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

diff -urN linux-2.4.22-pre2/Documentation/Configure.help linux-2.4.22-pre3/Documentation/Configure.help
--- linux-2.4.22-pre2/Documentation/Configure.help	2003-07-05 18:09:15.000000000 -0700
+++ linux-2.4.22-pre3/Documentation/Configure.help	2003-07-05 18:09:32.000000000 -0700
@@ -3052,6 +3052,11 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+ARP payload mangling
+CONFIG_IP_NF_ARP_MANGLE
+  Allows altering the ARP packet payload: source and destination
+  hardware and network addresses.
+
 TCP Explicit Congestion Notification support
 CONFIG_INET_ECN
   Explicit Congestion Notification (ECN) allows routers to notify
@@ -24029,6 +24034,20 @@
   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".
 
+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
@@ -26874,6 +26893,98 @@
   kernel tree does. Such modules that use library CRC32 functions
   require that you say M or Y here.
 
+CONFIG_CRYPTO
+  This option provides the core Cryptographic API.
+
+CONFIG_CRYPTO_HMAC
+  HMAC: Keyed-Hashing for Message Authentication (RFC2104).
+  This is required for IPSec.
+
+CONFIG_CRYPTO_NULL
+  These are 'Null' algorithms, used by IPsec, which do nothing.
+
+CONFIG_CRYPTO_MD4
+  MD4 message digest algorithm (RFC1320).
+  
+CONFIG_CRYPTO_MD5
+  MD5 message digest algorithm (RFC1321).
+
+CONFIG_CRYPTO_SHA1
+  SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
+
+CONFIG_CRYPTO_SHA256
+  SHA256 secure hash standard (DFIPS 180-2).
+
+  This version of SHA implements a 256 bit hash with 128 bits of
+  security against collision attacks.
+
+CONFIG_CRYPTO_SHA512
+  SHA512 secure hash standard (DFIPS 180-2).
+
+  This version of SHA implements a 512 bit hash with 256 bits of
+  security against collision attacks.
+
+  This code also includes SHA-384, a 384 bit hash with 192 bits
+  of security against collision attacks.
+
+CONFIG_CRYPTO_DES
+  DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
+
+CONFIG_CRYPTO_BLOWFISH
+  Blowfish cipher algorithm, by Bruce Schneier.
+
+  This is a variable key length cipher which can use keys from 32
+  bits to 448 bits in length.  It's fast, simple and specifically
+  designed for use on "large microprocessors".
+
+  See also <http://www.counterpane.com/blowfish.html>.
+
+CONFIG_CRYPTO_TWOFISH
+  Twofish cipher algorithm.
+
+  Twofish was submitted as an AES (Advanced Encryption Standard)
+  candidate cipher by researchers at CounterPane Systems.  It is a
+  16 round block cipher supporting key sizes of 128, 192, and 256
+  bits.
+
+  See also:
+  http://www.counterpane.com/twofish.html
+
+CONFIG_CRYPTO_SERPENT
+  Serpent cipher algorithm, by Anderson, Biham & Knudsen.
+
+  Keys are allowed to be from 0 to 256 bits in length, in steps
+  of 8 bits.
+
+  See also:
+  http://www.cl.cam.ac.uk/~rja14/serpent.html
+
+CONFIG_CRYPTO_AES
+  AES cipher algorithms (FIPS-197). AES uses the Rijndael 
+  algorithm.
+
+  Rijndael appears to be consistently a very good performer in
+  both hardware and software across a wide range of computing 
+  environments regardless of its use in feedback or non-feedback 
+  modes. Its key setup time is excellent, and its key agility is 
+  good. Rijndael's very low memory requirements make it very well 
+  suited for restricted-space environments, in which it also 
+  demonstrates excellent performance. Rijndael's operations are 
+  among the easiest to defend against power and timing attacks.	
+
+  The AES specifies three key sizes: 128, 192 and 256 bits	  
+
+  See http://csrc.nist.gov/encryption/aes/ for more information.
+
+CONFIG_CRYPTO_DEFLATE
+  This is the Deflate algorithm (RFC1951), specified for use in
+  IPSec with the IPCOMP protocol (RFC3173, RFC2394).
+
+  You will most probably want this if using IPSec.
+
+CONFIG_CRYPTO_TEST
+  Quick & dirty crypto test module.
+
 #
 # A couple of things I keep forgetting:
 #   capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
diff -urN linux-2.4.22-pre2/Documentation/cciss.txt linux-2.4.22-pre3/Documentation/cciss.txt
--- linux-2.4.22-pre2/Documentation/cciss.txt	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/Documentation/cciss.txt	2003-07-05 18:09:32.000000000 -0700
@@ -11,7 +11,8 @@
 	* SA 5312
 	* SA 641
 	* SA 642
-	* SA 6400
+	* SA 6402
+	* SA 6404/256
 
 If nodes are not already created in the /dev/cciss directory
 
diff -urN linux-2.4.22-pre2/Documentation/crypto/api-intro.txt linux-2.4.22-pre3/Documentation/crypto/api-intro.txt
--- linux-2.4.22-pre2/Documentation/crypto/api-intro.txt	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/Documentation/crypto/api-intro.txt	2003-07-05 18:09:32.000000000 -0700
@@ -0,0 +1,221 @@
+
+                    Scatterlist Cryptographic API
+                   
+INTRODUCTION
+
+The Scatterlist Crypto API takes page vectors (scatterlists) as
+arguments, and works directly on pages.  In some cases (e.g. ECB
+mode ciphers), this will allow for pages to be encrypted in-place
+with no copying.
+
+One of the initial goals of this design was to readily support IPsec,
+so that processing can be applied to paged skb's without the need
+for linearization.
+
+
+DETAILS
+
+At the lowest level are algorithms, which register dynamically with the
+API.
+
+'Transforms' are user-instantiated objects, which maintain state, handle all
+of the implementation logic (e.g. manipulating page vectors), provide an 
+abstraction to the underlying algorithms, and handle common logical 
+operations (e.g. cipher modes, HMAC for digests).  However, at the user 
+level they are very simple.
+
+Conceptually, the API layering looks like this:
+
+  [transform api]  (user interface)
+  [transform ops]  (per-type logic glue e.g. cipher.c, digest.c)
+  [algorithm api]  (for registering algorithms)
+  
+The idea is to make the user interface and algorithm registration API
+very simple, while hiding the core logic from both.  Many good ideas
+from existing APIs such as Cryptoapi and Nettle have been adapted for this.
+
+The API currently supports three types of transforms: Ciphers, Digests and
+Compressors.  The compression algorithms especially seem to be performing
+very well so far.
+
+Support for hardware crypto devices via an asynchronous interface is
+under development.
+
+Here's an example of how to use the API:
+
+	#include <linux/crypto.h>
+	
+	struct scatterlist sg[2];
+	char result[128];
+	struct crypto_tfm *tfm;
+	
+	tfm = crypto_alloc_tfm("md5", 0);
+	if (tfm == NULL)
+		fail();
+		
+	/* ... set up the scatterlists ... */
+	
+	crypto_digest_init(tfm);
+	crypto_digest_update(tfm, &sg, 2);
+	crypto_digest_final(tfm, result);
+	
+	crypto_free_tfm(tfm);
+
+    
+Many real examples are available in the regression test module (tcrypt.c).
+
+
+CONFIGURATION NOTES
+
+As Triple DES is part of the DES module, for those using modular builds,
+add the following line to /etc/modules.conf:
+
+  alias des3_ede des
+
+The Null algorithms reside in the crypto_null module, so these lines
+should also be added:
+
+  alias cipher_null crypto_null
+  alias digest_null crypto_null
+  alias compress_null crypto_null
+
+The SHA384 algorithm shares code within the SHA512 module, so you'll
+also need:
+  alias sha384 sha512
+
+
+DEVELOPER NOTES
+
+Transforms may only be allocated in user context, and cryptographic
+methods may only be called from softirq and user contexts.
+
+When using the API for ciphers, performance will be optimal if each
+scatterlist contains data which is a multiple of the cipher's block
+size (typically 8 bytes).  This prevents having to do any copying
+across non-aligned page fragment boundaries.
+
+
+ADDING NEW ALGORITHMS
+
+When submitting a new algorithm for inclusion, a mandatory requirement
+is that at least a few test vectors from known sources (preferably
+standards) be included.
+
+Converting existing well known code is preferred, as it is more likely
+to have been reviewed and widely tested.  If submitting code from LGPL
+sources, please consider changing the license to GPL (see section 3 of
+the LGPL).
+
+Algorithms submitted must also be generally patent-free (e.g. IDEA
+will not be included in the mainline until around 2011), and be based
+on a recognized standard and/or have been subjected to appropriate
+peer review.
+
+Also check for any RFCs which may relate to the use of specific algorithms,
+as well as general application notes such as RFC2451 ("The ESP CBC-Mode
+Cipher Algorithms").
+
+It's a good idea to avoid using lots of macros and use inlined functions
+instead, as gcc does a good job with inlining, while excessive use of
+macros can cause compilation problems on some platforms.
+
+Also check the TODO list at the web site listed below to see what people
+might already be working on.
+
+
+BUGS
+
+Send bug reports to:
+James Morris <jmorris@intercode.com.au>
+Cc: David S. Miller <davem@redhat.com>
+
+
+FURTHER INFORMATION
+
+For further patches and various updates, including the current TODO
+list, see:
+http://samba.org/~jamesm/crypto/
+
+
+AUTHORS
+
+James Morris
+David S. Miller
+
+
+CREDITS
+
+The following people provided invaluable feedback during the development
+of the API:
+
+  Alexey Kuznetzov
+  Rusty Russell
+  Herbert Valerio Riedel
+  Jeff Garzik
+  Michael Richardson
+  Andrew Morton
+  Ingo Oeser
+  Christoph Hellwig
+
+Portions of this API were derived from the following projects:
+  
+  Kerneli Cryptoapi (http://www.kerneli.org/)
+    Alexander Kjeldaas
+    Herbert Valerio Riedel
+    Kyle McMartin
+    Jean-Luc Cooke
+    David Bryson
+    Clemens Fruhwirth
+    Tobias Ringstrom
+    Harald Welte
+
+and;
+  
+  Nettle (http://www.lysator.liu.se/~nisse/nettle/)
+    Niels Möller
+
+Original developers of the crypto algorithms:
+
+  Dana L. How (DES)
+  Andrew Tridgell and Steve French (MD4)
+  Colin Plumb (MD5)
+  Steve Reid (SHA1)
+  Jean-Luc Cooke (SHA256, SHA384, SHA512)
+  Kazunori Miyazawa / USAGI (HMAC)
+  Matthew Skala (Twofish)
+  Dag Arne Osvik (Serpent)
+  Brian Gladman (AES)
+
+
+SHA1 algorithm contributors:
+  Jean-Francois Dive
+  
+DES algorithm contributors:
+  Raimar Falke
+  Gisle Sælensminde
+  Niels Möller
+
+Blowfish algorithm contributors:
+  Herbert Valerio Riedel
+  Kyle McMartin
+
+Twofish algorithm contributors:
+  Werner Koch
+  Marc Mutz
+
+SHA256/384/512 algorithm contributors:
+  Andrew McDonald
+  Kyle McMartin
+  Herbert Valerio Riedel
+  
+AES algorithm contributors:
+  Alexander Kjeldaas
+  Herbert Valerio Riedel
+  Kyle McMartin
+  Adam J. Richter
+
+Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
+
+Please send any credits updates or corrections to:
+James Morris <jmorris@intercode.com.au>
+
diff -urN linux-2.4.22-pre2/Documentation/crypto/descore-readme.txt linux-2.4.22-pre3/Documentation/crypto/descore-readme.txt
--- linux-2.4.22-pre2/Documentation/crypto/descore-readme.txt	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/Documentation/crypto/descore-readme.txt	2003-07-05 18:09:32.000000000 -0700
@@ -0,0 +1,352 @@
+Below is the orginal README file from the descore.shar package.
+------------------------------------------------------------------------------
+
+des - fast & portable DES encryption & decryption.
+Copyright (C) 1992  Dana L. How
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Author's address: how@isl.stanford.edu
+
+$Id: README,v 1.15 1992/05/20 00:25:32 how E $
+
+
+==>> To compile after untarring/unsharring, just `make' <<==
+
+
+This package was designed with the following goals:
+1.	Highest possible encryption/decryption PERFORMANCE.
+2.	PORTABILITY to any byte-addressable host with a 32bit unsigned C type
+3.	Plug-compatible replacement for KERBEROS's low-level routines.
+
+This second release includes a number of performance enhancements for
+register-starved machines.  My discussions with Richard Outerbridge,
+71755.204@compuserve.com, sparked a number of these enhancements.
+
+To more rapidly understand the code in this package, inspect desSmallFips.i
+(created by typing `make') BEFORE you tackle desCode.h.  The latter is set
+up in a parameterized fashion so it can easily be modified by speed-daemon
+hackers in pursuit of that last microsecond.  You will find it more
+illuminating to inspect one specific implementation,
+and then move on to the common abstract skeleton with this one in mind.
+
+
+performance comparison to other available des code which i could
+compile on a SPARCStation 1 (cc -O4, gcc -O2):
+
+this code (byte-order independent):
+   30us per encryption (options: 64k tables, no IP/FP)
+   33us per encryption (options: 64k tables, FIPS standard bit ordering)
+   45us per encryption (options:  2k tables, no IP/FP)
+   48us per encryption (options:  2k tables, FIPS standard bit ordering)
+  275us to set a new key (uses 1k of key tables)
+	this has the quickest encryption/decryption routines i've seen.
+	since i was interested in fast des filters rather than crypt(3)
+	and password cracking, i haven't really bothered yet to speed up
+	the key setting routine. also, i have no interest in re-implementing
+	all the other junk in the mit kerberos des library, so i've just
+	provided my routines with little stub interfaces so they can be
+	used as drop-in replacements with mit's code or any of the mit-
+	compatible packages below. (note that the first two timings above
+	are highly variable because of cache effects).
+
+kerberos des replacement from australia (version 1.95):
+   53us per encryption (uses 2k of tables)
+   96us to set a new key (uses 2.25k of key tables)
+	so despite the author's inclusion of some of the performance
+	improvements i had suggested to him, this package's
+	encryption/decryption is still slower on the sparc and 68000.
+	more specifically, 19-40% slower on the 68020 and 11-35% slower
+	on the sparc,  depending on the compiler;
+	in full gory detail (ALT_ECB is a libdes variant):
+	compiler   	machine		desCore	libdes	ALT_ECB	slower by
+	gcc 2.1 -O2	Sun 3/110	304  uS	369.5uS	461.8uS	 22%
+	cc      -O1	Sun 3/110	336  uS	436.6uS	399.3uS	 19%
+	cc      -O2	Sun 3/110	360  uS	532.4uS	505.1uS	 40%
+	cc      -O4	Sun 3/110	365  uS	532.3uS	505.3uS	 38%
+	gcc 2.1 -O2	Sun 4/50	 48  uS	 53.4uS	 57.5uS	 11%
+	cc      -O2	Sun 4/50	 48  uS	 64.6uS	 64.7uS	 35%
+	cc      -O4	Sun 4/50	 48  uS	 64.7uS	 64.9uS	 35%
+	(my time measurements are not as accurate as his).
+   the comments in my first release of desCore on version 1.92:
+   68us per encryption (uses 2k of tables)
+   96us to set a new key (uses 2.25k of key tables)
+	this is a very nice package which implements the most important
+	of the optimizations which i did in my encryption routines.
+	it's a bit weak on common low-level optimizations which is why
+	it's 39%-106% slower.  because he was interested in fast crypt(3) and
+	password-cracking applications,  he also used the same ideas to
+	speed up the key-setting routines with impressive results.
+	(at some point i may do the same in my package).  he also implements
+	the rest of the mit des library.
+	(code from eay@psych.psy.uq.oz.au via comp.sources.misc)
+
+fast crypt(3) package from denmark:
+	the des routine here is buried inside a loop to do the
+	crypt function and i didn't feel like ripping it out and measuring
+	performance. his code takes 26 sparc instructions to compute one
+	des iteration; above, Quick (64k) takes 21 and Small (2k) takes 37.
+	he claims to use 280k of tables but the iteration calculation seems
+	to use only 128k.  his tables and code are machine independent.
+	(code from glad@daimi.aau.dk via alt.sources or comp.sources.misc)
+
+swedish reimplementation of Kerberos des library
+  108us per encryption (uses 34k worth of tables)
+  134us to set a new key (uses 32k of key tables to get this speed!)
+	the tables used seem to be machine-independent;
+	he seems to have included a lot of special case code
+	so that, e.g., `long' loads can be used instead of 4 `char' loads
+	when the machine's architecture allows it.
+	(code obtained from chalmers.se:pub/des)
+
+crack 3.3c package from england:
+	as in crypt above, the des routine is buried in a loop. it's
+	also very modified for crypt.  his iteration code uses 16k
+	of tables and appears to be slow.
+	(code obtained from aem@aber.ac.uk via alt.sources or comp.sources.misc)
+
+``highly optimized'' and tweaked Kerberos/Athena code (byte-order dependent):
+  165us per encryption (uses 6k worth of tables)
+  478us to set a new key (uses <1k of key tables)
+	so despite the comments in this code, it was possible to get
+	faster code AND smaller tables, as well as making the tables
+	machine-independent.
+	(code obtained from prep.ai.mit.edu)
+
+UC Berkeley code (depends on machine-endedness):
+  226us per encryption
+10848us to set a new key
+	table sizes are unclear, but they don't look very small
+	(code obtained from wuarchive.wustl.edu)
+
+
+motivation and history
+
+a while ago i wanted some des routines and the routines documented on sun's
+man pages either didn't exist or dumped core.  i had heard of kerberos,
+and knew that it used des,  so i figured i'd use its routines.  but once
+i got it and looked at the code,  it really set off a lot of pet peeves -
+it was too convoluted, the code had been written without taking
+advantage of the regular structure of operations such as IP, E, and FP
+(i.e. the author didn't sit down and think before coding),
+it was excessively slow,  the author had attempted to clarify the code
+by adding MORE statements to make the data movement more `consistent'
+instead of simplifying his implementation and cutting down on all data
+movement (in particular, his use of L1, R1, L2, R2), and it was full of
+idiotic `tweaks' for particular machines which failed to deliver significant
+speedups but which did obfuscate everything.  so i took the test data
+from his verification program and rewrote everything else.
+
+a while later i ran across the great crypt(3) package mentioned above.
+the fact that this guy was computing 2 sboxes per table lookup rather
+than one (and using a MUCH larger table in the process) emboldened me to
+do the same - it was a trivial change from which i had been scared away
+by the larger table size.  in his case he didn't realize you don't need to keep
+the working data in TWO forms, one for easy use of half the sboxes in
+indexing, the other for easy use of the other half; instead you can keep
+it in the form for the first half and use a simple rotate to get the other
+half.  this means i have (almost) half the data manipulation and half
+the table size.  in fairness though he might be encoding something particular
+to crypt(3) in his tables - i didn't check.
+
+i'm glad that i implemented it the way i did, because this C version is
+portable (the ifdef's are performance enhancements) and it is faster
+than versions hand-written in assembly for the sparc!
+
+
+porting notes
+
+one thing i did not want to do was write an enormous mess
+which depended on endedness and other machine quirks,
+and which necessarily produced different code and different lookup tables
+for different machines.  see the kerberos code for an example
+of what i didn't want to do; all their endedness-specific `optimizations'
+obfuscate the code and in the end were slower than a simpler machine
+independent approach.  however, there are always some portability
+considerations of some kind, and i have included some options
+for varying numbers of register variables.
+perhaps some will still regard the result as a mess!
+
+1) i assume everything is byte addressable, although i don't actually
+   depend on the byte order, and that bytes are 8 bits.
+   i assume word pointers can be freely cast to and from char pointers.
+   note that 99% of C programs make these assumptions.
+   i always use unsigned char's if the high bit could be set.
+2) the typedef `word' means a 32 bit unsigned integral type.
+   if `unsigned long' is not 32 bits, change the typedef in desCore.h.
+   i assume sizeof(word) == 4 EVERYWHERE.
+
+the (worst-case) cost of my NOT doing endedness-specific optimizations
+in the data loading and storing code surrounding the key iterations
+is less than 12%.  also, there is the added benefit that
+the input and output work areas do not need to be word-aligned.
+
+
+OPTIONAL performance optimizations
+
+1) you should define one of `i386,' `vax,' `mc68000,' or `sparc,'
+   whichever one is closest to the capabilities of your machine.
+   see the start of desCode.h to see exactly what this selection implies.
+   note that if you select the wrong one, the des code will still work;
+   these are just performance tweaks.
+2) for those with functional `asm' keywords: you should change the
+   ROR and ROL macros to use machine rotate instructions if you have them.
+   this will save 2 instructions and a temporary per use,
+   or about 32 to 40 instructions per en/decryption.
+   note that gcc is smart enough to translate the ROL/R macros into
+   machine rotates!
+
+these optimizations are all rather persnickety, yet with them you should
+be able to get performance equal to assembly-coding, except that:
+1) with the lack of a bit rotate operator in C, rotates have to be synthesized
+   from shifts.  so access to `asm' will speed things up if your machine
+   has rotates, as explained above in (3) (not necessary if you use gcc).
+2) if your machine has less than 12 32-bit registers i doubt your compiler will
+   generate good code.
+   `i386' tries to configure the code for a 386 by only declaring 3 registers
+   (it appears that gcc can use ebx, esi and edi to hold register variables).
+   however, if you like assembly coding, the 386 does have 7 32-bit registers,
+   and if you use ALL of them, use `scaled by 8' address modes with displacement
+   and other tricks, you can get reasonable routines for DesQuickCore... with
+   about 250 instructions apiece.  For DesSmall... it will help to rearrange
+   des_keymap, i.e., now the sbox # is the high part of the index and
+   the 6 bits of data is the low part; it helps to exchange these.
+   since i have no way to conveniently test it i have not provided my
+   shoehorned 386 version.  note that with this release of desCore, gcc is able
+   to put everything in registers(!), and generate about 370 instructions apiece
+   for the DesQuickCore... routines!
+
+coding notes
+
+the en/decryption routines each use 6 necessary register variables,
+with 4 being actively used at once during the inner iterations.
+if you don't have 4 register variables get a new machine.
+up to 8 more registers are used to hold constants in some configurations.
+
+i assume that the use of a constant is more expensive than using a register:
+a) additionally, i have tried to put the larger constants in registers.
+   registering priority was by the following:
+	anything more than 12 bits (bad for RISC and CISC)
+	greater than 127 in value (can't use movq or byte immediate on CISC)
+	9-127 (may not be able to use CISC shift immediate or add/sub quick),
+	1-8 were never registered, being the cheapest constants.
+b) the compiler may be too stupid to realize table and table+256 should
+   be assigned to different constant registers and instead repetitively
+   do the arithmetic, so i assign these to explicit `m' register variables
+   when possible and helpful.
+
+i assume that indexing is cheaper or equivalent to auto increment/decrement,
+where the index is 7 bits unsigned or smaller.
+this assumption is reversed for 68k and vax.
+
+i assume that addresses can be cheaply formed from two registers,
+or from a register and a small constant.
+for the 68000, the `two registers and small offset' form is used sparingly.
+all index scaling is done explicitly - no hidden shifts by log2(sizeof).
+
+the code is written so that even a dumb compiler
+should never need more than one hidden temporary,
+increasing the chance that everything will fit in the registers.
+KEEP THIS MORE SUBTLE POINT IN MIND IF YOU REWRITE ANYTHING.
+(actually, there are some code fragments now which do require two temps,
+but fixing it would either break the structure of the macros or
+require declaring another temporary).
+
+
+special efficient data format
+
+bits are manipulated in this arrangement most of the time (S7 S5 S3 S1):
+	003130292827xxxx242322212019xxxx161514131211xxxx080706050403xxxx
+(the x bits are still there, i'm just emphasizing where the S boxes are).
+bits are rotated left 4 when computing S6 S4 S2 S0:
+	282726252423xxxx201918171615xxxx121110090807xxxx040302010031xxxx
+the rightmost two bits are usually cleared so the lower byte can be used
+as an index into an sbox mapping table. the next two x'd bits are set
+to various values to access different parts of the tables.
+
+
+how to use the routines
+
+datatypes:
+	pointer to 8 byte area of type DesData
+	used to hold keys and input/output blocks to des.
+
+	pointer to 128 byte area of type DesKeys
+	used to hold full 768-bit key.
+	must be long-aligned.
+
+DesQuickInit()
+	call this before using any other routine with `Quick' in its name.
+	it generates the special 64k table these routines need.
+DesQuickDone()
+	frees this table
+
+DesMethod(m, k)
+	m points to a 128byte block, k points to an 8 byte des key
+	which must have odd parity (or -1 is returned) and which must
+	not be a (semi-)weak key (or -2 is returned).
+	normally DesMethod() returns 0.
+	m is filled in from k so that when one of the routines below
+	is called with m, the routine will act like standard des
+	en/decryption with the key k. if you use DesMethod,
+	you supply a standard 56bit key; however, if you fill in
+	m yourself, you will get a 768bit key - but then it won't
+	be standard.  it's 768bits not 1024 because the least significant
+	two bits of each byte are not used.  note that these two bits
+	will be set to magic constants which speed up the encryption/decryption
+	on some machines.  and yes, each byte controls
+	a specific sbox during a specific iteration.
+	you really shouldn't use the 768bit format directly;  i should
+	provide a routine that converts 128 6-bit bytes (specified in
+	S-box mapping order or something) into the right format for you.
+	this would entail some byte concatenation and rotation.
+
+Des{Small|Quick}{Fips|Core}{Encrypt|Decrypt}(d, m, s)
+	performs des on the 8 bytes at s into the 8 bytes at d. (d,s: char *).
+	uses m as a 768bit key as explained above.
+	the Encrypt|Decrypt choice is obvious.
+	Fips|Core determines whether a completely standard FIPS initial
+	and final permutation is done; if not, then the data is loaded
+	and stored in a nonstandard bit order (FIPS w/o IP/FP).
+	Fips slows down Quick by 10%, Small by 9%.
+	Small|Quick determines whether you use the normal routine
+	or the crazy quick one which gobbles up 64k more of memory.
+	Small is 50% slower then Quick, but Quick needs 32 times as much
+	memory.  Quick is included for programs that do nothing but DES,
+	e.g., encryption filters, etc.
+
+
+Getting it to compile on your machine
+
+there are no machine-dependencies in the code (see porting),
+except perhaps the `now()' macro in desTest.c.
+ALL generated tables are machine independent.
+you should edit the Makefile with the appropriate optimization flags
+for your compiler (MAX optimization).
+
+
+Speeding up kerberos (and/or its des library)
+
+note that i have included a kerberos-compatible interface in desUtil.c
+through the functions des_key_sched() and des_ecb_encrypt().
+to use these with kerberos or kerberos-compatible code put desCore.a
+ahead of the kerberos-compatible library on your linker's command line.
+you should not need to #include desCore.h;  just include the header
+file provided with the kerberos library.
+
+Other uses
+
+the macros in desCode.h would be very useful for putting inline des
+functions in more complicated encryption routines.
diff -urN linux-2.4.22-pre2/Documentation/devices.txt linux-2.4.22-pre3/Documentation/devices.txt
--- linux-2.4.22-pre2/Documentation/devices.txt	2001-11-07 14:46:01.000000000 -0800
+++ linux-2.4.22-pre3/Documentation/devices.txt	2003-07-05 18:09:32.000000000 -0700
@@ -2531,17 +2531,17 @@
 		  1 = /dev/dri/card1		Second graphics card
 		    ...
 
-227 char	IBM 3270 terminal block-mode access
+227 char	IBM 3270 terminal Unix tty access
+		  1 = /dev/3270/tty1		First 3270 terminal
+		  2 = /dev/3270/tty2		Seconds 3270 terminal
+		    ...
+
+228 char	IBM 3270 terminal block-mode access
 		  0 = /dev/3270/tub		Controlling interface
 		  1 = /dev/3270/tub1		First 3270 terminal
 		  2 = /dev/3270/tub2		Second 3270 terminal
 		    ...
 
-228 char	IBM 3270 terminal Unix tty access
-		  1 = /dev/3270/tty1		First 3270 terminal
-		  2 = /dev/3270/tty2		Seconds 3270 terminal
-		    ...
-
 229 char	IBM iSeries virtual console
 		  0 = /dev/iseries/vtty0	First console port
 		  1 = /dev/iseries/vtty1	Second console port
diff -urN linux-2.4.22-pre2/Documentation/fb/vesafb.txt linux-2.4.22-pre3/Documentation/fb/vesafb.txt
--- linux-2.4.22-pre2/Documentation/fb/vesafb.txt	2000-07-28 12:50:51.000000000 -0700
+++ linux-2.4.22-pre3/Documentation/fb/vesafb.txt	2003-07-05 18:09:32.000000000 -0700
@@ -139,13 +139,17 @@
 redraw	scroll by redrawing the affected part of the screen, this
 	is the safe (and slow) default.
 
-
 vgapal	Use the standard vga registers for palette changes.
 	This is the default.
 pmipal	Use the protected mode interface for palette changes.
 
 mtrr	setup memory type range registers for the vesafb framebuffer.
 
+vram:n  remap 'n' MiB of video RAM. If 0 or not specified, remap memory
+        according to video mode. (2.5.66 patch/idea by Antonino Daplas
+	reversed to give override possibility (allocate more fb memory
+	than the kernel would) to 2.4 by tmb@iki.fi)
+  
 
 Have fun!
 
diff -urN linux-2.4.22-pre2/Documentation/filesystems/tmpfs.txt linux-2.4.22-pre3/Documentation/filesystems/tmpfs.txt
--- linux-2.4.22-pre2/Documentation/filesystems/tmpfs.txt	2001-12-21 09:41:53.000000000 -0800
+++ linux-2.4.22-pre3/Documentation/filesystems/tmpfs.txt	2003-07-05 18:09:32.000000000 -0700
@@ -47,26 +47,28 @@
    shared memory)
 
 3) Some people (including me) find it very convenient to mount it
-   e.g. on /tmp and /var/tmp and have a big swap partition. But be
-   aware: loop mounts of tmpfs files do not work due to the internal
-   design. So mkinitrd shipped by most distributions will fail with a
-   tmpfs /tmp.
+   e.g. on /tmp and /var/tmp and have a big swap partition. And now
+   loop mounts of tmpfs files do work, so mkinitrd shipped by most
+   distributions should succeed with a tmpfs /tmp.
 
 4) And probably a lot more I do not know about :-)
 
 
-tmpfs has a couple of mount options:
+tmpfs has three mount options for sizing:
 
-size:	   The limit of allocated bytes for this tmpfs instance. The 
+size:      The limit of allocated bytes for this tmpfs instance. The 
            default is half of your physical RAM without swap. If you
-	   oversize your tmpfs instances the machine will deadlock
-	   since the OOM handler will not be able to free that memory.
-nr_blocks: The same as size, but in blocks of PAGECACHE_SIZE.
+           oversize your tmpfs instances the machine will deadlock
+           since the OOM handler will not be able to free that memory.
+nr_blocks: The same as size, but in blocks of PAGE_CACHE_SIZE.
 nr_inodes: The maximum number of inodes for this instance. The default
            is half of the number of your physical RAM pages.
 
 These parameters accept a suffix k, m or g for kilo, mega and giga and
-can be changed on remount.
+can be changed on remount.  The size parameter also accepts a suffix %
+to limit this tmpfs instance to that percentage of your physical RAM:
+the default, when neither size nor nr_blocks is specified, is size=50%
+
 
 To specify the initial root directory you can use the following mount
 options:
@@ -84,19 +86,7 @@
 RAM/SWAP in 10240 inodes and it is only accessible by root.
 
 
-TODOs:
-
-1) give the size option a percent semantic: If you give a mount option
-   size=50% the tmpfs instance should be able to grow to 50 percent of
-   RAM + swap. So the instance should adapt automatically if you add
-   or remove swap space.
-2) loop mounts: This is difficult since loop.c relies on the readpage
-   operation. This operation gets a page from the caller to be filled
-   with the content of the file at that position. But tmpfs always has
-   the page and thus cannot copy the content to the given page. So it
-   cannot provide this operation. The VM had to be changed seriously
-   to achieve this.
-3) Show the number of tmpfs RAM pages. (As shared?)
-
 Author:
    Christoph Rohland <cr@sap.com>, 1.12.01
+Updated:
+   Hugh Dickins <hugh@veritas.com>, 01 April 2003
diff -urN linux-2.4.22-pre2/Documentation/s390/CommonIO linux-2.4.22-pre3/Documentation/s390/CommonIO
--- linux-2.4.22-pre2/Documentation/s390/CommonIO	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/Documentation/s390/CommonIO	2003-07-05 18:09:32.000000000 -0700
@@ -21,7 +21,8 @@
   Default is on.
 
 
-* cio_ignore = <range of device numbers>, <range of device numbers>, ...
+* cio_ignore = <device number> | <range of device numbers>, 
+	       <device number> | <range of device numbers>, ...
 
   The given device numbers will be ignored by the common I/O-layer; no detection
   and device sensing will be done on any of those devices. The subchannel to 
@@ -55,14 +56,22 @@
 
 * /proc/subchannels
 
-  Shows for each subchannel
-  - device number
-  - device type/model and if applicable control unit type/model
-  - whether the device is in use
-  - path installed mask, path available mask, path operational mask and last 
-    path used mask
-  - the channel path IDs (chpids)
+  This entry shows information on a per-subchannel basis.
 
+  The data is ordered in the following way:
+
+  - device number 
+  - subchannel number 
+  - device type/model (if applicable; if not, this is empty) and control unit 
+    type/model
+  - whether the device is in use (i. e. a device driver has requested ownership 
+    and registered an interrupt handler)
+  - path installed mask (PIM), as reflected by last store subchannel
+  - path available mask (PAM), as reflected by last store subchannel
+  - path operational mask (POM), as reflected by last store subchannel
+  - the channel path IDs (CHPIDs)
+
+  All fields are separated by spaces, the chpids are in blocks of four chpids.
 
 * /proc/deviceinfo/
 
@@ -137,3 +146,26 @@
 
   This entry counts how many times s390_process_IRQ has been called for each 
   CPU. This info is in /proc/interrupts on other architectures.
+
+* /proc/chpids
+
+  This entry will only show up if you specified CONFIG_CHSC=y during kernel
+  config.
+
+  This entry serves a dual purpose:
+ 
+  - show which chpids are currently known to Linux and their status (online,
+    logically offline),
+
+  - toggling known chpids logically online/offline.
+
+  To toggle a known chpid logically offline, do an
+	echo off <chpid> > /proc/chpids
+  <chpid> is interpreted as hex, even if you omit the '0x'.
+  The chpid will be treated by Linux as if it were not online, which can mean 
+  some devices will become unavailable.
+
+  You can toggle a logically offline chpid online again by
+	echo on <chpid> > /proc/chpids
+  If devices became unavailable by toggling the chpid logically offline, they 
+  will become available again after you toggle the chpid online again.
diff -urN linux-2.4.22-pre2/Documentation/s390/Debugging390.txt linux-2.4.22-pre3/Documentation/s390/Debugging390.txt
--- linux-2.4.22-pre2/Documentation/s390/Debugging390.txt	2002-02-25 11:37:51.000000000 -0800
+++ linux-2.4.22-pre3/Documentation/s390/Debugging390.txt	2003-07-05 18:09:33.000000000 -0700
@@ -238,7 +238,7 @@
 
 On 390 our limitations & strengths make us slightly different.
 For backward compatibility ( because of the psw address hi bit which
-indicates whether we are in 31 or 64 bit mode ) we are only allowed 
+indicates whether we are in 31 or 24 bit mode ) we are only allowed 
 use 31 bits (2GB) of our 32 bit addresses. However, 
 we use entirely separate address  spaces for the user & kernel.
 
@@ -1475,6 +1475,12 @@
 D 00014CB4.20
 V00014CB4  2F646576 2F636F6E 736F6C65 00001BF5
 V00014CC4  FC00014C B4001001 E0001000 B8070707
+
+Alternatively you can do the more elegant
+D 0.20;BASE2
+BASE2 telling VM to use GPR2 as the base register.
+
+
 Now copy the text till the first 00 hex ( which is the end of the string
 to an xterm & do hex2ascii on it.
 hex2ascii 2F646576 2F636F6E 736F6C65 00 
diff -urN linux-2.4.22-pre2/Documentation/s390/cds.txt linux-2.4.22-pre3/Documentation/s390/cds.txt
--- linux-2.4.22-pre2/Documentation/s390/cds.txt	2001-03-02 11:12:06.000000000 -0800
+++ linux-2.4.22-pre3/Documentation/s390/cds.txt	2003-07-05 18:09:34.000000000 -0700
@@ -5,12 +5,14 @@
 
 Author : Ingo Adlung
 
-Copyright, IBM Corp. 1999
+Copyright, IBM Corp. 1999-2002
+
+ChangeLog: 02/01/2002   Cornelia Huck    brought up-to-date
 
 Introduction
 
 This document describes the common device support routines for Linux/390.
-Different than other hardware architectures, ESA/390 hasdefined a unified
+Different than other hardware architectures, ESA/390 has defined a unified
 I/O access method. This gives relief to the device drivers as they don't
 have to deal with different bus types, polling versus interrupt
 processing, shared versus non-shared interrupt processing, DMA versus port
@@ -26,14 +28,11 @@
 
 In order to build common device support for ESA/390 I/O interfaces, a
 functional layer was introduced that provides generic I/O access methods to
-the hardware. The following figure shows the usage of the common device support
-of Linux/390 using a TbCP/IP driven device access an example. Similar figures
-could be drawn for other access methods, e.g. file system access to disk
-devices.
-
-The common device support layer shown above comprises the I/O support routines
-defined below. Some of them implement common Linux device driver interfaces,
-while some of them are ESA/390 platform specific.
+the hardware. 
+
+The common device support layer comprises the I/O support routines defined 
+below. Some of them implement common Linux device driver interfaces, while 
+some of them are ESA/390 platform specific.
 
 get_dev_info_by_irq() / get_dev_info_by_devno()	
    allow a device driver to determine the devices attached (visible) to the
@@ -44,10 +43,17 @@
 
 read_dev_chars()	
    read device characteristics
+   
+read_conf_data()
+   read configuration data.
 
 request_irq()	
    obtain ownership for a specific device.
 
+s390_request_irq_special()
+   obtain ownership for a specific device. Similar to request_irq(), but
+   allows for device not operational notification too.
+
 free_irq()	
    release ownership for a specific device.
 
@@ -60,6 +66,9 @@
 do_IO()	
    initiate an I/O request.
 
+resume_IO()
+   resume channel program execution.
+
 halt_IO()	
    terminate the current I/O request processed on the device.
 
@@ -70,12 +79,14 @@
    interrupt handler according to the rules (flags) defined during I/O request
    initiation with do_IO().
 
-The next chapters describe the functions, other than do_IRQ() in more details.
+The next chapters describe the functions other than do_IRQ() in more details.
 The do_IRQ() interface is not described, as it is called from the Linux/390
 first level interrupt handler only and does not comprise a device driver
 callable interface. Instead, the functional description of do_IO() also
 describes the input to the device specific interrupt handler.
 
+Note: All explanations apply also to the 64 bit architecture s390x.
+
 
 Common Device Support (CDS) for Linux/390 Device Drivers
 
@@ -90,7 +101,7 @@
 of them can be found on other Linux platforms implementations too.
 Miscellaneous function prototypes, data declarations, and macro definitions
 can be found in the architecture specific C header file
-linux/arch/s390/kernel/irq.h.
+linux/include/asm-s390/irq.h.
 
 Overview of CDS interface concepts
 
@@ -106,7 +117,7 @@
 single device is uniquely identified to the system by a so called subchannel,
 where the ESA/390 architecture allows for 64k devices be attached.
 
-Linux, however was first built on the Intel PC architecture, with its two
+Linux, however, was first built on the Intel PC architecture, with its two
 cascaded 8259 programmable interrupt controllers (PICs), that allow for a
 maximum of 15 different interrupt lines. All devices attached to such a system
 share those 15 interrupt levels. Devices attached to the ISA bus system must
@@ -117,7 +128,7 @@
 has to call every single device driver registered on this IRQ in order to
 determine the device driver owning the device that raised the interrupt.
 
-In order to not introduce a new I/O concept to the common Linux code,
+In order not to introduce a new I/O concept to the common Linux code,
 Linux/390 preserves the IRQ concept and semantically maps the ESA/390
 subchannels to Linux as IRQs. This allows Linux/390 to support up to 64k
 different IRQs, uniquely representig a single device each.
@@ -126,7 +137,7 @@
 of those devices is uniquely defined by a so called subchannel by the ESA/390
 channel subsystem. While the subchannel numbers are system generated, each
 subchannel also takes a user defined attribute, the so called device number.
-Both, subchannel number and device number can not exceed 65535. The
+Both subchannel number and device number can not exceed 65535. The
 init_IRQ() routine gathers the information about control unit type and device
 types that imply specific I/O commands (channel command words - CCWs) in
 order to operate the device. Device drivers can retrieve this set of hardware
@@ -141,7 +152,7 @@
 When a device driver has recognized a device it wants to claim ownership for,
 it calls request_irq() with the device's subchannel id serving as pseudo irq
 line. One of the required parameters it has to specify is dev_id, defining a
-device status block, the CDS layer will use to notify the device driver's
+device status block which the CDS layer will use to notify the device driver's
 interrupt handler about interrupt information observed. It depends on the
 device driver to properly handle those interrupts.
 
@@ -169,6 +180,41 @@
 
 
 
+get_irq_first() / get_irq_next() - Retrieve Information about available IRQs 
+
+A device driver can use those interface routines to retrieve information for 
+those IRQs only that have valid device information available. As 
+Linux for S/390 supports a maximum of 65535 subchannels (devices), it might 
+be a waste of CPU to scan for the max number of  devices while a fraction is 
+available/usable only. get_irq_first() will retrieve the first usable IRQ. 
+Using this as input get_irq_next() will retrieve the next IRQ available, etc..
+
+int get_irq_first( void );
+int get_irq_next( int irq );
+
+irq - defines the subchannel to start scanning with. This must be
+      a valid subchannel or an error is returned. 
+
+The get_irq_first() / get_irq_next() functions return:
+
+non-negative value - next available IRQ
+          -ENODEV  - no more IRQs available
+
+Example : 
+
+ irq = get_irq_first();
+ while ( irq != -ENODEV) 
+ {
+  get_dev_info_by_irq( irq, &dinfo);
+  if (    dinfo.devno == devno_to_look_for 
+       || dinfo.sid_data.cu_type == cu_type_to_look_for )
+  {
+   do_some_action( irq, &dinfo ); 
+  } /* endif */
+    
+  irq = get_irq_next(irq);
+ }
+
 get_dev_info_by_irq() / get_dev_info_by_devno() - Retrieve Device Information
 
 During system startup - init_IRQ() processing - the generic I/O device support
@@ -176,60 +222,69 @@
 SenseID information. For those devices supporting the command it also obtains
 extended SenseID information.
 
-int get_dev_info_by_irq( int         irq,
-                         dev_info_t *devinfo);
+int get_dev_info_by_irq( int             irq,
+                         s390_dev_info_t *pdi);
 
-int get_dev_info_by_devno( unsigned int  irq,
-                           dev_info_t   *devinfo);
+int get_dev_info_by_devno( __u16           devno,
+                           s390_dev_info_t *pdi);
 
-irq     - defines the subchannel, status information is to be
+irq     - defines the subchannel status information is to be
           returned for.
 devno   - device number.
-devinfo - pointer to a user buffer of type dev_info_t that should
+pdi     - pointer to a user buffer of type s390_dev_info_t that should
           be filled with device specific information.
 
 typedef struct {
-     unsigned int devno;     /* device number */
-     unsigned int status;    /* device status */
-     senseid_t    sid_data;  /* senseID data  */
-} dev_info_t;
+     int          irq;                  /* irq, aka. subchannel */
+     __u16        devno;                /* device number */
+     unsigned int status;               /* device status */
+     senseid_t    sid_data;             /* senseID data */
+} s390_dev_info_t;			
 
+irq       - subchannel.
 devno     - device number as configured in the IOCDS.
 status    - device status
 sid_data  - data obtained by a SenseID call
 
 Possible status values are :
 
-DEVSTAT_NOT_OPER - device was found not-operational. In this case
-                   the caller should disregard the sid_data
-                   buffer content.
+DEVSTAT_NOT_OPER -       device was found not-operational. In this case
+                         the caller should disregard the sid_data
+                         buffer content.
+DEVSTAT_UNFRIENDLY_DEV - device is locked by someone else. The sid_data buffer
+		         doesn't contain valid data.
+DEVSTAT_UNKNOWN_DEV -    The device is unknown, and the sid_data buffer doesn't
+		         contain valid data.
+DEVSTAT_DEVICE_OWNED -   An interrupt handler is registered.
 
 //
-// SenseID response buffer layout
+// sense-id response buffer layout
 //
 typedef struct {
   /* common part */
-      unsigned char  reserved;     /* always 0x'FF' */
-      unsigned short cu_type;      /* control unit type */
-      unsigned char  cu_model;     /* control unit model */
-      unsigned short dev_type;     /* device type */
-      unsigned char  dev_model;    /* device model */
-      unsigned char  unused;       /* padding byte */
+      __u8           reserved;     /* always 0x'FF' */
+      __u16          cu_type;      /* control unit type */
+      __u8           cu_model;     /* control unit model */
+      __u16          dev_type;     /* device type */
+      __u8           dev_model;    /* device model */
+      __u8           unused;       /* padding byte */
   /* extended part */
-      ciw_t    ciw[62];            /* variable # of CIWs */
-} senseid_t;
+      ciw_t    ciw[MAX_CIWS];      /* variable # of CIWs */
+}  __attribute__ ((packed,aligned(4))) senseid_t;
+
+MAX_CIWS is currently defined as 8.
 
 The ESA/390 I/O architecture defines certain device specific I/O functions.
 The device returns the device specific command code together with the SenseID
 data in so called Command Information Words (CIW) :
 
 typedef struct _ciw {
-   unsigned int et       :  2;    // entry type
-   unsigned int reserved :  2;    // reserved
-   unsigned int ct       :  4;    // command type
-   unsigned int cmd      :  8;    // command
-   unsigned int count    : 16;    // count
-} ciw_t;
+   __u32        et       :  2; // entry type
+   __u32        reserved :  2; // reserved
+   __u32        ct       :  4; // command type
+   __u32        cmd      :  8; // command
+   __u32        count    : 16; // count
+} __attribute__ ((packed)) ciw_t;
 
 Possible CIW entry types are :
 
@@ -245,6 +300,7 @@
 -ENODEV - irq or devno don't specify a known subchannel or device
           number.
 -EINVAL - invalid devinfo value.
+-EUSERS - device is locked by someone else.
 
 Usage Notes :
 
@@ -252,7 +308,7 @@
 calling     get_dev_info() until it returns -ENODEV as there aren't any more
 available devices.
 
-If a device driver wants to request ownership for a specific device it must
+If a device driver wants to request ownership for a specific device, it must
 call request_irq() prior to be able to issue any I/O request for it, including
 above mentioned   device dependent commands.
 
@@ -269,7 +325,7 @@
 numbers configured in the IOCDS. The following routines serve the purpose to
 convert irq values into device numbers and vice versa.
 
-int get_irq_by_devno( unsigned int devno );
+int get_irq_by_devno( __u16 devno );
 
 unsigned int get_devno_by_irq( int irq );
 
@@ -336,6 +392,41 @@
 he specifies, or the buffer he wants to be allocated.
 
 
+read_conf_data() - Read Configuration Data
+
+Retrieve the device dependent configuration data. Please have a look at your 
+device dependent I/O commands for the device specific layout of the node 
+descriptor elements. 
+
+The function is meant to be called without an irq handler be in place. However,
+the irq for the requested device must not be locked or this will cause a 
+deadlock situation ! 
+
+The function may be called enabled or disabled.
+
+int read_conf_data( int irq, void **buffer, int *length, __u8 lpm);
+
+irq    - Specifies the subchannel the configuration data is to be
+         retrieved for.
+buffer - Pointer to a buffer pointer. The read_conf_data() routine
+         will allocate a buffer and initialize the buffer pointer
+         accordingly. It's the device driver's responsability to
+         release the kernel memory if no longer needed. 
+length - Length of the buffer allocated and retrieved.
+lpm    - Logical path mask to be used for retrieving the data. If
+         zero the data is retrieved on the next path available.
+
+The read_conf_data() function returns :
+          0 - Successful completion
+-ENODEV     - irq doesn't specify a valid subchannel number
+-EINVAL     - An invalid parameter was detected
+-EIO        - An irrecoverable I/O error occured or the device is
+              not operational.
+-ENOMEM     - The read_conf_data() routine couldn't obtain storage.
+-EOPNOTSUPP - The device doesn't support the read configuration 
+              data command.
+
+
 request_irq() - Request Device Ownership
 
 As previously discussed a device driver will scan for the devices its supports
@@ -343,6 +434,9 @@
 request_irq() to request ownership for it. This call causes the subchannel to
 be enabled for interrupts if it was found operational.
 
+Note: This function is obsolete and provided for compatibility purposes only. 
+Device drivers should use s390_request_irq_special() instead. 
+
 int request_irq( unsigned int   irq,
                  int          (*handler)( int,
                                           void *,
@@ -354,27 +448,28 @@
 irq      : specifies the subchannel the ownership is requested for
 handler  : specifies the device driver's interrupt handler to be
            called for interrupt processing
-irqflags : IRQ flags, must be 0 (zero) or SA_SAMPLE_RANDOM
+irqflags : IRQ flags, currently ignored
 devname  : device name
 dev_id   : required pointer to a device specific buffer of type
            devstat_t
 
 typedef struct {
-     unsigned int  devno;   /* device number from irb */
-     unsigned int  intparm; /* interrupt parameter */
-     unsigned char cstat;   /* channel status - accumulated */
-     unsigned char dstat;   /* device status - accumulated */
-     unsigned char lpum;    /* last path used mask from irb */
-     unsigned char unused;  /* not used - reserved */
-     unsigned int  flag;    /* flag : see below */
-     unsigned long cpa;     /* CCW addr from irb at prim. status */
-     unsigned int  rescnt;  /* count from irb at primary status */
-     unsigned int  scnt;    /* sense count, if available */
+     __u16         devno;    /* device number, aka. "cuu" from irb */
+     unsigned long intparm;  /* interrupt parameter */
+     __u8          cstat;    /* channel status - accumulated */
+     __u8          dstat;    /* device status - accumulated */
+     __u8          lpum;     /* last path used mask from irb */
+     __u8          unused;   /* not used - reserved */
+     unsigned int  flag;     /* flag : see below */
+     __u32         cpa;      /* CCW address from irb at primary status */
+     __u32         rescnt;   /* res. count from irb at primary status */
+     __u32         scnt;     /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */
      union {
-        irb_t   irb;        /* interruption response block */
-        sense_t sense;      /* sense information */
-        } ii;               /* interrupt information */
-  } devstat_t;
+        irb_t   irb;         /* interruption response block */
+        sense_t sense;       /* sense information */
+     } ii;                /* interrupt information */
+} devstat_t;
+
 
 During request_irq() processing, the devstat_t layout does not matter as it
 won't be used during request_irq() processing. See do_IO() for a functional
@@ -396,9 +491,9 @@
 layer, and the device specific driver. The value passed to request_irq()
 must therefore point to a valid devstat_t type buffer area the device driver
 must preserve for later usage. I.e. it must not be released prior to a call
-to free_irq()
+to free_irq().
 
-The only value parameter irqflags supports is SA_SAMPLE_RANDOM if appropriate.
+Irqflags are currently ignored by the cds layer.
 The Linux/390 kernel does neither know about "fast" interrupt handlers, nor
 does it allow for interrupt sharing. Remember, the term interrupt level (irq),
 device, and subchannel are used interchangeably in Linux/390.
@@ -416,6 +511,126 @@
 therefore not rely on this parameter on function entry.
 
 
+s390_request_irq_special() - Request Device Ownership 
+
+As previously discussed a device driver will scan for the devices its supports 
+by calling get_dev_info(). Once it has found a device it will call 
+request_irq() to request ownership.
+
+Note:  This function replaces request_irq() described previously.
+
+int s390_request_irq_special( 
+                     int                      irq,
+                     io_handler_func_t        io_handler,
+                     not_oper_handler_func_t  not_oper_handler,
+                     unsigned long            irqflags,
+                     const char              *devname,
+                     void                    *dev_id);
+
+irq              : specifies the subchannel the ownership is
+                    requested for
+io_handler       : specifies the device driver's interrupt handler
+                    to be called for interrupt processing
+not_oper_handler : specifies a device driver "not operational" handler
+irqflags         : IRQ flags, currently ignored
+devname          : device name
+dev_id           : required pointer to a device specific buffer of
+                    type devstat_t
+
+
+typedef struct {
+     __u16         devno;    /* device number, aka. "cuu" from irb */
+     unsigned long intparm;  /* interrupt parameter */
+     __u8          cstat;    /* channel status - accumulated */
+     __u8          dstat;    /* device status - accumulated */
+     __u8          lpum;     /* last path used mask from irb */
+     __u8          unused;   /* not used - reserved */
+     unsigned int  flag;     /* flag : see below */
+     __u32         cpa;      /* CCW address from irb at primary status */
+     __u32         rescnt;   /* res. count from irb at primary status */
+     __u32         scnt;     /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */
+     union {
+        irb_t   irb;         /* interruption response block */
+        sense_t sense;       /* sense information */
+     } ii;                   /* interrupt information */
+} devstat_t;
+
+During request_irq() processing, the devstat_t layout does not matter as it 
+won't be used during request_irq() processing. See do_IO() for a functional 
+description of its usage.
+
+typedef  void (* io_handler_func_t) ( int             irq,
+                                      void           *devstat,
+                                      struct pt_regs *rgs);
+
+irq     : IRQ the interrupt handler is called for
+devstat : device status block
+rgs     : obsolete
+
+typedef (void)(* not_oper_handler_func_t)( int irq, 
+                                           int status );
+
+irq    : IRQ the not operational status has been encountered for
+status : device status
+         DEVSTAT_NOT_OPER    - device is not operational
+         DEVSTAT_REVALIDATE  - revalidate device number
+         DEVSTAT_DEVICE_GONE - no such device (irq)  
+
+Note: Revalidate indicates that running under VM the device number has been 
+modified by means of a DEFINE xxxx [as] yyyy command. Therewith device number 
+xxxx was altered to yyyy. It's the device drivers responsibility to decide 
+whether device ownership can be retained.
+
+Gone indicates that the device was detached under VM, or the device number 
+became invalid (native, LPAR). In order to prevent further I/O the IRQ was 
+implicitly freed on behalf of the device driver. The driver must not call 
+free_irq itself.
+
+Not Oper indicates the device became not operational. It's the device driver's 
+responsibility whether it wants to maintain ownership for the IRQ, or not. 
+
+The s390_request_irq_special() function returns :
+      0 - successful completion
+-EINVAL - an invalid parameter was detected
+-EBUSY  - device (subchannel) already owned 
+-ENODEV - the device is not-operational
+-ENOMEM - not enough kernel memory to process request
+
+Usage Notes :
+ 
+While Linux for Intel defines dev_id as a unique identifier for shared 
+interrupt lines, it has a totally different purpose on Linux for S/390. Here 
+it serves as a shared interrupt status area between the generic device support 
+layer and the device specific driver. The value passed to request_irq() must 
+therefore point to a valid devstat_t type buffer area the device driver must 
+preserve for later usage. I.e. it must not be released prior to a call to 
+free_irq().
+ 
+Currently, the value of irqflags is ignored. The Linux for S/390 kernel does 
+neither know about "fast" interrupt handlers, nor does it allow for interrupt 
+sharing. Remember, the term interrupt level (irq), device, and subchannel are 
+used interchangeably in Linux for S/390.
+ 
+Other than request_irq(), this function does allow for a not operational 
+handler to be defined. This handler is called when a device either became not 
+operational, the last path to a device became not operational, or the device 
+was detached from the system. A detach could be a "detach" under VM or that 
+the device became unassigned by the Support Element (SE) or Hardware Management 
+Console (HMC). 
+ 
+If s390_request_irq_special() was called in enabled state, or if multiple CPUs 
+are present, the device may present an interrupt to the specified handler prior 
+to request_irq() return to the caller already ! This includes the possibility 
+of unsolicited interrupts or a pending interrupt status from an earlier 
+solicited I/O request. The device driver must be able to handle this situation 
+properly or the device may become unoperational otherwise !
+
+Although the interrupt handler is defined to be called with a pointer to a 
+struct pt_regs buffer area, this is not implemented by the Linux for S/390 
+platform specific common I/O support layer. The device driver's interrupt 
+handler must therefore not rely on this parameter on function entry.
+
+
 free_irq() - Release Device Ownership
 
 A device driver may call free_irq() to release ownership of a previously
@@ -523,19 +738,19 @@
 
 int do_IO( int            irq,
            ccw1_t        *cpa,
-           unsigned long  intparm,
+           unsigned long  user_intparm,
            unsigned int   lpm,
            unsigned long  flag);
 
-irq     : irq (subchannel) the I/O request is destined for
-cpa     : logical start address of channel program
-intparm : user specific interrupt information; will be presented
-          back to the device driver's interrupt handler. Allows a
-          device driver to associate the interrupt with a
-          particular I/O request.
-lpm     : defines the channel path to be used for a specific I/O
-          request. Valid with flag value DOIO_VALID_LPM only.
-flag    : defines the action to e parformed for I/O processing
+irq          : irq (subchannel) the I/O request is destined for
+cpa          : logical start address of channel program
+user_intparm : user specific interrupt information; will be presented
+	       back to the device driver's interrupt handler. Allows a
+               device driver to associate the interrupt with a
+               particular I/O request.
+lpm          : defines the channel path to be used for a specific I/O
+               request. Valid with flag value DOIO_VALID_LPM only.
+flag         : defines the action to e parformed for I/O processing
 
 Possible flag values are :
 
@@ -543,16 +758,25 @@
 DOIO_VALID_LPM           - LPM input parameter is valid (see usage
                            notes below for details)
 DOIO_WAIT_FOR_INTERRUPT  - wait synchronously for final status
+DOIO_TIMEOUT             - perform a loop while waiting for final status
+			   and fail after a timeout
 DOIO_REPORT_ALL          - report all interrupt conditions
+DOIO_ALLOW_SUSPEND       - channel program may become suspended
+DOIO_DENY_PREFETCH       - don't allow for CCW prefetch; usually
+                           this implies the channel program might
+                           become modified 
+DOIO_CANCEL_ON_TIMEOUT   - do a cancel_IO if there is a timeout waiting
+			   for the channel program to finish (see usage
+                           notes below for details)
 
 The cpa parameter points to the first format 1 CCW of a channel program :
 
 typedef struct {
-   char            cmd_code; /* command code */
-   char            flags;    /* flags, like IDA addressing, etc. */
-   unsigned short  count;    /* byte count */
-   void           *cda;      /* data address */
-} ccw1_t __attribute__ ((aligned(8)));
+      __u8  cmd_code;/* command code */
+      __u8  flags;   /* flags, like IDA adressing, etc. */
+      __u16 count;   /* byte count */
+      __u32 cda;     /* data address */
+} __attribute__ ((packed,aligned(8))) ccw1_t;
 
 with the following CCW flags values defined :
 
@@ -605,6 +829,9 @@
                            successfully be started previously.
 DEVSTAT_FINAL_STATUS     - This is a final interrupt status for the
                            I/O requst identified by intparm.
+DEVSTAT_PCI              - A PCI was received. 
+DEVSTAT_SUSPENDED        - A "suspended" intermediate status was
+                           received.  
 
 If device status DEVSTAT_FLAG_SENSE_AVAIL is indicated in field dev_id->flag,
 field dev_id->scnt describes the numer of device specific sense bytes
@@ -612,9 +839,9 @@
 driver itself is required.
 
 typedef struct {
-   unsigned char res[32];       /* reserved   */
-   unsigned char data[32];      /* sense data */
-} sense_t;
+      __u8          res[32];   /* reserved   */
+      __u8          data[32];  /* sense data */
+   } __attribute__ ((packed)) sense_t;
 
 The device interrupt handler can use the following definitions to investigate
 the primary unit check source coded in sense byte 0 :
@@ -625,6 +852,7 @@
 SNS0_EQUIPMENT_CHECK    0x10
 SNS0_DATA_CHECK         0x08
 SNS0_OVERRUN            0x04
+SNS0_INCOMPL_DOMAIN     0x01
 
 Depending on the device status, multiple of those values may be set together.
 Please refer to the device specific documentation for details.
@@ -661,12 +889,10 @@
 
 Usage Notes :
 
-Prior to call do_IO() the device driver must
-
-assure disabled state, i.e. the I/O mask value in the PSW must be disabled.
-This can be accomplished by calling __save_flags( flags). The current PSW
-flags are preserved and can be restored by __restore_flags( flags) at a
-later time.
+Prior to call do_IO() the device driver must assure disabled state, i.e. the 
+I/O mask value in the PSW must be disabled. This can be accomplished by calling 
+__save_flags( flags). The current PSW flags are preserved and can be restored 
+by __restore_flags( flags) at a later time.
 
 If the device driver violates this rule while running in a uni-processor
 environment an interrupt might be presented prior to the do_IO() routine
@@ -674,7 +900,7 @@
 deadlock situation as the interrupt handler will try to obtain the irq
 lock the device driver still owns (see below) !
 
-the driver must assure to hold the device specific lock. This can be
+The driver must assure to hold the device specific lock. This can be
 accomplished by
 
 (i)  s390irq_spin_lock( irq), or
@@ -705,6 +931,10 @@
 is therewith primarily meant to be used during device driver initialization
 for ease of device setup.
 
+If the device driver is using the DOIO_TIMEOUT parameter, it is a good idea
+also to specify DOIO_CANCEL_ON_TIMEOUT. Otherwise, the failing channel program
+may prevent the execution of any other channel program at the subchannel.
+
 The lpm input parameter might be used for multipath devices shared among
 multiple systems as the Linux/390 CDS isn't grouping channel paths. Therefore
 its use might be required if multiple access paths to a device are available
@@ -757,6 +987,34 @@
 and dev_id->dstat that represent the accumulated subchannel and device status
 information gathered since do_IO() request initiation.
 
+Channel programs that intend to set the suspend flag on a channel command word 
+(CCW)  must start the I/O operation with the DOIO_ALLOW_SUSPEND option or the 
+suspend flag will cause a channel program check. At the time the channel program 
+becomes suspended an intermediate interrupt will be generated by the channel 
+subsystem.
+
+resume_IO() - Resume Channel Program Execution 
+
+If a device driver chooses to suspend the current channel program execution by 
+setting the CCW suspend flag on a particular CCW, the channel program execution 
+is suspended. In order to resume channel program execution the CIO layer 
+provides the resume_IO() routine. 
+
+int resume_IO( int irq);
+
+irq     : irq (subchannel) the halt operation is requested for
+
+The resume_IO() function returns:
+
+        0  - suspended channel program is resumed
+-EBUSY     - status pending
+-ENODEV    - invalid or not-operational subchannel 
+-EINVAL    - resume function not applicable  
+-ENOTCONN  - there is no I/O request pending for completion 
+
+Usage Notes:
+Please have a look at the do_IO()  usage notes for more details on suspended 
+channel programs.
 
 halt_IO() - Halt I/O Request Processing
 
@@ -765,9 +1023,9 @@
 a halt subchannel (HSCH) I/O command. For those purposes the halt_IO() command
 is provided.
 
-int halt_IO( int          irq,     /* subchannel number */
-             int          intparm, /* dummy intparm */
-             unsigned int flag);   /* operation mode */
+int halt_IO( int           irq,     /* subchannel number */
+             unsigned long intparm, /* dummy intparm */
+             unsigned long flag);   /* operation mode */
 
 irq     : irq (subchannel) the halt operation is requested for
 intparm : interruption parameter; value is only used if no I/O
@@ -867,7 +1125,7 @@
 reset_cons_dev - Reset Console Device
 
 This routine allows for resetting the console device specification. See
-set_cons_dev() for details.
+wait_cons_dev() for details.
 
 int reset_cons_dev( int irq);
 
diff -urN linux-2.4.22-pre2/Documentation/sonypi.txt linux-2.4.22-pre3/Documentation/sonypi.txt
--- linux-2.4.22-pre2/Documentation/sonypi.txt	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/Documentation/sonypi.txt	2003-07-05 18:09:34.000000000 -0700
@@ -130,7 +130,7 @@
 	  tested) when using the driver with the fnkeyinit parameter. I cannot
 	  reproduce it on my laptop and not all users have this problem.
 	  This happens because the fnkeyinit parameter enables the ACPI 
-	  mode (but without additionnal ACPI control, like processor 
+	  mode (but without additional ACPI control, like processor 
 	  speed handling etc). Use ACPI instead of APM if it works on your
 	  laptop.
 	
diff -urN linux-2.4.22-pre2/Documentation/x86_64/boot-options.txt linux-2.4.22-pre3/Documentation/x86_64/boot-options.txt
--- linux-2.4.22-pre2/Documentation/x86_64/boot-options.txt	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/Documentation/x86_64/boot-options.txt	2003-07-05 18:09:34.000000000 -0700
@@ -0,0 +1,151 @@
+AMD64 specific boot options
+
+There are many others (usually documented in driver documentation), but 
+only the AMD64 specific ones are listed here.
+
+Machine check
+
+(see the Opteron BIOS&Kernel manual for more details on the banks etc.)
+
+   mce=off disable machine check
+   mce=nok8 disable k8 specific features
+   mce=disable<NUMBER> disable bank NUMBER
+   mce=enable<NUMBER> enable bank number
+   mce=device	Enable more machine check options in Northbridge. 
+		Can be useful for device driver debugging.
+   mce=NUMBER mcheck timer interval number seconds. 
+   Can be also comma separated in a single mce=
+
+   nomce (for compatibility with i386): same as mce=off
+
+APICs
+
+   nolocalapic   Don't use a local or IO-APIC. This should only
+   		 be needed if you have a buggy BIOS. The newer
+		 kernels already turn it off by default if the
+		 BIOS didn't enable the local APIC, so it will
+		 be hopefully not needed.
+		 Note this code path is not very well tested, you are on
+		 your own.
+		
+   apic		 Use IO-APIC. Default
+
+   noapic	 Don't use the IO-APIC. 
+		 Also only lightly tested. 
+
+   pirq=...	 See Documentation/i386/IO-APIC.txt		 
+    
+Early Console
+
+   syntax: earlyprintk=vga
+           earlyprintk=serial[,ttySn[,baudrate]] 
+
+   The early console is useful when the kernel crashes before the
+   normal console is initialized. It is not enabled by 
+   default because it has some cosmetic problems.	   
+   Append ,keep to not disable it when the real console takes over.
+   Only vga or serial at a time, not both.
+   Currently only ttyS0 and ttyS1 are supported. 
+   Interaction with the standard serial driver is not very good. 
+   The VGA output is eventually overwritten by the real console.		 
+
+Timing
+
+  notsc
+  Don't use the CPU time stamp counter to read the wall time. 
+  This can be used to work around timing problems on multiprocessor systems 
+  with not properly synchronized CPUs. Only useful with a SMP kernel
+
+  report_lost_ticks
+  Report when timer interrupts are lost because some code turned off
+  interrupts for too long. 
+
+  nmi_watchdog=NUMBER
+  NUMBER can be: 
+  0 don't use an NMI watchdog
+  1 use the IO-APIC timer for the NMI watchdog
+  2 use the local APIC for the NMI watchdog using a performance counter. Note
+  This will use one performance counter.
+
+Idle loop
+
+  idle=poll
+  Don't do power saving in the idle loop using HLT, but poll for rescheduling 
+  event. This will make the CPUs eat a lot more power, but may be useful 
+  to get slightly better performance in multiprocessor benchmarks. It also
+  makes some profiling using performance counters more accurate.
+
+Rebooting
+
+   reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
+   bios	  Use the CPU reboto vector for warm reset
+   warm   Don't set the cold reboot flag
+   cold   Set the cold reboto flag
+   triple Force a triple fault (init)
+   kbd    Use the keyboard controller. cold reset (default)
+
+   Using warm reset will be much faster especially on big memory
+   systems because the BIOS will not go through the memory check.
+   Disadvantage is that not all hardware will be completely reinitialized
+   on reboot so there may be boot problems on some systems.
+   
+Non Executable Mappings
+
+  noexec=on|off
+
+  on      Enable
+  off     Disable
+  noforce (default) Don't enable by default for heap/stack/data,
+          but allow PROT_EXEC to be effective
+
+  noexec32=opt{,opt} 
+
+  Control the no exec default for 32bit processes. 
+  Requires noexec=on or noexec=noforce to be effective.
+
+  Valid options: 
+     all,on    Heap,stack,data is non executable. 	
+     off       (default) Heap,stack,data is executable
+     stack     Stack is non executable, heap/data is.
+     force     Don't imply PROT_EXEC for PROT_READ 
+     compat    (default) Imply PROT_EXEC for PROT_READ
+ 
+SMP 
+
+  nosmp	Only use a single CPU
+
+  maxcpus=NUMBER only use upto NUMBER CPUs
+
+  cpumask=MASK   only use cpus with bits set in mask
+
+NUMA
+
+  numa=off	Only set up a single NUMA node spanning all memory.
+
+
+ACPI 
+
+  acpi=off	Don't enable ACPI
+  
+PCI
+
+  pci=off	Don't use PCI
+  pci=conf1	Use conf1 access.
+  pci=conf2	Use conf2 access.
+  pci=rom	Assign ROMs.
+  pci=assign-busses    Assign busses
+  pci=irqmask=MASK	       Set PCI interrupt mask to MASK
+  pci=lastbus=NUMBER	       Scan upto NUMBER busses, no matter what the mptable says.
+
+IOMMU
+
+  iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]]
+   size  set size of iommu (in bytes) 
+   noagp don't initialize the AGP driver and use full aperture.
+   off   don't use the IOMMU
+   leak  turn on simple iommu leak tracing (only when CONFIG_IOMMU_LEAK is on)
+   memaper[=order] allocate an own aperture over RAM with size 32MB^order.
+   noforce don't force IOMMU usage. Should be fastest.
+   force  Force IOMMU and turn on unmap debugging.  
+
+
diff -urN linux-2.4.22-pre2/MAINTAINERS linux-2.4.22-pre3/MAINTAINERS
--- linux-2.4.22-pre2/MAINTAINERS	2003-07-05 18:09:16.000000000 -0700
+++ linux-2.4.22-pre3/MAINTAINERS	2003-07-05 18:09:34.000000000 -0700
@@ -445,6 +445,15 @@
 W:	http://developer.axis.com
 S:	Maintained
 
+CRYPTO API
+P:	James Morris
+M:	jmorris@intercode.com.au
+P:	David S. Miller
+M:	davem@redhat.com
+W	http://samba.org/~jamesm/crypto/
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 CYBERPRO FB DRIVER
 P:	Russell King
 M:	rmk@arm.linux.org.uk
@@ -840,7 +849,7 @@
 
 IMS TWINTURBO FRAMEBUFFER DRIVER
 P:	Paul Mundt
-M:	lethal@chaoticdreams.org
+M:	lethal@linux-sh.org
 L:	linux-fbdev-devel@lists.sourceforge.net
 S:	Maintained
 
@@ -1381,9 +1390,9 @@
 P:	M. R. Brown
 M:	mrbrown@0xd6.org
 P:	Paul Mundt
-M:	lethal@0xd6.org
+M:	lethal@linux-sh.org
 L:	linux-fbdev-devel@lists.sourceforge.net
-W:	http://www.linuxdc.org
+L:	linuxsh-dev@lists.sourceforge.net
 S:	Maintained
 
 PPP PROTOCOL DRIVERS AND COMPRESSORS
@@ -1648,19 +1657,35 @@
 W:	http://www.stradis.com/
 S:	Maintained
 
-SUPERH
+SUPERH (sh)
+P:	Paul Mundt
+M:	lethal@linux-sh.org
 P:	Niibe Yutaka
 M:	gniibe@m17n.org
 P:	Kazumoto Kojima
 M:	kkojima@rr.iij4u.or.jp
+L:	linuxsh-dev@lists.sourceforge.net
 L:	linux-sh@m17n.org
+W:	http://www.linux-sh.org
 W:	http://www.m17n.org/linux-sh/
 W:	http://www.rr.iij4u.or.jp/~kkojima/linux-sh4.html
 S:	Maintained
 
+SUPERH64 (sh64)
+P:	Paul Mundt
+M:	lethal@linux-sh.org
+P:	Richard Curnow
+M:	richard.curnow@superh.com
+P:	Benedict Gaster
+M:	benedict.gaster@superh.com
+L:	linuxsh-shmedia-dev@lists.sourceforge.net
+W:	http://www.linux-sh.org
+W:	http://linux-shmedia.bkbits.net
+S:	Maintained
+
 SUPERH WATCHDOG
 P:	Paul Mundt
-M:	lethal@0xd6.org
+M:	lethal@linux-sh.org
 L:	linuxsh-dev@lists.sourceforge.net
 W:	http://www.linuxsh.org
 S:	Maintained
diff -urN linux-2.4.22-pre2/Makefile linux-2.4.22-pre3/Makefile
--- linux-2.4.22-pre2/Makefile	2003-07-05 18:09:16.000000000 -0700
+++ linux-2.4.22-pre3/Makefile	2003-07-05 18:09:34.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 22
-EXTRAVERSION = -pre2
+EXTRAVERSION = -pre3
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -40,10 +40,13 @@
 MODFLAGS	= -DMODULE
 CFLAGS_KERNEL	=
 PERL		= perl
+AWK		= awk
+RPM 		:= $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
+		    	else echo rpm; fi)
 
 export	VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \
 	CONFIG_SHELL TOPDIR HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
-	CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES GENKSYMS MODFLAGS PERL
+	CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES GENKSYMS MODFLAGS PERL AWK
 
 all:	do-it-all
 
@@ -125,7 +128,7 @@
 NETWORKS	=net/network.o
 
 LIBS		=$(TOPDIR)/lib/lib.a
-SUBDIRS		=kernel drivers mm fs net ipc lib
+SUBDIRS		=kernel drivers mm fs net ipc lib crypto
 
 DRIVERS-n :=
 DRIVERS-y :=
@@ -190,6 +193,7 @@
 DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o
 DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
 DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o
+DRIVERS-$(CONFIG_CRYPTO) += crypto/crypto.o
 
 DRIVERS := $(DRIVERS-y)
 
@@ -570,5 +574,5 @@
 	rm $(KERNELPATH) ; \
 	cd $(TOPDIR) ; \
 	. scripts/mkversion > .version ; \
-	rpm -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
+	$(RPM) -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
 	rm $(TOPDIR)/../$(KERNELPATH).tar.gz
diff -urN linux-2.4.22-pre2/arch/alpha/config.in linux-2.4.22-pre3/arch/alpha/config.in
--- linux-2.4.22-pre2/arch/alpha/config.in	2003-07-05 18:09:16.000000000 -0700
+++ linux-2.4.22-pre3/arch/alpha/config.in	2003-07-05 18:09:34.000000000 -0700
@@ -455,4 +455,5 @@
 
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -urN linux-2.4.22-pre2/arch/alpha/kernel/Makefile linux-2.4.22-pre3/arch/alpha/kernel/Makefile
--- linux-2.4.22-pre2/arch/alpha/kernel/Makefile	2003-07-05 18:09:16.000000000 -0700
+++ linux-2.4.22-pre3/arch/alpha/kernel/Makefile	2003-07-05 18:09:34.000000000 -0700
@@ -45,7 +45,8 @@
 	    sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_rx164.o \
 	    sys_wildfire.o sys_marvel.o \
 	    err_titan.o err_marvel.o \
-	    irq_pyxis.o srmcons.o gct.o
+	    irq_pyxis.o srmcons.o gct.o \
+	    es1888.o smc37c669.o smc37c93x.o ns87312.o
 
 else
 
diff -urN linux-2.4.22-pre2/arch/alpha/kernel/core_t2.c linux-2.4.22-pre3/arch/alpha/kernel/core_t2.c
--- linux-2.4.22-pre2/arch/alpha/kernel/core_t2.c	2003-07-05 18:09:16.000000000 -0700
+++ linux-2.4.22-pre3/arch/alpha/kernel/core_t2.c	2003-07-05 18:09:34.000000000 -0700
@@ -508,10 +508,17 @@
 	*(vulp)T2_HAE_1 = 0; mb(); /* Sparse MEM HAE */
 	*(vulp)T2_HAE_2 = 0; mb(); /* Sparse I/O HAE */
 	*(vulp)T2_HAE_3 = 0; mb(); /* Config Space HAE */
-#if 0
-	/* !!! DO NOT EVER TOUCH THIS !!! */
-	*(vulp)T2_HAE_4 = 0; mb(); /* Dense MEM HAE */
-#endif
+
+	/*
+	 * We also now zero out HAE_4, the dense memory HAE, so that
+	 * we need not account for its "offset" when accessing dense
+	 * memory resources which we allocated in our normal way. This
+	 * HAE would need to stay untouched were we to keep the SRM
+	 * resource settings.
+	 *
+	 * Thus we can now run standard X servers on SABLE/LYNX. :-)
+	 */
+	*(vulp)T2_HAE_4 = 0; mb();
 }
 
 void
diff -urN linux-2.4.22-pre2/arch/arm/Makefile linux-2.4.22-pre3/arch/arm/Makefile
--- linux-2.4.22-pre2/arch/arm/Makefile	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/Makefile	2003-07-05 18:09:35.000000000 -0700
@@ -8,8 +8,15 @@
 # Copyright (C) 1995-2001 by Russell King
 
 LINKFLAGS	:=-p -X -T arch/arm/vmlinux.lds
+OBJCOPYFLAGS	:=-O binary -R .note -R .comment -S
 GZFLAGS		:=-9
-CFLAGS		+=-fno-common -pipe
+CFLAGS		+=-Uarm -fno-common -pipe
+
+ifeq ($(CONFIG_FRAME_POINTER),y)
+CFLAGS		:=$(CFLAGS:-fomit-frame-pointer=-mapcs -mno-sched-prolog)
+endif
+
+CFLAGS		:=$(CFLAGS:-O2=-Os)
 
 ifeq ($(CONFIG_DEBUG_INFO),y)
 CFLAGS		+=-g
@@ -24,10 +31,13 @@
 apcs-$(CONFIG_CPU_26)		:=-mapcs-26 -mcpu=arm3 -Os
 
 # This selects which instruction set is used.
+# Note that GCC is lame - it doesn't numerically define an
+# architecture version macro, but instead defines a whole
+# series of macros.
 arch-y				:=
-arch-$(CONFIG_CPU_32v3)		:=-march=armv3
-arch-$(CONFIG_CPU_32v4)		:=-march=armv4
-arch-$(CONFIG_CPU_32v5)		:=-march=armv5
+arch-$(CONFIG_CPU_32v3)		:=-D__LINUX_ARM_ARCH__=3 -march=armv3
+arch-$(CONFIG_CPU_32v4)		:=-D__LINUX_ARM_ARCH__=4 -march=armv4
+arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 -march=armv5
 
 # This selects how we optimise for the processor.
 tune-y				:=
@@ -40,12 +50,12 @@
 tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
 tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
 
-CFLAGS_BOOT	:=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float
-CFLAGS		+=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float
+CFLAGS_BOOT	:=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
+CFLAGS		+=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
 AFLAGS		+=$(apcs-y) $(arch-y) -mno-fpu -msoft-float
 
 ifeq ($(CONFIG_CPU_26),y)
-PROCESSOR	 = armo
+PROCESSOR	:= armo
   ifeq ($(CONFIG_ROM_KERNEL),y)
     DATAADDR	 = 0x02080000
     TEXTADDR	 = 0x03800000
@@ -81,6 +91,10 @@
 INCDIR		 = cl7500
 endif
 
+ifeq ($(CONFIG_ARCH_RISCSTATION),y)
+MACHINE		 = riscstation
+endif
+
 ifeq ($(CONFIG_FOOTBRIDGE),y)
 MACHINE		 = footbridge
 INCDIR		 = ebsa285
@@ -121,12 +135,16 @@
 MACHINE		 = integrator
 endif
 
+ifeq ($(CONFIG_ARCH_AT91RM9200),y)
+MACHINE		 = at91rm9200
+endif
+
 ifeq ($(CONFIG_ARCH_MX1ADS),y)
 MACHINE		 = mx1ads
 endif
 
 ifeq ($(CONFIG_ARCH_CAMELOT),y)
-MACHINE          = epxa10db
+MACHINE          = epxa
 endif
 
 ifeq ($(CONFIG_ARCH_CLPS711X),y)
@@ -135,19 +153,23 @@
 endif
 
 ifeq ($(CONFIG_ARCH_FORTUNET),y)
-TEXTADDR	 = 0xc0008000
+TEXTADDR	 = 0xc0208000
 endif
 
 ifeq ($(CONFIG_ARCH_ANAKIN),y)
 MACHINE		 = anakin
 endif
 
-export	MACHINE PROCESSOR TEXTADDR GZFLAGS CFLAGS_BOOT
+ifeq ($(CONFIG_ARCH_OMAHA),y)
+MACHINE                = omaha
+endif
+
+export	MACHINE PROCESSOR TEXTADDR GZFLAGS CFLAGS_BOOT OBJCOPYFLAGS
 
 # Only set INCDIR if its not already defined above
 # Grr, ?= doesn't work as all the other assignment operators do.  Make bug?
 ifeq ($(origin INCDIR), undefined)
-INCDIR		:= $(MACHINE)
+INCDIR		:=$(MACHINE)
 endif
 
 ifeq ($(origin DATAADDR), undefined)
@@ -161,32 +183,42 @@
 CORE_FILES	:= $(MACHDIR)/$(MACHINE).o $(CORE_FILES)
 endif
 
-HEAD		:= arch/arm/kernel/head-$(PROCESSOR).o \
-		   arch/arm/kernel/init_task.o
-SUBDIRS		+= arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe
-CORE_FILES	:= arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
-LIBS		:= arch/arm/lib/lib.a $(LIBS)
+HEAD		:=arch/arm/kernel/head-$(PROCESSOR).o \
+		  arch/arm/kernel/init_task.o
+SUBDIRS		+=arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe
+CORE_FILES	:=arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
+LIBS		:=arch/arm/lib/lib.a $(LIBS)
 
 ifeq ($(CONFIG_FPE_NWFPE),y)
-LIBS		:= arch/arm/nwfpe/math-emu.o $(LIBS)
+LIBS		:=arch/arm/nwfpe/math-emu.o $(LIBS)
 endif
 
 # Only include fastfpe if it is part of the kernel tree.
-FASTFPE		:= arch/arm/fastfpe
+FASTFPE		:=arch/arm/fastfpe
 ifeq ($(FASTFPE),$(wildcard $(FASTFPE)))
-SUBDIRS		+= $(FASTFPE)
+SUBDIRS		+=$(FASTFPE)
 ifeq ($(CONFIG_FPE_FASTFPE),y)
-LIBS		:= arch/arm/fastfpe/fast-math-emu.o $(LIBS)
+LIBS		:=arch/arm/fastfpe/fast-math-emu.o $(LIBS)
+endif
 endif
+
+ifeq ($(findstring y,$(CONFIG_USB_OHCI_SA1111) $(CONFIG_USB_OHCI_AT91)),y)
+   SUBDIRS	+=arch/arm/common
+   CORE_FILES	+=arch/arm/common/nopci.o
 endif
 
 ifeq ($(findstring y,$(CONFIG_ARCH_CLPS7500) $(CONFIG_ARCH_L7200)),y)
-SUBDIRS		+= drivers/acorn/char
-DRIVERS		+= drivers/acorn/char/acorn-char.o
+SUBDIRS		+=drivers/acorn/char
+DRIVERS		+=drivers/acorn/char/acorn-char.o
+endif
+
+ifeq ($(CONFIG_ARCH_RISCSTATION),y)
+SUBDIRS		+=drivers/acorn/char
+DRIVERS		+=drivers/acorn/char/acorn-char.o
 endif
 
-MAKEBOOT	 = $(MAKE) -C arch/$(ARCH)/boot
-MAKETOOLS	 = $(MAKE) -C arch/$(ARCH)/tools
+MAKEBOOT	 =$(MAKE) -C arch/$(ARCH)/boot
+MAKETOOLS	 =$(MAKE) -C arch/$(ARCH)/tools
 
 # The following is a hack to get 'constants.h' up
 # to date before starting compilation
@@ -194,15 +226,44 @@
 $(patsubst %,_dir_%, $(SUBDIRS)): maketools
 $(patsubst %,_modsubdir_%,$(MOD_DIRS)): maketools
 
-symlinks: archsymlinks
+symlinks: include/asm-arm/.arch include/asm-arm/.proc
 
-archsymlinks:
-	$(RM) include/asm-arm/arch include/asm-arm/proc
-	(cd include/asm-arm; ln -sf arch-$(INCDIR) arch; ln -sf proc-$(PROCESSOR) proc)
+#	Update machine arch and proc symlinks if something which affects
+#	them changed.  We use .arch and .proc to indicate when they were
+#	updated last, otherwise make uses the target directory mtime.
+
+include/asm-arm/.arch: $(wildcard include/config/arch/*.h)
+ifneq ("$(INCDIR)","")
+	@echo '  Making asm-arm/arch -> asm-arm/arch-$(INCDIR) symlink'
+	@rm -f include/asm-arm/arch
+	@ln -sf arch-$(INCDIR) include/asm-arm/arch
+	@touch $@
+else
+	@echo '  No architecture defined.  You may want to use a pre-packaged config.  make a5k_config, ebsa110_config, footbridge_config, etc.'
+endif
+
+include/asm-arm/.proc: $(wildcard include/config/cpu/32.h) $(wildcard include/config/cpu/26.h)
+ifneq ("$(INCDIR)","")
+	@echo '  Making asm-arm/proc -> asm-arm/proc-$(PROCESSOR) symlink'
+	@rm -f include/asm-arm/proc
+	@ln -sf proc-$(PROCESSOR) include/asm-arm/proc
+	@touch $@
+else
+	@echo '  No architecture defined.  You may want to use a pre-packaged config.  make a5k_config, ebsa110_config, footbridge_config, etc.'
+endif
+
+.PHONY: maketools
+maketools: include/asm-arm/.arch include/asm-arm/.proc \
+        include/asm-arm/constants.h include/linux/version.h checkbin
+	@$(MAKETOOLS)
 
 vmlinux: arch/arm/vmlinux.lds
 
-arch/arm/vmlinux.lds: $(LDSCRIPT) dummy
+arch/arm/vmlinux.lds: arch/arm/Makefile $(LDSCRIPT) \
+	$(wildcard include/config/cpu/32.h) \
+	$(wildcard include/config/cpu/26.h) \
+	$(wildcard include/config/arch/*.h)
+	@echo '  Generating $@'
 	@sed 's/TEXTADDR/$(TEXTADDR)/;s/DATAADDR/$(DATAADDR)/' $(LDSCRIPT) >$@
 
 arch/arm/kernel arch/arm/mm arch/arm/lib: dummy
@@ -216,39 +277,37 @@
 
 MRPROPER_FILES	+= \
 	arch/arm/tools/constants.h* \
-	include/asm-arm/arch \
-	include/asm-arm/proc \
+	include/asm-arm/arch include/asm-arm/.arch \
+	include/asm-arm/proc include/asm-arm/.proc \
 	include/asm-arm/constants.h* \
 	include/asm-arm/mach-types.h
 
 # We use MRPROPER_FILES and CLEAN_FILES now
-archmrproper:
+archmrproper: FORCE
 	@/bin/true
 
-archclean:
+archclean: FORCE
 	@$(MAKEBOOT) clean
 
-archdep: scripts/mkdep archsymlinks
+archdep: scripts/mkdep symlinks
 	@$(MAKETOOLS) dep
 	@$(MAKEBOOT) dep
 
-# we need version.h
-maketools: checkbin include/linux/version.h
-	@$(MAKETOOLS) all
-
-# Ensure this is ld "2.9.4" or later
+# Ensure this is ld "2.9.5" or later
 NEW_LINKER	:= $(shell $(LD) --gc-sections --version >/dev/null 2>&1; echo $$?)
 
 ifneq ($(NEW_LINKER),0)
-checkbin:
+checkbin: FORCE
 	@echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.'
 	@echo '*** Please upgrade your binutils to 2.9.5.'
 	@false
 else
-checkbin:
+checkbin: FORCE
 	@true
 endif
 
+.PHONY: FORCE
+
 # My testing targets (that short circuit a few dependencies)
 zImg:;	@$(MAKEBOOT) zImage
 Img:;	@$(MAKEBOOT) Image
diff -urN linux-2.4.22-pre2/arch/arm/boot/Makefile linux-2.4.22-pre3/arch/arm/boot/Makefile
--- linux-2.4.22-pre2/arch/arm/boot/Makefile	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/Makefile	2003-07-05 18:09:35.000000000 -0700
@@ -5,34 +5,42 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 1995-2000 Russell King
+# Copyright (C) 1995-2002 Russell King
 #
 
 SYSTEM	=$(TOPDIR)/vmlinux
 
+# Note: the following conditions must always be true:
+#  ZRELADDR == virt_to_phys(TEXTADDR)
+#   PARAMS_PHYS must be with 4MB of ZRELADDR
+#   INITRD_PHYS must be in RAM
+
 ifeq ($(CONFIG_CPU_26),y)
-ZTEXTADDR	 = 0x02080000
+ZRELADDR	 = 0x02080000
 PARAMS_PHYS	 = 0x0207c000
 INITRD_PHYS	 = 0x02180000
-INITRD_VIRT	 = 0x02180000
 endif
 
 ifeq ($(CONFIG_ARCH_RPC),y)
-ZTEXTADDR	 = 0x10008000
+ZRELADDR	 = 0x10008000
+PARAMS_PHYS	 = 0x10000100
+INITRD_PHYS	 = 0x18000000
+endif
+
+ifeq ($(CONFIG_ARCH_RISCSTATION),y)
+ZRELADDR	 = 0x10008000
 PARAMS_PHYS	 = 0x10000100
 INITRD_PHYS	 = 0x18000000
-INITRD_VIRT	 = 0xc8000000
 endif
 
 ifeq ($(CONFIG_ARCH_CLPS7500),y)
-ZTEXTADDR	 = 0x10008000
+ZRELADDR	 = 0x10008000
 endif
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
-ZTEXTADDR	 = 0x00008000
+ZRELADDR	 = 0x00008000
 PARAMS_PHYS	 = 0x00000400
 INITRD_PHYS	 = 0x00800000
-INITRD_VIRT	 = 0xc0800000
 endif
 
 ifeq ($(CONFIG_ARCH_SHARK),y)
@@ -41,126 +49,114 @@
 endif
 
 ifeq ($(CONFIG_FOOTBRIDGE),y)
-ZTEXTADDR	 = 0x00008000
+ZRELADDR	 = 0x00008000
 PARAMS_PHYS	 = 0x00000100
 INITRD_PHYS	 = 0x00800000
-INITRD_VIRT	 = 0xc0800000
 endif
 
 ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
-ZTEXTADDR	 = 0x00008000
+ZRELADDR	 = 0x00008000
 PARAMS_PHYS	 = 0x00000100
 INITRD_PHYS	 = 0x00800000
-INITRD_VIRT	 = 0xc0800000
+endif
+
+ifeq ($(CONFIG_ARCH_AT91RM9200),y)
+ZRELADDR	 = 0x20008000
 endif
 
 ifeq ($(CONFIG_ARCH_MX1ADS),y)
-ZTEXTADDR	 = 0x08008000
+ZRELADDR	 = 0x08008000
 endif
 
 ifeq ($(CONFIG_ARCH_CAMELOT),y)
-ZTEXTADDR	 = 0x00008000
+ZRELADDR	 = 0x00008000
 endif
 
 ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
-ZTEXTADDR	 = 0x40008000
+ZRELADDR	 = 0x40008000
 endif
 
 ifeq ($(CONFIG_ARCH_L7200),y)
-# RAM based kernel
-#ZTEXTADDR	 = 0xf0400000
-#ZRELADDR	 = 0xf0008000
-
-# FLASH based kernel
-ZTEXTADDR	 = 0x00010000
 ZRELADDR	 = 0xf0008000
-ZBSSADDR	 = 0xf03e0000
 endif
 
 # The standard locations for stuff on CLPS711x type processors
 ifeq ($(CONFIG_ARCH_CLPS711X),y)
-ZTEXTADDR	 = 0xc0028000
+ZRELADDR	 = 0xc0028000
 PARAMS_PHYS	 = 0xc0000100
 endif
 
 # Should probably have some agreement on these...
 ifeq ($(CONFIG_ARCH_P720T),y)
 INITRD_PHYS	 = 0xc0400000
-INITRD_VIRT	 = 0xc0400000
 endif
 ifeq ($(CONFIG_ARCH_CDB89712),y)
 INITRD_PHYS	 = 0x00700000
-INITRD_VIRT	 = 0xc0300000
+endif
+
+ifeq ($(CONFIG_ARCH_OMAHA),y)
+ZTEXTADDR	 = 0x0c008000
+PARAMS_PHYS	 = 0x0C000100
+INITRD_PHYS	 = 0x0C800000
+INITRD_VIRT	 = 0x0C800000
 endif
 
 ifeq ($(CONFIG_ARCH_SA1100),y)
-ZTEXTADDR	 = 0xc0008000
 ZRELADDR	 = 0xc0008000
-ifeq ($(CONFIG_SA1100_VICTOR),y)
-  ZTEXTADDR	 = 0x00002000
-  ZBSSADDR	 = 0xc0200000
-endif
-ifeq ($(CONFIG_SA1100_SHERMAN),y)
-  ZTEXTADDR      = 0x00050000   
-  ZBSSADDR       = 0xc0200000
-endif
-ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y)
-  ZTEXTADDR	 = 0xC0200000
-endif
-ifeq ($(CONFIG_SA1100_GRAPHICSMASTER),y)
-  ZTEXTADDR	 = 0xC0400000
-endif
-ifeq ($(CONFIG_SA1100_ADSBITSY),y)
-  ZTEXTADDR	 = 0xC0400000
-endif
-ifeq ($(CONFIG_SA1100_YOPY),y)
-  ZTEXTADDR      = 0x00080000
-  ZBSSADDR       = 0xc0200000
-endif
+# No defconfig file to move this into...
+#ifeq ($(CONFIG_SA1100_YOPY),y)
+#  ZTEXTADDR      = 0x00080000
+#  ZBSSADDR       = 0xc0200000
+#endif
 ifeq ($(CONFIG_SA1111),y)
   ZRELADDR	 = 0xc0208000
 endif
 endif
 
 ifeq ($(CONFIG_ARCH_ANAKIN),y)
-ZTEXTADDR	 = 0x20008000
+ZRELADDR	 = 0x20008000
 endif
 
 #
-# If you don't define ZRELADDR above,
-# then it defaults to ZTEXTADDR
+# We now have a PIC decompressor implementation.  Decompressors running
+# from RAM should not define ZTEXTADDR.  Decompressors running directly
+# from ROM or Flash must define ZTEXTADDR (preferably via the config)
 #
-ifeq ($(ZRELADDR),)
-ZRELADDR	= $(ZTEXTADDR)
+ifeq ($(CONFIG_ZBOOT_ROM),y)
+ZTEXTADDR	=0x$(CONFIG_ZBOOT_ROM_TEXT)
+ZBSSADDR	=0x$(CONFIG_ZBOOT_ROM_BSS)
+else
+ZTEXTADDR	=0
+ZBSSADDR	=ALIGN(4)
 endif
 
-export	SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS INITRD_VIRT PARAMS_PHYS
+export	SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS PARAMS_PHYS
 
-Image:	$(CONFIGURE) $(SYSTEM)
-	$(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) $@
+Image:	$(SYSTEM)
+	$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
 
 bzImage: zImage
 
-zImage:	$(CONFIGURE) compressed/vmlinux
-	$(OBJCOPY) -O binary -R .note -R .comment -S compressed/vmlinux $@
+zImage:	compressed/vmlinux
+	$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
 
 bootpImage: bootp/bootp
-	$(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
+	$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
 
-compressed/vmlinux: $(TOPDIR)/vmlinux dep
+compressed/vmlinux: $(TOPDIR)/vmlinux FORCE
 	@$(MAKE) -C compressed vmlinux
 
-bootp/bootp: zImage initrd
+bootp/bootp: zImage initrd FORCE
 	@$(MAKE) -C bootp bootp
 
 initrd:
-	@test "$(INITRD_VIRT)" != "" || (echo This architecture does not support INITRD; exit -1)
+	@test "$(INITRD_PHYS)" != "" || (echo This machine does not support INITRD; exit -1)
 	@test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1)
 
-install: $(CONFIGURE) Image
+install: Image
 	sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
 
-zinstall: $(CONFIGURE) zImage
+zinstall: zImage
 	sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
 
 clean:
@@ -169,3 +165,5 @@
 	@$(MAKE) -C bootp clean
 
 dep:
+
+FORCE:
diff -urN linux-2.4.22-pre2/arch/arm/boot/bootp/Makefile linux-2.4.22-pre3/arch/arm/boot/bootp/Makefile
--- linux-2.4.22-pre2/arch/arm/boot/bootp/Makefile	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/bootp/Makefile	2003-07-05 18:09:35.000000000 -0700
@@ -5,9 +5,7 @@
 ZSYSTEM		=$(TOPDIR)/arch/arm/boot/zImage
 ZLDFLAGS	=-p -X -T bootp.lds \
 		 --defsym initrd_addr=$(INITRD_PHYS) \
-		 --defsym initrd_virt=$(INITRD_VIRT) \
-		 --defsym params=$(PARAMS_PHYS) \
-		 --defsym kernel_addr=$(ZTEXTADDR)
+		 --defsym params=$(PARAMS_PHYS)
 
 all:		bootp
 
diff -urN linux-2.4.22-pre2/arch/arm/boot/bootp/bootp.lds linux-2.4.22-pre3/arch/arm/boot/bootp/bootp.lds
--- linux-2.4.22-pre2/arch/arm/boot/bootp/bootp.lds	2000-09-18 15:15:24.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/bootp/bootp.lds	2003-07-05 18:09:35.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/boot/bootp/bootp.lds
  *
- *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2000-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -15,13 +15,9 @@
   _text = .;
   .text : {
    _stext = .;
-   _start = .;
-   init.o(.start)
-   kernel_start = .;
+   *(.start)
    kernel.o
-   kernel_len = . - kernel_start;
    . = ALIGN(32);
-   *(.text)
    initrd_start = .;
    initrd.o
    initrd_len = . - initrd_start;
diff -urN linux-2.4.22-pre2/arch/arm/boot/bootp/init.S linux-2.4.22-pre3/arch/arm/boot/bootp/init.S
--- linux-2.4.22-pre2/arch/arm/boot/bootp/init.S	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/bootp/init.S	2003-07-05 18:09:35.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/boot/bootp/init.S
  *
- *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2000-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -11,8 +11,9 @@
  *  r0 through to r3 straight through.
  */
 		.section .start,#alloc,#execinstr
-		.type	_entry, #function
-_entry:		adr	r10, initdata
+		.type	_start, #function
+		.globl	_start
+_start:		adr	r10, initdata
 		ldr	r11, initdata
 		sub	r11, r10, r11		@ work out exec offset
 		b	splitify
@@ -22,17 +23,11 @@
 initdata:	.word	initdata		@ compiled address of this
 		.size	initdata,. - initdata
 
-		.text
 splitify:	adr	r13, data
 		ldmia	r13!, {r4-r6}		@ move the initrd
 		add	r4, r4, r11		@ correction
 		bl	move
 
-		ldmia	r13!, {r4-r6}		@ then the kernel
-		mov	r12, r5
-		add	r4, r4, r11		@ correction
-		bl	move
-
 /*
  * Setup the initrd parameters to pass to the kernel.  This can either be
  * passed in via a param_struct or a tag list.  We spot the param_struct
@@ -52,17 +47,16 @@
 
 		ldr	r9, [r8, #4]		@ get first tag
 		teq	r9, r4
-		bne	taglist			@ ok, we have a tag list
+		beq	taglist			@ ok, we have a tag list
 
 /*
  * We didn't find a valid tag list - create one.
  */
 		str	r4, [r8, #4]
-		mov	r4, #8
+		mov	r4, #(8 >> 2)
 		str	r4, [r8, #0]
 		mov	r4, #0
 		str	r4, [r8, #8]
-
 /*
  * find the end of the tag list, and then add an INITRD tag on the end.
  * If there is already an INITRD tag, then we ignore it; the last INITRD
@@ -70,12 +64,12 @@
  */
 taglist:	ldr	r9, [r8, #0]		@ tag length
 		teq	r9, #0			@ last tag?
-		addne	r8, r8, r9
+		addne	r8, r8, r9, lsl #2
 		bne	taglist
-
-		mov	r4, #16			@ length of initrd tag
+		mov	r4, #(16 >> 2)		@ length of initrd tag
 		mov	r9, #0			@ end of tag list terminator
 		stmia	r8, {r4, r5, r6, r7, r9}
+		adr	r12, kernel_start
 		mov	pc, r12			@ call kernel
 
 /*
@@ -83,6 +77,7 @@
  */
 param_struct:	add	r8, r8, #16*4
 		stmia	r8, {r6,r7}		@ save in param_struct
+		adr	r12, kernel_start
 		mov	pc, r12			@ call kernel
 
 move:		ldmia	r4!, {r7 - r10}		@ move 32-bytes at a time
@@ -97,15 +92,12 @@
 		.word	initrd_addr
 		.word	initrd_len
 
-		.word	kernel_start
-		.word	kernel_addr
-		.word	kernel_len
-
 		.word	0x54410001		@ r4 = ATAG_CORE
-		.word	0x54410005		@ r5 = ATAG_INITRD
-		.word	initrd_virt		@ r6
+		.word	0x54420005		@ r5 = ATAG_INITRD
+		.word	initrd_addr		@ r6
 		.word	initrd_len		@ r7
 		.word	params			@ r8
 
-		.type	kernel_start,#object
 		.type	initrd_start,#object
+
+kernel_start:
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/Makefile linux-2.4.22-pre3/arch/arm/boot/compressed/Makefile
--- linux-2.4.22-pre2/arch/arm/boot/compressed/Makefile	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/Makefile	2003-07-05 18:09:35.000000000 -0700
@@ -9,7 +9,7 @@
 
 HEAD		 = head.o
 OBJS		 = misc.o
-CFLAGS		 = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_BOOT)
+CFLAGS		 = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_BOOT) -fpic -Uarm
 FONTC		 = $(TOPDIR)/drivers/video/font_acorn_8x8.c
 ZLDFLAGS	 = -p -X -T vmlinux.lds
 
@@ -18,7 +18,12 @@
 #
 ifeq ($(CONFIG_ARCH_ACORN),y)
 OBJS		+= ll_char_wr.o font.o
-ZLDFLAGS	+= -defsym params=$(PARAMS_PHYS)
+CFLAGS		+= -DPARAMS_PHYS=$(PARAMS_PHYS)
+endif
+
+ifeq ($(CONFIG_ARCH_RISCSTATION),y)
+OBJS		+= ll_char_wr.o font.o
+CFLAGS		+= -DPARAMS_PHYS=$(PARAMS_PHYS)
 endif
 
 ifeq ($(CONFIG_ARCH_NETWINDER),y)
@@ -33,6 +38,10 @@
 OBJS		+= head-integrator.o
 endif
 
+ifeq ($(CONFIG_ARCH_AT91RM9200),y)
+OBJS		+= head-at91rm9200.o
+endif
+
 ifeq ($(CONFIG_ARCH_MX1ADS),y)
 OBJS		+= head-mx1ads.o
 endif
@@ -60,18 +69,9 @@
 
 ifeq ($(CONFIG_ARCH_SA1100),y)
 OBJS		+= head-sa1100.o
-ifeq ($(CONFIG_SA1100_NANOENGINE),y)
-  OBJS += hw-bse.o
-endif
 endif
 
-SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;
-
-ifneq ($(ZBSSADDR),)
-SEDFLAGS	+= s/BSS_START/$(ZBSSADDR)/
-else
-SEDFLAGS	+= s/BSS_START/ALIGN(4)/
-endif
+SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$(ZBSSADDR)/
 
 LIBGCC		:= $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
 
@@ -80,11 +80,14 @@
 vmlinux:	$(HEAD) $(OBJS) piggy.o vmlinux.lds
 		$(LD) $(ZLDFLAGS) $(HEAD) $(OBJS) piggy.o $(LIBGCC) -o vmlinux
 
-$(HEAD): 	$(HEAD:.o=.S)
+$(HEAD): 	$(HEAD:.o=.S) \
+			$(wildcard $(TOPDIR)/include/config/zboot/rom.h) \
+			$(wildcard $(TOPDIR)/include/config/cpu/32.h) \
+			$(wildcard $(TOPDIR)/include/config/cpu/26.h)
 		$(CC) $(AFLAGS) -traditional -c $(HEAD:.o=.S)
 
 piggy.o:	$(SYSTEM)
-		$(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) piggy
+		$(OBJCOPY) $(OBJCOPYFLAGS) $(SYSTEM) piggy
 		gzip $(GZFLAGS) < piggy > piggy.gz
 		$(LD) -r -o $@ -b binary piggy.gz
 		rm -f piggy piggy.gz
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/head-at91rm9200.S linux-2.4.22-pre3/arch/arm/boot/compressed/head-at91rm9200.S
--- linux-2.4.22-pre2/arch/arm/boot/compressed/head-at91rm9200.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/head-at91rm9200.S	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,15 @@
+/*
+ * linux/arch/arm/boot/compressed/head-at91rm9200.S
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <asm/mach-types.h>
+
+		.section	".start", "ax"
+		mov	r7, #MACH_TYPE_AT91RM9200
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/head-clps7500.S linux-2.4.22-pre3/arch/arm/boot/compressed/head-clps7500.S
--- linux-2.4.22-pre2/arch/arm/boot/compressed/head-clps7500.S	2001-04-12 12:03:50.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/head-clps7500.S	2003-07-05 18:09:35.000000000 -0700
@@ -13,7 +13,7 @@
 		/* This branch is taken if the CPU memory width matches the
 		   actual device in use.  The default at power on is 16 bits
 		   so we must be prepared for a mismatch. */
-		.section ".start", #alloc, #execinstr
+		.section ".start", "ax"
 2:
 		b	1f
 		.word	0xffff
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/head-epxa10db.S linux-2.4.22-pre3/arch/arm/boot/compressed/head-epxa10db.S
--- linux-2.4.22-pre2/arch/arm/boot/compressed/head-epxa10db.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/head-epxa10db.S	2003-07-05 18:09:35.000000000 -0700
@@ -1,5 +1,5 @@
 #include <asm/mach-types.h>
 #include <asm/arch/excalibur.h>
 
-		.section	".start", #alloc, #execinstr
+		.section	".start", "ax"
 		mov	r7, #MACH_TYPE_CAMELOT
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/head-ftvpci.S linux-2.4.22-pre3/arch/arm/boot/compressed/head-ftvpci.S
--- linux-2.4.22-pre2/arch/arm/boot/compressed/head-ftvpci.S	2001-02-08 16:32:44.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/head-ftvpci.S	2003-07-05 18:09:35.000000000 -0700
@@ -13,7 +13,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-	.section        ".start", #alloc, #execinstr
+	.section        ".start", "ax"
 ftv_start:
 	mcr	p15, 0, r0, c7, c5, 0		@ flush I cache
 	mrc	p15, 0, r0, c1, c0
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/head-integrator.S linux-2.4.22-pre3/arch/arm/boot/compressed/head-integrator.S
--- linux-2.4.22-pre2/arch/arm/boot/compressed/head-integrator.S	2001-06-27 14:12:04.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/head-integrator.S	2003-07-05 18:09:35.000000000 -0700
@@ -1,4 +1,4 @@
 #include <asm/mach-types.h>
 
-		.section	".start", #alloc, #execinstr
+		.section	".start", "ax"
 		mov	r7, #MACH_TYPE_INTEGRATOR
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/head-l7200.S linux-2.4.22-pre3/arch/arm/boot/compressed/head-l7200.S
--- linux-2.4.22-pre2/arch/arm/boot/compressed/head-l7200.S	2001-02-08 16:32:44.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/head-l7200.S	2003-07-05 18:09:35.000000000 -0700
@@ -8,12 +8,13 @@
  */
 
 #include <linux/config.h>
+#include <asm/mach-types.h>
 
 #ifndef CONFIG_ARCH_L7200
 #error What am I doing here...
 #endif
 
-		.section        ".start", #alloc, #execinstr
+		.section        ".start", "ax"
 
 __L7200_start:
 		mov	r0, #0x00100000		@ FLASH address of initrd
@@ -26,4 +27,4 @@
 		ble	1b
 
 		mov	r8, #0			@ Zero it out
-		mov	r7, #19			@ Set architecture ID
+		mov	r7, #MACH_TYPE_L7200	@ Set architecture ID
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/head-netwinder.S linux-2.4.22-pre3/arch/arm/boot/compressed/head-netwinder.S
--- linux-2.4.22-pre2/arch/arm/boot/compressed/head-netwinder.S	2000-09-18 15:15:24.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/head-netwinder.S	2003-07-05 18:09:35.000000000 -0700
@@ -1,50 +1,13 @@
 /*
  *  linux/arch/arm/boot/compressed/head-netwinder.S
  *
- *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2000-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define K(a,b,c)	((a) << 24 | (b) << 12 | (c))
+		.section	".start", "ax"
 
-		.section	".start", #alloc, #execinstr
-
-		/*
-		 * check to see if we are running from the correct address.
-		 * If not, we move ourselves in a two stage process.  Firstly,
-		 * we copy the start of the kernel (which includes this code)
-		 * to 0x8000, and then jump to this code to continue with the
-		 * rest (since this code will get overwritten).
-		 */
-		adr	r2, 1f
-		ldmdb	r2, {r9, r10}
-		and	r3, r2, #0xc000
-		teq	r3, #0x8000	@ correctly located?
-		beq	2f		@ skip this code
-		bic	r3, r2, #0xc000
-		orr	r3, r3, #0x8000
-		mov	r0, r3		@ new address if '1'
-		mov	r4, #64		@ number of bytes to copy
-		sub	r5, r10, r9	@ total number of bytes to copy
-		b	1f
-
-		.word	_start
-		.word	__bss_start
-
-1:
-		.rept	4
-		ldmia	r2!, {r6, r9, r10, r11}
-		stmia	r3!, {r6, r9, r10, r11}
-		.endr
-		subs	r4, r4, #64
-		bcs	1b
-		movs	r4, r5		@ remaining length
-		mov	r5, #0		@ no more to copy
-		movne	pc, r0		@ jump back to 1 (in the newly copied
-					@ code)
-		mov	r7, #5		@ only here to fix NeTTroms which dont
-		mov	r8, #2 << 24		@ scheduled for removal in 2.5.xx
-		orr	r8, r8, #5 << 12
-2:
+/*		mov	r7, #5*/
+/*		mov	r8, #0*/
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/head-sa1100.S linux-2.4.22-pre3/arch/arm/boot/compressed/head-sa1100.S
--- linux-2.4.22-pre2/arch/arm/boot/compressed/head-sa1100.S	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/head-sa1100.S	2003-07-05 18:09:35.000000000 -0700
@@ -11,7 +11,7 @@
 #include <linux/linkage.h>
 #include <asm/mach-types.h>
 
-		.section        ".start", #alloc, #execinstr
+		.section        ".start", "ax"
 
 __SA1100_start:
 
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/head-shark.S linux-2.4.22-pre3/arch/arm/boot/compressed/head-shark.S
--- linux-2.4.22-pre2/arch/arm/boot/compressed/head-shark.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/head-shark.S	2003-07-05 18:09:35.000000000 -0700
@@ -16,7 +16,7 @@
 
 #include <asm/assembler.h>
 	
-		.section	".start", #alloc, #execinstr
+		.section	".start", "ax"
 
 		b	__beginning
 	
@@ -38,7 +38,7 @@
 		adr	r1, __ofw_data
 		add	r2, r1, #4
 		mov	lr, pc
-		b	SYMBOL_NAME(ofw_init)
+		b	ofw_init
 		mov	r1, #0
 
 		adr	r2, __mmu_off			@ calculate physical address
@@ -109,7 +109,7 @@
 		add	sp, sp, #128
 		adr	r0, __ofw_data
 		mov	lr, pc
-		b	SYMBOL_NAME(create_params)
+		b	create_params
 	
 		mov	r8, #0
 		mov	r7, #15
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/head.S linux-2.4.22-pre3/arch/arm/boot/compressed/head.S
--- linux-2.4.22-pre2/arch/arm/boot/compressed/head.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/head.S	2003-07-05 18:09:35.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/boot/compressed/head.S
  *
- *  Copyright (C) 1996-1999 Russell King
+ *  Copyright (C) 1996-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,13 @@
  */
 #ifdef DEBUG
 #if defined(CONFIG_DEBUG_DC21285_PORT)
+		.macro	loadsp, rb
+		mov	\rb, #0x42000000
+		.endm
+		.macro	writeb, rb
+		str	\rb, [r3, #0x160]
+		.endm
+#elif defined(CONFIG_FOOTBRIDGE)
 		.macro	loadsp,	rb
 		mov	\rb, #0x7c000000
 		.endm
@@ -40,6 +47,15 @@
 		.macro	writeb, rb
 		strb	\rb, [r3, #0]
 		.endm
+#elif defined(CONFIG_ARCH_AT91RM9200)
+		.macro	loadsp, rb
+		mov	\rb, #0xFF000000	@ BASE_DBGU (we cannot use ldr \reg, =AT91_DBGU_BASE)
+		add	\rb, \rb, #0x00FF0000
+		add	\rb, \rb, #0x0000F200
+		.endm
+		.macro	writeb, rb
+		strb	\rb, [r3, #0x1C]	@ DBGU_THR (Transmitter Holding Register)
+		.endm
 #elif defined(CONFIG_ARCH_SA1100)
 		.macro	loadsp, rb
 		mov	\rb, #0x80000000	@ physical base address
@@ -50,6 +66,11 @@
 #  endif
 		.endm
 		.macro	writeb, rb
+/*
+ * "The ARM peripheral bus does not support byte or half-word operations.
+ * All reads and writes of the UART by the CPU should be wordwide."
+ *   - SA-1100 Developer's Manual, August 1999
+ */
 		str	\rb, [r3, #0x14]	@ UTDR
 		.endm
 #else
@@ -144,33 +165,98 @@
 		 */
 
 		.text
-1:		adr	r2, LC0
-		ldmia	r2, {r2, r3, r4, r5, sp}
+		adr	r0, LC0
+		ldmia	r0, {r1, r2, r3, r4, r5, r6, ip, sp}
+		subs	r0, r0, r1		@ calculate the delta offset
+
+		teq	r0, #0			@ if delta is zero, we're
+		beq	not_relocated		@ running at the address we
+						@ were linked at.
 
-		mov	r0, #0
+		/*
+		 * We're running at a different address.  We need to fix
+		 * up various pointers:
+		 *   r5 - zImage base address
+		 *   r6 - GOT start
+		 *   ip - GOT end
+		 */
+		add	r5, r5, r0
+		add	r6, r6, r0
+		add	ip, ip, r0
+
+#ifndef CONFIG_ZBOOT_ROM
+		/*
+		 * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
+		 * we need to fix up pointers into the BSS region.
+		 *   r2 - BSS start
+		 *   r3 - BSS end
+		 *   sp - stack pointer
+		 */
+		add	r2, r2, r0
+		add	r3, r3, r0
+		add	sp, sp, r0
+
+		/*
+		 * Relocate all entries in the GOT table.
+		 */
+1:		ldr	r1, [r6, #0]
+		add	r1, r1, r0
+		str	r1, [r6], #4
+		cmp	r6, ip
+		blo	1b
+#else
+
+		/*
+		 * Relocate entries in the GOT table.  We only relocate
+		 * the entries that are outside the (relocated) BSS region.
+		 */
+1:		ldr	r1, [r6, #0]
+		cmp	r1, r2			@ entry < bss_start ||
+		cmphs	r3, r1			@ _end < entry
+		addlo	r1, r1, r0
+		str	r1, [r6], #4
+		cmp	r6, ip
+		blo	1b
+
+#endif
+
+not_relocated:	mov	r0, #0
 1:		str	r0, [r2], #4		@ clear bss
 		str	r0, [r2], #4
 		str	r0, [r2], #4
 		str	r0, [r2], #4
 		cmp	r2, r3
-		blt	1b
+		blo	1b
 
-		mrc	p15, 0, r6, c0, c0	@ get processor ID
+		/*
+		 * The C runtime environment should now be setup
+		 * sufficiently.  Turn the cache on, set up some
+		 * pointers, and start decompressing.
+		 */
 		bl	cache_on
 
 		mov	r1, sp			@ malloc space above stack
 		add	r2, sp, #0x10000	@ 64k max
 
-		teq	r4, r5			@ will we overwrite ourselves?
-		moveq	r5, r2			@ decompress after image
-		movne	r5, r4			@ decompress to final location
+/*
+ * Check to see if we will overwrite ourselves.
+ *   r4 = final kernel address
+ *   r5 = start of this image
+ *   r2 = end of malloc space (and therefore this image)
+ * We basically want:
+ *   r4 >= r2 -> OK
+ *   r4 + image length <= r5 -> OK
+ */
+		cmp	r4, r2
+		bhs	wont_overwrite
+		add	r0, r4, #4096*1024	@ 4MB largest kernel size
+		cmp	r0, r5
+		bls	wont_overwrite
 
+		mov	r5, r2			@ decompress after malloc space
 		mov	r0, r5
 		mov	r3, r7
-		bl	SYMBOL_NAME(decompress_kernel)
-
-		teq	r4, r5			@ do we need to relocate
-		beq	call_kernel		@ the kernel?
+		bl	decompress_kernel
 
 		add	r0, r0, #127
 		bic	r0, r0, #127		@ align the kernel length
@@ -185,23 +271,39 @@
  */
 		add	r1, r5, r0		@ end of decompressed kernel
 		adr	r2, reloc_start
-		adr	r3, reloc_end
+		ldr	r3, LC1
+		add	r3, r2, r3
 1:		ldmia	r2!, {r8 - r13}		@ copy relocation code
 		stmia	r1!, {r8 - r13}
 		ldmia	r2!, {r8 - r13}
 		stmia	r1!, {r8 - r13}
 		cmp	r2, r3
-		blt	1b
+		blo	1b
 
 		bl	cache_clean_flush
 		add	pc, r5, r0		@ call relocation code
 
+/*
+ * We're not in danger of overwriting ourselves.  Do this the simple way.
+ *
+ * r4     = kernel execution address
+ * r7     = architecture ID
+ */
+wont_overwrite:	mov	r0, r4
+		mov	r3, r7
+		bl	decompress_kernel
+		b	call_kernel
+
 		.type	LC0, #object
-LC0:		.word	__bss_start
-		.word	_end
-		.word	_load_addr
-		.word	_start
-		.word	user_stack+4096
+LC0:		.word	LC0			@ r1
+		.word	__bss_start		@ r2
+		.word	_end			@ r3
+		.word	_load_addr		@ r4
+		.word	_start			@ r5
+		.word	_got_start		@ r6
+		.word	_got_end		@ ip
+		.word	user_stack+4096		@ sp
+LC1:		.word	reloc_end - reloc_start
 		.size	LC0, . - LC0
 
 /*
@@ -218,22 +320,15 @@
  *  r7 = architecture number
  *  r8 = run-time address of "start"
  * On exit,
- *  r0, r1, r2, r3, r8, r9 corrupted
+ *  r1, r2, r3, r8, r9, r12 corrupted
  * This routine must preserve:
  *  r4, r5, r6, r7
  */
 		.align	5
-cache_on:	ldr	r1, proc_sa110_type
-		eor	r1, r1, r6
-		movs	r1, r1, lsr #5		@ catch SA110 and SA1100
-		beq	1f
-		ldr     r1, proc_sa1110_type
-		eor	r1, r1, r6
-		movs	r1, r1, lsr #4
-@		movne	pc, lr
-		bne	cache_off
-1:
-		sub	r3, r4, #16384		@ Page directory size
+cache_on:	mov	r3, #8			@ cache_on function
+		b	call_cache_fn
+
+__setup_mmu:	sub	r3, r4, #16384		@ Page directory size
 		bic	r3, r3, #0xff		@ Align the pointer
 		bic	r3, r3, #0x3f00
 /*
@@ -248,9 +343,9 @@
 		orr	r1, r1, #3 << 10
 		add	r2, r3, #16384
 1:		cmp	r1, r8			@ if virt > start of RAM
-		orrge	r1, r1, #0x0c		@ set cacheable, bufferable
+		orrhs	r1, r1, #0x0c		@ set cacheable, bufferable
 		cmp	r1, r9			@ if virt > end of RAM
-		bicge	r1, r1, #0x0c		@ clear cacheable, bufferable
+		bichs	r1, r1, #0x0c		@ clear cacheable, bufferable
 		str	r1, [r0], #4		@ 1:1 mapping
 		add	r1, r1, #1048576
 		teq	r0, r2
@@ -269,24 +364,42 @@
 		str	r1, [r0], #4
 		add	r1, r1, #1048576
 		str	r1, [r0]
+		mov	pc, lr
 
+__armv4_cache_on:
+		mov	r12, lr
+		bl	__setup_mmu
 		mov	r0, #0
 		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
-		mcr	p15, 0, r0, c8, c7	@ flush I,D TLBs
-		mcr	p15, 0, r3, c2, c0	@ load page table pointer
+		mcr	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
+		mcr	p15, 0, r3, c2, c0, 0	@ load page table pointer
 		mov	r0, #-1
-		mcr	p15, 0, r0, c3, c0	@ load domain access register
-		mrc	p15, 0, r0, c1, c0
+		mcr	p15, 0, r0, c3, c0, 0	@ load domain access register
+		mrc	p15, 0, r0, c1, c0, 0
 		orr	r0, r0, #0x1000		@ I-cache enable
 #ifndef DEBUG
 		orr	r0, r0, #0x003d		@ Write buffer, mmu
 #endif
-		mcr	p15, 0, r0, c1, c0
-		mov	pc, lr
+		mcr	p15, 0, r0, c1, c0, 0
+		mov	pc, r12
+
+__arm6_cache_on:
+		mov	r12, lr
+		bl	__setup_mmu
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
+		mcr	p15, 0, r0, c5, c0, 0	@ invalidate whole TLB v3
+		mcr	p15, 0, r3, c2, c0, 0	@ load page table pointer
+		mov	r0, #-1
+		mcr	p15, 0, r0, c3, c0, 0	@ load domain access control
+		mov	r0, #0x3d
+		mcr	p15, 0, r0, c1, c0, 0	@ load control register
+		mov	pc, r12
 
 /*
- * This code is relocatable.  It is relocated by the above code to the end
- * of the kernel and executed there.  During this time, we have no stacks.
+ * All code following this line is relocatable.  It is relocated by
+ * the above code to the end of the decompressed kernel image and
+ * executed there.  During this time, we have no stacks.
  *
  * r0     = decompressed kernel length
  * r1-r3  = unused
@@ -307,7 +420,7 @@
 		.endr
 
 		cmp	r5, r8
-		blt	1b
+		blo	1b
 		debug_reloc_end
 
 call_kernel:	bl	cache_clean_flush
@@ -317,47 +430,117 @@
 		mov	pc, r4			@ call kernel
 
 /*
- * Here follow the relocatable cache support functions for
- * the various processors.
+ * Here follow the relocatable cache support functions for the
+ * various processors.  This is a generic hook for locating an
+ * entry and jumping to an instruction at the specified offset
+ * from the start of the block.  Please note this is all position
+ * independent code.
+ *
+ *  r1  = corrupted
+ *  r2  = corrupted
+ *  r3  = block offset
+ *  r6  = corrupted
+ *  r12 = corrupted
  */
 
-		.type	proc_sa110_type,#object
-proc_sa110_type:
-		.word	0x4401a100
-		.size	proc_sa110_type, . - proc_sa110_type
-
-		.type	proc_sa1110_type,#object
-proc_sa1110_type:
-		.word	0x6901b110
-		.size	proc_sa1110_type, . - proc_sa1110_type
+call_cache_fn:	adr	r12, proc_types
+		mrc	p15, 0, r6, c0, c0	@ get processor ID
+1:		ldr	r1, [r12, #0]		@ get value
+		ldr	r2, [r12, #4]		@ get mask
+		eor	r1, r1, r6		@ (real ^ match)
+		tst	r1, r2			@       & mask
+		addeq	pc, r12, r3		@ call cache function
+		add	r12, r12, #4*5
+		b	1b
+
+/*
+ * Table for cache operations.  This is basically:
+ *   - CPU ID match
+ *   - CPU ID mask
+ *   - 'cache on' method instruction
+ *   - 'cache off' method instruction
+ *   - 'cache flush' method instruction
+ *
+ * We match an entry using: ((real_id ^ match) & mask) == 0
+ *
+ * Writethrough caches generally only need 'on' and 'off'
+ * methods.  Writeback caches _must_ have the flush method
+ * defined.
+ */
+		.type	proc_types,#object
+proc_types:
+		.word	0x41560600		@ ARM6/610
+		.word	0xffffffe0
+		b	__arm6_cache_off	@ works, but slow
+		b	__arm6_cache_off
+		mov	pc, lr
+@		b	__arm6_cache_on		@ untested
+@		b	__arm6_cache_off
+@		b	__armv3_cache_flush
+
+		.word	0x41007000		@ ARM7/710
+		.word	0xfff8fe00
+		b	__arm7_cache_off
+		b	__arm7_cache_off
+		mov	pc, lr
+
+		.word	0x41807200		@ ARM720T (writethrough)
+		.word	0xffffff00
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		mov	pc, lr
+
+		.word	0x41129200		@ ARM920T
+		.word	0xff00fff0
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		b	__armv4_cache_flush
+
+		.word	0x41029220		@ ARM922T
+		.word	0xff00fff0
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		b	__armv4_cache_flush
+
+		.word	0x4401a100		@ sa110 / sa1100
+		.word	0xffffffe0
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		b	__armv4_cache_flush
+
+		.word	0x6901b110		@ sa1110
+		.word	0xfffffff0
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		b	__armv4_cache_flush
+
+		.word	0x69050000		@ xscale
+		.word	0xffff0000
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		b	__armv4_cache_flush
+
+		.word	0			@ unrecognised type
+		.word	0
+		mov	pc, lr
+		mov	pc, lr
+		mov	pc, lr
+
+		.size	proc_types, . - proc_types
 
 /*
  * Turn off the Cache and MMU.  ARMv3 does not support
  * reading the control register, but ARMv4 does.
  *
  * On entry,  r6 = processor ID
- * On exit,   r0, r1 corrupted
+ * On exit,   r0, r1, r2, r3, r12 corrupted
  * This routine must preserve: r4, r6, r7
  */
 		.align	5
-cache_off:
-#ifdef CONFIG_CPU_ARM610
-		eor	r1, r6, #0x41000000
-		eor	r1, r1, #0x00560000
-		bic	r1, r1, #0x0000001f
-		teq	r1, #0x00000600
-		mov	r0, #0x00000060		@ ARM6 control reg.
-		beq	__armv3_cache_off
-#endif
-#ifdef CONFIG_CPU_ARM710
-		eor	r1, r6, #0x41000000
-		bic	r1, r1, #0x00070000
-		bic	r1, r1, #0x000000ff
-		teq	r1, #0x00007000		@ ARM7
-		teqne	r1, #0x00007100		@ ARM710
-		mov	r0, #0x00000070		@ ARM7 control reg.
-		beq	__armv3_cache_off
-#endif
+cache_off:	mov	r3, #12			@ cache_off function
+		b	call_cache_fn
+
+__armv4_cache_off:
 		mrc	p15, 0, r0, c1, c0
 		bic	r0, r0, #0x000d
 		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
@@ -366,11 +549,19 @@
 		mcr	p15, 0, r0, c8, c7	@ invalidate whole TLB v4
 		mov	pc, lr
 
+__arm6_cache_off:
+		mov	r0, #0x00000030		@ ARM6 control reg.
+		b	__armv3_cache_off
+
+__arm7_cache_off:
+		mov	r0, #0x00000070		@ ARM7 control reg.
+		b	__armv3_cache_off
+
 __armv3_cache_off:
-		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
+		mcr	p15, 0, r0, c1, c0, 0	@ turn MMU and cache off
 		mov	r0, #0
-		mcr	p15, 0, r0, c7, c0	@ invalidate whole cache v3
-		mcr	p15, 0, r0, c5, c0	@ invalidate whole TLB v3
+		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
+		mcr	p15, 0, r0, c5, c0, 0	@ invalidate whole TLB v3
 		mov	pc, lr
 
 /*
@@ -379,23 +570,18 @@
  * On entry,
  *  r6 = processor ID
  * On exit,
- *  r1, r2, r12 corrupted
+ *  r1, r2, r3, r12 corrupted
  * This routine must preserve:
- *  r4, r6, r7
+ *  r0, r4, r5, r6, r7
  */
 		.align	5
 cache_clean_flush:
-		ldr	r1, proc_sa110_type
-		eor	r1, r1, r6
-		movs	r1, r1, lsr #5		@ catch SA110 and SA1100
-		beq	1f
-		ldr	r1, proc_sa1110_type
-		eor	r1, r1, r6
-		movs	r1, r1, lsr #4
-		movne	pc, lr
-1:
+		mov	r3, #16
+		b	call_cache_fn
+
+__armv4_cache_flush:
 		bic	r1, pc, #31
-		add	r2, r1, #32768
+		add	r2, r1, #65536		@ 2x the largest dcache size
 1:		ldr	r12, [r1], #32		@ s/w flush D cache
 		teq	r1, r2
 		bne	1b
@@ -404,6 +590,11 @@
 		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
 		mov	pc, lr
 
+__armv3_cache_flush:
+		mov	r1, #0
+		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
+		mov	pc, lr
+
 /*
  * Various debugging routines for printing hex characters and
  * memory, which again must be relocatable.
@@ -479,5 +670,5 @@
 reloc_end:
 
 		.align
-		.section	".stack"
+		.section ".stack", "w"
 user_stack:	.space	4096
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/hw-bse.c linux-2.4.22-pre3/arch/arm/boot/compressed/hw-bse.c
--- linux-2.4.22-pre2/arch/arm/boot/compressed/hw-bse.c	2000-08-13 09:54:15.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/hw-bse.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,74 +0,0 @@
-/*
- * Bright Star Engineering Inc.
- *
- * code for readng parameters from the
- * parameter blocks of the boot block
- * flash memory
- *
- */
-
-static int strcmp(const char *s1, const char *s2)
-{
-  while (*s1 != '\0' && *s1 == *s2)
-    {
-      s1++;
-      s2++;
-    }
-
-  return (*(unsigned char *) s1) - (*(unsigned char *) s2);
-}
-
-struct pblk_t {
-  char type;
-  unsigned short size;
-};
-
-static char *bse_getflashparam(char *name) {
-  unsigned int esize;
-  char *q,*r;
-  unsigned char *p,*e;
-  struct pblk_t *thepb = (struct pblk_t *) 0x00004000;
-  struct pblk_t *altpb = (struct pblk_t *) 0x00006000;  
-  if (thepb->type&1) {
-    if (altpb->type&1) {
-      /* no valid param block */ 
-      return (char*)0;
-    } else {
-      /* altpb is valid */
-      struct pblk_t *tmp;
-      tmp = thepb;
-      thepb = altpb;
-      altpb = tmp;
-    }
-  }
-  p = (char*)thepb + sizeof(struct pblk_t);
-  e = p + thepb->size; 
-  while (p < e) {
-    q = p;
-    esize = *p;
-    if (esize == 0xFF) break;
-    if (esize == 0) break;
-    if (esize > 127) {
-      esize = (esize&0x7F)<<8 | p[1];
-      q++;
-    }
-    q++;
-    r=q;
-    if (*r && ((name == 0) || (!strcmp(name,r)))) {
-      while (*q++) ;
-      return q;
-    }
-    p+=esize;
-  }
-  return (char*)0;
-}
-
-void bse_setup(void) {
-  /* extract the linux cmdline from flash */
-  char *name=bse_getflashparam("linuxboot");
-  char *x = (char *)0xc0000100;
-  if (name) { 
-    while (*name) *x++=*name++;
-  }
-  *x=0;
-}
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/ll_char_wr.S linux-2.4.22-pre3/arch/arm/boot/compressed/ll_char_wr.S
--- linux-2.4.22-pre2/arch/arm/boot/compressed/ll_char_wr.S	2001-04-12 12:03:50.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/ll_char_wr.S	2003-07-05 18:09:35.000000000 -0700
@@ -19,144 +19,116 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-		.text
+	.text
 
-#define BOLD            0x01
-#define ITALIC          0x02
-#define UNDERLINE       0x04
-#define FLASH           0x08
-#define INVERSE         0x10
-
-LC0:		.word	SYMBOL_NAME(bytes_per_char_h)
-		.word	SYMBOL_NAME(video_size_row)
-		.word	SYMBOL_NAME(acorndata_8x8)
-		.word	SYMBOL_NAME(con_charconvtable)
+LC0:	.word	LC0
+	.word	bytes_per_char_h
+	.word	video_size_row
+	.word	acorndata_8x8
+	.word	con_charconvtable
 
+/*
+ * r0 = ptr
+ * r1 = char
+ * r2 = white
+ */
 ENTRY(ll_write_char)
-		stmfd	sp!, {r4 - r7, lr}
+	stmfd	sp!, {r4 - r7, lr}
 @
 @ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
 @
-		eor	ip, r1, #UNDERLINE << 9
-/*
- * calculate colours
- */
-		tst	r1, #INVERSE << 9
-		moveq	r2, r1, lsr #16
-		moveq	r3, r1, lsr #24
-		movne	r2, r1, lsr #24
-		movne	r3, r1, lsr #16
-		and	r3, r3, #255
-		and	r2, r2, #255
-/*
- * calculate offset into character table
- */
-		mov	r1, r1, lsl #23
-		mov	r1, r1, lsr #20
-/*
- * calculate offset required for each row [maybe I should make this an argument to this fn.
- * Have to see what the register usage is like in the calling routines.
- */
-		adr	r4, LC0
-		ldmia	r4, {r4, r5, r6, lr}
-		ldr	r4, [r4]
-		ldr	r5, [r5]
-/*
- * Go to resolution-dependent routine...
- */
-		cmp	r4, #4
-		blt	Lrow1bpp
-		eor	r2, r3, r2			@ Create eor mask to change colour from bg
-		orr	r3, r3, r3, lsl #8		@ to fg.
-		orr	r3, r3, r3, lsl #16
-		add	r0, r0, r5, lsl #3		@ Move to bottom of character
-		add	r1, r1, #7
-		ldrb	r7, [r6, r1]
-		tst	ip, #UNDERLINE << 9
-		eoreq	r7, r7, #255
-		teq	r4, #8
-		beq	Lrow8bpplp
+	/*
+	 * calculate offset into character table
+	 */
+	mov	r1, r1, lsl #3
+	/*
+	 * calculate offset required for each row.
+	 */
+	adr	ip, LC0
+	ldmia	ip, {r3, r4, r5, r6, lr}
+	sub	ip, ip, r3
+	add	r6, r6, ip
+	add	lr, lr, ip
+	ldr	r4, [r4, ip]
+	ldr	r5, [r5, ip]
+	/*
+	 * Go to resolution-dependent routine...
+	 */
+	cmp	r4, #4
+	blt	Lrow1bpp
+	add	r0, r0, r5, lsl #3		@ Move to bottom of character
+	orr	r1, r1, #7
+	ldrb	r7, [r6, r1]
+	teq	r4, #8
+	beq	Lrow8bpplp
 @
 @ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
 @
-		orr	r3, r3, r3, lsl #4
-Lrow4bpplp:	ldr	r7, [lr, r7, lsl #2]
-		mul	r7, r2, r7
-		tst	r1, #7				@ avoid using r7 directly after
-		eor	ip, r3, r7
-		str	ip, [r0, -r5]!
-		LOADREGS(eqfd, sp!, {r4 - r7, pc})
-		sub	r1, r1, #1
-		ldrb	r7, [r6, r1]
-		ldr	r7, [lr, r7, lsl #2]
-		mul	r7, r2, r7
-		tst	r1, #7				@ avoid using r7 directly after
-		eor	ip, r3, r7
-		str	ip, [r0, -r5]!
-		subne	r1, r1, #1
-		ldrneb	r7, [r6, r1]
-		bne	Lrow4bpplp
-		LOADREGS(fd, sp!, {r4 - r7, pc})
+Lrow4bpplp:
+	ldr	r7, [lr, r7, lsl #2]
+	mul	r7, r2, r7
+	sub	r1, r1, #1			@ avoid using r7 directly after
+	str	r7, [r0, -r5]!
+	ldrb	r7, [r6, r1]
+	ldr	r7, [lr, r7, lsl #2]
+	mul	r7, r2, r7
+	tst	r1, #7				@ avoid using r7 directly after
+	str	r7, [r0, -r5]!
+	subne	r1, r1, #1
+	ldrneb	r7, [r6, r1]
+	bne	Lrow4bpplp
+	LOADREGS(fd, sp!, {r4 - r7, pc})
 
 @
 @ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
 @
-Lrow8bpplp:	mov	ip, r7, lsr #4
-		ldr	ip, [lr, ip, lsl #2]
-		mul	r4, r2, ip
-		and	ip, r7, #15			@ avoid r4
-		ldr	ip, [lr, ip, lsl #2]		@ avoid r4
-		mul	ip, r2, ip			@ avoid r4
-		eor	r4, r3, r4			@ avoid ip
-		tst	r1, #7				@ avoid ip
-		sub	r0, r0, r5			@ avoid ip
-		eor	ip, r3, ip
-		stmia	r0, {r4, ip}
-		LOADREGS(eqfd, sp!, {r4 - r7, pc})
-		sub	r1, r1, #1
-		ldrb	r7, [r6, r1]
-		mov	ip, r7, lsr #4
-		ldr	ip, [lr, ip, lsl #2]
-		mul	r4, r2, ip
-		and	ip, r7, #15			@ avoid r4
-		ldr	ip, [lr, ip, lsl #2]		@ avoid r4
-		mul	ip, r2, ip			@ avoid r4
-		eor	r4, r3, r4			@ avoid ip
-		tst	r1, #7				@ avoid ip
-		sub	r0, r0, r5			@ avoid ip
-		eor	ip, r3, ip
-		stmia	r0, {r4, ip}
-		subne	r1, r1, #1
-		ldrneb	r7, [r6, r1]
-		bne	Lrow8bpplp
-		LOADREGS(fd, sp!, {r4 - r7, pc})
+Lrow8bpplp:
+	mov	ip, r7, lsr #4
+	ldr	ip, [lr, ip, lsl #2]
+	mul	r4, r2, ip
+	and	ip, r7, #15			@ avoid r4
+	ldr	ip, [lr, ip, lsl #2]		@ avoid r4
+	mul	ip, r2, ip			@ avoid r4
+	sub	r1, r1, #1			@ avoid ip
+	sub	r0, r0, r5			@ avoid ip
+	stmia	r0, {r4, ip}
+	ldrb	r7, [r6, r1]
+	mov	ip, r7, lsr #4
+	ldr	ip, [lr, ip, lsl #2]
+	mul	r4, r2, ip
+	and	ip, r7, #15			@ avoid r4
+	ldr	ip, [lr, ip, lsl #2]		@ avoid r4
+	mul	ip, r2, ip			@ avoid r4
+	tst	r1, #7				@ avoid ip
+	sub	r0, r0, r5			@ avoid ip
+	stmia	r0, {r4, ip}
+	subne	r1, r1, #1
+	ldrneb	r7, [r6, r1]
+	bne	Lrow8bpplp
+	LOADREGS(fd, sp!, {r4 - r7, pc})
 
 @
 @ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
 @
-Lrow1bpp:	add	r6, r6, r1
-		ldmia	r6, {r4, r7}
-		tst	ip, #INVERSE << 9
-		mvnne	r4, r4
-		mvnne	r7, r7
-		strb	r4, [r0], r5
-		mov	r4, r4, lsr #8
-		strb	r4, [r0], r5
-		mov	r4, r4, lsr #8
-		strb	r4, [r0], r5
-		mov	r4, r4, lsr #8
-		strb	r4, [r0], r5
-		strb	r7, [r0], r5
-		mov	r7, r7, lsr #8
-		strb	r7, [r0], r5
-		mov	r7, r7, lsr #8
-		strb	r7, [r0], r5
-		mov	r7, r7, lsr #8
-		tst	ip, #UNDERLINE << 9
-		mvneq	r7, r7
-		strb	r7, [r0], r5
-		LOADREGS(fd, sp!, {r4 - r7, pc})
+Lrow1bpp:
+	add	r6, r6, r1
+	ldmia	r6, {r4, r7}
+	strb	r4, [r0], r5
+	mov	r4, r4, lsr #8
+	strb	r4, [r0], r5
+	mov	r4, r4, lsr #8
+	strb	r4, [r0], r5
+	mov	r4, r4, lsr #8
+	strb	r4, [r0], r5
+	strb	r7, [r0], r5
+	mov	r7, r7, lsr #8
+	strb	r7, [r0], r5
+	mov	r7, r7, lsr #8
+	strb	r7, [r0], r5
+	mov	r7, r7, lsr #8
+	strb	r7, [r0], r5
+	LOADREGS(fd, sp!, {r4 - r7, pc})
 
-		.bss
+	.bss
 ENTRY(con_charconvtable)
-		.space	1024
+	.space	1024
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/misc.c linux-2.4.22-pre3/arch/arm/boot/compressed/misc.c
--- linux-2.4.22-pre2/arch/arm/boot/compressed/misc.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/misc.c	2003-07-05 18:09:35.000000000 -0700
@@ -22,7 +22,6 @@
 
 #include <asm/uaccess.h>
 #include <asm/arch/uncompress.h>
-#include <asm/proc/uncompress.h>
 
 #ifdef STANDALONE_DEBUG
 #define puts printf
@@ -291,7 +290,6 @@
 	free_mem_ptr_end	= free_mem_ptr_end_p;
 	__machine_arch_type	= arch_id;
 
-	proc_decomp_setup();
 	arch_decomp_setup();
 
 	makecrc();
@@ -315,4 +313,3 @@
 	return 0;
 }
 #endif
-	
diff -urN linux-2.4.22-pre2/arch/arm/boot/compressed/vmlinux.lds.in linux-2.4.22-pre3/arch/arm/boot/compressed/vmlinux.lds.in
--- linux-2.4.22-pre2/arch/arm/boot/compressed/vmlinux.lds.in	2001-07-02 14:40:14.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/boot/compressed/vmlinux.lds.in	2003-07-05 18:09:35.000000000 -0700
@@ -35,29 +35,26 @@
 
   _etext = .;
 
-  .data : {
-    *(.data)
-  }
-
+  _got_start = .;
+  .got			: { *(.got) }
+  _got_end = .;
+  .got.plt		: { *(.got.plt) }
+  .data			: { *(.data) }
   _edata = .;
 
   . = BSS_START;
   __bss_start = .;
-  .bss : {
-    *(.bss)
-  }
+  .bss			: { *(.bss) }
   _end = .;
 
-  .stack : {
-    *(.stack)
-  }
-
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  .comment 0 : { *(.comment) }
+  .stack (NOLOAD)	: { *(.stack) }
+
+  .stab 0		: { *(.stab) }
+  .stabstr 0		: { *(.stabstr) }
+  .stab.excl 0		: { *(.stab.excl) }
+  .stab.exclstr 0	: { *(.stab.exclstr) }
+  .stab.index 0		: { *(.stab.index) }
+  .stab.indexstr 0	: { *(.stab.indexstr) }
+  .comment 0		: { *(.comment) }
 }
 
diff -urN linux-2.4.22-pre2/arch/arm/common/Makefile linux-2.4.22-pre3/arch/arm/common/Makefile
--- linux-2.4.22-pre2/arch/arm/common/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/common/Makefile	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,17 @@
+#
+# Makefile for the linux kernel.
+#
+
+O_TARGET := nopci.o
+
+export-objs := pcipool.o
+
+obj-y   :=
+obj-m   :=
+obj-n   :=
+obj-	:=
+
+obj-$(CONFIG_USB_OHCI_SA1111)   += pcipool.o
+obj-$(CONFIG_USB_OHCI_AT91)	+= pcipool.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/arm/common/pcipool.c linux-2.4.22-pre3/arch/arm/common/pcipool.c
--- linux-2.4.22-pre2/arch/arm/common/pcipool.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/common/pcipool.c	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,391 @@
+/*
+  NOTE:
+
+  this code was lifted straight out of drivers/pci/pci.c;
+  when compiling for the Intel StrongARM SA-1110/SA-1111 the
+  usb-ohci.c driver needs these routines even when the architecture
+  has no pci bus...
+*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+
+#include <asm/page.h>
+
+/*
+ * Pool allocator ... wraps the pci_alloc_consistent page allocator, so
+ * small blocks are easily used by drivers for bus mastering controllers.
+ * This should probably be sharing the guts of the slab allocator.
+ */
+
+struct pci_pool {	/* the pool */
+	struct list_head	page_list;
+	spinlock_t		lock;
+	size_t			blocks_per_page;
+	size_t			size;
+	struct pci_dev		*dev;
+	size_t			allocation;
+	char			name [32];
+	wait_queue_head_t	waitq;
+};
+
+struct pci_page {	/* cacheable header for 'allocation' bytes */
+	struct list_head	page_list;
+	void			*vaddr;
+	dma_addr_t		dma;
+	unsigned long		bitmap [0];
+};
+
+#define	POOL_TIMEOUT_JIFFIES	((100 /* msec */ * HZ) / 1000)
+#define	POOL_POISON_BYTE	0xa7
+
+// #define CONFIG_PCIPOOL_DEBUG
+
+static inline const char *slot_name(const struct pci_pool *pool)
+{
+	const struct pci_dev *pdev = pool->dev;
+
+	if (pdev == 0)
+		return "[0]";
+
+	else if (dev_is_sa1111(pdev))
+		return "[SA-1111]";
+	else
+		return pdev->slot_name;
+}
+
+
+/**
+ * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma.
+ * @name: name of pool, for diagnostics
+ * @pdev: pci device that will be doing the DMA
+ * @size: size of the blocks in this pool.
+ * @align: alignment requirement for blocks; must be a power of two
+ * @allocation: returned blocks won't cross this boundary (or zero)
+ * @mem_flags: SLAB_* flags.
+ *
+ * Returns a pci allocation pool with the requested characteristics, or
+ * null if one can't be created.  Given one of these pools, pci_pool_alloc()
+ * may be used to allocate memory.  Such memory will all have "consistent"
+ * DMA mappings, accessible by the device and its driver without using
+ * cache flushing primitives.  The actual size of blocks allocated may be
+ * larger than requested because of alignment.
+ *
+ * If allocation is nonzero, objects returned from pci_pool_alloc() won't
+ * cross that size boundary.  This is useful for devices which have
+ * addressing restrictions on individual DMA transfers, such as not crossing
+ * boundaries of 4KBytes.
+ */
+struct pci_pool *
+pci_pool_create (const char *name, struct pci_dev *pdev,
+	size_t size, size_t align, size_t allocation, int mem_flags)
+{
+	struct pci_pool		*retval;
+
+	if (align == 0)
+		align = 1;
+	if (size == 0)
+		return 0;
+	else if (size < align)
+		size = align;
+	else if ((size % align) != 0) {
+		size += align + 1;
+		size &= ~(align - 1);
+	}
+
+	if (allocation == 0) {
+		if (PAGE_SIZE < size)
+			allocation = size;
+		else
+			allocation = PAGE_SIZE;
+		// FIXME: round up for less fragmentation
+	} else if (allocation < size)
+		return 0;
+
+	if (!(retval = kmalloc (sizeof *retval, mem_flags)))
+		return retval;
+
+	strncpy (retval->name, name, sizeof retval->name);
+	retval->name [sizeof retval->name - 1] = 0;
+
+	retval->dev = pdev;
+	INIT_LIST_HEAD (&retval->page_list);
+	spin_lock_init (&retval->lock);
+	retval->size = size;
+	retval->allocation = allocation;
+	retval->blocks_per_page = allocation / size;
+	init_waitqueue_head (&retval->waitq);
+
+#ifdef CONFIG_PCIPOOL_DEBUG
+	printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n",
+		slot_name(retval), retval->name, size,
+		retval->blocks_per_page, allocation);
+#endif
+
+	return retval;
+}
+
+
+static struct pci_page *
+pool_alloc_page (struct pci_pool *pool, int mem_flags)
+{
+	struct pci_page	*page;
+	int		mapsize;
+
+	mapsize = pool->blocks_per_page;
+	mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
+	mapsize *= sizeof (long);
+
+	page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags);
+	if (!page)
+		return 0;
+	page->vaddr = pci_alloc_consistent (pool->dev,
+					    pool->allocation,
+					    &page->dma);
+	if (page->vaddr) {
+		memset (page->bitmap, 0xff, mapsize);	// bit set == free
+#ifdef	CONFIG_DEBUG_SLAB
+		memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+#endif
+		list_add (&page->page_list, &pool->page_list);
+	} else {
+		kfree (page);
+		page = 0;
+	}
+	return page;
+}
+
+
+static inline int
+is_page_busy (int blocks, unsigned long *bitmap)
+{
+	while (blocks > 0) {
+		if (*bitmap++ != ~0UL)
+			return 1;
+		blocks -= BITS_PER_LONG;
+	}
+	return 0;
+}
+
+static void
+pool_free_page (struct pci_pool *pool, struct pci_page *page)
+{
+	dma_addr_t	dma = page->dma;
+
+#ifdef	CONFIG_DEBUG_SLAB
+	memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+#endif
+	pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma);
+	list_del (&page->page_list);
+	kfree (page);
+}
+
+
+/**
+ * pci_pool_destroy - destroys a pool of pci memory blocks.
+ * @pool: pci pool that will be destroyed
+ *
+ * Caller guarantees that no more memory from the pool is in use,
+ * and that nothing will try to use the pool after this call.
+ */
+void
+pci_pool_destroy (struct pci_pool *pool)
+{
+	unsigned long		flags;
+
+#ifdef CONFIG_PCIPOOL_DEBUG
+	printk (KERN_DEBUG "pcipool destroy %s/%s\n",
+		slot_name(pool), pool->name);
+#endif
+
+	spin_lock_irqsave (&pool->lock, flags);
+	while (!list_empty (&pool->page_list)) {
+		struct pci_page		*page;
+		page = list_entry (pool->page_list.next,
+				struct pci_page, page_list);
+		if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
+			printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n",
+				slot_name(pool), pool->name, page->vaddr);
+			/* leak the still-in-use consistent memory */
+			list_del (&page->page_list);
+			kfree (page);
+		} else
+			pool_free_page (pool, page);
+	}
+	spin_unlock_irqrestore (&pool->lock, flags);
+	kfree (pool);
+}
+
+
+/**
+ * pci_pool_alloc - get a block of consistent memory
+ * @pool: pci pool that will produce the block
+ * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC
+ * @handle: pointer to dma address of block
+ *
+ * This returns the kernel virtual address of a currently unused block,
+ * and reports its dma address through the handle.
+ * If such a memory block can't be allocated, null is returned.
+ */
+void *
+pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
+{
+	unsigned long		flags;
+	struct list_head	*entry;
+	struct pci_page		*page;
+	int			map, block;
+	size_t			offset;
+	void			*retval;
+
+restart:
+	spin_lock_irqsave (&pool->lock, flags);
+	list_for_each (entry, &pool->page_list) {
+		int		i;
+		page = list_entry (entry, struct pci_page, page_list);
+		/* only cachable accesses here ... */
+		for (map = 0, i = 0;
+				i < pool->blocks_per_page;
+				i += BITS_PER_LONG, map++) {
+			if (page->bitmap [map] == 0)
+				continue;
+			block = ffz (~ page->bitmap [map]);
+			if ((i + block) < pool->blocks_per_page) {
+				clear_bit (block, &page->bitmap [map]);
+				offset = (BITS_PER_LONG * map) + block;
+				offset *= pool->size;
+				goto ready;
+			}
+		}
+	}
+	if (!(page = pool_alloc_page (pool, mem_flags))) {
+		if (mem_flags == SLAB_KERNEL) {
+			DECLARE_WAITQUEUE (wait, current);
+
+			current->state = TASK_INTERRUPTIBLE;
+			add_wait_queue (&pool->waitq, &wait);
+			spin_unlock_irqrestore (&pool->lock, flags);
+
+			schedule_timeout (POOL_TIMEOUT_JIFFIES);
+
+			current->state = TASK_RUNNING;
+			remove_wait_queue (&pool->waitq, &wait);
+			goto restart;
+		}
+		retval = 0;
+		goto done;
+	}
+
+	clear_bit (0, &page->bitmap [0]);
+	offset = 0;
+ready:
+	retval = offset + page->vaddr;
+	*handle = offset + page->dma;
+done:
+	spin_unlock_irqrestore (&pool->lock, flags);
+	return retval;
+}
+
+
+static struct pci_page *
+pool_find_page (struct pci_pool *pool, dma_addr_t dma)
+{
+	unsigned long		flags;
+	struct list_head	*entry;
+	struct pci_page		*page;
+
+	spin_lock_irqsave (&pool->lock, flags);
+	list_for_each (entry, &pool->page_list) {
+		page = list_entry (entry, struct pci_page, page_list);
+		if (dma < page->dma)
+			continue;
+		if (dma < (page->dma + pool->allocation))
+			goto done;
+	}
+	page = 0;
+done:
+	spin_unlock_irqrestore (&pool->lock, flags);
+	return page;
+}
+
+
+/**
+ * pci_pool_free - put block back into pci pool
+ * @pool: the pci pool holding the block
+ * @vaddr: virtual address of block
+ * @dma: dma address of block
+ *
+ * Caller promises neither device nor driver will again touch this block
+ * unless it is first re-allocated.
+ */
+void
+pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
+{
+	struct pci_page		*page;
+	unsigned long		flags;
+	int			map, block;
+
+	if ((page = pool_find_page (pool, dma)) == 0) {
+		printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, vaddr, (unsigned long) dma);
+		return;
+	}
+
+	block = dma - page->dma;
+	block /= pool->size;
+	map = block / BITS_PER_LONG;
+	block %= BITS_PER_LONG;
+
+#ifdef	CONFIG_DEBUG_SLAB
+	if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
+		printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%lx\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, vaddr, (unsigned long) dma);
+		return;
+	}
+	if (page->bitmap [map] & (1UL << block)) {
+		printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, dma);
+		return;
+	}
+	memset (vaddr, POOL_POISON_BYTE, pool->size);
+#endif
+
+	spin_lock_irqsave (&pool->lock, flags);
+	set_bit (block, &page->bitmap [map]);
+	if (waitqueue_active (&pool->waitq))
+		wake_up (&pool->waitq);
+	/*
+	 * Resist a temptation to do
+	 *    if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page);
+	 * it is not interrupt safe. Better have empty pages hang around.
+	 */
+	spin_unlock_irqrestore (&pool->lock, flags);
+}
+
+
+EXPORT_SYMBOL (pci_pool_create);
+EXPORT_SYMBOL (pci_pool_destroy);
+EXPORT_SYMBOL (pci_pool_alloc);
+EXPORT_SYMBOL (pci_pool_free);
+
+/* **************************************** */
+
+static int __init pcipool_init(void)
+{
+	MOD_INC_USE_COUNT;	/* never unload */
+
+	return 0;
+}
+module_init(pcipool_init);
+
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.22-pre2/arch/arm/config.in linux-2.4.22-pre3/arch/arm/config.in
--- linux-2.4.22-pre2/arch/arm/config.in	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/config.in	2003-07-05 18:09:35.000000000 -0700
@@ -2,7 +2,7 @@
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
-mainmenu_name "Linux Kernel Configuration"
+mainmenu_name "ARM Linux Kernel Configuration"
 
 define_bool CONFIG_ARM y
 define_bool CONFIG_EISA n
@@ -39,14 +39,17 @@
  	 CLPS711x/EP721x-based	CONFIG_ARCH_CLPS711X \
 	 Co-EBSA285		CONFIG_ARCH_CO285 \
 	 EBSA-110		CONFIG_ARCH_EBSA110 \
- 	 Epxa10db               CONFIG_ARCH_CAMELOT \
+ 	 Excalibur-ARM          CONFIG_ARCH_CAMELOT \
 	 FootBridge		CONFIG_ARCH_FOOTBRIDGE \
 	 Integrator		CONFIG_ARCH_INTEGRATOR \
+	 Omaha			CONFIG_ARCH_OMAHA \
 	 LinkUp-L7200		CONFIG_ARCH_L7200 \
 	 Motorola-MX1ADS        CONFIG_ARCH_MX1ADS \
 	 RiscPC			CONFIG_ARCH_RPC \
- 	 SA1100-based		CONFIG_ARCH_SA1100 \
-	 Shark			CONFIG_ARCH_SHARK" RiscPC
+	 RiscStation		CONFIG_ARCH_RISCSTATION \
+	 SA1100-based		CONFIG_ARCH_SA1100 \
+	 Shark			CONFIG_ARCH_SHARK \
+	 AT91RM9200-based	CONFIG_ARCH_AT91RM9200 " RiscPC
 
 mainmenu_option next_comment
 comment 'Archimedes/A5000 Implementations'
@@ -69,10 +72,14 @@
 
 mainmenu_option next_comment
 comment 'SA11x0 Implementations'
+dep_bool '  ACCELENT DevBoard' CONFIG_SA1100_ACCELENT $CONFIG_ARCH_SA1100
 dep_bool '  Assabet' CONFIG_SA1100_ASSABET $CONFIG_ARCH_SA1100
 dep_bool '    Include support for Neponset' CONFIG_ASSABET_NEPONSET $CONFIG_SA1100_ASSABET
+dep_bool '  ADS Advanced Graphics Client' CONFIG_SA1100_ADSAGC $CONFIG_ARCH_SA1100
 dep_bool '  ADS Bitsy' CONFIG_SA1100_ADSBITSY $CONFIG_ARCH_SA1100
+dep_bool '  ADS Bitsy Plus' CONFIG_SA1100_ADSBITSYPLUS $CONFIG_ARCH_SA1100
 dep_bool '  Brutus' CONFIG_SA1100_BRUTUS $CONFIG_ARCH_SA1100
+dep_bool '  Cep' CONFIG_SA1100_CEP $CONFIG_ARCH_SA1100
 dep_bool '  CerfBoard' CONFIG_SA1100_CERF $CONFIG_ARCH_SA1100
 if [ "$CONFIG_SA1100_CERF" = "y" ]; then
    choice 'Cerf RAM available' \
@@ -94,6 +101,8 @@
 else
   define_bool CONFIG_SA1100_H3XXX n
 fi
+dep_tristate 'Compaq iPAQ Handheld sleeve support' CONFIG_H3600_SLEEVE $CONFIG_SA1100_H3600
+#dep_bool '  Consus' CONFIG_SA1100_CONSUS $CONFIG_ARCH_SA1100
 #dep_bool '  Empeg' CONFIG_SA1100_EMPEG $CONFIG_ARCH_SA1100
 dep_bool '  Extenex HandHeld Theater (Squashtail)' CONFIG_SA1100_EXTENEX1 $CONFIG_ARCH_SA1100
 if [ "$CONFIG_SA1100_EXTENEX1" = "y" ]; then
@@ -104,6 +113,7 @@
 dep_bool '  Frodo' CONFIG_SA1100_FRODO $CONFIG_ARCH_SA1100
 dep_bool '  GraphicsClient Plus' CONFIG_SA1100_GRAPHICSCLIENT $CONFIG_ARCH_SA1100
 dep_bool '  GraphicsMaster' CONFIG_SA1100_GRAPHICSMASTER $CONFIG_ARCH_SA1100
+dep_bool '  HackKit Core Board' CONFIG_SA1100_HACKKIT $CONFIG_ARCH_SA1100
 dep_bool '  HP Labs BadgePAD 4' CONFIG_SA1100_BADGE4 $CONFIG_ARCH_SA1100
 dep_bool '  HP Jornada 720' CONFIG_SA1100_JORNADA720 $CONFIG_ARCH_SA1100
 dep_bool '  HuW WebPanel' CONFIG_SA1100_HUW_WEBPANEL $CONFIG_ARCH_SA1100
@@ -117,29 +127,23 @@
 dep_bool '  Shannon' CONFIG_SA1100_SHANNON $CONFIG_ARCH_SA1100
 dep_bool '  Sherman' CONFIG_SA1100_SHERMAN $CONFIG_ARCH_SA1100
 dep_bool '  Simpad' CONFIG_SA1100_SIMPAD $CONFIG_ARCH_SA1100
+dep_bool '  Simputer' CONFIG_SA1100_SIMPUTER $CONFIG_ARCH_SA1100
 dep_bool '  Tulsa' CONFIG_SA1100_PFS168 $CONFIG_ARCH_SA1100
 dep_bool '  Victor' CONFIG_SA1100_VICTOR $CONFIG_ARCH_SA1100
 dep_bool '  XP860' CONFIG_SA1100_XP860 $CONFIG_ARCH_SA1100
 dep_bool '  Yopy' CONFIG_SA1100_YOPY $CONFIG_ARCH_SA1100
 
-# Determine if SA1111 support is required
-if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \
-     "$CONFIG_SA1100_JORNADA720" = "y" -o \
-     "$CONFIG_SA1100_PFS168" = "y" -o \
-     "$CONFIG_SA1100_XP860" = "y" -o \
-     "$CONFIG_SA1100_GRAPHICSMASTER" = "y" -o \
-     "$CONFIG_SA1100_PT_SYSTEM3" = "y" -o \
-     "$CONFIG_SA1100_ADSBITSY" = "y" -o \
-     "$CONFIG_SA1100_BADGE4" = "y" ]; then
-   define_bool CONFIG_SA1111 y
-   define_int CONFIG_FORCE_MAX_ZONEORDER 9
-fi
+dep_tristate 'SA1100 USB function support' CONFIG_SA1100_USB $CONFIG_ARCH_SA1100
+dep_tristate '  Support for SA11x0 USB network link function' CONFIG_SA1100_USB_NETLINK $CONFIG_SA1100_USB
+dep_tristate '  Support for SA11x0 USB character device emulation' CONFIG_SA1100_USB_CHAR $CONFIG_SA1100_USB
 
-#dep_tristate 'SA1100 USB function support' CONFIG_SA1100_USB $CONFIG_ARCH_SA1100
-#dep_tristate '  Support for SA11x0 USB network link function' CONFIG_SA1100_USB_NETLINK $CONFIG_SA1100_USB
-#dep_tristate '  Support for SA11x0 USB character device emulation' CONFIG_SA1100_USB_CHAR $CONFIG_SA1100_USB
+dep_tristate 'SA1100 Generic PIO SSP support' CONFIG_SA1100_SSP $CONFIG_ARCH_SA1100
 
-dep_tristate 'Compaq iPAQ Handheld sleeve support' CONFIG_H3600_SLEEVE $CONFIG_SA1100_H3600
+endmenu
+
+mainmenu_option next_comment
+comment 'AT91RM9200 Implementations'
+dep_bool '  Atmel AT91RM9200 Development Board' CONFIG_ARCH_AT91RM9200DK $CONFIG_ARCH_AT91RM9200
 endmenu
 
 mainmenu_option next_comment
@@ -148,8 +152,10 @@
 dep_bool '  CDB89712' CONFIG_ARCH_CDB89712 $CONFIG_ARCH_CLPS711X
 dep_bool '  CLEP7312' CONFIG_ARCH_CLEP7312 $CONFIG_ARCH_CLPS711X
 dep_bool '  EDB7211' CONFIG_ARCH_EDB7211 $CONFIG_ARCH_CLPS711X
-dep_bool '  P720T' CONFIG_ARCH_P720T $CONFIG_ARCH_CLPS711X
 dep_bool '  FORTUNET' CONFIG_ARCH_FORTUNET $CONFIG_ARCH_CLPS711X
+dep_bool '  GUIDEA07' CONFIG_ARCH_GUIDEA07 $CONFIG_ARCH_CLPS711X
+dep_bool '  P720T' CONFIG_ARCH_P720T $CONFIG_ARCH_CLPS711X
+
 
 # XXX Maybe these should indicate register compatibility
 # instead of being mutually exclusive.
@@ -168,6 +174,11 @@
      "$CONFIG_ARCH_EP7212" = "y" ]; then
    bool '  EP72xx ROM boot' CONFIG_EP72XX_ROM_BOOT
 fi
+
+if [ "$CONFIG_ARCH_GUIDEA07" = "y" ]; then
+   define_bool CONFIG_ARCH_CDB89712 y
+fi
+
 endmenu
 
 # Definitions to make life easier
@@ -178,7 +189,8 @@
    define_bool CONFIG_ARCH_ACORN n
 fi
 
-# see Documentation/arm/ConfigVars for a description of these
+#####################################################################
+# Footbridge support
 if [ "$CONFIG_ARCH_CO285" = "y" -o \
      "$CONFIG_ARCH_FOOTBRIDGE" = "y" ]; then
    define_bool CONFIG_FOOTBRIDGE y
@@ -204,6 +216,42 @@
    define_bool CONFIG_ARCH_EBSA285 y
 fi
 
+#####################################################################
+# SA1111 support
+if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \
+     "$CONFIG_SA1100_ACCELENT" = "y" -o \
+     "$CONFIG_SA1100_ADSAGC" = "y" -o \
+     "$CONFIG_SA1100_ADSBITSY" = "y" -o \
+     "$CONFIG_SA1100_ADSBITSYPLUS" = "y" -o \
+     "$CONFIG_SA1100_BADGE4" = "y" -o \
+     "$CONFIG_SA1100_CONSUS" = "y" -o \
+     "$CONFIG_SA1100_GRAPHICSMASTER" = "y" -o \
+     "$CONFIG_SA1100_JORNADA720" = "y" -o \
+     "$CONFIG_SA1100_PFS168" = "y" -o \
+     "$CONFIG_SA1100_PT_SYSTEM3" = "y" -o \
+     "$CONFIG_SA1100_XP860" = "y" ]; then
+   define_bool CONFIG_SA1111 y
+   define_int CONFIG_FORCE_MAX_ZONEORDER 9
+fi
+
+if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then
+  choice 'EPXA system type' \
+         "EPXA10DB CONFIG_EPXA10DB \
+          EPXA1DB  CONFIG_EPXA1DB" EPXA10DB
+
+if [ "$CONFIG_EPXA10DB" = "y" ]; then
+  choice 'EPXA10B version' \
+         "SDR CONFIG_EPXA10DB_R2 \
+          DDR CONFIG_EPXA10DB_R3" DDR
+fi
+
+   comment 'PLD hotswap support'
+   define_bool CONFIG_PLD y
+   dep_bool 'Support for PLD device hotplugging' CONFIG_PLD_HOTSWAP $CONFIG_EXPERIMENTAL
+fi
+
+comment 'Processor Type'
+
 # Figure out whether this system uses 26-bit or 32-bit CPUs.
 if [ "$CONFIG_ARCH_ARCA5K" = "y" ]; then
    define_bool CONFIG_CPU_32 n
@@ -214,28 +262,9 @@
    define_bool CONFIG_CPU_26 n
 fi
 
-comment 'Processor Type'
-
-# Firstly, figure out what processor architecture version we should be using.
-if [ "$CONFIG_ARCH_RPC"        = "y" -o "$CONFIG_ARCH_CLPS7500" = "y" ]; then
-   define_bool CONFIG_CPU_32v3 y
-else
-   define_bool CONFIG_CPU_32v3 n
-fi
-if [ "$CONFIG_ARCH_EBSA110"    = "y" -o "$CONFIG_FOOTBRIDGE"    = "y" -o \
-     "$CONFIG_ARCH_TBOX"       = "y" -o "$CONFIG_ARCH_SHARK"    = "y" -o \
-     "$CONFIG_ARCH_NEXUSPCI"   = "y" -o "$CONFIG_ARCH_CLPS711X" = "y" -o \
-     "$CONFIG_ARCH_INTEGRATOR" = "y" -o "$CONFIG_ARCH_SA1100"   = "y" -o \
-     "$CONFIG_ARCH_L7200"      = "y" -o "$CONFIG_ARCH_ANAKIN"	= "y" -o \
-     "$CONFIG_ARCH_CAMELOT"    = "y" -o "$CONFIG_ARCH_MX1ADS"   = "y" ]; then
-   define_bool CONFIG_CPU_32v4 y
-else
-   define_bool CONFIG_CPU_32v4 n
-fi
-
-# Select CPU types depending on the architecture selected.
-# We use this to select which CPUs are supported, and to select
-# the compiler tuning options.
+# Select CPU types depending on the architecture selected.  This selects
+# which CPUs we support in the kernel image, and the compiler instruction
+# optimiser behaviour.
 
 # ARM610
 if [ "$CONFIG_ARCH_RPC" = "y" ]; then
@@ -245,7 +274,8 @@
 fi
 
 # ARM710
-if [ "$CONFIG_ARCH_CLPS7500" = "y" ]; then
+if [ "$CONFIG_ARCH_CLPS7500" = "y" -o \
+     "$CONFIG_ARCH_RISCSTATION" = "y" ]; then
    define_bool CONFIG_CPU_ARM710 y
 else
    if [ "$CONFIG_ARCH_RPC" = "y" ]; then
@@ -269,10 +299,12 @@
 fi
 
 # ARM920T
-if [ "$CONFIG_ARCH_MX1ADS" = "y" ]; then
+if [ "$CONFIG_ARCH_MX1ADS" = "y" -o \
+     "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
    define_bool CONFIG_CPU_ARM920T y
 else
-   if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
+   if [ "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
+	"$CONFIG_ARCH_OMAHA" = "y" ]; then
       bool 'Support ARM920T processor' CONFIG_CPU_ARM920T
    else
       define_bool CONFIG_CPU_ARM920T n
@@ -280,28 +312,13 @@
 fi
 
 
-if [ "$CONFIG_CPU_ARM920T" = "y" ]; then
-   bool '  ARM920T CPU idle' CONFIG_CPU_ARM920_CPU_IDLE
-   bool '  ARM920T I-Cache on' CONFIG_CPU_ARM920_I_CACHE_ON
-   bool '  ARM920T D-Cache on' CONFIG_CPU_ARM920_D_CACHE_ON
-   if [ "$CONFIG_CPU_ARM920_D_CACHE_ON" = "y" ] ; then
-      bool '  Force write through caches on ARM920T' CONFIG_CPU_ARM920_WRITETHROUGH
-   fi
-fi
-
 # ARM922T
 if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then
-         define_bool CONFIG_CPU_ARM922T y
+   define_bool CONFIG_CPU_ARM922T y
+   define_bool CONFIG_PLD y
 else
-         define_bool CONFIG_CPU_ARM922T n
-fi
-if [ "$CONFIG_CPU_ARM922T" = "y" ]; then
-   bool '  ARM922T CPU idle' CONFIG_CPU_ARM922_CPU_IDLE
-   bool '  ARM922T I-Cache on' CONFIG_CPU_ARM922_I_CACHE_ON
-   bool '  ARM922T D-Cache on' CONFIG_CPU_ARM922_D_CACHE_ON
-   if [ "$CONFIG_CPU_ARM922_D_CACHE_ON" = "y" ] ; then
-      bool '  Force write through caches on ARM922T' CONFIG_CPU_ARM922_WRITETHROUGH
-   fi
+   define_bool CONFIG_CPU_ARM922T n
+   define_bool CONFIG_PLD n
 fi
 
 # ARM926T
@@ -310,18 +327,6 @@
 else
    define_bool CONFIG_CPU_ARM926T n
 fi
-if [ "$CONFIG_CPU_ARM926T" = "y" ]; then
-   bool '  ARM926T CPU idle' CONFIG_CPU_ARM926_CPU_IDLE
-   bool '  ARM926T I-Cache on' CONFIG_CPU_ARM926_I_CACHE_ON
-   bool '  ARM926T D-Cache on' CONFIG_CPU_ARM926_D_CACHE_ON
-   if [ "$CONFIG_CPU_ARM926_D_CACHE_ON" = "y" ] ; then
-      bool '  Force write through caches on ARM926T' CONFIG_CPU_ARM926_WRITETHROUGH
-   fi
-   if [ "$CONFIG_CPU_ARM926_I_CACHE_ON" = "y" -o \
-        "$CONFIG_CPU_ARM926_D_CACHE_ON" = "y" ]; then
-      bool '  Round robin I and D cache replacement algorithm' CONFIG_CPU_ARM926_ROUND_ROBIN
-   fi
-fi
 
 # ARM1020
 if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
@@ -329,16 +334,12 @@
 else
     define_bool CONFIG_CPU_ARM1020 n
 fi
-if [ "$CONFIG_CPU_ARM1020" = "y" ]; then
-   bool '  ARM1020 I-Cache on' CONFIG_CPU_ARM1020_I_CACHE_ON
-   bool '  ARM10 D-Cache on' CONFIG_CPU_ARM1020_D_CACHE_ON
-   if [ "$CONFIG_CPU_ARM1020_D_CACHE_ON" = "y" ] ; then
-      bool '  Force write through caches on ARM1020' CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH
-   fi
-   if [ "$CONFIG_CPU_ARM1020_I_CACHE_ON" = "y" -o \
-        "$CONFIG_CPU_ARM1020_D_CACHE_ON" = "y" ]; then
-      bool '  Round robin I and D cache replacement algorithm' CONFIG_CPU_ARM1020_ROUND_ROBIN
-   fi
+
+# ARM1026EJ-S
+if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
+   bool 'Support ARM1026EJ-S processor' CONFIG_CPU_ARM1026
+else
+   define_bool CONFIG_CPU_ARM1026 n
 fi
 
 # SA110
@@ -361,13 +362,59 @@
    define_bool CONFIG_CPU_SA1100 n
 fi
 
-if [ "$CONFIG_CPU_32" = "y" ]; then
-   dep_bool 'Support Thumb instructions (experimental)' CONFIG_ARM_THUMB $CONFIG_EXPERIMENTAL
+# Figure out what processor architecture version we should be using.
+# This defines the compiler instruction set which depends on the machine type.
+
+if [ "$CONFIG_ARCH_RPC"         = "y" -o \
+     "$CONFIG_ARCH_RISCSTATION" = "y" -o \
+     "$CONFIG_ARCH_CLPS7500"    = "y" ]; then
+   define_bool CONFIG_CPU_32v3 y
+else
+   define_bool CONFIG_CPU_32v3 n
+fi
+if [ "$CONFIG_ARCH_EBSA110"    = "y" -o "$CONFIG_FOOTBRIDGE"    = "y" -o \
+     "$CONFIG_ARCH_TBOX"       = "y" -o "$CONFIG_ARCH_SHARK"    = "y" -o \
+     "$CONFIG_ARCH_NEXUSPCI"   = "y" -o "$CONFIG_ARCH_CLPS711X" = "y" -o \
+     "$CONFIG_ARCH_INTEGRATOR" = "y" -o "$CONFIG_ARCH_SA1100"   = "y" -o \
+     "$CONFIG_ARCH_L7200"      = "y" -o "$CONFIG_ARCH_ANAKIN"	= "y" -o \
+     "$CONFIG_ARCH_CAMELOT"    = "y" -o "$CONFIG_ARCH_MX1ADS"   = "y" -o \
+     "$CONFIG_ARCH_OMAHA"      = "y" -o "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
+   define_bool CONFIG_CPU_32v4 y
+else
+   define_bool CONFIG_CPU_32v4 n
+fi
+
+comment 'Processor Features'
+
+if [ "$CONFIG_CPU_ARM720T" = "y" -o "$CONFIG_CPU_ARM920T" = "y" -o \
+     "$CONFIG_CPU_ARM922T" = "y" -o "$CONFIG_CPU_ARM926T" = "y" -o \
+     "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1026" = "y" ]; then
+   dep_bool 'Support Thumb instructions (EXPERIMENTAL)' CONFIG_ARM_THUMB $CONFIG_EXPERIMENTAL
+fi
+if [ "$CONFIG_CPU_ARM920T" = "y" -o "$CONFIG_CPU_ARM922T" = "y" -o \
+     "$CONFIG_CPU_ARM926T" = "y" -o "$CONFIG_CPU_ARM1020" = "y" -o \
+     "$CONFIG_CPU_ARM1026" = "y" ]; then
+   bool 'Disable I-Cache' CONFIG_CPU_ICACHE_DISABLE
+   bool 'Disable D-Cache' CONFIG_CPU_DCACHE_DISABLE
+   if [ "$CONFIG_CPU_DISABLE_DCACHE" = "n" ]; then
+      bool 'Force write through D-cache' CONFIG_CPU_DCACHE_WRITETHROUGH
+   fi
+fi
+if [ "$CONFIG_CPU_ARM926T" = "y" -o "$CONFIG_CPU_ARM1020" = "y" -o \
+     "$CONFIG_CPU_ARM1026" = "y" ]; then
+   if [ "$CONFIG_CPU_ICACHE_DISABLE" = "n" -o "$CONFIG_CPU_DCACHE_DISABLE" = "n" ]; then
+      bool 'Round robin I and D cache replacement algorithm' CONFIG_CPU_CACHE_ROUND_ROBIN
+   fi
 fi
+if [ "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1026" = "y" ]; then
+   bool 'Disable branch prediction' CONFIG_CPU_BPREDICT_DISABLE
+fi
+
 
 # Select various configuration options depending on the machine type
 if [ "$CONFIG_ARCH_EDB7211" = "y" -o \
-     "$CONFIG_ARCH_SA1100" = "y" ]; then
+     "$CONFIG_ARCH_SA1100" = "y" -o \
+     "$CONFIG_ARCH_RISCSTATION" = "y" ]; then
    define_bool CONFIG_DISCONTIGMEM y
 else
    define_bool CONFIG_DISCONTIGMEM n
@@ -395,6 +442,7 @@
 if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \
      "$CONFIG_ARCH_SHARK" = "y" -o \
      "$CONFIG_ARCH_CLPS7500" = "y" -o \
+     "$CONFIG_ARCH_RISCSTATION" = "y" -o \
      "$CONFIG_ARCH_EBSA110" = "y" -o \
      "$CONFIG_ARCH_CDB89712" = "y" -o \
      "$CONFIG_ARCH_EDB7211" = "y" -o \
@@ -411,6 +459,12 @@
    define_bool CONFIG_ISA_DMA n
 fi
 
+# Compressed boot loader in ROM.  Yes, we really want to ask about
+# TEXT and BSS so we preserve their values in the config files.
+bool 'Compressed boot loader in ROM/flash' CONFIG_ZBOOT_ROM
+hex 'Compressed ROM boot loader base address' CONFIG_ZBOOT_ROM_TEXT 0
+hex 'Compressed ROM boot loader BSS address' CONFIG_ZBOOT_ROM_BSS 0
+
 if [ "$CONFIG_ARCH_SA1100" = "y" -o \
      "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
    dep_bool 'Support CPU clock change (EXPERIMENTAL)' CONFIG_CPU_FREQ $CONFIG_EXPERIMENTAL
@@ -423,13 +477,23 @@
 else
    define_bool CONFIG_PCMCIA n
 fi
+if [ "$CONFIG_SA1100_ACCELENT" = "y" ]; then
+   if [ "$CONFIG_PCMCIA" != "n" ]; then
+      bool '  Use second PCMCIA/CF slot (disables on-board IDE)' CONFIG_SA_PCMCIA_SLOT_1 y
+   fi
+fi
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
 comment 'At least one math emulation must be selected'
 tristate 'NWFPE math emulation' CONFIG_FPE_NWFPE
-dep_tristate 'FastFPE math emulation (experimental)' CONFIG_FPE_FASTFPE $CONFIG_EXPERIMENTAL
+if [ "$CONFIG_FPE_NWFPE" != "n" ]; then
+  bool '  Support extended precision' CONFIG_FPE_NWFPE_XP
+fi
+if [ "$CONFIG_CPU_26" = "n" -a "$CONFIG_CPU_32v3" = "n" ]; then
+   dep_tristate 'FastFPE math emulation (EXPERIMENTAL)' CONFIG_FPE_FASTFPE $CONFIG_EXPERIMENTAL
+fi
 choice 'Kernel core (/proc/kcore) format' \
 	"ELF		CONFIG_KCORE_ELF	\
 	 A.OUT		CONFIG_KCORE_AOUT" ELF
@@ -438,19 +502,8 @@
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 dep_bool 'Power Management support (experimental)' CONFIG_PM $CONFIG_EXPERIMENTAL
 dep_tristate 'RISC OS personality' CONFIG_ARTHUR $CONFIG_CPU_32
+string 'Default kernel command string' CONFIG_CMDLINE ""
 
-if [ "$CONFIG_ARCH_EBSA110" = "y" -o         \
-     "$CONFIG_ARCH_SA1100" = "y" -o          \
-     "$CONFIG_ARCH_CLPS7500" = "y" -o        \
-     "$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \
-     "$CONFIG_ARCH_CATS" = "y" -o            \
-     "$CONFIG_ARCH_P720T" = "y" -o	     \
-     "$CONFIG_ARCH_CDB89712" = "y" -o	     \
-     "$CONFIG_ARCH_CAMELOT" = "y" -o	     \
-     "$CONFIG_ARCH_ANAKIN" = "y"  -o         \
-     "$CONFIG_ARCH_MX1ADS" = "y" ]; then
-   string 'Default kernel command string' CONFIG_CMDLINE ""
-fi
 if [ "$CONFIG_ARCH_NETWINDER" = "y" -o  \
      "$CONFIG_ARCH_EBSA110" = "y" -o    \
      "$CONFIG_ARCH_EBSA285" = "y" -o    \
@@ -460,7 +513,8 @@
      "$CONFIG_ARCH_SA1100" = "y" -o     \
      "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
      "$CONFIG_ARCH_CDB89712" = "y" -o   \
-     "$CONFIG_ARCH_P720T" = "y" ]; then
+     "$CONFIG_ARCH_P720T" = "y" -o	\
+     "$CONFIG_ARCH_OMAHA" = "y" ]; then
    bool 'Timer and CPU usage LEDs' CONFIG_LEDS
    if [ "$CONFIG_LEDS" = "y" ]; then
       if [ "$CONFIG_ARCH_NETWINDER" = "y" -o  \
@@ -469,17 +523,24 @@
 	   "$CONFIG_ARCH_CO285" = "y" -o      \
 	   "$CONFIG_ARCH_SA1100" = "y" -o     \
            "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
-	   "$CONFIG_ARCH_P720T" = "y" ]; then
+	   "$CONFIG_ARCH_P720T" = "y" -o      \
+	   "$CONFIG_ARCH_OMAHA" = "y" ]; then
          bool '  Timer LED' CONFIG_LEDS_TIMER
          bool '  CPU usage LED' CONFIG_LEDS_CPU
       fi
-   fi
-   if [ "$CONFIG_ARCH_EBSA110" = "y" ]; then
-      define_bool CONFIG_LEDS_TIMER y
+      if [ "$CONFIG_ARCH_EBSA110" = "y" ]; then
+         define_bool CONFIG_LEDS_TIMER y
+      fi
    fi
 fi
-if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
-   bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP
+if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+   define_bool CONFIG_ALIGNMENT_TRAP y
+else
+   if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
+      bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP
+   else
+      define_bool CONFIG_ALIGNMENT_TRAP n
+   fi
 fi
 endmenu
 
@@ -487,6 +548,8 @@
 
 if [ "$CONFIG_ALIGNMENT_TRAP" = "y" ]; then
   source drivers/mtd/Config.in
+else
+  define_bool CONFIG_MTD n
 fi
 
 source drivers/pnp/Config.in
@@ -515,9 +578,9 @@
 fi
 
 mainmenu_option next_comment
-comment 'ATA/IDE/MFM/RLL support'
+comment 'ATA/ATAPI/MFM/RLL support'
 
-tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE
 
 if [ "$CONFIG_IDE" != "n" ]; then
   source drivers/ide/Config.in
@@ -538,7 +601,8 @@
 endmenu
 
 if [ "$CONFIG_ARCH_CLPS711X" = "y" ]; then
-   source drivers/scsi/Config.in
+   # This is _meant_ to be ssi _not_ scsi.  It is not a spelling error.
+   source drivers/ssi/Config.in
 fi
 
 source drivers/ieee1394/Config.in
@@ -602,7 +666,7 @@
 	"$CONFIG_ARCH_MX1ADS" = "y" ]; then
       define_bool CONFIG_PC_KEYMAP y
    fi
-   if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
+   if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" -a "$CONFIG_ARCH_RISCSTATION" != "y" ]; then
       bool 'VGA text console' CONFIG_VGA_CONSOLE
    fi
    source drivers/video/Config.in
@@ -611,6 +675,7 @@
 
 if [ "$CONFIG_ARCH_ACORN" = "y" -o \
      "$CONFIG_ARCH_CLPS7500" = "y" -o \
+     "$CONFIG_ARCH_RISCSTATION" = "y" -o \
      "$CONFIG_ARCH_TBOX" = "y" -o \
      "$CONFIG_ARCH_SHARK" = "y" -o \
      "$CONFIG_ARCH_SA1100" = "y" -o \
@@ -618,7 +683,7 @@
    mainmenu_option next_comment
    comment 'Sound'
 
-   tristate 'Sound card support' CONFIG_SOUND
+   tristate 'Sound support' CONFIG_SOUND
    if [ "$CONFIG_SOUND" != "n" ]; then
       source drivers/sound/Config.in
    fi
@@ -629,7 +694,9 @@
 
 source drivers/usb/Config.in
 
-source net/bluetooth/Config.in
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   source net/bluetooth/Config.in
+fi
 
 mainmenu_option next_comment
 comment 'Kernel hacking'
@@ -638,7 +705,16 @@
 # you know what you are doing and are willing to live without stack traces, you
 # can get a slightly smaller kernel by setting this option to n, but then RMK
 # will have to kill you ;).
-define_bool CONFIG_FRAME_POINTER y
+if [ "$CONFIG_ARCH_OMAHA" = "y" ]; then
+    # 
+    # Note: We want all the performance we can get, so this means
+    # we accept the debugging limitations of setting CONFIG_FRAME_POINTER=n
+    # -- ahaigh@arm.com (23 August 2002)
+    define_bool CONFIG_FRAME_POINTER n
+else
+    define_bool CONFIG_FRAME_POINTER y
+fi
+
 bool 'Verbose user fault messages' CONFIG_DEBUG_USER
 bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
 dep_bool 'Disable pgtable cache' CONFIG_NO_PGT_CACHE $CONFIG_CPU_26
@@ -650,10 +726,11 @@
 dep_bool '  Wait queue debugging' CONFIG_DEBUG_WAITQ $CONFIG_DEBUG_KERNEL
 dep_bool '  Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE $CONFIG_DEBUG_KERNEL
 dep_bool '  Verbose kernel error messages' CONFIG_DEBUG_ERRORS $CONFIG_DEBUG_KERNEL
-# These options are only for real kernel hackers who want to get their hands dirty. 
+# These options are only for real kernel hackers who want to get their hands dirty.
 dep_bool '  Kernel low-level debugging functions' CONFIG_DEBUG_LL $CONFIG_DEBUG_KERNEL
 dep_bool '    Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
 dep_bool '    Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/accelent_sa linux-2.4.22-pre3/arch/arm/def-configs/accelent_sa
--- linux-2.4.22-pre2/arch/arm/def-configs/accelent_sa	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/def-configs/accelent_sa	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,1099 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+CONFIG_SA1100_ACCELENT=y
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+CONFIG_SA1100_USB=m
+CONFIG_SA1100_USB_NETLINK=m
+CONFIG_SA1100_USB_CHAR=m
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=C0400000
+CONFIG_ZBOOT_ROM_BSS=C0200000
+CONFIG_CPU_FREQ=y
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+CONFIG_PCMCIA_SA1100=m
+# CONFIG_SA_PCMCIA_SLOT_1 is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PM=y
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=1f02"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+# CONFIG_PARPORT_PC is not set
+CONFIG_PARPORT_IDP=m
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_1284 is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_B1 is not set
+# CONFIG_MTD_CFI_B2 is not set
+CONFIG_MTD_CFI_B4=y
+# CONFIG_MTD_CFI_B8 is not set
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+CONFIG_CS89x0=y
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=m
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+# CONFIG_IRNET is not set
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+CONFIG_IRPORT_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+CONFIG_SA1100_FIR=m
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_SCSI_PCMCIA is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=115200
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SA1111_PS2_KEYB=y
+CONFIG_ASI_KEYBOARD=y
+# CONFIG_RTC_ASI is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+CONFIG_L3=y
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+CONFIG_L3_SA1111=y
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=m
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_21285_WATCHDOG is not set
+# CONFIG_977_WATCHDOG is not set
+CONFIG_SA1100_WATCHDOG=m
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_SA1100_RTC=m
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=m
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=m
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_CRAMFS=m
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=m
+# CONFIG_SYSV_FS is not set
+CONFIG_UDF_FS=m
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=m
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=m
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+CONFIG_FB_SA1100=y
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=y
+CONFIG_SOUND_UDA1341=y
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+CONFIG_SOUND_SA1111_UDA1341=y
+# CONFIG_SOUND_SA1100SSP is not set
+# CONFIG_SOUND_SA1111_AC97 is not set
+# CONFIG_SOUND_SA1111_AC97_RATE_CONVERSION is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+CONFIG_MCP=y
+CONFIG_MCP_SA1100=y
+CONFIG_MCP_UCB1200=y
+CONFIG_MCP_UCB1200_AUDIO=m
+CONFIG_MCP_UCB1200_TS=m
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=m
+CONFIG_USB_SL811HS=m
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=m
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+CONFIG_USB_USBNET=m
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/adsagc linux-2.4.22-pre3/arch/arm/def-configs/adsagc
--- linux-2.4.22-pre2/arch/arm/def-configs/adsagc	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/def-configs/adsagc	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,1101 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+CONFIG_SA1100_ADSAGC=y
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_CPU_FREQ is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+CONFIG_PCMCIA_SA1100=y
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PM=y
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttySA0 mem=16m@0xC0000000 mem=16m@0xC8000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=8000000
+CONFIG_MTD_PHYSMAP_LEN=4000000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=4
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+# CONFIG_SMC9194 is not set
+CONFIG_SMC91111=y
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_HERMES is not set
+
+#
+# Wireless Pcmcia cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_AIRO_CS is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_KEYBDEV is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=38400
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_TOUCHSCREEN_ADS784X=y
+# CONFIG_UCB1200 is not set
+# CONFIG_TOUCHSCREEN_UCB1200 is not set
+# CONFIG_AUDIO_UCB1200 is not set
+# CONFIG_ADC_UCB1200 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_ADSSIO_I2C_ALGO=y
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_PROC is not set
+CONFIG_I2C_DS1307=y
+CONFIG_I2C_DS1307_ADS=y
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_SA1100_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_CRAMFS=y
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+# CONFIG_FB_SA1100 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_E13806=y
+CONFIG_E13806_REG_BASE=48000000
+CONFIG_E13806_FB_BASE=48200000
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=y
+# CONFIG_SOUND_UDA1341 is not set
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+# CONFIG_SOUND_SA1111_UDA1341 is not set
+CONFIG_SOUND_SA1111_AC97=y
+# CONFIG_SOUND_SA1100SSP is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/adsbitsy linux-2.4.22-pre3/arch/arm/def-configs/adsbitsy
--- linux-2.4.22-pre2/arch/arm/def-configs/adsbitsy	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/def-configs/adsbitsy	2003-07-05 18:09:35.000000000 -0700
@@ -1,5 +1,5 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 CONFIG_ARM=y
 # CONFIG_EISA is not set
@@ -8,6 +8,8 @@
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
 
 #
 # Code maturity level options
@@ -31,16 +33,25 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
 # CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
 CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
 
 #
 # Archimedes/A5000 Implementations
 #
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
 # CONFIG_ARCH_ARC is not set
 # CONFIG_ARCH_A5K is not set
 
@@ -56,15 +67,27 @@
 #
 # SA11x0 Implementations
 #
+# CONFIG_SA1100_ACCELENT is not set
 # CONFIG_SA1100_ASSABET is not set
 # CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+CONFIG_SA1100_ADSBITSY=y
+# CONFIG_SA1100_ADSBITSYPLUS is not set
 # CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
 # CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_BITSY is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
 # CONFIG_SA1100_EXTENEX1 is not set
 # CONFIG_SA1100_FLEXANET is not set
 # CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
 # CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HUW_WEBPANEL is not set
 # CONFIG_SA1100_ITSY is not set
@@ -73,40 +96,61 @@
 # CONFIG_SA1100_OMNIMETER is not set
 # CONFIG_SA1100_PANGOLIN is not set
 # CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 # CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
 # CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-CONFIG_SA1100_ADSBITSY=y
-CONFIG_SA1111=y
 # CONFIG_SA1100_USB is not set
 # CONFIG_SA1100_USB_NETLINK is not set
 # CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
 
 #
 # CLPS711X/EP721X Implementations
 #
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
 # CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
 # CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+
+#
+# Processor Type
+#
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
 # CONFIG_CPU_ARM610 is not set
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
 # CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
 # CONFIG_CPU_SA110 is not set
 CONFIG_CPU_SA1100=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
 CONFIG_DISCONTIGMEM=y
-# CONFIG_CPU_BIG_ENDIAN is not set
 
 #
 # General setup
@@ -114,6 +158,9 @@
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
 # CONFIG_CPU_FREQ is not set
 CONFIG_HOTPLUG=y
 
@@ -121,6 +168,8 @@
 # PCMCIA/CardBus support
 #
 CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 # CONFIG_TCIC is not set
 # CONFIG_PCMCIA_CLPS6700 is not set
@@ -129,6 +178,10 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
 CONFIG_FPE_NWFPE=y
 # CONFIG_FPE_FASTFPE is not set
 CONFIG_KCORE_ELF=y
@@ -136,12 +189,12 @@
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_PM is not set
-# CONFIG_APM is not set
+CONFIG_PM=y
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="ip=off"
-# CONFIG_PFS168_CMDLINE is not set
-# CONFIG_LEDS is not set
+CONFIG_CMDLINE="console=ttySA0 mem=32m@0xC0000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+# CONFIG_LEDS_CPU is not set
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -152,7 +205,79 @@
 #
 # Memory Technology Devices (MTD)
 #
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=8000000
+CONFIG_MTD_PHYSMAP_LEN=4000000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=4
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
 
 #
 # Plug and Play configuration
@@ -168,7 +293,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -184,6 +311,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -191,7 +319,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -204,13 +332,24 @@
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -228,6 +367,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -240,19 +384,27 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+# CONFIG_SMC9194 is not set
+CONFIG_SMC91111=y
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_NET_ISA is not set
 # CONFIG_NET_PCI is not set
@@ -262,21 +414,44 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
 # CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
-# CONFIG_PPP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_HERMES is not set
+
+#
+# Wireless Pcmcia cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_AIRO_CS is not set
+CONFIG_NET_WIRELESS=y
 
 #
 # Token Ring devices
@@ -299,6 +474,7 @@
 # CONFIG_PCMCIA_3C574 is not set
 # CONFIG_PCMCIA_FMVJ18X is not set
 CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
 # CONFIG_PCMCIA_NMCLAN is not set
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
@@ -317,7 +493,7 @@
 # CONFIG_IRDA is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
 
@@ -325,10 +501,15 @@
 # IDE, ATA and ATAPI Block devices
 #
 CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -343,6 +524,11 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
@@ -350,6 +536,9 @@
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_DMA_NONPCI is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -385,35 +574,47 @@
 # Character devices
 #
 CONFIG_VT=y
-# CONFIG_VT_CONSOLE is not set
+CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
 # CONFIG_SERIAL_AMBA is not set
 # CONFIG_SERIAL_AMBA_CONSOLE is not set
 # CONFIG_SERIAL_CLPS711X is not set
 # CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
 CONFIG_SERIAL_SA1100=y
 CONFIG_SERIAL_SA1100_CONSOLE=y
 CONFIG_SA1100_DEFAULT_BAUDRATE=38400
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
 # CONFIG_SERIAL_8250 is not set
 # CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
+# CONFIG_TOUCHSCREEN_ADS784X is not set
 CONFIG_UCB1200=y
 CONFIG_TOUCHSCREEN_UCB1200=y
 CONFIG_AUDIO_UCB1200=y
 CONFIG_ADC_UCB1200=y
-# CONFIG_TOUCHSCREEN_BITSY is not set
-# CONFIG_PROFILER is not set
-# CONFIG_PFS168_SPI is not set
-# CONFIG_PFS168_DTMF is not set
-# CONFIG_PFS168_MISC is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
 
 #
 # I2C support
@@ -421,6 +622,19 @@
 # CONFIG_I2C is not set
 
 #
+# L3 serial bus support
+#
+CONFIG_L3=y
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+CONFIG_L3_SA1111=y
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
@@ -429,14 +643,43 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_SA1100_RTC is not set
@@ -468,23 +711,29 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=y
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
 CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_CRAMFS=y
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -509,6 +758,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
@@ -526,6 +776,8 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
 
 #
 # Partition Types
@@ -560,6 +812,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
@@ -588,11 +841,11 @@
 CONFIG_FB=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
 # CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_SA1100=y
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_E1355 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E13806 is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB2=y
@@ -610,50 +863,169 @@
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=y
+CONFIG_SOUND_UDA1341=y
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+CONFIG_SOUND_SA1111_UDA1341=y
+# CONFIG_SOUND_SA1111_AC97 is not set
+# CONFIG_SOUND_SA1100SSP is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
 
 #
 # USB support
 #
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_UHCI is not set
 # CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
-CONFIG_USB_OHCI_NOPCI=y
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=y
+
+#
+# USB Device Class drivers
+#
 # CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
-# CONFIG_USB_HID is not set
-# CONFIG_USB_KBD is not set
-CONFIG_USB_MOUSE=y
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
 # CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
 # CONFIG_USB_DC2XX is not set
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_SCANNER is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
 # CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_NET1080 is not set
+# CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
 # CONFIG_USB_USS720 is not set
 
 #
 # USB Serial Converter support
 #
 # CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
 
 #
 # Bluetooth support
@@ -664,11 +1036,16 @@
 # Kernel hacking
 #
 CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_LL is not set
 # CONFIG_DEBUG_DC21285_PORT is not set
 # CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/adsbitsyplus linux-2.4.22-pre3/arch/arm/def-configs/adsbitsyplus
--- linux-2.4.22-pre2/arch/arm/def-configs/adsbitsyplus	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/def-configs/adsbitsyplus	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,1087 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+CONFIG_SA1100_ADSBITSYPLUS=y
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_CPU_FREQ is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+CONFIG_PCMCIA_SA1100=y
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PM=y
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttySA0 mem=32m@0xC0000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+# CONFIG_LEDS_CPU is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=8000000
+CONFIG_MTD_PHYSMAP_LEN=4000000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=4
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+# CONFIG_SMC9194 is not set
+CONFIG_SMC91111=y
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_HERMES is not set
+
+#
+# Wireless Pcmcia cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_AIRO_CS is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_KEYBDEV is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=38400
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_TOUCHSCREEN_ADS784X=y
+# CONFIG_UCB1200 is not set
+# CONFIG_TOUCHSCREEN_UCB1200 is not set
+# CONFIG_AUDIO_UCB1200 is not set
+# CONFIG_ADC_UCB1200 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_ADSSIO_I2C_ALGO=y
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_PROC is not set
+CONFIG_I2C_DS1307=y
+CONFIG_I2C_DS1307_ADS=y
+
+#
+# L3 serial bus support
+#
+CONFIG_L3=y
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+CONFIG_L3_SA1111=y
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_SA1100_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_CRAMFS=y
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+CONFIG_FB_SA1100=y
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E13806 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=y
+# CONFIG_SOUND_UDA1341 is not set
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+# CONFIG_SOUND_SA1111_UDA1341 is not set
+CONFIG_SOUND_SA1111_AC97=y
+# CONFIG_SOUND_SA1100SSP is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/at91rm9200dk linux-2.4.22-pre3/arch/arm/def-configs/at91rm9200dk
--- linux-2.4.22-pre2/arch/arm/def-configs/at91rm9200dk	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/def-configs/at91rm9200dk	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,773 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# AT91RM9200 Implementations
+#
+CONFIG_ARCH_AT91RM9200DK=y
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+CONFIG_CPU_ARM920T=y
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20210000,3145728 root=/dev/ram rw"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=10000000
+CONFIG_MTD_PHYSMAP_LEN=200000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=2
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+CONFIG_MTD_AT91_DATAFLASH=y
+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_AT91_SMARTMEDIA=y
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+CONFIG_AT91_ETHER=y
+CONFIG_AT91_ETHER_RMII=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_AT91_SPIDEV=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_AT91=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+# CONFIG_I2C_DS1307 is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_21285_WATCHDOG is not set
+# CONFIG_977_WATCHDOG is not set
+# CONFIG_SA1100_WATCHDOG is not set
+# CONFIG_OMAHA_WATCHDOG is not set
+CONFIG_AT91_WATCHDOG=y
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_AT91_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+CONFIG_USB_OHCI_AT91=y
+# 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
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_HID is not set
+# CONFIG_USB_HIDINPUT is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/cep linux-2.4.22-pre3/arch/arm/def-configs/cep
--- linux-2.4.22-pre2/arch/arm/def-configs/cep	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/def-configs/cep	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,615 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+CONFIG_SA1100_CEP=y
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttySA0,9600 root=/dev/ram"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=9600
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_SA1100_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/epxa10db linux-2.4.22-pre3/arch/arm/def-configs/epxa10db
--- linux-2.4.22-pre2/arch/arm/def-configs/epxa10db	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/def-configs/epxa10db	2003-07-05 18:09:35.000000000 -0700
@@ -8,6 +8,8 @@
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
 
 #
 # Code maturity level options
@@ -34,10 +36,14 @@
 CONFIG_ARCH_CAMELOT=y
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
 # CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
 
 #
 # Archimedes/A5000 Implementations
@@ -57,17 +63,25 @@
 #
 # SA11x0 Implementations
 #
+# CONFIG_SA1100_ACCELENT is not set
 # CONFIG_SA1100_ASSABET is not set
 # CONFIG_ASSABET_NEPONSET is not set
 # CONFIG_SA1100_ADSBITSY is not set
 # CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
 # CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
 # CONFIG_SA1100_EXTENEX1 is not set
 # CONFIG_SA1100_FLEXANET is not set
 # CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
 # CONFIG_SA1100_GRAPHICSCLIENT is not set
 # CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HUW_WEBPANEL is not set
 # CONFIG_SA1100_ITSY is not set
@@ -76,42 +90,59 @@
 # CONFIG_SA1100_OMNIMETER is not set
 # CONFIG_SA1100_PANGOLIN is not set
 # CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 # CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
 # CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
 
 #
 # CLPS711X/EP721X Implementations
 #
+# CONFIG_ARCH_AUTCPU12 is not set
 # CONFIG_ARCH_CDB89712 is not set
 # CONFIG_ARCH_CLEP7312 is not set
 # CONFIG_ARCH_EDB7211 is not set
 # CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
 # CONFIG_ARCH_EP7211 is not set
 # CONFIG_ARCH_EP7212 is not set
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
 # CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_EPXA10DB=y
+# CONFIG_EPXA1DB is not set
+# CONFIG_EPXA10DB_R2 is not set
+CONFIG_EPXA10DB_R3=y
+CONFIG_PLD=y
+# CONFIG_PLD_HOTSWAP is not set
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
 # CONFIG_CPU_ARM610 is not set
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
 CONFIG_CPU_ARM922T=y
-CONFIG_CPU_ARM92X_CPU_IDLE=y
-CONFIG_CPU_ARM92X_I_CACHE_ON=y
-CONFIG_CPU_ARM92X_D_CACHE_ON=y
-# CONFIG_CPU_ARM92X_WRITETHROUGH is not set
+CONFIG_PLD=y
+# CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
 # CONFIG_CPU_SA110 is not set
 # CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
 # CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_DISCONTIGMEM is not set
 
 #
@@ -120,6 +151,9 @@
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
 CONFIG_NET=y
@@ -130,7 +164,7 @@
 # CONFIG_FPE_FASTFPE is not set
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
@@ -150,8 +184,9 @@
 CONFIG_MTD_DEBUG=y
 CONFIG_MTD_DEBUG_VERBOSE=0
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_BOOTLDR_PARTS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AFS_PARTS is not set
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
@@ -171,42 +206,32 @@
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
 # CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SUN_UFLASH is not set
 # CONFIG_MTD_NORA is not set
-# CONFIG_MTD_PNC2000 is not set
-# CONFIG_MTD_RPXLITE is not set
-# CONFIG_MTD_TQM8XXL is not set
-# CONFIG_MTD_SC520CDP is not set
-# CONFIG_MTD_NETSC520 is not set
-# CONFIG_MTD_SBC_GXX is not set
-# CONFIG_MTD_ELAN_104NC is not set
-# CONFIG_MTD_DBOX2 is not set
-# CONFIG_MTD_CSTM_MIPS_IXX is not set
-CONFIG_MTD_EPXA10DB=y
-# CONFIG_MTD_CFI_FLAGADM is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-# CONFIG_MTD_MIXMEM is not set
-# CONFIG_MTD_OCTAGON is not set
-# CONFIG_MTD_VMAX is not set
-# CONFIG_MTD_OCELOT is not set
-# CONFIG_MTD_L440GX is not set
 # CONFIG_MTD_ARM_INTEGRATOR is not set
 # CONFIG_MTD_CDB89712 is not set
 # CONFIG_MTD_SA1100 is not set
 # CONFIG_MTD_DC21285 is not set
 # CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+CONFIG_MTD_EPXA=y
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
 
 #
 # Self-contained MTD device drivers
 #
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_LART is not set
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_DOC1000 is not set
@@ -224,7 +249,6 @@
 #
 # CONFIG_PNP is not set
 # CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
 
 #
 # Block devices
@@ -234,7 +258,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -250,6 +276,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -257,7 +284,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -270,13 +297,20 @@
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -294,6 +328,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -306,16 +345,18 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
 CONFIG_ETHER00=y
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -335,6 +376,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -343,8 +385,8 @@
 # CONFIG_PPP_FILTER is not set
 CONFIG_PPP_ASYNC=y
 CONFIG_PPP_SYNC_TTY=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
 # CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 
@@ -377,7 +419,7 @@
 # CONFIG_IRDA is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
@@ -435,6 +477,8 @@
 CONFIG_SERIAL_UART00_CONSOLE=y
 # CONFIG_SERIAL_SA1100 is not set
 # CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
 # CONFIG_SERIAL_8250 is not set
 # CONFIG_SERIAL_8250_CONSOLE is not set
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -460,7 +504,6 @@
 # CONFIG_L3_ALGOBIT is not set
 # CONFIG_L3_BIT_SA1100_GPIO is not set
 # CONFIG_L3_SA1111 is not set
-# CONFIG_L3_DRV_UDA1341 is not set
 # CONFIG_BIT_SA1100_GPIO is not set
 
 #
@@ -479,13 +522,11 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -513,7 +554,6 @@
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
-# CONFIG_CMS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
 # CONFIG_JBD_DEBUG is not set
@@ -522,16 +562,17 @@
 # CONFIG_UMSDOS_FS is not set
 # CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS_FS=y
-CONFIG_JFFS_FS_VERBOSE=0
-# CONFIG_JFFS2_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
 # CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
-# CONFIG_FREEVXFS_FS is not set
+# CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -557,7 +598,7 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
-# CONFIG_ROOT_NFS is not set
+CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
 CONFIG_SUNRPC=y
@@ -572,6 +613,8 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -582,66 +625,18 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
 # USB support
 #
 # CONFIG_USB is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_PLUSB is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
 
 #
 # Bluetooth support
@@ -652,11 +647,16 @@
 # Kernel hacking
 #
 CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
-CONFIG_MAGIC_SYSRQ=y
 # CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_LL=y
 # CONFIG_DEBUG_DC21285_PORT is not set
 # CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/epxa1db linux-2.4.22-pre3/arch/arm/def-configs/epxa1db
--- linux-2.4.22-pre2/arch/arm/def-configs/epxa1db	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/def-configs/epxa1db	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,703 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+CONFIG_ARCH_CAMELOT=y
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_EPXA10DB is not set
+CONFIG_EPXA1DB=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+CONFIG_CPU_ARM922T=y
+CONFIG_PLD=y
+CONFIG_CPU_ARM922_CPU_IDLE=y
+CONFIG_CPU_ARM922_I_CACHE_ON=y
+CONFIG_CPU_ARM922_D_CACHE_ON=y
+# CONFIG_CPU_ARM922_WRITETHROUGH is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_ARM_THUMB is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyUA0,38400 root=/dev/mtdblock0 rw"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=0
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+CONFIG_MTD_EPXA10DB=y
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ETHER00 is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+# CONFIG_SMC9194 is not set
+CONFIG_SMC91111=y
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+CONFIG_SERIAL_UART00=y
+CONFIG_SERIAL_UART00_CONSOLE=y
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/frodo linux-2.4.22-pre3/arch/arm/def-configs/frodo
--- linux-2.4.22-pre2/arch/arm/def-configs/frodo	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/def-configs/frodo	2003-07-05 18:09:35.000000000 -0700
@@ -37,6 +37,7 @@
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
 # CONFIG_ARCH_RPC is not set
 CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_SHARK is not set
@@ -59,10 +60,12 @@
 #
 # SA11x0 Implementations
 #
+# CONFIG_SA1100_ACCELENT is not set
 # CONFIG_SA1100_ASSABET is not set
 # CONFIG_ASSABET_NEPONSET is not set
 # CONFIG_SA1100_ADSBITSY is not set
 # CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
 # CONFIG_SA1100_CERF is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
@@ -71,6 +74,7 @@
 # CONFIG_SA1100_EXTENEX1 is not set
 # CONFIG_SA1100_FLEXANET is not set
 # CONFIG_SA1100_FREEBIRD is not set
+CONFIG_SA1100_FRODO=y
 # CONFIG_SA1100_GRAPHICSCLIENT is not set
 # CONFIG_SA1100_GRAPHICSMASTER is not set
 # CONFIG_SA1100_BADGE4 is not set
@@ -86,11 +90,11 @@
 # CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 # CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
 # CONFIG_SA1100_YOPY is not set
-CONFIG_SA1100_FRODO=y
 # CONFIG_SA1100_USB is not set
 # CONFIG_SA1100_USB_NETLINK is not set
 # CONFIG_SA1100_USB_CHAR is not set
@@ -113,18 +117,18 @@
 # CONFIG_FOOTBRIDGE_ADDIN is not set
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
 # CONFIG_CPU_ARM610 is not set
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
 # CONFIG_CPU_ARM920T is not set
 # CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
 # CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
 # CONFIG_CPU_SA110 is not set
 CONFIG_CPU_SA1100=y
-# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
 CONFIG_DISCONTIGMEM=y
 
 #
@@ -133,15 +137,28 @@
 # CONFIG_PCI is not set
 CONFIG_ISA=y
 # CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
 # CONFIG_CPU_FREQ is not set
-# CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+CONFIG_PCMCIA_SA1100=y
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-# CONFIG_FPE_NWFPE is not set
-CONFIG_FPE_FASTFPE=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
@@ -149,7 +166,7 @@
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="console=ttySA0,9600 ramdisk_size=4096 root=/dev/ram idebus=33"
+CONFIG_CMDLINE="console=ttySA0,115200 ramdisk_size=12288 root=/dev/ram idebus=33 mem=63M"
 CONFIG_LEDS=y
 CONFIG_LEDS_TIMER=y
 CONFIG_LEDS_CPU=y
@@ -163,7 +180,68 @@
 #
 # Memory Technology Devices (MTD)
 #
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
 
 #
 # Plug and Play configuration
@@ -179,11 +257,13 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_SIZE=12288
 CONFIG_BLK_DEV_INITRD=y
 
 #
@@ -201,7 +281,8 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -221,6 +302,11 @@
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -238,9 +324,98 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Network device support
 #
-# CONFIG_NETDEVICES is not set
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_CIRRUS=y
+# CONFIG_CIRRUS_DEBUG is not set
+# CONFIG_CIRRUS_DUPLEX is not set
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=y
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
 
 #
 # Amateur Radio support
@@ -253,7 +428,7 @@
 # CONFIG_IRDA is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
 
@@ -265,6 +440,7 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -274,11 +450,12 @@
 # CONFIG_BLK_DEV_IDEDISK_WD is not set
 # CONFIG_BLK_DEV_COMMERIAL is not set
 # CONFIG_BLK_DEV_TIVO is not set
-# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECS=y
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
@@ -312,11 +489,13 @@
 #
 # Input core support
 #
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+CONFIG_INPUT_EVDEV=y
 
 #
 # Character devices
@@ -343,7 +522,7 @@
 # CONFIG_SERIAL_UART00_CONSOLE is not set
 CONFIG_SERIAL_SA1100=y
 CONFIG_SERIAL_SA1100_CONSOLE=y
-CONFIG_SA1100_DEFAULT_BAUDRATE=9600
+CONFIG_SA1100_DEFAULT_BAUDRATE=115200
 # CONFIG_SERIAL_8250 is not set
 # CONFIG_SERIAL_8250_CONSOLE is not set
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -355,12 +534,22 @@
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=16
+CONFIG_UNIX98_PTY_COUNT=64
 
 #
 # I2C support
 #
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+CONFIG_I2C_FRODO=y
+# CONFIG_I2C_BIT_SA1100_GPIO is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+CONFIG_I2C_DS1307=y
 
 #
 # L3 serial bus support
@@ -381,16 +570,61 @@
 # Joysticks
 #
 # CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
 # Watchdog Cards
 #
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_SA1100_RTC=y
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_21285_WATCHDOG is not set
+# CONFIG_977_WATCHDOG is not set
+CONFIG_SA1100_WATCHDOG=y
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+CONFIG_DS1307_RTC=y
+CONFIG_DS1307_NVRAM=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -403,9 +637,50 @@
 # CONFIG_DRM is not set
 
 #
+# PCMCIA character devices
+#
+
+#
 # Multimedia devices
 #
-# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_DEV=y
+
+#
+# Video For Linux
+#
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZORAN_BUZ is not set
+# CONFIG_VIDEO_ZORAN_DC10 is not set
+# CONFIG_VIDEO_ZORAN_LML33 is not set
+# CONFIG_VIDEO_ZR36120 is not set
+# CONFIG_VIDEO_MEYE is not set
+# CONFIG_VIDEO_CYBERPRO is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_RADIO_MIROPCM20 is not set
+# CONFIG_RADIO_MIROPCM20_RDS is not set
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
 
 #
 # File systems
@@ -424,32 +699,33 @@
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
 # CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
 # CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
 # CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
-CONFIG_ROMFS_FS=y
+# CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UDF_FS is not set
@@ -479,8 +755,8 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
+CONFIG_ZISOFS_FS=y
+CONFIG_ZLIB_FS_INFLATE=y
 
 #
 # Partition Types
@@ -488,11 +764,54 @@
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Console drivers
 #
+CONFIG_PC_KEYB=y
 CONFIG_PC_KEYMAP=y
 # CONFIG_VGA_CONSOLE is not set
 
@@ -507,15 +826,32 @@
 CONFIG_FB_SA1100=y
 # CONFIG_FB_CYBER2000 is not set
 # CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_CFB2=y
-CONFIG_FBCON_CFB4=y
-CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+# CONFIG_FBCON_CFB8 is not set
 CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
 # CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-# CONFIG_FBCON_FONTS is not set
-CONFIG_FONT_8x8=y
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
 CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
 
 #
 # Sound
@@ -534,12 +870,19 @@
 #
 # USB support
 #
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+# CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_UHCI is not set
 # CONFIG_USB_UHCI_ALT is not set
 # CONFIG_USB_OHCI is not set
 # CONFIG_USB_OHCI_SA1111 is not set
+CONFIG_USB_1161=y
 # 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
@@ -552,12 +895,25 @@
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_WACOM is not set
 # CONFIG_USB_DC2XX is not set
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_SCANNER is not set
 # CONFIG_USB_MICROTEK is not set
 # CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_DABUSB is not set
 # 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
@@ -575,6 +931,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
@@ -588,11 +945,14 @@
 # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
 
 #
 # Bluetooth support
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/graphicsclient linux-2.4.22-pre3/arch/arm/def-configs/graphicsclient
--- linux-2.4.22-pre2/arch/arm/def-configs/graphicsclient	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/def-configs/graphicsclient	2003-07-05 18:09:35.000000000 -0700
@@ -8,6 +8,8 @@
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
 
 #
 # Code maturity level options
@@ -31,12 +33,17 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
 # CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
 CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
 
 #
 # Archimedes/A5000 Implementations
@@ -60,15 +67,27 @@
 #
 # SA11x0 Implementations
 #
+# CONFIG_SA1100_ACCELENT is not set
 # CONFIG_SA1100_ASSABET is not set
 # CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
 # CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
 # CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_BITSY is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
 # CONFIG_SA1100_EXTENEX1 is not set
 # CONFIG_SA1100_FLEXANET is not set
 # CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
 CONFIG_SA1100_GRAPHICSCLIENT=y
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HUW_WEBPANEL is not set
 # CONFIG_SA1100_ITSY is not set
@@ -77,43 +96,59 @@
 # CONFIG_SA1100_OMNIMETER is not set
 # CONFIG_SA1100_PANGOLIN is not set
 # CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 # CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
 # CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_ADSBITSY is not set
 # CONFIG_SA1100_USB is not set
 # CONFIG_SA1100_USB_NETLINK is not set
 # CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
 
 #
 # CLPS711X/EP721X Implementations
 #
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
 # CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
 # CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
 
 #
 # Processor Type
 #
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
 # CONFIG_CPU_ARM610 is not set
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
 # CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
 # CONFIG_CPU_SA110 is not set
 CONFIG_CPU_SA1100=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
 CONFIG_DISCONTIGMEM=y
-# CONFIG_CPU_BIG_ENDIAN is not set
 
 #
 # General setup
@@ -121,6 +156,9 @@
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
 # CONFIG_CPU_FREQ is not set
 CONFIG_HOTPLUG=y
 
@@ -128,6 +166,8 @@
 # PCMCIA/CardBus support
 #
 CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 # CONFIG_TCIC is not set
 # CONFIG_PCMCIA_CLPS6700 is not set
@@ -136,6 +176,10 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
 CONFIG_FPE_NWFPE=y
 # CONFIG_FPE_FASTFPE is not set
 CONFIG_KCORE_ELF=y
@@ -143,11 +187,9 @@
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_PM is not set
-# CONFIG_APM is not set
+CONFIG_PM=y
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="ip=off"
-# CONFIG_PFS168_CMDLINE is not set
+CONFIG_CMDLINE="console=ttySA0 mem=16m@0xC0000000 mem=16m@0xC8000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram"
 CONFIG_LEDS=y
 CONFIG_LEDS_TIMER=y
 CONFIG_LEDS_CPU=y
@@ -164,8 +206,9 @@
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_BOOTLDR_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
 
 #
@@ -180,53 +223,44 @@
 # RAM/ROM/Flash chip drivers
 #
 CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
 # CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_JEDEC is not set
 
 #
 # Mapping drivers for chip access
 #
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=800000
-CONFIG_MTD_PHYSMAP_LEN=1000000
+CONFIG_MTD_PHYSMAP_START=8000000
+CONFIG_MTD_PHYSMAP_LEN=2000000
 CONFIG_MTD_PHYSMAP_BUSWIDTH=4
-# CONFIG_MTD_SUN_UFLASH is not set
 # CONFIG_MTD_NORA is not set
-# CONFIG_MTD_PNC2000 is not set
-# CONFIG_MTD_RPXLITE is not set
-# CONFIG_MTD_TQM8XXL is not set
-# CONFIG_MTD_SC520CDP is not set
-# CONFIG_MTD_NETSC520 is not set
-# CONFIG_MTD_SBC_GXX is not set
-# CONFIG_MTD_ELAN_104NC is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
 CONFIG_MTD_SA1100=y
-# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
-# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
 # CONFIG_MTD_DC21285 is not set
 # CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_DBOX2 is not set
-# CONFIG_MTD_CSTM_MIPS_IXX is not set
-# CONFIG_MTD_CFI_FLAGADM is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-# CONFIG_MTD_MIXMEM is not set
-# CONFIG_MTD_OCTAGON is not set
-# CONFIG_MTD_VMAX is not set
-# CONFIG_MTD_OCELOT is not set
-# CONFIG_MTD_L440GX is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
 
 #
 # Self-contained MTD device drivers
 #
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_LART is not set
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_BLKMTD is not set
 
@@ -257,8 +291,10 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
@@ -273,6 +309,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -280,7 +317,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -293,17 +330,24 @@
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
 
 #
-#  
+#
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -321,6 +365,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -333,15 +382,17 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -351,6 +402,7 @@
 # CONFIG_ULTRA is not set
 # CONFIG_ULTRA32 is not set
 CONFIG_SMC9194=y
+# CONFIG_SMC91111 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_NET_ISA is not set
 # CONFIG_NET_PCI is not set
@@ -360,21 +412,44 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
 # CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
-# CONFIG_PPP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_HERMES is not set
+
+#
+# Wireless Pcmcia cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_AIRO_CS is not set
+CONFIG_NET_WIRELESS=y
 
 #
 # Token Ring devices
@@ -397,6 +472,7 @@
 # CONFIG_PCMCIA_3C574 is not set
 # CONFIG_PCMCIA_FMVJ18X is not set
 CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
 # CONFIG_PCMCIA_NMCLAN is not set
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
@@ -415,7 +491,7 @@
 # CONFIG_IRDA is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
 
@@ -431,6 +507,7 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -445,6 +522,7 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
 
 #
 # IDE chipset support/bugfixes
@@ -456,6 +534,9 @@
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_DMA_NONPCI is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -479,46 +560,84 @@
 #
 # Input core support
 #
-# CONFIG_INPUT is not set
+CONFIG_INPUT=y
+# CONFIG_INPUT_KEYBDEV is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Character devices
 #
 CONFIG_VT=y
-# CONFIG_VT_CONSOLE is not set
+CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
 # CONFIG_SERIAL_AMBA is not set
 # CONFIG_SERIAL_AMBA_CONSOLE is not set
 # CONFIG_SERIAL_CLPS711X is not set
 # CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
 CONFIG_SERIAL_SA1100=y
 CONFIG_SERIAL_SA1100_CONSOLE=y
 CONFIG_SA1100_DEFAULT_BAUDRATE=38400
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
 # CONFIG_SERIAL_8250 is not set
 # CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
+# CONFIG_TOUCHSCREEN_ADS784X is not set
 CONFIG_UCB1200=y
 CONFIG_TOUCHSCREEN_UCB1200=y
 CONFIG_AUDIO_UCB1200=y
 CONFIG_ADC_UCB1200=y
-# CONFIG_TOUCHSCREEN_BITSY is not set
-# CONFIG_PROFILER is not set
-# CONFIG_PFS168_SPI is not set
-# CONFIG_PFS168_DTMF is not set
-# CONFIG_PFS168_MISC is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
 
 #
 # I2C support
 #
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_ADSSIO_I2C_ALGO=y
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_PROC is not set
+CONFIG_I2C_DS1307=y
+CONFIG_I2C_DS1307_ADS=y
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
 
 #
 # Mice
@@ -529,18 +648,43 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
 
 #
-# Input core support is needed for joysticks
+# Joysticks
 #
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_SA1100_RTC is not set
@@ -572,18 +716,21 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=y
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
 CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS_FS=y
-CONFIG_JFFS_FS_VERBOSE=0
+# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_CRAMFS=y
@@ -591,6 +738,7 @@
 CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -615,6 +763,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
@@ -632,6 +781,8 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
 
 #
 # Partition Types
@@ -666,6 +817,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
@@ -694,11 +846,11 @@
 CONFIG_FB=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
 # CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_SA1100=y
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_E1355 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E13806 is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB2=y
@@ -719,6 +871,15 @@
 # CONFIG_SOUND is not set
 
 #
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
 # USB support
 #
 # CONFIG_USB is not set
@@ -732,11 +893,16 @@
 # Kernel hacking
 #
 CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_LL is not set
 # CONFIG_DEBUG_DC21285_PORT is not set
 # CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/graphicsmaster linux-2.4.22-pre3/arch/arm/def-configs/graphicsmaster
--- linux-2.4.22-pre2/arch/arm/def-configs/graphicsmaster	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/def-configs/graphicsmaster	2003-07-05 18:09:35.000000000 -0700
@@ -1,5 +1,5 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 CONFIG_ARM=y
 # CONFIG_EISA is not set
@@ -8,6 +8,8 @@
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
 
 #
 # Code maturity level options
@@ -31,16 +33,25 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
 # CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
 CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
 
 #
 # Archimedes/A5000 Implementations
 #
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
 # CONFIG_ARCH_ARC is not set
 # CONFIG_ARCH_A5K is not set
 
@@ -56,15 +67,27 @@
 #
 # SA11x0 Implementations
 #
+# CONFIG_SA1100_ACCELENT is not set
 # CONFIG_SA1100_ASSABET is not set
 # CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
 # CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
 # CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_BITSY is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
 # CONFIG_SA1100_EXTENEX1 is not set
 # CONFIG_SA1100_FLEXANET is not set
 # CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
 # CONFIG_SA1100_GRAPHICSCLIENT is not set
+CONFIG_SA1100_GRAPHICSMASTER=y
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HUW_WEBPANEL is not set
 # CONFIG_SA1100_ITSY is not set
@@ -73,40 +96,61 @@
 # CONFIG_SA1100_OMNIMETER is not set
 # CONFIG_SA1100_PANGOLIN is not set
 # CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 # CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
 # CONFIG_SA1100_YOPY is not set
-CONFIG_SA1100_GRAPHICSMASTER=y
-# CONFIG_SA1100_ADSBITSY is not set
-CONFIG_SA1111=y
 # CONFIG_SA1100_USB is not set
 # CONFIG_SA1100_USB_NETLINK is not set
 # CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
 
 #
 # CLPS711X/EP721X Implementations
 #
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
 # CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
 # CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+
+#
+# Processor Type
+#
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
 # CONFIG_CPU_ARM610 is not set
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
 # CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
 # CONFIG_CPU_SA110 is not set
 CONFIG_CPU_SA1100=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
 CONFIG_DISCONTIGMEM=y
-# CONFIG_CPU_BIG_ENDIAN is not set
 
 #
 # General setup
@@ -114,6 +158,9 @@
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
 # CONFIG_CPU_FREQ is not set
 CONFIG_HOTPLUG=y
 
@@ -121,6 +168,8 @@
 # PCMCIA/CardBus support
 #
 CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 # CONFIG_TCIC is not set
 # CONFIG_PCMCIA_CLPS6700 is not set
@@ -129,6 +178,10 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
 CONFIG_FPE_NWFPE=y
 # CONFIG_FPE_FASTFPE is not set
 CONFIG_KCORE_ELF=y
@@ -136,11 +189,9 @@
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_PM is not set
-# CONFIG_APM is not set
+CONFIG_PM=y
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="ip=off"
-# CONFIG_PFS168_CMDLINE is not set
+CONFIG_CMDLINE="console=ttySA0 mem=16m@0xC0000000 mem=16m@0xC8000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram"
 CONFIG_LEDS=y
 CONFIG_LEDS_TIMER=y
 CONFIG_LEDS_CPU=y
@@ -157,9 +208,14 @@
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_BOOTLDR_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
@@ -169,55 +225,50 @@
 # RAM/ROM/Flash chip drivers
 #
 CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
 # CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_JEDEC is not set
 
 #
 # Mapping drivers for chip access
 #
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=800000
-CONFIG_MTD_PHYSMAP_LEN=1000000
+CONFIG_MTD_PHYSMAP_START=8000000
+CONFIG_MTD_PHYSMAP_LEN=4000000
 CONFIG_MTD_PHYSMAP_BUSWIDTH=4
-# CONFIG_MTD_SUN_UFLASH is not set
 # CONFIG_MTD_NORA is not set
-# CONFIG_MTD_PNC2000 is not set
-# CONFIG_MTD_RPXLITE is not set
-# CONFIG_MTD_TQM8XXL is not set
-# CONFIG_MTD_SC520CDP is not set
-# CONFIG_MTD_NETSC520 is not set
-# CONFIG_MTD_SBC_GXX is not set
-# CONFIG_MTD_ELAN_104NC is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
 CONFIG_MTD_SA1100=y
-# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
-# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
 # CONFIG_MTD_DC21285 is not set
 # CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_DBOX2 is not set
-# CONFIG_MTD_CSTM_MIPS_IXX is not set
-# CONFIG_MTD_CFI_FLAGADM is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-# CONFIG_MTD_MIXMEM is not set
-# CONFIG_MTD_OCTAGON is not set
-# CONFIG_MTD_VMAX is not set
-# CONFIG_MTD_OCELOT is not set
-# CONFIG_MTD_L440GX is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
 
 #
 # Self-contained MTD device drivers
 #
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_LART is not set
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
 # CONFIG_MTD_DOC1000 is not set
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
@@ -242,8 +293,10 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
@@ -258,6 +311,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -265,7 +319,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -278,13 +332,24 @@
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -302,6 +367,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -314,15 +384,17 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -332,6 +404,7 @@
 # CONFIG_ULTRA is not set
 # CONFIG_ULTRA32 is not set
 CONFIG_SMC9194=y
+# CONFIG_SMC91111 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_NET_ISA is not set
 # CONFIG_NET_PCI is not set
@@ -341,21 +414,44 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
 # CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
-# CONFIG_PPP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_HERMES is not set
+
+#
+# Wireless Pcmcia cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_AIRO_CS is not set
+CONFIG_NET_WIRELESS=y
 
 #
 # Token Ring devices
@@ -378,6 +474,7 @@
 # CONFIG_PCMCIA_3C574 is not set
 # CONFIG_PCMCIA_FMVJ18X is not set
 CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
 # CONFIG_PCMCIA_NMCLAN is not set
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
@@ -396,7 +493,7 @@
 # CONFIG_IRDA is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
 
@@ -404,10 +501,15 @@
 # IDE, ATA and ATAPI Block devices
 #
 CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -422,6 +524,11 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
@@ -429,6 +536,9 @@
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_DMA_NONPCI is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -464,35 +574,47 @@
 # Character devices
 #
 CONFIG_VT=y
-# CONFIG_VT_CONSOLE is not set
+CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
 # CONFIG_SERIAL_AMBA is not set
 # CONFIG_SERIAL_AMBA_CONSOLE is not set
 # CONFIG_SERIAL_CLPS711X is not set
 # CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
 CONFIG_SERIAL_SA1100=y
 CONFIG_SERIAL_SA1100_CONSOLE=y
 CONFIG_SA1100_DEFAULT_BAUDRATE=38400
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
+# CONFIG_TOUCHSCREEN_ADS784X is not set
 CONFIG_UCB1200=y
 CONFIG_TOUCHSCREEN_UCB1200=y
 CONFIG_AUDIO_UCB1200=y
 CONFIG_ADC_UCB1200=y
-# CONFIG_TOUCHSCREEN_BITSY is not set
-# CONFIG_PROFILER is not set
-# CONFIG_PFS168_SPI is not set
-# CONFIG_PFS168_DTMF is not set
-# CONFIG_PFS168_MISC is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
 
 #
 # I2C support
@@ -500,6 +622,19 @@
 # CONFIG_I2C is not set
 
 #
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
@@ -508,14 +643,43 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_SA1100_RTC is not set
@@ -533,6 +697,7 @@
 #
 # PCMCIA character devices
 #
+# CONFIG_PCMCIA_SERIAL_CS is not set
 
 #
 # Multimedia devices
@@ -547,18 +712,21 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=y
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
 CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS_FS=y
-CONFIG_JFFS_FS_VERBOSE=0
+# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_CRAMFS=y
@@ -566,6 +734,7 @@
 CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -590,6 +759,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
@@ -607,6 +777,8 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
 
 #
 # Partition Types
@@ -641,6 +813,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
@@ -669,11 +842,11 @@
 CONFIG_FB=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
 # CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_SA1100=y
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_E1355 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E13806 is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB2=y
@@ -691,50 +864,169 @@
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=y
+# CONFIG_SOUND_UDA1341 is not set
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+# CONFIG_SOUND_SA1111_UDA1341 is not set
+# CONFIG_SOUND_SA1111_AC97 is not set
+# CONFIG_SOUND_SA1100SSP is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
 
 #
 # USB support
 #
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_UHCI is not set
 # CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
-CONFIG_USB_OHCI_NOPCI=y
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=y
+
+#
+# USB Device Class drivers
+#
 # CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
-# CONFIG_USB_HID is not set
-# CONFIG_USB_KBD is not set
-CONFIG_USB_MOUSE=y
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
 # CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
 # CONFIG_USB_DC2XX is not set
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_SCANNER is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
 # CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_NET1080 is not set
+# CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
 # CONFIG_USB_USS720 is not set
 
 #
 # USB Serial Converter support
 #
 # CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
 
 #
 # Bluetooth support
@@ -745,11 +1037,16 @@
 # Kernel hacking
 #
 CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_LL is not set
 # CONFIG_DEBUG_DC21285_PORT is not set
 # CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/lusl7200 linux-2.4.22-pre3/arch/arm/def-configs/lusl7200
--- linux-2.4.22-pre2/arch/arm/def-configs/lusl7200	2000-06-19 17:59:33.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/def-configs/lusl7200	2003-07-05 18:09:35.000000000 -0700
@@ -23,6 +23,9 @@
 # CONFIG_CPU_26 is not set
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ARM720=y
+CONFIG_ZBOOT_ROM=y
+CONFIG_ZBOOT_ROM_TEXT=0x00010000
+CONFIG_ZBOOT_ROM_BSS=0xf03e0000
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_ISA_DMA is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/nanoengine linux-2.4.22-pre3/arch/arm/def-configs/nanoengine
--- linux-2.4.22-pre2/arch/arm/def-configs/nanoengine	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/def-configs/nanoengine	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,775 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+CONFIG_SA1100_NANOENGINE=y
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+CONFIG_ZBOOT_ROM=y
+CONFIG_ZBOOT_ROM_TEXT=11000
+CONFIG_ZBOOT_ROM_BSS=c1fc0000
+# CONFIG_CPU_FREQ is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/ram"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=1
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_BOOTLDR_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+CONFIG_MTD_MTDRAM=y
+CONFIG_MTDRAM_TOTAL_SIZE=2048
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTDRAM_ABS_POS=0
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=9600
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=64
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_SA1100_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=1
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/omaha linux-2.4.22-pre3/arch/arm/def-configs/omaha
--- linux-2.4.22-pre2/arch/arm/def-configs/omaha	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/def-configs/omaha	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,798 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+CONFIG_ARCH_OMAHA=y
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_ARM920_CPU_IDLE=y
+CONFIG_CPU_ARM920_I_CACHE_ON=y
+CONFIG_CPU_ARM920_D_CACHE_ON=y
+# CONFIG_CPU_ARM920_WRITETHROUGH is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_ARM_THUMB is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+CONFIG_SMC91C111=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_ARM_DCC is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+CONFIG_I2C_OMAHA=y
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_21285_WATCHDOG is not set
+# CONFIG_977_WATCHDOG is not set
+# CONFIG_SA1100_WATCHDOG is not set
+CONFIG_OMAHA_WATCHDOG=y
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_OMAHA_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_UMSDOS_FS=y
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# Omaha /proc drivers
+#
+CONFIG_OMAHA_MISC=y
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/riscstation linux-2.4.22-pre3/arch/arm/def-configs/riscstation
--- linux-2.4.22-pre2/arch/arm/def-configs/riscstation	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/def-configs/riscstation	2003-07-05 18:09:35.000000000 -0700
@@ -0,0 +1,766 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_RISCSTATION=y
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_CPU_32v3=y
+# CONFIG_CPU_32v4 is not set
+# CONFIG_CPU_ARM610 is not set
+CONFIG_CPU_ARM710=y
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_ARM_THUMB is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="ip=dhcp"
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_ETHER1 is not set
+# CONFIG_ARM_ETHER3 is not set
+# CONFIG_ARM_ETHERH is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+CONFIG_BLK_DEV_IDE_RISCSTATION=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+# CONFIG_PSMOUSE is not set
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+CONFIG_7K5MOUSE=y
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_ADFS_FS=y
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_EESOX=y
+CONFIG_ACORN_PARTITION_ICS=y
+CONFIG_ACORN_PARTITION_ADFS=y
+CONFIG_ACORN_PARTITION_POWERTEC=y
+CONFIG_ACORN_PARTITION_RISCIX=y
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_ACORN=y
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+# CONFIG_FB_SA1100 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_MFB=y
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_ACORN_8x8=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/sherman linux-2.4.22-pre3/arch/arm/def-configs/sherman
--- linux-2.4.22-pre2/arch/arm/def-configs/sherman	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/def-configs/sherman	2003-07-05 18:09:35.000000000 -0700
@@ -47,6 +47,9 @@
 #
 # General setup
 #
+CONFIG_ZBOOT_ROM=y
+CONFIG_ZBOOT_ROM_TEXT=0x00050000
+CONFIG_ZBOOT_ROM_BSS=0xc0200000
 # CONFIG_NET is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
diff -urN linux-2.4.22-pre2/arch/arm/def-configs/victor linux-2.4.22-pre3/arch/arm/def-configs/victor
--- linux-2.4.22-pre2/arch/arm/def-configs/victor	2000-06-19 17:59:33.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/def-configs/victor	2003-07-05 18:09:35.000000000 -0700
@@ -46,6 +46,9 @@
 #
 # General setup
 #
+CONFIG_ZBOOT_ROM=y
+CONFIG_ZBOOT_ROM_TEXT=0x00002000
+CONFIG_ZBOOT_ROM_BSS=0xc0200000
 # CONFIG_NET is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
diff -urN linux-2.4.22-pre2/arch/arm/kernel/Makefile linux-2.4.22-pre3/arch/arm/kernel/Makefile
--- linux-2.4.22-pre2/arch/arm/kernel/Makefile	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/Makefile	2003-07-05 18:09:35.000000000 -0700
@@ -18,6 +18,7 @@
 O_OBJS_rpc        = dma-rpc.o
 O_OBJS_footbridge = dma-footbridge.o isa.o
 O_OBJS_l7200      = fiq.o
+O_OBJS_riscstation = fiq.o dma-riscstation.o
 
 pci-ftvpci	  = plx90x0.o
 pci-footbridge	  = dec21285.o
@@ -43,7 +44,8 @@
 no-irq-arch	:= $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
 		   $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
 		   $(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT) \
-		   $(CONFIG_ARCH_MX1ADS)
+		   $(CONFIG_ARCH_MX1ADS) $(CONFIG_ARCH_OMAHA) \
+		   $(CONFIG_ARCH_AT91RM9200)
 
 ifneq ($(findstring y,$(no-irq-arch)),y)
   obj-y		+= irq-arch.o
@@ -51,6 +53,7 @@
 
 obj-$(CONFIG_ARCH_ACORN) += ecard.o fiq.o time-acorn.o
 obj-$(CONFIG_ARCH_CLPS7500) += time-acorn.o
+obj-$(CONFIG_ARCH_RISCSTATION) += time-acorn.o
 obj-$(CONFIG_DEBUG_LL)	+= debug-$(PROCESSOR).o
 obj-$(CONFIG_MODULES)	+= armksyms.o
 obj-$(CONFIG_ARTHUR)	+= arthur.o
diff -urN linux-2.4.22-pre2/arch/arm/kernel/arch.c linux-2.4.22-pre3/arch/arm/kernel/arch.c
--- linux-2.4.22-pre2/arch/arm/kernel/arch.c	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/arch.c	2003-07-05 18:09:35.000000000 -0700
@@ -20,7 +20,7 @@
 
 unsigned int vram_size;
 
-#ifdef CONFIG_ARCH_ACORN
+#if defined(CONFIG_ARCH_ACORN) || defined(CONFIG_ARCH_RISCSTATION)
 
 unsigned int memc_ctrl_reg;
 unsigned int number_mfm_drives;
@@ -49,7 +49,8 @@
 
 __tagtable(ATAG_ACORN, parse_tag_acorn);
 
-#ifdef CONFIG_ARCH_RPC
+
+#if defined(CONFIG_ARCH_RPC) || defined(CONFIG_ARCH_RISCSTATION)
 static void __init
 fixup_riscpc(struct machine_desc *desc, struct param_struct *unusd,
 	    char **cmdline, struct meminfo *mi)
@@ -61,7 +62,9 @@
 }
 
 extern void __init rpc_map_io(void);
+extern void __init riscstation_map_io(void);
 
+#ifdef CONFIG_ARCH_RPC
 MACHINE_START(RISCPC, "Acorn-RiscPC")
 	MAINTAINER("Russell King")
 	BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
@@ -73,6 +76,20 @@
 	INITIRQ(genarch_init_irq)
 MACHINE_END
 #endif
+
+#ifdef CONFIG_ARCH_RISCSTATION
+/* TODO = check all parameters */
+MACHINE_START(RISCSTATION, "RiscStation-RS7500")
+	MAINTAINER("Ben Dooks, Vincent Sanders")
+	BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
+	BOOT_PARAMS(0x10000100)
+	FIXUP(fixup_riscpc)
+	MAPIO(riscstation_map_io)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+
+#endif /* CONFIG_ARCH_RPC | CONFIG_ARCH_RISCSTATION */
 #ifdef CONFIG_ARCH_ARC
 MACHINE_START(ARCHIMEDES, "Acorn-Archimedes")
 	MAINTAINER("Dave Gilbert")
diff -urN linux-2.4.22-pre2/arch/arm/kernel/armksyms.c linux-2.4.22-pre3/arch/arm/kernel/armksyms.c
--- linux-2.4.22-pre2/arch/arm/kernel/armksyms.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/armksyms.c	2003-07-05 18:09:35.000000000 -0700
@@ -62,9 +62,11 @@
 extern void __muldi3(void);
 extern void __ucmpdi2(void);
 extern void __udivdi3(void);
+extern void __umoddi3(void);
 extern void __udivmoddi4(void);
 extern void __udivsi3(void);
 extern void __umodsi3(void);
+extern void abort(void);
 
 extern void ret_from_exception(void);
 extern void fpundefinstr(void);
@@ -106,7 +108,9 @@
 	/* platform dependent support */
 EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(udelay);
+EXPORT_SYMBOL(__udelay);
+EXPORT_SYMBOL(__ndelay);
+EXPORT_SYMBOL(__const_delay);
 #ifdef CONFIG_CPU_32
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(__iounmap);
@@ -189,6 +193,7 @@
 EXPORT_SYMBOL_NOVERS(memmove);
 EXPORT_SYMBOL_NOVERS(memcmp);
 EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(memchr);
 EXPORT_SYMBOL_NOVERS(__memzero);
 
 	/* user mem (segment) */
@@ -228,6 +233,7 @@
 EXPORT_SYMBOL_NOVERS(__muldi3);
 EXPORT_SYMBOL_NOVERS(__ucmpdi2);
 EXPORT_SYMBOL_NOVERS(__udivdi3);
+EXPORT_SYMBOL_NOVERS(__umoddi3);
 EXPORT_SYMBOL_NOVERS(__udivmoddi4);
 EXPORT_SYMBOL_NOVERS(__udivsi3);
 EXPORT_SYMBOL_NOVERS(__umodsi3);
diff -urN linux-2.4.22-pre2/arch/arm/kernel/arthur.c linux-2.4.22-pre3/arch/arm/kernel/arthur.c
--- linux-2.4.22-pre2/arch/arm/kernel/arthur.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/arthur.c	2003-07-05 18:09:35.000000000 -0700
@@ -46,7 +46,7 @@
 /*
  * Linux to Arthur signal map.
  */
-static unsigned long linux_to_arthur_signals[32] = {
+static unsigned long arthur_invmap[32] = {
 	[0]		= 0,
 	[SIGHUP]	= -1,
 	[SIGINT]	= ARTHUR_SIGINT,
@@ -97,7 +97,7 @@
 	.pers_low	= PER_RISCOS,
 	.pers_high	= PER_RISCOS,
 	.signal_map	= arthur_to_linux_signals,
-	.signal_invmap	= linux_to_arthur_signals,
+	.signal_invmap	= arthur_invmap,
 	.module		= THIS_MODULE,
 };
 
diff -urN linux-2.4.22-pre2/arch/arm/kernel/bios32.c linux-2.4.22-pre3/arch/arm/kernel/bios32.c
--- linux-2.4.22-pre2/arch/arm/kernel/bios32.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/kernel/bios32.c	2003-07-05 18:09:35.000000000 -0700
@@ -584,7 +584,7 @@
  * pcibios_enable_device - Enable I/O and memory.
  * @dev: PCI device to be enabled
  */
-int pcibios_enable_device(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	u16 cmd, old_cmd;
 	int idx;
@@ -593,6 +593,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"
@@ -604,6 +608,13 @@
 		if (r->flags & IORESOURCE_MEM)
 			cmd |= PCI_COMMAND_MEMORY;
 	}
+
+	/*
+	 * Bridges (eg, cardbus bridges) need to be fully enabled
+	 */
+	if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
+		cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+
 	if (cmd != old_cmd) {
 		printk("PCI: enabling device %s (%04x -> %04x)\n",
 		       dev->slot_name, old_cmd, cmd);
diff -urN linux-2.4.22-pre2/arch/arm/kernel/calls.S linux-2.4.22-pre3/arch/arm/kernel/calls.S
--- linux-2.4.22-pre2/arch/arm/kernel/calls.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/calls.S	2003-07-05 18:09:35.000000000 -0700
@@ -1,7 +1,7 @@
 /*
- *  linux/arch/arm/lib/calls.h
+ *  linux/arch/arm/kernel/calls.S
  *
- *  Copyright (C) 1995-1998 Russell King
+ *  Copyright (C) 1995-2003 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -10,7 +10,7 @@
  *  This file is included twice in entry-common.S
  */
 #ifndef NR_syscalls
-#define NR_syscalls 256
+#define NR_syscalls 288
 #else
 
 __syscall_start:
@@ -21,13 +21,13 @@
 		.long	SYMBOL_NAME(sys_write)
 /* 5 */		.long	SYMBOL_NAME(sys_open)
 		.long	SYMBOL_NAME(sys_close)
-		.long	SYMBOL_NAME(sys_waitpid)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_waitpid */
 		.long	SYMBOL_NAME(sys_creat)
 		.long	SYMBOL_NAME(sys_link)
 /* 10 */	.long	SYMBOL_NAME(sys_unlink)
 		.long	SYMBOL_NAME(sys_execve_wrapper)
 		.long	SYMBOL_NAME(sys_chdir)
-		.long	SYMBOL_NAME(sys_time)
+		.long	SYMBOL_NAME(sys_time)			/* used by libc4 */
 		.long	SYMBOL_NAME(sys_mknod)
 /* 15 */	.long	SYMBOL_NAME(sys_chmod)
 		.long	SYMBOL_NAME(sys_lchown16)
@@ -36,15 +36,15 @@
 		.long	SYMBOL_NAME(sys_lseek)
 /* 20 */	.long	SYMBOL_NAME(sys_getpid)
 		.long	SYMBOL_NAME(sys_mount)
-		.long	SYMBOL_NAME(sys_oldumount)
+		.long	SYMBOL_NAME(sys_oldumount)		/* used by libc4 */
 		.long	SYMBOL_NAME(sys_setuid16)
 		.long	SYMBOL_NAME(sys_getuid16)
 /* 25 */	.long	SYMBOL_NAME(sys_stime)
 		.long	SYMBOL_NAME(sys_ptrace)
-		.long	SYMBOL_NAME(sys_alarm)
+		.long	SYMBOL_NAME(sys_alarm)			/* used by libc4 */
 		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_fstat */
 		.long	SYMBOL_NAME(sys_pause)
-/* 30 */	.long	SYMBOL_NAME(sys_utime)
+/* 30 */	.long	SYMBOL_NAME(sys_utime)			/* used by libc4 */
 		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_stty */
 		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_getty */
 		.long	SYMBOL_NAME(sys_access)
@@ -62,7 +62,7 @@
 /* 45 */	.long	SYMBOL_NAME(sys_brk)
 		.long	SYMBOL_NAME(sys_setgid16)
 		.long	SYMBOL_NAME(sys_getgid16)
-		.long	SYMBOL_NAME(sys_signal)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_signal */
 		.long	SYMBOL_NAME(sys_geteuid16)
 /* 50 */	.long	SYMBOL_NAME(sys_getegid16)
 		.long	SYMBOL_NAME(sys_acct)
@@ -82,29 +82,29 @@
 /* 65 */	.long	SYMBOL_NAME(sys_getpgrp)
 		.long	SYMBOL_NAME(sys_setsid)
 		.long	SYMBOL_NAME(sys_sigaction)
-		.long	SYMBOL_NAME(sys_sgetmask)
-		.long	SYMBOL_NAME(sys_ssetmask)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_sgetmask */
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_ssetmask */
 /* 70 */	.long	SYMBOL_NAME(sys_setreuid16)
 		.long	SYMBOL_NAME(sys_setregid16)
 		.long	SYMBOL_NAME(sys_sigsuspend_wrapper)
 		.long	SYMBOL_NAME(sys_sigpending)
 		.long	SYMBOL_NAME(sys_sethostname)
 /* 75 */	.long	SYMBOL_NAME(sys_setrlimit)
-		.long	SYMBOL_NAME(sys_old_getrlimit)
+		.long	SYMBOL_NAME(sys_old_getrlimit)		/* used by libc4 */
 		.long	SYMBOL_NAME(sys_getrusage)
 		.long	SYMBOL_NAME(sys_gettimeofday)
 		.long	SYMBOL_NAME(sys_settimeofday)
 /* 80 */	.long	SYMBOL_NAME(sys_getgroups16)
 		.long	SYMBOL_NAME(sys_setgroups16)
-		.long	SYMBOL_NAME(old_select)
+		.long	SYMBOL_NAME(old_select)			/* used by libc4 */
 		.long	SYMBOL_NAME(sys_symlink)
 		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_lstat */
 /* 85 */	.long	SYMBOL_NAME(sys_readlink)
 		.long	SYMBOL_NAME(sys_uselib)
 		.long	SYMBOL_NAME(sys_swapon)
 		.long	SYMBOL_NAME(sys_reboot)
-		.long	SYMBOL_NAME(old_readdir)
-/* 90 */	.long	SYMBOL_NAME(old_mmap)
+		.long	SYMBOL_NAME(old_readdir)		/* used by libc4 */
+/* 90 */	.long	SYMBOL_NAME(old_mmap)			/* used by libc4 */
 		.long	SYMBOL_NAME(sys_munmap)
 		.long	SYMBOL_NAME(sys_truncate)
 		.long	SYMBOL_NAME(sys_ftruncate)
@@ -240,23 +240,37 @@
 		.long	SYMBOL_NAME(sys_ni_syscall) /* Security */
 		.long	SYMBOL_NAME(sys_gettid)
 /* 225 */	.long	SYMBOL_NAME(sys_readahead)
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_setxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lsetxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fsetxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_getxattr */
-/* 230 */	.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lgetxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fgetxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_listxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_llistxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_flistxattr */
-/* 235 */	.long	SYMBOL_NAME(sys_ni_syscall) /* sys_removexattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lremovexattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fremovexattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* setxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* lsetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* fsetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* getxattr */
+/* 230 */	.long	SYMBOL_NAME(sys_ni_syscall) /* lgetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* fgetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* listxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* llistxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* flistxattr */
+/* 235 */	.long	SYMBOL_NAME(sys_ni_syscall) /* removexattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* lremovexattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* fremovexattr */
 		.long	SYMBOL_NAME(sys_tkill)
-		/*
-		 * Please check 2.5 _before_ adding calls here,
-		 * and copy changes to rmk@arm.linux.org.uk.  Thanks.
-		 */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sendfile64 */
+/* 240 */	.long	SYMBOL_NAME(sys_ni_syscall) /* futex */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sched_setaffinity */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sched_getaffinity */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* io_setup */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* io_destroy */
+/* 245 */	.long	SYMBOL_NAME(sys_ni_syscall) /* io_getevents */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* io_submit */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* io_cancel */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* exit_group */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* lookup_dcookie */
+/* 250 */	.long	SYMBOL_NAME(sys_ni_syscall) /* epoll_create */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* epoll_ctl */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* epoll_wait */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* remap_file_pages */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* set_thread_area */
+/* 255 */	.long	SYMBOL_NAME(sys_ni_syscall) /* get_thread_area */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* set_tid_address */
 __syscall_end:
 
 		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
diff -urN linux-2.4.22-pre2/arch/arm/kernel/compat.c linux-2.4.22-pre3/arch/arm/kernel/compat.c
--- linux-2.4.22-pre2/arch/arm/kernel/compat.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/compat.c	2003-07-05 18:09:35.000000000 -0700
@@ -33,18 +33,35 @@
 	return tag;
 }
 
-static void __init build_tag_list(struct param_struct *params, void *taglist, int mem_init)
+static void __init build_tag_list(struct param_struct *params, void *taglist)
 {
 	struct tag *tag = taglist;
 
-	printk(KERN_DEBUG "Converting old-style param struct to taglist\n");
-
 	if (params->u1.s.page_size != PAGE_SIZE) {
 		printk(KERN_WARNING "Warning: bad configuration page, "
 		       "trying to continue\n");
 		return;
 	}
 
+	printk(KERN_DEBUG "Converting old-style param struct to taglist\n");
+
+#ifdef CONFIG_ARCH_NETWINDER
+	if (params->u1.s.nr_pages != 0x02000 &&
+	    params->u1.s.nr_pages != 0x04000 &&
+	    params->u1.s.nr_pages != 0x08000 &&
+	    params->u1.s.nr_pages != 0x10000) {
+		printk(KERN_WARNING "Warning: bad NeTTrom parameters "
+		       "detected, using defaults\n");
+
+		params->u1.s.nr_pages = 0x1000;	/* 16MB */
+		params->u1.s.ramdisk_size = 0;
+		params->u1.s.flags = FLAG_READONLY;
+		params->u1.s.initrd_start = 0;
+		params->u1.s.initrd_size = 0;
+		params->u1.s.rd_start = 0;
+	}
+#endif
+
 	tag->hdr.tag  = ATAG_CORE;
 	tag->hdr.size = tag_size(tag_core);
 	tag->u.core.flags = params->u1.s.flags & FLAG_READONLY;
@@ -76,17 +93,15 @@
 	tag->hdr.size = tag_size(tag_revision);
 	tag->u.revision.rev = params->u1.s.system_rev;
 
-	if (mem_init) {
 #ifdef CONFIG_ARCH_ACORN
-		if (machine_is_riscpc()) {
-			int i;
-			for (i = 0; i < 4; i++)
-				tag = memtag(tag, PHYS_OFFSET + (i << 26),
-					 params->u1.s.pages_in_bank[i] * PAGE_SIZE);
-		} else
+	if (machine_is_riscpc()) {
+		int i;
+		for (i = 0; i < 4; i++)
+			tag = memtag(tag, PHYS_OFFSET + (i << 26),
+				 params->u1.s.pages_in_bank[i] * PAGE_SIZE);
+	} else
 #endif
-		tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE);
-	}
+	tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE);
 
 #ifdef CONFIG_FOOTBRIDGE
 	if (params->u1.s.mem_fclk_21285) {
@@ -97,6 +112,23 @@
 	}
 #endif
 
+#ifdef CONFIG_ARCH_EBSA285
+	if (machine_is_ebsa285()) {
+		tag = tag_next(tag);
+		tag->hdr.tag = ATAG_VIDEOTEXT;
+		tag->hdr.size = tag_size(tag_videotext);
+		tag->u.videotext.x	      = params->u1.s.video_x;
+		tag->u.videotext.y	      = params->u1.s.video_y;
+		tag->u.videotext.video_page   = 0;
+		tag->u.videotext.video_mode   = 0;
+		tag->u.videotext.video_cols   = params->u1.s.video_num_cols;
+		tag->u.videotext.video_ega_bx = 0;
+		tag->u.videotext.video_lines  = params->u1.s.video_num_rows;
+		tag->u.videotext.video_isvga  = 1;
+		tag->u.videotext.video_points = 8;
+	}
+#endif
+
 #ifdef CONFIG_ARCH_ACORN
 	tag = tag_next(tag);
 	tag->hdr.tag = ATAG_ACORN;
@@ -114,14 +146,22 @@
 	strcpy(tag->u.cmdline.cmdline, params->commandline);
 
 	tag = tag_next(tag);
-	tag->hdr.tag = 0;
+	tag->hdr.tag = ATAG_NONE;
 	tag->hdr.size = 0;
 
 	memmove(params, taglist, ((int)tag) - ((int)taglist) +
 				 sizeof(struct tag_header));
 }
 
-void __init convert_to_tag_list(struct param_struct *params, int mem_init)
+void __init convert_to_tag_list(struct tag *tags)
+{
+	struct param_struct *params = (struct param_struct *)tags;
+	build_tag_list(params, &params->u2);
+}
+
+void __init squash_mem_tags(struct tag *tag)
 {
-	build_tag_list(params, &params->u2, mem_init);
+	for (; tag->hdr.size; tag = tag_next(tag))
+		if (tag->hdr.tag == ATAG_MEM)
+			tag->hdr.tag = ATAG_NONE;
 }
diff -urN linux-2.4.22-pre2/arch/arm/kernel/debug-armv.S linux-2.4.22-pre3/arch/arm/kernel/debug-armv.S
--- linux-2.4.22-pre2/arch/arm/kernel/debug-armv.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/debug-armv.S	2003-07-05 18:09:36.000000000 -0700
@@ -20,9 +20,20 @@
  * printk isn't working).  For DEBUGGING ONLY!!!  Do not leave
  * references to these in a production kernel!
  */
-#if defined(CONFIG_ARCH_RPC)
+#if defined(CONFIG_ARCH_RPC) || defined(CONFIG_ARCH_RISCSTATION)
 		.macro	addruart,rx
-		mov	\rx, #0xe0000000
+
+/* note, errors can occur in the head code BEFORE the memory map has been
+ * setup (and therefore the mapping for the IO) so the #if statement allows
+ * the address of the uart to be changed to the physical address instead of
+ * the logical
+ *
+ * (bjd)
+ */
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		movne	\rx, #0xe0000000
+		moveq	\rx, #0x03000000
 		orr	\rx, \rx, #0x00010000
 		orr	\rx, \rx, #0x00000fe0
 		.endm
@@ -66,7 +77,7 @@
 		tst	\rd, #0x10
 		beq	1001b
 		.endm
- 	
+
 #elif defined(CONFIG_ARCH_SHARK)
 		.macro	addruart,rx
 		mov	\rx, #0xe0000000
@@ -287,6 +298,30 @@
 		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
 		bne	1001b
 		.endm
+#elif defined(CONFIG_ARCH_AT91RM9200)
+
+		.macro  addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1				@ MMU enabled?
+		ldreq	\rx, =AT91C_BASE_SYS		@ System peripherals (phys address)
+		ldrne	\rx, =AT91C_VA_BASE_SYS		@ System peripherals (virt address)
+		.endm
+
+		.macro  senduart,rd,rx
+		strb    \rd, [\rx, #DBGU_THR]		@ DBGU_THR
+		.endm
+
+		.macro  waituart,rd,rx
+1001:		ldr     \rd, [\rx, #DBGU_CSR]		@ DBGU_CSR
+		tst	\rd, #AT91C_DBGU_TXRDY		@ DBGU_TXRDY = 1 when ready to transmit
+		beq	1001b
+		.endm
+
+		.macro  busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #DBGU_CSR]		@ DBGU_CSR
+		tst	\rd, #AT91C_DBGU_TXEMPTY	@ DBGU_TXEMPTY = 1 when transmission complete
+		beq	1001b
+		.endm
 
 #elif defined(CONFIG_ARCH_CLPS711X)
 
@@ -322,6 +357,21 @@
 		bne	1001b
 1002:
 		.endm
+#elif defined(CONFIG_ARCH_OMAHA)
+
+#include <asm/hardware/serial_omaha.h>
+
+		.macro	addruart,rx
+		.endm
+
+		.macro	senduart,rd,rx
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+
+		.macro	busyuart,rd,rx
+		.endm
 
 #elif defined(CONFIG_ARCH_ANAKIN)
 
@@ -365,7 +415,7 @@
 		tst	\rx, #1			@ MMU enabled?
 		ldr	\rx, =EXC_UART00_BASE	@ physical base address
 		orrne	\rx, \rx, #0xff000000	@ virtual base
-		orrne	\rx, \rx, #0x00f00000	
+		orrne	\rx, \rx, #0x00f00000
 		.endm
 
 		.macro	senduart,rd,rx
@@ -385,6 +435,41 @@
 		bne	1001b
 		.endm
 
+#elif defined(CONFIG_ARCH_MX1ADS)
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x00000000	@ physical
+		movne	\rx, #0xf0000000	@ virtual
+		orr	\rx, \rx, #0x00200000
+		orr	\rx, \rx, #0x00006000	@ UART1 offset
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x40]	@ TXDATA
+		.endm
+
+		.macro	waituart,rd,rx
+#if	0
+/* REVISIT: This isn't right. I believe we should be checking CTS here instead
+ * to see if the user has entered <CTRL><S> to pause console output.
+ * gdavis@mvista.com 28apr03
+ */
+1001:		ldr	\rd, [\rx, #0x94]	@ SR1
+		tst	\rd, #1 << 13		@ TRDY
+		bne	1001b			@ wait until TX FIFO ready
+#endif
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldr	\rd, [\rx, #0x98]	@ SR2
+		tst	\rd, #1 << 3		@ TXDC
+		beq	1002b			@ wait until transmit done
+		.endm
+
+
+
 #else
 #error Unknown architecture
 #endif
diff -urN linux-2.4.22-pre2/arch/arm/kernel/dma-arc.c linux-2.4.22-pre3/arch/arm/kernel/dma-arc.c
--- linux-2.4.22-pre2/arch/arm/kernel/dma-arc.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/dma-arc.c	2003-07-05 18:09:36.000000000 -0700
@@ -34,14 +34,14 @@
 		extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
 		unsigned long flags;
 		DPRINTK("enable_dma fdc1772 data read\n");
-		save_flags(flags);
-		clf();
+		local_save_flags(flags);
+		__clf();
 			
 		memcpy ((void *)0x1c, (void *)&fdc1772_dma_read,
 			&fdc1772_dma_read_end - &fdc1772_dma_read);
 		fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */
 		enable_fiq(FIQ_FLOPPYDATA);
-		restore_flags(flags);
+		local_irq_restore(flags);
 	   }
 	   break;
 
@@ -50,14 +50,14 @@
 		extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
 		unsigned long flags;
 		DPRINTK("enable_dma fdc1772 data write\n");
-		save_flags(flags);
-		clf();
+		local_save_flags(flags);
+		__clf();
 		memcpy ((void *)0x1c, (void *)&fdc1772_dma_write,
 			&fdc1772_dma_write_end - &fdc1772_dma_write);
 		fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */
 		enable_fiq(FIQ_FLOPPYDATA;
 
-		restore_flags(flags);
+		local_irq_restore(flags);
 	    }
 	    break;
 	default:
@@ -81,14 +81,14 @@
 
 	DPRINTK("arc_floppy_cmdend_enable_dma\n");
 	/*printk("enable_dma fdc1772 command end FIQ\n");*/
-	save_flags(flags);
-	clf();
+	local_save_flags(flags);
+	__clf();
 	
 	/* B fdc1772_comendhandler */
 	*((unsigned int *)0x1c)=0xea000000 |
 			(((unsigned int)fdc1772_comendhandler-(0x1c+8))/4);
 
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static int arc_floppy_cmdend_get_dma_residue(dmach_t channel, dma_t *dma)
diff -urN linux-2.4.22-pre2/arch/arm/kernel/dma-riscstation.c linux-2.4.22-pre3/arch/arm/kernel/dma-riscstation.c
--- linux-2.4.22-pre2/arch/arm/kernel/dma-riscstation.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/kernel/dma-riscstation.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,113 @@
+/*
+ *  linux/arch/arm/kernel/dma-riscstation.c
+ *
+ *  Copyright (C) 1998 Russell King
+ *  Copyright (C) 2002 Ben Dooks / Simtec Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  DMA functions specific to RiscStatiun architecture
+ *
+ * sliced down version of the RiscPC DMA code by RMK
+ */
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/page.h>
+#include <asm/dma.h>
+#include <asm/fiq.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+
+#include <asm/mach/dma.h>
+#include <asm/hardware/iomd.h>
+
+static struct fiq_handler fh = {
+	name: "floppydma"
+};
+
+static void floppy_enable_dma(dmach_t channel, dma_t *dma)
+{
+	void *fiqhandler_start;
+	unsigned int fiqhandler_length;
+	struct pt_regs regs;
+
+	if (dma->dma_mode == DMA_MODE_READ) {
+		extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
+		fiqhandler_start = &floppy_fiqin_start;
+		fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
+	} else {
+		extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
+		fiqhandler_start = &floppy_fiqout_start;
+		fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
+	}
+
+	regs.ARM_r9  = dma->buf.length;
+	regs.ARM_r10 = (unsigned long)dma->buf.address;
+	regs.ARM_fp  = FLOPPYDMA_BASE;
+
+	if (claim_fiq(&fh)) {
+		printk("floppydma: couldn't claim FIQ.\n");
+		return;
+	}
+
+	set_fiq_handler(fiqhandler_start, fiqhandler_length);
+	set_fiq_regs(&regs);
+	enable_fiq(dma->dma_irq);
+}
+
+static void floppy_disable_dma(dmach_t channel, dma_t *dma)
+{
+	disable_fiq(dma->dma_irq);
+	release_fiq(&fh);
+}
+
+static int floppy_get_residue(dmach_t channel, dma_t *dma)
+{
+	struct pt_regs regs;
+	get_fiq_regs(&regs);
+	return regs.ARM_r9;
+}
+
+static struct dma_ops floppy_dma_ops = {
+	type:		"FIQDMA",
+	enable:		floppy_enable_dma,
+	disable:	floppy_disable_dma,
+	residue:	floppy_get_residue,
+};
+
+/*
+ * This is virtual DMA - we don't need anything here.
+ */
+static void sound_enable_disable_dma(dmach_t channel, dma_t *dma)
+{
+}
+
+static struct dma_ops sound_dma_ops = {
+	type:		"VIRTUAL",
+	enable:		sound_enable_disable_dma,
+	disable:	sound_enable_disable_dma,
+};
+
+void __init arch_dma_init(dma_t *dma)
+{
+#if 0
+	iomd_writeb(0, IOMD_IO0CR);
+	iomd_writeb(0, IOMD_IO1CR);
+	iomd_writeb(0, IOMD_IO2CR);
+	iomd_writeb(0, IOMD_IO3CR);
+
+	iomd_writeb(0xa0, IOMD_DMATCR);
+#endif
+
+	dma[DMA_VIRTUAL_FLOPPY].dma_irq	= FIQ_FLOPPYDATA;
+	dma[DMA_VIRTUAL_FLOPPY].d_ops	= &floppy_dma_ops;
+	dma[DMA_VIRTUAL_SOUND].d_ops	= &sound_dma_ops;
+}
diff -urN linux-2.4.22-pre2/arch/arm/kernel/dma-rpc.c linux-2.4.22-pre3/arch/arm/kernel/dma-rpc.c
--- linux-2.4.22-pre2/arch/arm/kernel/dma-rpc.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/dma-rpc.c	2003-07-05 18:09:36.000000000 -0700
@@ -91,76 +91,40 @@
 	sg->length |= flags;
 }
 
-static inline void iomd_setup_dma_a(struct scatterlist *sg, dma_t *dma)
-{
-	iomd_writel(sg->dma_address, dma->dma_base + CURA);
-	iomd_writel(sg->length, dma->dma_base + ENDA);
-}
-
-static inline void iomd_setup_dma_b(struct scatterlist *sg, dma_t *dma)
-{
-	iomd_writel(sg->dma_address, dma->dma_base + CURB);
-	iomd_writel(sg->length, dma->dma_base + ENDB);
-}
-
 static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
 {
 	dma_t *dma = (dma_t *)dev_id;
-	unsigned int status = 0, no_buffer = dma->sg == NULL;
+	unsigned long base = dma->dma_base;
 
 	do {
-		switch (dma->state) {
-		case state_prog_a:
-			iomd_get_next_sg(&dma->cur_sg, dma);
-			iomd_setup_dma_a(&dma->cur_sg, dma);
-			dma->state = state_wait_a;
-
-		case state_wait_a:
-			status = iomd_readb(dma->dma_base + ST);
-			switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
-			case DMA_ST_OFL|DMA_ST_INT:
-				iomd_get_next_sg(&dma->cur_sg, dma);
-				iomd_setup_dma_a(&dma->cur_sg, dma);
-				break;
-
-			case DMA_ST_INT:
-				iomd_get_next_sg(&dma->cur_sg, dma);
-				iomd_setup_dma_b(&dma->cur_sg, dma);
-				dma->state = state_wait_b;
-				break;
-
-			case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB:
-				iomd_setup_dma_b(&dma->cur_sg, dma);
-				dma->state = state_wait_b;
-				break;
-			}
+		unsigned int status;
+
+		status = iomd_readb(base + ST);
+		if (!(status & DMA_ST_INT))
+			return;
+
+		if (status & DMA_ST_OFL && !dma->sg)
+			break;
+
+		iomd_get_next_sg(&dma->cur_sg, dma);
+
+		switch (status & (DMA_ST_OFL | DMA_ST_AB)) {
+		case DMA_ST_OFL:			/* OIA */
+		case DMA_ST_AB:				/* .IB */
+			iomd_writel(dma->cur_sg.dma_address, base + CURA);
+			iomd_writel(dma->cur_sg.length, base + ENDA);
 			break;
 
-		case state_wait_b:
-			status = iomd_readb(dma->dma_base + ST);
-			switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
-			case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB:
-				iomd_get_next_sg(&dma->cur_sg, dma);
-				iomd_setup_dma_b(&dma->cur_sg, dma);
-				break;
-
-			case DMA_ST_INT|DMA_ST_AB:
-				iomd_get_next_sg(&dma->cur_sg, dma);
-				iomd_setup_dma_a(&dma->cur_sg, dma);
-				dma->state = state_wait_a;
-				break;
-
-			case DMA_ST_OFL|DMA_ST_INT:
-				iomd_setup_dma_a(&dma->cur_sg, dma);
-				dma->state = state_wait_a;
-				break;
-			}
+		case DMA_ST_OFL | DMA_ST_AB:		/* OIB */
+		case 0:					/* .IA */
+			iomd_writel(dma->cur_sg.dma_address, base + CURB);
+			iomd_writel(dma->cur_sg.length, base + ENDB);
 			break;
 		}
-	} while (dma->sg && (status & DMA_ST_INT));
+	} while (1);
 
-	if (no_buffer)
-		disable_irq(irq);
+	iomd_writeb(0, base + CR);
+	disable_irq(irq);
 }
 
 static int iomd_request_dma(dmach_t channel, dma_t *dma)
@@ -194,7 +158,6 @@
 		}
 
 		iomd_writeb(DMA_CR_C, dma_base + CR);
-		dma->state = state_prog_a;
 	}
 		
 	if (dma->dma_mode == DMA_MODE_READ)
@@ -207,11 +170,15 @@
 static void iomd_disable_dma(dmach_t channel, dma_t *dma)
 {
 	unsigned long dma_base = dma->dma_base;
+	unsigned long flags;
 	unsigned int ctrl;
 
-	disable_irq(dma->dma_irq);
+	local_irq_save(flags);
 	ctrl = iomd_readb(dma_base + CR);
+	if (ctrl & DMA_CR_E)
+		disable_irq(dma->dma_irq);
 	iomd_writeb(ctrl & ~DMA_CR_E, dma_base + CR);
+	local_irq_restore(flags);
 }
 
 static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
diff -urN linux-2.4.22-pre2/arch/arm/kernel/dma.c linux-2.4.22-pre3/arch/arm/kernel/dma.c
--- linux-2.4.22-pre2/arch/arm/kernel/dma.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/dma.c	2003-07-05 18:09:36.000000000 -0700
@@ -119,6 +119,10 @@
 {
 	dma_t *dma = dma_chan + channel;
 
+	if (dma->active)
+		printk(KERN_ERR "dma%d: altering DMA SG while "
+		       "DMA active\n", channel);
+
 	dma->sg = sg;
 	dma->sgcount = nr_sg;
 	dma->using_sg = 1;
@@ -217,6 +221,14 @@
 	BUG();
 }
 
+/*
+ * Is the specified DMA channel active?
+ */
+int dma_channel_active(dmach_t channel)
+{
+	return dma_chan[channel].active;
+}
+
 void set_dma_page(dmach_t channel, char pagenr)
 {
 	printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
@@ -272,6 +284,7 @@
 GLOBAL_ALIAS(set_dma_sg, get_dma_residue);
 GLOBAL_ALIAS(set_dma_speed, get_dma_residue);
 GLOBAL_ALIAS(init_dma, get_dma_residue);
+GLOBAL_ALIAS(dma_channel_active, get_dma_residue);
 
 #endif
 
@@ -286,3 +299,6 @@
 EXPORT_SYMBOL(get_dma_residue);
 EXPORT_SYMBOL(set_dma_sg);
 EXPORT_SYMBOL(set_dma_speed);
+EXPORT_SYMBOL(dma_channel_active);
+
+EXPORT_SYMBOL(dma_spin_lock);
diff -urN linux-2.4.22-pre2/arch/arm/kernel/ecard.c linux-2.4.22-pre3/arch/arm/kernel/ecard.c
--- linux-2.4.22-pre2/arch/arm/kernel/ecard.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/ecard.c	2003-07-05 18:09:36.000000000 -0700
@@ -38,7 +38,10 @@
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/notifier.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 
 #include <asm/dma.h>
 #include <asm/ecard.h>
@@ -55,7 +58,7 @@
 
 enum req {
 	req_readbytes,
-	req_reset_all
+	req_reset
 };
 
 struct ecard_request {
@@ -136,14 +139,11 @@
 #define POD_INT_ADDR(x)	((volatile unsigned char *)\
 			 ((BUS_ADDR((x)) - IO_BASE) + IO_START))
 
-static inline void ecard_task_reset(void)
+static inline void ecard_task_reset(struct ecard_request *req)
 {
-	ecard_t *ec;
-
-	for (ec = cards; ec; ec = ec->next)
-		if (ec->loader)
-			ecard_loader_reset(POD_INT_ADDR(ec->podaddr),
-					   ec->loader);
+	struct expansion_card *ec = req->ec;
+	if (ec->loader)
+		ecard_loader_reset(POD_INT_ADDR(ec->podaddr), ec->loader);
 }
 
 static void
@@ -223,8 +223,8 @@
 		ecard_task_readbytes(req);
 		break;
 
-	case req_reset_all:
-		ecard_task_reset();
+	case req_reset:
+		ecard_task_reset(req);
 		break;
 	}
 }
@@ -371,60 +371,6 @@
 
 /* ======================= Mid-level card control ===================== */
 
-/*
- * This function is responsible for resetting the expansion cards to a
- * sensible state immediately prior to rebooting the system.  This function
- * has process state (keventd), so we can sleep.
- *
- * Possible "val" values here:
- *  SYS_RESTART   -  restarting system
- *  SYS_HALT      - halting system
- *  SYS_POWER_OFF - powering down system
- *
- * We ignore all calls, unless it is a SYS_RESTART call - power down/halts
- * will be followed by a SYS_RESTART if ctrl-alt-del is pressed again.
- */
-static int ecard_reboot(struct notifier_block *me, unsigned long val, void *v)
-{
-	struct ecard_request req;
-
-	if (val != SYS_RESTART)
-		return 0;
-
-	/*
-	 * Disable the expansion card interrupt
-	 */
-	disable_irq(IRQ_EXPANSIONCARD);
-
-	/*
-	 * If we have any expansion card loader code which will handle
-	 * the reset for us, call it now.
-	 */
-	req.req = req_reset_all;
-	ecard_call(&req);
-
-	/*
-	 * Disable the expansion card interrupt again, just to be sure.
-	 */
-	disable_irq(IRQ_EXPANSIONCARD);
-
-	/*
-	 * Finally, reset the expansion card interrupt mask to
-	 * all enable (RISC OS doesn't set this)
-	 */
-#ifdef HAS_EXPMASK
-	have_expmask = ~0;
-	__raw_writeb(have_expmask, EXPMASK_ENABLE);
-#endif
-	return 0;
-}
-
-static struct notifier_block ecard_reboot_notifier = {
-	.notifier_call	= ecard_reboot,
-};
-
-
-
 static void
 ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
 {
@@ -628,8 +574,7 @@
 		       ec->irqaddr, ec->irqmask, *ec->irqaddr);
 }
 
-static void
-ecard_check_lockup(void)
+static void ecard_check_lockup(void)
 {
 	static int last, lockup;
 	ecard_t *ec;
@@ -757,8 +702,7 @@
 		printk(KERN_WARNING "Wild interrupt from backplane (masks)\n");
 }
 
-static void __init
-ecard_probeirqhw(void)
+static void __init ecard_probeirqhw(void)
 {
 	ecard_t *ec;
 	int found;
@@ -785,7 +729,7 @@
 	__raw_writeb(have_expmask, EXPMASK_ENABLE);
 }
 #else
-#define ecard_probeirqhw()
+#define ecard_probeirqhw() do { } while (0)
 #endif
 
 #ifndef IO_EC_MEMC8_BASE
@@ -896,6 +840,57 @@
 		get_ecard_dev_info);
 }
 
+#define ec_set_resource(ec,nr,st,sz,flg)			\
+	do {							\
+		(ec)->resource[nr].name = ec->name;	 	\
+		(ec)->resource[nr].start = st;			\
+		(ec)->resource[nr].end = (st) + (sz) - 1;	\
+		(ec)->resource[nr].flags = flg;			\
+	} while (0)
+
+static void __init ecard_init_resources(struct expansion_card *ec)
+{
+	unsigned long base = PODSLOT_IOC4_BASE;
+	unsigned int slot = ec->slot_no;
+	int i;
+
+	if (slot < 4) {
+		ec_set_resource(ec, ECARD_RES_MEMC,
+				PODSLOT_MEMC_BASE + (slot << 14),
+				PODSLOT_MEMC_SIZE, IORESOURCE_MEM);
+		base = PODSLOT_IOC0_BASE;
+	}
+
+#ifdef CONFIG_ARCH_RPC
+	if (slot < 8) {
+		ec_set_resource(ec, ECARD_RES_EASI,
+				PODSLOT_EASI_BASE + (slot << 24),
+				PODSLOT_EASI_SIZE, IORESOURCE_MEM);
+	}
+
+	if (slot == 8) {
+		ec_set_resource(ec, ECARD_RES_MEMC, NETSLOT_BASE,
+				NETSLOT_SIZE, IORESOURCE_MEM);
+	} else
+#endif
+
+	for (i = 0; i < ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++) {
+		ec_set_resource(ec, i + ECARD_RES_IOCSLOW,
+				base + (slot << 14) + (i << 19),
+				PODSLOT_IOC_SIZE, IORESOURCE_MEM);
+	}
+
+	for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
+		if (ec->resource[i].start &&
+		    request_resource(&iomem_resource, &ec->resource[i])) {
+			printk(KERN_ERR "ecard%d: resource(s) not available\n",
+				ec->slot_no);
+			ec->resource[i].end -= ec->resource[i].start;
+			ec->resource[i].start = 0;
+		}
+	}
+}
+
 /*
  * Probe for an expansion card.
  *
@@ -964,21 +959,26 @@
 			break;
 		}
 
-	ec->irq = 32 + slot;
-#ifdef IO_EC_MEMC8_BASE
-	if (slot == 8)
-		ec->irq = 11;
-#endif
+	snprintf(ec->name, sizeof(ec->name), "ecard %04x:%04x",
+		 ec->cid.manufacturer, ec->cid.product);
+
+	ecard_init_resources(ec);
+
 	/*
 	 * hook the interrupt handlers
 	 */
-	if (ec->irq != 0 && ec->irq >= 32) {
+	if (slot < 8) {
+		ec->irq = 32 + slot;
 		irq_desc[ec->irq].mask_ack = ecard_disableirq;
 		irq_desc[ec->irq].mask     = ecard_disableirq;
 		irq_desc[ec->irq].unmask   = ecard_enableirq;
 		irq_desc[ec->irq].valid    = 1;
 	}
 
+#ifdef IO_EC_MEMC8_BASE
+	if (slot == 8)
+		ec->irq = 11;
+#endif
 #ifdef CONFIG_ARCH_RPC
 	/* On RiscPC, only first two slots have DMA capability */
 	if (slot < 2)
@@ -1012,7 +1012,7 @@
 		finding_pos = finding_pos->next;
 
 	for (; finding_pos; finding_pos = finding_pos->next) {
-		if (finding_pos->claimed)
+		if (finding_pos->claimed || finding_pos->driver)
 			continue;
 
 		if (!cids) {
@@ -1062,11 +1062,6 @@
 {
 	int slot;
 
-	/*
-	 * Register our reboot notifier
-	 */
-	register_reboot_notifier(&ecard_reboot_notifier);
-
 #ifdef CONFIG_CPU_32
 	init_waitqueue_head(&ecard_wait);
 #endif
@@ -1093,7 +1088,162 @@
 	ecard_proc_init();
 }
 
+/*
+ *	ECARD driver functions
+ */
+static const struct ecard_id *
+ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec)
+{
+	int i;
+
+	for (i = 0; ids[i].manufacturer != 65535; i++)
+		if (ec->cid.manufacturer == ids[i].manufacturer &&
+		    ec->cid.product == ids[i].product)
+			return ids + i;
+
+	return NULL;
+}
+
+static int ecard_drv_probe(struct expansion_card *ec, const struct ecard_id *id)
+{
+	struct ecard_driver *drv = ec->driver;
+	int ret;
+
+	ecard_claim(ec);
+	ret = drv->probe(ec, id);
+	if (ret)
+		ecard_release(ec);
+	return ret;
+}
+
+static int ecard_drv_remove(struct expansion_card *ec)
+{
+	struct ecard_driver *drv = ec->driver;
+
+	drv->remove(ec);
+	ecard_release(ec);
+
+	return 0;
+}
+
+/*
+ * Before rebooting, we must make sure that the expansion card is in a
+ * sensible state, so it can be re-detected.  This means that the first
+ * page of the ROM must be visible.  We call the expansion cards reset
+ * handler, if any.
+ */
+static void ecard_drv_shutdown(struct expansion_card *ec)
+{
+	struct ecard_driver *drv = ec->driver;
+	struct ecard_request req;
+
+	if (drv && drv->shutdown)
+		drv->shutdown(ec);
+	ecard_release(ec);
+	req.req = req_reset;
+	req.ec = ec;
+	ecard_call(&req);
+}
+
+int ecard_register_driver(struct ecard_driver *drv)
+{
+	struct expansion_card *ec;
+	int ret, found = 0;
+
+	for (ec = cards; ec; ec = ec->next) {
+		const struct ecard_id *id;
+
+		if (ec->driver || ec->claimed)
+			continue;
+
+		if (drv->id_table) {
+			id = ecard_match_device(drv->id_table, ec);
+			ret = id != NULL;
+		} else {
+			id = NULL;
+			ret = ec->cid.id == drv->id;
+		}
+
+		if (ret) {
+			ec->driver = drv;
+			ret = ecard_drv_probe(ec, id);
+			if (ret) {
+				ec->driver = NULL;
+			} else {
+				found++;
+			}
+		}
+	}
+
+	return found ? 0 : -ENODEV;
+}
+
+void ecard_remove_driver(struct ecard_driver *drv)
+{
+	struct expansion_card *ec;
+
+	for (ec = cards; ec; ec = ec->next)
+		if (ec->driver == drv) {
+			ecard_drv_remove(ec);
+			ec->driver = NULL;
+		}
+}
+
+/*
+ * This function is responsible for resetting the expansion cards to a
+ * sensible state immediately prior to rebooting the system.  This function
+ * has process state (keventd), so we can sleep.
+ *
+ * Possible "val" values here:
+ *  SYS_RESTART   -  restarting system
+ *  SYS_HALT      - halting system
+ *  SYS_POWER_OFF - powering down system
+ *
+ * We ignore all calls, unless it is a SYS_RESTART call - power down/halts
+ * will be followed by a SYS_RESTART if ctrl-alt-del is pressed again.
+ */
+static int ecard_reboot(struct notifier_block *me, unsigned long val, void *v)
+{
+	struct expansion_card *ec;
+
+	if (val != SYS_RESTART)
+		return 0;
+
+	for (ec = cards; ec; ec = ec->next)
+		if (ec->driver || ec->claimed)
+			ecard_drv_shutdown(ec);
+
+	/*
+	 * Disable the expansion card interrupt
+	 */
+	disable_irq(IRQ_EXPANSIONCARD);
+
+	/*
+	 * Finally, reset the expansion card interrupt mask to
+	 * all enable (RISC OS doesn't set this)
+	 */
+#ifdef HAS_EXPMASK
+	have_expmask = ~0;
+	__raw_writeb(have_expmask, EXPMASK_ENABLE);
+#endif
+	return 0;
+}
+
+static struct notifier_block ecard_reboot_notifier = {
+	.notifier_call	= ecard_reboot,
+};
+
+static int ecard_bus_init(void)
+{
+	register_reboot_notifier(&ecard_reboot_notifier);
+	return 0;
+}
+
+__initcall(ecard_bus_init);
+
 EXPORT_SYMBOL(ecard_startfind);
 EXPORT_SYMBOL(ecard_find);
 EXPORT_SYMBOL(ecard_readchunk);
 EXPORT_SYMBOL(ecard_address);
+EXPORT_SYMBOL(ecard_register_driver);
+EXPORT_SYMBOL(ecard_remove_driver);
diff -urN linux-2.4.22-pre2/arch/arm/kernel/entry-armv.S linux-2.4.22-pre3/arch/arm/kernel/entry-armv.S
--- linux-2.4.22-pre2/arch/arm/kernel/entry-armv.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/entry-armv.S	2003-07-05 18:09:36.000000000 -0700
@@ -187,11 +187,10 @@
 
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
 		mov	r4, #0xe0000000
-		orr	r4, r4, #0x20
 
 		mov	\irqstat, #0x0C
-		strb	\irqstat, [r4]			@outb(0x0C, 0x20) /* Poll command */
-		ldrb	\irqnr, [r4]			@irq = inb(0x20) & 7
+		strb	\irqstat, [r4, #0x20]		@outb(0x0C, 0x20) /* Poll command */
+		ldrb	\irqnr, [r4, #0x20]		@irq = inb(0x20) & 7
 		and	\irqstat, \irqnr, #0x80
 		teq	\irqstat, #0
 		beq	43f
@@ -199,8 +198,8 @@
 		teq	\irqnr, #2
 		bne	44f
 43:		mov	\irqstat, #0x0C
-		strb	\irqstat, [r4, #0x80]		@outb(0x0C, 0xA0) /* Poll command */
-		ldrb	\irqnr, [r4, #0x80]		@irq = (inb(0xA0) & 7) + 8
+		strb	\irqstat, [r4, #0xa0]		@outb(0x0C, 0xA0) /* Poll command */
+		ldrb	\irqnr, [r4, #0xa0]		@irq = (inb(0xA0) & 7) + 8
 		and	\irqstat, \irqnr, #0x80
 		teq	\irqstat, #0
 		beq	44f
@@ -454,6 +453,23 @@
 		.macro	irq_prio_table
 		.endm
 
+#elif defined(CONFIG_ARCH_AT91RM9200)
+#include <asm/hardware.h>
+
+		.macro  disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =(AT91C_VA_BASE_SYS)	@ base virtual address of SYS peripherals
+		ldr	\irqnr, [\base, #AIC_IVR]	@ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)
+		ldr	\irqstat, [\base, #AIC_ISR]	@ read interrupt source number
+		teq	\irqstat, #0			@ ISR is 0 when no current interrupt, or spurious interrupt
+		streq   \tmp, [\base, #AIC_EOICR]	@ not going to be handled further, then ACK it now.
+		.endm
+
+		.macro  irq_prio_table
+		.endm
+
 #elif defined(CONFIG_ARCH_MX1ADS)
 
 		.macro	disable_fiq
@@ -479,6 +495,32 @@
 		.macro	irq_prio_table
 		.endm
 
+#elif defined(CONFIG_ARCH_OMAHA)
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		
+		/* Read all interrupts pending... */
+		ldr	\irqnr, =IO_ADDRESS(PLAT_PERIPHERAL_BASE) + OMAHA_INTPND
+		ldr	\irqstat, [\irqnr]		/* INTPND */
+
+		/* All pending irqs are now in \irqstat */
+		mov	\irqnr, #0
+1001:		tst	\irqstat, #1
+		bne	1002f
+		add	\irqnr, \irqnr, #1
+		mov	\irqstat, \irqstat, lsr #1
+		cmp	\irqnr, #MAXIRQNUM
+		bcc	1001b
+1002:		/* EQ will be set if we reach MAXIRQNUM */
+
+		.endm
+
+		.macro	irq_prio_table
+		.endm    
+
 #elif defined(CONFIG_ARCH_CLPS711X)
 
 #include <asm/hardware/clps7111.h>
@@ -611,16 +653,6 @@
 		and	r2, r6, #31			@ int mode
 		b	SYMBOL_NAME(bad_mode)
 
-#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE
-		/* The FPE is always present */
-		.equ	fpe_not_present, 0
-#else
-wfs_mask_data:	.word	0x0e200110			@ WFS/RFS
-		.word	0x0fef0fff
-		.word	0x0d000100			@ LDF [sp]/STF [sp]
-		.word	0x0d000100			@ LDF [fp]/STF [fp]
-		.word	0x0f000f00
-
 /* We get here if an undefined instruction happens and the floating
  * point emulator is not present.  If the offending instruction was
  * a WFS, we just perform a normal return as if we had emulated the
@@ -628,30 +660,7 @@
  * to run so that the emulator module proper can be loaded. --philb
  */
 fpe_not_present:
-		adr	r10, wfs_mask_data
-		ldmia	r10, {r4, r5, r6, r7, r8}
-		ldr	r10, [sp, #S_PC]		@ Load PC
-		sub	r10, r10, #4
-		mask_pc	r10, r10
-		ldrt	r10, [r10]			@ get instruction
-		and	r5, r10, r5
-		teq	r5, r4				@ Is it WFS?
-		moveq	pc, r9
-		and	r5, r10, r8
-		teq	r5, r6				@ Is it LDF/STF on sp or fp?
-		teqne	r5, r7
-		movne	pc, lr
-		tst	r10, #0x00200000		@ Does it have WB
-		moveq	pc, r9
-		and	r4, r10, #255			@ get offset
-		and	r6, r10, #0x000f0000
-		tst	r10, #0x00800000		@ +/-
-		ldr	r5, [sp, r6, lsr #14]		@ Load reg
-		rsbeq	r4, r4, #0
-		add	r5, r5, r4, lsl #2
-		str	r5, [sp, r6, lsr #14]		@ Save reg
-		mov	pc, r9
-#endif
+		mov	pc, lr
 
 /*
  * SVC mode handlers
@@ -703,11 +712,13 @@
 		@ routine called with r0 = irq number, r1 = struct pt_regs *
 		@
 		adrsvc	ne, lr, 1b
-		bne	do_IRQ
+		bne	asm_do_IRQ
 		ldr	r0, [sp, #S_PSR]		@ irqs are already disabled
 		msr	spsr, r0
 		ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
 
+		.ltorg
+
 		.align	5
 __und_svc:	sub	sp, sp, #S_FRAME_SIZE
 		stmia	sp, {r0 - r12}			@ save r0 - r12
@@ -807,11 +818,13 @@
 		@
 		@ routine called with r0 = irq number, r1 = struct pt_regs *
 		@
-		bne	do_IRQ
+		bne	asm_do_IRQ
 		mov	why, #0
 		get_current_task tsk
 		b	ret_to_user
 
+		.ltorg
+
 		.align	5
 __und_usr:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
 		stmia	sp, {r0 - r12}			@ Save r0 - r12
@@ -822,6 +835,8 @@
 		stmdb	r8, {sp, lr}^			@ Save user sp, lr
 		alignment_trap r4, r7, __temp_und
 		zero_fp
+		tst	r6, #T_BIT			@ Thumb mode
+		bne	fpundefinstr
 		adrsvc	al, r9, ret_from_exception	@ r9  = normal FP return
 		adrsvc	al, lr, fpundefinstr		@ lr  = undefined instr return
 
@@ -859,8 +874,9 @@
  * This is the return code to user mode for abort handlers
  */
 ENTRY(ret_from_exception)
-		get_current_task tsk
+		disable_irq r1
 		mov	why, #0
+		get_current_task tsk
 		b	ret_to_user
 
 		.data
@@ -909,7 +925,9 @@
 		@
 		@ now branch to the relevent MODE handling routine
 		@
-		mov	r13, #I_BIT | MODE_SVC
+		mrs	r13, cpsr
+		bic	r13, r13, #MODE_MASK
+		orr	r13, r13, #I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
 
 		and	lr, lr, #15
@@ -950,7 +968,9 @@
 		@
 		@ now branch to the relevent MODE handling routine
 		@
-		mov	r13, #I_BIT | MODE_SVC
+		mrs	r13, cpsr
+		bic	r13, r13, #MODE_MASK
+		orr	r13, r13, #I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
 
 		and	lr, lr, #15
@@ -992,7 +1012,9 @@
 		@
 		@ now branch to the relevent MODE handling routine
 		@
-		mov	r13, #I_BIT | MODE_SVC
+		mrs	r13, cpsr
+		bic	r13, r13, #MODE_MASK
+		orr	r13, r13, #I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
 
 		ands	lr, lr, #15
@@ -1033,7 +1055,9 @@
 		@
 		@ now branch to the relevent MODE handling routine
 		@
-		mov	r13, #I_BIT | MODE_SVC
+		mrs	r13, cpsr
+		bic	r13, r13, #MODE_MASK
+		orr	r13, r13, #I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
 
 		and	lr, lr, #15
diff -urN linux-2.4.22-pre2/arch/arm/kernel/entry-common.S linux-2.4.22-pre3/arch/arm/kernel/entry-common.S
--- linux-2.4.22-pre2/arch/arm/kernel/entry-common.S	2002-02-25 11:37:52.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/kernel/entry-common.S	2003-07-05 18:09:36.000000000 -0700
@@ -34,6 +34,7 @@
  * stack.
  */
 ret_fast_syscall:
+	disable_irq r1				@ ensure IRQs are disabled
 	ldr	r1, [tsk, #TSK_NEED_RESCHED]
 	ldr	r2, [tsk, #TSK_SIGPENDING]
 	teq	r1, #0				@ need_resched || sigpending
@@ -45,28 +46,35 @@
  * Ok, we need to do extra processing, enter the slow path.
  */
 slow:	str	r0, [sp, #S_R0+S_OFF]!	@ returned r0
-	b	1f
+	teq	r1, #0
+	beq	1f
 
 /*
  * "slow" syscall return path.  "why" tells us if this was a real syscall.
  */
 reschedule:
 	bl	SYMBOL_NAME(schedule)
+ret_disable_irq:
+	disable_irq r1				@ ensure IRQs are disabled
 ENTRY(ret_to_user)
 ret_slow_syscall:
 	ldr	r1, [tsk, #TSK_NEED_RESCHED]
 	ldr	r2, [tsk, #TSK_SIGPENDING]
-1:	teq	r1, #0				@ need_resched => schedule()
+	teq	r1, #0				@ need_resched => schedule()
 	bne	reschedule
-	teq	r2, #0				@ sigpending => do_signal()
-	blne	__do_signal
+1:	teq	r2, #0				@ sigpending => do_signal()
+	bne	__do_signal
+restore:
 	restore_user_regs
 
 __do_signal:
+	enable_irq r1
 	mov	r0, #0				@ NULL 'oldset'
 	mov	r1, sp				@ 'regs'
 	mov	r2, why				@ 'syscall'
-	b	SYMBOL_NAME(do_signal)		@ note the bl above sets lr
+	bl	SYMBOL_NAME(do_signal)		@ note the bl above sets lr
+	disable_irq r1				@ ensure IRQs are disabled
+	b	restore
 
 /*
  * This is how we return from a fork.  __switch_to will be calling us
@@ -79,11 +87,11 @@
 	ldr	ip, [tsk, #TSK_PTRACE]		@ check for syscall tracing
 	mov	why, #1
 	tst	ip, #PT_TRACESYS		@ are we tracing syscalls?
-	beq	ret_slow_syscall
+	beq	ret_disable_irq
 	mov	r1, sp
 	mov	r0, #1				@ trace exit [IP = 1]
 	bl	SYMBOL_NAME(syscall_trace)
-	b	ret_slow_syscall
+	b	ret_disable_irq
 	
 
 #include "calls.S"
@@ -130,7 +138,7 @@
 	ldr	ip, [ip]
 	mcr	p15, 0, ip, c1, c0		@ update control register
 #endif
-	enable_irqs ip
+	enable_irq ip
 
 	str	r4, [sp, #-S_OFF]!		@ push fifth arg
 
@@ -174,7 +182,7 @@
 	mov	r1, sp
 	mov	r0, #1				@ trace exit [IP = 1]
 	bl	SYMBOL_NAME(syscall_trace)
-	b	ret_slow_syscall
+	b	ret_disable_irq
 
 	.align	5
 #ifdef CONFIG_ALIGNMENT_TRAP
diff -urN linux-2.4.22-pre2/arch/arm/kernel/entry-header.S linux-2.4.22-pre3/arch/arm/kernel/entry-header.S
--- linux-2.4.22-pre2/arch/arm/kernel/entry-header.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/entry-header.S	2003-07-05 18:09:36.000000000 -0700
@@ -41,14 +41,14 @@
 @
 @ Stack format (ensured by USER_* and SVC_*)
 @
-#define S_FRAME_SIZE	72
 #ifdef CONFIG_CPU_32
+#define S_FRAME_SIZE	72
 #define S_OLD_R0	68
 #define S_PSR		64
 #else
+#define S_FRAME_SIZE	68
 #define S_OLD_R0	64
 #define S_PSR		60
-#define S_PC		60
 #endif
 
 #define S_PC		60
@@ -70,6 +70,24 @@
 #define S_OFF		8
 
 #ifdef CONFIG_CPU_32
+	.macro	set_cpsr_c, reg, mode
+#if 1
+	/* broken binutils */
+	mov	\reg, \mode
+	msr	cpsr_c, \reg
+#else
+	msr	cpsr_c, \mode
+#endif
+	.endm
+
+	.macro	disable_irq, temp
+	set_cpsr_c \temp, #I_BIT | MODE_SVC
+	.endm
+
+	.macro	enable_irq, temp
+	set_cpsr_c \temp, #MODE_SVC
+	.endm
+
 		.macro	save_user_regs
 		sub	sp, sp, #S_FRAME_SIZE
 		stmia	sp, {r0 - r12}			@ Calling r0 - r12
@@ -81,21 +99,23 @@
 		str	r0, [sp, #S_OLD_R0]		@ Save OLD_R0
 		.endm
 
+/*
+ * Must be called with IRQs already disabled.
+ */
 		.macro	restore_user_regs
-		ldr	r0, [sp, #S_PSR]		@ Get calling cpsr
-		mov	ip, #I_BIT | MODE_SVC
-		msr	cpsr_c, ip			@ disable IRQs
-		msr	spsr, r0			@ save in spsr_svc
-		ldr	lr, [sp, #S_PC]			@ Get PC
-		ldmia	sp, {r0 - lr}^			@ Get calling r0 - lr
+		ldr	r1, [sp, #S_PSR]		@ Get calling cpsr
+		ldr	lr, [sp, #S_PC]!		@ Get PC
+		msr	spsr, r1			@ save in spsr_svc
+		ldmdb	sp, {r0 - lr}^			@ Get calling r0 - lr
 		mov	r0, r0
-		add	sp, sp, #S_FRAME_SIZE
+		add	sp, sp, #S_FRAME_SIZE - S_PC
 		movs	pc, lr				@ return & move spsr_svc into cpsr
 		.endm
 
+/*
+ * Must be called with IRQs already disabled.
+ */
 		.macro	fast_restore_user_regs
-		mov	ip, #I_BIT | MODE_SVC
-		msr	cpsr_c, ip			@ disable IRQs
 		ldr	r1, [sp, #S_OFF + S_PSR]	@ get calling cpsr
 		ldr	lr, [sp, #S_OFF + S_PC]!	@ get pc
  		msr	spsr, r1			@ save in spsr_svc
@@ -108,11 +128,6 @@
 		.macro	mask_pc, rd, rm
 		.endm
 
-		.macro	enable_irqs, temp
-		mov	\temp, #MODE_SVC
-		msr	cpsr_c, \temp
-		.endm
-
 		.macro	get_current_task, rd
 		mov	\rd, sp, lsr #13
 		mov	\rd, \rd, lsl #13
@@ -136,9 +151,9 @@
 
 #else
 		.macro	save_user_regs
-		str	r0, [sp, #-4]!
-		str	lr, [sp, #-4]!
-		sub	sp, sp, #15*4
+		sub	sp, sp, #S_FRAME_SIZE
+		str	r0, [sp, #S_OLD_R0]
+		str	lr, [sp, #S_PC]
 		stmia	sp, {r0 - lr}^
 		mov	r0, r0
 		.endm
@@ -146,17 +161,16 @@
 		.macro	restore_user_regs
 		ldmia	sp, {r0 - lr}^
 		mov	r0, r0
-		ldr	lr, [sp, #15*4]
-		add	sp, sp, #15*4+8
+		ldr	lr, [sp, #S_PC]
+		add	sp, sp, #S_FRAME_SIZE
 		movs	pc, lr
 		.endm
 
 		.macro	fast_restore_user_regs
-		add	sp, sp, #S_OFF
-		ldmib	sp, {r1 - lr}^
+		add	sp, sp, #S_OFF + S_PC
+		ldmdb	sp, {r1 - lr}^
 		mov	r0, r0
-		ldr	lr, [sp, #15*4]
-		add	sp, sp, #15*4+8
+		ldr	lr, [sp], #S_FRAME_SIZE - S_PC
 		movs	pc, lr
 		.endm
 
@@ -164,7 +178,11 @@
 		bic	\rd, \rm, #PCMASK
 		.endm
 
-		.macro	enable_irqs, temp
+		.macro	disable_irq, temp
+		teqp	pc, #0x08000003
+		.endm
+
+		.macro	enable_irq, temp
 		teqp	pc, #0x00000003
 		.endm
 
diff -urN linux-2.4.22-pre2/arch/arm/kernel/head-armv.S linux-2.4.22-pre3/arch/arm/kernel/head-armv.S
--- linux-2.4.22-pre2/arch/arm/kernel/head-armv.S	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/head-armv.S	2003-07-05 18:09:36.000000000 -0700
@@ -52,17 +52,22 @@
 		.endm
 
 /*
- *  Kernel startup entry point.
+ * Kernel startup entry point.
+ * ---------------------------
  *
- * The rules are:
- *  r0      - should be 0
- *  r1      - unique architecture number
- *  MMU     - off
- *  I-cache - on or off
- *  D-cache - off
+ * This is normally called from the decompressor code.  The requirements
+ * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
+ * r1 = machine nr.
  *
- * See linux/arch/arm/tools/mach-types for the complete list of numbers
- * for r1.
+ * This code is mostly position independent, so if you link the kernel at
+ * 0xc0008000, you call this at __pa(0xc0008000).
+ *
+ * See linux/arch/arm/tools/mach-types for the complete list of machine
+ * numbers for r1.
+ *
+ * We're trying to keep crap to a minimum; DO NOT add any machine specific
+ * crap here - that's what the boot loader (or in extreme, well justified
+ * circumstances, zImage) is for.
  */
 		.section ".text.init",#alloc,#execinstr
 		.type	stext, #function
@@ -143,7 +148,6 @@
 
 		.type	__switch_data, %object
 __switch_data:	.long	__mmap_switched
-		.long	SYMBOL_NAME(compat)
 		.long	SYMBOL_NAME(__bss_start)
 		.long	SYMBOL_NAME(_end)
 		.long	SYMBOL_NAME(processor_id)
@@ -151,28 +155,33 @@
 		.long	SYMBOL_NAME(cr_alignment)
 		.long	SYMBOL_NAME(init_task_union)+8192
 
+/*
+ * Enable the MMU.  This completely changes the structure of the visible
+ * memory space.  You will not be able to trace execution through this.
+ * If you have an enquiry about this, *please* check the linux-arm-kernel
+ * mailing list archives BEFORE sending another post to the list.
+ */
 		.type	__ret, %function
 __ret:		ldr	lr, __switch_data
 		mcr	p15, 0, r0, c1, c0
-		mov	r0, r0
+		mrc	p15, 0, r0, c1, c0, 0		@ read it back.
 		mov	r0, r0
 		mov	r0, r0
 		mov	pc, lr
 
-		/*
-		 * This code follows on after the page
-		 * table switch and jump above.
-		 *
-		 * r0  = processor control register
-		 * r1  = machine ID
-		 * r9  = processor ID
-		 */
+/*
+ * The following fragment of code is executed with the MMU on, and uses
+ * absolute addresses; this is not position independent.
+ *
+ *  r0  = processor control register
+ *  r1  = machine ID
+ *  r9  = processor ID
+ */
 		.align	5
 __mmap_switched:
 		adr	r3, __switch_data + 4
-		ldmia	r3, {r2, r4, r5, r6, r7, r8, sp}@ r2 = compat
+		ldmia	r3, {r4, r5, r6, r7, r8, sp}@ r2 = compat
 							@ sp = stack pointer
-		str	r12, [r2]
 
 		mov	fp, #0				@ Clear BSS (and zero fp)
 1:		cmp	r4, r5
diff -urN linux-2.4.22-pre2/arch/arm/kernel/irq-arch.c linux-2.4.22-pre3/arch/arm/kernel/irq-arch.c
--- linux-2.4.22-pre2/arch/arm/kernel/irq-arch.c	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/irq-arch.c	2003-07-05 18:09:36.000000000 -0700
@@ -20,6 +20,8 @@
 #include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/smp.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
diff -urN linux-2.4.22-pre2/arch/arm/kernel/irq.c linux-2.4.22-pre3/arch/arm/kernel/irq.c
--- linux-2.4.22-pre2/arch/arm/kernel/irq.c	2001-07-04 14:56:44.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/irq.c	2003-07-05 18:09:36.000000000 -0700
@@ -27,6 +27,8 @@
 #include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/smp.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 #include <linux/init.h>
 
 #include <asm/irq.h>
@@ -46,6 +48,7 @@
 
 static volatile unsigned long irq_err_count;
 static spinlock_t irq_controller_lock;
+static LIST_HEAD(irq_pending);
 
 struct irqdesc irq_desc[NR_IRQS];
 void (*init_arch_irq)(void) __initdata = NULL;
@@ -57,21 +60,32 @@
 {
 }
 
+/*
+ * No architecture-specific irq_finish function defined in arm/arch/irq.h.
+ */
+#ifndef irq_finish
+#define irq_finish(irq) do { } while (0)
+#endif
+
 /**
  *	disable_irq - disable an irq and wait for completion
  *	@irq: Interrupt to disable
  *
- *	Disable the selected interrupt line.
+ *	Disable the selected interrupt line.  We do this lazily.
  *
- *	This function may be called - with care - from IRQ context.
+ *	This function may be called from IRQ context.
  */
 void disable_irq(unsigned int irq)
 {
+	struct irqdesc *desc = irq_desc + irq;
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_controller_lock, flags);
-	irq_desc[irq].enabled = 0;
-	irq_desc[irq].mask(irq);
+	if (!desc->disable_depth++) {
+#ifndef CONFIG_CPU_SA1100
+		desc->mask(irq);
+#endif
+	}
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 
@@ -79,19 +93,37 @@
  *	enable_irq - enable interrupt handling on an irq
  *	@irq: Interrupt to enable
  *
- *	Re-enables the processing of interrupts on this IRQ line
+ *	Re-enables the processing of interrupts on this IRQ line.
+ *	Note that this may call the interrupt handler, so you may
+ *	get unexpected results if you hold IRQs disabled.
  *
  *	This function may be called from IRQ context.
  */
 void enable_irq(unsigned int irq)
 {
+	struct irqdesc *desc = irq_desc + irq;
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_controller_lock, flags);
-	irq_desc[irq].probing = 0;
-	irq_desc[irq].triggered = 0;
-	irq_desc[irq].enabled = 1;
-	irq_desc[irq].unmask(irq);
+	if (!desc->disable_depth) {
+		printk("enable_irq(%u) unbalanced from %p\n", irq,
+			__builtin_return_address(0));
+	} else if (!--desc->disable_depth) {
+		desc->probing = 0;
+		desc->unmask(irq);
+
+		/*
+		 * If the interrupt is waiting to be processed,
+		 * try to re-run it.  We can't directly run it
+		 * from here since the caller might be in an
+		 * interrupt-protected region.
+		 */
+		if (desc->pending) {
+			desc->pending = 0;
+			if (list_empty(&desc->pend))
+				list_add(&desc->pend, &irq_pending);
+		}
+	}
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 
@@ -128,7 +160,7 @@
  * a large number if IRQs to appear in the same jiffie with the
  * same instruction pointer (or within 2 instructions).
  */
-static void check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs)
+static int check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs)
 {
 	unsigned long instr_ptr = instruction_pointer(regs);
 
@@ -137,95 +169,202 @@
 		desc->lck_cnt += 1;
 
 		if (desc->lck_cnt > MAX_IRQ_CNT) {
-			printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq);
-			disable_irq(irq);
+			if (!desc->lck_warned++)
+				printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq);
+			mod_timer(&desc->lck_timer, jiffies + 10*HZ);
+			return 1;
 		}
 	} else {
 		desc->lck_cnt = 0;
 		desc->lck_pc  = instruction_pointer(regs);
 		desc->lck_jif = jiffies;
+		if (desc->lck_warned < 0)
+			desc->lck_warned ++;
 	}
+	return 0;
+}
+
+static void
+__do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
+{
+	unsigned int status;
+
+	spin_unlock(&irq_controller_lock);
+
+	if (!(action->flags & SA_INTERRUPT))
+		local_irq_enable();
+
+	status = 0;
+	do {
+		status |= action->flags;
+		action->handler(irq, action->dev_id, regs);
+		action = action->next;
+	} while (action);
+
+	if (status & SA_SAMPLE_RANDOM)
+		add_interrupt_randomness(irq);
+
+	spin_lock_irq(&irq_controller_lock);
 }
 
 /*
  * do_IRQ handles all normal device IRQ's
  */
-asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+void do_IRQ(int irq, struct pt_regs * regs)
 {
-	struct irqdesc * desc;
-	struct irqaction * action;
-	int cpu;
+	struct irqdesc *desc = irq_desc + irq;
 
-	irq = fixup_irq(irq);
+	desc->triggered = 1;
 
 	/*
-	 * Some hardware gives randomly wrong interrupts.  Rather
-	 * than crashing, do something sensible.
+	 * Acknowledge and clear the IRQ, but (if its
+	 * a level-based IRQ, don't mask it)
 	 */
-	if (irq >= NR_IRQS)
-		goto bad_irq;
+	desc->mask_ack(irq);
 
-	desc = irq_desc + irq;
+	/*
+	 * If we're currently running this IRQ, or its disabled,
+	 * we shouldn't process the IRQ.  Instead, turn on the
+	 * hardware masks.
+	 */
+	if (desc->running || desc->disable_depth)
+		goto running;
 
-	spin_lock(&irq_controller_lock);
-	desc->mask_ack(irq);
-	spin_unlock(&irq_controller_lock);
+	/*
+	 * Mark the IRQ currently in progress.
+	 */
+	desc->running = 1;
 
-	cpu = smp_processor_id();
-	irq_enter(cpu, irq);
-	kstat.irqs[cpu][irq]++;
-	desc->triggered = 1;
+	kstat.irqs[smp_processor_id()][irq]++;
 
-	/* Return with this interrupt masked if no action */
-	action = desc->action;
+	do {
+		struct irqaction *action;
 
-	if (action) {
-		int status = 0;
+		action = desc->action;
+		if (!action)
+			break;
 
-		if (desc->nomask) {
-			spin_lock(&irq_controller_lock);
+		if (desc->pending && desc->disable_depth == 0) {
+			desc->pending = 0;
 			desc->unmask(irq);
-			spin_unlock(&irq_controller_lock);
 		}
 
-		if (!(action->flags & SA_INTERRUPT))
-			__sti();
+		__do_irq(irq, action, regs);
+	} while (desc->pending && desc->disable_depth == 0);
 
-		do {
-			status |= action->flags;
-			action->handler(irq, action->dev_id, regs);
-			action = action->next;
-		} while (action);
+	desc->running = 0;
 
-		if (status & SA_SAMPLE_RANDOM)
-			add_interrupt_randomness(irq);
-		__cli();
+	/*
+	 * If we are disabled or freed, shut down the handler.
+	 */
+	if (desc->action && !check_irq_lock(desc, irq, regs))
+		desc->unmask(irq);
+	return;
 
-		if (!desc->nomask && desc->enabled) {
-			spin_lock(&irq_controller_lock);
-			desc->unmask(irq);
-			spin_unlock(&irq_controller_lock);
+ running:
+	/*
+	 * We got another IRQ while this one was masked or
+	 * currently running.  Delay it.
+	 */
+	desc->pending = 1;
+}
+
+static void do_pending_irqs(struct pt_regs *regs)
+{
+	struct list_head head, *l, *n;
+
+	do {
+		struct irqdesc *desc;
+
+		/*
+		 * First, take the pending interrupts off the list.
+		 * The act of calling the handlers may add some IRQs
+		 * back onto the list.
+		 */
+		head = irq_pending;
+		INIT_LIST_HEAD(&irq_pending);
+		head.next->prev = &head;
+		head.prev->next = &head;
+
+		/*
+		 * Now run each entry.  We must delete it from our
+		 * list before calling the handler.
+		 */
+		list_for_each_safe(l, n, &head) {
+			desc = list_entry(l, struct irqdesc, pend);
+			list_del_init(&desc->pend);
+			do_IRQ(desc - irq_desc, regs);
 		}
-	}
+
+		/*
+		 * The list must be empty.
+		 */
+		BUG_ON(!list_empty(&head));
+	} while (!list_empty(&irq_pending));
+}
+
+/*
+ * do_IRQ handles all hardware IRQ's.  Decoded IRQs should not
+ * come via this function.  Instead, they should provide their
+ * own 'handler'
+ */
+asmlinkage void asm_do_IRQ(int irq, struct pt_regs *regs)
+{
+	irq = fixup_irq(irq);
 
 	/*
-	 * Debug measure - hopefully we can continue if an
-	 * IRQ lockup problem occurs...
+	 * Some hardware gives randomly wrong interrupts.  Rather
+	 * than crashing, do something sensible.
 	 */
-	check_irq_lock(desc, irq, regs);
+	if (irq < NR_IRQS) {
+		int cpu = smp_processor_id();
 
-	irq_exit(cpu, irq);
+		irq_enter(cpu, irq);
+		spin_lock(&irq_controller_lock);
+		do_IRQ(irq, regs);
 
-	if (softirq_pending(cpu))
-		do_softirq();
-	return;
+		/*
+		 * Now re-run any pending interrupts.
+		 */
+		if (!list_empty(&irq_pending))
+			do_pending_irqs(regs);
+
+		spin_unlock(&irq_controller_lock);
+		irq_exit(cpu, irq);
+
+		if (softirq_pending(cpu))
+			do_softirq();
+
+		irq_finish(irq);
+		return;
+	}
 
-bad_irq:
 	irq_err_count += 1;
 	printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
+
+	irq_finish(irq);
 	return;
 }
 
+static void irqlck_timeout(unsigned long _data)
+{
+	struct irqdesc *desc = (struct irqdesc *)_data;
+
+	spin_lock(&irq_controller_lock);
+
+	del_timer(&desc->lck_timer);
+
+	desc->lck_cnt = 0;
+	desc->lck_pc  = 0;
+	desc->lck_jif = 0;
+	desc->lck_warned = -10;
+
+	if (desc->disable_depth == 0)
+		desc->unmask(desc - irq_desc);
+
+	spin_unlock(&irq_controller_lock);
+}
+
 #ifdef CONFIG_ARCH_ACORN
 void do_ecard_IRQ(int irq, struct pt_regs *regs)
 {
@@ -302,10 +441,12 @@
 	*p = new;
 
 	if (!shared) {
-		desc->nomask = (new->flags & SA_IRQNOMASK) ? 1 : 0;
 		desc->probing = 0;
+		desc->running = 0;
+		desc->pending = 0;
+		desc->disable_depth = 1;
 		if (!desc->noautoenable) {
-			desc->enabled = 1;
+			desc->disable_depth = 0;
 			desc->unmask(irq);
 		}
 	}
@@ -383,7 +524,7 @@
  *	On a shared IRQ the caller must ensure the interrupt is disabled
  *	on the card it drives before calling this function.
  *
- *	This function may be called from interrupt context.
+ *	This function must not be called from interrupt context.
  */
 void free_irq(unsigned int irq, void *dev_id)
 {
@@ -416,6 +557,8 @@
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 
+static DECLARE_MUTEX(probe_sem);
+
 /* Start the interrupt probing.  Unlike other architectures,
  * we don't return a mask of interrupts from probe_irq_on,
  * but return the number of interrupts enabled for the probe.
@@ -427,15 +570,15 @@
 	unsigned int i, irqs = 0;
 	unsigned long delay;
 
+	down(&probe_sem);
+
 	/*
 	 * first snaffle up any unassigned but
 	 * probe-able interrupts
 	 */
 	spin_lock_irq(&irq_controller_lock);
 	for (i = 0; i < NR_IRQS; i++) {
-		if (!irq_desc[i].valid ||
-		    !irq_desc[i].probe_ok ||
-		    irq_desc[i].action)
+		if (!irq_desc[i].probe_ok || irq_desc[i].action)
 			continue;
 
 		irq_desc[i].probing = 1;
@@ -456,18 +599,31 @@
 	 */
 	spin_lock_irq(&irq_controller_lock);
 	for (i = 0; i < NR_IRQS; i++) {
-		if (irq_desc[i].probing &&
-		    irq_desc[i].triggered) {
+		if (irq_desc[i].probing && irq_desc[i].triggered) {
 			irq_desc[i].probing = 0;
 			irqs -= 1;
 		}
 	}
 	spin_unlock_irq(&irq_controller_lock);
 
-	/* now filter out any obviously spurious interrupts */
 	return irqs;
 }
 
+unsigned int probe_irq_mask(unsigned long irqs)
+{
+	unsigned int mask = 0, i;
+
+	spin_lock_irq(&irq_controller_lock);
+	for (i = 0; i < 16 && i < NR_IRQS; i++)
+		if (irq_desc[i].probing && irq_desc[i].triggered)
+			mask |= 1 << i;
+	spin_unlock_irq(&irq_controller_lock);
+
+	up(&probe_sem);
+
+	return mask;
+}
+
 /*
  * Possible return values:
  *  >= 0 - interrupt number
@@ -499,6 +655,8 @@
 out:
 	spin_unlock_irq(&irq_controller_lock);
 
+	up(&probe_sem);
+
 	return irq_found;
 }
 
@@ -512,12 +670,17 @@
 	int irq;
 
 	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].disable_depth = 1;
 		irq_desc[irq].probe_ok = 0;
 		irq_desc[irq].valid    = 0;
 		irq_desc[irq].noautoenable = 0;
 		irq_desc[irq].mask_ack = dummy_mask_unmask_irq;
 		irq_desc[irq].mask     = dummy_mask_unmask_irq;
 		irq_desc[irq].unmask   = dummy_mask_unmask_irq;
+		INIT_LIST_HEAD(&irq_desc[irq].pend);
+		init_timer(&irq_desc[irq].lck_timer);
+		irq_desc[irq].lck_timer.data = (unsigned long)&irq_desc[irq];
+		irq_desc[irq].lck_timer.function = irqlck_timeout;
 	}
 
 	init_arch_irq();
diff -urN linux-2.4.22-pre2/arch/arm/kernel/oldlatches.c linux-2.4.22-pre3/arch/arm/kernel/oldlatches.c
--- linux-2.4.22-pre2/arch/arm/kernel/oldlatches.c	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/oldlatches.c	2003-07-05 18:09:36.000000000 -0700
@@ -29,10 +29,10 @@
 	if (machine_is_archimedes()) {
 		unsigned long flags;
 
-		local_save_flags(flags);
+		local_irq_save(flags);
 		latch_a_copy = (latch_a_copy & ~mask) | newdata;
 		__raw_writeb(latch_a_copy, LATCHA_BASE);
-		local_restore_flags(flags);
+		local_irq_restore(flags);
 
 		printk("Latch: A = 0x%02x\n", latch_a_copy);
 	} else
@@ -46,10 +46,10 @@
 	if (machine_is_archimedes()) {
 		unsigned long flags;
 
-		local_save_flags(flags);
+		local_irq_save(flags);
 		latch_b_copy = (latch_b_copy & ~mask) | newdata;
 		__raw_writeb(latch_b_copy, LATCHB_BASE);
-		local_restore_flags(flags);
+		local_irq_restore(flags);
 
 		printk("Latch: B = 0x%02x\n", latch_b_copy);
 	} else
diff -urN linux-2.4.22-pre2/arch/arm/kernel/process.c linux-2.4.22-pre3/arch/arm/kernel/process.c
--- linux-2.4.22-pre2/arch/arm/kernel/process.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/process.c	2003-07-05 18:09:36.000000000 -0700
@@ -24,18 +24,10 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 
-#include <asm/leds.h>
 #include <asm/system.h>
+#include <asm/leds.h>
 #include <asm/uaccess.h>
 
-/*
- * Values for cpu_do_idle()
- */
-#define IDLE_WAIT_SLOW	0
-#define IDLE_WAIT_FAST	1
-#define IDLE_CLOCK_SLOW	2
-#define IDLE_CLOCK_FAST	3
-
 extern const char *processor_modes[];
 extern void setup_mm_for_reboot(char mode);
 
@@ -75,6 +67,18 @@
 void (*pm_power_off)(void);
 
 /*
+ * This is our default idle handler.  We need to disable
+ * interrupts here to ensure we don't miss a wakeup call.
+ */
+void default_idle(void)
+{
+	local_irq_disable();
+	if (!current->need_resched && !hlt_counter)
+		arch_idle();
+	local_irq_enable();
+}
+
+/*
  * The idle thread.  We try to conserve power, while trying to keep
  * overall latency low.  The architecture specific idle is passed
  * a value to indicate the level of "idleness" of the system.
@@ -89,7 +93,7 @@
 	while (1) {
 		void (*idle)(void) = pm_idle;
 		if (!idle)
-			idle = arch_idle;
+			idle = default_idle;
 		leds_event(led_idle_start);
 		while (!current->need_resched)
 			idle();
@@ -176,15 +180,15 @@
 		flags & CC_Z_BIT ? 'Z' : 'z',
 		flags & CC_C_BIT ? 'C' : 'c',
 		flags & CC_V_BIT ? 'V' : 'v');
-	printk("  IRQs %s  FIQs %s  Mode %s%s  Segment %s\n",
-		interrupts_enabled(regs) ? "on" : "off",
-		fast_interrupts_enabled(regs) ? "on" : "off",
+	printk("  IRQs o%s  FIQs o%s  Mode %s%s  Segment %s\n",
+		interrupts_enabled(regs) ? "n" : "ff",
+		fast_interrupts_enabled(regs) ? "n" : "ff",
 		processor_modes[processor_mode(regs)],
 		thumb_mode(regs) ? " (T)" : "",
 		get_fs() == get_ds() ? "kernel" : "user");
 #if defined(CONFIG_CPU_32)
 	{
-		int ctrl, transbase, dac;
+		unsigned int ctrl, transbase, dac;
 		  __asm__ (
 		"	mrc p15, 0, %0, c1, c0\n"
 		"	mrc p15, 0, %1, c2, c0\n"
@@ -282,12 +286,22 @@
 {
 }
 
+static void default_fp_init(union fp_state *fp)
+{
+	memset(fp, 0, sizeof(union fp_state));
+}
+
+void (*fp_init)(union fp_state *) = default_fp_init;
+
 void flush_thread(void)
 {
-	memset(&current->thread.debug, 0, sizeof(struct debug_info));
-	memset(&current->thread.fpstate, 0, sizeof(union fp_state));
-	current->used_math = 0;
-	current->flags &= ~PF_USEDFPU;
+	struct task_struct *tsk = current;
+
+	tsk->flags &= ~PF_USEDFPU;
+	tsk->used_math = 0;
+
+	memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
+	fp_init(&tsk->thread.fpstate);
 }
 
 void release_thread(struct task_struct *dead_task)
@@ -296,16 +310,16 @@
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
-	unsigned long unused,
-	struct task_struct * p, struct pt_regs * regs)
+int
+copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
+	    unsigned long unused, struct task_struct * p, struct pt_regs * regs)
 {
-	struct pt_regs * childregs;
+	struct pt_regs *childregs;
 	struct context_save_struct * save;
 
 	atomic_set(&p->thread.refcount, 1);
 
-	childregs = ((struct pt_regs *)((unsigned long)p + 8192)) - 1;
+	childregs = ((struct pt_regs *)((unsigned long)p + 8192 - 8)) - 1;
 	*childregs = *regs;
 	childregs->ARM_r0 = 0;
 	childregs->ARM_sp = esp;
@@ -324,10 +338,12 @@
  */
 int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
 {
-	if (current->used_math)
+	int used_math = current->used_math;
+
+	if (used_math)
 		memcpy(fp, &current->thread.fpstate.soft, sizeof (*fp));
 
-	return current->used_math;
+	return used_math;
 }
 
 /*
@@ -347,8 +363,8 @@
 
 	dump->u_debugreg[0] = tsk->thread.debug.bp[0].address;
 	dump->u_debugreg[1] = tsk->thread.debug.bp[1].address;
-	dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn;
-	dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn;
+	dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn.arm;
+	dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn.arm;
 	dump->u_debugreg[4] = tsk->thread.debug.nsaved;
 
 	if (dump->start_stack < 0x04000000)
@@ -371,18 +387,18 @@
 	pid_t __ret;
 
 	__asm__ __volatile__(
-	"orr	r0, %1, %2	@ kernel_thread sys_clone
-	mov	r1, #0
-	"__syscall(clone)"
-	movs	%0, r0		@ if we are the child
-	bne	1f
-	mov	fp, #0		@ ensure that fp is zero
-	mov	r0, %4
-	mov	lr, pc
-	mov	pc, %3
-	b	sys_exit
+	"orr	r0, %1, %2	@ kernel_thread sys_clone	\n\
+	mov	r1, #0						\n\
+	"__syscall(clone)"					\n\
+	movs	%0, r0		@ if we are the child		\n\
+	bne	1f						\n\
+	mov	fp, #0		@ ensure that fp is zero	\n\
+	mov	r0, %4						\n\
+	mov	lr, pc						\n\
+	mov	pc, %3						\n\
+	b	sys_exit					\n\
 1:	"
-        : "=r" (__ret)
+        : "=&r" (__ret)
         : "Ir" (flags), "I" (CLONE_VM), "r" (fn), "r" (arg)
 	: "r0", "r1", "lr");
 	return __ret;
@@ -405,7 +421,7 @@
 		return 0;
 
 	stack_page = 4096 + (unsigned long)p;
-	fp = get_css_fp(&p->thread);
+	fp = thread_saved_fp(&p->thread);
 	do {
 		if (fp < stack_page || fp > 4092+stack_page)
 			return 0;
diff -urN linux-2.4.22-pre2/arch/arm/kernel/ptrace.c linux-2.4.22-pre3/arch/arm/kernel/ptrace.c
--- linux-2.4.22-pre2/arch/arm/kernel/ptrace.c	2001-09-18 17:03:51.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/ptrace.c	2003-07-05 18:09:36.000000000 -0700
@@ -9,6 +9,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -16,6 +17,7 @@
 #include <linux/smp_lock.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
+#include <linux/bitops.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -33,18 +35,24 @@
 /*
  * Breakpoint SWI instruction: SWI &9F0001
  */
-#define BREAKINST	0xef9f0001
+#define BREAKINST_ARM	0xef9f0001
+/* fill this in later */
+#define BREAKINST_THUMB	0xdf00
 
 /*
  * Get the address of the live pt_regs for the specified task.
  * These are saved onto the top kernel stack when the process
  * is not running.
+ *
+ * Note: if a user thread is execve'd from kernel space, the
+ * kernel stack will not be empty on entry to the kernel, so
+ * ptracing these tasks will fail.
  */
 static inline struct pt_regs *
 get_user_regs(struct task_struct *task)
 {
 	return (struct pt_regs *)
-		((unsigned long)task + 8192 - sizeof(struct pt_regs));
+		((unsigned long)task + 8192 - 8 - sizeof(struct pt_regs));
 }
 
 /*
@@ -53,7 +61,7 @@
  * this routine assumes that all the privileged stacks are in our
  * data space.
  */
-static inline long get_stack_long(struct task_struct *task, int offset)
+static inline long get_user_reg(struct task_struct *task, int offset)
 {
 	return get_user_regs(task)->uregs[offset];
 }
@@ -65,14 +73,14 @@
  * data space.
  */
 static inline int
-put_stack_long(struct task_struct *task, int offset, long data)
+put_user_reg(struct task_struct *task, int offset, long data)
 {
 	struct pt_regs newregs, *regs = get_user_regs(task);
 	int ret = -EINVAL;
 
 	newregs = *regs;
 	newregs.uregs[offset] = data;
-	
+
 	if (valid_user_regs(&newregs)) {
 		regs->uregs[offset] = data;
 		ret = 0;
@@ -82,23 +90,32 @@
 }
 
 static inline int
-read_tsk_long(struct task_struct *child, unsigned long addr, unsigned long *res)
+read_u32(struct task_struct *task, unsigned long addr, u32 *res)
 {
-	int copied;
+	int ret;
 
-	copied = access_process_vm(child, addr, res, sizeof(*res), 0);
+	ret = access_process_vm(task, addr, res, sizeof(*res), 0);
 
-	return copied != sizeof(*res) ? -EIO : 0;
+	return ret == sizeof(*res) ? 0 : -EIO;
 }
 
 static inline int
-write_tsk_long(struct task_struct *child, unsigned long addr, unsigned long val)
+read_instr(struct task_struct *task, unsigned long addr, u32 *res)
 {
-	int copied;
-
-	copied = access_process_vm(child, addr, &val, sizeof(val), 1);
+	int ret;
 
-	return copied != sizeof(val) ? -EIO : 0;
+	if (addr & 1) {
+		u16 val;
+		ret = access_process_vm(task, addr & ~1, &val, sizeof(val), 0);
+		ret = ret == sizeof(val) ? 0 : -EIO;
+		*res = val;
+	} else {
+		u32 val;
+		ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0);
+		ret = ret == sizeof(val) ? 0 : -EIO;
+		*res = val;
+	}
+	return ret;
 }
 
 /*
@@ -110,7 +127,7 @@
 	unsigned int reg = (insn >> 16) & 15;
 	unsigned long val;
 
-	val = get_stack_long(child, reg);
+	val = get_user_reg(child, reg);
 	if (reg == 15)
 		val = pc_pointer(val + 8);
 
@@ -132,10 +149,10 @@
 		shift = (insn >> 8) & 15;
 		type = 3;
 	} else {
-		val = get_stack_long (child, insn & 15);
+		val = get_user_reg (child, insn & 15);
 
 		if (insn & (1 << 4))
-			shift = (int)get_stack_long (child, (insn >> 8) & 15);
+			shift = (int)get_user_reg (child, (insn >> 8) & 15);
 		else
 			shift = (insn >> 7) & 31;
 
@@ -165,7 +182,7 @@
 	int shift;
 	int type;
 
-	val = get_stack_long(child, insn & 15);
+	val = get_user_reg(child, insn & 15);
 	shift = (insn >> 7) & 31;
 	type = (insn >> 5) & 3;
 
@@ -182,10 +199,24 @@
 	return val;
 }
 
+#define OP_MASK	0x01e00000
+#define OP_AND	0x00000000
+#define OP_EOR	0x00200000
+#define OP_SUB	0x00400000
+#define OP_RSB	0x00600000
+#define OP_ADD	0x00800000
+#define OP_ADC	0x00a00000
+#define OP_SBC	0x00c00000
+#define OP_RSC	0x00e00000
+#define OP_ORR	0x01800000
+#define OP_MOV	0x01a00000
+#define OP_BIC	0x01c00000
+#define OP_MVN	0x01e00000
+
 static unsigned long
 get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn)
 {
-	unsigned long alt = 0;
+	u32 alt = 0;
 
 	switch (insn & 0x0e000000) {
 	case 0x00000000:
@@ -200,21 +231,21 @@
 
 		aluop1 = ptrace_getrn(child, insn);
 		aluop2 = ptrace_getaluop2(child, insn);
-		ccbit  = get_stack_long(child, REG_PSR) & CC_C_BIT ? 1 : 0;
+		ccbit  = get_user_reg(child, REG_PSR) & CC_C_BIT ? 1 : 0;
 
-		switch (insn & 0x01e00000) {
-		case 0x00000000: alt = aluop1 & aluop2;		break;
-		case 0x00200000: alt = aluop1 ^ aluop2;		break;
-		case 0x00400000: alt = aluop1 - aluop2;		break;
-		case 0x00600000: alt = aluop2 - aluop1;		break;
-		case 0x00800000: alt = aluop1 + aluop2;		break;
-		case 0x00a00000: alt = aluop1 + aluop2 + ccbit;	break;
-		case 0x00c00000: alt = aluop1 - aluop2 + ccbit;	break;
-		case 0x00e00000: alt = aluop2 - aluop1 + ccbit;	break;
-		case 0x01800000: alt = aluop1 | aluop2;		break;
-		case 0x01a00000: alt = aluop2;			break;
-		case 0x01c00000: alt = aluop1 & ~aluop2;	break;
-		case 0x01e00000: alt = ~aluop2;			break;
+		switch (insn & OP_MASK) {
+		case OP_AND: alt = aluop1 & aluop2;		break;
+		case OP_EOR: alt = aluop1 ^ aluop2;		break;
+		case OP_SUB: alt = aluop1 - aluop2;		break;
+		case OP_RSB: alt = aluop2 - aluop1;		break;
+		case OP_ADD: alt = aluop1 + aluop2;		break;
+		case OP_ADC: alt = aluop1 + aluop2 + ccbit;	break;
+		case OP_SBC: alt = aluop1 - aluop2 + ccbit;	break;
+		case OP_RSC: alt = aluop2 - aluop1 + ccbit;	break;
+		case OP_ORR: alt = aluop1 | aluop2;		break;
+		case OP_MOV: alt = aluop2;			break;
+		case OP_BIC: alt = aluop1 & ~aluop2;		break;
+		case OP_MVN: alt = ~aluop2;			break;
 		}
 		break;
 	}
@@ -241,7 +272,7 @@
 				else
 					base -= aluop2;
 			}
-			if (read_tsk_long(child, base, &alt) == 0)
+			if (read_u32(child, base, &alt) == 0)
 				alt = pc_pointer(alt);
 		}
 		break;
@@ -255,13 +286,7 @@
 			unsigned int nr_regs;
 
 			if (insn & (1 << 23)) {
-				nr_regs = insn & 65535;
-
-				nr_regs = (nr_regs & 0x5555) + ((nr_regs & 0xaaaa) >> 1);
-				nr_regs = (nr_regs & 0x3333) + ((nr_regs & 0xcccc) >> 2);
-				nr_regs = (nr_regs & 0x0707) + ((nr_regs & 0x7070) >> 4);
-				nr_regs = (nr_regs & 0x000f) + ((nr_regs & 0x0f00) >> 8);
-				nr_regs <<= 2;
+				nr_regs = hweight16(insn & 65535) << 2;
 
 				if (!(insn & (1 << 24)))
 					nr_regs -= 4;
@@ -274,8 +299,8 @@
 
 			base = ptrace_getrn(child, insn);
 
-			if (read_tsk_long(child, base + nr_regs, &alt) == 0)
-				alt = pc_pointer (alt);
+			if (read_u32(child, base + nr_regs, &alt) == 0)
+				alt = pc_pointer(alt);
 			break;
 		}
 		break;
@@ -304,36 +329,82 @@
 }
 
 static int
-add_breakpoint(struct task_struct *child, struct debug_info *dbg, unsigned long addr)
+swap_insn(struct task_struct *task, unsigned long addr,
+	  void *old_insn, void *new_insn, int size)
+{
+	int ret;
+
+	ret = access_process_vm(task, addr, old_insn, size, 0);
+	if (ret == size)
+		ret = access_process_vm(task, addr, new_insn, size, 1);
+	return ret;
+}
+
+static void
+add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr)
 {
 	int nr = dbg->nsaved;
-	int res = -EINVAL;
 
 	if (nr < 2) {
-		res = read_tsk_long(child, addr, &dbg->bp[nr].insn);
-		if (res == 0)
-			res = write_tsk_long(child, addr, BREAKINST);
+		u32 new_insn = BREAKINST_ARM;
+		int res;
 
-		if (res == 0) {
+		res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4);
+
+		if (res == 4) {
 			dbg->bp[nr].address = addr;
 			dbg->nsaved += 1;
 		}
 	} else
 		printk(KERN_ERR "ptrace: too many breakpoints\n");
+}
+
+/*
+ * Clear one breakpoint in the user program.  We copy what the hardware
+ * does and use bit 0 of the address to indicate whether this is a Thumb
+ * breakpoint or an ARM breakpoint.
+ */
+static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp)
+{
+	unsigned long addr = bp->address;
+	union debug_insn old_insn;
+	int ret;
+
+	if (addr & 1) {
+		ret = swap_insn(task, addr & ~1, &old_insn.thumb,
+				&bp->insn.thumb, 2);
+
+		if (ret != 2 || old_insn.thumb != BREAKINST_THUMB)
+			printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at "
+				"0x%08lx (0x%04x)\n", task->comm, task->pid,
+				addr, old_insn.thumb);
+	} else {
+		ret = swap_insn(task, addr & ~3, &old_insn.thumb,
+				&bp->insn.thumb, 4);
 
-	return res;
+		if (ret != 4 || old_insn.arm != BREAKINST_ARM)
+			printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at "
+				"0x%08lx (0x%08x)\n", task->comm, task->pid,
+				addr, old_insn.arm);
+	}
 }
 
-int ptrace_set_bpt(struct task_struct *child)
+void ptrace_set_bpt(struct task_struct *child)
 {
 	struct pt_regs *regs;
-	unsigned long pc, insn;
+	unsigned long pc;
+	u32 insn;
 	int res;
 
 	regs = get_user_regs(child);
 	pc = instruction_pointer(regs);
 
-	res = read_tsk_long(child, pc, &insn);
+	if (thumb_mode(regs)) {
+		printk(KERN_WARNING "ptrace: can't handle thumb mode\n");
+		return;
+	}
+
+	res = read_instr(child, pc, &insn);
 	if (!res) {
 		struct debug_info *dbg = &child->thread.debug;
 		unsigned long alt;
@@ -342,7 +413,7 @@
 
 		alt = get_branch_address(child, pc, insn);
 		if (alt)
-			res = add_breakpoint(child, dbg, alt);
+			add_breakpoint(child, dbg, alt);
 
 		/*
 		 * Note that we ignore the result of setting the above
@@ -354,10 +425,8 @@
 		 * loose control of the thread during single stepping.
 		 */
 		if (!alt || predicate(insn) != PREDICATE_ALWAYS)
-			res = add_breakpoint(child, dbg, pc + 4);
+			add_breakpoint(child, dbg, pc + 4);
 	}
-
-	return res;
 }
 
 /*
@@ -366,24 +435,17 @@
  */
 void __ptrace_cancel_bpt(struct task_struct *child)
 {
-	struct debug_info *dbg = &child->thread.debug;
-	int i, nsaved = dbg->nsaved;
+	int i, nsaved = child->thread.debug.nsaved;
 
-	dbg->nsaved = 0;
+	child->thread.debug.nsaved = 0;
 
 	if (nsaved > 2) {
 		printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
 		nsaved = 2;
 	}
 
-	for (i = 0; i < nsaved; i++) {
-		unsigned long tmp;
-
-		read_tsk_long(child, dbg->bp[i].address, &tmp);
-		write_tsk_long(child, dbg->bp[i].address, dbg->bp[i].insn);
-		if (tmp != BREAKINST)
-			printk(KERN_ERR "ptrace_cancel_bpt: weirdness\n");
-	}
+	for (i = 0; i < nsaved; i++)
+		clear_breakpoint(child, &child->thread.debug.bp[i]);
 }
 
 /*
@@ -396,6 +458,114 @@
 	__ptrace_cancel_bpt(child);
 }
 
+/*
+ * Handle hitting a breakpoint.  regs points at the instruction.
+ */
+void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	/*
+	 * The PC is pointing at the next instruction.  Fix this.
+	 */
+	regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
+
+	__ptrace_cancel_bpt(tsk);
+
+	info.si_signo = SIGTRAP;
+	info.si_errno = 0;
+	info.si_code  = TRAP_BRKPT;
+	info.si_addr  = (void *)instruction_pointer(regs);
+
+	force_sig_info(SIGTRAP, &info, tsk);
+}
+
+/*
+ * Read the word at offset "off" into the "struct user".  We
+ * actually access the pt_regs stored on the kernel stack.
+ */
+static int ptrace_read_user(struct task_struct *tsk, unsigned long off,
+			    unsigned long *ret)
+{
+	unsigned long tmp;
+
+	if (off & 3 || off >= sizeof(struct user))
+		return -EIO;
+
+	tmp = 0;
+	if (off < sizeof(struct pt_regs))
+		tmp = get_user_reg(tsk, off >> 2);
+
+	return put_user(tmp, ret);
+}
+
+/*
+ * Write the word at offset "off" into "struct user".  We
+ * actually access the pt_regs stored on the kernel stack.
+ */
+static int ptrace_write_user(struct task_struct *tsk, unsigned long off,
+			     unsigned long val)
+{
+	if (off & 3 || off >= sizeof(struct user))
+		return -EIO;
+
+	if (off >= sizeof(struct pt_regs))
+		return 0;
+
+	return put_user_reg(tsk, off >> 2, val);
+}
+
+/*
+ * Get all user integer registers.
+ */
+static int ptrace_getregs(struct task_struct *tsk, void *uregs)
+{
+	struct pt_regs *regs = get_user_regs(tsk);
+
+	return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
+}
+
+/*
+ * Set all user integer registers.
+ */
+static int ptrace_setregs(struct task_struct *tsk, void *uregs)
+{
+	struct pt_regs newregs;
+	int ret;
+
+	ret = -EFAULT;
+	if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
+		struct pt_regs *regs = get_user_regs(tsk);
+
+		ret = -EINVAL;
+		if (valid_user_regs(&newregs)) {
+			*regs = newregs;
+			ret = 0;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * Get the child FPU state.
+ */
+static int ptrace_getfpregs(struct task_struct *tsk, void *ufp)
+{
+	return copy_to_user(ufp, &tsk->thread.fpstate,
+			    sizeof(struct user_fp)) ? -EFAULT : 0;
+}
+
+/*
+ * Set the child FPU state.
+ */
+static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
+{
+	tsk->used_math = 1;
+	return copy_from_user(&tsk->thread.fpstate, ufp,
+			      sizeof(struct user_fp)) ? -EFAULT : 0;
+}
+
 static int do_ptrace(int request, struct task_struct *child, long addr, long data)
 {
 	unsigned long tmp;
@@ -407,23 +577,16 @@
 		 */
 		case PTRACE_PEEKTEXT:
 		case PTRACE_PEEKDATA:
-			ret = read_tsk_long(child, addr, &tmp);
-			if (!ret)
+			ret = access_process_vm(child, addr, &tmp,
+						sizeof(unsigned long), 0);
+			if (ret == sizeof(unsigned long))
 				ret = put_user(tmp, (unsigned long *) data);
+			else
+				ret = -EIO;
 			break;
 
-		/*
-		 * read the word at location "addr" in the user registers.
-		 */
 		case PTRACE_PEEKUSR:
-			ret = -EIO;
-			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
-				break;
-
-			tmp = 0;  /* Default return condition */
-			if (addr < sizeof(struct pt_regs))
-				tmp = get_stack_long(child, (int)addr >> 2);
-			ret = put_user(tmp, (unsigned long *)data);
+			ret = ptrace_read_user(child, addr, (unsigned long *)data);
 			break;
 
 		/*
@@ -431,19 +594,16 @@
 		 */
 		case PTRACE_POKETEXT:
 		case PTRACE_POKEDATA:
-			ret = write_tsk_long(child, addr, data);
+			ret = access_process_vm(child, addr, &data,
+						sizeof(unsigned long), 1);
+			if (ret == sizeof(unsigned long))
+				ret = 0;
+			else
+				ret = -EIO;
 			break;
 
-		/*
-		 * write the word at location addr in the user registers.
-		 */
 		case PTRACE_POKEUSR:
-			ret = -EIO;
-			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
-				break;
-
-			if (addr < sizeof(struct pt_regs))
-				ret = put_stack_long(child, (int)addr >> 2, data);
+			ret = ptrace_write_user(child, addr, data);
 			break;
 
 		/*
@@ -471,14 +631,12 @@
 		 * exit.
 		 */
 		case PTRACE_KILL:
-			/* already dead */
-			ret = 0;
-			if (child->state == TASK_ZOMBIE)
-				break;
-			child->exit_code = SIGKILL;
 			/* make sure single-step breakpoint is gone. */
 			__ptrace_cancel_bpt(child);
-			wake_up_process(child);
+			if (child->state != TASK_ZOMBIE) {
+				child->exit_code = SIGKILL;
+				wake_up_process(child);
+			}
 			ret = 0;
 			break;
 
@@ -497,71 +655,32 @@
 			ret = 0;
 			break;
 
-		/*
-		 * detach a process that was attached.
-		 */
 		case PTRACE_DETACH:
 			ret = ptrace_detach(child, data);
 			break;
 
-		/*
-		 * Get all gp regs from the child.
-		 */
-		case PTRACE_GETREGS: {
-			struct pt_regs *regs = get_user_regs(child);
-
-			ret = 0;
-			if (copy_to_user((void *)data, regs,
-					 sizeof(struct pt_regs)))
-				ret = -EFAULT;
-
+		case PTRACE_GETREGS:
+			ret = ptrace_getregs(child, (void *)data);
 			break;
-		}
-
-		/*
-		 * Set all gp regs in the child.
-		 */
-		case PTRACE_SETREGS: {
-			struct pt_regs newregs;
 
-			ret = -EFAULT;
-			if (copy_from_user(&newregs, (void *)data,
-					   sizeof(struct pt_regs)) == 0) {
-				struct pt_regs *regs = get_user_regs(child);
-
-				ret = -EINVAL;
-				if (valid_user_regs(&newregs)) {
-					*regs = newregs;
-					ret = 0;
-				}
-			}
+		case PTRACE_SETREGS:
+			ret = ptrace_setregs(child, (void *)data);
 			break;
-		}
 
-		/*
-		 * Get the child FPU state.
-		 */
 		case PTRACE_GETFPREGS:
-			ret = -EIO;
-			if (!access_ok(VERIFY_WRITE, (void *)data, sizeof(struct user_fp)))
-				break;
-
-			/* we should check child->used_math here */
-			ret = __copy_to_user((void *)data, &child->thread.fpstate,
-					     sizeof(struct user_fp)) ? -EFAULT : 0;
+			ret = ptrace_getfpregs(child, (void *)data);
 			break;
 		
-		/*
-		 * Set the child FPU state.
-		 */
 		case PTRACE_SETFPREGS:
-			ret = -EIO;
-			if (!access_ok(VERIFY_READ, (void *)data, sizeof(struct user_fp)))
-				break;
+			ret = ptrace_setfpregs(child, (void *)data);
+			break;
 
-			child->used_math = 1;
-			ret = __copy_from_user(&child->thread.fpstate, (void *)data,
-					   sizeof(struct user_fp)) ? -EFAULT : 0;
+		case PTRACE_SETOPTIONS:
+			if (data & PTRACE_O_TRACESYSGOOD)
+				child->ptrace |= PT_TRACESYSGOOD;
+			else
+				child->ptrace &= ~PT_TRACESYSGOOD;
+			ret = 0;
 			break;
 
 		default:
diff -urN linux-2.4.22-pre2/arch/arm/kernel/ptrace.h linux-2.4.22-pre3/arch/arm/kernel/ptrace.h
--- linux-2.4.22-pre2/arch/arm/kernel/ptrace.h	2000-09-18 15:15:25.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/ptrace.h	2003-07-05 18:09:36.000000000 -0700
@@ -1,14 +1,15 @@
 /*
  *  linux/arch/arm/kernel/ptrace.h
  *
- *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2000-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
 extern void __ptrace_cancel_bpt(struct task_struct *);
-extern int ptrace_set_bpt(struct task_struct *);
+extern void ptrace_set_bpt(struct task_struct *);
+extern void ptrace_break(struct task_struct *, struct pt_regs *);
 
 /*
  * Clear a breakpoint, if one exists.
diff -urN linux-2.4.22-pre2/arch/arm/kernel/semaphore.c linux-2.4.22-pre3/arch/arm/kernel/semaphore.c
--- linux-2.4.22-pre2/arch/arm/kernel/semaphore.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/semaphore.c	2003-07-05 18:09:36.000000000 -0700
@@ -177,76 +177,76 @@
  * value in some cases..
  */
 #ifdef CONFIG_CPU_26
-asm("	.align	5
-	.globl	__down_failed
-__down_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down
-	ldmfd	sp!, {r0 - r3, pc}^
-
-	.align	5
-	.globl	__down_interruptible_failed
-__down_interruptible_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down_interruptible
-	mov	ip, r0
-	ldmfd	sp!, {r0 - r3, pc}^
-
-	.align	5
-	.globl	__down_trylock_failed
-__down_trylock_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down_trylock
-	mov	ip, r0
-	ldmfd	sp!, {r0 - r3, pc}^
-
-	.align	5
-	.globl	__up_wakeup
-__up_wakeup:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__up
-	ldmfd	sp!, {r0 - r3, pc}^
+asm("	.align	5				\n\
+	.globl	__down_failed			\n\
+__down_failed:					\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down				\n\
+	ldmfd	sp!, {r0 - r3, pc}^		\n\
+						\n\
+	.align	5				\n\
+	.globl	__down_interruptible_failed	\n\
+__down_interruptible_failed:			\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down_interruptible		\n\
+	mov	ip, r0				\n\
+	ldmfd	sp!, {r0 - r3, pc}^		\n\
+
+	.align	5				\n\
+	.globl	__down_trylock_failed		\n\
+__down_trylock_failed:				\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down_trylock			\n\
+	mov	ip, r0				\n\
+	ldmfd	sp!, {r0 - r3, pc}^		\n\
+						\n\
+	.align	5				\n\
+	.globl	__up_wakeup			\n\
+__up_wakeup:					\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__up				\n\
+	ldmfd	sp!, {r0 - r3, pc}^		\n\
 	");
 
 #else
 /* 32 bit version */
-asm("	.align	5
-	.globl	__down_failed
-__down_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down
-	ldmfd	sp!, {r0 - r3, pc}
-
-	.align	5
-	.globl	__down_interruptible_failed
-__down_interruptible_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down_interruptible
-	mov	ip, r0
-	ldmfd	sp!, {r0 - r3, pc}
-
-	.align	5
-	.globl	__down_trylock_failed
-__down_trylock_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down_trylock
-	mov	ip, r0
-	ldmfd	sp!, {r0 - r3, pc}
-
-	.align	5
-	.globl	__up_wakeup
-__up_wakeup:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__up
-	ldmfd	sp!, {r0 - r3, pc}
+asm("	.align	5				\n\
+	.globl	__down_failed			\n\
+__down_failed:					\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down				\n\
+	ldmfd	sp!, {r0 - r3, pc}		\n\
+						\n\
+	.align	5				\n\
+	.globl	__down_interruptible_failed	\n\
+__down_interruptible_failed:			\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down_interruptible		\n\
+	mov	ip, r0				\n\
+	ldmfd	sp!, {r0 - r3, pc}		\n\
+						\n\
+	.align	5				\n\
+	.globl	__down_trylock_failed		\n\
+__down_trylock_failed:				\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down_trylock			\n\
+	mov	ip, r0				\n\
+	ldmfd	sp!, {r0 - r3, pc}		\n\
+						\n\
+	.align	5				\n\
+	.globl	__up_wakeup			\n\
+__up_wakeup:					\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__up				\n\
+	ldmfd	sp!, {r0 - r3, pc}		\n\
 	");
 
 #endif
diff -urN linux-2.4.22-pre2/arch/arm/kernel/setup.c linux-2.4.22-pre3/arch/arm/kernel/setup.c
--- linux-2.4.22-pre2/arch/arm/kernel/setup.c	2001-11-16 10:07:47.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/kernel/setup.c	2003-07-05 18:09:36.000000000 -0700
@@ -17,6 +17,8 @@
 #include <linux/console.h>
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 #include <linux/init.h>
 
 #include <asm/elf.h>
@@ -33,10 +35,6 @@
 #define MEM_SIZE	(16*1024*1024)
 #endif
 
-#ifndef CONFIG_CMDLINE
-#define CONFIG_CMDLINE ""
-#endif
-
 #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
 char fpe_type[8];
 
@@ -51,14 +49,14 @@
 
 extern unsigned int mem_fclk_21285;
 extern void paging_init(struct meminfo *, struct machine_desc *desc);
-extern void convert_to_tag_list(struct param_struct *params, int mem_init);
+extern void convert_to_tag_list(struct tag *tags);
+extern void squash_mem_tags(struct tag *tag);
 extern void bootmem_init(struct meminfo *);
 extern void reboot_setup(char *str);
 extern int root_mountflags;
 extern int _stext, _text, _etext, _edata, _end;
 
 unsigned int processor_id;
-unsigned int compat;
 unsigned int __machine_arch_type;
 unsigned int system_rev;
 unsigned int system_serial_low;
@@ -72,9 +70,11 @@
 unsigned char aux_device_present;
 char elf_platform[ELF_PLATFORM_SIZE];
 char saved_command_line[COMMAND_LINE_SIZE];
+unsigned long phys_initrd_start __initdata = 0;
+unsigned long phys_initrd_size __initdata = 0;
 
 static struct meminfo meminfo __initdata = { 0, };
-static struct proc_info_item proc_info;
+static const char *cpu_name;
 static const char *machine_name;
 static char command_line[COMMAND_LINE_SIZE];
 
@@ -129,15 +129,13 @@
 		while (1);
 	}
 
-	proc_info = *list->info;
+	cpu_name = list->info->cpu_name;
 
 #ifdef MULTI_CPU
 	processor = *list->proc;
 #endif
 
-	printk("Processor: %s %s revision %d\n",
-	       proc_info.manufacturer, proc_info.cpu_name,
-	       (int)processor_id & 15);
+	printk("CPU: %s revision %d\n", cpu_name, (int)processor_id & 15);
 
 	sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
 	sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
@@ -146,7 +144,7 @@
 	cpu_proc_init();
 }
 
-static struct machine_desc * __init setup_architecture(unsigned int nr)
+static struct machine_desc * __init setup_machine(unsigned int nr)
 {
 	extern struct machine_desc __arch_info_begin, __arch_info_end;
 	struct machine_desc *list;
@@ -168,12 +166,7 @@
 		while (1);
 	}
 
-	printk("Architecture: %s\n", list->name);
-	if (compat)
-		printk(KERN_WARNING "Using compatibility code "
-			"scheduled for removal in v%d.%d.%d\n",
-			compat >> 24, (compat >> 12) & 0x3ff,
-			compat & 0x3ff);
+	printk("Machine: %s\n", list->name);
 
 	return list;
 }
@@ -215,6 +208,22 @@
 			mi->bank[mi->nr_banks].size  = size;
 			mi->bank[mi->nr_banks].node  = PHYS_TO_NID(start);
 			mi->nr_banks += 1;
+		} else if (c == ' ' && !memcmp(from, "initrd=", 7)) {
+			unsigned long start, size;
+
+			/*
+			 * Remove space character
+			 */
+			if (to != command_line)
+				to -= 1;
+
+			start = memparse(from + 7, &from);
+			if (*from == ',') {
+				size = memparse(from + 1, &from);
+
+				phys_initrd_start = start;
+				phys_initrd_size = size;
+			}
 		}
 		c = *from++;
 		if (!c)
@@ -231,7 +240,7 @@
 setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
 {
 #ifdef CONFIG_BLK_DEV_RAM
-	extern int rd_size;
+	extern int rd_size, rd_image_start, rd_prompt, rd_doload;
 
 	rd_image_start = image_start;
 	rd_prompt = prompt;
@@ -250,8 +259,8 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (start == 0)
 		size = 0;
-	initrd_start = start;
-	initrd_end   = start + size;
+	phys_initrd_start = __virt_to_phys(start);
+	phys_initrd_size = size;
 #endif
 }
 
@@ -351,12 +360,12 @@
 
 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
 struct screen_info screen_info = {
- orig_video_lines:	30,
- orig_video_cols:	80,
- orig_video_mode:	0,
- orig_video_ega_bx:	0,
- orig_video_isVGA:	1,
- orig_video_points:	8
+ .orig_video_lines	= 30,
+ .orig_video_cols	= 80,
+ .orig_video_mode	= 0,
+ .orig_video_ega_bx	= 0,
+ .orig_video_isVGA	= 1,
+ .orig_video_points	= 8
 };
 
 static int __init parse_tag_videotext(const struct tag *tag)
@@ -388,12 +397,22 @@
 
 static int __init parse_tag_initrd(const struct tag *tag)
 {
-	setup_initrd(tag->u.initrd.start, tag->u.initrd.size);
+	phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
+	phys_initrd_size = tag->u.initrd.size;
 	return 0;
 }
 
 __tagtable(ATAG_INITRD, parse_tag_initrd);
 
+static int __init parse_tag_initrd2(const struct tag *tag)
+{
+	phys_initrd_start = tag->u.initrd.start;
+	phys_initrd_size = tag->u.initrd.size;
+	return 0;
+}
+
+__tagtable(ATAG_INITRD2, parse_tag_initrd2);
+
 static int __init parse_tag_serialnr(const struct tag *tag)
 {
 	system_serial_low = tag->u.serialnr.low;
@@ -452,16 +471,30 @@
 				t->hdr.tag);
 }
 
+static struct init_tags {
+	struct tag_header hdr1;
+	struct tag_core   core;
+	struct tag_header hdr2;
+	struct tag_mem32  mem;
+	struct tag_header hdr3;
+} init_tags __initdata = {
+	{ tag_size(tag_core), ATAG_CORE },
+	{ 1, PAGE_SIZE, 0xff },
+	{ tag_size(tag_mem32), ATAG_MEM },
+	{ MEM_SIZE, PHYS_OFFSET },
+	{ 0, ATAG_NONE }
+};
+
 void __init setup_arch(char **cmdline_p)
 {
-	struct tag *tags = NULL;
+	struct tag *tags = (struct tag *)&init_tags;
 	struct machine_desc *mdesc;
 	char *from = default_command_line;
 
 	ROOT_DEV = MKDEV(0, 255);
 
 	setup_processor();
-	mdesc = setup_architecture(machine_arch_type);
+	mdesc = setup_machine(machine_arch_type);
 	machine_name = mdesc->name;
 
 	if (mdesc->soft_reboot)
@@ -480,14 +513,16 @@
 
 	/*
 	 * If we have the old style parameters, convert them to
-	 * a tag list before.
+	 * a tag list.
 	 */
-	if (tags && tags->hdr.tag != ATAG_CORE)
-		convert_to_tag_list((struct param_struct *)tags,
-				    meminfo.nr_banks == 0);
+	if (tags->hdr.tag != ATAG_CORE)
+		convert_to_tag_list(tags);
 
-	if (tags && tags->hdr.tag == ATAG_CORE)
+	if (tags->hdr.tag == ATAG_CORE) {
+		if (meminfo.nr_banks != 0)
+			squash_mem_tags(tags);
 		parse_tags(tags);
+	}
 
 	if (meminfo.nr_banks == 0) {
 		meminfo.nr_banks      = 1;
@@ -537,9 +572,8 @@
 {
 	int i;
 
-	seq_printf(m, "Processor\t: %s %s rev %d (%s)\n",
-		   proc_info.manufacturer, proc_info.cpu_name,
-		   (int)processor_id & 15, elf_platform);
+	seq_printf(m, "Processor\t: %s rev %d (%s)\n",
+		   cpu_name, (int)processor_id & 15, elf_platform);
 
 	seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
 		   loops_per_jiffy / (500000/HZ),
@@ -578,8 +612,8 @@
 }
 
 struct seq_operations cpuinfo_op = {
-	start:	c_start,
-	next:	c_next,
-	stop:	c_stop,
-	show:	c_show
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= c_show
 };
diff -urN linux-2.4.22-pre2/arch/arm/kernel/signal.c linux-2.4.22-pre3/arch/arm/kernel/signal.c
--- linux-2.4.22-pre2/arch/arm/kernel/signal.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/signal.c	2003-07-05 18:09:36.000000000 -0700
@@ -405,7 +405,7 @@
 	regs->ARM_r0 = usig;
 	regs->ARM_sp = (unsigned long)frame;
 	regs->ARM_lr = retcode;
-	regs->ARM_pc = handler & (thumb ? ~1 : ~3);
+	regs->ARM_pc = handler;
 
 #ifdef CONFIG_CPU_32
 	regs->ARM_cpsr = cpsr;
@@ -466,8 +466,8 @@
 		 * arguments for the signal handler.
 		 *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
 		 */
-		regs->ARM_r1 = (unsigned long)frame->pinfo;
-		regs->ARM_r2 = (unsigned long)frame->puc;
+		regs->ARM_r1 = (unsigned long)&frame->info;
+		regs->ARM_r2 = (unsigned long)&frame->uc;
 	}
 
 	return err;
@@ -613,7 +613,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:
@@ -621,13 +621,17 @@
 					continue;
 				/* FALLTHRU */
 
-			case SIGSTOP:
+			case SIGSTOP: {
+				struct signal_struct *sig;
 				current->state = TASK_STOPPED;
 				current->exit_code = signr;
-				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+				sig = current->p_pptr->sig;
+				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
+				single_stepping |= ptrace_cancel_bpt(current);
 				continue;
+			}
 
 			case SIGQUIT: case SIGILL: case SIGTRAP:
 			case SIGABRT: case SIGFPE: case SIGSEGV:
diff -urN linux-2.4.22-pre2/arch/arm/kernel/time.c linux-2.4.22-pre3/arch/arm/kernel/time.c
--- linux-2.4.22-pre2/arch/arm/kernel/time.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/time.c	2003-07-05 18:09:36.000000000 -0700
@@ -203,6 +203,7 @@
 
 static struct irqaction timer_irq = {
 	.name	= "timer",
+	.flags	= SA_INTERRUPT,
 };
 
 /*
diff -urN linux-2.4.22-pre2/arch/arm/kernel/traps.c linux-2.4.22-pre3/arch/arm/kernel/traps.c
--- linux-2.4.22-pre2/arch/arm/kernel/traps.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/kernel/traps.c	2003-07-05 18:09:36.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/kernel/traps.c
  *
- *  Copyright (C) 1995, 1996 Russell King
+ *  Copyright (C) 1995-2002 Russell King
  *  Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
  *
  * This program is free software; you can redistribute it and/or modify
@@ -63,8 +63,17 @@
 static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
 {
 	unsigned long p = bottom & ~31;
+	mm_segment_t fs;
 	int i;
 
+	/*
+	 * We need to switch to kernel mode so that we can use __get_user
+	 * to safely read from kernel space.  Note that we now dump the
+	 * code first, just in case the backtrace kills us.
+	 */
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+
 	printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
 
 	for (p = bottom & ~31; p < top;) {
@@ -82,6 +91,8 @@
 		}
 		printk ("\n");
 	}
+
+	set_fs(fs);
 }
 
 static void dump_instr(struct pt_regs *regs)
@@ -89,8 +100,17 @@
 	unsigned long addr = instruction_pointer(regs);
 	const int thumb = thumb_mode(regs);
 	const int width = thumb ? 4 : 8;
+	mm_segment_t fs;
 	int i;
 
+	/*
+	 * We need to switch to kernel mode so that we can use __get_user
+	 * to safely read from kernel space.  Note that we now dump the
+	 * code first, just in case the backtrace kills us.
+	 */
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+
 	printk("Code: ");
 	for (i = -4; i < 1; i++) {
 		unsigned int val, bad;
@@ -108,29 +128,36 @@
 		}
 	}
 	printk("\n");
+
+	set_fs(fs);
 }
 
-static void dump_stack(struct task_struct *tsk, unsigned long sp)
+static void I_really_mean_dump_stack_so_dont_mess_with_me(struct task_struct *tsk, unsigned long sp)
 {
-	dump_mem("Stack: ", sp - 16, 8192+(unsigned long)tsk);
+	dump_mem("Stack: ", sp, 8192+(unsigned long)tsk);
 }
 
 static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
 {
-	unsigned int fp;
+	unsigned int fp = regs->ARM_fp;
+	char *msg = "";
 	int ok = 1;
 
-	printk("Backtrace: ");
-	fp = regs->ARM_fp;
+#ifdef CONFIG_FRAME_POINTER
 	if (!fp) {
-		printk("no frame pointer");
+		msg = "no frame pointer";
 		ok = 0;
 	} else if (verify_stack(fp)) {
-		printk("invalid frame pointer 0x%08x", fp);
+		msg = "invalid frame pointer";
 		ok = 0;
 	} else if (fp < 4096+(unsigned long)tsk)
-		printk("frame pointer underflow");
-	printk("\n");
+		msg = "frame pointer underflow";
+#else
+	msg = "not available";
+	ok = 0;
+#endif
+
+	printk("Backtrace: %s\n", msg);
 
 	if (ok)
 		c_backtrace(fp, processor_mode(regs));
@@ -143,7 +170,7 @@
 void show_trace_task(struct task_struct *tsk)
 {
 	if (tsk != current) {
-		unsigned int fp = tsk->thread.save->fp;
+		unsigned int fp = thread_saved_fp(&tsk->thread);
 		c_backtrace(fp, 0x10);
 	}
 }
@@ -163,26 +190,13 @@
 	printk("Internal error: %s: %x\n", str, err);
 	printk("CPU: %d\n", smp_processor_id());
 	show_regs(regs);
-	printk("Process %s (pid: %d, stackpage=%08lx)\n",
-		current->comm, current->pid, 4096+(unsigned long)tsk);
+	printk("Process %s (pid: %d, stack limit = 0x%p)\n",
+		current->comm, current->pid, tsk + 1);
 
 	if (!user_mode(regs) || in_interrupt()) {
-		mm_segment_t fs;
-
-		/*
-		 * We need to switch to kernel mode so that we can
-		 * use __get_user to safely read from kernel space.
-		 * Note that we now dump the code first, just in case
-		 * the backtrace kills us.
-		 */
-		fs = get_fs();
-		set_fs(KERNEL_DS);
-
-		dump_stack(tsk, (unsigned long)(regs + 1));
+		I_really_mean_dump_stack_so_dont_mess_with_me(tsk, (unsigned long)(regs + 1));
 		dump_backtrace(regs, tsk);
 		dump_instr(regs);
-
-		set_fs(fs);
 	}
 
 	spin_unlock_irq(&die_lock);
@@ -270,7 +284,6 @@
 asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
 {
 	unsigned int vectors = vectors_base();
-	mm_segment_t fs;
 
 	console_verbose();
 
@@ -278,24 +291,14 @@
 		handler[reason], processor_modes[proc_mode]);
 
 	/*
-	 * We need to switch to kernel mode so that we can use __get_user
-	 * to safely read from kernel space.  Note that we now dump the
-	 * code first, just in case the backtrace kills us.
-	 */
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-
-	/*
 	 * Dump out the vectors and stub routines.  Maybe a better solution
 	 * would be to dump them out only if we detect that they are corrupted.
 	 */
 	dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40);
 	dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8);
 
-	set_fs(fs);
-
 	die("Oops", regs, 0);
-	cli();
+	local_irq_disable();
 	panic("bad mode");
 }
 
@@ -356,20 +359,7 @@
 		return 0;
 
 	case NR(breakpoint): /* SWI BREAK_POINT */
-		/*
-		 * The PC is always left pointing at the next
-		 * instruction.  Fix this.
-		 */
-		regs->ARM_pc -= 4;
-		__ptrace_cancel_bpt(current);
-
-		info.si_signo = SIGTRAP;
-		info.si_errno = 0;
-		info.si_code  = TRAP_BRKPT;
-		info.si_addr  = (void *)instruction_pointer(regs) -
-				 (thumb_mode(regs) ? 2 : 4);
-
-		force_sig_info(SIGTRAP, &info, current);
+		ptrace_break(current, regs);
 		return regs->ARM_r0;
 
 #ifdef CONFIG_CPU_32
@@ -522,12 +512,13 @@
 
 void __init trap_init(void)
 {
-	extern void __trap_init(void *);
+	extern void __trap_init(unsigned long);
+	unsigned long base = vectors_base();
 
-	__trap_init((void *)vectors_base());
-	if (vectors_base() != 0)
-		printk(KERN_DEBUG "Relocating machine vectors to 0x%08x\n",
-			vectors_base());
+	__trap_init(base);
+	if (base != 0)
+		printk(KERN_DEBUG "Relocating machine vectors to 0x%08lx\n",
+			base);
 #ifdef CONFIG_CPU_32
 	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
 #endif
diff -urN linux-2.4.22-pre2/arch/arm/lib/Makefile linux-2.4.22-pre3/arch/arm/lib/Makefile
--- linux-2.4.22-pre2/arch/arm/lib/Makefile	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/lib/Makefile	2003-07-05 18:09:36.000000000 -0700
@@ -27,15 +27,16 @@
 obj-l7200     	:= io-acorn.o
 obj-shark	:= io-shark.o
 obj-edb7211	:= io-acorn.o
+obj-riscstation := io-acorn.o floppydma.o
 
 obj-y		+= $(obj-$(MACHINE))
 
-ifeq ($(CONFIG_CPU_32v4),y)
-  v3		:= n
-  v4		:= y
-else
+ifeq ($(CONFIG_CPU_32v3),y)
   v3		:= y
   v4		:= n
+else
+  v3		:= n
+  v4		:= y
 endif
 
 obj-y		+= io-readsb.o io-writesb.o
@@ -51,4 +52,3 @@
 
 csumpartialcopy.o: csumpartialcopygeneric.S
 csumpartialcopyuser.o: csumpartialcopygeneric.S
-
diff -urN linux-2.4.22-pre2/arch/arm/lib/backtrace.S linux-2.4.22-pre3/arch/arm/lib/backtrace.S
--- linux-2.4.22-pre2/arch/arm/lib/backtrace.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/lib/backtrace.S	2003-07-05 18:09:36.000000000 -0700
@@ -52,25 +52,32 @@
 3:		tst	frame, mask		@ Check for address exceptions...
 		bne	1b
 
-1001:		ldmda	frame, {r0, r1, r2, r3}	@ fp, sp, lr, pc
-		mov	next, r0
-
+1001:		ldr	next, [frame, #-12]	@ get fp
+1002:		ldr	r2, [frame, #-4]	@ get lr
+1003:		ldr	r3, [frame, #0]		@ get pc
 		sub	save, r3, offset	@ Correct PC for prefetching
 		bic	save, save, mask
+1004:		ldr	r1, [save, #0]		@ get instruction at function
+		mov	r1, r1, lsr #10
+		ldr	r3, .Ldsi+4
+		teq	r1, r3
+		subeq	save, save, #4
 		adr	r0, .Lfe
 		mov	r1, save
 		bic	r2, r2, mask
-		bl	SYMBOL_NAME(printk)	@ print pc and link register
+		bl	printk			@ print pc and link register
 
-		sub	r0, frame, #16
-1002:		ldr	r1, [save, #4]		@ get instruction at function+4
+		ldr	r0, [frame, #-8]	@ get sp
+		sub	r0, r0, #4
+1005:		ldr	r1, [save, #4]		@ get instruction at function+4
 		mov	r3, r1, lsr #10
 		ldr	r2, .Ldsi+4
 		teq	r3, r2			@ Check for stmia sp!, {args}
 		addeq	save, save, #4		@ next instruction
 		bleq	.Ldumpstm
 
-1003:		ldr	r1, [save, #4]		@ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
+		sub	r0, frame, #16
+1006:		ldr	r1, [save, #4]		@ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
 		mov	r3, r1, lsr #10
 		ldr	r2, .Ldsi
 		teq	r3, r2
@@ -87,18 +94,21 @@
  */
 		.section .fixup,"ax"
 		.align	0
-1004:		ldr	r0, =.Lbad
+1007:		ldr	r0, =.Lbad
 		mov	r1, frame
-		bl	SYMBOL_NAME(printk)
+		bl	printk
 		LOADREGS(fd, sp!, {r4 - r8, pc})
 		.ltorg
 		.previous
 		
 		.section __ex_table,"a"
 		.align	3
-		.long	1001b, 1004b
-		.long	1002b, 1004b
-		.long	1003b, 1004b
+		.long	1001b, 1007b
+		.long	1002b, 1007b
+		.long	1003b, 1007b
+		.long	1004b, 1007b
+		.long	1005b, 1007b
+		.long	1006b, 1007b
 		.previous
 
 #define instr r4
@@ -121,12 +131,12 @@
 		ldr	r2, [stack], #-4
 		mov	r1, reg
 		adr	r0, .Lfp
-		bl	SYMBOL_NAME(printk)
+		bl	printk
 2:		subs	reg, reg, #1
 		bpl	1b
 		teq	r7, #0
 		adrne	r0, .Lcr
-		blne	SYMBOL_NAME(printk)
+		blne	printk
 		mov	r0, stack
 		LOADREGS(fd, sp!, {instr, reg, stack, r7, pc})
 
diff -urN linux-2.4.22-pre2/arch/arm/lib/csumpartial.S linux-2.4.22-pre3/arch/arm/lib/csumpartial.S
--- linux-2.4.22-pre2/arch/arm/lib/csumpartial.S	2001-05-16 15:25:16.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/lib/csumpartial.S	2003-07-05 18:09:36.000000000 -0700
@@ -49,8 +49,9 @@
 		/* we are now half-word aligned */
 
 .less8_wordlp:
-#ifdef __ARM_ARCH_4__
-		ldrh	td0, [buf], #2
+#if __LINUX_ARM_ARCH__ >= 4
+		ldrh	td0, [buf]
+		add	buf, buf, #2
 		sub	len, len, #2
 #else
 		ldrb	td0, [buf], #1
@@ -79,8 +80,9 @@
 		adcnes	sum, sum, td0, lsl #8	@ update checksum
 
 		tst	buf, #2			@ 32-bit aligned?
-#ifdef __ARM_ARCH_4__
-		ldrneh	td0, [buf], #2		@ make 32-bit aligned
+#if __LINUX_ARM_ARCH__ >= 4
+		ldrneh	td0, [buf]		@ make 32-bit aligned
+		add	buf, buf, #2
 		subne	len, len, #2
 #else
 		ldrneb	td0, [buf], #1
diff -urN linux-2.4.22-pre2/arch/arm/lib/delay.S linux-2.4.22-pre3/arch/arm/lib/delay.S
--- linux-2.4.22-pre2/arch/arm/lib/delay.S	2001-04-12 12:20:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/lib/delay.S	2003-07-05 18:09:36.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/lib/delay.S
  *
- *  Copyright (C) 1995, 1996 Russell King
+ *  Copyright (C) 1995-2003 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -9,45 +9,52 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-		.text
+#include <asm/delay.h>
 
-LC0:		.word	SYMBOL_NAME(loops_per_jiffy)
+		.text
 
 /*
- * 0 <= r0 <= 2000
+ * See linux/include/asm-arm/delay.h for a description of the maths.
  */
-ENTRY(udelay)
-		mov	r2,     #0x6800
-		orr	r2, r2, #0x00db
+
+#if NDELAY_FACTOR > 255
+#error NDELAY_FACTOR out of range
+#endif
+#if UDELAY_FACTOR > 65535
+#error UDELAY_FACTOR out of range
+#endif
+
+LC0:		.word	SYMBOL_NAME(loops_per_jiffy)
+
+ENTRY(__const_delay)
+		ldr	r3, LC0
+		mov	r1, r0, lsr #11
+		ldr	r2, [r3, #0]
+		b	2f
+
+ENTRY(__ndelay)
+		mov	r2, #NDELAY_FACTOR
+		b	1f
+
+ENTRY(__udelay)
+		mov	r2,     #UDELAY_FACTOR & 0xff00
+		orr	r2, r2, #UDELAY_FACTOR & 0x00ff
+1:		ldr	r3, LC0
 		mul	r1, r0, r2
-		ldr	r2, LC0
-		ldr	r2, [r2]
+		ldr	r2, [r3, #0]
 		mov	r1, r1, lsr #11
-		mov	r2, r2, lsr #11
+2:		mov	r2, r2, lsr #12
 		mul	r0, r1, r2
-		movs	r0, r0, lsr #6
+		movs	r0, r0, lsr #5
 		RETINSTR(moveq,pc,lr)
 
 /*
- * loops = (r0 * 0x10c6 * 100 * loops_per_jiffie) / 2^32
+ * loops = (r0 * 0x10c6 * HZ * loops_per_jiffy) / 2^32
+ *
+ * Oh, if only we had a cycle counter...
  */
 
-@ Delay routine
 ENTRY(__delay)
 		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
 		bcs	SYMBOL_NAME(__delay)
 		RETINSTR(mov,pc,lr)
diff -urN linux-2.4.22-pre2/arch/arm/lib/longlong.h linux-2.4.22-pre3/arch/arm/lib/longlong.h
--- linux-2.4.22-pre2/arch/arm/lib/longlong.h	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/lib/longlong.h	2003-07-05 18:09:36.000000000 -0700
@@ -75,7 +75,7 @@
 
 #if defined (__arm__)
 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
-  __asm__ ("adds	%1, %4, %5
+  __asm__ ("adds	%1, %4, %5					\n\
 	adc	%0, %2, %3"						\
 	   : "=r" ((USItype) (sh)),					\
 	     "=&r" ((USItype) (sl))					\
@@ -84,7 +84,7 @@
 	     "%r" ((USItype) (al)),					\
 	     "rI" ((USItype) (bl)))
 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
-  __asm__ ("subs	%1, %4, %5
+  __asm__ ("subs	%1, %4, %5					\n\
 	sbc	%0, %2, %3"						\
 	   : "=r" ((USItype) (sh)),					\
 	     "=&r" ((USItype) (sl))					\
@@ -94,18 +94,18 @@
 	     "rI" ((USItype) (bl)))
 #define umul_ppmm(xh, xl, a, b) \
 {register USItype __t0, __t1, __t2;					\
-  __asm__ ("%@ Inlined umul_ppmm
-	mov	%2, %5, lsr #16
-	mov	%0, %6, lsr #16
-	bic	%3, %5, %2, lsl #16
-	bic	%4, %6, %0, lsl #16
-	mul	%1, %3, %4
-	mul	%4, %2, %4
-	mul	%3, %0, %3
-	mul	%0, %2, %0
-	adds	%3, %4, %3
-	addcs	%0, %0, #65536
-	adds	%1, %1, %3, lsl #16
+  __asm__ ("%@ Inlined umul_ppmm					\n\
+	mov	%2, %5, lsr #16						\n\
+	mov	%0, %6, lsr #16						\n\
+	bic	%3, %5, %2, lsl #16					\n\
+	bic	%4, %6, %0, lsl #16					\n\
+	mul	%1, %3, %4						\n\
+	mul	%4, %2, %4						\n\
+	mul	%3, %0, %3						\n\
+	mul	%0, %2, %0						\n\
+	adds	%3, %4, %3						\n\
+	addcs	%0, %0, #65536						\n\
+	adds	%1, %1, %3, lsl #16					\n\
 	adc	%0, %0, %3, lsr #16"					\
 	   : "=&r" ((USItype) (xh)),					\
 	     "=r" ((USItype) (xl)),					\
diff -urN linux-2.4.22-pre2/arch/arm/lib/memchr.S linux-2.4.22-pre3/arch/arm/lib/memchr.S
--- linux-2.4.22-pre2/arch/arm/lib/memchr.S	2000-09-18 15:15:25.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/lib/memchr.S	2003-07-05 18:09:36.000000000 -0700
@@ -15,11 +15,11 @@
 	.text
 	.align	5
 ENTRY(memchr)
-1:	ldrb	r3, [r0], #1
+1:	subs	r2, r2, #1
+	bmi	2f
+	ldrb	r3, [r0], #1
 	teq	r3, r1
-	beq	2f
-	subs	r2, r2, #1
-	bpl	1b
+	bne	1b
+	sub	r0, r0, #1
 2:	movne	r0, #0
-	subeq	r0, r0, #1
 	RETINSTR(mov,pc,lr)
diff -urN linux-2.4.22-pre2/arch/arm/lib/muldi3.c linux-2.4.22-pre3/arch/arm/lib/muldi3.c
--- linux-2.4.22-pre2/arch/arm/lib/muldi3.c	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/lib/muldi3.c	2003-07-05 18:09:36.000000000 -0700
@@ -33,18 +33,18 @@
 
 #define umul_ppmm(xh, xl, a, b) \
 {register USItype __t0, __t1, __t2;                                     \
-  __asm__ ("%@ Inlined umul_ppmm
-        mov     %2, %5, lsr #16
-        mov     %0, %6, lsr #16
-        bic     %3, %5, %2, lsl #16
-        bic     %4, %6, %0, lsl #16
-        mul     %1, %3, %4
-        mul     %4, %2, %4
-        mul     %3, %0, %3
-        mul     %0, %2, %0
-        adds    %3, %4, %3
-        addcs   %0, %0, #65536
-        adds    %1, %1, %3, lsl #16
+  __asm__ ("%@ Inlined umul_ppmm					\n\
+        mov     %2, %5, lsr #16						\n\
+        mov     %0, %6, lsr #16						\n\
+        bic     %3, %5, %2, lsl #16					\n\
+        bic     %4, %6, %0, lsl #16					\n\
+        mul     %1, %3, %4						\n\
+        mul     %4, %2, %4						\n\
+        mul     %3, %0, %3						\n\
+        mul     %0, %2, %0						\n\
+        adds    %3, %4, %3						\n\
+        addcs   %0, %0, #65536						\n\
+        adds    %1, %1, %3, lsl #16					\n\
         adc     %0, %0, %3, lsr #16"                                    \
            : "=&r" ((USItype) (xh)),                                    \
              "=r" ((USItype) (xl)),                                     \
diff -urN linux-2.4.22-pre2/arch/arm/lib/strchr.S linux-2.4.22-pre3/arch/arm/lib/strchr.S
--- linux-2.4.22-pre2/arch/arm/lib/strchr.S	2000-09-18 15:15:25.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/lib/strchr.S	2003-07-05 18:09:36.000000000 -0700
@@ -15,11 +15,12 @@
 		.text
 		.align	5
 ENTRY(strchr)
+		and	r1, r1, #0xff
 1:		ldrb	r2, [r0], #1
 		teq	r2, r1
 		teqne	r2, #0
 		bne	1b
-		teq	r2, #0
-		moveq	r0, #0
-		subne	r0, r0, #1
+		teq	r2, r1
+		movne	r0, #0
+		subeq	r0, r0, #1
 		RETINSTR(mov,pc,lr)
diff -urN linux-2.4.22-pre2/arch/arm/lib/udivdi3.c linux-2.4.22-pre3/arch/arm/lib/udivdi3.c
--- linux-2.4.22-pre2/arch/arm/lib/udivdi3.c	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/lib/udivdi3.c	2003-07-05 18:09:36.000000000 -0700
@@ -229,3 +229,14 @@
 {
   return __udivmoddi4 (n, d, (UDItype *) 0);
 }
+
+UDItype
+__umoddi3 (UDItype u, UDItype v)
+{
+  UDItype w;
+
+  (void) __udivmoddi4 (u ,v, &w);
+
+  return w;
+}
+
diff -urN linux-2.4.22-pre2/arch/arm/mach-anakin/irq.c linux-2.4.22-pre3/arch/arm/mach-anakin/irq.c
--- linux-2.4.22-pre2/arch/arm/mach-anakin/irq.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-anakin/irq.c	2003-07-05 18:09:36.000000000 -0700
@@ -15,6 +15,8 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
diff -urN linux-2.4.22-pre2/arch/arm/mach-at91rm9200/Makefile linux-2.4.22-pre3/arch/arm/mach-at91rm9200/Makefile
--- linux-2.4.22-pre2/arch/arm/mach-at91rm9200/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-at91rm9200/Makefile	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= at91rm9200.o
+
+# Object file lists.
+
+obj-y			:= core.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:=
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/arm/mach-at91rm9200/core.c linux-2.4.22-pre3/arch/arm/mach-at91rm9200/core.c
--- linux-2.4.22-pre2/arch/arm/mach-at91rm9200/core.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-at91rm9200/core.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,183 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/core.c
+ *
+ *  Copyright (c) 2003 SAN People
+ *  Copyright (c) 2003 ATMEL
+ *  Copyright (c) Rick Bronson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/hardware.h>
+
+/*
+ * System peripheral registers mapped at virtual address.
+ */
+AT91PS_SYS AT91_SYS = (AT91PS_SYS) AT91C_VA_BASE_SYS;
+
+static struct map_desc at91rm9200_io_desc[] __initdata = {
+	/* virtual,             physical,          length,   domain,    r, w, c, b */
+	{ AT91C_VA_BASE_SYS,    AT91C_BASE_SYS,    SZ_4K,    DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_SPI,    AT91C_BASE_SPI,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_SSC2,   AT91C_BASE_SSC2,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_SSC1,   AT91C_BASE_SSC1,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_SSC0,   AT91C_BASE_SSC0,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_US3,    AT91C_BASE_US3,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_US2,    AT91C_BASE_US2,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_US1,    AT91C_BASE_US1,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_US0,    AT91C_BASE_US0,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_EMAC,   AT91C_BASE_EMAC,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_TWI,    AT91C_BASE_TWI,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_MCI,    AT91C_BASE_MCI,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_UDP,    AT91C_BASE_UDP,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_TCB1,   AT91C_BASE_TCB1,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_TCB0,   AT91C_BASE_TCB0,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	LAST_DESC
+};
+
+/* Interrupt configuration */
+static AT91_REG at91rm9200_irq_smr[] __initdata = {
+	(AT91_SMR_FIQ),		/* FIQ */
+	(AT91_SMR_SYS),		/* System Peripherals */
+	(AT91_SMR_PIOA),	/* PIO A */
+	(AT91_SMR_PIOB),	/* PIO B */
+	(AT91_SMR_PIOC),	/* PIO C */
+	(AT91_SMR_PIOD),	/* PIO D */
+	(AT91_SMR_US0),		/* USART 0 */
+	(AT91_SMR_US1),		/* USART 1 */
+	(AT91_SMR_US2),		/* USART 2 */
+	(AT91_SMR_US3),		/* USART 3 */
+	(AT91_SMR_MCI),		/* Multimedia Card */
+	(AT91_SMR_UDP),		/* USB Device */
+	(AT91_SMR_TWI),		/* Two-wire interface */
+	(AT91_SMR_SPI),		/* SPI */
+	(AT91_SMR_SSC0),	/* Sync Serial 0 */
+	(AT91_SMR_SSC1),	/* Sync Serial 1 */
+	(AT91_SMR_SSC2),	/* Sync Serial 2 */
+	(AT91_SMR_TC0),		/* TC 0 */
+	(AT91_SMR_TC1),		/* TC 1 */
+	(AT91_SMR_TC2),		/* TC 2 */
+	(AT91_SMR_TC3),		/* TC 3 */
+	(AT91_SMR_TC4),		/* TC 4 */
+	(AT91_SMR_TC5),		/* TC 5 */
+	(AT91_SMR_UHP),		/* USB Host */
+	(AT91_SMR_EMAC),	/* Ethernet */
+	(AT91_SMR_IRQ0),	/* IRQ 0 */
+	(AT91_SMR_IRQ1),	/* IRQ 1 */
+	(AT91_SMR_IRQ2),	/* IRQ 2 */
+	(AT91_SMR_IRQ3),	/* IRQ 3 */
+	(AT91_SMR_IRQ4),	/* IRQ 4 */
+	(AT91_SMR_IRQ5),	/* IRQ 5 */
+	(AT91_SMR_IRQ6)		/* IRQ 6 */
+};
+
+/* Architecture-specific fixups */
+static void __init at91rm9200_fixup(struct machine_desc *desc, struct param_struct *unused,
+		 char **cmdline, struct meminfo *mi)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	setup_ramdisk(1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
+//	setup_initrd(0xc0100000, 3*1024*1024);
+#endif
+}
+
+extern void at91_register_uart(int idx, int port);
+
+void __init at91rm9200_map_io(void)
+{
+	int serial[AT91C_NR_UART] = AT91C_UART_MAP;
+	int i;
+
+	iotable_init(at91rm9200_io_desc);
+
+	/* Register UARTs */
+	for (i = 0; i < AT91C_NR_UART; i++) {
+		if (serial[i] >= 0)
+			at91_register_uart(i, serial[i]);
+	}
+}
+
+static void at91rm9200_mask_irq(unsigned int irq)
+{
+	/* Disable interrupt on AIC */
+	AT91_SYS->AIC_IDCR =  1 << irq;
+}
+
+static void at91rm9200_unmask_irq(unsigned int irq)
+{
+	/* Enable interrupt on AIC */
+	AT91_SYS->AIC_IECR =  1 << irq;
+}
+
+void __init at91rm9200_init_irq(void)
+{
+	unsigned int i;
+
+	/*
+	 * The IVR is used by macro get_irqnr_and_base to read and verify.
+	 * The irq number is NR_IRQS when a spurious interrupt has occured.
+	 */
+	for (i = 0; i < NR_IRQS; i++) {
+		/* Put irq number in Source Vector Register: */
+		AT91_SYS->AIC_SVR[i] = i;
+		/* Store the Source Mode Register as defined in table above */
+		AT91_SYS->AIC_SMR[i] = at91rm9200_irq_smr[i];
+
+		irq_desc[i].valid	= 1;
+		irq_desc[i].mask_ack	= at91rm9200_mask_irq;
+		irq_desc[i].mask	= at91rm9200_mask_irq;
+		irq_desc[i].unmask	= at91rm9200_unmask_irq;
+
+		/* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
+		if (i < 8)
+			AT91_SYS->AIC_EOICR = AT91_SYS->AIC_EOICR;
+	}
+
+	/* Spurious Interrupt ID in Spurious Vector Register is NR_IRQS
+	 * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU
+	 */
+	AT91_SYS->AIC_SPU = NR_IRQS;
+
+	/* No debugging in AIC: Debug (Protect) Control Register */
+	AT91_SYS->AIC_DCR = 0;
+
+	/* Disable and clear all interrupts initially */
+	AT91_SYS->AIC_IDCR = 0xFFFFFFFF;
+	AT91_SYS->AIC_ICCR = 0xFFFFFFFF;
+}
+
+MACHINE_START(AT91RM9200, "ATMEL AT91RM9200")
+	MAINTAINER("SAN People / ATMEL")
+	BOOT_MEM(AT91_SDRAM_BASE, AT91C_BASE_SYS, AT91C_VA_BASE_SYS)
+	BOOT_PARAMS(AT91_SDRAM_BASE + 0x100)
+	FIXUP(at91rm9200_fixup)
+	MAPIO(at91rm9200_map_io)
+	INITIRQ(at91rm9200_init_irq)
+MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-clps711x/Makefile linux-2.4.22-pre3/arch/arm/mach-clps711x/Makefile
--- linux-2.4.22-pre2/arch/arm/mach-clps711x/Makefile	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-clps711x/Makefile	2003-07-05 18:09:36.000000000 -0700
@@ -16,12 +16,13 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= leds-p720t.o
+export-objs		:= p720t-leds.o
 
 obj-$(CONFIG_ARCH_AUTCPU12) += autcpu12.o
 obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o
 obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
 obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o
+obj-$(CONFIG_ARCH_GUIDEA07) += guide-a07.o
 obj-$(CONFIG_ARCH_P720T) += p720t.o
 obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
 leds-$(CONFIG_ARCH_P720T) += p720t-leds.o
diff -urN linux-2.4.22-pre2/arch/arm/mach-clps711x/fortunet.c linux-2.4.22-pre3/arch/arm/mach-clps711x/fortunet.c
--- linux-2.4.22-pre2/arch/arm/mach-clps711x/fortunet.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-clps711x/fortunet.c	2003-07-05 18:09:36.000000000 -0700
@@ -31,6 +31,10 @@
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/amba_kmi.h>
 
@@ -48,9 +52,11 @@
 	int	extra_param_type;
 	int	extra_param_ptr;
 	int	command_line;
+	int	extra_ram_start;
+	int	extra_ram_size;
 } IMAGE_PARAMS;
 
-#define IMAGE_PARAMS_PHYS	0xC01F0000
+#define IMAGE_PARAMS_PHYS	0xC0200000
 
 static void __init
 fortunet_fixup(struct machine_desc *desc, struct param_struct *params,
@@ -67,14 +73,23 @@
 	}
 #endif
 	memmap.bank[0].size = ip->ram_size;
+	memmap.bank[0].node = PHYS_TO_NID(0xC0000000);
+	if(ip->extra_ram_size)
+	{
+		memmap.bank[1].start = ip->extra_ram_start;
+		memmap.bank[1].size = ip->extra_ram_size;
+		memmap.bank[1].node = PHYS_TO_NID(ip->extra_ram_start);
+		mi->nr_banks=2;
+	}
 	memmap.end = ip->ram_size+0xC0000000;
 	*mi = memmap;
 }
 
 MACHINE_START(FORTUNET, "ARM-FortuNet")
 	MAINTAINER("FortuNet Inc.")
-        BOOT_MEM(0xc0000000, 0x80000000, 0xf0000000)
+        BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
 	BOOT_PARAMS(0x00000000)
+	VIDEO(0xC0000000,0xC00020000)
 	FIXUP(fortunet_fixup)
 	MAPIO(clps711x_map_io)
 	INITIRQ(clps711x_init_irq)
diff -urN linux-2.4.22-pre2/arch/arm/mach-clps711x/guide-a07.c linux-2.4.22-pre3/arch/arm/mach-clps711x/guide-a07.c
--- linux-2.4.22-pre2/arch/arm/mach-clps711x/guide-a07.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-clps711x/guide-a07.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,92 @@
+/*
+ *  linux/arch/arm/mach-clps711x/guide-a07.c
+ *
+ *  Copyright (C) 2003 Iders Incorporated
+ *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/config.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+extern void clps711x_init_irq(void);
+extern void clps711x_map_io(void);
+
+#ifndef CONFIG_I2C_GUIDE
+#error Config error - The Guide A07 requires I2C Guide GPIO support. Please enable it.
+#endif
+
+/*
+ * Map the CS89712 Ethernet port.  That should be moved to the
+ * ethernet driver, perhaps.
+ * also map the Guide FPGA and persistance locations
+ */
+static struct map_desc guide_a07_io_desc[] __initdata = {
+	{              ETHER_BASE,              ETHER_START,              ETHER_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0 },
+	{        GD_A07_FPGA_BASE,        GD_A07_FPGA_START,        GD_A07_FPGA_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0 },
+	{ GD_A07_PERSISTANCE_BASE, GD_A07_PERSISTANCE_START, GD_A07_PERSISTANCE_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0 },
+	LAST_DESC
+};
+
+static void __init
+fixup_guide_a07(struct machine_desc *desc, struct param_struct *params,
+	    char **cmdline, struct meminfo *mi)
+{
+}
+
+static void __init guide_a07_map_io(void)
+{
+	clps711x_map_io();
+	iotable_init(guide_a07_io_desc);
+}
+
+MACHINE_START(GUIDEA07, "Guide A07 (cs89712 core)")
+	MAINTAINER("Cam Mayor")
+	VIDEO(0x60000000, 0x6000bfff)
+	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_guide_a07)
+	MAPIO(guide_a07_map_io)
+	INITIRQ(clps711x_init_irq)
+MACHINE_END
+
+static int guide_a07_hw_init(void)
+{
+	/* in cs[1] (the FPGA), set zero wait states, clkenb, and sqaen */
+	u32 memcfg1 = 0xfc << 8;
+	memcfg1 |= clps_readl(MEMCFG1);
+	clps_writel(memcfg1, MEMCFG1);
+
+	return 0;
+}
+
+__initcall(guide_a07_hw_init);
+
diff -urN linux-2.4.22-pre2/arch/arm/mach-clps711x/irq.c linux-2.4.22-pre3/arch/arm/mach-clps711x/irq.c
--- linux-2.4.22-pre2/arch/arm/mach-clps711x/irq.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-clps711x/irq.c	2003-07-05 18:09:36.000000000 -0700
@@ -18,6 +18,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
 
 #include <asm/mach/irq.h>
 #include <asm/hardware.h>
diff -urN linux-2.4.22-pre2/arch/arm/mach-ebsa110/irq.c linux-2.4.22-pre3/arch/arm/mach-ebsa110/irq.c
--- linux-2.4.22-pre2/arch/arm/mach-ebsa110/irq.c	2001-04-12 12:20:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-ebsa110/irq.c	2003-07-05 18:09:36.000000000 -0700
@@ -11,6 +11,9 @@
  *   22-08-1998	RMK	Restructured IRQ routines
  */
 #include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/mach/irq.h>
 #include <asm/hardware.h>
@@ -35,14 +38,14 @@
 	unsigned long flags;
 	int irq;
 
-	save_flags_cli (flags);
+	local_irq_save(flags);
 	__raw_writeb(0xff, IRQ_MCLR);
 	__raw_writeb(0x55, IRQ_MSET);
 	__raw_writeb(0x00, IRQ_MSET);
 	if (__raw_readb(IRQ_MASK) != 0x55)
 		while (1);
 	__raw_writeb(0xff, IRQ_MCLR);	/* clear all interrupt enables */
-	restore_flags (flags);
+	local_irq_restore(flags);
 
 	for (irq = 0; irq < NR_IRQS; irq++) {
 		irq_desc[irq].valid	= 1;
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa/Makefile linux-2.4.22-pre3/arch/arm/mach-epxa/Makefile
--- linux-2.4.22-pre2/arch/arm/mach-epxa/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-epxa/Makefile	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,24 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= epxa.o
+
+# Object file lists.
+
+obj-y			:=  irq.o mm.o time.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+obj-$(CONFIG_EPXA1DB) += arch-epxa1db.o
+obj-$(CONFIG_EPXA10DB) += arch-epxa10db.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa/arch-epxa10db.c linux-2.4.22-pre3/arch/arm/mach-epxa/arch-epxa10db.c
--- linux-2.4.22-pre2/arch/arm/mach-epxa/arch-epxa10db.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-epxa/arch-epxa10db.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,60 @@
+/*
+ *  linux/arch/arm/mach-epxa/arch-epxa10db.c
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+extern void epxa_map_io(void);
+extern void epxa_init_irq(void);
+
+
+static void __init
+epxa10db_fixup(struct machine_desc *desc, struct param_struct *params,
+		 char **cmdline, struct meminfo *mi)
+{
+
+        mi->nr_banks      = 1;
+        mi->bank[0].start = 0;
+        mi->bank[0].size  = (128*1024*1024);
+        mi->bank[0].node  = 0;
+
+/*
+        ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+        setup_ramdisk( 1, 0, 0, 8192 );
+        setup_initrd(0xc0200000, 6*1024*1024);
+*/
+}
+
+MACHINE_START(CAMELOT, "Altera Epxa10db")
+	MAINTAINER("Altera Corporation")
+	BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000)
+      	FIXUP(epxa10db_fixup)
+	MAPIO(epxa_map_io)
+	INITIRQ(epxa_init_irq)
+        BOOT_PARAMS(0x100)
+MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa/arch-epxa1db.c linux-2.4.22-pre3/arch/arm/mach-epxa/arch-epxa1db.c
--- linux-2.4.22-pre2/arch/arm/mach-epxa/arch-epxa1db.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-epxa/arch-epxa1db.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,59 @@
+/*
+ *  linux/arch/arm/mach-epxa/arch-epxa10db.c
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+extern void epxa_map_io(void);
+extern void epxa_init_irq(void);
+
+static void __init
+epxa1db_fixup(struct machine_desc *desc, struct param_struct *params,
+		 char **cmdline, struct meminfo *mi)
+{
+
+        mi->nr_banks      = 1;
+        mi->bank[0].start = 0;
+        mi->bank[0].size  = (32*1024*1024);
+        mi->bank[0].node  = 0;
+
+/*
+        ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+        setup_ramdisk( 1, 0, 0, 8192 );
+        setup_initrd(0xc0200000, 6*1024*1024);
+*/
+}
+
+MACHINE_START(CAMELOT, "Altera Epxa1db")
+	MAINTAINER("Altera Corporation")
+	BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000)
+      	FIXUP(epxa1db_fixup)
+	MAPIO(epxa_map_io)
+	INITIRQ(epxa_init_irq)
+        BOOT_PARAMS(0x100)
+MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa/dma.c linux-2.4.22-pre3/arch/arm/mach-epxa/dma.c
--- linux-2.4.22-pre2/arch/arm/mach-epxa/dma.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-epxa/dma.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,36 @@
+/*
+ *  linux/arch/arm/mach-epxa10db/dma.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+}
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa/irq.c linux-2.4.22-pre3/arch/arm/mach-epxa/irq.c
--- linux-2.4.22-pre2/arch/arm/mach-epxa/irq.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-epxa/irq.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,74 @@
+/*
+ *  linux/arch/arm/mach-epxa10db/irq.c
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/platform.h>
+#include <asm/arch/int_ctrl00.h>
+
+
+static void mask_irq(unsigned int irq)
+{
+        __raw_writel(1 << irq, INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
+}
+
+static void unmask_irq(unsigned int irq)
+{
+        __raw_writel(1 << irq, INT_MS(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
+}
+ 
+void __init epxa_init_irq(void)
+{
+	unsigned int i;
+	
+	/*
+	 * This bit sets up the interrupt controller using 
+	 * the 6 PLD interrupts mode (the default) each 
+	 * irqs is assigned a priority which is the same
+	 * as its interrupt number. This scheme is used because 
+	 * its easy, but you may want to change it depending
+	 * on the contents of your PLD
+	 */
+
+	__raw_writel(3,INT_MODE(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
+	for (i = 0; i < NR_IRQS; i++){
+		__raw_writel(i+1, INT_PRIORITY_P0(IO_ADDRESS(EXC_INT_CTRL00_BASE)) + (4*i));
+	}
+
+
+	for (i = 0; i < NR_IRQS; i++) {
+	       
+		irq_desc[i].valid	= 1;
+		irq_desc[i].probe_ok	= 1;
+		irq_desc[i].mask_ack	= mask_irq;
+		irq_desc[i].mask	= mask_irq;
+		irq_desc[i].unmask	= unmask_irq;
+	}
+
+	/* Disable all interrupt */
+	__raw_writel(-1,INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
+
+}
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa/mm.c linux-2.4.22-pre3/arch/arm/mach-epxa/mm.c
--- linux-2.4.22-pre2/arch/arm/mach-epxa/mm.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-epxa/mm.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,43 @@
+/*
+ *  linux/arch/arm/mach-epxa10db/mm.c
+ *
+ *  MM routines for Altera'a Epxa10db board
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/sizes.h>
+ 
+#include <asm/mach/map.h>
+
+/* Page table mapping for I/O region */
+ 
+static struct map_desc epxa_io_desc[] __initdata = {
+ { IO_ADDRESS(EXC_REGISTERS_BASE),   EXC_REGISTERS_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},  LAST_DESC
+};
+
+void __init epxa_map_io(void)
+{
+	iotable_init(epxa_io_desc);
+}
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa/time.c linux-2.4.22-pre3/arch/arm/mach-epxa/time.c
--- linux-2.4.22-pre2/arch/arm/mach-epxa/time.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-epxa/time.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,33 @@
+/*
+ *  linux/arch/arm/mach-epxa10db/time.c
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+
+
+
+extern int (*set_rtc)(void);
+
+static int epxa10db_set_rtc(void)
+{
+	return 1;
+}
+
+static int epxa10db_rtc_init(void)
+{
+	set_rtc = epxa10db_set_rtc;
+
+	return 0;
+}
+
+__initcall(epxa10db_rtc_init);
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa10db/Makefile linux-2.4.22-pre3/arch/arm/mach-epxa10db/Makefile
--- linux-2.4.22-pre2/arch/arm/mach-epxa10db/Makefile	2001-10-25 13:53:45.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-epxa10db/Makefile	1969-12-31 16:00:00.000000000 -0800
@@ -1,22 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-USE_STANDARD_AS_RULE := true
-
-O_TARGET		:= epxa10db.o
-
-# Object file lists.
-
-obj-y			:= arch.o irq.o mm.o time.o 
-obj-m			:=
-obj-n			:=
-obj-			:=
-
-export-objs		:= 
-
-
-include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa10db/arch.c linux-2.4.22-pre3/arch/arm/mach-epxa10db/arch.c
--- linux-2.4.22-pre2/arch/arm/mach-epxa10db/arch.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-epxa10db/arch.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,61 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/arch.c
- *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-
-extern void epxa10db_map_io(void);
-extern void epxa10db_init_irq(void);
-
-
-static void __init
-epxa10db_fixup(struct machine_desc *desc, struct param_struct *params,
-		 char **cmdline, struct meminfo *mi)
-{
-
-        mi->nr_banks      = 1;
-        mi->bank[0].start = 0;
-        mi->bank[0].size  = (32*1024*1024);
-        mi->bank[0].node  = 0;
-
-/*
-        ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-        setup_ramdisk( 1, 0, 0, 8192 );
-        setup_initrd(0xc0200000, 6*1024*1024);
-*/
-}
-
-MACHINE_START(CAMELOT, "Altera Epxa10db")
-	MAINTAINER("Altera Corporation")
-	BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000)
-      	FIXUP(epxa10db_fixup)
-	MAPIO(epxa10db_map_io)
-	INITIRQ(epxa10db_init_irq)
-
-MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa10db/dma.c linux-2.4.22-pre3/arch/arm/mach-epxa10db/dma.c
--- linux-2.4.22-pre2/arch/arm/mach-epxa10db/dma.c	2001-11-22 10:41:14.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-epxa10db/dma.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,36 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/dma.c
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/mman.h>
-#include <linux/init.h>
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/hardware.h>
-
-#include <asm/mach/dma.h>
-
-void __init arch_dma_init(dma_t *dma)
-{
-}
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa10db/irq.c linux-2.4.22-pre3/arch/arm/mach-epxa10db/irq.c
--- linux-2.4.22-pre2/arch/arm/mach-epxa10db/irq.c	2001-10-25 13:53:45.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-epxa10db/irq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,70 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/irq.c
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/init.h>
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/mach/irq.h>
-#include <asm/arch/platform.h>
-#include <asm/arch/int_ctrl00.h>
-
-
-static void mask_irq(unsigned int irq)
-{
-        __raw_writel(1 << irq, INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-}
-
-static void unmask_irq(unsigned int irq)
-{
-        __raw_writel(1 << irq, INT_MS(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-}
- 
-void __init epxa10db_init_irq(void)
-{
-	unsigned int i;
-	
-	/*
-	 * This bit sets up the interrupt controller using 
-	 * the 6 PLD interrupts mode (the default) each 
-	 * irqs is assigned a priority which is the same
-	 * as its interrupt number. This scheme is used because 
-	 * its easy, but you may want to change it depending
-	 * on the contents of your PLD
-	 */
-
-	__raw_writel(3,INT_MODE(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-	for (i = 0; i < NR_IRQS; i++){
-		__raw_writel(i+1, INT_PRIORITY_P0(IO_ADDRESS(EXC_INT_CTRL00_BASE)) + (4*i));
-	}
-
-
-	for (i = 0; i < NR_IRQS; i++) {
-	       
-		irq_desc[i].valid	= 1;
-		irq_desc[i].probe_ok	= 1;
-		irq_desc[i].mask_ack	= mask_irq;
-		irq_desc[i].mask	= mask_irq;
-		irq_desc[i].unmask	= unmask_irq;
-	}
-
-	/* Disable all interrupt */
-	__raw_writel(-1,INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-
-}
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa10db/mm.c linux-2.4.22-pre3/arch/arm/mach-epxa10db/mm.c
--- linux-2.4.22-pre2/arch/arm/mach-epxa10db/mm.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-epxa10db/mm.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,49 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/mm.c
- *
- *  MM routines for Altera'a Epxa10db board
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/sizes.h>
- 
-#include <asm/mach/map.h>
-
-/* Page table mapping for I/O region */
- 
-static struct map_desc epxa10db_io_desc[] __initdata = {
- { IO_ADDRESS(EXC_REGISTERS_BASE),   EXC_REGISTERS_BASE,   SZ_16K     , DOMAIN_IO, 0, 1}, 
-{IO_ADDRESS(EXC_PLD_BLOCK0_BASE),   EXC_PLD_BLOCK0_BASE,   SZ_16K     , DOMAIN_IO, 0, 1}, 
-{IO_ADDRESS(EXC_PLD_BLOCK1_BASE),   EXC_PLD_BLOCK1_BASE,   SZ_16K     , DOMAIN_IO, 0, 1}, 
-{IO_ADDRESS(EXC_PLD_BLOCK2_BASE),   EXC_PLD_BLOCK2_BASE,   SZ_16K     , DOMAIN_IO, 0, 1}, 
-{IO_ADDRESS(EXC_PLD_BLOCK3_BASE),   EXC_PLD_BLOCK3_BASE,   SZ_16K     , DOMAIN_IO, 0, 1}, 
-{ FLASH_VADDR(EXC_EBI_BLOCK0_BASE),   EXC_EBI_BLOCK0_BASE,   SZ_16M     , DOMAIN_IO, 0, 1},
- LAST_DESC
-};
-
-void __init epxa10db_map_io(void)
-{
-	iotable_init(epxa10db_io_desc);
-}
diff -urN linux-2.4.22-pre2/arch/arm/mach-epxa10db/time.c linux-2.4.22-pre3/arch/arm/mach-epxa10db/time.c
--- linux-2.4.22-pre2/arch/arm/mach-epxa10db/time.c	2001-10-25 13:53:45.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-epxa10db/time.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,33 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/time.c
- *
- *  Copyright (C) 2000 Deep Blue Solutions
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-
-
-
-extern int (*set_rtc)(void);
-
-static int epxa10db_set_rtc(void)
-{
-	return 1;
-}
-
-static int epxa10db_rtc_init(void)
-{
-	set_rtc = epxa10db_set_rtc;
-
-	return 0;
-}
-
-__initcall(epxa10db_rtc_init);
diff -urN linux-2.4.22-pre2/arch/arm/mach-footbridge/arch.c linux-2.4.22-pre3/arch/arm/mach-footbridge/arch.c
--- linux-2.4.22-pre2/arch/arm/mach-footbridge/arch.c	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-footbridge/arch.c	2003-07-05 18:09:36.000000000 -0700
@@ -41,10 +41,12 @@
 fixup_ebsa285(struct machine_desc *desc, struct param_struct *params,
 	      char **cmdline, struct meminfo *mi)
 {
+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
 	ORIG_X		 = params->u1.s.video_x;
 	ORIG_Y		 = params->u1.s.video_y;
 	ORIG_VIDEO_COLS  = params->u1.s.video_num_cols;
 	ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
+#endif
 }
 
 MACHINE_START(EBSA285, "EBSA285")
diff -urN linux-2.4.22-pre2/arch/arm/mach-footbridge/irq.c linux-2.4.22-pre3/arch/arm/mach-footbridge/irq.c
--- linux-2.4.22-pre2/arch/arm/mach-footbridge/irq.c	2001-04-12 12:20:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-footbridge/irq.c	2003-07-05 18:09:36.000000000 -0700
@@ -18,6 +18,8 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/mach/irq.h>
 
diff -urN linux-2.4.22-pre2/arch/arm/mach-integrator/cpu.c linux-2.4.22-pre3/arch/arm/mach-integrator/cpu.c
--- linux-2.4.22-pre2/arch/arm/mach-integrator/cpu.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-integrator/cpu.c	2003-07-05 18:09:36.000000000 -0700
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2001 Deep Blue Solutions Ltd.
  *
- *  $Id: cpu.c,v 1.2 2001/09/22 12:11:17 rmk Exp $
+ *  $Id: cpu.c,v 1.2.2.1 2002/05/30 15:08:03 db Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff -urN linux-2.4.22-pre2/arch/arm/mach-integrator/irq.c linux-2.4.22-pre3/arch/arm/mach-integrator/irq.c
--- linux-2.4.22-pre2/arch/arm/mach-integrator/irq.c	2001-03-02 18:38:39.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-integrator/irq.c	2003-07-05 18:09:36.000000000 -0700
@@ -18,6 +18,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
diff -urN linux-2.4.22-pre2/arch/arm/mach-mx1ads/irq.c linux-2.4.22-pre3/arch/arm/mach-mx1ads/irq.c
--- linux-2.4.22-pre2/arch/arm/mach-mx1ads/irq.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-mx1ads/irq.c	2003-07-05 18:09:36.000000000 -0700
@@ -19,6 +19,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
diff -urN linux-2.4.22-pre2/arch/arm/mach-omaha/Makefile linux-2.4.22-pre3/arch/arm/mach-omaha/Makefile
--- linux-2.4.22-pre2/arch/arm/mach-omaha/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-omaha/Makefile	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= omaha.o
+
+# Object file lists.
+
+obj-y			:= core.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+obj-$(CONFIG_LEDS)	+= leds.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/arm/mach-omaha/core.c linux-2.4.22-pre3/arch/arm/mach-omaha/core.c
--- linux-2.4.22-pre2/arch/arm/mach-omaha/core.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-omaha/core.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,130 @@
+/*
+ *  linux/arch/arm/mach-omaha/core.c
+ *
+ *  Copyright (C) ARM Limited 2002.
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+extern void omaha_map_io(void);
+
+/* 
+ * All IO addresses are mapped onto VA 0xExxx.xxxx, where x.xxxx
+ * is the (PA + 0xE0000000).
+ *
+ * Setup a VA for the Omaha interrupt controller.
+ */
+ 
+#define VA_IC_BASE              IO_ADDRESS(PLAT_PERIPHERAL_BASE) 
+
+static void sc_mask_and_ack_irq(unsigned int irq)
+{
+	unsigned int tmp;
+	
+	// Mask this interrupt
+	tmp = __raw_readl(VA_IC_BASE + OMAHA_INTMSK);
+	tmp = tmp | (1 << irq);	  	
+        __raw_writel(tmp, VA_IC_BASE + OMAHA_INTMSK);
+	
+	// Clear the source pending register
+	tmp = __raw_readl(VA_IC_BASE + OMAHA_SRCPND);
+	tmp = tmp | (1 << irq);	  	
+        __raw_writel(tmp, VA_IC_BASE + OMAHA_SRCPND);
+	
+	// Clear the interrupt pending register
+	tmp = __raw_readl(VA_IC_BASE + OMAHA_INTPND);
+	tmp = tmp | (1 << irq);	  	
+	__raw_writel(tmp, VA_IC_BASE + OMAHA_INTPND);
+
+}
+
+static void sc_mask_irq(unsigned int irq)
+{
+	unsigned int tmp;
+	
+	// Mask this interrupt
+	tmp = __raw_readl(VA_IC_BASE + OMAHA_INTMSK);
+	tmp = tmp | (1 << irq);	  	
+        __raw_writel(tmp, VA_IC_BASE + OMAHA_INTMSK);
+}
+
+static void sc_unmask_irq(unsigned int irq)
+{
+	unsigned int tmp;
+	
+	tmp = __raw_readl(VA_IC_BASE + OMAHA_INTMSK);
+	tmp = tmp & ~(1 << irq);	  	
+        __raw_writel(tmp, VA_IC_BASE + OMAHA_INTMSK);
+}
+ 
+static void __init omaha_init_irq(void)
+{
+	unsigned int i;
+
+	/* bootloader disables interrupt hardware,
+	 * so we just set up linux data structures...
+	 */
+
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].valid	= 1;
+		irq_desc[i].probe_ok	= 1;
+		irq_desc[i].mask_ack	= sc_mask_and_ack_irq;
+		irq_desc[i].mask	= sc_mask_irq;
+		irq_desc[i].unmask	= sc_unmask_irq;
+	}
+}
+
+/* Notes
+ *
+ * IO space has been mapped into the top of virtual memory at 0xExxx xxxx
+ * See IO_ACCESS macro for details.
+ */
+
+/* 		Logical		Physical
+ * Start	0xE0000000	0x00000000
+ * End		0xFAFFFFFC	0x1AFFFFFC
+ */
+
+/* Map the bottom 2Gb of IO space into the top of memory, but leave
+ * space for the high vector table.
+ */ 
+static struct map_desc omaha_io_desc[] __initdata = {
+ { IO_ADDRESS(0x00000000), 0x00000000, 0x1B000000, DOMAIN_IO, 0, 1 },
+ LAST_DESC
+};
+
+static void __init omaha_map_io(void)
+{
diff -urN linux-2.4.22-pre2/arch/arm/mach-omaha/leds.c linux-2.4.22-pre3/arch/arm/mach-omaha/leds.c
--- linux-2.4.22-pre2/arch/arm/mach-omaha/leds.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-omaha/leds.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,89 @@
+/*
+ *  linux/arch/arm/mach-omaha/leds.c
+ *
+ *  Omaha LED control routines
+ *
+ *  Copyright (C) 1999-2002 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+static int saved_leds;
+
+static void omaha_leds_event(led_event_t ledevt)
+{
+	unsigned long flags;			      
+	unsigned int ctrl = IO_ADDRESS(PLAT_DBG_LEDS);
+	unsigned int leds;
+	
+	// yup, change the LEDs
+	local_irq_save(flags);
+
+	switch(ledevt) {
+	case led_idle_start:
+		leds = __raw_readl(ctrl);
+		leds |= GREEN_LED;
+		__raw_writel(leds,ctrl);
+		break;
+
+	case led_idle_end:
+		leds = __raw_readl(ctrl);
+		leds &= ~GREEN_LED;
+		__raw_writel(leds,ctrl);
+		break;
+
+	case led_timer:
+		leds = __raw_readl(ctrl);
+		leds ^= YELLOW_LED;
+		__raw_writel(leds,ctrl);
+		break;
+
+	case led_red_on:
+		leds = __raw_readl(ctrl);
+		leds |= RED_LED;
+		__raw_writel(leds,ctrl);
+		break;
+
+	case led_red_off:
+		leds = __raw_readl(ctrl);
+		leds &= ~RED_LED;
+		__raw_writel(leds,ctrl);
+		break;
+
+	default:
+		break;
+	}
+
+	local_irq_restore(flags);
+}
+
+static int __init leds_init(void)
+{
+	if (machine_is_omaha())
+		leds_event = omaha_leds_event;
+
+	return 0;
+}
+
+__initcall(leds_init);
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/Makefile linux-2.4.22-pre3/arch/arm/mach-sa1100/Makefile
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/Makefile	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/Makefile	2003-07-05 18:09:36.000000000 -0700
@@ -15,10 +15,10 @@
 obj-n :=
 obj-  :=
 
-export-objs :=	assabet.o dma-sa1100.o dma-sa1111.o \
-		flexanet.o freebird.o generic.o h3600.o \
-		huw_webpanel.o irq.o pcipool.o sa1111.o sa1111-pcibuf.o \
-		system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o
+export-objs :=	assabet.o consus.o badge4.o dma-sa1100.o dma-sa1111.o \
+		flexanet.o freebird.o frodo.o generic.o h3600.o \
+		huw_webpanel.o irq.o sa1111.o sa1111-pcibuf.o \
+		system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o simputer.o ssp.o
 
 # These aren't present yet, and prevents a plain -ac kernel building.
 # hwtimer.o
@@ -29,22 +29,30 @@
 # We link the CPU support next, so that RAM timings can be tuned.
 ifeq ($(CONFIG_CPU_FREQ),y)
 obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o
+obj-$(CONFIG_SA1100_CEP) += cpu-sa1110.o
+obj-$(CONFIG_SA1100_CONSUS) += cpu-sa1110.o
 obj-$(CONFIG_SA1100_CERF) += cpu-sa1110.o
+obj-$(CONFIG_SA1100_HACKKIT) += cpu-sa1110.o
 obj-$(CONFIG_SA1100_PT_SYSTEM3) += cpu-sa1110.o
+obj-$(CONFIG_SA1100_SIMPUTER) += cpu-sa1110.o
 obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o
 endif
 
 # Next, the SA1111 stuff.
 obj-$(CONFIG_SA1111) += sa1111.o dma-sa1111.o
-obj-$(CONFIG_USB_OHCI_SA1111) += sa1111-pcibuf.o pcipool.o
+obj-$(CONFIG_USB_OHCI_SA1111) += sa1111-pcibuf.o
 
 # Specific board support
+obj-$(CONFIG_SA1100_ADSAGC) += adsagc.o
 obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o
+obj-$(CONFIG_SA1100_ADSBITSYPLUS) += adsbitsyplus.o
 obj-$(CONFIG_SA1100_ASSABET) += assabet.o
 obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
 obj-$(CONFIG_SA1100_BADGE4) +=  badge4.o
 obj-$(CONFIG_SA1100_BRUTUS) += brutus.o
+obj-$(CONFIG_SA1100_CEP) += cep.o
 obj-$(CONFIG_SA1100_CERF) += cerf.o
+obj-$(CONFIG_SA1100_CONSUS) += consus.o
 obj-$(CONFIG_SA1100_EMPEG) += empeg.o
 obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o
 obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o
@@ -52,6 +60,7 @@
 obj-$(CONFIG_SA1100_GRAPHICSCLIENT) += graphicsclient.o
 obj-$(CONFIG_SA1100_GRAPHICSMASTER) += graphicsmaster.o
 obj-$(CONFIG_SA1100_H3600) += h3600.o
+obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o
 obj-$(CONFIG_SA1100_HUW_WEBPANEL) += huw_webpanel.o
 obj-$(CONFIG_SA1100_ITSY) += itsy.o
 obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
@@ -65,20 +74,25 @@
 obj-$(CONFIG_SA1100_SHANNON) += shannon.o
 obj-$(CONFIG_SA1100_SHERMAN) += sherman.o
 obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
+obj-$(CONFIG_SA1100_SIMPUTER) += simputer.o
 obj-$(CONFIG_SA1100_VICTOR) += victor.o
 obj-$(CONFIG_SA1100_XP860) += xp860.o
 obj-$(CONFIG_SA1100_YOPY) += yopy.o
 
 # LEDs support
 leds-y := leds.o
+leds-$(CONFIG_SA1100_ADSAGC) += leds-adsagc.o
 leds-$(CONFIG_SA1100_ADSBITSY) += leds-adsbitsy.o
+leds-$(CONFIG_SA1100_ADSBITSYPLUS) += leds-adsbitsyplus.o
 leds-$(CONFIG_SA1100_ASSABET) += leds-assabet.o
 leds-$(CONFIG_SA1100_BRUTUS) += leds-brutus.o
 leds-$(CONFIG_SA1100_CERF) += leds-cerf.o
+leds-$(CONFIG_SA1100_CONSUS) += leds-consus.o
 leds-$(CONFIG_SA1100_FLEXANET) += leds-flexanet.o
 leds-$(CONFIG_SA1100_FRODO) += leds-frodo.o
 leds-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o
 leds-$(CONFIG_SA1100_GRAPHICSMASTER) += leds-graphicsmaster.o
+leds-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o
 leds-$(CONFIG_SA1100_LART) += leds-lart.o
 leds-$(CONFIG_SA1100_PFS168) += leds-pfs168.o
 leds-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o  
@@ -95,6 +109,8 @@
 # Miscelaneous functions
 obj-$(CONFIG_PM) += pm.o sleep.o
 
+obj-$(CONFIG_SA1100_SSP)		+= ssp.o
+
 include $(TOPDIR)/Rules.make
 
 sa1100usb_core.o: $(sa1100usb_core-objs)
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/adsagc.c linux-2.4.22-pre3/arch/arm/mach-sa1100/adsagc.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/adsagc.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/adsagc.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,360 @@
+/*
+ * linux/arch/arm/mach-sa1100/adsagc.c
+ *
+ * Pieces specific to the ADS Advanced Graphics Client board
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/serial_core.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+static int __init adsagc_init(void)
+{
+	int ret;
+
+	if (!machine_is_adsagc())
+		return -ENODEV;
+
+	/*
+	 * Ensure that the memory bus request/grant signals are setup,
+	 * and the grant is held in its inactive state
+	 */
+	sa1110_mb_disable();
+
+	/* Adsagc uses GPIO pins for SPI interface to AVR
+	 * AGC uses the standard pins instead.  AGC also has controls
+	 * SA1111 and Smartio reset with GPIO.
+	 */
+
+	// Set RTS low during sleep
+	PGSR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+
+	// Reset SA1111
+	GPDR |= GPIO_GPIO12;
+	GPCR = GPIO_GPIO12;
+	udelay(1000);
+	GPSR = GPIO_GPIO12;
+
+	/* use the regular SSP pins */
+	PPAR &= ~PPAR_SSPGPIO;
+	/*
+	 * Probe for SA1111.
+	 */
+	ret = sa1111_probe(ADS_SA1111_BASE);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We found it.  Wake the chip up.
+	 */
+	sa1111_wake();
+
+	/*
+	 * The SDRAM configuration of the SA1110 and the SA1111 must
+	 * match.  This is very important to ensure that SA1111 accesses
+	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+	 * MBGNT signal, so we must have called sa1110_mb_disable()
+	 * beforehand.
+	 */
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+	/*
+	 * Enable PWM control for LCD
+	 */
+	SKPCR |= SKPCR_PWMCLKEN;
+	SACR1 &= ~SACR1_L3EN;
+	ADS_CR3 |= ADS_CR3_BLON;                // Enable the backlight
+	SKPWM1 = 0x7F;				// Backlight PWM
+	SKPEN1 = 1;
+	SKPWM0 = 0x7F;				// VEE
+	SKPEN0 = 1;
+
+	/*
+	 * We only need to turn on DCLK whenever we want to use the
+	 * DMA.  It can otherwise be held firmly in the off position.
+	 */
+	SKPCR |= SKPCR_DCLKEN;
+
+	/*
+	 * Enable the SA1110 memory bus request and grant signals.
+	 */
+	sa1110_mb_enable();
+
+	set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
+	sa1111_init_irq(IRQ_GPIO0);
+
+	return 0;
+}
+
+__initcall(adsagc_init);
+
+/*
+ * Handlers for Adsagc's external IRQ logic
+ */
+
+#define ADSAGC_N_IRQ (IRQ_ADSAGC_END - IRQ_ADSAGC_START)
+
+static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
+{
+	int i;
+
+	while( (irq = ADS_INT_ST1 ) ){
+		for( i = 0; i < ADSAGC_N_IRQ; i++ )
+			if( irq & (1<<i) ) {
+				do_IRQ( IRQ_ADSAGC_START + i, regs );
+			}
+	}
+}
+
+static struct irqaction ADS_ext_irq = {
+	.name		= "ADS_ext_IRQ",
+	.handler	= ADS_IRQ_demux,
+	.flags		= SA_INTERRUPT
+};
+
+static void ADS_mask_and_ack_irq0(unsigned int irq)
+{
+	int mask = (1 << (irq - IRQ_ADSAGC_START));
+	ADS_INT_EN1 &= ~mask;
+	ADS_INT_ST1 = mask;
+}
+
+static void ADS_mask_irq0(unsigned int irq)
+{
+	ADS_INT_ST1 = (1 << (irq - IRQ_ADSAGC_START));
+}
+
+static void ADS_unmask_irq0(unsigned int irq)
+{
+	ADS_INT_EN1 |= (1 << (irq - IRQ_ADSAGC_START));
+}
+
+static void __init adsagc_init_irq(void)
+{
+	int irq;
+
+	/* First the standard SA1100 IRQs */
+	sa1100_init_irq();
+
+
+	/* disable all IRQs */
+	ADS_INT_EN1 = 0;
+
+	/* clear all IRQs */
+	ADS_INT_ST1 = 0xff;
+
+	for (irq = IRQ_ADSAGC_START; irq < IRQ_ADSAGC_END; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq0;
+		irq_desc[irq].mask	= ADS_mask_irq0;
+		irq_desc[irq].unmask	= ADS_unmask_irq0;
+	}
+
+	GPDR &= ~GPIO_GPIO10;
+	set_GPIO_IRQ_edge(GPIO_GPIO10, GPIO_RISING_EDGE);  // this may change with final HW spin
+	setup_arm_irq( IRQ_GPIO10, &ADS_ext_irq );
+}
+
+
+/*
+ * Resume SA1111 when system wakes up
+ */
+void adsagc_sa1111_wake(void)
+{
+	// Reset SA1111
+	GPDR |= GPIO_GPIO12;
+	GPCR = GPIO_GPIO12;
+	udelay(1000);
+	GPSR = GPIO_GPIO12;
+	sa1111_wake();
+
+	SKPCR |= SKPCR_PWMCLKEN;
+	SACR1 &= ~SACR1_L3EN;
+
+	SKPWM1 = 0x7F;				// Backlight PWM
+	SKPEN1 = 1;
+	SKPWM0 = 0x7F;				// VEE
+	SKPEN0 = 1;
+
+	GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
+	GPDR |= GPIO_MBGNT;
+	GPDR &= ~GPIO_MBREQ;
+	TUCR |= TUCR_MR;
+
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+	SKPCR |= SKPCR_DCLKEN;
+
+	// Reset PCMCIA
+	PCCR = 0xFF;
+	mdelay(100);
+	PA_DDR = 0x00;
+	PA_DWR = 0x05;
+	PCCR = ~(PCCR_S0_RST | PCCR_S1_RST);
+
+#ifdef CONFIG_USB_OHCI_SA1111
+	// Turn ON clock
+	SKPCR |= SKPCR_UCLKEN;
+	udelay(100);
+
+	// force a RESET
+	USB_RESET = 0x01;
+	USB_RESET |= 0x02;
+	udelay(100);
+
+	// Set Power Sense and Control Line
+	USB_RESET = 0;
+	USB_RESET = USB_RESET_PWRSENSELOW;
+	USB_STATUS = 0;
+	udelay(10);
+#endif
+}
+
+static struct map_desc adsagc_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf2000000, 0x40000000, 0x00004000, DOMAIN_IO, 0, 1, 0, 0 }, /* 91C1111 */
+  { 0xf3000000, 0x48000000, 0x00340000, DOMAIN_IO, 0, 1, 0, 0 }, /* S1D13806 */
+  /* note: CPLD includes CAN in Advanced Graphics Client */
+  { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
+  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
+  LAST_DESC
+};
+
+static int adsagc_uart_open(struct uart_port *port, struct uart_info *info)
+{
+	int	ret = 0;
+
+	if (port->mapbase == _Ser1UTCR0) {
+		Ser1SDCR0 |= SDCR0_UART;
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		Ser2UTCR4 = Ser2HSCR0 = 0;
+	}
+	return ret;
+}
+
+static u_int adsagc_get_mctrl(struct uart_port *port)
+{
+	u_int result = TIOCM_CD | TIOCM_DSR;
+
+	if (port->mapbase == _Ser1UTCR0) {
+		if (!(GPLR & GPIO_GPIO14))
+			result |= TIOCM_CTS;
+	} else if (port->mapbase == _Ser2UTCR0) {
+		if (!(GPLR & GPIO_GPIO16))
+			result |= TIOCM_CTS;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (!(GPLR & GPIO_GPIO18))
+			result |= TIOCM_CTS;
+	} else {
+		result = TIOCM_CTS;
+	}
+
+	return result;
+}
+
+static void adsagc_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	if (port->mapbase == _Ser1UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			GPCR = GPIO_GPIO15;
+		else
+			GPSR = GPIO_GPIO15;
+	} else if (port->mapbase == _Ser2UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			GPCR = GPIO_GPIO17;
+		else
+			GPSR = GPIO_GPIO17;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			GPCR = GPIO_GPIO19;
+		else
+			GPSR = GPIO_GPIO19;
+	}
+}
+
+static void
+adsagc_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	// state has ACPI D0-D3
+	// ACPI D0 	  : resume from suspend
+	// ACPI D1-D3 : enter to a suspend state
+	if (port->mapbase == _Ser1UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser1UTCR3 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser2UTCR3 = 0;
+                        Ser2HSCR0 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser3UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser3UTCR3 = 0;
+		}
+	}
+}
+
+static struct sa1100_port_fns adsagc_port_fns __initdata = {
+	.open		= adsagc_uart_open,
+	.get_mctrl	= adsagc_get_mctrl,
+	.set_mctrl	= adsagc_set_mctrl,
+	.pm		= adsagc_uart_pm,
+};
+
+static void __init adsagc_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(adsagc_io_desc);
+
+	sa1100_register_uart_fns(&adsagc_port_fns);
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1);
+	// don't register if you want to use IRDA
+#ifndef CONFIG_SA1100_FIR
+	sa1100_register_uart(2, 2);
+#endif
+
+	/* set GPDR now */
+	GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+       	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18);
+}
+
+MACHINE_START(ADSAGC, "ADS Advanced GraphicsClient")
+        BOOT_PARAMS(0xc000003c)
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	MAPIO(adsagc_map_io)
+	INITIRQ(adsagc_init_irq)
+MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/adsbitsy.c linux-2.4.22-pre3/arch/arm/mach-sa1100/adsbitsy.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/adsbitsy.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/adsbitsy.c	2003-07-05 18:09:36.000000000 -0700
@@ -14,9 +14,13 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
+#include <linux/delay.h>
 #include <linux/serial_core.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
+#include <asm/hardware/sa1111.h>
 #include <asm/setup.h>
 #include <asm/irq.h>
 
@@ -30,6 +34,7 @@
 #include "generic.h"
 #include "sa1111.h"
 
+
 static int __init adsbitsy_init(void)
 {
 	int ret;
@@ -43,6 +48,13 @@
 	 */
 	sa1110_mb_disable();
 
+	/* Bitsy uses GPIO pins for SPI interface to AVR
+	 * Bitsy Plus uses the standard pins instead.
+	 * it also needs to reset the AVR when booting
+	 */
+
+	PPAR |= PPAR_SSPGPIO;
+
 	/*
 	 * Reset SA1111
 	 */
@@ -50,6 +62,19 @@
 	udelay(1000);
 	GPSR |= GPIO_GPIO26;
 
+
+#ifndef CONFIG_LEDS_TIMER
+	// Set Serial port 1 RTS and DTR Low during sleep
+	PGSR |= GPIO_GPIO15 | GPIO_GPIO20;
+#else
+	// only RTS (because DTR is also the LED
+	// which should be off during sleep);
+	PGSR |= GPIO_GPIO15;
+#endif
+
+	// Set Serial port 3RTS Low during sleep
+	PGSR |= GPIO_GPIO19;
+
 	/*
 	 * Probe for SA1111.
 	 */
@@ -74,15 +99,6 @@
 			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
 
 	/*
-	 * Enable PWM control for LCD
-	 */
-	SKPCR |= SKPCR_PWMCLKEN;
-	SKPWM0 = 0x7F;				// VEE
-	SKPEN0 = 1;
-	SKPWM1 = 0x01;				// Backlight
-	SKPEN1 = 1;
-
-	/*
 	 * We only need to turn on DCLK whenever we want to use the
 	 * DMA.  It can otherwise be held firmly in the off position.
 	 */
@@ -108,48 +124,135 @@
 }
 
 
-/*
- * Initialization fixup
- */
-
-static void __init
-fixup_adsbitsy(struct machine_desc *desc, struct param_struct *params,
-		     char **cmdline, struct meminfo *mi)
-{
-	SET_BANK( 0, 0xc0000000, 32*1024*1024 );
-	mi->nr_banks = 1;
-
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-	setup_ramdisk( 1, 0, 0, 8192 );
-	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
-}
-
 static struct map_desc adsbitsy_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf0000000, 0x3C000000, 0x00004000, DOMAIN_IO, 0, 1, 0, 0 }, /* 91C1111 */
   { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA1111 */
   LAST_DESC
 };
 
+/* Use this to see when all uarts are shutdown.  Or all are closed.
+ * We can only turn off RS232 chip if either of these are true.
+ */
+
+static int uart_wake_count[3] = {1, 1, 1};
+
+enum {UART_SHUTDOWN, UART_WAKEUP};
+
+static void update_uart_counts(int line, int state)
+{
+	switch (state) {
+	case UART_WAKEUP:
+		uart_wake_count[line]++;
+		break;
+	case UART_SHUTDOWN:
+		uart_wake_count[line]--;
+		break;
+	}
+}
+
 static int adsbitsy_uart_open(struct uart_port *port, struct uart_info *info)
 {
 	if (port->mapbase == _Ser1UTCR0) {
 		Ser1SDCR0 |= SDCR0_UART;
-#error Fixme	// Set RTS High (should be done in the set_mctrl fn)
-		GPCR = GPIO_GPIO15;
 	} else if (port->mapbase == _Ser2UTCR0) {
 		Ser2UTCR4 = Ser2HSCR0 = 0;
-#error Fixme	// Set RTS High (should be done in the set_mctrl fn)
-		GPCR = GPIO_GPIO17;
-	} else if (port->mapbase == _Ser2UTCR0) {
-#error Fixme	// Set RTS High (should be done in the set_mctrl fn)
-		GPCR = GPIO_GPIO19;
 	}
 	return 0;
 }
 
+void adsbitsy_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	// state has ACPI D0-D3
+	// ACPI D0 	  : resume from suspend
+	// ACPI D1-D3 : enter to a suspend state
+	if (port->mapbase == _Ser1UTCR0) {
+		if (state) {
+			update_uart_counts(1, UART_SHUTDOWN);
+			// disable uart
+			Ser1UTCR3 = 0;
+		}
+		else {
+			update_uart_counts(1, UART_WAKEUP);
+		}
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		if (state) {
+			update_uart_counts(2, UART_SHUTDOWN);
+			// disable uart
+			Ser2UTCR3 = 0;
+			Ser2HSCR0 = 0;
+		}
+		else {
+			update_uart_counts(2, UART_WAKEUP);
+		}
+	}
+	else if (port->mapbase == _Ser3UTCR0) {
+		if (state) {
+			update_uart_counts(0, UART_SHUTDOWN);
+			// disable uart
+			Ser3UTCR3 = 0;
+		}
+		else {
+			update_uart_counts(0, UART_WAKEUP);
+		}
+	}
+}
+
+static void adsbitsy_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	// note: only ports 1 and 3 have modem control
+	if (port->mapbase == _Ser1UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			// Set RTS High
+			GPCR = GPIO_GPIO15;
+		else
+			// Set RTS LOW
+			GPSR = GPIO_GPIO15;
+		if (mctrl & TIOCM_DTR)
+			// Set DTR High
+			GPCR = GPIO_GPIO20;
+		else
+			// Set DTR Low
+			GPSR = GPIO_GPIO20;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			// Set RTS High
+			GPCR = GPIO_GPIO19;
+		else
+			// Set RTS LOW
+			GPSR = GPIO_GPIO19;
+	}
+}
+
+static u_int adsbitsy_get_mctrl(struct uart_port *port)
+{
+	u_int ret = 0;
+
+	// note: only ports 1 and 3 have modem control
+	if (port->mapbase == _Ser1UTCR0) {
+		if (!(GPLR & GPIO_GPIO14))
+			ret |= TIOCM_CTS;
+		if (!(GPLR & GPIO_GPIO24))
+			ret |= TIOCM_DSR;
+		if (!(GPLR & GPIO_GPIO16))
+			ret |= TIOCM_RI;
+		if (!(GPLR & GPIO_GPIO17))
+			ret |= TIOCM_CD;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (!(GPLR & GPIO_GPIO18))
+			ret |= TIOCM_CTS;
+	}
+
+	return ret;
+}
+
 static struct sa1100_port_fns adsbitsy_port_fns __initdata = {
-	.open	= adsbitsy_uart_open,
+	.set_mctrl =    adsbitsy_set_mctrl,
+	.get_mctrl =    adsbitsy_get_mctrl,
+	.open =	        adsbitsy_uart_open,
+	.pm =           adsbitsy_uart_pm,
 };
 
 static void __init adsbitsy_map_io(void)
@@ -160,14 +263,27 @@
 	sa1100_register_uart_fns(&adsbitsy_port_fns);
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
+
+	// don't register if you want to use IRDA
+#ifndef CONFIG_SA1100_FIR
 	sa1100_register_uart(2, 2);
-	GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
-	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18);
+#endif
+
+	// COM1 Set RTS and DTR Output
+	GPDR |= GPIO_GPIO15 | GPIO_GPIO20;
+	// Set CTS, DSR, RI and CD Input
+	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO24 | GPIO_GPIO16 | GPIO_GPIO17);
+
+	// COM3 Set RTS Output
+	GPDR |= GPIO_GPIO19;
+	// Set CTS Input
+	GPDR &= ~GPIO_GPIO18;
 }
 
+
 MACHINE_START(ADSBITSY, "ADS Bitsy")
+	BOOT_PARAMS(0xc000003c)
 	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	FIXUP(fixup_adsbitsy)
 	MAPIO(adsbitsy_map_io)
 	INITIRQ(adsbitsy_init_irq)
 MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/adsbitsyplus.c linux-2.4.22-pre3/arch/arm/mach-sa1100/adsbitsyplus.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/adsbitsyplus.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/adsbitsyplus.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,395 @@
+/*
+ * linux/arch/arm/mach-sa1100/adsbitsyplus.c
+ *
+ * Author: Robert Whaley
+ *
+ * This file comes from adsbitsy.c of Woojung Huh <whuh@applieddata.net>
+ *
+ * Pieces specific to the ADS Bitsy Plus
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+/* unfortunately, we can't detect the difference between REV 2 and REV A
+   connector boards.  So by convention, the registers.txt file is used
+   to set a byte to either 0x02 or 0x0a to make this distinction.  The
+   bootloader must detect this by default we assume rev A since most boards
+   will be rev A */
+
+static int adsbitsyplus_connector_board_rev_number = 0xA;
+
+static int __init adsbitsyplus_connector_board_rev_setup(char *str)
+{
+	adsbitsyplus_connector_board_rev_number = simple_strtol(str,NULL,0);
+	return 1;
+}
+
+int adsbitsyplus_connector_board_rev(void)
+{
+	static int only_once = 1;
+	if (only_once) {
+		printk(KERN_INFO "Bitsy Connector Board REV: %#x\n", adsbitsyplus_connector_board_rev_number);
+		only_once = 0;
+	}
+	return adsbitsyplus_connector_board_rev_number;
+}
+
+static int __init adsbitsyplus_init(void)
+{
+	int ret;
+
+	if (!machine_is_adsbitsyplus())
+		return -ENODEV;
+
+	/*
+	 * Ensure that the memory bus request/grant signals are setup,
+	 * and the grant is held in its inactive state
+	 */
+	sa1110_mb_disable();
+
+	/* Bitsy uses GPIO pins for SPI interface to AVR
+	 * Bitsy Plus uses the standard pins instead.
+	 * it also needs to reset the AVR when booting
+	 */
+
+	PPAR &= ~PPAR_SSPGPIO;
+	ADS_CPLD_SUPPC |= ADS_SUPPC_AVR_WKP;
+	mdelay(100);
+	ADS_CPLD_SUPPC &= ~ADS_SUPPC_AVR_WKP;
+
+	/*
+	 * Reset SA1111
+	 */
+	GPCR |= GPIO_GPIO26;
+	udelay(1000);
+	GPSR |= GPIO_GPIO26;
+
+#ifndef CONFIG_LEDS_TIMER
+	// Set Serial port 1 RTS and DTR Low during sleep
+	PGSR |= GPIO_GPIO15 | GPIO_GPIO20;
+#else
+	// only RTS (because DTR is also the LED
+	// which should be off during sleep);
+	PGSR |= GPIO_GPIO15;
+#endif
+
+	// Set Serial port 3RTS Low during sleep
+	PGSR |= GPIO_GPIO19;
+
+	/*
+	 * Probe for SA1111.
+	 */
+	ret = sa1111_probe(ADSBITSYPLUS_SA1111_BASE);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We found it.  Wake the chip up.
+	 */
+	sa1111_wake();
+
+	/*
+	 * The SDRAM configuration of the SA1110 and the SA1111 must
+	 * match.  This is very important to ensure that SA1111 accesses
+	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+	 * MBGNT signal, so we must have called sa1110_mb_disable()
+	 * beforehand.
+	 */
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+	/*
+	 * We only need to turn on DCLK whenever we want to use the
+	 * DMA.  It can otherwise be held firmly in the off position.
+	 */
+	SKPCR |= SKPCR_DCLKEN;
+
+	/*
+	 * Enable the SA1110 memory bus request and grant signals.
+	 */
+	sa1110_mb_enable();
+
+	set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
+	sa1111_init_irq(IRQ_GPIO0);
+
+	return 0;
+}
+
+__initcall(adsbitsyplus_init);
+
+static void __init adsbitsyplus_init_irq(void)
+{
+	/* First the standard SA1100 IRQs */
+	sa1100_init_irq();
+}
+
+/*
+ * Resume SA1111 when system wakes up
+ */
+void adsbitsyplus_sa1111_wake(unsigned long pa_dwr)
+{
+	// Turn ON SA1111
+	GPCR |= GPIO_GPIO26;
+	mdelay(1);
+	GPSR |= GPIO_GPIO26;
+
+	GAFR |= GPIO_32_768kHz;
+	GPDR |= GPIO_32_768kHz;
+	TUCR = TUCR_3_6864MHz;
+
+	SBI_SKCR = SKCR_PLL_BYPASS | SKCR_RDYEN | SKCR_OE_EN;
+	udelay(100);
+	SBI_SKCR = SKCR_PLL_BYPASS | SKCR_RCLKEN | SKCR_RDYEN | SKCR_OE_EN;
+
+	GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
+	GPDR |= GPIO_MBGNT;
+	GPDR &= ~GPIO_MBREQ;
+	TUCR |= TUCR_MR;
+
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+	SKPCR |= SKPCR_DCLKEN;
+
+	// Reset PCMCIA
+	PCCR = 0xFF;
+	mdelay(100);
+	PA_DDR = 0x00;
+	// PA_DWR = GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
+	// PA_DWR = GPIO_GPIO0 | GPIO_GPIO2 | GPIO_GPIO3;
+	PA_DWR = pa_dwr;
+	PCCR = ~(PCCR_S0_RST | PCCR_S1_RST);
+
+#ifdef CONFIG_USB_OHCI_SA1111
+	// Turn ON clock
+	SKPCR |= SKPCR_UCLKEN;
+	udelay(100);
+
+	// force a RESET
+	USB_RESET = 0x01;
+	USB_RESET |= 0x02;
+	udelay(100);
+
+	// Set Power Sense and Control Line
+	USB_RESET = 0;
+	USB_RESET = USB_RESET_PWRSENSELOW;
+	USB_STATUS = 0;
+	udelay(10);
+#endif
+}
+
+
+static struct map_desc adsbitsyplus_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf0000000, 0x3C000000, 0x00004000, DOMAIN_IO, 0, 1, 0, 0 }, /* 91C1111 */
+  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA1111 */
+  { 0xf1000000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD Controller */
+  LAST_DESC
+};
+
+/* Use this to see when all uarts are shutdown.  Or all are closed.
+ * We can only turn off RS232 chip if either of these are true.
+ */
+
+static int uart_wake_count[3] = {1, 1, 1};
+
+enum {UART_SHUTDOWN, UART_WAKEUP};
+
+static void update_uart_counts(int line, int state)
+{
+	switch (state) {
+	case UART_WAKEUP:
+		uart_wake_count[line]++;
+		break;
+	case UART_SHUTDOWN:
+		uart_wake_count[line]--;
+		break;
+	}
+}
+
+static int adsbitsyplus_uart_open(struct uart_port *port, struct uart_info *info)
+{
+	if (port->mapbase == _Ser1UTCR0) {
+		Ser1SDCR0 |= SDCR0_UART;
+	} else if (port->mapbase == _Ser2UTCR0) {
+		Ser2UTCR4 = Ser2HSCR0 = 0;
+	}
+	return 0;
+}
+
+void adsbitsyplus_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	// state has ACPI D0-D3
+	// ACPI D0 	  : resume from suspend
+	// ACPI D1-D3 : enter to a suspend state
+	if (port->mapbase == _Ser1UTCR0) {
+		if (state) {
+			update_uart_counts(1, UART_SHUTDOWN);
+                        // disable uart
+                        Ser1UTCR3 = 0;
+		}
+		else {
+			update_uart_counts(1, UART_WAKEUP);
+		}
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		if (state) {
+			update_uart_counts(2, UART_SHUTDOWN);
+                        // disable uart
+                        Ser2UTCR3 = 0;
+                        Ser2HSCR0 = 0;
+		}
+		else {
+			update_uart_counts(2, UART_WAKEUP);
+		}
+	}
+	else if (port->mapbase == _Ser3UTCR0) {
+		if (state) {
+			update_uart_counts(0, UART_SHUTDOWN);
+                        // disable uart
+                        Ser3UTCR3 = 0;
+		}
+		else {
+			update_uart_counts(0, UART_WAKEUP);
+		}
+	}
+        if (state == 0) {
+		// Turn power on if uarts are awake
+		if (uart_wake_count[0] + uart_wake_count[1] != 0) {
+			// make sure RS-232 is turned on if 1 or 3 are open
+			ADS_CPLD_PCON |= ADS_PCON_COM1_3_ON;
+		}
+		if (uart_wake_count[2] != 0) {
+			if (adsbitsyplus_connector_board_rev() >= 0x0a)
+				ADS_CPLD_PCON |= ADS_PCON_CONN_B_PE2;
+		}
+	}
+	else {
+		// Turn power off if uarts are asleep
+		if (uart_wake_count[0] + uart_wake_count[1] == 0) {
+			// save power if we are sleeping
+			ADS_CPLD_PCON &= ~ADS_PCON_COM1_3_ON;
+			GAFR &= ~(GPIO_GPIO15 | GPIO_GPIO19 | GPIO_GPIO20);
+			GPDR |= GPIO_GPIO15 | GPIO_GPIO19 | GPIO_GPIO20;
+		}
+		if (uart_wake_count[2] == 0) {
+			if (adsbitsyplus_connector_board_rev() >= 0x0a)
+				ADS_CPLD_PCON &= ~ADS_PCON_CONN_B_PE2;
+		}
+	}
+}
+
+static void adsbitsyplus_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	// note: only ports 1 and 3 have modem control
+	if (port->mapbase == _Ser1UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			// Set RTS High
+			GPCR = GPIO_GPIO15;
+		else
+			// Set RTS LOW
+			GPSR = GPIO_GPIO15;
+		if (mctrl & TIOCM_DTR)
+			// Set DTR High
+			GPCR = GPIO_GPIO20;
+		else
+			// Set DTR Low
+			GPSR = GPIO_GPIO20;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			// Set RTS High
+			GPCR = GPIO_GPIO19;
+		else
+			// Set RTS LOW
+			GPSR = GPIO_GPIO19;
+	}
+}
+
+static u_int adsbitsyplus_get_mctrl(struct uart_port *port)
+{
+	u_int ret = 0;
+
+	// note: only ports 1 and 3 have modem control
+	if (port->mapbase == _Ser1UTCR0) {
+		if (!(GPLR & GPIO_GPIO14))
+			ret |= TIOCM_CTS;
+		if (!(GPLR & GPIO_GPIO24))
+			ret |= TIOCM_DSR;
+		if (!(GPLR & GPIO_GPIO16))
+			ret |= TIOCM_RI;
+		if (!(GPLR & GPIO_GPIO17))
+			ret |= TIOCM_CD;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (!(GPLR & GPIO_GPIO18))
+			ret |= TIOCM_CTS;
+	}
+
+	return ret;
+}
+
+static struct sa1100_port_fns adsbitsyplus_port_fns __initdata = {
+	.set_mctrl =    adsbitsyplus_set_mctrl,
+	.get_mctrl =    adsbitsyplus_get_mctrl,
+	.open =	        adsbitsyplus_uart_open,
+	.pm =           adsbitsyplus_uart_pm,
+};
+
+static void __init adsbitsyplus_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(adsbitsyplus_io_desc);
+
+	sa1100_register_uart_fns(&adsbitsyplus_port_fns);
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1);
+
+	// don't register if you want to use IRDA
+#ifndef CONFIG_SA1100_FIR
+	sa1100_register_uart(2, 2);
+#endif
+
+	// COM1 Set RTS and DTR Output
+	GPDR |= GPIO_GPIO15 | GPIO_GPIO20;
+	// Set CTS, DSR, RI and CD Input
+	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO24 | GPIO_GPIO16 | GPIO_GPIO17);
+
+	// COM3 Set RTS Output
+	GPDR |= GPIO_GPIO19;
+	// Set CTS Input
+	GPDR &= ~GPIO_GPIO18;
+}
+
+__setup("adsbitsyplus_conn_board_rev=", adsbitsyplus_connector_board_rev_setup);
+
+MACHINE_START(ADSBITSYPLUS, "ADS Bitsy Plus")
+        BOOT_PARAMS(0xc000003c)
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	MAPIO(adsbitsyplus_map_io)
+	INITIRQ(adsbitsyplus_init_irq)
+MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/assabet.c linux-2.4.22-pre3/arch/arm/mach-sa1100/assabet.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/assabet.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/assabet.c	2003-07-05 18:09:36.000000000 -0700
@@ -42,7 +42,8 @@
 	 ASSABET_BCR_LED_GREEN  | ASSABET_BCR_LED_RED   | \
 	 ASSABET_BCR_RS232EN    | ASSABET_BCR_LCD_12RGB | \
 	 ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \
-	 ASSABET_BCR_IRDA_MD0   | ASSABET_BCR_CF_RST)
+	 ASSABET_BCR_IRDA_MD0   | ASSABET_BCR_CF_RST	| \
+	 ASSABET_BCR_CODEC_RST  )
 
 unsigned long SCR_value = ASSABET_SCR_INIT;
 EXPORT_SYMBOL(SCR_value);
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/cep.c linux-2.4.22-pre3/arch/arm/mach-sa1100/cep.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/cep.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/cep.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,123 @@
+/*
+ * linux/arch/arm/mach-sa1100/cep.c
+ *
+ * Author: Matthias Gorjup
+ *
+ * This file contains all Cep - specific tweaks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/serial_core.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include "generic.h"
+
+
+extern void convert_to_tag_list(struct param_struct *params, int mem_init);
+
+static void __init
+fixup_cep(struct machine_desc *desc, struct param_struct *params,
+	      char **cmdline, struct meminfo *mi)
+{
+	struct tag *t = (struct tag *)params;
+
+
+	/*
+	 * Apparantly bootldr uses a param_struct.  Groan.
+	 */
+	if (t->hdr.tag != ATAG_CORE)
+		convert_to_tag_list(params, 1);
+
+	if (t->hdr.tag != ATAG_CORE) {
+		t->hdr.tag = ATAG_CORE;
+		t->hdr.size = tag_size(tag_core);
+		t->u.core.flags = 0;
+		t->u.core.pagesize = PAGE_SIZE;
+		t->u.core.rootdev = RAMDISK_MAJOR << 8 | 0;
+		t = tag_next(t);
+
+		t->hdr.tag = ATAG_MEM;
+		t->hdr.size = tag_size(tag_mem32);
+		t->u.mem.start = 0xc0000000;
+		t->u.mem.size  = 32 * 1024 * 1024;
+		t = tag_next(t);
+
+
+		t->hdr.tag = ATAG_RAMDISK;
+		t->hdr.size = tag_size(tag_ramdisk);
+		t->u.ramdisk.flags = 1;
+		t->u.ramdisk.size = 8192;
+		t->u.ramdisk.start = 0;
+		t = tag_next(t);
+
+		t->hdr.tag = ATAG_INITRD;
+		t->hdr.size = tag_size(tag_initrd);
+		t->u.initrd.start = 0xc0800000;
+		t->u.initrd.size = 3 * 1024 * 1024;
+		t = tag_next(t);
+
+		t->hdr.tag = ATAG_NONE;
+		t->hdr.size = 0;
+	}
+}
+
+
+static struct map_desc cep_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  LAST_DESC
+};
+
+static void __init cep_map_io(void)
+{
+
+	sa1100_map_io();
+	iotable_init(cep_io_desc);
+
+	sa1100_register_uart(0, 1);	/* com port */
+	sa1100_register_uart(2, 3);	/* radio module */
+
+	/*
+	 * Ensure that these pins are set as outputs and are driving
+	 * logic 0.  This ensures that we won't inadvertently toggle
+	 * the WS latch in the CPLD, and we don't float causing
+	 * excessive power drain.  --rmk
+	 */
+	GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+	GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+
+	/*
+	 * Set up registers for sleep mode.
+	 */
+	PWER = PWER_GPIO0;
+	PGSR = 0;
+	PCFR = 0;
+	PSDR = 0;
+}
+
+
+MACHINE_START(CEP, "Iskratel Cep")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_cep)
+	MAPIO(cep_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/cpu-sa1110.c linux-2.4.22-pre3/arch/arm/mach-sa1100/cpu-sa1110.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/cpu-sa1110.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/cpu-sa1110.c	2003-07-05 18:09:36.000000000 -0700
@@ -49,33 +49,33 @@
 };
 
 static struct sdram_params tc59sm716_cl2_params __initdata = {
-	rows:		    12,
-	tck:		    10,
-	trcd:		    20,
-	trp:		    20,
-	twr:		    10,
-	refresh:	 64000,
-	cas_latency:	     2,
+	.rows		=    12,
+	.tck		=    10,
+	.trcd		=    20,
+	.trp		=    20,
+	.twr		=    10,
+	.refresh	= 64000,
+	.cas_latency	=     2,
 };
 
 static struct sdram_params tc59sm716_cl3_params __initdata = {
-	rows:		    12,
-	tck:		     8,
-	trcd:		    20,
-	trp:		    20,
-	twr:		     8,
-	refresh:	 64000,
-	cas_latency:	     3,
+	.rows		=    12,
+	.tck		=     8,
+	.trcd		=    20,
+	.trp		=    20,
+	.twr		=     8,
+	.refresh	= 64000,
+	.cas_latency	=     3,
 };
 
 static struct sdram_params samsung_k4s641632d_tc75 __initdata = {
-	rows:		    14,
-	tck:		     9,
-	trcd:		    27,
-	trp:		    20,
-	twr:		     9,
-	refresh:	 64000,
-	cas_latency:	     3,
+	.rows		=    14,
+	.tck		=     9,
+	.trcd		=    27,
+	.trp		=    20,
+	.twr		=     9,
+	.refresh	= 64000,
+	.cas_latency	=     3,
 };
 
 static struct sdram_params sdram_params;
@@ -235,21 +235,21 @@
 	 * the programming.
 	 */
 	local_irq_save(flags);
-	asm("mcr p15, 0, %0, c10, c4" : : "r" (0));
+	asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
 	udelay(10);
-	__asm__ __volatile__("
-		b	2f
-		.align	5
-1:		str	%3, [%1, #0]		@ MDCNFG
-		str	%4, [%1, #28]		@ MDREFR
-		str	%5, [%1, #4]		@ MDCAS0
-		str	%6, [%1, #8]		@ MDCAS1
-		str	%7, [%1, #12]		@ MDCAS2
-		str	%8, [%2, #0]		@ PPCR
-		ldr	%0, [%1, #0]
-		b	3f
-2:		b	1b
-3:		nop
+	__asm__ __volatile__("					\n\
+		b	2f					\n\
+		.align	5					\n\
+1:		str	%3, [%1, #0]		@ MDCNFG	\n\
+		str	%4, [%1, #28]		@ MDREFR	\n\
+		str	%5, [%1, #4]		@ MDCAS0	\n\
+		str	%6, [%1, #8]		@ MDCAS1	\n\
+		str	%7, [%1, #12]		@ MDCAS2	\n\
+		str	%8, [%2, #0]		@ PPCR		\n\
+		ldr	%0, [%1, #0]				\n\
+		b	3f					\n\
+2:		b	1b					\n\
+3:		nop						\n\
 		nop"
 		: "=&r" (unused)
 		: "r" (&MDCNFG), "r" (&PPCR), "0" (sd.mdcnfg),
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/dma-sa1100.c linux-2.4.22-pre3/arch/arm/mach-sa1100/dma-sa1100.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/dma-sa1100.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/dma-sa1100.c	2003-07-05 18:09:36.000000000 -0700
@@ -477,11 +477,11 @@
 		return sa1111_dma_resume(channel);
 
 	if (dma->stopped) {
-		int flags;
-		save_flags_cli(flags);
+		unsigned long flags;
+		local_irq_save(flags);
 		dma->stopped = 0;
 		process_dma(dma);
-		restore_flags(flags);
+		local_irq_restore(flags);
 	}
 	return 0;
 }
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/dma-sa1111.c linux-2.4.22-pre3/arch/arm/mach-sa1100/dma-sa1111.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/dma-sa1111.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/dma-sa1111.c	2003-07-05 18:09:36.000000000 -0700
@@ -305,7 +305,8 @@
 	 * SDRAM bank 1 on Neponset). The default configuration selects
 	 * Assabet, so any address in bank 1 is necessarily invalid.
 	 */
-	if((machine_is_assabet() || machine_is_pfs168()) && addr >= 0xc8000000)
+	if((machine_is_assabet() || machine_is_pfs168() ||
+            machine_is_graphicsmaster() || machine_is_adsagc()) && addr >= 0xc8000000)
 	  	return -1;
 
 	/* The bug only applies to buffers located more than one megabyte
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/flexanet.c linux-2.4.22-pre3/arch/arm/mach-sa1100/flexanet.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/flexanet.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/flexanet.c	2003-07-05 18:09:36.000000000 -0700
@@ -26,6 +26,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/serial_sa1100.h>
 #include <linux/serial_core.h>
+#include <asm/arch/flexanet.h>
 
 #include "generic.h"
 
@@ -145,6 +146,11 @@
 
 static int __init flexanet_init(void)
 {
+	/* Set IRQ edges */
+	set_GPIO_IRQ_edge(GPIO_GUI_IRQ, GPIO_RISING_EDGE);
+
+	/* deassert the GUI reset */
+	FLEXANET_BCR_set(FHH_BCR_GUI_NRST);
 	return 0;
 }
 
@@ -155,10 +161,6 @@
 fixup_flexanet(struct machine_desc *desc, struct param_struct *params,
 	      char **cmdline, struct meminfo *mi)
 {
-	int				status;
-	unsigned long	now;
-
-
 	/* fixed RAM size, by now (64MB) */
 	SET_BANK( 0, 0xc0000000, 64*1024*1024 );
 	mi->nr_banks = 1;
@@ -175,7 +177,7 @@
   { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
   { 0xf0000000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* Board Control Register */
   { 0xf1000000, 0x18000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Ethernet controller */
-  { 0xD0000000, 0x40000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Instrument boards */
+  { 0xD0000000, 0x40000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Instrument boards */
   { 0xD8000000, 0x48000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* External peripherals */
   LAST_DESC
 };
@@ -198,13 +200,6 @@
 	 */
 	PCFR = PCFR_OPDE | PCFR_FP | PCFR_FS;
 
-	/* deassert the GUI reset */
-	FLEXANET_BCR_set(FHH_BCR_GUI_NRST);
-
-	/*
-	 * Set IRQ edges
-	 */
-	set_GPIO_IRQ_edge(GPIO_GUI_IRQ, GPIO_RISING_EDGE);
 }
 
 
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/frodo.c linux-2.4.22-pre3/arch/arm/mach-sa1100/frodo.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/frodo.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/frodo.c	2003-07-05 18:09:36.000000000 -0700
@@ -12,15 +12,22 @@
  *
  * History:
  *
+ *   2002/05/27   Setup GPIOs for all the onboard peripherals so
+ *                that we don't have to do it in each driver
+ *
  *   2002/01/31   Initial version
  */
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/tty.h>
+#include <linux/spinlock.h>
 
-#include <asm/hardware.h>
 #include <asm/setup.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -28,30 +35,108 @@
 
 #include "generic.h"
 
-static struct map_desc frodo_io_desc[] __initdata =
-{
-  /* virtual     physical    length      domain     r  w  c  b */
-   { 0xe8000000, 0x00000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 },	/* flash memory */
-   { 0xf0000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 },	/* 16-bit on-board devices (including CPLDs) */
-   { 0xf1000000, 0x18000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 },	/* 32-bit daughter card */
-   LAST_DESC
+static struct map_desc frodo_io_desc[] __initdata = {
+	/* virtual     physical    length      domain     r  w  c  b */
+	{ 0xe8000000, 0x00000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 },	/* flash memory */
+	{ 0xf0000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 },	/* 16-bit on-board devices (including CPLDs) */
+	{ 0xf1000000, 0x18000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 },	/* 32-bit daughter card */
+	LAST_DESC
 };
 
+static spinlock_t frodo_cpld_lock = SPIN_LOCK_UNLOCKED;
+static volatile u16 *frodo_cpld_memory = (u16 *) 0xf0000000;
+
 static void __init frodo_map_io (void)
 {
-   sa1100_map_io ();
-   iotable_init (frodo_io_desc);
+	sa1100_map_io ();
+	iotable_init (frodo_io_desc);
+
+	sa1100_register_uart (0,2);		/* UART2 (serial console) */
+	sa1100_register_uart (1,1);		/* UART1 (big kahuna flow control serial port) */
+
+	/*
+	 * Set SUS bit in SDCR0 so serial port 1 acts as a UART.
+	 * See Intel SA-1110 Developers Manual Section 11.9.2.1 (GPCLK/UART Select)
+	 */
+	Ser1SDCR0 |= SDCR0_SUS;
+}
+
+static int __init frodo_init_irq(void)
+{
+	int i,gpio[] = {
+		FRODO_IDE_GPIO,
+		FRODO_ETH_GPIO,
+		FRODO_USB_DC_GPIO,
+		FRODO_USB_HC_GPIO,
+		FRODO_RTC_GPIO,
+		FRODO_UART1_GPIO,
+		FRODO_UART2_GPIO,
+		FRODO_PCMCIA_STATUS_GPIO,
+		FRODO_PCMCIA_RDYBSY_GPIO
+	};
+
+	for (i = 0; i < sizeof (gpio) / sizeof (gpio[0]); i++)
+		set_GPIO_IRQ_edge (gpio[i],GPIO_RISING_EDGE);
+
+	return (0);
+}
+
+__initcall(frodo_init_irq);
+#if 0
+static int __init frodo_init_cpld(void)
+{
+	if ((frodo_cpld_memory = ioremap (FRODO_CPLD_BASE,FRODO_CPLD_LENGTH)) == NULL)
+		panic ("Couldn't map CPLD memory to a virtual address. We're screwed!\n");
+
+	return (0);
+}
+
+__initcall(frodo_init_cpld);
+#endif
+u16 frodo_cpld_read (u32 reg)
+{
+	unsigned long flags;
+	u16 value;
+
+	spin_lock_irqsave (&frodo_cpld_lock,flags);
+	value = frodo_cpld_memory[reg / 2];
+	spin_unlock_irqrestore (&frodo_cpld_lock,flags);
+
+	return (value);
+}
+
+void frodo_cpld_write (u32 reg,u16 value)
+{
+	unsigned long flags;
 
-   sa1100_register_uart (0,2);	/* UART2 (serial console) */
-   sa1100_register_uart (1,1);	/* UART1 (big kahuna flow control serial port) */
+	spin_lock_irqsave (&frodo_cpld_lock,flags);
+	frodo_cpld_memory[reg / 2] = value;
+	spin_unlock_irqrestore (&frodo_cpld_lock,flags);
+}
+
+void frodo_cpld_set (u32 reg,u16 mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave (&frodo_cpld_lock,flags);
+	frodo_cpld_memory[reg / 2] |= mask;
+	spin_unlock_irqrestore (&frodo_cpld_lock,flags);
+}
+
+void frodo_cpld_clear (u32 reg,u16 mask)
+{
+	unsigned long flags;
 
-   /*
-	* Set SUS bit in SDCR0 so serial port 1 acts as a UART.
-	* See Intel SA-1110 Developers Manual Section 11.9.2.1 (GPCLK/UART Select)
-	*/
-   Ser1SDCR0 |= SDCR0_SUS;
+	spin_lock_irqsave (&frodo_cpld_lock,flags);
+	frodo_cpld_memory[reg / 2] &= ~mask;
+	spin_unlock_irqrestore (&frodo_cpld_lock,flags);
 }
 
+EXPORT_SYMBOL (frodo_cpld_read);
+EXPORT_SYMBOL (frodo_cpld_write);
+EXPORT_SYMBOL (frodo_cpld_set);
+EXPORT_SYMBOL (frodo_cpld_clear);
+
 MACHINE_START (FRODO,"2d3D, Inc. SA-1110 Development Board")
 	BOOT_MEM (0xc0000000,0x80000000,0xf8000000)
 	BOOT_PARAMS (0xc0000100)
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/generic.c linux-2.4.22-pre3/arch/arm/mach-sa1100/generic.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/generic.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/generic.c	2003-07-05 18:09:36.000000000 -0700
@@ -86,7 +86,7 @@
 
 static int __init sa11x0_init_clock(void)
 {
-	cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100, 0, 0);
+	cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100, 59000, 287000);
 	return 0;
 }
 
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/graphicsclient.c linux-2.4.22-pre3/arch/arm/mach-sa1100/graphicsclient.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/graphicsclient.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/graphicsclient.c	2003-07-05 18:09:36.000000000 -0700
@@ -14,6 +14,8 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/setup.h>
@@ -34,55 +36,58 @@
  * Handlers for GraphicsClient's external IRQ logic
  */
 
+#define GRAPHICSCLIENT_N_IRQ     (IRQ_GRAPHICSCLIENT_END - IRQ_GRAPHICSCLIENT_START)
+#define GRAPHICSCLIENT_FIRST_IRQ (IRQ_GRAPHICSCLIENT_CAN - IRQ_GRAPHICSCLIENT_START)
+
 static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
 {
 	int i;
 
 	while( (irq = ADS_INT_ST1 | (ADS_INT_ST2 << 8)) ){
-		for( i = 0; i < 16; i++ )
+		for( i = GRAPHICSCLIENT_FIRST_IRQ; i < GRAPHICSCLIENT_N_IRQ; i++ )
 			if( irq & (1<<i) )
-				do_IRQ( ADS_EXT_IRQ(i), regs );
+				do_IRQ( IRQ_GRAPHICSCLIENT_START + i, regs );
 	}
 }
 
 static struct irqaction ADS_ext_irq = {
-	name:		"ADS_ext_IRQ",
-	handler:	ADS_IRQ_demux,
-	flags:		SA_INTERRUPT
+	.name		= "ADS_ext_IRQ",
+	.handler	= ADS_IRQ_demux,
+	.flags		= SA_INTERRUPT
 };
 
 static void ADS_mask_and_ack_irq0(unsigned int irq)
 {
-	int mask = (1 << (irq - ADS_EXT_IRQ(0)));
+	int mask = (1 << (irq - IRQ_GRAPHICSCLIENT_START));
 	ADS_INT_EN1 &= ~mask;
 	ADS_INT_ST1 = mask;
 }
 
 static void ADS_mask_irq0(unsigned int irq)
 {
-	ADS_INT_ST1 = (1 << (irq - ADS_EXT_IRQ(0)));
+	ADS_INT_ST1 = (1 << (irq - IRQ_GRAPHICSCLIENT_START));
 }
 
 static void ADS_unmask_irq0(unsigned int irq)
 {
-	ADS_INT_EN1 |= (1 << (irq - ADS_EXT_IRQ(0)));
+	ADS_INT_EN1 |= (1 << (irq - IRQ_GRAPHICSCLIENT_START));
 }
 
 static void ADS_mask_and_ack_irq1(unsigned int irq)
 {
-	int mask = (1 << (irq - ADS_EXT_IRQ(8)));
+	int mask = (1 << (irq - (IRQ_GRAPHICSCLIENT_UCB1200)));
 	ADS_INT_EN2 &= ~mask;
 	ADS_INT_ST2 = mask;
 }
 
 static void ADS_mask_irq1(unsigned int irq)
 {
-	ADS_INT_ST2 = (1 << (irq - ADS_EXT_IRQ(8)));
+	ADS_INT_ST2 = (1 << (irq - (IRQ_GRAPHICSCLIENT_UCB1200)));
 }
 
 static void ADS_unmask_irq1(unsigned int irq)
 {
-	ADS_INT_EN2 |= (1 << (irq - ADS_EXT_IRQ(8)));
+	ADS_INT_EN2 |= (1 << (irq - (IRQ_GRAPHICSCLIENT_UCB1200)));
 }
 
 static void __init graphicsclient_init_irq(void)
@@ -99,14 +104,17 @@
 	ADS_INT_ST1 = 0xff;
 	ADS_INT_ST2 = 0xff;
 
-	for (irq = ADS_EXT_IRQ(0); irq <= ADS_EXT_IRQ(7); irq++) {
+	// Set RTS low during sleep
+	PGSR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+
+	for (irq = IRQ_GRAPHICSCLIENT_START; irq < IRQ_GRAPHICSCLIENT_UCB1200; irq++) {
 		irq_desc[irq].valid	= 1;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq0;
 		irq_desc[irq].mask	= ADS_mask_irq0;
 		irq_desc[irq].unmask	= ADS_unmask_irq0;
 	}
-	for (irq = ADS_EXT_IRQ(8); irq <= ADS_EXT_IRQ(15); irq++) {
+	for (irq = IRQ_GRAPHICSCLIENT_UCB1200; irq < IRQ_GRAPHICSCLIENT_END; irq++) {
 		irq_desc[irq].valid	= 1;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq1;
@@ -117,24 +125,6 @@
 	setup_arm_irq( IRQ_GPIO0, &ADS_ext_irq );
 }
 
-
-/*
- * Initialization fixup
- */
-
-static void __init
-fixup_graphicsclient(struct machine_desc *desc, struct param_struct *params,
-		     char **cmdline, struct meminfo *mi)
-{
-	SET_BANK( 0, 0xc0000000, 16*1024*1024 );
-	SET_BANK( 1, 0xc8000000, 16*1024*1024 );
-	mi->nr_banks = 2;
-
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-	setup_ramdisk( 1, 0, 0, 8192 );
-	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
-}
-
 static struct map_desc graphicsclient_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
   { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
@@ -143,120 +133,31 @@
   LAST_DESC
 };
 
-static struct gc_uart_ctrl_data_t gc_uart_ctrl_data[] = {
-  { GPIO_GC_UART0_CTS, 0, NULL,NULL },
-  { GPIO_GC_UART1_CTS, 0, NULL,NULL },
-  { GPIO_GC_UART2_CTS, 0, NULL,NULL }
-};
-
-static void
-graphicsclient_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct gc_uart_ctrl_data_t * uart_data = (struct gc_uart_ctrl_data_t *)dev_id;
-	int cts = !(GPLR & uart_data->cts_gpio);
-
-	/* NOTE: I supose that we will no get any interrupt
-	   if the GPIO is not changed, so maybe
-	   the cts_prev_state can be removed ... */
-	if (cts != uart_data->cts_prev_state) {
-		uart_data->cts_prev_state = cts;
-
-		uart_handle_cts_change(uart_data->info, cts);
-	}
-}
-
-static int
-graphicsclient_register_cts_intr(int gpio, int irq,
-				 struct gc_uart_ctrl_data_t *uart_data)
-{
-	int ret = 0;
-
-	set_GPIO_IRQ_edge(gpio, GPIO_BOTH_EDGES);
-
-	ret = request_irq(irq, graphicsclient_cts_intr,
-			  0, "GC RS232 CTS", uart_data);
-	if (ret) {
-		printk(KERN_ERR "uart_open: failed to register CTS irq (%d)\n",
-		       ret);
-		free_irq(irq, uart_data);
-	}
-
-	return ret;
-}
-
-static int
-graphicsclient_uart_open(struct uart_port *port, struct uart_info *info)
+static int graphicsclient_uart_open(struct uart_port *port, struct uart_info *info)
 {
-	int ret = 0;
+	int	ret = 0;
 
 	if (port->mapbase == _Ser1UTCR0) {
 		Ser1SDCR0 |= SDCR0_UART;
-		/* Set RTS Output */
-		GPSR  = GPIO_GC_UART0_RTS;
-
-		gc_uart_ctrl_data[0].cts_prev_state = 0;
-		gc_uart_ctrl_data[0].info = info;
-		gc_uart_ctrl_data[0].port = port;
-
-		/* register uart0 CTS irq */
-		ret = graphicsclient_register_cts_intr(GPIO_GC_UART0_CTS,
-							IRQ_GC_UART0_CTS,
-							&gc_uart_ctrl_data[0]);
-	} else if (port->mapbase == _Ser2UTCR0) {
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
 		Ser2UTCR4 = Ser2HSCR0 = 0;
-		/* Set RTS Output */
-		GPSR  = GPIO_GC_UART1_RTS;
-
-		gc_uart_ctrl_data[1].cts_prev_state = 0;
-		gc_uart_ctrl_data[1].info = info;
-		gc_uart_ctrl_data[1].port = port;
-
-		/* register uart1 CTS irq */
-		ret = graphicsclient_register_cts_intr(GPIO_GC_UART1_CTS,
-							IRQ_GC_UART1_CTS,
-							&gc_uart_ctrl_data[1]);
-	} else if (port->mapbase == _Ser3UTCR0) {
-		/* Set RTS Output */
-		GPSR =	GPIO_GC_UART2_RTS;
-
-		gc_uart_ctrl_data[2].cts_prev_state = 0;
-		gc_uart_ctrl_data[2].info = info;
-		gc_uart_ctrl_data[2].port = port;
-
-		/* register uart2 CTS irq */
-		ret = graphicsclient_register_cts_intr(GPIO_GC_UART2_CTS,
-							IRQ_GC_UART2_CTS,
-							&gc_uart_ctrl_data[2]);
 	}
 	return ret;
 }
 
-static int
-graphicsclient_uart_close(struct uart_port *port, struct uart_info *info)
-{
-	if (port->mapbase == _Ser1UTCR0) {
-		free_irq(IRQ_GC_UART0_CTS, &gc_uart_ctrl_data[0]);
-	} else if (port->mapbase == _Ser2UTCR0) {
-		free_irq(IRQ_GC_UART1_CTS, &gc_uart_ctrl_data[1]);
-	} else if (port->mapbase == _Ser3UTCR0) {
-		free_irq(IRQ_GC_UART2_CTS, &gc_uart_ctrl_data[2]);
-	}
-
-	return 0;
-}
-
 static u_int graphicsclient_get_mctrl(struct uart_port *port)
 {
 	u_int result = TIOCM_CD | TIOCM_DSR;
 
 	if (port->mapbase == _Ser1UTCR0) {
-		if (!(GPLR & GPIO_GC_UART0_CTS))
+		if (!(GPLR & GPIO_GPIO14))
 			result |= TIOCM_CTS;
 	} else if (port->mapbase == _Ser2UTCR0) {
-		if (!(GPLR & GPIO_GC_UART1_CTS))
+		if (!(GPLR & GPIO_GPIO16))
 			result |= TIOCM_CTS;
 	} else if (port->mapbase == _Ser3UTCR0) {
-		if (!(GPLR & GPIO_GC_UART2_CTS))
+		if (!(GPLR & GPIO_GPIO18))
 			result |= TIOCM_CTS;
 	} else {
 		result = TIOCM_CTS;
@@ -269,39 +170,54 @@
 {
 	if (port->mapbase == _Ser1UTCR0) {
 		if (mctrl & TIOCM_RTS)
-			GPCR = GPIO_GC_UART0_RTS;
+			GPCR = GPIO_GPIO15;
 		else
-			GPSR = GPIO_GC_UART0_RTS;
+			GPSR = GPIO_GPIO15;
 	} else if (port->mapbase == _Ser2UTCR0) {
 		if (mctrl & TIOCM_RTS)
-			GPCR = GPIO_GC_UART1_RTS;
+			GPCR = GPIO_GPIO17;
 		else
-			GPSR = GPIO_GC_UART1_RTS;
+			GPSR = GPIO_GPIO17;
 	} else if (port->mapbase == _Ser3UTCR0) {
 		if (mctrl & TIOCM_RTS)
-			GPCR = GPIO_GC_UART2_RTS;
+			GPCR = GPIO_GPIO19;
 		else
-			GPSR = GPIO_GC_UART2_RTS;
+			GPSR = GPIO_GPIO19;
 	}
 }
 
 static void
 graphicsclient_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 {
-	if (!state) {
-		/* make serial ports work ... */
-		Ser2UTCR4 = 0;
-		Ser2HSCR0 = 0; 
-		Ser1SDCR0 |= SDCR0_UART;
+	// state has ACPI D0-D3
+	// ACPI D0 	  : resume from suspend
+	// ACPI D1-D3 : enter to a suspend state
+	if (port->mapbase == _Ser1UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser1UTCR3 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser2UTCR3 = 0;
+                        Ser2HSCR0 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser3UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser3UTCR3 = 0;
+		}
 	}
 }
 
 static struct sa1100_port_fns graphicsclient_port_fns __initdata = {
-	open:		graphicsclient_uart_open,
-	close:		graphicsclient_uart_close,
-	get_mctrl:	graphicsclient_get_mctrl,
-	set_mctrl:	graphicsclient_set_mctrl,
-	pm:		graphicsclient_uart_pm,
+	.open		= graphicsclient_uart_open,
+	.get_mctrl	= graphicsclient_get_mctrl,
+	.set_mctrl	= graphicsclient_set_mctrl,
+	.pm		= graphicsclient_uart_pm,
 };
 
 static void __init graphicsclient_map_io(void)
@@ -312,14 +228,20 @@
 	sa1100_register_uart_fns(&graphicsclient_port_fns);
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
+
+	// don't register if you want to use IRDA
+#ifndef CONFIG_SA1100_FIR
 	sa1100_register_uart(2, 2);
-	GPDR |= GPIO_GC_UART0_RTS | GPIO_GC_UART1_RTS | GPIO_GC_UART2_RTS;
-	GPDR &= ~(GPIO_GC_UART0_CTS | GPIO_GC_UART1_RTS | GPIO_GC_UART2_RTS);
+#endif
+
+	/* set GPDR now */
+	GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+       	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18);
 }
 
 MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient")
+        BOOT_PARAMS(0xc000003c)
 	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	FIXUP(fixup_graphicsclient)
 	MAPIO(graphicsclient_map_io)
 	INITIRQ(graphicsclient_init_irq)
 MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/graphicsmaster.c linux-2.4.22-pre3/arch/arm/mach-sa1100/graphicsmaster.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/graphicsmaster.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/graphicsmaster.c	2003-07-05 18:09:36.000000000 -0700
@@ -12,8 +12,13 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
+#include <linux/serial_core.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
+#include <asm/hardware/sa1111.h>
 #include <asm/setup.h>
 #include <asm/irq.h>
 
@@ -40,6 +45,15 @@
 	 */
 	sa1110_mb_disable();
 
+	/* GraphicsMaster uses GPIO pins for SPI interface to AVR
+	 */
+
+	/* use the alternate SSP pins */
+	PPAR |= PPAR_SSPGPIO;
+
+	// Set RTS low during sleep
+	PGSR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+
 	/*
 	 * Probe for SA1111.
 	 */
@@ -67,9 +81,11 @@
 	 * Enable PWM control for LCD
 	 */
 	SKPCR |= SKPCR_PWMCLKEN;
-	SKPWM0 = 0x7F;				// VEE
+	SACR1 &= ~SACR1_L3EN;
+	ADS_DCR |= DCR_BACKLITE_ON;
+	SKPWM0 = 0x01;				// Backlight
 	SKPEN0 = 1;
-	SKPWM1 = 0x01;				// Backlight
+	SKPWM1 = 0x7F;				// VEE
 	SKPEN1 = 1;
 
 	/*
@@ -83,7 +99,7 @@
 	 */
 	sa1110_mb_enable();
 
-	sa1111_init_irq(ADS_EXT_IRQ(0));
+	sa1111_init_irq(IRQ_GRAPHICSMASTER_SA1111);
 
 	return 0;
 }
@@ -94,56 +110,58 @@
  * Handlers for GraphicsMaster's external IRQ logic
  */
 
+#define GRAPHICSMASTER_N_IRQ (IRQ_GRAPHICSMASTER_END - IRQ_GRAPHICSMASTER_START)
+
 static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
 {
 	int i;
 
 	while( (irq = ADS_INT_ST1 | (ADS_INT_ST2 << 8)) ){
-		for( i = 0; i < 16; i++ )
+		for( i = 0; i < GRAPHICSMASTER_N_IRQ; i++ )
 			if( irq & (1<<i) ) {
-				do_IRQ( ADS_EXT_IRQ(i), regs );
+				do_IRQ( IRQ_GRAPHICSMASTER_START + i, regs );
 			}
 	}
 }
 
 static struct irqaction ADS_ext_irq = {
-	name:		"ADS_ext_IRQ",
-	handler:	ADS_IRQ_demux,
-	flags:		SA_INTERRUPT
+	.name		= "ADS_ext_IRQ",
+	.handler	= ADS_IRQ_demux,
+	.flags		= SA_INTERRUPT
 };
 
 static void ADS_mask_and_ack_irq0(unsigned int irq)
 {
-	int mask = (1 << (irq - ADS_EXT_IRQ(0)));
+	int mask = (1 << (irq - IRQ_GRAPHICSMASTER_START));
 	ADS_INT_EN1 &= ~mask;
 	ADS_INT_ST1 = mask;
 }
 
 static void ADS_mask_irq0(unsigned int irq)
 {
-	ADS_INT_ST1 = (1 << (irq - ADS_EXT_IRQ(0)));
+	ADS_INT_ST1 = (1 << (irq - IRQ_GRAPHICSMASTER_START));
 }
 
 static void ADS_unmask_irq0(unsigned int irq)
 {
-	ADS_INT_EN1 |= (1 << (irq - ADS_EXT_IRQ(0)));
+	ADS_INT_EN1 |= (1 << (irq - IRQ_GRAPHICSMASTER_START));
 }
 
 static void ADS_mask_and_ack_irq1(unsigned int irq)
 {
-	int mask = (1 << (irq - ADS_EXT_IRQ(8)));
+	int mask = (1 << (irq - (IRQ_GRAPHICSMASTER_UCB1200)));
 	ADS_INT_EN2 &= ~mask;
 	ADS_INT_ST2 = mask;
 }
 
 static void ADS_mask_irq1(unsigned int irq)
 {
-	ADS_INT_ST2 = (1 << (irq - ADS_EXT_IRQ(8)));
+	ADS_INT_ST2 = (1 << (irq - (IRQ_GRAPHICSMASTER_UCB1200)));
 }
 
 static void ADS_unmask_irq1(unsigned int irq)
 {
-	ADS_INT_EN2 |= (1 << (irq - ADS_EXT_IRQ(8)));
+	ADS_INT_EN2 |= (1 << (irq - (IRQ_GRAPHICSMASTER_UCB1200)));
 }
 
 static void __init graphicsmaster_init_irq(void)
@@ -160,43 +178,27 @@
 	ADS_INT_ST1 = 0xff;
 	ADS_INT_ST2 = 0xff;
 
-	for (irq = ADS_EXT_IRQ(0); irq <= ADS_EXT_IRQ(7); irq++) {
+	for (irq = IRQ_GRAPHICSMASTER_START; irq < IRQ_GRAPHICSMASTER_UCB1200; irq++) {
 		irq_desc[irq].valid	= 1;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq0;
 		irq_desc[irq].mask	= ADS_mask_irq0;
 		irq_desc[irq].unmask	= ADS_unmask_irq0;
 	}
-	for (irq = ADS_EXT_IRQ(8); irq <= ADS_EXT_IRQ(15); irq++) {
+	for (irq = IRQ_GRAPHICSMASTER_UCB1200; irq < IRQ_GRAPHICSMASTER_END; irq++) {
 		irq_desc[irq].valid	= 1;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq1;
 		irq_desc[irq].mask	= ADS_mask_irq1;
 		irq_desc[irq].unmask	= ADS_unmask_irq1;
 	}
+
+	GPDR &= ~GPIO_GPIO0;
 	set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_FALLING_EDGE);
 	setup_arm_irq( IRQ_GPIO0, &ADS_ext_irq );
 }
 
 
-/*
- * Initialization fixup
- */
-
-static void __init
-fixup_graphicsmaster(struct machine_desc *desc, struct param_struct *params,
-		     char **cmdline, struct meminfo *mi)
-{
-	SET_BANK( 0, 0xc0000000, 16*1024*1024 );
-	mi->nr_banks = 1;
-	SET_BANK( 1, 0xc8000000, 16*1024*1024 );
-	mi->nr_banks = 2;
-
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-	setup_ramdisk( 1, 0, 0, 8192 );
-	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
-}
-
 static struct map_desc graphicsmaster_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
   { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
@@ -212,17 +214,9 @@
 
 	if (port->mapbase == _Ser1UTCR0) {
 		Ser1SDCR0 |= SDCR0_UART;
-		/* Set RTS Output */
-		GPSR = GPIO_GPIO15;
 	}
 	else if (port->mapbase == _Ser2UTCR0) {
 		Ser2UTCR4 = Ser2HSCR0 = 0;
-		/* Set RTS Output */
-		GPSR = GPIO_GPIO17;
-	}
-	else if (port->mapbase == _Ser3UTCR0) {
-	        /* Set RTS Output */
-		GPSR = GPIO_GPIO19;
 	}
 	return ret;
 }
@@ -238,7 +232,7 @@
 		if (!(GPLR & GPIO_GPIO16))
 			result |= TIOCM_CTS;
 	} else if (port->mapbase == _Ser3UTCR0) {
-		if (!(GPLR & GPIO_GPIO17))
+		if (!(GPLR & GPIO_GPIO18))
 			result |= TIOCM_CTS;
 	} else {
 		result = TIOCM_CTS;
@@ -270,19 +264,35 @@
 static void
 graphicsmaster_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 {
-	if (!state) {
-		/* make serial ports work ... */
-		Ser2UTCR4 = 0;
-		Ser2HSCR0 = 0; 
-		Ser1SDCR0 |= SDCR0_UART;
+	// state has ACPI D0-D3
+	// ACPI D0 	  : resume from suspend
+	// ACPI D1-D3 : enter to a suspend state
+	if (port->mapbase == _Ser1UTCR0) {
+		if (state) {
+			// disable uart
+			Ser1UTCR3 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		if (state) {
+			// disable uart
+			Ser2UTCR3 = 0;
+			Ser2HSCR0 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser3UTCR0) {
+		if (state) {
+			// disable uart
+			Ser3UTCR3 = 0;
+		}
 	}
 }
 
 static struct sa1100_port_fns graphicsmaster_port_fns __initdata = {
-	open:		graphicsmaster_uart_open,
-	get_mctrl:	graphicsmaster_get_mctrl,
-	set_mctrl:	graphicsmaster_set_mctrl,
-	pm:		graphicsmaster_uart_pm,
+	.open		= graphicsmaster_uart_open,
+	.get_mctrl	= graphicsmaster_get_mctrl,
+	.set_mctrl	= graphicsmaster_set_mctrl,
+	.pm		= graphicsmaster_uart_pm,
 };
 
 static void __init graphicsmaster_map_io(void)
@@ -293,7 +303,10 @@
 	sa1100_register_uart_fns(&graphicsmaster_port_fns);
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
+	// don't register if you want to use IRDA
+#ifndef CONFIG_SA1100_FIR
 	sa1100_register_uart(2, 2);
+#endif
 
 	/* set GPDR now */
 	GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
@@ -301,8 +314,8 @@
 }
 
 MACHINE_START(GRAPHICSMASTER, "ADS GraphicsMaster")
+	BOOT_PARAMS(0xc000003c)
 	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	FIXUP(fixup_graphicsmaster)
 	MAPIO(graphicsmaster_map_io)
 	INITIRQ(graphicsmaster_init_irq)
 MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/h3600.c linux-2.4.22-pre3/arch/arm/mach-sa1100/h3600.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/h3600.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/h3600.c	2003-07-05 18:09:36.000000000 -0700
@@ -394,16 +394,16 @@
 
 static void h3600_dcd_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct uart_info *info = dev_id;
+	struct uart_port *port = dev_id;
 	/* Note: should only call this if something has changed */
-	uart_handle_dcd_change(info, !(GPLR & GPIO_H3600_COM_DCD));
+	uart_handle_dcd_change(port, !(GPLR & GPIO_H3600_COM_DCD));
 }
 
 static void h3600_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct uart_info *info = dev_id;
+	struct uart_port *port = dev_id;
 	/* Note: should only call this if something has changed */
-	uart_handle_cts_change(info, !(GPLR & GPIO_H3600_COM_CTS));
+	uart_handle_cts_change(port, !(GPLR & GPIO_H3600_COM_CTS));
 }
 
 static void h3600_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
@@ -433,7 +433,7 @@
 	return err;
 }
 
-static int h3600_uart_open(struct uart_port *port, struct uart_info *info)
+static int h3600_uart_open(struct uart_port *port)
 {
 	int ret = 0;
 
@@ -447,23 +447,23 @@
 				  GPIO_BOTH_EDGES);
 
 		ret = request_irq(IRQ_GPIO_H3600_COM_DCD, h3600_dcd_intr,
-				  0, "RS232 DCD", info);
+				  0, "RS232 DCD", port);
 		if (ret)
 			return ret;
 
 		ret = request_irq(IRQ_GPIO_H3600_COM_CTS, h3600_cts_intr,
-				  0, "RS232 CTS", info);
+				  0, "RS232 CTS", port);
 		if (ret)
-			free_irq(IRQ_GPIO_H3600_COM_DCD, info);
+			free_irq(IRQ_GPIO_H3600_COM_DCD, port);
 	}
 	return ret;
 }
 
-static void h3600_uart_close(struct uart_port *port, struct uart_info *info)
+static void h3600_uart_close(struct uart_port *port)
 {
 	if (port->mapbase == _Ser3UTCR0) {
-		free_irq(IRQ_GPIO_H3600_COM_DCD, info);
-		free_irq(IRQ_GPIO_H3600_COM_CTS, info);
+		free_irq(IRQ_GPIO_H3600_COM_DCD, port);
+		free_irq(IRQ_GPIO_H3600_COM_CTS, port);
 	}
 }
 
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/hackkit.c linux-2.4.22-pre3/arch/arm/mach-sa1100/hackkit.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/hackkit.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/hackkit.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,221 @@
+/*
+ * linux/arch/arm/mach-sa1100/hackkit.c
+ *
+ * Copyright (C) 2002 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>
+ *
+ * This file contains all HackKit tweaks. Based on original work from
+ * Nicolas Pitre's assabet fixes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/cpufreq.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include <linux/serial_core.h>
+
+#include "generic.h"
+
+#define DEBUG 1
+
+#ifdef DEBUG
+#	define DPRINTK( x, args... )	printk( "%s: line %d: "x, __FUNCTION__, __LINE__, ## args  );
+#else
+#	define DPRINTK( x, args... )	/* nix */
+#endif
+
+/**********************************************************************
+ *  prototypes
+ */
+
+/* init funcs */
+static void __init fixup_hackkit(struct machine_desc *desc,
+		struct param_struct *params, char **cmdline, struct meminfo *mi);
+static void __init get_hackkit_scr(void);
+static int __init hackkit_init(void);
+static void __init hackkit_init_irq(void);
+static void __init hackkit_map_io(void);
+
+static int hackkit_get_mctrl(struct uart_port *port);
+static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl);
+static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate);
+
+extern void convert_to_tag_list(struct param_struct *params, int mem_init);
+
+
+/**********************************************************************
+ *  global data
+ */
+
+/**********************************************************************
+ *  static data
+ */
+
+static struct map_desc hackkit_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  LAST_DESC
+};
+
+static struct sa1100_port_fns hackkit_port_fns __initdata = {
+	.set_mctrl	= hackkit_set_mctrl,
+	.get_mctrl	= hackkit_get_mctrl,
+	.pm		= hackkit_uart_pm,
+};
+
+/**********************************************************************
+ *  Static functions
+ */
+
+static void __init hackkit_map_io(void)
+{
+	DPRINTK( "%s\n", "START" );
+	sa1100_map_io();
+	iotable_init(hackkit_io_desc);
+
+	sa1100_register_uart_fns(&hackkit_port_fns);
+	sa1100_register_uart(0, 1);	/* com port */
+	sa1100_register_uart(1, 2);
+	sa1100_register_uart(2, 3);	/* radio module */
+
+	Ser1SDCR0 |= SDCR0_SUS;
+}
+
+static void __init hackkit_init_irq(void)
+{
+	/* none used yet */
+}
+
+/**
+ *	fixup_hackkit - fixup function for system 3 board
+ *	@desc:		machine description
+ *	@param:		kernel params
+ *	@cmdline:	kernel cmdline
+ *	@mi:		memory info struct
+ *
+ */
+static void __init fixup_hackkit(struct machine_desc *desc,
+		struct param_struct *params, char **cmdline, struct meminfo *mi)
+{
+	DPRINTK( "%s\n", "START" );
+
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+	setup_ramdisk( 1, 0, 0, 8192 );
+	setup_initrd( 0xc0800000, 8*1024*1024 );
+}
+
+
+/**
+ *	hackkit_uart_pm - powermgmt callback function for system 3 UART
+ *	@port: uart port structure
+ *	@state: pm state
+ *	@oldstate: old pm state
+ *
+ */
+static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	/* TODO: switch on/off uart in powersave mode */
+}
+
+/*
+ * Note! this can be called from IRQ context.
+ * FIXME: No modem ctrl lines yet.
+ */
+static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+#if 0
+	if (port->mapbase == _Ser1UTCR0) {
+		u_int set = 0, clear = 0;
+
+		if (mctrl & TIOCM_RTS)
+			set |= PT_CTRL2_RS1_RTS;
+		else
+			clear |= PT_CTRL2_RS1_RTS;
+
+		if (mctrl & TIOCM_DTR)
+			set |= PT_CTRL2_RS1_DTR;
+		else
+			clear |= PT_CTRL2_RS1_DTR;
+
+		PTCTRL2_clear(clear);
+		PTCTRL2_set(set);
+	}
+#endif
+}
+
+static int hackkit_get_mctrl(struct uart_port *port)
+{
+	u_int ret = 0;
+#if 0
+	u_int irqsr = PT_IRQSR;
+
+	/* need 2 reads to read current value */
+	irqsr = PT_IRQSR;
+
+	/* TODO: check IRQ source register for modem/com
+	 status lines and set them correctly. */
+#endif
+
+	ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+
+	return ret;
+}
+
+static int __init hackkit_init(void)
+{
+	int ret = 0;
+	DPRINTK( "%s\n", "START" );
+
+	if ( !machine_is_hackkit() ) {
+		ret = -EINVAL;
+		goto DONE;
+	}
+
+	hackkit_init_irq();
+
+	ret = 0;
+DONE:
+	DPRINTK( "ret=%d\n", ret );
+	return ret;
+}
+
+/**********************************************************************
+ *  Exported Functions
+ */
+
+/**********************************************************************
+ *  kernel magic macros
+ */
+__initcall(hackkit_init);
+
+MACHINE_START(HACKKIT, "HackKit Cpu Board")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_hackkit)
+	MAPIO(hackkit_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/irq.c linux-2.4.22-pre3/arch/arm/mach-sa1100/irq.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/irq.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/irq.c	2003-07-05 18:09:36.000000000 -0700
@@ -15,6 +15,8 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/ptrace.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
@@ -30,9 +32,9 @@
  * This must be called *before* the appropriate IRQ is registered.
  * Use this instead of directly setting GRER/GFER.
  */
-
 static int GPIO_IRQ_rising_edge;
 static int GPIO_IRQ_falling_edge;
+static int GPIO_IRQ_mask = (1 << 11) - 1;
 
 void set_GPIO_IRQ_edge(int gpio_mask, int edge)
 {
@@ -51,6 +53,8 @@
 		GPIO_IRQ_rising_edge &= ~gpio_mask;
 	GPDR &= ~gpio_mask;
 	GAFR &= ~gpio_mask;
+	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
+	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
 	while (gpio_mask) {
 		if (irq == 11)
 			irq = IRQ_GPIO11;
@@ -86,8 +90,10 @@
 
 static void sa1100_mask_and_ack_GPIO0_10_irq(unsigned int irq)
 {
-	ICMR &= ~(1 << irq);
-	GEDR = (1 << irq);
+	unsigned int mask = 1 << irq;
+
+	ICMR &= ~mask;
+	GEDR = mask;
 }
 
 static void sa1100_mask_GPIO0_10_irq(unsigned int irq)
@@ -97,16 +103,13 @@
 
 static void sa1100_unmask_GPIO0_10_irq(unsigned int irq)
 {
-	GRER = (GRER & ~(1 << irq)) | (GPIO_IRQ_rising_edge & (1 << irq));
-	GFER = (GFER & ~(1 << irq)) | (GPIO_IRQ_falling_edge & (1 << irq));
-	ICMR |= (1 << irq);
+	ICMR |= 1 << irq;
 }
 
 /*
  * Install handler for GPIO 11-27 edge detect interrupts
  */
 
-static int GPIO_11_27_enabled;		/* enabled i.e. unmasked GPIO IRQs */
 static int GPIO_11_27_spurious;		/* GPIOs that triggered when masked */
 
 static void sa1100_GPIO11_27_demux(int irq, void *dev_id,
@@ -124,7 +127,7 @@
 		 * enabled at this point are considered spurious.  Those
 		 * are cleared but only de-activated if they happen twice.
 		 */
-		spurious = irq & ~GPIO_11_27_enabled;
+		spurious = irq & ~GPIO_IRQ_mask;
 		if (spurious) {
 			GEDR = spurious;
 			GRER &= ~(spurious & GPIO_11_27_spurious);
@@ -143,29 +146,29 @@
 }
 
 static struct irqaction GPIO11_27_irq = {
-	name:		"GPIO 11-27",
-	handler:	sa1100_GPIO11_27_demux,
-	flags:		SA_INTERRUPT
+	.name		= "GPIO 11-27",
+	.handler	= sa1100_GPIO11_27_demux,
+	.flags		= SA_INTERRUPT
 };
 
 static void sa1100_mask_and_ack_GPIO11_27_irq(unsigned int irq)
 {
-	int mask = (1 << GPIO_11_27_IRQ(irq));
+	unsigned int mask = (1 << GPIO_11_27_IRQ(irq));
 	GPIO_11_27_spurious &= ~mask;
-	GPIO_11_27_enabled &= ~mask;
+	GPIO_IRQ_mask &= ~mask;
 	GEDR = mask;
 }
 
 static void sa1100_mask_GPIO11_27_irq(unsigned int irq)
 {
-	int mask = (1 << GPIO_11_27_IRQ(irq));
+	unsigned int mask = (1 << GPIO_11_27_IRQ(irq));
 	GPIO_11_27_spurious &= ~mask;
-	GPIO_11_27_enabled &= ~mask;
+	GPIO_IRQ_mask &= ~mask;
 }
 
 static void sa1100_unmask_GPIO11_27_irq(unsigned int irq)
 {
-	int mask = (1 << GPIO_11_27_IRQ(irq));
+	unsigned int mask = (1 << GPIO_11_27_IRQ(irq));
 	if (GPIO_11_27_spurious & mask) {
 		/*
 		 * We don't want to miss an interrupt that would have occurred
@@ -185,15 +188,17 @@
 			return;
 		}
 	}
-	GPIO_11_27_enabled |= mask;
-	GRER = (GRER & ~mask) | (GPIO_IRQ_rising_edge & mask);
-	GFER = (GFER & ~mask) | (GPIO_IRQ_falling_edge & mask);
+
+	GPIO_IRQ_mask |= mask;
+
+	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
+	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
 }
 
 static struct resource irq_resource = {
-	name:	"irqs",
-	start:	0x90050000,
-	end:	0x9005ffff,
+	.name	= "irqs",
+	.start	= 0x90050000,
+	.end	= 0x9005ffff,
 };
 
 void __init sa1100_init_irq(void)
@@ -248,10 +253,4 @@
 		irq_desc[irq].unmask	= sa1100_unmask_GPIO11_27_irq;
 	}
 	setup_arm_irq( IRQ_GPIO11_27, &GPIO11_27_irq );
-
-	/*
-	 * We generally don't want the LCD IRQ being
-	 * enabled as soon as we request it.
-	 */
-	irq_desc[IRQ_LCD].noautoenable = 1;
 }
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/jornada720.c linux-2.4.22-pre3/arch/arm/mach-sa1100/jornada720.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/jornada720.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/jornada720.c	2003-07-05 18:09:36.000000000 -0700
@@ -8,6 +8,8 @@
 #include <linux/delay.h>
 
 #include <asm/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/irq.h>
 #include <asm/setup.h>
 
 #include <asm/mach/arch.h>
@@ -34,7 +36,7 @@
 	udelay(1);
 	GPSR = GPIO_GPIO20;
 	udelay(20);
-	SKCR = JORSKCR_INIT;	/* Turn on the PLL, enable Ready and enable nOE assertion from DC */
+	SBI_SKCR = JORSKCR_INIT;/* Turn on the PLL, enable Ready and enable nOE assertion from DC */
 	mdelay(100);
 
 	SBI_SKCR = JORSKCR_RCLK;/* turn on the RCLOCK */
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-adsagc.c linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-adsagc.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-adsagc.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-adsagc.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,107 @@
+/*
+ *  linux/arch/arm/mach-sa1100/leds-adsagc.c
+ *
+ * ADS Advanced Graphics Client LEDs support
+ * Robert Whaley, Feb 7, 2003
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_TIMER       ADS_LED0  /* green heartbeat */
+#define LED_USER        ADS_LED1  /* amber, boots to on */
+#define LED_IDLE        ADS_LED2  /* red has the idle led, if any */
+
+#define LED_MASK	(ADS_LED0|ADS_LED1|ADS_LED2)
+
+void adsagc_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch (evt) {
+	case led_start:
+		hw_led_state = 0;        /* gc leds are positive logic */
+		led_state = LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = LED_MASK;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = LED_MASK;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state ^= LED_TIMER;
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state &= ~LED_IDLE;
+		break;
+
+	case led_idle_end:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state |= LED_IDLE;
+		break;
+#endif
+
+	case led_green_on:
+		break;
+
+	case led_green_off:
+		break;
+
+	case led_amber_on:
+		hw_led_state |= LED_USER;
+		break;
+
+	case led_amber_off:
+		hw_led_state &= ~LED_USER;
+		break;
+
+	case led_red_on:
+		break;
+
+	case led_red_off:
+		break;
+
+	default:
+		break;
+	}
+
+	if  (led_state & LED_STATE_ENABLED) {
+
+	        unsigned char ads_cr3 = ADS_CR3;
+		ads_cr3 &= ~LED_MASK;
+		ads_cr3 |= hw_led_state;
+		ADS_CR3 = ads_cr3;
+	}
+
+	local_irq_restore(flags);
+}
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-adsbitsy.c linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-adsbitsy.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-adsbitsy.c	2001-10-25 13:53:46.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-adsbitsy.c	2003-07-05 18:09:36.000000000 -0700
@@ -28,7 +28,7 @@
 {
 	unsigned long flags;
 
-	save_flags_cli(flags);
+	local_irq_save(flags);
 
 	switch (evt) {
 	case led_start:
@@ -92,5 +92,5 @@
 		GPCR = hw_led_state ^ LED_MASK;
 	}
 
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-adsbitsyplus.c linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-adsbitsyplus.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-adsbitsyplus.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-adsbitsyplus.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,97 @@
+/*
+ *  linux/arch/arm/mach-sa1100/leds-adsbitsy.c
+ *
+ * ADS Bitsy LED
+ * 2/7/2003 Robert Whaley
+ * This file comes from leds-adsbitsy.c of Woojung Huh <whuh@applieddata.net>
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_TIMER       GPIO_GPIO20  /* green heartbeat */
+
+#define LED_MASK		(LED_TIMER)
+
+void adsbitsyplus_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch (evt) {
+	case led_start:
+		hw_led_state = 0;        /* gc leds are positive logic */
+		led_state = LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = LED_MASK;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = LED_MASK;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state ^= LED_TIMER;
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		break;
+
+	case led_idle_end:
+		break;
+#endif
+
+	case led_green_on:
+		break;
+
+	case led_green_off:
+		break;
+
+	case led_amber_on:
+		break;
+
+	case led_amber_off:
+		break;
+
+	case led_red_on:
+		break;
+
+	case led_red_off:
+		break;
+
+	default:
+		break;
+	}
+
+	if  (led_state & LED_STATE_ENABLED) {
+		GPSR = hw_led_state;
+		GPCR = hw_led_state ^ LED_MASK;
+	}
+
+	local_irq_restore(flags);
+}
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-frodo.c linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-frodo.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-frodo.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-frodo.c	2003-07-05 18:09:36.000000000 -0700
@@ -22,22 +22,22 @@
 
 #include "leds.h"
 
-#define led6_on() FRODO_CPLD_GENERAL |= FRODO_LED2
-#define led6_off() FRODO_CPLD_GENERAL &= ~FRODO_LED2
-#define led6_invert() do {						\
-		if ((FRODO_CPLD_GENERAL & FRODO_LED2))	\
-			led6_off ();						\
-		else									\
-			led6_on ();							\
+#define led6_on() frodo_cpld_set (FRODO_CPLD_GENERAL,FRODO_LED2)
+#define led6_off() frodo_cpld_clear (FRODO_CPLD_GENERAL,FRODO_LED2)
+#define led6_invert() do {											\
+		if ((frodo_cpld_read (FRODO_CPLD_GENERAL) & FRODO_LED2))	\
+			led6_off ();											\
+		else														\
+			led6_on ();												\
 	} while (0)
 
-#define led7_on() FRODO_CPLD_GENERAL |= FRODO_LED1
-#define led7_off() FRODO_CPLD_GENERAL &= ~FRODO_LED1
+#define led7_on() frodo_cpld_set (FRODO_CPLD_GENERAL,FRODO_LED1)
+#define led7_off() frodo_cpld_clear (FRODO_CPLD_GENERAL,FRODO_LED1)
 #define led7_invert() do {						\
-		if ((FRODO_CPLD_GENERAL & FRODO_LED1))	\
-			led7_off ();						\
-		else									\
-			led7_on ();							\
+		if ((frodo_cpld_read (FRODO_CPLD_GENERAL) & FRODO_LED1))	\
+			led7_off ();											\
+		else														\
+			led7_on ();												\
 	} while (0)
 
 static int claimed;
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-graphicsclient.c linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-graphicsclient.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-graphicsclient.c	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-graphicsclient.c	2003-07-05 18:09:36.000000000 -0700
@@ -30,7 +30,7 @@
 {
 	unsigned long flags;
 
-	save_flags_cli(flags);
+	local_irq_save(flags);
 
 	switch (evt) {
 	case led_start:
@@ -100,5 +100,5 @@
 		GPCR = hw_led_state ^ LED_MASK;
 	}
 
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-graphicsmaster.c linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-graphicsmaster.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-graphicsmaster.c	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-graphicsmaster.c	2003-07-05 18:09:36.000000000 -0700
@@ -30,7 +30,7 @@
 {
 	unsigned long flags;
 
-	save_flags_cli(flags);
+	local_irq_save(flags);
 
 	switch (evt) {
 	case led_start:
@@ -100,5 +100,5 @@
 		GPCR = hw_led_state ^ LED_MASK;
 	}
 
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-hackkit.c linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-hackkit.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/leds-hackkit.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/leds-hackkit.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,113 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-hackkit.c
+ *
+ * based on leds-lart.c
+ *
+ * (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000
+ * (C) Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>, 2002
+ *
+ * The HackKit has two leds (GPIO 22/23). The red led (gpio 22) is used
+ * as cpu led, the green one is used as timer led.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_GREEN    GPIO_GPIO23
+#define LED_RED    GPIO_GPIO22
+#define LED_MASK  (LED_RED | LED_GREEN)
+
+void hackkit_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch(evt) {
+		case led_start:
+			/* pin 22/23 are outputs */
+			GPDR |= LED_MASK;
+			hw_led_state = LED_MASK;
+			led_state = LED_STATE_ENABLED;
+			break;
+
+		case led_stop:
+			led_state &= ~LED_STATE_ENABLED;
+			break;
+
+		case led_claim:
+			led_state |= LED_STATE_CLAIMED;
+			hw_led_state = LED_MASK;
+			break;
+
+		case led_release:
+			led_state &= ~LED_STATE_CLAIMED;
+			hw_led_state = LED_MASK;
+			break;
+
+#ifdef CONFIG_LEDS_TIMER
+		case led_timer:
+			if (!(led_state & LED_STATE_CLAIMED))
+				hw_led_state ^= LED_GREEN;
+			break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+		case led_idle_start:
+			/* The LART people like the LED to be off when the
+			   system is idle... */
+			if (!(led_state & LED_STATE_CLAIMED))
+				hw_led_state &= ~LED_RED;
+			break;
+
+		case led_idle_end:
+			/* ... and on if the system is not idle */
+			if (!(led_state & LED_STATE_CLAIMED))
+				hw_led_state |= LED_RED;
+			break;
+#endif
+
+		case led_red_on:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state &= ~LED_RED;
+			break;
+
+		case led_red_off:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state |= LED_RED;
+			break;
+
+		case led_green_on:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state &= ~LED_GREEN;
+			break;
+
+		case led_green_off:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state |= LED_GREEN;
+			break;
+
+		default:
+			break;
+	}
+
+	/* Now set the GPIO state, or nothing will happen at all */
+	if (led_state & LED_STATE_ENABLED) {
+		GPSR = hw_led_state;
+		GPCR = hw_led_state ^ LED_MASK;
+	}
+
+	local_irq_restore(flags);
+}
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/leds.c linux-2.4.22-pre3/arch/arm/mach-sa1100/leds.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/leds.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/leds.c	2003-07-05 18:09:36.000000000 -0700
@@ -15,8 +15,12 @@
 static int __init
 sa1100_leds_init(void)
 {
+	if (machine_is_adsagc())
+		leds_event = adsagc_leds_event;
 	if (machine_is_adsbitsy())
 		leds_event = adsbitsy_leds_event;
+	if (machine_is_adsbitsyplus())
+		leds_event = adsbitsyplus_leds_event;
 	if (machine_is_assabet())
 		leds_event = assabet_leds_event;
  	if (machine_is_consus())
@@ -33,6 +37,8 @@
 		leds_event = graphicsclient_leds_event;
 	if (machine_is_graphicsmaster())
 		leds_event = graphicsmaster_leds_event;
+	if (machine_is_hackkit())
+		leds_event = hackkit_leds_event;
 	if (machine_is_lart())
 		leds_event = lart_leds_event;
 	if (machine_is_pfs168())
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/leds.h linux-2.4.22-pre3/arch/arm/mach-sa1100/leds.h
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/leds.h	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/leds.h	2003-07-05 18:09:36.000000000 -0700
@@ -1,12 +1,15 @@
+extern void adsagc_leds_event(led_event_t evt);
+extern void adsbitsy_leds_event(led_event_t evt);
+extern void adsbitsyplus_leds_event(led_event_t evt);
 extern void assabet_leds_event(led_event_t evt);
 extern void consus_leds_event(led_event_t evt);
 extern void brutus_leds_event(led_event_t evt);
 extern void cerf_leds_event(led_event_t evt);
 extern void flexanet_leds_event(led_event_t evt);
+extern void frodo_leds_event(led_event_t evt);
 extern void graphicsclient_leds_event(led_event_t evt);
+extern void graphicsmaster_leds_event(led_event_t evt);
+extern void hackkit_leds_event(led_event_t evt);
 extern void lart_leds_event(led_event_t evt);
 extern void pfs168_leds_event(led_event_t evt);
-extern void graphicsmaster_leds_event(led_event_t evt);
-extern void adsbitsy_leds_event(led_event_t evt);
 extern void system3_leds_event(led_event_t evt);
-extern void frodo_leds_event(led_event_t evt);
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/nanoengine.c linux-2.4.22-pre3/arch/arm/mach-sa1100/nanoengine.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/nanoengine.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/nanoengine.c	2003-07-05 18:09:36.000000000 -0700
@@ -16,22 +16,6 @@
 #include "generic.h"
 
 
-static void __init
-fixup_nanoengine(struct machine_desc *desc, struct param_struct *params,
-		 char **cmdline, struct meminfo *mi)
-{
-	SET_BANK( 0, 0xc0000000, 32*1024*1024 );
-	mi->nr_banks = 1;
-
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-	setup_ramdisk( 1, 0, 0, 8192 );
-	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
-
-	/* Get command line parameters passed from the loader (if any) */
-	if( *((char*)0xc0000100) )
-		*cmdline = ((char *)0xc0000100);
-}
-
 static struct map_desc nanoengine_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
   { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
@@ -56,7 +40,7 @@
 
 MACHINE_START(NANOENGINE, "BSE nanoEngine")
 	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	FIXUP(fixup_nanoengine)
+	BOOT_PARAMS(0xc0000100)
 	MAPIO(nanoengine_map_io)
 	INITIRQ(sa1100_init_irq)
 MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/neponset.c linux-2.4.22-pre3/arch/arm/mach-sa1100/neponset.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/neponset.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/neponset.c	2003-07-05 18:09:36.000000000 -0700
@@ -10,6 +10,8 @@
 #include <linux/tty.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/pcipool.c linux-2.4.22-pre3/arch/arm/mach-sa1100/pcipool.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/pcipool.c	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/pcipool.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,377 +0,0 @@
-/*
-  NOTE:
-
-  this code was lifted straight out of drivers/pci/pci.c;
-  when compiling for the Intel StrongARM SA-1110/SA-1111 the
-  usb-ohci.c driver needs these routines even when the architecture
-  has no pci bus...
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/bitops.h>
-
-#include <asm/page.h>
-
-#include "pcipool.h"
-
-/*
- * Pool allocator ... wraps the pci_alloc_consistent page allocator, so
- * small blocks are easily used by drivers for bus mastering controllers.
- * This should probably be sharing the guts of the slab allocator.
- */
-
-struct pci_pool {	/* the pool */
-	struct list_head	page_list;
-	spinlock_t		lock;
-	size_t			blocks_per_page;
-	size_t			size;
-	int			flags;
-	struct pci_dev		*dev;
-	size_t			allocation;
-	char			name [32];
-	wait_queue_head_t	waitq;
-};
-
-struct pci_page {	/* cacheable header for 'allocation' bytes */
-	struct list_head	page_list;
-	void			*vaddr;
-	dma_addr_t		dma;
-	unsigned long		bitmap [0];
-};
-
-#define	POOL_TIMEOUT_JIFFIES	((100 /* msec */ * HZ) / 1000)
-#define	POOL_POISON_BYTE	0xa7
-
-// #define CONFIG_PCIPOOL_DEBUG
-
-
-/**
- * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma.
- * @name: name of pool, for diagnostics
- * @pdev: pci device that will be doing the DMA
- * @size: size of the blocks in this pool.
- * @align: alignment requirement for blocks; must be a power of two
- * @allocation: returned blocks won't cross this boundary (or zero)
- * @flags: SLAB_* flags (not all are supported).
- *
- * Returns a pci allocation pool with the requested characteristics, or
- * null if one can't be created.  Given one of these pools, pci_pool_alloc()
- * may be used to allocate memory.  Such memory will all have "consistent"
- * DMA mappings, accessible by the device and its driver without using
- * cache flushing primitives.  The actual size of blocks allocated may be
- * larger than requested because of alignment.
- *
- * If allocation is nonzero, objects returned from pci_pool_alloc() won't
- * cross that size boundary.  This is useful for devices which have
- * addressing restrictions on individual DMA transfers, such as not crossing
- * boundaries of 4KBytes.
- */
-struct pci_pool *
-pci_pool_create (const char *name, struct pci_dev *pdev,
-	size_t size, size_t align, size_t allocation, int flags)
-{
-	struct pci_pool		*retval;
-
-	if (align == 0)
-		align = 1;
-	if (size == 0)
-		return 0;
-	else if (size < align)
-		size = align;
-	else if ((size % align) != 0) {
-		size += align + 1;
-		size &= ~(align - 1);
-	}
-
-	if (allocation == 0) {
-		if (PAGE_SIZE < size)
-			allocation = size;
-		else
-			allocation = PAGE_SIZE;
-		// FIXME: round up for less fragmentation
-	} else if (allocation < size)
-		return 0;
-
-	if (!(retval = kmalloc (sizeof *retval, flags)))
-		return retval;
-
-#ifdef	CONFIG_PCIPOOL_DEBUG
-	flags |= SLAB_POISON;
-#endif
-
-	strncpy (retval->name, name, sizeof retval->name);
-	retval->name [sizeof retval->name - 1] = 0;
-
-	retval->dev = pdev;
-	INIT_LIST_HEAD (&retval->page_list);
-	spin_lock_init (&retval->lock);
-	retval->size = size;
-	retval->flags = flags;
-	retval->allocation = allocation;
-	retval->blocks_per_page = allocation / size;
-	init_waitqueue_head (&retval->waitq);
-
-#ifdef CONFIG_PCIPOOL_DEBUG
-	printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n",
-		pdev ? pdev->slot_name : NULL, retval->name, size,
-		retval->blocks_per_page, allocation);
-#endif
-
-	return retval;
-}
-
-
-static struct pci_page *
-pool_alloc_page (struct pci_pool *pool, int mem_flags)
-{
-	struct pci_page	*page;
-	int		mapsize;
-
-	mapsize = pool->blocks_per_page;
-	mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
-	mapsize *= sizeof (long);
-
-	page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags);
-	if (!page)
-		return 0;
-	page->vaddr = pci_alloc_consistent (pool->dev,
-				pool->allocation, &page->dma);
-	if (page->vaddr) {
-		memset (page->bitmap, 0xff, mapsize);	// bit set == free
-		if (pool->flags & SLAB_POISON)
-			memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
-		list_add (&page->page_list, &pool->page_list);
-	} else {
-		kfree (page);
-		page = 0;
-	}
-	return page;
-}
-
-
-static inline int
-is_page_busy (int blocks, unsigned long *bitmap)
-{
-	while (blocks > 0) {
-		if (*bitmap++ != ~0UL)
-			return 1;
-		blocks -= BITS_PER_LONG;
-	}
-	return 0;
-}
-
-static void
-pool_free_page (struct pci_pool *pool, struct pci_page *page)
-{
-	dma_addr_t	dma = page->dma;
-
-	if (pool->flags & SLAB_POISON)
-		memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
-	pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma);
-	list_del (&page->page_list);
-	kfree (page);
-}
-
-
-/**
- * pci_pool_destroy - destroys a pool of pci memory blocks.
- * @pool: pci pool that will be destroyed
- *
- * Caller guarantees that no more memory from the pool is in use,
- * and that nothing will try to use the pool after this call.
- */
-void
-pci_pool_destroy (struct pci_pool *pool)
-{
-	unsigned long		flags;
-
-#ifdef CONFIG_PCIPOOL_DEBUG
-	printk (KERN_DEBUG "pcipool destroy %s/%s\n",
-		pool->dev ? pool->dev->slot_name : NULL,
-		pool->name);
-#endif
-
-	spin_lock_irqsave (&pool->lock, flags);
-	while (!list_empty (&pool->page_list)) {
-		struct pci_page		*page;
-		page = list_entry (pool->page_list.next,
-				struct pci_page, page_list);
-		if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
-			printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n",
-				pool->dev ? pool->dev->slot_name : NULL,
-				pool->name, page->vaddr);
-			/* leak the still-in-use consistent memory */
-			list_del (&page->page_list);
-			kfree (page);
-		} else
-			pool_free_page (pool, page);
-	}
-	spin_unlock_irqrestore (&pool->lock, flags);
-	kfree (pool);
-}
-
-
-/**
- * pci_pool_alloc - get a block of consistent memory
- * @pool: pci pool that will produce the block
- * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC
- * @handle: pointer to dma address of block
- *
- * This returns the kernel virtual address of a currently unused block,
- * and reports its dma address through the handle.
- * If such a memory block can't be allocated, null is returned.
- */
-void *
-pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
-{
-	unsigned long		flags;
-	struct list_head	*entry;
-	struct pci_page		*page;
-	int			map, block;
-	size_t			offset;
-	void			*retval;
-
-restart:
-	spin_lock_irqsave (&pool->lock, flags);
-	list_for_each (entry, &pool->page_list) {
-		int		i;
-		page = list_entry (entry, struct pci_page, page_list);
-		/* only cachable accesses here ... */
-		for (map = 0, i = 0;
-				i < pool->blocks_per_page;
-				i += BITS_PER_LONG, map++) {
-			if (page->bitmap [map] == 0)
-				continue;
-			block = ffz (~ page->bitmap [map]);
-			if ((i + block) < pool->blocks_per_page) {
-				clear_bit (block, &page->bitmap [map]);
-				offset = (BITS_PER_LONG * map) + block;
-				offset *= pool->size;
-				goto ready;
-			}
-		}
-	}
-	if (!(page = pool_alloc_page (pool, mem_flags))) {
-		if (mem_flags == SLAB_KERNEL) {
-			DECLARE_WAITQUEUE (wait, current);
-
-			current->state = TASK_INTERRUPTIBLE;
-			add_wait_queue (&pool->waitq, &wait);
-			spin_unlock_irqrestore (&pool->lock, flags);
-
-			schedule_timeout (POOL_TIMEOUT_JIFFIES);
-
-			current->state = TASK_RUNNING;
-			remove_wait_queue (&pool->waitq, &wait);
-			goto restart;
-		}
-		retval = 0;
-		goto done;
-	}
-
-	clear_bit (0, &page->bitmap [0]);
-	offset = 0;
-ready:
-	retval = offset + page->vaddr;
-	*handle = offset + page->dma;
-done:
-	spin_unlock_irqrestore (&pool->lock, flags);
-	return retval;
-}
-
-
-static struct pci_page *
-pool_find_page (struct pci_pool *pool, dma_addr_t dma)
-{
-	unsigned long		flags;
-	struct list_head	*entry;
-	struct pci_page		*page;
-
-	spin_lock_irqsave (&pool->lock, flags);
-	list_for_each (entry, &pool->page_list) {
-		page = list_entry (entry, struct pci_page, page_list);
-		if (dma < page->dma)
-			continue;
-		if (dma < (page->dma + pool->allocation))
-			goto done;
-	}
-	page = 0;
-done:
-	spin_unlock_irqrestore (&pool->lock, flags);
-	return page;
-}
-
-
-/**
- * pci_pool_free - put block back into pci pool
- * @pool: the pci pool holding the block
- * @vaddr: virtual address of block
- * @dma: dma address of block
- *
- * Caller promises neither device nor driver will again touch this block
- * unless it is first re-allocated.
- */
-void
-pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
-{
-	struct pci_page		*page;
-	unsigned long		flags;
-	int			map, block;
-
-	if ((page = pool_find_page (pool, dma)) == 0) {
-		printk (KERN_ERR "pci_pool_free %s/%s, %p/%x (bad dma)\n",
-			pool->dev ? pool->dev->slot_name : NULL,
-			pool->name, vaddr, dma);
-		return;
-	}
-#ifdef	CONFIG_PCIPOOL_DEBUG
-	if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
-		printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%x\n",
-			pool->dev ? pool->dev->slot_name : NULL,
-			pool->name, vaddr, dma);
-		return;
-	}
-#endif
-
-	block = dma - page->dma;
-	block /= pool->size;
-	map = block / BITS_PER_LONG;
-	block %= BITS_PER_LONG;
-
-#ifdef	CONFIG_PCIPOOL_DEBUG
-	if (page->bitmap [map] & (1UL << block)) {
-		printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n",
-			pool->dev ? pool->dev->slot_name : NULL,
-			pool->name, dma);
-		return;
-	}
-#endif
-	if (pool->flags & SLAB_POISON)
-		memset (vaddr, POOL_POISON_BYTE, pool->size);
-
-	spin_lock_irqsave (&pool->lock, flags);
-	set_bit (block, &page->bitmap [map]);
-	if (waitqueue_active (&pool->waitq))
-		wake_up (&pool->waitq);
-	/*
-	 * Resist a temptation to do
-	 *    if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page);
-	 * it is not interrupt safe. Better have empty pages hang around.
-	 */
-	spin_unlock_irqrestore (&pool->lock, flags);
-}
-
-
-EXPORT_SYMBOL (pci_pool_create);
-EXPORT_SYMBOL (pci_pool_destroy);
-EXPORT_SYMBOL (pci_pool_alloc);
-EXPORT_SYMBOL (pci_pool_free);
-
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/pcipool.h linux-2.4.22-pre3/arch/arm/mach-sa1100/pcipool.h
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/pcipool.h	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/pcipool.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,8 +0,0 @@
-
-struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
-		size_t size, size_t align, size_t allocation, int flags);
-void pci_pool_destroy (struct pci_pool *pool);
-
-void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
-void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
-
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/pm.c linux-2.4.22-pre3/arch/arm/mach-sa1100/pm.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/pm.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/pm.c	2003-07-05 18:09:36.000000000 -0700
@@ -18,11 +18,13 @@
  * 2001-08-29:	Nicolas Pitre <nico@cam.org>
  * 			Cleaned up, pushed platform dependent stuff
  * 			in the platform specific files.
+ *
+ * 2002-05-27:	Nicolas Pitre	Killed sleep.h and the kmalloced save array.
+ * 				Storage is local on the stack now.
  */
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pm.h>
-#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/sysctl.h>
@@ -33,7 +35,6 @@
 #include <asm/system.h>
 #include <asm/leds.h>
 
-#include "sleep.h"
 
 /*
  * Debug macros
@@ -43,20 +44,32 @@
 extern void sa1100_cpu_suspend(void);
 extern void sa1100_cpu_resume(void);
 
-extern unsigned long *sleep_save;	/* virtual address */
-extern unsigned long  sleep_save_p;	/* physical address */
-
 #define SAVE(x)		sleep_save[SLEEP_SAVE_##x] = x
 #define RESTORE(x)	x = sleep_save[SLEEP_SAVE_##x]
 
+/*
+ * List of global SA11x0 peripheral registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * with the stack location in sleep.S.
+ */
+enum {	SLEEP_SAVE_START = 0,
+
+	SLEEP_SAVE_OSCR, SLEEP_SAVE_OIER,
+	SLEEP_SAVE_OSMR0, SLEEP_SAVE_OSMR1, SLEEP_SAVE_OSMR2, SLEEP_SAVE_OSMR3,
+
+	SLEEP_SAVE_GPDR, SLEEP_SAVE_GRER, SLEEP_SAVE_GFER, SLEEP_SAVE_GAFR,
+	SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
+
+	SLEEP_SAVE_ICMR,
+	SLEEP_SAVE_Ser1SDCR0,
+
+	SLEEP_SAVE_SIZE
+};
+
+
 int pm_do_suspend(void)
 {
-	/* set up pointer to sleep parameters */
-	sleep_save = kmalloc(SLEEP_SAVE_SIZE*sizeof(long), GFP_ATOMIC);
-	if (!sleep_save)
-		return -ENOMEM;
-
-	sleep_save_p = virt_to_phys(sleep_save);
+	unsigned long sleep_save[SLEEP_SAVE_SIZE];
 
 	cli();
 
@@ -144,8 +157,6 @@
 
 	sti();
 
-	kfree (sleep_save);
-
 	/*
 	 * Restore the CPU frequency settings.
 	 */
@@ -156,6 +167,11 @@
 	return 0;
 }
 
+unsigned long sleep_phys_sp(void *sp)
+{
+	return virt_to_phys(sp);
+}
+
 #ifdef CONFIG_SYSCTL
 /*
  * ARGH!  ACPI people defined CTL_ACPI in linux/acpi.h rather than
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/sa1111-pcibuf.c linux-2.4.22-pre3/arch/arm/mach-sa1100/sa1111-pcibuf.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/sa1111-pcibuf.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/sa1111-pcibuf.c	2003-07-05 18:09:36.000000000 -0700
@@ -1,272 +1,400 @@
 /*
  *  linux/arch/arm/mach-sa1100/pci-sa1111.c
  *
- *  Special pci_map/unmap_single routines for SA-1111.   These functions
- *  compensate for a bug in the SA-1111 hardware which don't allow DMA
- *  to/from addresses above 1MB.
+ *  Special pci_{map/unmap/dma_sync}_* routines for SA-1111.
  *
- *  Brad Parker (brad@heeltoe.com)
+ *  These functions utilize bouncer buffers to compensate for a bug in
+ *  the SA-1111 hardware which don't allow DMA to/from addresses
+ *  certain addresses above 1MB.
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
+ *  Re-written by Christopher Hoover <ch@murgatroid.com>
+ *  Original version by Brad Parker (brad@heeltoe.com)
  *
- *  06/13/2001 - created.
- */
+ *  Copyright (C) 2002 Hewlett Packard Company.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  version 2 as published by the Free Software Foundation.
+ * */
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/list.h>
+#include <asm/hardware/sa1111.h>
+//#define DEBUG
+#ifdef DEBUG
+#define DPRINTK(...) do { printk(KERN_DEBUG __VA_ARGS__); } while (0)
+#else
+#define DPRINTK(...) do { } while (0)
+#endif
+
+struct safe_buffer {
+	struct list_head node;
+
+	/* original request */
+	void		*ptr;
+	size_t		size;
+	int		direction;
 
-#include "pcipool.h"
+	/* safe buffer info */
+	struct pci_pool *pool;
+	void		*safe;
+	dma_addr_t	safe_dma_addr;
+};
 
-/*
- * simple buffer allocator for copying of unsafe to safe buffers
- * uses __alloc/__free for actual buffers
- * keeps track of safe buffers we've allocated so we can recover the
- * unsafe buffers.
- */
+LIST_HEAD(safe_buffers);
 
-#define MAX_SAFE	32
 #define SIZE_SMALL	1024
 #define SIZE_LARGE	(16*1024)
 
-static long mapped_alloc_size;
-static char *safe_buffers[MAX_SAFE][2];
-
-
-static struct pci_pool *small_buffer_cache, *large_buffer_cache;
+static struct pci_pool *small_buffer_pool, *large_buffer_pool;
 
-static int
-init_safe_buffers(struct pci_dev *dev)
+static int __init
+create_safe_buffer_pools(void)
 {
-	small_buffer_cache = pci_pool_create("pci_small_buffer",
-					    dev,
+	small_buffer_pool = pci_pool_create("sa1111_small_dma_buffer",
+					    SA1111_FAKE_PCIDEV,
 					    SIZE_SMALL,
 					    0 /* byte alignment */,
 					    0 /* no page-crossing issues */,
-					    GFP_KERNEL | GFP_DMA);
-
-	if (small_buffer_cache == 0)
+					    SLAB_KERNEL);
+	if (0 == small_buffer_pool) {
+		printk(KERN_ERR
+		       "sa1111_pcibuf: could not allocate small pci pool\n");
 		return -1;
+	}
 
-	large_buffer_cache = pci_pool_create("pci_large_buffer",
-					    dev,
+	large_buffer_pool = pci_pool_create("sa1111_large_dma_buffer",
+					    SA1111_FAKE_PCIDEV,
 					    SIZE_LARGE,
 					    0 /* byte alignment */,
 					    0 /* no page-crossing issues */,
-					    GFP_KERNEL | GFP_DMA);
-	if (large_buffer_cache == 0)
+					    SLAB_KERNEL);
+	if (0 == large_buffer_pool) {
+		printk(KERN_ERR
+		       "sa1111_pcibuf: could not allocate large pci pool\n");
+		pci_pool_destroy(small_buffer_pool);
+		small_buffer_pool = 0;
 		return -1;
+	}
 
 	return 0;
 }
 
+static void __exit
+destroy_safe_buffer_pools(void)
+{
+	if (small_buffer_pool)
+		pci_pool_destroy(small_buffer_pool);
+	if (large_buffer_pool)
+		pci_pool_destroy(large_buffer_pool);
+
+	small_buffer_pool = large_buffer_pool = 0;
+}
+
+
 /* allocate a 'safe' buffer and keep track of it */
-static char *
-alloc_safe_buffer(char *unsafe, int size, dma_addr_t *pbus)
+static struct safe_buffer *
+alloc_safe_buffer(void *ptr, size_t size, int direction)
 {
-	char *safe;
-	dma_addr_t busptr;
+	struct safe_buffer *buf;
 	struct pci_pool *pool;
-	int i;
-
-	if (0) printk("alloc_safe_buffer(size=%d)\n", size);
+	void *safe;
+	dma_addr_t safe_dma_addr;
 
-	if (size <= SIZE_SMALL)
-		pool = small_buffer_cache;
-	else
-		if (size < SIZE_LARGE)
-			pool = large_buffer_cache;
-				else
-					return 0;
+	DPRINTK("%s(ptr=%p, size=%d, direction=%d)\n",
+		__func__, ptr, size, direction);
 
-	safe = pci_pool_alloc(pool, SLAB_ATOMIC, &busptr);
-	if (safe == 0)
+	buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
+	if (buf == 0) {
+		printk(KERN_WARNING "%s: kmalloc failed\n", __func__);
 		return 0;
+	}
 
-	for (i = 0; i < MAX_SAFE; i++)
-		if (safe_buffers[i][0] == 0) {
-			break;
-		}
-
-	if (i == MAX_SAFE) {
-		panic(__FILE__ ": exceeded MAX_SAFE buffers");
+	if (size <= SIZE_SMALL) {
+		pool = small_buffer_pool;
+		safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
+	} else if (size <= SIZE_LARGE) {
+		pool = large_buffer_pool;
+		safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
+	} else {
+		printk(KERN_DEBUG
+		       "sa111_pcibuf: resorting to pci_alloc_consistent\n");
+		pool = 0;
+		safe = pci_alloc_consistent(SA1111_FAKE_PCIDEV, size,
+					    &safe_dma_addr);
 	}
 
-	/* place the size index and the old buffer ptr in the first 8 bytes
-	 * and return a ptr + 12 to caller
-	 */
-	((int *)safe)[0] = i;
-	((char **)safe)[1] = (char *)pool;
-	((char **)safe)[2] = unsafe;
+	if (safe == 0) {
+		printk(KERN_WARNING
+		       "%s: could not alloc dma memory (size=%d)\n",
+		       __func__, size);
+		kfree(buf);
+		return 0;
+	}
 
-	busptr += sizeof(int) + sizeof(char *) + sizeof(char *);
+	BUG_ON(sa1111_check_dma_bug(safe_dma_addr));	// paranoia
 
-	safe_buffers[i][0] = (void *)busptr;
-	safe_buffers[i][1] = (void *)safe;
+	buf->ptr = ptr;
+	buf->size = size;
+	buf->direction = direction;
+	buf->pool = pool;
+	buf->safe = safe;
+	buf->safe_dma_addr = safe_dma_addr;
 
-	safe += sizeof(int) + sizeof(char *) + sizeof(char *);
+	MOD_INC_USE_COUNT;
+	list_add(&buf->node, &safe_buffers);
 
-	*pbus = busptr;
-	return safe;
+	return buf;
 }
 
 /* determine if a buffer is from our "safe" pool */
-static char *
-find_safe_buffer(char *busptr, char **unsafe)
+static struct safe_buffer *
+find_safe_buffer(dma_addr_t safe_dma_addr)
 {
-	int i;
-	char *buf;
+	struct list_head *entry;
 
-	for (i = 0; i < MAX_SAFE; i++) {
-		if (safe_buffers[i][0] == busptr) {
-			if (0) printk("find_safe_buffer(%p) found @ %d\n", busptr, i);
-			buf = safe_buffers[i][1];
-			*unsafe = ((char **)buf)[2];
-			return buf + sizeof(int) + sizeof(char *) + sizeof(char *);
+	list_for_each(entry, &safe_buffers) {
+		struct safe_buffer *b =
+			list_entry(entry, struct safe_buffer, node);
+
+		if (b->safe_dma_addr == safe_dma_addr) {
+			return b;
 		}
 	}
 
-	return (char *)0;
+	return 0;
 }
 
 static void
-free_safe_buffer(char *buf)
+free_safe_buffer(struct safe_buffer *buf)
 {
-	int index;
-	struct pci_pool *pool;
-	char *dma;
+	DPRINTK("%s(buf=%p)\n", __func__, buf);
 
-	if (0) printk("free_safe_buffer(buf=%p)\n", buf);
+	list_del(&buf->node);
 
-	/* retrieve the buffer size index */
-	buf -= sizeof(int) + sizeof(char*) + sizeof(char*);
-	index = ((int *)buf)[0];
-	pool = (struct pci_pool *)((char **)buf)[1];
+	if (buf->pool)
+		pci_pool_free(buf->pool, buf->safe, buf->safe_dma_addr);
+	else
+		pci_free_consistent(SA1111_FAKE_PCIDEV, buf->size, buf->safe,
+				    buf->safe_dma_addr);
+	kfree(buf);
 
-	if (0) printk("free_safe_buffer(%p) index %d\n",
-		      buf, index);
+	MOD_DEC_USE_COUNT;
+}
 
-	if (index < 0 || index >= MAX_SAFE) {
-		printk(__FILE__ ": free_safe_buffer() corrupt buffer\n");
-		return;
-	}
+static inline int
+dma_range_is_safe(dma_addr_t addr, size_t size)
+{
+	unsigned int physaddr = SA1111_DMA_ADDR((unsigned int) addr);
 
-	dma = safe_buffers[index][0];
-	safe_buffers[index][0] = 0;
+	/* Any address within one megabyte of the start of the target
+         * bank will be OK.  This is an overly conservative test:
+         * other addresses can be OK depending on the dram
+         * configuration.  (See sa1111.c:sa1111_check_dma_bug() * for
+         * details.)
+	 *
+	 * We take care to ensure the entire dma region is within
+	 * the safe range.
+	 */
 
-	pci_pool_free(pool, buf, (u32)dma);
+	return ((physaddr + size - 1) < (1<<20));
 }
 
 /*
-  NOTE:
-  replace pci_map/unmap_single with local routines which will
-  do buffer copies if buffer is above 1mb...
-*/
-
-/*
  * see if a buffer address is in an 'unsafe' range.  if it is
  * allocate a 'safe' buffer and copy the unsafe buffer into it.
  * substitute the safe buffer for the unsafe one.
  * (basically move the buffer from an unsafe area to a safe one)
- *
- * we assume calls to map_single are symmetric with calls to unmap_single...
  */
 dma_addr_t
-sa1111_map_single(struct pci_dev *hwdev, void *virtptr,
-	       size_t size, int direction)
+sa1111_map_single(void *ptr, size_t size, int direction)
 {
-	dma_addr_t busptr;
+	unsigned long flags;
+	dma_addr_t dma_addr;
 
-	mapped_alloc_size += size;
+	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
+	       __func__, ptr, size, direction);
 
-	if (0) printk("pci_map_single(hwdev=%p,ptr=%p,size=%d,dir=%x) "
-		      "alloced=%ld\n",
-		      hwdev, virtptr, size, direction, mapped_alloc_size);
+	BUG_ON(direction == PCI_DMA_NONE);
 
-	busptr = virt_to_bus(virtptr);
+	local_irq_save(flags);
 
-	/* we assume here that a buffer will never be >=64k */
-	if ( (((unsigned long)busptr) & 0x100000) ||
-	     ((((unsigned long)busptr)+size) & 0x100000) )
-	{
-		char *safe;
+	dma_addr = virt_to_bus(ptr);
 
-		safe = alloc_safe_buffer(virtptr, size, &busptr);
-		if (safe == 0) {
-			printk("unable to map unsafe buffer %p!\n", virtptr);
+	if (!dma_range_is_safe(dma_addr, size)) {
+		struct safe_buffer *buf;
+
+		buf = alloc_safe_buffer(ptr, size, direction);
+		if (buf == 0) {
+			printk(KERN_ERR
+			       "%s: unable to map unsafe buffer %p!\n",
+			       __func__, ptr);
+			local_irq_restore(flags);
 			return 0;
 		}
 
-		if (0) printk("unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
-			      virtptr, (void *)virt_to_bus(virtptr),
-			      safe, (void *)busptr);
-
-		memcpy(safe, virtptr, size);
-		consistent_sync(safe, size, direction);
+		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
+			__func__,
+			buf->ptr, (void *) virt_to_bus(buf->ptr),
+			buf->safe, (void *) buf->safe_dma_addr);
+
+		if ((direction == PCI_DMA_TODEVICE) ||
+		    (direction == PCI_DMA_BIDIRECTIONAL)) {
+			DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n",
+				__func__, ptr, buf->safe, size);
+			memcpy(buf->safe, ptr, size);
+		}
+		consistent_sync(buf->safe, size, direction);
 
-		return busptr;
+		dma_addr = buf->safe_dma_addr;
+	} else {
+		consistent_sync(ptr, size, direction);
 	}
 
-	consistent_sync(virtptr, size, direction);
-	return busptr;
+	local_irq_restore(flags);
+	return dma_addr;
 }
 
 /*
- * see if a mapped address was really a "safe" buffer and if so,
- * copy the data from the safe buffer back to the unsafe buffer
- * and free up the safe buffer.
- * (basically return things back to the way they should be)
+ * see if a mapped address was really a "safe" buffer and if so, copy
+ * the data from the safe buffer back to the unsafe buffer and free up
+ * the safe buffer.  (basically return things back to the way they
+ * should be)
  */
+
 void
-sa1111_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
-		 size_t size, int direction)
+sa1111_unmap_single(dma_addr_t dma_addr, size_t size, int direction)
 {
-	char *safe, *unsafe;
-	void *buf;
+	unsigned long flags;
+	struct safe_buffer *buf;
 
-	/* hack; usb-ohci.c never sends hwdev==NULL, all others do */
-	if (hwdev == NULL) {
-		return;
+	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
+		__func__, (void *) dma_addr, size, direction);
+
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	local_irq_save(flags);
+
+	buf = find_safe_buffer(dma_addr);
+	if (buf) {
+		BUG_ON(buf->size != size);
+		BUG_ON(buf->direction != direction);
+
+		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
+			__func__,
+			buf->ptr, (void *) virt_to_bus(buf->ptr),
+			buf->safe, (void *) buf->safe_dma_addr);
+
+		if ((direction == PCI_DMA_FROMDEVICE) ||
+		    (direction == PCI_DMA_BIDIRECTIONAL)) {
+			DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n",
+				__func__, buf->safe, buf->ptr, size);
+			memcpy(buf->ptr, buf->safe, size);
+		}
+		free_safe_buffer(buf);
 	}
 
-	mapped_alloc_size -= size;
+	local_irq_restore(flags);
+}
+
+int
+sa1111_map_sg(struct scatterlist *sg, int nents, int direction)
+{
+	BUG();			/* Not implemented. */
+
+	return -1;
+}
+
+void
+sa1111_unmap_sg(struct scatterlist *sg, int nents, int direction)
+{
+	BUG();			/* Not implemented. */
+}
+
+void
+sa1111_dma_sync_single(dma_addr_t dma_addr, size_t size, int direction)
+{
+	unsigned long flags;
+	struct safe_buffer *buf;
+
+	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
+		__func__, (void *) dma_addr, size, direction);
 
-	if (0) printk("pci_unmap_single(hwdev=%p,ptr=%p,size=%d,dir=%x) "
-		      "alloced=%ld\n",
-		      hwdev, (void *)dma_addr, size, direction,
-		      mapped_alloc_size);
-
-	if ((safe = find_safe_buffer((void *)dma_addr, &unsafe))) {
-		if (0) printk("copyback unsafe %p, safe %p, size %d\n",
-			      unsafe, safe, size);
-
-		consistent_sync(safe, size, PCI_DMA_FROMDEVICE);
-		memcpy(unsafe, safe, size);
-		free_safe_buffer(safe);
+	local_irq_save(flags);
+
+	buf = find_safe_buffer(dma_addr);
+	if (buf) {
+		BUG_ON(buf->size != size);
+		BUG_ON(buf->direction != direction);
+
+		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
+			__func__,
+			buf->ptr, (void *) virt_to_bus(buf->ptr),
+			buf->safe, (void *) buf->safe_dma_addr);
+
+		switch (direction) {
+		case PCI_DMA_FROMDEVICE:
+			DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n",
+				__func__, buf->safe, buf->ptr, size);
+			memcpy(buf->ptr, buf->safe, size);
+			break;
+		case PCI_DMA_TODEVICE:
+			DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n",
+				__func__,buf->ptr, buf->safe, size);
+			memcpy(buf->safe, buf->ptr, size);
+			break;
+		case PCI_DMA_BIDIRECTIONAL:
+			BUG();	/* is this allowed?  what does it mean? */
+		default:
+			BUG();
+		}
+		consistent_sync(buf->safe, size, direction);
 	} else {
-		/* assume this is normal memory */
-		buf = bus_to_virt(dma_addr);
-		consistent_sync(buf, size, PCI_DMA_FROMDEVICE);
+		consistent_sync(bus_to_virt(dma_addr), size, direction);
 	}
+
+	local_irq_restore(flags);
+}
+
+void
+sa1111_dma_sync_sg(struct scatterlist *sg, int nelems, int direction)
+{
+	BUG();			/* Not implemented. */
 }
 
 EXPORT_SYMBOL(sa1111_map_single);
 EXPORT_SYMBOL(sa1111_unmap_single);
+EXPORT_SYMBOL(sa1111_map_sg);
+EXPORT_SYMBOL(sa1111_unmap_sg);
+EXPORT_SYMBOL(sa1111_dma_sync_single);
+EXPORT_SYMBOL(sa1111_dma_sync_sg);
 
-static int __init sa1111_init_safe_buffers(void)
+/* **************************************** */
+
+static int __init sa1111_pcibuf_init(void)
 {
-	printk("Initializing SA1111 buffer pool for DMA workaround\n");
-	init_safe_buffers(NULL);
-	return 0;
+	int ret;
+
+	printk(KERN_DEBUG
+	       "sa1111_pcibuf: initializing SA-1111 DMA workaround\n");
+
+	ret = create_safe_buffer_pools();
+
+	return ret;
 }
+module_init(sa1111_pcibuf_init);
 
-static void free_safe_buffers(void)
+static void __exit sa1111_pcibuf_exit(void)
 {
-	pci_pool_destroy(small_buffer_cache);
-	pci_pool_destroy(large_buffer_cache);
+	BUG_ON(!list_empty(&safe_buffers));
+
+	destroy_safe_buffer_pools();
 }
+module_exit(sa1111_pcibuf_exit);
 
-module_init(sa1111_init_safe_buffers);
-module_exit(free_safe_buffers);
+MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>");
+MODULE_DESCRIPTION("Special pci_{map/unmap/dma_sync}_* routines for SA-1111.");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/sa1111.c linux-2.4.22-pre3/arch/arm/mach-sa1100/sa1111.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/sa1111.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/sa1111.c	2003-07-05 18:09:36.000000000 -0700
@@ -24,6 +24,8 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/simputer.c linux-2.4.22-pre3/arch/arm/mach-sa1100/simputer.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/simputer.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/simputer.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,78 @@
+/*
+ * linux/arch/arm/mach-sa1100/simputer.c
+ *
+ * Author: Vivek K S (modified from Nicolas Pitre's Assabet file)
+ *
+ * This file contains all Simputer-specific tweaks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/serial_core.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+#include <asm/arch/simputer.h>
+
+#include "generic.h"
+
+static void __init
+fixup_simputer(struct machine_desc *desc, struct param_struct *params,
+	      char **cmdline, struct meminfo *mi)
+{
+}
+
+
+static struct map_desc simputer_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf2800000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Simputer Modem */
+  { 0xf3800000, 0x48000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* USB */
+  LAST_DESC
+};
+
+static void __init simputer_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(simputer_io_desc);
+
+	sa1100_register_uart(1, 2);
+	sa1100_register_uart(0, 1);	/* com port */
+	sa1100_register_uart(2, 3);	/* radio module */
+
+	/*
+	 * Set up registers for sleep mode.
+	 */
+	PWER = PWER_GPIO0;
+	PGSR = 0;
+	PCFR = 0;
+
+	/*
+	 * Clear all possible wakeup reasons.
+	 */
+	RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
+}
+
+
+MACHINE_START(SIMPUTER, "Picopeta-Simputer")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_simputer)
+	MAPIO(simputer_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/sleep.S linux-2.4.22-pre3/arch/arm/mach-sa1100/sleep.S
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/sleep.S	2001-10-25 13:53:46.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/sleep.S	2003-07-05 18:09:36.000000000 -0700
@@ -11,12 +11,17 @@
  * 2001-02-06: Cliff Brake         Initial code
  *
  * 2001-08-29:	Nicolas Pitre	Simplified.
+ *
+ * 2002-05-27:	Nicolas Pitre	Revisited, more cleanup and simplification.
+ *				Storage is on the stack now.
  */
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <asm/hardware.h>
-#include "sleep.h"
+
+
+		.text
 
 /*
  * sa1100_cpu_suspend()
@@ -25,35 +30,25 @@
  *
  */
 
-	.text
-
-ENTRY(sleep_save)	.word	0		@ virtual address of parameter array
-ENTRY(sleep_save_p)	.word	0		@ physical address of parameter array
-
 ENTRY(sa1100_cpu_suspend)
 
-	@ save registers on stack
-	stmfd	sp!, {r4 - r12, lr}
-
-	@ load virtual address for sleep_save array
-	ldr	r4, sleep_save
+	stmfd	sp!, {r4 - r12, lr}		@ save registers on stack
 
-	@ save stack pointer
-	str	sp, [r4, #(SLEEP_SAVE_SP*4)]
-
-	@ save coprocessor registers
-	mrc 	p15, 0, r1, c1, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R1*4)]
-	mrc 	p15, 0, r1, c2, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R2*4)]
-	mrc 	p15, 0, r1, c3, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R3*4)]
-	mrc 	p15, 0, r1, c5, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R5*4)]
-	mrc 	p15, 0, r1, c6, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R6*4)]
-	mrc 	p15, 0, r1, c13, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R13*4)]
+	@ get coprocessor registers
+	mrc 	p15, 0, r4, c3, c0, 0		@ domain ID
+	mrc 	p15, 0, r5, c2, c0, 0		@ translation table base addr
+	mrc	p15, 0, r6, c13, c0, 0		@ PID
+	mrc 	p15, 0, r7, c1, c0, 0		@ control reg
+
+	@ store them plus current virtual stack ptr on stack
+	mov	r8, sp
+	stmfd	sp!, {r4 - r8}
+
+	@ preserve phys address of stack
+	mov	r0, sp
+	bl	sleep_phys_sp
+	ldr	r1, =sleep_save_sp
+	str	r0, [r1]
 
 	@ clean data cache and invalidate WB
 	bl	cpu_sa1100_cache_clean_invalidate_all
@@ -72,32 +67,31 @@
 	@ delay 90us and set CPU PLL to lowest speed
 	@ fixes resume problem on high speed SA1110
 	mov	r0, #90
-	bl	SYMBOL_NAME(udelay)
+	bl	SYMBOL_NAME(__udelay)
 	ldr	r0, =PPCR
 	mov	r1, #0
 	str	r1, [r0]
 	mov	r0, #90
-	bl	SYMBOL_NAME(udelay)
+	bl	SYMBOL_NAME(__udelay)
 
-
-/* setup up register contents for jump to page containing SA1110 SDRAM controller bug fix suspend code
- *
- * r0 points to MSC0 register
- * r1 points to MSC1 register
- * r2 points to MSC2 register
- * r3 is MSC0 value
- * r4 is MSC1 value
- * r5 is MSC2 value
- * r6 points to MDREFR register
- * r7 is first MDREFR value
- * r8 is second MDREFR value
- * r9 is pointer to MDCNFG register
- * r10 is MDCNFG value
- * r11 is third MDREFR value
- * r12 is pointer to PMCR register
- * r13 is PMCR value (1)
- *
- */
+	/*
+	 * SA1110 SDRAM controller workaround.  register values:
+	 *
+	 * r0  = &MSC0
+	 * r1  = &MSC1
+	 * r2  = &MSC2
+	 * r3  = MSC0 value
+	 * r4  = MSC1 value
+	 * r5  = MSC2 value
+	 * r6  = &MDREFR
+	 * r7  = first MDREFR value
+	 * r8  = second MDREFR value
+	 * r9  = &MDCNFG
+	 * r10 = MDCNFG value
+	 * r11 = third MDREFR value
+	 * r12 = &PMCR
+	 * r13 = PMCR value (1)
+	 */
 
 	ldr	r0, =MSC0
 	ldr	r1, =MSC1
@@ -170,69 +164,49 @@
  *
  * entry point from bootloader into kernel during resume
  *
+ * Note: Yes, part of the following code is located into the .data section.
+ *       This is to allow sleep_save_sp to be accessed with a relative load
+ *       while we can't rely on any MMU translation.  We could have put
+ *       sleep_save_sp in the .text section as well, but some setups might
+ *       insist on .text to be truely read-only.
  */
 
+	.data
 	.align 5
 ENTRY(sa1100_cpu_resume)
-
-	@ set SVC, irqs off
-	mov	r0, #I_BIT | MODE_SVC
+	mov	r0, #I_BIT | F_BIT | MODE_SVC	@ set SVC, irqs off
 	msr	cpsr_c, r0
 
-	@ load physical address of sleep_save
-	ldr	r4, sleep_save_p
-
-	@ restore cp15_r3, domain id
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R3*4)]
-	mcr 	p15, 0, r1, c3, c0 ,0
-
-	@ restore cp15_r2, translation table base address
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R2*4)]
-	mcr 	p15, 0, r1, c2, c0 ,0
+	ldr	r0, sleep_save_sp		@ stack phys addr
+	ldr	r2, =resume_after_mmu		@ its absolute virtual address
+	ldmfd	r0, {r4 - r7, sp}		@ CP regs + virt stack ptr
 
 	mov	r1, #0
 	mcr	p15, 0, r1, c8, c7, 0   	@ flush I+D TLBs
 	mcr	p15, 0, r1, c7, c7, 0		@ flush I&D cache
+	mcr	p15, 0, r1, c9, c0, 0		@ invalidate RB
+	mcr     p15, 0, r1, c9, c0, 5		@ allow user space to use RB
 
-	@ get saved cp15 r1 (control register)
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R1*4)]
-
-	@ get address to jump to after turning on MMU
-	ldr	r2, =resume_after_mmu
-
-	cmp	r2, #0
-
-	b	resume_turn_on_mmu
+	mcr 	p15, 0, r4, c3, c0, 0		@ domain ID
+	mcr 	p15, 0, r5, c2, c0, 0		@ translation table base addr
+	mcr	p15, 0, r6, c13, c0, 0		@ PID
+	b	resume_turn_on_mmu		@ cache align execution
 
 	.align 5
 resume_turn_on_mmu:
-
-	@ turn on mmu
-	mcr 	p15, 0, r1, c1, c0 ,0
-
-	@ jump to resume_after_mmu
-	mov	pc, r2
+	mcr 	p15, 0, r7, c1, c0, 0		@ turn on MMU, caches, etc.
+	nop
+	mov	pc, r2				@ jump to virtual addr
+	nop
 	nop
 	nop
 
-	.align 5
-resume_after_mmu:
-
-	@ load virtual address for sleep_save array
-	ldr	r4, sleep_save
-
-	@ restore the rest of CPU state
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R13*4)]
-	mcr	p15, 0, r1, c13, c0, 0
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R5*4)]
-	mcr 	p15, 0, r1, c5, c0 ,0
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R6*4)]
-	mcr 	p15, 0, r1, c6, c0 ,0
-
-	@ restore stack pointer
-	ldr	sp, [r4, #(SLEEP_SAVE_SP*4)]
+sleep_save_sp:
+	.word	0				@ preserve stack phys ptr here
 
-	@ return to caller
-	ldmfd	sp!, {r4 - r12, pc}
+	.text
+resume_after_mmu:
+	mcr     p15, 0, r1, c15, c1, 2		@ enable clock switching
+	ldmfd	sp!, {r4 - r12, pc}		@ return to caller
 
 
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/sleep.h linux-2.4.22-pre3/arch/arm/mach-sa1100/sleep.h
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/sleep.h	2001-10-25 13:53:46.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/sleep.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,30 +0,0 @@
-/*
- * Offsets for register values preserved in RAM while in sleep mode
- */
-
-#define SLEEP_SAVE_OSCR		0
-#define SLEEP_SAVE_OSMR0	1
-#define SLEEP_SAVE_OSMR1	2
-#define SLEEP_SAVE_OSMR2	3
-#define SLEEP_SAVE_OSMR3	4
-#define SLEEP_SAVE_OIER		5
-#define SLEEP_SAVE_GPDR		6
-#define SLEEP_SAVE_GRER		7
-#define SLEEP_SAVE_GFER		8
-#define SLEEP_SAVE_GAFR		9
-#define SLEEP_SAVE_PPDR		10
-#define SLEEP_SAVE_PPSR		11
-#define SLEEP_SAVE_PPAR		12
-#define SLEEP_SAVE_PSDR		13
-#define SLEEP_SAVE_Ser1SDCR0	14
-#define SLEEP_SAVE_ICMR		15
-#define SLEEP_SAVE_SP		16
-#define SLEEP_SAVE_CP15_R1	17
-#define SLEEP_SAVE_CP15_R2	18
-#define SLEEP_SAVE_CP15_R3	19
-#define SLEEP_SAVE_CP15_R5	20
-#define SLEEP_SAVE_CP15_R6	21
-#define SLEEP_SAVE_CP15_R13	22
-
-#define SLEEP_SAVE_SIZE		23
-
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/ssp.c linux-2.4.22-pre3/arch/arm/mach-sa1100/ssp.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/ssp.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/ssp.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,208 @@
+/*
+ *  linux/arch/arm/mach-sa1100/ssp.c
+ *
+ *  Copyright (C) 2003 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Generic SSP driver.  This provides the generic core for simple
+ *  IO-based SSP applications.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/hardware/ssp.h>
+
+static void ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int status = Ser4SSSR;
+
+	if (status & SSSR_ROR) {
+		printk(KERN_WARNING "SSP: receiver overrun\n");
+	}
+
+	Ser4SSSR = SSSR_ROR;
+}
+
+/**
+ * ssp_write_word - write a word to the SSP port
+ * @data: 16-bit, MSB justified data to write.
+ *
+ * Wait for a free entry in the SSP transmit FIFO, and write a data
+ * word to the SSP port.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ *   %-ETIMEDOUT	timeout occurred (for future)
+ *   0			success
+ */
+int ssp_write_word(u16 data)
+{
+	while (!(Ser4SSSR & SSSR_TNF))
+		cpu_relax();
+
+	Ser4SSDR = data;
+
+	return 0;
+}
+
+/**
+ * ssp_read_word - read a word from the SSP port
+ *
+ * Wait for a data word in the SSP receive FIFO, and return the
+ * received data.  Data is LSB justified.
+ *
+ * Note: Currently, if data is not expected to be received, this
+ * function will wait for ever.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ *   %-ETIMEDOUT	timeout occurred (for future)
+ *   16-bit data	success
+ */
+int ssp_read_word(void)
+{
+	while (!(Ser4SSSR & SSSR_RNE))
+		cpu_relax();
+
+	return Ser4SSDR;
+}
+
+/**
+ * ssp_flush - flush the transmit and receive FIFOs
+ *
+ * Wait for the SSP to idle, and ensure that the receive FIFO
+ * is empty.
+ *
+ * The caller is expected to perform the necessary locking.
+ */
+void ssp_flush(void)
+{
+	do {
+		while (Ser4SSSR & SSSR_RNE) {
+			(void) Ser4SSDR;
+		}
+	} while (Ser4SSSR & SSSR_BSY);
+}
+
+/**
+ * ssp_enable - enable the SSP port
+ *
+ * Turn on the SSP port.
+ */
+void ssp_enable(void)
+{
+	Ser4SSCR0 |= SSCR0_SSE;
+}
+
+/**
+ * ssp_disable - shut down the SSP port
+ *
+ * Turn off the SSP port, optionally powering it down.
+ */
+void ssp_disable(void)
+{
+	Ser4SSCR0 &= ~SSCR0_SSE;
+}
+
+/**
+ * ssp_save_state - save the SSP configuration
+ * @ssp: pointer to structure to save SSP configuration
+ *
+ * Save the configured SSP state for suspend.
+ */
+void ssp_save_state(struct ssp_state *ssp)
+{
+	ssp->cr0 = Ser4SSCR0;
+	ssp->cr1 = Ser4SSCR1;
+
+	Ser4SSCR0 &= ~SSCR0_SSE;
+}
+
+/**
+ * ssp_restore_state - restore a previously saved SSP configuration
+ * @ssp: pointer to configuration saved by ssp_save_state
+ *
+ * Restore the SSP configuration saved previously by ssp_save_state.
+ */
+void ssp_restore_state(struct ssp_state *ssp)
+{
+	Ser4SSSR = SSSR_ROR;
+
+	Ser4SSCR0 = ssp->cr0 & ~SSCR0_SSE;
+	Ser4SSCR1 = ssp->cr1;
+	Ser4SSCR0 = ssp->cr0;
+}
+
+/**
+ * ssp_init - setup the SSP port
+ *
+ * initialise and claim resources for the SSP port.
+ *
+ * Returns:
+ *   %-ENODEV	if the SSP port is unavailable
+ *   %-EBUSY	if the resources are already in use
+ *   %0		on success
+ */
+int ssp_init(void)
+{
+	int ret;
+
+	if (!(PPAR & PPAR_SPR) && (Ser4MCCR0 & MCCR0_MCE))
+		return -ENODEV;
+
+	if (!request_mem_region(__PREG(Ser4SSCR0), 0x18, "SSP")) {
+		return -EBUSY;
+	}
+
+	Ser4SSSR = SSSR_ROR;
+
+	ret = request_irq(IRQ_Ser4SSP, ssp_interrupt, 0, "SSP", NULL);
+	if (ret)
+		goto out_region;
+
+	return 0;
+
+ out_region:
+	release_mem_region(__PREG(Ser4SSCR0), 0x18);
+	return ret;
+}
+
+/**
+ * ssp_exit - undo the effects of ssp_init
+ *
+ * release and free resources for the SSP port.
+ */
+void ssp_exit(void)
+{
+	Ser4SSCR0 &= ~SSCR0_SSE;
+
+	free_irq(IRQ_Ser4SSP, NULL);
+	release_mem_region(__PREG(Ser4SSCR0), 0x18);
+}
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SA11x0 SSP PIO driver");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ssp_write_word);
+EXPORT_SYMBOL(ssp_read_word);
+EXPORT_SYMBOL(ssp_flush);
+EXPORT_SYMBOL(ssp_enable);
+EXPORT_SYMBOL(ssp_disable);
+EXPORT_SYMBOL(ssp_save_state);
+EXPORT_SYMBOL(ssp_restore_state);
+EXPORT_SYMBOL(ssp_init);
+EXPORT_SYMBOL(ssp_exit);
diff -urN linux-2.4.22-pre2/arch/arm/mach-sa1100/system3.c linux-2.4.22-pre3/arch/arm/mach-sa1100/system3.c
--- linux-2.4.22-pre2/arch/arm/mach-sa1100/system3.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mach-sa1100/system3.c	2003-07-05 18:09:36.000000000 -0700
@@ -42,6 +42,8 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/cpufreq.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/setup.h>
diff -urN linux-2.4.22-pre2/arch/arm/mm/Makefile linux-2.4.22-pre3/arch/arm/mm/Makefile
--- linux-2.4.22-pre2/arch/arm/mm/Makefile	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/Makefile	2003-07-05 18:09:36.000000000 -0700
@@ -36,8 +36,10 @@
 p-$(CONFIG_CPU_ARM720T)	+= proc-arm720.o
 p-$(CONFIG_CPU_ARM920T)	+= proc-arm920.o
 p-$(CONFIG_CPU_ARM922T)	+= proc-arm922.o
+p-$(CONFIG_CPU_ARM925T)	+= proc-arm925.o
 p-$(CONFIG_CPU_ARM926T)	+= proc-arm926.o
 p-$(CONFIG_CPU_ARM1020)	+= proc-arm1020.o
+p-$(CONFIG_CPU_ARM1026)	+= proc-arm1026.o
 p-$(CONFIG_CPU_SA110)	+= proc-sa110.o
 p-$(CONFIG_CPU_SA1100)	+= proc-sa110.o
 
diff -urN linux-2.4.22-pre2/arch/arm/mm/alignment.c linux-2.4.22-pre3/arch/arm/mm/alignment.c
--- linux-2.4.22-pre2/arch/arm/mm/alignment.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/alignment.c	2003-07-05 18:09:36.000000000 -0700
@@ -426,13 +426,13 @@
 		eaddr += 4;
 
 	/* 
-	 * For alignment faults on the ARM922T the MMU  makes 
+	 * For alignment faults on the ARM922T/ARM920T the MMU  makes
 	 * the FSR (and hence addr) equal to the updated base address
 	 * of the multiple access rather than the restored value.
-	 * Switch this messsage off if we've got a ARM922, otherwise
+	 * Switch this messsage off if we've got a ARM92[02], otherwise
 	 * [ls]dm alignment faults are noisy!
 	 */
-#if !(defined CONFIG_CPU_ARM922T)  
+#if !(defined CONFIG_CPU_ARM922T)  && !(defined CONFIG_CPU_ARM920T)
 	/*
 	 * This is a "hint" - we already have eaddr worked out by the
 	 * processor for us.
diff -urN linux-2.4.22-pre2/arch/arm/mm/consistent.c linux-2.4.22-pre3/arch/arm/mm/consistent.c
--- linux-2.4.22-pre2/arch/arm/mm/consistent.c	2001-06-27 14:12:04.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/consistent.c	2003-07-05 18:09:36.000000000 -0700
@@ -30,14 +30,20 @@
  * now, we expressly forbid it, especially as some of the stuff we do
  * here is not interrupt context safe.
  *
+ * We should allow this function to be called from interrupt context.
+ * However, we call ioremap, which needs to fiddle around with various
+ * things (like the vmlist_lock, and allocating page tables).  These
+ * things aren't interrupt safe (yet).
+ *
  * Note that this does *not* zero the allocated area!
  */
 void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
 {
 	struct page *page, *end, *free;
 	unsigned long order;
-	void *ret, *virt;
+	void *ret;
 
+	/* FIXME */
 	if (in_interrupt())
 		BUG();
 
@@ -48,22 +54,22 @@
 	if (!page)
 		goto no_page;
 
-	/*
-	 * We could do with a page_to_phys and page_to_bus here.
-	 */
-	virt = page_address(page);
-	*dma_handle = virt_to_bus(virt);
-	ret = __ioremap(virt_to_phys(virt), size, 0);
+	*dma_handle = page_to_bus(page);
+	ret = __ioremap(page_to_pfn(page) << PAGE_SHIFT, size, 0);
 	if (!ret)
 		goto no_remap;
 
 #if 0 /* ioremap_does_flush_cache_all */
-	/*
-	 * we need to ensure that there are no cachelines in use, or
-	 * worse dirty in this area.  Really, we don't need to do
-	 * this since __ioremap does a flush_cache_all() anyway. --rmk
-	 */
-	invalidate_dcache_range(virt, virt + size);
+	{
+		void *virt = page_address(page);
+
+		/*
+		 * we need to ensure that there are no cachelines in use, or
+		 * worse dirty in this area.  Really, we don't need to do
+		 * this since __ioremap does a flush_cache_all() anyway. --rmk
+		 */
+		invalidate_dcache_range(virt, virt + size);
+	}
 #endif
 
 	/*
@@ -72,7 +78,6 @@
 	 * We also mark the pages in use as reserved so that
 	 * remap_page_range works.
 	 */
-	page = virt_to_page(virt);
 	free = page + (size >> PAGE_SHIFT);
 	end  = page + (1 << order);
 
@@ -93,18 +98,15 @@
 
 void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle)
 {
-	void *__ret;
-	int __gfp = GFP_KERNEL;
+	int gfp = GFP_KERNEL;
 
-#ifdef CONFIG_PCI
-	if ((hwdev) == NULL ||
+#if defined(CONFIG_PCI) || defined(CONFIG_SA1111)
+	if ((hwdev) == NULL || dev_is_sa1111(hwdev) ||
 	    (hwdev)->dma_mask != 0xffffffff)
 #endif
-		__gfp |= GFP_DMA;
+		gfp |= GFP_DMA;
 
-	__ret = consistent_alloc(__gfp, (size),
-				 (handle));
-	return __ret;
+	return consistent_alloc(gfp, size, handle);
 }
 
 /*
@@ -114,19 +116,16 @@
 void consistent_free(void *vaddr, size_t size, dma_addr_t handle)
 {
 	struct page *page, *end;
-	void *virt;
 
 	if (in_interrupt())
 		BUG();
 
-	virt = bus_to_virt(handle);
-
 	/*
 	 * More messing around with the MM internals.  This is
 	 * sick, but then so is remap_page_range().
 	 */
 	size = PAGE_ALIGN(size);
-	page = virt_to_page(virt);
+	page = virt_to_page(bus_to_virt(handle));
 	end = page + (size >> PAGE_SHIFT);
 
 	for (; page < end; page++)
diff -urN linux-2.4.22-pre2/arch/arm/mm/fault-armv.c linux-2.4.22-pre3/arch/arm/mm/fault-armv.c
--- linux-2.4.22-pre2/arch/arm/mm/fault-armv.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/fault-armv.c	2003-07-05 18:09:36.000000000 -0700
@@ -28,7 +28,6 @@
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 
-extern void die_if_kernel(const char *str, struct pt_regs *regs, int err);
 extern void show_pte(struct mm_struct *mm, unsigned long addr);
 extern int do_page_fault(unsigned long addr, int error_code,
 			 struct pt_regs *regs);
@@ -236,9 +235,13 @@
  */
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
 {
-	struct page *page = pte_page(pte);
+	unsigned long pfn = pte_pfn(pte);
+	struct page *page;
 
-	if (VALID_PAGE(page) && page->mapping) {
+	if (!pfn_valid(pfn))
+		return;
+	page = pfn_to_page(pfn);
+	if (page->mapping) {
 		if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) {
 			unsigned long kvirt = (unsigned long)page_address(page);
 			cpu_cache_clean_invalidate_range(kvirt, kvirt + PAGE_SIZE, 0);
diff -urN linux-2.4.22-pre2/arch/arm/mm/fault-common.c linux-2.4.22-pre3/arch/arm/mm/fault-common.c
--- linux-2.4.22-pre2/arch/arm/mm/fault-common.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mm/fault-common.c	2003-07-05 18:09:36.000000000 -0700
@@ -43,52 +43,77 @@
 #define READ_FAULT(m)		(!(m))
 #endif
 
-NORET_TYPE void die(const char *msg, struct pt_regs *regs, int err) ATTRIB_NORET;
-
 /*
  * This is useful to dump out the page tables associated with
  * 'addr' in mm 'mm'.
  */
 void show_pte(struct mm_struct *mm, unsigned long addr)
 {
-	pgd_t *pgd;
+	mm_segment_t fs;
 
 	if (!mm)
 		mm = &init_mm;
 
-	printk(KERN_ALERT "pgd = %p\n", mm->pgd);
-	pgd = pgd_offset(mm, addr);
-	printk(KERN_ALERT "*pgd = %08lx", pgd_val(*pgd));
+	printk(KERN_ALERT "mm = %p pgd = %p\n", mm, mm->pgd);
 
+	fs = get_fs();
+	set_fs(get_ds());
 	do {
-		pmd_t *pmd;
-		pte_t *pte;
+		pgd_t pg, *pgd = pgd_offset(mm, addr);
+		pmd_t pm, *pmd;
+		pte_t pt, *pte;
+
+		printk(KERN_ALERT "*pgd = ");
 
-		if (pgd_none(*pgd))
+		if (__get_user(pgd_val(pg), (unsigned long *)pgd)) {
+			printk("(faulted)");
 			break;
+		}
 
-		if (pgd_bad(*pgd)) {
+		printk("%08lx", pgd_val(pg));
+
+		if (pgd_none(pg))
+			break;
+
+		if (pgd_bad(pg)) {
 			printk("(bad)");
 			break;
 		}
 
 		pmd = pmd_offset(pgd, addr);
-		printk(", *pmd = %08lx", pmd_val(*pmd));
 
-		if (pmd_none(*pmd))
+		printk(", *pmd = ");
+
+		if (__get_user(pmd_val(pm), (unsigned long *)pmd)) {
+			printk("(faulted)");
+			break;
+		}
+
+		printk("%08lx", pmd_val(pm));
+
+		if (pmd_none(pm))
 			break;
 
-		if (pmd_bad(*pmd)) {
+		if (pmd_bad(pm)) {
 			printk("(bad)");
 			break;
 		}
 
 		pte = pte_offset(pmd, addr);
-		printk(", *pte = %08lx", pte_val(*pte));
+
+		printk(", *pte = ");
+
+		if (__get_user(pte_val(pt), (unsigned long *)pte)) {
+			printk("(faulted)");
+			break;
+		}
+
+		printk("%08lx", pte_val(pt));
 #ifdef CONFIG_CPU_32
 		printk(", *ppte = %08lx", pte_val(pte[-PTRS_PER_PTE]));
 #endif
 	} while(0);
+	set_fs(fs);
 
 	printk("\n");
 }
@@ -345,6 +370,9 @@
 
 	offset = __pgd_offset(addr);
 
+	/*
+	 * FIXME: CP15 C1 is write only on ARMv3 architectures.
+	 */
 	pgd = cpu_get_pgd() + offset;
 	pgd_k = init_mm.pgd + offset;
 
diff -urN linux-2.4.22-pre2/arch/arm/mm/init.c linux-2.4.22-pre3/arch/arm/mm/init.c
--- linux-2.4.22-pre2/arch/arm/mm/init.c	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/init.c	2003-07-05 18:09:36.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/mm/init.c
  *
- *  Copyright (C) 1995-2000 Russell King
+ *  Copyright (C) 1995-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -46,11 +46,13 @@
 #define TABLE_OFFSET	0
 #endif
 
-#define TABLE_SIZE	((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *))
+#define TABLE_SIZE	((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(pte_t))
 
 static unsigned long totalram_pages;
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern char _stext, _text, _etext, _end, __init_begin, __init_end;
+extern unsigned long phys_initrd_start;
+extern unsigned long phys_initrd_size;
 
 /*
  * The sole use of this is to pass memory configuration
@@ -292,6 +294,7 @@
 	 * also get rid of some of the stuff above as well.
 	 */
 	max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
+//	max_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
 	mi->end = memend_pfn << PAGE_SHIFT;
 
 	return bootmem_pages;
@@ -302,16 +305,16 @@
 	int initrd_node = -2;
 
 #ifdef CONFIG_BLK_DEV_INITRD
+	unsigned long end = phys_initrd_start + phys_initrd_size;
+
 	/*
 	 * Make sure that the initrd is within a valid area of
 	 * memory.
 	 */
-	if (initrd_start) {
-		unsigned long phys_initrd_start, phys_initrd_end;
+	if (phys_initrd_size) {
 		unsigned int i;
 
-		phys_initrd_start = __pa(initrd_start);
-		phys_initrd_end   = __pa(initrd_end);
+		initrd_node = -1;
 
 		for (i = 0; i < mi->nr_banks; i++) {
 			unsigned long bank_end;
@@ -319,7 +322,7 @@
 			bank_end = mi->bank[i].start + mi->bank[i].size;
 
 			if (mi->bank[i].start <= phys_initrd_start &&
-			    phys_initrd_end <= bank_end)
+			    end <= bank_end)
 				initrd_node = mi->bank[i].node;
 		}
 	}
@@ -327,8 +330,8 @@
 	if (initrd_node == -1) {
 		printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond "
 		       "physical memory - disabling initrd\n",
-		       initrd_start, initrd_end);
-		initrd_start = initrd_end = 0;
+		       phys_initrd_start, end);
+		phys_initrd_start = phys_initrd_size = 0;
 	}
 #endif
 
@@ -354,7 +357,7 @@
 	 * and can only be in node 0.
 	 */
 	reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
-			     PTRS_PER_PGD * sizeof(void *));
+			     PTRS_PER_PGD * sizeof(pgd_t));
 #endif
 	/*
 	 * And don't forget to reserve the allocator bitmap,
@@ -378,7 +381,7 @@
 	 */
 	if (machine_is_archimedes() || machine_is_a5k())
 		reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
-	if (machine_is_edb7211())
+	if (machine_is_edb7211() || machine_is_fortunet())
 		reserve_bootmem_node(pgdat, 0xc0000000, 0x00020000);
 	if (machine_is_p720t())
 		reserve_bootmem_node(pgdat, PHYS_OFFSET, 0x00014000);
@@ -469,9 +472,12 @@
 
 
 #ifdef CONFIG_BLK_DEV_INITRD
-	if (initrd_node >= 0)
-		reserve_bootmem_node(NODE_DATA(initrd_node), __pa(initrd_start),
-				     initrd_end - initrd_start);
+	if (phys_initrd_size && initrd_node >= 0) {
+		reserve_bootmem_node(NODE_DATA(initrd_node), phys_initrd_start,
+				     phys_initrd_size);
+		initrd_start = __phys_to_virt(phys_initrd_start);
+		initrd_end = initrd_start + phys_initrd_size;
+	}
 #endif
 
 	if (map_pg != bootmap_pfn + bootmap_pages)
@@ -501,6 +507,7 @@
 	memtable_init(mi);
 	if (mdesc->map_io)
 		mdesc->map_io();
+	flush_cache_all();
 	flush_tlb_all();
 
 	/*
@@ -583,7 +590,7 @@
 	}
 
 	if (size && s)
-		printk("Freeing %s memory: %dK\n", s, size);
+		printk(KERN_INFO "Freeing %s memory: %dK\n", s, size);
 }
 
 /*
diff -urN linux-2.4.22-pre2/arch/arm/mm/ioremap.c linux-2.4.22-pre3/arch/arm/mm/ioremap.c
--- linux-2.4.22-pre2/arch/arm/mm/ioremap.c	2001-04-12 12:20:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/ioremap.c	2003-07-05 18:09:36.000000000 -0700
@@ -8,24 +8,19 @@
  * Hacked for ARM by Phil Blundell <philb@gnu.org>
  * Hacked to allow all architectures to build, and various cleanups
  * by Russell King
- */
-
-/*
+ *
  * This allows a driver to remap an arbitrary region of bus memory into
  * virtual space.  One should *only* use readl, writel, memcpy_toio and
  * so on with such remapped areas.
  *
- * Because the ARM only has a 32-bit address space we can't address the
- * whole of the (physical) PCI space at once.  PCI huge-mode addressing
- * allows us to circumvent this restriction by splitting PCI space into
- * two 2GB chunks and mapping only one at a time into processor memory.
- * We use MMU protection domains to trap any attempt to access the bank
- * that is not currently mapped.  (This isn't fully implemented yet.)
- *
- * DC21285 currently has a bug in that the PCI address extension
- * register affects the address of any writes waiting in the outbound
- * FIFO.  Unfortunately, it is not possible to tell the DC21285 to
- * flush this - flushing the area causes the bus to lock.
+ * ioremap support tweaked to allow support for large page mappings.  We
+ * have several issues that needs to be resolved first however:
+ *
+ *  1. We need set_pte, or something like set_pte to understand large
+ *     page mappings.
+ *
+ *  2. we need the unmap_* functions to likewise understand large page
+ *     mappings.
  */
 #include <linux/errno.h>
 #include <linux/mm.h>
@@ -35,8 +30,9 @@
 #include <asm/pgalloc.h>
 #include <asm/io.h>
 
-static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
-	unsigned long phys_addr, pgprot_t pgprot)
+static inline void
+remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+	       unsigned long pfn, pgprot_t pgprot)
 {
 	unsigned long end;
 
@@ -44,22 +40,26 @@
 	end = address + size;
 	if (end > PMD_SIZE)
 		end = PMD_SIZE;
-	if (address >= end)
-		BUG();
+	BUG_ON(address >= end);
 	do {
-		if (!pte_none(*pte)) {
-			printk("remap_area_pte: page already exists\n");
-			BUG();
-		}
-		set_pte(pte, mk_pte_phys(phys_addr, pgprot));
+		if (!pte_none(*pte))
+			goto bad;
+
+		set_pte(pte, pfn_pte(pfn, pgprot));
 		address += PAGE_SIZE;
-		phys_addr += PAGE_SIZE;
+		pfn++;
 		pte++;
 	} while (address && (address < end));
+	return;
+
+ bad:
+	printk("remap_area_pte: page already exists\n");
+	BUG();
 }
 
-static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
-	unsigned long phys_addr, unsigned long flags)
+static inline int
+remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
+	       unsigned long pfn, unsigned long flags)
 {
 	unsigned long end;
 	pgprot_t pgprot;
@@ -70,34 +70,33 @@
 	if (end > PGDIR_SIZE)
 		end = PGDIR_SIZE;
 
-	phys_addr -= address;
-	if (address >= end)
-		BUG();
+	pfn -= address >> PAGE_SHIFT;
+	BUG_ON(address >= end);
 
 	pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
 	do {
 		pte_t * pte = pte_alloc(&init_mm, pmd, address);
 		if (!pte)
 			return -ENOMEM;
-		remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
+		remap_area_pte(pte, address, end - address, pfn + (address >> PAGE_SHIFT), pgprot);
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
 	} while (address && (address < end));
 	return 0;
 }
 
-static int remap_area_pages(unsigned long address, unsigned long phys_addr,
-				 unsigned long size, unsigned long flags)
+static int
+remap_area_pages(unsigned long address, unsigned long pfn,
+		 unsigned long size, unsigned long flags)
 {
 	int error;
 	pgd_t * dir;
 	unsigned long end = address + size;
 
-	phys_addr -= address;
+	pfn -= address >> PAGE_SHIFT;
 	dir = pgd_offset(&init_mm, address);
 	flush_cache_all();
-	if (address >= end)
-		BUG();
+	BUG_ON(address >= end);
 	spin_lock(&init_mm.page_table_lock);
 	do {
 		pmd_t *pmd;
@@ -106,7 +105,7 @@
 		if (!pmd)
 			break;
 		if (remap_area_pmd(pmd, address, end - address,
-					 phys_addr + address, flags))
+					 pfn + (address >> PAGE_SHIFT), flags))
 			break;
 		error = 0;
 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
@@ -154,7 +153,7 @@
 	if (!area)
 		return NULL;
 	addr = area->addr;
-	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
+	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr >> PAGE_SHIFT, size, flags)) {
 		vfree(addr);
 		return NULL;
 	}
diff -urN linux-2.4.22-pre2/arch/arm/mm/mm-armv.c linux-2.4.22-pre3/arch/arm/mm/mm-armv.c
--- linux-2.4.22-pre2/arch/arm/mm/mm-armv.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/mm-armv.c	2003-07-05 18:09:36.000000000 -0700
@@ -200,7 +200,7 @@
 	}
 	ptep = pte_offset(pmdp, virt);
 
-	set_pte(ptep, mk_pte_phys(phys, __pgprot(prot)));
+	set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, __pgprot(prot)));
 }
 
 /*
@@ -388,8 +388,6 @@
 	init_maps->bufferable = 0;
 
 	create_mapping(init_maps);
-
-	flush_cache_all();
 }
 
 /*
diff -urN linux-2.4.22-pre2/arch/arm/mm/mm-riscstation.c linux-2.4.22-pre3/arch/arm/mm/mm-riscstation.c
--- linux-2.4.22-pre2/arch/arm/mm/mm-riscstation.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mm/mm-riscstation.c	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,35 @@
+/*
+ *  linux/arch/arm/mm/mm-rpc.c
+ *  linux/arch/arm/mm/mm-riscstation.c
+ *
+ *  Copyright (C) 1998-1999 Russell King
+ *  Copyright (C) 2002 Simtec Electronics / Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Extra MM routines for RiscStation
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/page.h>
+#include <asm/proc/domain.h>
+#include <asm/setup.h>
+
+#include <asm/mach/map.h>
+
+/* map the EASI space to use for the ISA slot */
+
+static struct map_desc riscstation_io_desc[] __initdata = {
+ { IO_BASE,	IO_START,	IO_SIZE	 , DOMAIN_IO, 0, 1, 0, 0 }, /* IO space		*/
+ { EASI_BASE,	EASI_START,	EASI_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, /* EASI space	*/
+ LAST_DESC
+};
+
+void __init riscstation_map_io(void)
+{
+	iotable_init(riscstation_io_desc);
+}
diff -urN linux-2.4.22-pre2/arch/arm/mm/proc-arm1020.S linux-2.4.22-pre3/arch/arm/mm/proc-arm1020.S
--- linux-2.4.22-pre2/arch/arm/mm/proc-arm1020.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/proc-arm1020.S	2003-07-05 18:09:36.000000000 -0700
@@ -135,7 +135,7 @@
 	.align	5
 ENTRY(cpu_arm1020_do_idle)
 	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -156,7 +156,7 @@
 ENTRY(cpu_arm1020_cache_clean_invalidate_all)
 	mov	r2, #1
 cpu_arm1020_cache_clean_invalidate_all_r2:
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, ip, c7, c10, 4
 
 	mov	r1, #0xf			@ 16 segments
@@ -165,7 +165,7 @@
 	orr	ip, ip, r1, LSL #5		@ shift in/up index
 	mcr	p15, 0, ip, c7, c14, 2		@ Clean & Inval DCache entry
 	mcr	p15, 0, ip, c7, c10, 4		@ drain WB 
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	ip, ip
 #endif
 	subs	r3, r3, #1
@@ -176,12 +176,12 @@
 	bge	1b				@ segments 7 to 0
 #endif
         
-#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	teq	r2, #0
 	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
 #endif
 	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	ip, ip
 	mov	ip, ip
 #endif
@@ -203,13 +203,13 @@
 	cmp	r3, #MAX_AREA_SIZE
 	bgt	cpu_arm1020_cache_clean_invalidate_all_r2
 	mcr	p15, 0, r3, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
@@ -217,11 +217,11 @@
 	blt	1b
 #endif
 
-#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	teq	r2, #0
 	movne	r0, #0
 	mcrne	p15, 0, r0, c7, c5, 0		@ invalidate I cache
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -238,14 +238,14 @@
 	.align	5
 ENTRY(cpu_arm1020_flush_ram_page)
 	mcr	p15, 0, r1, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mov	r1, #PAGESIZE
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -254,7 +254,7 @@
 	mov	r0, #0
 
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -275,14 +275,14 @@
  */
 	.align	5
 ENTRY(cpu_arm1020_dcache_invalidate_range)
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	/* D cache are on */
 	tst	r0, #DCACHELINESIZE - 1
 	bic	r0, r0, #DCACHELINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 4
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry at start
 	mcrne	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -290,14 +290,14 @@
 	mcrne	p15, 0, r1, c7, c10, 4
 	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry at end
 	mcrne	p15, 0, r1, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r1, r1
 	mov	r1, r1
 	mov	r1, r1
 #endif
         
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
@@ -306,7 +306,7 @@
 #else
 	/* D cache off, but still drain the write buffer */
 	mcr	p15, 0, r0, c7, c10, 4		@ Drain write buffer
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -330,13 +330,13 @@
 	cmp	r3, #MAX_AREA_SIZE
 	bgt	cpu_arm1020_cache_clean_invalidate_all_r2
 	mcr	p15, 0, r3, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
@@ -344,7 +344,7 @@
 	blt	1b
 #endif
 
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -367,23 +367,23 @@
 ENTRY(cpu_arm1020_dcache_clean_page)
 	mov	r1, #PAGESIZE
 	mcr	p15, 0, r0, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry  (drain is done by TLB fns)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
 	subs	r1, r1, #2 * DCACHELINESIZE
 	bhi	1b
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -401,14 +401,14 @@
 ENTRY(cpu_arm1020_dcache_clean_entry)
 	mov	r1, #0
 	mcr	p15, 0, r1, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 1		@ clean single D entry
 	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
 #endif
-#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	mcr	p15, 0, r1, c7, c5, 1		@ invalidate I entry
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r1, r1
 	mov	r1, r1
 #endif
@@ -427,14 +427,14 @@
 	.align	5
 ENTRY(cpu_arm1020_icache_invalidate_range)
 1:	mcr	p15, 0, r0, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
@@ -442,7 +442,7 @@
 	blo	1b
 ENTRY(cpu_arm1020_icache_invalidate_page)
 	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -460,7 +460,7 @@
 	mov	r0, #0
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I & D tlbs
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -476,12 +476,15 @@
  */
 	.align	5
 ENTRY(cpu_arm1020_tlb_invalidate_range)
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE
+	bhi	cpu_arm1020_tlb_invalidate_all
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
 	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
 	add	r0, r0, #PAGESIZE
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	cmp	r0, r1
@@ -500,14 +503,14 @@
 ENTRY(cpu_arm1020_tlb_invalidate_page)
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
 	teq	r1, #0
 	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
 	mcrne	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -524,7 +527,7 @@
  */
 	.align	5
 ENTRY(cpu_arm1020_set_pgd)
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r3, c7, c10, 4
 	mov	r1, #0xF			@ 16 segments
 1:	mov	r3, #0x3F			@ 64 entries
@@ -533,7 +536,7 @@
 	mcr	p15, 0, ip, c7, c14, 2		@ Clean & Inval DCache entry
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	ip, ip
 #endif
 	subs	r3, r3, #1
@@ -545,13 +548,13 @@
 
 #endif
 	mov	r1, #0
-#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	mcr	p15, 0, r1, c7, c5, 0		@ invalidate I cache
 #endif
 	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
 	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
 	mcr	p15, 0, r1, c8, c7, 0		@ invalidate I & D TLBs
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	ip, ip
 	mov	ip, ip
 #endif
@@ -568,18 +571,18 @@
  */
 	.align	5
 ENTRY(cpu_arm1020_set_pmd)
-#ifdef CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r2, r1, #0x0a			@ C & Section
 	tst	r2, #0x0b
 	biceq	r1, r1, #4			@ clear bufferable bit
 #endif
 	str	r1, [r0]
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 4
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry  (drain is done by TLB fns)
 #endif
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -609,47 +612,42 @@
 	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
 	movne	r2, #0
 
-#ifdef CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r3, r1, #0x0a			@ C & small page?
 	tst	r3, #0x0b
 	biceq	r2, r2, #4
 #endif
 	str	r2, [r0]			@ hardware version
 	mov	r0, r0
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 4
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 #endif
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
 	mov	pc, lr
 
 
-cpu_manu_name:
-	.asciz	"ARM/VLSI"
 ENTRY(cpu_arm1020_name)
 	.ascii	"Arm1020"
-#if defined(CONFIG_CPU_ARM1020_CPU_IDLE)
-	.ascii	"s"
-#endif
-#if defined(CONFIG_CPU_ARM1020_I_CACHE_ON)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	.ascii	"i"
 #endif
-#if defined(CONFIG_CPU_ARM1020_D_CACHE_ON)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	.ascii	"d"
-#if defined(CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH)
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	.ascii	"(wt)"
 #else
 	.ascii	"(wb)"
 #endif
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	.ascii	"B"
 #endif
-#ifdef CONFIG_CPU_ARM1020_ROUND_ROBIN
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	.ascii	"RR"
 #endif
 	.ascii	"\0"
@@ -679,16 +677,16 @@
 	orr	r0, r0, #0x0031 		@ ..........DP...M
 	orr	r0, r0, #0x0100 		@ .......S........
 
-#ifdef CONFIG_CPU_ARM1020_ROUND_ROBIN
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000 		@ .R..............
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	orr	r0, r0, #0x0800 		@ ....Z...........
 #endif
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	orr	r0, r0, #0x0004 		@ Enable D cache
 #endif
-#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	orr	r0, r0, #0x1000 		@ I Cache on
 #endif
 	mov	pc, lr
@@ -736,7 +734,7 @@
 
 	.type	cpu_arm1020_info, #object
 cpu_arm1020_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_arm1020_name
 	.size	cpu_arm1020_info, . - cpu_arm1020_info
 
@@ -761,7 +759,7 @@
 	b	__arm1020_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
 	.long	cpu_arm1020_info
 	.long	arm1020_processor_functions
 	.size	__arm1020_proc_info, . - __arm1020_proc_info
diff -urN linux-2.4.22-pre2/arch/arm/mm/proc-arm1026.S linux-2.4.22-pre3/arch/arm/mm/proc-arm1026.S
--- linux-2.4.22-pre2/arch/arm/mm/proc-arm1026.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mm/proc-arm1026.S	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,660 @@
+/*
+ *  linux/arch/arm/mm/arm1026.S: MMU functions for ARM1026EJ-S
+ *
+ *  Copyright (C) 2002 ARM Limited
+ *  Copyright (C) 2002 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm1026.
+ */
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions.  Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE	16384
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE	32
+#define ICACHELINESIZE	32
+
+/*
+ * and the page size
+ */
+#define PAGESIZE	4096
+
+	.text
+
+/*
+ * cpu_arm1026_data_abort()
+ *
+ * obtain information about current aborted instruction
+ * Note: we read user space.  This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture.  Unfortunately, this does happen.  We live with it.
+ *
+ * Inputs:
+ *  r2 = address of abort 
+ *  r3 = cpsr of abort
+ *
+ * Returns:
+ *  r0 = address of abort
+ *  r1 != 0 if writing
+ *  r3 = FSR
+ *  r4 = corrupted
+ */
+	.align	5
+ENTRY(cpu_arm1026_data_abort)
+	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+	and	r2, r3, #0b1101			@ Check for translation error
+	sub	r1, r2, #0b0101
+
+	and	r3, r3, #255
+	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_check_bugs()
+ */
+ENTRY(cpu_arm1026_check_bugs)
+	mrs	ip, cpsr
+	bic	ip, ip, #F_BIT
+	msr	cpsr, ip
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_proc_init()
+ */
+ENTRY(cpu_arm1026_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_proc_fin()
+ */
+ENTRY(cpu_arm1026_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #F_BIT | I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	cpu_arm1026_cache_clean_invalidate_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000 		@ ...i............
+	bic	r0, r0, #0x000e 		@ ............wca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_arm1026_reset(loc)
+ *
+ * Perform a soft reset of the system.	Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_arm1026_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x000f 		@ ............wcam
+	bic	ip, ip, #0x1100 		@ ...i...s........
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0
+
+/*
+ * cpu_arm1026_do_idle()
+ */
+	.align	5
+ENTRY(cpu_arm1026_do_idle)
+	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
+	mov	pc, lr
+
+/* ================================= CACHE ================================ */
+
+
+/*
+ * cpu_arm1026_cache_clean_invalidate_all()
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ *  1. we should preserve r0 at all times
+ */
+	.align	5
+ENTRY(cpu_arm1026_cache_clean_invalidate_all)
+	mov	r2, #1
+cpu_arm1026_cache_clean_invalidate_all_r2:
+	mov	ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+1:	mrc	p15, 0, r15, c7, c14, 3 	@ test,clean,invalidate
+	bne	1b
+#endif
+	teq	r2, #0
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * This is a little misleading, it is not intended to clean out
+ * the i-cache but to make sure that any data written to the
+ * range is made consistant.  This means that when we execute code
+ * in that region, everything works as we expect.
+ *
+ * This generally means writing back data in the Dcache and
+ * write buffer and flushing the Icache over that region
+ * start: Area start address
+ * end:   Area end address
+ * flags: nonzero for I cache as well
+ */
+	.align	5
+ENTRY(cpu_arm1026_cache_clean_invalidate_range)
+	bic	r0, r0, #DCACHELINESIZE - 1	@ && added by PGM
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bhi	cpu_arm1026_cache_clean_invalidate_all_r2
+
+1:	teq	r2, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+#else
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+#endif
+        
+	cmp	r0, r1
+	blo	1b
+
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_flush_ram_page(page)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * page: page to clean and invalidate
+ */
+	.align	5
+ENTRY(cpu_arm1026_flush_ram_page)
+	mov	r1, #PAGESIZE
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+#else
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+#endif
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ D-CACHE =============================== */
+
+/*
+ * cpu_arm1026_dcache_invalidate_range(start, end)
+ *
+ * throw away all D-cached data in specified region without an obligation
+ * to write them back.	Note however that we must clean the D-cached entries
+ * around the boundaries if the start and/or end address are not cache
+ * aligned.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm1026_dcache_invalidate_range)
+#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
+	tst	r0, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+#endif
+	bic	r0, r0, #DCACHELINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_dcache_clean_range(start, end)
+ *
+ * For the specified virtual address range, ensure that all caches contain
+ * clean data, such that peripheral accesses to the physical RAM fetch
+ * correct data.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm1026_dcache_clean_range)
+#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
+	bic	r0, r0, #DCACHELINESIZE - 1
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	mov	r2, #0
+	bhi	cpu_arm1026_cache_clean_invalidate_all_r2
+
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+#endif
+	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_dcache_clean_page(page)
+ *
+ * Cleans a single page of dcache so that if we have any future aliased
+ * mappings, they will be consistent at the time that they are created.
+ *
+ * page: virtual address of page to clean from dcache
+ *
+ * Note:
+ *  1. we don't need to flush the write buffer in this case.
+ *  2. we don't invalidate the entries since when we write the page
+ *     out to disk, the entries may get reloaded into the cache.
+ */
+	.align	5
+ENTRY(cpu_arm1026_dcache_clean_page)
+#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+#endif
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_dcache_clean_entry(addr)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+	.align	5
+ENTRY(cpu_arm1026_dcache_clean_entry)
+#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ I-CACHE =============================== */
+
+/*
+ * cpu_arm1026_icache_invalidate_range(start, end)
+ *
+ * This *is not* just icache.  It is to make data written to memory
+ * consistent such that instructions fetched from the region are what
+ * we expect.
+ *
+ * This is typically used after we have copied a module into kernel space,
+ * and we're about to start executing code from that module.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm1026_icache_invalidate_range)
+	bic	r0, r0, #DCACHELINESIZE - 1	@ Safety check
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bhi	cpu_arm1026_cache_clean_invalidate_all_r2
+
+1:	mcr	p15, 0, r0, c7, c5, 1		@ clean I entries
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+ENTRY(cpu_arm1026_icache_invalidate_page)
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mov	pc, lr
+
+
+/* ================================== TLB ================================= */
+
+/*
+ * cpu_arm1026_tlb_invalidate_all()
+ *
+ * Invalidate all TLB entries
+ */
+	.align	5
+ENTRY(cpu_arm1026_tlb_invalidate_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_tlb_invalidate_range(start, end)
+ *
+ * invalidate TLB entries covering the specified range
+ *
+ * start: range start address
+ * end:   range end address
+ */
+	.align	5
+ENTRY(cpu_arm1026_tlb_invalidate_range)
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+	bhi	cpu_arm1026_tlb_invalidate_all
+
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+
+	bic	r0, r0, #(PAGESIZE - 1) & 0x00ff
+	bic	r0, r0, #(PAGESIZE - 1) & 0xff00
+
+1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	add	r0, r0, #PAGESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_tlb_invalidate_page(page, flags)
+ *
+ * invalidate the TLB entries for the specified page.
+ *
+ * page:  page to invalidate
+ * flags: non-zero if we include the I TLB
+ */
+	.align	5
+ENTRY(cpu_arm1026_tlb_invalidate_page)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+	teq	r1, #0
+	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcrne	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm1026_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_arm1026_set_pgd)
+	mov	ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	/* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+@ && 'Clean & Invalidate whole DCache'
+1:	mrc	p15, 0, r15, c7, c14, 3 	@ test,clean,invalidate
+	bne	1b
+#endif
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_set_pmd(pmdp, pmd)
+ *
+ * Set a level 1 translation table entry, and clean it out of
+ * any caches such that the MMUs can load it correctly.
+ *
+ * pmdp: pointer to PMD entry
+ * pmd:  PMD value to store
+ */
+	.align	5
+ENTRY(cpu_arm1026_set_pmd)
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	eor	r2, r1, #0x0a			@ C & Section
+	tst	r2, #0x0b
+	biceq	r1, r1, #4			@ clear bufferable bit
+#endif
+	str	r1, [r0]
+#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	5
+ENTRY(cpu_arm1026_set_pte)
+	str	r1, [r0], #-1024		@ linux version
+
+	eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+	bic	r2, r1, #0xff0
+	bic	r2, r2, #3
+	orr	r2, r2, #HPTE_TYPE_SMALL
+
+	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	orrne	r2, r2, #HPTE_AP_READ
+
+	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+	orreq	r2, r2, #HPTE_AP_WRITE
+
+	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
+	movne	r2, #0
+
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	eor	r3, r2, #0x0a			@ C & small page?
+	tst	r3, #0x0b
+	biceq	r2, r2, #4
+#endif
+	str	r2, [r0]			@ hardware version
+	mov	r0, r0
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+
+ENTRY(cpu_arm1026_name)
+	.ascii	"ARM1026EJ-S"
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+	.ascii	"i"
+#endif
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+	.ascii	"d"
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	.ascii	"(wt)"
+#else
+	.ascii	"(wb)"
+#endif
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
+	.ascii	"B"
+#endif
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+	.ascii	"RR"
+#endif
+#endif
+	.ascii	"\0"
+	.align
+
+	.section ".text.init", #alloc, #execinstr
+
+__arm1026_setup:
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
+	mcr	p15, 0, r4, c2, c0		@ load page table pointer
+
+
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mov	r0, #4				@ disable write-back on caches explicitly
+	mcr	p15, 7, r0, c15, c0, 0
+#endif 
+
+	mov	r0, #0x1f			@ Domains 0, 1 = client
+	mcr	p15, 0, r0, c3, c0		@ load domain access register
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+/*
+ * Clear out 'unwanted' bits (then put them in if we need them)
+ */
+						@   VI ZFRS BLDP WCAM
+	bic	r0, r0, #0x0e00
+	bic	r0, r0, #0x0002
+	bic	r0, r0, #0x000c
+	bic	r0, r0, #0x1000 		@ ...0 000. .... 000.
+/*
+ * Turn on what we want
+ */
+	orr	r0, r0, #0x0031
+	orr	r0, r0, #0x2100 		@ ..1. ...1 ..11 ...1
+
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+	orr	r0, r0, #0x4000 		@ .1.. .... .... ....
+#endif
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
+	orr	r0, r0, #0x0800 		@ ....Z...........
+#endif
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+	orr	r0, r0, #0x0004 		@ .... .... .... .1..
+#endif
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+	orr	r0, r0, #0x1000 		@ ...1 .... .... ....
+#endif
+	mov	pc, lr
+
+	.text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	arm1026_processor_functions, #object
+arm1026_processor_functions:
+	.word	cpu_arm1026_data_abort
+	.word	cpu_arm1026_check_bugs
+	.word	cpu_arm1026_proc_init
+	.word	cpu_arm1026_proc_fin
+	.word	cpu_arm1026_reset
+	.word	cpu_arm1026_do_idle
+
+	/* cache */
+	.word	cpu_arm1026_cache_clean_invalidate_all
+	.word	cpu_arm1026_cache_clean_invalidate_range
+	.word	cpu_arm1026_flush_ram_page
+
+	/* dcache */
+	.word	cpu_arm1026_dcache_invalidate_range
+	.word	cpu_arm1026_dcache_clean_range
+	.word	cpu_arm1026_dcache_clean_page
+	.word	cpu_arm1026_dcache_clean_entry
+
+	/* icache */
+	.word	cpu_arm1026_icache_invalidate_range
+	.word	cpu_arm1026_icache_invalidate_page
+
+	/* tlb */
+	.word	cpu_arm1026_tlb_invalidate_all
+	.word	cpu_arm1026_tlb_invalidate_range
+	.word	cpu_arm1026_tlb_invalidate_page
+
+	/* pgtable */
+	.word	cpu_arm1026_set_pgd
+	.word	cpu_arm1026_set_pmd
+	.word	cpu_arm1026_set_pte
+	.size	arm1026_processor_functions, . - arm1026_processor_functions
+
+	.type	cpu_arm1026_info, #object
+cpu_arm1026_info:
+	.long	0
+	.long	cpu_arm1026_name
+	.size	cpu_arm1026_info, . - cpu_arm1026_info
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv5EJ"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v5EJ"
+	.size	cpu_elf_name, . - cpu_elf_name
+	.align
+
+	.section ".proc.info", #alloc, #execinstr
+
+	.type	__arm1026_proc_info,#object
+__arm1026_proc_info:
+	.long	0x4100a260
+	.long	0xff00fff0
+	.long	0x00000c1e			@ mmuflags
+	b	__arm1026_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | \
+		HWCAP_FAST_MULT
+	.long	cpu_arm1026_info
+	.long	arm1026_processor_functions
+	.size	__arm1026_proc_info, . - __arm1026_proc_info
diff -urN linux-2.4.22-pre2/arch/arm/mm/proc-arm2,3.S linux-2.4.22-pre3/arch/arm/mm/proc-arm2,3.S
--- linux-2.4.22-pre2/arch/arm/mm/proc-arm2,3.S	2001-03-06 19:44:35.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mm/proc-arm2,3.S	2003-07-05 18:09:36.000000000 -0700
@@ -275,7 +275,6 @@
 _arm2_3_check_bugs:
 		bics	pc, lr, #0x04000000		@ Clear FIQ disable bit
 
-armvlsi_name:	.asciz	"ARM/VLSI"
 _arm2_name:	.asciz	"ARM 2"
 _arm250_name:	.asciz	"ARM 250"
 _arm3_name:	.asciz	"ARM 3"
@@ -295,7 +294,7 @@
 		.word	_arm2_xchg_4
 
 cpu_arm2_info:
-		.long	armvlsi_name
+		.long	0
 		.long	_arm2_name
 
 		.globl	SYMBOL_NAME(arm250_processor_functions)
@@ -308,7 +307,7 @@
 		.word	_arm3_xchg_4
 
 cpu_arm250_info:
-		.long	armvlsi_name
+		.long	0
 		.long	_arm250_name
 
 		.globl	SYMBOL_NAME(arm3_processor_functions)
@@ -321,7 +320,7 @@
 		.word	_arm3_xchg_4
 
 cpu_arm3_info:
-		.long	armvlsi_name
+		.long	0
 		.long	_arm3_name
 
 arm2_arch_name:	.asciz	"armv1"
diff -urN linux-2.4.22-pre2/arch/arm/mm/proc-arm6,7.S linux-2.4.22-pre3/arch/arm/mm/proc-arm6,7.S
--- linux-2.4.22-pre2/arch/arm/mm/proc-arm6,7.S	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/proc-arm6,7.S	2003-07-05 18:09:36.000000000 -0700
@@ -68,13 +68,27 @@
  * Purpose : flush a TLB entry
  */
 ENTRY(cpu_arm6_tlb_invalidate_range)
-ENTRY(cpu_arm7_tlb_invalidate_range)
-1:		mcr	p15, 0, r0, c6, c0, 0		@ flush TLB
+                @ arm 6 tbl purge reg is bits 12 - 31
+1:		mcr	p15, 0, r0, c6, c0, 0		@ purge TLB
 		add	r0, r0, #4096
 		cmp	r0, r1
 		blt	1b
 		mov	pc, lr
 
+ENTRY(cpu_arm7_tlb_invalidate_range)
+#if defined(CONFIG_ARCH_RISCSTATION)
+		mov	r0, #0
+		mcr	p15, 0, r0, c5, c0, 0		@ flush TLB
+		mov	pc, lr
+#else
+                @ arm 7 tbl purge reg is bits 14 - 31
+1:		mcr	p15, 0, r0, c6, c0, 0		@ purge TLB
+		add	r0, r0, #0x4000
+		cmp	r0, r1
+		blt	1b
+		mov	pc, lr
+#endif
+
 /*
  * Function: arm6_7_tlb_invalidate_page (unsigned long address, int flags)
  *
@@ -143,7 +157,7 @@
 		movs	pc, lr
 
 		b	Ldata_unknown
-		b	Ldata_unknown
+		b	Ldata_simple			@ swp
 		b	Ldata_unknown
 		b	Ldata_unknown
 		b	Ldata_lateldrpostconst		@ ldr	rd, [rn], #m
@@ -160,7 +174,7 @@
 Ldata_unknown:	@ Part of jumptable
 		mov	r0, r2
 		mov	r1, r4
-		mov	r2, r3
+		mov	r2, r5
 		bl	baddataabort
 		b	ret_from_exception
 
@@ -258,7 +272,6 @@
 
 ENTRY(cpu_arm6_do_idle)
 ENTRY(cpu_arm7_do_idle)
-		mov	r0, #-EINVAL
 		mov	pc, lr
 
 /*
@@ -349,8 +362,6 @@
 		mcr	p15, 0, r1, c1, c0, 0		@ turn off MMU etc
 		mov	pc, r0
 
-cpu_armvlsi_name:
-		.asciz	"ARM/VLSI"
 cpu_arm6_name:	.asciz	"ARM 6"
 cpu_arm610_name:
 		.asciz	"ARM 610"
@@ -461,25 +472,25 @@
 
 		.type	cpu_arm6_info, #object
 cpu_arm6_info:
-		.long	cpu_armvlsi_name
+		.long	0
 		.long	cpu_arm6_name
 		.size	cpu_arm6_info, . - cpu_arm6_info
 
 		.type	cpu_arm610_info, #object
 cpu_arm610_info:
-		.long	cpu_armvlsi_name
+		.long	0
 		.long	cpu_arm610_name
 		.size	cpu_arm610_info, . - cpu_Arm610_info
 
 		.type	cpu_arm7_info, #object
 cpu_arm7_info:
-		.long	cpu_armvlsi_name
+		.long	0
 		.long	cpu_arm7_name
 		.size	cpu_arm7_info, . - cpu_arm7_info
 
 		.type	cpu_arm710_info, #object
 cpu_arm710_info:
-		.long	cpu_armvlsi_name
+		.long	0
 		.long	cpu_arm710_name
 		.size	cpu_arm710_info, . - cpu_arm710_info
 
diff -urN linux-2.4.22-pre2/arch/arm/mm/proc-arm720.S linux-2.4.22-pre3/arch/arm/mm/proc-arm720.S
--- linux-2.4.22-pre2/arch/arm/mm/proc-arm720.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/proc-arm720.S	2003-07-05 18:09:36.000000000 -0700
@@ -37,6 +37,11 @@
 #include <asm/hardware.h>
 
 /*
+ * and the page size
+ */
+#define PAGESIZE	4096
+
+/*
  * Function: arm720_cache_clean_invalidate_all (void)
  *	   : arm720_cache_clean_invalidate_page (unsigned long address, int size,
  *                                    int flags)
@@ -86,8 +91,11 @@
  * Purpose : flush a TLB entry
  */
 ENTRY(cpu_arm720_tlb_invalidate_range)
+		sub	r3, r1, r0
+		cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+		bhi	cpu_arm720_tlb_invalidate_all
 1:		mcr	p15, 0, r0, c8, c7, 1		@ flush TLB (v4)
-		add	r0, r0, #4096
+		add	r0, r0, #PAGESIZE
 		cmp	r0, r1
 		blt	1b
 		mov	pc, lr
@@ -438,8 +446,6 @@
 		mov	pc, r0
 
 	
-cpu_armvlsi_name:
-		.asciz	"ARM"
 cpu_arm720_name:
 		.asciz	"ARM720T"
 		.align
@@ -500,7 +506,7 @@
 
 		.type	cpu_arm720_info, #object
 cpu_arm720_info:
-		.long	cpu_armvlsi_name
+		.long	0
 		.long	cpu_arm720_name
 		.size	cpu_arm720_info, . - cpu_arm720_info
 	
@@ -527,7 +533,7 @@
 		b	__arm720_setup				@ cpu_flush
 		.long	cpu_arch_name				@ arch_name
 		.long	cpu_elf_name				@ elf_name
-		.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT	@ elf_hwcap
+		.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB	@ elf_hwcap
 		.long	cpu_arm720_info				@ info
 		.long	arm720_processor_functions
 		.size	__arm720_proc_info, . - __arm720_proc_info
diff -urN linux-2.4.22-pre2/arch/arm/mm/proc-arm920.S linux-2.4.22-pre3/arch/arm/mm/proc-arm920.S
--- linux-2.4.22-pre2/arch/arm/mm/proc-arm920.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/proc-arm920.S	2003-07-05 18:09:36.000000000 -0700
@@ -134,9 +134,7 @@
  */
 	.align	5
 ENTRY(cpu_arm920_do_idle)
-#if defined(CONFIG_CPU_ARM920_CPU_IDLE)
 	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
-#endif
 	mov	pc, lr
 
 /* ================================= CACHE ================================ */
@@ -155,7 +153,7 @@
 	mov	r2, #1
 cpu_arm920_cache_clean_invalidate_all_r2:
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
 /*
@@ -193,7 +191,7 @@
 	cmp	r3, #MAX_AREA_SIZE
 	bgt	cpu_arm920_cache_clean_invalidate_all_r2
 1:	teq	r2, #0
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
 	add	r0, r0, #DCACHELINESIZE
@@ -224,7 +222,7 @@
 	.align	5
 ENTRY(cpu_arm920_flush_ram_page)
 	mov	r1, #PAGESIZE
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
@@ -410,6 +408,10 @@
  */
 	.align	5
 ENTRY(cpu_arm920_tlb_invalidate_range)
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+	bhi	cpu_arm920_tlb_invalidate_all
+
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 
@@ -454,7 +456,7 @@
 	.align	5
 ENTRY(cpu_arm920_set_pgd)
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	/* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
@@ -487,7 +489,7 @@
  */
 	.align	5
 ENTRY(cpu_arm920_set_pmd)
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r2, r1, #0x0a			@ C & Section
 	tst	r2, #0x0b
 	biceq	r1, r1, #4			@ clear bufferable bit
@@ -521,7 +523,7 @@
 	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
 	movne	r2, #0
 
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r3, r2, #0x0a			@ C & small page?
 	tst	r3, #0x0b
 	biceq	r2, r2, #4
@@ -533,19 +535,14 @@
 	mov	pc, lr
 
 
-cpu_manu_name:
-	.asciz	"ARM/CIRRUS"
 ENTRY(cpu_arm920_name)
 	.ascii	"Arm920T"
-#if defined(CONFIG_CPU_ARM920_CPU_IDLE)
-	.ascii	"s"
-#endif
-#if defined(CONFIG_CPU_ARM920_I_CACHE_ON)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	.ascii	"i"
 #endif
-#if defined(CONFIG_CPU_ARM920_D_CACHE_ON)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	.ascii	"d"
-#if defined(CONFIG_CPU_ARM920_WRITETHROUGH)
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	.ascii	"(wt)"
 #else
 	.ascii	"(wb)"
@@ -579,10 +576,10 @@
 	orr	r0, r0, #0x0031
 	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
 
-#ifdef CONFIG_CPU_ARM920_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	orr	r0, r0, #0x0004			@ .... .... .... .1..
 #endif
-#ifdef CONFIG_CPU_ARM920_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	orr	r0, r0, #0x1000			@ ...1 .... .... ....
 #endif
 	mov	pc, lr
@@ -630,7 +627,7 @@
 
 	.type	cpu_arm920_info, #object
 cpu_arm920_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_arm920_name
 	.size	cpu_arm920_info, . - cpu_arm920_info
 
@@ -655,7 +652,7 @@
 	b	__arm920_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
 	.long	cpu_arm920_info
 	.long	arm920_processor_functions
 	.size	__arm920_proc_info, . - __arm920_proc_info
diff -urN linux-2.4.22-pre2/arch/arm/mm/proc-arm922.S linux-2.4.22-pre3/arch/arm/mm/proc-arm922.S
--- linux-2.4.22-pre2/arch/arm/mm/proc-arm922.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/proc-arm922.S	2003-07-05 18:09:36.000000000 -0700
@@ -130,9 +130,7 @@
  */
 	.align	5
 ENTRY(cpu_arm922_do_idle)
-#if defined(CONFIG_CPU_ARM922_CPU_IDLE)
 	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
-#endif
 	mov	pc, lr
 
 /* ================================= CACHE ================================ */
@@ -151,7 +149,7 @@
 	mov	r2, #1
 cpu_arm922_cache_clean_invalidate_all_r2:
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
 /*
@@ -189,7 +187,7 @@
 	cmp	r3, #MAX_AREA_SIZE
 	bgt	cpu_arm922_cache_clean_invalidate_all_r2
 1:	teq	r2, #0
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
 	add	r0, r0, #DCACHELINESIZE
@@ -220,7 +218,7 @@
 	.align	5
 ENTRY(cpu_arm922_flush_ram_page)
 	mov	r1, #PAGESIZE
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
@@ -406,6 +404,10 @@
  */
 	.align	5
 ENTRY(cpu_arm922_tlb_invalidate_range)
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+	bhi	cpu_arm922_tlb_invalidate_all
+
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 
@@ -450,7 +452,7 @@
 	.align	5
 ENTRY(cpu_arm922_set_pgd)
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	/* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
@@ -483,7 +485,7 @@
  */
 	.align	5
 ENTRY(cpu_arm922_set_pmd)
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r2, r1, #0x0a			@ C & Section
 	tst	r2, #0x0b
 	biceq	r1, r1, #4			@ clear bufferable bit
@@ -517,7 +519,7 @@
 	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
 	movne	r2, #0
 
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r3, r2, #0x0a			@ C & small page?
 	tst	r3, #0x0b
 	biceq	r2, r2, #4
@@ -529,19 +531,14 @@
 	mov	pc, lr
 
 
-cpu_manu_name:
-	.asciz	"ARM/ALTERA"
 ENTRY(cpu_arm922_name)
 	.ascii	"Arm922T"
-#if defined(CONFIG_CPU_ARM922_CPU_IDLE)
-	.ascii	"s"
-#endif
-#if defined(CONFIG_CPU_ARM922_I_CACHE_ON)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	.ascii	"i"
 #endif
-#if defined(CONFIG_CPU_ARM922_D_CACHE_ON)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	.ascii	"d"
-#if defined(CONFIG_CPU_ARM922_WRITETHROUGH)
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	.ascii	"(wt)"
 #else
 	.ascii	"(wb)"
@@ -575,10 +572,10 @@
 	orr	r0, r0, #0x0031
 	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
 
-#ifdef CONFIG_CPU_ARM922_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	orr	r0, r0, #0x0004			@ .... .... .... .1..
 #endif
-#ifdef CONFIG_CPU_ARM922_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	orr	r0, r0, #0x1000			@ ...1 .... .... ....
 #endif
 	mov	pc, lr
@@ -626,7 +623,7 @@
 
 	.type	cpu_arm922_info, #object
 cpu_arm922_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_arm922_name
 	.size	cpu_arm922_info, . - cpu_arm922_info
 
@@ -651,7 +648,7 @@
 	b	__arm922_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
 	.long	cpu_arm922_info
 	.long	arm922_processor_functions
 	.size	__arm922_proc_info, . - __arm922_proc_info
diff -urN linux-2.4.22-pre2/arch/arm/mm/proc-arm925.S linux-2.4.22-pre3/arch/arm/mm/proc-arm925.S
--- linux-2.4.22-pre2/arch/arm/mm/proc-arm925.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/mm/proc-arm925.S	2003-07-05 18:09:36.000000000 -0700
@@ -0,0 +1,732 @@
+/*
+ *  linux/arch/arm/mm/arm925.S: MMU functions for ARM925
+ *
+ *  Copyright (C) 1999-2001 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *  Copyright (C) 2002 RidgeRun, Inc.
+ *  Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm925.
+ */
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions.  Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE	(2 * 1024)
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE	16
+#define ICACHELINESIZE	16
+
+/*
+ * and the page size
+ */
+#define PAGESIZE	4096
+
+	.text
+
+/*
+ * cpu_arm925_data_abort()
+ *
+ * obtain information about current aborted instruction
+ * Note: we read user space.  This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture.  Unfortunately, this does happen.  We live with it.
+ *
+ * Inputs:
+ *  r2 = address of abort
+ *  r3 = cpsr of abort
+ *
+ * Returns:
+ *  r0 = address of abort
+ *  r1 != 0 if writing
+ *  r3 = FSR
+ *  r4 = corrupted
+ */
+	.align	5
+ENTRY(cpu_arm925_data_abort)
+	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+	mrc	p15, 0, r4, c5, c0, 0		@ get FSR
+
+	tst	r3, #1<<5			@ Check for Thumb-bit (NE -> found)
+	ldrneh	r1, [r2]			@ Read aborted Thumb instruction
+	tstne	r1, r1, lsr #12 		@ C = bit 11
+
+	ldreq	r1, [r2]			@ Read aborted ARM instruction
+	tsteq	r1, r1, lsr #21 		@ C = bit 20
+
+	sbc	r1, r1, r1			@ r1 = C - 1
+	and	r3, r4, #255
+	mov	pc, lr
+
+/*
+ * cpu_arm925_check_bugs()
+ */
+ENTRY(cpu_arm925_check_bugs)
+	mrs	ip, cpsr
+	bic	ip, ip, #F_BIT
+	msr	cpsr, ip
+	mov	pc, lr
+
+/*
+ * cpu_arm925_proc_init()
+ */
+ENTRY(cpu_arm925_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_arm925_proc_fin()
+ */
+ENTRY(cpu_arm925_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #F_BIT | I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	cpu_arm925_cache_clean_invalidate_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000			@ ...i............
+	bic	r0, r0, #0x000e			@ ............wca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_arm925_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_arm925_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x000f			@ ............wcam
+	bic	ip, ip, #0x1100			@ ...i...s........
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0
+
+/*
+ * cpu_arm925_do_idle()
+ */
+	.align	5
+ENTRY(cpu_arm925_do_idle)
+#if defined(CONFIG_CPU_ARM925_CPU_IDLE)
+	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
+#endif
+	mov	pc, lr
+
+/* ================================= CACHE ================================ */
+
+
+/*
+ * cpu_arm925_cache_clean_invalidate_all()
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ *  1. we should preserve r0 at all times
+ */
+	.align	5
+ENTRY(cpu_arm925_cache_clean_invalidate_all)
+	mov	r2, #1
+cpu_arm925_cache_clean_invalidate_all_r2:
+	mov	ip, #0
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+/*
+ * 'Clean & Invalidate whole DCache'
+ * Re-written to use Index Ops.
+ * NOTE: Requires TI925T Configuration Register C bit <- 0
+ *       for clean and invalidate of both D-Cache sets.
+ */
+	mov	r3, #255 << 4		@ 256 entries/set
+					@ ((NSETS - 1) << (CIR[13-12] + 3))
+2:	mcr	p15, 0, r3, c7, c14, 2	@ clean & invalidate D index
+	subs	r3, r3, #1 << 4
+	bcs	2b			@ entries 255 to 0
+#endif
+	teq	r2, #0
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm925_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * This is a little misleading, it is not intended to clean out
+ * the i-cache but to make sure that any data written to the
+ * range is made consistant.  This means that when we execute code
+ * in that region, everything works as we expect.
+ *
+ * This generally means writing back data in the Dcache and
+ * write buffer and flushing the Icache over that region
+ * start: Area start address
+ * end:   Area end address
+ * flags: nonzero for I cache as well
+ */
+		.align	5
+ENTRY(cpu_arm925_cache_clean_invalidate_range)
+	bic	r0, r0, #DCACHELINESIZE - 1	@ && added by PGM
+	bic	r1, r1, #DCACHELINESIZE - 1     @ && added by DHM
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bgt	cpu_arm925_cache_clean_invalidate_all_r2
+1:	teq	r2, #0
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+#else
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+#endif
+	cmp	r0, r1
+	blt	1b
+
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm925_flush_ram_page(page)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * page: page to clean and invalidate
+ */
+	.align	5
+ENTRY(cpu_arm925_flush_ram_page)
+	mov	r1, #PAGESIZE
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+#else
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+#endif
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ D-CACHE =============================== */
+
+/*
+ * cpu_arm925_dcache_invalidate_range(start, end)
+ *
+ * throw away all D-cached data in specified region without an obligation
+ * to write them back.  Note however that we must clean the D-cached entries
+ * around the boundaries if the start and/or end address are not cache
+ * aligned.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm925_dcache_invalidate_range)
+#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
+	tst	r0, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+#endif
+	bic	r0, r0, #DCACHELINESIZE - 1
+	bic	r1, r1, #DCACHELINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blt	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm925_dcache_clean_range(start, end)
+ *
+ * For the specified virtual address range, ensure that all caches contain
+ * clean data, such that peripheral accesses to the physical RAM fetch
+ * correct data.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm925_dcache_clean_range)
+#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
+	bic	r0, r0, #DCACHELINESIZE - 1
+	sub	r1, r1, r0
+	cmp	r1, #MAX_AREA_SIZE
+	mov	r2, #0
+	bgt	cpu_arm925_cache_clean_invalidate_all_r2
+
+	bic	r1, r1, #DCACHELINESIZE -1
+	add	r1, r1, #DCACHELINESIZE
+
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #DCACHELINESIZE
+	bpl	1b
+#endif
+	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm925_dcache_clean_page(page)
+ *
+ * Cleans a single page of dcache so that if we have any future aliased
+ * mappings, they will be consistent at the time that they are created.
+ *
+ * page: virtual address of page to clean from dcache
+ *
+ * Note:
+ *  1. we don't need to flush the write buffer in this case.
+ *  2. we don't invalidate the entries since when we write the page
+ *     out to disk, the entries may get reloaded into the cache.
+ */
+	.align	5
+ENTRY(cpu_arm925_dcache_clean_page)
+#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+#endif
+	mov	pc, lr
+
+/*
+ * cpu_arm925_dcache_clean_entry(addr)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+	.align	5
+ENTRY(cpu_arm925_dcache_clean_entry)
+#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ I-CACHE =============================== */
+
+/*
+ * cpu_arm925_icache_invalidate_range(start, end)
+ *
+ * invalidate a range of virtual addresses from the Icache
+ *
+ * This is a little misleading, it is not intended to clean out
+ * the i-cache but to make sure that any data written to the
+ * range is made consistant.  This means that when we execute code
+ * in that region, everything works as we expect.
+ *
+ * This generally means writing back data in the Dcache and
+ * write buffer and flushing the Icache over that region
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ *
+ * NOTE: ICACHELINESIZE == DCACHELINESIZE (so we don't need to
+ * loop twice, once for i-cache, once for d-cache)
+ */
+	.align	5
+ENTRY(cpu_arm925_icache_invalidate_range)
+	bic	r0, r0, #ICACHELINESIZE - 1	@ Safety check
+	sub	r1, r1, r0
+	cmp	r1, #MAX_AREA_SIZE
+	bgt	cpu_arm925_cache_clean_invalidate_all_r2
+
+	bic	r1, r1, #ICACHELINESIZE - 1
+	add	r1, r1, #ICACHELINESIZE
+
+1:	mcr	p15, 0, r0, c7, c5, 1		@ Clean I entry
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
+	add	r0, r0, #ICACHELINESIZE
+	subs	r1, r1, #ICACHELINESIZE
+	bne	1b
+
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+
+ENTRY(cpu_arm925_icache_invalidate_page)
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+        nop
+        nop
+        nop
+        nop
+	mov	pc, lr
+
+/* ================================== TLB ================================= */
+
+/*
+ * cpu_arm925_tlb_invalidate_all()
+ *
+ * Invalidate all TLB entries
+ */
+	.align	5
+ENTRY(cpu_arm925_tlb_invalidate_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm925_tlb_invalidate_range(start, end)
+ *
+ * invalidate TLB entries covering the specified range
+ *
+ * start: range start address
+ * end:   range end address
+ */
+	.align	5
+ENTRY(cpu_arm925_tlb_invalidate_range)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+
+	mov	r3, #PAGESIZE
+	sub	r3, r3, #1
+	bic 	r0, r0, r3
+	bic	r1, r1, r3
+
+1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	add	r0, r0, #PAGESIZE
+	cmp	r0, r1
+	blt	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm925_tlb_invalidate_page(page, flags)
+ *
+ * invalidate the TLB entries for the specified page.
+ *
+ * page:  page to invalidate
+ * flags: non-zero if we include the I TLB
+ */
+	.align	5
+ENTRY(cpu_arm925_tlb_invalidate_page)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+	teq	r1, #0
+	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcrne	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm925_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_arm925_set_pgd)
+	mov	ip, #0
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I & D cache
+#else
+/*
+ * 'Clean & Invalidate whole DCache'
+ * Re-written to use Index Ops.
+ * NOTE: Requires TI925T Configuration Register C bit <- 0
+ *       for clean and invalidate of both D-Cache sets.
+ */
+	mov	r3, #255 << 4		@ 256 entries/set
+					@ ((NSETS - 1) << (CIR[13-12] + 3))
+2:	mcr	p15, 0, r3, c7, c14, 2	@ clean & invalidate D index
+	subs	r3, r3, #1 << 4
+	bcs	2b			@ entries 255 to 0
+#endif
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm925_set_pmd(pmdp, pmd)
+ *
+ * Set a level 1 translation table entry, and clean it out of
+ * any caches such that the MMUs can load it correctly.
+ *
+ * pmdp: pointer to PMD entry
+ * pmd:  PMD value to store
+ */
+	.align	5
+ENTRY(cpu_arm925_set_pmd)
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+	eor	r2, r1, #0x0a			@ C & Section
+	tst	r2, #0x0b
+	biceq	r1, r1, #4			@ clear bufferable bit
+#endif
+	str	r1, [r0]
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm925_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	5
+ENTRY(cpu_arm925_set_pte)
+	str	r1, [r0], #-1024		@ linux version
+
+	eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+	bic	r2, r1, #0xff0
+	bic	r2, r2, #3
+	orr	r2, r2, #HPTE_TYPE_SMALL
+
+	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	orrne	r2, r2, #HPTE_AP_READ
+
+	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+	orreq	r2, r2, #HPTE_AP_WRITE
+
+	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
+	movne	r2, #0
+
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+	eor	r3, r2, #0x0a			@ C & small page?
+	tst	r3, #0x0b
+	biceq	r2, r2, #4
+#endif
+	str	r2, [r0]			@ hardware version
+	mov	r0, r0
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+
+ENTRY(cpu_arm925_name)
+	.ascii	"Arm925T"
+#if defined(CONFIG_CPU_ARM925_CPU_IDLE)
+	.ascii	"s"
+#endif
+#if defined(CONFIG_CPU_ARM925_I_CACHE_ON)
+	.ascii	"i"
+#endif
+#if defined(CONFIG_CPU_ARM925_D_CACHE_ON)
+	.ascii	"d"
+#if defined(CONFIG_CPU_ARM925_WRITETHROUGH)
+	.ascii	"(wt)"
+#else
+	.ascii	"(wb)"
+#endif
+#endif
+	.ascii	"\0"
+
+ENTRY(cpu_arm915_name)
+	.ascii	"Arm915T"
+#if defined(CONFIG_CPU_ARM925_CPU_IDLE)
+	.ascii	"s"
+#endif
+#if defined(CONFIG_CPU_ARM925_I_CACHE_ON)
+	.ascii	"i"
+#endif
+#if defined(CONFIG_CPU_ARM925_D_CACHE_ON)
+	.ascii	"d"
+#if defined(CONFIG_CPU_ARM925_WRITETHROUGH)
+	.ascii	"(wt)"
+#else
+	.ascii	"(wb)"
+#endif
+#endif
+	.ascii	"\0"
+	.align
+
+	.section ".text.init", #alloc, #execinstr
+
+__arm925_setup:
+	mov	r0, #0
+#if defined(CONFIG_CPU_ARM925_NON_STREAMING_ON)
+        orr     r0,r0,#0x80
+#endif
+#if defined(CONFIG_CPU_ARM925_TRANSPARENT_ON)
+        orr     r0,r0,#0x2
+#endif
+	mcr	p15, 0, r0, c15, c1, 0		@ write TI config register
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
+	mcr	p15, 0, r4, c2, c0		@ load page table pointer
+	mov	r0, #0x1f			@ Domains 0, 1 = client
+	mcr	p15, 0, r0, c3, c0		@ load domain access register
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+/*
+ * Clear out 'unwanted' bits (then put them in if we need them)
+ */
+						@   VI ZFRS BLDP WCAM
+	bic	r0, r0, #0x0e00
+	bic	r0, r0, #0x0002
+	bic	r0, r0, #0x000c
+	bic	r0, r0, #0x1000			@ ...0 000. .... 000.
+/*
+ * Turn on what we want
+ */
+	orr	r0, r0, #0x0031
+	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
+
+#ifdef CONFIG_CPU_ARM925_WRITEBUFFER_ON
+	orr	r0, r0, #0x0008			@ .... .... .... 1...
+#endif
+#ifdef CONFIG_CPU_ARM925_D_CACHE_ON
+	orr	r0, r0, #0x0004			@ .... .... .... .1..
+#endif
+#ifdef CONFIG_CPU_ARM925_I_CACHE_ON
+	orr	r0, r0, #0x1000			@ ...1 .... .... ....
+#endif
+	mov	pc, lr
+
+	.text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	arm925_processor_functions, #object
+arm925_processor_functions:
+	.word	cpu_arm925_data_abort
+	.word	cpu_arm925_check_bugs
+	.word	cpu_arm925_proc_init
+	.word	cpu_arm925_proc_fin
+	.word	cpu_arm925_reset
+	.word   cpu_arm925_do_idle
+
+	/* cache */
+	.word	cpu_arm925_cache_clean_invalidate_all
+	.word	cpu_arm925_cache_clean_invalidate_range
+	.word	cpu_arm925_flush_ram_page
+
+	/* dcache */
+	.word	cpu_arm925_dcache_invalidate_range
+	.word	cpu_arm925_dcache_clean_range
+	.word	cpu_arm925_dcache_clean_page
+	.word	cpu_arm925_dcache_clean_entry
+
+	/* icache */
+	.word	cpu_arm925_icache_invalidate_range
+	.word	cpu_arm925_icache_invalidate_page
+
+	/* tlb */
+	.word	cpu_arm925_tlb_invalidate_all
+	.word	cpu_arm925_tlb_invalidate_range
+	.word	cpu_arm925_tlb_invalidate_page
+
+	/* pgtable */
+	.word	cpu_arm925_set_pgd
+	.word	cpu_arm925_set_pmd
+	.word	cpu_arm925_set_pte
+	.size	arm925_processor_functions, . - arm925_processor_functions
+
+	.type	cpu_arm925_info, #object
+cpu_arm925_info:
+	.long	0
+	.long	cpu_arm925_name
+	.size	cpu_arm925_info, . - cpu_arm925_info
+
+	.type	cpu_arm915_info, #object
+cpu_arm915_info:
+	.long	cpu_manu_name
+	.long	cpu_arm915_name
+	.size	cpu_arm915_info, . - cpu_arm915_info
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv4"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v4"
+	.size	cpu_elf_name, . - cpu_elf_name
+	.align
+
+#if	defined(CONFIG_CPU_ARM925_WRITETHROUGH)
+#  define	MMU_FLAGS	0x00000c1a
+#else
+#  define	MMU_FLAGS	0x00000c1e
+#endif
+	.section ".proc.info", #alloc, #execinstr
+
+	.type	__arm925_proc_info,#object
+__arm925_proc_info:
+	.long	0x54029252
+	.long	0xffffffff
+	.long	MMU_FLAGS
+	b	__arm925_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
+	.long	cpu_arm925_info
+	.long	arm925_processor_functions
+	.size	__arm925_proc_info, . - __arm925_proc_info
+
+	.type	__arm915_proc_info,#object
+__arm915_proc_info:
+	.long	0x54029152
+	.long	0xffffffff
+	.long	MMU_FLAGS
+	b	__arm925_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
+	.long	cpu_arm915_info
+	.long	arm925_processor_functions
+	.size	__arm925_proc_info, . - __arm925_proc_info
diff -urN linux-2.4.22-pre2/arch/arm/mm/proc-arm926.S linux-2.4.22-pre3/arch/arm/mm/proc-arm926.S
--- linux-2.4.22-pre2/arch/arm/mm/proc-arm926.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/proc-arm926.S	2003-07-05 18:09:36.000000000 -0700
@@ -81,9 +81,8 @@
 
 	tst	r3, #1<<5			@ Check for Thumb-bit (NE -> found)
 	ldrneh	r1, [r2]			@ Read aborted Thumb instruction        
-	tstne	r1, r1, lsr #12 		@ C = bit 11
-
 	ldreq	r1, [r2]			@ Read aborted ARM instruction
+	movne	r1, r1, lsl #(20-12)		@ shift thumb bit 10 to ARM bit 20
 	tsteq	r1, r1, lsr #21 		@ C = bit 20
 
 	sbc	r1, r1, r1			@ r1 = C - 1
@@ -146,9 +145,7 @@
  */
 	.align	5
 ENTRY(cpu_arm926_do_idle)
-#if defined(CONFIG_CPU_ARM926_CPU_IDLE)
 	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
-#endif
 	mov	pc, lr
 
 /* ================================= CACHE ================================ */
@@ -167,7 +164,7 @@
 	mov	r2, #1
 cpu_arm926_cache_clean_invalidate_all_r2:
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
 1:	mrc	p15, 0, r15, c7, c14, 3 	@ test,clean,invalidate
@@ -202,7 +199,7 @@
 	bhi	cpu_arm926_cache_clean_invalidate_all_r2
 
 1:	teq	r2, #0
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
 	add	r0, r0, #DCACHELINESIZE
@@ -235,7 +232,7 @@
 	.align	5
 ENTRY(cpu_arm926_flush_ram_page)
 	mov	r1, #PAGESIZE
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
@@ -408,6 +405,10 @@
  */
 	.align	5
 ENTRY(cpu_arm926_tlb_invalidate_range)
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+	bhi	cpu_arm926_tlb_invalidate_all
+
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 
@@ -450,7 +451,7 @@
 	.align	5
 ENTRY(cpu_arm926_set_pgd)
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	/* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
@@ -475,7 +476,7 @@
  */
 	.align	5
 ENTRY(cpu_arm926_set_pmd)
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r2, r1, #0x0a			@ C & Section
 	tst	r2, #0x0b
 	biceq	r1, r1, #4			@ clear bufferable bit
@@ -511,38 +512,33 @@
 	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
 	movne	r2, #0
 
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r3, r2, #0x0a			@ C & small page?
 	tst	r3, #0x0b
 	biceq	r2, r2, #4
 #endif
 	str	r2, [r0]			@ hardware version
 	mov	r0, r0
-#ifndef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 #endif
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
 
-cpu_manu_name:
-	.asciz	"ARM"
 ENTRY(cpu_arm926_name)
 	.ascii	"ARM926EJ-S"
-#if defined(CONFIG_CPU_ARM926_CPU_IDLE)
-	.ascii	"s"
-#endif
-#if defined(CONFIG_CPU_ARM926_I_CACHE_ON)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	.ascii	"i"
 #endif
-#if defined(CONFIG_CPU_ARM926_D_CACHE_ON)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	.ascii	"d"
-#if defined(CONFIG_CPU_ARM926_WRITETHROUGH)
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	.ascii	"(wt)"
 #else
 	.ascii	"(wb)"
 #endif
-#ifdef CONFIG_CPU_ARM926_ROUND_ROBIN
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	.ascii	"RR"
 #endif
 #endif
@@ -559,7 +555,7 @@
 	mcr	p15, 0, r4, c2, c0		@ load page table pointer
 
 
-#if defined(CONFIG_CPU_ARM926_WRITETHROUGH) 
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mov	r0, #4				@ disable write-back on caches explicitly
 	mcr	p15, 7, r0, c15, c0, 0
 #endif 
@@ -581,13 +577,13 @@
 	orr	r0, r0, #0x0031
 	orr	r0, r0, #0x2100 		@ ..1. ...1 ..11 ...1
 
-#ifdef CONFIG_CPU_ARM926_ROUND_ROBIN
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000 		@ .1.. .... .... ....
 #endif
-#ifdef CONFIG_CPU_ARM926_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	orr	r0, r0, #0x0004 		@ .... .... .... .1..
 #endif
-#ifdef CONFIG_CPU_ARM926_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	orr	r0, r0, #0x1000 		@ ...1 .... .... ....
 #endif
 	mov	pc, lr
@@ -635,7 +631,7 @@
 
 	.type	cpu_arm926_info, #object
 cpu_arm926_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_arm926_name
 	.size	cpu_arm926_info, . - cpu_arm926_info
 
@@ -660,7 +656,8 @@
 	b	__arm926_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | \
+		HWCAP_FAST_MULT
 	.long	cpu_arm926_info
 	.long	arm926_processor_functions
 	.size	__arm926_proc_info, . - __arm926_proc_info
diff -urN linux-2.4.22-pre2/arch/arm/mm/proc-sa110.S linux-2.4.22-pre3/arch/arm/mm/proc-sa110.S
--- linux-2.4.22-pre2/arch/arm/mm/proc-sa110.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/proc-sa110.S	2003-07-05 18:09:36.000000000 -0700
@@ -159,43 +159,12 @@
 	mov	pc, r0
 
 /*
- * cpu_sa110_do_idle(type)
+ * cpu_sa110_do_idle()
  *
  * Cause the processor to idle
- *
- * type: call type:
- *   0 = slow idle
- *   1 = fast idle
- *   2 = switch to slow processor clock
- *   3 = switch to fast processor clock
  */
 	.align	5
-idle:	mcr	p15, 0, r0, c15, c8, 2		@ Wait for interrupt, cache aligned
-	mov	r0, r0				@ safety
-	mov	pc, lr
-
 ENTRY(cpu_sa110_do_idle)
-	mov	ip, #0
-	cmp	r0, #4
-	addcc	pc, pc, r0, lsl #2
-	mov	pc, lr
-
-	b	idle
-	b	idle
-	b	slow_clock
-	b	fast_clock
-
-fast_clock:
-	mcr	p15, 0, ip, c15, c1, 2		@ enable clock switching
-	mov	pc, lr
-
-slow_clock:
-	mcr	p15, 0, ip, c15, c2, 2		@ disable clock switching
-	ldr	r1, =UNCACHEABLE_ADDR		@ load from uncacheable loc
-	ldr	r1, [r1, #0]			@ force switch to MCLK
-	mov	pc, lr
-
-	.align	5
 ENTRY(cpu_sa1100_do_idle)
 	mov	r0, r0				@ 4 nop padding
 	mov	r0, r0
@@ -468,6 +437,9 @@
 ENTRY(cpu_sa1100_tlb_invalidate_range)
 	bic	r0, r0, #0x0ff
 	bic	r0, r0, #0xf00
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+	bhi	cpu_sa110_tlb_invalidate_all
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
@@ -595,8 +567,6 @@
 	mov	pc, lr
 
 
-cpu_manu_name:
-	.asciz	"Intel"
 cpu_sa110_name:
 	.asciz	"StrongARM-110"
 cpu_sa1100_name:
@@ -676,7 +646,7 @@
 
 	.type	cpu_sa110_info, #object
 cpu_sa110_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_sa110_name
 	.size	cpu_sa110_info, . - cpu_sa110_info
 
@@ -720,12 +690,12 @@
 	.size	sa1100_processor_functions, . - sa1100_processor_functions
 
 cpu_sa1100_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_sa1100_name
 	.size	cpu_sa1100_info, . - cpu_sa1100_info
 
 cpu_sa1110_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_sa1110_name
 	.size	cpu_sa1110_info, . - cpu_sa1110_info
 
diff -urN linux-2.4.22-pre2/arch/arm/mm/small_page.c linux-2.4.22-pre3/arch/arm/mm/small_page.c
--- linux-2.4.22-pre2/arch/arm/mm/small_page.c	2001-04-12 12:20:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/mm/small_page.c	2003-07-05 18:09:37.000000000 -0700
@@ -150,8 +150,8 @@
 	unsigned long flags;
 	struct page *page;
 
-	page = virt_to_page(spage);
-	if (VALID_PAGE(page)) {
+	if (virt_addr_valid(spage)) {
+		page = virt_to_page(spage);
 
 		/*
 		 * The container-page must be marked Reserved
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/ChangeLog linux-2.4.22-pre3/arch/arm/nwfpe/ChangeLog
--- linux-2.4.22-pre2/arch/arm/nwfpe/ChangeLog	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/ChangeLog	2003-07-05 18:09:37.000000000 -0700
@@ -1,3 +1,11 @@
+2003-03-22  Ralph Siemsen <ralphs@netwinder.org>
+	* Reformat all but softfloat files to get a consistent coding style.
+	  Used "indent -kr -i8 -ts8 -sob -l132 -ss" and a few manual fixups.
+	* Removed dead code and fixed function protypes to match definitions.
+	* Consolidated use of (opcode && MASK_ARITHMETIC_OPCODE) >> 20.
+	* Make 80-bit precision a compile-time option. (1%)
+	* Only initialize FPE state once in repeat-FP situations. (6%)
+
 2002-01-19  Russell King <rmk@arm.linux.org.uk>
 
 	* fpa11.h - Add documentation
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/Makefile linux-2.4.22-pre3/arch/arm/nwfpe/Makefile
--- linux-2.4.22-pre2/arch/arm/nwfpe/Makefile	2001-04-11 19:02:27.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/Makefile	2003-07-05 18:09:37.000000000 -0700
@@ -18,7 +18,11 @@
 
 nwfpe-objs		:= fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o \
 			   fpmodule.o fpopcode.o softfloat.o \
-			   single_cpdo.o double_cpdo.o extended_cpdo.o
+			   single_cpdo.o double_cpdo.o
+
+ifeq ($(CONFIG_FPE_NWFPE_XP),y)
+nwfpe-objs		+= extended_cpdo.o
+endif
 
 ifeq ($(CONFIG_CPU_26),y)
 nwfpe-objs		+= entry26.o
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/double_cpdo.c linux-2.4.22-pre3/arch/arm/nwfpe/double_cpdo.c
--- linux-2.4.22-pre2/arch/arm/nwfpe/double_cpdo.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/double_cpdo.c	2003-07-05 18:09:37.000000000 -0700
@@ -23,6 +23,11 @@
 #include "softfloat.h"
 #include "fpopcode.h"
 
+union float64_components {
+	float64 f64;
+	unsigned int i[2];
+};
+
 float64 float64_exp(float64 Fm);
 float64 float64_ln(float64 Fm);
 float64 float64_sin(float64 rFm);
@@ -32,257 +37,123 @@
 float64 float64_log(float64 rFm);
 float64 float64_tan(float64 rFm);
 float64 float64_arccos(float64 rFm);
-float64 float64_pow(float64 rFn,float64 rFm);
-float64 float64_pol(float64 rFn,float64 rFm);
+float64 float64_pow(float64 rFn, float64 rFm);
+float64 float64_pol(float64 rFn, float64 rFm);
 
-unsigned int DoubleCPDO(const unsigned int opcode)
+static float64 float64_rsf(float64 rFn, float64 rFm)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   float64 rFm, rFn;
-   unsigned int Fd, Fm, Fn, nRc = 1;
-
-   //printk("DoubleCPDO(0x%08x)\n",opcode);
-   
-   Fm = getFm(opcode);
-   if (CONSTANT_FM(opcode))
-   {
-     rFm = getDoubleConstant(Fm);
-   }
-   else
-   {  
-     switch (fpa11->fType[Fm])
-     {
-        case typeSingle:
-          rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle);
-        break;
-
-        case typeDouble:
-          rFm = fpa11->fpreg[Fm].fDouble;
-          break;
-
-        case typeExtended:
-            // !! patb
-	    //printk("not implemented! why not?\n");
-            //!! ScottB
-            // should never get here, if extended involved
-            // then other operand should be promoted then
-            // ExtendedCPDO called.
-            break;
-
-        default: return 0;
-     }
-   }
-
-   if (!MONADIC_INSTRUCTION(opcode))
-   {
-      Fn = getFn(opcode);
-      switch (fpa11->fType[Fn])
-      {
-        case typeSingle:
-          rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle);
-        break;
-
-        case typeDouble:
-          rFn = fpa11->fpreg[Fn].fDouble;
-        break;
-        
-        default: return 0;
-      }
-   }
-
-   Fd = getFd(opcode);
-   /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
-   switch (opcode & MASK_ARITHMETIC_OPCODE)
-   {
-      /* dyadic opcodes */
-      case ADF_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm);
-      break;
-
-      case MUF_CODE:
-      case FML_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm);
-      break;
-
-      case SUF_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm);
-      break;
-
-      case RSF_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn);
-      break;
-
-      case DVF_CODE:
-      case FDV_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm);
-      break;
-
-      case RDF_CODE:
-      case FRD_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn);
-      break;
-
-#if 0
-      case POW_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm);
-      break;
-
-      case RPW_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn);
-      break;
-#endif
-
-      case RMF_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm);
-      break;
-
-#if 0
-      case POL_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm);
-      break;
-#endif
-
-      /* monadic opcodes */
-      case MVF_CODE:
-         fpa11->fpreg[Fd].fDouble = rFm;
-      break;
-
-      case MNF_CODE:
-      {
-         unsigned int *p = (unsigned int*)&rFm;
-         p[1] ^= 0x80000000;
-         fpa11->fpreg[Fd].fDouble = rFm;
-      }
-      break;
-
-      case ABS_CODE:
-      {
-         unsigned int *p = (unsigned int*)&rFm;
-         p[1] &= 0x7fffffff;
-         fpa11->fpreg[Fd].fDouble = rFm;
-      }
-      break;
-
-      case RND_CODE:
-      case URD_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm);
-      break;
-
-      case SQT_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm);
-      break;
-
-#if 0
-      case LOG_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_log(rFm);
-      break;
-
-      case LGN_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
-      break;
-
-      case EXP_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
-      break;
-
-      case SIN_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
-      break;
-
-      case COS_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
-      break;
-
-      case TAN_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
-      break;
-
-      case ASN_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
-      break;
-
-      case ACS_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
-      break;
-
-      case ATN_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
-      break;
-#endif
-
-      case NRM_CODE:
-      break;
-      
-      default:
-      {
-        nRc = 0;
-      }
-   }
-
-   if (0 != nRc) fpa11->fType[Fd] = typeDouble;
-   return nRc;
+	return float64_sub(rFm, rFn);
 }
 
-#if 0
-float64 float64_exp(float64 rFm)
+static float64 float64_rdv(float64 rFn, float64 rFm)
 {
-  return rFm;
-//series
+	return float64_div(rFm, rFn);
 }
 
-float64 float64_ln(float64 rFm)
-{
-  return rFm;
-//series
-}
+static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = {
+	[ADF_CODE >> 20] = float64_add,
+	[MUF_CODE >> 20] = float64_mul,
+	[SUF_CODE >> 20] = float64_sub,
+	[RSF_CODE >> 20] = float64_rsf,
+	[DVF_CODE >> 20] = float64_div,
+	[RDF_CODE >> 20] = float64_rdv,
+	[RMF_CODE >> 20] = float64_rem,
 
-float64 float64_sin(float64 rFm)
-{
-  return rFm;
-//series
-}
+	/* strictly, these opcodes should not be implemented */
+	[FML_CODE >> 20] = float64_mul,
+	[FDV_CODE >> 20] = float64_div,
+	[FRD_CODE >> 20] = float64_rdv,
+};
 
-float64 float64_cos(float64 rFm)
+static float64 float64_mvf(float64 rFm)
 {
-   return rFm;
-   //series
+	return rFm;
 }
 
-#if 0
-float64 float64_arcsin(float64 rFm)
+static float64 float64_mnf(float64 rFm)
 {
-//series
-}
+	union float64_components u;
 
-float64 float64_arctan(float64 rFm)
-{
-  //series
-}
-#endif
+	u.f64 = rFm;
+	u.i[1] ^= 0x80000000;
 
-float64 float64_log(float64 rFm)
-{
-  return float64_div(float64_ln(rFm),getDoubleConstant(7));
+	return u.f64;
 }
 
-float64 float64_tan(float64 rFm)
+static float64 float64_abs(float64 rFm)
 {
-  return float64_div(float64_sin(rFm),float64_cos(rFm));
-}
+	union float64_components u;
 
-float64 float64_arccos(float64 rFm)
-{
-return rFm;
-   //return float64_sub(halfPi,float64_arcsin(rFm));
-}
+	u.f64 = rFm;
+	u.i[1] &= 0x7fffffff;
 
-float64 float64_pow(float64 rFn,float64 rFm)
-{
-  return float64_exp(float64_mul(rFm,float64_ln(rFn))); 
+	return u.f64;
 }
 
-float64 float64_pol(float64 rFn,float64 rFm)
+static float64 (*const monadic_double[16])(float64 rFm) = {
+	[MVF_CODE >> 20] = float64_mvf,
+	[MNF_CODE >> 20] = float64_mnf,
+	[ABS_CODE >> 20] = float64_abs,
+	[RND_CODE >> 20] = float64_round_to_int,
+	[URD_CODE >> 20] = float64_round_to_int,
+	[SQT_CODE >> 20] = float64_sqrt,
+	[NRM_CODE >> 20] = float64_mvf,
+};
+
+unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd)
 {
-  return float64_arctan(float64_div(rFn,rFm)); 
+	FPA11 *fpa11 = GET_FPA11();
+	float64 rFm;
+	unsigned int Fm, opc_mask_shift;
+
+	Fm = getFm(opcode);
+	if (CONSTANT_FM(opcode)) {
+		rFm = getDoubleConstant(Fm);
+	} else {
+		switch (fpa11->fType[Fm]) {
+		case typeSingle:
+			rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle);
+			break;
+
+		case typeDouble:
+			rFm = fpa11->fpreg[Fm].fDouble;
+			break;
+
+		default:
+			return 0;
+		}
+	}
+
+	opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
+	if (!MONADIC_INSTRUCTION(opcode)) {
+		unsigned int Fn = getFn(opcode);
+		float64 rFn;
+
+		switch (fpa11->fType[Fn]) {
+		case typeSingle:
+			rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle);
+			break;
+
+		case typeDouble:
+			rFn = fpa11->fpreg[Fn].fDouble;
+			break;
+
+		default:
+			return 0;
+		}
+
+		if (dyadic_double[opc_mask_shift]) {
+			rFd->fDouble = dyadic_double[opc_mask_shift](rFn, rFm);
+		} else {
+			return 0;
+		}
+	} else {
+		if (monadic_double[opc_mask_shift]) {
+			rFd->fDouble = monadic_double[opc_mask_shift](rFm);
+		} else {
+			return 0;
+		}
+	}
+
+	return 1;
 }
-#endif
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/entry.S linux-2.4.22-pre3/arch/arm/nwfpe/entry.S
--- linux-2.4.22-pre2/arch/arm/nwfpe/entry.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/entry.S	2003-07-05 18:09:37.000000000 -0700
@@ -70,39 +70,42 @@
 
 	.globl	nwfpe_enter
 nwfpe_enter:
-        mov r4, lr			@ save the failure-return addresses
-	mov sl, sp			@ we access the registers via 'sl'
-
-        ldr r5, [sp, #60]	 	@ get contents of PC;
-	sub r8, r5, #4
-.Lx2:	ldrt r0, [r8]			@ get actual instruction into r0
+	mov	r4, lr			@ save the failure-return addresses
+	ldr	ip, [r10, #112]		@ get init_flag
+	mov	sl, sp			@ we access the registers via 'sl'
+
+	ldr	r5, [sp, #60]		@ get contents of PC;
+	cmp	ip, #0
+	bleq	nwfpe_init_fpa
+	sub	r8, r5, #4
+.Lx1:	ldrt	r0, [r8]		@ get actual instruction into r0
 emulate:
-	bl EmulateAll			@ emulate the instruction
-   	cmp r0, #0			@ was emulation successful
-        moveq pc, r4			@ no, return failure
+	bl	EmulateAll		@ emulate the instruction
+	cmp	r0, #0			@ was emulation successful
+	moveq	pc, r4			@ no, return failure
 
 next:
-.Lx1:	ldrt r6, [r5], #4		@ get the next instruction and
+.Lx2:	ldrt	r6, [r5], #4		@ get the next instruction and
 					@ increment PC
 
-	and   r2, r6, #0x0F000000	@ test for FP insns
-        teq   r2, #0x0C000000
-        teqne r2, #0x0D000000
-        teqne r2, #0x0E000000
-        movne pc, r9			@ return ok if not a fp insn
-
-        str r5, [sp, #60]		@ update PC copy in regs
-
-        mov r0, r6			@ save a copy
-        ldr r1, [sp, #64]		@ fetch the condition codes
-   	bl  checkCondition		@ check the condition
-   	cmp r0, #0			@ r0 = 0 ==> condition failed
-
-        @ if condition code failed to match, next insn
-   	beq next			@ get the next instruction;
-   	    
-        mov r0, r6			@ prepare for EmulateAll()
-   	b emulate			@ if r0 != 0, goto EmulateAll
+	and	r2, r6, #0x0F000000	@ test for FP insns
+	teq	r2, #0x0C000000
+	teqne	r2, #0x0D000000
+	teqne	r2, #0x0E000000
+	movne	pc, r9			@ return ok if not a fp insn
+
+	str	r5, [sp, #60]		@ update PC copy in regs
+
+	mov	r0, r6			@ save a copy
+	ldr	r1, [sp, #64]		@ fetch the condition codes
+	bl	checkCondition		@ check the condition
+	cmp	r0, #0			@ r0 = 0 ==> condition failed
+
+	@ if condition code failed to match, next insn
+	beq	next			@ get the next instruction;
+
+	mov	r0, r6			@ prepare for EmulateAll()
+	b	emulate			@ if r0 != 0, goto EmulateAll
 
 	@ We need to be prepared for the instructions at .Lx1 and .Lx2 
 	@ to fault.  Emit the appropriate exception gunk to fix things up.
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/entry26.S linux-2.4.22-pre3/arch/arm/nwfpe/entry26.S
--- linux-2.4.22-pre2/arch/arm/nwfpe/entry26.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/entry26.S	2003-07-05 18:09:37.000000000 -0700
@@ -95,7 +95,7 @@
 
 	@ if condition code failed to match, next insn
 	beq	next			@ get the next instruction;
-	    
+
 	mov	r0, r6			@ prepare for EmulateAll()
 	adr	lr, 1b
 	orr	lr, lr, #3
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/extended_cpdo.c linux-2.4.22-pre3/arch/arm/nwfpe/extended_cpdo.c
--- linux-2.4.22-pre2/arch/arm/nwfpe/extended_cpdo.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/extended_cpdo.c	2003-07-05 18:09:37.000000000 -0700
@@ -32,242 +32,123 @@
 floatx80 floatx80_log(floatx80 rFm);
 floatx80 floatx80_tan(floatx80 rFm);
 floatx80 floatx80_arccos(floatx80 rFm);
-floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm);
-floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm);
+floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm);
+floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm);
 
-unsigned int ExtendedCPDO(const unsigned int opcode)
+static floatx80 floatx80_rsf(floatx80 rFn, floatx80 rFm)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   floatx80 rFm, rFn;
-   unsigned int Fd, Fm, Fn, nRc = 1;
-
-   //printk("ExtendedCPDO(0x%08x)\n",opcode);
-   
-   Fm = getFm(opcode);
-   if (CONSTANT_FM(opcode))
-   {
-     rFm = getExtendedConstant(Fm);
-   }
-   else
-   {  
-     switch (fpa11->fType[Fm])
-     {
-        case typeSingle:
-          rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
-        break;
-
-        case typeDouble:
-          rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
-        break;
-        
-        case typeExtended:
-          rFm = fpa11->fpreg[Fm].fExtended;
-        break;
-        
-        default: return 0;
-     }
-   }
-   
-   if (!MONADIC_INSTRUCTION(opcode))
-   {
-      Fn = getFn(opcode);
-      switch (fpa11->fType[Fn])
-      {
-        case typeSingle:
-          rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
-        break;
-
-        case typeDouble:
-          rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
-        break;
-        
-        case typeExtended:
-          rFn = fpa11->fpreg[Fn].fExtended;
-        break;
-        
-        default: return 0;
-      }
-   }
-
-   Fd = getFd(opcode);
-   switch (opcode & MASK_ARITHMETIC_OPCODE)
-   {
-      /* dyadic opcodes */
-      case ADF_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm);
-      break;
-
-      case MUF_CODE:
-      case FML_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm);
-      break;
-
-      case SUF_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm);
-      break;
-
-      case RSF_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn);
-      break;
-
-      case DVF_CODE:
-      case FDV_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm);
-      break;
-
-      case RDF_CODE:
-      case FRD_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn);
-      break;
-
-#if 0
-      case POW_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm);
-      break;
-
-      case RPW_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn);
-      break;
-#endif
-
-      case RMF_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm);
-      break;
-
-#if 0
-      case POL_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm);
-      break;
-#endif
-
-      /* monadic opcodes */
-      case MVF_CODE:
-         fpa11->fpreg[Fd].fExtended = rFm;
-      break;
-
-      case MNF_CODE:
-         rFm.high ^= 0x8000;
-         fpa11->fpreg[Fd].fExtended = rFm;
-      break;
-
-      case ABS_CODE:
-         rFm.high &= 0x7fff;
-         fpa11->fpreg[Fd].fExtended = rFm;
-      break;
-
-      case RND_CODE:
-      case URD_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_round_to_int(rFm);
-      break;
-
-      case SQT_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm);
-      break;
-
-#if 0
-      case LOG_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_log(rFm);
-      break;
-
-      case LGN_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm);
-      break;
-
-      case EXP_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm);
-      break;
-
-      case SIN_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm);
-      break;
-
-      case COS_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm);
-      break;
-
-      case TAN_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm);
-      break;
-
-      case ASN_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm);
-      break;
-
-      case ACS_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm);
-      break;
-
-      case ATN_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm);
-      break;
-#endif
-
-      case NRM_CODE:
-      break;
-      
-      default:
-      {
-        nRc = 0;
-      }
-   }
-   
-   if (0 != nRc) fpa11->fType[Fd] = typeExtended;
-   return nRc;
+	return floatx80_sub(rFm, rFn);
 }
 
-#if 0
-floatx80 floatx80_exp(floatx80 Fm)
+static floatx80 floatx80_rdv(floatx80 rFn, floatx80 rFm)
 {
-//series
+	return floatx80_div(rFm, rFn);
 }
 
-floatx80 floatx80_ln(floatx80 Fm)
-{
-//series
-}
+static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = {
+	[ADF_CODE >> 20] = floatx80_add,
+	[MUF_CODE >> 20] = floatx80_mul,
+	[SUF_CODE >> 20] = floatx80_sub,
+	[RSF_CODE >> 20] = floatx80_rsf,
+	[DVF_CODE >> 20] = floatx80_div,
+	[RDF_CODE >> 20] = floatx80_rdv,
+	[RMF_CODE >> 20] = floatx80_rem,
 
-floatx80 floatx80_sin(floatx80 rFm)
-{
-//series
-}
+	/* strictly, these opcodes should not be implemented */
+	[FML_CODE >> 20] = floatx80_mul,
+	[FDV_CODE >> 20] = floatx80_div,
+	[FRD_CODE >> 20] = floatx80_rdv,
+};
 
-floatx80 floatx80_cos(floatx80 rFm)
+static floatx80 floatx80_mvf(floatx80 rFm)
 {
-//series
+	return rFm;
 }
 
-floatx80 floatx80_arcsin(floatx80 rFm)
+static floatx80 floatx80_mnf(floatx80 rFm)
 {
-//series
+	rFm.high ^= 0x8000;
+	return rFm;
 }
 
-floatx80 floatx80_arctan(floatx80 rFm)
+static floatx80 floatx80_abs(floatx80 rFm)
 {
-  //series
+	rFm.high &= 0x7fff;
+	return rFm;
 }
 
-floatx80 floatx80_log(floatx80 rFm)
-{
-  return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7));
-}
+static floatx80 (*const monadic_extended[16])(floatx80 rFm) = {
+	[MVF_CODE >> 20] = floatx80_mvf,
+	[MNF_CODE >> 20] = floatx80_mnf,
+	[ABS_CODE >> 20] = floatx80_abs,
+	[RND_CODE >> 20] = floatx80_round_to_int,
+	[URD_CODE >> 20] = floatx80_round_to_int,
+	[SQT_CODE >> 20] = floatx80_sqrt,
+	[NRM_CODE >> 20] = floatx80_mvf,
+};
 
-floatx80 floatx80_tan(floatx80 rFm)
+unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd)
 {
-  return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm));
-}
+	FPA11 *fpa11 = GET_FPA11();
+	floatx80 rFm;
+	unsigned int Fm, opc_mask_shift;
 
-floatx80 floatx80_arccos(floatx80 rFm)
-{
-   //return floatx80_sub(halfPi,floatx80_arcsin(rFm));
-}
+	Fm = getFm(opcode);
+	if (CONSTANT_FM(opcode)) {
+		rFm = getExtendedConstant(Fm);
+	} else {
+		switch (fpa11->fType[Fm]) {
+		case typeSingle:
+			rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
+			break;
 
-floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm)
-{
-  return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn))); 
-}
+		case typeDouble:
+			rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
+			break;
 
-floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm)
-{
-  return floatx80_arctan(floatx80_div(rFn,rFm)); 
+		case typeExtended:
+			rFm = fpa11->fpreg[Fm].fExtended;
+			break;
+
+		default:
+			return 0;
+		}
+	}
+
+	opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
+	if (!MONADIC_INSTRUCTION(opcode)) {
+		unsigned int Fn = getFn(opcode);
+		floatx80 rFn;
+
+		switch (fpa11->fType[Fn]) {
+		case typeSingle:
+			rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+			break;
+
+		case typeDouble:
+			rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+			break;
+
+		case typeExtended:
+			rFn = fpa11->fpreg[Fn].fExtended;
+			break;
+
+		default:
+			return 0;
+		}
+
+		if (dyadic_extended[opc_mask_shift]) {
+			rFd->fExtended = dyadic_extended[opc_mask_shift](rFn, rFm);
+		} else {
+			return 0;
+		}
+	} else {
+		if (monadic_extended[opc_mask_shift]) {
+			rFd->fExtended = monadic_extended[opc_mask_shift](rFm);
+		} else {
+			return 0;
+		}
+	}
+
+	return 1;
 }
-#endif
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/fpa11.c linux-2.4.22-pre3/arch/arm/nwfpe/fpa11.c
--- linux-2.4.22-pre2/arch/arm/nwfpe/fpa11.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/fpa11.c	2003-07-05 18:09:37.000000000 -0700
@@ -1,6 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.COM, 1998,1999
+    (c) Philip Blundell, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -20,7 +21,6 @@
 */
 
 #include "fpa11.h"
-
 #include "fpopcode.h"
 
 #include "fpmodule.h"
@@ -36,180 +36,96 @@
 /* Reset the FPA11 chip.  Called to initialize and reset the emulator. */
 void resetFPA11(void)
 {
-  int i;
-  FPA11 *fpa11 = GET_FPA11();
-  
-  /* initialize the register type array */
-  for (i=0;i<=7;i++)
-  {
-    fpa11->fType[i] = typeNone;
-  }
-  
-  /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
-  fpa11->fpsr = FP_EMULATOR | BIT_AC;
-  
-  /* FPCR: set SB, AB and DA bits, clear all others */
-#if MAINTAIN_FPCR
-  fpa11->fpcr = MASK_RESET;
-#endif
+	int i;
+	FPA11 *fpa11 = GET_FPA11();
+
+	/* initialize the register type array */
+	for (i = 0; i <= 7; i++) {
+		fpa11->fType[i] = typeNone;
+	}
+
+	/* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
+	fpa11->fpsr = FP_EMULATOR | BIT_AC;
 }
 
 void SetRoundingMode(const unsigned int opcode)
 {
-#if MAINTAIN_FPCR
-   FPA11 *fpa11 = GET_FPA11();
-   fpa11->fpcr &= ~MASK_ROUNDING_MODE;
-#endif   
-   switch (opcode & MASK_ROUNDING_MODE)
-   {
-      default:
-      case ROUND_TO_NEAREST:
-         float_rounding_mode = float_round_nearest_even;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_TO_NEAREST;
-#endif         
-      break;
-      
-      case ROUND_TO_PLUS_INFINITY:
-         float_rounding_mode = float_round_up;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_TO_PLUS_INFINITY;
-#endif         
-      break;
-      
-      case ROUND_TO_MINUS_INFINITY:
-         float_rounding_mode = float_round_down;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_TO_MINUS_INFINITY;
-#endif         
-      break;
-      
-      case ROUND_TO_ZERO:
-         float_rounding_mode = float_round_to_zero;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_TO_ZERO;
-#endif         
-      break;
-  }
+	switch (opcode & MASK_ROUNDING_MODE) {
+	default:
+	case ROUND_TO_NEAREST:
+		float_rounding_mode = float_round_nearest_even;
+		break;
+
+	case ROUND_TO_PLUS_INFINITY:
+		float_rounding_mode = float_round_up;
+		break;
+
+	case ROUND_TO_MINUS_INFINITY:
+		float_rounding_mode = float_round_down;
+		break;
+
+	case ROUND_TO_ZERO:
+		float_rounding_mode = float_round_to_zero;
+		break;
+	}
 }
 
 void SetRoundingPrecision(const unsigned int opcode)
 {
-#if MAINTAIN_FPCR
-   FPA11 *fpa11 = GET_FPA11();
-   fpa11->fpcr &= ~MASK_ROUNDING_PRECISION;
-#endif   
-   switch (opcode & MASK_ROUNDING_PRECISION)
-   {
-      case ROUND_SINGLE:
-         floatx80_rounding_precision = 32;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_SINGLE;
-#endif         
-      break;
-      
-      case ROUND_DOUBLE:
-         floatx80_rounding_precision = 64;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_DOUBLE;
-#endif         
-      break;
-      
-      case ROUND_EXTENDED:
-         floatx80_rounding_precision = 80;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_EXTENDED;
-#endif         
-      break;
-      
-      default: floatx80_rounding_precision = 80;
-  }
+#ifdef CONFIG_FPE_NWFPE_XP
+	switch (opcode & MASK_ROUNDING_PRECISION) {
+	case ROUND_SINGLE:
+		floatx80_rounding_precision = 32;
+		break;
+
+	case ROUND_DOUBLE:
+		floatx80_rounding_precision = 64;
+		break;
+
+	case ROUND_EXTENDED:
+		floatx80_rounding_precision = 80;
+		break;
+
+	default:
+		floatx80_rounding_precision = 80;
+	}
+#endif
 }
 
-/* Emulate the instruction in the opcode. */
-unsigned int EmulateAll(unsigned int opcode)
+void nwfpe_init_fpa(void)
 {
-  unsigned int nRc = 0;
-  unsigned long flags;
-  FPA11 *fpa11; 
-  save_flags(flags); sti();
-
-  fpa11 = GET_FPA11();
-
-  if (fpa11->initflag == 0)		/* good place for __builtin_expect */
-  {
-    resetFPA11();
-    SetRoundingMode(ROUND_TO_NEAREST);
-    SetRoundingPrecision(ROUND_EXTENDED);
-    fpa11->initflag = 1;
-  }
-
-  if (TEST_OPCODE(opcode,MASK_CPRT))
-  {
-    /* Emulate conversion opcodes. */
-    /* Emulate register transfer opcodes. */
-    /* Emulate comparison opcodes. */
-    nRc = EmulateCPRT(opcode);
-  }
-  else if (TEST_OPCODE(opcode,MASK_CPDO))
-  {
-    /* Emulate monadic arithmetic opcodes. */
-    /* Emulate dyadic arithmetic opcodes. */
-    nRc = EmulateCPDO(opcode);
-  }
-  else if (TEST_OPCODE(opcode,MASK_CPDT))
-  {
-    /* Emulate load/store opcodes. */
-    /* Emulate load/store multiple opcodes. */
-    nRc = EmulateCPDT(opcode);
-  }
-  else
-  {
-    /* Invalid instruction detected.  Return FALSE. */
-    nRc = 0;
-  }
-
-  restore_flags(flags);
-
-  return(nRc);
+	FPA11 *fpa11 = GET_FPA11();
+#ifdef NWFPE_DEBUG
+	printk("NWFPE: setting up state.\n");
+#endif
+	resetFPA11();
+	SetRoundingMode(ROUND_TO_NEAREST);
+	SetRoundingPrecision(ROUND_EXTENDED);
+	fpa11->initflag = 1;
 }
 
-#if 0
-unsigned int EmulateAll1(unsigned int opcode)
+/* Emulate the instruction in the opcode. */
+unsigned int EmulateAll(const unsigned int opcode)
 {
-  switch ((opcode >> 24) & 0xf)
-  {
-     case 0xc:
-     case 0xd:
-       if ((opcode >> 20) & 0x1)
-       {
-          switch ((opcode >> 8) & 0xf)
-          {
-             case 0x1: return PerformLDF(opcode); break;
-             case 0x2: return PerformLFM(opcode); break;
-             default: return 0;
-          }
-       }
-       else
-       {
-          switch ((opcode >> 8) & 0xf)
-          {
-             case 0x1: return PerformSTF(opcode); break;
-             case 0x2: return PerformSFM(opcode); break;
-             default: return 0;
-          }
-      }
-     break;
-     
-     case 0xe: 
-       if (opcode & 0x10)
-         return EmulateCPDO(opcode);
-       else
-         return EmulateCPRT(opcode);
-     break;
-  
-     default: return 0;
-  }
-}
+#ifdef NWFPE_DEBUG
+	printk("NWFPE: emulating opcode %08x\n", opcode);
 #endif
 
+	if (TEST_OPCODE(opcode, MASK_CPRT)) {
+		/* Emulate conversion opcodes. */
+		/* Emulate register transfer opcodes. */
+		/* Emulate comparison opcodes. */
+		return EmulateCPRT(opcode);
+	} else if (TEST_OPCODE(opcode, MASK_CPDO)) {
+		/* Emulate monadic arithmetic opcodes. */
+		/* Emulate dyadic arithmetic opcodes. */
+		return EmulateCPDO(opcode);
+	} else if (TEST_OPCODE(opcode, MASK_CPDT)) {
+		/* Emulate load/store opcodes. */
+		/* Emulate load/store multiple opcodes. */
+		return EmulateCPDT(opcode);
+	}
+
+	/* Invalid instruction detected.  Return FALSE. */
+	return 0;
+}
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/fpa11.h linux-2.4.22-pre3/arch/arm/nwfpe/fpa11.h
--- linux-2.4.22-pre2/arch/arm/nwfpe/fpa11.h	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/fpa11.h	2003-07-05 18:09:37.000000000 -0700
@@ -38,6 +38,7 @@
 
 /* includes */
 #include "fpsr.h"		/* FP control and status register definitions */
+#include "milieu.h"
 #include "softfloat.h"
 
 #define		typeNone		0x00
@@ -49,9 +50,13 @@
  * This must be no more and no less than 12 bytes.
  */
 typedef union tagFPREG {
-   floatx80 fExtended;
-   float64  fDouble;
-   float32  fSingle;
+	float32 fSingle;
+	float64 fDouble;
+#ifdef CONFIG_FPE_NWFPE_XP
+	floatx80 fExtended;
+#else
+	int padding[3];
+#endif
 } FPREG;
 
 /*
@@ -68,17 +73,17 @@
  * not initialise.
  */
 typedef struct tagFPA11 {
-/*   0 */  FPREG fpreg[8];		/* 8 floating point registers */
-/*  96 */  FPSR fpsr;			/* floating point status register */
-/* 100 */  FPCR fpcr;			/* floating point control register */
-/* 104 */  unsigned char fType[8];	/* type of floating point value held in
-					   floating point registers.  One of none
-					   single, double or extended. */
-/* 112 */  int initflag;		/* this is special.  The kernel guarantees
-					   to set it to 0 when a thread is launched,
-					   so we can use it to detect whether this
-					   instance of the emulator needs to be
-					   initialised. */
+/*   0 */ FPREG fpreg[8];	/* 8 floating point registers */
+/*  96 */ FPSR fpsr;		/* floating point status register */
+/* 100 */ FPCR fpcr;		/* floating point control register */
+/* 104 */ unsigned char fType[8];	/* type of floating point value held in
+					   floating point registers.  One of
+					   none, single, double or extended. */
+/* 112 */ int initflag;		/* this is special.  The kernel guarantees
+				   to set it to 0 when a thread is launched,
+				   so we can use it to detect whether this
+				   instance of the emulator needs to be
+				   initialised. */
 } FPA11;
 
 extern void resetFPA11(void);
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/fpa11.inl linux-2.4.22-pre3/arch/arm/nwfpe/fpa11.inl
--- linux-2.4.22-pre2/arch/arm/nwfpe/fpa11.inl	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/fpa11.inl	2003-07-05 18:09:37.000000000 -0700
@@ -24,28 +24,28 @@
 /* Read and write floating point status register */
 extern __inline__ unsigned int readFPSR(void)
 {
-  FPA11 *fpa11 = GET_FPA11();
-  return(fpa11->fpsr);
+	FPA11 *fpa11 = GET_FPA11();
+	return (fpa11->fpsr);
 }
 
 extern __inline__ void writeFPSR(FPSR reg)
 {
-  FPA11 *fpa11 = GET_FPA11();
-  /* the sysid byte in the status register is readonly */
-  fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID);
+	FPA11 *fpa11 = GET_FPA11();
+	/* the sysid byte in the status register is readonly */
+	fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID);
 }
 
 /* Read and write floating point control register */
 extern __inline__ FPCR readFPCR(void)
 {
-  FPA11 *fpa11 = GET_FPA11();
-  /* clear SB, AB and DA bits before returning FPCR */
-  return(fpa11->fpcr & ~MASK_RFC);
+	FPA11 *fpa11 = GET_FPA11();
+	/* clear SB, AB and DA bits before returning FPCR */
+	return (fpa11->fpcr & ~MASK_RFC);
 }
 
 extern __inline__ void writeFPCR(FPCR reg)
 {
-  FPA11 *fpa11 = GET_FPA11();
-  fpa11->fpcr &= ~MASK_WFC;		/* clear SB, AB and DA bits */
-  fpa11->fpcr |= (reg & MASK_WFC);	/* write SB, AB and DA bits */
+	FPA11 *fpa11 = GET_FPA11();
+	fpa11->fpcr &= ~MASK_WFC;		/* clear SB, AB and DA bits */
+	fpa11->fpcr |= (reg & MASK_WFC);	/* write SB, AB and DA bits */
 }
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/fpa11_cpdo.c linux-2.4.22-pre3/arch/arm/nwfpe/fpa11_cpdo.c
--- linux-2.4.22-pre2/arch/arm/nwfpe/fpa11_cpdo.c	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/fpa11_cpdo.c	2003-07-05 18:09:37.000000000 -0700
@@ -1,6 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.COM, 1998,1999
+    (c) Philip Blundell, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -22,96 +23,109 @@
 #include "fpa11.h"
 #include "fpopcode.h"
 
-unsigned int SingleCPDO(const unsigned int opcode);
-unsigned int DoubleCPDO(const unsigned int opcode);
-unsigned int ExtendedCPDO(const unsigned int opcode);
+unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd);
+unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd);
+unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd);
 
 unsigned int EmulateCPDO(const unsigned int opcode)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   unsigned int Fd, nType, nDest, nRc = 1;
-   
-   //printk("EmulateCPDO(0x%08x)\n",opcode);
-
-   /* Get the destination size.  If not valid let Linux perform
-      an invalid instruction trap. */
-   nDest = getDestinationSize(opcode);
-   if (typeNone == nDest) return 0;
-   
-   SetRoundingMode(opcode);
-     
-   /* Compare the size of the operands in Fn and Fm.
-      Choose the largest size and perform operations in that size,
-      in order to make use of all the precision of the operands. 
-      If Fm is a constant, we just grab a constant of a size 
-      matching the size of the operand in Fn. */
-   if (MONADIC_INSTRUCTION(opcode))
-     nType = nDest;
-   else
-     nType = fpa11->fType[getFn(opcode)];
-   
-   if (!CONSTANT_FM(opcode))
-   {
-     register unsigned int Fm = getFm(opcode);
-     if (nType < fpa11->fType[Fm])
-     {
-        nType = fpa11->fType[Fm];
-     }
-   }
-
-   switch (nType)
-   {
-      case typeSingle   : nRc = SingleCPDO(opcode);   break;
-      case typeDouble   : nRc = DoubleCPDO(opcode);   break;
-      case typeExtended : nRc = ExtendedCPDO(opcode); break;
-      default           : nRc = 0;
-   }
-
-   /* If the operation succeeded, check to see if the result in the
-      destination register is the correct size.  If not force it
-      to be. */
-   Fd = getFd(opcode);
-   nType = fpa11->fType[Fd];
-   if ((0 != nRc) && (nDest != nType))
-   {
-     switch (nDest)
-     {
-       case typeSingle:
-       {
-         if (typeDouble == nType)
-           fpa11->fpreg[Fd].fSingle = 
-              float64_to_float32(fpa11->fpreg[Fd].fDouble);
-         else
-           fpa11->fpreg[Fd].fSingle = 
-              floatx80_to_float32(fpa11->fpreg[Fd].fExtended);
-       }
-       break;
-          
-       case typeDouble:
-       {
-         if (typeSingle == nType)
-           fpa11->fpreg[Fd].fDouble = 
-              float32_to_float64(fpa11->fpreg[Fd].fSingle);
-         else
-           fpa11->fpreg[Fd].fDouble = 
-              floatx80_to_float64(fpa11->fpreg[Fd].fExtended);
-       }
-       break;
-          
-       case typeExtended:
-       {
-         if (typeSingle == nType)
-           fpa11->fpreg[Fd].fExtended = 
-              float32_to_floatx80(fpa11->fpreg[Fd].fSingle);
-         else
-           fpa11->fpreg[Fd].fExtended = 
-              float64_to_floatx80(fpa11->fpreg[Fd].fDouble);
-       }
-       break;
-     }
-     
-     fpa11->fType[Fd] = nDest;
-   }
-   
-   return nRc;
+	FPA11 *fpa11 = GET_FPA11();
+	FPREG *rFd;
+	unsigned int nType, nDest, nRc;
+
+	/* Get the destination size.  If not valid let Linux perform
+	   an invalid instruction trap. */
+	nDest = getDestinationSize(opcode);
+	if (typeNone == nDest)
+		return 0;
+
+	SetRoundingMode(opcode);
+
+	/* Compare the size of the operands in Fn and Fm.
+	   Choose the largest size and perform operations in that size,
+	   in order to make use of all the precision of the operands.
+	   If Fm is a constant, we just grab a constant of a size
+	   matching the size of the operand in Fn. */
+	if (MONADIC_INSTRUCTION(opcode))
+		nType = nDest;
+	else
+		nType = fpa11->fType[getFn(opcode)];
+
+	if (!CONSTANT_FM(opcode)) {
+		register unsigned int Fm = getFm(opcode);
+		if (nType < fpa11->fType[Fm]) {
+			nType = fpa11->fType[Fm];
+		}
+	}
+
+	rFd = &fpa11->fpreg[getFd(opcode)];
+
+	switch (nType) {
+	case typeSingle:
+		nRc = SingleCPDO(opcode, rFd);
+		break;
+	case typeDouble:
+		nRc = DoubleCPDO(opcode, rFd);
+		break;
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		nRc = ExtendedCPDO(opcode, rFd);
+		break;
+#endif
+	default:
+		nRc = 0;
+	}
+
+	/* The CPDO functions used to always set the destination type
+	   to be the same as their working size. */
+
+	if (nRc != 0) {
+		/* If the operation succeeded, check to see if the result in the
+		   destination register is the correct size.  If not force it
+		   to be. */
+
+		fpa11->fType[getFd(opcode)] = nDest;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+		if (nDest != nType) {
+			switch (nDest) {
+			case typeSingle:
+				{
+					if (typeDouble == nType)
+						rFd->fSingle = float64_to_float32(rFd->fDouble);
+					else
+						rFd->fSingle = floatx80_to_float32(rFd->fExtended);
+				}
+				break;
+
+			case typeDouble:
+				{
+					if (typeSingle == nType)
+						rFd->fDouble = float32_to_float64(rFd->fSingle);
+					else
+						rFd->fDouble = floatx80_to_float64(rFd->fExtended);
+				}
+				break;
+
+			case typeExtended:
+				{
+					if (typeSingle == nType)
+						rFd->fExtended = float32_to_floatx80(rFd->fSingle);
+					else
+						rFd->fExtended = float64_to_floatx80(rFd->fDouble);
+				}
+				break;
+			}
+		}
+#else
+		if (nDest != nType) {
+			if (nDest == typeSingle)
+				rFd->fSingle = float64_to_float32(rFd->fDouble);
+			else
+				rFd->fDouble = float32_to_float64(rFd->fSingle);
+		}
+#endif
+	}
+
+	return nRc;
 }
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/fpa11_cpdt.c linux-2.4.22-pre3/arch/arm/nwfpe/fpa11_cpdt.c
--- linux-2.4.22-pre2/arch/arm/nwfpe/fpa11_cpdt.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/fpa11_cpdt.c	2003-07-05 18:09:37.000000000 -0700
@@ -1,7 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.com, 1998-1999
-    (c) Philip Blundell, 1998
+    (c) Philip Blundell, 1998, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -28,331 +28,347 @@
 
 #include <asm/uaccess.h>
 
-static inline
-void loadSingle(const unsigned int Fn,const unsigned int *pMem)
+static inline void loadSingle(const unsigned int Fn, const unsigned int *pMem)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   fpa11->fType[Fn] = typeSingle;
-   get_user(fpa11->fpreg[Fn].fSingle, pMem);
-}
-
-static inline
-void loadDouble(const unsigned int Fn,const unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   unsigned int *p;
-   p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
-   fpa11->fType[Fn] = typeDouble;
-   get_user(p[0], &pMem[1]);
-   get_user(p[1], &pMem[0]); /* sign & exponent */
-}   
-
-static inline
-void loadExtended(const unsigned int Fn,const unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   unsigned int *p;
-   p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
-   fpa11->fType[Fn] = typeExtended;
-   get_user(p[0], &pMem[0]);  /* sign & exponent */
-   get_user(p[1], &pMem[2]);  /* ls bits */
-   get_user(p[2], &pMem[1]);  /* ms bits */
-}   
-
-static inline
-void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   register unsigned int *p;
-   unsigned long x;
-
-   p = (unsigned int*)&(fpa11->fpreg[Fn]);
-   get_user(x, &pMem[0]);
-   fpa11->fType[Fn] = (x >> 14) & 0x00000003;
-   
-   switch (fpa11->fType[Fn])
-   {
-      case typeSingle:
-      case typeDouble:
-      {
-         get_user(p[0], &pMem[2]);  /* Single */
-         get_user(p[1], &pMem[1]);  /* double msw */
-         p[2] = 0;        /* empty */
-      }
-      break; 
-   
-      case typeExtended:
-      {
-         get_user(p[1], &pMem[2]);
-         get_user(p[2], &pMem[1]);  /* msw */
-         p[0] = (x & 0x80003fff);      
-      }
-      break;
-   }
-}
-
-static inline
-void storeSingle(const unsigned int Fn,unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   float32 val;
-   register unsigned int *p = (unsigned int*)&val;
-   
-   switch (fpa11->fType[Fn])
-   {
-      case typeDouble: 
-         val = float64_to_float32(fpa11->fpreg[Fn].fDouble);
-      break;
-
-      case typeExtended: 
-         val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
-      break;
-
-      default: val = fpa11->fpreg[Fn].fSingle;
-   }
-  
-   put_user(p[0], pMem);
-}   
-
-static inline
-void storeDouble(const unsigned int Fn,unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   float64 val;
-   register unsigned int *p = (unsigned int*)&val;
-
-   switch (fpa11->fType[Fn])
-   {
-      case typeSingle: 
-         val = float32_to_float64(fpa11->fpreg[Fn].fSingle);
-      break;
-
-      case typeExtended:
-         val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
-      break;
-
-      default: val = fpa11->fpreg[Fn].fDouble;
-   }
-   put_user(p[1], &pMem[0]);	/* msw */
-   put_user(p[0], &pMem[1]);	/* lsw */
-}   
-
-static inline
-void storeExtended(const unsigned int Fn,unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   floatx80 val;
-   register unsigned int *p = (unsigned int*)&val;
-   
-   switch (fpa11->fType[Fn])
-   {
-      case typeSingle: 
-         val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
-      break;
-
-      case typeDouble: 
-         val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
-      break;
-
-      default: val = fpa11->fpreg[Fn].fExtended;
-   }
-   
-   put_user(p[0], &pMem[0]); /* sign & exp */
-   put_user(p[1], &pMem[2]);
-   put_user(p[2], &pMem[1]); /* msw */
-}   
-
-static inline
-void storeMultiple(const unsigned int Fn,unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   register unsigned int nType, *p;
-   
-   p = (unsigned int*)&(fpa11->fpreg[Fn]);
-   nType = fpa11->fType[Fn];
-   
-   switch (nType)
-   {
-      case typeSingle:
-      case typeDouble:
-      {
-	 put_user(p[0], &pMem[2]); /* single */
-	 put_user(p[1], &pMem[1]); /* double msw */
-	 put_user(nType << 14, &pMem[0]);
-      }
-      break; 
-   
-      case typeExtended:
-      {
-	 put_user(p[2], &pMem[1]); /* msw */
-	 put_user(p[1], &pMem[2]);
-	 put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]);
-      }
-      break;
-   }
+	FPA11 *fpa11 = GET_FPA11();
+	fpa11->fType[Fn] = typeSingle;
+	get_user(fpa11->fpreg[Fn].fSingle, pMem);
 }
 
-unsigned int PerformLDF(const unsigned int opcode)
+static inline void loadDouble(const unsigned int Fn, const unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	unsigned int *p;
+	p = (unsigned int *) &fpa11->fpreg[Fn].fDouble;
+	fpa11->fType[Fn] = typeDouble;
+	get_user(p[0], &pMem[1]);
+	get_user(p[1], &pMem[0]);	/* sign & exponent */
+}
+
+#ifdef CONFIG_FPE_NWFPE_XP
+static inline void loadExtended(const unsigned int Fn, const unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	unsigned int *p;
+	p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
+	fpa11->fType[Fn] = typeExtended;
+	get_user(p[0], &pMem[0]);	/* sign & exponent */
+	get_user(p[1], &pMem[2]);	/* ls bits */
+	get_user(p[2], &pMem[1]);	/* ms bits */
+}
+#endif
+
+static inline void loadMultiple(const unsigned int Fn, const unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	register unsigned int *p;
+	unsigned long x;
+
+	p = (unsigned int *) &(fpa11->fpreg[Fn]);
+	get_user(x, &pMem[0]);
+	fpa11->fType[Fn] = (x >> 14) & 0x00000003;
+
+	switch (fpa11->fType[Fn]) {
+	case typeSingle:
+	case typeDouble:
+		{
+			get_user(p[0], &pMem[2]);	/* Single */
+			get_user(p[1], &pMem[1]);	/* double msw */
+			p[2] = 0;			/* empty */
+		}
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		{
+			get_user(p[1], &pMem[2]);
+			get_user(p[2], &pMem[1]);	/* msw */
+			p[0] = (x & 0x80003fff);
+		}
+		break;
+#endif
+	}
+}
+
+static inline void storeSingle(const unsigned int Fn, unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	float32 val;
+	register unsigned int *p = (unsigned int *) &val;
+
+	switch (fpa11->fType[Fn]) {
+	case typeDouble:
+		val = float64_to_float32(fpa11->fpreg[Fn].fDouble);
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
+		break;
+#endif
+
+	default:
+		val = fpa11->fpreg[Fn].fSingle;
+	}
+
+	put_user(p[0], pMem);
+}
+
+static inline void storeDouble(const unsigned int Fn, unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	float64 val;
+	register unsigned int *p = (unsigned int *) &val;
+
+	switch (fpa11->fType[Fn]) {
+	case typeSingle:
+		val = float32_to_float64(fpa11->fpreg[Fn].fSingle);
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
+		break;
+#endif
+
+	default:
+		val = fpa11->fpreg[Fn].fDouble;
+	}
+	put_user(p[1], &pMem[0]);	/* msw */
+	put_user(p[0], &pMem[1]);	/* lsw */
+}
+
+#ifdef CONFIG_FPE_NWFPE_XP
+static inline void storeExtended(const unsigned int Fn, unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	floatx80 val;
+	register unsigned int *p = (unsigned int *) &val;
+
+	switch (fpa11->fType[Fn]) {
+	case typeSingle:
+		val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+		break;
+
+	case typeDouble:
+		val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+		break;
+
+	default:
+		val = fpa11->fpreg[Fn].fExtended;
+	}
+
+	put_user(p[0], &pMem[0]);	/* sign & exp */
+	put_user(p[1], &pMem[2]);
+	put_user(p[2], &pMem[1]);	/* msw */
+}
+#endif
+
+static inline void storeMultiple(const unsigned int Fn, unsigned int *pMem)
 {
-   unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
-     write_back = WRITE_BACK(opcode);
+	FPA11 *fpa11 = GET_FPA11();
+	register unsigned int nType, *p;
+
+	p = (unsigned int *) &(fpa11->fpreg[Fn]);
+	nType = fpa11->fType[Fn];
+
+	switch (nType) {
+	case typeSingle:
+	case typeDouble:
+		{
+			put_user(p[0], &pMem[2]);	/* single */
+			put_user(p[1], &pMem[1]);	/* double msw */
+			put_user(nType << 14, &pMem[0]);
+		}
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		{
+			put_user(p[2], &pMem[1]);	/* msw */
+			put_user(p[1], &pMem[2]);
+			put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]);
+		}
+		break;
+#endif
+	}
+}
 
-   //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
+unsigned int PerformLDF(const unsigned int opcode)
+{
+	unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
+	    write_back = WRITE_BACK(opcode);
 
-   pBase = (unsigned int*)readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
-   {
-     pBase += 2;
-     write_back = 0;
-   }
-
-   pFinal = pBase;
-   if (BIT_UP_SET(opcode))
-     pFinal += getOffset(opcode);
-   else
-     pFinal -= getOffset(opcode);
-
-   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
-   switch (opcode & MASK_TRANSFER_LENGTH)
-   {
-      case TRANSFER_SINGLE  : loadSingle(getFd(opcode),pAddress);   break;
-      case TRANSFER_DOUBLE  : loadDouble(getFd(opcode),pAddress);   break;
-      case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break;
-      default: nRc = 0;
-   }
-   
-   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
-   return nRc;
+	pBase = (unsigned int *) readRegister(getRn(opcode));
+	if (REG_PC == getRn(opcode)) {
+		pBase += 2;
+		write_back = 0;
+	}
+
+	pFinal = pBase;
+	if (BIT_UP_SET(opcode))
+		pFinal += getOffset(opcode);
+	else
+		pFinal -= getOffset(opcode);
+
+	if (PREINDEXED(opcode))
+		pAddress = pFinal;
+	else
+		pAddress = pBase;
+
+	switch (opcode & MASK_TRANSFER_LENGTH) {
+	case TRANSFER_SINGLE:
+		loadSingle(getFd(opcode), pAddress);
+		break;
+	case TRANSFER_DOUBLE:
+		loadDouble(getFd(opcode), pAddress);
+		break;
+#ifdef CONFIG_FPE_NWFPE_XP
+	case TRANSFER_EXTENDED:
+		loadExtended(getFd(opcode), pAddress);
+		break;
+#endif
+	default:
+		nRc = 0;
+	}
+
+	if (write_back)
+		writeRegister(getRn(opcode), (unsigned int) pFinal);
+	return nRc;
 }
 
 unsigned int PerformSTF(const unsigned int opcode)
 {
-   unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
-     write_back = WRITE_BACK(opcode);
-   
-   //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
-   SetRoundingMode(ROUND_TO_NEAREST);
-   
-   pBase = (unsigned int*)readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
-   {
-     pBase += 2;
-     write_back = 0;
-   }
-
-   pFinal = pBase;
-   if (BIT_UP_SET(opcode))
-     pFinal += getOffset(opcode);
-   else
-     pFinal -= getOffset(opcode);
-
-   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
-   switch (opcode & MASK_TRANSFER_LENGTH)
-   {
-      case TRANSFER_SINGLE  : storeSingle(getFd(opcode),pAddress);   break;
-      case TRANSFER_DOUBLE  : storeDouble(getFd(opcode),pAddress);   break;
-      case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break;
-      default: nRc = 0;
-   }
-   
-   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
-   return nRc;
+	unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
+	    write_back = WRITE_BACK(opcode);
+
+	SetRoundingMode(ROUND_TO_NEAREST);
+
+	pBase = (unsigned int *) readRegister(getRn(opcode));
+	if (REG_PC == getRn(opcode)) {
+		pBase += 2;
+		write_back = 0;
+	}
+
+	pFinal = pBase;
+	if (BIT_UP_SET(opcode))
+		pFinal += getOffset(opcode);
+	else
+		pFinal -= getOffset(opcode);
+
+	if (PREINDEXED(opcode))
+		pAddress = pFinal;
+	else
+		pAddress = pBase;
+
+	switch (opcode & MASK_TRANSFER_LENGTH) {
+	case TRANSFER_SINGLE:
+		storeSingle(getFd(opcode), pAddress);
+		break;
+	case TRANSFER_DOUBLE:
+		storeDouble(getFd(opcode), pAddress);
+		break;
+#ifdef CONFIG_FPE_NWFPE_XP
+	case TRANSFER_EXTENDED:
+		storeExtended(getFd(opcode), pAddress);
+		break;
+#endif
+	default:
+		nRc = 0;
+	}
+
+	if (write_back)
+		writeRegister(getRn(opcode), (unsigned int) pFinal);
+	return nRc;
 }
 
 unsigned int PerformLFM(const unsigned int opcode)
 {
-   unsigned int i, Fd, *pBase, *pAddress, *pFinal,
-     write_back = WRITE_BACK(opcode);
-
-   pBase = (unsigned int*)readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
-   {
-     pBase += 2;
-     write_back = 0;
-   }
-
-   pFinal = pBase;
-   if (BIT_UP_SET(opcode))
-     pFinal += getOffset(opcode);
-   else
-     pFinal -= getOffset(opcode);
-
-   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
-   Fd = getFd(opcode);
-   for (i=getRegisterCount(opcode);i>0;i--)
-   {
-     loadMultiple(Fd,pAddress);
-     pAddress += 3; Fd++;
-     if (Fd == 8) Fd = 0;
-   }
+	unsigned int i, Fd, *pBase, *pAddress, *pFinal,
+	    write_back = WRITE_BACK(opcode);
 
-   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
-   return 1;
+	pBase = (unsigned int *) readRegister(getRn(opcode));
+	if (REG_PC == getRn(opcode)) {
+		pBase += 2;
+		write_back = 0;
+	}
+
+	pFinal = pBase;
+	if (BIT_UP_SET(opcode))
+		pFinal += getOffset(opcode);
+	else
+		pFinal -= getOffset(opcode);
+
+	if (PREINDEXED(opcode))
+		pAddress = pFinal;
+	else
+		pAddress = pBase;
+
+	Fd = getFd(opcode);
+	for (i = getRegisterCount(opcode); i > 0; i--) {
+		loadMultiple(Fd, pAddress);
+		pAddress += 3;
+		Fd++;
+		if (Fd == 8)
+			Fd = 0;
+	}
+
+	if (write_back)
+		writeRegister(getRn(opcode), (unsigned int) pFinal);
+	return 1;
 }
 
 unsigned int PerformSFM(const unsigned int opcode)
 {
-   unsigned int i, Fd, *pBase, *pAddress, *pFinal,
-     write_back = WRITE_BACK(opcode);
-   
-   pBase = (unsigned int*)readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
-   {
-     pBase += 2;
-     write_back = 0;
-   }
-   
-   pFinal = pBase;
-   if (BIT_UP_SET(opcode))
-     pFinal += getOffset(opcode);
-   else
-     pFinal -= getOffset(opcode);
-
-   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
-   Fd = getFd(opcode);
-   for (i=getRegisterCount(opcode);i>0;i--)
-   {
-     storeMultiple(Fd,pAddress);
-     pAddress += 3; Fd++;
-     if (Fd == 8) Fd = 0;
-   }
+	unsigned int i, Fd, *pBase, *pAddress, *pFinal,
+	    write_back = WRITE_BACK(opcode);
 
-   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
-   return 1;
+	pBase = (unsigned int *) readRegister(getRn(opcode));
+	if (REG_PC == getRn(opcode)) {
+		pBase += 2;
+		write_back = 0;
+	}
+
+	pFinal = pBase;
+	if (BIT_UP_SET(opcode))
+		pFinal += getOffset(opcode);
+	else
+		pFinal -= getOffset(opcode);
+
+	if (PREINDEXED(opcode))
+		pAddress = pFinal;
+	else
+		pAddress = pBase;
+
+	Fd = getFd(opcode);
+	for (i = getRegisterCount(opcode); i > 0; i--) {
+		storeMultiple(Fd, pAddress);
+		pAddress += 3;
+		Fd++;
+		if (Fd == 8)
+			Fd = 0;
+	}
+
+	if (write_back)
+		writeRegister(getRn(opcode), (unsigned int) pFinal);
+	return 1;
 }
 
-#if 1
 unsigned int EmulateCPDT(const unsigned int opcode)
 {
-  unsigned int nRc = 0;
+	unsigned int nRc = 0;
 
-  //printk("EmulateCPDT(0x%08x)\n",opcode);
-  
-  if (LDF_OP(opcode))
-  {
-    nRc = PerformLDF(opcode);
-  }
-  else if (LFM_OP(opcode))
-  {
-    nRc = PerformLFM(opcode);
-  }
-  else if (STF_OP(opcode))
-  {
-    nRc = PerformSTF(opcode);
-  } 
-  else if (SFM_OP(opcode))
-  {
-    nRc = PerformSFM(opcode);
-  }
-  else
-  {
-    nRc = 0;
-  }
-  
-  return nRc;
+	if (LDF_OP(opcode)) {
+		nRc = PerformLDF(opcode);
+	} else if (LFM_OP(opcode)) {
+		nRc = PerformLFM(opcode);
+	} else if (STF_OP(opcode)) {
+		nRc = PerformSTF(opcode);
+	} else if (SFM_OP(opcode)) {
+		nRc = PerformSFM(opcode);
+	} else {
+		nRc = 0;
+	}
+
+	return nRc;
 }
-#endif
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/fpa11_cprt.c linux-2.4.22-pre3/arch/arm/nwfpe/fpa11_cprt.c
--- linux-2.4.22-pre2/arch/arm/nwfpe/fpa11_cprt.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/fpa11_cprt.c	2003-07-05 18:09:37.000000000 -0700
@@ -1,7 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.COM, 1998,1999
-    (c) Philip Blundell, 1999
+    (c) Philip Blundell, 1999, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -21,269 +21,348 @@
 */
 
 #include "fpa11.h"
-#include "milieu.h"
-#include "softfloat.h"
 #include "fpopcode.h"
 #include "fpa11.inl"
 #include "fpmodule.h"
 #include "fpmodule.inl"
 
+#ifdef CONFIG_FPE_NWFPE_XP
 extern flag floatx80_is_nan(floatx80);
-extern flag float64_is_nan( float64);
-extern flag float32_is_nan( float32);
+#endif
+extern flag float64_is_nan(float64);
+extern flag float32_is_nan(float32);
 
 void SetRoundingMode(const unsigned int opcode);
 
 unsigned int PerformFLT(const unsigned int opcode);
 unsigned int PerformFIX(const unsigned int opcode);
 
-static unsigned int
-PerformComparison(const unsigned int opcode);
+static unsigned int PerformComparison(const unsigned int opcode);
 
 unsigned int EmulateCPRT(const unsigned int opcode)
 {
-  unsigned int nRc = 1;
-
-  //printk("EmulateCPRT(0x%08x)\n",opcode);
 
-  if (opcode & 0x800000)
-  {
-     /* This is some variant of a comparison (PerformComparison will
-	sort out which one).  Since most of the other CPRT
-	instructions are oddball cases of some sort or other it makes
-	sense to pull this out into a fast path.  */
-     return PerformComparison(opcode);
-  }
-
-  /* Hint to GCC that we'd like a jump table rather than a load of CMPs */
-  switch ((opcode & 0x700000) >> 20)
-  {
-    case  FLT_CODE >> 20: nRc = PerformFLT(opcode); break;
-    case  FIX_CODE >> 20: nRc = PerformFIX(opcode); break;
-    
-    case  WFS_CODE >> 20: writeFPSR(readRegister(getRd(opcode))); break;
-    case  RFS_CODE >> 20: writeRegister(getRd(opcode),readFPSR()); break;
-
-#if 0    /* We currently have no use for the FPCR, so there's no point
-	    in emulating it. */
-    case  WFC_CODE >> 20: writeFPCR(readRegister(getRd(opcode)));
-    case  RFC_CODE >> 20: writeRegister(getRd(opcode),readFPCR()); break;
-#endif
+	if (opcode & 0x800000) {
+		/* This is some variant of a comparison (PerformComparison
+		   will sort out which one).  Since most of the other CPRT
+		   instructions are oddball cases of some sort or other it
+		   makes sense to pull this out into a fast path.  */
+		return PerformComparison(opcode);
+	}
+
+	/* Hint to GCC that we'd like a jump table rather than a load of CMPs */
+	switch ((opcode & 0x700000) >> 20) {
+	case FLT_CODE >> 20:
+		return PerformFLT(opcode);
+		break;
+	case FIX_CODE >> 20:
+		return PerformFIX(opcode);
+		break;
+
+	case WFS_CODE >> 20:
+		writeFPSR(readRegister(getRd(opcode)));
+		break;
+	case RFS_CODE >> 20:
+		writeRegister(getRd(opcode), readFPSR());
+		break;
+
+	default:
+		return 0;
+	}
 
-    default: nRc = 0;
-  }
-  
-  return nRc;
+	return 1;
 }
 
 unsigned int PerformFLT(const unsigned int opcode)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   
-   unsigned int nRc = 1;
-   SetRoundingMode(opcode);
-
-   switch (opcode & MASK_ROUNDING_PRECISION)
-   {
-      case ROUND_SINGLE:
-      {
-        fpa11->fType[getFn(opcode)] = typeSingle;
-        fpa11->fpreg[getFn(opcode)].fSingle =
-	   int32_to_float32(readRegister(getRd(opcode)));
-      }
-      break;
-
-      case ROUND_DOUBLE:
-      {
-        fpa11->fType[getFn(opcode)] = typeDouble;
-        fpa11->fpreg[getFn(opcode)].fDouble =
-            int32_to_float64(readRegister(getRd(opcode)));
-      }
-      break;
-        
-      case ROUND_EXTENDED:
-      {
-        fpa11->fType[getFn(opcode)] = typeExtended;
-        fpa11->fpreg[getFn(opcode)].fExtended =
-	   int32_to_floatx80(readRegister(getRd(opcode)));
-      }
-      break;
-      
-      default: nRc = 0;
-  }
-  
-  return nRc;
+	FPA11 *fpa11 = GET_FPA11();
+	SetRoundingMode(opcode);
+	SetRoundingPrecision(opcode);
+
+	switch (opcode & MASK_ROUNDING_PRECISION) {
+	case ROUND_SINGLE:
+		{
+			fpa11->fType[getFn(opcode)] = typeSingle;
+			fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(readRegister(getRd(opcode)));
+		}
+		break;
+
+	case ROUND_DOUBLE:
+		{
+			fpa11->fType[getFn(opcode)] = typeDouble;
+			fpa11->fpreg[getFn(opcode)].fDouble = int32_to_float64(readRegister(getRd(opcode)));
+		}
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case ROUND_EXTENDED:
+		{
+			fpa11->fType[getFn(opcode)] = typeExtended;
+			fpa11->fpreg[getFn(opcode)].fExtended = int32_to_floatx80(readRegister(getRd(opcode)));
+		}
+		break;
+#endif
+
+	default:
+		return 0;
+	}
+
+	return 1;
 }
 
 unsigned int PerformFIX(const unsigned int opcode)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   unsigned int nRc = 1;
-   unsigned int Fn = getFm(opcode);
-   
-   SetRoundingMode(opcode);
-
-   switch (fpa11->fType[Fn])
-   {
-      case typeSingle:
-      {
-         writeRegister(getRd(opcode),
-	               float32_to_int32(fpa11->fpreg[Fn].fSingle));
-      }
-      break;
-
-      case typeDouble:
-      {
-         writeRegister(getRd(opcode),
-	               float64_to_int32(fpa11->fpreg[Fn].fDouble));
-      }
-      break;
-      	               
-      case typeExtended:
-      {
-         writeRegister(getRd(opcode),
-	               floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
-      }
-      break;
-      
-      default: nRc = 0;
-  }
-  
-  return nRc;
-}
+	FPA11 *fpa11 = GET_FPA11();
+	unsigned int Fn = getFm(opcode);
 
-   
-static unsigned int __inline__
-PerformComparisonOperation(floatx80 Fn, floatx80 Fm)
-{
-   unsigned int flags = 0;
+	SetRoundingMode(opcode);
 
-   /* test for less than condition */
-   if (floatx80_lt(Fn,Fm))
-   {
-      flags |= CC_NEGATIVE;
-   }
-  
-   /* test for equal condition */
-   if (floatx80_eq(Fn,Fm))
-   {
-      flags |= CC_ZERO;
-   }
-
-   /* test for greater than or equal condition */
-   if (floatx80_lt(Fm,Fn))
-   {
-      flags |= CC_CARRY;
-   }
-   
-   writeConditionCodes(flags);
-   return 1;
+	switch (fpa11->fType[Fn]) {
+	case typeSingle:
+		{
+			writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle));
+		}
+		break;
+
+	case typeDouble:
+		{
+			writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble));
+		}
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		{
+			writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
+		}
+		break;
+#endif
+
+	default:
+		return 0;
+	}
+
+	return 1;
 }
 
 /* This instruction sets the flags N, Z, C, V in the FPSR. */
-   
 static unsigned int PerformComparison(const unsigned int opcode)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   unsigned int Fn, Fm;
-   floatx80 rFn, rFm;
-   int e_flag = opcode & 0x400000;	/* 1 if CxFE */
-   int n_flag = opcode & 0x200000;	/* 1 if CNxx */
-   unsigned int flags = 0;
-
-   //printk("PerformComparison(0x%08x)\n",opcode);
-
-   Fn = getFn(opcode);
-   Fm = getFm(opcode);
-
-   /* Check for unordered condition and convert all operands to 80-bit
-      format.
-      ?? Might be some mileage in avoiding this conversion if possible.
-      Eg, if both operands are 32-bit, detect this and do a 32-bit
-      comparison (cheaper than an 80-bit one).  */
-   switch (fpa11->fType[Fn])
-   {
-      case typeSingle: 
-        //printk("single.\n");
-	if (float32_is_nan(fpa11->fpreg[Fn].fSingle))
-	   goto unordered;
-        rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
-      break;
-
-      case typeDouble: 
-        //printk("double.\n");
-	if (float64_is_nan(fpa11->fpreg[Fn].fDouble))
-	   goto unordered;
-        rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
-      break;
-      
-      case typeExtended: 
-        //printk("extended.\n");
-	if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended))
-	   goto unordered;
-        rFn = fpa11->fpreg[Fn].fExtended;
-      break;
-      
-      default: return 0;
-   }
-
-   if (CONSTANT_FM(opcode))
-   {
-     //printk("Fm is a constant: #%d.\n",Fm);
-     rFm = getExtendedConstant(Fm);
-     if (floatx80_is_nan(rFm))
-        goto unordered;
-   }
-   else
-   {
-     //printk("Fm = r%d which contains a ",Fm);
-      switch (fpa11->fType[Fm])
-      {
-         case typeSingle: 
-           //printk("single.\n");
-	   if (float32_is_nan(fpa11->fpreg[Fm].fSingle))
-	      goto unordered;
-           rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
-         break;
-
-         case typeDouble: 
-           //printk("double.\n");
-	   if (float64_is_nan(fpa11->fpreg[Fm].fDouble))
-	      goto unordered;
-           rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
-         break;
-      
-         case typeExtended: 
-           //printk("extended.\n");
-	   if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended))
-	      goto unordered;
-           rFm = fpa11->fpreg[Fm].fExtended;
-         break;
-      
-         default: return 0;
-      }
-   }
-
-   if (n_flag)
-   {
-      rFm.high ^= 0x8000;
-   }
-
-   return PerformComparisonOperation(rFn,rFm);
-
- unordered:
-   /* ?? The FPA data sheet is pretty vague about this, in particular
-      about whether the non-E comparisons can ever raise exceptions.
-      This implementation is based on a combination of what it says in
-      the data sheet, observation of how the Acorn emulator actually
-      behaves (and how programs expect it to) and guesswork.  */
-   flags |= CC_OVERFLOW;
-   flags &= ~(CC_ZERO | CC_NEGATIVE);
+	FPA11 *fpa11 = GET_FPA11();
+	unsigned int Fn = getFn(opcode), Fm = getFm(opcode);
+	int e_flag = opcode & 0x400000;	/* 1 if CxFE */
+	int n_flag = opcode & 0x200000;	/* 1 if CNxx */
+	unsigned int flags = 0;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	floatx80 rFn, rFm;
+
+	/* Check for unordered condition and convert all operands to 80-bit
+	   format.
+	   ?? Might be some mileage in avoiding this conversion if possible.
+	   Eg, if both operands are 32-bit, detect this and do a 32-bit
+	   comparison (cheaper than an 80-bit one).  */
+	switch (fpa11->fType[Fn]) {
+	case typeSingle:
+		//printk("single.\n");
+		if (float32_is_nan(fpa11->fpreg[Fn].fSingle))
+			goto unordered;
+		rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+		break;
+
+	case typeDouble:
+		//printk("double.\n");
+		if (float64_is_nan(fpa11->fpreg[Fn].fDouble))
+			goto unordered;
+		rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+		break;
+
+	case typeExtended:
+		//printk("extended.\n");
+		if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended))
+			goto unordered;
+		rFn = fpa11->fpreg[Fn].fExtended;
+		break;
+
+	default:
+		return 0;
+	}
+
+	if (CONSTANT_FM(opcode)) {
+		//printk("Fm is a constant: #%d.\n",Fm);
+		rFm = getExtendedConstant(Fm);
+		if (floatx80_is_nan(rFm))
+			goto unordered;
+	} else {
+		//printk("Fm = r%d which contains a ",Fm);
+		switch (fpa11->fType[Fm]) {
+		case typeSingle:
+			//printk("single.\n");
+			if (float32_is_nan(fpa11->fpreg[Fm].fSingle))
+				goto unordered;
+			rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
+			break;
+
+		case typeDouble:
+			//printk("double.\n");
+			if (float64_is_nan(fpa11->fpreg[Fm].fDouble))
+				goto unordered;
+			rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
+			break;
+
+		case typeExtended:
+			//printk("extended.\n");
+			if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended))
+				goto unordered;
+			rFm = fpa11->fpreg[Fm].fExtended;
+			break;
+
+		default:
+			return 0;
+		}
+	}
+
+	if (n_flag)
+		rFm.high ^= 0x8000;
+
+	/* test for less than condition */
+	if (floatx80_lt(rFn, rFm))
+		flags |= CC_NEGATIVE;
+
+	/* test for equal condition */
+	if (floatx80_eq(rFn, rFm))
+		flags |= CC_ZERO;
+
+	/* test for greater than or equal condition */
+	if (floatx80_lt(rFm, rFn))
+		flags |= CC_CARRY;
+
+#else
+	if (CONSTANT_FM(opcode)) {
+		/* Fm is a constant.  Do the comparison in whatever precision
+		   Fn happens to be stored in.  */
+		if (fpa11->fType[Fn] == typeSingle) {
+			float32 rFm = getSingleConstant(Fm);
+			float32 rFn = fpa11->fpreg[Fn].fSingle;
+
+			if (float32_is_nan(rFn))
+				goto unordered;
+
+			if (n_flag)
+				rFm ^= 0x80000000;
+
+			/* test for less than condition */
+			if (float32_lt_nocheck(rFn, rFm))
+				flags |= CC_NEGATIVE;
+
+			/* test for equal condition */
+			if (float32_eq_nocheck(rFn, rFm))
+				flags |= CC_ZERO;
+
+			/* test for greater than or equal condition */
+			if (float32_lt_nocheck(rFm, rFn))
+				flags |= CC_CARRY;
+		} else {
+			float64 rFm = getDoubleConstant(Fm);
+			float64 rFn = fpa11->fpreg[Fn].fDouble;
+
+			if (float64_is_nan(rFn))
+				goto unordered;
+
+			if (n_flag)
+				rFm ^= 0x8000000000000000ULL;
+
+			/* test for less than condition */
+			if (float64_lt_nocheck(rFn, rFm))
+				flags |= CC_NEGATIVE;
+
+			/* test for equal condition */
+			if (float64_eq_nocheck(rFn, rFm))
+				flags |= CC_ZERO;
+
+			/* test for greater than or equal condition */
+			if (float64_lt_nocheck(rFm, rFn))
+				flags |= CC_CARRY;
+		}
+	} else {
+		/* Both operands are in registers.  */
+		if (fpa11->fType[Fn] == typeSingle
+		    && fpa11->fType[Fm] == typeSingle) {
+			float32 rFm = fpa11->fpreg[Fm].fSingle;
+			float32 rFn = fpa11->fpreg[Fn].fSingle;
+
+			if (float32_is_nan(rFn)
+			    || float32_is_nan(rFm))
+				goto unordered;
+
+			if (n_flag)
+				rFm ^= 0x80000000;
+
+			/* test for less than condition */
+			if (float32_lt_nocheck(rFn, rFm))
+				flags |= CC_NEGATIVE;
+
+			/* test for equal condition */
+			if (float32_eq_nocheck(rFn, rFm))
+				flags |= CC_ZERO;
+
+			/* test for greater than or equal condition */
+			if (float32_lt_nocheck(rFm, rFn))
+				flags |= CC_CARRY;
+		} else {
+			/* Promote 32-bit operand to 64 bits.  */
+			float64 rFm, rFn;
+
+			rFm = (fpa11->fType[Fm] == typeSingle) ?
+			    float32_to_float64(fpa11->fpreg[Fm].fSingle)
+			    : fpa11->fpreg[Fm].fDouble;
+
+			rFn = (fpa11->fType[Fn] == typeSingle) ?
+			    float32_to_float64(fpa11->fpreg[Fn].fSingle)
+			    : fpa11->fpreg[Fn].fDouble;
+
+			if (float64_is_nan(rFn)
+			    || float64_is_nan(rFm))
+				goto unordered;
+
+			if (n_flag)
+				rFm ^= 0x8000000000000000ULL;
+
+			/* test for less than condition */
+			if (float64_lt_nocheck(rFn, rFm))
+				flags |= CC_NEGATIVE;
+
+			/* test for equal condition */
+			if (float64_eq_nocheck(rFn, rFm))
+				flags |= CC_ZERO;
+
+			/* test for greater than or equal condition */
+			if (float64_lt_nocheck(rFm, rFn))
+				flags |= CC_CARRY;
+		}
+	}
+
+#endif
+
+	writeConditionCodes(flags);
+
+	return 1;
+
+      unordered:
+	/* ?? The FPA data sheet is pretty vague about this, in particular
+	   about whether the non-E comparisons can ever raise exceptions.
+	   This implementation is based on a combination of what it says in
+	   the data sheet, observation of how the Acorn emulator actually
+	   behaves (and how programs expect it to) and guesswork.  */
+	flags |= CC_OVERFLOW;
+	flags &= ~(CC_ZERO | CC_NEGATIVE);
 
-   if (BIT_AC & readFPSR()) flags |= CC_CARRY;
+	if (BIT_AC & readFPSR())
+		flags |= CC_CARRY;
 
-   if (e_flag) float_raise(float_flag_invalid);
+	if (e_flag)
+		float_raise(float_flag_invalid);
 
-   writeConditionCodes(flags);
-   return 1;
+	writeConditionCodes(flags);
+	return 1;
 }
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/fpmodule.c linux-2.4.22-pre3/arch/arm/nwfpe/fpmodule.c
--- linux-2.4.22-pre2/arch/arm/nwfpe/fpmodule.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/fpmodule.c	2003-07-05 18:09:37.000000000 -0700
@@ -41,13 +41,19 @@
 #include "fpa11.inl"
 
 /* kernel symbols required for signal handling */
-typedef struct task_struct*	PTASK;
+typedef struct task_struct *PTASK;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+#define NWFPE_BITS "extended"
+#else
+#define NWFPE_BITS "double"
+#endif
 
 #ifdef MODULE
 void fp_send_sig(unsigned long sig, PTASK p, int priv);
 #if LINUX_VERSION_CODE > 0x20115
 MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
-MODULE_DESCRIPTION("NWFPE floating point emulator");
+MODULE_DESCRIPTION("NWFPE floating point emulator (" NWFPE_BITS " precision)");
 #endif
 
 #else
@@ -63,7 +69,7 @@
 /* external declarations for saved kernel symbols */
 extern void (*kern_fp_enter)(void);
 
-/* Original value of fp_enter from kernel before patched by fpe_init. */ 
+/* Original value of fp_enter from kernel before patched by fpe_init. */
 static void (*orig_fp_enter)(void);
 
 /* forward declarations */
@@ -76,46 +82,45 @@
  */
 static int fpe_unload(void)
 {
-  return (kern_fp_enter == nwfpe_enter) ? 0 : 1;
+	return (kern_fp_enter == nwfpe_enter) ? 0 : 1;
 }
 #endif
 
 static int __init fpe_init(void)
 {
-  if (sizeof(FPA11) > sizeof(union fp_state)) {
-    printk(KERN_ERR "nwfpe: bad structure size\n");
-    return -EINVAL;
-  }
-
-  if (sizeof(FPREG) != 12) {
-    printk(KERN_ERR "nwfpe: bad register size\n");
-    return -EINVAL;
-  }
-
+	if (sizeof(FPA11) > sizeof(union fp_state)) {
+		printk(KERN_ERR "nwfpe: bad structure size\n");
+		return -EINVAL;
+	}
+
+	if (sizeof(FPREG) != 12) {
+		printk(KERN_ERR "nwfpe: bad register size\n");
+		return -EINVAL;
+	}
 #ifdef MODULE
-  if (!mod_member_present(&__this_module, can_unload))
-    return -EINVAL;
-  __this_module.can_unload = fpe_unload;
+	if (!mod_member_present(&__this_module, can_unload))
+		return -EINVAL;
+	__this_module.can_unload = fpe_unload;
 #else
-  if (fpe_type[0] && strcmp(fpe_type, "nwfpe"))
-    return 0;
+	if (fpe_type[0] && strcmp(fpe_type, "nwfpe"))
+		return 0;
 #endif
 
-  /* Display title, version and copyright information. */
-  printk(KERN_WARNING "NetWinder Floating Point Emulator V0.95 "
-	 "(c) 1998-1999 Rebel.com\n");
-
-  /* Save pointer to the old FP handler and then patch ourselves in */
-  orig_fp_enter = kern_fp_enter;
-  kern_fp_enter = nwfpe_enter;
+	/* Display title, version and copyright information. */
+	printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 ("
+	       NWFPE_BITS " precision)\n");
+
+	/* Save pointer to the old FP handler and then patch ourselves in */
+	orig_fp_enter = kern_fp_enter;
+	kern_fp_enter = nwfpe_enter;
 
-  return 0;
+	return 0;
 }
 
 static void __exit fpe_exit(void)
 {
-  /* Restore the values we saved earlier. */
-  kern_fp_enter = orig_fp_enter;
+	/* Restore the values we saved earlier. */
+	kern_fp_enter = orig_fp_enter;
 }
 
 /*
@@ -140,41 +145,42 @@
 
 void float_raise(signed char flags)
 {
-  register unsigned int fpsr, cumulativeTraps;
-  
+	register unsigned int fpsr, cumulativeTraps;
+
 #ifdef CONFIG_DEBUG_USER
-  printk(KERN_DEBUG "NWFPE: %s[%d] takes exception %08x at %p from %08x\n",
-	 current->comm, current->pid, flags,
-	 __builtin_return_address(0), GET_USERREG()[15]);
-#endif
-
-  /* Keep SoftFloat exception flags up to date.  */
-  float_exception_flags |= flags;
-
-  /* Read fpsr and initialize the cumulativeTraps.  */
-  fpsr = readFPSR();
-  cumulativeTraps = 0;
-  
-  /* For each type of exception, the cumulative trap exception bit is only
-     set if the corresponding trap enable bit is not set.  */
-  if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC))
-     cumulativeTraps |= BIT_IXC;  
-  if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC))
-     cumulativeTraps |= BIT_UFC;  
-  if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC))
-     cumulativeTraps |= BIT_OFC;  
-  if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC))
-     cumulativeTraps |= BIT_DZC;  
-  if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC))
-     cumulativeTraps |= BIT_IOC;  
-
-  /* Set the cumulative exceptions flags.  */
-  if (cumulativeTraps)
-    writeFPSR(fpsr | cumulativeTraps);
-
-  /* Raise an exception if necessary.  */
-  if (fpsr & (flags << 16))
-    fp_send_sig(SIGFPE, current, 1);
+	printk(KERN_DEBUG
+	       "NWFPE: %s[%d] takes exception %08x at %p from %08x\n",
+	       current->comm, current->pid, flags,
+	       __builtin_return_address(0), GET_USERREG()[15]);
+#endif
+
+	/* Keep SoftFloat exception flags up to date.  */
+	float_exception_flags |= flags;
+
+	/* Read fpsr and initialize the cumulativeTraps.  */
+	fpsr = readFPSR();
+	cumulativeTraps = 0;
+
+	/* For each type of exception, the cumulative trap exception bit is only
+	   set if the corresponding trap enable bit is not set.  */
+	if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC))
+		cumulativeTraps |= BIT_IXC;
+	if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC))
+		cumulativeTraps |= BIT_UFC;
+	if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC))
+		cumulativeTraps |= BIT_OFC;
+	if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC))
+		cumulativeTraps |= BIT_DZC;
+	if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC))
+		cumulativeTraps |= BIT_IOC;
+
+	/* Set the cumulative exceptions flags.  */
+	if (cumulativeTraps)
+		writeFPSR(fpsr | cumulativeTraps);
+
+	/* Raise an exception if necessary.  */
+	if (fpsr & (flags << 16))
+		fp_send_sig(SIGFPE, current, 1);
 }
 
 module_init(fpe_init);
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/fpmodule.inl linux-2.4.22-pre3/arch/arm/nwfpe/fpmodule.inl
--- linux-2.4.22-pre2/arch/arm/nwfpe/fpmodule.inl	2001-08-12 11:13:59.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/fpmodule.inl	2003-07-05 18:09:37.000000000 -0700
@@ -22,63 +22,64 @@
 extern __inline__
 unsigned int readRegister(const unsigned int nReg)
 {
-  /* Note: The CPU thinks it has dealt with the current instruction.  As
-           a result the program counter has been advanced to the next
-           instruction, and points 4 bytes beyond the actual instruction
-           that caused the invalid instruction trap to occur.  We adjust
-           for this in this routine.  LDF/STF instructions with Rn = PC
-           depend on the PC being correct, as they use PC+8 in their 
-           address calculations. */
-  unsigned int *userRegisters = GET_USERREG();
-  unsigned int val = userRegisters[nReg];
-  if (REG_PC == nReg) val -= 4;
-  return val;
+	/* Note: The CPU thinks it has dealt with the current instruction.
+	   As a result the program counter has been advanced to the next
+	   instruction, and points 4 bytes beyond the actual instruction
+	   that caused the invalid instruction trap to occur.  We adjust
+	   for this in this routine.  LDF/STF instructions with Rn = PC
+	   depend on the PC being correct, as they use PC+8 in their
+	   address calculations. */
+	unsigned int *userRegisters = GET_USERREG();
+	unsigned int val = userRegisters[nReg];
+	if (REG_PC == nReg)
+		val -= 4;
+	return val;
 }
 
 extern __inline__
 void writeRegister(const unsigned int nReg, const unsigned int val)
 {
-  unsigned int *userRegisters = GET_USERREG();
-  userRegisters[nReg] = val;
+	unsigned int *userRegisters = GET_USERREG();
+	userRegisters[nReg] = val;
 }
 
 extern __inline__
 unsigned int readCPSR(void)
 {
-  return(readRegister(REG_CPSR));
+	return (readRegister(REG_CPSR));
 }
 
 extern __inline__
 void writeCPSR(const unsigned int val)
 {
-  writeRegister(REG_CPSR,val);
+	writeRegister(REG_CPSR, val);
 }
 
 extern __inline__
 unsigned int readConditionCodes(void)
 {
 #ifdef __FPEM_TEST__
-   return(0);
+	return (0);
 #else
-   return(readCPSR() & CC_MASK);
+	return (readCPSR() & CC_MASK);
 #endif
 }
 
 extern __inline__
 void writeConditionCodes(const unsigned int val)
 {
-  unsigned int *userRegisters = GET_USERREG();
-  unsigned int rval;
-  /*
-   * Operate directly on userRegisters since
-   * the CPSR may be the PC register itself.
-   */
-  rval = userRegisters[REG_CPSR] & ~CC_MASK;
-  userRegisters[REG_CPSR] = rval | (val & CC_MASK);
+	unsigned int *userRegisters = GET_USERREG();
+	unsigned int rval;
+	/*
+	 * Operate directly on userRegisters since
+	 * the CPSR may be the PC register itself.
+	 */
+	rval = userRegisters[REG_CPSR] & ~CC_MASK;
+	userRegisters[REG_CPSR] = rval | (val & CC_MASK);
 }
 
 extern __inline__
 unsigned int readMemoryInt(unsigned int *pMem)
 {
-  return *pMem;
+	return *pMem;
 }
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/fpopcode.c linux-2.4.22-pre3/arch/arm/nwfpe/fpopcode.c
--- linux-2.4.22-pre2/arch/arm/nwfpe/fpopcode.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/fpopcode.c	2003-07-05 18:09:37.000000000 -0700
@@ -26,123 +26,64 @@
 #include "fpmodule.h"
 #include "fpmodule.inl"
 
+#ifdef CONFIG_FPE_NWFPE_XP
 const floatx80 floatx80Constant[] = {
-  { 0x0000, 0x0000000000000000ULL},	/* extended 0.0 */
-  { 0x3fff, 0x8000000000000000ULL},	/* extended 1.0 */
-  { 0x4000, 0x8000000000000000ULL},	/* extended 2.0 */
-  { 0x4000, 0xc000000000000000ULL},	/* extended 3.0 */
-  { 0x4001, 0x8000000000000000ULL},	/* extended 4.0 */
-  { 0x4001, 0xa000000000000000ULL},	/* extended 5.0 */
-  { 0x3ffe, 0x8000000000000000ULL},	/* extended 0.5 */
-  { 0x4002, 0xa000000000000000ULL}	/* extended 10.0 */
-};  
+	{0x0000, 0x0000000000000000ULL},	/* extended 0.0 */
+	{0x3fff, 0x8000000000000000ULL},	/* extended 1.0 */
+	{0x4000, 0x8000000000000000ULL},	/* extended 2.0 */
+	{0x4000, 0xc000000000000000ULL},	/* extended 3.0 */
+	{0x4001, 0x8000000000000000ULL},	/* extended 4.0 */
+	{0x4001, 0xa000000000000000ULL},	/* extended 5.0 */
+	{0x3ffe, 0x8000000000000000ULL},	/* extended 0.5 */
+	{0x4002, 0xa000000000000000ULL}		/* extended 10.0 */
+};
+#endif
 
 const float64 float64Constant[] = {
-  0x0000000000000000ULL,		/* double 0.0 */
-  0x3ff0000000000000ULL,		/* double 1.0 */
-  0x4000000000000000ULL,		/* double 2.0 */
-  0x4008000000000000ULL,		/* double 3.0 */
-  0x4010000000000000ULL,		/* double 4.0 */
-  0x4014000000000000ULL,		/* double 5.0 */
-  0x3fe0000000000000ULL,		/* double 0.5 */
-  0x4024000000000000ULL			/* double 10.0 */
-};  
+	0x0000000000000000ULL,	/* double 0.0 */
+	0x3ff0000000000000ULL,	/* double 1.0 */
+	0x4000000000000000ULL,	/* double 2.0 */
+	0x4008000000000000ULL,	/* double 3.0 */
+	0x4010000000000000ULL,	/* double 4.0 */
+	0x4014000000000000ULL,	/* double 5.0 */
+	0x3fe0000000000000ULL,	/* double 0.5 */
+	0x4024000000000000ULL	/* double 10.0 */
+};
 
 const float32 float32Constant[] = {
-  0x00000000,				/* single 0.0 */
-  0x3f800000,				/* single 1.0 */
-  0x40000000,				/* single 2.0 */
-  0x40400000,				/* single 3.0 */
-  0x40800000,				/* single 4.0 */
-  0x40a00000,				/* single 5.0 */
-  0x3f000000,				/* single 0.5 */
-  0x41200000				/* single 10.0 */
-};  
-
-unsigned int getTransferLength(const unsigned int opcode)
-{
-  unsigned int nRc;
-  
-  switch (opcode & MASK_TRANSFER_LENGTH)
-  {
-    case 0x00000000: nRc = 1; break; /* single precision */
-    case 0x00008000: nRc = 2; break; /* double precision */
-    case 0x00400000: nRc = 3; break; /* extended precision */
-    default: nRc = 0;
-  }
-  
-  return(nRc);
-}
-
-unsigned int getRegisterCount(const unsigned int opcode)
-{
-  unsigned int nRc;
-  
-  switch (opcode & MASK_REGISTER_COUNT)
-  {
-    case 0x00000000: nRc = 4; break;
-    case 0x00008000: nRc = 1; break;
-    case 0x00400000: nRc = 2; break;
-    case 0x00408000: nRc = 3; break;
-    default: nRc = 0;
-  }
-  
-  return(nRc);
-}
-
-unsigned int getRoundingPrecision(const unsigned int opcode)
-{
-  unsigned int nRc;
-  
-  switch (opcode & MASK_ROUNDING_PRECISION)
-  {
-    case 0x00000000: nRc = 1; break;
-    case 0x00000080: nRc = 2; break;
-    case 0x00080000: nRc = 3; break;
-    default: nRc = 0;
-  }
-  
-  return(nRc);
-}
-
-unsigned int getDestinationSize(const unsigned int opcode)
-{
-  unsigned int nRc;
-  
-  switch (opcode & MASK_DESTINATION_SIZE)
-  {
-    case 0x00000000: nRc = typeSingle; break;
-    case 0x00000080: nRc = typeDouble; break;
-    case 0x00080000: nRc = typeExtended; break;
-    default: nRc = typeNone;
-  }
-  
-  return(nRc);
-}
+	0x00000000,		/* single 0.0 */
+	0x3f800000,		/* single 1.0 */
+	0x40000000,		/* single 2.0 */
+	0x40400000,		/* single 3.0 */
+	0x40800000,		/* single 4.0 */
+	0x40a00000,		/* single 5.0 */
+	0x3f000000,		/* single 0.5 */
+	0x41200000		/* single 10.0 */
+};
 
 /* condition code lookup table
  index into the table is test code: EQ, NE, ... LT, GT, AL, NV
  bit position in short is condition code: NZCV */
 static const unsigned short aCC[16] = {
-    0xF0F0, // EQ == Z set
-    0x0F0F, // NE
-    0xCCCC, // CS == C set
-    0x3333, // CC
-    0xFF00, // MI == N set
-    0x00FF, // PL
-    0xAAAA, // VS == V set
-    0x5555, // VC
-    0x0C0C, // HI == C set && Z clear
-    0xF3F3, // LS == C clear || Z set
-    0xAA55, // GE == (N==V)
-    0x55AA, // LT == (N!=V)
-    0x0A05, // GT == (!Z && (N==V))
-    0xF5FA, // LE == (Z || (N!=V))
-    0xFFFF, // AL always
-    0 // NV
+	0xF0F0,			// EQ == Z set
+	0x0F0F,			// NE
+	0xCCCC,			// CS == C set
+	0x3333,			// CC
+	0xFF00,			// MI == N set
+	0x00FF,			// PL
+	0xAAAA,			// VS == V set
+	0x5555,			// VC
+	0x0C0C,			// HI == C set && Z clear
+	0xF3F3,			// LS == C clear || Z set
+	0xAA55,			// GE == (N==V)
+	0x55AA,			// LT == (N!=V)
+	0x0A05,			// GT == (!Z && (N==V))
+	0xF5FA,			// LE == (Z || (N!=V))
+	0xFFFF,			// AL always
+	0			// NV
 };
 
 unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes)
 {
-  return (aCC[opcode>>28] >> (ccodes>>28)) & 1;
+	return (aCC[opcode >> 28] >> (ccodes >> 28)) & 1;
 }
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/fpopcode.h linux-2.4.22-pre3/arch/arm/nwfpe/fpopcode.h
--- linux-2.4.22-pre2/arch/arm/nwfpe/fpopcode.h	2001-04-11 19:02:27.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/fpopcode.h	2003-07-05 18:09:37.000000000 -0700
@@ -1,6 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.COM, 1998,1999
+    (c) Philip Blundell, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -26,7 +27,7 @@
 ARM Floating Point Instruction Classes
 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
 |c o n d|1 1 0 P|U|u|W|L|   Rn  |v|  Fd |0|0|0|1|  o f f s e t  | CPDT
-|c o n d|1 1 0 P|U|w|W|L|   Rn  |x|  Fd |0|0|0|1|  o f f s e t  | CPDT
+|c o n d|1 1 0 P|U|w|W|L|   Rn  |x|  Fd |0|0|1|0|  o f f s e t  | CPDT (copro 2)
 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
 |c o n d|1 1 1 0|a|b|c|d|e|  Fn |j|  Fd |0|0|0|1|f|g|h|0|i|  Fm | CPDO
 |c o n d|1 1 1 0|a|b|c|L|e|  Fn |   Rd  |0|0|0|1|f|g|h|1|i|  Fm | CPRT
@@ -34,7 +35,7 @@
 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
 
 CPDT		data transfer instructions
-		LDF, STF, LFM, SFM
+		LDF, STF, LFM (copro 2), SFM (copro 2)
 		
 CPDO		dyadic arithmetic instructions
 		ADF, MUF, SUF, RSF, DVF, RDF,
@@ -186,7 +187,7 @@
 #define BIT_LOAD	0x00100000
 
 /* masks for load/store */
-#define MASK_CPDT		0x0c000000  /* data processing opcode */
+#define MASK_CPDT		0x0c000000	/* data processing opcode */
 #define MASK_OFFSET		0x000000ff
 #define MASK_TRANSFER_LENGTH	0x00408000
 #define MASK_REGISTER_COUNT	MASK_TRANSFER_LENGTH
@@ -236,7 +237,7 @@
 #define MONADIC_INSTRUCTION(opcode)	((opcode & BIT_MONADIC) != 0)
 
 /* instruction identification masks */
-#define MASK_CPDO		0x0e000000  /* arithmetic opcode */
+#define MASK_CPDO		0x0e000000	/* arithmetic opcode */
 #define MASK_ARITHMETIC_OPCODE	0x00f08000
 #define MASK_DESTINATION_SIZE	0x00080080
 
@@ -282,7 +283,7 @@
 ===
 */
 
-#define MASK_CPRT		0x0e000010  /* register transfer opcode */
+#define MASK_CPRT		0x0e000010	/* register transfer opcode */
 #define MASK_CPRT_CODE		0x00f00000
 #define FLT_CODE		0x00000000
 #define FIX_CODE		0x00100000
@@ -366,25 +367,111 @@
 /* Get the rounding mode from the opcode. */
 #define getRoundingMode(opcode)		((opcode & MASK_ROUNDING_MODE) >> 5)
 
+#ifdef CONFIG_FPE_NWFPE_XP
 static inline const floatx80 getExtendedConstant(const unsigned int nIndex)
 {
-   extern const floatx80 floatx80Constant[];
-   return floatx80Constant[nIndex];
-} 
+	extern const floatx80 floatx80Constant[];
+	return floatx80Constant[nIndex];
+}
+#endif
 
 static inline const float64 getDoubleConstant(const unsigned int nIndex)
 {
-   extern const float64 float64Constant[];
-   return float64Constant[nIndex];
-} 
+	extern const float64 float64Constant[];
+	return float64Constant[nIndex];
+}
 
 static inline const float32 getSingleConstant(const unsigned int nIndex)
 {
-   extern const float32 float32Constant[];
-   return float32Constant[nIndex];
-} 
+	extern const float32 float32Constant[];
+	return float32Constant[nIndex];
+}
+
+static inline unsigned int getTransferLength(const unsigned int opcode)
+{
+	unsigned int nRc;
+
+	switch (opcode & MASK_TRANSFER_LENGTH) {
+	case 0x00000000:
+		nRc = 1;
+		break;		/* single precision */
+	case 0x00008000:
+		nRc = 2;
+		break;		/* double precision */
+	case 0x00400000:
+		nRc = 3;
+		break;		/* extended precision */
+	default:
+		nRc = 0;
+	}
+
+	return (nRc);
+}
+
+static inline unsigned int getRegisterCount(const unsigned int opcode)
+{
+	unsigned int nRc;
+
+	switch (opcode & MASK_REGISTER_COUNT) {
+	case 0x00000000:
+		nRc = 4;
+		break;
+	case 0x00008000:
+		nRc = 1;
+		break;
+	case 0x00400000:
+		nRc = 2;
+		break;
+	case 0x00408000:
+		nRc = 3;
+		break;
+	default:
+		nRc = 0;
+	}
+
+	return (nRc);
+}
+
+static inline unsigned int getRoundingPrecision(const unsigned int opcode)
+{
+	unsigned int nRc;
+
+	switch (opcode & MASK_ROUNDING_PRECISION) {
+	case 0x00000000:
+		nRc = 1;
+		break;
+	case 0x00000080:
+		nRc = 2;
+		break;
+	case 0x00080000:
+		nRc = 3;
+		break;
+	default:
+		nRc = 0;
+	}
+
+	return (nRc);
+}
+
+static inline unsigned int getDestinationSize(const unsigned int opcode)
+{
+	unsigned int nRc;
+
+	switch (opcode & MASK_DESTINATION_SIZE) {
+	case 0x00000000:
+		nRc = typeSingle;
+		break;
+	case 0x00000080:
+		nRc = typeDouble;
+		break;
+	case 0x00080000:
+		nRc = typeExtended;
+		break;
+	default:
+		nRc = typeNone;
+	}
 
-extern unsigned int getRegisterCount(const unsigned int opcode);
-extern unsigned int getDestinationSize(const unsigned int opcode);
+	return (nRc);
+}
 
 #endif
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/fpsr.h linux-2.4.22-pre3/arch/arm/nwfpe/fpsr.h
--- linux-2.4.22-pre2/arch/arm/nwfpe/fpsr.h	2000-02-13 10:47:01.000000000 -0800
+++ linux-2.4.22-pre3/arch/arm/nwfpe/fpsr.h	2003-07-05 18:09:37.000000000 -0700
@@ -38,12 +38,12 @@
 ------------
 Note: the system id byte is read only  */
 
-typedef unsigned int FPSR;  /* type for floating point status register */
-typedef unsigned int FPCR;  /* type for floating point control register */
+typedef unsigned int FPSR;	/* type for floating point status register */
+typedef unsigned int FPCR;	/* type for floating point control register */
 
 #define MASK_SYSID		0xff000000
 #define BIT_HARDWARE		0x80000000
-#define FP_EMULATOR		0x01000000	/* System ID for emulator */ 
+#define FP_EMULATOR		0x01000000	/* System ID for emulator */
 #define FP_ACCELERATOR		0x81000000	/* System ID for FPA11 */
 
 /* EXCEPTION TRAP ENABLE BYTE
@@ -51,11 +51,11 @@
 
 #define MASK_TRAP_ENABLE	0x00ff0000
 #define MASK_TRAP_ENABLE_STRICT	0x001f0000
-#define BIT_IXE		0x00100000   /* inexact exception enable */
-#define BIT_UFE		0x00080000   /* underflow exception enable */
-#define BIT_OFE		0x00040000   /* overflow exception enable */
-#define BIT_DZE		0x00020000   /* divide by zero exception enable */
-#define BIT_IOE		0x00010000   /* invalid operation exception enable */
+#define BIT_IXE		0x00100000	/* inexact exception enable */
+#define BIT_UFE		0x00080000	/* underflow exception enable */
+#define BIT_OFE		0x00040000	/* overflow exception enable */
+#define BIT_DZE		0x00020000	/* divide by zero exception enable */
+#define BIT_IOE		0x00010000	/* invalid operation exception enable */
 
 /* SYSTEM CONTROL BYTE
 ---------------------- */
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/single_cpdo.c linux-2.4.22-pre3/arch/arm/nwfpe/single_cpdo.c
--- linux-2.4.22-pre2/arch/arm/nwfpe/single_cpdo.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/single_cpdo.c	2003-07-05 18:09:37.000000000 -0700
@@ -1,6 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.COM, 1998,1999
+    (c) Philip Blundell, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -32,224 +33,92 @@
 float32 float32_log(float32 rFm);
 float32 float32_tan(float32 rFm);
 float32 float32_arccos(float32 rFm);
-float32 float32_pow(float32 rFn,float32 rFm);
-float32 float32_pol(float32 rFn,float32 rFm);
+float32 float32_pow(float32 rFn, float32 rFm);
+float32 float32_pol(float32 rFn, float32 rFm);
 
-unsigned int SingleCPDO(const unsigned int opcode)
+static float32 float32_rsf(float32 rFn, float32 rFm)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   float32 rFm, rFn;
-   unsigned int Fd, Fm, Fn, nRc = 1;
-
-   Fm = getFm(opcode);
-   if (CONSTANT_FM(opcode))
-   {
-     rFm = getSingleConstant(Fm);
-   }
-   else
-   {  
-     switch (fpa11->fType[Fm])
-     {
-        case typeSingle:
-          rFm = fpa11->fpreg[Fm].fSingle;
-        break;
-        
-        default: return 0;
-     }
-   }
-
-   if (!MONADIC_INSTRUCTION(opcode))
-   {
-      Fn = getFn(opcode);
-      switch (fpa11->fType[Fn])
-      {
-        case typeSingle:
-          rFn = fpa11->fpreg[Fn].fSingle;
-        break;
-
-        default: return 0;
-      }
-   }
-
-   Fd = getFd(opcode);
-   switch (opcode & MASK_ARITHMETIC_OPCODE)
-   {
-      /* dyadic opcodes */
-      case ADF_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm);
-      break;
-
-      case MUF_CODE:
-      case FML_CODE:
-        fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm);
-      break;
-
-      case SUF_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm);
-      break;
-
-      case RSF_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn);
-      break;
-
-      case DVF_CODE:
-      case FDV_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm);
-      break;
-
-      case RDF_CODE:
-      case FRD_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn);
-      break;
-
-#if 0
-      case POW_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm);
-      break;
-
-      case RPW_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn);
-      break;
-#endif
-
-      case RMF_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm);
-      break;
-
-#if 0
-      case POL_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm);
-      break;
-#endif
-
-      /* monadic opcodes */
-      case MVF_CODE:
-         fpa11->fpreg[Fd].fSingle = rFm;
-      break;
-
-      case MNF_CODE:
-         rFm ^= 0x80000000;
-         fpa11->fpreg[Fd].fSingle = rFm;
-      break;
-
-      case ABS_CODE:
-         rFm &= 0x7fffffff;
-         fpa11->fpreg[Fd].fSingle = rFm;
-      break;
-
-      case RND_CODE:
-      case URD_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm);
-      break;
-
-      case SQT_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm);
-      break;
-
-#if 0
-      case LOG_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_log(rFm);
-      break;
-
-      case LGN_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_ln(rFm);
-      break;
-
-      case EXP_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_exp(rFm);
-      break;
-
-      case SIN_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_sin(rFm);
-      break;
-
-      case COS_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_cos(rFm);
-      break;
-
-      case TAN_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_tan(rFm);
-      break;
-
-      case ASN_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm);
-      break;
-
-      case ACS_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_arccos(rFm);
-      break;
-
-      case ATN_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_arctan(rFm);
-      break;
-#endif
-
-      case NRM_CODE:
-      break;
-      
-      default:
-      {
-        nRc = 0;
-      }
-   }
-
-   if (0 != nRc) fpa11->fType[Fd] = typeSingle;
-   return nRc;
+	return float32_sub(rFm, rFn);
 }
 
-#if 0
-float32 float32_exp(float32 Fm)
+static float32 float32_rdv(float32 rFn, float32 rFm)
 {
-//series
+	return float32_div(rFm, rFn);
 }
 
-float32 float32_ln(float32 Fm)
-{
-//series
-}
+static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = {
+	[ADF_CODE >> 20] = float32_add,
+	[MUF_CODE >> 20] = float32_mul,
+	[SUF_CODE >> 20] = float32_sub,
+	[RSF_CODE >> 20] = float32_rsf,
+	[DVF_CODE >> 20] = float32_div,
+	[RDF_CODE >> 20] = float32_rdv,
+	[RMF_CODE >> 20] = float32_rem,
 
-float32 float32_sin(float32 rFm)
-{
-//series
-}
+	[FML_CODE >> 20] = float32_mul,
+	[FDV_CODE >> 20] = float32_div,
+	[FRD_CODE >> 20] = float32_rdv,
+};
 
-float32 float32_cos(float32 rFm)
+static float32 float32_mvf(float32 rFm)
 {
-//series
+	return rFm;
 }
 
-float32 float32_arcsin(float32 rFm)
+static float32 float32_mnf(float32 rFm)
 {
-//series
+	return rFm ^ 0x80000000;
 }
 
-float32 float32_arctan(float32 rFm)
+static float32 float32_abs(float32 rFm)
 {
-  //series
+	return rFm & 0x7fffffff;
 }
 
-float32 float32_arccos(float32 rFm)
-{
-   //return float32_sub(halfPi,float32_arcsin(rFm));
-}
+static float32 (*const monadic_single[16])(float32 rFm) = {
+	[MVF_CODE >> 20] = float32_mvf,
+	[MNF_CODE >> 20] = float32_mnf,
+	[ABS_CODE >> 20] = float32_abs,
+	[RND_CODE >> 20] = float32_round_to_int,
+	[URD_CODE >> 20] = float32_round_to_int,
+	[SQT_CODE >> 20] = float32_sqrt,
+	[NRM_CODE >> 20] = float32_mvf,
+};
 
-float32 float32_log(float32 rFm)
+unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd)
 {
-  return float32_div(float32_ln(rFm),getSingleConstant(7));
-}
+	FPA11 *fpa11 = GET_FPA11();
+	float32 rFm;
+	unsigned int Fm, opc_mask_shift;
 
-float32 float32_tan(float32 rFm)
-{
-  return float32_div(float32_sin(rFm),float32_cos(rFm));
-}
+	Fm = getFm(opcode);
+	if (CONSTANT_FM(opcode)) {
+		rFm = getSingleConstant(Fm);
+	} else if (fpa11->fType[Fm] == typeSingle) {
+		rFm = fpa11->fpreg[Fm].fSingle;
+	} else {
+		return 0;
+	}
 
-float32 float32_pow(float32 rFn,float32 rFm)
-{
-  return float32_exp(float32_mul(rFm,float32_ln(rFn))); 
-}
+	opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
+	if (!MONADIC_INSTRUCTION(opcode)) {
+		unsigned int Fn = getFn(opcode);
+		float32 rFn;
 
-float32 float32_pol(float32 rFn,float32 rFm)
-{
-  return float32_arctan(float32_div(rFn,rFm)); 
+		if (fpa11->fType[Fn] == typeSingle &&
+		    dyadic_single[opc_mask_shift]) {
+			rFn = fpa11->fpreg[Fn].fSingle;
+			rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm);
+		} else {
+			return 0;
+		}
+	} else {
+		if (monadic_single[opc_mask_shift]) {
+			rFd->fSingle = monadic_single[opc_mask_shift](rFm);
+		} else {
+			return 0;
+		}
+	}
+
+	return 1;
 }
-#endif
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/softfloat.c linux-2.4.22-pre3/arch/arm/nwfpe/softfloat.c
--- linux-2.4.22-pre2/arch/arm/nwfpe/softfloat.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/softfloat.c	2003-07-05 18:09:37.000000000 -0700
@@ -29,8 +29,8 @@
 */
 
 #include "fpa11.h"
-#include "milieu.h"
-#include "softfloat.h"
+//#include "milieu.h"
+//#include "softfloat.h"
 
 /*
 -------------------------------------------------------------------------------
@@ -142,12 +142,14 @@
 Returns the sign bit of the single-precision floating-point value `a'.
 -------------------------------------------------------------------------------
 */
+#if 0	/* in softfloat.h */
 INLINE flag extractFloat32Sign( float32 a )
 {
 
     return a>>31;
 
 }
+#endif
 
 /*
 -------------------------------------------------------------------------------
@@ -184,9 +186,9 @@
 {
 #if 0
    float32 f;
-   __asm__("@ packFloat32;
-   	    mov %0, %1, asl #31;
-   	    orr %0, %2, asl #23;
+   __asm__("@ packFloat32				\n\
+   	    mov %0, %1, asl #31				\n\
+   	    orr %0, %2, asl #23				\n\
    	    orr %0, %3"
    	    : /* no outputs */
    	    : "g" (f), "g" (zSign), "g" (zExp), "g" (zSig)
@@ -321,12 +323,14 @@
 Returns the sign bit of the double-precision floating-point value `a'.
 -------------------------------------------------------------------------------
 */
+#if 0	/* in softfloat.h */
 INLINE flag extractFloat64Sign( float64 a )
 {
 
     return a>>63;
 
 }
+#endif
 
 /*
 -------------------------------------------------------------------------------
diff -urN linux-2.4.22-pre2/arch/arm/nwfpe/softfloat.h linux-2.4.22-pre3/arch/arm/nwfpe/softfloat.h
--- linux-2.4.22-pre2/arch/arm/nwfpe/softfloat.h	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/nwfpe/softfloat.h	2003-07-05 18:09:37.000000000 -0700
@@ -40,7 +40,9 @@
 input or output the `floatx80' type will be defined.
 -------------------------------------------------------------------------------
 */
+#ifdef CONFIG_FPE_NWFPE_XP
 #define FLOATX80
+#endif
 
 /*
 -------------------------------------------------------------------------------
@@ -229,4 +231,46 @@
 
 #endif
 
+static inline flag extractFloat32Sign(float32 a)
+{
+	return a >> 31;
+}
+
+static inline flag float32_eq_nocheck(float32 a, float32 b)
+{
+	return (a == b) || ((bits32) ((a | b) << 1) == 0);
+}
+
+static inline flag float32_lt_nocheck(float32 a, float32 b)
+{
+	flag aSign, bSign;
+
+	aSign = extractFloat32Sign(a);
+	bSign = extractFloat32Sign(b);
+	if (aSign != bSign)
+		return aSign && ((bits32) ((a | b) << 1) != 0);
+	return (a != b) && (aSign ^ (a < b));
+}
+
+static inline flag extractFloat64Sign(float64 a)
+{
+	return a >> 63;
+}
+
+static inline flag float64_eq_nocheck(float64 a, float64 b)
+{
+	return (a == b) || ((bits64) ((a | b) << 1) == 0);
+}
+
+static inline flag float64_lt_nocheck(float64 a, float64 b)
+{
+	flag aSign, bSign;
+
+	aSign = extractFloat64Sign(a);
+	bSign = extractFloat64Sign(b);
+	if (aSign != bSign)
+		return aSign && ((bits64) ((a | b) << 1) != 0);
+	return (a != b) && (aSign ^ (a < b));
+}
+
 #endif
diff -urN linux-2.4.22-pre2/arch/arm/tools/mach-types linux-2.4.22-pre3/arch/arm/tools/mach-types
--- linux-2.4.22-pre2/arch/arm/tools/mach-types	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/arm/tools/mach-types	2003-07-05 18:09:37.000000000 -0700
@@ -6,7 +6,7 @@
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Sat Mar 16 15:56:27 2002
+# Last update: Sat Jun 28 12:10:54 2003
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -71,7 +71,7 @@
 jupiter			SA1100_JUPITER		JUPITER			59
 psionw			ARCH_PSIONW		PSIONW			60
 aln			SA1100_ALN		ALN			61
-epxa10db		ARCH_CAMELOT		CAMELOT			62
+epxa			ARCH_CAMELOT		CAMELOT			62
 gds2200			SA1100_GDS2200		GDS2200			63
 psion_series7		SA1100_PSION_SERIES7	PSION_SERIES7		64
 xfile			SA1100_XFILE		XFILE			65
@@ -149,12 +149,12 @@
 blue_v1			ARCH_BLUE_V1		BLUE_V1			138
 pxa_cerf		ARCH_PXA_CERF		PXA_CERF		139
 arm7tevb		ARCH_ARM7TEVB		ARM7TEVB		140
-d7400			ARCH_D7400		D7400			141
+d7400			SA1100_D7400		D7400			141
 piranha			ARCH_PIRANHA		PIRANHA			142
 sbcamelot		SA1100_SBCAMELOT	SBCAMELOT		143
 kings			SA1100_KINGS		KINGS			144
 smdk2400		ARCH_SMDK2400		SMDK2400		145
-collie			ARCH_COLLIE		COLLIE			146
+collie			SA1100_COLLIE		COLLIE			146
 idr			ARCH_IDR		IDR			147
 badge4			SA1100_BADGE4		BADGE4			148
 webnet			ARCH_WEBNET		WEBNET			149
@@ -175,6 +175,184 @@
 iam			SA1100_IAM		IAM			164
 tt530			SA1100_TT530		TT530			165
 sam2400			ARCH_SAM2400		SAM2400			166
-jornada56x		ARCH_JORNADA56X		JORNADA56X		167
+jornada56x		SA1100_JORNADA56X	JORNADA56X		167
 active			SA1100_ACTIVE		ACTIVE			168
 iq80321			ARCH_IQ80321		IQ80321			169
+wid			SA1100_WID		WID			170
+sabinal			ARCH_SABINAL		SABINAL			171
+ixp425_matacumbe	ARCH_IXP425_MATACUMBE	IXP425_MATACUMBE	172
+miniprint		SA1100_MINIPRINT	MINIPRINT		173
+adm510x			ARCH_ADM510X		ADM510X			174
+svs200			SA1100_SVS200		SVS200			175
+atg_tcu			ARCH_ATG_TCU		ATG_TCU			176
+jornada820		SA1100_JORNADA820	JORNADA820		177
+s3c44b0			ARCH_S3C44B0		S3C44B0			178
+margis2			ARCH_MARGIS2		MARGIS2			179
+ks8695			ARCH_KS8695		KS8695			180
+brh			ARCH_BRH		BRH			181
+s3c2410			ARCH_S3C2410		S3C2410			182
+possio_px30		ARCH_POSSIO_PX30	POSSIO_PX30		183
+s3c2800			ARCH_S3C2800		S3C2800			184
+fleetwood		SA1100_FLEETWOOD	FLEETWOOD		185
+omaha			ARCH_OMAHA		OMAHA			186
+ta7			ARCH_TA7		TA7			187
+nova			SA1100_NOVA		NOVA			188
+hmk			ARCH_HMK		HMK			189
+karo			ARCH_KARO		KARO			190
+fester			SA1100_FESTER		FESTER			191
+gpi			ARCH_GPI		GPI			192
+smdk2410		ARCH_SMDK2410		SMDK2410		193
+premium			ARCH_PREMIUM		PREMIUM			194
+nexio			SA1100_NEXIO		NEXIO			195
+bitbox			SA1100_BITBOX		BITBOX			196
+g200			SA1100_G200		G200			197
+gill			SA1100_GILL		GILL			198
+pxa_mercury		ARCH_PXA_MERCURY	PXA_MERCURY		199
+ceiva			ARCH_CEIVA		CEIVA			200
+fret			SA1100_FRET		FRET			201
+emailphone		SA1100_EMAILPHONE	EMAILPHONE		202
+h3900			ARCH_H3900		H3900			203
+pxa1			ARCH_PXA1		PXA1			204
+koan369			SA1100_KOAN369		KOAN369			205
+cogent			ARCH_COGENT		COGENT			206
+esl_simputer		ARCH_ESL_SIMPUTER	ESL_SIMPUTER		207
+esl_simputer_clr	ARCH_ESL_SIMPUTER_CLR	ESL_SIMPUTER_CLR	208
+esl_simputer_bw		ARCH_ESL_SIMPUTER_BW	ESL_SIMPUTER_BW		209
+hhp_cradle		ARCH_HHP_CRADLE		HHP_CRADLE		210
+he500			ARCH_HE500		HE500			211
+inhandelf2		SA1100_INHANDELF2	INHANDELF2		212
+inhandftip		SA1100_INHANDFTIP	INHANDFTIP		213
+dnp1110			SA1100_DNP1110		DNP1110			214
+pnp1110			SA1100_PNP1110		PNP1110			215
+csb226			ARCH_CSB226		CSB226			216
+arnold			SA1100_ARNOLD		ARNOLD			217
+psiboard		SA1100_PSIBOARD		PSIBOARD		218
+jz8028			ARCH_JZ8028		JZ8028			219
+h5400			ARCH_IPAQ3		IPAQ3			220
+forte			SA1100_FORTE		FORTE			221
+acam			SA1100_ACAM		ACAM			222
+abox			SA1100_ABOX		ABOX			223
+atmel			ARCH_ATMEL		ATMEL			224
+sitsang			ARCH_SITSANG		SITSANG			225
+cpu1110lcdnet		SA1100_CPU1110LCDNET	CPU1110LCDNET		226
+mpl_vcma9		ARCH_MPL_VCMA9		MPL_VCMA9		227
+opus_a1			ARCH_OPUS_A1		OPUS_A1			228
+daytona			ARCH_DAYTONA		DAYTONA			229
+killbear		SA1100_KILLBEAR		KILLBEAR		230
+yoho			ARCH_YOHO		YOHO			231
+jasper			ARCH_JASPER		JASPER			232
+dsc25			ARCH_DSC25		DSC25			233
+innovator		ARCH_INNOVATOR		INNOVATOR		234
+ramses			ARCH_RAMSES		RAMSES			235
+s28x			ARCH_S28X		S28X			236
+mport3			ARCH_MPORT3		MPORT3			237
+pxa_eagle250		ARCH_PXA_EAGLE250	PXA_EAGLE250		238
+pdb			ARCH_PDB		PDB			239
+blue_2g			SA1100_BLUE_2G		BLUE_2G			240
+bluearch		SA1100_BLUEARCH		BLUEARCH		241
+ixdp2400		ARCH_IXMB2400		IXMB2400		242
+ixdp2800		ARCH_IXMB2800		IXMB2800		243
+explorer		SA1100_EXPLORER		EXPLORER		244
+ixdp425			ARCH_IXDP425		IXDP425			245
+chimp			ARCH_CHIMP		CHIMP			246
+stork_nest		ARCH_STORK_NEST		STORK_NEST		247
+stork_egg		ARCH_STORK_EGG		STORK_EGG		248
+wismo			SA1100_WISMO		WISMO			249
+ezlinx			ARCH_EZLINX		EZLINX			250
+at91rm9200		ARCH_AT91		AT91			251
+orion			ARCH_ORION		ORION			252
+neptune			ARCH_NEPTUNE		NEPTUNE			253
+hackkit			SA1100_HACKKIT		HACKKIT			254
+pxa_wins30		ARCH_PXA_WINS30		PXA_WINS30		255
+lavinna			SA1100_LAVINNA		LAVINNA			256
+pxa_uengine		ARCH_PXA_UENGINE	PXA_UENGINE		257
+innokom			ARCH_INNOKOM		INNOKOM			258
+bms			ARCH_BMS		BMS			259
+ixcdp1100		ARCH_IXCDP1100		IXCDP1100		260
+prpmc1100		ARCH_PRPMC1100		PRPMC1100		261
+at91rm9200dk		ARCH_AT91RM9200DK	AT91RM9200DK		262
+armstick		ARCH_ARMSTICK		ARMSTICK		263
+armonie			ARCH_ARMONIE		ARMONIE			264
+mport1			ARCH_MPORT1		MPORT1			265
+s3c5410			ARCH_S3C5410		S3C5410			266
+zcp320a			ARCH_ZCP320A		ZCP320A			267
+i_box			ARCH_I_BOX		I_BOX			268
+stlc1502		ARCH_STLC1502		STLC1502		269
+siren			ARCH_SIREN		SIREN			270
+greenlake		ARCH_GREENLAKE		GREENLAKE		271
+argus			ARCH_ARGUS		ARGUS			272
+combadge		SA1100_COMBADGE		COMBADGE		273
+rokepxa			ARCH_ROKEPXA		ROKEPXA			274
+cintegrator		ARCH_CINTEGRATOR	CINTEGRATOR		275
+guidea07		ARCH_GUIDEA07		GUIDEA07		276
+tat257			ARCH_TAT257		TAT257			277
+igp2425			ARCH_IGP2425		IGP2425			278
+bluegrama		ARCH_BLUEGRAMMA		BLUEGRAMMA		279
+ipod			ARCH_IPOD		IPOD			280
+adsbitsyx		ARCH_ADSBITSYX		ADSBITSYX		281
+trizeps2		ARCH_TRIZEPS2		TRIZEPS2		282
+viper			ARCH_VIPER		VIPER			283
+adsbitsyplus		SA1100_ADSBITSYPLUS	ADSBITSYPLUS		284
+adsagc			SA1100_ADSAGC		ADSAGC			285
+stp7312			ARCH_STP7312		STP7312			286
+nx_phnx			ARCH_PXA255		PXA255			287
+wep_ep250		ARCH_WEP_EP250		WEP_EP250		288
+inhandelf3		ARCH_INHANDELF3		INHANDELF3		289
+adi_coyote		ARCH_ADI_COYOTE		ADI_COYOTE		290
+iyonix			ARCH_IYONIX		IYONIX			291
+damicam_sa1110		ARCH_DAMICAM_SA1110	DAMICAM_SA1110		292
+meg03			ARCH_MEG03		MEG03			293
+pxa_whitechapel		ARCH_PXA_WHITECHAPEL	PXA_WHITECHAPEL		294
+nwsc			ARCH_NWSC		NWSC			295
+nwlarm			ARCH_NWLARM		NWLARM			296
+ixp425_mguard		ARCH_IXP425_MGUARD	IXP425_MGUARD		297
+pxa_netdcu4		ARCH_PXA_NETDCU4	PXA_NETDCU4		298
+ixdp2401		ARCH_IXDP2401		IXDP2401		299
+ixdp2801		ARCH_IXDP2801		IXDP2801		300
+zodiac			ARCH_ZODIAC		ZODIAC			301
+armmodul		ARCH_ARMMODUL		ARMMODUL		302
+ketop			SA1100_KETOP		KETOP			303
+av7200			ARCH_AV7200		AV7200			304
+arch_ti925		ARCH_ARCH_TI925		ARCH_TI925		305
+acq200			ARCH_ACQ200		ACQ200			306
+pt_dafit		SA1100_PT_DAFIT		PT_DAFIT		307
+ihba			ARCH_IHBA		IHBA			308
+quinque			ARCH_QUINQUE		QUINQUE			309
+nimbraone		ARCH_NIMBRAONE		NIMBRAONE		310
+nimbra29x		ARCH_NIMBRA29X		NIMBRA29X		311
+nimbra210		ARCH_NIMBRA210		NIMBRA210		312
+hhp_d95xx		ARCH_HHP_D95XX		HHP_D95XX		313
+labarm			ARCH_LABARM		LABARM			314
+m825xx			ARCH_M825XX		M825XX			315
+m7100			SA1100_M7100		M7100			316
+nipc2			ARCH_NIPC2		NIPC2			317
+fu7202			ARCH_FU7202		FU7202			318
+adsagx			ARCH_ADSAGX		ADSAGX			319
+pxa_pooh		ARCH_PXA_POOH		PXA_POOH		320
+bandon			ARCH_BANDON		BANDON			321
+pcm7210			ARCH_PCM7210		PCM7210			322
+nms9200			ARCH_NMS9200		NMS9200			323
+logodl			ARCH_LOGODL		LOGODL			324
+m7140			SA1100_M7140		M7140			325
+korebot			ARCH_KOREBOT		KOREBOT			326
+iq31244			ARCH_IQ31244		IQ31244			327
+koan393			SA1100_KOAN393		KOAN393			328
+inhandftip3		ARCH_INHANDFTIP3	INHANDFTIP3		329
+gonzo			ARCH_GONZO		GONZO			330
+bast			ARCH_BAST		BAST			331
+scanpass		ARCH_SCANPASS		SCANPASS		332
+ep7312_pooh		ARCH_EP7312_POOH	EP7312_POOH		333
+ta7s			ARCH_TA7S		TA7S			334
+ta7v			ARCH_TA7V		TA7V			335
+icarus			SA1100_ICARUS		ICARUS			336
+h1900			ARCH_H1900		H1900			337
+gemini			SA1100_GEMINI		GEMINI			338
+axim			ARCH_AXIM		AXIM			339
+audiotron		ARCH_AUDIOTRON		AUDIOTRON		340
+h2200			ARCH_H2200		H2200			341
+loox600			ARCH_LOOX600		LOOX600			342
+niop			ARCH_NIOP		NIOP			343
+dm310			ARCH_DM310		DM310			344
+seedpxa_c2		ARCH_SEEDPXA_C2		SEEDPXA_C2		345
+ixp4xx_mguardpci	ARCH_IXP4XX_MGUARD_PCI	IXP4XX_MGUARD_PCI	346
+h1940			ARCH_H1940		H1940			347
diff -urN linux-2.4.22-pre2/arch/cris/config.in linux-2.4.22-pre3/arch/cris/config.in
--- linux-2.4.22-pre2/arch/cris/config.in	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/cris/config.in	2003-07-05 18:09:37.000000000 -0700
@@ -261,5 +261,6 @@
   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
 
+source crypto/Config.in
 source lib/Config.in
 endmenu
diff -urN linux-2.4.22-pre2/arch/i386/config.in linux-2.4.22-pre3/arch/i386/config.in
--- linux-2.4.22-pre2/arch/i386/config.in	2003-07-05 18:09:16.000000000 -0700
+++ linux-2.4.22-pre3/arch/i386/config.in	2003-07-05 18:09:37.000000000 -0700
@@ -478,4 +478,5 @@
 
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -urN linux-2.4.22-pre2/arch/i386/kernel/apm.c linux-2.4.22-pre3/arch/i386/kernel/apm.c
--- linux-2.4.22-pre2/arch/i386/kernel/apm.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/i386/kernel/apm.c	2003-07-05 18:09:37.000000000 -0700
@@ -868,6 +868,8 @@
 		idle_percentage *= 100;
 		idle_percentage /= jiffies_since_last_check;
 		use_apm_idle = (idle_percentage > idle_threshold);
+		if (apm_info.forbid_idle)
+			use_apm_idle = 0;
 		last_jiffies = jiffies;
 		last_stime = current->times.tms_stime;
 	}
diff -urN linux-2.4.22-pre2/arch/i386/kernel/dmi_scan.c linux-2.4.22-pre3/arch/i386/kernel/dmi_scan.c
--- linux-2.4.22-pre2/arch/i386/kernel/dmi_scan.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/i386/kernel/dmi_scan.c	2003-07-05 18:09:37.000000000 -0700
@@ -297,6 +297,32 @@
 	return 0;
 }
 
+static __init int apm_is_horked_d850md(struct dmi_blacklist *d)
+{
+	if (apm_info.disabled == 0)
+	{
+		apm_info.disabled = 1;
+		printk(KERN_ERR "%s machine detected. Disabling APM.\n", d->ident);
+		printk(KERN_ERR "This bug is fixed in bios P15 which is available for \n");
+		printk(KERN_ERR "download from support.intel.com \n");
+	}
+	return 0;
+}
+
+/* 
+ * Some APM bioses hang on APM idle calls
+ */
+
+static __init int apm_likes_to_melt(struct dmi_blacklist *d)
+{
+	if (apm_info.forbid_idle == 0)
+	{
+		apm_info.forbid_idle = 1;
+		printk(KERN_INFO "%s machine detected. Disabling APM idle calls.\n", d->ident);
+	}
+	return 0;
+}
+
 /*
  * Some machines, usually laptops, can't handle an enabled local APIC.
  * The symptoms include hangs or reboots when suspending or resuming,
@@ -415,8 +441,10 @@
  */
  
 extern int skip_ioapic_setup;
+#ifdef CONFIG_PCI
 extern int broken_440gx_bios;
 extern unsigned int pci_probe;
+#endif
 static __init int broken_pirq(struct dmi_blacklist *d)
 {
 	printk(KERN_INFO " *** Possibly defective BIOS detected (irqtable)\n");
@@ -483,6 +511,18 @@
 }
 
 /*
+ *	Exploding PnPBIOS. Don't yet know if its the BIOS or us for
+ *	some entries
+ */
+
+static __init int exploding_pnp_bios(struct dmi_blacklist *d)
+{
+	printk(KERN_WARNING "%s detected. Disabling PnPBIOS\n", d->ident);
+	dmi_broken |= BROKEN_PNP_BIOS;
+	return 0;
+}
+
+/*
  *	Simple "print if true" callback
  */
  
@@ -508,17 +548,47 @@
 			MATCH(DMI_PRODUCT_NAME, "KT7-RAID"),
 			NO_MATCH, NO_MATCH, NO_MATCH
 			} },
+	{ disable_ide_dma, "Dell Inspiron 8100", {	/* Kill DMA on Dell Inspiron 8100 laptops */
+			MATCH(DMI_PRODUCT_NAME, "Inspiron 8100"),
+			MATCH(DMI_SYS_VENDOR,"Dell Computer Corporation"), NO_MATCH, NO_MATCH
+			} },
+
 #endif			
+	/* Dell Laptop hall of shame */
 	{ broken_ps2_resume, "Dell Latitude C600", {	/* Handle problems with APM on the C600 */
 		        MATCH(DMI_SYS_VENDOR, "Dell"),
 			MATCH(DMI_PRODUCT_NAME, "Latitude C600"),
 			NO_MATCH, NO_MATCH
 	                } },
+	{ apm_is_horked, "Dell Inspiron 2500", { /* APM crashes */
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
+			MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
+			MATCH(DMI_BIOS_VERSION,"A11")
+			} },
+	{ apm_is_horked, "Dell Dimension 4100", { /* APM crashes */
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
+			MATCH(DMI_BIOS_VENDOR,"Intel Corp."),
+			MATCH(DMI_BIOS_VERSION,"A11")
+			} },
+	{ set_apm_ints, "Dell Inspiron", {	/* Allow interrupts during suspend on Dell Inspiron laptops*/
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"),
+			NO_MATCH, NO_MATCH
+			} },
+	{ set_apm_ints, "Dell Latitude", {	/* Allow interrupts during suspend on Dell Latitude laptops*/
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Latitude C510"),
+			NO_MATCH, NO_MATCH
+			} },
 	{ broken_apm_power, "Dell Inspiron 5000e", {	/* Handle problems with APM on Inspiron 5000e */
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION, "A04"),
 			MATCH(DMI_BIOS_DATE, "08/24/2000"), NO_MATCH
 			} },
+
+	/* other items */	
 	{ broken_apm_power, "Dell Inspiron 2500", {	/* Handle problems with APM on Inspiron 2500 */
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION, "A12"),
@@ -539,16 +609,11 @@
 			MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
 			NO_MATCH, NO_MATCH
 			} },
-	{ set_bios_reboot, "Dell PowerEdge 2400", {  /* Handle problems with rebooting on Dell 300/800's */
+	{ set_bios_reboot, "Dell PowerEdge 2400", {  /* Handle problems with rebooting on Dell 2400's */
 			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
 			MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
 			NO_MATCH, NO_MATCH
 			} },
-	{ set_apm_ints, "Dell Inspiron", {	/* Allow interrupts during suspend on Dell Inspiron laptops*/
-			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
-			MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"),
-			NO_MATCH, NO_MATCH
-			} },
 	{ set_apm_ints, "Compaq 12XL125", {	/* Allow interrupts during suspend on Compaq Laptops*/
 			MATCH(DMI_SYS_VENDOR, "Compaq"),
 			MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
@@ -570,7 +635,7 @@
 			MATCH(DMI_BIOS_VERSION, "Version1.01"),
 			NO_MATCH, NO_MATCH,
 			} },
-	{ apm_is_horked, "Intel D850MD", { /* APM crashes */
+	{ apm_is_horked_d850md, "Intel D850MD", { /* APM crashes */
 			MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
 			MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"),
 			NO_MATCH, NO_MATCH,
@@ -598,6 +663,22 @@
 			MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION,"A11")
 			} },
+	{ apm_likes_to_melt, "Jabil AMD", { /* APM idle hangs */
+			MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
+			MATCH(DMI_BIOS_VERSION, "0AASNP06"),
+			NO_MATCH, NO_MATCH,
+			} },
+	{ apm_likes_to_melt, "AMI Bios", { /* APM idle hangs */
+			MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
+			MATCH(DMI_BIOS_VERSION, "0AASNP05"), 
+			NO_MATCH, NO_MATCH,
+			} },
+	{ apm_likes_to_melt, "Dell Inspiron 7500", { /* APM idle hangs */
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME,  "Inspiron 7500"), 
+			NO_MATCH, NO_MATCH,
+			} },
+
 	{ sony_vaio_laptop, "Sony Vaio", { /* This is a Sony Vaio laptop */
 			MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 			MATCH(DMI_PRODUCT_NAME, "PCG-"),
@@ -692,6 +773,13 @@
 			NO_MATCH, NO_MATCH
 			} },
 
+	{ exploding_pnp_bios, "Higraded P14H", {	/* BIOSPnP problem */
+			MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
+			MATCH(DMI_BIOS_VERSION, "07.00T"),
+			MATCH(DMI_SYS_VENDOR, "Higraded"),
+			MATCH(DMI_PRODUCT_NAME, "P14H")
+			} },
+
 	/* Machines which have problems handling enabled local APICs */
 
 	{ local_apic_kills_bios, "Dell Inspiron", {
@@ -731,11 +819,26 @@
 			} },
 	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
 			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
+			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0066.P07"),
+			NO_MATCH, NO_MATCH
+                        } },
+	{ broken_pirq, "IBM xseries 370", {        		/* Bad $PIR */
+			MATCH(DMI_BIOS_VENDOR, "IBM"),
+			MATCH(DMI_BIOS_VERSION,"MMKT33AUS"),
+			NO_MATCH, NO_MATCH
+                        } },
+	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
 			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0094.P10"),
 			NO_MATCH, NO_MATCH
                         } },
 	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
 			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
+			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0115.P12"),
+			NO_MATCH, NO_MATCH
+                        } },
+	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
 			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0120.P12"),
 			NO_MATCH, NO_MATCH
                         } },
@@ -746,7 +849,17 @@
 			} },
 	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
 			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0066.P07.9906041405"),
+			MATCH(DMI_BIOS_VERSION,"C440GX0.86B"),
+			NO_MATCH, NO_MATCH
+			} },
+	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
+			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0133.P14"),
+			NO_MATCH, NO_MATCH
+			} },
+	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
+			MATCH(DMI_BIOS_VERSION,"L440GX0"),
 			NO_MATCH, NO_MATCH
 			} },
                         
@@ -774,7 +887,6 @@
 			MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"),
 			MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736")
 			} },
- 
 
 	/*
 	 *	Generic per vendor APM settings
diff -urN linux-2.4.22-pre2/arch/i386/kernel/io_apic.c linux-2.4.22-pre3/arch/i386/kernel/io_apic.c
--- linux-2.4.22-pre2/arch/i386/kernel/io_apic.c	2003-07-05 18:09:16.000000000 -0700
+++ linux-2.4.22-pre3/arch/i386/kernel/io_apic.c	2003-07-05 18:09:37.000000000 -0700
@@ -125,7 +125,7 @@
 			break;						\
 		reg = io_apic_read(entry->apic, 0x10 + R + pin*2);	\
 		reg ACTION;						\
-		io_apic_modify(entry->apic, reg);			\
+		io_apic_write(entry->apic, 0x10 + R + pin*2, reg);	\
 		if (!entry->next)					\
 			break;						\
 		entry = irq_2_pin + entry->next;			\
diff -urN linux-2.4.22-pre2/arch/i386/kernel/pci-irq.c linux-2.4.22-pre3/arch/i386/kernel/pci-irq.c
--- linux-2.4.22-pre2/arch/i386/kernel/pci-irq.c	2003-07-05 18:09:16.000000000 -0700
+++ linux-2.4.22-pre3/arch/i386/kernel/pci-irq.c	2003-07-05 18:09:37.000000000 -0700
@@ -196,15 +196,16 @@
 /*
  * The VIA pirq rules are nibble-based, like ALI,
  * but without the ugly irq number munging.
+ * However, PIRQD is in the upper instead of lower nibble.
  */
 static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
 {
-	return read_config_nybble(router, 0x55, pirq);
+	return read_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq);
 }
 
 static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
 {
-	write_config_nybble(router, 0x55, pirq, irq);
+	write_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq, irq);
 	return 1;
 }
 
diff -urN linux-2.4.22-pre2/arch/i386/kernel/process.c linux-2.4.22-pre3/arch/i386/kernel/process.c
--- linux-2.4.22-pre2/arch/i386/kernel/process.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/i386/kernel/process.c	2003-07-05 18:09:37.000000000 -0700
@@ -253,7 +253,7 @@
 	0x66, 0x0f, 0x20, 0xc3,			/*    movl  %cr0,%ebx        */
 	0x66, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x60,	/*    andl  $0x60000000,%ebx */
 	0x74, 0x02,				/*    jz    f                */
-	0x0f, 0x08,				/*    invd                   */
+	0x0f, 0x09,				/*    wbinvd                 */
 	0x24, 0x10,				/* f: andb  $0x10,al         */
 	0x66, 0x0f, 0x22, 0xc0			/*    movl  %eax,%cr0        */
 };
diff -urN linux-2.4.22-pre2/arch/i386/kernel/sys_i386.c linux-2.4.22-pre3/arch/i386/kernel/sys_i386.c
--- linux-2.4.22-pre2/arch/i386/kernel/sys_i386.c	2001-03-19 12:35:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/i386/kernel/sys_i386.c	2003-07-05 18:09:37.000000000 -0700
@@ -139,7 +139,10 @@
 
 	switch (call) {
 	case SEMOP:
-		return sys_semop (first, (struct sembuf *)ptr, second);
+		return sys_semtimedop (first, (struct sembuf *)ptr, second, NULL);
+	case SEMTIMEDOP:
+		return sys_semtimedop (first, (struct sembuf *)ptr, second, 
+				       (const struct timespec *)fifth);
 	case SEMGET:
 		return sys_semget (first, second, third);
 	case SEMCTL: {
@@ -200,7 +203,7 @@
 		return sys_shmctl (first, second,
 				   (struct shmid_ds *) ptr);
 	default:
-		return -EINVAL;
+		return -ENOSYS;
 	}
 }
 
diff -urN linux-2.4.22-pre2/arch/i386/kernel/vm86.c linux-2.4.22-pre3/arch/i386/kernel/vm86.c
--- linux-2.4.22-pre2/arch/i386/kernel/vm86.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/i386/kernel/vm86.c	2003-07-05 18:09:37.000000000 -0700
@@ -362,6 +362,9 @@
 
 	if (VEFLAGS & VIF_MASK)
 		flags |= IF_MASK;
+	else
+		flags &= ~IF_MASK;
+	flags |= IOPL_MASK;
 	return flags | (VEFLAGS & current->thread.v86mask);
 }
 
diff -urN linux-2.4.22-pre2/arch/i386/math-emu/fpu_trig.c linux-2.4.22-pre3/arch/i386/math-emu/fpu_trig.c
--- linux-2.4.22-pre2/arch/i386/math-emu/fpu_trig.c	2001-06-12 11:06:54.000000000 -0700
+++ linux-2.4.22-pre3/arch/i386/math-emu/fpu_trig.c	2003-07-05 18:09:37.000000000 -0700
@@ -1058,7 +1058,7 @@
 	return;
       goto fprem_valid;
     }
-  else if ( (st0_tag == TAG_Empty) | (st1_tag == TAG_Empty) )
+  else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
     {
       FPU_stack_underflow();
       return;
diff -urN linux-2.4.22-pre2/arch/i386/math-emu/poly.h linux-2.4.22-pre3/arch/i386/math-emu/poly.h
--- linux-2.4.22-pre2/arch/i386/math-emu/poly.h	2001-07-26 13:37:38.000000000 -0700
+++ linux-2.4.22-pre3/arch/i386/math-emu/poly.h	2003-07-05 18:09:37.000000000 -0700
@@ -64,7 +64,7 @@
 				      const unsigned long arg2)
 {
   int retval;
-  asm volatile ("mull %2; movl %%edx,%%eax" \
+  asm volatile ("mull %2; movl %%edx,%%eax; " \
 		:"=a" (retval) \
 		:"0" (arg1), "g" (arg2) \
 		:"dx");
@@ -75,11 +75,11 @@
 /* Add the 12 byte Xsig x2 to Xsig dest, with no checks for overflow. */
 static inline void add_Xsig_Xsig(Xsig *dest, const Xsig *x2)
 {
-  asm volatile ("movl %1,%%edi; movl %2,%%esi;
-                 movl (%%esi),%%eax; addl %%eax,(%%edi);
-                 movl 4(%%esi),%%eax; adcl %%eax,4(%%edi);
-                 movl 8(%%esi),%%eax; adcl %%eax,8(%%edi);"
-                 :"=g" (*dest):"g" (dest), "g" (x2)
+  asm volatile ("movl %1,%%edi; movl %2,%%esi; " \
+                 "movl (%%esi),%%eax; addl %%eax,(%%edi); " \
+                 "movl 4(%%esi),%%eax; adcl %%eax,4(%%edi); " \
+                 "movl 8(%%esi),%%eax; adcl %%eax,8(%%edi); " \
+                 :"=g" (*dest):"g" (dest), "g" (x2) \
                  :"ax","si","di");
 }
 
@@ -90,19 +90,19 @@
    problem, but keep fingers crossed! */
 static inline void add_two_Xsig(Xsig *dest, const Xsig *x2, long int *exp)
 {
-  asm volatile ("movl %2,%%ecx; movl %3,%%esi;
-                 movl (%%esi),%%eax; addl %%eax,(%%ecx);
-                 movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx);
-                 movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx);
-                 jnc 0f;
-		 rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx)
-                 movl %4,%%ecx; incl (%%ecx)
-                 movl $1,%%eax; jmp 1f;
-                 0: xorl %%eax,%%eax;
-                 1:"
-		:"=g" (*exp), "=g" (*dest)
-		:"g" (dest), "g" (x2), "g" (exp)
-		:"cx","si","ax");
+  asm volatile ("movl %2,%%ecx; movl %3,%%esi; " \
+                 "movl (%%esi),%%eax; addl %%eax,(%%ecx); " \
+                 "movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx); " \
+                 "movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx); " \
+                 "jnc 0f; " \
+		 "rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx); " \
+                 "movl %4,%%ecx; incl (%%ecx); " \
+                 "movl $1,%%eax; jmp 1f; " \
+                 "0: xorl %%eax,%%eax; " \
+                 "1: " \
+		:"=g" (*exp), "=g" (*dest) \
+		:"g" (dest), "g" (x2), "g" (exp) \
+		:"cx","si","ax"); 
 }
 
 
@@ -110,11 +110,11 @@
 /* This is faster in a loop on my 386 than using the "neg" instruction. */
 static inline void negate_Xsig(Xsig *x)
 {
-  asm volatile("movl %1,%%esi; "
-               "xorl %%ecx,%%ecx; "
-               "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi); "
-               "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi); "
-               "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi); "
+  asm volatile("movl %1,%%esi; " \
+               "xorl %%ecx,%%ecx; " \
+               "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi); " \
+               "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi); " \
+               "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi); " \
                :"=g" (*x):"g" (x):"si","ax","cx");
 }
 
diff -urN linux-2.4.22-pre2/arch/ia64/Makefile linux-2.4.22-pre3/arch/ia64/Makefile
--- linux-2.4.22-pre2/arch/ia64/Makefile	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/Makefile	2003-07-05 18:09:37.000000000 -0700
@@ -132,6 +132,9 @@
 archclean:
 	@$(MAKEBOOT) clean
 
+check: vmlinux
+	arch/ia64/scripts/unwcheck.sh vmlinux
+
 archmrproper:
 	rm -f arch/$(ARCH)/vmlinux.lds
 	@$(MAKE) -C arch/$(ARCH)/tools mrproper
diff -urN linux-2.4.22-pre2/arch/ia64/config.in linux-2.4.22-pre3/arch/ia64/config.in
--- linux-2.4.22-pre2/arch/ia64/config.in	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/config.in	2003-07-05 18:09:37.000000000 -0700
@@ -23,8 +23,8 @@
 define_bool CONFIG_EISA n
 define_bool CONFIG_MCA n
 define_bool CONFIG_SBUS n
-define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
-define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
 
 choice 'IA-64 processor type' \
 	"Itanium		CONFIG_ITANIUM \
@@ -242,6 +242,7 @@
 
   source drivers/usb/Config.in
 
+  source crypto/Config.in
   source lib/Config.in
 
   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
diff -urN linux-2.4.22-pre2/arch/ia64/configs/dig linux-2.4.22-pre3/arch/ia64/configs/dig
--- linux-2.4.22-pre2/arch/ia64/configs/dig	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/configs/dig	2003-07-05 18:09:37.000000000 -0700
@@ -22,8 +22,8 @@
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ITANIUM=y
 # CONFIG_MCKINLEY is not set
 # CONFIG_IA64_GENERIC is not set
@@ -41,6 +41,14 @@
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
+CONFIG_FORCE_MAX_ZONEORDER=19
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_16MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -243,7 +251,7 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
@@ -257,7 +265,6 @@
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -322,6 +329,7 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -623,6 +631,7 @@
 #
 # Video Adapters
 #
+# CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5249 is not set
@@ -672,6 +681,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -874,6 +884,7 @@
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 
 #
diff -urN linux-2.4.22-pre2/arch/ia64/configs/generic linux-2.4.22-pre3/arch/ia64/configs/generic
--- linux-2.4.22-pre2/arch/ia64/configs/generic	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/configs/generic	2003-07-05 18:09:37.000000000 -0700
@@ -22,8 +22,8 @@
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ITANIUM=y
 # CONFIG_MCKINLEY is not set
 CONFIG_IA64_GENERIC=y
@@ -41,6 +41,14 @@
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
+CONFIG_FORCE_MAX_ZONEORDER=19
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_16MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -243,13 +251,13 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
-# CONFIG_BLK_DEV_CMD64X is not set
+CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
@@ -257,7 +265,6 @@
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -322,6 +329,7 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -628,6 +636,7 @@
 #
 # Video Adapters
 #
+# CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5249 is not set
@@ -677,6 +686,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -879,6 +889,7 @@
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 
 #
diff -urN linux-2.4.22-pre2/arch/ia64/configs/ski linux-2.4.22-pre3/arch/ia64/configs/ski
--- linux-2.4.22-pre2/arch/ia64/configs/ski	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/configs/ski	2003-07-05 18:09:37.000000000 -0700
@@ -22,8 +22,8 @@
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ITANIUM=y
 # CONFIG_MCKINLEY is not set
 # CONFIG_IA64_GENERIC is not set
@@ -39,6 +39,14 @@
 # CONFIG_ITANIUM_BSTEP_SPECIFIC is not set
 CONFIG_IA64_L1_CACHE_SHIFT=6
 CONFIG_KCORE_ELF=y
+CONFIG_FORCE_MAX_ZONEORDER=19
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_16MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -149,6 +157,7 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -274,6 +283,7 @@
 #
 # Video Adapters
 #
+# CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_BWQCAM is not set
 # CONFIG_VIDEO_CQCAM is not set
@@ -326,6 +336,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
diff -urN linux-2.4.22-pre2/arch/ia64/configs/zx1 linux-2.4.22-pre3/arch/ia64/configs/zx1
--- linux-2.4.22-pre2/arch/ia64/configs/zx1	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/configs/zx1	2003-07-05 18:09:37.000000000 -0700
@@ -22,8 +22,8 @@
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 # CONFIG_ITANIUM is not set
 CONFIG_MCKINLEY=y
 # CONFIG_IA64_GENERIC is not set
@@ -40,6 +40,16 @@
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
+CONFIG_FORCE_MAX_ZONEORDER=19
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_4GB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1GB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_16MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -242,7 +252,7 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
@@ -256,7 +266,6 @@
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -321,6 +330,7 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -622,6 +632,7 @@
 #
 # Video Adapters
 #
+# CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5249 is not set
@@ -671,6 +682,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -873,6 +885,7 @@
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 
 #
diff -urN linux-2.4.22-pre2/arch/ia64/defconfig linux-2.4.22-pre3/arch/ia64/defconfig
--- linux-2.4.22-pre2/arch/ia64/defconfig	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/defconfig	2003-07-05 18:09:37.000000000 -0700
@@ -22,8 +22,8 @@
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ITANIUM=y
 # CONFIG_MCKINLEY is not set
 CONFIG_IA64_GENERIC=y
@@ -41,6 +41,14 @@
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
+CONFIG_FORCE_MAX_ZONEORDER=19
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_16MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -243,13 +251,13 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
-# CONFIG_BLK_DEV_CMD64X is not set
+CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
@@ -257,7 +265,6 @@
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -322,6 +329,7 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -628,6 +636,7 @@
 #
 # Video Adapters
 #
+# CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5249 is not set
@@ -677,6 +686,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -879,6 +889,7 @@
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 
 #
diff -urN linux-2.4.22-pre2/arch/ia64/dig/machvec.c linux-2.4.22-pre3/arch/ia64/dig/machvec.c
--- linux-2.4.22-pre2/arch/ia64/dig/machvec.c	2000-08-11 19:09:06.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/dig/machvec.c	2003-07-05 18:09:37.000000000 -0700
@@ -1,2 +1,3 @@
-#define MACHVEC_PLATFORM_NAME	dig
+#define MACHVEC_PLATFORM_NAME		dig
+#define MACHVEC_PLATFORM_HEADER		<asm/machvec_dig.h>
 #include <asm/machvec_init.h>
diff -urN linux-2.4.22-pre2/arch/ia64/dig/setup.c linux-2.4.22-pre3/arch/ia64/dig/setup.c
--- linux-2.4.22-pre2/arch/ia64/dig/setup.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/dig/setup.c	2003-07-05 18:09:37.000000000 -0700
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1999 Intel Corp.
  * Copyright (C) 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999, 2001, 2003 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
@@ -56,7 +56,7 @@
 	if (!ia64_boot_param->console_info.num_rows
 	    || !ia64_boot_param->console_info.num_cols)
 	{
-		printk("dig_setup: warning: invalid screen-info, guessing 80x25\n");
+		printk(KERN_WARNING "dig_setup: warning: invalid screen-info, guessing 80x25\n");
 		orig_x = 0;
 		orig_y = 0;
 		num_cols = 80;
diff -urN linux-2.4.22-pre2/arch/ia64/hp/common/sba_iommu.c linux-2.4.22-pre3/arch/ia64/hp/common/sba_iommu.c
--- linux-2.4.22-pre2/arch/ia64/hp/common/sba_iommu.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/hp/common/sba_iommu.c	2003-07-05 18:09:37.000000000 -0700
@@ -1,8 +1,9 @@
 /*
 **  IA64 System Bus Adapter (SBA) I/O MMU manager
 **
-**	(c) Copyright 2002 Alex Williamson
-**	(c) Copyright 2002 Hewlett-Packard Company
+**	(c) Copyright 2002-2003 Alex Williamson
+**	(c) Copyright 2002-2003 Grant Grundler
+**	(c) Copyright 2002-2003 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)
@@ -29,12 +30,14 @@
 #include <linux/string.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.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 */
+#include <asm/system.h>		/* wmb() */
 
 
 #define PFX "IOC: "
@@ -206,7 +209,7 @@
 	/* 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;
+	char		*name;
 	unsigned int	func_id;
 	unsigned int	rev;		/* HW revision of chip */
 	u32		iov_size;
@@ -217,11 +220,15 @@
 static struct ioc *ioc_list;
 static int reserve_sba_gart = 1;
 
-#define sba_sg_address(sg)	(sg->address ? sg->address : \
-				       page_address((sg)->page) + (sg)->offset)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define sba_sg_address(sg)	(page_address((sg)->page) + (sg)->offset)
+#else
+#define sba_sg_address(sg)	((sg)->address ? (sg)->address : \
+                                  page_address((sg)->page) + (sg)->offset)
+#endif
 
 #ifdef FULL_VALID_PDIR
-static void* prefetch_spill_page;
+static u64 prefetch_spill_page;
 #endif
 
 #define GET_IOC(dev)	((struct ioc *) PCI_CONTROLLER(dev)->iommu)
@@ -282,24 +289,23 @@
 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)]);
+	u64 *ptr = &ioc->pdir_base[pide  & ~(BITS_PER_LONG - 1)];
+	unsigned long *rptr = (unsigned long *) &ioc->res_map[(pide >>3) & -sizeof(unsigned long)];
 	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",
+	printk(KERN_DEBUG "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 );
+		printk(KERN_DEBUG "%s %2d %p %016Lx\n",
+		       (rcnt == (pide & (BITS_PER_LONG - 1)))
+		       ? "    -->" : "       ",
+		       rcnt, ptr, (unsigned long long) *ptr );
 		rcnt++;
 		ptr++;
 	}
-	printk("%s", msg);
+	printk(KERN_DEBUG "%s", msg);
 }
 
 
@@ -361,12 +367,13 @@
 sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
 {
 	while (nents-- > 0) {
-		printk(" %d : %08lx/%05x %p\n",
-				nents, startsg->dma_address,
-				startsg->dma_length, sba_sg_address(startsg));
+		printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents,
+		       startsg->dma_address, startsg->dma_length,
+		       sba_sg_address(startsg));
 		startsg++;
 	}
 }
+
 static void
 sba_check_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
 {
@@ -397,7 +404,8 @@
 #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_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 */
@@ -520,7 +528,8 @@
 	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);
+			panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n",
+			      ioc->ioc_hpa);
 	}
 
 #ifdef ASSERT_PDIR_SANITY
@@ -625,7 +634,8 @@
  */
 
 #if 1
-#define sba_io_pdir_entry(pdir_ptr, vba) *pdir_ptr = ((vba & ~0xE000000000000FFFULL) | 0x8000000000000000ULL)
+#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)
@@ -709,7 +719,7 @@
 		** the spill page so devices prefetching won't
 		** cause a hard fail.
 		*/
-		ioc->pdir_base[off] = (0x80000000000000FFULL | (u64)prefetch_spill_page);
+		ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page);
 #endif
 	} else {
 		u32 t = get_order(byte_cnt) + PAGE_SHIFT;
@@ -724,7 +734,7 @@
 			/* clear I/O Pdir entry "valid" bit first */
 			ioc->pdir_base[off] &= ~(0x80000000000000FFULL);
 #else
-			ioc->pdir_base[off] = (0x80000000000000FFULL | (u64)prefetch_spill_page);
+			ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page);
 #endif
 			off++;
 			byte_cnt -= IOVP_SIZE;
@@ -747,7 +757,7 @@
 sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
 {
 	struct ioc *ioc;
-	unsigned long flags; 
+	unsigned long flags;
 	dma_addr_t iovp;
 	dma_addr_t offset;
 	u64 *pdir_start;
@@ -816,6 +826,9 @@
 		size -= IOVP_SIZE;
 		pdir_start++;
 	}
+	/* force pdir update */
+	wmb();
+
 	/* form complete address */
 #ifdef ASSERT_PDIR_SANITY
 	sba_check_pdir(ioc,"Check after sba_map_single()");
@@ -840,7 +853,7 @@
 #if DELAYED_RESOURCE_CNT > 0
 	struct sba_dma_pair *d;
 #endif
-	unsigned long flags; 
+	unsigned long flags;
 	dma_addr_t offset;
 
 	ioc = GET_IOC(dev);
@@ -932,7 +945,7 @@
 	** 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");	
+	asm volatile("syncdma");
 	*/
 }
 
@@ -1078,6 +1091,9 @@
 		}
 		startsg++;
 	}
+	/* force pdir update */
+	wmb();
+
 #ifdef DEBUG_LARGE_SG_ENTRIES
 	dump_run_sg = 0;
 #endif
@@ -1122,7 +1138,7 @@
 	int n_mappings = 0;
 
 	while (nents > 0) {
-		unsigned long vaddr = (unsigned long) sba_sg_address(startsg); 
+		unsigned long vaddr = (unsigned long) sba_sg_address(startsg);
 
 		/*
 		** Prepare for first/next DMA stream
@@ -1155,7 +1171,8 @@
 			** exceed DMA_CHUNK_SIZE if we coalesce the
 			** next entry.
 			*/
-			if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK) > DMA_CHUNK_SIZE)
+			if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK)
+			    > DMA_CHUNK_SIZE)
 				break;
 
 			/*
@@ -1214,7 +1231,7 @@
 		vcontig_sg->dma_length = vcontig_len;
 		dma_len = (dma_len + dma_offset + ~IOVP_MASK) & IOVP_MASK;
 		ASSERT(dma_len <= DMA_CHUNK_SIZE);
-		dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG 
+		dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG
 			| (sba_alloc_range(ioc, dma_len) << IOVP_SHIFT)
 			| dma_offset);
 		n_mappings++;
@@ -1233,8 +1250,7 @@
  *
  * See Documentation/DMA-mapping.txt
  */
-int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents,
-		int direction)
+int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
 {
 	struct ioc *ioc;
 	int coalesced, filled = 0;
@@ -1299,13 +1315,13 @@
 	** 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 dma_len will contain the number of bytes to map
 	** o address contains the virtual address.
 	*/
 	filled = sba_fill_pdir(ioc, sglist, nents);
@@ -1371,7 +1387,8 @@
 		** were coalesced to a single entry.  The stats are fun,
 		** but speed is more important.
 		*/
-		ioc->usg_pages += ((sglist->dma_address & ~IOVP_MASK) + sglist->dma_length + IOVP_SIZE - 1) >> PAGE_SHIFT;
+		ioc->usg_pages += ((sglist->dma_address & ~IOVP_MASK) + sglist->dma_length
+				   + IOVP_SIZE - 1) >> PAGE_SHIFT;
 #endif
 		sglist++;
 		nents--;
@@ -1387,12 +1404,6 @@
 
 }
 
-int
-sba_dma_supported (struct pci_dev *dev, u64 mask)
-{
-	return 1;
-}
-
 /**************************************************************
 *
 *   Initialization and claim
@@ -1418,19 +1429,6 @@
 	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.
@@ -1438,9 +1436,9 @@
 	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);
+	DBG_INIT("%s() hpa %p IOV %dMB (%d bits) PDIR size 0x%x\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;
@@ -1520,7 +1518,8 @@
 		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__);
+		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;
 	}
@@ -1532,26 +1531,27 @@
 	if (!prefetch_spill_page) {
 		char *spill_poison = "SBAIOMMU POISON";
 		int poison_size = 16;
-		void *poison_addr;
-									
-		prefetch_spill_page = (void *)__get_free_pages(GFP_KERNEL, get_order(IOVP_SIZE));
-		if (!prefetch_spill_page)
+		void *poison_addr, *addr;
+
+		addr = (void *)__get_free_pages(GFP_KERNEL, get_order(IOVP_SIZE));
+		if (!addr)
 			panic(PFX "Couldn't allocate PDIR spill page\n");
 
-		poison_addr = prefetch_spill_page;
-		for (; (u64)poison_addr < (u64)prefetch_spill_page + IOVP_SIZE ; poison_addr += poison_size)
-			(void)memcpy(poison_addr,spill_poison,poison_size);
+		poison_addr = addr;
+		for ( ; (u64) poison_addr < addr + IOVP_SIZE; poison_addr += poison_size)
+			memcpy(poison_addr, spill_poison, poison_size);
 
-		prefetch_spill_page = (void *)virt_to_phys(prefetch_spill_page);
+		prefetch_spill_page = virt_to_phys(addr);
 
-		DBG_INIT("%s() prefetch spill addr: %p\n", __FUNCTION__, prefetch_spill_page);
+		DBG_INIT("%s() prefetch spill addr: 0x%lx\n", __FUNCTION__, prefetch_spill_page);
 	}
 	/*
   	** Set all the PDIR entries valid w/ the spill page as the target
 	*/
 	for (index = 0 ; index < (ioc->pdir_size / sizeof(u64)) ; index++)
-		((u64 *)ioc->pdir_base)[index] = (0x80000000000000FFULL | (u64)prefetch_spill_page);
+		((u64 *)ioc->pdir_base)[index] = (0x80000000000000FF | prefetch_spill_page);
 #endif
+
 }
 
 static void __init
@@ -1581,7 +1581,8 @@
 #ifdef FULL_VALID_PDIR
 	/* Mark the last resource used so we don't prefetch beyond IOVA space */
 	ioc->res_map[ioc->res_size - 1] |= 0x80UL; /* res_map is chars */
-	ioc->pdir_base[(ioc->pdir_size / sizeof(u64)) - 1] = (0x80000000000000FFULL | (u64)prefetch_spill_page);
+	ioc->pdir_base[(ioc->pdir_size / sizeof(u64)) - 1] = (0x80000000000000FF
+							      | prefetch_spill_page);
 #endif
 
 	DBG_INIT("%s() res_map %x %p\n", __FUNCTION__,
@@ -1701,25 +1702,52 @@
 **************************************************************************/
 
 #ifdef CONFIG_PROC_FS
+static void *
+ioc_start(struct seq_file *s, loff_t *pos)
+{
+	struct ioc *ioc;
+	loff_t n = *pos;
+
+	for (ioc = ioc_list; ioc; ioc = ioc->next)
+		if (!n--)
+			return ioc;
+
+	return NULL;
+}
+
+static void *
+ioc_next(struct seq_file *s, void *v, loff_t *pos)
+{
+	struct ioc *ioc = v;
+
+	++*pos;
+	return ioc->next;
+}
+
+static void
+ioc_stop(struct seq_file *s, void *v)
+{
+}
+
 static int
-sba_proc_info_one(char *buf, struct ioc *ioc)
+ioc_show(struct seq_file *s, void *v)
 {
+	struct ioc *ioc = v;
 	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",
+	seq_printf(s, "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,
+	seq_printf(s, "IO PDIR size    : %d bytes (%d entries)\n",
 		(int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */
 		total_pages);
 
-	sprintf(buf, "%sIO PDIR entries : %ld free  %ld used (%d%%)\n", buf,
+	seq_printf(s, "IO PDIR entries : %ld free  %ld used (%d%%)\n",
 		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 */
+
+	seq_printf(s, "Resource bitmap : %d bytes (%d pages)\n",
+		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++) {
@@ -1728,81 +1756,106 @@
 		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);
+	seq_printf(s, "  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
+		min, avg, max);
 
-	sprintf(buf, "%spci_map_single(): %12ld calls  %12ld pages (avg %d/1000)\n",
-		buf, ioc->msingle_calls, ioc->msingle_pages,
+	seq_printf(s, "pci_map_single(): %12ld calls  %12ld pages (avg %d/1000)\n",
+		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);
+	seq_printf(s, "pci_map_single(): %12ld bypasses\n", ioc->msingle_bypass);
 #endif
 
-	sprintf(buf, "%spci_unmap_single: %12ld calls  %12ld pages (avg %d/1000)\n",
-		buf, ioc->usingle_calls, ioc->usingle_pages,
+	seq_printf(s, "pci_unmap_single: %12ld calls  %12ld pages (avg %d/1000)\n",
+		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);
+	seq_printf(s, "pci_unmap_single: %12ld bypasses\n", ioc->usingle_bypass);
 #endif
 
-	sprintf(buf, "%spci_map_sg()    : %12ld calls  %12ld pages (avg %d/1000)\n",
-		buf, ioc->msg_calls, ioc->msg_pages,
+	seq_printf(s, "pci_map_sg()    : %12ld calls  %12ld pages (avg %d/1000)\n",
+		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);
+	seq_printf(s, "pci_map_sg()    : %12ld bypasses\n", ioc->msg_bypass);
 #endif
 
-	sprintf(buf, "%spci_unmap_sg()  : %12ld calls  %12ld pages (avg %d/1000)\n",
-		buf, ioc->usg_calls, ioc->usg_pages,
+	seq_printf(s, "pci_unmap_sg()  : %12ld calls  %12ld pages (avg %d/1000)\n",
+		ioc->usg_calls, ioc->usg_pages,
 		(int) ((ioc->usg_pages * 1000)/ioc->usg_calls));
 
-	return strlen(buf);
+	return 0;
 }
 
+static struct seq_operations ioc_seq_ops = {
+	.start = ioc_start,
+	.next  = ioc_next,
+	.stop  = ioc_stop,
+	.show  = ioc_show
+};
+
 static int
-sba_proc_info(char *buf, char **start, off_t offset, int len)
+ioc_open(struct inode *inode, struct file *file)
 {
-	struct ioc *ioc;
-	char *base = buf;
-
-	for (ioc = ioc_list; ioc; ioc = ioc->next) {
-		buf += sba_proc_info_one(buf, ioc);
-	}
-
-	return strlen(base);
+	return seq_open(file, &ioc_seq_ops);
 }
 
+static struct file_operations ioc_fops = {
+	.open    = ioc_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release
+};
+
 static int
-sba_resource_map_one(char *buf, struct ioc *ioc)
+ioc_map_show(struct seq_file *s, void *v)
 {
+	struct ioc *ioc = v;
 	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");
+	for (i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr)
+		seq_printf(s, "%s%08x", (i & 7) ? " " : "\n    ", *res_ptr);
+	seq_printf(s, "\n");
 
-	return strlen(buf);
+	return 0;
 }
 
+static struct seq_operations ioc_map_ops = {
+	.start = ioc_start,
+	.next  = ioc_next,
+	.stop  = ioc_stop,
+	.show  = ioc_map_show
+};
+
 static int
-sba_resource_map(char *buf, char **start, off_t offset, int len)
+ioc_map_open(struct inode *inode, struct file *file)
 {
-	struct ioc *ioc;
-	char *base = buf;
+	return seq_open(file, &ioc_map_ops);
+}
 
-	for (ioc = ioc_list; ioc; ioc = ioc->next) {
-		buf += sba_resource_map_one(buf, ioc);
-	}
+static struct file_operations ioc_map_fops = {
+	.open    = ioc_map_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release
+};
 
-	return strlen(base);
+static void __init
+ioc_proc_init(void)
+{
+	if (ioc_list) {
+		struct proc_dir_entry *dir, *entry;
+
+		dir = proc_mkdir("bus/mckinley", 0);
+		entry = create_proc_entry(ioc_list->name, 0, dir);
+		if (entry)
+			entry->proc_fops = &ioc_fops;
+
+		entry = create_proc_entry("bitmap", 0, dir);
+		if (entry)
+			entry->proc_fops = &ioc_map_fops;
+	}
 }
 #endif
 
@@ -1833,7 +1886,7 @@
 		handle = parent;
 	} while (ACPI_SUCCESS(status));
 
-	printk("No IOC for %s in ACPI\n", dev->slot_name);
+	printk(KERN_WARNING "No IOC for %s in ACPI\n", dev->slot_name);
 }
 
 static int __init
@@ -1842,31 +1895,23 @@
 	struct ioc *ioc;
 	acpi_status status;
 	u64 hpa, length;
+	acpi_device_info dev_info;
 
-	/*
-	 * 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);
+	status = acpi_get_object_info(device->handle, &dev_info);
 	if (ACPI_FAILURE(status))
 		return 1;
+
+	/*
+	 * For HWP0001, only SBA appears in ACPI namespace.  It encloses the PCI
+	 * root bridges, and its CSR space includes the IOC function.
+	 */
+	if (strncmp("HWP0001", dev_info.hardware_id, 7) == 0)
+		hpa += ZX1_IOC_OFFSET;
+
 	ioc = ioc_init(hpa, device->handle);
 	if (!ioc)
 		return 1;
@@ -1876,40 +1921,19 @@
 
 static struct acpi_driver acpi_sba_ioc_driver = {
 	name:		"IOC IOMMU Driver",
-	ids:		"HWP0001",
+	ids:		"HWP0001,HWP0004",
 	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();
+	acpi_bus_register_driver(&acpi_sba_ioc_driver);
 
 #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);
-	}
+	ioc_proc_init();
 #endif
 }
 
@@ -1920,6 +1944,13 @@
 	return 1;
 }
 
+int
+sba_dma_supported (struct pci_dev *dev, u64 mask)
+{
+	/* make sure it's at least 32bit capable */
+	return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL);
+}
+
 __setup("nosbagart", nosbagart);
 
 EXPORT_SYMBOL(sba_init);
diff -urN linux-2.4.22-pre2/arch/ia64/hp/sim/hpsim_console.c linux-2.4.22-pre3/arch/ia64/hp/sim/hpsim_console.c
--- linux-2.4.22-pre2/arch/ia64/hp/sim/hpsim_console.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/hp/sim/hpsim_console.c	2003-07-05 18:09:37.000000000 -0700
@@ -28,12 +28,12 @@
 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,
+	.name =		"simcons",
+	.write =	simcons_write,
+	.device =	simcons_console_device,
+	.setup =	simcons_init,
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
 };
 
 static int
diff -urN linux-2.4.22-pre2/arch/ia64/hp/sim/hpsim_irq.c linux-2.4.22-pre3/arch/ia64/hp/sim/hpsim_irq.c
--- linux-2.4.22-pre2/arch/ia64/hp/sim/hpsim_irq.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/hp/sim/hpsim_irq.c	2003-07-05 18:09:37.000000000 -0700
@@ -22,14 +22,14 @@
 }
 
 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,
+	.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
diff -urN linux-2.4.22-pre2/arch/ia64/hp/sim/hpsim_machvec.c linux-2.4.22-pre3/arch/ia64/hp/sim/hpsim_machvec.c
--- linux-2.4.22-pre2/arch/ia64/hp/sim/hpsim_machvec.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/hp/sim/hpsim_machvec.c	2003-07-05 18:09:37.000000000 -0700
@@ -1,2 +1,3 @@
-#define MACHVEC_PLATFORM_NAME	hpsim
+#define MACHVEC_PLATFORM_NAME		hpsim
+#define MACHVEC_PLATFORM_HEADER		<asm/machvec_hpsim.h>
 #include <asm/machvec_init.h>
diff -urN linux-2.4.22-pre2/arch/ia64/hp/zx1/hpzx1_machvec.c linux-2.4.22-pre3/arch/ia64/hp/zx1/hpzx1_machvec.c
--- linux-2.4.22-pre2/arch/ia64/hp/zx1/hpzx1_machvec.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/hp/zx1/hpzx1_machvec.c	2003-07-05 18:09:37.000000000 -0700
@@ -1,2 +1,3 @@
-#define MACHVEC_PLATFORM_NAME	hpzx1
+#define MACHVEC_PLATFORM_NAME		hpzx1
+#define MACHVEC_PLATFORM_HEADER		<asm/machvec_hpzx1.h>
 #include <asm/machvec_init.h>
diff -urN linux-2.4.22-pre2/arch/ia64/ia32/binfmt_elf32.c linux-2.4.22-pre3/arch/ia64/ia32/binfmt_elf32.c
--- linux-2.4.22-pre2/arch/ia64/ia32/binfmt_elf32.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/ia32/binfmt_elf32.c	2003-07-05 18:09:37.000000000 -0700
@@ -67,7 +67,7 @@
 }
 
 static struct vm_operations_struct ia32_shared_page_vm_ops = {
-	nopage:	ia32_install_shared_page
+	.nopage =ia32_install_shared_page
 };
 
 void
diff -urN linux-2.4.22-pre2/arch/ia64/ia32/ia32_entry.S linux-2.4.22-pre3/arch/ia64/ia32/ia32_entry.S
--- linux-2.4.22-pre2/arch/ia64/ia32/ia32_entry.S	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/ia32/ia32_entry.S	2003-07-05 18:09:37.000000000 -0700
@@ -87,12 +87,19 @@
 
 GLOBAL_ENTRY(ia32_ret_from_clone)
 	PT_REGS_UNWIND_INFO(0)
+{	/*
+	 * Some versions of gas generate bad unwind info if the first instruction of a
+	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
+	 */
+	nop.m 0
+	nop.i 0
 	/*
 	 * We need to call schedule_tail() to complete the scheduling process.
 	 * Called by ia64_switch_to after do_fork()->copy_thread().  r8 contains the
 	 * address of the previously executing task.
 	 */
 	br.call.sptk.many rp=ia64_invoke_schedule_tail
+}
 .ret1:	adds r2=IA64_TASK_PTRACE_OFFSET,r13
 	;;
 	ld8 r2=[r2]
diff -urN linux-2.4.22-pre2/arch/ia64/ia32/ia32_ioctl.c linux-2.4.22-pre3/arch/ia64/ia32/ia32_ioctl.c
--- linux-2.4.22-pre2/arch/ia64/ia32/ia32_ioctl.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/ia32/ia32_ioctl.c	2003-07-05 18:09:37.000000000 -0700
@@ -268,6 +268,6 @@
 		return sys_ioctl(fd, cmd, (unsigned long)arg);
 
 	}
-	printk("%x:unimplemented IA32 ioctl system call\n", cmd);
+	printk(KERN_ERR "%x:unimplemented IA32 ioctl system call\n", cmd);
 	return -EINVAL;
 }
diff -urN linux-2.4.22-pre2/arch/ia64/ia32/sys_ia32.c linux-2.4.22-pre3/arch/ia64/ia32/sys_ia32.c
--- linux-2.4.22-pre2/arch/ia64/ia32/sys_ia32.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/ia32/sys_ia32.c	2003-07-05 18:09:37.000000000 -0700
@@ -250,9 +250,8 @@
 
 
 static int
-get_page_prot (unsigned long addr)
+get_page_prot (struct vm_area_struct *vma, unsigned long addr)
 {
-	struct vm_area_struct *vma = find_vma(current->mm, addr);
 	int prot = 0;
 
 	if (!vma || vma->vm_start > addr)
@@ -275,14 +274,26 @@
 mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags,
 	      loff_t off)
 {
-	void *page = (void *) get_zeroed_page(GFP_KERNEL);
+	void *page = NULL;
 	struct inode *inode;
-	unsigned long ret;
-	int old_prot = get_page_prot(start);
+	unsigned long ret = 0;
+	struct vm_area_struct *vma = find_vma(current->mm, start);
+	int old_prot = get_page_prot(vma, start);
 
 	DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n",
 	    file, start, end, prot, flags, off);
 
+
+	/* Optimize the case where the old mmap and the new mmap are both anonymous */
+	if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) {
+		if (clear_user((void *) start, end - start)) {
+			ret = -EFAULT;
+			goto out;
+		}
+		goto skip_mmap;
+	}
+
+	page = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!page)
 		return -ENOMEM;
 
@@ -307,6 +318,7 @@
 			copy_to_user((void *) end, page + PAGE_OFF(end),
 				     PAGE_SIZE - PAGE_OFF(end));
 	}
+
 	if (!(flags & MAP_ANONYMOUS)) {
 		/* read the file contents */
 		inode = file->f_dentry->d_inode;
@@ -317,10 +329,13 @@
 			goto out;
 		}
 	}
+
+ skip_mmap:
 	if (!(prot & PROT_WRITE))
 		ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot);
   out:
-	free_page((unsigned long) page);
+	if (page)
+		free_page((unsigned long) page);
 	return ret;
 }
 
@@ -448,7 +463,12 @@
 		return addr;
 
 	if (len > IA32_PAGE_OFFSET || addr > IA32_PAGE_OFFSET - len)
+	{
+		if (flags & MAP_FIXED)
+			return -ENOMEM;
+		else
 		return -EINVAL;
+	}
 
 	if (OFFSET4K(offset))
 		return -EINVAL;
@@ -547,7 +567,7 @@
 #if PAGE_SHIFT <= IA32_PAGE_SHIFT
 	ret = sys_munmap(start, end - start);
 #else
-	if (start > end)
+	if (start >= end)
 		return -EINVAL;
 
 	start = PAGE_ALIGN(start);
@@ -576,11 +596,12 @@
 mprotect_subpage (unsigned long address, int new_prot)
 {
 	int old_prot;
+	struct vm_area_struct *vma;
 
 	if (new_prot == PROT_NONE)
 		return 0;		/* optimize case where nothing changes... */
-
-	old_prot = get_page_prot(address);
+	vma = find_vma(current->mm, address);
+	old_prot = get_page_prot(vma, address);
 	return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot);
 }
 
@@ -1230,8 +1251,8 @@
 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
 
 struct rlimit32 {
-	int	rlim_cur;
-	int	rlim_max;
+	unsigned int	rlim_cur;
+	unsigned int	rlim_max;
 };
 
 extern asmlinkage long sys_getrlimit (unsigned int resource, struct rlimit *rlim);
@@ -2085,7 +2106,7 @@
 };
 
 struct shmid64_ds32 {
-	struct ipc64_perm shm_perm;
+	struct ipc64_perm32 shm_perm;
 	__kernel_size_t32 shm_segsz;
 	__kernel_time_t32 shm_atime;
 	unsigned int __unused1;
@@ -2126,6 +2147,7 @@
 #define SEMOP		 1
 #define SEMGET		 2
 #define SEMCTL		 3
+#define SEMTIMEDOP	 4
 #define MSGSND		11
 #define MSGRCV		12
 #define MSGGET		13
@@ -2167,6 +2189,10 @@
 	else
 		fourth.__pad = (void *)A(pad);
 	switch (third) {
+	      default:
+		err = -EINVAL;
+		break;
+
 	      case IPC_INFO:
 	      case IPC_RMID:
 	      case IPC_SET:
@@ -2234,7 +2260,7 @@
 static int
 do_sys32_msgsnd (int first, int second, int third, void *uptr)
 {
-	struct msgbuf *p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
+	struct msgbuf *p = kmalloc(second + sizeof(struct msgbuf), GFP_USER);
 	struct msgbuf32 *up = (struct msgbuf32 *)uptr;
 	mm_segment_t old_fs;
 	int err;
@@ -2276,12 +2302,12 @@
 		msgtyp = ipck.msgtyp;
 	}
 	err = -ENOMEM;
-	p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
+	p = kmalloc(second + sizeof(struct msgbuf), GFP_USER);
 	if (!p)
 		goto out;
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
-	err = sys_msgrcv(first, p, second + 4, msgtyp, third);
+	err = sys_msgrcv(first, p, second, msgtyp, third);
 	set_fs(old_fs);
 	if (err < 0)
 		goto free_then_out;
@@ -2314,21 +2340,21 @@
 
 	      case IPC_SET:
 		if (version == IPC_64) {
-			err = get_user(m.msg_perm.uid, &up64->msg_perm.uid);
-			err |= get_user(m.msg_perm.gid, &up64->msg_perm.gid);
-			err |= get_user(m.msg_perm.mode, &up64->msg_perm.mode);
-			err |= get_user(m.msg_qbytes, &up64->msg_qbytes);
+			err = get_user(m64.msg_perm.uid, &up64->msg_perm.uid);
+			err |= get_user(m64.msg_perm.gid, &up64->msg_perm.gid);
+			err |= get_user(m64.msg_perm.mode, &up64->msg_perm.mode);
+			err |= get_user(m64.msg_qbytes, &up64->msg_qbytes);
 		} else {
-			err = get_user(m.msg_perm.uid, &up32->msg_perm.uid);
-			err |= get_user(m.msg_perm.gid, &up32->msg_perm.gid);
-			err |= get_user(m.msg_perm.mode, &up32->msg_perm.mode);
-			err |= get_user(m.msg_qbytes, &up32->msg_qbytes);
+			err = get_user(m64.msg_perm.uid, &up32->msg_perm.uid);
+			err |= get_user(m64.msg_perm.gid, &up32->msg_perm.gid);
+			err |= get_user(m64.msg_perm.mode, &up32->msg_perm.mode);
+			err |= get_user(m64.msg_qbytes, &up32->msg_qbytes);
 		}
 		if (err)
 			break;
 		old_fs = get_fs();
 		set_fs(KERNEL_DS);
-		err = sys_msgctl(first, second, &m);
+		err = sys_msgctl(first, second, &m64);
 		set_fs(old_fs);
 		break;
 
@@ -2408,7 +2434,7 @@
 shmctl32 (int first, int second, void *uptr)
 {
 	int err = -EFAULT, err2;
-	struct shmid_ds s;
+
 	struct shmid64_ds s64;
 	struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
 	struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
@@ -2460,19 +2486,19 @@
 
 	      case IPC_SET:
 		if (version == IPC_64) {
-			err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
-			err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
-			err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
+			err = get_user(s64.shm_perm.uid, &up64->shm_perm.uid);
+			err |= get_user(s64.shm_perm.gid, &up64->shm_perm.gid);
+			err |= get_user(s64.shm_perm.mode, &up64->shm_perm.mode);
 		} else {
-			err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
-			err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
-			err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
+			err = get_user(s64.shm_perm.uid, &up32->shm_perm.uid);
+			err |= get_user(s64.shm_perm.gid, &up32->shm_perm.gid);
+			err |= get_user(s64.shm_perm.mode, &up32->shm_perm.mode);
 		}
 		if (err)
 			break;
 		old_fs = get_fs();
 		set_fs(KERNEL_DS);
-		err = sys_shmctl(first, second, &s);
+		err = sys_shmctl(first, second, &s64);
 		set_fs(old_fs);
 		break;
 
@@ -2553,6 +2579,17 @@
 	return err;
 }
 
+static long
+semtimedop32(int semid, struct sembuf *tsems, int nsems,
+	     const struct timespec32 *timeout32)
+{
+	struct timespec t;
+	if (get_user (t.tv_sec, &timeout32->tv_sec) ||
+	    get_user (t.tv_nsec, &timeout32->tv_nsec))
+		return -EFAULT;
+	return sys_semtimedop(semid, tsems, nsems, &t);
+}
+
 asmlinkage long
 sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
 {
@@ -2564,7 +2601,11 @@
 	switch (call) {
 	      case SEMOP:
 		/* struct sembuf is the same on 32 and 64bit :)) */
-		return sys_semop(first, (struct sembuf *)AA(ptr), second);
+		return sys_semtimedop(first, (struct sembuf *)AA(ptr), second,
+				      NULL);
+	      case SEMTIMEDOP:
+		return semtimedop32(first, (struct sembuf *)AA(ptr), second, 
+				    (const struct timespec32 *)AA(fifth));
 	      case SEMGET:
 		return sys_semget(first, second, third);
 	      case SEMCTL:
@@ -2590,7 +2631,7 @@
 		return shmctl32(first, second, (void *)AA(ptr));
 
 	      default:
-		return -EINVAL;
+		return -ENOSYS;
 	}
 	return -EINVAL;
 }
@@ -2924,7 +2965,7 @@
 	ptp = ia64_task_regs(tsk);
 	tos = (tsk->thread.fsr >> 11) & 7;
 	for (i = 0; i < 8; i++)
-		put_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
+		put_fpreg(i, &save->st_space[i], ptp, swp, tos);
 	return 0;
 }
 
@@ -2957,7 +2998,7 @@
 	ptp = ia64_task_regs(tsk);
 	tos = (tsk->thread.fsr >> 11) & 7;
 	for (i = 0; i < 8; i++)
-		get_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
+		get_fpreg(i, &save->st_space[i], ptp, swp, tos);
 	return 0;
 }
 
@@ -3076,26 +3117,23 @@
 	ret = -ESRCH;
 	read_lock(&tasklist_lock);
 	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
 	read_unlock(&tasklist_lock);
 	if (!child)
 		goto out;
 	ret = -EPERM;
 	if (pid == 1)		/* no messing around with init! */
-		goto out;
+		goto out_tsk;
 
 	if (request == PTRACE_ATTACH) {
 		ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
-		goto out;
+		goto out_tsk;
 	}
-	ret = -ESRCH;
-	if (!(child->ptrace & PT_PTRACED))
-		goto out;
-	if (child->state != TASK_STOPPED) {
-		if (request != PTRACE_KILL)
-			goto out;
-	}
-	if (child->p_pptr != current)
-		goto out;
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
+		goto out_tsk;
 
 	switch (request) {
 	      case PTRACE_PEEKTEXT:
@@ -3105,12 +3143,12 @@
 			ret = put_user(value, (unsigned int *) A(data));
 		else
 			ret = -EIO;
-		goto out;
+		goto out_tsk;
 
 	      case PTRACE_POKETEXT:
 	      case PTRACE_POKEDATA:	/* write the word at location addr */
 		ret = ia32_poke(regs, child, addr, data);
-		goto out;
+		goto out_tsk;
 
 	      case PTRACE_PEEKUSR:	/* read word at addr in USER area */
 		ret = -EIO;
@@ -3185,6 +3223,8 @@
 		break;
 
 	}
+  out_tsk:
+	free_task_struct(child);
   out:
 	unlock_kernel();
 	return ret;
@@ -3407,6 +3447,7 @@
 asmlinkage long
 sys32_sysctl (struct sysctl32 *args)
 {
+#ifdef CONFIG_SYSCTL
 	struct sysctl32 a32;
 	mm_segment_t old_fs = get_fs ();
 	void *oldvalp, *newvalp;
@@ -3444,6 +3485,9 @@
 		return -EFAULT;
 
 	return ret;
+#else
+	return -ENOSYS;
+#endif
 }
 
 asmlinkage long
@@ -3707,21 +3751,43 @@
 	u32 bufferram;
 	u32 totalswap;
 	u32 freeswap;
-	unsigned short procs;
-	char _f[22];
+	u16 procs;
+	u16 pad;
+	u32 totalhigh;
+	u32 freehigh;
+	u32 mem_unit;
+	char _f[8];
 };
 
 asmlinkage long
 sys32_sysinfo (struct sysinfo32 *info)
 {
 	extern asmlinkage long sys_sysinfo (struct sysinfo *);
-	mm_segment_t old_fs = get_fs();
 	struct sysinfo s;
 	long ret, err;
+	int bitcount = 0;
+	mm_segment_t old_fs = get_fs();
 
 	set_fs(KERNEL_DS);
 	ret = sys_sysinfo(&s);
 	set_fs(old_fs);
+	/* Check to see if any memory value is too large for 32-bit and
+	 * scale down if needed.
+	 */
+	if ((s.totalram >> 32) || (s.totalswap >> 32)) {
+		while (s.mem_unit < PAGE_SIZE) {
+			s.mem_unit <<= 1;
+			bitcount++;
+		}
+		s.totalram >>= bitcount;
+		s.freeram >>= bitcount;
+		s.sharedram >>= bitcount;
+		s.bufferram >>= bitcount;
+		s.totalswap >>= bitcount;
+		s.freeswap >>= bitcount;
+		s.totalhigh >>= bitcount;
+		s.freehigh >>= bitcount;
+	}
 
 	if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
 		return -EFAULT;
@@ -3737,6 +3803,9 @@
 	err |= __put_user(s.totalswap, &info->totalswap);
 	err |= __put_user(s.freeswap, &info->freeswap);
 	err |= __put_user(s.procs, &info->procs);
+	err |= __put_user(s.totalhigh, &info->totalhigh);
+	err |= __put_user(s.freehigh, &info->freehigh);
+	err |= __put_user(s.mem_unit, &info->mem_unit);
 	if (err)
 		return -EFAULT;
 	return ret;
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/acpi.c linux-2.4.22-pre3/arch/ia64/kernel/acpi.c
--- linux-2.4.22-pre2/arch/ia64/kernel/acpi.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/acpi.c	2003-07-05 18:09:37.000000000 -0700
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 1999 VA Linux Systems
  *  Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
- *  Copyright (C) 2000, 2002 Hewlett-Packard Co.
+ *  Copyright (C) 2000, 2002-2003 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>
@@ -51,6 +51,7 @@
 asm (".weak iosapic_override_isa_irq");
 asm (".weak iosapic_register_platform_intr");
 asm (".weak iosapic_init");
+asm (".weak iosapic_system_init");
 asm (".weak iosapic_version");
 
 void (*pm_idle) (void);
@@ -69,20 +70,20 @@
 
 	rsdp_phys = acpi_find_rsdp();
 	if (!rsdp_phys) {
-		printk("ACPI 2.0 RSDP not found, default to \"dig\"\n");
+		printk(KERN_ERR "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");
+		printk(KERN_ERR "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");
+		printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
 		return "dig";
 	}
 
@@ -110,165 +111,88 @@
 
 #ifdef CONFIG_ACPI
 
-static acpi_resource *
-acpi_get_crs_next (acpi_buffer *buf, int *offset)
-{
-	acpi_resource *res;
-
-	if (*offset >= buf->length)
-		return NULL;
+struct acpi_vendor_descriptor {
+	u8				guid_id;
+	efi_guid_t			guid;
+};
+
+struct acpi_vendor_info {
+	struct acpi_vendor_descriptor	*descriptor;
+	u8				*data;
+	u32				length;
+};
 
-	res = (acpi_resource *)((char *) buf->pointer + *offset);
-	*offset += res->length;
-	return res;
-}
-
-static 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;
-	}
-}
-
-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;
-			case ACPI_RSTYPE_END_TAG:
-				return;
-				break;
-		}
-	}
+acpi_status
+acpi_vendor_resource_match(acpi_resource *resource, void *context)
+{
+	struct acpi_vendor_info *info = (struct acpi_vendor_info *) context;
+	acpi_resource_vendor *vendor;
+	struct acpi_vendor_descriptor *descriptor;
+	u32 length;
+
+	if (resource->id != ACPI_RSTYPE_VENDOR)
+		return AE_OK;
+
+	vendor = (acpi_resource_vendor *) &resource->data;
+	descriptor = (struct acpi_vendor_descriptor *) vendor->reserved;
+	if (vendor->length <= sizeof(*info->descriptor) ||
+	    descriptor->guid_id != info->descriptor->guid_id ||
+	    efi_guidcmp(descriptor->guid, info->descriptor->guid))
+		return AE_OK;
+
+	length = vendor->length - sizeof(struct acpi_vendor_descriptor);
+	info->data = acpi_os_allocate(length);
+	if (!info->data)
+		return AE_NO_MEMORY;
+
+	memcpy(info->data, vendor->reserved + sizeof(struct acpi_vendor_descriptor), length);
+	info->length = length;
+	return AE_CTRL_TERMINATE;
 }
 
 acpi_status
-acpi_get_addr_space(acpi_handle obj, u8 type, u64 *base, u64 *length, u64 *tra)
+acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor *id,
+		u8 **data, u32 *length)
 {
-	acpi_status status;
-	acpi_buffer buf = { .length  = ACPI_ALLOCATE_BUFFER,
-			    .pointer = NULL };
+	struct acpi_vendor_info info;
 
-	*base = 0;
-	*length = 0;
-	*tra = 0;
+	info.descriptor = id;
+	info.data = 0;
 
-	status = acpi_get_current_resources(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_os_free(buf.pointer);
+	acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, &info);
+	if (!info.data)
+		return AE_NOT_FOUND;
 
+	*data = info.data;
+	*length = info.length;
 	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)
+struct acpi_vendor_descriptor hp_ccsr_descriptor = {
+	.guid_id = 2,
+	.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 = { .length  = ACPI_ALLOCATE_BUFFER,
-			    .pointer = NULL };
-	acpi_resource_vendor *res;
-	acpi_hp_vendor_long *hp_res;
-	efi_guid_t vendor_guid;
-
-	*csr_base = 0;
-	*csr_length = 0;
+	u8 *data;
+	u32 length;
+	int i;
+
+	status = acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length);
+
+	if (ACPI_FAILURE(status) || length != 16)
+		return AE_NOT_FOUND;
+
+	memcpy(csr_base, data, sizeof(*csr_base));
+	memcpy(csr_length, data + 8, sizeof(*csr_length));
+	acpi_os_free(data);
 
-	status = acpi_get_current_resources(obj, &buf);
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n");
-		return status;
-	}
-
-	status = AE_NOT_FOUND;
-	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");
-		goto out;
-	}
-
-	status = AE_TYPE; /* Revisit error? */
-	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");
-		goto out;
-	}
-
-	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");
-		goto out;
-	}
-
-	/* It's probably unaligned, so use memcpy */
-	memcpy(csr_base, hp_res->csr_base, 8);
-	memcpy(csr_length, hp_res->csr_length, 8);
-	status = AE_OK;
-
- out:
-	acpi_os_free(buf.pointer);
-	return status;
+	return AE_OK;
 }
+
 #endif /* CONFIG_ACPI */
 
 #ifdef CONFIG_ACPI_BOOT
@@ -293,8 +217,7 @@
 		/* correctable platform error interrupt */
 		vector = platform_intr_list[int_type];
 	} else
-		printk("acpi_request_vector(): invalid interrupt type\n");
-
+		printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n");
 	return vector;
 }
 
@@ -354,7 +277,7 @@
 		return 0;
 	}
 
-	printk("CPU %d (0x%04x)", total_cpus, phys_id);
+	printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, phys_id);
 
 	if (lsapic->flags.enabled) {
 		available_cpus++;
@@ -397,40 +320,6 @@
 
 
 static int __init
-acpi_find_iosapic (unsigned int gsi, u32 *gsi_base, char **iosapic_address)
-{
-	struct acpi_table_iosapic *iosapic;
-	int ver;
-	int max_pin;
-	char *p;
-	char *end;
-
-	if (!gsi_base || !iosapic_address)
-		return -ENODEV;
-
-	p = (char *) (acpi_madt + 1);
-	end = p + (acpi_madt->header.length - sizeof(struct acpi_table_madt));
-
-	while (p < end) {
-		if (*p == ACPI_MADT_IOSAPIC) {
-			iosapic = (struct acpi_table_iosapic *) p;
-
-			*gsi_base = iosapic->global_irq_base;
-			*iosapic_address = ioremap(iosapic->address, 0);
-
-			ver = iosapic_version(*iosapic_address);
-			max_pin = (ver >> 16) & 0xff;
-
-			if ((gsi - *gsi_base) <= max_pin)
-				return 0;	/* Found it! */
-		}
-		p += p[1];
-	}
-	return -ENODEV;
-}
-
-
-static int __init
 acpi_parse_iosapic (acpi_table_entry_header *header)
 {
 	struct acpi_table_iosapic *iosapic;
@@ -441,15 +330,9 @@
 
 	acpi_table_print_madt_entry(header);
 
-	if (iosapic_init) {
-#ifndef CONFIG_ITANIUM
-		iosapic_init(iosapic->address, iosapic->global_irq_base,
-			     has_8259);
-#else
-		/* Firmware on old Itanium systems is broken */
-		iosapic_init(iosapic->address, iosapic->global_irq_base, 1);
-#endif
-	}
+	if (iosapic_init)
+		iosapic_init(iosapic->address, iosapic->global_irq_base);
+
 	return 0;
 }
 
@@ -459,8 +342,6 @@
 {
 	struct acpi_table_plat_int_src *plintsrc;
 	int vector;
-	u32 gsi_base;
-	char *iosapic_address;
 
 	plintsrc = (struct acpi_table_plat_int_src *) header;
 	if (!plintsrc)
@@ -473,11 +354,6 @@
 		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 interrupt, set attributes,
 	 * and program the IOSAPIC routing table.
@@ -487,10 +363,8 @@
 						plintsrc->iosapic_vector,
 						plintsrc->eid,
 						plintsrc->id,
-						(plintsrc->flags.polarity == 1) ? 1 : 0,
-						(plintsrc->flags.trigger == 1) ? 1 : 0,
-						gsi_base,
-						iosapic_address);
+						(plintsrc->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
+						(plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
 
 	platform_intr_list[plintsrc->type] = vector;
 	return 0;
@@ -513,9 +387,8 @@
 		return 0;
 
 	iosapic_override_isa_irq(p->bus_irq, p->global_irq,
-				 (p->flags.polarity == 1) ? 1 : 0,
-				 (p->flags.trigger == 1) ? 1 : 0);
-
+				 (p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
+				 (p->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
 	return 0;
 }
 
@@ -546,7 +419,13 @@
 	acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
 
 	/* remember the value for reference after free_initmem() */
+#ifdef CONFIG_ITANIUM
+	has_8259 = 1; /* Firmware on old Itanium systems is broken */
+#else
 	has_8259 = acpi_madt->flags.pcat_compat;
+#endif
+	if (iosapic_system_init)
+		iosapic_system_init(has_8259);
 
 	/* Get base address of IPI Message Block */
 
@@ -563,8 +442,7 @@
 {
 	struct acpi_table_header *fadt_header;
 	fadt_descriptor_rev2 *fadt;
-	u32 sci_irq, gsi_base;
-	char *iosapic_address;
+	u32 sci_irq;
 
 	if (!phys_addr || !size)
 		return -EINVAL;
@@ -587,9 +465,7 @@
 	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);
-
+	iosapic_register_intr(sci_irq, IOSAPIC_POL_LOW, IOSAPIC_LEVEL);
 	return 0;
 }
 
@@ -676,13 +552,13 @@
 
 #ifdef CONFIG_SMP
 	if (available_cpus == 0) {
-		printk("ACPI: Found 0 CPUS; assuming 1\n");
+		printk(KERN_INFO "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);
+	printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
 	return 0;
 }
 
@@ -690,6 +566,7 @@
 /* --------------------------------------------------------------------------
                              PCI Interrupt Routing
    -------------------------------------------------------------------------- */
+#ifdef CONFIG_PCI
 
 int __init
 acpi_get_prt (struct pci_vector_struct **vectors, int *count)
@@ -732,7 +609,7 @@
 	*count = acpi_prt.count;
 	return 0;
 }
-
+#endif
 /* Assume IA64 always use I/O SAPIC */
 
 int __init
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/brl_emu.c linux-2.4.22-pre3/arch/ia64/kernel/brl_emu.c
--- linux-2.4.22-pre2/arch/ia64/kernel/brl_emu.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/brl_emu.c	2003-07-05 18:09:37.000000000 -0700
@@ -55,11 +55,11 @@
 ia64_emulate_brl (struct pt_regs *regs, unsigned long ar_ec)
 {
 	unsigned long bundle[2];
-	unsigned long opcode, btype, qp, offset;
+	unsigned long opcode, btype, qp, offset, cpl;
 	unsigned long next_ip;
 	struct siginfo siginfo;
 	struct illegal_op_return rv;
-	int tmp_taken, unimplemented_address;
+	long tmp_taken, unimplemented_address;
 
 	rv.fkt = (unsigned long) -1;
 
@@ -158,9 +158,9 @@
 			 *  AR[PFS].pec = AR[EC]
 			 *  AR[PFS].ppl = PSR.cpl
 			 */
+			cpl = ia64_psr(regs)->cpl;
 			regs->ar_pfs = ((regs->cr_ifs & 0x3fffffffff)
-					| (ar_ec << 52)
-					| ((unsigned long) ia64_psr(regs)->cpl << 62));
+					| (ar_ec << 52) | (cpl << 62));
 
 			/*
 			 *  CFM.sof -= CFM.sol
@@ -195,7 +195,7 @@
 		/*
 		 *  The target address contains unimplemented bits.
 		 */
-		printk("Woah! Unimplemented Instruction Address Trap!\n");
+		printk(KERN_DEBUG "Woah! Unimplemented Instruction Address Trap!\n");
 		siginfo.si_signo = SIGILL;
 		siginfo.si_errno = 0;
 		siginfo.si_flags = 0;
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/efi.c linux-2.4.22-pre3/arch/ia64/kernel/efi.c
--- linux-2.4.22-pre2/arch/ia64/kernel/efi.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/efi.c	2003-07-05 18:09:37.000000000 -0700
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999-2002 Hewlett-Packard Co.
+ * Copyright (C) 1999-2003 Hewlett-Packard Co.
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  *
@@ -365,7 +365,7 @@
 				prev_valid = 1;
 			} else {
 				if (curr.start < prev.start)
-					printk("Oops: EFI memory table not ordered!\n");
+					printk(KERN_ERR "Oops: EFI memory table not ordered!\n");
 
 				if (prev.end == curr.start) {
 					/* merge two consecutive memory ranges */
@@ -437,7 +437,8 @@
 		 * dedicated ITR for the PAL code.
 		 */
 		if ((vaddr & mask) == (KERNEL_START & mask)) {
-			printk("%s: no need to install ITR for PAL code\n", __FUNCTION__);
+			printk(KERN_INFO "%s: no need to install ITR for PAL code\n",
+			       __FUNCTION__);
 			continue;
 		}
 
@@ -445,7 +446,7 @@
 			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",
+		printk(KERN_INFO "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 << EFI_PAGE_SHIFT),
 		       vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
@@ -488,7 +489,7 @@
 		}
 	}
 	if (mem_limit != ~0UL)
-		printk("Ignoring memory above %luMB\n", mem_limit >> 20);
+		printk(KERN_INFO "Ignoring memory above %luMB\n", mem_limit >> 20);
 
 	efi.systab = __va(ia64_boot_param->efi_systab);
 
@@ -500,7 +501,7 @@
 	if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
 		panic("Woah! EFI system table signature incorrect\n");
 	if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
-		printk("Warning: EFI system table major version mismatch: "
+		printk(KERN_WARNING "Warning: EFI system table major version mismatch: "
 		       "got %d.%02d, expected %d.%02d\n",
 		       efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff,
 		       EFI_SYSTEM_TABLE_REVISION >> 16, EFI_SYSTEM_TABLE_REVISION & 0xffff);
@@ -515,7 +516,7 @@
 		vendor[i] = '\0';
 	}
 
-	printk("EFI v%u.%.02u by %s:",
+	printk(KERN_INFO "EFI v%u.%.02u by %s:",
 	       efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor);
 
 	for (i = 0; i < efi.systab->nr_tables; i++) {
@@ -607,7 +608,7 @@
 									   | _PAGE_PL_0
 									   | _PAGE_AR_RW));
 #else
-				printk("EFI_MEMORY_WC mapping\n");
+				printk(KERN_INFO "EFI_MEMORY_WC mapping\n");
 				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
 #endif
 			} else if (md->attribute & EFI_MEMORY_WT) {
@@ -617,7 +618,7 @@
 									   | _PAGE_PL_0
 									   | _PAGE_AR_RW));
 #else
-				printk("EFI_MEMORY_WT mapping\n");
+				printk(KERN_INFO "EFI_MEMORY_WT mapping\n");
 				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
 #endif
 			}
@@ -629,7 +630,7 @@
 			       efi_desc_size, ia64_boot_param->efi_memdesc_version,
 			       ia64_boot_param->efi_memmap);
 	if (status != EFI_SUCCESS) {
-		printk("Warning: unable to switch EFI into virtual mode (status=0x%lx)\n", status);
+		printk(KERN_WARNING "warning: unable to switch EFI into virtual mode (status=0x%lx)\n", status);
 		return;
 	}
 
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/efivars.c linux-2.4.22-pre3/arch/ia64/kernel/efivars.c
--- linux-2.4.22-pre2/arch/ia64/kernel/efivars.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/kernel/efivars.c	2003-07-05 18:09:37.000000000 -0700
@@ -29,6 +29,9 @@
  *
  * Changelog:
  *
+ *  10 Dec 2002 - Matt Domsch <Matt_Domsch@dell.com>
+ *   fix locking per Peter Chubb's findings
+ * 
  *  25 Mar 2002 - Matt Domsch <Matt_Domsch@dell.com>
  *   move uuid_unparse() to include/asm-ia64/efi.h:efi_guid_unparse()
  *
@@ -73,7 +76,7 @@
 MODULE_DESCRIPTION("/proc interface to EFI Variables");
 MODULE_LICENSE("GPL");
 
-#define EFIVARS_VERSION "0.05 2002-Mar-26"
+#define EFIVARS_VERSION "0.06 2002-Dec-10"
 
 static int
 efivar_read(char *page, char **start, off_t off,
@@ -106,6 +109,14 @@
 	struct list_head        list;
 } efivar_entry_t;
 
+/*
+  efivars_lock protects two things:
+  1) efivar_list - adds, removals, reads, writes
+  2) efi.[gs]et_variable() calls.
+  It must not be held when creating proc entries or calling kmalloc.
+  efi.get_next_variable() is only called from efivars_init(),
+  which is protected by the BKL, so that path is safe.
+*/
 static spinlock_t efivars_lock = SPIN_LOCK_UNLOCKED;
 static LIST_HEAD(efivar_list);
 static struct proc_dir_entry *efi_vars_dir = NULL;
@@ -150,6 +161,7 @@
  *    variable_name_size = number of bytes required to hold
  *                         variable_name (not counting the NULL
  *                         character at the end.
+ *    efivars_lock is not held on entry or exit.
  * Returns 1 on failure, 0 on success
  */
 static int
@@ -157,13 +169,14 @@
 			 efi_char16_t *variable_name,
 			 efi_guid_t *vendor_guid)
 {
-
 	int i, short_name_size = variable_name_size /
 		sizeof(efi_char16_t) + 38;
-	char *short_name = kmalloc(short_name_size+1,
-				   GFP_KERNEL);
-	efivar_entry_t *new_efivar = kmalloc(sizeof(efivar_entry_t),
-					     GFP_KERNEL);
+	char *short_name;
+	efivar_entry_t *new_efivar;
+
+	short_name = kmalloc(short_name_size+1, GFP_KERNEL);
+	new_efivar = kmalloc(sizeof(efivar_entry_t), GFP_KERNEL);
+
 	if (!short_name || !new_efivar)  {
 		if (short_name)        kfree(short_name);
 		if (new_efivar)        kfree(new_efivar);
@@ -188,19 +201,18 @@
 	*(short_name + strlen(short_name)) = '-';
 	efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
 
-
 	/* Create the entry in proc */
 	new_efivar->entry = create_proc_entry(short_name, 0600, efi_vars_dir);
 	kfree(short_name); short_name = NULL;
 	if (!new_efivar->entry) return 1;
 
-
 	new_efivar->entry->data = new_efivar;
 	new_efivar->entry->read_proc = efivar_read;
 	new_efivar->entry->write_proc = efivar_write;
 
+	spin_lock(&efivars_lock);
 	list_add(&new_efivar->list, &efivar_list);
-
+	spin_unlock(&efivars_lock);
 
 	return 0;
 }
@@ -326,6 +338,8 @@
 		kfree(efivar);
 	}
 
+	spin_unlock(&efivars_lock);
+
 	/* If this is a new variable, set up the proc entry for it. */
 	if (!found) {
 		efivar_create_proc_entry(utf8_strsize(var_data->VariableName,
@@ -336,36 +350,96 @@
 
 	kfree(var_data);
 	MOD_DEC_USE_COUNT;
-	spin_unlock(&efivars_lock);
 	return size;
 }
 
+/*
+ * The EFI system table contains pointers to the SAL system table,
+ * HCDP, ACPI, SMBIOS, etc, that may be useful to applications.
+ */
+static ssize_t
+efi_systab_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	void *data;
+	u8 *proc_buffer;
+	ssize_t size, length;
+	int ret;
+	const int max_nr_entries = 7; 	/* num ptrs to tables we could expose */
+	const int max_line_len = 80;
+
+	if (!efi.systab)
+		return 0;
+
+	proc_buffer = kmalloc(max_nr_entries * max_line_len, GFP_KERNEL);
+	if (!proc_buffer)
+		return -ENOMEM;
+
+	length = 0;
+	if (efi.mps)
+		length += sprintf(proc_buffer + length, "MPS=0x%lx\n", __pa(efi.mps));
+	if (efi.acpi20)
+		length += sprintf(proc_buffer + length, "ACPI20=0x%lx\n", __pa(efi.acpi20));
+	if (efi.acpi)
+		length += sprintf(proc_buffer + length, "ACPI=0x%lx\n", __pa(efi.acpi));
+	if (efi.smbios)
+		length += sprintf(proc_buffer + length, "SMBIOS=0x%lx\n", __pa(efi.smbios));
+	if (efi.sal_systab)
+		length += sprintf(proc_buffer + length, "SAL=0x%lx\n", __pa(efi.sal_systab));
+	if (efi.hcdp)
+		length += sprintf(proc_buffer + length, "HCDP=0x%lx\n", __pa(efi.hcdp));
+	if (efi.boot_info)
+		length += sprintf(proc_buffer + length, "BOOTINFO=0x%lx\n", __pa(efi.boot_info));
+
+	if (*ppos >= length) {
+		ret = 0;
+		goto out;
+	}
 
+	data = proc_buffer + file->f_pos;
+	size = length - file->f_pos;
+	if (size > count)
+		size = count;
+	if (copy_to_user(buffer, data, size)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	*ppos += size;
+	ret = size;
+
+out:
+	kfree(proc_buffer);
+	return ret;
+}
+
+static struct proc_dir_entry *efi_systab_entry;
+static struct file_operations efi_systab_fops = {
+	.read = efi_systab_read,
+};
 
 static int __init
 efivars_init(void)
 {
-
 	efi_status_t status;
 	efi_guid_t vendor_guid;
 	efi_char16_t *variable_name = kmalloc(1024, GFP_KERNEL);
 	unsigned long variable_name_size = 1024;
 
-	spin_lock(&efivars_lock);
-
 	printk(KERN_INFO "EFI Variables Facility v%s\n", EFIVARS_VERSION);
 
-        /* Since efi.c happens before procfs is available,
-           we create the directory here if it doesn't
-           already exist.  There's probably a better way
-           to do this.
-        */
-        if (!efi_dir)
+	/* Since efi.c happens before procfs is available,
+	   we create the directory here if it doesn't
+	   already exist.  There's probably a better way
+	   to do this.
+	*/
+	if (!efi_dir)
                 efi_dir = proc_mkdir("efi", NULL);
 
-	efi_vars_dir = proc_mkdir("vars", efi_dir);
-
+	efi_systab_entry = create_proc_entry("systab", S_IRUSR | S_IRGRP, efi_dir);
+	if (efi_systab_entry)
+		efi_systab_entry->proc_fops = &efi_systab_fops;
 
+	efi_vars_dir = proc_mkdir("vars", efi_dir);
 
 	/* Per EFI spec, the maximum storage allocated for both
 	   the variable name and variable data is 1024 bytes.
@@ -398,7 +472,6 @@
 	} while (status != EFI_NOT_FOUND);
 
 	kfree(variable_name);
-	spin_unlock(&efivars_lock);
 	return 0;
 }
 
@@ -409,16 +482,17 @@
 	efivar_entry_t *efivar;
 
 	spin_lock(&efivars_lock);
-
+	if (efi_systab_entry)
+		remove_proc_entry(efi_systab_entry->name, efi_dir);
 	list_for_each_safe(pos, n, &efivar_list) {
 		efivar = efivar_entry(pos);
 		remove_proc_entry(efivar->entry->name, efi_vars_dir);
 		list_del(&efivar->list);
 		kfree(efivar);
 	}
-	remove_proc_entry(efi_vars_dir->name, efi_dir);
 	spin_unlock(&efivars_lock);
 
+	remove_proc_entry(efi_vars_dir->name, efi_dir);
 }
 
 module_init(efivars_init);
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/entry.S linux-2.4.22-pre3/arch/ia64/kernel/entry.S
--- linux-2.4.22-pre2/arch/ia64/kernel/entry.S	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/entry.S	2003-07-05 18:09:37.000000000 -0700
@@ -161,7 +161,7 @@
 	mov r8=r13			// return pointer to previously running task
 	mov r13=in0			// set "current" pointer
 	;;
-(p6)	ssm psr.i			// renable psr.i AFTER the ic bit is serialized
+	ssm psr.i			// renable psr.i AFTER the ic bit is serialized
 	DO_LOAD_SWITCH_STACK
 
 #ifdef CONFIG_SMP
@@ -454,7 +454,14 @@
 
 GLOBAL_ENTRY(ia64_trace_syscall)
 	PT_REGS_UNWIND_INFO(0)
+{	/*
+	 * Some versions of gas generate bad unwind info if the first instruction of a
+	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
+	 */
+	nop.m 0
+	nop.i 0
 	br.call.sptk.many rp=invoke_syscall_trace // give parent a chance to catch syscall args
+}
 .ret6:	br.call.sptk.many rp=b6			// do the syscall
 strace_check_retval:
 	cmp.lt p6,p0=r8,r0			// syscall failed?
@@ -484,12 +491,19 @@
 
 GLOBAL_ENTRY(ia64_ret_from_clone)
 	PT_REGS_UNWIND_INFO(0)
+{	/*
+	 * Some versions of gas generate bad unwind info if the first instruction of a
+	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
+	 */
+	nop.m 0
+	nop.i 0
 	/*
 	 * We need to call schedule_tail() to complete the scheduling process.
 	 * Called by ia64_switch_to after do_fork()->copy_thread().  r8 contains the
 	 * address of the previously executing task.
 	 */
 	br.call.sptk.many rp=ia64_invoke_schedule_tail
+}
 .ret8:
 	adds r2=IA64_TASK_PTRACE_OFFSET,r13
 	;;
@@ -652,7 +666,7 @@
 	 * NOTE: alloc, loadrs, and cover can't be predicated.
 	 */
 (pNonSys) br.cond.dpnt dont_preserve_current_frame
-	cover				// add current frame into dirty partition
+	cover				// add current frame into dirty partition and set cr.ifs
 	;;
 	mov r19=ar.bsp			// get new backing store pointer
 	sub r16=r16,r18			// krbs = old bsp - size of dirty partition
@@ -678,24 +692,12 @@
 #	define Nregs	14
 #endif
 	alloc loc0=ar.pfs,2,Nregs-2,2,0
-	shr.u loc1=r18,9		// RNaTslots <= dirtySize / (64*8) + 1
+	shr.u loc1=r18,9		// RNaTslots <= floor(dirtySize / (64*8))
 	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
 	;;
 rse_clear_invalid:
 #ifdef CONFIG_ITANIUM
@@ -737,13 +739,13 @@
 	;;
 	mov loc3=0
 	mov loc4=0
-	mov loc9=0
 	mov loc5=0
 	mov loc6=0
+	mov loc7=0
 (pRecurse) br.call.sptk.many b6=rse_clear_invalid
 	;;
-	mov loc7=0
 	mov loc8=0
+	mov loc9=0
 	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
 	mov loc10=0
 	mov loc11=0
@@ -848,13 +850,14 @@
 	mov r9=ar.unat
 	mov loc0=rp				// save return address
 	mov out0=0				// there is no "oldset"
-	adds out1=0,sp				// out1=&sigscratch
+	adds out1=8,sp				// out1=&sigscratch->ar_pfs
 (pSys)	mov out2=1				// out2==1 => we're in a syscall
 	;;
 (pNonSys) mov out2=0				// out2==0 => not a syscall
 	.fframe 16
 	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
+	st8 [out1]=loc1,-8			// save ar.pfs, out1=&sigscratch
 	.body
 	br.call.sptk.many rp=ia64_do_signal
 .ret15:	.restore sp
@@ -875,11 +878,12 @@
 	mov loc0=rp				// save return address
 	mov out0=in0				// mask
 	mov out1=in1				// sigsetsize
-	adds out2=0,sp				// out2=&sigscratch
+	adds out2=8,sp				// out2=&sigscratch->ar_pfs
 	;;
 	.fframe 16
 	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
+	st8 [out2]=loc1,-8			// save ar.pfs, out2=&sigscratch
 	.body
 	br.call.sptk.many rp=ia64_rt_sigsuspend
 .ret17:	.restore sp
@@ -915,17 +919,16 @@
 END(sys_rt_sigreturn)
 
 GLOBAL_ENTRY(ia64_prepare_handle_unaligned)
-	//
-	// r16 = fake ar.pfs, we simply need to make sure
-	// privilege is still 0
-	//
-	mov r16=r0
 	.prologue
+	/*
+	 * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
+	 */
+	mov r16=r0
 	DO_SAVE_SWITCH_STACK
-	br.call.sptk.many rp=ia64_handle_unaligned // stack frame setup in ivt
+	br.call.sptk.many rp=ia64_handle_unaligned	// stack frame setup in ivt
 .ret21:	.body
 	DO_LOAD_SWITCH_STACK
-	br.cond.sptk.many rp			  // goes to ia64_leave_kernel
+	br.cond.sptk.many rp				// goes to ia64_leave_kernel
 END(ia64_prepare_handle_unaligned)
 
 	//
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/gate.S linux-2.4.22-pre3/arch/ia64/kernel/gate.S
--- linux-2.4.22-pre2/arch/ia64/kernel/gate.S	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/gate.S	2003-07-05 18:09:37.000000000 -0700
@@ -63,15 +63,19 @@
 	 * call stack.
 	 */
 
+#define SIGTRAMP_SAVES										\
+	.unwabi @svr4, 's';	/* mark this as a sigtramp handler (saves scratch regs) */	\
+	.savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF;						\
+	.savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF;						\
+	.savesp pr, PR_OFF+SIGCONTEXT_OFF;     							\
+	.savesp rp, RP_OFF+SIGCONTEXT_OFF;							\
+	.savesp ar.pfs, CFM_OFF+SIGCONTEXT_OFF;							\
+	.vframesp SP_OFF+SIGCONTEXT_OFF
+
 GLOBAL_ENTRY(ia64_sigtramp)
 	// describe the state that is active when we get here:
 	.prologue
-	.unwabi @svr4, 's'		// mark this as a sigtramp handler (saves scratch regs)
-	.savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF
-	.savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF
-	.savesp pr, PR_OFF+SIGCONTEXT_OFF
-	.savesp rp, RP_OFF+SIGCONTEXT_OFF
-	.vframesp SP_OFF+SIGCONTEXT_OFF
+	SIGTRAMP_SAVES
 	.body
 
 	.label_state 1
@@ -89,9 +93,7 @@
 	.spillsp.p p8, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
 (p8)	br.cond.spnt setup_rbs		// yup -> (clobbers r14, r15, and r16)
 back_from_setup_rbs:
-
-	.spillreg ar.pfs, r8
-	alloc r8=ar.pfs,0,0,3,0		// get CFM0, EC0, and CPL0 into r8
+	alloc r8=ar.pfs,0,0,3,0
 	ld8 out0=[base0],16		// load arg0 (signum)
 	adds base1=(ARG1_OFF-(RBS_BASE_OFF+SIGCONTEXT_OFF)),base1
 	;;
@@ -100,17 +102,12 @@
 	;;
 	ld8 out2=[base0]		// load arg2 (sigcontextp)
 	ld8 gp=[r17]			// get signal handler's global pointer
-
 	adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
 	;;
 	.spillsp ar.bsp, BSP_OFF+SIGCONTEXT_OFF
-	st8 [base0]=r9,(CFM_OFF-BSP_OFF)	// save sc_ar_bsp
-	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+SIGCONTEXT_OFF
-	st8 [base0]=r8				// save CFM0
+	st8 [base0]=r9			// save sc_ar_bsp
 	adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
+	adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
 	;;
 	stf.spill [base0]=f6,32
 	stf.spill [base1]=f7,32
@@ -133,7 +130,6 @@
 	ld8 r15=[base0],(CFM_OFF-BSP_OFF)	// fetch sc_ar_bsp and advance to CFM_OFF
 	mov r14=ar.bsp
 	;;
-	ld8 r8=[base0]				// restore (perhaps modified) CFM0, EC0, and CPL0
 	cmp.ne p8,p0=r14,r15			// do we need to restore the rbs?
 (p8)	br.cond.spnt restore_rbs		// yup -> (clobbers r14-r18, f6 & f7)
 	;;
@@ -156,10 +152,11 @@
 	ldf.fill f14=[base0],32
 	ldf.fill f15=[base1],32
 	mov r15=__NR_rt_sigreturn
+	.restore sp				// pop .prologue
 	break __BREAK_SYSCALL
 
-	.body
-	.copy_state 1
+	.prologue
+	SIGTRAMP_SAVES
 setup_rbs:
 	mov ar.rsc=0				// put RSE into enforced lazy mode
 	;;
@@ -171,6 +168,7 @@
 	;;
 	.spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
 	st8 [r14]=r16				// save sc_ar_rnat
+	.body
 	adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp
 
 	mov.m r16=ar.bsp			// sc_loadrs <- (new bsp - new bspstore) << 16
@@ -182,10 +180,11 @@
 	;;
 	st8 [r14]=r15				// save sc_loadrs
 	mov ar.rsc=0xf				// set RSE into eager mode, pl 3
+	.restore sp				// pop .prologue
 	br.cond.sptk back_from_setup_rbs
 
 	.prologue
-	.copy_state 1
+	SIGTRAMP_SAVES
 	.spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
 	.body
 restore_rbs:
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/ia64_ksyms.c linux-2.4.22-pre3/arch/ia64/kernel/ia64_ksyms.c
--- linux-2.4.22-pre2/arch/ia64/kernel/ia64_ksyms.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/ia64_ksyms.c	2003-07-05 18:09:37.000000000 -0700
@@ -4,6 +4,9 @@
 #include <linux/config.h>
 #include <linux/module.h>
 
+#include <linux/pm.h>
+EXPORT_SYMBOL(pm_idle);
+
 #include <linux/string.h>
 
 EXPORT_SYMBOL_NOVERS(memset);
@@ -47,6 +50,7 @@
 EXPORT_SYMBOL(__ia64_memcpy_fromio);
 EXPORT_SYMBOL(__ia64_memcpy_toio);
 EXPORT_SYMBOL(__ia64_memset_c_io);
+EXPORT_SYMBOL(io_space);
 
 #include <asm/semaphore.h>
 EXPORT_SYMBOL_NOVERS(__down);
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/iosapic.c linux-2.4.22-pre3/arch/ia64/kernel/iosapic.c
--- linux-2.4.22-pre2/arch/ia64/kernel/iosapic.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/iosapic.c	2003-07-05 18:09:37.000000000 -0700
@@ -4,7 +4,7 @@
  * Copyright (C) 1999 Intel Corp.
  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
  * Copyright (C) 2000-2002 J.I. Lee <jung-ik.lee@intel.com>
- * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co.
+ * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co.
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
@@ -28,6 +28,9 @@
  * 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
+ * 03/02/19	B. Helgaas	Make pcat_compat system-wide, not per-IOSAPIC.
+ *				Remove iosapic_address & gsi_base from external interfaces.
+ *				Rationalize __init/__devinit attributes.
  */
 /*
  * Here is what the interrupt logic between a PCI device and the CPU looks like:
@@ -63,14 +66,14 @@
  */
 #include <linux/config.h>
 
-#include <linux/kernel.h>
+#include <linux/acpi.h>
 #include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/string.h>
-#include <linux/irq.h>
-#include <linux/acpi.h>
 
 #include <asm/delay.h>
 #include <asm/hw_irq.h>
@@ -83,7 +86,6 @@
 
 
 #undef DEBUG_INTERRUPT_ROUTING
-#undef OVERRIDE_DEBUG
 
 #ifdef DEBUG_INTERRUPT_ROUTING
 #define DBG(fmt...)	printk(fmt)
@@ -115,23 +117,26 @@
 	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;
+} iosapic_lists[256];
 
-static int __devinitdata num_iosapic = 0;
+static int num_iosapic;
+
+static unsigned char pcat_compat __initdata;	/* 8259 compatibility flag */
 
 
 /*
  * Find an IOSAPIC associated with a GSI
  */
-static inline int __devinit
+static inline int
 find_iosapic (unsigned int gsi)
 {
 	int i;
 
-	for (i = 0; i < num_iosapic; i++)
+	for (i = 0; i < num_iosapic; i++) {
 		if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
 			return i;
+	}
+
 	return -1;
 }
 
@@ -159,6 +164,8 @@
 	int rte_index;
 	char redir;
 
+	DBG(KERN_DEBUG "IOSAPIC: routing vector %d to 0x%x\n", vector, dest);
+
 	rte_index = iosapic_intr_info[vector].rte_index;
 	if (rte_index < 0)
 		return;		/* not an IOSAPIC interrupt */
@@ -171,7 +178,7 @@
 	redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
 #ifdef CONFIG_SMP
 	{
-		int irq;
+		unsigned int irq;
 
 		for (irq = 0; irq < NR_IRQS; ++irq)
 			if (irq_to_vector(irq) == vector) {
@@ -333,14 +340,14 @@
 #define iosapic_ack_level_irq		nop
 
 struct hw_interrupt_type irq_type_iosapic_level = {
-	typename:	"IO-SAPIC-level",
-	startup:	iosapic_startup_level_irq,
-	shutdown:	iosapic_shutdown_level_irq,
-	enable:		iosapic_enable_level_irq,
-	disable:	iosapic_disable_level_irq,
-	ack:		iosapic_ack_level_irq,
-	end:		iosapic_end_level_irq,
-	set_affinity:	iosapic_set_affinity
+	.typename =	"IO-SAPIC-level",
+	.startup =	iosapic_startup_level_irq,
+	.shutdown =	iosapic_shutdown_level_irq,
+	.enable =	iosapic_enable_level_irq,
+	.disable =	iosapic_disable_level_irq,
+	.ack =		iosapic_ack_level_irq,
+	.end =		iosapic_end_level_irq,
+	.set_affinity =	iosapic_set_affinity
 };
 
 /*
@@ -377,14 +384,14 @@
 #define iosapic_end_edge_irq		nop
 
 struct hw_interrupt_type irq_type_iosapic_edge = {
-	typename:	"IO-SAPIC-edge",
-	startup:	iosapic_startup_edge_irq,
-	shutdown:	iosapic_disable_edge_irq,
-	enable:		iosapic_enable_edge_irq,
-	disable:	iosapic_disable_edge_irq,
-	ack:		iosapic_ack_edge_irq,
-	end:		iosapic_end_edge_irq,
-	set_affinity:	iosapic_set_affinity
+	.typename =	"IO-SAPIC-edge",
+	.startup =	iosapic_startup_edge_irq,
+	.shutdown =	iosapic_disable_edge_irq,
+	.enable =	iosapic_enable_edge_irq,
+	.disable =	iosapic_disable_edge_irq,
+	.ack =		iosapic_ack_edge_irq,
+	.end =		iosapic_end_edge_irq,
+	.set_affinity =	iosapic_set_affinity
 };
 
 unsigned int
@@ -407,7 +414,7 @@
  * if the given vector is already owned by other,
  *  assign a new vector for the other and make the vector available
  */
-static void
+static void __init
 iosapic_reassign_vector (int vector)
 {
 	int new_vector;
@@ -417,67 +424,52 @@
 	    || iosapic_intr_info[vector].polarity || iosapic_intr_info[vector].trigger)
 	{
 		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));
+		printk(KERN_INFO "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_intr (unsigned int gsi, int vector, unsigned char delivery,
-	       unsigned long polarity, unsigned long edge_triggered,
-	       unsigned int gsi_base, char *iosapic_address)
+	       unsigned long polarity, unsigned long trigger)
 {
 	irq_desc_t *idesc;
 	struct hw_interrupt_type *irq_type;
 	int rte_index;
+	int index;
+	unsigned long gsi_base;
+	char *iosapic_address;
+
+	index = find_iosapic(gsi);
+	if (index < 0) {
+		printk(KERN_WARNING "%s: No IOSAPIC for GSI 0x%x\n", __FUNCTION__, gsi);
+		return;
+	}
+
+	iosapic_address = iosapic_lists[index].addr;
+	gsi_base = iosapic_lists[index].gsi_base;
 
 	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].polarity = polarity;
 	iosapic_intr_info[vector].dmode    = delivery;
+	iosapic_intr_info[vector].addr     = iosapic_address;
+	iosapic_intr_info[vector].gsi_base = gsi_base;
+	iosapic_intr_info[vector].trigger  = trigger;
 
-	/*
-	 * 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_intr_info[vector].addr = iosapic_address;
-		iosapic_intr_info[vector].gsi_base = gsi_base;
-	}
-#else
-	if (iosapic_address) {
-		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_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_intr_info[vector].trigger = IOSAPIC_EDGE;
+	if (trigger == IOSAPIC_EDGE)
 		irq_type = &irq_type_iosapic_edge;
-	} else {
-		iosapic_intr_info[vector].trigger = IOSAPIC_LEVEL;
+	else
 		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);
+			printk(KERN_WARNING "%s: changing vector %d from %s to %s\n",
+			       __FUNCTION__, vector, idesc->handler->typename, irq_type->typename);
 		idesc->handler = irq_type;
 	}
 }
@@ -489,8 +481,7 @@
  */
 int
 iosapic_register_intr (unsigned int gsi,
-		       unsigned long polarity, unsigned long edge_triggered,
-		       unsigned int gsi_base, char *iosapic_address)
+		       unsigned long polarity, unsigned long trigger)
 {
 	int vector;
 	unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
@@ -500,11 +491,11 @@
 		vector = ia64_alloc_vector();
 
 	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
-		      polarity, edge_triggered, gsi_base, iosapic_address);
+		      polarity, trigger);
 
-	printk("GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
-	       gsi, (polarity ? "high" : "low"),
-	       (edge_triggered ? "edge" : "level"), dest, vector);
+	printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	       gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+	       (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
 
 	/* program the IOSAPIC routing table */
 	set_rte(vector, dest);
@@ -515,11 +506,10 @@
  * ACPI calls this when it finds an entry for a platform interrupt.
  * Note that the irq_base and IOSAPIC address must be set in iosapic_init().
  */
-int
+int __init
 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 long polarity, unsigned long trigger)
 {
 	unsigned char delivery;
 	int vector;
@@ -544,17 +534,16 @@
 		delivery = IOSAPIC_LOWEST_PRIORITY;
 		break;
 	      default:
-		printk("%s: invalid interrupt type (%d)\n", __FUNCTION__,
+		printk(KERN_ERR "%s: invalid interrupt type (%d)\n", __FUNCTION__,
 			int_type);
 		return -1;
 	}
 
-	register_intr(gsi, vector, delivery, polarity,
-		      edge_triggered, gsi_base, iosapic_address);
+	register_intr(gsi, vector, delivery, polarity, trigger);
 
-	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);
+	printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	       int_type, gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+	       (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
 
 	/* program the IOSAPIC routing table */
 	set_rte(vector, dest);
@@ -566,32 +555,20 @@
  * 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
+void __init
 iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
-			  unsigned long polarity, unsigned long edge_triggered)
+			  unsigned long polarity, unsigned long trigger)
 {
-	int index, vector;
-	unsigned int gsi_base;
-	char *addr;
+	int vector;
 	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);
+	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
 
-	DBG("ISA: IRQ %u -> GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n",
 	    isa_irq, gsi,
-	    polarity ? "high" : "low", edge_triggered ? "edge" : "level",
+	    polarity == IOSAPIC_POL_HIGH ? "high" : "low", trigger == IOSAPIC_EDGE ? "edge" : "level",
 	    dest, vector);
 
 	/* program the IOSAPIC routing table */
@@ -624,13 +601,11 @@
 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;
+	int vector;
 	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",
+		printk(KERN_ERR "PCI: no interrupt route for %02x:%02x:%02x pin %c\n",
 			segment, bus, slot, 'A' + pci_pin);
 		return -1;
 	}
@@ -638,19 +613,7 @@
 	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;
-
+		/* allocate a vector for this interrupt line */
 		if (pcat_compat && (gsi < 16))
 			vector = isa_irq_to_vector(gsi);
 		else {
@@ -658,8 +621,7 @@
 			vector = ia64_alloc_vector();
 		}
 
-		register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
-			      0, 0, gsi_base, addr);
+		register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, IOSAPIC_LEVEL);
 
 		DBG("PCI: (%02x:%02x:%02x INT%c) -> GSI 0x%x -> vector %d\n",
 		    segment, bus, slot, 'A' + pci_pin, gsi, vector);
@@ -668,29 +630,32 @@
 	return vector;
 }
 
-void __devinit
-iosapic_init (unsigned long phys_addr, unsigned int gsi_base, int pcat_compat)
+void __init
+iosapic_system_init (int system_pcat_compat)
 {
-	int num_rte, vector;
-	unsigned int isa_irq, ver;
-	char *addr;
-	static int first_time = 1;
+	int vector;
 
-	if (first_time) {
-		first_time = 0;
-		for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
-			iosapic_intr_info[vector].rte_index = -1;	/* mark as unused */
-	}
+	for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
+		iosapic_intr_info[vector].rte_index = -1;	/* mark as unused */
 
+	pcat_compat = system_pcat_compat;
 	if (pcat_compat) {
 		/*
 		 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
 		 * enabled.
 		 */
-		printk("%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__);
+		printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__);
 		outb(0xff, 0xA1);
 		outb(0xff, 0x21);
 	}
+}
+
+void __init
+iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
+{
+	int num_rte;
+	unsigned int isa_irq, ver;
+	char *addr;
 
 	addr = ioremap(phys_addr, 0);
 	ver = iosapic_version(addr);
@@ -703,35 +668,22 @@
 	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",
+	printk(KERN_INFO "  IOSAPIC v%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;
 
 		/*
 		 * 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 (isa_irq = 0; isa_irq < 16; ++isa_irq) {
-			vector = isa_irq_to_vector(isa_irq);
-
-			register_intr(isa_irq, vector, IOSAPIC_LOWEST_PRIORITY,
-				     /* IOSAPIC_POL_HIGH, IOSAPIC_EDGE */
-				     1, 1, gsi_base, addr);
-
-			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, dest);
-		}
+		for (isa_irq = 0; isa_irq < 16; ++isa_irq)
+			iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
 	}
 }
 
@@ -790,7 +742,7 @@
 			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",
+					printk(KERN_INFO "%s: changing vector %d from %s to %s\n",
 					       __FUNCTION__, vector,
 					       idesc->handler->typename,
 					       irq_type->typename);
@@ -822,7 +774,7 @@
 			dest = (ia64_get_lid() >> 16) & 0xffff;
 #endif
 
-			printk("PCI->APIC IRQ transform: (%s INT%c) -> CPU 0x%04x vector %d\n",
+			printk(KERN_INFO "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);
 		}
@@ -837,7 +789,7 @@
 
 	if (phase == 0) {
 		if (0 != acpi_get_prt(&pci_irq.route, &pci_irq.num_routes)) {
-			printk("%s: acpi_get_prt failed\n", __FUNCTION__);
+			printk(KERN_ERR "%s: acpi_get_prt failed\n", __FUNCTION__);
 		}
 		return;
 	}
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/irq.c linux-2.4.22-pre3/arch/ia64/kernel/irq.c
--- linux-2.4.22-pre2/arch/ia64/kernel/irq.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/irq.c	2003-07-05 18:09:37.000000000 -0700
@@ -111,7 +111,7 @@
  * a generic callback i think.
  */
 #if CONFIG_X86
-	printk("unexpected IRQ trap at vector %02x\n", irq);
+	printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
 	 * Currently unexpected vectors happen only on SMP and APIC.
@@ -125,7 +125,7 @@
 #endif
 #endif
 #if CONFIG_IA64
-	printk("Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
+	printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
 #endif
 }
 
@@ -591,7 +591,7 @@
 		desc->depth--;
 		break;
 	case 0:
-		printk("enable_irq(%u) unbalanced from %p\n",
+		printk(KERN_ERR "enable_irq(%u) unbalanced from %p\n",
 		       irq, (void *) __builtin_return_address(0));
 	}
 	spin_unlock_irqrestore(&desc->lock, flags);
@@ -738,7 +738,7 @@
 	 */
 	if (irqflags & SA_SHIRQ) {
 		if (!dev_id)
-			printk("Bad boy: %s called us without a dev_id!\n", devname);
+			printk(KERN_ERR "Bad boy: %s called us without a dev_id!\n", devname);
 	}
 #endif
 
@@ -819,7 +819,7 @@
 			kfree(action);
 			return;
 		}
-		printk("Trying to free free IRQ%d\n",irq);
+		printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
 		spin_unlock_irqrestore(&desc->lock,flags);
 		return;
 	}
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/irq_ia64.c linux-2.4.22-pre3/arch/ia64/kernel/irq_ia64.c
--- linux-2.4.22-pre2/arch/ia64/kernel/irq_ia64.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/irq_ia64.c	2003-07-05 18:09:37.000000000 -0700
@@ -148,9 +148,9 @@
 extern void handle_IPI (int irq, void *dev_id, struct pt_regs *regs);
 
 static struct irqaction ipi_irqaction = {
-	handler:	handle_IPI,
-	flags:		SA_INTERRUPT,
-	name:		"IPI"
+	.handler =	handle_IPI,
+	.flags =	SA_INTERRUPT,
+	.name =		"IPI"
 };
 #endif
 
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/irq_lsapic.c linux-2.4.22-pre3/arch/ia64/kernel/irq_lsapic.c
--- linux-2.4.22-pre2/arch/ia64/kernel/irq_lsapic.c	2001-07-31 10:30:08.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/irq_lsapic.c	2003-07-05 18:09:37.000000000 -0700
@@ -27,12 +27,12 @@
 }
 
 struct hw_interrupt_type irq_type_ia64_lsapic = {
-	typename:	"LSAPIC",
-	startup:	lsapic_noop_startup,
-	shutdown:	lsapic_noop,
-	enable:		lsapic_noop,
-	disable:	lsapic_noop,
-	ack:		lsapic_noop,
-	end:		lsapic_noop,
-	set_affinity:	(void (*)(unsigned int, unsigned long)) lsapic_noop
+	.typename =	"LSAPIC",
+	.startup =	lsapic_noop_startup,
+	.shutdown =	lsapic_noop,
+	.enable =	lsapic_noop,
+	.disable =	lsapic_noop,
+	.ack =		lsapic_noop,
+	.end =		lsapic_noop,
+	.set_affinity =	(void (*)(unsigned int, unsigned long)) lsapic_noop
 };
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/machvec.c linux-2.4.22-pre3/arch/ia64/kernel/machvec.c
--- linux-2.4.22-pre2/arch/ia64/kernel/machvec.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/machvec.c	2003-07-05 18:09:37.000000000 -0700
@@ -44,7 +44,7 @@
 		panic("generic kernel failed to find machine vector for platform %s!", name);
 	}
 	ia64_mv = *mv;
-	printk("booting generic kernel on platform %s\n", name);
+	printk(KERN_INFO "booting generic kernel on platform %s\n", name);
 }
 
 #endif /* CONFIG_IA64_GENERIC */
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/mca.c linux-2.4.22-pre3/arch/ia64/kernel/mca.c
--- linux-2.4.22-pre2/arch/ia64/kernel/mca.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/mca.c	2003-07-05 18:09:37.000000000 -0700
@@ -3,6 +3,9 @@
  * Purpose:	Generic MCA handling layer
  *
  * Updated for latest kernel
+ * Copyright (C) 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *
  * Copyright (C) 2002 Dell Computer Corporation
  * Copyright (C) Matt Domsch (Matt_Domsch@dell.com)
  *
@@ -18,6 +21,7 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) Vijay Chander(vijay@engr.sgi.com)
  *
+ * 03/04/15 D. Mosberger Added INIT backtrace support.
  * 02/03/25 M. Domsch	GUID cleanups
  *
  * 02/01/04 J. Hall	Aligned MCA stack to 16 bytes, added platform vs. CPU
@@ -45,7 +49,9 @@
 #include <linux/timer.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/smp.h>
 
+#include <asm/delay.h>
 #include <asm/machvec.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
@@ -53,11 +59,14 @@
 #include <asm/sal.h>
 #include <asm/mca.h>
 
+#include <asm/processor.h>
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
 
 #undef MCA_PRT_XTRA_DATA
 
+#define print_symbol(fmt, addr)	printk(fmt, "");
+
 typedef struct ia64_fptr {
 	unsigned long fp;
 	unsigned long gp;
@@ -70,7 +79,7 @@
 u64				ia64_mca_stack[1024] __attribute__((aligned(16)));
 u64				ia64_mca_stackframe[32];
 u64				ia64_mca_bspstore[1024];
-u64				ia64_init_stack[INIT_TASK_SIZE] __attribute__((aligned(16)));
+u64				ia64_init_stack[INIT_TASK_SIZE/8] __attribute__((aligned(16)));
 u64				ia64_mca_sal_data_area[1356];
 u64				ia64_tlb_functional;
 u64				ia64_os_mca_recovery_successful;
@@ -85,40 +94,50 @@
 extern struct hw_interrupt_type	irq_type_iosapic_level;
 
 static struct irqaction cmci_irqaction = {
-	handler:    ia64_mca_cmc_int_handler,
-	flags:      SA_INTERRUPT,
-	name:       "cmc_hndlr"
+	.handler =	ia64_mca_cmc_int_handler,
+	.flags =	SA_INTERRUPT,
+	.name =		"cmc_hndlr"
 };
 
 static struct irqaction mca_rdzv_irqaction = {
-	handler:    ia64_mca_rendez_int_handler,
-	flags:      SA_INTERRUPT,
-	name:       "mca_rdzv"
+	.handler =	ia64_mca_rendez_int_handler,
+	.flags =	SA_INTERRUPT,
+	.name =		"mca_rdzv"
 };
 
 static struct irqaction mca_wkup_irqaction = {
-	handler:    ia64_mca_wakeup_int_handler,
-	flags:      SA_INTERRUPT,
-	name:       "mca_wkup"
+	.handler =	ia64_mca_wakeup_int_handler,
+	.flags =	SA_INTERRUPT,
+	.name =		"mca_wkup"
 };
 
 static struct irqaction mca_cpe_irqaction = {
-	handler:    ia64_mca_cpe_int_handler,
-	flags:      SA_INTERRUPT,
-	name:       "cpe_hndlr"
+	.handler =	ia64_mca_cpe_int_handler,
+	.flags =	SA_INTERRUPT,
+	.name =		"cpe_hndlr"
 };
 
 #define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */
 #define MIN_CPE_POLL_INTERVAL (2*60*HZ)  /* 2 minutes */
+#define CMC_POLL_INTERVAL     (1*60*HZ)  /* 1 minute */
+#define CMC_HISTORY_LENGTH    5
 
 static struct timer_list cpe_poll_timer;
+static struct timer_list cmc_poll_timer;
+/*
+ * Start with this in the wrong state so we won't play w/ timers
+ * before the system is ready.
+ */
+static int cmc_polling_enabled = 1;
+
+extern void salinfo_log_wakeup(int);
 
 /*
  *  ia64_mca_log_sal_error_record
  *
- *  This function retrieves a specified error record type from SAL, sends it to
- *  the system log, and notifies SALs to clear the record from its non-volatile
- *  memory.
+ *  This function retrieves a specified error record type from SAL,
+ *  wakes up any processes waiting for error records, and sends it to
+ *  the system log.
  *
  *  Inputs  :   sal_info_type   (Type of error record MCA/CMC/CPE/INIT)
  *  Outputs :   platform error status
@@ -130,7 +149,7 @@
 
 	/* Get the MCA error record */
 	if (!ia64_log_get(sal_info_type, (prfunc_t)printk))
-		return platform_err;                 // no record retrieved
+		return platform_err;		/* no record retrieved */
 
 	/* TODO:
 	 * 1. analyze error logs to determine recoverability
@@ -138,11 +157,8 @@
 	 * 3. set ia64_os_mca_recovery_successful flag, if applicable
 	 */
 
+	salinfo_log_wakeup(sal_info_type);
 	platform_err = ia64_log_print(sal_info_type, (prfunc_t)printk);
-	/* temporary: only clear SAL logs on hardware-corrected errors
-		or if we're logging an error after an MCA-initiated reboot */
-	if ((sal_info_type > 1) || (called_from_init))
-		ia64_sal_clear_state_info(sal_info_type);
 
 	return platform_err;
 }
@@ -160,24 +176,174 @@
 void
 ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
 {
-	IA64_MCA_DEBUG("ia64_mca_cpe_int_handler: received interrupt. vector = %#x\n", cpe_irq);
+	IA64_MCA_DEBUG("ia64_mca_cpe_int_handler: received interrupt. CPU:%d vector = %#x\n",
+		       smp_processor_id(), cpe_irq);
 
 	/* Get the CMC error record and log it */
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE, 0);
 }
 
-/*
- * This routine will be used to deal with platform specific handling
- * of the init, i.e. drop into the kernel debugger on server machine,
- * or if the processor is part of some parallel machine without a
- * console, then we would call the appropriate debug hooks here.
- */
+static void
+show_min_state (pal_min_state_area_t *minstate)
+{
+	u64 iip = minstate->pmsa_iip + ((struct ia64_psr *)(&minstate->pmsa_ipsr))->ri;
+	u64 xip = minstate->pmsa_xip + ((struct ia64_psr *)(&minstate->pmsa_xpsr))->ri;
+
+	printk("NaT bits\t%016lx\n", minstate->pmsa_nat_bits);
+	printk("pr\t\t%016lx\n", minstate->pmsa_pr);
+	printk("b0\t\t%016lx ", minstate->pmsa_br0); print_symbol("%s\n", minstate->pmsa_br0);
+	printk("ar.rsc\t\t%016lx\n", minstate->pmsa_rsc);
+	printk("cr.iip\t\t%016lx ", iip); print_symbol("%s\n", iip);
+	printk("cr.ipsr\t\t%016lx\n", minstate->pmsa_ipsr);
+	printk("cr.ifs\t\t%016lx\n", minstate->pmsa_ifs);
+	printk("xip\t\t%016lx ", xip); print_symbol("%s\n", xip);
+	printk("xpsr\t\t%016lx\n", minstate->pmsa_xpsr);
+	printk("xfs\t\t%016lx\n", minstate->pmsa_xfs);
+	printk("b1\t\t%016lx ", minstate->pmsa_br1);
+	print_symbol("%s\n", minstate->pmsa_br1);
+
+	printk("\nstatic registers r0-r15:\n");
+	printk(" r0- 3 %016lx %016lx %016lx %016lx\n",
+	       0UL, minstate->pmsa_gr[0], minstate->pmsa_gr[1], minstate->pmsa_gr[2]);
+	printk(" r4- 7 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_gr[3], minstate->pmsa_gr[4],
+	       minstate->pmsa_gr[5], minstate->pmsa_gr[6]);
+	printk(" r8-11 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_gr[7], minstate->pmsa_gr[8],
+	       minstate->pmsa_gr[9], minstate->pmsa_gr[10]);
+	printk("r12-15 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_gr[11], minstate->pmsa_gr[12],
+	       minstate->pmsa_gr[13], minstate->pmsa_gr[14]);
+
+	printk("\nbank 0:\n");
+	printk("r16-19 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank0_gr[0], minstate->pmsa_bank0_gr[1],
+	       minstate->pmsa_bank0_gr[2], minstate->pmsa_bank0_gr[3]);
+	printk("r20-23 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank0_gr[4], minstate->pmsa_bank0_gr[5],
+	       minstate->pmsa_bank0_gr[6], minstate->pmsa_bank0_gr[7]);
+	printk("r24-27 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank0_gr[8], minstate->pmsa_bank0_gr[9],
+	       minstate->pmsa_bank0_gr[10], minstate->pmsa_bank0_gr[11]);
+	printk("r28-31 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank0_gr[12], minstate->pmsa_bank0_gr[13],
+	       minstate->pmsa_bank0_gr[14], minstate->pmsa_bank0_gr[15]);
+
+	printk("\nbank 1:\n");
+	printk("r16-19 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank1_gr[0], minstate->pmsa_bank1_gr[1],
+	       minstate->pmsa_bank1_gr[2], minstate->pmsa_bank1_gr[3]);
+	printk("r20-23 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank1_gr[4], minstate->pmsa_bank1_gr[5],
+	       minstate->pmsa_bank1_gr[6], minstate->pmsa_bank1_gr[7]);
+	printk("r24-27 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank1_gr[8], minstate->pmsa_bank1_gr[9],
+	       minstate->pmsa_bank1_gr[10], minstate->pmsa_bank1_gr[11]);
+	printk("r28-31 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank1_gr[12], minstate->pmsa_bank1_gr[13],
+	       minstate->pmsa_bank1_gr[14], minstate->pmsa_bank1_gr[15]);
+}
+
+static void
+fetch_min_state (pal_min_state_area_t *ms, struct pt_regs *pt, struct switch_stack *sw)
+{
+	u64 *dst_banked, *src_banked, bit, shift, nat_bits;
+	int i;
+
+	/*
+	 * First, update the pt-regs and switch-stack structures with the contents stored
+	 * in the min-state area:
+	 */
+	if (((struct ia64_psr *) &ms->pmsa_ipsr)->ic == 0) {
+		pt->cr_ipsr = ms->pmsa_xpsr;
+		pt->cr_iip = ms->pmsa_xip;
+		pt->cr_ifs = ms->pmsa_xfs;
+	} else {
+		pt->cr_ipsr = ms->pmsa_ipsr;
+		pt->cr_iip = ms->pmsa_iip;
+		pt->cr_ifs = ms->pmsa_ifs;
+	}
+	pt->ar_rsc = ms->pmsa_rsc;
+	pt->pr = ms->pmsa_pr;
+	pt->r1 = ms->pmsa_gr[0];
+	pt->r2 = ms->pmsa_gr[1];
+	pt->r3 = ms->pmsa_gr[2];
+	sw->r4 = ms->pmsa_gr[3];
+	sw->r5 = ms->pmsa_gr[4];
+	sw->r6 = ms->pmsa_gr[5];
+	sw->r7 = ms->pmsa_gr[6];
+	pt->r8 = ms->pmsa_gr[7];
+	pt->r9 = ms->pmsa_gr[8];
+	pt->r10 = ms->pmsa_gr[9];
+	pt->r11 = ms->pmsa_gr[10];
+	pt->r12 = ms->pmsa_gr[11];
+	pt->r13 = ms->pmsa_gr[12];
+	pt->r14 = ms->pmsa_gr[13];
+	pt->r15 = ms->pmsa_gr[14];
+	dst_banked = &pt->r16;		/* r16-r31 are contiguous in struct pt_regs */
+	src_banked = ms->pmsa_bank1_gr;
+	for (i = 0; i < 16; ++i)
+		dst_banked[i] = src_banked[i];
+	pt->b0 = ms->pmsa_br0;
+	sw->b1 = ms->pmsa_br1;
+
+	/* construct the NaT bits for the pt-regs structure: */
+#	define PUT_NAT_BIT(dst, addr)					\
+	do {								\
+		bit = nat_bits & 1; nat_bits >>= 1;			\
+		shift = ((unsigned long) addr >> 3) & 0x3f;		\
+		dst = ((dst) & ~(1UL << shift)) | (bit << shift);	\
+	} while (0)
+
+	/* Rotate the saved NaT bits such that bit 0 corresponds to pmsa_gr[0]: */
+	shift = ((unsigned long) &ms->pmsa_gr[0] >> 3) & 0x3f;
+	nat_bits = (ms->pmsa_nat_bits >> shift) | (ms->pmsa_nat_bits << (64 - shift));
+
+	PUT_NAT_BIT(sw->caller_unat, &pt->r1);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r2);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r3);
+	PUT_NAT_BIT(sw->ar_unat, &sw->r4);
+	PUT_NAT_BIT(sw->ar_unat, &sw->r5);
+	PUT_NAT_BIT(sw->ar_unat, &sw->r6);
+	PUT_NAT_BIT(sw->ar_unat, &sw->r7);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r8);	PUT_NAT_BIT(sw->caller_unat, &pt->r9);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r10);	PUT_NAT_BIT(sw->caller_unat, &pt->r11);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r12);	PUT_NAT_BIT(sw->caller_unat, &pt->r13);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r14);	PUT_NAT_BIT(sw->caller_unat, &pt->r15);
+	nat_bits >>= 16;	/* skip over bank0 NaT bits */
+	PUT_NAT_BIT(sw->caller_unat, &pt->r16);	PUT_NAT_BIT(sw->caller_unat, &pt->r17);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r18);	PUT_NAT_BIT(sw->caller_unat, &pt->r19);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r20);	PUT_NAT_BIT(sw->caller_unat, &pt->r21);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r22);	PUT_NAT_BIT(sw->caller_unat, &pt->r23);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r24);	PUT_NAT_BIT(sw->caller_unat, &pt->r25);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r26);	PUT_NAT_BIT(sw->caller_unat, &pt->r27);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r28);	PUT_NAT_BIT(sw->caller_unat, &pt->r29);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r30);	PUT_NAT_BIT(sw->caller_unat, &pt->r31);
+}
+
 void
-init_handler_platform (struct pt_regs *regs)
+init_handler_platform (sal_log_processor_info_t *proc_ptr,
+		       struct pt_regs *pt, struct switch_stack *sw)
 {
+	struct unw_frame_info info;
+
 	/* if a kernel debugger is available call it here else just dump the registers */
 
-	show_regs(regs);		/* dump the state info */
+	/*
+	 * Wait for a bit.  On some machines (e.g., HP's zx2000 and zx6000, INIT can be
+	 * generated via the BMC's command-line interface, but since the console is on the
+	 * same serial line, the user will need some time to switch out of the BMC before
+	 * the dump begins.
+	 */
+	printk("Delaying for 5 seconds...\n");
+	udelay(5*1000000);
+	show_min_state(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area);
+
+	fetch_min_state(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area, pt, sw);
+	unw_init_from_interruption(&info, current, pt, sw);
+	ia64_do_show_stack(&info, NULL);
+
+	printk("\nINIT dump complete.  Please reboot now.\n");
 	while (1);			/* hang city if no debugger */
 }
 
@@ -202,21 +368,22 @@
  *  ia64_mca_check_errors
  *
  *  External entry to check for error records which may have been posted by SAL
- *  for a prior failure which resulted in a machine shutdown before an the
- *  error could be logged.  This function must be called after the filesystem
- *  is initialized.
+ *  for a prior failure.
  *
  *  Inputs  :   None
  *
  *  Outputs :   None
  */
-void
+int
 ia64_mca_check_errors (void)
 {
 	/*
 	 *  If there is an MCA error record pending, get it and log it.
 	 */
+	printk("CPU %d: checking for saved MCA error records\n", smp_processor_id());
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA, 1);
+
+	return 0;
 }
 
 /*
@@ -234,8 +401,11 @@
 ia64_mca_register_cpev (int cpev)
 {
 	/* Register the CPE interrupt vector with SAL */
-	if (ia64_sal_mc_set_params(SAL_MC_PARAM_CPE_INT, SAL_MC_PARAM_MECHANISM_INT, cpev, 0, 0)) {
-		printk("ia64_mca_platform_init: failed to register Corrected "
+	struct ia64_sal_retval isrv;
+
+	isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_CPE_INT, SAL_MC_PARAM_MECHANISM_INT, cpev, 0, 0);
+	if (isrv.status) {
+		printk(KERN_ERR "ia64_mca_platform_init: failed to register Corrected "
 		       "Platform Error interrupt vector with SAL.\n");
 		return;
 	}
@@ -246,26 +416,9 @@
 
 #endif /* PLATFORM_MCA_HANDLERS */
 
-static char *min_state_labels[] = {
-	"nat",
-	"r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
-	"r9", "r10","r11", "r12","r13","r14", "r15",
-	"b0r16","b0r17", "b0r18", "b0r19", "b0r20",
-	"b0r21", "b0r22","b0r23", "b0r24", "b0r25",
-	"b0r26", "b0r27", "b0r28","b0r29", "b0r30", "b0r31",
-	"r16", "r17", "r18","r19", "r20", "r21","r22",
-	"r23", "r24","r25", "r26", "r27","r28", "r29", "r30","r31",
-	"preds", "br0", "rsc",
-	"iip", "ipsr", "ifs",
-	"xip", "xpsr", "xfs"
-};
-
-int ia64_pmss_dump_bank0=0;  /* dump bank 0 ? */
-
 /*
  * routine to process and prepare to dump min_state_save
  * information for debugging purposes.
- *
  */
 void
 ia64_process_min_state_save (pal_min_state_area_t *pmss)
@@ -274,30 +427,12 @@
 	u64 *tpmss_ptr = (u64 *)pmss;
 	u64 *return_min_state_ptr = ia64_mca_min_state_save_info;
 
-	/* dump out the min_state_area information */
-
 	for (i=0;i<max;i++) {
 
 		/* copy min-state register info for eventual return to PAL */
 		*return_min_state_ptr++ = *tpmss_ptr;
 
-#if 1
 		tpmss_ptr++;  /* skip to next entry */
-#else
-		/* the printing part */
-		if(!ia64_pmss_dump_bank0) {
-			if(strncmp("B0",min_state_labels[i],2)==0) {
-				tpmss_ptr++;  /* skip to next entry */
-				continue;
-			}
-		}
-
-		printk("%5s=0x%16.16lx ",min_state_labels[i],*tpmss_ptr++);
-
-		if (((i+1)%3)==0 || ((!strcmp("GR16",min_state_labels[i]))
-				     && !ia64_pmss_dump_bank0))
-			printk("\n");
-#endif
 	}
 }
 
@@ -331,6 +466,60 @@
 		       smp_processor_id(), ia64_get_cmcv());
 }
 
+/*
+ * ia64_mca_cmc_vector_disable
+ *
+ *  Mask the corrected machine check vector register in the processor.
+ *  This function is invoked on a per-processor basis.
+ *
+ * Inputs
+ *      dummy(unused)
+ *
+ * Outputs
+ *	None
+ */
+void
+ia64_mca_cmc_vector_disable (void *dummy)
+{
+	cmcv_reg_t	cmcv;
+	
+	cmcv = (cmcv_reg_t)ia64_get_cmcv();
+
+	cmcv.cmcv_mask = 1; /* Mask/disable interrupt */
+	ia64_set_cmcv(cmcv.cmcv_regval);
+
+	IA64_MCA_DEBUG("ia64_mca_cmc_vector_disable: CPU %d corrected "
+		       "machine check vector %#x disabled.\n",
+		       smp_processor_id(), cmcv.cmcv_vector);
+}
+
+/*
+ * ia64_mca_cmc_vector_enable
+ *
+ *  Unmask the corrected machine check vector register in the processor.
+ *  This function is invoked on a per-processor basis.
+ *
+ * Inputs
+ *      dummy(unused)
+ *
+ * Outputs
+ *	None
+ */
+void
+ia64_mca_cmc_vector_enable (void *dummy)
+{
+	cmcv_reg_t	cmcv;
+	
+	cmcv = (cmcv_reg_t)ia64_get_cmcv();
+
+	cmcv.cmcv_mask = 0; /* Unmask/enable interrupt */
+	ia64_set_cmcv(cmcv.cmcv_regval);
+
+	IA64_MCA_DEBUG("ia64_mca_cmc_vector_enable: CPU %d corrected "
+		       "machine check vector %#x enabled.\n",
+		       smp_processor_id(), cmcv.cmcv_vector);
+}
+
 
 #if defined(MCA_TEST)
 
@@ -413,6 +602,8 @@
 	ia64_fptr_t *mca_hldlr_ptr = (ia64_fptr_t *)ia64_os_mca_dispatch;
 	int i;
 	s64 rc;
+	struct ia64_sal_retval isrv;
+	u64 timeout = IA64_MCA_RENDEZ_TIMEOUT;	/* platform specific */
 
 	IA64_MCA_DEBUG("ia64_mca_init: begin\n");
 
@@ -428,25 +619,35 @@
 	 */
 
 	/* Register the rendezvous interrupt vector with SAL */
-	if ((rc = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_INT,
-					 SAL_MC_PARAM_MECHANISM_INT,
-					 IA64_MCA_RENDEZ_VECTOR,
-					 IA64_MCA_RENDEZ_TIMEOUT,
-					 0)))
-	{
-		printk("ia64_mca_init: Failed to register rendezvous interrupt "
+	while (1) {
+		isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_INT,
+					      SAL_MC_PARAM_MECHANISM_INT,
+					      IA64_MCA_RENDEZ_VECTOR,
+					      timeout,
+					      SAL_MC_PARAM_RZ_ALWAYS);
+		rc = isrv.status;
+		if (rc == 0)
+			break;
+		if (rc == -2) {
+			printk(KERN_INFO "ia64_mca_init: increasing MCA rendezvous timeout from "
+				"%ld to %ld\n", timeout, isrv.v0);
+			timeout = isrv.v0;
+			continue;
+		}
+		printk(KERN_ERR "ia64_mca_init: Failed to register rendezvous interrupt "
 		       "with SAL.  rc = %ld\n", rc);
 		return;
 	}
 
 	/* Register the wakeup interrupt vector with SAL */
-	if ((rc = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_WAKEUP,
-					 SAL_MC_PARAM_MECHANISM_INT,
-					 IA64_MCA_WAKEUP_VECTOR,
-					 0, 0)))
-	{
-		printk("ia64_mca_init: Failed to register wakeup interrupt with SAL.  rc = %ld\n",
-		       rc);
+	isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_WAKEUP,
+				      SAL_MC_PARAM_MECHANISM_INT,
+				      IA64_MCA_WAKEUP_VECTOR,
+				      0, 0);
+	rc = isrv.status;
+	if (rc) {
+		printk(KERN_ERR "ia64_mca_init: Failed to register wakeup interrupt with SAL.  "
+		       "rc = %ld\n", rc);
 		return;
 	}
 
@@ -466,8 +667,8 @@
 				       ia64_mc_info.imi_mca_handler_size,
 				       0, 0, 0)))
 	{
-		printk("ia64_mca_init: Failed to register os mca handler with SAL.  rc = %ld\n",
-		       rc);
+		printk(KERN_ERR "ia64_mca_init: Failed to register os mca handler with SAL.  "
+		       "rc = %ld\n", rc);
 		return;
 	}
 
@@ -495,8 +696,8 @@
 				       __pa(ia64_get_gp()),
 				       ia64_mc_info.imi_slave_init_handler_size)))
 	{
-		printk("ia64_mca_init: Failed to register m/s init handlers with SAL. rc = %ld\n",
-		       rc);
+		printk(KERN_ERR "ia64_mca_init: Failed to register m/s init handlers with SAL. "
+		       "rc = %ld\n", rc);
 		return;
 	}
 
@@ -546,7 +747,7 @@
 	mca_test();
 #endif /* #if defined(MCA_TEST) */
 
-	printk("Mca related initialization done\n");
+	printk(KERN_INFO "Mca related initialization done\n");
 
 	/* commented out because this is done elsewhere */
 #if 0
@@ -640,13 +841,12 @@
 void
 ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
 {
-	int flags, cpu = 0;
+	int flags;
+	int cpu = smp_processor_id();
+
 	/* Mask all interrupts */
 	save_and_cli(flags);
 
-#ifdef CONFIG_SMP
-	cpu = cpu_logical_id(hard_smp_processor_id());
-#endif
 	ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
 	/* Register with the SAL monarch that the slave has
 	 * reached SAL
@@ -719,7 +919,7 @@
 
 	/* Register pointer to new min state values */
 	ia64_os_to_sal_handoff_state.imots_new_min_state =
-		(pal_min_state_area_t *)ia64_mca_min_state_save_info;
+		ia64_mca_min_state_save_info;
 }
 
 /*
@@ -780,11 +980,68 @@
 void
 ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
 {
+	static unsigned long	cmc_history[CMC_HISTORY_LENGTH];
+	static int		index;
+	static spinlock_t	cmc_history_lock = SPIN_LOCK_UNLOCKED;
+
 	IA64_MCA_DEBUG("ia64_mca_cmc_int_handler: received interrupt vector = %#x on CPU %d\n",
 		       cmc_irq, smp_processor_id());
 
 	/* Get the CMC error record and log it */
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC, 0);
+
+	spin_lock(&cmc_history_lock);
+	if (!cmc_polling_enabled) {
+		int i, count = 1; /* we know 1 happened now */
+		unsigned long now = jiffies;
+		
+		for (i = 0; i < CMC_HISTORY_LENGTH; i++) {
+			if (now - cmc_history[i] <= HZ)
+				count++;
+		}
+
+		IA64_MCA_DEBUG(KERN_INFO "CMC threshold %d/%d\n", count, CMC_HISTORY_LENGTH);
+		if (count >= CMC_HISTORY_LENGTH) {
+			/*
+			 * CMC threshold exceeded, clear the history
+			 * so we have a fresh start when we return
+			 */
+			for (index = 0 ; index < CMC_HISTORY_LENGTH; index++)
+				cmc_history[index] = 0;
+			index = 0;
+
+			/* Switch to polling mode */
+			cmc_polling_enabled = 1;
+
+			/*
+			 * Unlock & enable interrupts  before
+			 * smp_call_function or risk deadlock
+			 */
+			spin_unlock(&cmc_history_lock);
+			ia64_mca_cmc_vector_disable(NULL);
+
+			local_irq_enable();
+			smp_call_function(ia64_mca_cmc_vector_disable, NULL, 1, 1);
+
+			/*
+			 * Corrected errors will still be corrected, but
+			 * make sure there's a log somewhere that indicates
+			 * something is generating more than we can handle.
+			 */
+			printk(KERN_WARNING "ia64_mca_cmc_int_handler: WARNING: Switching to polling CMC handler, error records may be lost\n");
+			
+
+			mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
+
+			/* lock already released, get out now */
+			return;
+		} else {
+			cmc_history[index++] = now;
+			if (index == CMC_HISTORY_LENGTH)
+				index = 0;
+		}
+	}
+	spin_unlock(&cmc_history_lock);
 }
 
 /*
@@ -797,6 +1054,7 @@
 {
 	spinlock_t	isl_lock;
 	int		isl_index;
+	unsigned long	isl_count;
 	ia64_err_rec_t  *isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */
 } ia64_state_log_t;
 
@@ -813,11 +1071,78 @@
 #define IA64_LOG_NEXT_INDEX(it)    ia64_state_log[it].isl_index
 #define IA64_LOG_CURR_INDEX(it)    1 - ia64_state_log[it].isl_index
 #define IA64_LOG_INDEX_INC(it) \
-    ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index
+    {ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index; \
+    ia64_state_log[it].isl_count++;}
 #define IA64_LOG_INDEX_DEC(it) \
     ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index
 #define IA64_LOG_NEXT_BUFFER(it)   (void *)((ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)]))
 #define IA64_LOG_CURR_BUFFER(it)   (void *)((ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)]))
+#define IA64_LOG_COUNT(it)         ia64_state_log[it].isl_count
+
+/*
+ *  ia64_mca_cmc_int_caller
+ *
+ * 	Call CMC interrupt handler, only purpose is to have a
+ * 	smp_call_function callable entry.
+ *
+ * Inputs   :	dummy(unused)
+ * Outputs  :	None
+ * */
+static void
+ia64_mca_cmc_int_caller(void *dummy)
+{
+	ia64_mca_cmc_int_handler(0, NULL, NULL);
+}
+
+/*
+ *  ia64_mca_cmc_poll
+ *
+ *	Poll for Corrected Machine Checks (CMCs)
+ *
+ * Inputs   :   dummy(unused)
+ * Outputs  :   None
+ *
+ */
+static void
+ia64_mca_cmc_poll (unsigned long dummy)
+{
+	int start_count;
+
+	start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC);
+
+	/* Call the interrupt handler */
+	smp_call_function(ia64_mca_cmc_int_caller, NULL, 1, 1);
+	local_irq_disable();
+	ia64_mca_cmc_int_caller(NULL);
+	local_irq_enable();
+
+	/*
+	 * If no log recored, switch out of polling mode.
+	 */
+	if (start_count == IA64_LOG_COUNT(SAL_INFO_TYPE_CMC)) {
+		printk(KERN_WARNING "ia64_mca_cmc_poll: Returning to interrupt driven CMC handler\n");
+		cmc_polling_enabled = 0;
+		smp_call_function(ia64_mca_cmc_vector_enable, NULL, 1, 1);
+		ia64_mca_cmc_vector_enable(NULL);
+	} else {
+		mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
+	}
+}
+
+/*
+ *  ia64_mca_cpe_int_caller
+ *
+ * 	Call CPE interrupt handler, only purpose is to have a
+ * 	smp_call_function callable entry.
+ *
+ * Inputs   :	dummy(unused)
+ * Outputs  :	None
+ * */
+static void
+ia64_mca_cpe_int_caller(void *dummy)
+{
+	ia64_mca_cpe_int_handler(0, NULL, NULL);
+}
 
 /*
  *  ia64_mca_cpe_poll
@@ -832,19 +1157,22 @@
 static void
 ia64_mca_cpe_poll (unsigned long dummy)
 {
-	int start_index;
+	int start_count;
 	static int poll_time = MAX_CPE_POLL_INTERVAL;
 
-	start_index = IA64_LOG_CURR_INDEX(SAL_INFO_TYPE_CPE);
+	start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CPE);
 
 	/* Call the interrupt handler */
-	ia64_mca_cpe_int_handler(0, NULL, NULL);
+	smp_call_function(ia64_mca_cpe_int_caller, NULL, 1, 1);
+	local_irq_disable();
+	ia64_mca_cpe_int_caller(NULL);
+	local_irq_enable();
 
 	/*
 	 * If a log was recorded, increase our polling frequency,
 	 * otherwise, backoff.
 	 */
-	if (start_index != IA64_LOG_CURR_INDEX(SAL_INFO_TYPE_CPE)) {
+	if (start_count != IA64_LOG_COUNT(SAL_INFO_TYPE_CPE)) {
 		poll_time = max(MIN_CPE_POLL_INTERVAL, poll_time/2);
 	} else {
 		poll_time = min(MAX_CPE_POLL_INTERVAL, poll_time * 2);
@@ -865,11 +1193,19 @@
 static int __init
 ia64_mca_late_init(void)
 {
-	if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0) {
-		init_timer(&cpe_poll_timer);
-		cpe_poll_timer.function = ia64_mca_cpe_poll;
-		ia64_mca_cpe_poll(0);
-	}
+	init_timer(&cmc_poll_timer);
+	cmc_poll_timer.function = ia64_mca_cmc_poll;
+
+	/* Reset to the correct state */
+	cmc_polling_enabled = 0;
+
+	init_timer(&cpe_poll_timer);
+	cpe_poll_timer.function = ia64_mca_cpe_poll;
+
+	/* If platform doesn't support CPEI, get the timer going. */
+	if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0)
+		ia64_mca_cpe_poll(0UL);
+
 	return 0;
 }
 
@@ -888,12 +1224,12 @@
  *
  */
 void
-ia64_init_handler (struct pt_regs *regs)
+ia64_init_handler (struct pt_regs *pt, struct switch_stack *sw)
 {
 	sal_log_processor_info_t *proc_ptr;
 	ia64_err_rec_t *plog_ptr;
 
-	printk("Entered OS INIT handler\n");
+	printk(KERN_INFO "Entered OS INIT handler\n");
 
 	/* Get the INIT processor log */
 	if (!ia64_log_get(SAL_INFO_TYPE_INIT, (prfunc_t)printk))
@@ -910,12 +1246,9 @@
 	plog_ptr=(ia64_err_rec_t *)IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_INIT);
 	proc_ptr = &plog_ptr->proc_err;
 
-	ia64_process_min_state_save(&proc_ptr->processor_static_info.min_state_area);
-
-	/* Clear the INIT SAL logs now that they have been saved in the OS buffer */
-	ia64_sal_clear_state_info(SAL_INFO_TYPE_INIT);
+	ia64_process_min_state_save(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area);
 
-	init_handler_platform(regs);              /* call platform specific routines */
+	init_handler_platform(proc_ptr, pt, sw);	/* call platform specific routines */
 }
 
 /*
@@ -1076,12 +1409,12 @@
 ia64_log_rec_header_print (sal_log_record_header_t *lh, prfunc_t prfunc)
 {
 	prfunc("+Err Record ID: %d    SAL Rev: %2x.%02x\n", lh->id,
-		lh->revision.major, lh->revision.minor);
-	prfunc("+Time: %02x/%02x/%02x%02x %02d:%02d:%02d    Severity %d\n",
-		lh->timestamp.slh_month, lh->timestamp.slh_day,
-		lh->timestamp.slh_century, lh->timestamp.slh_year,
-		lh->timestamp.slh_hour, lh->timestamp.slh_minute,
-		lh->timestamp.slh_second, lh->severity);
+			lh->revision.major, lh->revision.minor);
+	prfunc("+Time: %02x/%02x/%02x%02x %02x:%02x:%02x    Severity %d\n",
+			lh->timestamp.slh_month, lh->timestamp.slh_day,
+			lh->timestamp.slh_century, lh->timestamp.slh_year,
+			lh->timestamp.slh_hour, lh->timestamp.slh_minute,
+			lh->timestamp.slh_second, lh->severity);
 }
 
 /*
@@ -1704,7 +2037,7 @@
 	 *  absent. Also, current implementations only allocate space for number of
 	 *  elements used.  So we walk the data pointer from here on.
 	 */
-	p_data = &slpi->cache_check_info[0];
+	p_data = &slpi->info[0];
 
 	/* Print the cache check information if any*/
 	for (i = 0 ; i < slpi->valid.num_cache_check; i++, p_data++)
@@ -1821,8 +2154,7 @@
 		/*
 		 *  Now process processor device error record section
 		 */
-		ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh,
-						 printk);
+		ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh, printk);
 	}
 
 	IA64_MCA_DEBUG("ia64_mca_log_print: "
@@ -1965,9 +2297,8 @@
 
 	switch(sal_info_type) {
 	      case SAL_INFO_TYPE_MCA:
-		prfunc("+BEGIN HARDWARE ERROR STATE AT MCA\n");
-		platform_err = ia64_log_platform_info_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc);
-		prfunc("+END HARDWARE ERROR STATE AT MCA\n");
+		prfunc("+CPU %d: SAL log contains MCA error record\n", smp_processor_id());
+		ia64_log_rec_header_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc);
 		break;
 	      case SAL_INFO_TYPE_INIT:
 		prfunc("+MCA INIT ERROR LOG (UNIMPLEMENTED)\n");
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/mca_asm.S linux-2.4.22-pre3/arch/ia64/kernel/mca_asm.S
--- linux-2.4.22-pre2/arch/ia64/kernel/mca_asm.S	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/kernel/mca_asm.S	2003-07-05 18:09:37.000000000 -0700
@@ -766,8 +766,6 @@
 	// stash the information the SAL passed to os
 	SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2)
 	;;
-
-// now we want to save information so we can dump registers
 	SAVE_MIN_WITH_COVER
 	;;
 	mov r8=cr.ifa
@@ -798,10 +796,12 @@
 	//
 	// Let's call the C handler to get the rest of the state info
 	//
-	alloc r14=ar.pfs,0,0,1,0		// now it's safe (must be first in insn group!)
-	;;					//
+	alloc r14=ar.pfs,0,0,2,0		// now it's safe (must be first in insn group!)
+	;;
 	adds out0=16,sp				// out0 = pointer to pt_regs
 	;;
+	DO_SAVE_SWITCH_STACK
+	adds out1=16,sp				// out0 = pointer to switch_stack
 
 	br.call.sptk.many rp=ia64_init_handler
 .ret1:
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/palinfo.c linux-2.4.22-pre3/arch/ia64/kernel/palinfo.c
--- linux-2.4.22-pre2/arch/ia64/kernel/palinfo.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/kernel/palinfo.c	2003-07-05 18:09:37.000000000 -0700
@@ -6,7 +6,7 @@
  * Intel IA-64 Architecture Software Developer's Manual v1.0.
  *
  *
- * Copyright (C) 2000-2001 Hewlett-Packard Co
+ * Copyright (C) 2000-2001, 2003 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
  *
  * 05/26/2000	S.Eranian	initial release
@@ -27,9 +27,7 @@
 #include <asm/sal.h>
 #include <asm/page.h>
 #include <asm/processor.h>
-#ifdef CONFIG_SMP
 #include <linux/smp.h>
-#endif
 
 MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
 MODULE_DESCRIPTION("/proc interface to IA-64 PAL");
@@ -37,12 +35,6 @@
 
 #define PALINFO_VERSION "0.5"
 
-#ifdef CONFIG_SMP
-#define cpu_is_online(i) (cpu_online_map & (1UL << i))
-#else
-#define cpu_is_online(i)	1
-#endif
-
 typedef int (*palinfo_func_t)(char*);
 
 typedef struct {
@@ -101,26 +93,15 @@
 
 #define RSE_HINTS_COUNT (sizeof(rse_hints)/sizeof(const char *))
 
-/*
- * The current revision of the Volume 2 (July 2000) of
- * IA-64 Architecture Software Developer's Manual is wrong.
- * Table 4-10 has invalid information concerning the ma field:
- * Correct table is:
- *      bit 0 - 001 - UC
- *      bit 4 - 100 - UC
- *      bit 5 - 101 - UCE
- *      bit 6 - 110 - WC
- *      bit 7 - 111 - NatPage
- */
 static const char *mem_attrib[]={
-	"Write Back (WB)",		/* 000 */
-	"Uncacheable (UC)",		/* 001 */
-	"Reserved",			/* 010 */
-	"Reserved",			/* 011 */
-	"Uncacheable (UC)",		/* 100 */
-	"Uncacheable Exported (UCE)",	/* 101 */
-	"Write Coalescing (WC)",	/* 110 */
-	"NaTPage"			/* 111 */
+	"WB",		/* 000 */
+	"SW",		/* 001 */
+	"010",		/* 010 */
+	"011",		/* 011 */
+	"UC",		/* 100 */
+	"UCE",		/* 101 */
+	"WC",		/* 110 */
+	"NaTPage"	/* 111 */
 };
 
 /*
@@ -236,15 +217,12 @@
 	int i,j, k;
 	s64 status;
 
-	if ((status=ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
-			printk("ia64_pal_cache_summary=%ld\n", status);
-			return 0;
+	if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
+		printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status);
+		return 0;
 	}
 
-	p += sprintf(p, "Cache levels  : %ld\n" \
-			"Unique caches : %ld\n\n",
-			levels,
-			unique_caches);
+	p += sprintf(p, "Cache levels  : %ld\nUnique caches : %ld\n\n", levels, unique_caches);
 
 	for (i=0; i < levels; i++) {
 
@@ -315,11 +293,12 @@
 	pal_vm_info_2_u_t vm_info_2;
 	pal_tc_info_u_t	tc_info;
 	ia64_ptce_info_t ptce;
+	const char *sep;
 	int i, j;
 	s64 status;
 
-	if ((status=ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
-		printk("ia64_pal_vm_summary=%ld\n", status);
+	if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
+		printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
 		return 0;
 	}
 
@@ -339,18 +318,26 @@
 
 	if (ia64_pal_mem_attrib(&attrib) != 0) return 0;
 
-	p += sprintf(p, "Supported memory attributes    : %s\n", mem_attrib[attrib&0x7]);
+	p += sprintf(p, "Supported memory attributes    : ");
+	sep = "";
+	for (i = 0; i < 8; i++) {
+		if (attrib & (1 << i)) {
+			p += sprintf(p, "%s%s", sep, mem_attrib[i]);
+			sep = ", ";
+		}
+	}
+	p += sprintf(p, "\n");
 
-	if ((status=ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) {
-		printk("ia64_pal_vm_page_size=%ld\n", status);
+	if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) {
+		printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status);
 		return 0;
 	}
 
-	p += sprintf(p, "\nTLB walker                     : %s implemented\n" \
+	p += sprintf(p, "\nTLB walker                     : %simplemented\n" \
 			"Number of DTR                  : %d\n" \
 			"Number of ITR                  : %d\n" \
 			"TLB insertable page sizes      : ",
-			vm_info_1.pal_vm_info_1_s.vw ? "\b":"not",
+			vm_info_1.pal_vm_info_1_s.vw ? "" : "not ",
 			vm_info_1.pal_vm_info_1_s.max_dtr_entry+1,
 			vm_info_1.pal_vm_info_1_s.max_itr_entry+1);
 
@@ -362,7 +349,7 @@
 	p = bitvector_process(p, vw_pages);
 
 	if ((status=ia64_get_ptce(&ptce)) != 0) {
-		printk("ia64_get_ptce=%ld\n",status);
+		printk(KERN_ERR "ia64_get_ptce=%ld\n", status);
 		return 0;
 	}
 
@@ -712,8 +699,8 @@
 		u64 rv2:32;
 	} *rid_reg;
 
-	if ((status=ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
-		printk("ia64_pal_vm_summary=%ld\n", status);
+	if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
+		printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
 		return 0;
 	}
 	max[0] = vm_info_1.pal_vm_info_1_s.max_itr_entry+1;
@@ -724,7 +711,8 @@
 
 		status = ia64_pal_tr_read(j, i, tr_buffer, &tr_valid);
 		if (status != 0) {
-			printk("palinfo: pal call failed on tr[%d:%d]=%ld\n", i, j, status);
+			printk(KERN_ERR "palinfo: pal call failed on tr[%d:%d]=%ld\n",
+			       i, j, status);
 			continue;
 		}
 
@@ -843,7 +831,7 @@
 {
 	palinfo_smp_data_t *data = (palinfo_smp_data_t *)info;
 	if (data == NULL) {
-		printk("%s palinfo: data pointer is NULL\n", KERN_ERR);
+		printk(KERN_ERR "palinfo: data pointer is NULL\n");
 		data->ret = 0; /* no output */
 		return;
 	}
@@ -870,7 +858,8 @@
 
 	/* will send IPI to other CPU and wait for completion of remote call */
 	if ((ret=smp_call_function_single(f->req_cpu, palinfo_smp_call, &ptr, 0, 1))) {
-		printk("palinfo: remote CPU call from %d to %d on function %d: error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret);
+		printk(KERN_ERR "palinfo: remote CPU call from %d to %d on function %d: "
+		       "error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret);
 		return 0;
 	}
 	return ptr.ret;
@@ -879,7 +868,7 @@
 static
 int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page)
 {
-	printk("palinfo: should not be called with non SMP kernel\n");
+	printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n");
 	return 0;
 }
 #endif /* CONFIG_SMP */
@@ -937,7 +926,7 @@
 	 */
 	for (i=0; i < NR_CPUS; i++) {
 
-		if (!cpu_is_online(i)) continue;
+		if (!cpu_online(i)) continue;
 
 		sprintf(cpustr,CPUSTR, i);
 
@@ -947,8 +936,10 @@
 
 		for (j=0; j < NR_PALINFO_ENTRIES; j++) {
 			f.func_id = j;
-			*pdir++ = create_proc_read_entry (palinfo_entries[j].name, 0, cpu_dir,
-						palinfo_read_entry, (void *)f.value);
+			*pdir = create_proc_read_entry(
+					palinfo_entries[j].name, 0, cpu_dir,
+					palinfo_read_entry, (void *)f.value);
+			pdir++;
 		}
 		*pdir++ = cpu_dir;
 	}
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/pci.c linux-2.4.22-pre3/arch/ia64/kernel/pci.c
--- linux-2.4.22-pre2/arch/ia64/kernel/pci.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/pci.c	2003-07-05 18:09:37.000000000 -0700
@@ -2,9 +2,15 @@
  * pci.c - Low-Level PCI Access in IA-64
  *
  * Derived from bios32.c of i386 tree.
+ * Copyright (C) 2002, 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *	Bjorn Helgaas <bjorn_helgaas@hp.com>
+ *
+ * Note: Above list of copyright holders is incomplete...
  */
 #include <linux/config.h>
 
+#include <linux/acpi.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -13,9 +19,9 @@
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
-#include <linux/acpi.h>
 
 #include <asm/machvec.h>
+#include <asm/mca.h>
 #include <asm/page.h>
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -39,12 +45,6 @@
 #define DBG(x...)
 #endif
 
-#ifdef CONFIG_IA64_MCA
-extern void ia64_mca_check_errors( void );
-#endif
-
-static unsigned int acpi_root_bridges;
-
 struct pci_fixup pcibios_fixups[1];
 
 struct pci_ops *pci_root_ops;
@@ -213,14 +213,14 @@
 	return b;
 }
 
-static void
+static int
 alloc_resource (char *name, struct resource *root, unsigned long start, unsigned long end, unsigned long flags)
 {
 	struct resource *res;
 
 	res = kmalloc(sizeof(*res), GFP_KERNEL);
 	if (!res)
-		return;
+		return -ENOMEM;
 
 	memset(res, 0, sizeof(*res));
 	res->name = name;
@@ -228,7 +228,10 @@
 	res->end = end;
 	res->flags = flags;
 
-	request_resource(root, res);
+	if (request_resource(root, res))
+		return -EBUSY;
+
+	return 0;
 }
 
 static u64
@@ -308,14 +311,24 @@
 		} else
 			return AE_OK;
 
+		if (addr.min_address_range == addr.max_address_range) {
+			printk(KERN_INFO "ACPI reports bogus %s %s range 0x%lx-0x%lx; ignoring it\n",
+					info->name, root->name, addr.min_address_range + offset,
+					addr.max_address_range + offset);
+			return AE_OK;
+		}
+
 		window = &info->controller->window[info->controller->windows++];
 		window->resource.flags |= flags;
 		window->resource.start  = addr.min_address_range;
 		window->resource.end    = addr.max_address_range;
 		window->offset		= offset;
 
-		alloc_resource(info->name, root, addr.min_address_range + offset,
-			addr.max_address_range + offset, flags);
+		if (alloc_resource(info->name, root, addr.min_address_range + offset,
+			addr.max_address_range + offset, flags))
+			printk(KERN_ERR "alloc 0x%lx-0x%lx from %s for %s failed\n",
+				addr.min_address_range + offset, addr.max_address_range + offset,
+				root->name, info->name);
 	}
 
 	return AE_OK;
@@ -329,8 +342,6 @@
 	unsigned int windows = 0;
 	char *name;
 
-	acpi_root_bridges++;
-
 	controller = alloc_pci_controller(seg);
 	if (!controller)
 		goto out1;
@@ -379,7 +390,6 @@
 void __init
 pcibios_init (void)
 {
-#	define PCI_BUSES_TO_SCAN 256
 	int i = 0;
 	struct pci_controller *controller;
 
@@ -391,15 +401,6 @@
 
 	platform_pci_fixup(0);	/* phase 0 fixups (before buses scanned) */
 
-	/* Only probe blindly if ACPI didn't tell us about root bridges */
-	if (!acpi_root_bridges) {
-		printk("PCI: Probing PCI hardware\n");
-		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) */
 
 	return;
@@ -576,9 +577,81 @@
 		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
 	if (remap_page_range(vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
-			     vma->vm_end - vma->vm_start,
-			     vma->vm_page_prot))
+			     vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
 
 	return 0;
 }
+
+/**
+ * pci_cacheline_size - determine cacheline size for PCI devices
+ * @dev: void
+ *
+ * We want to use the line-size of the outer-most cache.  We assume
+ * that this line-size is the same for all CPUs.
+ *
+ * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info().
+ *
+ * RETURNS: An appropriate -ERRNO error value on eror, or zero for success.
+ */
+static unsigned long
+pci_cacheline_size (void)
+{
+	u64 levels, unique_caches;
+	s64 status;
+	pal_cache_config_info_t cci;
+	static u8 cacheline_size;
+
+	if (cacheline_size)
+		return cacheline_size;
+
+	status = ia64_pal_cache_summary(&levels, &unique_caches);
+	if (status != 0) {
+		printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
+		       __FUNCTION__, status);
+		return SMP_CACHE_BYTES;
+	}
+
+	status = ia64_pal_cache_config_info(levels - 1, /* cache_type (data_or_unified)= */ 2,
+					    &cci);
+	if (status != 0) {
+		printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed (status=%ld)\n",
+		       __FUNCTION__, status);
+		return SMP_CACHE_BYTES;
+	}
+	cacheline_size = 1 << cci.pcci_line_size;
+	return cacheline_size;
+}
+
+/**
+ * pcibios_prep_mwi - helper function for drivers/pci/pci.c:pci_set_mwi()
+ * @dev: the PCI device for which MWI is enabled
+ *
+ * For ia64, we can get the cacheline sizes from PAL.
+ *
+ * RETURNS: An appropriate -ERRNO error value on eror, or zero for success.
+ */
+int
+pcibios_set_mwi (struct pci_dev *dev)
+{
+	unsigned long desired_linesize, current_linesize;
+	int rc = 0;
+	u8 pci_linesize;
+
+	desired_linesize = pci_cacheline_size();
+
+	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &pci_linesize);
+	current_linesize = 4 * pci_linesize;
+	if (desired_linesize != current_linesize) {
+		printk(KERN_WARNING "PCI: slot %s has incorrect PCI cache line size of %lu bytes,",
+		       dev->slot_name, current_linesize);
+		if (current_linesize > desired_linesize) {
+			printk(" expected %lu bytes instead\n", desired_linesize);
+			rc = -EINVAL;
+		} else {
+			printk(" correcting to %lu\n", desired_linesize);
+			pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, desired_linesize / 4);
+		}
+	}
+	return rc;
+}
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/perfmon.c linux-2.4.22-pre3/arch/ia64/kernel/perfmon.c
--- linux-2.4.22-pre2/arch/ia64/kernel/perfmon.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/perfmon.c	2003-07-05 18:09:37.000000000 -0700
@@ -24,6 +24,7 @@
 #include <linux/wrapper.h>
 #include <linux/mm.h>
 #include <linux/sysctl.h>
+#include <linux/smp.h>
 
 #include <asm/bitops.h>
 #include <asm/errno.h>
@@ -120,8 +121,22 @@
 #define CTX_USED_DBR(ctx,n) 	(ctx)->ctx_used_dbrs[(n)>>6] |= 1UL<< ((n) % 64)
 #define CTX_USES_DBREGS(ctx)	(((pfm_context_t *)(ctx))->ctx_fl_using_dbreg==1)
 
-#define LOCK_CTX(ctx)	spin_lock(&(ctx)->ctx_lock)
-#define UNLOCK_CTX(ctx)	spin_unlock(&(ctx)->ctx_lock)
+#ifdef CONFIG_SMP
+#define GET_ACTIVATION()	pmu_owners[smp_processor_id()].activation_number
+#define INC_ACTIVATION()	pmu_owners[smp_processor_id()].activation_number++
+#define SET_ACTIVATION(c)	(c)->ctx_last_activation = GET_ACTIVATION()
+#define SET_LAST_CPU(ctx, v)	(ctx)->ctx_last_cpu = (v)
+#define GET_LAST_CPU(ctx)	(ctx)->ctx_last_cpu
+#else /* !CONFIG_SMP */
+#define SET_ACTIVATION(t)	do {} while(0)
+#define GET_ACTIVATION(t)	do {} while(0)
+#define INC_ACTIVATION(t)	do {} while(0)
+#define SET_LAST_CPU(ctx, v)	do {} while(0)
+#define GET_LAST_CPU(ctx)	do {} while(0)
+#endif /* CONFIG_SMP */
+
+
+#define PFM_INVALID_ACTIVATION	(~0UL)
 
 #define SET_PMU_OWNER(t)    do { pmu_owners[smp_processor_id()].owner = (t); } while(0)
 #define PMU_OWNER()	    pmu_owners[smp_processor_id()].owner
@@ -131,14 +146,13 @@
 
 #define PFM_REG_RETFLAG_SET(flags, val)	do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0)
 
-#define PFM_CPUINFO_CLEAR(v)	local_cpu_data->pfm_syst_info &= ~(v)
-#define PFM_CPUINFO_SET(v)	local_cpu_data->pfm_syst_info |= (v)
+#define TASK_PTREGS(t) (((struct pt_regs *)((unsigned long) (t) + IA64_STK_OFFSET))-1)
+
+/*
+ * cmp0 must be the value of pmc0
+ */
+#define PMC0_HAS_OVFL(cmp0)  (cmp0 & ~0x1UL)
 
-#ifdef CONFIG_SMP
-#define cpu_is_online(i) (cpu_online_map & (1UL << i))
-#else
-#define cpu_is_online(i)        (i==0)
-#endif
 
 /*
  * debugging
@@ -230,7 +244,8 @@
 	unsigned int protected:1;	/* allow access to creator of context only */
 	unsigned int using_dbreg:1;	/* using range restrictions (debug registers) */
 	unsigned int excl_idle:1;	/* exclude idle task in system wide session */
-	unsigned int reserved:23;
+	unsigned int unsecure:1;	/* sp = 0 for non self-monitored task */
+	unsigned int reserved:22;
 } pfm_context_flags_t;
 
 /*
@@ -265,13 +280,17 @@
 
 	u64			ctx_saved_psr;		/* copy of psr used for lazy ctxsw */
 	unsigned long		ctx_saved_cpus_allowed;	/* copy of the task cpus_allowed (system wide) */
+	unsigned long		ctx_last_activation;	/* context last activation number for last_cpu */
+	unsigned int		ctx_last_cpu;		/* CPU id of current or last CPU used (SMP only) */
 	unsigned int		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 */
+	struct tasklet_struct   ctx_tasklet;		/* used for sending signal-based notifications */
 } pfm_context_t;
 
+#define PFM_GET_CTX(t)	((pfm_context_t *)(t)->thread.pfm_context)
+#define LOCK_CTX(ctx)	spin_lock(&(ctx)->ctx_lock)
+#define UNLOCK_CTX(ctx)	spin_unlock(&(ctx)->ctx_lock)
+
 #define ctx_fl_inherit		ctx_flags.inherit
 #define ctx_fl_block		ctx_flags.block
 #define ctx_fl_system		ctx_flags.system
@@ -279,6 +298,7 @@
 #define ctx_fl_protected	ctx_flags.protected
 #define ctx_fl_using_dbreg	ctx_flags.using_dbreg
 #define ctx_fl_excl_idle	ctx_flags.excl_idle
+#define ctx_fl_unsecure		ctx_flags.unsecure
 
 /*
  * global information about all sessions
@@ -335,17 +355,6 @@
 } 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.
- *
- * not used in UP kernels
- */
-typedef struct {
-	struct task_struct *task;	/* which task we are interested in */
-	int retval;			/* return value of the call: 0=you can proceed, 1=need to wait for completion */
-} pfm_smp_ipi_arg_t;
-
-/*
  * perfmon command descriptions
  */
 typedef struct {
@@ -428,7 +437,8 @@
  */
 static struct {
 	struct task_struct *owner;
-	char pad[SMP_CACHE_BYTES] ____cacheline_aligned;
+	unsigned long	   activation_number;
+	char 		   pad[SMP_CACHE_BYTES] ____cacheline_aligned;
 } pmu_owners[NR_CPUS];
 
 
@@ -437,10 +447,7 @@
  * forward declarations
  */
 static void pfm_reset_pmu(struct task_struct *);
-#ifdef CONFIG_SMP
-static void pfm_fetch_regs(int cpu, struct task_struct *task, pfm_context_t *ctx);
-#endif
-static void pfm_lazy_save_regs (struct task_struct *ta);
+static unsigned long pfm_lazy_save_regs (struct task_struct *ta);
 
 #if   defined(CONFIG_ITANIUM)
 #include "perfmon_itanium.h"
@@ -504,6 +511,69 @@
 	ia64_srlz_d();
 }
 
+static inline void
+pfm_restore_ibrs(unsigned long *ibrs, unsigned int nibrs)
+{
+	int i;
+
+	for (i=0; i < nibrs; i++) {
+		ia64_set_ibr(i, ibrs[i]);
+	}
+	ia64_srlz_i();
+}
+
+static inline void
+pfm_restore_dbrs(unsigned long *dbrs, unsigned int ndbrs)
+{
+	int i;
+
+	for (i=0; i < ndbrs; i++) {
+		ia64_set_dbr(i, dbrs[i]);
+	}
+	ia64_srlz_d();
+}
+
+static inline void
+pfm_restore_pmcs(unsigned long *pmcs, unsigned long mask)
+{
+	int i;
+
+	DBprintk(("mask=0x%lx\n", mask));
+	for (i=0; mask; i++, mask>>=1) {
+		if ((mask & 0x1) == 0) continue;
+		ia64_set_pmc(i, pmcs[i]);
+		DBprintk(("pmc[%d]=0x%lx\n", i, pmcs[i]));
+	}
+	ia64_srlz_d();
+}
+
+static inline void
+pfm_restore_pmds(unsigned long *pmds, unsigned long mask)
+{
+	int i;
+	unsigned long val, ovfl_val = pmu_conf.ovfl_val;
+
+	DBprintk(("mask=0x%lx\n", mask));
+	for (i=0; mask; i++, mask>>=1) {
+		if ((mask & 0x1) == 0) continue;
+		val = PMD_IS_COUNTING(i) ? pmds[i] & ovfl_val : pmds[i];
+		ia64_set_pmd(i, val);
+		DBprintk(("pmd[%d]=0x%lx\n", i, val));
+	}
+	ia64_srlz_d();
+}
+
+static inline void
+pfm_save_pmds(unsigned long *pmds, unsigned long mask)
+{
+	int i;
+
+	ia64_srlz_d();
+
+	for (i=0; mask; i++, mask>>=1) {
+		if (mask & 0x1) pmds[i] = ia64_get_pmd(i);
+	}
+}
 
 static inline unsigned long
 pfm_read_soft_counter(pfm_context_t *ctx, int i)
@@ -600,7 +670,7 @@
 	pfm_smpl_buffer_desc_t *psb = (pfm_smpl_buffer_desc_t *)vma->vm_private_data;
 
 	if (psb == NULL) {
-		printk("perfmon: psb is null in [%d]\n", current->pid);
+		printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid);
 		return;
 	}
 	/*
@@ -665,7 +735,7 @@
 	 * some sanity checks first
 	 */
 	if (ctx == NULL || task->mm == NULL || ctx->ctx_smpl_vaddr == 0 || ctx->ctx_psb == NULL) {
-		printk("perfmon: invalid context mm=%p\n", task->mm);
+		printk(KERN_DEBUG "perfmon: invalid context mm=%p\n", task->mm);
 		return -1;
 	}
 	psb = ctx->ctx_psb;
@@ -676,11 +746,11 @@
 
 	up_write(&task->mm->mmap_sem);
 	if (r !=0) {
-		printk("perfmon: pid %d unable to unmap sampling buffer @0x%lx size=%ld\n", 
-				task->pid, ctx->ctx_smpl_vaddr, psb->psb_size);
+		printk(KERN_DEBUG "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 refcnt=%lu psb_flags=0x%x\n", 
+	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;
@@ -701,7 +771,14 @@
 static void
 pfm_context_free(pfm_context_t *ctx)
 {
-	if (ctx) kfree(ctx);
+	if (ctx) {
+		DBprintk(("kill tasklet for ctx %p\n", ctx));
+
+		tasklet_kill(&ctx->ctx_tasklet);
+
+		DBprintk(("free ctx @%p\n", ctx));
+		kfree(ctx);
+	}
 }
 
 static int
@@ -715,7 +792,7 @@
 		page = pfm_kvirt_to_pa(buf);
 
 		if (remap_page_range(addr, page, PAGE_SIZE, PAGE_READONLY)) return -ENOMEM;
-		
+
 		addr  += PAGE_SIZE;
 		buf   += PAGE_SIZE;
 		size  -= PAGE_SIZE;
@@ -873,7 +950,7 @@
 	vma->vm_end = vma->vm_start + size;
 
 	DBprintk(("entries=%ld aligned size=%ld, unmapped @0x%lx\n", entries, size, vma->vm_start));
-		
+
 	/* can only be applied to current, need to have the mm semaphore held when called */
 	if (pfm_remap_buffer((unsigned long)smpl_buf, vma->vm_start, size)) {
 		DBprintk(("Can't remap buffer\n"));
@@ -991,7 +1068,7 @@
 		pfm_sessions.pfs_sys_use_dbregs,
 		is_syswide,
 		cpu_mask));
-		
+
 
 	if (is_syswide) {
 		m = cpu_mask; n = 0;
@@ -1005,7 +1082,8 @@
 		 */
 		if (ctx && 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);
+				printk(KERN_DEBUG "perfmon: invalid release for [%d] "
+				       "sys_use_dbregs=0\n", task->pid);
 			} else {
 				pfm_sessions.pfs_sys_use_dbregs--;
 			}
@@ -1025,7 +1103,44 @@
 	return 0;
 }
 
+static void
+pfm_send_notification_signal(unsigned long data)
+{
+	pfm_context_t *ctx = (pfm_context_t *)data;
+	struct siginfo si;
+	int ret;
+
+	DBprintk(("[%d] tasklet called\n", current->pid));
+
+	LOCK_CTX(ctx);
+
+	if (ctx->ctx_notify_task == NULL) {
+		printk(KERN_INFO "perfmon: tasklet lost notify_task\n");
+		goto nothing_to_do;
+	}
+	/* no leak */
+	memset(&si,0, sizeof(si));
 
+	si.si_addr        = NULL;
+	si.si_pid         = current->pid; /* irrelevant */
+	si.si_signo       = SIGPROF;
+	si.si_code        = PROF_OVFL; /* indicates a perfmon SIGPROF signal */
+	si.si_pfm_ovfl[0] = ctx->ctx_ovfl_regs[0];
+
+	if (ctx->ctx_notify_task != current) read_lock(&tasklist_lock);
+
+	DBprintk_ovfl(("[%d] tasklet sending notification to [%d]\n", current->pid, ctx->ctx_notify_task->pid));
+
+	ret = send_sig_info(SIGPROF, &si, ctx->ctx_notify_task);
+	if (ret != 0) printk(KERN_ERR "send_sig_info(process %d, SIGPROF)=%d\n", ctx->ctx_notify_task->pid, ret);
+
+	/*
+	 * now undo the protections in order
+	 */
+	if (ctx->ctx_notify_task != current) read_unlock(&tasklist_lock);
+nothing_to_do:
+	UNLOCK_CTX(ctx);
+}
 
 /*
  * XXX: do something better here
@@ -1080,7 +1195,7 @@
 		 * and it must be a valid CPU
 		 */
 		cpu = ffz(~pfx->ctx_cpu_mask);
-		if (cpu_is_online(cpu) == 0) {
+		if (cpu_online(cpu) == 0) {
 			DBprintk(("CPU%d is not online\n", cpu));
 			return -EINVAL;
 		}
@@ -1229,6 +1344,7 @@
 	ctx->ctx_fl_block     = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0;
 	ctx->ctx_fl_system    = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
 	ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0;
+	ctx->ctx_fl_unsecure  = (ctx_flags & PFM_FL_UNSECURE) ? 1: 0;
 	ctx->ctx_fl_frozen    = 0;
 	/*
 	 * setting this flag to 0 here means, that the creator or the task that the
@@ -1242,14 +1358,20 @@
 	ctx->ctx_cpu = ffz(~tmp.ctx_cpu_mask);
 
 	/* SMP only, means no CPU */
-	atomic_set(&ctx->ctx_last_cpu,-1); 
-
-	/* 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); 
+	ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
+	SET_LAST_CPU(ctx, -1);
 
 	sema_init(&ctx->ctx_restart_sem, 0); /* init this semaphore to locked */
 
+	/*
+	 * initialize tasklet for signal notifications
+	 *
+	 * ALL signal-based (or any notification using data structures
+	 * external to perfmon) MUST use tasklets to avoid lock contentions
+	 * when a signal has to be sent for overflow interrupt handler.
+	 */
+	tasklet_init(&ctx->ctx_tasklet, pfm_send_notification_signal, (unsigned long)ctx);
+
 	if (__copy_to_user(req, &tmp, sizeof(tmp))) {
 		ret = -EFAULT;
 		goto buffer_error;
@@ -1258,9 +1380,11 @@
 	DBprintk(("context=%p, pid=%d notify_task=%p\n",
 			(void *)ctx, task->pid, ctx->ctx_notify_task));
 
-	DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d excl_idle=%d\n", 
+	DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d excl_idle=%d unsecure=%d\n", 
 			(void *)ctx, task->pid, ctx_flags, ctx->ctx_fl_inherit, 
-			ctx->ctx_fl_block, ctx->ctx_fl_system, ctx->ctx_fl_excl_idle));
+			ctx->ctx_fl_block, ctx->ctx_fl_system, 
+			ctx->ctx_fl_excl_idle,
+			ctx->ctx_fl_unsecure));
 
 	/*
 	 * when no notification is required, we can make this visible at the last moment
@@ -1362,8 +1486,9 @@
 	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
 	unsigned long value, reset_pmds;
 	unsigned int cnum, reg_flags, flags;
-	int i;
-	int ret = -EINVAL;
+	int is_monitor, is_counting;
+	int i, ret = -EINVAL;
+#define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z))
 
 	/* we don't quite support this right now */
 	if (task != current) return -EINVAL;
@@ -1383,6 +1508,9 @@
 		reset_pmds = tmp.reg_reset_pmds[0];
 		flags      = 0;
 
+		is_counting = PMC_IS_COUNTING(cnum);
+		is_monitor  = PMC_IS_MONITOR(cnum);
+
 		/* 
 		 * we reject all non implemented PMC as well
 		 * as attempts to modify PMC[0-3] which are used
@@ -1393,21 +1521,19 @@
 			goto error;
 		}
 		/*
-		 * A PMC used to configure monitors must be:
-		 * 	- system-wide session: privileged monitor
-		 * 	- per-task : user monitor
-		 * any other configuration is rejected.
-		 */
-		if (PMC_IS_MONITOR(cnum) || PMC_IS_COUNTING(cnum)) {
-			DBprintk(("pmc[%u].pm=%ld\n", cnum, PMC_PM(cnum, value))); 
-
-			if (ctx->ctx_fl_system ^ PMC_PM(cnum, value)) {
-				DBprintk(("pmc_pm=%ld fl_system=%d\n", PMC_PM(cnum, value), ctx->ctx_fl_system));
-				goto error;
-			}
+		 * If the PMC is a monitor, then if the value is not the default:
+		 * 	- system-wide session: PMCx.pm=1 (privileged monitor)
+		 * 	- per-task           : PMCx.pm=0 (user monitor)
+		 */
+		if ((is_monitor || is_counting) && value != PMC_DFL_VAL(i) && PFM_CHECK_PMC_PM(ctx, cnum, value)) {
+			DBprintk(("pmc%u pmc_pm=%ld fl_system=%d\n", 
+				cnum, 
+				PMC_PM(cnum, value), 
+				ctx->ctx_fl_system));
+			goto error;
 		}
 
-		if (PMC_IS_COUNTING(cnum)) {
+		if (is_counting) {
 			pfm_monitor_t *p = (pfm_monitor_t *)&value;
 			/*
 		 	 * enforce generation of overflow interrupt. Necessary on all
@@ -1470,7 +1596,7 @@
 		 */
 		ctx->ctx_soft_pmds[cnum].flags = flags;
 
-		if (PMC_IS_COUNTING(cnum)) {
+		if (is_counting) {
 			ctx->ctx_soft_pmds[cnum].reset_pmds[0] = reset_pmds;
 
 			/* mark all PMDS to be accessed as used */
@@ -1591,7 +1717,7 @@
 		ia64_srlz_d();
 
 		DBprintk(("[%d] pmd[%u]: value=0x%lx hw_value=0x%lx 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",
+			  "long_reset=0x%lx hw_pmd=%lx notify=%c used_pmds=0x%lx reset_pmds=0x%lx psr=%d\n",
 				task->pid, cnum,
 				value, hw_value,
 				ctx->ctx_soft_pmds[cnum].val,
@@ -1600,7 +1726,7 @@
 				ia64_get_pmd(cnum) & pmu_conf.ovfl_val,
 				PMC_OVFL_NOTIFY(ctx, cnum) ? 'Y':'N',
 				ctx->ctx_used_pmds[0],
-				ctx->ctx_soft_pmds[cnum].reset_pmds[0]));
+				ctx->ctx_soft_pmds[cnum].reset_pmds[0], ia64_psr(regs)->sp));
 	}
 
 	return 0;
@@ -1635,7 +1761,10 @@
 	int foo;
 #endif
 
-	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+	if (!CTX_IS_ENABLED(ctx)) {
+		DBprintk(("context for [%d] is disabled\n", task->pid));
+		return -EINVAL;
+	}
 
 	/*
 	 * XXX: MUST MAKE SURE WE DON"T HAVE ANY PENDING OVERFLOW BEFORE READING
@@ -1646,7 +1775,10 @@
 
 	/* XXX: ctx locking may be required here */
 
-	DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), task->pid));
+	/*
+	 * should we need to access the PMU, serialization is needed
+	 */
+	ia64_srlz_d();
 
 	for (i = 0; i < count; i++, req++) {
 
@@ -1673,36 +1805,20 @@
 		if (!CTX_IS_USED_PMD(ctx, cnum)) goto abort_mission;
 
 		/*
-		 * If the task is not the current one, then we check if the
-		 * PMU state is still in the local live register due to lazy ctxsw.
-		 * If true, then we read directly from the registers.
+		 * we can access the registers directly only when task
+		 * is the OWNER of the local PMU. In SMP, this can
+		 * happen only when task == current. In addition
+		 * this can happen when task != currrent but
+		 * only in UP mode.
 		 */
-		if (atomic_read(&ctx->ctx_last_cpu) == smp_processor_id()){
-			ia64_srlz_d();
+		if (task == PMU_OWNER()) {
 			val = ia64_get_pmd(cnum);
 			DBprintk(("reading pmd[%u]=0x%lx from hw\n", cnum, val));
 		} else {
-#ifdef CONFIG_SMP
-			int cpu;
-			/*
-			 * for SMP system, the context may still be live on another
-			 * CPU so we need to fetch it before proceeding with the read
-			 * This call we only be made once for the whole loop because
-			 * of ctx_last_cpu becoming == -1.
-			 *
-			 * We cannot reuse ctx_last_cpu as it may change before we get to the
-			 * actual IPI call. In this case, we will do the call for nothing but
-			 * there is no way around it. The receiving side will simply do nothing.
-			 */
-			cpu = atomic_read(&ctx->ctx_last_cpu);
-			if (cpu != -1) {
-				DBprintk(("must fetch on CPU%d for [%d]\n", cpu, task->pid));
-				pfm_fetch_regs(cpu, task, ctx);
-			}
-#endif
 			/* context has been saved */
 			val = th->pmd[cnum];
 		}
+
 		if (PMD_IS_COUNTING(cnum)) {
 			/*
 			 * XXX: need to check for overflow
@@ -1814,7 +1930,8 @@
 
 	LOCK_PFS();
 	if (pfm_sessions.pfs_ptrace_use_dbregs == 0) {
-		printk("perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid);
+		printk(KERN_DEBUG "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n",
+		       task->pid);
 		ret = -1;
 	}  else {
 		pfm_sessions.pfs_ptrace_use_dbregs--;
@@ -2051,7 +2168,6 @@
 pfm_protect_context(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
 	 struct pt_regs *regs)
 {
-	DBprintk(("context from [%d] is protected\n", task->pid));
 	/*
 	 * from now on, only the creator of the context has access to it
 	 */
@@ -2060,7 +2176,9 @@
 	/*
 	 * reinforce secure monitoring: cannot toggle psr.up
 	 */
-	ia64_psr(regs)->sp = 1;
+	if (ctx->ctx_fl_unsecure == 0) ia64_psr(regs)->sp = 1;
+
+	DBprintk(("[%d] protected psr.sp=%d\n", task->pid, ia64_psr(regs)->sp));
 
 	return 0;
 }
@@ -2073,7 +2191,7 @@
 
 	pfm_sysctl.debug = mode == 0 ? 0 : 1;
 
-	printk("perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off");
+	printk(KERN_INFO "perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off");
 
 	return 0;
 }
@@ -2338,7 +2456,7 @@
 				current));
 
 	if (PMU_OWNER() != task) {
-		printk("perfmon: pfm_start task [%d] not pmu owner\n", task->pid);
+		printk(KERN_DEBUG "perfmon: pfm_start task [%d] not pmu owner\n", task->pid);
 		return -EINVAL;
 	}
 
@@ -2359,7 +2477,8 @@
 
 	} else {
 		if ((task->thread.flags & IA64_THREAD_PM_VALID) == 0) {
-			printk("perfmon: pfm_start task flag not set for [%d]\n", task->pid);
+			printk(KERN_DEBUG "perfmon: pfm_start task flag not set for [%d]\n",
+			       task->pid);
 			return -EINVAL;
 		}
 		/* set user level psr.up */
@@ -2384,8 +2503,10 @@
 		return -EINVAL;
 	}
 
+#ifndef CONFIG_SMP
 	if (ctx->ctx_fl_system == 0 && PMU_OWNER()  && PMU_OWNER() != current) 
 		pfm_lazy_save_regs(PMU_OWNER());
+#endif
 
 	/* reset all registers to stable quiet state */
 	pfm_reset_pmu(task);
@@ -2427,7 +2548,9 @@
 	SET_PMU_OWNER(task);
 
 	ctx->ctx_flags.state = PFM_CTX_ENABLED;
-	atomic_set(&ctx->ctx_last_cpu, smp_processor_id());
+	SET_LAST_CPU(ctx, smp_processor_id());
+	INC_ACTIVATION();
+	SET_ACTIVATION(ctx);
 
 	/* simply unfreeze */
 	pfm_unfreeze_pmu();
@@ -2599,12 +2722,15 @@
 
 			if (PFM_CMD_CHK(cmd)) {
 				ret = check_task_state(task);
-				if (ret != 0) goto abort_call;
+				if (ret != 0) {
+					DBprintk(("check_task_state=%ld for [%d]\n", ret, task->pid));
+					goto abort_call;
+				}
 			}
 		} 
 	} 
 
-	ctx = task->thread.pfm_context;
+	ctx = PFM_GET_CTX(task);
 
 	if (PFM_CMD_USE_CTX(cmd)) {
 		ret = -EINVAL;
@@ -2612,6 +2738,8 @@
 			DBprintk(("no context for task %d\n", task->pid));
 			goto abort_call;
 	       }
+
+
 	       ret = -EPERM;
 	       /*
 		* we only grant access to the context if:
@@ -2651,7 +2779,7 @@
 	 * do some sanity checks first
 	 */
 	if (!ctx) {
-		printk("perfmon: [%d] has no PFM context\n", current->pid);
+		printk(KERN_DEBUG "perfmon: [%d] has no PFM context\n", current->pid);
 		return;
 	}
 
@@ -2701,6 +2829,8 @@
 
 /*
  * This function will record an entry in the sampling if it is not full already.
+ * Input:
+ * 	ovfl_mask: mask of overflowed PMD. MUST NEVER be 0.
  * Return:
  * 	0 : buffer is not full (did not BECOME full: still space or was already full)
  * 	1 : buffer is full (recorded the last entry)
@@ -2713,8 +2843,6 @@
 	perfmon_smpl_entry_t *h;
 	int j;
 
-
-
 	idx = ia64_fetch_and_add(1, &psb->psb_index);
 	DBprintk_ovfl(("recording index=%ld entries=%ld\n", idx-1, psb->psb_entries));
 
@@ -2736,7 +2864,7 @@
 	/*
 	 * initialize entry header
 	 */
-	h->pid  = current->pid;
+	h->pid  = ctx->ctx_fl_system ? current->pid : task->pid;
 	h->cpu  = smp_processor_id();
 	h->last_reset_value = ovfl_mask ? ctx->ctx_soft_pmds[ffz(~ovfl_mask)].lval : 0UL;
 	h->ip   = regs ? regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3): 0x0UL;
@@ -2802,7 +2930,6 @@
 	unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL;
 	int i;
 	int ret = 1;
-	struct siginfo si;
 	/*
 	 * It is never safe to access the task for which the overflow interrupt is destinated
 	 * using the current variable as the interrupt may occur in the middle of a context switch
@@ -2823,16 +2950,16 @@
 	 * Don't think this could happen given upfront tests
 	 */
 	if ((t->flags & IA64_THREAD_PM_VALID) == 0 && ctx->ctx_fl_system == 0) {
-		printk("perfmon: Spurious overflow interrupt: process %d not using perfmon\n", 
-			task->pid);
+		printk(KERN_DEBUG "perfmon: Spurious overflow interrupt: process %d not "
+		       "using perfmon\n", task->pid);
 		return 0x1;
 	}
 	/*
 	 * sanity test. Should never happen
 	 */
 	if ((pmc0 & 0x1) == 0) {
-		printk("perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n", 
-			task->pid, pmc0);
+		printk(KERN_DEBUG "perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n",
+		       task->pid, pmc0);
 		return 0x0;
 	}
 
@@ -2863,7 +2990,7 @@
 		 * taken into consideration here but will be with any read of the pmd via
 		 * pfm_read_pmds().
 		 */
-		old_val = ctx->ctx_soft_pmds[i].val;
+		old_val                    = ctx->ctx_soft_pmds[i].val;
 		ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.ovfl_val;
 
 		/*
@@ -2876,6 +3003,11 @@
 			if (PMC_OVFL_NOTIFY(ctx, i)) {
 				ovfl_notify |= 1UL << i;
 			}
+		} else {
+			/*
+			 * clear top bits (maintain counts in lower part, may not always be zero)
+			 */
+			ia64_set_pmd(i, ia64_get_pmd(i) & pmu_conf.ovfl_val);
 		}
 		DBprintk_ovfl(("soft_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx\n", 
 			  i, ctx->ctx_soft_pmds[i].val, old_val, 
@@ -2885,10 +3017,10 @@
 	/*
 	 * check for sampling buffer
 	 *
-	 * if present, record sample. We propagate notification ONLY when buffer
-	 * becomes full.
+	 * if present, record sample only when a 64-bit counter has overflowed.
+	 * We propagate notification ONLY when buffer becomes full.
 	 */
-	if(CTX_HAS_SMPL(ctx)) {
+	if(CTX_HAS_SMPL(ctx) && ovfl_pmds) {
 		ret = pfm_record_sample(task, ctx, ovfl_pmds, regs);
 		if (ret == 1) {
 			/*
@@ -2924,136 +3056,40 @@
 	ctx->ctx_ovfl_regs[0]  = ovfl_pmds; 
 
 	/*
+	 * As a consequence of the overflow, we always resume
+	 * with monitoring turned off. pfm_restart() will
+	 * reactivate.
+	 */
+	ctx->ctx_fl_frozen = 1;
+
+	/*
 	 * we have come to this point because there was an overflow and that notification
 	 * was requested. The notify_task may have disappeared, in which case notify_task
 	 * is NULL.
 	 */
-	if (ctx->ctx_notify_task) {
-
-		si.si_errno    = 0;
-		si.si_addr     = NULL;
-		si.si_pid      = task->pid; /* who is sending */
-
-		si.si_signo    = SIGPROF;
-		si.si_code     = PROF_OVFL; /* indicates a perfmon SIGPROF signal */
-		/*
-		 * Shift the bitvector such that the user sees bit 4 for PMD4 and so on.
-		 * We only use smpl_ovfl[0] for now. It should be fine for quite a while
-		 * until we have more than 61 PMD available.
-		 */
-		si.si_pfm_ovfl[0] = ovfl_notify;
-	
-		/*
-		 * when the target of the signal is not ourself, we have to be more
-		 * careful. The notify_task may being cleared by the target task itself
-		 * in release_thread(). We must ensure mutual exclusion here such that
-		 * the signal is delivered (even to a dying task) safely.
-		 */
-
-		if (ctx->ctx_notify_task != current) {
-			/*
-			 * grab the notification lock for this task
-			 * This guarantees that the sequence: test + send_signal
-			 * is atomic with regards to the ctx_notify_task field.
-			 *
-			 * We need a spinlock and not just an atomic variable for this.
-			 *
-			 */
-			spin_lock(&ctx->ctx_lock);
-
-			/*
-			 * now notify_task cannot be modified until we're done
-			 * if NULL, they it got modified while we were in the handler
-			 */
-			if (ctx->ctx_notify_task == NULL) {
-
-				spin_unlock(&ctx->ctx_lock);
+	LOCK_CTX(ctx);
 
-				/*
-				 * If we've lost the notified task, then we will run
-				 * to completion wbut keep the PMU frozen. Results
-				 * will be incorrect anyway. We do not kill task
-				 * to leave it possible to attach perfmon context
-				 * to already running task.
-				 */
-				goto lost_notify;
-			}
-			/*
-			 * required by send_sig_info() to make sure the target
-			 * task does not disappear on us.
-			 */
-			read_lock(&tasklist_lock);
+	if (ctx->ctx_notify_task) {
+		if (CTX_OVFL_NOBLOCK(ctx) == 0 && ctx->ctx_notify_task != task) {
+			t->pfm_ovfl_block_reset = 1; /* will cause blocking */
+		} else {
+			t->pfm_ovfl_block_reset = 0;
 		}
-		/*
-	 	 * in this case, we don't stop the task, we let it go on. It will
-	 	 * necessarily go to the signal handler (if any) when it goes back to
-	 	 * user mode.
-	 	 */
-		DBprintk_ovfl(("[%d] sending notification to [%d]\n", 
-			  task->pid, ctx->ctx_notify_task->pid));
-
 
-		/* 
-		 * this call is safe in an interrupt handler, so does read_lock() on tasklist_lock
-		 */
-		ret = send_sig_info(SIGPROF, &si, ctx->ctx_notify_task);
-		if (ret != 0) 
-			printk("send_sig_info(process %d, SIGPROF)=%d\n",  
-			       ctx->ctx_notify_task->pid, ret);
-		/*
-		 * now undo the protections in order
-		 */
-		if (ctx->ctx_notify_task != current) {
-			read_unlock(&tasklist_lock);
-			spin_unlock(&ctx->ctx_lock);
-		}
+		DBprintk_ovfl(("[%d] scheduling tasklet\n", current->pid));
 
 		/*
-		 * if we block set the pfm_must_block bit
-		 * when in block mode, we can effectively block only when the notified
-		 * task is not self, otherwise we would deadlock. 
-		 * in this configuration, the notification is sent, the task will not 
-		 * block on the way back to user mode, but the PMU will be kept frozen
-		 * until PFM_RESTART.
-		 * Note that here there is still a race condition with notify_task
-		 * possibly being nullified behind our back, but this is fine because
-		 * it can only be changed to NULL which by construction, can only be
-		 * done when notify_task != current. So if it was already different
-		 * 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_ovfl(("block=%d notify [%d] current [%d]\n", 
-			ctx->ctx_fl_block,
-			ctx->ctx_notify_task ? ctx->ctx_notify_task->pid: -1, 
-			current->pid ));
+		 * the tasklet is responsible for sending the notification
+		 * not the PMU owner nor the current task.
+		 */
+		tasklet_schedule(&ctx->ctx_tasklet);
 
-		if (!CTX_OVFL_NOBLOCK(ctx) && ctx->ctx_notify_task != task) {
-			t->pfm_ovfl_block_reset = 1; /* will cause blocking */
-		}
 	} else {
-lost_notify: /* XXX: more to do here, to convert to non-blocking (reset values) */
-
 		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 
-		 * notify process, then we do not want to block either (even though it is 
-		 * interruptible). In this case, the PMU will be kept frozen and the process will 
-		 * run to completion without monitoring enabled.
-		 *
-		 * Of course, we cannot loose notify process when self-monitoring.
-		 */
-		t->pfm_ovfl_block_reset = 0; 
-
+		t->pfm_ovfl_block_reset = 0;
 	}
-	/*
-	 * If notification was successful, then we rely on the pfm_restart()
-	 * call to unfreeze and reset (in both blocking or non-blocking mode).
-	 *
-	 * If notification failed, then we will keep the PMU frozen and run
-	 * the task to completion
-	 */
-	ctx->ctx_fl_frozen = 1;
+
+	UNLOCK_CTX(ctx);
 
 	DBprintk_ovfl(("return pmc0=0x%x must_block=%ld\n",
 				ctx->ctx_fl_frozen ? 0x1 : 0x0, t->pfm_ovfl_block_reset));
@@ -3084,37 +3120,23 @@
 	 * This is slow
 	 */
 	pmc0 = ia64_get_pmc(0); 
-
+	task = PMU_OWNER();
 	/*
 	 * if we have some pending bits set
 	 * assumes : if any PM[0].bit[63-1] is set, then PMC[0].fr = 1
 	 */
-	if ((pmc0 & ~0x1UL)!=0UL && (task=PMU_OWNER())!= NULL) {
+	if (PMC0_HAS_OVFL(pmc0) && task) {
 		/* 
 		 * we assume that pmc0.fr is always set here
 		 */
-		ctx = task->thread.pfm_context;
+		ctx = PFM_GET_CTX(task);
 
 		/* sanity check */
 		if (!ctx) {
-			printk("perfmon: Spurious overflow interrupt: process %d has no PFM context\n", 
-				task->pid);
+			printk(KERN_DEBUG "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 
 		 */
@@ -3122,26 +3144,21 @@
 
 		/*
 		 * we can only update pmc0 when the overflow
-		 * is for the current context. In UP the current
-		 * task may not be the one owning the PMU
+		 * is for the current context or we are in system
+		 * wide mode. In UP (per-task) the current
+		 * task may not be the one owning the PMU,
+		 * same thing for system-wide.
 		 */
-		if (task == current) {
+		if (task == current || ctx->ctx_fl_system) {
 			/*
-		 	* We always clear the overflow status bits and either unfreeze
-		 	* or keep the PMU frozen.
-		 	*/
+		 	 * We always clear the overflow status bits and either unfreeze
+		 	 * or keep the PMU frozen.
+		 	 */
 			ia64_set_pmc(0, pmc0);
 			ia64_srlz_d();
 		} else {
 			task->thread.pmc[0] = pmc0;
 		}
-
-#ifdef CONFIG_SMP
-		/*
-		 * announce that we are doing with the context
-		 */
-		atomic_set(&ctx->ctx_is_busy, 0);
-#endif
 	} else {
 		pfm_stats[smp_processor_id()].pfm_spurious_ovfl_intr_count++;
 	}
@@ -3158,7 +3175,7 @@
 	p += sprintf(p, "ovfl_mask              : 0x%lx\n", pmu_conf.ovfl_val);
 
 	for(i=0; i < NR_CPUS; i++) {
-		if (cpu_is_online(i) == 0) continue;
+		if (cpu_online(i) == 0) continue;
 		p += sprintf(p, "CPU%-2d overflow intrs   : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_count);
 		p += sprintf(p, "CPU%-2d spurious intrs   : %lu\n", i, pfm_stats[i].pfm_spurious_ovfl_intr_count);
 		p += sprintf(p, "CPU%-2d recorded samples : %lu\n", i, pfm_stats[i].pfm_recorded_samples_count);
@@ -3167,6 +3184,7 @@
 		p += sprintf(p, "CPU%-2d dcr_pp           : %d\n", i, cpu_data(i)->pfm_syst_info & PFM_CPUINFO_DCR_PP ? 1 : 0);
 		p += sprintf(p, "CPU%-2d exclude idle     : %d\n", i, cpu_data(i)->pfm_syst_info & PFM_CPUINFO_EXCL_IDLE ? 1 : 0);
 		p += sprintf(p, "CPU%-2d owner            : %d\n", i, pmu_owners[i].owner ? pmu_owners[i].owner->pid: -1);
+		p += sprintf(p, "CPU%-2d activations      : %lu\n", i, pmu_owners[i].activation_number);
 	}
 
 	LOCK_PFS();
@@ -3257,13 +3275,26 @@
 	}
 }
 
+#ifdef CONFIG_SMP
 void
-pfm_save_regs (struct task_struct *task)
+pfm_save_regs(struct task_struct *task)
 {
 	pfm_context_t *ctx;
+	struct thread_struct *t;
 	u64 psr;
 
-	ctx = task->thread.pfm_context;
+	ctx = PFM_GET_CTX(task);
+	if (ctx == NULL) goto save_error;
+	t = &task->thread;
+
+	/* 
+	 * sanity check 
+	 */
+	if (ctx->ctx_last_activation != GET_ACTIVATION()) {
+		DBprintk(("ctx_activation=%lu activation=%lu: no save\n", 
+			ctx->ctx_last_activation, GET_ACTIVATION()));
+		return;
+	}
 
 	/*
 	 * save current PSR: needed because we modify it
@@ -3272,229 +3303,258 @@
 
 	/*
 	 * stop monitoring:
-	 * This is the last instruction which can generate an overflow
+	 * This is the last instruction which may generate an overflow
 	 *
 	 * We do not need to set psr.sp because, it is irrelevant in kernel.
 	 * It will be restored from ipsr when going back to user level
 	 */
 	pfm_clear_psr_up();
-	ia64_srlz_i();
 
+	/*
+	 * keep a copy of the saved psr (for reload)
+	 */
 	ctx->ctx_saved_psr = psr;
 
-	//ctx->ctx_last_cpu  = smp_processor_id();
+	/*
+	 * release ownership of this PMU.
+	 */
+	SET_PMU_OWNER(NULL);
+
+	/*
+	 * we systematically save the PMD as we have no
+	 * guarantee we will be schedule at that same 
+	 * CPU again.
+	 */
+	pfm_save_pmds(t->pmd, ctx->ctx_used_pmds[0]);
+
+	/* 
+	 * save pmc0 ia64_srlz_d() done in pfm_save_pmds() 
+	 * we will need it on the restore path to check
+	 * for pending overflow.
+	 */
+	t->pmc[0] = ia64_get_pmc(0);
+
+	return;
 
+save_error:
+	printk(KERN_ERR "perfmon: pfm_save_regs CPU%d [%d] NULL context PM_VALID=%ld\n", 
+		smp_processor_id(), task->pid,
+		task->thread.flags & IA64_THREAD_PM_VALID);
 }
 
-static void
-pfm_lazy_save_regs (struct task_struct *task)
+#else /* !CONFIG_SMP */
+
+void
+pfm_save_regs(struct task_struct *task)
 {
 	pfm_context_t *ctx;
-	struct thread_struct *t;
-	unsigned long mask;
-	int i;
-
-	DBprintk(("on [%d] by [%d]\n", task->pid, current->pid));
+	u64 psr;
 
-	t   = &task->thread;
-	ctx = task->thread.pfm_context;
+	ctx = PFM_GET_CTX(task);
+	if (ctx == NULL) goto save_error;
+	/*
+	 * save current PSR: needed because we modify it
+	 */
+	psr = pfm_get_psr();
 
-#ifdef CONFIG_SMP
-	/* 
-	 * announce we are saving this PMU state
-	 * This will cause other CPU, to wait until we're done
-	 * before using the context.h
+	/*
+	 * stop monitoring:
+	 * This is the last instruction which may generate an overflow
 	 *
-	 * must be an atomic operation
+	 * We do not need to set psr.sp because, it is irrelevant in kernel.
+	 * It will be restored from ipsr when going back to user level
 	 */
-	atomic_set(&ctx->ctx_saving_in_progress, 1);
-
-	 /*
-	  * if owner is NULL, it means that the other CPU won the race
-	  * and the IPI has caused the context to be saved in pfm_handle_fectch_regs()
-	  * instead of here. We have nothing to do
-	  *
-	  * note that this is safe, because the other CPU NEVER modifies saving_in_progress.
-	  */
-	if (PMU_OWNER() == NULL) goto do_nothing;
-#endif
+	pfm_clear_psr_up();
 
 	/*
-	 * do not own the PMU
+	 * keep a copy of the saved psr (for reload)
 	 */
-	SET_PMU_OWNER(NULL);
+	ctx->ctx_saved_psr = psr;
 
-	ia64_srlz_d();
+	return;
+save_error:
+	printk(KERN_ERR "perfmon: pfm_save_regs CPU%d [%d] NULL context PM_VALID=%ld\n", 
+		smp_processor_id(), task->pid,
+		task->thread.flags & IA64_THREAD_PM_VALID);
+}
 
-	/*
-	 * 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);
-	}
+static unsigned long
+pfm_lazy_save_regs (struct task_struct *task)
+{
+	pfm_context_t *ctx;
+	struct thread_struct *t;
 
-	/* save pmc0 */
-	t->pmc[0] = ia64_get_pmc(0);
+	ctx = PFM_GET_CTX(task);
+	t   = &task->thread;
 
-	/* not owned by this CPU */
-	atomic_set(&ctx->ctx_last_cpu, -1);
+	DBprintk(("on [%d] used_pmds=0x%lx\n", task->pid, ctx->ctx_used_pmds[0]));
 
-#ifdef CONFIG_SMP
-do_nothing:
-#endif
 	/*
-	 * declare we are done saving this context
+	 * release ownership of this PMU.
+	 * must be done before we save the registers.
 	 *
-	 * must be an atomic operation
+	 * after this call any PMU interrupt is treated
+	 * as spurious.
 	 */
-	atomic_set(&ctx->ctx_saving_in_progress,0);
+	SET_PMU_OWNER(NULL);
 
+	/*
+	 * save all the pmds we use
+	 */
+	pfm_save_pmds(t->pmd, ctx->ctx_used_pmds[0]);
+
+	/* 
+	 * save pmc0 ia64_srlz_d() done in pfm_save_pmds() 
+	 * it is needed to check for pended overflow
+	 * on the restore path
+	 */
+	t->pmc[0] = ia64_get_pmc(0);
+
+	return t->pmc[0];
 }
+#endif /* CONFIG_SMP */
 
 #ifdef CONFIG_SMP
-/*
- * Handles request coming from other CPUs
- */
-static void 
-pfm_handle_fetch_regs(void *info)
+void
+pfm_load_regs (struct task_struct *task)
 {
-	pfm_smp_ipi_arg_t *arg = info;
-	struct thread_struct *t;
 	pfm_context_t *ctx;
-	unsigned long mask;
-	int i;
-
-	ctx = arg->task->thread.pfm_context;
-	t   = &arg->task->thread;
+	struct thread_struct *t;
+	struct task_struct *owner;
+	unsigned long pmc_mask = 0UL, pmd_mask = 0UL;
+	u64 psr;
 
-	DBprintk(("task=%d owner=%d saving=%d\n", 
-		  arg->task->pid,
-		  PMU_OWNER() ? PMU_OWNER()->pid: -1,
-		  atomic_read(&ctx->ctx_saving_in_progress)));
-
-	/* must wait until not busy before retrying whole request */
-	if (atomic_read(&ctx->ctx_is_busy)) {
-		arg->retval = 2;
+	ctx = PFM_GET_CTX(task);
+	if (unlikely(ctx == NULL)) {
+		printk(KERN_ERR "perfmon: pfm_load_regs() null context\n");
 		return;
 	}
 
-	/* must wait if saving was interrupted */
-	if (atomic_read(&ctx->ctx_saving_in_progress)) {
-		arg->retval = 1;
-		return;
-	}
+	owner = PMU_OWNER();
+	t     = &task->thread;
 
-	/* can proceed, done with context */
-	if (PMU_OWNER() != arg->task) {
-		arg->retval = 0;
+	/*
+	 * possible on unload
+	 */
+	if ((t->flags & IA64_THREAD_PM_VALID) == 0) {
+		DBprintk(("[%d] PM_VALID=0, nothing to do\n", task->pid));
 		return;
 	}
 
-	DBprintk(("saving state for [%d] used_pmcs=0x%lx reload_pmcs=0x%lx used_pmds=0x%lx\n", 
-		arg->task->pid,
-		ctx->ctx_used_pmcs[0],
-		ctx->ctx_reload_pmcs[0],
-		ctx->ctx_used_pmds[0]));
-
 	/*
-	 * XXX: will be replaced with pure assembly call
+	 * 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. 
 	 */
-	SET_PMU_OWNER(NULL);
-
-	ia64_srlz_d();
+	if (ctx->ctx_fl_using_dbreg) {
+		pfm_restore_ibrs(t->ibr, pmu_conf.num_ibrs);
+		pfm_restore_dbrs(t->dbr, pmu_conf.num_dbrs);
+	}
 
 	/*
-	 * XXX needs further optimization.
+	 * retrieve saved psr
 	 */
-	mask = ctx->ctx_used_pmds[0];
-	for (i=0; mask; i++, mask>>=1) {
-		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);
+	psr = ctx->ctx_saved_psr;
 
-	/* can proceed */
-	arg->retval = 0;
-}
+	/*
+	 * if we were the last user of the PMU on that CPU, 
+	 * then nothing to do except restore psr
+	 */
+	if (GET_LAST_CPU(ctx) == smp_processor_id() && ctx->ctx_last_activation == GET_ACTIVATION()) {
+		/*
+		 * retrieve partial reload masks (due to user modifications)
+		 */
+		pmc_mask = 0UL;
+		pmd_mask = 0UL;
 
-/*
- * Function call to fetch PMU state from another CPU identified by 'cpu'.
- * If the context is being saved on the remote CPU, then we busy wait until
- * the saving is done and then we return. In this case, non IPI is sent.
- * Otherwise, we send an IPI to the remote CPU, potentially interrupting 
- * pfm_lazy_save_regs() over there.
- *
- * If the retval==1, then it means that we interrupted remote save and that we must
- * wait until the saving is over before proceeding.
- * Otherwise, we did the saving on the remote CPU, and it was done by the time we got there.
- * in either case, we can proceed.
- */
-static void
-pfm_fetch_regs(int cpu, struct task_struct *task, pfm_context_t *ctx)
-{
-	pfm_smp_ipi_arg_t  arg;
-	int ret;
+		if (pmc_mask || pmd_mask) DBprintk(("partial reload [%d] pmd_mask=0x%lx pmc_mask=0x%lx\n", task->pid, pmd_mask, pmc_mask));
+	} else {
+		/*
+	 	 * 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.
+	 	 */
+		pmd_mask = pfm_sysctl.fastctxsw ?  ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0];
 
-	arg.task   = task;
-	arg.retval = -1;
+		/* 
+	 	 * ALL accessible PMCs are systematically reloaded, unused registers
+	 	 * get their default (from pfm_reset_pmu_state()) values to avoid picking 
+	 	 * up stale configuration.
+	 	 *
+	 	 * PMC0 is never in the mask. It is always restored separately.  
+	 	 */	
+		pmc_mask = ctx->ctx_reload_pmcs[0];
+
+		DBprintk(("full reload for [%d] owner=%d activation=%lu last_activation=%lu last_cpu=%d pmd_mask=0x%lx pmc_mask=0x%lx\n", 
+			task->pid, owner ? owner->pid : -1, 
+			GET_ACTIVATION(), ctx->ctx_last_activation,
+			GET_LAST_CPU(ctx), pmd_mask, pmc_mask));
 
-	if (atomic_read(&ctx->ctx_is_busy)) {
-must_wait_busy:
-		while (atomic_read(&ctx->ctx_is_busy));
 	}
+	
+	if (pmd_mask) pfm_restore_pmds(t->pmd, pmd_mask);
+	if (pmc_mask) pfm_restore_pmcs(t->pmc, pmc_mask);
 
-	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;
+	/*
+	 * check for pending overflow at the time the state
+	 * was saved.
+	 */
+	if (PMC0_HAS_OVFL(t->pmc[0])) {
+		struct pt_regs *regs = TASK_PTREGS(task);
+		pfm_overflow_handler(task, ctx, t->pmc[0], regs);
 	}
-	DBprintk(("calling CPU %d from CPU %d\n", cpu, smp_processor_id()));
 
-	if (cpu == -1) {
-		printk("refusing to use -1 for [%d]\n", task->pid);
-		return;
+	/*
+	 * fl_frozen==1 when we are in blocking mode waiting for restart
+	 */
+	if (ctx->ctx_fl_frozen == 0) {
+		pfm_unfreeze_pmu();
 	}
 
-	/* will send IPI to other CPU and wait for completion of remote call */
-	if ((ret=smp_call_function_single(cpu, pfm_handle_fetch_regs, &arg, 0, 1))) {
-		printk("perfmon: remote CPU call from %d to %d error %d\n", smp_processor_id(), cpu, ret);
-		return;
-	}
+	SET_LAST_CPU(ctx, smp_processor_id());
+	
 	/*
-	 * we must wait until saving is over on the other CPU
-	 * This is the case, where we interrupted the saving which started just at the time we sent the
-	 * IPI.
+	 * dump activation value for this PMU
 	 */
-	if (arg.retval == 1) goto must_wait_saving;
-	if (arg.retval == 2) goto must_wait_busy;
-}
-#endif /* CONFIG_SMP */
+	INC_ACTIVATION();
+	/*
+	 * record current activation for this context
+	 */
+	SET_ACTIVATION(ctx);
 
+	/*
+	 * establish new ownership. Interrupts
+	 * are still masked at this point.
+	 */
+	SET_PMU_OWNER(task);
+
+	/*
+	 * restore the psr we changed
+	 */
+	pfm_set_psr_l(psr);
+
+}
+#else /*  !CONFIG_SMP */
+/*
+ * reload PMU state for UP kernels
+ */
 void
 pfm_load_regs (struct task_struct *task)
 {
 	struct thread_struct *t;
 	pfm_context_t *ctx;
 	struct task_struct *owner;
-	unsigned long mask;
+	unsigned long pmd_mask, pmc_mask;
+	unsigned long prev_pmc0 = ~0UL;
 	u64 psr;
-	int i;
-#ifdef CONFIG_SMP
-	int cpu;
-#endif
 
-	owner = PMU_OWNER();
-	ctx   = task->thread.pfm_context;
-	t     = &task->thread;
+	owner      = PMU_OWNER();
+	ctx        = PFM_GET_CTX(task);
+	t          = &task->thread;
 
 	/*
 	 * we restore ALL the debug registers to avoid picking up 
@@ -3503,105 +3563,112 @@
 	 * 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();
+		pfm_restore_ibrs(t->ibr, pmu_conf.num_ibrs);
+		pfm_restore_dbrs(t->dbr, pmu_conf.num_dbrs);
 	}
 
 	/*
-	 * if we were the last user, then nothing to do except restore psr
+	 * retrieved save psr
 	 */
-	if (owner == task) {
-		if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id())
-			DBprintk(("invalid last_cpu=%d for [%d]\n", 
-				atomic_read(&ctx->ctx_last_cpu), task->pid));
+	psr = ctx->ctx_saved_psr;
 
-		psr = ctx->ctx_saved_psr;
+	/*
+	 * short path, our state is still there, just
+	 * need to restore psr and we go
+	 *
+	 * we do not touch either PMC nor PMD. the psr is not touched
+	 * by the overflow_handler. So we are safe w.r.t. to interrupt
+	 * concurrency even without interrupt masking.
+	 */
+	if (owner == task) {
 		pfm_set_psr_l(psr);
-
 		return;
 	}
-	DBprintk(("load_regs: must reload for [%d] owner=%d\n", 
-		task->pid, owner ? owner->pid : -1 ));
+
+	DBprintk(("reload for [%d] owner=%d\n", task->pid, owner ? owner->pid : -1));
+
 	/*
 	 * someone else is still using the PMU, first push it out and
 	 * then we'll be able to install our stuff !
+	 *
+	 * Upon return, there will be no owner for the current PMU
 	 */
-	if (owner) pfm_lazy_save_regs(owner);
-
-#ifdef CONFIG_SMP
-	/* 
-	 * check if context on another CPU (-1 means saved)
-	 * We MUST use the variable, as last_cpu may change behind our 
-	 * back. If it changes to -1 (not on a CPU anymore), then in cpu
-	 * we have the last CPU the context was on. We may be sending the 
-	 * IPI for nothing, but we have no way of verifying this. 
-	 */
-	cpu = atomic_read(&ctx->ctx_last_cpu);
-	if (cpu != -1) {
-		pfm_fetch_regs(cpu, task, ctx);
-	}
-#endif
-
+	if (owner) prev_pmc0 = pfm_lazy_save_regs(owner);
 	/*
 	 * 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 = 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] & pmu_conf.ovfl_val);
-	}
-
+	pmd_mask = pfm_sysctl.fastctxsw ?  ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0];
+	
 	/* 
-	 * PMC0 is never set in the mask because it is always restored
-	 * separately.  
+	 * ALL accessible PMCs are systematically reloaded, unused registers
+	 * get their default (from pfm_reset_pmu_state()) values to avoid picking 
+	 * up stale configuration.
 	 *
-	 * ALL PMCs are systematically reloaded, unused registers
-	 * get their default (PAL reset) values to avoid picking up 
-	 * stale configuration.
+	 * PMC0 is never in the mask. It is always restored separately.  
 	 */	
-	mask = ctx->ctx_reload_pmcs[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) ia64_set_pmc(i, t->pmc[i]);
-	}
+	pmc_mask = ctx->ctx_reload_pmcs[0];
+
+	pfm_restore_pmds(t->pmd, pmd_mask);
+	pfm_restore_pmcs(t->pmc, pmc_mask);
 
-	if (t->pmc[0] & ~0x1) {
-		pfm_overflow_handler(task, ctx, t->pmc[0], NULL);
+	/*
+	 * Check for pending overflow when state was last saved.
+	 * invoked handler is overflow status bits set.
+	 *
+	 * Any PMU overflow in flight at this point, will still
+	 * be treated as spurious because we have no declared
+	 * owner. Note that the first level interrupt handler 
+	 * DOES NOT TOUCH any PMC except PMC0 for which we have 
+	 * a copy already.
+	 */
+	if (PMC0_HAS_OVFL(t->pmc[0])) {
+		struct pt_regs *regs = TASK_PTREGS(task);
+		pfm_overflow_handler(task, ctx, t->pmc[0], regs);
 	}
 
+
+
 	/*
 	 * fl_frozen==1 when we are in blocking mode waiting for restart
 	 */
 	if (ctx->ctx_fl_frozen == 0) {
 		pfm_unfreeze_pmu();
+	} else if (prev_pmc0 == 0UL && ctx->ctx_fl_frozen) {
+		/*
+		 * owner is still NULL at this point.
+		 *
+		 * if the previous owner (from lazy_save_regs())
+		 * was not in frozen state, then we need to freeze
+		 * the PMU if the new context is frozen.
+		 *
+		 * on McKinley this will generate a spurious interrupt
+		 * but we have no other way.
+		 */
+		pfm_freeze_pmu();
 	}
-	atomic_set(&ctx->ctx_last_cpu, smp_processor_id());
 
+	/*
+	 * establish new ownership. If there was an in-flight
+	 * overflow interrupt, it will be treated as spurious 
+	 * before and after the call, because no overflow
+	 * status bit can possibly be set. No new overflow
+	 * can be generated because, at this point, psr.up
+	 * is still cleared.
+	 */
 	SET_PMU_OWNER(task);
 
 	/*
-	 * restore the psr we changed in pfm_save_regs()
+	 * restore the psr. This is the point at which 
+	 * new overflow interrupts can be generated again.
 	 */
-	psr = ctx->ctx_saved_psr;
 	pfm_set_psr_l(psr);
 }
+#endif /* CONFIG_SMP */
 
 /*
  * XXX: make this routine able to work with non current context
@@ -3798,9 +3865,11 @@
 	 * waitpid().
 	 *
 	 */
-
-	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));
+#ifdef CONFIG_SMP
+	if (GET_LAST_CPU(ctx) != smp_processor_id())
+		printk(KERN_DEBUG "perfmon: [%d] last_cpu=%d\n",
+		       task->pid, GET_LAST_CPU(ctx));
+#endif
 
 	/*
 	 * we save all the used pmds
@@ -3847,11 +3916,7 @@
 			task->thread.pmd[i] = val;
 		}
 	}
-	/* 
-	 * indicates that context has been saved
-	 */
-	atomic_set(&ctx->ctx_last_cpu, -1);
-
+	SET_LAST_CPU(ctx, -1);
 }
 
 
@@ -3875,10 +3940,15 @@
 	thread = &task->thread;
 
 	/*
-	 * make sure child cannot mess up the monitoring session
+	 * for secure sessions, make sure child cannot mess up 
+	 * the monitoring session.
 	 */
-	 ia64_psr(regs)->sp = 1;
-	 DBprintk(("enabling psr.sp for [%d]\n", task->pid));
+	if (ctx->ctx_fl_unsecure == 0) {
+		ia64_psr(regs)->sp = 1;
+	 	DBprintk(("enabling psr.sp for [%d]\n", task->pid));
+	} else {
+	 	DBprintk(("psr.sp=%d [%d]\n", ia64_psr(regs)->sp, task->pid));
+	}
 
 
 	/*
@@ -3938,7 +4008,6 @@
 	/* copy content */
 	*nctx = *ctx;
 
-
 	if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_ONCE) {
 		nctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE;
 		DBprintk(("downgrading to INHERIT_NONE for [%d]\n", task->pid));
@@ -3978,7 +4047,7 @@
 
 	nctx->ctx_fl_frozen    = 0;
 	nctx->ctx_ovfl_regs[0] = 0UL;
-	atomic_set(&nctx->ctx_last_cpu, -1);
+	SET_LAST_CPU(nctx, -1);
 
 	/*
 	 * here nctx->ctx_psb == ctx->ctx_psb
@@ -4014,6 +4083,21 @@
 	 */
 	nctx->ctx_saved_psr = pfm_get_psr();
 
+	/*
+	 * force a full reload on ctxsw in
+	 */
+	nctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
+	SET_LAST_CPU(nctx, -1);
+
+	/*
+	 * initialize tasklet for signal notifications
+	 *
+	 * ALL signal-based (or any notification using data structures
+	 * external to perfmon) MUST use tasklets to avoid lock contentions
+	 * when a signal has to be sent for overflow interrupt handler.
+	 */
+	tasklet_init(&nctx->ctx_tasklet, pfm_send_notification_signal, (unsigned long)nctx);
+
 	/* link with new task */
 	thread->pfm_context = nctx;
 
@@ -4027,7 +4111,6 @@
 		DBprintk(("setting PM_VALID for [%d]\n", task->pid));
 		thread->flags |= IA64_THREAD_PM_VALID;
 	}
-
 	return 0;
 }
 
@@ -4171,7 +4254,7 @@
 	pfm_smpl_buffer_desc_t *tmp, *psb = task->thread.pfm_smpl_buf_list;
 
 	if (psb == NULL) {
-		printk("perfmon: psb is null in [%d]\n", current->pid);
+		printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid);
 		return -1;
 	}
 	/*
@@ -4331,7 +4414,8 @@
 	if (ret) return ret;
 
 	if (pfm_alternate_intr_handler) {
-		printk("perfmon: install_alternate, intr_handler not NULL after reserve\n");
+		printk(KERN_DEBUG "perfmon: install_alternate, intr_handler not NULL "
+		       "after reserve\n");
 		return -EINVAL;
 	}
 
@@ -4368,10 +4452,8 @@
 
 	pmu_conf.disabled = 1;
 
-	printk("perfmon: version %u.%u IRQ %u\n", 
-		PFM_VERSION_MAJ, 
-		PFM_VERSION_MIN, 
-		IA64_PERFMON_VECTOR);
+	printk(KERN_INFO "perfmon: version %u.%u IRQ %u\n", PFM_VERSION_MAJ, PFM_VERSION_MIN,
+	       IA64_PERFMON_VECTOR);
 
 	/*
 	 * compute the number of implemented PMD/PMC from the
@@ -4395,8 +4477,8 @@
 	pmu_conf.num_pmds      = n;
 	pmu_conf.num_counters  = n_counters;
 
-	printk("perfmon: %u PMCs, %u PMDs, %u counters (%lu bits)\n", 
-	       pmu_conf.num_pmcs, 
+	printk(KERN_INFO "perfmon: %u PMCs, %u PMDs, %u counters (%lu bits)\n",
+	       pmu_conf.num_pmcs,
 	       pmu_conf.num_pmds,
 	       pmu_conf.num_counters,
 	       ffz(pmu_conf.ovfl_val));
@@ -4413,7 +4495,7 @@
 	perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL);
 	if (perfmon_dir == NULL) {
 		printk(KERN_ERR "perfmon: cannot create /proc entry, perfmon disabled\n");
-		return -1; 
+		return -1;
 	}
 
 	/*
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/perfmon_mckinley.h linux-2.4.22-pre3/arch/ia64/kernel/perfmon_mckinley.h
--- linux-2.4.22-pre2/arch/ia64/kernel/perfmon_mckinley.h	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/perfmon_mckinley.h	2003-07-05 18:09:37.000000000 -0700
@@ -25,8 +25,8 @@
 /* pmc5  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_reserved, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc6  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_reserved, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc7  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_reserved, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc8  */ { PFM_REG_CONFIG  , 0, 0xffffffff3fffffffUL, 0xffffffff9fffffffUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc9  */ { PFM_REG_CONFIG  , 0, 0xffffffff3ffffffcUL, 0xffffffff9fffffffUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc8  */ { PFM_REG_CONFIG  , 0, 0xffffffff3fffffffUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc9  */ { PFM_REG_CONFIG  , 0, 0xffffffff3ffffffcUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc10 */ { PFM_REG_MONITOR , 4, 0x0UL, 0xffffUL, NULL, pfm_mck_reserved, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc11 */ { PFM_REG_MONITOR , 6, 0x0UL, 0x30f01cf, NULL,  pfm_mck_reserved, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc12 */ { PFM_REG_MONITOR , 6, 0x0UL, 0xffffUL, NULL,  pfm_mck_reserved, {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}},
@@ -143,11 +143,8 @@
 		case  8: val8 = *val;
 			 val13 = th->pmc[13];
 			 val14 = th->pmc[14];
-			 *val |= 1UL << 2; /* bit 2 must always be 1 */
 			 check_case1 = 1;
 			 break;
-		case  9: *val |= 1UL << 2; /* bit 2 must always be 1 */
-			 break;
 		case 13: val8  = th->pmc[8];
 			 val13 = *val;
 			 val14 = th->pmc[14];
@@ -163,12 +160,12 @@
 	 * i-side events in L1D and L2 caches
 	 */
 	if (check_case1) {
-		ret =   ((val13 >> 45) & 0xf) == 0 
+		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");
+		if (ret) printk(KERN_DEBUG "perfmon: failure check_case1\n");
 	}
 
 	return ret ? -EINVAL : 0;
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/process.c linux-2.4.22-pre3/arch/ia64/kernel/process.c
--- linux-2.4.22-pre2/arch/ia64/kernel/process.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/process.c	2003-07-05 18:09:37.000000000 -0700
@@ -33,10 +33,13 @@
 #include <asm/sn/idle.h>
 #endif
 
-static void
-do_show_stack (struct unw_frame_info *info, void *arg)
+#define print_symbol(fmt, addr)	printk(fmt, "");
+
+void
+ia64_do_show_stack (struct unw_frame_info *info, void *arg)
 {
 	unsigned long ip, sp, bsp;
+	char buf[80];			/* don't make it so big that it overflows the stack! */
 
 	printk("\nCall Trace: ");
 	do {
@@ -46,29 +49,28 @@
 
 		unw_get_sp(info, &sp);
 		unw_get_bsp(info, &bsp);
-		printk("[<%016lx>] sp=0x%016lx bsp=0x%016lx\n", ip, sp, bsp);
+		snprintf(buf, sizeof(buf), " [<%016lx>] %%s\n\t\t\t\tsp=%016lx bsp=%016lx\n",
+			 ip, sp, bsp);
+		print_symbol(buf, ip);
 	} while (unw_unwind(info) >= 0);
 }
 
 void
 show_trace_task (struct task_struct *task)
 {
-	struct unw_frame_info info;
-
-	unw_init_from_blocked_task(&info, task);
-	do_show_stack(&info, 0);
+	show_stack(task);
 }
 
 void
 show_stack (struct task_struct *task)
 {
 	if (!task)
-		unw_init_running(do_show_stack, 0);
+		unw_init_running(ia64_do_show_stack, 0);
 	else {
 		struct unw_frame_info info;
 
 		unw_init_from_blocked_task(&info, task);
-		do_show_stack(&info, 0);
+		ia64_do_show_stack(&info, 0);
 	}
 }
 
@@ -119,7 +121,7 @@
 		}
 	}
 	if (!user_mode(regs))
-		show_stack(0);
+		show_stack(NULL);
 }
 
 void __attribute__((noreturn))
@@ -331,6 +333,7 @@
 #	define THREAD_FLAGS_TO_SET	0
 	p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR)
 			   | THREAD_FLAGS_TO_SET);
+	ia64_drop_fpu(p);	/* don't pick up stale state from a CPU's fph */
 #ifdef CONFIG_IA32_SUPPORT
 	/*
 	 * If we're cloning an IA32 task then save the IA32 extra
@@ -492,6 +495,15 @@
 
 	tid = clone(flags | CLONE_VM, 0);
 	if (parent != current) {
+#ifdef CONFIG_IA32_SUPPORT
+		if (IS_IA32_PROCESS(ia64_task_regs(current))) {
+			/* A kernel thread is always a 64-bit process. */
+			current->thread.map_base  = DEFAULT_MAP_BASE;
+			current->thread.task_size = DEFAULT_TASK_SIZE;
+			ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
+			ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
+		}
+#endif
 		result = (*fn)(arg);
 		_exit(result);
 	}
@@ -506,11 +518,7 @@
 {
 	/* drop floating-point and debug-register state if it exists: */
 	current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
-
-#ifndef CONFIG_SMP
-	if (ia64_get_fpu_owner() == current)
-		ia64_set_fpu_owner(0);
-#endif
+	ia64_drop_fpu(current);
 }
 
 #ifdef CONFIG_PERFMON
@@ -548,10 +556,7 @@
 void
 exit_thread (void)
 {
-#ifndef CONFIG_SMP
-	if (ia64_get_fpu_owner() == current)
-		ia64_set_fpu_owner(0);
-#endif
+	ia64_drop_fpu(current);
 #ifdef CONFIG_PERFMON
        /* stop monitoring */
 	if (current->thread.pfm_context)
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/ptrace.c linux-2.4.22-pre3/arch/ia64/kernel/ptrace.c
--- linux-2.4.22-pre2/arch/ia64/kernel/ptrace.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/ptrace.c	2003-07-05 18:09:38.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  * Kernel support for the ptrace() and syscall tracing interfaces.
  *
- * Copyright (C) 1999-2002 Hewlett-Packard Co
+ * Copyright (C) 1999-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * Derived from the x86 and Alpha versions.  Most of the code in here
@@ -25,7 +25,7 @@
 #include <asm/uaccess.h>
 #include <asm/unwind.h>
 #ifdef CONFIG_PERFMON
-# include <asm/perfmon.h>
+#include <asm/perfmon.h>
 #endif
 
 /*
@@ -198,20 +198,27 @@
  *   rnat0/rnat1 gets its value from sw->ar_rnat.
  */
 static unsigned long
-get_rnat (struct pt_regs *pt, struct switch_stack *sw,
-	  unsigned long *krbs, unsigned long *urnat_addr)
+get_rnat (struct task_struct *task, struct switch_stack *sw,
+	  unsigned long *krbs, unsigned long *urnat_addr, unsigned long *urbs_end)
 {
-	unsigned long rnat0 = 0, rnat1 = 0, urnat = 0, *slot0_kaddr, kmask = ~0UL;
+	unsigned long rnat0 = 0, rnat1 = 0, urnat = 0, *slot0_kaddr, umask = 0, mask, m;
 	unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift;
-	long num_regs;
+	long num_regs, nbits;
+	struct pt_regs *pt;
 
+	pt = ia64_task_regs(task);
 	kbsp = (unsigned long *) sw->ar_bspstore;
 	ubspstore = (unsigned long *) pt->ar_bspstore;
+
+	if (urbs_end < urnat_addr)
+		nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_end);
+	else
+		nbits = 63;
+	mask = (1UL << nbits) - 1;
 	/*
-	 * First, figure out which bit number slot 0 in user-land maps
-	 * to in the kernel rnat.  Do this by figuring out how many
-	 * register slots we're beyond the user's backingstore and
-	 * then computing the equivalent address in kernel space.
+	 * First, figure out which bit number slot 0 in user-land maps to in the kernel
+	 * rnat.  Do this by figuring out how many register slots we're beyond the user's
+	 * backingstore and then computing the equivalent address in kernel space.
 	 */
 	num_regs = ia64_rse_num_regs(ubspstore, urnat_addr + 1);
 	slot0_kaddr = ia64_rse_skip_regs(krbs, num_regs);
@@ -221,20 +228,26 @@
 
 	if (ubspstore + 63 > urnat_addr) {
 		/* some bits need to be merged in from pt->ar_rnat */
-		kmask = ~((1UL << ia64_rse_slot_num(ubspstore)) - 1);
-		urnat = (pt->ar_rnat & ~kmask);
+		umask = ((1UL << ia64_rse_slot_num(ubspstore)) - 1) & mask;
+		urnat = (pt->ar_rnat & umask);
+		mask &= ~umask;
+		if (!mask)
+			return urnat;
 	}
-	if (rnat0_kaddr >= kbsp) {
+
+	m = mask << shift;
+	if (rnat0_kaddr >= kbsp)
 		rnat0 = sw->ar_rnat;
-	} else if (rnat0_kaddr > krbs) {
+	else if (rnat0_kaddr > krbs)
 		rnat0 = *rnat0_kaddr;
-	}
-	if (rnat1_kaddr >= kbsp) {
+	urnat |= (rnat0 & m) >> shift;
+
+	m = mask >> (63 - shift);
+	if (rnat1_kaddr >= kbsp)
 		rnat1 = sw->ar_rnat;
-	} else if (rnat1_kaddr > krbs) {
+	else if (rnat1_kaddr > krbs)
 		rnat1 = *rnat1_kaddr;
-	}
-	urnat |= ((rnat1 << (63 - shift)) | (rnat0 >> shift)) & kmask;
+	urnat |= (rnat1 & m) << (63 - shift);
 	return urnat;
 }
 
@@ -242,22 +255,49 @@
  * The reverse of get_rnat.
  */
 static void
-put_rnat (struct pt_regs *pt, struct switch_stack *sw,
-	  unsigned long *krbs, unsigned long *urnat_addr, unsigned long urnat)
+put_rnat (struct task_struct *task, struct switch_stack *sw,
+	  unsigned long *krbs, unsigned long *urnat_addr, unsigned long urnat,
+	  unsigned long *urbs_end)
 {
-	unsigned long rnat0 = 0, rnat1 = 0, rnat = 0, *slot0_kaddr, kmask = ~0UL, mask;
+	unsigned long rnat0 = 0, rnat1 = 0, *slot0_kaddr, umask = 0, mask, m;
 	unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift;
-	long num_regs;
+	long num_regs, nbits;
+	struct pt_regs *pt;
+	unsigned long cfm, *urbs_kargs;
+	struct unw_frame_info info;
 
+	pt = ia64_task_regs(task);
 	kbsp = (unsigned long *) sw->ar_bspstore;
 	ubspstore = (unsigned long *) pt->ar_bspstore;
+
+	urbs_kargs = urbs_end;
+	if ((long)pt->cr_ifs >= 0) {
+		/*
+		 * If entered via syscall, don't allow user to set rnat bits
+		 * for syscall args.
+		 */
+		unw_init_from_blocked_task(&info,task);
+		if (unw_unwind_to_user(&info) == 0) {
+			unw_get_cfm(&info,&cfm);
+			urbs_kargs = ia64_rse_skip_regs(urbs_end,-(cfm & 0x7f));
+		}
+	}
+
+	if (urbs_kargs >= urnat_addr)
+		nbits = 63;
+	else {
+		if ((urnat_addr - 63) >= urbs_kargs)
+			return;
+		nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_kargs);
+	}
+	mask = (1UL << nbits) - 1;
+
 	/*
-	 * First, figure out which bit number slot 0 in user-land maps
-	 * to in the kernel rnat.  Do this by figuring out how many
-	 * register slots we're beyond the user's backingstore and
-	 * then computing the equivalent address in kernel space.
+	 * First, figure out which bit number slot 0 in user-land maps to in the kernel
+	 * rnat.  Do this by figuring out how many register slots we're beyond the user's
+	 * backingstore and then computing the equivalent address in kernel space.
 	 */
-	num_regs = (long) ia64_rse_num_regs(ubspstore, urnat_addr + 1);
+	num_regs = ia64_rse_num_regs(ubspstore, urnat_addr + 1);
 	slot0_kaddr = ia64_rse_skip_regs(krbs, num_regs);
 	shift = ia64_rse_slot_num(slot0_kaddr);
 	rnat1_kaddr = ia64_rse_rnat_addr(slot0_kaddr);
@@ -265,28 +305,29 @@
 
 	if (ubspstore + 63 > urnat_addr) {
 		/* some bits need to be place in pt->ar_rnat: */
-		kmask = ~((1UL << ia64_rse_slot_num(ubspstore)) - 1);
-		pt->ar_rnat = (pt->ar_rnat & kmask) | (rnat & ~kmask);
+		umask = ((1UL << ia64_rse_slot_num(ubspstore)) - 1) & mask;
+		pt->ar_rnat = (pt->ar_rnat & ~umask) | (urnat & umask);
+		mask &= ~umask;
+		if (!mask)
+			return;
 	}
 	/*
 	 * Note: Section 11.1 of the EAS guarantees that bit 63 of an
 	 * rnat slot is ignored. so we don't have to clear it here.
 	 */
 	rnat0 = (urnat << shift);
-	mask = ~0UL << shift;
-	if (rnat0_kaddr >= kbsp) {
-		sw->ar_rnat = (sw->ar_rnat & ~mask) | (rnat0 & mask);
-	} else if (rnat0_kaddr > krbs) {
-		*rnat0_kaddr = ((*rnat0_kaddr & ~mask) | (rnat0 & mask));
-	}
+	m = mask << shift;
+	if (rnat0_kaddr >= kbsp)
+		sw->ar_rnat = (sw->ar_rnat & ~m) | (rnat0 & m);
+	else if (rnat0_kaddr > krbs)
+		*rnat0_kaddr = ((*rnat0_kaddr & ~m) | (rnat0 & m));
 
 	rnat1 = (urnat >> (63 - shift));
-	mask = ~0UL >> (63 - shift);
-	if (rnat1_kaddr >= kbsp) {
-		sw->ar_rnat = (sw->ar_rnat & ~mask) | (rnat1 & mask);
-	} else if (rnat1_kaddr > krbs) {
-		*rnat1_kaddr = ((*rnat1_kaddr & ~mask) | (rnat1 & mask));
-	}
+	m = mask >> (63 - shift);
+	if (rnat1_kaddr >= kbsp)
+		sw->ar_rnat = (sw->ar_rnat & ~m) | (rnat1 & m);
+	else if (rnat1_kaddr > krbs)
+		*rnat1_kaddr = ((*rnat1_kaddr & ~m) | (rnat1 & m));
 }
 
 /*
@@ -319,7 +360,7 @@
 		 * read the corresponding bits in the kernel RBS.
 		 */
 		rnat_addr = ia64_rse_rnat_addr(laddr);
-		ret = get_rnat(child_regs, child_stack, krbs, rnat_addr);
+		ret = get_rnat(child, child_stack, krbs, rnat_addr, urbs_end);
 
 		if (laddr == rnat_addr) {
 			/* return NaT collection word itself */
@@ -370,7 +411,7 @@
 		 * => write the corresponding bits in the kernel RBS.
 		 */
 		if (ia64_rse_is_rnat_slot(laddr))
-			put_rnat(child_regs, child_stack, krbs, laddr, val);
+			put_rnat(child, child_stack, krbs, laddr, val, urbs_end);
 		else {
 			if (laddr < urbs_end) {
 				regnum = ia64_rse_num_regs(bspstore, laddr);
@@ -578,16 +619,11 @@
 ia64_flush_fph (struct task_struct *task)
 {
 	struct ia64_psr *psr = ia64_psr(ia64_task_regs(task));
-#ifdef CONFIG_SMP
-	struct task_struct *fpu_owner = current;
-#else
-	struct task_struct *fpu_owner = ia64_get_fpu_owner();
-#endif
 
-	if (task == fpu_owner && psr->mfh) {
+	if (ia64_is_local_fpu_owner(task) && psr->mfh) {
 		psr->mfh = 0;
-		ia64_save_fpu(&task->thread.fph[0]);
 		task->thread.flags |= IA64_THREAD_FPH_VALID;
+		ia64_save_fpu(&task->thread.fph[0]);
 	}
 }
 
@@ -609,10 +645,7 @@
 		task->thread.flags |= IA64_THREAD_FPH_VALID;
 		memset(&task->thread.fph, 0, sizeof(task->thread.fph));
 	}
-#ifndef CONFIG_SMP
-	if (ia64_get_fpu_owner() == task)
-		ia64_set_fpu_owner(0);
-#endif
+	ia64_drop_fpu(task);
 	psr->dfh = 1;
 }
 
@@ -701,7 +734,9 @@
 		      case PT_R4: case PT_R5: case PT_R6: case PT_R7:
 			if (write_access) {
 				/* read NaT bit first: */
-				ret = unw_get_gr(&info, (addr - PT_R4)/8 + 4, data, &nat);
+				unsigned long dummy;
+
+				ret = unw_get_gr(&info, (addr - PT_R4)/8 + 4, &dummy, &nat);
 				if (ret < 0)
 					return ret;
 			}
@@ -846,8 +881,7 @@
 		 * IA64_THREAD_DBG_VALID. The registers are restored by the PMU context
 		 * switch code.
 		 */
-		if (pfm_use_debug_registers(child))
-			return -1;
+		if (pfm_use_debug_registers(child)) return -1;
 #endif
 
 		if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
@@ -1344,10 +1378,11 @@
 	set_current_state(TASK_STOPPED);
 	notify_parent(current, SIGCHLD);
 	schedule();
+
 	/*
-	 * This isn't the same as continuing with a signal, but it
-	 * will do for normal use.  strace only continues with a
-	 * signal if the stopping signal is not SIGTRAP.  -brl
+	 * This isn't the same as continuing with a signal, but it will do for normal use.
+	 * strace only continues with a signal if the stopping signal is not SIGTRAP.
+	 * -brl
 	 */
 	if (current->exit_code) {
 		send_sig(current->exit_code, current, 1);
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/sal.c linux-2.4.22-pre3/arch/ia64/kernel/sal.c
--- linux-2.4.22-pre2/arch/ia64/kernel/sal.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/sal.c	2003-07-05 18:09:38.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  * System Abstraction Layer (SAL) interface routines.
  *
- * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
@@ -77,7 +77,7 @@
 	return str;
 }
 
-static void __init
+void __init
 ia64_sal_handler_init (void *entry_point, void *gpval)
 {
 	/* fill in the SAL procedure descriptor and point ia64_sal to it: */
@@ -96,17 +96,17 @@
 	int i;
 
 	if (!systab) {
-		printk("Hmm, no SAL System Table.\n");
+		printk(KERN_WARNING "Hmm, no SAL System Table.\n");
 		return;
 	}
 
 	if (strncmp(systab->signature, "SST_", 4) != 0)
-		printk("bad signature in system table!");
+		printk(KERN_ERR "bad signature in system table!");
 
 	/*
 	 * revisions are coded in BCD, so %x does the job for us
 	 */
-	printk("SAL v%x.%02x: oem=%.32s, product=%.32s\n",
+	printk(KERN_INFO "SAL v%x.%02x: oem=%.32s, product=%.32s\n",
 	       systab->sal_rev_major, systab->sal_rev_minor,
 	       systab->oem_id, systab->product_id);
 
@@ -121,7 +121,7 @@
 		switch (*p) {
 		      case SAL_DESC_ENTRY_POINT:
 			ep = (struct ia64_sal_desc_entry_point *) p;
-			printk("SAL: entry: pal_proc=0x%lx, sal_proc=0x%lx\n",
+			printk(KERN_INFO "SAL: entry: pal_proc=0x%lx, sal_proc=0x%lx\n",
 			       ep->pal_proc, ep->sal_proc);
 			ia64_pal_handler_init(__va(ep->pal_proc));
 			ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp));
@@ -139,12 +139,12 @@
 			      switch (ap->mechanism) {
 				    case IA64_SAL_AP_EXTERNAL_INT:
 				      ap_wakeup_vector = ap->vector;
-				      printk("SAL: AP wakeup using external interrupt "
+				      printk(KERN_INFO "SAL: AP wakeup using external interrupt "
 					     "vector 0x%lx\n", ap_wakeup_vector);
 				      break;
 
 				    default:
-				      printk("SAL: AP wakeup mechanism unsupported!\n");
+				      printk(KERN_ERR "SAL: AP wakeup mechanism unsupported!\n");
 				      break;
 			      }
 			      break;
@@ -154,7 +154,7 @@
 		      {
 			      struct ia64_sal_desc_platform_feature *pf = (void *) p;
 			      sal_platform_features = pf->feature_mask;
-			      printk("SAL: Platform features ");
+			      printk(KERN_INFO "SAL: Platform features ");
 
 			      if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_BUS_LOCK)
 				      printk("BusLock ");
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/salinfo.c linux-2.4.22-pre3/arch/ia64/kernel/salinfo.c
--- linux-2.4.22-pre2/arch/ia64/kernel/salinfo.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/kernel/salinfo.c	2003-07-05 18:09:38.000000000 -0700
@@ -4,6 +4,8 @@
  * Creates entries in /proc/sal for various system features.
  *
  * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2003 Hewlett-Packard Co
+ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
  *
  * 10/30/2001	jbarnes@sgi.com		copied much of Stephane's palinfo
  *					code to create this file
@@ -12,8 +14,10 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/module.h>
+#include <linux/smp.h>
 
 #include <asm/sal.h>
+#include <asm/uaccess.h>
 
 MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>");
 MODULE_DESCRIPTION("/proc interface to IA-64 SAL features");
@@ -40,25 +44,325 @@
 
 #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 char *salinfo_log_name[] = {
+	"mca",
+	"init",
+	"cmc",
+	"cpe",
+};
+
+static struct proc_dir_entry *salinfo_proc_entries[
+	ARRAY_SIZE(salinfo_entries) +			/* /proc/sal/bus_lock */
+	ARRAY_SIZE(salinfo_log_name) +			/* /proc/sal/{mca,...} */
+	(2 * ARRAY_SIZE(salinfo_log_name)) +		/* /proc/sal/mca/{event,data} */
+	1];						/* /proc/sal */
+
+struct salinfo_log_data {
+	int	type;
+	u8	*log_buffer;
+	u64	log_size;
+};
+
+struct salinfo_event {
+	int			type;
+	int			cpu;		/* next CPU to check */
+	volatile unsigned long	cpu_mask;
+	wait_queue_head_t	queue;
+};
+
+static struct salinfo_event *salinfo_event[ARRAY_SIZE(salinfo_log_name)];
+
+struct salinfo_data {
+	int	open;		/* single-open to prevent races */
+	int	type;
+	int	cpu;		/* "current" cpu for reads */
+};
+
+static struct salinfo_data salinfo_data[ARRAY_SIZE(salinfo_log_name)];
+
+static spinlock_t data_lock;
+
+void
+salinfo_log_wakeup(int type)
+{
+	if (type < ARRAY_SIZE(salinfo_log_name)) {
+		struct salinfo_event *event = salinfo_event[type];
+
+		if (event) {
+			set_bit(smp_processor_id(), &event->cpu_mask);
+			wake_up_interruptible(&event->queue);
+		}
+	}
+}
+
+static int
+salinfo_event_open(struct inode *inode, struct file *file)
+{
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_event *event = entry->data;
+
+	if (!suser())
+		return -EPERM;
+	return 0;
+}
+
+static ssize_t
+salinfo_event_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_event *event = entry->data;
+	char cmd[32];
+	size_t size;
+	int i, n, cpu = -1;
+
+retry:
+	if (!event->cpu_mask) {
+		if (file->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		interruptible_sleep_on(&event->queue);
+		if (signal_pending(current))
+			return -EINTR;
+	}
+
+	n = event->cpu;
+	for (i = 0; i < NR_CPUS; i++) {
+		if (event->cpu_mask & 1UL << n) {
+			cpu = n;
+			break;
+		}
+		if (++n == NR_CPUS)
+			n = 0;
+	}
+
+	if (cpu == -1)
+		goto retry;
+
+	/* for next read, start checking at next CPU */
+	event->cpu = cpu;
+	if (++event->cpu == NR_CPUS)
+		event->cpu = 0;
+
+	snprintf(cmd, sizeof(cmd), "read %d\n", cpu);
+
+	size = strlen(cmd);
+	if (size > count)
+		size = count;
+	if (copy_to_user(buffer, cmd, size))
+		return -EFAULT;
+
+	return size;
+}
+
+static struct file_operations salinfo_event_fops = {
+	.open  = salinfo_event_open,
+	.read  = salinfo_event_read,
+};
+
+static int
+salinfo_log_open(struct inode *inode, struct file *file)
+{
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_data *data = entry->data;
+
+	if (!suser())
+		return -EPERM;
+
+	spin_lock(&data_lock);
+	if (data->open) {
+		spin_unlock(&data_lock);
+		return -EBUSY;
+	}
+	data->open = 1;
+	spin_unlock(&data_lock);
+
+	return 0;
+}
+
+static int
+salinfo_log_release(struct inode *inode, struct file *file)
+{
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_data *data = entry->data;
+
+	spin_lock(&data_lock);
+	data->open = 0;
+	spin_unlock(&data_lock);
+	return 0;
+}
+
+static void
+call_on_cpu(int cpu, void (*fn)(void *), void *arg)
+{
+	if (cpu == smp_processor_id())
+		(*fn)(arg);
+#ifdef CONFIG_SMP
+	else if (cpu_online(cpu))	/* cpu may not have been validated */
+		smp_call_function_single(cpu, fn, arg, 0, 1);
+#endif
+}
+
+static void
+salinfo_log_read_cpu(void *context)
+{
+	struct salinfo_log_data *info = context;
+	struct salinfo_event *event = salinfo_event[info->type];
+	u64 size;
+
+	size = ia64_sal_get_state_info_size(info->type);
+	info->log_buffer = kmalloc(size, GFP_ATOMIC);
+	if (!info->log_buffer)
+		return;
+
+	clear_bit(smp_processor_id(), &event->cpu_mask);
+	info->log_size = ia64_sal_get_state_info(info->type, (u64 *) info->log_buffer);
+	if (info->log_size)
+		salinfo_log_wakeup(info->type);
+}
+
+static ssize_t
+salinfo_log_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_data *data = entry->data;
+	struct salinfo_log_data info;
+	int ret;
+	void *saldata;
+	size_t size;
+
+	info.type = data->type;
+	info.log_buffer = 0;
+	call_on_cpu(data->cpu, salinfo_log_read_cpu, &info);
+	if (!info.log_buffer || *ppos >= info.log_size) {
+		ret = 0;
+		goto out;
+	}
+
+	saldata = info.log_buffer + file->f_pos;
+	size = info.log_size - file->f_pos;
+	if (size > count)
+		size = count;
+	if (copy_to_user(buffer, saldata, size)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	*ppos += size;
+	ret = size;
+
+out:
+	kfree(info.log_buffer);
+	return ret;
+}
+
+static void
+salinfo_log_clear_cpu(void *context)
+{
+	struct salinfo_data *data = context;
+	struct salinfo_event *event = salinfo_event[data->type];
+	struct salinfo_log_data info;
+
+	clear_bit(smp_processor_id(), &event->cpu_mask);
+	ia64_sal_clear_state_info(data->type);
+
+	/* clearing one record may make another visible */
+	info.type = data->type;
+	salinfo_log_read_cpu(&info);
+	if (info.log_buffer && info.log_size)
+		salinfo_log_wakeup(data->type);
+
+	kfree(info.log_buffer);
+}
+
+static ssize_t
+salinfo_log_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_data *data = entry->data;
+	char cmd[32];
+	size_t size;
+	int cpu;
+
+	size = sizeof(cmd);
+	if (count < size)
+		size = count;
+	if (copy_from_user(cmd, buffer, size))
+		return -EFAULT;
+
+	if (sscanf(cmd, "read %d", &cpu) == 1)
+		data->cpu = cpu;
+	else if (sscanf(cmd, "clear %d", &cpu) == 1)
+		call_on_cpu(cpu, salinfo_log_clear_cpu, data);
+
+	return count;
+}
+
+static struct file_operations salinfo_data_fops = {
+	.open    = salinfo_log_open,
+	.release = salinfo_log_release,
+	.read    = salinfo_log_read,
+	.write   = salinfo_log_write,
+};
 
 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;
+	struct proc_dir_entry *dir, *entry;
+	struct salinfo_event *event;
+	struct salinfo_data *data;
+	int i, j;
 
 	salinfo_dir = proc_mkdir("sal", NULL);
+	if (!salinfo_dir)
+		return 0;
 
 	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);
 	}
+
+	for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) {
+		dir = proc_mkdir(salinfo_log_name[i], salinfo_dir);
+		if (!dir)
+			continue;
+
+		entry = create_proc_entry("event", S_IRUSR, dir);
+		if (!entry)
+			continue;
+
+		event = kmalloc(sizeof(*event), GFP_KERNEL);
+		if (!event)
+			continue;
+		memset(event, 0, sizeof(*event));
+		event->type = i;
+		init_waitqueue_head(&event->queue);
+		salinfo_event[i] = event;
+		/* we missed any events before now */
+		for (j = 0; j < NR_CPUS; j++)
+			if (cpu_online(j))
+				set_bit(j, &event->cpu_mask);
+		entry->data = event;
+		entry->proc_fops = &salinfo_event_fops;
+		*sdir++ = entry;
+
+		entry = create_proc_entry("data", S_IRUSR | S_IWUSR, dir);
+		if (!entry)
+			continue;
+
+		data = &salinfo_data[i];
+		data->type = i;
+		entry->data = data;
+		entry->proc_fops = &salinfo_data_fops;
+		*sdir++ = entry;
+
+		*sdir++ = dir;
+	}
+
 	*sdir++ = salinfo_dir;
 
 	return 0;
@@ -69,7 +373,7 @@
 {
 	int i = 0;
 
-	for (i = 0; i < NR_SALINFO_ENTRIES ; i++) {
+	for (i = 0; i < ARRAY_SIZE(salinfo_proc_entries); i++) {
 		if (salinfo_proc_entries[i])
 			remove_proc_entry (salinfo_proc_entries[i]->name, NULL);
 	}
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/setup.c linux-2.4.22-pre3/arch/ia64/kernel/setup.c
--- linux-2.4.22-pre2/arch/ia64/kernel/setup.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/setup.c	2003-07-05 18:09:39.000000000 -0700
@@ -125,7 +125,7 @@
 
 #if IGNORE_PFN0
 	if (start == PAGE_OFFSET) {
-		printk("warning: skipping physical page 0\n");
+		printk(KERN_WARNING "warning: skipping physical page 0\n");
 		start += PAGE_SIZE;
 		if (start >= end) return 0;
 	}
@@ -278,7 +278,7 @@
 		initrd_start = (unsigned long)__va(ia64_boot_param->initrd_start);
 		initrd_end   = initrd_start+ia64_boot_param->initrd_size;
 
-		printk("Initial ramdisk at: 0x%lx (%lu bytes)\n",
+		printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n",
 		       initrd_start, ia64_boot_param->initrd_size);
 	}
 #endif
@@ -335,8 +335,9 @@
 		ia64_set_kr(IA64_KR_IO_BASE, phys_iobase);
 	else {
 		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", phys_iobase);
+		printk(KERN_INFO "No I/O port range found in EFI memory map, falling back "
+		       "to AR.KR0\n");
+		printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase);
 	}
 	ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
 
@@ -470,10 +471,10 @@
 }
 
 struct seq_operations cpuinfo_op = {
-	start:	c_start,
-	next:	c_next,
-	stop:	c_stop,
-	show:	show_cpuinfo
+	.start =c_start,
+	.next =	c_next,
+	.stop =	c_stop,
+	.show =	show_cpuinfo
 };
 
 void
@@ -526,7 +527,7 @@
 		impl_va_msb = vm2.pal_vm_info_2_s.impl_va_msb;
 		phys_addr_size = vm1.pal_vm_info_1_s.phys_add_size;
 	}
-	printk("CPU %d: %lu virtual and %lu physical address bits\n",
+	printk(KERN_INFO "CPU %d: %lu virtual and %lu physical address bits\n",
 	       smp_processor_id(), impl_va_msb + 1, phys_addr_size);
 	c->unimpl_va_mask = ~((7L<<61) | ((1L << (impl_va_msb + 1)) - 1));
 	c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1));
@@ -609,6 +610,8 @@
 	/* Clear the stack memory reserved for pt_regs: */
 	memset(ia64_task_regs(current), 0, sizeof(struct pt_regs));
 
+	ia64_set_kr(IA64_KR_FPU_OWNER, 0);
+
 	/*
 	 * Initialize default control register to defer all speculative faults.  The
 	 * kernel MUST NOT depend on a particular setting of these bits (in other words,
@@ -619,10 +622,6 @@
 	 */
 	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);
-#endif
-
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
 
@@ -650,7 +649,7 @@
 	if (ia64_pal_vm_summary(NULL, &vmi) == 0)
 		max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1;
 	else {
-		printk("cpu_init: PAL VM summary failed, assuming 18 RID bits\n");
+		printk(KERN_WARNING "cpu_init: PAL VM summary failed, assuming 18 RID bits\n");
 		max_ctx = (1U << 15) - 1;	/* use architected minimum */
 	}
 	while (max_ctx < ia64_ctx.max_ctx) {
@@ -660,7 +659,7 @@
 	}
 
 	if (ia64_pal_rse_info(&num_phys_stacked, 0) != 0) {
-		printk ("cpu_init: PAL RSE info failed, assuming 96 physical stacked regs\n");
+		printk(KERN_WARNING "cpu_init: PAL RSE info failed, assuming 96 physical stacked regs\n");
 		num_phys_stacked = 96;
 	}
 	local_cpu_data->phys_stacked_size_p8 = num_phys_stacked*8 + 8;
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/sigframe.h linux-2.4.22-pre3/arch/ia64/kernel/sigframe.h
--- linux-2.4.22-pre2/arch/ia64/kernel/sigframe.h	2001-11-09 14:26:17.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/kernel/sigframe.h	2003-07-05 18:09:39.000000000 -0700
@@ -1,6 +1,6 @@
 struct sigscratch {
 	unsigned long scratch_unat;	/* ar.unat for the general registers saved in pt */
-	unsigned long pad;
+	unsigned long ar_pfs;		/* for syscalls, the user-level function-state  */
 	struct pt_regs pt;
 };
 
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/signal.c linux-2.4.22-pre3/arch/ia64/kernel/signal.c
--- linux-2.4.22-pre2/arch/ia64/kernel/signal.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/signal.c	2003-07-05 18:09:39.000000000 -0700
@@ -142,8 +142,13 @@
 
 		__copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16);
 		psr->mfh = 0;	/* drop signal handler's fph contents... */
-		if (!psr->dfh)
+		if (psr->dfh)
+			ia64_drop_fpu(current);
+		else {
+			/* We already own the local fph, otherwise psr->dfh wouldn't be 0.  */
 			__ia64_load_fpu(current->thread.fph);
+			ia64_set_local_fpu_owner(current);
+		}
 	}
 	return err;
 }
@@ -315,7 +320,7 @@
 static long
 setup_sigcontext (struct sigcontext *sc, sigset_t *mask, struct sigscratch *scr)
 {
-	unsigned long flags = 0, ifs, nat;
+	unsigned long flags = 0, ifs, cfm, nat;
 	long err;
 
 	ifs = scr->pt.cr_ifs;
@@ -325,7 +330,9 @@
 	if ((ifs & (1UL << 63)) == 0) {
 		/* if cr_ifs isn't valid, we got here through a syscall */
 		flags |= IA64_SC_FLAG_IN_SYSCALL;
-	}
+		cfm = scr->ar_pfs & ((1UL << 38) - 1);
+	} else
+		cfm = ifs & ((1UL << 38) - 1);
 	ia64_flush_fph(current);
 	if ((current->thread.flags & IA64_THREAD_FPH_VALID)) {
 		flags |= IA64_SC_FLAG_FPH_VALID;
@@ -344,6 +351,7 @@
 
 	err |= __put_user(nat, &sc->sc_nat);
 	err |= PUT_SIGSET(mask, &sc->sc_mask);
+	err |= __put_user(cfm, &sc->sc_cfm);
 	err |= __put_user(scr->pt.cr_ipsr & IA64_PSR_UM, &sc->sc_um);
 	err |= __put_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
 	err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);
@@ -422,6 +430,15 @@
 	scr->pt.ar_fpsr = FPSR_DEFAULT;			/* reset fpsr for signal handler */
 	scr->pt.cr_iip = tramp_addr;
 	ia64_psr(&scr->pt)->ri = 0;			/* start executing in first slot */
+	/*
+	 * Force the interruption function mask to zero.  This has no effect when a
+	 * system-call got interrupted by a signal (since, in that case, scr->pt_cr_ifs is
+	 * ignored), but it has the desirable effect of making it possible to deliver a
+	 * signal with an incomplete register frame (which happens when a mandatory RSE
+	 * load faults).  Furthermore, it has no negative effect on the getting the user's
+	 * dirty partition preserved, because that's governed by scr->pt.loadrs.
+	 */
+	scr->pt.cr_ifs = (1UL << 63);
 
 	/*
 	 * Note: this affects only the NaT bits of the scratch regs (the ones saved in
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/smpboot.c linux-2.4.22-pre3/arch/ia64/kernel/smpboot.c
--- linux-2.4.22-pre2/arch/ia64/kernel/smpboot.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/smpboot.c	2003-07-05 18:09:39.000000000 -0700
@@ -1,7 +1,8 @@
 /*
  * SMP boot-related support
  *
- * Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 01/05/16 Rohit Seth <rohit.seth@intel.com>	Moved SMP booting functions from smp.c to here.
  * 01/04/27 David Mosberger <davidm@hpl.hp.com>	Added ITC synching code.
@@ -66,8 +67,8 @@
 
 #define DEBUG_ITC_SYNC	0
 
-extern void __init calibrate_delay(void);
-extern void start_ap(void);
+extern void __init calibrate_delay (void);
+extern void start_ap (void);
 extern unsigned long ia64_iobase;
 
 int cpucount;
@@ -235,7 +236,7 @@
 	go[MASTER] = 1;
 
 	if (smp_call_function_single(master, sync_master, NULL, 1, 0) < 0) {
-		printk("sync_itc: failed to get attention of CPU %u!\n", master);
+		printk(KERN_ERR "sync_itc: failed to get attention of CPU %u!\n", master);
 		return;
 	}
 
@@ -275,8 +276,8 @@
 		       t[i].rt, t[i].master, t[i].diff, t[i].lat);
 #endif
 
-	printk("CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, maxerr %lu cycles)\n",
-	       smp_processor_id(), master, delta, rt);
+	printk(KERN_INFO "CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, "
+	       "maxerr %lu cycles)\n", smp_processor_id(), master, delta, rt);
 }
 
 /*
@@ -328,19 +329,14 @@
 	phys_id = hard_smp_processor_id();
 
 	if (test_and_set_bit(cpuid, &cpu_online_map)) {
-		printk("huh, phys CPU#0x%x, CPU#0x%x already present??\n", phys_id, cpuid);
+		printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
+		       phys_id, cpuid);
 		BUG();
 	}
 
 	smp_setup_percpu_timer();
 
 	/*
-	 * Synchronize the ITC with the BP
-	 */
-	Dprintk("Going to syncup ITC with BP.\n");
-
-	ia64_sync_itc(0);
-	/*
 	 * Get our bogomips.
 	 */
 	ia64_init_itm();
@@ -362,6 +358,27 @@
 	local_irq_enable();
 	calibrate_delay();
 	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
+
+	if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
+		/*
+		 * Synchronize the ITC with the BP.  Need to do this after irqs are
+		 * enabled because ia64_sync_itc() calls smp_call_function_single(), which
+		 * calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls
+		 * local_bh_enable(), which bugs out if irqs are not enabled...
+		 */
+		Dprintk("Going to syncup ITC with BP.\n");
+		ia64_sync_itc(0);
+
+		/*
+		 * Make sure we didn't sync the itc ahead of the next
+		 * timer interrupt, if so, just reset it.
+		 */
+		if (time_after(ia64_get_itc(),local_cpu_data->itm_next)) {
+			Dprintk("oops, jumped a timer.\n");
+			ia64_cpu_local_tick();
+		}
+	}
+
 	/*
 	 * Allow the master to continue.
 	 */
@@ -394,8 +411,8 @@
 fork_by_hand (void)
 {
 	/*
-	 * don't care about the eip and regs settings since
-	 * we'll never reschedule the forked task.
+	 * don't care about the eip and regs settings since we'll never reschedule the
+	 * forked task.
 	 */
 	return do_fork(CLONE_VM|CLONE_PID, 0, 0, 0);
 }
@@ -430,7 +447,7 @@
 	unhash_process(idle);
 	init_tasks[cpu] = idle;
 
-	Dprintk("Sending wakeup vector %u to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);
+	Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);
 
 	platform_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0);
 
@@ -447,9 +464,7 @@
 
 	if (test_bit(cpu, &cpu_callin_map)) {
 		/* number CPUs logically, starting from 1 (BSP is 0) */
-		printk("CPU%d: ", cpu);
-		/*print_cpu_info(&cpu_data[cpu]); */
-		printk("CPU has booted.\n");
+		printk(KERN_INFO "CPU%d: CPU has booted.\n", cpu);
 	} else {
 		printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid);
 		ia64_cpu_to_sapicid[cpu] = -1;
@@ -476,15 +491,15 @@
 	smp_setup_percpu_timer();
 
 	/*
-	* We have the boot CPU online for sure.
-	*/
+	 * We have the boot CPU online for sure.
+	 */
 	set_bit(0, &cpu_online_map);
 	set_bit(0, &cpu_callin_map);
 
 	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
 	ia64_cpu_to_sapicid[0] = boot_cpu_id;
 
-	printk("Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id);
+	printk(KERN_INFO "Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id);
 
 	global_irq_holder = 0;
 	current->processor = 0;
@@ -500,7 +515,7 @@
 		goto smp_done;
 	}
 	if  (max_cpus != -1)
-		printk (KERN_INFO "Limiting CPUs to %d\n", max_cpus);
+		printk(KERN_INFO "Limiting CPUs to %d\n", max_cpus);
 
 	if (smp_boot_data.cpu_count > 1) {
 
@@ -518,12 +533,6 @@
 				break;
 
 			do_boot_cpu(sapicid);
-
-			/*
-			 * Make sure we unmap all failed CPUs
-			 */
-			if (ia64_cpu_to_sapicid[cpu] == -1)
-				printk("phys CPU#%d not responding - cannot use it.\n", cpu);
 		}
 
 		smp_num_cpus = cpucount + 1;
@@ -541,7 +550,7 @@
 				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",
+			printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
 			       cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100);
 		}
 	}
@@ -550,7 +559,7 @@
 }
 
 /*
- * Assume that CPU's have been discovered by some platform-dependant interface.  For
+ * Assume that CPU's have been discovered by some platform-dependent interface.  For
  * SoftSDV/Lion, that would be ACPI.
  *
  * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP().
@@ -569,7 +578,7 @@
 	sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ,
 				       __pa(ap_startup->fp), __pa(ap_startup->gp), 0, 0, 0, 0);
 	if (sal_ret < 0) {
-		printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n     Forcing UP mode\n",
+		printk(KERN_ERR "SMP: Can't set SAL AP Boot Rendezvous: %s\n     Forcing UP mode\n",
 		       ia64_sal_strerror(sal_ret));
 		max_cpus = 0;
 		smp_num_cpus = 1;
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/sys_ia64.c linux-2.4.22-pre3/arch/ia64/kernel/sys_ia64.c
--- linux-2.4.22-pre2/arch/ia64/kernel/sys_ia64.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/sys_ia64.c	2003-07-05 18:09:39.000000000 -0700
@@ -56,16 +56,14 @@
 }
 
 asmlinkage long
-ia64_getpriority (int which, int who, long arg2, long arg3, long arg4, long arg5, long arg6,
-		  long arg7, long stack)
+ia64_getpriority (int which, int who)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
 	extern long sys_getpriority (int, int);
 	long prio;
 
 	prio = sys_getpriority(which, who);
 	if (prio >= 0) {
-		regs->r8 = 0;	/* ensure negative priority is not mistaken as error code */
+		force_successful_syscall_return();
 		prio = 20 - prio;
 	}
 	return prio;
@@ -79,11 +77,9 @@
 }
 
 asmlinkage unsigned long
-ia64_shmat (int shmid, void *shmaddr, int shmflg, long arg3, long arg4, long arg5, long arg6,
-	    long arg7, long stack)
+ia64_shmat (int shmid, void *shmaddr, int shmflg)
 {
 	extern int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr);
-	struct pt_regs *regs = (struct pt_regs *) &stack;
 	unsigned long raddr;
 	int retval;
 
@@ -91,16 +87,14 @@
 	if (retval < 0)
 		return retval;
 
-	regs->r8 = 0;	/* ensure negative addresses are not mistaken as an error code */
+	force_successful_syscall_return();
 	return raddr;
 }
 
 asmlinkage unsigned long
-ia64_brk (unsigned long brk, long arg1, long arg2, long arg3,
-	  long arg4, long arg5, long arg6, long arg7, long stack)
+ia64_brk (unsigned long brk)
 {
 	extern int vm_enough_memory (long pages);
-	struct pt_regs *regs = (struct pt_regs *) &stack;
 	unsigned long rlim, retval, newbrk, oldbrk;
 	struct mm_struct *mm = current->mm;
 
@@ -150,7 +144,7 @@
 out:
 	retval = mm->brk;
 	up_write(&mm->mmap_sem);
-	regs->r8 = 0;		/* ensure large retval isn't mistaken as error code */
+	force_successful_syscall_return();
 	return retval;
 }
 
@@ -227,29 +221,23 @@
  * of) files that are larger than the address space of the CPU.
  */
 asmlinkage unsigned long
-sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff,
-	   long arg6, long arg7, long stack)
+sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
-
 	addr = do_mmap2(addr, len, prot, flags, fd, pgoff);
 	if (!IS_ERR((void *) addr))
-		regs->r8 = 0;	/* ensure large addresses are not mistaken as failures... */
+		force_successful_syscall_return();
 	return addr;
 }
 
 asmlinkage unsigned long
-sys_mmap (unsigned long addr, unsigned long len, int prot, int flags,
-	  int fd, long off, long arg6, long arg7, long stack)
+sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, long off)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
-
 	if ((off & ~PAGE_MASK) != 0)
 		return -EINVAL;
 
 	addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 	if (!IS_ERR((void *) addr))
-		regs->r8 = 0;	/* ensure large addresses are not mistaken as failures... */
+		force_successful_syscall_return();
 	return addr;
 }
 
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/time.c linux-2.4.22-pre3/arch/ia64/kernel/time.c
--- linux-2.4.22-pre2/arch/ia64/kernel/time.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/kernel/time.c	2003-07-05 18:09:39.000000000 -0700
@@ -73,10 +73,8 @@
 
 	now = ia64_get_itc();
 	if ((long) (now - last_tick) < 0) {
-# if 1
-		printk("CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n",
+		printk(KERN_ERR "CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n",
 		       smp_processor_id(), now, last_tick);
-# endif
 		return last_time_offset;
 	}
 	elapsed_cycles = now - last_tick;
@@ -154,7 +152,7 @@
 	new_itm = local_cpu_data->itm_next;
 
 	if (!time_after(ia64_get_itc(), new_itm))
-		printk("Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
+		printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
 		       ia64_get_itc(), new_itm);
 
 	while (1) {
@@ -243,21 +241,22 @@
 	 */
 	status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, &platform_base_freq, &drift);
 	if (status != 0) {
-		printk("SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status));
+		printk(KERN_ERR "SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status));
 	} else {
 		status = ia64_pal_freq_ratios(&proc_ratio, 0, &itc_ratio);
 		if (status != 0)
-			printk("PAL_FREQ_RATIOS failed with status=%ld\n", status);
+			printk(KERN_ERR "PAL_FREQ_RATIOS failed with status=%ld\n", status);
 	}
 	if (status != 0) {
 		/* invent "random" values */
-		printk("SAL/PAL failed to obtain frequency info---inventing reasonably values\n");
+		printk(KERN_ERR
+		       "SAL/PAL failed to obtain frequency info---inventing reasonably values\n");
 		platform_base_freq = 100000000;
 		itc_ratio.num = 3;
 		itc_ratio.den = 1;
 	}
 	if (platform_base_freq < 40000000) {
-		printk("Platform base frequency %lu bogus---resetting to 75MHz!\n",
+		printk(KERN_ERR "Platform base frequency %lu bogus---resetting to 75MHz!\n",
 		       platform_base_freq);
 		platform_base_freq = 75000000;
 	}
@@ -268,8 +267,8 @@
 
 	itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den;
 	local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ;
-	printk("CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, ITC freq=%lu.%03luMHz\n",
-	       smp_processor_id(),
+	printk(KERN_INFO "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, "
+	       "ITC freq=%lu.%03luMHz\n", smp_processor_id(),
 	       platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
 	       itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000);
 
@@ -284,9 +283,9 @@
 }
 
 static struct irqaction timer_irqaction = {
-	handler:	timer_interrupt,
-	flags:		SA_INTERRUPT,
-	name:		"timer"
+	.handler =	timer_interrupt,
+	.flags =	SA_INTERRUPT,
+	.name =		"timer"
 };
 
 void __init
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/traps.c linux-2.4.22-pre3/arch/ia64/kernel/traps.c
--- linux-2.4.22-pre2/arch/ia64/kernel/traps.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/traps.c	2003-07-05 18:09:39.000000000 -0700
@@ -51,12 +51,12 @@
 	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",
+		printk(KERN_INFO "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");
+		printk(KERN_INFO "No FPSWA interface\n");
 }
 
 /*
@@ -97,9 +97,9 @@
 		int lock_owner;
 		int lock_owner_depth;
 	} die = {
-		lock:			SPIN_LOCK_UNLOCKED,
-		lock_owner:		-1,
-		lock_owner_depth:	0
+		.lock =		SPIN_LOCK_UNLOCKED,
+		.lock_owner =		-1,
+		.lock_owner_depth =	0
 	};
 
 	if (die.lock_owner != smp_processor_id()) {
@@ -223,7 +223,7 @@
 {
 	struct pt_regs *regs = (struct pt_regs *) &stack;
 
-	printk("%s(%d): <sc%ld(%lx,%lx,%lx,%lx)>\n", current->comm, current->pid,
+	printk(KERN_DEBUG "%s(%d): <sc%ld(%lx,%lx,%lx,%lx)>\n", current->comm, current->pid,
 	       regs->r15, arg0, arg1, arg2, arg3);
 	return -ENOSYS;
 }
@@ -245,17 +245,17 @@
 	psr->dfh = 0;
 #ifndef CONFIG_SMP
 	{
-		struct task_struct *fpu_owner = ia64_get_fpu_owner();
+		struct task_struct *fpu_owner
+			= (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
 
-		if (fpu_owner == current)
+		if (ia64_is_local_fpu_owner(current))
 			return;
 
 		if (fpu_owner)
 			ia64_flush_fph(fpu_owner);
-
 	}
 #endif /* !CONFIG_SMP */
-	ia64_set_fpu_owner(current);
+	ia64_set_local_fpu_owner(current);
 	if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
 		__ia64_load_fpu(current->thread.fph);
 		psr->mfh = 0;
@@ -337,8 +337,8 @@
 		fpu_swa_count = 0;
 	if ((++fpu_swa_count < 5) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
 		last_time = jiffies;
-		printk(KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx\n",
-		       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri);
+		printk(KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
+		       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
 	}
 
 	exception = fp_emulate(fp_fault, bundle, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr,
@@ -348,7 +348,7 @@
 			/* emulation was successful */
 			ia64_increment_ip(regs);
 		} else if (exception == -1) {
-			printk("handle_fpu_swa: fp_emulate() returned -1\n");
+			printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
 			return -1;
 		} else {
 			/* is next instruction a trap? */
@@ -371,7 +371,7 @@
 		}
 	} else {
 		if (exception == -1) {
-			printk("handle_fpu_swa: fp_emulate() returned -1\n");
+			printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
 			return -1;
 		} else if (exception != 0) {
 			/* raise exception */
@@ -469,7 +469,9 @@
 				       ? " (RSE access)" : " (data access)") : "");
 		if (code == 8) {
 # ifdef CONFIG_IA64_PRINT_HAZARDS
-			printk("%016lx:possible hazard, pr = %016lx\n", regs->cr_iip, regs->pr);
+			printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
+			       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri,
+			       regs->pr);
 # endif
 			return;
 		}
@@ -485,19 +487,23 @@
 
 	      case 26: /* NaT Consumption */
 		if (user_mode(regs)) {
+			void *addr;
+
 			if (((isr >> 4) & 0xf) == 2) {
 				/* NaT page consumption */
 				sig = SIGSEGV;
 				code = SEGV_ACCERR;
+				addr = (void *) ifa;
 			} else {
 				/* register NaT consumption */
 				sig = SIGILL;
 				code = ILL_ILLOPN;
+				addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
 			}
 			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_addr = addr;
 			siginfo.si_imm = vector;
 			siginfo.si_flags = __ISR_VALID;
 			siginfo.si_isr = isr;
@@ -585,8 +591,9 @@
 		if (ia32_exception(regs, isr) == 0)
 			return;
 #endif
-		printk("Unexpected IA-32 exception (Trap 45)\n");
-		printk("  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", regs->cr_iip, ifa, isr);
+		printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");
+		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
+		       regs->cr_iip, ifa, isr);
 		force_sig(SIGSEGV, current);
 		break;
 
@@ -595,8 +602,8 @@
 		if (ia32_intercept(regs, isr) == 0)
 			return;
 #endif
-		printk("Unexpected IA-32 intercept trap (Trap 46)\n");
-		printk("  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
+		printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
+		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
 		       regs->cr_iip, ifa, isr, iim);
 		force_sig(SIGSEGV, current);
 		return;
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/unwind.c linux-2.4.22-pre3/arch/ia64/kernel/unwind.c
--- linux-2.4.22-pre2/arch/ia64/kernel/unwind.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/kernel/unwind.c	2003-07-05 18:09:39.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2002 Hewlett-Packard Co
+ * Copyright (C) 1999-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 /*
@@ -51,18 +51,24 @@
 #define UNW_LOG_HASH_SIZE	(UNW_LOG_CACHE_SIZE + 1)
 #define UNW_HASH_SIZE		(1 << UNW_LOG_HASH_SIZE)
 
-#define UNW_DEBUG	0
 #define UNW_STATS	0	/* WARNING: this disabled interrupts for long time-spans!! */
 
-#if UNW_DEBUG
-  static long unw_debug_level = 255;
-# define debug(level,format...)	if (unw_debug_level > level) printk(format)
-# define dprintk(format...)	printk(format)
-# define inline
-#else
-# define debug(level,format...)
-# define dprintk(format...)
-#endif
+#ifdef UNW_DEBUG
+  static unsigned int unw_debug_level = UNW_DEBUG;
+#  ifdef CONFIG_KDB
+#    include <linux/kdb.h>
+#    define UNW_DEBUG_ON(n)	(unw_debug_level >= n && !KDB_IS_RUNNING())
+#    define UNW_DPRINT(n, ...)	if (UNW_DEBUG_ON(n)) kdb_printf(__VA_ARGS__)
+#  else	/* !CONFIG_KDB */
+#    define UNW_DEBUG_ON(n)	unw_debug_level >= n
+     /* Do not code a printk level, not all debug lines end in newline */
+#    define UNW_DPRINT(n, ...)  if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__)
+#  endif /* CONFIG_KDB */
+#  define inline
+#else /* !UNW_DEBUG */
+#  define UNW_DEBUG_ON(n)  0
+#  define UNW_DPRINT(n, ...)
+#endif /* UNW_DEBUG */
 
 #if UNW_STATS
 # define STAT(x...)	x
@@ -111,7 +117,7 @@
 	/* script cache: */
 	struct unw_script cache[UNW_CACHE_SIZE];
 
-# if UNW_DEBUG
+# ifdef UNW_DEBUG
 	const char *preg_name[UNW_NUM_REGS];
 # endif
 # if UNW_STATS
@@ -140,13 +146,13 @@
 	} stat;
 # endif
 } unw = {
-	tables: &unw.kernel_table,
-	lock: SPIN_LOCK_UNLOCKED,
-	save_order: {
+	.tables = &unw.kernel_table,
+	.lock = SPIN_LOCK_UNLOCKED,
+	.save_order = {
 		UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR,
 		UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR
 	},
-	preg_index: {
+	.preg_index = {
 		struct_offset(struct unw_frame_info, pri_unat_loc)/8,	/* PRI_UNAT_GR */
 		struct_offset(struct unw_frame_info, pri_unat_loc)/8,	/* PRI_UNAT_MEM */
 		struct_offset(struct unw_frame_info, bsp_loc)/8,
@@ -189,9 +195,9 @@
 		struct_offset(struct unw_frame_info, fr_loc[30 - 16])/8,
 		struct_offset(struct unw_frame_info, fr_loc[31 - 16])/8,
 	},
-	hash : { [0 ... UNW_HASH_SIZE - 1] = -1 },
-#if UNW_DEBUG
-	preg_name: {
+	.hash = { [0 ... UNW_HASH_SIZE - 1] = -1 },
+#ifdef UNW_DEBUG
+	.preg_name = {
 		"pri_unat_gr", "pri_unat_mem", "bsp", "bspstore", "ar.pfs", "ar.rnat", "psp", "rp",
 		"r4", "r5", "r6", "r7",
 		"ar.unat", "pr", "ar.lc", "ar.fpsr",
@@ -223,10 +229,25 @@
 	else if (reg <= 31)
 		off = struct_offset(struct pt_regs, r16) + 8*(reg - 16);
 	else
-		dprintk("unwind: bad scratch reg r%lu\n", reg);
+		UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __FUNCTION__, reg);
 	return off;
 }
 
+static inline struct pt_regs *
+get_scratch_regs (struct unw_frame_info *info)
+{
+	if (!info->pt) {
+		/* This should not happen with valid unwind info.  */
+		UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __FUNCTION__);
+		if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
+			info->pt = (unsigned long) ((struct pt_regs *) info->psp - 1);
+		else
+			info->pt = info->sp - 16;
+	}
+	UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __FUNCTION__, info->sp, info->pt);
+	return (struct pt_regs *) info->pt;
+}
+
 int
 unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char *nat, int write)
 {
@@ -235,7 +256,13 @@
 	struct pt_regs *pt;
 
 	if ((unsigned) regnum - 1 >= 127) {
-		dprintk("unwind: trying to access non-existent r%u\n", regnum);
+		if (regnum == 0 && !write) {
+			*val = 0;	/* read r0 always returns 0 */
+			*nat = 0;
+			return 0;
+		}
+		UNW_DPRINT(0, "unwind.%s: trying to access non-existent r%u\n",
+			   __FUNCTION__, regnum);
 		return -1;
 	}
 
@@ -280,8 +307,9 @@
 					if ((unsigned long) addr < info->regstk.limit
 					    || (unsigned long) addr >= info->regstk.top)
 					{
-						dprintk("unwind: %p outside of regstk "
-							"[0x%lx-0x%lx)\n", (void *) addr,
+						UNW_DPRINT(0, "unwind.%s: %p outside of regstk "
+							"[0x%lx-0x%lx)\n",
+							__FUNCTION__, (void *) addr,
 							info->regstk.limit,
 							info->regstk.top);
 						return -1;
@@ -298,11 +326,8 @@
 			}
 		} else {
 			/* access a scratch register */
-			if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
-				pt = (struct pt_regs *) info->psp - 1;
-			else
-				pt = (struct pt_regs *) info->sp - 1;
-			addr = (unsigned long *) ((long) pt + pt_regs_off(regnum));
+			pt = get_scratch_regs(info);
+			addr = (unsigned long *) ((unsigned long)pt + pt_regs_off(regnum));
 			if (info->pri_unat_loc)
 				nat_addr = info->pri_unat_loc;
 			else
@@ -316,7 +341,8 @@
 		if ((unsigned long) addr < info->regstk.limit
 		    || (unsigned long) addr >= info->regstk.top)
 		{
-			dprintk("unwind: ignoring attempt to access register outside of rbs\n");
+			UNW_DPRINT(0, "unwind.%s: ignoring attempt to access register outside "
+				   "of rbs\n",  __FUNCTION__);
 			return -1;
 		}
 		if ((unsigned long) nat_addr >= info->regstk.top)
@@ -348,15 +374,11 @@
 	unsigned long *addr;
 	struct pt_regs *pt;
 
-	if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
-		pt = (struct pt_regs *) info->psp - 1;
-	else
-		pt = (struct pt_regs *) info->sp - 1;
 	switch (regnum) {
 		/* scratch: */
-	      case 0: addr = &pt->b0; break;
-	      case 6: addr = &pt->b6; break;
-	      case 7: addr = &pt->b7; break;
+	      case 0: pt = get_scratch_regs(info); addr = &pt->b0; break;
+	      case 6: pt = get_scratch_regs(info); addr = &pt->b6; break;
+	      case 7: pt = get_scratch_regs(info); addr = &pt->b7; break;
 
 		/* preserved: */
 	      case 1: case 2: case 3: case 4: case 5:
@@ -366,7 +388,8 @@
 		break;
 
 	      default:
-		dprintk("unwind: trying to access non-existent b%u\n", regnum);
+		UNW_DPRINT(0, "unwind.%s: trying to access non-existent b%u\n",
+			   __FUNCTION__, regnum);
 		return -1;
 	}
 	if (write)
@@ -383,22 +406,20 @@
 	struct pt_regs *pt;
 
 	if ((unsigned) (regnum - 2) >= 126) {
-		dprintk("unwind: trying to access non-existent f%u\n", regnum);
+		UNW_DPRINT(0, "unwind.%s: trying to access non-existent f%u\n",
+			   __FUNCTION__, regnum);
 		return -1;
 	}
 
-	if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
-		pt = (struct pt_regs *) info->psp - 1;
-	else
-		pt = (struct pt_regs *) info->sp - 1;
-
 	if (regnum <= 5) {
 		addr = *(&info->f2_loc + (regnum - 2));
 		if (!addr)
 			addr = &info->sw->f2 + (regnum - 2);
 	} else if (regnum <= 15) {
-		if (regnum <= 9)
+		if (regnum <= 9) {
+			pt = get_scratch_regs(info);
 			addr = &pt->f6  + (regnum - 6);
+		}
 		else
 			addr = &info->sw->f10 + (regnum - 10);
 	} else if (regnum <= 31) {
@@ -428,11 +449,6 @@
 	unsigned long *addr;
 	struct pt_regs *pt;
 
-	if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
-		pt = (struct pt_regs *) info->psp - 1;
-	else
-		pt = (struct pt_regs *) info->sp - 1;
-
 	switch (regnum) {
 	      case UNW_AR_BSP:
 		addr = info->bsp_loc;
@@ -487,15 +503,18 @@
 		break;
 
 	      case UNW_AR_RSC:
+		pt = get_scratch_regs(info);
 		addr = &pt->ar_rsc;
 		break;
 
 	      case UNW_AR_CCV:
+		pt = get_scratch_regs(info);
 		addr = &pt->ar_ccv;
 		break;
 
 	      default:
-		dprintk("unwind: trying to access non-existent ar%u\n", regnum);
+		UNW_DPRINT(0, "unwind.%s: trying to access non-existent ar%u\n",
+			   __FUNCTION__, regnum);
 		return -1;
 	}
 
@@ -532,7 +551,7 @@
 
 	rs = alloc_reg_state();
 	if (!rs) {
-		printk("unwind: cannot stack reg state!\n");
+		printk(KERN_ERR "unwind: cannot stack reg state!\n");
 		return;
 	}
 	memcpy(rs, &sr->curr, sizeof(*rs));
@@ -545,7 +564,7 @@
 	struct unw_reg_state *rs = sr->curr.next;
 
 	if (!rs) {
-		printk("unwind: stack underflow!\n");
+		printk(KERN_ERR "unwind: stack underflow!\n");
 		return;
 	}
 	memcpy(&sr->curr, rs, sizeof(*rs));
@@ -561,7 +580,7 @@
 	while (rs) {
 		copy = alloc_reg_state();
 		if (!copy) {
-			printk ("unwind.dup_state_stack: out of memory\n");
+			printk(KERN_ERR "unwind.dup_state_stack: out of memory\n");
 			return NULL;
 		}
 		memcpy(copy, rs, sizeof(*copy));
@@ -612,7 +631,7 @@
 	      default:
 		break;
 	}
-	dprintk("unwind: bad abreg=0x%x\n", abreg);
+	UNW_DPRINT(0, "unwind.%s: bad abreg=0x%x\n", __FUNCTION__, abreg);
 	return UNW_REG_LC;
 }
 
@@ -652,7 +671,7 @@
 			return;
 		}
 	}
-	dprintk("unwind: excess spill!\n");
+	UNW_DPRINT(0, "unwind.%s: excess spill!\n",  __FUNCTION__);
 }
 
 static inline void
@@ -720,7 +739,7 @@
 desc_prologue (int body, unw_word rlen, unsigned char mask, unsigned char grsave,
 	       struct unw_state_record *sr)
 {
-	int i;
+	int i, region_start;
 
 	if (!(sr->in_body || sr->first_region))
 		finish_prologue(sr);
@@ -732,19 +751,20 @@
 		return;
 	}
 
+	region_start = sr->region_start + sr->region_len;
+
 	for (i = 0; i < sr->epilogue_count; ++i)
 		pop(sr);
 	sr->epilogue_count = 0;
 	sr->epilogue_start = UNW_WHEN_NEVER;
 
-	if (!body)
-		push(sr);
-
-	sr->region_start += sr->region_len;
+	sr->region_start = region_start;
 	sr->region_len = rlen;
 	sr->in_body = body;
 
 	if (!body) {
+		push(sr);
+
 		for (i = 0; i < 4; ++i) {
 			if (mask & 0x8)
 				set_reg(sr->curr.reg + unw.save_order[i], UNW_WHERE_GR,
@@ -765,10 +785,13 @@
 static inline void
 desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr)
 {
-	if (abi == 0 && context == 'i')
+	if (abi == 0 && context == 'i') {
 		sr->flags |= UNW_FLAG_INTERRUPT_FRAME;
+		UNW_DPRINT(3, "unwind.%s: interrupt frame\n",  __FUNCTION__);
+	}
 	else
-		dprintk("unwind: ignoring unwabi(abi=0x%x,context=0x%x)\n", abi, context);
+		UNW_DPRINT(0, "unwind%s: ignoring unwabi(abi=0x%x,context=0x%x)\n",
+				__FUNCTION__, abi, context);
 }
 
 static inline void
@@ -951,7 +974,7 @@
 			return;
 		}
 	}
-	printk("unwind: failed to find state labeled 0x%lx\n", label);
+	printk(KERN_ERR "unwind: failed to find state labeled 0x%lx\n", label);
 }
 
 static inline void
@@ -961,7 +984,7 @@
 
 	ls = alloc_labeled_state();
 	if (!ls) {
-		printk("unwind.desc_label_state(): out of memory\n");
+		printk(KERN_ERR "unwind.desc_label_state(): out of memory\n");
 		return;
 	}
 	ls->label = label;
@@ -1055,7 +1078,8 @@
 	r->val = 4*spoff;
 }
 
-#define UNW_DEC_BAD_CODE(code)			printk("unwind: unknown code 0x%02x\n", code);
+#define UNW_DEC_BAD_CODE(code)			printk(KERN_ERR "unwind: unknown code 0x%02x\n", \
+						       code);
 
 /*
  * region headers:
@@ -1135,6 +1159,9 @@
 	unsigned short index;
 	unsigned long ip, pr;
 
+	if (UNW_DEBUG_ON(0))
+		return 0;	/* Always regenerate scripts in debug mode */
+
 	STAT(++unw.stat.cache.lookups);
 
 	ip = info->ip;
@@ -1259,8 +1286,8 @@
 script_emit (struct unw_script *script, struct unw_insn insn)
 {
 	if (script->count >= UNW_MAX_SCRIPT_LEN) {
-		dprintk("unwind: script exceeds maximum size of %u instructions!\n",
-			UNW_MAX_SCRIPT_LEN);
+		UNW_DPRINT(0, "unwind.%s: script exceeds maximum size of %u instructions!\n",
+			__FUNCTION__, UNW_MAX_SCRIPT_LEN);
 		return;
 	}
 	script->insn[script->count++] = insn;
@@ -1301,7 +1328,8 @@
 		break;
 
 	      default:
-		dprintk("unwind: don't know how to emit nat info for where = %u\n", r->where);
+		UNW_DPRINT(0, "unwind.%s: don't know how to emit nat info for where = %u\n",
+			   __FUNCTION__, r->where);
 		return;
 	}
 	insn.opc = opc;
@@ -1338,8 +1366,9 @@
 			}
 			val = unw.preg_index[UNW_REG_R4 + (rval - 4)];
 		} else {
-			opc = UNW_INSN_ADD_SP;
-			val = -sizeof(struct pt_regs) + pt_regs_off(rval);
+			/* register got spilled to a scratch register */
+			opc = UNW_INSN_MOVE_SCRATCH;
+			val = pt_regs_off(rval);
 		}
 		break;
 
@@ -1349,12 +1378,12 @@
 		else if (rval >= 16 && rval <= 31)
 			val = unw.preg_index[UNW_REG_F16 + (rval - 16)];
 		else {
-			opc = UNW_INSN_ADD_SP;
-			val = -sizeof(struct pt_regs);
+			opc = UNW_INSN_MOVE_SCRATCH;
 			if (rval <= 9)
-				val += struct_offset(struct pt_regs, f6) + 16*(rval - 6);
+				val = struct_offset(struct pt_regs, f6) + 16*(rval - 6);
 			else
-				dprintk("unwind: kernel may not touch f%lu\n", rval);
+				UNW_DPRINT(0, "unwind.%s: kernel may not touch f%lu\n",
+					   __FUNCTION__, rval);
 		}
 		break;
 
@@ -1362,14 +1391,13 @@
 		if (rval >= 1 && rval <= 5)
 			val = unw.preg_index[UNW_REG_B1 + (rval - 1)];
 		else {
-			opc = UNW_INSN_ADD_SP;
-			val = -sizeof(struct pt_regs);
+			opc = UNW_INSN_MOVE_SCRATCH;
 			if (rval == 0)
-				val += struct_offset(struct pt_regs, b0);
+				val = struct_offset(struct pt_regs, b0);
 			else if (rval == 6)
-				val += struct_offset(struct pt_regs, b6);
+				val = struct_offset(struct pt_regs, b6);
 			else
-				val += struct_offset(struct pt_regs, b7);
+				val = struct_offset(struct pt_regs, b7);
 		}
 		break;
 
@@ -1382,7 +1410,8 @@
 		break;
 
 	      default:
-		dprintk("unwind: register %u has unexpected `where' value of %u\n", i, r->where);
+		UNW_DPRINT(0, "unwind%s: register %u has unexpected `where' value of %u\n",
+			   __FUNCTION__, i, r->where);
 		break;
 	}
 	insn.opc = opc;
@@ -1455,9 +1484,10 @@
 		r->when = UNW_WHEN_NEVER;
 	sr.pr_val = info->pr;
 
+	UNW_DPRINT(3, "unwind.%s: ip 0x%lx\n", __FUNCTION__, ip);
 	script = script_new(ip);
 	if (!script) {
-		dprintk("unwind: failed to create unwind script\n");
+		UNW_DPRINT(0, "unwind.%s: failed to create unwind script\n",  __FUNCTION__);
 		STAT(unw.stat.script.build_time += ia64_get_itc() - start);
 		return 0;
 	}
@@ -1475,8 +1505,8 @@
 	}
 	if (!e) {
 		/* no info, return default unwinder (leaf proc, no mem stack, no saved regs)  */
-		dprintk("unwind: no unwind info for ip=0x%lx (prev ip=0x%lx)\n", ip,
-			unw.cache[info->prev_script].ip);
+		UNW_DPRINT(1, "unwind.%s: no unwind info for ip=0x%lx (prev ip=0x%lx)\n",
+			__FUNCTION__, ip, unw.cache[info->prev_script].ip);
 		sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
 		sr.curr.reg[UNW_REG_RP].when = -1;
 		sr.curr.reg[UNW_REG_RP].val = 0;
@@ -1524,26 +1554,32 @@
 		sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
 		sr.curr.reg[UNW_REG_RP].when = -1;
 		sr.curr.reg[UNW_REG_RP].val = sr.return_link_reg;
+		UNW_DPRINT(1, "unwind.%s: using default for rp at ip=0x%lx where=%d val=0x%lx\n",
+			   __FUNCTION__, ip, sr.curr.reg[UNW_REG_RP].where,
+			   sr.curr.reg[UNW_REG_RP].val);
 	}
 
-#if UNW_DEBUG
-	printk("unwind: state record for func 0x%lx, t=%u:\n",
-	       table->segment_base + e->start_offset, sr.when_target);
+#ifdef UNW_DEBUG
+	UNW_DPRINT(1, "unwind.%s: state record for func 0x%lx, t=%u:\n",
+		__FUNCTION__, table->segment_base + e->start_offset, sr.when_target);
 	for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) {
 		if (r->where != UNW_WHERE_NONE || r->when != UNW_WHEN_NEVER) {
-			printk("  %s <- ", unw.preg_name[r - sr.curr.reg]);
+			UNW_DPRINT(1, "  %s <- ", unw.preg_name[r - sr.curr.reg]);
 			switch (r->where) {
-			      case UNW_WHERE_GR:     printk("r%lu", r->val); break;
-			      case UNW_WHERE_FR:     printk("f%lu", r->val); break;
-			      case UNW_WHERE_BR:     printk("b%lu", r->val); break;
-			      case UNW_WHERE_SPREL:  printk("[sp+0x%lx]", r->val); break;
-			      case UNW_WHERE_PSPREL: printk("[psp+0x%lx]", r->val); break;
+			      case UNW_WHERE_GR:     UNW_DPRINT(1, "r%lu", r->val); break;
+			      case UNW_WHERE_FR:     UNW_DPRINT(1, "f%lu", r->val); break;
+			      case UNW_WHERE_BR:     UNW_DPRINT(1, "b%lu", r->val); break;
+			      case UNW_WHERE_SPREL:  UNW_DPRINT(1, "[sp+0x%lx]", r->val); break;
+			      case UNW_WHERE_PSPREL: UNW_DPRINT(1, "[psp+0x%lx]", r->val); break;
 			      case UNW_WHERE_NONE:
-				printk("%s+0x%lx", unw.preg_name[r - sr.curr.reg], r->val);
+				UNW_DPRINT(1, "%s+0x%lx", unw.preg_name[r - sr.curr.reg], r->val);
+				break;
+
+			      default:
+				UNW_DPRINT(1, "BADWHERE(%d)", r->where);
 				break;
-			      default:		     printk("BADWHERE(%d)", r->where); break;
 			}
-			printk("\t\t%d\n", r->when);
+			UNW_DPRINT(1, "\t\t%d\n", r->when);
 		}
 	}
 #endif
@@ -1641,6 +1677,16 @@
 			s[dst] = s[val];
 			break;
 
+		      case UNW_INSN_MOVE_SCRATCH:
+			if (state->pt) {
+				s[dst] = (unsigned long) get_scratch_regs(state) + val;
+			} else {
+				s[dst] = 0;
+				UNW_DPRINT(0, "unwind.%s: no state->pt, dst=%ld, val=%ld\n",
+					   __FUNCTION__, dst, val);
+			}
+			break;
+
 		      case UNW_INSN_MOVE_STACKED:
 			s[dst] = (unsigned long) ia64_rse_skip_regs((unsigned long *)state->bsp,
 								    val);
@@ -1666,11 +1712,12 @@
 			break;
 
 		      case UNW_INSN_LOAD:
-#if UNW_DEBUG
+#ifdef UNW_DEBUG
 			if ((s[val] & (local_cpu_data->unimpl_va_mask | 0x7)) != 0
 			    || s[val] < TASK_SIZE)
 			{
-				debug(1, "unwind: rejecting bad psp=0x%lx\n", s[val]);
+				UNW_DPRINT(0, "unwind.%s: rejecting bad psp=0x%lx\n",
+					   __FUNCTION__, s[val]);
 				break;
 			}
 #endif
@@ -1703,7 +1750,8 @@
 
 	if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) {
 		/* don't let obviously bad addresses pollute the cache */
-		debug(1, "unwind: rejecting bad ip=0x%lx\n", info->ip);
+		/* FIXME: should really be level 0 but it occurs too often. KAO */
+		UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __FUNCTION__, info->ip);
 		info->rp_loc = 0;
 		return -1;
 	}
@@ -1712,8 +1760,9 @@
 	if (!scr) {
 		scr = build_script(info);
 		if (!scr) {
-			dprintk("unwind: failed to locate/build unwind script for ip %lx\n",
-				info->ip);
+			UNW_DPRINT(0,
+				   "unwind.%s: failed to locate/build unwind script for ip %lx\n",
+				   __FUNCTION__, info->ip);
 			return -1;
 		}
 		have_write_lock = 1;
@@ -1746,7 +1795,9 @@
 
 	/* restore the ip */
 	if (!info->rp_loc) {
-		debug(1, "unwind: failed to locate return link (ip=0x%lx)!\n", info->ip);
+		/* FIXME: should really be level 0 but it occurs too often. KAO */
+		UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n",
+			   __FUNCTION__, info->ip);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
@@ -1756,14 +1807,14 @@
 		 * We don't have unwind info for the gate page, so we consider that part
 		 * of user-space for the purpose of unwinding.
 		 */
-		debug(1, "unwind: reached user-space (ip=0x%lx)\n", ip);
+		UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
 
 	/* restore the cfm: */
 	if (!info->pfs_loc) {
-		dprintk("unwind: failed to locate ar.pfs!\n");
+		UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
@@ -1773,16 +1824,18 @@
 	pr = info->pr;
 	num_regs = 0;
 	if ((info->flags & UNW_FLAG_INTERRUPT_FRAME)) {
+		info->pt = info->sp + 16;
 		if ((pr & (1UL << pNonSys)) != 0)
 			num_regs = *info->cfm_loc & 0x7f;		/* size of frame */
 		info->pfs_loc =
-			(unsigned long *) (info->sp + 16 + struct_offset(struct pt_regs, ar_pfs));
+			(unsigned long *) (info->pt + struct_offset(struct pt_regs, ar_pfs));
+		UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __FUNCTION__, info->pt);
 	} else
 		num_regs = (*info->cfm_loc >> 7) & 0x7f;	/* size of locals */
 	info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->bsp, -num_regs);
 	if (info->bsp < info->regstk.limit || info->bsp > info->regstk.top) {
-		dprintk("unwind: bsp (0x%lx) out of range [0x%lx-0x%lx]\n",
-			info->bsp, info->regstk.limit, info->regstk.top);
+		UNW_DPRINT(0, "unwind.%s: bsp (0x%lx) out of range [0x%lx-0x%lx]\n",
+			__FUNCTION__, info->bsp, info->regstk.limit, info->regstk.top);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
@@ -1790,14 +1843,15 @@
 	/* restore the sp: */
 	info->sp = info->psp;
 	if (info->sp < info->memstk.top || info->sp > info->memstk.limit) {
-		dprintk("unwind: sp (0x%lx) out of range [0x%lx-0x%lx]\n",
-			info->sp, info->memstk.top, info->memstk.limit);
+		UNW_DPRINT(0, "unwind.%s: sp (0x%lx) out of range [0x%lx-0x%lx]\n",
+			__FUNCTION__, info->sp, info->memstk.top, info->memstk.limit);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
 
 	if (info->ip == prev_ip && info->sp == prev_sp && info->bsp == prev_bsp) {
-		dprintk("unwind: ip, sp, bsp remain unchanged; stopping here (ip=0x%lx)\n", ip);
+		UNW_DPRINT(0, "unwind.%s: ip, sp, bsp unchanged; stopping here (ip=0x%lx)\n",
+			   __FUNCTION__, ip);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
@@ -1821,7 +1875,8 @@
 	while (unw_unwind(info) >= 0) {
 		if (unw_get_rp(info, &ip) < 0) {
 			unw_get_ip(info, &ip);
-			dprintk("unwind: failed to read return pointer (ip=0x%lx)\n", ip);
+			UNW_DPRINT(0, "unwind.%s: failed to read return pointer (ip=0x%lx)\n",
+				   __FUNCTION__, ip);
 			return -1;
 		}
 		/*
@@ -1832,26 +1887,25 @@
 			return 0;
 	}
 	unw_get_ip(info, &ip);
-	dprintk("unwind: failed to unwind to user-level (ip=0x%lx)\n", ip);
+	UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n", __FUNCTION__, ip);
 	return -1;
 }
 
-void
-unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct switch_stack *sw)
+static void
+init_frame_info (struct unw_frame_info *info, struct task_struct *t,
+		 struct switch_stack *sw, unsigned long stktop)
 {
-	unsigned long rbslimit, rbstop, stklimit, stktop, sol;
+	unsigned long rbslimit, rbstop, stklimit;
 	STAT(unsigned long start, flags;)
 
 	STAT(local_irq_save(flags); ++unw.stat.api.inits; start = ia64_get_itc());
 
 	/*
-	 * Subtle stuff here: we _could_ unwind through the
-	 * switch_stack frame but we don't want to do that because it
-	 * would be slow as each preserved register would have to be
-	 * processed.  Instead, what we do here is zero out the frame
-	 * info and start the unwind process at the function that
-	 * created the switch_stack frame.  When a preserved value in
-	 * switch_stack needs to be accessed, run_script() will
+	 * Subtle stuff here: we _could_ unwind through the switch_stack frame but we
+	 * don't want to do that because it would be slow as each preserved register would
+	 * have to be processed.  Instead, what we do here is zero out the frame info and
+	 * start the unwind process at the function that created the switch_stack frame.
+	 * When a preserved value in switch_stack needs to be accessed, run_script() will
 	 * initialize the appropriate pointer on demand.
 	 */
 	memset(info, 0, sizeof(*info));
@@ -1862,7 +1916,6 @@
 		rbstop = rbslimit;
 
 	stklimit = (unsigned long) t + IA64_STK_OFFSET;
-	stktop   = (unsigned long) sw - 16;
 	if (stktop <= rbstop)
 		stktop = rbstop;
 
@@ -1872,15 +1925,56 @@
 	info->memstk.top   = stktop;
 	info->task = t;
 	info->sw  = sw;
-	info->sp = info->psp = (unsigned long) (sw + 1) - 16;
+	info->sp = info->psp = stktop;
+	info->pr = sw->pr;
+	UNW_DPRINT(3, "unwind.%s:\n"
+		   "  task   0x%lx\n"
+		   "  rbs = [0x%lx-0x%lx)\n"
+		   "  stk = [0x%lx-0x%lx)\n"
+		   "  pr     0x%lx\n"
+		   "  sw     0x%lx\n"
+		   "  sp     0x%lx\n",
+		   __FUNCTION__, (unsigned long) task, rbslimit, rbstop, stktop, stklimit,
+		   info->pr, (unsigned long) info->sw, info->sp);
+	STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags));
+}
+
+void
+unw_init_from_interruption (struct unw_frame_info *info, struct task_struct *t,
+			    struct pt_regs *pt, struct switch_stack *sw)
+{
+	unsigned long sof;
+
+	init_frame_info(info, t, sw, pt->r12);
+	info->cfm_loc = &pt->cr_ifs;
+	sof = *info->cfm_loc & 0x7f;
+	info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sof);
+	info->ip = pt->cr_iip + ia64_psr(pt)->ri;
+	info->pt = (unsigned long) pt;
+	UNW_DPRINT(3, "unwind.%s:\n"
+		   "  bsp    0x%lx\n"
+		   "  sof    0x%lx\n"
+		   "  ip     0x%lx\n",
+		   info->bsp, sof, info->ip);
+	find_save_locs(info);
+}
+
+void
+unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct switch_stack *sw)
+{
+	unsigned long sol;
+
+	init_frame_info(info, t, sw, (unsigned long) (sw + 1) - 16);
 	info->cfm_loc = &sw->ar_pfs;
 	sol = (*info->cfm_loc >> 7) & 0x7f;
 	info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sol);
 	info->ip = sw->b0;
-	info->pr = sw->pr;
-
+	UNW_DPRINT(3, "unwind.%s:\n"
+		   "  bsp    0x%lx\n"
+		   "  sol    0x%lx\n"
+		   "  ip     0x%lx\n",
+		   info->bsp, sol, info->ip);
 	find_save_locs(info);
-	STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags));
 }
 
 void
@@ -1888,6 +1982,7 @@
 {
 	struct switch_stack *sw = (struct switch_stack *) (t->thread.ksp + 16);
 
+	UNW_DPRINT(1, "unwind.%s\n", __FUNCTION__);
 	unw_init_frame_info(info, t, sw);
 }
 
@@ -1915,7 +2010,8 @@
 	unsigned long flags;
 
 	if (end - start <= 0) {
-		dprintk("unwind: ignoring attempt to insert empty unwind table\n");
+		UNW_DPRINT(0, "unwind.%s: ignoring attempt to insert empty unwind table\n",
+			   __FUNCTION__);
 		return 0;
 	}
 
@@ -1945,13 +2041,15 @@
 	long index;
 
 	if (!handle) {
-		dprintk("unwind: ignoring attempt to remove non-existent unwind table\n");
+		UNW_DPRINT(0, "unwind.%s: ignoring attempt to remove non-existent unwind table\n",
+			   __FUNCTION__);
 		return;
 	}
 
 	table = handle;
 	if (table == &unw.kernel_table) {
-		dprintk("unwind: sorry, freeing the kernel's unwind table is a no-can-do!\n");
+		UNW_DPRINT(0, "unwind.%s: sorry, freeing the kernel's unwind table is a "
+			   "no-can-do!\n", __FUNCTION__);
 		return;
 	}
 
@@ -1963,7 +2061,8 @@
 			if (prev->next == table)
 				break;
 		if (!prev) {
-			dprintk("unwind: failed to find unwind table %p\n", (void *) table);
+			UNW_DPRINT(0, "unwind.%s: failed to find unwind table %p\n",
+				   __FUNCTION__, (void *) table);
 			spin_unlock_irqrestore(&unw.lock, flags);
 			return;
 		}
@@ -2015,7 +2114,7 @@
 	unw.gate_table = alloc_bootmem(size);
 	if (!unw.gate_table) {
 		unw.gate_table_size = 0;
-		printk("unwind: unable to create unwind data for gate page!\n");
+		printk(KERN_ERR "unwind: unable to create unwind data for gate page!\n");
 		return;
 	}
 	unw.gate_table_size = size;
diff -urN linux-2.4.22-pre2/arch/ia64/kernel/unwind_i.h linux-2.4.22-pre3/arch/ia64/kernel/unwind_i.h
--- linux-2.4.22-pre2/arch/ia64/kernel/unwind_i.h	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/kernel/unwind_i.h	2003-07-05 18:09:39.000000000 -0700
@@ -137,7 +137,8 @@
 	UNW_INSN_SETNAT_MEMSTK,		/* s[dst+1].nat.type = MEMSTK;
 					   s[dst+1].nat.off = *s.pri_unat - s[dst] */
 	UNW_INSN_SETNAT_TYPE,		/* s[dst+1].nat.type = val */
-	UNW_INSN_LOAD			/* s[dst] = *s[val] */
+	UNW_INSN_LOAD,			/* s[dst] = *s[val] */
+	UNW_INSN_MOVE_SCRATCH,		/* s[dst] = scratch reg "val" */
 };
 
 struct unw_insn {
diff -urN linux-2.4.22-pre2/arch/ia64/lib/memcpy_mck.S linux-2.4.22-pre3/arch/ia64/lib/memcpy_mck.S
--- linux-2.4.22-pre2/arch/ia64/lib/memcpy_mck.S	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/lib/memcpy_mck.S	2003-07-05 18:09:40.000000000 -0700
@@ -163,7 +163,7 @@
 	mov	ar.ec=2
 (p10)	br.dpnt.few .aligned_src_tail
 	;;
-	.align 32
+//	.align 32
 1:
 EX(.ex_handler, (p16)	ld8	r34=[src0],16)
 EK(.ex_handler, (p16)	ld8	r38=[src1],16)
@@ -320,7 +320,7 @@
 (p7)	mov	ar.lc = r21
 (p8)	mov	ar.lc = r0
 	;;
-	.align 32
+//	.align 32
 1:	lfetch	  [src_pre_mem], 128
 	lfetch.excl [dst_pre_mem], 128
 	br.cloop.dptk.few 1b
@@ -526,7 +526,7 @@
 		 shrp	r21=r22,r38,shift;	/* speculative work */			\
 		 br.sptk.few .unaligned_src_tail /* branch out of jump table */		\
 		 ;;
-	.align 32
+//	.align 32
 .jump_table:
 	COPYU(8)	// unaligned cases
 .jmp1:
diff -urN linux-2.4.22-pre2/arch/ia64/lib/memset.S linux-2.4.22-pre3/arch/ia64/lib/memset.S
--- linux-2.4.22-pre2/arch/ia64/lib/memset.S	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/lib/memset.S	2003-07-05 18:09:40.000000000 -0700
@@ -125,7 +125,7 @@
 (p_zr)	br.cond.dptk.many .l1b			// Jump to use stf.spill
 ;; }
 
-	.align 32 // -------------------------- //  L1A: store ahead into cache lines; fill later
+//	.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
@@ -194,7 +194,7 @@
 	br.cond.dpnt.many  .move_bytes_from_alignment	// Branch no. 3
 ;; }
 
-	.align 32
+//	.align 32
 .l1b:	// ------------------------------------ //  L1B: store ahead into cache lines; fill later
 { .mmi
 	and	tmp = -(LINE_SIZE), cnt		// compute end of range
@@ -261,7 +261,7 @@
 	and	cnt = 0x1f, cnt			// compute the remaining cnt
 	mov.i   ar.lc = loopcnt
 ;; }
-	.align 32
+//	.align 32
 .l2:	// ------------------------------------ //  L2A:  store 32B in 2 cycles
 { .mmb
 	stf8	[ptr1] = fvalue, 8
diff -urN linux-2.4.22-pre2/arch/ia64/lib/swiotlb.c linux-2.4.22-pre3/arch/ia64/lib/swiotlb.c
--- linux-2.4.22-pre2/arch/ia64/lib/swiotlb.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/lib/swiotlb.c	2003-07-05 18:09:40.000000000 -0700
@@ -116,7 +116,7 @@
 	io_tlb_index = 0;
 	io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *));
 
-	printk("Placing software IO TLB between 0x%p - 0x%p\n",
+	printk(KERN_INFO "Placing software IO TLB between 0x%p - 0x%p\n",
 	       (void *) io_tlb_start, (void *) io_tlb_end);
 }
 
diff -urN linux-2.4.22-pre2/arch/ia64/mm/extable.c linux-2.4.22-pre3/arch/ia64/mm/extable.c
--- linux-2.4.22-pre2/arch/ia64/mm/extable.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/mm/extable.c	2003-07-05 18:09:40.000000000 -0700
@@ -38,6 +38,8 @@
 register unsigned long main_gp __asm__("gp");
 #endif
 
+extern spinlock_t modlist_lock;
+
 struct exception_fixup
 search_exception_table (unsigned long addr)
 {
@@ -52,9 +54,11 @@
 	return fix;
 #else
 	struct archdata *archdata;
+	unsigned long flags;
 	struct module *mp;
 
 	/* The kernel is the last "module" -- no need to treat it special. */
+	spin_lock_irqsave(&modlist_lock, flags);
 	for (mp = module_list; mp; mp = mp->next) {
 		if (!mp->ex_table_start)
 			continue;
@@ -65,9 +69,10 @@
 					 addr, (unsigned long) archdata->gp);
 		if (entry) {
 			fix.cont = entry->cont + (unsigned long) archdata->gp;
-			return fix;
+			break;
 		}
 	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
 #endif
 	return fix;
 }
diff -urN linux-2.4.22-pre2/arch/ia64/mm/fault.c linux-2.4.22-pre3/arch/ia64/mm/fault.c
--- linux-2.4.22-pre2/arch/ia64/mm/fault.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/mm/fault.c	2003-07-05 18:09:40.000000000 -0700
@@ -43,6 +43,33 @@
 	return 0;
 }
 
+/*
+ * Return TRUE if ADDRESS points at a page in the kernel's mapped segment
+ * (inside region 5, on ia64) and that page is present.
+ */
+static int
+mapped_kernel_page_is_present (unsigned long address)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *ptep, pte;
+
+	pgd = pgd_offset_k(address);
+	if (pgd_none(*pgd) || pgd_bad(*pgd))
+		return 0;
+
+	pmd = pmd_offset(pgd,address);
+	if (pmd_none(*pmd) || pmd_bad(*pmd))
+		return 0;
+
+	ptep = pte_offset(pmd, address);
+	if (!ptep)
+		return 0;
+
+	pte = *ptep;
+	return pte_present(pte);
+}
+
 void
 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
 {
@@ -183,6 +210,16 @@
 		return;
 
 	/*
+	 * Since we have no vma's for region 5, we might get here even if the address is
+	 * valid, due to the VHPT walker inserting a non present translation that becomes
+	 * stale. If that happens, the non present fault handler already purged the stale
+	 * translation, which fixed the problem. So, we check to see if the translation is
+	 * valid, and return if it is.
+	 */
+	if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address))
+		return;
+
+	/*
 	 * Oops. The kernel tried to access some bad page. We'll have to terminate things
 	 * with extreme prejudice.
 	 */
@@ -204,7 +241,7 @@
 		goto survive;
 	}
 	up_read(&mm->mmap_sem);
-	printk("VM: killing process %s\n", current->comm);
+	printk(KERN_CRIT "VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
 	goto no_context;
diff -urN linux-2.4.22-pre2/arch/ia64/mm/init.c linux-2.4.22-pre3/arch/ia64/mm/init.c
--- linux-2.4.22-pre2/arch/ia64/mm/init.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/mm/init.c	2003-07-05 18:09:40.000000000 -0700
@@ -255,7 +255,7 @@
 	pte_t *pte;
 
 	if (!PageReserved(page))
-		printk("put_gate_page: gate page at 0x%p not in reserved memory\n",
+		printk(KERN_ERR "put_gate_page: gate page at 0x%p not in reserved memory\n",
 		       page_address(page));
 
 	pgd = pgd_offset_k(address);		/* note: this is NOT pgd_offset()! */
@@ -560,7 +560,7 @@
 		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);
+		printk(KERN_INFO "Virtual mem_map starts at 0x%p\n", mem_map);
 	}
 #endif
 }
diff -urN linux-2.4.22-pre2/arch/ia64/mm/tlb.c linux-2.4.22-pre3/arch/ia64/mm/tlb.c
--- linux-2.4.22-pre2/arch/ia64/mm/tlb.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/mm/tlb.c	2003-07-05 18:09:40.000000000 -0700
@@ -34,10 +34,10 @@
 		1 << _PAGE_SIZE_4K )
 
 struct ia64_ctx ia64_ctx = {
-	lock:	SPIN_LOCK_UNLOCKED,
-	next:	1,
-	limit:	(1 << 15) - 1,		/* start out with the safe (architected) limit */
-	max_ctx: ~0U
+	.lock =	SPIN_LOCK_UNLOCKED,
+	.next =	1,
+	.limit =(1 << 15) - 1,		/* start out with the safe (architected) limit */
+	.max_ctx = ~0U
 };
 
 /*
@@ -48,6 +48,7 @@
 {
 	unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx;
 	struct task_struct *tsk;
+	int i;
 
 	if (ia64_ctx.next > max_ctx)
 		ia64_ctx.next = 300;	/* skip daemons */
@@ -76,7 +77,14 @@
 			ia64_ctx.limit = tsk_context;
 	}
 	read_unlock(&tasklist_lock);
-	flush_tlb_all();
+	/*
+	 * Can't call flush_tlb_all() here because of race condition with scheduler [EF]
+	 * and because interrupts are disabled during context switch.
+	 */
+	for (i = 0; i < NR_CPUS; ++i)
+		if (i != smp_processor_id())
+			cpu_data(i)->need_tlb_flush = 1;
+	local_flush_tlb_all();
 }
 
 void
diff -urN linux-2.4.22-pre2/arch/ia64/scripts/unwcheck.sh linux-2.4.22-pre3/arch/ia64/scripts/unwcheck.sh
--- linux-2.4.22-pre2/arch/ia64/scripts/unwcheck.sh	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/scripts/unwcheck.sh	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,109 @@
+#!/bin/sh
+#   Usage: unwcheck.sh <executable_file_name>
+#   Pre-requisite: readelf [from Gnu binutils package]
+#   Purpose: Check the following invariant
+#       For each code range in the input binary:
+#          Sum[ lengths of unwind regions] = Number of slots in code range.
+#   Author : Harish Patil
+#   First version: January 2002
+#   Modified : 2/13/2002
+#   Modified : 3/15/2002: duplicate detection
+readelf -u $1 | gawk '\
+ function todec(hexstr){
+    dec = 0;
+    l = length(hexstr);
+    for (i = 1; i <= l; i++)
+    {
+        c = substr(hexstr, i, 1);
+        if (c == "A")
+            dec = dec*16 + 10;
+        else if (c == "B")
+            dec = dec*16 + 11;
+        else if (c == "C")
+            dec = dec*16 + 12;
+        else if (c == "D")
+            dec = dec*16 + 13;
+        else if (c == "E")
+            dec = dec*16 + 14;
+        else if (c == "F")
+            dec = dec*16 + 15;
+        else
+            dec = dec*16 + c;
+    }
+    return dec;
+ }
+ BEGIN { first = 1; sum_rlen = 0; no_slots = 0; errors=0; no_code_ranges=0; }
+ {
+   if (NF==5 && $3=="info")
+   {
+      no_code_ranges += 1;
+      if (first == 0)
+      {
+         if (sum_rlen != no_slots)
+         {
+            print full_code_range;
+            print "       ", "lo = ", lo, " hi =", hi;
+            print "       ", "sum_rlen = ", sum_rlen, "no_slots = " no_slots;
+            print "       ","   ", "*******ERROR ***********";
+            print "       ","   ", "sum_rlen:", sum_rlen, " != no_slots:" no_slots;
+            errors += 1;
+         }
+         sum_rlen = 0;
+      }
+      full_code_range =  $0;
+      code_range =  $2;
+      gsub("..$", "", code_range);
+      gsub("^.", "", code_range);
+      split(code_range, addr, "-");
+      lo = toupper(addr[1]);
+
+      code_range_lo[no_code_ranges] = addr[1];
+      occurs[addr[1]] += 1;
+      full_range[addr[1]] = $0;
+
+      gsub("0X.[0]*", "", lo);
+      hi = toupper(addr[2]);
+      gsub("0X.[0]*", "", hi);
+      no_slots = (todec(hi) - todec(lo))/ 16*3
+      first = 0;
+   }
+   if (index($0,"rlen") > 0 )
+   {
+    rlen_str =  substr($0, index($0,"rlen"));
+    rlen = rlen_str;
+    gsub("rlen=", "", rlen);
+    gsub(")", "", rlen);
+    sum_rlen = sum_rlen +  rlen;
+   }
+  }
+  END {
+      if (first == 0)
+      {
+         if (sum_rlen != no_slots)
+         {
+            print "code_range=", code_range;
+            print "       ", "lo = ", lo, " hi =", hi;
+            print "       ", "sum_rlen = ", sum_rlen, "no_slots = " no_slots;
+            print "       ","   ", "*******ERROR ***********";
+            print "       ","   ", "sum_rlen:", sum_rlen, " != no_slots:" no_slots;
+            errors += 1;
+         }
+      }
+    no_duplicates = 0;
+    for (i=1; i<=no_code_ranges; i++)
+    {
+        cr = code_range_lo[i];
+        if (reported_cr[cr]==1) continue;
+        if ( occurs[cr] > 1)
+        {
+            reported_cr[cr] = 1;
+            print "Code range low ", code_range_lo[i], ":", full_range[cr], " occurs: ", occurs[cr], " times.";
+            print " ";
+            no_duplicates++;
+        }
+    }
+    print "======================================"
+    print "Total errors:", errors, "/", no_code_ranges, " duplicates:", no_duplicates;
+    print "======================================"
+  }
+  '
diff -urN linux-2.4.22-pre2/arch/ia64/sn/fakeprom/Makefile linux-2.4.22-pre3/arch/ia64/sn/fakeprom/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/fakeprom/Makefile	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/fakeprom/Makefile	2003-07-05 18:09:40.000000000 -0700
@@ -3,7 +3,7 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-#  Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+#  Copyright (c) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
 #
 
 TOPDIR=../../../..
@@ -13,14 +13,15 @@
 
 OBJ=fpromasm.o main.o  fw-emu.o fpmem.o klgraph_init.o
 obj-y=fprom
+EXTRA_CFLAGS += -DSGI_SN2
+EXTRA_AFLAGS += -DSGI_SN2
+AFLAGS += -DSGI_SN2
 
 fprom: $(OBJ)
 	$(LD) -static -Tfprom.lds -o fprom $(OBJ) $(LIB)
 
 .S.o:
-	$(CC)  -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
-.c.o:
-	$(CC)  $(CFLAGS) $(CFLAGS_KERNEL) -c -o $*.o $<
+	$(CC)  -D__ASSEMBLY__ $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
 
 clean:
 	rm -f *.o fprom
diff -urN linux-2.4.22-pre2/arch/ia64/sn/fakeprom/README linux-2.4.22-pre3/arch/ia64/sn/fakeprom/README
--- linux-2.4.22-pre2/arch/ia64/sn/fakeprom/README	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/fakeprom/README	2003-07-05 18:09:40.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
diff -urN linux-2.4.22-pre2/arch/ia64/sn/fakeprom/fpmem.c linux-2.4.22-pre3/arch/ia64/sn/fakeprom/fpmem.c
--- linux-2.4.22-pre2/arch/ia64/sn/fakeprom/fpmem.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/fakeprom/fpmem.c	2003-07-05 18:09:40.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -13,7 +13,7 @@
  * FPROM EFI memory descriptor build routines
  *
  * 	- Routines to build the EFI memory descriptor map
- * 	- Should also be usable by the SGI SN1 prom to convert
+ * 	- Should also be usable by the SGI prom to convert
  * 	  klconfig to efi_memmap
  */
 
@@ -53,10 +53,7 @@
 #define KERNEL_SIZE		(4*MB)
 #define PROMRESERVED_SIZE	(1*MB)
 
-#ifdef CONFIG_IA64_SGI_SN1
-#define PHYS_ADDRESS(_n, _x)		(((long)_n<<33) | (long)_x)
-#define MD_BANK_SHFT 30
-#else
+#ifdef SGI_SN2
 #define PHYS_ADDRESS(_n, _x)		(((long)_n<<38) | (long)_x | 0x3000000000UL)
 #define MD_BANK_SHFT 34
 #endif
@@ -77,7 +74,7 @@
 	return sn_config->cpus;
 }
 
-/* For SN1, get the index th nasid */
+/* For SN, get the index th nasid */
 
 int
 GetNasid(int index)
@@ -104,40 +101,7 @@
  * actually disabled etc.
  */
 
-#ifdef CONFIG_IA64_SGI_SN1
-int
-IsBankPresent(int index, node_memmap_t nmemmap)
-{
-	switch (index) {
-		case 0:return nmemmap.b0;
-		case 1:return nmemmap.b1;
-		case 2:return nmemmap.b2;
-		case 3:return nmemmap.b3;
-		case 4:return nmemmap.b4;
-		case 5:return nmemmap.b5;
-		case 6:return nmemmap.b6;
-		case 7:return nmemmap.b7;
-		default:return -1 ;
-	}
-}
-
-int
-GetBankSize(int index, node_memmap_t nmemmap)
-{
-        switch (index) {
-                case 0:
-                case 1:return nmemmap.b01size;
-                case 2:
-                case 3:return nmemmap.b23size;
-                case 4:
-                case 5:return nmemmap.b45size;
-                case 6:
-                case 7:return nmemmap.b67size;
-                default:return -1 ;
-        }
-}
-
-#else
+#ifdef SGI_SN2
 int
 IsBankPresent(int index, node_memmap_t nmemmap)
 {
@@ -168,13 +132,13 @@
 #endif
 
 void
-build_mem_desc(efi_memory_desc_t *md, int type, long paddr, long numbytes)
+build_mem_desc(efi_memory_desc_t *md, int type, long paddr, long numbytes, long attr)
 {
         md->type = type;
         md->phys_addr = paddr;
         md->virt_addr = 0;
         md->num_pages = numbytes >> 12;
-        md->attribute = EFI_MEMORY_WB;
+        md->attribute = attr;
 }
 
 int
@@ -192,12 +156,12 @@
 	for (cnode=0;cnode<numnodes;cnode++) {
 		nasid = GetNasid(cnode) ;
 		membank_info = GetMemBankInfo(cnode) ;
-		for (bank=0;bank<PLAT_CLUMPS_PER_NODE;bank++) {
+		for (bank=0;bank<MD_BANKS_PER_NODE;bank++) {
 			if (IsBankPresent(bank, membank_info)) {
 				bsize = GetBankSize(bank, membank_info) ;
                                 paddr = PHYS_ADDRESS(nasid, (long)bank<<MD_BANK_SHFT);
                                 numbytes = BankSizeBytes(bsize);
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 				/* 
 				 * Ignore directory.
 				 * Shorten memory chunk by 1 page - makes a better
@@ -236,28 +200,40 @@
                                  */
                                 if (bank == 0) {
 					if (cnode == 0) {
+						hole = 2*1024*1024;
+						build_mem_desc(md, EFI_PAL_CODE, paddr, hole, EFI_MEMORY_WB|EFI_MEMORY_WB);
+						numbytes -= hole;
+                                        	paddr += hole;
+			        		count++ ;
+                                        	md += mdsize;
 						hole = 1*1024*1024;
-						build_mem_desc(md, EFI_PAL_CODE, paddr, hole);
+						build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, hole, EFI_MEMORY_UC);
 						numbytes -= hole;
                                         	paddr += hole;
 			        		count++ ;
                                         	md += mdsize;
-						hole = 3*1024*1024;
-						build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole);
+						hole = 1*1024*1024;
+						build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole, EFI_MEMORY_WB|EFI_MEMORY_WB);
 						numbytes -= hole;
                                         	paddr += hole;
 			        		count++ ;
                                         	md += mdsize;
 					} else {
-						hole = PROMRESERVED_SIZE;
-                                        	build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole);
+						hole = 2*1024*1024;
+                                        	build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole, EFI_MEMORY_WB|EFI_MEMORY_WB);
+						numbytes -= hole;
+                                        	paddr += hole;
+			        		count++ ;
+                                        	md += mdsize;
+						hole = 2*1024*1024;
+                                        	build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole, EFI_MEMORY_UC);
 						numbytes -= hole;
                                         	paddr += hole;
 			        		count++ ;
                                         	md += mdsize;
 					}
                                 }
-                                build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, numbytes);
+                                build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, numbytes, EFI_MEMORY_WB|EFI_MEMORY_WB);
 
 			        md += mdsize ;
 			        count++ ;
diff -urN linux-2.4.22-pre2/arch/ia64/sn/fakeprom/fpmem.h linux-2.4.22-pre3/arch/ia64/sn/fakeprom/fpmem.h
--- linux-2.4.22-pre2/arch/ia64/sn/fakeprom/fpmem.h	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/fakeprom/fpmem.h	2003-07-05 18:09:40.000000000 -0700
@@ -4,13 +4,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 #include <linux/config.h>
 
 /*
- * Structure of the mem config of the node as a SN1 MI reg
+ * Structure of the mem config of the node as a SN MI reg
  * Medusa supports this reg config.
  *
  * BankSize nibble to bank size mapping
@@ -24,32 +24,7 @@
 
 #define MBSHIFT				20
 
-#ifdef CONFIG_IA64_SGI_SN1
-typedef struct node_memmap_s
-{
-        unsigned int    b0      :1,     /* 0 bank 0 present */
-                        b1      :1,     /* 1 bank 1 present */
-                        r01     :2,     /* 2-3 reserved */
-                        b01size :4,     /* 4-7 Size of bank 0 and 1 */
-                        b2      :1,     /* 8 bank 2 present */
-                        b3      :1,     /* 9 bank 3 present */
-                        r23     :2,     /* 10-11 reserved */
-                        b23size :4,     /* 12-15 Size of bank 2 and 3 */
-                        b4      :1,     /* 16 bank 4 present */
-                        b5      :1,     /* 17 bank 5 present */
-                        r45     :2,     /* 18-19 reserved */
-                        b45size :4,     /* 20-23 Size of bank 4 and 5 */
-                        b6      :1,     /* 24 bank 6 present */
-                        b7      :1,     /* 25 bank 7 present */
-                        r67     :2,     /* 26-27 reserved */
-                        b67size :4;     /* 28-31 Size of bank 6 and 7 */
-} node_memmap_t ;
-
-/* Support the medusa hack for 8M/16M/32M nodes */
-#define SN1_BANK_SIZE_SHIFT		(MBSHIFT+6)     /* 64 MB */
-#define BankSizeBytes(bsize)            ((bsize<6) ? (1<<((bsize-1)+SN1_BANK_SIZE_SHIFT)) :\
-                                         (1<<((bsize-9)+MBSHIFT)))
-#else
+#ifdef SGI_SN2
 typedef struct node_memmap_s
 {
         unsigned int    b0size  :3,     /* 0-2   bank 0 size */
@@ -73,6 +48,8 @@
 #define SN2_BANK_SIZE_SHIFT		(MBSHIFT+6)     /* 64 MB */
 #define BankPresent(bsize)		(bsize<6)
 #define BankSizeBytes(bsize)            (BankPresent(bsize) ? 1UL<<((bsize)+SN2_BANK_SIZE_SHIFT) : 0)
+#define MD_BANKS_PER_NODE 4
+#define MD_BANKSIZE			(1UL << 34)
 #endif
 
 typedef struct sn_memmap_s
diff -urN linux-2.4.22-pre2/arch/ia64/sn/fakeprom/fprom.lds linux-2.4.22-pre3/arch/ia64/sn/fakeprom/fprom.lds
--- linux-2.4.22-pre2/arch/ia64/sn/fakeprom/fprom.lds	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/fakeprom/fprom.lds	2003-07-05 18:09:40.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
diff -urN linux-2.4.22-pre2/arch/ia64/sn/fakeprom/fpromasm.S linux-2.4.22-pre3/arch/ia64/sn/fakeprom/fpromasm.S
--- linux-2.4.22-pre2/arch/ia64/sn/fakeprom/fpromasm.S	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/fakeprom/fpromasm.S	2003-07-05 18:09:40.000000000 -0700
@@ -8,7 +8,7 @@
  * Copyright (C) 1998-2000 Hewlett-Packard Co
  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -57,9 +57,7 @@
  * be 0x00000ffffc000000, but on snia we use the (inverse swizzled)
  * IOSPEC_BASE value
  */
-#ifdef CONFIG_IA64_SGI_SN1
-#define IOPB_PA		0xc0000FFFFC000000
-#else
+#ifdef SGI_SN2
 #define IOPB_PA		0xc000000fcc000000
 #endif
 
@@ -84,10 +82,7 @@
 
 // Isolate node number we are running on.
 	mov		r6 = ip;;
-#ifdef CONFIG_IA64_SGI_SN1
-	shr		r5 = r6,33;;			// r5 = node number
-	shl		r6 = r5,33			// r6 = base memory address of node
-#else
+#ifdef SGI_SN2
 	shr		r5 = r6,38			// r5 = node number
 	dep		r6 = 0,r6,0,36			// r6 = base memory address of node
 
@@ -99,7 +94,7 @@
 	or 		r1 = r1,r6			// Relocate to boot node
 
 // Lets figure out who we are & put it in the LID register.
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 // On SN2, we (currently) pass the cpu number in r10 at boot
 	and		r25=3,r10;;
 	movl		r16=0x8000008110000400		// Allow IPIs
@@ -324,10 +319,7 @@
 1:	cmp.eq	p6,p7=8,r28		/* PAL_VM_SUMMARY */
 (p7)	br.cond.sptk.few 1f
 	movl	r8=0
-#ifdef CONFIG_IA64_SGI_SN1
-	movl	r9=0x0203083001151059
-	movl	r10=0x1232
-#else
+#ifdef SGI_SN2
 	movl	r9=0x0203083001151065
 	movl	r10=0x183f
 #endif
diff -urN linux-2.4.22-pre2/arch/ia64/sn/fakeprom/fw-emu.c linux-2.4.22-pre3/arch/ia64/sn/fakeprom/fw-emu.c
--- linux-2.4.22-pre2/arch/ia64/sn/fakeprom/fw-emu.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/fakeprom/fw-emu.c	2003-07-05 18:09:40.000000000 -0700
@@ -5,7 +5,7 @@
  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  *
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -42,7 +42,7 @@
 #include <asm/sn/sn_sal.h>
 #include <asm/processor.h>
 #include <asm/sn/sn_cpuid.h>
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 #include <asm/sn/sn2/addrs.h>
 #include <asm/sn/sn2/shub_mmr.h>
 #endif
@@ -68,10 +68,7 @@
 #define ACPI_SLIT_REVISION 1
 
 #define OEMID			"SGI"
-#ifdef CONFIG_IA64_SGI_SN1
-#define PRODUCT			"SN1"
-#define PROXIMITY_DOMAIN(nasid)	(nasid)
-#else
+#ifdef SGI_SN2
 #define PRODUCT			"SN2"
 #define PROXIMITY_DOMAIN(nasid)	(((nasid)>>1) & 255)
 #endif
@@ -99,12 +96,7 @@
 
 typedef union ia64_nasid_va {
         struct {
-#if defined(CONFIG_IA64_SGI_SN1)
-                unsigned long off   : 33;       /* intra-region offset */
-		unsigned long nasid :  7;	/* NASID */
-		unsigned long off2  : 21;	/* fill */
-                unsigned long reg   :  3;       /* region number */
-#elif defined(CONFIG_IA64_SGI_SN2)
+#if defined(SGI_SN2)
                 unsigned long off   : 36;       /* intra-region offset */
 		unsigned long attr  :  2;
 		unsigned long nasid : 11;	/* NASID */
@@ -124,9 +116,7 @@
 #define IS_VIRTUAL_MODE() 	 ({struct ia64_psr psr; asm("mov %0=psr" : "=r"(psr)); psr.dt;})
 #define ADDR_OF(p)		(IS_VIRTUAL_MODE() ? ((void*)((long)(p)+PAGE_OFFSET)) : ((void*) (p)))
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#define __fwtab_pa(n,x)		({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.l;})
-#elif defined(CONFIG_IA64_SGI_SN2)
+#if defined(SGI_SN2)
 #define __fwtab_pa(n,x)		({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.f.attr = 3; _v.l;})
 #endif
 
@@ -207,7 +197,7 @@
 	return EFI_UNSUPPORTED;
 }
 
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 
 #undef cpu_physical_id
 #define cpu_physical_id(cpuid)                  ((ia64_get_lid() >> 16) & 0xffff)
@@ -300,7 +290,7 @@
 		;
 	} else if (index == SAL_UPDATE_PAL) {
 		;
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 	} else if (index == SN_SAL_LOG_CE) {
 #ifdef ajmtestcpei
 		fprom_send_cpei();
@@ -500,9 +490,7 @@
 	/*
 	 * Pass the parameter base address to the build_efi_xxx routines.
 	 */
-#if defined(CONFIG_IA64_SGI_SN1)
-	build_init(8LL*GB*base_nasid);
-#else
+#if defined(SGI_SN2)
 	build_init(0x3000000000UL | ((long)base_nasid<<38));
 #endif
 
@@ -624,10 +612,7 @@
 			lsapic20->header.length = sizeof(struct acpi_table_lsapic);
 			lsapic20->acpi_id = cnode*4+cpu;
 			lsapic20->flags.enabled = 1;
-#if defined(CONFIG_IA64_SGI_SN1)
-			lsapic20->eid = cpu;
-			lsapic20->id = nasid;
-#else
+#if defined(SGI_SN2)
 			lsapic20->eid = nasid&0xffff;
 			lsapic20->id = (cpu<<4) | (nasid>>16);
 #endif
@@ -648,12 +633,9 @@
 		srat_memory_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
 		srat_memory_affinity->base_addr_lo = 0;
 		srat_memory_affinity->length_lo = 0;
-#if defined(CONFIG_IA64_SGI_SN1)
-		srat_memory_affinity->base_addr_hi = nasid<<1;
-		srat_memory_affinity->length_hi = SN1_NODE_SIZE>>32;
-#else
+#if defined(SGI_SN2)
 		srat_memory_affinity->base_addr_hi = (nasid<<6) | (3<<4);
-		srat_memory_affinity->length_hi = SN2_NODE_SIZE>>32;
+		srat_memory_affinity->length_hi = (MD_BANKSIZE*MD_BANKS_PER_NODE)>>32;
 #endif
 		srat_memory_affinity->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
 		srat_memory_affinity->flags.enabled = 1;
@@ -670,10 +652,7 @@
 			srat_cpu_affinity->header.length = sizeof(struct acpi_table_processor_affinity);
 			srat_cpu_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
 			srat_cpu_affinity->flags.enabled = 1;
-#if defined(CONFIG_IA64_SGI_SN1)
-			srat_cpu_affinity->apic_id = nasid;
-			srat_cpu_affinity->lsapic_eid = cpu;
-#else
+#if defined(SGI_SN2)
 			srat_cpu_affinity->lsapic_eid = nasid&0xffff;
 			srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>16);
 #endif
@@ -707,7 +686,7 @@
 	sal_systab->sal_b_rev_minor = 0x0; /* 1.00 */
 
 	strcpy(sal_systab->oem_id, "SGI");
-	strcpy(sal_systab->product_id, "SN1");
+	strcpy(sal_systab->product_id, "SN2");
 
 	/* fill in an entry point: */	
 	sal_ed->type = SAL_DESC_ENTRY_POINT;
@@ -785,9 +764,7 @@
 		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
 			if (!IsCpuPresent(cnode, cpu))
 				continue;
-#ifdef CONFIG_IA64_SGI_SN1
-			bsp_lid = (GetNasid(cnode)<<24) | (cpu<<16);
-#else
+#ifdef SGI_SN2
 			bsp_lid = (GetNasid(cnode)<<16) | (cpu<<28);
 #endif
 			if (bsp-- > 0)
diff -urN linux-2.4.22-pre2/arch/ia64/sn/fakeprom/klgraph_init.c linux-2.4.22-pre3/arch/ia64/sn/fakeprom/klgraph_init.c
--- linux-2.4.22-pre2/arch/ia64/sn/fakeprom/klgraph_init.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/fakeprom/klgraph_init.c	2003-07-05 18:09:40.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 
@@ -49,41 +49,13 @@
 klgraph_init(void)
 {
 
-#ifdef CONFIG_IA64_SGI_SN1
 	u64 *temp;
-#endif
 	/*
 	 * Initialize some hub/xbow registers that allows access to 
 	 * Xbridge etc.  These are normally done in PROM.
 	 */
 
         /* Write IOERR clear to clear the CRAZY bit in the status */
-#ifdef CONFIG_IA64_SGI_SN1
-        *(volatile uint64_t *)0xc0000a0001c001f8 = (uint64_t)0xffffffff;
-
-        /* set widget control register...setting bedrock widget id to b */
-        *(volatile uint64_t *)0xc0000a0001c00020 = (uint64_t)0x801b;
-
-        /* set io outbound widget access...allow all */
-        *(volatile uint64_t *)0xc0000a0001c00110 = (uint64_t)0xff01;
-
-        /* set io inbound widget access...allow all */
-        *(volatile uint64_t *)0xc0000a0001c00118 = (uint64_t)0xff01;
-
-        /* set io crb timeout to max */
-        *(volatile uint64_t *)0xc0000a0001c003c0 = (uint64_t)0xffffff;
-        *(volatile uint64_t *)0xc0000a0001c003c0 = (uint64_t)0xffffff;
-
-        /* set local block io permission...allow all */
-        *(volatile uint64_t *)0xc0000a0001e04010 = (uint64_t)0xfffffffffffffff;
-
-        /* clear any errors */
-        /* clear_ii_error(); medusa should have cleared these */
-
-        /* set default read response buffers in bridge */
-        *(volatile u32 *)0xc0000a000f000280L = 0xba98;
-        *(volatile u32 *)0xc0000a000f000288L = 0xba98;
-#elif CONFIG_IA64_SGI_SN2
         *(volatile uint64_t *)0xc000000801c001f8 = (uint64_t)0xffffffff;
 
         /* set widget control register...setting bedrock widget id to a */
@@ -108,184 +80,126 @@
         /* set default read response buffers in bridge */
 // [PI]       *(volatile u32 *)0xc00000080f000280L = 0xba98;
 // [PI]       *(volatile u32 *)0xc00000080f000288L = 0xba98;
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-#ifdef CONFIG_IA64_SGI_SN1
-
-	/*
-	 * kldir entries initialization - mankato
-	 */
-	convert(0x8000000000002000, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002010, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002020, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002030, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002040, 0x434d5f53505f5357, 0x0000000000030000);
-	convert(0x8000000000002050, 0x0000000000000000, 0x0000000000010000);
-	convert(0x8000000000002060, 0x0000000000000001, 0x0000000000000000);
-	convert(0x8000000000002070, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002080, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002090, 0x0000000000000000, 0x0000000000000000);
-	convert(0x80000000000020a0, 0x0000000000000000, 0x0000000000000000);
-	convert(0x80000000000020b0, 0x0000000000000000, 0x0000000000000000);
-	convert(0x80000000000020c0, 0x434d5f53505f5357, 0x0000000000000000);
-	convert(0x80000000000020d0, 0x0000000000002400, 0x0000000000000400);
-	convert(0x80000000000020e0, 0x0000000000000001, 0x0000000000000000);
-	convert(0x80000000000020f0, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002100, 0x434d5f53505f5357, 0x0000000000040000);
-	convert(0x8000000000002110, 0x0000000000000000, 0xffffffffffffffff);
-	convert(0x8000000000002120, 0x0000000000000001, 0x0000000000000000);
-	convert(0x8000000000002130, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002140, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002150, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002160, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002170, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002180, 0x434d5f53505f5357, 0x0000000000020000);
-	convert(0x8000000000002190, 0x0000000000000000, 0x0000000000010000);
-	convert(0x80000000000021a0, 0x0000000000000001, 0x0000000000000000); 
 
-	/*
-	 * klconfig entries initialization - mankato
-	 */
-	convert(0x0000000000030000, 0x00000000beedbabe, 0x0000004800000000);
-	convert(0x0000000000030010, 0x0003007000000018, 0x800002000f820178);
-	convert(0x0000000000030020, 0x80000a000f024000, 0x800002000f800000);
-	convert(0x0000000000030030, 0x0300fafa00012580, 0x00000000040f0000);
-	convert(0x0000000000030040, 0x0000000000000000, 0x0003097000030070);
-	convert(0x0000000000030050, 0x00030970000303b0, 0x0003181000033f70);
-	convert(0x0000000000030060, 0x0003d51000037570, 0x0000000000038330);
-	convert(0x0000000000030070, 0x0203110100030140, 0x0001000000000101);
-	convert(0x0000000000030080, 0x0900000000000000, 0x000000004e465e67);
-	convert(0x0000000000030090, 0x0003097000000000, 0x00030b1000030a40);
-	convert(0x00000000000300a0, 0x00030cb000030be0, 0x000315a0000314d0);
-	convert(0x00000000000300b0, 0x0003174000031670, 0x0000000000000000);
-	convert(0x0000000000030100, 0x000000000000001a, 0x3350490000000000);
-	convert(0x0000000000030110, 0x0000000000000037, 0x0000000000000000);
-	convert(0x0000000000030140, 0x0002420100030210, 0x0001000000000101);
-	convert(0x0000000000030150, 0x0100000000000000, 0xffffffffffffffff);
-	convert(0x0000000000030160, 0x00030d8000000000, 0x0000000000030e50);
-	convert(0x00000000000301c0, 0x0000000000000000, 0x0000000000030070);
-	convert(0x00000000000301d0, 0x0000000000000025, 0x424f490000000000);
-	convert(0x00000000000301e0, 0x000000004b434952, 0x0000000000000000);
-	convert(0x0000000000030210, 0x00027101000302e0, 0x00010000000e4101);
-	convert(0x0000000000030220, 0x0200000000000000, 0xffffffffffffffff);
-	convert(0x0000000000030230, 0x00030f2000000000, 0x0000000000030ff0);
-	convert(0x0000000000030290, 0x0000000000000000, 0x0000000000030140);
-	convert(0x00000000000302a0, 0x0000000000000026, 0x7262490000000000);
-	convert(0x00000000000302b0, 0x00000000006b6369, 0x0000000000000000);
-	convert(0x00000000000302e0, 0x0002710100000000, 0x00010000000f3101);
-	convert(0x00000000000302f0, 0x0500000000000000, 0xffffffffffffffff);
-	convert(0x0000000000030300, 0x000310c000000000, 0x0003126000031190);
-	convert(0x0000000000030310, 0x0003140000031330, 0x0000000000000000);
-	convert(0x0000000000030360, 0x0000000000000000, 0x0000000000030140);
-	convert(0x0000000000030370, 0x0000000000000029, 0x7262490000000000);
-	convert(0x0000000000030380, 0x00000000006b6369, 0x0000000000000000);
-	convert(0x0000000000030970, 0x0000000002010102, 0x0000000000000000);
-	convert(0x0000000000030980, 0x000000004e465e67, 0xffffffff00000000);
-	/* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */
-	convert(0x00000000000309a0, 0x0000000000037570, 0xffffffff00000000);
-	convert(0x00000000000309b0, 0x0000000000030070, 0x0000000000000000);
-	convert(0x00000000000309c0, 0x000000000003f420, 0x0000000000000000);
-	convert(0x0000000000030a40, 0x0000000002010125, 0x0000000000000000);
-	convert(0x0000000000030a50, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000030a70, 0x0000000000037b78, 0x0000000000000000);
-	convert(0x0000000000030b10, 0x0000000002010125, 0x0000000000000000);
-	convert(0x0000000000030b20, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000030b40, 0x0000000000037d30, 0x0000000000000001);
-	convert(0x0000000000030be0, 0x00000000ff010203, 0x0000000000000000);
-	convert(0x0000000000030bf0, 0xffffffffffffffff, 0xffffffff000000ff);
-	convert(0x0000000000030c10, 0x0000000000037ee8, 0x0100010000000200);
-	convert(0x0000000000030cb0, 0x00000000ff310111, 0x0000000000000000);
-	convert(0x0000000000030cc0, 0xffffffffffffffff, 0x0000000000000000);
-	convert(0x0000000000030d80, 0x0000000002010104, 0x0000000000000000);
-	convert(0x0000000000030d90, 0xffffffffffffffff, 0x00000000000000ff);
-	convert(0x0000000000030db0, 0x0000000000037f18, 0x0000000000000000);
-	convert(0x0000000000030dc0, 0x0000000000000000, 0x0003007000060000);
-	convert(0x0000000000030de0, 0x0000000000000000, 0x0003021000050000);
-	convert(0x0000000000030df0, 0x000302e000050000, 0x0000000000000000);
-	convert(0x0000000000030e30, 0x0000000000000000, 0x000000000000000a);
-	convert(0x0000000000030e50, 0x00000000ff00011a, 0x0000000000000000);
-	convert(0x0000000000030e60, 0xffffffffffffffff, 0x0000000000000000);
-	convert(0x0000000000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e);
-	convert(0x0000000000030e90, 0x000000000000bc6e, 0x0000000000000000);
-	convert(0x0000000000030f20, 0x0000000002010205, 0x00000000d0020000);
-	convert(0x0000000000030f30, 0xffffffffffffffff, 0x0000000e0000000e);
-	convert(0x0000000000030f40, 0x000000000000000e, 0x0000000000000000);
-	convert(0x0000000000030f50, 0x0000000000038010, 0x00000000000007ff);
-	convert(0x0000000000030f70, 0x0000000000000000, 0x0000000022001077);
-	convert(0x0000000000030fa0, 0x0000000000000000, 0x000000000003f4a8);
-	convert(0x0000000000030ff0, 0x0000000000310120, 0x0000000000000000);
-	convert(0x0000000000031000, 0xffffffffffffffff, 0xffffffff00000002);
-	convert(0x0000000000031010, 0x000000000000000e, 0x0000000000000000);
-	convert(0x0000000000031020, 0x0000000000038088, 0x0000000000000000);
-	convert(0x00000000000310c0, 0x0000000002010205, 0x00000000d0020000);
-	convert(0x00000000000310d0, 0xffffffffffffffff, 0x0000000f0000000f);
-	convert(0x00000000000310e0, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000310f0, 0x00000000000380b8, 0x00000000000007ff);
-	convert(0x0000000000031120, 0x0000000022001077, 0x00000000000310a9);
-	convert(0x0000000000031130, 0x00000000580211c1, 0x000000008009104c);
-	convert(0x0000000000031140, 0x0000000000000000, 0x000000000003f4c0);
-	convert(0x0000000000031190, 0x0000000000310120, 0x0000000000000000);
-	convert(0x00000000000311a0, 0xffffffffffffffff, 0xffffffff00000003);
-	convert(0x00000000000311b0, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000311c0, 0x0000000000038130, 0x0000000000000000);
-	convert(0x0000000000031260, 0x0000000000110106, 0x0000000000000000);
-	convert(0x0000000000031270, 0xffffffffffffffff, 0xffffffff00000004);
-	convert(0x0000000000031280, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000312a0, 0x00000000ff110013, 0x0000000000000000);
-	convert(0x00000000000312b0, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x00000000000312c0, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000312e0, 0x0000000000110012, 0x0000000000000000);
-	convert(0x00000000000312f0, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000031300, 0x000000000000000f, 0x0000000000000000);
-	convert(0x0000000000031310, 0x0000000000038160, 0x0000000000000000);
-	convert(0x0000000000031330, 0x00000000ff310122, 0x0000000000000000);
-	convert(0x0000000000031340, 0xffffffffffffffff, 0xffffffff00000005);
-	convert(0x0000000000031350, 0x000000000000000f, 0x0000000000000000);
-	convert(0x0000000000031360, 0x0000000000038190, 0x0000000000000000);
-	convert(0x0000000000031400, 0x0000000000310121, 0x0000000000000000);
-	convert(0x0000000000031400, 0x0000000000310121, 0x0000000000000000);
-	convert(0x0000000000031410, 0xffffffffffffffff, 0xffffffff00000006);
-	convert(0x0000000000031420, 0x000000000000000f, 0x0000000000000000);
-	convert(0x0000000000031430, 0x00000000000381c0, 0x0000000000000000);
-	convert(0x00000000000314d0, 0x00000000ff010201, 0x0000000000000000);
-	convert(0x00000000000314e0, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000031500, 0x00000000000381f0, 0x000030430000ffff);
-	convert(0x0000000000031510, 0x000000000000ffff, 0x0000000000000000);
-	convert(0x00000000000315a0, 0x00000020ff000201, 0x0000000000000000);
-	convert(0x00000000000315b0, 0xffffffffffffffff, 0xffffffff00000001);
-	convert(0x00000000000315d0, 0x0000000000038240, 0x00003f3f0000ffff);
-	convert(0x00000000000315e0, 0x000000000000ffff, 0x0000000000000000);
-	convert(0x0000000000031670, 0x00000000ff010201, 0x0000000000000000);
-	convert(0x0000000000031680, 0xffffffffffffffff, 0x0000000100000002);
-	convert(0x00000000000316a0, 0x0000000000038290, 0x000030430000ffff);
-	convert(0x00000000000316b0, 0x000000000000ffff, 0x0000000000000000);
-	convert(0x0000000000031740, 0x00000020ff000201, 0x0000000000000000);
-	convert(0x0000000000031750, 0xffffffffffffffff, 0x0000000500000003);
-	convert(0x0000000000031770, 0x00000000000382e0, 0x00003f3f0000ffff);
-	convert(0x0000000000031780, 0x000000000000ffff, 0x0000000000000000);
-
-	/*
-	 * GDA initialization - mankato
-	 */
-	convert(0x8000000000002400, 0x0000000258464552, 0x000000000ead0000);
-	convert(0x8000000000002480, 0xffffffff00010000, 0xffffffffffffffff);
-	convert(0x8000000000002490, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024a0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024b0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024c0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024d0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024e0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024f0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002500, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002510, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002520, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002530, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002540, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002550, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002560, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002570, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002580, 0x000000000000ffff, 0x0000000000000000);
-#endif
-	
+        /*
+         * klconfig entries initialization - mankato
+         */
+        convert(0xe000003000030000, 0x00000000beedbabe, 0x0000004800000000);
+        convert(0xe000003000030010, 0x0003007000000018, 0x800002000f820178);
+        convert(0xe000003000030020, 0x80000a000f024000, 0x800002000f800000);
+        convert(0xe000003000030030, 0x0300fafa00012580, 0x00000000040f0000);
+        convert(0xe000003000030040, 0x0000000000000000, 0x0003097000030070);
+        convert(0xe000003000030050, 0x00030970000303b0, 0x0003181000033f70);
+        convert(0xe000003000030060, 0x0003d51000037570, 0x0000000000038330);
+        convert(0xe000003000030070, 0x0203110100030140, 0x0001000000000101);
+        convert(0xe000003000030080, 0x0900000000000000, 0x000000004e465e67);
+        convert(0xe000003000030090, 0x0003097000000000, 0x00030b1000030a40);
+        convert(0xe0000030000300a0, 0x00030cb000030be0, 0x000315a0000314d0);
+        convert(0xe0000030000300b0, 0x0003174000031670, 0x0000000000000000);
+        convert(0xe000003000030100, 0x000000000000001a, 0x3350490000000000);
+        convert(0xe000003000030110, 0x0000000000000037, 0x0000000000000000);
+        convert(0xe000003000030140, 0x0002420100030210, 0x0001000000000101);
+        convert(0xe000003000030150, 0x0100000000000000, 0xffffffffffffffff);
+        convert(0xe000003000030160, 0x00030d8000000000, 0x0000000000030e50);
+        convert(0xe0000030000301c0, 0x0000000000000000, 0x0000000000030070);
+        convert(0xe0000030000301d0, 0x0000000000000025, 0x424f490000000000);
+        convert(0xe0000030000301e0, 0x000000004b434952, 0x0000000000000000);
+        convert(0xe000003000030210, 0x00027101000302e0, 0x00010000000e4101);
+        convert(0xe000003000030220, 0x0200000000000000, 0xffffffffffffffff);
+        convert(0xe000003000030230, 0x00030f2000000000, 0x0000000000030ff0);
+        convert(0xe000003000030290, 0x0000000000000000, 0x0000000000030140);
+        convert(0xe0000030000302a0, 0x0000000000000026, 0x7262490000000000);
+        convert(0xe0000030000302b0, 0x00000000006b6369, 0x0000000000000000);
+        convert(0xe0000030000302e0, 0x0002710100000000, 0x00010000000f3101);
+        convert(0xe0000030000302f0, 0x0500000000000000, 0xffffffffffffffff);
+        convert(0xe000003000030300, 0x000310c000000000, 0x0003126000031190);
+        convert(0xe000003000030310, 0x0003140000031330, 0x0000000000000000);
+        convert(0xe000003000030360, 0x0000000000000000, 0x0000000000030140);
+        convert(0xe000003000030370, 0x0000000000000029, 0x7262490000000000);
+        convert(0xe000003000030380, 0x00000000006b6369, 0x0000000000000000);
+        convert(0xe000003000030970, 0x0000000002010102, 0x0000000000000000);
+        convert(0xe000003000030980, 0x000000004e465e67, 0xffffffff00000000);
+        /* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */
+        convert(0xe0000030000309a0, 0x0000000000037570, 0xffffffff00000000);
+        convert(0xe0000030000309b0, 0x0000000000030070, 0x0000000000000000);
+        convert(0xe0000030000309c0, 0x000000000003f420, 0x0000000000000000);
+        convert(0xe000003000030a40, 0x0000000002010125, 0x0000000000000000);
+        convert(0xe000003000030a50, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000030a70, 0x0000000000037b78, 0x0000000000000000);
+        convert(0xe000003000030b10, 0x0000000002010125, 0x0000000000000000);
+        convert(0xe000003000030b20, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000030b40, 0x0000000000037d30, 0x0000000000000001);
+        convert(0xe000003000030be0, 0x00000000ff010203, 0x0000000000000000);
+        convert(0xe000003000030bf0, 0xffffffffffffffff, 0xffffffff000000ff);
+        convert(0xe000003000030c10, 0x0000000000037ee8, 0x0100010000000200);
+        convert(0xe000003000030cb0, 0x00000000ff310111, 0x0000000000000000);
+        convert(0xe000003000030cc0, 0xffffffffffffffff, 0x0000000000000000);
+        convert(0xe000003000030d80, 0x0000000002010104, 0x0000000000000000);
+        convert(0xe000003000030d90, 0xffffffffffffffff, 0x00000000000000ff);
+        convert(0xe000003000030db0, 0x0000000000037f18, 0x0000000000000000);
+        convert(0xe000003000030dc0, 0x0000000000000000, 0x0003007000060000);
+        convert(0xe000003000030de0, 0x0000000000000000, 0x0003021000050000);
+        convert(0xe000003000030df0, 0x000302e000050000, 0x0000000000000000);
+        convert(0xe000003000030e30, 0x0000000000000000, 0x000000000000000a);
+        convert(0xe000003000030e50, 0x00000000ff00011a, 0x0000000000000000);
+        convert(0xe000003000030e60, 0xffffffffffffffff, 0x0000000000000000);
+        convert(0xe000003000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e);
+        convert(0xe000003000030e90, 0x000000000000bc6e, 0x0000000000000000);
+        convert(0xe000003000030f20, 0x0000000002010205, 0x00000000d0020000);
+        convert(0xe000003000030f30, 0xffffffffffffffff, 0x0000000e0000000e);
+        convert(0xe000003000030f40, 0x000000000000000e, 0x0000000000000000);
+        convert(0xe000003000030f50, 0x0000000000038010, 0x00000000000007ff);
+        convert(0xe000003000030f70, 0x0000000000000000, 0x0000000022001077);
+        convert(0xe000003000030fa0, 0x0000000000000000, 0x000000000003f4a8);
+        convert(0xe000003000030ff0, 0x0000000000310120, 0x0000000000000000);
+        convert(0xe000003000031000, 0xffffffffffffffff, 0xffffffff00000002);
+        convert(0xe000003000031010, 0x000000000000000e, 0x0000000000000000);
+        convert(0xe000003000031020, 0x0000000000038088, 0x0000000000000000);
+        convert(0xe0000030000310c0, 0x0000000002010205, 0x00000000d0020000);
+        convert(0xe0000030000310d0, 0xffffffffffffffff, 0x0000000f0000000f);
+        convert(0xe0000030000310e0, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000310f0, 0x00000000000380b8, 0x00000000000007ff);
+        convert(0xe000003000031120, 0x0000000022001077, 0x00000000000310a9);
+        convert(0xe000003000031130, 0x00000000580211c1, 0x000000008009104c);
+        convert(0xe000003000031140, 0x0000000000000000, 0x000000000003f4c0);
+        convert(0xe000003000031190, 0x0000000000310120, 0x0000000000000000);
+        convert(0xe0000030000311a0, 0xffffffffffffffff, 0xffffffff00000003);
+        convert(0xe0000030000311b0, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000311c0, 0x0000000000038130, 0x0000000000000000);
+        convert(0xe000003000031260, 0x0000000000110106, 0x0000000000000000);
+        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
+        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
+        convert(0xe000003000031280, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000312a0, 0x00000000ff110013, 0x0000000000000000);
+        convert(0xe0000030000312b0, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe0000030000312c0, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000312e0, 0x0000000000110012, 0x0000000000000000);
+        convert(0xe0000030000312f0, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000031300, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe000003000031310, 0x0000000000038160, 0x0000000000000000);
+        convert(0xe000003000031330, 0x00000000ff310122, 0x0000000000000000);
+        convert(0xe000003000031340, 0xffffffffffffffff, 0xffffffff00000005);
+        convert(0xe000003000031350, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe000003000031360, 0x0000000000038190, 0x0000000000000000);
+        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
+        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
+        convert(0xe000003000031410, 0xffffffffffffffff, 0xffffffff00000006);
+        convert(0xe000003000031420, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe000003000031430, 0x00000000000381c0, 0x0000000000000000);
+        convert(0xe0000030000314d0, 0x00000000ff010201, 0x0000000000000000);
+        convert(0xe0000030000314e0, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000031500, 0x00000000000381f0, 0x000030430000ffff);
+        convert(0xe000003000031510, 0x000000000000ffff, 0x0000000000000000);
+        convert(0xe0000030000315a0, 0x00000020ff000201, 0x0000000000000000);
+        convert(0xe0000030000315b0, 0xffffffffffffffff, 0xffffffff00000001);
+        convert(0xe0000030000315d0, 0x0000000000038240, 0x00003f3f0000ffff);
+        convert(0xe0000030000315e0, 0x000000000000ffff, 0x0000000000000000);
+        convert(0xe000003000031670, 0x00000000ff010201, 0x0000000000000000);
+        convert(0xe000003000031680, 0xffffffffffffffff, 0x0000000100000002);
+        convert(0xe0000030000316a0, 0x0000000000038290, 0x000030430000ffff);
+        convert(0xe0000030000316b0, 0x000000000000ffff, 0x0000000000000000);
+        convert(0xe000003000031740, 0x00000020ff000201, 0x0000000000000000);
+        convert(0xe000003000031750, 0xffffffffffffffff, 0x0000000500000003);
+        convert(0xe000003000031770, 0x00000000000382e0, 0x00003f3f0000ffff);
+        convert(0xe000003000031780, 0x000000000000ffff, 0x0000000000000000);
 }
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/fakeprom/main.c linux-2.4.22-pre3/arch/ia64/sn/fakeprom/main.c
--- linux-2.4.22-pre2/arch/ia64/sn/fakeprom/main.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/fakeprom/main.c	2003-07-05 18:09:40.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -33,25 +33,9 @@
 	 * First lets figure out who we are. This is done from the
 	 * LID passed to us.
 	 */
-
-#ifdef CONFIG_IA64_SGI_SN1
-	nasid = (lid>>24);
-	syn = (lid>>17)&1;
-	cpu = (lid>>16)&1;
-
-	/*
-	 * Now pick a synergy master to initialize synergy registers.
-	 */
-	if (test_and_set_bit(syn, &nasidmaster[nasid]) == 0) {
-		synergy_init(nasid, syn);
-		test_and_set_bit(syn+2, &nasidmaster[nasid]);
-	} else
-		while (get_bit(syn+2, &nasidmaster[nasid]) == 0);
-#else
 	nasid = (lid>>16)&0xfff;
 	cpu = (lid>>28)&3;
 	syn = 0;
-#endif
 	
 	/*
 	 * Now pick a nasid master to initialize Bedrock registers.
diff -urN linux-2.4.22-pre2/arch/ia64/sn/fakeprom/runsim linux-2.4.22-pre3/arch/ia64/sn/fakeprom/runsim
--- linux-2.4.22-pre2/arch/ia64/sn/fakeprom/runsim	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/fakeprom/runsim	1969-12-31 16:00:00.000000000 -0800
@@ -1,387 +0,0 @@
-#!/bin/sh
-
-# Script for running PROMs and LINUX kernwls on medusa. 
-# Type "sim -H" for instructions.
-
-MEDUSA=${MEDUSA:-/home/rickc/official_medusa/medusa}
-
-# ------------------ err -----------------------
-err() {
-	echo "ERROR - $1"
-	exit 1
-}
-
-# ----------------  help ----------------------
-help() {
-cat <<END
-Script for running a PROM or LINUX kernel under medusa.
-This script creates a control file, creates links to the appropriate
-linux/prom files, and/or calls medusa to make simulation runs.
-
-Usage:  
-   Initial setup:
-   	sim [-c <config_file>] <-p> | <-k>  [<work_dir>]
-		-p	Create PROM control file & links
-		-k	Create LINUX control file & links
-		-c<cf>	Control file name				[Default: cf]
-		<work_dir> Path to directory that contains the linux or PROM files.
-		    The directory can be any of the following:
-		       (linux simulations)
-		       		worktree
-				worktree/linux
-				any directory with vmlinux, vmlinux.sym & fprom files
-			(prom simulations)
-				worktree
-				worktree/stand/arcs/IP37prom/dev
-				any directory with fw.bin & fw.sim files
-
-    Simulations:
-	sim  [-X <n>] [-o <output>] [-M] [<config_file>]
-		-c<cf>	Control file name				[Default: cf]
-		-M	Pipe output thru fmtmedusa
-		-o	Output filename (copy of all commands/output)	[Default: simout]
-		-X	Specifies number of instructions to execute	[Default: 0]
-			(Used only in auto test mode - not described here)
-
-Examples:
-	sim -p <promtree>	# create control file (cf) & links for prom simulations
-	sim -k <linuxtree>	# create control file (cf) & links for linux simulations
-	sim -p -c cfprom	# create a prom control file (cfprom) only. No links are made.
-
-	sim			# run medusa using previously created links &
-				#   control file (cf).
-END
-exit 1
-}
-
-# ----------------------- create control file header --------------------
-create_cf_header() {
-cat <<END >>$CF
-#
-# Template for a control file for running linux kernels under medusa. 
-# You probably want to make mods here but this is a good starting point.
-#
-
-# Preferences
-setenv cpu_stepping A
-setenv exceptionPrint off
-setenv interrupt_messages off
-setenv lastPCsize 100000
-setenv low_power_mode on
-setenv partialIntelChipSet on
-setenv printIntelMessages off
-setenv prom_write_action halt
-setenv prom_write_messages on
-setenv step_quantum 100
-setenv swizzling on
-setenv tsconsole on
-setenv uart_echo on
-symbols on
-
-# IDE disk params
-setenv diskCylinders 611
-setenv bootDrive C
-setenv diskHeads 16
-setenv diskPath idedisk
-setenv diskPresent 1
-setenv diskSpt 63
-
-# Hardware config
-setenv coherency_type nasid
-setenv cpu_cache_type default
-setenv synergy_cache_type syn_cac_64m_8w
-setenv l4_uc_snoop off
-
-# Numalink config
-setenv route_enable on
-setenv network_type router		# Select [xbar|router]
-setenv network_warning 0xff
-
-END
-}
-
-
-# ------------------ create control file entries for linux simulations -------------
-create_cf_linux() {
-cat <<END >>$CF
-# Kernel specific options
-setenv calias_size 0
-setenv mca_on_memory_failure off
-setenv LOADPC 0x00100000		# FPROM load address/entry point (8 digits!)
-setenv symbol_table vmlinux.sym
-load fprom
-load vmlinux
-
-# Useful breakpoints to always have set. Add more if desired.
-break 0xe000000000505e00	all	# dispatch_to_fault_handler
-break panic			all	# stop on panic
-break die_if_kernel		all	# may as well stop
-
-END
-}
-
-# ------------------ create control file entries for prom simulations ---------------
-create_cf_prom() {
-	SYM2=""
-	ADDR="0x80000000ff800000"
-	[ "$EMBEDDED_LINUX" != "0" ] || SYM2="setenv symbol_table2 vmlinux.sym"
-	[ "$SIZE" = "8MB" ] || ADDR="0x80000000ffc00000"
-	cat <<END >>$CF
-# PROM specific options
-setenv mca_on_memory_failure on
-setenv LOADPC 0x80000000ffffffb0
-setenv promFile fw.bin
-setenv promAddr $ADDR
-setenv symbol_table fw.sym
-$SYM2
-
-# Useful breakpoints to always have set. Add more if desired.
-break ivt_gexx 		all
-break ivt_brk		all
-break PROM_Panic_Spin	all
-break PROM_Panic	all
-break PROM_C_Panic	all
-break fled_die		all
-break ResetNow		all
-break zzzbkpt		all
-
-END
-}
-
-
-# ------------------ create control file entries for memory configuration -------------
-create_cf_memory() {
-cat <<END >>$CF
-# CPU/Memory map format:
-#	setenv nodeN_memory_config 0xBSBSBSBS
-#		B=banksize (0=unused, 1=64M, 2=128M, .., 5-1G, c=8M, d=16M, e=32M)
-#		S=bank enable (0=both disable, 3=both enable, 2=bank1 enable, 1=bank0 enable)
-#		  rightmost digits are for bank 0, the lowest address.
-#	setenv nodeN_nasid <nasid>
-#		specifies the NASID for the node. This is used ONLY if booting the kernel.
-#		On PROM configurations, set to 0 - PROM will change it later.
-#	setenv nodeN_cpu_config <cpu_mask>
-#		Set bit number N to 1 to enable cpu N. Ex., a value of 5 enables cpu 0 & 2.
-#
-# Repeat the above 3 commands for each node.
-#
-# For kernel, default to 32MB. Although this is not a valid hardware configuration,
-# it runs faster on medusa. For PROM, 64MB is smallest allowed value.
-
-setenv node0_cpu_config		0x1	# Enable only cpu 0 on the node
-END
-
-if [ $LINUX -eq 1 ] ; then
-cat <<END >>$CF
-setenv node0_nasid		0	# cnode 0 has NASID 0
-setenv node0_memory_config 	0xe1	# 32MB
-END
-else
-cat <<END >>$CF
-setenv node0_memory_config 	0x31	# 256MB
-END
-fi
-}
-
-# -------------------- set links to linux files -------------------------
-set_linux_links() {
-	if [ -d $D/linux/arch ] ; then
-		D=$D/linux
-	elif [ -d $D/arch -o -e vmlinux.sym -o -e $D/vmlinux ] ; then
-		D=$D
-	else
-		err "cant determine directory for linux binaries"
-	fi
-	rm -rf vmlinux vmlinux.sym fprom
-	ln -s $D/vmlinux vmlinux
-	if [ -f $D/vmlinux.sym ] ; then
-		ln -s $D/vmlinux.sym vmlinux.sym
-	elif  [ -f $D/System.map ] ; then
-		ln -s $D/System.map vmlinux.sym
-	fi
-	if [ -d $D/arch ] ; then
-		ln -s $D/arch/ia64/sn/fprom/fprom fprom
-	else
-		ln -s $D/fprom fprom
-	fi
-	echo "  .. Created links to linux files"	
-}
-
-# -------------------- set links to prom files -------------------------
-set_prom_links() {
-	if [ -d $D/stand ] ; then
-		D=$D/stand/arcs/IP37prom/dev
-	elif [ -d $D/sal ] ; then
-		D=$D
-	else
-		err "cant determine directory for PROM binaries"
-	fi
-	SETUP="/tmp/tmp.$$"
-	rm -r -f $SETUP
-	sed 's/export/setenv/' < $D/../../../../.setup | sed 's/=/ /' >$SETUP
-	egrep -q '^ *setenv *PROMSIZE *8MB|^ *export' $SETUP
-	if [ $? -eq 0 ] ; then
-		SIZE="8MB"
-	else
-		SIZE="4MB"
-	fi
-	grep -q '^ *setenv *LAUNCH_VMLINUX' $SETUP
-	EMBEDDED_LINUX=$?
-	PRODUCT=`grep '^ *setenv *PRODUCT' $SETUP | cut -d" " -f3`
-	rm -f fw.bin fw.map fw.sym vmlinux vmlinux.sym fprom $SETUP
-	SDIR="${PRODUCT}${SIZE}.O"
-	BIN="${PRODUCT}ip37prom${SIZE}"
-	ln -s $D/$SDIR/$BIN.bin fw.bin
-	ln -s $D/$SDIR/$BIN.map fw.map
-	ln -s $D/$SDIR/$BIN.sym fw.sym
-	echo "  .. Created links to $SIZE prom files"
-	if [ $EMBEDDED_LINUX -eq 0 ] ; then
-		ln -s $D/linux/vmlinux vmlinux
-		ln -s $D/linux/vmlinux.sym vmlinux.sym
-		if [ -d linux/arch ] ; then
-			ln -s $D/linux/arch/ia64/sn/fprom/fprom fprom
-		else
-			ln -s $D/linux/fprom fprom
-		fi
-		echo "  .. Created links to embedded linux files in prom tree"
-	fi
-}
-
-# --------------- start of shell script --------------------------------
-OUT="simout"
-FMTMED=0
-STEPCNT=0
-PROM=0
-LINUX=0
-NCF="cf"
-while getopts "HMX:c:o:pk" c ; do
-        case ${c} in
-                H) help;;
-		M) FMTMED=1;;
-		X) STEPCNT=${OPTARG};;
-		c) NCF=${OPTARG};;
-		k) PROM=0;LINUX=1;;
-		p) PROM=1;LINUX=0;;
-		o) OUT=${OPTARG};;
-                \?) exit 1;;
-        esac
-done
-shift `expr ${OPTIND} - 1`
-
-# Check if command is for creating control file and/or links to images.
-if [ $PROM -eq 1 -o $LINUX -eq 1 ] ; then
-	CF=$NCF
-	[ ! -f $CF ] || err "wont overwrite an existing control file ($CF)"
-	if [ $# -gt 0 ] ; then
-		D=$1
-		[ -d $D ] || err "cannot find directory $D"
-		[ $PROM -eq 0 ]  || set_prom_links
-		[ $LINUX -eq 0 ] || set_linux_links
-	fi
-	create_cf_header
-	[ $PROM -eq 0 ]  || create_cf_prom
-	[ $LINUX -eq 0 ] || create_cf_linux
-	[ ! -f ../idedisk ] || ln -s ../idedisk .
-	create_cf_memory
-	echo "  .. Basic control file created (in $CF). You might want to edit"
-	echo "     this file (at least, look at it)."
-	exit 0
-fi
-
-# Verify that the control file exists
-CF=${1:-$NCF}
-[ -f $CF ] || err "No control file exists. For help, type: $0 -H"
-
-# Build the .cf files from the user control file. The .cf file is
-# identical except that the actual start & load addresses are inserted
-# into the file. In addition, the FPROM commands for configuring memory
-# and LIDs are generated. 
-
-rm -f .cf .cf1 .cf2
-awk '
-function strtonum(n) {
-	 if (substr(n,1,2) != "0x")
-	 	return int(n)
-	 n = substr(n,3)
-	 r=0
-	 while (length(n) > 0) {
-	 	r = r*16+(index("0123456789abcdef", substr(n,1,1))-1)
-		n = substr(n,2)
-	 }
-	 return r
-	}
-/^#/   	{next}
-/^$/	{next}
-/^setenv *LOADPC/               {loadpc = $3; next}
-/^setenv *node.._cpu_config/	{n=int(substr($2,5,2)); cpuconf[n] = strtonum($3); print; next}
-/^setenv *node.._memory_config/	{n=int(substr($2,5,2)); memconf[n] = strtonum($3); print; next}
-/^setenv *node.._nasid/		{n=int(substr($2,5,2)); nasid[n] = strtonum($3); print; next}
-/^setenv *node._cpu_config/	{n=int(substr($2,5,1)); cpuconf[n] = strtonum($3); print; next}
-/^setenv *node._memory_config/	{n=int(substr($2,5,1)); memconf[n] = strtonum($3); print; next}
-/^setenv *node._nasid/		{n=int(substr($2,5,1)); nasid[n] = strtonum($3); print; next}
-		{print}
-END	{
-	 # Generate the memmap info that starts at the beginning of
-	 # the node the kernel was loaded on.
-	 loadnasid = nasid[0]
-	 cnode = 0
-	 for (i=0; i<128; i++) {
-		if (memconf[i] != "") {
-			printf "sm 0x%x%08x 0x%x%04x%04x\n", 
-				2*loadnasid, 8*cnodes+8, memconf[i], cpuconf[i], nasid[i]
-			cnodes++
-			cpus += substr("0112122312232334", cpuconf[i]+1,1)
-		}
-	 }
-	 printf "sm 0x%x00000000 0x%x%08x\n", 2*loadnasid, cnodes, cpus
-	 printf "setenv number_of_nodes %d\n", cnodes
-
-	 # Now set the starting PC for each cpu.
-	 cnode = 0
-	 lowcpu=-1
-	 for (i=0; i<128; i++) {
-		if (memconf[i] != "") {
-			printf "setnode %d\n", cnode
-			conf = cpuconf[i]
-			for (j=0; j<4; j++) {
-				if (conf != int(conf/2)*2) {
-	 				printf "setcpu %d\n", j
-					if (length(loadpc) == 18)
-						printf "sr pc %s\n", loadpc
-					else
-						printf "sr pc 0x%x%s\n", 2*loadnasid, substr(loadpc,3)
-					if (lowcpu == -1)
-						lowcpu = j
-				}
-				conf = int(conf/2)
-			}
-			cnode++
-		}
-	 }
-	 printf "setnode 0\n"
-	 printf "setcpu %d\n", lowcpu
-	}
-' <$CF >.cf
-
-# Now build the .cf1 & .cf2 control files.
-CF2_LINES="^sm |^break |^run |^si |^quit |^symbols "
-egrep  "$CF2_LINES" .cf >.cf2
-egrep -v "$CF2_LINES" .cf >.cf1
-if [ $STEPCNT -ne 0 ] ; then
-	echo "s $STEPCNT" >>.cf2
-	echo "lastpc 1000" >>.cf2
-	echo "q" >>.cf2
-fi
-if [ -f vmlinux.sym ] ; then
-	awk '/ _start$/ {print "sr g 9 0x" $3}' < vmlinux.sym >> .cf2
-fi
-echo "script-on $OUT" >>.cf2
-
-# Now start medusa....
-if [ $FMTMED -ne 0 ] ; then
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 |  fmtmedusa
-elif [ $STEPCNT -eq 0 ] ; then
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 
-else
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 2>&1 
-fi
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/Makefile linux-2.4.22-pre3/arch/ia64/sn/io/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/io/Makefile	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/Makefile	2003-07-05 18:09:40.000000000 -0700
@@ -3,31 +3,34 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+# Copyright (C) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
 #
 # Makefile for the sn kernel routines.
 
 EXTRA_CFLAGS    := -DLITTLE_ENDIAN
 
-ifdef CONFIG_IA64_SGI_SN2
 EXTRA_CFLAGS    += -DSHUB_SWAP_WAR
-endif
 
 O_TARGET := sgiio.o
  
-export-objs := hcl.o pci_dma.o
+obj-y :=	sgi_if.o xswitch.o sgi_io_sim.o \
+		cdl.o io.o
+
+obj-y		+= sn2/snio.o machvec/snio.o \
+	           drivers/snio.o platform_init/snio.o
 
-obj-y :=	stubs.o sgi_if.o xswitch.o klgraph_hack.o \
-		hcl.o labelcl.o invent.o sgi_io_sim.o \
-		klgraph_hack.o hcl_util.o cdl.o hubdev.o hubspc.o \
-		alenlist.o pci.o pci_dma.o ate_utils.o \
-		ifconfig_net.o io.o ifconfig_bus.o
-
-obj-$(CONFIG_IA64_SGI_SN1)	+= sn1/snio.o
-obj-$(CONFIG_IA64_SGI_SN2)	+= sn2/snio.o
-obj-$(CONFIG_PCIBA)		+= pciba.o
+ifdef CONFIG_HWGFS_FS
+obj-$(CONFIG_HWGFS_FS)		+= hwgfs/snio.o
+else
+obj-$(CONFIG_DEVFS_FS)		+= hwgdfs/snio.o
+endif
 
-subdir-$(CONFIG_IA64_SGI_SN1)	+= sn1
-subdir-$(CONFIG_IA64_SGI_SN2)	+= sn2
+subdir-y			+= sn2 machvec drivers platform_init
+
+ifdef CONFIG_HWGFS_FS
+subdir-$(CONFIG_HWGFS_FS)	+= hwgfs
+else
+subdir-$(CONFIG_DEVFS_FS)	+= hwgdfs
+endif
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/alenlist.c linux-2.4.22-pre3/arch/ia64/sn/io/alenlist.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/alenlist.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/alenlist.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,899 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/* Implementation of Address/Length Lists. */
-
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/mmzone.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/alenlist.h>
-
-/*
- * Logically, an Address/Length List is a list of Pairs, where each pair
- * holds an Address and a Length, all in some Address Space.  In this
- * context, "Address Space" is a particular Crosstalk Widget address
- * space, a PCI device address space, a VME bus address space, a
- * physical memory address space, etc.
- *
- * The main use for these Lists is to provide a single mechanism that
- * describes where in an address space a DMA occurs.  This allows the
- * various I/O Bus support layers to provide a single interface for
- * DMA mapping and DMA translation without regard to how the DMA target
- * was specified by upper layers.  The upper layers commonly specify a 
- * DMA target via a buf structure page list, a kernel virtual address,
- * a user virtual address, a vector of addresses (a la uio and iov), 
- * or possibly a pfn list.
- *
- * Address/Length Lists also enable drivers to take advantage of their
- * inate scatter/gather capabilities in systems where some address
- * translation may be required between bus adapters.  The driver forms
- * a List that represents physical memory targets.  This list is passed
- * to the various adapters, which apply various translations.  The final
- * list that's returned to the driver is in terms of its local address
- * address space -- addresses which can be passed off to a scatter/gather
- * capable DMA controller.
- *
- * The current implementation is intended to be useful both in kernels
- * that support interrupt threads (INTR_KTHREAD) and in systems that do
- * not support interrupt threads.  Of course, in the latter case, some
- * interfaces can be called only within a suspendable context.
- *
- * Basic operations on Address/Length Lists include:
- *	alenlist_create		Create a list
- *	alenlist_clear		Clear a list
- *	alenlist_destroy	Destroy a list
- *	alenlist_append		Append a Pair to the end of a list
- *	alenlist_replace	Replace a Pair in the middle of a list
- *	alenlist_get		Get an Address/Length Pair from a list
- *	alenlist_size		Return the number of Pairs in a list
- *	alenlist_concat		Append one list to the end of another
- *	alenlist_clone		Create a new copy of a list
- *
- * Operations that convert from upper-level specifications to Address/
- * Length Lists currently include:
- *	kvaddr_to_alenlist	Convert from a kernel virtual address
- *	uvaddr_to_alenlist	Convert from a user virtual address
- *	buf_to_alenlist		Convert from a buf structure
- *	alenlist_done		Tell system that we're done with an alenlist
- *				obtained from a conversion.
- * Additional convenience operations:
- *	alenpair_init		Create a list and initialize it with a Pair
- *	alenpair_get		Peek at the first pair on a List
- *
- * A supporting type for Address/Length Lists is an alenlist_cursor_t.  A
- * cursor marks a position in a List, and determines which Pair is fetched
- * by alenlist_get.
- *	alenlist_cursor_create	Allocate and initialize a cursor
- *	alenlist_cursor_destroy	Free space consumed by a cursor
- *	alenlist_cursor_init	(Re-)Initialize a cursor to point 
- *				to the start of a list
- *	alenlist_cursor_clone	Clone a cursor (at the current offset)
- *	alenlist_cursor_offset	Return the number of bytes into
- *				a list that this cursor marks
- * Multiple cursors can point at various points into a List.  Also, each
- * list maintains one "internal cursor" which may be updated by alenlist_clear
- * and alenlist_get.  If calling code simply wishes to scan sequentially
- * through a list starting at the beginning, and if it is the only user of
- * a list, it can rely on this internal cursor rather than managing a 
- * separate explicit cursor.
- *
- * The current implementation allows callers to allocate both cursors and
- * the lists as local stack (structure) variables.  This allows for some
- * extra efficiency at the expense of forward binary compatibility.  It 
- * is recommended that customer drivers refrain from local allocation.
- * In fact, we likely will choose to move the structures out of the public 
- * header file into a private place in order to discourage this usage.
- *
- * Currently, no locking is provided by the alenlist implementation.
- *
- * Implementation notes:
- * For efficiency, Pairs are grouped into "chunks" of, say, 32 Pairs
- * and a List consists of some number of these chunks.  Chunks are completely
- * invisible to calling code.  Chunks should be large enough to hold most
- * standard-sized DMA's, but not so large that they consume excessive space.
- *
- * It is generally expected that Lists will be constructed at one time and
- * scanned at a later time.  It is NOT expected that drivers will scan
- * a List while the List is simultaneously extended, although this is
- * theoretically possible with sufficient upper-level locking.
- *
- * In order to support demands of Real-Time drivers and in order to support
- * swapping under low-memory conditions, we support the concept of a
- * "pre-allocated fixed-sized List".  After creating a List with 
- * alenlist_create, a driver may explicitly grow the list (via "alenlist_grow")
- * to a specific number of Address/Length pairs.  It is guaranteed that future 
- * operations involving this list will never automatically grow the list 
- * (i.e. if growth is ever required, the operation will fail).  Additionally, 
- * operations that use alenlist's (e.g. DMA operations) accept a flag which 
- * causes processing to take place "in-situ"; that is, the input alenlist 
- * entries are replaced with output alenlist entries.  The combination of 
- * pre-allocated Lists and in-situ processing allows us to avoid the 
- * potential deadlock scenario where we sleep (waiting for memory) in the 
- * swap out path.
- *
- * For debugging, we track the number of allocated Lists in alenlist_count
- * the number of allocated chunks in alenlist_chunk_count, and the number
- * of allocate cursors in alenlist_cursor_count.  We also provide a debug 
- * routine, alenlist_show, which dumps the contents of an Address/Length List.
- *
- * Currently, Lists are formed by drivers on-demand.  Eventually, we may
- * associate an alenlist with a buf structure and keep it up to date as
- * we go along.  In that case, buf_to_alenlist simply returns a pointer
- * to the existing List, and increments the Lists's reference count.
- * alenlist_done would decrement the reference count and destroys the List
- * if it was the last reference.
- *
- * Eventually alenlist's may allow better support for user-level scatter/
- * gather operations (e.g. via readv/writev):  With proper support, we
- * could potentially handle a vector of reads with a single scatter/gather
- * DMA operation.  This could be especially useful on NUMA systems where
- * there's more of a reason for users to use vector I/O operations.
- *
- * Eventually, alenlist's may replace kaio lists, vhand page lists,
- * buffer cache pfdat lists, DMA page lists, etc.
- */
-
-/* Opaque data types */
-
-/* An Address/Length pair.  */
-typedef struct alen_s {
-	alenaddr_t	al_addr;
-	size_t		al_length;
-} alen_t;
-
-/* 
- * Number of elements in one chunk of an Address/Length List.
- *
- * This size should be sufficient to hold at least an "average" size
- * DMA request.  Must be at least 1, and should be a power of 2,
- * for efficiency.
- */
-#define ALEN_CHUNK_SZ ((512*1024)/NBPP)
-
-/*
- * A fixed-size set of Address/Length Pairs.  Chunks of Pairs are strung together 
- * to form a complete Address/Length List.  Chunking is entirely hidden within the 
- * alenlist implementation, and it simply makes allocation and growth of lists more 
- * efficient.
- */
-typedef struct alenlist_chunk_s {
-	alen_t			alc_pair[ALEN_CHUNK_SZ];/* list of addr/len pairs */
-	struct alenlist_chunk_s *alc_next;		/* point to next chunk of pairs */
-} *alenlist_chunk_t;
-
-/* 
- * An Address/Length List.  An Address/Length List is allocated with alenlist_create.  
- * Alternatively, a list can be allocated on the stack (local variable of type 
- * alenlist_t) and initialized with alenpair_init or with a combination of 
- * alenlist_clear and alenlist_append, etc.  Code which statically allocates these
- * structures loses forward binary compatibility!
- *
- * A statically allocated List is sufficiently large to hold ALEN_CHUNK_SZ pairs.
- */
-struct alenlist_s {
-	unsigned short		al_flags;
-	unsigned short		al_logical_size;	/* logical size of list, in pairs */
-	unsigned short		al_actual_size;		/* actual size of list, in pairs */
-	struct alenlist_chunk_s	*al_last_chunk;		/* pointer to last logical chunk */
-	struct alenlist_cursor_s al_cursor;		/* internal cursor */
-	struct alenlist_chunk_s	al_chunk;		/* initial set of pairs */
-	alenaddr_t		al_compaction_address;	/* used to compact pairs */
-};
-
-/* al_flags field */
-#define AL_FIXED_SIZE	0x1	/* List is pre-allocated, and of fixed size */
-
-
-zone_t *alenlist_zone = NULL;
-zone_t *alenlist_chunk_zone = NULL;
-zone_t *alenlist_cursor_zone = NULL;
-
-#if DEBUG
-int alenlist_count=0;		/* Currently allocated Lists */
-int alenlist_chunk_count = 0;	/* Currently allocated chunks */
-int alenlist_cursor_count = 0;	/* Currently allocate cursors */
-#define INCR_COUNT(ptr) atomic_inc((ptr));
-#define DECR_COUNT(ptr) atomic_dec((ptr));
-#else
-#define INCR_COUNT(ptr)
-#define DECR_COUNT(ptr)
-#endif /* DEBUG */
-
-#if DEBUG
-static void alenlist_show(alenlist_t);
-#endif /* DEBUG */
-
-/*
- * Initialize Address/Length List management.  One time initialization.
- */
-void
-alenlist_init(void)
-{
-	alenlist_zone = snia_kmem_zone_init(sizeof(struct alenlist_s), "alenlist");
-	alenlist_chunk_zone = snia_kmem_zone_init(sizeof(struct alenlist_chunk_s), "alchunk");
-	alenlist_cursor_zone = snia_kmem_zone_init(sizeof(struct alenlist_cursor_s), "alcursor");
-#if DEBUG
-	idbg_addfunc("alenshow", alenlist_show);
-#endif /* DEBUG */
-}
-
-
-/*
- * Initialize an Address/Length List cursor.
- */
-static void
-do_cursor_init(alenlist_t alenlist, alenlist_cursor_t cursorp)
-{
-	cursorp->al_alenlist = alenlist;
-	cursorp->al_offset = 0;
-	cursorp->al_chunk = &alenlist->al_chunk;
-	cursorp->al_index = 0;
-	cursorp->al_bcount = 0;
-}
-
-
-/*
- * Create an Address/Length List, and clear it.
- * Set the cursor to the beginning.
- */
-alenlist_t 
-alenlist_create(unsigned flags)
-{
-	alenlist_t alenlist;
-
-	alenlist = snia_kmem_zone_alloc(alenlist_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
-	if (alenlist) {
-		INCR_COUNT(&alenlist_count);
-
-		alenlist->al_flags = 0;
-		alenlist->al_logical_size = 0;
-		alenlist->al_actual_size = ALEN_CHUNK_SZ;
-		alenlist->al_last_chunk = &alenlist->al_chunk;
-		alenlist->al_chunk.alc_next = NULL;
-		do_cursor_init(alenlist, &alenlist->al_cursor);
-	}
-
-	return(alenlist);
-}
-
-
-/*
- * Grow an Address/Length List so that all resources needed to contain
- * the specified number of Pairs are pre-allocated.  An Address/Length
- * List that has been explicitly "grown" will never *automatically*
- * grow, shrink, or be destroyed.
- *
- * Pre-allocation is useful for Real-Time drivers and for drivers that
- * may be used along the swap-out path and therefore cannot afford to 
- * sleep until memory is freed.
- * 
- * The cursor is set to the beginning of the list.
- */
-int
-alenlist_grow(alenlist_t alenlist, size_t npairs)
-{
-	/* 
-	 * This interface should be used relatively rarely, so
-	 * the implementation is kept simple: We clear the List,
-	 * then append npairs bogus entries.  Finally, we mark
-	 * the list as FIXED_SIZE and re-initialize the internal
-	 * cursor.
-	 */
-
-	/* 
-	 * Temporarily mark as non-fixed size, since we're about
-	 * to shrink and expand it.
-	 */
-	alenlist->al_flags &= ~AL_FIXED_SIZE;
-
-	/* Free whatever was in the alenlist. */
-	alenlist_clear(alenlist);
-
-	/* Allocate everything that we need via automatic expansion. */
-	while (npairs--)
-		if (alenlist_append(alenlist, 0, 0, AL_NOCOMPACT) == ALENLIST_FAILURE)
-			return(ALENLIST_FAILURE);
-
-	/* Now, mark as FIXED_SIZE */
-	alenlist->al_flags |= AL_FIXED_SIZE;
-
-	/* Clear out bogus entries */
-	alenlist_clear(alenlist);
-
-	/* Initialize internal cursor to the beginning */
-	do_cursor_init(alenlist, &alenlist->al_cursor);
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Clear an Address/Length List so that it holds no pairs.
- */
-void
-alenlist_clear(alenlist_t alenlist)
-{
-	alenlist_chunk_t chunk, freechunk;
-
-	/*
-	 * If this List is not FIXED_SIZE, free all the
-	 * extra chunks.
-	 */
-	if (!(alenlist->al_flags & AL_FIXED_SIZE)) {
-		/* First, free any extension alenlist chunks */
-		chunk = alenlist->al_chunk.alc_next;
-		while (chunk) {
-			freechunk = chunk;
-			chunk = chunk->alc_next;
-			snia_kmem_zone_free(alenlist_chunk_zone, freechunk);
-			DECR_COUNT(&alenlist_chunk_count);
-		}
-		alenlist->al_actual_size = ALEN_CHUNK_SZ;
-		alenlist->al_chunk.alc_next = NULL;
-	}
-
-	alenlist->al_logical_size = 0;
-	alenlist->al_last_chunk = &alenlist->al_chunk;
-	do_cursor_init(alenlist, &alenlist->al_cursor);
-}
-
-
-/*
- * Create and initialize an Address/Length Pair.
- * This is intended for degenerate lists, consisting of a single 
- * address/length pair.
- */
-alenlist_t
-alenpair_init(	alenaddr_t address, 
-		size_t length)
-{
-	alenlist_t alenlist;
-
-	alenlist = alenlist_create(0);
-
-	alenlist->al_logical_size = 1;
-	ASSERT(alenlist->al_last_chunk == &alenlist->al_chunk);
-	alenlist->al_chunk.alc_pair[0].al_length = length;
-	alenlist->al_chunk.alc_pair[0].al_addr = address;
-
-	return(alenlist);
-}
-
-/*
- * Return address/length from a degenerate (1-pair) List, or
- * first pair from a larger list.  Does NOT update the internal cursor,
- * so this is an easy way to peek at a start address.
- */
-int
-alenpair_get(	alenlist_t alenlist,
-		alenaddr_t *address,
-		size_t *length)
-{
-	if (alenlist->al_logical_size == 0)
-		return(ALENLIST_FAILURE);
-
-	*length = alenlist->al_chunk.alc_pair[0].al_length;
-	*address = alenlist->al_chunk.alc_pair[0].al_addr;
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Destroy an Address/Length List.
- */
-void 
-alenlist_destroy(alenlist_t alenlist)
-{
-	if (alenlist == NULL)
-		return;
-
-	/* 
-	 * Turn off FIXED_SIZE so this List can be 
-	 * automatically shrunk.
-	 */
-	alenlist->al_flags &= ~AL_FIXED_SIZE;
-
-	/* Free extension chunks first */
-	if (alenlist->al_chunk.alc_next)
-		alenlist_clear(alenlist);
-
-	/* Now, free the alenlist itself */
-	snia_kmem_zone_free(alenlist_zone, alenlist);
-	DECR_COUNT(&alenlist_count);
-}
-
-/*
- * Release an Address/Length List.
- * This is in preparation for a day when alenlist's may be longer-lived, and
- * perhaps associated with a buf structure.  We'd add a reference count, and
- * this routine would decrement the count.  For now, we create alenlist's on
- * on demand and free them when done.  If the driver is not explicitly managing
- * a List for its own use, it should call alenlist_done rather than alenlist_destroy.
- */
-void
-alenlist_done(alenlist_t alenlist)
-{
-	alenlist_destroy(alenlist);
-}
-
-
-/*
- * Append another address/length to the end of an Address/Length List,
- * growing the list if permitted and necessary.
- *
- * Returns: SUCCESS/FAILURE
- */
-int 
-alenlist_append(	alenlist_t alenlist, 		/* append to this list */
-			alenaddr_t address, 		/* address to append */
-			size_t length,			/* length to append */
-			unsigned flags)
-{
-	alen_t *alenp;
-	int index, last_index;
-
-	index = alenlist->al_logical_size % ALEN_CHUNK_SZ;
-
-	if ((alenlist->al_logical_size > 0)) {
-		/*
-		 * See if we can compact this new pair in with the previous entry.
-		 * al_compaction_address holds that value that we'd need to see
-		 * in order to compact.
-		 */
-		if (!(flags & AL_NOCOMPACT) &&
-		    (alenlist->al_compaction_address == address)) {
-			last_index = (alenlist->al_logical_size-1) % ALEN_CHUNK_SZ;
-			alenp = &(alenlist->al_last_chunk->alc_pair[last_index]);
-			alenp->al_length += length;
-			alenlist->al_compaction_address += length;
-			return(ALENLIST_SUCCESS);
-		}
-
-		/*
-		 * If we're out of room in this chunk, move to a new chunk.
-	 	 */
-		if (index == 0) {
-			if (alenlist->al_flags & AL_FIXED_SIZE) {
-				alenlist->al_last_chunk = alenlist->al_last_chunk->alc_next;
-
-				/* If we're out of space in a FIXED_SIZE List, quit. */
-				if (alenlist->al_last_chunk == NULL) {
-					ASSERT(alenlist->al_logical_size == alenlist->al_actual_size);
-					return(ALENLIST_FAILURE);
-				}
-			} else {
-				alenlist_chunk_t new_chunk;
-
-				new_chunk = snia_kmem_zone_alloc(alenlist_chunk_zone, 
-							flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
-
-				if (new_chunk == NULL)
-					return(ALENLIST_FAILURE);
-
-				alenlist->al_last_chunk->alc_next = new_chunk;
-				new_chunk->alc_next = NULL;
-				alenlist->al_last_chunk = new_chunk;
-				alenlist->al_actual_size += ALEN_CHUNK_SZ;
-				INCR_COUNT(&alenlist_chunk_count);
-			}
-		}
-	}
-
-	alenp = &(alenlist->al_last_chunk->alc_pair[index]);
-	alenp->al_addr = address;
-	alenp->al_length = length;
-	
-	alenlist->al_logical_size++;
-	alenlist->al_compaction_address = address + length;
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Replace an item in an Address/Length List.  Cursor is updated so
- * that alenlist_get will get the next item in the list.  This interface 
- * is not very useful for drivers; but it is useful to bus providers 
- * that need to translate between address spaced in situ.  The old Address
- * and Length are returned.
- */
-/* ARGSUSED */
-int
-alenlist_replace(	alenlist_t alenlist, 		/* in: replace in this list */
-			alenlist_cursor_t cursorp, 	/* inout: which item to replace */
-			alenaddr_t *addrp, 		/* inout: address */
-			size_t *lengthp,		/* inout: length */
-			unsigned flags)
-{
-	alen_t *alenp;
-	alenlist_chunk_t chunk;
-	unsigned int index;
-	size_t length;
-	alenaddr_t addr;
-
-	if ((addrp == NULL) || (lengthp == NULL))
-		return(ALENLIST_FAILURE);
-
-	if (alenlist->al_logical_size == 0)
-		return(ALENLIST_FAILURE);
-
-	addr = *addrp;
-	length = *lengthp;
-
-	/* 
-	 * If no cursor explicitly specified, use the Address/Length List's 
-	 * internal cursor.
-	 */
-	if (cursorp == NULL)
-		cursorp = &alenlist->al_cursor;
-
-	chunk = cursorp->al_chunk;
-	index = cursorp->al_index;
-
-	ASSERT(cursorp->al_alenlist == alenlist);
-	if (cursorp->al_alenlist != alenlist)
-		return(ALENLIST_FAILURE);
-
-	alenp = &chunk->alc_pair[index];
-
-	/* Return old values */
-	*addrp = alenp->al_length;
-	*lengthp = alenp->al_addr;
-
-	/* Set up new values */
-	alenp->al_length = length;
-	alenp->al_addr = addr;
-
-	/* Update cursor to point to next item */
-	cursorp->al_bcount = length;
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Initialize a cursor in order to walk an alenlist.
- * An alenlist_cursor always points to the last thing that was obtained
- * from the list.  If al_chunk is NULL, then nothing has yet been obtained.
- *
- * Note: There is an "internal cursor" associated with every Address/Length List.
- * For users that scan sequentially through a List, it is more efficient to
- * simply use the internal cursor.  The caller must insure that no other users
- * will simultaneously scan the List.  The caller can reposition the internal
- * cursor by calling alenlist_cursor_init with a NULL cursorp.
- */
-int
-alenlist_cursor_init(alenlist_t alenlist, size_t offset, alenlist_cursor_t cursorp)
-{
-	size_t byte_count;
-
-	if (cursorp == NULL)
-		cursorp = &alenlist->al_cursor;
-
-	/* Get internal cursor's byte count for use as a hint.
-	 *
-	 * If the internal cursor points passed the point that we're interested in,
-	 * we need to seek forward from the beginning.  Otherwise, we can seek forward
-	 * from the internal cursor.
-	 */
-	if ((offset > 0) &&
-	   ((byte_count = alenlist_cursor_offset(alenlist, (alenlist_cursor_t)NULL)) <= offset)) {
-		offset -= byte_count;
-		alenlist_cursor_clone(alenlist, NULL, cursorp);
-	} else
-		do_cursor_init(alenlist, cursorp);
-
-	/* We could easily speed this up, but it shouldn't be used very often. */
-	while (offset != 0) {
-		alenaddr_t addr;
-		size_t length;
-
-		if (alenlist_get(alenlist, cursorp, offset, &addr, &length, 0) != ALENLIST_SUCCESS)
-			return(ALENLIST_FAILURE);
-		offset -= length;
-	}
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Copy a cursor.  The source cursor is either an internal alenlist cursor
- * or an explicit cursor.
- */
-int
-alenlist_cursor_clone(	alenlist_t alenlist, 
-			alenlist_cursor_t cursorp_in, 
-			alenlist_cursor_t cursorp_out)
-{
-	ASSERT(cursorp_out);
-
-	if (alenlist && cursorp_in)
-		if (alenlist != cursorp_in->al_alenlist)
-			return(ALENLIST_FAILURE);
-
-	if (alenlist)
-		*cursorp_out = alenlist->al_cursor; /* small structure copy */
-	else if (cursorp_in)
-		*cursorp_out = *cursorp_in; /* small structure copy */
-	else
-		return(ALENLIST_FAILURE); /* no source */
-
-	return(ALENLIST_SUCCESS);
-}
-
-/*
- * Return the number of bytes passed so far according to the specified cursor.
- * If cursorp is NULL, use the alenlist's internal cursor.
- */
-size_t
-alenlist_cursor_offset(alenlist_t alenlist, alenlist_cursor_t cursorp)
-{
-	ASSERT(!alenlist || !cursorp || (alenlist == cursorp->al_alenlist));
-
-	if (cursorp == NULL) {
-		ASSERT(alenlist);
-		cursorp = &alenlist->al_cursor;
-	}
-
-	return(cursorp->al_offset);
-}
-
-/*
- * Allocate and initialize an Address/Length List cursor.
- */
-alenlist_cursor_t
-alenlist_cursor_create(alenlist_t alenlist, unsigned flags)
-{
-	alenlist_cursor_t cursorp;
-
-	ASSERT(alenlist != NULL);
-	cursorp = snia_kmem_zone_alloc(alenlist_cursor_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
-	if (cursorp) {
-		INCR_COUNT(&alenlist_cursor_count);
-		alenlist_cursor_init(alenlist, 0, cursorp);
-	}
-	return(cursorp);
-}
-
-/*
- * Free an Address/Length List cursor.
- */
-void
-alenlist_cursor_destroy(alenlist_cursor_t cursorp)
-{
-	DECR_COUNT(&alenlist_cursor_count);
-	snia_kmem_zone_free(alenlist_cursor_zone, cursorp);
-}
-
-
-/*
- * Fetch an address/length pair from an Address/Length List.  Update
- * the "cursor" so that next time this routine is called, we'll get
- * the next address range.  Never return a length that exceeds maxlength
- * (if non-zero).  If maxlength is a power of 2, never return a length 
- * that crosses a maxlength boundary.  [This may seem strange at first,
- * but it's what many drivers want.]
- *
- * Returns: SUCCESS/FAILURE
- */
-int
-alenlist_get(	alenlist_t alenlist, 		/* in: get from this list */
-		alenlist_cursor_t cursorp, 	/* inout: which item to get */
-		size_t	maxlength,		/* in: at most this length */
-		alenaddr_t *addrp, 		/* out: address */
-		size_t *lengthp,		/* out: length */
-		unsigned flags)
-{
-	alen_t *alenp;
-	alenlist_chunk_t chunk;
-	unsigned int index;
-	size_t bcount;
-	size_t length;
-
-	/* 
-	 * If no cursor explicitly specified, use the Address/Length List's 
-	 * internal cursor.
-	 */
-	if (cursorp == NULL) {
-		if (alenlist->al_logical_size == 0)
-			return(ALENLIST_FAILURE);
-		cursorp = &alenlist->al_cursor;
-	}
-
-	chunk = cursorp->al_chunk;
-	index = cursorp->al_index;
-	bcount = cursorp->al_bcount;
-
-	ASSERT(cursorp->al_alenlist == alenlist);
-	if (cursorp->al_alenlist != alenlist)
-		return(ALENLIST_FAILURE);
-
-	alenp = &chunk->alc_pair[index];
-	length = alenp->al_length - bcount;
-
-	/* Bump up to next pair, if we're done with this pair. */
-	if (length == 0) {
-		cursorp->al_bcount = bcount = 0;
-		cursorp->al_index = index = (index + 1) % ALEN_CHUNK_SZ;
-
-		/* Bump up to next chunk, if we're done with this chunk. */
-		if (index == 0) {
-			if (cursorp->al_chunk == alenlist->al_last_chunk)
-				return(ALENLIST_FAILURE);
-			chunk = chunk->alc_next;
-			ASSERT(chunk != NULL);
-		} else {
-			/* If in last chunk, don't go beyond end. */
-			if (cursorp->al_chunk == alenlist->al_last_chunk) {
-				int last_size = alenlist->al_logical_size % ALEN_CHUNK_SZ;
-				if (last_size && (index >= last_size))
-					return(ALENLIST_FAILURE);
-			}
-		}
-
-		alenp = &chunk->alc_pair[index];
-		length = alenp->al_length;
-	}
-
-	/* Constrain what we return according to maxlength */
-	if (maxlength) {
-		size_t maxlen1 = maxlength - 1;
-
-		if ((maxlength & maxlen1) == 0) /* power of 2 */
-			maxlength -= 
-			   ((alenp->al_addr + cursorp->al_bcount) & maxlen1);
-
-		length = min(maxlength, length);
-	}
-
-	/* Update the cursor, if desired. */
-	if (!(flags & AL_LEAVE_CURSOR)) {
-		cursorp->al_bcount += length;
-		cursorp->al_chunk = chunk;
-	}
-
-	*lengthp = length;
-	*addrp = alenp->al_addr + bcount;
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Return the number of pairs in the specified Address/Length List.
- * (For FIXED_SIZE Lists, this returns the logical size of the List, 
- * not the actual capacity of the List.)
- */
-int
-alenlist_size(alenlist_t alenlist)
-{
-	return(alenlist->al_logical_size);
-}
-
-
-/*
- * Concatenate two Address/Length Lists.
- */
-void
-alenlist_concat(alenlist_t from,
-		alenlist_t to)
-{
-	struct alenlist_cursor_s cursor;
-	alenaddr_t addr;
-	size_t length;
-
-	alenlist_cursor_init(from, 0, &cursor);
-
-	while(alenlist_get(from, &cursor, (size_t)0, &addr, &length, 0) == ALENLIST_SUCCESS)
-		alenlist_append(to, addr, length, 0);
-}
-
-/*
- * Create a copy of a list.
- * (Not all attributes of the old list are cloned.  For instance, if
- * a FIXED_SIZE list is cloned, the resulting list is NOT FIXED_SIZE.)
- */
-alenlist_t
-alenlist_clone(alenlist_t old_list, unsigned flags)
-{
-	alenlist_t new_list;
-
-	new_list = alenlist_create(flags);
-	if (new_list != NULL)
-		alenlist_concat(old_list, new_list);
-
-	return(new_list);
-}
-
-
-/* 
- * Convert a kernel virtual address to a Physical Address/Length List.
- */
-alenlist_t
-kvaddr_to_alenlist(alenlist_t alenlist, caddr_t kvaddr, size_t length, unsigned flags)
-{
-	alenaddr_t paddr;
-	long offset;
-	size_t piece_length;
-	int created_alenlist;
-
-	if (length <=0)
-		return(NULL);
-
-	/* If caller supplied a List, use it.  Otherwise, allocate one. */
-	if (alenlist == NULL) {
-		alenlist = alenlist_create(0);
-		created_alenlist = 1;
-	} else {
-		alenlist_clear(alenlist);
-		created_alenlist = 0;
-	}
-
-	paddr = kvtophys(kvaddr);
-	offset = poff(kvaddr);
-
-	/* Handle first page */
-	piece_length = min((size_t)(NBPP - offset), length);
-	if (alenlist_append(alenlist, paddr, piece_length, flags) == ALENLIST_FAILURE)
-		goto failure;
-	length -= piece_length;
-	kvaddr += piece_length;
-
-	/* Handle middle pages */
-	while (length >= NBPP) {
-		paddr = kvtophys(kvaddr);
-		if (alenlist_append(alenlist, paddr, NBPP, flags) == ALENLIST_FAILURE)
-			goto failure;
-		length -= NBPP;
-		kvaddr += NBPP;
-	}
-
-	/* Handle last page */
-	if (length) {
-		ASSERT(length < NBPP);
-		paddr = kvtophys(kvaddr);
-		if (alenlist_append(alenlist, paddr, length, flags) == ALENLIST_FAILURE)
-			goto failure;
-	}
-
-	alenlist_cursor_init(alenlist, 0, NULL);
-	return(alenlist);
-
-failure:
-	if (created_alenlist)
-		alenlist_destroy(alenlist);
-	return(NULL);
-}
-
-
-#if DEBUG
-static void
-alenlist_show(alenlist_t alenlist)
-{
-	struct alenlist_cursor_s cursor;
-	alenaddr_t addr;
-	size_t length;
-	int i = 0;
-
-	alenlist_cursor_init(alenlist, 0, &cursor);
-
-	qprintf("Address/Length List@0x%x:\n", alenlist);
-	qprintf("logical size=0x%x actual size=0x%x last_chunk at 0x%x\n", 
-		alenlist->al_logical_size, alenlist->al_actual_size, 
-		alenlist->al_last_chunk);
-	qprintf("cursor: chunk=0x%x index=%d offset=0x%x\n",
-		alenlist->al_cursor.al_chunk, 
-		alenlist->al_cursor.al_index,
-		alenlist->al_cursor.al_bcount);
-	while(alenlist_get(alenlist, &cursor, (size_t)0, &addr, &length, 0) == ALENLIST_SUCCESS)
-		qprintf("%d:\t0x%lx 0x%lx\n", ++i, addr, length);
-}
-#endif /* DEBUG */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/ate_utils.c linux-2.4.22-pre3/arch/ia64/sn/io/ate_utils.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/ate_utils.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/ate_utils.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,205 +0,0 @@
-/* $Id: ate_utils.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/io.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_defs.h>
-#include <asm/sn/prio.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/sn_private.h>
-
-#include <asm/sn/ate_utils.h>
-
-/*
- * Allocate the map needed to allocate the ATE entries.
- */
-struct map *
-atemapalloc(ulong_t mapsiz)
-{
-	struct map *mp;
-	ulong_t size;
-	struct a {
-		spinlock_t lock;
-		sv_t 	sema;
-	} *sync;
-
-	if (mapsiz == 0)
-		return(NULL);
-	size = sizeof(struct map) * (mapsiz + 2);
-	if ((mp = (struct map *) kmalloc(size, GFP_KERNEL)) == NULL)
-		return(NULL);
-	memset(mp, 0x0, size);
-
-	sync = kmalloc(sizeof(struct a), GFP_KERNEL);
-	if (sync == NULL) {
-		kfree(mp);
-		return(NULL);
-	}
-	memset(sync, 0x0, sizeof(struct a));
-
-	mutex_spinlock_init(&sync->lock);
-	sv_init( &(sync->sema), &(sync->lock), SV_MON_SPIN | SV_ORDER_FIFO /*| SV_INTS*/);
-	mp[1].m_size = (unsigned long) &sync->lock;
-	mp[1].m_addr = (unsigned long) &sync->sema;
-	mapsize(mp) = mapsiz - 1;
-	return(mp);
-}
-
-/*
- * free a map structure previously allocated via rmallocmap().
- */
-void
-atemapfree(struct map *mp)
-{
-	struct a {
-		spinlock_t lock;
-		sv_t 	sema;
-	};
-	/* ASSERT(sv_waitq(mapout(mp)) == 0); */
-	/* sv_destroy(mapout(mp)); */
-	spin_lock_destroy(maplock(mp));
-	kfree((void *)mp[1].m_size);
-	kfree(mp);
-}
-
-/*
- * Allocate 'size' units from the given map.
- * Return the base of the allocated space.
- * In a map, the addresses are increasing and the
- * list is terminated by a 0 size.
- * Algorithm is first-fit.
- */
-
-ulong_t
-atealloc(
-	struct map *mp,
-	size_t size)
-{
-	register unsigned int a;
-	register struct map *bp;
-	register unsigned long s;
-
-	ASSERT(size >= 0);
-
-	if (size == 0)
-		return((ulong_t) NULL);
-
-	s = mutex_spinlock(maplock(mp));
-
-	for (bp = mapstart(mp); bp->m_size; bp++) {
-		if (bp->m_size >= size) {
-			a = bp->m_addr;
-			bp->m_addr += size;
-			if ((bp->m_size -= size) == 0) {
-				do {
-					bp++;
-					(bp-1)->m_addr = bp->m_addr;
-				} while ((((bp-1)->m_size) = (bp->m_size)));
-				mapsize(mp)++;
-			}
-
-			ASSERT(bp->m_size < 0x80000000);
-			mutex_spinunlock(maplock(mp), s);
-			return(a);
-		}
-	}
-
-	/*
-	 * We did not get what we need .. we cannot sleep .. 
-	 */
-	mutex_spinunlock(maplock(mp), s);
-	return(0);
-}
-
-/*
- * Free the previously allocated space a of size units into the specified map.
- * Sort ``a'' into map and combine on one or both ends if possible.
- * Returns 0 on success, 1 on failure.
- */
-void
-atefree(struct map *mp, size_t size, ulong_t a)
-{
-	register struct map *bp;
-	register unsigned int t;
-	register unsigned long s;
-
-	ASSERT(size >= 0);
-
-	if (size == 0)
-		return;
-
-	bp = mapstart(mp);
-	s = mutex_spinlock(maplock(mp));
-
-	for ( ; bp->m_addr<=a && bp->m_size!=0; bp++)
-		;
-	if (bp>mapstart(mp) && (bp-1)->m_addr+(bp-1)->m_size == a) {
-		(bp-1)->m_size += size;
-		if (bp->m_addr) {	
-			/* m_addr==0 end of map table */
-			ASSERT(a+size <= bp->m_addr);
-			if (a+size == bp->m_addr) { 
-
-				/* compress adjacent map addr entries */
-				(bp-1)->m_size += bp->m_size;
-				while (bp->m_size) {
-					bp++;
-					(bp-1)->m_addr = bp->m_addr;
-					(bp-1)->m_size = bp->m_size;
-				}
-				mapsize(mp)++;
-			}
-		}
-	} else {
-		if (a+size == bp->m_addr && bp->m_size) {
-			bp->m_addr -= size;
-			bp->m_size += size;
-		} else {
-			ASSERT(size);
-			if (mapsize(mp) == 0) {
-				mutex_spinunlock(maplock(mp), s);
-				printk("atefree : map overflow 0x%p Lost 0x%lx items at 0x%lx",
-						(void *)mp, size, a) ;
-				return ;
-			}
-			do {
-				t = bp->m_addr;
-				bp->m_addr = a;
-				a = t;
-				t = bp->m_size;
-				bp->m_size = size;
-				bp++;
-			} while ((size = t));
-			mapsize(mp)--;
-		}
-	}
-	mutex_spinunlock(maplock(mp), s);
-	/*
-	 * wake up everyone waiting for space
-	 */
-	if (mapout(mp))
-		;
-		/* sv_broadcast(mapout(mp)); */
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/cdl.c linux-2.4.22-pre3/arch/ia64/sn/io/cdl.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/cdl.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/cdl.c	2003-07-05 18:09:40.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
@@ -18,9 +18,9 @@
 #include <asm/sn/xtalk/xbow.h>
 
 /* these get called directly in cdl_add_connpt in fops bypass hack */
-extern int pcibr_attach(devfs_handle_t);
-extern int xbow_attach(devfs_handle_t);
-extern int pic_attach(devfs_handle_t);
+extern int pcibr_attach(vertex_hdl_t);
+extern int xbow_attach(vertex_hdl_t);
+extern int pic_attach(vertex_hdl_t);
 
 
 /*
@@ -32,75 +32,20 @@
  *	IO Infrastructure Drivers e.g. pcibr.
  */
 
-struct cdl {
-    int		part_num;
-    int		mfg_num;
-    int (*attach) (devfs_handle_t);
-} dummy_reg;
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define MAX_SGI_IO_INFRA_DRVR 4
-#else
 #define MAX_SGI_IO_INFRA_DRVR 7
-#endif
+
 static struct cdl sgi_infrastructure_drivers[MAX_SGI_IO_INFRA_DRVR] =
 {
 	{ XBRIDGE_WIDGET_PART_NUM, XBRIDGE_WIDGET_MFGR_NUM, pcibr_attach /* &pcibr_fops  */},
 	{ BRIDGE_WIDGET_PART_NUM,  BRIDGE_WIDGET_MFGR_NUM,  pcibr_attach /* &pcibr_fops */},
-#ifndef CONFIG_IA64_SGI_SN1
 	{ PIC_WIDGET_PART_NUM_BUS0,  PIC_WIDGET_MFGR_NUM,   pic_attach /* &pic_fops */},
 	{ PIC_WIDGET_PART_NUM_BUS1,  PIC_WIDGET_MFGR_NUM,   pic_attach /* &pic_fops */},
-#endif
 	{ XXBOW_WIDGET_PART_NUM,   XXBOW_WIDGET_MFGR_NUM,   xbow_attach /* &xbow_fops */},
 	{ XBOW_WIDGET_PART_NUM,    XBOW_WIDGET_MFGR_NUM,    xbow_attach /* &xbow_fops */},
-#ifndef CONFIG_IA64_SGI_SN1
 	{ PXBOW_WIDGET_PART_NUM,   XXBOW_WIDGET_MFGR_NUM,   xbow_attach /* &xbow_fops */},
-#endif
 };
 
 /*
- * cdl_new:  Called by pciio and xtalk.
- */
-cdl_p
-cdl_new(char *name, char *k1str, char *k2str)
-{
-    /*
-     * Just return a dummy pointer.
-     */
-    return((cdl_p)&dummy_reg);
-}
-
-/*
- * cdl_del: Do nothing.
- */
-void
-cdl_del(cdl_p reg)
-{
-	return;
-}
-
-/*
- * cdl_add_driver: The driver part number and manufacturers number 
- * are statically initialized above.
- * 
-  Do nothing.
- */
-int
-cdl_add_driver(cdl_p reg, int key1, int key2, char *prefix, int flags, cdl_drv_f *func)
-{
-    return 0;
-}
-
-/*
- * cdl_del_driver: Not supported.
- */
-void
-cdl_del_driver(cdl_p reg, char *prefix, cdl_drv_f *func)
-{
-	return;
-}
-
-/*
  * cdl_add_connpt: We found a device and it's connect point.  Call the 
  * attach routine of that driver.
  *
@@ -112,8 +57,8 @@
  * vertices.
  */
 int
-cdl_add_connpt(cdl_p reg, int part_num, int mfg_num, 
-	       devfs_handle_t connpt, int drv_flags)
+cdl_add_connpt(int part_num, int mfg_num, 
+	       vertex_hdl_t connpt, int drv_flags)
 {
 	int i;
 	
@@ -121,7 +66,6 @@
 	 * Find the driver entry point and call the attach routine.
 	 */
 	for (i = 0; i < MAX_SGI_IO_INFRA_DRVR; i++) {
-
 		if ( (part_num == sgi_infrastructure_drivers[i].part_num) &&
 		   ( mfg_num == sgi_infrastructure_drivers[i].mfg_num) ) {
 			/*
@@ -139,73 +83,3 @@
 
 	return (0);
 }
-
-/*
- * cdl_del_connpt: Not implemented.
- */
-int
-cdl_del_connpt(cdl_p reg, int key1, int key2, devfs_handle_t connpt, int drv_flags)
-{
-
-	return(0);
-}
-
-/*
- *    cdl_iterate: Not Implemented.
- */
-void
-cdl_iterate(cdl_p reg,
-	    char *prefix,
-	    cdl_iter_f * func)
-{
-	return;
-}
-
-async_attach_t 
-async_attach_new(void)
-{
-
-	return(0);
-}
-
-void 
-async_attach_free(async_attach_t aa)
-{
-	return;
-}
-
-async_attach_t 
-async_attach_get_info(devfs_handle_t vhdl)
-{
-
-	return(0);
-}
-
-void            
-async_attach_add_info(devfs_handle_t vhdl, async_attach_t aa)
-{
-	return;
-
-}
-
-void            
-async_attach_del_info(devfs_handle_t vhdl)
-{
-	return;
-}
-
-void async_attach_signal_start(async_attach_t aa)
-{
-	return;
-}
-
-void async_attach_signal_done(async_attach_t aa)
-{
-	return;
-}
-
-void async_attach_waitall(async_attach_t aa)
-{
-	return;
-}
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/drivers/Makefile linux-2.4.22-pre3/arch/ia64/sn/io/drivers/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/io/drivers/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/drivers/Makefile	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,18 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+O_TARGET := snio.o
+
+obj-y				+= hubdev.o ioconfig_bus.o ifconfig_net.o
+
+obj-$(CONFIG_PCIBA)		+= pciba.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/drivers/hubdev.c linux-2.4.22-pre3/arch/ia64/sn/io/drivers/hubdev.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/drivers/hubdev.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/drivers/hubdev.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,100 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+
+struct hubdev_callout {
+        int (*attach_method)(vertex_hdl_t);
+        struct hubdev_callout *fp;
+};
+
+typedef struct hubdev_callout hubdev_callout_t;
+
+mutex_t hubdev_callout_mutex;
+static hubdev_callout_t *hubdev_callout_list;
+
+void
+hubdev_init(void)
+{
+	mutex_init(&hubdev_callout_mutex);
+        hubdev_callout_list = NULL;
+}
+        
+void
+hubdev_register(int (*attach_method)(vertex_hdl_t))
+{
+        hubdev_callout_t *callout;
+        
+        ASSERT(attach_method);
+
+        callout =  (hubdev_callout_t *)snia_kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP);
+        ASSERT(callout);
+        
+	mutex_lock(&hubdev_callout_mutex);
+        /*
+         * Insert at the end of the list
+         */
+        callout->fp = hubdev_callout_list;
+        hubdev_callout_list = callout;
+        callout->attach_method = attach_method;
+	mutex_unlock(&hubdev_callout_mutex);
+}
+
+int
+hubdev_unregister(int (*attach_method)(vertex_hdl_t))
+{
+        hubdev_callout_t **p;
+        
+        ASSERT(attach_method);
+   
+	mutex_lock(&hubdev_callout_mutex);
+        /*
+         * Remove registry element containing attach_method
+         */
+        for (p = &hubdev_callout_list; *p != NULL; p = &(*p)->fp) {
+                if ((*p)->attach_method == attach_method) {
+                        hubdev_callout_t* victim = *p;
+                        *p = (*p)->fp;
+                        kfree(victim);
+                        mutex_unlock(&hubdev_callout_mutex);
+                        return (0);
+                }
+        }
+        mutex_unlock(&hubdev_callout_mutex);
+        return (ENOENT);
+}
+
+
+int
+hubdev_docallouts(vertex_hdl_t hub)
+{
+        hubdev_callout_t *p;
+        int errcode;
+
+	mutex_lock(&hubdev_callout_mutex);
+        
+        for (p = hubdev_callout_list; p != NULL; p = p->fp) {
+                ASSERT(p->attach_method);
+                errcode = (*p->attach_method)(hub);
+                if (errcode != 0) {
+			mutex_unlock(&hubdev_callout_mutex);
+                        return (errcode);
+                }
+        }
+        mutex_unlock(&hubdev_callout_mutex);
+        return (0);
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/drivers/ifconfig_net.c linux-2.4.22-pre3/arch/ia64/sn/io/drivers/ifconfig_net.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/drivers/ifconfig_net.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/drivers/ifconfig_net.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,298 @@
+/* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  ifconfig_net - SGI's Persistent Network Device names.
+ *
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/sn/sgi.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/ifconfig_net.h>
+
+#define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER"
+#define SGI_IFCONFIG_NET_VERSION "1.0"
+
+/*
+ * Some Global definitions.
+ */
+static devfs_handle_t ifconfig_net_handle;
+static unsigned long ifconfig_net_debug;
+
+/*
+ * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net".
+ */
+static int ifconfig_net_open(struct inode * inode, struct file * filp)
+{
+	if (ifconfig_net_debug) {
+        	printk("ifconfig_net_open called.\n");
+	}
+
+        return(0);
+
+}
+
+/*
+ * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net".
+ */
+static int ifconfig_net_close(struct inode * inode, struct file * filp)
+{
+
+	if (ifconfig_net_debug) {
+        	printk("ifconfig_net_close called.\n");
+	}
+
+        return(0);
+}
+
+/*
+ * assign_ifname - Assign the next available interface name from the persistent list.
+ */
+void
+assign_ifname(struct net_device *dev,
+		  struct ifname_num *ifname_num)
+
+{
+
+	/*
+	 * Handle eth devices.
+	 */
+        if ( (memcmp(dev->name, "eth", 3) == 0) ) {
+		if (ifname_num->next_eth != -1) {
+			/*
+			 * Assign it the next available eth interface number. 
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "eth%d", (int)ifname_num->next_eth);
+			ifname_num->next_eth++;
+		} 
+
+                return;
+        }
+
+	/*
+	 * Handle fddi devices.
+	 */
+	if ( (memcmp(dev->name, "fddi", 4) == 0) ) {
+		if (ifname_num->next_fddi != -1) {
+			/*
+			 * Assign it the next available fddi interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi);
+			ifname_num->next_fddi++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle hip devices.
+	 */
+	if ( (memcmp(dev->name, "hip", 3) == 0) ) {
+		if (ifname_num->next_hip != -1) {
+			/*
+			 * Assign it the next available hip interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "hip%d", (int)ifname_num->next_hip);
+			ifname_num->next_hip++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle tr devices.
+	 */
+	if ( (memcmp(dev->name, "tr", 2) == 0) ) {
+		if (ifname_num->next_tr != -1) {
+			/*
+			 * Assign it the next available tr interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "tr%d", (int)ifname_num->next_tr);
+			ifname_num->next_tr++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle fc devices.
+	 */
+	if ( (memcmp(dev->name, "fc", 2) == 0) ) {
+		if (ifname_num->next_fc != -1) {
+			/*
+			 * Assign it the next available fc interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "fc%d", (int)ifname_num->next_fc);
+			ifname_num->next_fc++;
+		}
+
+		return;
+	}
+}
+
+/*
+ * find_persistent_ifname: Returns the entry that was seen in previous boot.
+ */
+struct ifname_MAC *
+find_persistent_ifname(struct net_device *dev,
+	struct ifname_MAC *ifname_MAC)
+
+{
+
+	while (ifname_MAC->addr_len) {
+		if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0)
+			return(ifname_MAC);
+
+		ifname_MAC++;
+	}
+
+	return(NULL);
+}
+
+/*
+ * ifconfig_net_ioctl: ifconfig_net driver ioctl interface.
+ */
+static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	extern struct net_device *__dev_get_by_name(const char *);
+#ifdef CONFIG_NET
+	struct net_device *dev;
+	struct ifname_MAC *found;
+	char temp[64];
+#endif
+	struct ifname_MAC *ifname_MAC;
+	struct ifname_MAC *new_devices, *temp_new_devices;
+	struct ifname_num *ifname_num;
+	unsigned long size;
+
+
+	if (ifconfig_net_debug) {
+		printk("HCL: hcl_ioctl called.\n");
+	}
+
+	/*
+	 * Read in the header and see how big of a buffer we really need to 
+	 * allocate.
+	 */
+	ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), 
+			GFP_KERNEL);
+	copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num));
+	size = ifname_num->size;
+	kfree(ifname_num);
+	ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL);
+	ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) );
+
+	copy_from_user( ifname_num, (char *) arg, size);
+	new_devices =  kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL);
+	temp_new_devices = new_devices;
+
+	memset(new_devices, 0, size - sizeof(struct ifname_num));
+
+#ifdef CONFIG_NET
+	/*
+	 * Go through the net device entries and make them persistent!
+	 */
+	for (dev = dev_base; dev != NULL; dev = dev->next) {
+		/*
+		 * Skip NULL entries or "lo"
+		 */
+		if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){
+			continue;
+		}
+
+		/*
+		 * See if we have a persistent interface name for this device.
+		 */
+		found = NULL;
+		found = find_persistent_ifname(dev, ifname_MAC);
+		if (found) {
+			strcpy(dev->name, found->name);
+		} else {
+			/* Never seen this before .. */
+			assign_ifname(dev, ifname_num);
+
+			/* 
+			 * Save the information for the next boot.
+			 */
+ 			sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
+				dev->dev_addr[0],  dev->dev_addr[1],  dev->dev_addr[2],
+				dev->dev_addr[3],  dev->dev_addr[4],  dev->dev_addr[5]);
+			strcpy(temp_new_devices->name, dev->name);
+			temp_new_devices->addr_len = dev->addr_len;
+			memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len);
+			temp_new_devices++;
+		}
+		
+	}
+#endif
+
+	/*
+	 * Copy back to the User Buffer area any new devices encountered.
+	 */
+	copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, 
+			size - sizeof(struct ifname_num));
+
+	return(0);
+
+}
+
+struct file_operations ifconfig_net_fops = {
+	ioctl:ifconfig_net_ioctl,	/* ioctl */
+	open:ifconfig_net_open,		/* open */
+	release:ifconfig_net_close	/* release */
+};
+
+
+/*
+ * init_ifconfig_net() - Boot time initialization.  Ensure that it is called 
+ *	after devfs has been initialized.
+ *
+ */
+#ifdef MODULE
+int init_module (void)
+#else
+int __init init_ifconfig_net(void)
+#endif
+{
+	ifconfig_net_handle = NULL;
+	ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net",
+			0, DEVFS_FL_AUTO_DEVNUM,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&ifconfig_net_fops, NULL);
+
+	if (ifconfig_net_handle == NULL) {
+		panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.\n");
+	}
+
+	return(0);
+
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/drivers/ioconfig_bus.c linux-2.4.22-pre3/arch/ia64/sn/io/drivers/ioconfig_bus.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/drivers/ioconfig_bus.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/drivers/ioconfig_bus.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,401 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  ioconfig_bus - SGI's Persistent PCI Bus Numbering.
+ *
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/pci.h>
+
+#include <asm/sn/sgi.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm//sn/sn_sal.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/ioconfig_bus.h>
+
+#define SGI_IOCONFIG_BUS "SGI-PERSISTENT PCI BUS NUMBERING"
+#define SGI_IOCONFIG_BUS_VERSION "1.0"
+
+/*
+ * Some Global definitions.
+ */
+static vertex_hdl_t ioconfig_bus_handle;
+static unsigned long ioconfig_bus_debug;
+
+#ifdef IOCONFIG_BUS_DEBUG
+#define DBG(x...)	printk(x)
+#else
+#define DBG(x...)
+#endif
+
+static u64 ioconfig_file;
+static u64 ioconfig_file_size;
+static u64 ioconfig_activated;
+static char ioconfig_kernopts[128];
+
+/*
+ * For debugging purpose .. hardcode a table ..
+ */
+struct  ascii_moduleid *ioconfig_bus_table;
+u64 ioconfig_bus_table_size;
+
+
+static int free_entry;
+static int new_entry;
+
+int next_basebus_number;
+
+void
+ioconfig_get_busnum(char *io_moduleid, int *bus_num)
+{
+	struct	ascii_moduleid  *temp;
+	int index;
+
+	DBG("ioconfig_get_busnum io_moduleid %s\n", io_moduleid);
+
+	*bus_num = -1;
+	temp = ioconfig_bus_table;
+	for (index = 0; index < free_entry; temp++, index++) {
+		if ( (io_moduleid[0] == temp->io_moduleid[0]) &&
+		     (io_moduleid[1] == temp->io_moduleid[1]) &&
+		     (io_moduleid[2] == temp->io_moduleid[2]) &&
+		     (io_moduleid[4] == temp->io_moduleid[4]) &&
+		     (io_moduleid[5] == temp->io_moduleid[5]) ) {
+			*bus_num = index * 0x10;
+			return;
+		}
+	}
+
+	/*
+	 * New IO Brick encountered.
+	 */
+	if (((int)io_moduleid[0]) == 0) {
+		DBG("ioconfig_get_busnum: Invalid Module Id given %s\n", io_moduleid);
+		return;
+	}
+
+	io_moduleid[3] = '#';
+	strcpy((char *)&(ioconfig_bus_table[free_entry].io_moduleid), io_moduleid);
+	*bus_num = free_entry * 0x10;
+	free_entry++;
+}
+
+static void
+dump_ioconfig_table(void)
+{
+
+	int index = 0;
+	struct ascii_moduleid *temp;
+
+	temp = ioconfig_bus_table;
+	while (index < free_entry) {
+		DBG("ASSCI Module ID %s\n", temp->io_moduleid);
+		temp++;
+		index++;
+	}
+}
+
+/*
+ * nextline
+ *	This routine returns the nextline in the buffer.
+ */
+int nextline(char *buffer, char **next, char *line)
+{
+
+	char *temp;
+
+	if (buffer[0] == 0x0) {
+		return(0);
+	}
+
+	temp = buffer;
+	while (*temp != 0) {
+		*line = *temp;
+		if (*temp != '\n'){
+			*line = *temp;
+			temp++; line++;
+		} else
+			break;
+	}
+
+	if (*temp == 0)
+		*next = temp;
+	else
+		*next = ++temp;
+
+	return(1);
+}
+
+/*
+ * build_pcibus_name
+ *	This routine parses the ioconfig contents read into
+ *	memory by ioconfig command in EFI and builds the
+ *	persistent pci bus naming table.
+ */
+void
+build_moduleid_table(char *file_contents, struct ascii_moduleid *table)
+{
+	/*
+	 * Read the whole file into memory.
+	 */
+	int rc;
+	char *name;
+	char *temp;
+	char *next;
+	char *current;
+	char *line;
+	struct ascii_moduleid *moduleid;
+
+	line = kmalloc(256, GFP_KERNEL);
+	memset(line, 0,256);
+	name = kmalloc(125, GFP_KERNEL);
+	memset(name, 0, 125);
+	moduleid = table;
+	current = file_contents;
+	while (nextline(current, &next, line)){
+
+		DBG("current 0x%lx next 0x%lx\n", current, next);
+
+		temp = line;
+		/*
+		 * Skip all leading Blank lines ..
+		 */
+		while (isspace(*temp))
+			if (*temp != '\n')
+				temp++;
+			else
+				break;
+
+		if (*temp == '\n') {
+			current = next;
+			memset(line, 0, 256);
+			continue;
+		}
+ 
+		/*
+		 * Skip comment lines
+		 */
+		if (*temp == '#') {
+			current = next;
+			memset(line, 0, 256);
+			continue;
+		}
+
+		/*
+		 * Get the next free entry in the table.
+		 */
+		rc = sscanf(temp, "%s", name);
+		strcpy(&moduleid->io_moduleid[0], name);
+		DBG("Found %s\n", name);
+		moduleid++;
+		free_entry++;
+		current = next;
+		memset(line, 0, 256);
+	}
+
+	new_entry = free_entry;
+	kfree(line);
+	kfree(name);
+
+	return;
+}
+
+void
+ioconfig_bus_init(void)
+{
+
+	struct ia64_sal_retval ret_stuff;
+	u64	*temp;
+	int	cnode;
+
+	DBG("ioconfig_bus_init called.\n");
+
+        for (cnode = 0; cnode < numnodes; cnode++) {
+		nasid_t nasid;
+		/*
+	 	 * Make SAL call to get the address of the bus configuration table.
+	 	 */
+		ret_stuff.status = (uint64_t)0;
+		ret_stuff.v0 = (uint64_t)0;
+		ret_stuff.v1 = (uint64_t)0;
+		ret_stuff.v2 = (uint64_t)0;
+		nasid = COMPACT_TO_NASID_NODEID(cnode);
+		SAL_CALL(ret_stuff, SN_SAL_BUS_CONFIG, 0, nasid, 0, 0, 0, 0, 0);
+		temp = (u64 *)TO_NODE_CAC(nasid, ret_stuff.v0);
+		ioconfig_file = *temp;
+		DBG("ioconfig_bus_init: Nasid %d ret_stuff.v0 0x%lx\n", nasid,
+			ret_stuff.v0);
+		if (ioconfig_file) {
+			ioconfig_file_size = ret_stuff.v1;
+			ioconfig_file = (ioconfig_file | CACHEABLE_MEM_SPACE);
+			ioconfig_activated = 1;
+			break;
+		}
+	}
+
+	DBG("ioconfig_bus_init: ret_stuff.v0 %p ioconfig_file %p %d\n",
+		ret_stuff.v0, (void *)ioconfig_file, (int)ioconfig_file_size);
+
+	ioconfig_bus_table = kmalloc( 512, GFP_KERNEL );
+	memset(ioconfig_bus_table, 0, 512);
+
+	/*
+	 * If ioconfig options are given on the bootline .. take it.
+	 */
+	if (*ioconfig_kernopts != '\0') {
+		/*
+		 * ioconfig="..." kernel options given.
+		 */
+		DBG("ioconfig_bus_init: Kernel Options given.\n");
+		(void) build_moduleid_table((char *)ioconfig_kernopts, ioconfig_bus_table);
+		(void) dump_ioconfig_table();
+		return;
+	}
+
+	if (ioconfig_activated) {
+		DBG("ioconfig_bus_init: ioconfig file given.\n");
+		(void) build_moduleid_table((char *)ioconfig_file, ioconfig_bus_table);
+		(void) dump_ioconfig_table();
+	} else {
+		DBG("ioconfig_bus_init: ioconfig command not executed in prom\n");
+	}
+
+}
+
+void
+ioconfig_bus_new_entries(void)
+{
+
+	
+	int index = 0;
+	struct ascii_moduleid *temp;
+
+	if ((ioconfig_activated) && (free_entry > new_entry)) {
+		printk("### Please add the following new IO Bricks Module ID \n");
+		printk("### to your Persistent Bus Numbering Config File\n");
+	} else
+		return;
+
+	index = new_entry;
+	temp = &ioconfig_bus_table[index];
+        while (index < free_entry) {
+                printk("%s\n", (char *)temp);
+		temp++;
+                index++;
+        }
+	printk("### End\n");
+
+}
+static int ioconfig_bus_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	struct ioconfig_parm parm;
+
+	/*
+	 * Copy in the parameters.
+	 */
+	copy_from_user(&parm, (char *)arg, sizeof(struct ioconfig_parm));
+	parm.number = free_entry - new_entry;
+	parm.ioconfig_activated = ioconfig_activated;
+	copy_to_user((char *)arg, &parm, sizeof(struct ioconfig_parm));
+	copy_to_user((char *)parm.buffer, &ioconfig_bus_table[new_entry], sizeof(struct  ascii_moduleid) * (free_entry - new_entry));
+
+	return 0;
+}
+
+/*
+ * ioconfig_bus_open - Opens the special device node "/dev/hw/.ioconfig_bus".
+ */
+static int ioconfig_bus_open(struct inode * inode, struct file * filp)
+{
+	if (ioconfig_bus_debug) {
+        	DBG("ioconfig_bus_open called.\n");
+	}
+
+        return(0);
+
+}
+
+/*
+ * ioconfig_bus_close - Closes the special device node "/dev/hw/.ioconfig_bus".
+ */
+static int ioconfig_bus_close(struct inode * inode, struct file * filp)
+{
+
+	if (ioconfig_bus_debug) {
+        	DBG("ioconfig_bus_close called.\n");
+	}
+
+        return(0);
+}
+
+struct file_operations ioconfig_bus_fops = {
+	ioctl:ioconfig_bus_ioctl,
+	open:ioconfig_bus_open,		/* open */
+	release:ioconfig_bus_close	/* release */
+};
+
+
+/*
+ * init_ifconfig_bus() - Boot time initialization.  Ensure that it is called 
+ *	after devfs has been initialized.
+ *
+ */
+int init_ioconfig_bus(void)
+{
+	ioconfig_bus_handle = NULL;
+	ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus",
+			0, DEVFS_FL_AUTO_DEVNUM,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&ioconfig_bus_fops, NULL);
+
+	if (ioconfig_bus_handle == NULL) {
+		panic("Unable to create SGI PERSISTENT BUS NUMBERING Driver.\n");
+	}
+
+	return(0);
+
+}
+
+static int __init ioconfig_bus_setup (char *str)
+{
+
+	char *temp;
+
+	DBG("ioconfig_bus_setup: Kernel Options %s\n", str);
+
+	temp = (char *)ioconfig_kernopts;
+	memset(temp, 0, 128);
+	while ( (*str != '\0') && !isspace (*str) ) {
+		if (*str == ',') {
+			*temp = '\n';
+			temp++;
+			str++;
+			continue;
+		}
+		*temp = *str;
+		temp++;
+		str++;
+	}
+
+	return(0);
+		
+}
+__setup("ioconfig=", ioconfig_bus_setup);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/drivers/pciba.c linux-2.4.22-pre3/arch/ia64/sn/io/drivers/pciba.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/drivers/pciba.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/drivers/pciba.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,945 @@
+/*
+ * arch/ia64/sn/io/pciba.c
+ *
+ * IRIX PCIBA-inspired user mode PCI interface
+ *
+ * requires: devfs
+ *
+ * device nodes show up in /dev/pci/BB/SS.F (where BB is the bus the
+ * device is on, SS is the slot the device is in, and F is the
+ * device's function on a multi-function card).
+ *
+ * when compiled into the kernel, it will only be initialized by the
+ * sgi sn1 specific initialization code.  in this case, device nodes
+ * are under /dev/hw/..../
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+ *
+ * 03262001 - Initial version by Chad Talbott
+ */
+
+
+/* jesse's beefs:
+
+   register_pci_device should be documented
+   
+   grossness with do_swap should be documented
+   
+   big, gross union'ized node_data should be replaced with independent
+   structures
+
+   replace global list of nodes with global lists of resources.  could
+   use object oriented approach of allocating and cleaning up
+   resources.
+   
+*/
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+#include <linux/raw.h>
+#include <linux/capability.h>
+
+#include <asm/uaccess.h>
+#include <asm/sn/sgi.h>
+#include <asm/io.h>
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/system.h>
+
+#include <asm/sn/pci/pciba.h>
+
+
+MODULE_DESCRIPTION("User mode PCI interface");
+MODULE_AUTHOR("Chad Talbott");
+
+
+#undef DEBUG_PCIBA
+/* #define DEBUG_PCIBA */
+
+#undef TRACE_PCIBA
+/* #define TRACE_PCIBA */
+
+#if defined(DEBUG_PCIBA)
+#  define DPRINTF(x...) printk(KERN_DEBUG x)
+#else
+#  define DPRINTF(x...)
+#endif
+
+#if defined(TRACE_PCIBA)
+#  if defined(__GNUC__)
+#    define TRACE()	printk(KERN_DEBUG "%s:%d:%s\n", \
+			       __FILE__, __LINE__, __FUNCTION__)
+#  else
+#    define TRACE()	printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__)
+#  endif
+#else
+#  define TRACE()
+#endif
+
+
+typedef enum { failure, success } status;
+typedef enum { false, true } boolean;
+
+
+/* major data structures:
+
+   struct node_data -
+   
+   	one for each file registered with devfs.  contains everything
+   	that any file's fops would need to know about.
+
+   struct dma_allocation -
+
+   	a single DMA allocation.  only the 'dma' nodes care about
+   	these.  they are there primarily to allow the driver to look
+   	up the kernel virtual address of dma buffers allocated by
+   	pci_alloc_consistent, as the application is only given the
+   	physical address (to program the device's dma, presumably) and
+   	cannot supply the kernel virtual address when freeing the
+   	buffer.
+
+	it's also useful to maintain a list of buffers allocated
+	through a specific node to allow some sanity checking by this
+	driver.  this prevents (for example) a broken application from
+	freeing buffers that it didn't allocate, or buffers allocated
+	on another node.
+   
+   global_node_list -
+
+   	a list of all nodes allocated.  this allows the driver to free
+   	all the memory it has 'kmalloc'd in case of an error, or on
+   	module removal.
+
+   global_dma_list -
+
+        a list of all dma buffers allocated by this driver.  this
+	allows the driver to 'pci_free_consistent' all buffers on
+	module removal or error.
+
+*/
+
+
+struct node_data {
+	/* flat list of all the device nodes.  makes it easy to free
+	   them all when we're unregistered */
+	struct list_head global_node_list;
+	vertex_hdl_t devfs_handle;
+
+	void (* cleanup)(struct node_data *);
+
+	union {
+		struct {
+			struct pci_dev * dev;
+			struct list_head dma_allocs;
+			boolean mmapped;
+		} dma;
+		struct {
+			struct pci_dev * dev;
+			u32 saved_rom_base_reg;
+			boolean mmapped;
+		} rom;
+		struct {
+			struct resource * res;
+		} base;
+		struct {
+			struct pci_dev * dev;
+		} config;
+	} u;
+};
+
+struct dma_allocation {
+	struct list_head list;
+
+	dma_addr_t handle;
+	void * va;
+	size_t size;
+};
+
+
+static LIST_HEAD(global_node_list);
+static LIST_HEAD(global_dma_list);
+
+
+/* module entry points */
+int __init pciba_init(void);
+void __exit pciba_exit(void);
+
+static status __init register_with_devfs(void);
+static void __exit unregister_with_devfs(void);
+
+static status __init register_pci_device(vertex_hdl_t device_dir_handle,
+					 struct pci_dev * dev);
+
+/* file operations */
+static int generic_open(struct inode * inode, struct file * file);
+static int rom_mmap(struct file * file, struct vm_area_struct * vma);
+static int rom_release(struct inode * inode, struct file * file);
+static int base_mmap(struct file * file, struct vm_area_struct * vma);
+static int config_ioctl(struct inode * inode, struct file * file, 
+			unsigned int cmd, 
+			unsigned long arg);
+static int dma_ioctl(struct inode * inode, struct file * file, 
+		     unsigned int cmd, 
+		     unsigned long arg);
+static int dma_mmap(struct file * file, struct vm_area_struct * vma);
+
+/* support routines */
+static int mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va);
+static int mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va);
+
+#ifdef DEBUG_PCIBA
+static void dump_nodes(struct list_head * nodes);
+static void dump_allocations(struct list_head * dalp);
+#endif
+
+/* file operations for each type of node */
+static struct file_operations rom_fops = {
+	owner:		THIS_MODULE,
+	mmap:		rom_mmap,
+	open:		generic_open,
+	release:	rom_release
+};
+ 
+
+static struct file_operations base_fops = {
+	owner:		THIS_MODULE,
+	mmap:		base_mmap,
+	open:		generic_open
+};
+
+
+static struct file_operations config_fops = {
+	owner:		THIS_MODULE,
+	ioctl:		config_ioctl,
+	open:		generic_open
+};	
+
+static struct file_operations dma_fops = {
+	owner:		THIS_MODULE,
+	ioctl:		dma_ioctl,
+	mmap:		dma_mmap,
+	open:		generic_open
+};	
+
+
+module_init(pciba_init);
+module_exit(pciba_exit);
+
+
+int __init
+pciba_init(void)
+{
+	if (!ia64_platform_is("sn2"))
+		return -ENODEV;
+
+	TRACE();
+
+	if (register_with_devfs() == failure)
+		return 1; /* failure */
+
+	printk("PCIBA (a user mode PCI interface) initialized.\n");
+
+	return 0; /* success */
+}
+
+
+void __exit
+pciba_exit(void)
+{
+	TRACE();
+
+	/* FIXME: should also free all that memory that we allocated
+           ;) */
+	unregister_with_devfs();
+}
+
+
+# if 0
+static void __exit
+free_nodes(void)
+{
+	struct node_data * nd;
+	
+	TRACE();
+
+	list_for_each(nd, &node_list) {
+		kfree(list_entry(nd, struct nd, node_list));
+	}
+}
+#endif
+
+
+static vertex_hdl_t pciba_devfs_handle;
+
+
+extern vertex_hdl_t
+devfn_to_vertex(unsigned char busnum, unsigned int devfn);
+
+static status __init
+register_with_devfs(void)
+{
+	struct pci_dev * dev;
+	vertex_hdl_t device_dir_handle;
+
+	TRACE();
+
+	/* FIXME: don't forget /dev/.../pci/mem & /dev/.../pci/io */
+
+	pci_for_each_dev(dev) {
+		device_dir_handle = devfn_to_vertex(dev->bus->number,
+						    dev->devfn);
+		if (device_dir_handle == NULL)
+			return failure;
+	
+		if (register_pci_device(device_dir_handle, dev) == failure) {
+			hwgraph_vertex_destroy(pciba_devfs_handle);
+			return failure;
+		}
+	}
+
+	return success;
+}
+
+static void __exit
+unregister_with_devfs(void)
+{
+	struct list_head * lhp;
+	struct node_data * nd;
+	
+	TRACE();
+
+	list_for_each(lhp, &global_node_list) {
+		nd = list_entry(lhp, struct node_data, global_node_list);
+		hwgraph_vertex_destroy(nd->devfs_handle);
+	}
+
+}
+
+
+struct node_data * new_node(void)
+{
+	struct node_data * node;
+	
+	TRACE();
+	
+	node = kmalloc(sizeof(struct node_data), GFP_KERNEL);
+	if (node == NULL)
+		return NULL;
+	list_add(&node->global_node_list, &global_node_list);
+	return node;
+}
+
+
+void dma_cleanup(struct node_data * dma_node)
+{
+	TRACE();
+
+	/* FIXME: should free these allocations */
+#ifdef DEBUG_PCIBA
+	dump_allocations(&dma_node->u.dma.dma_allocs);
+#endif
+	hwgraph_vertex_destroy(dma_node->devfs_handle);
+}
+
+
+void init_dma_node(struct node_data * node,
+		   struct pci_dev * dev, vertex_hdl_t dh)
+{
+	TRACE();
+
+	node->devfs_handle = dh;
+	node->u.dma.dev = dev;
+	node->cleanup = dma_cleanup;
+	INIT_LIST_HEAD(&node->u.dma.dma_allocs);
+}
+
+
+void rom_cleanup(struct node_data * rom_node)
+{
+	TRACE();
+
+	if (rom_node->u.rom.mmapped)
+		pci_write_config_dword(rom_node->u.rom.dev,
+				       PCI_ROM_ADDRESS,
+				       rom_node->u.rom.saved_rom_base_reg);
+	hwgraph_vertex_destroy(rom_node->devfs_handle);
+}
+
+
+void init_rom_node(struct node_data * node,
+		   struct pci_dev * dev, vertex_hdl_t dh)
+{
+	TRACE();
+
+	node->devfs_handle = dh;
+	node->u.rom.dev = dev;
+	node->cleanup = rom_cleanup;
+	node->u.rom.mmapped = false;
+}
+
+
+static status __init
+register_pci_device(vertex_hdl_t device_dir_handle, struct pci_dev * dev)
+{
+	struct node_data * nd;
+	char devfs_path[20];
+	vertex_hdl_t node_devfs_handle;
+	int ri;
+
+	TRACE();
+
+
+	/* register nodes for all the device's base address registers */
+	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
+		if (pci_resource_len(dev, ri) != 0) {
+			sprintf(devfs_path, "base/%d", ri);
+			if (hwgraph_register(device_dir_handle, devfs_path,
+					   0, DEVFS_FL_NONE,
+					   0, 0,
+					   S_IFCHR | S_IRUSR | S_IWUSR, 0, 0,
+					   &base_fops, 
+					   &dev->resource[ri]) == NULL)
+				return failure;
+		}
+	}
+	
+	/* register a node corresponding to the first MEM resource on
+           the device */
+	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
+		if (dev->resource[ri].flags & IORESOURCE_MEM &&
+		    pci_resource_len(dev, ri) != 0) {
+			if (hwgraph_register(device_dir_handle, "mem",
+					   0, DEVFS_FL_NONE, 0, 0,
+					   S_IFCHR | S_IRUSR | S_IWUSR, 0, 0,
+					   &base_fops, 
+					   &dev->resource[ri]) == NULL)
+				return failure;
+			break;
+		}
+	}
+
+	/* also register a node corresponding to the first IO resource
+           on the device */
+	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
+		if (dev->resource[ri].flags & IORESOURCE_IO &&
+		    pci_resource_len(dev, ri) != 0) {
+			if (hwgraph_register(device_dir_handle, "io",
+					   0, DEVFS_FL_NONE, 0, 0,
+					   S_IFCHR | S_IRUSR | S_IWUSR, 0, 0,
+					   &base_fops, 
+					   &dev->resource[ri]) == NULL)
+				return failure;
+			break;
+		}
+	}
+
+	/* register a node corresponding to the device's ROM resource,
+           if present */
+	if (pci_resource_len(dev, PCI_ROM_RESOURCE) != 0) {
+		nd = new_node();
+		if (nd == NULL)
+			return failure;
+		node_devfs_handle = hwgraph_register(device_dir_handle, "rom",
+						   0, DEVFS_FL_NONE, 0, 0,
+						   S_IFCHR | S_IRUSR, 0, 0,
+						   &rom_fops, nd);
+		if (node_devfs_handle == NULL)
+			return failure;
+		init_rom_node(nd, dev, node_devfs_handle);
+	}
+
+	/* register a node that allows ioctl's to read and write to
+           the device's config space */
+	if (hwgraph_register(device_dir_handle, "config", 0, DEVFS_FL_NONE,
+			   0, 0, S_IFCHR | S_IRUSR | S_IWUSR, 0, 0,
+			   &config_fops, dev) == NULL)
+		return failure;
+
+
+	/* finally, register a node that allows ioctl's to allocate
+           and free DMA buffers, as well as memory map those
+           buffers. */
+	nd = new_node();
+	if (nd == NULL)
+		return failure;
+	node_devfs_handle =
+		hwgraph_register(device_dir_handle, "dma", 0, DEVFS_FL_NONE,
+			       0, 0, S_IFCHR | S_IRUSR | S_IWUSR, 0, 0,
+			       &dma_fops, nd);
+	if (node_devfs_handle == NULL)
+		return failure;
+	init_dma_node(nd, dev, node_devfs_handle);
+
+#ifdef DEBUG_PCIBA
+	dump_nodes(&global_node_list);
+#endif
+	
+	return success;
+}
+
+
+static int
+generic_open(struct inode * inode, struct file * file)
+{
+	TRACE();
+
+	/* FIXME: should check that they're not trying to open the ROM
+           writable */
+
+	return 0; /* success */
+}
+
+
+static int
+rom_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	unsigned long pci_pa;
+	struct node_data * nd;
+
+	TRACE();
+
+#ifdef CONFIG_HWGFS_FS
+	nd = (struct node_data * )file->f_dentry->d_fsdata;
+#else
+	nd = (struct node_data * )file->private_data;
+#endif
+
+	pci_pa = pci_resource_start(nd->u.rom.dev, PCI_ROM_RESOURCE);
+
+	if (!nd->u.rom.mmapped) {
+		nd->u.rom.mmapped = true;
+		DPRINTF("Enabling ROM address decoder.\n");
+		DPRINTF(
+"rom_mmap: FIXME: some cards do not allow both ROM and memory addresses to\n"
+"rom_mmap: FIXME: be enabled simultaneously, as they share a decoder.\n");
+		pci_read_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
+				      &nd->u.rom.saved_rom_base_reg);
+		DPRINTF("ROM base address contains %x\n",
+			nd->u.rom.saved_rom_base_reg);
+		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
+				       nd->u.rom.saved_rom_base_reg |
+				       PCI_ROM_ADDRESS_ENABLE);
+	}
+	
+	return mmap_pci_address(vma, pci_pa);
+}
+
+
+static int
+rom_release(struct inode * inode, struct file * file)
+{
+	struct node_data * nd;
+
+	TRACE();
+
+#ifdef CONFIG_HWGFS_FS
+	nd = (struct node_data * )file->f_dentry->d_fsdata;
+#else
+	nd = (struct node_data * )file->private_data;
+#endif
+
+	if (nd->u.rom.mmapped) {
+		nd->u.rom.mmapped = false;
+		DPRINTF("Disabling ROM address decoder.\n");
+		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
+				       nd->u.rom.saved_rom_base_reg);
+	}
+	return 0; /* indicate success */
+}
+
+
+static int
+base_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	struct resource * resource;
+
+	TRACE();
+
+#ifdef CONFIG_HWGFS_FS
+	resource = (struct resource *)file->f_dentry->d_fsdata;
+#else
+	resource = (struct resource *)file->private_data;
+#endif
+
+	return mmap_pci_address(vma, resource->start);
+}
+
+
+static int
+config_ioctl(struct inode * inode, struct file * file, 
+	     unsigned int cmd, 
+	     unsigned long arg)
+{
+	struct pci_dev * dev;
+
+	union cfg_data {
+		uint8_t byte;
+		uint16_t word;
+		uint32_t dword;
+	} read_data, write_data;
+
+	int dir, size, offset;
+
+	TRACE();
+
+	DPRINTF("cmd = %x (DIR = %x, TYPE = %x, NR = %x, SIZE = %x)\n", 
+		cmd, 
+		_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
+	DPRINTF("arg = %lx\n", arg);
+
+#ifdef CONFIG_HWGFS_FS
+	dev = (struct pci_dev *)file->f_dentry->d_fsdata;
+#else
+	dev = (struct pci_dev *)file->private_data;
+#endif
+
+	/* PCIIOCCFG{RD,WR}: read and/or write PCI configuration
+	   space. If both, the read happens first (this becomes a swap
+	   operation, atomic with respect to other updates through
+	   this path).  */
+
+	dir = _IOC_DIR(cmd);
+
+#define do_swap(suffix, type)	 					\
+	do {								\
+		if (dir & _IOC_READ) {					\
+			pci_read_config_##suffix(dev, _IOC_NR(cmd), 	\
+						 &read_data.suffix);	\
+		}							\
+		if (dir & _IOC_WRITE) {					\
+			get_user(write_data.suffix, (type)arg);		\
+			pci_write_config_##suffix(dev, _IOC_NR(cmd), 	\
+						  write_data.suffix);	\
+		}							\
+		if (dir & _IOC_READ) {					\
+			put_user(read_data.suffix, (type)arg);		\
+		}							\
+	} while (0)
+
+	size = _IOC_SIZE(cmd);
+	offset = _IOC_NR(cmd);
+
+	DPRINTF("sanity check\n");
+	if (((size > 0) || (size <= 4)) &&
+	    ((offset + size) <= 256) &&
+	    (dir & (_IOC_READ | _IOC_WRITE))) {
+
+		switch (size)
+		{
+		case 1:
+			do_swap(byte, uint8_t *);
+			break;
+		case 2:
+			do_swap(word, uint16_t *);
+			break;
+		case 4:
+			do_swap(dword, uint32_t *);
+			break;
+		default:
+			DPRINTF("invalid ioctl\n");
+			return -EINVAL;
+		}
+	} else
+		return -EINVAL;
+		
+	return 0;
+}
+
+
+#ifdef DEBUG_PCIBA
+static void
+dump_allocations(struct list_head * dalp)
+{
+	struct dma_allocation * dap;
+	struct list_head * p;
+	
+	printk("{\n");
+	list_for_each(p, dalp) {
+		dap = list_entry(p, struct dma_allocation, 
+				 list);
+		printk("  handle = %lx, va = %p\n",
+		       dap->handle, dap->va);
+	}
+	printk("}\n");
+}
+
+static void
+dump_nodes(struct list_head * nodes)
+{
+	struct node_data * ndp;
+	struct list_head * p;
+	
+	printk("{\n");
+	list_for_each(p, nodes) {
+		ndp = list_entry(p, struct node_data, 
+				 global_node_list);
+		printk("  %p\n", (void *)ndp);
+	}
+	printk("}\n");
+}
+
+
+#if 0
+#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
+
+static void
+test_list(void)
+{
+	u64 i;
+	LIST_HEAD(the_list);
+
+	for (i = 0; i < 5; i++) {
+		struct dma_allocation * new_alloc;
+		NEW(new_alloc);
+		new_alloc->va = (void *)i;
+		new_alloc->handle = 5*i;
+		printk("%d - the_list->next = %lx\n", i, the_list.next);
+		list_add(&new_alloc->list, &the_list);
+	}
+	dump_allocations(&the_list);
+}
+#endif
+#endif
+
+
+static LIST_HEAD(dma_buffer_list);
+
+
+static int
+dma_ioctl(struct inode * inode, struct file * file, 
+	  unsigned int cmd, 
+	  unsigned long arg)
+{
+	struct node_data * nd;
+	uint64_t argv;
+	int result;
+	struct dma_allocation * dma_alloc;
+	struct list_head * iterp;
+
+	TRACE();
+
+	DPRINTF("cmd = %x\n", cmd);
+	DPRINTF("arg = %lx\n", arg);
+
+#ifdef CONFIG_HWGFS_FS
+	nd = (struct node_data *)file->f_dentry->d_fsdata;
+#else
+	nd = (struct node_data *)file->private_data;
+#endif
+
+#ifdef DEBUG_PCIBA
+	DPRINTF("at dma_ioctl entry\n");
+	dump_allocations(&nd->u.dma.dma_allocs);
+#endif
+
+	switch (cmd) {
+	case PCIIOCDMAALLOC:
+		/* PCIIOCDMAALLOC: allocate a chunk of physical memory
+		   and set it up for DMA. Return the PCI address that
+		   gets to it.  */
+		DPRINTF("case PCIIOCDMAALLOC (%lx)\n", PCIIOCDMAALLOC);
+		
+		if ( (result = get_user(argv, (uint64_t *)arg)) )
+			return result;
+		DPRINTF("argv (size of buffer) = %lx\n", argv);
+
+		dma_alloc = (struct dma_allocation *)
+			kmalloc(sizeof(struct dma_allocation), GFP_KERNEL);
+		if (dma_alloc == NULL)
+			return -ENOMEM;
+
+		dma_alloc->size = (size_t)argv;
+		dma_alloc->va = pci_alloc_consistent(nd->u.dma.dev,
+						     dma_alloc->size,
+						     &dma_alloc->handle);
+		DPRINTF("dma_alloc->va = %p, dma_alloc->handle = %lx\n",
+			dma_alloc->va, dma_alloc->handle);
+		if (dma_alloc->va == NULL) {
+			kfree(dma_alloc);
+			return -ENOMEM;
+		}
+
+		list_add(&dma_alloc->list, &nd->u.dma.dma_allocs);
+		if ( (result = put_user((uint64_t)dma_alloc->handle, 
+				      (uint64_t *)arg)) ) {
+			DPRINTF("put_user failed\n");
+			pci_free_consistent(nd->u.dma.dev, (size_t)argv,
+					    dma_alloc->va, dma_alloc->handle);
+			kfree(dma_alloc);
+			return result;
+		}
+
+#ifdef DEBUG_PCIBA
+		DPRINTF("after insertion\n");
+		dump_allocations(&nd->u.dma.dma_allocs);
+#endif
+		break;
+
+	case PCIIOCDMAFREE:
+		DPRINTF("case PCIIOCDMAFREE (%lx)\n", PCIIOCDMAFREE);
+
+		if ( (result = get_user(argv, (uint64_t *)arg)) ) {
+			DPRINTF("get_user failed\n");
+			return result;
+		}
+
+		DPRINTF("argv (physical address of DMA buffer) = %lx\n", argv);
+		list_for_each(iterp, &nd->u.dma.dma_allocs) {
+			struct dma_allocation * da =
+				list_entry(iterp, struct dma_allocation, list);
+			if (da->handle == argv) {
+				pci_free_consistent(nd->u.dma.dev, da->size,
+						    da->va, da->handle);
+				list_del(&da->list);
+				kfree(da);
+#ifdef DEBUG_PCIBA
+				DPRINTF("after deletion\n");
+				dump_allocations(&nd->u.dma.dma_allocs);
+#endif
+				return 0; /* success */
+			}
+		}
+		/* previously allocated dma buffer wasn't found */
+		DPRINTF("attempt to free invalid dma handle\n");
+		return -EINVAL;
+
+	default:
+		DPRINTF("undefined ioctl\n");
+		return -EINVAL;
+	}
+
+	DPRINTF("success\n");
+	return 0;
+}
+		
+
+static int
+dma_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	struct node_data * nd;
+	struct list_head * iterp;
+	int result;
+	
+	TRACE();
+
+#ifdef CONFIG_HWGFS_FS
+	nd = (struct node_data *)file->f_dentry->d_fsdata;
+#else
+	nd = (struct node_data *)file->private_data;
+#endif
+	
+	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
+	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
+	DPRINTF("offset = %lx\n", vma->vm_pgoff);
+
+	/* get kernel virtual address for the dma buffer (necessary
+	 * for the mmap). */
+	list_for_each(iterp, &nd->u.dma.dma_allocs) {
+		struct dma_allocation * da =
+			list_entry(iterp, struct dma_allocation, list);
+		/* why does mmap shift its offset argument? */
+		if (da->handle == vma->vm_pgoff << PAGE_SHIFT) {
+			DPRINTF("found dma handle\n");
+			if ( (result = mmap_kernel_address(vma,
+							   da->va)) ) {
+				return result; /* failure */
+			} else {
+				/* it seems like at least one of these
+				   should show up in user land....
+				   I'm missing something */
+				*(char *)da->va = 0xaa;
+				strncpy(da->va, "        Toastie!", da->size);
+				if (put_user(0x18badbeeful,
+					     (u64 *)vma->vm_start))
+					DPRINTF("put_user failed?!\n");
+				return 0; /* success */
+			}
+
+		}
+	}
+	DPRINTF("attempt to mmap an invalid dma handle\n");
+	return -EINVAL;
+}
+
+
+static int
+mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va)
+{
+	unsigned long pci_pa;
+
+	TRACE();
+
+	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
+	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
+
+	/* the size of the vma doesn't necessarily correspond to the
+           size specified in the mmap call.  So we can't really do any
+           kind of sanity check here.  This is a dangerous driver, and
+           it's very easy for a user process to kill the machine.  */
+
+	DPRINTF("PCI base at virtual address %lx\n", pci_va);
+	/* the __pa macro is intended for region 7 on IA64, so it
+	   doesn't work for region 6 */
+  	/* pci_pa = __pa(pci_va); */
+	/* should be replaced by __tpa or equivalent (preferably a
+	   generic equivalent) */
+	pci_pa = pci_va & ~0xe000000000000000ul;
+	DPRINTF("PCI base at physical address %lx\n", pci_pa);
+
+	/* there are various arch-specific versions of this function
+           defined in linux/drivers/char/mem.c, but it would be nice
+           if all architectures put it in pgtable.h.  it's defined
+           there for ia64.... */
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
+
+	return io_remap_page_range(vma->vm_start, pci_pa, 
+				   vma->vm_end-vma->vm_start,
+				   vma->vm_page_prot);
+}
+
+
+static int
+mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va)
+{
+	unsigned long kernel_pa;
+
+	TRACE();
+
+	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
+	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
+
+	/* the size of the vma doesn't necessarily correspond to the
+           size specified in the mmap call.  So we can't really do any
+           kind of sanity check here.  This is a dangerous driver, and
+           it's very easy for a user process to kill the machine.  */
+
+	DPRINTF("mapping virtual address %p\n", kernel_va);
+	kernel_pa = __pa(kernel_va);
+	DPRINTF("mapping physical address %lx\n", kernel_pa);
+
+	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
+
+	return remap_page_range(vma->vm_start, kernel_pa, 
+				vma->vm_end-vma->vm_start,
+				vma->vm_page_prot);
+}	
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/eeprom.c linux-2.4.22-pre3/arch/ia64/sn/io/eeprom.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/eeprom.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/eeprom.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1422 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * WARNING:     There is more than one copy of this file in different isms.
- *              All copies must be kept exactly in sync.
- *              Do not modify this file without also updating the following:
- *
- *              irix/kern/io/eeprom.c
- *              stand/arcs/lib/libsk/ml/eeprom.c
- *		stand/arcs/lib/libkl/io/eeprom.c
- *
- *      (from time to time they might not be in sync but that's due to bringup
- *       activity - this comment is to remind us that they eventually have to
- *       get back together)
- *
- * eeprom.c
- *
- * access to board-mounted EEPROMs via the L1 system controllers
- *
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/simulator.h>
-
-#if defined(EEPROM_DEBUG)
-#define db_printf(x) printk x
-#else
-#define db_printf(x) printk x
-#endif
-
-#define BCOPY(x,y,z)	memcpy(y,x,z)
-
-#define UNDERSCORE	0	/* don't convert underscores to hyphens */
-#define HYPHEN		1	/* convert underscores to hyphens */
-
-void		copy_ascii_field( char *to, char *from, int length,
-			          int change_underscore );
-uint64_t	generate_unique_id( char *sn, int sn_len );
-uchar_t		char_to_base36( char c );
-int		nicify( char *dst, eeprom_brd_record_t *src );
-static void	int64_to_hex_string( char *out, uint64_t val );
-
-// extern int router_lock( net_vec_t, int, int );
-// extern int router_unlock( net_vec_t );
-#define ROUTER_LOCK(p) 	// router_lock(p, 10000, 3000000)
-#define ROUTER_UNLOCK(p) 	// router_unlock(p)
-
-#define IP27LOG_OVNIC           "OverrideNIC"
-
-
-/* the following function converts an EEPROM record to a close facsimile
- * of the string returned by reading a Dallas Semiconductor NIC (see
- * one of the many incarnations of nic.c for details on that driver)
- */
-int nicify( char *dst, eeprom_brd_record_t *src )
-{
-    int field_len;
-    uint64_t unique_id;
-    char *cur_dst = dst;
-    eeprom_board_ia_t   *board;
-
-    board   = src->board_ia;
-    ASSERT( board );  /* there should always be a board info area */
-
-    /* copy part number */
-    strcpy( cur_dst, "Part:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->part_num_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->part_num_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->part_num, field_len, HYPHEN );
-    cur_dst += field_len;
-
-    /* copy product name */
-    strcpy( cur_dst, ";Name:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->product_tl & FIELD_FORMAT_MASK) == FIELD_FORMAT_ASCII );
-    field_len = board->product_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->product, field_len, UNDERSCORE );
-    cur_dst += field_len;
-
-    /* copy serial number */
-    strcpy( cur_dst, ";Serial:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->serial_num_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->serial_num_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->serial_num, field_len,
-		      HYPHEN);
-
-    cur_dst += field_len;
-
-    /* copy revision */
-    strcpy( cur_dst, ";Revision:");
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->board_rev_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->board_rev_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->board_rev, field_len, HYPHEN );
-    cur_dst += field_len;
-
-    /* EEPROMs don't have equivalents for the Group, Capability and
-     * Variety fields, so we pad these with 0's
-     */
-    strcpy( cur_dst, ";Group:ff;Capability:ffffffff;Variety:ff" );
-    cur_dst += strlen( cur_dst );
-
-    /* use the board serial number to "fake" a laser id */
-    strcpy( cur_dst, ";Laser:" );
-    cur_dst += strlen( cur_dst );
-    unique_id = generate_unique_id( board->serial_num,
-				    board->serial_num_tl & FIELD_LENGTH_MASK );
-    int64_to_hex_string( cur_dst, unique_id );
-    strcat( dst, ";" );
-
-    return 1;
-}
-
-
-/* These functions borrow heavily from chars2* in nic.c
- */
-void copy_ascii_field( char *to, char *from, int length,
-		       int change_underscore )
-{
-    int i;
-    for( i = 0; i < length; i++ ) {
-
-	/* change underscores to hyphens if requested */
-	if( from[i] == '_' && change_underscore == HYPHEN )
-	    to[i] = '-';
-
-	/* ; and ; are separators, so mustn't appear within
-	 * a field */
-	else if( from[i] == ':' || from[i] == ';' )
-	    to[i] = '?';
-
-	/* I'm not sure why or if ASCII character 0xff would
-	 * show up in an EEPROM field, but the NIC parsing
-	 * routines wouldn't like it if it did... so we
-	 * get rid of it, just in case. */
-	else if( (unsigned char)from[i] == (unsigned char)0xff )
-	    to[i] = ' ';
-	
-	/* unprintable characters are replaced with . */
-	else if( from[i] < ' ' || from[i] >= 0x7f )
-	    to[i] = '.';
-
-	/* otherwise, just copy the character */
-	else
-	    to[i] = from[i];
-    }
-
-    if( i == 0 ) {
-	to[i] = ' '; /* return at least a space... */
-	i++;
-    }
-    to[i] = 0;	     /* terminating null */
-}
-
-/* Note that int64_to_hex_string currently only has a big-endian
- * implementation.
- */
-#ifdef _MIPSEB
-static void int64_to_hex_string( char *out, uint64_t val )
-{
-    int i;
-    uchar_t table[] = "0123456789abcdef";
-    uchar_t *byte_ptr = (uchar_t *)&val;
-    for( i = 0; i < sizeof(uint64_t); i++ ) {
-	out[i*2] = table[ ((*byte_ptr) >> 4) & 0x0f ];
-	out[i*2+1] = table[ (*byte_ptr) & 0x0f ];
-	byte_ptr++;
-    }
-    out[i*2] = '\0';
-}
-
-#else /* little endian */
-
-static void int64_to_hex_string( char *out, uint64_t val )
-{
-
-
-	printk("int64_to_hex_string needs a little-endian implementation.\n");
-}
-#endif /* _MIPSEB */
-
-/* Convert a standard ASCII serial number to a unique integer
- * id number by treating the serial number string as though
- * it were a base 36 number
- */
-uint64_t generate_unique_id( char *sn, int sn_len )
-{
-    int uid = 0;
-    int i;
-
-    #define VALID_BASE36(c)	((c >= '0' && c <='9') \
-			    ||   (c >= 'A' && c <='Z') \
-			    ||   (c >= 'a' && c <='z'))
-
-    for( i = 0; i < sn_len; i++ ) {
-	if( !VALID_BASE36(sn[i]) )
-	    continue;
-	uid *= 36;
-	uid += char_to_base36( sn[i] );
-    }
-
-    if( uid == 0 )
-	return rtc_time();
-
-    return uid;
-}
-
-uchar_t char_to_base36( char c )
-{
-    uchar_t val;
-
-    if( c >= '0' && c <= '9' )
-	val = (c - '0');
-
-    else if( c >= 'A' && c <= 'Z' )
-	val = (c - 'A' + 10);
-
-    else if( c >= 'a' && c <= 'z' )
-	val = (c - 'a' + 10);
-
-    else val = 0;
-
-    return val;
-}
-
-
-/* given a pointer to the three-byte little-endian EEPROM representation
- * of date-of-manufacture, this function translates to a big-endian
- * integer format
- */
-int eeprom_xlate_board_mfr_date( uchar_t *src )
-{
-    int rval = 0;
-    rval += *src; src++;
-    rval += ((int)(*src) << 8); src ++;
-    rval += ((int)(*src) << 16);
-    return rval;
-}
-
-
-int eeprom_str( char *nic_str, nasid_t nasid, int component )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    if( (component & C_DIMM) == C_DIMM ) {
-	/* this function isn't applicable to DIMMs */
-	return EEP_PARAM;
-    }
-    else {
-	eep.board_ia = &board;
-	eep.spd = NULL;
-	if( !(component & SUBORD_MASK) )
-	    eep.chassis_ia = &chassis;  /* only main boards have a chassis
-					 * info area */
-	else
-	    eep.chassis_ia = NULL;
-    }
-    
-    switch( component & BRICK_MASK ) {
-      case C_BRICK:
-	r = cbrick_eeprom_read( &eep, nasid, component );
-	break;
-      case IO_BRICK:
-	r = iobrick_eeprom_read( &eep, nasid, component );
-	break;
-      default:
-	return EEP_PARAM;  /* must be an invalid component */
-    }
-    if( r )
-	return r;
-    if( !nicify( nic_str, &eep ) )
-	return EEP_NICIFY;
-
-    return EEP_OK;
-}
-
-int vector_eeprom_str( char *nic_str, nasid_t nasid,
-		       int component, net_vec_t path )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    eep.board_ia = &board;
-    if( !(component & SUBORD_MASK) )
-        eep.chassis_ia = &chassis;  /* only main boards have a chassis
-                                     * info area */
-    else
-        eep.chassis_ia = NULL;
-
-    if( !(component & VECTOR) )
-	return EEP_PARAM;
-
-    if( (r = vector_eeprom_read( &eep, nasid, path, component )) )
-	return r;
-
-    if( !nicify( nic_str, &eep ) )
-        return EEP_NICIFY;
-
-    return EEP_OK;
-}
-
-
-int is_iobrick( int nasid, int widget_num )
-{
-    uint32_t wid_reg;
-    int part_num, mfg_num;
-
-    /* Read the widget's WIDGET_ID register to get
-     * its part number and mfg number
-     */
-    wid_reg = *(volatile int32_t *)
-        (NODE_SWIN_BASE( nasid, widget_num ) + WIDGET_ID);
-
-    part_num = (wid_reg & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT;
-    mfg_num = (wid_reg & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT;
-
-    /* Is this the "xbow part" of an XBridge?  If so, this
-     * widget is definitely part of an I/O brick.
-     */
-    if( part_num == XXBOW_WIDGET_PART_NUM &&
-	mfg_num == XXBOW_WIDGET_MFGR_NUM )
-
-	return 1;
-
-    /* Is this a "bridge part" of an XBridge?  If so, once
-     * again, we know this widget is part of an I/O brick.
-     */
-    if( part_num == XBRIDGE_WIDGET_PART_NUM &&
-	mfg_num == XBRIDGE_WIDGET_MFGR_NUM )
-
-	return 1;
-
-    return 0;
-}
-
-
-int cbrick_uid_get( nasid_t nasid, uint64_t *uid )
-{
-    char uid_str[32];
-    char msg[BRL1_QSIZE];
-    int subch, len;
-    l1sc_t sc;
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* If the promlog variable pointed to by IP27LOG_OVNIC is set,
-     * use that value for the cbrick UID rather than the EEPROM
-     * serial number.
-     */
-#ifdef LOG_GETENV
-    if( ip27log_getenv( nasid, IP27LOG_OVNIC, uid_str, NULL, 0 ) >= 0 )
-    {
-	/* We successfully read IP27LOG_OVNIC, so return it as the UID. */
-	db_printf(( "cbrick_uid_get:"
-		    "Overriding UID with environment variable %s\n", 
-		    IP27LOG_OVNIC ));
-	*uid = strtoull( uid_str, NULL, 0 );
-	return EEP_OK;
-    }
-#endif
-
-    /* If this brick is retrieving its own uid, use the local l1sc_t to
-     * arbitrate access to the l1; otherwise, set up a new one.
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &sc;
-	sc_init( &sc, nasid, BRL1_LOCALHUB_UART );
-    }
-
-    /* fill in msg with the opcode & params */
-    BZERO( msg, BRL1_QSIZE );
-    if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 )
-	return EEP_L1;
-
-    if( (len = sc_construct_msg( scp, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SER_NUM, 0 )) < 0 )
-    {
-	sc_close( scp, subch );
-	return( EEP_L1 );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( scp, subch, msg, msg, &len ) ) {
-	sc_close( scp, subch );
-	return( EEP_L1 );
-    }
-
-    /* free up subchannel */
-    sc_close(scp, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 )
-    {
-	return( EEP_L1 );
-    }
-
-    *uid = generate_unique_id( uid_str, strlen( uid_str ) );
-
-    return EEP_OK;
-}
-
-
-int rbrick_uid_get( nasid_t nasid, net_vec_t path, uint64_t *uid )
-{
-    char uid_str[32];
-    char msg[BRL1_QSIZE];
-    int subch, len;
-    l1sc_t sc;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-#define FAIL								\
-    {									\
-	*uid = rtc_time();						\
-	printk( "rbrick_uid_get failed; using current time as uid\n" );	\
-	return EEP_OK;							\
-    }
-
-    ROUTER_LOCK(path);
-    sc_init( &sc, nasid, path );
-
-    /* fill in msg with the opcode & params */
-    BZERO( msg, BRL1_QSIZE );
-    if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) {
-	ROUTER_UNLOCK(path);
-	FAIL;
-    }
-
-    if( (len = sc_construct_msg( &sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SER_NUM, 0 )) < 0 )
-    {
-	ROUTER_UNLOCK(path);
-	sc_close( &sc, subch );
-	FAIL;
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( &sc, subch, msg, msg, &len ) ) {
-	ROUTER_UNLOCK(path);
-	sc_close( &sc, subch );
-	FAIL;
-    }
-
-    /* free up subchannel */
-    ROUTER_UNLOCK(path);
-    sc_close(&sc, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 )
-    {
-	FAIL;
-    }
-
-    *uid = generate_unique_id( uid_str, strlen( uid_str ) );
-
-    return EEP_OK;
-}
-
-int iobrick_uid_get( nasid_t nasid, uint64_t *uid )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    eep.board_ia = &board;
-    eep.chassis_ia = &chassis;
-    eep.spd = NULL;
-
-    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );
-    if( r != EEP_OK ) {
-        *uid = rtc_time();
-        return r;
-    }
-
-    *uid = generate_unique_id( board.serial_num,
-                               board.serial_num_tl & FIELD_LENGTH_MASK );
-
-    return EEP_OK;
-}
-
-
-int ibrick_mac_addr_get( nasid_t nasid, char *eaddr )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-    char *tmp;
-
-    eep.board_ia = &board;
-    eep.chassis_ia = &chassis;
-    eep.spd = NULL;
-
-    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );
-    if( (r != EEP_OK) || (board.mac_addr[0] == '\0') ) {
-	db_printf(( "ibrick_mac_addr_get: "
-		    "Couldn't read MAC address from EEPROM\n" ));
-	return EEP_L1;
-    }
-    else {
-	/* successfully read info area */
-	int ix;
-	tmp = board.mac_addr;
-	for( ix = 0; ix < (board.mac_addr_tl & FIELD_LENGTH_MASK); ix++ )
-	{
-	    *eaddr++ = *tmp++;
-	}
-	*eaddr = '\0';
-    }
-
-    return EEP_OK;
-}
-
-
-/* 
- * eeprom_vertex_info_set
- *
- * Given a vertex handle, a component designation, a starting nasid
- * and (in the case of a router) a vector path to the component, this
- * function will read the EEPROM and attach the resulting information
- * to the vertex in the same string format as that provided by the
- * Dallas Semiconductor NIC drivers.  If the vertex already has the
- * string, this function just returns the string.
- */
-
-extern char *nic_vertex_info_get( devfs_handle_t );
-extern void nic_vmc_check( devfs_handle_t, char * );
-/* the following were lifted from nic.c - change later? */
-#define MAX_INFO 2048
-#define NEWSZ(ptr,sz)   ((ptr) = kern_malloc((sz)))
-#define DEL(ptr) (kern_free((ptr)))
-
-char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v,
-                              net_vec_t path )
-{
-        char *info_tmp;
-        int info_len;
-        char *info;
-
-        /* see if this vertex is already marked */
-        info_tmp = nic_vertex_info_get(v);
-        if (info_tmp) return info_tmp;
-
-        /* get a temporary place for the data */
-        NEWSZ(info_tmp, MAX_INFO);
-        if (!info_tmp) return NULL;
-
-        /* read the EEPROM */
-	if( component & R_BRICK ) {
-	    if( RBRICK_EEPROM_STR( info_tmp, nasid, path ) != EEP_OK )
-		return NULL;
-	}
-	else {
-            if( eeprom_str( info_tmp, nasid, component ) != EEP_OK )
-	        return NULL;
-	}
-
-        /* allocate a smaller final place */
-        info_len = strlen(info_tmp)+1;
-        NEWSZ(info, info_len);
-        if (info) {
-                strcpy(info, info_tmp);
-                DEL(info_tmp);
-        } else {
-                info = info_tmp;
-        }
-
-        /* add info to the vertex */
-        hwgraph_info_add_LBL(v, INFO_LBL_NIC,
-                             (arbitrary_info_t) info);
-
-        /* see if someone else got there first */
-        info_tmp = nic_vertex_info_get(v);
-        if (info != info_tmp) {
-            DEL(info);
-            return info_tmp;
-        }
-
-        /* export the data */
-        hwgraph_info_export_LBL(v, INFO_LBL_NIC, info_len);
-
-        /* trigger all matching callbacks */
-        nic_vmc_check(v, info);
-
-        return info;
-}
-
-
-/*********************************************************************
- *
- * stubs for use until the Bedrock/L1 link is available
- *
- */
-
-#include <asm/sn/nic.h>
-
-/* #define EEPROM_TEST */
-
-/* fake eeprom reading functions (replace when the BR/L1 communication
- * channel is in working order)
- */
-
-
-/* generate a charater in [0-9A-Z]; if an "extra" character is
- * specified (such as '_'), include it as one of the possibilities.
- */
-char random_eeprom_ch( char extra ) 
-{
-    char ch;
-    int modval = 36;
-    if( extra )
-	modval++;
-    
-    ch = rtc_time() % modval;
-
-    if( ch < 10 )
-        ch += '0';
-    else if( ch >= 10 && ch < 36 )
-	ch += ('A' - 10);
-    else
-	ch = extra;
-
-    return ch;
-}
-
-/* create a part number of the form xxx-xxxx-xxx.
- * It may be important later to generate different
- * part numbers depending on the component we're
- * supposed to be "reading" from, so the component
- * paramter is provided.
- */
-void fake_a_part_number( char *buf, int component )
-{
-    int i;
-    switch( component ) {
-
-    /* insert component-specific routines here */
-
-    case C_BRICK:
-	strcpy( buf, "030-1266-001" );
-	break;
-    default:
-        for( i = 0; i < 12; i++ ) {
-	    if( i == 3 || i == 8 )
-	        buf[i] = '-';
-	    else
-	        buf[i] = random_eeprom_ch(0);
-        }
-    }
-}
-
-
-/* create a six-character serial number */
-void fake_a_serial_number( char *buf, uint64_t ser )
-{
-    int i;
-    static const char hexchars[] = "0123456789ABCDEF";
-
-    if (ser) {
-	for( i = 5; i >=0; i-- ) {
-	    buf[i] = hexchars[ser & 0xf];
-	    ser >>= 4;
-	}
-    }
-    else {
-	for( i = 0; i < 6; i++ )
-	    buf[i] = random_eeprom_ch(0);
-    }
-}
-
-
-void fake_a_product_name( uchar_t *format, char* buf, int component )
-{
-    switch( component & BRICK_MASK ) {
-
-    case C_BRICK:
-	if( component & SUBORD_MASK ) {
-	    strcpy( buf, "C_BRICK_SUB" );
-	    *format = 0xCB;
-	}
-	else {
-	    strcpy( buf, "IP35" );
-	    *format = 0xC4;
-	}
-	break;
-
-    case R_BRICK:
-        if( component & SUBORD_MASK ) {
-            strcpy( buf, "R_BRICK_SUB" );
-            *format = 0xCB;
-        }
-        else {
-            strcpy( buf, "R_BRICK" );
-            *format = 0xC7;
-        }
-        break;
-
-    case IO_BRICK:
-        if( component & SUBORD_MASK ) {
-            strcpy( buf, "IO_BRICK_SUB" );
-            *format = 0xCC;
-        }
-        else {
-            strcpy( buf, "IO_BRICK" );
-            *format = 0xC8;
-        }
-        break;
-
-    default:
-	strcpy( buf, "UNK_DEVICE" );
-	*format = 0xCA;
-    }
-}
-
-
-
-int fake_an_eeprom_record( eeprom_brd_record_t *buf, int component, 
-			   uint64_t ser )
-{
-    eeprom_board_ia_t *board;
-    eeprom_chassis_ia_t *chassis;
-    int i, cs;
-
-    board = buf->board_ia;
-    chassis = buf->chassis_ia;
-
-    if( !(component & SUBORD_MASK) ) {
-	if( !chassis )
-	    return EEP_PARAM;
-	chassis->format = 0;
-	chassis->length = 5;
-	chassis->type = 0x17;
-
-	chassis->part_num_tl = 0xCC;
-	fake_a_part_number( chassis->part_num, component );
-	chassis->serial_num_tl = 0xC6;
-	fake_a_serial_number( chassis->serial_num, ser );
-
-	cs = chassis->format + chassis->length + chassis->type
-	    + chassis->part_num_tl + chassis->serial_num_tl;
-	for( i = 0; i < (chassis->part_num_tl & FIELD_LENGTH_MASK); i++ )
-	    cs += chassis->part_num[i];
-	for( i = 0; i < (chassis->serial_num_tl & FIELD_LENGTH_MASK); i++ )
-	    cs += chassis->serial_num[i];
-	chassis->checksum = 256 - (cs % 256);
-    }
-
-    if( !board )
-	return EEP_PARAM;
-    board->format = 0;
-    board->length = 10;
-    board->language = 0;
-    board->mfg_date = 1789200; /* noon, 5/26/99 */
-    board->manuf_tl = 0xC3;
-    strcpy( board->manuf, "SGI" );
-
-    fake_a_product_name( &(board->product_tl), board->product, component );
-
-    board->serial_num_tl = 0xC6;
-    fake_a_serial_number( board->serial_num, ser );
-
-    board->part_num_tl = 0xCC;
-    fake_a_part_number( board->part_num, component );
-
-    board->board_rev_tl = 0xC2;
-    board->board_rev[0] = '0';
-    board->board_rev[1] = '1';
-
-    board->eeprom_size_tl = 0x01;
-    board->eeprom_size = 1;
-
-    board->temp_waiver_tl = 0xC2;
-    board->temp_waiver[0] = '0';
-    board->temp_waiver[1] = '1';
-
-    cs = board->format + board->length + board->language
-	+ (board->mfg_date & 0xFF)
-	+ (board->mfg_date & 0xFF00)
-	+ (board->mfg_date & 0xFF0000)
-	+ board->manuf_tl + board->product_tl + board->serial_num_tl
-	+ board->part_num_tl + board->board_rev_tl
-	+ board->board_rev[0] + board->board_rev[1]
-	+ board->eeprom_size_tl + board->eeprom_size + board->temp_waiver_tl
-	+ board->temp_waiver[0] + board->temp_waiver[1];
-    for( i = 0; i < (board->manuf_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->manuf[i];
-    for( i = 0; i < (board->product_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->product[i];
-    for( i = 0; i < (board->serial_num_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->serial_num[i];
-    for( i = 0; i < (board->part_num_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->part_num[i];
-    
-    board->checksum = 256 - (cs % 256);
-
-    return EEP_OK;
-}
-
-#define EEPROM_CHUNKSIZE	64
-
-#if defined(EEPROM_DEBUG)
-#define RETURN_ERROR							\
-{									\
-    printk( "read_ia error return, component 0x%x, line %d"		\
-	    ", address 0x%x, ia code 0x%x\n",				\
-	    l1_compt, __LINE__, sc->subch[subch].target, ia_code );	\
-    return EEP_L1;							\
-}
-
-#else
-#define RETURN_ERROR	return(EEP_L1)
-#endif
-
-int read_ia( l1sc_t *sc, int subch, int l1_compt, 
-	     int ia_code, char *eep_record )
-{
-    char msg[BRL1_QSIZE]; 	   /* message buffer */
-    int len;              	   /* number of bytes used in message buffer */
-    int ia_len = EEPROM_CHUNKSIZE; /* remaining bytes in info area */
-    int offset = 0;                /* current offset into info area */
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    BZERO( msg, BRL1_QSIZE );
-
-    /* retrieve EEPROM data in 64-byte chunks
-     */
-
-    while( ia_len )
-    {
-	/* fill in msg with opcode & params */
-	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				     L1_ADDR_TASK_GENERAL,
-				     L1_REQ_EEPROM, 8,
-				     L1_ARG_INT, l1_compt,
-				     L1_ARG_INT, ia_code,
-				     L1_ARG_INT, offset,
-				     L1_ARG_INT, ia_len )) < 0 )
-	{
-	    RETURN_ERROR;
-	}
-
-	/* send the request to the L1 */
-
-	if( sc_command( sc, subch, msg, msg, &len ) ) {
-	    RETURN_ERROR;
-	}
-
-	/* check response */
-	if( sc_interpret_resp( msg, 5, 
-			       L1_ARG_INT, &ia_len,
-			       L1_ARG_UNKNOWN, &len, eep_record ) < 0 )
-	{
-	    RETURN_ERROR;
-	}
-
-	if( ia_len > EEPROM_CHUNKSIZE )
-	    ia_len = EEPROM_CHUNKSIZE;
-
-	eep_record += EEPROM_CHUNKSIZE;
-	offset += EEPROM_CHUNKSIZE;
-    }
-
-    return EEP_OK;
-}
-
-
-int read_spd( l1sc_t *sc, int subch, int l1_compt,
-	      eeprom_spd_u *spd )
-{
-    char msg[BRL1_QSIZE]; 	    /* message buffer */
-    int len;              	    /* number of bytes used in message buffer */
-    int resp;                       /* l1 response code */
-    int spd_len = EEPROM_CHUNKSIZE; /* remaining bytes in spd record */
-    int offset = 0;		    /* current offset into spd record */
-    char *spd_p = spd->bytes;	    /* "thumb" for writing to spd */
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    BZERO( msg, BRL1_QSIZE );
-
-    /* retrieve EEPROM data in 64-byte chunks
-     */
-
-    while( spd_len )
-    {
-	/* fill in msg with opcode & params */
-	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				     L1_ADDR_TASK_GENERAL,
-				     L1_REQ_EEPROM, 8,
-				     L1_ARG_INT, l1_compt,
-				     L1_ARG_INT, L1_EEP_SPD,
-				     L1_ARG_INT, offset,
-				     L1_ARG_INT, spd_len )) < 0 )
-	{
-	    return( EEP_L1 );
-	}
-
-	/* send the request to the L1 */
-	if( sc_command( sc, subch, msg, msg, &len ) ) {
-	    return( EEP_L1 );
-	}
-
-	/* check response */
-	if( (resp = sc_interpret_resp( msg, 5, 
-			       L1_ARG_INT, &spd_len,
-			       L1_ARG_UNKNOWN, &len, spd_p )) < 0 )
-	{
-            /*
-             * translate l1 response code to eeprom.c error codes:
-             * The L1 response will be L1_RESP_NAVAIL if the spd
-             * can't be read (i.e. the spd isn't physically there). It will
-             * return L1_RESP_INVAL if the spd exists, but fails the checksum
-             * test because the eeprom wasn't programmed, programmed incorrectly,
-             * or corrupted. L1_RESP_NAVAIL indicates the eeprom is likely not present,
-             * whereas L1_RESP_INVAL indicates the eeprom is present, but the data is
-             * invalid.
-             */
-            if(resp == L1_RESP_INVAL) {
-                resp = EEP_BAD_CHECKSUM;
-            } else {
-                resp = EEP_L1;
-            }
-            return( resp );
-	}
-
-	if( spd_len > EEPROM_CHUNKSIZE )
-	    spd_len = EEPROM_CHUNKSIZE;
-
-	spd_p += EEPROM_CHUNKSIZE;
-	offset += EEPROM_CHUNKSIZE;
-    }
-    return EEP_OK;
-}
-
-
-int read_chassis_ia( l1sc_t *sc, int subch, int l1_compt,
-		     eeprom_chassis_ia_t *ia )
-{
-    char eep_record[512];          /* scratch area for building up info area */
-    char *eep_rec_p = eep_record;  /* thumb for moving through eep_record */
-    int checksum = 0;              /* use to verify eeprom record checksum */
-    int i;
-
-    /* Read in info area record from the L1.
-     */
-    if( read_ia( sc, subch, l1_compt, L1_EEP_CHASSIS, eep_record )
-	!= EEP_OK )
-    {
-	return EEP_L1;
-    }
-
-    /* Now we've got the whole info area.  Transfer it to the data structure.
-     */
-
-    eep_rec_p = eep_record;
-    ia->format = *eep_rec_p++;
-    ia->length = *eep_rec_p++;
-    if( ia->length == 0 ) {
-	/* since we're using 8*ia->length-1 as an array index later, make
-	 * sure it's sane.
-	 */
-	db_printf(( "read_chassis_ia: eeprom length byte of ZERO\n" ));
-	return EEP_L1;
-    }
-    ia->type = *eep_rec_p++;
-   
-    ia->part_num_tl = *eep_rec_p++;
-
-    (void)BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK);
-
-    ia->serial_num_tl = *eep_rec_p++;
-
-    BCOPY( eep_rec_p, ia->serial_num, 
-	   (ia->serial_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK);
-
-    ia->checksum = eep_record[(8 * ia->length) - 1];
-
-    /* verify checksum */
-    eep_rec_p = eep_record;
-    checksum = 0;
-    for( i = 0; i < (8 * ia->length); i++ ) {
-	checksum += *eep_rec_p++;
-    }
-
-    if( (checksum & 0xff) != 0 )
-    {
-	db_printf(( "read_chassis_ia: bad checksum\n" ));
-	db_printf(( "read_chassis_ia: target 0x%x  uart 0x%lx\n",
-			   sc->subch[subch].target, sc->uart ));
-	return EEP_BAD_CHECKSUM;
-    }
-
-    return EEP_OK;
-}
-
-
-int read_board_ia( l1sc_t *sc, int subch, int l1_compt,
-		   eeprom_board_ia_t *ia )
-{
-    char eep_record[512];          /* scratch area for building up info area */
-    char *eep_rec_p = eep_record;  /* thumb for moving through eep_record */
-    int checksum = 0;              /* running checksum total */
-    int i;
-
-    BZERO( ia, sizeof( eeprom_board_ia_t ) );
-
-    /* Read in info area record from the L1.
-     */
-    if( read_ia( sc, subch, l1_compt, L1_EEP_BOARD, eep_record )
-	!= EEP_OK )
-    {
-	db_printf(( "read_board_ia: error reading info area from L1\n" ));
-	return EEP_L1;
-    }
-
-     /* Now we've got the whole info area.  Transfer it to the data structure.
-      */
-
-    eep_rec_p = eep_record;
-    ia->format = *eep_rec_p++;
-    ia->length = *eep_rec_p++;
-    if( ia->length == 0 ) {
-	/* since we're using 8*ia->length-1 as an array index later, make
-	 * sure it's sane.
-	 */
-	db_printf(( "read_board_ia: eeprom length byte of ZERO\n" ));
-	return EEP_L1;
-    }
-    ia->language = *eep_rec_p++;
-    
-    ia->mfg_date = eeprom_xlate_board_mfr_date( (uchar_t *)eep_rec_p );
-    eep_rec_p += 3;
-
-    ia->manuf_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->manuf, (ia->manuf_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->manuf_tl & FIELD_LENGTH_MASK);
-
-    ia->product_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->product, (ia->product_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->product_tl & FIELD_LENGTH_MASK);
-
-    ia->serial_num_tl = *eep_rec_p++;
-    
-    BCOPY(eep_rec_p, ia->serial_num, (ia->serial_num_tl & FIELD_LENGTH_MASK));
-    eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK);
-
-    ia->part_num_tl = *eep_rec_p++;
-
-    BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK);
-
-    eep_rec_p++; /* we do not use the FRU file id */
-    
-    ia->board_rev_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->board_rev, (ia->board_rev_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->board_rev_tl & FIELD_LENGTH_MASK);
-
-    ia->eeprom_size_tl = *eep_rec_p++;
-    ia->eeprom_size = *eep_rec_p++;
-
-    ia->temp_waiver_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->temp_waiver, 
-	   (ia->temp_waiver_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->temp_waiver_tl & FIELD_LENGTH_MASK);
-
-    /* if there's more, we must be reading a main board; get
-     * additional fields
-     */
-    if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) {
-
-	ia->ekey_G_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_G, 
-	       ia->ekey_G_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_G_tl & FIELD_LENGTH_MASK);
-	
-	ia->ekey_P_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_P, 
-	       ia->ekey_P_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_P_tl & FIELD_LENGTH_MASK);
-	
-	ia->ekey_Y_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_Y, 
-	       ia->ekey_Y_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_Y_tl & FIELD_LENGTH_MASK);
-	
-	/* 
-	 * need to get a couple more fields if this is an I brick 
-	 */
-	if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) {
-
-	    ia->mac_addr_tl = *eep_rec_p++;
-	    BCOPY( eep_rec_p, ia->mac_addr, 
-		   ia->mac_addr_tl & FIELD_LENGTH_MASK );
-	    eep_rec_p += (ia->mac_addr_tl & FIELD_LENGTH_MASK);
-	    
-	    ia->ieee1394_cfg_tl = *eep_rec_p++;
-	    BCOPY( eep_rec_p, ia->ieee1394_cfg,
-		   ia->ieee1394_cfg_tl & FIELD_LENGTH_MASK );
-	    
-	}
-    }
-
-    ia->checksum = eep_record[(ia->length * 8) - 1];
-
-    /* verify checksum */
-    eep_rec_p = eep_record;
-    checksum = 0;
-    for( i = 0; i < (8 * ia->length); i++ ) {
-	checksum += *eep_rec_p++;
-    }
-
-    if( (checksum & 0xff) != 0 )
-    {
-	db_printf(( "read_board_ia: bad checksum\n" ));
-	db_printf(( "read_board_ia: target 0x%x  uart 0x%lx\n",
-		    sc->subch[subch].target, sc->uart ));
-	return EEP_BAD_CHECKSUM;
-    }
-
-    return EEP_OK;
-}
-
-
-int _cbrick_eeprom_read( eeprom_brd_record_t *buf, l1sc_t *scp,
-			 int component )
-{
-    int r;
-    uint64_t uid = 0;
-#ifdef LOG_GETENV
-    char uid_str[32];
-#endif
-    int l1_compt, subch;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're targeting a cbrick */
-    if( !(component & C_BRICK) )
-	return EEP_PARAM;
-
-    /* If the promlog variable pointed to by IP27LOG_OVNIC is set,
-     * use that value for the cbrick UID rather than the EEPROM
-     * serial number.
-     */
-#ifdef LOG_GETENV
-    if( ip27log_getenv( scp->nasid, IP27LOG_OVNIC, uid_str, "0", 0 ) >= 0 )
-    {
-	db_printf(( "_cbrick_eeprom_read: "
-		    "Overriding UID with environment variable %s\n", 
-		    IP27LOG_OVNIC ));
-	uid = strtoull( uid_str, NULL, 0 );
-    }
-#endif
-
-    if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 )
-	return EEP_L1;
-
-    if((component & C_DIMM) == C_DIMM) {
-        l1_compt = L1_EEP_DIMM(component & COMPT_MASK);
-        r = read_spd(scp,subch,l1_compt, buf->spd);
-        sc_close(scp,subch);
-        return(r);
-    }
-
-    switch( component )
-    {
-      case C_BRICK:
-	/* c-brick motherboard */
-	l1_compt = L1_EEP_NODE;
-	r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia );
-	if( r != EEP_OK ) {
-	    sc_close( scp, subch );
-	    db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" ));
-	    return fake_an_eeprom_record( buf, component, uid );
-	}
-	if( uid ) {
-	    /* If IP27LOG_OVNIC is set, we want to put that value
-	     * in as our UID. */
-	    fake_a_serial_number( buf->chassis_ia->serial_num, uid );
-	    buf->chassis_ia->serial_num_tl = 6;
-	}
-	break;
-
-      case C_PIMM:
-	/* one of the PIMM boards */
-	l1_compt = L1_EEP_PIMM( component & COMPT_MASK );
-	break;
-
-      default:
-	/* unsupported board type */
-	sc_close( scp, subch );
-	return EEP_PARAM;
-    }
-	      
-    r = read_board_ia( scp, subch, l1_compt, buf->board_ia );
-    sc_close( scp, subch );
-    if( r != EEP_OK ) 
-    {
-	db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" ));
-	return fake_an_eeprom_record( buf, component, uid );
-    }
-    return EEP_OK;
-}
-
-
-int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-    		        int component )
-{
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* If this brick is retrieving its own uid, use the local l1sc_t to
-     * arbitrate access to the l1; otherwise, set up a new one (prom) or
-     * use an existing remote l1sc_t (kernel)
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    }
-
-    return _cbrick_eeprom_read( buf, scp, component );
-}
-
-
-int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			 int component )
-{
-    int r;
-    int l1_compt, subch;
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're talking to an applicable brick */
-    if( !(component & IO_BRICK) ) {
-	return EEP_PARAM;
-    }
-
-    /* If we're talking to this c-brick's attached io brick, use
-     * the local l1sc_t; otherwise, set up a new one (prom) or
-     * use an existing remote l1sc_t (kernel)
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    }
-
-    if( (subch = sc_open( scp, L1_ADDR_LOCALIO )) < 0 )
-	return EEP_L1;
-
-
-    switch( component )
-    {
-      case IO_BRICK:
-	/* IO brick motherboard */
-	l1_compt = L1_EEP_LOGIC;
-	r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia );
-
-	if( r != EEP_OK ) {
-	    sc_close( scp, subch );
-	/*
-	 * Whenever we no longer need to test on hardware
-	 * that does not have EEPROMS, then this can be removed.
-	 */
-	    r = fake_an_eeprom_record( buf, component, rtc_time() );
-	    return r;
-	}
-	break;
-
-      case IO_POWER:
-	/* IO brick power board */
-	l1_compt = L1_EEP_POWER;
-	break;
-
-      default:
-	/* unsupported board type */
-	sc_close( scp, subch );
-	return EEP_PARAM;
-    }
-
-    r = read_board_ia( scp, subch, l1_compt, buf->board_ia );
-    sc_close( scp, subch );
-    if( r != EEP_OK ) {
-	return r;
-    }
-    return EEP_OK;
-}
-
-
-int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			net_vec_t path, int component )
-{
-    int r;
-    uint64_t uid = 0;
-    int l1_compt, subch;
-    l1sc_t sc;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're targeting an applicable brick */
-    if( !(component & VECTOR) )
-	return EEP_PARAM;
-
-    switch( component & BRICK_MASK )
-    {
-      case R_BRICK:
-	ROUTER_LOCK( path );
-	sc_init( &sc, nasid, path );
-
-	if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 )
-	{
-	    db_printf(( "vector_eeprom_read: couldn't open subch\n" ));
-	    ROUTER_UNLOCK(path);
-	    return EEP_L1;
-	}
-	switch( component )
-	{
-	  case R_BRICK:
-	    /* r-brick motherboard */
-	    l1_compt = L1_EEP_LOGIC;
-    	    r = read_chassis_ia( &sc, subch, l1_compt, buf->chassis_ia );
-	    if( r != EEP_OK ) {
-		sc_close( &sc, subch );
-		ROUTER_UNLOCK( path );
-		printk( "vector_eeprom_read: couldn't get rbrick eeprom info;"
-			" using current time as uid\n" );
-		uid = rtc_time();
-		db_printf(("vector_eeprom_read: using a fake eeprom record\n"));
-		return fake_an_eeprom_record( buf, component, uid );
-	    }
-	    break;
-
-	  case R_POWER:
-	    /* r-brick power board */
-	    l1_compt = L1_EEP_POWER;
-	    break;
-
-	  default:
-	    /* unsupported board type */
-	    sc_close( &sc, subch );
-	    ROUTER_UNLOCK( path );
-	    return EEP_PARAM;
-	}
-	r = read_board_ia( &sc, subch, l1_compt, buf->board_ia );
-	sc_close( &sc, subch );
-	ROUTER_UNLOCK( path );
-	if( r != EEP_OK ) {
-	    db_printf(( "vector_eeprom_read: using a fake eeprom record\n" ));
-	    return fake_an_eeprom_record( buf, component, uid );
-	}
-	return EEP_OK;
-
-      case C_BRICK:
-	sc_init( &sc, nasid, path );
-	return _cbrick_eeprom_read( buf, &sc, component );
-
-      default:
-	/* unsupported brick type */
-	return EEP_PARAM;
-    }
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/efi-rtc.c linux-2.4.22-pre3/arch/ia64/sn/io/efi-rtc.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/efi-rtc.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/efi-rtc.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,185 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 Silicon Graphics, Inc.
- * Copyright (C) 2001 by Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/efi.h>
-#include <asm/sn/klclock.h>
-
-/*
- * No locking necessary when this is called from efirtc which protects us
- * from racing by efi_rtc_lock.
- */
-#define __swizzle(addr) ((u8 *)((unsigned long)(addr) ^ 3))
-#define read_io_port(addr) (*(volatile u8 *) __swizzle(addr))
-#define write_io_port(addr, data) (*(volatile u8 *) __swizzle(addr) = (data))
-
-#define TOD_SGS_M48T35		1
-#define TOD_DALLAS_DS1386	2
-
-static unsigned long nvram_base = 0;
-static int tod_chip_type;
-
-static int
-get_tod_chip_type(void)
-{
-	unsigned char testval;
-
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-	write_io_port(RTC_DAL_DAY_ADDR, 0xff);
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-
-	testval = read_io_port(RTC_DAL_DAY_ADDR);
-	if (testval == 0xff)
-		return TOD_SGS_M48T35;
-
-	return TOD_DALLAS_DS1386;
-}
-
-efi_status_t
-ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	memset(time, 0, sizeof(*time));
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT);
-
-		time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF;
-		time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR));
-		time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR));
-		time->nanosecond = 0;
-
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-
-		time->nanosecond = 0;
-		time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR));
-		time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR));
-		time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF;
-
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	if (caps) {
-		caps->resolution = 50000000;	/*  50PPM */
-		caps->accuracy = 1000;		/*  1ms */
-		caps->sets_to_zero = 0;
-	}
-
-	return EFI_SUCCESS;
-}
-
-static efi_status_t ioc3_set_time (efi_time_t *t)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_WRITE_ENABLE);
-        	write_io_port(RTC_SGS_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_SGS_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_SGS_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_SGS_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_SGS_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_SGS_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-		write_io_port(RTC_DAL_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_DAL_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_DAL_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_DAL_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_DAL_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_DAL_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	return EFI_SUCCESS;
-}
-
-/* The following two are not supported atm.  */
-static efi_status_t
-ioc3_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static efi_status_t
-ioc3_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-/*
- * It looks like the master IOC3 is usually on bus 0, device 4.  Hope
- * that's right
- */
-static __init int efi_ioc3_time_init(void)
-{
-	struct pci_dev *dev;
-	static struct ioc3 *ioc3;
-
-	dev = pci_find_slot(0, PCI_DEVFN(4, 0));
-	if (!dev) {
-		printk(KERN_CRIT "Couldn't find master IOC3\n");
-
-		return -ENODEV;
-	}
-
-	ioc3 = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0));
-	nvram_base = (unsigned long) ioc3 + IOC3_BYTEBUS_DEV0;
-
-	tod_chip_type = get_tod_chip_type();
-	if (tod_chip_type == 1)
-		printk(KERN_NOTICE "TOD type is SGS M48T35\n");
-	else if (tod_chip_type == 2)
-		printk(KERN_NOTICE "TOD type is Dallas DS1386\n");
-	else
-		printk(KERN_CRIT "No or unknown TOD\n");
-
-	efi.get_time = ioc3_get_time;
-	efi.set_time = ioc3_set_time;
-	efi.get_wakeup_time = ioc3_get_wakeup_time;
-	efi.set_wakeup_time = ioc3_set_wakeup_time;
-
-	return 0;
-}
-
-module_init(efi_ioc3_time_init);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hcl.c linux-2.4.22-pre3/arch/ia64/sn/io/hcl.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hcl.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hcl.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1531 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- *  hcl - SGI's Hardware Graph compatibility layer.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER"
-#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE"
-#define HCL_TEMP_NAME_LEN 44 
-#define HCL_VERSION "1.0"
-devfs_handle_t hwgraph_root = NULL;
-devfs_handle_t linux_busnum = NULL;
-
-/*
- * Debug flag definition.
- */
-#define OPTION_NONE             0x00
-#define HCL_DEBUG_NONE 0x00000
-#define HCL_DEBUG_ALL  0x0ffff
-#if defined(CONFIG_HCL_DEBUG)
-static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE;
-#endif
-static unsigned int hcl_debug = HCL_DEBUG_NONE;
-#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
-static unsigned int boot_options = OPTION_NONE;
-#endif
-
-/*
- * Some Global definitions.
- */
-devfs_handle_t hcl_handle = NULL;
-
-invplace_t invplace_none = {
-	GRAPH_VERTEX_NONE,
-	GRAPH_VERTEX_PLACE_NONE,
-	NULL
-};
-
-/*
- * HCL device driver.
- * The purpose of this device driver is to provide a facility 
- * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path 
- * to manipulate label entries without having to implement
- * system call interfaces.  This methodology will enable us to 
- * make this feature module loadable.
- */
-static int hcl_open(struct inode * inode, struct file * filp)
-{
-	if (hcl_debug) {
-        	printk("HCL: hcl_open called.\n");
-	}
-
-        return(0);
-
-}
-
-static int hcl_close(struct inode * inode, struct file * filp)
-{
-
-	if (hcl_debug) {
-        	printk("HCL: hcl_close called.\n");
-	}
-
-        return(0);
-
-}
-
-static int hcl_ioctl(struct inode * inode, struct file * file,
-        unsigned int cmd, unsigned long arg)
-{
-
-	if (hcl_debug) {
-		printk("HCL: hcl_ioctl called.\n");
-	}
-
-	switch (cmd) {
-		default:
-			if (hcl_debug) {
-				printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd);
-			}
-	}
-
-	return(0);
-
-}
-
-struct file_operations hcl_fops = {
-	(struct module *)0,
-	NULL,		/* lseek - default */
-	NULL,		/* read - general block-dev read */
-	NULL,		/* write - general block-dev write */
-	NULL,		/* readdir - bad */
-	NULL,		/* poll */
-	hcl_ioctl,      /* ioctl */
-	NULL,		/* mmap */
-	hcl_open,	/* open */
-	NULL,		/* flush */
-	hcl_close,	/* release */
-	NULL,		/* fsync */
-	NULL,		/* fasync */
-	NULL,		/* lock */
-	NULL,		/* readv */
-	NULL,		/* writev */
-};
-
-
-/*
- * init_hcl() - Boot time initialization.  Ensure that it is called 
- *	after devfs has been initialized.
- *
- * For now this routine is being called out of devfs/base.c.  Actually 
- * Not a bad place to be ..
- *
- */
-#ifdef MODULE
-int init_module (void)
-#else
-int __init init_hcl(void)
-#endif
-{
-	extern void string_table_init(struct string_table *);
-	extern struct string_table label_string_table;
-	extern int init_ifconfig_net(void);
-	int rv = 0;
-
-#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
-	printk ("\n%s: v%s Colin Ngam (cngam@sgi.com)\n",
-		HCL_NAME, HCL_VERSION);
-
-	hcl_debug = hcl_debug_init;
-	printk ("%s: hcl_debug: 0x%0x\n", HCL_NAME, hcl_debug);
-	printk ("\n%s: boot_options: 0x%0x\n", HCL_NAME, boot_options);
-#endif
-
-	/*
-	 * Create the hwgraph_root on devfs.
-	 */
-	rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
-	if (rv)
-		printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
-
-	/*
-	 * Create the hcl driver to support inventory entry manipulations.
-	 * By default, it is expected that devfs is mounted on /dev.
-	 *
-	 */
-	hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
-			0, DEVFS_FL_AUTO_DEVNUM,
-			0, 0,
-			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-			&hcl_fops, NULL);
-
-	if (hcl_handle == NULL) {
-		panic("HCL: Unable to create HCL Driver in init_hcl().\n");
-		return(0);
-	}
-
-	/*
-	 * Initialize the HCL string table.
-	 */
-	string_table_init(&label_string_table);
-
-	/*
-	 * Create the directory that links Linux bus numbers to our Xwidget.
-	 */
-	rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
-	if (linux_busnum == NULL) {
-		panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
-		return(0);
-	}
-
-	/*
-	 * Initialize the ifconfgi_net driver that does network devices 
-	 * Persistent Naming.
-	 */
-	init_ifconfig_net();
-
-	return(0);
-
-}
-
-
-/*
- * hcl_setup() - Process boot time parameters if given.
- *	"hcl="
- *	This routine gets called only if "hcl=" is given in the 
- *	boot line and before init_hcl().
- *
- *	We currently do not have any boot options .. when we do, 
- *	functionalities can be added here.
- *
- */
-static int __init hcl_setup(char *str)
-{
-    while ( (*str != '\0') && !isspace (*str) )
-    {
-#ifdef CONFIG_HCL_DEBUG
-        if (strncmp (str, "all", 3) == 0) {
-            hcl_debug_init |= HCL_DEBUG_ALL;
-            str += 3;
-        } else 
-        	return 0;
-#endif
-        if (*str != ',') return 0;
-        ++str;
-    }
-
-    return 1;
-
-}
-
-__setup("hcl=", hcl_setup);
-
-
-/*
- * Set device specific "fast information".
- *
- */
-void
-hwgraph_fastinfo_set(devfs_handle_t de, arbitrary_info_t fastinfo)
-{
-
-	if (hcl_debug) {
-		printk("HCL: hwgraph_fastinfo_set handle 0x%p fastinfo %ld\n", (void *)de, fastinfo);
-	}
-		
-	labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
-
-}
-
-
-/*
- * Get device specific "fast information".
- *
- */
-arbitrary_info_t
-hwgraph_fastinfo_get(devfs_handle_t de)
-{
-	arbitrary_info_t fastinfo;
-	int rv;
-
-	if (!de) {
-		printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
-		return(-1);
-	}
-
-	rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo);
-	if (rv == 0)
-		return(fastinfo);
-
-	return(0);
-}
-
-
-/*
- * hwgraph_connectpt_set - Sets the connect point handle in de to the 
- *	given connect_de handle.  By default, the connect point of the 
- *	devfs node is the parent.  This effectively changes this assumption.
- */
-int
-hwgraph_connectpt_set(devfs_handle_t de, devfs_handle_t connect_de)
-{
-	int rv;
-
-	if (!de)
-		return(-1);
-
-	rv = labelcl_info_connectpt_set(de, connect_de);
-
-	return(rv);
-}
-
-
-/*
- * hwgraph_connectpt_get: Returns the entry's connect point  in the devfs 
- *	tree.
- */
-devfs_handle_t
-hwgraph_connectpt_get(devfs_handle_t de)
-{
-	int rv;
-	arbitrary_info_t info;
-	devfs_handle_t connect;
-
-	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
-	if (rv != 0) {
-		return(NULL);
-	}
-
-	connect = (devfs_handle_t)info;
-	return(connect);
-
-}
-
-
-/*
- * hwgraph_mk_dir - Creates a directory entry with devfs.
- *	Note that a directory entry in devfs can have children 
- *	but it cannot be a char|block special file.
- */
-devfs_handle_t
-hwgraph_mk_dir(devfs_handle_t de, const char *name,
-                unsigned int namelen, void *info)
-{
-
-	int rv;
-	labelcl_info_t *labelcl_info = NULL;
-	devfs_handle_t new_devfs_handle = NULL;
-	devfs_handle_t parent = NULL;
-
-	/*
-	 * Create the device info structure for hwgraph compatiblity support.
-	 */
-	labelcl_info = labelcl_info_create();
-	if (!labelcl_info)
-		return(NULL);
-
-	/*
-	 * Create a devfs entry.
-	 */
-	new_devfs_handle = devfs_mk_dir(de, name, (void *)labelcl_info);
-	if (!new_devfs_handle) {
-		labelcl_info_destroy(labelcl_info);
-		return(NULL);
-	}
-
-	/*
-	 * Get the parent handle.
-	 */
-	parent = devfs_get_parent (new_devfs_handle);
-
-	/*
-	 * To provide the same semantics as the hwgraph, set the connect point.
-	 */
-	rv = hwgraph_connectpt_set(new_devfs_handle, parent);
-	if (!rv) {
-		/*
-		 * We need to clean up!
-		 */
-	}
-
-	/*
-	 * If the caller provides a private data pointer, save it in the 
-	 * labelcl info structure(fastinfo).  This can be retrieved via
-	 * hwgraph_fastinfo_get()
-	 */
-	if (info)
-		hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
-		
-	return(new_devfs_handle);
-
-}
-
-/*
- * hwgraph_vertex_create - Create a vertex by giving it a temp name.
- */
-
-/*
- * hwgraph_path_add - Create a directory node with the given path starting 
- * from the given devfs_handle_t.
- */
-extern char * dev_to_name(devfs_handle_t, char *, uint);
-int
-hwgraph_path_add(devfs_handle_t  fromv,
-		 char *path,
-		 devfs_handle_t *new_de)
-{
-
-	unsigned int	namelen = strlen(path);
-	int		rv;
-
-	/*
-	 * We need to handle the case when fromv is NULL ..
-	 * in this case we need to create the path from the 
-	 * hwgraph root!
-	 */
-	if (fromv == NULL)
-		fromv = hwgraph_root;
-
-	/*
-	 * check the entry doesn't already exist, if it does
-	 * then we simply want new_de to point to it (otherwise
-	 * we'll overwrite the existing labelcl_info struct)
-	 */
-	rv = hwgraph_edge_get(fromv, path, new_de);
-	if (rv)	{	/* couldn't find entry so we create it */
-		*new_de = hwgraph_mk_dir(fromv, path, namelen, NULL);
-		if (new_de == NULL)
-			return(-1);
-		else
-			return(0);
-	}
-	else 
- 		return(0);
-
-}
-
-/*
- * hwgraph_register  - Creates a file entry with devfs.
- *	Note that a file entry cannot have children .. it is like a 
- *	char|block special vertex in hwgraph.
- */
-devfs_handle_t
-hwgraph_register(devfs_handle_t de, const char *name,
-                unsigned int namelen, unsigned int flags, 
-		unsigned int major, unsigned int minor,
-                umode_t mode, uid_t uid, gid_t gid, 
-		struct file_operations *fops,
-                void *info)
-{
-
-	int rv;
-        void *labelcl_info = NULL;
-        devfs_handle_t new_devfs_handle = NULL;
-	devfs_handle_t parent = NULL;
-
-        /*
-         * Create the labelcl info structure for hwgraph compatiblity support.
-         */
-        labelcl_info = labelcl_info_create();
-        if (!labelcl_info)
-                return(NULL);
-
-        /*
-         * Create a devfs entry.
-         */
-        new_devfs_handle = devfs_register(de, name, flags, major,
-				minor, mode, fops, labelcl_info);
-        if (!new_devfs_handle) {
-                labelcl_info_destroy((labelcl_info_t *)labelcl_info);
-                return(NULL);
-        }
-
-	/*
-	 * Get the parent handle.
-	 */
-	if (de == NULL)
-		parent = devfs_get_parent (new_devfs_handle);
-	else
-		parent = de;
-		
-	/*
-	 * To provide the same semantics as the hwgraph, set the connect point.
-	 */
-	rv = hwgraph_connectpt_set(new_devfs_handle, parent);
-	if (rv) {
-		/*
-		 * We need to clean up!
-		 */
-		printk(KERN_WARNING "HCL: Unable to set the connect point to it's parent 0x%p\n",
-			(void *)new_devfs_handle);
-	}
-
-        /*
-         * If the caller provides a private data pointer, save it in the 
-         * labelcl info structure(fastinfo).  This can be retrieved via
-         * hwgraph_fastinfo_get()
-         */
-        if (info)
-                hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
-
-        return(new_devfs_handle);
-
-}
-
-
-/*
- * hwgraph_mk_symlink - Create a symbolic link.
- */
-int
-hwgraph_mk_symlink(devfs_handle_t de, const char *name, unsigned int namelen,
-                unsigned int flags, const char *link, unsigned int linklen, 
-		devfs_handle_t *handle, void *info)
-{
-
-	void *labelcl_info = NULL;
-	int status = 0;
-	devfs_handle_t new_devfs_handle = NULL;
-
-	/*
-	 * Create the labelcl info structure for hwgraph compatiblity support.
-	 */
-	labelcl_info = labelcl_info_create();
-	if (!labelcl_info)
-		return(-1);
-
-	/*
-	 * Create a symbolic link devfs entry.
-	 */
-	status = devfs_mk_symlink(de, name, flags, link,
-				&new_devfs_handle, labelcl_info);
-	if ( (!new_devfs_handle) || (!status) ){
-		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
-		return(-1);
-	}
-
-	/*
-	 * If the caller provides a private data pointer, save it in the 
-	 * labelcl info structure(fastinfo).  This can be retrieved via
-	 * hwgraph_fastinfo_get()
-	 */
-	if (info)
-		hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
-
-	*handle = new_devfs_handle;
-	return(0);
-
-}
-
-/*
- * hwgraph_vertex_get_next - this routine returns the next sibbling for the 
- *	device entry given in de.  If there are no more sibbling, NULL 
- * 	is returned in next_sibbling.
- *
- *	Currently we do not have any protection against de being deleted 
- *	while it's handle is being held.
- */
-int
-hwgraph_vertex_get_next(devfs_handle_t *next_sibbling, devfs_handle_t *de)
-{
-	*next_sibbling = devfs_get_next_sibling (*de);
-
-	if (*next_sibbling != NULL)
-		*de = *next_sibbling;
-	return (0);
-}
-
-
-/*
- * hwgraph_vertex_destroy - Destroy the devfs entry
- */
-int
-hwgraph_vertex_destroy(devfs_handle_t de)
-{
-
-	void *labelcl_info = NULL;
-
-	labelcl_info = devfs_get_info(de);
-	devfs_unregister(de);
-
-	if (labelcl_info)
-		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
-
-	return(0);
-}
-
-/*
-** See if a vertex has an outgoing edge with a specified name.
-** Vertices in the hwgraph *implicitly* contain these edges:
-**	"." 	refers to "current vertex"
-**	".." 	refers to "connect point vertex"
-**	"char"	refers to current vertex (character device access)
-**	"block"	refers to current vertex (block device access)
-*/
-
-/*
- * hwgraph_edge_add - This routines has changed from the original conext.
- * All it does now is to create a symbolic link from "from" to "to".
- */
-/* ARGSUSED */
-int
-hwgraph_edge_add(devfs_handle_t from, devfs_handle_t to, char *name)
-{
-
-	char *path;
-	char *s1;
-	char *index;
-	int name_start;
-	devfs_handle_t handle = NULL;
-	int rv;
-	int i, count;
-
-	path = kmalloc(1024, GFP_KERNEL);
-	memset(path, 0x0, 1024);
-	name_start = devfs_generate_path (from, path, 1024);
-	s1 = &path[name_start];
-	count = 0;
-	while (1) {
-		index = strstr (s1, "/");
-		if (index) {
-			count++;
-			s1 = ++index;
-		} else {
-			count++;
-			break;
-		}
-	}
-
-	memset(path, 0x0, 1024);
-	name_start = devfs_generate_path (to, path, 1024);
-
-	for (i = 0; i < count; i++) {
-		strcat(path,"../");
-	}
-
-	strcat(path, &path[name_start]);
-
-	/*
-	 * Otherwise, just create a symlink to the vertex.
-	 * In this case the vertex was previous created with a REAL pathname.
-	 */
-	rv = devfs_mk_symlink (from, (const char *)name, 
-			       DEVFS_FL_DEFAULT, path,
-			       &handle, NULL);
-
-	name_start = devfs_generate_path (handle, path, 1024);
-	return(rv);
-
-	
-}
-/* ARGSUSED */
-int
-hwgraph_edge_get(devfs_handle_t from, char *name, devfs_handle_t *toptr)
-{
-
-	int namelen = 0;
-	devfs_handle_t target_handle = NULL;
-
-	if (name == NULL)
-		return(-1);
-
-	if (toptr == NULL)
-		return(-1);
-
-	/*
-	 * If the name is "." just return the current devfs entry handle.
-	 */
-	if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {
-		if (toptr) {
-			*toptr = from;
-		}
-	} else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {
-		/*
-		 * Hmmm .. should we return the connect point or parent ..
-		 * see in hwgraph, the concept of parent is the connectpt!
-		 *
-		 * Maybe we should see whether the connectpt is set .. if 
-		 * not just return the parent!
-		 */
-		target_handle = hwgraph_connectpt_get(from);
-		if (target_handle) {
-			/*
-			 * Just return the connect point.
-			 */
-			*toptr = target_handle;
-			return(0);
-		}
-		target_handle = devfs_get_parent(from);
-		*toptr = target_handle;
-
-	} else {
-		/*
-		 * Call devfs to get the devfs entry.
-		 */
-		namelen = (int) strlen(name);
-		target_handle = devfs_find_handle (from, name, 0, 0,
-					0, 1); /* Yes traverse symbolic links */
-		if (target_handle == NULL)
-			return(-1);
-		else
-		*toptr = target_handle;
-	}
-
-	return(0);
-}
-
-
-/*
- * hwgraph_edge_get_next - Retrieves the next sibbling given the current
- *	entry number "placeptr".
- *
- * 	Allow the caller to retrieve walk through the sibblings of "source" 
- * 	devfs_handle_t.  The implicit edges "." and ".." is returned first 
- * 	followed by each of the real children.
- *
- *	We may end up returning garbage if another thread perform any deletion 
- *	in this directory before "placeptr".
- *
- */
-/* ARGSUSED */
-int
-hwgraph_edge_get_next(devfs_handle_t source, char *name, devfs_handle_t *target,
-                              uint *placeptr)
-
-{
-
-        uint which_place;
-	unsigned int namelen = 0;
-	const char *tempname = NULL;
-
-        if (placeptr == NULL)
-                return(-1);
-
-        which_place = *placeptr;
-
-again:
-        if (which_place <= HWGRAPH_RESERVED_PLACES) {
-                if (which_place == EDGE_PLACE_WANT_CURRENT) {
-			/*
-			 * Looking for "."
-			 * Return the current devfs handle.
-			 */
-                        if (name != NULL)
-                                strcpy(name, HWGRAPH_EDGELBL_DOT);
-
-                        if (target != NULL) {
-                                *target = source; 
-				/* XXX should incr "source" ref count here if we
-				 * ever implement ref counts */
-                        }
-
-                } else if (which_place == EDGE_PLACE_WANT_CONNECTPT) {
-			/*
-			 * Looking for the connect point or parent.
-			 * If the connect point is set .. it returns the connect point.
-			 * Otherwise, it returns the parent .. will we support 
-			 * connect point?
-			 */
-                        devfs_handle_t connect_point = hwgraph_connectpt_get(source);
-
-                        if (connect_point == NULL) {
-				/*
-				 * No connectpoint set .. either the User
-				 * explicitly NULL it or this node was not 
-				 * created via hcl.
-				 */
-                                which_place++;
-                                goto again;
-                        }
-
-                        if (name != NULL)
-                                strcpy(name, HWGRAPH_EDGELBL_DOTDOT);
-
-                        if (target != NULL)
-                                *target = connect_point;
-
-                } else if (which_place == EDGE_PLACE_WANT_REAL_EDGES) {
-			/* 
-			 * return first "real" entry in directory, and increment
-			 * placeptr.  Next time around we should have 
-			 * which_place > HWGRAPH_RESERVED_EDGES so we'll fall through
-			 * this nested if block.
-			 */
-			*target = devfs_get_first_child(source);
-			if (*target && name) {
-				tempname = devfs_get_name(*target, &namelen);
-				if (tempname && namelen)
-					strcpy(name, tempname);
-			}
-					
-			*placeptr = which_place + 1;
-			return (0);
-                }
-
-                *placeptr = which_place+1;
-                return(0);
-        }
-
-	/*
-	 * walk linked list, (which_place - HWGRAPH_RESERVED_PLACES) times
-	 */
-	{
-		devfs_handle_t	curr;
-		int		i = 0;
-
-		for (curr=devfs_get_first_child(source), i= i+HWGRAPH_RESERVED_PLACES; 
-			curr!=NULL && i<which_place; 
-			curr=devfs_get_next_sibling(curr), i++)
-			;
-		*target = curr;
-		*placeptr = which_place + 1;
-		if (curr && name) {
-			tempname = devfs_get_name(*target, &namelen);
-			if (tempname && namelen)
-				strcpy(name, tempname);
-		}
-	}
-	if (target == NULL)
-		return(-1);
-	else
-        	return(0);
-}
-
-/*
- * hwgraph_info_add_LBL - Adds a new label for the device.  Mark the info_desc
- *	of the label as INFO_DESC_PRIVATE and store the info in the label.
- */
-/* ARGSUSED */
-int
-hwgraph_info_add_LBL(	devfs_handle_t de,
-			char *name,
-			arbitrary_info_t info)
-{
-	return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));
-}
-
-/*
- * hwgraph_info_remove_LBL - Remove the label entry for the device.
- */
-/* ARGSUSED */
-int
-hwgraph_info_remove_LBL(	devfs_handle_t de,
-				char *name,
-				arbitrary_info_t *old_info)
-{
-	return(labelcl_info_remove_LBL(de, name, NULL, old_info));
-}
-
-/*
- * hwgraph_info_replace_LBL - replaces an existing label with 
- *	a new label info value.
- */
-/* ARGSUSED */
-int
-hwgraph_info_replace_LBL(	devfs_handle_t de,
-				char *name,
-				arbitrary_info_t info,
-				arbitrary_info_t *old_info)
-{
-	return(labelcl_info_replace_LBL(de, name,
-			INFO_DESC_PRIVATE, info,
-			NULL, old_info));
-}
-/*
- * hwgraph_info_get_LBL - Get and return the info value in the label of the 
- * 	device.
- */
-/* ARGSUSED */
-int
-hwgraph_info_get_LBL(	devfs_handle_t de,
-			char *name,
-			arbitrary_info_t *infop)
-{
-	return(labelcl_info_get_LBL(de, name, NULL, infop));
-}
-
-/*
- * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer 
- *	of the given label for the device.  The weird thing is that the label 
- *	that matches the name is return irrespective of the info_desc value!
- *	Do not understand why the word "exported" is used!
- */
-/* ARGSUSED */
-int
-hwgraph_info_get_exported_LBL(	devfs_handle_t de,
-				char *name,
-				int *export_info,
-				arbitrary_info_t *infop)
-{
-	int rc;
-	arb_info_desc_t info_desc;
-
-	rc = labelcl_info_get_LBL(de, name, &info_desc, infop);
-	if (rc == 0)
-		*export_info = (int)info_desc;
-
-	return(rc);
-}
-
-/*
- * hwgraph_info_get_next_LBL - Returns the next label info given the 
- *	current label entry in place.
- *
- *	Once again this has no locking or reference count for protection.
- *
- */
-/* ARGSUSED */
-int
-hwgraph_info_get_next_LBL(	devfs_handle_t de,
-				char *buf,
-				arbitrary_info_t *infop,
-				labelcl_info_place_t *place)
-{
-	return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));
-}
-
-/*
- * hwgraph_info_export_LBL - Retrieve the specified label entry and modify 
- *	the info_desc field with the given value in nbytes.
- */
-/* ARGSUSED */
-int
-hwgraph_info_export_LBL(devfs_handle_t de, char *name, int nbytes)
-{
-	arbitrary_info_t info;
-	int rc;
-
-	if (nbytes == 0)
-		nbytes = INFO_DESC_EXPORT;
-
-	if (nbytes < 0)
-		return(-1);
-
-	rc = labelcl_info_get_LBL(de, name, NULL, &info);
-	if (rc != 0)
-		return(rc);
-
-	rc = labelcl_info_replace_LBL(de, name,
-				nbytes, info, NULL, NULL);
-
-	return(rc);
-}
-
-/*
- * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the 
- * label info_descr filed to INFO_DESC_PRIVATE.
- */
-/* ARGSUSED */
-int
-hwgraph_info_unexport_LBL(devfs_handle_t de, char *name)
-{
-	arbitrary_info_t info;
-	int rc;
-
-	rc = labelcl_info_get_LBL(de, name, NULL, &info);
-	if (rc != 0)
-		return(rc);
-
-	rc = labelcl_info_replace_LBL(de, name,
-				INFO_DESC_PRIVATE, info, NULL, NULL);
-
-	return(rc);
-}
-
-/*
- * hwgraph_path_lookup - return the handle for the given path.
- *
- */
-int
-hwgraph_path_lookup(	devfs_handle_t start_vertex_handle,
-			char *lookup_path,
-			devfs_handle_t *vertex_handle_ptr,
-			char **remainder)
-{
-	*vertex_handle_ptr = devfs_find_handle(start_vertex_handle,	/* start dir */
-					lookup_path,		/* path */
-					0,			/* major */
-					0,			/* minor */
-					0,			/* char | block */
-					1);			/* traverse symlinks */
-	if (*vertex_handle_ptr == NULL)
-		return(-1);
-	else
-		return(0);
-}
-
-/*
- * hwgraph_traverse - Find and return the devfs handle starting from de.
- *
- */
-graph_error_t
-hwgraph_traverse(devfs_handle_t de, char *path, devfs_handle_t *found)
-{
-	/* 
-	 * get the directory entry (path should end in a directory)
-	 */
-
-	*found = devfs_find_handle(de,	/* start dir */
-			    path,	/* path */
-			    0,		/* major */
-			    0,		/* minor */
-			    0,		/* char | block */
-			    1);		/* traverse symlinks */
-	if (*found == NULL)
-		return(GRAPH_NOT_FOUND);
-	else
-		return(GRAPH_SUCCESS);
-}
-
-/*
- * hwgraph_path_to_vertex - Return the devfs entry handle for the given 
- *	pathname .. assume traverse symlinks too!.
- */
-devfs_handle_t
-hwgraph_path_to_vertex(char *path)
-{
-	return(devfs_find_handle(NULL,	/* start dir */
-			path,		/* path */
-		    	0,		/* major */
-		    	0,		/* minor */
-		    	0,		/* char | block */
-		    	1));		/* traverse symlinks */
-}
-
-/*
- * hwgraph_path_to_dev - Returns the devfs_handle_t of the given path ..
- *	We only deal with devfs handle and not devfs_handle_t.
-*/
-devfs_handle_t
-hwgraph_path_to_dev(char *path)
-{
-	devfs_handle_t  de;
-
-	de = hwgraph_path_to_vertex(path);
-	return(de);
-}
-
-/*
- * hwgraph_block_device_get - return the handle of the block device file.
- *	The assumption here is that de is a directory.
-*/
-devfs_handle_t
-hwgraph_block_device_get(devfs_handle_t de)
-{
-	return(devfs_find_handle(de,		/* start dir */
-			"block",		/* path */
-		    	0,			/* major */
-		    	0,			/* minor */
-		    	DEVFS_SPECIAL_BLK,	/* char | block */
-		    	1));			/* traverse symlinks */
-}
-
-/*
- * hwgraph_char_device_get - return the handle of the char device file.
- *      The assumption here is that de is a directory.
-*/
-devfs_handle_t
-hwgraph_char_device_get(devfs_handle_t de)
-{
-	return(devfs_find_handle(de,		/* start dir */
-			"char",			/* path */
-		    	0,			/* major */
-		    	0,			/* minor */
-		    	DEVFS_SPECIAL_CHR,	/* char | block */
-		    	1));			/* traverse symlinks */
-}
-
-/*
-** Inventory is now associated with a vertex in the graph.  For items that
-** belong in the inventory but have no vertex 
-** (e.g. old non-graph-aware drivers), we create a bogus vertex under the 
-** INFO_LBL_INVENT name.
-**
-** For historical reasons, we prevent exact duplicate entries from being added
-** to a single vertex.
-*/
-
-/*
- * hwgraph_inventory_add - Adds an inventory entry into de.
- */
-int
-hwgraph_inventory_add(	devfs_handle_t de,
-			int class,
-			int type,
-			major_t controller,
-			minor_t unit,
-			int state)
-{
-	inventory_t *pinv = NULL, *old_pinv = NULL, *last_pinv = NULL;
-	int rv;
-
-	/*
-	 * Add our inventory data to the list of inventory data
-	 * associated with this vertex.
-	 */
-again:
-	/* GRAPH_LOCK_UPDATE(&invent_lock); */
-	rv = labelcl_info_get_LBL(de,
-			INFO_LBL_INVENT,
-			NULL, (arbitrary_info_t *)&old_pinv);
-	if ((rv != LABELCL_SUCCESS) && (rv != LABELCL_NOT_FOUND))
-		goto failure;
-
-	/*
-	 * Seek to end of inventory items associated with this
-	 * vertex.  Along the way, make sure we're not duplicating
-	 * an inventory item (for compatibility with old add_to_inventory)
-	 */
-	for (;old_pinv; last_pinv = old_pinv, old_pinv = old_pinv->inv_next) {
-		if ((int)class != -1 && old_pinv->inv_class != class)
-			continue;
-		if ((int)type != -1 && old_pinv->inv_type != type)
-			continue;
-		if ((int)state != -1 && old_pinv->inv_state != state)
-			continue;
-		if ((int)controller != -1
-		    && old_pinv->inv_controller != controller)
-			continue;
-		if ((int)unit != -1 && old_pinv->inv_unit != unit)
-			continue;
-
-		/* exact duplicate of previously-added inventory item */
-		rv = LABELCL_DUP;
-		goto failure;
-	}
-
-	/* Not a duplicate, so we know that we need to add something. */
-	if (pinv == NULL) {
-		/* Release lock while we wait for memory. */
-		/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-		pinv = (inventory_t *)kmalloc(sizeof(inventory_t), GFP_KERNEL);
-		replace_in_inventory(pinv, class, type, controller, unit, state);
-		goto again;
-	}
-
-	pinv->inv_next = NULL;
-	if (last_pinv) {
-		last_pinv->inv_next = pinv;
-	} else {
-		rv = labelcl_info_add_LBL(de, INFO_LBL_INVENT, 
-			sizeof(inventory_t), (arbitrary_info_t)pinv);
-
-		if (!rv)
-			goto failure;
-	}
-
-	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-	return(0);
-
-failure:
-	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-	if (pinv)
-		kfree(pinv);
-	return(rv);
-}
-
-
-/*
- * hwgraph_inventory_remove - Removes an inventory entry.
- *
- *	Remove an inventory item associated with a vertex.   It is the caller's
- *	responsibility to make sure that there are no races between removing
- *	inventory from a vertex and simultaneously removing that vertex.
-*/
-int
-hwgraph_inventory_remove(	devfs_handle_t de,
-				int class,
-				int type,
-				major_t controller,
-				minor_t unit,
-				int state)
-{
-	inventory_t *pinv = NULL, *last_pinv = NULL, *next_pinv = NULL;
-	labelcl_error_t rv;
-
-	/*
-	 * We never remove stuff from ".invent" ..
-	 */
-	if (!de)
-		return (-1);
-
-	/*
-	 * Remove our inventory data to the list of inventory data
-	 * associated with this vertex.
-	 */
-	/* GRAPH_LOCK_UPDATE(&invent_lock); */
-	rv = labelcl_info_get_LBL(de,
-			INFO_LBL_INVENT,
-			NULL, (arbitrary_info_t *)&pinv);
-	if (rv != LABELCL_SUCCESS)
-		goto failure;
-
-	/*
-	 * Search through inventory items associated with this
-	 * vertex, looking for a match.
-	 */
-	for (;pinv; pinv = next_pinv) {
-		next_pinv = pinv->inv_next;
-
-		if(((int)class == -1 || pinv->inv_class == class) &&
-		   ((int)type == -1 || pinv->inv_type == type) &&
-		   ((int)state == -1 || pinv->inv_state == state) &&
-		   ((int)controller == -1 || pinv->inv_controller == controller) &&
-		   ((int)unit == -1 || pinv->inv_unit == unit)) {
-
-			/* Found a matching inventory item. Remove it. */
-			if (last_pinv) {
-				last_pinv->inv_next = pinv->inv_next;
-			} else {
-				rv = hwgraph_info_replace_LBL(de, INFO_LBL_INVENT, (arbitrary_info_t)pinv->inv_next, NULL);
-				if (rv != LABELCL_SUCCESS)
-					goto failure;
-			}
-
-			pinv->inv_next = NULL; /* sanity */
-			kfree(pinv);
-		} else
-			last_pinv = pinv;
-	}
-
-	if (last_pinv == NULL) {
-		rv = hwgraph_info_remove_LBL(de, INFO_LBL_INVENT, NULL);
-		if (rv != LABELCL_SUCCESS)
-			goto failure;
-	}
-
-	rv = LABELCL_SUCCESS;
-
-failure:
-	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-	return(rv);
-}
-
-/*
- * hwgraph_inventory_get_next - Get next inventory item associated with the 
- *	specified vertex.
- *
- *	No locking is really needed.  We don't yet have the ability
- *	to remove inventory items, and new items are always added to
- *	the end of a vertex' inventory list.
- *
- * 	However, a devfs entry can be removed!
-*/
-int
-hwgraph_inventory_get_next(devfs_handle_t de, invplace_t *place, inventory_t **ppinv)
-{
-	inventory_t *pinv;
-	labelcl_error_t rv;
-
-	if (de == NULL)
-		return(LABELCL_BAD_PARAM);
-
-	if (place->invplace_vhdl == NULL) {
-		place->invplace_vhdl = de;
-		place->invplace_inv = NULL;
-	}
-
-	if (de != place->invplace_vhdl)
-		return(LABELCL_BAD_PARAM);
-
-	if (place->invplace_inv == NULL) {
-		/* Just starting on this vertex */
-		rv = labelcl_info_get_LBL(de, INFO_LBL_INVENT,
-						NULL, (arbitrary_info_t *)&pinv);
-		if (rv != LABELCL_SUCCESS)
-			return(LABELCL_NOT_FOUND);
-
-	} else {
-		/* Advance to next item on this vertex */
-		pinv = place->invplace_inv->inv_next;
-	}
-	place->invplace_inv = pinv;
-	*ppinv = pinv;
-
-	return(LABELCL_SUCCESS);
-}
-
-/*
- * hwgraph_controller_num_get - Returns the controller number in the inventory 
- *	entry.
- */
-int
-hwgraph_controller_num_get(devfs_handle_t device)
-{
-	inventory_t *pinv;
-	invplace_t invplace = { NULL, NULL, NULL };
-	int val = -1;
-	if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) {
-		val = (pinv->inv_class == INV_NETWORK)? pinv->inv_unit: pinv->inv_controller;
-	}
-#ifdef DEBUG
-	/*
-	 * It does not make any sense to call this on vertexes with multiple
-	 * inventory structs chained together
-	 */
-	if ( device_inventory_get_next(device, &invplace) != NULL ) {
-		printk("Should panic here ... !\n");
-#endif
-	return (val);	
-}
-
-/*
- * hwgraph_controller_num_set - Sets the controller number in the inventory 
- *	entry.
- */
-void
-hwgraph_controller_num_set(devfs_handle_t device, int contr_num)
-{
-	inventory_t *pinv;
-	invplace_t invplace = { NULL, NULL, NULL };
-	if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) {
-		if (pinv->inv_class == INV_NETWORK)
-			pinv->inv_unit = contr_num;
-		else {
-			if (pinv->inv_class == INV_FCNODE)
-				pinv = device_inventory_get_next(device, &invplace);
-			if (pinv != NULL)
-				pinv->inv_controller = contr_num;
-		}
-	}
-#ifdef DEBUG
-	/*
-	 * It does not make any sense to call this on vertexes with multiple
-	 * inventory structs chained together
-	 */
-	if(pinv != NULL)
-		ASSERT(device_inventory_get_next(device, &invplace) == NULL);
-#endif
-}
-
-/*
- * Find the canonical name for a given vertex by walking back through
- * connectpt's until we hit the hwgraph root vertex (or until we run
- * out of buffer space or until something goes wrong).
- *
- *	COMPATIBILITY FUNCTIONALITY
- * Walks back through 'parents', not necessarily the same as connectpts.
- *
- * Need to resolve the fact that devfs does not return the path from 
- * "/" but rather it just stops right before /dev ..
- */
-int
-hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen)
-{
-	char *locbuf;
-	int   pos;
-
-	if (buflen < 1)
-		return(-1);	/* XXX should be GRAPH_BAD_PARAM ? */
-
-	locbuf = kmalloc(buflen, GFP_KERNEL);
-
-	pos = devfs_generate_path(vhdl, locbuf, buflen);
-	if (pos < 0) {
-		kfree(locbuf);
-		return pos;
-	}
-
-	strcpy(buf, &locbuf[pos]);
-	kfree(locbuf);
-	return 0;
-}
-
-/*
-** vertex_to_name converts a vertex into a canonical name by walking
-** back through connect points until we hit the hwgraph root (or until
-** we run out of buffer space).
-**
-** Usually returns a pointer to the original buffer, filled in as
-** appropriate.  If the buffer is too small to hold the entire name,
-** or if anything goes wrong while determining the name, vertex_to_name
-** returns "UnknownDevice".
-*/
-
-#define DEVNAME_UNKNOWN "UnknownDevice"
-
-char *
-vertex_to_name(devfs_handle_t vhdl, char *buf, uint buflen)
-{
-	if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)
-		return(buf);
-	else
-		return(DEVNAME_UNKNOWN);
-}
-
-#ifdef LATER
-/*
-** Return the compact node id of the node that ultimately "owns" the specified
-** vertex.  In order to do this, we walk back through masters and connect points
-** until we reach a vertex that represents a node.
-*/
-cnodeid_t
-master_node_get(devfs_handle_t vhdl)
-{
-	cnodeid_t cnodeid;
-	devfs_handle_t master;
-
-	for (;;) {
-		cnodeid = nodevertex_to_cnodeid(vhdl);
-		if (cnodeid != CNODEID_NONE)
-			return(cnodeid);
-
-		master = device_master_get(vhdl);
-
-		/* Check for exceptional cases */
-		if (master == vhdl) {
-			/* Since we got a reference to the "master" thru
-			 * device_master_get() we should decrement
-			 * its reference count by 1
-			 */
-			hwgraph_vertex_unref(master);
-			return(CNODEID_NONE);
-		}
-
-		if (master == GRAPH_VERTEX_NONE) {
-			master = hwgraph_connectpt_get(vhdl);
-			if ((master == GRAPH_VERTEX_NONE) ||
-			    (master == vhdl)) {
-				if (master == vhdl)
-					/* Since we got a reference to the
-					 * "master" thru
-					 * hwgraph_connectpt_get() we should
-					 * decrement its reference count by 1
-					 */
-					hwgraph_vertex_unref(master);
-				return(CNODEID_NONE);
-			}
-		}
-		
-		vhdl = master;
-		/* Decrement the reference to "master" which was got
-		 * either thru device_master_get() or hwgraph_connectpt_get()
-		 * above.
-		 */
-		hwgraph_vertex_unref(master);
-	}
-}
-
-/*
- * Using the canonical path name to get hold of the desired vertex handle will
- * not work on multi-hub sn0 nodes. Hence, we use the following (slightly
- * convoluted) algorithm.
- *
- * - Start at the vertex corresponding to the driver (provided as input parameter)
- * - Loop till you reach a vertex which has EDGE_LBL_MEMORY
- *    - If EDGE_LBL_CONN exists, follow that up.
- *      else if EDGE_LBL_MASTER exists, follow that up.
- *      else follow EDGE_LBL_DOTDOT up.
- *
- * * We should be at desired hub/heart vertex now *
- * - Follow EDGE_LBL_CONN to the widget vertex.
- *
- * - return vertex handle of this widget.
- */
-devfs_handle_t
-mem_vhdl_get(devfs_handle_t drv_vhdl)
-{
-devfs_handle_t cur_vhdl, cur_upper_vhdl;
-devfs_handle_t tmp_mem_vhdl, mem_vhdl;
-graph_error_t loop_rv;
-
-  /* Initializations */
-  cur_vhdl = drv_vhdl;
-  loop_rv = ~GRAPH_SUCCESS;
-
-  /* Loop till current vertex has EDGE_LBL_MEMORY */
-  while (loop_rv != GRAPH_SUCCESS) {
-
-    if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &cur_upper_vhdl)) == GRAPH_SUCCESS) {
-
-    } else if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_MASTER, &cur_upper_vhdl)) == GRAPH_SUCCESS) {
-      } else { /* Follow HWGRAPH_EDGELBL_DOTDOT up */
-           (void) hwgraph_edge_get(cur_vhdl, HWGRAPH_EDGELBL_DOTDOT, &cur_upper_vhdl);
-        }
-
-    cur_vhdl = cur_upper_vhdl;
-
-#if DEBUG && HWG_DEBUG
-    printf("Current vhdl %d \n", cur_vhdl);
-#endif /* DEBUG */
-
-    loop_rv = hwgraph_edge_get(cur_vhdl, EDGE_LBL_MEMORY, &tmp_mem_vhdl);
-  }
-
-  /* We should be at desired hub/heart vertex now */
-  if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &mem_vhdl)) != GRAPH_SUCCESS)
-    return (GRAPH_VERTEX_NONE);
-
-  return (mem_vhdl);
-}
-#endif /* LATER */
-
-
-/*
-** Add a char device -- if the driver supports it -- at a specified vertex.
-*/
-graph_error_t
-hwgraph_char_device_add(        devfs_handle_t from,
-                                char *path,
-                                char *prefix,
-                                devfs_handle_t *devhdl)
-{
-	devfs_handle_t xx = NULL;
-
-	printk("WARNING: hwgraph_char_device_add() not supported .. use hwgraph_register.\n");
-	*devhdl = xx;	// Must set devhdl
-	return(GRAPH_SUCCESS);
-}
-
-graph_error_t
-hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr)
-{
-	printk("WARNING: hwgraph_edge_remove NOT supported.\n");
-	return(GRAPH_ILLEGAL_REQUEST);
-}
-
-graph_error_t
-hwgraph_vertex_unref(devfs_handle_t vhdl)
-{
-	return(GRAPH_ILLEGAL_REQUEST);
-}
-
-
-EXPORT_SYMBOL(hwgraph_mk_dir);
-EXPORT_SYMBOL(hwgraph_path_add);
-EXPORT_SYMBOL(hwgraph_char_device_add);
-EXPORT_SYMBOL(hwgraph_register);
-EXPORT_SYMBOL(hwgraph_vertex_destroy);
-
-EXPORT_SYMBOL(hwgraph_fastinfo_get);
-EXPORT_SYMBOL(hwgraph_edge_get);
-
-EXPORT_SYMBOL(hwgraph_fastinfo_set);
-EXPORT_SYMBOL(hwgraph_connectpt_set);
-EXPORT_SYMBOL(hwgraph_connectpt_get);
-EXPORT_SYMBOL(hwgraph_edge_get_next);
-EXPORT_SYMBOL(hwgraph_info_add_LBL);
-EXPORT_SYMBOL(hwgraph_info_remove_LBL);
-EXPORT_SYMBOL(hwgraph_info_replace_LBL);
-EXPORT_SYMBOL(hwgraph_info_get_LBL);
-EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);
-EXPORT_SYMBOL(hwgraph_info_get_next_LBL);
-EXPORT_SYMBOL(hwgraph_info_export_LBL);
-EXPORT_SYMBOL(hwgraph_info_unexport_LBL);
-EXPORT_SYMBOL(hwgraph_path_lookup);
-EXPORT_SYMBOL(hwgraph_traverse);
-EXPORT_SYMBOL(hwgraph_path_to_vertex);
-EXPORT_SYMBOL(hwgraph_path_to_dev);
-EXPORT_SYMBOL(hwgraph_block_device_get);
-EXPORT_SYMBOL(hwgraph_char_device_get);
-EXPORT_SYMBOL(hwgraph_vertex_name_get);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hcl_util.c linux-2.4.22-pre3/arch/ia64/sn/io/hcl_util.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hcl_util.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hcl_util.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,200 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/sn/sgi.h>
-#include <asm/io.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/nodepda.h>
-
-static devfs_handle_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE;
-extern devfs_handle_t hwgraph_root;
-
-
-/*
-** Return the "master" for a given vertex.  A master vertex is a
-** controller or adapter or other piece of hardware that the given
-** vertex passes through on the way to the rest of the system.
-*/
-devfs_handle_t
-device_master_get(devfs_handle_t vhdl)
-{
-	graph_error_t rc;
-	devfs_handle_t master;
-
-	rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master);
-	if (rc == GRAPH_SUCCESS)
-		return(master);
-	else
-		return(GRAPH_VERTEX_NONE);
-}
-
-/*
-** Set the master for a given vertex.
-** Returns 0 on success, non-0 indicates failure
-*/
-int
-device_master_set(devfs_handle_t vhdl, devfs_handle_t master)
-{
-	graph_error_t rc;
-
-	rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER);
-	return(rc != GRAPH_SUCCESS);
-}
-
-
-/*
-** Return the compact node id of the node that ultimately "owns" the specified
-** vertex.  In order to do this, we walk back through masters and connect points
-** until we reach a vertex that represents a node.
-*/
-cnodeid_t
-master_node_get(devfs_handle_t vhdl)
-{
-	cnodeid_t cnodeid;
-	devfs_handle_t master;
-
-	for (;;) {
-		cnodeid = nodevertex_to_cnodeid(vhdl);
-		if (cnodeid != CNODEID_NONE)
-			return(cnodeid);
-
-		master = device_master_get(vhdl);
-
-		/* Check for exceptional cases */
-		if (master == vhdl) {
-			/* Since we got a reference to the "master" thru
-			 * device_master_get() we should decrement
-			 * its reference count by 1
-			 */
-			return(CNODEID_NONE);
-		}
-
-		if (master == GRAPH_VERTEX_NONE) {
-			master = hwgraph_connectpt_get(vhdl);
-			if ((master == GRAPH_VERTEX_NONE) ||
-			    (master == vhdl)) {
-				return(CNODEID_NONE);
-			}
-		}
-
-		vhdl = master;
-	}
-}
-
-static devfs_handle_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
-extern int maxcpus;
-
-void
-mark_cpuvertex_as_cpu(devfs_handle_t vhdl, cpuid_t cpuid)
-{
-	if (cpuid == CPU_NONE)
-		return;
-
-	(void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT,
-			(arbitrary_info_t)cpuid);
-	{
-		char cpuid_buffer[10];
-
-		if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) {
-			(void)hwgraph_path_add( hwgraph_root,
-						EDGE_LBL_CPUNUM,
-						&hwgraph_all_cpuids);
-		}
-
-		sprintf(cpuid_buffer, "%ld", cpuid);
-		(void)hwgraph_edge_add( hwgraph_all_cpuids,
-							vhdl,
-							cpuid_buffer);
-	}
-}
-
-/*
-** If the specified device represents a node, return its
-** compact node ID; otherwise, return CNODEID_NONE.
-*/
-cnodeid_t
-nodevertex_to_cnodeid(devfs_handle_t vhdl)
-{
-	int rv = 0;
-	arbitrary_info_t cnodeid = CNODEID_NONE;
-
-	rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid);
-
-	return((cnodeid_t)cnodeid);
-}
-
-void
-mark_nodevertex_as_node(devfs_handle_t vhdl, cnodeid_t cnodeid)
-{
-	if (cnodeid == CNODEID_NONE)
-		return;
-
-	cnodeid_to_vertex(cnodeid) = vhdl;
-	labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, 
-		(arbitrary_info_t)cnodeid);
-
-	{
-		char cnodeid_buffer[10];
-
-		if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) {
-			(void)hwgraph_path_add( hwgraph_root,
-						EDGE_LBL_NODENUM,
-						&hwgraph_all_cnodes);
-		}
-
-		sprintf(cnodeid_buffer, "%d", cnodeid);
-		(void)hwgraph_edge_add( hwgraph_all_cnodes,
-					vhdl,
-					cnodeid_buffer);
-	}
-}
-
-/*
-** If the specified device represents a CPU, return its cpuid;
-** otherwise, return CPU_NONE.
-*/
-cpuid_t
-cpuvertex_to_cpuid(devfs_handle_t vhdl)
-{
-	arbitrary_info_t cpuid = CPU_NONE;
-
-	(void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid);
-
-	return((cpuid_t)cpuid);
-}
-
-
-/*
-** dev_to_name converts a devfs_handle_t into a canonical name.  If the devfs_handle_t
-** represents a vertex in the hardware graph, it is converted in the
-** normal way for vertices.  If the devfs_handle_t is an old devfs_handle_t (one which
-** does not represent a hwgraph vertex), we synthesize a name based
-** on major/minor number.
-**
-** Usually returns a pointer to the original buffer, filled in as
-** appropriate.  If the buffer is too small to hold the entire name,
-** or if anything goes wrong while determining the name, dev_to_name
-** returns "UnknownDevice".
-*/
-char *
-dev_to_name(devfs_handle_t dev, char *buf, uint buflen)
-{
-        return(vertex_to_name(dev, buf, buflen));
-}
-
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hubdev.c linux-2.4.22-pre3/arch/ia64/sn/io/hubdev.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hubdev.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hubdev.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,132 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-struct hubdev_callout {
-        int (*attach_method)(devfs_handle_t);
-        struct hubdev_callout *fp;
-};
-
-typedef struct hubdev_callout hubdev_callout_t;
-
-mutex_t hubdev_callout_mutex;
-hubdev_callout_t *hubdev_callout_list = NULL;
-
-void
-hubdev_init(void)
-{
-	mutex_init(&hubdev_callout_mutex);
-        hubdev_callout_list = NULL;
-}
-        
-void
-hubdev_register(int (*attach_method)(devfs_handle_t))
-{
-        hubdev_callout_t *callout;
-        
-        ASSERT(attach_method);
-
-        callout =  (hubdev_callout_t *)snia_kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP);
-        ASSERT(callout);
-        
-	mutex_lock(&hubdev_callout_mutex);
-        /*
-         * Insert at the end of the list
-         */
-        callout->fp = hubdev_callout_list;
-        hubdev_callout_list = callout;
-        callout->attach_method = attach_method;
-	mutex_unlock(&hubdev_callout_mutex);
-}
-
-int
-hubdev_unregister(int (*attach_method)(devfs_handle_t))
-{
-        hubdev_callout_t **p;
-        
-        ASSERT(attach_method);
-   
-	mutex_lock(&hubdev_callout_mutex);
-        /*
-         * Remove registry element containing attach_method
-         */
-        for (p = &hubdev_callout_list; *p != NULL; p = &(*p)->fp) {
-                if ((*p)->attach_method == attach_method) {
-                        hubdev_callout_t* victim = *p;
-                        *p = (*p)->fp;
-                        kfree(victim);
-                        mutex_unlock(&hubdev_callout_mutex);
-                        return (0);
-                }
-        }
-        mutex_unlock(&hubdev_callout_mutex);
-        return (ENOENT);
-}
-
-
-int
-hubdev_docallouts(devfs_handle_t hub)
-{
-        hubdev_callout_t *p;
-        int errcode;
-
-	mutex_lock(&hubdev_callout_mutex);
-        
-        for (p = hubdev_callout_list; p != NULL; p = p->fp) {
-                ASSERT(p->attach_method);
-                errcode = (*p->attach_method)(hub);
-                if (errcode != 0) {
-			mutex_unlock(&hubdev_callout_mutex);
-                        return (errcode);
-                }
-        }
-        mutex_unlock(&hubdev_callout_mutex);
-        return (0);
-}
-
-/*
- * Given a hub vertex, return the base address of the Hspec space
- * for that hub.
- */
-
-#if defined(CONFIG_IA64_SGI_SN1)
-
-caddr_t
-hubdev_prombase_get(devfs_handle_t hub)
-{
-	hubinfo_t	hinfo = NULL;
-
-	hubinfo_get(hub, &hinfo);
-	ASSERT(hinfo);
-
-	return ((caddr_t)NODE_RBOOT_BASE(hinfo->h_nasid));
-}
-
-cnodeid_t
-hubdev_cnodeid_get(devfs_handle_t hub)
-{
-	hubinfo_t	hinfo = NULL;
-	hubinfo_get(hub, &hinfo);
-	ASSERT(hinfo);
-
-	return hinfo->h_cnodeid;
-}
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hubspc.c linux-2.4.22-pre3/arch/ia64/sn/io/hubspc.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hubspc.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hubspc.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,251 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/*
- * hubspc.c - Hub Memory Space Management Driver
- * This driver implements the managers for the following
- * memory resources:
- * 1) reference counters
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn1/mem_refcnt.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/snconfig.h>
-#include <asm/sn/sn1/hubspc.h>
-#include <asm/sn/ksys/elsc.h>
-#include <asm/sn/simulator.h>
-
-
-/* Uncomment the following line for tracing */
-/* #define HUBSPC_DEBUG 1 */
-
-int hubspc_devflag = D_MP;
-
-
-/***********************************************************************/
-/* CPU Prom Space 						       */
-/***********************************************************************/
-
-typedef struct cpuprom_info {
-	devfs_handle_t	prom_dev;
-	devfs_handle_t	nodevrtx;
-	struct	cpuprom_info *next;
-}cpuprom_info_t;
-
-static cpuprom_info_t	*cpuprom_head;
-static spinlock_t	cpuprom_spinlock;
-#define	PROM_LOCK()	mutex_spinlock(&cpuprom_spinlock)
-#define	PROM_UNLOCK(s)	mutex_spinunlock(&cpuprom_spinlock, (s))
-
-/*
- * Add prominfo to the linked list maintained.
- */
-void
-prominfo_add(devfs_handle_t hub, devfs_handle_t prom)
-{
-	cpuprom_info_t	*info;
-	unsigned long	s;
-
-	info = kmalloc(sizeof(cpuprom_info_t), GFP_KERNEL);
-	ASSERT(info);
-	info->prom_dev = prom;
-	info->nodevrtx = hub;
-
-
-	s = PROM_LOCK();
-	info->next = cpuprom_head;
-	cpuprom_head = info;
-	PROM_UNLOCK(s);
-}
-
-void
-prominfo_del(devfs_handle_t prom)
-{
-	unsigned long	s;
-	cpuprom_info_t	*info;
-	cpuprom_info_t	**prev;
-
-	s = PROM_LOCK();
-	prev = &cpuprom_head;
-	while ( (info = *prev) ) {
-		if (info->prom_dev == prom) {
-			*prev = info->next;
-			PROM_UNLOCK(s);
-			return;
-		}
-		
-		prev = &info->next;
-	}
-	PROM_UNLOCK(s);
-	ASSERT(0);
-}
-
-devfs_handle_t
-prominfo_nodeget(devfs_handle_t prom)
-{
-	unsigned long	s;
-	cpuprom_info_t	*info;
-
-	s = PROM_LOCK();
-	info = cpuprom_head;
-	while (info) {
-		if(info->prom_dev == prom) {
-			PROM_UNLOCK(s);
-			return info->nodevrtx;
-		}
-		info = info->next;
-	}
-	PROM_UNLOCK(s);
-	return 0;
-}
-
-#if defined(CONFIG_IA64_SGI_SN1)
-#define	SN_PROMVERSION		INV_IP35PROM
-
-/* Add "detailed" labelled inventory information to the
- * prom vertex 
- */
-void
-cpuprom_detailed_inventory_info_add(devfs_handle_t prom_dev,devfs_handle_t node)
-{
-	invent_miscinfo_t 	*cpuprom_inventory_info;
-	extern invent_generic_t *klhwg_invent_alloc(cnodeid_t cnode, 
-						     int class, int size);
-	cnodeid_t		cnode = hubdev_cnodeid_get(node);
-
-	/* Allocate memory for the extra inventory information
-	 * for the  prom
-	 */
-	cpuprom_inventory_info = (invent_miscinfo_t *) 
-		klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t));
-
-	ASSERT(cpuprom_inventory_info);
-
-	/* Set the enabled flag so that the hinv interprets this
-	 * information
-	 */
-	cpuprom_inventory_info->im_gen.ig_flag = INVENT_ENABLED;
-	cpuprom_inventory_info->im_type = SN_PROMVERSION;
-	/* Store prom revision into inventory information */
-	cpuprom_inventory_info->im_rev = IP27CONFIG.pvers_rev;
-	cpuprom_inventory_info->im_version = IP27CONFIG.pvers_vers;
-
-	/* Store this info as labelled information hanging off the
-	 * prom device vertex
-	 */
-	hwgraph_info_add_LBL(prom_dev, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) cpuprom_inventory_info);
-	/* Export this information so that user programs can get to
-	 * this by using attr_get()
-	 */
-        hwgraph_info_export_LBL(prom_dev, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-#endif  /* CONFIG_IA64_SGI_SN1 */
-
-
-/***********************************************************************/
-/* Base Hub Space Driver                                               */
-/***********************************************************************/
-
-/*
- * hubspc_init
- * Registration of the hubspc devices with the hub manager
- */
-void
-hubspc_init(void)
-{
-        /*
-         * Register with the hub manager
-         */
-
-        /* The reference counters */
-#if defined(CONFIG_IA64_SGI_SN1)
-        hubdev_register(mem_refcnt_attach);
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN1
-	/* L1 system controller link */
-	if ( !IS_RUNNING_ON_SIMULATOR() ) {
-		/* initialize the L1 link */
-		extern void l1_init(void);
-		l1_init();
-	}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-#ifdef	HUBSPC_DEBUG
-	printk("hubspc_init: Completed\n");
-#endif	/* HUBSPC_DEBUG */
-	/* Initialize spinlocks */
-	mutex_spinlock_init(&cpuprom_spinlock);
-}
-
-/* ARGSUSED */
-int
-hubspc_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp)
-{
-        return (0);
-}
-
-
-/* ARGSUSED */
-int
-hubspc_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-        return (0);
-}
-
-/* ARGSUSED */
-int
-hubspc_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-	/*REFERENCED*/
-        int errcode = 0;
-
-	/* check validity of request */
-	if( len == 0 ) {
-		return -ENXIO;
-        }
-
-	return errcode;
-}
-
-/* ARGSUSED */
-int
-hubspc_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-	return (0);
-
-}
-
-/* ARGSUSED */
-int
-hubspc_ioctl(devfs_handle_t dev,
-             int cmd,
-             void *arg,
-             int mode,
-             cred_t *cred_p,
-             int *rvalp)
-{
-	return (0);
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgdfs/Makefile linux-2.4.22-pre3/arch/ia64/sn/io/hwgdfs/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgdfs/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgdfs/Makefile	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,18 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+O_TARGET := snio.o
+
+export-objs := hcl.o
+
+obj-y				+= hcl.o labelcl.o hcl_util.o invent_stub.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgdfs/hcl.c linux-2.4.22-pre3/arch/ia64/sn/io/hwgdfs/hcl.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgdfs/hcl.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgdfs/hcl.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,916 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  hcl - SGI's Hardware Graph compatibility layer.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/sn/sgi.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/simulator.h>
+
+#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER"
+#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE"
+#define HCL_TEMP_NAME_LEN 44 
+#define HCL_VERSION "1.0"
+vertex_hdl_t hwgraph_root;
+vertex_hdl_t linux_busnum;
+
+extern void pci_bus_cvlink_init(void);
+
+/*
+ * Debug flag definition.
+ */
+#define OPTION_NONE             0x00
+#define HCL_DEBUG_NONE 0x00000
+#define HCL_DEBUG_ALL  0x0ffff
+#if defined(CONFIG_HCL_DEBUG)
+static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE;
+#endif
+static unsigned int hcl_debug = HCL_DEBUG_NONE;
+#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
+static unsigned int boot_options = OPTION_NONE;
+#endif
+
+/*
+ * Some Global definitions.
+ */
+static vertex_hdl_t hcl_handle;
+
+invplace_t invplace_none = {
+	GRAPH_VERTEX_NONE,
+	GRAPH_VERTEX_PLACE_NONE,
+	NULL
+};
+
+/*
+ * HCL device driver.
+ * The purpose of this device driver is to provide a facility 
+ * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path 
+ * to manipulate label entries without having to implement
+ * system call interfaces.  This methodology will enable us to 
+ * make this feature module loadable.
+ */
+static int hcl_open(struct inode * inode, struct file * filp)
+{
+	if (hcl_debug) {
+        	printk("HCL: hcl_open called.\n");
+	}
+
+        return(0);
+
+}
+
+static int hcl_close(struct inode * inode, struct file * filp)
+{
+
+	if (hcl_debug) {
+        	printk("HCL: hcl_close called.\n");
+	}
+
+        return(0);
+
+}
+
+static int hcl_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	if (hcl_debug) {
+		printk("HCL: hcl_ioctl called.\n");
+	}
+
+	switch (cmd) {
+		default:
+			if (hcl_debug) {
+				printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd);
+			}
+	}
+
+	return(0);
+
+}
+
+struct file_operations hcl_fops = {
+	(struct module *)0,
+	NULL,		/* lseek - default */
+	NULL,		/* read - general block-dev read */
+	NULL,		/* write - general block-dev write */
+	NULL,		/* readdir - bad */
+	NULL,		/* poll */
+	hcl_ioctl,      /* ioctl */
+	NULL,		/* mmap */
+	hcl_open,	/* open */
+	NULL,		/* flush */
+	hcl_close,	/* release */
+	NULL,		/* fsync */
+	NULL,		/* fasync */
+	NULL,		/* lock */
+	NULL,		/* readv */
+	NULL,		/* writev */
+};
+
+
+/*
+ * init_hcl() - Boot time initialization.  Ensure that it is called 
+ *	after devfs has been initialized.
+ *
+ * For now this routine is being called out of devfs/base.c.  Actually 
+ * Not a bad place to be ..
+ *
+ */
+int __init init_hcl(void)
+{
+	extern void string_table_init(struct string_table *);
+	extern struct string_table label_string_table;
+	extern int init_ifconfig_net(void);
+	extern int init_ioconfig_bus(void);
+	int status = 0;
+	int rv = 0;
+
+	if (IS_RUNNING_ON_SIMULATOR()) {
+		extern u64 klgraph_addr[];
+		klgraph_addr[0] = 0xe000003000030000;
+	}
+
+	/*
+	 * Create the hwgraph_root on devfs.
+	 */
+	rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
+	if (rv)
+		printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
+
+	status = devfs_set_flags (hwgraph_root, DEVFS_FL_HIDE);
+
+	/*
+	 * Create the hcl driver to support inventory entry manipulations.
+	 * By default, it is expected that devfs is mounted on /dev.
+	 *
+	 */
+	hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
+			0, DEVFS_FL_AUTO_DEVNUM,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&hcl_fops, NULL);
+
+	if (hcl_handle == NULL) {
+		panic("HCL: Unable to create HCL Driver in init_hcl().\n");
+		return(0);
+	}
+
+	/*
+	 * Initialize the HCL string table.
+	 */
+	string_table_init(&label_string_table);
+
+	/*
+	 * Create the directory that links Linux bus numbers to our Xwidget.
+	 */
+	rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
+	if (linux_busnum == NULL) {
+		panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
+		return(0);
+	}
+
+	pci_bus_cvlink_init();
+
+	/*
+	 * Initialize the ifconfgi_net driver that does network devices 
+	 * Persistent Naming.
+	 */
+	init_ifconfig_net();
+	init_ioconfig_bus();
+
+	return(0);
+
+}
+
+
+/*
+ * hcl_setup() - Process boot time parameters if given.
+ *	"hcl="
+ *	This routine gets called only if "hcl=" is given in the 
+ *	boot line and before init_hcl().
+ *
+ *	We currently do not have any boot options .. when we do, 
+ *	functionalities can be added here.
+ *
+ */
+static int __init hcl_setup(char *str)
+{
+    while ( (*str != '\0') && !isspace (*str) )
+    {
+#ifdef CONFIG_HCL_DEBUG
+        if (strncmp (str, "all", 3) == 0) {
+            hcl_debug_init |= HCL_DEBUG_ALL;
+            str += 3;
+        } else 
+        	return 0;
+#endif
+        if (*str != ',') return 0;
+        ++str;
+    }
+
+    return 1;
+
+}
+
+__setup("hcl=", hcl_setup);
+
+
+/*
+ * Set device specific "fast information".
+ *
+ */
+void
+hwgraph_fastinfo_set(vertex_hdl_t de, arbitrary_info_t fastinfo)
+{
+	labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
+}
+
+
+/*
+ * Get device specific "fast information".
+ *
+ */
+arbitrary_info_t
+hwgraph_fastinfo_get(vertex_hdl_t de)
+{
+	arbitrary_info_t fastinfo;
+	int rv;
+
+	if (!de) {
+		printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
+		return(-1);
+	}
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo);
+	if (rv == 0)
+		return(fastinfo);
+
+	return(0);
+}
+
+
+/*
+ * hwgraph_connectpt_set - Sets the connect point handle in de to the 
+ *	given connect_de handle.  By default, the connect point of the 
+ *	devfs node is the parent.  This effectively changes this assumption.
+ */
+int
+hwgraph_connectpt_set(vertex_hdl_t de, vertex_hdl_t connect_de)
+{
+	int rv;
+
+	if (!de)
+		return(-1);
+
+	rv = labelcl_info_connectpt_set(de, connect_de);
+
+	return(rv);
+}
+
+
+/*
+ * hwgraph_connectpt_get: Returns the entry's connect point  in the devfs 
+ *	tree.
+ */
+vertex_hdl_t
+hwgraph_connectpt_get(vertex_hdl_t de)
+{
+	int rv;
+	arbitrary_info_t info;
+	vertex_hdl_t connect;
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
+	if (rv != 0) {
+		return(NULL);
+	}
+
+	connect = (vertex_hdl_t)info;
+	return(connect);
+
+}
+
+
+/*
+ * hwgraph_mk_dir - Creates a directory entry with devfs.
+ *	Note that a directory entry in devfs can have children 
+ *	but it cannot be a char|block special file.
+ */
+vertex_hdl_t
+hwgraph_mk_dir(vertex_hdl_t de, const char *name,
+                unsigned int namelen, void *info)
+{
+
+	int rv;
+	labelcl_info_t *labelcl_info = NULL;
+	vertex_hdl_t new_devfs_handle = NULL;
+	vertex_hdl_t parent = NULL;
+
+	/*
+	 * Create the device info structure for hwgraph compatiblity support.
+	 */
+	labelcl_info = labelcl_info_create();
+	if (!labelcl_info)
+		return(NULL);
+
+	/*
+	 * Create a devfs entry.
+	 */
+	new_devfs_handle = devfs_mk_dir(de, name, (void *)labelcl_info);
+	if (!new_devfs_handle) {
+		labelcl_info_destroy(labelcl_info);
+		return(NULL);
+	}
+
+	/*
+	 * Get the parent handle.
+	 */
+	parent = devfs_get_parent (new_devfs_handle);
+
+	/*
+	 * To provide the same semantics as the hwgraph, set the connect point.
+	 */
+	rv = hwgraph_connectpt_set(new_devfs_handle, parent);
+	if (!rv) {
+		/*
+		 * We need to clean up!
+		 */
+	}
+
+	/*
+	 * If the caller provides a private data pointer, save it in the 
+	 * labelcl info structure(fastinfo).  This can be retrieved via
+	 * hwgraph_fastinfo_get()
+	 */
+	if (info)
+		hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
+		
+	return(new_devfs_handle);
+
+}
+
+/*
+ * hwgraph_path_add - Create a directory node with the given path starting 
+ * from the given vertex_hdl_t.
+ */
+int
+hwgraph_path_add(vertex_hdl_t  fromv,
+		 char *path,
+		 vertex_hdl_t *new_de)
+{
+
+	unsigned int	namelen = strlen(path);
+	int		rv;
+
+	/*
+	 * We need to handle the case when fromv is NULL ..
+	 * in this case we need to create the path from the 
+	 * hwgraph root!
+	 */
+	if (fromv == NULL)
+		fromv = hwgraph_root;
+
+	/*
+	 * check the entry doesn't already exist, if it does
+	 * then we simply want new_de to point to it (otherwise
+	 * we'll overwrite the existing labelcl_info struct)
+	 */
+	rv = hwgraph_edge_get(fromv, path, new_de);
+	if (rv)	{	/* couldn't find entry so we create it */
+		*new_de = hwgraph_mk_dir(fromv, path, namelen, NULL);
+		if (new_de == NULL)
+			return(-1);
+		else
+			return(0);
+	}
+	else 
+ 		return(0);
+
+}
+
+/*
+ * hwgraph_register  - Creates a file entry with devfs.
+ *	Note that a file entry cannot have children .. it is like a 
+ *	char|block special vertex in hwgraph.
+ */
+vertex_hdl_t
+hwgraph_register(vertex_hdl_t de, const char *name,
+                unsigned int namelen, unsigned int flags, 
+		unsigned int major, unsigned int minor,
+                umode_t mode, uid_t uid, gid_t gid, 
+		struct file_operations *fops,
+                void *info)
+{
+
+        vertex_hdl_t new_devfs_handle = NULL;
+
+        /*
+         * Create a devfs entry.
+         */
+        new_devfs_handle = devfs_register(de, name, flags, major,
+				minor, mode, fops, info);
+        if (!new_devfs_handle) {
+                return(NULL);
+        }
+
+        return(new_devfs_handle);
+
+}
+
+
+/*
+ * hwgraph_mk_symlink - Create a symbolic link.
+ */
+int
+hwgraph_mk_symlink(vertex_hdl_t de, const char *name, unsigned int namelen,
+                unsigned int flags, const char *link, unsigned int linklen, 
+		vertex_hdl_t *handle, void *info)
+{
+
+	void *labelcl_info = NULL;
+	int status = 0;
+	vertex_hdl_t new_devfs_handle = NULL;
+
+	/*
+	 * Create the labelcl info structure for hwgraph compatiblity support.
+	 */
+	labelcl_info = labelcl_info_create();
+	if (!labelcl_info)
+		return(-1);
+
+	/*
+	 * Create a symbolic link devfs entry.
+	 */
+	status = devfs_mk_symlink(de, name, flags, link,
+				&new_devfs_handle, labelcl_info);
+	if ( (!new_devfs_handle) || (!status) ){
+		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
+		return(-1);
+	}
+
+	/*
+	 * If the caller provides a private data pointer, save it in the 
+	 * labelcl info structure(fastinfo).  This can be retrieved via
+	 * hwgraph_fastinfo_get()
+	 */
+	if (info)
+		hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
+
+	*handle = new_devfs_handle;
+	return(0);
+
+}
+
+/*
+ * hwgraph_vertex_destroy - Destroy the devfs entry
+ */
+int
+hwgraph_vertex_destroy(vertex_hdl_t de)
+{
+
+	void *labelcl_info = NULL;
+
+	labelcl_info = devfs_get_info(de);
+	devfs_unregister(de);
+
+	if (labelcl_info)
+		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
+
+	return(0);
+}
+
+/*
+ * hwgraph_edge_add - This routines has changed from the original conext.
+ * All it does now is to create a symbolic link from "from" to "to".
+ */
+/* ARGSUSED */
+int
+hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
+{
+
+	char *path;
+	char *s1;
+	char *index;
+	int name_start;
+	vertex_hdl_t handle = NULL;
+	int rv;
+	int i, count;
+
+	path = kmalloc(1024, GFP_KERNEL);
+	memset(path, 0x0, 1024);
+	name_start = devfs_generate_path (from, path, 1024);
+	s1 = &path[name_start];
+	count = 0;
+	while (1) {
+		index = strstr (s1, "/");
+		if (index) {
+			count++;
+			s1 = ++index;
+		} else {
+			count++;
+			break;
+		}
+	}
+
+	memset(path, 0x0, 1024);
+	name_start = devfs_generate_path (to, path, 1024);
+
+	for (i = 0; i < count; i++) {
+		strcat(path,"../");
+	}
+
+	strcat(path, &path[name_start]);
+
+	/*
+	 * Otherwise, just create a symlink to the vertex.
+	 * In this case the vertex was previous created with a REAL pathname.
+	 */
+	rv = devfs_mk_symlink (from, (const char *)name, 
+			       DEVFS_FL_DEFAULT, path,
+			       &handle, NULL);
+
+	name_start = devfs_generate_path (handle, path, 1024);
+	return(rv);
+
+	
+}
+/* ARGSUSED */
+int
+hwgraph_edge_get(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
+{
+
+	int namelen = 0;
+	vertex_hdl_t target_handle = NULL;
+
+	if (name == NULL)
+		return(-1);
+
+	if (toptr == NULL)
+		return(-1);
+
+	/*
+	 * If the name is "." just return the current devfs entry handle.
+	 */
+	if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {
+		if (toptr) {
+			*toptr = from;
+		}
+	} else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {
+		/*
+		 * Hmmm .. should we return the connect point or parent ..
+		 * see in hwgraph, the concept of parent is the connectpt!
+		 *
+		 * Maybe we should see whether the connectpt is set .. if 
+		 * not just return the parent!
+		 */
+		target_handle = hwgraph_connectpt_get(from);
+		if (target_handle) {
+			/*
+			 * Just return the connect point.
+			 */
+			*toptr = target_handle;
+			return(0);
+		}
+		target_handle = devfs_get_parent(from);
+		*toptr = target_handle;
+
+	} else {
+		/*
+		 * Call devfs to get the devfs entry.
+		 */
+		namelen = (int) strlen(name);
+		target_handle = devfs_find_handle (from, name, 0, 0,
+					0, 1); /* Yes traverse symbolic links */
+		if (target_handle == NULL)
+			return(-1);
+		else
+		*toptr = target_handle;
+	}
+
+	return(0);
+}
+
+/*
+ * hwgraph_info_add_LBL - Adds a new label for the device.  Mark the info_desc
+ *	of the label as INFO_DESC_PRIVATE and store the info in the label.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_add_LBL(	vertex_hdl_t de,
+			char *name,
+			arbitrary_info_t info)
+{
+	return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));
+}
+
+/*
+ * hwgraph_info_remove_LBL - Remove the label entry for the device.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_remove_LBL(	vertex_hdl_t de,
+				char *name,
+				arbitrary_info_t *old_info)
+{
+	return(labelcl_info_remove_LBL(de, name, NULL, old_info));
+}
+
+/*
+ * hwgraph_info_replace_LBL - replaces an existing label with 
+ *	a new label info value.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_replace_LBL(	vertex_hdl_t de,
+				char *name,
+				arbitrary_info_t info,
+				arbitrary_info_t *old_info)
+{
+	return(labelcl_info_replace_LBL(de, name,
+			INFO_DESC_PRIVATE, info,
+			NULL, old_info));
+}
+/*
+ * hwgraph_info_get_LBL - Get and return the info value in the label of the 
+ * 	device.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_LBL(	vertex_hdl_t de,
+			char *name,
+			arbitrary_info_t *infop)
+{
+	return(labelcl_info_get_LBL(de, name, NULL, infop));
+}
+
+/*
+ * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer 
+ *	of the given label for the device.  The weird thing is that the label 
+ *	that matches the name is return irrespective of the info_desc value!
+ *	Do not understand why the word "exported" is used!
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_exported_LBL(	vertex_hdl_t de,
+				char *name,
+				int *export_info,
+				arbitrary_info_t *infop)
+{
+	int rc;
+	arb_info_desc_t info_desc;
+
+	rc = labelcl_info_get_LBL(de, name, &info_desc, infop);
+	if (rc == 0)
+		*export_info = (int)info_desc;
+
+	return(rc);
+}
+
+/*
+ * hwgraph_info_get_next_LBL - Returns the next label info given the 
+ *	current label entry in place.
+ *
+ *	Once again this has no locking or reference count for protection.
+ *
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_next_LBL(	vertex_hdl_t de,
+				char *buf,
+				arbitrary_info_t *infop,
+				labelcl_info_place_t *place)
+{
+	return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));
+}
+
+/*
+ * hwgraph_info_export_LBL - Retrieve the specified label entry and modify 
+ *	the info_desc field with the given value in nbytes.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_export_LBL(vertex_hdl_t de, char *name, int nbytes)
+{
+	arbitrary_info_t info;
+	int rc;
+
+	if (nbytes == 0)
+		nbytes = INFO_DESC_EXPORT;
+
+	if (nbytes < 0)
+		return(-1);
+
+	rc = labelcl_info_get_LBL(de, name, NULL, &info);
+	if (rc != 0)
+		return(rc);
+
+	rc = labelcl_info_replace_LBL(de, name,
+				nbytes, info, NULL, NULL);
+
+	return(rc);
+}
+
+/*
+ * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the 
+ * label info_descr filed to INFO_DESC_PRIVATE.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_unexport_LBL(vertex_hdl_t de, char *name)
+{
+	arbitrary_info_t info;
+	int rc;
+
+	rc = labelcl_info_get_LBL(de, name, NULL, &info);
+	if (rc != 0)
+		return(rc);
+
+	rc = labelcl_info_replace_LBL(de, name,
+				INFO_DESC_PRIVATE, info, NULL, NULL);
+
+	return(rc);
+}
+
+/*
+ * hwgraph_path_lookup - return the handle for the given path.
+ *
+ */
+int
+hwgraph_path_lookup(	vertex_hdl_t start_vertex_handle,
+			char *lookup_path,
+			vertex_hdl_t *vertex_handle_ptr,
+			char **remainder)
+{
+	*vertex_handle_ptr = devfs_find_handle(start_vertex_handle,	/* start dir */
+					lookup_path,		/* path */
+					0,			/* major */
+					0,			/* minor */
+					0,			/* char | block */
+					1);			/* traverse symlinks */
+	if (*vertex_handle_ptr == NULL)
+		return(-1);
+	else
+		return(0);
+}
+
+/*
+ * hwgraph_traverse - Find and return the devfs handle starting from de.
+ *
+ */
+graph_error_t
+hwgraph_traverse(vertex_hdl_t de, char *path, vertex_hdl_t *found)
+{
+	/* 
+	 * get the directory entry (path should end in a directory)
+	 */
+
+	*found = devfs_find_handle(de,	/* start dir */
+			    path,	/* path */
+			    0,		/* major */
+			    0,		/* minor */
+			    0,		/* char | block */
+			    1);		/* traverse symlinks */
+	if (*found == NULL)
+		return(GRAPH_NOT_FOUND);
+	else
+		return(GRAPH_SUCCESS);
+}
+
+/*
+ * hwgraph_path_to_vertex - Return the devfs entry handle for the given 
+ *	pathname .. assume traverse symlinks too!.
+ */
+vertex_hdl_t
+hwgraph_path_to_vertex(char *path)
+{
+	return(devfs_find_handle(NULL,	/* start dir */
+			path,		/* path */
+		    	0,		/* major */
+		    	0,		/* minor */
+		    	0,		/* char | block */
+		    	1));		/* traverse symlinks */
+}
+
+/*
+ * hwgraph_inventory_remove - Removes an inventory entry.
+ *
+ *	Remove an inventory item associated with a vertex.   It is the caller's
+ *	responsibility to make sure that there are no races between removing
+ *	inventory from a vertex and simultaneously removing that vertex.
+*/
+int
+hwgraph_inventory_remove(	vertex_hdl_t de,
+				int class,
+				int type,
+				major_t controller,
+				minor_t unit,
+				int state)
+{
+	return(0); /* Just a Stub for IRIX code. */
+}
+
+/*
+ * Find the canonical name for a given vertex by walking back through
+ * connectpt's until we hit the hwgraph root vertex (or until we run
+ * out of buffer space or until something goes wrong).
+ *
+ *	COMPATIBILITY FUNCTIONALITY
+ * Walks back through 'parents', not necessarily the same as connectpts.
+ *
+ * Need to resolve the fact that devfs does not return the path from 
+ * "/" but rather it just stops right before /dev ..
+ */
+int
+hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen)
+{
+	char *locbuf;
+	int   pos;
+
+	if (buflen < 1)
+		return(-1);	/* XXX should be GRAPH_BAD_PARAM ? */
+
+	locbuf = kmalloc(buflen, GFP_KERNEL);
+
+	pos = devfs_generate_path(vhdl, locbuf, buflen);
+	if (pos < 0) {
+		kfree(locbuf);
+		return pos;
+	}
+
+	strcpy(buf, &locbuf[pos]);
+	kfree(locbuf);
+	return 0;
+}
+
+/*
+** vertex_to_name converts a vertex into a canonical name by walking
+** back through connect points until we hit the hwgraph root (or until
+** we run out of buffer space).
+**
+** Usually returns a pointer to the original buffer, filled in as
+** appropriate.  If the buffer is too small to hold the entire name,
+** or if anything goes wrong while determining the name, vertex_to_name
+** returns "UnknownDevice".
+*/
+
+#define DEVNAME_UNKNOWN "UnknownDevice"
+
+char *
+vertex_to_name(vertex_hdl_t vhdl, char *buf, uint buflen)
+{
+	if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)
+		return(buf);
+	else
+		return(DEVNAME_UNKNOWN);
+}
+
+graph_error_t
+hwgraph_edge_remove(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
+{
+	printk("WARNING: hwgraph_edge_remove NOT supported.\n");
+	return(GRAPH_ILLEGAL_REQUEST);
+}
+
+graph_error_t
+hwgraph_vertex_unref(vertex_hdl_t vhdl)
+{
+	return(GRAPH_ILLEGAL_REQUEST);
+}
+
+
+EXPORT_SYMBOL(hwgraph_mk_dir);
+EXPORT_SYMBOL(hwgraph_path_add);
+EXPORT_SYMBOL(hwgraph_register);
+EXPORT_SYMBOL(hwgraph_vertex_destroy);
+EXPORT_SYMBOL(hwgraph_fastinfo_get);
+EXPORT_SYMBOL(hwgraph_fastinfo_set);
+EXPORT_SYMBOL(hwgraph_connectpt_set);
+EXPORT_SYMBOL(hwgraph_connectpt_get);
+EXPORT_SYMBOL(hwgraph_info_add_LBL);
+EXPORT_SYMBOL(hwgraph_info_remove_LBL);
+EXPORT_SYMBOL(hwgraph_info_replace_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_next_LBL);
+EXPORT_SYMBOL(hwgraph_info_export_LBL);
+EXPORT_SYMBOL(hwgraph_info_unexport_LBL);
+EXPORT_SYMBOL(hwgraph_path_lookup);
+EXPORT_SYMBOL(hwgraph_traverse);
+EXPORT_SYMBOL(hwgraph_vertex_name_get);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgdfs/hcl_util.c linux-2.4.22-pre3/arch/ia64/sn/io/hwgdfs/hcl_util.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgdfs/hcl_util.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgdfs/hcl_util.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,200 @@
+/* $Id: hcl_util.c,v 1.3 2003/04/24 13:59:39 pfg Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/sn/sgi.h>
+#include <asm/io.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/nodepda.h>
+
+static vertex_hdl_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE;
+extern vertex_hdl_t hwgraph_root;
+
+
+/*
+** Return the "master" for a given vertex.  A master vertex is a
+** controller or adapter or other piece of hardware that the given
+** vertex passes through on the way to the rest of the system.
+*/
+vertex_hdl_t
+device_master_get(vertex_hdl_t vhdl)
+{
+	graph_error_t rc;
+	vertex_hdl_t master;
+
+	rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master);
+	if (rc == GRAPH_SUCCESS)
+		return(master);
+	else
+		return(GRAPH_VERTEX_NONE);
+}
+
+/*
+** Set the master for a given vertex.
+** Returns 0 on success, non-0 indicates failure
+*/
+int
+device_master_set(vertex_hdl_t vhdl, vertex_hdl_t master)
+{
+	graph_error_t rc;
+
+	rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER);
+	return(rc != GRAPH_SUCCESS);
+}
+
+
+/*
+** Return the compact node id of the node that ultimately "owns" the specified
+** vertex.  In order to do this, we walk back through masters and connect points
+** until we reach a vertex that represents a node.
+*/
+cnodeid_t
+master_node_get(vertex_hdl_t vhdl)
+{
+	cnodeid_t cnodeid;
+	vertex_hdl_t master;
+
+	for (;;) {
+		cnodeid = nodevertex_to_cnodeid(vhdl);
+		if (cnodeid != CNODEID_NONE)
+			return(cnodeid);
+
+		master = device_master_get(vhdl);
+
+		/* Check for exceptional cases */
+		if (master == vhdl) {
+			/* Since we got a reference to the "master" thru
+			 * device_master_get() we should decrement
+			 * its reference count by 1
+			 */
+			return(CNODEID_NONE);
+		}
+
+		if (master == GRAPH_VERTEX_NONE) {
+			master = hwgraph_connectpt_get(vhdl);
+			if ((master == GRAPH_VERTEX_NONE) ||
+			    (master == vhdl)) {
+				return(CNODEID_NONE);
+			}
+		}
+
+		vhdl = master;
+	}
+}
+
+static vertex_hdl_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
+extern int maxcpus;
+
+void
+mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid)
+{
+	if (cpuid == CPU_NONE)
+		return;
+
+	(void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT,
+			(arbitrary_info_t)cpuid);
+	{
+		char cpuid_buffer[10];
+
+		if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) {
+			(void)hwgraph_path_add( hwgraph_root,
+						EDGE_LBL_CPUNUM,
+						&hwgraph_all_cpuids);
+		}
+
+		sprintf(cpuid_buffer, "%ld", cpuid);
+		(void)hwgraph_edge_add( hwgraph_all_cpuids,
+							vhdl,
+							cpuid_buffer);
+	}
+}
+
+/*
+** If the specified device represents a node, return its
+** compact node ID; otherwise, return CNODEID_NONE.
+*/
+cnodeid_t
+nodevertex_to_cnodeid(vertex_hdl_t vhdl)
+{
+	int rv = 0;
+	arbitrary_info_t cnodeid = CNODEID_NONE;
+
+	rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid);
+
+	return((cnodeid_t)cnodeid);
+}
+
+void
+mark_nodevertex_as_node(vertex_hdl_t vhdl, cnodeid_t cnodeid)
+{
+	if (cnodeid == CNODEID_NONE)
+		return;
+
+	cnodeid_to_vertex(cnodeid) = vhdl;
+	labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, 
+		(arbitrary_info_t)cnodeid);
+
+	{
+		char cnodeid_buffer[10];
+
+		if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) {
+			(void)hwgraph_path_add( hwgraph_root,
+						EDGE_LBL_NODENUM,
+						&hwgraph_all_cnodes);
+		}
+
+		sprintf(cnodeid_buffer, "%d", cnodeid);
+		(void)hwgraph_edge_add( hwgraph_all_cnodes,
+					vhdl,
+					cnodeid_buffer);
+	}
+}
+
+/*
+** If the specified device represents a CPU, return its cpuid;
+** otherwise, return CPU_NONE.
+*/
+cpuid_t
+cpuvertex_to_cpuid(vertex_hdl_t vhdl)
+{
+	arbitrary_info_t cpuid = CPU_NONE;
+
+	(void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid);
+
+	return((cpuid_t)cpuid);
+}
+
+
+/*
+** dev_to_name converts a vertex_hdl_t into a canonical name.  If the vertex_hdl_t
+** represents a vertex in the hardware graph, it is converted in the
+** normal way for vertices.  If the vertex_hdl_t is an old vertex_hdl_t (one which
+** does not represent a hwgraph vertex), we synthesize a name based
+** on major/minor number.
+**
+** Usually returns a pointer to the original buffer, filled in as
+** appropriate.  If the buffer is too small to hold the entire name,
+** or if anything goes wrong while determining the name, dev_to_name
+** returns "UnknownDevice".
+*/
+char *
+dev_to_name(vertex_hdl_t dev, char *buf, uint buflen)
+{
+        return(vertex_to_name(dev, buf, buflen));
+}
+
+
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgdfs/invent_stub.c linux-2.4.22-pre3/arch/ia64/sn/io/hwgdfs/invent_stub.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgdfs/invent_stub.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgdfs/invent_stub.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,146 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+/*
+ * Hardware Inventory
+ *
+ * See sys/sn/invent.h for an explanation of the hardware inventory contents.
+ *
+ */
+#include <linux/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+
+void
+inventinit(void)
+{
+}
+
+/*
+ * For initializing/updating an inventory entry.
+ */
+void
+replace_in_inventory(
+	inventory_t *pinv, int class, int type,
+	int controller, int unit, int state)
+{
+}
+
+/*
+ * Inventory addition 
+ *
+ * XXX NOTE: Currently must be called after dynamic memory allocator is
+ * initialized.
+ *
+ */
+void
+add_to_inventory(int class, int type, int controller, int unit, int state)
+{
+}
+
+
+/*
+ * Inventory retrieval 
+ *
+ * These two routines are intended to prevent the caller from having to know
+ * the internal structure of the inventory table.
+ *
+ * The caller of get_next_inventory is supposed to call start_scan_invent
+ * before the irst call to get_next_inventory, and the caller is required
+ * to call end_scan_invent after the last call to get_next_inventory.
+ */
+inventory_t *
+get_next_inventory(invplace_t *place)
+{
+	return((inventory_t *) NULL);
+}
+
+/* ARGSUSED */
+int
+get_sizeof_inventory(int abi)
+{
+	return sizeof(inventory_t);
+}
+
+/* Must be called prior to first call to get_next_inventory */
+void
+start_scan_inventory(invplace_t *iplace)
+{
+}
+
+/* Must be called after last call to get_next_inventory */
+void
+end_scan_inventory(invplace_t *iplace)
+{
+}
+
+/*
+ * Hardware inventory scanner.
+ *
+ * Calls fun() for every entry in inventory list unless fun() returns something
+ * other than 0.
+ */
+int
+scaninvent(int (*fun)(inventory_t *, void *), void *arg)
+{
+	return 0;
+}
+
+/*
+ * Find a particular inventory object
+ *
+ * pinv can be a pointer to an inventory entry and the search will begin from
+ * there, or it can be 0 in which case the search starts at the beginning.
+ * A -1 for any of the other arguments is a wildcard (i.e. it always matches).
+ */
+inventory_t *
+find_inventory(inventory_t *pinv, int class, int type, int controller,
+	       int unit, int state)
+{
+	return((inventory_t *) NULL);
+}
+
+
+/*
+** Retrieve inventory data associated with a device.
+*/
+inventory_t *
+device_inventory_get_next(	vertex_hdl_t device,
+				invplace_t *invplace)
+{
+		return((inventory_t *) NULL);
+}
+
+
+/*
+** Associate canonical inventory information with a device (and
+** add it to the general inventory).
+*/
+void
+device_inventory_add(	vertex_hdl_t device,
+			int class, 
+			int type, 
+			major_t controller, 
+			minor_t unit, 
+			int state)
+{
+}
+
+int
+device_controller_num_get(vertex_hdl_t device)
+{
+	return (0);
+}
+
+void
+device_controller_num_set(vertex_hdl_t device, int contr_num)
+{
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgdfs/labelcl.c linux-2.4.22-pre3/arch/ia64/sn/io/hwgdfs/labelcl.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgdfs/labelcl.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgdfs/labelcl.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,653 @@
+/*  labelcl - SGI's Hwgraph Compatibility Layer.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+*/
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+
+/*
+** Very simple and dumb string table that supports only find/insert.
+** In practice, if this table gets too large, we may need a more
+** efficient data structure.   Also note that currently there is no 
+** way to delete an item once it's added.  Therefore, name collision 
+** will return an error.
+*/
+
+struct string_table label_string_table;
+
+
+
+/*
+ * string_table_init - Initialize the given string table.
+ */
+void
+string_table_init(struct string_table *string_table)
+{
+	string_table->string_table_head = NULL;
+	string_table->string_table_generation = 0;
+
+	/*
+	 * We nedd to initialize locks here!
+	 */
+
+	return;
+}
+
+
+/*
+ * string_table_destroy - Destroy the given string table.
+ */
+void
+string_table_destroy(struct string_table *string_table)
+{
+	struct string_table_item *item, *next_item;
+
+	item = string_table->string_table_head;
+	while (item) {
+		next_item = item->next;
+
+		STRTBL_FREE(item);
+		item = next_item;
+	}
+
+	/*
+	 * We need to destroy whatever lock we have here
+	 */
+
+	return;
+}
+
+
+
+/*
+ * string_table_insert - Insert an entry in the string table .. duplicate 
+ *	names are not allowed.
+ */
+char *
+string_table_insert(struct string_table *string_table, char *name)
+{
+	struct string_table_item *item, *new_item = NULL, *last_item = NULL;
+
+again:
+	/*
+	 * Need to lock the table ..
+	 */
+	item = string_table->string_table_head;
+	last_item = NULL;
+
+	while (item) {
+		if (!strcmp(item->string, name)) {
+			/*
+			 * If we allocated space for the string and the found that
+			 * someone else already entered it into the string table,
+			 * free the space we just allocated.
+			 */
+			if (new_item)
+				STRTBL_FREE(new_item);
+
+
+			/*
+			 * Search optimization: move the found item to the head
+			 * of the list.
+			 */
+			if (last_item != NULL) {
+				last_item->next = item->next;
+				item->next = string_table->string_table_head;
+				string_table->string_table_head = item;
+			}
+			goto out;
+		}
+		last_item = item;
+		item=item->next;
+	}
+
+	/*
+	 * name was not found, so add it to the string table.
+	 */
+	if (new_item == NULL) {
+		long old_generation = string_table->string_table_generation;
+
+		new_item = STRTBL_ALLOC(strlen(name));
+
+		strcpy(new_item->string, name);
+
+		/*
+		 * While we allocated memory for the new string, someone else 
+		 * changed the string table.
+		 */
+		if (old_generation != string_table->string_table_generation) {
+			goto again;
+		}
+	} else {
+		/* At this we only have the string table lock in access mode.
+		 * Promote the access lock to an update lock for the string
+		 * table insertion below.
+		 */
+			long old_generation = 
+				string_table->string_table_generation;
+
+			/*
+			 * After we did the unlock and wer waiting for update
+			 * lock someone could have potentially updated
+			 * the string table. Check the generation number
+			 * for this case. If it is the case we have to
+			 * try all over again.
+			 */
+			if (old_generation != 
+			    string_table->string_table_generation) {
+				goto again;
+			}
+		}
+
+	/*
+	 * At this point, we're committed to adding new_item to the string table.
+	 */
+	new_item->next = string_table->string_table_head;
+	item = string_table->string_table_head = new_item;
+	string_table->string_table_generation++;
+
+out:
+	/*
+	 * Need to unlock here.
+	 */
+	return(item->string);
+}
+
+/*
+ * labelcl_info_create - Creates the data structure that will hold the
+ *	device private information asscoiated with a devfs entry.
+ *	The pointer to this structure is what gets stored in the devfs 
+ *	(void * info).
+ */
+labelcl_info_t *
+labelcl_info_create()
+{
+
+	labelcl_info_t *new = NULL;
+
+	/* Initial allocation does not include any area for labels */
+	if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL )
+		return NULL;
+
+	memset (new, 0, sizeof(labelcl_info_t));
+	new->hwcl_magic = LABELCL_MAGIC;
+	return( new);
+
+}
+
+/*
+ * labelcl_info_destroy - Frees the data structure that holds the
+ *      device private information asscoiated with a devfs entry.  This 
+ *	data structure was created by device_info_create().
+ *
+ *	The caller is responsible for nulling the (void *info) in the 
+ *	corresponding devfs entry.
+ */
+int
+labelcl_info_destroy(labelcl_info_t *labelcl_info)
+{
+
+	if (labelcl_info == NULL)
+		return(0);
+
+	/* Free the label list */
+	if (labelcl_info->label_list)
+		kfree(labelcl_info->label_list);
+
+	/* Now free the label info area */
+	labelcl_info->hwcl_magic = 0;
+	kfree(labelcl_info);
+
+	return(0);
+}
+
+/*
+ * labelcl_info_add_LBL - Adds a new label entry in the labelcl info 
+ *	structure.
+ *
+ *	Error is returned if we find another label with the same name.
+ */
+int
+labelcl_info_add_LBL(vertex_hdl_t de,
+			char *info_name,
+			arb_info_desc_t info_desc,
+			arbitrary_info_t info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	int new_label_list_size;
+	label_info_t *old_label_list, *new_label_list = NULL;
+	char *name;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+        labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if (info_name == NULL)
+		return(-1);
+
+	if (strlen(info_name) >= LABEL_LENGTH_MAX)
+		return(-1);
+
+	name = string_table_insert(&label_string_table, info_name);
+
+	num_labels = labelcl_info->num_labels;
+	new_label_list_size = sizeof(label_info_t) * (num_labels+1);
+
+	/*
+	 * Create a new label info area.
+	 */
+	if (new_label_list_size != 0) {
+		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
+
+		if (new_label_list == NULL)
+			return(-1);
+	}
+
+	/*
+	 * At this point, we are committed to adding the labelled info, 
+	 * if there isn't already information there with the same name.
+	 */
+	old_label_list = labelcl_info->label_list;
+
+	/* 
+	 * Look for matching info name.
+	 */
+	for (i=0; i<num_labels; i++) {
+		if (!strcmp(info_name, old_label_list[i].name)) {
+			/* Not allowed to add duplicate labelled info names. */
+			kfree(new_label_list);
+			return(-1);
+		}
+		new_label_list[i] = old_label_list[i]; /* structure copy */
+	}
+
+	new_label_list[num_labels].name = name;
+	new_label_list[num_labels].desc = info_desc;
+	new_label_list[num_labels].info = info;
+
+	labelcl_info->num_labels = num_labels+1;
+	labelcl_info->label_list = new_label_list;
+
+	if (old_label_list != NULL)
+		kfree(old_label_list);
+
+	return(0);
+}
+
+/*
+ * labelcl_info_remove_LBL - Remove a label entry.
+ */
+int
+labelcl_info_remove_LBL(vertex_hdl_t de,
+			 char *info_name,
+			 arb_info_desc_t *info_desc,
+			 arbitrary_info_t *info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	int new_label_list_size;
+	label_info_t *old_label_list, *new_label_list = NULL;
+	arb_info_desc_t label_desc_found;
+	arbitrary_info_t label_info_found;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	/*
+	 * Create a new info area.
+	 */
+	new_label_list_size = sizeof(label_info_t) * (num_labels-1);
+	if (new_label_list_size) {
+		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
+		if (new_label_list == NULL)
+			return(-1);
+	}
+
+	/*
+	 * At this point, we are committed to removing the labelled info, 
+	 * if it still exists.
+	 */
+	old_label_list = labelcl_info->label_list;
+
+	/* 
+	 * Find matching info name.
+	 */
+	for (i=0; i<num_labels; i++) {
+		if (!strcmp(info_name, old_label_list[i].name)) {
+			label_desc_found = old_label_list[i].desc;
+			label_info_found = old_label_list[i].info;
+			goto found;
+		}
+		if (i < num_labels-1) /* avoid walking off the end of the new vertex */
+			new_label_list[i] = old_label_list[i]; /* structure copy */
+	}
+
+	/* The named info doesn't exist. */
+	if (new_label_list)
+		kfree(new_label_list);
+
+	return(-1);
+
+found:
+	/* Finish up rest of labelled info */
+	for (i=i+1; i<num_labels; i++)
+		new_label_list[i-1] = old_label_list[i]; /* structure copy */
+
+	labelcl_info->num_labels = num_labels+1;
+	labelcl_info->label_list = new_label_list;
+
+	kfree(old_label_list);
+
+	if (info != NULL)
+		*info = label_info_found;
+
+	if (info_desc != NULL)
+		*info_desc = label_desc_found;
+
+	return(0);
+}
+
+
+/*
+ * labelcl_info_replace_LBL - Replace an existing label entry with the 
+ *	given new information.
+ *
+ *	Label entry must exist.
+ */
+int
+labelcl_info_replace_LBL(vertex_hdl_t de,
+			char *info_name,
+			arb_info_desc_t info_desc,
+			arbitrary_info_t info,
+			arb_info_desc_t *old_info_desc,
+			arbitrary_info_t *old_info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	label_info_t *label_list;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	if (info_name == NULL)
+		return(-1);
+
+	label_list = labelcl_info->label_list;
+
+	/* 
+	 * Verify that information under info_name already exists.
+	 */
+	for (i=0; i<num_labels; i++)
+		if (!strcmp(info_name, label_list[i].name)) {
+			if (old_info != NULL)
+				*old_info = label_list[i].info;
+
+			if (old_info_desc != NULL)
+				*old_info_desc = label_list[i].desc;
+
+			label_list[i].info = info;
+			label_list[i].desc = info_desc;
+
+			return(0);
+		}
+
+
+	return(-1);
+}
+
+/*
+ * labelcl_info_get_LBL - Retrieve and return the information for the 
+ *	given label entry.
+ */
+int
+labelcl_info_get_LBL(vertex_hdl_t de,
+		      char *info_name,
+		      arb_info_desc_t *info_desc,
+		      arbitrary_info_t *info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	label_info_t *label_list;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	label_list = labelcl_info->label_list;
+
+	/* 
+	 * Find information under info_name.
+	 */
+	for (i=0; i<num_labels; i++)
+		if (!strcmp(info_name, label_list[i].name)) {
+			if (info != NULL)
+				*info = label_list[i].info;
+			if (info_desc != NULL)
+				*info_desc = label_list[i].desc;
+
+			return(0);
+		}
+
+	return(-1);
+}
+
+/*
+ * labelcl_info_get_next_LBL - returns the next label entry on the list.
+ */
+int
+labelcl_info_get_next_LBL(vertex_hdl_t de,
+			   char *buffer,
+			   arb_info_desc_t *info_descp,
+			   arbitrary_info_t *infop,
+			   labelcl_info_place_t *placeptr)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	uint which_info;
+	label_info_t *label_list;
+
+	if ((buffer == NULL) && (infop == NULL))
+		return(-1);
+
+	if (placeptr == NULL)
+		return(-1);
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	which_info = *placeptr;
+
+	if (which_info >= labelcl_info->num_labels) {
+		return(-1);
+	}
+
+	label_list = (label_info_t *) labelcl_info->label_list;
+
+	if (buffer != NULL)
+		strcpy(buffer, label_list[which_info].name);
+
+	if (infop)
+		*infop = label_list[which_info].info;
+
+	if (info_descp)
+		*info_descp = label_list[which_info].desc;
+
+	*placeptr = which_info + 1;
+
+	return(0);
+}
+
+
+int
+labelcl_info_replace_IDX(vertex_hdl_t de,
+			int index,
+			arbitrary_info_t info,
+			arbitrary_info_t *old_info)
+{
+	arbitrary_info_t *info_list_IDX;
+	labelcl_info_t	*labelcl_info = NULL;
+
+	if (de == NULL) {
+		printk(KERN_ALERT "labelcl: NULL devfs handle given.\n");
+		return(-1);
+	}
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL) {
+		printk(KERN_ALERT "labelcl: Entry does not have info pointer.\n");
+		return(-1);
+	}
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
+		return(-1);
+
+	/*
+	 * Replace information at the appropriate index in this vertex with 
+	 * the new info.
+	 */
+	info_list_IDX = labelcl_info->IDX_list;
+	if (old_info != NULL)
+		*old_info = info_list_IDX[index];
+	info_list_IDX[index] = info;
+
+	return(0);
+
+}
+
+/*
+ * labelcl_info_connectpt_set - Sets the connectpt.
+ */
+int
+labelcl_info_connectpt_set(struct devfs_entry *de,
+			  struct devfs_entry *connect_de)
+{
+	arbitrary_info_t old_info;
+	int	rv;
+
+	rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, 
+		(arbitrary_info_t) connect_de, &old_info);
+
+	if (rv) {
+		return(rv);
+	}
+
+	return(0);
+}
+
+
+/*
+ * labelcl_info_get_IDX - Returns the information pointed at by index.
+ *
+ */
+int
+labelcl_info_get_IDX(vertex_hdl_t de,
+			int index,
+			arbitrary_info_t *info)
+{
+	arbitrary_info_t *info_list_IDX;
+	labelcl_info_t	*labelcl_info = NULL;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
+		return(-1);
+
+	/*
+	 * Return information at the appropriate index in this vertex.
+	 */
+	info_list_IDX = labelcl_info->IDX_list;
+	if (info != NULL)
+		*info = info_list_IDX[index];
+
+	return(0);
+}
+
+/*
+ * labelcl_info_connectpt_get - Retrieve the connect point for a device entry.
+ */
+struct devfs_entry *
+labelcl_info_connectpt_get(struct devfs_entry *de)
+{
+	int rv;
+	arbitrary_info_t info;
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
+	if (rv)
+		return(NULL);
+
+	return((struct devfs_entry *)info);
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/Makefile linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/Makefile	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,19 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+O_TARGET := snio.o
+
+export-objs := hcl.o ramfs.o interface.o
+
+obj-y				+= hcl.o labelcl.o hcl_util.o invent_stub.o \
+				   ramfs.o interface.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/hcl.c linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/hcl.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/hcl.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/hcl.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,938 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  hcl - SGI's Hardware Graph compatibility layer.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/sched.h>                /* needed for smp_lock.h :( */
+#include <linux/smp_lock.h>
+#include <asm/sn/sgi.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/simulator.h>
+
+#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER"
+#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE"
+#define HCL_TEMP_NAME_LEN 44 
+#define HCL_VERSION "1.0"
+
+#define vertex_hdl_t hwgfs_handle_t
+vertex_hdl_t hwgraph_root;
+vertex_hdl_t linux_busnum;
+
+extern void pci_bus_cvlink_init(void);
+
+/*
+ * Debug flag definition.
+ */
+#define OPTION_NONE             0x00
+#define HCL_DEBUG_NONE 0x00000
+#define HCL_DEBUG_ALL  0x0ffff
+#if defined(CONFIG_HCL_DEBUG)
+static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE;
+#endif
+static unsigned int hcl_debug = HCL_DEBUG_NONE;
+#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
+static unsigned int boot_options = OPTION_NONE;
+#endif
+
+/*
+ * Some Global definitions.
+ */
+vertex_hdl_t hcl_handle;
+
+invplace_t invplace_none = {
+	GRAPH_VERTEX_NONE,
+	GRAPH_VERTEX_PLACE_NONE,
+	NULL
+};
+
+/*
+ * HCL device driver.
+ * The purpose of this device driver is to provide a facility 
+ * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path 
+ * to manipulate label entries without having to implement
+ * system call interfaces.  This methodology will enable us to 
+ * make this feature module loadable.
+ */
+static int hcl_open(struct inode * inode, struct file * filp)
+{
+	if (hcl_debug) {
+        	printk("HCL: hcl_open called.\n");
+	}
+
+        return(0);
+
+}
+
+static int hcl_close(struct inode * inode, struct file * filp)
+{
+
+	if (hcl_debug) {
+        	printk("HCL: hcl_close called.\n");
+	}
+
+        return(0);
+
+}
+
+static int hcl_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	if (hcl_debug) {
+		printk("HCL: hcl_ioctl called.\n");
+	}
+
+	switch (cmd) {
+		default:
+			if (hcl_debug) {
+				printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd);
+			}
+	}
+
+	return(0);
+
+}
+
+struct file_operations hcl_fops = {
+	(struct module *)0,
+	NULL,		/* lseek - default */
+	NULL,		/* read - general block-dev read */
+	NULL,		/* write - general block-dev write */
+	NULL,		/* readdir - bad */
+	NULL,		/* poll */
+	hcl_ioctl,      /* ioctl */
+	NULL,		/* mmap */
+	hcl_open,	/* open */
+	NULL,		/* flush */
+	hcl_close,	/* release */
+	NULL,		/* fsync */
+	NULL,		/* fasync */
+	NULL,		/* lock */
+	NULL,		/* readv */
+	NULL,		/* writev */
+};
+
+
+/*
+ * init_hcl() - Boot time initialization.
+ *
+ */
+int __init init_hcl(void)
+{
+	extern void string_table_init(struct string_table *);
+	extern struct string_table label_string_table;
+	extern int init_ifconfig_net(void);
+	extern int init_ioconfig_bus(void);
+	extern int init_hwgfs_fs(void);
+	int rv = 0;
+
+	if (IS_RUNNING_ON_SIMULATOR()) {
+		extern u64 klgraph_addr[];
+		klgraph_addr[0] = 0xe000003000030000;
+	}
+
+	init_hwgfs_fs();
+
+	/*
+	 * Create the hwgraph_root.
+	 */
+	rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
+	if (rv)
+		printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
+
+	/*
+	 * Create the hcl driver to support inventory entry manipulations.
+	 *
+	 */
+	hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
+			0, DEVFS_FL_AUTO_DEVNUM,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&hcl_fops, NULL);
+
+	if (hcl_handle == NULL) {
+		panic("HCL: Unable to create HCL Driver in init_hcl().\n");
+		return(0);
+	}
+
+	/*
+	 * Initialize the HCL string table.
+	 */
+
+	string_table_init(&label_string_table);
+
+	/*
+	 * Create the directory that links Linux bus numbers to our Xwidget.
+	 */
+	rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
+	if (linux_busnum == NULL) {
+		panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
+		return(0);
+	}
+
+	pci_bus_cvlink_init();
+
+	/*
+	 * Initialize the ifconfgi_net driver that does network devices 
+	 * Persistent Naming.
+	 */
+	init_ifconfig_net();
+	init_ioconfig_bus();
+
+	return(0);
+
+}
+
+
+/*
+ * hcl_setup() - Process boot time parameters if given.
+ *	"hcl="
+ *	This routine gets called only if "hcl=" is given in the 
+ *	boot line and before init_hcl().
+ *
+ *	We currently do not have any boot options .. when we do, 
+ *	functionalities can be added here.
+ *
+ */
+static int __init hcl_setup(char *str)
+{
+    while ( (*str != '\0') && !isspace (*str) )
+    {
+#ifdef CONFIG_HCL_DEBUG
+        if (strncmp (str, "all", 3) == 0) {
+            hcl_debug_init |= HCL_DEBUG_ALL;
+            str += 3;
+        } else 
+        	return 0;
+#endif
+        if (*str != ',') return 0;
+        ++str;
+    }
+
+    return 1;
+
+}
+
+__setup("hcl=", hcl_setup);
+
+
+/*
+ * Set device specific "fast information".
+ *
+ */
+void
+hwgraph_fastinfo_set(vertex_hdl_t de, arbitrary_info_t fastinfo)
+{
+	labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
+}
+
+
+/*
+ * Get device specific "fast information".
+ *
+ */
+arbitrary_info_t
+hwgraph_fastinfo_get(vertex_hdl_t de)
+{
+	arbitrary_info_t fastinfo;
+	int rv;
+
+	if (!de) {
+		printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
+		return(-1);
+	}
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo);
+	if (rv == 0)
+		return(fastinfo);
+
+	return(0);
+}
+
+
+/*
+ * hwgraph_connectpt_set - Sets the connect point handle in de to the 
+ *	given connect_de handle.  By default, the connect point of the 
+ *	node is the parent.  This effectively changes this assumption.
+ */
+int
+hwgraph_connectpt_set(vertex_hdl_t de, vertex_hdl_t connect_de)
+{
+	int rv;
+
+	if (!de)
+		return(-1);
+
+	rv = labelcl_info_connectpt_set(de, connect_de);
+
+	return(rv);
+}
+
+
+/*
+ * hwgraph_connectpt_get: Returns the entry's connect point.
+ *
+ */
+vertex_hdl_t
+hwgraph_connectpt_get(vertex_hdl_t de)
+{
+	int rv;
+	arbitrary_info_t info;
+	vertex_hdl_t connect;
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
+	if (rv != 0) {
+		return(NULL);
+	}
+
+	connect = (vertex_hdl_t)info;
+	return(connect);
+
+}
+
+
+/*
+ * hwgraph_mk_dir - Creates a directory entry.
+ */
+vertex_hdl_t
+hwgraph_mk_dir(vertex_hdl_t de, const char *name,
+                unsigned int namelen, void *info)
+{
+
+	int rv;
+	labelcl_info_t *labelcl_info = NULL;
+	vertex_hdl_t new_handle = NULL;
+	vertex_hdl_t parent = NULL;
+
+	/*
+	 * Create the device info structure for hwgraph compatiblity support.
+	 */
+	labelcl_info = labelcl_info_create();
+	if (!labelcl_info)
+		return(NULL);
+
+	/*
+	 * Create an entry.
+	 */
+	new_handle = hwgfs_mk_dir(de, name, (void *)labelcl_info);
+	if (!new_handle) {
+		labelcl_info_destroy(labelcl_info);
+		return(NULL);
+	}
+
+	/*
+	 * Get the parent handle.
+	 */
+	parent = hwgfs_get_parent (new_handle);
+
+	/*
+	 * To provide the same semantics as the hwgraph, set the connect point.
+	 */
+	rv = hwgraph_connectpt_set(new_handle, parent);
+	if (!rv) {
+		/*
+		 * We need to clean up!
+		 */
+	}
+
+	/*
+	 * If the caller provides a private data pointer, save it in the 
+	 * labelcl info structure(fastinfo).  This can be retrieved via
+	 * hwgraph_fastinfo_get()
+	 */
+	if (info)
+		hwgraph_fastinfo_set(new_handle, (arbitrary_info_t)info);
+		
+	return(new_handle);
+
+}
+
+/*
+ * hwgraph_path_add - Create a directory node with the given path starting 
+ * from the given fromv.
+ */
+int
+hwgraph_path_add(vertex_hdl_t  fromv,
+		 char *path,
+		 vertex_hdl_t *new_de)
+{
+
+	unsigned int	namelen = strlen(path);
+	int		rv;
+
+	/*
+	 * We need to handle the case when fromv is NULL ..
+	 * in this case we need to create the path from the 
+	 * hwgraph root!
+	 */
+	if (fromv == NULL)
+		fromv = hwgraph_root;
+
+	/*
+	 * check the entry doesn't already exist, if it does
+	 * then we simply want new_de to point to it (otherwise
+	 * we'll overwrite the existing labelcl_info struct)
+	 */
+	rv = hwgraph_edge_get(fromv, path, new_de);
+	if (rv)	{	/* couldn't find entry so we create it */
+		*new_de = hwgraph_mk_dir(fromv, path, namelen, NULL);
+		if (new_de == NULL)
+			return(-1);
+		else
+			return(0);
+	}
+	else 
+ 		return(0);
+
+}
+
+/*
+ * hwgraph_register  - Creates a special device file.
+ *
+ */
+vertex_hdl_t
+hwgraph_register(vertex_hdl_t de, const char *name,
+                unsigned int namelen, unsigned int flags, 
+		unsigned int major, unsigned int minor,
+                umode_t mode, uid_t uid, gid_t gid, 
+		struct file_operations *fops,
+                void *info)
+{
+
+        vertex_hdl_t new_handle = NULL;
+
+        /*
+         * Create an entry.
+         */
+        new_handle = hwgfs_register(de, name, flags, major,
+				minor, mode, fops, info);
+
+        return(new_handle);
+
+}
+
+
+/*
+ * hwgraph_mk_symlink - Create a symbolic link.
+ */
+int
+hwgraph_mk_symlink(vertex_hdl_t de, const char *name, unsigned int namelen,
+                unsigned int flags, const char *link, unsigned int linklen, 
+		vertex_hdl_t *handle, void *info)
+{
+
+	void *labelcl_info = NULL;
+	int status = 0;
+	vertex_hdl_t new_handle = NULL;
+
+	/*
+	 * Create the labelcl info structure for hwgraph compatiblity support.
+	 */
+	labelcl_info = labelcl_info_create();
+	if (!labelcl_info)
+		return(-1);
+
+	/*
+	 * Create a symbolic link.
+	 */
+	status = hwgfs_mk_symlink(de, name, flags, link,
+				&new_handle, labelcl_info);
+	if ( (!new_handle) || (!status) ){
+		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
+		return(-1);
+	}
+
+	/*
+	 * If the caller provides a private data pointer, save it in the 
+	 * labelcl info structure(fastinfo).  This can be retrieved via
+	 * hwgraph_fastinfo_get()
+	 */
+	if (info)
+		hwgraph_fastinfo_set(new_handle, (arbitrary_info_t)info);
+
+	*handle = new_handle;
+	return(0);
+
+}
+
+/*
+ * hwgraph_vertex_destroy - Destroy the entry
+ */
+int
+hwgraph_vertex_destroy(vertex_hdl_t de)
+{
+
+	void *labelcl_info = NULL;
+
+	labelcl_info = hwgfs_get_info(de);
+	hwgfs_unregister(de);
+
+	if (labelcl_info)
+		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
+
+	return(0);
+}
+
+#if 0
+/*
+ * hwgraph_edge_add - This routines has changed from the original conext.
+ * All it does now is to create a symbolic link from "from" to "to".
+ */
+/* ARGSUSED */
+int
+hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
+{
+
+	char *path, *link;
+	vertex_hdl_t handle = NULL;
+	int rv, i;
+
+	handle = hwgfs_find_handle(from, name, 0, 0, 0, 1);
+	if (handle) {
+		return(0);
+	}
+
+	path = kmalloc(1024, GFP_KERNEL);
+	memset(path, 0x0, 1024);
+	link = kmalloc(1024, GFP_KERNEL);
+	memset(path, 0x0, 1024);
+	i = hwgfs_generate_path (to, link, 1024);
+	rv = hwgfs_mk_symlink (from, (const char *)name, 
+			       DEVFS_FL_DEFAULT, link,
+			       &handle, NULL);
+	return(0);
+
+
+}
+#endif
+
+int
+hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
+{
+
+	char *path, *link;
+	char *s1;
+	char *index;
+	vertex_hdl_t handle = NULL;
+	int rv;
+	int i, count;
+
+	path = kmalloc(1024, GFP_KERNEL);
+	memset((char *)path, 0x0, 1024);
+	link = kmalloc(1024, GFP_KERNEL);
+	memset((char *)link, 0x0, 1024);
+
+	i = hwgfs_generate_path (from, path, 1024);
+	s1 = (char *)path;
+	count = 0;
+	while (1) {
+		index = strstr (s1, "/");
+		if (index) {
+			count++;
+			s1 = ++index;
+		} else {
+			count++;
+			break;
+		}
+	}
+
+	for (i = 0; i < count; i++) {
+		strcat((char *)link,"../");
+	}
+
+	memset(path, 0x0, 1024);
+	i = hwgfs_generate_path (to, path, 1024);
+	strcat((char *)link, (char *)path);
+
+	/*
+	 * Otherwise, just create a symlink to the vertex.
+	 * In this case the vertex was previous created with a REAL pathname.
+	 */
+	rv = hwgfs_mk_symlink (from, (const char *)name,
+			       DEVFS_FL_DEFAULT, link,
+			       &handle, NULL);
+	kfree(path);
+	kfree(link);
+
+	return(rv);
+
+
+}
+
+/* ARGSUSED */
+int
+hwgraph_edge_get(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
+{
+
+	vertex_hdl_t target_handle = NULL;
+
+	if (name == NULL)
+		return(-1);
+
+	if (toptr == NULL)
+		return(-1);
+
+	/*
+	 * If the name is "." just return the current entry handle.
+	 */
+	if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {
+		if (toptr) {
+			*toptr = from;
+		}
+	} else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {
+		/*
+		 * Hmmm .. should we return the connect point or parent ..
+		 * see in hwgraph, the concept of parent is the connectpt!
+		 *
+		 * Maybe we should see whether the connectpt is set .. if 
+		 * not just return the parent!
+		 */
+		target_handle = hwgraph_connectpt_get(from);
+		if (target_handle) {
+			/*
+			 * Just return the connect point.
+			 */
+			*toptr = target_handle;
+			return(0);
+		}
+		target_handle = hwgfs_get_parent(from);
+		*toptr = target_handle;
+
+	} else {
+		target_handle = hwgfs_find_handle (from, name, 0, 0,
+					0, 1); /* Yes traverse symbolic links */
+	}
+
+	if (target_handle == NULL)
+		return(-1);
+	else
+	 *toptr = target_handle;
+
+	return(0);
+}
+
+/*
+ * hwgraph_info_add_LBL - Adds a new label for the device.  Mark the info_desc
+ *	of the label as INFO_DESC_PRIVATE and store the info in the label.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_add_LBL( vertex_hdl_t de,
+			char *name,
+			arbitrary_info_t info)
+{
+	return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));
+}
+
+/*
+ * hwgraph_info_remove_LBL - Remove the label entry for the device.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_remove_LBL( vertex_hdl_t de,
+				char *name,
+				arbitrary_info_t *old_info)
+{
+	return(labelcl_info_remove_LBL(de, name, NULL, old_info));
+}
+
+/*
+ * hwgraph_info_replace_LBL - replaces an existing label with 
+ *	a new label info value.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_replace_LBL( vertex_hdl_t de,
+				char *name,
+				arbitrary_info_t info,
+				arbitrary_info_t *old_info)
+{
+	return(labelcl_info_replace_LBL(de, name,
+			INFO_DESC_PRIVATE, info,
+			NULL, old_info));
+}
+/*
+ * hwgraph_info_get_LBL - Get and return the info value in the label of the 
+ * 	device.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_LBL(vertex_hdl_t de,
+			char *name,
+			arbitrary_info_t *infop)
+{
+	return(labelcl_info_get_LBL(de, name, NULL, infop));
+}
+
+/*
+ * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer 
+ *	of the given label for the device.  The weird thing is that the label 
+ *	that matches the name is return irrespective of the info_desc value!
+ *	Do not understand why the word "exported" is used!
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_exported_LBL(vertex_hdl_t de,
+				char *name,
+				int *export_info,
+				arbitrary_info_t *infop)
+{
+	int rc;
+	arb_info_desc_t info_desc;
+
+	rc = labelcl_info_get_LBL(de, name, &info_desc, infop);
+	if (rc == 0)
+		*export_info = (int)info_desc;
+
+	return(rc);
+}
+
+/*
+ * hwgraph_info_get_next_LBL - Returns the next label info given the 
+ *	current label entry in place.
+ *
+ *	Once again this has no locking or reference count for protection.
+ *
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_next_LBL(vertex_hdl_t de,
+				char *buf,
+				arbitrary_info_t *infop,
+				labelcl_info_place_t *place)
+{
+	return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));
+}
+
+/*
+ * hwgraph_info_export_LBL - Retrieve the specified label entry and modify 
+ *	the info_desc field with the given value in nbytes.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_export_LBL(vertex_hdl_t de, char *name, int nbytes)
+{
+	arbitrary_info_t info;
+	int rc;
+
+	if (nbytes == 0)
+		nbytes = INFO_DESC_EXPORT;
+
+	if (nbytes < 0)
+		return(-1);
+
+	rc = labelcl_info_get_LBL(de, name, NULL, &info);
+	if (rc != 0)
+		return(rc);
+
+	rc = labelcl_info_replace_LBL(de, name,
+				nbytes, info, NULL, NULL);
+
+	return(rc);
+}
+
+/*
+ * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the 
+ * label info_descr filed to INFO_DESC_PRIVATE.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_unexport_LBL(vertex_hdl_t de, char *name)
+{
+	arbitrary_info_t info;
+	int rc;
+
+	rc = labelcl_info_get_LBL(de, name, NULL, &info);
+	if (rc != 0)
+		return(rc);
+
+	rc = labelcl_info_replace_LBL(de, name,
+				INFO_DESC_PRIVATE, info, NULL, NULL);
+
+	return(rc);
+}
+
+/*
+ * hwgraph_path_lookup - return the handle for the given path.
+ *
+ */
+int
+hwgraph_path_lookup(vertex_hdl_t start_vertex_handle,
+			char *lookup_path,
+			vertex_hdl_t *vertex_handle_ptr,
+			char **remainder)
+{
+	*vertex_handle_ptr = hwgfs_find_handle(start_vertex_handle,	/* start dir */
+					lookup_path,		/* path */
+					0,			/* major */
+					0,			/* minor */
+					0,			/* char | block */
+					1);			/* traverse symlinks */
+	if (*vertex_handle_ptr == NULL)
+		return(-1);
+	else
+		return(0);
+}
+
+/*
+ * hwgraph_traverse - Find and return the handle starting from de.
+ *
+ */
+graph_error_t
+hwgraph_traverse(vertex_hdl_t de, char *path, vertex_hdl_t *found)
+{
+	/* 
+	 * get the directory entry (path should end in a directory)
+	 */
+
+	*found = hwgfs_find_handle(de,	/* start dir */
+			    path,	/* path */
+			    0,		/* major */
+			    0,		/* minor */
+			    0,		/* char | block */
+			    1);		/* traverse symlinks */
+	if (*found == NULL)
+		return(GRAPH_NOT_FOUND);
+	else
+		return(GRAPH_SUCCESS);
+}
+
+/*
+ * hwgraph_path_to_vertex - Return the entry handle for the given 
+ *	pathname .. assume traverse symlinks too!.
+ */
+vertex_hdl_t
+hwgraph_path_to_vertex(char *path)
+{
+	return(hwgfs_find_handle(NULL,	/* start dir */
+			path,		/* path */
+		    	0,		/* major */
+		    	0,		/* minor */
+		    	0,		/* char | block */
+		    	1));		/* traverse symlinks */
+}
+
+/*
+ * hwgraph_inventory_remove - Removes an inventory entry.
+ *
+ *	Remove an inventory item associated with a vertex.   It is the caller's
+ *	responsibility to make sure that there are no races between removing
+ *	inventory from a vertex and simultaneously removing that vertex.
+*/
+int
+hwgraph_inventory_remove(	vertex_hdl_t de,
+				int class,
+				int type,
+				major_t controller,
+				minor_t unit,
+				int state)
+{
+	return(0); /* Just a Stub for IRIX code. */
+}
+
+/*
+ * Find the canonical name for a given vertex by walking back through
+ * connectpt's until we hit the hwgraph root vertex (or until we run
+ * out of buffer space or until something goes wrong).
+ *
+ *	COMPATIBILITY FUNCTIONALITY
+ * Walks back through 'parents', not necessarily the same as connectpts.
+ *
+ * Need to resolve the fact that does not return the path from 
+ * "/" but rather it just stops right before /dev ..
+ */
+int
+hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen)
+{
+	char *locbuf;
+	int   pos;
+
+	if (buflen < 1)
+		return(-1);	/* XXX should be GRAPH_BAD_PARAM ? */
+
+	locbuf = kmalloc(buflen, GFP_KERNEL);
+
+	pos = hwgfs_generate_path(vhdl, locbuf, buflen);
+	if (pos < 0) {
+		kfree(locbuf);
+		return pos;
+	}
+
+	strcpy(buf, &locbuf[pos]);
+	kfree(locbuf);
+	return 0;
+}
+
+/*
+** vertex_to_name converts a vertex into a canonical name by walking
+** back through connect points until we hit the hwgraph root (or until
+** we run out of buffer space).
+**
+** Usually returns a pointer to the original buffer, filled in as
+** appropriate.  If the buffer is too small to hold the entire name,
+** or if anything goes wrong while determining the name, vertex_to_name
+** returns "UnknownDevice".
+*/
+
+#define DEVNAME_UNKNOWN "UnknownDevice"
+
+char *
+vertex_to_name(vertex_hdl_t vhdl, char *buf, uint buflen)
+{
+	if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)
+		return(buf);
+	else
+		return(DEVNAME_UNKNOWN);
+}
+
+graph_error_t
+hwgraph_edge_remove(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
+{
+	return(GRAPH_ILLEGAL_REQUEST);
+}
+
+graph_error_t
+hwgraph_vertex_unref(vertex_hdl_t vhdl)
+{
+	return(GRAPH_ILLEGAL_REQUEST);
+}
+
+
+EXPORT_SYMBOL(hwgraph_mk_dir);
+EXPORT_SYMBOL(hwgraph_path_add);
+EXPORT_SYMBOL(hwgraph_register);
+EXPORT_SYMBOL(hwgraph_vertex_destroy);
+EXPORT_SYMBOL(hwgraph_fastinfo_get);
+EXPORT_SYMBOL(hwgraph_fastinfo_set);
+EXPORT_SYMBOL(hwgraph_connectpt_set);
+EXPORT_SYMBOL(hwgraph_connectpt_get);
+EXPORT_SYMBOL(hwgraph_info_add_LBL);
+EXPORT_SYMBOL(hwgraph_info_remove_LBL);
+EXPORT_SYMBOL(hwgraph_info_replace_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_next_LBL);
+EXPORT_SYMBOL(hwgraph_info_export_LBL);
+EXPORT_SYMBOL(hwgraph_info_unexport_LBL);
+EXPORT_SYMBOL(hwgraph_path_lookup);
+EXPORT_SYMBOL(hwgraph_traverse);
+EXPORT_SYMBOL(hwgraph_vertex_name_get);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/hcl_util.c linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/hcl_util.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/hcl_util.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/hcl_util.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,200 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/sn/sgi.h>
+#include <asm/io.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/nodepda.h>
+
+static vertex_hdl_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE;
+extern vertex_hdl_t hwgraph_root;
+
+
+/*
+** Return the "master" for a given vertex.  A master vertex is a
+** controller or adapter or other piece of hardware that the given
+** vertex passes through on the way to the rest of the system.
+*/
+vertex_hdl_t
+device_master_get(vertex_hdl_t vhdl)
+{
+	graph_error_t rc;
+	vertex_hdl_t master;
+
+	rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master);
+	if (rc == GRAPH_SUCCESS)
+		return(master);
+	else
+		return(GRAPH_VERTEX_NONE);
+}
+
+/*
+** Set the master for a given vertex.
+** Returns 0 on success, non-0 indicates failure
+*/
+int
+device_master_set(vertex_hdl_t vhdl, vertex_hdl_t master)
+{
+	graph_error_t rc;
+
+	rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER);
+	return(rc != GRAPH_SUCCESS);
+}
+
+
+/*
+** Return the compact node id of the node that ultimately "owns" the specified
+** vertex.  In order to do this, we walk back through masters and connect points
+** until we reach a vertex that represents a node.
+*/
+cnodeid_t
+master_node_get(vertex_hdl_t vhdl)
+{
+	cnodeid_t cnodeid;
+	vertex_hdl_t master;
+
+	for (;;) {
+		cnodeid = nodevertex_to_cnodeid(vhdl);
+		if (cnodeid != CNODEID_NONE)
+			return(cnodeid);
+
+		master = device_master_get(vhdl);
+
+		/* Check for exceptional cases */
+		if (master == vhdl) {
+			/* Since we got a reference to the "master" thru
+			 * device_master_get() we should decrement
+			 * its reference count by 1
+			 */
+			return(CNODEID_NONE);
+		}
+
+		if (master == GRAPH_VERTEX_NONE) {
+			master = hwgraph_connectpt_get(vhdl);
+			if ((master == GRAPH_VERTEX_NONE) ||
+			    (master == vhdl)) {
+				return(CNODEID_NONE);
+			}
+		}
+
+		vhdl = master;
+	}
+}
+
+static vertex_hdl_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
+extern int maxcpus;
+
+void
+mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid)
+{
+	if (cpuid == CPU_NONE)
+		return;
+
+	(void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT,
+			(arbitrary_info_t)cpuid);
+	{
+		char cpuid_buffer[10];
+
+		if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) {
+			(void)hwgraph_path_add( hwgraph_root,
+						EDGE_LBL_CPUNUM,
+						&hwgraph_all_cpuids);
+		}
+
+		sprintf(cpuid_buffer, "%ld", cpuid);
+		(void)hwgraph_edge_add( hwgraph_all_cpuids,
+							vhdl,
+							cpuid_buffer);
+	}
+}
+
+/*
+** If the specified device represents a node, return its
+** compact node ID; otherwise, return CNODEID_NONE.
+*/
+cnodeid_t
+nodevertex_to_cnodeid(vertex_hdl_t vhdl)
+{
+	int rv = 0;
+	arbitrary_info_t cnodeid = CNODEID_NONE;
+
+	rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid);
+
+	return((cnodeid_t)cnodeid);
+}
+
+void
+mark_nodevertex_as_node(vertex_hdl_t vhdl, cnodeid_t cnodeid)
+{
+	if (cnodeid == CNODEID_NONE)
+		return;
+
+	cnodeid_to_vertex(cnodeid) = vhdl;
+	labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, 
+		(arbitrary_info_t)cnodeid);
+
+	{
+		char cnodeid_buffer[10];
+
+		if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) {
+			(void)hwgraph_path_add( hwgraph_root,
+						EDGE_LBL_NODENUM,
+						&hwgraph_all_cnodes);
+		}
+
+		sprintf(cnodeid_buffer, "%d", cnodeid);
+		(void)hwgraph_edge_add( hwgraph_all_cnodes,
+					vhdl,
+					cnodeid_buffer);
+	}
+}
+
+/*
+** If the specified device represents a CPU, return its cpuid;
+** otherwise, return CPU_NONE.
+*/
+cpuid_t
+cpuvertex_to_cpuid(vertex_hdl_t vhdl)
+{
+	arbitrary_info_t cpuid = CPU_NONE;
+
+	(void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid);
+
+	return((cpuid_t)cpuid);
+}
+
+
+/*
+** dev_to_name converts a vertex_hdl_t into a canonical name.  If the vertex_hdl_t
+** represents a vertex in the hardware graph, it is converted in the
+** normal way for vertices.  If the vertex_hdl_t is an old vertex_hdl_t (one which
+** does not represent a hwgraph vertex), we synthesize a name based
+** on major/minor number.
+**
+** Usually returns a pointer to the original buffer, filled in as
+** appropriate.  If the buffer is too small to hold the entire name,
+** or if anything goes wrong while determining the name, dev_to_name
+** returns "UnknownDevice".
+*/
+char *
+dev_to_name(vertex_hdl_t dev, char *buf, uint buflen)
+{
+        return(vertex_to_name(dev, buf, buflen));
+}
+
+
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/hwgfs.h linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/hwgfs.h
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/hwgfs.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/hwgfs.h	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,23 @@
+
+typedef struct dentry *hwgfs_handle_t;
+
+extern hwgfs_handle_t hwgfs_register(hwgfs_handle_t dir, const char *name,
+				     unsigned int flags,
+				     unsigned int major, unsigned int minor,
+				     umode_t mode, void *ops, void *info);
+extern int hwgfs_mk_symlink(hwgfs_handle_t dir, const char *name,
+			     unsigned int flags, const char *link,
+			     hwgfs_handle_t *handle, void *info);
+extern hwgfs_handle_t hwgfs_mk_dir(hwgfs_handle_t dir, const char *name,
+				    void *info);
+extern void hwgfs_unregister(hwgfs_handle_t de);
+
+extern hwgfs_handle_t hwgfs_find_handle(hwgfs_handle_t dir, const char *name,
+					unsigned int major,unsigned int minor,
+					char type, int traverse_symlinks);
+extern hwgfs_handle_t hwgfs_get_parent(hwgfs_handle_t de);
+extern int hwgfs_generate_path(hwgfs_handle_t de, char *path, int buflen);
+
+extern void *hwgfs_get_info(hwgfs_handle_t de);
+extern int hwgfs_set_info(hwgfs_handle_t de, void *info);
+
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/interface.c linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/interface.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/interface.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/interface.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,326 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/sched.h>		/* needed for smp_lock.h :( */
+#include <linux/smp_lock.h>
+
+#include <linux/slab.h>
+
+#include <asm/sn/hwgfs.h>
+
+extern struct vfsmount *hwgfs_vfsmount;
+
+/* TODO: Move this to some .h file or, more likely, use a slightly
+   different interface from lookup_create. */
+extern struct dentry *lookup_create(struct nameidata *nd, int is_dir);
+
+static int
+walk_parents_mkdir(
+	const char		**path,
+	struct nameidata	*nd,
+	int			is_dir)
+{
+	char			*slash;
+	char			buf[strlen(*path)+1];
+	int			error;
+
+	while ((slash = strchr(*path, '/')) != NULL) {
+		int len = slash - *path;
+		memcpy(buf, *path, len);
+		buf[len] = '\0';
+
+		error = link_path_walk(buf, nd); 
+		if (unlikely(error))
+			return error;
+
+		nd->dentry = lookup_create(nd, is_dir);
+		if (unlikely(IS_ERR(nd->dentry)))
+			return PTR_ERR(nd->dentry);
+
+		if (!nd->dentry->d_inode)
+			error = vfs_mkdir(nd->dentry->d_parent->d_inode,
+					nd->dentry, 0755);
+		
+		up(&nd->dentry->d_parent->d_inode->i_sem);
+		if (unlikely(error))
+			return error;
+
+		*path += len + 1;
+	}
+
+	return 0;
+}
+
+/* On success, returns with parent_inode->i_sem taken. */
+static int
+hwgfs_decode(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	int			is_dir,
+	struct inode		**parent_inode,
+	struct dentry		**dentry)
+{
+	struct nameidata	nd;
+	int			error;
+
+	if (!dir)
+		dir = hwgfs_vfsmount->mnt_sb->s_root;
+
+	memset(&nd, 0, sizeof(nd));
+	nd.flags = LOOKUP_PARENT;
+	nd.mnt = mntget(hwgfs_vfsmount);
+	nd.dentry = dget(dir);
+
+	error = walk_parents_mkdir(&name, &nd, is_dir);
+	if (unlikely(error))
+		return error;
+
+	error = link_path_walk(name, &nd);
+	if (unlikely(error))
+		return error;
+
+	*dentry = lookup_create(&nd, is_dir);
+
+	if (unlikely(IS_ERR(*dentry)))
+		return PTR_ERR(*dentry);
+	*parent_inode = (*dentry)->d_parent->d_inode;
+	return 0;
+}
+
+static int
+path_len(
+	struct dentry		*de,
+	struct dentry		*root)
+{
+	int			len = 0;
+
+	while (de != root) {
+		len += de->d_name.len + 1;	/* count the '/' */
+		de = de->d_parent;
+	}
+	return len;		/* -1 because we omit the leading '/',
+				   +1 because we include trailing '\0' */
+}
+
+int
+hwgfs_generate_path(
+	hwgfs_handle_t		de,
+	char			*path,
+	int			buflen)
+{
+	struct dentry		*hwgfs_root;
+	int			len;
+	char			*path_orig = path;
+
+	if (unlikely(de == NULL))
+		return -EINVAL;
+
+	hwgfs_root = hwgfs_vfsmount->mnt_sb->s_root;
+	if (unlikely(de == hwgfs_root))
+		return -EINVAL;
+
+	spin_lock(&dcache_lock);
+	len = path_len(de, hwgfs_root);
+	if (len > buflen) {
+		spin_unlock(&dcache_lock);
+		return -ENAMETOOLONG;
+	}
+
+	path += len - 1;
+	*path = '\0';
+
+	for (;;) {
+		path -= de->d_name.len;
+		memcpy(path, de->d_name.name, de->d_name.len);
+		de = de->d_parent;
+		if (de == hwgfs_root)
+			break;
+		*(--path) = '/';
+	}
+		
+	spin_unlock(&dcache_lock);
+	BUG_ON(path != path_orig);
+	return 0;
+}
+
+hwgfs_handle_t
+hwgfs_register(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	unsigned int		flags,
+	unsigned int		major,
+	unsigned int		minor,
+	umode_t			mode,
+	void			*ops,
+	void			*info)
+{
+	dev_t			devnum = MKDEV(major, minor);
+	struct inode		*parent_inode;
+	struct dentry		*dentry;
+	int			error;
+
+	error = hwgfs_decode(dir, name, 0, &parent_inode, &dentry);
+	if (likely(!error)) {
+		error = vfs_mknod(parent_inode, dentry, mode, devnum);
+		if (likely(!error)) {
+			/*
+			 * Do this inside parents i_sem to avoid racing
+			 * with lookups.
+			 */
+			if (S_ISCHR(mode))
+				dentry->d_inode->i_fop = ops;
+			dentry->d_fsdata = info;
+			up(&parent_inode->i_sem);
+		} else {
+			up(&parent_inode->i_sem);
+			dput(dentry);
+			dentry = NULL;
+                }
+	}
+
+	return dentry;
+}
+
+int
+hwgfs_mk_symlink(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	unsigned int		flags,
+	const char		*link,
+	hwgfs_handle_t		*handle,
+	void			*info)
+{
+	struct inode		*parent_inode;
+	struct dentry		*dentry;
+	int			error;
+
+	error = hwgfs_decode(dir, name, 0, &parent_inode, &dentry);
+	if (likely(!error)) {
+		error = vfs_symlink(parent_inode, dentry, link);
+		dentry->d_fsdata = info;
+		if (handle)
+			*handle = dentry;
+		up(&parent_inode->i_sem);
+		/* dput(dentry); */
+	}
+	return error;
+}
+
+hwgfs_handle_t
+hwgfs_mk_dir(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	void			*info)
+{
+	struct inode		*parent_inode;
+	struct dentry		*dentry;
+	int			error;
+
+	error = hwgfs_decode(dir, name, 1, &parent_inode, &dentry);
+	if (likely(!error)) {
+		error = vfs_mkdir(parent_inode, dentry, 0755);
+		up(&parent_inode->i_sem);
+
+		if (unlikely(error)) {
+			dput(dentry);
+			dentry = NULL;
+		} else {
+			dentry->d_fsdata = info;
+		}
+	}
+	return dentry;
+}
+
+void
+hwgfs_unregister(
+	hwgfs_handle_t		de)
+{
+	struct inode		*parent_inode = de->d_parent->d_inode;
+
+	if (S_ISDIR(de->d_inode->i_mode))
+		vfs_rmdir(parent_inode, de);
+	else
+		vfs_unlink(parent_inode, de);
+}
+
+/* XXX: this function is utterly bogus.  Every use of it is racy and the
+        prototype is stupid.  You have been warned.  --hch.  */
+hwgfs_handle_t
+hwgfs_find_handle(
+	hwgfs_handle_t		base,
+	const char		*name,
+	unsigned int		major,		/* IGNORED */
+	unsigned int		minor,		/* IGNORED */
+	char			type,		/* IGNORED */
+	int			traverse_symlinks)
+{
+	struct dentry		*dentry = NULL;
+	struct nameidata	nd;
+	int			error;
+
+	BUG_ON(*name=='/');
+
+	memset(&nd, 0, sizeof(nd));
+
+	nd.mnt = mntget(hwgfs_vfsmount);
+	nd.dentry = dget(base ? base : hwgfs_vfsmount->mnt_sb->s_root);
+	nd.flags = LOOKUP_POSITIVE | (traverse_symlinks ? LOOKUP_FOLLOW : 0);
+
+	error = link_path_walk(name, &nd);
+	if (likely(!error)) {
+		dentry = nd.dentry;
+		path_release(&nd);		/* stale data from here! */
+	}
+
+	return dentry;
+}
+
+hwgfs_handle_t
+hwgfs_get_parent(
+	hwgfs_handle_t		de)
+{
+	struct dentry		*parent;
+
+	lock_kernel();		/* XXX: for LBS this must be dparent_lock */
+	parent = de->d_parent;
+	unlock_kernel();
+
+	return parent;
+}
+
+int
+hwgfs_set_info(
+	hwgfs_handle_t		de,
+	void			*info)
+{
+	if (unlikely(de == NULL))
+		return -EINVAL;
+	de->d_fsdata = info;
+	return 0;
+}
+
+void *
+hwgfs_get_info(
+	hwgfs_handle_t		de)
+{
+	return de->d_fsdata;
+}
+
+EXPORT_SYMBOL(hwgfs_generate_path);
+EXPORT_SYMBOL(hwgfs_register);
+EXPORT_SYMBOL(hwgfs_unregister);
+EXPORT_SYMBOL(hwgfs_mk_symlink);
+EXPORT_SYMBOL(hwgfs_mk_dir);
+EXPORT_SYMBOL(hwgfs_find_handle);
+EXPORT_SYMBOL(hwgfs_get_parent);
+EXPORT_SYMBOL(hwgfs_set_info);
+EXPORT_SYMBOL(hwgfs_get_info);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/invent_stub.c linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/invent_stub.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/invent_stub.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/invent_stub.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,148 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+/*
+ * Hardware Inventory
+ *
+ * See sys/sn/invent.h for an explanation of the hardware inventory contents.
+ *
+ */
+#include <linux/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/invent.h>
+
+void
+inventinit(void)
+{
+}
+
+/*
+ * For initializing/updating an inventory entry.
+ */
+void
+replace_in_inventory(
+	inventory_t *pinv, int class, int type,
+	int controller, int unit, int state)
+{
+}
+
+/*
+ * Inventory addition 
+ *
+ * XXX NOTE: Currently must be called after dynamic memory allocator is
+ * initialized.
+ *
+ */
+void
+add_to_inventory(int class, int type, int controller, int unit, int state)
+{
+}
+
+
+/*
+ * Inventory retrieval 
+ *
+ * These two routines are intended to prevent the caller from having to know
+ * the internal structure of the inventory table.
+ *
+ * The caller of get_next_inventory is supposed to call start_scan_invent
+ * before the irst call to get_next_inventory, and the caller is required
+ * to call end_scan_invent after the last call to get_next_inventory.
+ */
+inventory_t *
+get_next_inventory(invplace_t *place)
+{
+	return((inventory_t *) NULL);
+}
+
+/* ARGSUSED */
+int
+get_sizeof_inventory(int abi)
+{
+	return sizeof(inventory_t);
+}
+
+/* Must be called prior to first call to get_next_inventory */
+void
+start_scan_inventory(invplace_t *iplace)
+{
+}
+
+/* Must be called after last call to get_next_inventory */
+void
+end_scan_inventory(invplace_t *iplace)
+{
+}
+
+/*
+ * Hardware inventory scanner.
+ *
+ * Calls fun() for every entry in inventory list unless fun() returns something
+ * other than 0.
+ */
+int
+scaninvent(int (*fun)(inventory_t *, void *), void *arg)
+{
+	return 0;
+}
+
+/*
+ * Find a particular inventory object
+ *
+ * pinv can be a pointer to an inventory entry and the search will begin from
+ * there, or it can be 0 in which case the search starts at the beginning.
+ * A -1 for any of the other arguments is a wildcard (i.e. it always matches).
+ */
+inventory_t *
+find_inventory(inventory_t *pinv, int class, int type, int controller,
+	       int unit, int state)
+{
+	return((inventory_t *) NULL);
+}
+
+
+/*
+** Retrieve inventory data associated with a device.
+*/
+inventory_t *
+device_inventory_get_next(	vertex_hdl_t device,
+				invplace_t *invplace)
+{
+		return((inventory_t *) NULL);
+}
+
+
+/*
+** Associate canonical inventory information with a device (and
+** add it to the general inventory).
+*/
+void
+device_inventory_add(	vertex_hdl_t device,
+			int class, 
+			int type, 
+			major_t controller, 
+			minor_t unit, 
+			int state)
+{
+}
+
+int
+device_controller_num_get(vertex_hdl_t device)
+{
+	return (0);
+}
+
+void
+device_controller_num_set(vertex_hdl_t device, int contr_num)
+{
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/labelcl.c linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/labelcl.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/labelcl.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/labelcl.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,657 @@
+/*  labelcl - SGI's Hwgraph Compatibility Layer.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+*/
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/sched.h>                /* needed for smp_lock.h :( */
+#include <linux/smp_lock.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+
+/*
+** Very simple and dumb string table that supports only find/insert.
+** In practice, if this table gets too large, we may need a more
+** efficient data structure.   Also note that currently there is no 
+** way to delete an item once it's added.  Therefore, name collision 
+** will return an error.
+*/
+
+struct string_table label_string_table;
+
+
+
+/*
+ * string_table_init - Initialize the given string table.
+ */
+void
+string_table_init(struct string_table *string_table)
+{
+	string_table->string_table_head = NULL;
+	string_table->string_table_generation = 0;
+
+	/*
+	 * We nedd to initialize locks here!
+	 */
+
+	return;
+}
+
+
+/*
+ * string_table_destroy - Destroy the given string table.
+ */
+void
+string_table_destroy(struct string_table *string_table)
+{
+	struct string_table_item *item, *next_item;
+
+	item = string_table->string_table_head;
+	while (item) {
+		next_item = item->next;
+
+		STRTBL_FREE(item);
+		item = next_item;
+	}
+
+	/*
+	 * We need to destroy whatever lock we have here
+	 */
+
+	return;
+}
+
+
+
+/*
+ * string_table_insert - Insert an entry in the string table .. duplicate 
+ *	names are not allowed.
+ */
+char *
+string_table_insert(struct string_table *string_table, char *name)
+{
+	struct string_table_item *item, *new_item = NULL, *last_item = NULL;
+
+again:
+	/*
+	 * Need to lock the table ..
+	 */
+	item = string_table->string_table_head;
+	last_item = NULL;
+
+	while (item) {
+		if (!strcmp(item->string, name)) {
+			/*
+			 * If we allocated space for the string and the found that
+			 * someone else already entered it into the string table,
+			 * free the space we just allocated.
+			 */
+			if (new_item)
+				STRTBL_FREE(new_item);
+
+
+			/*
+			 * Search optimization: move the found item to the head
+			 * of the list.
+			 */
+			if (last_item != NULL) {
+				last_item->next = item->next;
+				item->next = string_table->string_table_head;
+				string_table->string_table_head = item;
+			}
+			goto out;
+		}
+		last_item = item;
+		item=item->next;
+	}
+
+	/*
+	 * name was not found, so add it to the string table.
+	 */
+	if (new_item == NULL) {
+		long old_generation = string_table->string_table_generation;
+
+		new_item = STRTBL_ALLOC(strlen(name));
+
+		strcpy(new_item->string, name);
+
+		/*
+		 * While we allocated memory for the new string, someone else 
+		 * changed the string table.
+		 */
+		if (old_generation != string_table->string_table_generation) {
+			goto again;
+		}
+	} else {
+		/* At this we only have the string table lock in access mode.
+		 * Promote the access lock to an update lock for the string
+		 * table insertion below.
+		 */
+			long old_generation = 
+				string_table->string_table_generation;
+
+			/*
+			 * After we did the unlock and wer waiting for update
+			 * lock someone could have potentially updated
+			 * the string table. Check the generation number
+			 * for this case. If it is the case we have to
+			 * try all over again.
+			 */
+			if (old_generation != 
+			    string_table->string_table_generation) {
+				goto again;
+			}
+		}
+
+	/*
+	 * At this point, we're committed to adding new_item to the string table.
+	 */
+	new_item->next = string_table->string_table_head;
+	item = string_table->string_table_head = new_item;
+	string_table->string_table_generation++;
+
+out:
+	/*
+	 * Need to unlock here.
+	 */
+	return(item->string);
+}
+
+/*
+ * labelcl_info_create - Creates the data structure that will hold the
+ *	device private information asscoiated with a entry.
+ *	The pointer to this structure is what gets stored in the 
+ *	(void * info).
+ */
+labelcl_info_t *
+labelcl_info_create()
+{
+
+	labelcl_info_t *new = NULL;
+
+	/* Initial allocation does not include any area for labels */
+	if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL )
+		return NULL;
+
+	memset (new, 0, sizeof(labelcl_info_t));
+	new->hwcl_magic = LABELCL_MAGIC;
+	return( new);
+
+}
+
+/*
+ * labelcl_info_destroy - Frees the data structure that holds the
+ *      device private information asscoiated with a entry.  This 
+ *	data structure was created by device_info_create().
+ *
+ *	The caller is responsible for nulling the (void *info) in the 
+ *	corresponding entry.
+ */
+int
+labelcl_info_destroy(labelcl_info_t *labelcl_info)
+{
+
+	if (labelcl_info == NULL)
+		return(0);
+
+	/* Free the label list */
+	if (labelcl_info->label_list)
+		kfree(labelcl_info->label_list);
+
+	/* Now free the label info area */
+	labelcl_info->hwcl_magic = 0;
+	kfree(labelcl_info);
+
+	return(0);
+}
+
+/*
+ * labelcl_info_add_LBL - Adds a new label entry in the labelcl info 
+ *	structure.
+ *
+ *	Error is returned if we find another label with the same name.
+ */
+int
+labelcl_info_add_LBL(vertex_hdl_t de,
+			char *info_name,
+			arb_info_desc_t info_desc,
+			arbitrary_info_t info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	int new_label_list_size;
+	label_info_t *old_label_list, *new_label_list = NULL;
+	char *name;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+        labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if (info_name == NULL)
+		return(-1);
+
+	if (strlen(info_name) >= LABEL_LENGTH_MAX)
+		return(-1);
+
+	name = string_table_insert(&label_string_table, info_name);
+
+	num_labels = labelcl_info->num_labels;
+	new_label_list_size = sizeof(label_info_t) * (num_labels+1);
+
+	/*
+	 * Create a new label info area.
+	 */
+	if (new_label_list_size != 0) {
+		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
+
+		if (new_label_list == NULL)
+			return(-1);
+	}
+
+	/*
+	 * At this point, we are committed to adding the labelled info, 
+	 * if there isn't already information there with the same name.
+	 */
+	old_label_list = labelcl_info->label_list;
+
+	/* 
+	 * Look for matching info name.
+	 */
+	for (i=0; i<num_labels; i++) {
+		if (!strcmp(info_name, old_label_list[i].name)) {
+			/* Not allowed to add duplicate labelled info names. */
+			kfree(new_label_list);
+			return(-1);
+		}
+		new_label_list[i] = old_label_list[i]; /* structure copy */
+	}
+
+	new_label_list[num_labels].name = name;
+	new_label_list[num_labels].desc = info_desc;
+	new_label_list[num_labels].info = info;
+
+	labelcl_info->num_labels = num_labels+1;
+	labelcl_info->label_list = new_label_list;
+
+	if (old_label_list != NULL)
+		kfree(old_label_list);
+
+	return(0);
+}
+
+/*
+ * labelcl_info_remove_LBL - Remove a label entry.
+ */
+int
+labelcl_info_remove_LBL(vertex_hdl_t de,
+			 char *info_name,
+			 arb_info_desc_t *info_desc,
+			 arbitrary_info_t *info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	int new_label_list_size;
+	label_info_t *old_label_list, *new_label_list = NULL;
+	arb_info_desc_t label_desc_found;
+	arbitrary_info_t label_info_found;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	/*
+	 * Create a new info area.
+	 */
+	new_label_list_size = sizeof(label_info_t) * (num_labels-1);
+	if (new_label_list_size) {
+		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
+		if (new_label_list == NULL)
+			return(-1);
+	}
+
+	/*
+	 * At this point, we are committed to removing the labelled info, 
+	 * if it still exists.
+	 */
+	old_label_list = labelcl_info->label_list;
+
+	/* 
+	 * Find matching info name.
+	 */
+	for (i=0; i<num_labels; i++) {
+		if (!strcmp(info_name, old_label_list[i].name)) {
+			label_desc_found = old_label_list[i].desc;
+			label_info_found = old_label_list[i].info;
+			goto found;
+		}
+		if (i < num_labels-1) /* avoid walking off the end of the new vertex */
+			new_label_list[i] = old_label_list[i]; /* structure copy */
+	}
+
+	/* The named info doesn't exist. */
+	if (new_label_list)
+		kfree(new_label_list);
+
+	return(-1);
+
+found:
+	/* Finish up rest of labelled info */
+	for (i=i+1; i<num_labels; i++)
+		new_label_list[i-1] = old_label_list[i]; /* structure copy */
+
+	labelcl_info->num_labels = num_labels+1;
+	labelcl_info->label_list = new_label_list;
+
+	kfree(old_label_list);
+
+	if (info != NULL)
+		*info = label_info_found;
+
+	if (info_desc != NULL)
+		*info_desc = label_desc_found;
+
+	return(0);
+}
+
+
+/*
+ * labelcl_info_replace_LBL - Replace an existing label entry with the 
+ *	given new information.
+ *
+ *	Label entry must exist.
+ */
+int
+labelcl_info_replace_LBL(vertex_hdl_t de,
+			char *info_name,
+			arb_info_desc_t info_desc,
+			arbitrary_info_t info,
+			arb_info_desc_t *old_info_desc,
+			arbitrary_info_t *old_info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	label_info_t *label_list;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	if (info_name == NULL)
+		return(-1);
+
+	label_list = labelcl_info->label_list;
+
+	/* 
+	 * Verify that information under info_name already exists.
+	 */
+	for (i=0; i<num_labels; i++)
+		if (!strcmp(info_name, label_list[i].name)) {
+			if (old_info != NULL)
+				*old_info = label_list[i].info;
+
+			if (old_info_desc != NULL)
+				*old_info_desc = label_list[i].desc;
+
+			label_list[i].info = info;
+			label_list[i].desc = info_desc;
+
+			return(0);
+		}
+
+
+	return(-1);
+}
+
+/*
+ * labelcl_info_get_LBL - Retrieve and return the information for the 
+ *	given label entry.
+ */
+int
+labelcl_info_get_LBL(vertex_hdl_t de,
+		      char *info_name,
+		      arb_info_desc_t *info_desc,
+		      arbitrary_info_t *info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	label_info_t *label_list;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	label_list = labelcl_info->label_list;
+
+	/* 
+	 * Find information under info_name.
+	 */
+	for (i=0; i<num_labels; i++)
+		if (!strcmp(info_name, label_list[i].name)) {
+			if (info != NULL)
+				*info = label_list[i].info;
+			if (info_desc != NULL)
+				*info_desc = label_list[i].desc;
+
+			return(0);
+		}
+
+	return(-1);
+}
+
+/*
+ * labelcl_info_get_next_LBL - returns the next label entry on the list.
+ */
+int
+labelcl_info_get_next_LBL(vertex_hdl_t de,
+			   char *buffer,
+			   arb_info_desc_t *info_descp,
+			   arbitrary_info_t *infop,
+			   labelcl_info_place_t *placeptr)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	uint which_info;
+	label_info_t *label_list;
+
+	if ((buffer == NULL) && (infop == NULL))
+		return(-1);
+
+	if (placeptr == NULL)
+		return(-1);
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	which_info = *placeptr;
+
+	if (which_info >= labelcl_info->num_labels) {
+		return(-1);
+	}
+
+	label_list = (label_info_t *) labelcl_info->label_list;
+
+	if (buffer != NULL)
+		strcpy(buffer, label_list[which_info].name);
+
+	if (infop)
+		*infop = label_list[which_info].info;
+
+	if (info_descp)
+		*info_descp = label_list[which_info].desc;
+
+	*placeptr = which_info + 1;
+
+	return(0);
+}
+
+
+int
+labelcl_info_replace_IDX(vertex_hdl_t de,
+			int index,
+			arbitrary_info_t info,
+			arbitrary_info_t *old_info)
+{
+	arbitrary_info_t *info_list_IDX;
+	labelcl_info_t	*labelcl_info = NULL;
+
+	if (de == NULL) {
+		printk(KERN_ALERT "labelcl: NULL handle given.\n");
+		return(-1);
+	}
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL) {
+		printk(KERN_ALERT "labelcl: Entry %p does not have info pointer.\n", (void *)de);
+		return(-1);
+	}
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
+		return(-1);
+
+	/*
+	 * Replace information at the appropriate index in this vertex with 
+	 * the new info.
+	 */
+	info_list_IDX = labelcl_info->IDX_list;
+	if (old_info != NULL)
+		*old_info = info_list_IDX[index];
+	info_list_IDX[index] = info;
+
+	return(0);
+
+}
+
+/*
+ * labelcl_info_connectpt_set - Sets the connectpt.
+ */
+int
+labelcl_info_connectpt_set(hwgfs_handle_t de,
+			  hwgfs_handle_t connect_de)
+{
+	arbitrary_info_t old_info;
+	int	rv;
+
+	rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, 
+		(arbitrary_info_t) connect_de, &old_info);
+
+	if (rv) {
+		return(rv);
+	}
+
+	return(0);
+}
+
+
+/*
+ * labelcl_info_get_IDX - Returns the information pointed at by index.
+ *
+ */
+int
+labelcl_info_get_IDX(vertex_hdl_t de,
+			int index,
+			arbitrary_info_t *info)
+{
+	arbitrary_info_t *info_list_IDX;
+	labelcl_info_t	*labelcl_info = NULL;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
+		return(-1);
+
+	/*
+	 * Return information at the appropriate index in this vertex.
+	 */
+	info_list_IDX = labelcl_info->IDX_list;
+	if (info != NULL)
+		*info = info_list_IDX[index];
+
+	return(0);
+}
+
+/*
+ * labelcl_info_connectpt_get - Retrieve the connect point for a device entry.
+ */
+hwgfs_handle_t
+labelcl_info_connectpt_get(hwgfs_handle_t de)
+{
+	int rv;
+	arbitrary_info_t info;
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
+	if (rv)
+		return(NULL);
+
+	return((hwgfs_handle_t) info);
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/ramfs.c linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/ramfs.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/hwgfs/ramfs.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/hwgfs/ramfs.c	2003-07-05 18:09:40.000000000 -0700
@@ -0,0 +1,341 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/machvec.h>
+
+/* some random number */
+#define HWGFS_MAGIC	0x12061983
+
+static struct super_operations hwgfs_ops;
+static struct address_space_operations hwgfs_aops;
+static struct file_operations hwgfs_file_operations;
+static struct inode_operations hwgfs_dir_inode_operations;
+
+static int hwgfs_statfs(struct super_block *sb, struct statfs *buf)
+{
+	buf->f_type = HWGFS_MAGIC;
+	buf->f_bsize = PAGE_CACHE_SIZE;
+	buf->f_namelen = 255;
+	return 0;
+}
+
+/*
+ * Lookup the data. This is trivial - if the dentry didn't already
+ * exist, we know it is negative.
+ */
+static struct dentry * hwgfs_lookup(struct inode *dir, struct dentry *dentry)
+{
+	d_add(dentry, NULL);
+	return NULL;
+}
+
+/*
+ * Read a page. Again trivial. If it didn't already exist
+ * in the page cache, it is zero-filled.
+ */
+static int hwgfs_readpage(struct file *file, struct page * page)
+{
+	if (!Page_Uptodate(page)) {
+		memset(kmap(page), 0, PAGE_CACHE_SIZE);
+		kunmap(page);
+		flush_dcache_page(page);
+		SetPageUptodate(page);
+	}
+	UnlockPage(page);
+	return 0;
+}
+
+static int hwgfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+{
+	void *addr = kmap(page);
+	if (!Page_Uptodate(page)) {
+		memset(addr, 0, PAGE_CACHE_SIZE);
+		flush_dcache_page(page);
+		SetPageUptodate(page);
+	}
+	SetPageDirty(page);
+	return 0;
+}
+
+static int hwgfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+{
+	struct inode *inode = page->mapping->host;
+	loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+
+	kunmap(page);
+	if (pos > inode->i_size)
+		inode->i_size = pos;
+	return 0;
+}
+
+struct inode *hwgfs_get_inode(struct super_block *sb, int mode, int dev)
+{
+	struct inode * inode = new_inode(sb);
+
+	if (inode) {
+		inode->i_mode = mode;
+		inode->i_uid = current->fsuid;
+		inode->i_gid = current->fsgid;
+		inode->i_blksize = PAGE_CACHE_SIZE;
+		inode->i_blocks = 0;
+		inode->i_rdev = NODEV;
+		inode->i_mapping->a_ops = &hwgfs_aops;
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		switch (mode & S_IFMT) {
+		default:
+			init_special_inode(inode, mode, dev);
+			break;
+		case S_IFREG:
+			inode->i_fop = &hwgfs_file_operations;
+			break;
+		case S_IFDIR:
+			inode->i_op = &hwgfs_dir_inode_operations;
+			inode->i_fop = &dcache_dir_ops;
+			break;
+		case S_IFLNK:
+			inode->i_op = &page_symlink_inode_operations;
+			break;
+		}
+	}
+	return inode;
+}
+
+/*
+ * File creation. Allocate an inode, and we're done..
+ */
+static int hwgfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
+{
+	struct inode * inode = hwgfs_get_inode(dir->i_sb, mode, dev);
+	int error = -ENOSPC;
+
+	if (inode) {
+		d_instantiate(dentry, inode);
+		dget(dentry);		/* Extra count - pin the dentry in core */
+		error = 0;
+	}
+	return error;
+}
+
+static int hwgfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+{
+	return hwgfs_mknod(dir, dentry, mode | S_IFDIR, 0);
+}
+
+static int hwgfs_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+	return hwgfs_mknod(dir, dentry, mode | S_IFREG, 0);
+}
+
+/*
+ * Link a file..
+ */
+static int hwgfs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
+{
+	struct inode *inode = old_dentry->d_inode;
+
+	if (S_ISDIR(inode->i_mode))
+		return -EPERM;
+
+	inode->i_nlink++;
+	atomic_inc(&inode->i_count);	/* New dentry reference */
+	dget(dentry);		/* Extra pinning count for the created dentry */
+	d_instantiate(dentry, inode);
+	return 0;
+}
+
+static inline int hwgfs_positive(struct dentry *dentry)
+{
+	return dentry->d_inode && !d_unhashed(dentry);
+}
+
+/*
+ * Check that a directory is empty (this works
+ * for regular files too, they'll just always be
+ * considered empty..).
+ *
+ * Note that an empty directory can still have
+ * children, they just all have to be negative..
+ */
+static int hwgfs_empty(struct dentry *dentry)
+{
+	struct list_head *list;
+
+	spin_lock(&dcache_lock);
+	list = dentry->d_subdirs.next;
+
+	while (list != &dentry->d_subdirs) {
+		struct dentry *de = list_entry(list, struct dentry, d_child);
+
+		if (hwgfs_positive(de)) {
+			spin_unlock(&dcache_lock);
+			return 0;
+		}
+		list = list->next;
+	}
+	spin_unlock(&dcache_lock);
+	return 1;
+}
+
+/*
+ * This works for both directories and regular files.
+ * (non-directories will always have empty subdirs)
+ */
+static int hwgfs_unlink(struct inode * dir, struct dentry *dentry)
+{
+	int retval = -ENOTEMPTY;
+
+	if (hwgfs_empty(dentry)) {
+		struct inode *inode = dentry->d_inode;
+
+		inode->i_nlink--;
+		dput(dentry);			/* Undo the count from "create" - this does all the work */
+		retval = 0;
+	}
+	return retval;
+}
+
+#define hwgfs_rmdir hwgfs_unlink
+
+/*
+ * The VFS layer already does all the dentry stuff for rename,
+ * we just have to decrement the usage count for the target if
+ * it exists so that the VFS layer correctly free's it when it
+ * gets overwritten.
+ */
+static int hwgfs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
+{
+	int error = -ENOTEMPTY;
+
+	if (hwgfs_empty(new_dentry)) {
+		struct inode *inode = new_dentry->d_inode;
+		if (inode) {
+			inode->i_nlink--;
+			dput(new_dentry);
+		}
+		error = 0;
+	}
+	return error;
+}
+
+static int hwgfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
+{
+	int error;
+
+	error = hwgfs_mknod(dir, dentry, S_IFLNK | S_IRWXUGO, 0);
+	if (!error) {
+		int l = strlen(symname)+1;
+		struct inode *inode = dentry->d_inode;
+		error = block_symlink(inode, symname, l);
+	}
+	return error;
+}
+
+static int hwgfs_sync_file(struct file * file, struct dentry *dentry, int datasync)
+{
+	return 0;
+}
+
+static struct address_space_operations hwgfs_aops = {
+	.readpage	= hwgfs_readpage,
+	.writepage	= fail_writepage,
+	.prepare_write	= hwgfs_prepare_write,
+	.commit_write	= hwgfs_commit_write
+};
+
+static struct file_operations hwgfs_file_operations = {
+	.read		= generic_file_read,
+	.write		= generic_file_write,
+	.mmap		= generic_file_mmap,
+	.fsync		= hwgfs_sync_file,
+};
+
+static struct inode_operations hwgfs_dir_inode_operations = {
+	.create		= hwgfs_create,
+	.lookup		= hwgfs_lookup,
+	.link		= hwgfs_link,
+	.unlink		= hwgfs_unlink,
+	.symlink	= hwgfs_symlink,
+	.mkdir		= hwgfs_mkdir,
+	.rmdir		= hwgfs_rmdir,
+	.mknod		= hwgfs_mknod,
+	.rename		= hwgfs_rename,
+};
+
+static struct super_operations hwgfs_ops = {
+	.statfs		= hwgfs_statfs,
+	.put_inode	= force_delete,
+};
+
+static struct super_block *hwgfs_read_super(struct super_block * sb, void * data, int silent)
+{
+	struct inode * inode;
+	struct dentry * root;
+
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = HWGFS_MAGIC;
+	sb->s_op = &hwgfs_ops;
+	inode = hwgfs_get_inode(sb, S_IFDIR | 0755, 0);
+	if (!inode)
+		return NULL;
+
+	root = d_alloc_root(inode);
+	if (!root) {
+		iput(inode);
+		return NULL;
+	}
+	sb->s_root = root;
+	return sb;
+}
+
+static struct file_system_type hwgfs_fs_type = {
+	.owner			= THIS_MODULE,
+	.name			= "hwgfs",
+	.read_super		= hwgfs_read_super,
+	.fs_flags		= FS_SINGLE|FS_LITTER,
+};
+
+struct vfsmount *hwgfs_vfsmount;
+
+int __init init_hwgfs_fs(void)
+{
+	int error;
+
+	if (!ia64_platform_is("sn2"))
+		return -ENODEV;
+
+	error = register_filesystem(&hwgfs_fs_type);
+	if (error)
+		return error;
+
+	hwgfs_vfsmount = kern_mount(&hwgfs_fs_type);
+	if (IS_ERR(hwgfs_vfsmount))
+		goto fail;
+	return 0;
+
+fail:
+	unregister_filesystem(&hwgfs_fs_type);
+	return PTR_ERR(hwgfs_vfsmount);
+}
+
+static void __exit exit_hwgfs_fs(void)
+{
+	unregister_filesystem(&hwgfs_fs_type);
+}
+
+MODULE_LICENSE("GPL");
+
+module_init(init_hwgfs_fs)
+module_exit(exit_hwgfs_fs)
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/ifconfig_bus.c linux-2.4.22-pre3/arch/ia64/sn/io/ifconfig_bus.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/ifconfig_bus.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/ifconfig_bus.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,345 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- *  ifconfig_bus - SGI's Persistent PCI Bus Numbering.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/pci.h>
-
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm//sn/sn_sal.h>
-#include <asm/sn/addrs.h>
-
-#define SGI_IFCONFIG_BUS "SGI-PERSISTENT PCI BUS NUMBERING"
-#define SGI_IFCONFIG_BUS_VERSION "1.0"
-
-/*
- * Some Global definitions.
- */
-devfs_handle_t ioconfig_bus_handle = NULL;
-unsigned long ioconfig_bus_debug = 0;
-
-#define IFCONFIG_BUS_DEBUG 1
-#ifdef IFCONFIG_BUS_DEBUG
-#define DBG(x...)	printk(x)
-#else
-#define DBG(x...)
-#endif
-
-u64 ioconfig_file = 0;
-u64 ioconfig_file_size = 0;
-
-
-/*
- * PCI Bus Name for PCI
- * 		 module/001c02/Ibrick/xtalk/14/pci - only 1 bus per widget
- *
- * PCI Bus Name for PCI-X
- *		 module/001c02/Ibrick/xtalk/14/pci-x/0 - PCI bus 0 on Widget 14
- *		 module/001c02/Ibrick/xtalk/14/pci-x/1 - PCI bus 1 on Widget 14
- */
-
-struct	pcipath_to_busnum{
-	unsigned int  num;			/* persistent bus number */
-	unsigned int  len;			/* pci path length */
-	unsigned char	path[120];		/* pci path name */
-};
-
-struct  pcipath_to_busnum *ioconfig_bus_table;
-u64 ioconfig_bus_table_size = 0;
-
-
-struct pcipath_to_busnum pcibus_names[256];
-
-/*
- * highest_pcibus_num : The highest PCI bus number allocated.  Use for next 
- *			PCI Bus Number to be assigned.
- * pcibus_names_index : The starting entry of any new configuration.  It also 
- *			tracks the number of old config in the table.
- * current_index : Next free index in the table for new config.
- *		   current_index - pcibus_names_index = number new config.
- */
-
-int	highest_pcibus_num = 0;
-int	pcibus_names_index = 0; /* Start of new config */
-int	current_index = 0; /* Next entry for new config */
-
-/*
- * ioconfig_get_busnum():
- *	ioconfig_get_busnum() returns the bus number given a pci path name.
- *	If the pci path name exist in the persistent naming table, the
- *	corresponding bun number is returned.  If the pci path name does not
- *	exist, the next bus number is assigned to that path, added to the
- *	persistent naming table and the new bus num returned.
- */
-void
-ioconfig_get_busnum(char *pci_path, int *bus_num)
-{
-	struct	pcipath_to_busnum *temp;
-	int index;
-
-	*bus_num = -1;
-	temp = ioconfig_bus_table;
-	for (index = 0; index < current_index; ioconfig_bus_table++, index++) {
-		if ( (strncmp(pci_path, ioconfig_bus_table->path, strlen(pci_path) == 0)) ){
-			*bus_num = ioconfig_bus_table->num;
-			return;
-		}
-	}
-
-	/*
-	 * This is a new path and it is not in the config table.
-	 * Add it to the end.
-	 */
-	*bus_num = highest_pcibus_num;
-	highest_pcibus_num++;
-	ioconfig_bus_table->num = *bus_num;
-	strcpy((char *)&(ioconfig_bus_table->path), pci_path);
-	ioconfig_bus_table->len = strlen(pci_path);
-	current_index++;
-
-}
-
-void
-dump_ioconfig_table(struct pcipath_to_busnum *ioconfig_bus_table)
-{
-
-	int index = 0;
-	struct pcipath_to_busnum *temp;
-
-	temp = ioconfig_bus_table;
-	while (index < pcibus_names_index) {
-		printk("Bus Number %d PCI path %s\n", temp->num, temp->path);
-		temp++;
-		index++;
-	}
-		
-}
-/*
- * nextline
- *	This routine returns the nextline in the buffer.
- */
-int nextline(char *buffer, char **next, char *line)
-{
-
-	char *temp;
-
-	if (buffer[0] == 0x0) {
-		return(0);
-	}
-
-	temp = buffer;
-	while (*temp != 0) {
-		*line = *temp;
-		if (*temp != '\n'){
-			*line = *temp;
-			temp++; line++;
-		} else
-			break;
-	}
-
-	if (*temp == 0)
-		*next = temp;
-	else
-		*next = ++temp;
-
-	return(1);
-}
-
-/*
- * build_pcibus_name
- *	This routine parses the ioconfig contents read into
- *	memory by ioconfig command in EFI and builds the
- *	persistent pci bus naming table.
- */
-void
-build_pcibus_name(char *file_contents, struct pcipath_to_busnum *table)
-{
-	/*
-	 * Read the whole file into memory.
-	 */
-	int busnum;
-	int rc;
-	char *name;
-	char *temp;
-	char *next;
-	char *current;
-	char *line;
-	struct pcipath_to_busnum *pcibus;
-
-	line = kmalloc(256, GFP_KERNEL);
-	memset(line, 0,256);
-	name = kmalloc(125, GFP_KERNEL);
-	memset(name, 0, 125);
-	pcibus = table;
-	current = file_contents;
-	while (nextline(current, &next, line)){
-printk("current 0x%lx next 0x%lx\n", current, next);
-		temp = line;
-		/*
-		 * Skip all leading Blank lines ..
-		 */
-		while (isspace(*temp))
-			if (*temp != '\n')
-				temp++;
-			else
-				break;
-
-		if (*temp == '\n') {
-			current = next;
-			memset(line, 0, 256);
-			continue;
-		}
- 
-		/*
-		 * Skip comment lines
-		 */
-		if (*temp == '#') {
-			current = next;
-			memset(line, 0, 256);
-			continue;
-		}
-
-		/*
-		 * Get the next free entry in the table.
-		 */
-		rc = sscanf(temp, "%d %s", &busnum, name);
-		pcibus->num = busnum;
-		pcibus->len = strlen(name);
-		strcpy(&pcibus->path[0], name);
-		DBG("pci number = %d pci path = %s\n", pcibus->num, pcibus->path);
-		if (busnum > highest_pcibus_num)
-			highest_pcibus_num = busnum;
-		else 
-			highest_pcibus_num = busnum; 
- 
-		pcibus_names_index++;
-		pcibus++;
-		current = next;
-		memset(line, 0, 256);
-	}
-
-	DBG("highest_pcibus_num %d pcibus_names_index %d\n", highest_pcibus_num, pcibus_names_index);
-
-	current_index = pcibus_names_index;
-	kfree(line);
-	kfree(name);
-
-	return;
-}
-
-void
-ioconfig_bus_init(void)
-{
-
-	struct ia64_sal_retval ret_stuff;
-
-	DBG("ioconfig_bus_init called.\n");
-
-	/*
-	 * Make SAL call to get the address of the bus configuration table.
-	 */
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
-	SAL_CALL(ret_stuff, SN_SAL_BUS_CONFIG, 0, get_nasid(), 0, 0, 0, 0, 0);
-	if (ret_stuff.status != 0) {
-		DBG("ifconfig_bus_init: No Address given\n");
-	}
-
-	ioconfig_file = ret_stuff.v0;
-	ioconfig_file_size = ret_stuff.v1;
-	DBG("ioconfig_bus_init: ioconfig_file %p %d\n", 
-		(void *)ioconfig_file, (int)ioconfig_file_size);
-
-	/*
-	 * Convert the address to a Cache Address.
-	 */
-	ioconfig_file = (CACHEABLE_MEM_SPACE | 
-		(ioconfig_file & TO_PHYS_MASK));
-
-	ioconfig_bus_table = kmalloc( 512*sizeof(struct pcipath_to_busnum), 
-				GFP_KERNEL );
-
-	DBG("ioconfig_bus_init: Kernel virtual ioconfig_file %p ioconfig_bus_table %p\n", 
-		(void *)ioconfig_file, (void *)ioconfig_bus_table);
-
-	(void) build_pcibus_name((char *)ioconfig_file, ioconfig_bus_table);
-
-	(void) dump_ioconfig_table(ioconfig_bus_table);
-
-}
-
-/*
- * ioconfig_bus_open - Opens the special device node "/dev/hw/.ioconfig_bus".
- */
-static int ioconfig_bus_open(struct inode * inode, struct file * filp)
-{
-	if (ioconfig_bus_debug) {
-        	printk("ioconfig_bus_open called.\n");
-	}
-
-        return(0);
-
-}
-
-/*
- * ioconfig_bus_close - Closes the special device node "/dev/hw/.ioconfig_bus".
- */
-static int ioconfig_bus_close(struct inode * inode, struct file * filp)
-{
-
-	if (ioconfig_bus_debug) {
-        	printk("ioconfig_bus_close called.\n");
-	}
-
-        return(0);
-}
-
-struct file_operations ioconfig_bus_fops = {
-	/* ioctl:ioconfig_bus_ioctl, ioctl */
-	open:ioconfig_bus_open,		/* open */
-	release:ioconfig_bus_close	/* release */
-};
-
-
-/*
- * init_ifconfig_net() - Boot time initialization.  Ensure that it is called 
- *	after devfs has been initialized.
- *
- */
-int init_ioconfig_bus(void)
-{
-	ioconfig_bus_handle = NULL;
-	ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus",
-			0, DEVFS_FL_AUTO_DEVNUM,
-			0, 0,
-			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-			&ioconfig_bus_fops, NULL);
-
-	if (ioconfig_bus_handle == NULL) {
-		panic("Unable to create SGI PERSISTENT BUS NUMBERING Driver.\n");
-	}
-
-	return(0);
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/ifconfig_net.c linux-2.4.22-pre3/arch/ia64/sn/io/ifconfig_net.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/ifconfig_net.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/ifconfig_net.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,298 +0,0 @@
-/* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- *  ifconfig_net - SGI's Persistent Network Device names.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/ifconfig_net.h>
-
-#define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER"
-#define SGI_IFCONFIG_NET_VERSION "1.0"
-
-/*
- * Some Global definitions.
- */
-devfs_handle_t ifconfig_net_handle = NULL;
-unsigned long ifconfig_net_debug = 0;
-
-/*
- * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net".
- */
-static int ifconfig_net_open(struct inode * inode, struct file * filp)
-{
-	if (ifconfig_net_debug) {
-        	printk("ifconfig_net_open called.\n");
-	}
-
-        return(0);
-
-}
-
-/*
- * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net".
- */
-static int ifconfig_net_close(struct inode * inode, struct file * filp)
-{
-
-	if (ifconfig_net_debug) {
-        	printk("ifconfig_net_close called.\n");
-	}
-
-        return(0);
-}
-
-/*
- * assign_ifname - Assign the next available interface name from the persistent list.
- */
-void
-assign_ifname(struct net_device *dev,
-		  struct ifname_num *ifname_num)
-
-{
-
-	/*
-	 * Handle eth devices.
-	 */
-        if ( (memcmp(dev->name, "eth", 3) == 0) ) {
-		if (ifname_num->next_eth != -1) {
-			/*
-			 * Assign it the next available eth interface number. 
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "eth%d", (int)ifname_num->next_eth);
-			ifname_num->next_eth++;
-		} 
-
-                return;
-        }
-
-	/*
-	 * Handle fddi devices.
-	 */
-	if ( (memcmp(dev->name, "fddi", 4) == 0) ) {
-		if (ifname_num->next_fddi != -1) {
-			/*
-			 * Assign it the next available fddi interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi);
-			ifname_num->next_fddi++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle hip devices.
-	 */
-	if ( (memcmp(dev->name, "hip", 3) == 0) ) {
-		if (ifname_num->next_hip != -1) {
-			/*
-			 * Assign it the next available hip interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "hip%d", (int)ifname_num->next_hip);
-			ifname_num->next_hip++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle tr devices.
-	 */
-	if ( (memcmp(dev->name, "tr", 2) == 0) ) {
-		if (ifname_num->next_tr != -1) {
-			/*
-			 * Assign it the next available tr interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "tr%d", (int)ifname_num->next_tr);
-			ifname_num->next_tr++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle fc devices.
-	 */
-	if ( (memcmp(dev->name, "fc", 2) == 0) ) {
-		if (ifname_num->next_fc != -1) {
-			/*
-			 * Assign it the next available fc interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "fc%d", (int)ifname_num->next_fc);
-			ifname_num->next_fc++;
-		}
-
-		return;
-	}
-}
-
-/*
- * find_persistent_ifname: Returns the entry that was seen in previous boot.
- */
-struct ifname_MAC *
-find_persistent_ifname(struct net_device *dev,
-	struct ifname_MAC *ifname_MAC)
-
-{
-
-	while (ifname_MAC->addr_len) {
-		if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0)
-			return(ifname_MAC);
-
-		ifname_MAC++;
-	}
-
-	return(NULL);
-}
-
-/*
- * ifconfig_net_ioctl: ifconfig_net driver ioctl interface.
- */
-static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
-        unsigned int cmd, unsigned long arg)
-{
-
-	extern struct net_device *__dev_get_by_name(const char *);
-#ifdef CONFIG_NET
-	struct net_device *dev;
-	struct ifname_MAC *found;
-	char temp[64];
-#endif
-	struct ifname_MAC *ifname_MAC;
-	struct ifname_MAC *new_devices, *temp_new_devices;
-	struct ifname_num *ifname_num;
-	unsigned long size;
-
-
-	if (ifconfig_net_debug) {
-		printk("HCL: hcl_ioctl called.\n");
-	}
-
-	/*
-	 * Read in the header and see how big of a buffer we really need to 
-	 * allocate.
-	 */
-	ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), 
-			GFP_KERNEL);
-	copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num));
-	size = ifname_num->size;
-	kfree(ifname_num);
-	ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL);
-	ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) );
-
-	copy_from_user( ifname_num, (char *) arg, size);
-	new_devices =  kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL);
-	temp_new_devices = new_devices;
-
-	memset(new_devices, 0, size - sizeof(struct ifname_num));
-
-#ifdef CONFIG_NET
-	/*
-	 * Go through the net device entries and make them persistent!
-	 */
-	for (dev = dev_base; dev != NULL; dev = dev->next) {
-		/*
-		 * Skip NULL entries or "lo"
-		 */
-		if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){
-			continue;
-		}
-
-		/*
-		 * See if we have a persistent interface name for this device.
-		 */
-		found = NULL;
-		found = find_persistent_ifname(dev, ifname_MAC);
-		if (found) {
-			strcpy(dev->name, found->name);
-		} else {
-			/* Never seen this before .. */
-			assign_ifname(dev, ifname_num);
-
-			/* 
-			 * Save the information for the next boot.
-			 */
- 			sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
-				dev->dev_addr[0],  dev->dev_addr[1],  dev->dev_addr[2],
-				dev->dev_addr[3],  dev->dev_addr[4],  dev->dev_addr[5]);
-			strcpy(temp_new_devices->name, dev->name);
-			temp_new_devices->addr_len = dev->addr_len;
-			memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len);
-			temp_new_devices++;
-		}
-		
-	}
-#endif
-
-	/*
-	 * Copy back to the User Buffer area any new devices encountered.
-	 */
-	copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, 
-			size - sizeof(struct ifname_num));
-
-	return(0);
-
-}
-
-struct file_operations ifconfig_net_fops = {
-	ioctl:ifconfig_net_ioctl,	/* ioctl */
-	open:ifconfig_net_open,		/* open */
-	release:ifconfig_net_close	/* release */
-};
-
-
-/*
- * init_ifconfig_net() - Boot time initialization.  Ensure that it is called 
- *	after devfs has been initialized.
- *
- */
-#ifdef MODULE
-int init_module (void)
-#else
-int __init init_ifconfig_net(void)
-#endif
-{
-	ifconfig_net_handle = NULL;
-	ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net",
-			0, DEVFS_FL_AUTO_DEVNUM,
-			0, 0,
-			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-			&ifconfig_net_fops, NULL);
-
-	if (ifconfig_net_handle == NULL) {
-		panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.\n");
-	}
-
-	return(0);
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/invent.c linux-2.4.22-pre3/arch/ia64/sn/io/invent.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/invent.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/invent.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,224 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * Hardware Inventory
- *
- * See sys/sn/invent.h for an explanation of the hardware inventory contents.
- *
- */
-#include <linux/types.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-void
-inventinit(void)
-{
-}
-
-/*
- * For initializing/updating an inventory entry.
- */
-void
-replace_in_inventory(
-	inventory_t *pinv, int class, int type,
-	int controller, int unit, int state)
-{
-	pinv->inv_class = class;
-	pinv->inv_type = type;
-	pinv->inv_controller = controller;
-	pinv->inv_unit = unit;
-	pinv->inv_state = state;
-}
-
-/*
- * Inventory addition 
- *
- * XXX NOTE: Currently must be called after dynamic memory allocator is
- * initialized.
- *
- */
-void
-add_to_inventory(int class, int type, int controller, int unit, int state)
-{
-	(void)device_inventory_add((devfs_handle_t)GRAPH_VERTEX_NONE, class, type, 
-					controller, unit, state);
-}
-
-
-/*
- * Inventory retrieval 
- *
- * These two routines are intended to prevent the caller from having to know
- * the internal structure of the inventory table.
- *
- * The caller of get_next_inventory is supposed to call start_scan_invent
- * before the irst call to get_next_inventory, and the caller is required
- * to call end_scan_invent after the last call to get_next_inventory.
- */
-inventory_t *
-get_next_inventory(invplace_t *place)
-{
-	inventory_t *pinv;
-	devfs_handle_t device = place->invplace_vhdl;
-	int rv;
-
-	while ((pinv = device_inventory_get_next(device, place)) == NULL) {
-		/*
-		 * We've exhausted inventory items on the last device.
-		 * Advance to next device.
-		 */
-		place->invplace_inv = NULL; /* Start from beginning invent on this device */
-		rv = hwgraph_vertex_get_next(&device, &place->invplace_vplace);
-		if (rv == LABELCL_SUCCESS) {
-			place->invplace_vhdl = device;
-		}
-		else {
-			place->invplace_vhdl = GRAPH_VERTEX_NONE;
-			return(NULL);
-		}
-	}
-
-	return(pinv);
-}
-
-/* ARGSUSED */
-int
-get_sizeof_inventory(int abi)
-{
-	return sizeof(inventory_t);
-}
-
-/* Must be called prior to first call to get_next_inventory */
-void
-start_scan_inventory(invplace_t *iplace)
-{
-	*iplace = INVPLACE_NONE;
-}
-
-/* Must be called after last call to get_next_inventory */
-void
-end_scan_inventory(invplace_t *iplace)
-{
-	devfs_handle_t vhdl = iplace->invplace_vhdl;
-	if (vhdl != GRAPH_VERTEX_NONE)
-		hwgraph_vertex_unref(vhdl);
-	*iplace = INVPLACE_NONE; /* paranoia */
-}
-
-/*
- * Hardware inventory scanner.
- *
- * Calls fun() for every entry in inventory list unless fun() returns something
- * other than 0.
- */
-int
-scaninvent(int (*fun)(inventory_t *, void *), void *arg)
-{
-	inventory_t *ie;
-	invplace_t iplace = { NULL,NULL, NULL };
-	int rc;
-
-	ie = 0;
-	rc = 0;
-	start_scan_inventory(&iplace);
-	while ((ie = (inventory_t *)get_next_inventory(&iplace))) {
-		rc = (*fun)(ie, arg);
-		if (rc)
-			break;
-	}
-	end_scan_inventory(&iplace);
-	return rc;
-}
-
-/*
- * Find a particular inventory object
- *
- * pinv can be a pointer to an inventory entry and the search will begin from
- * there, or it can be 0 in which case the search starts at the beginning.
- * A -1 for any of the other arguments is a wildcard (i.e. it always matches).
- */
-inventory_t *
-find_inventory(inventory_t *pinv, int class, int type, int controller,
-	       int unit, int state)
-{
-	invplace_t iplace =  { NULL,NULL, NULL };
-
-	start_scan_inventory(&iplace);
-	while ((pinv = (inventory_t *)get_next_inventory(&iplace)) != NULL) {
-		if (class != -1 && pinv->inv_class != class)
-			continue;
-		if (type != -1 && pinv->inv_type != type)
-			continue;
-
-		/* XXXX - perhaps the "state" entry should be ignored so an
-		 * an existing entry can be updated.  See vino_init() and
-		 * ml/IP22.c:add_ioboard() for an example.
-		 */
-		if (state != -1 && pinv->inv_state != state)
-			continue;
-		if (controller != -1
-		    && pinv->inv_controller != controller)
-			continue;
-		if (unit != -1 && pinv->inv_unit != unit)
-			continue;
-		break;
-	}
-	end_scan_inventory(&iplace);
-
-	return(pinv);
-}
-
-
-/*
-** Retrieve inventory data associated with a device.
-*/
-inventory_t *
-device_inventory_get_next(	devfs_handle_t device,
-				invplace_t *invplace)
-{
-	inventory_t *pinv;
-	int rv;
-
-	rv = hwgraph_inventory_get_next(device, invplace, &pinv);
-	if (rv == LABELCL_SUCCESS)
-		return(pinv);
-	else
-		return(NULL);
-}
-
-
-/*
-** Associate canonical inventory information with a device (and
-** add it to the general inventory).
-*/
-void
-device_inventory_add(	devfs_handle_t device,
-			int class, 
-			int type, 
-			major_t controller, 
-			minor_t unit, 
-			int state)
-{
-	hwgraph_inventory_add(device, class, type, controller, unit, state);
-}
-
-int
-device_controller_num_get(devfs_handle_t device)
-{
-	return (hwgraph_controller_num_get(device));
-}
-
-void
-device_controller_num_set(devfs_handle_t device, int contr_num)
-{
-	hwgraph_controller_num_set(device, contr_num);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/io.c linux-2.4.22-pre3/arch/ia64/sn/io/io.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/io.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/io.c	2003-07-05 18:09:41.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/config.h>
@@ -29,17 +29,11 @@
 #include <asm/sn/sn_cpuid.h>
 
 extern xtalk_provider_t hub_provider;
-extern void hub_intr_init(devfs_handle_t hubv);
+extern void hub_intr_init(vertex_hdl_t hubv);
 
+static int force_fire_and_forget = 1;
+static int ignore_conveyor_override;
 
-/*
- * Perform any initializations needed to support hub-based I/O.
- * Called once during startup.
- */
-void
-hubio_init(void)
-{
-}
 
 /* 
  * Implementation of hub iobus operations.
@@ -58,8 +52,8 @@
 /*
  * Setup pio structures needed for a particular hub.
  */
-void
-hub_pio_init(devfs_handle_t hubv)
+static void
+hub_pio_init(vertex_hdl_t hubv)
 {
 	xwidgetnum_t widget;
 	hubinfo_t hubinfo;
@@ -114,7 +108,7 @@
  */
 /* ARGSUSED */
 hub_piomap_t
-hub_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
+hub_piomap_alloc(vertex_hdl_t dev,	/* set up mapping for this device */
 		device_desc_t dev_desc,	/* device descriptor */
 		iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
 		size_t byte_count,
@@ -123,7 +117,7 @@
 {
 	xwidget_info_t widget_info = xwidget_info_get(dev);
 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
-	devfs_handle_t hubv = xwidget_info_master_get(widget_info);
+	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
 	hubinfo_t hubinfo;
 	hub_piomap_t bw_piomap;
 	int bigwin, free_bw_index;
@@ -288,7 +282,7 @@
 void
 hub_piomap_free(hub_piomap_t hub_piomap)
 {
-	devfs_handle_t hubv;
+	vertex_hdl_t hubv;
 	hubinfo_t hubinfo;
 	nasid_t nasid;
 	unsigned long s;
@@ -371,7 +365,7 @@
  */
 /* ARGSUSED */
 caddr_t
-hub_piotrans_addr(	devfs_handle_t dev,	/* translate to this device */
+hub_piotrans_addr(	vertex_hdl_t dev,	/* translate to this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			iopaddr_t xtalk_addr,	/* Crosstalk address */
 			size_t byte_count,	/* map this many bytes */
@@ -379,7 +373,7 @@
 {
 	xwidget_info_t widget_info = xwidget_info_get(dev);
 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
-	devfs_handle_t hubv = xwidget_info_master_get(widget_info);
+	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
 	hub_piomap_t hub_piomap;
 	hubinfo_t hubinfo;
 	caddr_t addr;
@@ -416,7 +410,7 @@
  */
 /* ARGSUSED */
 hub_dmamap_t
-hub_dmamap_alloc(	devfs_handle_t dev,	/* set up mappings for this device */
+hub_dmamap_alloc(	vertex_hdl_t dev,	/* set up mappings for this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			size_t byte_count_max, 	/* max size of a mapping */
 			unsigned flags)		/* defined in dma.h */
@@ -424,7 +418,7 @@
 	hub_dmamap_t dmamap;
 	xwidget_info_t widget_info = xwidget_info_get(dev);
 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
-	devfs_handle_t hubv = xwidget_info_master_get(widget_info);
+	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
 
 	dmamap = kmalloc(sizeof(struct hub_dmamap_s), GFP_ATOMIC);
 	dmamap->hdma_xtalk_info.xd_dev = dev;
@@ -460,7 +454,7 @@
 			paddr_t paddr,		/* map for this address */
 			size_t byte_count)	/* map this many bytes */
 {
-	devfs_handle_t vhdl;
+	vertex_hdl_t vhdl;
 
 	ASSERT(dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);
 
@@ -479,12 +473,7 @@
 	}
 
 	/* There isn't actually any DMA mapping hardware on the hub. */
-#ifdef CONFIG_IA64_SGI_SN2
         return( (PHYS_TO_DMA(paddr)) );
-#else
-        /* no translation needed */
-        return(paddr);
-#endif
 }
 
 /*
@@ -498,7 +487,7 @@
 		alenlist_t palenlist,		/* map this area of memory */
 		unsigned flags)
 {
-	devfs_handle_t vhdl;
+	vertex_hdl_t vhdl;
 
 	ASSERT(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);
 
@@ -527,7 +516,7 @@
 void
 hub_dmamap_done(hub_dmamap_t hub_dmamap)	/* done with these mapping resources */
 {
-	devfs_handle_t vhdl;
+	vertex_hdl_t vhdl;
 
 	if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {
 		hub_dmamap->hdma_flags &= ~HUB_DMAMAP_USED;
@@ -549,18 +538,13 @@
  */
 /* ARGSUSED */
 iopaddr_t
-hub_dmatrans_addr(	devfs_handle_t dev,	/* translate for this device */
+hub_dmatrans_addr(	vertex_hdl_t dev,	/* translate for this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			paddr_t paddr,		/* system physical address */
 			size_t byte_count,	/* length */
 			unsigned flags)		/* defined in dma.h */
 {
-#ifdef CONFIG_IA64_SGI_SN2
 	return( (PHYS_TO_DMA(paddr)) );
-#else
-	/* no translation needed */
-	return(paddr);
-#endif
 }
 
 /*
@@ -570,7 +554,7 @@
  */
 /* ARGSUSED */
 alenlist_t
-hub_dmatrans_list(	devfs_handle_t dev,	/* translate for this device */
+hub_dmatrans_list(	vertex_hdl_t dev,	/* translate for this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			alenlist_t palenlist,	/* system address/length list */
 			unsigned flags)		/* defined in dma.h */
@@ -589,7 +573,7 @@
 
 /*ARGSUSED*/
 void
-hub_dmaaddr_drain(	devfs_handle_t vhdl,
+hub_dmaaddr_drain(	vertex_hdl_t vhdl,
 			paddr_t addr,
 			size_t bytes)
 {
@@ -598,7 +582,7 @@
 
 /*ARGSUSED*/
 void
-hub_dmalist_drain(	devfs_handle_t vhdl,
+hub_dmalist_drain(	vertex_hdl_t vhdl,
 			alenlist_t list)
 {
     /* XXX- flush caches, if cache coherency WAR is needed */
@@ -612,10 +596,8 @@
  * Perform initializations that allow this hub to start crosstalk support.
  */
 void
-hub_provider_startup(devfs_handle_t hubv)
+hub_provider_startup(vertex_hdl_t hubv)
 {
-	extern void hub_pio_init(devfs_handle_t hubv);
-
 	hub_pio_init(hubv);
 	hub_intr_init(hubv);
 }
@@ -624,14 +606,14 @@
  * Shutdown crosstalk support from a hub.
  */
 void
-hub_provider_shutdown(devfs_handle_t hub)
+hub_provider_shutdown(vertex_hdl_t hub)
 {
 	/* TBD */
 	xtalk_provider_unregister(hub);
 }
 
 /*
- * Check that an address is in teh real small window widget 0 space
+ * Check that an address is in the real small window widget 0 space
  * or else in the big window we're using to emulate small window 0
  * in the kernel.
  */
@@ -666,49 +648,9 @@
 
 
 /*
- * Determine whether two PCI addresses actually refer to the same device.
- * This only works if both addresses are in small windows.  It's used to
- * determine whether prom addresses refer to particular PCI devices.
- */
-/*	
- * XXX - This won't work as written if we ever have more than two nodes
- * on a crossbow.  In that case, we'll need an array or partners.
- */
-int
-hub_check_pci_equiv(void *addra, void *addrb)
-{
-	nasid_t nasida, nasidb;
-
-	/*
-	 * This is for a permanent workaround that causes us to use a
-	 * big window in place of small window 0.
-	 */
-	if (!hub_check_window_equiv(addra, addrb))
-		return 0;
-
-	/* If the offsets aren't the same, forget it. */
-	if (SWIN_WIDGETADDR((__psunsigned_t)addra) !=
-	    (SWIN_WIDGETADDR((__psunsigned_t)addrb)))
-		return 0;
-
-	/* Now, check the nasids */
-	nasida = NASID_GET(addra);
-	nasidb = NASID_GET(addrb);
-
-	ASSERT(NASID_TO_COMPACT_NODEID(nasida) != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasidb) != INVALID_NASID);
-
-	/*
-	 * Either the NASIDs must be the same or they must be crossbow
-	 * partners (on the same crossbow).
-	 */
-	return (check_nasid_equiv(nasida, nasidb));
-}
-
-/*
  * hub_setup_prb(nasid, prbnum, credits, conveyor)
  *
- * 	Put a PRB into fire-and-forget mode if conveyor isn't set.  Otehrwise,
+ * 	Put a PRB into fire-and-forget mode if conveyor isn't set.  Otherwise,
  * 	put it into conveyor belt mode with the specified number of credits.
  */
 void
@@ -716,8 +658,6 @@
 {
 	iprb_t prb;
 	int prb_offset;
-	extern int force_fire_and_forget;
-	extern volatile int ignore_conveyor_override;
 
 	if (force_fire_and_forget && !ignore_conveyor_override)
 	    if (conveyor == HUB_PIO_CONVEYOR)
@@ -776,13 +716,8 @@
 	int direct_connect;
 	hubii_wcr_t ii_wcr;
 	int prbnum;
-	int cons_lock = 0;
 
 	ASSERT(NASID_TO_COMPACT_NODEID(nasid) != INVALID_CNODEID);
-	if (nasid == get_console_nasid()) {
-		PUTBUF_LOCK(s);	
-		cons_lock = 1;
-	}
 
 	ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS);
 	REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0);
@@ -812,9 +747,6 @@
 	}
 
 	REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa);
-
-	if (cons_lock)
-	    PUTBUF_UNLOCK(s);
 }
 /* Interface to allow special drivers to set hub specific
  * device flags.
@@ -842,90 +774,6 @@
 
 	return 1;
 }
-/* Interface to allow special drivers to set hub specific
- * device flags.
- * Return 0 on failure , 1 on success
- */
-int
-hub_device_flags_set(devfs_handle_t	widget_vhdl,
-		     hub_widget_flags_t	flags)
-{
-	xwidget_info_t		widget_info = xwidget_info_get(widget_vhdl);
-	xwidgetnum_t		widget_num  = xwidget_info_id_get(widget_info);
-	devfs_handle_t		hub_vhdl    = xwidget_info_master_get(widget_info);
-	hubinfo_t		hub_info = 0;
-	nasid_t			nasid;
-	unsigned long		s;
-	int			rv;
-
-	/* Use the nasid from the hub info hanging off the hub vertex
-	 * and widget number from the widget vertex
-	 */
-	hubinfo_get(hub_vhdl, &hub_info);
-	/* Being over cautious by grabbing a lock */
-	s 	= mutex_spinlock(&hub_info->h_bwlock);
-	nasid 	= hub_info->h_nasid;
-	rv 	= hub_widget_flags_set(nasid,widget_num,flags);
-	mutex_spinunlock(&hub_info->h_bwlock, s);
-
-	return rv;
-}
-
-/*
- * hub_device_inquiry
- *	Find out the xtalk widget related information stored in this 
- *	hub's II.
- */
-void
-hub_device_inquiry(devfs_handle_t	xbus_vhdl, xwidgetnum_t widget)
-{
-	devfs_handle_t	xconn, hub_vhdl;
-	char		widget_name[8];
-	hubreg_t	ii_iidem,ii_iiwa, ii_iowa;
-	hubinfo_t	hubinfo;
-	nasid_t		nasid;
-	int		d;
-
-	sprintf(widget_name, "%d", widget);
-	if (hwgraph_traverse(xbus_vhdl, widget_name, &xconn)
-	    != GRAPH_SUCCESS)
-		return;
-
-	hub_vhdl = device_master_get(xconn);
-	if (hub_vhdl == GRAPH_VERTEX_NONE)
-		return;
-
-	hubinfo_get(hub_vhdl, &hubinfo);
-	if (!hubinfo)
-		return;
-	
-	nasid = hubinfo->h_nasid;
-
-	ii_iidem	= REMOTE_HUB_L(nasid, IIO_IIDEM);
-	ii_iiwa 	= REMOTE_HUB_L(nasid, IIO_IIWA);
-	ii_iowa 	= REMOTE_HUB_L(nasid, IIO_IOWA);
-
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	printk("Inquiry Info for %v\n", xconn);
-#else
-	printk("Inquiry Info for %p\n", (void *)xconn);
-#endif
-
-	printk("\tDevices shutdown [ ");
-
-	for (d = 0 ; d <= 7 ; d++)
-		if (!(ii_iidem & (IIO_IIDEM_WIDGETDEV_MASK(widget,d))))
-			printk(" %d", d);
-
-	printk("]\n");
-
-	printk("\tInbound access ? %s\n",
-		ii_iiwa & IIO_IIWA_WIDGET(widget) ? "yes" : "no");
-
-	printk("\tOutbound access ? %s\n",
-		ii_iowa & IIO_IOWA_WIDGET(widget) ? "yes" : "no");
-
-}
 
 /*
  * A pointer to this structure hangs off of every hub hwgraph vertex.
@@ -955,8 +803,6 @@
 	(xtalk_intr_free_f *)		hub_intr_free,
 	(xtalk_intr_connect_f *)	hub_intr_connect,
 	(xtalk_intr_disconnect_f *)	hub_intr_disconnect,
-	(xtalk_intr_cpu_get_f *)	hub_intr_cpu_get,
-
 	(xtalk_provider_startup_f *)	hub_provider_startup,
 	(xtalk_provider_shutdown_f *)	hub_provider_shutdown,
 };
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/klconflib.c linux-2.4.22-pre3/arch/ia64/sn/io/klconflib.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/klconflib.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/klconflib.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1046 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/ctype.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/module.h>
-#include <asm/sn/router.h>
-#include <asm/sn/xtalk/xbow.h>
-
-#define printf printk
-int hasmetarouter;
-
-#define LDEBUG 0
-#define NIC_UNKNOWN ((nic_t) -1)
-
-#undef DEBUG_KLGRAPH
-#ifdef DEBUG_KLGRAPH
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_KLGRAPH */
-
-static void sort_nic_names(lboard_t *) ;
-
-u64 klgraph_addr[MAX_COMPACT_NODES];
-int module_number = 0;
-
-lboard_t *
-find_lboard(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (start->brd_type == brd_type)
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_class(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-klinfo_t *
-find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
-{
-	int index, j;
-
-	if (kli == (klinfo_t *)NULL) {
-		index = 0;
-	} else {
-		for (j = 0; j < KLCF_NUM_COMPS(brd); j++) {
-			if (kli == KLCF_COMP(brd, j))
-				break;
-		}
-		index = j;
-		if (index == KLCF_NUM_COMPS(brd)) {
-			DBG("find_component: Bad pointer: 0x%p\n", kli);
-			return (klinfo_t *)NULL;
-		}
-		index++;	/* next component */
-	}
-	
-	for (; index < KLCF_NUM_COMPS(brd); index++) {		
-		kli = KLCF_COMP(brd, index);
-		DBG("find_component: brd %p kli %p  request type = 0x%x kli type 0x%x\n", brd, kli, kli->struct_type, KLCF_COMP_TYPE(kli));
-		if (KLCF_COMP_TYPE(kli) == struct_type)
-			return kli;
-	}
-
-	/* Didn't find it. */
-	return (klinfo_t *)NULL;
-}
-
-klinfo_t *
-find_first_component(lboard_t *brd, unsigned char struct_type)
-{
-	return find_component(brd, (klinfo_t *)NULL, struct_type);
-}
-
-lboard_t *
-find_lboard_modslot(lboard_t *start, moduleid_t mod, slotid_t slot)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (MODULE_MATCH(start->brd_module, mod) &&
-		    (start->brd_slot == slot))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_module(lboard_t *start, moduleid_t mod)
-{
-        /* Search all boards stored on this node. */
-        while (start) {
-                if (MODULE_MATCH(start->brd_module, mod))
-                        return start;
-                start = KLCF_NEXT(start);
-        }
-
-        /* Didn't find it. */
-        return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_module_class(lboard_t *start, moduleid_t mod,
-                                                unsigned char brd_type)
-{
-	while (start) {
-
-		DBG("find_lboard_module_class: lboard 0x%p, start->brd_module 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_module, mod, start->brd_type, brd_type);
-
-		if (MODULE_MATCH(start->brd_module, mod) &&
-			(KLCLASS(start->brd_type) == KLCLASS(brd_type)))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-
-/*
- * Convert a NIC name to a name for use in the hardware graph.
- */
-void
-nic_name_convert(char *old_name, char *new_name)
-{
-        int i;
-        char c;
-        char *compare_ptr;
-
-	if ((old_name[0] == '\0') || (old_name[1] == '\0')) {
-                strcpy(new_name, EDGE_LBL_XWIDGET);
-        } else {
-                for (i = 0; i < strlen(old_name); i++) {
-                        c = old_name[i];
-
-                        if (isalpha(c))
-                                new_name[i] = tolower(c);
-                        else if (isdigit(c))
-                                new_name[i] = c;
-                        else
-                                new_name[i] = '_';
-                }
-                new_name[i] = '\0';
-        }
-
-        /* XXX -
-         * Since a bunch of boards made it out with weird names like
-         * IO6-fibbbed and IO6P2, we need to look for IO6 in a name and
-         * replace it with "baseio" to avoid confusion in the field.
-	 * We also have to make sure we don't report media_io instead of
-	 * baseio.
-         */
-
-        /* Skip underscores at the beginning of the name */
-        for (compare_ptr = new_name; (*compare_ptr) == '_'; compare_ptr++)
-                ;
-
-	/*
-	 * Check for some names we need to replace.  Early boards
-	 * had junk following the name so check only the first
-	 * characters.
-	 */
-        if (!strncmp(new_name, "io6", 3) || 
-            !strncmp(new_name, "mio", 3) || 
-	    !strncmp(new_name, "media_io", 8))
-		strcpy(new_name, "baseio");
-	else if (!strncmp(new_name, "divo", 4))
-		strcpy(new_name, "divo") ;
-
-}
-
-/* Check if the given board corresponds to the global 
- * master io6
- */
-int
-is_master_baseio(nasid_t nasid,moduleid_t module,slotid_t slot)
-{
-	lboard_t	*board;
-
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-/* If this works then look for callers of is_master_baseio()
- * (e.g. iograph.c) and let them pass in a slot if they want
- */
-	board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), module);
-#else
-	board = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), module, slot);
-#endif
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!board && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-			board = find_lboard_module((lboard_t *)
-				    KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				    module);
-#else
-			board = find_lboard_modslot((lboard_t *)
-				    KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				    module, slot);
-#endif
-	}
-#endif
-	if (!board)
-		return(0);
-	return(board->brd_flags & GLOBAL_MASTER_IO6);
-}
-/*
- * Find the lboard structure and get the board name.
- * If we can't find the structure or it's too low a revision,
- * use default name.
- */
-lboard_t *
-get_board_name(nasid_t nasid, moduleid_t mod, slotid_t slot, char *name)
-{
-	lboard_t *brd;
-
-	brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid),
-				  mod, slot);
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-			brd = find_lboard_modslot((lboard_t *)
-				KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				mod, slot);
-	}
-#endif
-
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, name);
-	}
-
-	/*
- 	 * PV # 540860
-	 * If the name is not 'baseio' 
-	 * get the lowest of all the names in the nic string.
-	 * This is needed for boards like divo, which can have
-	 * a bunch of daughter cards, but would like to be called
-	 * divo. We could do this for baseio 
- 	 * but it has some special case names that we would not
- 	 * like to disturb at this point.
-	 */
-
-	/* gfx boards don't need any of this name scrambling */
-	if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) {
-		return(brd);
-	}
-
-	if (!(!strcmp(name, "baseio") )) {
-		if (brd) {
-			sort_nic_names(brd) ;
-			/* Convert to small case, '-' to '_' etc */
-			nic_name_convert(brd->brd_name, name) ;
-		}
-	}
-
-	return(brd);
-}
-
-/*
- * get_actual_nasid
- *
- *	Completely disabled brds have their klconfig on 
- *	some other nasid as they have no memory. But their
- *	actual nasid is hidden in the klconfig. Use this
- *	routine to get it. Works for normal boards too.
- */
-nasid_t
-get_actual_nasid(lboard_t *brd)
-{
-	klhub_t	*hub ;
-
-	if (!brd)
-		return INVALID_NASID ;
-
-	/* find out if we are a completely disabled brd. */
-
-        hub  = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-	if (!hub)
-                return INVALID_NASID ;
-	if (!(hub->hub_info.flags & KLINFO_ENABLE))	/* disabled node brd */
-		return hub->hub_info.physid ;
-	else
-		return brd->brd_nasid ;
-}
-
-int
-xbow_port_io_enabled(nasid_t nasid, int link)
-{
-	lboard_t *brd;
-	klxbow_t *xbow_p;
-
-	/*
-	 * look for boards that might contain an xbow or xbridge
-	 */
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW);
-	if (brd == NULL) return 0;
-		
-	if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
-	    == NULL)
-	    return 0;
-
-	if (!XBOW_PORT_TYPE_IO(xbow_p, link) || !XBOW_PORT_IS_ENABLED(xbow_p, link))
-	    return 0;
-
-	DBG("xbow_port_io_enabled:  brd 0x%p xbow_p 0x%p \n", brd, xbow_p);
-
-	return 1;
-}
-
-void
-board_to_path(lboard_t *brd, char *path)
-{
-	moduleid_t modnum;
-	char *board_name;
-
-	ASSERT(brd);
-
-	switch (KLCLASS(brd->brd_type)) {
-
-		case KLCLASS_NODE:
-			board_name = EDGE_LBL_NODE;
-			break;
-		case KLCLASS_ROUTER:
-			if (brd->brd_type == KLTYPE_META_ROUTER) {
-				board_name = EDGE_LBL_META_ROUTER;
-				hasmetarouter++;
-			} else if (brd->brd_type == KLTYPE_REPEATER_ROUTER) {
-				board_name = EDGE_LBL_REPEATER_ROUTER;
-				hasmetarouter++;
-			} else
-				board_name = EDGE_LBL_ROUTER;
-			break;
-		case KLCLASS_MIDPLANE:
-			board_name = EDGE_LBL_MIDPLANE;
-			break;
-		case KLCLASS_IO:
-			board_name = EDGE_LBL_IO;
-			break;
-		case KLCLASS_IOBRICK:
-			if (brd->brd_type == KLTYPE_PBRICK)
-				board_name = EDGE_LBL_PBRICK;
-			else if (brd->brd_type == KLTYPE_IBRICK)
-				board_name = EDGE_LBL_IBRICK;
-			else if (brd->brd_type == KLTYPE_XBRICK)
-				board_name = EDGE_LBL_XBRICK;
-			else
-				board_name = EDGE_LBL_IOBRICK;
-			break;
-		default:
-			board_name = EDGE_LBL_UNKNOWN;
-	}
-			
-	modnum = brd->brd_module;
-
-	/* ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE); */
-if ((modnum == MODULE_UNKNOWN) || (modnum == INVALID_MODULE)) {
-	modnum = ++module_number;
-}
-#ifdef __ia64
-	{
-		char	buffer[16];
-		memset(buffer, 0, 16);
-		format_module_id(buffer, modnum, MODULE_FORMAT_BRIEF);
-		sprintf(path, EDGE_LBL_MODULE "/%s/%s", buffer, board_name);
-	}
-#else
-	sprintf(path, "%H/%s", modnum, board_name);
-#endif
-}
-
-/*
- * Get the module number for a NASID.
- */
-moduleid_t
-get_module_id(nasid_t nasid)
-{
-	lboard_t *brd;
-
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-
-	if (!brd)
-		return INVALID_MODULE;
-	else
-		return brd->brd_module;
-}
-
-
-#define MHZ	1000000
-
-
-/* Get the canonical hardware graph name for the given pci component
- * on the given io board.
- */
-void
-device_component_canonical_name_get(lboard_t 	*brd,
-				    klinfo_t 	*component,
-				    char 	*name)
-{
-	moduleid_t 	modnum;
-	slotid_t 	slot;
-	char 		board_name[20];
-
-	ASSERT(brd);
-
-	/* Get the module number of this board */
-	modnum = brd->brd_module;
-
-	/* Convert the [ CLASS | TYPE ] kind of slotid
-	 * into a string 
-	 */
-	slot = brd->brd_slot;
-	ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE);
-
-	/* Get the io board name  */
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, board_name);
-	}
-
-	/* Give out the canonical  name of the pci device*/
-	sprintf(name, 
-		"/dev/hw/"EDGE_LBL_MODULE "/%x/"EDGE_LBL_SLOT"/%s/"
-		EDGE_LBL_PCI"/%d", 
-		modnum, board_name,KLCF_BRIDGE_W_ID(component));
-}
-
-/*
- * Get the serial number of the main  component of a board
- * Returns 0 if a valid serial number is found
- * 1 otherwise.
- * Assumptions: Nic manufacturing string  has the following format
- *			*Serial:<serial_number>;*
- */
-static int
-component_serial_number_get(lboard_t 		*board,
-			    klconf_off_t 	mfg_nic_offset,
-			    char		*serial_number,
-			    char		*key_pattern)
-{
-
-	char	*mfg_nic_string;
-	char	*serial_string,*str;
-	int	i;
-	char	*serial_pattern = "Serial:";
-
-	/* We have an error on a null mfg nic offset */
-	if (!mfg_nic_offset)
-		return(1);
-	/* Get the hub's manufacturing nic information
-	 * which is in the form of a pre-formatted string
-	 */
-	mfg_nic_string = 
-		(char *)NODE_OFFSET_TO_K0(NASID_GET(board),
-					  mfg_nic_offset);
-	/* There is no manufacturing nic info */
-	if (!mfg_nic_string)
-		return(1);
-
-	str = mfg_nic_string;
-	/* Look for the key pattern first (if it is  specified)
-	 * and then print the serial number corresponding to that.
-	 */
-	if (strcmp(key_pattern,"") && 
-	    !(str = strstr(mfg_nic_string,key_pattern)))
-		return(1);
-
-	/* There is no serial number info in the manufacturing
-	 * nic info
-	 */
-	if (!(serial_string = strstr(str,serial_pattern)))
-		return(1);
-
-	serial_string = serial_string + strlen(serial_pattern);
-	/*  Copy the serial number information from the klconfig */
-	i = 0;
-	while (serial_string[i] != ';') {
-		serial_number[i] = serial_string[i];
-		i++;
-	}
-	serial_number[i] = 0;
-	
-	return(0);
-}
-/*
- * Get the serial number of a board
- * Returns 0 if a valid serial number is found
- * 1 otherwise.
- */
-
-int
-board_serial_number_get(lboard_t *board,char *serial_number)
-{
-	ASSERT(board && serial_number);
-	if (!board || !serial_number)
-		return(1);
-
-	strcpy(serial_number,"");
-	switch(KLCLASS(board->brd_type)) {
-	case KLCLASS_CPU: {	/* Node board */
-		klhub_t	*hub;
-		
-		/* Get the hub component information */
-		hub = (klhub_t *)find_first_component(board,
-						      KLSTRUCT_HUB);
-		/* If we don't have a hub component on an IP27
-		 * then we have a weird klconfig.
-		 */
-		if (!hub)
-			return(1);
-		/* Get the serial number information from
-		 * the hub's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						hub->hub_mfg_nic,
-						serial_number,
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-						"IP37"))
-#else
-						"IP27"))
-			/* Try with IP31 key if IP27 key fails */
-			if (component_serial_number_get(board,
-							hub->hub_mfg_nic,
-							serial_number,
-							"IP31"))
-#endif /* CONFIG_IA64_SGI_SN1 */
-				return(1);
-		break;
-	}
-	case KLCLASS_IO: {	/* IO board */
-		if (KLTYPE(board->brd_type) == KLTYPE_TPU) {
-		/* Special case for TPU boards */
-			kltpu_t *tpu;	
-		
-			/* Get the tpu component information */
-			tpu = (kltpu_t *)find_first_component(board,
-						      KLSTRUCT_TPU);
-			/* If we don't have a tpu component on a tpu board
-			 * then we have a weird klconfig.
-			 */
-			if (!tpu)
-				return(1);
-			/* Get the serial number information from
-			 * the tpu's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						tpu->tpu_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		} else  if ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ||
-		            (KLTYPE(board->brd_type) == KLTYPE_GSN_B)) {
-		/* Special case for GSN boards */
-			klgsn_t *gsn;	
-		
-			/* Get the gsn component information */
-			gsn = (klgsn_t *)find_first_component(board,
-			      ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ?
-					KLSTRUCT_GSN_A : KLSTRUCT_GSN_B));
-			/* If we don't have a gsn component on a gsn board
-			 * then we have a weird klconfig.
-			 */
-			if (!gsn)
-				return(1);
-			/* Get the serial number information from
-			 * the gsn's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						gsn->gsn_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		} else {
-		     	klbri_t	*bridge;
-		
-			/* Get the bridge component information */
-			bridge = (klbri_t *)find_first_component(board,
-							 KLSTRUCT_BRI);
-			/* If we don't have a bridge component on an IO board
-			 * then we have a weird klconfig.
-			 */
-			if (!bridge)
-				return(1);
-			/* Get the serial number information from
-		 	 * the bridge's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						bridge->bri_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		}
-	}
-	case KLCLASS_ROUTER: {	/* Router board */
-		klrou_t *router;	
-		
-		/* Get the router component information */
-		router = (klrou_t *)find_first_component(board,
-							 KLSTRUCT_ROU);
-		/* If we don't have a router component on a router board
-		 * then we have a weird klconfig.
-		 */
-		if (!router)
-			return(1);
-		/* Get the serial number information from
-		 * the router's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						router->rou_mfg_nic,
-						serial_number,
-						""))
-			return(1);
-		break;
-	}
-	case KLCLASS_GFX: {	/* Gfx board */
-		klgfx_t *graphics;
-		
-		/* Get the graphics component information */
-		graphics = (klgfx_t *)find_first_component(board, KLSTRUCT_GFX);
-		/* If we don't have a gfx component on a gfx board
-		 * then we have a weird klconfig.
-		 */
-		if (!graphics)
-			return(1);
-		/* Get the serial number information from
-		 * the graphics's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						graphics->gfx_mfg_nic,
-						serial_number,
-						""))
-			return(1);
-		break;
-	}
-	default:
-		strcpy(serial_number,"");
-		break;
-	}
-	return(0);
-}
-
-#include "asm/sn/sn_private.h"
-
-xwidgetnum_t
-nodevertex_widgetnum_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, 
-			     (arbitrary_info_t *) &hubinfo_p);
-	return(hubinfo_p->h_widgetid);
-}
-
-devfs_handle_t
-nodevertex_xbow_peer_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-	nasid_t xbow_peer_nasid;
-	cnodeid_t xbow_peer;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO,
-				     (arbitrary_info_t *) &hubinfo_p);
-	xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer;
-	if(xbow_peer_nasid == INVALID_NASID) 
-			return ( (devfs_handle_t)-1);
-	xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid);
-	return(NODEPDA(xbow_peer)->node_vertex);
-}
-
-/* NIC Sorting Support */
-
-#define MAX_NICS_PER_STRING 	32
-#define MAX_NIC_NAME_LEN	32
-
-static char *
-get_nic_string(lboard_t *lb)
-{
-        int         	i;
-        klinfo_t    	*k = NULL ;
-    	klconf_off_t    mfg_off = 0 ;
-    	char            *mfg_nic = NULL ;
-
-        for (i = 0; i < KLCF_NUM_COMPS(lb); i++) {
-                k = KLCF_COMP(lb, i) ;
-                switch(k->struct_type) {
-                        case KLSTRUCT_BRI:
-            			mfg_off = ((klbri_t *)k)->bri_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_HUB:
-            			mfg_off = ((klhub_t *)k)->hub_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_ROU:
-            			mfg_off = ((klrou_t *)k)->rou_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GFX:
-            			mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_TPU:
-            			mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GSN_A:
-                        case KLSTRUCT_GSN_B:
-            			mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_XTHD:
-                                mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ;
-                                break;
-
-			default:
-				mfg_off = 0 ;
-                                break ;
-                }
-		if (mfg_off)
-			break ;
-        }
-
-	if ((mfg_off) && (k))
-		mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ;
-
-        return mfg_nic ;
-}
-
-char *
-get_first_string(char **ptrs, int n)
-{
-        int     i ;
-        char    *tmpptr ;
-
-        if ((ptrs == NULL) || (n == 0))
-                return NULL ;
-
-        tmpptr = ptrs[0] ;
-
-        if (n == 1)
-                return tmpptr ;
-
-        for (i = 0 ; i < n ; i++) {
-                if (strcmp(tmpptr, ptrs[i]) > 0)
-                        tmpptr = ptrs[i] ;
-        }
-
-        return tmpptr ;
-}
-
-int
-get_ptrs(char *idata, char **ptrs, int n, char *label)
-{
-        int     i = 0 ;
-        char    *tmp = idata ;
-
-        if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0))
-                return 0 ;
-
-        while  ( (tmp = strstr(tmp, label)) ){
-                tmp += strlen(label) ;
-                /* check for empty name field, and last NULL ptr */
-                if ((i < (n-1)) && (*tmp != ';')) {
-                        ptrs[i++] = tmp ;
-                }
-        }
-
-        ptrs[i] = NULL ;
-
-        return i ;
-}
-
-/*
- * sort_nic_names
- *
- * 	Does not really do sorting. Find the alphabetically lowest
- *	name among all the nic names found in a nic string.
- *
- * Return:
- *	Nothing
- *
- * Side Effects:
- *
- *	lb->brd_name gets the new name found
- */
-
-static void
-sort_nic_names(lboard_t *lb)
-{
-	char 	*nic_str ;
-        char    *ptrs[MAX_NICS_PER_STRING] ;
-        char    name[MAX_NIC_NAME_LEN] ;
-        char    *tmp, *tmp1 ;
-
-	*name = 0 ;
-
-	/* Get the nic pointer from the lb */
-
-	if ((nic_str = get_nic_string(lb)) == NULL)
-		return ;
-
-        tmp = get_first_string(ptrs,
-                        get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ;
-
-        if (tmp == NULL)
-		return ;
-
-        if  ( (tmp1 = strchr(tmp, ';')) ){
-                strncpy(name, tmp, tmp1-tmp) ;
-                name[tmp1-tmp] = 0 ;
-        } else {
-                strncpy(name, tmp, (sizeof(name) -1)) ;
-                name[sizeof(name)-1] = 0 ;
-        }
-
-	strcpy(lb->brd_name, name) ;
-}
-
-
-
-char brick_types[MAX_BRICK_TYPES + 1] = "crikxdp789012345";
-
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-
-/*
- * Format a module id for printing.
- */
-void
-format_module_id(char *buffer, moduleid_t m, int fmt)
-{
-	int rack, position;
-	char brickchar;
-
-	rack = MODULE_GET_RACK(m);
-	ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES);
-	brickchar = MODULE_GET_BTCHAR(m);
-	position = MODULE_GET_BPOS(m);
-
-	if (fmt == MODULE_FORMAT_BRIEF) {
-	    /* Brief module number format, eg. 002c15 */
-
-	    /* Decompress the rack number */
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
-
-	    /* Add the brick type */
-	    *buffer++ = brickchar;
-	}
-	else if (fmt == MODULE_FORMAT_LONG) {
-	    /* Fuller hwgraph format, eg. rack/002/bay/15 */
-
-	    strcpy(buffer, EDGE_LBL_RACK "/");  buffer += strlen(buffer);
-
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
-
-	    strcpy(buffer, "/" EDGE_LBL_RPOS "/");  buffer += strlen(buffer);
-	}
-
-	/* Add the bay position, using at least two digits */
-	if (position < 10)
-	    *buffer++ = '0';
-	sprintf(buffer, "%d", position);
-
-}
-
-/*
- * Parse a module id, in either brief or long form.
- * Returns < 0 on error.
- * The long form does not include a brick type, so it defaults to 0 (CBrick)
- */
-int
-parse_module_id(char *buffer)
-{
-	unsigned int	v, rack, bay, type, form;
-	moduleid_t	m;
-	char 		c;
-
-	if (strstr(buffer, EDGE_LBL_RACK "/") == buffer) {
-		form = MODULE_FORMAT_LONG;
-		buffer += strlen(EDGE_LBL_RACK "/");
-
-		/* A long module ID must be exactly 5 non-template chars. */
-		if (strlen(buffer) != strlen("/" EDGE_LBL_RPOS "/") + 5)
-			return -1;
-	}
-	else {
-		form = MODULE_FORMAT_BRIEF;
-
-		/* A brief module id must be exactly 6 characters */
-		if (strlen(buffer) != 6)
-			return -2;
-	}
-
-	/* The rack number must be exactly 3 digits */
-	if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && isdigit(buffer[2])))
-		return -3;
-
-	rack = 0;
-	v = *buffer++ - '0';
-	if (v > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-		return -4;
-	RACK_ADD_CLASS(rack, v);
-
-	v = *buffer++ - '0';
-	if (v > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-		return -5;
-	RACK_ADD_GROUP(rack, v);
-
-	v = *buffer++ - '0';
-	/* rack numbers are 1-based */
-	if (v-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-		return -6;
-	RACK_ADD_NUM(rack, v);
-
-	if (form == MODULE_FORMAT_BRIEF) {
-		/* Next should be a module type character.  Accept ucase or lcase. */
-		c = *buffer++;
-		if (!isalpha(c))
-			return -7;
-
-		/* strchr() returns a pointer into brick_types[], or NULL */
-		type = (unsigned int)(strchr(brick_types, tolower(c)) - brick_types);
-		if (type > MODULE_BTYPE_MASK >> MODULE_BTYPE_SHFT)
-			return -8;
-	}
-	else {
-		/* Hardcode the module type, and skip over the boilerplate */
-		type = MODULE_CBRICK;
-
-		if (strstr(buffer, "/" EDGE_LBL_RPOS "/") != buffer)
-			return -9;
-
-		buffer += strlen("/" EDGE_LBL_RPOS "/");
-	}
-		
-	/* The bay number is last.  Make sure it's exactly two digits */
-
-	if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && !buffer[2]))
-		return -10;
-
-	bay = 10 * (buffer[0] - '0') + (buffer[1] - '0');
-
-	if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-		return -11;
-
-	m = RBT_TO_MODULE(rack, bay, type);
-
-	/* avoid sign extending the moduleid_t */
-	return (int)(unsigned short)m;
-}
-
-#else /* CONFIG_IA64_SGI_SN1 */
-
-/*
- * Format a module id for printing.
- */
-void
-format_module_id(char *buffer, moduleid_t m, int fmt)
-{
-    if (fmt == MODULE_FORMAT_BRIEF) {
-		sprintf(buffer, "%d", m);
-    }
-    else if (fmt == MODULE_FORMAT_LONG) {
-		sprintf(buffer, EDGE_LBL_MODULE "/%d", m);
-    }
-}
-
-/*
- * Parse a module id, in either brief or long form.
- * Returns < 0 on error.
- */
-int
-parse_module_id(char *buffer)
-{
-    moduleid_t m;
-    char c;
-
-    if (strstr(buffer, EDGE_LBL_MODULE "/") == buffer)
-	buffer += strlen(EDGE_LBL_MODULE "/");
-
-    for (m = 0; *buffer; buffer++) {
-	c = *buffer;
-	if (!isdigit(c))
-	    return -1;
-	m = 10 * m + (c - '0');
-    }
-
-    /* avoid sign extending the moduleid_t */
-    return (int)(unsigned short)m;
-}
-
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/klgraph.c linux-2.4.22-pre3/arch/ia64/sn/io/klgraph.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/klgraph.c	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/klgraph.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,795 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * klgraph.c-
- *      This file specifies the interface between the kernel and the PROM's
- *      configuration data structures.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/kldir.h>
-#include <asm/sn/gda.h> 
-#include <asm/sn/klconfig.h>
-#include <asm/sn/router.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/hcl_util.h>
-
-/* #define KLGRAPH_DEBUG 1 */
-#ifdef KLGRAPH_DEBUG
-#define GRPRINTF(x)	printk x
-#define CE_GRPANIC	CE_PANIC
-#else
-#define GRPRINTF(x)
-#define CE_GRPANIC	CE_PANIC
-#endif
-
-#include <asm/sn/sn_private.h>
-
-extern char arg_maxnodes[];
-extern u64 klgraph_addr[];
-
-/*
- * Support for verbose inventory via hardware graph. 
- * klhwg_invent_alloc allocates the necessary size of inventory information
- * and fills in the generic information.
- */
-invent_generic_t *
-klhwg_invent_alloc(cnodeid_t cnode, int class, int size)
-{
-	invent_generic_t *invent;
-
-	invent = kern_malloc(size);
-	if (!invent) return NULL;
-	
-	invent->ig_module = NODE_MODULEID(cnode);
-	invent->ig_slot = SLOTNUM_GETSLOT(NODE_SLOTID(cnode));
-	invent->ig_invclass = class;
-
-	return invent;
-}
-
-/* 
- * Add information about the baseio prom version number
- * as a part of detailed inventory info in the hwgraph.
- */
-void
-klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode)
-{
-	invent_miscinfo_t	*baseio_inventory;
-	unsigned char		version = 0,revision = 0;
-
-	/* Allocate memory for the "detailed inventory" info
-	 * for the baseio
-	 */
-	baseio_inventory = (invent_miscinfo_t *) 
-		klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t));
-	baseio_inventory->im_type = INV_IO6PROM;
-	/* Read the io6prom revision from the nvram */
-#ifdef LATER
-	nvram_prom_version_get(&version,&revision);
-#endif
-	/* Store the revision info  in the inventory */
-	baseio_inventory->im_version = version;
-	baseio_inventory->im_rev = revision;
-	/* Put the inventory info in the hardware graph */
-	hwgraph_info_add_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) baseio_inventory);
-	/* Make the information available to the user programs
-	 * thru hwgfs.
-	 */
-        hwgraph_info_export_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-char	*hub_rev[] = {
-	"0.0",
-	"1.0",
-	"2.0",
-	"2.1",
-	"2.2",
-	"2.3"
-};
-
-/*
- * Add detailed cpu inventory info to the hardware graph.
- */
-void
-klhwg_hub_invent_info(devfs_handle_t hubv,
-		      cnodeid_t cnode, 
-		      klhub_t *hub)
-{
-	invent_miscinfo_t *hub_invent;
-
-	hub_invent = (invent_miscinfo_t *) 
-	    klhwg_invent_alloc(cnode, INV_MISC, sizeof(invent_miscinfo_t));
-	if (!hub_invent)
-	    return;
-
-	if (KLCONFIG_INFO_ENABLED((klinfo_t *)hub))
-	    hub_invent->im_gen.ig_flag = INVENT_ENABLED;
-
-	hub_invent->im_type = INV_HUB;
-	hub_invent->im_rev = hub->hub_info.revision;
-	hub_invent->im_speed = hub->hub_speed;
-	hwgraph_info_add_LBL(hubv, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) hub_invent);
-        hwgraph_info_export_LBL(hubv, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-/* ARGSUSED */
-void
-klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode)
-{
-#if defined(CONFIG_IA64_SGI_SN1)
-	devfs_handle_t myhubv;
-	devfs_handle_t hub_mon;
-	devfs_handle_t synergy;
-	devfs_handle_t fsb0;
-	devfs_handle_t fsb1;
-	int rc;
-	extern struct file_operations hub_mon_fops;
-
-	GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB));
-
-	(void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
-	rc = device_master_set(myhubv, node_vertex);
-
-	/*
-	 * hub perf stats.
-	 */
-	rc = hwgraph_info_add_LBL(myhubv, INFO_LBL_HUB_INFO,
-                        (arbitrary_info_t)(&NODEPDA(cnode)->hubstats));
-
-	if (rc != GRAPH_SUCCESS) {
-		printk(KERN_WARNING  "klhwg_add_hub: Can't add hub info label 0x%p, code %d",
-			(void *)myhubv, rc);
-	}
-
-	klhwg_hub_invent_info(myhubv, cnode, hub);
-
-	hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &hub_mon_fops,
-	    (void *)(long)cnode);
-
-	init_hub_stats(cnode, NODEPDA(cnode));
-
-	/*
-	 * synergy perf
-	 */
-	(void) hwgraph_path_add(myhubv, EDGE_LBL_SYNERGY, &synergy);
-	(void) hwgraph_path_add(synergy, "0", &fsb0);
-	(void) hwgraph_path_add(synergy, "1", &fsb1);
-
-	fsb0 = hwgraph_register(fsb0, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 0));
-
-	fsb1 = hwgraph_register(fsb1, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 1));
-#endif /* CONFIG_IA64_SGI_SN1 */
-}
-
-void
-klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid)
-{
-	lboard_t *brd;
-	klxbow_t *xbow_p;
-	nasid_t hub_nasid;
-	cnodeid_t hub_cnode;
-	int widgetnum;
-	devfs_handle_t xbow_v, hubv;
-	/*REFERENCED*/
-	graph_error_t err;
-
-	if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW)) == NULL)
-			return;
-
-	if (KL_CONFIG_DUPLICATE_BOARD(brd))
-	    return;
-
-	GRPRINTF(("klhwg_add_xbow: adding cnode %d nasid %d xbow edges\n",
-			cnode, nasid));
-
-	if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
-	    == NULL)
-	    return;
-
-#ifdef	LATER
-	/*
-	 * We cannot support this function in devfs .. see below where 
-	 * we use hwgraph_path_add() to create this vertex with a known 
-	 * name.
-	 */
-	err = hwgraph_vertex_create(&xbow_v);
-	ASSERT(err == GRAPH_SUCCESS);
-
-	xswitch_vertex_init(xbow_v);
-#endif /* LATER */
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-		if (!XBOW_PORT_TYPE_HUB(xbow_p, widgetnum)) 
-		    continue;
-
-		hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum);
-		if (hub_nasid == INVALID_NASID) {
-			printk(KERN_WARNING  "hub widget %d, skipping xbow graph\n", widgetnum);
-			continue;
-		}
-
-		hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid);
-
-		if (is_specified(arg_maxnodes) && hub_cnode == INVALID_CNODEID) {
-			continue;
-		}
-			
-		hubv = cnodeid_to_vertex(hub_cnode);
-
-		err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v);
-                if (err != GRAPH_SUCCESS) {
-                        if (err == GRAPH_DUP)
-                                printk(KERN_WARNING  "klhwg_add_xbow: Check for "
-                                        "working routers and router links!");
-
-                        PRINT_PANIC("klhwg_add_xbow: Failed to add "
-                                "edge: vertex 0x%p to vertex 0x%p,"
-                                "error %d\n",
-                                (void *)hubv, (void *)xbow_v, err);
-                }
-		xswitch_vertex_init(xbow_v); 
-
-		NODEPDA(hub_cnode)->xbow_vhdl = xbow_v;
-
-		/*
-		 * XXX - This won't work is we ever hook up two hubs
-		 * by crosstown through a crossbow.
-		 */
-		if (hub_nasid != nasid) {
-			NODEPDA(hub_cnode)->xbow_peer = nasid;
-			NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer =
-				hub_nasid;
-		}
-
-		GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n",
-			hub_nasid, EDGE_LBL_XTALK, hubv));
-
-#ifdef	LATER
-		err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK);
-		if (err != GRAPH_SUCCESS) {
-			if (err == GRAPH_DUP)
-				printk(KERN_WARNING  "klhwg_add_xbow: Check for "
-					"working routers and router links!");
-
-			PRINT_PANIC("klhwg_add_xbow: Failed to add "
-				"edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p), "
-				"error %d\n",
-				hubv, hubv, xbow_v, xbow_v, err);
-		}
-#endif
-	}
-}
-
-
-/* ARGSUSED */
-void
-klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap)
-{
-	nasid_t nasid;
-	lboard_t *brd;
-	klhub_t *hub;
-	devfs_handle_t node_vertex = NULL;
-	char path_buffer[100];
-	int rv;
-	char *s;
-	int board_disabled = 0;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-	GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n",
-                cnode, nasid, brd));
-	ASSERT(brd);
-
-	do {
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(brd, path_buffer);
-
-		GRPRINTF(("klhwg_add_node: adding %s to vertex 0x%p\n",
-			path_buffer, hwgraph_root));
-		rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
-		if (rv != GRAPH_SUCCESS)
-			PRINT_PANIC("Node vertex creation failed.  "
-					  "Path == %s",
-				path_buffer);
-
-		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-		ASSERT(hub);
-		if(hub->hub_info.flags & KLINFO_ENABLE)
-			board_disabled = 0;
-		else
-			board_disabled = 1;
-		
-		if(!board_disabled) {
-			mark_nodevertex_as_node(node_vertex,
-					    cnode + board_disabled * numnodes);
-
-			s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer));
-			NODEPDA(cnode)->hwg_node_name =
-						kmalloc(strlen(s) + 1,
-						GFP_KERNEL);
-			ASSERT_ALWAYS(NODEPDA(cnode)->hwg_node_name != NULL);
-			strcpy(NODEPDA(cnode)->hwg_node_name, s);
-
-			hubinfo_set(node_vertex, NODEPDA(cnode)->pdinfo);
-
-			/* Set up node board's slot */
-			NODEPDA(cnode)->slotdesc = brd->brd_slot;
-
-			/* Set up the module we're in */
-			NODEPDA(cnode)->module_id = brd->brd_module;
-			NODEPDA(cnode)->module = module_lookup(brd->brd_module);
-		}
-
-		if(!board_disabled)
-		klhwg_add_hub(node_vertex, hub, cnode);
-		
-		brd = KLCF_NEXT(brd);
-		if (brd)
-			brd = find_lboard(brd, KLTYPE_SNIA);
-		else
-			break;
-	} while(brd);
-}
-
-
-/* ARGSUSED */
-void
-klhwg_add_all_routers(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-	devfs_handle_t node_vertex;
-	char path_buffer[100];
-	int rv;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_add_all_routers: adding router on cnode %d\n",
-			cnode));
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_ROUTER);
-
-		if (!brd)
-			/* No routers stored in this node's memory */
-			continue;
-
-		do {
-			ASSERT(brd);
-			GRPRINTF(("Router board struct is %p\n", brd));
-
-			/* Don't add duplicate boards. */
-			if (brd->brd_flags & DUPLICATE_BOARD)
-				continue;
-
-			GRPRINTF(("Router 0x%p module number is %d\n", brd, brd->brd_module));
-			/* Generate a hardware graph path for this board. */
-			board_to_path(brd, path_buffer);
-
-			GRPRINTF(("Router path is %s\n", path_buffer));
-
-			/* Add the router */
-			GRPRINTF(("klhwg_add_all_routers: adding %s to vertex 0x%p\n",
-				path_buffer, hwgraph_root));
-			rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
-			if (rv != GRAPH_SUCCESS)
-				PRINT_PANIC("Router vertex creation "
-						  "failed.  Path == %s",
-					path_buffer);
-
-			GRPRINTF(("klhwg_add_all_routers: get next board from 0x%p\n",
-					brd));
-		/* Find the rest of the routers stored on this node. */
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd),
-			 KLTYPE_ROUTER)) );
-
-		GRPRINTF(("klhwg_add_all_routers: Done.\n"));
-	}
-
-}
-
-/* ARGSUSED */
-void
-klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd,
-			 cnodeid_t cnode, nasid_t nasid)
-{
-	klrou_t *router;
-	char path_buffer[50];
-	char dest_path[50];
-	devfs_handle_t router_hndl;
-	devfs_handle_t dest_hndl;
-	int rc;
-	int port;
-	lboard_t *dest_brd;
-
-	GRPRINTF(("klhwg_connect_one_router: Connecting router on cnode %d\n",
-			cnode));
-
-	/* Don't add duplicate boards. */
-	if (brd->brd_flags & DUPLICATE_BOARD) {
-		GRPRINTF(("klhwg_connect_one_router: Duplicate router 0x%p on cnode %d\n",
-			brd, cnode));
-		return;
-	}
-
-	/* Generate a hardware graph path for this board. */
-	board_to_path(brd, path_buffer);
-
-	rc = hwgraph_traverse(hwgraph_root, path_buffer, &router_hndl);
-
-	if (rc != GRAPH_SUCCESS && is_specified(arg_maxnodes))
-			return;
-
-	if (rc != GRAPH_SUCCESS)
-		printk(KERN_WARNING  "Can't find router: %s", path_buffer);
-
-	/* We don't know what to do with multiple router components */
-	if (brd->brd_numcompts != 1) {
-		PRINT_PANIC("klhwg_connect_one_router: %d cmpts on router\n",
-			brd->brd_numcompts);
-		return;
-	}
-
-
-	/* Convert component 0 to klrou_t ptr */
-	router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd),
-					      brd->brd_compts[0]);
-
-	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
-		/* See if the port's active */
-		if (router->rou_port[port].port_nasid == INVALID_NASID) {
-			GRPRINTF(("klhwg_connect_one_router: port %d inactive.\n",
-				 port));
-			continue;
-		}
-		if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(router->rou_port[port].port_nasid) 
-		    == INVALID_CNODEID) {
-			continue;
-		}
-
-		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-				router->rou_port[port].port_nasid,
-				router->rou_port[port].port_offset);
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(dest_brd, dest_path);
-
-		rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
-
-		if (rc != GRAPH_SUCCESS) {
-			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
-				continue;
-			PRINT_PANIC("Can't find router: %s", dest_path);
-		}
-		GRPRINTF(("klhwg_connect_one_router: Link from %s/%d to %s\n",
-			  path_buffer, port, dest_path));
-
-		sprintf(dest_path, "%d", port);
-
-		rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path);
-
-		if (rc == GRAPH_DUP) {
-			GRPRINTF(("Skipping port %d. nasid %d %s/%s\n",
-				  port, router->rou_port[port].port_nasid,
-				  path_buffer, dest_path));
-			continue;
-		}
-
-		if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes))
-			PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
-				path_buffer, dest_path, (void *)dest_hndl, rc);
-		
-	}
-}
-
-
-void
-klhwg_connect_routers(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_connect_routers: Connecting routers on cnode %d\n",
-			cnode));
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_ROUTER);
-
-		if (!brd)
-			continue;
-
-		do {
-
-			nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-			klhwg_connect_one_router(hwgraph_root, brd,
-						 cnode, nasid);
-
-		/* Find the rest of the routers stored on this node. */
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
-	}
-}
-
-
-
-void
-klhwg_connect_hubs(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-	klhub_t *hub;
-	lboard_t *dest_brd;
-	devfs_handle_t hub_hndl;
-	devfs_handle_t dest_hndl;
-	char path_buffer[50];
-	char dest_path[50];
-	graph_error_t rc;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_connect_hubs: Connecting hubs on cnode %d\n",
-			cnode));
-
-		brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-		ASSERT(brd);
-
-		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-		ASSERT(hub);
-
-		/* See if the port's active */
-		if (hub->hub_port.port_nasid == INVALID_NASID) {
-			GRPRINTF(("klhwg_connect_hubs: port inactive.\n"));
-			continue;
-		}
-
-		if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(hub->hub_port.port_nasid) == INVALID_CNODEID)
-			continue;
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(brd, path_buffer);
-
-		GRPRINTF(("klhwg_connect_hubs: Hub path is %s.\n", path_buffer));
-		rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl);
-
-		if (rc != GRAPH_SUCCESS)
-			printk(KERN_WARNING  "Can't find hub: %s", path_buffer);
-
-		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-				hub->hub_port.port_nasid,
-				hub->hub_port.port_offset);
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(dest_brd, dest_path);
-
-		rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
-
-		if (rc != GRAPH_SUCCESS) {
-			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
-				continue;
-			PRINT_PANIC("Can't find board: %s", dest_path);
-		} else {
-		
-
-			GRPRINTF(("klhwg_connect_hubs: Link from %s to %s.\n",
-			  path_buffer, dest_path));
-
-			rc = hwgraph_edge_add(hub_hndl, dest_hndl, EDGE_LBL_INTERCONNECT);
-
-			if (rc != GRAPH_SUCCESS)
-				PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
-				path_buffer, dest_path, (void *)dest_hndl, rc);
-
-		}
-	}
-}
-
-/* Store the pci/vme disabled board information as extended administrative
- * hints which can later be used by the drivers using the device/driver
- * admin interface. 
- */
-void
-klhwg_device_disable_hints_add(void)
-{
-	cnodeid_t	cnode; 		/* node we are looking at */
-	nasid_t		nasid;		/* nasid of the node */
-	lboard_t	*board;		/* board we are looking at */
-	int		comp_index;	/* component index */
-	klinfo_t	*component;	/* component in the board we are
-					 * looking at 
-					 */
-	char		device_name[MAXDEVNAME];
-	
-#ifdef	LATER
-	device_admin_table_init();
-#endif
-	for(cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		/* Check out all the board info stored  on a node */
-		while(board) {
-			/* No need to look at duplicate boards or non-io 
-			 * boards
-			 */
-			if (KL_CONFIG_DUPLICATE_BOARD(board) ||
-			    KLCLASS(board->brd_type) != KLCLASS_IO) {
-				board = KLCF_NEXT(board);
-				continue;
-			}
-			/* Check out all the components of a board */
-			for (comp_index = 0; 
-			     comp_index < KLCF_NUM_COMPS(board);
-			     comp_index++) {
-				component = KLCF_COMP(board,comp_index);
-				/* If the component is enabled move on to
-				 * the next component
-				 */
-				if (KLCONFIG_INFO_ENABLED(component))
-					continue;
-				/* NOTE : Since the prom only supports
-				 * the disabling of pci devices the following
-				 * piece of code makes sense. 
-				 * Make sure that this assumption is valid
-				 */
-				/* This component is disabled. Store this
-				 * hint in the extended device admin table
-				 */
-				/* Get the canonical name of the pci device */
-				device_component_canonical_name_get(board,
-							    component,
-							    device_name);
-#ifdef	LATER
-				device_admin_table_update(device_name,
-							  ADMIN_LBL_DISABLED,
-							  "yes");
-#endif
-#ifdef DEBUG
-				printf("%s DISABLED\n",device_name);
-#endif				
-			}
-			/* go to the next board info stored on this 
-			 * node 
-			 */
-			board = KLCF_NEXT(board);
-		}
-	}
-}
-
-void
-klhwg_add_all_modules(devfs_handle_t hwgraph_root)
-{
-	cmoduleid_t	cm;
-	char		name[128];
-	devfs_handle_t	vhdl;
-	int		rc;
-	char		buffer[16];
-
-	/* Add devices under each module */
-
-	for (cm = 0; cm < nummodules; cm++) {
-		/* Use module as module vertex fastinfo */
-
-#ifdef __ia64
-		memset(buffer, 0, 16);
-		format_module_id(buffer, modules[cm]->id, MODULE_FORMAT_BRIEF);
-		sprintf(name, EDGE_LBL_MODULE "/%s", buffer);
-#else
-		sprintf(name, EDGE_LBL_MODULE "/%x", modules[cm]->id);
-#endif
-
-		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
-		ASSERT(rc == GRAPH_SUCCESS);
-		rc = rc;
-
-		hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) modules[cm]);
-
-		/* Add system controller */
-
-#ifdef __ia64
-		sprintf(name,
-			EDGE_LBL_MODULE "/%s/" EDGE_LBL_L1,
-			buffer);
-#else
-		sprintf(name,
-			EDGE_LBL_MODULE "/%x/" EDGE_LBL_L1,
-			modules[cm]->id);
-#endif
-
-		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
-		ASSERT_ALWAYS(rc == GRAPH_SUCCESS); 
-		rc = rc;
-
-		hwgraph_info_add_LBL(vhdl,
-				     INFO_LBL_ELSC,
-				     (arbitrary_info_t) (__psint_t) 1);
-
-#ifdef	LATER
-		sndrv_attach(vhdl);
-#else
-		/*
-		 * We need to call the drivers attach routine ..
-		 */
-		FIXME("klhwg_add_all_modules: Need code to call driver attach.\n");
-#endif
-	}
-}
-
-void
-klhwg_add_all_nodes(devfs_handle_t hwgraph_root)
-{
-	cnodeid_t	cnode;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		klhwg_add_node(hwgraph_root, cnode, NULL);
-	}
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		klhwg_add_xbow(cnode, cnodeid_to_nasid(cnode));
-	}
-
-	/*
-	 * As for router hardware inventory information, we set this
-	 * up in router.c. 
-	 */
-	
-	klhwg_add_all_routers(hwgraph_root);
-	klhwg_connect_routers(hwgraph_root);
-	klhwg_connect_hubs(hwgraph_root);
-
-	/* Assign guardian nodes to each of the
-	 * routers in the system.
-	 */
-
-#ifdef	LATER
-	router_guardians_set(hwgraph_root);
-#endif
-
-	/* Go through the entire system's klconfig
-	 * to figure out which pci components have been disabled
-	 */
-	klhwg_device_disable_hints_add();
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/klgraph_hack.c linux-2.4.22-pre3/arch/ia64/sn/io/klgraph_hack.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/klgraph_hack.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/klgraph_hack.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,341 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-/*
- * This is a temporary file that statically initializes the expected 
- * initial klgraph information that is normally provided by prom.
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/simulator.h>
-
-extern u64 klgraph_addr[];
-void * real_port;
-void * real_io_base;
-void * real_addr;
-
-char *BW0 = NULL;
-
-kl_config_hdr_t *linux_klcfg;
-
-#ifdef DEFINE_DUMP_RTNS
-/* forward declarations */
-static void dump_ii(void), dump_crossbow(void);
-static void clear_ii_error(void);
-#endif /* DEFINE_DUMP_RTNS */
-
-#define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
-#define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
-#define HUBREG                  ((char *)0xc0000a0001e00000)
-#define WIDGET0                 ((char *)0xc0000a0000000000)
-#define WIDGET4                 ((char *)0xc0000a0000000004)
-
-#define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
-#define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
-#define HUBREG                  ((char *)0xc0000a0001e00000)
-#define WIDGET0                 ((char *)0xc0000a0000000000)
-
-#define convert(a,b,c) temp = (u64 *)a; *temp = b; temp++; *temp = c
-
-void
-klgraph_hack_init(void)
-{
-
-	u64     *temp;
-
-#ifdef CONFIG_IA64_SGI_SN1
-	/*
-	 * We need to know whether we are booting from PROM or 
-	 * boot from disk.
-	 */
-	linux_klcfg = (kl_config_hdr_t *)0xe000000000030000;
-	if (linux_klcfg->ch_magic == 0xbeedbabe) {
-		return;
-	} else {
-		panic("klgraph_hack_init: Unable to locate KLCONFIG TABLE\n");
-	}
-
-	convert(0x0000000000030000, 0x00000000beedbabe, 0x0000004800000000);
-
-#else
-
-	if (IS_RUNNING_ON_SIMULATOR()) {
-		printk("Creating FAKE Klconfig Structure for Embeded Kernel\n");
-		klgraph_addr[0] = 0xe000003000030000;
-
-        /*
-         * klconfig entries initialization - mankato
-         */
-        convert(0xe000003000030000, 0x00000000beedbabe, 0x0000004800000000);
-        convert(0xe000003000030010, 0x0003007000000018, 0x800002000f820178);
-        convert(0xe000003000030020, 0x80000a000f024000, 0x800002000f800000);
-        convert(0xe000003000030030, 0x0300fafa00012580, 0x00000000040f0000);
-        convert(0xe000003000030040, 0x0000000000000000, 0x0003097000030070);
-        convert(0xe000003000030050, 0x00030970000303b0, 0x0003181000033f70);
-        convert(0xe000003000030060, 0x0003d51000037570, 0x0000000000038330);
-        convert(0xe000003000030070, 0x0203110100030140, 0x0001000000000101);
-        convert(0xe000003000030080, 0x0900000000000000, 0x000000004e465e67);
-        convert(0xe000003000030090, 0x0003097000000000, 0x00030b1000030a40);
-        convert(0xe0000030000300a0, 0x00030cb000030be0, 0x000315a0000314d0);
-        convert(0xe0000030000300b0, 0x0003174000031670, 0x0000000000000000);
-        convert(0xe000003000030100, 0x000000000000001a, 0x3350490000000000);
-        convert(0xe000003000030110, 0x0000000000000037, 0x0000000000000000);
-        convert(0xe000003000030140, 0x0002420100030210, 0x0001000000000101);
-        convert(0xe000003000030150, 0x0100000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030160, 0x00030d8000000000, 0x0000000000030e50);
-        convert(0xe0000030000301c0, 0x0000000000000000, 0x0000000000030070);
-        convert(0xe0000030000301d0, 0x0000000000000025, 0x424f490000000000);
-        convert(0xe0000030000301e0, 0x000000004b434952, 0x0000000000000000);
-        convert(0xe000003000030210, 0x00027101000302e0, 0x00010000000e4101);
-        convert(0xe000003000030220, 0x0200000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030230, 0x00030f2000000000, 0x0000000000030ff0);
-        convert(0xe000003000030290, 0x0000000000000000, 0x0000000000030140);
-        convert(0xe0000030000302a0, 0x0000000000000026, 0x7262490000000000);
-        convert(0xe0000030000302b0, 0x00000000006b6369, 0x0000000000000000);
-        convert(0xe0000030000302e0, 0x0002710100000000, 0x00010000000f3101);
-        convert(0xe0000030000302f0, 0x0500000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030300, 0x000310c000000000, 0x0003126000031190);
-        convert(0xe000003000030310, 0x0003140000031330, 0x0000000000000000);
-        convert(0xe000003000030360, 0x0000000000000000, 0x0000000000030140);
-        convert(0xe000003000030370, 0x0000000000000029, 0x7262490000000000);
-        convert(0xe000003000030380, 0x00000000006b6369, 0x0000000000000000);
-        convert(0xe000003000030970, 0x0000000002010102, 0x0000000000000000);
-        convert(0xe000003000030980, 0x000000004e465e67, 0xffffffff00000000);
-        /* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */
-        convert(0xe0000030000309a0, 0x0000000000037570, 0xffffffff00000000);
-        convert(0xe0000030000309b0, 0x0000000000030070, 0x0000000000000000);
-        convert(0xe0000030000309c0, 0x000000000003f420, 0x0000000000000000);
-        convert(0xe000003000030a40, 0x0000000002010125, 0x0000000000000000);
-        convert(0xe000003000030a50, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000030a70, 0x0000000000037b78, 0x0000000000000000);
-        convert(0xe000003000030b10, 0x0000000002010125, 0x0000000000000000);
-        convert(0xe000003000030b20, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000030b40, 0x0000000000037d30, 0x0000000000000001);
-        convert(0xe000003000030be0, 0x00000000ff010203, 0x0000000000000000);
-        convert(0xe000003000030bf0, 0xffffffffffffffff, 0xffffffff000000ff);
-        convert(0xe000003000030c10, 0x0000000000037ee8, 0x0100010000000200);
-        convert(0xe000003000030cb0, 0x00000000ff310111, 0x0000000000000000);
-        convert(0xe000003000030cc0, 0xffffffffffffffff, 0x0000000000000000);
-        convert(0xe000003000030d80, 0x0000000002010104, 0x0000000000000000);
-        convert(0xe000003000030d90, 0xffffffffffffffff, 0x00000000000000ff);
-        convert(0xe000003000030db0, 0x0000000000037f18, 0x0000000000000000);
-        convert(0xe000003000030dc0, 0x0000000000000000, 0x0003007000060000);
-        convert(0xe000003000030de0, 0x0000000000000000, 0x0003021000050000);
-        convert(0xe000003000030df0, 0x000302e000050000, 0x0000000000000000);
-        convert(0xe000003000030e30, 0x0000000000000000, 0x000000000000000a);
-        convert(0xe000003000030e50, 0x00000000ff00011a, 0x0000000000000000);
-        convert(0xe000003000030e60, 0xffffffffffffffff, 0x0000000000000000);
-        convert(0xe000003000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e);
-        convert(0xe000003000030e90, 0x000000000000bc6e, 0x0000000000000000);
-        convert(0xe000003000030f20, 0x0000000002010205, 0x00000000d0020000);
-        convert(0xe000003000030f30, 0xffffffffffffffff, 0x0000000e0000000e);
-        convert(0xe000003000030f40, 0x000000000000000e, 0x0000000000000000);
-        convert(0xe000003000030f50, 0x0000000000038010, 0x00000000000007ff);
-        convert(0xe000003000030f70, 0x0000000000000000, 0x0000000022001077);
-        convert(0xe000003000030fa0, 0x0000000000000000, 0x000000000003f4a8);
-        convert(0xe000003000030ff0, 0x0000000000310120, 0x0000000000000000);
-        convert(0xe000003000031000, 0xffffffffffffffff, 0xffffffff00000002);
-        convert(0xe000003000031010, 0x000000000000000e, 0x0000000000000000);
-        convert(0xe000003000031020, 0x0000000000038088, 0x0000000000000000);
-        convert(0xe0000030000310c0, 0x0000000002010205, 0x00000000d0020000);
-        convert(0xe0000030000310d0, 0xffffffffffffffff, 0x0000000f0000000f);
-        convert(0xe0000030000310e0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000310f0, 0x00000000000380b8, 0x00000000000007ff);
-        convert(0xe000003000031120, 0x0000000022001077, 0x00000000000310a9);
-        convert(0xe000003000031130, 0x00000000580211c1, 0x000000008009104c);
-        convert(0xe000003000031140, 0x0000000000000000, 0x000000000003f4c0);
-        convert(0xe000003000031190, 0x0000000000310120, 0x0000000000000000);
-        convert(0xe0000030000311a0, 0xffffffffffffffff, 0xffffffff00000003);
-        convert(0xe0000030000311b0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000311c0, 0x0000000000038130, 0x0000000000000000);
-        convert(0xe000003000031260, 0x0000000000110106, 0x0000000000000000);
-        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
-        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
-        convert(0xe000003000031280, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000312a0, 0x00000000ff110013, 0x0000000000000000);
-        convert(0xe0000030000312b0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe0000030000312c0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000312e0, 0x0000000000110012, 0x0000000000000000);
-        convert(0xe0000030000312f0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000031300, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031310, 0x0000000000038160, 0x0000000000000000);
-        convert(0xe000003000031330, 0x00000000ff310122, 0x0000000000000000);
-        convert(0xe000003000031340, 0xffffffffffffffff, 0xffffffff00000005);
-        convert(0xe000003000031350, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031360, 0x0000000000038190, 0x0000000000000000);
-        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
-        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
-        convert(0xe000003000031410, 0xffffffffffffffff, 0xffffffff00000006);
-        convert(0xe000003000031420, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031430, 0x00000000000381c0, 0x0000000000000000);
-        convert(0xe0000030000314d0, 0x00000000ff010201, 0x0000000000000000);
-        convert(0xe0000030000314e0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000031500, 0x00000000000381f0, 0x000030430000ffff);
-        convert(0xe000003000031510, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe0000030000315a0, 0x00000020ff000201, 0x0000000000000000);
-        convert(0xe0000030000315b0, 0xffffffffffffffff, 0xffffffff00000001);
-        convert(0xe0000030000315d0, 0x0000000000038240, 0x00003f3f0000ffff);
-        convert(0xe0000030000315e0, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe000003000031670, 0x00000000ff010201, 0x0000000000000000);
-        convert(0xe000003000031680, 0xffffffffffffffff, 0x0000000100000002);
-        convert(0xe0000030000316a0, 0x0000000000038290, 0x000030430000ffff);
-        convert(0xe0000030000316b0, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe000003000031740, 0x00000020ff000201, 0x0000000000000000);
-        convert(0xe000003000031750, 0xffffffffffffffff, 0x0000000500000003);
-        convert(0xe000003000031770, 0x00000000000382e0, 0x00003f3f0000ffff);
-        convert(0xe000003000031780, 0x000000000000ffff, 0x0000000000000000);
-}
-
-#endif
-
-}
-
-
-
-
-	
-#ifdef DEFINE_DUMP_RTNS
-/* 
- * these were useful for printing out registers etc
- * during bringup  
- */
-
-static void
-xdump(long long *addr, int count)
-{
-	int ii;
-	volatile long long *xx = addr;
-
-	for ( ii = 0; ii < count; ii++, xx++ ) {
-		printk("0x%p : 0x%p\n", (void *)xx, (void *)*xx);
-	}
-}
-
-static void
-xdump32(unsigned int *addr, int count)
-{
-	int ii;
-	volatile unsigned int *xx = addr;
-
-	for ( ii = 0; ii < count; ii++, xx++ ) {
-		printk("0x%p : 0x%0x\n", (void *)xx, (int)*xx);
-	}
-}
-
-static void
-clear_ii_error(void)
-{
-	volatile long long *tmp;
-
-	printk("... WSTAT ");
-	xdump((long long *)0xc0000a0001c00008, 1);
-	printk("... WCTRL ");
-	xdump((long long *)0xc0000a0001c00020, 1);
-	printk("... WLCSR ");
-	xdump((long long *)0xc0000a0001c00128, 1);
-	printk("... IIDSR ");
-	xdump((long long *)0xc0000a0001c00138, 1);
-        printk("... IOPRBs ");
-	xdump((long long *)0xc0000a0001c00198, 9);
-	printk("... IXSS ");
-	xdump((long long *)0xc0000a0001c00210, 1);
-	printk("... IBLS0 ");
-	xdump((long long *)0xc0000a0001c10000, 1);
-	printk("... IBLS1 ");
-	xdump((long long *)0xc0000a0001c20000, 1);
-
-        /* Write IOERR clear to clear the CRAZY bit in the status */
-        tmp = (long long *)0xc0000a0001c001f8; *tmp = (long long)0xffffffff;
-
-	/* dump out local block error registers */
-	printk("... ");
-	xdump((long long *)0xc0000a0001e04040, 1);	/* LB_ERROR_BITS */
-	printk("... ");
-	xdump((long long *)0xc0000a0001e04050, 1);	/* LB_ERROR_HDR1 */
-	printk("... ");
-	xdump((long long *)0xc0000a0001e04058, 1);	/* LB_ERROR_HDR2 */
-	/* and clear the LB_ERROR_BITS */
-	tmp = (long long *)0xc0000a0001e04040; *tmp = 0x0;
-	printk("clr: ");
-	xdump((long long *)0xc0000a0001e04040, 1);	/* LB_ERROR_BITS */
-	tmp = (long long *)0xc0000a0001e04050; *tmp = 0x0;
-	tmp = (long long *)0xc0000a0001e04058; *tmp = 0x0;
-}
-
-
-static void
-dump_ii(void)
-{
-	printk("===== Dump the II regs =====\n");
-	xdump((long long *)0xc0000a0001c00000, 2);
-	xdump((long long *)0xc0000a0001c00020, 1);
-	xdump((long long *)0xc0000a0001c00100, 37);
-	xdump((long long *)0xc0000a0001c00300, 98);
-	xdump((long long *)0xc0000a0001c10000, 6);
-	xdump((long long *)0xc0000a0001c20000, 6);
-	xdump((long long *)0xc0000a0001c30000, 2);
-
-	xdump((long long *)0xc0000a0000000000, 1);
-	xdump((long long *)0xc0000a0001000000, 1);
-	xdump((long long *)0xc0000a0002000000, 1);
-	xdump((long long *)0xc0000a0003000000, 1);
-	xdump((long long *)0xc0000a0004000000, 1);
-	xdump((long long *)0xc0000a0005000000, 1);
-	xdump((long long *)0xc0000a0006000000, 1);
-	xdump((long long *)0xc0000a0007000000, 1);
-	xdump((long long *)0xc0000a0008000000, 1);
-	xdump((long long *)0xc0000a0009000000, 1);
-	xdump((long long *)0xc0000a000a000000, 1);
-	xdump((long long *)0xc0000a000b000000, 1);
-	xdump((long long *)0xc0000a000c000000, 1);
-	xdump((long long *)0xc0000a000d000000, 1);
-	xdump((long long *)0xc0000a000e000000, 1);
-	xdump((long long *)0xc0000a000f000000, 1);
-}
-
-static void
-dump_crossbow(void)
-{
-	printk("===== Dump the Crossbow regs =====\n");
-	clear_ii_error();
-	xdump32((unsigned int *)0xc0000a0000000004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc0000a0000000000, 1);
-	printk("and again..\n");
-	xdump32((unsigned int *)0xc0000a0000000000, 1);
-	xdump32((unsigned int *)0xc0000a0000000000, 1);
-
-
-	clear_ii_error();
-
-	xdump32((unsigned int *)0xc000020000000004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc000020000000000, 1);
-	clear_ii_error();
-
-	xdump32((unsigned int *)0xc0000a0000800004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc0000a0000800000, 1);
-	clear_ii_error();
-
-	xdump32((unsigned int *)0xc000020000800004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc000020000800000, 1);
-	clear_ii_error();
-
-
-}
-#endif /* DEFINE_DUMP_RTNS */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/l1.c linux-2.4.22-pre3/arch/ia64/sn/io/l1.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/l1.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/l1.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,3143 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/* In general, this file is organized in a hierarchy from lower-level
- * to higher-level layers, as follows:
- *
- *	UART routines
- *	Bedrock/L1 "PPP-like" protocol implementation
- *	System controller "message" interface (allows multiplexing
- *		of various kinds of requests and responses with
- *		console I/O)
- *	Console interface:
- *	  "l1_cons", the glue that allows the L1 to act
- *		as the system console for the stdio libraries
- *
- * Routines making use of the system controller "message"-style interface
- * can be found in l1_command.c.
- */
-
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/uart16550.h>
-#include <asm/sn/simulator.h>
-
-#if defined(CONFIG_IA64_SGI_SN2)
-#define USE_SAL_CONSOLE_IO	1	/* DON'T un-def this for the simulator... */
-#endif
-
-/* Make all console writes atomic */
-#define SYNC_CONSOLE_WRITE	1
-
-
-/*********************************************************************
- * Hardware-level (UART) driver routines.
- */
-
-/* macros for reading/writing registers */
-
-#define LD(x)			(*(volatile uint64_t *)(x))
-#define SD(x, v)        	(LD(x) = (uint64_t) (v))
-
-/* location of uart receive/xmit data register */
-#if defined(CONFIG_IA64_SGI_SN1)
-#define L1_UART_BASE(n)		((ulong)REMOTE_HSPEC_ADDR((n), 0x00000080))
-#define LOCK_HUB		REMOTE_HUB_ADDR
-#elif defined(CONFIG_IA64_SGI_SN2)
-#define L1_UART_BASE(n)		((ulong)REMOTE_HUB((n), SH_JUNK_BUS_UART0))
-#define LOCK_HUB		REMOTE_HUB
-typedef u64 rtc_time_t;
-#endif
-
-
-#define ADDR_L1_REG(n, r)	( L1_UART_BASE(n) | ( (r) << 3 ) )
-#define READ_L1_UART_REG(n, r)	( LD(ADDR_L1_REG((n), (r))) )
-#define WRITE_L1_UART_REG(n, r, v) ( SD(ADDR_L1_REG((n), (r)), (v)) )
-
-/* upper layer interface calling methods */
-#define SERIAL_INTERRUPT_MODE	0
-#define SERIAL_POLLED_MODE	1
-
-
-/* UART-related #defines */
-
-#define UART_BAUD_RATE		57600
-#define UART_FIFO_DEPTH		16
-#define UART_DELAY_SPAN		10
-#define UART_PUTC_TIMEOUT	50000
-#define UART_INIT_TIMEOUT	100000
-
-/* error codes */
-#define UART_SUCCESS		  0
-#define UART_TIMEOUT		(-1)
-#define UART_LINK		(-2)
-#define UART_NO_CHAR		(-3)
-#define UART_VECTOR		(-4)
-
-#define UART_DELAY(x)		udelay(x)
-
-/* Some debug counters */
-#define L1C_INTERRUPTS		0
-#define L1C_OUR_R_INTERRUPTS	1
-#define L1C_OUR_X_INTERRUPTS	2
-#define L1C_SEND_CALLUPS	3
-#define L1C_RECEIVE_CALLUPS	4
-#define L1C_SET_BAUD		5
-#define L1C_ALREADY_LOCKED	L1C_SET_BAUD
-#define L1C_R_IRQ		6
-#define L1C_R_IRQ_RET		7
-#define L1C_LOCK_TIMEOUTS	8
-#define L1C_LOCK_COUNTER	9
-#define L1C_UNLOCK_COUNTER	10
-#define L1C_REC_STALLS		11
-#define L1C_CONNECT_CALLS	12
-#define L1C_SIZE		L1C_CONNECT_CALLS	/* Set to the last one */
-
-uint64_t L1_collectibles[L1C_SIZE + 1];
-
-
-/*
- *	Some macros for handling Endian-ness
- */
-
-#define COPY_INT_TO_BUFFER(_b, _i, _n)		\
-	{					\
-		_b[_i++] = (_n >> 24) & 0xff;	\
-		_b[_i++] = (_n >> 16) & 0xff;	\
-		_b[_i++] = (_n >>  8) & 0xff;	\
-		_b[_i++] =  _n        & 0xff;	\
-	}
-
-#define COPY_BUFFER_TO_INT(_b, _i, _n)		\
-	{					\
-		_n  = (_b[_i++] << 24) & 0xff;	\
-		_n |= (_b[_i++] << 16) & 0xff;	\
-		_n |= (_b[_i++] <<  8) & 0xff;	\
-		_n |=  _b[_i++]        & 0xff;	\
-	}
-
-#define COPY_BUFFER_TO_BUFFER(_b, _i, _bn)	\
-	{					\
-	    char *_xyz = (char *)_bn;		\
-	    _xyz[3] = _b[_i++];			\
-	    _xyz[2] = _b[_i++];			\
-	    _xyz[1] = _b[_i++];			\
-	    _xyz[0] = _b[_i++];			\
-	}
-
-void snia_kmem_free(void *where, int size);
-
-#define ALREADY_LOCKED		1
-#define NOT_LOCKED		0
-static int early_l1_serial_out(nasid_t, char *, int, int /* defines above*/ );
-
-#define BCOPY(x,y,z)	memcpy(y,x,z)
-
-uint8_t L1_interrupts_connected;		/* Non-zero when we are in interrupt mode */
-
-
-/*
- * Console locking defines and functions.
- *
- */
-
-uint8_t L1_cons_is_inited = 0;			/* non-zero when console is init'd */
-nasid_t Master_console_nasid = (nasid_t)-1;
-extern nasid_t console_nasid;
-
-#if defined(CONFIG_IA64_SGI_SN1)
-u64 ia64_sn_get_console_nasid(void);
-#endif
-
-inline nasid_t
-get_master_nasid(void)
-{
-#if defined(CONFIG_IA64_SGI_SN1)
-	nasid_t nasid = Master_console_nasid;
-
-	if ( nasid == (nasid_t)-1 ) {
-		nasid = (nasid_t)ia64_sn_get_console_nasid();
-		if ( (nasid < 0) || (nasid >= MAX_NASIDS) ) {
-			/* Out of bounds, use local */
-			console_nasid = nasid = get_nasid();
-		}
-		else {
-			/* Got a valid nasid, set the console_nasid */
-			char xx[100];
-/* zzzzzz - force nasid to 0 for now */
-			sprintf(xx, "Master console is set to nasid %d (%d)\n", 0, (int)nasid);
-nasid = 0;
-/* end zzzzzz */
-			xx[99] = (char)0;
-			early_l1_serial_out(nasid, xx, strlen(xx), NOT_LOCKED);
-			Master_console_nasid = console_nasid = nasid;
-		}
-	}
-	return(nasid);
-#else
-	return((nasid_t)0);
-#endif	/* CONFIG_IA64_SGI_SN1 */
-}
-
-
-#if defined(CONFIG_IA64_SGI_SN1)
-
-#define HUB_LOCK		16
-
-#define PRIMARY_LOCK_TIMEOUT    10000000
-#define HUB_LOCK_REG(n)         LOCK_HUB(n, MD_PERF_CNT0)
-
-#define SET_BITS(reg, bits)     SD(reg, LD(reg) |  (bits))
-#define CLR_BITS(reg, bits)     SD(reg, LD(reg) & ~(bits))
-#define TST_BITS(reg, bits)     ((LD(reg) & (bits)) != 0)
-
-#define HUB_TEST_AND_SET(n)	LD(LOCK_HUB(n,LB_SCRATCH_REG3_RZ))
-#define HUB_CLEAR(n)		SD(LOCK_HUB(n,LB_SCRATCH_REG3),0)
-
-#define RTC_TIME_MAX		((rtc_time_t) ~0ULL)
-
-/*
- * primary_lock
- *
- *   Allows CPU's 0-3  to mutually exclude the hub from one another by
- *   obtaining a blocking lock.  Does nothing if only one CPU is active.
- *
- *   This lock should be held just long enough to set or clear a global
- *   lock bit.  After a relatively short timeout period, this routine
- *   figures something is wrong, and steals the lock. It does not set
- *   any other CPU to "dead".
- */
-inline void
-primary_lock(nasid_t nasid)
-{
-	rtc_time_t          expire;
-
-	expire = rtc_time() + PRIMARY_LOCK_TIMEOUT;
-
-	while (HUB_TEST_AND_SET(nasid)) {
-		if (rtc_time() > expire) {
-			HUB_CLEAR(nasid);
-		}
-	}
-}
-
-/*
- * primary_unlock (internal)
- *
- *   Counterpart to primary_lock
- */
-
-inline void
-primary_unlock(nasid_t nasid)
-{
-	HUB_CLEAR(nasid);
-}
-
-/*
- * hub_unlock
- *
- *   Counterpart to hub_lock_timeout and hub_lock
- */
-
-inline void
-hub_unlock(nasid_t nasid, int level)
-{
-	uint64_t mask = 1ULL << level;
-
-	primary_lock(nasid);
-	CLR_BITS(HUB_LOCK_REG(nasid), mask);
-	primary_unlock(nasid);
-}
-
-/*
- * hub_lock_timeout
- *
- *   Uses primary_lock to implement multiple lock levels.
- *
- *   There are 20 lock levels from 0 to 19 (limited by the number of bits
- *   in HUB_LOCK_REG).  To prevent deadlock, multiple locks should be
- *   obtained in order of increasingly higher level, and released in the
- *   reverse order.
- *
- *   A timeout value of 0 may be used for no timeout.
- *
- *   Returns 0 if successful, -1 if lock times out.
- */
-
-inline int
-hub_lock_timeout(nasid_t nasid, int level, rtc_time_t timeout)
-{
-	uint64_t mask = 1ULL << level;
-	rtc_time_t expire = (timeout ?  rtc_time() + timeout : RTC_TIME_MAX);
-	int done    = 0;
-
-	while (! done) {
-		while (TST_BITS(HUB_LOCK_REG(nasid), mask)) {
-			if (rtc_time() > expire)
-				return -1;
-		}
-
-		primary_lock(nasid);
-
-		if (! TST_BITS(HUB_LOCK_REG(nasid), mask)) {
-			SET_BITS(HUB_LOCK_REG(nasid), mask);
-			done = 1;
-		}
-		primary_unlock(nasid);
-	}
-	return 0;
-}
-
-
-#define LOCK_TIMEOUT	(0x1500000 * 1) /* 0x1500000 is ~30 sec */
-
-void
-lock_console(nasid_t nasid)
-{
-	int ret;
-
-	/* If we already have it locked, just return */
-	L1_collectibles[L1C_LOCK_COUNTER]++;
-
-	ret = hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
-	if ( ret != 0 ) {
-		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
-		/* timeout */
-		hub_unlock(nasid, HUB_LOCK);
-		/* If the 2nd lock fails, just pile ahead.... */
-		hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
-		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
-	}
-}
-
-inline void
-unlock_console(nasid_t nasid)
-{
-	L1_collectibles[L1C_UNLOCK_COUNTER]++;
-	hub_unlock(nasid, HUB_LOCK);
-}
-
-#else /* SN2 */
-inline void lock_console(nasid_t n)	{}
-inline void unlock_console(nasid_t n)	{}
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-int 
-get_L1_baud(void)
-{
-    return UART_BAUD_RATE;
-}
-
-
-/* uart driver functions */
-
-static inline void
-uart_delay( rtc_time_t delay_span )
-{
-    UART_DELAY( delay_span );
-}
-
-#define UART_PUTC_READY(n)      (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE)
-
-static int
-uart_putc( l1sc_t *sc ) 
-{
-    WRITE_L1_UART_REG( sc->nasid, REG_DAT, sc->send[sc->sent] );
-    return UART_SUCCESS;
-}
-
-
-static int
-uart_getc( l1sc_t *sc )
-{
-    u_char lsr_reg = 0;
-    nasid_t nasid = sc->nasid;
-
-    if( (lsr_reg = READ_L1_UART_REG( nasid, REG_LSR )) & 
-	(LSR_RCA | LSR_PARERR | LSR_FRMERR) ) 
-    {
-	if( lsr_reg & LSR_RCA ) 
-	    return( (u_char)READ_L1_UART_REG( nasid, REG_DAT ) );
-	else if( lsr_reg & (LSR_PARERR | LSR_FRMERR) ) {
-	    return UART_LINK;
-	}
-    }
-
-    return UART_NO_CHAR;
-}
-
-
-#define PROM_SER_CLK_SPEED	12000000
-#define PROM_SER_DIVISOR(x)	(PROM_SER_CLK_SPEED / ((x) * 16))
-
-static void
-uart_init( l1sc_t *sc, int baud )
-{
-    rtc_time_t expire;
-    int clkdiv;
-    nasid_t nasid;
-
-    clkdiv = PROM_SER_DIVISOR(baud);
-    expire = rtc_time() + UART_INIT_TIMEOUT;
-    nasid = sc->nasid;
-    
-    /* make sure the transmit FIFO is empty */
-    while( !(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XSRE) ) {
-	uart_delay( UART_DELAY_SPAN );
-	if( rtc_time() > expire ) {
-	    break;
-	}
-    }
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* Setup for the proper baud rate */
-    WRITE_L1_UART_REG( nasid, REG_LCR, LCR_DLAB );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_DLH, (clkdiv >> 8) & 0xff );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_DLL, clkdiv & 0xff );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* set operating parameters and set DLAB to 0 */
-
-    /* 8bit, one stop, clear request to send, auto flow control */
-    WRITE_L1_UART_REG( nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_MCR, MCR_RTS | MCR_AFE );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* disable interrupts */
-    WRITE_L1_UART_REG( nasid, REG_ICR, 0x0 );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* enable FIFO mode and reset both FIFOs, trigger on 1 */
-    WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO | RxLVL0);
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-
-/* This requires the console lock */
-
-#if	defined(CONFIG_IA64_SGI_SN1)
-
-static void
-uart_intr_enable( l1sc_t *sc, u_char mask )
-{
-    u_char lcr_reg, icr_reg;
-    nasid_t nasid = sc->nasid;
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* make sure that the DLAB bit in the LCR register is 0
-     */
-    lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
-    lcr_reg &= ~(LCR_DLAB);
-    WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg );
-
-    /* enable indicated interrupts
-     */
-    icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
-    icr_reg |= mask;
-    WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-
-/* This requires the console lock */
-static void
-uart_intr_disable( l1sc_t *sc, u_char mask )
-{
-    u_char lcr_reg, icr_reg;
-    nasid_t nasid = sc->nasid;
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* make sure that the DLAB bit in the LCR register is 0
-     */
-    lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
-    lcr_reg &= ~(LCR_DLAB);
-    WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg );
-
-    /* enable indicated interrupts
-     */
-    icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
-    icr_reg &= mask;
-    WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-#define uart_enable_xmit_intr(sc) \
-	uart_intr_enable((sc), ICR_TIEN)
-
-#define uart_disable_xmit_intr(sc) \
-        uart_intr_disable((sc), ~(ICR_TIEN))
-
-#define uart_enable_recv_intr(sc) \
-        uart_intr_enable((sc), ICR_RIEN)
-
-#define uart_disable_recv_intr(sc) \
-        uart_intr_disable((sc), ~(ICR_RIEN))
-
-
-/*********************************************************************
- * Routines for accessing a remote (router) UART
- */
-
-#define READ_RTR_L1_UART_REG(p, n, r, v)		\
-    {							\
-	if( vector_read_node( (p), (n), 0,		\
-			      RR_JBUS1(r), (v) ) ) {	\
-	    return UART_VECTOR;				\
-	}						\
-    }
-
-#define WRITE_RTR_L1_UART_REG(p, n, r, v)		\
-    {							\
-	if( vector_write_node( (p), (n), 0,		\
-			       RR_JBUS1(r), (v) ) ) {	\
-	    return UART_VECTOR;				\
-	}						\
-    }
-
-#define RTR_UART_PUTC_TIMEOUT	UART_PUTC_TIMEOUT*10
-#define RTR_UART_DELAY_SPAN	UART_DELAY_SPAN
-#define RTR_UART_INIT_TIMEOUT	UART_INIT_TIMEOUT*10
-
-static int
-rtr_uart_putc( l1sc_t *sc )
-{
-    uint64_t regval, c;
-    nasid_t nasid = sc->nasid;
-    net_vec_t path = sc->uart;
-    rtc_time_t expire = rtc_time() + RTR_UART_PUTC_TIMEOUT;
-
-    c = (sc->send[sc->sent] & 0xffULL);
-    
-    while( 1 ) 
-    {
-        /* Check for "tx hold reg empty" bit. */
-	READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-	if( regval & LSR_XHRE )
-	{
-	    WRITE_RTR_L1_UART_REG( path, nasid, REG_DAT, c );
-	    return UART_SUCCESS;
-	}
-
-	if( rtc_time() >= expire ) 
-	{
-	    return UART_TIMEOUT;
-	}
-	uart_delay( RTR_UART_DELAY_SPAN );
-    }
-}
-
-
-static int
-rtr_uart_getc( l1sc_t *sc )
-{
-    uint64_t regval;
-    nasid_t nasid = sc->nasid;
-    net_vec_t path = sc->uart;
-
-    READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-    if( regval & (LSR_RCA | LSR_PARERR | LSR_FRMERR) )
-    {
-	if( regval & LSR_RCA )
-	{
-	    READ_RTR_L1_UART_REG( path, nasid, REG_DAT, &regval );
-	    return( (int)regval );
-	}
-	else
-	{
-	    return UART_LINK;
-	}
-    }
-
-    return UART_NO_CHAR;
-}
-
-
-static int
-rtr_uart_init( l1sc_t *sc, int baud )
-{
-    rtc_time_t expire;
-    int clkdiv;
-    nasid_t nasid;
-    net_vec_t path;
-    uint64_t regval;
-
-    clkdiv = PROM_SER_DIVISOR(baud);
-    expire = rtc_time() + RTR_UART_INIT_TIMEOUT;
-    nasid = sc->nasid;
-    path = sc->uart;
-
-    /* make sure the transmit FIFO is empty */
-    while(1) {
-	READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-	if( regval & LSR_XSRE ) {
-	    break;
-	}
-	if( rtc_time() > expire ) {
-	    break;
-	}
-	uart_delay( RTR_UART_DELAY_SPAN );
-    }
-
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_DLAB  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_DLH, (clkdiv >> 8) & 0xff  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_DLL, clkdiv & 0xff  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* set operating parameters and set DLAB to 0 */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_BITS8 | LCR_STOP1  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_MCR, MCR_RTS | MCR_AFE  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* disable interrupts */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_ICR, 0x0  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* enable FIFO mode and reset both FIFOs */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR, FCR_FIFOEN  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR,
-	FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO );
-
-    return 0;
-}
-
-/*********************************************************************
- * locking macros 
- */
-
-#define L1SC_SEND_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->send_lock),p); }
-#define L1SC_SEND_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->send_lock), p); }
-#define L1SC_RECV_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->recv_lock), p); } 
-#define L1SC_RECV_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->recv_lock), p); }
-
-
-/*********************************************************************
- * subchannel manipulation 
- *
- * The SUBCH_[UN]LOCK macros are used to arbitrate subchannel
- * allocation.  SUBCH_DATA_[UN]LOCK control access to data structures
- * associated with particular subchannels (e.g., receive queues).
- *
- */
-#define SUBCH_LOCK(sc, p)		spin_lock_irqsave( &((sc)->subch_lock), p )
-#define SUBCH_UNLOCK(sc, p)		spin_unlock_irqrestore( &((sc)->subch_lock), p )
-#define SUBCH_DATA_LOCK(sbch, p) 	spin_lock_irqsave( &((sbch)->data_lock), p )
-#define SUBCH_DATA_UNLOCK(sbch, p)	spin_unlock_irqrestore( &((sbch)->data_lock), p )
-
-
-/*
- * set a function to be called for subchannel ch in the event of
- * a transmission low-water interrupt from the uart
- */
-void
-subch_set_tx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-    unsigned long pl = 0;
-
-    L1SC_SEND_LOCK( sc, pl );
-#if	!defined(SYNC_CONSOLE_WRITE)
-    if ( func && !sc->send_in_use )
-	uart_enable_xmit_intr( sc );
-#endif
-    sc->subch[ch].tx_notify = func;
-    L1SC_SEND_UNLOCK(sc, pl );
-}
-
-/*
- * set a function to be called for subchannel ch when data is received
- */
-void
-subch_set_rx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    SUBCH_DATA_LOCK( subch, pl );
-    sc->subch[ch].rx_notify = func;
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-/*********************************************************************
- * Queue manipulation macros
- *
- *
- */
-#define NEXT(p)         (((p) + 1) & (BRL1_QSIZE-1)) /* assume power of 2 */
-
-#define cq_init(q)      bzero((q), sizeof (*(q)))
-#define cq_empty(q)     ((q)->ipos == (q)->opos)
-#define cq_full(q)      (NEXT((q)->ipos) == (q)->opos)
-#define cq_used(q)      ((q)->opos <= (q)->ipos ?                       \
-                         (q)->ipos - (q)->opos :                        \
-                         BRL1_QSIZE + (q)->ipos - (q)->opos)
-#define cq_room(q)      ((q)->opos <= (q)->ipos ?                       \
-                         BRL1_QSIZE - 1 + (q)->opos - (q)->ipos :       \
-                         (q)->opos - (q)->ipos - 1)
-#define cq_add(q, c)    ((q)->buf[(q)->ipos] = (u_char) (c),            \
-                         (q)->ipos = NEXT((q)->ipos))
-#define cq_rem(q, c)    ((c) = (q)->buf[(q)->opos],                     \
-                         (q)->opos = NEXT((q)->opos))
-#define cq_discard(q)	((q)->opos = NEXT((q)->opos))
-
-#define cq_tent_full(q)	(NEXT((q)->tent_next) == (q)->opos)
-#define cq_tent_len(q)	((q)->ipos <= (q)->tent_next ?			\
-			 (q)->tent_next - (q)->ipos :			\
-			 BRL1_QSIZE + (q)->tent_next - (q)->ipos)
-#define cq_tent_add(q, c)						\
-			((q)->buf[(q)->tent_next] = (u_char) (c),	\
-			 (q)->tent_next = NEXT((q)->tent_next))
-#define cq_commit_tent(q)						\
-			((q)->ipos = (q)->tent_next)
-#define cq_discard_tent(q)						\
-			((q)->tent_next = (q)->ipos)
-
-
-
-
-/*********************************************************************
- * CRC-16 (for checking bedrock/L1 packets).
- *
- * These are based on RFC 1662 ("PPP in HDLC-like framing").
- */
-
-static unsigned short fcstab[256] = {
-      0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
-      0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
-      0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
-      0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
-      0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
-      0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
-      0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
-      0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
-      0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
-      0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
-      0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
-      0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
-      0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
-      0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
-      0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
-      0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
-      0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
-      0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
-      0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
-      0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
-      0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
-      0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
-      0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
-      0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
-      0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
-      0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
-      0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
-      0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
-      0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
-      0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
-      0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
-      0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
-};
-
-#define INIT_CRC	0xFFFF	/* initial CRC value	  */
-#define	GOOD_CRC	0xF0B8	/* "good" final CRC value */
-
-static unsigned short crc16_calc( unsigned short crc, u_char c )
-{
-    return( (crc >> 8) ^ fcstab[(crc ^ c) & 0xff] );
-}
-
-
-/***********************************************************************
- * The following functions implement the PPP-like bedrock/L1 protocol
- * layer.
- *
- */
-
-#define BRL1_FLAG_CH	0x7e
-#define BRL1_ESC_CH	0x7d
-#define BRL1_XOR_CH	0x20
-
-/* L1<->Bedrock packet types */
-#define BRL1_REQUEST    0x00
-#define BRL1_RESPONSE   0x20
-#define BRL1_EVENT      0x40
-
-#define BRL1_PKT_TYPE_MASK      0xE0
-#define BRL1_SUBCH_MASK         0x1F
-
-#define PKT_TYPE(tsb)   ((tsb) & BRL1_PKT_TYPE_MASK)
-#define SUBCH(tsb)	((tsb) & BRL1_SUBCH_MASK)
-
-/* timeouts */
-#define BRL1_INIT_TIMEOUT	500000
-
-/*
- * brl1_discard_packet is a dummy "receive callback" used to get rid
- * of packets we don't want
- */
-void brl1_discard_packet( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &sc->subch[ch];
-
-    sc_cq_t *q = subch->iqp;
-    SUBCH_DATA_LOCK( subch, pl );
-    q->opos = q->ipos;
-    atomic_set(&(subch->packet_arrived), 0);
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-
-/*
- * brl1_send_chars sends the send buffer in the l1sc_t structure
- * out through the uart.  Assumes that the caller has locked the
- * UART (or send buffer in the kernel).
- *
- * This routine doesn't block-- if you want it to, call it in
- * a loop.
- */
-static int
-brl1_send_chars( l1sc_t *sc )
-{
-    /* We track the depth of the C brick's UART's
-     * fifo in software, and only check if the UART is accepting
-     * characters when our count indicates that the fifo should
-     * be full.
-     *
-     * For remote (router) UARTs, we check with the UART before sending every
-     * character.
-     */
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	if( !(sc->fifo_space) && UART_PUTC_READY( sc->nasid ) )
-	    sc->fifo_space = UART_FIFO_DEPTH;
-	
-	while( (sc->sent < sc->send_len) && (sc->fifo_space) ) {
-	    uart_putc( sc );
-	    sc->fifo_space--;
-	    sc->sent++;
-	}
-    }
-    else {
-
-	/* remote (router) UARTs */
-
-	int result;
-	int tries = 0;
-
-	while( sc->sent < sc->send_len ) {
-	    result = sc->putc_f( sc );
-	    if( result >= 0 ) {
-		(sc->sent)++;
-		continue;
-	    }
-	    if( result == UART_TIMEOUT ) {
-		tries++;
-		/* send this character in TIMEOUT_RETRIES... */
-		if( tries < 30 /* TIMEOUT_RETRIES */ ) {
-		    continue;
-		}
-		/* ...or else... */
-		else {
-		    /* ...drop the packet. */
-		    sc->sent = sc->send_len;
-		    return sc->send_len;
-		}
-	    }
-	    if( result < 0 ) {
-		return result;
-	    }
-	}
-    }
-    return sc->sent;
-}
-
-
-/* brl1_send formats up a packet and (at least begins to) send it
- * to the uart.  If the send buffer is in use when this routine obtains
- * the lock, it will behave differently depending on the "wait" parameter.
- * For wait == 0 (most I/O), it will return 0 (as in "zero bytes sent"),
- * hopefully encouraging the caller to back off (unlock any high-level 
- * spinlocks) and allow the buffer some time to drain.  For wait==1 (high-
- * priority I/O along the lines of kernel error messages), we will flush
- * the current contents of the send buffer and beat on the uart
- * until our message has been completely transmitted.
- */
-
-static int
-brl1_send( l1sc_t *sc, char *msg, int len, u_char type_and_subch, int wait )
-{
-    unsigned long pl = 0;
-    int index;
-    int pkt_len = 0;
-    unsigned short crc = INIT_CRC;
-    char *send_ptr = sc->send;
-
-
-    if( sc->send_in_use && !(wait) ) {
-	/* We are in the middle of sending, but can wait until done */
-	return 0;
-    }
-    else if( sc->send_in_use ) {
-	/* buffer's in use, but we're synchronous I/O, so we're going
-	 * to send whatever's in there right now and take the buffer
-	 */
-	int counter = 0;
-
-	if ( sc->uart == BRL1_LOCALHUB_UART )
-		lock_console(sc->nasid);
-	L1SC_SEND_LOCK(sc, pl);
-	while( sc->sent < sc->send_len ) {
-		brl1_send_chars( sc );
-		if ( counter++ > 0xfffff ) {
-			char *str = "Looping waiting for uart to clear (1)\n";
-			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
-			break;
-		}
-	}
-    }
-    else {
-	if ( sc->uart == BRL1_LOCALHUB_UART )
-		lock_console(sc->nasid);
-	L1SC_SEND_LOCK(sc, pl);
-	sc->send_in_use = 1;
-    }
-    *send_ptr++ = BRL1_FLAG_CH;
-    *send_ptr++ = type_and_subch;
-    pkt_len += 2;
-    crc = crc16_calc( crc, type_and_subch );
-
-    /* limit number of characters accepted to max payload size */
-    if( len > (BRL1_QSIZE - 1) )
-	len = (BRL1_QSIZE - 1);
-
-    /* copy in the message buffer (inserting PPP 
-     * framing info where necessary)
-     */
-    for( index = 0; index < len; index++ ) {
-
-	switch( *msg ) {
-	    
-	  case BRL1_FLAG_CH:
-	    *send_ptr++ = BRL1_ESC_CH;
-	    *send_ptr++ = (*msg) ^ BRL1_XOR_CH;
-	    pkt_len += 2;
-	    break;
-	    
-	  case BRL1_ESC_CH:
-	    *send_ptr++ = BRL1_ESC_CH;
-	    *send_ptr++ = (*msg) ^ BRL1_XOR_CH;
-	    pkt_len += 2;
-	    break;
-	    
-	  default:
-	    *send_ptr++ = *msg;
-	    pkt_len++;
-	}
-	crc = crc16_calc( crc, *msg );
-	msg++;
-    }
-    crc ^= 0xffff;
-
-    for( index = 0; index < sizeof(crc); index++ ) {
-	char crc_char = (char)(crc & 0x00FF);
-	if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	    *send_ptr++ = BRL1_ESC_CH;
-	    pkt_len++;
-	    crc_char ^= BRL1_XOR_CH;
-	}
-	*send_ptr++ = crc_char;
-	pkt_len++;
-	crc >>= 8;
-    }
-    
-    *send_ptr++ = BRL1_FLAG_CH;
-    pkt_len++;
-
-    sc->send_len = pkt_len;
-    sc->sent = 0;
-
-    {
-	int counter = 0;
-	do {
-		brl1_send_chars( sc );
-		if ( counter++ > 0xfffff ) {
-			char *str = "Looping waiting for uart to clear (2)\n";
-			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
-			break;
-		}
-	} while( (sc->sent < sc->send_len) && wait );
-    }
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(sc->nasid);
-
-    if( sc->sent == sc->send_len ) {
-	/* success! release the send buffer and call the callup */
-#if	!defined(SYNC_CONSOLE_WRITE)
-	brl1_notif_t callup;
-#endif
-
-	sc->send_in_use = 0;
-	/* call any upper layer that's asked for notification */
-#if	defined(XX_SYNC_CONSOLE_WRITE)
-	/*
-	 * This is probably not a good idea - since the l1_ write func can be called multiple
-	 * time within the callup function.
-	 */
-	callup = subch->tx_notify;
-	if( callup && (SUBCH(type_and_subch) == SC_CONS_SYSTEM) ) {
-		L1_collectibles[L1C_SEND_CALLUPS]++;
-		(*callup)(sc->subch[SUBCH(type_and_subch)].irq_frame.bf_irq,
-				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_dev_id,
-				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_regs, sc, SUBCH(type_and_subch));
-	}
-#endif	/* SYNC_CONSOLE_WRITE */
-    }
-#if	!defined(SYNC_CONSOLE_WRITE)
-    else if ( !wait ) {
-	/* enable low-water interrupts so buffer will be drained */
-	uart_enable_xmit_intr(sc);
-    }
-#endif
-
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    return len;
-}
-
-/* brl1_send_cont is intended to be called as an interrupt service
- * routine.  It sends until the UART won't accept any more characters,
- * or until an error is encountered (in which case we surrender the
- * send buffer and give up trying to send the packet).  Once the
- * last character in the packet has been sent, this routine releases
- * the send buffer and calls any previously-registered "low-water"
- * output routines.
- */
-
-#if	!defined(SYNC_CONSOLE_WRITE)
-
-int
-brl1_send_cont( l1sc_t *sc )
-{
-    unsigned long pl = 0;
-    int done = 0;
-    brl1_notif_t callups[BRL1_NUM_SUBCHANS];
-    brl1_notif_t *callup;
-    brl1_sch_t *subch;
-    int index;
-
-    /*
-     * I'm not sure how I think this is to be handled - whether the lock is held
-     * over the interrupt - but it seems like it is a bad idea....
-     */
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(sc->nasid);
-    L1SC_SEND_LOCK(sc, pl);
-    brl1_send_chars( sc );
-    done = (sc->sent == sc->send_len);
-    if( done ) {
-	sc->send_in_use = 0;
-#if	!defined(SYNC_CONSOLE_WRITE)
-	uart_disable_xmit_intr(sc);
-#endif
-    }
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(sc->nasid);
-    /* Release the lock */
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    return 0;
-}
-#endif	/* SYNC_CONSOLE_WRITE */
-
-/* internal function -- used by brl1_receive to read a character 
- * from the uart and check whether errors occurred in the process.
- */
-static int
-read_uart( l1sc_t *sc, int *c, int *result )
-{
-    *c = sc->getc_f( sc );
-
-    /* no character is available */
-    if( *c == UART_NO_CHAR ) {
-	*result = BRL1_NO_MESSAGE;
-	return 0;
-    }
-
-    /* some error in UART */
-    if( *c < 0 ) {
-	*result = BRL1_LINK;
-	return 0;
-    }
-
-    /* everything's fine */
-    *result = BRL1_VALID;
-    return 1;
-}
-
-
-/*
- * brl1_receive
- *
- * This function reads a Bedrock-L1 protocol packet into the l1sc_t
- * response buffer.
- *
- * The operation of this function can be expressed as a finite state
- * machine:
- *
-
-START STATE			INPUT		TRANSITION
-==========================================================
-BRL1_IDLE (reset or error)	flag		BRL1_FLAG
-				other		BRL1_IDLE@
-
-BRL1_FLAG (saw a flag (0x7e))	flag		BRL1_FLAG
-				escape		BRL1_IDLE@
-				header byte	BRL1_HDR
-				other		BRL1_IDLE@
-
-BRL1_HDR (saw a type/subch byte)(see below)	BRL1_BODY
-						BRL1_HDR
-
-BRL1_BODY (reading packet body)	flag		BRL1_FLAG
-				escape		BRL1_ESC
-				other		BRL1_BODY
-
-BRL1_ESC (saw an escape (0x7d))	flag		BRL1_FLAG@
-				escape		BRL1_IDLE@
-				other		BRL1_BODY
-==========================================================
-
-"@" denotes an error transition.
-
- * The BRL1_HDR state is a transient state which doesn't read input,
- * but just provides a way in to code which decides to whom an
- * incoming packet should be directed.
- *
- * brl1_receive can be used to poll for input from the L1, or as 
- * an interrupt service routine.  It reads as much data as is
- * ready from the junk bus UART and places into the appropriate
- * input queues according to subchannel.  The header byte is
- * stripped from console-type data, but is retained for message-
- * type data (L1 responses).  A length byte will also be
- * prepended to message-type packets.
- *
- * This routine is non-blocking; if the caller needs to block
- * for input, it must call brl1_receive in a loop.
- *
- * brl1_receive returns when there is no more input, the queue
- * for the current incoming message is full, or there is an
- * error (parity error, bad header, bad CRC, etc.).
- */
-
-#define STATE_SET(l,s)		((l)->brl1_state = (s))
-#define STATE_GET(l)		((l)->brl1_state)
-
-#define LAST_HDR_SET(l,h)	((l)->brl1_last_hdr = (h))
-#define LAST_HDR_GET(l)		((l)->brl1_last_hdr)
-
-#define VALID_HDR(c)				\
-    ( SUBCH((c)) <= SC_CONS_SYSTEM		\
-	? PKT_TYPE((c)) == BRL1_REQUEST		\
-	: ( PKT_TYPE((c)) == BRL1_RESPONSE ||	\
-	    PKT_TYPE((c)) == BRL1_EVENT ) )
-
-#define IS_TTY_PKT(l)		( SUBCH(LAST_HDR_GET(l)) <= SC_CONS_SYSTEM ? 1 : 0 )
-
-
-int
-brl1_receive( l1sc_t *sc, int mode )
-{
-    int result;		/* value to be returned by brl1_receive */
-    int c;		/* most-recently-read character	     	*/
-    int done;		/* set done to break out of recv loop	*/
-    unsigned long pl = 0, cpl = 0;
-    sc_cq_t *q;		/* pointer to queue we're working with	*/
-
-    result = BRL1_NO_MESSAGE;
-
-    L1SC_RECV_LOCK(sc, cpl);
-
-    done = 0;
-    while( !done )
-    {
-	switch( STATE_GET(sc) )
-	{
-
-	  case BRL1_IDLE:
-	    /* Initial or error state.  Waiting for a flag character
-             * to resynchronize with the L1.
-             */
-
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* saw a flag character */
-		STATE_SET( sc, BRL1_FLAG );
-		continue;
-	    }
-	    break;
-	    
-	  case BRL1_FLAG:
-	    /* One or more flag characters have been read; look for
-	     * the beginning of a packet (header byte).
-	     */
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR )
-		    STATE_SET( sc, BRL1_IDLE );
-
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* multiple flags are OK */
-		continue;
-	    }
-
-	    if( !VALID_HDR( c ) ) {
-		/* if c isn't a flag it should have been
-		 * a valid header, so we have an error
-		 */
-		result = BRL1_PROTOCOL;
-		STATE_SET( sc, BRL1_IDLE );
-		done = 1;
-		continue;
-	    }
-
-	    /* we have a valid header byte */
-	    LAST_HDR_SET( sc, c );
-	    STATE_SET( sc, BRL1_HDR );
-
-	    break; 
-
-	  case BRL1_HDR:
-	    /* A header byte has been read. Do some bookkeeping. */
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-	    
-	    if( !IS_TTY_PKT(sc) ) {
-		/* if this is an event or command response rather
-		 * than console I/O, we need to reserve a couple
-		 * of extra spaces in the queue for the header
-		 * byte and a length byte; if we can't, stay in
-		 * the BRL1_HDR state.
-		 */
-		if( cq_room( q ) < 2 ) {
-		    result = BRL1_FULL_Q;
-		    done = 1;
-		    continue;
-		}
-		cq_tent_add( q, 0 );			/* reserve length byte */
-		cq_tent_add( q, LAST_HDR_GET( sc ) );	/* record header byte  */
-	    }
-	    STATE_SET( sc, BRL1_BODY );
-
-	    break;
-
-	  case BRL1_BODY:
-	    /* A header byte has been read.  We are now attempting
-	     * to receive the packet body.
-	     */
-
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-
-	    /* if the queue we want to write into is full, don't read from
-	     * the uart (this provides backpressure to the L1 side)
-	     */
-	    if( cq_tent_full( q ) ) {
-		result = BRL1_FULL_Q;
-		done = 1;
-		continue;
-	    }
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR )
-		    STATE_SET( sc, BRL1_IDLE );
-		done = 1;
-		continue;
-	    }
-
-	    if( c == BRL1_ESC_CH ) {
-		/* prepare to unescape the next character */
-		STATE_SET( sc, BRL1_ESC );
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* flag signifies the end of a packet */
-
-		unsigned short crc;	/* holds the crc as we calculate it */
-		int i;			/* index variable */
-		brl1_sch_t *subch;      /* subchannel for received packet */
-		brl1_notif_t callup;	/* "data ready" callup */
-
-		/* whatever else may happen, we've seen a flag and we're
-		 * starting a new packet
-		 */
-		STATE_SET( sc, BRL1_FLAG );
-
-		/* if the packet body has less than 2 characters,
-		 * it can't be a well-formed packet.  Discard it.
-		 */
-		if( cq_tent_len( q ) < /* 2 + possible length byte */
-		    (2 + (IS_TTY_PKT(sc) ? 0 : 1)) )
-		{
-		    result = BRL1_PROTOCOL;
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_FLAG );
-		    done = 1;
-		    continue;
-		}
-		
-		/* check CRC */
-
-		/* accumulate CRC, starting with the header byte and
-		 * ending with the transmitted CRC.  This should
-		 * result in a known good value.
-		 */
-		crc = crc16_calc( INIT_CRC, LAST_HDR_GET(sc) );
-		for( i = (q->ipos + (IS_TTY_PKT(sc) ? 0 : 2)) % BRL1_QSIZE;
-		     i != q->tent_next;
-		     i = (i + 1) % BRL1_QSIZE )
-		{
-		    crc = crc16_calc( crc, q->buf[i] );
-		}
-
-		/* verify the caclulated crc against the "good" crc value;
-		 * if we fail, discard the bad packet and return an error.
-		 */
-		if( crc != (unsigned short)GOOD_CRC ) {
-		    result = BRL1_CRC;
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_FLAG );
-		    done = 1;
-		    continue;
-		}
-		
-		/* so the crc check was ok.  Now we discard the CRC
-		 * from the end of the received bytes.
-		 */
-		q->tent_next += (BRL1_QSIZE - 2);
-		q->tent_next %= BRL1_QSIZE;
-
-		/* get the subchannel and lock it */
-		subch = &(sc->subch[SUBCH( LAST_HDR_GET(sc) )]);
-		SUBCH_DATA_LOCK( subch, pl );
-		
-		/* if this isn't a console packet, we need to record
-		 * a length byte
-		 */
-		if( !IS_TTY_PKT(sc) ) {
-		    q->buf[q->ipos] = cq_tent_len( q ) - 1;
-		}
-		
-		/* record packet for posterity */
-		cq_commit_tent( q );
-		result = BRL1_VALID;
-
-		/* notify subchannel owner that there's something
-		 * on the queue for them
-		 */
-		atomic_inc(&(subch->packet_arrived));
-		callup = subch->rx_notify;
-		SUBCH_DATA_UNLOCK( subch, pl );
-
-		if( callup && (mode == SERIAL_INTERRUPT_MODE) ) {
-		    L1SC_RECV_UNLOCK( sc, cpl );
-		    L1_collectibles[L1C_RECEIVE_CALLUPS]++;
-		    (*callup)( sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_irq,
-				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_dev_id,
-				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_regs,
-				sc, SUBCH(LAST_HDR_GET(sc)) );
-		    L1SC_RECV_LOCK( sc, cpl );
-		}
-		continue;	/* go back for more! */
-	    }
-	    
-	    /* none of the special cases applied; we've got a normal
-	     * body character
-	     */
-	    cq_tent_add( q, c );
-
-	    break;
-
-	  case BRL1_ESC:
-	    /* saw an escape character.  The next character will need
-	     * to be unescaped.
-	     */
-
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-
-	    /* if the queue we want to write into is full, don't read from
-	     * the uart (this provides backpressure to the L1 side)
-	     */
-	    if( cq_tent_full( q ) ) {
-		result = BRL1_FULL_Q;
-		done = 1;
-		continue;
-	    }
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR ) {
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_IDLE );
-		}
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* flag after escape is an error */
-		STATE_SET( sc, BRL1_FLAG );
-		cq_discard_tent( q );
-		result = BRL1_PROTOCOL;
-		done = 1;
-		continue;
-	    }
-
-	    if( c == BRL1_ESC_CH ) {
-		/* two consecutive escapes is an error */
-		STATE_SET( sc, BRL1_IDLE );
-		cq_discard_tent( q );
-		result = BRL1_PROTOCOL;
-		done = 1;
-		continue;
-	    }
-	    
-	    /* otherwise, we've got a character that needs
-	     * to be unescaped
-	     */
-	    cq_tent_add( q, (c ^ BRL1_XOR_CH) );
-	    STATE_SET( sc, BRL1_BODY );
-
-	    break;
-
-	} /* end of switch( STATE_GET(sc) ) */
-    } /* end of while(!done) */
-
-    L1SC_RECV_UNLOCK( sc, cpl );
-
-    return result;
-}	    
-
-
-/* brl1_init initializes the Bedrock/L1 protocol layer.  This includes
- * zeroing out the send and receive state information.
- */
-
-void
-brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    int i;
-    brl1_sch_t *subch;
-
-    bzero( sc, sizeof( *sc ) );
-    sc->nasid = nasid;
-    sc->uart = uart;
-    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
-    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
-    sc->sol = 1;
-    subch = sc->subch;
-
-    /* initialize L1 subchannels
-     */
-
-    /* assign processor TTY channels */
-    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	spin_lock_init( &(subch->data_lock) );
-	sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
-	subch->tx_notify = NULL;
-	/* (for now, drop elscuart packets in the kernel) */
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* assign system TTY channel (first free subchannel after each
-     * processor's individual TTY channel has been assigned)
-     */
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = ATOMIC_INIT(0);
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &subch->data_lock, SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
-    subch->tx_notify = NULL;
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, NASID_TO_COMPACT_NODEID(nasid) );
-	ASSERT( subch->iqp );
-	cq_init( subch->iqp );
-	subch->rx_notify = NULL;
-    }
-    else {
-	/* we shouldn't be getting console input from remote UARTs */
-	subch->iqp = &sc->garbage_q;
-	subch->rx_notify = brl1_discard_packet;
-    }
-    subch++; i++;
-
-    /* "reserved" subchannels (0x05-0x0F); for now, throw away
-     * incoming packets
-     */
-    for( ; i < 0x10; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* remaining subchannels are free */
-    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* initialize synchronization structures
-     */
-    spin_lock_init( &(sc->subch_lock) );
-    spin_lock_init( &(sc->send_lock) );
-    spin_lock_init( &(sc->recv_lock) );
-
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	uart_init( sc, UART_BAUD_RATE );
-    }
-    else {
-	rtr_uart_init( sc, UART_BAUD_RATE );
-    }
-
-    /* Set up remaining fields using L1 command functions-- elsc_module_get
-     * to read the module id, elsc_debug_get to see whether or not we're
-     * in verbose mode.
-     */
-    {
-	extern int elsc_module_get(l1sc_t *);
-
-	sc->modid = elsc_module_get( sc );
-	sc->modid = (sc->modid < 0 ? INVALID_MODULE : sc->modid);
-	sc->verbose = 1;
-    }
-}
-
-/*********************************************************************
- * These are interrupt-related functions used in the kernel to service
- * the L1.
- */
-
-/*
- * brl1_intrd is the function which is called on a console interrupt.
- */
-
-#if defined(CONFIG_IA64_SGI_SN1)
-
-static void
-brl1_intrd(int irq, void *dev_id, struct pt_regs *stuff)
-{
-    u_char isr_reg;
-    l1sc_t *sc = get_elsc();
-    int ret;
-
-    L1_collectibles[L1C_INTERRUPTS]++;
-    isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-
-    /* Save for callup args in console */
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_irq = irq;
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_dev_id = dev_id;
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_regs = stuff;
-
-#if	defined(SYNC_CONSOLE_WRITE)
-    while( isr_reg & ISR_RxRDY )
-#else
-    while( isr_reg & (ISR_RxRDY | ISR_TxRDY) )
-#endif
-    {
-	if( isr_reg & ISR_RxRDY ) {
-	    L1_collectibles[L1C_OUR_R_INTERRUPTS]++;
-	    ret = brl1_receive(sc, SERIAL_INTERRUPT_MODE);
-	    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
-		L1_collectibles[L1C_REC_STALLS] = ret;
-	}
-#if	!defined(SYNC_CONSOLE_WRITE)
-	if( (isr_reg & ISR_TxRDY) || (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) {
-	    L1_collectibles[L1C_OUR_X_INTERRUPTS]++;
-	    brl1_send_cont(sc);
-	}
-#endif	/* SYNC_CONSOLE_WRITE */
-	isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-    }
-}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-
-/*
- * Install a callback function for the system console subchannel 
- * to allow an upper layer to be notified when the send buffer 
- * has been emptied.
- */
-static inline void
-l1_tx_notif( brl1_notif_t func )
-{
-	subch_set_tx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
-			SC_CONS_SYSTEM, func );
-}
-
-
-/*
- * Install a callback function for the system console subchannel
- * to allow an upper layer to be notified when a packet has been
- * received.
- */
-static inline void
-l1_rx_notif( brl1_notif_t func )
-{
-	subch_set_rx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
-				SC_CONS_SYSTEM, func );
-}
-
-
-/* brl1_intr is called directly from the uart interrupt; after it runs, the
- * interrupt "daemon" xthread is signalled to continue.
- */
-void
-brl1_intr( void )
-{
-}
-
-#define BRL1_INTERRUPT_LEVEL	65	/* linux request_irq() value */
-
-/* Return the current interrupt level */
-
-//#define CONSOLE_POLLING_ALSO
-
-int
-l1_get_intr_value( void )
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	return(0);
-#else
-#if defined(CONSOLE_POLLING_ALSO)
-	return(0);
-#else
-	return(BRL1_INTERRUPT_LEVEL);
-#endif /* CONSOLE_POLLING_ALSO */
-#endif /* USE_SAL_CONSOLE_IO */
-}
-
-/* Disconnect the callup functions - throw away interrupts */
-
-void
-l1_unconnect_intr(void)
-{
-#if !defined(USE_SAL_CONSOLE_IO)
-	/* UnRegister the upper-level callup functions */
-	l1_rx_notif((brl1_notif_t)NULL);
-	l1_tx_notif((brl1_notif_t)NULL);
-	/* We do NOT unregister the interrupts */
-#endif /* !USE_SAL_CONSOLE_IO */
-}
-
-/* Set up uart interrupt handling for this node's uart */
-
-void
-l1_connect_intr(void *rx_notify, void *tx_notify)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-#if 0
-	// Will need code here for sn2 - something like this
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid());
-	intr_connect_level(console_nodepda->node_first_cpu,
-                                SGI_UART_VECTOR, INTPEND0_MAXMASK,
-                                dummy_intr_func);
-	request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8),
-                                intr_func, SA_INTERRUPT | SA_SHIRQ,
-                                "l1_protocol_driver", (void *)sc);
-#endif
-#else
-	l1sc_t *sc;
-	nasid_t nasid;
-#if defined(CONFIG_IA64_SGI_SN1)
-	int tmp;
-#endif
-	nodepda_t *console_nodepda;
-	int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t);
-
-	if ( L1_interrupts_connected ) {
-		/* Interrupts are connected, so just register the callups */
-		l1_rx_notif((brl1_notif_t)rx_notify);
-		l1_tx_notif((brl1_notif_t)tx_notify);
-
-		L1_collectibles[L1C_CONNECT_CALLS]++;
-		return;
-	}
-	else
-		L1_interrupts_connected = 1;
-
-	nasid = get_master_nasid();
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(nasid));
-	sc = &console_nodepda->module->elsc;
-	sc->intr_cpu = console_nodepda->node_first_cpu;
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	if ( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK, (intr_func_t)brl1_intr) ) {
-		L1_interrupts_connected = 0; /* FAILS !! */
-	}
-	else {
-		void synergy_intr_connect(int, int);
-
-		synergy_intr_connect(UART_INTR, sc->intr_cpu);
-		L1_collectibles[L1C_R_IRQ]++;
-		tmp = request_irq(BRL1_INTERRUPT_LEVEL, brl1_intrd, SA_INTERRUPT | SA_SHIRQ, "l1_protocol_driver", (void *)sc);
-		L1_collectibles[L1C_R_IRQ_RET] = (uint64_t)tmp;
-		if ( tmp ) {
-			L1_interrupts_connected = 0; /* FAILS !! */
-		}
-		else {
-			/* Register the upper-level callup functions */
-			l1_rx_notif((brl1_notif_t)rx_notify);
-			l1_tx_notif((brl1_notif_t)tx_notify);
-
-			/* Set the uarts the way we like it */
-			uart_enable_recv_intr( sc );
-			uart_disable_xmit_intr( sc );
-		}
-	}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-#endif	/* USE_SAL_CONSOLE_IO */
-}
-
-
-/* These are functions to use from serial_in/out when in protocol
- * mode to send and receive uart control regs. These are external
- * interfaces into the protocol driver.
- */
-
-void
-l1_control_out(int offset, int value)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	/* quietly ignore unless simulator */
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		if ( master_node_bedrock_address != (u64)0 ) {
-			writeb(value, (unsigned long)master_node_bedrock_address +
-				(offset<< 3));
-		}
-		return;
-	}
-#else
-	nasid_t nasid = get_master_nasid();
-	WRITE_L1_UART_REG(nasid, offset, value); 
-#endif
-}
-
-/* Console input exported interface. Return a register value.  */
-
-int
-l1_control_in_polled(int offset)
-{
-	static int l1_control_in_local(int, int);
-
-	return(l1_control_in_local(offset, SERIAL_POLLED_MODE));
-}
-
-int
-l1_control_in(int offset)
-{
-	static int l1_control_in_local(int, int);
-
-	return(l1_control_in_local(offset, SERIAL_INTERRUPT_MODE));
-}
-
-static int
-l1_control_in_local(int offset, int mode)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	int sal_call_status = 0, input;
-	int ret = 0;
-
-	if ( offset == REG_LSR ) {
-		ret = (LSR_XHRE | LSR_XSRE);	/* can send anytime */
-		sal_call_status = ia64_sn_console_check(&input);
-		if ( !sal_call_status && input ) {
-			/* input pending */
-			ret |= LSR_RCA;
-		}
-	}
-
-	/* If the sal call failed, do it the old-fashioned way */
-	if ( sal_call_status ) {
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-			ret = readb((unsigned long)master_node_bedrock_address +
-					(offset<< 3));
-		}		
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid;
-			int ret, input;
-			static int l1_poll(l1sc_t *, int);
-
-			nasid = get_master_nasid();
-			ret = READ_L1_UART_REG(nasid, offset); 
-
-			if ( offset == REG_LSR ) {
-				ret |= (LSR_XHRE | LSR_XSRE);	/* can send anytime */
-				if ( L1_cons_is_inited ) {
-					if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
-						input = l1_poll(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, mode);
-						if ( input ) {
-							ret |= LSR_RCA;
-						}
-					}
-				}
-			}
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-#endif
-	return(ret);
-}
-
-/*
- * Console input exported interface. Return a character (if one is available)
- */
-
-int
-l1_serial_in_polled(void)
-{
-	static int l1_serial_in_local(int mode);
-
-	return(l1_serial_in_local(SERIAL_POLLED_MODE));
-}
-
-int
-l1_serial_in(void)
-{
-	static int l1_serial_in_local(int mode);
-
-	return(l1_serial_in_local(SERIAL_INTERRUPT_MODE));
-}
-
-static int
-l1_serial_in_local(int mode)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	int sal_call_status;
-	int ch;
-
-	sal_call_status = ia64_sn_console_getc(&ch);
-	if ( !sal_call_status ) {
-		return(ch);
-	}
-	else {
-		/* If the sal called failed - do it the old-fashioned way */
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-			return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));
-		}		
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid;
-			l1sc_t *sc;
-			int value;
-			static int l1_getc( l1sc_t *, int );
-			static inline l1sc_t *early_sc_init(nasid_t);
-
-			nasid = get_master_nasid();
-			sc = early_sc_init(nasid);
-			if ( L1_cons_is_inited ) {
-				if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
-					sc = &NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc;
-				}
-			}
-			value = l1_getc(sc, mode);
-			return(value);
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-#endif
-}
-
-/* Console output exported interface. Write message to the console.  */
-
-int
-l1_serial_out( char *str, int len )
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	int sal_call_status = 0;
-	int counter = len;
-
-	/* Attempt to write things out thru the sal */
-	while ( counter > 0 ) {
-		if ( (sal_call_status = ia64_sn_console_putc(*str)) ) {
-			break;
-		}
-		counter--;
-		str++;
-	}
-	if ( sal_call_status ) {
-		/* If the sal called failed - do it the old-fashioned way */
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-                        if (!master_node_bedrock_address)
-                                early_sn_setup();
-			if ( master_node_bedrock_address != (u64)0 ) {
-#ifdef FLAG_DIRECT_CONSOLE_WRITES
-				/* This is an easy way to pre-pend the output to know whether the output
-				 * was done via sal or directly */
-				writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-#endif	/* FLAG_DIRECT_CONSOLE_WRITES */
-				while ( counter > 0 ) {
-					writeb(*str, (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-					counter--;
-					str++;
-				}
-			}
-		}
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid = get_master_nasid();
-			int l1_write(l1sc_t *, char *, int, int);
-
-			if ( L1_cons_is_inited ) {
-				if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 )
-					return(l1_write(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, str, len,
-#if	defined(SYNC_CONSOLE_WRITE)
-							1
-#else
-							!L1_interrupts_connected
-#endif
-									));
-			}
-			return(early_l1_serial_out(nasid, str, len, NOT_LOCKED));
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-	return((counter <= 0) ? 0 : (len - counter));
-#endif
-}
-
-
-/*
- * These are the 'early' functions - when we need to do things before we have
- * all the structs setup.
- */
-
-
-static l1sc_t Early_console;		/* fake l1sc_t */
-static int Early_console_inited = 0;
-
-static void
-early_brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    int i;
-    brl1_sch_t *subch;
-
-    bzero( sc, sizeof( *sc ) );
-    sc->nasid = nasid;
-    sc->uart = uart;
-    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
-    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
-    sc->sol = 1;
-    subch = sc->subch;
-
-    /* initialize L1 subchannels
-     */
-
-    /* assign processor TTY channels */
-    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* assign system TTY channel (first free subchannel after each
-     * processor's individual TTY channel has been assigned)
-     */
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = ATOMIC_INIT(0);
-    subch->tx_notify = NULL;
-    subch->rx_notify = NULL;
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	static sc_cq_t x_iqp;
-
-	subch->iqp = &x_iqp;
-	ASSERT( subch->iqp );
-	cq_init( subch->iqp );
-    }
-    else {
-	/* we shouldn't be getting console input from remote UARTs */
-	subch->iqp = &sc->garbage_q;
-    }
-    subch++; i++;
-
-    /* "reserved" subchannels (0x05-0x0F); for now, throw away
-     * incoming packets
-     */
-    for( ; i < 0x10; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* remaining subchannels are free */
-    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-}
-
-static inline l1sc_t *
-early_sc_init(nasid_t nasid)
-{
-	/* This is for early I/O */
-	if ( Early_console_inited == 0 ) {
-    		early_brl1_init(&Early_console, nasid,  BRL1_LOCALHUB_UART);
-		Early_console_inited = 1;
-	}
-	return(&Early_console);
-}
-
-#define PUTCHAR(ch) \
-    { \
-        while( (!(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE)) || \
-                (!(READ_L1_UART_REG( nasid, REG_MSR ) & MSR_CTS)) ); \
-        WRITE_L1_UART_REG( nasid, REG_DAT, (ch) ); \
-    }
-
-static int
-early_l1_serial_out( nasid_t nasid, char *str, int len, int lock_state )
-{
-	int ret, sent = 0;
-	char *msg = str;
-	static int early_l1_send( nasid_t nasid, char *str, int len, int lock_state );
-
-	while ( sent < len ) {
-		ret = early_l1_send(nasid, msg, len - sent, lock_state);
-		sent += ret;
-		msg += ret;
-	}
-	return(len);
-}
-
-static inline int
-early_l1_send( nasid_t nasid, char *str, int len, int lock_state )
-{
-    int sent;
-    char crc_char;
-    unsigned short crc = INIT_CRC;
-
-    if( len > (BRL1_QSIZE - 1) )
-	len = (BRL1_QSIZE - 1);
-
-    sent = len;
-    if ( lock_state == NOT_LOCKED )
-    	lock_console(nasid);
-
-    PUTCHAR( BRL1_FLAG_CH );
-    PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM );
-    crc = crc16_calc( crc, (BRL1_EVENT | SC_CONS_SYSTEM) );
-
-    while( len ) {
-
-	if( (*str == BRL1_FLAG_CH) || (*str == BRL1_ESC_CH) ) {
-	    PUTCHAR( BRL1_ESC_CH );
-	    PUTCHAR( (*str) ^ BRL1_XOR_CH );
-	}
-	else {
-	    PUTCHAR( *str );
-	}
-	
-	crc = crc16_calc( crc, *str );
-
-	str++; len--;
-    }
-    
-    crc ^= 0xffff;
-    crc_char = crc & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    crc_char = (crc >> 8) & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    PUTCHAR( BRL1_FLAG_CH );
-
-    if ( lock_state == NOT_LOCKED )
-    	unlock_console(nasid);
-    return sent;
-}
-
-/*********************************************************************
- * l1_cons functions
- *
- * These allow the L1 to act as the system console.  They're intended
- * to abstract away most of the br/l1 internal details from the
- * _L1_cons_* functions (in the prom-- see "l1_console.c") and
- * l1_* functions (in the kernel-- see "sio_l1.c") that they support.
- *
- */
-
-static int
-l1_poll( l1sc_t *sc, int mode )
-{
-    int ret;
-
-    /* in case this gets called before the l1sc_t structure for the module_t
-     * struct for this node is initialized (i.e., if we're called with a
-     * zero l1sc_t pointer)...
-     */
-
-
-    if( !sc ) {
-	return 0;
-    }
-
-    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
-	return 1;
-    }
-
-    ret = brl1_receive( sc, mode );
-    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
-	L1_collectibles[L1C_REC_STALLS] = ret;
-
-    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
-	return 1;
-    }
-    return 0;
-}
-
-
-/* pull a character off of the system console queue (if one is available)
- */
-static int
-l1_getc( l1sc_t *sc, int mode )
-{
-    unsigned long pl = 0;
-    int c;
-
-    brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
-    sc_cq_t *q = subch->iqp;
-
-    if( !l1_poll( sc, mode ) ) {
-	return 0;
-    }
-
-    SUBCH_DATA_LOCK( subch, pl );
-    if( cq_empty( q ) ) {
-	atomic_set(&subch->packet_arrived, 0);
-	SUBCH_DATA_UNLOCK( subch, pl );
-	return 0;
-    }
-    cq_rem( q, c );
-    if( cq_empty( q ) )
-	atomic_set(&subch->packet_arrived, 0);
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return c;
-}
-
-/*
- * Write a message to the L1 on the system console subchannel.
- *
- * Danger: don't use a non-zero value for the wait parameter unless you're
- * someone important (like a kernel error message).
- */
-
-int
-l1_write( l1sc_t *sc, char *msg, int len, int wait )
-{
-	int sent = 0, ret = 0;
-
-	if ( wait ) {
-		while ( sent < len ) {
-			ret = brl1_send( sc, msg, len - sent, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
-			sent += ret;
-			msg += ret;
-		}
-		ret = len;
-	}
-	else {
-		ret = brl1_send( sc, msg, len, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
-	}
-	return(ret);
-}
-
-/* initialize the system console subchannel
- */
-void
-l1_init(void)
-{
-	/* All we do now is remember that we have been called */
-	L1_cons_is_inited = 1;
-}
-
-
-/*********************************************************************
- * The following functions and definitions implement the "message"-
- * style interface to the L1 system controller.
- *
- * Note that throughout this file, "sc" generally stands for "system
- * controller", while "subchannels" tend to be represented by
- * variables with names like subch or ch.
- *
- */
-
-#ifdef L1_DEBUG
-#define L1_DBG_PRF(x) printf x
-#else
-#define L1_DBG_PRF(x)
-#endif
-
-/*
- * sc_data_ready is called to signal threads that are blocked on l1 input.
- */
-void
-sc_data_ready( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-
-    brl1_sch_t *subch = &(sc->subch[ch]);
-    SUBCH_DATA_LOCK( subch, pl );
-    sv_signal( &(subch->arrive_sv) );
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-/* sc_open reserves a subchannel to send a request to the L1 (the
- * L1's response will arrive on the same channel).  The number
- * returned by sc_open is the system controller subchannel
- * acquired.
- */
-int
-sc_open( l1sc_t *sc, uint target )
-{
-    /* The kernel version implements a locking scheme to arbitrate
-     * subchannel assignment.
-     */
-    int ch;
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    SUBCH_LOCK( sc, pl );
-
-    /* Look for a free subchannel. Subchannels 0-15 are reserved
-     * for other purposes.
-     */
-    for( subch = &(sc->subch[BRL1_CMD_SUBCH]), ch = BRL1_CMD_SUBCH; 
-			ch < BRL1_NUM_SUBCHANS; subch++, ch++ ) {
-        if( subch->use == BRL1_SUBCH_FREE )
-            break;
-    }
-
-    if( ch == BRL1_NUM_SUBCHANS ) {
-        /* there were no subchannels available! */
-        SUBCH_UNLOCK( sc, pl );
-        return SC_NSUBCH;
-    }
-
-    subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->target = target;
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
-    subch->tx_notify = NULL;
-    subch->rx_notify = sc_data_ready;
-    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
-				   NASID_TO_COMPACT_NODEID(sc->nasid) );
-    ASSERT( subch->iqp );
-    cq_init( subch->iqp );
-
-    return ch;
-}
-
-
-/* sc_close frees a Bedrock<->L1 subchannel.
- */
-int
-sc_close( l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    SUBCH_LOCK( sc, pl );
-    subch = &(sc->subch[ch]);
-    if( subch->use != BRL1_SUBCH_RSVD ) {
-        /* we're trying to close a subchannel that's not open */
-	SUBCH_UNLOCK( sc, pl );
-        return SC_NOPEN;
-    }
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->use = BRL1_SUBCH_FREE;
-
-    sv_broadcast( &(subch->arrive_sv) );
-    sv_destroy( &(subch->arrive_sv) );
-    spin_lock_destroy( &(subch->data_lock) );
-
-    ASSERT( subch->iqp && (subch->iqp != &sc->garbage_q) );
-    snia_kmem_free( subch->iqp, sizeof(sc_cq_t) );
-    subch->iqp = &sc->garbage_q;
-    subch->tx_notify = NULL;
-    subch->rx_notify = brl1_discard_packet;
-
-    SUBCH_UNLOCK( sc, pl );
-
-    return SC_SUCCESS;
-}
-
-
-/* sc_construct_msg builds a bedrock-to-L1 request in the supplied
- * buffer.  Returns the length of the message.  The
- * safest course when passing a buffer to be filled in is to use
- * BRL1_QSIZE as the buffer size.
- *
- * Command arguments are passed as type/argument pairs, i.e., to
- * pass the number 5 as an argument to an L1 command, call
- * sc_construct_msg as follows:
- *
- *    char msg[BRL1_QSIZE];
- *    msg_len = sc_construct_msg( msg,
- *				  BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                2,
- *                                L1_ARG_INT, 5 );
- *
- * To pass an additional ASCII argument, you'd do the following:
- *
- *    char *str;
- *    ... str points to a null-terminated ascii string ...
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                4,
- *                                L1_ARG_INT, 5,
- *                                L1_ARG_ASCII, str );
- *
- * Finally, arbitrary data of unknown type is passed using the argtype
- * code L1_ARG_UNKNOWN, a data length, and a buffer pointer, e.g.
- *
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                3,
- *                                L1_ARG_UNKNOWN, 32, bufptr );
- *
- * ...passes 32 bytes of data starting at bufptr.  Note that no string or
- * "unknown"-type argument should be long enough to overflow the message
- * buffer.
- *
- * To construct a message for an L1 command that requires no arguments,
- * you'd use the following:
- *
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                0 );
- *
- * The final 0 means "no varargs".  Notice that this parameter is used to hold
- * the number of additional arguments to sc_construct_msg, _not_ the actual
- * number of arguments used by the L1 command (so 2 per L1_ARG_[INT,ASCII]
- * type argument, and 3 per L1_ARG_UNKOWN type argument).  A call to construct
- * an L1 command which required three integer arguments and two arguments of
- * some arbitrary (unknown) type would pass 12 as the value for this parameter.
- *
- * ENDIANNESS WARNING: The following code does a lot of copying back-and-forth
- * between byte arrays and four-byte big-endian integers.  Depending on the
- * system controller connection and endianness of future architectures, some
- * rewriting might be necessary.
- */
-int
-sc_construct_msg( l1sc_t  *sc,		/* system controller struct */
-		  int	   ch,           /* subchannel for this message */
-		  char    *msg,          /* message buffer */
-		  int      msg_len,      /* size of message buffer */
-                  l1addr_t addr_task,    /* target system controller task */
-                  short    req_code,     /* 16-bit request code */
-                  int      req_nargs,    /* # of arguments (varargs) passed */
-                  ... )                 /* any additional parameters */
-{
-    uint32_t buf32;   /* 32-bit buffer used to bounce things around */
-    void *bufptr;       /* used to hold command argument addresses */
-    va_list al;         /* variable argument list */
-    int index;          /* current index into msg buffer */
-    int argno;          /* current position in varargs list */
-    int l1_argno;       /* running total of arguments to l1 */
-    int l1_arg_t;       /* argument type/length */
-    int l1_argno_byte;  /* offset of argument count byte */
-
-    index = argno = 0;
-
-    /* set up destination address */
-    if( (msg_len -= sizeof( buf32 )) < 0 )
-	return -1;
-    L1_ADDRESS_TO_TASK( &buf32, sc->subch[ch].target, addr_task );
-    COPY_INT_TO_BUFFER(msg, index, buf32);
-
-    /* copy request code */
-    if( (msg_len -= 2) < 0 )
-	return( -1 );
-    msg[index++] = ((req_code >> 8) & 0xff);
-    msg[index++] = (req_code & 0xff);
-
-    if( !req_nargs ) {
-        return index;
-    }
-
-    /* reserve a byte for the argument count */
-    if( (msg_len -= 1) < 0 )
-	return( -1 );
-    l1_argno_byte = index++;
-    l1_argno = 0;
-
-    /* copy additional arguments */
-    va_start( al, req_nargs );
-    while( argno < req_nargs ) {
-        l1_argno++;
-        l1_arg_t = va_arg( al, int ); argno++;
-        switch( l1_arg_t )
-        {
-          case L1_ARG_INT:
-	    if( (msg_len -= (sizeof( buf32 ) + 1)) < 0 )
-		return( -1 );
-            msg[index++] = L1_ARG_INT;
-            buf32 = (unsigned)va_arg( al, int ); argno++;
-	    COPY_INT_TO_BUFFER(msg, index, buf32);
-            break;
-
-          case L1_ARG_ASCII:
-            bufptr = va_arg( al, char* ); argno++;
-	    if( (msg_len -= (strlen( bufptr ) + 2)) < 0 )
-		return( -1 );
-            msg[index++] = L1_ARG_ASCII;
-            strcpy( (char *)&(msg[index]), (char *)bufptr );
-            index += (strlen( bufptr ) + 1); /* include terminating null */
-            break;
-
-	  case L1_ARG_UNKNOWN:
-              {
-                  int arglen;
-		  
-                  arglen = va_arg( al, int ); argno++;
-                  bufptr = va_arg( al, void* ); argno++;
-		  if( (msg_len -= (arglen + 1)) < 0 )
-		      return( -1 );
-                  msg[index++] = L1_ARG_UNKNOWN | arglen;
-                  BCOPY( bufptr, &(msg[index]), arglen  );
-                  index += arglen;
-		  break;
-              }
-	  
-	  default: /* unhandled argument type */
-	    return -1;
-        }
-    }
-
-    va_end( al );
-    msg[l1_argno_byte] = l1_argno;
-
-    return index;
-}
-
-
-
-/* sc_interpret_resp verifies an L1 response to a bedrock request, and
- * breaks the response data up into the constituent parts.  If the
- * response message indicates error, or if a mismatch is found in the
- * expected number and type of arguments, an error is returned.  The
- * arguments to this function work very much like the arguments to
- * sc_construct_msg, above, except that L1_ARG_INTs must be followed
- * by a _pointer_ to an integer that can be filled in by this function.
- */
-int
-sc_interpret_resp( char *resp,          /* buffer received from L1 */
-                   int   resp_nargs,    /* number of _varargs_ passed in */
-                   ... )
-{
-    uint32_t buf32;   /* 32-bit buffer used to bounce things around */
-    void *bufptr;       /* used to hold response field addresses */
-    va_list al;         /* variable argument list */
-    int index;          /* current index into response buffer */
-    int argno;          /* current position in varargs list */
-    int l1_fldno;       /* number of resp fields received from l1 */
-    int l1_fld_t;       /* field type/length */
-
-    index = argno = 0;
-
-#if defined(L1_DEBUG)
-#define DUMP_RESP							  \
-    {									  \
-	int ix;								  \
-        char outbuf[512];						  \
-        sprintf( outbuf, "sc_interpret_resp error line %d: ", __LINE__ ); \
-	for( ix = 0; ix < 16; ix++ ) {					  \
-	    sprintf( &outbuf[strlen(outbuf)], "%x ", resp[ix] );	  \
-	}								  \
-	printk( "%s\n", outbuf );					  \
-    }
-#else
-#define DUMP_RESP
-#endif /* L1_DEBUG */
-
-    /* check response code */
-    COPY_BUFFER_TO_INT(resp, index, buf32);
-    if( buf32 != L1_RESP_OK ) {
-	DUMP_RESP;
-        return buf32;
-    }
-
-    /* get number of response fields */
-    l1_fldno = resp[index++];
-
-    va_start( al, resp_nargs );
-
-    /* copy out response fields */
-    while( argno < resp_nargs ) {
-        l1_fldno--;
-        l1_fld_t = va_arg( al, int ); argno++;
-        switch( l1_fld_t )
-        {
-          case L1_ARG_INT:
-            if( resp[index++] != L1_ARG_INT ) {
-                /* type mismatch */
-		va_end( al );
-		DUMP_RESP;
-		return -1;
-            }
-            bufptr = va_arg( al, int* ); argno++;
-	    COPY_BUFFER_TO_BUFFER(resp, index, bufptr);
-            break;
-
-          case L1_ARG_ASCII:
-            if( resp[index++] != L1_ARG_ASCII ) {
-                /* type mismatch */
-		va_end( al );
-		DUMP_RESP;
-                return -1;
-            }
-            bufptr = va_arg( al, char* ); argno++;
-            strcpy( (char *)bufptr, (char *)&(resp[index]) );
-            /* include terminating null */
-            index += (strlen( &(resp[index]) ) + 1);
-            break;
-
-          default:
-	    if( (l1_fld_t & L1_ARG_UNKNOWN) == L1_ARG_UNKNOWN )
-	    {
-		int *arglen;
-		
-		arglen = va_arg( al, int* ); argno++;
-		bufptr = va_arg( al, void* ); argno++;
-		*arglen = ((resp[index++] & ~L1_ARG_UNKNOWN) & 0xff);
-		BCOPY( &(resp[index]), bufptr, *arglen  );
-		index += (*arglen);
-	    }
-	    
-	    else {
-		/* unhandled type */
-		va_end( al );
-		DUMP_RESP;
-		return -1;
-	    }
-        }
-    }
-    va_end( al );
-  
-    if( (l1_fldno != 0) || (argno != resp_nargs) ) {
-        /* wrong number of arguments */
-	DUMP_RESP;
-        return -1;
-    }
-    return 0;
-}
-
-/* sc_send takes as arguments a system controller struct, a
- * buffer which contains a Bedrock<->L1 "request" message,
- * the message length, and the subchannel (presumably obtained
- * from an earlier invocation of sc_open) over which the
- * message is to be sent.  The final argument ("wait") indicates
- * whether the send is to be performed synchronously or not.
- *
- * sc_send returns either zero or an error value.  Synchronous sends 
- * (wait != 0) will not return until the data has actually been sent
- * to the UART.  Synchronous sends generally receive privileged
- * treatment.  The intent is that they be used sparingly, for such
- * purposes as kernel printf's (the "ducons" routines).  Run-of-the-mill
- * console output and L1 requests should NOT use a non-zero value
- * for wait.
- */
-int
-sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait )
-{
-    char type_and_subch;
-    int result;
-
-    if( (ch < 0) || ( ch >= BRL1_NUM_SUBCHANS) ) {
-        return SC_BADSUBCH;
-    }
-
-    /* Verify that this is an open subchannel
-     */
-    if( sc->subch[ch].use == BRL1_SUBCH_FREE ) {
-        return SC_NOPEN;
-    }
-
-    type_and_subch = (BRL1_REQUEST | ((u_char)ch));
-    result = brl1_send( sc, msg, len, type_and_subch, wait );
-
-    /* If we sent as much as we asked to, return "ok". */
-    if( result == len )
-	return( SC_SUCCESS );
-
-    /* Or, if we sent less, than either the UART is busy or
-     * we're trying to send too large a packet anyway.
-     */
-    else if( result >= 0 && result < len )
-	return( SC_BUSY );
-
-    /* Or, if something else went wrong (result < 0), then
-     * return that error value.
-     */
-    else
-	return( result );
-}
-
-/* subch_pull_msg pulls a message off the receive queue for subch
- * and places it the buffer pointed to by msg.  This routine should only
- * be called when the caller already knows a message is available on the
- * receive queue (and, in the kernel, only when the subchannel data lock
- * is held by the caller).
- */
-static void
-subch_pull_msg( brl1_sch_t *subch, char *msg, int *len )
-{
-    sc_cq_t *q;         /* receive queue */
-    int before_wrap,    /* packet may be split into two different       */
-        after_wrap;     /*   pieces to acommodate queue wraparound      */
-
-    /* pull message off the receive queue */
-    q = subch->iqp;
-
-    cq_rem( q, *len );   /* remove length byte and store */
-    cq_discard( q );     /* remove type/subch byte and discard */
-
-    if ( *len > 0 )
-	(*len)--;        /* don't count type/subch byte in length returned */
-
-    if( (q->opos + (*len)) > BRL1_QSIZE ) {
-        before_wrap = BRL1_QSIZE - q->opos;
-        after_wrap = (*len) - before_wrap;
-    }
-    else {
-        before_wrap = (*len);
-        after_wrap = 0;
-    }
-
-    BCOPY( q->buf + q->opos, msg, before_wrap  );
-    if( after_wrap ) {
-        BCOPY( q->buf, msg + before_wrap, after_wrap  );
-	q->opos = after_wrap;
-    }
-    else {
-	q->opos = ((q->opos + before_wrap) & (BRL1_QSIZE - 1));
-    }
-    atomic_dec(&(subch->packet_arrived));
-}
-
-
-/* sc_recv_poll can be called as a blocking or non-blocking function;
- * it attempts to pull a message off of the subchannel specified
- * in the argument list (ch).
- *
- * The "block" argument, if non-zero, is interpreted as a timeout
- * delay (to avoid permanent waiting).
- */
-
-int
-sc_recv_poll( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
-{
-    int is_msg = 0;
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    rtc_time_t exp_time = rtc_time() + block;
-
-    /* sanity check-- make sure this is an open subchannel */
-    if( subch->use == BRL1_SUBCH_FREE )
-	return( SC_NOPEN );
-
-    do {
-
-        /* kick the next lower layer and see if it pulls anything in
-         */
-	brl1_receive( sc, SERIAL_POLLED_MODE );
-	is_msg = atomic_read(&subch->packet_arrived);
-
-    } while( block && !is_msg && (rtc_time() < exp_time) );
-
-    if( !is_msg ) {
-	/* no message and we didn't care to wait for one */
-	return( SC_NMSG );
-    }
-
-    SUBCH_DATA_LOCK( subch, pl );
-    subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( SC_SUCCESS );
-}
-    
-
-/* Like sc_recv_poll, sc_recv_intr can be called in either a blocking
- * or non-blocking mode.  Rather than polling until an appointed timeout,
- * however, sc_recv_intr sleeps on a syncrhonization variable until a
- * signal from the lower layer tells us that a packet has arrived.
- *
- * sc_recv_intr can't be used with remote (router) L1s.
- */
-int
-sc_recv_intr( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
-{
-    int is_msg = 0;
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    do {
-	SUBCH_DATA_LOCK(subch, pl);
-	is_msg = atomic_read(&subch->packet_arrived);
-	if( !is_msg && block ) {
-	    /* wake me when you've got something */
-	    subch->rx_notify = sc_data_ready;
-	    sv_wait( &(subch->arrive_sv), 0, 0);
-	    if( subch->use == BRL1_SUBCH_FREE ) {
-		/* oops-- somebody closed our subchannel while we were
-		 * sleeping!
-		 */
-
-		/* no need to unlock since the channel's closed anyhow */
-		return( SC_NOPEN );
-	    }
-	}
-    } while( !is_msg && block );
-
-    if( !is_msg ) {
-	/* no message and we didn't care to wait for one */
-	SUBCH_DATA_UNLOCK( subch, pl );
-	return( SC_NMSG );
-    }
-
-    subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( SC_SUCCESS );
-}
-
-/* sc_command implements a (blocking) combination of sc_send and sc_recv.
- * It is intended to be the SN1 equivalent of SN0's "elsc_command", which
- * issued a system controller command and then waited for a response from
- * the system controller before returning.
- *
- * cmd points to the outgoing command; resp points to the buffer in
- * which the response is to be stored.  Both buffers are assumed to
- * be the same length; if there is any doubt as to whether the
- * response buffer is long enough to hold the L1's response, then
- * make it BRL1_QSIZE bytes-- no Bedrock<->L1 message can be any
- * bigger.
- *
- * Be careful using the same buffer for both cmd and resp; it could get
- * hairy if there were ever an L1 command reqeuest that spanned multiple
- * packets.  (On the other hand, that would require some additional
- * rewriting of the L1 command interface anyway.)
- */
-#define __RETRIES	50
-#define __WAIT_SEND	1	// ( sc->uart != BRL1_LOCALHUB_UART )
-#define __WAIT_RECV	10000000
-
-
-int
-sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
-{
-    int result;
-    int retries;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-    	return SC_NMSG;
-
-    retries = __RETRIES;
-
-    while( (result = sc_send( sc, ch, cmd, *len, __WAIT_SEND )) < 0 ) {
-	if( result == SC_BUSY ) {
-	    retries--;
-	    if( retries <= 0 )
-		return result;
-	    uart_delay(500);
-	}
-	else {
-	    return result;
-	}
-    }
-    
-    /* block on sc_recv_* */
-    if( (sc->uart == BRL1_LOCALHUB_UART) && L1_interrupts_connected ) {
-	return( sc_recv_intr( sc, ch, resp, len, __WAIT_RECV ) );
-    }
-    else {
-	return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
-    }
-}
-
-/* sc_command_kern is a knuckle-dragging, no-patience version of sc_command
- * used in situations where the kernel has a command that shouldn't be
- * delayed until the send buffer clears.  sc_command should be used instead
- * under most circumstances.
- */
-
-int
-sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
-{
-    int result;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-    	return SC_NMSG;
-
-    if( (result = sc_send( sc, ch, cmd, *len, 1 )) < 0 ) {
-	return result;
-    }
-
-    return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
-}
-
-
-
-/* sc_poll checks the queue corresponding to the given
- * subchannel to see if there's anything available.  If
- * not, it kicks the brl1 layer and then checks again.
- *
- * Returns 1 if input is available on the given queue,
- * 0 otherwise.
- */
-
-int
-sc_poll( l1sc_t *sc, int ch )
-{
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    if( atomic_read(&subch->packet_arrived) )
-	return 1;
-
-    brl1_receive( sc, SERIAL_POLLED_MODE );
-
-    if( atomic_read(&subch->packet_arrived) )
-	return 1;
-
-    return 0;
-}
-
-/* for now, sc_init just calls brl1_init */
-
-void
-sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    if ( !IS_RUNNING_ON_SIMULATOR() )
-    	brl1_init( sc, nasid, uart );
-}
-
-/* sc_dispatch_env_event handles events sent from the system control
- * network's environmental monitor tasks.
- */
-
-#if	defined(LINUX_KERNEL_THREADS)
-
-static void
-sc_dispatch_env_event( uint code, int argc, char *args, int maxlen )
-{
-    int j, i = 0;
-    uint32_t ESPcode;
-
-    switch( code ) {
-	/* for now, all codes do the same thing: grab two arguments
-	 * and print a cmn_err_tag message */
-      default:
-	/* check number of arguments */
-	if( argc != 2 ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected 2 arguments, got %d\n", argc ));
-	    return;
-	}
-	
-	/* get ESP code (integer argument) */
-	if( args[i++] != L1_ARG_INT ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected integer argument\n" ));
-	    return;
-	}
-	/* WARNING: highly endian */
-	COPY_BUFFER_TO_INT(args, i, ESPcode);
-
-	/* verify string argument */
-	if( args[i++] != L1_ARG_ASCII ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected an ASCII string\n" ));
-	    return;
-	}
-	for( j = i; j < maxlen; j++ ) {
-	    if( args[j] == '\0' ) break; /* found string termination */
-	}
-	if( j == maxlen ) {
-	    j--;
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "message too long-- truncating\n" ));
-	}
-
-	/* strip out trailing cr/lf */
-	for( ; 
-	     j > 1 && ((args[j-1] == 0xd) || (args[j-1] == 0xa)); 
-	     j-- );
-	args[j] = '\0';
-	
-	/* strip out leading cr/lf */
-	for( ;
-	     i < j && ((args[i] == 0xd) || (args[i] == 0xa));
-	     i++ );
-    }
-}
-
-
-/* sc_event waits for events to arrive from the system controller, and
- * prints appropriate messages to the syslog.
- */
-
-static void
-sc_event( l1sc_t *sc, int ch )
-{
-    char event[BRL1_QSIZE];
-    int i;
-    int result;
-    int event_len;
-    uint32_t ev_src;
-    uint32_t ev_code;
-    int ev_argc;
-
-    while(1) {
-	
-	bzero( event, BRL1_QSIZE );
-
-	/*
-	 * wait for an event 
-	 */
-	result = sc_recv_intr( sc, ch, event, &event_len, 1 );
-	if( result != SC_SUCCESS ) {
-	    printk(KERN_WARNING  "Error receiving sysctl event on nasid %d\n",
-		     sc->nasid );
-	}
-	else {
-	    /*
-	     * an event arrived; break it down into useful pieces
-	     */
-#if defined(L1_DEBUG) && 0
-	    int ix;
-	    printf( "Event packet received:\n" );
-	    for (ix = 0; ix < 64; ix++) {
-		printf( "%x%x ", ((event[ix] >> 4) & ((uint64_t)0xf)),
-			(event[ix] & ((uint64_t)0xf)) );
-		if( (ix % 16) == 0xf ) printf( "\n" );
-	    }
-#endif /* L1_DEBUG */
-
-	    i = 0;
-
-	    /* get event source */
-	    COPY_BUFFER_TO_INT(event, i, ev_src);
-	    COPY_BUFFER_TO_INT(event, i, ev_code);
-
-	    /* get arg count */
-	    ev_argc = (event[i++] & 0xffUL);
-	    
-	    /* dispatch events by task */
-	    switch( (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT )
-	    {
-	      case L1_ADDR_TASK_ENV: /* environmental monitor event */
-		sc_dispatch_env_event( ev_code, ev_argc, &(event[i]), 
-				       BRL1_QSIZE - i );
-		break;
-
-	      default: /* unhandled task type */
-		L1_DBG_PRF(( "Unhandled event type received from system "
-			     "controllers: source task %x\n",
-			     (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT
-			   ));
-	    }
-	}
-	
-    }			
-}
-
-/* sc_listen sets up a service thread to listen for incoming events.
- */
-
-void
-sc_listen( l1sc_t *sc )
-{
-    int result;
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    char        msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         ch;     /* system controller subchannel used */
-
-    extern int msc_shutdown_pri;
-
-    /* grab the designated "event subchannel" */
-    SUBCH_LOCK( sc, pl );
-    subch = &(sc->subch[BRL1_EVENT_SUBCH]);
-    if( subch->use != BRL1_SUBCH_FREE ) {
-	SUBCH_UNLOCK( sc, pl );
-	printk(KERN_WARNING  "sysctl event subchannel in use! "
-		 "Not monitoring sysctl events.\n" );
-	return;
-    }
-    subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->target = BRL1_LOCALHUB_UART;
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
-    subch->tx_notify = NULL;
-    subch->rx_notify = sc_data_ready;
-    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
-				   NASID_TO_COMPACT_NODEID(sc->nasid) );
-    ASSERT( subch->iqp );
-    cq_init( subch->iqp );
-
-    /* set up a thread to listen for events */
-    sthread_create( "sysctl event handler", 0, 0, 0, msc_shutdown_pri,
-		    KT_PS, (st_func_t *) sc_event,
-		    (void *)sc, (void *)(uint64_t)BRL1_EVENT_SUBCH, 0, 0 );
-
-    /* signal the L1 to begin sending events */
-    bzero( msg, BRL1_QSIZE );
-    ch = sc_open( sc, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( sc, ch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_EVENT_SUBCH, 2,
-				 L1_ARG_INT, BRL1_EVENT_SUBCH )) < 0 )
-    {
-	sc_close( sc, ch );
-	L1_DBG_PRF(( "Failure in sc_construct_msg (%d)\n", len ));
-	goto err_return;
-    }
-
-    result = sc_command_kern( sc, ch, msg, msg, &len );
-    if( result < 0 )
-    {
-	sc_close( sc, ch );
-	L1_DBG_PRF(( "Failure in sc_command_kern (%d)\n", result ));
-	goto err_return;
-    }
-
-    sc_close( sc, ch );
-
-    result = sc_interpret_resp( msg, 0 );
-    if( result < 0 )
-    {
-	L1_DBG_PRF(( "Failure in sc_interpret_resp (%d)\n", result ));
-	goto err_return;
-    }
-
-    /* everything went fine; just return */
-    return;
-	
-err_return:
-    /* there was a problem; complain */
-    printk(KERN_WARNING  "failed to set sysctl event-monitoring subchannel.  "
-	     "Sysctl events will not be monitored.\n" );
-}
-
-#endif	/* LINUX_KERNEL_THREADS */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/l1_command.c linux-2.4.22-pre3/arch/ia64/sn/io/l1_command.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/l1_command.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/l1_command.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1378 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 - 2001 Silicon Graphics, Inc.
- * All rights reserved.
- */ 
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-
-#define ELSC_TIMEOUT	1000000		/* ELSC response timeout (usec) */
-#define LOCK_TIMEOUT	5000000		/* Hub lock timeout (usec) */
-
-#define LD(x)		(*(volatile uint64_t *)(x))
-#define SD(x, v)	(LD(x) = (uint64_t) (v))
-
-#define hub_cpu_get()	0
-
-#define LBYTE(caddr)	(*(char *) caddr)
-
-extern char *bcopy(const char * src, char * dest, int count);
-
-#define LDEBUG		0
-
-/*
- * ELSC data is in NVRAM page 7 at the following offsets.
- */
-
-#define NVRAM_MAGIC_AD	0x700		/* magic number used for init */
-#define NVRAM_PASS_WD	0x701		/* password (4 bytes in length) */
-#define NVRAM_DBG1	0x705		/* virtual XOR debug switches */
-#define NVRAM_DBG2	0x706		/* physical XOR debug switches */
-#define NVRAM_CFG	0x707		/* ELSC Configuration info */
-#define NVRAM_MODULE	0x708		/* system module number */
-#define NVRAM_BIST_FLG	0x709		/* BIST flags (2 bits per nodeboard) */
-#define NVRAM_PARTITION 0x70a		/* module's partition id */
-#define	NVRAM_DOMAIN	0x70b		/* module's domain id */
-#define	NVRAM_CLUSTER	0x70c		/* module's cluster id */
-#define	NVRAM_CELL	0x70d		/* module's cellid */
-
-#define NVRAM_MAGIC_NO	0x37		/* value of magic number */
-#define NVRAM_SIZE	16		/* 16 bytes in nvram */
-
-/*
- * Declare a static ELSC NVRAM buffer to hold all data read from
- * and written to NVRAM.  This nvram "cache" will be used only during the
- * IP27prom execution.
- */
-static char elsc_nvram_buffer[NVRAM_SIZE];
-
-#define SC_COMMAND sc_command
-
-/*
- * elsc_init
- *
- *   Initialize ELSC structure
- */
-
-void elsc_init(elsc_t *e, nasid_t nasid)
-{
-    sc_init((l1sc_t *)e, nasid, BRL1_LOCALHUB_UART);
-}
-
-
-/*
- * elsc_errmsg
- *
- *   Given a negative error code,
- *   returns a corresponding static error string.
- */
-
-char *elsc_errmsg(int code)
-{
-    switch (code) {
-    case ELSC_ERROR_CMD_SEND:
-	return "Command send error";
-    case ELSC_ERROR_CMD_CHECKSUM:
-	return "Command packet checksum error";
-    case ELSC_ERROR_CMD_UNKNOWN:
-	return "Unknown command";
-    case ELSC_ERROR_CMD_ARGS:
-	return "Invalid command argument(s)";
-    case ELSC_ERROR_CMD_PERM:
-	return "Permission denied";
-    case ELSC_ERROR_RESP_TIMEOUT:
-	return "System controller response timeout";
-    case ELSC_ERROR_RESP_CHECKSUM:
-	return "Response packet checksum error";
-    case ELSC_ERROR_RESP_FORMAT:
-	return "Response format error";
-    case ELSC_ERROR_RESP_DIR:
-	return "Response direction error";
-    case ELSC_ERROR_MSG_LOST:
-	return "Message lost because queue is full";
-    case ELSC_ERROR_LOCK_TIMEOUT:
-	return "Timed out getting ELSC lock";
-    case ELSC_ERROR_DATA_SEND:
-	return "Error sending data";
-    case ELSC_ERROR_NIC:
-	return "NIC protocol error";
-    case ELSC_ERROR_NVMAGIC:
-	return "Bad magic number in NVRAM";
-    case ELSC_ERROR_MODULE:
-	return "Module location protocol error";
-    default:
-	return "Unknown error";
-    }
-}
-
-/*
- * elsc_nvram_init
- *
- *   Initializes reads and writes to NVRAM.  This will perform a single
- *   read to NVRAM, getting all data at once.  When the PROM tries to
- *   read NVRAM, it returns the data from the buffer being read.  If the
- *   PROM tries to write out to NVRAM, the write is done, and the internal
- *   buffer is updated.
- */
-
-void elsc_nvram_init(nasid_t nasid, uchar_t *elsc_nvram_data)
-{
-    /* This might require implementation of multiple-packet request/responses
-     * if it's to provide the same behavior that was available in SN0.
-     */
-    nasid = nasid;
-    elsc_nvram_data = elsc_nvram_data;
-}
-
-/*
- * elsc_nvram_copy
- *
- *   Copies the content of a buffer into the static buffer in this library.
- */
-
-void elsc_nvram_copy(uchar_t *elsc_nvram_data)
-{
-    memcpy(elsc_nvram_buffer, elsc_nvram_data, NVRAM_SIZE);
-}
-
-/*
- * elsc_nvram_write
- *
- *   Copies bytes from 'buf' into NVRAM, starting at NVRAM address
- *   'addr' which must be between 0 and 2047.
- *
- *   If 'len' is non-negative, the routine copies 'len' bytes.
- *
- *   If 'len' is negative, the routine treats the data as a string and
- *   copies bytes up to and including a NUL-terminating zero, but not
- *   to exceed '-len' bytes.
- */
-
-int elsc_nvram_write(elsc_t *e, int addr, char *buf, int len)
-{
-    /* Here again, we might need to work out the details of a
-     * multiple-packet protocol.
-     */
-
-    /* For now, pretend it worked. */
-    e = e;
-    addr = addr;
-    buf = buf;
-    return (len < 0 ? -len : len);
-}
-
-/*
- * elsc_nvram_read
- *
- *   Copies bytes from NVRAM into 'buf', starting at NVRAM address
- *   'addr' which must be between 0 and 2047.
- *
- *   If 'len' is non-negative, the routine copies 'len' bytes.
- *
- *   If 'len' is negative, the routine treats the data as a string and
- *   copies bytes up to and including a NUL-terminating zero, but not
- *   to exceed '-len' bytes.  NOTE:  This method is no longer supported.
- *   It was never used in the first place.
- */
-
-int elsc_nvram_read(elsc_t *e, int addr, char *buf, int len)
-{
-    /* multiple packets? */
-    e = e;
-    addr = addr;
-    buf = buf;
-    len = len;
-    return -1;
-}
-
-
-/*
- * Command Set
- */
-
-int elsc_version(elsc_t *e, char *result)
-{
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-    int		major,  /* major rev number */
-	        minor,  /* minor rev number */
-                bugfix; /* bugfix rev number */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_FW_REV, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major,
-			   L1_ARG_INT, &minor, L1_ARG_INT, &bugfix )
-	< 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    sprintf( result, "%d.%d.%d", major, minor, bugfix );
-
-    return 0;
-}
-
-int elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2)
-{
-    /* shush compiler */
-    e = e;
-    byte1 = byte1;
-    byte2 = byte2;
-
-    /* fill in a buffer with the opcode & params; call sc_command */
-
-    return 0;
-}
-
-int elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		dbg_sw; /* holds debug switch settings */
-    int		len;	/* number of msg buffer bytes used */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RDBG, 0 ) ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &dbg_sw ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* copy out debug switch settings (last two bytes of the
-     * integer response)
-     */
-    *byte1 = ((dbg_sw >> 8) & 0xFF);
-    *byte2 = (dbg_sw & 0xFF);
-
-    return 0;
-}
-
-
-/*
- * elsc_rack_bay_get fills in the two int * arguments with the
- * rack number and bay number of the L1 being addressed
- */
-int elsc_rack_bay_get(elsc_t *e, uint *rack, uint *bay)
-{
-    char msg[BRL1_QSIZE];	/* L1 request/response info */
-    int subch;			/* system controller subchannel used */
-    int len;			/* length of message */
-    uint32_t	buf32;		/* used to copy 32-bit rack/bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRACK, 0 )) < 0 ) 
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-
-    /* send the request to the L1 */
-    if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close(e, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &buf32 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    return 0;
-}
-
-
-/* elsc_rack_bay_type_get fills in the three int * arguments with the
- * rack number, bay number and brick type of the L1 being addressed.  Note
- * that if the L1 operation fails and this function returns an error value, 
- * garbage may be written to brick_type.
- */
-int elsc_rack_bay_type_get( l1sc_t *sc, uint *rack, 
-			       uint *bay, uint *brick_type )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t buf32;	        /* used to copy 32-bit rack & bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRBT, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, 
-			           L1_ARG_INT, brick_type ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    /* convert brick_type to lower case */
-    *brick_type = *brick_type - 'A' + 'a';
-
-    return 0;
-}
-
-
-int elsc_module_get(elsc_t *e)
-{
-    extern char brick_types[];
-    uint rnum, rack, bay, bricktype, t;
-    int ret;
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = elsc_rack_bay_type_get(e, &rnum, &bay, &bricktype)) < 0) {
-	return ret;
-    }
-
-    /* report unset location info. with a special, otherwise invalid modid */
-    if (rnum == 0 && bay == 0)
-	return MODULE_NOT_SET;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-	return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;		
-    t = rnum / 100;		/* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;		/* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;		/* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    for( t = 0; t < MAX_BRICK_TYPES; t++ ) {
-	if( brick_types[t] == bricktype )
-	    return RBT_TO_MODULE(rack, bay, t);
-    }
-    
-    return ELSC_ERROR_MODULE;
-}
-
-int elsc_partition_set(elsc_t *e, int partition)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PARTITION_SET, 2,
-				 L1_ARG_INT, partition )) < 0 )
-    {
-	
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-    
-    return( 0 );
-}
-
-int elsc_partition_get(elsc_t *e)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t partition_id;    /* used to copy partition id out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PARTITION_GET, 0 )) < 0 )
-
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &partition_id ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-    
-    return( partition_id );
-}
-
-
-/*
- * elsc_cons_subch selects the "active" console subchannel for this node
- * (i.e., the one that will currently receive input)
- */
-int elsc_cons_subch(elsc_t *e, uint ch)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( e, L1_ADDR_LOCAL );
-    
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_CONS_SUBCH, 2,
-				 L1_ARG_INT, ch)) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-/*
- * elsc_cons_node should only be executed by one node.  It declares to
- * the system controller that the node from which it is called will be
- * the owner of the system console.
- */
-int elsc_cons_node(elsc_t *e)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( e, L1_ADDR_LOCAL );
-    
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_CONS_NODE, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-    
-
-/* elsc_display_line writes up to 12 characters to either the top or bottom
- * line of the L1 display.  line points to a buffer containing the message
- * to be displayed.  The zero-based line number is specified by lnum (so
- * lnum == 0 specifies the top line and lnum == 1 specifies the bottom).
- * Lines longer than 12 characters, or line numbers not less than
- * L1_DISPLAY_LINES, cause elsc_display_line to return an error.
- */
-int elsc_display_line(elsc_t *e, char *line, int lnum)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		len;	/* number of msg buffer bytes used */
-
-    /* argument sanity checking */
-    if( !(lnum < L1_DISPLAY_LINES) )
-	return( ELSC_ERROR_CMD_ARGS );
-    if( !(strlen( line ) <= L1_DISPLAY_LINE_LENGTH) )
-	return( ELSC_ERROR_CMD_ARGS );
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 (L1_REQ_DISP1+lnum), 2,
-				 L1_ARG_ASCII, line )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-/* elsc_display_mesg silently drops message characters beyond the 12th.
- */
-int elsc_display_mesg(elsc_t *e, char *chr)
-{
-
-    char line[L1_DISPLAY_LINE_LENGTH+1];
-    int numlines, i;
-    int result;
-
-    numlines = (strlen( chr ) + L1_DISPLAY_LINE_LENGTH - 1) /
-	L1_DISPLAY_LINE_LENGTH;
-
-    if( numlines > L1_DISPLAY_LINES )
-	numlines = L1_DISPLAY_LINES;
-
-    for( i = 0; i < numlines; i++ )
-    {
-	strncpy( line, chr, L1_DISPLAY_LINE_LENGTH );
-	line[L1_DISPLAY_LINE_LENGTH] = '\0';
-
-	/* generally we want to leave the first line of the L1 display
-	 * alone (so the L1 can manipulate it).  If you need to be able
-	 * to display to both lines (for debugging purposes), define
-	 * L1_DISP_2LINES in irix/kern/ksys/l1.h, or add -DL1_DISP_2LINES
-	 * to your 'defs file.
-	 */
-#if defined(L1_DISP_2LINES)
-	if( (result = elsc_display_line( e, line, i )) < 0 )
-#else
-	if( (result = elsc_display_line( e, line, i+1 )) < 0 )
-#endif
-
-	    return result;
-
-	chr += L1_DISPLAY_LINE_LENGTH;
-    }
-    
-    return 0;
-}
-
-
-int elsc_password_set(elsc_t *e, char *password)
-{
-    /* shush compiler */
-    e = e;
-    password = password;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-int elsc_password_get(elsc_t *e, char *password)
-{
-    /* shush compiler */
-    e = e;
-    password = password;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-/*
- * sc_portspeed_get
- *
- * retrieve the current portspeed setting for the bedrock II
- */
-int sc_portspeed_get(l1sc_t *sc)
-{
-    char	msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         subch;  /* system controller subchannel used */
-    int		portspeed_a, portspeed_b;
-			/* ioport clock rates */
-
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-                                 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PORTSPEED,
-				 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-    
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) < 0 )
-    {
-        sc_close( sc, subch );
-        return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, 
-			   L1_ARG_INT, &portspeed_a,
-			   L1_ARG_INT, &portspeed_b ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* for the c-brick, we ignore the portspeed_b value */
-    return (portspeed_a ? 600 : 400);
-}
-
-/*
- * elsc_power_query
- *
- *   To be used after system reset, this command returns 1 if the reset
- *   was the result of a power-on, 0 otherwise.
- *
- *   The power query status is cleared to 0 after it is read.
- */
-
-int elsc_power_query(elsc_t *e)
-{
-    e = e; /* shush the compiler */
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 1;
-}
-
-int elsc_rpwr_query(elsc_t *e, int is_master)
-{
-    /* shush the compiler */
-    e = e;
-    is_master = is_master;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-} 
-
-/*
- * elsc_power_down
- *
- *   Sets up system to shut down in "sec" seconds (or modifies the
- *   shutdown time if one is already in effect).  Use 0 to power
- *   down immediately.
- */
-
-int elsc_power_down(elsc_t *e, int sec)
-{
-    /* shush compiler */
-    e = e;
-    sec = sec;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-int elsc_system_reset(elsc_t *e)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		len;	/* number of msg buffer bytes used */
-    int		result;
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RESET, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( (result = sc_command( e, subch, msg, msg, &len )) ) {
-	sc_close( e, subch );
-	if( result == SC_NMSG ) {
-	    /* timeout is OK.  We've sent the reset.  Now it's just
-	     * a matter of time...
-	     */
-	    return( 0 );
-	}
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-int elsc_power_cycle(elsc_t *e)
-{
-    /* shush compiler */
-    e = e;
-
-    /* fill in buffer with the opcode & params; call sc_command */
-
-    return 0;
-}
-
-
-/*
- * L1 Support for reading 
- * cbrick uid.
- */
-
-int elsc_nic_get(elsc_t *e, uint64_t *nic, int verbose)
-{
-    /* this parameter included only for SN0 compatibility */
-    verbose = verbose;
-
-    /* We don't go straight to the bedrock/L1 protocol on this one, but let
-     * the eeprom layer prepare the eeprom data as we would like it to
-     * appear to the caller
-     */
-    return cbrick_uid_get( e->nasid, nic );
-}
-
-
-int _elsc_hbt(elsc_t *e, int ival, int rdly)
-{
-    e = e;
-    ival = ival;
-    rdly = rdly;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-/* send a command string to an L1 */
-int sc_command_interp( l1sc_t *sc, l1addr_t compt, l1addr_t rack, l1addr_t bay,
-		       char *cmd )
-{
-    char        msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         subch;  /* system controller subchannel used */
-    l1addr_t	target; /* target system controller for command */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-
-    L1_BUILD_ADDR( &target, compt, rack, bay, 0 );
-    subch = sc_open( sc, target );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_CMD, L1_REQ_EXEC_CMD, 2,
-				 L1_ARG_ASCII, cmd )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-		   
-    /* send the request to the L1 */
-    if( SC_COMMAND( sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-    
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-/*
- * sc_power_down
- *
- * Shuts down the c-brick associated with sc, and any attached I/O bricks
- * or other c-bricks (won't go through r-bricks).
- */
-
-int sc_power_down(l1sc_t *sc)
-{
-    return sc_command_interp( sc, L1_ADDR_TYPE_L1, L1_ADDR_RACK_LOCAL, 
-			      L1_ADDR_BAY_LOCAL, "* pwr d" );
-}
-
-
-/*
- * sc_power_down_all
- *
- * Works similarly to sc_power_down, except that the request is sent to the
- * closest L2 and EVERYBODY gets turned off.
- */
-
-int sc_power_down_all(l1sc_t *sc)
-{
-    if( nodepda->num_routers > 0 ) {
-	return sc_command_interp( sc, L1_ADDR_TYPE_L2, L1_ADDR_RACK_LOCAL, 
-				  L1_ADDR_BAY_LOCAL, "* pwr d" );
-    }
-    else {
-	return sc_power_down( sc );
-    }
-}
-
-
-/*
- * Routines for reading the R-brick's L1
- */
-
-int router_module_get( nasid_t nasid, net_vec_t path )
-{
-    uint rnum, rack, bay, t;
-    int ret;
-    l1sc_t sc;
-
-    /* prepare l1sc_t struct */
-    sc_init( &sc, nasid, path );
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = elsc_rack_bay_get(&sc, &rnum, &bay)) < 0)
-	return ret;
-
-    /* report unset location info. with a special, otherwise invalid modid */
-    if (rnum == 0 && bay == 0)
-	return MODULE_NOT_SET;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-	return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;		
-    t = rnum / 100;		/* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;		/* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;		/* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    ret = RBT_TO_MODULE(rack, bay, MODULE_RBRICK);
-    return ret;
-}
-    
-
-/*
- * iobrick routines
- */
-
-/* iobrick_rack_bay_type_get fills in the three int * arguments with the
- * rack number, bay number and brick type of the L1 being addressed.  Note
- * that if the L1 operation fails and this function returns an error value, 
- * garbage may be written to brick_type.
- */
-int iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack, 
-			       uint *bay, uint *brick_type )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t buf32;	        /* used to copy 32-bit rack & bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRBT, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, 
-			           L1_ARG_INT, brick_type ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    return 0;
-}
-
-
-int iobrick_module_get(l1sc_t *sc)
-{
-    uint rnum, rack, bay, brick_type, t;
-    int ret;
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = iobrick_rack_bay_type_get(sc, &rnum, &bay, &brick_type)) < 0)
-        return ret;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-        return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;           
-    t = rnum / 100;             /* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;              /* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;              /* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    switch( brick_type ) {
-      case 'I': 
-	brick_type = MODULE_IBRICK; break;
-      case 'P':
-	brick_type = MODULE_PBRICK; break;
-      case 'X':
-	brick_type = MODULE_XBRICK; break;
-    }
-
-    ret = RBT_TO_MODULE(rack, bay, brick_type);
-
-    return ret;
-}
-
-/* iobrick_get_sys_snum asks the attached iobrick for the system
- * serial number.  This function will only be relevant to the master
- * cbrick (the one attached to the bootmaster ibrick); other nodes
- * may call the function, but the value returned to the master node
- * will be the one used as the system serial number by the kernel.
- */
-
-int
-iobrick_get_sys_snum( l1sc_t *sc, char *snum_str )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SYS_SERIAL, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    return( sc_interpret_resp( msg, 2, L1_ARG_ASCII, snum_str ) );
-}
-
-
-/*
- * The following functions apply (or cut off) power to the specified
- * pci bus or slot.
- */
-
-int
-iobrick_pci_pwr( l1sc_t *sc, int bus, int slot, int req_code )
-{
-#if 0 /* The "bedrock request" method of performing this function
-       * seems to be broken in the L1, so for now use the command-
-       * interpreter method
-       */
-
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCALIO );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 req_code, 4,
-				 L1_ARG_INT, bus,
-				 L1_ARG_INT, slot )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-
-#else
-    char cmd[64];
-    char *fxn;
-
-    switch( req_code )
-    {
-    case L1_REQ_PCI_UP:
-	fxn = "u";
-	break;
-    case L1_REQ_PCI_DOWN:
-	fxn = "d";
-	break;
-    case L1_REQ_PCI_RESET:
-	fxn = "rst";
-	break;
-    default:
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    if( slot == -1 ) 
-	sprintf( cmd, "pci %d %s", bus, fxn );
-    else
-        sprintf( cmd, "pci %d %d %s", bus, slot, fxn );
-	
-    return sc_command_interp( sc, L1_ADDR_TYPE_IOBRICK,
-	L1_ADDR_RACK_LOCAL, L1_ADDR_BAY_LOCAL, cmd );
-#endif
-}
-				 
-int
-iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up )
-{
-    return iobrick_pci_pwr( sc, bus, slot, up );
-}
-
-int
-iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up )
-{
-    return iobrick_pci_pwr( sc, bus, -1, up );
-}
-
-
-int
-iobrick_pci_slot_rst( l1sc_t *sc, int bus, int slot )
-{
-    return iobrick_pci_pwr( sc, bus, slot, L1_REQ_PCI_RESET );
-}
-
-int
-iobrick_pci_bus_rst( l1sc_t *sc, int bus )
-{
-    return iobrick_pci_pwr( sc, bus, -1, L1_REQ_PCI_RESET );
-}
-
-
-/* get the L1 firmware version for an iobrick */
-int
-iobrick_sc_version( l1sc_t *sc, char *result )
-{
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-    int		major,  /* major rev number */
-	        minor,  /* minor rev number */
-                bugfix; /* bugfix rev number */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCALIO );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_FW_REV, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major,
-			   L1_ARG_INT, &minor, L1_ARG_INT, &bugfix )
-	< 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    sprintf( result, "%d.%d.%d", major, minor, bugfix );
-
-    return 0;
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/labelcl.c linux-2.4.22-pre3/arch/ia64/sn/io/labelcl.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/labelcl.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/labelcl.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,654 +0,0 @@
-/*  labelcl - SGI's Hwgraph Compatibility Layer.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
-*/
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-/*
-** Very simple and dumb string table that supports only find/insert.
-** In practice, if this table gets too large, we may need a more
-** efficient data structure.   Also note that currently there is no 
-** way to delete an item once it's added.  Therefore, name collision 
-** will return an error.
-*/
-
-struct string_table label_string_table;
-
-
-
-/*
- * string_table_init - Initialize the given string table.
- */
-void
-string_table_init(struct string_table *string_table)
-{
-	string_table->string_table_head = NULL;
-	string_table->string_table_generation = 0;
-
-	/*
-	 * We nedd to initialize locks here!
-	 */
-
-	return;
-}
-
-
-/*
- * string_table_destroy - Destroy the given string table.
- */
-void
-string_table_destroy(struct string_table *string_table)
-{
-	struct string_table_item *item, *next_item;
-
-	item = string_table->string_table_head;
-	while (item) {
-		next_item = item->next;
-
-		STRTBL_FREE(item);
-		item = next_item;
-	}
-
-	/*
-	 * We need to destroy whatever lock we have here
-	 */
-
-	return;
-}
-
-
-
-/*
- * string_table_insert - Insert an entry in the string table .. duplicate 
- *	names are not allowed.
- */
-char *
-string_table_insert(struct string_table *string_table, char *name)
-{
-	struct string_table_item *item, *new_item = NULL, *last_item = NULL;
-
-again:
-	/*
-	 * Need to lock the table ..
-	 */
-	item = string_table->string_table_head;
-	last_item = NULL;
-
-	while (item) {
-		if (!strcmp(item->string, name)) {
-			/*
-			 * If we allocated space for the string and the found that
-			 * someone else already entered it into the string table,
-			 * free the space we just allocated.
-			 */
-			if (new_item)
-				STRTBL_FREE(new_item);
-
-
-			/*
-			 * Search optimization: move the found item to the head
-			 * of the list.
-			 */
-			if (last_item != NULL) {
-				last_item->next = item->next;
-				item->next = string_table->string_table_head;
-				string_table->string_table_head = item;
-			}
-			goto out;
-		}
-		last_item = item;
-		item=item->next;
-	}
-
-	/*
-	 * name was not found, so add it to the string table.
-	 */
-	if (new_item == NULL) {
-		long old_generation = string_table->string_table_generation;
-
-		new_item = STRTBL_ALLOC(strlen(name));
-
-		strcpy(new_item->string, name);
-
-		/*
-		 * While we allocated memory for the new string, someone else 
-		 * changed the string table.
-		 */
-		if (old_generation != string_table->string_table_generation) {
-			goto again;
-		}
-	} else {
-		/* At this we only have the string table lock in access mode.
-		 * Promote the access lock to an update lock for the string
-		 * table insertion below.
-		 */
-			long old_generation = 
-				string_table->string_table_generation;
-
-			/*
-			 * After we did the unlock and wer waiting for update
-			 * lock someone could have potentially updated
-			 * the string table. Check the generation number
-			 * for this case. If it is the case we have to
-			 * try all over again.
-			 */
-			if (old_generation != 
-			    string_table->string_table_generation) {
-				goto again;
-			}
-		}
-
-	/*
-	 * At this point, we're committed to adding new_item to the string table.
-	 */
-	new_item->next = string_table->string_table_head;
-	item = string_table->string_table_head = new_item;
-	string_table->string_table_generation++;
-
-out:
-	/*
-	 * Need to unlock here.
-	 */
-	return(item->string);
-}
-
-/*
- * labelcl_info_create - Creates the data structure that will hold the
- *	device private information asscoiated with a devfs entry.
- *	The pointer to this structure is what gets stored in the devfs 
- *	(void * info).
- */
-labelcl_info_t *
-labelcl_info_create()
-{
-
-	labelcl_info_t *new = NULL;
-
-	/* Initial allocation does not include any area for labels */
-	if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL )
-		return NULL;
-
-	memset (new, 0, sizeof(labelcl_info_t));
-	new->hwcl_magic = LABELCL_MAGIC;
-	return( new);
-
-}
-
-/*
- * labelcl_info_destroy - Frees the data structure that holds the
- *      device private information asscoiated with a devfs entry.  This 
- *	data structure was created by device_info_create().
- *
- *	The caller is responsible for nulling the (void *info) in the 
- *	corresponding devfs entry.
- */
-int
-labelcl_info_destroy(labelcl_info_t *labelcl_info)
-{
-
-	if (labelcl_info == NULL)
-		return(0);
-
-	/* Free the label list */
-	if (labelcl_info->label_list)
-		kfree(labelcl_info->label_list);
-
-	/* Now free the label info area */
-	labelcl_info->hwcl_magic = 0;
-	kfree(labelcl_info);
-
-	return(0);
-}
-
-/*
- * labelcl_info_add_LBL - Adds a new label entry in the labelcl info 
- *	structure.
- *
- *	Error is returned if we find another label with the same name.
- */
-int
-labelcl_info_add_LBL(devfs_handle_t de,
-			char *info_name,
-			arb_info_desc_t info_desc,
-			arbitrary_info_t info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	int new_label_list_size;
-	label_info_t *old_label_list, *new_label_list = NULL;
-	char *name;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-        labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	if (info_name == NULL)
-		return(-1);
-
-	if (strlen(info_name) >= LABEL_LENGTH_MAX)
-		return(-1);
-
-	name = string_table_insert(&label_string_table, info_name);
-
-	num_labels = labelcl_info->num_labels;
-	new_label_list_size = sizeof(label_info_t) * (num_labels+1);
-
-	/*
-	 * Create a new label info area.
-	 */
-	if (new_label_list_size != 0) {
-		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
-
-		if (new_label_list == NULL)
-			return(-1);
-	}
-
-	/*
-	 * At this point, we are committed to adding the labelled info, 
-	 * if there isn't already information there with the same name.
-	 */
-	old_label_list = labelcl_info->label_list;
-
-	/* 
-	 * Look for matching info name.
-	 */
-	for (i=0; i<num_labels; i++) {
-		if (!strcmp(info_name, old_label_list[i].name)) {
-			/* Not allowed to add duplicate labelled info names. */
-			kfree(new_label_list);
-			printk(KERN_WARNING "labelcl_info_add_LBL: Duplicate label name %s for vertex 0x%p\n", info_name, (void *)de);
-			return(-1);
-		}
-		new_label_list[i] = old_label_list[i]; /* structure copy */
-	}
-
-	new_label_list[num_labels].name = name;
-	new_label_list[num_labels].desc = info_desc;
-	new_label_list[num_labels].info = info;
-
-	labelcl_info->num_labels = num_labels+1;
-	labelcl_info->label_list = new_label_list;
-
-	if (old_label_list != NULL)
-		kfree(old_label_list);
-
-	return(0);
-}
-
-/*
- * labelcl_info_remove_LBL - Remove a label entry.
- */
-int
-labelcl_info_remove_LBL(devfs_handle_t de,
-			 char *info_name,
-			 arb_info_desc_t *info_desc,
-			 arbitrary_info_t *info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	int new_label_list_size;
-	label_info_t *old_label_list, *new_label_list = NULL;
-	arb_info_desc_t label_desc_found;
-	arbitrary_info_t label_info_found;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	num_labels = labelcl_info->num_labels;
-	if (num_labels == 0) {
-		return(-1);
-	}
-
-	/*
-	 * Create a new info area.
-	 */
-	new_label_list_size = sizeof(label_info_t) * (num_labels-1);
-	if (new_label_list_size) {
-		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
-		if (new_label_list == NULL)
-			return(-1);
-	}
-
-	/*
-	 * At this point, we are committed to removing the labelled info, 
-	 * if it still exists.
-	 */
-	old_label_list = labelcl_info->label_list;
-
-	/* 
-	 * Find matching info name.
-	 */
-	for (i=0; i<num_labels; i++) {
-		if (!strcmp(info_name, old_label_list[i].name)) {
-			label_desc_found = old_label_list[i].desc;
-			label_info_found = old_label_list[i].info;
-			goto found;
-		}
-		if (i < num_labels-1) /* avoid walking off the end of the new vertex */
-			new_label_list[i] = old_label_list[i]; /* structure copy */
-	}
-
-	/* The named info doesn't exist. */
-	if (new_label_list)
-		kfree(new_label_list);
-
-	return(-1);
-
-found:
-	/* Finish up rest of labelled info */
-	for (i=i+1; i<num_labels; i++)
-		new_label_list[i-1] = old_label_list[i]; /* structure copy */
-
-	labelcl_info->num_labels = num_labels+1;
-	labelcl_info->label_list = new_label_list;
-
-	kfree(old_label_list);
-
-	if (info != NULL)
-		*info = label_info_found;
-
-	if (info_desc != NULL)
-		*info_desc = label_desc_found;
-
-	return(0);
-}
-
-
-/*
- * labelcl_info_replace_LBL - Replace an existing label entry with the 
- *	given new information.
- *
- *	Label entry must exist.
- */
-int
-labelcl_info_replace_LBL(devfs_handle_t de,
-			char *info_name,
-			arb_info_desc_t info_desc,
-			arbitrary_info_t info,
-			arb_info_desc_t *old_info_desc,
-			arbitrary_info_t *old_info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	label_info_t *label_list;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	num_labels = labelcl_info->num_labels;
-	if (num_labels == 0) {
-		return(-1);
-	}
-
-	if (info_name == NULL)
-		return(-1);
-
-	label_list = labelcl_info->label_list;
-
-	/* 
-	 * Verify that information under info_name already exists.
-	 */
-	for (i=0; i<num_labels; i++)
-		if (!strcmp(info_name, label_list[i].name)) {
-			if (old_info != NULL)
-				*old_info = label_list[i].info;
-
-			if (old_info_desc != NULL)
-				*old_info_desc = label_list[i].desc;
-
-			label_list[i].info = info;
-			label_list[i].desc = info_desc;
-
-			return(0);
-		}
-
-
-	return(-1);
-}
-
-/*
- * labelcl_info_get_LBL - Retrieve and return the information for the 
- *	given label entry.
- */
-int
-labelcl_info_get_LBL(devfs_handle_t de,
-		      char *info_name,
-		      arb_info_desc_t *info_desc,
-		      arbitrary_info_t *info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	label_info_t *label_list;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	num_labels = labelcl_info->num_labels;
-	if (num_labels == 0) {
-		return(-1);
-	}
-
-	label_list = labelcl_info->label_list;
-
-	/* 
-	 * Find information under info_name.
-	 */
-	for (i=0; i<num_labels; i++)
-		if (!strcmp(info_name, label_list[i].name)) {
-			if (info != NULL)
-				*info = label_list[i].info;
-			if (info_desc != NULL)
-				*info_desc = label_list[i].desc;
-
-			return(0);
-		}
-
-	return(-1);
-}
-
-/*
- * labelcl_info_get_next_LBL - returns the next label entry on the list.
- */
-int
-labelcl_info_get_next_LBL(devfs_handle_t de,
-			   char *buffer,
-			   arb_info_desc_t *info_descp,
-			   arbitrary_info_t *infop,
-			   labelcl_info_place_t *placeptr)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	uint which_info;
-	label_info_t *label_list;
-
-	if ((buffer == NULL) && (infop == NULL))
-		return(-1);
-
-	if (placeptr == NULL)
-		return(-1);
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	which_info = *placeptr;
-
-	if (which_info >= labelcl_info->num_labels) {
-		return(-1);
-	}
-
-	label_list = (label_info_t *) labelcl_info->label_list;
-
-	if (buffer != NULL)
-		strcpy(buffer, label_list[which_info].name);
-
-	if (infop)
-		*infop = label_list[which_info].info;
-
-	if (info_descp)
-		*info_descp = label_list[which_info].desc;
-
-	*placeptr = which_info + 1;
-
-	return(0);
-}
-
-
-int
-labelcl_info_replace_IDX(devfs_handle_t de,
-			int index,
-			arbitrary_info_t info,
-			arbitrary_info_t *old_info)
-{
-	arbitrary_info_t *info_list_IDX;
-	labelcl_info_t	*labelcl_info = NULL;
-
-	if (de == NULL) {
-		printk(KERN_ALERT "labelcl: NULL devfs handle given.\n");
-		return(-1);
-	}
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL) {
-		printk(KERN_ALERT "labelcl: Entry does not have info pointer.\n");
-		return(-1);
-	}
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
-		return(-1);
-
-	/*
-	 * Replace information at the appropriate index in this vertex with 
-	 * the new info.
-	 */
-	info_list_IDX = labelcl_info->IDX_list;
-	if (old_info != NULL)
-		*old_info = info_list_IDX[index];
-	info_list_IDX[index] = info;
-
-	return(0);
-
-}
-
-/*
- * labelcl_info_connectpt_set - Sets the connectpt.
- */
-int
-labelcl_info_connectpt_set(struct devfs_entry *de,
-			  struct devfs_entry *connect_de)
-{
-	arbitrary_info_t old_info;
-	int	rv;
-
-	rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, 
-		(arbitrary_info_t) connect_de, &old_info);
-
-	if (rv) {
-		return(rv);
-	}
-
-	return(0);
-}
-
-
-/*
- * labelcl_info_get_IDX - Returns the information pointed at by index.
- *
- */
-int
-labelcl_info_get_IDX(devfs_handle_t de,
-			int index,
-			arbitrary_info_t *info)
-{
-	arbitrary_info_t *info_list_IDX;
-	labelcl_info_t	*labelcl_info = NULL;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
-		return(-1);
-
-	/*
-	 * Return information at the appropriate index in this vertex.
-	 */
-	info_list_IDX = labelcl_info->IDX_list;
-	if (info != NULL)
-		*info = info_list_IDX[index];
-
-	return(0);
-}
-
-/*
- * labelcl_info_connectpt_get - Retrieve the connect point for a device entry.
- */
-struct devfs_entry *
-labelcl_info_connectpt_get(struct devfs_entry *de)
-{
-	int rv;
-	arbitrary_info_t info;
-
-	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
-	if (rv)
-		return(NULL);
-
-	return((struct devfs_entry *)info);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/machvec/Makefile linux-2.4.22-pre3/arch/ia64/sn/io/machvec/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/io/machvec/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/machvec/Makefile	2003-07-05 18:09:41.000000000 -0700
@@ -0,0 +1,18 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+O_TARGET := snio.o
+
+export-objs := pci_dma.o iomv.o
+
+obj-y				+= pci.o pci_dma.o pci_bus_cvlink.o iomv.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/machvec/iomv.c linux-2.4.22-pre3/arch/ia64/sn/io/machvec/iomv.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/machvec/iomv.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/machvec/iomv.c	2003-07-05 18:09:41.000000000 -0700
@@ -0,0 +1,75 @@
+/* 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/sn/simulator.h>
+#include <asm/sn/pda.h>
+#include <asm/sn/sn_cpuid.h>
+
+/**
+ * sn_io_addr - convert an in/out port to an i/o address
+ * @port: port to convert
+ *
+ * Legacy in/out instructions are converted to ld/st instructions
+ * on IA64.  This routine will convert a port number into a valid 
+ * SN i/o address.  Used by sn_in*() and sn_out*().
+ */
+void *
+sn_io_addr(unsigned long port)
+{
+	if (!IS_RUNNING_ON_SIMULATOR()) {
+		/* On sn2, legacy I/O ports don't point at anything */
+		if (port < 64*1024)
+			return 0;
+		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
+	} else {
+		/* but the simulator uses them... */
+		unsigned long io_base;
+		unsigned long addr;
+ 
+		/*
+ 		 * word align port, but need more than 10 bits
+ 		 * for accessing registers in bedrock local block
+ 		 * (so we don't do port&0xfff)
+ 		 */
+		if ((port >= 0x1f0 && port <= 0x1f7) ||
+			port == 0x3f6 || port == 0x3f7) {
+			io_base = (0xc000000fcc000000 | ((unsigned long)get_nasid() << 38));
+			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
+		} else {
+			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
+		}
+		return(void *) addr;
+	}
+}
+
+EXPORT_SYMBOL(sn_io_addr);
+
+/**
+ * sn_mmiob - I/O space memory barrier
+ *
+ * Acts as a memory mapped I/O barrier for platforms that queue writes to 
+ * I/O space.  This ensures that subsequent writes to I/O space arrive after
+ * all previous writes.  For most ia64 platforms, this is a simple
+ * 'mf.a' instruction.  For other platforms, mmiob() may have to read
+ * a chipset register to ensure ordering.
+ *
+ * On SN2, we wait for the PIO_WRITE_STATUS SHub register to clear.
+ * See PV 871084 for details about the WAR about zero value.
+ *
+ */
+void
+sn_mmiob (void)
+{
+	while ((((volatile unsigned long) (*pda.pio_write_status_addr)) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) != 
+				SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
+		udelay(1);
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/machvec/pci.c linux-2.4.22-pre3/arch/ia64/sn/io/machvec/pci.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/machvec/pci.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/machvec/pci.c	2003-07-05 18:09:41.000000000 -0700
@@ -0,0 +1,291 @@
+/* 
+ *
+ * SNI64 specific PCI support for SNI IO.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1997, 1998, 2000-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/iograph.h>
+#include <asm/param.h>
+#include <asm/sn/pio.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/bridge.h>
+
+#ifdef DEBUG_CONFIG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+
+
+#ifdef CONFIG_PCI
+
+extern vertex_hdl_t pci_bus_to_vertex(unsigned char);
+extern vertex_hdl_t devfn_to_vertex(unsigned char bus, unsigned char devfn);
+
+/*
+ * snia64_read_config_byte - Read a byte from the config area of the device.
+ */
+static int snia64_read_config_byte (struct pci_dev *dev,
+                                   int where, unsigned char *val)
+{
+	unsigned long res = 0;
+	unsigned size = 1;
+	vertex_hdl_t device_vertex;
+
+	if ( (dev == (struct pci_dev *)0) || (val == (unsigned char *)0) ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	res = pciio_config_get(device_vertex, (unsigned) where, size);
+	*val = (unsigned char) res;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * snia64_read_config_word - Read 2 bytes from the config area of the device.
+ */
+static int snia64_read_config_word (struct pci_dev *dev,
+                                   int where, unsigned short *val)
+{
+	unsigned long res = 0;
+	unsigned size = 2; /* 2 bytes */
+	vertex_hdl_t device_vertex;
+
+	if ( (dev == (struct pci_dev *)0) || (val == (unsigned short *)0) ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	res = pciio_config_get(device_vertex, (unsigned) where, size);
+	*val = (unsigned short) res;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * snia64_read_config_dword - Read 4 bytes from the config area of the device.
+ */
+static int snia64_read_config_dword (struct pci_dev *dev,
+                                    int where, unsigned int *val)
+{
+	unsigned long res = 0;
+	unsigned size = 4; /* 4 bytes */
+	vertex_hdl_t device_vertex;
+
+	if (where & 3) {
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+	if ( (dev == (struct pci_dev *)0) || (val == (unsigned int *)0) ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	res = pciio_config_get(device_vertex, (unsigned) where, size);
+	*val = (unsigned int) res;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * snia64_write_config_byte - Writes 1 byte to the config area of the device.
+ */
+static int snia64_write_config_byte (struct pci_dev *dev,
+                                    int where, unsigned char val)
+{
+	vertex_hdl_t device_vertex;
+
+	if ( dev == (struct pci_dev *)0 ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	/* 
+	 * if it's an IOC3 then we bail out, we special
+	 * case them with pci_fixup_ioc3
+	 */
+	if (dev->vendor == PCI_VENDOR_ID_SGI && 
+	    dev->device == PCI_DEVICE_ID_SGI_IOC3 )
+		return PCIBIOS_SUCCESSFUL;
+
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	pciio_config_set( device_vertex, (unsigned)where, 1, (uint64_t) val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * snia64_write_config_word - Writes 2 bytes to the config area of the device.
+ */
+static int snia64_write_config_word (struct pci_dev *dev,
+                                    int where, unsigned short val)
+{
+	vertex_hdl_t device_vertex = NULL;
+
+	if (where & 1) {
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+	if ( dev == (struct pci_dev *)0 ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	/* 
+	 * if it's an IOC3 then we bail out, we special
+	 * case them with pci_fixup_ioc3
+	 */
+	if (dev->vendor == PCI_VENDOR_ID_SGI && 
+	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
+		return PCIBIOS_SUCCESSFUL;
+
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	pciio_config_set( device_vertex, (unsigned)where, 2, (uint64_t) val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * snia64_write_config_dword - Writes 4 bytes to the config area of the device.
+ */
+static int snia64_write_config_dword (struct pci_dev *dev,
+                                     int where, unsigned int val)
+{
+	vertex_hdl_t device_vertex;
+
+	if (where & 3) {
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+	if ( dev == (struct pci_dev *)0 ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	/* 
+	 * if it's an IOC3 then we bail out, we special
+	 * case them with pci_fixup_ioc3
+	 */
+	if (dev->vendor == PCI_VENDOR_ID_SGI && 
+	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
+		return PCIBIOS_SUCCESSFUL;
+
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	pciio_config_set( device_vertex, (unsigned)where, 4, (uint64_t) val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops snia64_pci_ops = {
+	snia64_read_config_byte,
+	snia64_read_config_word,
+	snia64_read_config_dword,
+	snia64_write_config_byte,
+	snia64_write_config_word,
+	snia64_write_config_dword
+};
+
+/*
+ * snia64_pci_find_bios - SNIA64 pci_find_bios() platform specific code.
+ */
+void __init
+sn_pci_find_bios(void)
+{
+	extern struct pci_ops *pci_root_ops;
+	/*
+	 * Go initialize our IO Infrastructure ..
+	 */
+	extern void sgi_master_io_infr_init(void);
+
+	sgi_master_io_infr_init();
+
+	/* sn_io_infrastructure_init(); */
+	pci_root_ops = &snia64_pci_ops;
+}
+
+void
+pci_fixup_ioc3(struct pci_dev *d)
+{
+        int 		i;
+	unsigned int 	size;
+
+        /* IOC3 only decodes 0x20 bytes of the config space, reading
+	 * beyond that is relatively benign but writing beyond that
+	 * (especially the base address registers) will shut down the
+	 * pci bus...so avoid doing so.
+	 * NOTE: this means we can't program the intr_pin into the device,
+	 *       currently we hack this with special code in 
+	 *	 sgi_pci_intr_support()
+	 */
+        DBG("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name);
+
+	/* I happen to know from the spec that the ioc3 needs only 0xfffff 
+	 * The standard pci trick of writing ~0 to the baddr and seeing
+	 * what comes back doesn't work with the ioc3
+	 */
+	size = 0xfffff;
+	d->resource[0].end = (unsigned long) d->resource[0].start + (unsigned long) size;
+
+	/*
+	 * Zero out the resource structure .. because we did not go through 
+	 * the normal PCI Infrastructure Init, garbbage are left in these 
+	 * fileds.
+	 */
+        for (i = 1; i <= PCI_ROM_RESOURCE; i++) {
+                d->resource[i].start = 0UL;
+                d->resource[i].end = 0UL;
+                d->resource[i].flags = 0UL;
+        }
+
+        d->subsystem_vendor = 0;
+        d->subsystem_device = 0;
+
+}
+
+#else
+void sn_pci_find_bios(void) {}
+void pci_fixup_ioc3(struct pci_dev *d) {}
+struct list_head pci_root_buses;
+struct list_head pci_root_buses;
+struct list_head pci_devices;
+
+#endif /* CONFIG_PCI */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/machvec/pci_bus_cvlink.c linux-2.4.22-pre3/arch/ia64/sn/io/machvec/pci_bus_cvlink.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	2003-07-05 18:09:41.000000000 -0700
@@ -0,0 +1,930 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/iograph.h>
+#include <asm/param.h>
+#include <asm/sn/pio.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/xtalk/xtalkaddrs.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/nodepda.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_bus_cvlink.h>
+#include <asm/sn/simulator.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/arch.h>
+
+extern int bridge_rev_b_data_check_disable;
+
+vertex_hdl_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
+nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
+void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
+unsigned char num_bridges;
+static int done_probing;
+extern irqpda_t *irqpdaindr;
+
+static int pci_bus_map_create(vertex_hdl_t xtalk, char * io_moduleid);
+vertex_hdl_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
+
+extern void register_pcibr_intr(int irq, pcibr_intr_t intr);
+
+void sn_dma_flush_init(unsigned long start, unsigned long end, int idx, int pin, int slot);
+
+
+/*
+ * For the given device, initialize whether it is a PIC device.
+ */
+static void
+set_isPIC(struct sn_device_sysdata *device_sysdata)
+{
+	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
+	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+
+	device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);;
+}
+
+/*
+ * pci_bus_cvlink_init() - To be called once during initialization before 
+ *	SGI IO Infrastructure init is called.
+ */
+void
+pci_bus_cvlink_init(void)
+{
+
+	extern void ioconfig_bus_init(void);
+
+	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(vertex_hdl_t) * MAX_PCI_XWIDGET);
+	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
+
+	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
+
+	num_bridges = 0;
+
+	ioconfig_bus_init();
+}
+
+/*
+ * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
+ *	pci bus vertex from the SGI IO Infrastructure.
+ */
+vertex_hdl_t
+pci_bus_to_vertex(unsigned char busnum)
+{
+
+	vertex_hdl_t	pci_bus = NULL;
+
+
+	/*
+	 * First get the xwidget vertex.
+	 */
+	pci_bus = busnum_to_pcibr_vhdl[busnum];
+	return(pci_bus);
+}
+
+/*
+ * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
+ *	and function numbers.
+ */
+vertex_hdl_t
+devfn_to_vertex(unsigned char busnum, unsigned int devfn)
+{
+
+	int slot = 0;
+	int func = 0;
+	char	name[16];
+	vertex_hdl_t  pci_bus = NULL;
+	vertex_hdl_t	device_vertex = (vertex_hdl_t)NULL;
+
+	/*
+	 * Go get the pci bus vertex.
+	 */
+	pci_bus = pci_bus_to_vertex(busnum);
+	if (!pci_bus) {
+		/*
+		 * During probing, the Linux pci code invents non-existent
+		 * bus numbers and pci_dev structures and tries to access
+		 * them to determine existence. Don't crib during probing.
+		 */
+		if (done_probing)
+			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
+		return(NULL);
+	}
+
+
+	/*
+	 * Go get the slot&function vertex.
+	 * Should call pciio_slot_func_to_name() when ready.
+	 */
+	slot = PCI_SLOT(devfn);
+	func = PCI_FUNC(devfn);
+
+	/*
+	 * For a NON Multi-function card the name of the device looks like:
+	 * ../pci/1, ../pci/2 ..
+	 */
+	if (func == 0) {
+        	sprintf(name, "%d", slot);
+		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
+			GRAPH_SUCCESS) {
+			if (device_vertex) {
+				return(device_vertex);
+			}
+		}
+	}
+			
+	/*
+	 * This maybe a multifunction card.  It's names look like:
+	 * ../pci/1a, ../pci/1b, etc.
+	 */
+	sprintf(name, "%d%c", slot, 'a'+func);
+	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
+		if (!device_vertex) {
+			return(NULL);
+		}
+	}
+
+	return(device_vertex);
+}
+
+/*
+ * For the given device, initialize the addresses for both the Device(x) Flush 
+ * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
+ * is connected.
+ */
+static void
+set_flush_addresses(struct pci_dev *device_dev, 
+	struct sn_device_sysdata *device_sysdata)
+{
+	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
+	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
+	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    	bridge_t               *bridge = pcibr_soft->bs_base;
+	nasid_t			nasid;
+
+	/*
+	 * Get the nasid from the bridge.
+	 */
+	nasid = NASID_GET(device_sysdata->dma_buf_sync);
+	if (IS_PIC_DEVICE(device_dev)) {
+		device_sysdata->dma_buf_sync = (volatile unsigned int *)
+			&bridge->b_wr_req_buf[pciio_slot].reg;
+		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
+			XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(nasid, 0),
+			pcibr_soft->bs_xid);
+	} else {
+		/*
+		 * Accessing Xbridge and Xbow register when SHUB swapoper is on!.
+		 */
+		device_sysdata->dma_buf_sync = (volatile unsigned int *)
+			((uint64_t)&(bridge->b_wr_req_buf[pciio_slot].reg)^4);
+		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
+			((uint64_t)(XBOW_PRIO_LINKREGS_PTR(
+			NODE_SWIN_BASE(nasid, 0), pcibr_soft->bs_xid)) ^ 4);
+	}
+
+#ifdef DEBUG
+	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
+		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
+
+printk("set_flush_addresses: dma_buf_sync\n");
+	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
+printk("set_flush_addresses: xbow_buf_sync\n");
+	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
+#endif
+
+}
+
+struct sn_flush_nasid_entry flush_nasid_list[MAX_NASIDS];
+
+// Initialize the data structures for flushing write buffers after a PIO read.
+// The theory is: 
+// Take an unused int. pin and associate it with a pin that is in use.
+// After a PIO read, force an interrupt on the unused pin, forcing a write buffer flush
+// on the in use pin.  This will prevent the race condition between PIO read responses and 
+// DMA writes.
+void
+sn_dma_flush_init(unsigned long start, unsigned long end, int idx, int pin, int slot) {
+	nasid_t nasid; 
+	unsigned long dnasid;
+	int wid_num;
+	int bus;
+	struct sn_flush_device_list *p;
+	bridge_t *b;
+	bridgereg_t dev_sel;
+	extern int isIO9(int);
+	int bwin;
+	int i;
+
+	nasid = NASID_GET(start);
+	wid_num = SWIN_WIDGETNUM(start);
+	bus = (start >> 23) & 0x1;
+	bwin = BWIN_WINDOWNUM(start);
+
+	if (flush_nasid_list[nasid].widget_p == NULL) {
+		flush_nasid_list[nasid].widget_p = (struct sn_flush_device_list **)kmalloc((HUB_WIDGET_ID_MAX+1) *
+			sizeof(struct sn_flush_device_list *), GFP_KERNEL);
+		memset(flush_nasid_list[nasid].widget_p, 0, (HUB_WIDGET_ID_MAX+1) * sizeof(struct sn_flush_device_list *));
+	}
+	if (bwin > 0) {
+		bwin--;
+		switch (bwin) {
+			case 0:
+				flush_nasid_list[nasid].iio_itte1 = HUB_L(IIO_ITTE_GET(nasid, 0));
+				wid_num = ((flush_nasid_list[nasid].iio_itte1) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte1 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 1:
+				flush_nasid_list[nasid].iio_itte2 = HUB_L(IIO_ITTE_GET(nasid, 1));
+				wid_num = ((flush_nasid_list[nasid].iio_itte2) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte2 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 2:
+				flush_nasid_list[nasid].iio_itte3 = HUB_L(IIO_ITTE_GET(nasid, 2));
+				wid_num = ((flush_nasid_list[nasid].iio_itte3) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte3 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 3:
+				flush_nasid_list[nasid].iio_itte4 = HUB_L(IIO_ITTE_GET(nasid, 3));
+				wid_num = ((flush_nasid_list[nasid].iio_itte4) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte4 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 4:
+				flush_nasid_list[nasid].iio_itte5 = HUB_L(IIO_ITTE_GET(nasid, 4));
+				wid_num = ((flush_nasid_list[nasid].iio_itte5) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte5 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 5:
+				flush_nasid_list[nasid].iio_itte6 = HUB_L(IIO_ITTE_GET(nasid, 5));
+				wid_num = ((flush_nasid_list[nasid].iio_itte6) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte6 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 6:
+				flush_nasid_list[nasid].iio_itte7 = HUB_L(IIO_ITTE_GET(nasid, 6));
+				wid_num = ((flush_nasid_list[nasid].iio_itte7) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte7 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+		}
+	}
+
+	// if it's IO9, bus 1, we don't care about slots 1, 3, and 4.  This is
+	// because these are the IOC4 slots and we don't flush them.
+	if (isIO9(nasid) && bus == 0 && (slot == 1 || slot == 4)) {
+		return;
+	}
+	if (flush_nasid_list[nasid].widget_p[wid_num] == NULL) {
+		flush_nasid_list[nasid].widget_p[wid_num] = (struct sn_flush_device_list *)kmalloc(
+			DEV_PER_WIDGET * sizeof (struct sn_flush_device_list), GFP_KERNEL);
+		memset(flush_nasid_list[nasid].widget_p[wid_num], 0, 
+			DEV_PER_WIDGET * sizeof (struct sn_flush_device_list));
+		p = &flush_nasid_list[nasid].widget_p[wid_num][0];
+		for (i=0; i<DEV_PER_WIDGET;i++) {
+			p->bus = -1;
+			p->pin = -1;
+			p++;
+		}
+	}
+
+	p = &flush_nasid_list[nasid].widget_p[wid_num][0];
+	for (i=0;i<DEV_PER_WIDGET; i++) {
+		if (p->pin == pin && p->bus == bus) break;
+		if (p->pin < 0) {
+			p->pin = pin;
+			p->bus = bus;
+			break;
+		}
+		p++;
+	}
+
+	for (i=0; i<PCI_ROM_RESOURCE; i++) {
+		if (p->bar_list[i].start == 0) {
+			p->bar_list[i].start = start;
+			p->bar_list[i].end = end;
+			break;
+		}
+	}
+	b = (bridge_t *)(NODE_SWIN_BASE(nasid, wid_num) | (bus << 23) );
+
+	// If it's IO9, then slot 2 maps to slot 7 and slot 6 maps to slot 8.
+	// To see this is non-trivial.  By drawing pictures and reading manuals and talking
+	// to HW guys, we can see that on IO9 bus 1, slots 7 and 8 are always unused.
+	// Further, since we short-circuit slots  1, 3, and 4 above, we only have to worry
+	// about the case when there is a card in slot 2.  A multifunction card will appear
+	// to be in slot 6 (from an interrupt point of view) also.  That's the  most we'll
+	// have to worry about.  A four function card will overload the interrupt lines in
+	// slot 2 and 6.  
+	// We also need to special case the 12160 device in slot 3.  Fortunately, we have
+	// a spare intr. line for pin 4, so we'll use that for the 12160.
+	// All other buses have slot 3 and 4 and slots 7 and 8 unused.  Since we can only
+	// see slots 1 and 2 and slots 5 and 6 coming through here for those buses (this
+	// is true only on Pxbricks with 2 physical slots per bus), we just need to add
+	// 2 to the slot number to find an unused slot.
+	// We have convinced ourselves that we will never see a case where two different cards
+	// in two different slots will ever share an interrupt line, so there is no need to
+	// special case this.
+
+	if (isIO9(nasid) && wid_num == 0xc && bus == 0) {
+		if (slot == 2) {
+			p->force_int_addr = (unsigned long)&b->b_force_always[6].intr;
+			dev_sel = b->b_int_device;
+			dev_sel |= (1<<18);
+			b->b_int_device = dev_sel;
+			dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+			b->p_int_addr_64[6] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+				(dnasid << 36) | (0xfUL << 48);
+		} else  if (slot == 3) { /* 12160 SCSI device in IO9 */
+			p->force_int_addr = (unsigned long)&b->b_force_always[4].intr;
+			dev_sel = b->b_int_device;
+			dev_sel |= (2<<12);
+			b->b_int_device = dev_sel;
+			dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+			b->p_int_addr_64[4] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+				(dnasid << 36) | (0xfUL << 48);
+		} else { /* slot == 6 */
+			p->force_int_addr = (unsigned long)&b->b_force_always[7].intr;
+			dev_sel = b->b_int_device;
+			dev_sel |= (5<<21);
+			b->b_int_device = dev_sel;
+			dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+			b->p_int_addr_64[7] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+				(dnasid << 36) | (0xfUL << 48);
+		}
+	} else {
+		p->force_int_addr = (unsigned long)&b->b_force_always[pin + 2].intr;
+		dev_sel = b->b_int_device;
+		dev_sel |= ((slot - 1) << ( pin * 3) );
+		b->b_int_device = dev_sel;
+		dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+		b->p_int_addr_64[pin + 2] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+			(dnasid << 36) | (0xfUL << 48);
+	}
+}
+
+/*
+ * Most drivers currently do not properly tell the arch specific pci dma
+ * interfaces whether they can handle A64. Here is where we privately
+ * keep track of this.
+ */
+static void __init
+set_sn_pci64(struct pci_dev *dev)
+{
+	unsigned short vendor = dev->vendor;
+	unsigned short device = dev->device;
+
+	if (vendor == PCI_VENDOR_ID_QLOGIC) {
+		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
+				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
+			SET_PCIA64(dev);
+			return;
+		}
+	}
+
+	if (vendor == PCI_VENDOR_ID_SGI) {
+		if (device == PCI_DEVICE_ID_SGI_IOC3) {
+			SET_PCIA64(dev);
+			return;
+		}
+	}
+
+}
+
+/*
+ * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
+ *	invoked at the end of pcibios_init() to link the Linux pci 
+ *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
+ *
+ *	Other platform specific fixup can also be done here.
+ */
+void
+sn_pci_fixup(int arg)
+{
+	struct list_head *ln;
+	struct pci_bus *pci_bus = NULL;
+	struct pci_dev *device_dev = NULL;
+	struct sn_widget_sysdata *widget_sysdata;
+	struct sn_device_sysdata *device_sysdata;
+	pciio_intr_t intr_handle;
+	int cpuid, bit;
+	vertex_hdl_t device_vertex;
+	pciio_intr_line_t lines;
+	extern void sn_pci_find_bios(void);
+	extern int numnodes;
+	int cnode;
+
+	if (arg == 0) {
+#ifdef CONFIG_PROC_FS
+		extern void register_sn_procfs(void);
+#endif
+
+		sn_pci_find_bios();
+		for (cnode = 0; cnode < numnodes; cnode++) {
+			extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
+			intr_init_vecblk(NODEPDA(cnode), cnode, 0);
+		} 
+#ifdef CONFIG_PROC_FS
+		register_sn_procfs();
+#endif
+		return;
+	}
+
+
+	done_probing = 1;
+
+	/*
+	 * Initialize the pci bus vertex in the pci_bus struct.
+	 */
+	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
+		pci_bus = pci_bus_b(ln);
+		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
+					GFP_KERNEL);
+		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
+		pci_bus->sysdata = (void *)widget_sysdata;
+	}
+
+	/*
+ 	 * set the root start and end so that drivers calling check_region()
+	 * won't see a conflict
+	 */
+	ioport_resource.start  = 0xc000000000000000;
+	ioport_resource.end =    0xcfffffffffffffff;
+
+	/*
+	 * Set the root start and end for Mem Resource.
+	 */
+	iomem_resource.start = 0;
+	iomem_resource.end = 0xffffffffffffffff;
+
+	/*
+	 * Initialize the device vertex in the pci_dev struct.
+	 */
+	pci_for_each_dev(device_dev) {
+		unsigned int irq;
+		int idx;
+		u16 cmd;
+		vertex_hdl_t vhdl;
+		unsigned long size;
+		extern int bit_pos_to_irq(int);
+
+		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
+				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
+			extern void pci_fixup_ioc3(struct pci_dev *d);
+			pci_fixup_ioc3(device_dev);
+		}
+
+		/* Set the device vertex */
+
+		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
+					GFP_KERNEL);
+		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
+		device_sysdata->isa64 = 0;
+		/*
+		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
+		 * register addresses.
+		 */
+		(void) set_flush_addresses(device_dev, device_sysdata);
+
+		device_dev->sysdata = (void *) device_sysdata;
+		set_sn_pci64(device_dev);
+		set_isPIC(device_sysdata);
+
+		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
+
+		/*
+		 * Set the resources address correctly.  The assumption here 
+		 * is that the addresses in the resource structure has been
+		 * read from the card and it was set in the card by our
+		 * Infrastructure ..
+		 */
+		vhdl = device_sysdata->vhdl;
+		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
+			size = 0;
+			size = device_dev->resource[idx].end -
+				device_dev->resource[idx].start;
+			if (size) {
+				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
+				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
+			}
+			else
+				continue;
+
+			device_dev->resource[idx].end = 
+				device_dev->resource[idx].start + size;
+
+			if (device_dev->resource[idx].flags & IORESOURCE_IO)
+				cmd |= PCI_COMMAND_IO;
+
+			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
+				cmd |= PCI_COMMAND_MEMORY;
+		}
+#if 0
+	/*
+	 * Software WAR for a Software BUG.
+	 * This is only temporary.
+	 * See PV 872791
+	 */
+
+		/*
+		 * Now handle the ROM resource ..
+		 */
+		size = device_dev->resource[PCI_ROM_RESOURCE].end -
+			device_dev->resource[PCI_ROM_RESOURCE].start;
+
+		if (size) {
+			device_dev->resource[PCI_ROM_RESOURCE].start =
+			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
+				size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
+			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
+			device_dev->resource[PCI_ROM_RESOURCE].end =
+			device_dev->resource[PCI_ROM_RESOURCE].start + size;
+		}
+#endif
+
+		/*
+		 * Update the Command Word on the Card.
+		 */
+		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
+					   /* bit gets dropped .. no harm */
+		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
+
+		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
+		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
+			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
+				lines = 1;
+		}
+ 
+		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
+		device_vertex = device_sysdata->vhdl;
+ 
+		irqpdaindr->current = device_dev;
+		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
+
+		irq = intr_handle->pi_irq;
+		irqpdaindr->device_dev[irq] = device_dev;
+		cpuid = intr_handle->pi_cpu;
+		pciio_intr_connect(intr_handle, (intr_func_t)0, (intr_arg_t)0);
+		device_dev->irq = irq;
+		register_pcibr_intr(irq, (pcibr_intr_t)intr_handle);
+
+		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
+			int ibits = ((pcibr_intr_t)intr_handle)->bi_ibits;
+			int i;
+
+			size = device_dev->resource[idx].end -
+				device_dev->resource[idx].start;
+			if (size == 0) continue;
+
+			for (i=0; i<8; i++) {
+				if (ibits & (1 << i) ) {
+					sn_dma_flush_init(device_dev->resource[idx].start, 
+							device_dev->resource[idx].end,
+							idx,
+							i,
+							PCI_SLOT(device_dev->devfn));
+				}
+			}
+		}
+
+	}
+#ifdef ajmtestintr
+		{
+			int slot = PCI_SLOT(device_dev->devfn);
+			static int timer_set = 0;
+			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
+			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
+			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
+
+			if (!timer_set) {
+				intr_test_set_timer();
+				timer_set = 1;
+			}
+			intr_test_register_irq(irq, pcibr_soft, slot);
+			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
+		}
+#endif
+}
+
+/*
+ * linux_bus_cvlink() Creates a link between the Linux PCI Bus number 
+ *	to the actual hardware component that it represents:
+ *	/dev/hw/linux/busnum/0 -> ../../../hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
+ *
+ *	The bus vertex, when called to devfs_generate_path() returns:
+ *		hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
+ *		hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/0
+ *		hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/1
+ */
+void
+linux_bus_cvlink(void)
+{
+	char name[8];
+	int index;
+	
+	for (index=0; index < MAX_PCI_XWIDGET; index++) {
+		if (!busnum_to_pcibr_vhdl[index])
+			continue;
+
+		sprintf(name, "%x", index);
+		(void) hwgraph_edge_add(linux_busnum, busnum_to_pcibr_vhdl[index], 
+				name);
+	}
+}
+
+/*
+ * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
+ *
+ *	Linux PCI Bus numbers are assigned from lowest module_id numbers
+ *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
+ *	HUB_WIDGET_ID_MIN:
+ *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
+ *
+ *	Given 2 modules 001c01 and 001c02 we get the following mappings:
+ *		001c01, widgetnum 15 = Bus number 0
+ *		001c01, widgetnum 14 = Bus number 1
+ *		001c02, widgetnum 15 = Bus number 3
+ *		001c02, widgetnum 14 = Bus number 4
+ *		etc.
+ *
+ * The rational for starting Bus Number 0 with Widget number 15 is because 
+ * the system boot disks are always connected via Widget 15 Slot 0 of the 
+ * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
+ * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
+ * module id(Master Cnode) of the system.
+ *	
+ */
+static int 
+pci_bus_map_create(vertex_hdl_t xtalk, char * io_moduleid)
+{
+
+	vertex_hdl_t master_node_vertex = NULL;
+	vertex_hdl_t xwidget = NULL;
+	vertex_hdl_t pci_bus = NULL;
+	hubinfo_t hubinfo = NULL;
+	xwidgetnum_t widgetnum;
+	char pathname[128];
+	graph_error_t rv;
+	int bus;
+	int basebus_num;
+	extern void ioconfig_get_busnum(char *, int *);
+
+	int bus_number;
+
+	/*
+	 * Loop throught this vertex and get the Xwidgets ..
+	 */
+
+
+	/* PCI devices */
+
+	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
+		sprintf(pathname, "%d", widgetnum);
+		xwidget = NULL;
+		
+		/*
+		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
+		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
+		 */
+		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
+		if ( (rv != GRAPH_SUCCESS) ) {
+			if (!xwidget) {
+				continue;
+			}
+		}
+
+		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
+		pci_bus = NULL;
+		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
+			if (!pci_bus) {
+				continue;
+}
+
+		/*
+		 * Assign the correct bus number and also the nasid of this 
+		 * pci Xwidget.
+		 * 
+		 * Should not be any race here ...
+		 */
+		num_bridges++;
+		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
+
+		/*
+		 * Get the master node and from there get the NASID.
+		 */
+		master_node_vertex = device_master_get(xwidget);
+		if (!master_node_vertex) {
+			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
+		}
+	
+		hubinfo_get(master_node_vertex, &hubinfo);
+		if (!hubinfo) {
+			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
+			return(1);
+		} else {
+			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
+		}
+
+		/*
+		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
+		 */
+		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
+			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
+		if (!busnum_to_atedmamaps[num_bridges - 1])
+			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
+
+		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
+			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
+
+	}
+
+	/*
+	 * PCIX devices
+	 * We number busses differently for PCI-X devices.
+	 * We start from Lowest Widget on up ..
+	 */
+
+        (void) ioconfig_get_busnum((char *)io_moduleid, &basebus_num);
+
+	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
+
+		/* Do both buses */
+		for ( bus = 0; bus < 2; bus++ ) {
+			sprintf(pathname, "%d", widgetnum);
+			xwidget = NULL;
+			
+			/*
+			 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
+			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0 is the bus
+			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0/1 is device
+			 */
+			rv = hwgraph_traverse(xtalk, pathname, &xwidget);
+			if ( (rv != GRAPH_SUCCESS) ) {
+				if (!xwidget) {
+					continue;
+				}
+			}
+	
+			if ( bus == 0 )
+				sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
+			else
+				sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
+			pci_bus = NULL;
+			if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
+				if (!pci_bus) {
+					continue;
+				}
+	
+			/*
+			 * Assign the correct bus number and also the nasid of this 
+			 * pci Xwidget.
+			 * 
+			 * Should not be any race here ...
+			 */
+			bus_number = basebus_num + bus + io_brick_map_widget(MODULE_PXBRICK, widgetnum);
+#ifdef DEBUG
+			printk("bus_number %d basebus_num %d bus %d io %d\n", 
+				bus_number, basebus_num, bus, 
+				io_brick_map_widget(MODULE_PXBRICK, widgetnum));
+#endif
+			busnum_to_pcibr_vhdl[bus_number] = pci_bus;
+	
+			/*
+			 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
+			 */
+			busnum_to_atedmamaps[bus_number] = (void *) kmalloc(
+				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
+			if (!busnum_to_atedmamaps[bus_number])
+				printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
+	
+			memset(busnum_to_atedmamaps[bus_number], 0x0, 
+				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
+		}
+	}
+
+        return(0);
+}
+
+/*
+ * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
+ *      initialization has completed to set up the mappings between Xbridge
+ *      and logical pci bus numbers.  We also set up the NASID for each of these
+ *      xbridges.
+ *
+ *      Must be called before pci_init() is invoked.
+ */
+int
+pci_bus_to_hcl_cvlink(void) 
+{
+
+	vertex_hdl_t devfs_hdl = NULL;
+	vertex_hdl_t xtalk = NULL;
+	int rv = 0;
+	char name[256];
+	char tmp_name[256];
+	int i, ii, j;
+	char *brick_name;
+	extern void ioconfig_bus_new_entries(void);
+
+	/*
+	 * Figure out which IO Brick is connected to the Compute Bricks.
+	 */
+	for (i = 0; i < nummodules; i++) {
+		extern int iomoduleid_get(nasid_t);
+		moduleid_t iobrick_id;
+		nasid_t nasid = -1;
+		int nodecnt;
+		int n = 0;
+
+		nodecnt = modules[i]->nodecnt;
+		for ( n = 0; n < nodecnt; n++ ) {
+			nasid = cnodeid_to_nasid(modules[i]->nodes[n]);
+			iobrick_id = iomoduleid_get(nasid);
+			if ((int)iobrick_id > 0) { /* Valid module id */
+				char name[12];
+				memset(name, 0, 12);
+				format_module_id((char *)&(modules[i]->io[n].moduleid), iobrick_id, MODULE_FORMAT_BRIEF);
+			}
+		}
+	}
+				
+	devfs_hdl = hwgraph_path_to_vertex("hw/module");
+	for (i = 0; i < nummodules ; i++) {
+	    for ( j = 0; j < 3; j++ ) {
+		if ( j == 0 )
+			brick_name = EDGE_LBL_PBRICK;
+		else if ( j == 1 )
+			brick_name = EDGE_LBL_PXBRICK;
+		else
+			brick_name = EDGE_LBL_IXBRICK;
+
+		for ( ii = 0; ii < 2 ; ii++ ) {
+			memset(name, 0, 256);
+			memset(tmp_name, 0, 256);
+			format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
+			sprintf(tmp_name, "/slab/%d/%s/xtalk", geo_slab(modules[i]->geoid[ii]), brick_name);
+			strcat(name, tmp_name);
+			xtalk = NULL;
+			rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
+			if ( rv == 0 ) 
+				pci_bus_map_create(xtalk, (char *)&(modules[i]->io[ii].moduleid));
+		}
+	    }
+	}
+
+	/*
+	 * Create the Linux PCI bus number vertex link.
+	 */
+	(void)linux_bus_cvlink();
+	(void)ioconfig_bus_new_entries();
+
+	return(0);
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/machvec/pci_dma.c linux-2.4.22-pre3/arch/ia64/sn/io/machvec/pci_dma.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/machvec/pci_dma.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/machvec/pci_dma.c	2003-07-05 18:09:41.000000000 -0700
@@ -0,0 +1,584 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000,2002-2003 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/config.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#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>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/types.h>
+#include <asm/sn/alenlist.h>
+#include <asm/sn/pci/pci_bus_cvlink.h>
+#include <asm/sn/nag.h>
+
+/*
+ * For ATE allocations
+ */
+pciio_dmamap_t get_free_pciio_dmamap(vertex_hdl_t);
+void free_pciio_dmamap(pcibr_dmamap_t);
+static struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char);
+void sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction);
+
+/*
+ * Toplogy stuff
+ */
+extern vertex_hdl_t busnum_to_pcibr_vhdl[];
+extern nasid_t busnum_to_nid[];
+extern void * busnum_to_atedmamaps[];
+
+/**
+ * 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(vertex_hdl_t pci_bus)
+{
+	int i;
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+
+	/*
+	 * Darn, we need to get the maps allocated for this bus.
+	 */
+	for (i = 0; i < MAX_PCI_XWIDGET; i++) {
+		if (busnum_to_pcibr_vhdl[i] == pci_bus) {
+			sn_dma_map = busnum_to_atedmamaps[i];
+		}
+	}
+
+	/*
+	 * Now get a free dmamap entry from this list.
+	 */
+	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;
+}
+
+/**
+ * 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)
+{
+	struct sn_dma_maps_s *sn_dma_map;
+
+	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;
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * 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 %PCIIO_DMA_CMD flag set.
+ *
+ * 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 will always put a 32 bit
+ * DMA address into @dma_handle.  This is because most devices
+ * 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)
+{
+        void *cpuaddr;
+	vertex_hdl_t vhdl;
+	struct sn_device_sysdata *device_sysdata;
+	unsigned long phys_addr;
+	pciio_dmamap_t dma_map = 0;
+	struct sn_dma_maps_s *sn_dma_map;
+
+	*dma_handle = 0;
+
+	if (hwdev->dma_mask < 0xffffffffUL)
+		return NULL;
+
+	/*
+	 * Get hwgraph vertex for the device
+	 */
+	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
+	vhdl = device_sysdata->vhdl;
+
+	/*
+	 * 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;
+
+	/* physical addr. of the memory we just got */
+	phys_addr = __pa(cpuaddr);
+
+	/*
+	 * This will try to use a Direct Map register to do the
+	 * 32 bit DMA mapping, but it may not succeed if another
+	 * device on the same bus is already mapped with different
+	 * attributes or to a different memory region.
+	 */
+	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					  PCIIO_DMA_CMD);
+
+        /*
+	 * If this device is in PCI-X mode, the system would have
+	 * automatically allocated a 64Bits DMA Address.  Error out if the 
+	 * device cannot support DAC.
+	 */
+	if (*dma_handle > hwdev->consistent_dma_mask) {
+		free_pages((unsigned long) cpuaddr, get_order(size));
+		return NULL;
+	}
+
+	/*
+	 * It is a 32 bit card and we cannot do direct mapping,
+	 * so we try to use an ATE.
+	 */
+	if (!(*dma_handle)) {
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
+				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					     PCIIO_DMA_CMD);
+		if (!dma_map) {
+			printk(KERN_ERR "sn_pci_alloc_consistent: Unable to "
+			       "allocate anymore 32 bit page map entries.\n");
+			return 0;
+		}
+		*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;
+	}
+
+        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));
+}
+
+/**
+ * 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)
+{
+
+	int i;
+	vertex_hdl_t vhdl;
+	unsigned long phys_addr;
+	struct sn_device_sysdata *device_sysdata;
+	pciio_dmamap_t dma_map;
+	struct sn_dma_maps_s *sn_dma_map;
+	struct scatterlist *saved_sg = sg;
+
+	/* can't go anywhere w/o a direction in life */
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/*
+	 * 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++) {
+		phys_addr = __pa(sg->address ? sg->address :
+			page_address(sg->page) + sg->offset);
+
+		/*
+		 * Handle the most common case: 64 bit cards.  This
+		 * call should always succeed.
+		 */
+		if (IS_PCIA64(hwdev)) {
+			sg->dma_address = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
+						       sg->length,
+			       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+						       PCIIO_DMA_DATA |
+						       PCIIO_DMA_A64);
+			sg->dma_length = sg->length;
+			continue;
+		}
+
+		/*
+		 * Handle 32-63 bit cards via direct mapping
+		 */
+		if (IS_PCI32G(hwdev)) {
+			sg->dma_address = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
+						       sg->length,
+					((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+						       PCIIO_DMA_DATA);
+			sg->dma_length = sg->length;
+			/*
+			 * See if we got a direct map entry
+			 */
+			if (sg->dma_address) {
+				continue;
+			}
+
+		}
+
+		/*
+		 * It is a 32 bit card and we cannot do direct mapping,
+		 * so we use an ATE.
+		 */
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
+				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					     PCIIO_DMA_DATA);
+		if (!dma_map) {
+			printk(KERN_ERR "sn_pci_map_sg: Unable to allocate "
+			       "anymore 32 bit page map entries.\n");
+			/*
+			 * We will need to free all previously allocated entries.
+			 */
+			if (i > 0) {
+				sn_pci_unmap_sg(hwdev, saved_sg, i, direction);
+			}
+			return (0);
+		}
+
+		sg->dma_address = pciio_dmamap_addr(dma_map, phys_addr, sg->length);
+		sg->dma_length = sg->length;
+		sn_dma_map = (struct sn_dma_maps_s *)dma_map;
+		sn_dma_map->dma_addr = sg->dma_address;
+	}
+
+	return nents;
+
+}
+
+/**
+ * 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 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 < nents; i++, sg++){
+
+		if (IS_PCI32_MAPPED(sg->dma_address)) {
+			sn_dma_map = NULL;
+                	sn_dma_map = find_sn_dma_map(sg->dma_address, hwdev->bus->number);
+        		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;
+			}
+        	}
+
+		sg->dma_address = (dma_addr_t)NULL;
+		sg->dma_length = 0;
+	}
+}
+
+/**
+ * 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
+ * (which is pretty much unacceptable).
+ *
+ * TODO: simplify our interface;
+ *       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)
+{
+	vertex_hdl_t vhdl;
+	dma_addr_t dma_addr;
+	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
+	 */
+	device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata;
+	vhdl = device_sysdata->vhdl;
+
+	/*
+	 * Call our dmamap interface
+	 */
+	dma_addr = 0;
+	phys_addr = __pa(ptr);
+
+	if (IS_PCIA64(hwdev)) {
+		/* This device supports 64 bit DMA addresses. */
+		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+		       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					       PCIIO_DMA_DATA |
+					       PCIIO_DMA_A64);
+		return dma_addr;
+	}
+
+	/*
+	 * Devices that support 32 bit to 63 bit DMA addresses get
+	 * 32 bit DMA addresses.
+	 *
+	 * First try to get a 32 bit direct map register.
+	 */
+	if (IS_PCI32G(hwdev)) {
+		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					       PCIIO_DMA_DATA);
+		if (dma_addr)
+			return dma_addr;
+	}
+
+	/*
+	 * It's a 32 bit card and we cannot do direct mapping so
+	 * let's use the PMU instead.
+	 */
+	dma_map = NULL;
+	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, 
+			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+			PCIIO_DMA_DATA);
+
+	if (!dma_map) {
+		printk(KERN_ERR "pci_map_single: Unable to allocate anymore "
+		       "32 bit page map entries.\n");
+		return 0;
+	}
+
+	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)
+{
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+
+        if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/*
+	 * Get the sn_dma_map entry.
+	 */
+	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'.  We do not need to do 
+ * anything on our platform.
+ */
+void
+sn_pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
+{
+	return;
+
+}
+
+/**
+ * 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'.  We do not need to do anything 
+ * on our platform.
+ */
+void
+sn_pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+{
+	return;
+
+}
+
+/**
+ * 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 when using the PMU.  We could theoretically support <32 bit
+ * cards using direct mapping, but we'll worry about that later--on the off
+ * chance that someone actually wants to use such a card.
+ */
+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_pci_dma_supported);
+
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/ml_SN_init.c linux-2.4.22-pre3/arch/ia64/sn/io/ml_SN_init.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/ml_SN_init.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/ml_SN_init.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,235 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/bootmem.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/snconfig.h>
-
-extern int numcpus;
-extern char arg_maxnodes[];
-extern cpuid_t master_procid;
-#if defined(CONFIG_IA64_SGI_SN1)
-extern synergy_da_t    *Synergy_da_indr[];
-#endif
-
-extern int hasmetarouter;
-
-int		maxcpus;
-cpumask_t	boot_cpumask;
-hubreg_t	region_mask = 0;
-
-
-extern xwidgetnum_t hub_widget_id(nasid_t);
-
-extern int valid_icache_reasons;	/* Reasons to flush the icache */
-extern int valid_dcache_reasons;	/* Reasons to flush the dcache */
-extern u_char miniroot;
-extern volatile int	need_utlbmiss_patch;
-extern void iograph_early_init(void);
-
-nasid_t master_nasid = INVALID_NASID;
-
-
-/*
- * mlreset(int slave)
- * 	very early machine reset - at this point NO interrupts have been
- * 	enabled; nor is memory, tlb, p0, etc setup.
- *
- * 	slave is zero when mlreset is called for the master processor and
- *	is nonzero thereafter.
- */
-
-
-void
-mlreset(int slave)
-{
-	if (!slave) {
-		/*
-		 * We are the master cpu and node.
-		 */ 
-		master_nasid = get_nasid();
-		set_master_bridge_base();
-
-		/* We're the master processor */
-		master_procid = smp_processor_id();
-		master_nasid = cpuid_to_nasid(master_procid);
-
-		/*
-		 * master_nasid we get back better be same as one from
-		 * get_nasid()
-		 */
-		ASSERT_ALWAYS(master_nasid == get_nasid());
-
-		/* early initialization of iograph */
-		iograph_early_init();
-
-		/* Initialize Hub Pseudodriver Management */
-		hubdev_init();
-
-	} else { /* slave != 0 */
-		/*
-		 * This code is performed ONLY by slave processors.
-		 */
-
-	}
-}
-
-
-/* XXX - Move the meat of this to intr.c ? */
-/*
- * Set up the platform-dependent fields in the nodepda.
- */
-void init_platform_nodepda(nodepda_t *npda, cnodeid_t node)
-{
-	hubinfo_t hubinfo;
-#ifdef CONFIG_IA64_SGI_SN1
-	int	  sn;
-#endif
-
-	extern void router_map_init(nodepda_t *);
-	extern void router_queue_init(nodepda_t *,cnodeid_t);
-	extern void intr_init_vecblk(nodepda_t *, cnodeid_t, int);
-
-	/* Allocate per-node platform-dependent data */
-	hubinfo = (hubinfo_t)alloc_bootmem_node(NODE_DATA(node), sizeof(struct hubinfo_s));
-
-	npda->pdinfo = (void *)hubinfo;
-	hubinfo->h_nodepda = npda;
-	hubinfo->h_cnodeid = node;
-	hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(node);
-
-	spin_lock_init(&hubinfo->h_crblock);
-
-	hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid);
-	npda->xbow_peer = INVALID_NASID;
-
-	/* 
-	 * Initialize the linked list of
-	 * router info pointers to the dependent routers
-	 */
-	npda->npda_rip_first = NULL;
-
-	/*
-	 * npda_rip_last always points to the place
-	 * where the next element is to be inserted
-	 * into the list 
-	 */
-	npda->npda_rip_last = &npda->npda_rip_first;
-	npda->module_id = INVALID_MODULE;
-
-#ifdef CONFIG_IA64_SGI_SN1
-	/*
-	* Initialize the interrupts.
-	* On sn2, this is done at pci init time,
-	* because sn2 needs the cpus checked in
-	* when it initializes interrupts.  This is
-	* so we don't see all the nodes as headless.
-	*/
-	for (sn=0; sn<NUM_SUBNODES; sn++) {
-		intr_init_vecblk(npda, node, sn);
-	}
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-	mutex_init_locked(&npda->xbow_sema); /* init it locked? */
-
-#ifdef	LATER
-
-	/* Setup the (module,slot) --> nic mapping for all the routers
-	 * in the system. This is useful during error handling when
-	 * there is no shared memory.
-	 */
-	router_map_init(npda);
-
-	/* Allocate memory for the per-node router traversal queue */
-	router_queue_init(npda,node);
-	npda->sbe_info = alloc_bootmem_node(NODE_DATA(node), sizeof (sbe_info_t));
-	ASSERT(npda->sbe_info);
-
-#endif /* LATER */
-}
-
-/* XXX - Move the interrupt stuff to intr.c ? */
-/*
- * Set up the platform-dependent fields in the processor pda.
- * Must be done _after_ init_platform_nodepda().
- * If we need a lock here, something else is wrong!
- */
-void init_platform_pda(cpuid_t cpu)
-{
-#if defined(CONFIG_IA64_SGI_SN1)
-	hub_intmasks_t *intmasks;
-	int i, subnode;
-	cnodeid_t	cnode;
-	synergy_da_t	*sda;
-	int	which_synergy;
-
-
-	cnode = cpuid_to_cnodeid(cpu);
-	which_synergy = cpuid_to_synergy(cpu);
-
-	sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-	intmasks = &sda->s_intmasks;
-
-	/* Clear INT_PEND0 masks. */
-	for (i = 0; i < N_INTPEND0_MASKS; i++)
-		intmasks->intpend0_masks[i] = 0;
-
-	/* Set up pointer to the vector block in the nodepda. */
-	/* (Cant use SUBNODEPDA - not working yet) */
-	subnode = cpuid_to_subnode(cpu);
-	intmasks->dispatch0 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch0;
-	intmasks->dispatch1 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch1;
-	if (intmasks->dispatch0 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch0 ||
-	   intmasks->dispatch1 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch1)
-	   	panic("xxx");
-	intmasks->dispatch0 = &SUBNODEPDA(cnode, subnode)->intr_dispatch0;
-	intmasks->dispatch1 = &SUBNODEPDA(cnode, subnode)->intr_dispatch1;
-
-	/* Clear INT_PEND1 masks. */
-	for (i = 0; i < N_INTPEND1_MASKS; i++)
-		intmasks->intpend1_masks[i] = 0;
-#endif	/* CONFIG_IA64_SGI_SN1 */
-}
-
-void
-update_node_information(cnodeid_t cnodeid)
-{
-	nodepda_t *npda = NODEPDA(cnodeid);
-	nodepda_router_info_t *npda_rip;
-	
-	/* Go through the list of router info 
-	 * structures and copy some frequently
-	 * accessed info from the info hanging
-	 * off the corresponding router vertices
-	 */
-	npda_rip = npda->npda_rip_first;
-	while(npda_rip) {
-		if (npda_rip->router_infop) {
-			npda_rip->router_portmask = 
-				npda_rip->router_infop->ri_portmask;
-			npda_rip->router_slot = 
-				npda_rip->router_infop->ri_slotnum;
-		} else {
-			/* No router, no ports. */
-			npda_rip->router_portmask = 0;
-		}
-		npda_rip = npda_rip->router_next;
-	}
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/ml_iograph.c linux-2.4.22-pre3/arch/ia64/sn/io/ml_iograph.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/ml_iograph.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/ml_iograph.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1570 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-
-/* #define IOGRAPH_DEBUG */
-#ifdef IOGRAPH_DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* IOGRAPH_DEBUG */
-
-/* #define PROBE_TEST */
-
-/* At most 2 hubs can be connected to an xswitch */
-#define NUM_XSWITCH_VOLUNTEER 2
-
-/*
- * Track which hubs have volunteered to manage devices hanging off of
- * a Crosstalk Switch (e.g. xbow).  This structure is allocated,
- * initialized, and hung off the xswitch vertex early on when the
- * xswitch vertex is created.
- */
-typedef struct xswitch_vol_s {
-	mutex_t xswitch_volunteer_mutex;
-	int		xswitch_volunteer_count;
-	devfs_handle_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
-} *xswitch_vol_t;
-
-void
-xswitch_vertex_init(devfs_handle_t xswitch)
-{
-	xswitch_vol_t xvolinfo;
-	int rc;
-
-	xvolinfo = kmalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL);
-	mutex_init(&xvolinfo->xswitch_volunteer_mutex);
-	xvolinfo->xswitch_volunteer_count = 0;
-	rc = hwgraph_info_add_LBL(xswitch, 
-			INFO_LBL_XSWITCH_VOL,
-			(arbitrary_info_t)xvolinfo);
-	ASSERT(rc == GRAPH_SUCCESS); rc = rc;
-}
-
-
-/*
- * When assignment of hubs to widgets is complete, we no longer need the
- * xswitch volunteer structure hanging around.  Destroy it.
- */
-static void
-xswitch_volunteer_delete(devfs_handle_t xswitch)
-{
-	xswitch_vol_t xvolinfo;
-	int rc;
-
-	rc = hwgraph_info_remove_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL,
-				(arbitrary_info_t *)&xvolinfo);
-#ifdef LATER
-	ASSERT(rc == GRAPH_SUCCESS); rc = rc;
-#endif
-
-	kfree(xvolinfo);
-}
-/*
- * A Crosstalk master volunteers to manage xwidgets on the specified xswitch.
- */
-/* ARGSUSED */
-static void
-volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master)
-{
-	xswitch_vol_t xvolinfo = NULL;
-
-	(void)hwgraph_info_get_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL, 
-				(arbitrary_info_t *)&xvolinfo);
-	if (xvolinfo == NULL) {
-#ifdef LATER
-	    if (!is_headless_node_vertex(master)) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "volunteer for widgets: vertex %v has no info label",
-			xswitch);
-#else
-		printk(KERN_WARNING  "volunteer for widgets: vertex 0x%x has no info label",
-			xswitch);
-#endif
-	    }
-#endif	/* LATER */
-	    return;
-	}
-
-	mutex_lock(&xvolinfo->xswitch_volunteer_mutex);
-	ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER);
-	xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master;
-	xvolinfo->xswitch_volunteer_count++;
-	mutex_unlock(&xvolinfo->xswitch_volunteer_mutex);
-}
-
-extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum);
-
-/*
- * Assign all the xwidgets hanging off the specified xswitch to the
- * Crosstalk masters that have volunteered for xswitch duty.
- */
-/* ARGSUSED */
-static void
-assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv)
-{
-	int curr_volunteer, num_volunteer;
-	xwidgetnum_t widgetnum;
-	xswitch_info_t xswitch_info;
-	xswitch_vol_t xvolinfo = NULL;
-	nasid_t nasid;
-	hubinfo_t hubinfo;
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-	
-	xswitch_info = xswitch_info_get(xswitch);
-	ASSERT(xswitch_info != NULL);
-
-	(void)hwgraph_info_get_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL, 
-				(arbitrary_info_t *)&xvolinfo);
-	if (xvolinfo == NULL) {
-#ifdef LATER
-	    if (!is_headless_node_vertex(hubv)) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "assign_widgets_to_volunteers:vertex %v has "
-			" no info label",
-			xswitch);
-#else
-		printk(KERN_WARNING  "assign_widgets_to_volunteers:vertex 0x%x has "
-			" no info label",
-			xswitch);
-#endif
-	    }
-#endif	/* LATER */
-	    return;
-	}
-
-	num_volunteer = xvolinfo->xswitch_volunteer_count;
-	ASSERT(num_volunteer > 0);
-	curr_volunteer = 0;
-
-	/* Assign master hub for xswitch itself.  */
-	if (HUB_WIDGET_ID_MIN > 0) {
-		hubv = xvolinfo->xswitch_volunteer[0];
-		xswitch_info_master_assignment_set(xswitch_info, (xwidgetnum_t)0, hubv);
-	}
-
-	/*
-	 * TBD: Use administrative information to alter assignment of
-	 * widgets to hubs.
-	 */
-	for (widgetnum=HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-
-		/*
-		 * Ignore disabled/empty ports.
-		 */
-		if (!xbow_port_io_enabled(nasid, widgetnum)) 
-		    continue;
-
-		/*
-		 * If this is the master IO board, assign it to the same 
-		 * hub that owned it in the prom.
-		 */
-		if (is_master_nasid_widget(nasid, widgetnum)) {
-			int i;
-
-			for (i=0; i<num_volunteer; i++) {
-				hubv = xvolinfo->xswitch_volunteer[i];
-				hubinfo_get(hubv, &hubinfo);
-				nasid = hubinfo->h_nasid;
-				if (nasid == get_console_nasid())
-					goto do_assignment;
-			}
-#ifdef LATER
-			PRINT_PANIC("Nasid == %d, console nasid == %d",
-				nasid, get_console_nasid());
-#endif
-		}
-
-
-		/*
-		 * Do a round-robin assignment among the volunteer nodes.
-		 */
-		hubv = xvolinfo->xswitch_volunteer[curr_volunteer];
-		curr_volunteer = (curr_volunteer + 1) % num_volunteer;
-		/* fall through */
-
-do_assignment:
-		/*
-		 * At this point, we want to make hubv the master of widgetnum.
-		 */
-		xswitch_info_master_assignment_set(xswitch_info, widgetnum, hubv);
-	}
-
-	xswitch_volunteer_delete(xswitch);
-}
-
-/*
- * Early iograph initialization.  Called by master CPU in mlreset().
- * Useful for including iograph.o in kernel.o.
- */
-void
-iograph_early_init(void)
-{
-/*
- * Need new way to get this information ..
- */
-	cnodeid_t cnode;
-	nasid_t nasid;
-	lboard_t *board;
-	
-	/*
-	 * Init. the board-to-hwgraph link early, so FRU analyzer
-	 * doesn't trip on leftover values if we panic early on.
-	 */
-	for(cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		DBG("iograph_early_init: Found board 0x%p\n", board);
-
-		/* Check out all the board info stored on a node */
-		while(board) {
-			board->brd_graph_link = GRAPH_VERTEX_NONE;
-			board = KLCF_NEXT(board);
-			DBG("iograph_early_init: Found board 0x%p\n", board);
-
-
-		}
-	}
-
-	hubio_init();
-}
-
-#ifdef LINUX_KERNEL_THREADS
-static struct semaphore io_init_sema;
-#endif
-
-/*
- * Let boot processor know that we're done initializing our node's IO
- * and then exit.
- */
-/* ARGSUSED */
-static void
-io_init_done(cnodeid_t cnodeid,cpu_cookie_t c)
-{
-	/* Let boot processor know that we're done. */
-#ifdef LINUX_KERNEL_THREADS
-	up(&io_init_sema);
-#endif
-#ifdef LATER
-	/* This is for the setnoderun done when the io_init thread
-	 * started 
-	 */
-	restorenoderun(c);
-	sthread_exit();
-#endif
-}
-
-/* 
- * Probe to see if this hub's xtalk link is active.  If so,
- * return the Crosstalk Identification of the widget that we talk to.  
- * This is called before any of the Crosstalk infrastructure for 
- * this hub is set up.  It's usually called on the node that we're
- * probing, but not always.
- *
- * TBD: Prom code should actually do this work, and pass through 
- * hwid for our use.
- */
-static void
-early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid)
-{
-	hubreg_t llp_csr_reg;
-	nasid_t nasid;
-	hubinfo_t hubinfo;
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-
-	llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
-	/* 
-	 * If link is up, read the widget's part number.
-	 * A direct connect widget must respond to widgetnum=0.
-	 */
-	if (llp_csr_reg & IIO_LLP_CSR_IS_UP) {
-		/* TBD: Put hub into "indirect" mode */
-		/*
-		 * We're able to read from a widget because our hub's 
-		 * WIDGET_ID was set up earlier.
-		 */
-		widgetreg_t widget_id = *(volatile widgetreg_t *)
-			(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
-
-		DBG("early_probe_for_widget: Hub Vertex 0x%p is UP widget_id = 0x%x Register 0x%p\n", hubv, widget_id,
-		(volatile widgetreg_t *)(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID) );
-
-		hwid->part_num = XWIDGET_PART_NUM(widget_id);
-		hwid->rev_num = XWIDGET_REV_NUM(widget_id);
-		hwid->mfg_num = XWIDGET_MFG_NUM(widget_id);
-
-		/* TBD: link reset */
-	} else {
-
-		hwid->part_num = XWIDGET_PART_NUM_NONE;
-		hwid->rev_num = XWIDGET_REV_NUM_NONE;
-		hwid->mfg_num = XWIDGET_MFG_NUM_NONE;
-	}
-
-}
-
-/* Add inventory information to the widget vertex 
- * Right now (module,slot,revision) is being
- * added as inventory information.
- */
-static void
-xwidget_inventory_add(devfs_handle_t 		widgetv,
-		      lboard_t 			*board,
-		      struct xwidget_hwid_s 	hwid)
-{
-	if (!board)
-		return;
-	/* Donot add inventory information for the baseio
-	 * on a speedo with an xbox. It has already been
-	 * taken care of in SN00_vmc.
-	 * Speedo with xbox's baseio comes in at slot io1 (widget 9)
-	 */
-	device_inventory_add(widgetv,INV_IOBD,board->brd_type,
-			     board->brd_module,
-			     SLOTNUM_GETSLOT(board->brd_slot),
-			     hwid.rev_num);
-}
-
-/*
- * io_xswitch_widget_init
- *	
- */
-
-/* defined in include/linux/ctype.h  */
-/* #define toupper(c)	(islower(c) ? (c) - 'a' + 'A' : (c)) */
-
-void
-io_xswitch_widget_init(devfs_handle_t  	xswitchv,
-		       devfs_handle_t	hubv,
-		       xwidgetnum_t	widgetnum,
-		       async_attach_t	aa)
-{
-	xswitch_info_t		xswitch_info;
-	xwidgetnum_t		hub_widgetid;
-	devfs_handle_t		widgetv;
-	cnodeid_t		cnode;
-	widgetreg_t		widget_id;
-	nasid_t			nasid, peer_nasid;
-	struct xwidget_hwid_s 	hwid;
-	hubinfo_t		hubinfo;
-	/*REFERENCED*/
-	int			rc;
-	char			slotname[SLOTNUM_MAXLENGTH];
-	char 			pathname[128];
-	char			new_name[64];
-	moduleid_t		module;
-	slotid_t		slot;
-	lboard_t		*board = NULL;
-	char			buffer[16];
-	slotid_t get_widget_slotnum(int xbow, int widget);
-	
-	DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum);
-	/*
-	 * Verify that xswitchv is indeed an attached xswitch.
-	 */
-	xswitch_info = xswitch_info_get(xswitchv);
-	ASSERT(xswitch_info != NULL);
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-	cnode = NASID_TO_COMPACT_NODEID(nasid);
-	hub_widgetid = hubinfo->h_widgetid;
-
-
-	/* Who's the other guy on out crossbow (if anyone) */
-	peer_nasid = NODEPDA(cnode)->xbow_peer;
-	if (peer_nasid == INVALID_NASID)
-		/* If I don't have a peer, use myself. */
-		peer_nasid = nasid;
-
-
-	/* Check my xbow structure and my peer's */
-	if (!xbow_port_io_enabled(nasid, widgetnum) &&
-	    !xbow_port_io_enabled(peer_nasid, widgetnum)) {
-		return;
-	}
-
-	if (xswitch_info_link_ok(xswitch_info, widgetnum)) {
-		char			name[4];
-		/*
-		 * If the current hub is not supposed to be the master 
-		 * for this widgetnum, then skip this widget.
-		 */
-		if (xswitch_info_master_assignment_get(xswitch_info,
-						       widgetnum) != hubv) {
-			return;
-		}
-
-		module  = NODEPDA(cnode)->module_id;
-#ifdef XBRIDGE_REGS_SIM
-		/* hardwire for now...could do this with something like:
-		 * xbow_soft_t soft = hwgraph_fastinfo_get(vhdl);
-		 * xbow_t xbow = soft->base;
-		 * xbowreg_t xwidget_id = xbow->xb_wid_id;
-		 * but I don't feel like figuring out vhdl right now..
-		 * and I know for a fact the answer is 0x2d000049 
-		 */
-		DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
-		DBG("XWIDGET_PART_NUM(0x2d000049)= 0x%x\n", XWIDGET_PART_NUM(0x2d000049));
-		if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) {
-#else
-		if (nasid_has_xbridge(nasid)) {
-#endif /* XBRIDGE_REGS_SIM */
-			board = find_lboard_module_class(
-				(lboard_t *)KL_CONFIG_INFO(nasid),
-				module,
-				KLTYPE_IOBRICK);
-
-DBG("io_xswitch_widget_init: Board 0x%p\n", board);
-{
-		lboard_t dummy;
-
-
-			if (board) {
-				DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type);
-			} else {
-				DBG("io_xswitch_widget_init: FIXME did not find IOBOARD\n");
-				board = &dummy;
-			}
-				
-}
-
-			/*
-	 		 * Make sure we really want to say xbrick, pbrick,
-			 * etc. rather than XIO, graphics, etc.
-	 		 */
-
-#ifdef SUPPORT_PRINTING_M_FORMAT
-			sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-				"%cbrick" "/%s/%d",
-				NODEPDA(cnode)->module_id,
-				
-#else
-			memset(buffer, 0, 16);
-			format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF);
-			sprintf(pathname, EDGE_LBL_MODULE "/%s/"
-				"%cbrick" "/%s/%d",
-				buffer,
-#endif
-
-				(board->brd_type == KLTYPE_IBRICK) ? 'I' :
-				(board->brd_type == KLTYPE_PBRICK) ? 'P' :
-				(board->brd_type == KLTYPE_XBRICK) ? 'X' : '?',
-				EDGE_LBL_XTALK, widgetnum);
-		} 
-		
-		DBG("io_xswitch_widget_init: path= %s\n", pathname);
-		rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
-		
-		ASSERT(rc == GRAPH_SUCCESS);
-
-		/* This is needed to let the user programs to map the
-		 * module,slot numbers to the corresponding widget numbers
-		 * on the crossbow.
-		 */
-		rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv);
-
-		/* If we are looking at the global master io6
-		 * then add information about the version of
-		 * the io6prom as a part of "detailed inventory"
-		 * information.
-		 */
-		if (is_master_baseio(nasid,
-				     NODEPDA(cnode)->module_id,
- 				     get_widget_slotnum(0,widgetnum))) {
-			extern void klhwg_baseio_inventory_add(devfs_handle_t,
-							       cnodeid_t);
-			module 	= NODEPDA(cnode)->module_id;
-
-#ifdef XBRIDGE_REGS_SIM
-			DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
-			if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) {
-#else
-			if (nasid_has_xbridge(nasid)) {
-#endif /* XBRIDGE_REGS_SIM */
-				board = find_lboard_module(
-					(lboard_t *)KL_CONFIG_INFO(nasid),
-					module);
-				/*
-				 * Change iobrick to correct i/o brick
-				 */
-#ifdef SUPPORT_PRINTING_M_FORMAT
-				sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-#else
-				sprintf(pathname, EDGE_LBL_MODULE "/%x/"
-#endif
-					"iobrick" "/%s/%d",
-					NODEPDA(cnode)->module_id,
-					EDGE_LBL_XTALK, widgetnum);
-			} else {
-				slot = get_widget_slotnum(0, widgetnum);
-				board = get_board_name(nasid, module, slot,
-								new_name);
-				/*
-			 	 * Create the vertex for the widget, 
-				 * using the decimal 
-			 	 * widgetnum as the name of the primary edge.
-			 	 */
-#ifdef SUPPORT_PRINTING_M_FORMAT
-				sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-                                                EDGE_LBL_SLOT "/%s/%s",
-                                        NODEPDA(cnode)->module_id,
-                                        slotname, new_name);
-#else
-				memset(buffer, 0, 16);
-				format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF);
-				sprintf(pathname, EDGE_LBL_MODULE "/%s/"
-					  	EDGE_LBL_SLOT "/%s/%s",
-					buffer,
-					slotname, new_name);
-#endif
-			}
-
-			rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
-			DBG("io_xswitch_widget_init: (2) path= %s\n", pathname);
-		        /*
-		         * This is a weird ass code needed for error injection
-		         * purposes.
-		         */
-		        rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv);
-			
-			klhwg_baseio_inventory_add(widgetv,cnode);
-		}
-		sprintf(name, "%d", widgetnum);
-		DBG("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv);
-		rc = hwgraph_edge_add(xswitchv, widgetv, name);
-		
-		/*
-		 * crosstalk switch code tracks which
-		 * widget is attached to each link.
-		 */
-		xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv);
-		
-		/*
-		 * Peek at the widget to get its crosstalk part and
-		 * mfgr numbers, then present it to the generic xtalk
-		 * bus provider to have its driver attach routine
-		 * called (or not).
-		 */
-#ifdef XBRIDGE_REGS_SIM
-		widget_id = 0x2d000049;
-		DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: id hardwired to widget_id\n");
-#else
-		widget_id = XWIDGET_ID_READ(nasid, widgetnum);
-#endif /* XBRIDGE_REGS_SIM */
-		hwid.part_num = XWIDGET_PART_NUM(widget_id);
-		hwid.rev_num = XWIDGET_REV_NUM(widget_id);
-		hwid.mfg_num = XWIDGET_MFG_NUM(widget_id);
-		/* Store some inventory information about
-		 * the xwidget in the hardware graph.
-		 */
-		xwidget_inventory_add(widgetv,board,hwid);
-		
-		(void)xwidget_register(&hwid, widgetv, widgetnum,
-				       hubv, hub_widgetid,
-				       aa);
-
-#ifdef	SN0_USE_BTE
-		bte_bpush_war(cnode, (void *)board);
-#endif
-	}
-
-}
-
-
-static void
-io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode)
-{
-	xwidgetnum_t		widgetnum;
-	async_attach_t          aa;
-
-	aa = async_attach_new();
-	
-	DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode);
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; 
-	     widgetnum++) {
-		io_xswitch_widget_init(xswitchv,
-				       cnodeid_to_vertex(cnode),
-				       widgetnum, aa);
-	}
-	/* 
-	 * Wait for parallel attach threads, if any, to complete.
-	 */
-	async_attach_waitall(aa);
-	async_attach_free(aa);
-}
-
-/*
- * For each PCI bridge connected to the xswitch, add a link from the
- * board's klconfig info to the bridge's hwgraph vertex.  This lets
- * the FRU analyzer find the bridge without traversing the hardware
- * graph and risking hangs.
- */
-static void
-io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid)
-{
-	xwidgetnum_t		widgetnum;
-	char 			pathname[128];
-	devfs_handle_t		vhdl;
-	nasid_t			nasid, peer_nasid;
-	lboard_t		*board;
-
-
-
-	/* And its connected hub's nasids */
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-	peer_nasid = NODEPDA(cnodeid)->xbow_peer;
-
-	/* 
-	 * Look for paths matching "<widgetnum>/pci" under xswitchv.
-	 * For every widget, init. its lboard's hwgraph link.  If the
-	 * board has a PCI bridge, point the link to it.
-	 */
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX;
-		 widgetnum++) {
-		sprintf(pathname, "%d", widgetnum);
-		if (hwgraph_traverse(xswitchv, pathname, &vhdl) !=
-		    GRAPH_SUCCESS)
-			continue;
-
-		board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid),
-				NODEPDA(cnodeid)->module_id);
-		if (board == NULL && peer_nasid != INVALID_NASID) {
-			/*
-			 * Try to find the board on our peer
-			 */
-			board = find_lboard_module(
-				(lboard_t *)KL_CONFIG_INFO(peer_nasid),
-				NODEPDA(cnodeid)->module_id);
-		}
-		if (board == NULL) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-			printk(KERN_WARNING  "Could not find PROM info for vertex %v, "
-				"FRU analyzer may fail",
-				vhdl);
-#else
-			printk(KERN_WARNING  "Could not find PROM info for vertex 0x%p, "
-				"FRU analyzer may fail",
-				(void *)vhdl);
-#endif
-			return;
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		if (hwgraph_traverse(xswitchv, pathname, &vhdl) == 
-		    GRAPH_SUCCESS)
-			board->brd_graph_link = vhdl;
-		else
-			board->brd_graph_link = GRAPH_VERTEX_NONE;
-	}
-}
-
-/*
- * Initialize all I/O on the specified node.
- */
-static void
-io_init_node(cnodeid_t cnodeid)
-{
-	/*REFERENCED*/
-	devfs_handle_t hubv, switchv, widgetv;
-	struct xwidget_hwid_s hwid;
-	hubinfo_t hubinfo;
-	int is_xswitch;
-	nodepda_t	*npdap;
-	struct semaphore *peer_sema = 0;
-	uint32_t	widget_partnum;
-	nodepda_router_info_t *npda_rip;
-	cpu_cookie_t	c = 0;
-	extern int hubdev_docallouts(devfs_handle_t);
-
-#ifdef LATER
-	/* Try to execute on the node that we're initializing. */
-	c = setnoderun(cnodeid);
-#endif
-	npdap = NODEPDA(cnodeid);
-
-	/*
-	 * Get the "top" vertex for this node's hardware
-	 * graph; it will carry the per-hub hub-specific
-	 * data, and act as the crosstalk provider master.
-	 * It's canonical path is probably something of the
-	 * form /hw/module/%M/slot/%d/node
-	 */
-	hubv = cnodeid_to_vertex(cnodeid);
-	DBG("io_init_node: Initialize IO for cnode %d hubv(node) 0x%p npdap 0x%p\n", cnodeid, hubv, npdap);
-
-	ASSERT(hubv != GRAPH_VERTEX_NONE);
-
-	hubdev_docallouts(hubv);
-
-	/*
-	 * Set up the dependent routers if we have any.
-	 */
-	npda_rip = npdap->npda_rip_first;
-
-	while(npda_rip) {
-		/* If the router info has not been initialized
-		 * then we need to do the router initialization
-		 */
-		if (!npda_rip->router_infop) {
-			router_init(cnodeid,0,npda_rip);
-		}
-		npda_rip = npda_rip->router_next;
-	}
-
-	/*
-	 * Read mfg info on this hub
-	 */
-#ifdef LATER
-	printk("io_init_node: FIXME need to implement HUB_VERTEX_MFG_INFO\n");
-	HUB_VERTEX_MFG_INFO(hubv);
-#endif /* LATER */
-
-	/* 
-	 * If nothing connected to this hub's xtalk port, we're done.
-	 */
-	early_probe_for_widget(hubv, &hwid);
-	if (hwid.part_num == XWIDGET_PART_NUM_NONE) {
-#ifdef PROBE_TEST
-		if ((cnodeid == 1) || (cnodeid == 2)) {
-			int index;
-
-			for (index = 0; index < 600; index++)
-				DBG("Interfering with device probing!!!\n");
-		}
-#endif
-		/* io_init_done takes cpu cookie as 2nd argument 
-		 * to do a restorenoderun for the setnoderun done 
-		 * at the start of this thread 
-		 */
-		
-		DBG("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv);
-		return;
-		/* NOTREACHED */
-	}
-
-	/* 
-	 * attach our hub_provider information to hubv,
-	 * so we can use it as a crosstalk provider "master"
-	 * vertex.
-	 */
-	xtalk_provider_register(hubv, &hub_provider);
-	xtalk_provider_startup(hubv);
-
-	/*
-	 * Create a vertex to represent the crosstalk bus
-	 * attached to this hub, and a vertex to be used
-	 * as the connect point for whatever is out there
-	 * on the other side of our crosstalk connection.
-	 *
-	 * Crosstalk Switch drivers "climb up" from their
-	 * connection point to try and take over the switch
-	 * point.
-	 *
-	 * Of course, the edges and verticies may already
-	 * exist, in which case our net effect is just to
-	 * associate the "xtalk_" driver with the connection
-	 * point for the device.
-	 */
-
-	(void)hwgraph_path_add(hubv, EDGE_LBL_XTALK, &switchv);
-
-	DBG("io_init_node: Created 'xtalk' entry to '../node/' xtalk vertex 0x%p\n", switchv);
-
-	ASSERT(switchv != GRAPH_VERTEX_NONE);
-
-	(void)hwgraph_edge_add(hubv, switchv, EDGE_LBL_IO);
-
-	DBG("io_init_node: Created symlink 'io' from ../node/io to ../node/xtalk \n");
-
-	/*
-	 * We need to find the widget id and update the basew_id field
-	 * accordingly. In particular, SN00 has direct connected bridge,
-	 * and hence widget id is Not 0.
-	 */
-
-	widget_partnum = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + WIDGET_ID))) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT;
-
-	if (widget_partnum == BRIDGE_WIDGET_PART_NUM ||
-				widget_partnum == XBRIDGE_WIDGET_PART_NUM){
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-
-		DBG("io_init_node: Found XBRIDGE widget_partnum= 0x%x\n", widget_partnum);
-
-	} else if (widget_partnum == XBOW_WIDGET_PART_NUM ||
-				widget_partnum == XXBOW_WIDGET_PART_NUM) {
-		/* 
-		 * Xbow control register does not have the widget ID field.
-		 * So, hard code the widget ID to be zero.
-		 */
-		DBG("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum);
-		npdap->basew_id = 0;
-
-	} else if (widget_partnum == XG_WIDGET_PART_NUM) {
-		/* 
-		 * OK, WTF do we do here if we have an XG direct connected to a HUB/Bedrock???
-		 * So, hard code the widget ID to be zero?
-		 */
-		npdap->basew_id = 0;
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-	} else { 
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-
-		panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widgt ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, (void *)hubv);
-
-		/*NOTREACHED*/
-	}
-	{
-		char widname[10];
-		sprintf(widname, "%x", npdap->basew_id);
-		(void)hwgraph_path_add(switchv, widname, &widgetv);
-		DBG("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv);
-		ASSERT(widgetv != GRAPH_VERTEX_NONE);
-	}
-	
-	nodepda->basew_xc = widgetv;
-
-	is_xswitch = xwidget_hwid_is_xswitch(&hwid);
-
-	/* 
-	 * Try to become the master of the widget.  If this is an xswitch
-	 * with multiple hubs connected, only one will succeed.  Mastership
-	 * of an xswitch is used only when touching registers on that xswitch.
-	 * The slave xwidgets connected to the xswitch can be owned by various
-	 * masters.
-	 */
-	if (device_master_set(widgetv, hubv) == 0) {
-
-		/* Only one hub (thread) per Crosstalk device or switch makes
-		 * it to here.
-		 */
-
-		/* 
-		 * Initialize whatever xwidget is hanging off our hub.
-		 * Whatever it is, it's accessible through widgetnum 0.
-		 */
-		hubinfo_get(hubv, &hubinfo);
-
-		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL);
-
-		if (!is_xswitch) {
-			/* io_init_done takes cpu cookie as 2nd argument 
-			 * to do a restorenoderun for the setnoderun done 
-			 * at the start of this thread 
-			 */
-			io_init_done(cnodeid,c);
-			/* NOTREACHED */
-		}
-
-		/* 
-		 * Special handling for Crosstalk Switches (e.g. xbow).
-		 * We need to do things in roughly the following order:
-		 *	1) Initialize xswitch hardware (done above)
-		 *	2) Determine which hubs are available to be widget masters
-		 *	3) Discover which links are active from the xswitch
-		 *	4) Assign xwidgets hanging off the xswitch to hubs
-		 *	5) Initialize all xwidgets on the xswitch
-		 */
-
-		volunteer_for_widgets(switchv, hubv);
-
-		/* If there's someone else on this crossbow, recognize him */
-		if (npdap->xbow_peer != INVALID_NASID) {
-			nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer));
-			peer_sema = &peer_npdap->xbow_sema;
-			volunteer_for_widgets(switchv, peer_npdap->node_vertex);
-		}
-
-		assign_widgets_to_volunteers(switchv, hubv);
-
-		/* Signal that we're done */
-		if (peer_sema) {
-			mutex_unlock(peer_sema);
-		}
-		
-	}
-	else {
-	    /* Wait 'til master is done assigning widgets. */
-	    mutex_lock(&npdap->xbow_sema);
-	}
-
-#ifdef PROBE_TEST
-	if ((cnodeid == 1) || (cnodeid == 2)) {
-		int index;
-
-		for (index = 0; index < 500; index++)
-			DBG("Interfering with device probing!!!\n");
-	}
-#endif
-	/* Now both nodes can safely inititialize widgets */
-	io_init_xswitch_widgets(switchv, cnodeid);
-	io_link_xswitch_widgets(switchv, cnodeid);
-
-	/* io_init_done takes cpu cookie as 2nd argument 
-	 * to do a restorenoderun for the setnoderun done 
-	 * at the start of this thread 
-	 */
-	io_init_done(cnodeid,c);
-
-	DBG("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid);
-}
-
-
-#define IOINIT_STKSZ	(16 * 1024)
-
-#define __DEVSTR1 	"/../.master/"
-#define __DEVSTR2 	"/target/"
-#define __DEVSTR3 	"/lun/0/disk/partition/"
-#define	__DEVSTR4	"/../ef"
-
-#if defined(CONFIG_IA64_SGI_SN1)
-/*
- * Currently, we need to allow for 5 IBrick slots with 1 FC each
- * plus an internal 1394.
- *
- * ioconfig starts numbering SCSI's at NUM_BASE_IO_SCSI_CTLR.
- */
-#define NUM_BASE_IO_SCSI_CTLR 6
-#else
-#define NUM_BASE_IO_SCSI_CTLR 6
-#endif
-/*
- * This tells ioconfig where it can start numbering scsi controllers.
- * Below this base number, platform-specific handles the numbering.
- * XXX Irix legacy..controller numbering should be part of devfsd's job
- */
-int num_base_io_scsi_ctlr = 2; /* used by syssgi */
-devfs_handle_t		base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];
-static devfs_handle_t	baseio_enet_vhdl,baseio_console_vhdl;
-
-/*
- * Put the logical controller number information in the 
- * scsi controller vertices for each scsi controller that
- * is in a "fixed position".
- */
-static void
-scsi_ctlr_nums_add(devfs_handle_t pci_vhdl)
-{
-	{
-		int i;
-
-		num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR;
-
-		/* Initialize base_io_scsi_ctlr_vhdl array */
-		for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++)
-			base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE;
-	}
-	{
-	/*
-	 * May want to consider changing the SN0 code, above, to work more like
-	 * the way this works.
-	 */
-	devfs_handle_t base_ibrick_xbridge_vhdl;
-	devfs_handle_t base_ibrick_xtalk_widget_vhdl;
-	devfs_handle_t scsi_ctlr_vhdl;
-	int i;
-	graph_error_t rv;
-
-	/*
-	 * This is a table of "well-known" SCSI controllers and their well-known
-	 * controller numbers.  The names in the table start from the base IBrick's
-	 * Xbridge vertex, so the first component is the xtalk widget number.
-	 */
-	static struct {
-		char	*base_ibrick_scsi_path;
-		int	controller_number;
-	} hardwired_scsi_controllers[] = {
-		{"15/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 0},
-		{"15/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 1},
-		{"15/" EDGE_LBL_PCI "/3/" EDGE_LBL_SCSI_CTLR "/0", 2},
-		{"14/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 3},
-		{"14/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 4},
-		{"15/" EDGE_LBL_PCI "/6/ohci/0/" EDGE_LBL_SCSI_CTLR "/0", 5},
-		{NULL, -1} /* must be last */
-	};
-
-	base_ibrick_xtalk_widget_vhdl = hwgraph_connectpt_get(pci_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xtalk_widget_vhdl != GRAPH_VERTEX_NONE);
-
-	base_ibrick_xbridge_vhdl = hwgraph_connectpt_get(base_ibrick_xtalk_widget_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xbridge_vhdl != GRAPH_VERTEX_NONE);
-	hwgraph_vertex_unref(base_ibrick_xtalk_widget_vhdl);
-
-	/*
-	 * Iterate through the list of well-known SCSI controllers.
-	 * For each controller found, set it's controller number according
-	 * to the table.
-	 */
-	for (i=0; hardwired_scsi_controllers[i].base_ibrick_scsi_path != NULL; i++) {
-		rv = hwgraph_path_lookup(base_ibrick_xbridge_vhdl,
-			hardwired_scsi_controllers[i].base_ibrick_scsi_path, &scsi_ctlr_vhdl, NULL);
-
-		if (rv != GRAPH_SUCCESS) /* No SCSI at this path */
-			continue;
-
-		ASSERT(hardwired_scsi_controllers[i].controller_number < NUM_BASE_IO_SCSI_CTLR);
-		base_io_scsi_ctlr_vhdl[hardwired_scsi_controllers[i].controller_number] = scsi_ctlr_vhdl;
-		device_controller_num_set(scsi_ctlr_vhdl, hardwired_scsi_controllers[i].controller_number);
-		hwgraph_vertex_unref(scsi_ctlr_vhdl); /* (even though we're actually keeping a reference) */
-	}
-
-	hwgraph_vertex_unref(base_ibrick_xbridge_vhdl);
-	}
-}
-
-
-#include <asm/sn/ioerror_handling.h>
-devfs_handle_t		sys_critical_graph_root = GRAPH_VERTEX_NONE;
-
-/* Define the system critical vertices and connect them through
- * a canonical parent-child relationships for easy traversal
- * during io error handling.
- */
-static void
-sys_critical_graph_init(void)
-{
-	devfs_handle_t		bridge_vhdl,master_node_vhdl;
-	devfs_handle_t  		xbow_vhdl = GRAPH_VERTEX_NONE;
-	extern devfs_handle_t	hwgraph_root;
-	devfs_handle_t		pci_slot_conn;
-	int			slot;
-	devfs_handle_t		baseio_console_conn;
-
-	DBG("sys_critical_graph_init: FIXME.\n");
-	baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl);
-
-	if (baseio_console_conn == NULL) {
-		return;
-	}
-
-	/* Get the vertex handle for the baseio bridge */
-	bridge_vhdl = device_master_get(baseio_console_conn);
-
-	/* Get the master node of the baseio card */
-	master_node_vhdl = cnodeid_to_vertex(
-				master_node_get(baseio_console_vhdl));
-	
-	/* Add the "root->node" part of the system critical graph */
-
-	sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl);
-
-	/* Check if we have a crossbow */
-	if (hwgraph_traverse(master_node_vhdl,
-			     EDGE_LBL_XTALK"/0",
-			     &xbow_vhdl) == GRAPH_SUCCESS) {
-		/* We have a crossbow.Add "node->xbow" part of the system 
-		 * critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl);
-		
-		/* Add "xbow->baseio bridge" of the system critical graph */
-		sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl);
-
-		hwgraph_vertex_unref(xbow_vhdl);
-	} else 
-		/* We donot have a crossbow. Add "node->baseio_bridge"
-		 * part of the system critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl);
-
-	/* Add all the populated PCI slot vertices to the system critical
-	 * graph with the bridge vertex as the parent.
-	 */
-	for (slot = 0 ; slot < 8; slot++) {
-		char	slot_edge[10];
-
-		sprintf(slot_edge,"%d",slot);
-		if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn)
-		    != GRAPH_SUCCESS)
-			continue;
-		sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	hwgraph_vertex_unref(bridge_vhdl);
-
-	/* Add the "ioc3 pci connection point  -> console ioc3" part 
-	 * of the system critical graph
-	 */
-
-	if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_console_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "ethernet pci connection point  -> base ethernet" part of 
-	 * the system  critical graph
-	 */
-	if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_enet_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "scsi controller pci connection point  -> base scsi 
-	 * controller" part of the system critical graph
-	 */
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[0]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[1]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	hwgraph_vertex_unref(baseio_console_conn);
-
-}
-
-static void
-baseio_ctlr_num_set(void)
-{
-	char 			name[MAXDEVNAME];
-	devfs_handle_t		console_vhdl, pci_vhdl, enet_vhdl;
-	devfs_handle_t		ioc3_console_vhdl_get(void);
-
-
-	DBG("baseio_ctlr_num_set; FIXME\n");
-	console_vhdl = ioc3_console_vhdl_get();
-	if (console_vhdl == GRAPH_VERTEX_NONE)
-		return;
-	/* Useful for setting up the system critical graph */
-	baseio_console_vhdl = console_vhdl;
-
-	vertex_to_name(console_vhdl,name,MAXDEVNAME);
-
-	strcat(name,__DEVSTR1);
-	pci_vhdl =  hwgraph_path_to_vertex(name);
-	scsi_ctlr_nums_add(pci_vhdl);
-	/* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(pci_vhdl);
-
-	vertex_to_name(console_vhdl, name, MAXDEVNAME);
-	strcat(name, __DEVSTR4);
-	enet_vhdl = hwgraph_path_to_vertex(name);
-
-	/* Useful for setting up the system critical graph */
-	baseio_enet_vhdl = enet_vhdl;
-
-	device_controller_num_set(enet_vhdl, 0);
-	/* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(enet_vhdl);
-}
-/* #endif */
-
-void
-sn00_rrb_alloc(devfs_handle_t vhdl, int *vendor_list)
-{
-	/* REFERENCED */
-	int rtn_val;
-
-	/* 
-	** sn00 population:		errb	orrb
-	**	0- ql			3+?
-	**	1- ql			        2
-	**	2- ioc3 ethernet	2+?
-	**	3- ioc3 secondary	        1
-	**	4-                      0
-	** 	5- PCI slot
-	** 	6- PCI slot
-	** 	7- PCI slot
-	*/	
-	
-	/* The following code implements this heuristic for getting 
-	 * maximum usage out of the rrbs
-	 *
-	 * constraints:
-	 *  8 bit ql1 needs 1+1
-	 *  ql0 or ql5,6,7 wants 1+2
-	 *  ethernet wants 2 or more
-	 *
-	 * rules for even rrbs:
-	 *  if nothing in slot 6 
-	 *   4 rrbs to 0 and 2  (0xc8889999)
-	 *  else 
-         *   3 2 3 to slots 0 2 6  (0xc8899bbb)
-	 *
-         * rules for odd rrbs
-	 *  if nothing in slot 5 or 7  (0xc8889999)
-	 *   4 rrbs to 1 and 3
-	 *  else if 1 thing in 5 or 7  (0xc8899aaa) or (0xc8899bbb)
-         *   3 2 3 to slots 1 3 5|7
-         *  else
-         *   2 1 3 2 to slots 1 3 5 7 (note: if there's a ql card in 7 this
-	 *           (0xc89aaabb)      may short what it wants therefore the
-	 *			       rule should be to plug pci slots in order)
-	 */
-
-
-	if (vendor_list[6] != PCIIO_VENDOR_ID_NONE) {
-		/* something in slot 6 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 3,1, 2,0, 0,0, 3,0);
-	}
-	else {
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 4,1, 4,0, 0,0, 0,0);
-	}
-	if (rtn_val)
-		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-
-	if ((vendor_list[5] != PCIIO_VENDOR_ID_NONE) && 
-	    (vendor_list[7] != PCIIO_VENDOR_ID_NONE)) {
-		/* soemthing in slot 5 and 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 2,1, 1,0, 3,0, 2,0);
-	}
-	else if (vendor_list[5] != PCIIO_VENDOR_ID_NONE) {
-		/* soemthing in slot 5 but not 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 3,0, 0,0);
-	}
-	else if (vendor_list[7] != PCIIO_VENDOR_ID_NONE) {
-		/* soemthing in slot 7 but not 5 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 0,0, 3,0);
-	}
-	else {
-		/* nothing in slot 5 or 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 4,1, 4,0, 0,0, 0,0);
-	}
-	if (rtn_val)
-		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-}
-
-
-/*
- * Initialize all I/O devices.  Starting closest to nodes, probe and
- * initialize outward.
- */
-void
-init_all_devices(void)
-{
-	/* Governor on init threads..bump up when safe 
-	 * (beware many devfs races) 
-	 */
-#ifdef LATER
-	int io_init_node_threads = 2;	
-#endif
-	cnodeid_t cnodeid, active;
-
-#ifdef LINUX_KERNEL_THREADS
-	sema_init(&io_init_sema, 0);
-#endif
-
-	active = 0;
-	for (cnodeid = 0; cnodeid < numnodes; cnodeid++) {
-#ifdef LINUX_KERNEL_THREADS
-		char thread_name[16];
-		extern int io_init_pri;
-
-		/*
-		 * Spawn a service thread for each node to initialize all
-		 * I/O on that node.  Each thread attempts to bind itself 
-		 * to the node whose I/O it's initializing.
-		 */
-		sprintf(thread_name, "IO_init[%d]", cnodeid);
-
-		(void)sthread_create(thread_name, 0, IOINIT_STKSZ, 0,
-			io_init_pri, KT_PS, (st_func_t *)io_init_node,
-			(void *)(long)cnodeid, 0, 0, 0);
-#else
-                DBG("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid);
-                io_init_node(cnodeid);
-
-		DBG("init_all_devices: Done io_init_node() for cnode %d\n", cnodeid);
-
-#endif /* LINUX_KERNEL_THREADS */
-
-#ifdef LINUX_KERNEL_THREADS
-		/* Limit how many nodes go at once, to not overload hwgraph */
-		/* TBD: Should timeout */
-		DBG("started thread for cnode %d\n", cnodeid);
-		active++;
-		if (io_init_node_threads && 
-			active >= io_init_node_threads) {
-			down(&io_init_sema);
-			active--;
-		}
-#endif /* LINUX_KERNEL_THREADS */
-	}
-
-#ifdef LINUX_KERNEL_THREADS
-	/* Wait until all IO_init threads are done */
-
-	while (active > 0) {
-#ifdef AA_DEBUG
-	    DBG("waiting, %d still active\n", active);
-#endif
-	    down(&io_init_sema);
-	    active--;
-	}
-
-#endif /* LINUX_KERNEL_THREADS */
-
-	for (cnodeid = 0; cnodeid < numnodes; cnodeid++)
-		/*
-	 	 * Update information generated by IO init.
-		 */
-		update_node_information(cnodeid);
-
-	baseio_ctlr_num_set();
-	/* Setup the system critical graph (which is a subgraph of the
-	 * main hwgraph). This information is useful during io error
-	 * handling.
-	 */
-	sys_critical_graph_init();
-
-#if HWG_PRINT
-	hwgraph_print();
-#endif
-
-}
-
-#define toint(x) ((int)(x) - (int)('0'))
-
-void
-devnamefromarcs(char *devnm)
-{
-	int 			val;
-	char 			tmpnm[MAXDEVNAME];
-	char 			*tmp1, *tmp2;
-	
-	val = strncmp(devnm, "dks", 3);
-	if (val != 0) 
-		return;
-	tmp1 = devnm + 3;
-	if (!isdigit(*tmp1))
-		return;
-
-	val = 0;
-	while (isdigit(*tmp1)) {
-		val = 10*val+toint(*tmp1);
-		tmp1++;
-	}
-
-	if(*tmp1 != 'd')
-		return;
-	else
-		tmp1++;
-
-	if ((val < 0) || (val >= NUM_BASE_IO_SCSI_CTLR)) {
-		int i;
-		int viable_found = 0;
-
-		DBG("Only controller numbers 0..%d  are supported for\n", NUM_BASE_IO_SCSI_CTLR-1);
-		DBG("prom \"root\" variables of the form dksXdXsX.\n");
-		DBG("To use another disk you must use the full hardware graph path\n\n");
-		DBG("Possible controller numbers for use in 'dksXdXsX' on this system: ");
-		for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++) {
-			if (base_io_scsi_ctlr_vhdl[i] != GRAPH_VERTEX_NONE) {
-				DBG("%d ", i);
-				viable_found=1;
-			}
-		}
-		if (viable_found)
-			DBG("\n");
-		else
-			DBG("none found!\n");
-
-#ifdef LATER
-		if (kdebug)
-			debug("ring");
-#endif
-		DELAY(15000000);
-		//prom_reboot();
-		panic("FIXME: devnamefromarcs: should call prom_reboot here.\n");
-		/* NOTREACHED */
-	}
-		
-	ASSERT(base_io_scsi_ctlr_vhdl[val] != GRAPH_VERTEX_NONE);
-	vertex_to_name(base_io_scsi_ctlr_vhdl[val],
-		       tmpnm,
-		       MAXDEVNAME);
-	tmp2 = 	tmpnm + strlen(tmpnm);
-	strcpy(tmp2, __DEVSTR2);
-	tmp2 += strlen(__DEVSTR2);
-	while (*tmp1 != 's') {
-		if((*tmp2++ = *tmp1++) == '\0')
-			return;
-	}	
-	tmp1++;
-	strcpy(tmp2, __DEVSTR3);
-	tmp2 += strlen(__DEVSTR3);
-	while ( (*tmp2++ = *tmp1++) )
-		;
-	tmp2--;
-	*tmp2++ = '/';
-	strcpy(tmp2, EDGE_LBL_BLOCK);
-	strcpy(devnm,tmpnm);
-}
-
-static
-struct io_brick_map_s io_brick_tab[] = {
-
-/* Ibrick widget number to PCI bus number map */
-  {
-        'I',                                    /* Ibrick type    */ 
-    /*  PCI Bus #                                  Widget #       */
-     {  0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        0,                                      /* 0x8            */
-        0,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        0,                                      /* 0xc            */
-        0,                                      /* 0xd            */
-        2,                                      /* 0xe            */
-        1                                       /* 0xf            */
-     }
-  },
-
-/* Pbrick widget number to PCI bus number map */
-  {
-        'P',                                    /* Pbrick type    */ 
-    /*  PCI Bus #                                  Widget #       */
-     {  0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        2,                                      /* 0x8            */
-        1,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        5,                                      /* 0xc            */
-        6,                                      /* 0xd            */
-        4,                                      /* 0xe            */
-        3                                       /* 0xf            */
-     }
-  },
-
-/* Xbrick widget to XIO slot map */
-  {
-        'X',                                    /* Xbrick type    */ 
-    /*  XIO Slot #                                 Widget #       */
-     {  0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        1,                                      /* 0x8            */
-        2,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        3,                                      /* 0xc            */
-        4,                                      /* 0xd            */
-        0,                                      /* 0xe            */
-        0                                       /* 0xf            */
-     }
-  }
-};
-
-/*
- * Use the brick's type to map a widget number to a meaningful int
- */
-int
-io_brick_map_widget(char brick_type, int widget_num)
-{
-        int num_bricks, i;
-
-        /* Calculate number of bricks in table */
-        num_bricks = sizeof(io_brick_tab)/sizeof(io_brick_tab[0]);
-
-        /* Look for brick prefix in table */
-        for (i = 0; i < num_bricks; i++) {
-               if (brick_type == io_brick_tab[i].ibm_type)
-                       return(io_brick_tab[i].ibm_map_wid[widget_num]);
-        }
-
-        return 0;
-
-}
-
-/*
- * Use the device's vertex to map the device's widget to a meaningful int
- */
-int
-io_path_map_widget(devfs_handle_t vertex)
-{
-        char hw_path_name[MAXDEVNAME];
-        char *wp, *bp, *sp = NULL;
-        int  widget_num;
-	long atoi(char *);
-	int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-
-
-        /* Get the full path name of the vertex */
-        if (GRAPH_SUCCESS != hwgraph_vertex_name_get(vertex, hw_path_name,
-                                                     MAXDEVNAME))
-                return 0;
-
-        /* Find the widget number in the path name */
-        wp = strstr(hw_path_name, "/"EDGE_LBL_XTALK"/");
-        if (wp == NULL)
-                return 0;
-        widget_num = atoi(wp+7);
-        if (widget_num < XBOW_PORT_8 || widget_num > XBOW_PORT_F)
-                return 0;
-
-        /* Find "brick" in the path name */
-        bp = strstr(hw_path_name, "brick");
-        if (bp == NULL)
-                return 0;
-
-        /* Find preceding slash */
-        sp = bp;
-        while (sp > hw_path_name) {
-                sp--;
-                if (*sp == '/')
-                        break;
-        }
-
-        /* Invalid if no preceding slash */
-        if (!sp)
-                return 0;
-
-        /* Bump slash pointer to "brick" prefix */
-        sp++;
-        /*
-         * Verify "brick" prefix length;  valid exaples:
-         * 'I' from "/Ibrick"
-         * 'P' from "/Pbrick"
-         * 'X' from "/Xbrick"
-         */
-         if ((bp - sp) != 1)
-                return 0;
-
-        return (io_brick_map_widget(*sp, widget_num));
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/module.c linux-2.4.22-pre3/arch/ia64/sn/io/module.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/module.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/module.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,312 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/module.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/sn_cpuid.h>
-
-
-/* #define LDEBUG	1 */
-
-#ifdef LDEBUG
-#define DPRINTF		printk
-#define printf		printk
-#else
-#define DPRINTF(x...)
-#endif
-
-module_t	       *modules[MODULE_MAX];
-int			nummodules;
-
-#define SN00_SERIAL_FUDGE	0x3b1af409d513c2
-#define SN0_SERIAL_FUDGE	0x6e
-
-void
-encode_int_serial(uint64_t src,uint64_t *dest)
-{
-    uint64_t val;
-    int i;
-
-    val = src + SN00_SERIAL_FUDGE;
-
-
-    for (i = 0; i < sizeof(long long); i++) {
-	((char*)dest)[i] =
-	    ((char*)&val)[sizeof(long long)/2 +
-			 ((i%2) ? ((i/2 * -1) - 1) : (i/2))];
-    }
-}
-
-
-void
-decode_int_serial(uint64_t src, uint64_t *dest)
-{
-    uint64_t val;
-    int i;
-
-    for (i = 0; i < sizeof(long long); i++) {
-	((char*)&val)[sizeof(long long)/2 +
-		     ((i%2) ? ((i/2 * -1) - 1) : (i/2))] =
-	    ((char*)&src)[i];
-    }
-
-    *dest = val - SN00_SERIAL_FUDGE;
-}
-
-
-void
-encode_str_serial(const char *src, char *dest)
-{
-    int i;
-
-    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
-
-	dest[i] = src[MAX_SERIAL_NUM_SIZE/2 +
-		     ((i%2) ? ((i/2 * -1) - 1) : (i/2))] +
-	    SN0_SERIAL_FUDGE;
-    }
-}
-
-void
-decode_str_serial(const char *src, char *dest)
-{
-    int i;
-
-    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
-	dest[MAX_SERIAL_NUM_SIZE/2 +
-	    ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = src[i] -
-	    SN0_SERIAL_FUDGE;
-    }
-}
-
-
-module_t *module_lookup(moduleid_t id)
-{
-    int			i;
-
-    for (i = 0; i < nummodules; i++)
-	if (modules[i]->id == id) {
-	    DPRINTF("module_lookup: found m=0x%p\n", modules[i]);
-	    return modules[i];
-	}
-
-    return NULL;
-}
-
-/*
- * module_add_node
- *
- *   The first time a new module number is seen, a module structure is
- *   inserted into the module list in order sorted by module number
- *   and the structure is initialized.
- *
- *   The node number is added to the list of nodes in the module.
- */
-
-module_t *module_add_node(moduleid_t id, cnodeid_t n)
-{
-    module_t	       *m;
-    int			i;
-    char		buffer[16];
-
-#ifdef __ia64
-    memset(buffer, 0, 16);
-    format_module_id(buffer, id, MODULE_FORMAT_BRIEF);
-    DPRINTF("module_add_node: id=%s node=%d\n", buffer, n);
-#endif
-
-    if ((m = module_lookup(id)) == 0) {
-#ifdef LATER
-	m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n);
-#else
-	m = kmalloc(sizeof (module_t), GFP_KERNEL);
-	memset(m, 0 , sizeof(module_t));
-#endif
-	ASSERT_ALWAYS(m);
-
-	m->id = id;
-	spin_lock_init(&m->lock);
-
-	mutex_init_locked(&m->thdcnt);
-
-// set_elsc(&m->elsc);
-	elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n));
-	spin_lock_init(&m->elsclock);
-
-	/* Insert in sorted order by module number */
-
-	for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--)
-	    modules[i] = modules[i - 1];
-
-	modules[i] = m;
-	nummodules++;
-    }
-
-    m->nodes[m->nodecnt++] = n;
-
-    DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt);
-
-    return m;
-}
-
-int module_probe_snum(module_t *m, nasid_t nasid)
-{
-    lboard_t	       *board;
-    klmod_serial_num_t *comp;
-    char * bcopy(const char * src, char * dest, int count);
-    char serial_number[16];
-
-    /*
-     * record brick serial number
-     */
-    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-
-    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
-    {
-#if	LDEBUG
-	printf ("module_probe_snum: no IP35 board found!\n");
-#endif
-	return 0;
-    }
-
-    board_serial_number_get( board, serial_number );
-    if( serial_number[0] != '\0' ) {
-	encode_str_serial( serial_number, m->snum.snum_str );
-	m->snum_valid = 1;
-    }
-#if	LDEBUG
-    else {
-	printf("module_probe_snum: brick serial number is null!\n");
-    }
-    printf("module_probe_snum: brick serial number == %s\n", serial_number);
-#endif /* DEBUG */
-
-    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
-			KLTYPE_IOBRICK_XBOW);
-
-    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
-	return 0;
-
-    comp = GET_SNUM_COMP(board);
-
-    if (comp) {
-#if LDEBUG
-	    int i;
-
-	    printf("********found module with id %x and string", m->id);
-
-	    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++)
-		printf(" %x ", comp->snum.snum_str[i]);
-
-	    printf("\n");	/* Fudged string is not ASCII */
-#endif
-
-	    if (comp->snum.snum_str[0] != '\0') {
-		bcopy(comp->snum.snum_str,
-		      m->sys_snum,
-		      MAX_SERIAL_NUM_SIZE);
-		m->sys_snum_valid = 1;
-	    }
-    }
-
-    if (m->sys_snum_valid)
-	return 1;
-    else {
-	DPRINTF("Invalid serial number for module %d, "
-		"possible missing or invalid NIC.", m->id);
-	return 0;
-    }
-}
-
-void
-io_module_init(void)
-{
-    cnodeid_t		node;
-    lboard_t	       *board;
-    nasid_t		nasid;
-    int			nserial;
-    module_t	       *m;
-
-    DPRINTF("*******module_init\n");
-
-    nserial = 0;
-
-    for (node = 0; node < numnodes; node++) {
-	nasid = COMPACT_TO_NASID_NODEID(node);
-
-	board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-	ASSERT(board);
-
-	m = module_add_node(board->brd_module, node);
-
-	if (! m->snum_valid && module_probe_snum(m, nasid))
-	    nserial++;
-    }
-
-    DPRINTF("********found total of %d serial numbers in the system\n",
-	    nserial);
-
-    if (nserial == 0)
-	printk(KERN_WARNING  "io_module_init: No serial number found.\n");
-}
-
-elsc_t *get_elsc(void)
-{
-	return &NODEPDA(cpuid_to_cnodeid(smp_processor_id()))->module->elsc;
-}
-
-int
-get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info)
-{
-    int i;
-
-    if (cmod < 0 || cmod >= nummodules)
-	return EINVAL;
-
-    if (! modules[cmod]->snum_valid)
-	return ENXIO;
-
-    mod_info->mod_num = modules[cmod]->id;
-    {
-	char temp[MAX_SERIAL_NUM_SIZE];
-
-	decode_str_serial(modules[cmod]->snum.snum_str, temp);
-
-	/* if this is an invalid serial number return an error */
-	if (temp[0] != 'K')
-	    return ENXIO;
-
-	mod_info->serial_num = 0;
-
-	for (i = 0; i < MAX_SERIAL_NUM_SIZE && temp[i] != '\0'; i++) {
-	    mod_info->serial_num <<= 4;
-	    mod_info->serial_num |= (temp[i] & 0xf);
-
-	    mod_info->serial_str[i] = temp[i];
-	}
-
-	mod_info->serial_str[i] = '\0';
-    }
-
-    return 0;
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/pci.c linux-2.4.22-pre3/arch/ia64/sn/io/pci.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/pci.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/pci.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,294 +0,0 @@
-/* 
- *
- * SNI64 specific PCI support for SNI IO.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1997, 1998, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <asm/sn/types.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/bridge.h>
-
-#ifdef DEBUG_CONFIG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-
-
-#ifdef CONFIG_PCI
-
-extern devfs_handle_t pci_bus_to_vertex(unsigned char);
-extern devfs_handle_t devfn_to_vertex(unsigned char bus, unsigned char devfn);
-
-/*
- * snia64_read_config_byte - Read a byte from the config area of the device.
- */
-static int snia64_read_config_byte (struct pci_dev *dev,
-                                   int where, unsigned char *val)
-{
-	unsigned long res = 0;
-	unsigned size = 1;
-	devfs_handle_t device_vertex;
-
-	if ( (dev == (struct pci_dev *)0) || (val == (unsigned char *)0) ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	res = pciio_config_get(device_vertex, (unsigned) where, size);
-	*val = (unsigned char) res;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_read_config_word - Read 2 bytes from the config area of the device.
- */
-static int snia64_read_config_word (struct pci_dev *dev,
-                                   int where, unsigned short *val)
-{
-	unsigned long res = 0;
-	unsigned size = 2; /* 2 bytes */
-	devfs_handle_t device_vertex;
-
-	if ( (dev == (struct pci_dev *)0) || (val == (unsigned short *)0) ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	res = pciio_config_get(device_vertex, (unsigned) where, size);
-	*val = (unsigned short) res;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_read_config_dword - Read 4 bytes from the config area of the device.
- */
-static int snia64_read_config_dword (struct pci_dev *dev,
-                                    int where, unsigned int *val)
-{
-	unsigned long res = 0;
-	unsigned size = 4; /* 4 bytes */
-	devfs_handle_t device_vertex;
-
-	if (where & 3) {
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-	if ( (dev == (struct pci_dev *)0) || (val == (unsigned int *)0) ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	res = pciio_config_get(device_vertex, (unsigned) where, size);
-	*val = (unsigned int) res;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_write_config_byte - Writes 1 byte to the config area of the device.
- */
-static int snia64_write_config_byte (struct pci_dev *dev,
-                                    int where, unsigned char val)
-{
-	devfs_handle_t device_vertex;
-
-	if ( dev == (struct pci_dev *)0 ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3 )
-		return PCIBIOS_SUCCESSFUL;
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	pciio_config_set( device_vertex, (unsigned)where, 1, (uint64_t) val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_write_config_word - Writes 2 bytes to the config area of the device.
- */
-static int snia64_write_config_word (struct pci_dev *dev,
-                                    int where, unsigned short val)
-{
-	devfs_handle_t device_vertex = NULL;
-
-	if (where & 1) {
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-	if ( dev == (struct pci_dev *)0 ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
-		return PCIBIOS_SUCCESSFUL;
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	pciio_config_set( device_vertex, (unsigned)where, 2, (uint64_t) val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_write_config_dword - Writes 4 bytes to the config area of the device.
- */
-static int snia64_write_config_dword (struct pci_dev *dev,
-                                     int where, unsigned int val)
-{
-	devfs_handle_t device_vertex;
-
-	if (where & 3) {
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-	if ( dev == (struct pci_dev *)0 ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
-		return PCIBIOS_SUCCESSFUL;
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	pciio_config_set( device_vertex, (unsigned)where, 4, (uint64_t) val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops snia64_pci_ops = {
-	snia64_read_config_byte,
-	snia64_read_config_word,
-	snia64_read_config_dword,
-	snia64_write_config_byte,
-	snia64_write_config_word,
-	snia64_write_config_dword
-};
-
-/*
- * snia64_pci_find_bios - SNIA64 pci_find_bios() platform specific code.
- */
-void __init
-sn_pci_find_bios(void)
-{
-	extern struct pci_ops *pci_root_ops;
-	/*
-	 * Go initialize our IO Infrastructure ..
-	 */
-	extern void sgi_master_io_infr_init(void);
-
-	sgi_master_io_infr_init();
-
-	/* sn_io_infrastructure_init(); */
-	pci_root_ops = &snia64_pci_ops;
-}
-
-void
-pci_fixup_ioc3(struct pci_dev *d)
-{
-        int 		i;
-	unsigned int 	size;
-
-        /* IOC3 only decodes 0x20 bytes of the config space, reading
-	 * beyond that is relatively benign but writing beyond that
-	 * (especially the base address registers) will shut down the
-	 * pci bus...so avoid doing so.
-	 * NOTE: this means we can't program the intr_pin into the device,
-	 *       currently we hack this with special code in 
-	 *	 sgi_pci_intr_support()
-	 */
-        DBG("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name);
-
-	/* I happen to know from the spec that the ioc3 needs only 0xfffff 
-	 * The standard pci trick of writing ~0 to the baddr and seeing
-	 * what comes back doesn't work with the ioc3
-	 */
-	size = 0xfffff;
-	d->resource[0].end = (unsigned long) d->resource[0].start + (unsigned long) size;
-
-	/*
-	 * Zero out the resource structure .. because we did not go through 
-	 * the normal PCI Infrastructure Init, garbbage are left in these 
-	 * fileds.
-	 */
-        for (i = 1; i <= PCI_ROM_RESOURCE; i++) {
-                d->resource[i].start = 0UL;
-                d->resource[i].end = 0UL;
-                d->resource[i].flags = 0UL;
-        }
-
-#ifdef CONFIG_IA64_SGI_SN1
-	*(volatile u32 *)0xc0000a000f000220 |= 0x90000;
-#endif
-        d->subsystem_vendor = 0;
-        d->subsystem_device = 0;
-
-}
-
-#else
-void sn_pci_find_bios(void) {}
-void pci_fixup_ioc3(struct pci_dev *d) {}
-struct list_head pci_root_buses;
-struct list_head pci_root_buses;
-struct list_head pci_devices;
-
-#endif /* CONFIG_PCI */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/pci_bus_cvlink.c linux-2.4.22-pre3/arch/ia64/sn/io/pci_bus_cvlink.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/pci_bus_cvlink.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/pci_bus_cvlink.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,743 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <asm/sn/types.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/sn_cpuid.h>
-
-extern int bridge_rev_b_data_check_disable;
-
-devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
-nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
-void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
-unsigned char num_bridges;
-static int done_probing = 0;
-
-static int pci_bus_map_create(devfs_handle_t xtalk);
-devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-#define SN_IOPORTS_UNIT 256
-#define MAX_IOPORTS 0xffff
-#define MAX_IOPORTS_CHUNKS (MAX_IOPORTS / SN_IOPORTS_UNIT)
-struct ioports_to_tlbs_s ioports_to_tlbs[MAX_IOPORTS_CHUNKS];
-unsigned long sn_allocate_ioports(unsigned long pci_address);
-
-extern void sn_init_irq_desc(void);
-
-
-
-/*
- * pci_bus_cvlink_init() - To be called once during initialization before 
- *	SGI IO Infrastructure init is called.
- */
-void
-pci_bus_cvlink_init(void)
-{
-	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET);
-	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
-
-	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
-
-	memset(ioports_to_tlbs, 0x0, sizeof(ioports_to_tlbs));
-
-	num_bridges = 0;
-}
-
-/*
- * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
- *	pci bus vertex from the SGI IO Infrastructure.
- */
-devfs_handle_t
-pci_bus_to_vertex(unsigned char busnum)
-{
-
-	devfs_handle_t	pci_bus = NULL;
-
-
-	/*
-	 * First get the xwidget vertex.
-	 */
-	pci_bus = busnum_to_pcibr_vhdl[busnum];
-	return(pci_bus);
-}
-
-/*
- * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
- *	and function numbers.
- */
-devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn)
-{
-
-	int slot = 0;
-	int func = 0;
-	char	name[16];
-	devfs_handle_t  pci_bus = NULL;
-	devfs_handle_t	device_vertex = (devfs_handle_t)NULL;
-
-	/*
-	 * Go get the pci bus vertex.
-	 */
-	pci_bus = pci_bus_to_vertex(busnum);
-	if (!pci_bus) {
-		/*
-		 * During probing, the Linux pci code invents non-existent
-		 * bus numbers and pci_dev structures and tries to access
-		 * them to determine existence. Don't crib during probing.
-		 */
-		if (done_probing)
-			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
-		return(NULL);
-	}
-
-
-	/*
-	 * Go get the slot&function vertex.
-	 * Should call pciio_slot_func_to_name() when ready.
-	 */
-	slot = PCI_SLOT(devfn);
-	func = PCI_FUNC(devfn);
-
-	/*
-	 * For a NON Multi-function card the name of the device looks like:
-	 * ../pci/1, ../pci/2 ..
-	 */
-	if (func == 0) {
-        	sprintf(name, "%d", slot);
-		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
-			GRAPH_SUCCESS) {
-			if (device_vertex) {
-				return(device_vertex);
-			}
-		}
-	}
-			
-	/*
-	 * This maybe a multifunction card.  It's names look like:
-	 * ../pci/1a, ../pci/1b, etc.
-	 */
-	sprintf(name, "%d%c", slot, 'a'+func);
-	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
-		if (!device_vertex) {
-			return(NULL);
-		}
-	}
-
-	return(device_vertex);
-}
-
-/*
- * For the given device, initialize the addresses for both the Device(x) Flush 
- * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
- * is connected.
- */
-static void
-set_flush_addresses(struct pci_dev *device_dev, 
-	struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	device_sysdata->dma_buf_sync = (volatile unsigned int *) 
-		&(bridge->b_wr_req_buf[pciio_slot].reg);
-	device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-		XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(get_nasid(), 0), 
-		pcibr_soft->bs_xid);
-#ifdef DEBUG
-
-	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
-		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
-
-	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
-	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
-#endif
-
-}
-
-/*
- * Most drivers currently do not properly tell the arch specific pci dma
- * interfaces whether they can handle A64. Here is where we privately
- * keep track of this.
- */
-static void __init
-set_sn_pci64(struct pci_dev *dev)
-{
-	unsigned short vendor = dev->vendor;
-	unsigned short device = dev->device;
-
-	if (vendor == PCI_VENDOR_ID_QLOGIC) {
-		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
-				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-	if (vendor == PCI_VENDOR_ID_SGI) {
-		if (device == PCI_DEVICE_ID_SGI_IOC3) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-}
-
-/*
- * sn_allocate_ioports() - This routine provides the allocation and 
- *	mappings between Linux style IOPORTs management.
- *
- *	For simplicity sake, SN1 will allocate IOPORTs in chunks of 
- *	256bytes .. irrespective of what the card desires.  This may 
- *	have to change when we understand how to deal with legacy ioports 
- *	which are hardcoded in some drivers e.g. SVGA.
- *
- *	Ofcourse, the SN1 IO Infrastructure has no concept of IOPORT numbers.
- *	It will remain so.  The IO Infrastructure will continue to map 
- *	IO Resource just like IRIX.  When this is done, we map IOPORT 
- *	chunks to these resources.  The Linux drivers will see and use real 
- *	IOPORT numbers.  The various IOPORT access macros e.g. inb/outb etc. 
- *	does the munging of these IOPORT numbers to make a Uncache Virtual 
- *	Address.  This address via the tlb entries generates the PCI Address 
- *	allocated by the SN1 IO Infrastructure Layer.
- */
-static unsigned long sn_ioport_num = 0x1000; /* Reserve room for Legacy stuff */
-unsigned long
-sn_allocate_ioports(unsigned long pci_address)
-{
-	
-	unsigned long ioport_index;
-
-	/*
-	 * Just some idiot checking ..
-	 */
-	if ( sn_ioport_num > 0xffff ) {
-		printk("sn_allocate_ioports: No more IO PORTS available\n");
-		return(-1);
-	}
-
-	/*
-	 * See Section 4.1.1.5 of Intel IA-64 Acrchitecture Software Developer's
-	 * Manual for details.
-	 */
-	ioport_index = sn_ioport_num / SN_IOPORTS_UNIT;
-
-	ioports_to_tlbs[ioport_index].p = 1; /* Present Bit */
-	ioports_to_tlbs[ioport_index].rv_1 = 0; /* 1 Bit */
-	ioports_to_tlbs[ioport_index].ma = 4; /* Memory Attributes 3 bits*/
-	ioports_to_tlbs[ioport_index].a = 1; /* Set Data Access Bit Fault 1 Bit*/
-	ioports_to_tlbs[ioport_index].d = 1; /* Dirty Bit */
-	ioports_to_tlbs[ioport_index].pl = 0;/* Privilege Level - All levels can R/W*/
-	ioports_to_tlbs[ioport_index].ar = 3; /* Access Rights - R/W only*/
-	ioports_to_tlbs[ioport_index].ppn = pci_address >> 12; /* 4K page size */
-	ioports_to_tlbs[ioport_index].ed = 0; /* Exception Deferral Bit */
-	ioports_to_tlbs[ioport_index].ig = 0; /* Ignored */
-
-	/* printk("sn_allocate_ioports: ioport_index 0x%x ioports_to_tlbs 0x%p\n", ioport_index, ioports_to_tlbs[ioport_index]); */
-	
-	sn_ioport_num += SN_IOPORTS_UNIT;
-
-	return(sn_ioport_num - SN_IOPORTS_UNIT);
-}
-
-/*
- * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
- *	invoked at the end of pcibios_init() to link the Linux pci 
- *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
- *
- *	Other platform specific fixup can also be done here.
- */
-void
-sn_pci_fixup(int arg)
-{
-	struct list_head *ln;
-	struct pci_bus *pci_bus = NULL;
-	struct pci_dev *device_dev = NULL;
-	struct sn_widget_sysdata *widget_sysdata;
-	struct sn_device_sysdata *device_sysdata;
-#ifdef SN_IOPORTS
-	unsigned long ioport;
-#endif
-	pciio_intr_t intr_handle;
-	int cpuid, bit;
-	devfs_handle_t device_vertex;
-	pciio_intr_line_t lines;
-	extern void sn_pci_find_bios(void);
-#ifdef CONFIG_IA64_SGI_SN2
-	extern int numnodes;
-	int cnode;
-#endif /* CONFIG_IA64_SGI_SN2 */
-
-
-	if (arg == 0) {
-		sn_init_irq_desc();
-		sn_pci_find_bios();
-#ifdef CONFIG_IA64_SGI_SN2
-		for (cnode = 0; cnode < numnodes; cnode++) {
-				extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
-				intr_init_vecblk(NODEPDA(cnode), cnode, 0);
-		} 
-#endif /* CONFIG_IA64_SGI_SN2 */
-		return;
-	}
-
-#if 0
-{
-        devfs_handle_t  bridge_vhdl = pci_bus_to_vertex(0);
-        pcibr_soft_t    pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl);
-	bridge_t        *bridge = pcibr_soft->bs_base;
-        printk("pci_fixup_ioc3: Before devreg fixup\n");
-        printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg);
-        printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg);
-        printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg);
-        printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg);
-        printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg);
-        printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg);
-        printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg);
-        printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg);
-}
-#endif
-	done_probing = 1;
-
-	/*
-	 * Initialize the pci bus vertex in the pci_bus struct.
-	 */
-	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		pci_bus = pci_bus_b(ln);
-		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
-					GFP_KERNEL);
-		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
-		pci_bus->sysdata = (void *)widget_sysdata;
-	}
-
-	/*
- 	 * set the root start and end so that drivers calling check_region()
-	 * won't see a conflict
-	 */
-#ifdef SN_IOPORTS
-	ioport_resource.start  = sn_ioport_num;
-	ioport_resource.end = 0xffff;
-#else
-#if defined(CONFIG_IA64_SGI_SN1)
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		/*
-		 * IDE legacy IO PORTs are supported in Medusa.
-		 * Just open up IO PORTs from 0 .. ioport_resource.end.
-		 */
-		ioport_resource.start = 0;
-	} else {
-		/*
-		 * We do not support Legacy IO PORT numbers.
-		 */
-		ioport_resource.start |= IO_SWIZ_BASE | __IA64_UNCACHED_OFFSET;
-	}
-	ioport_resource.end |= (HSPEC_SWIZ_BASE-1) | __IA64_UNCACHED_OFFSET;
-#else
-	// Need something here for sn2.... ZXZXZX
-#endif
-#endif
-
-	/*
-	 * Set the root start and end for Mem Resource.
-	 */
-	iomem_resource.start = 0;
-	iomem_resource.end = 0xffffffffffffffff;
-
-	/*
-	 * Initialize the device vertex in the pci_dev struct.
-	 */
-	pci_for_each_dev(device_dev) {
-		unsigned int irq;
-		int idx;
-		u16 cmd;
-		devfs_handle_t vhdl;
-		unsigned long size;
-		extern int bit_pos_to_irq(int);
-
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
-			extern void pci_fixup_ioc3(struct pci_dev *d);
-			pci_fixup_ioc3(device_dev);
-		}
-
-		/* Set the device vertex */
-
-		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
-					GFP_KERNEL);
-		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
-		device_sysdata->isa64 = 0;
-		/*
-		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
-		 * register addresses.
-		 */
-		(void) set_flush_addresses(device_dev, device_sysdata);
-
-		device_dev->sysdata = (void *) device_sysdata;
-		set_sn_pci64(device_dev);
-		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
-
-		/*
-		 * Set the resources address correctly.  The assumption here 
-		 * is that the addresses in the resource structure has been
-		 * read from the card and it was set in the card by our
-		 * Infrastructure ..
-		 */
-		vhdl = device_sysdata->vhdl;
-		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
-			size = 0;
-			size = device_dev->resource[idx].end -
-				device_dev->resource[idx].start;
-			if (size) {
-				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, PCIIO_BYTE_STREAM);
-				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
-			}
-			else
-				continue;
-
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].start + size;
-
-#ifdef CONFIG_IA64_SGI_SN1
-			/*
-			 * Adjust the addresses to go to the SWIZZLE ..
-			 */
-			device_dev->resource[idx].start = 
-				device_dev->resource[idx].start & 0xfffff7ffffffffff;
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].end & 0xfffff7ffffffffff;
-#endif
-
-			if (device_dev->resource[idx].flags & IORESOURCE_IO) {
-				cmd |= PCI_COMMAND_IO;
-#ifdef SN_IOPORTS
-				ioport = sn_allocate_ioports(device_dev->resource[idx].start);
-				if (ioport < 0) {
-					printk("sn_pci_fixup: PCI Device 0x%x on PCI Bus %d not mapped to IO PORTs .. IO PORTs exhausted\n", device_dev->devfn, device_dev->bus->number);
-					continue;
-				}
-				pciio_config_set(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + (idx * 4), 4, (res + (ioport & 0xfff)));
-
-printk("sn_pci_fixup: ioport number %d mapped to pci address 0x%lx\n", ioport, (res + (ioport & 0xfff)));
-
-				device_dev->resource[idx].start = ioport;
-				device_dev->resource[idx].end = ioport + SN_IOPORTS_UNIT;
-#endif
-			}
-			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
-				cmd |= PCI_COMMAND_MEMORY;
-		}
-		/*
-		 * Now handle the ROM resource ..
-		 */
-		size = device_dev->resource[PCI_ROM_RESOURCE].end -
-			device_dev->resource[PCI_ROM_RESOURCE].start;
-
-		if (size) {
-			device_dev->resource[PCI_ROM_RESOURCE].start =
-			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
-				size, 0, PCIIO_BYTE_STREAM);
-			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
-			device_dev->resource[PCI_ROM_RESOURCE].end =
-			device_dev->resource[PCI_ROM_RESOURCE].start + size;
-
-#ifdef CONFIG_IA64_SGI_SN1
-                	/*
-                 	 * go through synergy swizzled space
-                 	 */
-			device_dev->resource[PCI_ROM_RESOURCE].start &= 0xfffff7ffffffffffUL;
-			device_dev->resource[PCI_ROM_RESOURCE].end   &= 0xfffff7ffffffffffUL;
-#endif
-
-		}
-
-		/*
-		 * Update the Command Word on the Card.
-		 */
-		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
-					   /* bit gets dropped .. no harm */
-		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
-
-		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-				lines = 1;
-		}
- 
-		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
-		device_vertex = device_sysdata->vhdl;
- 
-		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
-
-		bit = intr_handle->pi_irq;
-		cpuid = intr_handle->pi_cpu;
-#ifdef CONFIG_IA64_SGI_SN1
-		irq = bit_pos_to_irq(bit);
-#else /* SN2 */
-		irq = bit;
-#endif
-		irq = irq + (cpuid << 8);
-		pciio_intr_connect(intr_handle);
-		device_dev->irq = irq;
-#ifdef ajmtestintr
-		{
-			int slot = PCI_SLOT(device_dev->devfn);
-			static int timer_set = 0;
-			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
-			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
-			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
-
-			if (!timer_set) {
-				intr_test_set_timer();
-				timer_set = 1;
-			}
-			intr_test_register_irq(irq, pcibr_soft, slot);
-			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
-		}
-#endif
-
-	}
-
-#if 0
-
-{
-        devfs_handle_t  bridge_vhdl = pci_bus_to_vertex(0);
-        pcibr_soft_t    pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl);
-        bridge_t        *bridge = pcibr_soft->bs_base;
-
-        printk("pci_fixup_ioc3: Before devreg fixup\n");
-        printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg);
-        printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg);
-        printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg);
-        printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg);
-        printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg);
-        printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg);
-        printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg);
-        printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg);
-}
-
-printk("testing Big Window: 0xC0000200c0000000 %p\n", *( (volatile uint64_t *)0xc0000200a0000000));
-printk("testing Big Window: 0xC0000200c0000008 %p\n", *( (volatile uint64_t *)0xc0000200a0000008));
-
-#endif
-
-}
-
-/*
- * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
- *
- *	Linux PCI Bus numbers are assigned from lowest module_id numbers
- *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
- *	HUB_WIDGET_ID_MIN:
- *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
- *
- *	Given 2 modules 001c01 and 001c02 we get the following mappings:
- *		001c01, widgetnum 15 = Bus number 0
- *		001c01, widgetnum 14 = Bus number 1
- *		001c02, widgetnum 15 = Bus number 3
- *		001c02, widgetnum 14 = Bus number 4
- *		etc.
- *
- * The rational for starting Bus Number 0 with Widget number 15 is because 
- * the system boot disks are always connected via Widget 15 Slot 0 of the 
- * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
- * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
- * module id(Master Cnode) of the system.
- *	
- */
-static int 
-pci_bus_map_create(devfs_handle_t xtalk)
-{
-
-	devfs_handle_t master_node_vertex = NULL;
-	devfs_handle_t xwidget = NULL;
-	devfs_handle_t pci_bus = NULL;
-	hubinfo_t hubinfo = NULL;
-	xwidgetnum_t widgetnum;
-	char pathname[128];
-	graph_error_t rv;
-
-	/*
-	 * Loop throught this vertex and get the Xwidgets ..
-	 */
-	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
-#if 0
-        {
-                int pos;
-                char dname[256];
-                pos = devfs_generate_path(xtalk, dname, 256);
-                printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-        }
-#endif
-
-		sprintf(pathname, "%d", widgetnum);
-		xwidget = NULL;
-		
-		/*
-		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
-		 */
-		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-		if ( (rv != GRAPH_SUCCESS) ) {
-			if (!xwidget)
-				continue;
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		pci_bus = NULL;
-		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-			if (!pci_bus)
-				continue;
-
-		/*
-		 * Assign the correct bus number and also the nasid of this 
-		 * pci Xwidget.
-		 * 
-		 * Should not be any race here ...
-		 */
-		num_bridges++;
-		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
-
-		/*
-		 * Get the master node and from there get the NASID.
-		 */
-		master_node_vertex = device_master_get(xwidget);
-		if (!master_node_vertex) {
-			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
-		}
-	
-		hubinfo_get(master_node_vertex, &hubinfo);
-		if (!hubinfo) {
-			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
-			return(1);
-		} else {
-			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
-		}
-
-		/*
-		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-		 */
-		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-		if (!busnum_to_atedmamaps[num_bridges - 1])
-			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-
-		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
-
-	}
-
-        return(0);
-}
-
-/*
- * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
- *      initialization has completed to set up the mappings between Xbridge
- *      and logical pci bus numbers.  We also set up the NASID for each of these
- *      xbridges.
- *
- *      Must be called before pci_init() is invoked.
- */
-int
-pci_bus_to_hcl_cvlink(void) 
-{
-
-	devfs_handle_t devfs_hdl = NULL;
-	devfs_handle_t xtalk = NULL;
-	int rv = 0;
-	char name[256];
-	int master_iobrick;
-	int i;
-
-	/*
-	 * Iterate throught each xtalk links in the system ..
-	 * /hw/module/001c01/node/xtalk/ 8|9|10|11|12|13|14|15 
-	 *
-	 * /hw/module/001c01/node/xtalk/15 -> /hw/module/001c01/Ibrick/xtalk/15
-	 *
-	 * What if it is not pci?
-	 */
-	devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");
-
-	/*
-	 * To provide consistent(not persistent) device naming, we need to start 
-	 * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 
-	 * with an attached I-Brick.  Find the master_iobrick.
-	 */
-	master_iobrick = -1;
-	for (i = 0; i < nummodules; i++) {
-		moduleid_t iobrick_id; 
-		iobrick_id = iobrick_module_get(&modules[i]->elsc);
-		if (iobrick_id > 0) { /* Valid module id */
-			if (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) {
-				master_iobrick = i;
-				break;
-			}
-		}
-	}
-
-	/*
-	 * The master_iobrick gets bus 0 and 1.
-	 */
-	if (master_iobrick >= 0) {
-		memset(name, 0, 256);
-		format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF);
-		strcat(name, "/node/xtalk");
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-		
-	/*
-	 * Now go do the rest of the modules, starting from the C-Brick with the lowest 
-	 * module id, remembering to skip the master_iobrick, which was done above.
-	 */
-	for (i = 0; i < nummodules; i++) {
-		if (i == master_iobrick) {
-			continue; /* Did the master_iobrick already. */
-		}
-
-		memset(name, 0, 256);
-		format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
-		strcat(name, "/node/xtalk");
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-
-	return(0);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/pci_dma.c linux-2.4.22-pre3/arch/ia64/sn/io/pci_dma.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/pci_dma.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/pci_dma.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,700 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000,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/config.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#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>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/types.h>
-#include <asm/sn/alenlist.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/nag.h>
-
-/*
- * For ATE allocations
- */
-pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
-void free_pciio_dmamap(pcibr_dmamap_t);
-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_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)
-{
-	int i;
-	struct sn_dma_maps_s *sn_dma_map = NULL;
-
-	/*
-	 * Darn, we need to get the maps allocated for this bus.
-	 */
-	for (i = 0; i < MAX_PCI_XWIDGET; i++) {
-		if (busnum_to_pcibr_vhdl[i] == pci_bus) {
-			sn_dma_map = busnum_to_atedmamaps[i];
-		}
-	}
-
-	/*
-	 * Now get a free dmamap entry from this list.
-	 */
-	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;
-}
-
-/**
- * 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)
-{
-	struct sn_dma_maps_s *sn_dma_map;
-
-	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;
-		}
-	}
-
-	return NULL;
-}
-
-/**
- * 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)
-{
-
-#ifdef SN_DMA_SYNC
-
-	struct sn_device_sysdata *device_sysdata;
-	volatile unsigned long dummy;
-
-	/*
-	 * A DMA sync is supposed to ensure 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 may be denied the request because 
-	 * someone else may be flushing the port .. try again.
-	 */
-	while((volatile unsigned long ) *device_sysdata->xbow_buf_sync) {
-		udelay(2);
-	}
-#endif
-}
-
-/**
- * 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 %PCIIO_DMA_CMD flag set.
- *
- * 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 will always put a 32 bit
- * DMA address into @dma_handle.  This is because most devices
- * 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)
-{
-        void *cpuaddr;
-	devfs_handle_t vhdl;
-	struct sn_device_sysdata *device_sysdata;
-	unsigned long phys_addr;
-	pciio_dmamap_t dma_map = 0;
-	struct sn_dma_maps_s *sn_dma_map;
-
-	*dma_handle = 0;
-
-	/* We can't easily support < 32 bit devices */
-	if (IS_PCI32L(hwdev))
-		return NULL;
-
-	/*
-	 * Get hwgraph vertex for the device
-	 */
-	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
-	vhdl = device_sysdata->vhdl;
-
-	/*
-	 * 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;
-
-	memset(cpuaddr, 0, size); /* have to zero it out */
-
-	/* physical addr. of the memory we just got */
-	phys_addr = __pa(cpuaddr);
-
-	/*
-	 * This will try to use a Direct Map register to do the
-	 * 32 bit DMA mapping, but it may not succeed if another
-	 * device on the same bus is already mapped with different
-	 * attributes or to a different memory region.
-	 */
-#ifdef CONFIG_IA64_SGI_SN1
-	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-					  PCIIO_BYTE_STREAM |
-					  PCIIO_DMA_CMD);
-#elif defined(CONFIG_IA64_SGI_SN2)
-	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					  PCIIO_DMA_CMD);
-#else
-#error unsupported platform
-#endif
-
-	/*
-	 * It is a 32 bit card and we cannot do direct mapping,
-	 * so we try to use an ATE.
-	 */
-	if (!(*dma_handle)) {
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
-					     PCIIO_BYTE_STREAM |
-					     PCIIO_DMA_CMD);
-#elif defined(CONFIG_IA64_SGI_SN2)
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
-				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					     PCIIO_DMA_CMD);
-#else
-#error unsupported platform
-#endif
-		if (!dma_map) {
-			printk(KERN_ERR "sn_pci_alloc_consistent: Unable to "
-			       "allocate anymore 32 bit page map entries.\n");
-			BUG();
-		}
-		*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;
-	}
-
-        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));
-}
-
-/**
- * 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)
-{
-
-	int i;
-	devfs_handle_t vhdl;
-	dma_addr_t dma_addr;
-	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();
-
-	/*
-	 * 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
-                   previously mapped.  we print a warning and
-                   continue, but the driver should be fixed */
-		switch (((u64)sg->address) >> 60) {
-		case 0xa:
-		case 0xb:
-#ifdef DEBUG
-/* This needs to be cleaned up at some point. */
-			NAG("A PCI driver (for device at%8s) has attempted to "
-			    "map a scatterlist that was previously mapped at "
-			    "%p - this is currently being worked around.\n",
-			    hwdev->slot_name, (void *)sg->address);
-#endif
-			phys_addr = (u64)sg->address & TO_PHYS_MASK;
-			break;
-		default: /* not previously mapped, get the phys. addr */
-			phys_addr = __pa(sg->address);
-			break;
-		}
-		sg->page = NULL;
-		dma_addr = 0;
-
-		/*
-		 * Handle the most common case: 64 bit cards.  This
-		 * call should always succeed.
-		 */
-		if (IS_PCIA64(hwdev)) {
-			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length,
-			       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-						       PCIIO_DMA_DATA |
-						       PCIIO_DMA_A64);
-			sg->address = (char *)dma_addr;
-			continue;
-		}
-
-		/*
-		 * Handle 32-63 bit cards via direct mapping
-		 */
-		if (IS_PCI32G(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length,
-						       PCIIO_BYTE_STREAM |
-						       PCIIO_DMA_DATA);
-#elif defined(CONFIG_IA64_SGI_SN2)
-			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length,
-					((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-						       PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-			/*
-			 * See if we got a direct map entry
-			 */
-			if (dma_addr) {
-				sg->address = (char *)dma_addr;
-				continue;
-			}
-
-		}
-
-		/*
-		 * It is a 32 bit card and we cannot do direct mapping,
-		 * so we use an ATE.
-		 */
-		dma_map = 0;
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
-					     PCIIO_BYTE_STREAM |
-					     PCIIO_DMA_DATA);
-#elif defined(CONFIG_IA64_SGI_SN2)
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
-				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					     PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-		if (!dma_map) {
-			printk(KERN_ERR "sn_pci_map_sg: Unable to allocate "
-			       "anymore 32 bit page map entries.\n");
-			BUG();
-		}
-		dma_addr = pciio_dmamap_addr(dma_map, phys_addr, sg->length);
-		sg->address = (char *)dma_addr;
-		sg->page = (struct page *)dma_map;
-		
-	}
-
-	return nents;
-
-}
-
-/**
- * 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 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 < nents; i++, sg++)
-		if (sg->page) {
-			/*
-			 * We maintain the DMA Map pointer in sg->page if 
-			 * it is ever allocated.
-			 */
-			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);
-			sn_dma_map->dma_addr = 0;
-			sg->page = 0;
-		}
-
-}
-
-/**
- * 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
- * (which is pretty much unacceptable).
- *
- * TODO: simplify our interface;
- *       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)
-{
-	devfs_handle_t vhdl;
-	dma_addr_t dma_addr;
-	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
-	 */
-	device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata;
-	vhdl = device_sysdata->vhdl;
-
-	/*
-	 * Call our dmamap interface
-	 */
-	dma_addr = 0;
-	phys_addr = __pa(ptr);
-
-	if (IS_PCIA64(hwdev)) {
-		/* This device supports 64 bit DMA addresses. */
-		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-		       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					       PCIIO_DMA_DATA |
-					       PCIIO_DMA_A64);
-		return dma_addr;
-	}
-
-	/*
-	 * Devices that support 32 bit to 63 bit DMA addresses get
-	 * 32 bit DMA addresses.
-	 *
-	 * First try to get a 32 bit direct map register.
-	 */
-	if (IS_PCI32G(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-					       PCIIO_BYTE_STREAM |
-					       PCIIO_DMA_DATA);
-#elif defined(CONFIG_IA64_SGI_SN2)
-		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					       PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-		if (dma_addr)
-			return dma_addr;
-	}
-
-	/*
-	 * 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);
-#elif defined(CONFIG_IA64_SGI_SN2)
-	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, 
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-			PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-
-	if (!dma_map) {
-		printk(KERN_ERR "pci_map_single: Unable to allocate anymore "
-		       "32 bit page map entries.\n");
-		BUG();
-	}
-
-	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)
-{
-	struct sn_dma_maps_s *sn_dma_map = NULL;
-
-        if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/*
-	 * Get the sn_dma_map entry.
-	 */
-	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)
-{
-	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 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)
-{
-	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 when using the PMU.  We could theoretically support <32 bit
- * cards using direct mapping, but we'll worry about that later--on the off
- * chance that someone actually wants to use such a card.
- */
-int
-sn_pci_dma_supported(struct pci_dev *hwdev, u64 mask)
-{
-	if (mask < 0xffffffff)
-		return 0;
-	return 1;
-}
-
-EXPORT_SYMBOL(sn_pci_unmap_single);
-EXPORT_SYMBOL(sn_pci_map_single);
-EXPORT_SYMBOL(sn_pci_dma_sync_single);
-EXPORT_SYMBOL(sn_pci_map_sg);
-EXPORT_SYMBOL(sn_pci_unmap_sg);
-EXPORT_SYMBOL(sn_pci_alloc_consistent);
-EXPORT_SYMBOL(sn_pci_free_consistent);
-EXPORT_SYMBOL(sn_dma_address);
-EXPORT_SYMBOL(sn_pci_dma_supported);
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/pciba.c linux-2.4.22-pre3/arch/ia64/sn/io/pciba.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/pciba.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/pciba.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,916 +0,0 @@
-/*
- * arch/ia64/sn/io/pciba.c
- *
- * IRIX PCIBA-inspired user mode PCI interface
- *
- * requires: devfs
- *
- * device nodes show up in /dev/pci/BB/SS.F (where BB is the bus the
- * device is on, SS is the slot the device is in, and F is the
- * device's function on a multi-function card).
- *
- * when compiled into the kernel, it will only be initialized by the
- * sgi sn1 specific initialization code.  in this case, device nodes
- * are under /dev/hw/..../
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License.  See the file "COPYING" in the main directory of
- * this archive for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
- *
- * 03262001 - Initial version by Chad Talbott
- */
-
-
-/* jesse's beefs:
-
-   register_pci_device should be documented
-   
-   grossness with do_swap should be documented
-   
-   big, gross union'ized node_data should be replaced with independent
-   structures
-
-   replace global list of nodes with global lists of resources.  could
-   use object oriented approach of allocating and cleaning up
-   resources.
-   
-*/
-
-
-#include <linux/config.h>
-#ifndef CONFIG_DEVFS_FS
-#  error PCIBA requires devfs
-#endif
-
-#include <linux/module.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/pci.h>
-#include <linux/list.h>
-
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/mman.h>
-#include <linux/init.h>
-#include <linux/raw.h>
-#include <linux/capability.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/pgalloc.h>
-#include <asm/page.h>
-
-#include <asm/sn/pci/pciba.h>
-
-
-MODULE_DESCRIPTION("User mode PCI interface");
-MODULE_AUTHOR("Chad Talbott");
-
-
-#undef DEBUG_PCIBA
-/* #define DEBUG_PCIBA */
-
-#undef TRACE_PCIBA
-/* #define TRACE_PCIBA */
-
-#if defined(DEBUG_PCIBA)
-#  define DPRINTF(x...) printk(KERN_DEBUG x)
-#else
-#  define DPRINTF(x...)
-#endif
-
-#if defined(TRACE_PCIBA)
-#  if defined(__GNUC__)
-#    define TRACE()	printk(KERN_DEBUG "%s:%d:%s\n", \
-			       __FILE__, __LINE__, __FUNCTION__)
-#  else
-#    define TRACE()	printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__)
-#  endif
-#else
-#  define TRACE()
-#endif
-
-
-typedef enum { failure, success } status;
-typedef enum { false, true } boolean;
-
-
-/* major data structures:
-
-   struct node_data -
-   
-   	one for each file registered with devfs.  contains everything
-   	that any file's fops would need to know about.
-
-   struct dma_allocation -
-
-   	a single DMA allocation.  only the 'dma' nodes care about
-   	these.  they are there primarily to allow the driver to look
-   	up the kernel virtual address of dma buffers allocated by
-   	pci_alloc_consistent, as the application is only given the
-   	physical address (to program the device's dma, presumably) and
-   	cannot supply the kernel virtual address when freeing the
-   	buffer.
-
-	it's also useful to maintain a list of buffers allocated
-	through a specific node to allow some sanity checking by this
-	driver.  this prevents (for example) a broken application from
-	freeing buffers that it didn't allocate, or buffers allocated
-	on another node.
-   
-   global_node_list -
-
-   	a list of all nodes allocated.  this allows the driver to free
-   	all the memory it has 'kmalloc'd in case of an error, or on
-   	module removal.
-
-   global_dma_list -
-
-        a list of all dma buffers allocated by this driver.  this
-	allows the driver to 'pci_free_consistent' all buffers on
-	module removal or error.
-
-*/
-
-
-struct node_data {
-	/* flat list of all the device nodes.  makes it easy to free
-	   them all when we're unregistered */
-	struct list_head global_node_list;
-	devfs_handle_t devfs_handle;
-
-	void (* cleanup)(struct node_data *);
-
-	union {
-		struct {
-			struct pci_dev * dev;
-			struct list_head dma_allocs;
-			boolean mmapped;
-		} dma;
-		struct {
-			struct pci_dev * dev;
-			u32 saved_rom_base_reg;
-			boolean mmapped;
-		} rom;
-		struct {
-			struct resource * res;
-		} base;
-		struct {
-			struct pci_dev * dev;
-		} config;
-	} u;
-};
-
-struct dma_allocation {
-	struct list_head list;
-
-	dma_addr_t handle;
-	void * va;
-	size_t size;
-};
-
-
-static LIST_HEAD(global_node_list);
-static LIST_HEAD(global_dma_list);
-
-
-/* module entry points */
-int __init pciba_init(void);
-void __exit pciba_exit(void);
-
-static status __init register_with_devfs(void);
-static void __exit unregister_with_devfs(void);
-
-static status __init register_pci_device(devfs_handle_t device_dir_handle,
-					 struct pci_dev * dev);
-
-/* file operations */
-static int generic_open(struct inode * inode, struct file * file);
-static int rom_mmap(struct file * file, struct vm_area_struct * vma);
-static int rom_release(struct inode * inode, struct file * file);
-static int base_mmap(struct file * file, struct vm_area_struct * vma);
-static int config_ioctl(struct inode * inode, struct file * file, 
-			unsigned int cmd, 
-			unsigned long arg);
-static int dma_ioctl(struct inode * inode, struct file * file, 
-		     unsigned int cmd, 
-		     unsigned long arg);
-static int dma_mmap(struct file * file, struct vm_area_struct * vma);
-
-/* support routines */
-static int mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va);
-static int mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va);
-
-#ifdef DEBUG_PCIBA
-static void dump_nodes(struct list_head * nodes);
-static void dump_allocations(struct list_head * dalp);
-#endif
-
-/* file operations for each type of node */
-static struct file_operations rom_fops = {
-	owner:		THIS_MODULE,
-	mmap:		rom_mmap,
-	open:		generic_open,
-	release:	rom_release
-};
- 
-
-static struct file_operations base_fops = {
-	owner:		THIS_MODULE,
-	mmap:		base_mmap,
-	open:		generic_open
-};
-
-
-static struct file_operations config_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		config_ioctl,
-	open:		generic_open
-};	
-
-static struct file_operations dma_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		dma_ioctl,
-	mmap:		dma_mmap,
-	open:		generic_open
-};	
-
-
-module_init(pciba_init);
-module_exit(pciba_exit);
-
-
-int __init
-pciba_init(void)
-{
-	TRACE();
-
-	if (register_with_devfs() == failure)
-		return 1; /* failure */
-
-	printk("PCIBA (a user mode PCI interface) initialized.\n");
-
-	return 0; /* success */
-}
-
-
-void __exit
-pciba_exit(void)
-{
-	TRACE();
-
-	/* FIXME: should also free all that memory that we allocated
-           ;) */
-	unregister_with_devfs();
-}
-
-
-# if 0
-static void __exit
-free_nodes(void)
-{
-	struct node_data * nd;
-	
-	TRACE();
-
-	list_for_each(nd, &node_list) {
-		kfree(list_entry(nd, struct nd, node_list));
-	}
-}
-#endif
-
-
-static devfs_handle_t pciba_devfs_handle;
-
-
-extern devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-static status __init
-register_with_devfs(void)
-{
-	struct pci_dev * dev;
-	devfs_handle_t device_dir_handle;
-
-	TRACE();
-
-	/* FIXME: don't forget /dev/.../pci/mem & /dev/.../pci/io */
-
-	pci_for_each_dev(dev) {
-		device_dir_handle = devfn_to_vertex(dev->bus->number,
-						    dev->devfn);
-		if (device_dir_handle == NULL)
-			return failure;
-	
-		if (register_pci_device(device_dir_handle, dev) == failure) {
-			devfs_unregister(pciba_devfs_handle);
-			return failure;
-		}
-	}
-
-	return success;
-}
-
-static void __exit
-unregister_with_devfs(void)
-{
-	struct list_head * lhp;
-	struct node_data * nd;
-	
-	TRACE();
-
-	list_for_each(lhp, &global_node_list) {
-		nd = list_entry(lhp, struct node_data, global_node_list);
-		devfs_unregister(nd->devfs_handle);
-	}
-
-}
-
-
-struct node_data * new_node(void)
-{
-	struct node_data * node;
-	
-	TRACE();
-	
-	node = kmalloc(sizeof(struct node_data), GFP_KERNEL);
-	if (node == NULL)
-		return NULL;
-	list_add(&node->global_node_list, &global_node_list);
-	return node;
-}
-
-
-void dma_cleanup(struct node_data * dma_node)
-{
-	TRACE();
-
-	/* FIXME: should free these allocations */
-#ifdef DEBUG_PCIBA
-	dump_allocations(&dma_node->u.dma.dma_allocs);
-#endif
-	devfs_unregister(dma_node->devfs_handle);
-}
-
-
-void init_dma_node(struct node_data * node,
-		   struct pci_dev * dev, devfs_handle_t dh)
-{
-	TRACE();
-
-	node->devfs_handle = dh;
-	node->u.dma.dev = dev;
-	node->cleanup = dma_cleanup;
-	INIT_LIST_HEAD(&node->u.dma.dma_allocs);
-}
-
-
-void rom_cleanup(struct node_data * rom_node)
-{
-	TRACE();
-
-	if (rom_node->u.rom.mmapped)
-		pci_write_config_dword(rom_node->u.rom.dev,
-				       PCI_ROM_ADDRESS,
-				       rom_node->u.rom.saved_rom_base_reg);
-	devfs_unregister(rom_node->devfs_handle);
-}
-
-
-void init_rom_node(struct node_data * node,
-		   struct pci_dev * dev, devfs_handle_t dh)
-{
-	TRACE();
-
-	node->devfs_handle = dh;
-	node->u.rom.dev = dev;
-	node->cleanup = rom_cleanup;
-	node->u.rom.mmapped = false;
-}
-
-
-static status __init
-register_pci_device(devfs_handle_t device_dir_handle, struct pci_dev * dev)
-{
-	struct node_data * nd;
-	char devfs_path[20];
-	devfs_handle_t node_devfs_handle;
-	int ri;
-
-	TRACE();
-
-
-	/* register nodes for all the device's base address registers */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (pci_resource_len(dev, ri) != 0) {
-			sprintf(devfs_path, "base/%d", ri);
-			if (devfs_register(device_dir_handle, devfs_path,
-					   DEVFS_FL_NONE,
-					   0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-		}
-	}
-	
-	/* register a node corresponding to the first MEM resource on
-           the device */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (dev->resource[ri].flags & IORESOURCE_MEM &&
-		    pci_resource_len(dev, ri) != 0) {
-			if (devfs_register(device_dir_handle, "mem",
-					   DEVFS_FL_NONE, 0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-			break;
-		}
-	}
-
-	/* also register a node corresponding to the first IO resource
-           on the device */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (dev->resource[ri].flags & IORESOURCE_IO &&
-		    pci_resource_len(dev, ri) != 0) {
-			if (devfs_register(device_dir_handle, "io",
-					   DEVFS_FL_NONE, 0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-			break;
-		}
-	}
-
-	/* register a node corresponding to the device's ROM resource,
-           if present */
-	if (pci_resource_len(dev, PCI_ROM_RESOURCE) != 0) {
-		nd = new_node();
-		if (nd == NULL)
-			return failure;
-		node_devfs_handle = devfs_register(device_dir_handle, "rom",
-						   DEVFS_FL_NONE, 0, 0,
-						   S_IFREG | S_IRUSR,
-						   &rom_fops, nd);
-		if (node_devfs_handle == NULL)
-			return failure;
-		init_rom_node(nd, dev, node_devfs_handle);
-	}
-
-	/* register a node that allows ioctl's to read and write to
-           the device's config space */
-	if (devfs_register(device_dir_handle, "config", DEVFS_FL_NONE,
-			   0, 0, S_IFREG | S_IRUSR | S_IWUSR,
-			   &config_fops, dev) == NULL)
-		return failure;
-
-
-	/* finally, register a node that allows ioctl's to allocate
-           and free DMA buffers, as well as memory map those
-           buffers. */
-	nd = new_node();
-	if (nd == NULL)
-		return failure;
-	node_devfs_handle =
-		devfs_register(device_dir_handle, "dma", DEVFS_FL_NONE,
-			       0, 0, S_IFREG | S_IRUSR | S_IWUSR,
-			       &dma_fops, nd);
-	if (node_devfs_handle == NULL)
-		return failure;
-	init_dma_node(nd, dev, node_devfs_handle);
-
-#ifdef DEBUG_PCIBA
-	dump_nodes(&global_node_list);
-#endif
-	
-	return success;
-}
-
-
-static int
-generic_open(struct inode * inode, struct file * file)
-{
-	TRACE();
-
-	/* FIXME: should check that they're not trying to open the ROM
-           writable */
-
-	return 0; /* success */
-}
-
-
-static int
-rom_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	unsigned long pci_pa;
-	struct node_data * nd;
-
-	TRACE();
-
-	nd = (struct node_data * )file->private_data;
-
-	pci_pa = pci_resource_start(nd->u.rom.dev, PCI_ROM_RESOURCE);
-
-	if (!nd->u.rom.mmapped) {
-		nd->u.rom.mmapped = true;
-		DPRINTF("Enabling ROM address decoder.\n");
-		DPRINTF(
-"rom_mmap: FIXME: some cards do not allow both ROM and memory addresses to\n"
-"rom_mmap: FIXME: be enabled simultaneously, as they share a decoder.\n");
-		pci_read_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				      &nd->u.rom.saved_rom_base_reg);
-		DPRINTF("ROM base address contains %x\n",
-			nd->u.rom.saved_rom_base_reg);
-		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				       nd->u.rom.saved_rom_base_reg |
-				       PCI_ROM_ADDRESS_ENABLE);
-	}
-	
-	return mmap_pci_address(vma, pci_pa);
-}
-
-
-static int
-rom_release(struct inode * inode, struct file * file)
-{
-	struct node_data * nd;
-
-	TRACE();
-
-	nd = (struct node_data * )file->private_data;
-
-	if (nd->u.rom.mmapped) {
-		nd->u.rom.mmapped = false;
-		DPRINTF("Disabling ROM address decoder.\n");
-		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				       nd->u.rom.saved_rom_base_reg);
-	}
-	return 0; /* indicate success */
-}
-
-
-static int
-base_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	struct resource * resource;
-
-	TRACE();
-
-	resource = (struct resource *)file->private_data;
-
-	return mmap_pci_address(vma, resource->start);
-}
-
-
-static int
-config_ioctl(struct inode * inode, struct file * file, 
-	     unsigned int cmd, 
-	     unsigned long arg)
-{
-	struct pci_dev * dev;
-
-	union cfg_data {
-		uint8_t byte;
-		uint16_t word;
-		uint32_t dword;
-	} read_data, write_data;
-
-	int dir, size, offset;
-
-	TRACE();
-
-	DPRINTF("cmd = %x (DIR = %x, TYPE = %x, NR = %x, SIZE = %x)\n", 
-		cmd, 
-		_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
-	DPRINTF("arg = %lx\n", arg);
-
-	dev = (struct pci_dev *)file->private_data;
-
-	/* PCIIOCCFG{RD,WR}: read and/or write PCI configuration
-	   space. If both, the read happens first (this becomes a swap
-	   operation, atomic with respect to other updates through
-	   this path).  */
-
-	dir = _IOC_DIR(cmd);
-
-#define do_swap(suffix, type)	 					\
-	do {								\
-		if (dir & _IOC_READ) {					\
-			pci_read_config_##suffix(dev, _IOC_NR(cmd), 	\
-						 &read_data.suffix);	\
-		}							\
-		if (dir & _IOC_WRITE) {					\
-			get_user(write_data.suffix, (type)arg);		\
-			pci_write_config_##suffix(dev, _IOC_NR(cmd), 	\
-						  write_data.suffix);	\
-		}							\
-		if (dir & _IOC_READ) {					\
-			put_user(read_data.suffix, (type)arg);		\
-		}							\
-	} while (0)
-
-	size = _IOC_SIZE(cmd);
-	offset = _IOC_NR(cmd);
-
-	DPRINTF("sanity check\n");
-	if (((size > 0) || (size <= 4)) &&
-	    ((offset + size) <= 256) &&
-	    (dir & (_IOC_READ | _IOC_WRITE))) {
-
-		switch (size)
-		{
-		case 1:
-			do_swap(byte, uint8_t *);
-			break;
-		case 2:
-			do_swap(word, uint16_t *);
-			break;
-		case 4:
-			do_swap(dword, uint32_t *);
-			break;
-		default:
-			DPRINTF("invalid ioctl\n");
-			return -EINVAL;
-		}
-	} else
-		return -EINVAL;
-		
-	return 0;
-}
-
-
-#ifdef DEBUG_PCIBA
-static void
-dump_allocations(struct list_head * dalp)
-{
-	struct dma_allocation * dap;
-	struct list_head * p;
-	
-	printk("{\n");
-	list_for_each(p, dalp) {
-		dap = list_entry(p, struct dma_allocation, 
-				 list);
-		printk("  handle = %lx, va = %p\n",
-		       dap->handle, dap->va);
-	}
-	printk("}\n");
-}
-
-static void
-dump_nodes(struct list_head * nodes)
-{
-	struct node_data * ndp;
-	struct list_head * p;
-	
-	printk("{\n");
-	list_for_each(p, nodes) {
-		ndp = list_entry(p, struct node_data, 
-				 global_node_list);
-		printk("  %p\n", (void *)ndp);
-	}
-	printk("}\n");
-}
-
-
-#if 0
-#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-
-static void
-test_list(void)
-{
-	u64 i;
-	LIST_HEAD(the_list);
-
-	for (i = 0; i < 5; i++) {
-		struct dma_allocation * new_alloc;
-		NEW(new_alloc);
-		new_alloc->va = (void *)i;
-		new_alloc->handle = 5*i;
-		printk("%d - the_list->next = %lx\n", i, the_list.next);
-		list_add(&new_alloc->list, &the_list);
-	}
-	dump_allocations(&the_list);
-}
-#endif
-#endif
-
-
-static LIST_HEAD(dma_buffer_list);
-
-
-static int
-dma_ioctl(struct inode * inode, struct file * file, 
-	  unsigned int cmd, 
-	  unsigned long arg)
-{
-	struct node_data * nd;
-	uint64_t argv;
-	int result;
-	struct dma_allocation * dma_alloc;
-	struct list_head * iterp;
-
-	TRACE();
-
-	DPRINTF("cmd = %x\n", cmd);
-	DPRINTF("arg = %lx\n", arg);
-
-	nd = (struct node_data *)file->private_data;
-
-#ifdef DEBUG_PCIBA
-	DPRINTF("at dma_ioctl entry\n");
-	dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-
-	switch (cmd) {
-	case PCIIOCDMAALLOC:
-		/* PCIIOCDMAALLOC: allocate a chunk of physical memory
-		   and set it up for DMA. Return the PCI address that
-		   gets to it.  */
-		DPRINTF("case PCIIOCDMAALLOC (%lx)\n", PCIIOCDMAALLOC);
-		
-		if ( (result = get_user(argv, (uint64_t *)arg)) )
-			return result;
-		DPRINTF("argv (size of buffer) = %lx\n", argv);
-
-		dma_alloc = (struct dma_allocation *)
-			kmalloc(sizeof(struct dma_allocation), GFP_KERNEL);
-		if (dma_alloc == NULL)
-			return -ENOMEM;
-
-		dma_alloc->size = (size_t)argv;
-		dma_alloc->va = pci_alloc_consistent(nd->u.dma.dev,
-						     dma_alloc->size,
-						     &dma_alloc->handle);
-		DPRINTF("dma_alloc->va = %p, dma_alloc->handle = %lx\n",
-			dma_alloc->va, dma_alloc->handle);
-		if (dma_alloc->va == NULL) {
-			kfree(dma_alloc);
-			return -ENOMEM;
-		}
-
-		list_add(&dma_alloc->list, &nd->u.dma.dma_allocs);
-		if ( (result = put_user((uint64_t)dma_alloc->handle, 
-				      (uint64_t *)arg)) ) {
-			DPRINTF("put_user failed\n");
-			pci_free_consistent(nd->u.dma.dev, (size_t)argv,
-					    dma_alloc->va, dma_alloc->handle);
-			kfree(dma_alloc);
-			return result;
-		}
-
-#ifdef DEBUG_PCIBA
-		DPRINTF("after insertion\n");
-		dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-		break;
-
-	case PCIIOCDMAFREE:
-		DPRINTF("case PCIIOCDMAFREE (%lx)\n", PCIIOCDMAFREE);
-
-		if ( (result = get_user(argv, (uint64_t *)arg)) ) {
-			DPRINTF("get_user failed\n");
-			return result;
-		}
-
-		DPRINTF("argv (physical address of DMA buffer) = %lx\n", argv);
-		list_for_each(iterp, &nd->u.dma.dma_allocs) {
-			struct dma_allocation * da =
-				list_entry(iterp, struct dma_allocation, list);
-			if (da->handle == argv) {
-				pci_free_consistent(nd->u.dma.dev, da->size,
-						    da->va, da->handle);
-				list_del(&da->list);
-				kfree(da);
-#ifdef DEBUG_PCIBA
-				DPRINTF("after deletion\n");
-				dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-				return 0; /* success */
-			}
-		}
-		/* previously allocated dma buffer wasn't found */
-		DPRINTF("attempt to free invalid dma handle\n");
-		return -EINVAL;
-
-	default:
-		DPRINTF("undefined ioctl\n");
-		return -EINVAL;
-	}
-
-	DPRINTF("success\n");
-	return 0;
-}
-		
-
-static int
-dma_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	struct node_data * nd;
-	struct list_head * iterp;
-	int result;
-	
-	TRACE();
-
-	nd = (struct node_data *)file->private_data;
-	
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-	DPRINTF("offset = %lx\n", vma->vm_pgoff);
-
-	/* get kernel virtual address for the dma buffer (necessary
-	 * for the mmap). */
-	list_for_each(iterp, &nd->u.dma.dma_allocs) {
-		struct dma_allocation * da =
-			list_entry(iterp, struct dma_allocation, list);
-		/* why does mmap shift its offset argument? */
-		if (da->handle == vma->vm_pgoff << PAGE_SHIFT) {
-			DPRINTF("found dma handle\n");
-			if ( (result = mmap_kernel_address(vma,
-							   da->va)) ) {
-				return result; /* failure */
-			} else {
-				/* it seems like at least one of these
-				   should show up in user land....
-				   I'm missing something */
-				*(char *)da->va = 0xaa;
-				strncpy(da->va, "        Toastie!", da->size);
-				if (put_user(0x18badbeeful,
-					     (u64 *)vma->vm_start))
-					DPRINTF("put_user failed?!\n");
-				return 0; /* success */
-			}
-
-		}
-	}
-	DPRINTF("attempt to mmap an invalid dma handle\n");
-	return -EINVAL;
-}
-
-
-static int
-mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va)
-{
-	unsigned long pci_pa;
-
-	TRACE();
-
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-
-	/* the size of the vma doesn't necessarily correspond to the
-           size specified in the mmap call.  So we can't really do any
-           kind of sanity check here.  This is a dangerous driver, and
-           it's very easy for a user process to kill the machine.  */
-
-	DPRINTF("PCI base at virtual address %lx\n", pci_va);
-	/* the __pa macro is intended for region 7 on IA64, so it
-	   doesn't work for region 6 */
-  	/* pci_pa = __pa(pci_va); */
-	/* should be replaced by __tpa or equivalent (preferably a
-	   generic equivalent) */
-	pci_pa = pci_va & ~0xe000000000000000ul;
-	DPRINTF("PCI base at physical address %lx\n", pci_pa);
-
-	/* there are various arch-specific versions of this function
-           defined in linux/drivers/char/mem.c, but it would be nice
-           if all architectures put it in pgtable.h.  it's defined
-           there for ia64.... */
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
-
-	return io_remap_page_range(vma->vm_start, pci_pa, 
-				   vma->vm_end-vma->vm_start,
-				   vma->vm_page_prot);
-}
-
-
-static int
-mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va)
-{
-	unsigned long kernel_pa;
-
-	TRACE();
-
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-
-	/* the size of the vma doesn't necessarily correspond to the
-           size specified in the mmap call.  So we can't really do any
-           kind of sanity check here.  This is a dangerous driver, and
-           it's very easy for a user process to kill the machine.  */
-
-	DPRINTF("mapping virtual address %p\n", kernel_va);
-	kernel_pa = __pa(kernel_va);
-	DPRINTF("mapping physical address %lx\n", kernel_pa);
-
-	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
-
-	return remap_page_range(vma->vm_start, kernel_pa, 
-				vma->vm_end-vma->vm_start,
-				vma->vm_page_prot);
-}	
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/pciio.c linux-2.4.22-pre3/arch/ia64/sn/io/pciio.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/pciio.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/pciio.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1511 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#define	USRPCI	0
-
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/xtalk/xbow.h>	/* Must be before iograph.h to get MAX_PORT_NUM */
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pciio_private.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/simulator.h>
-
-#define DEBUG_PCIIO
-#undef DEBUG_PCIIO	/* turn this on for yet more console output */
-
-
-#define GET_NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DO_DEL(ptr)	(kfree(ptr))
-
-char                    pciio_info_fingerprint[] = "pciio_info";
-
-cdl_p                   pciio_registry = NULL;
-
-int
-badaddr_val(volatile void *addr, int len, volatile void *ptr)
-{
-	int ret = 0;
-	volatile void *new_addr;
-
-	switch (len) {
-		case 4:
-#ifdef CONFIG_IA64_SGI_SN1
-			new_addr = (void *)(((u64) addr)^4);
-#else
-			new_addr = (void *) addr;
-#endif
-			ret = ia64_sn_probe_io_slot((long)new_addr, len, (void *)ptr);
-			break;
-		default:
-			printk(KERN_WARNING "badaddr_val given len %x but supports len of 4 only\n", len);
-	}
-
-	if (ret < 0)
-		panic("badaddr_val: unexpected status (%d) in probing", ret);
-	return(ret);
-
-}
-
-
-nasid_t
-get_console_nasid(void)
-{
-	extern nasid_t console_nasid;
-	if (console_nasid < 0) {
-		console_nasid = ia64_sn_get_console_nasid();
-		if (console_nasid < 0) {
-// ZZZ What do we do if we don't get a console nasid on the hardware????
-			if (IS_RUNNING_ON_SIMULATOR() )
-				console_nasid = master_nasid;
-		}
-	} 
-	return console_nasid;
-}
-
-int
-hub_dma_enabled(devfs_handle_t xconn_vhdl)
-{
-	return(0);
-}
-
-int
-hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
-{
-	return(0);
-}
-
-void
-ioerror_dump(char *name, int error_code, int error_mode, ioerror_t *ioerror)
-{
-}
-
-/******
- ****** end hack defines ......
- ******/
-
-
-
-
-/* =====================================================================
- *    PCI Generic Bus Provider
- * Implement PCI provider operations.  The pciio* layer provides a
- * platform-independent interface for PCI devices.  This layer
- * switches among the possible implementations of a PCI adapter.
- */
-
-/* =====================================================================
- *    Provider Function Location SHORTCUT
- *
- * On platforms with only one possible PCI provider, macros can be
- * set up at the top that cause the table lookups and indirections to
- * completely disappear.
- */
-
-#if defined(CONFIG_IA64_SGI_SN1)
-/*
- *    For the moment, we will assume that IP27
- *      only use Bridge ASICs to provide PCI support.
- */
-#include <asm/sn/pci/pcibr.h>
-#define DEV_FUNC(dev,func)	pcibr_##func
-#define CAST_PIOMAP(x)		((pcibr_piomap_t)(x))
-#define CAST_DMAMAP(x)		((pcibr_dmamap_t)(x))
-#define CAST_INTR(x)		((pcibr_intr_t)(x))
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-/* =====================================================================
- *    Function Table of Contents
- */
-
-#if !defined(DEV_FUNC)
-static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev);
-#endif
-
-pciio_piomap_t          pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
-void                    pciio_piomap_free(pciio_piomap_t);
-caddr_t                 pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t);
-
-void                    pciio_piomap_done(pciio_piomap_t);
-caddr_t                 pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-caddr_t			pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
-
-iopaddr_t               pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
-
-pciio_dmamap_t          pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    pciio_dmamap_free(pciio_dmamap_t);
-iopaddr_t               pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-alenlist_t              pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned);
-void                    pciio_dmamap_done(pciio_dmamap_t);
-iopaddr_t               pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void			pciio_dmamap_drain(pciio_dmamap_t);
-void			pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void			pciio_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
-
-pciio_intr_t            pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
-void                    pciio_intr_free(pciio_intr_t);
-int                     pciio_intr_connect(pciio_intr_t);
-void                    pciio_intr_disconnect(pciio_intr_t);
-devfs_handle_t            pciio_intr_cpu_get(pciio_intr_t);
-
-void			pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t);
-
-void                    pciio_provider_startup(devfs_handle_t);
-void                    pciio_provider_shutdown(devfs_handle_t);
-
-pciio_endian_t          pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-pciio_priority_t        pciio_priority_set(devfs_handle_t, pciio_priority_t);
-devfs_handle_t            pciio_intr_dev_get(pciio_intr_t);
-
-devfs_handle_t            pciio_pio_dev_get(pciio_piomap_t);
-pciio_slot_t            pciio_pio_slot_get(pciio_piomap_t);
-pciio_space_t           pciio_pio_space_get(pciio_piomap_t);
-iopaddr_t               pciio_pio_pciaddr_get(pciio_piomap_t);
-ulong                   pciio_pio_mapsz_get(pciio_piomap_t);
-caddr_t                 pciio_pio_kvaddr_get(pciio_piomap_t);
-
-devfs_handle_t            pciio_dma_dev_get(pciio_dmamap_t);
-pciio_slot_t            pciio_dma_slot_get(pciio_dmamap_t);
-
-pciio_info_t            pciio_info_chk(devfs_handle_t);
-pciio_info_t            pciio_info_get(devfs_handle_t);
-void                    pciio_info_set(devfs_handle_t, pciio_info_t);
-devfs_handle_t            pciio_info_dev_get(pciio_info_t);
-pciio_slot_t            pciio_info_slot_get(pciio_info_t);
-pciio_function_t        pciio_info_function_get(pciio_info_t);
-pciio_vendor_id_t       pciio_info_vendor_id_get(pciio_info_t);
-pciio_device_id_t       pciio_info_device_id_get(pciio_info_t);
-devfs_handle_t            pciio_info_master_get(pciio_info_t);
-arbitrary_info_t        pciio_info_mfast_get(pciio_info_t);
-pciio_provider_t       *pciio_info_pops_get(pciio_info_t);
-error_handler_f	       *pciio_info_efunc_get(pciio_info_t);
-error_handler_arg_t    *pciio_info_einfo_get(pciio_info_t);
-pciio_space_t		pciio_info_bar_space_get(pciio_info_t, int);
-iopaddr_t		pciio_info_bar_base_get(pciio_info_t, int);
-size_t			pciio_info_bar_size_get(pciio_info_t, int);
-iopaddr_t		pciio_info_rom_base_get(pciio_info_t);
-size_t			pciio_info_rom_size_get(pciio_info_t);
-
-void                    pciio_init(void);
-int                     pciio_attach(devfs_handle_t);
-
-void                    pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns);
-void                    pciio_provider_unregister(devfs_handle_t);
-pciio_provider_t       *pciio_provider_fns_get(devfs_handle_t);
-
-int                     pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned);
-void                    pciio_driver_unregister(char *driver_prefix);
-
-devfs_handle_t            pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-
-void			pciio_device_unregister(devfs_handle_t);
-pciio_info_t		pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-void			pciio_device_info_free(pciio_info_t);
-devfs_handle_t		pciio_device_info_register(devfs_handle_t, pciio_info_t);
-void			pciio_device_info_unregister(devfs_handle_t, pciio_info_t);
-int                     pciio_device_attach(devfs_handle_t, int);
-int			pciio_device_detach(devfs_handle_t, int);
-void                    pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
-
-int                     pciio_reset(devfs_handle_t);
-int                     pciio_write_gather_flush(devfs_handle_t);
-int                     pciio_slot_inuse(devfs_handle_t);
-
-/* =====================================================================
- *    Provider Function Location
- *
- *      If there is more than one possible provider for
- *      this platform, we need to examine the master
- *      vertex of the current vertex for a provider
- *      function structure, and indirect through the
- *      appropriately named member.
- */
-
-#if !defined(DEV_FUNC)
-
-static pciio_provider_t *
-pciio_to_provider_fns(devfs_handle_t dev)
-{
-    pciio_info_t            card_info;
-    pciio_provider_t       *provider_fns;
-
-    /*
-     * We're called with two types of vertices, one is
-     * the bridge vertex (ends with "pci") and the other is the
-     * pci slot vertex (ends with "pci/[0-8]").  For the first type
-     * we need to get the provider from the PFUNCS label.  For
-     * the second we get it from fastinfo/c_pops.
-     */
-    provider_fns = pciio_provider_fns_get(dev);
-    if (provider_fns == NULL) {
-	card_info = pciio_info_get(dev);
-	if (card_info != NULL) {
-		provider_fns = pciio_info_pops_get(card_info);
-	}
-    }
-
-    if (provider_fns == NULL)
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	PRINT_PANIC("%v: provider_fns == NULL", dev);
-#else
-	PRINT_PANIC("0x%p: provider_fns == NULL", (void *)dev);
-#endif
-
-    return provider_fns;
-
-}
-
-#define DEV_FUNC(dev,func)	pciio_to_provider_fns(dev)->func
-#define CAST_PIOMAP(x)		((pciio_piomap_t)(x))
-#define CAST_DMAMAP(x)		((pciio_dmamap_t)(x))
-#define CAST_INTR(x)		((pciio_intr_t)(x))
-#endif
-
-/*
- * Many functions are not passed their vertex
- * information directly; rather, they must
- * dive through a resource map. These macros
- * are available to coordinate this detail.
- */
-#define PIOMAP_FUNC(map,func)		DEV_FUNC((map)->pp_dev,func)
-#define DMAMAP_FUNC(map,func)		DEV_FUNC((map)->pd_dev,func)
-#define INTR_FUNC(intr_hdl,func)	DEV_FUNC((intr_hdl)->pi_dev,func)
-
-/* =====================================================================
- *          PIO MANAGEMENT
- *
- *      For mapping system virtual address space to
- *      pciio space on a specified card
- */
-
-pciio_piomap_t
-pciio_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-		   iopaddr_t addr,	/* lowest address (or offset in window) */
-		   size_t byte_count,	/* size of region containing our mappings */
-		   size_t byte_count_max,	/* maximum size of a mapping */
-		   unsigned flags)
-{					/* defined in sys/pio.h */
-    return (pciio_piomap_t) DEV_FUNC(dev, piomap_alloc)
-	(dev, dev_desc, space, addr, byte_count, byte_count_max, flags);
-}
-
-void
-pciio_piomap_free(pciio_piomap_t pciio_piomap)
-{
-    PIOMAP_FUNC(pciio_piomap, piomap_free)
-	(CAST_PIOMAP(pciio_piomap));
-}
-
-caddr_t
-pciio_piomap_addr(pciio_piomap_t pciio_piomap,	/* mapping resources */
-		  iopaddr_t pciio_addr,	/* map for this pciio address */
-		  size_t byte_count)
-{					/* map this many bytes */
-    pciio_piomap->pp_kvaddr = PIOMAP_FUNC(pciio_piomap, piomap_addr)
-	(CAST_PIOMAP(pciio_piomap), pciio_addr, byte_count);
-
-    return pciio_piomap->pp_kvaddr;
-}
-
-void
-pciio_piomap_done(pciio_piomap_t pciio_piomap)
-{
-    PIOMAP_FUNC(pciio_piomap, piomap_done)
-	(CAST_PIOMAP(pciio_piomap));
-}
-
-caddr_t
-pciio_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-		    iopaddr_t addr,	/* starting address (or offset in window) */
-		    size_t byte_count,	/* map this many bytes */
-		    unsigned flags)
-{					/* (currently unused) */
-    return DEV_FUNC(dev, piotrans_addr)
-	(dev, dev_desc, space, addr, byte_count, flags);
-}
-
-caddr_t
-pciio_pio_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-	       iopaddr_t addr,		/* starting address (or offset in window) */
-	       size_t byte_count,	/* map this many bytes */
-	       pciio_piomap_t *mapp,	/* where to return the map pointer */
-	       unsigned flags)
-{					/* PIO flags */
-    pciio_piomap_t          map = 0;
-    int			    errfree = 0;
-    caddr_t                 res;
-
-    if (mapp) {
-	map = *mapp;			/* possible pre-allocated map */
-	*mapp = 0;			/* record "no map used" */
-    }
-
-    res = pciio_piotrans_addr
-	(dev, dev_desc, space, addr, byte_count, flags);
-    if (res)
-	return res;			/* pciio_piotrans worked */
-
-    if (!map) {
-	map = pciio_piomap_alloc
-	    (dev, dev_desc, space, addr, byte_count, byte_count, flags);
-	if (!map)
-	    return res;			/* pciio_piomap_alloc failed */
-	errfree = 1;
-    }
-
-    res = pciio_piomap_addr
-	(map, addr, byte_count);
-    if (!res) {
-	if (errfree)
-	    pciio_piomap_free(map);
-	return res;			/* pciio_piomap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* pciio_piomap_addr succeeded */
-}
-
-iopaddr_t
-pciio_piospace_alloc(devfs_handle_t dev,	/* Device requiring space */
-		     device_desc_t dev_desc,	/* Device descriptor */
-		     pciio_space_t space,	/* MEM32/MEM64/IO */
-		     size_t byte_count,	/* Size of mapping */
-		     size_t align)
-{					/* Alignment needed */
-    if (align < NBPP)
-	align = NBPP;
-    return DEV_FUNC(dev, piospace_alloc)
-	(dev, dev_desc, space, byte_count, align);
-}
-
-void
-pciio_piospace_free(devfs_handle_t dev,	/* Device freeing space */
-		    pciio_space_t space,	/* Type of space        */
-		    iopaddr_t pciaddr,	/* starting address */
-		    size_t byte_count)
-{					/* Range of address   */
-    DEV_FUNC(dev, piospace_free)
-	(dev, space, pciaddr, byte_count);
-}
-
-/* =====================================================================
- *          DMA MANAGEMENT
- *
- *      For mapping from pci space to system
- *      physical space.
- */
-
-pciio_dmamap_t
-pciio_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   size_t byte_count_max,	/* max size of a mapping */
-		   unsigned flags)
-{					/* defined in dma.h */
-    return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-	(dev, dev_desc, byte_count_max, flags);
-}
-
-void
-pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_free)
-	(CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  paddr_t paddr,	/* map for this address */
-		  size_t byte_count)
-{					/* map this many bytes */
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
-	(CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
-}
-
-alenlist_t
-pciio_dmamap_list(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_list)
-	(CAST_DMAMAP(pciio_dmamap), alenlist, flags);
-}
-
-void
-pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_done)
-	(CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-pciio_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    paddr_t paddr,	/* system physical address */
-		    size_t byte_count,	/* length */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_addr)
-	(dev, dev_desc, paddr, byte_count, flags);
-}
-
-alenlist_t
-pciio_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
-iopaddr_t
-pciio_dma_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       paddr_t paddr,		/* system physical address */
-	       size_t byte_count,	/* length */
-	       pciio_dmamap_t *mapp,	/* map to use, then map we used */
-	       unsigned flags)
-{					/* PIO flags */
-    pciio_dmamap_t          map = 0;
-    int			    errfree = 0;
-    iopaddr_t               res;
-
-    if (mapp) {
-	map = *mapp;			/* possible pre-allocated map */
-	*mapp = 0;			/* record "no map used" */
-    }
-
-    res = pciio_dmatrans_addr
-	(dev, dev_desc, paddr, byte_count, flags);
-    if (res)
-	return res;			/* pciio_dmatrans worked */
-
-    if (!map) {
-	map = pciio_dmamap_alloc
-	    (dev, dev_desc, byte_count, flags);
-	if (!map)
-	    return res;			/* pciio_dmamap_alloc failed */
-	errfree = 1;
-    }
-
-    res = pciio_dmamap_addr
-	(map, paddr, byte_count);
-    if (!res) {
-	if (errfree)
-	    pciio_dmamap_free(map);
-	return res;			/* pciio_dmamap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* pciio_dmamap_addr succeeded */
-}
-
-void
-pciio_dmamap_drain(pciio_dmamap_t map)
-{
-    DMAMAP_FUNC(map, dmamap_drain)
-	(CAST_DMAMAP(map));
-}
-
-void
-pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
-{
-    DEV_FUNC(dev, dmaaddr_drain)
-	(dev, addr, size);
-}
-
-void
-pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-	(dev, list);
-}
-
-/* =====================================================================
- *          INTERRUPT MANAGEMENT
- *
- *      Allow crosstalk devices to establish interrupts
- */
-
-/*
- * Allocate resources required for an interrupt as specified in intr_desc.
- * Return resource handle in intr_hdl.
- */
-pciio_intr_t
-pciio_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
-		 device_desc_t dev_desc,	/* device descriptor */
-		 pciio_intr_line_t lines,	/* INTR line(s) to attach */
-		 devfs_handle_t owner_dev)
-{					/* owner of this interrupt */
-    return (pciio_intr_t) DEV_FUNC(dev, intr_alloc)
-	(dev, dev_desc, lines, owner_dev);
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-pciio_intr_free(pciio_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_free)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Associate resources allocated with a previous pciio_intr_alloc call with the
- * described handler, arg, name, etc.
- *
- * Returns 0 on success, returns <0 on failure.
- */
-int
-pciio_intr_connect(pciio_intr_t intr_hdl)	/* pciio intr resource handle */
-{
-    return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-pciio_intr_disconnect(pciio_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_disconnect)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-pciio_intr_cpu_get(pciio_intr_t intr_hdl)
-{
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
-}
-
-void
-pciio_slot_func_to_name(char		       *name,
-			pciio_slot_t		slot,
-			pciio_function_t	func)
-{
-    /*
-     * standard connection points:
-     *
-     * PCIIO_SLOT_NONE:	.../pci/direct
-     * PCIIO_FUNC_NONE: .../pci/<SLOT>			ie. .../pci/3
-     * multifunction:   .../pci/<SLOT><FUNC>		ie. .../pci/3c
-     */
-
-    if (slot == PCIIO_SLOT_NONE)
-	sprintf(name, "direct");
-    else if (func == PCIIO_FUNC_NONE)
-	sprintf(name, "%d", slot);
-    else
-	sprintf(name, "%d%c", slot, 'a'+func);
-}
-
-/* =====================================================================
- *          CONFIGURATION MANAGEMENT
- */
-
-/*
- * Startup a crosstalk provider
- */
-void
-pciio_provider_startup(devfs_handle_t pciio_provider)
-{
-    DEV_FUNC(pciio_provider, provider_startup)
-	(pciio_provider);
-}
-
-/*
- * Shutdown a crosstalk provider
- */
-void
-pciio_provider_shutdown(devfs_handle_t pciio_provider)
-{
-    DEV_FUNC(pciio_provider, provider_shutdown)
-	(pciio_provider);
-}
-
-/*
- * Specify endianness constraints.  The driver tells us what the device
- * does and how it would like to see things in memory.  We reply with
- * how things will actually appear in memory.
- */
-pciio_endian_t
-pciio_endian_set(devfs_handle_t dev,
-		 pciio_endian_t device_end,
-		 pciio_endian_t desired_end)
-{
-    ASSERT((device_end == PCIDMA_ENDIAN_BIG) || (device_end == PCIDMA_ENDIAN_LITTLE));
-    ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE));
-
-#if DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk(KERN_ALERT  "%v: pciio_endian_set is going away.\n"
-	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
-	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
-	    dev);
-#else
-    printk(KERN_ALERT  "0x%x: pciio_endian_set is going away.\n"
-	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
-	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
-	    dev);
-#endif
-#endif
-
-    return DEV_FUNC(dev, endian_set)
-	(dev, device_end, desired_end);
-}
-
-/*
- * Specify PCI arbitration priority.
- */
-pciio_priority_t
-pciio_priority_set(devfs_handle_t dev,
-		   pciio_priority_t device_prio)
-{
-    ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW));
-
-    return DEV_FUNC(dev, priority_set)
-	(dev, device_prio);
-}
-
-/*
- * Read value of configuration register
- */
-uint64_t
-pciio_config_get(devfs_handle_t	dev,
-		 unsigned	reg,
-		 unsigned	size)
-{
-    uint64_t	value = 0;
-    unsigned	shift = 0;
-
-    /* handle accesses that cross words here,
-     * since that's common code between all
-     * possible providers.
-     */
-    while (size > 0) {
-	unsigned	biw = 4 - (reg&3);
-	if (biw > size)
-	    biw = size;
-
-	value |= DEV_FUNC(dev, config_get)
-	    (dev, reg, biw) << shift;
-
-	shift += 8*biw;
-	reg += biw;
-	size -= biw;
-    }
-    return value;
-}
-
-/*
- * Change value of configuration register
- */
-void
-pciio_config_set(devfs_handle_t	dev,
-		 unsigned	reg,
-		 unsigned	size,
-		 uint64_t	value)
-{
-    /* handle accesses that cross words here,
-     * since that's common code between all
-     * possible providers.
-     */
-    while (size > 0) {
-	unsigned	biw = 4 - (reg&3);
-	if (biw > size)
-	    biw = size;
-	    
-	DEV_FUNC(dev, config_set)
-	    (dev, reg, biw, value);
-	reg += biw;
-	size -= biw;
-	value >>= biw * 8;
-    }
-}
-
-/* =====================================================================
- *          GENERIC PCI SUPPORT FUNCTIONS
- */
-
-/*
- * Issue a hardware reset to a card.
- */
-int
-pciio_reset(devfs_handle_t dev)
-{
-    return DEV_FUNC(dev, reset) (dev);
-}
-
-/*
- * flush write gather buffers
- */
-int
-pciio_write_gather_flush(devfs_handle_t dev)
-{
-    return DEV_FUNC(dev, write_gather_flush) (dev);
-}
-
-devfs_handle_t
-pciio_intr_dev_get(pciio_intr_t pciio_intr)
-{
-    return (pciio_intr->pi_dev);
-}
-
-/****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
-pciio_pio_dev_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_dev);
-}
-
-pciio_slot_t
-pciio_pio_slot_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_slot);
-}
-
-pciio_space_t
-pciio_pio_space_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_space);
-}
-
-iopaddr_t
-pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_pciaddr);
-}
-
-ulong
-pciio_pio_mapsz_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_mapsz);
-}
-
-caddr_t
-pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_kvaddr);
-}
-
-/****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
-pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap)
-{
-    return (pciio_dmamap->pd_dev);
-}
-
-pciio_slot_t
-pciio_dma_slot_get(pciio_dmamap_t pciio_dmamap)
-{
-    return (pciio_dmamap->pd_slot);
-}
-
-/****** Generic pci slot information interfaces ******/
-
-pciio_info_t
-pciio_info_chk(devfs_handle_t pciio)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo);
-    return (pciio_info_t) ainfo;
-}
-
-pciio_info_t
-pciio_info_get(devfs_handle_t pciio)
-{
-    pciio_info_t            pciio_info;
-
-    pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio);
-
-#ifdef DEBUG_PCIIO
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(pciio, dname, 256);
-	printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-    }
-#endif /* DEBUG_PCIIO */
-
-    if ((pciio_info != NULL) &&
-	(pciio_info->c_fingerprint != pciio_info_fingerprint)
-	&& (pciio_info->c_fingerprint != NULL)) {
-
-	return((pciio_info_t)-1); /* Should panic .. */
-    }
-	
-
-    return pciio_info;
-}
-
-void
-pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info)
-{
-    if (pciio_info != NULL)
-	pciio_info->c_fingerprint = pciio_info_fingerprint;
-    hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info);
-
-    /* Also, mark this vertex as a PCI slot
-     * and use the pciio_info, so pciio_info_chk
-     * can work (and be fairly efficient).
-     */
-    hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO,
-			 (arbitrary_info_t) pciio_info);
-}
-
-devfs_handle_t
-pciio_info_dev_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_vertex);
-}
-
-/*ARGSUSED*/
-pciio_bus_t
-pciio_info_bus_get(pciio_info_t pciio_info)
-{
-    /* XXX for now O2 always gets back bus 0 */
-    return (pciio_bus_t)0;
-}
-
-pciio_slot_t
-pciio_info_slot_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_slot);
-}
-
-pciio_function_t
-pciio_info_function_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_func);
-}
-
-pciio_vendor_id_t
-pciio_info_vendor_id_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_vendor);
-}
-
-pciio_device_id_t
-pciio_info_device_id_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_device);
-}
-
-devfs_handle_t
-pciio_info_master_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_master);
-}
-
-arbitrary_info_t
-pciio_info_mfast_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_mfast);
-}
-
-pciio_provider_t       *
-pciio_info_pops_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_pops);
-}
-
-error_handler_f	       *
-pciio_info_efunc_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_efunc);
-}
-
-error_handler_arg_t    *
-pciio_info_einfo_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_einfo);
-}
-
-pciio_space_t
-pciio_info_bar_space_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_space;
-}
-
-iopaddr_t
-pciio_info_bar_base_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_base;
-}
-
-size_t
-pciio_info_bar_size_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_size;
-}
-
-iopaddr_t
-pciio_info_rom_base_get(pciio_info_t info)
-{
-    return info->c_rbase;
-}
-
-size_t
-pciio_info_rom_size_get(pciio_info_t info)
-{
-    return info->c_rsize;
-}
-
-
-/* =====================================================================
- *          GENERIC PCI INITIALIZATION FUNCTIONS
- */
-
-/*
- *    pciioinit: called once during device driver
- *      initializtion if this driver is configured into
- *      the system.
- */
-void
-pciio_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("pciio_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (pciio_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_PCI, "vendor", "device");
-	if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(pciio_registry != NULL);
-}
-
-/*
- *    pciioattach: called for each vertex in the graph
- *      that is a PCI provider.
- */
-/*ARGSUSED */
-int
-pciio_attach(devfs_handle_t pciio)
-{
-#if DEBUG && ATTACH_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk("%v: pciio_attach\n", pciio);
-#else
-    printk("0x%x: pciio_attach\n", pciio);
-#endif
-#endif
-    return 0;
-}
-
-/*
- * Associate a set of pciio_provider functions with a vertex.
- */
-void
-pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns)
-{
-    hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns);
-}
-
-/*
- * Disassociate a set of pciio_provider functions with a vertex.
- */
-void
-pciio_provider_unregister(devfs_handle_t provider)
-{
-    arbitrary_info_t        ainfo;
-
-    hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo);
-}
-
-/*
- * Obtain a pointer to the pciio_provider functions for a specified Crosstalk
- * provider.
- */
-pciio_provider_t       *
-pciio_provider_fns_get(devfs_handle_t provider)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo);
-    return (pciio_provider_t *) ainfo;
-}
-
-/*ARGSUSED4 */
-int
-pciio_driver_register(
-			 pciio_vendor_id_t vendor_id,
-			 pciio_device_id_t device_id,
-			 char *driver_prefix,
-			 unsigned flags)
-{
-    /* a driver's init routine might call
-     * pciio_driver_register before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    return cdl_add_driver(pciio_registry,
-			  vendor_id, device_id,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Remove an initialization function.
- */
-void
-pciio_driver_unregister(
-			   char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called register; so
-     * we can assume we have a registry here.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    cdl_del_driver(pciio_registry, driver_prefix, NULL);
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being registered.
- */
-void
-pciio_driver_reg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being unregistered.
- */
-void
-pciio_driver_unreg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-pciio_iterate(char *driver_prefix,
-	      pciio_iter_f * func)
-{
-    /* a driver's init routine might call
-     * pciio_iterate before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    ASSERT(pciio_registry != NULL);
-
-    cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func);
-}
-
-devfs_handle_t
-pciio_device_register(
-		devfs_handle_t connectpt,	/* vertex for /hw/.../pciio/%d */
-		devfs_handle_t master,	/* card's master ASIC (PCI provider) */
-		pciio_slot_t slot,	/* card's slot */
-		pciio_function_t func,	/* card's func */
-		pciio_vendor_id_t vendor_id,
-		pciio_device_id_t device_id)
-{
-    return pciio_device_info_register
-	(connectpt, pciio_device_info_new (NULL, master, slot, func,
-					   vendor_id, device_id));
-}
-
-void
-pciio_device_unregister(devfs_handle_t pconn)
-{
-    DEV_FUNC(pconn,device_unregister)(pconn);
-}
-
-pciio_info_t
-pciio_device_info_new(
-		pciio_info_t pciio_info,
-		devfs_handle_t master,
-		pciio_slot_t slot,
-		pciio_function_t func,
-		pciio_vendor_id_t vendor_id,
-		pciio_device_id_t device_id)
-{
-    if (!pciio_info)
-	GET_NEW(pciio_info);
-    ASSERT(pciio_info != NULL);
-
-    pciio_info->c_slot = slot;
-    pciio_info->c_func = func;
-    pciio_info->c_vendor = vendor_id;
-    pciio_info->c_device = device_id;
-    pciio_info->c_master = master;
-    pciio_info->c_mfast = hwgraph_fastinfo_get(master);
-    pciio_info->c_pops = pciio_provider_fns_get(master);
-    pciio_info->c_efunc = 0;
-    pciio_info->c_einfo = 0;
-
-    return pciio_info;
-}
-
-void
-pciio_device_info_free(pciio_info_t pciio_info)
-{
-    /* NOTE : pciio_info is a structure within the pcibr_info
-     *	      and not a pointer to memory allocated on the heap !!
-     */
-    BZERO((char *)pciio_info,sizeof(pciio_info));
-}
-
-devfs_handle_t
-pciio_device_info_register(
-		devfs_handle_t connectpt,		/* vertex at center of bus */
-		pciio_info_t pciio_info)	/* details about the connectpt */
-{
-    char		name[32];
-    devfs_handle_t	pconn;
-    int device_master_set(devfs_handle_t, devfs_handle_t);
-
-    pciio_slot_func_to_name(name,
-			    pciio_info->c_slot,
-			    pciio_info->c_func);
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_path_add(connectpt, name, &pconn))
-	return pconn;
-
-    pciio_info->c_vertex = pconn;
-    pciio_info_set(pconn, pciio_info);
-#ifdef DEBUG_PCIIO
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(pconn, dname, 256);
-	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
-    }
-#endif /* DEBUG_PCIIO */
-
-    /*
-     * create link to our pci provider
-     */
-
-    device_master_set(pconn, pciio_info->c_master);
-
-#if USRPCI
-    /*
-     * Call into usrpci provider to let it initialize for
-     * the given slot.
-     */
-    if (pciio_info->c_slot != PCIIO_SLOT_NONE)
-	usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);
-#endif
-
-    return pconn;
-}
-
-void
-pciio_device_info_unregister(devfs_handle_t connectpt,
-			     pciio_info_t pciio_info)
-{
-    char		name[32];
-    devfs_handle_t	pconn;
-
-    if (!pciio_info)
-	return;
-
-    pciio_slot_func_to_name(name,
-			    pciio_info->c_slot,
-			    pciio_info->c_func);
-
-    hwgraph_edge_remove(connectpt,name,&pconn);
-    pciio_info_set(pconn,0);
-
-    /* Remove the link to our pci provider */
-    hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL);
-
-
-    hwgraph_vertex_unref(pconn);
-    hwgraph_vertex_destroy(pconn);
-    
-}
-/* Add the pci card inventory information to the hwgraph
- */
-static void
-pciio_device_inventory_add(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
-
-    ASSERT(pciio_info);
-    ASSERT(pciio_info->c_vertex == pconn_vhdl);
-
-    /* Donot add inventory  for non-existent devices */
-    if ((pciio_info->c_vendor == PCIIO_VENDOR_ID_NONE)	||
-	(pciio_info->c_device == PCIIO_DEVICE_ID_NONE))
-	return;
-    device_inventory_add(pconn_vhdl,INV_IOBD,INV_PCIADAP,
-			 pciio_info->c_vendor,pciio_info->c_device,
-			 pciio_info->c_slot);
-}
-
-static void
-pciio_device_inventory_remove(devfs_handle_t pconn_vhdl)
-{
-#ifdef LATER
-    hwgraph_inventory_remove(pconn_vhdl,-1,-1,-1,-1,-1);
-#endif
-}
-
-/*ARGSUSED */
-int
-pciio_device_attach(devfs_handle_t pconn,
-		    int          drv_flags)
-{
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-
-    pciio_device_inventory_add(pconn);
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));
-}
-
-int
-pciio_device_detach(devfs_handle_t pconn,
-		    int          drv_flags)
-{
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-    pciio_device_inventory_remove(pconn);
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_del_connpt(pciio_registry, vendor_id, device_id,
-		          pconn, drv_flags));
-
-}
-
-/*
- * pciio_error_register:
- * arrange for a function to be called with
- * a specified first parameter plus other
- * information when an error is encountered
- * and traced to the pci slot corresponding
- * to the connection point pconn.
- *
- * may also be called with a null function
- * pointer to "unregister" the error handler.
- *
- * NOTE: subsequent calls silently overwrite
- * previous data for this vertex. We assume that
- * cooperating drivers, well, cooperate ...
- */
-void
-pciio_error_register(devfs_handle_t pconn,
-		     error_handler_f *efunc,
-		     error_handler_arg_t einfo)
-{
-    pciio_info_t            pciio_info;
-
-    pciio_info = pciio_info_get(pconn);
-    ASSERT(pciio_info != NULL);
-    pciio_info->c_efunc = efunc;
-    pciio_info->c_einfo = einfo;
-}
-
-/*
- * Check if any device has been found in this slot, and return
- * true or false
- * vhdl is the vertex for the slot
- */
-int
-pciio_slot_inuse(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-
-    ASSERT(pciio_info);
-    ASSERT(pciio_info->c_vertex == pconn_vhdl);
-    if (pciio_info->c_vendor) {
-	/*
-	 * Non-zero value for vendor indicate
-	 * a board being found in this slot.
-	 */
-	return 1;
-    }
-    return 0;
-}
-
-int
-pciio_dma_enabled(devfs_handle_t pconn_vhdl)
-{
-	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);
-}
-
-/*
- * These are complementary Linux interfaces that takes in a pci_dev * as the 
- * first arguement instead of devfs_handle_t.
- */
-iopaddr_t               snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned);
-pciio_dmamap_t          snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned);
-void                    snia_pciio_dmamap_free(pciio_dmamap_t);
-iopaddr_t               snia_pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-void                    snia_pciio_dmamap_done(pciio_dmamap_t);
-pciio_endian_t          snia_pciio_endian_set(struct pci_dev *pci_dev, pciio_endian_t device_end,
-					      pciio_endian_t desired_end);
-
-#include <linux/module.h>
-EXPORT_SYMBOL(snia_pciio_dmatrans_addr);
-EXPORT_SYMBOL(snia_pciio_dmamap_alloc);
-EXPORT_SYMBOL(snia_pciio_dmamap_free);
-EXPORT_SYMBOL(snia_pciio_dmamap_addr);
-EXPORT_SYMBOL(snia_pciio_dmamap_done);
-EXPORT_SYMBOL(snia_pciio_endian_set);
-
-pciio_endian_t
-snia_pciio_endian_set(struct pci_dev *pci_dev,
-	pciio_endian_t device_end,
-	pciio_endian_t desired_end)
-{
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-	
-	return DEV_FUNC(dev, endian_set)
-		(dev, device_end, desired_end);
-}
-
-iopaddr_t
-snia_pciio_dmatrans_addr(struct pci_dev *pci_dev, /* translate for this device */
-                    device_desc_t dev_desc,     /* device descriptor */
-                    paddr_t paddr,      /* system physical address */
-                    size_t byte_count,  /* length */
-                    unsigned flags)
-{                                       /* defined in dma.h */
-
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-    return DEV_FUNC(dev, dmatrans_addr)
-        (dev, dev_desc, paddr, byte_count, flags);
-}
-
-pciio_dmamap_t
-snia_pciio_dmamap_alloc(struct pci_dev *pci_dev,  /* set up mappings for this device */
-                   device_desc_t dev_desc,      /* device descriptor */
-                   size_t byte_count_max,       /* max size of a mapping */
-                   unsigned flags)
-{                                       /* defined in dma.h */
-
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-    return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-        (dev, dev_desc, byte_count_max, flags);
-}
-
-void
-snia_pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_free)
-        (CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-snia_pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,  /* use these mapping resources */
-                  paddr_t paddr,        /* map for this address */
-                  size_t byte_count)
-{                                       /* map this many bytes */
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
-        (CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
-}
-
-void
-snia_pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_done)
-        (CAST_DMAMAP(pciio_dmamap));
-}
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/platform_init/Makefile linux-2.4.22-pre3/arch/ia64/sn/io/platform_init/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/io/platform_init/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/platform_init/Makefile	2003-07-05 18:09:41.000000000 -0700
@@ -0,0 +1,16 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+O_TARGET := snio.o
+
+obj-y				+=  sgi_io_init.o irix_io_init.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/platform_init/irix_io_init.c linux-2.4.22-pre3/arch/ia64/sn/io/platform_init/irix_io_init.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/platform_init/irix_io_init.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/platform_init/irix_io_init.c	2003-07-05 18:09:41.000000000 -0700
@@ -0,0 +1,89 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/pci/pciba.h>
+#include <linux/smp.h>
+#include <asm/sn/simulator.h>
+
+extern void init_all_devices(void);
+extern void klhwg_add_all_modules(vertex_hdl_t);
+extern void klhwg_add_all_nodes(vertex_hdl_t);
+
+extern vertex_hdl_t hwgraph_root;
+extern void io_module_init(void);
+extern int pci_bus_to_hcl_cvlink(void);
+extern void mlreset(void);
+
+/* #define DEBUG_IO_INIT 1 */
+#ifdef DEBUG_IO_INIT
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG_IO_INIT */
+
+/*
+ * This routine is responsible for the setup of all the IRIX hwgraph style
+ * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
+ * is called just before the generic Linux PCI layer does its probing (by 
+ * platform_pci_fixup aka sn_pci_fixup).
+ *
+ * It is very IMPORTANT that this call is only made by the Master CPU!
+ *
+ */
+
+void
+irix_io_init(void)
+{
+	cnodeid_t cnode;
+
+	/*
+	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
+	 */
+	mlreset();
+
+        /*
+         * Initialize platform-dependent vertices in the hwgraph:
+         *      module
+         *      node
+         *      cpu
+         *      memory
+         *      slot
+         *      hub
+         *      router
+         *      xbow
+         */
+
+        io_module_init(); /* Use to be called module_init() .. */
+        klhwg_add_all_modules(hwgraph_root);
+        klhwg_add_all_nodes(hwgraph_root);
+
+	for (cnode = 0; cnode < numnodes; cnode++) {
+		extern void per_hub_init(cnodeid_t);
+		per_hub_init(cnode);
+	}
+
+	/* We can do headless hub cnodes here .. */
+
+	/*
+	 *
+	 * Our IO Infrastructure drivers are in place .. 
+	 * Initialize the whole IO Infrastructure .. xwidget/device probes.
+	 *
+	 */
+	init_all_devices();
+	pci_bus_to_hcl_cvlink();
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/platform_init/sgi_io_init.c linux-2.4.22-pre3/arch/ia64/sn/io/platform_init/sgi_io_init.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/platform_init/sgi_io_init.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/platform_init/sgi_io_init.c	2003-07-05 18:09:41.000000000 -0700
@@ -0,0 +1,109 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/pda.h>
+#include <linux/smp.h>
+
+extern int init_hcl(void);
+
+/*
+ * per_hub_init
+ *
+ * 	This code is executed once for each Hub chip.
+ */
+void
+per_hub_init(cnodeid_t cnode)
+{
+	nasid_t		nasid;
+	nodepda_t	*npdap;
+	ii_icmr_u_t	ii_icmr;
+	ii_ibcr_u_t	ii_ibcr;
+	ii_ilcsr_u_t	ii_ilcsr;
+
+	nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+	ASSERT(nasid != INVALID_NASID);
+	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
+
+	npdap = NODEPDA(cnode);
+
+	/* Disable the request and reply errors. */
+	REMOTE_HUB_S(nasid, IIO_IWEIM, 0xC000);
+
+	/*
+	 * Set the total number of CRBs that can be used.
+	 */
+	ii_icmr.ii_icmr_regval= 0x0;
+	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xf;
+	if (enable_shub_wars_1_1() ) {
+		// Set bit one of ICMR to prevent II from sending interrupt for II bug.
+		ii_icmr.ii_icmr_regval |= 0x1; 
+	}
+	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
+
+	/*
+	 * Set the number of CRBs that both of the BTEs combined
+	 * can use minus 1.
+	 */
+	ii_ibcr.ii_ibcr_regval= 0x0;
+	ii_ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
+	if (ii_ilcsr.ii_ilcsr_fld_s.i_llp_stat & LNK_STAT_WORKING) {
+	    ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
+	} else {
+	    /*
+	     * if the LLP is down, there is no attached I/O, so
+	    * give BTE all the CRBs.
+	    */
+	    ii_ibcr.ii_ibcr_fld_s.i_count = 0x14;
+	}
+	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
+
+	/*
+	 * Set CRB timeout to be 10ms.
+	 */
+	REMOTE_HUB_S(nasid, IIO_ICTP, 0xffffff );
+	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
+
+	/* Initialize error interrupts for this hub. */
+	hub_error_init(cnode);
+}
+
+/*
+ * This routine is responsible for the setup of all the IRIX hwgraph style
+ * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
+ * is called just before the generic Linux PCI layer does its probing (by 
+ * platform_pci_fixup aka sn_pci_fixup).
+ *
+ * It is very IMPORTANT that this call is only made by the Master CPU!
+ *
+ */
+
+void
+sgi_master_io_infr_init(void)
+{
+	extern void irix_io_init(void);
+
+	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
+	irix_io_init(); /* Do IRIX Compatibility IO Init */
+
+#ifdef	CONFIG_KDB
+	{
+		extern void kdba_io_init(void);
+		kdba_io_init();
+	}
+#endif
+
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sgi_if.c linux-2.4.22-pre3/arch/ia64/sn/io/sgi_if.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sgi_if.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sgi_if.c	2003-07-05 18:09:41.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -20,8 +20,6 @@
 #include <asm/sn/pci/pciio.h>
 #include <asm/sn/slotnum.h>
 
-unsigned char Is_pic_on_this_nasid[512];	/* non-0 when this is a pic shub */
-
 void *
 snia_kmem_zalloc(size_t size, int flag)
 {
@@ -37,13 +35,6 @@
         kfree(ptr);
 }
 
-int
-nic_vertex_info_match(devfs_handle_t v, char *s)
-{
-	/* we don't support this */
-	return(0);
-}
-
 /*
  * the alloc/free_node routines do a simple kmalloc for now ..
  */
@@ -64,74 +55,6 @@
 }
 
 
-#define xtod(c)         ((c) <= '9' ? '0' - (c) : 'a' - (c) - 10)
-long
-atoi(register char *p)
-{
-        register long n;
-        register int c, neg = 0;
-
-        if (p == NULL)
-                return 0;
-
-        if (!isdigit(c = *p)) {
-                while (isspace(c))
-                        c = *++p;
-                switch (c) {
-                case '-':
-                        neg++;
-                case '+': /* fall-through */
-                        c = *++p;
-                }
-                if (!isdigit(c))
-                        return (0);
-        }
-        if (c == '0' && *(p + 1) == 'x') {
-                p += 2;
-                c = *p;
-                n = xtod(c);
-                while ((c = *++p) && isxdigit(c)) {
-                        n *= 16; /* two steps to avoid unnecessary overflow */
-                        n += xtod(c); /* accum neg to avoid surprises at MAX */
-                }
-        } else {
-                n = '0' - c;
-                while ((c = *++p) && isdigit(c)) {
-                        n *= 10; /* two steps to avoid unnecessary overflow */
-                        n += '0' - c; /* accum neg to avoid surprises at MAX */
-                }
-        }
-        return (neg ? n : -n);
-}
-
-char *
-strtok_r(char *string, const char *sepset, char **lasts)
-{
-        register char   *q, *r;
-
-        /*first or subsequent call*/
-        if (string == NULL)
-                string = *lasts;
-
-        if(string == 0)         /* return if no tokens remaining */
-                return(NULL);
-
-        q = string + strspn(string, sepset);    /* skip leading separators */
-
-        if(*q == '\0') {                /* return if no tokens remaining */
-                *lasts = 0;     /* indicate this is last token */
-                return(NULL);
-        }
-
-        if((r = strpbrk(q, sepset)) == NULL)    /* move past token */
-                *lasts = 0;     /* indicate this is last token */
-        else {
-                *r = '\0';
-                *lasts = r+1;
-        }
-        return(q);
-}
-
 /*
  * print_register() allows formatted printing of bit fields.  individual
  * bit fields are described by a struct reg_desc, multiple bit fields within
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sgi_io_init.c linux-2.4.22-pre3/arch/ia64/sn/io/sgi_io_init.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sgi_io_init.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sgi_io_init.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,336 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pciba.h>
-#include <linux/smp.h>
-
-extern void mlreset(int );
-extern int init_hcl(void);
-extern void klgraph_hack_init(void);
-extern void hubspc_init(void);
-extern void pciio_init(void);
-extern void pcibr_init(void);
-extern void xtalk_init(void);
-extern void xbow_init(void);
-extern void xbmon_init(void);
-extern void pciiox_init(void);
-extern void usrpci_init(void);
-extern void ioc3_init(void);
-extern void initialize_io(void);
-#if defined(CONFIG_IA64_SGI_SN1)
-extern void intr_clear_all(nasid_t);
-#endif
-extern void klhwg_add_all_modules(devfs_handle_t);
-extern void klhwg_add_all_nodes(devfs_handle_t);
-
-void sn_mp_setup(void);
-extern devfs_handle_t hwgraph_root;
-extern void io_module_init(void);
-extern void pci_bus_cvlink_init(void);
-extern void temp_hack(void);
-
-extern int pci_bus_to_hcl_cvlink(void);
-
-/* #define DEBUG_IO_INIT 1 */
-#ifdef DEBUG_IO_INIT
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_IO_INIT */
-
-/*
- * per_hub_init
- *
- * 	This code is executed once for each Hub chip.
- */
-static void
-per_hub_init(cnodeid_t cnode)
-{
-	nasid_t		nasid;
-	nodepda_t	*npdap;
-	ii_icmr_u_t	ii_icmr;
-	ii_ibcr_u_t	ii_ibcr;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	ASSERT(nasid != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
-
-	npdap = NODEPDA(cnode);
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	/* initialize per-node synergy perf instrumentation */
-	npdap->synergy_perf_enabled = 0; /* off by default */
-	npdap->synergy_perf_lock = SPIN_LOCK_UNLOCKED;
-	npdap->synergy_perf_freq = SYNERGY_PERF_FREQ_DEFAULT;
-	npdap->synergy_inactive_intervals = 0;
-	npdap->synergy_active_intervals = 0;
-	npdap->synergy_perf_data = NULL;
-	npdap->synergy_perf_first = NULL;
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-
-	/*
-	 * Set the total number of CRBs that can be used.
-	 */
-	ii_icmr.ii_icmr_regval= 0x0;
-	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF;
-	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
-
-	/*
-	 * Set the number of CRBs that both of the BTEs combined
-	 * can use minus 1.
-	 */
-	ii_ibcr.ii_ibcr_regval= 0x0;
-	ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
-	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
-
-	/*
-	 * Set CRB timeout to be 10ms.
-	 */
-	REMOTE_HUB_S(nasid, IIO_ICTP, 0x1000 );
-	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
-
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	/* Reserve all of the hardwired interrupt levels. */
-	intr_reserve_hardwired(cnode);
-#endif
-
-	/* Initialize error interrupts for this hub. */
-	hub_error_init(cnode);
-}
-
-/*
- * This routine is responsible for the setup of all the IRIX hwgraph style
- * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
- * is called just before the generic Linux PCI layer does its probing (by 
- * platform_pci_fixup aka sn_pci_fixup).
- *
- * It is very IMPORTANT that this call is only made by the Master CPU!
- *
- */
-
-void
-sgi_master_io_infr_init(void)
-{
-	int cnode;
-
-	/*
-	 * Do any early init stuff .. einit_tbl[] etc.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling init_hcl().\n");
-	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
-
-#ifdef Colin
-
-printk("Testing out Xbridge Access .. if it hangs Xbridge is not init yet.\n");
-printk("	Reading Xbridge WID at address 0xc00000080f000000 0x%p\n", (* (volatile uint32_t *)(0xc00000080f000000)));
-
-printk("Testing out PCI Address Space Accesses\n");
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020000 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020000)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020001 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020001)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020002 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020002)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020003 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020003)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020004)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020005 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020005)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020006 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020006)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020007 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020007)));
-
-printk("	Testing PCI Config Word: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020004)));
-
-printk("	Testing PCI Config Word: address 0xc00000080f020008 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020008)));
-
-#endif
-
-	/*
-	 * initialize the Linux PCI to xwidget vertexes ..
-	 */
-	DBG("--> sgi_master_io_infr_init: calling pci_bus_cvlink_init().\n");
-	pci_bus_cvlink_init();
-
-#ifdef BRINGUP
-#ifdef CONFIG_IA64_SGI_SN1
-	/*
-	 * Hack to provide statically initialzed klgraph entries.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n");
-	klgraph_hack_init();
-#endif /* CONFIG_IA64_SGI_SN1 */
-#endif /* BRINGUP */
-
-	/*
-	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling mlreset(0).\n");
-	mlreset(0); /* Master .. */
-
-	/*
-	 * allowboot() is called by kern/os/main.c in main()
-	 * Emulate allowboot() ...
-	 *   per_cpu_init() - only need per_hub_init()
-	 *   cpu_io_setup() - Nothing to do.
-	 * 
-	 */
-	DBG("--> sgi_master_io_infr_init: calling sn_mp_setup().\n");
-	sn_mp_setup();
-
-	DBG("--> sgi_master_io_infr_init: calling per_hub_init(0).\n");
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		per_hub_init(cnode);
-	}
-
-	/* We can do headless hub cnodes here .. */
-
-	/*
-	 * io_init[] stuff.
-	 *
-	 * Get SGI IO Infrastructure drivers to init and register with 
-	 * each other etc.
-	 */
-
-	DBG("--> sgi_master_io_infr_init: calling hubspc_init()\n");
-	hubspc_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pciio_init()\n");
-	pciio_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pcibr_init()\n");
-	pcibr_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xtalk_init()\n");
-	xtalk_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xbow_init()\n");
-	xbow_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xbmon_init()\n");
-	xbmon_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pciiox_init()\n");
-	pciiox_init();
-
-	DBG("--> sgi_master_io_infr_init: calling usrpci_init()\n");
-	usrpci_init();
-
-	DBG("--> sgi_master_io_infr_init: calling ioc3_init()\n");
-	ioc3_init();
-
-	/*
-	 *
-	 * Our IO Infrastructure drivers are in place .. 
-	 * Initialize the whole IO Infrastructure .. xwidget/device probes.
-	 *
-	 */
-	DBG("--> sgi_master_io_infr_init: Start Probe and IO Initialization\n");
-	initialize_io();
-
-	DBG("--> sgi_master_io_infr_init: Setting up SGI IO Links for Linux PCI\n");
-	pci_bus_to_hcl_cvlink();
-
-#ifdef CONFIG_PCIBA
-	DBG("--> sgi_master_io_infr_init: calling pciba_init()\n");
-	pciba_init();
-#endif
-
-	DBG("--> Leave sgi_master_io_infr_init: DONE setting up SGI Links for PCI\n");
-}
-
-/*
- * sgi_slave_io_infr_init - This routine must be called on all cpus except 
- * the Master CPU.
- */
-void
-sgi_slave_io_infr_init(void)
-{
-	/* Emulate cboot() .. */
-	mlreset(1); /* This is a slave cpu */
-
-	// per_hub_init(0); /* Need to get and send in actual cnode number */
-
-	/* Done */
-}
-
-/*
- * One-time setup for MP SN.
- * Allocate per-node data, slurp prom klconfig information and
- * convert it to hwgraph information.
- */
-void
-sn_mp_setup(void)
-{
-	cnodeid_t	cnode;
-	cpuid_t		cpu;
-
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		/* Skip holes in CPU space */
-		if (cpu_enabled(cpu)) {
-			init_platform_pda(cpu);
-		}
-	}
-
-	/*
-	 * Initialize platform-dependent vertices in the hwgraph:
-	 *	module
-	 *	node
-	 *	cpu
-	 *	memory
-	 *	slot
-	 *	hub
-	 *	router
-	 *	xbow
-	 */
-
-	DBG("sn_mp_io_setup: calling io_module_init()\n");
-	io_module_init(); /* Use to be called module_init() .. */
-
-	DBG("sn_mp_setup: calling klhwg_add_all_modules()\n");
-	klhwg_add_all_modules(hwgraph_root);
-	DBG("sn_mp_setup: calling klhwg_add_all_nodes()\n");
-	klhwg_add_all_nodes(hwgraph_root);
-
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-
-		/*
-		 * This routine clears the Hub's Interrupt registers.
-		 */
-		/*
-		 * We need to move this intr_clear_all() routine 
-		 * from SN/intr.c to a more appropriate file.
-		 * Talk to Al Mayer.
-		 */
-#if defined(CONFIG_IA64_SGI_SN1)
-                intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
-#endif
-		/* now init the hub */
-	//	per_hub_init(cnode);
-
-	}
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	synergy_perf_init();
-#endif
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sgi_io_sim.c linux-2.4.22-pre3/arch/ia64/sn/io/sgi_io_sim.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sgi_io_sim.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sgi_io_sim.c	2003-07-05 18:09:41.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
@@ -15,18 +15,11 @@
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/module.h>
-#include <asm/sn/nic.h>
 #include <asm/sn/sn_private.h>
 
-cpuid_t         master_procid = 0;
+cpuid_t         master_procid;
 char arg_maxnodes[4];
 
-extern void init_all_devices(void);
-
-#if defined(CONFIG_IA64_SGI_SN1)
-synergy_da_t	*Synergy_da_indr[MAX_COMPACT_NODES * 2];
-#endif
-
 /*
  * Return non-zero if the given variable was specified
  */
@@ -36,44 +29,12 @@
         return (strlen(s) != 0);
 }
 
-void xbmon_init(void)
-{
-	FIXME("xbmon_init : no-op\n");
-
-}
-
-void pciiox_init(void)
-{
-	FIXME("pciiox_init : no-op\n");
-
-}
-
-void usrpci_init(void)
-{
-	FIXME("usrpci_init : no-op\n");
-
-}
-
-void ioc3_init(void)
-{
-	FIXME("ioc3_init : no-op\n");
-
-}
-
-void initialize_io(void)
-{
-
-	init_all_devices();
-}
-
 /*
  * Routines provided by ml/SN/promif.c.
  */
-static __psunsigned_t master_bridge_base = (__psunsigned_t)NULL;
+static __psunsigned_t master_bridge_base;
 nasid_t console_nasid = (nasid_t)-1;
-#if !defined(CONFIG_IA64_SGI_SN1)
 char master_baseio_wid;
-#endif
 static char console_wid;
 static char console_pcislot;
 
@@ -95,27 +56,6 @@
                 return 0;
 }
 
-#if defined(CONFIG_IA64_SGI_SN1)
-int
-is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid)
-{
-
-        /*
-         * If the widget numbers are different, we're not the master.
-         */
-        if (test_wid != (xwidgetnum_t)console_wid)
-                return 0;
-
-        /*
-         * If the NASIDs are the same or equivalent, we're the master.
-         */
-        if (check_nasid_equiv(test_nasid, console_nasid)) {
-                return 1;
-        } else {
-                return 0;
-        }
-}
-#else
 int
 is_master_baseio_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid)
 {
@@ -137,14 +77,3 @@
                 return 0;
         }
 }
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-/*
- * Routines provided by ml/SN/nvram.c
- */
-void
-nvram_baseinit(void)
-{
-	FIXME("nvram_baseinit : no-op\n");
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/Makefile linux-2.4.22-pre3/arch/ia64/sn/io/sn1/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/Makefile	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/Makefile	1969-12-31 16:00:00.000000000 -0800
@@ -1,25 +0,0 @@
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 2002 Silicon Graphics, Inc.  All Rights Reserved.
-#
-# Makefile for the sn1 io routines.
-
-EXTRA_CFLAGS    := -DLITTLE_ENDIAN
-
-O_TARGET := snio.o
-
-export-objs := pciio.o
-
-obj-$(CONFIG_IA64_SGI_SN1)	+= ml_SN_intr.o mem_refcnt.o hubcounters.o \
-				   ip37.o huberror.o hub_intr.o pcibr.o \
-				   eeprom.o l1.o l1_command.o pciio.o \
-				   klconflib.o klgraph.o \
-				   efi-rtc.o xbow.o xtalk.o \
-				   ml_SN_init.o ml_iograph.o module.o \
-				   pci_bus_cvlink.o sgi_io_init.o
-
-
-include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/eeprom.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/eeprom.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/eeprom.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/eeprom.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1421 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * WARNING:     There is more than one copy of this file in different isms.
- *              All copies must be kept exactly in sync.
- *              Do not modify this file without also updating the following:
- *
- *              irix/kern/io/eeprom.c
- *              stand/arcs/lib/libsk/ml/eeprom.c
- *		stand/arcs/lib/libkl/io/eeprom.c
- *
- *      (from time to time they might not be in sync but that's due to bringup
- *       activity - this comment is to remind us that they eventually have to
- *       get back together)
- *
- * eeprom.c
- *
- * access to board-mounted EEPROMs via the L1 system controllers
- *
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/simulator.h>
-
-#if defined(EEPROM_DEBUG)
-#define db_printf(x) printk x
-#else
-#define db_printf(x) printk x
-#endif
-
-#define BCOPY(x,y,z)	memcpy(y,x,z)
-
-#define UNDERSCORE	0	/* don't convert underscores to hyphens */
-#define HYPHEN		1	/* convert underscores to hyphens */
-
-void		copy_ascii_field( char *to, char *from, int length,
-			          int change_underscore );
-uint64_t	generate_unique_id( char *sn, int sn_len );
-uchar_t		char_to_base36( char c );
-int		nicify( char *dst, eeprom_brd_record_t *src );
-static void	int64_to_hex_string( char *out, uint64_t val );
-
-// extern int router_lock( net_vec_t, int, int );
-// extern int router_unlock( net_vec_t );
-#define ROUTER_LOCK(p) 	// router_lock(p, 10000, 3000000)
-#define ROUTER_UNLOCK(p) 	// router_unlock(p)
-
-#define IP27LOG_OVNIC           "OverrideNIC"
-
-
-/* the following function converts an EEPROM record to a close facsimile
- * of the string returned by reading a Dallas Semiconductor NIC (see
- * one of the many incarnations of nic.c for details on that driver)
- */
-int nicify( char *dst, eeprom_brd_record_t *src )
-{
-    int field_len;
-    uint64_t unique_id;
-    char *cur_dst = dst;
-    eeprom_board_ia_t   *board;
-
-    board   = src->board_ia;
-    ASSERT( board );  /* there should always be a board info area */
-
-    /* copy part number */
-    strcpy( cur_dst, "Part:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->part_num_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->part_num_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->part_num, field_len, HYPHEN );
-    cur_dst += field_len;
-
-    /* copy product name */
-    strcpy( cur_dst, ";Name:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->product_tl & FIELD_FORMAT_MASK) == FIELD_FORMAT_ASCII );
-    field_len = board->product_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->product, field_len, UNDERSCORE );
-    cur_dst += field_len;
-
-    /* copy serial number */
-    strcpy( cur_dst, ";Serial:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->serial_num_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->serial_num_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->serial_num, field_len,
-		      HYPHEN);
-
-    cur_dst += field_len;
-
-    /* copy revision */
-    strcpy( cur_dst, ";Revision:");
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->board_rev_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->board_rev_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->board_rev, field_len, HYPHEN );
-    cur_dst += field_len;
-
-    /* EEPROMs don't have equivalents for the Group, Capability and
-     * Variety fields, so we pad these with 0's
-     */
-    strcpy( cur_dst, ";Group:ff;Capability:ffffffff;Variety:ff" );
-    cur_dst += strlen( cur_dst );
-
-    /* use the board serial number to "fake" a laser id */
-    strcpy( cur_dst, ";Laser:" );
-    cur_dst += strlen( cur_dst );
-    unique_id = generate_unique_id( board->serial_num,
-				    board->serial_num_tl & FIELD_LENGTH_MASK );
-    int64_to_hex_string( cur_dst, unique_id );
-    strcat( dst, ";" );
-
-    return 1;
-}
-
-
-/* These functions borrow heavily from chars2* in nic.c
- */
-void copy_ascii_field( char *to, char *from, int length,
-		       int change_underscore )
-{
-    int i;
-    for( i = 0; i < length; i++ ) {
-
-	/* change underscores to hyphens if requested */
-	if( from[i] == '_' && change_underscore == HYPHEN )
-	    to[i] = '-';
-
-	/* ; and ; are separators, so mustn't appear within
-	 * a field */
-	else if( from[i] == ':' || from[i] == ';' )
-	    to[i] = '?';
-
-	/* I'm not sure why or if ASCII character 0xff would
-	 * show up in an EEPROM field, but the NIC parsing
-	 * routines wouldn't like it if it did... so we
-	 * get rid of it, just in case. */
-	else if( (unsigned char)from[i] == (unsigned char)0xff )
-	    to[i] = ' ';
-	
-	/* unprintable characters are replaced with . */
-	else if( from[i] < ' ' || from[i] >= 0x7f )
-	    to[i] = '.';
-
-	/* otherwise, just copy the character */
-	else
-	    to[i] = from[i];
-    }
-
-    if( i == 0 ) {
-	to[i] = ' '; /* return at least a space... */
-	i++;
-    }
-    to[i] = 0;	     /* terminating null */
-}
-
-/* Note that int64_to_hex_string currently only has a big-endian
- * implementation.
- */
-#ifdef _MIPSEB
-static void int64_to_hex_string( char *out, uint64_t val )
-{
-    int i;
-    uchar_t table[] = "0123456789abcdef";
-    uchar_t *byte_ptr = (uchar_t *)&val;
-    for( i = 0; i < sizeof(uint64_t); i++ ) {
-	out[i*2] = table[ ((*byte_ptr) >> 4) & 0x0f ];
-	out[i*2+1] = table[ (*byte_ptr) & 0x0f ];
-	byte_ptr++;
-    }
-    out[i*2] = '\0';
-}
-
-#else /* little endian */
-
-static void int64_to_hex_string( char *out, uint64_t val )
-{
-
-
-	printk("int64_to_hex_string needs a little-endian implementation.\n");
-}
-#endif /* _MIPSEB */
-
-/* Convert a standard ASCII serial number to a unique integer
- * id number by treating the serial number string as though
- * it were a base 36 number
- */
-uint64_t generate_unique_id( char *sn, int sn_len )
-{
-    int uid = 0;
-    int i;
-
-    #define VALID_BASE36(c)	((c >= '0' && c <='9') \
-			    ||   (c >= 'A' && c <='Z') \
-			    ||   (c >= 'a' && c <='z'))
-
-    for( i = 0; i < sn_len; i++ ) {
-	if( !VALID_BASE36(sn[i]) )
-	    continue;
-	uid *= 36;
-	uid += char_to_base36( sn[i] );
-    }
-
-    if( uid == 0 )
-	return rtc_time();
-
-    return uid;
-}
-
-uchar_t char_to_base36( char c )
-{
-    uchar_t val;
-
-    if( c >= '0' && c <= '9' )
-	val = (c - '0');
-
-    else if( c >= 'A' && c <= 'Z' )
-	val = (c - 'A' + 10);
-
-    else if( c >= 'a' && c <= 'z' )
-	val = (c - 'a' + 10);
-
-    else val = 0;
-
-    return val;
-}
-
-
-/* given a pointer to the three-byte little-endian EEPROM representation
- * of date-of-manufacture, this function translates to a big-endian
- * integer format
- */
-int eeprom_xlate_board_mfr_date( uchar_t *src )
-{
-    int rval = 0;
-    rval += *src; src++;
-    rval += ((int)(*src) << 8); src ++;
-    rval += ((int)(*src) << 16);
-    return rval;
-}
-
-
-int eeprom_str( char *nic_str, nasid_t nasid, int component )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    if( (component & C_DIMM) == C_DIMM ) {
-	/* this function isn't applicable to DIMMs */
-	return EEP_PARAM;
-    }
-    else {
-	eep.board_ia = &board;
-	eep.spd = NULL;
-	if( !(component & SUBORD_MASK) )
-	    eep.chassis_ia = &chassis;  /* only main boards have a chassis
-					 * info area */
-	else
-	    eep.chassis_ia = NULL;
-    }
-    
-    switch( component & BRICK_MASK ) {
-      case C_BRICK:
-	r = cbrick_eeprom_read( &eep, nasid, component );
-	break;
-      case IO_BRICK:
-	r = iobrick_eeprom_read( &eep, nasid, component );
-	break;
-      default:
-	return EEP_PARAM;  /* must be an invalid component */
-    }
-    if( r )
-	return r;
-    if( !nicify( nic_str, &eep ) )
-	return EEP_NICIFY;
-
-    return EEP_OK;
-}
-
-int vector_eeprom_str( char *nic_str, nasid_t nasid,
-		       int component, net_vec_t path )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    eep.board_ia = &board;
-    if( !(component & SUBORD_MASK) )
-        eep.chassis_ia = &chassis;  /* only main boards have a chassis
-                                     * info area */
-    else
-        eep.chassis_ia = NULL;
-
-    if( !(component & VECTOR) )
-	return EEP_PARAM;
-
-    if( (r = vector_eeprom_read( &eep, nasid, path, component )) )
-	return r;
-
-    if( !nicify( nic_str, &eep ) )
-        return EEP_NICIFY;
-
-    return EEP_OK;
-}
-
-
-int is_iobrick( int nasid, int widget_num )
-{
-    uint32_t wid_reg;
-    int part_num, mfg_num;
-
-    /* Read the widget's WIDGET_ID register to get
-     * its part number and mfg number
-     */
-    wid_reg = *(volatile int32_t *)
-        (NODE_SWIN_BASE( nasid, widget_num ) + WIDGET_ID);
-
-    part_num = (wid_reg & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT;
-    mfg_num = (wid_reg & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT;
-
-    /* Is this the "xbow part" of an XBridge?  If so, this
-     * widget is definitely part of an I/O brick.
-     */
-    if( part_num == XXBOW_WIDGET_PART_NUM &&
-	mfg_num == XXBOW_WIDGET_MFGR_NUM )
-
-	return 1;
-
-    /* Is this a "bridge part" of an XBridge?  If so, once
-     * again, we know this widget is part of an I/O brick.
-     */
-    if( part_num == XBRIDGE_WIDGET_PART_NUM &&
-	mfg_num == XBRIDGE_WIDGET_MFGR_NUM )
-
-	return 1;
-
-    return 0;
-}
-
-
-int cbrick_uid_get( nasid_t nasid, uint64_t *uid )
-{
-    char uid_str[32];
-    char msg[BRL1_QSIZE];
-    int subch, len;
-    l1sc_t sc;
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* If the promlog variable pointed to by IP27LOG_OVNIC is set,
-     * use that value for the cbrick UID rather than the EEPROM
-     * serial number.
-     */
-#ifdef LOG_GETENV
-    if( ip27log_getenv( nasid, IP27LOG_OVNIC, uid_str, NULL, 0 ) >= 0 )
-    {
-	/* We successfully read IP27LOG_OVNIC, so return it as the UID. */
-	db_printf(( "cbrick_uid_get:"
-		    "Overriding UID with environment variable %s\n", 
-		    IP27LOG_OVNIC ));
-	*uid = strtoull( uid_str, NULL, 0 );
-	return EEP_OK;
-    }
-#endif
-
-    /* If this brick is retrieving its own uid, use the local l1sc_t to
-     * arbitrate access to the l1; otherwise, set up a new one.
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &sc;
-	sc_init( &sc, nasid, BRL1_LOCALHUB_UART );
-    }
-
-    /* fill in msg with the opcode & params */
-    BZERO( msg, BRL1_QSIZE );
-    if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 )
-	return EEP_L1;
-
-    if( (len = sc_construct_msg( scp, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SER_NUM, 0 )) < 0 )
-    {
-	sc_close( scp, subch );
-	return( EEP_L1 );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( scp, subch, msg, msg, &len ) ) {
-	sc_close( scp, subch );
-	return( EEP_L1 );
-    }
-
-    /* free up subchannel */
-    sc_close(scp, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 )
-    {
-	return( EEP_L1 );
-    }
-
-    *uid = generate_unique_id( uid_str, strlen( uid_str ) );
-
-    return EEP_OK;
-}
-
-
-int rbrick_uid_get( nasid_t nasid, net_vec_t path, uint64_t *uid )
-{
-    char uid_str[32];
-    char msg[BRL1_QSIZE];
-    int subch, len;
-    l1sc_t sc;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-#define FAIL								\
-    {									\
-	*uid = rtc_time();						\
-	printk( "rbrick_uid_get failed; using current time as uid\n" );	\
-	return EEP_OK;							\
-    }
-
-    ROUTER_LOCK(path);
-    sc_init( &sc, nasid, path );
-
-    /* fill in msg with the opcode & params */
-    BZERO( msg, BRL1_QSIZE );
-    if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) {
-	ROUTER_UNLOCK(path);
-	FAIL;
-    }
-
-    if( (len = sc_construct_msg( &sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SER_NUM, 0 )) < 0 )
-    {
-	ROUTER_UNLOCK(path);
-	sc_close( &sc, subch );
-	FAIL;
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( &sc, subch, msg, msg, &len ) ) {
-	ROUTER_UNLOCK(path);
-	sc_close( &sc, subch );
-	FAIL;
-    }
-
-    /* free up subchannel */
-    ROUTER_UNLOCK(path);
-    sc_close(&sc, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 )
-    {
-	FAIL;
-    }
-
-    *uid = generate_unique_id( uid_str, strlen( uid_str ) );
-
-    return EEP_OK;
-}
-
-int iobrick_uid_get( nasid_t nasid, uint64_t *uid )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    eep.board_ia = &board;
-    eep.chassis_ia = &chassis;
-    eep.spd = NULL;
-
-    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );
-    if( r != EEP_OK ) {
-        *uid = rtc_time();
-        return r;
-    }
-
-    *uid = generate_unique_id( board.serial_num,
-                               board.serial_num_tl & FIELD_LENGTH_MASK );
-
-    return EEP_OK;
-}
-
-
-int ibrick_mac_addr_get( nasid_t nasid, char *eaddr )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-    char *tmp;
-
-    eep.board_ia = &board;
-    eep.chassis_ia = &chassis;
-    eep.spd = NULL;
-
-    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );
-    if( (r != EEP_OK) || (board.mac_addr[0] == '\0') ) {
-	db_printf(( "ibrick_mac_addr_get: "
-		    "Couldn't read MAC address from EEPROM\n" ));
-	return EEP_L1;
-    }
-    else {
-	/* successfully read info area */
-	int ix;
-	tmp = board.mac_addr;
-	for( ix = 0; ix < (board.mac_addr_tl & FIELD_LENGTH_MASK); ix++ )
-	{
-	    *eaddr++ = *tmp++;
-	}
-	*eaddr = '\0';
-    }
-
-    return EEP_OK;
-}
-
-
-/* 
- * eeprom_vertex_info_set
- *
- * Given a vertex handle, a component designation, a starting nasid
- * and (in the case of a router) a vector path to the component, this
- * function will read the EEPROM and attach the resulting information
- * to the vertex in the same string format as that provided by the
- * Dallas Semiconductor NIC drivers.  If the vertex already has the
- * string, this function just returns the string.
- */
-
-extern char *nic_vertex_info_get( devfs_handle_t );
-extern void nic_vmc_check( devfs_handle_t, char * );
-/* the following were lifted from nic.c - change later? */
-#define MAX_INFO 2048
-#define NEWSZ(ptr,sz)   ((ptr) = kern_malloc((sz)))
-#define DEL(ptr) (kern_free((ptr)))
-
-char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v,
-                              net_vec_t path )
-{
-        char *info_tmp;
-        int info_len;
-        char *info;
-
-        /* see if this vertex is already marked */
-        info_tmp = nic_vertex_info_get(v);
-        if (info_tmp) return info_tmp;
-
-        /* get a temporary place for the data */
-        NEWSZ(info_tmp, MAX_INFO);
-        if (!info_tmp) return NULL;
-
-        /* read the EEPROM */
-	if( component & R_BRICK ) {
-	    if( RBRICK_EEPROM_STR( info_tmp, nasid, path ) != EEP_OK )
-		return NULL;
-	}
-	else {
-            if( eeprom_str( info_tmp, nasid, component ) != EEP_OK )
-	        return NULL;
-	}
-
-        /* allocate a smaller final place */
-        info_len = strlen(info_tmp)+1;
-        NEWSZ(info, info_len);
-        if (info) {
-                strcpy(info, info_tmp);
-                DEL(info_tmp);
-        } else {
-                info = info_tmp;
-        }
-
-        /* add info to the vertex */
-        hwgraph_info_add_LBL(v, INFO_LBL_NIC,
-                             (arbitrary_info_t) info);
-
-        /* see if someone else got there first */
-        info_tmp = nic_vertex_info_get(v);
-        if (info != info_tmp) {
-            DEL(info);
-            return info_tmp;
-        }
-
-        /* export the data */
-        hwgraph_info_export_LBL(v, INFO_LBL_NIC, info_len);
-
-        /* trigger all matching callbacks */
-        nic_vmc_check(v, info);
-
-        return info;
-}
-
-
-/*********************************************************************
- *
- * stubs for use until the Bedrock/L1 link is available
- *
- */
-
-#include <asm/sn/nic.h>
-
-/* #define EEPROM_TEST */
-
-/* fake eeprom reading functions (replace when the BR/L1 communication
- * channel is in working order)
- */
-
-
-/* generate a charater in [0-9A-Z]; if an "extra" character is
- * specified (such as '_'), include it as one of the possibilities.
- */
-char random_eeprom_ch( char extra ) 
-{
-    char ch;
-    int modval = 36;
-    if( extra )
-	modval++;
-    
-    ch = rtc_time() % modval;
-
-    if( ch < 10 )
-        ch += '0';
-    else if( ch >= 10 && ch < 36 )
-	ch += ('A' - 10);
-    else
-	ch = extra;
-
-    return ch;
-}
-
-/* create a part number of the form xxx-xxxx-xxx.
- * It may be important later to generate different
- * part numbers depending on the component we're
- * supposed to be "reading" from, so the component
- * paramter is provided.
- */
-void fake_a_part_number( char *buf, int component )
-{
-    int i;
-    switch( component ) {
-
-    /* insert component-specific routines here */
-
-    case C_BRICK:
-	strcpy( buf, "030-1266-001" );
-	break;
-    default:
-        for( i = 0; i < 12; i++ ) {
-	    if( i == 3 || i == 8 )
-	        buf[i] = '-';
-	    else
-	        buf[i] = random_eeprom_ch(0);
-        }
-    }
-}
-
-
-/* create a six-character serial number */
-void fake_a_serial_number( char *buf, uint64_t ser )
-{
-    int i;
-    static const char hexchars[] = "0123456789ABCDEF";
-
-    if (ser) {
-	for( i = 5; i >=0; i-- ) {
-	    buf[i] = hexchars[ser & 0xf];
-	    ser >>= 4;
-	}
-    }
-    else {
-	for( i = 0; i < 6; i++ )
-	    buf[i] = random_eeprom_ch(0);
-    }
-}
-
-
-void fake_a_product_name( uchar_t *format, char* buf, int component )
-{
-    switch( component & BRICK_MASK ) {
-
-    case C_BRICK:
-	if( component & SUBORD_MASK ) {
-	    strcpy( buf, "C_BRICK_SUB" );
-	    *format = 0xCB;
-	}
-	else {
-	    strcpy( buf, "IP35" );
-	    *format = 0xC4;
-	}
-	break;
-
-    case R_BRICK:
-        if( component & SUBORD_MASK ) {
-            strcpy( buf, "R_BRICK_SUB" );
-            *format = 0xCB;
-        }
-        else {
-            strcpy( buf, "R_BRICK" );
-            *format = 0xC7;
-        }
-        break;
-
-    case IO_BRICK:
-        if( component & SUBORD_MASK ) {
-            strcpy( buf, "IO_BRICK_SUB" );
-            *format = 0xCC;
-        }
-        else {
-            strcpy( buf, "IO_BRICK" );
-            *format = 0xC8;
-        }
-        break;
-
-    default:
-	strcpy( buf, "UNK_DEVICE" );
-	*format = 0xCA;
-    }
-}
-
-
-
-int fake_an_eeprom_record( eeprom_brd_record_t *buf, int component, 
-			   uint64_t ser )
-{
-    eeprom_board_ia_t *board;
-    eeprom_chassis_ia_t *chassis;
-    int i, cs;
-
-    board = buf->board_ia;
-    chassis = buf->chassis_ia;
-
-    if( !(component & SUBORD_MASK) ) {
-	if( !chassis )
-	    return EEP_PARAM;
-	chassis->format = 0;
-	chassis->length = 5;
-	chassis->type = 0x17;
-
-	chassis->part_num_tl = 0xCC;
-	fake_a_part_number( chassis->part_num, component );
-	chassis->serial_num_tl = 0xC6;
-	fake_a_serial_number( chassis->serial_num, ser );
-
-	cs = chassis->format + chassis->length + chassis->type
-	    + chassis->part_num_tl + chassis->serial_num_tl;
-	for( i = 0; i < (chassis->part_num_tl & FIELD_LENGTH_MASK); i++ )
-	    cs += chassis->part_num[i];
-	for( i = 0; i < (chassis->serial_num_tl & FIELD_LENGTH_MASK); i++ )
-	    cs += chassis->serial_num[i];
-	chassis->checksum = 256 - (cs % 256);
-    }
-
-    if( !board )
-	return EEP_PARAM;
-    board->format = 0;
-    board->length = 10;
-    board->language = 0;
-    board->mfg_date = 1789200; /* noon, 5/26/99 */
-    board->manuf_tl = 0xC3;
-    strcpy( board->manuf, "SGI" );
-
-    fake_a_product_name( &(board->product_tl), board->product, component );
-
-    board->serial_num_tl = 0xC6;
-    fake_a_serial_number( board->serial_num, ser );
-
-    board->part_num_tl = 0xCC;
-    fake_a_part_number( board->part_num, component );
-
-    board->board_rev_tl = 0xC2;
-    board->board_rev[0] = '0';
-    board->board_rev[1] = '1';
-
-    board->eeprom_size_tl = 0x01;
-    board->eeprom_size = 1;
-
-    board->temp_waiver_tl = 0xC2;
-    board->temp_waiver[0] = '0';
-    board->temp_waiver[1] = '1';
-
-    cs = board->format + board->length + board->language
-	+ (board->mfg_date & 0xFF)
-	+ (board->mfg_date & 0xFF00)
-	+ (board->mfg_date & 0xFF0000)
-	+ board->manuf_tl + board->product_tl + board->serial_num_tl
-	+ board->part_num_tl + board->board_rev_tl
-	+ board->board_rev[0] + board->board_rev[1]
-	+ board->eeprom_size_tl + board->eeprom_size + board->temp_waiver_tl
-	+ board->temp_waiver[0] + board->temp_waiver[1];
-    for( i = 0; i < (board->manuf_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->manuf[i];
-    for( i = 0; i < (board->product_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->product[i];
-    for( i = 0; i < (board->serial_num_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->serial_num[i];
-    for( i = 0; i < (board->part_num_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->part_num[i];
-    
-    board->checksum = 256 - (cs % 256);
-
-    return EEP_OK;
-}
-
-#define EEPROM_CHUNKSIZE	64
-
-#if defined(EEPROM_DEBUG)
-#define RETURN_ERROR							\
-{									\
-    printk( "read_ia error return, component 0x%x, line %d"		\
-	    ", address 0x%x, ia code 0x%x\n",				\
-	    l1_compt, __LINE__, sc->subch[subch].target, ia_code );	\
-    return EEP_L1;							\
-}
-
-#else
-#define RETURN_ERROR	return(EEP_L1)
-#endif
-
-int read_ia( l1sc_t *sc, int subch, int l1_compt, 
-	     int ia_code, char *eep_record )
-{
-    char msg[BRL1_QSIZE]; 	   /* message buffer */
-    int len;              	   /* number of bytes used in message buffer */
-    int ia_len = EEPROM_CHUNKSIZE; /* remaining bytes in info area */
-    int offset = 0;                /* current offset into info area */
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    BZERO( msg, BRL1_QSIZE );
-
-    /* retrieve EEPROM data in 64-byte chunks
-     */
-
-    while( ia_len )
-    {
-	/* fill in msg with opcode & params */
-	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				     L1_ADDR_TASK_GENERAL,
-				     L1_REQ_EEPROM, 8,
-				     L1_ARG_INT, l1_compt,
-				     L1_ARG_INT, ia_code,
-				     L1_ARG_INT, offset,
-				     L1_ARG_INT, ia_len )) < 0 )
-	{
-	    RETURN_ERROR;
-	}
-
-	/* send the request to the L1 */
-
-	if( sc_command( sc, subch, msg, msg, &len ) ) {
-	    RETURN_ERROR;
-	}
-
-	/* check response */
-	if( sc_interpret_resp( msg, 5, 
-			       L1_ARG_INT, &ia_len,
-			       L1_ARG_UNKNOWN, &len, eep_record ) < 0 )
-	{
-	    RETURN_ERROR;
-	}
-
-	if( ia_len > EEPROM_CHUNKSIZE )
-	    ia_len = EEPROM_CHUNKSIZE;
-
-	eep_record += EEPROM_CHUNKSIZE;
-	offset += EEPROM_CHUNKSIZE;
-    }
-
-    return EEP_OK;
-}
-
-
-int read_spd( l1sc_t *sc, int subch, int l1_compt,
-	      eeprom_spd_u *spd )
-{
-    char msg[BRL1_QSIZE]; 	    /* message buffer */
-    int len;              	    /* number of bytes used in message buffer */
-    int resp;                       /* l1 response code */
-    int spd_len = EEPROM_CHUNKSIZE; /* remaining bytes in spd record */
-    int offset = 0;		    /* current offset into spd record */
-    char *spd_p = spd->bytes;	    /* "thumb" for writing to spd */
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    BZERO( msg, BRL1_QSIZE );
-
-    /* retrieve EEPROM data in 64-byte chunks
-     */
-
-    while( spd_len )
-    {
-	/* fill in msg with opcode & params */
-	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				     L1_ADDR_TASK_GENERAL,
-				     L1_REQ_EEPROM, 8,
-				     L1_ARG_INT, l1_compt,
-				     L1_ARG_INT, L1_EEP_SPD,
-				     L1_ARG_INT, offset,
-				     L1_ARG_INT, spd_len )) < 0 )
-	{
-	    return( EEP_L1 );
-	}
-
-	/* send the request to the L1 */
-	if( sc_command( sc, subch, msg, msg, &len ) ) {
-	    return( EEP_L1 );
-	}
-
-	/* check response */
-	if( (resp = sc_interpret_resp( msg, 5, 
-			       L1_ARG_INT, &spd_len,
-			       L1_ARG_UNKNOWN, &len, spd_p )) < 0 )
-	{
-            /*
-             * translate l1 response code to eeprom.c error codes:
-             * The L1 response will be L1_RESP_NAVAIL if the spd
-             * can't be read (i.e. the spd isn't physically there). It will
-             * return L1_RESP_INVAL if the spd exists, but fails the checksum
-             * test because the eeprom wasn't programmed, programmed incorrectly,
-             * or corrupted. L1_RESP_NAVAIL indicates the eeprom is likely not present,
-             * whereas L1_RESP_INVAL indicates the eeprom is present, but the data is
-             * invalid.
-             */
-            if(resp == L1_RESP_INVAL) {
-                resp = EEP_BAD_CHECKSUM;
-            } else {
-                resp = EEP_L1;
-            }
-            return( resp );
-	}
-
-	if( spd_len > EEPROM_CHUNKSIZE )
-	    spd_len = EEPROM_CHUNKSIZE;
-
-	spd_p += EEPROM_CHUNKSIZE;
-	offset += EEPROM_CHUNKSIZE;
-    }
-    return EEP_OK;
-}
-
-
-int read_chassis_ia( l1sc_t *sc, int subch, int l1_compt,
-		     eeprom_chassis_ia_t *ia )
-{
-    char eep_record[512];          /* scratch area for building up info area */
-    char *eep_rec_p = eep_record;  /* thumb for moving through eep_record */
-    int checksum = 0;              /* use to verify eeprom record checksum */
-    int i;
-
-    /* Read in info area record from the L1.
-     */
-    if( read_ia( sc, subch, l1_compt, L1_EEP_CHASSIS, eep_record )
-	!= EEP_OK )
-    {
-	return EEP_L1;
-    }
-
-    /* Now we've got the whole info area.  Transfer it to the data structure.
-     */
-
-    eep_rec_p = eep_record;
-    ia->format = *eep_rec_p++;
-    ia->length = *eep_rec_p++;
-    if( ia->length == 0 ) {
-	/* since we're using 8*ia->length-1 as an array index later, make
-	 * sure it's sane.
-	 */
-	db_printf(( "read_chassis_ia: eeprom length byte of ZERO\n" ));
-	return EEP_L1;
-    }
-    ia->type = *eep_rec_p++;
-   
-    ia->part_num_tl = *eep_rec_p++;
-
-    (void)BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK);
-
-    ia->serial_num_tl = *eep_rec_p++;
-
-    BCOPY( eep_rec_p, ia->serial_num, 
-	   (ia->serial_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK);
-
-    ia->checksum = eep_record[(8 * ia->length) - 1];
-
-    /* verify checksum */
-    eep_rec_p = eep_record;
-    checksum = 0;
-    for( i = 0; i < (8 * ia->length); i++ ) {
-	checksum += *eep_rec_p++;
-    }
-
-    if( (checksum & 0xff) != 0 )
-    {
-	db_printf(( "read_chassis_ia: bad checksum\n" ));
-	db_printf(( "read_chassis_ia: target 0x%x  uart 0x%lx\n",
-			   sc->subch[subch].target, sc->uart ));
-	return EEP_BAD_CHECKSUM;
-    }
-
-    return EEP_OK;
-}
-
-
-int read_board_ia( l1sc_t *sc, int subch, int l1_compt,
-		   eeprom_board_ia_t *ia )
-{
-    char eep_record[512];          /* scratch area for building up info area */
-    char *eep_rec_p = eep_record;  /* thumb for moving through eep_record */
-    int checksum = 0;              /* running checksum total */
-    int i;
-
-    BZERO( ia, sizeof( eeprom_board_ia_t ) );
-
-    /* Read in info area record from the L1.
-     */
-    if( read_ia( sc, subch, l1_compt, L1_EEP_BOARD, eep_record )
-	!= EEP_OK )
-    {
-	db_printf(( "read_board_ia: error reading info area from L1\n" ));
-	return EEP_L1;
-    }
-
-     /* Now we've got the whole info area.  Transfer it to the data structure.
-      */
-
-    eep_rec_p = eep_record;
-    ia->format = *eep_rec_p++;
-    ia->length = *eep_rec_p++;
-    if( ia->length == 0 ) {
-	/* since we're using 8*ia->length-1 as an array index later, make
-	 * sure it's sane.
-	 */
-	db_printf(( "read_board_ia: eeprom length byte of ZERO\n" ));
-	return EEP_L1;
-    }
-    ia->language = *eep_rec_p++;
-    
-    ia->mfg_date = eeprom_xlate_board_mfr_date( (uchar_t *)eep_rec_p );
-    eep_rec_p += 3;
-
-    ia->manuf_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->manuf, (ia->manuf_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->manuf_tl & FIELD_LENGTH_MASK);
-
-    ia->product_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->product, (ia->product_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->product_tl & FIELD_LENGTH_MASK);
-
-    ia->serial_num_tl = *eep_rec_p++;
-    
-    BCOPY(eep_rec_p, ia->serial_num, (ia->serial_num_tl & FIELD_LENGTH_MASK));
-    eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK);
-
-    ia->part_num_tl = *eep_rec_p++;
-
-    BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK);
-
-    eep_rec_p++; /* we do not use the FRU file id */
-    
-    ia->board_rev_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->board_rev, (ia->board_rev_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->board_rev_tl & FIELD_LENGTH_MASK);
-
-    ia->eeprom_size_tl = *eep_rec_p++;
-    ia->eeprom_size = *eep_rec_p++;
-
-    ia->temp_waiver_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->temp_waiver, 
-	   (ia->temp_waiver_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->temp_waiver_tl & FIELD_LENGTH_MASK);
-
-    /* if there's more, we must be reading a main board; get
-     * additional fields
-     */
-    if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) {
-
-	ia->ekey_G_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_G, 
-	       ia->ekey_G_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_G_tl & FIELD_LENGTH_MASK);
-	
-	ia->ekey_P_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_P, 
-	       ia->ekey_P_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_P_tl & FIELD_LENGTH_MASK);
-	
-	ia->ekey_Y_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_Y, 
-	       ia->ekey_Y_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_Y_tl & FIELD_LENGTH_MASK);
-	
-	/* 
-	 * need to get a couple more fields if this is an I brick 
-	 */
-	if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) {
-
-	    ia->mac_addr_tl = *eep_rec_p++;
-	    BCOPY( eep_rec_p, ia->mac_addr, 
-		   ia->mac_addr_tl & FIELD_LENGTH_MASK );
-	    eep_rec_p += (ia->mac_addr_tl & FIELD_LENGTH_MASK);
-	    
-	    ia->ieee1394_cfg_tl = *eep_rec_p++;
-	    BCOPY( eep_rec_p, ia->ieee1394_cfg,
-		   ia->ieee1394_cfg_tl & FIELD_LENGTH_MASK );
-	    
-	}
-    }
-
-    ia->checksum = eep_record[(ia->length * 8) - 1];
-
-    /* verify checksum */
-    eep_rec_p = eep_record;
-    checksum = 0;
-    for( i = 0; i < (8 * ia->length); i++ ) {
-	checksum += *eep_rec_p++;
-    }
-
-    if( (checksum & 0xff) != 0 )
-    {
-	db_printf(( "read_board_ia: bad checksum\n" ));
-	db_printf(( "read_board_ia: target 0x%x  uart 0x%lx\n",
-		    sc->subch[subch].target, sc->uart ));
-	return EEP_BAD_CHECKSUM;
-    }
-
-    return EEP_OK;
-}
-
-
-int _cbrick_eeprom_read( eeprom_brd_record_t *buf, l1sc_t *scp,
-			 int component )
-{
-    int r;
-    uint64_t uid = 0;
-#ifdef LOG_GETENV
-    char uid_str[32];
-#endif
-    int l1_compt, subch;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're targeting a cbrick */
-    if( !(component & C_BRICK) )
-	return EEP_PARAM;
-
-    /* If the promlog variable pointed to by IP27LOG_OVNIC is set,
-     * use that value for the cbrick UID rather than the EEPROM
-     * serial number.
-     */
-#ifdef LOG_GETENV
-    if( ip27log_getenv( scp->nasid, IP27LOG_OVNIC, uid_str, "0", 0 ) >= 0 )
-    {
-	db_printf(( "_cbrick_eeprom_read: "
-		    "Overriding UID with environment variable %s\n", 
-		    IP27LOG_OVNIC ));
-	uid = strtoull( uid_str, NULL, 0 );
-    }
-#endif
-
-    if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 )
-	return EEP_L1;
-
-    if((component & C_DIMM) == C_DIMM) {
-        l1_compt = L1_EEP_DIMM(component & COMPT_MASK);
-        r = read_spd(scp,subch,l1_compt, buf->spd);
-        sc_close(scp,subch);
-        return(r);
-    }
-
-    switch( component )
-    {
-      case C_BRICK:
-	/* c-brick motherboard */
-	l1_compt = L1_EEP_NODE;
-	r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia );
-	if( r != EEP_OK ) {
-	    sc_close( scp, subch );
-	    db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" ));
-	    return fake_an_eeprom_record( buf, component, uid );
-	}
-	if( uid ) {
-	    /* If IP27LOG_OVNIC is set, we want to put that value
-	     * in as our UID. */
-	    fake_a_serial_number( buf->chassis_ia->serial_num, uid );
-	    buf->chassis_ia->serial_num_tl = 6;
-	}
-	break;
-
-      case C_PIMM:
-	/* one of the PIMM boards */
-	l1_compt = L1_EEP_PIMM( component & COMPT_MASK );
-	break;
-
-      default:
-	/* unsupported board type */
-	sc_close( scp, subch );
-	return EEP_PARAM;
-    }
-	      
-    r = read_board_ia( scp, subch, l1_compt, buf->board_ia );
-    sc_close( scp, subch );
-    if( r != EEP_OK ) 
-    {
-	db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" ));
-	return fake_an_eeprom_record( buf, component, uid );
-    }
-    return EEP_OK;
-}
-
-
-int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-    		        int component )
-{
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* If this brick is retrieving its own uid, use the local l1sc_t to
-     * arbitrate access to the l1; otherwise, set up a new one (prom) or
-     * use an existing remote l1sc_t (kernel)
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    }
-
-    return _cbrick_eeprom_read( buf, scp, component );
-}
-
-
-int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			 int component )
-{
-    int r;
-    int l1_compt, subch;
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're talking to an applicable brick */
-    if( !(component & IO_BRICK) ) {
-	return EEP_PARAM;
-    }
-
-    /* If we're talking to this c-brick's attached io brick, use
-     * the local l1sc_t; otherwise, set up a new one (prom) or
-     * use an existing remote l1sc_t (kernel)
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    }
-
-    if( (subch = sc_open( scp, L1_ADDR_LOCALIO )) < 0 )
-	return EEP_L1;
-
-
-    switch( component )
-    {
-      case IO_BRICK:
-	/* IO brick motherboard */
-	l1_compt = L1_EEP_LOGIC;
-	r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia );
-
-	if( r != EEP_OK ) {
-	    sc_close( scp, subch );
-	/*
-	 * Whenever we no longer need to test on hardware
-	 * that does not have EEPROMS, then this can be removed.
-	 */
-	    r = fake_an_eeprom_record( buf, component, rtc_time() );
-	    return r;
-	}
-	break;
-
-      case IO_POWER:
-	/* IO brick power board */
-	l1_compt = L1_EEP_POWER;
-	break;
-
-      default:
-	/* unsupported board type */
-	sc_close( scp, subch );
-	return EEP_PARAM;
-    }
-
-    r = read_board_ia( scp, subch, l1_compt, buf->board_ia );
-    sc_close( scp, subch );
-    if( r != EEP_OK ) {
-	return r;
-    }
-    return EEP_OK;
-}
-
-
-int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			net_vec_t path, int component )
-{
-    int r;
-    uint64_t uid = 0;
-    int l1_compt, subch;
-    l1sc_t sc;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're targeting an applicable brick */
-    if( !(component & VECTOR) )
-	return EEP_PARAM;
-
-    switch( component & BRICK_MASK )
-    {
-      case R_BRICK:
-	ROUTER_LOCK( path );
-	sc_init( &sc, nasid, path );
-
-	if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 )
-	{
-	    db_printf(( "vector_eeprom_read: couldn't open subch\n" ));
-	    ROUTER_UNLOCK(path);
-	    return EEP_L1;
-	}
-	switch( component )
-	{
-	  case R_BRICK:
-	    /* r-brick motherboard */
-	    l1_compt = L1_EEP_LOGIC;
-    	    r = read_chassis_ia( &sc, subch, l1_compt, buf->chassis_ia );
-	    if( r != EEP_OK ) {
-		sc_close( &sc, subch );
-		ROUTER_UNLOCK( path );
-		printk( "vector_eeprom_read: couldn't get rbrick eeprom info;"
-			" using current time as uid\n" );
-		uid = rtc_time();
-		db_printf(("vector_eeprom_read: using a fake eeprom record\n"));
-		return fake_an_eeprom_record( buf, component, uid );
-	    }
-	    break;
-
-	  case R_POWER:
-	    /* r-brick power board */
-	    l1_compt = L1_EEP_POWER;
-	    break;
-
-	  default:
-	    /* unsupported board type */
-	    sc_close( &sc, subch );
-	    ROUTER_UNLOCK( path );
-	    return EEP_PARAM;
-	}
-	r = read_board_ia( &sc, subch, l1_compt, buf->board_ia );
-	sc_close( &sc, subch );
-	ROUTER_UNLOCK( path );
-	if( r != EEP_OK ) {
-	    db_printf(( "vector_eeprom_read: using a fake eeprom record\n" ));
-	    return fake_an_eeprom_record( buf, component, uid );
-	}
-	return EEP_OK;
-
-      case C_BRICK:
-	sc_init( &sc, nasid, path );
-	return _cbrick_eeprom_read( buf, &sc, component );
-
-      default:
-	/* unsupported brick type */
-	return EEP_PARAM;
-    }
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/efi-rtc.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/efi-rtc.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/efi-rtc.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/efi-rtc.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,202 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
- * Copyright (C) 2001 by Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/efi.h>
-#include <asm/sn/klclock.h>
-
-/*
- * No locking necessary when this is called from efirtc which protects us
- * from racing by efi_rtc_lock.
- */
-#define __swizzle(addr) ((u8 *)((unsigned long)(addr) ^ 3))
-#define read_io_port(addr) (*(volatile u8 *) __swizzle(addr))
-#define write_io_port(addr, data) (*(volatile u8 *) __swizzle(addr) = (data))
-
-#define TOD_SGS_M48T35		1
-#define TOD_DALLAS_DS1386	2
-
-#define TYPE_IOC3		1
-#define TYPE_IOC4		2
-
-static unsigned long nvram_base = 0;
-static int tod_chip_type;
-static int ioc_type;
-
-static int
-get_tod_chip_type(void)
-{
-	unsigned char testval;
-
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-	write_io_port(RTC_DAL_DAY_ADDR, 0xff);
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-
-	testval = read_io_port(RTC_DAL_DAY_ADDR);
-	if (testval == 0xff)
-		return TOD_SGS_M48T35;
-
-	return TOD_DALLAS_DS1386;
-}
-
-efi_status_t
-ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	memset(time, 0, sizeof(*time));
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT);
-
-		time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF;
-		time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR));
-		time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR));
-		time->nanosecond = 0;
-
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-
-		time->nanosecond = 0;
-		time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR));
-		time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR));
-		time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF;
-
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	if (caps) {
-		caps->resolution = 50000000;	/*  50PPM */
-		caps->accuracy = 1000;		/*  1ms */
-		caps->sets_to_zero = 0;
-	}
-
-	return EFI_SUCCESS;
-}
-
-static efi_status_t ioc3_set_time (efi_time_t *t)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_WRITE_ENABLE);
-        	write_io_port(RTC_SGS_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_SGS_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_SGS_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_SGS_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_SGS_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_SGS_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-		write_io_port(RTC_DAL_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_DAL_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_DAL_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_DAL_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_DAL_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_DAL_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	return EFI_SUCCESS;
-}
-
-/* The following two are not supported atm.  */
-static efi_status_t
-ioc3_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static efi_status_t
-ioc3_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static __init int efi_ioc_time_init(void)
-{
-	struct pci_dev *dev = NULL;
-	static void *ioc_base;
-
-        while ( (dev = pci_find_subsys(PCI_VENDOR_ID_SGI,
-                               PCI_ANY_ID,
-                               PCI_ANY_ID,
-                               PCI_ANY_ID, dev))) {
-		if ( dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-			ioc_type = TYPE_IOC3;
-			break;
-		}
-		else if ( dev->device == PCI_DEVICE_ID_SGI_IOC4 ) {
-			ioc_type = TYPE_IOC4;
-			break;
-		}
-		else
-			;; // keep looking
-	}
-
-	if ( !dev ) {
-		printk(KERN_CRIT "Couldn't find master IOC\n");
-		return -ENODEV;
-	}
-
-	ioc_base = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0));
-	if ( ioc_type == TYPE_IOC3 )
-		nvram_base = (unsigned long) ioc_base + IOC3_BYTEBUS_DEV0;
-	if ( ioc_type == TYPE_IOC4 )
-		nvram_base = (unsigned long) ioc_base + IOC4_BYTEBUS_DEV0;
-
-	tod_chip_type = get_tod_chip_type();
-	if (tod_chip_type == 1)
-		printk(KERN_NOTICE "TOD type is SGS M48T35\n");
-	else if (tod_chip_type == 2)
-		printk(KERN_NOTICE "TOD type is Dallas DS1386\n");
-	else
-		printk(KERN_CRIT "No or unknown TOD\n");
-
-	efi.get_time = ioc3_get_time;
-	efi.set_time = ioc3_set_time;
-	efi.get_wakeup_time = ioc3_get_wakeup_time;
-	efi.set_wakeup_time = ioc3_set_wakeup_time;
-
-	return 0;
-}
-
-module_init(efi_ioc_time_init);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/hub_intr.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/hub_intr.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/hub_intr.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/hub_intr.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,307 +0,0 @@
-/* $Id: hub_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/types.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-
-extern xtalk_provider_t hub_provider;
-
-/* ARGSUSED */
-void
-hub_intr_init(devfs_handle_t hubv)
-{
-}
-
-/*
- * hub_device_desc_update
- *	Update the passed in device descriptor with the actual the
- * 	target cpu number and interrupt priority level.
- *	NOTE : These might be the same as the ones passed in thru
- *	the descriptor.
- */
-static void
-hub_device_desc_update(device_desc_t 	dev_desc, 
-		       ilvl_t 		intr_swlevel,
-		       cpuid_t		cpu)
-{
-}
-
-int allocate_my_bit = INTRCONNECT_ANYBIT;
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-static hub_intr_t
-do_hub_intr_alloc(devfs_handle_t dev,		/* which crosstalk device */
-		  device_desc_t dev_desc,	/* device descriptor */
-		  devfs_handle_t owner_dev,	/* owner of this interrupt, if known */
-		  int uncond_nothread)		/* unconditionally non-threaded */
-{
-	cpuid_t cpu = (cpuid_t)0;			/* cpu to receive interrupt */
-        int cpupicked = 0;
-	int bit;			/* interrupt vector */
-	/*REFERENCED*/
-	int intr_resflags = 0;
-	hub_intr_t intr_hdl;
-	cnodeid_t nodeid;		/* node to receive interrupt */
-	/*REFERENCED*/
-	nasid_t nasid;			/* nasid to receive interrupt */
-	struct xtalk_intr_s *xtalk_info;
-	iopaddr_t xtalk_addr;		/* xtalk addr on hub to set intr */
-	xwidget_info_t xwidget_info;	/* standard crosstalk widget info handle */
-	char *intr_name = NULL;
-	ilvl_t intr_swlevel = (ilvl_t)0;
-	extern int default_intr_pri;
-	extern void synergy_intr_alloc(int, int);
-
-
-	if (dev_desc) {
-		if (dev_desc->flags & D_INTR_ISERR) {
-			intr_resflags = II_ERRORINT;
-		} else if (!uncond_nothread && !(dev_desc->flags & D_INTR_NOTHREAD)) {
-			intr_resflags = II_THREADED;
-		} else {
-			/* Neither an error nor a thread. */
-			intr_resflags = 0;
-		}
-	} else {
-		intr_swlevel = default_intr_pri;
-		if (!uncond_nothread)
-			intr_resflags = II_THREADED;
-	}
-
-	/* XXX - Need to determine if the interrupt should be threaded. */
-
-	/* If the cpu has not been picked already then choose a candidate 
-	 * interrupt target and reserve the interrupt bit 
-	 */
-	if (!cpupicked) {
-		cpu = intr_heuristic(dev,dev_desc,allocate_my_bit,
-				     intr_resflags,owner_dev,
-				     intr_name,&bit);
-	}
-
-	/* At this point we SHOULD have a valid cpu */
-	if (cpu == CPU_NONE) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "%v hub_intr_alloc could not allocate interrupt\n",
-			owner_dev);
-#else
-		printk(KERN_WARNING  "%p hub_intr_alloc could not allocate interrupt\n",
-			(void *)owner_dev);
-#endif
-		return(0);
-
-	}
-
-	/* If the cpu has been picked already (due to the bridge data 
-	 * corruption bug) then try to reserve an interrupt bit .
-	 */
-	if (cpupicked) {
-		bit = intr_reserve_level(cpu, allocate_my_bit, 
-					 intr_resflags, 
-					 owner_dev, intr_name);
-		if (bit < 0) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-			printk(KERN_WARNING  "Could not reserve an interrupt bit for cpu "
-				" %d and dev %v\n",
-				cpu,owner_dev);
-#else
-			printk(KERN_WARNING  "Could not reserve an interrupt bit for cpu "
-				" %d and dev %p\n",
-				(int)cpu, (void *)owner_dev);
-#endif
-				
-			return(0);
-		}
-	}
-
-	nodeid = cpuid_to_cnodeid(cpu);
-	nasid = cpuid_to_nasid(cpu);
-	xtalk_addr = HUBREG_AS_XTALKADDR(nasid, PIREG(PI_INT_PEND_MOD, cpuid_to_subnode(cpu)));
-
-	/*
-	 * Allocate an interrupt handle, and fill it in.  There are two
-	 * pieces to an interrupt handle: the piece needed by generic
-	 * xtalk code which is used by crosstalk device drivers, and
-	 * the piece needed by low-level IP27 hardware code.
-	 */
-	intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, nodeid);
-	ASSERT_ALWAYS(intr_hdl);
-
-	/* 
-	 * Fill in xtalk information for generic xtalk interfaces that
-	 * operate on xtalk_intr_hdl's.
-	 */
-	xtalk_info = &intr_hdl->i_xtalk_info;
-	xtalk_info->xi_dev = dev;
-	xtalk_info->xi_vector = bit;
-	xtalk_info->xi_addr = xtalk_addr;
-
-	/*
-	 * Regardless of which CPU we ultimately interrupt, a given crosstalk
-	 * widget always handles interrupts (and PIO and DMA) through its 
-	 * designated "master" crosstalk provider.
-	 */
-	xwidget_info = xwidget_info_get(dev);
-	if (xwidget_info)
-		xtalk_info->xi_target = xwidget_info_masterid_get(xwidget_info);
-
-	/* Fill in low level hub information for hub_* interrupt interface */
-	intr_hdl->i_swlevel = intr_swlevel;
-	intr_hdl->i_cpuid = cpu;
-	intr_hdl->i_bit = bit;
-	intr_hdl->i_flags = HUB_INTR_IS_ALLOCED;
-
-	/* Store the actual interrupt priority level & interrupt target
-	 * cpu back in the device descriptor.
-	 */
-	hub_device_desc_update(dev_desc, intr_swlevel, cpu);
-	synergy_intr_alloc((int)bit, (int)cpu);
-	return(intr_hdl);
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-hub_intr_t
-hub_intr_alloc(	devfs_handle_t dev,		/* which crosstalk device */
-		device_desc_t dev_desc,		/* device descriptor */
-		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */
-{
-	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0));
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Uncondtionally request non-threaded, regardless of what the device
- * descriptor might say.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-hub_intr_t
-hub_intr_alloc_nothd(devfs_handle_t dev,		/* which crosstalk device */
-		device_desc_t dev_desc,		/* device descriptor */
-		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */
-{
-	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1));
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-hub_intr_free(hub_intr_t intr_hdl)
-{
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-	xtalk_intr_t xtalk_info;
-
-	if (intr_hdl->i_flags & HUB_INTR_IS_CONNECTED) {
-		/* Setting the following fields in the xtalk interrupt info
-	 	 * clears the interrupt target register in the xtalk user
-	 	 */
-		xtalk_info = &intr_hdl->i_xtalk_info;
-		xtalk_info->xi_dev = NODEV;
-		xtalk_info->xi_vector = 0;
-		xtalk_info->xi_addr = 0;
-		hub_intr_disconnect(intr_hdl);
-	}
-
-	if (intr_hdl->i_flags & HUB_INTR_IS_ALLOCED)
-		kfree(intr_hdl);
-
-	intr_unreserve_level(cpu, bit);
-}
-
-
-/*
- * Associate resources allocated with a previous hub_intr_alloc call with the
- * described handler, arg, name, etc.
- */
-/*ARGSUSED*/
-int
-hub_intr_connect(	hub_intr_t intr_hdl,		/* xtalk intr resource handle */
-			xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */
-			void *setfunc_arg)		/* arg to setfunc */
-{
-	int rv;
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-	extern int synergy_intr_connect(int, int);
-
-	ASSERT(intr_hdl->i_flags & HUB_INTR_IS_ALLOCED);
-
-	rv = intr_connect_level(cpu, bit, intr_hdl->i_swlevel, NULL);
-	if (rv < 0)
-		return(rv);
-
-	intr_hdl->i_xtalk_info.xi_setfunc = setfunc;
-	intr_hdl->i_xtalk_info.xi_sfarg = setfunc_arg;
-
-	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);
-
-	intr_hdl->i_flags |= HUB_INTR_IS_CONNECTED;
-	return(synergy_intr_connect((int)bit, (int)cpu));
-}
-
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-hub_intr_disconnect(hub_intr_t intr_hdl)
-{
-	/*REFERENCED*/
-	int rv;
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-	xtalk_intr_setfunc_t setfunc;
-
-	setfunc = intr_hdl->i_xtalk_info.xi_setfunc;
-
-	/* TBD: send disconnected interrupts somewhere harmless */
-	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);
-
-	rv = intr_disconnect_level(cpu, bit);
-	ASSERT(rv == 0);
-	intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED;
-}
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-hub_intr_cpu_get(hub_intr_t intr_hdl)
-{
-	cpuid_t cpuid = intr_hdl->i_cpuid;
-	ASSERT(cpuid != CPU_NONE);
-
-	return(cpuid_to_vertex(cpuid));
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/hubcounters.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/hubcounters.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/hubcounters.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/hubcounters.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,282 +0,0 @@
-/* $Id: hubcounters.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All Rights Reserved.
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <asm/types.h>
-#include <asm/sn/io.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/router.h>
-#include <asm/sn/snconfig.h>
-#include <asm/sn/slotnum.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sndrv.h>
-
-extern void hubni_error_handler(char *, int); /* huberror.c */
-
-static int hubstats_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-struct file_operations hub_mon_fops = {
-        ioctl:          hubstats_ioctl,
-};
-
-#define HUB_CAPTURE_TICKS	(2 * HZ)
-
-#define HUB_ERR_THRESH		500
-#define USEC_PER_SEC		1000000
-#define NSEC_PER_SEC		USEC_PER_SEC*1000
-
-volatile int hub_print_usecs = 600 * USEC_PER_SEC;
-
-/* Return success if the hub's crosstalk link is working */
-int
-hub_xtalk_link_up(nasid_t nasid)
-{
-	hubreg_t	llp_csr_reg;
-
-	/* Read the IO LLP control status register */
-	llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
-
-	/* Check if the xtalk link is working */
-	if (llp_csr_reg & IIO_LLP_CSR_IS_UP) 
-		return(1);
-
-	return(0);
-
-	
-}
-
-static char *error_flag_to_type(unsigned char error_flag)
-{
-    switch(error_flag) {
-    case 0x1: return ("NI retries");
-    case 0x2: return ("NI SN errors");
-    case 0x4: return ("NI CB errors");
-    case 0x8: return ("II CB errors");
-    case 0x10: return ("II SN errors");
-    default: return ("Errors");
-    }
-}
-
-int
-print_hub_error(hubstat_t *hsp, hubreg_t reg,
-		int64_t delta, unsigned char error_flag)
-{
-	int64_t rate;
-
-	reg *= hsp->hs_per_minute;	/* Convert to minutes */
-	rate = reg / delta;
-
-	if (rate > HUB_ERR_THRESH) {
-		
-		if(hsp->hs_maint & error_flag) 
-		{
-		printk( "Excessive %s (%ld/min) on %s",
-			error_flag_to_type(error_flag), rate, hsp->hs_name); 
-		}
-		else 
-		{
-		   hsp->hs_maint |= error_flag;
-		printk( "Excessive %s (%ld/min) on %s",
-			error_flag_to_type(error_flag), rate, hsp->hs_name); 
-		}
-		return 1;
-	} else {
-		return 0;
-	}
-}
-
-
-int
-check_hub_error_rates(hubstat_t *hsp)
-{
-	int64_t delta = hsp->hs_timestamp - hsp->hs_timebase;
-	int printed = 0;
-
-	printed += print_hub_error(hsp, hsp->hs_ni_retry_errors,
-				   delta, 0x1);
-
-#if 0
-	printed += print_hub_error(hsp, hsp->hs_ni_sn_errors,
-				   delta, 0x2);
-#endif
-
-	printed += print_hub_error(hsp, hsp->hs_ni_cb_errors,
-				   delta, 0x4);
-
-
-	/* If the hub's xtalk link is not working there is 
-	 * no need to print the "Excessive..." warning 
-	 * messages
-	 */
-	if (!hub_xtalk_link_up(hsp->hs_nasid))
-		return(printed);
-
-
-	printed += print_hub_error(hsp, hsp->hs_ii_cb_errors,
-				   delta, 0x8);
-
-	printed += print_hub_error(hsp, hsp->hs_ii_sn_errors,
-				   delta, 0x10);
-
-	return printed;
-}
-
-
-void
-capture_hub_stats(cnodeid_t cnodeid, struct nodepda_s *npda)
-{
-	nasid_t nasid;
-	hubstat_t *hsp = &(npda->hubstats);
-	hubreg_t port_error;
-	ii_illr_u_t illr;
-	int count;
-	int overflow = 0;
-
-	/*
-	 * If our link wasn't up at boot time, don't worry about error rates.
-	 */
-	if (!(hsp->hs_ni_port_status & NPS_LINKUP_MASK)) {
-		printk("capture_hub_stats: cnode=%d hs_ni_port_status=0x%016lx : link is not up\n",
-		cnodeid, hsp->hs_ni_port_status);
-		return;
-	}
-
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-
-	hsp->hs_timestamp = GET_RTC_COUNTER();
-
-	port_error = REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
-	count = ((port_error & NPE_RETRYCOUNT_MASK) >> NPE_RETRYCOUNT_SHFT);
-	hsp->hs_ni_retry_errors += count;
-	if (count == NPE_COUNT_MAX)
-		overflow = 1;
-	count = ((port_error & NPE_SNERRCOUNT_MASK) >> NPE_SNERRCOUNT_SHFT);
-	hsp->hs_ni_sn_errors += count;
-	if (count == NPE_COUNT_MAX)
-		overflow = 1;
-	count = ((port_error & NPE_CBERRCOUNT_MASK) >> NPE_CBERRCOUNT_SHFT);
-	hsp->hs_ni_cb_errors += count;
-	if (overflow || count == NPE_COUNT_MAX)
-		hsp->hs_ni_overflows++;
-
-	if (port_error & NPE_FATAL_ERRORS) {
-#ifdef ajm
-		hubni_error_handler("capture_hub_stats", 1);
-#else
-		printk("Error: hubni_error_handler in capture_hub_stats");
-#endif
-	}
-
-	illr.ii_illr_regval = REMOTE_HUB_L(nasid, IIO_LLP_LOG);
-	REMOTE_HUB_S(nasid, IIO_LLP_LOG, 0);
-
-	hsp->hs_ii_sn_errors += illr.ii_illr_fld_s.i_sn_cnt;
-	hsp->hs_ii_cb_errors += illr.ii_illr_fld_s.i_cb_cnt;
-	if ((illr.ii_illr_fld_s.i_sn_cnt == IIO_LLP_SN_MAX) ||
-	    (illr.ii_illr_fld_s.i_cb_cnt == IIO_LLP_CB_MAX))
-		hsp->hs_ii_overflows++;
-
-	if (hsp->hs_print) {
-		if (check_hub_error_rates(hsp)) {
-			hsp->hs_last_print = GET_RTC_COUNTER();
-			hsp->hs_print = 0;
-		}
-	} else {
-		if ((GET_RTC_COUNTER() -
-		    hsp->hs_last_print) > hub_print_usecs)
-			hsp->hs_print = 1;
-	}
-		
-	npda->hubticks = HUB_CAPTURE_TICKS;
-}
-
-
-void
-init_hub_stats(cnodeid_t cnodeid, struct nodepda_s *npda)
-{
-	hubstat_t *hsp = &(npda->hubstats);
-	nasid_t nasid = cnodeid_to_nasid(cnodeid);
-	bzero(&(npda->hubstats), sizeof(hubstat_t));
-
-	hsp->hs_version = HUBSTAT_VERSION;
-	hsp->hs_cnode = cnodeid;
-	hsp->hs_nasid = nasid;
-	hsp->hs_timebase = GET_RTC_COUNTER();
-	hsp->hs_ni_port_status = REMOTE_HUB_L(nasid, NI_PORT_STATUS);
-
-	/* Clear the II error counts. */
-	REMOTE_HUB_S(nasid, IIO_LLP_LOG, 0);
-
-	/* Clear the NI counts. */
-	REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
-
-	hsp->hs_per_minute = (long long)RTC_CYCLES_PER_SEC * 60LL;
-
-	npda->hubticks = HUB_CAPTURE_TICKS;
-
-	/* XX should use kmem_alloc_node */
-	hsp->hs_name = (char *)kmalloc(MAX_HUB_PATH, GFP_KERNEL);
-	ASSERT_ALWAYS(hsp->hs_name);
-
-	sprintf(hsp->hs_name, "/dev/hw/" EDGE_LBL_MODULE "/%03d/"
-	        EDGE_LBL_NODE "/" EDGE_LBL_HUB,
-		npda->module_id);
-
-	hsp->hs_last_print = 0;
-	hsp->hs_print = 1;
-
-	hub_print_usecs = hub_print_usecs;
-
-#if 0
-	printk("init_hub_stats: cnode=%d nasid=%d hs_version=%d hs_ni_port_status=0x%016lx\n",
-		cnodeid, nasid, hsp->hs_version, hsp->hs_ni_port_status);
-#endif
-}
-
-static int
-hubstats_ioctl(struct inode *inode, struct file *file,
-        unsigned int cmd, unsigned long arg)
-{
-        cnodeid_t       cnode;
-        nodepda_t       *npdap;
-        uint64_t        longarg;
-        devfs_handle_t  d;
-
-        if ((d = devfs_get_handle_from_inode(inode)) == NULL)
-                return -ENODEV;
-        cnode = (cnodeid_t)hwgraph_fastinfo_get(d);
-        npdap = NODEPDA(cnode);
-
-	if (npdap->hubstats.hs_version != HUBSTAT_VERSION) {
-		init_hub_stats(cnode, npdap);
-	}
-
-        switch (cmd) {
-	case SNDRV_GET_INFOSIZE:
-		longarg = sizeof(hubstat_t);
-		if (copy_to_user((void *)arg, &longarg, sizeof(longarg))) {
-		    return -EFAULT;
-		}
-		break;
-
-	case SNDRV_GET_HUBINFO:
-		/* refresh npda->hubstats */
-		capture_hub_stats(cnode, npdap);
-		if (copy_to_user((void *)arg, &npdap->hubstats, sizeof(hubstat_t))) {
-		    return -EFAULT;
-		}
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/huberror.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/huberror.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/huberror.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/huberror.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,228 +0,0 @@
-/* $Id: huberror.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/smp.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/intr.h>
-
-extern void hubni_eint_init(cnodeid_t cnode);
-extern void hubii_eint_init(cnodeid_t cnode);
-extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
-extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
-
-extern int maxcpus;
-
-#define HUB_ERROR_PERIOD        (120 * HZ)      /* 2 minutes */
-
-
-void
-hub_error_clear(nasid_t nasid)
-{
-	int i;
-	hubreg_t idsr;
-	int sn;
-
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_PEND, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_A_CLR, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_B_CLR, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_0, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_1, 0);
-	}
-
-	REMOTE_HUB_L(nasid, MD_DIR_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_MEM_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_MISC1_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_PROTOCOL_ERR_CLR);
-
-    /*
-     * Make sure spurious write response errors are cleared
-     * (values are from hub_set_prb())
-     */
-    for (i = 0; i <= HUB_WIDGET_ID_MAX - HUB_WIDGET_ID_MIN + 1; i++) {
-        iprb_t prb;
-
-	prb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)));
-
-        /* Clear out some fields */
-        prb.iprb_ovflow = 1;
-        prb.iprb_bnakctr = 0;
-        prb.iprb_anakctr = 0;
-
-	/*
-	 * PIO reads in fire-and-forget mode on bedrock 1.0 don't
-	 * frob the credit count properly, making the responses appear
-	 * spurious.  So don't use fire-and-forget mode.  Bug 761802.
-	 */
-        prb.iprb_ff = 0;        /* disable fire-and-forget mode by default */
-
-        prb.iprb_xtalkctr = 3;  /* approx. PIO credits for the widget */
-
-        REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval);
-    }
-
-    REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1);
-    idsr = REMOTE_HUB_L(nasid, IIO_IIDSR);
-    REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK)));
-
-    REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
-    /* No need to clear NI_PORT_HEADER regs; they are continually overwritten*/
-
-    REMOTE_HUB_S(nasid, LB_ERROR_MASK_CLR, -1);
-    REMOTE_HUB_S(nasid, LB_ERROR_HDR1, 0);
-
-    /* Clear XB error regs, in order */
-    for (i = 0;
-         i <= XB_FIRST_ERROR_CLEAR - XB_POQ0_ERROR_CLEAR;
-         i += sizeof(hubreg_t)) {
-        REMOTE_HUB_S(nasid, XB_POQ0_ERROR_CLEAR + i, 0);
-    }
-}
-
-
-/*
- * Function	: hub_error_init
- * Purpose	: initialize the error handling requirements for a given hub.
- * Parameters	: cnode, the compact nodeid.
- * Assumptions	: Called only once per hub, either by a local cpu. Or by a 
- *			remote cpu, when this hub is headless.(cpuless)
- * Returns	: None
- */
-
-void
-hub_error_init(cnodeid_t cnode)
-{
-	nasid_t nasid;
-
-    nasid = cnodeid_to_nasid(cnode);
-    hub_error_clear(nasid);
-
-    /*
-     * Now setup the hub ii and ni error interrupt handler.
-     */
-
-    hubii_eint_init(cnode);
-    hubni_eint_init(cnode);
-
-    return;
-}
-
-/*
- * Function	: hubii_eint_init
- * Parameters	: cnode
- * Purpose	: to initialize the hub iio error interrupt.
- * Assumptions	: Called once per hub, by the cpu which will ultimately
- *			handle this interrupt.
- * Returns	: None.
- */
-
-
-void
-hubii_eint_init(cnodeid_t cnode)
-{
-    int			bit, rv;
-    ii_iidsr_u_t    	hubio_eint;
-    hubinfo_t		hinfo; 
-    cpuid_t		intr_cpu;
-    devfs_handle_t 	hub_v;
-    ii_ilcsr_u_t	ilcsr;
-    int bit_pos_to_irq(int bit);
-    int synergy_intr_connect(int bit, int cpuid);
-
-
-    hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode);
-    ASSERT_ALWAYS(hub_v);
-    hubinfo_get(hub_v, &hinfo);
-
-    ASSERT(hinfo);
-    ASSERT(hinfo->h_cnodeid == cnode);
-
-    ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
-
-    if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) {
-	/* 
-	 * HUB II link is not up. 
-	 * Just disable LLP, and don't connect any interrupts.
-	 */
-	ilcsr.ii_ilcsr_fld_s.i_llp_en = 0;
-	REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval);
-	return;
-    }
-    /* Select a possible interrupt target where there is a free interrupt
-     * bit and also reserve the interrupt bit for this IO error interrupt
-     */
-    intr_cpu = intr_heuristic(hub_v,0,INTRCONNECT_ANYBIT,II_ERRORINT,hub_v,
-			      "HUB IO error interrupt",&bit);
-    if (intr_cpu == CPU_NONE) {
-	printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode);
-	return;
-    }
-	
-    rv = intr_connect_level(intr_cpu, bit, 0, NULL);
-    synergy_intr_connect(bit, intr_cpu);
-    request_irq(bit_pos_to_irq(bit) + (intr_cpu << 8), hubii_eint_handler, 0, "SN hub error", (void *)hub_v);
-    ASSERT_ALWAYS(rv >= 0);
-    hubio_eint.ii_iidsr_regval = 0;
-    hubio_eint.ii_iidsr_fld_s.i_enable = 1;
-    hubio_eint.ii_iidsr_fld_s.i_level = bit;/* Take the least significant bits*/
-    hubio_eint.ii_iidsr_fld_s.i_node = COMPACT_TO_NASID_NODEID(cnode);
-    hubio_eint.ii_iidsr_fld_s.i_pi_id = cpuid_to_subnode(intr_cpu);
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, hubio_eint.ii_iidsr_regval);
-
-}
-
-void
-hubni_eint_init(cnodeid_t cnode)
-{
-    int intr_bit;
-    cpuid_t targ;
-
-
-    if ((targ = cnodeid_to_cpuid(cnode)) == CPU_NONE)
-	return;
-
-	/* The prom chooses which cpu gets these interrupts, but we
-	*  don't know which one it chose.  We will register all of the 
-	*  cpus to be sure.  This only costs us an irqaction per cpu.
-	*/
-    for (; targ < CPUS_PER_NODE; targ++) {
-	if (!cpu_enabled(targ) ) continue;
-	/* connect the INTEND1 bits. */
-	for (intr_bit = XB_ERROR; intr_bit <= MSC_PANIC_INTR; intr_bit++) {
-		intr_connect_level(targ, intr_bit, II_ERRORINT, NULL);
-	}
-	request_irq(SGI_HUB_ERROR_IRQ + (targ << 8), snia_error_intr_handler, 0, "SN hub error", NULL);
-	/* synergy masks are initialized in the prom to enable all interrupts. */
-	/* We'll just leave them that way, here, for these interrupts. */
-    }
-}
-
-
-/*ARGSUSED*/
-void
-hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
-{
-
-	panic("Hubii interrupt\n");
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/ip37.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/ip37.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/ip37.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/ip37.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,47 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * ip37.c
- *	Support for IP35/IP37 machines
- */
-
-#include <linux/types.h>
-
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/pci/bridge.h>     /* for bridge_t */
-
-
-xwidgetnum_t
-hub_widget_id(nasid_t nasid)
-{
-	hubii_wcr_t	ii_wcr;	/* the control status register */
-		
-	ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid,IIO_WCR);
-
-	return ii_wcr.wcr_fields_s.wcr_widget_id;
-}
-
-int
-is_fine_dirmode(void)
-{
-	return (((LOCAL_HUB_L(LB_REV_ID) & LRI_SYSTEM_SIZE_MASK)
-		>> LRI_SYSTEM_SIZE_SHFT) == SYSTEM_SIZE_SMALL);
-
-}
-
-
-void
-ni_reset_port(void)
-{
-	LOCAL_HUB_S(NI_RESET_ENABLE, NRE_RESETOK);
-	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/klconflib.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/klconflib.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/klconflib.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/klconflib.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,979 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#include <linux/types.h>
-#include <linux/ctype.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/module.h>
-#include <asm/sn/router.h>
-#include <asm/sn/xtalk/xbow.h>
-
-#define printf printk
-int hasmetarouter;
-
-#define LDEBUG 0
-#define NIC_UNKNOWN ((nic_t) -1)
-
-#undef DEBUG_KLGRAPH
-#ifdef DEBUG_KLGRAPH
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_KLGRAPH */
-
-static void sort_nic_names(lboard_t *) ;
-
-u64 klgraph_addr[MAX_COMPACT_NODES];
-int module_number = 0;
-
-lboard_t *
-find_lboard(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (start->brd_type == brd_type)
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_class(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-klinfo_t *
-find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
-{
-	int index, j;
-
-	if (kli == (klinfo_t *)NULL) {
-		index = 0;
-	} else {
-		for (j = 0; j < KLCF_NUM_COMPS(brd); j++) {
-			if (kli == KLCF_COMP(brd, j))
-				break;
-		}
-		index = j;
-		if (index == KLCF_NUM_COMPS(brd)) {
-			DBG("find_component: Bad pointer: 0x%p\n", kli);
-			return (klinfo_t *)NULL;
-		}
-		index++;	/* next component */
-	}
-	
-	for (; index < KLCF_NUM_COMPS(brd); index++) {		
-		kli = KLCF_COMP(brd, index);
-		DBG("find_component: brd %p kli %p  request type = 0x%x kli type 0x%x\n", brd, kli, kli->struct_type, KLCF_COMP_TYPE(kli));
-		if (KLCF_COMP_TYPE(kli) == struct_type)
-			return kli;
-	}
-
-	/* Didn't find it. */
-	return (klinfo_t *)NULL;
-}
-
-klinfo_t *
-find_first_component(lboard_t *brd, unsigned char struct_type)
-{
-	return find_component(brd, (klinfo_t *)NULL, struct_type);
-}
-
-lboard_t *
-find_lboard_modslot(lboard_t *start, moduleid_t mod, slotid_t slot)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (MODULE_MATCH(start->brd_module, mod) &&
-		    (start->brd_slot == slot))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_module(lboard_t *start, moduleid_t mod)
-{
-        /* Search all boards stored on this node. */
-        while (start) {
-                if (MODULE_MATCH(start->brd_module, mod))
-                        return start;
-                start = KLCF_NEXT(start);
-        }
-
-        /* Didn't find it. */
-        return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_module_class(lboard_t *start, moduleid_t mod,
-                                                unsigned char brd_type)
-{
-	while (start) {
-		DBG("find_lboard_module_class: lboard 0x%p, start->brd_module 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_module, mod, start->brd_type, brd_type);
-
-		if (MODULE_MATCH(start->brd_module, mod) &&
-			(KLCLASS(start->brd_type) == KLCLASS(brd_type)))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-
-/*
- * Convert a NIC name to a name for use in the hardware graph.
- */
-void
-nic_name_convert(char *old_name, char *new_name)
-{
-        int i;
-        char c;
-        char *compare_ptr;
-
-	if ((old_name[0] == '\0') || (old_name[1] == '\0')) {
-                strcpy(new_name, EDGE_LBL_XWIDGET);
-        } else {
-                for (i = 0; i < strlen(old_name); i++) {
-                        c = old_name[i];
-
-                        if (isalpha(c))
-                                new_name[i] = tolower(c);
-                        else if (isdigit(c))
-                                new_name[i] = c;
-                        else
-                                new_name[i] = '_';
-                }
-                new_name[i] = '\0';
-        }
-
-        /* XXX -
-         * Since a bunch of boards made it out with weird names like
-         * IO6-fibbbed and IO6P2, we need to look for IO6 in a name and
-         * replace it with "baseio" to avoid confusion in the field.
-	 * We also have to make sure we don't report media_io instead of
-	 * baseio.
-         */
-
-        /* Skip underscores at the beginning of the name */
-        for (compare_ptr = new_name; (*compare_ptr) == '_'; compare_ptr++)
-                ;
-
-	/*
-	 * Check for some names we need to replace.  Early boards
-	 * had junk following the name so check only the first
-	 * characters.
-	 */
-        if (!strncmp(new_name, "io6", 3) || 
-            !strncmp(new_name, "mio", 3) || 
-	    !strncmp(new_name, "media_io", 8))
-		strcpy(new_name, "baseio");
-	else if (!strncmp(new_name, "divo", 4))
-		strcpy(new_name, "divo") ;
-
-}
-
-/* Check if the given board corresponds to the global 
- * master io6
- */
-int
-is_master_baseio(nasid_t nasid,moduleid_t module,slotid_t slot)
-{
-	lboard_t	*board;
-
-/* If this works then look for callers of is_master_baseio()
- * (e.g. iograph.c) and let them pass in a slot if they want
- */
-	board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), module);
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!board && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-			board = find_lboard_module((lboard_t *)
-				    KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				    module);
-	}
-#endif
-	if (!board)
-		return(0);
-	return(board->brd_flags & GLOBAL_MASTER_IO6);
-}
-/*
- * Find the lboard structure and get the board name.
- * If we can't find the structure or it's too low a revision,
- * use default name.
- */
-lboard_t *
-get_board_name(nasid_t nasid, moduleid_t mod, slotid_t slot, char *name)
-{
-	lboard_t *brd;
-
-	brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid),
-				  mod, slot);
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-			brd = find_lboard_modslot((lboard_t *)
-				KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				mod, slot);
-	}
-#endif
-
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, name);
-	}
-
-	/*
- 	 * PV # 540860
-	 * If the name is not 'baseio' 
-	 * get the lowest of all the names in the nic string.
-	 * This is needed for boards like divo, which can have
-	 * a bunch of daughter cards, but would like to be called
-	 * divo. We could do this for baseio 
- 	 * but it has some special case names that we would not
- 	 * like to disturb at this point.
-	 */
-
-	/* gfx boards don't need any of this name scrambling */
-	if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) {
-		return(brd);
-	}
-
-	if (!(!strcmp(name, "baseio") )) {
-		if (brd) {
-			sort_nic_names(brd) ;
-			/* Convert to small case, '-' to '_' etc */
-			nic_name_convert(brd->brd_name, name) ;
-		}
-	}
-
-	return(brd);
-}
-
-/*
- * get_actual_nasid
- *
- *	Completely disabled brds have their klconfig on 
- *	some other nasid as they have no memory. But their
- *	actual nasid is hidden in the klconfig. Use this
- *	routine to get it. Works for normal boards too.
- */
-nasid_t
-get_actual_nasid(lboard_t *brd)
-{
-	klhub_t	*hub ;
-
-	if (!brd)
-		return INVALID_NASID ;
-
-	/* find out if we are a completely disabled brd. */
-
-        hub  = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-	if (!hub)
-                return INVALID_NASID ;
-	if (!(hub->hub_info.flags & KLINFO_ENABLE))	/* disabled node brd */
-		return hub->hub_info.physid ;
-	else
-		return brd->brd_nasid ;
-}
-
-int
-xbow_port_io_enabled(nasid_t nasid, int link)
-{
-	lboard_t *brd;
-	klxbow_t *xbow_p;
-
-	/*
-	 * look for boards that might contain an xbow or xbridge
-	 */
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW);
-	if (brd == NULL) return 0;
-		
-	if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
-	    == NULL)
-	    return 0;
-
-	if (!XBOW_PORT_TYPE_IO(xbow_p, link) || !XBOW_PORT_IS_ENABLED(xbow_p, link))
-	    return 0;
-
-	return 1;
-}
-
-void
-board_to_path(lboard_t *brd, char *path)
-{
-	moduleid_t modnum;
-	char *board_name;
-
-	ASSERT(brd);
-
-	switch (KLCLASS(brd->brd_type)) {
-
-		case KLCLASS_NODE:
-			board_name = EDGE_LBL_NODE;
-			break;
-		case KLCLASS_ROUTER:
-			if (brd->brd_type == KLTYPE_META_ROUTER) {
-				board_name = EDGE_LBL_META_ROUTER;
-				hasmetarouter++;
-			} else if (brd->brd_type == KLTYPE_REPEATER_ROUTER) {
-				board_name = EDGE_LBL_REPEATER_ROUTER;
-				hasmetarouter++;
-			} else
-				board_name = EDGE_LBL_ROUTER;
-			break;
-		case KLCLASS_MIDPLANE:
-			board_name = EDGE_LBL_MIDPLANE;
-			break;
-		case KLCLASS_IO:
-			board_name = EDGE_LBL_IO;
-			break;
-		case KLCLASS_IOBRICK:
-			if (brd->brd_type == KLTYPE_PBRICK)
-				board_name = EDGE_LBL_PBRICK;
-			else if (brd->brd_type == KLTYPE_IBRICK)
-				board_name = EDGE_LBL_IBRICK;
-			else if (brd->brd_type == KLTYPE_XBRICK)
-				board_name = EDGE_LBL_XBRICK;
-			else
-				board_name = EDGE_LBL_IOBRICK;
-			break;
-		default:
-			board_name = EDGE_LBL_UNKNOWN;
-	}
-			
-	modnum = brd->brd_module;
-
-	/* ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE); */
-if ((modnum == MODULE_UNKNOWN) || (modnum == INVALID_MODULE)) {
-	modnum = ++module_number;
-}
-#ifdef __ia64
-	{
-		char	buffer[16];
-		memset(buffer, 0, 16);
-		format_module_id(buffer, modnum, MODULE_FORMAT_BRIEF);
-		sprintf(path, EDGE_LBL_MODULE "/%s/%s", buffer, board_name);
-	}
-#else
-	sprintf(path, "%H/%s", modnum, board_name);
-#endif
-}
-
-/*
- * Get the module number for a NASID.
- */
-moduleid_t
-get_module_id(nasid_t nasid)
-{
-	lboard_t *brd;
-
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-
-	if (!brd)
-		return INVALID_MODULE;
-	else
-		return brd->brd_module;
-}
-
-
-#define MHZ	1000000
-
-
-/* Get the canonical hardware graph name for the given pci component
- * on the given io board.
- */
-void
-device_component_canonical_name_get(lboard_t 	*brd,
-				    klinfo_t 	*component,
-				    char 	*name)
-{
-	moduleid_t 	modnum;
-	slotid_t 	slot;
-	char 		board_name[20];
-
-	ASSERT(brd);
-
-	/* Get the module number of this board */
-	modnum = brd->brd_module;
-
-	/* Convert the [ CLASS | TYPE ] kind of slotid
-	 * into a string 
-	 */
-	slot = brd->brd_slot;
-	ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE);
-
-	/* Get the io board name  */
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, board_name);
-	}
-
-	/* Give out the canonical  name of the pci device*/
-	sprintf(name, 
-		"/dev/hw/"EDGE_LBL_MODULE "/%x/"EDGE_LBL_SLOT"/%s/"
-		EDGE_LBL_PCI"/%d", 
-		modnum, board_name,KLCF_BRIDGE_W_ID(component));
-}
-
-/*
- * Get the serial number of the main  component of a board
- * Returns 0 if a valid serial number is found
- * 1 otherwise.
- * Assumptions: Nic manufacturing string  has the following format
- *			*Serial:<serial_number>;*
- */
-static int
-component_serial_number_get(lboard_t 		*board,
-			    klconf_off_t 	mfg_nic_offset,
-			    char		*serial_number,
-			    char		*key_pattern)
-{
-
-	char	*mfg_nic_string;
-	char	*serial_string,*str;
-	int	i;
-	char	*serial_pattern = "Serial:";
-
-	/* We have an error on a null mfg nic offset */
-	if (!mfg_nic_offset)
-		return(1);
-	/* Get the hub's manufacturing nic information
-	 * which is in the form of a pre-formatted string
-	 */
-	mfg_nic_string = 
-		(char *)NODE_OFFSET_TO_K0(NASID_GET(board),
-					  mfg_nic_offset);
-	/* There is no manufacturing nic info */
-	if (!mfg_nic_string)
-		return(1);
-
-	str = mfg_nic_string;
-	/* Look for the key pattern first (if it is  specified)
-	 * and then print the serial number corresponding to that.
-	 */
-	if (strcmp(key_pattern,"") && 
-	    !(str = strstr(mfg_nic_string,key_pattern)))
-		return(1);
-
-	/* There is no serial number info in the manufacturing
-	 * nic info
-	 */
-	if (!(serial_string = strstr(str,serial_pattern)))
-		return(1);
-
-	serial_string = serial_string + strlen(serial_pattern);
-	/*  Copy the serial number information from the klconfig */
-	i = 0;
-	while (serial_string[i] != ';') {
-		serial_number[i] = serial_string[i];
-		i++;
-	}
-	serial_number[i] = 0;
-	
-	return(0);
-}
-/*
- * Get the serial number of a board
- * Returns 0 if a valid serial number is found
- * 1 otherwise.
- */
-
-int
-board_serial_number_get(lboard_t *board,char *serial_number)
-{
-	ASSERT(board && serial_number);
-	if (!board || !serial_number)
-		return(1);
-
-	strcpy(serial_number,"");
-	switch(KLCLASS(board->brd_type)) {
-	case KLCLASS_CPU: {	/* Node board */
-		klhub_t	*hub;
-		
-		/* Get the hub component information */
-		hub = (klhub_t *)find_first_component(board,
-						      KLSTRUCT_HUB);
-		/* If we don't have a hub component on an IP27
-		 * then we have a weird klconfig.
-		 */
-		if (!hub)
-			return(1);
-		/* Get the serial number information from
-		 * the hub's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						hub->hub_mfg_nic,
-						serial_number,
-						"IP37"))
-				return(1);
-		break;
-	}
-	case KLCLASS_IO: {	/* IO board */
-		if (KLTYPE(board->brd_type) == KLTYPE_TPU) {
-		/* Special case for TPU boards */
-			kltpu_t *tpu;	
-		
-			/* Get the tpu component information */
-			tpu = (kltpu_t *)find_first_component(board,
-						      KLSTRUCT_TPU);
-			/* If we don't have a tpu component on a tpu board
-			 * then we have a weird klconfig.
-			 */
-			if (!tpu)
-				return(1);
-			/* Get the serial number information from
-			 * the tpu's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						tpu->tpu_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		} else  if ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ||
-		            (KLTYPE(board->brd_type) == KLTYPE_GSN_B)) {
-		/* Special case for GSN boards */
-			klgsn_t *gsn;	
-		
-			/* Get the gsn component information */
-			gsn = (klgsn_t *)find_first_component(board,
-			      ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ?
-					KLSTRUCT_GSN_A : KLSTRUCT_GSN_B));
-			/* If we don't have a gsn component on a gsn board
-			 * then we have a weird klconfig.
-			 */
-			if (!gsn)
-				return(1);
-			/* Get the serial number information from
-			 * the gsn's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						gsn->gsn_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		} else {
-		     	klbri_t	*bridge;
-		
-			/* Get the bridge component information */
-			bridge = (klbri_t *)find_first_component(board,
-							 KLSTRUCT_BRI);
-			/* If we don't have a bridge component on an IO board
-			 * then we have a weird klconfig.
-			 */
-			if (!bridge)
-				return(1);
-			/* Get the serial number information from
-		 	 * the bridge's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						bridge->bri_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		}
-	}
-	case KLCLASS_ROUTER: {	/* Router board */
-		klrou_t *router;	
-		
-		/* Get the router component information */
-		router = (klrou_t *)find_first_component(board,
-							 KLSTRUCT_ROU);
-		/* If we don't have a router component on a router board
-		 * then we have a weird klconfig.
-		 */
-		if (!router)
-			return(1);
-		/* Get the serial number information from
-		 * the router's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						router->rou_mfg_nic,
-						serial_number,
-						""))
-			return(1);
-		break;
-	}
-	case KLCLASS_GFX: {	/* Gfx board */
-		klgfx_t *graphics;
-		
-		/* Get the graphics component information */
-		graphics = (klgfx_t *)find_first_component(board, KLSTRUCT_GFX);
-		/* If we don't have a gfx component on a gfx board
-		 * then we have a weird klconfig.
-		 */
-		if (!graphics)
-			return(1);
-		/* Get the serial number information from
-		 * the graphics's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						graphics->gfx_mfg_nic,
-						serial_number,
-						""))
-			return(1);
-		break;
-	}
-	default:
-		strcpy(serial_number,"");
-		break;
-	}
-	return(0);
-}
-
-#include "asm/sn/sn_private.h"
-
-xwidgetnum_t
-nodevertex_widgetnum_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, 
-			     (arbitrary_info_t *) &hubinfo_p);
-	return(hubinfo_p->h_widgetid);
-}
-
-devfs_handle_t
-nodevertex_xbow_peer_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-	nasid_t xbow_peer_nasid;
-	cnodeid_t xbow_peer;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO,
-				     (arbitrary_info_t *) &hubinfo_p);
-	xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer;
-	if(xbow_peer_nasid == INVALID_NASID) 
-			return ( (devfs_handle_t)-1);
-	xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid);
-	return(NODEPDA(xbow_peer)->node_vertex);
-}
-
-/* NIC Sorting Support */
-
-#define MAX_NICS_PER_STRING 	32
-#define MAX_NIC_NAME_LEN	32
-
-static char *
-get_nic_string(lboard_t *lb)
-{
-        int         	i;
-        klinfo_t    	*k = NULL ;
-    	klconf_off_t    mfg_off = 0 ;
-    	char            *mfg_nic = NULL ;
-
-        for (i = 0; i < KLCF_NUM_COMPS(lb); i++) {
-                k = KLCF_COMP(lb, i) ;
-                switch(k->struct_type) {
-                        case KLSTRUCT_BRI:
-            			mfg_off = ((klbri_t *)k)->bri_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_HUB:
-            			mfg_off = ((klhub_t *)k)->hub_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_ROU:
-            			mfg_off = ((klrou_t *)k)->rou_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GFX:
-            			mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_TPU:
-            			mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GSN_A:
-                        case KLSTRUCT_GSN_B:
-            			mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_XTHD:
-                                mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ;
-                                break;
-
-			default:
-				mfg_off = 0 ;
-                                break ;
-                }
-		if (mfg_off)
-			break ;
-        }
-
-	if ((mfg_off) && (k))
-		mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ;
-
-        return mfg_nic ;
-}
-
-char *
-get_first_string(char **ptrs, int n)
-{
-        int     i ;
-        char    *tmpptr ;
-
-        if ((ptrs == NULL) || (n == 0))
-                return NULL ;
-
-        tmpptr = ptrs[0] ;
-
-        if (n == 1)
-                return tmpptr ;
-
-        for (i = 0 ; i < n ; i++) {
-                if (strcmp(tmpptr, ptrs[i]) > 0)
-                        tmpptr = ptrs[i] ;
-        }
-
-        return tmpptr ;
-}
-
-int
-get_ptrs(char *idata, char **ptrs, int n, char *label)
-{
-        int     i = 0 ;
-        char    *tmp = idata ;
-
-        if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0))
-                return 0 ;
-
-        while  ( (tmp = strstr(tmp, label)) ){
-                tmp += strlen(label) ;
-                /* check for empty name field, and last NULL ptr */
-                if ((i < (n-1)) && (*tmp != ';')) {
-                        ptrs[i++] = tmp ;
-                }
-        }
-
-        ptrs[i] = NULL ;
-
-        return i ;
-}
-
-/*
- * sort_nic_names
- *
- * 	Does not really do sorting. Find the alphabetically lowest
- *	name among all the nic names found in a nic string.
- *
- * Return:
- *	Nothing
- *
- * Side Effects:
- *
- *	lb->brd_name gets the new name found
- */
-
-static void
-sort_nic_names(lboard_t *lb)
-{
-	char 	*nic_str ;
-        char    *ptrs[MAX_NICS_PER_STRING] ;
-        char    name[MAX_NIC_NAME_LEN] ;
-        char    *tmp, *tmp1 ;
-
-	*name = 0 ;
-
-	/* Get the nic pointer from the lb */
-
-	if ((nic_str = get_nic_string(lb)) == NULL)
-		return ;
-
-        tmp = get_first_string(ptrs,
-                        get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ;
-
-        if (tmp == NULL)
-		return ;
-
-        if  ( (tmp1 = strchr(tmp, ';')) ){
-                strncpy(name, tmp, tmp1-tmp) ;
-                name[tmp1-tmp] = 0 ;
-        } else {
-                strncpy(name, tmp, (sizeof(name) -1)) ;
-                name[sizeof(name)-1] = 0 ;
-        }
-
-	strcpy(lb->brd_name, name) ;
-}
-
-
-
-char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#012345";
-
-
-/*
- * Format a module id for printing.
- */
-void
-format_module_id(char *buffer, moduleid_t m, int fmt)
-{
-	int rack, position;
-	char brickchar;
-
-	rack = MODULE_GET_RACK(m);
-	ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES);
-	brickchar = MODULE_GET_BTCHAR(m);
-	position = MODULE_GET_BPOS(m);
-
-	if (fmt == MODULE_FORMAT_BRIEF) {
-	    /* Brief module number format, eg. 002c15 */
-
-	    /* Decompress the rack number */
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
-
-	    /* Add the brick type */
-	    *buffer++ = brickchar;
-	}
-	else if (fmt == MODULE_FORMAT_LONG) {
-	    /* Fuller hwgraph format, eg. rack/002/bay/15 */
-
-	    strcpy(buffer, EDGE_LBL_RACK "/");  buffer += strlen(buffer);
-
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
-
-	    strcpy(buffer, "/" EDGE_LBL_RPOS "/");  buffer += strlen(buffer);
-	}
-
-	/* Add the bay position, using at least two digits */
-	if (position < 10)
-	    *buffer++ = '0';
-	sprintf(buffer, "%d", position);
-
-}
-
-/*
- * Parse a module id, in either brief or long form.
- * Returns < 0 on error.
- * The long form does not include a brick type, so it defaults to 0 (CBrick)
- */
-int
-parse_module_id(char *buffer)
-{
-	unsigned int	v, rack, bay, type, form;
-	moduleid_t	m;
-	char 		c;
-
-	if (strstr(buffer, EDGE_LBL_RACK "/") == buffer) {
-		form = MODULE_FORMAT_LONG;
-		buffer += strlen(EDGE_LBL_RACK "/");
-
-		/* A long module ID must be exactly 5 non-template chars. */
-		if (strlen(buffer) != strlen("/" EDGE_LBL_RPOS "/") + 5)
-			return -1;
-	}
-	else {
-		form = MODULE_FORMAT_BRIEF;
-
-		/* A brief module id must be exactly 6 characters */
-		if (strlen(buffer) != 6)
-			return -2;
-	}
-
-	/* The rack number must be exactly 3 digits */
-	if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && isdigit(buffer[2])))
-		return -3;
-
-	rack = 0;
-	v = *buffer++ - '0';
-	if (v > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-		return -4;
-	RACK_ADD_CLASS(rack, v);
-
-	v = *buffer++ - '0';
-	if (v > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-		return -5;
-	RACK_ADD_GROUP(rack, v);
-
-	v = *buffer++ - '0';
-	/* rack numbers are 1-based */
-	if (v-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-		return -6;
-	RACK_ADD_NUM(rack, v);
-
-	if (form == MODULE_FORMAT_BRIEF) {
-		/* Next should be a module type character.  Accept ucase or lcase. */
-		c = *buffer++;
-		if (!isalpha(c))
-			return -7;
-
-		/* strchr() returns a pointer into brick_types[], or NULL */
-		type = (unsigned int)(strchr(brick_types, tolower(c)) - brick_types);
-		if (type > MODULE_BTYPE_MASK >> MODULE_BTYPE_SHFT)
-			return -8;
-	}
-	else {
-		/* Hardcode the module type, and skip over the boilerplate */
-		type = MODULE_CBRICK;
-
-		if (strstr(buffer, "/" EDGE_LBL_RPOS "/") != buffer)
-			return -9;
-
-		buffer += strlen("/" EDGE_LBL_RPOS "/");
-	}
-		
-	/* The bay number is last.  Make sure it's exactly two digits */
-
-	if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && !buffer[2]))
-		return -10;
-
-	bay = 10 * (buffer[0] - '0') + (buffer[1] - '0');
-
-	if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-		return -11;
-
-	m = RBT_TO_MODULE(rack, bay, type);
-
-	/* avoid sign extending the moduleid_t */
-	return (int)(unsigned short)m;
-}
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/klgraph.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/klgraph.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/klgraph.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/klgraph.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,940 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * klgraph.c-
- *      This file specifies the interface between the kernel and the PROM's
- *      configuration data structures.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/kldir.h>
-#include <asm/sn/gda.h> 
-#include <asm/sn/klconfig.h>
-#include <asm/sn/router.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/hcl_util.h>
-
-/* #define KLGRAPH_DEBUG 1 */
-#ifdef KLGRAPH_DEBUG
-#define GRPRINTF(x)	printk x
-#define CE_GRPANIC	CE_PANIC
-#else
-#define GRPRINTF(x)
-#define CE_GRPANIC	CE_PANIC
-#endif
-
-#include <asm/sn/sn_private.h>
-
-extern char arg_maxnodes[];
-extern u64 klgraph_addr[];
-
-/*
- * Support for verbose inventory via hardware graph. 
- * klhwg_invent_alloc allocates the necessary size of inventory information
- * and fills in the generic information.
- */
-invent_generic_t *
-klhwg_invent_alloc(cnodeid_t cnode, int class, int size)
-{
-	invent_generic_t *invent;
-
-	invent = kern_malloc(size);
-	if (!invent) return NULL;
-	
-	invent->ig_module = NODE_MODULEID(cnode);
-	invent->ig_slot = SLOTNUM_GETSLOT(NODE_SLOTID(cnode));
-	invent->ig_invclass = class;
-
-	return invent;
-}
-
-/*
- * Add detailed disabled cpu inventory info to the hardware graph.
- */
-void
-klhwg_disabled_cpu_invent_info(devfs_handle_t cpuv,
-                               cnodeid_t cnode,
-                               klcpu_t *cpu, slotid_t slot)
-{
-	invent_cpuinfo_t *cpu_invent;
-	diag_inv_t       *diag_invent;
-
-	cpu_invent = (invent_cpuinfo_t *)
-	klhwg_invent_alloc(cnode, INV_PROCESSOR, sizeof(invent_cpuinfo_t));
-	if (!cpu_invent)
-		return;
-
-	/* Diag information on this processor */
-	diag_invent = (diag_inv_t *)
-	klhwg_invent_alloc(cnode, INV_CPUDIAGVAL, sizeof(diag_inv_t));
-
-	if (!diag_invent)
-		return;
-
-
-	/* Disabled CPU */
-	cpu_invent->ic_gen.ig_flag = 0x0;
-	cpu_invent->ic_gen.ig_slot = slot;
-	cpu_invent->ic_cpu_info.cpuflavor = cpu->cpu_prid;
-	cpu_invent->ic_cpu_info.cpufq = cpu->cpu_speed;
-	cpu_invent->ic_cpu_info.sdfreq = cpu->cpu_scachespeed;
-
-	cpu_invent->ic_cpu_info.sdsize = cpu->cpu_scachesz;
-	cpu_invent->ic_cpuid = cpu->cpu_info.virtid;
-	cpu_invent->ic_slice = cpu->cpu_info.physid;
-
-	/* Disabled CPU label */
-	hwgraph_info_add_LBL(cpuv, INFO_LBL_DETAIL_INVENT,
-			(arbitrary_info_t) cpu_invent);
-	hwgraph_info_export_LBL(cpuv, INFO_LBL_DETAIL_INVENT,
-			sizeof(invent_cpuinfo_t));
-
-	/* Diagval label - stores reason for disable +{virt,phys}id +diagval*/
-	hwgraph_info_add_LBL(cpuv, INFO_LBL_DIAGVAL,
-			(arbitrary_info_t) diag_invent);
-
-	hwgraph_info_export_LBL(cpuv, INFO_LBL_DIAGVAL,
-			sizeof(diag_inv_t));
-}
-
-/*
- * Add detailed cpu inventory info to the hardware graph.
- */
-void
-klhwg_cpu_invent_info(devfs_handle_t cpuv,
-			cnodeid_t cnode,
-			klcpu_t *cpu)
-{
-	invent_cpuinfo_t *cpu_invent;
-
-	cpu_invent = (invent_cpuinfo_t *)
-		klhwg_invent_alloc(cnode, INV_PROCESSOR, sizeof(invent_cpuinfo_t));
-	if (!cpu_invent)
-		return;
-
-	if (KLCONFIG_INFO_ENABLED((klinfo_t *)cpu))
-		cpu_invent->ic_gen.ig_flag = INVENT_ENABLED;
-	else
-		cpu_invent->ic_gen.ig_flag = 0x0;
-
-	cpu_invent->ic_cpu_info.cpuflavor = cpu->cpu_prid;
-	cpu_invent->ic_cpu_info.cpufq = cpu->cpu_speed;
-	cpu_invent->ic_cpu_info.sdfreq = cpu->cpu_scachespeed;
-
-	cpu_invent->ic_cpu_info.sdsize = cpu->cpu_scachesz;
-	cpu_invent->ic_cpuid = cpu->cpu_info.virtid;
-	cpu_invent->ic_slice = cpu_physical_id_to_slice(cpu->cpu_info.virtid);
-
-	hwgraph_info_add_LBL(cpuv, INFO_LBL_DETAIL_INVENT,
-			(arbitrary_info_t) cpu_invent);
-	hwgraph_info_export_LBL(cpuv, INFO_LBL_DETAIL_INVENT,
-			sizeof(invent_cpuinfo_t));
-}
-
-/* 
- * Add information about the baseio prom version number
- * as a part of detailed inventory info in the hwgraph.
- */
-void
-klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode)
-{
-	invent_miscinfo_t	*baseio_inventory;
-	unsigned char		version = 0,revision = 0;
-
-	/* Allocate memory for the "detailed inventory" info
-	 * for the baseio
-	 */
-	baseio_inventory = (invent_miscinfo_t *) 
-		klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t));
-	baseio_inventory->im_type = INV_IO6PROM;
-	/* Store the revision info  in the inventory */
-	baseio_inventory->im_version = version;
-	baseio_inventory->im_rev = revision;
-	/* Put the inventory info in the hardware graph */
-	hwgraph_info_add_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) baseio_inventory);
-	/* Make the information available to the user programs
-	 * thru hwgfs.
-	 */
-        hwgraph_info_export_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-char	*hub_rev[] = {
-	"0.0",
-	"1.0",
-	"2.0",
-	"2.1",
-	"2.2",
-	"2.3"
-};
-
-/*
- * Add detailed cpu inventory info to the hardware graph.
- */
-void
-klhwg_hub_invent_info(devfs_handle_t hubv,
-		      cnodeid_t cnode, 
-		      klhub_t *hub)
-{
-	invent_miscinfo_t *hub_invent;
-
-	hub_invent = (invent_miscinfo_t *) 
-	    klhwg_invent_alloc(cnode, INV_MISC, sizeof(invent_miscinfo_t));
-	if (!hub_invent)
-	    return;
-
-	if (KLCONFIG_INFO_ENABLED((klinfo_t *)hub))
-	    hub_invent->im_gen.ig_flag = INVENT_ENABLED;
-
-	hub_invent->im_type = INV_HUB;
-	hub_invent->im_rev = hub->hub_info.revision;
-	hub_invent->im_speed = hub->hub_speed;
-	hwgraph_info_add_LBL(hubv, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) hub_invent);
-        hwgraph_info_export_LBL(hubv, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-/* ARGSUSED */
-void
-klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode)
-{
-	devfs_handle_t myhubv;
-	devfs_handle_t hub_mon;
-	devfs_handle_t synergy;
-	devfs_handle_t fsb0;
-	devfs_handle_t fsb1;
-	int rc;
-	extern struct file_operations hub_mon_fops;
-
-	GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB));
-
-	(void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
-	rc = device_master_set(myhubv, node_vertex);
-
-	/*
-	 * hub perf stats.
-	 */
-	rc = hwgraph_info_add_LBL(myhubv, INFO_LBL_HUB_INFO,
-                        (arbitrary_info_t)(&NODEPDA(cnode)->hubstats));
-
-	if (rc != GRAPH_SUCCESS) {
-		printk(KERN_WARNING  "klhwg_add_hub: Can't add hub info label 0x%p, code %d",
-			(void *)myhubv, rc);
-	}
-
-	klhwg_hub_invent_info(myhubv, cnode, hub);
-
-	hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &hub_mon_fops,
-	    (void *)(long)cnode);
-
-	init_hub_stats(cnode, NODEPDA(cnode));
-
-	/*
-	 * synergy perf
-	 */
-	(void) hwgraph_path_add(myhubv, EDGE_LBL_SYNERGY, &synergy);
-	(void) hwgraph_path_add(synergy, "0", &fsb0);
-	(void) hwgraph_path_add(synergy, "1", &fsb1);
-
-	fsb0 = hwgraph_register(fsb0, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 0));
-
-	fsb1 = hwgraph_register(fsb1, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 1));
-}
-
-/* ARGSUSED */
-void
-klhwg_add_disabled_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot)
-{
-        devfs_handle_t my_cpu;
-        char name[120];
-        cpuid_t cpu_id;
-	nasid_t nasid;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-        cpu_id = nasid_slice_to_cpuid(nasid, cpu->cpu_info.physid);
-        if(cpu_id != -1){
-		sprintf(name, "%s/%s/%c", EDGE_LBL_DISABLED, EDGE_LBL_CPU, 'a' + cpu->cpu_info.physid);
-		(void) hwgraph_path_add(node_vertex, name, &my_cpu);
-
-		mark_cpuvertex_as_cpu(my_cpu, cpu_id);
-		device_master_set(my_cpu, node_vertex);
-
-		klhwg_disabled_cpu_invent_info(my_cpu, cnode, cpu, slot);
-		return;
-        }
-}
-
-/* ARGSUSED */
-void
-klhwg_add_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu)
-{
-        devfs_handle_t my_cpu, cpu_dir;
-        char name[120];
-        cpuid_t cpu_id;
-	nasid_t nasid;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-        cpu_id = nasid_slice_to_cpuid(nasid, cpu->cpu_info.physid);
-
-        sprintf(name, "%s/%d/%c",
-                EDGE_LBL_CPUBUS,
-                0,
-                'a' + cpu->cpu_info.physid);
-
-        GRPRINTF(("klhwg_add_cpu: adding %s to vertex 0x%x\n", name, node_vertex));
-        (void) hwgraph_path_add(node_vertex, name, &my_cpu);
-        mark_cpuvertex_as_cpu(my_cpu, cpu_id);
-        device_master_set(my_cpu, node_vertex);
-
-        /* Add an alias under the node's CPU directory */
-        if (hwgraph_edge_get(node_vertex, EDGE_LBL_CPU, &cpu_dir) == GRAPH_SUCCESS) {
-                sprintf(name, "%c", 'a' + cpu->cpu_info.physid);
-                (void) hwgraph_edge_add(cpu_dir, my_cpu, name);
-        }
-
-        klhwg_cpu_invent_info(my_cpu, cnode, cpu);
-}
-
-
-void
-klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid)
-{
-	lboard_t *brd;
-	klxbow_t *xbow_p;
-	nasid_t hub_nasid;
-	cnodeid_t hub_cnode;
-	int widgetnum;
-	devfs_handle_t xbow_v, hubv;
-	/*REFERENCED*/
-	graph_error_t err;
-
-	if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW)) == NULL)
-			return;
-
-	if (KL_CONFIG_DUPLICATE_BOARD(brd))
-	    return;
-
-	GRPRINTF(("klhwg_add_xbow: adding cnode %d nasid %d xbow edges\n",
-			cnode, nasid));
-
-	if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
-	    == NULL)
-	    return;
-
-#ifdef	LATER
-	/*
-	 * We cannot support this function in devfs .. see below where 
-	 * we use hwgraph_path_add() to create this vertex with a known 
-	 * name.
-	 */
-	err = hwgraph_vertex_create(&xbow_v);
-	ASSERT(err == GRAPH_SUCCESS);
-
-	xswitch_vertex_init(xbow_v);
-#endif /* LATER */
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-		if (!XBOW_PORT_TYPE_HUB(xbow_p, widgetnum)) 
-		    continue;
-
-		hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum);
-		if (hub_nasid == INVALID_NASID) {
-			printk(KERN_WARNING  "hub widget %d, skipping xbow graph\n", widgetnum);
-			continue;
-		}
-
-		hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid);
-
-		if (is_specified(arg_maxnodes) && hub_cnode == INVALID_CNODEID) {
-			continue;
-		}
-			
-		hubv = cnodeid_to_vertex(hub_cnode);
-
-		err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v);
-                if (err != GRAPH_SUCCESS) {
-                        if (err == GRAPH_DUP)
-                                printk(KERN_WARNING  "klhwg_add_xbow: Check for "
-                                        "working routers and router links!");
-
-                        PRINT_PANIC("klhwg_add_xbow: Failed to add "
-                                "edge: vertex 0x%p to vertex 0x%p,"
-                                "error %d\n",
-                                (void *)hubv, (void *)xbow_v, err);
-                }
-		xswitch_vertex_init(xbow_v); 
-
-		NODEPDA(hub_cnode)->xbow_vhdl = xbow_v;
-
-		/*
-		 * XXX - This won't work is we ever hook up two hubs
-		 * by crosstown through a crossbow.
-		 */
-		if (hub_nasid != nasid) {
-			NODEPDA(hub_cnode)->xbow_peer = nasid;
-			NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer =
-				hub_nasid;
-		}
-
-		GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n",
-			hub_nasid, EDGE_LBL_XTALK, hubv));
-
-#ifdef	LATER
-		err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK);
-		if (err != GRAPH_SUCCESS) {
-			if (err == GRAPH_DUP)
-				printk(KERN_WARNING  "klhwg_add_xbow: Check for "
-					"working routers and router links!");
-
-			PRINT_PANIC("klhwg_add_xbow: Failed to add "
-				"edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p), "
-				"error %d\n",
-				hubv, hubv, xbow_v, xbow_v, err);
-		}
-#endif
-	}
-}
-
-
-/* ARGSUSED */
-void
-klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap)
-{
-	nasid_t nasid;
-	lboard_t *brd;
-	klhub_t *hub;
-	devfs_handle_t node_vertex = NULL;
-	char path_buffer[100];
-	int rv;
-	char *s;
-	int board_disabled = 0;
-	klcpu_t *cpu;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-	GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n",
-                cnode, nasid, brd));
-	ASSERT(brd);
-
-	do {
-		devfs_handle_t cpu_dir;
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(brd, path_buffer);
-
-		GRPRINTF(("klhwg_add_node: adding %s to vertex 0x%p\n",
-			path_buffer, hwgraph_root));
-		rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
-		if (rv != GRAPH_SUCCESS)
-			PRINT_PANIC("Node vertex creation failed.  "
-					  "Path == %s",
-				path_buffer);
-
-		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-		ASSERT(hub);
-		if(hub->hub_info.flags & KLINFO_ENABLE)
-			board_disabled = 0;
-		else
-			board_disabled = 1;
-		
-		if(!board_disabled) {
-			mark_nodevertex_as_node(node_vertex,
-					    cnode + board_disabled * numnodes);
-
-			s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer));
-			NODEPDA(cnode)->hwg_node_name =
-						kmalloc(strlen(s) + 1,
-						GFP_KERNEL);
-			ASSERT_ALWAYS(NODEPDA(cnode)->hwg_node_name != NULL);
-			strcpy(NODEPDA(cnode)->hwg_node_name, s);
-
-			hubinfo_set(node_vertex, NODEPDA(cnode)->pdinfo);
-
-			/* Set up node board's slot */
-			NODEPDA(cnode)->slotdesc = brd->brd_slot;
-
-			/* Set up the module we're in */
-			NODEPDA(cnode)->module_id = brd->brd_module;
-			NODEPDA(cnode)->module = module_lookup(brd->brd_module);
-		}
-
-
-		/* Get the first CPU structure */
-		cpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
-
-		/*
-		* If there's at least 1 CPU, add a "cpu" directory to represent
-		* the collection of all CPUs attached to this node.
-		*/
-		if (cpu) {
-			graph_error_t rv;
-
-			rv = hwgraph_path_add(node_vertex, EDGE_LBL_CPU, &cpu_dir);
-			if (rv != GRAPH_SUCCESS)
-				panic("klhwg_add_node: Cannot create CPU directory\n");
-		}
-
-		/* Add each CPU */
-		while (cpu) {
-			cpuid_t cpu_id;
-			cpu_id = nasid_slice_to_cpuid(nasid,cpu->cpu_info.physid);
-			if (cpu_enabled(cpu_id))
-				klhwg_add_cpu(node_vertex, cnode, cpu);
-			else
-				klhwg_add_disabled_cpu(node_vertex, cnode, cpu, brd->brd_slot);
-
-			cpu = (klcpu_t *)
-				find_component(brd, (klinfo_t *)cpu, KLSTRUCT_CPU);
-		} /* while */
-
-		if(!board_disabled)
-		klhwg_add_hub(node_vertex, hub, cnode);
-		
-		brd = KLCF_NEXT(brd);
-		if (brd)
-			brd = find_lboard(brd, KLTYPE_SNIA);
-		else
-			break;
-	} while(brd);
-}
-
-
-/* ARGSUSED */
-void
-klhwg_add_all_routers(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-	devfs_handle_t node_vertex;
-	char path_buffer[100];
-	int rv;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_add_all_routers: adding router on cnode %d\n",
-			cnode));
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_ROUTER);
-
-		if (!brd)
-			/* No routers stored in this node's memory */
-			continue;
-
-		do {
-			ASSERT(brd);
-			GRPRINTF(("Router board struct is %p\n", brd));
-
-			/* Don't add duplicate boards. */
-			if (brd->brd_flags & DUPLICATE_BOARD)
-				continue;
-
-			GRPRINTF(("Router 0x%p module number is %d\n", brd, brd->brd_module));
-			/* Generate a hardware graph path for this board. */
-			board_to_path(brd, path_buffer);
-
-			GRPRINTF(("Router path is %s\n", path_buffer));
-
-			/* Add the router */
-			GRPRINTF(("klhwg_add_all_routers: adding %s to vertex 0x%p\n",
-				path_buffer, hwgraph_root));
-			rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
-			if (rv != GRAPH_SUCCESS)
-				PRINT_PANIC("Router vertex creation "
-						  "failed.  Path == %s",
-					path_buffer);
-
-			GRPRINTF(("klhwg_add_all_routers: get next board from 0x%p\n",
-					brd));
-		/* Find the rest of the routers stored on this node. */
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd),
-			 KLTYPE_ROUTER)) );
-
-		GRPRINTF(("klhwg_add_all_routers: Done.\n"));
-	}
-
-}
-
-/* ARGSUSED */
-void
-klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd,
-			 cnodeid_t cnode, nasid_t nasid)
-{
-	klrou_t *router;
-	char path_buffer[50];
-	char dest_path[50];
-	devfs_handle_t router_hndl;
-	devfs_handle_t dest_hndl;
-	int rc;
-	int port;
-	lboard_t *dest_brd;
-
-	GRPRINTF(("klhwg_connect_one_router: Connecting router on cnode %d\n",
-			cnode));
-
-	/* Don't add duplicate boards. */
-	if (brd->brd_flags & DUPLICATE_BOARD) {
-		GRPRINTF(("klhwg_connect_one_router: Duplicate router 0x%p on cnode %d\n",
-			brd, cnode));
-		return;
-	}
-
-	/* Generate a hardware graph path for this board. */
-	board_to_path(brd, path_buffer);
-
-	rc = hwgraph_traverse(hwgraph_root, path_buffer, &router_hndl);
-
-	if (rc != GRAPH_SUCCESS && is_specified(arg_maxnodes))
-			return;
-
-	if (rc != GRAPH_SUCCESS)
-		printk(KERN_WARNING  "Can't find router: %s", path_buffer);
-
-	/* We don't know what to do with multiple router components */
-	if (brd->brd_numcompts != 1) {
-		PRINT_PANIC("klhwg_connect_one_router: %d cmpts on router\n",
-			brd->brd_numcompts);
-		return;
-	}
-
-
-	/* Convert component 0 to klrou_t ptr */
-	router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd),
-					      brd->brd_compts[0]);
-
-	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
-		/* See if the port's active */
-		if (router->rou_port[port].port_nasid == INVALID_NASID) {
-			GRPRINTF(("klhwg_connect_one_router: port %d inactive.\n",
-				 port));
-			continue;
-		}
-		if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(router->rou_port[port].port_nasid) 
-		    == INVALID_CNODEID) {
-			continue;
-		}
-
-		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-				router->rou_port[port].port_nasid,
-				router->rou_port[port].port_offset);
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(dest_brd, dest_path);
-
-		rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
-
-		if (rc != GRAPH_SUCCESS) {
-			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
-				continue;
-			PRINT_PANIC("Can't find router: %s", dest_path);
-		}
-		GRPRINTF(("klhwg_connect_one_router: Link from %s/%d to %s\n",
-			  path_buffer, port, dest_path));
-
-		sprintf(dest_path, "%d", port);
-
-		rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path);
-
-		if (rc == GRAPH_DUP) {
-			GRPRINTF(("Skipping port %d. nasid %d %s/%s\n",
-				  port, router->rou_port[port].port_nasid,
-				  path_buffer, dest_path));
-			continue;
-		}
-
-		if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes))
-			PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
-				path_buffer, dest_path, (void *)dest_hndl, rc);
-		
-	}
-}
-
-
-void
-klhwg_connect_routers(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_connect_routers: Connecting routers on cnode %d\n",
-			cnode));
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_ROUTER);
-
-		if (!brd)
-			continue;
-
-		do {
-
-			nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-			klhwg_connect_one_router(hwgraph_root, brd,
-						 cnode, nasid);
-
-		/* Find the rest of the routers stored on this node. */
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
-	}
-}
-
-
-
-void
-klhwg_connect_hubs(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-	klhub_t *hub;
-	lboard_t *dest_brd;
-	devfs_handle_t hub_hndl;
-	devfs_handle_t dest_hndl;
-	char path_buffer[50];
-	char dest_path[50];
-	graph_error_t rc;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_connect_hubs: Connecting hubs on cnode %d\n",
-			cnode));
-
-		brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-		ASSERT(brd);
-
-		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-		ASSERT(hub);
-
-		/* See if the port's active */
-		if (hub->hub_port.port_nasid == INVALID_NASID) {
-			GRPRINTF(("klhwg_connect_hubs: port inactive.\n"));
-			continue;
-		}
-
-		if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(hub->hub_port.port_nasid) == INVALID_CNODEID)
-			continue;
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(brd, path_buffer);
-
-		GRPRINTF(("klhwg_connect_hubs: Hub path is %s.\n", path_buffer));
-		rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl);
-
-		if (rc != GRAPH_SUCCESS)
-			printk(KERN_WARNING  "Can't find hub: %s", path_buffer);
-
-		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-				hub->hub_port.port_nasid,
-				hub->hub_port.port_offset);
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(dest_brd, dest_path);
-
-		rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
-
-		if (rc != GRAPH_SUCCESS) {
-			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
-				continue;
-			PRINT_PANIC("Can't find board: %s", dest_path);
-		} else {
-		
-
-			GRPRINTF(("klhwg_connect_hubs: Link from %s to %s.\n",
-			  path_buffer, dest_path));
-
-			rc = hwgraph_edge_add(hub_hndl, dest_hndl, EDGE_LBL_INTERCONNECT);
-
-			if (rc != GRAPH_SUCCESS)
-				PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
-				path_buffer, dest_path, (void *)dest_hndl, rc);
-
-		}
-	}
-}
-
-/* Store the pci/vme disabled board information as extended administrative
- * hints which can later be used by the drivers using the device/driver
- * admin interface. 
- */
-void
-klhwg_device_disable_hints_add(void)
-{
-	cnodeid_t	cnode; 		/* node we are looking at */
-	nasid_t		nasid;		/* nasid of the node */
-	lboard_t	*board;		/* board we are looking at */
-	int		comp_index;	/* component index */
-	klinfo_t	*component;	/* component in the board we are
-					 * looking at 
-					 */
-	char		device_name[MAXDEVNAME];
-	
-	for(cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		/* Check out all the board info stored  on a node */
-		while(board) {
-			/* No need to look at duplicate boards or non-io 
-			 * boards
-			 */
-			if (KL_CONFIG_DUPLICATE_BOARD(board) ||
-			    KLCLASS(board->brd_type) != KLCLASS_IO) {
-				board = KLCF_NEXT(board);
-				continue;
-			}
-			/* Check out all the components of a board */
-			for (comp_index = 0; 
-			     comp_index < KLCF_NUM_COMPS(board);
-			     comp_index++) {
-				component = KLCF_COMP(board,comp_index);
-				/* If the component is enabled move on to
-				 * the next component
-				 */
-				if (KLCONFIG_INFO_ENABLED(component))
-					continue;
-				/* NOTE : Since the prom only supports
-				 * the disabling of pci devices the following
-				 * piece of code makes sense. 
-				 * Make sure that this assumption is valid
-				 */
-				/* This component is disabled. Store this
-				 * hint in the extended device admin table
-				 */
-				/* Get the canonical name of the pci device */
-				device_component_canonical_name_get(board,
-							    component,
-							    device_name);
-#ifdef DEBUG
-				printf("%s DISABLED\n",device_name);
-#endif				
-			}
-			/* go to the next board info stored on this 
-			 * node 
-			 */
-			board = KLCF_NEXT(board);
-		}
-	}
-}
-
-void
-klhwg_add_all_modules(devfs_handle_t hwgraph_root)
-{
-	cmoduleid_t	cm;
-	char		name[128];
-	devfs_handle_t	vhdl;
-	int		rc;
-	char		buffer[16];
-
-	/* Add devices under each module */
-
-	for (cm = 0; cm < nummodules; cm++) {
-		/* Use module as module vertex fastinfo */
-
-#ifdef __ia64
-		memset(buffer, 0, 16);
-		format_module_id(buffer, modules[cm]->id, MODULE_FORMAT_BRIEF);
-		sprintf(name, EDGE_LBL_MODULE "/%s", buffer);
-#else
-		sprintf(name, EDGE_LBL_MODULE "/%x", modules[cm]->id);
-#endif
-
-		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
-		ASSERT(rc == GRAPH_SUCCESS);
-		rc = rc;
-
-		hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) modules[cm]);
-
-		/* Add system controller */
-
-#ifdef __ia64
-		sprintf(name,
-			EDGE_LBL_MODULE "/%s/" EDGE_LBL_L1,
-			buffer);
-#else
-		sprintf(name,
-			EDGE_LBL_MODULE "/%x/" EDGE_LBL_L1,
-			modules[cm]->id);
-#endif
-
-		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
-		ASSERT_ALWAYS(rc == GRAPH_SUCCESS); 
-		rc = rc;
-
-		hwgraph_info_add_LBL(vhdl,
-				     INFO_LBL_ELSC,
-				     (arbitrary_info_t) (__psint_t) 1);
-
-#ifdef	LATER
-		sndrv_attach(vhdl);
-		/*
-		 * We need to call the drivers attach routine ..
-		 */
-		FIXME("klhwg_add_all_modules: Need code to call driver attach.\n");
-#endif
-	}
-}
-
-void
-klhwg_add_all_nodes(devfs_handle_t hwgraph_root)
-{
-	cnodeid_t	cnode;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		klhwg_add_node(hwgraph_root, cnode, NULL);
-	}
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		klhwg_add_xbow(cnode, cnodeid_to_nasid(cnode));
-	}
-
-	/*
-	 * As for router hardware inventory information, we set this
-	 * up in router.c. 
-	 */
-	
-	klhwg_add_all_routers(hwgraph_root);
-	klhwg_connect_routers(hwgraph_root);
-	klhwg_connect_hubs(hwgraph_root);
-
-	/* Go through the entire system's klconfig
-	 * to figure out which pci components have been disabled
-	 */
-	klhwg_device_disable_hints_add();
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/l1.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/l1.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/l1.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/l1.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,3124 +0,0 @@
-/* $Id: l1.c,v 1.2 2002/11/16 02:23:19 steiner Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/* In general, this file is organized in a hierarchy from lower-level
- * to higher-level layers, as follows:
- *
- *	UART routines
- *	Bedrock/L1 "PPP-like" protocol implementation
- *	System controller "message" interface (allows multiplexing
- *		of various kinds of requests and responses with
- *		console I/O)
- *	Console interface:
- *	  "l1_cons", the glue that allows the L1 to act
- *		as the system console for the stdio libraries
- *
- * Routines making use of the system controller "message"-style interface
- * can be found in l1_command.c.
- */
-
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/uart16550.h>
-#include <asm/sn/simulator.h>
-
-
-/* Make all console writes atomic */
-#define SYNC_CONSOLE_WRITE	1
-
-
-/*********************************************************************
- * Hardware-level (UART) driver routines.
- */
-
-/* macros for reading/writing registers */
-
-/* USLD and USSD are needed for SN2 - but since we moving this code out soon ... */
-#define LD(x)			(*(volatile uint64_t *)(x))
-#define USLD(x)			LD(x)			// (*(volatile ushort *)(x))
-#define SD(x, v)        	(LD(x) = (uint64_t) (v))
-#define USSD(x, v)        	SD(x,v)			// (USLD(x) = (ushort) (v))
-
-/* location of uart receive/xmit data register */
-#define L1_UART_BASE(n)		((ulong)REMOTE_HSPEC_ADDR((n), 0x00000080))
-#define LOCK_HUB		REMOTE_HUB_ADDR
-
-#define ADDR_L1_REG(n, r)	( L1_UART_BASE(n) | ( (r) << 3 ) )
-#define READ_L1_UART_REG(n, r)  ( LD(ADDR_L1_REG((n), (r))) )
-
-#define WRITE_L1_UART_REG(n, r, v) ( SD(ADDR_L1_REG((n), (r)), (v)) )
-
-/* upper layer interface calling methods */
-#define SERIAL_INTERRUPT_MODE	0
-#define SERIAL_POLLED_MODE	1
-
-
-/* UART-related #defines */
-
-#define UART_BAUD_RATE		57600
-#define UART_FIFO_DEPTH		16
-#define UART_DELAY_SPAN		10
-#define UART_PUTC_TIMEOUT	50000
-#define UART_INIT_TIMEOUT	100000
-
-/* error codes */
-#define UART_SUCCESS		  0
-#define UART_TIMEOUT		(-1)
-#define UART_LINK		(-2)
-#define UART_NO_CHAR		(-3)
-#define UART_VECTOR		(-4)
-
-#define UART_DELAY(x)		udelay(x)
-
-/* Some debug counters */
-#define L1C_INTERRUPTS		0
-#define L1C_OUR_R_INTERRUPTS	1
-#define L1C_OUR_X_INTERRUPTS	2
-#define L1C_SEND_CALLUPS	3
-#define L1C_RECEIVE_CALLUPS	4
-#define L1C_SET_BAUD		5
-#define L1C_ALREADY_LOCKED	L1C_SET_BAUD
-#define L1C_R_IRQ		6
-#define L1C_R_IRQ_RET		7
-#define L1C_LOCK_TIMEOUTS	8
-#define L1C_LOCK_COUNTER	9
-#define L1C_UNLOCK_COUNTER	10
-#define L1C_REC_STALLS		11
-#define L1C_CONNECT_CALLS	12
-#define L1C_SIZE		L1C_CONNECT_CALLS	/* Set to the last one */
-
-uint64_t L1_collectibles[L1C_SIZE + 1];
-
-
-/*
- *	Some macros for handling Endian-ness
- */
-
-#define COPY_INT_TO_BUFFER(_b, _i, _n)		\
-	{					\
-		_b[_i++] = (_n >> 24) & 0xff;	\
-		_b[_i++] = (_n >> 16) & 0xff;	\
-		_b[_i++] = (_n >>  8) & 0xff;	\
-		_b[_i++] =  _n        & 0xff;	\
-	}
-
-#define COPY_BUFFER_TO_INT(_b, _i, _n)		\
-	{					\
-		_n  = (_b[_i++] << 24) & 0xff;	\
-		_n |= (_b[_i++] << 16) & 0xff;	\
-		_n |= (_b[_i++] <<  8) & 0xff;	\
-		_n |=  _b[_i++]        & 0xff;	\
-	}
-
-#define COPY_BUFFER_TO_BUFFER(_b, _i, _bn)	\
-	{					\
-	    char *_xyz = (char *)_bn;		\
-	    _xyz[3] = _b[_i++];			\
-	    _xyz[2] = _b[_i++];			\
-	    _xyz[1] = _b[_i++];			\
-	    _xyz[0] = _b[_i++];			\
-	}
-
-void snia_kmem_free(void *where, int size);
-
-#define ALREADY_LOCKED		1
-#define NOT_LOCKED		0
-static int early_l1_serial_out(nasid_t, char *, int, int /* defines above*/ );
-
-#define BCOPY(x,y,z)	memcpy(y,x,z)
-
-uint8_t L1_interrupts_connected;		/* Non-zero when we are in interrupt mode */
-
-
-/*
- * Console locking defines and functions.
- *
- */
-
-uint8_t L1_cons_is_inited = 0;			/* non-zero when console is init'd */
-nasid_t Master_console_nasid = (nasid_t)-1;
-extern nasid_t console_nasid;
-
-u64 ia64_sn_get_console_nasid(void);
-
-inline nasid_t
-get_master_nasid(void)
-{
-	nasid_t nasid = Master_console_nasid;
-
-	master_nasid = Master_console_nasid = nasid = 0;
-	if ( nasid == (nasid_t)-1 ) {
-		nasid = (nasid_t)ia64_sn_get_console_nasid();
-		if ( (nasid < 0) || (nasid >= MAX_NASIDS) ) {
-			/* Out of bounds, use local */
-			console_nasid = nasid = get_nasid();
-		}
-		else {
-			/* Got a valid nasid, set the console_nasid */
-			char xx[100];
-/* zzzzzz - force nasid to 0 for now */
-			sprintf(xx, "Master console is set to nasid %d (%d)\n", 0, (int)nasid);
-nasid = 0;
-/* end zzzzzz */
-			xx[99] = (char)0;
-			early_l1_serial_out(nasid, xx, strlen(xx), NOT_LOCKED);
-			Master_console_nasid = console_nasid = nasid;
-		}
-	}
-	return(nasid);
-}
-
-
-
-#define HUB_LOCK		16
-
-#define PRIMARY_LOCK_TIMEOUT    10000000
-#define HUB_LOCK_REG(n)         LOCK_HUB(n, MD_PERF_CNT0)
-
-#define SET_BITS(reg, bits)     SD(reg, LD(reg) |  (bits))
-#define CLR_BITS(reg, bits)     SD(reg, LD(reg) & ~(bits))
-#define TST_BITS(reg, bits)     ((LD(reg) & (bits)) != 0)
-
-#define HUB_TEST_AND_SET(n)	LD(LOCK_HUB(n,LB_SCRATCH_REG3_RZ))
-#define HUB_CLEAR(n)		SD(LOCK_HUB(n,LB_SCRATCH_REG3),0)
-
-#define RTC_TIME_MAX		((rtc_time_t) ~0ULL)
-
-/*
- * primary_lock
- *
- *   Allows CPU's 0-3  to mutually exclude the hub from one another by
- *   obtaining a blocking lock.  Does nothing if only one CPU is active.
- *
- *   This lock should be held just long enough to set or clear a global
- *   lock bit.  After a relatively short timeout period, this routine
- *   figures something is wrong, and steals the lock. It does not set
- *   any other CPU to "dead".
- */
-inline void
-primary_lock(nasid_t nasid)
-{
-	rtc_time_t          expire;
-
-	expire = rtc_time() + PRIMARY_LOCK_TIMEOUT;
-
-	while (HUB_TEST_AND_SET(nasid)) {
-		if (rtc_time() > expire) {
-			HUB_CLEAR(nasid);
-		}
-	}
-}
-
-/*
- * primary_unlock (internal)
- *
- *   Counterpart to primary_lock
- */
-
-inline void
-primary_unlock(nasid_t nasid)
-{
-	HUB_CLEAR(nasid);
-}
-
-/*
- * hub_unlock
- *
- *   Counterpart to hub_lock_timeout and hub_lock
- */
-
-inline void
-hub_unlock(nasid_t nasid, int level)
-{
-	uint64_t mask = 1ULL << level;
-
-	primary_lock(nasid);
-	CLR_BITS(HUB_LOCK_REG(nasid), mask);
-	primary_unlock(nasid);
-}
-
-/*
- * hub_lock_timeout
- *
- *   Uses primary_lock to implement multiple lock levels.
- *
- *   There are 20 lock levels from 0 to 19 (limited by the number of bits
- *   in HUB_LOCK_REG).  To prevent deadlock, multiple locks should be
- *   obtained in order of increasingly higher level, and released in the
- *   reverse order.
- *
- *   A timeout value of 0 may be used for no timeout.
- *
- *   Returns 0 if successful, -1 if lock times out.
- */
-
-inline int
-hub_lock_timeout(nasid_t nasid, int level, rtc_time_t timeout)
-{
-	uint64_t mask = 1ULL << level;
-	rtc_time_t expire = (timeout ?  rtc_time() + timeout : RTC_TIME_MAX);
-	int done    = 0;
-
-	while (! done) {
-		while (TST_BITS(HUB_LOCK_REG(nasid), mask)) {
-			if (rtc_time() > expire)
-				return -1;
-		}
-
-		primary_lock(nasid);
-
-		if (! TST_BITS(HUB_LOCK_REG(nasid), mask)) {
-			SET_BITS(HUB_LOCK_REG(nasid), mask);
-			done = 1;
-		}
-		primary_unlock(nasid);
-	}
-	return 0;
-}
-
-
-#define LOCK_TIMEOUT	(0x1500000 * 1) /* 0x1500000 is ~30 sec */
-
-void
-lock_console(nasid_t nasid)
-{
-	int ret;
-
-	/* If we already have it locked, just return */
-	L1_collectibles[L1C_LOCK_COUNTER]++;
-
-	ret = hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
-	if ( ret != 0 ) {
-		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
-		/* timeout */
-		hub_unlock(nasid, HUB_LOCK);
-		/* If the 2nd lock fails, just pile ahead.... */
-		hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
-		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
-	}
-}
-
-inline void
-unlock_console(nasid_t nasid)
-{
-	L1_collectibles[L1C_UNLOCK_COUNTER]++;
-	hub_unlock(nasid, HUB_LOCK);
-}
-
-
-int 
-get_L1_baud(void)
-{
-    return UART_BAUD_RATE;
-}
-
-
-/* uart driver functions */
-
-static inline void
-uart_delay( rtc_time_t delay_span )
-{
-    UART_DELAY( delay_span );
-}
-
-#define UART_PUTC_READY(n)      (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE)
-
-static int
-uart_putc( l1sc_t *sc ) 
-{
-    WRITE_L1_UART_REG( sc->nasid, REG_DAT, sc->send[sc->sent] );
-    return UART_SUCCESS;
-}
-
-
-static int
-uart_getc( l1sc_t *sc )
-{
-    u_char lsr_reg = 0;
-    nasid_t nasid = sc->nasid;
-
-    if( (lsr_reg = READ_L1_UART_REG( nasid, REG_LSR )) & 
-	(LSR_RCA | LSR_PARERR | LSR_FRMERR) ) 
-    {
-	if( lsr_reg & LSR_RCA ) 
-	    return( (u_char)READ_L1_UART_REG( nasid, REG_DAT ) );
-	else if( lsr_reg & (LSR_PARERR | LSR_FRMERR) ) {
-	    return UART_LINK;
-	}
-    }
-    return UART_NO_CHAR;
-}
-
-
-#define PROM_SER_CLK_SPEED	12000000
-#define PROM_SER_DIVISOR(x)	(PROM_SER_CLK_SPEED / ((x) * 16))
-
-static void
-uart_init( l1sc_t *sc, int baud )
-{
-#if !defined(USE_SAL_CONSOLE_IO)
-    rtc_time_t expire;
-    int clkdiv;
-    nasid_t nasid;
-
-    clkdiv = PROM_SER_DIVISOR(baud);
-    expire = rtc_time() + UART_INIT_TIMEOUT;
-    nasid = sc->nasid;
-    
-    /* make sure the transmit FIFO is empty */
-    while( !(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XSRE) ) {
-	uart_delay( UART_DELAY_SPAN );
-	if( rtc_time() > expire ) {
-	    break;
-	}
-    }
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* Setup for the proper baud rate */
-    WRITE_L1_UART_REG( nasid, REG_LCR, LCR_DLAB );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_DLH, (clkdiv >> 8) & 0xff );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_DLL, clkdiv & 0xff );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* set operating parameters and set DLAB to 0 */
-
-    /* 8bit, one stop, clear request to send, auto flow control */
-    WRITE_L1_UART_REG( nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_MCR, MCR_RTS | MCR_AFE );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* disable interrupts */
-    WRITE_L1_UART_REG( nasid, REG_ICR, 0x0 );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* enable FIFO mode and reset both FIFOs, trigger on 1 */
-    WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO | RxLVL0);
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-#endif	/* !USE_SAL_CONSOLE_IO */
-}
-
-/* This requires the console lock */
-
-
-static void
-uart_intr_enable( l1sc_t *sc, u_char mask )
-{
-    u_char lcr_reg, icr_reg;
-    nasid_t nasid = sc->nasid;
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* make sure that the DLAB bit in the LCR register is 0
-     */
-    lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
-    lcr_reg &= ~(LCR_DLAB);
-    WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg );
-
-    /* enable indicated interrupts
-     */
-    icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
-    icr_reg |= mask;
-    WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-
-/* This requires the console lock */
-static void
-uart_intr_disable( l1sc_t *sc, u_char mask )
-{
-    u_char lcr_reg, icr_reg;
-    nasid_t nasid = sc->nasid;
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* make sure that the DLAB bit in the LCR register is 0
-     */
-    lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
-    lcr_reg &= ~(LCR_DLAB);
-    WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg );
-
-    /* enable indicated interrupts
-     */
-    icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
-    icr_reg &= mask;
-    WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-
-#define uart_enable_xmit_intr(sc) \
-	uart_intr_enable((sc), ICR_TIEN)
-
-#define uart_disable_xmit_intr(sc) \
-        uart_intr_disable((sc), ~(ICR_TIEN))
-
-#define uart_enable_recv_intr(sc) \
-        uart_intr_enable((sc), ICR_RIEN)
-
-#define uart_disable_recv_intr(sc) \
-        uart_intr_disable((sc), ~(ICR_RIEN))
-
-
-/*********************************************************************
- * Routines for accessing a remote (router) UART
- */
-
-#define READ_RTR_L1_UART_REG(p, n, r, v)		\
-    {							\
-	if( vector_read_node( (p), (n), 0,		\
-			      RR_JBUS1(r), (v) ) ) {	\
-	    return UART_VECTOR;				\
-	}						\
-    }
-
-#define WRITE_RTR_L1_UART_REG(p, n, r, v)		\
-    {							\
-	if( vector_write_node( (p), (n), 0,		\
-			       RR_JBUS1(r), (v) ) ) {	\
-	    return UART_VECTOR;				\
-	}						\
-    }
-
-#define RTR_UART_PUTC_TIMEOUT	UART_PUTC_TIMEOUT*10
-#define RTR_UART_DELAY_SPAN	UART_DELAY_SPAN
-#define RTR_UART_INIT_TIMEOUT	UART_INIT_TIMEOUT*10
-
-static int
-rtr_uart_putc( l1sc_t *sc )
-{
-    uint64_t regval, c;
-    nasid_t nasid = sc->nasid;
-    net_vec_t path = sc->uart;
-    rtc_time_t expire = rtc_time() + RTR_UART_PUTC_TIMEOUT;
-
-    c = (sc->send[sc->sent] & 0xffULL);
-    
-    while( 1 ) 
-    {
-        /* Check for "tx hold reg empty" bit. */
-	READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-	if( regval & LSR_XHRE )
-	{
-	    WRITE_RTR_L1_UART_REG( path, nasid, REG_DAT, c );
-	    return UART_SUCCESS;
-	}
-
-	if( rtc_time() >= expire ) 
-	{
-	    return UART_TIMEOUT;
-	}
-	uart_delay( RTR_UART_DELAY_SPAN );
-    }
-}
-
-
-static int
-rtr_uart_getc( l1sc_t *sc )
-{
-    uint64_t regval;
-    nasid_t nasid = sc->nasid;
-    net_vec_t path = sc->uart;
-
-    READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-    if( regval & (LSR_RCA | LSR_PARERR | LSR_FRMERR) )
-    {
-	if( regval & LSR_RCA )
-	{
-	    READ_RTR_L1_UART_REG( path, nasid, REG_DAT, &regval );
-	    return( (int)regval );
-	}
-	else
-	{
-	    return UART_LINK;
-	}
-    }
-
-    return UART_NO_CHAR;
-}
-
-
-static int
-rtr_uart_init( l1sc_t *sc, int baud )
-{
-    rtc_time_t expire;
-    int clkdiv;
-    nasid_t nasid;
-    net_vec_t path;
-    uint64_t regval;
-
-    clkdiv = PROM_SER_DIVISOR(baud);
-    expire = rtc_time() + RTR_UART_INIT_TIMEOUT;
-    nasid = sc->nasid;
-    path = sc->uart;
-
-    /* make sure the transmit FIFO is empty */
-    while(1) {
-	READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-	if( regval & LSR_XSRE ) {
-	    break;
-	}
-	if( rtc_time() > expire ) {
-	    break;
-	}
-	uart_delay( RTR_UART_DELAY_SPAN );
-    }
-
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_DLAB  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_DLH, (clkdiv >> 8) & 0xff  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_DLL, clkdiv & 0xff  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* set operating parameters and set DLAB to 0 */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_BITS8 | LCR_STOP1  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_MCR, MCR_RTS | MCR_AFE  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* disable interrupts */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_ICR, 0x0  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* enable FIFO mode and reset both FIFOs */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR, FCR_FIFOEN  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR,
-	FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO );
-
-    return 0;
-}
-
-/*********************************************************************
- * locking macros 
- */
-
-#define L1SC_SEND_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->send_lock),p); }
-#define L1SC_SEND_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->send_lock), p); }
-#define L1SC_RECV_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->recv_lock), p); } 
-#define L1SC_RECV_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->recv_lock), p); }
-
-
-/*********************************************************************
- * subchannel manipulation 
- *
- * The SUBCH_[UN]LOCK macros are used to arbitrate subchannel
- * allocation.  SUBCH_DATA_[UN]LOCK control access to data structures
- * associated with particular subchannels (e.g., receive queues).
- *
- */
-#define SUBCH_LOCK(sc, p)		spin_lock_irqsave( &((sc)->subch_lock), p )
-#define SUBCH_UNLOCK(sc, p)		spin_unlock_irqrestore( &((sc)->subch_lock), p )
-#define SUBCH_DATA_LOCK(sbch, p) 	spin_lock_irqsave( &((sbch)->data_lock), p )
-#define SUBCH_DATA_UNLOCK(sbch, p)	spin_unlock_irqrestore( &((sbch)->data_lock), p )
-
-
-/*
- * set a function to be called for subchannel ch in the event of
- * a transmission low-water interrupt from the uart
- */
-void
-subch_set_tx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-    unsigned long pl = 0;
-
-    L1SC_SEND_LOCK( sc, pl );
-#if	!defined(SYNC_CONSOLE_WRITE)
-    if ( func && !sc->send_in_use )
-	uart_enable_xmit_intr( sc );
-#endif
-    sc->subch[ch].tx_notify = func;
-    L1SC_SEND_UNLOCK(sc, pl );
-}
-
-/*
- * set a function to be called for subchannel ch when data is received
- */
-void
-subch_set_rx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    SUBCH_DATA_LOCK( subch, pl );
-    sc->subch[ch].rx_notify = func;
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-/*********************************************************************
- * Queue manipulation macros
- *
- *
- */
-#define NEXT(p)         (((p) + 1) & (BRL1_QSIZE-1)) /* assume power of 2 */
-
-#define cq_init(q)      bzero((q), sizeof (*(q)))
-#define cq_empty(q)     ((q)->ipos == (q)->opos)
-#define cq_full(q)      (NEXT((q)->ipos) == (q)->opos)
-#define cq_used(q)      ((q)->opos <= (q)->ipos ?                       \
-                         (q)->ipos - (q)->opos :                        \
-                         BRL1_QSIZE + (q)->ipos - (q)->opos)
-#define cq_room(q)      ((q)->opos <= (q)->ipos ?                       \
-                         BRL1_QSIZE - 1 + (q)->opos - (q)->ipos :       \
-                         (q)->opos - (q)->ipos - 1)
-#define cq_add(q, c)    ((q)->buf[(q)->ipos] = (u_char) (c),            \
-                         (q)->ipos = NEXT((q)->ipos))
-#define cq_rem(q, c)    ((c) = (q)->buf[(q)->opos],                     \
-                         (q)->opos = NEXT((q)->opos))
-#define cq_discard(q)	((q)->opos = NEXT((q)->opos))
-
-#define cq_tent_full(q)	(NEXT((q)->tent_next) == (q)->opos)
-#define cq_tent_len(q)	((q)->ipos <= (q)->tent_next ?			\
-			 (q)->tent_next - (q)->ipos :			\
-			 BRL1_QSIZE + (q)->tent_next - (q)->ipos)
-#define cq_tent_add(q, c)						\
-			((q)->buf[(q)->tent_next] = (u_char) (c),	\
-			 (q)->tent_next = NEXT((q)->tent_next))
-#define cq_commit_tent(q)						\
-			((q)->ipos = (q)->tent_next)
-#define cq_discard_tent(q)						\
-			((q)->tent_next = (q)->ipos)
-
-
-
-
-/*********************************************************************
- * CRC-16 (for checking bedrock/L1 packets).
- *
- * These are based on RFC 1662 ("PPP in HDLC-like framing").
- */
-
-static unsigned short fcstab[256] = {
-      0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
-      0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
-      0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
-      0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
-      0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
-      0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
-      0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
-      0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
-      0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
-      0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
-      0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
-      0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
-      0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
-      0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
-      0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
-      0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
-      0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
-      0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
-      0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
-      0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
-      0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
-      0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
-      0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
-      0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
-      0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
-      0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
-      0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
-      0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
-      0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
-      0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
-      0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
-      0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
-};
-
-#define INIT_CRC	0xFFFF	/* initial CRC value	  */
-#define	GOOD_CRC	0xF0B8	/* "good" final CRC value */
-
-static unsigned short crc16_calc( unsigned short crc, u_char c )
-{
-    return( (crc >> 8) ^ fcstab[(crc ^ c) & 0xff] );
-}
-
-
-/***********************************************************************
- * The following functions implement the PPP-like bedrock/L1 protocol
- * layer.
- *
- */
-
-#define BRL1_FLAG_CH	0x7e
-#define BRL1_ESC_CH	0x7d
-#define BRL1_XOR_CH	0x20
-
-/* L1<->Bedrock packet types */
-#define BRL1_REQUEST    0x00
-#define BRL1_RESPONSE   0x20
-#define BRL1_EVENT      0x40
-
-#define BRL1_PKT_TYPE_MASK      0xE0
-#define BRL1_SUBCH_MASK         0x1F
-
-#define PKT_TYPE(tsb)   ((tsb) & BRL1_PKT_TYPE_MASK)
-#define SUBCH(tsb)	((tsb) & BRL1_SUBCH_MASK)
-
-/* timeouts */
-#define BRL1_INIT_TIMEOUT	500000
-
-/*
- * brl1_discard_packet is a dummy "receive callback" used to get rid
- * of packets we don't want
- */
-void brl1_discard_packet( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &sc->subch[ch];
-
-    sc_cq_t *q = subch->iqp;
-    SUBCH_DATA_LOCK( subch, pl );
-    q->opos = q->ipos;
-    atomic_set(&(subch->packet_arrived), 0);
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-
-/*
- * brl1_send_chars sends the send buffer in the l1sc_t structure
- * out through the uart.  Assumes that the caller has locked the
- * UART (or send buffer in the kernel).
- *
- * This routine doesn't block-- if you want it to, call it in
- * a loop.
- */
-static int
-brl1_send_chars( l1sc_t *sc )
-{
-    /* We track the depth of the C brick's UART's
-     * fifo in software, and only check if the UART is accepting
-     * characters when our count indicates that the fifo should
-     * be full.
-     *
-     * For remote (router) UARTs, we check with the UART before sending every
-     * character.
-     */
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	if( !(sc->fifo_space) && UART_PUTC_READY( sc->nasid ) )
-	    sc->fifo_space = UART_FIFO_DEPTH;
-	
-	while( (sc->sent < sc->send_len) && (sc->fifo_space) ) {
-	    uart_putc( sc );
-	    sc->fifo_space--;
-	    sc->sent++;
-	}
-    }
-    else {
-
-	/* remote (router) UARTs */
-
-	int result;
-	int tries = 0;
-
-	while( sc->sent < sc->send_len ) {
-	    result = sc->putc_f( sc );
-	    if( result >= 0 ) {
-		(sc->sent)++;
-		continue;
-	    }
-	    if( result == UART_TIMEOUT ) {
-		tries++;
-		/* send this character in TIMEOUT_RETRIES... */
-		if( tries < 30 /* TIMEOUT_RETRIES */ ) {
-		    continue;
-		}
-		/* ...or else... */
-		else {
-		    /* ...drop the packet. */
-		    sc->sent = sc->send_len;
-		    return sc->send_len;
-		}
-	    }
-	    if( result < 0 ) {
-		return result;
-	    }
-	}
-    }
-    return sc->sent;
-}
-
-
-/* brl1_send formats up a packet and (at least begins to) send it
- * to the uart.  If the send buffer is in use when this routine obtains
- * the lock, it will behave differently depending on the "wait" parameter.
- * For wait == 0 (most I/O), it will return 0 (as in "zero bytes sent"),
- * hopefully encouraging the caller to back off (unlock any high-level 
- * spinlocks) and allow the buffer some time to drain.  For wait==1 (high-
- * priority I/O along the lines of kernel error messages), we will flush
- * the current contents of the send buffer and beat on the uart
- * until our message has been completely transmitted.
- */
-
-static int
-brl1_send( l1sc_t *sc, char *msg, int len, u_char type_and_subch, int wait )
-{
-    unsigned long pl = 0;
-    int index;
-    int pkt_len = 0;
-    unsigned short crc = INIT_CRC;
-    char *send_ptr = sc->send;
-
-
-    if( sc->send_in_use && !(wait) ) {
-	/* We are in the middle of sending, but can wait until done */
-	return 0;
-    }
-    else if( sc->send_in_use ) {
-	/* buffer's in use, but we're synchronous I/O, so we're going
-	 * to send whatever's in there right now and take the buffer
-	 */
-	int counter = 0;
-
-	if ( sc->uart == BRL1_LOCALHUB_UART )
-		lock_console(sc->nasid);
-	L1SC_SEND_LOCK(sc, pl);
-	while( sc->sent < sc->send_len ) {
-		brl1_send_chars( sc );
-		if ( counter++ > 0xfffff ) {
-			char *str = "Looping waiting for uart to clear (1)\n";
-			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
-			break;
-		}
-	}
-    }
-    else {
-	if ( sc->uart == BRL1_LOCALHUB_UART )
-		lock_console(sc->nasid);
-	L1SC_SEND_LOCK(sc, pl);
-	sc->send_in_use = 1;
-    }
-    *send_ptr++ = BRL1_FLAG_CH;
-    *send_ptr++ = type_and_subch;
-    pkt_len += 2;
-    crc = crc16_calc( crc, type_and_subch );
-
-    /* limit number of characters accepted to max payload size */
-    if( len > (BRL1_QSIZE - 1) )
-	len = (BRL1_QSIZE - 1);
-
-    /* copy in the message buffer (inserting PPP 
-     * framing info where necessary)
-     */
-    for( index = 0; index < len; index++ ) {
-
-	switch( *msg ) {
-	    
-	  case BRL1_FLAG_CH:
-	    *send_ptr++ = BRL1_ESC_CH;
-	    *send_ptr++ = (*msg) ^ BRL1_XOR_CH;
-	    pkt_len += 2;
-	    break;
-	    
-	  case BRL1_ESC_CH:
-	    *send_ptr++ = BRL1_ESC_CH;
-	    *send_ptr++ = (*msg) ^ BRL1_XOR_CH;
-	    pkt_len += 2;
-	    break;
-	    
-	  default:
-	    *send_ptr++ = *msg;
-	    pkt_len++;
-	}
-	crc = crc16_calc( crc, *msg );
-	msg++;
-    }
-    crc ^= 0xffff;
-
-    for( index = 0; index < sizeof(crc); index++ ) {
-	char crc_char = (char)(crc & 0x00FF);
-	if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	    *send_ptr++ = BRL1_ESC_CH;
-	    pkt_len++;
-	    crc_char ^= BRL1_XOR_CH;
-	}
-	*send_ptr++ = crc_char;
-	pkt_len++;
-	crc >>= 8;
-    }
-    
-    *send_ptr++ = BRL1_FLAG_CH;
-    pkt_len++;
-
-    sc->send_len = pkt_len;
-    sc->sent = 0;
-
-    {
-	int counter = 0;
-	do {
-		brl1_send_chars( sc );
-		if ( counter++ > 0xfffff ) {
-			char *str = "Looping waiting for uart to clear (2)\n";
-			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
-			break;
-		}
-	} while( (sc->sent < sc->send_len) && wait );
-    }
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(sc->nasid);
-
-    if( sc->sent == sc->send_len ) {
-	/* success! release the send buffer and call the callup */
-#if	!defined(SYNC_CONSOLE_WRITE)
-	brl1_notif_t callup;
-#endif
-
-	sc->send_in_use = 0;
-	/* call any upper layer that's asked for notification */
-#if	defined(XX_SYNC_CONSOLE_WRITE)
-	/*
-	 * This is probably not a good idea - since the l1_ write func can be called multiple
-	 * time within the callup function.
-	 */
-	callup = subch->tx_notify;
-	if( callup && (SUBCH(type_and_subch) == SC_CONS_SYSTEM) ) {
-		L1_collectibles[L1C_SEND_CALLUPS]++;
-		(*callup)(sc->subch[SUBCH(type_and_subch)].irq_frame.bf_irq,
-				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_dev_id,
-				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_regs, sc, SUBCH(type_and_subch));
-	}
-#endif	/* SYNC_CONSOLE_WRITE */
-    }
-#if	!defined(SYNC_CONSOLE_WRITE)
-    else if ( !wait ) {
-	/* enable low-water interrupts so buffer will be drained */
-	uart_enable_xmit_intr(sc);
-    }
-#endif
-
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    return len;
-}
-
-/* brl1_send_cont is intended to be called as an interrupt service
- * routine.  It sends until the UART won't accept any more characters,
- * or until an error is encountered (in which case we surrender the
- * send buffer and give up trying to send the packet).  Once the
- * last character in the packet has been sent, this routine releases
- * the send buffer and calls any previously-registered "low-water"
- * output routines.
- */
-
-#if	!defined(SYNC_CONSOLE_WRITE)
-
-int
-brl1_send_cont( l1sc_t *sc )
-{
-    unsigned long pl = 0;
-    int done = 0;
-    brl1_notif_t callups[BRL1_NUM_SUBCHANS];
-    brl1_notif_t *callup;
-    brl1_sch_t *subch;
-    int index;
-
-    /*
-     * I'm not sure how I think this is to be handled - whether the lock is held
-     * over the interrupt - but it seems like it is a bad idea....
-     */
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(sc->nasid);
-    L1SC_SEND_LOCK(sc, pl);
-    brl1_send_chars( sc );
-    done = (sc->sent == sc->send_len);
-    if( done ) {
-	sc->send_in_use = 0;
-#if	!defined(SYNC_CONSOLE_WRITE)
-	uart_disable_xmit_intr(sc);
-#endif
-    }
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(sc->nasid);
-    /* Release the lock */
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    return 0;
-}
-#endif	/* SYNC_CONSOLE_WRITE */
-
-/* internal function -- used by brl1_receive to read a character 
- * from the uart and check whether errors occurred in the process.
- */
-static int
-read_uart( l1sc_t *sc, int *c, int *result )
-{
-    *c = sc->getc_f( sc );
-
-    /* no character is available */
-    if( *c == UART_NO_CHAR ) {
-	*result = BRL1_NO_MESSAGE;
-	return 0;
-    }
-
-    /* some error in UART */
-    if( *c < 0 ) {
-	*result = BRL1_LINK;
-	return 0;
-    }
-
-    /* everything's fine */
-    *result = BRL1_VALID;
-    return 1;
-}
-
-
-/*
- * brl1_receive
- *
- * This function reads a Bedrock-L1 protocol packet into the l1sc_t
- * response buffer.
- *
- * The operation of this function can be expressed as a finite state
- * machine:
- *
-
-START STATE			INPUT		TRANSITION
-==========================================================
-BRL1_IDLE (reset or error)	flag		BRL1_FLAG
-				other		BRL1_IDLE@
-
-BRL1_FLAG (saw a flag (0x7e))	flag		BRL1_FLAG
-				escape		BRL1_IDLE@
-				header byte	BRL1_HDR
-				other		BRL1_IDLE@
-
-BRL1_HDR (saw a type/subch byte)(see below)	BRL1_BODY
-						BRL1_HDR
-
-BRL1_BODY (reading packet body)	flag		BRL1_FLAG
-				escape		BRL1_ESC
-				other		BRL1_BODY
-
-BRL1_ESC (saw an escape (0x7d))	flag		BRL1_FLAG@
-				escape		BRL1_IDLE@
-				other		BRL1_BODY
-==========================================================
-
-"@" denotes an error transition.
-
- * The BRL1_HDR state is a transient state which doesn't read input,
- * but just provides a way in to code which decides to whom an
- * incoming packet should be directed.
- *
- * brl1_receive can be used to poll for input from the L1, or as 
- * an interrupt service routine.  It reads as much data as is
- * ready from the junk bus UART and places into the appropriate
- * input queues according to subchannel.  The header byte is
- * stripped from console-type data, but is retained for message-
- * type data (L1 responses).  A length byte will also be
- * prepended to message-type packets.
- *
- * This routine is non-blocking; if the caller needs to block
- * for input, it must call brl1_receive in a loop.
- *
- * brl1_receive returns when there is no more input, the queue
- * for the current incoming message is full, or there is an
- * error (parity error, bad header, bad CRC, etc.).
- */
-
-#define STATE_SET(l,s)		((l)->brl1_state = (s))
-#define STATE_GET(l)		((l)->brl1_state)
-
-#define LAST_HDR_SET(l,h)	((l)->brl1_last_hdr = (h))
-#define LAST_HDR_GET(l)		((l)->brl1_last_hdr)
-
-#define VALID_HDR(c)				\
-    ( SUBCH((c)) <= SC_CONS_SYSTEM		\
-	? PKT_TYPE((c)) == BRL1_REQUEST		\
-	: ( PKT_TYPE((c)) == BRL1_RESPONSE ||	\
-	    PKT_TYPE((c)) == BRL1_EVENT ) )
-
-#define IS_TTY_PKT(l)		( SUBCH(LAST_HDR_GET(l)) <= SC_CONS_SYSTEM ? 1 : 0 )
-
-
-int
-brl1_receive( l1sc_t *sc, int mode )
-{
-    int result;		/* value to be returned by brl1_receive */
-    int c;		/* most-recently-read character	     	*/
-    int done;		/* set done to break out of recv loop	*/
-    unsigned long pl = 0, cpl = 0;
-    sc_cq_t *q;		/* pointer to queue we're working with	*/
-
-    result = BRL1_NO_MESSAGE;
-
-    L1SC_RECV_LOCK(sc, cpl);
-
-    done = 0;
-    while( !done )
-    {
-	switch( STATE_GET(sc) )
-	{
-
-	  case BRL1_IDLE:
-	    /* Initial or error state.  Waiting for a flag character
-             * to resynchronize with the L1.
-             */
-
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* saw a flag character */
-		STATE_SET( sc, BRL1_FLAG );
-		continue;
-	    }
-	    break;
-	    
-	  case BRL1_FLAG:
-	    /* One or more flag characters have been read; look for
-	     * the beginning of a packet (header byte).
-	     */
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR )
-		    STATE_SET( sc, BRL1_IDLE );
-
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* multiple flags are OK */
-		continue;
-	    }
-
-	    if( !VALID_HDR( c ) ) {
-		/* if c isn't a flag it should have been
-		 * a valid header, so we have an error
-		 */
-		result = BRL1_PROTOCOL;
-		STATE_SET( sc, BRL1_IDLE );
-		done = 1;
-		continue;
-	    }
-
-	    /* we have a valid header byte */
-	    LAST_HDR_SET( sc, c );
-	    STATE_SET( sc, BRL1_HDR );
-
-	    break; 
-
-	  case BRL1_HDR:
-	    /* A header byte has been read. Do some bookkeeping. */
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-	    
-	    if( !IS_TTY_PKT(sc) ) {
-		/* if this is an event or command response rather
-		 * than console I/O, we need to reserve a couple
-		 * of extra spaces in the queue for the header
-		 * byte and a length byte; if we can't, stay in
-		 * the BRL1_HDR state.
-		 */
-		if( cq_room( q ) < 2 ) {
-		    result = BRL1_FULL_Q;
-		    done = 1;
-		    continue;
-		}
-		cq_tent_add( q, 0 );			/* reserve length byte */
-		cq_tent_add( q, LAST_HDR_GET( sc ) );	/* record header byte  */
-	    }
-	    STATE_SET( sc, BRL1_BODY );
-
-	    break;
-
-	  case BRL1_BODY:
-	    /* A header byte has been read.  We are now attempting
-	     * to receive the packet body.
-	     */
-
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-
-	    /* if the queue we want to write into is full, don't read from
-	     * the uart (this provides backpressure to the L1 side)
-	     */
-	    if( cq_tent_full( q ) ) {
-		result = BRL1_FULL_Q;
-		done = 1;
-		continue;
-	    }
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR )
-		    STATE_SET( sc, BRL1_IDLE );
-		done = 1;
-		continue;
-	    }
-
-	    if( c == BRL1_ESC_CH ) {
-		/* prepare to unescape the next character */
-		STATE_SET( sc, BRL1_ESC );
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* flag signifies the end of a packet */
-
-		unsigned short crc;	/* holds the crc as we calculate it */
-		int i;			/* index variable */
-		brl1_sch_t *subch;      /* subchannel for received packet */
-		brl1_notif_t callup;	/* "data ready" callup */
-
-		/* whatever else may happen, we've seen a flag and we're
-		 * starting a new packet
-		 */
-		STATE_SET( sc, BRL1_FLAG );
-
-		/* if the packet body has less than 2 characters,
-		 * it can't be a well-formed packet.  Discard it.
-		 */
-		if( cq_tent_len( q ) < /* 2 + possible length byte */
-		    (2 + (IS_TTY_PKT(sc) ? 0 : 1)) )
-		{
-		    result = BRL1_PROTOCOL;
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_FLAG );
-		    done = 1;
-		    continue;
-		}
-		
-		/* check CRC */
-
-		/* accumulate CRC, starting with the header byte and
-		 * ending with the transmitted CRC.  This should
-		 * result in a known good value.
-		 */
-		crc = crc16_calc( INIT_CRC, LAST_HDR_GET(sc) );
-		for( i = (q->ipos + (IS_TTY_PKT(sc) ? 0 : 2)) % BRL1_QSIZE;
-		     i != q->tent_next;
-		     i = (i + 1) % BRL1_QSIZE )
-		{
-		    crc = crc16_calc( crc, q->buf[i] );
-		}
-
-		/* verify the caclulated crc against the "good" crc value;
-		 * if we fail, discard the bad packet and return an error.
-		 */
-		if( crc != (unsigned short)GOOD_CRC ) {
-		    result = BRL1_CRC;
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_FLAG );
-		    done = 1;
-		    continue;
-		}
-		
-		/* so the crc check was ok.  Now we discard the CRC
-		 * from the end of the received bytes.
-		 */
-		q->tent_next += (BRL1_QSIZE - 2);
-		q->tent_next %= BRL1_QSIZE;
-
-		/* get the subchannel and lock it */
-		subch = &(sc->subch[SUBCH( LAST_HDR_GET(sc) )]);
-		SUBCH_DATA_LOCK( subch, pl );
-		
-		/* if this isn't a console packet, we need to record
-		 * a length byte
-		 */
-		if( !IS_TTY_PKT(sc) ) {
-		    q->buf[q->ipos] = cq_tent_len( q ) - 1;
-		}
-		
-		/* record packet for posterity */
-		cq_commit_tent( q );
-		result = BRL1_VALID;
-
-		/* notify subchannel owner that there's something
-		 * on the queue for them
-		 */
-		atomic_inc(&(subch->packet_arrived));
-		callup = subch->rx_notify;
-		SUBCH_DATA_UNLOCK( subch, pl );
-
-		if( callup && (mode == SERIAL_INTERRUPT_MODE) ) {
-		    L1SC_RECV_UNLOCK( sc, cpl );
-		    L1_collectibles[L1C_RECEIVE_CALLUPS]++;
-		    (*callup)( sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_irq,
-				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_dev_id,
-				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_regs,
-				sc, SUBCH(LAST_HDR_GET(sc)) );
-		    L1SC_RECV_LOCK( sc, cpl );
-		}
-		continue;	/* go back for more! */
-	    }
-	    
-	    /* none of the special cases applied; we've got a normal
-	     * body character
-	     */
-	    cq_tent_add( q, c );
-
-	    break;
-
-	  case BRL1_ESC:
-	    /* saw an escape character.  The next character will need
-	     * to be unescaped.
-	     */
-
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-
-	    /* if the queue we want to write into is full, don't read from
-	     * the uart (this provides backpressure to the L1 side)
-	     */
-	    if( cq_tent_full( q ) ) {
-		result = BRL1_FULL_Q;
-		done = 1;
-		continue;
-	    }
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR ) {
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_IDLE );
-		}
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* flag after escape is an error */
-		STATE_SET( sc, BRL1_FLAG );
-		cq_discard_tent( q );
-		result = BRL1_PROTOCOL;
-		done = 1;
-		continue;
-	    }
-
-	    if( c == BRL1_ESC_CH ) {
-		/* two consecutive escapes is an error */
-		STATE_SET( sc, BRL1_IDLE );
-		cq_discard_tent( q );
-		result = BRL1_PROTOCOL;
-		done = 1;
-		continue;
-	    }
-	    
-	    /* otherwise, we've got a character that needs
-	     * to be unescaped
-	     */
-	    cq_tent_add( q, (c ^ BRL1_XOR_CH) );
-	    STATE_SET( sc, BRL1_BODY );
-
-	    break;
-
-	} /* end of switch( STATE_GET(sc) ) */
-    } /* end of while(!done) */
-
-    L1SC_RECV_UNLOCK( sc, cpl );
-
-    return result;
-}	    
-
-
-/* brl1_init initializes the Bedrock/L1 protocol layer.  This includes
- * zeroing out the send and receive state information.
- */
-
-void
-brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    int i;
-    brl1_sch_t *subch;
-
-    bzero( sc, sizeof( *sc ) );
-    sc->nasid = nasid;
-    sc->uart = uart;
-    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
-    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
-    sc->sol = 1;
-    subch = sc->subch;
-
-    /* initialize L1 subchannels
-     */
-
-    /* assign processor TTY channels */
-    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	spin_lock_init( &(subch->data_lock) );
-	sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
-	subch->tx_notify = NULL;
-	/* (for now, drop elscuart packets in the kernel) */
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* assign system TTY channel (first free subchannel after each
-     * processor's individual TTY channel has been assigned)
-     */
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = ATOMIC_INIT(0);
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &subch->data_lock, SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
-    subch->tx_notify = NULL;
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, NASID_TO_COMPACT_NODEID(nasid) );
-	ASSERT( subch->iqp );
-	cq_init( subch->iqp );
-	subch->rx_notify = NULL;
-    }
-    else {
-	/* we shouldn't be getting console input from remote UARTs */
-	subch->iqp = &sc->garbage_q;
-	subch->rx_notify = brl1_discard_packet;
-    }
-    subch++; i++;
-
-    /* "reserved" subchannels (0x05-0x0F); for now, throw away
-     * incoming packets
-     */
-    for( ; i < 0x10; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* remaining subchannels are free */
-    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* initialize synchronization structures
-     */
-    spin_lock_init( &(sc->subch_lock) );
-    spin_lock_init( &(sc->send_lock) );
-    spin_lock_init( &(sc->recv_lock) );
-
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	uart_init( sc, UART_BAUD_RATE );
-    }
-    else {
-	rtr_uart_init( sc, UART_BAUD_RATE );
-    }
-
-    /* Set up remaining fields using L1 command functions-- elsc_module_get
-     * to read the module id, elsc_debug_get to see whether or not we're
-     * in verbose mode.
-     */
-    {
-	extern int elsc_module_get(l1sc_t *);
-
-	sc->modid = elsc_module_get( sc );
-	sc->modid = (sc->modid < 0 ? INVALID_MODULE : sc->modid);
-	sc->verbose = 1;
-    }
-}
-
-/*********************************************************************
- * These are interrupt-related functions used in the kernel to service
- * the L1.
- */
-
-/*
- * brl1_intrd is the function which is called on a console interrupt.
- */
-
-
-static void
-brl1_intrd(int irq, void *dev_id, struct pt_regs *stuff)
-{
-    u_char isr_reg;
-    l1sc_t *sc = get_elsc();
-    int ret;
-
-    L1_collectibles[L1C_INTERRUPTS]++;
-    isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-
-    /* Save for callup args in console */
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_irq = irq;
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_dev_id = dev_id;
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_regs = stuff;
-
-#if	defined(SYNC_CONSOLE_WRITE)
-    while( isr_reg & ISR_RxRDY )
-#else
-    while( isr_reg & (ISR_RxRDY | ISR_TxRDY) )
-#endif
-    {
-	if( isr_reg & ISR_RxRDY ) {
-	    L1_collectibles[L1C_OUR_R_INTERRUPTS]++;
-	    ret = brl1_receive(sc, SERIAL_INTERRUPT_MODE);
-	    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
-		L1_collectibles[L1C_REC_STALLS] = ret;
-	}
-#if	!defined(SYNC_CONSOLE_WRITE)
-	if( (isr_reg & ISR_TxRDY) || (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) {
-	    L1_collectibles[L1C_OUR_X_INTERRUPTS]++;
-	    brl1_send_cont(sc);
-	}
-#endif	/* SYNC_CONSOLE_WRITE */
-	isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-    }
-}
-
-
-/*
- * Install a callback function for the system console subchannel 
- * to allow an upper layer to be notified when the send buffer 
- * has been emptied.
- */
-static inline void
-l1_tx_notif( brl1_notif_t func )
-{
-	subch_set_tx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
-			SC_CONS_SYSTEM, func );
-}
-
-
-/*
- * Install a callback function for the system console subchannel
- * to allow an upper layer to be notified when a packet has been
- * received.
- */
-static inline void
-l1_rx_notif( brl1_notif_t func )
-{
-	subch_set_rx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
-				SC_CONS_SYSTEM, func );
-}
-
-
-/* brl1_intr is called directly from the uart interrupt; after it runs, the
- * interrupt "daemon" xthread is signalled to continue.
- */
-void
-brl1_intr( void )
-{
-}
-
-#define BRL1_INTERRUPT_LEVEL	65	/* linux request_irq() value */
-
-/* Return the current interrupt level */
-
-//#define CONSOLE_POLLING_ALSO
-
-int
-l1_get_intr_value( void )
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	return(0);
-#else
-#if defined(CONSOLE_POLLING_ALSO)
-	return(0);
-#else
-	return(BRL1_INTERRUPT_LEVEL);
-#endif /* CONSOLE_POLLING_ALSO */
-#endif /* USE_SAL_CONSOLE_IO */
-}
-
-/* Disconnect the callup functions - throw away interrupts */
-
-void
-l1_unconnect_intr(void)
-{
-#if !defined(USE_SAL_CONSOLE_IO)
-	/* UnRegister the upper-level callup functions */
-	l1_rx_notif((brl1_notif_t)NULL);
-	l1_tx_notif((brl1_notif_t)NULL);
-	/* We do NOT unregister the interrupts */
-#endif /* !USE_SAL_CONSOLE_IO */
-}
-
-/* Set up uart interrupt handling for this node's uart */
-
-void
-l1_connect_intr(void *rx_notify, void *tx_notify)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-#if 0
-	// Will need code here for sn2 - something like this
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid());
-	intr_connect_level(console_nodepda->node_first_cpu,
-                                SGI_UART_VECTOR, INTPEND0_MAXMASK,
-                                dummy_intr_func);
-	request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8),
-                                intr_func, SA_INTERRUPT | SA_SHIRQ,
-                                "l1_protocol_driver", (void *)sc);
-#endif
-#else
-	l1sc_t *sc;
-	nasid_t nasid;
-	int tmp;
-	nodepda_t *console_nodepda;
-	int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t);
-
-	if ( L1_interrupts_connected ) {
-		/* Interrupts are connected, so just register the callups */
-		l1_rx_notif((brl1_notif_t)rx_notify);
-		l1_tx_notif((brl1_notif_t)tx_notify);
-
-		L1_collectibles[L1C_CONNECT_CALLS]++;
-		return;
-	}
-	else
-		L1_interrupts_connected = 1;
-
-	nasid = get_master_nasid();
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(nasid));
-	sc = &console_nodepda->module->elsc;
-	sc->intr_cpu = console_nodepda->node_first_cpu;
-
-	if ( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK, (intr_func_t)brl1_intr) ) {
-		L1_interrupts_connected = 0; /* FAILS !! */
-	}
-	else {
-		void synergy_intr_connect(int, int);
-
-		synergy_intr_connect(UART_INTR, sc->intr_cpu);
-		L1_collectibles[L1C_R_IRQ]++;
-		tmp = request_irq(BRL1_INTERRUPT_LEVEL, brl1_intrd, SA_INTERRUPT | SA_SHIRQ, "l1_protocol_driver", (void *)sc);
-		L1_collectibles[L1C_R_IRQ_RET] = (uint64_t)tmp;
-		if ( tmp ) {
-			L1_interrupts_connected = 0; /* FAILS !! */
-		}
-		else {
-			/* Register the upper-level callup functions */
-			l1_rx_notif((brl1_notif_t)rx_notify);
-			l1_tx_notif((brl1_notif_t)tx_notify);
-
-			/* Set the uarts the way we like it */
-			uart_enable_recv_intr( sc );
-			uart_disable_xmit_intr( sc );
-		}
-	}
-#endif	/* USE_SAL_CONSOLE_IO */
-}
-
-
-/* These are functions to use from serial_in/out when in protocol
- * mode to send and receive uart control regs. These are external
- * interfaces into the protocol driver.
- */
-
-void
-l1_control_out(int offset, int value)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	/* quietly ignore unless simulator */
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		if ( master_node_bedrock_address != (u64)0 ) {
-			writeb(value, (unsigned long)master_node_bedrock_address +
-				(offset<< 3));
-		}
-		return;
-	}
-#else
-	nasid_t nasid = get_master_nasid();
-	WRITE_L1_UART_REG(nasid, offset, value); 
-#endif
-}
-
-/* Console input exported interface. Return a register value.  */
-
-int
-l1_control_in_polled(int offset)
-{
-	static int l1_control_in_local(int, int);
-
-	return(l1_control_in_local(offset, SERIAL_POLLED_MODE));
-}
-
-int
-l1_control_in(int offset)
-{
-	static int l1_control_in_local(int, int);
-
-	return(l1_control_in_local(offset, SERIAL_INTERRUPT_MODE));
-}
-
-static int
-l1_control_in_local(int offset, int mode)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	int sal_call_status = 0, input;
-	int ret = 0;
-
-	if ( offset == REG_LSR ) {
-		ret = (LSR_XHRE | LSR_XSRE);	/* can send anytime */
-		sal_call_status = ia64_sn_console_check(&input);
-		if ( !sal_call_status && input ) {
-			/* input pending */
-			ret |= LSR_RCA;
-		}
-	}
-
-	/* If the sal call failed, do it the old-fashioned way */
-	if ( sal_call_status ) {
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-			ret = readb((unsigned long)master_node_bedrock_address +
-					(offset<< 3));
-		}		
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid;
-			int ret, input;
-			static int l1_poll(l1sc_t *, int);
-
-			nasid = get_master_nasid();
-			ret = READ_L1_UART_REG(nasid, offset); 
-
-			if ( offset == REG_LSR ) {
-				ret |= (LSR_XHRE | LSR_XSRE);	/* can send anytime */
-				if ( L1_cons_is_inited ) {
-					if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
-						input = l1_poll(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, mode);
-						if ( input ) {
-							ret |= LSR_RCA;
-						}
-					}
-				}
-			}
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-#endif
-	return(ret);
-}
-
-/*
- * Console input exported interface. Return a character (if one is available)
- */
-
-int
-l1_serial_in_polled(void)
-{
-	static int l1_serial_in_local(int mode);
-
-	return(l1_serial_in_local(SERIAL_POLLED_MODE));
-}
-
-int
-l1_serial_in(void)
-{
-	static int l1_serial_in_local(int mode);
-
-	return(l1_serial_in_local(SERIAL_INTERRUPT_MODE));
-}
-
-static int
-l1_serial_in_local(int mode)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	int sal_call_status;
-	int ch;
-
-	sal_call_status = ia64_sn_console_getc(&ch);
-	if ( !sal_call_status ) {
-		return(ch);
-	}
-	else {
-		/* If the sal called failed - do it the old-fashioned way */
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-			return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));
-		}		
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid;
-			l1sc_t *sc;
-			int value;
-			static int l1_getc( l1sc_t *, int );
-			static inline l1sc_t *early_sc_init(nasid_t);
-
-			nasid = get_master_nasid();
-			sc = early_sc_init(nasid);
-			if ( L1_cons_is_inited ) {
-				if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
-					sc = &NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc;
-				}
-			}
-			value = l1_getc(sc, mode);
-			return(value);
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-#endif
-}
-
-/* Console output exported interface. Write message to the console.  */
-
-int
-l1_serial_out( char *str, int len )
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	void early_sn_setup(void);
-	int sal_call_status = 0;
-	int counter = len;
-
-#if defined(CONFIG_IA64_EARLY_PRINTK)
-	{
-		static int inited;
-		if(!inited) {
-			inited=1;
-			early_sn_setup();
-		}
-	}
-#endif
-
-	/* Attempt to write things out thru the sal */
-	sal_call_status = ia64_sn_console_putb(str, len);
-	if ( sal_call_status ) {
-		/* If the sal called failed - do it the old-fashioned way */
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-                        if (!master_node_bedrock_address)
-                                early_sn_setup();
-			if ( master_node_bedrock_address != (u64)0 ) {
-#ifdef FLAG_DIRECT_CONSOLE_WRITES
-				/* This is an easy way to pre-pend the output to know whether the output
-				 * was done via sal or directly */
-				writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-#endif	/* FLAG_DIRECT_CONSOLE_WRITES */
-				while ( counter > 0 ) {
-					writeb(*str, (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-					counter--;
-					str++;
-				}
-			}
-		}
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid = get_master_nasid();
-			int l1_write(l1sc_t *, char *, int, int);
-
-			if ( L1_cons_is_inited ) {
-				if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 )
-					return(l1_write(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, str, len,
-#if	defined(SYNC_CONSOLE_WRITE)
-							1
-#else
-							!L1_interrupts_connected
-#endif
-									));
-			}
-			return(early_l1_serial_out(nasid, str, len, NOT_LOCKED));
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-	return((counter <= 0) ? 0 : (len - counter));
-#endif
-}
-
-
-/*
- * These are the 'early' functions - when we need to do things before we have
- * all the structs setup.
- */
-
-
-static l1sc_t Early_console;		/* fake l1sc_t */
-static int Early_console_inited = 0;
-
-static void
-early_brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    int i;
-    brl1_sch_t *subch;
-
-    bzero( sc, sizeof( *sc ) );
-    sc->nasid = nasid;
-    sc->uart = uart;
-    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
-    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
-    sc->sol = 1;
-    subch = sc->subch;
-
-    /* initialize L1 subchannels
-     */
-
-    /* assign processor TTY channels */
-    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* assign system TTY channel (first free subchannel after each
-     * processor's individual TTY channel has been assigned)
-     */
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = ATOMIC_INIT(0);
-    subch->tx_notify = NULL;
-    subch->rx_notify = NULL;
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	static sc_cq_t x_iqp;
-
-	subch->iqp = &x_iqp;
-	ASSERT( subch->iqp );
-	cq_init( subch->iqp );
-    }
-    else {
-	/* we shouldn't be getting console input from remote UARTs */
-	subch->iqp = &sc->garbage_q;
-    }
-    subch++; i++;
-
-    /* "reserved" subchannels (0x05-0x0F); for now, throw away
-     * incoming packets
-     */
-    for( ; i < 0x10; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* remaining subchannels are free */
-    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-}
-
-static inline l1sc_t *
-early_sc_init(nasid_t nasid)
-{
-	/* This is for early I/O */
-	if ( Early_console_inited == 0 ) {
-    		early_brl1_init(&Early_console, nasid,  BRL1_LOCALHUB_UART);
-		Early_console_inited = 1;
-	}
-	return(&Early_console);
-}
-
-#define PUTCHAR(ch) \
-    { \
-        while( (!(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE)) || \
-                (!(READ_L1_UART_REG( nasid, REG_MSR ) & MSR_CTS)) ); \
-        WRITE_L1_UART_REG( nasid, REG_DAT, (ch) ); \
-    }
-
-static int
-early_l1_serial_out( nasid_t nasid, char *str, int len, int lock_state )
-{
-	int ret, sent = 0;
-	char *msg = str;
-	static int early_l1_send( nasid_t nasid, char *str, int len, int lock_state );
-
-	while ( sent < len ) {
-		ret = early_l1_send(nasid, msg, len - sent, lock_state);
-		sent += ret;
-		msg += ret;
-	}
-	return(len);
-}
-
-static inline int
-early_l1_send( nasid_t nasid, char *str, int len, int lock_state )
-{
-    int sent;
-    char crc_char;
-    unsigned short crc = INIT_CRC;
-
-    if( len > (BRL1_QSIZE - 1) )
-	len = (BRL1_QSIZE - 1);
-
-    sent = len;
-    if ( lock_state == NOT_LOCKED )
-    	lock_console(nasid);
-
-    PUTCHAR( BRL1_FLAG_CH );
-    PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM );
-    crc = crc16_calc( crc, (BRL1_EVENT | SC_CONS_SYSTEM) );
-
-    while( len ) {
-
-	if( (*str == BRL1_FLAG_CH) || (*str == BRL1_ESC_CH) ) {
-	    PUTCHAR( BRL1_ESC_CH );
-	    PUTCHAR( (*str) ^ BRL1_XOR_CH );
-	}
-	else {
-	    PUTCHAR( *str );
-	}
-	
-	crc = crc16_calc( crc, *str );
-
-	str++; len--;
-    }
-    
-    crc ^= 0xffff;
-    crc_char = crc & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    crc_char = (crc >> 8) & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    PUTCHAR( BRL1_FLAG_CH );
-
-    if ( lock_state == NOT_LOCKED )
-    	unlock_console(nasid);
-    return sent;
-}
-
-/*********************************************************************
- * l1_cons functions
- *
- * These allow the L1 to act as the system console.  They're intended
- * to abstract away most of the br/l1 internal details from the
- * _L1_cons_* functions (in the prom-- see "l1_console.c") and
- * l1_* functions (in the kernel-- see "sio_l1.c") that they support.
- *
- */
-
-static int
-l1_poll( l1sc_t *sc, int mode )
-{
-    int ret;
-
-    /* in case this gets called before the l1sc_t structure for the module_t
-     * struct for this node is initialized (i.e., if we're called with a
-     * zero l1sc_t pointer)...
-     */
-
-
-    if( !sc ) {
-	return 0;
-    }
-
-    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
-	return 1;
-    }
-
-    ret = brl1_receive( sc, mode );
-    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
-	L1_collectibles[L1C_REC_STALLS] = ret;
-
-    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
-	return 1;
-    }
-    return 0;
-}
-
-
-/* pull a character off of the system console queue (if one is available)
- */
-static int
-l1_getc( l1sc_t *sc, int mode )
-{
-    unsigned long pl = 0;
-    int c;
-
-    brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
-    sc_cq_t *q = subch->iqp;
-
-    if( !l1_poll( sc, mode ) ) {
-	return 0;
-    }
-
-    SUBCH_DATA_LOCK( subch, pl );
-    if( cq_empty( q ) ) {
-	atomic_set(&subch->packet_arrived, 0);
-	SUBCH_DATA_UNLOCK( subch, pl );
-	return 0;
-    }
-    cq_rem( q, c );
-    if( cq_empty( q ) )
-	atomic_set(&subch->packet_arrived, 0);
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return c;
-}
-
-/*
- * Write a message to the L1 on the system console subchannel.
- *
- * Danger: don't use a non-zero value for the wait parameter unless you're
- * someone important (like a kernel error message).
- */
-
-int
-l1_write( l1sc_t *sc, char *msg, int len, int wait )
-{
-	int sent = 0, ret = 0;
-
-	if ( wait ) {
-		while ( sent < len ) {
-			ret = brl1_send( sc, msg, len - sent, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
-			sent += ret;
-			msg += ret;
-		}
-		ret = len;
-	}
-	else {
-		ret = brl1_send( sc, msg, len, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
-	}
-	return(ret);
-}
-
-/* initialize the system console subchannel
- */
-void
-l1_init(void)
-{
-	/* All we do now is remember that we have been called */
-	L1_cons_is_inited = 1;
-}
-
-
-/*********************************************************************
- * The following functions and definitions implement the "message"-
- * style interface to the L1 system controller.
- *
- * Note that throughout this file, "sc" generally stands for "system
- * controller", while "subchannels" tend to be represented by
- * variables with names like subch or ch.
- *
- */
-
-#ifdef L1_DEBUG
-#define L1_DBG_PRF(x) printf x
-#else
-#define L1_DBG_PRF(x)
-#endif
-
-/*
- * sc_data_ready is called to signal threads that are blocked on l1 input.
- */
-void
-sc_data_ready( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-
-    brl1_sch_t *subch = &(sc->subch[ch]);
-    SUBCH_DATA_LOCK( subch, pl );
-    sv_signal( &(subch->arrive_sv) );
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-/* sc_open reserves a subchannel to send a request to the L1 (the
- * L1's response will arrive on the same channel).  The number
- * returned by sc_open is the system controller subchannel
- * acquired.
- */
-int
-sc_open( l1sc_t *sc, uint target )
-{
-    /* The kernel version implements a locking scheme to arbitrate
-     * subchannel assignment.
-     */
-    int ch;
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    SUBCH_LOCK( sc, pl );
-
-    /* Look for a free subchannel. Subchannels 0-15 are reserved
-     * for other purposes.
-     */
-    for( subch = &(sc->subch[BRL1_CMD_SUBCH]), ch = BRL1_CMD_SUBCH; 
-			ch < BRL1_NUM_SUBCHANS; subch++, ch++ ) {
-        if( subch->use == BRL1_SUBCH_FREE )
-            break;
-    }
-
-    if( ch == BRL1_NUM_SUBCHANS ) {
-        /* there were no subchannels available! */
-        SUBCH_UNLOCK( sc, pl );
-        return SC_NSUBCH;
-    }
-
-    subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->target = target;
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
-    subch->tx_notify = NULL;
-    subch->rx_notify = sc_data_ready;
-    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
-				   NASID_TO_COMPACT_NODEID(sc->nasid) );
-    ASSERT( subch->iqp );
-    cq_init( subch->iqp );
-
-    return ch;
-}
-
-
-/* sc_close frees a Bedrock<->L1 subchannel.
- */
-int
-sc_close( l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    SUBCH_LOCK( sc, pl );
-    subch = &(sc->subch[ch]);
-    if( subch->use != BRL1_SUBCH_RSVD ) {
-        /* we're trying to close a subchannel that's not open */
-	SUBCH_UNLOCK( sc, pl );
-        return SC_NOPEN;
-    }
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->use = BRL1_SUBCH_FREE;
-
-    sv_broadcast( &(subch->arrive_sv) );
-    sv_destroy( &(subch->arrive_sv) );
-    spin_lock_destroy( &(subch->data_lock) );
-
-    ASSERT( subch->iqp && (subch->iqp != &sc->garbage_q) );
-    snia_kmem_free( subch->iqp, sizeof(sc_cq_t) );
-    subch->iqp = &sc->garbage_q;
-    subch->tx_notify = NULL;
-    subch->rx_notify = brl1_discard_packet;
-
-    SUBCH_UNLOCK( sc, pl );
-
-    return SC_SUCCESS;
-}
-
-
-/* sc_construct_msg builds a bedrock-to-L1 request in the supplied
- * buffer.  Returns the length of the message.  The
- * safest course when passing a buffer to be filled in is to use
- * BRL1_QSIZE as the buffer size.
- *
- * Command arguments are passed as type/argument pairs, i.e., to
- * pass the number 5 as an argument to an L1 command, call
- * sc_construct_msg as follows:
- *
- *    char msg[BRL1_QSIZE];
- *    msg_len = sc_construct_msg( msg,
- *				  BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                2,
- *                                L1_ARG_INT, 5 );
- *
- * To pass an additional ASCII argument, you'd do the following:
- *
- *    char *str;
- *    ... str points to a null-terminated ascii string ...
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                4,
- *                                L1_ARG_INT, 5,
- *                                L1_ARG_ASCII, str );
- *
- * Finally, arbitrary data of unknown type is passed using the argtype
- * code L1_ARG_UNKNOWN, a data length, and a buffer pointer, e.g.
- *
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                3,
- *                                L1_ARG_UNKNOWN, 32, bufptr );
- *
- * ...passes 32 bytes of data starting at bufptr.  Note that no string or
- * "unknown"-type argument should be long enough to overflow the message
- * buffer.
- *
- * To construct a message for an L1 command that requires no arguments,
- * you'd use the following:
- *
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                0 );
- *
- * The final 0 means "no varargs".  Notice that this parameter is used to hold
- * the number of additional arguments to sc_construct_msg, _not_ the actual
- * number of arguments used by the L1 command (so 2 per L1_ARG_[INT,ASCII]
- * type argument, and 3 per L1_ARG_UNKOWN type argument).  A call to construct
- * an L1 command which required three integer arguments and two arguments of
- * some arbitrary (unknown) type would pass 12 as the value for this parameter.
- *
- * ENDIANNESS WARNING: The following code does a lot of copying back-and-forth
- * between byte arrays and four-byte big-endian integers.  Depending on the
- * system controller connection and endianness of future architectures, some
- * rewriting might be necessary.
- */
-int
-sc_construct_msg( l1sc_t  *sc,		/* system controller struct */
-		  int	   ch,           /* subchannel for this message */
-		  char    *msg,          /* message buffer */
-		  int      msg_len,      /* size of message buffer */
-                  l1addr_t addr_task,    /* target system controller task */
-                  short    req_code,     /* 16-bit request code */
-                  int      req_nargs,    /* # of arguments (varargs) passed */
-                  ... )                 /* any additional parameters */
-{
-    uint32_t buf32;   /* 32-bit buffer used to bounce things around */
-    void *bufptr;       /* used to hold command argument addresses */
-    va_list al;         /* variable argument list */
-    int index;          /* current index into msg buffer */
-    int argno;          /* current position in varargs list */
-    int l1_argno;       /* running total of arguments to l1 */
-    int l1_arg_t;       /* argument type/length */
-    int l1_argno_byte;  /* offset of argument count byte */
-
-    index = argno = 0;
-
-    /* set up destination address */
-    if( (msg_len -= sizeof( buf32 )) < 0 )
-	return -1;
-    L1_ADDRESS_TO_TASK( &buf32, sc->subch[ch].target, addr_task );
-    COPY_INT_TO_BUFFER(msg, index, buf32);
-
-    /* copy request code */
-    if( (msg_len -= 2) < 0 )
-	return( -1 );
-    msg[index++] = ((req_code >> 8) & 0xff);
-    msg[index++] = (req_code & 0xff);
-
-    if( !req_nargs ) {
-        return index;
-    }
-
-    /* reserve a byte for the argument count */
-    if( (msg_len -= 1) < 0 )
-	return( -1 );
-    l1_argno_byte = index++;
-    l1_argno = 0;
-
-    /* copy additional arguments */
-    va_start( al, req_nargs );
-    while( argno < req_nargs ) {
-        l1_argno++;
-        l1_arg_t = va_arg( al, int ); argno++;
-        switch( l1_arg_t )
-        {
-          case L1_ARG_INT:
-	    if( (msg_len -= (sizeof( buf32 ) + 1)) < 0 )
-		return( -1 );
-            msg[index++] = L1_ARG_INT;
-            buf32 = (unsigned)va_arg( al, int ); argno++;
-	    COPY_INT_TO_BUFFER(msg, index, buf32);
-            break;
-
-          case L1_ARG_ASCII:
-            bufptr = va_arg( al, char* ); argno++;
-	    if( (msg_len -= (strlen( bufptr ) + 2)) < 0 )
-		return( -1 );
-            msg[index++] = L1_ARG_ASCII;
-            strcpy( (char *)&(msg[index]), (char *)bufptr );
-            index += (strlen( bufptr ) + 1); /* include terminating null */
-            break;
-
-	  case L1_ARG_UNKNOWN:
-              {
-                  int arglen;
-		  
-                  arglen = va_arg( al, int ); argno++;
-                  bufptr = va_arg( al, void* ); argno++;
-		  if( (msg_len -= (arglen + 1)) < 0 )
-		      return( -1 );
-                  msg[index++] = L1_ARG_UNKNOWN | arglen;
-                  BCOPY( bufptr, &(msg[index]), arglen  );
-                  index += arglen;
-		  break;
-              }
-	  
-	  default: /* unhandled argument type */
-	    return -1;
-        }
-    }
-
-    va_end( al );
-    msg[l1_argno_byte] = l1_argno;
-
-    return index;
-}
-
-
-
-/* sc_interpret_resp verifies an L1 response to a bedrock request, and
- * breaks the response data up into the constituent parts.  If the
- * response message indicates error, or if a mismatch is found in the
- * expected number and type of arguments, an error is returned.  The
- * arguments to this function work very much like the arguments to
- * sc_construct_msg, above, except that L1_ARG_INTs must be followed
- * by a _pointer_ to an integer that can be filled in by this function.
- */
-int
-sc_interpret_resp( char *resp,          /* buffer received from L1 */
-                   int   resp_nargs,    /* number of _varargs_ passed in */
-                   ... )
-{
-    uint32_t buf32;   /* 32-bit buffer used to bounce things around */
-    void *bufptr;       /* used to hold response field addresses */
-    va_list al;         /* variable argument list */
-    int index;          /* current index into response buffer */
-    int argno;          /* current position in varargs list */
-    int l1_fldno;       /* number of resp fields received from l1 */
-    int l1_fld_t;       /* field type/length */
-
-    index = argno = 0;
-
-#if defined(L1_DEBUG)
-#define DUMP_RESP							  \
-    {									  \
-	int ix;								  \
-        char outbuf[512];						  \
-        sprintf( outbuf, "sc_interpret_resp error line %d: ", __LINE__ ); \
-	for( ix = 0; ix < 16; ix++ ) {					  \
-	    sprintf( &outbuf[strlen(outbuf)], "%x ", resp[ix] );	  \
-	}								  \
-	printk( "%s\n", outbuf );					  \
-    }
-#else
-#define DUMP_RESP
-#endif /* L1_DEBUG */
-
-    /* check response code */
-    COPY_BUFFER_TO_INT(resp, index, buf32);
-    if( buf32 != L1_RESP_OK ) {
-	DUMP_RESP;
-        return buf32;
-    }
-
-    /* get number of response fields */
-    l1_fldno = resp[index++];
-
-    va_start( al, resp_nargs );
-
-    /* copy out response fields */
-    while( argno < resp_nargs ) {
-        l1_fldno--;
-        l1_fld_t = va_arg( al, int ); argno++;
-        switch( l1_fld_t )
-        {
-          case L1_ARG_INT:
-            if( resp[index++] != L1_ARG_INT ) {
-                /* type mismatch */
-		va_end( al );
-		DUMP_RESP;
-		return -1;
-            }
-            bufptr = va_arg( al, int* ); argno++;
-	    COPY_BUFFER_TO_BUFFER(resp, index, bufptr);
-            break;
-
-          case L1_ARG_ASCII:
-            if( resp[index++] != L1_ARG_ASCII ) {
-                /* type mismatch */
-		va_end( al );
-		DUMP_RESP;
-                return -1;
-            }
-            bufptr = va_arg( al, char* ); argno++;
-            strcpy( (char *)bufptr, (char *)&(resp[index]) );
-            /* include terminating null */
-            index += (strlen( &(resp[index]) ) + 1);
-            break;
-
-          default:
-	    if( (l1_fld_t & L1_ARG_UNKNOWN) == L1_ARG_UNKNOWN )
-	    {
-		int *arglen;
-		
-		arglen = va_arg( al, int* ); argno++;
-		bufptr = va_arg( al, void* ); argno++;
-		*arglen = ((resp[index++] & ~L1_ARG_UNKNOWN) & 0xff);
-		BCOPY( &(resp[index]), bufptr, *arglen  );
-		index += (*arglen);
-	    }
-	    
-	    else {
-		/* unhandled type */
-		va_end( al );
-		DUMP_RESP;
-		return -1;
-	    }
-        }
-    }
-    va_end( al );
-  
-    if( (l1_fldno != 0) || (argno != resp_nargs) ) {
-        /* wrong number of arguments */
-	DUMP_RESP;
-        return -1;
-    }
-    return 0;
-}
-
-/* sc_send takes as arguments a system controller struct, a
- * buffer which contains a Bedrock<->L1 "request" message,
- * the message length, and the subchannel (presumably obtained
- * from an earlier invocation of sc_open) over which the
- * message is to be sent.  The final argument ("wait") indicates
- * whether the send is to be performed synchronously or not.
- *
- * sc_send returns either zero or an error value.  Synchronous sends 
- * (wait != 0) will not return until the data has actually been sent
- * to the UART.  Synchronous sends generally receive privileged
- * treatment.  The intent is that they be used sparingly, for such
- * purposes as kernel printf's (the "ducons" routines).  Run-of-the-mill
- * console output and L1 requests should NOT use a non-zero value
- * for wait.
- */
-int
-sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait )
-{
-    char type_and_subch;
-    int result;
-
-    if( (ch < 0) || ( ch >= BRL1_NUM_SUBCHANS) ) {
-        return SC_BADSUBCH;
-    }
-
-    /* Verify that this is an open subchannel
-     */
-    if( sc->subch[ch].use == BRL1_SUBCH_FREE ) {
-        return SC_NOPEN;
-    }
-
-    type_and_subch = (BRL1_REQUEST | ((u_char)ch));
-    result = brl1_send( sc, msg, len, type_and_subch, wait );
-
-    /* If we sent as much as we asked to, return "ok". */
-    if( result == len )
-	return( SC_SUCCESS );
-
-    /* Or, if we sent less, than either the UART is busy or
-     * we're trying to send too large a packet anyway.
-     */
-    else if( result >= 0 && result < len )
-	return( SC_BUSY );
-
-    /* Or, if something else went wrong (result < 0), then
-     * return that error value.
-     */
-    else
-	return( result );
-}
-
-/* subch_pull_msg pulls a message off the receive queue for subch
- * and places it the buffer pointed to by msg.  This routine should only
- * be called when the caller already knows a message is available on the
- * receive queue (and, in the kernel, only when the subchannel data lock
- * is held by the caller).
- */
-static void
-subch_pull_msg( brl1_sch_t *subch, char *msg, int *len )
-{
-    sc_cq_t *q;         /* receive queue */
-    int before_wrap,    /* packet may be split into two different       */
-        after_wrap;     /*   pieces to acommodate queue wraparound      */
-
-    /* pull message off the receive queue */
-    q = subch->iqp;
-
-    cq_rem( q, *len );   /* remove length byte and store */
-    cq_discard( q );     /* remove type/subch byte and discard */
-
-    if ( *len > 0 )
-	(*len)--;        /* don't count type/subch byte in length returned */
-
-    if( (q->opos + (*len)) > BRL1_QSIZE ) {
-        before_wrap = BRL1_QSIZE - q->opos;
-        after_wrap = (*len) - before_wrap;
-    }
-    else {
-        before_wrap = (*len);
-        after_wrap = 0;
-    }
-
-    BCOPY( q->buf + q->opos, msg, before_wrap  );
-    if( after_wrap ) {
-        BCOPY( q->buf, msg + before_wrap, after_wrap  );
-	q->opos = after_wrap;
-    }
-    else {
-	q->opos = ((q->opos + before_wrap) & (BRL1_QSIZE - 1));
-    }
-    atomic_dec(&(subch->packet_arrived));
-}
-
-
-/* sc_recv_poll can be called as a blocking or non-blocking function;
- * it attempts to pull a message off of the subchannel specified
- * in the argument list (ch).
- *
- * The "block" argument, if non-zero, is interpreted as a timeout
- * delay (to avoid permanent waiting).
- */
-
-int
-sc_recv_poll( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
-{
-    int is_msg = 0;
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    rtc_time_t exp_time = rtc_time() + block;
-
-    /* sanity check-- make sure this is an open subchannel */
-    if( subch->use == BRL1_SUBCH_FREE )
-	return( SC_NOPEN );
-
-    do {
-
-        /* kick the next lower layer and see if it pulls anything in
-         */
-	brl1_receive( sc, SERIAL_POLLED_MODE );
-	is_msg = atomic_read(&subch->packet_arrived);
-
-    } while( block && !is_msg && (rtc_time() < exp_time) );
-
-    if( !is_msg ) {
-	/* no message and we didn't care to wait for one */
-	return( SC_NMSG );
-    }
-
-    SUBCH_DATA_LOCK( subch, pl );
-    subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( SC_SUCCESS );
-}
-    
-
-/* Like sc_recv_poll, sc_recv_intr can be called in either a blocking
- * or non-blocking mode.  Rather than polling until an appointed timeout,
- * however, sc_recv_intr sleeps on a syncrhonization variable until a
- * signal from the lower layer tells us that a packet has arrived.
- *
- * sc_recv_intr can't be used with remote (router) L1s.
- */
-int
-sc_recv_intr( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
-{
-    int is_msg = 0;
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    do {
-	SUBCH_DATA_LOCK(subch, pl);
-	is_msg = atomic_read(&subch->packet_arrived);
-	if( !is_msg && block ) {
-	    /* wake me when you've got something */
-	    subch->rx_notify = sc_data_ready;
-	    sv_wait( &(subch->arrive_sv), 0, 0);
-	    if( subch->use == BRL1_SUBCH_FREE ) {
-		/* oops-- somebody closed our subchannel while we were
-		 * sleeping!
-		 */
-
-		/* no need to unlock since the channel's closed anyhow */
-		return( SC_NOPEN );
-	    }
-	}
-    } while( !is_msg && block );
-
-    if( !is_msg ) {
-	/* no message and we didn't care to wait for one */
-	SUBCH_DATA_UNLOCK( subch, pl );
-	return( SC_NMSG );
-    }
-
-    subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( SC_SUCCESS );
-}
-
-/* sc_command implements a (blocking) combination of sc_send and sc_recv.
- * It is intended to be the SN1 equivalent of SN0's "elsc_command", which
- * issued a system controller command and then waited for a response from
- * the system controller before returning.
- *
- * cmd points to the outgoing command; resp points to the buffer in
- * which the response is to be stored.  Both buffers are assumed to
- * be the same length; if there is any doubt as to whether the
- * response buffer is long enough to hold the L1's response, then
- * make it BRL1_QSIZE bytes-- no Bedrock<->L1 message can be any
- * bigger.
- *
- * Be careful using the same buffer for both cmd and resp; it could get
- * hairy if there were ever an L1 command reqeuest that spanned multiple
- * packets.  (On the other hand, that would require some additional
- * rewriting of the L1 command interface anyway.)
- */
-#define __RETRIES	50
-#define __WAIT_SEND	1	// ( sc->uart != BRL1_LOCALHUB_UART )
-#define __WAIT_RECV	10000000
-
-
-int
-sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
-{
-    int result;
-    int retries;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-    	return SC_NMSG;
-
-    retries = __RETRIES;
-
-    while( (result = sc_send( sc, ch, cmd, *len, __WAIT_SEND )) < 0 ) {
-	if( result == SC_BUSY ) {
-	    retries--;
-	    if( retries <= 0 )
-		return result;
-	    uart_delay(500);
-	}
-	else {
-	    return result;
-	}
-    }
-    
-    /* block on sc_recv_* */
-    if( (sc->uart == BRL1_LOCALHUB_UART) && L1_interrupts_connected ) {
-	return( sc_recv_intr( sc, ch, resp, len, __WAIT_RECV ) );
-    }
-    else {
-	return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
-    }
-}
-
-/* sc_command_kern is a knuckle-dragging, no-patience version of sc_command
- * used in situations where the kernel has a command that shouldn't be
- * delayed until the send buffer clears.  sc_command should be used instead
- * under most circumstances.
- */
-
-int
-sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
-{
-    int result;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-    	return SC_NMSG;
-
-    if( (result = sc_send( sc, ch, cmd, *len, 1 )) < 0 ) {
-	return result;
-    }
-
-    return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
-}
-
-
-
-/* sc_poll checks the queue corresponding to the given
- * subchannel to see if there's anything available.  If
- * not, it kicks the brl1 layer and then checks again.
- *
- * Returns 1 if input is available on the given queue,
- * 0 otherwise.
- */
-
-int
-sc_poll( l1sc_t *sc, int ch )
-{
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    if( atomic_read(&subch->packet_arrived) )
-	return 1;
-
-    brl1_receive( sc, SERIAL_POLLED_MODE );
-
-    if( atomic_read(&subch->packet_arrived) )
-	return 1;
-
-    return 0;
-}
-
-/* for now, sc_init just calls brl1_init */
-
-void
-sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    if ( !IS_RUNNING_ON_SIMULATOR() )
-    	brl1_init( sc, nasid, uart );
-}
-
-/* sc_dispatch_env_event handles events sent from the system control
- * network's environmental monitor tasks.
- */
-
-#if	defined(LINUX_KERNEL_THREADS)
-
-static void
-sc_dispatch_env_event( uint code, int argc, char *args, int maxlen )
-{
-    int j, i = 0;
-    uint32_t ESPcode;
-
-    switch( code ) {
-	/* for now, all codes do the same thing: grab two arguments
-	 * and print a cmn_err_tag message */
-      default:
-	/* check number of arguments */
-	if( argc != 2 ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected 2 arguments, got %d\n", argc ));
-	    return;
-	}
-	
-	/* get ESP code (integer argument) */
-	if( args[i++] != L1_ARG_INT ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected integer argument\n" ));
-	    return;
-	}
-	/* WARNING: highly endian */
-	COPY_BUFFER_TO_INT(args, i, ESPcode);
-
-	/* verify string argument */
-	if( args[i++] != L1_ARG_ASCII ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected an ASCII string\n" ));
-	    return;
-	}
-	for( j = i; j < maxlen; j++ ) {
-	    if( args[j] == '\0' ) break; /* found string termination */
-	}
-	if( j == maxlen ) {
-	    j--;
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "message too long-- truncating\n" ));
-	}
-
-	/* strip out trailing cr/lf */
-	for( ; 
-	     j > 1 && ((args[j-1] == 0xd) || (args[j-1] == 0xa)); 
-	     j-- );
-	args[j] = '\0';
-	
-	/* strip out leading cr/lf */
-	for( ;
-	     i < j && ((args[i] == 0xd) || (args[i] == 0xa));
-	     i++ );
-    }
-}
-
-
-/* sc_event waits for events to arrive from the system controller, and
- * prints appropriate messages to the syslog.
- */
-
-static void
-sc_event( l1sc_t *sc, int ch )
-{
-    char event[BRL1_QSIZE];
-    int i;
-    int result;
-    int event_len;
-    uint32_t ev_src;
-    uint32_t ev_code;
-    int ev_argc;
-
-    while(1) {
-	
-	bzero( event, BRL1_QSIZE );
-
-	/*
-	 * wait for an event 
-	 */
-	result = sc_recv_intr( sc, ch, event, &event_len, 1 );
-	if( result != SC_SUCCESS ) {
-	    printk(KERN_WARNING  "Error receiving sysctl event on nasid %d\n",
-		     sc->nasid );
-	}
-	else {
-	    /*
-	     * an event arrived; break it down into useful pieces
-	     */
-#if defined(L1_DEBUG) && 0
-	    int ix;
-	    printf( "Event packet received:\n" );
-	    for (ix = 0; ix < 64; ix++) {
-		printf( "%x%x ", ((event[ix] >> 4) & ((uint64_t)0xf)),
-			(event[ix] & ((uint64_t)0xf)) );
-		if( (ix % 16) == 0xf ) printf( "\n" );
-	    }
-#endif /* L1_DEBUG */
-
-	    i = 0;
-
-	    /* get event source */
-	    COPY_BUFFER_TO_INT(event, i, ev_src);
-	    COPY_BUFFER_TO_INT(event, i, ev_code);
-
-	    /* get arg count */
-	    ev_argc = (event[i++] & 0xffUL);
-	    
-	    /* dispatch events by task */
-	    switch( (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT )
-	    {
-	      case L1_ADDR_TASK_ENV: /* environmental monitor event */
-		sc_dispatch_env_event( ev_code, ev_argc, &(event[i]), 
-				       BRL1_QSIZE - i );
-		break;
-
-	      default: /* unhandled task type */
-		L1_DBG_PRF(( "Unhandled event type received from system "
-			     "controllers: source task %x\n",
-			     (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT
-			   ));
-	    }
-	}
-	
-    }			
-}
-
-/* sc_listen sets up a service thread to listen for incoming events.
- */
-
-void
-sc_listen( l1sc_t *sc )
-{
-    int result;
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    char        msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         ch;     /* system controller subchannel used */
-
-    extern int msc_shutdown_pri;
-
-    /* grab the designated "event subchannel" */
-    SUBCH_LOCK( sc, pl );
-    subch = &(sc->subch[BRL1_EVENT_SUBCH]);
-    if( subch->use != BRL1_SUBCH_FREE ) {
-	SUBCH_UNLOCK( sc, pl );
-	printk(KERN_WARNING  "sysctl event subchannel in use! "
-		 "Not monitoring sysctl events.\n" );
-	return;
-    }
-    subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->target = BRL1_LOCALHUB_UART;
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
-    subch->tx_notify = NULL;
-    subch->rx_notify = sc_data_ready;
-    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
-				   NASID_TO_COMPACT_NODEID(sc->nasid) );
-    ASSERT( subch->iqp );
-    cq_init( subch->iqp );
-
-    /* set up a thread to listen for events */
-    sthread_create( "sysctl event handler", 0, 0, 0, msc_shutdown_pri,
-		    KT_PS, (st_func_t *) sc_event,
-		    (void *)sc, (void *)(uint64_t)BRL1_EVENT_SUBCH, 0, 0 );
-
-    /* signal the L1 to begin sending events */
-    bzero( msg, BRL1_QSIZE );
-    ch = sc_open( sc, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( sc, ch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_EVENT_SUBCH, 2,
-				 L1_ARG_INT, BRL1_EVENT_SUBCH )) < 0 )
-    {
-	sc_close( sc, ch );
-	L1_DBG_PRF(( "Failure in sc_construct_msg (%d)\n", len ));
-	goto err_return;
-    }
-
-    result = sc_command_kern( sc, ch, msg, msg, &len );
-    if( result < 0 )
-    {
-	sc_close( sc, ch );
-	L1_DBG_PRF(( "Failure in sc_command_kern (%d)\n", result ));
-	goto err_return;
-    }
-
-    sc_close( sc, ch );
-
-    result = sc_interpret_resp( msg, 0 );
-    if( result < 0 )
-    {
-	L1_DBG_PRF(( "Failure in sc_interpret_resp (%d)\n", result ));
-	goto err_return;
-    }
-
-    /* everything went fine; just return */
-    return;
-	
-err_return:
-    /* there was a problem; complain */
-    printk(KERN_WARNING  "failed to set sysctl event-monitoring subchannel.  "
-	     "Sysctl events will not be monitored.\n" );
-}
-
-#endif	/* LINUX_KERNEL_THREADS */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/l1_command.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/l1_command.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/l1_command.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/l1_command.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1409 +0,0 @@
-/* $Id: l1_command.c,v 1.2 2002/11/21 17:51:57 jh Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */ 
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_cpuid.h>
-
-#define ELSC_TIMEOUT	1000000		/* ELSC response timeout (usec) */
-#define LOCK_TIMEOUT	5000000		/* Hub lock timeout (usec) */
-
-#define LD(x)		(*(volatile uint64_t *)(x))
-#define SD(x, v)	(LD(x) = (uint64_t) (v))
-
-#define hub_cpu_get()	0
-
-#define LBYTE(caddr)	(*(char *) caddr)
-
-extern char *bcopy(const char * src, char * dest, int count);
-
-#define LDEBUG		0
-
-/*
- * ELSC data is in NVRAM page 7 at the following offsets.
- */
-
-#define NVRAM_MAGIC_AD	0x700		/* magic number used for init */
-#define NVRAM_PASS_WD	0x701		/* password (4 bytes in length) */
-#define NVRAM_DBG1	0x705		/* virtual XOR debug switches */
-#define NVRAM_DBG2	0x706		/* physical XOR debug switches */
-#define NVRAM_CFG	0x707		/* ELSC Configuration info */
-#define NVRAM_MODULE	0x708		/* system module number */
-#define NVRAM_BIST_FLG	0x709		/* BIST flags (2 bits per nodeboard) */
-#define NVRAM_PARTITION 0x70a		/* module's partition id */
-#define	NVRAM_DOMAIN	0x70b		/* module's domain id */
-#define	NVRAM_CLUSTER	0x70c		/* module's cluster id */
-#define	NVRAM_CELL	0x70d		/* module's cellid */
-
-#define NVRAM_MAGIC_NO	0x37		/* value of magic number */
-#define NVRAM_SIZE	16		/* 16 bytes in nvram */
-
-/*
- * Declare a static ELSC NVRAM buffer to hold all data read from
- * and written to NVRAM.  This nvram "cache" will be used only during the
- * IP27prom execution.
- */
-static char elsc_nvram_buffer[NVRAM_SIZE];
-
-#define SC_COMMAND sc_command
-
-/*
- * elsc_init
- *
- *   Initialize ELSC structure
- */
-
-void elsc_init(elsc_t *e, nasid_t nasid)
-{
-    sc_init((l1sc_t *)e, nasid, BRL1_LOCALHUB_UART);
-}
-
-
-/*
- * elsc_errmsg
- *
- *   Given a negative error code,
- *   returns a corresponding static error string.
- */
-
-char *elsc_errmsg(int code)
-{
-    switch (code) {
-    case ELSC_ERROR_CMD_SEND:
-	return "Command send error";
-    case ELSC_ERROR_CMD_CHECKSUM:
-	return "Command packet checksum error";
-    case ELSC_ERROR_CMD_UNKNOWN:
-	return "Unknown command";
-    case ELSC_ERROR_CMD_ARGS:
-	return "Invalid command argument(s)";
-    case ELSC_ERROR_CMD_PERM:
-	return "Permission denied";
-    case ELSC_ERROR_RESP_TIMEOUT:
-	return "System controller response timeout";
-    case ELSC_ERROR_RESP_CHECKSUM:
-	return "Response packet checksum error";
-    case ELSC_ERROR_RESP_FORMAT:
-	return "Response format error";
-    case ELSC_ERROR_RESP_DIR:
-	return "Response direction error";
-    case ELSC_ERROR_MSG_LOST:
-	return "Message lost because queue is full";
-    case ELSC_ERROR_LOCK_TIMEOUT:
-	return "Timed out getting ELSC lock";
-    case ELSC_ERROR_DATA_SEND:
-	return "Error sending data";
-    case ELSC_ERROR_NIC:
-	return "NIC protocol error";
-    case ELSC_ERROR_NVMAGIC:
-	return "Bad magic number in NVRAM";
-    case ELSC_ERROR_MODULE:
-	return "Module location protocol error";
-    default:
-	return "Unknown error";
-    }
-}
-
-/*
- * elsc_nvram_init
- *
- *   Initializes reads and writes to NVRAM.  This will perform a single
- *   read to NVRAM, getting all data at once.  When the PROM tries to
- *   read NVRAM, it returns the data from the buffer being read.  If the
- *   PROM tries to write out to NVRAM, the write is done, and the internal
- *   buffer is updated.
- */
-
-void elsc_nvram_init(nasid_t nasid, uchar_t *elsc_nvram_data)
-{
-    /* This might require implementation of multiple-packet request/responses
-     * if it's to provide the same behavior that was available in SN0.
-     */
-    nasid = nasid;
-    elsc_nvram_data = elsc_nvram_data;
-}
-
-/*
- * elsc_nvram_copy
- *
- *   Copies the content of a buffer into the static buffer in this library.
- */
-
-void elsc_nvram_copy(uchar_t *elsc_nvram_data)
-{
-    memcpy(elsc_nvram_buffer, elsc_nvram_data, NVRAM_SIZE);
-}
-
-/*
- * elsc_nvram_write
- *
- *   Copies bytes from 'buf' into NVRAM, starting at NVRAM address
- *   'addr' which must be between 0 and 2047.
- *
- *   If 'len' is non-negative, the routine copies 'len' bytes.
- *
- *   If 'len' is negative, the routine treats the data as a string and
- *   copies bytes up to and including a NUL-terminating zero, but not
- *   to exceed '-len' bytes.
- */
-
-int elsc_nvram_write(elsc_t *e, int addr, char *buf, int len)
-{
-    /* Here again, we might need to work out the details of a
-     * multiple-packet protocol.
-     */
-
-    /* For now, pretend it worked. */
-    e = e;
-    addr = addr;
-    buf = buf;
-    return (len < 0 ? -len : len);
-}
-
-/*
- * elsc_nvram_read
- *
- *   Copies bytes from NVRAM into 'buf', starting at NVRAM address
- *   'addr' which must be between 0 and 2047.
- *
- *   If 'len' is non-negative, the routine copies 'len' bytes.
- *
- *   If 'len' is negative, the routine treats the data as a string and
- *   copies bytes up to and including a NUL-terminating zero, but not
- *   to exceed '-len' bytes.  NOTE:  This method is no longer supported.
- *   It was never used in the first place.
- */
-
-int elsc_nvram_read(elsc_t *e, int addr, char *buf, int len)
-{
-    /* multiple packets? */
-    e = e;
-    addr = addr;
-    buf = buf;
-    len = len;
-    return -1;
-}
-
-
-/*
- * Command Set
- */
-
-int elsc_version(elsc_t *e, char *result)
-{
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-    int		major,  /* major rev number */
-	        minor,  /* minor rev number */
-                bugfix; /* bugfix rev number */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_FW_REV, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major,
-			   L1_ARG_INT, &minor, L1_ARG_INT, &bugfix )
-	< 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    sprintf( result, "%d.%d.%d", major, minor, bugfix );
-
-    return 0;
-}
-
-int elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2)
-{
-    /* shush compiler */
-    e = e;
-    byte1 = byte1;
-    byte2 = byte2;
-
-    /* fill in a buffer with the opcode & params; call sc_command */
-
-    return 0;
-}
-
-int elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		dbg_sw; /* holds debug switch settings */
-    int		len;	/* number of msg buffer bytes used */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RDBG, 0 ) ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &dbg_sw ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* copy out debug switch settings (last two bytes of the
-     * integer response)
-     */
-    *byte1 = ((dbg_sw >> 8) & 0xFF);
-    *byte2 = (dbg_sw & 0xFF);
-
-    return 0;
-}
-
-
-/*
- * elsc_rack_bay_get fills in the two int * arguments with the
- * rack number and bay number of the L1 being addressed
- */
-int elsc_rack_bay_get(elsc_t *e, uint *rack, uint *bay)
-{
-    char msg[BRL1_QSIZE];	/* L1 request/response info */
-    int subch;			/* system controller subchannel used */
-    int len;			/* length of message */
-    uint32_t	buf32;		/* used to copy 32-bit rack/bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRACK, 0 )) < 0 ) 
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-
-    /* send the request to the L1 */
-    if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close(e, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &buf32 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    return 0;
-}
-
-
-/* elsc_rack_bay_type_get fills in the three int * arguments with the
- * rack number, bay number and brick type of the L1 being addressed.  Note
- * that if the L1 operation fails and this function returns an error value, 
- * garbage may be written to brick_type.
- */
-int elsc_rack_bay_type_get( l1sc_t *sc, uint *rack, 
-			       uint *bay, uint *brick_type )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t buf32;	        /* used to copy 32-bit rack & bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRBT, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, 
-			           L1_ARG_INT, brick_type ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    /* convert brick_type to lower case */
-    *brick_type = *brick_type - 'A' + 'a';
-
-    return 0;
-}
-
-
-int elsc_module_get(elsc_t *e)
-{
-    extern char brick_types[];
-    uint rnum, rack, bay, bricktype, t;
-    int ret;
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = elsc_rack_bay_type_get(e, &rnum, &bay, &bricktype)) < 0) {
-	return ret;
-    }
-
-    /* report unset location info. with a special, otherwise invalid modid */
-    if (rnum == 0 && bay == 0)
-	return MODULE_NOT_SET;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-	return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;		
-    t = rnum / 100;		/* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;		/* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;		/* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    for( t = 0; t < MAX_BRICK_TYPES; t++ ) {
-	if( brick_types[t] == bricktype )
-	    return RBT_TO_MODULE(rack, bay, t);
-    }
-    
-    return ELSC_ERROR_MODULE;
-}
-
-int elsc_partition_set(elsc_t *e, int partition)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PARTITION_SET, 2,
-				 L1_ARG_INT, partition )) < 0 )
-    {
-	
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-    
-    return( 0 );
-}
-
-int elsc_partition_get(elsc_t *e)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t partition_id;    /* used to copy partition id out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PARTITION_GET, 0 )) < 0 )
-
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &partition_id ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-    
-    return( partition_id );
-}
-
-
-/*
- * elsc_cons_subch selects the "active" console subchannel for this node
- * (i.e., the one that will currently receive input)
- */
-int elsc_cons_subch(elsc_t *e, uint ch)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( e, L1_ADDR_LOCAL );
-    
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_CONS_SUBCH, 2,
-				 L1_ARG_INT, ch)) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-/*
- * elsc_cons_node should only be executed by one node.  It declares to
- * the system controller that the node from which it is called will be
- * the owner of the system console.
- */
-int elsc_cons_node(elsc_t *e)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( e, L1_ADDR_LOCAL );
-    
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_CONS_NODE, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-    
-
-/* elsc_display_line writes up to 12 characters to either the top or bottom
- * line of the L1 display.  line points to a buffer containing the message
- * to be displayed.  The zero-based line number is specified by lnum (so
- * lnum == 0 specifies the top line and lnum == 1 specifies the bottom).
- * Lines longer than 12 characters, or line numbers not less than
- * L1_DISPLAY_LINES, cause elsc_display_line to return an error.
- */
-int elsc_display_line(elsc_t *e, char *line, int lnum)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		len;	/* number of msg buffer bytes used */
-
-    /* argument sanity checking */
-    if( !(lnum < L1_DISPLAY_LINES) )
-	return( ELSC_ERROR_CMD_ARGS );
-    if( !(strlen( line ) <= L1_DISPLAY_LINE_LENGTH) )
-	return( ELSC_ERROR_CMD_ARGS );
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 (L1_REQ_DISP1+lnum), 2,
-				 L1_ARG_ASCII, line )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-/* elsc_display_mesg silently drops message characters beyond the 12th.
- */
-int elsc_display_mesg(elsc_t *e, char *chr)
-{
-
-    char line[L1_DISPLAY_LINE_LENGTH+1];
-    int numlines, i;
-    int result;
-
-    numlines = (strlen( chr ) + L1_DISPLAY_LINE_LENGTH - 1) /
-	L1_DISPLAY_LINE_LENGTH;
-
-    if( numlines > L1_DISPLAY_LINES )
-	numlines = L1_DISPLAY_LINES;
-
-    for( i = 0; i < numlines; i++ )
-    {
-	strncpy( line, chr, L1_DISPLAY_LINE_LENGTH );
-	line[L1_DISPLAY_LINE_LENGTH] = '\0';
-
-	/* generally we want to leave the first line of the L1 display
-	 * alone (so the L1 can manipulate it).  If you need to be able
-	 * to display to both lines (for debugging purposes), define
-	 * L1_DISP_2LINES in irix/kern/ksys/l1.h, or add -DL1_DISP_2LINES
-	 * to your 'defs file.
-	 */
-#if defined(L1_DISP_2LINES)
-	if( (result = elsc_display_line( e, line, i )) < 0 )
-#else
-	if( (result = elsc_display_line( e, line, i+1 )) < 0 )
-#endif
-
-	    return result;
-
-	chr += L1_DISPLAY_LINE_LENGTH;
-    }
-    
-    return 0;
-}
-
-
-int elsc_password_set(elsc_t *e, char *password)
-{
-    /* shush compiler */
-    e = e;
-    password = password;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-int elsc_password_get(elsc_t *e, char *password)
-{
-    /* shush compiler */
-    e = e;
-    password = password;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-/*
- * sc_portspeed_get
- *
- * retrieve the current portspeed setting for the bedrock II
- */
-int sc_portspeed_get(l1sc_t *sc)
-{
-    char	msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         subch;  /* system controller subchannel used */
-    int		portspeed_a, portspeed_b;
-			/* ioport clock rates */
-
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-                                 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PORTSPEED,
-				 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-    
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) < 0 )
-    {
-        sc_close( sc, subch );
-        return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, 
-			   L1_ARG_INT, &portspeed_a,
-			   L1_ARG_INT, &portspeed_b ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* for the c-brick, we ignore the portspeed_b value */
-    return (portspeed_a ? 600 : 400);
-}
-
-/*
- * elsc_power_query
- *
- *   To be used after system reset, this command returns 1 if the reset
- *   was the result of a power-on, 0 otherwise.
- *
- *   The power query status is cleared to 0 after it is read.
- */
-
-int elsc_power_query(elsc_t *e)
-{
-    e = e; /* shush the compiler */
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 1;
-}
-
-int elsc_rpwr_query(elsc_t *e, int is_master)
-{
-    /* shush the compiler */
-    e = e;
-    is_master = is_master;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-} 
-
-/*
- * elsc_power_down
- *
- *   Sets up system to shut down in "sec" seconds (or modifies the
- *   shutdown time if one is already in effect).  Use 0 to power
- *   down immediately.
- */
-
-int elsc_power_down(elsc_t *e, int sec)
-{
-    /* shush compiler */
-    e = e;
-    sec = sec;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-int elsc_system_reset(elsc_t *e)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		len;	/* number of msg buffer bytes used */
-    int		result;
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RESET, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( (result = sc_command( e, subch, msg, msg, &len )) ) {
-	sc_close( e, subch );
-	if( result == SC_NMSG ) {
-	    /* timeout is OK.  We've sent the reset.  Now it's just
-	     * a matter of time...
-	     */
-	    return( 0 );
-	}
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-int elsc_power_cycle(elsc_t *e)
-{
-    /* shush compiler */
-    e = e;
-
-    /* fill in buffer with the opcode & params; call sc_command */
-
-    return 0;
-}
-
-
-int _elsc_hbt(elsc_t *e, int ival, int rdly)
-{
-    e = e;
-    ival = ival;
-    rdly = rdly;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-/* send a command string to an L1 */
-int sc_command_interp( l1sc_t *sc, l1addr_t compt, l1addr_t rack, l1addr_t bay,
-		       char *cmd )
-{
-    char        msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         subch;  /* system controller subchannel used */
-    l1addr_t	target; /* target system controller for command */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-
-    L1_BUILD_ADDR( &target, compt, rack, bay, 0 );
-    subch = sc_open( sc, target );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_CMD, L1_REQ_EXEC_CMD, 2,
-				 L1_ARG_ASCII, cmd )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-		   
-    /* send the request to the L1 */
-    if( SC_COMMAND( sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-    
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-/*
- * sc_power_down
- *
- * Shuts down the c-brick associated with sc, and any attached I/O bricks
- * or other c-bricks (won't go through r-bricks).
- */
-
-int sc_power_down(l1sc_t *sc)
-{
-    return sc_command_interp( sc, L1_ADDR_TYPE_L1, L1_ADDR_RACK_LOCAL, 
-			      L1_ADDR_BAY_LOCAL, "* pwr d" );
-}
-
-
-/*
- * sc_power_down_all
- *
- * Works similarly to sc_power_down, except that the request is sent to the
- * closest L2 and EVERYBODY gets turned off.
- */
-
-int sc_power_down_all(l1sc_t *sc)
-{
-    if( nodepda->num_routers > 0 ) {
-	return sc_command_interp( sc, L1_ADDR_TYPE_L2, L1_ADDR_RACK_LOCAL, 
-				  L1_ADDR_BAY_LOCAL, "* pwr d" );
-    }
-    else {
-	return sc_power_down( sc );
-    }
-}
-
-
-/*
- * iobrick routines
- */
-
-/* iobrick_rack_bay_type_get fills in the three int * arguments with the
- * rack number, bay number and brick type of the L1 being addressed.  Note
- * that if the L1 operation fails and this function returns an error value, 
- * garbage may be written to brick_type.
- */
-int iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack, 
-			       uint *bay, uint *brick_type )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t buf32;	        /* used to copy 32-bit rack & bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRBT, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, 
-			           L1_ARG_INT, brick_type ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    return 0;
-}
-
-
-int iobrick_module_get(l1sc_t *sc)
-{
-    uint rnum, rack, bay, brick_type, t;
-    int ret;
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = iobrick_rack_bay_type_get(sc, &rnum, &bay, &brick_type)) < 0)
-        return ret;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-        return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;           
-    t = rnum / 100;             /* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;              /* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;              /* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    switch( brick_type ) {
-      case 'I': 
-	brick_type = MODULE_IBRICK; break;
-      case 'P':
-	brick_type = MODULE_PBRICK; break;
-      case 'X':
-	brick_type = MODULE_XBRICK; break;
-    }
-
-    ret = RBT_TO_MODULE(rack, bay, brick_type);
-
-    return ret;
-}
-
-/*
- * iobrick_module_get_nasid() returns a module_id which has the brick
- * type encoded in bits 15-12, but this is not the true brick type...
- * The module_id returned by iobrick_module_get_nasid() is modified
- * to make a PEBRICKs & PXBRICKs look like a PBRICK.  So this routine
- * iobrick_type_get_nasid() returns the true unmodified brick type.
- */
-int
-iobrick_type_get_nasid(nasid_t nasid)
-{
-    l1sc_t *sc = get_elsc();
-    elsc_t tmp_sc;
-    uint rack, bay, type;
-    int t, ret;
-
-#ifdef PIC_LATER
-    if (PEBRICK_NODE(nasid)) {
-        if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) {
-            printf("Could not read rack and bay location "
-                   "of PEBrick at nasid %d\n", nasid);
-        }
-        if ((ret = peer_iobrick_type_get(sc, rack, bay, &type)) < 0)
-            return ret;
-    }
-    else
-#endif	/* PIC_LATER */
-    if (nasid != get_nasid()) { /* get the io_moduleid from remote node */
-        elsc_init(&tmp_sc, nasid);
-        if ((ret = iobrick_rack_bay_type_get(&tmp_sc, &rack, &bay, &type)) < 0)
-            return ret;
-    }
-    else {
-        if ((ret = iobrick_rack_bay_type_get(sc, &rack, &bay, &type)) < 0)
-            return ret;
-    }
-
-    /*
-     * Some brick_types need special treatment.  NOTE: This switch is
-     * duplicated in iobrick_module_get(),  so if you change this switch
-     * you must also change it there.
-     */
-    switch (type)
-    {
-    case L1_BRICKTYPE_IP45:
-        /* treat speedo2 like Ibrick for moduleid purposes */
-        type = L1_BRICKTYPE_I;
-        break;
-    case L1_BRICKTYPE_X2:
-        /* give X2 bricks the same moduleid as earlier models */
-        type = L1_BRICKTYPE_X;
-        break;
-    }
-
-    /* convert brick_type to lower case */
-    if ((type >= 'A') && (type <= 'Z'))
-        type = type - 'A' + 'a';
-
-    /* convert to a module.h brick type */
-    for( t = 0; t < MAX_BRICK_TYPES; t++ ) {
-        if( brick_types[t] == type )
-            return t;
-    }
-
-    return -1;    /* unknown brick */
-}
-
-int iobrick_module_get_nasid(nasid_t nasid)
-{
-    int io_moduleid;
-    l1sc_t *sc = get_elsc();
-    elsc_t tmp_sc;
-
-#ifdef PIC_LATER
-    uint rack, bay;
-
-    if (PEBRICK_NODE(nasid)) {
-        if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) {
-            printf("Could not read rack and bay location "
-                   "of PEBrick at nasid %d\n", nasid);
-        }
-
-        io_moduleid = peer_iobrick_module_get(sc, rack, bay);
-    }
-    else
-#endif	/* PIC_LATER */
-    if (nasid != get_nasid()) { /* get the io_moduleid from remote node */
-        elsc_init(&tmp_sc, nasid);
-
-        io_moduleid = iobrick_module_get(&tmp_sc);
-    }
-    else {
-        io_moduleid = iobrick_module_get(sc);
-    }
-
-    return io_moduleid;
-}
-
-
-/* iobrick_get_sys_snum asks the attached iobrick for the system
- * serial number.  This function will only be relevant to the master
- * cbrick (the one attached to the bootmaster ibrick); other nodes
- * may call the function, but the value returned to the master node
- * will be the one used as the system serial number by the kernel.
- */
-
-int
-iobrick_get_sys_snum( l1sc_t *sc, char *snum_str )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SYS_SERIAL, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    return( sc_interpret_resp( msg, 2, L1_ARG_ASCII, snum_str ) );
-}
-
-
-/*
- * The following functions apply (or cut off) power to the specified
- * pci bus or slot.
- */
-
-int
-iobrick_pci_pwr( l1sc_t *sc, int bus, int slot, int req_code )
-{
-#if 0 /* The "bedrock request" method of performing this function
-       * seems to be broken in the L1, so for now use the command-
-       * interpreter method
-       */
-
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCALIO );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 req_code, 4,
-				 L1_ARG_INT, bus,
-				 L1_ARG_INT, slot )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-
-#else
-    char cmd[64];
-    char *fxn;
-
-    switch( req_code )
-    {
-    case L1_REQ_PCI_UP:
-	fxn = "u";
-	break;
-    case L1_REQ_PCI_DOWN:
-	fxn = "d";
-	break;
-    case L1_REQ_PCI_RESET:
-	fxn = "rst";
-	break;
-    default:
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    if( slot == -1 ) 
-	sprintf( cmd, "pci %d %s", bus, fxn );
-    else
-        sprintf( cmd, "pci %d %d %s", bus, slot, fxn );
-	
-    return sc_command_interp( sc, L1_ADDR_TYPE_IOBRICK,
-	L1_ADDR_RACK_LOCAL, L1_ADDR_BAY_LOCAL, cmd );
-#endif
-}
-				 
-int
-iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up )
-{
-    return iobrick_pci_pwr( sc, bus, slot, up );
-}
-
-int
-iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up )
-{
-    return iobrick_pci_pwr( sc, bus, -1, up );
-}
-
-
-int
-iobrick_pci_slot_rst( l1sc_t *sc, int bus, int slot )
-{
-    return iobrick_pci_pwr( sc, bus, slot, L1_REQ_PCI_RESET );
-}
-
-int
-iobrick_pci_bus_rst( l1sc_t *sc, int bus )
-{
-    return iobrick_pci_pwr( sc, bus, -1, L1_REQ_PCI_RESET );
-}
-
-
-/* get the L1 firmware version for an iobrick */
-int
-iobrick_sc_version( l1sc_t *sc, char *result )
-{
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-    int		major,  /* major rev number */
-	        minor,  /* minor rev number */
-                bugfix; /* bugfix rev number */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCALIO );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_FW_REV, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major,
-			   L1_ARG_INT, &minor, L1_ARG_INT, &bugfix )
-	< 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    sprintf( result, "%d.%d.%d", major, minor, bugfix );
-
-    return 0;
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/mem_refcnt.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/mem_refcnt.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/mem_refcnt.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/mem_refcnt.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,220 +0,0 @@
-/* $Id: mem_refcnt.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/sn1/mem_refcnt.h>
-#include <asm/sn/sn1/hwcntrs.h>
-#include <asm/sn/sn1/hubspc.h>
-// From numa_hw.h
-
-#define MIGR_COUNTER_MAX_GET(nodeid) \
-        (NODEPDA_MCD((nodeid))->migr_system_kparms.migr_threshold_reference)
-/*
- * Get the Absolute Theshold
- */
-#define MIGR_THRESHOLD_ABS_GET(nodeid) ( \
-        MD_MIG_VALUE_THRESH_GET(COMPACT_TO_NASID_NODEID(nodeid)))
-/*
- * Get the current Differential Threshold
- */
-#define MIGR_THRESHOLD_DIFF_GET(nodeid) \
-        (NODEPDA_MCD(nodeid)->migr_as_kparms.migr_base_threshold)
-
-#define NUM_OF_HW_PAGES_PER_SW_PAGE()   (NBPP / MD_PAGE_SIZE)
-
-// #include "migr_control.h"
-
-int
-mem_refcnt_attach(devfs_handle_t hub)
-{
-#if 0
-        devfs_handle_t refcnt_dev;
-        
-        hwgraph_char_device_add(hub,
-                                "refcnt",
-                                "hubspc_", 
-				&refcnt_dev);
-        device_info_set(refcnt_dev, (void*)(ulong)HUBSPC_REFCOUNTERS);
-#endif
-
-        return (0);
-}
-
-
-/*ARGSUSED*/
-int
-mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp)
-{
-        cnodeid_t node;
-
-        node = master_node_get(*devp);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        if (NODEPDA(node)->migr_refcnt_counterbuffer == NULL) {
-                return (ENODEV);
-        }
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != (size_t)0 );
-
-        return (0);
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-        return 0;
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-        cnodeid_t node;
-        int errcode;
-        char* buffer;
-        size_t blen;
-        
-        node = master_node_get(dev);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
-
-        /*
-         * XXXX deal with prot's somewhere around here....
-         */
-
-        buffer = NODEPDA(node)->migr_refcnt_counterbuffer;
-        blen = NODEPDA(node)->migr_refcnt_cbsize;
-
-        /*
-         * Force offset to be a multiple of sizeof(refcnt_t)
-         * We round up.
-         */
-
-        off = (((off - 1)/sizeof(refcnt_t)) + 1) * sizeof(refcnt_t);
-
-        if ( ((buffer + blen) - (buffer + off + len)) < 0 ) {
-                return (EPERM);
-        }
-
-        errcode = v_mapphys(vt,
-                            buffer + off,
-                            len);
-
-        return errcode;
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-        return 0;
-}
-
-/* ARGSUSED */
-int
-mem_refcnt_ioctl(devfs_handle_t dev,
-                 int cmd,
-                 void *arg,
-                 int mode,
-                 cred_t *cred_p,
-                 int *rvalp)
-{
-        cnodeid_t node;
-        int errcode;
-	extern int numnodes;
-        
-        node = master_node_get(dev);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
-
-        errcode = 0;
-        
-        switch (cmd) {
-        case RCB_INFO_GET:
-        {
-                rcb_info_t rcb;
-                
-                rcb.rcb_len = NODEPDA(node)->migr_refcnt_cbsize;
-                
-                rcb.rcb_sw_sets = NODEPDA(node)->migr_refcnt_numsets;
-                rcb.rcb_sw_counters_per_set = numnodes;
-                rcb.rcb_sw_counter_size = sizeof(refcnt_t);
-
-                rcb.rcb_base_pages = NODEPDA(node)->migr_refcnt_numsets /
-                                     NUM_OF_HW_PAGES_PER_SW_PAGE();  
-                rcb.rcb_base_page_size = NBPP;
-                rcb.rcb_base_paddr = ctob(slot_getbasepfn(node, 0));
-                
-                rcb.rcb_cnodeid = node;
-                rcb.rcb_granularity = MD_PAGE_SIZE;
-#ifdef LATER
-                rcb.rcb_hw_counter_max = MIGR_COUNTER_MAX_GET(node);
-                rcb.rcb_diff_threshold = MIGR_THRESHOLD_DIFF_GET(node);
-#endif
-                rcb.rcb_abs_threshold = MIGR_THRESHOLD_ABS_GET(node);
-                rcb.rcb_num_slots = MAX_MEM_SLOTS;
-
-                if (COPYOUT(&rcb, arg, sizeof(rcb_info_t))) {
-                        errcode = EFAULT;
-                }
-
-                break;
-        }
-        case RCB_SLOT_GET:
-        {
-                rcb_slot_t slot[MAX_MEM_SLOTS];
-                int s;
-                int nslots;
-
-                nslots = MAX_MEM_SLOTS;
-                ASSERT(nslots <= MAX_MEM_SLOTS);
-                for (s = 0; s < nslots; s++) {
-                        slot[s].base = (uint64_t)ctob(slot_getbasepfn(node, s));
-#ifdef LATER
-                        slot[s].size  = (uint64_t)ctob(slot_getsize(node, s));
-#else
-                        slot[s].size  = (uint64_t)1;
-#endif
-                }
-                if (COPYOUT(&slot[0], arg, nslots * sizeof(rcb_slot_t))) {
-                        errcode = EFAULT;
-                }
-                
-                *rvalp = nslots;
-                break;
-        }
-                
-        default:
-                errcode = EINVAL;
-                break;
-
-        }
-        
-        return errcode;
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/ml_SN_init.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/ml_SN_init.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/ml_SN_init.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/ml_SN_init.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,211 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/bootmem.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/snconfig.h>
-
-extern int numcpus;
-extern char arg_maxnodes[];
-extern cpuid_t master_procid;
-extern synergy_da_t    *Synergy_da_indr[];
-
-extern int hasmetarouter;
-
-int		maxcpus;
-cpumask_t	boot_cpumask;
-hubreg_t	region_mask = 0;
-
-
-extern xwidgetnum_t hub_widget_id(nasid_t);
-
-extern int valid_icache_reasons;	/* Reasons to flush the icache */
-extern int valid_dcache_reasons;	/* Reasons to flush the dcache */
-extern u_char miniroot;
-extern volatile int	need_utlbmiss_patch;
-extern void iograph_early_init(void);
-
-nasid_t master_nasid = INVALID_NASID;
-
-
-/*
- * mlreset(int slave)
- * 	very early machine reset - at this point NO interrupts have been
- * 	enabled; nor is memory, tlb, p0, etc setup.
- *
- * 	slave is zero when mlreset is called for the master processor and
- *	is nonzero thereafter.
- */
-
-
-void
-mlreset(int slave)
-{
-	if (!slave) {
-		/*
-		 * We are the master cpu and node.
-		 */ 
-		master_nasid = get_nasid();
-		set_master_bridge_base();
-
-		/* We're the master processor */
-		master_procid = smp_processor_id();
-		master_nasid = cpuid_to_nasid(master_procid);
-
-		/*
-		 * master_nasid we get back better be same as one from
-		 * get_nasid()
-		 */
-		ASSERT_ALWAYS(master_nasid == get_nasid());
-
-		/* early initialization of iograph */
-		iograph_early_init();
-
-		/* Initialize Hub Pseudodriver Management */
-		hubdev_init();
-
-	} else { /* slave != 0 */
-		/*
-		 * This code is performed ONLY by slave processors.
-		 */
-
-	}
-}
-
-
-/* XXX - Move the meat of this to intr.c ? */
-/*
- * Set up the platform-dependent fields in the nodepda.
- */
-void init_platform_nodepda(nodepda_t *npda, cnodeid_t node)
-{
-	hubinfo_t hubinfo;
-	int	  sn;
-
-	extern void router_map_init(nodepda_t *);
-	extern void router_queue_init(nodepda_t *,cnodeid_t);
-	extern void intr_init_vecblk(nodepda_t *, cnodeid_t, int);
-
-	/* Allocate per-node platform-dependent data */
-	hubinfo = (hubinfo_t)alloc_bootmem_node(NODE_DATA(node), sizeof(struct hubinfo_s));
-
-	npda->pdinfo = (void *)hubinfo;
-	hubinfo->h_nodepda = npda;
-	hubinfo->h_cnodeid = node;
-	hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(node);
-
-	spin_lock_init(&hubinfo->h_crblock);
-
-	hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid);
-	npda->xbow_peer = INVALID_NASID;
-
-	/* 
-	 * Initialize the linked list of
-	 * router info pointers to the dependent routers
-	 */
-	npda->npda_rip_first = NULL;
-
-	/*
-	 * npda_rip_last always points to the place
-	 * where the next element is to be inserted
-	 * into the list 
-	 */
-	npda->npda_rip_last = &npda->npda_rip_first;
-	npda->module_id = INVALID_MODULE;
-
-	/*
-	* Initialize the interrupts.
-	* On sn2, this is done at pci init time,
-	* because sn2 needs the cpus checked in
-	* when it initializes interrupts.  This is
-	* so we don't see all the nodes as headless.
-	*/
-	for (sn=0; sn<NUM_SUBNODES; sn++) {
-		intr_init_vecblk(npda, node, sn);
-	}
-
-	mutex_init_locked(&npda->xbow_sema); /* init it locked? */
-}
-
-/* XXX - Move the interrupt stuff to intr.c ? */
-/*
- * Set up the platform-dependent fields in the processor pda.
- * Must be done _after_ init_platform_nodepda().
- * If we need a lock here, something else is wrong!
- */
-void init_platform_pda(cpuid_t cpu)
-{
-	hub_intmasks_t *intmasks;
-	int i, subnode;
-	cnodeid_t	cnode;
-	synergy_da_t	*sda;
-	int	which_synergy;
-
-
-	cnode = cpuid_to_cnodeid(cpu);
-	which_synergy = cpuid_to_synergy(cpu);
-
-	sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-	intmasks = &sda->s_intmasks;
-
-	/* Clear INT_PEND0 masks. */
-	for (i = 0; i < N_INTPEND0_MASKS; i++)
-		intmasks->intpend0_masks[i] = 0;
-
-	/* Set up pointer to the vector block in the nodepda. */
-	/* (Cant use SUBNODEPDA - not working yet) */
-	subnode = cpuid_to_subnode(cpu);
-	intmasks->dispatch0 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch0;
-	intmasks->dispatch1 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch1;
-	if (intmasks->dispatch0 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch0 ||
-	   intmasks->dispatch1 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch1)
-	   	panic("xxx");
-	intmasks->dispatch0 = &SUBNODEPDA(cnode, subnode)->intr_dispatch0;
-	intmasks->dispatch1 = &SUBNODEPDA(cnode, subnode)->intr_dispatch1;
-
-	/* Clear INT_PEND1 masks. */
-	for (i = 0; i < N_INTPEND1_MASKS; i++)
-		intmasks->intpend1_masks[i] = 0;
-}
-
-void
-update_node_information(cnodeid_t cnodeid)
-{
-	nodepda_t *npda = NODEPDA(cnodeid);
-	nodepda_router_info_t *npda_rip;
-	
-	/* Go through the list of router info 
-	 * structures and copy some frequently
-	 * accessed info from the info hanging
-	 * off the corresponding router vertices
-	 */
-	npda_rip = npda->npda_rip_first;
-	while(npda_rip) {
-		if (npda_rip->router_infop) {
-			npda_rip->router_portmask = 
-				npda_rip->router_infop->ri_portmask;
-			npda_rip->router_slot = 
-				npda_rip->router_infop->ri_slotnum;
-		} else {
-			/* No router, no ports. */
-			npda_rip->router_portmask = 0;
-		}
-		npda_rip = npda_rip->router_next;
-	}
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/ml_SN_intr.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/ml_SN_intr.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/ml_SN_intr.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/ml_SN_intr.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1154 +0,0 @@
-/* $Id: ml_SN_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * intr.c-
- *	This file contains all of the routines necessary to set up and
- *	handle interrupts on an IP27 board.
- */
-
-#ident  "$Revision: 1.1 $"
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/smp.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/intr.h>
-
-
-#if DEBUG_INTR_TSTAMP_DEBUG
-#include <sys/debug.h>
-#include <sys/idbg.h>
-#include <sys/inst.h>
-void do_splx_log(int, int);
-void spldebug_log_event(int);
-#endif
-
-#ifdef CONFIG_SMP
-extern unsigned long cpu_online_map;
-#endif
-#define cpu_allows_intr(cpu)	(1)
-// If I understand what's going on with this, 32 should work.
-// physmem_maxradius seems to be the maximum number of router
-// hops to get from one end of the system to the other.  With
-// a maximally configured machine, with the dumbest possible
-// topology, we would make 32 router hops.  For what we're using
-// it for, the dumbest possible should suffice.
-#define physmem_maxradius()	32
-
-#define SUBNODE_ANY (-1)
-
-extern int	nmied;
-extern int	hub_intr_wakeup_cnt;
-extern synergy_da_t	*Synergy_da_indr[];
-extern cpuid_t         master_procid;
-
-extern cnodeid_t master_node_get(devfs_handle_t vhdl);
-
-extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
-
-
-#define INTR_LOCK(vecblk) \
-     (s = mutex_spinlock(&(vecblk)->vector_lock))
-#define INTR_UNLOCK(vecblk) \
-      mutex_spinunlock(&(vecblk)->vector_lock, s)
-
-/*
- * REACT/Pro
- */
-
-
-
-/* 
- * Find first bit set 
- * Used outside this file also 
- */
-int ms1bit(unsigned long x)
-{
-    int			b;
-
-    if (x >> 32)	b  = 32, x >>= 32;
-    else		b  =  0;
-    if (x >> 16)	b += 16, x >>= 16;
-    if (x >>  8)	b +=  8, x >>=  8;
-    if (x >>  4)	b +=  4, x >>=  4;
-    if (x >>  2)	b +=  2, x >>=  2;
-
-    return b + (int) (x >> 1);
-}
-
-/* ARGSUSED */
-void
-intr_stray(void *lvl)
-{
-    printk(KERN_WARNING  "Stray Interrupt - level %ld to cpu %d", (long)lvl, smp_processor_id());
-}
-
-#if defined(DEBUG)
-
-/* Infrastructure  to gather the device - target cpu mapping info */
-#define MAX_DEVICES	1000	/* Reasonable large number . Need not be 
-				 * the exact maximum # devices possible.
-				 */
-#define MAX_NAME	100	
-typedef struct {
-	dev_t		dev;	/* device */
-	cpuid_t		cpuid;	/* target cpu */
-	cnodeid_t	cnodeid;/* node on which the target cpu is present */
-	int		bit;	/* intr bit reserved */
-	char		intr_name[MAX_NAME]; /* name of the interrupt */
-} intr_dev_targ_map_t;
-
-intr_dev_targ_map_t 	intr_dev_targ_map[MAX_DEVICES];
-uint64_t		intr_dev_targ_map_size;
-spinlock_t		intr_dev_targ_map_lock;
-
-/* Print out the device - target cpu mapping.
- * This routine is used only in the idbg command
- * "intrmap" 
- */
-void
-intr_dev_targ_map_print(cnodeid_t cnodeid)
-{
-	int  i,j,size = 0;
-	int  print_flag = 0,verbose = 0;	
-	char node_name[10];
-	
-	if (cnodeid != CNODEID_NONE) {
-		nodepda_t 	*npda;
-
-		npda = NODEPDA(cnodeid);
-		for (j=0; j<NUM_SUBNODES; j++) {
-			qprintf("\n SUBNODE %d\n INT_PEND0: ", j);
-			for(i = 0 ; i < N_INTPEND_BITS ; i++)
-				qprintf("%d",SNPDA(npda,j)->intr_dispatch0.info[i].ii_flags);
-			qprintf("\n INT_PEND1: ");
-			for(i = 0 ; i < N_INTPEND_BITS ; i++)
-				qprintf("%d",SNPDA(npda,j)->intr_dispatch1.info[i].ii_flags);
-		}
-		verbose = 1;
-	}
-	qprintf("\n Device - Target Map [Interrupts: %s Node%s]\n\n",
-		(verbose ? "All" : "Non-hardwired"),
-		(cnodeid == CNODEID_NONE) ? "s: All" : node_name); 
-		
-	qprintf("Device\tCpu\tCnode\tIntr_bit\tIntr_name\n");
-	for (i = 0 ; i < intr_dev_targ_map_size ; i++) {
-
-		print_flag = 0;
-		if (verbose) {
-			if (cnodeid != CNODEID_NONE) {
-				if (cnodeid == intr_dev_targ_map[i].cnodeid)
-					print_flag = 1;
-			} else {
-				print_flag = 1;
-			}
-		} else {
-			if (intr_dev_targ_map[i].dev != 0) {
-				if (cnodeid != CNODEID_NONE) {
-					if (cnodeid == 
-					    intr_dev_targ_map[i].cnodeid)
-						print_flag = 1;
-				} else {
-					print_flag = 1;
-				}
-			}
-		}
-		if (print_flag) {
-			size++;
-			qprintf("%d\t%d\t%d\t%d\t%s\n",
-				intr_dev_targ_map[i].dev,
-				intr_dev_targ_map[i].cpuid,
-				intr_dev_targ_map[i].cnodeid,
-				intr_dev_targ_map[i].bit,
-				intr_dev_targ_map[i].intr_name);
-		}
-
-	}
-	qprintf("\nTotal : %d\n",size);
-}
-#endif /* DEBUG */
-
-/*
- * The spinlocks have already been initialized.  Now initialize the interrupt
- * vectors.  One processor on each hub does the work.
- */
-void
-intr_init_vecblk(nodepda_t *npda, cnodeid_t node, int sn)
-{
-    int			i, ip=0;
-    intr_vecblk_t	*vecblk;
-    subnode_pda_t	*snpda;
-
-
-    snpda = SNPDA(npda,sn);
-    do {
-	if (ip == 0) {
-	    vecblk = &snpda->intr_dispatch0;
-	} else {
-	    vecblk = &snpda->intr_dispatch1;
-	}
-
-	/* Initialize this vector. */
-	for (i = 0; i < N_INTPEND_BITS; i++) {
-		vecblk->vectors[i].iv_func = intr_stray;
-		vecblk->vectors[i].iv_prefunc = NULL;
-		vecblk->vectors[i].iv_arg = (void *)(__psint_t)(ip * N_INTPEND_BITS + i);
-
-		vecblk->info[i].ii_owner_dev = 0;
-		strcpy(vecblk->info[i].ii_name, "Unused");
-		vecblk->info[i].ii_flags = 0;	/* No flags */
-		vecblk->vectors[i].iv_mustruncpu = -1; /* No CPU yet. */
-
-	    }
-
-	mutex_spinlock_init(&vecblk->vector_lock);
-
-	vecblk->vector_count = 0;    
-	for (i = 0; i < CPUS_PER_SUBNODE; i++)
-		vecblk->cpu_count[i] = 0;
-
-	vecblk->vector_state = VECTOR_UNINITED;
-
-    } while (++ip < 2);
-
-}
-
-
-/*
- * do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, 
- *					devfs_handle_t owner_dev, char *name)
- *	Internal work routine to reserve or unreserve an interrupt level.
- *		cpu is the CPU to which the interrupt will be sent.
- *		bit is the level bit to reserve.  -1 means any level
- *		resflags should include II_ERRORINT if this is an
- *			error interrupt, II_THREADED if the interrupt handler
- *			will be threaded, or 0 otherwise.
- *		reserve should be set to II_RESERVE or II_UNRESERVE
- *			to get or clear a reservation.
- *		owner_dev is the device that "owns" this interrupt, if supplied
- *		name is a human-readable name for this interrupt, if supplied
- *	intr_reserve_level returns the bit reserved or -1 to indicate an error
- */
-static int
-do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, 
-					devfs_handle_t owner_dev, char *name)
-{
-    intr_vecblk_t	*vecblk;
-    hub_intmasks_t 	*hub_intmasks;
-    unsigned long s;
-    int rv = 0;
-    int ip;
-    synergy_da_t	*sda;
-    int		which_synergy;
-    cnodeid_t	cnode;
-
-    ASSERT(bit < N_INTPEND_BITS * 2);
-
-    cnode = cpuid_to_cnodeid(cpu);
-    which_synergy = cpuid_to_synergy(cpu);
-    sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-    hub_intmasks = &sda->s_intmasks;
-    // hub_intmasks = &pdaindr[cpu].pda->p_intmasks;
-
-    // if (pdaindr[cpu].pda == NULL) return -1;
-    if ((bit < N_INTPEND_BITS) && !(resflags & II_ERRORINT)) {
-	vecblk = hub_intmasks->dispatch0;
-	ip = 0;
-    } else {
-	ASSERT((bit >= N_INTPEND_BITS) || (bit == -1));
-	bit -= N_INTPEND_BITS;	/* Get position relative to INT_PEND1 reg. */
-	vecblk = hub_intmasks->dispatch1;
-	ip = 1;
-    }
-
-    INTR_LOCK(vecblk);
-
-    if (bit <= -1) {
-	bit = 0;
-	ASSERT(reserve == II_RESERVE);
-	/* Choose any available level */
-	for (; bit < N_INTPEND_BITS; bit++) {
-	    if (!(vecblk->info[bit].ii_flags & II_RESERVE)) {
-		rv = bit;
-		break;
-	    }
-	}
-
-	/* Return -1 if all interrupt levels int this register are taken. */
-	if (bit == N_INTPEND_BITS)
-	    rv = -1;
-
-    } else {
-	/* Reserve a particular level if it's available. */
-	if ((vecblk->info[bit].ii_flags & II_RESERVE) == reserve) {
-	    /* Can't (un)reserve a level that's already (un)reserved. */
-	    rv = -1;
-	} else {
-	    rv = bit;
-	}
-    }
-
-    /* Reserve the level and bump the count. */
-    if (rv != -1) {
-	if (reserve) {
-	    int maxlen = sizeof(vecblk->info[bit].ii_name) - 1;
-	    int namelen;
-	    vecblk->info[bit].ii_flags |= (II_RESERVE | resflags);
-	    vecblk->info[bit].ii_owner_dev = owner_dev;
-	    /* Copy in the name. */
-	    namelen = name ? strlen(name) : 0;
-	    strncpy(vecblk->info[bit].ii_name, name, min(namelen, maxlen)); 
-	    vecblk->info[bit].ii_name[maxlen] = '\0';
-	    vecblk->vector_count++;
-	} else {
-	    vecblk->info[bit].ii_flags = 0;	/* Clear all the flags */
-	    vecblk->info[bit].ii_owner_dev = 0;
-	    /* Clear the name. */
-	    vecblk->info[bit].ii_name[0] = '\0';
-	    vecblk->vector_count--;
-	}
-    }
-
-    INTR_UNLOCK(vecblk);
-
-#if defined(DEBUG)
-    if (rv >= 0) {
-	    int namelen = name ? strlen(name) : 0;
-	    /* Gather this device - target cpu mapping information
-	     * in a table which can be used later by the idbg "intrmap"
-	     * command
-	     */
-	    s = mutex_spinlock(&intr_dev_targ_map_lock);
-	    if (intr_dev_targ_map_size < MAX_DEVICES) {
-		    intr_dev_targ_map_t	*p;
-
-		    p 		= &intr_dev_targ_map[intr_dev_targ_map_size];
-		    p->dev  	= owner_dev;
-		    p->cpuid 	= cpu; 
-		    p->cnodeid 	= cpuid_to_cnodeid(cpu); 
-		    p->bit 	= ip * N_INTPEND_BITS + rv;
-		    strncpy(p->intr_name,
-			    name,
-			    min(MAX_NAME,namelen));
-		    intr_dev_targ_map_size++;
-	    }
-	    mutex_spinunlock(&intr_dev_targ_map_lock,s);
-    }
-#endif /* DEBUG */
-
-    return (((rv == -1) ? rv : (ip * N_INTPEND_BITS) + rv)) ;
-}
-
-
-/*
- * WARNING:  This routine should only be called from within ml/SN.
- *	Reserve an interrupt level.
- */
-int
-intr_reserve_level(cpuid_t cpu, int bit, int resflags, devfs_handle_t owner_dev, char *name)
-{
-	return(do_intr_reserve_level(cpu, bit, resflags, II_RESERVE, owner_dev, name));
-}
-
-
-/*
- * WARNING:  This routine should only be called from within ml/SN.
- *	Unreserve an interrupt level.
- */
-void
-intr_unreserve_level(cpuid_t cpu, int bit)
-{
-	(void)do_intr_reserve_level(cpu, bit, 0, II_UNRESERVE, 0, NULL);
-}
-
-/*
- * Get values that vary depending on which CPU and bit we're operating on
- */
-static hub_intmasks_t *
-intr_get_ptrs(cpuid_t cpu, int bit,
-	      int *new_bit,		/* Bit relative to the register */
-	      hubreg_t **intpend_masks, /* Masks for this register */
-	      intr_vecblk_t **vecblk,	/* Vecblock for this interrupt */
-	      int *ip)			/* Which intpend register */
-{
-	hub_intmasks_t *hub_intmasks;
-	synergy_da_t	*sda;
-	int		which_synergy;
-	cnodeid_t	cnode;
-
-	ASSERT(bit < N_INTPEND_BITS * 2);
-
-	cnode = cpuid_to_cnodeid(cpu);
-	which_synergy = cpuid_to_synergy(cpu);
-	sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-	hub_intmasks = &sda->s_intmasks;
-
-	// hub_intmasks = &pdaindr[cpu].pda->p_intmasks;
-
-	if (bit < N_INTPEND_BITS) {
-		*intpend_masks = hub_intmasks->intpend0_masks;
-		*vecblk = hub_intmasks->dispatch0;
-		*ip = 0;
-		*new_bit = bit;
-	} else {
-		*intpend_masks = hub_intmasks->intpend1_masks;
-		*vecblk = hub_intmasks->dispatch1;
-		*ip = 1;
-		*new_bit = bit - N_INTPEND_BITS;
-	}
-
-	return hub_intmasks;
-}
-
-
-/*
- * intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, 
- *		intr_func_t intr_func, void *intr_arg);
- *	This is the lowest-level interface to the interrupt code.  It shouldn't
- *	be called from outside the ml/SN directory.
- *	intr_connect_level hooks up an interrupt to a particular bit in
- *	the INT_PEND0/1 masks.  Returns 0 on success.
- *		cpu is the CPU to which the interrupt will be sent.
- *		bit is the level bit to connect to
- *		intr_swlevel tells which software level to use
- *		intr_func is the interrupt handler
- *		intr_arg is an arbitrary argument interpreted by the handler
- *		intr_prefunc is a prologue function, to be called
- *			with interrupts disabled, to disable
- *			the interrupt at source.  It is called
- *			with the same argument.  Should be NULL for
- *			typical interrupts, which can be masked
- *			by the infrastructure at the level bit.
- *	intr_connect_level returns 0 on success or nonzero on an error
- */
-/* ARGSUSED */
-int
-intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, intr_func_t intr_prefunc)
-{
-    intr_vecblk_t	*vecblk;
-    hubreg_t		*intpend_masks;
-    int rv = 0;
-    int ip;
-    unsigned long s;
-
-    ASSERT(bit < N_INTPEND_BITS * 2);
-
-    (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks,
-				 &vecblk, &ip);
-
-    INTR_LOCK(vecblk);
-
-    if ((vecblk->info[bit].ii_flags & II_INUSE) ||
-	(!(vecblk->info[bit].ii_flags & II_RESERVE))) {
-	/* Can't assign to a level that's in use or isn't reserved. */
-	rv = -1;
-    } else {
-	/* Stuff parameters into vector and info */
-	vecblk->vectors[bit].iv_prefunc = intr_prefunc;
-	vecblk->info[bit].ii_flags |= II_INUSE;
-    }
-
-    /* Now stuff the masks if everything's okay. */
-    if (!rv) {
-	int lslice;
-	volatile hubreg_t *mask_reg;
-	// nasid_t nasid = COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu));
-	nasid_t nasid = cpuid_to_nasid(cpu);
-	int	subnode = cpuid_to_subnode(cpu);
-
-	/* Make sure it's not already pending when we connect it. */
-	REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit + ip * N_INTPEND_BITS);
-
-	if (bit >= GFX_INTR_A && bit <= CC_PEND_B) {
-		intpend_masks[0] |= (1ULL << (uint64_t)bit);
-	}
-
-	lslice = cpuid_to_localslice(cpu);
-	vecblk->cpu_count[lslice]++;
-#if SN1
-	/*
-	 * On SN1, there are 8 interrupt mask registers per node:
-	 * 	PI_0 MASK_0 A
-	 * 	PI_0 MASK_1 A
-	 * 	PI_0 MASK_0 B
-	 * 	PI_0 MASK_1 B
-	 * 	PI_1 MASK_0 A
-	 * 	PI_1 MASK_1 A
-	 * 	PI_1 MASK_0 B
-	 * 	PI_1 MASK_1 B
-	 */
-#endif
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode, 
-		        PI_INT_MASK0_A + PI_INT_MASK_OFFSET * lslice);
-	} else {
-		mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode,
-			PI_INT_MASK1_A + PI_INT_MASK_OFFSET * lslice);
-	}
-
-	HUB_S(mask_reg, intpend_masks[0]);
-    }
-
-    INTR_UNLOCK(vecblk);
-
-    return rv;
-}
-
-
-/*
- * intr_disconnect_level(cpuid_t cpu, int bit)
- *
- *	This is the lowest-level interface to the interrupt code.  It should
- *	not be called from outside the ml/SN directory.
- *	intr_disconnect_level removes a particular bit from an interrupt in
- * 	the INT_PEND0/1 masks.  Returns 0 on success or nonzero on failure.
- */
-int
-intr_disconnect_level(cpuid_t cpu, int bit)
-{
-    intr_vecblk_t	*vecblk;
-    hubreg_t		*intpend_masks;
-    unsigned long s;
-    int rv = 0;
-    int ip;
-
-    (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks,
-				 &vecblk, &ip);
-
-    INTR_LOCK(vecblk);
-
-    if ((vecblk->info[bit].ii_flags & (II_RESERVE | II_INUSE)) !=
-	((II_RESERVE | II_INUSE))) {
-	/* Can't remove a level that's not in use or isn't reserved. */
-	rv = -1;
-    } else {
-	/* Stuff parameters into vector and info */
-	vecblk->vectors[bit].iv_func = (intr_func_t)NULL;
-	vecblk->vectors[bit].iv_prefunc = (intr_func_t)NULL;
-	vecblk->vectors[bit].iv_arg = 0;
-	vecblk->info[bit].ii_flags &= ~II_INUSE;
-#ifdef BASE_ITHRTEAD
-	vecblk->vectors[bit].iv_mustruncpu = -1; /* No mustrun CPU any more. */
-#endif
-    }
-
-    /* Now clear the masks if everything's okay. */
-    if (!rv) {
-	int lslice;
-	volatile hubreg_t *mask_reg;
-
-	intpend_masks[0] &= ~(1ULL << (uint64_t)bit);
-	lslice = cpuid_to_localslice(cpu);
-	vecblk->cpu_count[lslice]--;
-	mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
-				   cpuid_to_subnode(cpu),
-				   ip == 0 ? PI_INT_MASK0_A : PI_INT_MASK1_A);
-	mask_reg = (volatile hubreg_t *)((__psunsigned_t)mask_reg +
-					(PI_INT_MASK_OFFSET * lslice));
-	*mask_reg = intpend_masks[0];
-    }
-
-    INTR_UNLOCK(vecblk);
-
-    return rv;
-}
-
-/*
- * Actually block or unblock an interrupt
- */
-void
-do_intr_block_bit(cpuid_t cpu, int bit, int block)
-{
-	intr_vecblk_t *vecblk;
-	int ip;
-	unsigned long s;
-	hubreg_t *intpend_masks;
-	volatile hubreg_t mask_value;
-	volatile hubreg_t *mask_reg;
-
-	intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &vecblk, &ip);
-
-	INTR_LOCK(vecblk);
-
-	if (block)
-		/* Block */
-		intpend_masks[0] &= ~(1ULL << (uint64_t)bit);
-	else
-		/* Unblock */
-		intpend_masks[0] |= (1ULL << (uint64_t)bit);
-
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
-		        cpuid_to_subnode(cpu), PI_INT_MASK0_A);
-	} else {
-		mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
-			cpuid_to_subnode(cpu), PI_INT_MASK1_A);
-	}
-
-	HUB_S(mask_reg, intpend_masks[0]);
-
-	/*
-	 * Wait for it to take effect.  (One read should suffice.)
-	 * This is only necessary when blocking an interrupt
-	 */
-	if (block)
-		while ((mask_value = HUB_L(mask_reg)) != intpend_masks[0])
-			;
-
-	INTR_UNLOCK(vecblk);
-}
-
-
-/*
- * Block a particular interrupt (cpu/bit pair).
- */
-/* ARGSUSED */
-void
-intr_block_bit(cpuid_t cpu, int bit)
-{
-	do_intr_block_bit(cpu, bit, 1);
-}
-
-
-/*
- * Unblock a particular interrupt (cpu/bit pair).
- */
-/* ARGSUSED */
-void
-intr_unblock_bit(cpuid_t cpu, int bit)
-{
-	do_intr_block_bit(cpu, bit, 0);
-}
-
-
-/* verifies that the specified CPUID is on the specified SUBNODE (if any) */
-#define cpu_on_subnode(cpuid, which_subnode) \
-	   (((which_subnode) == SUBNODE_ANY) || (cpuid_to_subnode(cpuid) == (which_subnode)))
-
-
-/*
- * Choose one of the CPUs on a specified node or subnode to receive
- * interrupts. Don't pick a cpu which has been specified as a NOINTR cpu.
- *
- * Among all acceptable CPUs, the CPU that has the fewest total number
- * of interrupts targetted towards it is chosen.  Note that we never
- * consider how frequent each of these interrupts might occur, so a rare
- * hardware error interrupt is weighted equally with a disk interrupt.
- */
-static cpuid_t
-do_intr_cpu_choose(cnodeid_t cnode, int which_subnode)
-{
-	cpuid_t 	cpu, best_cpu = CPU_NONE;
-	int		slice, min_count=1000;
-
-	min_count = 1000;
-	for (slice=0; slice < CPUS_PER_NODE; slice++) {
-		intr_vecblk_t 	*vecblk0, *vecblk1;
-		int total_intrs_to_slice;
-		subnode_pda_t *snpda;
-		int local_cpu_num;
-
-		cpu = cnode_slice_to_cpuid(cnode, slice);
-		if (cpu == CPU_NONE)
-			continue;
-
-		/* If this cpu isn't enabled for interrupts, skip it */
-		if (!cpu_enabled(cpu) || !cpu_allows_intr(cpu))
-			continue;
-
-		/* If this isn't the right subnode, skip it */
-		if (!cpu_on_subnode(cpu, which_subnode))
-			continue;
-
-		/* OK, this one's a potential CPU for interrupts */
-		snpda = SUBNODEPDA(cnode,SUBNODE(slice));
-		vecblk0 = &snpda->intr_dispatch0;
-		vecblk1 = &snpda->intr_dispatch1;
-		local_cpu_num = LOCALCPU(slice);
-		total_intrs_to_slice = vecblk0->cpu_count[local_cpu_num] +
-		              vecblk1->cpu_count[local_cpu_num];
-
-		if (min_count > total_intrs_to_slice) {
-			min_count = total_intrs_to_slice;
-			best_cpu = cpu;
-		}
-	}
-	return best_cpu;
-}
-
-/*
- * Choose an appropriate interrupt target CPU on a specified node.
- * If which_subnode is SUBNODE_ANY, then subnode is not considered.
- * Otherwise, the chosen CPU must be on the specified subnode.
- */
-static cpuid_t
-intr_cpu_choose_from_node(cnodeid_t cnode, int which_subnode)
-{
-	return(do_intr_cpu_choose(cnode, which_subnode));
-}
-
-
-/* Make it easy to identify subnode vertices in the hwgraph */
-void
-mark_subnodevertex_as_subnode(devfs_handle_t vhdl, int which_subnode)
-{
-	graph_error_t rv;
-
-	ASSERT(0 <= which_subnode);
-	ASSERT(which_subnode < NUM_SUBNODES);
-
-	rv = hwgraph_info_add_LBL(vhdl, INFO_LBL_CPUBUS, (arbitrary_info_t)which_subnode);
-	ASSERT_ALWAYS(rv == GRAPH_SUCCESS);
-
-	rv = hwgraph_info_export_LBL(vhdl, INFO_LBL_CPUBUS, sizeof(arbitrary_info_t));
-	ASSERT_ALWAYS(rv == GRAPH_SUCCESS);
-}
-
-
-/*
- * Given a device descriptor, extract interrupt target information and
- * choose an appropriate CPU.  Return CPU_NONE if we can't make sense
- * out of the target information.
- * TBD: Should this be considered platform-independent code?
- */
-
-
-/*
- * intr_bit_reserve_test(cpuid,which_subnode,cnode,req_bit,intr_resflags,
- *		owner_dev,intr_name,*resp_bit)
- *	Either cpuid is not CPU_NONE or cnodeid not CNODE_NONE but
- * 	not both.
- * 1. 	If cpuid is specified, this routine tests if this cpu can be a valid
- * 	interrupt target candidate.
- * 2. 	If cnodeid is specified, this routine tests if there is a cpu on 
- *	this node which can be a valid interrupt target candidate.
- * 3.	If a valid interrupt target cpu candidate is found then an attempt at 
- * 	reserving an interrupt bit on the corresponding cnode is made.
- *
- * If steps 1 & 2 both fail or step 3 fails then we are not able to get a valid
- * interrupt target cpu then routine returns CPU_NONE (failure)
- * Otherwise routine returns cpuid of interrupt target (success)
- */
-static cpuid_t
-intr_bit_reserve_test(cpuid_t 		cpuid,
-		      int		favor_subnode,
-		      cnodeid_t 	cnodeid,
-		      int		req_bit,
-		      int 		intr_resflags,
-		      devfs_handle_t 	owner_dev,
-		      char		*intr_name,
-		      int		*resp_bit)
-{
-
-	ASSERT((cpuid==CPU_NONE) || (cnodeid==CNODEID_NONE));
-
-	if (cnodeid != CNODEID_NONE) {
-		/* Try to choose a interrupt cpu candidate */
-		cpuid = intr_cpu_choose_from_node(cnodeid, favor_subnode);
-	}
-
-	if (cpuid != CPU_NONE) {
-		/* Try to reserve an interrupt bit on the hub 
-		 * corresponding to the canidate cnode. If we
-		 * are successful then we got a cpu which can
-		 * act as an interrupt target for the io device.
-		 * Otherwise we need to continue the search
-		 * further.
-		 */
-		*resp_bit = do_intr_reserve_level(cpuid, 
-						  req_bit,
-						  intr_resflags,
-						  II_RESERVE,
-						  owner_dev, 
-						  intr_name);
-
-		if (*resp_bit >= 0)
-			/* The interrupt target  specified was fine */
-			return(cpuid);
-	}
-	return(CPU_NONE);
-}
-/*
- * intr_heuristic(dev_t dev,device_desc_t dev_desc,
- *		  int req_bit,int intr_resflags,dev_t owner_dev,
- *		  char *intr_name,int *resp_bit)
- *
- * Choose an interrupt destination for an interrupt.
- *	dev is the device for which the interrupt is being set up
- *	dev_desc is a description of hardware and policy that could
- *		help determine where this interrupt should go
- *	req_bit is the interrupt bit requested 
- *		(can be INTRCONNECT_ANY_BIT in which the first available
- * 		 interrupt bit is used)
- *	intr_resflags indicates whether we want to (un)reserve bit
- *	owner_dev is the owner device
- *	intr_name is the readable interrupt name	
- * 	resp_bit indicates whether we succeeded in getting the required
- *		 action  { (un)reservation} done	
- *		 negative value indicates failure
- *
- */
-/* ARGSUSED */
-cpuid_t
-intr_heuristic(devfs_handle_t 		dev,
-	       device_desc_t 	dev_desc,
-	       int		req_bit,
-	       int 		intr_resflags,
-	       devfs_handle_t 		owner_dev,
-	       char		*intr_name,
-	       int		*resp_bit)
-{
-	cpuid_t		cpuid;				/* possible intr targ*/
-	cnodeid_t 	candidate;			/* possible canidate */
-	int		which_subnode = SUBNODE_ANY;
-
-/* SN1 + pcibr Addressing Limitation */
-	{
-	devfs_handle_t pconn_vhdl;
-	pcibr_soft_t pcibr_soft;
-
-	/*
-	 * This combination of SN1 and Bridge hardware has an odd "limitation".
-	 * Due to the choice of addresses for PI0 and PI1 registers on SN1
-	 * and historical limitations in Bridge, Bridge is unable to
-	 * send interrupts to both PI0 CPUs and PI1 CPUs -- we have
-	 * to choose one set or the other.  That choice is implicitly
-	 * made when Bridge first attaches its error interrupt.  After
-	 * that point, all subsequent interrupts are restricted to the
-	 * same PI number (though it's possible to send interrupts to
-	 * the same PI number on a different node).
-	 *
-	 * Since neither SN1 nor Bridge designers are willing to admit a
-	 * bug, we can't really call this a "workaround".  It's a permanent
-	 * solution for an SN1-specific and Bridge-specific hardware
-	 * limitation that won't ever be lifted.
-	 */
-        if ((hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) &&
-	   ((pcibr_soft = pcibr_soft_get(pconn_vhdl)) != NULL)) {
-		/*
-		 * We "know" that the error interrupt is the first
-		 * interrupt set up by pcibr_attach.  Send all interrupts
-		 * on this bridge to the same subnode number.
-		 */
-		if (pcibr_soft->bsi_err_intr) {
-			which_subnode = cpuid_to_subnode(((hub_intr_t) pcibr_soft->bsi_err_intr)->i_cpuid);
-		}
-	}
-	}
-
-	/* Check if we can find a valid interrupt target candidate on
-	 * the master node for the device.
-	 */
-	cpuid = intr_bit_reserve_test(CPU_NONE,
-				      which_subnode,	
-				      master_node_get(dev),
-				      req_bit,
-				      intr_resflags,
-				      owner_dev,
-				      intr_name,
-				      resp_bit);
-
-	if (cpuid != CPU_NONE) {
-		if (cpu_on_subnode(cpuid, which_subnode))
-			return(cpuid);	/* got a valid interrupt target */
-		else
-			intr_unreserve_level(cpuid, *resp_bit);
-	}
-
-	printk(KERN_WARNING  "Cannot target interrupts to closest node(%d): (0x%lx)\n",
-		master_node_get(dev),(unsigned long)owner_dev);
-
-	/* Fall through into the default algorithm
-	 * (exhaustive-search-for-the-nearest-possible-interrupt-target)
-	 * for finding the interrupt target
-	 */
-
-	{
-	/*
-	 * Do a stupid round-robin assignment of the node.
-	 *  (Should do a "nearest neighbor" but not for SN1.
-	 */
-		static cnodeid_t last_node = -1;
-
-		if (last_node >= numnodes) last_node = 0;
-		for (candidate = last_node + 1; candidate != last_node; candidate++) {
-			if (candidate == numnodes) candidate = 0;
-			cpuid = intr_bit_reserve_test(CPU_NONE,
-					      which_subnode,
-					      candidate,
-					      req_bit,
-					      intr_resflags,
-					      owner_dev,
-					      intr_name,
-					      resp_bit);
-
-			if (cpuid != CPU_NONE) {
-				if (cpu_on_subnode(cpuid, which_subnode)) {
-					last_node = candidate;
-					return(cpuid);	/* got a valid interrupt target */
-				}
-				else
-					intr_unreserve_level(cpuid, *resp_bit);
-			}
-		}
-		last_node = candidate;
-	}
-
-	printk(KERN_WARNING  "Cannot target interrupts to any close node: %ld (0x%lx)\n",
-		(long)owner_dev, (unsigned long)owner_dev);
-
-	/* In the worst case try to allocate interrupt bits on the
-	 * master processor's node. We may get here during error interrupt
-	 * allocation phase when the topology matrix is not yet setup
-	 * and hence cannot do an exhaustive search.
-	 */
-	ASSERT(cpu_allows_intr(master_procid));
-	cpuid = intr_bit_reserve_test(master_procid,
-				      which_subnode,
-				      CNODEID_NONE,
-				      req_bit,
-				      intr_resflags,
-				      owner_dev,
-				      intr_name,
-				      resp_bit);
-
-	if (cpuid != CPU_NONE) {
-		if (cpu_on_subnode(cpuid, which_subnode))
-			return(cpuid);
-		else
-			intr_unreserve_level(cpuid, *resp_bit);
-	}
-
-	printk(KERN_WARNING  "Cannot target interrupts: (0x%lx)\n",
-		(unsigned long)owner_dev);
-
-	return(CPU_NONE);	/* Should never get here */
-}
-
-struct hardwired_intr_s {
-	signed char level;
-	int flags;
-	char *name;
-} const hardwired_intr[] = {
-	{ INT_PEND0_BASELVL + RESERVED_INTR,	0,	"Reserved" },
-	{ INT_PEND0_BASELVL + GFX_INTR_A,	0, 	"Gfx A" },
-	{ INT_PEND0_BASELVL + GFX_INTR_B,	0, 	"Gfx B" },
-	{ INT_PEND0_BASELVL + PG_MIG_INTR,	II_THREADED, "Migration" },
-	{ INT_PEND0_BASELVL + UART_INTR,	II_THREADED, "Bedrock/L1" },
-	{ INT_PEND0_BASELVL + CC_PEND_A,	0,	"Crosscall A" },
-	{ INT_PEND0_BASELVL + CC_PEND_B,	0,	"Crosscall B" },
-	{ INT_PEND1_BASELVL + CLK_ERR_INTR,	II_ERRORINT, "Clock Error" },
-	{ INT_PEND1_BASELVL + COR_ERR_INTR_A,	II_ERRORINT, "Correctable Error A" },
-	{ INT_PEND1_BASELVL + COR_ERR_INTR_B,	II_ERRORINT, "Correctable Error B" },
-	{ INT_PEND1_BASELVL + MD_COR_ERR_INTR,	II_ERRORINT, "MD Correct. Error" },
-	{ INT_PEND1_BASELVL + NI_ERROR_INTR,	II_ERRORINT, "NI Error" },
-	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_A,	II_ERRORINT, "Remote NI Error"},
-	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_B,	II_ERRORINT, "Remote NI Error"},
-	{ INT_PEND1_BASELVL + MSC_PANIC_INTR,	II_ERRORINT, "MSC Panic" },
-	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_A,	II_ERRORINT, "LLP Pfail WAR" },
-	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_B,	II_ERRORINT, "LLP Pfail WAR" },
-	{ INT_PEND1_BASELVL + NACK_INT_A,	0, "CPU A Nack count == NACK_CMP" },
-	{ INT_PEND1_BASELVL + NACK_INT_B,	0, "CPU B Nack count == NACK_CMP" },
-	{ INT_PEND1_BASELVL + LB_ERROR,		0, "Local Block Error" },
-	{ INT_PEND1_BASELVL + XB_ERROR,		0, "Local XBar Error" },
-	{ -1, 0, (char *)NULL},
-};
-
-/*
- * Reserve all of the hardwired interrupt levels so they're not used as
- * general purpose bits later.
- */
-void
-intr_reserve_hardwired(cnodeid_t cnode)
-{
-	cpuid_t cpu;
-	int level;
-	int i;
-	char subnode_done[NUM_SUBNODES];
-
-	// cpu = cnodetocpu(cnode);
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		if (cpuid_to_cnodeid(cpu) == cnode) {
-			break;
-		}
-	}
-	if (cpu == smp_num_cpus) cpu = CPU_NONE;
-	if (cpu == CPU_NONE) {
-		printk("Node %d has no CPUs", cnode);
-		return;
-	}
-
-	for (i=0; i<NUM_SUBNODES; i++)
-		subnode_done[i] = 0;
-
-	for (; cpu<smp_num_cpus && cpu_enabled(cpu) && cpuid_to_cnodeid(cpu) == cnode; cpu++) {
-		int which_subnode = cpuid_to_subnode(cpu);
-		if (subnode_done[which_subnode])
-			continue;
-		subnode_done[which_subnode] = 1;
-
-		for (i = 0; hardwired_intr[i].level != -1; i++) {
-			level = hardwired_intr[i].level;
-
-			if (level != intr_reserve_level(cpu, level,
-						hardwired_intr[i].flags,
-						(devfs_handle_t) NULL,
-						hardwired_intr[i].name))
-				panic("intr_reserve_hardwired: Can't reserve level %d, cpu %ld.", level, cpu);
-		}
-	}
-}
-
-
-/*
- * Check and clear interrupts.
- */
-/*ARGSUSED*/
-static void
-intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, int base_level,
-		char *name)
-{
-	volatile hubreg_t bits;
-	int i;
-
-	/* Check pending interrupts */
-	if ((bits = HUB_L(pend)) != 0) {
-		for (i = 0; i < N_INTPEND_BITS; i++) {
-			if (bits & (1 << i)) {
-#ifdef INTRDEBUG
-				printk(KERN_WARNING  "Nasid %d interrupt bit %d set in %s",
-					nasid, i, name);
-#endif
-				LOCAL_HUB_CLR_INTR(base_level + i);
-			}
-		}
-	}
-}
-
-/*
- * Clear out our interrupt registers.
- */
-void
-intr_clear_all(nasid_t nasid)
-{
-	int	sn;
-
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_A, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_B, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_A, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_B, 0);
-	
-		intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND0),
-				INT_PEND0_BASELVL, "INT_PEND0");
-		intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND1),
-				INT_PEND1_BASELVL, "INT_PEND1");
-	}
-}
-
-/* 
- * Dump information about a particular interrupt vector.
- */
-static void
-dump_vector(intr_info_t *info, intr_vector_t *vector, int bit, hubreg_t ip,
-		hubreg_t ima, hubreg_t imb, void (*pf)(char *, ...))
-{
-	hubreg_t value = 1LL << bit;
-
-	pf("  Bit %02d: %s: func 0x%x arg 0x%x prefunc 0x%x\n",
-		bit, info->ii_name,
-		vector->iv_func, vector->iv_arg, vector->iv_prefunc);
-	pf("   vertex 0x%x %s%s",
-		info->ii_owner_dev,
-		((info->ii_flags) & II_RESERVE) ? "R" : "U",
-		((info->ii_flags) & II_INUSE) ? "C" : "-");
-	pf("%s%s%s%s",
-		ip & value ? "P" : "-",
-		ima & value ? "A" : "-",
-		imb & value ? "B" : "-",
-		((info->ii_flags) & II_ERRORINT) ? "E" : "-");
-	pf("\n");
-}
-
-
-/*
- * Dump information about interrupt vector assignment.
- */
-void
-intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...))
-{
-	nodepda_t *npda;
-	int ip, sn, bit;
-	intr_vecblk_t *dispatch;
-	hubreg_t ipr, ima, imb;
-	nasid_t nasid;
-
-	if ((cnode < 0) || (cnode >= numnodes)) {
-		pf("intr_dumpvec: cnodeid out of range: %d\n", cnode);
-		return ;
-	}
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	if (nasid == INVALID_NASID) {
-		pf("intr_dumpvec: Bad cnodeid: %d\n", cnode);
-		return ;
-	}
-		
-
-	npda = NODEPDA(cnode);
-
-	for (sn = 0; sn < NUM_SUBNODES; sn++) {
-		for (ip = 0; ip < 2; ip++) {
-			dispatch = ip ? &(SNPDA(npda,sn)->intr_dispatch1) : &(SNPDA(npda,sn)->intr_dispatch0);
-			ipr = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_PEND1 : PI_INT_PEND0);
-			ima = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_A : PI_INT_MASK0_A);
-			imb = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_B : PI_INT_MASK0_B);
-	
-			pf("Node %d INT_PEND%d:\n", cnode, ip);
-	
-			if (dispatch->ithreads_enabled)
-				pf(" Ithreads enabled\n");
-			else
-				pf(" Ithreads disabled\n");
-			pf(" vector_count = %d, vector_state = %d\n",
-				dispatch->vector_count,
-				dispatch->vector_state);
-			pf(" CPU A count %d, CPU B count %d\n",
- 		   	dispatch->cpu_count[0],
- 		   	dispatch->cpu_count[1]);
-			pf(" &vector_lock = 0x%x\n",
-				&(dispatch->vector_lock));
-			for (bit = 0; bit < N_INTPEND_BITS; bit++) {
-				if ((dispatch->info[bit].ii_flags & II_RESERVE) ||
-			    	(ipr & (1L << bit))) {
-					dump_vector(&(dispatch->info[bit]),
-					    	&(dispatch->vectors[bit]),
-					    	bit, ipr, ima, imb, pf);
-				}
-			}
-			pf("\n");
-		}
-	}
-}
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/ml_iograph.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/ml_iograph.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/ml_iograph.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/ml_iograph.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1505 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-
-/* #define IOGRAPH_DEBUG */
-#ifdef IOGRAPH_DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* IOGRAPH_DEBUG */
-
-/* #define PROBE_TEST */
-
-/* At most 2 hubs can be connected to an xswitch */
-#define NUM_XSWITCH_VOLUNTEER 2
-
-/*
- * Track which hubs have volunteered to manage devices hanging off of
- * a Crosstalk Switch (e.g. xbow).  This structure is allocated,
- * initialized, and hung off the xswitch vertex early on when the
- * xswitch vertex is created.
- */
-typedef struct xswitch_vol_s {
-	mutex_t xswitch_volunteer_mutex;
-	int		xswitch_volunteer_count;
-	devfs_handle_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
-} *xswitch_vol_t;
-
-void
-xswitch_vertex_init(devfs_handle_t xswitch)
-{
-	xswitch_vol_t xvolinfo;
-	int rc;
-
-	xvolinfo = kmalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL);
-	mutex_init(&xvolinfo->xswitch_volunteer_mutex);
-	xvolinfo->xswitch_volunteer_count = 0;
-	rc = hwgraph_info_add_LBL(xswitch, 
-			INFO_LBL_XSWITCH_VOL,
-			(arbitrary_info_t)xvolinfo);
-	ASSERT(rc == GRAPH_SUCCESS); rc = rc;
-}
-
-
-/*
- * When assignment of hubs to widgets is complete, we no longer need the
- * xswitch volunteer structure hanging around.  Destroy it.
- */
-static void
-xswitch_volunteer_delete(devfs_handle_t xswitch)
-{
-	xswitch_vol_t xvolinfo;
-	int rc;
-
-	rc = hwgraph_info_remove_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL,
-				(arbitrary_info_t *)&xvolinfo);
-	kfree(xvolinfo);
-}
-/*
- * A Crosstalk master volunteers to manage xwidgets on the specified xswitch.
- */
-/* ARGSUSED */
-static void
-volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master)
-{
-	xswitch_vol_t xvolinfo = NULL;
-	devfs_handle_t hubv;
-	hubinfo_t hubinfo;
-
-	(void)hwgraph_info_get_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL, 
-				(arbitrary_info_t *)&xvolinfo);
-	if (xvolinfo == NULL) {
-	    return;
-	}
-
-	mutex_lock(&xvolinfo->xswitch_volunteer_mutex);
-	ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER);
-	xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master;
-	xvolinfo->xswitch_volunteer_count++;
-
-	/*
-	 * if dual ported, make the lowest widgetid always be 
-	 * xswitch_volunteer[0].
-	 */
-	if (xvolinfo->xswitch_volunteer_count == NUM_XSWITCH_VOLUNTEER) {
-		hubv = xvolinfo->xswitch_volunteer[0];
-		hubinfo_get(hubv, &hubinfo);
-		if (hubinfo->h_widgetid != XBOW_HUBLINK_LOW) {
-			xvolinfo->xswitch_volunteer[0] = 
-						xvolinfo->xswitch_volunteer[1];
-			xvolinfo->xswitch_volunteer[1] = hubv;
-		}
-	}
-	mutex_unlock(&xvolinfo->xswitch_volunteer_mutex);
-}
-
-extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum);
-
-/*
- * Assign all the xwidgets hanging off the specified xswitch to the
- * Crosstalk masters that have volunteered for xswitch duty.
- */
-/* ARGSUSED */
-static void
-assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv)
-{
-	xswitch_info_t xswitch_info;
-	xswitch_vol_t xvolinfo = NULL;
-	xwidgetnum_t widgetnum;
-	int num_volunteer;
-	nasid_t nasid;
-	hubinfo_t hubinfo;
-	extern int iobrick_type_get_nasid(nasid_t);
-
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-	
-	xswitch_info = xswitch_info_get(xswitch);
-	ASSERT(xswitch_info != NULL);
-
-	(void)hwgraph_info_get_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL, 
-				(arbitrary_info_t *)&xvolinfo);
-	if (xvolinfo == NULL) {
-	    return;
-	}
-
-	num_volunteer = xvolinfo->xswitch_volunteer_count;
-	ASSERT(num_volunteer > 0);
-
-	/* Assign master hub for xswitch itself.  */
-	if (HUB_WIDGET_ID_MIN > 0) {
-		hubv = xvolinfo->xswitch_volunteer[0];
-		xswitch_info_master_assignment_set(xswitch_info, (xwidgetnum_t)0, hubv);
-	}
-
-	/*
-	 * TBD: Use administrative information to alter assignment of
-	 * widgets to hubs.
-	 */
-	for (widgetnum=HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-		int i;
-
-		/*
-		 * Ignore disabled/empty ports.
-		 */
-		if (!xbow_port_io_enabled(nasid, widgetnum)) 
-		    continue;
-
-		/*
-		 * If this is the master IO board, assign it to the same 
-		 * hub that owned it in the prom.
-		 */
-		if (is_master_nasid_widget(nasid, widgetnum)) {
-			for (i=0; i<num_volunteer; i++) {
-				hubv = xvolinfo->xswitch_volunteer[i];
-				hubinfo_get(hubv, &hubinfo);
-				nasid = hubinfo->h_nasid;
-				if (nasid == get_console_nasid())
-					goto do_assignment;
-			}
-		}
-
-		/*
-		 * Assuming that we're dual-hosted and that PCI cards 
-		 * are naturally placed left-to-right, alternate PCI 
-		 * buses across both Cbricks.   For Pbricks, and Ibricks,
-                 * io_brick_map_widget() returns the PCI bus number
-                 * associated with the given brick type and widget number.
-                 * For Xbricks, it returns the XIO slot number.
-		 */
-
-		i = 0;
-		if (num_volunteer > 1) {
-                        int	       bt;
-
-                       	bt = iobrick_type_get_nasid(nasid);
-                        if (bt >= 0) {
-				/*
-				 * PXBRICK has two busses per widget so this
-				 * algorithm wouldn't work (all busses would
-				 * be assigned to one volunteer). Change the
-				 * bricktype to PBRICK whose mapping is setup
-				 * suchthat 2 of the PICs will be assigned to
-				 * one volunteer and the other one will be
-				 * assigned to the other volunteer.
-				 */
-				if (bt == MODULE_PXBRICK) 
-					bt = MODULE_PBRICK;
-
-			        i = io_brick_map_widget(bt, widgetnum) & 1;
-                        }
-                }
-
-		hubv = xvolinfo->xswitch_volunteer[i];
-
-do_assignment:
-		/*
-		 * At this point, we want to make hubv the master of widgetnum.
-		 */
-		xswitch_info_master_assignment_set(xswitch_info, widgetnum, hubv);
-	}
-
-	xswitch_volunteer_delete(xswitch);
-}
-
-/*
- * Early iograph initialization.  Called by master CPU in mlreset().
- * Useful for including iograph.o in kernel.o.
- */
-void
-iograph_early_init(void)
-{
-/*
- * Need new way to get this information ..
- */
-	cnodeid_t cnode;
-	nasid_t nasid;
-	lboard_t *board;
-	
-	/*
-	 * Init. the board-to-hwgraph link early, so FRU analyzer
-	 * doesn't trip on leftover values if we panic early on.
-	 */
-	for(cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		DBG("iograph_early_init: Found board 0x%p\n", board);
-
-		/* Check out all the board info stored on a node */
-		while(board) {
-			board->brd_graph_link = GRAPH_VERTEX_NONE;
-			board = KLCF_NEXT(board);
-			DBG("iograph_early_init: Found board 0x%p\n", board);
-		}
-	}
-
-	hubio_init();
-}
-
-/*
- * Let boot processor know that we're done initializing our node's IO
- * and then exit.
- */
-/* ARGSUSED */
-static void
-io_init_done(cnodeid_t cnodeid,cpu_cookie_t c)
-{
-	/* Let boot processor know that we're done. */
-}
-
-/* 
- * Probe to see if this hub's xtalk link is active.  If so,
- * return the Crosstalk Identification of the widget that we talk to.  
- * This is called before any of the Crosstalk infrastructure for 
- * this hub is set up.  It's usually called on the node that we're
- * probing, but not always.
- *
- * TBD: Prom code should actually do this work, and pass through 
- * hwid for our use.
- */
-static void
-early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid)
-{
-	hubreg_t llp_csr_reg;
-	nasid_t nasid;
-	hubinfo_t hubinfo;
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-
-	llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
-	/* 
-	 * If link is up, read the widget's part number.
-	 * A direct connect widget must respond to widgetnum=0.
-	 */
-	if (llp_csr_reg & IIO_LLP_CSR_IS_UP) {
-		/* TBD: Put hub into "indirect" mode */
-		/*
-		 * We're able to read from a widget because our hub's 
-		 * WIDGET_ID was set up earlier.
-		 */
-		widgetreg_t widget_id = *(volatile widgetreg_t *)
-			(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
-
-		DBG("early_probe_for_widget: Hub Vertex 0x%p is UP widget_id = 0x%x Register 0x%p\n", hubv, widget_id,
-		(volatile widgetreg_t *)(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID) );
-
-		hwid->part_num = XWIDGET_PART_NUM(widget_id);
-		hwid->rev_num = XWIDGET_REV_NUM(widget_id);
-		hwid->mfg_num = XWIDGET_MFG_NUM(widget_id);
-
-		/* TBD: link reset */
-	} else {
-
-		hwid->part_num = XWIDGET_PART_NUM_NONE;
-		hwid->rev_num = XWIDGET_REV_NUM_NONE;
-		hwid->mfg_num = XWIDGET_MFG_NUM_NONE;
-	}
-}
-
-/* Add inventory information to the widget vertex 
- * Right now (module,slot,revision) is being
- * added as inventory information.
- */
-static void
-xwidget_inventory_add(devfs_handle_t 		widgetv,
-		      lboard_t 			*board,
-		      struct xwidget_hwid_s 	hwid)
-{
-	if (!board)
-		return;
-	/* Donot add inventory information for the baseio
-	 * on a speedo with an xbox. It has already been
-	 * taken care of in SN00_vmc.
-	 * Speedo with xbox's baseio comes in at slot io1 (widget 9)
-	 */
-	device_inventory_add(widgetv,INV_IOBD,board->brd_type,
-			     board->brd_module,
-			     SLOTNUM_GETSLOT(board->brd_slot),
-			     hwid.rev_num);
-}
-
-/*
- * io_xswitch_widget_init
- *	
- */
-
-void
-io_xswitch_widget_init(devfs_handle_t  	xswitchv,
-		       devfs_handle_t	hubv,
-		       xwidgetnum_t	widgetnum,
-		       async_attach_t	aa)
-{
-	xswitch_info_t		xswitch_info;
-	xwidgetnum_t		hub_widgetid;
-	devfs_handle_t		widgetv;
-	cnodeid_t		cnode;
-	widgetreg_t		widget_id;
-	nasid_t			nasid, peer_nasid;
-	struct xwidget_hwid_s 	hwid;
-	hubinfo_t		hubinfo;
-	/*REFERENCED*/
-	int			rc;
-	char 			pathname[128];
-	char			new_name[64];
-	moduleid_t		module;
-	slotid_t		slot;
-	lboard_t		*board = NULL;
-	char			buffer[16];
-	slotid_t get_widget_slotnum(int xbow, int widget);
-	
-	DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum);
-
-	/*
-	 * Verify that xswitchv is indeed an attached xswitch.
-	 */
-	xswitch_info = xswitch_info_get(xswitchv);
-	ASSERT(xswitch_info != NULL);
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-	cnode = NASID_TO_COMPACT_NODEID(nasid);
-	hub_widgetid = hubinfo->h_widgetid;
-
-	/*
-	 * Check that the widget is an io widget and is enabled
-	 * on this nasid or the `peer' nasid.  The peer nasid
-	 * is the other hub/bedrock connected to the xbow.
-	 */
-	peer_nasid = NODEPDA(cnode)->xbow_peer;
-	if (peer_nasid == INVALID_NASID)
-		/* If I don't have a peer, use myself. */
-		peer_nasid = nasid;
-	if (!xbow_port_io_enabled(nasid, widgetnum) &&
-	    !xbow_port_io_enabled(peer_nasid, widgetnum)) {
-		return;
-	}
-
-	if (xswitch_info_link_ok(xswitch_info, widgetnum)) {
-		char			name[4];
-
-		/*
-		 * If the current hub is not supposed to be the master 
-		 * for this widgetnum, then skip this widget.
-		 */
-		if (xswitch_info_master_assignment_get(xswitch_info,
-						       widgetnum) != hubv) {
-			return;
-		}
-
-		module  = NODEPDA(cnode)->module_id;
-#ifdef XBRIDGE_REGS_SIM
-		/* hardwire for now...could do this with something like:
-		 * xbow_soft_t soft = hwgraph_fastinfo_get(vhdl);
-		 * xbow_t xbow = soft->base;
-		 * xbowreg_t xwidget_id = xbow->xb_wid_id;
-		 * but I don't feel like figuring out vhdl right now..
-		 * and I know for a fact the answer is 0x2d000049 
-		 */
-		DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
-		DBG("XWIDGET_PART_NUM(0x2d000049)= 0x%x\n", XWIDGET_PART_NUM(0x2d000049));
-		if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM)
-#else
-		if (nasid_has_xbridge(nasid))
-#endif /* XBRIDGE_REGS_SIM */
-		{
-			board = find_lboard_module_class(
-				(lboard_t *)KL_CONFIG_INFO(nasid),
-				module,
-				KLTYPE_IOBRICK);
-
-DBG("io_xswitch_widget_init: Board 0x%p\n", board);
-{
-		lboard_t dummy;
-
-
-			if (board) {
-				DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type);
-			} else {
-				DBG("io_xswitch_widget_init: FIXME did not find IOBOARD\n");
-				board = &dummy;
-			}
-				
-}
-
-			/*
-	 		 * Make sure we really want to say xbrick, pbrick,
-			 * etc. rather than XIO, graphics, etc.
-	 		 */
-
-#ifdef SUPPORT_PRINTING_M_FORMAT
-			sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-				"%cbrick" "/%s/%d",
-				NODEPDA(cnode)->module_id,
-				
-#else
-			memset(buffer, 0, 16);
-			format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF);
-			sprintf(pathname, EDGE_LBL_MODULE "/%s/"
-				"%cbrick" "/%s/%d",
-				buffer,
-#endif
-
-				(board->brd_type == KLTYPE_IBRICK) ? 'I' :
-				(board->brd_type == KLTYPE_PBRICK) ? 'P' :
-				(board->brd_type == KLTYPE_XBRICK) ? 'X' : '?',
-				EDGE_LBL_XTALK, widgetnum);
-		} 
-		
-		DBG("io_xswitch_widget_init: path= %s\n", pathname);
-		rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
-		
-		ASSERT(rc == GRAPH_SUCCESS);
-
-		/* This is needed to let the user programs to map the
-		 * module,slot numbers to the corresponding widget numbers
-		 * on the crossbow.
-		 */
-		rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv);
-
-		/* If we are looking at the global master io6
-		 * then add information about the version of
-		 * the io6prom as a part of "detailed inventory"
-		 * information.
-		 */
-		if (is_master_baseio(nasid,
-				     NODEPDA(cnode)->module_id,
- 				     get_widget_slotnum(0,widgetnum))) {
-			extern void klhwg_baseio_inventory_add(devfs_handle_t,
-							       cnodeid_t);
-			module 	= NODEPDA(cnode)->module_id;
-
-#ifdef XBRIDGE_REGS_SIM
-			DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
-			if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM)
-#else
-			if (nasid_has_xbridge(nasid))
-#endif /* XBRIDGE_REGS_SIM */
-			{
-				board = find_lboard_module(
-					(lboard_t *)KL_CONFIG_INFO(nasid),
-					module);
-				/*
-				 * Change iobrick to correct i/o brick
-				 */
-#ifdef SUPPORT_PRINTING_M_FORMAT
-				sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-#else
-				sprintf(pathname, EDGE_LBL_MODULE "/%x/"
-#endif
-					"iobrick" "/%s/%d",
-					NODEPDA(cnode)->module_id,
-					EDGE_LBL_XTALK, widgetnum);
-			} else {
-				slot = get_widget_slotnum(0, widgetnum);
-				board = get_board_name(nasid, module, slot,
-								new_name);
-				/*
-			 	 * Create the vertex for the widget, 
-				 * using the decimal 
-			 	 * widgetnum as the name of the primary edge.
-			 	 */
-#ifdef SUPPORT_PRINTING_M_FORMAT
-				sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-                                                EDGE_LBL_SLOT "/%s",
-                                        NODEPDA(cnode)->module_id,
-                                        new_name);
-#else
-				memset(buffer, 0, 16);
-				format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF);
-				sprintf(pathname, EDGE_LBL_MODULE "/%s/"
-					  	EDGE_LBL_SLOT "/%s",
-					buffer,
-					new_name);
-#endif
-			}
-
-			rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
-			DBG("io_xswitch_widget_init: (2) path= %s\n", pathname);
-		        /*
-		         * This is a weird ass code needed for error injection
-		         * purposes.
-		         */
-		        rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv);
-			
-			klhwg_baseio_inventory_add(widgetv,cnode);
-		}
-		sprintf(name, "%d", widgetnum);
-		DBG("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv);
-		rc = hwgraph_edge_add(xswitchv, widgetv, name);
-		
-		/*
-		 * crosstalk switch code tracks which
-		 * widget is attached to each link.
-		 */
-		xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv);
-		
-		/*
-		 * Peek at the widget to get its crosstalk part and
-		 * mfgr numbers, then present it to the generic xtalk
-		 * bus provider to have its driver attach routine
-		 * called (or not).
-		 */
-#ifdef XBRIDGE_REGS_SIM
-		widget_id = 0x2d000049;
-		DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: id hardwired to widget_id\n");
-#else
-		widget_id = XWIDGET_ID_READ(nasid, widgetnum);
-#endif /* XBRIDGE_REGS_SIM */
-		hwid.part_num = XWIDGET_PART_NUM(widget_id);
-		hwid.rev_num = XWIDGET_REV_NUM(widget_id);
-		hwid.mfg_num = XWIDGET_MFG_NUM(widget_id);
-		/* Store some inventory information about
-		 * the xwidget in the hardware graph.
-		 */
-		xwidget_inventory_add(widgetv,board,hwid);
-		
-		(void)xwidget_register(&hwid, widgetv, widgetnum,
-				       hubv, hub_widgetid,
-				       aa);
-
-#ifdef	SN0_USE_BTE
-		bte_bpush_war(cnode, (void *)board);
-#endif
-	}
-}
-
-
-static void
-io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode)
-{
-	xwidgetnum_t		widgetnum;
-	async_attach_t          aa;
-
-	aa = async_attach_new();
-	
-	DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode);
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; 
-	     widgetnum++) {
-		io_xswitch_widget_init(xswitchv,
-				       cnodeid_to_vertex(cnode),
-				       widgetnum, aa);
-	}
-	/* 
-	 * Wait for parallel attach threads, if any, to complete.
-	 */
-	async_attach_waitall(aa);
-	async_attach_free(aa);
-}
-
-/*
- * For each PCI bridge connected to the xswitch, add a link from the
- * board's klconfig info to the bridge's hwgraph vertex.  This lets
- * the FRU analyzer find the bridge without traversing the hardware
- * graph and risking hangs.
- */
-static void
-io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid)
-{
-	xwidgetnum_t		widgetnum;
-	char 			pathname[128];
-	devfs_handle_t		vhdl;
-	nasid_t			nasid, peer_nasid;
-	lboard_t		*board;
-
-
-
-	/* And its connected hub's nasids */
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-	peer_nasid = NODEPDA(cnodeid)->xbow_peer;
-
-	/* 
-	 * Look for paths matching "<widgetnum>/pci" under xswitchv.
-	 * For every widget, init. its lboard's hwgraph link.  If the
-	 * board has a PCI bridge, point the link to it.
-	 */
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX;
-		 widgetnum++) {
-		sprintf(pathname, "%d", widgetnum);
-		if (hwgraph_traverse(xswitchv, pathname, &vhdl) !=
-		    GRAPH_SUCCESS)
-			continue;
-
-		board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid),
-				NODEPDA(cnodeid)->module_id);
-		if (board == NULL && peer_nasid != INVALID_NASID) {
-			/*
-			 * Try to find the board on our peer
-			 */
-			board = find_lboard_module(
-				(lboard_t *)KL_CONFIG_INFO(peer_nasid),
-				NODEPDA(cnodeid)->module_id);
-		}
-		if (board == NULL) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-			printk(KERN_WARNING  "Could not find PROM info for vertex %v, "
-				"FRU analyzer may fail",
-				vhdl);
-#else
-			printk(KERN_WARNING  "Could not find PROM info for vertex 0x%p, "
-				"FRU analyzer may fail",
-				(void *)vhdl);
-#endif
-			return;
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		if (hwgraph_traverse(xswitchv, pathname, &vhdl) == 
-		    GRAPH_SUCCESS)
-			board->brd_graph_link = vhdl;
-		else
-			board->brd_graph_link = GRAPH_VERTEX_NONE;
-	}
-}
-
-/*
- * Initialize all I/O on the specified node.
- */
-static void
-io_init_node(cnodeid_t cnodeid)
-{
-	/*REFERENCED*/
-	devfs_handle_t hubv, switchv, widgetv;
-	struct xwidget_hwid_s hwid;
-	hubinfo_t hubinfo;
-	int is_xswitch;
-	nodepda_t	*npdap;
-	struct semaphore *peer_sema = 0;
-	uint32_t	widget_partnum;
-	nodepda_router_info_t *npda_rip;
-	cpu_cookie_t	c = 0;
-	extern int hubdev_docallouts(devfs_handle_t);
-
-#ifdef LATER
-	/* Try to execute on the node that we're initializing. */
-	c = setnoderun(cnodeid);
-#endif
-	npdap = NODEPDA(cnodeid);
-
-	/*
-	 * Get the "top" vertex for this node's hardware
-	 * graph; it will carry the per-hub hub-specific
-	 * data, and act as the crosstalk provider master.
-	 * It's canonical path is probably something of the
-	 * form /hw/module/%M/slot/%d/node
-	 */
-	hubv = cnodeid_to_vertex(cnodeid);
-	DBG("io_init_node: Initialize IO for cnode %d hubv(node) 0x%p npdap 0x%p\n", cnodeid, hubv, npdap);
-
-	ASSERT(hubv != GRAPH_VERTEX_NONE);
-
-	hubdev_docallouts(hubv);
-
-	/*
-	 * Set up the dependent routers if we have any.
-	 */
-	npda_rip = npdap->npda_rip_first;
-
-	while(npda_rip) {
-		/* If the router info has not been initialized
-		 * then we need to do the router initialization
-		 */
-		if (!npda_rip->router_infop) {
-			router_init(cnodeid,0,npda_rip);
-		}
-		npda_rip = npda_rip->router_next;
-	}
-
-	/*
-	 * Read mfg info on this hub
-	 */
-
-	/* 
-	 * If nothing connected to this hub's xtalk port, we're done.
-	 */
-	early_probe_for_widget(hubv, &hwid);
-	if (hwid.part_num == XWIDGET_PART_NUM_NONE) {
-#ifdef PROBE_TEST
-		if ((cnodeid == 1) || (cnodeid == 2)) {
-			int index;
-
-			for (index = 0; index < 600; index++)
-				DBG("Interfering with device probing!!!\n");
-		}
-#endif
-		/* io_init_done takes cpu cookie as 2nd argument 
-		 * to do a restorenoderun for the setnoderun done 
-		 * at the start of this thread 
-		 */
-		
-		DBG("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv);
-		return;
-		/* NOTREACHED */
-	}
-
-	/* 
-	 * attach our hub_provider information to hubv,
-	 * so we can use it as a crosstalk provider "master"
-	 * vertex.
-	 */
-	xtalk_provider_register(hubv, &hub_provider);
-	xtalk_provider_startup(hubv);
-
-	/*
-	 * Create a vertex to represent the crosstalk bus
-	 * attached to this hub, and a vertex to be used
-	 * as the connect point for whatever is out there
-	 * on the other side of our crosstalk connection.
-	 *
-	 * Crosstalk Switch drivers "climb up" from their
-	 * connection point to try and take over the switch
-	 * point.
-	 *
-	 * Of course, the edges and verticies may already
-	 * exist, in which case our net effect is just to
-	 * associate the "xtalk_" driver with the connection
-	 * point for the device.
-	 */
-
-	(void)hwgraph_path_add(hubv, EDGE_LBL_XTALK, &switchv);
-
-	DBG("io_init_node: Created 'xtalk' entry to '../node/' xtalk vertex 0x%p\n", switchv);
-
-	ASSERT(switchv != GRAPH_VERTEX_NONE);
-
-	(void)hwgraph_edge_add(hubv, switchv, EDGE_LBL_IO);
-
-	DBG("io_init_node: Created symlink 'io' from ../node/io to ../node/xtalk \n");
-
-	/*
-	 * We need to find the widget id and update the basew_id field
-	 * accordingly. In particular, SN00 has direct connected bridge,
-	 * and hence widget id is Not 0.
-	 */
-
-	widget_partnum = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + WIDGET_ID))) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT;
-
-	if (widget_partnum == BRIDGE_WIDGET_PART_NUM ||
-				widget_partnum == XBRIDGE_WIDGET_PART_NUM){
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-
-		DBG("io_init_node: Found XBRIDGE widget_partnum= 0x%x\n", widget_partnum);
-
-	} else if ((widget_partnum == XBOW_WIDGET_PART_NUM) ||
-			(widget_partnum == XXBOW_WIDGET_PART_NUM) ||
-			(widget_partnum == PXBOW_WIDGET_PART_NUM) ) {
-		/* 
-		 * Xbow control register does not have the widget ID field.
-		 * So, hard code the widget ID to be zero.
-		 */
-		DBG("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum);
-		npdap->basew_id = 0;
-
-	} else {
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-
-		panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widget ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, (void *)hubv);
-
-		/*NOTREACHED*/
-	}
-	{
-		char widname[10];
-		sprintf(widname, "%x", npdap->basew_id);
-		(void)hwgraph_path_add(switchv, widname, &widgetv);
-		DBG("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv);
-		ASSERT(widgetv != GRAPH_VERTEX_NONE);
-	}
-	
-	nodepda->basew_xc = widgetv;
-
-	is_xswitch = xwidget_hwid_is_xswitch(&hwid);
-
-	/* 
-	 * Try to become the master of the widget.  If this is an xswitch
-	 * with multiple hubs connected, only one will succeed.  Mastership
-	 * of an xswitch is used only when touching registers on that xswitch.
-	 * The slave xwidgets connected to the xswitch can be owned by various
-	 * masters.
-	 */
-	if (device_master_set(widgetv, hubv) == 0) {
-
-		/* Only one hub (thread) per Crosstalk device or switch makes
-		 * it to here.
-		 */
-
-		/* 
-		 * Initialize whatever xwidget is hanging off our hub.
-		 * Whatever it is, it's accessible through widgetnum 0.
-		 */
-		hubinfo_get(hubv, &hubinfo);
-
-		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL);
-
-		if (!is_xswitch) {
-			/* io_init_done takes cpu cookie as 2nd argument 
-			 * to do a restorenoderun for the setnoderun done 
-			 * at the start of this thread 
-			 */
-			io_init_done(cnodeid,c);
-			/* NOTREACHED */
-		}
-
-		/* 
-		 * Special handling for Crosstalk Switches (e.g. xbow).
-		 * We need to do things in roughly the following order:
-		 *	1) Initialize xswitch hardware (done above)
-		 *	2) Determine which hubs are available to be widget masters
-		 *	3) Discover which links are active from the xswitch
-		 *	4) Assign xwidgets hanging off the xswitch to hubs
-		 *	5) Initialize all xwidgets on the xswitch
-		 */
-
-		volunteer_for_widgets(switchv, hubv);
-
-		/* If there's someone else on this crossbow, recognize him */
-		if (npdap->xbow_peer != INVALID_NASID) {
-			nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer));
-			peer_sema = &peer_npdap->xbow_sema;
-			volunteer_for_widgets(switchv, peer_npdap->node_vertex);
-		}
-
-		assign_widgets_to_volunteers(switchv, hubv);
-
-		/* Signal that we're done */
-		if (peer_sema) {
-			mutex_unlock(peer_sema);
-		}
-		
-	}
-	else {
-	    /* Wait 'til master is done assigning widgets. */
-	    mutex_lock(&npdap->xbow_sema);
-	}
-
-#ifdef PROBE_TEST
-	if ((cnodeid == 1) || (cnodeid == 2)) {
-		int index;
-
-		for (index = 0; index < 500; index++)
-			DBG("Interfering with device probing!!!\n");
-	}
-#endif
-	/* Now both nodes can safely inititialize widgets */
-	io_init_xswitch_widgets(switchv, cnodeid);
-	io_link_xswitch_widgets(switchv, cnodeid);
-
-	/* io_init_done takes cpu cookie as 2nd argument 
-	 * to do a restorenoderun for the setnoderun done 
-	 * at the start of this thread 
-	 */
-	io_init_done(cnodeid,c);
-
-	DBG("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid);
-}
-
-
-#define IOINIT_STKSZ	(16 * 1024)
-
-#define __DEVSTR1 	"/../.master/"
-#define __DEVSTR2 	"/target/"
-#define __DEVSTR3 	"/lun/0/disk/partition/"
-#define	__DEVSTR4	"/../ef"
-
-/*
- * Currently, we need to allow for 5 IBrick slots with 1 FC each
- * plus an internal 1394.
- *
- * ioconfig starts numbering SCSI's at NUM_BASE_IO_SCSI_CTLR.
- */
-#define NUM_BASE_IO_SCSI_CTLR 6
-
-/*
- * This tells ioconfig where it can start numbering scsi controllers.
- * Below this base number, platform-specific handles the numbering.
- * XXX Irix legacy..controller numbering should be part of devfsd's job
- */
-int num_base_io_scsi_ctlr = 2; /* used by syssgi */
-devfs_handle_t		base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];
-static devfs_handle_t	baseio_enet_vhdl,baseio_console_vhdl;
-
-/*
- * Put the logical controller number information in the 
- * scsi controller vertices for each scsi controller that
- * is in a "fixed position".
- */
-static void
-scsi_ctlr_nums_add(devfs_handle_t pci_vhdl)
-{
-	{
-		int i;
-
-		num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR;
-
-		/* Initialize base_io_scsi_ctlr_vhdl array */
-		for (i=0; i<num_base_io_scsi_ctlr; i++)
-			base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE;
-	}
-	{
-	/*
-	 * May want to consider changing the SN0 code, above, to work more like
-	 * the way this works.
-	 */
-	devfs_handle_t base_ibrick_xbridge_vhdl;
-	devfs_handle_t base_ibrick_xtalk_widget_vhdl;
-	devfs_handle_t scsi_ctlr_vhdl;
-	int i;
-	graph_error_t rv;
-
-	/*
-	 * This is a table of "well-known" SCSI controllers and their well-known
-	 * controller numbers.  The names in the table start from the base IBrick's
-	 * Xbridge vertex, so the first component is the xtalk widget number.
-	 */
-	static struct {
-		char	*base_ibrick_scsi_path;
-		int	controller_number;
-	} hardwired_scsi_controllers[] = {
-		{"15/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 0},
-		{"15/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 1},
-		{"15/" EDGE_LBL_PCI "/3/" EDGE_LBL_SCSI_CTLR "/0", 2},
-		{"14/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 3},
-		{"14/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 4},
-		{"15/" EDGE_LBL_PCI "/6/ohci/0/" EDGE_LBL_SCSI_CTLR "/0", 5},
-		{NULL, -1} /* must be last */
-	};
-
-	base_ibrick_xtalk_widget_vhdl = hwgraph_connectpt_get(pci_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xtalk_widget_vhdl != GRAPH_VERTEX_NONE);
-
-	base_ibrick_xbridge_vhdl = hwgraph_connectpt_get(base_ibrick_xtalk_widget_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xbridge_vhdl != GRAPH_VERTEX_NONE);
-	hwgraph_vertex_unref(base_ibrick_xtalk_widget_vhdl);
-
-	/*
-	 * Iterate through the list of well-known SCSI controllers.
-	 * For each controller found, set it's controller number according
-	 * to the table.
-	 */
-	for (i=0; hardwired_scsi_controllers[i].base_ibrick_scsi_path != NULL; i++) {
-		rv = hwgraph_path_lookup(base_ibrick_xbridge_vhdl,
-			hardwired_scsi_controllers[i].base_ibrick_scsi_path, &scsi_ctlr_vhdl, NULL);
-
-		if (rv != GRAPH_SUCCESS) /* No SCSI at this path */
-			continue;
-
-		ASSERT(hardwired_scsi_controllers[i].controller_number < NUM_BASE_IO_SCSI_CTLR);
-		base_io_scsi_ctlr_vhdl[hardwired_scsi_controllers[i].controller_number] = scsi_ctlr_vhdl;
-		device_controller_num_set(scsi_ctlr_vhdl, hardwired_scsi_controllers[i].controller_number);
-		hwgraph_vertex_unref(scsi_ctlr_vhdl); /* (even though we're actually keeping a reference) */
-	}
-
-	hwgraph_vertex_unref(base_ibrick_xbridge_vhdl);
-	}
-}
-
-
-#include <asm/sn/ioerror_handling.h>
-devfs_handle_t		sys_critical_graph_root = GRAPH_VERTEX_NONE;
-
-/* Define the system critical vertices and connect them through
- * a canonical parent-child relationships for easy traversal
- * during io error handling.
- */
-static void
-sys_critical_graph_init(void)
-{
-	devfs_handle_t		bridge_vhdl,master_node_vhdl;
-	devfs_handle_t  		xbow_vhdl = GRAPH_VERTEX_NONE;
-	extern devfs_handle_t	hwgraph_root;
-	devfs_handle_t		pci_slot_conn;
-	int			slot;
-	devfs_handle_t		baseio_console_conn;
-
-	DBG("sys_critical_graph_init: FIXME.\n");
-	baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl);
-
-	if (baseio_console_conn == NULL) {
-		return;
-	}
-
-	/* Get the vertex handle for the baseio bridge */
-	bridge_vhdl = device_master_get(baseio_console_conn);
-
-	/* Get the master node of the baseio card */
-	master_node_vhdl = cnodeid_to_vertex(
-				master_node_get(baseio_console_vhdl));
-	
-	/* Add the "root->node" part of the system critical graph */
-
-	sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl);
-
-	/* Check if we have a crossbow */
-	if (hwgraph_traverse(master_node_vhdl,
-			     EDGE_LBL_XTALK"/0",
-			     &xbow_vhdl) == GRAPH_SUCCESS) {
-		/* We have a crossbow.Add "node->xbow" part of the system 
-		 * critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl);
-		
-		/* Add "xbow->baseio bridge" of the system critical graph */
-		sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl);
-
-		hwgraph_vertex_unref(xbow_vhdl);
-	} else 
-		/* We donot have a crossbow. Add "node->baseio_bridge"
-		 * part of the system critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl);
-
-	/* Add all the populated PCI slot vertices to the system critical
-	 * graph with the bridge vertex as the parent.
-	 */
-	for (slot = 0 ; slot < 8; slot++) {
-		char	slot_edge[10];
-
-		sprintf(slot_edge,"%d",slot);
-		if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn)
-		    != GRAPH_SUCCESS)
-			continue;
-		sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	hwgraph_vertex_unref(bridge_vhdl);
-
-	/* Add the "ioc3 pci connection point  -> console ioc3" part 
-	 * of the system critical graph
-	 */
-
-	if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_console_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "ethernet pci connection point  -> base ethernet" part of 
-	 * the system  critical graph
-	 */
-	if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_enet_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "scsi controller pci connection point  -> base scsi 
-	 * controller" part of the system critical graph
-	 */
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[0]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[1]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	hwgraph_vertex_unref(baseio_console_conn);
-
-}
-
-static void
-baseio_ctlr_num_set(void)
-{
-	char 			name[MAXDEVNAME];
-	devfs_handle_t		console_vhdl, pci_vhdl, enet_vhdl;
-	devfs_handle_t		ioc3_console_vhdl_get(void);
-
-
-	DBG("baseio_ctlr_num_set; FIXME\n");
-	console_vhdl = ioc3_console_vhdl_get();
-	if (console_vhdl == GRAPH_VERTEX_NONE)
-		return;
-	/* Useful for setting up the system critical graph */
-	baseio_console_vhdl = console_vhdl;
-
-	vertex_to_name(console_vhdl,name,MAXDEVNAME);
-
-	strcat(name,__DEVSTR1);
-	pci_vhdl =  hwgraph_path_to_vertex(name);
-	scsi_ctlr_nums_add(pci_vhdl);
-	/* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(pci_vhdl);
-
-	vertex_to_name(console_vhdl, name, MAXDEVNAME);
-	strcat(name, __DEVSTR4);
-	enet_vhdl = hwgraph_path_to_vertex(name);
-
-	/* Useful for setting up the system critical graph */
-	baseio_enet_vhdl = enet_vhdl;
-
-	device_controller_num_set(enet_vhdl, 0);
-	/* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(enet_vhdl);
-}
-/* #endif */
-
-void
-sn00_rrb_alloc(devfs_handle_t vhdl, int *vendor_list)
-{
-	/* REFERENCED */
-	int rtn_val;
-
-	/* 
-	** sn00 population:		errb	orrb
-	**	0- ql			3+?
-	**	1- ql			        2
-	**	2- ioc3 ethernet	2+?
-	**	3- ioc3 secondary	        1
-	**	4-                      0
-	** 	5- PCI slot
-	** 	6- PCI slot
-	** 	7- PCI slot
-	*/	
-	
-	/* The following code implements this heuristic for getting 
-	 * maximum usage out of the rrbs
-	 *
-	 * constraints:
-	 *  8 bit ql1 needs 1+1
-	 *  ql0 or ql5,6,7 wants 1+2
-	 *  ethernet wants 2 or more
-	 *
-	 * rules for even rrbs:
-	 *  if nothing in slot 6 
-	 *   4 rrbs to 0 and 2  (0xc8889999)
-	 *  else 
-         *   3 2 3 to slots 0 2 6  (0xc8899bbb)
-	 *
-         * rules for odd rrbs
-	 *  if nothing in slot 5 or 7  (0xc8889999)
-	 *   4 rrbs to 1 and 3
-	 *  else if 1 thing in 5 or 7  (0xc8899aaa) or (0xc8899bbb)
-         *   3 2 3 to slots 1 3 5|7
-         *  else
-         *   2 1 3 2 to slots 1 3 5 7 (note: if there's a ql card in 7 this
-	 *           (0xc89aaabb)      may short what it wants therefore the
-	 *			       rule should be to plug pci slots in order)
-	 */
-
-
-	if (vendor_list[6] != PCIIO_VENDOR_ID_NONE) {
-		/* something in slot 6 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 3,1, 2,0, 0,0, 3,0);
-	}
-	else {
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 4,1, 4,0, 0,0, 0,0);
-	}
-	if (rtn_val)
-		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-
-	if ((vendor_list[5] != PCIIO_VENDOR_ID_NONE) && 
-	    (vendor_list[7] != PCIIO_VENDOR_ID_NONE)) {
-		/* soemthing in slot 5 and 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 2,1, 1,0, 3,0, 2,0);
-	}
-	else if (vendor_list[5] != PCIIO_VENDOR_ID_NONE) {
-		/* soemthing in slot 5 but not 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 3,0, 0,0);
-	}
-	else if (vendor_list[7] != PCIIO_VENDOR_ID_NONE) {
-		/* soemthing in slot 7 but not 5 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 0,0, 3,0);
-	}
-	else {
-		/* nothing in slot 5 or 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 4,1, 4,0, 0,0, 0,0);
-	}
-	if (rtn_val)
-		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-}
-
-
-/*
- * Initialize all I/O devices.  Starting closest to nodes, probe and
- * initialize outward.
- */
-void
-init_all_devices(void)
-{
-	/* Governor on init threads..bump up when safe 
-	 * (beware many devfs races) 
-	 */
-	cnodeid_t cnodeid, active;
-
-	active = 0;
-	for (cnodeid = 0; cnodeid < numnodes; cnodeid++) {
-                DBG("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid);
-                io_init_node(cnodeid);
-
-		DBG("init_all_devices: Done io_init_node() for cnode %d\n", cnodeid);
-	}
-
-	for (cnodeid = 0; cnodeid < numnodes; cnodeid++)
-		/*
-	 	 * Update information generated by IO init.
-		 */
-		update_node_information(cnodeid);
-
-	baseio_ctlr_num_set();
-	/* Setup the system critical graph (which is a subgraph of the
-	 * main hwgraph). This information is useful during io error
-	 * handling.
-	 */
-	sys_critical_graph_init();
-
-#if HWG_PRINT
-	hwgraph_print();
-#endif
-
-}
-
-#define toint(x) ((int)(x) - (int)('0'))
-
-void
-devnamefromarcs(char *devnm)
-{
-	int 			val;
-	char 			tmpnm[MAXDEVNAME];
-	char 			*tmp1, *tmp2;
-	
-	val = strncmp(devnm, "dks", 3);
-	if (val != 0) 
-		return;
-	tmp1 = devnm + 3;
-	if (!isdigit(*tmp1))
-		return;
-
-	val = 0;
-	while (isdigit(*tmp1)) {
-		val = 10*val+toint(*tmp1);
-		tmp1++;
-	}
-
-	if(*tmp1 != 'd')
-		return;
-	else
-		tmp1++;
-
-	if ((val < 0) || (val >= num_base_io_scsi_ctlr)) {
-		int i;
-		int viable_found = 0;
-
-		DBG("Only controller numbers 0..%d  are supported for\n", NUM_BASE_IO_SCSI_CTLR-1);
-		DBG("prom \"root\" variables of the form dksXdXsX.\n");
-		DBG("To use another disk you must use the full hardware graph path\n\n");
-		DBG("Possible controller numbers for use in 'dksXdXsX' on this system: ");
-		for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++) {
-			if (base_io_scsi_ctlr_vhdl[i] != GRAPH_VERTEX_NONE) {
-				DBG("%d ", i);
-				viable_found=1;
-			}
-		}
-		if (viable_found)
-			DBG("\n");
-		else
-			DBG("none found!\n");
-
-		DELAY(15000000);
-		//prom_reboot();
-		panic("FIXME: devnamefromarcs: should call prom_reboot here.\n");
-		/* NOTREACHED */
-	}
-		
-	ASSERT(base_io_scsi_ctlr_vhdl[val] != GRAPH_VERTEX_NONE);
-	vertex_to_name(base_io_scsi_ctlr_vhdl[val],
-		       tmpnm,
-		       MAXDEVNAME);
-	tmp2 = 	tmpnm + strlen(tmpnm);
-	strcpy(tmp2, __DEVSTR2);
-	tmp2 += strlen(__DEVSTR2);
-	while (*tmp1 != 's') {
-		if((*tmp2++ = *tmp1++) == '\0')
-			return;
-	}	
-	tmp1++;
-	strcpy(tmp2, __DEVSTR3);
-	tmp2 += strlen(__DEVSTR3);
-	while ( (*tmp2++ = *tmp1++) )
-		;
-	tmp2--;
-	*tmp2++ = '/';
-	strcpy(tmp2, EDGE_LBL_BLOCK);
-	strcpy(devnm,tmpnm);
-}
-
-static
-struct io_brick_map_s io_brick_tab[] = {
-
-/* Ibrick widget number to PCI bus number map */
- {      MODULE_IBRICK,                          /* Ibrick type    */ 
-    /*  PCI Bus #                                  Widget #       */
-    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        0,                                      /* 0x8            */
-        0,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        0,                                      /* 0xc            */
-        0,                                      /* 0xd            */
-        2,                                      /* 0xe            */
-        1                                       /* 0xf            */
-     }
- },
-
-/* Pbrick widget number to PCI bus number map */
- {      MODULE_PBRICK,                          /* Pbrick type    */ 
-    /*  PCI Bus #                                  Widget #       */
-    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        2,                                      /* 0x8            */
-        1,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        5,                                      /* 0xc            */
-        6,                                      /* 0xd            */
-        4,                                      /* 0xe            */
-        3                                       /* 0xf            */
-    }
- },
-
-/* PXbrick widget number to PCI bus number map */
- {      MODULE_PXBRICK,                         /* PXbrick type   */ 
-    /*  PCI Bus #                                  Widget #       */
-    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        0,                                      /* 0x8            */
-        0,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        1,                                      /* 0xc            */
-        5,                                      /* 0xd            */
-        0,                                      /* 0xe            */
-        3                                       /* 0xf            */
-    }
- },
-
-/* Xbrick widget to XIO slot map */
- {      MODULE_XBRICK,                          /* Xbrick type    */ 
-    /*  XIO Slot #                                 Widget #       */
-    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        1,                                      /* 0x8            */
-        3,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        2,                                      /* 0xc            */
-        4,                                      /* 0xd            */
-        0,                                      /* 0xe            */
-        0                                       /* 0xf            */
-    }
- }
-};
-
-/*
- * Use the brick's type to map a widget number to a meaningful int
- */
-int
-io_brick_map_widget(int brick_type, int widget_num)
-{
-        int num_bricks, i;
-
-        /* Calculate number of bricks in table */
-        num_bricks = sizeof(io_brick_tab)/sizeof(io_brick_tab[0]);
-
-        /* Look for brick prefix in table */
-        for (i = 0; i < num_bricks; i++) {
-               if (brick_type == io_brick_tab[i].ibm_type)
-                       return(io_brick_tab[i].ibm_map_wid[widget_num]);
-        }
-
-        return 0;
-
-}
-
-/*
- * Use the device's vertex to map the device's widget to a meaningful int
- */
-int
-io_path_map_widget(devfs_handle_t vertex)
-{
-        char hw_path_name[MAXDEVNAME];
-        char *wp, *bp, *sp = NULL;
-        int  widget_num;
-	long atoi(char *);
-	int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-
-
-        /* Get the full path name of the vertex */
-        if (GRAPH_SUCCESS != hwgraph_vertex_name_get(vertex, hw_path_name,
-                                                     MAXDEVNAME))
-                return 0;
-
-        /* Find the widget number in the path name */
-        wp = strstr(hw_path_name, "/"EDGE_LBL_XTALK"/");
-        if (wp == NULL)
-                return 0;
-        widget_num = atoi(wp+7);
-        if (widget_num < XBOW_PORT_8 || widget_num > XBOW_PORT_F)
-                return 0;
-
-        /* Find "brick" in the path name */
-        bp = strstr(hw_path_name, "brick");
-        if (bp == NULL)
-                return 0;
-
-        /* Find preceding slash */
-        sp = bp;
-        while (sp > hw_path_name) {
-                sp--;
-                if (*sp == '/')
-                        break;
-        }
-
-        /* Invalid if no preceding slash */
-        if (!sp)
-                return 0;
-
-        /* Bump slash pointer to "brick" prefix */
-        sp++;
-        /*
-         * Verify "brick" prefix length;  valid exaples:
-         * 'I' from "/Ibrick"
-         * 'P' from "/Pbrick"
-         * 'X' from "/Xbrick"
-         */
-         if ((bp - sp) != 1)
-                return 0;
-
-        return (io_brick_map_widget((int)*sp, widget_num));
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/module.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/module.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/module.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/module.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,311 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/module.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/sn_cpuid.h>
-
-
-/* #define LDEBUG	1 */
-
-#ifdef LDEBUG
-#define DPRINTF		printk
-#define printf		printk
-#else
-#define DPRINTF(x...)
-#endif
-
-module_t	       *modules[MODULE_MAX];
-int			nummodules;
-
-#define SN00_SERIAL_FUDGE	0x3b1af409d513c2
-#define SN0_SERIAL_FUDGE	0x6e
-
-void
-encode_int_serial(uint64_t src,uint64_t *dest)
-{
-    uint64_t val;
-    int i;
-
-    val = src + SN00_SERIAL_FUDGE;
-
-
-    for (i = 0; i < sizeof(long long); i++) {
-	((char*)dest)[i] =
-	    ((char*)&val)[sizeof(long long)/2 +
-			 ((i%2) ? ((i/2 * -1) - 1) : (i/2))];
-    }
-}
-
-
-void
-decode_int_serial(uint64_t src, uint64_t *dest)
-{
-    uint64_t val;
-    int i;
-
-    for (i = 0; i < sizeof(long long); i++) {
-	((char*)&val)[sizeof(long long)/2 +
-		     ((i%2) ? ((i/2 * -1) - 1) : (i/2))] =
-	    ((char*)&src)[i];
-    }
-
-    *dest = val - SN00_SERIAL_FUDGE;
-}
-
-
-void
-encode_str_serial(const char *src, char *dest)
-{
-    int i;
-
-    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
-
-	dest[i] = src[MAX_SERIAL_NUM_SIZE/2 +
-		     ((i%2) ? ((i/2 * -1) - 1) : (i/2))] +
-	    SN0_SERIAL_FUDGE;
-    }
-}
-
-void
-decode_str_serial(const char *src, char *dest)
-{
-    int i;
-
-    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
-	dest[MAX_SERIAL_NUM_SIZE/2 +
-	    ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = src[i] -
-	    SN0_SERIAL_FUDGE;
-    }
-}
-
-
-module_t *module_lookup(moduleid_t id)
-{
-    int			i;
-
-    for (i = 0; i < nummodules; i++)
-	if (modules[i]->id == id) {
-	    DPRINTF("module_lookup: found m=0x%p\n", modules[i]);
-	    return modules[i];
-	}
-
-    return NULL;
-}
-
-/*
- * module_add_node
- *
- *   The first time a new module number is seen, a module structure is
- *   inserted into the module list in order sorted by module number
- *   and the structure is initialized.
- *
- *   The node number is added to the list of nodes in the module.
- */
-
-module_t *module_add_node(moduleid_t id, cnodeid_t n)
-{
-    module_t	       *m;
-    int			i;
-    char		buffer[16];
-
-#ifdef __ia64
-    memset(buffer, 0, 16);
-    format_module_id(buffer, id, MODULE_FORMAT_BRIEF);
-    DPRINTF("module_add_node: id=%s node=%d\n", buffer, n);
-#endif
-
-    if ((m = module_lookup(id)) == 0) {
-#ifdef LATER
-	m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n);
-#else
-	m = kmalloc(sizeof (module_t), GFP_KERNEL);
-	memset(m, 0 , sizeof(module_t));
-#endif
-	ASSERT_ALWAYS(m);
-
-	m->id = id;
-	spin_lock_init(&m->lock);
-
-	mutex_init_locked(&m->thdcnt);
-
-	elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n));
-	spin_lock_init(&m->elsclock);
-
-	/* Insert in sorted order by module number */
-
-	for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--)
-	    modules[i] = modules[i - 1];
-
-	modules[i] = m;
-	nummodules++;
-    }
-
-    m->nodes[m->nodecnt++] = n;
-
-    DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt);
-
-    return m;
-}
-
-int module_probe_snum(module_t *m, nasid_t nasid)
-{
-    lboard_t	       *board;
-    klmod_serial_num_t *comp;
-    char * bcopy(const char * src, char * dest, int count);
-    char serial_number[16];
-
-    /*
-     * record brick serial number
-     */
-    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-
-    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
-    {
-#if	LDEBUG
-	printf ("module_probe_snum: no IP35 board found!\n");
-#endif
-	return 0;
-    }
-
-    board_serial_number_get( board, serial_number );
-    if( serial_number[0] != '\0' ) {
-	encode_str_serial( serial_number, m->snum.snum_str );
-	m->snum_valid = 1;
-    }
-#if	LDEBUG
-    else {
-	printf("module_probe_snum: brick serial number is null!\n");
-    }
-    printf("module_probe_snum: brick serial number == %s\n", serial_number);
-#endif /* DEBUG */
-
-    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
-			KLTYPE_IOBRICK_XBOW);
-
-    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
-	return 0;
-
-    comp = GET_SNUM_COMP(board);
-
-    if (comp) {
-#if LDEBUG
-	    int i;
-
-	    printf("********found module with id %x and string", m->id);
-
-	    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++)
-		printf(" %x ", comp->snum.snum_str[i]);
-
-	    printf("\n");	/* Fudged string is not ASCII */
-#endif
-
-	    if (comp->snum.snum_str[0] != '\0') {
-		bcopy(comp->snum.snum_str,
-		      m->sys_snum,
-		      MAX_SERIAL_NUM_SIZE);
-		m->sys_snum_valid = 1;
-	    }
-    }
-
-    if (m->sys_snum_valid)
-	return 1;
-    else {
-	DPRINTF("Invalid serial number for module %d, "
-		"possible missing or invalid NIC.", m->id);
-	return 0;
-    }
-}
-
-void
-io_module_init(void)
-{
-    cnodeid_t		node;
-    lboard_t	       *board;
-    nasid_t		nasid;
-    int			nserial;
-    module_t	       *m;
-
-    DPRINTF("*******module_init\n");
-
-    nserial = 0;
-
-    for (node = 0; node < numnodes; node++) {
-	nasid = COMPACT_TO_NASID_NODEID(node);
-
-	board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-	ASSERT(board);
-
-	m = module_add_node(board->brd_module, node);
-
-	if (! m->snum_valid && module_probe_snum(m, nasid))
-	    nserial++;
-    }
-
-    DPRINTF("********found total of %d serial numbers in the system\n",
-	    nserial);
-
-    if (nserial == 0)
-	printk(KERN_WARNING  "io_module_init: No serial number found.\n");
-}
-
-elsc_t *get_elsc(void)
-{
-	return &NODEPDA(cpuid_to_cnodeid(smp_processor_id()))->module->elsc;
-}
-
-int
-get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info)
-{
-    int i;
-
-    if (cmod < 0 || cmod >= nummodules)
-	return -EINVAL;
-
-    if (! modules[cmod]->snum_valid)
-	return -ENXIO;
-
-    mod_info->mod_num = modules[cmod]->id;
-    {
-	char temp[MAX_SERIAL_NUM_SIZE];
-
-	decode_str_serial(modules[cmod]->snum.snum_str, temp);
-
-	/* if this is an invalid serial number return an error */
-	if (temp[0] != 'K')
-	    return -ENXIO;
-
-	mod_info->serial_num = 0;
-
-	for (i = 0; i < MAX_SERIAL_NUM_SIZE && temp[i] != '\0'; i++) {
-	    mod_info->serial_num <<= 4;
-	    mod_info->serial_num |= (temp[i] & 0xf);
-
-	    mod_info->serial_str[i] = temp[i];
-	}
-
-	mod_info->serial_str[i] = '\0';
-    }
-
-    return 0;
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/pci_bus_cvlink.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/pci_bus_cvlink.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/pci_bus_cvlink.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/pci_bus_cvlink.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,696 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <asm/sn/types.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/sn_cpuid.h>
-
-extern int bridge_rev_b_data_check_disable;
-
-devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
-nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
-void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
-unsigned char num_bridges;
-static int done_probing = 0;
-
-static int pci_bus_map_create(devfs_handle_t xtalk);
-devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-#define SN_IOPORTS_UNIT 256
-#define MAX_IOPORTS 0xffff
-#define MAX_IOPORTS_CHUNKS (MAX_IOPORTS / SN_IOPORTS_UNIT)
-struct ioports_to_tlbs_s ioports_to_tlbs[MAX_IOPORTS_CHUNKS];
-unsigned long sn_allocate_ioports(unsigned long pci_address);
-extern unsigned char Is_pic_on_this_nasid[512];
-
-extern void sn_init_irq_desc(void);
-
-
-/*
- * For the given device, initialize whether it is a PIC device.
- */
-static void
-set_isPIC(struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-	device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);;
-}
-
-/*
- * pci_bus_cvlink_init() - To be called once during initialization before 
- *	SGI IO Infrastructure init is called.
- */
-void
-pci_bus_cvlink_init(void)
-{
-	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET);
-	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
-
-	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
-
-	memset(ioports_to_tlbs, 0x0, sizeof(ioports_to_tlbs));
-
-	num_bridges = 0;
-}
-
-/*
- * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
- *	pci bus vertex from the SGI IO Infrastructure.
- */
-devfs_handle_t
-pci_bus_to_vertex(unsigned char busnum)
-{
-
-	devfs_handle_t	pci_bus = NULL;
-
-
-	/*
-	 * First get the xwidget vertex.
-	 */
-	pci_bus = busnum_to_pcibr_vhdl[busnum];
-	return(pci_bus);
-}
-
-/*
- * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
- *	and function numbers.
- */
-devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn)
-{
-
-	int slot = 0;
-	int func = 0;
-	char	name[16];
-	devfs_handle_t  pci_bus = NULL;
-	devfs_handle_t	device_vertex = (devfs_handle_t)NULL;
-
-	/*
-	 * Go get the pci bus vertex.
-	 */
-	pci_bus = pci_bus_to_vertex(busnum);
-	if (!pci_bus) {
-		/*
-		 * During probing, the Linux pci code invents non existant
-		 * bus numbers and pci_dev structures and tries to access
-		 * them to determine existance. Don't crib during probing.
-		 */
-		if (done_probing)
-			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
-		return(NULL);
-	}
-
-
-	/*
-	 * Go get the slot&function vertex.
-	 * Should call pciio_slot_func_to_name() when ready.
-	 */
-	slot = PCI_SLOT(devfn);
-	func = PCI_FUNC(devfn);
-
-	/*
-	 * For a NON Multi-function card the name of the device looks like:
-	 * ../pci/1, ../pci/2 ..
-	 */
-	if (func == 0) {
-        	sprintf(name, "%d", slot);
-		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
-			GRAPH_SUCCESS) {
-			if (device_vertex) {
-				return(device_vertex);
-			}
-		}
-	}
-			
-	/*
-	 * This maybe a multifunction card.  It's names look like:
-	 * ../pci/1a, ../pci/1b, etc.
-	 */
-	sprintf(name, "%d%c", slot, 'a'+func);
-	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
-		if (!device_vertex) {
-			return(NULL);
-		}
-	}
-
-	return(device_vertex);
-}
-
-/*
- * For the given device, initialize the addresses for both the Device(x) Flush 
- * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
- * is connected.
- */
-static void
-set_flush_addresses(struct pci_dev *device_dev, 
-	struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	device_sysdata->dma_buf_sync = (volatile unsigned int *) 
-		&(bridge->b_wr_req_buf[pciio_slot].reg);
-	device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-		XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(get_nasid(), 0), 
-		pcibr_soft->bs_xid);
-#ifdef DEBUG
-
-	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
-		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
-
-	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
-	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
-#endif
-
-}
-
-/*
- * Most drivers currently do not properly tell the arch specific pci dma
- * interfaces whether they can handle A64. Here is where we privately
- * keep track of this.
- */
-static void __init
-set_sn_pci64(struct pci_dev *dev)
-{
-	unsigned short vendor = dev->vendor;
-	unsigned short device = dev->device;
-
-	if (vendor == PCI_VENDOR_ID_QLOGIC) {
-		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
-				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-	if (vendor == PCI_VENDOR_ID_SGI) {
-		if (device == PCI_DEVICE_ID_SGI_IOC3) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-}
-
-/*
- * sn_allocate_ioports() - This routine provides the allocation and 
- *	mappings between Linux style IOPORTs management.
- *
- *	For simplicity sake, SN1 will allocate IOPORTs in chunks of 
- *	256bytes .. irrespective of what the card desires.  This may 
- *	have to change when we understand how to deal with legacy ioports 
- *	which are hardcoded in some drivers e.g. SVGA.
- *
- *	Ofcourse, the SN1 IO Infrastructure has no concept of IOPORT numbers.
- *	It will remain so.  The IO Infrastructure will continue to map 
- *	IO Resource just like IRIX.  When this is done, we map IOPORT 
- *	chunks to these resources.  The Linux drivers will see and use real 
- *	IOPORT numbers.  The various IOPORT access macros e.g. inb/outb etc. 
- *	does the munging of these IOPORT numbers to make a Uncache Virtual 
- *	Address.  This address via the tlb entries generates the PCI Address 
- *	allocated by the SN1 IO Infrastructure Layer.
- */
-static unsigned long sn_ioport_num = 0x1000; /* Reserve room for Legacy stuff */
-unsigned long
-sn_allocate_ioports(unsigned long pci_address)
-{
-	
-	unsigned long ioport_index;
-
-	/*
-	 * Just some idiot checking ..
-	 */
-	if ( sn_ioport_num > 0xffff ) {
-		printk("sn_allocate_ioports: No more IO PORTS available\n");
-		return(-1);
-	}
-
-	/*
-	 * See Section 4.1.1.5 of Intel IA-64 Acrchitecture Software Developer's
-	 * Manual for details.
-	 */
-	ioport_index = sn_ioport_num / SN_IOPORTS_UNIT;
-
-	ioports_to_tlbs[ioport_index].p = 1; /* Present Bit */
-	ioports_to_tlbs[ioport_index].rv_1 = 0; /* 1 Bit */
-	ioports_to_tlbs[ioport_index].ma = 4; /* Memory Attributes 3 bits*/
-	ioports_to_tlbs[ioport_index].a = 1; /* Set Data Access Bit Fault 1 Bit*/
-	ioports_to_tlbs[ioport_index].d = 1; /* Dirty Bit */
-	ioports_to_tlbs[ioport_index].pl = 0;/* Privilege Level - All levels can R/W*/
-	ioports_to_tlbs[ioport_index].ar = 3; /* Access Rights - R/W only*/
-	ioports_to_tlbs[ioport_index].ppn = pci_address >> 12; /* 4K page size */
-	ioports_to_tlbs[ioport_index].ed = 0; /* Exception Deferral Bit */
-	ioports_to_tlbs[ioport_index].ig = 0; /* Ignored */
-
-	/* printk("sn_allocate_ioports: ioport_index 0x%x ioports_to_tlbs 0x%p\n", ioport_index, ioports_to_tlbs[ioport_index]); */
-	
-	sn_ioport_num += SN_IOPORTS_UNIT;
-
-	return(sn_ioport_num - SN_IOPORTS_UNIT);
-}
-
-/*
- * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
- *	invoked at the end of pcibios_init() to link the Linux pci 
- *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
- *
- *	Other platform specific fixup can also be done here.
- */
-void
-sn_pci_fixup(int arg)
-{
-	struct list_head *ln;
-	struct pci_bus *pci_bus = NULL;
-	struct pci_dev *device_dev = NULL;
-	struct sn_widget_sysdata *widget_sysdata;
-	struct sn_device_sysdata *device_sysdata;
-#ifdef SN_IOPORTS
-	unsigned long ioport;
-#endif
-	pciio_intr_t intr_handle;
-	int cpuid, bit;
-	devfs_handle_t device_vertex;
-	pciio_intr_line_t lines;
-	extern void sn_pci_find_bios(void);
-
-	if (arg == 0) {
-		sn_init_irq_desc();
-		sn_pci_find_bios();
-		return;
-	}
-
-	done_probing = 1;
-
-	/*
-	 * Initialize the pci bus vertex in the pci_bus struct.
-	 */
-	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		pci_bus = pci_bus_b(ln);
-		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
-					GFP_KERNEL);
-		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
-		pci_bus->sysdata = (void *)widget_sysdata;
-	}
-
-	/*
- 	 * set the root start and end so that drivers calling check_region()
-	 * won't see a conflict
-	 */
-#ifdef SN_IOPORTS
-	ioport_resource.start  = sn_ioport_num;
-	ioport_resource.end = 0xffff;
-#else
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		/*
-		 * IDE legacy IO PORTs are supported in Medusa.
-		 * Just open up IO PORTs from 0 .. ioport_resource.end.
-		 */
-		ioport_resource.start = 0;
-	} else {
-		/*
-		 * We do not support Legacy IO PORT numbers.
-		 */
-		ioport_resource.start |= IO_SWIZ_BASE | __IA64_UNCACHED_OFFSET;
-	}
-	ioport_resource.end |= (HSPEC_SWIZ_BASE-1) | __IA64_UNCACHED_OFFSET;
-#endif
-
-	/*
-	 * Set the root start and end for Mem Resource.
-	 */
-	iomem_resource.start = 0;
-	iomem_resource.end = 0xffffffffffffffff;
-
-	/*
-	 * Initialize the device vertex in the pci_dev struct.
-	 */
-	pci_for_each_dev(device_dev) {
-		unsigned int irq;
-		int idx;
-		u16 cmd;
-		devfs_handle_t vhdl;
-		unsigned long size;
-		extern int bit_pos_to_irq(int);
-
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
-			extern void pci_fixup_ioc3(struct pci_dev *d);
-			pci_fixup_ioc3(device_dev);
-		}
-
-		/* Set the device vertex */
-
-		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
-					GFP_KERNEL);
-		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
-		device_sysdata->isa64 = 0;
-		/*
-		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
-		 * register addresses.
-		 */
-		(void) set_flush_addresses(device_dev, device_sysdata);
-
-		device_dev->sysdata = (void *) device_sysdata;
-		set_sn_pci64(device_dev);
-		set_isPIC(device_sysdata);
-
-		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
-
-		/*
-		 * Set the resources address correctly.  The assumption here 
-		 * is that the addresses in the resource structure has been
-		 * read from the card and it was set in the card by our
-		 * Infrastructure ..
-		 */
-		vhdl = device_sysdata->vhdl;
-		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
-			size = 0;
-			size = device_dev->resource[idx].end -
-				device_dev->resource[idx].start;
-			if (size) {
-				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
-				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
-			}
-			else
-				continue;
-
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].start + size;
-
-			/*
-			 * Adjust the addresses to go to the SWIZZLE ..
-			 */
-			device_dev->resource[idx].start = 
-				device_dev->resource[idx].start & 0xfffff7ffffffffff;
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].end & 0xfffff7ffffffffff;
-
-			if (device_dev->resource[idx].flags & IORESOURCE_IO) {
-				cmd |= PCI_COMMAND_IO;
-#ifdef SN_IOPORTS
-				ioport = sn_allocate_ioports(device_dev->resource[idx].start);
-				if (ioport < 0) {
-					printk("sn_pci_fixup: PCI Device 0x%x on PCI Bus %d not mapped to IO PORTs .. IO PORTs exhausted\n", device_dev->devfn, device_dev->bus->number);
-					continue;
-				}
-				pciio_config_set(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + (idx * 4), 4, (res + (ioport & 0xfff)));
-
-				printk("sn_pci_fixup: ioport number %d mapped to pci address 0x%lx\n", ioport, (res + (ioport & 0xfff)));
-
-				device_dev->resource[idx].start = ioport;
-				device_dev->resource[idx].end = ioport + SN_IOPORTS_UNIT;
-#endif
-			}
-			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
-				cmd |= PCI_COMMAND_MEMORY;
-		}
-		/*
-		 * Now handle the ROM resource ..
-		 */
-		size = device_dev->resource[PCI_ROM_RESOURCE].end -
-			device_dev->resource[PCI_ROM_RESOURCE].start;
-
-		if (size) {
-			device_dev->resource[PCI_ROM_RESOURCE].start =
-			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
-				size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
-			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
-			device_dev->resource[PCI_ROM_RESOURCE].end =
-			device_dev->resource[PCI_ROM_RESOURCE].start + size;
-
-                	/*
-                 	 * go through synergy swizzled space
-                 	 */
-			device_dev->resource[PCI_ROM_RESOURCE].start &= 0xfffff7ffffffffffUL;
-			device_dev->resource[PCI_ROM_RESOURCE].end   &= 0xfffff7ffffffffffUL;
-
-		}
-
-		/*
-		 * Update the Command Word on the Card.
-		 */
-		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
-					   /* bit gets dropped .. no harm */
-		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
-
-		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-				lines = 1;
-		}
- 
-		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
-		device_vertex = device_sysdata->vhdl;
- 
-		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
-
-		bit = intr_handle->pi_irq;
-		cpuid = intr_handle->pi_cpu;
-		irq = bit_pos_to_irq(bit);
-		irq = irq + (cpuid << 8);
-		pciio_intr_connect(intr_handle);
-		device_dev->irq = irq;
-#ifdef ajmtestintr
-		{
-			int slot = PCI_SLOT(device_dev->devfn);
-			static int timer_set = 0;
-			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
-			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
-			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
-
-			if (!timer_set) {
-				intr_test_set_timer();
-				timer_set = 1;
-			}
-			intr_test_register_irq(irq, pcibr_soft, slot);
-			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
-		}
-#endif
-
-	}
-}
-
-/*
- * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
- *
- *	Linux PCI Bus numbers are assigned from lowest module_id numbers
- *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
- *	HUB_WIDGET_ID_MIN:
- *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
- *
- *	Given 2 modules 001c01 and 001c02 we get the following mappings:
- *		001c01, widgetnum 15 = Bus number 0
- *		001c01, widgetnum 14 = Bus number 1
- *		001c02, widgetnum 15 = Bus number 3
- *		001c02, widgetnum 14 = Bus number 4
- *		etc.
- *
- * The rational for starting Bus Number 0 with Widget number 15 is because 
- * the system boot disks are always connected via Widget 15 Slot 0 of the 
- * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
- * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
- * module id(Master Cnode) of the system.
- *	
- */
-static int 
-pci_bus_map_create(devfs_handle_t xtalk)
-{
-
-	devfs_handle_t master_node_vertex = NULL;
-	devfs_handle_t xwidget = NULL;
-	devfs_handle_t pci_bus = NULL;
-	hubinfo_t hubinfo = NULL;
-	xwidgetnum_t widgetnum;
-	char pathname[128];
-	graph_error_t rv;
-
-	/*
-	 * Loop throught this vertex and get the Xwidgets ..
-	 */
-	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
-
-#if 0
-        {
-                int pos;
-                char dname[256];
-                pos = devfs_generate_path(xtalk, dname, 256);
-                printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-        }
-#endif
-
-		sprintf(pathname, "%d", widgetnum);
-		xwidget = NULL;
-		
-		/*
-		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
-		 */
-		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-		if ( (rv != GRAPH_SUCCESS) ) {
-			if (!xwidget) {
-				continue;
-}
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		pci_bus = NULL;
-		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-			if (!pci_bus) {
-				continue;
-}
-
-		/*
-		 * Assign the correct bus number and also the nasid of this 
-		 * pci Xwidget.
-		 * 
-		 * Should not be any race here ...
-		 */
-		num_bridges++;
-		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
-
-		/*
-		 * Get the master node and from there get the NASID.
-		 */
-		master_node_vertex = device_master_get(xwidget);
-		if (!master_node_vertex) {
-			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
-		}
-	
-		hubinfo_get(master_node_vertex, &hubinfo);
-		if (!hubinfo) {
-			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
-			return(1);
-		} else {
-			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
-		}
-
-		/*
-		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-		 */
-		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-		if (!busnum_to_atedmamaps[num_bridges - 1])
-			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-
-		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
-
-	}
-
-        return(0);
-}
-
-/*
- * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
- *      initialization has completed to set up the mappings between Xbridge
- *      and logical pci bus numbers.  We also set up the NASID for each of these
- *      xbridges.
- *
- *      Must be called before pci_init() is invoked.
- */
-int
-pci_bus_to_hcl_cvlink(void) 
-{
-
-	devfs_handle_t devfs_hdl = NULL;
-	devfs_handle_t xtalk = NULL;
-	int rv = 0;
-	char name[256];
-	int master_iobrick;
-	int i;
-
-	/*
-	 * Iterate throught each xtalk links in the system ..
-	 * /hw/module/001c01/node/xtalk/ 8|9|10|11|12|13|14|15 
-	 *
-	 * /hw/module/001c01/node/xtalk/15 -> /hw/module/001c01/Ibrick/xtalk/15
-	 *
-	 * What if it is not pci?
-	 */
-	devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");
-
-	/*
-	 * To provide consistent(not persistent) device naming, we need to start 
-	 * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 
-	 * with an attached I-Brick.  Find the master_iobrick.
-	 */
-	master_iobrick = -1;
-	for (i = 0; i < nummodules; i++) {
-		moduleid_t iobrick_id; 
-		iobrick_id = iobrick_module_get(&modules[i]->elsc);
-		if (iobrick_id > 0) { /* Valid module id */
-			if (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) {
-				master_iobrick = i;
-				break;
-			}
-		}
-	}
-
-	/*
-	 * The master_iobrick gets bus 0 and 1.
-	 */
-	if (master_iobrick >= 0) {
-		memset(name, 0, 256);
-		format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF);
-		strcat(name, "/node/xtalk");
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-		
-	/*
-	 * Now go do the rest of the modules, starting from the C-Brick with the lowest 
-	 * module id, remembering to skip the master_iobrick, which was done above.
-	 */
-	for (i = 0; i < nummodules; i++) {
-		if (i == master_iobrick) {
-			continue; /* Did the master_iobrick already. */
-		}
-
-		memset(name, 0, 256);
-		format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
-		strcat(name, "/node/xtalk");
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-
-	return(0);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/pcibr.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/pcibr.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/pcibr.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/pcibr.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,7704 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-int NeedXbridgeSwap = 0;
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_defs.h>
-#include <asm/sn/prio.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_private.h>
-
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
-extern boolean_t                is_sys_critical_vertex(devfs_handle_t);
-
-#undef PCIBR_ATE_DEBUG
-
-#if 0
-#define DEBUG 1	 /* To avoid lots of bad printk() formats leave off */
-#endif
-#define PCI_DEBUG 1
-#define ATTACH_DEBUG 1
-#define PCIBR_SOFT_LIST 1
-
-#ifndef	LOCAL
-#define	LOCAL		static
-#endif
-
-/*
- * Macros related to the Lucent USS 302/312 usb timeout workaround.  It
- * appears that if the lucent part can get into a retry loop if it sees a
- * DAC on the bus during a pio read retry.  The loop is broken after about
- * 1ms, so we need to set up bridges holding this part to allow at least
- * 1ms for pio.
- */
-
-#define USS302_TIMEOUT_WAR
-
-#ifdef USS302_TIMEOUT_WAR
-#define LUCENT_USBHC_VENDOR_ID_NUM	0x11c1
-#define LUCENT_USBHC302_DEVICE_ID_NUM	0x5801
-#define LUCENT_USBHC312_DEVICE_ID_NUM	0x5802
-#define USS302_BRIDGE_TIMEOUT_HLD	4
-#endif
-
-#define PCIBR_LLP_CONTROL_WAR
-#if defined (PCIBR_LLP_CONTROL_WAR)
-int                     pcibr_llp_control_war_cnt;
-#endif				/* PCIBR_LLP_CONTROL_WAR */
-
-int                     pcibr_devflag = D_MP;
-
-#ifdef LATER
-#define F(s,n)		{ 1l<<(s),-(s), n }
-
-struct reg_desc         bridge_int_status_desc[] =
-{
-    F(31, "MULTI_ERR"),
-    F(30, "PMU_ESIZE_EFAULT"),
-    F(29, "UNEXPECTED_RESP"),
-    F(28, "BAD_XRESP_PACKET"),
-    F(27, "BAD_XREQ_PACKET"),
-    F(26, "RESP_XTALK_ERROR"),
-    F(25, "REQ_XTALK_ERROR"),
-    F(24, "INVALID_ADDRESS"),
-    F(23, "UNSUPPORTED_XOP"),
-    F(22, "XREQ_FIFO_OFLOW"),
-    F(21, "LLP_REC_SNERROR"),
-    F(20, "LLP_REC_CBERROR"),
-    F(19, "LLP_RCTY"),
-    F(18, "LLP_TX_RETRY"),
-    F(17, "LLP_TCTY"),
-    F(16, "SSRAM_PERR"),
-    F(15, "PCI_ABORT"),
-    F(14, "PCI_PARITY"),
-    F(13, "PCI_SERR"),
-    F(12, "PCI_PERR"),
-    F(11, "PCI_MASTER_TOUT"),
-    F(10, "PCI_RETRY_CNT"),
-    F(9, "XREAD_REQ_TOUT"),
-    F(8, "GIO_BENABLE_ERR"),
-    F(7, "INT7"),
-    F(6, "INT6"),
-    F(5, "INT5"),
-    F(4, "INT4"),
-    F(3, "INT3"),
-    F(2, "INT2"),
-    F(1, "INT1"),
-    F(0, "INT0"),
-    {0}
-};
-
-struct reg_values       space_v[] =
-{
-    {PCIIO_SPACE_NONE, "none"},
-    {PCIIO_SPACE_ROM, "ROM"},
-    {PCIIO_SPACE_IO, "I/O"},
-    {PCIIO_SPACE_MEM, "MEM"},
-    {PCIIO_SPACE_MEM32, "MEM(32)"},
-    {PCIIO_SPACE_MEM64, "MEM(64)"},
-    {PCIIO_SPACE_CFG, "CFG"},
-    {PCIIO_SPACE_WIN(0), "WIN(0)"},
-    {PCIIO_SPACE_WIN(1), "WIN(1)"},
-    {PCIIO_SPACE_WIN(2), "WIN(2)"},
-    {PCIIO_SPACE_WIN(3), "WIN(3)"},
-    {PCIIO_SPACE_WIN(4), "WIN(4)"},
-    {PCIIO_SPACE_WIN(5), "WIN(5)"},
-    {PCIIO_SPACE_BAD, "BAD"},
-    {0}
-};
-
-struct reg_desc         space_desc[] =
-{
-    {0xFF, 0, "space", 0, space_v},
-    {0}
-};
-
-#if DEBUG
-#define	device_desc	device_bits
-LOCAL struct reg_desc   device_bits[] =
-{
-    {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"},
-    {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"},
-    {BRIDGE_DEV_FORCE_PCI_PAR, 0, "FORCE_PCI_PAR"},
-    {BRIDGE_DEV_VIRTUAL_EN, 0, "VIRTUAL_EN"},
-    {BRIDGE_DEV_PMU_WRGA_EN, 0, "PMU_WRGA_EN"},
-    {BRIDGE_DEV_DIR_WRGA_EN, 0, "DIR_WRGA_EN"},
-    {BRIDGE_DEV_DEV_SIZE, 0, "DEV_SIZE"},
-    {BRIDGE_DEV_RT, 0, "RT"},
-    {BRIDGE_DEV_SWAP_PMU, 0, "SWAP_PMU"},
-    {BRIDGE_DEV_SWAP_DIR, 0, "SWAP_DIR"},
-    {BRIDGE_DEV_PREF, 0, "PREF"},
-    {BRIDGE_DEV_PRECISE, 0, "PRECISE"},
-    {BRIDGE_DEV_COH, 0, "COH"},
-    {BRIDGE_DEV_BARRIER, 0, "BARRIER"},
-    {BRIDGE_DEV_GBR, 0, "GBR"},
-    {BRIDGE_DEV_DEV_SWAP, 0, "DEV_SWAP"},
-    {BRIDGE_DEV_DEV_IO_MEM, 0, "DEV_IO_MEM"},
-    {BRIDGE_DEV_OFF_MASK, BRIDGE_DEV_OFF_ADDR_SHFT, "DEV_OFF", "%x"},
-    {0}
-};
-#endif	/* DEBUG */
-
-#ifdef SUPPORT_PRINTING_R_FORMAT
-LOCAL struct reg_values xio_cmd_pactyp[] =
-{
-    {0x0, "RdReq"},
-    {0x1, "RdResp"},
-    {0x2, "WrReqWithResp"},
-    {0x3, "WrResp"},
-    {0x4, "WrReqNoResp"},
-    {0x5, "Reserved(5)"},
-    {0x6, "FetchAndOp"},
-    {0x7, "Reserved(7)"},
-    {0x8, "StoreAndOp"},
-    {0x9, "Reserved(9)"},
-    {0xa, "Reserved(a)"},
-    {0xb, "Reserved(b)"},
-    {0xc, "Reserved(c)"},
-    {0xd, "Reserved(d)"},
-    {0xe, "SpecialReq"},
-    {0xf, "SpecialResp"},
-    {0}
-};
-
-LOCAL struct reg_desc   xio_cmd_bits[] =
-{
-    {WIDGET_DIDN, -28, "DIDN", "%x"},
-    {WIDGET_SIDN, -24, "SIDN", "%x"},
-    {WIDGET_PACTYP, -20, "PACTYP", 0, xio_cmd_pactyp},
-    {WIDGET_TNUM, -15, "TNUM", "%x"},
-    {WIDGET_COHERENT, 0, "COHERENT"},
-    {WIDGET_DS, 0, "DS"},
-    {WIDGET_GBR, 0, "GBR"},
-    {WIDGET_VBPM, 0, "VBPM"},
-    {WIDGET_ERROR, 0, "ERROR"},
-    {WIDGET_BARRIER, 0, "BARRIER"},
-    {0}
-};
-#endif	/* SUPPORT_PRINTING_R_FORMAT */
-
-#if PCIBR_FREEZE_TIME || PCIBR_ATE_DEBUG
-LOCAL struct reg_desc   ate_bits[] =
-{
-    {0xFFFF000000000000ull, -48, "RMF", "%x"},
-    {~(IOPGSIZE - 1) &			/* may trim off some low bits */
-     0x0000FFFFFFFFF000ull, 0, "XIO", "%x"},
-    {0x0000000000000F00ull, -8, "port", "%x"},
-    {0x0000000000000010ull, 0, "Barrier"},
-    {0x0000000000000008ull, 0, "Prefetch"},
-    {0x0000000000000004ull, 0, "Precise"},
-    {0x0000000000000002ull, 0, "Coherent"},
-    {0x0000000000000001ull, 0, "Valid"},
-    {0}
-};
-#endif
-
-#if PCIBR_ATE_DEBUG
-LOCAL struct reg_values ssram_sizes[] =
-{
-    {BRIDGE_CTRL_SSRAM_512K, "512k"},
-    {BRIDGE_CTRL_SSRAM_128K, "128k"},
-    {BRIDGE_CTRL_SSRAM_64K, "64k"},
-    {BRIDGE_CTRL_SSRAM_1K, "1k"},
-    {0}
-};
-
-LOCAL struct reg_desc   control_bits[] =
-{
-    {BRIDGE_CTRL_FLASH_WR_EN, 0, "FLASH_WR_EN"},
-    {BRIDGE_CTRL_EN_CLK50, 0, "EN_CLK50"},
-    {BRIDGE_CTRL_EN_CLK40, 0, "EN_CLK40"},
-    {BRIDGE_CTRL_EN_CLK33, 0, "EN_CLK33"},
-    {BRIDGE_CTRL_RST_MASK, -24, "RST", "%x"},
-    {BRIDGE_CTRL_IO_SWAP, 0, "IO_SWAP"},
-    {BRIDGE_CTRL_MEM_SWAP, 0, "MEM_SWAP"},
-    {BRIDGE_CTRL_PAGE_SIZE, 0, "PAGE_SIZE"},
-    {BRIDGE_CTRL_SS_PAR_BAD, 0, "SS_PAR_BAD"},
-    {BRIDGE_CTRL_SS_PAR_EN, 0, "SS_PAR_EN"},
-    {BRIDGE_CTRL_SSRAM_SIZE_MASK, 0, "SSRAM_SIZE", 0, ssram_sizes},
-    {BRIDGE_CTRL_F_BAD_PKT, 0, "F_BAD_PKT"},
-    {BRIDGE_CTRL_LLP_XBAR_CRD_MASK, -12, "LLP_XBAR_CRD", "%d"},
-    {BRIDGE_CTRL_CLR_RLLP_CNT, 0, "CLR_RLLP_CNT"},
-    {BRIDGE_CTRL_CLR_TLLP_CNT, 0, "CLR_TLLP_CNT"},
-    {BRIDGE_CTRL_SYS_END, 0, "SYS_END"},
-    {BRIDGE_CTRL_MAX_TRANS_MASK, -4, "MAX_TRANS", "%d"},
-    {BRIDGE_CTRL_WIDGET_ID_MASK, 0, "WIDGET_ID", "%x"},
-    {0}
-};
-#endif
-#endif	/* LATER */
-
-/* kbrick widgetnum-to-bus layout */
-int p_busnum[MAX_PORT_NUM] = {                  /* widget#      */
-        0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7    */
-        2,                                      /* 0x8          */
-        1,                                      /* 0x9          */
-        0, 0,                                   /* 0xa - 0xb    */
-        5,                                      /* 0xc          */
-        6,                                      /* 0xd          */
-        4,                                      /* 0xe          */
-        3,                                      /* 0xf          */
-};
-
-/*
- * Additional PIO spaces per slot are
- * recorded in this structure.
- */
-struct pciio_piospace_s {
-    pciio_piospace_t        next;	/* another space for this device */
-    char                    free;	/* 1 if free, 0 if in use               */
-    pciio_space_t           space;	/* Which space is in use                */
-    iopaddr_t               start;	/* Starting address of the PIO space    */
-    size_t                  count;	/* size of PIO space                    */
-};
-
-#if PCIBR_SOFT_LIST
-pcibr_list_p            pcibr_list = 0;
-#endif
-
-#define	INFO_LBL_PCIBR_ASIC_REV	"_pcibr_asic_rev"
-
-#define	PCIBR_D64_BASE_UNSET	(0xFFFFFFFFFFFFFFFF)
-#define	PCIBR_D32_BASE_UNSET	(0xFFFFFFFF)
-
-#define PCIBR_VALID_SLOT(s)	(s < 8)
-
-#ifdef SN_XXX
-extern int      hub_device_flags_set(devfs_handle_t       widget_dev,
-                                     hub_widget_flags_t flags);
-#endif
-extern pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
-extern void free_pciio_dmamap(pcibr_dmamap_t);
-
-/*
- * This is the file operation table for the pcibr driver.
- * As each of the functions are implemented, put the 
- * appropriate function name below.
- */
-struct file_operations pcibr_fops = {
-        owner:  THIS_MODULE,
-        llseek: NULL,
-        read: NULL,
-        write: NULL,
-        readdir: NULL,
-        poll: NULL,
-        ioctl: NULL,
-        mmap: NULL,
-        open: NULL,
-        flush: NULL,
-        release: NULL,
-        fsync: NULL,
-        fasync: NULL,
-        lock: NULL,
-        readv: NULL,
-        writev: NULL
-};
-
-extern devfs_handle_t hwgraph_root;
-extern graph_error_t hwgraph_vertex_unref(devfs_handle_t vhdl);
-extern int cap_able(uint64_t x);
-extern uint64_t rmalloc(struct map *mp, size_t size);
-extern void rmfree(struct map *mp, size_t size, uint64_t a);
-extern int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-extern long atoi(register char *p);
-extern char *dev_to_name(devfs_handle_t dev, char *buf, uint buflen);
-extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t vhdl);
-extern graph_error_t hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr);
-extern struct map *rmallocmap(uint64_t mapsiz);
-extern void rmfreemap(struct map *mp);
-extern int compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr);
-extern int io_path_map_widget(devfs_handle_t vertex);
-
-
-
-/* =====================================================================
- *    Function Table of Contents
- *
- *      The order of functions in this file has stopped
- *      making much sense. We might want to take a look
- *      at it some time and bring back some sanity, or
- *      perhaps bust this file into smaller chunks.
- */
-
-LOCAL void              do_pcibr_rrb_clear(bridge_t *, int);
-LOCAL void              do_pcibr_rrb_flush(bridge_t *, int);
-LOCAL int               do_pcibr_rrb_count_valid(bridge_t *, pciio_slot_t);
-LOCAL int               do_pcibr_rrb_count_avail(bridge_t *, pciio_slot_t);
-LOCAL int               do_pcibr_rrb_alloc(bridge_t *, pciio_slot_t, int);
-LOCAL int               do_pcibr_rrb_free(bridge_t *, pciio_slot_t, int);
-
-LOCAL void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int);
-
-int			pcibr_wrb_flush(devfs_handle_t);
-int                     pcibr_rrb_alloc(devfs_handle_t, int *, int *);
-int                     pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *);
-int                     pcibr_alloc_all_rrbs(devfs_handle_t, int, int, int, int, int, int, int, int, int);
-void                    pcibr_rrb_flush(devfs_handle_t);
-
-LOCAL int               pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t);
-void                    pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t);
-
-LOCAL void              pcibr_clearwidint(bridge_t *);
-LOCAL void              pcibr_setwidint(xtalk_intr_t);
-LOCAL int               pcibr_probe_slot(bridge_t *, cfg_p, unsigned *);
-
-void                    pcibr_init(void);
-int                     pcibr_attach(devfs_handle_t);
-int			pcibr_detach(devfs_handle_t);
-int                     pcibr_open(devfs_handle_t *, int, int, cred_t *);
-int                     pcibr_close(devfs_handle_t, int, int, cred_t *);
-int                     pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     pcibr_unmap(devfs_handle_t, vhandl_t *);
-int                     pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
-
-void                    pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t);
-
-LOCAL int               pcibr_init_ext_ate_ram(bridge_t *);
-LOCAL int               pcibr_ate_alloc(pcibr_soft_t, int);
-LOCAL void              pcibr_ate_free(pcibr_soft_t, int, int);
-
-LOCAL pcibr_info_t      pcibr_info_get(devfs_handle_t);
-LOCAL pcibr_info_t      pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-LOCAL void		pcibr_device_info_free(devfs_handle_t, pciio_slot_t);
-LOCAL iopaddr_t         pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-
-pcibr_piomap_t          pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
-void                    pcibr_piomap_free(pcibr_piomap_t);
-caddr_t                 pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t);
-void                    pcibr_piomap_done(pcibr_piomap_t);
-caddr_t                 pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-iopaddr_t               pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
-
-LOCAL iopaddr_t         pcibr_flags_to_d64(unsigned, pcibr_soft_t);
-LOCAL bridge_ate_t      pcibr_flags_to_ate(unsigned);
-
-pcibr_dmamap_t          pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    pcibr_dmamap_free(pcibr_dmamap_t);
-LOCAL bridge_ate_p      pcibr_ate_addr(pcibr_soft_t, int);
-LOCAL iopaddr_t         pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t);
-iopaddr_t               pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t);
-alenlist_t              pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned);
-void                    pcibr_dmamap_done(pcibr_dmamap_t);
-cnodeid_t		pcibr_get_dmatrans_node(devfs_handle_t);
-iopaddr_t               pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void                    pcibr_dmamap_drain(pcibr_dmamap_t);
-void                    pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void                    pcibr_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pcibr_dmamap_pciaddr_get(pcibr_dmamap_t);
-
-static unsigned		pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines);
-pcibr_intr_t            pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
-void                    pcibr_intr_free(pcibr_intr_t);
-LOCAL void              pcibr_setpciint(xtalk_intr_t);
-int                     pcibr_intr_connect(pcibr_intr_t);
-void                    pcibr_intr_disconnect(pcibr_intr_t);
-
-devfs_handle_t            pcibr_intr_cpu_get(pcibr_intr_t);
-void                    pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
-void                    pcibr_intr_func(intr_arg_t);
-
-void                    pcibr_provider_startup(devfs_handle_t);
-void                    pcibr_provider_shutdown(devfs_handle_t);
-
-int                     pcibr_reset(devfs_handle_t);
-pciio_endian_t          pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-int                     pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t);
-pciio_priority_t        pcibr_priority_set(devfs_handle_t, pciio_priority_t);
-int                     pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t);
-
-LOCAL cfg_p             pcibr_config_addr(devfs_handle_t, unsigned);
-uint64_t                pcibr_config_get(devfs_handle_t, unsigned, unsigned);
-LOCAL uint64_t          do_pcibr_config_get(cfg_p, unsigned, unsigned);
-void                    pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
-LOCAL void              do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
-
-LOCAL pcibr_hints_t     pcibr_hints_get(devfs_handle_t, int);
-void                    pcibr_hints_fix_rrbs(devfs_handle_t);
-void                    pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-void			pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
-void                    pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
-void                    pcibr_hints_handsoff(devfs_handle_t);
-void                    pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, ulong);
-
-LOCAL int		pcibr_slot_info_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_info_free(devfs_handle_t,pciio_slot_t);
-
-#ifdef LATER
-LOCAL int	        pcibr_slot_info_return(pcibr_soft_t, pciio_slot_t,
-                                               pcibr_slot_info_resp_t);
-LOCAL void       	pcibr_slot_func_info_return(pcibr_info_h, int,
-                                                    pcibr_slot_func_info_resp_t);
-#endif	/* LATER */
-
-LOCAL int		pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_device_init(devfs_handle_t, pciio_slot_t);
-LOCAL int		pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_call_device_attach(devfs_handle_t,
-						      pciio_slot_t, int);
-LOCAL int		pcibr_slot_call_device_detach(devfs_handle_t,
-						      pciio_slot_t, int);
-
-LOCAL int               pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int);
-LOCAL int 		pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t);
-#ifdef LATER
-LOCAL int		pcibr_slot_query(devfs_handle_t, pcibr_slot_info_req_t);
-#endif
-
-/* =====================================================================
- *    RRB management
- */
-
-#define LSBIT(word)		((word) &~ ((word)-1))
-
-#define PCIBR_RRB_SLOT_VIRTUAL	8
-
-LOCAL void
-do_pcibr_rrb_clear(bridge_t *bridge, int rrb)
-{
-    bridgereg_t             status;
-
-    /* bridge_lock must be held;
-     * this RRB must be disabled.
-     */
-
-    /* wait until RRB has no outstanduing XIO packets. */
-    while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
-	;				/* XXX- beats on bridge. bad idea? */
-    }
-
-    /* if the RRB has data, drain it. */
-    if (status & BRIDGE_RRB_VALID(rrb)) {
-	bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
-
-	/* wait until RRB is no longer valid. */
-	while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
-	    ;				/* XXX- beats on bridge. bad idea? */
-	}
-    }
-}
-
-LOCAL void
-do_pcibr_rrb_flush(bridge_t *bridge, int rrbn)
-{
-    reg_p                   rrbp = &bridge->b_rrb_map[rrbn & 1].reg;
-    bridgereg_t             rrbv;
-    int                     shft = 4 * (rrbn >> 1);
-    unsigned                ebit = BRIDGE_RRB_EN << shft;
-
-    rrbv = *rrbp;
-    if (rrbv & ebit)
-	*rrbp = rrbv & ~ebit;
-
-    do_pcibr_rrb_clear(bridge, rrbn);
-
-    if (rrbv & ebit)
-	*rrbp = rrbv;
-}
-
-/*
- *    pcibr_rrb_count_valid: count how many RRBs are
- *      marked valid for the specified PCI slot on this
- *      bridge.
- *
- *      NOTE: The "slot" parameter for all pcibr_rrb
- *      management routines must include the "virtual"
- *      bit; when manageing both the normal and the
- *      virtual channel, separate calls to these
- *      routines must be made. To denote the virtual
- *      channel, add PCIBR_RRB_SLOT_VIRTUAL to the slot
- *      number.
- *
- *      IMPL NOTE: The obvious algorithm is to iterate
- *      through the RRB fields, incrementing a count if
- *      the RRB is valid and matches the slot. However,
- *      it is much simpler to use an algorithm derived
- *      from the "partitioned add" idea. First, XOR in a
- *      pattern such that the fields that match this
- *      slot come up "all ones" and all other fields
- *      have zeros in the mismatching bits. Then AND
- *      together the bits in the field, so we end up
- *      with one bit turned on for each field that
- *      matched. Now we need to count these bits. This
- *      can be done either with a series of shift/add
- *      instructions or by using "tmp % 15"; I expect
- *      that the cascaded shift/add will be faster.
- */
-
-LOCAL int
-do_pcibr_rrb_count_valid(bridge_t *bridge,
-			 pciio_slot_t slot)
-{
-    bridgereg_t             tmp;
-
-    tmp = bridge->b_rrb_map[slot & 1].reg;
-    tmp ^= 0x11111111 * (7 - slot / 2);
-    tmp &= (0xCCCCCCCC & tmp) >> 2;
-    tmp &= (0x22222222 & tmp) >> 1;
-    tmp += tmp >> 4;
-    tmp += tmp >> 8;
-    tmp += tmp >> 16;
-    return tmp & 15;
-}
-
-/*
- *    do_pcibr_rrb_count_avail: count how many RRBs are
- *      available to be allocated for the specified slot.
- *
- *      IMPL NOTE: similar to the above, except we are
- *      just counting how many fields have the valid bit
- *      turned off.
- */
-LOCAL int
-do_pcibr_rrb_count_avail(bridge_t *bridge,
-			 pciio_slot_t slot)
-{
-    bridgereg_t             tmp;
-
-    tmp = bridge->b_rrb_map[slot & 1].reg;
-    tmp = (0x88888888 & ~tmp) >> 3;
-    tmp += tmp >> 4;
-    tmp += tmp >> 8;
-    tmp += tmp >> 16;
-    return tmp & 15;
-}
-
-/*
- *    do_pcibr_rrb_alloc: allocate some additional RRBs
- *      for the specified slot. Returns -1 if there were
- *      insufficient free RRBs to satisfy the request,
- *      or 0 if the request was fulfilled.
- *
- *      Note that if a request can be partially filled,
- *      it will be, even if we return failure.
- *
- *      IMPL NOTE: again we avoid iterating across all
- *      the RRBs; instead, we form up a word containing
- *      one bit for each free RRB, then peel the bits
- *      off from the low end.
- */
-LOCAL int
-do_pcibr_rrb_alloc(bridge_t *bridge,
-		   pciio_slot_t slot,
-		   int more)
-{
-    int                     rv = 0;
-    bridgereg_t             reg, tmp, bit;
-
-    reg = bridge->b_rrb_map[slot & 1].reg;
-    tmp = (0x88888888 & ~reg) >> 3;
-    while (more-- > 0) {
-	bit = LSBIT(tmp);
-	if (!bit) {
-	    rv = -1;
-	    break;
-	}
-	tmp &= ~bit;
-	reg = ((reg & ~(bit * 15)) | (bit * (8 + slot / 2)));
-    }
-    bridge->b_rrb_map[slot & 1].reg = reg;
-    return rv;
-}
-
-/*
- *    do_pcibr_rrb_free: release some of the RRBs that
- *      have been allocated for the specified
- *      slot. Returns zero for success, or negative if
- *      it was unable to free that many RRBs.
- *
- *      IMPL NOTE: We form up a bit for each RRB
- *      allocated to the slot, aligned with the VALID
- *      bitfield this time; then we peel bits off one at
- *      a time, releasing the corresponding RRB.
- */
-LOCAL int
-do_pcibr_rrb_free(bridge_t *bridge,
-		  pciio_slot_t slot,
-		  int less)
-{
-    int                     rv = 0;
-    bridgereg_t             reg, tmp, clr, bit;
-    int                     i;
-
-    clr = 0;
-    reg = bridge->b_rrb_map[slot & 1].reg;
-
-    /* This needs to be done otherwise the rrb's on the virtual channel
-     * for this slot won't be freed !!
-     */
-    tmp = reg & 0xbbbbbbbb;
-
-    tmp ^= (0x11111111 * (7 - slot / 2));
-    tmp &= (0x33333333 & tmp) << 2;
-    tmp &= (0x44444444 & tmp) << 1;
-    while (less-- > 0) {
-	bit = LSBIT(tmp);
-	if (!bit) {
-	    rv = -1;
-	    break;
-	}
-	tmp &= ~bit;
-	reg &= ~bit;
-	clr |= bit;
-    }
-    bridge->b_rrb_map[slot & 1].reg = reg;
-
-    for (i = 0; i < 8; i++)
-	if (clr & (8 << (4 * i)))
-	    do_pcibr_rrb_clear(bridge, (2 * i) + (slot & 1));
-
-    return rv;
-}
-
-LOCAL void
-do_pcibr_rrb_autoalloc(pcibr_soft_t pcibr_soft,
-		       int slot,
-		       int more_rrbs)
-{
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     got;
-
-    for (got = 0; got < more_rrbs; ++got) {
-	if (pcibr_soft->bs_rrb_res[slot & 7] > 0)
-	    pcibr_soft->bs_rrb_res[slot & 7]--;
-	else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0)
-	    pcibr_soft->bs_rrb_avail[slot & 1]--;
-	else
-	    break;
-	if (do_pcibr_rrb_alloc(bridge, slot, 1) < 0)
-	    break;
-#if PCIBR_RRB_DEBUG
-	printk( "do_pcibr_rrb_autoalloc: add one to slot %d%s\n",
-		slot & 7, slot & 8 ? "v" : "");
-#endif
-	pcibr_soft->bs_rrb_valid[slot]++;
-    }
-#if PCIBR_RRB_DEBUG
-    printk("%s: %d+%d free RRBs. Allocation list:\n", pcibr_soft->bs_name,
-	    pcibr_soft->bs_rrb_avail[0],
-	    pcibr_soft->bs_rrb_avail[1]);
-    for (slot = 0; slot < 8; ++slot)
-	printk("\t%d+%d+%d",
-		0xFFF & pcibr_soft->bs_rrb_valid[slot],
-		0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-		pcibr_soft->bs_rrb_res[slot]);
-	printk("\n");
-#endif
-}
-
-/*
- * Device driver interface to flush the write buffers for a specified
- * device hanging off the bridge.
- */
-int
-pcibr_wrb_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    volatile bridgereg_t   *wrb_flush;
-
-    wrb_flush = &(bridge->b_wr_req_buf[pciio_slot].reg);
-    while (*wrb_flush);
-
-    return(0);
-}
-/*
- * Device driver interface to request RRBs for a specified device
- * hanging off a Bridge.  The driver requests the total number of
- * RRBs it would like for the normal channel (vchan0) and for the
- * "virtual channel" (vchan1).  The actual number allocated to each
- * channel is returned.
- *
- * If we cannot allocate at least one RRB to a channel that needs
- * at least one, return -1 (failure).  Otherwise, satisfy the request
- * as best we can and return 0.
- */
-int
-pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
-		int *count_vchan0,
-		int *count_vchan1)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     desired_vchan0;
-    int                     desired_vchan1;
-    int                     orig_vchan0;
-    int                     orig_vchan1;
-    int                     delta_vchan0;
-    int                     delta_vchan1;
-    int                     final_vchan0;
-    int                     final_vchan1;
-    int                     avail_rrbs;
-    unsigned long           s;
-    int                     error;
-
-    /*
-     * TBD: temper request with admin info about RRB allocation,
-     * and according to demand from other devices on this Bridge.
-     *
-     * One way of doing this would be to allocate two RRBs
-     * for each device on the bus, before any drivers start
-     * asking for extras. This has the weakness that one
-     * driver might not give back an "extra" RRB until after
-     * another driver has already failed to get one that
-     * it wanted.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-
-    /* How many RRBs do we own? */
-    orig_vchan0 = pcibr_soft->bs_rrb_valid[pciio_slot];
-    orig_vchan1 = pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
-
-    /* How many RRBs do we want? */
-    desired_vchan0 = count_vchan0 ? *count_vchan0 : orig_vchan0;
-    desired_vchan1 = count_vchan1 ? *count_vchan1 : orig_vchan1;
-
-    /* How many RRBs are free? */
-    avail_rrbs = pcibr_soft->bs_rrb_avail[pciio_slot & 1]
-	+ pcibr_soft->bs_rrb_res[pciio_slot];
-
-    /* Figure desired deltas */
-    delta_vchan0 = desired_vchan0 - orig_vchan0;
-    delta_vchan1 = desired_vchan1 - orig_vchan1;
-
-    /* Trim back deltas to something
-     * that we can actually meet, by
-     * decreasing the ending allocation
-     * for whichever channel wants
-     * more RRBs. If both want the same
-     * number, cut the second channel.
-     * NOTE: do not change the allocation for
-     * a channel that was passed as NULL.
-     */
-    while ((delta_vchan0 + delta_vchan1) > avail_rrbs) {
-	if (count_vchan0 &&
-	    (!count_vchan1 ||
-	     ((orig_vchan0 + delta_vchan0) >
-	      (orig_vchan1 + delta_vchan1))))
-	    delta_vchan0--;
-	else
-	    delta_vchan1--;
-    }
-
-    /* Figure final RRB allocations
-     */
-    final_vchan0 = orig_vchan0 + delta_vchan0;
-    final_vchan1 = orig_vchan1 + delta_vchan1;
-
-    /* If either channel wants RRBs but our actions
-     * would leave it with none, declare an error,
-     * but DO NOT change any RRB allocations.
-     */
-    if ((desired_vchan0 && !final_vchan0) ||
-	(desired_vchan1 && !final_vchan1)) {
-
-	error = -1;
-
-    } else {
-
-	/* Commit the allocations: free, then alloc.
-	 */
-	if (delta_vchan0 < 0)
-	    (void) do_pcibr_rrb_free(bridge, pciio_slot, -delta_vchan0);
-	if (delta_vchan1 < 0)
-	    (void) do_pcibr_rrb_free(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, -delta_vchan1);
-
-	if (delta_vchan0 > 0)
-	    (void) do_pcibr_rrb_alloc(bridge, pciio_slot, delta_vchan0);
-	if (delta_vchan1 > 0)
-	    (void) do_pcibr_rrb_alloc(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, delta_vchan1);
-
-	/* Return final values to caller.
-	 */
-	if (count_vchan0)
-	    *count_vchan0 = final_vchan0;
-	if (count_vchan1)
-	    *count_vchan1 = final_vchan1;
-
-	/* prevent automatic changes to this slot's RRBs
-	 */
-	pcibr_soft->bs_rrb_fixed |= 1 << pciio_slot;
-
-	/* Track the actual allocations, release
-	 * any further reservations, and update the
-	 * number of available RRBs.
-	 */
-
-	pcibr_soft->bs_rrb_valid[pciio_slot] = final_vchan0;
-	pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL] = final_vchan1;
-	pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
-	    pcibr_soft->bs_rrb_avail[pciio_slot & 1]
-	    + pcibr_soft->bs_rrb_res[pciio_slot]
-	    - delta_vchan0
-	    - delta_vchan1;
-	pcibr_soft->bs_rrb_res[pciio_slot] = 0;
-
-#if PCIBR_RRB_DEBUG
-	printk("pcibr_rrb_alloc: slot %d set to %d+%d; %d+%d free\n",
-		pciio_slot, final_vchan0, final_vchan1,
-		pcibr_soft->bs_rrb_avail[0],
-		pcibr_soft->bs_rrb_avail[1]);
-	for (pciio_slot = 0; pciio_slot < 8; ++pciio_slot)
-	    printk("\t%d+%d+%d",
-		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot],
-		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL],
-		    pcibr_soft->bs_rrb_res[pciio_slot]);
-	printk("\n");
-#endif
-
-	error = 0;
-    }
-
-    pcibr_unlock(pcibr_soft, s);
-    return error;
-}
-
-/*
- * Device driver interface to check the current state
- * of the RRB allocations.
- *
- *   pconn_vhdl is your PCI connection point (specifies which
- *      PCI bus and which slot).
- *
- *   count_vchan0 points to where to return the number of RRBs
- *      assigned to the primary DMA channel, used by all DMA
- *      that does not explicitly ask for the alternate virtual
- *      channel.
- *
- *   count_vchan1 points to where to return the number of RRBs
- *      assigned to the secondary DMA channel, used when
- *      PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified.
- *
- *   count_reserved points to where to return the number of RRBs
- *      that have been automatically reserved for your device at
- *      startup, but which have not been assigned to a
- *      channel. RRBs must be assigned to a channel to be used;
- *      this can be done either with an explicit pcibr_rrb_alloc
- *      call, or automatically by the infrastructure when a DMA
- *      translation is constructed. Any call to pcibr_rrb_alloc
- *      will release any unassigned reserved RRBs back to the
- *      free pool.
- *
- *   count_pool points to where to return the number of RRBs
- *      that are currently unassigned and unreserved. This
- *      number can (and will) change as other drivers make calls
- *      to pcibr_rrb_alloc, or automatically allocate RRBs for
- *      DMA beyond their initial reservation.
- *
- * NULL may be passed for any of the return value pointers
- * the caller is not interested in.
- *
- * The return value is "0" if all went well, or "-1" if
- * there is a problem. Additionally, if the wrong vertex
- * is passed in, one of the subsidiary support functions
- * could panic with a "bad pciio fingerprint."
- */
-
-int
-pcibr_rrb_check(devfs_handle_t pconn_vhdl,
-		int *count_vchan0,
-		int *count_vchan1,
-		int *count_reserved,
-		int *count_pool)
-{
-    pciio_info_t            pciio_info;
-    pciio_slot_t            pciio_slot;
-    pcibr_soft_t            pcibr_soft;
-    unsigned long           s;
-    int                     error = -1;
-
-    if ((pciio_info = pciio_info_get(pconn_vhdl)) &&
-	(pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) &&
-	((pciio_slot = pciio_info_slot_get(pciio_info)) < 8)) {
-
-	s = pcibr_lock(pcibr_soft);
-
-	if (count_vchan0)
-	    *count_vchan0 =
-		pcibr_soft->bs_rrb_valid[pciio_slot];
-
-	if (count_vchan1)
-	    *count_vchan1 =
-		pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
-
-	if (count_reserved)
-	    *count_reserved =
-		pcibr_soft->bs_rrb_res[pciio_slot];
-
-	if (count_pool)
-	    *count_pool =
-		pcibr_soft->bs_rrb_avail[pciio_slot & 1];
-
-	error = 0;
-
-	pcibr_unlock(pcibr_soft, s);
-    }
-    return error;
-}
-
-/* pcibr_alloc_all_rrbs allocates all the rrbs available in the quantities
- * requested for each of the devies.  The evn_odd argument indicates whether
- * allcoation for the odd or even rrbs is requested and next group of four pairse
- * are the amount to assign to each device (they should sum to <= 8) and
- * whether to set the viritual bit for that device (1 indictaes yes, 0 indicates no)
- * the devices in order are either 0, 2, 4, 6 or 1, 3, 5, 7
- * if even_odd is even we alloc even rrbs else we allocate odd rrbs
- * returns 0 if no errors else returns -1
- */
-
-int
-pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd,
-		     int dev_1_rrbs, int virt1, int dev_2_rrbs, int virt2,
-		     int dev_3_rrbs, int virt3, int dev_4_rrbs, int virt4)
-{
-    devfs_handle_t            pcibr_vhdl;
-    pcibr_soft_t            pcibr_soft = NULL;
-    bridge_t               *bridge = NULL;
-
-    uint32_t              rrb_setting = 0;
-    int                     rrb_shift = 7;
-    uint32_t              cur_rrb;
-    int                     dev_rrbs[4];
-    int                     virt[4];
-    int                     i, j;
-    unsigned long           s;
-
-    if (GRAPH_SUCCESS ==
-	hwgraph_traverse(vhdl, EDGE_LBL_PCI, &pcibr_vhdl)) {
-	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-	if (pcibr_soft)
-	    bridge = pcibr_soft->bs_base;
-	hwgraph_vertex_unref(pcibr_vhdl);
-    }
-    if (bridge == NULL)
-	bridge = (bridge_t *) xtalk_piotrans_addr
-	    (vhdl, NULL, 0, sizeof(bridge_t), 0);
-
-    even_odd &= 1;
-
-    dev_rrbs[0] = dev_1_rrbs;
-    dev_rrbs[1] = dev_2_rrbs;
-    dev_rrbs[2] = dev_3_rrbs;
-    dev_rrbs[3] = dev_4_rrbs;
-
-    virt[0] = virt1;
-    virt[1] = virt2;
-    virt[2] = virt3;
-    virt[3] = virt4;
-
-    if ((dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs) > 8) {
-	return -1;
-    }
-    if ((dev_1_rrbs < 0) || (dev_2_rrbs < 0) || (dev_3_rrbs < 0) || (dev_4_rrbs < 0)) {
-	return -1;
-    }
-    /* walk through rrbs */
-    for (i = 0; i < 4; i++) {
-	if (virt[i]) {
-	    cur_rrb = i | 0xc;
-	    cur_rrb = cur_rrb << (rrb_shift * 4);
-	    rrb_shift--;
-	    rrb_setting = rrb_setting | cur_rrb;
-	    dev_rrbs[i] = dev_rrbs[i] - 1;
-	}
-	for (j = 0; j < dev_rrbs[i]; j++) {
-	    cur_rrb = i | 0x8;
-	    cur_rrb = cur_rrb << (rrb_shift * 4);
-	    rrb_shift--;
-	    rrb_setting = rrb_setting | cur_rrb;
-	}
-    }
-
-    if (pcibr_soft)
-	s = pcibr_lock(pcibr_soft);
-
-    bridge->b_rrb_map[even_odd].reg = rrb_setting;
-
-    if (pcibr_soft) {
-
-	pcibr_soft->bs_rrb_fixed |= 0x55 << even_odd;
-
-	/* since we've "FIXED" the allocations
-	 * for these slots, we probably can dispense
-	 * with tracking avail/res/valid data, but
-	 * keeping it up to date helps debugging.
-	 */
-
-	pcibr_soft->bs_rrb_avail[even_odd] =
-	    8 - (dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs);
-
-	pcibr_soft->bs_rrb_res[even_odd + 0] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 2] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 4] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 6] = 0;
-
-	pcibr_soft->bs_rrb_valid[even_odd + 0] = dev_1_rrbs - virt1;
-	pcibr_soft->bs_rrb_valid[even_odd + 2] = dev_2_rrbs - virt2;
-	pcibr_soft->bs_rrb_valid[even_odd + 4] = dev_3_rrbs - virt3;
-	pcibr_soft->bs_rrb_valid[even_odd + 6] = dev_4_rrbs - virt4;
-
-	pcibr_soft->bs_rrb_valid[even_odd + 0 + PCIBR_RRB_SLOT_VIRTUAL] = virt1;
-	pcibr_soft->bs_rrb_valid[even_odd + 2 + PCIBR_RRB_SLOT_VIRTUAL] = virt2;
-	pcibr_soft->bs_rrb_valid[even_odd + 4 + PCIBR_RRB_SLOT_VIRTUAL] = virt3;
-	pcibr_soft->bs_rrb_valid[even_odd + 6 + PCIBR_RRB_SLOT_VIRTUAL] = virt4;
-
-	pcibr_unlock(pcibr_soft, s);
-    }
-    return 0;
-}
-
-/*
- *    pcibr_rrb_flush: chase down all the RRBs assigned
- *      to the specified connection point, and flush
- *      them.
- */
-void
-pcibr_rrb_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned long           s;
-    reg_p                   rrbp;
-    unsigned                rrbm;
-    int                     i;
-    int                     rrbn;
-    unsigned                sval;
-    unsigned                mask;
-
-    sval = BRIDGE_RRB_EN | (pciio_slot >> 1);
-    mask = BRIDGE_RRB_EN | BRIDGE_RRB_PDEV;
-    rrbn = pciio_slot & 1;
-    rrbp = &bridge->b_rrb_map[rrbn].reg;
-
-    s = pcibr_lock(pcibr_soft);
-    rrbm = *rrbp;
-    for (i = 0; i < 8; ++i) {
-	if ((rrbm & mask) == sval)
-	    do_pcibr_rrb_flush(bridge, rrbn);
-	rrbm >>= 4;
-	rrbn += 2;
-    }
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/* =====================================================================
- *    Device(x) register management
- */
-
-/* pcibr_try_set_device: attempt to modify Device(x)
- * for the specified slot on the specified bridge
- * as requested in flags, limited to the specified
- * bits. Returns which BRIDGE bits were in conflict,
- * or ZERO if everything went OK.
- *
- * Caller MUST hold pcibr_lock when calling this function.
- */
-LOCAL int
-pcibr_try_set_device(pcibr_soft_t pcibr_soft,
-		     pciio_slot_t slot,
-		     unsigned flags,
-		     bridgereg_t mask)
-{
-    bridge_t               *bridge;
-    pcibr_soft_slot_t       slotp;
-    bridgereg_t             old;
-    bridgereg_t             new;
-    bridgereg_t             chg;
-    bridgereg_t             bad;
-    bridgereg_t             badpmu;
-    bridgereg_t             badd32;
-    bridgereg_t             badd64;
-    bridgereg_t             fix;
-    unsigned long           s;
-    bridgereg_t             xmask;
-
-    xmask = mask;
-    if (pcibr_soft->bs_xbridge) {
-    	if (mask == BRIDGE_DEV_PMU_BITS)
-		xmask = XBRIDGE_DEV_PMU_BITS;
-	if (mask == BRIDGE_DEV_D64_BITS)
-		xmask = XBRIDGE_DEV_D64_BITS;
-    }
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    s = pcibr_lock(pcibr_soft);
-
-    bridge = pcibr_soft->bs_base;
-
-    old = slotp->bss_device;
-
-    /* figure out what the desired
-     * Device(x) bits are based on
-     * the flags specified.
-     */
-
-    new = old;
-
-    /* Currently, we inherit anything that
-     * the new caller has not specified in
-     * one way or another, unless we take
-     * action here to not inherit.
-     *
-     * This is needed for the "swap" stuff,
-     * since it could have been set via
-     * pcibr_endian_set -- altho note that
-     * any explicit PCIBR_BYTE_STREAM or
-     * PCIBR_WORD_VALUES will freely override
-     * the effect of that call (and vice
-     * versa, no protection either way).
-     *
-     * I want to get rid of pcibr_endian_set
-     * in favor of tracking DMA endianness
-     * using the flags specified when DMA
-     * channels are created.
-     */
-
-#define	BRIDGE_DEV_WRGA_BITS	(BRIDGE_DEV_PMU_WRGA_EN | BRIDGE_DEV_DIR_WRGA_EN)
-#define	BRIDGE_DEV_SWAP_BITS	(BRIDGE_DEV_SWAP_PMU | BRIDGE_DEV_SWAP_DIR)
-
-    /* Do not use Barrier, Write Gather,
-     * or Prefetch unless asked.
-     * Leave everything else as it
-     * was from the last time.
-     */
-    new = new
-	& ~BRIDGE_DEV_BARRIER
-	& ~BRIDGE_DEV_WRGA_BITS
-	& ~BRIDGE_DEV_PREF
-	;
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {
-	new = (new
-            & ~BRIDGE_DEV_BARRIER)      /* barrier off */
-            | BRIDGE_DEV_PREF;          /* prefetch on */
-
-    }
-    if (flags & PCIIO_DMA_CMD) {
-        new = ((new
-            & ~BRIDGE_DEV_PREF)         /* prefetch off */
-            & ~BRIDGE_DEV_WRGA_BITS)    /* write gather off */
-            | BRIDGE_DEV_BARRIER;       /* barrier on */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_WRITE_GATHER)
-	new |= BRIDGE_DEV_WRGA_BITS;
-    if (flags & PCIIO_NOWRITE_GATHER)
-	new &= ~BRIDGE_DEV_WRGA_BITS;
-
-    if (flags & PCIIO_PREFETCH)
-	new |= BRIDGE_DEV_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	new &= ~BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_WRITE_GATHER)
-	new |= BRIDGE_DEV_WRGA_BITS;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	new &= ~BRIDGE_DEV_WRGA_BITS;
-
-    if (flags & PCIIO_BYTE_STREAM)
-	new |= (pcibr_soft->bs_xbridge) ? 
-			BRIDGE_DEV_SWAP_DIR : BRIDGE_DEV_SWAP_BITS;
-    if (flags & PCIIO_WORD_VALUES)
-	new &= (pcibr_soft->bs_xbridge) ? 
-			~BRIDGE_DEV_SWAP_DIR : ~BRIDGE_DEV_SWAP_BITS;
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_PREFETCH)
-	new |= BRIDGE_DEV_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	new &= ~BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	new |= BRIDGE_DEV_PRECISE;
-    if (flags & PCIBR_NOPRECISE)
-	new &= ~BRIDGE_DEV_PRECISE;
-
-    if (flags & PCIBR_BARRIER)
-	new |= BRIDGE_DEV_BARRIER;
-    if (flags & PCIBR_NOBARRIER)
-	new &= ~BRIDGE_DEV_BARRIER;
-
-    if (flags & PCIBR_64BIT)
-	new |= BRIDGE_DEV_DEV_SIZE;
-    if (flags & PCIBR_NO64BIT)
-	new &= ~BRIDGE_DEV_DEV_SIZE;
-
-    chg = old ^ new;				/* what are we changing, */
-    chg &= xmask;				/* of the interesting bits */
-
-    if (chg) {
-
-	badd32 = slotp->bss_d32_uctr ? (BRIDGE_DEV_D32_BITS & chg) : 0;
-	if (pcibr_soft->bs_xbridge) {
-		badpmu = slotp->bss_pmu_uctr ? (XBRIDGE_DEV_PMU_BITS & chg) : 0;
-		badd64 = slotp->bss_d64_uctr ? (XBRIDGE_DEV_D64_BITS & chg) : 0;
-	} else {
-		badpmu = slotp->bss_pmu_uctr ? (BRIDGE_DEV_PMU_BITS & chg) : 0;
-		badd64 = slotp->bss_d64_uctr ? (BRIDGE_DEV_D64_BITS & chg) : 0;
-	}
-	bad = badpmu | badd32 | badd64;
-
-	if (bad) {
-
-	    /* some conflicts can be resolved by
-	     * forcing the bit on. this may cause
-	     * some performance degredation in
-	     * the stream(s) that want the bit off,
-	     * but the alternative is not allowing
-	     * the new stream at all.
-	     */
-            if ( (fix = bad & (BRIDGE_DEV_PRECISE |
-                             BRIDGE_DEV_BARRIER)) ){
-		bad &= ~fix;
-		/* don't change these bits if
-		 * they are already set in "old"
-		 */
-		chg &= ~(fix & old);
-	    }
-	    /* some conflicts can be resolved by
-	     * forcing the bit off. this may cause
-	     * some performance degredation in
-	     * the stream(s) that want the bit on,
-	     * but the alternative is not allowing
-	     * the new stream at all.
-	     */
-	    if ( (fix = bad & (BRIDGE_DEV_WRGA_BITS |
-			     BRIDGE_DEV_PREF)) ) {
-		bad &= ~fix;
-		/* don't change these bits if
-		 * we wanted to turn them on.
-		 */
-		chg &= ~(fix & new);
-	    }
-	    /* conflicts in other bits mean
-	     * we can not establish this DMA
-	     * channel while the other(s) are
-	     * still present.
-	     */
-	    if (bad) {
-		pcibr_unlock(pcibr_soft, s);
-#if (DEBUG && PCIBR_DEV_DEBUG)
-		printk("pcibr_try_set_device: mod blocked by %R\n", bad, device_bits);
-#endif
-		return bad;
-	    }
-	}
-    }
-    if (mask == BRIDGE_DEV_PMU_BITS)
-	slotp->bss_pmu_uctr++;
-    if (mask == BRIDGE_DEV_D32_BITS)
-	slotp->bss_d32_uctr++;
-    if (mask == BRIDGE_DEV_D64_BITS)
-	slotp->bss_d64_uctr++;
-
-    /* the value we want to write is the
-     * original value, with the bits for
-     * our selected changes flipped, and
-     * with any disabled features turned off.
-     */
-    new = old ^ chg;			/* only change what we want to change */
-
-    if (slotp->bss_device == new) {
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-    bridge->b_device[slot].reg = new;
-    slotp->bss_device = new;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-#if DEBUG && PCIBR_DEV_DEBUG
-    printk("pcibr Device(%d): 0x%p\n", slot, bridge->b_device[slot].reg);
-#endif
-
-    return 0;
-}
-
-void
-pcibr_release_device(pcibr_soft_t pcibr_soft,
-		     pciio_slot_t slot,
-		     bridgereg_t mask)
-{
-    pcibr_soft_slot_t       slotp;
-    unsigned long           s;
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    s = pcibr_lock(pcibr_soft);
-
-    if (mask == BRIDGE_DEV_PMU_BITS)
-	slotp->bss_pmu_uctr--;
-    if (mask == BRIDGE_DEV_D32_BITS)
-	slotp->bss_d32_uctr--;
-    if (mask == BRIDGE_DEV_D64_BITS)
-	slotp->bss_d64_uctr--;
-
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/*
- * flush write gather buffer for slot
- */
-LOCAL void
-pcibr_device_write_gather_flush(pcibr_soft_t pcibr_soft,
-              pciio_slot_t slot)
-{
-    bridge_t               *bridge;
-    unsigned long          s;
-    volatile uint32_t     wrf;
-    s = pcibr_lock(pcibr_soft);
-    bridge = pcibr_soft->bs_base;
-    wrf = bridge->b_wr_req_buf[slot].reg;
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/* =====================================================================
- *    Bridge (pcibr) "Device Driver" entry points
- */
-
-/*
- * pcibr_probe_slot: read a config space word
- * while trapping any errors; reutrn zero if
- * all went OK, or nonzero if there was an error.
- * The value read, if any, is passed back
- * through the valp parameter.
- */
-LOCAL int
-pcibr_probe_slot(bridge_t *bridge,
-		 cfg_p cfg,
-		 unsigned *valp)
-{
-    int                     rv;
-    bridgereg_t             old_enable, new_enable;
-    int badaddr_val(volatile void *, int, volatile void *);
-
-
-    old_enable = bridge->b_int_enable;
-    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-
-    bridge->b_int_enable = new_enable;
-
-	/*
-	 * The xbridge doesn't clear b_err_int_view unless
-	 * multi-err is cleared...
-	 */
-	if (is_xbridge(bridge))
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-	    }
-
-    if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {
-	bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;
-	(void) bridge->b_wid_tflush;	/* flushbus */
-    }
-    rv = badaddr_val((void *) cfg, 4, valp);
-
-	/*
-	 * The xbridge doesn't set master timeout in b_int_status
-	 * here.  Fortunately it's in error_interrupt_view.
-	 */
-	if (is_xbridge(bridge))
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-		rv = 1;		/* unoccupied slot */
-	    }
-
-    bridge->b_int_enable = old_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    return rv;
-}
-
-/*
- *    pcibr_init: called once during system startup or
- *      when a loadable driver is loaded.
- *
- *      The driver_register function should normally
- *      be in _reg, not _init.  But the pcibr driver is
- *      required by devinit before the _reg routines
- *      are called, so this is an exception.
- */
-void
-pcibr_init(void)
-{
-#if DEBUG && ATTACH_DEBUG
-    printk("pcibr_init\n");
-#endif
-
-    xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM,
-			    XBRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
-    xwidget_driver_register(BRIDGE_WIDGET_PART_NUM,
-			    BRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
-}
-
-/*
- * open/close mmap/munmap interface would be used by processes
- * that plan to map the PCI bridge, and muck around with the
- * registers. This is dangerous to do, and will be allowed
- * to a select brand of programs. Typically these are
- * diagnostics programs, or some user level commands we may
- * write to do some weird things.
- * To start with expect them to have root priveleges.
- * We will ask for more later.
- */
-/* ARGSUSED */
-int
-pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    int                     error;
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get(vhdl);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    ASSERT(pcibr_soft);
-    len = ctob(btoc(len));		/* Make len page aligned */
-    error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len);
-
-    /*
-     * If the offset being mapped corresponds to the flash prom
-     * base, and if the mapping succeeds, and if the user
-     * has requested the protections to be WRITE, enable the
-     * flash prom to be written.
-     *
-     * XXX- deprecate this in favor of using the
-     * real flash driver ...
-     */
-    if (!error &&
-	((off == BRIDGE_EXTERNAL_FLASH) ||
-	 (len > BRIDGE_EXTERNAL_FLASH))) {
-	int                     s;
-
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	s = splhi();
-	bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN;
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(s);
-    }
-    return error;
-}
-
-/*ARGSUSED */
-int
-pcibr_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    /*
-     * If flashprom write was enabled, disable it, as
-     * this is the last unmap.
-     */
-    if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) {
-	int                     s;
-
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	s = splhi();
-	bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(s);
-    }
-    return 0;
-}
-
-/* This is special case code used by grio. There are plans to make
- * this a bit more general in the future, but till then this should
- * be sufficient.
- */
-pciio_slot_t
-pcibr_device_slot_get(devfs_handle_t dev_vhdl)
-{
-    char                    devname[MAXDEVNAME];
-    devfs_handle_t            tdev;
-    pciio_info_t            pciio_info;
-    pciio_slot_t            slot = PCIIO_SLOT_NONE;
-
-    vertex_to_name(dev_vhdl, devname, MAXDEVNAME);
-
-    /* run back along the canonical path
-     * until we find a PCI connection point.
-     */
-    tdev = hwgraph_connectpt_get(dev_vhdl);
-    while (tdev != GRAPH_VERTEX_NONE) {
-	pciio_info = pciio_info_chk(tdev);
-	if (pciio_info) {
-	    slot = pciio_info_slot_get(pciio_info);
-	    break;
-	}
-	hwgraph_vertex_unref(tdev);
-	tdev = hwgraph_connectpt_get(tdev);
-    }
-    hwgraph_vertex_unref(tdev);
-
-    return slot;
-}
-
-/*==========================================================================
- *	BRIDGE PCI SLOT RELATED IOCTLs
- */
-char *pci_space_name[] = {"NONE", 
-			  "ROM",
-			  "IO",
-			  "",
-			  "MEM",
-			  "MEM32",
-			  "MEM64",
-			  "CFG",
-			  "WIN0",
-			  "WIN1",
-			  "WIN2",
-			  "WIN3",
-			  "WIN4",
-			  "WIN5",
-			  "",
-			  "BAD"};
-
-
-/*ARGSUSED */
-int
-pcibr_ioctl(devfs_handle_t dev,
-	    int cmd,
-	    void *arg,
-	    int flag,
-	    struct cred *cr,
-	    int *rvalp)
-{
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t)dev);
-#ifdef LATER
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-#endif
-    int                     error = 0;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    switch (cmd) {
-#ifdef LATER
-    case GIOCSETBW:
-	{
-	    grio_ioctl_info_t       info;
-	    pciio_slot_t            slot = 0;
-
-	    if (!cap_able((uint64_t)CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
-		    info.prev_vhdl, info.reqbw);
-#endif				/* GRIO_DEBUG */
-
-	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
-		PCIIO_SLOT_NONE) {
-		error = EIO;
-		break;
-	    }
-	    if (info.reqbw)
-		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_HIGH);
-	    break;
-	}
-
-    case GIOCRELEASEBW:
-	{
-	    grio_ioctl_info_t       info;
-	    pciio_slot_t            slot = 0;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
-		    info.prev_vhdl, info.reqbw);
-#endif				/* GRIO_DEBUG */
-
-	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
-		PCIIO_SLOT_NONE) {
-		error = EIO;
-		break;
-	    }
-	    if (info.reqbw)
-		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_LOW);
-	    break;
-	}
-
-    case PCIBR_SLOT_POWERUP:
-	{
-	    pciio_slot_t	slot;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-	    slot = (pciio_slot_t)(uint64_t)arg;
-	    error = pcibr_slot_powerup(pcibr_vhdl,slot);
-	    break;
-	}
-    case PCIBR_SLOT_SHUTDOWN:
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-	    slot = (pciio_slot_t)(uint64_t)arg;
-	    error = pcibr_slot_powerup(pcibr_vhdl,slot);
-	    break;
-	}
-    case PCIBR_SLOT_QUERY:
-	{
-	    struct pcibr_slot_info_req_s        req;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-            if (COPYIN(arg, &req, sizeof(req))) {
-                error = EFAULT;
-                break;
-            }
-
-            error = pcibr_slot_query(pcibr_vhdl, &req);
-	    break;
-	}
-#endif	/* LATER */
-    default:
-	break;
-
-    }
-
-    return error;
-}
-
-void
-pcibr_freeblock_sub(iopaddr_t *free_basep,
-		    iopaddr_t *free_lastp,
-		    iopaddr_t base,
-		    size_t size)
-{
-    iopaddr_t               free_base = *free_basep;
-    iopaddr_t               free_last = *free_lastp;
-    iopaddr_t               last = base + size - 1;
-
-    if ((last < free_base) || (base > free_last));	/* free block outside arena */
-
-    else if ((base <= free_base) && (last >= free_last))
-	/* free block contains entire arena */
-	*free_basep = *free_lastp = 0;
-
-    else if (base <= free_base)
-	/* free block is head of arena */
-	*free_basep = last + 1;
-
-    else if (last >= free_last)
-	/* free block is tail of arena */
-	*free_lastp = base - 1;
-
-    /*
-     * We are left with two regions: the free area
-     * in the arena "below" the block, and the free
-     * area in the arena "above" the block. Keep
-     * the one that is bigger.
-     */
-
-    else if ((base - free_base) > (free_last - last))
-	*free_lastp = base - 1;		/* keep lower chunk */
-    else
-	*free_basep = last + 1;		/* keep upper chunk */
-}
-
-/* Convert from ssram_bits in control register to number of SSRAM entries */
-#define ATE_NUM_ENTRIES(n) _ate_info[n]
-
-/* Possible choices for number of ATE entries in Bridge's SSRAM */
-LOCAL int               _ate_info[] =
-{
-    0,					/* 0 entries */
-    8 * 1024,				/* 8K entries */
-    16 * 1024,				/* 16K entries */
-    64 * 1024				/* 64K entries */
-};
-
-#define ATE_NUM_SIZES (sizeof(_ate_info) / sizeof(int))
-#define ATE_PROBE_VALUE 0x0123456789abcdefULL
-
-/*
- * Determine the size of this bridge's external mapping SSRAM, and set
- * the control register appropriately to reflect this size, and initialize
- * the external SSRAM.
- */
-LOCAL int
-pcibr_init_ext_ate_ram(bridge_t *bridge)
-{
-    int                     largest_working_size = 0;
-    int                     num_entries, entry;
-    int                     i, j;
-    bridgereg_t             old_enable, new_enable;
-    int                     s;
-
-    /* Probe SSRAM to determine its size. */
-    old_enable = bridge->b_int_enable;
-    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-    bridge->b_int_enable = new_enable;
-
-    for (i = 1; i < ATE_NUM_SIZES; i++) {
-	/* Try writing a value */
-	bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
-
-	/* Guard against wrap */
-	for (j = 1; j < i; j++)
-	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;
-
-	/* See if value was written */
-	if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
-	    largest_working_size = i;
-    }
-    bridge->b_int_enable = old_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    /*
-     * ensure that we write and read without any interruption.
-     * The read following the write is required for the Bridge war
-     */
-
-    s = splhi();
-    bridge->b_wid_control = (bridge->b_wid_control
-	& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
-	| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
-    bridge->b_wid_control;		/* inval addr bug war */
-    splx(s);
-
-    num_entries = ATE_NUM_ENTRIES(largest_working_size);
-
-#if PCIBR_ATE_DEBUG
-    if (num_entries)
-	printk("bridge at 0x%x: clearing %d external ATEs\n", bridge, num_entries);
-    else
-	printk("bridge at 0x%x: no externa9422l ATE RAM found\n", bridge);
-#endif
-
-    /* Initialize external mapping entries */
-    for (entry = 0; entry < num_entries; entry++)
-	bridge->b_ext_ate_ram[entry] = 0;
-
-    return (num_entries);
-}
-
-/*
- * Allocate "count" contiguous Bridge Address Translation Entries
- * on the specified bridge to be used for PCI to XTALK mappings.
- * Indices in rm map range from 1..num_entries.  Indicies returned
- * to caller range from 0..num_entries-1.
- *
- * Return the start index on success, -1 on failure.
- */
-LOCAL int
-pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count)
-{
-    int                     index = 0;
-
-    index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count);
-/* printk("Colin: pcibr_ate_alloc - index %d count %d \n", index, count); */
-
-    if (!index && pcibr_soft->bs_ext_ate_map)
-	index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count);
-
-    /* rmalloc manages resources in the 1..n
-     * range, with 0 being failure.
-     * pcibr_ate_alloc manages resources
-     * in the 0..n-1 range, with -1 being failure.
-     */
-    return index - 1;
-}
-
-LOCAL void
-pcibr_ate_free(pcibr_soft_t pcibr_soft, int index, int count)
-/* Who says there's no such thing as a free meal? :-) */
-{
-    /* note the "+1" since rmalloc handles 1..n but
-     * we start counting ATEs at zero.
-     */
-/* printk("Colin: pcibr_ate_free - index %d count %d\n", index, count); */
-
-    rmfree((index < pcibr_soft->bs_int_ate_size)
-	   ? pcibr_soft->bs_int_ate_map
-	   : pcibr_soft->bs_ext_ate_map,
-	   count, index + 1);
-}
-
-LOCAL pcibr_info_t
-pcibr_info_get(devfs_handle_t vhdl)
-{
-    return (pcibr_info_t) pciio_info_get(vhdl);
-}
-
-pcibr_info_t
-pcibr_device_info_new(
-			 pcibr_soft_t pcibr_soft,
-			 pciio_slot_t slot,
-			 pciio_function_t rfunc,
-			 pciio_vendor_id_t vendor,
-			 pciio_device_id_t device)
-{
-    pcibr_info_t            pcibr_info;
-    pciio_function_t        func;
-    int                     ibit;
-
-    func = (rfunc == PCIIO_FUNC_NONE) ? 0 : rfunc;
-
-    NEW(pcibr_info);
-    pciio_device_info_new(&pcibr_info->f_c,
-			  pcibr_soft->bs_vhdl,
-			  slot, rfunc,
-			  vendor, device);
-
-    if (slot != PCIIO_SLOT_NONE) {
-
-	/*
-	 * Currently favored mapping from PCI
-	 * slot number and INTA/B/C/D to Bridge
-	 * PCI Interrupt Bit Number:
-	 *
-	 *     SLOT     A B C D
-	 *      0       0 4 0 4
-	 *      1       1 5 1 5
-	 *      2       2 6 2 6
-	 *      3       3 7 3 7
-	 *      4       4 0 4 0
-	 *      5       5 1 5 1
-	 *      6       6 2 6 2
-	 *      7       7 3 7 3
-	 *
-	 * XXX- allow pcibr_hints to override default
-	 * XXX- allow ADMIN to override pcibr_hints
-	 */
-	for (ibit = 0; ibit < 4; ++ibit)
-	    pcibr_info->f_ibit[ibit] =
-		(slot + 4 * ibit) & 7;
-
-	/*
-	 * Record the info in the sparse func info space.
-	 */
-	if (func < pcibr_soft->bs_slot[slot].bss_ninfo)
-	    pcibr_soft->bs_slot[slot].bss_infos[func] = pcibr_info;
-    }
-    return pcibr_info;
-}
-
-void
-pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    pcibr_info_t	pcibr_info;
-    pciio_function_t	func;
-    pcibr_soft_slot_t	slotp = &pcibr_soft->bs_slot[slot];
-    int			nfunc = slotp->bss_ninfo;
-
-
-    for (func = 0; func < nfunc; func++) {
-	pcibr_info = slotp->bss_infos[func];
-
-	if (!pcibr_info) 
-	    continue;
-
-	slotp->bss_infos[func] = 0;
-	pciio_device_info_unregister(pcibr_vhdl, &pcibr_info->f_c);
-	pciio_device_info_free(&pcibr_info->f_c);
-	DEL(pcibr_info);
-    }
-
-    /* Clear the DEVIO(x) for this slot */
-    slotp->bss_devio.bssd_space = PCIIO_SPACE_NONE;
-    slotp->bss_devio.bssd_base = PCIBR_D32_BASE_UNSET;
-    slotp->bss_device  = 0;
-
-    
-    /* Reset the mapping usage counters */
-    slotp->bss_pmu_uctr = 0;
-    slotp->bss_d32_uctr = 0;
-    slotp->bss_d64_uctr = 0;
-
-    /* Clear the Direct translation info */
-    slotp->bss_d64_base = PCIBR_D64_BASE_UNSET;
-    slotp->bss_d64_flags = 0;
-    slotp->bss_d32_base = PCIBR_D32_BASE_UNSET;
-    slotp->bss_d32_flags = 0;
-
-    /* Clear out shadow info necessary for the external SSRAM workaround */
-    slotp->bss_ext_ates_active = ATOMIC_INIT(0);
-    slotp->bss_cmd_pointer = 0;
-    slotp->bss_cmd_shadow = 0;
-
-}
-
-/* 
- * PCI_ADDR_SPACE_LIMITS_LOAD
- *	Gets the current values of 
- *		pci io base, 
- *		pci io last,
- *		pci low memory base,
- *		pci low memory last,
- *		pci high memory base,
- * 		pci high memory last
- */
-#define PCI_ADDR_SPACE_LIMITS_LOAD()			\
-    pci_io_fb = pcibr_soft->bs_spinfo.pci_io_base;	\
-    pci_io_fl = pcibr_soft->bs_spinfo.pci_io_last;	\
-    pci_lo_fb = pcibr_soft->bs_spinfo.pci_swin_base;	\
-    pci_lo_fl = pcibr_soft->bs_spinfo.pci_swin_last;	\
-    pci_hi_fb = pcibr_soft->bs_spinfo.pci_mem_base;	\
-    pci_hi_fl = pcibr_soft->bs_spinfo.pci_mem_last;
-/*
- * PCI_ADDR_SPACE_LIMITS_STORE
- *	Sets the current values of
- *		pci io base, 
- *		pci io last,
- *		pci low memory base,
- *		pci low memory last,
- *		pci high memory base,
- * 		pci high memory last
- */
-#define PCI_ADDR_SPACE_LIMITS_STORE()			\
-    pcibr_soft->bs_spinfo.pci_io_base = pci_io_fb;	\
-    pcibr_soft->bs_spinfo.pci_io_last = pci_io_fl;	\
-    pcibr_soft->bs_spinfo.pci_swin_base = pci_lo_fb;	\
-    pcibr_soft->bs_spinfo.pci_swin_last = pci_lo_fl;	\
-    pcibr_soft->bs_spinfo.pci_mem_base = pci_hi_fb;	\
-    pcibr_soft->bs_spinfo.pci_mem_last = pci_hi_fl;
-
-#define PCI_ADDR_SPACE_LIMITS_PRINT()			\
-    printf("+++++++++++++++++++++++\n"			\
-	   "IO base 0x%x last 0x%x\n"			\
-	   "SWIN base 0x%x last 0x%x\n"			\
-	   "MEM base 0x%x last 0x%x\n"			\
-	   "+++++++++++++++++++++++\n",			\
-	   pcibr_soft->bs_spinfo.pci_io_base,		\
-	   pcibr_soft->bs_spinfo.pci_io_last,		\
-	   pcibr_soft->bs_spinfo.pci_swin_base,		\
-	   pcibr_soft->bs_spinfo.pci_swin_last,		\
-	   pcibr_soft->bs_spinfo.pci_mem_base,		\
-	   pcibr_soft->bs_spinfo.pci_mem_last);
-
-/*
- * pcibr_slot_info_init
- *	Probe for this slot and see if it is populated.
- *	If it is populated initialize the generic PCI infrastructural
- * 	information associated with this particular PCI device.
- */
-int
-pcibr_slot_info_init(devfs_handle_t 	pcibr_vhdl,
-		     pciio_slot_t 	slot)
-{
-    pcibr_soft_t	    pcibr_soft;
-    pcibr_info_h	    pcibr_infoh;
-    pcibr_info_t	    pcibr_info;
-    bridge_t		   *bridge;
-    cfg_p                   cfgw;
-    unsigned                idword;
-    unsigned                pfail;
-    unsigned                idwords[8];
-    pciio_vendor_id_t       vendor;
-    pciio_device_id_t       device;
-    unsigned                htype;
-    cfg_p                   wptr;
-    int                     win;
-    pciio_space_t           space;
-    iopaddr_t		    pci_io_fb,	pci_io_fl;
-    iopaddr_t		    pci_lo_fb,  pci_lo_fl;
-    iopaddr_t		    pci_hi_fb,  pci_hi_fl;
-    int			    nfunc;
-    pciio_function_t	    rfunc;
-    int			    func;
-    devfs_handle_t	    conn_vhdl;
-    pcibr_soft_slot_t	    slotp;
-    
-    /* Get the basic software information required to proceed */
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (!pcibr_soft)
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-    if (!PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    /* If we have a host slot (eg:- IOC3 has 2 PCI slots and the initialization
-     * is done by the host slot then we are done.
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	return(0);    
-    }
-
-    /* Check for a slot with any system critical functions */
-    if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(EPERM);
-
-    /* Load the current values of allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_LOAD();
-    
-    /* Try to read the device-id/vendor-id from the config space */
-    cfgw = bridge->b_type0_cfg_dev[slot].l;
-
-    if (pcibr_probe_slot(bridge, cfgw, &idword)) 
-	return(ENODEV);
-
-    slotp = &pcibr_soft->bs_slot[slot];
-    slotp->slot_status |= SLOT_POWER_UP;
-
-    vendor = 0xFFFF & idword;
-    /* If the vendor id is not valid then the slot is not populated
-     * and we are done.
-     */
-    if (vendor == 0xFFFF) 
-	return(ENODEV);			
-    
-    device = 0xFFFF & (idword >> 16);
-    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
-
-    nfunc = 1;
-    rfunc = PCIIO_FUNC_NONE;
-    pfail = 0;
-
-    /* NOTE: if a card claims to be multifunction
-     * but only responds to config space 0, treat
-     * it as a unifunction card.
-     */
-
-    if (htype & 0x80) {		/* MULTIFUNCTION */
-	for (func = 1; func < 8; ++func) {
-	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	    if (pcibr_probe_slot(bridge, cfgw, &idwords[func])) {
-		pfail |= 1 << func;
-		continue;
-	    }
-	    vendor = 0xFFFF & idwords[func];
-	    if (vendor == 0xFFFF) {
-		pfail |= 1 << func;
-		continue;
-	    }
-	    nfunc = func + 1;
-	    rfunc = 0;
-	}
-	cfgw = bridge->b_type0_cfg_dev[slot].l;
-    }
-    NEWA(pcibr_infoh, nfunc);
-    
-    pcibr_soft->bs_slot[slot].bss_ninfo = nfunc;
-    pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
-
-    for (func = 0; func < nfunc; ++func) {
-	unsigned                cmd_reg;
-	
-	if (func) {
-	    if (pfail & (1 << func))
-		continue;
-	    
-	    idword = idwords[func];
-	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	    
-	    device = 0xFFFF & (idword >> 16);
-	    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
-	    rfunc = func;
-	}
-	htype &= 0x7f;
-	if (htype != 0x00) {
-	    printk(KERN_WARNING  "%s pcibr: pci slot %d func %d has strange header type 0x%x\n",
-		    pcibr_soft->bs_name, slot, func, htype);
-	    continue;
-	}
-#if DEBUG && ATTACH_DEBUG
-	printk(KERN_NOTICE   
-		"%s pcibr: pci slot %d func %d: vendor 0x%x device 0x%x",
-		pcibr_soft->bs_name, slot, func, vendor, device);
-#endif	
-
-	pcibr_info = pcibr_device_info_new
-	    (pcibr_soft, slot, rfunc, vendor, device);
-	conn_vhdl = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c);
-	if (func == 0)
-	    slotp->slot_conn = conn_vhdl;
-
-#ifdef LITTLE_ENDIAN
-	cmd_reg = cfgw[(PCI_CFG_COMMAND ^ 4) / 4];
-#else
-	cmd_reg = cfgw[PCI_CFG_COMMAND / 4];
-#endif
-	
-	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
-
-	for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) {
-	    iopaddr_t               base, mask, code;
-	    size_t                  size;
-
-	    /*
-	     * GET THE BASE & SIZE OF THIS WINDOW:
-	     *
-	     * The low two or four bits of the BASE register
-	     * determines which address space we are in; the
-	     * rest is a base address. BASE registers
-	     * determine windows that are power-of-two sized
-	     * and naturally aligned, so we can get the size
-	     * of a window by writing all-ones to the
-	     * register, reading it back, and seeing which
-	     * bits are used for decode; the least
-	     * significant nonzero bit is also the size of
-	     * the window.
-	     *
-	     * WARNING: someone may already have allocated
-	     * some PCI space to this window, and in fact
-	     * PIO may be in process at this very moment
-	     * from another processor (or even from this
-	     * one, if we get interrupted)! So, if the BASE
-	     * already has a nonzero address, be generous
-	     * and use the LSBit of that address as the
-	     * size; this could overstate the window size.
-	     * Usually, when one card is set up, all are set
-	     * up; so, since we don't bitch about
-	     * overlapping windows, we are ok.
-	     *
-	     * UNFORTUNATELY, some cards do not clear their
-	     * BASE registers on reset. I have two heuristics
-	     * that can detect such cards: first, if the
-	     * decode enable is turned off for the space
-	     * that the window uses, we can disregard the
-	     * initial value. second, if the address is
-	     * outside the range that we use, we can disregard
-	     * it as well.
-	     *
-	     * This is looking very PCI generic. Except for
-	     * knowing how many slots and where their config
-	     * spaces are, this window loop and the next one
-	     * could probably be shared with other PCI host
-	     * adapters. It would be interesting to see if
-	     * this could be pushed up into pciio, when we
-	     * start supporting more PCI providers.
-	     */
-#ifdef LITTLE_ENDIAN
-	    base = wptr[((win*4)^4)/4];
-#else
-	    base = wptr[win];
-#endif
-
-	    if (base & PCI_BA_IO_SPACE) {
-		/* BASE is in I/O space. */
-		space = PCIIO_SPACE_IO;
-		mask = -4;
-		code = base & 3;
-		base = base & mask;
-		if (base == 0) {
-		    ;		/* not assigned */
-		} else if (!(cmd_reg & PCI_CMD_IO_SPACE)) {
-		    base = 0;	/* decode not enabled */
-		}
-	    } else {
-		/* BASE is in MEM space. */
-		space = PCIIO_SPACE_MEM;
-		mask = -16;
-		code = base & PCI_BA_MEM_LOCATION;	/* extract BAR type */
-		base = base & mask;
-		if (base == 0) {
-		    ;		/* not assigned */
-		} else if (!(cmd_reg & PCI_CMD_MEM_SPACE)) {
-		    base = 0;	/* decode not enabled */
-		} else if (base & 0xC0000000) {
-		    base = 0;	/* outside permissable range */
-		} else if ((code == PCI_BA_MEM_64BIT) &&
-#ifdef LITTLE_ENDIAN
-			   (wptr[(((win + 1)*4)^4)/4] != 0)) {
-#else 
-			   (wptr[win + 1] != 0)) {
-#endif /* LITTLE_ENDIAN */
-		    base = 0;	/* outside permissable range */
-		}
-	    }
-
-	    if (base != 0) {	/* estimate size */
-		size = base & -base;
-	    } else {		/* calculate size */
-#ifdef LITTLE_ENDIAN
-		wptr[((win*4)^4)/4] = ~0;	/* turn on all bits */
-		size = wptr[((win*4)^4)/4];	/* get stored bits */
-#else 
-		wptr[win] = ~0;	/* turn on all bits */
-		size = wptr[win];	/* get stored bits */
-#endif /* LITTLE_ENDIAN */
-		size &= mask;	/* keep addr */
-		size &= -size;	/* keep lsbit */
-		if (size == 0)
-		    continue;
-	    }	
-
-	    pcibr_info->f_window[win].w_space = space;
-	    pcibr_info->f_window[win].w_base = base;
-	    pcibr_info->f_window[win].w_size = size;
-
-	    /*
-	     * If this window already has PCI space
-	     * allocated for it, "subtract" that space from
-	     * our running freeblocks. Don't worry about
-	     * overlaps in existing allocated windows; we
-	     * may be overstating their sizes anyway.
-	     */
-
-	    if (base && size) {
-		if (space == PCIIO_SPACE_IO) {
-		    pcibr_freeblock_sub(&pci_io_fb,
-					&pci_io_fl,
-					base, size);
-		} else {
-		    pcibr_freeblock_sub(&pci_lo_fb,
-					&pci_lo_fl,
-					base, size);
-		    pcibr_freeblock_sub(&pci_hi_fb,
-					&pci_hi_fl,
-					base, size);
-		}	
-	    }
-#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM)
-	    /*
-	     * IOC3 BASE_ADDR* BUG WORKAROUND
-	     *
-	     
-	     * If we write to BASE1 on the IOC3, the
-	     * data in BASE0 is replaced. The
-	     * original workaround was to remember
-	     * the value of BASE0 and restore it
-	     * when we ran off the end of the BASE
-	     * registers; however, a later
-	     * workaround was added (I think it was
-	     * rev 1.44) to avoid setting up
-	     * anything but BASE0, with the comment
-	     * that writing all ones to BASE1 set
-	     * the enable-parity-error test feature
-	     * in IOC3's SCR bit 14.
-	     *
-	     * So, unless we defer doing any PCI
-	     * space allocation until drivers
-	     * attach, and set up a way for drivers
-	     * (the IOC3 in paricular) to tell us
-	     * generically to keep our hands off
-	     * BASE registers, we gotta "know" about
-	     * the IOC3 here.
-	     *
-	     * Too bad the PCI folks didn't reserve the
-	     * all-zero value for 'no BASE here' (it is a
-	     * valid code for an uninitialized BASE in
-	     * 32-bit PCI memory space).
-	     */
-	    
-	    if ((vendor == IOC3_VENDOR_ID_NUM) &&
-		(device == IOC3_DEVICE_ID_NUM))
-		break;
-#endif
-	    if (code == PCI_BA_MEM_64BIT) {
-		win++;		/* skip upper half */
-#ifdef LITTLE_ENDIAN
-		wptr[((win*4)^4)/4] = 0;	/* which must be zero */
-#else 
-		wptr[win] = 0;	/* which must be zero */
-#endif /* LITTLE_ENDIAN */
-	    }
-	}				/* next win */
-    }				/* next func */
-
-    /* Store back the values for allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_STORE();
-    return(0);
-}					
-
-/*
- * pcibr_slot_info_free
- *	Remove all the PCI infrastructural information associated
- * 	with a particular PCI device.
- */
-int
-pcibr_slot_info_free(devfs_handle_t pcibr_vhdl,
-                     pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    int			nfunc;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-
-    pcibr_device_info_free(pcibr_vhdl, slot);
-
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    DELA(pcibr_infoh,nfunc);
-    pcibr_soft->bs_slot[slot].bss_ninfo = 0;
-
-    return(0);
-}
-
-int as_debug = 0;
-/*
- * pcibr_slot_addr_space_init
- *	Reserve chunks of PCI address space as required by 
- * 	the base registers in the card.
- */
-int
-pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,
-			   pciio_slot_t	slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    bridge_t		*bridge;
-    iopaddr_t		pci_io_fb, pci_io_fl;
-    iopaddr_t		pci_lo_fb, pci_lo_fl;
-    iopaddr_t		pci_hi_fb, pci_hi_fl;
-    size_t              align;
-    iopaddr_t           mask;
-    int		    	nbars;
-    int		       	nfunc;
-    int			func;
-    int			win;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /* Get the current values for the allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_LOAD();
-
-    if (as_debug)
-#ifdef LATER
-    PCI_ADDR_SPACE_LIMITS_PRINT();
-#endif
-    /* allocate address space,
-     * for windows that have not been
-     * previously assigned.
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	return(0);
-    }
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    if (nfunc < 1)
-	return(EINVAL);
-
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    if (!pcibr_infoh)
-	return(EINVAL);
-
-    /*
-     * Try to make the DevIO windows not
-     * overlap by pushing the "io" and "hi"
-     * allocation areas up to the next one
-     * or two megabyte bound. This also
-     * keeps them from being zero.
-     *
-     * DO NOT do this with "pci_lo" since
-     * the entire "lo" area is only a
-     * megabyte, total ...
-     */
-    align = (slot < 2) ? 0x200000 : 0x100000;
-    mask = -align;
-    pci_io_fb = (pci_io_fb + align - 1) & mask;
-    pci_hi_fb = (pci_hi_fb + align - 1) & mask;
-
-    for (func = 0; func < nfunc; ++func) {
-	cfg_p                   cfgw;
-	cfg_p                   wptr;
-	pciio_space_t           space;
-	iopaddr_t               base;
-	size_t                  size;
-	cfg_p                   pci_cfg_cmd_reg_p;
-	unsigned                pci_cfg_cmd_reg;
-	unsigned                pci_cfg_cmd_reg_add = 0;
-
-	pcibr_info = pcibr_infoh[func];
-
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-	
-	cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
-
-	nbars = PCI_CFG_BASE_ADDRS;
-
-	for (win = 0; win < nbars; ++win) {
-
-	    space = pcibr_info->f_window[win].w_space;
-	    base = pcibr_info->f_window[win].w_base;
-	    size = pcibr_info->f_window[win].w_size;
-	    
-	    if (size < 1)
-		continue;
-
-	    if (base >= size) {
-#if DEBUG && PCI_DEBUG
-		printk("pcibr: slot %d func %d window %d is in %d[0x%x..0x%x], alloc by prom\n",
-			slot, func, win, space, base, base + size - 1);
-#endif
-		continue;		/* already allocated */
-	    }
-	    align = size;		/* ie. 0x00001000 */
-	    if (align < _PAGESZ)
-		align = _PAGESZ;	/* ie. 0x00004000 */
-	    mask = -align;		/* ie. 0xFFFFC000 */
-
-	    switch (space) {
-	    case PCIIO_SPACE_IO:
-		base = (pci_io_fb + align - 1) & mask;
-		if ((base + size) > pci_io_fl) {
-		    base = 0;
-		    break;
-		}
-		pci_io_fb = base + size;
-		break;
-		
-	    case PCIIO_SPACE_MEM:
-#ifdef LITTLE_ENDIAN
-		if ((wptr[((win*4)^4)/4] & PCI_BA_MEM_LOCATION) ==
-#else
-		if ((wptr[win] & PCI_BA_MEM_LOCATION) ==
-#endif  /* LITTLE_ENDIAN */
-		    PCI_BA_MEM_1MEG) {
-		    /* allocate from 20-bit PCI space */
-		    base = (pci_lo_fb + align - 1) & mask;
-		    if ((base + size) > pci_lo_fl) {
-			base = 0;
-			break;
-		    }
-		    pci_lo_fb = base + size;
-		} else {
-		    /* allocate from 32-bit or 64-bit PCI space */
-		    base = (pci_hi_fb + align - 1) & mask;
-		    if ((base + size) > pci_hi_fl) {
-			base = 0;
-			break;
-		    }
-		    pci_hi_fb = base + size;
-		}
-		break;
-		
-	    default:
-		base = 0;
-#if DEBUG && PCI_DEBUG
-		printk("pcibr: slot %d window %d had bad space code %d\n",
-			slot, win, space);
-#endif
-	    }
-	    pcibr_info->f_window[win].w_base = base;
-#ifdef LITTLE_ENDIAN
-	    wptr[((win*4)^4)/4] = base;
-#if DEBUG && PCI_DEBUG
-		printk("Setting base address 0x%p base 0x%x\n", &(wptr[((win*4)^4)/4]), base);
-#endif
-#else
-	    wptr[win] = base;
-#endif  /* LITTLE_ENDIAN */
-
-#if DEBUG && PCI_DEBUG
-	    if (base >= size)
-		printk("pcibr: slot %d func %d window %d is in %d [0x%x..0x%x], alloc by pcibr\n",
-			slot, func, win, space, base, base + size - 1);
-	    else
-		printk("pcibr: slot %d func %d window %d, unable to alloc 0x%x in 0x%p\n",
-			slot, func, win, size, space);
-#endif
-	}				/* next base */
-
-	/*
-	 * Allocate space for the EXPANSION ROM
-	 * NOTE: DO NOT DO THIS ON AN IOC3,
-	 * as it blows the system away.
-	 */
-	base = size = 0;
-	if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) ||
-	    (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) {
-
-	    wptr = cfgw + PCI_EXPANSION_ROM / 4;
-#ifdef LITTLE_ENDIAN
-	    wptr[1] = 0xFFFFF000;
-	    mask = wptr[1];
-#else
-	    *wptr = 0xFFFFF000;
-	    mask = *wptr;
-#endif  /* LITTLE_ENDIAN */
-	    if (mask & 0xFFFFF000) {
-		size = mask & -mask;
-		align = size;
-		if (align < _PAGESZ)
-		    align = _PAGESZ;
-		mask = -align;
-		base = (pci_hi_fb + align - 1) & mask;
-		if ((base + size) > pci_hi_fl)
-		    base = size = 0;
-		else {
-		    pci_hi_fb = base + size;
-#ifdef LITTLE_ENDIAN
-		    wptr[1] = base;
-#else
-		    *wptr = base;
-#endif  /* LITTLE_ENDIAN */
-#if DEBUG && PCI_DEBUG
-		    printk("%s/%d ROM in 0x%lx..0x%lx (alloc by pcibr)\n",
-			    pcibr_soft->bs_name, slot,
-			    base, base + size - 1);
-#endif
-		}
-	    }
-	}
-	pcibr_info->f_rbase = base;
-	pcibr_info->f_rsize = size;
-	
-	/*
-	 * if necessary, update the board's
-	 * command register to enable decoding
-	 * in the windows we added.
-	 *
-	 * There are some bits we always want to
-	 * be sure are set.
-	 */
-	pci_cfg_cmd_reg_add |= PCI_CMD_IO_SPACE;
-
-	/*
-	 * The Adaptec 1160 FC Controller WAR #767995:
-	 * The part incorrectly ignores the upper 32 bits of a 64 bit
-	 * address when decoding references to it's registers so to
-	 * keep it from responding to a bus cycle that it shouldn't
-	 * we only use I/O space to get at it's registers.  Don't
-	 * enable memory space accesses on that PCI device.
-	 */
-	#define FCADP_VENDID 0x9004 /* Adaptec Vendor ID from fcadp.h */
-	#define FCADP_DEVID 0x1160  /* Adaptec 1160 Device ID from fcadp.h */
-
-	if ((pcibr_info->f_vendor != FCADP_VENDID) ||
-	    (pcibr_info->f_device != FCADP_DEVID))
-	    pci_cfg_cmd_reg_add |= PCI_CMD_MEM_SPACE;
-
-	pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER;
-
-	pci_cfg_cmd_reg_p = cfgw + PCI_CFG_COMMAND / 4;
-	pci_cfg_cmd_reg = *pci_cfg_cmd_reg_p;
-#if PCI_FBBE	/* XXX- check here to see if dev can do fast-back-to-back */
-	if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP))
-	    fast_back_to_back_enable = 0;
-#endif
-	pci_cfg_cmd_reg &= 0xFFFF;
-	if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg)
-	    *pci_cfg_cmd_reg_p = pci_cfg_cmd_reg | pci_cfg_cmd_reg_add;
-	
-    }				/* next func */
-
-    /* Now that we have allocated new chunks of PCI address spaces to this
-     * card we need to update the bookkeeping values which indicate
-     * the current PCI address space allocations.
-     */
-    PCI_ADDR_SPACE_LIMITS_STORE();
-    return(0);
-}
-
-/*
- * pcibr_slot_device_init
- * 	Setup the device register in the bridge for this PCI slot.
- */
-int
-pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,
-		       pciio_slot_t slot)
-{
-    pcibr_soft_t	 pcibr_soft;
-    bridge_t		*bridge;
-    bridgereg_t		 devreg;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /*
-     * Adjustments to Device(x)
-     * and init of bss_device shadow
-     */
-    devreg = bridge->b_device[slot].reg;
-    devreg &= ~BRIDGE_DEV_PAGE_CHK_DIS;
-    devreg |= BRIDGE_DEV_COH | BRIDGE_DEV_VIRTUAL_EN;
-#ifdef LITTLE_ENDIAN
-    devreg |= BRIDGE_DEV_DEV_SWAP;
-#endif
-    pcibr_soft->bs_slot[slot].bss_device = devreg;
-    bridge->b_device[slot].reg = devreg;
-
-#if DEBUG && PCI_DEBUG
-	printk("pcibr Device(%d): 0x%lx\n", slot, bridge->b_device[slot].reg);
-#endif
-
-#if DEBUG && PCI_DEBUG
-    printk("pcibr: PCI space allocation done.\n");
-#endif
-
-    return(0);
-}
-
-/*
- * pcibr_slot_guest_info_init
- *	Setup the host/guest relations for a PCI slot.
- */
-int
-pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,
-			   pciio_slot_t	slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    pcibr_soft_slot_t	slotp;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    /* create info and verticies for guest slots;
-     * for compatibilitiy macros, create info
-     * for even unpopulated slots (but do not
-     * build verticies for them).
-     */
-    if (pcibr_soft->bs_slot[slot].bss_ninfo < 1) {
-	NEWA(pcibr_infoh, 1);
-	pcibr_soft->bs_slot[slot].bss_ninfo = 1;
-	pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
-
-	pcibr_info = pcibr_device_info_new
-	    (pcibr_soft, slot, PCIIO_FUNC_NONE,
-	     PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
-
-	if (pcibr_soft->bs_slot[slot].has_host) {
-	    slotp->slot_conn = pciio_device_info_register
-		(pcibr_vhdl, &pcibr_info->f_c);
-	}
-    }
-
-    /* generate host/guest relations
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	int  host = pcibr_soft->bs_slot[slot].host_slot;
-	pcibr_soft_slot_t host_slotp = &pcibr_soft->bs_slot[host];
-
-	hwgraph_edge_add(slotp->slot_conn,
-			 host_slotp->slot_conn,
-			 EDGE_LBL_HOST);
-
-	/* XXX- only gives us one guest edge per
-	 * host. If/when we have a host with more than
-	 * one guest, we will need to figure out how
-	 * the host finds all its guests, and sorts
-	 * out which one is which.
-	 */
-	hwgraph_edge_add(host_slotp->slot_conn,
-			 slotp->slot_conn,
-			 EDGE_LBL_GUEST);
-    }
-
-    return(0);
-}
-
-/*
- * pcibr_slot_initial_rrb_alloc
- *	Allocate a default number of rrbs for this slot on 
- * 	the two channels.  This is dictated by the rrb allocation
- * 	strategy routine defined per platform.
- */
-
-int
-pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,
-			     pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    bridge_t		*bridge;
-    int                 c0, c1;
-    int			r;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /* How may RRBs are on this slot?
-     */
-    c0 = do_pcibr_rrb_count_valid(bridge, slot);
-    c1 = do_pcibr_rrb_count_valid(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL);
-
-#if PCIBR_RRB_DEBUG
-    printk("pcibr_attach: slot %d started with %d+%d\n", slot, c0, c1);
-#endif
-
-    /* Do we really need any?
-     */
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    pcibr_info = pcibr_infoh[0];
-    if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) &&
-	!pcibr_soft->bs_slot[slot].has_host) {
-	if (c0 > 0)
-	    do_pcibr_rrb_free(bridge, slot, c0);
-	if (c1 > 0)
-	    do_pcibr_rrb_free(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL, c1);
-	pcibr_soft->bs_rrb_valid[slot] = 0x1000;
-	pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0x1000;
-	return(ENODEV);
-    }
-
-    pcibr_soft->bs_rrb_avail[slot & 1] -= c0 + c1;
-    pcibr_soft->bs_rrb_valid[slot] = c0;
-    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = c1;
-
-    pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0);
-    pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1);
-
-    r = 3 - (c0 + c1);
-
-    if (r > 0) {
-	pcibr_soft->bs_rrb_res[slot] = r;
-	pcibr_soft->bs_rrb_avail[slot & 1] -= r;
-    }
-
-#if PCIBR_RRB_DEBUG
-    printk("\t%d+%d+%d",
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-    printk("\n");
-#endif
-
-    return(0);
-}
-
-/*
- * pcibr_slot_call_device_attach
- *	This calls the associated driver attach routine for the PCI
- * 	card in this slot.
- */
-int
-pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
-			      pciio_slot_t slot,
-			      int          drv_flags)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    async_attach_t	aa = NULL;
-    int			func;
-    devfs_handle_t	xconn_vhdl,conn_vhdl;
-    int			nfunc;
-    int                 error_func;
-    int                 error_slot = 0;
-    int                 error = ENODEV;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-
-    if (pcibr_soft->bs_slot[slot].has_host) {
-        return(EPERM);
-    }
-    
-    xconn_vhdl = pcibr_soft->bs_conn;
-    aa = async_attach_get_info(xconn_vhdl);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-	pcibr_info = pcibr_infoh[func];
-	
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-
-	conn_vhdl = pcibr_info->f_vertex;
-
-#ifdef LATER
-	/*
-	 * Activate if and when we support cdl.
-	 */
-	if (aa)
-	    async_attach_add_info(conn_vhdl, aa);
-#endif	/* LATER */
-
-	error_func = pciio_device_attach(conn_vhdl, drv_flags);
-
-        pcibr_info->f_att_det_error = error_func;
-
-	if (error_func)
-	    error_slot = error_func;
-
-        error = error_slot;
-
-    }				/* next func */
-
-    if (error) {
-	if ((error != ENODEV) && (error != EUNATCH))
-	    pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT;
-    } else {
-        pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT;
-    }
-        
-    return(error);
-}
-
-/*
- * pcibr_slot_call_device_detach
- *	This calls the associated driver detach routine for the PCI
- * 	card in this slot.
- */
-int
-pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
-			      pciio_slot_t slot,
-			      int          drv_flags)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    int			func;
-    devfs_handle_t	conn_vhdl = GRAPH_VERTEX_NONE;
-    int			nfunc;
-    int                 error_func;
-    int                 error_slot = 0;
-    int                 error = ENODEV;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    if (pcibr_soft->bs_slot[slot].has_host)
-        return(EPERM);
-
-    /* Make sure that we do not detach a system critical function vertex */
-    if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(EPERM);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-	pcibr_info = pcibr_infoh[func];
-	
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-
-	conn_vhdl = pcibr_info->f_vertex;
-
-	error_func = pciio_device_detach(conn_vhdl, drv_flags);
-
-        pcibr_info->f_att_det_error = error_func;
-
-	if (error_func)
-	    error_slot = error_func;
-
-	error = error_slot;
-
-    }				/* next func */
-
-    pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
-
-    if (error) {
-	if ((error != ENODEV) && (error != EUNATCH))
-            pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT;
-    } else {
-        if (conn_vhdl != GRAPH_VERTEX_NONE) 
-            pcibr_device_unregister(conn_vhdl);
-        pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT;
-    }
-        
-    return(error);
-}
-
-/*
- * pcibr_slot_detach
- *	This is a place holder routine to keep track of all the
- *	slot-specific freeing that needs to be done.
- */
-int
-pcibr_slot_detach(devfs_handle_t pcibr_vhdl,
-		  pciio_slot_t slot,
-		  int          drv_flags)
-{
-    int		  error;
-    
-    /* Call the device detach function */
-    error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
-    return (error);
-
-}
-
-/*
- * pcibr_is_slot_sys_critical
- *      Check slot for any functions that are system critical.
- *      Return 1 if any are system critical or 0 otherwise.
- *
- *      This function will always return 0 when called by 
- *      pcibr_attach() because the system critical vertices 
- *      have not yet been set in the hwgraph.
- */
-int
-pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,
-                      pciio_slot_t slot)
-{
-    pcibr_soft_t        pcibr_soft;
-    pcibr_info_h        pcibr_infoh;
-    pcibr_info_t        pcibr_info;
-    devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;
-    int                 nfunc;
-    int                 func;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-        return(0);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-        pcibr_info = pcibr_infoh[func];
-        if (!pcibr_info)
-            continue;
-
-        if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-            continue;
-
-        conn_vhdl = pcibr_info->f_vertex;
-        if (is_sys_critical_vertex(conn_vhdl)) { 
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-            printk(KERN_WARNING  "%v is a system critical device vertex\n", conn_vhdl);
-#else
-            printk(KERN_WARNING  "%p is a system critical device vertex\n", (void *)conn_vhdl);
-#endif
-            return(1); 
-        }
-
-    }
-
-    return(0);
-}
-
-/*
- * pcibr_device_unregister
- *	This frees up any hardware resources reserved for this PCI device
- * 	and removes any PCI infrastructural information setup for it.
- *	This is usually used at the time of shutting down of the PCI card.
- */
-int
-pcibr_device_unregister(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t	 pciio_info;
-    devfs_handle_t	 pcibr_vhdl;
-    pciio_slot_t	 slot;
-    pcibr_soft_t	 pcibr_soft;
-    bridge_t		*bridge;
-    int			 error_call;
-    int			 error = 0;
-
-    pciio_info = pciio_info_get(pconn_vhdl);
-
-    pcibr_vhdl = pciio_info_master_get(pciio_info);
-    slot = pciio_info_slot_get(pciio_info);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge = pcibr_soft->bs_base;
-
-    /* Clear all the hardware xtalk resources for this device */
-    xtalk_widgetdev_shutdown(pcibr_soft->bs_conn, slot);
-
-    /* Flush all the rrbs */
-    pcibr_rrb_flush(pconn_vhdl);
-
-    /* Free the rrbs allocated to this slot */
-    error_call = do_pcibr_rrb_free(bridge, slot, 
-		                   pcibr_soft->bs_rrb_valid[slot] +
-		                   pcibr_soft->bs_rrb_valid[slot + 
-                                   PCIBR_RRB_SLOT_VIRTUAL]);
-
-    if (error_call)
-        error = ERANGE;
-
-    pcibr_soft->bs_rrb_valid[slot] = 0;
-    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0;
-    pcibr_soft->bs_rrb_res[slot] = 0;
-
-    /* Flush the write buffers !! */
-    error_call = pcibr_wrb_flush(pconn_vhdl);
-
-    if (error_call)
-        error = error_call;
-
-    /* Clear the information specific to the slot */
-    error_call = pcibr_slot_info_free(pcibr_vhdl, slot);
-
-    if (error_call)
-        error = error_call;
-
-    return(error);
-    
-}
-
-/* 
- * build a convenience link path in the
- * form of ".../<iobrick>/bus/<busnum>"
- * 
- * returns 1 on success, 0 otherwise
- *
- * depends on hwgraph separator == '/'
- */
-int
-pcibr_bus_cnvlink(devfs_handle_t f_c, int slot)
-{
-        char dst[MAXDEVNAME];
-	char *dp = dst;
-        char *cp, *xp;
-        int widgetnum;
-        char pcibus[8];
-	devfs_handle_t nvtx, svtx;
-	int rv;
-
-#if DEBUG
-	printk("pcibr_bus_cnvlink: slot= %d f_c= %p\n", 
-		slot, f_c);
-	{
-		int pos;
-		char dname[256];
-		pos = devfs_generate_path(f_c, dname, 256);
-		printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-	}
-#endif
-
-	if (GRAPH_SUCCESS != hwgraph_vertex_name_get(f_c, dst, MAXDEVNAME))
-		return 0;
-
-	/* dst example == /hw/module/001c02/Pbrick/xtalk/8/pci/direct */
-
-	/* find the widget number */
-	xp = strstr(dst, "/"EDGE_LBL_XTALK"/");
-	if (xp == NULL)
-		return 0;
-	widgetnum = atoi(xp+7);
-	if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F)
-		return 0;
-
-	/* remove "/pci/direct" from path */
-	cp = strstr(dst, "/" EDGE_LBL_PCI "/" "direct");
-	if (cp == NULL)
-		return 0;
-	*cp = (char)NULL;
-
-	/* get the vertex for the widget */
-	if (GRAPH_SUCCESS != hwgraph_traverse(NULL, dp, &svtx))	
-		return 0;
-
-	*xp = (char)NULL;		/* remove "/xtalk/..." from path */
-
-	/* dst example now == /hw/module/001c02/Pbrick */
-
-	/* get the bus number */
-        strcat(dst, "/bus");
-        sprintf(pcibus, "%d", p_busnum[widgetnum]);
-
-	/* link to bus to widget */
-	rv = hwgraph_path_add(NULL, dp, &nvtx);
-	if (GRAPH_SUCCESS == rv)
-		rv = hwgraph_edge_add(nvtx, svtx, pcibus);
-
-	return (rv == GRAPH_SUCCESS);
-}
-
-
-/*
- *    pcibr_attach: called every time the crosstalk
- *      infrastructure is asked to initialize a widget
- *      that matches the part number we handed to the
- *      registration routine above.
- */
-/*ARGSUSED */
-int
-pcibr_attach(devfs_handle_t xconn_vhdl)
-{
-    /* REFERENCED */
-    graph_error_t           rc;
-    devfs_handle_t            pcibr_vhdl;
-    devfs_handle_t            ctlr_vhdl;
-    bridge_t               *bridge = NULL;
-    bridgereg_t             id;
-    int                     rev;
-    pcibr_soft_t            pcibr_soft;
-    pcibr_info_t            pcibr_info;
-    xwidget_info_t          info;
-    xtalk_intr_t            xtalk_intr;
-    device_desc_t           dev_desc = (device_desc_t)0;
-    int                     slot;
-    int                     ibit;
-    devfs_handle_t            noslot_conn;
-    char                    devnm[MAXDEVNAME], *s;
-    pcibr_hints_t           pcibr_hints;
-    bridgereg_t             b_int_enable;
-    unsigned                rrb_fixed = 0;
-
-    iopaddr_t               pci_io_fb, pci_io_fl;
-    iopaddr_t               pci_lo_fb, pci_lo_fl;
-    iopaddr_t               pci_hi_fb, pci_hi_fl;
-
-    int                     spl_level;
-#ifdef LATER
-    char		    *nicinfo = (char *)0;
-#endif
-
-#if PCI_FBBE
-    int                     fast_back_to_back_enable;
-#endif
-    l1sc_t		    *scp;
-    nasid_t		    nasid;
-
-    async_attach_t          aa = NULL;
-
-    aa = async_attach_get_info(xconn_vhdl);
-
-#if DEBUG && ATTACH_DEBUG
-    printk("pcibr_attach: xconn_vhdl=  %p\n", xconn_vhdl);
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(xconn_vhdl, dname, 256);
-	printk("%s : path= %s \n", __FUNCTION__, &dname[pos]);
-    }
-#endif
-
-    /* Setup the PRB for the bridge in CONVEYOR BELT
-     * mode. PRBs are setup in default FIRE-AND-FORGET
-     * mode during the initialization.
-     */
-    hub_device_flags_set(xconn_vhdl, HUB_PIO_CONVEYOR);
-
-    bridge = (bridge_t *)
-	xtalk_piotrans_addr(xconn_vhdl, NULL,
-			    0, sizeof(bridge_t), 0);
-
-#ifndef MEDUSA_HACK
-    if ((bridge->b_wid_stat & BRIDGE_STAT_PCI_GIO_N) == 0)
-	return -1;			/* someone else handles GIO bridges. */
-#endif
-
-    if (XWIDGET_PART_REV_NUM(bridge->b_wid_id) == XBRIDGE_PART_REV_A)
-	NeedXbridgeSwap = 1;
-
-    /*
-     * Create the vertex for the PCI bus, which we
-     * will also use to hold the pcibr_soft and
-     * which will be the "master" vertex for all the
-     * pciio connection points we will hang off it.
-     * This needs to happen before we call nic_bridge_vertex_info
-     * as we are some of the *_vmc functions need access to the edges.
-     *
-     * Opening this vertex will provide access to
-     * the Bridge registers themselves.
-     */
-    rc = hwgraph_path_add(xconn_vhdl, EDGE_LBL_PCI, &pcibr_vhdl);
-    ASSERT(rc == GRAPH_SUCCESS);
-
-    ctlr_vhdl = NULL;
-    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER,
-                0, DEVFS_FL_AUTO_DEVNUM,
-                0, 0,
-                S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                &pcibr_fops, NULL);
-
-    ASSERT(ctlr_vhdl != NULL);
-
-    /*
-     * decode the nic, and hang its stuff off our
-     * connection point where other drivers can get
-     * at it.
-     */
-#ifdef LATER
-    nicinfo = BRIDGE_VERTEX_MFG_INFO(xconn_vhdl, (nic_data_t) & bridge->b_nic);
-#endif
-
-    /*
-     * Get the hint structure; if some NIC callback
-     * marked this vertex as "hands-off" then we
-     * just return here, before doing anything else.
-     */
-    pcibr_hints = pcibr_hints_get(xconn_vhdl, 0);
-
-    if (pcibr_hints && pcibr_hints->ph_hands_off)
-	return -1;			/* generic operations disabled */
-
-    id = bridge->b_wid_id;
-    rev = XWIDGET_PART_REV_NUM(id);
-
-    hwgraph_info_add_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, (arbitrary_info_t) rev);
-
-    /*
-     * allocate soft state structure, fill in some
-     * fields, and hook it up to our vertex.
-     */
-    NEW(pcibr_soft);
-    BZERO(pcibr_soft, sizeof *pcibr_soft);
-    pcibr_soft_set(pcibr_vhdl, pcibr_soft);
-
-    pcibr_soft->bs_conn = xconn_vhdl;
-    pcibr_soft->bs_vhdl = pcibr_vhdl;
-    pcibr_soft->bs_base = bridge;
-    pcibr_soft->bs_rev_num = rev;
-    pcibr_soft->bs_intr_bits = pcibr_intr_bits;
-    if (is_xbridge(bridge)) {
-	pcibr_soft->bs_int_ate_size = XBRIDGE_INTERNAL_ATES;
-	pcibr_soft->bs_xbridge = 1;
-    } else {
-	pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES;
-	pcibr_soft->bs_xbridge = 0;
-    }
-
-    nasid = NASID_GET(bridge);
-    scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    pcibr_soft->bs_l1sc = scp;
-    pcibr_soft->bs_moduleid = iobrick_module_get(scp);
-    pcibr_soft->bsi_err_intr = 0;
-
-    /* Bridges up through REV C
-     * are unable to set the direct
-     * byteswappers to BYTE_STREAM.
-     */
-    if (pcibr_soft->bs_rev_num <= BRIDGE_PART_REV_C) {
-	pcibr_soft->bs_pio_end_io = PCIIO_WORD_VALUES;
-	pcibr_soft->bs_pio_end_mem = PCIIO_WORD_VALUES;
-    }
-#if PCIBR_SOFT_LIST
-    {
-	pcibr_list_p            self;
-
-	NEW(self);
-	self->bl_soft = pcibr_soft;
-	self->bl_vhdl = pcibr_vhdl;
-	self->bl_next = pcibr_list;
-        pcibr_list = self; 
-    }
-#endif
-
-    /*
-     * get the name of this bridge vertex and keep the info. Use this
-     * only where it is really needed now: like error interrupts.
-     */
-    s = dev_to_name(pcibr_vhdl, devnm, MAXDEVNAME);
-    pcibr_soft->bs_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
-    strcpy(pcibr_soft->bs_name, s);
-
-#if SHOW_REVS || DEBUG
-#if !DEBUG
-    if (kdebug)
-#endif
-	printk("%sBridge ASIC: rev %s (code=0x%x) at %s\n",
-		is_xbridge(bridge) ? "X" : "",
-		(rev == BRIDGE_PART_REV_A) ? "A" :
-		(rev == BRIDGE_PART_REV_B) ? "B" :
-		(rev == BRIDGE_PART_REV_C) ? "C" :
-		(rev == BRIDGE_PART_REV_D) ? "D" :
-		(rev == XBRIDGE_PART_REV_A) ? "A" :
-		(rev == XBRIDGE_PART_REV_B) ? "B" :
-		"unknown",
-		rev, pcibr_soft->bs_name);
-#endif
-
-    info = xwidget_info_get(xconn_vhdl);
-    pcibr_soft->bs_xid = xwidget_info_id_get(info);
-    pcibr_soft->bs_master = xwidget_info_master_get(info);
-    pcibr_soft->bs_mxid = xwidget_info_masterid_get(info);
-
-    /*
-     * Init bridge lock.
-     */
-    spin_lock_init(&pcibr_soft->bs_lock);
-
-    /*
-     * If we have one, process the hints structure.
-     */
-    if (pcibr_hints) {
-	rrb_fixed = pcibr_hints->ph_rrb_fixed;
-
-	pcibr_soft->bs_rrb_fixed = rrb_fixed;
-
-	if (pcibr_hints->ph_intr_bits)
-	    pcibr_soft->bs_intr_bits = pcibr_hints->ph_intr_bits;
-
-	for (slot = 0; slot < 8; ++slot) {
-	    int                     hslot = pcibr_hints->ph_host_slot[slot] - 1;
-
-	    if (hslot < 0) {
-		pcibr_soft->bs_slot[slot].host_slot = slot;
-	    } else {
-		pcibr_soft->bs_slot[slot].has_host = 1;
-		pcibr_soft->bs_slot[slot].host_slot = hslot;
-	    }
-	}
-    }
-    /*
-     * set up initial values for state fields
-     */
-    for (slot = 0; slot < 8; ++slot) {
-	pcibr_soft->bs_slot[slot].bss_devio.bssd_space = PCIIO_SPACE_NONE;
-	pcibr_soft->bs_slot[slot].bss_d64_base = PCIBR_D64_BASE_UNSET;
-	pcibr_soft->bs_slot[slot].bss_d32_base = PCIBR_D32_BASE_UNSET;
-	pcibr_soft->bs_slot[slot].bss_ext_ates_active = ATOMIC_INIT(0);
-    }
-
-    for (ibit = 0; ibit < 8; ++ibit) {
-	pcibr_soft->bs_intr[ibit].bsi_xtalk_intr = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_soft = pcibr_soft;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_list = NULL;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_stat = 
-							&(bridge->b_int_status);
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_hdlrcnt = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_shared = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_connected = 0;
-    }
-
-    /*
-     * Initialize various Bridge registers.
-     */
-
-    /*
-     * On pre-Rev.D bridges, set the PCI_RETRY_CNT
-     * to zero to avoid dropping stores. (#475347)
-     */
-    if (rev < BRIDGE_PART_REV_D)
-	bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_MASK;
-
-    /*
-     * Clear all pending interrupts.
-     */
-    bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
-
-    /*
-     * Until otherwise set up,
-     * assume all interrupts are
-     * from slot 7.
-     */
-    bridge->b_int_device = (uint32_t) 0xffffffff;
-
-    {
-	bridgereg_t             dirmap;
-	paddr_t                 paddr;
-	iopaddr_t               xbase;
-	xwidgetnum_t            xport;
-	iopaddr_t               offset;
-	int                     num_entries = 0;
-	int                     entry;
-	cnodeid_t		cnodeid;
-	nasid_t			nasid;
-
-	/* Set the Bridge's 32-bit PCI to XTalk
-	 * Direct Map register to the most useful
-	 * value we can determine.  Note that we
-	 * must use a single xid for all of:
-	 *      direct-mapped 32-bit DMA accesses
-	 *      direct-mapped 64-bit DMA accesses
-	 *      DMA accesses through the PMU
-	 *      interrupts
-	 * This is the only way to guarantee that
-	 * completion interrupts will reach a CPU
-	 * after all DMA data has reached memory.
-	 * (Of course, there may be a few special
-	 * drivers/controlers that explicitly manage
-	 * this ordering problem.)
-	 */
-
-	cnodeid = 0;  /* default node id */
-	/*
-	 * Determine the base address node id to be used for all 32-bit
-	 * Direct Mapping I/O. The default is node 0, but this can be changed
-	 * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE
-	 * attribute in the irix.sm config file. A device driver can obtain
-	 * this node value via a call to pcibr_get_dmatrans_node().
-	 */
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-	paddr = NODE_OFFSET(nasid) + 0;
-
-	/* currently, we just assume that if we ask
-	 * for a DMA mapping to "zero" the XIO
-	 * host will transmute this into a request
-	 * for the lowest hunk of memory.
-	 */
-	xbase = xtalk_dmatrans_addr(xconn_vhdl, 0,
-				    paddr, _PAGESZ, 0);
-
-	if (xbase != XIO_NOWHERE) {
-	    if (XIO_PACKED(xbase)) {
-		xport = XIO_PORT(xbase);
-		xbase = XIO_ADDR(xbase);
-	    } else
-		xport = pcibr_soft->bs_mxid;
-
-	    offset = xbase & ((1ull << BRIDGE_DIRMAP_OFF_ADDRSHFT) - 1ull);
-	    xbase >>= BRIDGE_DIRMAP_OFF_ADDRSHFT;
-
-	    dirmap = xport << BRIDGE_DIRMAP_W_ID_SHFT;
-
-	    if (xbase)
-		dirmap |= BRIDGE_DIRMAP_OFF & xbase;
-	    else if (offset >= (512 << 20))
-		dirmap |= BRIDGE_DIRMAP_ADD512;
-
-	    bridge->b_dir_map = dirmap;
-	}
-	/*
-	 * Set bridge's idea of page size according to the system's
-	 * idea of "IO page size".  TBD: The idea of IO page size
-	 * should really go away.
-	 */
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	spl_level = splhi();
-#if IOPGSIZE == 4096
-	bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE;
-#elif IOPGSIZE == 16384
-	bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE;
-#else
-	<<<Unable to deal with IOPGSIZE >>>;
-#endif
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(spl_level);
-
-	/* Initialize internal mapping entries */
-	for (entry = 0; entry < pcibr_soft->bs_int_ate_size; entry++)
-	    bridge->b_int_ate_ram[entry].wr = 0;
-
-	/*
-	 * Determine if there's external mapping SSRAM on this
-	 * bridge.  Set up Bridge control register appropriately,
-	 * inititlize SSRAM, and set software up to manage RAM
-	 * entries as an allocatable resource.
-	 *
-	 * Currently, we just use the rm* routines to manage ATE
-	 * allocation.  We should probably replace this with a
-	 * Best Fit allocator.
-	 *
-	 * For now, if we have external SSRAM, avoid using
-	 * the internal ssram: we can't turn PREFETCH on
-	 * when we use the internal SSRAM; and besides,
-	 * this also guarantees that no allocation will
-	 * straddle the internal/external line, so we
-	 * can increment ATE write addresses rather than
-	 * recomparing against BRIDGE_INTERNAL_ATES every
-	 * time.
-	 */
-	if (is_xbridge(bridge))
-		num_entries = 0;
-	else
-		num_entries = pcibr_init_ext_ate_ram(bridge);
-
-	/* we always have 128 ATEs (512 for Xbridge) inside the chip
-	 * even if disabled for debugging.
-	 */
-	pcibr_soft->bs_int_ate_map = rmallocmap(pcibr_soft->bs_int_ate_size);
-	pcibr_ate_free(pcibr_soft, 0, pcibr_soft->bs_int_ate_size);
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_attach: %d INTERNAL ATEs\n", pcibr_soft->bs_int_ate_size);
-#endif
-
-	if (num_entries > pcibr_soft->bs_int_ate_size) {
-#if PCIBR_ATE_NOTBOTH			/* for debug -- forces us to use external ates */
-	    printk("pcibr_attach: disabling internal ATEs.\n");
-	    pcibr_ate_alloc(pcibr_soft, pcibr_soft->bs_int_ate_size);
-#endif
-	    pcibr_soft->bs_ext_ate_map = rmallocmap(num_entries);
-	    pcibr_ate_free(pcibr_soft, pcibr_soft->bs_int_ate_size,
-			   num_entries - pcibr_soft->bs_int_ate_size);
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_attach: %d EXTERNAL ATEs\n",
-		    num_entries - pcibr_soft->bs_int_ate_size);
-#endif
-	}
-    }
-
-    {
-	bridgereg_t             dirmap;
-	iopaddr_t               xbase;
-
-	/*
-	 * now figure the *real* xtalk base address
-	 * that dirmap sends us to.
-	 */
-	dirmap = bridge->b_dir_map;
-	if (dirmap & BRIDGE_DIRMAP_OFF)
-	    xbase = (iopaddr_t)(dirmap & BRIDGE_DIRMAP_OFF)
-			<< BRIDGE_DIRMAP_OFF_ADDRSHFT;
-	else if (dirmap & BRIDGE_DIRMAP_ADD512)
-	    xbase = 512 << 20;
-	else
-	    xbase = 0;
-
-	pcibr_soft->bs_dir_xbase = xbase;
-
-	/* it is entirely possible that we may, at this
-	 * point, have our dirmap pointing somewhere
-	 * other than our "master" port.
-	 */
-	pcibr_soft->bs_dir_xport =
-	    (dirmap & BRIDGE_DIRMAP_W_ID) >> BRIDGE_DIRMAP_W_ID_SHFT;
-    }
-
-    /* pcibr sources an error interrupt;
-     * figure out where to send it.
-     *
-     * If any interrupts are enabled in bridge,
-     * then the prom set us up and our interrupt
-     * has already been reconnected in mlreset
-     * above.
-     *
-     * Need to set the D_INTR_ISERR flag
-     * in the dev_desc used for allocating the
-     * error interrupt, so our interrupt will
-     * be properly routed and prioritized.
-     *
-     * If our crosstalk provider wants to
-     * fix widget error interrupts to specific
-     * destinations, D_INTR_ISERR is how it
-     * knows to do this.
-     */
-
-    xtalk_intr = xtalk_intr_alloc(xconn_vhdl, dev_desc, pcibr_vhdl);
-    ASSERT(xtalk_intr != NULL);
-
-    pcibr_soft->bsi_err_intr = xtalk_intr;
-
-    /*
-     * On IP35 with XBridge, we do some extra checks in pcibr_setwidint
-     * in order to work around some addressing limitations.  In order
-     * for that fire wall to work properly, we need to make sure we
-     * start from a known clean state.
-     */
-    pcibr_clearwidint(bridge);
-
-    xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t)pcibr_setwidint, (void *)bridge);
-
-    /*
-     * now we can start handling error interrupts;
-     * enable all of them.
-     * NOTE: some PCI ints may already be enabled.
-     */
-    b_int_enable = bridge->b_int_enable | BRIDGE_ISR_ERRORS;
-
-
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_int_mode = 0;		/* do not send "clear interrupt" packets */
-
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    /*
-     * Depending on the rev of bridge, disable certain features.
-     * Easiest way seems to be to force the PCIBR_NOwhatever
-     * flag to be on for all DMA calls, which overrides any
-     * PCIBR_whatever flag or even the setting of whatever
-     * from the PCIIO_DMA_class flags (or even from the other
-     * PCIBR flags, since NO overrides YES).
-     */
-    pcibr_soft->bs_dma_flags = 0;
-
-    /* PREFETCH:
-     * Always completely disabled for REV.A;
-     * at "pcibr_prefetch_enable_rev", anyone
-     * asking for PCIIO_PREFETCH gets it.
-     * Between these two points, you have to ask
-     * for PCIBR_PREFETCH, which promises that
-     * your driver knows about known Bridge WARs.
-     */
-    if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B)
-	pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH;
-    else if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev))
-	pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH;
-
-    /* WRITE_GATHER:
-     * Disabled up to but not including the
-     * rev number in pcibr_wg_enable_rev. There
-     * is no "WAR range" as with prefetch.
-     */
-    if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev))
-	pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER;
-
-    pciio_provider_register(pcibr_vhdl, &pcibr_provider);
-    pciio_provider_startup(pcibr_vhdl);
-
-    pci_io_fb = 0x00000004;		/* I/O FreeBlock Base */
-    pci_io_fl = 0xFFFFFFFF;		/* I/O FreeBlock Last */
-
-    pci_lo_fb = 0x00000010;		/* Low Memory FreeBlock Base */
-    pci_lo_fl = 0x001FFFFF;		/* Low Memory FreeBlock Last */
-
-    pci_hi_fb = 0x00200000;		/* High Memory FreeBlock Base */
-    pci_hi_fl = 0x3FFFFFFF;		/* High Memory FreeBlock Last */
-
-
-    PCI_ADDR_SPACE_LIMITS_STORE();
-
-    /* build "no-slot" connection point
-     */
-    pcibr_info = pcibr_device_info_new
-	(pcibr_soft, PCIIO_SLOT_NONE, PCIIO_FUNC_NONE,
-	 PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
-    noslot_conn = pciio_device_info_register
-	(pcibr_vhdl, &pcibr_info->f_c);
-
-    /* Remember the no slot connection point info for tearing it
-     * down during detach.
-     */
-    pcibr_soft->bs_noslot_conn = noslot_conn;
-    pcibr_soft->bs_noslot_info = pcibr_info;
-#if PCI_FBBE
-    fast_back_to_back_enable = 1;
-#endif
-
-#if PCI_FBBE
-    if (fast_back_to_back_enable) {
-	/*
-	 * All devices on the bus are capable of fast back to back, so
-	 * we need to set the fast back to back bit in all devices on
-	 * the bus that are capable of doing such accesses.
-	 */
-    }
-#endif
-
-#ifdef LATER
-    /* If the bridge has been reset then there is no need to reset
-     * the individual PCI slots.
-     */
-    for (slot = 0; slot < 8; ++slot)  
-	/* Reset all the slots */
-	(void)pcibr_slot_reset(pcibr_vhdl, slot);
-#endif
-
-    for (slot = 0; slot < 8; ++slot)
-	/* Find out what is out there */
-	(void)pcibr_slot_info_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Set up the address space for this slot in the pci land */
-	(void)pcibr_slot_addr_space_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Setup the device register */
-	(void)pcibr_slot_device_init(pcibr_vhdl, slot);
-
-#ifndef __ia64
-    for (slot = 0; slot < 8; ++slot)  
-	/* Set up convenience links */
-	if (is_xbridge(bridge))
-		if (pcibr_soft->bs_slot[slot].bss_ninfo > 0) /* if occupied */
-			pcibr_bus_cnvlink(pcibr_info->f_vertex, slot);
-#endif
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Setup host/guest relations */
-	(void)pcibr_slot_guest_info_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Initial RRB management */
-	(void)pcibr_slot_initial_rrb_alloc(pcibr_vhdl,slot);
-
-    /* driver attach routines should be called out from generic linux code */
-    for (slot = 0; slot < 8; ++slot)  
-	/* Call the device attach */
-	(void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0);
-
-    /*
-     * Each Pbrick PCI bus only has slots 1 and 2.   Similarly for
-     * widget 0xe on Ibricks.  Allocate RRB's accordingly.
-     */
-    if (pcibr_soft->bs_moduleid > 0) {
-	switch (MODULE_GET_BTCHAR(pcibr_soft->bs_moduleid)) {
-	case 'p':		/* Pbrick */
-		do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-		do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
-		break;
-	case 'i':		/* Ibrick */
-	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
-		if (pcibr_soft->bs_xid == 0xe) {
-			do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-			do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
-		}
-		else {
-		    	/* allocate one RRB for the serial port */
-			do_pcibr_rrb_autoalloc(pcibr_soft, 0, 1);
-		}
-		break;
-	} /* switch */
-    }
-
-#ifdef LATER
-    if (strstr(nicinfo, XTALK_PCI_PART_NUM)) {
-	do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-#if PCIBR_RRB_DEBUG
-	printf("\n\nFound XTALK_PCI (030-1275) at %v\n", xconn_vhdl);
-
-	printf("pcibr_attach: %v Shoebox RRB MANAGEMENT: %d+%d free\n",
-		pcibr_vhdl,
-		pcibr_soft->bs_rrb_avail[0],
-		pcibr_soft->bs_rrb_avail[1]);
-
-	for (slot = 0; slot < 8; ++slot)
-	    printf("\t%d+%d+%d",
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-
-	printf("\n");
-#endif
-    }
-#else
-	FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n");
-#endif
-
-    if (aa)
-	    async_attach_add_info(noslot_conn, aa);
-
-    pciio_device_attach(noslot_conn, 0);
-
-
-    /* 
-     * Tear down pointer to async attach info -- async threads for
-     * bridge's descendants may be running but the bridge's work is done.
-     */
-    if (aa)
-	    async_attach_del_info(xconn_vhdl);
-
-    return 0;
-}
-/*
- * pcibr_detach:
- *	Detach the bridge device from the hwgraph after cleaning out all the 
- *	underlying vertices.
- */
-int
-pcibr_detach(devfs_handle_t xconn)
-{
-    pciio_slot_t	slot;
-    devfs_handle_t	pcibr_vhdl;
-    pcibr_soft_t	pcibr_soft;
-    bridge_t		*bridge;
-
-    /* Get the bridge vertex from its xtalk connection point */
-    if (hwgraph_traverse(xconn, EDGE_LBL_PCI, &pcibr_vhdl) != GRAPH_SUCCESS)
-	return(1);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge = pcibr_soft->bs_base;
-
-    /* Disable the interrupts from the bridge */
-    bridge->b_int_enable = 0;
-
-    /* Detach all the PCI devices talking to this bridge */
-    for(slot = 0; slot < 8; slot++) {
-#ifdef DEBUG
-	printk("pcibr_device_detach called for %p/%d\n",
-		pcibr_vhdl,slot);
-#endif
-	pcibr_slot_detach(pcibr_vhdl, slot, 0);
-    }
-
-    /* Unregister the no-slot connection point */
-    pciio_device_info_unregister(pcibr_vhdl,
-				 &(pcibr_soft->bs_noslot_info->f_c));
-
-    spin_lock_destroy(&pcibr_soft->bs_lock);
-    kfree(pcibr_soft->bs_name);
-    
-    /* Error handler gets unregistered when the widget info is 
-     * cleaned 
-     */
-    /* Free the soft ATE maps */
-    if (pcibr_soft->bs_int_ate_map)
-	rmfreemap(pcibr_soft->bs_int_ate_map);
-    if (pcibr_soft->bs_ext_ate_map)
-	rmfreemap(pcibr_soft->bs_ext_ate_map);
-
-    /* Disconnect the error interrupt and free the xtalk resources 
-     * associated with it.
-     */
-    xtalk_intr_disconnect(pcibr_soft->bsi_err_intr);
-    xtalk_intr_free(pcibr_soft->bsi_err_intr);
-
-    /* Clear the software state maintained by the bridge driver for this
-     * bridge.
-     */
-    DEL(pcibr_soft);
-    /* Remove the Bridge revision labelled info */
-    (void)hwgraph_info_remove_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, NULL);
-    /* Remove the character device associated with this bridge */
-    (void)hwgraph_edge_remove(pcibr_vhdl, EDGE_LBL_CONTROLLER, NULL);
-    /* Remove the PCI bridge vertex */
-    (void)hwgraph_edge_remove(xconn, EDGE_LBL_PCI, NULL);
-
-    return(0);
-}
-
-int
-pcibr_asic_rev(devfs_handle_t pconn_vhdl)
-{
-    devfs_handle_t            pcibr_vhdl;
-    arbitrary_info_t        ainfo;
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_traverse(pconn_vhdl, EDGE_LBL_MASTER, &pcibr_vhdl))
-	return -1;
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &ainfo))
-	return -1;
-
-    return (int) ainfo;
-}
-
-int
-pcibr_write_gather_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t  pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    pciio_slot_t  slot;
-    slot = pciio_info_slot_get(pciio_info);
-    pcibr_device_write_gather_flush(pcibr_soft, slot);
-    return 0;
-}
-
-/* =====================================================================
- *    PIO MANAGEMENT
- */
-
-LOCAL iopaddr_t
-pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl,
-		      pciio_slot_t slot,
-		      pciio_space_t space,
-		      iopaddr_t pci_addr,
-		      size_t req_size,
-		      unsigned flags)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    unsigned                bar;	/* which BASE reg on device is decoding */
-    iopaddr_t               xio_addr = XIO_NOWHERE;
-
-    pciio_space_t           wspace;	/* which space device is decoding */
-    iopaddr_t               wbase;	/* base of device decode on PCI */
-    size_t                  wsize;	/* size of device decode on PCI */
-
-    int                     try;	/* DevIO(x) window scanning order control */
-    int                     win;	/* which DevIO(x) window is being used */
-    pciio_space_t           mspace;	/* target space for devio(x) register */
-    iopaddr_t               mbase;	/* base of devio(x) mapped area on PCI */
-    size_t                  msize;	/* size of devio(x) mapped area on PCI */
-    size_t                  mmask;	/* addr bits stored in Device(x) */
-
-    unsigned long           s;
-
-    s = pcibr_lock(pcibr_soft);
-
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	slot = pcibr_soft->bs_slot[slot].host_slot;
-	pcibr_info = pcibr_soft->bs_slot[slot].bss_infos[0];
-    }
-    if (space == PCIIO_SPACE_NONE)
-	goto done;
-
-    if (space == PCIIO_SPACE_CFG) {
-	/*
-	 * Usually, the first mapping
-	 * established to a PCI device
-	 * is to its config space.
-	 *
-	 * In any case, we definitely
-	 * do NOT need to worry about
-	 * PCI BASE registers, and
-	 * MUST NOT attempt to point
-	 * the DevIO(x) window at
-	 * this access ...
-	 */
-	if (((flags & PCIIO_BYTE_STREAM) == 0) &&
-	    ((pci_addr + req_size) <= BRIDGE_TYPE0_CFG_FUNC_OFF))
-	    xio_addr = pci_addr + BRIDGE_TYPE0_CFG_DEV(slot);
-
-	goto done;
-    }
-    if (space == PCIIO_SPACE_ROM) {
-	/* PIO to the Expansion Rom.
-	 * Driver is responsible for
-	 * enabling and disabling
-	 * decodes properly.
-	 */
-	wbase = pcibr_info->f_rbase;
-	wsize = pcibr_info->f_rsize;
-
-	/*
-	 * While the driver should know better
-	 * than to attempt to map more space
-	 * than the device is decoding, he might
-	 * do it; better to bail out here.
-	 */
-	if ((pci_addr + req_size) > wsize)
-	    goto done;
-
-	pci_addr += wbase;
-	space = PCIIO_SPACE_MEM;
-    }
-    /*
-     * reduce window mappings to raw
-     * space mappings (maybe allocating
-     * windows), and try for DevIO(x)
-     * usage (setting it if it is available).
-     */
-    bar = space - PCIIO_SPACE_WIN0;
-    if (bar < 6) {
-	wspace = pcibr_info->f_window[bar].w_space;
-	if (wspace == PCIIO_SPACE_NONE)
-	    goto done;
-
-	/* get PCI base and size */
-	wbase = pcibr_info->f_window[bar].w_base;
-	wsize = pcibr_info->f_window[bar].w_size;
-
-	/*
-	 * While the driver should know better
-	 * than to attempt to map more space
-	 * than the device is decoding, he might
-	 * do it; better to bail out here.
-	 */
-	if ((pci_addr + req_size) > wsize)
-	    goto done;
-
-	/* shift from window relative to
-	 * decoded space relative.
-	 */
-	pci_addr += wbase;
-	space = wspace;
-    } else
-	bar = -1;
-
-    /* Scan all the DevIO(x) windows twice looking for one
-     * that can satisfy our request. The first time through,
-     * only look at assigned windows; the second time, also
-     * look at PCIIO_SPACE_NONE windows. Arrange the order
-     * so we always look at our own window first.
-     *
-     * We will not attempt to satisfy a single request
-     * by concatinating multiple windows.
-     */
-    for (try = 0; try < 16; ++try) {
-	bridgereg_t             devreg;
-	unsigned                offset;
-
-	win = (try + slot) % 8;
-
-	/* If this DevIO(x) mapping area can provide
-	 * a mapping to this address, use it.
-	 */
-	msize = (win < 2) ? 0x200000 : 0x100000;
-	mmask = -msize;
-	if (space != PCIIO_SPACE_IO)
-	    mmask &= 0x3FFFFFFF;
-
-	offset = pci_addr & (msize - 1);
-
-	/* If this window can't possibly handle that request,
-	 * go on to the next window.
-	 */
-	if (((pci_addr & (msize - 1)) + req_size) > msize)
-	    continue;
-
-	devreg = pcibr_soft->bs_slot[win].bss_device;
-
-	/* Is this window "nailed down"?
-	 * If not, maybe we can use it.
-	 * (only check this the second time through)
-	 */
-	mspace = pcibr_soft->bs_slot[win].bss_devio.bssd_space;
-	if ((try > 7) && (mspace == PCIIO_SPACE_NONE)) {
-
-	    /* If this is the primary DevIO(x) window
-	     * for some other device, skip it.
-	     */
-	    if ((win != slot) &&
-		(PCIIO_VENDOR_ID_NONE !=
-		 pcibr_soft->bs_slot[win].bss_vendor_id))
-		continue;
-
-	    /* It's a free window, and we fit in it.
-	     * Set up Device(win) to our taste.
-	     */
-	    mbase = pci_addr & mmask;
-
-	    /* check that we would really get from
-	     * here to there.
-	     */
-	    if ((mbase | offset) != pci_addr)
-		continue;
-
-	    devreg &= ~BRIDGE_DEV_OFF_MASK;
-	    if (space != PCIIO_SPACE_IO)
-		devreg |= BRIDGE_DEV_DEV_IO_MEM;
-	    else
-		devreg &= ~BRIDGE_DEV_DEV_IO_MEM;
-	    devreg |= (mbase >> 20) & BRIDGE_DEV_OFF_MASK;
-
-	    /* default is WORD_VALUES.
-	     * if you specify both,
-	     * operation is undefined.
-	     */
-	    if (flags & PCIIO_BYTE_STREAM)
-		devreg |= BRIDGE_DEV_DEV_SWAP;
-	    else
-		devreg &= ~BRIDGE_DEV_DEV_SWAP;
-
-	    if (pcibr_soft->bs_slot[win].bss_device != devreg) {
-		bridge->b_device[win].reg = devreg;
-		pcibr_soft->bs_slot[win].bss_device = devreg;
-		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-
-#if DEBUG && PCI_DEBUG
-		printk("pcibr Device(%d): 0x%lx\n", win, bridge->b_device[win].reg);
-#endif
-	    }
-	    pcibr_soft->bs_slot[win].bss_devio.bssd_space = space;
-	    pcibr_soft->bs_slot[win].bss_devio.bssd_base = mbase;
-	    xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
-
-#if DEBUG && PCI_DEBUG
-	    printk("%s LINE %d map to space %d space desc 0x%x[%lx..%lx] for slot %d allocates DevIO(%d) devreg 0x%x\n", 
-		    __FUNCTION__, __LINE__, space, space_desc,
-		    pci_addr, pci_addr + req_size - 1,
-		    slot, win, devreg);
-#endif
-
-	    goto done;
-	}				/* endif DevIO(x) not pointed */
-	mbase = pcibr_soft->bs_slot[win].bss_devio.bssd_base;
-
-	/* Now check for request incompat with DevIO(x)
-	 */
-	if ((mspace != space) ||
-	    (pci_addr < mbase) ||
-	    ((pci_addr + req_size) > (mbase + msize)) ||
-	    ((flags & PCIIO_BYTE_STREAM) && !(devreg & BRIDGE_DEV_DEV_SWAP)) ||
-	    (!(flags & PCIIO_BYTE_STREAM) && (devreg & BRIDGE_DEV_DEV_SWAP)))
-	    continue;
-
-	/* DevIO(x) window is pointed at PCI space
-	 * that includes our target. Calculate the
-	 * final XIO address, release the lock and
-	 * return.
-	 */
-	xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
-
-#if DEBUG && PCI_DEBUG
-	printk("%s LINE %d map to space %d [0x%p..0x%p] for slot %d uses DevIO(%d)\n",
-		__FUNCTION__, __LINE__, space,  pci_addr, pci_addr + req_size - 1, slot, win);
-#endif
-	goto done;
-    }
-
-    switch (space) {
-	/*
-	 * Accesses to device decode
-	 * areas that do a not fit
-	 * within the DevIO(x) space are
-	 * modified to be accesses via
-	 * the direct mapping areas.
-	 *
-	 * If necessary, drivers can
-	 * explicitly ask for mappings
-	 * into these address spaces,
-	 * but this should never be needed.
-	 */
-    case PCIIO_SPACE_MEM:		/* "mem space" */
-    case PCIIO_SPACE_MEM32:		/* "mem, use 32-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM32_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE;
-	break;
-
-    case PCIIO_SPACE_MEM64:		/* "mem, use 64-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM64_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE;
-	break;
-
-    case PCIIO_SPACE_IO:		/* "i/o space" */
-	/* Bridge Hardware Bug WAR #482741:
-	 * The 4G area that maps directly from
-	 * XIO space to PCI I/O space is busted
-	 * until Bridge Rev D.
-	 */
-	if ((pcibr_soft->bs_rev_num > BRIDGE_PART_REV_C) &&
-	    ((pci_addr + BRIDGE_PCI_IO_BASE + req_size - 1) <=
-	     BRIDGE_PCI_IO_LIMIT))
-	    xio_addr = pci_addr + BRIDGE_PCI_IO_BASE;
-	break;
-    }
-
-    /* Check that "Direct PIO" byteswapping matches,
-     * try to change it if it does not.
-     */
-    if (xio_addr != XIO_NOWHERE) {
-	unsigned                bst;	/* nonzero to set bytestream */
-	unsigned               *bfp;	/* addr of record of how swapper is set */
-	unsigned                swb;	/* which control bit to mung */
-	unsigned                bfo;	/* current swapper setting */
-	unsigned                bfn;	/* desired swapper setting */
-
-	bfp = ((space == PCIIO_SPACE_IO)
-	       ? (&pcibr_soft->bs_pio_end_io)
-	       : (&pcibr_soft->bs_pio_end_mem));
-
-	bfo = *bfp;
-
-	bst = flags & PCIIO_BYTE_STREAM;
-
-	bfn = bst ? PCIIO_BYTE_STREAM : PCIIO_WORD_VALUES;
-
-	if (bfn == bfo) {		/* we already match. */
-	    ;
-	} else if (bfo != 0) {		/* we have a conflict. */
-#if DEBUG && PCI_DEBUG
-	    printk("pcibr_addr_pci_to_xio: swap conflict in space %d , was%s%s, want%s%s\n",
-		    space, 
-		    bfo & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfo & PCIIO_WORD_VALUES ? " WORD_VALUES" : "",
-		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
-#endif
-	    xio_addr = XIO_NOWHERE;
-	} else {			/* OK to make the change. */
-	    bridgereg_t             octl, nctl;
-
-	    swb = (space == PCIIO_SPACE_IO) ? BRIDGE_CTRL_IO_SWAP : BRIDGE_CTRL_MEM_SWAP;
-	    octl = bridge->b_wid_control;
-	    nctl = bst ? octl | swb : octl & ~swb;
-
-	    if (octl != nctl)		/* make the change if any */
-		bridge->b_wid_control = nctl;
-
-	    *bfp = bfn;			/* record the assignment */
-
-#if DEBUG && PCI_DEBUG
-	    printk("pcibr_addr_pci_to_xio: swap for space %d  set to%s%s\n",
-		    space, 
-		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
-#endif
-	}
-    }
-  done:
-    pcibr_unlock(pcibr_soft, s);
-    return xio_addr;
-}
-
-/*ARGSUSED6 */
-pcibr_piomap_t
-pcibr_piomap_alloc(devfs_handle_t pconn_vhdl,
-		   device_desc_t dev_desc,
-		   pciio_space_t space,
-		   iopaddr_t pci_addr,
-		   size_t req_size,
-		   size_t req_size_max,
-		   unsigned flags)
-{
-    pcibr_info_t	    pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    pcibr_piomap_t         *mapptr;
-    pcibr_piomap_t          maplist;
-    pcibr_piomap_t          pcibr_piomap;
-    iopaddr_t               xio_addr;
-    xtalk_piomap_t          xtalk_piomap;
-    unsigned long           s;
-
-    /* Make sure that the req sizes are non-zero */
-    if ((req_size < 1) || (req_size_max < 1))
-	return NULL;
-
-    /*
-     * Code to translate slot/space/addr
-     * into xio_addr is common between
-     * this routine and pcibr_piotrans_addr.
-     */
-    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
-
-    if (xio_addr == XIO_NOWHERE)
-	return NULL;
-
-    /* Check the piomap list to see if there is already an allocated
-     * piomap entry but not in use. If so use that one. Otherwise
-     * allocate a new piomap entry and add it to the piomap list
-     */
-    mapptr = &(pcibr_info->f_piomap);
-
-    s = pcibr_lock(pcibr_soft);
-    for (pcibr_piomap = *mapptr;
-	 pcibr_piomap != NULL;
-	 pcibr_piomap = pcibr_piomap->bp_next) {
-	if (pcibr_piomap->bp_mapsz == 0)
-	    break;
-    }
-
-    if (pcibr_piomap)
-	mapptr = NULL;
-    else {
-	pcibr_unlock(pcibr_soft, s);
-	NEW(pcibr_piomap);
-    }
-
-    pcibr_piomap->bp_dev = pconn_vhdl;
-    pcibr_piomap->bp_slot = pciio_slot;
-    pcibr_piomap->bp_flags = flags;
-    pcibr_piomap->bp_space = space;
-    pcibr_piomap->bp_pciaddr = pci_addr;
-    pcibr_piomap->bp_mapsz = req_size;
-    pcibr_piomap->bp_soft = pcibr_soft;
-    pcibr_piomap->bp_toc[0] = ATOMIC_INIT(0);
-
-    if (mapptr) {
-	s = pcibr_lock(pcibr_soft);
-	maplist = *mapptr;
-	pcibr_piomap->bp_next = maplist;
-	*mapptr = pcibr_piomap;
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-
-    if (pcibr_piomap) {
-	xtalk_piomap =
-	    xtalk_piomap_alloc(xconn_vhdl, 0,
-			       xio_addr,
-			       req_size, req_size_max,
-			       flags & PIOMAP_FLAGS);
-	if (xtalk_piomap) {
-	    pcibr_piomap->bp_xtalk_addr = xio_addr;
-	    pcibr_piomap->bp_xtalk_pio = xtalk_piomap;
-	} else {
-	    pcibr_piomap->bp_mapsz = 0;
-	    pcibr_piomap = 0;
-	}
-    }
-    return pcibr_piomap;
-}
-
-/*ARGSUSED */
-void
-pcibr_piomap_free(pcibr_piomap_t pcibr_piomap)
-{
-    xtalk_piomap_free(pcibr_piomap->bp_xtalk_pio);
-    pcibr_piomap->bp_xtalk_pio = 0;
-    pcibr_piomap->bp_mapsz = 0;
-}
-
-/*ARGSUSED */
-caddr_t
-pcibr_piomap_addr(pcibr_piomap_t pcibr_piomap,
-		  iopaddr_t pci_addr,
-		  size_t req_size)
-{
-    return xtalk_piomap_addr(pcibr_piomap->bp_xtalk_pio,
-			     pcibr_piomap->bp_xtalk_addr +
-			     pci_addr - pcibr_piomap->bp_pciaddr,
-			     req_size);
-}
-
-/*ARGSUSED */
-void
-pcibr_piomap_done(pcibr_piomap_t pcibr_piomap)
-{
-    xtalk_piomap_done(pcibr_piomap->bp_xtalk_pio);
-}
-
-/*ARGSUSED */
-caddr_t
-pcibr_piotrans_addr(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    pciio_space_t space,
-		    iopaddr_t pci_addr,
-		    size_t req_size,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    iopaddr_t               xio_addr;
-
-    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
-
-    if (xio_addr == XIO_NOWHERE)
-	return NULL;
-
-    return xtalk_piotrans_addr(xconn_vhdl, 0, xio_addr, req_size, flags & PIOMAP_FLAGS);
-}
-
-/*
- * PIO Space allocation and management.
- *      Allocate and Manage the PCI PIO space (mem and io space)
- *      This routine is pretty simplistic at this time, and
- *      does pretty trivial management of allocation and freeing..
- *      The current scheme is prone for fragmentation..
- *      Change the scheme to use bitmaps.
- */
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_piospace_alloc(devfs_handle_t pconn_vhdl,
-		     device_desc_t dev_desc,
-		     pciio_space_t space,
-		     size_t req_size,
-		     size_t alignment)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    pciio_piospace_t        piosp;
-    unsigned long           s;
-
-    iopaddr_t              *pciaddr, *pcilast;
-    iopaddr_t               start_addr;
-    size_t                  align_mask;
-
-    /*
-     * Check for proper alignment
-     */
-    ASSERT(alignment >= NBPP);
-    ASSERT((alignment & (alignment - 1)) == 0);
-
-    align_mask = alignment - 1;
-    s = pcibr_lock(pcibr_soft);
-
-    /*
-     * First look if a previously allocated chunk exists.
-     */
-    if ((piosp = pcibr_info->f_piospace)) {
-	/*
-	 * Look through the list for a right sized free chunk.
-	 */
-	do {
-	    if (piosp->free &&
-		(piosp->space == space) &&
-		(piosp->count >= req_size) &&
-		!(piosp->start & align_mask)) {
-		piosp->free = 0;
-		pcibr_unlock(pcibr_soft, s);
-		return piosp->start;
-	    }
-	    piosp = piosp->next;
-	} while (piosp);
-    }
-    ASSERT(!piosp);
-
-    switch (space) {
-    case PCIIO_SPACE_IO:
-	pciaddr = &pcibr_soft->bs_spinfo.pci_io_base;
-	pcilast = &pcibr_soft->bs_spinfo.pci_io_last;
-	break;
-    case PCIIO_SPACE_MEM:
-    case PCIIO_SPACE_MEM32:
-	pciaddr = &pcibr_soft->bs_spinfo.pci_mem_base;
-	pcilast = &pcibr_soft->bs_spinfo.pci_mem_last;
-	break;
-    default:
-	ASSERT(0);
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-
-    start_addr = *pciaddr;
-
-    /*
-     * Align start_addr.
-     */
-    if (start_addr & align_mask)
-	start_addr = (start_addr + align_mask) & ~align_mask;
-
-    if ((start_addr + req_size) > *pcilast) {
-	/*
-	 * If too big a request, reject it.
-	 */
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-    *pciaddr = (start_addr + req_size);
-
-    NEW(piosp);
-    piosp->free = 0;
-    piosp->space = space;
-    piosp->start = start_addr;
-    piosp->count = req_size;
-    piosp->next = pcibr_info->f_piospace;
-    pcibr_info->f_piospace = piosp;
-
-    pcibr_unlock(pcibr_soft, s);
-    return start_addr;
-}
-
-/*ARGSUSED */
-void
-pcibr_piospace_free(devfs_handle_t pconn_vhdl,
-		    pciio_space_t space,
-		    iopaddr_t pciaddr,
-		    size_t req_size)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-
-    pciio_piospace_t        piosp;
-    unsigned long           s;
-    char                    name[1024];
-
-    /*
-     * Look through the bridge data structures for the pciio_piospace_t
-     * structure corresponding to  'pciaddr'
-     */
-    s = pcibr_lock(pcibr_soft);
-    piosp = pcibr_info->f_piospace;
-    while (piosp) {
-	/*
-	 * Piospace free can only be for the complete
-	 * chunk and not parts of it..
-	 */
-	if (piosp->start == pciaddr) {
-	    if (piosp->count == req_size)
-		break;
-	    /*
-	     * Improper size passed for freeing..
-	     * Print a message and break;
-	     */
-	    hwgraph_vertex_name_get(pconn_vhdl, name, 1024);
-	    printk(KERN_WARNING  "pcibr_piospace_free: error");
-	    printk(KERN_WARNING  "Device %s freeing size (0x%lx) different than allocated (0x%lx)",
-					name, req_size, piosp->count);
-	    printk(KERN_WARNING  "Freeing 0x%lx instead", piosp->count);
-	    break;
-	}
-	piosp = piosp->next;
-    }
-
-    if (!piosp) {
-	printk(KERN_WARNING  
-		"pcibr_piospace_free: Address 0x%lx size 0x%lx - No match\n",
-		pciaddr, req_size);
-	pcibr_unlock(pcibr_soft, s);
-	return;
-    }
-    piosp->free = 1;
-    pcibr_unlock(pcibr_soft, s);
-    return;
-}
-
-/* =====================================================================
- *    DMA MANAGEMENT
- *
- *      The Bridge ASIC provides three methods of doing
- *      DMA: via a "direct map" register available in
- *      32-bit PCI space (which selects a contiguous 2G
- *      address space on some other widget), via
- *      "direct" addressing via 64-bit PCI space (all
- *      destination information comes from the PCI
- *      address, including transfer attributes), and via
- *      a "mapped" region that allows a bunch of
- *      different small mappings to be established with
- *      the PMU.
- *
- *      For efficiency, we most prefer to use the 32-bit
- *      direct mapping facility, since it requires no
- *      resource allocations. The advantage of using the
- *      PMU over the 64-bit direct is that single-cycle
- *      PCI addressing can be used; the advantage of
- *      using 64-bit direct over PMU addressing is that
- *      we do not have to allocate entries in the PMU.
- */
-
-/*
- * Convert PCI-generic software flags and Bridge-specific software flags
- * into Bridge-specific Direct Map attribute bits.
- */
-LOCAL iopaddr_t
-pcibr_flags_to_d64(unsigned flags, pcibr_soft_t pcibr_soft)
-{
-    iopaddr_t               attributes = 0;
-
-    /* Sanity check: Bridge only allows use of VCHAN1 via 64-bit addrs */
-#ifdef LATER
-    ASSERT_ALWAYS(!(flags & PCIBR_VCHAN1) || (flags & PCIIO_DMA_A64));
-#endif
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
-	attributes &= ~PCI64_ATTR_BAR;	/* no barrier bit */
-	attributes |= PCI64_ATTR_PREF;	/* prefetch on */
-    }
-    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
-	attributes |= PCI64_ATTR_BAR;	/* barrier bit on */
-	attributes &= ~PCI64_ATTR_PREF;	/* disable prefetch */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_PREFETCH)
-	attributes |= PCI64_ATTR_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	attributes &= ~PCI64_ATTR_PREF;
-
-    /* the swap bit is in the address attributes for xbridge */
-    if (pcibr_soft->bs_xbridge) {
-    	if (flags & PCIIO_BYTE_STREAM)
-        	attributes |= PCI64_ATTR_SWAP;
-    	if (flags & PCIIO_WORD_VALUES)
-        	attributes &= ~PCI64_ATTR_SWAP;
-    }
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_BARRIER)
-	attributes |= PCI64_ATTR_BAR;
-    if (flags & PCIBR_NOBARRIER)
-	attributes &= ~PCI64_ATTR_BAR;
-
-    if (flags & PCIBR_PREFETCH)
-	attributes |= PCI64_ATTR_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	attributes &= ~PCI64_ATTR_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	attributes |= PCI64_ATTR_PREC;
-    if (flags & PCIBR_NOPRECISE)
-	attributes &= ~PCI64_ATTR_PREC;
-
-    if (flags & PCIBR_VCHAN1)
-	attributes |= PCI64_ATTR_VIRTUAL;
-    if (flags & PCIBR_VCHAN0)
-	attributes &= ~PCI64_ATTR_VIRTUAL;
-
-    return (attributes);
-}
-
-/*
- * Convert PCI-generic software flags and Bridge-specific software flags
- * into Bridge-specific Address Translation Entry attribute bits.
- */
-LOCAL bridge_ate_t
-pcibr_flags_to_ate(unsigned flags)
-{
-    bridge_ate_t            attributes;
-
-    /* default if nothing specified:
-     * NOBARRIER
-     * NOPREFETCH
-     * NOPRECISE
-     * COHERENT
-     * Plus the valid bit
-     */
-    attributes = ATE_CO | ATE_V;
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
-	attributes &= ~ATE_BAR;		/* no barrier */
-	attributes |= ATE_PREF;		/* prefetch on */
-    }
-    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
-	attributes |= ATE_BAR;		/* barrier bit on */
-	attributes &= ~ATE_PREF;	/* disable prefetch */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_PREFETCH)
-	attributes |= ATE_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	attributes &= ~ATE_PREF;
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_BARRIER)
-	attributes |= ATE_BAR;
-    if (flags & PCIBR_NOBARRIER)
-	attributes &= ~ATE_BAR;
-
-    if (flags & PCIBR_PREFETCH)
-	attributes |= ATE_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	attributes &= ~ATE_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	attributes |= ATE_PREC;
-    if (flags & PCIBR_NOPRECISE)
-	attributes &= ~ATE_PREC;
-
-    return (attributes);
-}
-
-/*ARGSUSED */
-pcibr_dmamap_t
-pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl,
-		   device_desc_t dev_desc,
-		   size_t req_size_max,
-		   unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            slot;
-    xwidgetnum_t            xio_port;
-
-    xtalk_dmamap_t          xtalk_dmamap;
-    pcibr_dmamap_t          pcibr_dmamap;
-    int                     ate_count;
-    int                     ate_index;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-#ifdef IRIX
-    NEWf(pcibr_dmamap, flags);
-#else
-    /*
-     * On SNIA64, these maps are pre-allocated because pcibr_dmamap_alloc()
-     * can be called within an interrupt thread.
-     */
-    pcibr_dmamap = (pcibr_dmamap_t)get_free_pciio_dmamap(pcibr_soft->bs_vhdl);
-#endif
-
-    if (!pcibr_dmamap)
-	return 0;
-
-    xtalk_dmamap = xtalk_dmamap_alloc(xconn_vhdl, dev_desc, req_size_max,
-				      flags & DMAMAP_FLAGS);
-    if (!xtalk_dmamap) {
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_attach: xtalk_dmamap_alloc failed\n");
-#endif
-#ifdef IRIX
-	DEL(pcibr_dmamap);
-#else
-	free_pciio_dmamap(pcibr_dmamap);
-#endif
-	return 0;
-    }
-    xio_port = pcibr_soft->bs_mxid;
-    slot = pciio_info_slot_get(pciio_info);
-
-    pcibr_dmamap->bd_dev = pconn_vhdl;
-    pcibr_dmamap->bd_slot = slot;
-    pcibr_dmamap->bd_soft = pcibr_soft;
-    pcibr_dmamap->bd_xtalk = xtalk_dmamap;
-    pcibr_dmamap->bd_max_size = req_size_max;
-    pcibr_dmamap->bd_xio_port = xio_port;
-
-    if (flags & PCIIO_DMA_A64) {
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D64_BITS)) {
-	    iopaddr_t               pci_addr;
-	    int                     have_rrbs;
-	    int                     min_rrbs;
-
-	    /* Device is capable of A64 operations,
-	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
-	     * mappings using shared resources.
-	     */
-
-	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
-
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_xio_addr = 0;
-	    pcibr_dmamap->bd_pci_addr = pci_addr;
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
-		if (flags & PCIBR_VCHAN1)
-		    slot += PCIBR_RRB_SLOT_VIRTUAL;
-		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
-		if (have_rrbs < 2) {
-		    if (pci_addr & PCI64_ATTR_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
-		}
-	    }
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using direct64\n");
-#endif
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use direct64\n");
-#endif
-	flags &= ~PCIIO_DMA_A64;
-    }
-    if (flags & PCIIO_FIXED) {
-	/* warning: mappings may fail later,
-	 * if direct32 can't get to the address.
-	 */
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) {
-	    /* User desires DIRECT A32 operations,
-	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
-	     * mappings using shared resources.
-	     * Mapping calls may fail if target
-	     * is outside the direct32 range.
-	     */
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using direct32\n");
-#endif
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_xio_addr = pcibr_soft->bs_dir_xbase;
-	    pcibr_dmamap->bd_pci_addr = PCI32_DIRECT_BASE;
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use direct32\n");
-#endif
-	/* If the user demands FIXED and we can't
-	 * give it to him, fail.
-	 */
-	xtalk_dmamap_free(xtalk_dmamap);
-#ifdef IRIX
-	DEL(pcibr_dmamap);
-#else
-	free_pciio_dmamap(pcibr_dmamap);
-#endif
-	return 0;
-    }
-    /*
-     * Allocate Address Translation Entries from the mapping RAM.
-     * Unless the PCIBR_NO_ATE_ROUNDUP flag is specified,
-     * the maximum number of ATEs is based on the worst-case
-     * scenario, where the requested target is in the
-     * last byte of an ATE; thus, mapping IOPGSIZE+2
-     * does end up requiring three ATEs.
-     */
-    if (!(flags & PCIBR_NO_ATE_ROUNDUP)) {
-	ate_count = IOPG((IOPGSIZE - 1)	/* worst case start offset */
-		     +req_size_max	/* max mapping bytes */
-		     - 1) + 1;		/* round UP */
-    } else {	/* assume requested target is page aligned */
-	ate_count = IOPG(req_size_max   /* max mapping bytes */
-		     - 1) + 1;		/* round UP */
-    }
-
-    ate_index = pcibr_ate_alloc(pcibr_soft, ate_count);
-
-    if (ate_index != -1) {
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_PMU_BITS)) {
-	    bridge_ate_t            ate_proto;
-	    int                     have_rrbs;
-	    int                     min_rrbs;
-
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using PMU\n");
-#endif
-
-	    ate_proto = pcibr_flags_to_ate(flags);
-
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_pci_addr =
-		PCI32_MAPPED_BASE + IOPGSIZE * ate_index;
-	    /*
-	     * for xbridge the byte-swap bit == bit 29 of PCI address
-	     */
-	    if (pcibr_soft->bs_xbridge) {
-		    if (flags & PCIIO_BYTE_STREAM)
-			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
-		    /*
-		     * If swap was set in bss_device in pcibr_endian_set()
-		     * we need to change the address bit.
-		     */
-		    if (pcibr_soft->bs_slot[slot].bss_device & 
-							BRIDGE_DEV_SWAP_PMU)
-			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
-		    if (flags & PCIIO_WORD_VALUES)
-			    ATE_SWAP_OFF(pcibr_dmamap->bd_pci_addr);
-	    }
-	    pcibr_dmamap->bd_xio_addr = 0;
-	    pcibr_dmamap->bd_ate_ptr = pcibr_ate_addr(pcibr_soft, ate_index);
-	    pcibr_dmamap->bd_ate_index = ate_index;
-	    pcibr_dmamap->bd_ate_count = ate_count;
-	    pcibr_dmamap->bd_ate_proto = ate_proto;
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
-		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
-		if (have_rrbs < 2) {
-		    if (ate_proto & ATE_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
-		}
-	    }
-	    if (ate_index >= pcibr_soft->bs_int_ate_size && 
-				!pcibr_soft->bs_xbridge) {
-		bridge_t               *bridge = pcibr_soft->bs_base;
-		volatile unsigned      *cmd_regp;
-		unsigned                cmd_reg;
-		unsigned long           s;
-
-		pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_SSRAM;
-
-		s = pcibr_lock(pcibr_soft);
-		cmd_regp = &(bridge->
-			     b_type0_cfg_dev[slot].
-			     l[PCI_CFG_COMMAND / 4]);
-		cmd_reg = *cmd_regp;
-		pcibr_soft->bs_slot[slot].bss_cmd_pointer = cmd_regp;
-		pcibr_soft->bs_slot[slot].bss_cmd_shadow = cmd_reg;
-		pcibr_unlock(pcibr_soft, s);
-	    }
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use PMU\n");
-#endif
-	pcibr_ate_free(pcibr_soft, ate_index, ate_count);
-    }
-    /* total failure: sorry, you just can't
-     * get from here to there that way.
-     */
-#if PCIBR_ATE_DEBUG
-    printk("pcibr_dmamap_alloc: complete failure.\n");
-#endif
-    xtalk_dmamap_free(xtalk_dmamap);
-#ifdef IRIX
-    DEL(pcibr_dmamap);
-#else
-    free_pciio_dmamap(pcibr_dmamap);
-#endif
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_dmamap_free(pcibr_dmamap_t pcibr_dmamap)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-    pciio_slot_t            slot = pcibr_dmamap->bd_slot;
-
-    unsigned                flags = pcibr_dmamap->bd_flags;
-
-    /* Make sure that bss_ext_ates_active
-     * is properly kept up to date.
-     */
-
-    if (PCIBR_DMAMAP_BUSY & flags)
-	if (PCIBR_DMAMAP_SSRAM & flags)
-	    atomic_dec(&(pcibr_soft->bs_slot[slot]. bss_ext_ates_active));
-
-    xtalk_dmamap_free(pcibr_dmamap->bd_xtalk);
-
-    if (pcibr_dmamap->bd_flags & PCIIO_DMA_A64) {
-	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_D64_BITS);
-    }
-    if (pcibr_dmamap->bd_ate_count) {
-	pcibr_ate_free(pcibr_dmamap->bd_soft,
-		       pcibr_dmamap->bd_ate_index,
-		       pcibr_dmamap->bd_ate_count);
-	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_PMU_BITS);
-    }
-#ifdef IRIX
-    DEL(pcibr_dmamap);
-#else
-    free_pciio_dmamap(pcibr_dmamap);
-#endif
-}
-
-/*
- * Setup an Address Translation Entry as specified.  Use either the Bridge
- * internal maps or the external map RAM, as appropriate.
- */
-LOCAL bridge_ate_p
-pcibr_ate_addr(pcibr_soft_t pcibr_soft,
-	       int ate_index)
-{
-    bridge_t *bridge = pcibr_soft->bs_base;
-
-    return (ate_index < pcibr_soft->bs_int_ate_size)
-	? &(bridge->b_int_ate_ram[ate_index].wr)
-	: &(bridge->b_ext_ate_ram[ate_index]);
-}
-
-/*
- *    pcibr_addr_xio_to_pci: given a PIO range, hand
- *      back the corresponding base PCI MEM address;
- *      this is used to short-circuit DMA requests that
- *      loop back onto this PCI bus.
- */
-LOCAL iopaddr_t
-pcibr_addr_xio_to_pci(pcibr_soft_t soft,
-		      iopaddr_t xio_addr,
-		      size_t req_size)
-{
-    iopaddr_t               xio_lim = xio_addr + req_size - 1;
-    iopaddr_t               pci_addr;
-    pciio_slot_t            slot;
-
-    if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) &&
-	(xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) {
-	pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE;
-	return pci_addr;
-    }
-    if ((xio_addr >= BRIDGE_PCI_MEM64_BASE) &&
-	(xio_lim <= BRIDGE_PCI_MEM64_LIMIT)) {
-	pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE;
-	return pci_addr;
-    }
-    for (slot = 0; slot < 8; ++slot)
-	if ((xio_addr >= BRIDGE_DEVIO(slot)) &&
-	    (xio_lim < BRIDGE_DEVIO(slot + 1))) {
-	    bridgereg_t             dev;
-
-	    dev = soft->bs_slot[slot].bss_device;
-	    pci_addr = dev & BRIDGE_DEV_OFF_MASK;
-	    pci_addr <<= BRIDGE_DEV_OFF_ADDR_SHFT;
-	    pci_addr += xio_addr - BRIDGE_DEVIO(slot);
-	    return (dev & BRIDGE_DEV_DEV_IO_MEM) ? pci_addr : PCI_NOWHERE;
-	}
-    return 0;
-}
-
-/* We are starting to get more complexity
- * surrounding writing ATEs, so pull
- * the writing code into this new function.
- */
-
-#if PCIBR_FREEZE_TIME
-#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, &freeze_time, cmd_regs)
-#else
-#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, cmd_regs)
-#endif
-
-LOCAL unsigned
-ate_freeze(pcibr_dmamap_t pcibr_dmamap,
-#if PCIBR_FREEZE_TIME
-	   unsigned *freeze_time_ptr,
-#endif
-	   unsigned *cmd_regs)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-#ifdef LATER
-    int                     dma_slot = pcibr_dmamap->bd_slot;
-#endif
-    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
-    int                     slot;
-
-    unsigned long           s;
-    unsigned                cmd_reg;
-    volatile unsigned      *cmd_lwa;
-    unsigned                cmd_lwd;
-
-    if (!ext_ates)
-	return 0;
-
-    /* Bridge Hardware Bug WAR #484930:
-     * Bridge can't handle updating External ATEs
-     * while DMA is occuring that uses External ATEs,
-     * even if the particular ATEs involved are disjoint.
-     */
-
-    /* need to prevent anyone else from
-     * unfreezing the grant while we
-     * are working; also need to prevent
-     * this thread from being interrupted
-     * to keep PCI grant freeze time
-     * at an absolute minimum.
-     */
-    s = pcibr_lock(pcibr_soft);
-
-#ifdef LATER
-    /* just in case pcibr_dmamap_done was not called */
-    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
-	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
-	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
-	    atomic_dec(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
-	xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
-    }
-#endif	/* LATER */
-#if PCIBR_FREEZE_TIME
-    *freeze_time_ptr = get_timestamp();
-#endif
-
-    cmd_lwa = 0;
-    for (slot = 0; slot < 8; ++slot)
-	if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
-	    cmd_reg = pcibr_soft->
-		bs_slot[slot].
-		bss_cmd_shadow;
-	    if (cmd_reg & PCI_CMD_BUS_MASTER) {
-		cmd_lwa = pcibr_soft->
-		    bs_slot[slot].
-		    bss_cmd_pointer;
-		cmd_lwd = cmd_reg ^ PCI_CMD_BUS_MASTER;
-		cmd_lwa[0] = cmd_lwd;
-	    }
-	    cmd_regs[slot] = cmd_reg;
-	} else
-	    cmd_regs[slot] = 0;
-
-    if (cmd_lwa) {
-	    bridge_t	*bridge = pcibr_soft->bs_base;
-
-	    /* Read the last master bit that has been cleared. This PIO read
-	     * on the PCI bus is to ensure the completion of any DMAs that
-	     * are due to bus requests issued by PCI devices before the
-	     * clearing of master bits.
-	     */
-	    cmd_lwa[0];
-
-	    /* Flush all the write buffers in the bridge */
-	    for (slot = 0; slot < 8; ++slot)
-		    if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
-			    /* Flush the write buffer associated with this
-			     * PCI device which might be using dma map RAM.
-			     */
-			    bridge->b_wr_req_buf[slot].reg;
-		    }
-    }
-    return s;
-}
-
-#define	ATE_WRITE()    ate_write(ate_ptr, ate_count, ate)
-
-LOCAL void
-ate_write(bridge_ate_p ate_ptr,
-	  int ate_count,
-	  bridge_ate_t ate)
-{
-    while (ate_count-- > 0) {
-	*ate_ptr++ = ate;
-	ate += IOPGSIZE;
-    }
-}
-
-
-#if PCIBR_FREEZE_TIME
-#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, ate, ate_total, freeze_time, cmd_regs, s)
-#else
-#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, cmd_regs, s)
-#endif
-
-LOCAL void
-ate_thaw(pcibr_dmamap_t pcibr_dmamap,
-	 int ate_index,
-#if PCIBR_FREEZE_TIME
-	 bridge_ate_t ate,
-	 int ate_total,
-	 unsigned freeze_time_start,
-#endif
-	 unsigned *cmd_regs,
-	 unsigned s)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-    int                     dma_slot = pcibr_dmamap->bd_slot;
-    int                     slot;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
-
-    unsigned                cmd_reg;
-
-#if PCIBR_FREEZE_TIME
-    unsigned                freeze_time;
-    static unsigned         max_freeze_time = 0;
-    static unsigned         max_ate_total;
-#endif
-
-    if (!ext_ates)
-	return;
-
-    /* restore cmd regs */
-    for (slot = 0; slot < 8; ++slot)
-	if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER)
-	    bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg;
-
-    pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY;
-    atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
-
-#if PCIBR_FREEZE_TIME
-    freeze_time = get_timestamp() - freeze_time_start;
-
-    if ((max_freeze_time < freeze_time) ||
-	(max_ate_total < ate_total)) {
-	if (max_freeze_time < freeze_time)
-	    max_freeze_time = freeze_time;
-	if (max_ate_total < ate_total)
-	    max_ate_total = ate_total;
-	pcibr_unlock(pcibr_soft, s);
-	printk("%s: pci freeze time %d usec for %d ATEs\n"
-		"\tfirst ate: %R\n",
-		pcibr_soft->bs_name,
-		freeze_time * 1000 / 1250,
-		ate_total,
-		ate, ate_bits);
-    } else
-#endif
-	pcibr_unlock(pcibr_soft, s);
-}
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_dmamap_addr(pcibr_dmamap_t pcibr_dmamap,
-		  paddr_t paddr,
-		  size_t req_size)
-{
-    pcibr_soft_t            pcibr_soft;
-    iopaddr_t               xio_addr;
-    xwidgetnum_t            xio_port;
-    iopaddr_t               pci_addr;
-    unsigned                flags;
-
-    ASSERT(pcibr_dmamap != NULL);
-    ASSERT(req_size > 0);
-    ASSERT(req_size <= pcibr_dmamap->bd_max_size);
-
-    pcibr_soft = pcibr_dmamap->bd_soft;
-
-    flags = pcibr_dmamap->bd_flags;
-
-    xio_addr = xtalk_dmamap_addr(pcibr_dmamap->bd_xtalk, paddr, req_size);
-    if (XIO_PACKED(xio_addr)) {
-	xio_port = XIO_PORT(xio_addr);
-	xio_addr = XIO_ADDR(xio_addr);
-    } else
-	xio_port = pcibr_dmamap->bd_xio_port;
-
-    /* If this DMA is to an address that
-     * refers back to this Bridge chip,
-     * reduce it back to the correct
-     * PCI MEM address.
-     */
-    if (xio_port == pcibr_soft->bs_xid) {
-	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
-    } else if (flags & PCIIO_DMA_A64) {
-	/* A64 DMA:
-	 * always use 64-bit direct mapping,
-	 * which always works.
-	 * Device(x) was set up during
-	 * dmamap allocation.
-	 */
-
-	/* attributes are already bundled up into bd_pci_addr.
-	 */
-	pci_addr = pcibr_dmamap->bd_pci_addr
-	    | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT)
-	    | xio_addr;
-
-	/* Bridge Hardware WAR #482836:
-	 * If the transfer is not cache aligned
-	 * and the Bridge Rev is <= B, force
-	 * prefetch to be off.
-	 */
-	if (flags & PCIBR_NOPREFETCH)
-	    pci_addr &= ~PCI64_ATTR_PREF;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-	printk("pcibr_dmamap_addr (direct64):\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\tXIO port 0x%x offset 0x%x\n"
-		"\treturning PCI 0x%x\n",
-		paddr, paddr + req_size - 1,
-		xio_port, xio_addr, pci_addr);
-#endif
-    } else if (flags & PCIIO_FIXED) {
-	/* A32 direct DMA:
-	 * always use 32-bit direct mapping,
-	 * which may fail.
-	 * Device(x) was set up during
-	 * dmamap allocation.
-	 */
-
-	if (xio_port != pcibr_soft->bs_dir_xport)
-	    pci_addr = 0;		/* wrong DIDN */
-	else if (xio_addr < pcibr_dmamap->bd_xio_addr)
-	    pci_addr = 0;		/* out of range */
-	else if ((xio_addr + req_size) >
-		 (pcibr_dmamap->bd_xio_addr + BRIDGE_DMA_DIRECT_SIZE))
-	    pci_addr = 0;		/* out of range */
-	else
-	    pci_addr = pcibr_dmamap->bd_pci_addr +
-		xio_addr - pcibr_dmamap->bd_xio_addr;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-	printk("pcibr_dmamap_addr (direct32):\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\tXIO port 0x%x offset 0x%x\n"
-		"\treturning PCI 0x%x\n",
-		paddr, paddr + req_size - 1,
-		xio_port, xio_addr, pci_addr);
-#endif
-    } else {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-	iopaddr_t               offset = IOPGOFF(xio_addr);
-	bridge_ate_t            ate_proto = pcibr_dmamap->bd_ate_proto;
-	int                     ate_count = IOPG(offset + req_size - 1) + 1;
-
-	int                     ate_index = pcibr_dmamap->bd_ate_index;
-	unsigned                cmd_regs[8];
-	unsigned                s;
-
-#if PCIBR_FREEZE_TIME
-	int                     ate_total = ate_count;
-	unsigned                freeze_time;
-#endif
-
-#if PCIBR_ATE_DEBUG
-	bridge_ate_t            ate_cmp;
-	bridge_ate_p            ate_cptr;
-	unsigned                ate_lo, ate_hi;
-	int                     ate_bad = 0;
-	int                     ate_rbc = 0;
-#endif
-	bridge_ate_p            ate_ptr = pcibr_dmamap->bd_ate_ptr;
-	bridge_ate_t            ate;
-
-	/* Bridge Hardware WAR #482836:
-	 * If the transfer is not cache aligned
-	 * and the Bridge Rev is <= B, force
-	 * prefetch to be off.
-	 */
-	if (flags & PCIBR_NOPREFETCH)
-	    ate_proto &= ~ATE_PREF;
-
-	ate = ate_proto
-	    | (xio_port << ATE_TIDSHIFT)
-	    | (xio_addr - offset);
-
-	pci_addr = pcibr_dmamap->bd_pci_addr + offset;
-
-	/* Fill in our mapping registers
-	 * with the appropriate xtalk data,
-	 * and hand back the PCI address.
-	 */
-
-	ASSERT(ate_count > 0);
-	if (ate_count <= pcibr_dmamap->bd_ate_count) {
-		ATE_FREEZE();
-		ATE_WRITE();
-		ATE_THAW();
-		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	} else {
-		/* The number of ATE's required is greater than the number
-		 * allocated for this map. One way this can happen is if
-		 * pcibr_dmamap_alloc() was called with the PCIBR_NO_ATE_ROUNDUP
-		 * flag, and then when that map is used (right now), the
-		 * target address tells us we really did need to roundup.
-		 * The other possibility is that the map is just plain too
-		 * small to handle the requested target area.
-		 */
-#if PCIBR_ATE_DEBUG
-		printk(KERN_WARNING   "pcibr_dmamap_addr :\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\tate_count 0x%x bd_ate_count 0x%x\n"
-			"\tATE's required > number allocated\n",
-			paddr, paddr + req_size - 1,
-			ate_count, pcibr_dmamap->bd_ate_count);
-#endif
-		pci_addr = 0;
-	}
-
-    }
-    return pci_addr;
-}
-
-/*ARGSUSED */
-alenlist_t
-pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap,
-		  alenlist_t palenlist,
-		  unsigned flags)
-{
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge=NULL;
-
-    unsigned                al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-    int                     inplace = flags & PCIIO_INPLACE;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist;
-    size_t                  length;
-    iopaddr_t               offset;
-    unsigned                direct64;
-    int                     ate_index = 0;
-    int                     ate_count = 0;
-    int                     ate_total = 0;
-    bridge_ate_p            ate_ptr = (bridge_ate_p)0;
-    bridge_ate_t            ate_proto = (bridge_ate_t)0;
-    bridge_ate_t            ate_prev;
-    bridge_ate_t            ate;
-    alenaddr_t              xio_addr;
-    xwidgetnum_t            xio_port;
-    iopaddr_t               pci_addr;
-    alenaddr_t              new_addr;
-
-    unsigned                cmd_regs[8];
-    unsigned                s = 0;
-
-#if PCIBR_FREEZE_TIME
-    unsigned                freeze_time;
-#endif
-    int			    ate_freeze_done = 0;	/* To pair ATE_THAW
-							 * with an ATE_FREEZE
-							 */
-
-    pcibr_soft = pcibr_dmamap->bd_soft;
-
-    xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist,
-				       flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist)
-	goto fail;
-
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist)
-	    goto fail;
-    }
-
-    direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64;
-    if (!direct64) {
-	bridge = pcibr_soft->bs_base;
-	ate_ptr = pcibr_dmamap->bd_ate_ptr;
-	ate_index = pcibr_dmamap->bd_ate_index;
-	ate_proto = pcibr_dmamap->bd_ate_proto;
-	ATE_FREEZE();
-	ate_freeze_done = 1;	/* Remember that we need to do an ATE_THAW */
-    }
-    pci_addr = pcibr_dmamap->bd_pci_addr;
-
-    ate_prev = 0;			/* matches no valid ATEs */
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &length, al_flags)) {
-	if (XIO_PACKED(xio_addr)) {
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_dmamap->bd_xio_port;
-
-	if (xio_port == pcibr_soft->bs_xid) {
-	    new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length);
-	    if (new_addr == PCI_NOWHERE)
-		goto fail;
-	} else if (direct64) {
-	    new_addr = pci_addr | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-	    /* Bridge Hardware WAR #482836:
-	     * If the transfer is not cache aligned
-	     * and the Bridge Rev is <= B, force
-	     * prefetch to be off.
-	     */
-	    if (flags & PCIBR_NOPREFETCH)
-		new_addr &= ~PCI64_ATTR_PREF;
-
-	} else {
-	    /* calculate the ate value for
-	     * the first address. If it
-	     * matches the previous
-	     * ATE written (ie. we had
-	     * multiple blocks in the
-	     * same IOPG), then back up
-	     * and reuse that ATE.
-	     *
-	     * We are NOT going to
-	     * aggressively try to
-	     * reuse any other ATEs.
-	     */
-	    offset = IOPGOFF(xio_addr);
-	    ate = ate_proto
-		| (xio_port << ATE_TIDSHIFT)
-		| (xio_addr - offset);
-	    if (ate == ate_prev) {
-#if PCIBR_ATE_DEBUG
-		printk("pcibr_dmamap_list: ATE share\n");
-#endif
-		ate_ptr--;
-		ate_index--;
-		pci_addr -= IOPGSIZE;
-	    }
-	    new_addr = pci_addr + offset;
-
-	    /* Fill in the hardware ATEs
-	     * that contain this block.
-	     */
-	    ate_count = IOPG(offset + length - 1) + 1;
-	    ate_total += ate_count;
-
-	    /* Ensure that this map contains enough ATE's */
-	    if (ate_total > pcibr_dmamap->bd_ate_count) {
-#if PCIBR_ATE_DEBUG
-		printk(KERN_WARNING   "pcibr_dmamap_list :\n"
-			"\twanted xio_addr [0x%x..0x%x]\n"
-			"\tate_total 0x%x bd_ate_count 0x%x\n"
-			"\tATE's required > number allocated\n",
-			xio_addr, xio_addr + length - 1,
-			ate_total, pcibr_dmamap->bd_ate_count);
-#endif
-		goto fail;
-	    }
-
-	    ATE_WRITE();
-
-	    ate_index += ate_count;
-	    ate_ptr += ate_count;
-
-	    ate_count <<= IOPFNSHIFT;
-	    ate += ate_count;
-	    pci_addr += ate_count;
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &new_addr, &length, al_flags))
-		goto fail;
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				new_addr, length, al_flags))
-		goto fail;
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-
-
-    /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the
-     * changes that ATE_FREEZE has done to implement the external SSRAM
-     * bug workaround.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    return pciio_alenlist;
-
-  fail:
-    /* There are various points of failure after doing an ATE_FREEZE
-     * We need to do an ATE_THAW. Otherwise the ATEs are locked forever.
-     * The decision to do an ATE_THAW needs to be based on whether a
-     * an ATE_FREEZE was done before.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	bridge->b_wid_tflush;
-    }
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap)
-{
-    /*
-     * We could go through and invalidate ATEs here;
-     * for performance reasons, we don't.
-     * We also don't enforce the strict alternation
-     * between _addr/_list and _done, but Hub does.
-     */
-
-    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
-	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
-
-	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
-	    atomic_dec(&(pcibr_dmamap->bd_soft->bs_slot[pcibr_dmamap->bd_slot]. bss_ext_ates_active));
-    }
-
-    xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
-}
-
-
-/*
- * For each bridge, the DIR_OFF value in the Direct Mapping Register
- * determines the PCI to Crosstalk memory mapping to be used for all
- * 32-bit Direct Mapping memory accesses. This mapping can be to any
- * node in the system. This function will return that compact node id.
- */
-
-/*ARGSUSED */
-cnodeid_t
-pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl)
-{
-
-	pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
-	pcibr_soft_t	pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-	return(NASID_TO_COMPACT_NODEID(NASID_GET(pcibr_soft->bs_dir_xbase)));
-}
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    paddr_t paddr,
-		    size_t req_size,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
-
-    xwidgetnum_t            xio_port;
-    iopaddr_t               xio_addr;
-    iopaddr_t               pci_addr;
-
-    int                     have_rrbs;
-    int                     min_rrbs;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-    xio_addr = xtalk_dmatrans_addr(xconn_vhdl, 0, paddr, req_size,
-				   flags & DMAMAP_FLAGS);
-
-    if (!xio_addr) {
-#if PCIBR_DMA_DEBUG
-	printk("pcibr_dmatrans_addr:\n"
-		"\tpciio connection point %v\n"
-		"\txtalk connection point %v\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\txtalk_dmatrans_addr returned 0x%x\n",
-		pconn_vhdl, xconn_vhdl,
-		paddr, paddr + req_size - 1,
-		xio_addr);
-#endif
-	return 0;
-    }
-    /*
-     * find which XIO port this goes to.
-     */
-    if (XIO_PACKED(xio_addr)) {
-	if (xio_addr == XIO_NOWHERE) {
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	    return 0;
-	}
-	xio_port = XIO_PORT(xio_addr);
-	xio_addr = XIO_ADDR(xio_addr);
-
-    } else
-	xio_port = pcibr_soft->bs_mxid;
-
-    /*
-     * If this DMA comes back to us,
-     * return the PCI MEM address on
-     * which it would land, or NULL
-     * if the target is something
-     * on bridge other than PCI MEM.
-     */
-    if (xio_port == pcibr_soft->bs_xid) {
-	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
-	return pci_addr;
-    }
-    /* If the caller can use A64, try to
-     * satisfy the request with the 64-bit
-     * direct map. This can fail if the
-     * configuration bits in Device(x)
-     * conflict with our flags.
-     */
-
-    if (flags & PCIIO_DMA_A64) {
-	pci_addr = slotp->bss_d64_base;
-	if (!(flags & PCIBR_VCHAN1))
-	    flags |= PCIBR_VCHAN0;
-	if ((pci_addr != PCIBR_D64_BASE_UNSET) &&
-	    (flags == slotp->bss_d64_flags)) {
-
-	    pci_addr |= xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-#if DEBUG && PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-	    if (xio_addr != 0x20000000)
-#endif
-		printk("pcibr_dmatrans_addr: [reuse]\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tdirect 64bit address is 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, pci_addr);
-#endif
-	    return (pci_addr);
-	}
-	if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS)) {
-	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
-	    slotp->bss_d64_flags = flags;
-	    slotp->bss_d64_base = pci_addr;
-	    pci_addr |= xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
-		if (flags & PCIBR_VCHAN1)
-		    pciio_slot += PCIBR_RRB_SLOT_VIRTUAL;
-		have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
-		if (have_rrbs < 2) {
-		    if (pci_addr & PCI64_ATTR_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
-		}
-	    }
-#if PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-	    if (xio_addr != 0x20000000)
-#endif
-		printk("pcibr_dmatrans_addr:\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tdirect 64bit address is 0x%x\n"
-			"\tnew flags: 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, pci_addr, (uint64_t) flags);
-#endif
-	    return (pci_addr);
-	}
-	/* our flags conflict with Device(x).
-	 */
-	flags = flags
-	    & ~PCIIO_DMA_A64
-	    & ~PCIBR_VCHAN0
-	    ;
-
-#if PCIBR_DMA_DEBUG
-	printk("pcibr_dmatrans_addr:\n"
-		"\tpciio connection point %v\n"
-		"\txtalk connection point %v\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\txtalk_dmatrans_addr returned 0x%x\n"
-		"\tUnable to set Device(x) bits for Direct-64\n",
-		pconn_vhdl, xconn_vhdl,
-		paddr, paddr + req_size - 1,
-		xio_addr);
-#endif
-    }
-    /* Try to satisfy the request with the 32-bit direct
-     * map. This can fail if the configuration bits in
-     * Device(x) conflict with our flags, or if the
-     * target address is outside where DIR_OFF points.
-     */
-    {
-	size_t                  map_size = 1ULL << 31;
-	iopaddr_t               xio_base = pcibr_soft->bs_dir_xbase;
-	iopaddr_t               offset = xio_addr - xio_base;
-	iopaddr_t               endoff = req_size + offset;
-
-	if ((req_size > map_size) ||
-	    (xio_addr < xio_base) ||
-	    (xio_port != pcibr_soft->bs_dir_xport) ||
-	    (endoff > map_size)) {
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n"
-		    "\txio region outside direct32 target\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	} else {
-	    pci_addr = slotp->bss_d32_base;
-	    if ((pci_addr != PCIBR_D32_BASE_UNSET) &&
-		(flags == slotp->bss_d32_flags)) {
-
-		pci_addr |= offset;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-		printk("pcibr_dmatrans_addr: [reuse]\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tmapped via direct32 offset 0x%x\n"
-			"\twill DMA via pci addr 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, offset, pci_addr);
-#endif
-		return (pci_addr);
-	    }
-	    if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS)) {
-
-		pci_addr = PCI32_DIRECT_BASE;
-		slotp->bss_d32_flags = flags;
-		slotp->bss_d32_base = pci_addr;
-		pci_addr |= offset;
-
-		/* Make sure we have an RRB (or two).
-		 */
-		if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
-		    have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
-		    if (have_rrbs < 2) {
-			if (slotp->bss_device & BRIDGE_DEV_PREF)
-			    min_rrbs = 2;
-			else
-			    min_rrbs = 1;
-			if (have_rrbs < min_rrbs)
-			    do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
-		    }
-		}
-#if PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-		if (xio_addr != 0x20000000)
-#endif
-		    printk("pcibr_dmatrans_addr:\n"
-			    "\tpciio connection point %v\n"
-			    "\txtalk connection point %v\n"
-			    "\twanted paddr [0x%x..0x%x]\n"
-			    "\txtalk_dmatrans_addr returned 0x%x\n"
-			    "\tmapped via direct32 offset 0x%x\n"
-			    "\twill DMA via pci addr 0x%x\n"
-			    "\tnew flags: 0x%x\n",
-			    pconn_vhdl, xconn_vhdl,
-			    paddr, paddr + req_size - 1,
-			    xio_addr, offset, pci_addr, (uint64_t) flags);
-#endif
-		return (pci_addr);
-	    }
-	    /* our flags conflict with Device(x).
-	     */
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n"
-		    "\tUnable to set Device(x) bits for Direct-32\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	}
-    }
-
-#if PCIBR_DMA_DEBUG
-    printk("pcibr_dmatrans_addr:\n"
-	    "\tpciio connection point %v\n"
-	    "\txtalk connection point %v\n"
-	    "\twanted paddr [0x%x..0x%x]\n"
-	    "\txtalk_dmatrans_addr returned 0x%x\n"
-	    "\tno acceptable PCI address found or constructable\n",
-	    pconn_vhdl, xconn_vhdl,
-	    paddr, paddr + req_size - 1,
-	    xio_addr);
-#endif
-
-    return 0;
-}
-
-/*ARGSUSED */
-alenlist_t
-pcibr_dmatrans_list(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    alenlist_t palenlist,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
-    xwidgetnum_t            xio_port;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist = 0;
-
-    int                     inplace;
-    unsigned                direct64;
-    unsigned                al_flags;
-
-    iopaddr_t               xio_base;
-    alenaddr_t              xio_addr;
-    size_t                  xio_size;
-
-    size_t                  map_size;
-    iopaddr_t               pci_base;
-    alenaddr_t              pci_addr;
-
-    unsigned                relbits = 0;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-    inplace = flags & PCIIO_INPLACE;
-    direct64 = flags & PCIIO_DMA_A64;
-    al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-
-    if (direct64) {
-	map_size = 1ull << 48;
-	xio_base = 0;
-	pci_base = slotp->bss_d64_base;
-	if ((pci_base != PCIBR_D64_BASE_UNSET) &&
-	    (flags == slotp->bss_d64_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D64_BITS;
-	    pci_base =
-		pcibr_flags_to_d64(flags, pcibr_soft);
-	}
-    } else {
-	xio_base = pcibr_soft->bs_dir_xbase;
-	map_size = 1ull << 31;
-	pci_base = slotp->bss_d32_base;
-	if ((pci_base != PCIBR_D32_BASE_UNSET) &&
-	    (flags == slotp->bss_d32_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D32_BITS;
-	    pci_base = PCI32_DIRECT_BASE;
-	}
-    }
-
-    xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist,
-					 flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist)
-	goto fail;
-
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist)
-	    goto fail;
-    }
-
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &xio_size, al_flags)) {
-
-	/*
-	 * find which XIO port this goes to.
-	 */
-	if (XIO_PACKED(xio_addr)) {
-	    if (xio_addr == XIO_NOWHERE) {
-#if PCIBR_DMA_DEBUG
-		printk("pcibr_dmatrans_addr:\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr);
-#endif
-		return 0;
-	    }
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_soft->bs_mxid;
-
-	/*
-	 * If this DMA comes back to us,
-	 * return the PCI MEM address on
-	 * which it would land, or NULL
-	 * if the target is something
-	 * on bridge other than PCI MEM.
-	 */
-	if (xio_port == pcibr_soft->bs_xid) {
-	    pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size);
-	    if ( (pci_addr == (alenaddr_t)NULL) )
-		goto fail;
-	} else if (direct64) {
-	    ASSERT(xio_port != 0);
-	    pci_addr = pci_base | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-	} else {
-	    iopaddr_t               offset = xio_addr - xio_base;
-	    iopaddr_t               endoff = xio_size + offset;
-
-	    if ((xio_size > map_size) ||
-		(xio_addr < xio_base) ||
-		(xio_port != pcibr_soft->bs_dir_xport) ||
-		(endoff > map_size))
-		goto fail;
-
-	    pci_addr = pci_base + (xio_addr - xio_base);
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &pci_addr, &xio_size, al_flags))
-		goto fail;
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				pci_addr, xio_size, al_flags))
-		goto fail;
-	}
-    }
-
-    if (relbits) {
-	if (direct64) {
-	    slotp->bss_d64_flags = flags;
-	    slotp->bss_d64_base = pci_base;
-	} else {
-	    slotp->bss_d32_flags = flags;
-	    slotp->bss_d32_base = pci_base;
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-    return pciio_alenlist;
-
-  fail:
-    if (relbits)
-	pcibr_release_device(pcibr_soft, pciio_slot, relbits);
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
-void
-pcibr_dmamap_drain(pcibr_dmamap_t map)
-{
-    xtalk_dmamap_drain(map->bd_xtalk);
-}
-
-void
-pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl,
-		    paddr_t paddr,
-		    size_t bytes)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes);
-}
-
-void
-pcibr_dmalist_drain(devfs_handle_t pconn_vhdl,
-		    alenlist_t list)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    xtalk_dmalist_drain(xconn_vhdl, list);
-}
-
-/*
- * Get the starting PCIbus address out of the given DMA map.
- * This function is supposed to be used by a close friend of PCI bridge
- * since it relies on the fact that the starting address of the map is fixed at
- * the allocation time in the current implementation of PCI bridge.
- */
-iopaddr_t
-pcibr_dmamap_pciaddr_get(pcibr_dmamap_t pcibr_dmamap)
-{
-    return (pcibr_dmamap->bd_pci_addr);
-}
-
-/*
- *	There are end cases where a deadlock can occur if interrupt 
- *	processing completes and the Bridge b_int_status bit is still set.
- *
- *	One scenerio is if a second PCI interrupt occurs within 60ns of
- *	the previous interrupt being cleared. In this case the Bridge
- *	does not detect the transition, the Bridge b_int_status bit
- *	remains set, and because no transition was detected no interrupt
- *	packet is sent to the Hub/Heart.
- *
- *	A second scenerio is possible when a b_int_status bit is being
- *	shared by multiple devices:
- *						Device #1 generates interrupt
- *						Bridge b_int_status bit set
- *						Device #2 generates interrupt
- *		interrupt processing begins
- *		  ISR for device #1 runs and
- *			clears interrupt
- *						Device #1 generates interrupt
- *		  ISR for device #2 runs and
- *			clears interrupt
- *						(b_int_status bit still set)
- *		interrupt processing completes
- *		  
- *	Interrupt processing is now complete, but an interrupt is still
- *	outstanding for Device #1. But because there was no transition of
- *	the b_int_status bit, no interrupt packet will be generated and
- *	a deadlock will occur.
- *
- *	To avoid these deadlock situations, this function is used
- *	to check if a specific Bridge b_int_status bit is set, and if so,
- *	cause the setting of the corresponding interrupt bit.
- *
- *	On a XBridge (IP35), we do this by writing the appropriate Bridge Force 
- *	Interrupt register.
- */
-void
-pcibr_force_interrupt(pcibr_intr_wrap_t wrap)
-{
-	unsigned	bit;
-	pcibr_soft_t    pcibr_soft = wrap->iw_soft;
-	bridge_t       *bridge = pcibr_soft->bs_base;
-	cpuid_t cpuvertex_to_cpuid(devfs_handle_t vhdl);
-
-	bit = wrap->iw_intr;
-
-	if (pcibr_soft->bs_xbridge) {
-	    bridge->b_force_pin[bit].intr = 1;
-	} else if ((1 << bit) & *wrap->iw_stat) {
-	    cpuid_t	    cpu;
-	    unsigned        intr_bit;
-	    xtalk_intr_t    xtalk_intr =
-				pcibr_soft->bs_intr[bit].bsi_xtalk_intr;
-
-	    intr_bit = (short) xtalk_intr_vector_get(xtalk_intr);
-	    cpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr));
-	    REMOTE_CPU_SEND_INTR(cpu, intr_bit);
-	}
-}
-
-/* =====================================================================
- *    INTERRUPT MANAGEMENT
- */
-
-static unsigned
-pcibr_intr_bits(pciio_info_t info,
-		pciio_intr_line_t lines)
-{
-    pciio_slot_t            slot = pciio_info_slot_get(info);
-    unsigned		    bbits = 0;
-
-    /*
-     * Currently favored mapping from PCI
-     * slot number and INTA/B/C/D to Bridge
-     * PCI Interrupt Bit Number:
-     *
-     *     SLOT     A B C D
-     *      0       0 4 0 4
-     *      1       1 5 1 5
-     *      2       2 6 2 6
-     *      3       3 7 3 7
-     *      4       4 0 4 0
-     *      5       5 1 5 1
-     *      6       6 2 6 2
-     *      7       7 3 7 3
-     */
-
-    if (slot < 8) {
-	if (lines & (PCIIO_INTR_LINE_A| PCIIO_INTR_LINE_C))
-	    bbits |= 1 << slot;
-	if (lines & (PCIIO_INTR_LINE_B| PCIIO_INTR_LINE_D))
-	    bbits |= 1 << (slot ^ 4);
-    }
-    return bbits;
-}
-
-
-/*ARGSUSED */
-pcibr_intr_t
-pcibr_intr_alloc(devfs_handle_t pconn_vhdl,
-		 device_desc_t dev_desc,
-		 pciio_intr_line_t lines,
-		 devfs_handle_t owner_dev)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pcibr_info->f_slot;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     is_threaded = 0;
-    int                     thread_swlevel;
-
-    xtalk_intr_t           *xtalk_intr_p;
-    pcibr_intr_t           *pcibr_intr_p;
-    pcibr_intr_list_t      *intr_list_p;
-
-    unsigned                pcibr_int_bits;
-    unsigned                pcibr_int_bit;
-    xtalk_intr_t            xtalk_intr = (xtalk_intr_t)0;
-    hub_intr_t		    hub_intr;
-    pcibr_intr_t            pcibr_intr;
-    pcibr_intr_list_t       intr_entry;
-    pcibr_intr_list_t       intr_list;
-    bridgereg_t             int_dev;
-
-#if DEBUG && INTR_DEBUG
-    printk("%v: pcibr_intr_alloc\n"
-	    "%v:%s%s%s%s%s\n",
-	    owner_dev, pconn_vhdl,
-	    !(lines & 15) ? " No INTs?" : "",
-	    lines & 1 ? " INTA" : "",
-	    lines & 2 ? " INTB" : "",
-	    lines & 4 ? " INTC" : "",
-	    lines & 8 ? " INTD" : "");
-#endif
-
-    NEW(pcibr_intr);
-    if (!pcibr_intr)
-	return NULL;
-
-    if (dev_desc) {
-	cpuid_t intr_target_from_desc(device_desc_t, int);
-    } else {
-	extern int default_intr_pri;
-
-	is_threaded = 1; /* PCI interrupts are threaded, by default */
-	thread_swlevel = default_intr_pri;
-    }
-
-    pcibr_intr->bi_dev = pconn_vhdl;
-    pcibr_intr->bi_lines = lines;
-    pcibr_intr->bi_soft = pcibr_soft;
-    pcibr_intr->bi_ibits = 0;		/* bits will be added below */
-    pcibr_intr->bi_flags = is_threaded ? 0 : PCIIO_INTR_NOTHREAD;
-    pcibr_intr->bi_mustruncpu = CPU_NONE;
-    mutex_spinlock_init(&pcibr_intr->bi_ibuf.ib_lock);
-
-    pcibr_int_bits = pcibr_soft->bs_intr_bits((pciio_info_t)pcibr_info, lines);
-
-
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and make sure there are xtalk resources
-     * allocated for it.
-     */
-#if DEBUG && INTR_DEBUG
-    printk("pcibr_int_bits: 0x%X\n", pcibr_int_bits);
-#endif 
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit ++) {
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    xtalk_intr_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    xtalk_intr = *xtalk_intr_p;
-
-	    if (xtalk_intr == NULL) {
-		/*
-		 * This xtalk_intr_alloc is constrained for two reasons:
-		 * 1) Normal interrupts and error interrupts need to be delivered
-		 *    through a single xtalk target widget so that there aren't any
-		 *    ordering problems with DMA, completion interrupts, and error
-		 *    interrupts. (Use of xconn_vhdl forces this.)
-		 *
-		 * 2) On IP35, addressing constraints on IP35 and Bridge force
-		 *    us to use a single PI number for all interrupts from a
-		 *    single Bridge. (IP35-specific code forces this, and we
-		 *    verify in pcibr_setwidint.)
-		 */
-
-		/*
-		 * All code dealing with threaded PCI interrupt handlers
-		 * is located at the pcibr level. Because of this,
-		 * we always want the lower layers (hub/heart_intr_alloc, 
-		 * intr_level_connect) to treat us as non-threaded so we
-		 * don't set up a duplicate threaded environment. We make
-		 * this happen by calling a special xtalk interface.
-		 */
-		xtalk_intr = xtalk_intr_alloc_nothd(xconn_vhdl, dev_desc, 
-			owner_dev);
-#if DEBUG && INTR_DEBUG
-		printk("%v: xtalk_intr=0x%X\n", xconn_vhdl, xtalk_intr);
-#endif
-
-		/* both an assert and a runtime check on this:
-		 * we need to check in non-DEBUG kernels, and
-		 * the ASSERT gets us more information when
-		 * we use DEBUG kernels.
-		 */
-		ASSERT(xtalk_intr != NULL);
-		if (xtalk_intr == NULL) {
-		    /* it is quite possible that our
-		     * xtalk_intr_alloc failed because
-		     * someone else got there first,
-		     * and we can find their results
-		     * in xtalk_intr_p.
-		     */
-		    if (!*xtalk_intr_p) {
-#ifdef SUPPORT_PRINTING_V_FORMAT
-			printk(KERN_ALERT  
-				"pcibr_intr_alloc %v: unable to get xtalk interrupt resources",
-				xconn_vhdl);
-#else
-			printk(KERN_ALERT  
-				"pcibr_intr_alloc 0x%p: unable to get xtalk interrupt resources",
-				(void *)xconn_vhdl);
-#endif
-			/* yes, we leak resources here. */
-			return 0;
-		    }
-		} else if (compare_and_swap_ptr((void **) xtalk_intr_p, NULL, xtalk_intr)) {
-		    /*
-		     * now tell the bridge which slot is
-		     * using this interrupt line.
-		     */
-		    int_dev = bridge->b_int_device;
-		    int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
-		    int_dev |= pciio_slot << BRIDGE_INT_DEV_SHFT(pcibr_int_bit);
-		    bridge->b_int_device = int_dev;	/* XXXMP */
-
-#if DEBUG && INTR_DEBUG
-		    printk("%v: bridge intr bit %d clears my wrb\n",
-			    pconn_vhdl, pcibr_int_bit);
-#endif
-		} else {
-		    /* someone else got one allocated first;
-		     * free the one we just created, and
-		     * retrieve the one they allocated.
-		     */
-		    xtalk_intr_free(xtalk_intr);
-		    xtalk_intr = *xtalk_intr_p;
-#if PARANOID
-		    /* once xtalk_intr is set, we never clear it,
-		     * so if the CAS fails above, this condition
-		     * can "never happen" ...
-		     */
-		    if (!xtalk_intr) {
-			printk(KERN_ALERT  
-				"pcibr_intr_alloc %v: unable to set xtalk interrupt resources",
-				xconn_vhdl);
-			/* yes, we leak resources here. */
-			return 0;
-		    }
-#endif
-		}
-	    }
-
-	    pcibr_intr->bi_ibits |= 1 << pcibr_int_bit;
-
-	    NEW(intr_entry);
-	    intr_entry->il_next = NULL;
-	    intr_entry->il_intr = pcibr_intr;
-	    intr_entry->il_wrbf = &(bridge->b_wr_req_buf[pciio_slot].reg);
-	    intr_list_p = 
-		&pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
-#if DEBUG && INTR_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	    printk("0x%x: Bridge bit %d wrap=0x%x\n",
-		pconn_vhdl, pcibr_int_bit,
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
-#else
-	    printk("%v: Bridge bit %d wrap=0x%x\n",
-		pconn_vhdl, pcibr_int_bit,
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
-#endif
-#endif
-
-	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		/* we are the first interrupt on this bridge bit.
-		 */
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) allocated [FIRST]\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    intr_list = *intr_list_p;
-	    pcibr_intr_p = &intr_list->il_intr;
-	    if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
-		/* first entry on list was erased,
-		 * and we replaced it, so we
-		 * don't need our intr_entry.
-		 */
-		DEL(intr_entry);
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) replaces erased first\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    intr_list_p = &intr_list->il_next;
-	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		/* we are the new second interrupt on this bit.
-		 */
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared = 1;
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) is new SECOND\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    while (1) {
-		pcibr_intr_p = &intr_list->il_intr;
-		if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
-		    /* an entry on list was erased,
-		     * and we replaced it, so we
-		     * don't need our intr_entry.
-		     */
-		    DEL(intr_entry);
-#if DEBUG && INTR_DEBUG
-		    printk("%v INT 0x%x (bridge bit %d) replaces erased Nth\n",
-			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		    break;
-		}
-		intr_list_p = &intr_list->il_next;
-		if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		    /* entry appended to share list
-		     */
-#if DEBUG && INTR_DEBUG
-		    printk("%v INT 0x%x (bridge bit %d) is new Nth\n",
-			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		    break;
-		}
-		/* step to next record in chain
-		 */
-		intr_list = *intr_list_p;
-	    }
-	}
-    }
-
-#if DEBUG && INTR_DEBUG
-    printk("%v pcibr_intr_alloc complete\n", pconn_vhdl);
-#endif
-    hub_intr = (hub_intr_t)xtalk_intr;
-    pcibr_intr->bi_irq = hub_intr->i_bit;
-    pcibr_intr->bi_cpu = hub_intr->i_cpuid;
-    return pcibr_intr;
-}
-
-/*ARGSUSED */
-void
-pcibr_intr_free(pcibr_intr_t pcibr_intr)
-{
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    unsigned                pcibr_int_bit;
-    pcibr_intr_list_t       intr_list;
-    int			    intr_shared;
-    xtalk_intr_t	    *xtalk_intrp;
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) {
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    for (intr_list = 
-		     pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
-		 intr_list != NULL;
-		 intr_list = intr_list->il_next)
-		if (compare_and_swap_ptr((void **) &intr_list->il_intr, 
-					 pcibr_intr, 
-					 NULL)) {
-#if DEBUG && INTR_DEBUG
-		    printk("%s: cleared a handler from bit %d\n",
-			    pcibr_soft->bs_name, pcibr_int_bit);
-#endif
-		}
-	    /* If this interrupt line is not being shared between multiple
-	     * devices release the xtalk interrupt resources.
-	     */
-	    intr_shared = 
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared;
-	    xtalk_intrp = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    if ((!intr_shared) && (*xtalk_intrp)) {
-
-		bridge_t 	*bridge = pcibr_soft->bs_base;
-		bridgereg_t	int_dev;
-
-		xtalk_intr_free(*xtalk_intrp);
-		*xtalk_intrp = 0;
-
-		/* Clear the PCI device interrupt to bridge interrupt pin
-		 * mapping.
-		 */
-		int_dev = bridge->b_int_device;
-		int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
-		bridge->b_int_device = int_dev;
-
-	    }
-	}
-    }
-    DEL(pcibr_intr);
-}
-
-LOCAL void
-pcibr_setpciint(xtalk_intr_t xtalk_intr)
-{
-    iopaddr_t               addr = xtalk_intr_addr_get(xtalk_intr);
-    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(xtalk_intr);
-    bridgereg_t            *int_addr = (bridgereg_t *)
-    xtalk_intr_sfarg_get(xtalk_intr);
-
-    *int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
-		 (BRIDGE_INT_ADDR_FLD & vect));
-}
-
-/*ARGSUSED */
-int
-pcibr_intr_connect(pcibr_intr_t pcibr_intr)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-    bridgereg_t             b_int_enable;
-    unsigned long           s;
-
-    if (pcibr_intr == NULL)
-	return -1;
-
-#if DEBUG && INTR_DEBUG
-    printk("%v: pcibr_intr_connect\n",
-	    pcibr_intr->bi_dev);
-#endif
-
-    *((volatile unsigned *)&pcibr_intr->bi_flags) |= PCIIO_INTR_CONNECTED;
-
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and make sure there are xtalk resources
-     * allocated for it.
-     */
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    xtalk_intr_t            xtalk_intr;
-
-	    xtalk_intr = pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    /*
-	     * If this interrupt line is being shared and the connect has
-	     * already been done, no need to do it again.
-	     */
-	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected)
-		continue;
-
-
-	    /*
-	     * Use the pcibr wrapper function to handle all Bridge interrupts
-	     * regardless of whether the interrupt line is shared or not.
-	     */
-	    xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t) pcibr_setpciint,
-			       (void *)&(bridge->b_int_addr[pcibr_int_bit].addr));
-	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 1;
-
-#if DEBUG && INTR_DEBUG
-	    printk("%v bridge bit %d wrapper connected\n",
-		    pcibr_intr->bi_dev, pcibr_int_bit);
-#endif
-	}
-    s = pcibr_lock(pcibr_soft);
-    b_int_enable = bridge->b_int_enable;
-    b_int_enable |= pcibr_int_bits;
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_intr_disconnect(pcibr_intr_t pcibr_intr)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-    bridgereg_t             b_int_enable;
-    unsigned long           s;
-
-    /* Stop calling the function. Now.
-     */
-    *((volatile unsigned *)&pcibr_intr->bi_flags) &= ~PCIIO_INTR_CONNECTED;
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and disconnect the interrupt.
-     */
-
-    /* don't disable interrupts for lines that
-     * are shared between devices.
-     */
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if ((pcibr_int_bits & (1 << pcibr_int_bit)) &&
-	    (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared))
-	    pcibr_int_bits &= ~(1 << pcibr_int_bit);
-    if (!pcibr_int_bits)
-	return;
-
-    s = pcibr_lock(pcibr_soft);
-    b_int_enable = bridge->b_int_enable;
-    b_int_enable &= ~pcibr_int_bits;
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    /* if the interrupt line is now shared,
-	     * do not disconnect it.
-	     */
-	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
-		continue;
-
-	    xtalk_intr_disconnect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
-	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 0;
-
-#if DEBUG && INTR_DEBUG
-	    printk("%s: xtalk disconnect done for Bridge bit %d\n",
-		pcibr_soft->bs_name, pcibr_int_bit);
-#endif
-
-	    /* if we are sharing the interrupt line,
-	     * connect us up; this closes the hole
-	     * where the another pcibr_intr_alloc()
-	     * was in progress as we disconnected.
-	     */
-	    if (!pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
-		continue;
-
-	    xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr,
-			       (xtalk_intr_setfunc_t)pcibr_setpciint,
-			       (void *) &(bridge->b_int_addr[pcibr_int_bit].addr));
-	}
-}
-
-/*ARGSUSED */
-devfs_handle_t
-pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit))
-	    return xtalk_intr_cpu_get(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
-    return 0;
-}
-
-/* =====================================================================
- *    INTERRUPT HANDLING
- */
-LOCAL void
-pcibr_clearwidint(bridge_t *bridge)
-{
-    bridge->b_wid_int_upper = 0;
-    bridge->b_wid_int_lower = 0;
-}
-
-LOCAL void
-pcibr_setwidint(xtalk_intr_t intr)
-{
-    xwidgetnum_t            targ = xtalk_intr_target_get(intr);
-    iopaddr_t               addr = xtalk_intr_addr_get(intr);
-    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);
-    widgetreg_t		    NEW_b_wid_int_upper, NEW_b_wid_int_lower;
-    widgetreg_t		    OLD_b_wid_int_upper, OLD_b_wid_int_lower;
-
-    bridge_t               *bridge = (bridge_t *)xtalk_intr_sfarg_get(intr);
-
-    NEW_b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
-			       XTALK_ADDR_TO_UPPER(addr));
-    NEW_b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-
-    OLD_b_wid_int_upper = bridge->b_wid_int_upper;
-    OLD_b_wid_int_lower = bridge->b_wid_int_lower;
-
-    /* Verify that all interrupts from this Bridge are using a single PI */
-    if ((OLD_b_wid_int_upper != 0) && (OLD_b_wid_int_lower != 0)) {
-	/*
-	 * Once set, these registers shouldn't change; they should
-	 * be set multiple times with the same values.
-	 *
-	 * If we're attempting to change these registers, it means
-	 * that our heuristics for allocating interrupts in a way
-	 * appropriate for IP35 have failed, and the admin needs to
-	 * explicitly direct some interrupts (or we need to make the
-	 * heuristics more clever).
-	 *
-	 * In practice, we hope this doesn't happen very often, if
-	 * at all.
-	 */
-	if ((OLD_b_wid_int_upper != NEW_b_wid_int_upper) ||
-	    (OLD_b_wid_int_lower != NEW_b_wid_int_lower)) {
-		printk(KERN_WARNING  "Interrupt allocation is too complex.\n");
-		printk(KERN_WARNING  "Use explicit administrative interrupt targetting.\n");
-		printk(KERN_WARNING  "bridge=0x%lx targ=0x%x\n", (unsigned long)bridge, targ);
-		printk(KERN_WARNING  "NEW=0x%x/0x%x  OLD=0x%x/0x%x\n",
-			NEW_b_wid_int_upper, NEW_b_wid_int_lower,
-			OLD_b_wid_int_upper, OLD_b_wid_int_lower);
-		PRINT_PANIC("PCI Bridge interrupt targetting error\n");
-	}
-    }
-
-    bridge->b_wid_int_upper = NEW_b_wid_int_upper;
-    bridge->b_wid_int_lower = NEW_b_wid_int_lower;
-    bridge->b_int_host_err = vect;
-}
-
-/*
- * pcibr_intr_preset: called during mlreset time
- * if the platform specific code needs to route
- * one of the Bridge's xtalk interrupts before the
- * xtalk infrastructure is available.
- */
-void
-pcibr_xintr_preset(void *which_widget,
-		   int which_widget_intr,
-		   xwidgetnum_t targ,
-		   iopaddr_t addr,
-		   xtalk_intr_vector_t vect)
-{
-    bridge_t               *bridge = (bridge_t *) which_widget;
-
-    if (which_widget_intr == -1) {
-	/* bridge widget error interrupt */
-	bridge->b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
-				   XTALK_ADDR_TO_UPPER(addr));
-	bridge->b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-	bridge->b_int_host_err = vect;
-
-	/* turn on all interrupts except
-	 * the PCI interrupt requests,
-	 * at least at heart.
-	 */
-	bridge->b_int_enable |= ~BRIDGE_IMR_INT_MSK;
-
-    } else {
-	/* routing a PCI device interrupt.
-	 * targ and low 38 bits of addr must
-	 * be the same as the already set
-	 * value for the widget error interrupt.
-	 */
-	bridge->b_int_addr[which_widget_intr].addr =
-	    ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
-	     (BRIDGE_INT_ADDR_FLD & vect));
-	/*
-	 * now bridge can let it through;
-	 * NB: still should be blocked at
-	 * xtalk provider end, until the service
-	 * function is set.
-	 */
-	bridge->b_int_enable |= 1 << vect;
-    }
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-}
-
-
-/*
- * pcibr_intr_func()
- *
- * This is the pcibr interrupt "wrapper" function that is called,
- * in interrupt context, to initiate the interrupt handler(s) registered
- * (via pcibr_intr_alloc/connect) for the occuring interrupt. Non-threaded 
- * handlers will be called directly, and threaded handlers will have their 
- * thread woken up.
- */
-void
-pcibr_intr_func(intr_arg_t arg)
-{
-    pcibr_intr_wrap_t       wrap = (pcibr_intr_wrap_t) arg;
-    reg_p                   wrbf;
-    pcibr_intr_t            intr;
-    pcibr_intr_list_t       list;
-    int                     clearit;
-    int			    do_nonthreaded = 1;
-    int			    is_threaded = 0;
-    int			    x = 0;
-
-	/*
-	 * If any handler is still running from a previous interrupt
-	 * just return. If there's a need to call the handler(s) again,
-	 * another interrupt will be generated either by the device or by
-	 * pcibr_force_interrupt().
-	 */
-
-	if (wrap->iw_hdlrcnt) {
-		return;
-	}
-
-    /*
-     * Call all interrupt handlers registered.
-     * First, the pcibr_intrd threads for any threaded handlers will be
-     * awoken, then any non-threaded handlers will be called sequentially.
-     */
-	
-	clearit = 1;
-	while (do_nonthreaded) {
-	    for (list = wrap->iw_list; list != NULL; list = list->il_next) {
-		if ((intr = list->il_intr) &&
-		    (intr->bi_flags & PCIIO_INTR_CONNECTED)) {
-
-		/*
-		 * This device may have initiated write
-		 * requests since the bridge last saw
-		 * an edge on this interrupt input; flushing
-		 * the buffer prior to invoking the handler
-		 * should help but may not be sufficient if we 
-		 * get more requests after the flush, followed
-		 * by the card deciding it wants service, before
-		 * the interrupt handler checks to see if things need
-		 * to be done.
-		 *
-		 * There is a similar race condition if
-		 * an interrupt handler loops around and
-		 * notices further service is required.
-		 * Perhaps we need to have an explicit
-		 * call that interrupt handlers need to
-		 * do between noticing that DMA to memory
-		 * has completed, but before observing the
-		 * contents of memory?
-		 */
-
-			if ((do_nonthreaded) && (!is_threaded)) {
-			/* Non-threaded. 
-			 * Call the interrupt handler at interrupt level
-			 */
-
-			/* Only need to flush write buffers if sharing */
-
-			if ((wrap->iw_shared) && (wrbf = list->il_wrbf)) {
-			    if ((x = *wrbf))	/* write request buffer flush */
-#ifdef SUPPORT_PRINTING_V_FORMAT
-				printk(KERN_ALERT  "pcibr_intr_func %v: \n"
-				    "write buffer flush failed, wrbf=0x%x\n", 
-				    list->il_intr->bi_dev, wrbf);
-#else
-				printk(KERN_ALERT  "pcibr_intr_func %p: \n"
-				    "write buffer flush failed, wrbf=0x%lx\n", 
-				    (void *)list->il_intr->bi_dev, (long) wrbf);
-#endif
-			}
-		    }
-
-		    clearit = 0;
-		}
-	    }
-
-		do_nonthreaded = 0;
-		/*
-		 * If the non-threaded handler was the last to complete,
-		 * (i.e., no threaded handlers still running) force an
-		 * interrupt to avoid a potential deadlock situation.
-		 */
-		if (wrap->iw_hdlrcnt == 0) {
-			pcibr_force_interrupt(wrap);
-		}
-	}
-
-	/* If there were no handlers,
-	 * disable the interrupt and return.
-	 * It will get enabled again after
-	 * a handler is connected.
-	 * If we don't do this, we would
-	 * sit here and spin through the
-	 * list forever.
-	 */
-	if (clearit) {
-	    pcibr_soft_t            pcibr_soft = wrap->iw_soft;
-	    bridge_t               *bridge = pcibr_soft->bs_base;
-	    bridgereg_t             b_int_enable;
-	    bridgereg_t		    mask = 1 << wrap->iw_intr;
-	    unsigned long           s;
-
-	    s = pcibr_lock(pcibr_soft);
-	    b_int_enable = bridge->b_int_enable;
-	    b_int_enable &= ~mask;
-	    bridge->b_int_enable = b_int_enable;
-	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	    pcibr_unlock(pcibr_soft, s);
-	    return;
-	}
-}
-
-/* =====================================================================
- *    CONFIGURATION MANAGEMENT
- */
-/*ARGSUSED */
-void
-pcibr_provider_startup(devfs_handle_t pcibr)
-{
-}
-
-/*ARGSUSED */
-void
-pcibr_provider_shutdown(devfs_handle_t pcibr)
-{
-}
-
-int
-pcibr_reset(devfs_handle_t conn)
-{
-    pciio_info_t            pciio_info = pciio_info_get(conn);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    bridgereg_t             ctlreg;
-    unsigned                cfgctl[8];
-    unsigned long           s;
-    int                     f, nf;
-    pcibr_info_h            pcibr_infoh;
-    pcibr_info_t            pcibr_info;
-    int                     win;
-
-    if (pcibr_soft->bs_slot[pciio_slot].has_host) {
-	pciio_slot = pcibr_soft->bs_slot[pciio_slot].host_slot;
-	pcibr_info = pcibr_soft->bs_slot[pciio_slot].bss_infos[0];
-    }
-    if (pciio_slot < 4) {
-	s = pcibr_lock(pcibr_soft);
-	nf = pcibr_soft->bs_slot[pciio_slot].bss_ninfo;
-	pcibr_infoh = pcibr_soft->bs_slot[pciio_slot].bss_infos;
-	for (f = 0; f < nf; ++f)
-	    if (pcibr_infoh[f])
-		cfgctl[f] = bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4];
-
-	ctlreg = bridge->b_wid_control;
-	bridge->b_wid_control = ctlreg | BRIDGE_CTRL_RST(pciio_slot);
-	/* XXX delay? */
-	bridge->b_wid_control = ctlreg;
-	/* XXX delay? */
-
-	for (f = 0; f < nf; ++f)
-	    if ((pcibr_info = pcibr_infoh[f]))
-		for (win = 0; win < 6; ++win)
-		    if (pcibr_info->f_window[win].w_base != 0)
-			bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_BASE_ADDR(win) / 4] =
-			    pcibr_info->f_window[win].w_base;
-	for (f = 0; f < nf; ++f)
-	    if (pcibr_infoh[f])
-		bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4] = cfgctl[f];
-	pcibr_unlock(pcibr_soft, s);
-
-	return 0;
-    }
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    printk(KERN_WARNING   "%v: pcibr_reset unimplemented for slot %d\n",
-	    conn, pciio_slot);
-#endif
-    return -1;
-}
-
-pciio_endian_t
-pcibr_endian_set(devfs_handle_t pconn_vhdl,
-		 pciio_endian_t device_end,
-		 pciio_endian_t desired_end)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridgereg_t             devreg;
-    unsigned long           s;
-
-    /*
-     * Bridge supports hardware swapping; so we can always
-     * arrange for the caller's desired endianness.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-    if (device_end != desired_end)
-	devreg |= BRIDGE_DEV_SWAP_BITS;
-    else
-	devreg &= ~BRIDGE_DEV_SWAP_BITS;
-
-    /* NOTE- if we ever put SWAP bits
-     * onto the disabled list, we will
-     * have to change the logic here.
-     */
-    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	bridge->b_device[pciio_slot].reg = devreg;
-	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-#if DEBUG && PCIBR_DEV_DEBUG
-    printk("pcibr Device(%d): 0x%p\n", pciio_slot, bridge->b_device[pciio_slot].reg);
-#endif
-
-    return desired_end;
-}
-
-/* This (re)sets the GBR and REALTIME bits and also keeps track of how
- * many sets are outstanding. Reset succeeds only if the number of outstanding
- * sets == 1.
- */
-int
-pcibr_priority_bits_set(pcibr_soft_t pcibr_soft,
-			pciio_slot_t pciio_slot,
-			pciio_priority_t device_prio)
-{
-    unsigned long           s;
-    int                    *counter;
-    bridgereg_t             rtbits = 0;
-    bridgereg_t             devreg;
-    int                     rc = PRIO_SUCCESS;
-
-    /* in dual-slot configurations, the host and the
-     * guest have separate DMA resources, so they
-     * have separate requirements for priority bits.
-     */
-
-    counter = &(pcibr_soft->bs_slot[pciio_slot].bss_pri_uctr);
-
-    /*
-     * Bridge supports PCI notions of LOW and HIGH priority
-     * arbitration rings via a "REAL_TIME" bit in the per-device
-     * Bridge register. The "GBR" bit controls access to the GBR
-     * ring on the xbow. These two bits are (re)set together.
-     *
-     * XXX- Bug in Rev B Bridge Si:
-     * Symptom: Prefetcher starts operating incorrectly. This happens
-     * due to corruption of the address storage ram in the prefetcher
-     * when a non-real time PCI request is pulled and a real-time one is
-     * put in it's place. Workaround: Use only a single arbitration ring
-     * on PCI bus. GBR and RR can still be uniquely used per
-     * device. NETLIST MERGE DONE, WILL BE FIXED IN REV C.
-     */
-
-    if (pcibr_soft->bs_rev_num != BRIDGE_PART_REV_B)
-	rtbits |= BRIDGE_DEV_RT;
-
-    /* NOTE- if we ever put DEV_RT or DEV_GBR on
-     * the disabled list, we will have to take
-     * it into account here.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-    if (device_prio == PCI_PRIO_HIGH) {
-	if ((++*counter == 1)) {
-	    if (rtbits)
-		devreg |= rtbits;
-	    else
-		rc = PRIO_FAIL;
-	}
-    } else if (device_prio == PCI_PRIO_LOW) {
-	if (*counter <= 0)
-	    rc = PRIO_FAIL;
-	else if (--*counter == 0)
-	    if (rtbits)
-		devreg &= ~rtbits;
-    }
-    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	bridge->b_device[pciio_slot].reg = devreg;
-	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-    return rc;
-}
-
-pciio_priority_t
-pcibr_priority_set(devfs_handle_t pconn_vhdl,
-		   pciio_priority_t device_prio)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    (void) pcibr_priority_bits_set(pcibr_soft, pciio_slot, device_prio);
-
-    return device_prio;
-}
-
-/*
- * Interfaces to allow special (e.g. SGI) drivers to set/clear
- * Bridge-specific device flags.  Many flags are modified through
- * PCI-generic interfaces; we don't allow them to be directly
- * manipulated here.  Only flags that at this point seem pretty
- * Bridge-specific can be set through these special interfaces.
- * We may add more flags as the need arises, or remove flags and
- * create PCI-generic interfaces as the need arises.
- *
- * Returns 0 on failure, 1 on success
- */
-int
-pcibr_device_flags_set(devfs_handle_t pconn_vhdl,
-		       pcibr_device_flags_t flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridgereg_t             set = 0;
-    bridgereg_t             clr = 0;
-
-    ASSERT((flags & PCIBR_DEVICE_FLAGS) == flags);
-
-    if (flags & PCIBR_WRITE_GATHER)
-	set |= BRIDGE_DEV_PMU_WRGA_EN;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	clr |= BRIDGE_DEV_PMU_WRGA_EN;
-
-    if (flags & PCIBR_WRITE_GATHER)
-	set |= BRIDGE_DEV_DIR_WRGA_EN;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	clr |= BRIDGE_DEV_DIR_WRGA_EN;
-
-    if (flags & PCIBR_PREFETCH)
-	set |= BRIDGE_DEV_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	clr |= BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	set |= BRIDGE_DEV_PRECISE;
-    if (flags & PCIBR_NOPRECISE)
-	clr |= BRIDGE_DEV_PRECISE;
-
-    if (flags & PCIBR_BARRIER)
-	set |= BRIDGE_DEV_BARRIER;
-    if (flags & PCIBR_NOBARRIER)
-	clr |= BRIDGE_DEV_BARRIER;
-
-    if (flags & PCIBR_64BIT)
-	set |= BRIDGE_DEV_DEV_SIZE;
-    if (flags & PCIBR_NO64BIT)
-	clr |= BRIDGE_DEV_DEV_SIZE;
-
-    if (set || clr) {
-	bridgereg_t             devreg;
-	unsigned long           s;
-
-	s = pcibr_lock(pcibr_soft);
-	devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-	devreg = (devreg & ~clr) | set;
-	if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	    bridge_t               *bridge = pcibr_soft->bs_base;
-
-	    bridge->b_device[pciio_slot].reg = devreg;
-	    pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	}
-	pcibr_unlock(pcibr_soft, s);
-#if DEBUG && PCIBR_DEV_DEBUG
-	printk("pcibr Device(%d): %R\n", pciio_slot, bridge->b_device[pciio_slot].regbridge->b_device[pciio_slot].reg, device_bits);
-#endif
-    }
-    return (1);
-}
-
-#ifdef LITTLE_ENDIAN
-/*
- * on sn-ia we need to twiddle the addresses going out
- * the pci bus because we use the unswizzled synergy space
- * (the alternative is to use the swizzled synergy space
- * and byte swap the data)
- */
-#define	CB(b,r)	(((volatile uint8_t *) b)[((r)^4)])
-#define	CS(b,r)	(((volatile uint16_t *) b)[((r^4)/2)])
-#define	CW(b,r)	(((volatile uint32_t *) b)[((r^4)/4)])
-#else
-#define	CB(b,r)	(((volatile uint8_t *) cfgbase)[(r)^3])
-#define	CS(b,r)	(((volatile uint16_t *) cfgbase)[((r)/2)^1])
-#define	CW(b,r)	(((volatile uint32_t *) cfgbase)[(r)/4])
-#endif /* LITTLE_ENDIAN */
-
-
-LOCAL                   cfg_p
-pcibr_config_addr(devfs_handle_t conn,
-		  unsigned reg)
-{
-    pcibr_info_t            pcibr_info;
-    pciio_slot_t            pciio_slot;
-    pciio_function_t        pciio_func;
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge;
-    cfg_p                   cfgbase = (cfg_p)0;
-
-    pcibr_info = pcibr_info_get(conn);
-
-    pciio_slot = pcibr_info->f_slot;
-    if (pciio_slot == PCIIO_SLOT_NONE)
-	pciio_slot = PCI_TYPE1_SLOT(reg);
-
-    pciio_func = pcibr_info->f_func;
-    if (pciio_func == PCIIO_FUNC_NONE)
-	pciio_func = PCI_TYPE1_FUNC(reg);
-
-    pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-
-    bridge = pcibr_soft->bs_base;
-
-    cfgbase = bridge->b_type0_cfg_dev[pciio_slot].f[pciio_func].l;
-
-    return cfgbase;
-}
-
-uint64_t
-pcibr_config_get(devfs_handle_t conn,
-		 unsigned reg,
-		 unsigned size)
-{
-    return do_pcibr_config_get(pcibr_config_addr(conn, reg),
-			       PCI_TYPE1_REG(reg), size);
-}
-
-LOCAL uint64_t
-do_pcibr_config_get(
-		       cfg_p cfgbase,
-		       unsigned reg,
-		       unsigned size)
-{
-    unsigned                value;
-
-   
-    value = CW(cfgbase, reg);
-
-    if (reg & 3)
-	value >>= 8 * (reg & 3);
-    if (size < 4)
-	value &= (1 << (8 * size)) - 1;
-
-    return value;
-}
-
-void
-pcibr_config_set(devfs_handle_t conn,
-		 unsigned reg,
-		 unsigned size,
-		 uint64_t value)
-{
-    do_pcibr_config_set(pcibr_config_addr(conn, reg),
-			PCI_TYPE1_REG(reg), size, value);
-}
-
-LOCAL void
-do_pcibr_config_set(cfg_p cfgbase,
-		    unsigned reg,
-		    unsigned size,
-		    uint64_t value)
-{
-    switch (size) {
-    case 1:
-	CB(cfgbase, reg) = value;
-	break;
-    case 2:
-	if (reg & 1) {
-	    CB(cfgbase, reg) = value;
-	    CB(cfgbase, reg + 1) = value >> 8;
-	} else
-	    CS(cfgbase, reg) = value;
-	break;
-    case 3:
-	if (reg & 1) {
-	    CB(cfgbase, reg) = value;
-	    CS(cfgbase, (reg + 1)) = value >> 8;
-	} else {
-	    CS(cfgbase, reg) = value;
-	    CB(cfgbase, reg + 2) = value >> 16;
-	}
-	break;
-
-    case 4:
-	CW(cfgbase, reg) = value;
-	break;
-    }
-}
-
-pciio_provider_t        pcibr_provider =
-{
-    (pciio_piomap_alloc_f *) pcibr_piomap_alloc,
-    (pciio_piomap_free_f *) pcibr_piomap_free,
-    (pciio_piomap_addr_f *) pcibr_piomap_addr,
-    (pciio_piomap_done_f *) pcibr_piomap_done,
-    (pciio_piotrans_addr_f *) pcibr_piotrans_addr,
-    (pciio_piospace_alloc_f *) pcibr_piospace_alloc,
-    (pciio_piospace_free_f *) pcibr_piospace_free,
-
-    (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
-    (pciio_dmamap_free_f *) pcibr_dmamap_free,
-    (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
-    (pciio_dmamap_list_f *) pcibr_dmamap_list,
-    (pciio_dmamap_done_f *) pcibr_dmamap_done,
-    (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
-    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
-    (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
-    (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
-    (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
-
-    (pciio_intr_alloc_f *) pcibr_intr_alloc,
-    (pciio_intr_free_f *) pcibr_intr_free,
-    (pciio_intr_connect_f *) pcibr_intr_connect,
-    (pciio_intr_disconnect_f *) pcibr_intr_disconnect,
-    (pciio_intr_cpu_get_f *) pcibr_intr_cpu_get,
-
-    (pciio_provider_startup_f *) pcibr_provider_startup,
-    (pciio_provider_shutdown_f *) pcibr_provider_shutdown,
-    (pciio_reset_f *) pcibr_reset,
-    (pciio_write_gather_flush_f *) pcibr_write_gather_flush,
-    (pciio_endian_set_f *) pcibr_endian_set,
-    (pciio_priority_set_f *) pcibr_priority_set,
-    (pciio_config_get_f *) pcibr_config_get,
-    (pciio_config_set_f *) pcibr_config_set,
-
-    (pciio_error_devenable_f *) 0,
-    (pciio_error_extract_f *) 0,
-
-#ifdef LATER
-    (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,
-    (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,
-#else
-    (pciio_driver_reg_callback_f *) 0,
-    (pciio_driver_unreg_callback_f *) 0,
-#endif
-    (pciio_device_unregister_f 	*) pcibr_device_unregister,
-    (pciio_dma_enabled_f		*) pcibr_dma_enabled,
-};
-
-LOCAL                   pcibr_hints_t
-pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc)
-{
-    arbitrary_info_t        ainfo = 0;
-    graph_error_t	    rv;
-    pcibr_hints_t           hint;
-
-    rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
-
-    if (alloc && (rv != GRAPH_SUCCESS)) {
-
-	NEW(hint);
-	hint->rrb_alloc_funct = NULL;
-	hint->ph_intr_bits = NULL;
-	rv = hwgraph_info_add_LBL(xconn_vhdl, 
-				  INFO_LBL_PCIBR_HINTS, 	
-				  (arbitrary_info_t) hint);
-	if (rv != GRAPH_SUCCESS)
-	    goto abnormal_exit;
-
-	rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
-	
-	if (rv != GRAPH_SUCCESS)
-	    goto abnormal_exit;
-
-	if (ainfo != (arbitrary_info_t) hint)
-	    goto abnormal_exit;
-    }
-    return (pcibr_hints_t) ainfo;
-
-abnormal_exit:
-#ifdef LATER
-    printf("SHOULD NOT BE HERE\n");
-#endif
-    DEL(hint);
-    return(NULL);
-
-}
-
-void
-pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_rrb_fixed = mask;
-#if DEBUG
-    else
-	printk("pcibr_hints_fix_rrbs: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl)
-{
-    pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF);
-}
-
-void
-pcibr_hints_dualslot(devfs_handle_t xconn_vhdl,
-		     pciio_slot_t host,
-		     pciio_slot_t guest)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_host_slot[guest] = host + 1;
-#if DEBUG
-    else
-	printk("pcibr_hints_dualslot: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl,
-		      pcibr_intr_bits_f *xxx_intr_bits)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_intr_bits = xxx_intr_bits;
-#if DEBUG
-    else
-	printk("pcibr_hints_intr_bits: pcibr_hints_get failed at\n"
-	       "\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->rrb_alloc_funct = rrb_alloc_funct;
-}
-
-void
-pcibr_hints_handsoff(devfs_handle_t xconn_vhdl)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_hands_off = 1;
-#if DEBUG
-    else
-	printk("pcibr_hints_handsoff: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
-		    pciio_slot_t slot,
-		    uint64_t subdevs)
-{
-    arbitrary_info_t        ainfo = 0;
-    char                    sdname[16];
-    devfs_handle_t            pconn_vhdl = GRAPH_VERTEX_NONE;
-
-    sprintf(sdname, "pci/%d", slot);
-    (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
-    if (pconn_vhdl == GRAPH_VERTEX_NONE) {
-#if DEBUG
-	printk("pcibr_hints_subdevs: hwgraph_path_create failed at\n"
-		"\t%p (seeking %s)\n", xconn_vhdl, sdname);
-#endif
-	return;
-    }
-    hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
-    if (ainfo == 0) {
-	uint64_t                *subdevp;
-
-	NEW(subdevp);
-	if (!subdevp) {
-#if DEBUG
-	    printk("pcibr_hints_subdevs: subdev ptr alloc failed at\n"
-		    "\t%p\n", pconn_vhdl);
-#endif
-	    return;
-	}
-	*subdevp = subdevs;
-	hwgraph_info_add_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, (arbitrary_info_t) subdevp);
-	hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
-	if (ainfo == (arbitrary_info_t) subdevp)
-	    return;
-	DEL(subdevp);
-	if (ainfo == (arbitrary_info_t) NULL) {
-#if DEBUG
-	    printk("pcibr_hints_subdevs: null subdevs ptr at\n"
-		    "\t%p\n", pconn_vhdl);
-#endif
-	    return;
-	}
-#if DEBUG
-	printk("pcibr_subdevs_get: dup subdev add_LBL at\n"
-		"\t%p\n", pconn_vhdl);
-#endif
-    }
-    *(uint64_t *) ainfo = subdevs;
-}
-
-
-#ifdef LATER
-
-#include <sys/idbg.h>
-#include <sys/idbgentry.h>
-
-char *pci_space[] = {"NONE", 
-		     "ROM",
-		     "IO",
-		     "",
-		     "MEM",
-		     "MEM32",
-		     "MEM64",
-		     "CFG",
-		     "WIN0",
-		     "WIN1",
-		     "WIN2",
-		     "WIN3",
-		     "WIN4",
-		     "WIN5",
-		     "",
-		     "BAD"};
-
-void
-idbg_pss_func(pcibr_info_h pcibr_infoh, int func)
-{
-    pcibr_info_t	pcibr_info = pcibr_infoh[func];
-    char		name[MAXDEVNAME];
-    int			win;
-    
-    if (!pcibr_info)
-	return;
-    qprintf("Per-slot Function Info\n");
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(name, "%v", pcibr_info->f_vertex);
-#endif
-    qprintf("\tSlot Name : %s\n",name);
-    qprintf("\tPCI Bus : %d ",pcibr_info->f_bus);
-    qprintf("Slot : %d ", pcibr_info->f_slot);
-    qprintf("Function : %d ", pcibr_info->f_func);
-    qprintf("VendorId : 0x%x " , pcibr_info->f_vendor);
-    qprintf("DeviceId : 0x%x\n", pcibr_info->f_device);
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(name, "%v", pcibr_info->f_master);
-#endif
-    qprintf("\tBus provider : %s\n",name);
-    qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops);
-    qprintf("Error Handler : 0x%x Arg 0x%x\n", 
-	    pcibr_info->f_efunc,pcibr_info->f_einfo);
-    for(win = 0 ; win < 6 ; win++) 
-	qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n",
-		win,pci_space[pcibr_info->f_window[win].w_space],
-		pcibr_info->f_window[win].w_base,
-		pcibr_info->f_window[win].w_size);
-
-    qprintf("\tRom base 0x%x size 0x%x\n", 
-	    pcibr_info->f_rbase,pcibr_info->f_rsize);
-
-    qprintf("\tInterrupt Bit Map\n");
-    qprintf("\t\tPCI Int#\tBridge Pin#\n");
-    for (win = 0 ; win < 4; win++)
-	qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]);
-    qprintf("\n");
-}
-
-
-void
-idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot)
-{
-    pcibr_soft_slot_t	pss;
-    char		slot_conn_name[MAXDEVNAME];
-    int			func;
-
-    pss = &pcibr_soft->bs_slot[slot];
-    qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot);
-    qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no");
-    qprintf("\tHost Slot : %d\n",pss->host_slot);
-    sprintf(slot_conn_name, "%v", pss->slot_conn);
-    qprintf("\tSlot Conn : %s\n",slot_conn_name);	
-    qprintf("\t#Functions : %d\n",pss->bss_ninfo);
-    for (func = 0; func < pss->bss_ninfo; func++)
-	idbg_pss_func(pss->bss_infos,func);
-    qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]);
-    qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base);
-    qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device);
-    qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n",
-	    pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr);
-    
-    qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x"
-	    "d32_base 0x%x d32_flags 0x%x\n",
-	    pss->bss_d64_base, pss->bss_d64_flags,
-	    pss->bss_d32_base, pss->bss_d32_flags);
-    
-    qprintf("\tExt ATEs active ? %s", 
-	    atomic_read(&pss->bss_ext_ates_active) ? "yes" : "no");
-    qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer);
-    qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow);
-
-    qprintf("\tRRB Info : Valid %d+%d Reserved %d\n",
-	    pcibr_soft->bs_rrb_valid[slot],
-	    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-		
-}
-
-int	ips = 0;
-
-void
-idbg_pss(pcibr_soft_t pcibr_soft)
-{
-    pciio_slot_t	slot;
-
-    
-    if (ips >= 0 && ips < 8)
-	idbg_pss_info(pcibr_soft,ips);
-    else if (ips < 0)
-	for (slot = 0; slot < 8; slot++) 
-	    idbg_pss_info(pcibr_soft,slot);
-    else
-	qprintf("Invalid ips %d\n",ips);
-}
-
-#endif /* LATER */
-
-int
-pcibr_dma_enabled(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-	
-
-    return xtalk_dma_enabled(pcibr_soft->bs_conn);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/pciio.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/pciio.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/pciio.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/pciio.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1681 +0,0 @@
-/* $Id: pciio.c,v 1.2 2002/11/16 02:23:19 steiner Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#define	USRPCI	0
-
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/xtalk/xbow.h>	/* Must be before iograph.h to get MAX_PORT_NUM */
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pciio_private.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/ate_utils.h>
-#include <asm/sn/simulator.h>
-
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
-#define DEBUG_PCIIO
-#undef DEBUG_PCIIO	/* turn this on for yet more console output */
-
-
-#define GET_NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DO_DEL(ptr)	(kfree(ptr))
-
-char                    pciio_info_fingerprint[] = "pciio_info";
-
-cdl_p                   pciio_registry = NULL;
-
-int
-badaddr_val(volatile void *addr, int len, volatile void *ptr)
-{
-	int ret = 0;
-	volatile void *new_addr;
-
-	switch (len) {
-		case 4:
-			new_addr = (void *)(((u64) addr)^4);
-			ret = ia64_sn_probe_io_slot((long)new_addr, len, (void *)ptr);
-			break;
-		default:
-			printk(KERN_WARNING "badaddr_val given len %x but supports len of 4 only\n", len);
-	}
-
-	if (ret < 0)
-		panic("badaddr_val: unexpected status (%d) in probing", ret);
-	return(ret);
-
-}
-
-
-nasid_t
-get_console_nasid(void)
-{
-	extern nasid_t console_nasid;
-	if (console_nasid < 0) {
-		console_nasid = ia64_sn_get_console_nasid();
-		if (console_nasid < 0) {
-// ZZZ What do we do if we don't get a console nasid on the hardware????
-			if (IS_RUNNING_ON_SIMULATOR() )
-				console_nasid = master_nasid;
-		}
-	} 
-	return console_nasid;
-}
-
-int
-hub_dma_enabled(devfs_handle_t xconn_vhdl)
-{
-	return(0);
-}
-
-int
-hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
-{
-	return(0);
-}
-
-void
-ioerror_dump(char *name, int error_code, int error_mode, ioerror_t *ioerror)
-{
-}
-
-/******
- ****** end hack defines ......
- ******/
-
-
-
-
-/* =====================================================================
- *    PCI Generic Bus Provider
- * Implement PCI provider operations.  The pciio* layer provides a
- * platform-independent interface for PCI devices.  This layer
- * switches among the possible implementations of a PCI adapter.
- */
-
-/* =====================================================================
- *    Provider Function Location SHORTCUT
- *
- * On platforms with only one possible PCI provider, macros can be
- * set up at the top that cause the table lookups and indirections to
- * completely disappear.
- */
-
-/*
- *    For the moment, we will assume that IP27
- *      only use Bridge ASICs to provide PCI support.
- */
-#include <asm/sn/pci/pcibr.h>
-#define DEV_FUNC(dev,func)	pcibr_##func
-#define CAST_PIOMAP(x)		((pcibr_piomap_t)(x))
-#define CAST_DMAMAP(x)		((pcibr_dmamap_t)(x))
-#define CAST_INTR(x)		((pcibr_intr_t)(x))
-
-/* =====================================================================
- *    Function Table of Contents
- */
-
-#if !defined(DEV_FUNC)
-static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev);
-#endif
-
-pciio_piomap_t          pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
-void                    pciio_piomap_free(pciio_piomap_t);
-caddr_t                 pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t);
-
-void                    pciio_piomap_done(pciio_piomap_t);
-caddr_t                 pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-caddr_t			pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
-
-iopaddr_t               pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
-
-pciio_dmamap_t          pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    pciio_dmamap_free(pciio_dmamap_t);
-iopaddr_t               pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-alenlist_t              pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned);
-void                    pciio_dmamap_done(pciio_dmamap_t);
-iopaddr_t               pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void			pciio_dmamap_drain(pciio_dmamap_t);
-void			pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void			pciio_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
-
-pciio_intr_t            pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
-void                    pciio_intr_free(pciio_intr_t);
-int                     pciio_intr_connect(pciio_intr_t);
-void                    pciio_intr_disconnect(pciio_intr_t);
-devfs_handle_t            pciio_intr_cpu_get(pciio_intr_t);
-
-void			pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t);
-
-void                    pciio_provider_startup(devfs_handle_t);
-void                    pciio_provider_shutdown(devfs_handle_t);
-
-pciio_endian_t          pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-pciio_priority_t        pciio_priority_set(devfs_handle_t, pciio_priority_t);
-devfs_handle_t            pciio_intr_dev_get(pciio_intr_t);
-
-devfs_handle_t            pciio_pio_dev_get(pciio_piomap_t);
-pciio_slot_t            pciio_pio_slot_get(pciio_piomap_t);
-pciio_space_t           pciio_pio_space_get(pciio_piomap_t);
-iopaddr_t               pciio_pio_pciaddr_get(pciio_piomap_t);
-ulong                   pciio_pio_mapsz_get(pciio_piomap_t);
-caddr_t                 pciio_pio_kvaddr_get(pciio_piomap_t);
-
-devfs_handle_t            pciio_dma_dev_get(pciio_dmamap_t);
-pciio_slot_t            pciio_dma_slot_get(pciio_dmamap_t);
-
-pciio_info_t            pciio_info_chk(devfs_handle_t);
-pciio_info_t            pciio_info_get(devfs_handle_t);
-void                    pciio_info_set(devfs_handle_t, pciio_info_t);
-devfs_handle_t            pciio_info_dev_get(pciio_info_t);
-pciio_slot_t            pciio_info_slot_get(pciio_info_t);
-pciio_function_t        pciio_info_function_get(pciio_info_t);
-pciio_vendor_id_t       pciio_info_vendor_id_get(pciio_info_t);
-pciio_device_id_t       pciio_info_device_id_get(pciio_info_t);
-devfs_handle_t            pciio_info_master_get(pciio_info_t);
-arbitrary_info_t        pciio_info_mfast_get(pciio_info_t);
-pciio_provider_t       *pciio_info_pops_get(pciio_info_t);
-error_handler_f	       *pciio_info_efunc_get(pciio_info_t);
-error_handler_arg_t    *pciio_info_einfo_get(pciio_info_t);
-pciio_space_t		pciio_info_bar_space_get(pciio_info_t, int);
-iopaddr_t		pciio_info_bar_base_get(pciio_info_t, int);
-size_t			pciio_info_bar_size_get(pciio_info_t, int);
-iopaddr_t		pciio_info_rom_base_get(pciio_info_t);
-size_t			pciio_info_rom_size_get(pciio_info_t);
-
-void                    pciio_init(void);
-int                     pciio_attach(devfs_handle_t);
-
-void                    pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns);
-void                    pciio_provider_unregister(devfs_handle_t);
-pciio_provider_t       *pciio_provider_fns_get(devfs_handle_t);
-
-int                     pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned);
-void                    pciio_driver_unregister(char *driver_prefix);
-
-devfs_handle_t            pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-
-void			pciio_device_unregister(devfs_handle_t);
-pciio_info_t		pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-void			pciio_device_info_free(pciio_info_t);
-devfs_handle_t		pciio_device_info_register(devfs_handle_t, pciio_info_t);
-void			pciio_device_info_unregister(devfs_handle_t, pciio_info_t);
-int                     pciio_device_attach(devfs_handle_t, int);
-int			pciio_device_detach(devfs_handle_t, int);
-void                    pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
-
-int                     pciio_reset(devfs_handle_t);
-int                     pciio_write_gather_flush(devfs_handle_t);
-int                     pciio_slot_inuse(devfs_handle_t);
-
-/* =====================================================================
- *    Provider Function Location
- *
- *      If there is more than one possible provider for
- *      this platform, we need to examine the master
- *      vertex of the current vertex for a provider
- *      function structure, and indirect through the
- *      appropriately named member.
- */
-
-#if !defined(DEV_FUNC)
-
-static pciio_provider_t *
-pciio_to_provider_fns(devfs_handle_t dev)
-{
-    pciio_info_t            card_info;
-    pciio_provider_t       *provider_fns;
-
-    /*
-     * We're called with two types of vertices, one is
-     * the bridge vertex (ends with "pci") and the other is the
-     * pci slot vertex (ends with "pci/[0-8]").  For the first type
-     * we need to get the provider from the PFUNCS label.  For
-     * the second we get it from fastinfo/c_pops.
-     */
-    provider_fns = pciio_provider_fns_get(dev);
-    if (provider_fns == NULL) {
-	card_info = pciio_info_get(dev);
-	if (card_info != NULL) {
-		provider_fns = pciio_info_pops_get(card_info);
-	}
-    }
-
-    if (provider_fns == NULL)
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	PRINT_PANIC("%v: provider_fns == NULL", dev);
-#else
-	PRINT_PANIC("0x%p: provider_fns == NULL", (void *)dev);
-#endif
-
-    return provider_fns;
-
-}
-
-#define DEV_FUNC(dev,func)	pciio_to_provider_fns(dev)->func
-#define CAST_PIOMAP(x)		((pciio_piomap_t)(x))
-#define CAST_DMAMAP(x)		((pciio_dmamap_t)(x))
-#define CAST_INTR(x)		((pciio_intr_t)(x))
-#endif
-
-/*
- * Many functions are not passed their vertex
- * information directly; rather, they must
- * dive through a resource map. These macros
- * are available to coordinate this detail.
- */
-#define PIOMAP_FUNC(map,func)		DEV_FUNC((map)->pp_dev,func)
-#define DMAMAP_FUNC(map,func)		DEV_FUNC((map)->pd_dev,func)
-#define INTR_FUNC(intr_hdl,func)	DEV_FUNC((intr_hdl)->pi_dev,func)
-
-/* =====================================================================
- *          PIO MANAGEMENT
- *
- *      For mapping system virtual address space to
- *      pciio space on a specified card
- */
-
-pciio_piomap_t
-pciio_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-		   iopaddr_t addr,	/* lowest address (or offset in window) */
-		   size_t byte_count,	/* size of region containing our mappings */
-		   size_t byte_count_max,	/* maximum size of a mapping */
-		   unsigned flags)
-{					/* defined in sys/pio.h */
-    return (pciio_piomap_t) DEV_FUNC(dev, piomap_alloc)
-	(dev, dev_desc, space, addr, byte_count, byte_count_max, flags);
-}
-
-void
-pciio_piomap_free(pciio_piomap_t pciio_piomap)
-{
-    PIOMAP_FUNC(pciio_piomap, piomap_free)
-	(CAST_PIOMAP(pciio_piomap));
-}
-
-caddr_t
-pciio_piomap_addr(pciio_piomap_t pciio_piomap,	/* mapping resources */
-		  iopaddr_t pciio_addr,	/* map for this pciio address */
-		  size_t byte_count)
-{					/* map this many bytes */
-    pciio_piomap->pp_kvaddr = PIOMAP_FUNC(pciio_piomap, piomap_addr)
-	(CAST_PIOMAP(pciio_piomap), pciio_addr, byte_count);
-
-    return pciio_piomap->pp_kvaddr;
-}
-
-void
-pciio_piomap_done(pciio_piomap_t pciio_piomap)
-{
-    PIOMAP_FUNC(pciio_piomap, piomap_done)
-	(CAST_PIOMAP(pciio_piomap));
-}
-
-caddr_t
-pciio_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-		    iopaddr_t addr,	/* starting address (or offset in window) */
-		    size_t byte_count,	/* map this many bytes */
-		    unsigned flags)
-{					/* (currently unused) */
-    return DEV_FUNC(dev, piotrans_addr)
-	(dev, dev_desc, space, addr, byte_count, flags);
-}
-
-caddr_t
-pciio_pio_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-	       iopaddr_t addr,		/* starting address (or offset in window) */
-	       size_t byte_count,	/* map this many bytes */
-	       pciio_piomap_t *mapp,	/* where to return the map pointer */
-	       unsigned flags)
-{					/* PIO flags */
-    pciio_piomap_t          map = 0;
-    int			    errfree = 0;
-    caddr_t                 res;
-
-    if (mapp) {
-	map = *mapp;			/* possible pre-allocated map */
-	*mapp = 0;			/* record "no map used" */
-    }
-
-    res = pciio_piotrans_addr
-	(dev, dev_desc, space, addr, byte_count, flags);
-    if (res)
-	return res;			/* pciio_piotrans worked */
-
-    if (!map) {
-	map = pciio_piomap_alloc
-	    (dev, dev_desc, space, addr, byte_count, byte_count, flags);
-	if (!map)
-	    return res;			/* pciio_piomap_alloc failed */
-	errfree = 1;
-    }
-
-    res = pciio_piomap_addr
-	(map, addr, byte_count);
-    if (!res) {
-	if (errfree)
-	    pciio_piomap_free(map);
-	return res;			/* pciio_piomap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* pciio_piomap_addr succeeded */
-}
-
-iopaddr_t
-pciio_piospace_alloc(devfs_handle_t dev,	/* Device requiring space */
-		     device_desc_t dev_desc,	/* Device descriptor */
-		     pciio_space_t space,	/* MEM32/MEM64/IO */
-		     size_t byte_count,	/* Size of mapping */
-		     size_t align)
-{					/* Alignment needed */
-    if (align < NBPP)
-	align = NBPP;
-    return DEV_FUNC(dev, piospace_alloc)
-	(dev, dev_desc, space, byte_count, align);
-}
-
-void
-pciio_piospace_free(devfs_handle_t dev,	/* Device freeing space */
-		    pciio_space_t space,	/* Type of space        */
-		    iopaddr_t pciaddr,	/* starting address */
-		    size_t byte_count)
-{					/* Range of address   */
-    DEV_FUNC(dev, piospace_free)
-	(dev, space, pciaddr, byte_count);
-}
-
-/* =====================================================================
- *          DMA MANAGEMENT
- *
- *      For mapping from pci space to system
- *      physical space.
- */
-
-pciio_dmamap_t
-pciio_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   size_t byte_count_max,	/* max size of a mapping */
-		   unsigned flags)
-{					/* defined in dma.h */
-    return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-	(dev, dev_desc, byte_count_max, flags);
-}
-
-void
-pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_free)
-	(CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  paddr_t paddr,	/* map for this address */
-		  size_t byte_count)
-{					/* map this many bytes */
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
-	(CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
-}
-
-alenlist_t
-pciio_dmamap_list(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_list)
-	(CAST_DMAMAP(pciio_dmamap), alenlist, flags);
-}
-
-void
-pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_done)
-	(CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-pciio_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    paddr_t paddr,	/* system physical address */
-		    size_t byte_count,	/* length */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_addr)
-	(dev, dev_desc, paddr, byte_count, flags);
-}
-
-alenlist_t
-pciio_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
-iopaddr_t
-pciio_dma_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       paddr_t paddr,		/* system physical address */
-	       size_t byte_count,	/* length */
-	       pciio_dmamap_t *mapp,	/* map to use, then map we used */
-	       unsigned flags)
-{					/* PIO flags */
-    pciio_dmamap_t          map = 0;
-    int			    errfree = 0;
-    iopaddr_t               res;
-
-    if (mapp) {
-	map = *mapp;			/* possible pre-allocated map */
-	*mapp = 0;			/* record "no map used" */
-    }
-
-    res = pciio_dmatrans_addr
-	(dev, dev_desc, paddr, byte_count, flags);
-    if (res)
-	return res;			/* pciio_dmatrans worked */
-
-    if (!map) {
-	map = pciio_dmamap_alloc
-	    (dev, dev_desc, byte_count, flags);
-	if (!map)
-	    return res;			/* pciio_dmamap_alloc failed */
-	errfree = 1;
-    }
-
-    res = pciio_dmamap_addr
-	(map, paddr, byte_count);
-    if (!res) {
-	if (errfree)
-	    pciio_dmamap_free(map);
-	return res;			/* pciio_dmamap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* pciio_dmamap_addr succeeded */
-}
-
-void
-pciio_dmamap_drain(pciio_dmamap_t map)
-{
-    DMAMAP_FUNC(map, dmamap_drain)
-	(CAST_DMAMAP(map));
-}
-
-void
-pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
-{
-    DEV_FUNC(dev, dmaaddr_drain)
-	(dev, addr, size);
-}
-
-void
-pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-	(dev, list);
-}
-
-/* =====================================================================
- *          INTERRUPT MANAGEMENT
- *
- *      Allow crosstalk devices to establish interrupts
- */
-
-/*
- * Allocate resources required for an interrupt as specified in intr_desc.
- * Return resource handle in intr_hdl.
- */
-pciio_intr_t
-pciio_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
-		 device_desc_t dev_desc,	/* device descriptor */
-		 pciio_intr_line_t lines,	/* INTR line(s) to attach */
-		 devfs_handle_t owner_dev)
-{					/* owner of this interrupt */
-    return (pciio_intr_t) DEV_FUNC(dev, intr_alloc)
-	(dev, dev_desc, lines, owner_dev);
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-pciio_intr_free(pciio_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_free)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Associate resources allocated with a previous pciio_intr_alloc call with the
- * described handler, arg, name, etc.
- *
- * Returns 0 on success, returns <0 on failure.
- */
-int
-pciio_intr_connect(pciio_intr_t intr_hdl)	/* pciio intr resource handle */
-{
-    return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-pciio_intr_disconnect(pciio_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_disconnect)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-pciio_intr_cpu_get(pciio_intr_t intr_hdl)
-{
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
-}
-
-void
-pciio_slot_func_to_name(char		       *name,
-			pciio_slot_t		slot,
-			pciio_function_t	func)
-{
-    /*
-     * standard connection points:
-     *
-     * PCIIO_SLOT_NONE:	.../pci/direct
-     * PCIIO_FUNC_NONE: .../pci/<SLOT>			ie. .../pci/3
-     * multifunction:   .../pci/<SLOT><FUNC>		ie. .../pci/3c
-     */
-
-    if (slot == PCIIO_SLOT_NONE)
-	sprintf(name, EDGE_LBL_DIRECT);
-    else if (func == PCIIO_FUNC_NONE)
-	sprintf(name, "%d", slot);
-    else
-	sprintf(name, "%d%c", slot, 'a'+func);
-}
-
-/* =====================================================================
- *          CONFIGURATION MANAGEMENT
- */
-
-/*
- * Startup a crosstalk provider
- */
-void
-pciio_provider_startup(devfs_handle_t pciio_provider)
-{
-    DEV_FUNC(pciio_provider, provider_startup)
-	(pciio_provider);
-}
-
-/*
- * Shutdown a crosstalk provider
- */
-void
-pciio_provider_shutdown(devfs_handle_t pciio_provider)
-{
-    DEV_FUNC(pciio_provider, provider_shutdown)
-	(pciio_provider);
-}
-
-/*
- * Specify endianness constraints.  The driver tells us what the device
- * does and how it would like to see things in memory.  We reply with
- * how things will actually appear in memory.
- */
-pciio_endian_t
-pciio_endian_set(devfs_handle_t dev,
-		 pciio_endian_t device_end,
-		 pciio_endian_t desired_end)
-{
-    ASSERT((device_end == PCIDMA_ENDIAN_BIG) || (device_end == PCIDMA_ENDIAN_LITTLE));
-    ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE));
-
-#if DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk(KERN_ALERT  "%v: pciio_endian_set is going away.\n"
-	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
-	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
-	    dev);
-#else
-    printk(KERN_ALERT  "0x%x: pciio_endian_set is going away.\n"
-	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
-	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
-	    dev);
-#endif
-#endif
-
-    return DEV_FUNC(dev, endian_set)
-	(dev, device_end, desired_end);
-}
-
-/*
- * Specify PCI arbitration priority.
- */
-pciio_priority_t
-pciio_priority_set(devfs_handle_t dev,
-		   pciio_priority_t device_prio)
-{
-    ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW));
-
-    return DEV_FUNC(dev, priority_set)
-	(dev, device_prio);
-}
-
-/*
- * Read value of configuration register
- */
-uint64_t
-pciio_config_get(devfs_handle_t	dev,
-		 unsigned	reg,
-		 unsigned	size)
-{
-    uint64_t	value = 0;
-    unsigned	shift = 0;
-
-    /* handle accesses that cross words here,
-     * since that's common code between all
-     * possible providers.
-     */
-    while (size > 0) {
-	unsigned	biw = 4 - (reg&3);
-	if (biw > size)
-	    biw = size;
-
-	value |= DEV_FUNC(dev, config_get)
-	    (dev, reg, biw) << shift;
-
-	shift += 8*biw;
-	reg += biw;
-	size -= biw;
-    }
-    return value;
-}
-
-/*
- * Change value of configuration register
- */
-void
-pciio_config_set(devfs_handle_t	dev,
-		 unsigned	reg,
-		 unsigned	size,
-		 uint64_t	value)
-{
-    /* handle accesses that cross words here,
-     * since that's common code between all
-     * possible providers.
-     */
-    while (size > 0) {
-	unsigned	biw = 4 - (reg&3);
-	if (biw > size)
-	    biw = size;
-	    
-	DEV_FUNC(dev, config_set)
-	    (dev, reg, biw, value);
-	reg += biw;
-	size -= biw;
-	value >>= biw * 8;
-    }
-}
-
-/* =====================================================================
- *          GENERIC PCI SUPPORT FUNCTIONS
- */
-
-/*
- * Issue a hardware reset to a card.
- */
-int
-pciio_reset(devfs_handle_t dev)
-{
-    return DEV_FUNC(dev, reset) (dev);
-}
-
-/*
- * flush write gather buffers
- */
-int
-pciio_write_gather_flush(devfs_handle_t dev)
-{
-    return DEV_FUNC(dev, write_gather_flush) (dev);
-}
-
-devfs_handle_t
-pciio_intr_dev_get(pciio_intr_t pciio_intr)
-{
-    return (pciio_intr->pi_dev);
-}
-
-/****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
-pciio_pio_dev_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_dev);
-}
-
-pciio_slot_t
-pciio_pio_slot_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_slot);
-}
-
-pciio_space_t
-pciio_pio_space_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_space);
-}
-
-iopaddr_t
-pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_pciaddr);
-}
-
-ulong
-pciio_pio_mapsz_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_mapsz);
-}
-
-caddr_t
-pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_kvaddr);
-}
-
-/****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
-pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap)
-{
-    return (pciio_dmamap->pd_dev);
-}
-
-pciio_slot_t
-pciio_dma_slot_get(pciio_dmamap_t pciio_dmamap)
-{
-    return (pciio_dmamap->pd_slot);
-}
-
-/****** Generic pci slot information interfaces ******/
-
-pciio_info_t
-pciio_info_chk(devfs_handle_t pciio)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo);
-    return (pciio_info_t) ainfo;
-}
-
-pciio_info_t
-pciio_info_get(devfs_handle_t pciio)
-{
-    pciio_info_t            pciio_info;
-
-    pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio);
-
-#ifdef DEBUG_PCIIO
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(pciio, dname, 256);
-	printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-    }
-#endif /* DEBUG_PCIIO */
-
-    if ((pciio_info != NULL) &&
-	(pciio_info->c_fingerprint != pciio_info_fingerprint)
-	&& (pciio_info->c_fingerprint != NULL)) {
-
-	return((pciio_info_t)-1); /* Should panic .. */
-    }
-	
-
-    return pciio_info;
-}
-
-void
-pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info)
-{
-    if (pciio_info != NULL)
-	pciio_info->c_fingerprint = pciio_info_fingerprint;
-    hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info);
-
-    /* Also, mark this vertex as a PCI slot
-     * and use the pciio_info, so pciio_info_chk
-     * can work (and be fairly efficient).
-     */
-    hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO,
-			 (arbitrary_info_t) pciio_info);
-}
-
-devfs_handle_t
-pciio_info_dev_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_vertex);
-}
-
-pciio_slot_t
-pciio_info_slot_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_slot);
-}
-
-pciio_function_t
-pciio_info_function_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_func);
-}
-
-pciio_vendor_id_t
-pciio_info_vendor_id_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_vendor);
-}
-
-pciio_device_id_t
-pciio_info_device_id_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_device);
-}
-
-devfs_handle_t
-pciio_info_master_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_master);
-}
-
-arbitrary_info_t
-pciio_info_mfast_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_mfast);
-}
-
-pciio_provider_t       *
-pciio_info_pops_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_pops);
-}
-
-error_handler_f	       *
-pciio_info_efunc_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_efunc);
-}
-
-error_handler_arg_t    *
-pciio_info_einfo_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_einfo);
-}
-
-pciio_space_t
-pciio_info_bar_space_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_space;
-}
-
-iopaddr_t
-pciio_info_bar_base_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_base;
-}
-
-size_t
-pciio_info_bar_size_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_size;
-}
-
-iopaddr_t
-pciio_info_rom_base_get(pciio_info_t info)
-{
-    return info->c_rbase;
-}
-
-size_t
-pciio_info_rom_size_get(pciio_info_t info)
-{
-    return info->c_rsize;
-}
-
-
-/* =====================================================================
- *          GENERIC PCI INITIALIZATION FUNCTIONS
- */
-
-/*
- *    pciioinit: called once during device driver
- *      initializtion if this driver is configured into
- *      the system.
- */
-void
-pciio_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("pciio_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (pciio_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_PCI, "vendor", "device");
-	if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(pciio_registry != NULL);
-}
-
-/*
- *    pciioattach: called for each vertex in the graph
- *      that is a PCI provider.
- */
-/*ARGSUSED */
-int
-pciio_attach(devfs_handle_t pciio)
-{
-#if DEBUG && ATTACH_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk("%v: pciio_attach\n", pciio);
-#else
-    printk("0x%x: pciio_attach\n", pciio);
-#endif
-#endif
-    return 0;
-}
-
-/*
- * Associate a set of pciio_provider functions with a vertex.
- */
-void
-pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns)
-{
-    hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns);
-}
-
-/*
- * Disassociate a set of pciio_provider functions with a vertex.
- */
-void
-pciio_provider_unregister(devfs_handle_t provider)
-{
-    arbitrary_info_t        ainfo;
-
-    hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo);
-}
-
-/*
- * Obtain a pointer to the pciio_provider functions for a specified Crosstalk
- * provider.
- */
-pciio_provider_t       *
-pciio_provider_fns_get(devfs_handle_t provider)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo);
-    return (pciio_provider_t *) ainfo;
-}
-
-/*ARGSUSED4 */
-int
-pciio_driver_register(
-			 pciio_vendor_id_t vendor_id,
-			 pciio_device_id_t device_id,
-			 char *driver_prefix,
-			 unsigned flags)
-{
-    /* a driver's init routine might call
-     * pciio_driver_register before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    return cdl_add_driver(pciio_registry,
-			  vendor_id, device_id,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Remove an initialization function.
- */
-void
-pciio_driver_unregister(
-			   char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called register; so
-     * we can assume we have a registry here.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    cdl_del_driver(pciio_registry, driver_prefix, NULL);
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being registered.
- */
-void
-pciio_driver_reg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being unregistered.
- */
-void
-pciio_driver_unreg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-pciio_iterate(char *driver_prefix,
-	      pciio_iter_f * func)
-{
-    /* a driver's init routine might call
-     * pciio_iterate before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    ASSERT(pciio_registry != NULL);
-
-    cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func);
-}
-
-devfs_handle_t
-pciio_device_register(
-		devfs_handle_t connectpt,	/* vertex for /hw/.../pciio/%d */
-		devfs_handle_t master,	/* card's master ASIC (PCI provider) */
-		pciio_slot_t slot,	/* card's slot */
-		pciio_function_t func,	/* card's func */
-		pciio_vendor_id_t vendor_id,
-		pciio_device_id_t device_id)
-{
-    return pciio_device_info_register
-	(connectpt, pciio_device_info_new (NULL, master, slot, func,
-					   vendor_id, device_id));
-}
-
-void
-pciio_device_unregister(devfs_handle_t pconn)
-{
-    DEV_FUNC(pconn,device_unregister)(pconn);
-}
-
-pciio_info_t
-pciio_device_info_new(
-		pciio_info_t pciio_info,
-		devfs_handle_t master,
-		pciio_slot_t slot,
-		pciio_function_t func,
-		pciio_vendor_id_t vendor_id,
-		pciio_device_id_t device_id)
-{
-    if (!pciio_info)
-	GET_NEW(pciio_info);
-    ASSERT(pciio_info != NULL);
-
-    pciio_info->c_slot = slot;
-    pciio_info->c_func = func;
-    pciio_info->c_vendor = vendor_id;
-    pciio_info->c_device = device_id;
-    pciio_info->c_master = master;
-    pciio_info->c_mfast = hwgraph_fastinfo_get(master);
-    pciio_info->c_pops = pciio_provider_fns_get(master);
-    pciio_info->c_efunc = 0;
-    pciio_info->c_einfo = 0;
-
-    return pciio_info;
-}
-
-void
-pciio_device_info_free(pciio_info_t pciio_info)
-{
-    /* NOTE : pciio_info is a structure within the pcibr_info
-     *	      and not a pointer to memory allocated on the heap !!
-     */
-    BZERO((char *)pciio_info,sizeof(pciio_info));
-}
-
-devfs_handle_t
-pciio_device_info_register(
-		devfs_handle_t connectpt,		/* vertex at center of bus */
-		pciio_info_t pciio_info)	/* details about the connectpt */
-{
-    char		name[32];
-    devfs_handle_t	pconn;
-    int device_master_set(devfs_handle_t, devfs_handle_t);
-
-    pciio_slot_func_to_name(name,
-			    pciio_info->c_slot,
-			    pciio_info->c_func);
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_path_add(connectpt, name, &pconn))
-	return pconn;
-
-    pciio_info->c_vertex = pconn;
-    pciio_info_set(pconn, pciio_info);
-#ifdef DEBUG_PCIIO
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(pconn, dname, 256);
-	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
-    }
-#endif /* DEBUG_PCIIO */
-
-    /*
-     * create link to our pci provider
-     */
-
-    device_master_set(pconn, pciio_info->c_master);
-
-#if USRPCI
-    /*
-     * Call into usrpci provider to let it initialize for
-     * the given slot.
-     */
-    if (pciio_info->c_slot != PCIIO_SLOT_NONE)
-	usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);
-#endif
-
-    return pconn;
-}
-
-void
-pciio_device_info_unregister(devfs_handle_t connectpt,
-			     pciio_info_t pciio_info)
-{
-    char		name[32];
-    devfs_handle_t	pconn;
-
-    if (!pciio_info)
-	return;
-
-    pciio_slot_func_to_name(name,
-			    pciio_info->c_slot,
-			    pciio_info->c_func);
-
-    hwgraph_edge_remove(connectpt,name,&pconn);
-    pciio_info_set(pconn,0);
-
-    /* Remove the link to our pci provider */
-    hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL);
-
-
-    hwgraph_vertex_unref(pconn);
-    hwgraph_vertex_destroy(pconn);
-    
-}
-/* Add the pci card inventory information to the hwgraph
- */
-static void
-pciio_device_inventory_add(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
-
-    ASSERT(pciio_info);
-    ASSERT(pciio_info->c_vertex == pconn_vhdl);
-
-    /* Donot add inventory  for non-existent devices */
-    if ((pciio_info->c_vendor == PCIIO_VENDOR_ID_NONE)	||
-	(pciio_info->c_device == PCIIO_DEVICE_ID_NONE))
-	return;
-    device_inventory_add(pconn_vhdl,INV_IOBD,INV_PCIADAP,
-			 pciio_info->c_vendor,pciio_info->c_device,
-			 pciio_info->c_slot);
-}
-
-/*ARGSUSED */
-int
-pciio_device_attach(devfs_handle_t pconn,
-		    int          drv_flags)
-{
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-
-    pciio_device_inventory_add(pconn);
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));
-}
-
-int
-pciio_device_detach(devfs_handle_t pconn,
-		    int          drv_flags)
-{
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_del_connpt(pciio_registry, vendor_id, device_id,
-		          pconn, drv_flags));
-
-}
-
-/* SN2 */
-/*
- * Allocate (if necessary) and initialize a PCI window mapping structure.
- */
-pciio_win_map_t
-pciio_device_win_map_new(pciio_win_map_t win_map,
-			 size_t region_size,
-			 size_t page_size)
-{
-	ASSERT((page_size & (page_size - 1)) == 0);
-	ASSERT((region_size & (page_size - 1)) == 0);
-
-	if (win_map == NULL)
-		NEW(win_map);
-
-	/*
-	 * The map array tracks the free ``pages'' in the region.  The worst
-	 * case scenario is when every other page in the region is free --
-	 * e.i. maximum fragmentation.  This leads to (max pages + 1) / 2 + 1
-	 * map entries.  The first "+1" handles the divide by 2 rounding; the
-	 * second handles the need for an end marker sentinel.
-	 */
-	win_map->wm_map = rmallocmap((region_size / page_size + 1) / 2 + 1);
-	win_map->wm_page_size = page_size;
-	ASSERT(win_map->wm_map != NULL);
-
-	return win_map;
-}
-
-/*
- * Free resources associated with a PCI window mapping structure.
- */
-extern void
-pciio_device_win_map_free(pciio_win_map_t win_map)
-{
-	rmfreemap(win_map->wm_map);
-	bzero(win_map, sizeof *win_map);
-}
-
-/*
- * Populate window map with specified free range.
- */
-void
-pciio_device_win_populate(pciio_win_map_t win_map,
-                          iopaddr_t ioaddr,
-                          size_t size)
-{
-	ASSERT((size & (win_map->wm_page_size - 1)) == 0);
-	ASSERT((ioaddr & (win_map->wm_page_size - 1)) == 0);
-
-	rmfree(win_map->wm_map,
-	       size / win_map->wm_page_size,
-	       (unsigned long)ioaddr / win_map->wm_page_size);
-	       
-}
-/*
- * Allocate space from the specified PCI window mapping resource.  On
- * success record information about the allocation in the supplied window
- * allocation cookie (if non-NULL) and return the address of the allocated
- * window.  On failure return NULL.
- *
- * The "size" parameter is usually from a PCI device's Base Address Register
- * (BAR) decoder.  As such, the allocation must be aligned to be a multiple of
- * that.  The "align" parameter acts as a ``minimum alignment'' allocation
- * constraint.  The alignment contraint reflects system or device addressing
- * restrictions such as the inability to share higher level ``windows''
- * between devices, etc.  The returned PCI address allocation will be a
- * multiple of the alignment constraint both in alignment and size.  Thus, the
- * returned PCI address block is aligned to the maximum of the requested size
- * and alignment.
- */
-iopaddr_t
-pciio_device_win_alloc(pciio_win_map_t win_map,
-		       pciio_win_alloc_t win_alloc,
-		       size_t size, size_t align)
-{
-	unsigned long base;
-
-#ifdef PIC_LATER
-	ASSERT((size & (size - 1)) == 0);
-	ASSERT((align & (align - 1)) == 0);
-
-	/*
-	 * Convert size and alignment to pages.  If size is greated than the
-	 * requested alignment, we bump the alignment up to size; otherwise
-	 * convert the size into a multiple of the alignment request.
-	 */
-	size = (size + win_map->wm_page_size - 1) / win_map->wm_page_size;
-	align = align / win_map->wm_page_size;
-	if (size > align)
-		align = size;
-	else
-		size = (size + align - 1) & ~(align - 1);
-
-	/* XXXX */
-	base = rmalloc_align(win_map->wm_map, size, align, VM_NOSLEEP);
-	if (base == RMALLOC_FAIL)
-		return((iopaddr_t)NULL);
-#else
-    int                 index_page, index_page_align;
-    int                 align_pages, size_pages;
-    int                 alloc_pages, free_pages;
-    int                 addr_align;
-
-    /* Convert PCI bus alignment from bytes to pages */
-    align_pages = align / win_map->wm_page_size;
-
-    /* Convert PCI request from bytes to pages */
-    size_pages = (size / win_map->wm_page_size) +
-                  ((size % win_map->wm_page_size) ? 1 : 0);
-
-    /* Align address with the larger of the size or the requested slot align */
-    if (size_pages > align_pages)
-        align_pages = size_pages;
-  
-    /*
-     * Avoid wasting space by aligning - 1; this will prevent crossing
-     * another alignment boundary.
-     */
-    alloc_pages = size_pages + (align_pages - 1);
-
-    /* Allocate PCI bus space in pages */
-    index_page = (int) rmalloc(win_map->wm_map,
-                               (size_t) alloc_pages);
-
-    /* Error if no PCI bus address space available */
-    if (!index_page)
-        return 0;
-
-    /* PCI bus address index starts at 0 */
-    index_page--;
-
-    /* Align the page offset as requested */
-    index_page_align = (index_page + (align_pages - 1)) -
-                       ((index_page + (align_pages - 1)) % align_pages);
-
-    free_pages = (align_pages - 1) - (index_page_align - index_page);
-
-    /* Free unused PCI bus pages adjusting the index to start at 1 */
-    rmfree(win_map->wm_map, 
-           free_pages,
-           (index_page_align + 1) + size_pages);
-
-    /* Return aligned PCI bus space in bytes */ 
-    addr_align = (index_page_align * win_map->wm_page_size); 
-    base = index_page;
-    size = alloc_pages - free_pages;
-#endif	/* PIC_LATER */
-
-	/*
-	 * If a window allocation cookie has been supplied, use it to keep
-	 * track of all the allocated space assigned to this window.
-	 */
-	if (win_alloc) {
-		win_alloc->wa_map = win_map;
-		win_alloc->wa_base = base;
-		win_alloc->wa_pages = size;
-	}
-
-	return base * win_map->wm_page_size;
-}
-
-/*
- * Free the specified window allocation back into the PCI window mapping
- * resource.  As noted above, we keep page addresses offset by 1 ...
- */
-void
-pciio_device_win_free(pciio_win_alloc_t win_alloc)
-{
-	if (win_alloc->wa_pages)
-		rmfree(win_alloc->wa_map->wm_map,
-		       win_alloc->wa_pages,
-		       win_alloc->wa_base);
-}
-
-/*
- * pciio_error_register:
- * arrange for a function to be called with
- * a specified first parameter plus other
- * information when an error is encountered
- * and traced to the pci slot corresponding
- * to the connection point pconn.
- *
- * may also be called with a null function
- * pointer to "unregister" the error handler.
- *
- * NOTE: subsequent calls silently overwrite
- * previous data for this vertex. We assume that
- * cooperating drivers, well, cooperate ...
- */
-void
-pciio_error_register(devfs_handle_t pconn,
-		     error_handler_f *efunc,
-		     error_handler_arg_t einfo)
-{
-    pciio_info_t            pciio_info;
-
-    pciio_info = pciio_info_get(pconn);
-    ASSERT(pciio_info != NULL);
-    pciio_info->c_efunc = efunc;
-    pciio_info->c_einfo = einfo;
-}
-
-/*
- * Check if any device has been found in this slot, and return
- * true or false
- * vhdl is the vertex for the slot
- */
-int
-pciio_slot_inuse(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-
-    ASSERT(pciio_info);
-    ASSERT(pciio_info->c_vertex == pconn_vhdl);
-    if (pciio_info->c_vendor) {
-	/*
-	 * Non-zero value for vendor indicate
-	 * a board being found in this slot.
-	 */
-	return 1;
-    }
-    return 0;
-}
-
-int
-pciio_dma_enabled(devfs_handle_t pconn_vhdl)
-{
-	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);
-}
-
-/*
- * These are complementary Linux interfaces that takes in a pci_dev * as the 
- * first arguement instead of devfs_handle_t.
- */
-iopaddr_t               snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned);
-pciio_dmamap_t          snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned);
-void                    snia_pciio_dmamap_free(pciio_dmamap_t);
-iopaddr_t               snia_pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-void                    snia_pciio_dmamap_done(pciio_dmamap_t);
-pciio_endian_t          snia_pciio_endian_set(struct pci_dev *pci_dev, pciio_endian_t device_end,
-					      pciio_endian_t desired_end);
-
-#include <linux/module.h>
-EXPORT_SYMBOL(snia_pciio_dmatrans_addr);
-EXPORT_SYMBOL(snia_pciio_dmamap_alloc);
-EXPORT_SYMBOL(snia_pciio_dmamap_free);
-EXPORT_SYMBOL(snia_pciio_dmamap_addr);
-EXPORT_SYMBOL(snia_pciio_dmamap_done);
-EXPORT_SYMBOL(snia_pciio_endian_set);
-
-int
-snia_pcibr_rrb_alloc(struct pci_dev *pci_dev,
-	int *count_vchan0,
-	int *count_vchan1)
-{
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-	return pcibr_rrb_alloc(dev, count_vchan0, count_vchan1);
-}
-EXPORT_SYMBOL(snia_pcibr_rrb_alloc);
-
-pciio_endian_t
-snia_pciio_endian_set(struct pci_dev *pci_dev,
-	pciio_endian_t device_end,
-	pciio_endian_t desired_end)
-{
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-	
-	return DEV_FUNC(dev, endian_set)
-		(dev, device_end, desired_end);
-}
-
-iopaddr_t
-snia_pciio_dmatrans_addr(struct pci_dev *pci_dev, /* translate for this device */
-                    device_desc_t dev_desc,     /* device descriptor */
-                    paddr_t paddr,      /* system physical address */
-                    size_t byte_count,  /* length */
-                    unsigned flags)
-{                                       /* defined in dma.h */
-
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-    return DEV_FUNC(dev, dmatrans_addr)
-        (dev, dev_desc, paddr, byte_count, flags);
-}
-
-pciio_dmamap_t
-snia_pciio_dmamap_alloc(struct pci_dev *pci_dev,  /* set up mappings for this device */
-                   device_desc_t dev_desc,      /* device descriptor */
-                   size_t byte_count_max,       /* max size of a mapping */
-                   unsigned flags)
-{                                       /* defined in dma.h */
-
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-    return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-        (dev, dev_desc, byte_count_max, flags);
-}
-
-void
-snia_pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_free)
-        (CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-snia_pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,  /* use these mapping resources */
-                  paddr_t paddr,        /* map for this address */
-                  size_t byte_count)
-{                                       /* map this many bytes */
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
-        (CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
-}
-
-void
-snia_pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_done)
-        (CAST_DMAMAP(pciio_dmamap));
-}
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/sgi_io_init.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/sgi_io_init.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/sgi_io_init.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/sgi_io_init.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,324 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pciba.h>
-#include <linux/smp.h>
-
-extern void mlreset(int );
-extern int init_hcl(void);
-extern void klgraph_hack_init(void);
-extern void hubspc_init(void);
-extern void pciio_init(void);
-extern void pcibr_init(void);
-extern void xtalk_init(void);
-extern void xbow_init(void);
-extern void xbmon_init(void);
-extern void pciiox_init(void);
-extern void usrpci_init(void);
-extern void ioc3_init(void);
-extern void initialize_io(void);
-extern void intr_clear_all(nasid_t);
-extern void klhwg_add_all_modules(devfs_handle_t);
-extern void klhwg_add_all_nodes(devfs_handle_t);
-
-void sn_mp_setup(void);
-extern devfs_handle_t hwgraph_root;
-extern void io_module_init(void);
-extern void pci_bus_cvlink_init(void);
-extern void temp_hack(void);
-
-extern int pci_bus_to_hcl_cvlink(void);
-
-/* #define DEBUG_IO_INIT 1 */
-#ifdef DEBUG_IO_INIT
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_IO_INIT */
-
-/*
- * per_hub_init
- *
- * 	This code is executed once for each Hub chip.
- */
-static void
-per_hub_init(cnodeid_t cnode)
-{
-	nasid_t		nasid;
-	nodepda_t	*npdap;
-	ii_icmr_u_t	ii_icmr;
-	ii_ibcr_u_t	ii_ibcr;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	ASSERT(nasid != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
-
-	npdap = NODEPDA(cnode);
-
-	/* initialize per-node synergy perf instrumentation */
-	npdap->synergy_perf_enabled = 0; /* off by default */
-	npdap->synergy_perf_lock = SPIN_LOCK_UNLOCKED;
-	npdap->synergy_perf_freq = SYNERGY_PERF_FREQ_DEFAULT;
-	npdap->synergy_inactive_intervals = 0;
-	npdap->synergy_active_intervals = 0;
-	npdap->synergy_perf_data = NULL;
-	npdap->synergy_perf_first = NULL;
-
-
-	/*
-	 * Set the total number of CRBs that can be used.
-	 */
-	ii_icmr.ii_icmr_regval= 0x0;
-	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF;
-	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
-
-	/*
-	 * Set the number of CRBs that both of the BTEs combined
-	 * can use minus 1.
-	 */
-	ii_ibcr.ii_ibcr_regval= 0x0;
-	ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
-	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
-
-	/*
-	 * Set CRB timeout to be 10ms.
-	 */
-	REMOTE_HUB_S(nasid, IIO_ICTP, 0x1000 );
-	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
-
-
-	/* Reserve all of the hardwired interrupt levels. */
-	intr_reserve_hardwired(cnode);
-
-	/* Initialize error interrupts for this hub. */
-	hub_error_init(cnode);
-}
-
-/*
- * This routine is responsible for the setup of all the IRIX hwgraph style
- * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
- * is called just before the generic Linux PCI layer does its probing (by 
- * platform_pci_fixup aka sn_pci_fixup).
- *
- * It is very IMPORTANT that this call is only made by the Master CPU!
- *
- */
-
-void
-sgi_master_io_infr_init(void)
-{
-	int cnode;
-
-	/*
-	 * Do any early init stuff .. einit_tbl[] etc.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling init_hcl().\n");
-	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
-
-#ifdef Colin
-
-printk("Testing out Xbridge Access .. if it hangs Xbridge is not init yet.\n");
-printk("	Reading Xbridge WID at address 0xc00000080f000000 0x%p\n", (* (volatile uint32_t *)(0xc00000080f000000)));
-
-printk("Testing out PCI Address Space Accesses\n");
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020000 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020000)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020001 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020001)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020002 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020002)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020003 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020003)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020004)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020005 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020005)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020006 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020006)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020007 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020007)));
-
-printk("	Testing PCI Config Word: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020004)));
-
-printk("	Testing PCI Config Word: address 0xc00000080f020008 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020008)));
-
-#endif
-
-	/*
-	 * initialize the Linux PCI to xwidget vertexes ..
-	 */
-	DBG("--> sgi_master_io_infr_init: calling pci_bus_cvlink_init().\n");
-	pci_bus_cvlink_init();
-
-#ifdef BRINGUP
-	/*
-	 * Hack to provide statically initialzed klgraph entries.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n");
-	klgraph_hack_init();
-#endif /* BRINGUP */
-
-	/*
-	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling mlreset(0).\n");
-	mlreset(0); /* Master .. */
-
-	/*
-	 * allowboot() is called by kern/os/main.c in main()
-	 * Emulate allowboot() ...
-	 *   per_cpu_init() - only need per_hub_init()
-	 *   cpu_io_setup() - Nothing to do.
-	 * 
-	 */
-	DBG("--> sgi_master_io_infr_init: calling sn_mp_setup().\n");
-	sn_mp_setup();
-
-	DBG("--> sgi_master_io_infr_init: calling per_hub_init(0).\n");
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		per_hub_init(cnode);
-	}
-
-	/* We can do headless hub cnodes here .. */
-
-	/*
-	 * io_init[] stuff.
-	 *
-	 * Get SGI IO Infrastructure drivers to init and register with 
-	 * each other etc.
-	 */
-
-	DBG("--> sgi_master_io_infr_init: calling hubspc_init()\n");
-	hubspc_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pciio_init()\n");
-	pciio_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pcibr_init()\n");
-	pcibr_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xtalk_init()\n");
-	xtalk_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xbow_init()\n");
-	xbow_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xbmon_init()\n");
-	xbmon_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pciiox_init()\n");
-	pciiox_init();
-
-	DBG("--> sgi_master_io_infr_init: calling usrpci_init()\n");
-	usrpci_init();
-
-	DBG("--> sgi_master_io_infr_init: calling ioc3_init()\n");
-	ioc3_init();
-
-	/*
-	 *
-	 * Our IO Infrastructure drivers are in place .. 
-	 * Initialize the whole IO Infrastructure .. xwidget/device probes.
-	 *
-	 */
-	DBG("--> sgi_master_io_infr_init: Start Probe and IO Initialization\n");
-	initialize_io();
-
-	DBG("--> sgi_master_io_infr_init: Setting up SGI IO Links for Linux PCI\n");
-	pci_bus_to_hcl_cvlink();
-
-#ifdef CONFIG_PCIBA
-	DBG("--> sgi_master_io_infr_init: calling pciba_init()\n");
- 	pciba_init();
-#endif
-
-	DBG("--> Leave sgi_master_io_infr_init: DONE setting up SGI Links for PCI\n");
-}
-
-/*
- * sgi_slave_io_infr_init - This routine must be called on all cpus except 
- * the Master CPU.
- */
-void
-sgi_slave_io_infr_init(void)
-{
-	/* Emulate cboot() .. */
-	mlreset(1); /* This is a slave cpu */
-
-	// per_hub_init(0); /* Need to get and send in actual cnode number */
-
-	/* Done */
-}
-
-/*
- * One-time setup for MP SN.
- * Allocate per-node data, slurp prom klconfig information and
- * convert it to hwgraph information.
- */
-void
-sn_mp_setup(void)
-{
-	cnodeid_t	cnode;
-	cpuid_t		cpu;
-
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		/* Skip holes in CPU space */
-		if (cpu_enabled(cpu)) {
-			init_platform_pda(cpu);
-		}
-	}
-
-	/*
-	 * Initialize platform-dependent vertices in the hwgraph:
-	 *	module
-	 *	node
-	 *	cpu
-	 *	memory
-	 *	slot
-	 *	hub
-	 *	router
-	 *	xbow
-	 */
-
-	DBG("sn_mp_io_setup: calling io_module_init()\n");
-	io_module_init(); /* Use to be called module_init() .. */
-
-	DBG("sn_mp_setup: calling klhwg_add_all_modules()\n");
-	klhwg_add_all_modules(hwgraph_root);
-	DBG("sn_mp_setup: calling klhwg_add_all_nodes()\n");
-	klhwg_add_all_nodes(hwgraph_root);
-
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-
-		/*
-		 * This routine clears the Hub's Interrupt registers.
-		 */
-		/*
-		 * We need to move this intr_clear_all() routine 
-		 * from SN/intr.c to a more appropriate file.
-		 * Talk to Al Mayer.
-		 */
-                intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
-		/* now init the hub */
-	//	per_hub_init(cnode);
-
-	}
-
-	synergy_perf_init();
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/xbow.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/xbow.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/xbow.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/xbow.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1086 +0,0 @@
-/* $Id: xbow.c,v 1.3 2002/11/21 17:51:57 jh Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-#include <asm/sn/simulator.h>
-
-/* #define DEBUG		1 */
-/* #define XBOW_DEBUG	1 */
-
-
-/*
- * Files needed to get the device driver entry points
- */
-
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-
-#include <asm/sn/prio.h>
-#include <asm/sn/hcl_util.h>
-
-
-#define NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DEL(ptr)	(kfree(ptr))
-
-int                     xbow_devflag = D_MP;
-
-/*
- * This file supports the Xbow chip.  Main functions: initializtion,
- * error handling, and GBR.
- */
-
-/*
- * each vertex corresponding to an xbow chip
- * has a "fastinfo" pointer pointing at one
- * of these things.
- */
-typedef struct xbow_soft_s *xbow_soft_t;
-
-struct xbow_soft_s {
-    devfs_handle_t            conn;	/* our connection point */
-    devfs_handle_t            vhdl;	/* xbow's private vertex */
-    devfs_handle_t            busv;	/* the xswitch vertex */
-    xbow_t                 *base;	/* PIO pointer to crossbow chip */
-    char                   *name;	/* hwgraph name */
-
-    xbow_perf_t             xbow_perfcnt[XBOW_PERF_COUNTERS];
-    xbow_perf_link_t        xbow_perflink[MAX_XBOW_PORTS];
-    xbow_link_status_t      xbow_link_status[MAX_XBOW_PORTS];
-    spinlock_t              xbow_perf_lock;
-    int                     link_monitor;
-    widget_cfg_t	   *wpio[MAX_XBOW_PORTS];	/* cached PIO pointer */
-
-    /* Bandwidth allocation state. Bandwidth values are for the
-     * destination port since contention happens there.
-     * Implicit mapping from xbow ports (8..f) -> (0..7) array indices.
-     */
-    spinlock_t		    xbow_bw_alloc_lock;		/* bw allocation lock */
-    unsigned long long	    bw_hiwm[MAX_XBOW_PORTS];	/* hiwater mark values */
-    unsigned long long      bw_cur_used[MAX_XBOW_PORTS]; /* bw used currently */
-};
-
-#define xbow_soft_set(v,i)	hwgraph_fastinfo_set((v), (arbitrary_info_t)(i))
-#define xbow_soft_get(v)	((xbow_soft_t)hwgraph_fastinfo_get((v)))
-
-/*
- * Function Table of Contents
- */
-
-void                    xbow_mlreset(xbow_t *);
-void                    xbow_init(void);
-int                     xbow_attach(devfs_handle_t);
-
-int                     xbow_open(devfs_handle_t *, int, int, cred_t *);
-int                     xbow_close(devfs_handle_t, int, int, cred_t *);
-
-int                     xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     xbow_unmap(devfs_handle_t, vhandl_t *);
-int                     xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
-
-int                     xbow_widget_present(xbow_t *, int);
-static int              xbow_link_alive(xbow_t *, int);
-devfs_handle_t            xbow_widget_lookup(devfs_handle_t, int);
-
-void                    xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
-
-
-
-void                    xbow_update_perf_counters(devfs_handle_t);
-xbow_perf_link_t       *xbow_get_perf_counters(devfs_handle_t);
-int                     xbow_enable_perf_counter(devfs_handle_t, int, int, int);
-xbow_link_status_t     *xbow_get_llp_status(devfs_handle_t);
-void                    xbow_update_llp_status(devfs_handle_t);
-
-int                     xbow_disable_llp_monitor(devfs_handle_t);
-int                     xbow_enable_llp_monitor(devfs_handle_t);
-int                     xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t,
-                                unsigned long long, unsigned long long);
-
-xswitch_reset_link_f    xbow_reset_link;
-
-void                    idbg_xbowregs(int64_t);
-
-xswitch_provider_t      xbow_provider =
-{
-    xbow_reset_link,
-};
-
-/*
- *    xbow_mlreset: called at mlreset time if the
- *      platform specific code determines that there is
- *      a crossbow in a critical path that must be
- *      functional before the driver would normally get
- *      the device properly set up.
- *
- *      what do we need to do, that the boot prom can
- *      not be counted on to have already done, that is
- *      generic across all platforms using crossbows?
- */
-/*ARGSUSED */
-void
-xbow_mlreset(xbow_t * xbow)
-{
-}
-
-/*
- *    xbow_init: called with the rest of the device
- *      driver XXX_init routines. This platform *might*
- *      have a Crossbow chip, or even several, but it
- *      might have none. Register with the crosstalk
- *      generic provider so when we encounter the chip
- *      the right magic happens.
- */
-void
-xbow_init(void)
-{
-
-#if DEBUG && ATTACH_DEBUG
-    printk("xbow_init\n");
-#endif
-
-    xwidget_driver_register(PXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-
-    xwidget_driver_register(XXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-    xwidget_driver_register(XBOW_WIDGET_PART_NUM,
-			    XBOW_WIDGET_MFGR_NUM,
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-}
-
-#ifdef XBRIDGE_REGS_SIM
-/*    xbow_set_simulated_regs: sets xbow regs as needed
- *	for powering through the boot
- */
-void
-xbow_set_simulated_regs(xbow_t *xbow, int port)
-{
-    /*
-     * turn on link
-     */
-    xbow->xb_link(port).link_status = (1<<31);
-    /*
-     * and give it a live widget too
-     */
-    xbow->xb_link(port).link_aux_status = XB_AUX_STAT_PRESENT;
-    /*
-     * zero the link control reg
-     */
-    xbow->xb_link(port).link_control = 0x0;
-}
-#endif /* XBRIDGE_REGS_SIM */
-
-/*
- *    xbow_attach: the crosstalk provider has
- *      determined that there is a crossbow widget
- *      present, and has handed us the connection
- *      point for that vertex.
- *
- *      We not only add our own vertex, but add
- *      some "xtalk switch" data to the switch
- *      vertex (at the connect point's parent) if
- *      it does not have any.
- */
-
-/*ARGSUSED */
-int
-xbow_attach(devfs_handle_t conn)
-{
-    /*REFERENCED */
-    devfs_handle_t            vhdl;
-    devfs_handle_t            busv;
-    xbow_t                 *xbow;
-    xbow_soft_t             soft;
-    int                     port;
-    xswitch_info_t          info;
-    char                    devnm[MAXDEVNAME], *s;
-    xbowreg_t               id;
-    int                     rev;
-    int			    i;
-    int			    xbow_num;
-	
-#if DEBUG && ATTACH_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk("%v: xbow_attach\n", conn);
-#else
-    printk("0x%x: xbow_attach\n", conn);
-#endif
-#endif
-
-    /*
-     * Get a PIO pointer to the base of the crossbow
-     * chip.
-     */
-#ifdef XBRIDGE_REGS_SIM
-    printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: allocating %ld bytes for xbow_s\n", sizeof(xbow_t));
-    xbow = (xbow_t *) kmalloc(sizeof(xbow_t), GFP_KERNEL);
-    /*
-     * turn on ports e and f like in a real live ibrick
-     */
-    xbow_set_simulated_regs(xbow, 0xe);
-    xbow_set_simulated_regs(xbow, 0xf);
-#else
-    xbow = (xbow_t *) xtalk_piotrans_addr(conn, 0, 0, sizeof(xbow_t), 0);
-#endif /* XBRIDGE_REGS_SIM */
-
-    /*
-     * Locate the "switch" vertex: it is the parent
-     * of our connection point.
-     */
-    busv = hwgraph_connectpt_get(conn);
-#if DEBUG && ATTACH_DEBUG
-    printk("xbow_attach: Bus Vertex 0x%p, conn 0x%p, xbow register 0x%p wid= 0x%x\n", busv, conn, xbow, *(volatile u32 *)xbow);
-#endif
-
-    ASSERT(busv != GRAPH_VERTEX_NONE);
-
-    /*
-     * Create our private vertex, and connect our
-     * driver information to it. This makes it possible
-     * for diagnostic drivers to open the crossbow
-     * vertex for access to registers.
-     */
-
-    /*
-     * We need to teach xbow drivers to provide the right set of
-     * file ops.
-     */
-    vhdl = NULL;
-    vhdl = hwgraph_register(conn, EDGE_LBL_XBOW,
-                        0, DEVFS_FL_AUTO_DEVNUM,
-                        0, 0,
-                        S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                        /* &hcl_fops */ (void *)&vhdl, NULL);
-    if (!vhdl) {
-        printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n",
-                (void *)conn);
-    }
-
-    /*
-     * Allocate the soft state structure and attach
-     * it to the xbow's vertex
-     */
-    NEW(soft);
-    soft->conn = conn;
-    soft->vhdl = vhdl;
-    soft->busv = busv;
-    soft->base = xbow;
-    /* does the universe really need another macro?  */
-    /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */
-    hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft);
-
-#define XBOW_NUM_SUFFIX_FORMAT	"[xbow# %d]"
-
-    /* Add xbow number as a suffix to the hwgraph name of the xbow.
-     * This is helpful while looking at the error/warning messages.
-     */
-    xbow_num = 0;
-
-    /*
-     * get the name of this xbow vertex and keep the info.
-     * This is needed during errors and interupts, but as
-     * long as we have it, we can use it elsewhere.
-     */
-    s = dev_to_name(vhdl, devnm, MAXDEVNAME);
-    soft->name = kmalloc(strlen(s) + strlen(XBOW_NUM_SUFFIX_FORMAT) + 1, 
-			    GFP_KERNEL);
-    sprintf(soft->name,"%s"XBOW_NUM_SUFFIX_FORMAT, s,xbow_num);
-
-#ifdef XBRIDGE_REGS_SIM
-    /* my o200/ibrick has id=0x2d002049, but XXBOW_WIDGET_PART_NUM is defined
-     * as 0xd000, so I'm using that for the partnum bitfield.
-     */
-    printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: need xb_wid_id value!!\n");
-    id = 0x2d000049;
-#else
-    id = xbow->xb_wid_id;
-#endif /* XBRIDGE_REGS_SIM */
-    rev = XWIDGET_PART_REV_NUM(id);
-
-    mutex_spinlock_init(&soft->xbow_perf_lock);
-    soft->xbow_perfcnt[0].xp_perf_reg = &xbow->xb_perf_ctr_a;
-    soft->xbow_perfcnt[1].xp_perf_reg = &xbow->xb_perf_ctr_b;
-
-    /* Initialization for GBR bw allocation */
-    mutex_spinlock_init(&soft->xbow_bw_alloc_lock);
-
-#define	XBOW_8_BIT_PORT_BW_MAX		(400 * 1000 * 1000)	/* 400 MB/s */
-#define XBOW_16_BIT_PORT_BW_MAX		(800 * 1000 * 1000)	/* 800 MB/s */
-
-    /* Set bandwidth hiwatermark and current values */
-    for (i = 0; i < MAX_XBOW_PORTS; i++) {
-	soft->bw_hiwm[i] = XBOW_16_BIT_PORT_BW_MAX;	/* for now */
-	soft->bw_cur_used[i] = 0;
-    }
-
-    /*
-     * Enable xbow error interrupts
-     */
-    xbow->xb_wid_control = (XB_WID_CTRL_REG_ACC_IE | XB_WID_CTRL_XTALK_IE);
-
-    /*
-     * take a census of the widgets present,
-     * leaving notes at the switch vertex.
-     */
-    info = xswitch_info_new(busv);
-
-    for (port = MAX_PORT_NUM - MAX_XBOW_PORTS;
-	 port < MAX_PORT_NUM; ++port) {
-	if (!xbow_link_alive(xbow, port)) {
-#if DEBUG && XBOW_DEBUG
-	    printk(KERN_INFO "0x%p link %d is not alive\n",
-		    busv, port);
-#endif
-	    continue;
-	}
-	if (!xbow_widget_present(xbow, port)) {
-#if DEBUG && XBOW_DEBUG
-	    printk(KERN_INFO "0x%p link %d is alive but no widget is present\n", busv, port);
-#endif
-	    continue;
-	}
-#if DEBUG && XBOW_DEBUG
-	printk(KERN_INFO "0x%p link %d has a widget\n",
-		busv, port);
-#endif
-
-	xswitch_info_link_is_ok(info, port);
-	/*
-	 * Turn some error interrupts on
-	 * and turn others off. The PROM has
-	 * some things turned on we don't
-	 * want to see (bandwidth allocation
-	 * errors for instance); so if it
-	 * is not listed here, it is not on.
-	 */
-	xbow->xb_link(port).link_control =
-	    ( (xbow->xb_link(port).link_control
-	/*
-	 * Turn off these bits; they are non-fatal,
-	 * but we might want to save some statistics
-	 * on the frequency of these errors.
-	 * XXX FIXME XXX
-	 */
-	    & ~XB_CTRL_RCV_CNT_OFLOW_IE
-	    & ~XB_CTRL_XMT_CNT_OFLOW_IE
-	    & ~XB_CTRL_BNDWDTH_ALLOC_IE
-	    & ~XB_CTRL_RCV_IE)
-	/*
-	 * These are the ones we want to turn on.
-	 */
-	    | (XB_CTRL_ILLEGAL_DST_IE
-	    | XB_CTRL_OALLOC_IBUF_IE
-	    | XB_CTRL_XMT_MAX_RTRY_IE
-	    | XB_CTRL_MAXREQ_TOUT_IE
-	    | XB_CTRL_XMT_RTRY_IE
-	    | XB_CTRL_SRC_TOUT_IE) );
-    }
-
-    xswitch_provider_register(busv, &xbow_provider);
-
-    return 0;				/* attach successful */
-}
-
-/*ARGSUSED */
-int
-xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-
-}
-
-/*ARGSUSED */
-int
-xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    int                     error;
-
-    ASSERT(soft);
-    len = ctob(btoc(len));
-    /* XXX- this ignores the offset!!! */
-    error = v_mapphys(vt, (void *) soft->base, len);
-    return error;
-}
-
-/*ARGSUSED */
-int
-xbow_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    return 0;
-}
-
-/* This contains special-case code for grio. There are plans to make
- * this general sometime in the future, but till then this should
- * be good enough.
- */
-xwidgetnum_t
-xbow_widget_num_get(devfs_handle_t dev)
-{
-	devfs_handle_t	tdev;
-	char		devname[MAXDEVNAME];
-	xwidget_info_t	xwidget_info;
-	int		i;
-
-	vertex_to_name(dev, devname, MAXDEVNAME);
-
-	/* If this is a pci controller vertex, traverse up using
-	 * the ".." links to get to the widget.
-	 */
-	if (strstr(devname, EDGE_LBL_PCI) &&
-			strstr(devname, EDGE_LBL_CONTROLLER)) {
-		tdev = dev;
-		for (i=0; i< 2; i++) {
-			if (hwgraph_edge_get(tdev,
-				HWGRAPH_EDGELBL_DOTDOT, &tdev) !=
-					GRAPH_SUCCESS)
-				return XWIDGET_NONE;
-		}
-
-		if ((xwidget_info = xwidget_info_chk(tdev)) != NULL) {
-			return (xwidget_info_id_get(xwidget_info));
-		} else {
-			return XWIDGET_NONE;
-		}
-	}
-
-	return XWIDGET_NONE;
-}
-
-int
-xbow_ioctl(devfs_handle_t dev,
-	   int cmd,
-	   void *arg,
-	   int flag,
-	   struct cred *cr,
-	   int *rvalp)
-{
-    devfs_handle_t            vhdl;
-    int                     error = 0;
-
-#if defined (DEBUG)
-    int                     rc;
-    devfs_handle_t            conn;
-    struct xwidget_info_s  *xwidget_info;
-    xbow_soft_t             xbow_soft;
-#endif
-    *rvalp = 0;
-
-    vhdl = dev_to_vhdl(dev);
-#if defined (DEBUG)
-    xbow_soft = xbow_soft_get(vhdl);
-    conn = xbow_soft->conn;
-
-    xwidget_info = xwidget_info_get(conn);
-    ASSERT_ALWAYS(xwidget_info != NULL);
-
-    rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid);
-    ASSERT_ALWAYS(rc != 0);
-#endif
-    switch (cmd) {
-
-    case XBOWIOC_LLP_ERROR_ENABLE:
-	if ((error = xbow_enable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    case XBOWIOC_LLP_ERROR_DISABLE:
-
-	if ((error = xbow_disable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    default:
-	break;
-
-    }
-    return error;
-}
-
-/*
- * xbow_widget_present: See if a device is present
- * on the specified port of this crossbow.
- */
-int
-xbow_widget_present(xbow_t *xbow, int port)
-{
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		if ( (port == 14) || (port == 15) ) {
-			return 1;
-		}
-		else {
-			return 0;
-		}
-	}
-	else {
-		/* WAR: port 0xf on PIC is missing present bit */
-		/* Need this for PIC */
-		if (IS_PIC_XBOW(xbow->xb_wid_id) && port == 0xf) {
-			return 1;
-		}
-		return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT;
-	}
-}
-
-static int
-xbow_link_alive(xbow_t * xbow, int port)
-{
-    xbwX_stat_t             xbow_linkstat;
-
-    xbow_linkstat.linkstatus = xbow->xb_link(port).link_status;
-    return (xbow_linkstat.link_alive);
-}
-
-/*
- * xbow_widget_lookup
- *      Lookup the edges connected to the xbow specified, and
- *      retrieve the handle corresponding to the widgetnum
- *      specified.
- *      If not found, return 0.
- */
-devfs_handle_t
-xbow_widget_lookup(devfs_handle_t vhdl,
-		   int widgetnum)
-{
-    xswitch_info_t          xswitch_info;
-    devfs_handle_t            conn;
-
-    xswitch_info = xswitch_info_get(vhdl);
-    conn = xswitch_info_vhdl_get(xswitch_info, widgetnum);
-    return conn;
-}
-
-/*
- * xbow_intr_preset: called during mlreset time
- * if the platform specific code needs to route
- * an xbow interrupt before the xtalk infrastructure
- * is available for use.
- *
- * Also called from xbow_setwidint, so we don't
- * replicate the guts of the routine.
- *
- * XXX- probably should be renamed xbow_wid_intr_set or
- * something to reduce confusion.
- */
-/*ARGSUSED3 */
-void
-xbow_intr_preset(void *which_widget,
-		 int which_widget_intr,
-		 xwidgetnum_t targ,
-		 iopaddr_t addr,
-		 xtalk_intr_vector_t vect)
-{
-    xbow_t                 *xbow = (xbow_t *) which_widget;
-
-    xbow->xb_wid_int_upper = ((0xFF000000 & (vect << 24)) |
-			      (0x000F0000 & (targ << 16)) |
-			      XTALK_ADDR_TO_UPPER(addr));
-    xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-
-}
-
-int                     xbow_xmit_retry_errors = 0;
-
-int
-xbow_xmit_retry_error(xbow_soft_t soft,
-		      int port)
-{
-    xswitch_info_t          info;
-    devfs_handle_t            vhdl;
-    widget_cfg_t           *wid;
-    widgetreg_t             id;
-    int                     part;
-    int                     mfgr;
-
-    wid = soft->wpio[port - BASE_XBOW_PORT];
-    if (wid == NULL) {
-	/* If we can't track down a PIO
-	 * pointer to our widget yet,
-	 * leave our caller knowing that
-	 * we are interested in this
-	 * interrupt if it occurs in
-	 * the future.
-	 */
-	info = xswitch_info_get(soft->busv);
-	if (!info)
-	    return 1;
-	vhdl = xswitch_info_vhdl_get(info, port);
-	if (vhdl == GRAPH_VERTEX_NONE)
-	    return 1;
-	wid = (widget_cfg_t *) xtalk_piotrans_addr
-	    (vhdl, 0, 0, sizeof *wid, 0);
-	if (!wid)
-	    return 1;
-	soft->wpio[port - BASE_XBOW_PORT] = wid;
-    }
-    id = wid->w_id;
-    part = XWIDGET_PART_NUM(id);
-    mfgr = XWIDGET_MFG_NUM(id);
-
-    /* If this thing is not a Bridge,
-     * do not activate the WAR, and
-     * tell our caller we do not need
-     * to be called again.
-     */
-    if ((part != BRIDGE_WIDGET_PART_NUM) ||
-	(mfgr != BRIDGE_WIDGET_MFGR_NUM)) {
-		/* FIXME: add Xbridge to the WAR.
-		 * Shouldn't hurt anything.  Later need to
-		 * check if we can remove this.
-                 */
-    		if ((part != XBRIDGE_WIDGET_PART_NUM) ||
-		    (mfgr != XBRIDGE_WIDGET_MFGR_NUM))
-			return 0;
-    }
-
-    /* count how many times we
-     * have picked up after
-     * LLP Transmit problems.
-     */
-    xbow_xmit_retry_errors++;
-
-    /* rewrite the control register
-     * to fix things up.
-     */
-    wid->w_control = wid->w_control;
-    wid->w_control;
-
-    return 1;
-}
-
-void
-xbow_update_perf_counters(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
-    xbow_perf_link_t       *xbow_plink = xbow_soft->xbow_perflink;
-    xbow_perfcount_t        perf_reg;
-    unsigned long           s;
-    int                     link, i;
-
-    for (i = 0; i < XBOW_PERF_COUNTERS; i++, xbow_perf++) {
-	if (xbow_perf->xp_mode == XBOW_MONITOR_NONE)
-	    continue;
-
-	s = mutex_spinlock(&xbow_soft->xbow_perf_lock);
-
-	perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg;
-
-	link = perf_reg.xb_perf.link_select;
-
-	(xbow_plink + link)->xlp_cumulative[xbow_perf->xp_curmode] +=
-	    ((perf_reg.xb_perf.count - xbow_perf->xp_current) & XBOW_COUNTER_MASK);
-	xbow_perf->xp_current = perf_reg.xb_perf.count;
-
-	mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-    }
-}
-
-xbow_perf_link_t       *
-xbow_get_perf_counters(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_link_t       *xbow_perf_link = xbow_soft->xbow_perflink;
-
-    return xbow_perf_link;
-}
-
-int
-xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
-    xbow_linkctrl_t         xbow_link_ctrl;
-    xbow_t                 *xbow = xbow_soft->base;
-    xbow_perfcount_t        perf_reg;
-    unsigned long           s;
-    int                     i;
-
-    link -= BASE_XBOW_PORT;
-    if ((link < 0) || (link >= MAX_XBOW_PORTS))
-	return -1;
-
-    if ((mode < XBOW_MONITOR_NONE) || (mode > XBOW_MONITOR_DEST_LINK))
-	return -1;
-
-    if ((counter < 0) || (counter >= XBOW_PERF_COUNTERS))
-	return -1;
-
-    s = mutex_spinlock(&xbow_soft->xbow_perf_lock);
-
-    if ((xbow_perf + counter)->xp_mode && mode) {
-	mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-	return -1;
-    }
-    for (i = 0; i < XBOW_PERF_COUNTERS; i++) {
-	if (i == counter)
-	    continue;
-	if (((xbow_perf + i)->xp_link == link) &&
-	    ((xbow_perf + i)->xp_mode)) {
-	    mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-	    return -1;
-	}
-    }
-    xbow_perf += counter;
-
-    xbow_perf->xp_curlink = xbow_perf->xp_link = link;
-    xbow_perf->xp_curmode = xbow_perf->xp_mode = mode;
-
-    xbow_link_ctrl.xbl_ctrlword = xbow->xb_link_raw[link].link_control;
-    xbow_link_ctrl.xb_linkcontrol.perf_mode = mode;
-    xbow->xb_link_raw[link].link_control = xbow_link_ctrl.xbl_ctrlword;
-
-    perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg;
-    perf_reg.xb_perf.link_select = link;
-    *(xbowreg_t *) xbow_perf->xp_perf_reg = perf_reg.xb_counter_val;
-    xbow_perf->xp_current = perf_reg.xb_perf.count;
-
-    mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-    return 0;
-}
-
-xbow_link_status_t     *
-xbow_get_llp_status(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
-
-    return xbow_llp_status;
-}
-
-void
-xbow_update_llp_status(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
-    xbow_t                 *xbow;
-    xbwX_stat_t             lnk_sts;
-    xbow_aux_link_status_t  aux_sts;
-    int                     link;
-    devfs_handle_t	    xwidget_vhdl;
-    char		   *xwidget_name;	
-
-    xbow = (xbow_t *) xbow_soft->base;
-    for (link = 0; link < MAX_XBOW_PORTS; link++, xbow_llp_status++) {
-	/* Get the widget name corresponding the current link.
-	 * Note : 0 <= link < MAX_XBOW_PORTS(8).
-	 * 	  BASE_XBOW_PORT(0x8) <= xwidget number < MAX_PORT_NUM (0x10)
-	 */
-	xwidget_vhdl = xbow_widget_lookup(xbow_soft->busv,link+BASE_XBOW_PORT);
-	xwidget_name = xwidget_name_get(xwidget_vhdl);
-	aux_sts.aux_linkstatus
-	    = xbow->xb_link_raw[link].link_aux_status;
-	lnk_sts.linkstatus = xbow->xb_link_raw[link].link_status_clr;
-
-	if (lnk_sts.link_alive == 0)
-	    continue;
-
-	xbow_llp_status->rx_err_count +=
-	    aux_sts.xb_aux_linkstatus.rx_err_cnt;
-
-	xbow_llp_status->tx_retry_count +=
-	    aux_sts.xb_aux_linkstatus.tx_retry_cnt;
-
-	if (lnk_sts.linkstatus & ~(XB_STAT_RCV_ERR | XB_STAT_XMT_RTRY_ERR | XB_STAT_LINKALIVE)) {
-#ifdef	LATER
-	    printk(KERN_WARNING  "link %d[%s]: bad status 0x%x\n",
-		    link, xwidget_name, lnk_sts.linkstatus);
-#endif
-	}
-    }
-}
-
-int
-xbow_disable_llp_monitor(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    int                     port;
-
-    for (port = 0; port < MAX_XBOW_PORTS; port++) {
-	xbow_soft->xbow_link_status[port].rx_err_count = 0;
-	xbow_soft->xbow_link_status[port].tx_retry_count = 0;
-    }
-
-    xbow_soft->link_monitor = 0;
-    return 0;
-}
-
-int
-xbow_enable_llp_monitor(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-
-    xbow_soft->link_monitor = 1;
-    return 0;
-}
-
-
-int
-xbow_reset_link(devfs_handle_t xconn_vhdl)
-{
-    xwidget_info_t          widget_info;
-    xwidgetnum_t            port;
-    xbow_t                 *xbow;
-    xbowreg_t               ctrl;
-    xbwX_stat_t             stat;
-    unsigned                itick;
-    unsigned                dtick;
-    static int              ticks_per_ms = 0;
-
-    if (!ticks_per_ms) {
-	itick = get_timestamp();
-	us_delay(1000);
-	ticks_per_ms = get_timestamp() - itick;
-    }
-    widget_info = xwidget_info_get(xconn_vhdl);
-    port = xwidget_info_id_get(widget_info);
-
-#ifdef XBOW_K1PTR			/* defined if we only have one xbow ... */
-    xbow = XBOW_K1PTR;
-#else
-    {
-	devfs_handle_t            xbow_vhdl;
-	xbow_soft_t             xbow_soft;
-
-	hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl);
-	xbow_soft = xbow_soft_get(xbow_vhdl);
-	xbow = xbow_soft->base;
-    }
-#endif
-
-    /*
-     * This requires three PIOs (reset the link, check for the
-     * reset, restore the control register for the link) plus
-     * 10us to wait for the reset. We allow up to 1ms for the
-     * widget to come out of reset before giving up and
-     * returning a failure.
-     */
-    ctrl = xbow->xb_link(port).link_control;
-    xbow->xb_link(port).link_reset = 0;
-    itick = get_timestamp();
-    while (1) {
-	stat.linkstatus = xbow->xb_link(port).link_status;
-	if (stat.link_alive)
-	    break;
-	dtick = get_timestamp() - itick;
-	if (dtick > ticks_per_ms) {
-	    return -1;			/* never came out of reset */
-	}
-	DELAY(2);			/* don't beat on link_status */
-    }
-    xbow->xb_link(port).link_control = ctrl;
-    return 0;
-}
-
-/*
- * Dump xbow registers.
- * input parameter is either a pointer to
- * the xbow chip or the vertex handle for
- * an xbow vertex.
- */
-void
-idbg_xbowregs(int64_t regs)
-{
-    xbow_t                 *xbow;
-    int                     i;
-    xb_linkregs_t          *link;
-
-    xbow = (xbow_t *) regs;
-
-#ifdef LATER
-    qprintf("Printing xbow registers starting at 0x%x\n", xbow);
-    qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n",
-	    xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper,
-	    xbow->xb_wid_err_lower, xbow->xb_wid_control,
-	    xbow->xb_wid_req_timeout);
-    qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n",
-	    xbow->xb_wid_int_upper, xbow->xb_wid_int_lower,
-	    xbow->xb_wid_err_cmdword, xbow->xb_wid_llp,
-	    xbow->xb_wid_arb_reload);
-#endif
-
-    for (i = 8; i <= 0xf; i++) {
-	link = &xbow->xb_link(i);
-#ifdef LATER
-	qprintf("Link %d registers\n", i);
-	qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n",
-		link->link_control, link->link_status,
-		link->link_arb_upper, link->link_arb_lower,
-		link->link_aux_status);
-#endif
-    }
-}
-
-
-#define XBOW_ARB_RELOAD_TICKS		25
-					/* granularity: 4 MB/s, max: 124 MB/s */
-#define GRANULARITY			((100 * 1000000) / XBOW_ARB_RELOAD_TICKS)
-
-#define XBOW_BYTES_TO_GBR(BYTES_per_s)	(int) (BYTES_per_s / GRANULARITY)
-
-#define XBOW_GBR_TO_BYTES(cnt)		(bandwidth_t) ((cnt) * GRANULARITY)
-
-#define CEILING_BYTES_TO_GBR(gbr, bytes_per_sec)	\
-			((XBOW_GBR_TO_BYTES(gbr) < bytes_per_sec) ? gbr+1 : gbr)
-
-#define XBOW_ARB_GBR_MAX		31
-
-#define ABS(x)				((x > 0) ? (x) : (-1 * x))
-					/* absolute value */
-
-int
-xbow_bytes_to_gbr(bandwidth_t old_bytes_per_sec, bandwidth_t bytes_per_sec)
-{
-    int                     gbr_granted;
-    int                     new_total_gbr;
-    int                     change_gbr;
-    bandwidth_t             new_total_bw;
-
-#ifdef GRIO_DEBUG
-    printk("xbow_bytes_to_gbr: old_bytes_per_sec %lld bytes_per_sec %lld\n",
-		old_bytes_per_sec, bytes_per_sec);
-#endif	/* GRIO_DEBUG */
-
-    gbr_granted = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(old_bytes_per_sec)),
-			old_bytes_per_sec);
-    new_total_bw = old_bytes_per_sec + bytes_per_sec;
-    new_total_gbr = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(new_total_bw)),
-			new_total_bw);
-
-    change_gbr = new_total_gbr - gbr_granted;
-
-#ifdef GRIO_DEBUG
-    printk("xbow_bytes_to_gbr: gbr_granted %d new_total_gbr %d change_gbr %d\n",
-		gbr_granted, new_total_gbr, change_gbr);
-#endif	/* GRIO_DEBUG */
-
-    return (change_gbr);
-}
-
-/* Conversion from GBR to bytes */
-bandwidth_t
-xbow_gbr_to_bytes(int gbr)
-{
-    return (XBOW_GBR_TO_BYTES(gbr));
-}
-
-/* Given the vhdl for the desired xbow, the src and dest. widget ids
- * and the req_bw value, this xbow driver entry point accesses the
- * xbow registers and allocates the desired bandwidth if available.
- *
- * If bandwidth allocation is successful, return success else return failure.
- */
-int
-xbow_prio_bw_alloc(devfs_handle_t vhdl,
-		xwidgetnum_t src_wid,
-		xwidgetnum_t dest_wid,
-		unsigned long long old_alloc_bw,
-		unsigned long long req_bw)
-{
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    volatile xbowreg_t     *xreg;
-    xbowreg_t               mask;
-    unsigned long           s;
-    int                     error = 0;
-    bandwidth_t             old_bw_BYTES, req_bw_BYTES;
-    xbowreg_t               old_xreg;
-    int                     old_bw_GBR, req_bw_GBR, new_bw_GBR;
-
-#ifdef GRIO_DEBUG
-    printk("xbow_prio_bw_alloc: vhdl %d src_wid %d dest_wid %d req_bw %lld\n",
-		(int) vhdl, (int) src_wid, (int) dest_wid, req_bw);
-#endif
-
-    ASSERT(XBOW_WIDGET_IS_VALID(src_wid));
-    ASSERT(XBOW_WIDGET_IS_VALID(dest_wid));
-
-    s = mutex_spinlock(&soft->xbow_bw_alloc_lock);
-
-    /* Get pointer to the correct register */
-    xreg = XBOW_PRIO_ARBREG_PTR(soft->base, dest_wid, src_wid);
-
-    /* Get mask for GBR count value */
-    mask = XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(src_wid);
-
-    req_bw_GBR = xbow_bytes_to_gbr(old_alloc_bw, req_bw);
-    req_bw_BYTES = (req_bw_GBR < 0) ? (-1 * xbow_gbr_to_bytes(ABS(req_bw_GBR)))
-		: xbow_gbr_to_bytes(req_bw_GBR);
-
-#ifdef GRIO_DEBUG
-    printk("req_bw %lld req_bw_BYTES %lld req_bw_GBR %d\n",
-		req_bw, req_bw_BYTES, req_bw_GBR);
-#endif	/* GRIO_DEBUG */
-
-    old_bw_BYTES = soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS];
-    old_xreg = *xreg;
-    old_bw_GBR = (((*xreg) & mask) >> XB_ARB_GBR_SHFT(src_wid));
-
-#ifdef GRIO_DEBUG
-    ASSERT(XBOW_BYTES_TO_GBR(old_bw_BYTES) == old_bw_GBR);
-
-    printk("old_bw_BYTES %lld old_bw_GBR %d\n", old_bw_BYTES, old_bw_GBR);
-
-    printk("req_bw_BYTES %lld old_bw_BYTES %lld soft->bw_hiwm %lld\n",
-		req_bw_BYTES, old_bw_BYTES,
-		soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]);
-	   
-#endif				/* GRIO_DEBUG */
-
-    /* Accept the request only if we don't exceed the destination
-     * port HIWATER_MARK *AND* the max. link GBR arbitration count
-     */
-    if (((old_bw_BYTES + req_bw_BYTES) <=
-		soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]) &&
-		(req_bw_GBR + old_bw_GBR <= XBOW_ARB_GBR_MAX)) {
-
-	new_bw_GBR = (old_bw_GBR + req_bw_GBR);
-
-	/* Set this in the xbow link register */
-	*xreg = (old_xreg & ~mask) | \
-	    (new_bw_GBR << XB_ARB_GBR_SHFT(src_wid) & mask);
-
-	soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS] =
-			xbow_gbr_to_bytes(new_bw_GBR);
-    } else {
-	error = 1;
-    }
-
-    mutex_spinunlock(&soft->xbow_bw_alloc_lock, s);
-
-    return (error);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn1/xtalk.c linux-2.4.22-pre3/arch/ia64/sn/io/sn1/xtalk.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn1/xtalk.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn1/xtalk.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1003 +0,0 @@
-/* $Id: xtalk.c,v 1.2 2002/11/21 17:51:57 jh Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-
-/*
- * Implement crosstalk provider operations.  The xtalk* layer provides a
- * platform-independent interface for crosstalk devices.  This layer
- * switches among the possible implementations of a crosstalk adapter.
- *
- * On platforms with only one possible xtalk provider, macros can be
- * set up at the top that cause the table lookups and indirections to
- * completely disappear.
- */
-
-#define	NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define	DEL(ptr)	(kfree(ptr))
-
-char                    widget_info_fingerprint[] = "widget_info";
-
-cdl_p                   xtalk_registry = NULL;
-
-#define	DEV_FUNC(dev,func)	hub_##func
-#define	CAST_PIOMAP(x)		((hub_piomap_t)(x))
-#define	CAST_DMAMAP(x)		((hub_dmamap_t)(x))
-#define	CAST_INTR(x)		((hub_intr_t)(x))
-
-/* =====================================================================
- *            Function Table of Contents
- */
-xtalk_piomap_t          xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
-void                    xtalk_piomap_free(xtalk_piomap_t);
-caddr_t                 xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t);
-void                    xtalk_piomap_done(xtalk_piomap_t);
-caddr_t                 xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned);
-caddr_t                 xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
-void                    xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
-caddr_t                 xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-static caddr_t          null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-xtalk_dmamap_t          xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    xtalk_dmamap_free(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);
-alenlist_t              xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);
-void                    xtalk_dmamap_done(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void			xtalk_dmamap_drain(xtalk_dmamap_t);
-void			xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t);
-void			xtalk_dmalist_drain(devfs_handle_t, alenlist_t);
-xtalk_intr_t            xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t);
-xtalk_intr_t            xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t);
-void                    xtalk_intr_free(xtalk_intr_t);
-int                     xtalk_intr_connect(xtalk_intr_t, xtalk_intr_setfunc_t, void *);
-void                    xtalk_intr_disconnect(xtalk_intr_t);
-devfs_handle_t            xtalk_intr_cpu_get(xtalk_intr_t);
-int                     xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
-int                     xtalk_error_devenable(devfs_handle_t, int, int);
-void                    xtalk_provider_startup(devfs_handle_t);
-void                    xtalk_provider_shutdown(devfs_handle_t);
-devfs_handle_t            xtalk_intr_dev_get(xtalk_intr_t);
-xwidgetnum_t            xtalk_intr_target_get(xtalk_intr_t);
-xtalk_intr_vector_t     xtalk_intr_vector_get(xtalk_intr_t);
-iopaddr_t               xtalk_intr_addr_get(struct xtalk_intr_s *);
-void                   *xtalk_intr_sfarg_get(xtalk_intr_t);
-devfs_handle_t            xtalk_pio_dev_get(xtalk_piomap_t);
-xwidgetnum_t            xtalk_pio_target_get(xtalk_piomap_t);
-iopaddr_t               xtalk_pio_xtalk_addr_get(xtalk_piomap_t);
-ulong                   xtalk_pio_mapsz_get(xtalk_piomap_t);
-caddr_t                 xtalk_pio_kvaddr_get(xtalk_piomap_t);
-devfs_handle_t            xtalk_dma_dev_get(xtalk_dmamap_t);
-xwidgetnum_t            xtalk_dma_target_get(xtalk_dmamap_t);
-xwidget_info_t          xwidget_info_chk(devfs_handle_t);
-xwidget_info_t          xwidget_info_get(devfs_handle_t);
-void                    xwidget_info_set(devfs_handle_t, xwidget_info_t);
-devfs_handle_t            xwidget_info_dev_get(xwidget_info_t);
-xwidgetnum_t            xwidget_info_id_get(xwidget_info_t);
-devfs_handle_t            xwidget_info_master_get(xwidget_info_t);
-xwidgetnum_t            xwidget_info_masterid_get(xwidget_info_t);
-xwidget_part_num_t      xwidget_info_part_num_get(xwidget_info_t);
-xwidget_mfg_num_t       xwidget_info_mfg_num_get(xwidget_info_t);
-char 			*xwidget_info_name_get(xwidget_info_t);
-void                    xtalk_init(void);
-void                    xtalk_provider_register(devfs_handle_t, xtalk_provider_t *);
-void                    xtalk_provider_unregister(devfs_handle_t);
-xtalk_provider_t       *xtalk_provider_fns_get(devfs_handle_t);
-int                     xwidget_driver_register(xwidget_part_num_t, 
-						xwidget_mfg_num_t, 
-						char *, unsigned);
-void                    xwidget_driver_unregister(char *);
-int                     xwidget_register(xwidget_hwid_t, devfs_handle_t, 
-					 xwidgetnum_t, devfs_handle_t, 
-					 xwidgetnum_t, async_attach_t);
-int			xwidget_unregister(devfs_handle_t);
-void                    xwidget_reset(devfs_handle_t);
-char			*xwidget_name_get(devfs_handle_t);
-#if !defined(DEV_FUNC)
-/*
- * There is more than one possible provider
- * for this platform. We need to examine the
- * master vertex of the current vertex for
- * a provider function structure, and indirect
- * through the appropriately named member.
- */
-#define	DEV_FUNC(dev,func)	xwidget_to_provider_fns(dev)->func
-#define	CAST_PIOMAP(x)		((xtalk_piomap_t)(x))
-#define	CAST_DMAMAP(x)		((xtalk_dmamap_t)(x))
-#define	CAST_INTR(x)		((xtalk_intr_t)(x))
-
-static xtalk_provider_t *
-xwidget_to_provider_fns(devfs_handle_t xconn)
-{
-    xwidget_info_t          widget_info;
-    xtalk_provider_t       *provider_fns;
-
-    widget_info = xwidget_info_get(xconn);
-    ASSERT(widget_info != NULL);
-
-    provider_fns = xwidget_info_pops_get(widget_info);
-    ASSERT(provider_fns != NULL);
-
-    return (provider_fns);
-}
-#endif
-
-/*
- * Many functions are not passed their vertex
- * information directly; rather, they must
- * dive through a resource map. These macros
- * are available to coordinate this detail.
- */
-#define	PIOMAP_FUNC(map,func)	DEV_FUNC(map->xp_dev,func)
-#define	DMAMAP_FUNC(map,func)	DEV_FUNC(map->xd_dev,func)
-#define	INTR_FUNC(intr,func)	DEV_FUNC(intr_hdl->xi_dev,func)
-
-/* =====================================================================
- *                    PIO MANAGEMENT
- *
- *      For mapping system virtual address space to
- *      xtalk space on a specified widget
- */
-
-xtalk_piomap_t
-xtalk_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
-		   size_t byte_count,
-		   size_t byte_count_max,	/* maximum size of a mapping */
-		   unsigned flags)
-{				/* defined in sys/pio.h */
-    return (xtalk_piomap_t) DEV_FUNC(dev, piomap_alloc)
-	(dev, dev_desc, xtalk_addr, byte_count, byte_count_max, flags);
-}
-
-
-void
-xtalk_piomap_free(xtalk_piomap_t xtalk_piomap)
-{
-    PIOMAP_FUNC(xtalk_piomap, piomap_free)
-	(CAST_PIOMAP(xtalk_piomap));
-}
-
-
-caddr_t
-xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap,	/* mapping resources */
-		  iopaddr_t xtalk_addr,		/* map for this xtalk address */
-		  size_t byte_count)
-{				/* map this many bytes */
-    return PIOMAP_FUNC(xtalk_piomap, piomap_addr)
-	(CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count);
-}
-
-
-void
-xtalk_piomap_done(xtalk_piomap_t xtalk_piomap)
-{
-    PIOMAP_FUNC(xtalk_piomap, piomap_done)
-	(CAST_PIOMAP(xtalk_piomap));
-}
-
-
-caddr_t
-xtalk_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    iopaddr_t xtalk_addr,	/* Crosstalk address */
-		    size_t byte_count,	/* map this many bytes */
-		    unsigned flags)
-{				/* (currently unused) */
-    return DEV_FUNC(dev, piotrans_addr)
-	(dev, dev_desc, xtalk_addr, byte_count, flags);
-}
-
-caddr_t
-xtalk_pio_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       iopaddr_t addr,		/* starting address (or offset in window) */
-	       size_t byte_count,	/* map this many bytes */
-	       xtalk_piomap_t *mapp,	/* where to return the map pointer */
-	       unsigned flags)
-{					/* PIO flags */
-    xtalk_piomap_t          map = 0;
-    caddr_t                 res;
-
-    if (mapp)
-	*mapp = 0;			/* record "no map used" */
-
-    res = xtalk_piotrans_addr
-	(dev, dev_desc, addr, byte_count, flags);
-    if (res)
-	return res;			/* xtalk_piotrans worked */
-
-    map = xtalk_piomap_alloc
-	(dev, dev_desc, addr, byte_count, byte_count, flags);
-    if (!map)
-	return res;			/* xtalk_piomap_alloc failed */
-
-    res = xtalk_piomap_addr
-	(map, addr, byte_count);
-    if (!res) {
-	xtalk_piomap_free(map);
-	return res;			/* xtalk_piomap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* xtalk_piomap_addr succeeded */
-}
-
-/* =====================================================================
- *            EARLY PIOTRANS SUPPORT
- *
- *      There are places where drivers (mgras, for instance)
- *      need to get PIO translations before the infrastructure
- *      is extended to them (setting up textports, for
- *      instance). These drivers should call
- *      xtalk_early_piotrans_addr with their xtalk ID
- *      information, a sequence number (so we can use the second
- *      mgras for instance), and the usual piotrans parameters.
- *
- *      Machine specific code should provide an implementation
- *      of early_piotrans_addr, and present a pointer to this
- *      function to xtalk_set_early_piotrans_addr so it can be
- *      used by clients without the clients having to know what
- *      platform or what xtalk provider is in use.
- */
-
-static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr;
-
-xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr;
-
-/* xtalk_set_early_piotrans_addr:
- * specify the early_piotrans_addr implementation function.
- */
-void
-xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl)
-{
-    impl_early_piotrans_addr = impl;
-}
-
-/* xtalk_early_piotrans_addr:
- * figure out a PIO address for the "nth" crosstalk widget that
- * matches the specified part and mfgr number. Returns NULL if
- * there is no such widget, or if the requested mapping can not
- * be constructed.
- * Limitations on which crosstalk slots (and busses) are
- * checked, and definitions of the ordering of the search across
- * the crosstalk slots, are defined by the platform.
- */
-caddr_t
-xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
-			  xwidget_mfg_num_t mfg_num,
-			  int which,
-			  iopaddr_t xtalk_addr,
-			  size_t byte_count,
-			  unsigned flags)
-{
-    return impl_early_piotrans_addr
-	(part_num, mfg_num, which, xtalk_addr, byte_count, flags);
-}
-
-/* null_xtalk_early_piotrans_addr:
- * used as the early_piotrans_addr implementation until and
- * unless a real implementation is provided. In DEBUG kernels,
- * we want to know who is calling before the implementation is
- * registered; in non-DEBUG kernels, return NULL representing
- * lack of mapping support.
- */
-/*ARGSUSED */
-static caddr_t
-null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
-			       xwidget_mfg_num_t mfg_num,
-			       int which,
-			       iopaddr_t xtalk_addr,
-			       size_t byte_count,
-			       unsigned flags)
-{
-#if DEBUG
-    PRINT_PANIC("null_xtalk_early_piotrans_addr");
-#endif
-    return NULL;
-}
-
-/* =====================================================================
- *                    DMA MANAGEMENT
- *
- *      For mapping from crosstalk space to system
- *      physical space.
- */
-
-xtalk_dmamap_t
-xtalk_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   size_t byte_count_max,	/* max size of a mapping */
-		   unsigned flags)
-{				/* defined in dma.h */
-    return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-	(dev, dev_desc, byte_count_max, flags);
-}
-
-
-void
-xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap)
-{
-    DMAMAP_FUNC(xtalk_dmamap, dmamap_free)
-	(CAST_DMAMAP(xtalk_dmamap));
-}
-
-
-iopaddr_t
-xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */
-		  paddr_t paddr,	/* map for this address */
-		  size_t byte_count)
-{				/* map this many bytes */
-    return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr)
-	(CAST_DMAMAP(xtalk_dmamap), paddr, byte_count);
-}
-
-
-alenlist_t
-xtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(xtalk_dmamap, dmamap_list)
-	(CAST_DMAMAP(xtalk_dmamap), alenlist, flags);
-}
-
-
-void
-xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap)
-{
-    DMAMAP_FUNC(xtalk_dmamap, dmamap_done)
-	(CAST_DMAMAP(xtalk_dmamap));
-}
-
-
-iopaddr_t
-xtalk_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    paddr_t paddr,	/* system physical address */
-		    size_t byte_count,	/* length */
-		    unsigned flags)
-{				/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_addr)
-	(dev, dev_desc, paddr, byte_count, flags);
-}
-
-
-alenlist_t
-xtalk_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{				/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
-void
-xtalk_dmamap_drain(xtalk_dmamap_t map)
-{
-    DMAMAP_FUNC(map, dmamap_drain)
-	(CAST_DMAMAP(map));
-}
-
-void
-xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
-{
-    DEV_FUNC(dev, dmaaddr_drain)
-	(dev, addr, size);
-}
-
-void
-xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-	(dev, list);
-}
-
-/* =====================================================================
- *                    INTERRUPT MANAGEMENT
- *
- *      Allow crosstalk devices to establish interrupts
- */
-
-/*
- * Allocate resources required for an interrupt as specified in intr_desc.
- * Return resource handle in intr_hdl.
- */
-xtalk_intr_t
-xtalk_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
-		 device_desc_t dev_desc,	/* device descriptor */
-		 devfs_handle_t owner_dev)
-{				/* owner of this interrupt */
-    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc)
-	(dev, dev_desc, owner_dev);
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Unconditionally setup resources to be non-threaded.
- * Return resource handle in intr_hdl.
- */
-xtalk_intr_t
-xtalk_intr_alloc_nothd(devfs_handle_t dev,	/* which Crosstalk device */
-		 	device_desc_t dev_desc,	/* device descriptor */
-		 	devfs_handle_t owner_dev)	/* owner of this interrupt */
-{
-    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)
-	(dev, dev_desc, owner_dev);
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-xtalk_intr_free(xtalk_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_free)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/*
- * Associate resources allocated with a previous xtalk_intr_alloc call with the
- * described handler, arg, name, etc.
- *
- * Returns 0 on success, returns <0 on failure.
- */
-int
-xtalk_intr_connect(xtalk_intr_t intr_hdl,	/* xtalk intr resource handle */
-		   xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */
-		   void *setfunc_arg)	/* arg to setfunc */
-{
-    return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl), setfunc, setfunc_arg);
-}
-
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-xtalk_intr_disconnect(xtalk_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_disconnect)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
-{
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/* =====================================================================
- *                    CONFIGURATION MANAGEMENT
- */
-
-/*
- * Startup a crosstalk provider
- */
-void
-xtalk_provider_startup(devfs_handle_t xtalk_provider)
-{
-    DEV_FUNC(xtalk_provider, provider_startup)
-	(xtalk_provider);
-}
-
-
-/*
- * Shutdown a crosstalk provider
- */
-void
-xtalk_provider_shutdown(devfs_handle_t xtalk_provider)
-{
-    DEV_FUNC(xtalk_provider, provider_shutdown)
-	(xtalk_provider);
-}
-
-/* 
- * Enable a device on a xtalk widget 
- */
-void
-xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
-{
-    DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum);
-}
-
-/* 
- * Shutdown a device on a xtalk widget 
- */
-void
-xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
-{
-    DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum);
-}
-
-int
-xtalk_dma_enabled(devfs_handle_t xconn_vhdl)
-{
-    return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl);
-}
-/*
- * Generic crosstalk functions, for use with all crosstalk providers
- * and all crosstalk devices.
- */
-
-/****** Generic crosstalk interrupt interfaces ******/
-devfs_handle_t
-xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_dev);
-}
-
-xwidgetnum_t
-xtalk_intr_target_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_target);
-}
-
-xtalk_intr_vector_t
-xtalk_intr_vector_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_vector);
-}
-
-iopaddr_t
-xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr)
-{
-    return (xtalk_intr->xi_addr);
-}
-
-void                   *
-xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_sfarg);
-}
-
-/****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
-xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_dev);
-}
-
-xwidgetnum_t
-xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_target);
-}
-
-iopaddr_t
-xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_xtalk_addr);
-}
-
-ulong
-xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_mapsz);
-}
-
-caddr_t
-xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_kvaddr);
-}
-
-
-/****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
-xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
-{
-    return (xtalk_dmamap->xd_dev);
-}
-
-xwidgetnum_t
-xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap)
-{
-    return (xtalk_dmamap->xd_target);
-}
-
-
-/****** Generic crosstalk widget information interfaces ******/
-
-/* xwidget_info_chk:
- * check to see if this vertex is a widget;
- * if so, return its widget_info (if any).
- * if not, return NULL.
- */
-xwidget_info_t
-xwidget_info_chk(devfs_handle_t xwidget)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo);
-    return (xwidget_info_t) ainfo;
-}
-
-
-xwidget_info_t
-xwidget_info_get(devfs_handle_t xwidget)
-{
-    xwidget_info_t          widget_info;
-
-    widget_info = (xwidget_info_t)
-	hwgraph_fastinfo_get(xwidget);
-
-#ifdef	LATER
-    if ((widget_info != NULL) &&
-	(widget_info->w_fingerprint != widget_info_fingerprint))
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	PRINT_PANIC("%v bad xwidget_info", xwidget);
-#else
-	PRINT_PANIC("%x bad xwidget_info", xwidget);
-#endif
-#endif	/* LATER */
-
-    return (widget_info);
-}
-
-void
-xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info)
-{
-    if (widget_info != NULL)
-	widget_info->w_fingerprint = widget_info_fingerprint;
-
-    hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info);
-
-    /* Also, mark this vertex as an xwidget,
-     * and use the widget_info, so xwidget_info_chk
-     * can work (and be fairly efficient).
-     */
-    hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET,
-			 (arbitrary_info_t) widget_info);
-}
-
-devfs_handle_t
-xwidget_info_dev_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_vertex);
-}
-
-xwidgetnum_t
-xwidget_info_id_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_id);
-}
-
-
-devfs_handle_t
-xwidget_info_master_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_master);
-}
-
-xwidgetnum_t
-xwidget_info_masterid_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_masterid);
-}
-
-xwidget_part_num_t
-xwidget_info_part_num_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_hwid.part_num);
-}
-
-xwidget_mfg_num_t
-xwidget_info_mfg_num_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_hwid.mfg_num);
-}
-/* Extract the widget name from the widget information
- * for the xtalk widget.
- */
-char *
-xwidget_info_name_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget info");
-    return(xwidget_info->w_name);
-}
-/****** Generic crosstalk initialization interfaces ******/
-
-/*
- * One-time initialization needed for systems that support crosstalk.
- */
-void
-xtalk_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("xtalk_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (xtalk_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr");
-	if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(xtalk_registry != NULL);
-}
-
-/*
- * Associate a set of xtalk_provider functions with a vertex.
- */
-void
-xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns)
-{
-    hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);
-}
-
-/*
- * Disassociate a set of xtalk_provider functions with a vertex.
- */
-void
-xtalk_provider_unregister(devfs_handle_t provider)
-{
-    hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);
-}
-
-/*
- * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk
- * provider.
- */
-xtalk_provider_t       *
-xtalk_provider_fns_get(devfs_handle_t provider)
-{
-    return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));
-}
-
-/*
- * Announce a driver for a particular crosstalk part.
- * Returns 0 on success or -1 on failure.  Failure occurs if the
- * specified hardware already has a driver.
- */
-/*ARGSUSED4 */
-int
-xwidget_driver_register(xwidget_part_num_t part_num,
-			xwidget_mfg_num_t mfg_num,
-			char *driver_prefix,
-			unsigned flags)
-{
-    /* a driver's init routine could call
-     * xwidget_driver_register before the
-     * system calls xtalk_init; so, we
-     * make the call here.
-     */
-    if (xtalk_registry == NULL)
-	xtalk_init();
-
-    return cdl_add_driver(xtalk_registry,
-			  part_num, mfg_num,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Inform xtalk infrastructure that a driver is no longer available for
- * handling any widgets.
- */
-void
-xwidget_driver_unregister(char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called registger; so we
-     * can assume we have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_del_driver(xtalk_registry, driver_prefix, NULL);
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-xtalk_iterate(char *driver_prefix,
-	      xtalk_iter_f *func)
-{
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func);
-}
-
-/*
- * xwidget_register:
- *	Register a xtalk device (xwidget) by doing the following.
- *      -allocate and initialize xwidget_info data
- *      -allocate a hwgraph vertex with name based on widget number (id)
- *      -look up the widget's initialization function and call it,
- *      or remember the vertex for later initialization.
- *
- */
-int
-xwidget_register(xwidget_hwid_t hwid,		/* widget's hardware ID */
-		 devfs_handle_t 	widget,		/* widget to initialize */
-		 xwidgetnum_t 	id,		/* widget's target id (0..f) */
-		 devfs_handle_t 	master,		/* widget's master vertex */
-		 xwidgetnum_t 	targetid,	/* master's target id (9/a) */
-		 async_attach_t aa)
-{			
-    xwidget_info_t          widget_info;
-    char		    *s,devnm[MAXDEVNAME];
-
-    /* Allocate widget_info and associate it with widget vertex */
-    NEW(widget_info);
-
-    /* Initialize widget_info */
-    widget_info->w_vertex = widget;
-    widget_info->w_id = id;
-    widget_info->w_master = master;
-    widget_info->w_masterid = targetid;
-    widget_info->w_hwid = *hwid;	/* structure copy */
-    widget_info->w_efunc = 0;
-    widget_info->w_einfo = 0;
-    /*
-     * get the name of this xwidget vertex and keep the info.
-     * This is needed during errors and interupts, but as
-     * long as we have it, we can use it elsewhere.
-     */
-    s = dev_to_name(widget,devnm,MAXDEVNAME);
-    widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
-    strcpy(widget_info->w_name,s);
-    
-    xwidget_info_set(widget, widget_info);
-
-    device_master_set(widget, master);
-
-    /* All the driver init routines (including
-     * xtalk_init) are called before we get into
-     * attaching devices, so we can assume we
-     * have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    /* 
-     * Add pointer to async attach info -- tear down will be done when
-     * the particular descendant is done with the info.
-     */
-    if (aa)
-	    async_attach_add_info(widget, aa);
-
-    return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                          widget, 0);
-}
-
-/*
- * xwidget_unregister :
- *	Unregister the xtalk device and detach all its hwgraph namespace.
- */
-int
-xwidget_unregister(devfs_handle_t widget)
-{
-    xwidget_info_t	widget_info;
-    xwidget_hwid_t	hwid;
-
-    /* Make sure that we have valid widget information initialized */
-    if (!(widget_info = xwidget_info_get(widget)))
-	return(1);
-
-    /* Remove the inventory information associated
-     * with the widget.
-     */
-    hwgraph_inventory_remove(widget, -1, -1, -1, -1, -1);
-    
-    hwid = &(widget_info->w_hwid);
-
-    cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                   widget, 0);
-
-    /* Clean out the xwidget information */
-    (void)kfree(widget_info->w_name);
-    BZERO((void *)widget_info, sizeof(widget_info));
-    DEL(widget_info);
-    
-    return(0);
-}
-
-/*
- * Issue a link reset to a widget.
- */
-void
-xwidget_reset(devfs_handle_t xwidget)
-{
-    xswitch_reset_link(xwidget);
-
-}
-
-
-void
-xwidget_gfx_reset(devfs_handle_t xwidget)
-{
-    xwidget_info_t info;
-
-    xswitch_reset_link(xwidget);
-    info = xwidget_info_get(xwidget);
-#ifdef LATER
-    ASSERT_ALWAYS(info != NULL);
-#endif
-
-    /*
-     * Enable this for other architectures once we add widget_reset to the
-     * xtalk provider interface.
-     */
-    DEV_FUNC(xtalk_provider, widget_reset)
-	(xwidget_info_master_get(info), xwidget_info_id_get(info));
-}
-
-#define ANON_XWIDGET_NAME	"No Name"	/* Default Widget Name */
-
-/* Get the canonical hwgraph  name of xtalk widget */
-char *
-xwidget_name_get(devfs_handle_t xwidget_vhdl)
-{
-	xwidget_info_t  info;
-
-	/* If we have a bogus widget handle then return
-	 * a default anonymous widget name.
-	 */
-	if (xwidget_vhdl == GRAPH_VERTEX_NONE)
-	    return(ANON_XWIDGET_NAME);
-	/* Read the widget name stored in the widget info
-	 * for the widget setup during widget initialization.
-	 */
-	info = xwidget_info_get(xwidget_vhdl);
-	ASSERT(info != NULL);
-	return(xwidget_info_name_get(info));
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/Makefile linux-2.4.22-pre3/arch/ia64/sn/io/sn2/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/Makefile	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/Makefile	2003-07-05 18:09:43.000000000 -0700
@@ -3,7 +3,7 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
 #
 # Makefile for the sn2 io routines.
 
@@ -15,13 +15,11 @@
 
 obj-y				+= ml_SN_intr.o shub_intr.o shuberror.o shub.o \
 				   bte_error.o pcibr/pcibr.o pic.o geo_op.o \
-				   l1.o l1_command.o klconflib.o klgraph.o \
+				   l1_command.o klconflib.o klgraph.o \
 				   ml_SN_init.o ml_iograph.o module.o pciio.o \
-				   xbow.o xtalk.o \
-				   pci_bus_cvlink.o sgi_io_init.o shubio.o
+				   xbow.o xtalk.o shubio.o
+obj-$(CONFIG_KDB)		+= kdba_io.o
 
 subdir-y			+= pcibr
 
-obj-$(CONFIG_SHUB_1_0_SPECIFIC) += efi-rtc.o
-
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/bte_error.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/bte_error.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/bte_error.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/bte_error.c	2003-07-05 18:09:43.000000000 -0700
@@ -1,10 +1,35 @@
-/* $Id: bte_error.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+/*
  *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 
 
@@ -29,121 +54,208 @@
 #include <asm/sn/sn2/shubio.h>
 #include <asm/sn/bte.h>
 
-/************************************************************************
- *									*
- * 			 BTE ERROR RECOVERY				*
- *									*
- * Given a BTE error, the node causing the error must do the following: *
- *    a) Clear all crbs relating to that BTE				*
- *		1) Read CRBA value for crb in question			*
- *		2) Mark CRB as VALID, store local physical 		*
- *		   address known to be good in the address field	*
- *		   (bte_notification_targ is a known good local		*
- *		    address).						*
- *		3) Write CRBA						*
- *		4) Using ICCR, FLUSH the CRB, and wait for it to 	*
- *		   complete.						*
- *		... BTE BUSY bit should now be clear (or at least 	*
- *		    should be after ALL CRBs associated with the 	*
- *		    transfer are complete.				*
- *									*
- *    b) Re-enable BTE							*
- *		1) Write IMEM with BTE Enable + XXX bits
- *		2) Write IECLR with BTE clear bits
- *		3) Clear IIDSR INT_SENT bits.
- *									*
- ************************************************************************/
-
-/* 
- * >>> bte_crb_error_handler needs to be broken into two parts.  The
- * first should cleanup the CRB.  The second should wait until all bte
- * related CRB's are complete and then do the error reset.
+
+/*
+ * Bte error handling is done in two parts.  The first captures
+ * any crb related errors.  Since there can be multiple crbs per
+ * interface and multiple interfaces active, we need to wait until
+ * all active crbs are completed.  This is the first job of the
+ * second part error handler.  When all bte related CRBs are cleanly
+ * completed, it resets the interfaces and gets them ready for new
+ * transfers to be queued.
  */
-void
-bte_crb_error_handler(devfs_handle_t hub_v, int btenum, 
-		      int crbnum, ioerror_t *ioe, int bteop)
+
+
+void bte_error_handler(unsigned long);
+
+
 /*
- * Function: 	bte_crb_error_handler
- * Purpose:	Process a CRB for a specific HUB/BTE
- * Parameters:	hub_v	- vertex of hub in HW graph
- *		btenum	- bte number on hub (0 == a, 1 == b)
- *		crbnum	- crb number being processed
- * Notes: 
- *	This routine assumes serialization at a higher level. A CRB 
- *	should not be processed more than once. The error recovery 
- *	follows the following sequence - if you change this, be real
- *	sure about what you are doing. 
- *
+ * First part error handler.  This is called whenever any error CRB interrupt
+ * is generated by the II.
  */
+void
+bte_crb_error_handler(vertex_hdl_t hub_v, int btenum,
+		      int crbnum, ioerror_t * ioe, int bteop)
 {
-        hubinfo_t	hinfo;
-	icrba_t		crba; 
-	icrbb_t		crbb; 
-	nasid_t		n;
-	hubreg_t	iidsr, imem, ieclr;
+	hubinfo_t hinfo;
+	struct bteinfo_s *bte;
+
 
 	hubinfo_get(hub_v, &hinfo);
+	bte = &hinfo->h_nodepda->bte_if[btenum];
+
+	/*
+	 * The caller has already figured out the error type, we save that
+	 * in the bte handle structure for the thread excercising the
+	 * interface to consume.
+	 */
+	switch (ioe->ie_errortype) {
+	case IIO_ICRB_ECODE_PERR:
+		bte->bh_error = BTEFAIL_POISON;
+		break;
+	case IIO_ICRB_ECODE_WERR:
+		bte->bh_error = BTEFAIL_PROT;
+		break;
+	case IIO_ICRB_ECODE_AERR:
+		bte->bh_error = BTEFAIL_ACCESS;
+		break;
+	case IIO_ICRB_ECODE_TOUT:
+		bte->bh_error = BTEFAIL_TOUT;
+		break;
+	case IIO_ICRB_ECODE_XTERR:
+		bte->bh_error = BTEFAIL_XTERR;
+		break;
+	case IIO_ICRB_ECODE_DERR:
+		bte->bh_error = BTEFAIL_DIR;
+		break;
+	case IIO_ICRB_ECODE_PWERR:
+	case IIO_ICRB_ECODE_PRERR:
+		/* NO BREAK */
+	default:
+		bte->bh_error = BTEFAIL_ERROR;
+	}
+
+	bte->bte_error_count++;
 
+	BTE_PRINTK(("Got an error on cnode %d bte %d\n",
+		    bte->bte_cnode, bte->bte_num));
+	bte_error_handler((unsigned long) hinfo->h_nodepda);
+}
 
-	n = hinfo->h_nasid;
-	
 
+/*
+ * Second part error handler.  Wait until all BTE related CRBs are completed
+ * and then reset the interfaces.
+ */
+void
+bte_error_handler(unsigned long _nodepda)
+{
+	struct nodepda_s *err_nodepda = (struct nodepda_s *) _nodepda;
+	spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock;
+	struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
+	nasid_t nasid;
+	int i;
+	int valid_crbs;
+	unsigned long irq_flags;
+	volatile u64 *notify;
+	bte_result_t bh_error;
+	ii_imem_u_t imem;	/* II IMEM Register */
+	ii_icrb0_d_u_t icrbd;	/* II CRB Register D */
+	ii_ibcr_u_t ibcr;
+	ii_icmr_u_t icmr;
+
+
+	BTE_PRINTK(("bte_error_handler(%p) - %d\n", err_nodepda,
+		    smp_processor_id()));
+
+	spin_lock_irqsave(recovery_lock, irq_flags);
+
+	if ((err_nodepda->bte_if[0].bh_error == BTE_SUCCESS) &&
+	    (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) {
+		BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda,
+			    smp_processor_id()));
+		spin_unlock_irqrestore(recovery_lock, irq_flags);
+		return;
+	}
 	/*
-	 * The following 10 lines (or so) are adapted from IRIXs
-	 * bte_crb_error function.  No clear documentation tells
-	 * why the crb needs to complete normally in order for
-	 * the BTE to resume normal operations.  This first step
-	 * appears vital!
+	 * Lock all interfaces on this node to prevent new transfers
+	 * from being queued.
 	 */
+	for (i = 0; i < BTES_PER_NODE; i++) {
+		if (err_nodepda->bte_if[i].cleanup_active) {
+			continue;
+		}
+		spin_lock(&err_nodepda->bte_if[i].spinlock);
+		BTE_PRINTK(("eh:%p:%d locked %d\n", err_nodepda,
+			    smp_processor_id(), i));
+		err_nodepda->bte_if[i].cleanup_active = 1;
+	}
+
+	/* Determine information about our hub */
+	nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode);
+
 
 	/*
-	 * Zero error and error code to prevent error_dump complaining
-	 * about these CRBs. Copy the CRB to the notification line.
-	 * The crb address is in shub format (physical address shifted
-	 * right by cacheline size).
+	 * A BTE transfer can use multiple CRBs.  We need to make sure
+	 * that all the BTE CRBs are complete (or timed out) before
+	 * attempting to clean up the error.  Resetting the BTE while
+	 * there are still BTE CRBs active will hang the BTE.
+	 * We should look at all the CRBs to see if they are allocated
+	 * to the BTE and see if they are still active.  When none
+	 * are active, we can continue with the cleanup.
+	 *
+	 * We also want to make sure that the local NI port is up.
+	 * When a router resets the NI port can go down, while it
+	 * goes through the LLP handshake, but then comes back up.
 	 */
-	crbb.ii_icrb0_b_regval = REMOTE_HUB_L(n, IIO_ICRB_B(crbnum));
-	crbb.b_error=0;
-	crbb.b_ecode=0;
-	REMOTE_HUB_S(n, IIO_ICRB_B(crbnum), crbb.ii_icrb0_b_regval);
-
-	crba.ii_icrb0_a_regval = REMOTE_HUB_L(n, IIO_ICRB_A(crbnum));
-	crba.a_addr = TO_PHYS((u64)&nodepda->bte_if[btenum].notify) >> 3;
-	crba.a_valid = 1;
-	REMOTE_HUB_S(n, IIO_ICRB_A(crbnum), crba.ii_icrb0_a_regval);
-
-	REMOTE_HUB_S(n, IIO_ICCR, 
-		     IIO_ICCR_PENDING | IIO_ICCR_CMD_FLUSH | crbnum);
-
-	while (REMOTE_HUB_L(n, IIO_ICCR) & IIO_ICCR_PENDING)
-	    ;
-
-
-	/* Terminate the BTE. */
-	/* >>> The other bte transfer will need to be restarted. */
-	HUB_L((shubreg_t *)((nodepda->bte_if[btenum].bte_base_addr +
-		       IIO_IBCT0 - IIO_IBLS0)));
-
-	imem = REMOTE_HUB_L(n, IIO_IMEM);
-	ieclr = REMOTE_HUB_L(n, IIO_IECLR);
-	if (btenum == 0) {
-		imem |= IIO_IMEM_W0ESD | IIO_IMEM_B0ESD;
-		ieclr|= IECLR_BTE0;
-	} else {
-		imem |= IIO_IMEM_W0ESD | IIO_IMEM_B1ESD;
-		ieclr|= IECLR_BTE1;
-	}
-	REMOTE_HUB_S(n, IIO_IMEM, imem);
-	REMOTE_HUB_S(n, IIO_IECLR, ieclr);
-		
-	iidsr  = REMOTE_HUB_L(n, IIO_IIDSR);
-	iidsr &= ~IIO_IIDSR_SENT_MASK;
-	iidsr |= IIO_IIDSR_ENB_MASK;
-	REMOTE_HUB_S(n, IIO_IIDSR, iidsr);
+	icmr.ii_icmr_regval = REMOTE_HUB_L(nasid, IIO_ICMR);
+	if (icmr.ii_icmr_fld_s.i_crb_mark != 0) {
+		/*
+		 * There are errors which still need to be cleaned up by
+		 * hubiio_crb_error_handler
+		 */
+		mod_timer(recovery_timer, HZ * 5);
+		BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
+			    smp_processor_id()));
+		spin_unlock_irqrestore(recovery_lock, irq_flags);
+		return;
+	}
+	if (icmr.ii_icmr_fld_s.i_crb_vld != 0) {
 
+		valid_crbs = icmr.ii_icmr_fld_s.i_crb_vld;
 
- 	bte_reset_nasid(n);
+		for (i = 0; i < IIO_NUM_CRBS; i++) {
+			if (!((1 << i) & valid_crbs)) {
+				/* This crb was not marked as valid, ignore */
+				continue;
+			}
+			icrbd.ii_icrb0_d_regval =
+			    REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
+			if (icrbd.d_bteop) {
+				mod_timer(recovery_timer, HZ * 5);
+				BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n",
+					 err_nodepda, smp_processor_id(), i));
+				spin_unlock_irqrestore(recovery_lock,
+						       irq_flags);
+				return;
+			}
+		}
+	}
 
-	*nodepda->bte_if[btenum].most_rcnt_na = IBLS_ERROR;
-}
 
+	BTE_PRINTK(("eh:%p:%d Cleaning up\n", err_nodepda,
+		    smp_processor_id()));
+	/* Reenable both bte interfaces */
+	imem.ii_imem_regval = REMOTE_HUB_L(nasid, IIO_IMEM);
+	imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1;
+	REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval);
+
+	/* Reinitialize both BTE state machines. */
+	ibcr.ii_ibcr_regval = REMOTE_HUB_L(nasid, IIO_IBCR);
+	ibcr.ii_ibcr_fld_s.i_soft_reset = 1;
+	REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval);
+
+
+	for (i = 0; i < BTES_PER_NODE; i++) {
+		bh_error = err_nodepda->bte_if[i].bh_error;
+		if (bh_error != BTE_SUCCESS) {
+			/* There is an error which needs to be notified */
+			notify = err_nodepda->bte_if[i].most_rcnt_na;
+			BTE_PRINTK(("cnode %d bte %d error=0x%lx\n",
+				    err_nodepda->bte_if[i].bte_cnode,
+				    err_nodepda->bte_if[i].bte_num,
+				    IBLS_ERROR | (u64) bh_error));
+			*notify = IBLS_ERROR | bh_error;
+			err_nodepda->bte_if[i].bh_error = BTE_SUCCESS;
+		}
+
+		err_nodepda->bte_if[i].cleanup_active = 0;
+		BTE_PRINTK(("eh:%p:%d Unlocked %d\n", err_nodepda,
+			    smp_processor_id(), i));
+		spin_unlock(&pda.cpu_bte_if[i]->spinlock);
+	}
+
+	del_timer(recovery_timer);
+
+	spin_unlock_irqrestore(recovery_lock, irq_flags);
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/efi-rtc.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/efi-rtc.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/efi-rtc.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/efi-rtc.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,202 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
- * Copyright (C) 2001 by Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/efi.h>
-#include <asm/sn/klclock.h>
-
-/*
- * No locking necessary when this is called from efirtc which protects us
- * from racing by efi_rtc_lock.
- */
-#define __swizzle(addr) ((u8 *)((unsigned long)(addr) ^ 3))
-#define read_io_port(addr) (*(volatile u8 *) __swizzle(addr))
-#define write_io_port(addr, data) (*(volatile u8 *) __swizzle(addr) = (data))
-
-#define TOD_SGS_M48T35		1
-#define TOD_DALLAS_DS1386	2
-
-#define TYPE_IOC3		1
-#define TYPE_IOC4		2
-
-static unsigned long nvram_base = 0;
-static int tod_chip_type;
-static int ioc_type;
-
-static int
-get_tod_chip_type(void)
-{
-	unsigned char testval;
-
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-	write_io_port(RTC_DAL_DAY_ADDR, 0xff);
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-
-	testval = read_io_port(RTC_DAL_DAY_ADDR);
-	if (testval == 0xff)
-		return TOD_SGS_M48T35;
-
-	return TOD_DALLAS_DS1386;
-}
-
-efi_status_t
-ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	memset(time, 0, sizeof(*time));
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT);
-
-		time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF;
-		time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR));
-		time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR));
-		time->nanosecond = 0;
-
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-
-		time->nanosecond = 0;
-		time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR));
-		time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR));
-		time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF;
-
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	if (caps) {
-		caps->resolution = 50000000;	/*  50PPM */
-		caps->accuracy = 1000;		/*  1ms */
-		caps->sets_to_zero = 0;
-	}
-
-	return EFI_SUCCESS;
-}
-
-static efi_status_t ioc3_set_time (efi_time_t *t)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_WRITE_ENABLE);
-        	write_io_port(RTC_SGS_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_SGS_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_SGS_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_SGS_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_SGS_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_SGS_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-		write_io_port(RTC_DAL_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_DAL_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_DAL_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_DAL_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_DAL_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_DAL_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	return EFI_SUCCESS;
-}
-
-/* The following two are not supported atm.  */
-static efi_status_t
-ioc3_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static efi_status_t
-ioc3_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static __init int efi_ioc_time_init(void)
-{
-	struct pci_dev *dev = NULL;
-	static void *ioc_base;
-
-        while ( (dev = pci_find_subsys(PCI_VENDOR_ID_SGI,
-                               PCI_ANY_ID,
-                               PCI_ANY_ID,
-                               PCI_ANY_ID, dev))) {
-		if ( dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-			ioc_type = TYPE_IOC3;
-			break;
-		}
-		else if ( dev->device == PCI_DEVICE_ID_SGI_IOC4 ) {
-			ioc_type = TYPE_IOC4;
-			break;
-		}
-		else
-			;; // keep looking
-	}
-
-	if ( !dev ) {
-		printk(KERN_CRIT "Couldn't find master IOC\n");
-		return -ENODEV;
-	}
-
-	ioc_base = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0));
-	if ( ioc_type == TYPE_IOC3 )
-		nvram_base = (unsigned long) ioc_base + IOC3_BYTEBUS_DEV0;
-	if ( ioc_type == TYPE_IOC4 )
-		nvram_base = (unsigned long) ioc_base + IOC4_BYTEBUS_DEV0;
-
-	tod_chip_type = get_tod_chip_type();
-	if (tod_chip_type == 1)
-		printk(KERN_NOTICE "TOD type is SGS M48T35\n");
-	else if (tod_chip_type == 2)
-		printk(KERN_NOTICE "TOD type is Dallas DS1386\n");
-	else
-		printk(KERN_CRIT "No or unknown TOD\n");
-
-	efi.get_time = ioc3_get_time;
-	efi.set_time = ioc3_set_time;
-	efi.get_wakeup_time = ioc3_get_wakeup_time;
-	efi.set_wakeup_time = ioc3_set_wakeup_time;
-
-	return 0;
-}
-
-module_init(efi_ioc_time_init);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/geo_op.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/geo_op.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/geo_op.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/geo_op.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 /*
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/kdba_io.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/kdba_io.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/kdba_io.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/kdba_io.c	2003-07-05 18:09:44.000000000 -0700
@@ -0,0 +1,76 @@
+/*
+ * Kernel Debugger Architecture Dependent POD functions.
+ *
+ * Copyright (C) 1999-2003 Silicon Graphics, Inc.  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA  94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/types.h>
+#include <linux/kdb.h>
+//#include <linux/kdbprivate.h>
+
+/**
+ * kdba_io - enter POD mode from kdb
+ * @argc: arg count
+ * @argv: arg values
+ * @envp: kdb env. vars
+ * @regs: current register state
+ *
+ * Enter POD mode from kdb using SGI SN specific SAL function call.
+ */
+static int
+kdba_io(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+	kdb_printf("kdba_io entered with addr 0x%p\n", (void *) regs);
+
+        return(0);
+}
+
+/**
+ * kdba_io_init - register 'io' command with kdb
+ *
+ * Register the 'io' command with kdb at load time.
+ */
+void
+kdba_io_init(void)
+{
+        kdb_register("io", kdba_io, "<vaddr>", "Display IO Contents", 0);
+}
+
+/**
+ * kdba_io_exit - unregister the 'io' command
+ *
+ * Tell kdb that the 'io' command is no longer available.
+ */
+static void __exit
+kdba_exit(void)
+{
+        kdb_unregister("io");
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/klconflib.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/klconflib.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/klconflib.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/klconflib.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -24,8 +24,6 @@
 #include <asm/sn/router.h>
 #include <asm/sn/xtalk/xbow.h>
 
-#define printf printk
-int hasmetarouter;
 
 #define LDEBUG 0
 #define NIC_UNKNOWN ((nic_t) -1)
@@ -37,10 +35,11 @@
 #define DBG(x...)
 #endif /* DEBUG_KLGRAPH */
 
-static void sort_nic_names(lboard_t *) ;
-
 u64 klgraph_addr[MAX_COMPACT_NODES];
-int module_number = 0;
+static int hasmetarouter;
+
+
+char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#=012345";
 
 lboard_t *
 find_lboard(lboard_t *start, unsigned char brd_type)
@@ -135,23 +134,6 @@
         return (lboard_t *)NULL;
 }
 
-lboard_t *
-find_lboard_module_class(lboard_t *start, geoid_t geoid,
-                                                unsigned char brd_type)
-{
-	while (start) {
-		DBG("find_lboard_module_class: lboard 0x%p, start->brd_geoid 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_geoid, geoid, start->brd_type, brd_type);
-
-		if (geo_cmp(start->brd_geoid, geoid) &&
-			(KLCLASS(start->brd_type) == KLCLASS(brd_type)))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
 /*
  * Convert a NIC name to a name for use in the hardware graph.
  */
@@ -205,63 +187,6 @@
 }
 
 /*
- * Find the lboard structure and get the board name.
- * If we can't find the structure or it's too low a revision,
- * use default name.
- */
-lboard_t *
-get_board_name(nasid_t nasid, geoid_t geoid, slotid_t slot, char *name)
-{
-	lboard_t *brd;
-
-	brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid),
-				  geoid);
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-			brd = find_lboard_modslot((lboard_t *)
-				KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				geoid);
-	}
-#endif
-
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, name);
-	}
-
-	/*
-	 * PV # 540860
-	 * If the name is not 'baseio'
-	 * get the lowest of all the names in the nic string.
-	 * This is needed for boards like divo, which can have
-	 * a bunch of daughter cards, but would like to be called
-	 * divo. We could do this for baseio
-	 * but it has some special case names that we would not
-	 * like to disturb at this point.
-	 */
-
-	/* gfx boards don't need any of this name scrambling */
-	if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) {
-		return(brd);
-	}
-
-	if (!(!strcmp(name, "baseio") )) {
-		if (brd) {
-			sort_nic_names(brd) ;
-			/* Convert to small case, '-' to '_' etc */
-			nic_name_convert(brd->brd_name, name) ;
-		}
-	}
-
-	return(brd);
-}
-
-/*
  * get_actual_nasid
  *
  *	Completely disabled brds have their klconfig on 
@@ -341,12 +266,20 @@
 			board_name = EDGE_LBL_IO;
 			break;
 		case KLCLASS_IOBRICK:
-			if (brd->brd_type == KLTYPE_PBRICK)
+			if (brd->brd_type == KLTYPE_PXBRICK)
+				board_name = EDGE_LBL_PXBRICK;
+			else if (brd->brd_type == KLTYPE_IXBRICK)
+				board_name = EDGE_LBL_IXBRICK;
+			else if (brd->brd_type == KLTYPE_PBRICK)
 				board_name = EDGE_LBL_PBRICK;
 			else if (brd->brd_type == KLTYPE_IBRICK)
 				board_name = EDGE_LBL_IBRICK;
 			else if (brd->brd_type == KLTYPE_XBRICK)
 				board_name = EDGE_LBL_XBRICK;
+			else if (brd->brd_type == KLTYPE_PEBRICK)
+				board_name = EDGE_LBL_PEBRICK;
+			else if (brd->brd_type == KLTYPE_CGBRICK)
+				board_name = EDGE_LBL_CGBRICK;
 			else
 				board_name = EDGE_LBL_IOBRICK;
 			break;
@@ -623,185 +556,6 @@
 
 #include "asm/sn/sn_private.h"
 
-xwidgetnum_t
-nodevertex_widgetnum_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, 
-			     (arbitrary_info_t *) &hubinfo_p);
-	return(hubinfo_p->h_widgetid);
-}
-
-devfs_handle_t
-nodevertex_xbow_peer_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-	nasid_t xbow_peer_nasid;
-	cnodeid_t xbow_peer;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO,
-				     (arbitrary_info_t *) &hubinfo_p);
-	xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer;
-	if(xbow_peer_nasid == INVALID_NASID) 
-			return ( (devfs_handle_t)-1);
-	xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid);
-	return(NODEPDA(xbow_peer)->node_vertex);
-}
-
-/* NIC Sorting Support */
-
-#define MAX_NICS_PER_STRING 	32
-#define MAX_NIC_NAME_LEN	32
-
-static char *
-get_nic_string(lboard_t *lb)
-{
-        int         	i;
-        klinfo_t    	*k = NULL ;
-    	klconf_off_t    mfg_off = 0 ;
-    	char            *mfg_nic = NULL ;
-
-        for (i = 0; i < KLCF_NUM_COMPS(lb); i++) {
-                k = KLCF_COMP(lb, i) ;
-                switch(k->struct_type) {
-                        case KLSTRUCT_BRI:
-            			mfg_off = ((klbri_t *)k)->bri_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_HUB:
-            			mfg_off = ((klhub_t *)k)->hub_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_ROU:
-            			mfg_off = ((klrou_t *)k)->rou_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GFX:
-            			mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_TPU:
-            			mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GSN_A:
-                        case KLSTRUCT_GSN_B:
-            			mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_XTHD:
-                                mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ;
-                                break;
-
-			default:
-				mfg_off = 0 ;
-                                break ;
-                }
-		if (mfg_off)
-			break ;
-        }
-
-	if ((mfg_off) && (k))
-		mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ;
-
-        return mfg_nic ;
-}
-
-char *
-get_first_string(char **ptrs, int n)
-{
-        int     i ;
-        char    *tmpptr ;
-
-        if ((ptrs == NULL) || (n == 0))
-                return NULL ;
-
-        tmpptr = ptrs[0] ;
-
-        if (n == 1)
-                return tmpptr ;
-
-        for (i = 0 ; i < n ; i++) {
-                if (strcmp(tmpptr, ptrs[i]) > 0)
-                        tmpptr = ptrs[i] ;
-        }
-
-        return tmpptr ;
-}
-
-int
-get_ptrs(char *idata, char **ptrs, int n, char *label)
-{
-        int     i = 0 ;
-        char    *tmp = idata ;
-
-        if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0))
-                return 0 ;
-
-        while  ( (tmp = strstr(tmp, label)) ){
-                tmp += strlen(label) ;
-                /* check for empty name field, and last NULL ptr */
-                if ((i < (n-1)) && (*tmp != ';')) {
-                        ptrs[i++] = tmp ;
-                }
-        }
-
-        ptrs[i] = NULL ;
-
-        return i ;
-}
-
-/*
- * sort_nic_names
- *
- * 	Does not really do sorting. Find the alphabetically lowest
- *	name among all the nic names found in a nic string.
- *
- * Return:
- *	Nothing
- *
- * Side Effects:
- *
- *	lb->brd_name gets the new name found
- */
-
-static void
-sort_nic_names(lboard_t *lb)
-{
-	char 	*nic_str ;
-        char    *ptrs[MAX_NICS_PER_STRING] ;
-        char    name[MAX_NIC_NAME_LEN] ;
-        char    *tmp, *tmp1 ;
-
-	*name = 0 ;
-
-	/* Get the nic pointer from the lb */
-
-	if ((nic_str = get_nic_string(lb)) == NULL)
-		return ;
-
-        tmp = get_first_string(ptrs,
-                        get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ;
-
-        if (tmp == NULL)
-		return ;
-
-        if  ( (tmp1 = strchr(tmp, ';')) ){
-                strncpy(name, tmp, tmp1-tmp) ;
-                name[tmp1-tmp] = 0 ;
-        } else {
-                strncpy(name, tmp, (sizeof(name) -1)) ;
-                name[sizeof(name)-1] = 0 ;
-        }
-
-	strcpy(lb->brd_name, name) ;
-}
-
-
-
-char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#012345";
-
 /*
  * Format a module id for printing.
  */
@@ -814,6 +568,7 @@
 	rack = MODULE_GET_RACK(m);
 	ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES);
 	brickchar = MODULE_GET_BTCHAR(m);
+
 	position = MODULE_GET_BPOS(m);
 
 	if (fmt == MODULE_FORMAT_BRIEF) {
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/klgraph.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/klgraph.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/klgraph.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/klgraph.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 /*
@@ -23,7 +23,6 @@
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
 #include <asm/sn/kldir.h>
-#include <asm/sn/gda.h> 
 #include <asm/sn/klconfig.h>
 #include <asm/sn/router.h>
 #include <asm/sn/xtalk/xbow.h>
@@ -42,7 +41,7 @@
 
 extern char arg_maxnodes[];
 extern u64 klgraph_addr[];
-void mark_cpuvertex_as_cpu(devfs_handle_t vhdl, cpuid_t cpuid);
+void mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid);
 
 
 /*
@@ -69,7 +68,7 @@
  * Add detailed disabled cpu inventory info to the hardware graph.
  */
 void
-klhwg_disabled_cpu_invent_info(devfs_handle_t cpuv,
+klhwg_disabled_cpu_invent_info(vertex_hdl_t cpuv,
                                cnodeid_t cnode,
                                klcpu_t *cpu, slotid_t slot)
 {
@@ -118,7 +117,7 @@
  * Add detailed cpu inventory info to the hardware graph.
  */
 void
-klhwg_cpu_invent_info(devfs_handle_t cpuv,
+klhwg_cpu_invent_info(vertex_hdl_t cpuv,
 			cnodeid_t cnode,
 			klcpu_t *cpu)
 {
@@ -153,7 +152,7 @@
  * as a part of detailed inventory info in the hwgraph.
  */
 void
-klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode)
+klhwg_baseio_inventory_add(vertex_hdl_t baseio_vhdl,cnodeid_t cnode)
 {
 	invent_miscinfo_t	*baseio_inventory;
 	unsigned char		version = 0,revision = 0;
@@ -177,20 +176,11 @@
 				sizeof(invent_miscinfo_t));
 }
 
-char	*hub_rev[] = {
-	"0.0",
-	"1.0",
-	"2.0",
-	"2.1",
-	"2.2",
-	"2.3"
-};
-
 /*
  * Add detailed cpu inventory info to the hardware graph.
  */
 void
-klhwg_hub_invent_info(devfs_handle_t hubv,
+klhwg_hub_invent_info(vertex_hdl_t hubv,
 		      cnodeid_t cnode, 
 		      klhub_t *hub)
 {
@@ -215,10 +205,10 @@
 
 /* ARGSUSED */
 void
-klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode)
+klhwg_add_hub(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode)
 {
-	devfs_handle_t myhubv;
-	devfs_handle_t hub_mon;
+	vertex_hdl_t myhubv;
+	vertex_hdl_t hub_mon;
 	int rc;
 	extern struct file_operations shub_mon_fops;
 
@@ -234,9 +224,9 @@
 
 /* ARGSUSED */
 void
-klhwg_add_disabled_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot)
+klhwg_add_disabled_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot)
 {
-        devfs_handle_t my_cpu;
+        vertex_hdl_t my_cpu;
         char name[120];
         cpuid_t cpu_id;
 	nasid_t nasid;
@@ -257,9 +247,9 @@
 
 /* ARGSUSED */
 void
-klhwg_add_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu)
+klhwg_add_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu)
 {
-        devfs_handle_t my_cpu, cpu_dir;
+        vertex_hdl_t my_cpu, cpu_dir;
         char name[120];
         cpuid_t cpu_id;
 	nasid_t nasid;
@@ -295,7 +285,7 @@
 	nasid_t hub_nasid;
 	cnodeid_t hub_cnode;
 	int widgetnum;
-	devfs_handle_t xbow_v, hubv;
+	vertex_hdl_t xbow_v, hubv;
 	/*REFERENCED*/
 	graph_error_t err;
 
@@ -363,12 +353,12 @@
 
 /* ARGSUSED */
 void
-klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap)
+klhwg_add_node(vertex_hdl_t hwgraph_root, cnodeid_t cnode)
 {
 	nasid_t nasid;
 	lboard_t *brd;
 	klhub_t *hub;
-	devfs_handle_t node_vertex = NULL;
+	vertex_hdl_t node_vertex = NULL;
 	char path_buffer[100];
 	int rv;
 	char *s;
@@ -382,7 +372,7 @@
 	ASSERT(brd);
 
 	do {
-		devfs_handle_t cpu_dir;
+		vertex_hdl_t cpu_dir;
 
 		/* Generate a hardware graph path for this board. */
 		board_to_path(brd, path_buffer);
@@ -443,7 +433,7 @@
 		while (cpu) {
 			cpuid_t cpu_id;
 			cpu_id = nasid_slice_to_cpuid(nasid,cpu->cpu_info.physid);
-			if (cpu_enabled(cpu_id))
+			if (cpu_online(cpu_id))
 				klhwg_add_cpu(node_vertex, cnode, cpu);
 			else
 				klhwg_add_disabled_cpu(node_vertex, cnode, cpu, brd->brd_slot);
@@ -466,12 +456,12 @@
 
 /* ARGSUSED */
 void
-klhwg_add_all_routers(devfs_handle_t hwgraph_root)
+klhwg_add_all_routers(vertex_hdl_t hwgraph_root)
 {
 	nasid_t nasid;
 	cnodeid_t cnode;
 	lboard_t *brd;
-	devfs_handle_t node_vertex;
+	vertex_hdl_t node_vertex;
 	char path_buffer[100];
 	int rv;
 
@@ -525,14 +515,14 @@
 
 /* ARGSUSED */
 void
-klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd,
+klhwg_connect_one_router(vertex_hdl_t hwgraph_root, lboard_t *brd,
 			 cnodeid_t cnode, nasid_t nasid)
 {
 	klrou_t *router;
 	char path_buffer[50];
 	char dest_path[50];
-	devfs_handle_t router_hndl;
-	devfs_handle_t dest_hndl;
+	vertex_hdl_t router_hndl;
+	vertex_hdl_t dest_hndl;
 	int rc;
 	int port;
 	lboard_t *dest_brd;
@@ -619,7 +609,7 @@
 
 
 void
-klhwg_connect_routers(devfs_handle_t hwgraph_root)
+klhwg_connect_routers(vertex_hdl_t hwgraph_root)
 {
 	nasid_t nasid;
 	cnodeid_t cnode;
@@ -652,15 +642,15 @@
 
 
 void
-klhwg_connect_hubs(devfs_handle_t hwgraph_root)
+klhwg_connect_hubs(vertex_hdl_t hwgraph_root)
 {
 	nasid_t nasid;
 	cnodeid_t cnode;
 	lboard_t *brd;
 	klhub_t *hub;
 	lboard_t *dest_brd;
-	devfs_handle_t hub_hndl;
-	devfs_handle_t dest_hndl;
+	vertex_hdl_t hub_hndl;
+	vertex_hdl_t dest_hndl;
 	char path_buffer[50];
 	char dest_path[50];
 	graph_error_t rc;
@@ -796,12 +786,12 @@
 }
 
 void
-klhwg_add_all_modules(devfs_handle_t hwgraph_root)
+klhwg_add_all_modules(vertex_hdl_t hwgraph_root)
 {
 	cmoduleid_t	cm;
 	char		name[128];
-	devfs_handle_t	vhdl;
-	devfs_handle_t  module_vhdl;
+	vertex_hdl_t	vhdl;
+	vertex_hdl_t  module_vhdl;
 	int		rc;
 	char		buffer[16];
 
@@ -837,12 +827,12 @@
 }
 
 void
-klhwg_add_all_nodes(devfs_handle_t hwgraph_root)
+klhwg_add_all_nodes(vertex_hdl_t hwgraph_root)
 {
 	cnodeid_t	cnode;
 
 	for (cnode = 0; cnode < numnodes; cnode++) {
-		klhwg_add_node(hwgraph_root, cnode, NULL);
+		klhwg_add_node(hwgraph_root, cnode);
 	}
 
 	for (cnode = 0; cnode < numnodes; cnode++) {
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/l1.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/l1.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/l1.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/l1.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,239 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/* In general, this file is organized in a hierarchy from lower-level
- * to higher-level layers, as follows:
- *
- *	UART routines
- *	Bedrock/L1 "PPP-like" protocol implementation
- *	System controller "message" interface (allows multiplexing
- *		of various kinds of requests and responses with
- *		console I/O)
- *	Console interface:
- *	  "l1_cons", the glue that allows the L1 to act
- *		as the system console for the stdio libraries
- *
- * Routines making use of the system controller "message"-style interface
- * can be found in l1_command.c.
- */
-
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/uart16550.h>
-#include <asm/sn/simulator.h>
-
-
-#define UART_BAUD_RATE          57600
-
-int 
-get_L1_baud(void)
-{
-    return UART_BAUD_RATE;
-}
-
-
-
-/* Return the current interrupt level */
-int
-l1_get_intr_value( void )
-{
-	return(0);
-}
-
-/* Disconnect the callup functions - throw away interrupts */
-
-void
-l1_unconnect_intr(void)
-{
-}
-
-/* Set up uart interrupt handling for this node's uart */
-
-void
-l1_connect_intr(void *rx_notify, void *tx_notify)
-{
-#if 0
-	// Will need code here for sn2 - something like this
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid());
-	intr_connect_level(console_nodepda->node_first_cpu,
-                                SGI_UART_VECTOR, INTPEND0_MAXMASK,
-                                dummy_intr_func);
-	request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8),
-                                intr_func, SA_INTERRUPT | SA_SHIRQ,
-                                "l1_protocol_driver", (void *)sc);
-#endif
-}
-
-
-/* These are functions to use from serial_in/out when in protocol
- * mode to send and receive uart control regs. These are external
- * interfaces into the protocol driver.
- */
-
-void
-l1_control_out(int offset, int value)
-{
-	/* quietly ignore unless simulator */
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		if ( master_node_bedrock_address != (u64)0 ) {
-			writeb(value, (unsigned long)master_node_bedrock_address +
-				(offset<< 3));
-		}
-		return;
-	}
-}
-
-/* Console input exported interface. Return a register value.  */
-
-int
-l1_control_in_polled(int offset)
-{
-	static int l1_control_in_local(int);
-
-	return(l1_control_in_local(offset));
-}
-
-int
-l1_control_in(int offset)
-{
-	static int l1_control_in_local(int);
-
-	return(l1_control_in_local(offset));
-}
-
-static int
-l1_control_in_local(int offset)
-{
-	int sal_call_status = 0, input;
-	int ret = 0;
-
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		ret = readb((unsigned long)master_node_bedrock_address +
-				(offset<< 3));
-		return(ret);
-	}		
-	if ( offset == REG_LSR ) {
-		ret = (LSR_XHRE | LSR_XSRE);	/* can send anytime */
-		sal_call_status = ia64_sn_console_check(&input);
-		if ( !sal_call_status && input ) {
-			/* input pending */
-			ret |= LSR_RCA;
-		}
-	}
-	return(ret);
-}
-
-/*
- * Console input exported interface. Return a character (if one is available)
- */
-
-int
-l1_serial_in_polled(void)
-{
-	static int l1_serial_in_local(void);
-
-	return(l1_serial_in_local());
-}
-
-int
-l1_serial_in(void)
-{
-	static int l1_serial_in_local(void);
-
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));
-	}	
-	return(l1_serial_in_local());
-}
-
-static int
-l1_serial_in_local(void)
-{
-	int ch;
-
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));
-	}		
-
-	if ( !(ia64_sn_console_getc(&ch)) )
-		return(ch);
-	else
-		return(0);
-}
-
-/* Console output exported interface. Write message to the console.  */
-
-int
-l1_serial_out( char *str, int len )
-{
-	int counter = len;
-
-#if defined(CONFIG_IA64_EARLY_PRINTK)
-	/* Need to setup SAL calls so the PROM calls will work */
-	{
-		static int inited;
-		void early_sn_setup(void);
-		if(!inited) {
-			inited=1;
-			early_sn_setup();
-		}
-	}
-#endif
-
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		void early_sn_setup(void);
-		if (!master_node_bedrock_address)
-			early_sn_setup();
-		if ( master_node_bedrock_address != (u64)0 ) {
-#ifdef FLAG_DIRECT_CONSOLE_WRITES
-			/* This is an easy way to pre-pend the output to know whether the output
-			 * was done via sal or directly */
-			writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-			writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-			writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-			writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-#endif	/* FLAG_DIRECT_CONSOLE_WRITES */
-			while ( counter > 0 ) {
-				writeb(*str, (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				counter--;
-				str++;
-			}
-		}
-		return(len);
-	}
-
-	/* Attempt to write things out thru the sal */
-	if ( ia64_sn_console_putb(str, len) )
-		return(0);
-	return((counter <= 0) ? 0 : (len - counter));
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/l1_command.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/l1_command.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/l1_command.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/l1_command.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */ 
 
 #include <linux/types.h>
@@ -16,7 +16,6 @@
 #include <asm/sn/hcl.h>
 #include <asm/sn/hcl_util.h>
 #include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/router.h>
 #include <asm/sn/module.h>
 #include <asm/sn/ksys/l1.h>
@@ -26,37 +25,6 @@
 #include <asm/sn/sn_sal.h>
 #include <linux/ctype.h>
 
-#define ELSC_TIMEOUT	1000000		/* ELSC response timeout (usec) */
-#define LOCK_TIMEOUT	5000000		/* Hub lock timeout (usec) */
-
-#define hub_cpu_get()	0
-
-#define LBYTE(caddr)	(*(char *) caddr)
-
-extern char *bcopy(const char * src, char * dest, int count);
-
-#define LDEBUG		0
-
-/*
- * ELSC data is in NVRAM page 7 at the following offsets.
- */
-
-#define NVRAM_MAGIC_AD	0x700		/* magic number used for init */
-#define NVRAM_PASS_WD	0x701		/* password (4 bytes in length) */
-#define NVRAM_DBG1	0x705		/* virtual XOR debug switches */
-#define NVRAM_DBG2	0x706		/* physical XOR debug switches */
-#define NVRAM_CFG	0x707		/* ELSC Configuration info */
-#define NVRAM_MODULE	0x708		/* system module number */
-#define NVRAM_BIST_FLG	0x709		/* BIST flags (2 bits per nodeboard) */
-#define NVRAM_PARTITION 0x70a		/* module's partition id */
-#define	NVRAM_DOMAIN	0x70b		/* module's domain id */
-#define	NVRAM_CLUSTER	0x70c		/* module's cluster id */
-#define	NVRAM_CELL	0x70d		/* module's cellid */
-
-#define NVRAM_MAGIC_NO	0x37		/* value of magic number */
-#define NVRAM_SIZE	16		/* 16 bytes in nvram */
-
-
 /* elsc_display_line writes up to 12 characters to either the top or bottom
  * line of the L1 display.  line points to a buffer containing the message
  * to be displayed.  The zero-based line number is specified by lnum (so
@@ -69,6 +37,7 @@
     return 0;
 }
 
+
 /*
  * iobrick routines
  */
@@ -88,15 +57,25 @@
 	if ( ia64_sn_sysctl_iobrick_module_get(nasid, &result) )
 		return( ELSC_ERROR_CMD_SEND );
 
-	*rack = (result & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-	*bay = (result & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-	*brick_type = (result & L1_ADDR_TYPE_MASK) >> L1_ADDR_TYPE_SHFT;
+	*rack = (result & MODULE_RACK_MASK) >> MODULE_RACK_SHFT;
+	*bay = (result & MODULE_BPOS_MASK) >> MODULE_BPOS_SHFT;
+	*brick_type = (result & MODULE_BTYPE_MASK) >> MODULE_BTYPE_SHFT;
 	*brick_type = toupper(*brick_type);
 
 	return 0;
 }
 
 
+int iomoduleid_get(nasid_t nasid)
+{
+	int result = 0;
+
+	if ( ia64_sn_sysctl_iobrick_module_get(nasid, &result) )
+		return( ELSC_ERROR_CMD_SEND );
+
+	return result;
+}
+
 int iobrick_module_get(nasid_t nasid)
 {
     uint rnum, rack, bay, brick_type, t;
@@ -130,11 +109,15 @@
     RACK_ADD_NUM(rack, t);
 
     switch( brick_type ) {
-      case 'I': 
+      case L1_BRICKTYPE_IX: 
+	brick_type = MODULE_IXBRICK; break;
+      case L1_BRICKTYPE_PX: 
+	brick_type = MODULE_PXBRICK; break;
+      case L1_BRICKTYPE_I: 
 	brick_type = MODULE_IBRICK; break;
-      case 'P':
+      case L1_BRICKTYPE_P:
 	brick_type = MODULE_PBRICK; break;
-      case 'X':
+      case L1_BRICKTYPE_X:
 	brick_type = MODULE_XBRICK; break;
     }
 
@@ -167,8 +150,9 @@
 
     /* convert to a module.h brick type */
     for( t = 0; t < MAX_BRICK_TYPES; t++ ) {
-        if( brick_types[t] == type )
+        if( brick_types[t] == type ) {
             return t;
+	}
     }
 
     return -1;    /* unknown brick */
@@ -178,18 +162,42 @@
 {
     int io_moduleid;
 
-#ifdef PIC_LATER
-    uint rack, bay;
+    io_moduleid = iobrick_module_get(nasid);
+    return io_moduleid;
+}
+
+/*
+ * given a L1 bricktype, return a bricktype string.  This string is the
+ * string that will be used in the hwpath for I/O bricks
+ */
+char *
+iobrick_L1bricktype_to_name(int type)
+{
+    switch (type)
+    {
+    default:
+        return("Unknown");
 
-    if (PEBRICK_NODE(nasid)) {
-        if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) {
-            printf("Could not read rack and bay location "
-                   "of PEBrick at nasid %d\n", nasid);
-        }
+    case L1_BRICKTYPE_X:
+        return("Xbrick");
 
-        io_moduleid = peer_iobrick_module_get(sc, rack, bay);
+    case L1_BRICKTYPE_I:
+        return("Ibrick");
+
+    case L1_BRICKTYPE_P:
+        return("Pbrick");
+
+    case L1_BRICKTYPE_PX:
+        return("PXbrick");
+
+    case L1_BRICKTYPE_IX:
+        return("IXbrick");
+
+    case L1_BRICKTYPE_C:
+        return("Cbrick");
+
+    case L1_BRICKTYPE_R:
+        return("Rbrick");
     }
-#endif	/* PIC_LATER */
-    io_moduleid = iobrick_module_get(nasid);
-    return io_moduleid;
 }
+
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/ml_SN_init.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/ml_SN_init.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/ml_SN_init.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/ml_SN_init.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -19,25 +19,12 @@
 #include <asm/sn/sn_private.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/sn_cpuid.h>
-#include <asm/sn/snconfig.h>
 
-extern int numcpus;
-extern char arg_maxnodes[];
 extern cpuid_t master_procid;
-
-extern int hasmetarouter;
-
 int		maxcpus;
-cpumask_t	boot_cpumask;
-hubreg_t	region_mask = 0;
-
 
 extern xwidgetnum_t hub_widget_id(nasid_t);
 
-extern int valid_icache_reasons;	/* Reasons to flush the icache */
-extern int valid_dcache_reasons;	/* Reasons to flush the dcache */
-extern u_char miniroot;
-extern volatile int	need_utlbmiss_patch;
 extern void iograph_early_init(void);
 
 nasid_t master_nasid = INVALID_NASID;		/* This is the partition master nasid */
@@ -123,16 +110,6 @@
 	mutex_init_locked(&npda->xbow_sema); /* init it locked? */
 }
 
-/* XXX - Move the interrupt stuff to intr.c ? */
-/*
- * Set up the platform-dependent fields in the processor pda.
- * Must be done _after_ init_platform_nodepda().
- * If we need a lock here, something else is wrong!
- */
-void init_platform_pda(cpuid_t cpu)
-{
-}
-
 void
 update_node_information(cnodeid_t cnodeid)
 {
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/ml_SN_intr.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/ml_SN_intr.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/ml_SN_intr.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/ml_SN_intr.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 /*
@@ -40,30 +40,13 @@
 #include <asm/sal.h>
 #include <asm/sn/sn_sal.h>
 
-extern irqpda_t	*irqpdaindr[];
-extern cnodeid_t master_node_get(devfs_handle_t vhdl);
+extern irqpda_t	*irqpdaindr;
+extern cnodeid_t master_node_get(vertex_hdl_t vhdl);
 extern nasid_t master_nasid;
 
 //  Initialize some shub registers for interrupts, both IO and error.
 //  
 
-#ifdef BRINGUP2
-static long vec1_opt, ii0_opt;
-static int __init set_vec1_opt(char *str)
-{
-        vec1_opt = 1;
-        return 1;
-}
-
-static int __init set_ii0_opt(char *str)
-{
-        ii0_opt = 1;
-        return 1;
-}
-
-__setup("vec1", set_vec1_opt);
-__setup("ii0", set_ii0_opt);
-#endif
 
 
 void
@@ -78,6 +61,8 @@
 	nodepda_t		*lnodepda;
 	sh_ii_int0_enable_u_t	ii_int_enable;
 	sh_int_node_id_config_u_t	node_id_config;
+	sh_local_int5_config_u_t	local5_config;
+	sh_local_int5_enable_u_t	local5_enable;
 	extern void sn_init_cpei_timer(void);
 	static int timer_added = 0;
 
@@ -113,6 +98,19 @@
 	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_ERROR_MASK), 0);
 	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_CRBP_ERROR_MASK), 0);
 
+	// Config and enable UART interrupt, all nodes.
+
+	local5_config.sh_local_int5_config_regval = 0;
+	local5_config.sh_local_int5_config_s.idx = SGI_UART_VECTOR;
+	local5_config.sh_local_int5_config_s.pid = cpu0;
+	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_CONFIG),
+		local5_config.sh_local_int5_config_regval);
+
+	local5_enable.sh_local_int5_enable_regval = 0;
+	local5_enable.sh_local_int5_enable_s.uart_int = 1;
+	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_ENABLE),
+		local5_enable.sh_local_int5_enable_regval);
+
 
 	// The II_INT_CONFIG register for cpu 0.
 	ii_int_config.sh_ii_int0_config_regval = 0;
@@ -139,13 +137,6 @@
 	// Enable interrupts for II_INT0 and 1.
 	ii_int_enable.sh_ii_int0_enable_regval = 0;
 	ii_int_enable.sh_ii_int0_enable_s.ii_enable = 1;
-#if defined(BUS_INT_WAR) && defined(CONFIG_SHUB_1_0_SPECIFIC)
-	/* Dont enable any ints from II. We will poll for interrupts. */
-	ii_int_enable.sh_ii_int0_enable_s.ii_enable = 0;
-
-	/* Enable IPIs. We use them ONLY for send INITs to hung cpus */
-	*(volatile long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT_ENABLE) = 1;
-#endif
 
 	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_ENABLE),
 		ii_int_enable.sh_ii_int0_enable_regval);
@@ -167,24 +158,44 @@
 			int reserve)
 {
 	int i;
-	irqpda_t	*irqs = irqpdaindr[cpu];
-	static int	nextvec=IA64_SN2_FIRST_DEVICE_VECTOR;
+	irqpda_t	*irqs = irqpdaindr;
+	int		min_shared;
 
 	if (reserve) {
 		if (bit < 0) {
-			for (i = nextvec; i <= IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+			for (i = IA64_SN2_FIRST_DEVICE_VECTOR; i <= IA64_SN2_LAST_DEVICE_VECTOR; i++) {
 				if (irqs->irq_flags[i] == 0) {
 					bit = i;
-#ifdef BRINGUP2
-					if (vec1_opt)
-						nextvec = i+1;
-#endif
 					break;
 				}
 			}
 		}
-		if (bit < 0) {
-			return -1;
+		if (bit < 0) {  /* ran out of irqs.  Have to share.  This will be rare. */
+			min_shared = 256;
+			for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+				/* Share with the same device class */
+				if (irqpdaindr->current->vendor == irqpdaindr->device_dev[i]->vendor &&
+					irqpdaindr->current->device == irqpdaindr->device_dev[i]->device &&
+					irqpdaindr->share_count[i] < min_shared) {
+						min_shared = irqpdaindr->share_count[i];
+						bit = i;
+				}
+			}
+			min_shared = 256;
+			if (bit < 0) {  /* didn't find a matching device, just pick one. This will be */
+					/* exceptionally rare. */
+				for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+					if (irqpdaindr->share_count[i] < min_shared) {
+						min_shared = irqpdaindr->share_count[i];
+						bit = i;
+					}
+				}
+			}
+			irqpdaindr->share_count[bit]++;
+		}
+		if (irqs->irq_flags[bit] & SN2_IRQ_SHARED) {
+			irqs->irq_flags[bit] |= SN2_IRQ_RESERVED;
+			return bit;
 		}
 		if (irqs->irq_flags[bit] & SN2_IRQ_RESERVED) {
 			return -1;
@@ -208,7 +219,7 @@
 intr_reserve_level(cpuid_t cpu,
 		int bit,
 		int resflags,
-		devfs_handle_t owner_dev,
+		vertex_hdl_t owner_dev,
 		char *name)
 {
 	return(do_intr_reserve_level(cpu, bit, 1));
@@ -228,9 +239,13 @@
 			int bit,
 			int connect)
 {
-	irqpda_t	*irqs = irqpdaindr[cpu];
+	irqpda_t	*irqs = irqpdaindr;
 
 	if (connect) {
+		if (irqs->irq_flags[bit] & SN2_IRQ_SHARED) {
+			irqs->irq_flags[bit] |= SN2_IRQ_CONNECTED;
+			return bit;
+		}
 		if (irqs->irq_flags[bit] & SN2_IRQ_CONNECTED) {
 			return -1;
 		} else {
@@ -273,28 +288,29 @@
 	int		slice, min_count = 1000;
 	irqpda_t	*irqs;
 
-	for (slice = 0; slice < CPUS_PER_NODE; slice++) {
+	for (slice = CPUS_PER_NODE - 1; slice >= 0; slice--) {
 		int intrs;
 
 		cpu = cnode_slice_to_cpuid(cnode, slice);
-		if (cpu == CPU_NONE) {
+		if (cpu == smp_num_cpus) {
 			continue;
 		}
 
-		if (!cpu_enabled(cpu)) {
+		if (!cpu_online(cpu)) {
 			continue;
 		}
 
-		irqs = irqpdaindr[cpu];
+		irqs = irqpdaindr;
 		intrs = irqs->num_irq_used;
 
 		if (min_count > intrs) {
 			min_count = intrs;
 			best_cpu = cpu;
-#ifdef BRINGUP2
-			if (ii0_opt)
+			if ( enable_shub_wars_1_1() ) {
+				/* Rather than finding the best cpu, always return the first cpu*/
+				/* This forces all interrupts to the same cpu */
 				break;
-#endif
+			}
 		}
 	}
 	return best_cpu;
@@ -314,7 +330,7 @@
 			cnodeid_t cnode,
 			int req_bit,
 			int resflags,
-			devfs_handle_t owner_dev,
+			vertex_hdl_t owner_dev,
 			char *name,
 			int *resp_bit)
 {
@@ -336,18 +352,18 @@
 // Find the node to assign for this interrupt.
 
 cpuid_t
-intr_heuristic(devfs_handle_t dev,
+intr_heuristic(vertex_hdl_t dev,
 		device_desc_t dev_desc,
 		int	req_bit,
 		int resflags,
-		devfs_handle_t owner_dev,
+		vertex_hdl_t owner_dev,
 		char *name,
 		int *resp_bit)
 {
 	cpuid_t		cpuid;
 	cpuid_t		candidate = CPU_NONE;
 	cnodeid_t	candidate_node;
-	devfs_handle_t	pconn_vhdl;
+	vertex_hdl_t	pconn_vhdl;
 	pcibr_soft_t	pcibr_soft;
 	int 		bit;
 
@@ -398,8 +414,8 @@
 	if (candidate  != CPU_NONE) {
 		printk("Cannot target interrupt to target node (%ld).\n",candidate);
 		return CPU_NONE; } else {
-		printk("Cannot target interrupt to closest node (%d) 0x%p\n",
-			master_node_get(dev), (void *)owner_dev);
+		/* printk("Cannot target interrupt to closest node (%d) 0x%p\n",
+			master_node_get(dev), (void *)owner_dev); */
 	}
 
 	// We couldn't put it on the closest node.  Try to find another one.
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/ml_iograph.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/ml_iograph.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/ml_iograph.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/ml_iograph.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -22,7 +22,6 @@
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/klconfig.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/sn_private.h>
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/xtalk/xtalk.h>
@@ -43,8 +42,6 @@
 /* At most 2 hubs can be connected to an xswitch */
 #define NUM_XSWITCH_VOLUNTEER 2
 
-extern unsigned char Is_pic_on_this_nasid[512];
-
 /*
  * Track which hubs have volunteered to manage devices hanging off of
  * a Crosstalk Switch (e.g. xbow).  This structure is allocated,
@@ -54,11 +51,11 @@
 typedef struct xswitch_vol_s {
 	mutex_t xswitch_volunteer_mutex;
 	int		xswitch_volunteer_count;
-	devfs_handle_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
+	vertex_hdl_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
 } *xswitch_vol_t;
 
 void
-xswitch_vertex_init(devfs_handle_t xswitch)
+xswitch_vertex_init(vertex_hdl_t xswitch)
 {
 	xswitch_vol_t xvolinfo;
 	int rc;
@@ -78,7 +75,7 @@
  * xswitch volunteer structure hanging around.  Destroy it.
  */
 static void
-xswitch_volunteer_delete(devfs_handle_t xswitch)
+xswitch_volunteer_delete(vertex_hdl_t xswitch)
 {
 	xswitch_vol_t xvolinfo;
 	int rc;
@@ -94,10 +91,10 @@
  */
 /* ARGSUSED */
 static void
-volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master)
+volunteer_for_widgets(vertex_hdl_t xswitch, vertex_hdl_t master)
 {
 	xswitch_vol_t xvolinfo = NULL;
-	devfs_handle_t hubv;
+	vertex_hdl_t hubv;
 	hubinfo_t hubinfo;
 
 	(void)hwgraph_info_get_LBL(xswitch, 
@@ -140,7 +137,7 @@
  */
 /* ARGSUSED */
 static void
-assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv)
+assign_widgets_to_volunteers(vertex_hdl_t xswitch, vertex_hdl_t hubv)
 {
 	xswitch_info_t xswitch_info;
 	xswitch_vol_t xvolinfo = NULL;
@@ -223,18 +220,6 @@
 
                        	bt = iobrick_type_get_nasid(nasid);
                         if (bt >= 0) {
-				/*
-				 * PXBRICK has two busses per widget so this
-				 * algorithm wouldn't work (all busses would
-				 * be assigned to one volunteer). Change the
-				 * bricktype to PBRICK whose mapping is setup
-				 * suchthat 2 of the PICs will be assigned to
-				 * one volunteer and the other one will be
-				 * assigned to the other volunteer.
-				 */
-				if (bt == MODULE_PXBRICK) 
-					bt = MODULE_PBRICK;
-
 			        i = io_brick_map_widget(bt, widgetnum) & 1;
                         }
                 }
@@ -281,8 +266,6 @@
 			DBG("iograph_early_init: Found board 0x%p\n", board);
 		}
 	}
-
-	hubio_init();
 }
 
 /*
@@ -307,7 +290,7 @@
  * hwid for our use.
  */
 static void
-early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid)
+early_probe_for_widget(vertex_hdl_t hubv, xwidget_hwid_t hwid)
 {
 	hubreg_t llp_csr_reg;
 	nasid_t nasid;
@@ -351,7 +334,7 @@
  * added as inventory information.
  */
 static void
-xwidget_inventory_add(devfs_handle_t 		widgetv,
+xwidget_inventory_add(vertex_hdl_t 		widgetv,
 		      lboard_t 			*board,
 		      struct xwidget_hwid_s 	hwid)
 {
@@ -374,14 +357,13 @@
  */
 
 void
-io_xswitch_widget_init(devfs_handle_t  	xswitchv,
-		       devfs_handle_t	hubv,
-		       xwidgetnum_t	widgetnum,
-		       async_attach_t	aa)
+io_xswitch_widget_init(vertex_hdl_t  	xswitchv,
+		       vertex_hdl_t	hubv,
+		       xwidgetnum_t	widgetnum)
 {
 	xswitch_info_t		xswitch_info;
 	xwidgetnum_t		hub_widgetid;
-	devfs_handle_t		widgetv;
+	vertex_hdl_t		widgetv;
 	cnodeid_t		cnode;
 	widgetreg_t		widget_id;
 	nasid_t			nasid, peer_nasid;
@@ -427,6 +409,7 @@
 		char			name[4];
 		lboard_t dummy;
 
+
 		/*
 		 * If the current hub is not supposed to be the master 
 		 * for this widgetnum, then skip this widget.
@@ -470,12 +453,15 @@
 
 		memset(buffer, 0, 16);
 		format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF);
-		sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%cbrick" "/%s/%d",
+
+		sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%s" "/%s/%d",
 			buffer,
 			geo_slab(board->brd_geoid),
-			(board->brd_type == KLTYPE_IBRICK) ? 'I' :
-			(board->brd_type == KLTYPE_PBRICK) ? 'P' :
-			(board->brd_type == KLTYPE_XBRICK) ? 'X' : '?',
+			(board->brd_type == KLTYPE_IBRICK) ? EDGE_LBL_IBRICK :
+			(board->brd_type == KLTYPE_PBRICK) ? EDGE_LBL_PBRICK :
+			(board->brd_type == KLTYPE_PXBRICK) ? EDGE_LBL_PXBRICK :
+			(board->brd_type == KLTYPE_IXBRICK) ? EDGE_LBL_IXBRICK :
+			(board->brd_type == KLTYPE_XBRICK) ? EDGE_LBL_XBRICK : "?brick",
 			EDGE_LBL_XTALK, widgetnum);
 		
 		DBG("io_xswitch_widget_init: path= %s\n", pathname);
@@ -514,36 +500,46 @@
 		xwidget_inventory_add(widgetv,board,hwid);
 
 		(void)xwidget_register(&hwid, widgetv, widgetnum,
-				       hubv, hub_widgetid,
-				       aa);
+				       hubv, hub_widgetid);
 
 		ia64_sn_sysctl_iobrick_module_get(nasid, &io_module);
 
 		if (io_module >= 0) {
 			char			buffer[16];
-			devfs_handle_t		to, from;
+			vertex_hdl_t		to, from;
+			char           		*brick_name;
+			extern char *iobrick_L1bricktype_to_name(int type);
+
 
 			memset(buffer, 0, 16);
 			format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF);
 
-			bt = toupper(MODULE_GET_BTCHAR(io_module));
+			if ( islower(MODULE_GET_BTCHAR(io_module)) ) {
+				bt = toupper(MODULE_GET_BTCHAR(io_module));
+			}
+			else {
+				bt = MODULE_GET_BTCHAR(io_module);
+			}
+
+			brick_name = iobrick_L1bricktype_to_name(bt);
+
 			/* Add a helper vertex so xbow monitoring
 			* can identify the brick type. It's simply
 			* an edge from the widget 0 vertex to the
 			*  brick vertex.
 			*/
 
-			sprintf(pathname, "/dev/hw/" EDGE_LBL_MODULE "/%s/"
+			sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/"
 				EDGE_LBL_SLAB "/%d/"
 				EDGE_LBL_NODE "/" EDGE_LBL_XTALK "/"
 				"0",
 				buffer, geo_slab(board->brd_geoid));
 			from = hwgraph_path_to_vertex(pathname);
 			ASSERT_ALWAYS(from);
-			sprintf(pathname, "/dev/hw/" EDGE_LBL_MODULE "/%s/"
+			sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/"
 				EDGE_LBL_SLAB "/%d/"
-				"%cbrick",
-				buffer, geo_slab(board->brd_geoid), bt);
+				"%s",
+				buffer, geo_slab(board->brd_geoid), brick_name);
 
 			to = hwgraph_path_to_vertex(pathname);
 			ASSERT_ALWAYS(to);
@@ -566,12 +562,9 @@
 
 
 static void
-io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode)
+io_init_xswitch_widgets(vertex_hdl_t xswitchv, cnodeid_t cnode)
 {
 	xwidgetnum_t		widgetnum;
-	async_attach_t          aa;
-
-	aa = async_attach_new();
 	
 	DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode);
 
@@ -579,13 +572,8 @@
 	     widgetnum++) {
 		io_xswitch_widget_init(xswitchv,
 				       cnodeid_to_vertex(cnode),
-				       widgetnum, aa);
+				       widgetnum);
 	}
-	/* 
-	 * Wait for parallel attach threads, if any, to complete.
-	 */
-	async_attach_waitall(aa);
-	async_attach_free(aa);
 }
 
 /*
@@ -595,11 +583,11 @@
  * graph and risking hangs.
  */
 static void
-io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid)
+io_link_xswitch_widgets(vertex_hdl_t xswitchv, cnodeid_t cnodeid)
 {
 	xwidgetnum_t		widgetnum;
 	char 			pathname[128];
-	devfs_handle_t		vhdl;
+	vertex_hdl_t		vhdl;
 	nasid_t			nasid, peer_nasid;
 	lboard_t		*board;
 
@@ -638,21 +626,12 @@
 			return;
 		}
 
-		if ( Is_pic_on_this_nasid[nasid] ) {
-			/* Check both buses */
-			sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
-			if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
-				board->brd_graph_link = vhdl;
-			else {
-				sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
-				if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
-					board->brd_graph_link = vhdl;
-				else
-					board->brd_graph_link = GRAPH_VERTEX_NONE;
-			}
-		}
+		/* Check both buses */
+		sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
+		if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
+			board->brd_graph_link = vhdl;
 		else {
-			sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
+			sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
 			if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
 				board->brd_graph_link = vhdl;
 			else
@@ -668,16 +647,15 @@
 io_init_node(cnodeid_t cnodeid)
 {
 	/*REFERENCED*/
-	devfs_handle_t hubv, switchv, widgetv;
+	vertex_hdl_t hubv, switchv, widgetv;
 	struct xwidget_hwid_s hwid;
 	hubinfo_t hubinfo;
 	int is_xswitch;
 	nodepda_t	*npdap;
 	struct semaphore *peer_sema = 0;
 	uint32_t	widget_partnum;
-	nodepda_router_info_t *npda_rip;
 	cpu_cookie_t	c = 0;
-	extern int hubdev_docallouts(devfs_handle_t);
+	extern int hubdev_docallouts(vertex_hdl_t);
 
 	npdap = NODEPDA(cnodeid);
 
@@ -696,21 +674,6 @@
 	hubdev_docallouts(hubv);
 
 	/*
-	 * Set up the dependent routers if we have any.
-	 */
-	npda_rip = npdap->npda_rip_first;
-
-	while(npda_rip) {
-		/* If the router info has not been initialized
-		 * then we need to do the router initialization
-		 */
-		if (!npda_rip->router_infop) {
-			router_init(cnodeid,0,npda_rip);
-		}
-		npda_rip = npda_rip->router_next;
-	}
-
-	/*
 	 * Read mfg info on this hub
 	 */
 
@@ -833,7 +796,7 @@
 		 */
 		hubinfo_get(hubv, &hubinfo);
 
-		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL);
+		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid);
 
 		if (!is_xswitch) {
 			/* io_init_done takes cpu cookie as 2nd argument 
@@ -915,231 +878,9 @@
  * XXX Irix legacy..controller numbering should be part of devfsd's job
  */
 int num_base_io_scsi_ctlr = 2; /* used by syssgi */
-devfs_handle_t		base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];
-static devfs_handle_t	baseio_enet_vhdl,baseio_console_vhdl;
-
-/*
- * Put the logical controller number information in the 
- * scsi controller vertices for each scsi controller that
- * is in a "fixed position".
- */
-static void
-scsi_ctlr_nums_add(devfs_handle_t pci_vhdl)
-{
-	{
-		int i;
-
-		num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR;
-
-		/* Initialize base_io_scsi_ctlr_vhdl array */
-		for (i=0; i<num_base_io_scsi_ctlr; i++)
-			base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE;
-	}
-	{
-	/*
-	 * May want to consider changing the SN0 code, above, to work more like
-	 * the way this works.
-	 */
-	devfs_handle_t base_ibrick_xbridge_vhdl;
-	devfs_handle_t base_ibrick_xtalk_widget_vhdl;
-	devfs_handle_t scsi_ctlr_vhdl;
-	int i;
-	graph_error_t rv;
-
-	/*
-	 * This is a table of "well-known" SCSI controllers and their well-known
-	 * controller numbers.  The names in the table start from the base IBrick's
-	 * Xbridge vertex, so the first component is the xtalk widget number.
-	 */
-	static struct {
-		char	*base_ibrick_scsi_path;
-		int	controller_number;
-	} hardwired_scsi_controllers[] = {
-		{"15/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 0},
-		{"15/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 1},
-		{"15/" EDGE_LBL_PCI "/3/" EDGE_LBL_SCSI_CTLR "/0", 2},
-		{"14/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 3},
-		{"14/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 4},
-		{"15/" EDGE_LBL_PCI "/6/ohci/0/" EDGE_LBL_SCSI_CTLR "/0", 5},
-		{NULL, -1} /* must be last */
-	};
-
-	base_ibrick_xtalk_widget_vhdl = hwgraph_connectpt_get(pci_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xtalk_widget_vhdl != GRAPH_VERTEX_NONE);
-
-	base_ibrick_xbridge_vhdl = hwgraph_connectpt_get(base_ibrick_xtalk_widget_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xbridge_vhdl != GRAPH_VERTEX_NONE);
-	hwgraph_vertex_unref(base_ibrick_xtalk_widget_vhdl);
-
-	/*
-	 * Iterate through the list of well-known SCSI controllers.
-	 * For each controller found, set it's controller number according
-	 * to the table.
-	 */
-	for (i=0; hardwired_scsi_controllers[i].base_ibrick_scsi_path != NULL; i++) {
-		rv = hwgraph_path_lookup(base_ibrick_xbridge_vhdl,
-			hardwired_scsi_controllers[i].base_ibrick_scsi_path, &scsi_ctlr_vhdl, NULL);
-
-		if (rv != GRAPH_SUCCESS) /* No SCSI at this path */
-			continue;
-
-		ASSERT(hardwired_scsi_controllers[i].controller_number < NUM_BASE_IO_SCSI_CTLR);
-		base_io_scsi_ctlr_vhdl[hardwired_scsi_controllers[i].controller_number] = scsi_ctlr_vhdl;
-		device_controller_num_set(scsi_ctlr_vhdl, hardwired_scsi_controllers[i].controller_number);
-		hwgraph_vertex_unref(scsi_ctlr_vhdl); /* (even though we're actually keeping a reference) */
-	}
-
-	hwgraph_vertex_unref(base_ibrick_xbridge_vhdl);
-	}
-}
-
+vertex_hdl_t		base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];
 
 #include <asm/sn/ioerror_handling.h>
-devfs_handle_t		sys_critical_graph_root = GRAPH_VERTEX_NONE;
-
-/* Define the system critical vertices and connect them through
- * a canonical parent-child relationships for easy traversal
- * during io error handling.
- */
-static void
-sys_critical_graph_init(void)
-{
-	devfs_handle_t		bridge_vhdl,master_node_vhdl;
-	devfs_handle_t  		xbow_vhdl = GRAPH_VERTEX_NONE;
-	extern devfs_handle_t	hwgraph_root;
-	devfs_handle_t		pci_slot_conn;
-	int			slot;
-	devfs_handle_t		baseio_console_conn;
-
-	DBG("sys_critical_graph_init: FIXME.\n");
-	baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl);
-
-	if (baseio_console_conn == NULL) {
-		return;
-	}
-
-	/* Get the vertex handle for the baseio bridge */
-	bridge_vhdl = device_master_get(baseio_console_conn);
-
-	/* Get the master node of the baseio card */
-	master_node_vhdl = cnodeid_to_vertex(
-				master_node_get(baseio_console_vhdl));
-	
-	/* Add the "root->node" part of the system critical graph */
-
-	sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl);
-
-	/* Check if we have a crossbow */
-	if (hwgraph_traverse(master_node_vhdl,
-			     EDGE_LBL_XTALK"/0",
-			     &xbow_vhdl) == GRAPH_SUCCESS) {
-		/* We have a crossbow.Add "node->xbow" part of the system 
-		 * critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl);
-		
-		/* Add "xbow->baseio bridge" of the system critical graph */
-		sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl);
-
-		hwgraph_vertex_unref(xbow_vhdl);
-	} else 
-		/* We donot have a crossbow. Add "node->baseio_bridge"
-		 * part of the system critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl);
-
-	/* Add all the populated PCI slot vertices to the system critical
-	 * graph with the bridge vertex as the parent.
-	 */
-	for (slot = 0 ; slot < 8; slot++) {
-		char	slot_edge[10];
-
-		sprintf(slot_edge,"%d",slot);
-		if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn)
-		    != GRAPH_SUCCESS)
-			continue;
-		sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	hwgraph_vertex_unref(bridge_vhdl);
-
-	/* Add the "ioc3 pci connection point  -> console ioc3" part 
-	 * of the system critical graph
-	 */
-
-	if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_console_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "ethernet pci connection point  -> base ethernet" part of 
-	 * the system  critical graph
-	 */
-	if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_enet_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "scsi controller pci connection point  -> base scsi 
-	 * controller" part of the system critical graph
-	 */
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[0]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[1]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	hwgraph_vertex_unref(baseio_console_conn);
-
-}
-
-static void
-baseio_ctlr_num_set(void)
-{
-	char 			name[MAXDEVNAME];
-	devfs_handle_t		console_vhdl, pci_vhdl, enet_vhdl;
-	devfs_handle_t		ioc3_console_vhdl_get(void);
-
-
-	DBG("baseio_ctlr_num_set; FIXME\n");
-	console_vhdl = ioc3_console_vhdl_get();
-	if (console_vhdl == GRAPH_VERTEX_NONE)
-		return;
-	/* Useful for setting up the system critical graph */
-	baseio_console_vhdl = console_vhdl;
-
-	vertex_to_name(console_vhdl,name,MAXDEVNAME);
-
-	strcat(name,__DEVSTR1);
-	pci_vhdl =  hwgraph_path_to_vertex(name);
-	scsi_ctlr_nums_add(pci_vhdl);
-	/* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(pci_vhdl);
-
-	vertex_to_name(console_vhdl, name, MAXDEVNAME);
-	strcat(name, __DEVSTR4);
-	enet_vhdl = hwgraph_path_to_vertex(name);
-
-	/* Useful for setting up the system critical graph */
-	baseio_enet_vhdl = enet_vhdl;
-
-	device_controller_num_set(enet_vhdl, 0);
-	/* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(enet_vhdl);
-}
 /* #endif */
 
 /*
@@ -1168,13 +909,6 @@
 		 */
 		update_node_information(cnodeid);
 
-	baseio_ctlr_num_set();
-	/* Setup the system critical graph (which is a subgraph of the
-	 * main hwgraph). This information is useful during io error
-	 * handling.
-	 */
-	sys_critical_graph_init();
-
 #if HWG_PRINT
 	hwgraph_print();
 #endif
@@ -1279,10 +1013,10 @@
         2,                                      /* 0x8            */
         1,                                      /* 0x9            */
         0, 0,                                   /* 0xa - 0xb      */
-        5,                                      /* 0xc            */
+        4,                                      /* 0xc            */
         6,                                      /* 0xd            */
-        4,                                      /* 0xe            */
-        3                                       /* 0xf            */
+        3,                                      /* 0xe            */
+        5                                       /* 0xf            */
     }
  },
 
@@ -1300,6 +1034,20 @@
     }
  },
 
+/* IXbrick widget number to PCI bus number map */
+ {      MODULE_IXBRICK,                         /* IXbrick type   */ 
+    /*  PCI Bus #                                  Widget #       */
+    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
+        0,                                      /* 0x8            */
+        0,                                      /* 0x9            */
+        0, 0,                                   /* 0xa - 0xb      */
+        1,                                      /* 0xc            */
+        5,                                      /* 0xd            */
+        0,                                      /* 0xe            */
+        3                                       /* 0xf            */
+    }
+ },
+
 /* Xbrick widget to XIO slot map */
  {      MODULE_XBRICK,                          /* Xbrick type    */ 
     /*  XIO Slot #                                 Widget #       */
@@ -1335,61 +1083,3 @@
         return 0;
 
 }
-
-/*
- * Use the device's vertex to map the device's widget to a meaningful int
- */
-int
-io_path_map_widget(devfs_handle_t vertex)
-{
-        char hw_path_name[MAXDEVNAME];
-        char *wp, *bp, *sp = NULL;
-        int  widget_num;
-	long atoi(char *);
-	int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-
-
-        /* Get the full path name of the vertex */
-        if (GRAPH_SUCCESS != hwgraph_vertex_name_get(vertex, hw_path_name,
-                                                     MAXDEVNAME))
-                return 0;
-
-        /* Find the widget number in the path name */
-        wp = strstr(hw_path_name, "/"EDGE_LBL_XTALK"/");
-        if (wp == NULL)
-                return 0;
-        widget_num = atoi(wp+7);
-        if (widget_num < XBOW_PORT_8 || widget_num > XBOW_PORT_F)
-                return 0;
-
-        /* Find "brick" in the path name */
-        bp = strstr(hw_path_name, "brick");
-        if (bp == NULL)
-                return 0;
-
-        /* Find preceding slash */
-        sp = bp;
-        while (sp > hw_path_name) {
-                sp--;
-                if (*sp == '/')
-                        break;
-        }
-
-        /* Invalid if no preceding slash */
-        if (!sp)
-                return 0;
-
-        /* Bump slash pointer to "brick" prefix */
-        sp++;
-        /*
-         * Verify "brick" prefix length;  valid exaples:
-         * 'I' from "/Ibrick"
-         * 'P' from "/Pbrick"
-         * 'X' from "/Xbrick"
-         */
-         if ((bp - sp) != 1)
-                return 0;
-
-        return (io_brick_map_widget((int)*sp, widget_num));
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/module.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/module.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/module.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/module.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -18,7 +18,6 @@
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/klconfig.h>
-#include <asm/sn/sn1/hubdev.h>
 #include <asm/sn/module.h>
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/xtalk/xswitch.h>
@@ -261,20 +260,5 @@
 	    nserial);
 
     if (nserial == 0)
-	printk(KERN_WARNING  "io_module_init: No serial number found.\n");
-}
-
-int
-get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info)
-{
-    if (cmod < 0 || cmod >= nummodules)
-	return -EINVAL;
-
-    mod_info->mod_num = modules[cmod]->id;
-
-    ia64_sn_sys_serial_get(mod_info->serial_str);
-    
-    mod_info->serial_num = ia64_sn_partition_serial_get();
-
-    return 0;
+	DPRINTF(KERN_WARNING  "io_module_init: No serial number found.\n");
 }
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pci_bus_cvlink.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pci_bus_cvlink.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pci_bus_cvlink.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pci_bus_cvlink.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,811 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <asm/sn/types.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/sn_cpuid.h>
-
-extern int bridge_rev_b_data_check_disable;
-
-devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
-nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
-void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
-unsigned char num_bridges;
-static int done_probing = 0;
-
-static int pci_bus_map_create(devfs_handle_t xtalk);
-devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-extern unsigned char Is_pic_on_this_nasid[512];
-
-extern void sn_init_irq_desc(void);
-
-
-/*
- * For the given device, initialize whether it is a PIC device.
- */
-static void
-set_isPIC(struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-	device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);;
-}
-
-/*
- * pci_bus_cvlink_init() - To be called once during initialization before 
- *	SGI IO Infrastructure init is called.
- */
-void
-pci_bus_cvlink_init(void)
-{
-
-	extern void ioconfig_bus_init(void);
-
-	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET);
-	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
-
-	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
-
-	num_bridges = 0;
-
-	// ioconfig_bus_init();
-}
-
-/*
- * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
- *	pci bus vertex from the SGI IO Infrastructure.
- */
-devfs_handle_t
-pci_bus_to_vertex(unsigned char busnum)
-{
-
-	devfs_handle_t	pci_bus = NULL;
-
-
-	/*
-	 * First get the xwidget vertex.
-	 */
-	pci_bus = busnum_to_pcibr_vhdl[busnum];
-	return(pci_bus);
-}
-
-/*
- * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
- *	and function numbers.
- */
-devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn)
-{
-
-	int slot = 0;
-	int func = 0;
-	char	name[16];
-	devfs_handle_t  pci_bus = NULL;
-	devfs_handle_t	device_vertex = (devfs_handle_t)NULL;
-
-	/*
-	 * Go get the pci bus vertex.
-	 */
-	pci_bus = pci_bus_to_vertex(busnum);
-	if (!pci_bus) {
-		/*
-		 * During probing, the Linux pci code invents non existant
-		 * bus numbers and pci_dev structures and tries to access
-		 * them to determine existance. Don't crib during probing.
-		 */
-		if (done_probing)
-			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
-		return(NULL);
-	}
-
-
-	/*
-	 * Go get the slot&function vertex.
-	 * Should call pciio_slot_func_to_name() when ready.
-	 */
-	slot = PCI_SLOT(devfn);
-	func = PCI_FUNC(devfn);
-
-	/*
-	 * For a NON Multi-function card the name of the device looks like:
-	 * ../pci/1, ../pci/2 ..
-	 */
-	if (func == 0) {
-        	sprintf(name, "%d", slot);
-		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
-			GRAPH_SUCCESS) {
-			if (device_vertex) {
-				return(device_vertex);
-			}
-		}
-	}
-			
-	/*
-	 * This maybe a multifunction card.  It's names look like:
-	 * ../pci/1a, ../pci/1b, etc.
-	 */
-	sprintf(name, "%d%c", slot, 'a'+func);
-	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
-		if (!device_vertex) {
-			return(NULL);
-		}
-	}
-
-	return(device_vertex);
-}
-
-/*
- * For the given device, initialize the addresses for both the Device(x) Flush 
- * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
- * is connected.
- */
-static void
-set_flush_addresses(struct pci_dev *device_dev, 
-	struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    	bridge_t               *bridge = pcibr_soft->bs_base;
-	nasid_t			nasid;
-
-	/*
-	 * Get the nasid from the bridge.
-	 */
-	nasid = NASID_GET(device_sysdata->dma_buf_sync);
-	if (IS_PIC_DEVICE(device_dev)) {
-		device_sysdata->dma_buf_sync = (volatile unsigned int *)
-			&bridge->b_wr_req_buf[pciio_slot].reg;
-		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-			XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(nasid, 0),
-			pcibr_soft->bs_xid);
-	} else {
-		/*
-		 * Accessing Xbridge and Xbow register when SHUB swapoper is on!.
-		 */
-		device_sysdata->dma_buf_sync = (volatile unsigned int *)
-			((uint64_t)&(bridge->b_wr_req_buf[pciio_slot].reg)^4);
-		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-			((uint64_t)(XBOW_PRIO_LINKREGS_PTR(
-			NODE_SWIN_BASE(nasid, 0), pcibr_soft->bs_xid)) ^ 4);
-	}
-
-#ifdef DEBUG
-	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
-		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
-
-printk("set_flush_addresses: dma_buf_sync\n");
-	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
-printk("set_flush_addresses: xbow_buf_sync\n");
-	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
-#endif
-
-}
-
-/*
- * Most drivers currently do not properly tell the arch specific pci dma
- * interfaces whether they can handle A64. Here is where we privately
- * keep track of this.
- */
-static void __init
-set_sn_pci64(struct pci_dev *dev)
-{
-	unsigned short vendor = dev->vendor;
-	unsigned short device = dev->device;
-
-	if (vendor == PCI_VENDOR_ID_QLOGIC) {
-		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
-				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-	if (vendor == PCI_VENDOR_ID_SGI) {
-		if (device == PCI_DEVICE_ID_SGI_IOC3) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-}
-
-/*
- * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
- *	invoked at the end of pcibios_init() to link the Linux pci 
- *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
- *
- *	Other platform specific fixup can also be done here.
- */
-void
-sn_pci_fixup(int arg)
-{
-	struct list_head *ln;
-	struct pci_bus *pci_bus = NULL;
-	struct pci_dev *device_dev = NULL;
-	struct sn_widget_sysdata *widget_sysdata;
-	struct sn_device_sysdata *device_sysdata;
-	pciio_intr_t intr_handle;
-	int cpuid, bit;
-	devfs_handle_t device_vertex;
-	pciio_intr_line_t lines;
-	extern void sn_pci_find_bios(void);
-	extern int numnodes;
-	int cnode;
-	extern void io_sh_swapper(int, int);
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
-			io_sh_swapper((cnodeid_to_nasid(cnode)), 0);
-	}
-
-	if (arg == 0) {
-#ifdef CONFIG_PROC_FS
-		extern void register_sn_partition_id(void);
-		extern void register_sn_serial_numbers(void);
-#endif
-
-		sn_init_irq_desc();
-		sn_pci_find_bios();
-		for (cnode = 0; cnode < numnodes; cnode++) {
-			extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
-			intr_init_vecblk(NODEPDA(cnode), cnode, 0);
-		} 
-
-		/*
-		 * When we return to generic Linux, Swapper is always on ..
-		 */
-		for (cnode = 0; cnode < numnodes; cnode++) {
-			if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
-				io_sh_swapper((cnodeid_to_nasid(cnode)), 1);
-		}
-#ifdef CONFIG_PROC_FS
-		register_sn_partition_id();
-		register_sn_serial_numbers();
-#endif
-		return;
-	}
-
-
-	done_probing = 1;
-
-	/*
-	 * Initialize the pci bus vertex in the pci_bus struct.
-	 */
-	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		pci_bus = pci_bus_b(ln);
-		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
-					GFP_KERNEL);
-		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
-		pci_bus->sysdata = (void *)widget_sysdata;
-	}
-
-	/*
- 	 * set the root start and end so that drivers calling check_region()
-	 * won't see a conflict
-	 */
-	ioport_resource.start  = 0xc000000000000000;
-	ioport_resource.end =    0xcfffffffffffffff;
-
-	/*
-	 * Set the root start and end for Mem Resource.
-	 */
-	iomem_resource.start = 0;
-	iomem_resource.end = 0xffffffffffffffff;
-
-	/*
-	 * Initialize the device vertex in the pci_dev struct.
-	 */
-	pci_for_each_dev(device_dev) {
-		unsigned int irq;
-		int idx;
-		u16 cmd;
-		devfs_handle_t vhdl;
-		unsigned long size;
-		extern int bit_pos_to_irq(int);
-
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
-			extern void pci_fixup_ioc3(struct pci_dev *d);
-			pci_fixup_ioc3(device_dev);
-		}
-
-		/* Set the device vertex */
-
-		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
-					GFP_KERNEL);
-		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
-		device_sysdata->isa64 = 0;
-		/*
-		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
-		 * register addresses.
-		 */
-		(void) set_flush_addresses(device_dev, device_sysdata);
-
-		device_dev->sysdata = (void *) device_sysdata;
-		set_sn_pci64(device_dev);
-		set_isPIC(device_sysdata);
-
-		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
-
-		/*
-		 * Set the resources address correctly.  The assumption here 
-		 * is that the addresses in the resource structure has been
-		 * read from the card and it was set in the card by our
-		 * Infrastructure ..
-		 */
-		vhdl = device_sysdata->vhdl;
-		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
-			size = 0;
-			size = device_dev->resource[idx].end -
-				device_dev->resource[idx].start;
-			if (size) {
-				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
-				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
-			}
-			else
-				continue;
-
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].start + size;
-#ifdef BRINGUP2
-			printk("Device Vendor 0x%x, resource[%d] PIO Address = 0x%lx\n", device_dev->vendor, idx, (long)device_dev->resource[idx].start);
-#endif
-
-			if (device_dev->resource[idx].flags & IORESOURCE_IO)
-				cmd |= PCI_COMMAND_IO;
-
-			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
-				cmd |= PCI_COMMAND_MEMORY;
-		}
-		/*
-		 * Now handle the ROM resource ..
-		 */
-#if 0
-	/*
-	 * Software WAR for a Software BUG.
-	 * This is only temporary.
-	 * See PV 872791
-	 */
-		size = device_dev->resource[PCI_ROM_RESOURCE].end -
-			device_dev->resource[PCI_ROM_RESOURCE].start;
-
-		if (size) {
-			device_dev->resource[PCI_ROM_RESOURCE].start =
-			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
-				size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
-			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
-			device_dev->resource[PCI_ROM_RESOURCE].end =
-			device_dev->resource[PCI_ROM_RESOURCE].start + size;
-		}
-#endif
-
-		/*
-		 * Update the Command Word on the Card.
-		 */
-		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
-					   /* bit gets dropped .. no harm */
-		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
-
-		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-				lines = 1;
-		}
- 
-		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
-		device_vertex = device_sysdata->vhdl;
- 
-		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
-
-		bit = intr_handle->pi_irq;
-		cpuid = intr_handle->pi_cpu;
-		irq = bit;
-		irq = irq + (cpuid << 8);
-		pciio_intr_connect(intr_handle, (intr_func_t)0, (intr_arg_t)0);
-		device_dev->irq = irq;
-#ifdef ajmtestintr
-		{
-			int slot = PCI_SLOT(device_dev->devfn);
-			static int timer_set = 0;
-			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
-			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
-			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
-
-			if (!timer_set) {
-				intr_test_set_timer();
-				timer_set = 1;
-			}
-			intr_test_register_irq(irq, pcibr_soft, slot);
-			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
-		}
-#endif
-
-	}
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
-			io_sh_swapper((cnodeid_to_nasid(cnode)), 1);
-	}
-}
-
-/*
- * linux_bus_cvlink() Creates a link between the Linux PCI Bus number 
- *	to the actual hardware component that it represents:
- *	/dev/hw/linux/busnum/0 -> ../../../hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
- */
-void
-linux_bus_cvlink(void)
-{
-	char name[8];
-	int index;
-	
-	for (index=0; index < MAX_PCI_XWIDGET; index++) {
-		if (!busnum_to_pcibr_vhdl[index])
-			continue;
-
-		sprintf(name, "%d", index);
-		(void) hwgraph_edge_add(linux_busnum, busnum_to_pcibr_vhdl[index], 
-				name);
-	}
-}
-
-/*
- * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
- *
- *	Linux PCI Bus numbers are assigned from lowest module_id numbers
- *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
- *	HUB_WIDGET_ID_MIN:
- *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
- *
- *	Given 2 modules 001c01 and 001c02 we get the following mappings:
- *		001c01, widgetnum 15 = Bus number 0
- *		001c01, widgetnum 14 = Bus number 1
- *		001c02, widgetnum 15 = Bus number 3
- *		001c02, widgetnum 14 = Bus number 4
- *		etc.
- *
- * The rational for starting Bus Number 0 with Widget number 15 is because 
- * the system boot disks are always connected via Widget 15 Slot 0 of the 
- * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
- * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
- * module id(Master Cnode) of the system.
- *	
- */
-static int 
-pci_bus_map_create(devfs_handle_t xtalk)
-{
-
-	devfs_handle_t master_node_vertex = NULL;
-	devfs_handle_t xwidget = NULL;
-	devfs_handle_t pci_bus = NULL;
-	hubinfo_t hubinfo = NULL;
-	xwidgetnum_t widgetnum;
-	char pathname[128];
-	graph_error_t rv;
-	int bus;
-
-	/*
-	 * Loop throught this vertex and get the Xwidgets ..
-	 */
-
-
-	/* PCI devices */
-
-	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
-
-#if  0
-        {
-                int pos;
-                char dname[256];
-                pos = devfs_generate_path(xtalk, dname, 256);
-                printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-        }
-#endif
-
-		sprintf(pathname, "%d", widgetnum);
-		xwidget = NULL;
-		
-		/*
-		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
-		 */
-		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-		if ( (rv != GRAPH_SUCCESS) ) {
-			if (!xwidget) {
-				continue;
-}
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		pci_bus = NULL;
-		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-			if (!pci_bus) {
-				continue;
-}
-
-		/*
-		 * Assign the correct bus number and also the nasid of this 
-		 * pci Xwidget.
-		 * 
-		 * Should not be any race here ...
-		 */
-		num_bridges++;
-		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
-
-		/*
-		 * Get the master node and from there get the NASID.
-		 */
-		master_node_vertex = device_master_get(xwidget);
-		if (!master_node_vertex) {
-			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
-		}
-	
-		hubinfo_get(master_node_vertex, &hubinfo);
-		if (!hubinfo) {
-			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
-			return(1);
-		} else {
-			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
-		}
-
-		/*
-		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-		 */
-		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-		if (!busnum_to_atedmamaps[num_bridges - 1])
-			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-
-		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
-
-	}
-
-	/*
-	 * PCIX devices
-	 * We number busses differently for PCI-X devices.
-	 * We start from Lowest Widget on up ..
-	 */
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-
-		/* Do both buses */
-		for ( bus = 0; bus < 2; bus++ ) {
-			sprintf(pathname, "%d", widgetnum);
-			xwidget = NULL;
-			
-			/*
-			 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0 is the bus
-			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0/1 is device
-			 */
-			rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-			if ( (rv != GRAPH_SUCCESS) ) {
-				if (!xwidget) {
-					continue;
-				}
-			}
-	
-			if ( bus == 0 )
-				sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
-			else
-				sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
-			pci_bus = NULL;
-			if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-				if (!pci_bus) {
-					continue;
-				}
-	
-			/*
-			 * Assign the correct bus number and also the nasid of this 
-			 * pci Xwidget.
-			 * 
-			 * Should not be any race here ...
-			 */
-			num_bridges++;
-			busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
-	
-			/*
-			 * Get the master node and from there get the NASID.
-			 */
-			master_node_vertex = device_master_get(xwidget);
-			if (!master_node_vertex) {
-				printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
-			}
-		
-			hubinfo_get(master_node_vertex, &hubinfo);
-			if (!hubinfo) {
-				printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
-				return(1);
-			} else {
-				busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
-			}
-	
-			/*
-			 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-			 */
-			busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-			if (!busnum_to_atedmamaps[num_bridges - 1])
-				printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-	
-			memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
-		}
-	}
-
-        return(0);
-}
-
-/*
- * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
- *      initialization has completed to set up the mappings between Xbridge
- *      and logical pci bus numbers.  We also set up the NASID for each of these
- *      xbridges.
- *
- *      Must be called before pci_init() is invoked.
- */
-int
-pci_bus_to_hcl_cvlink(void) 
-{
-
-	devfs_handle_t devfs_hdl = NULL;
-	devfs_handle_t xtalk = NULL;
-	int rv = 0;
-	char name[256];
-	char tmp_name[256];
-	int master_iobrick;
-	slabid_t master_slab;
-	int i, ii;
-	extern nasid_t master_baseio_nasid;
-	extern nasid_t get_master_baseio_nasid(void);
-
-	/*
-	 * Iterate throught each xtalk links in the system ..
-	 * /hw/module/001c01/slab/0/node/xtalk/ 8|9|10|11|12|13|14|15 
-	 *
-	 * /hw/module/001c01/slab/0/node/xtalk/15 -> /hw/module/001c01/slab/0/Ibrick/xtalk/15
-	 *
-	 * What if it is not pci?
-	 */
-	devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");
-
-	/*
-	 * To provide consistent(not persistent) device naming, we need to start 
-	 * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 
-	 * with an attached I-Brick.  Find the master_iobrick.
-	 */
-	master_baseio_nasid = get_master_baseio_nasid();
-	master_iobrick = -1;
-	master_slab = -1;
-	if ( master_baseio_nasid >= 0 ) {
-		/* Valid nasid, need the slab ID */
-		for (i = 0; i < nummodules; i++) {
-			extern int iobrick_module_get_nasid(nasid_t);
-			moduleid_t iobrick_id; 
-			nasid_t nasid = -1;
-			int n = 0;
-			for ( n = 0; n < modules[i]->nodecnt; n++ ) {
-				nasid = cnodeid_to_nasid(modules[i]->nodes[n]);
-				iobrick_id = iobrick_module_get_nasid(nasid);
-				if (iobrick_id > 0) { /* Valid module id */
-					if ( master_baseio_nasid == nasid ) {
-						master_iobrick = i;
-						master_slab = geo_slab(modules[i]->geoid[n]);
-						printk("pci_bus_to_hcl_cvlink: Found Master Base IO Brick type %d Master Base I/O nasid %d Master Cbrick Index %d Slab %d\n", MODULE_GET_BTYPE(iobrick_id), master_baseio_nasid, master_iobrick, master_slab);
-						break;
-					}
-				}
-			}
-			if (master_slab >= 0)
-				break;
-		}
-	}
-	else {
-		/* Not sure which nasid it is - call failed, so make a guess */
-		for (i = 0; i < nummodules; i++) {
-			extern int iobrick_module_get_nasid(nasid_t);
-			moduleid_t iobrick_id; 
-			nasid_t nasid = -1;
-			int n = 0;
-			for ( n = 0; n < modules[i]->nodecnt; n++ ) {
-				nasid = cnodeid_to_nasid(modules[i]->nodes[n]);
-				iobrick_id = iobrick_module_get_nasid(nasid);
-				if (iobrick_id > 0) { /* Valid module id */
-					if ( (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) || 
-					   		(MODULE_GET_BTYPE(iobrick_id) == MODULE_PXBRICK) ||
-				   			(MODULE_GET_BTYPE(iobrick_id) == MODULE_PBRICK) ) {
-						master_iobrick = i;
-						master_baseio_nasid = nasid;
-						master_slab = geo_slab(modules[i]->geoid[n]);
-						printk("pci_bus_to_hcl_cvlink: Found Master Base IO Brick type %d Master Cbrick Index %d Slab %d\n", MODULE_GET_BTYPE(iobrick_id), master_iobrick, master_slab);
-						break;
-					}
-				}
-			}
-			if (master_iobrick >= 0)
-				break;
-		}
-	}
-
-	if (master_iobrick == -1) {
-		panic("Unable to find the Master BaseIO PCI/PCIX Bus\n");
-	}
-
-	/*
-	 * The master_iobrick gets bus 0 and 1.
-	 */
-	if (master_iobrick >= 0) {
-		memset(name, 0, 256);
-		memset(tmp_name, 0, 256);
-		format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF);
-		sprintf(tmp_name, "/slab/%d/node/xtalk", master_slab);
-		strcat(name, tmp_name);
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-		
-	/*
-	 * Now go do the rest of the modules, starting from the C-Brick with the lowest 
-	 * module id, remembering to skip the master_iobrick, which was done above.
-	 */
-	for (i = 0; i < nummodules ; i++) {
-		for ( ii = 0; ii < MAX_SLABS; ii++ ) {
-			if ((i == master_iobrick) && (master_slab == ii))
-				continue; /* Did the master_iobrick/slab already. */
-			memset(name, 0, 256);
-			memset(tmp_name, 0, 256);
-			format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
-			sprintf(tmp_name, "/slab/%d/node/xtalk", ii);
-			strcat(name, tmp_name);
-			xtalk = NULL;
-			rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-			pci_bus_map_create(xtalk);
-		}
-	}
-
-	/*
-	 * Create the Linux PCI bus number vertex link.
-	 */
-	(void)linux_bus_cvlink();
-
-	return(0);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/Makefile linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/Makefile	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/Makefile	2003-07-05 18:09:44.000000000 -0700
@@ -3,21 +3,20 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
 #
 # Makefile for the sn2 io pcibr routines.
 
 EXTRA_CFLAGS    := -DLITTLE_ENDIAN
 
-ifdef CONFIG_IA64_SGI_SN2
 EXTRA_CFLAGS    += -DSHUB_SWAP_WAR
-endif
 
 O_TARGET := pcibr.o
+export-objs := pcibr_intr.o
 
-obj-$(CONFIG_IA64_SGI_SN2)	+= pcibr_dvr.o pcibr_ate.o pcibr_config.o \
-                                   pcibr_dvr.o pcibr_hints.o \
-				   pcibr_intr.o pcibr_rrb.o pcibr_slot.o \
-				   pcibr_error.o
+obj-y	+= pcibr_ate.o pcibr_config.o \
+           pcibr_dvr.o pcibr_hints.o \
+	   pcibr_intr.o pcibr_rrb.o pcibr_slot.o \
+	   pcibr_error.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	2003-06-13 07:51:30.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,23 +27,9 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-#ifdef __ia64
-uint64_t atealloc(struct map *mp, size_t size);
-void atefree(struct map *mp, size_t size, uint64_t a);
-void atemapfree(struct map *mp);
-struct map *atemapalloc(uint64_t mapsiz);
-
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
-
 #ifndef LOCAL
 #define LOCAL           static
 #endif
@@ -101,73 +87,26 @@
     int                     i, j;
     bridgereg_t             old_enable, new_enable;
     int                     s;
-    int			    this_is_pic = is_pic(bridge);
 
     /* Probe SSRAM to determine its size. */
-    if ( this_is_pic ) {
-	old_enable = bridge->b_int_enable;
-	new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-	bridge->b_int_enable = new_enable;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		old_enable = BRIDGE_REG_GET32((&bridge->b_int_enable));
-		new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-		BRIDGE_REG_SET32((&bridge->b_int_enable)) = new_enable;
-	}
-	else {
-		old_enable = bridge->b_int_enable;
-		new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-		bridge->b_int_enable = new_enable;
-	}
-    }
+    old_enable = bridge->b_int_enable;
+    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
+    bridge->b_int_enable = new_enable;
 
     for (i = 1; i < ATE_NUM_SIZES; i++) {
 	/* Try writing a value */
-	if ( this_is_pic ) {
-		bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge)))
-			bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = __swab64(ATE_PROBE_VALUE);
-		else
-			bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
-	}
+	bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
 
 	/* Guard against wrap */
 	for (j = 1; j < i; j++)
 	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;
 
 	/* See if value was written */
-	if ( this_is_pic ) {
-		if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
+	if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
 				largest_working_size = i;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == __swab64(ATE_PROBE_VALUE))
-					largest_working_size = i;
-			else {
-				if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
-					largest_working_size = i;
-			}
-		}
-	}
-    }
-    if ( this_is_pic ) {
-	bridge->b_int_enable = old_enable;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_int_enable)) = old_enable;
-		BRIDGE_REG_GET32((&bridge->b_wid_tflush));   /* wait until Bridge PIO complete */
-	}
-	else {
-		bridge->b_int_enable = old_enable;
-		bridge->b_wid_tflush;               /* wait until Bridge PIO complete */
-	}
     }
+    bridge->b_int_enable = old_enable;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
 
     /*
      * ensure that we write and read without any interruption.
@@ -175,26 +114,10 @@
      */
 
     s = splhi();
-    if ( this_is_pic ) {
-	bridge->b_wid_control = (bridge->b_wid_control
+    bridge->b_wid_control = (bridge->b_wid_control
 			& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
 			| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
-	bridge->b_wid_control;		/* inval addr bug war */
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&(bridge->b_wid_control))) = 
-				__swab32((BRIDGE_REG_GET32((&bridge->b_wid_control))
-					& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
-					| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size));
-		BRIDGE_REG_GET32((&bridge->b_wid_control));/* inval addr bug war */
-	}
-	else {
-		bridge->b_wid_control = (bridge->b_wid_control & ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
-				| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
-		bridge->b_wid_control;              /* inval addr bug war */
-	}
-    }
+    bridge->b_wid_control;		/* inval addr bug war */
     splx(s);
 
     num_entries = ATE_NUM_ENTRIES(largest_working_size);
@@ -229,32 +152,55 @@
 int
 pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count)
 {
-    int                     index = 0;
-
-    index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count);
+    int			    status = 0;
+    struct resource	    *new_res;
+    struct resource         **allocated_res;
+
+    new_res = (struct resource *) kmalloc( sizeof(struct resource), GFP_ATOMIC);
+    memset(new_res, 0, sizeof(*new_res));
+    status = allocate_resource( &pcibr_soft->bs_int_ate_resource, new_res,
+				count, pcibr_soft->bs_int_ate_resource.start, 
+				pcibr_soft->bs_int_ate_resource.end, 1,
+				NULL, NULL);
+
+    if ( status && (pcibr_soft->bs_ext_ate_resource.end != 0) ) {
+	status = allocate_resource( &pcibr_soft->bs_ext_ate_resource, new_res,
+				count, pcibr_soft->bs_ext_ate_resource.start,
+				pcibr_soft->bs_ext_ate_resource.end, 1,
+				NULL, NULL);
+	if (status) {
+		new_res->start = -1;
+	}
+    }
 
-    if (!index && pcibr_soft->bs_ext_ate_map)
-	index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count);
+    if (status) {
+	/* Failed to allocate */
+	kfree(new_res);
+	return -1;
+    }
+
+    /* Save the resource for freeing */
+    allocated_res = (struct resource **)(((unsigned long)pcibr_soft->bs_allocated_ate_res) + new_res->start * sizeof( unsigned long));
+    *allocated_res = new_res;
 
-    /* rmalloc manages resources in the 1..n
-     * range, with 0 being failure.
-     * pcibr_ate_alloc manages resources
-     * in the 0..n-1 range, with -1 being failure.
-     */
-    return index - 1;
+    return new_res->start;
 }
 
 void
 pcibr_ate_free(pcibr_soft_t pcibr_soft, int index, int count)
 /* Who says there's no such thing as a free meal? :-) */
 {
-    /* note the "+1" since rmalloc handles 1..n but
-     * we start counting ATEs at zero.
-     */
-    rmfree((index < pcibr_soft->bs_int_ate_size)
-	   ? pcibr_soft->bs_int_ate_map
-	   : pcibr_soft->bs_ext_ate_map,
-	   count, index + 1);
+
+    struct resource **allocated_res;
+    int status = 0;
+
+    allocated_res = (struct resource **)(((unsigned long)pcibr_soft->bs_allocated_ate_res) + index * sizeof(unsigned long));
+
+    status = release_resource(*allocated_res);
+    if (status)
+	BUG(); /* Ouch .. */
+    kfree(*allocated_res);
+
 }
 
 /*
@@ -362,7 +308,7 @@
 
     /* Bridge Hardware Bug WAR #484930:
      * Bridge can't handle updating External ATEs
-     * while DMA is occuring that uses External ATEs,
+     * while DMA is occurring that uses External ATEs,
      * even if the particular ATEs involved are disjoint.
      */
 
@@ -423,16 +369,7 @@
 			    /* Flush the write buffer associated with this
 			     * PCI device which might be using dma map RAM.
 			     */
-			if ( is_pic(bridge) ) {
-				bridge->b_wr_req_buf[slot].reg;
-			}
-			else {
-				if (io_get_sh_swapper(NASID_GET(bridge)) ) {
-					BRIDGE_REG_GET32((&bridge->b_wr_req_buf[slot].reg));
-				}
-				else
-					bridge->b_wr_req_buf[slot].reg;
-			}
+			bridge->b_wr_req_buf[slot].reg;
 		    }
 	    }
     }
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -28,21 +28,18 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-extern pcibr_info_t      pcibr_info_get(devfs_handle_t);
+extern pcibr_info_t      pcibr_info_get(vertex_hdl_t);
 
-uint64_t          pcibr_config_get(devfs_handle_t, unsigned, unsigned);
-uint64_t          do_pcibr_config_get(int, cfg_p, unsigned, unsigned);
-void              pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
-void       	  do_pcibr_config_set(int, cfg_p, unsigned, unsigned, uint64_t);
-static void	  swap_do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
+uint64_t          pcibr_config_get(vertex_hdl_t, unsigned, unsigned);
+uint64_t          do_pcibr_config_get(cfg_p, unsigned, unsigned);
+void              pcibr_config_set(vertex_hdl_t, unsigned, unsigned, uint64_t);
+void       	  do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
 
-#ifdef LITTLE_ENDIAN
 /*
- * on sn-ia we need to twiddle the addresses going out
+ * on sn-ia we need to twiddle the the addresses going out
  * the pci bus because we use the unswizzled synergy space
  * (the alternative is to use the swizzled synergy space
  * and byte swap the data)
@@ -51,18 +48,13 @@
 #define CS(b,r) (((volatile uint16_t *) b)[((r^4)/2)])
 #define CW(b,r) (((volatile uint32_t *) b)[((r^4)/4)])
 
-#define	CBP(b,r) (((volatile uint8_t *) b)[(r)^3])
-#define	CSP(b,r) (((volatile uint16_t *) b)[((r)/2)^1])
+#define	CBP(b,r) (((volatile uint8_t *) b)[(r)])
+#define	CSP(b,r) (((volatile uint16_t *) b)[((r)/2)])
 #define	CWP(b,r) (((volatile uint32_t *) b)[(r)/4])
 
 #define SCB(b,r) (((volatile uint8_t *) b)[((r)^3)])
 #define SCS(b,r) (((volatile uint16_t *) b)[((r^2)/2)])
 #define SCW(b,r) (((volatile uint32_t *) b)[((r)/4)])
-#else
-#define	CB(b,r)	(((volatile uint8_t *) cfgbase)[(r)^3])
-#define	CS(b,r)	(((volatile uint16_t *) cfgbase)[((r)/2)^1])
-#define	CW(b,r)	(((volatile uint32_t *) cfgbase)[(r)/4])
-#endif
 
 /*
  * Return a config space address for given slot / func / offset.  Note the
@@ -84,8 +76,7 @@
 	/*
 	 * Type 0 config space
 	 */
-	if (is_pic(bridge))
-		slot++;
+	slot++;
 	return &bridge->b_type0_cfg_dev[slot].f[func].l[offset];
 }
 
@@ -109,7 +100,7 @@
 	cfg_p  cfg_base;
 	
 	cfg_base = pcibr_slot_config_addr(bridge, slot, 0);
-	return (do_pcibr_config_get(is_pic(bridge), cfg_base, offset, sizeof(unsigned)));
+	return (do_pcibr_config_get(cfg_base, offset, sizeof(unsigned)));
 }
 
 /*
@@ -122,7 +113,7 @@
 	cfg_p  cfg_base;
 
 	cfg_base = pcibr_func_config_addr(bridge, 0, slot, func, 0);
-	return (do_pcibr_config_get(is_pic(bridge), cfg_base, offset, sizeof(unsigned)));
+	return (do_pcibr_config_get(cfg_base, offset, sizeof(unsigned)));
 }
 
 /*
@@ -135,7 +126,7 @@
 	cfg_p  cfg_base;
 
 	cfg_base = pcibr_slot_config_addr(bridge, slot, 0);
-	do_pcibr_config_set(is_pic(bridge), cfg_base, offset, sizeof(unsigned), val);
+	do_pcibr_config_set(cfg_base, offset, sizeof(unsigned), val);
 }
 
 /*
@@ -148,13 +139,13 @@
 	cfg_p  cfg_base;
 
 	cfg_base = pcibr_func_config_addr(bridge, 0, slot, func, 0);
-	do_pcibr_config_set(is_pic(bridge), cfg_base, offset, sizeof(unsigned), val);
+	do_pcibr_config_set(cfg_base, offset, sizeof(unsigned), val);
 }
 
 int pcibr_config_debug = 0;
 
 cfg_p
-pcibr_config_addr(devfs_handle_t conn,
+pcibr_config_addr(vertex_hdl_t conn,
 		  unsigned reg)
 {
     pcibr_info_t            pcibr_info;
@@ -183,19 +174,6 @@
 	pciio_func = PCI_TYPE1_FUNC(reg);
 
 	ASSERT(pciio_bus != 0);
-#if 0
-    } else if (conn != pciio_info_hostdev_get(pciio_info)) {
-	/*
-	 * Conn is on a subordinate bus, so get bus/slot/func directly from
-	 * its pciio_info_t structure.
-	 */
-	pciio_bus = pciio_info->c_bus;
-	pciio_slot = pciio_info->c_slot;
-	pciio_func = pciio_info->c_func;
-	if (pciio_func == PCIIO_FUNC_NONE) {
-		pciio_func = 0;
-	}
-#endif
     } else {
 	/*
 	 * Conn is directly connected to the host bus.  PCI bus number is
@@ -224,44 +202,23 @@
     return cfgbase;
 }
 
-extern unsigned char Is_pic_on_this_nasid[];
 uint64_t
-pcibr_config_get(devfs_handle_t conn,
+pcibr_config_get(vertex_hdl_t conn,
 		 unsigned reg,
 		 unsigned size)
 {
-    if ( !Is_pic_on_this_nasid[ NASID_GET((pcibr_config_addr(conn, reg)))] )
-    	return do_pcibr_config_get(0, pcibr_config_addr(conn, reg),
-				PCI_TYPE1_REG(reg), size);
-    else
-    	return do_pcibr_config_get(1, pcibr_config_addr(conn, reg),
+	return do_pcibr_config_get(pcibr_config_addr(conn, reg),
 				PCI_TYPE1_REG(reg), size);
 }
 
 uint64_t
-do_pcibr_config_get(
-		       int pic,
-		       cfg_p cfgbase,
+do_pcibr_config_get(cfg_p cfgbase,
 		       unsigned reg,
 		       unsigned size)
 {
     unsigned                value;
 
-    if ( pic ) {
-	value = CWP(cfgbase, reg);
-    }
-    else {
-	if ( io_get_sh_swapper(NASID_GET(cfgbase)) ) {
-	    /*
-	     * Shub Swapper on - 0 returns PCI Offset 0 but byte swapped!
-	     * Do not swizzle address and byte swap the result.
-	     */
-	    value = SCW(cfgbase, reg);
-	    value = __swab32(value);
-	} else {
-    	    value = CW(cfgbase, reg);
-	}
-    }
+    value = CWP(cfgbase, reg);
     if (reg & 3)
 	value >>= 8 * (reg & 3);
     if (size < 4)
@@ -270,108 +227,43 @@
 }
 
 void
-pcibr_config_set(devfs_handle_t conn,
+pcibr_config_set(vertex_hdl_t conn,
 		 unsigned reg,
 		 unsigned size,
 		 uint64_t value)
 {
-    if ( Is_pic_on_this_nasid[ NASID_GET((pcibr_config_addr(conn, reg)))] )
-    	do_pcibr_config_set(1, pcibr_config_addr(conn, reg),
-			PCI_TYPE1_REG(reg), size, value);
-    else
-	swap_do_pcibr_config_set(pcibr_config_addr(conn, reg),
+	do_pcibr_config_set(pcibr_config_addr(conn, reg),
 			PCI_TYPE1_REG(reg), size, value);
 }
 
 void
-do_pcibr_config_set(int pic,
-		    cfg_p cfgbase,
+do_pcibr_config_set(cfg_p cfgbase,
 		    unsigned reg,
 		    unsigned size,
 		    uint64_t value)
 {
-	if ( pic ) {
-		switch (size) {
-		case 1:
+	switch (size) {
+	case 1:
+		CBP(cfgbase, reg) = value;
+		break;
+	case 2:
+		if (reg & 1) {
 			CBP(cfgbase, reg) = value;
-			break;
-		case 2:
-			if (reg & 1) {
-				CBP(cfgbase, reg) = value;
-				CBP(cfgbase, reg + 1) = value >> 8;
-			} else
-				CSP(cfgbase, reg) = value;
-			break;
-		case 3:
-			if (reg & 1) {
-				CBP(cfgbase, reg) = value;
-				CSP(cfgbase, (reg + 1)) = value >> 8;
-			} else {
-				CSP(cfgbase, reg) = value;
-				CBP(cfgbase, reg + 2) = value >> 16;
-			}
-			break;
-		case 4:
-			CWP(cfgbase, reg) = value;
-			break;
-   		}
-	}
-	else {
-		switch (size) {
-		case 1:
-			CB(cfgbase, reg) = value;
-			break;
-		case 2:
-			if (reg & 1) {
-				CB(cfgbase, reg) = value;
-				CB(cfgbase, reg + 1) = value >> 8;
-			} else
-				CS(cfgbase, reg) = value;
-			break;
-		case 3:
-			if (reg & 1) {
-				CB(cfgbase, reg) = value;
-				CS(cfgbase, (reg + 1)) = value >> 8;
-			} else {
-				CS(cfgbase, reg) = value;
-				CB(cfgbase, reg + 2) = value >> 16;
-			}
-			break;
-		case 4:
-			CW(cfgbase, reg) = value;
-			break;
-   		}
-	}
-}
-
-void
-swap_do_pcibr_config_set(cfg_p cfgbase,
-                    unsigned reg,
-                    unsigned size,
-                    uint64_t value)
-{
-
-    uint64_t temp_value = 0;
-
-    switch (size) {
-    case 1:
-        SCB(cfgbase, reg) = value;
-        break;
-    case 2:
-	temp_value = __swab16(value);
-        if (reg & 1) {
-            SCB(cfgbase, reg) = temp_value;
-            SCB(cfgbase, reg + 1) = temp_value >> 8;
-        } else
-            SCS(cfgbase, reg) = temp_value;
-        break;
-    case 3:
-	BUG();
-        break;
-
-    case 4:
-	temp_value = __swab32(value);
-        SCW(cfgbase, reg) = temp_value;
-        break;
-    }
+			CBP(cfgbase, reg + 1) = value >> 8;
+		} else
+			CSP(cfgbase, reg) = value;
+		break;
+	case 3:
+		if (reg & 1) {
+			CBP(cfgbase, reg) = value;
+			CSP(cfgbase, (reg + 1)) = value >> 8;
+		} else {
+			CSP(cfgbase, reg) = value;
+			CBP(cfgbase, reg + 2) = value >> 16;
+		}
+		break;
+	case 4:
+		CWP(cfgbase, reg) = value;
+		break;
+ 	}
 }
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,13 +4,17 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/sn_sal.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
@@ -18,6 +22,7 @@
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
+#include <asm/sn/klconfig.h>
 #include <asm/sn/xtalk/xwidget.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/pci/pciio.h>
@@ -27,17 +32,9 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
 /*
  * global variables to toggle the different levels of pcibr debugging.  
  *   -pcibr_debug_mask is the mask of the different types of debugging
@@ -74,32 +71,6 @@
 #define USS302_BRIDGE_TIMEOUT_HLD	4
 #endif
 
-int                     pcibr_devflag = D_MP;
-
-/*
- * This is the file operation table for the pcibr driver.
- * As each of the functions are implemented, put the
- * appropriate function name below.
- */
-struct file_operations pcibr_fops = {
-	owner:  THIS_MODULE,
-	llseek: NULL,
-	read: NULL,
-	write: NULL,
-	readdir: NULL,
-	poll: NULL,
-	ioctl: NULL,
-	mmap: NULL,
-	open: NULL,
-	flush: NULL,
-	release: NULL,
-	fsync: NULL,
-	fasync: NULL,
-	lock: NULL,
-	readv: NULL,
-	writev: NULL
-};
-
 /* kbrick widgetnum-to-bus layout */
 int p_busnum[MAX_PORT_NUM] = {                  /* widget#      */
         0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7    */
@@ -116,17 +87,16 @@
 pcibr_list_p            pcibr_list = 0;
 #endif
 
-extern int              hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-extern int              hub_device_flags_set(devfs_handle_t widget_dev, hub_widget_flags_t flags);
+extern int              hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen);
 extern long             atoi(register char *p);
-extern cnodeid_t        nodevertex_to_cnodeid(devfs_handle_t vhdl);
-extern char             *dev_to_name(devfs_handle_t dev, char *buf, uint buflen);
+extern cnodeid_t        nodevertex_to_cnodeid(vertex_hdl_t vhdl);
+extern char             *dev_to_name(vertex_hdl_t dev, char *buf, uint buflen);
 extern struct map       *atemapalloc(uint64_t);
 extern void             atefree(struct map *, size_t, uint64_t);
 extern void             atemapfree(struct map *);
-extern pciio_dmamap_t   get_free_pciio_dmamap(devfs_handle_t);
+extern pciio_dmamap_t   get_free_pciio_dmamap(vertex_hdl_t);
 extern void		free_pciio_dmamap(pcibr_dmamap_t);
-extern void		xwidget_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
+extern void		xwidget_error_register(vertex_hdl_t, error_handler_f *, error_handler_arg_t);
 
 #define	ATE_WRITE()    ate_write(pcibr_soft, ate_ptr, ate_count, ate)
 #if PCIBR_FREEZE_TIME
@@ -153,9 +123,9 @@
 extern int		 do_pcibr_rrb_free_all(pcibr_soft_t, bridge_t *, pciio_slot_t);
 extern void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int, int);
 
-extern int  		 pcibr_wrb_flush(devfs_handle_t);
-extern int               pcibr_rrb_alloc(devfs_handle_t, int *, int *);
-extern void              pcibr_rrb_flush(devfs_handle_t);
+extern int  		 pcibr_wrb_flush(vertex_hdl_t);
+extern int               pcibr_rrb_alloc(vertex_hdl_t, int *, int *);
+extern void              pcibr_rrb_flush(vertex_hdl_t);
 
 static int                pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t);
 void                     pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t);
@@ -166,21 +136,15 @@
 extern iopaddr_t         pcibr_bus_addr_alloc(pcibr_soft_t, pciio_win_info_t,
                                               pciio_space_t, int, int, int);
 
-void                     pcibr_init(void);
-int                      pcibr_attach(devfs_handle_t);
-int			 pcibr_attach2(devfs_handle_t, bridge_t *, devfs_handle_t,
+int                      pcibr_attach(vertex_hdl_t);
+int			 pcibr_attach2(vertex_hdl_t, bridge_t *, vertex_hdl_t,
 				       int, pcibr_soft_t *);
-int			 pcibr_detach(devfs_handle_t);
-int                      pcibr_open(devfs_handle_t *, int, int, cred_t *);
-int                      pcibr_close(devfs_handle_t, int, int, cred_t *);
-int                      pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                      pcibr_unmap(devfs_handle_t, vhandl_t *);
-int                      pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
+int			 pcibr_detach(vertex_hdl_t);
 int			 pcibr_pcix_rbars_calc(pcibr_soft_t);
 extern int               pcibr_init_ext_ate_ram(bridge_t *);
 extern int               pcibr_ate_alloc(pcibr_soft_t, int);
 extern void              pcibr_ate_free(pcibr_soft_t, int, int);
-extern int 		 pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl);
+extern int 		 pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl);
 
 extern unsigned ate_freeze(pcibr_dmamap_t pcibr_dmamap,
 #if PCIBR_FREEZE_TIME
@@ -197,45 +161,43 @@
 	 		unsigned *cmd_regs,
 	 		unsigned s);
 
-pcibr_info_t      pcibr_info_get(devfs_handle_t);
+pcibr_info_t      pcibr_info_get(vertex_hdl_t);
 
-static iopaddr_t         pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+static iopaddr_t         pcibr_addr_pci_to_xio(vertex_hdl_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
 
-pcibr_piomap_t          pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
+pcibr_piomap_t          pcibr_piomap_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
 void                    pcibr_piomap_free(pcibr_piomap_t);
 caddr_t                 pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t);
 void                    pcibr_piomap_done(pcibr_piomap_t);
-caddr_t                 pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-iopaddr_t               pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
+caddr_t                 pcibr_piotrans_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+iopaddr_t               pcibr_piospace_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, size_t, size_t);
+void                    pcibr_piospace_free(vertex_hdl_t, pciio_space_t, iopaddr_t, size_t);
 
 static iopaddr_t         pcibr_flags_to_d64(unsigned, pcibr_soft_t);
 extern bridge_ate_t     pcibr_flags_to_ate(unsigned);
 
-pcibr_dmamap_t          pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
+pcibr_dmamap_t          pcibr_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned);
 void                    pcibr_dmamap_free(pcibr_dmamap_t);
 extern bridge_ate_p     pcibr_ate_addr(pcibr_soft_t, int);
 static iopaddr_t         pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t);
 iopaddr_t               pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t);
-alenlist_t              pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned);
 void                    pcibr_dmamap_done(pcibr_dmamap_t);
-cnodeid_t		pcibr_get_dmatrans_node(devfs_handle_t);
-iopaddr_t               pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
+cnodeid_t		pcibr_get_dmatrans_node(vertex_hdl_t);
+iopaddr_t               pcibr_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
 void                    pcibr_dmamap_drain(pcibr_dmamap_t);
-void                    pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void                    pcibr_dmalist_drain(devfs_handle_t, alenlist_t);
+void                    pcibr_dmaaddr_drain(vertex_hdl_t, paddr_t, size_t);
+void                    pcibr_dmalist_drain(vertex_hdl_t, alenlist_t);
 iopaddr_t               pcibr_dmamap_pciaddr_get(pcibr_dmamap_t);
 
 extern unsigned		pcibr_intr_bits(pciio_info_t info, 
 					pciio_intr_line_t lines, int nslots);
-extern pcibr_intr_t     pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+extern pcibr_intr_t     pcibr_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t);
 extern void             pcibr_intr_free(pcibr_intr_t);
 extern void             pcibr_setpciint(xtalk_intr_t);
 extern int              pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t);
 extern void             pcibr_intr_disconnect(pcibr_intr_t);
 
-extern devfs_handle_t     pcibr_intr_cpu_get(pcibr_intr_t);
+extern vertex_hdl_t     pcibr_intr_cpu_get(pcibr_intr_t);
 extern void             pcibr_intr_func(intr_arg_t);
 
 extern void             print_bridge_errcmd(uint32_t, char *);
@@ -253,51 +215,48 @@
 extern int              pcibr_dmawr_error(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *);
 extern int              pcibr_error_handler(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *);
 extern int              pcibr_error_handler_wrapper(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *);
-void                    pcibr_provider_startup(devfs_handle_t);
-void                    pcibr_provider_shutdown(devfs_handle_t);
+void                    pcibr_provider_startup(vertex_hdl_t);
+void                    pcibr_provider_shutdown(vertex_hdl_t);
 
-int                     pcibr_reset(devfs_handle_t);
-pciio_endian_t          pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
+int                     pcibr_reset(vertex_hdl_t);
+pciio_endian_t          pcibr_endian_set(vertex_hdl_t, pciio_endian_t, pciio_endian_t);
 int                     pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t);
-pciio_priority_t        pcibr_priority_set(devfs_handle_t, pciio_priority_t);
-int                     pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t);
+pciio_priority_t        pcibr_priority_set(vertex_hdl_t, pciio_priority_t);
+int                     pcibr_device_flags_set(vertex_hdl_t, pcibr_device_flags_t);
+
+extern cfg_p            pcibr_config_addr(vertex_hdl_t, unsigned);
+extern uint64_t         pcibr_config_get(vertex_hdl_t, unsigned, unsigned);
+extern void             pcibr_config_set(vertex_hdl_t, unsigned, unsigned, uint64_t);
+
+extern pcibr_hints_t    pcibr_hints_get(vertex_hdl_t, int);
+extern void             pcibr_hints_fix_rrbs(vertex_hdl_t);
+extern void             pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
+extern void	 	pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *);
+extern void             pcibr_set_rrb_callback(vertex_hdl_t, rrb_alloc_funct_t);
+extern void             pcibr_hints_handsoff(vertex_hdl_t);
+extern void             pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, uint64_t);
 
-extern cfg_p            pcibr_config_addr(devfs_handle_t, unsigned);
-extern uint64_t         pcibr_config_get(devfs_handle_t, unsigned, unsigned);
-extern void             pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
-
-extern pcibr_hints_t    pcibr_hints_get(devfs_handle_t, int);
-extern void             pcibr_hints_fix_rrbs(devfs_handle_t);
-extern void             pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-extern void	 	pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
-extern void             pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
-extern void             pcibr_hints_handsoff(devfs_handle_t);
-extern void             pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t);
-
-extern int		pcibr_slot_reset(devfs_handle_t,pciio_slot_t);
-extern int		pcibr_slot_info_init(devfs_handle_t,pciio_slot_t);
-extern int		pcibr_slot_info_free(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_info_init(vertex_hdl_t,pciio_slot_t);
+extern int		pcibr_slot_info_free(vertex_hdl_t,pciio_slot_t);
 extern int	        pcibr_slot_info_return(pcibr_soft_t, pciio_slot_t,
                                                pcibr_slot_info_resp_t);
 extern void       	pcibr_slot_func_info_return(pcibr_info_h, int,
                                                     pcibr_slot_func_info_resp_t);
-extern int		pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_addr_space_init(vertex_hdl_t,pciio_slot_t);
 extern int		pcibr_slot_pcix_rbar_init(pcibr_soft_t, pciio_slot_t);
-extern int		pcibr_slot_device_init(devfs_handle_t, pciio_slot_t);
-extern int		pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t);
-extern int		pcibr_slot_call_device_attach(devfs_handle_t,
+extern int		pcibr_slot_device_init(vertex_hdl_t, pciio_slot_t);
+extern int		pcibr_slot_guest_info_init(vertex_hdl_t,pciio_slot_t);
+extern int		pcibr_slot_call_device_attach(vertex_hdl_t,
 						      pciio_slot_t, int);
-extern int		pcibr_slot_call_device_detach(devfs_handle_t,
+extern int		pcibr_slot_call_device_detach(vertex_hdl_t,
 						      pciio_slot_t, int);
-extern int              pcibr_slot_attach(devfs_handle_t, pciio_slot_t, int, 
+extern int              pcibr_slot_attach(vertex_hdl_t, pciio_slot_t, int, 
                                                       char *, int *);
-extern int              pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int,
+extern int              pcibr_slot_detach(vertex_hdl_t, pciio_slot_t, int,
                                                       char *, int *);
-extern int 		pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t);
-
-extern int		pcibr_slot_initial_rrb_alloc(devfs_handle_t, pciio_slot_t);
-extern int		pcibr_initial_rrb(devfs_handle_t, pciio_slot_t, pciio_slot_t);
 
+extern int		pcibr_slot_initial_rrb_alloc(vertex_hdl_t, pciio_slot_t);
+extern int		pcibr_initial_rrb(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
 
 /* =====================================================================
  *    Device(x) register management
@@ -623,172 +582,52 @@
  */
 
 
-/*
- *    pcibr_init: called once during system startup or
- *      when a loadable driver is loaded.
- *
- *      The driver_register function should normally
- *      be in _reg, not _init.  But the pcibr driver is
- *      required by devinit before the _reg routines
- *      are called, so this is an exception.
- */
-void
-pcibr_init(void)
+static int
+pcibr_mmap(struct file * file, struct vm_area_struct * vma)
 {
-    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INIT, NULL, "pcibr_init()\n"));
+	vertex_hdl_t		pcibr_vhdl;
+	pcibr_soft_t            pcibr_soft;
+	bridge_t               *bridge;
+	unsigned long		phys_addr;
+	int			error = 0;
 
-    xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM,
-			    XBRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
-    xwidget_driver_register(BRIDGE_WIDGET_PART_NUM,
-			    BRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
+#ifdef CONFIG_HWGFS_FS
+	pcibr_vhdl = (vertex_hdl_t) file->f_dentry->d_fsdata;
+#else
+	pcibr_vhdl = (vertex_hdl_t) file->private_data;
+#endif
+	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+	bridge = pcibr_soft->bs_base;
+	phys_addr = (unsigned long)bridge & ~0xc000000000000000; /* Mask out the Uncache bits */
+        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+        vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
+        error = io_remap_page_range(vma->vm_start, phys_addr,
+                                   vma->vm_end-vma->vm_start,
+                                   vma->vm_page_prot);
+	return(error);
 }
 
 /*
- * open/close mmap/munmap interface would be used by processes
- * that plan to map the PCI bridge, and muck around with the
- * registers. This is dangerous to do, and will be allowed
- * to a select brand of programs. Typically these are
- * diagnostics programs, or some user level commands we may
- * write to do some weird things.
- * To start with expect them to have root priveleges.
- * We will ask for more later.
+ * This is the file operation table for the pcibr driver.
+ * As each of the functions are implemented, put the
+ * appropriate function name below.
  */
-/* ARGSUSED */
-int
-pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    int                     error;
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get(vhdl);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    ASSERT(pcibr_soft);
-    len = ctob(btoc(len));		/* Make len page aligned */
-    error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len);
-
-    /*
-     * If the offset being mapped corresponds to the flash prom
-     * base, and if the mapping succeeds, and if the user
-     * has requested the protections to be WRITE, enable the
-     * flash prom to be written.
-     *
-     * XXX- deprecate this in favor of using the
-     * real flash driver ...
-     */
-    if (IS_BRIDGE_SOFT(pcibr_soft) && !error &&
-	((off == BRIDGE_EXTERNAL_FLASH) ||
-	 (len > BRIDGE_EXTERNAL_FLASH))) {
-	int                     s;
-
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	s = splhi();
-
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_wid_control)) |= __swab32(BRIDGE_CTRL_FLASH_WR_EN);
-		BRIDGE_REG_GET32((&bridge->b_wid_control));          /* inval addr bug war */
-	} else {
-		bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN;
-		bridge->b_wid_control;          /* inval addr bug war */
-	}
-	splx(s);
-    }
-    return error;
-}
-
-/*ARGSUSED */
-int
-pcibr_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    if ( IS_PIC_SOFT(pcibr_soft) ) {
-	/*
-	 * If flashprom write was enabled, disable it, as
-	 * this is the last unmap.
-	 */
-	if (IS_BRIDGE_SOFT(pcibr_soft) && 
-			(bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN)) {
-		int                     s;
-
-		/*
-		 * ensure that we write and read without any interruption.
-		 * The read following the write is required for the Bridge war
-		 */
-		s = splhi();
-		bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
-		bridge->b_wid_control;		/* inval addr bug war */
-		splx(s);
-	}
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		if (BRIDGE_REG_GET32((&bridge->b_wid_control)) & BRIDGE_CTRL_FLASH_WR_EN) {
-			int                     s;
-
-			/*
-			 * ensure that we write and read without any interruption.
-			 * The read following the write is required for the Bridge war
-			 */
-			s = splhi();
-			BRIDGE_REG_SET32((&bridge->b_wid_control)) &= __swab32((unsigned int)~BRIDGE_CTRL_FLASH_WR_EN);
-			BRIDGE_REG_GET32((&bridge->b_wid_control));          /* inval addr bug war */
-			splx(s);
-		} else {
-			if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) {
-				int                     s;
+static int pcibr_mmap(struct file * file, struct vm_area_struct * vma);
+struct file_operations pcibr_fops = {
+	.owner		= THIS_MODULE,
+	.mmap		= pcibr_mmap,
+};
 
-				/*
-				 * ensure that we write and read without any interruption.
-				 * The read following the write is required for the Bridge war
-				 */
-				s = splhi();
-				bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
-				bridge->b_wid_control;          /* inval addr bug war */
-				splx(s);
-    			}
-		}
-	}
-    }
-    return 0;
-}
 
 /* This is special case code used by grio. There are plans to make
  * this a bit more general in the future, but till then this should
  * be sufficient.
  */
 pciio_slot_t
-pcibr_device_slot_get(devfs_handle_t dev_vhdl)
+pcibr_device_slot_get(vertex_hdl_t dev_vhdl)
 {
     char                    devname[MAXDEVNAME];
-    devfs_handle_t            tdev;
+    vertex_hdl_t            tdev;
     pciio_info_t            pciio_info;
     pciio_slot_t            slot = PCIIO_SLOT_NONE;
 
@@ -812,20 +651,8 @@
     return slot;
 }
 
-/*ARGSUSED */
-int
-pcibr_ioctl(devfs_handle_t dev,
-	    int cmd,
-	    void *arg,
-	    int flag,
-	    struct cred *cr,
-	    int *rvalp)
-{
-    return 0;
-}
-
 pcibr_info_t
-pcibr_info_get(devfs_handle_t vhdl)
+pcibr_info_get(vertex_hdl_t vhdl)
 {
     return (pcibr_info_t) pciio_info_get(vhdl);
 }
@@ -849,7 +676,7 @@
      * will set the c_slot (which is suppose to represent the external
      * slot (i.e the slot number silk screened on the back of the I/O
      * brick)).  So for PIC we need to adjust this "internal slot" num
-     * passed into us, into it's external representation.  See comment
+     * passed into us, into its external representation.  See comment
      * for the PCIBR_DEVICE_TO_SLOT macro for more information.
      */
     NEW(pcibr_info);
@@ -902,10 +729,10 @@
  *	This is usually used at the time of shutting down of the PCI card.
  */
 int
-pcibr_device_unregister(devfs_handle_t pconn_vhdl)
+pcibr_device_unregister(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t	 pciio_info;
-    devfs_handle_t	 pcibr_vhdl;
+    vertex_hdl_t	 pcibr_vhdl;
     pciio_slot_t	 slot;
     pcibr_soft_t	 pcibr_soft;
     bridge_t		*bridge;
@@ -982,12 +809,12 @@
  *      slot's device status to be set.
  */
 void
-pcibr_driver_reg_callback(devfs_handle_t pconn_vhdl,
+pcibr_driver_reg_callback(vertex_hdl_t pconn_vhdl,
 			  int key1, int key2, int error)
 {
     pciio_info_t	 pciio_info;
     pcibr_info_t         pcibr_info;
-    devfs_handle_t	 pcibr_vhdl;
+    vertex_hdl_t	 pcibr_vhdl;
     pciio_slot_t	 slot;
     pcibr_soft_t	 pcibr_soft;
 
@@ -1033,12 +860,12 @@
  *      slot's device status to be set.
  */
 void
-pcibr_driver_unreg_callback(devfs_handle_t pconn_vhdl, 
+pcibr_driver_unreg_callback(vertex_hdl_t pconn_vhdl, 
                             int key1, int key2, int error)
 {
     pciio_info_t	 pciio_info;
     pcibr_info_t         pcibr_info;
-    devfs_handle_t	 pcibr_vhdl;
+    vertex_hdl_t	 pcibr_vhdl;
     pciio_slot_t	 slot;
     pcibr_soft_t	 pcibr_soft;
 
@@ -1084,14 +911,14 @@
  * depends on hwgraph separator == '/'
  */
 int
-pcibr_bus_cnvlink(devfs_handle_t f_c)
+pcibr_bus_cnvlink(vertex_hdl_t f_c)
 {
         char dst[MAXDEVNAME];
 	char *dp = dst;
         char *cp, *xp;
         int widgetnum;
         char pcibus[8];
-	devfs_handle_t nvtx, svtx;
+	vertex_hdl_t nvtx, svtx;
 	int rv;
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, f_c, "pcibr_bus_cnvlink\n"));
@@ -1105,7 +932,7 @@
 	xp = strstr(dst, "/"EDGE_LBL_XTALK"/");
 	if (xp == NULL)
 		return 0;
-	widgetnum = atoi(xp+7);
+	widgetnum = simple_strtoul(xp+7, NULL, 0);
 	if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F)
 		return 0;
 
@@ -1145,11 +972,11 @@
  */
 /*ARGSUSED */
 int
-pcibr_attach(devfs_handle_t xconn_vhdl)
+pcibr_attach(vertex_hdl_t xconn_vhdl)
 {
     /* REFERENCED */
     graph_error_t           rc;
-    devfs_handle_t            pcibr_vhdl;
+    vertex_hdl_t            pcibr_vhdl;
     bridge_t               *bridge;
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, xconn_vhdl, "pcibr_attach\n"));
@@ -1180,11 +1007,11 @@
 
 /*ARGSUSED */
 int
-pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, 
-	      devfs_handle_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp)
+pcibr_attach2(vertex_hdl_t xconn_vhdl, bridge_t *bridge, 
+	      vertex_hdl_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp)
 {
     /* REFERENCED */
-    devfs_handle_t            ctlr_vhdl;
+    vertex_hdl_t            ctlr_vhdl;
     bridgereg_t             id;
     int                     rev;
     pcibr_soft_t            pcibr_soft;
@@ -1193,7 +1020,7 @@
     xtalk_intr_t            xtalk_intr;
     int                     slot;
     int                     ibit;
-    devfs_handle_t            noslot_conn;
+    vertex_hdl_t            noslot_conn;
     char                    devnm[MAXDEVNAME], *s;
     pcibr_hints_t           pcibr_hints;
     uint64_t              int_enable;
@@ -1209,23 +1036,15 @@
     nasid_t		    nasid;
     int	                    iobrick_type_get_nasid(nasid_t nasid);
     int                     iobrick_module_get_nasid(nasid_t nasid);
-    extern unsigned char    Is_pic_on_this_nasid[512];
-
-
-    async_attach_t          aa = NULL;
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,
 	        "pcibr_attach2: bridge=0x%p, busnum=%d\n", bridge, busnum));
 
-    aa = async_attach_get_info(xconn_vhdl);
-
     ctlr_vhdl = NULL;
-    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER,
-                0, DEVFS_FL_AUTO_DEVNUM,
-                0, 0,
-                S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                &pcibr_fops, NULL);
-
+    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER, 0, 
+                DEVFS_FL_AUTO_DEVNUM, 0, 0,
+		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, 
+		(struct file_operations *)&pcibr_fops, (void *)pcibr_vhdl);
     ASSERT(ctlr_vhdl != NULL);
 
     /*
@@ -1261,13 +1080,7 @@
     pcibr_soft->bs_min_slot = 0;		/* lowest possible slot# */
     pcibr_soft->bs_max_slot = 7;		/* highest possible slot# */
     pcibr_soft->bs_busnum = busnum;
-    if (is_xbridge(bridge)) {
-	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_XBRIDGE;
-    } else if (is_pic(bridge)) {
-	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC;
-    } else {
-	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_BRIDGE;
-    }
+    pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC;
     switch(pcibr_soft->bs_bridge_type) {
     case PCIBR_BRIDGETYPE_BRIDGE:
 	pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES;
@@ -1367,10 +1180,6 @@
 
     nasid = NASID_GET(bridge);
 
-    /* set whether it is a PIC or not */
-    Is_pic_on_this_nasid[nasid] = (IS_PIC_SOFT(pcibr_soft)) ? 1 : 0;
-
-
     if ((pcibr_soft->bs_bricktype = iobrick_type_get_nasid(nasid)) < 0)
 	printk(KERN_WARNING "0x%p: Unknown bricktype : 0x%x\n", (void *)xconn_vhdl,
 				(unsigned int)pcibr_soft->bs_bricktype);
@@ -1380,11 +1189,27 @@
     if (pcibr_soft->bs_bricktype > 0) {
 	switch (pcibr_soft->bs_bricktype) {
 	case MODULE_PXBRICK:
+	case MODULE_IXBRICK:
 	    pcibr_soft->bs_first_slot = 0;
 	    pcibr_soft->bs_last_slot = 1;
 	    pcibr_soft->bs_last_reset = 1;
+
+	    /* If Bus 1 has IO9 then there are 4 devices in that bus.  Note
+	     * we figure this out from klconfig since the kernel has yet to 
+	     * probe
+	     */
+	    if (pcibr_widget_to_bus(pcibr_vhdl) == 1) {
+		lboard_t *brd = (lboard_t *)KL_CONFIG_INFO(nasid);
+
+		while (brd) {
+		    if (brd->brd_flags & LOCAL_MASTER_IO6) {
+			pcibr_soft->bs_last_slot = 3;
+			pcibr_soft->bs_last_reset = 3;
+		    }
+		    brd = KLCF_NEXT(brd);
+		}
+	    }
 	    break;
-	case MODULE_PEBRICK:
 	case MODULE_PBRICK:
             pcibr_soft->bs_first_slot = 1;
             pcibr_soft->bs_last_slot = 2;
@@ -1559,11 +1384,6 @@
 	int                     entry;
 	cnodeid_t		cnodeid;
 	nasid_t			nasid;
-#ifdef PIC_LATER
-	char		       *node_val;
-	devfs_handle_t		node_vhdl;
-	char			vname[MAXDEVNAME];
-#endif
 
 	/* Set the Bridge's 32-bit PCI to XTalk
 	 * Direct Map register to the most useful
@@ -1582,30 +1402,6 @@
 	 */
 
 	cnodeid = 0;  /* default node id */
-	/*
-	 * Determine the base address node id to be used for all 32-bit
-	 * Direct Mapping I/O. The default is node 0, but this can be changed
-	 * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE
-	 * attribute in the irix.sm config file. A device driver can obtain
-	 * this node value via a call to pcibr_get_dmatrans_node().
-	 */
-#ifdef PIC_LATER
-// This probably needs to be addressed - pfg
-	node_val = device_admin_info_get(pcibr_vhdl, ADMIN_LBL_DMATRANS_NODE);
-	if (node_val != NULL) {
-	    node_vhdl = hwgraph_path_to_vertex(node_val);
-	    if (node_vhdl != GRAPH_VERTEX_NONE) {
-		cnodeid = nodevertex_to_cnodeid(node_vhdl);
-	    }
-	    if ((node_vhdl == GRAPH_VERTEX_NONE) || (cnodeid == CNODEID_NONE)) {
-		cnodeid = 0;
-		vertex_to_name(pcibr_vhdl, vname, sizeof(vname));
-		printk(KERN_WARNING "Invalid hwgraph node path specified:\n"
-			"    DEVICE_ADMIN: %s %s=%s\n",
-			vname, ADMIN_LBL_DMATRANS_NODE, node_val);
-	    }
-	}
-#endif	/* PIC_LATER */
 	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
 	paddr = NODE_OFFSET(nasid) + 0;
 
@@ -1697,18 +1493,21 @@
 	/* we always have 128 ATEs (512 for Xbridge) inside the chip
 	 * even if disabled for debugging.
 	 */
-	pcibr_soft->bs_int_ate_map = rmallocmap(pcibr_soft->bs_int_ate_size);
-	pcibr_ate_free(pcibr_soft, 0, pcibr_soft->bs_int_ate_size);
+	pcibr_soft->bs_int_ate_resource.start = 0;
+	pcibr_soft->bs_int_ate_resource.end = pcibr_soft->bs_int_ate_size - 1;
 
 	if (num_entries > pcibr_soft->bs_int_ate_size) {
 #if PCIBR_ATE_NOTBOTH			/* for debug -- forces us to use external ates */
 	    printk("pcibr_attach: disabling internal ATEs.\n");
 	    pcibr_ate_alloc(pcibr_soft, pcibr_soft->bs_int_ate_size);
 #endif
-	    pcibr_soft->bs_ext_ate_map = rmallocmap(num_entries);
-	    pcibr_ate_free(pcibr_soft, pcibr_soft->bs_int_ate_size,
-			   num_entries - pcibr_soft->bs_int_ate_size);
+	   pcibr_soft->bs_ext_ate_resource.start = pcibr_soft->bs_int_ate_size;
+	   pcibr_soft->bs_ext_ate_resource.end = num_entries;
 	}
+
+        pcibr_soft->bs_allocated_ate_res = (void *) kmalloc(pcibr_soft->bs_int_ate_size * sizeof(unsigned long), GFP_KERNEL);
+	memset(pcibr_soft->bs_allocated_ate_res, 0x0, pcibr_soft->bs_int_ate_size * sizeof(unsigned long));
+
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, pcibr_vhdl,
 		    "pcibr_attach2: %d ATEs, %d internal & %d external\n",
 		    num_entries ? num_entries : pcibr_soft->bs_int_ate_size,
@@ -1763,6 +1562,13 @@
      */
 
     xtalk_intr = xtalk_intr_alloc(xconn_vhdl, (device_desc_t)0, pcibr_vhdl);
+	{
+		int irq = ((hub_intr_t)xtalk_intr)->i_bit;
+		int cpu = ((hub_intr_t)xtalk_intr)->i_cpuid;
+
+		intr_unreserve_level(cpu, irq);
+		((hub_intr_t)xtalk_intr)->i_bit = SGI_PCIBR_ERROR;
+	}
     ASSERT(xtalk_intr != NULL);
 
     pcibr_soft->bsi_err_intr = xtalk_intr;
@@ -1778,12 +1584,8 @@
     xtalk_intr_connect(xtalk_intr, (intr_func_t) pcibr_error_intr_handler,
 		(intr_arg_t) pcibr_soft, (xtalk_intr_setfunc_t)pcibr_setwidint, (void *)bridge);
 
-#ifdef BUS_INT_WAR_NOT_YET
-    request_irq(CPU_VECTOR_TO_IRQ(((hub_intr_t)xtalk_intr)->i_cpuid,
-			((hub_intr_t)xtalk_intr)->i_bit),
-				(intr_func_t)pcibr_error_intr_handler, 0, "PCIBR error",
+    request_irq(SGI_PCIBR_ERROR, (void *)pcibr_error_intr_handler, SA_SHIRQ, "PCIBR error",
 					(intr_arg_t) pcibr_soft);
-#endif
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_vhdl,
 		"pcibr_setwidint: b_wid_int_upper=0x%x, b_wid_int_lower=0x%x\n",
@@ -1801,18 +1603,16 @@
     if (IS_PIC_SOFT(pcibr_soft)) {
 	int_enable_64 = bridge->p_int_enable_64 | BRIDGE_ISR_ERRORS;
         int_enable = (uint64_t)int_enable_64;
+#ifdef PFG_TEST
+	int_enable = (uint64_t)0x7ffffeff7ffffeff;
+#endif
     } else {
 	int_enable_32 = bridge->b_int_enable | (BRIDGE_ISR_ERRORS & 0xffffffff);
 	int_enable = ((uint64_t)int_enable_32 & 0xffffffff);
-    }
-#ifdef BUS_INT_WAR_NOT_YET
-    {
-	extern void sn_add_polled_interrupt(int irq, int interval);
-
-        sn_add_polled_interrupt(CPU_VECTOR_TO_IRQ(((hub_intr_t)xtalk_intr)->i_cpuid,
-				((hub_intr_t)xtalk_intr)->i_bit), 20000);
-    }
+#ifdef PFG_TEST
+	int_enable = (uint64_t)0x7ffffeff;
 #endif
+    }
 
 
 #if BRIDGE_ERROR_INTR_WAR
@@ -1849,24 +1649,6 @@
     }
 #endif
 
-#ifdef BRIDGE_B_DATACORR_WAR
-
-    /* WAR panic for Rev B silent data corruption.
-     * PIOERR turned off here because there is a problem
-     * with not re-arming it in pcibr_error_intr_handler.
-     * We don't get LLP error interrupts if we don't
-     * re-arm PIOERR interrupts! Just disable them here
-     */
-
-    if (pcibr_soft->bs_rev_num == BRIDGE_PART_REV_B) {
-	int_enable |= BRIDGE_IMR_LLP_REC_CBERR;
-	int_enable &= ~BRIDGE_ISR_PCIBUS_PIOERR;
-
-	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,
-		    "Turning on LLP_REC_CBERR for Rev B Bridge.\n"));
-    }
-#endif
-
     /* PIC BRINGUP WAR (PV# 856864 & 856865): allow the tnums that are
      * locked out to be freed up sooner (by timing out) so that the
      * read tnums are never completely used up.
@@ -1918,16 +1700,12 @@
     if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B)
 	pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH;
     else if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev))
+		(BRIDGE_WIDGET_PART_NUM << 4))
 	pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH;
 
-    /* WRITE_GATHER:
-     * Disabled up to but not including the
-     * rev number in pcibr_wg_enable_rev. There
-     * is no "WAR range" as with prefetch.
-     */
+    /* WRITE_GATHER: Disabled */
     if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev))
+		(BRIDGE_WIDGET_PART_NUM << 4))
 	pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER;
 
     /* PIC only supports 64-bit direct mapping in PCI-X mode.  Since
@@ -1940,10 +1718,10 @@
 
     {
 
-    pciio_win_map_t         win_map_p;
     iopaddr_t               prom_base_addr = pcibr_soft->bs_xid << 24;
     int                     prom_base_size = 0x1000000;
-    iopaddr_t               prom_base_limit = prom_base_addr + prom_base_size; 
+    int			    status;
+    struct resource	    *res;
 
     /* Allocate resource maps based on bus page size; for I/O and memory
      * space, free all pages except those in the base area and in the
@@ -1953,35 +1731,38 @@
      * the widget number and s is the device register offset for the slot.
      */
 
-    win_map_p = &pcibr_soft->bs_io_win_map;
-    pciio_device_win_map_new(win_map_p,
-			     PCIBR_BUS_IO_MAX + 1,
-			     PCIBR_BUS_IO_PAGE);
-    pciio_device_win_populate(win_map_p,
-			      PCIBR_BUS_IO_BASE,
-			      prom_base_addr - PCIBR_BUS_IO_BASE);
-    pciio_device_win_populate(win_map_p,
-			      prom_base_limit,
-			      (PCIBR_BUS_IO_MAX + 1) - prom_base_limit);
-
-    win_map_p = &pcibr_soft->bs_swin_map;
-    pciio_device_win_map_new(win_map_p,
-			     PCIBR_BUS_SWIN_MAX + 1,
-			     PCIBR_BUS_SWIN_PAGE);
-    pciio_device_win_populate(win_map_p,
-			      PCIBR_BUS_SWIN_BASE,
-			      (PCIBR_BUS_SWIN_MAX + 1) - PCIBR_BUS_SWIN_PAGE);
-
-    win_map_p = &pcibr_soft->bs_mem_win_map;
-    pciio_device_win_map_new(win_map_p,
-			     PCIBR_BUS_MEM_MAX + 1,
-			     PCIBR_BUS_MEM_PAGE);
-    pciio_device_win_populate(win_map_p,
-			      PCIBR_BUS_MEM_BASE,
-			      prom_base_addr - PCIBR_BUS_MEM_BASE);
-    pciio_device_win_populate(win_map_p,
-			      prom_base_limit,
-			      (PCIBR_BUS_MEM_MAX + 1) - prom_base_limit);
+    /* Setup the Bus's PCI IO Root Resource. */
+    pcibr_soft->bs_io_win_root_resource.start = PCIBR_BUS_IO_BASE;
+    pcibr_soft->bs_io_win_root_resource.end = 0xffffffff;
+    res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP);
+    if (!res)
+	panic("PCIBR:Unable to allocate resource structure\n");
+
+    /* Block off the range used by PROM. */
+    res->start = prom_base_addr;
+    res->end = prom_base_addr + (prom_base_size - 1);
+    status = request_resource(&pcibr_soft->bs_io_win_root_resource, res);
+    if (status)
+	panic("PCIBR:Unable to request_resource()\n");
+
+    /* Setup the Small Window Root Resource */
+    pcibr_soft->bs_swin_root_resource.start = _PAGESZ;
+    pcibr_soft->bs_swin_root_resource.end = 0x000FFFFF;
+
+    /* Setup the Bus's PCI Memory Root Resource */
+    pcibr_soft->bs_mem_win_root_resource.start = 0x200000;
+    pcibr_soft->bs_mem_win_root_resource.end = 0xffffffff;
+    res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP);
+    if (!res)
+        panic("PCIBR:Unable to allocate resource structure\n");
+
+    /* Block off the range used by PROM. */
+    res->start = prom_base_addr;
+    res->end = prom_base_addr + (prom_base_size - 1);;
+    status = request_resource(&pcibr_soft->bs_mem_win_root_resource, res);
+    if (status)
+        panic("PCIBR:Unable to request_resource()\n");
+
     }
 
     /* build "no-slot" connection point
@@ -2064,7 +1845,23 @@
      */
     if (pcibr_soft->bs_bricktype > 0) {
 	switch (pcibr_soft->bs_bricktype) {
+	case MODULE_PBRICK:
+		do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
+		do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
+		break;
+	case MODULE_IBRICK:
+	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
+		if (pcibr_soft->bs_xid == 0xe) {
+			do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
+			do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
+		}
+		else {
+		    	/* allocate one RRB for the serial port */
+			do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 1);
+		}
+		break;
 	case MODULE_PXBRICK:
+	case MODULE_IXBRICK:
 		/* 
 		 * If the IO9 is in the PXBrick (bus1, slot1) allocate
                  * RRBs to all the devices
@@ -2080,23 +1877,6 @@
 			do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 8);
 			do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
 		}
-
-		break;
-	case MODULE_PEBRICK:
-	case MODULE_PBRICK:
-		do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
-		do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
-		break;
-	case MODULE_IBRICK:
-	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
-		if (pcibr_soft->bs_xid == 0xe) {
-			do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
-			do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
-		}
-		else {
-		    	/* allocate one RRB for the serial port */
-			do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 1);
-		}
 		break;
 	} /* switch */
     }
@@ -2113,78 +1893,8 @@
 	/* Call the device attach */
 	(void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0);
 
-#ifdef PIC_LATER
-#if (defined(USS302_TIMEOUT_WAR))
-    /*
-     * If this bridge holds a Lucent USS-302 or USS-312 pci/usb controller,
-     * increase the Bridge PCI retry backoff interval.  This part seems
-     * to go away for long periods of time if a DAC appears on the bus during
-     * a read command that is being retried.
-     */
-
-{
-    ii_ixtt_u_t ixtt;
-
-    for (slot = pcibr_soft->bs_min_slot; 
-				slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
-	if (pcibr_soft->bs_slot[slot].bss_vendor_id ==
-					LUCENT_USBHC_VENDOR_ID_NUM &&
-	    (pcibr_soft->bs_slot[slot].bss_device_id ==
-					LUCENT_USBHC302_DEVICE_ID_NUM ||
-	     pcibr_soft->bs_slot[slot].bss_device_id ==
-					LUCENT_USBHC312_DEVICE_ID_NUM)) {
-	    printk(KERN_NOTICE
-		    "pcibr_attach: %x Bus holds a usb part - setting"
-		    "bridge PCI_RETRY_HLD to %d\n",
-		    pcibr_vhdl, USS302_BRIDGE_TIMEOUT_HLD);
-
-	    bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_HLD_MASK;
-	    bridge->b_bus_timeout |=
-			BRIDGE_BUS_PCI_RETRY_HLD(USS302_BRIDGE_TIMEOUT_HLD);
-
-	    /*
-	     * Have to consider the read response timer in the hub II as well
-	     */
-
-	    hubii_ixtt_get(xconn_vhdl, &ixtt);
-
-	    /*
-	     * bump rrsp_ps to allow at least 1ms for read
- 	     * responses from this widget
-	     */
-
-	    ixtt.ii_ixtt_fld_s.i_rrsp_ps = 20000;
-	    hubii_ixtt_set(xconn_vhdl, &ixtt);
-
-	    /*
-	     * print the current setting
-	     */
-
-	    hubii_ixtt_get(xconn_vhdl, &ixtt);
-	    printk( "Setting hub ixtt.rrsp_ps field to 0x%x\n",
-		    ixtt.ii_ixtt_fld_s.i_rrsp_ps);
-
-	    break;	/* only need to do it once */
-	}
-    }
-}
-#endif	/* (defined(USS302_TIMEOUT_WAR)) */
-#else
-	FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n");
-#endif	/* PIC_LATER */
-
-    if (aa)
-	    async_attach_add_info(noslot_conn, aa);
-
     pciio_device_attach(noslot_conn, (int)0);
 
-    /* 
-     * Tear down pointer to async attach info -- async threads for
-     * bridge's descendants may be running but the bridge's work is done.
-     */
-    if (aa)
-	    async_attach_del_info(xconn_vhdl);
-
     return 0;
 }
 
@@ -2195,10 +1905,10 @@
  */
 
 int
-pcibr_detach(devfs_handle_t xconn)
+pcibr_detach(vertex_hdl_t xconn)
 {
     pciio_slot_t	slot;
-    devfs_handle_t	pcibr_vhdl;
+    vertex_hdl_t	pcibr_vhdl;
     pcibr_soft_t	pcibr_soft;
     bridge_t		*bridge;
     unsigned             s;
@@ -2235,15 +1945,6 @@
     spin_lock_destroy(&pcibr_soft->bs_lock);
     kfree(pcibr_soft->bs_name);
     
-    /* Error handler gets unregistered when the widget info is 
-     * cleaned 
-     */
-    /* Free the soft ATE maps */
-    if (pcibr_soft->bs_int_ate_map)
-	rmfreemap(pcibr_soft->bs_int_ate_map);
-    if (pcibr_soft->bs_ext_ate_map)
-	rmfreemap(pcibr_soft->bs_ext_ate_map);
-
     /* Disconnect the error interrupt and free the xtalk resources 
      * associated with it.
      */
@@ -2265,9 +1966,9 @@
 }
 
 int
-pcibr_asic_rev(devfs_handle_t pconn_vhdl)
+pcibr_asic_rev(vertex_hdl_t pconn_vhdl)
 {
-    devfs_handle_t          pcibr_vhdl;
+    vertex_hdl_t          pcibr_vhdl;
     int                     tmp_vhdl;
     arbitrary_info_t        ainfo;
 
@@ -2294,7 +1995,7 @@
 }
 
 int
-pcibr_write_gather_flush(devfs_handle_t pconn_vhdl)
+pcibr_write_gather_flush(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t  pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
@@ -2309,7 +2010,7 @@
  */
 
 static iopaddr_t
-pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl,
+pcibr_addr_pci_to_xio(vertex_hdl_t pconn_vhdl,
 		      pciio_slot_t slot,
 		      pciio_space_t space,
 		      iopaddr_t pci_addr,
@@ -2323,6 +2024,8 @@
 
     unsigned                bar;	/* which BASE reg on device is decoding */
     iopaddr_t               xio_addr = XIO_NOWHERE;
+    iopaddr_t               base;	/* base of devio(x) mapped area on PCI */
+    iopaddr_t               limit;	/* base of devio(x) mapped area on PCI */
 
     pciio_space_t           wspace;	/* which space device is decoding */
     iopaddr_t               wbase;	/* base of device decode on PCI */
@@ -2533,8 +2236,6 @@
 		PCIBR_DEBUG((PCIBR_DEBUG_DEVREG, pconn_vhdl, 
 			    "pcibr_addr_pci_to_xio: Device(%d): %x\n",
 			    win, devreg, device_bits));
-#else
-	        printk("pcibr_addr_pci_to_xio: Device(%d): %x\n", win, devreg);
 #endif
 	    }
 	    pcibr_soft->bs_slot[win].bss_devio.bssd_space = space;
@@ -2620,18 +2321,46 @@
 	 */
     case PCIIO_SPACE_MEM:		/* "mem space" */
     case PCIIO_SPACE_MEM32:		/* "mem, use 32-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM32_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE;
+	if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 0)) {	/* PIC bus 0 */
+		base = PICBRIDGE0_PCI_MEM32_BASE;
+		limit = PICBRIDGE0_PCI_MEM32_LIMIT;
+	} else if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 1)) {	/* PIC bus 1 */
+		base = PICBRIDGE1_PCI_MEM32_BASE;
+		limit = PICBRIDGE1_PCI_MEM32_LIMIT;
+	} else {					/* Bridge/Xbridge */
+		base = BRIDGE_PCI_MEM32_BASE;
+		limit = BRIDGE_PCI_MEM32_LIMIT;
+	}
+
+	if ((pci_addr + base + req_size - 1) <= limit)
+	    xio_addr = pci_addr + base;
 	break;
 
     case PCIIO_SPACE_MEM64:		/* "mem, use 64-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM64_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE;
+	if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 0)) {	/* PIC bus 0 */
+		base = PICBRIDGE0_PCI_MEM64_BASE;
+		limit = PICBRIDGE0_PCI_MEM64_LIMIT;
+	} else if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 1)) {	/* PIC bus 1 */
+		base = PICBRIDGE1_PCI_MEM64_BASE;
+		limit = PICBRIDGE1_PCI_MEM64_LIMIT;
+	} else {					/* Bridge/Xbridge */
+		base = BRIDGE_PCI_MEM64_BASE;
+		limit = BRIDGE_PCI_MEM64_LIMIT;
+	}
+
+	if ((pci_addr + base + req_size - 1) <= limit)
+	    xio_addr = pci_addr + base;
 	break;
 
     case PCIIO_SPACE_IO:		/* "i/o space" */
+	/*
+	 * PIC bridges do not support big-window aliases into PCI I/O space
+	 */
+	if (IS_PIC_SOFT(pcibr_soft)) {
+		xio_addr = XIO_NOWHERE;
+		break;
+	}
+
 	/* Bridge Hardware Bug WAR #482741:
 	 * The 4G area that maps directly from
 	 * XIO space to PCI I/O space is busted
@@ -2725,7 +2454,7 @@
 
 /*ARGSUSED6 */
 pcibr_piomap_t
-pcibr_piomap_alloc(devfs_handle_t pconn_vhdl,
+pcibr_piomap_alloc(vertex_hdl_t pconn_vhdl,
 		   device_desc_t dev_desc,
 		   pciio_space_t space,
 		   iopaddr_t pci_addr,
@@ -2737,7 +2466,7 @@
     pciio_info_t            pciio_info = &pcibr_info->f_c;
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     pcibr_piomap_t         *mapptr;
     pcibr_piomap_t          maplist;
@@ -2867,7 +2596,7 @@
 
 /*ARGSUSED */
 caddr_t
-pcibr_piotrans_addr(devfs_handle_t pconn_vhdl,
+pcibr_piotrans_addr(vertex_hdl_t pconn_vhdl,
 		    device_desc_t dev_desc,
 		    pciio_space_t space,
 		    iopaddr_t pci_addr,
@@ -2877,7 +2606,7 @@
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     iopaddr_t               xio_addr;
     caddr_t		    addr;
@@ -2908,7 +2637,7 @@
 
 /*ARGSUSED */
 iopaddr_t
-pcibr_piospace_alloc(devfs_handle_t pconn_vhdl,
+pcibr_piospace_alloc(vertex_hdl_t pconn_vhdl,
 		     device_desc_t dev_desc,
 		     pciio_space_t space,
 		     size_t req_size,
@@ -3010,7 +2739,7 @@
 
 /*ARGSUSED */
 void
-pcibr_piospace_free(devfs_handle_t pconn_vhdl,
+pcibr_piospace_free(vertex_hdl_t pconn_vhdl,
 		    pciio_space_t space,
 		    iopaddr_t pciaddr,
 		    size_t req_size)
@@ -3161,14 +2890,14 @@
 
 /*ARGSUSED */
 pcibr_dmamap_t
-pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl,
+pcibr_dmamap_alloc(vertex_hdl_t pconn_vhdl,
 		   device_desc_t dev_desc,
 		   size_t req_size_max,
 		   unsigned flags)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
     pciio_slot_t            slot;
     xwidgetnum_t            xio_port;
 
@@ -3216,7 +2945,7 @@
 
 	    /* Device is capable of A64 operations,
 	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
+	     * consistent with any previous DMA
 	     * mappings using shared resources.
 	     */
 
@@ -3266,7 +2995,7 @@
 	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) {
 	    /* User desires DIRECT A32 operations,
 	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
+	     * consistent with any previous DMA
 	     * mappings using shared resources.
 	     * Mapping calls may fail if target
 	     * is outside the direct32 range.
@@ -3454,6 +3183,29 @@
     iopaddr_t               pci_addr;
     pciio_slot_t            slot;
 
+    if (IS_PIC_BUSNUM_SOFT(soft, 0)) {
+    	if ((xio_addr >= PICBRIDGE0_PCI_MEM32_BASE) &&
+	    (xio_lim <= PICBRIDGE0_PCI_MEM32_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE0_PCI_MEM32_BASE;
+	    return pci_addr;
+    	}
+    	if ((xio_addr >= PICBRIDGE0_PCI_MEM64_BASE) &&
+	    (xio_lim <= PICBRIDGE0_PCI_MEM64_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE0_PCI_MEM64_BASE;
+	    return pci_addr;
+    	}
+    } else if (IS_PIC_BUSNUM_SOFT(soft, 1)) {
+    	if ((xio_addr >= PICBRIDGE1_PCI_MEM32_BASE) &&
+	    (xio_lim <= PICBRIDGE1_PCI_MEM32_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE1_PCI_MEM32_BASE;
+	    return pci_addr;
+    	}
+    	if ((xio_addr >= PICBRIDGE1_PCI_MEM64_BASE) &&
+	    (xio_lim <= PICBRIDGE1_PCI_MEM64_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE1_PCI_MEM64_BASE;
+	    return pci_addr;
+    	}
+    } else {
     if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) &&
 	(xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) {
 	pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE;
@@ -3464,6 +3216,7 @@
 	pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE;
 	return pci_addr;
     }
+    }
     for (slot = soft->bs_min_slot; slot < PCIBR_NUM_SLOTS(soft); ++slot)
 	if ((xio_addr >= PCIBR_BRIDGE_DEVIO(soft, slot)) &&
 	    (xio_lim < PCIBR_BRIDGE_DEVIO(soft, slot + 1))) {
@@ -3505,7 +3258,7 @@
     } else
 	xio_port = pcibr_dmamap->bd_xio_port;
 
-    /* If this DMA is to an addres that
+    /* If this DMA is to an address that
      * refers back to this Bridge chip,
      * reduce it back to the correct
      * PCI MEM address.
@@ -3644,243 +3397,6 @@
 }
 
 /*ARGSUSED */
-alenlist_t
-pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap,
-		  alenlist_t palenlist,
-		  unsigned flags)
-{
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge=NULL;
-
-    unsigned                al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-    int                     inplace = flags & PCIIO_INPLACE;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist;
-    size_t                  length;
-    iopaddr_t               offset;
-    unsigned                direct64;
-    int                     ate_index = 0;
-    int                     ate_count = 0;
-    int                     ate_total = 0;
-    bridge_ate_p            ate_ptr = (bridge_ate_p)0;
-    bridge_ate_t            ate_proto = (bridge_ate_t)0;
-    bridge_ate_t            ate_prev;
-    bridge_ate_t            ate;
-    alenaddr_t              xio_addr;
-    xwidgetnum_t            xio_port;
-    iopaddr_t               pci_addr;
-    alenaddr_t              new_addr;
-    unsigned                cmd_regs[8];
-    unsigned                s = 0;
-
-#if PCIBR_FREEZE_TIME
-    unsigned                freeze_time;
-#endif
-    int			    ate_freeze_done = 0;	/* To pair ATE_THAW
-							 * with an ATE_FREEZE
-							 */
-
-    pcibr_soft = pcibr_dmamap->bd_soft;
-
-    xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist,
-				       flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist) {
-        PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                    "pcibr_dmamap_list: xtalk_dmamap_list() failed, "
-		    "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-	goto fail;
-    }
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist) {
-	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-			"pcibr_dmamap_list: alenlist_create() failed, "
-			"pcibr_dmamap=0x%lx\n", (unsigned long)pcibr_dmamap));
-	    goto fail;
-	}
-    }
-
-    direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64;
-    if (!direct64) {
-	bridge = pcibr_soft->bs_base;
-	ate_ptr = pcibr_dmamap->bd_ate_ptr;
-	ate_index = pcibr_dmamap->bd_ate_index;
-	ate_proto = pcibr_dmamap->bd_ate_proto;
-	ATE_FREEZE();
-	ate_freeze_done = 1;	/* Remember that we need to do an ATE_THAW */
-    }
-    pci_addr = pcibr_dmamap->bd_pci_addr;
-
-    ate_prev = 0;			/* matches no valid ATEs */
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &length, al_flags)) {
-	if (XIO_PACKED(xio_addr)) {
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_dmamap->bd_xio_port;
-
-	if (xio_port == pcibr_soft->bs_xid) {
-	    new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length);
-	    if (new_addr == PCI_NOWHERE) {
-                PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                            "pcibr_dmamap_list: pcibr_addr_xio_to_pci failed, "
-                            "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-		goto fail;
-	    }
-	} else if (direct64) {
-	    new_addr = pci_addr | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-	    /* Bridge Hardware WAR #482836:
-	     * If the transfer is not cache aligned
-	     * and the Bridge Rev is <= B, force
-	     * prefetch to be off.
-	     */
-	    if (flags & PCIBR_NOPREFETCH)
-		new_addr &= ~PCI64_ATTR_PREF;
-
-	} else {
-	    /* calculate the ate value for
-	     * the first address. If it
-	     * matches the previous
-	     * ATE written (ie. we had
-	     * multiple blocks in the
-	     * same IOPG), then back up
-	     * and reuse that ATE.
-	     *
-	     * We are NOT going to
-	     * aggressively try to
-	     * reuse any other ATEs.
-	     */
-	    offset = IOPGOFF(xio_addr);
-	    ate = ate_proto
-		| (xio_port << ATE_TIDSHIFT)
-		| (xio_addr - offset);
-	    if (ate == ate_prev) {
-		PCIBR_DEBUG((PCIBR_DEBUG_ATE, pcibr_dmamap->bd_dev,
-			    "pcibr_dmamap_list: ATE share\n"));
-		ate_ptr--;
-		ate_index--;
-		pci_addr -= IOPGSIZE;
-	    }
-	    new_addr = pci_addr + offset;
-
-	    /* Fill in the hardware ATEs
-	     * that contain this block.
-	     */
-	    ate_count = IOPG(offset + length - 1) + 1;
-	    ate_total += ate_count;
-
-	    /* Ensure that this map contains enough ATE's */
-	    if (ate_total > pcibr_dmamap->bd_ate_count) {
-		PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, pcibr_dmamap->bd_dev,
-			     "pcibr_dmamap_list :\n"
-			     "\twanted xio_addr [0x%x..0x%x]\n"
-			     "\tate_total 0x%x bd_ate_count 0x%x\n"
-			     "\tATE's required > number allocated\n",
-			     xio_addr, xio_addr + length - 1,
-			     ate_total, pcibr_dmamap->bd_ate_count));
-		goto fail;
-	    }
-
-	    ATE_WRITE();
-
-	    ate_index += ate_count;
-	    ate_ptr += ate_count;
-
-	    ate_count <<= IOPFNSHIFT;
-	    ate += ate_count;
-	    pci_addr += ate_count;
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &new_addr, &length, al_flags)) {
-                PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                            "pcibr_dmamap_list: alenlist_replace() failed, "
-                            "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-
-		goto fail;
-	    }
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				new_addr, length, al_flags)) {
-                PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                            "pcibr_dmamap_list: alenlist_append() failed, "
-                            "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-		goto fail;
-	    }
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-
-
-    /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the
-     * changes that ATE_FREEZE has done to implement the external SSRAM
-     * bug workaround.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	if ( IS_PIC_SOFT(pcibr_soft) ) {
-		bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_GET32((&bridge->b_wid_tflush));
-		} else {
-			bridge->b_wid_tflush;
-		}
-	}
-    }
-    PCIBR_DEBUG((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-		"pcibr_dmamap_list: pcibr_dmamap=0x%x, pciio_alenlist=0x%x\n",
-		pcibr_dmamap, pciio_alenlist));
-
-    return pciio_alenlist;
-
-  fail:
-    /* There are various points of failure after doing an ATE_FREEZE
-     * We need to do an ATE_THAW. Otherwise the ATEs are locked forever.
-     * The decision to do an ATE_THAW needs to be based on whether a
-     * an ATE_FREEZE was done before.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	if ( IS_PIC_SOFT(pcibr_soft) ) {
-		bridge->b_wid_tflush;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_GET32((&bridge->b_wid_tflush));
-		} else {
-			bridge->b_wid_tflush;
-		}
-	}
-    }
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
-/*ARGSUSED */
 void
 pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap)
 {
@@ -3917,7 +3433,7 @@
 
 /*ARGSUSED */
 cnodeid_t
-pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl)
+pcibr_get_dmatrans_node(vertex_hdl_t pconn_vhdl)
 {
 
 	pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
@@ -3928,7 +3444,7 @@
 
 /*ARGSUSED */
 iopaddr_t
-pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl,
+pcibr_dmatrans_addr(vertex_hdl_t pconn_vhdl,
 		    device_desc_t dev_desc,
 		    paddr_t paddr,
 		    size_t req_size,
@@ -3936,7 +3452,7 @@
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
     pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
 
@@ -4149,213 +3665,6 @@
     return 0;
 }
 
-/*ARGSUSED */
-alenlist_t
-pcibr_dmatrans_list(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    alenlist_t palenlist,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
-    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
-    xwidgetnum_t            xio_port;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist = 0;
-
-    int                     inplace;
-    unsigned                direct64;
-    unsigned                al_flags;
-
-    iopaddr_t               xio_base;
-    alenaddr_t              xio_addr;
-    size_t                  xio_size;
-
-    size_t                  map_size;
-    iopaddr_t               pci_base;
-    alenaddr_t              pci_addr;
-
-    unsigned                relbits = 0;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-    inplace = flags & PCIIO_INPLACE;
-    direct64 = flags & PCIIO_DMA_A64;
-    al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-
-    if (direct64) {
-	map_size = 1ull << 48;
-	xio_base = 0;
-	pci_base = slotp->bss_d64_base;
-	if ((pci_base != PCIBR_D64_BASE_UNSET) &&
-	    (flags == slotp->bss_d64_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: DMA configuration conflict "
-			"for direct64, flags=0x%x\n", flags));
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D64_BITS;
-	    pci_base =
-		pcibr_flags_to_d64(flags, pcibr_soft);
-	}
-    } else {
-	xio_base = pcibr_soft->bs_dir_xbase;
-	map_size = 1ull << 31;
-	pci_base = slotp->bss_d32_base;
-	if ((pci_base != PCIBR_D32_BASE_UNSET) &&
-	    (flags == slotp->bss_d32_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: DMA configuration conflict "
-			"for direct32, flags=0x%x\n", flags));
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D32_BITS;
-	    pci_base = PCI32_DIRECT_BASE;
-	}
-    }
-
-    xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist,
-					 flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist) {
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: xtalk_dmatrans_list failed "
-			"xtalk_alenlist=0x%x\n", xtalk_alenlist));
-	goto fail;
-    }
-
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist) {
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: alenlist_create failed with "
-			" 0x%x\n", pciio_alenlist));
-	    goto fail;
-	}
-    }
-
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &xio_size, al_flags)) {
-
-	/*
-	 * find which XIO port this goes to.
-	 */
-	if (XIO_PACKED(xio_addr)) {
-	    if (xio_addr == XIO_NOWHERE) {
-	        PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: xio_addr == XIO_NOWHERE\n"));
-		return 0;
-	    }
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_soft->bs_mxid;
-
-	/*
-	 * If this DMA comes back to us,
-	 * return the PCI MEM address on
-	 * which it would land, or NULL
-	 * if the target is something
-	 * on bridge other than PCI MEM.
-	 */
-	if (xio_port == pcibr_soft->bs_xid) {
-	    pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size);
-	    if (pci_addr == (alenaddr_t)NULL) {
-	        PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: pcibr_addr_xio_to_pci failed "
-			"xio_addr=0x%x, xio_size=0x%x\n", xio_addr, xio_size));
-		goto fail;
-	    }
-	} else if (direct64) {
-	    ASSERT(xio_port != 0);
-	    pci_addr = pci_base | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-	} else {
-	    iopaddr_t               offset = xio_addr - xio_base;
-	    iopaddr_t               endoff = xio_size + offset;
-
-	    if ((xio_size > map_size) ||
-		(xio_addr < xio_base) ||
-		(xio_port != pcibr_soft->bs_dir_xport) ||
-		(endoff > map_size)) {
-		PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			    "pcibr_dmatrans_list: xio_size > map_size fail\n"
-			    "xio_addr=0x%x, xio_size=0x%x. map_size=0x%x, "
-			    "xio_port=0x%x, endoff=0x%x\n", 
-			    xio_addr, xio_size, map_size, xio_port, endoff));
-		goto fail;
-	    }
-
-	    pci_addr = pci_base + (xio_addr - xio_base);
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &pci_addr, &xio_size, al_flags)) {
-		PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			    "pcibr_dmatrans_list: alenlist_replace failed\n"));
-		goto fail;
-	    }
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				pci_addr, xio_size, al_flags)) {
-		PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			    "pcibr_dmatrans_list: alenlist_append failed\n"));
-		goto fail;
-	    }
-	}
-    }
-
-    if (relbits) {
-	if (direct64) {
-	    slotp->bss_d64_flags = flags;
-	    slotp->bss_d64_base = pci_base;
-	} else {
-	    slotp->bss_d32_flags = flags;
-	    slotp->bss_d32_base = pci_base;
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-
-    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-		"pcibr_dmatrans_list: pciio_alenlist=0x%x\n",
-		 pciio_alenlist));
-
-    return pciio_alenlist;
-
-  fail:
-    if (relbits)
-	pcibr_release_device(pcibr_soft, pciio_slot, relbits);
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
 void
 pcibr_dmamap_drain(pcibr_dmamap_t map)
 {
@@ -4363,24 +3672,24 @@
 }
 
 void
-pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl,
+pcibr_dmaaddr_drain(vertex_hdl_t pconn_vhdl,
 		    paddr_t paddr,
 		    size_t bytes)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes);
 }
 
 void
-pcibr_dmalist_drain(devfs_handle_t pconn_vhdl,
+pcibr_dmalist_drain(vertex_hdl_t pconn_vhdl,
 		    alenlist_t list)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     xtalk_dmalist_drain(xconn_vhdl, list);
 }
@@ -4402,18 +3711,18 @@
  */
 /*ARGSUSED */
 void
-pcibr_provider_startup(devfs_handle_t pcibr)
+pcibr_provider_startup(vertex_hdl_t pcibr)
 {
 }
 
 /*ARGSUSED */
 void
-pcibr_provider_shutdown(devfs_handle_t pcibr)
+pcibr_provider_shutdown(vertex_hdl_t pcibr)
 {
 }
 
 int
-pcibr_reset(devfs_handle_t conn)
+pcibr_reset(vertex_hdl_t conn)
 {
 #ifdef PIC_LATER
     pciio_info_t            pciio_info = pciio_info_get(conn);
@@ -4484,7 +3793,7 @@
 }
 
 pciio_endian_t
-pcibr_endian_set(devfs_handle_t pconn_vhdl,
+pcibr_endian_set(vertex_hdl_t pconn_vhdl,
 		 pciio_endian_t device_end,
 		 pciio_endian_t desired_end)
 {
@@ -4629,7 +3938,7 @@
 }
 
 pciio_priority_t
-pcibr_priority_set(devfs_handle_t pconn_vhdl,
+pcibr_priority_set(vertex_hdl_t pconn_vhdl,
 		   pciio_priority_t device_prio)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
@@ -4653,7 +3962,7 @@
  * Returns 0 on failure, 1 on success
  */
 int
-pcibr_device_flags_set(devfs_handle_t pconn_vhdl,
+pcibr_device_flags_set(vertex_hdl_t pconn_vhdl,
 		       pcibr_device_flags_t flags)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
@@ -4792,10 +4101,8 @@
     (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
     (pciio_dmamap_free_f *) pcibr_dmamap_free,
     (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
-    (pciio_dmamap_list_f *) pcibr_dmamap_list,
     (pciio_dmamap_done_f *) pcibr_dmamap_done,
     (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
-    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
     (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
     (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
     (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
@@ -4814,23 +4121,16 @@
     (pciio_priority_set_f *) pcibr_priority_set,
     (pciio_config_get_f *) pcibr_config_get,
     (pciio_config_set_f *) pcibr_config_set,
-#ifdef PIC_LATER
-    (pciio_error_devenable_f *) pcibr_error_devenable,
-    (pciio_error_extract_f *) pcibr_error_extract,
-    (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,
-    (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,
-#else
     (pciio_error_devenable_f *) 0,
     (pciio_error_extract_f *) 0,
     (pciio_driver_reg_callback_f *) 0,
     (pciio_driver_unreg_callback_f *) 0,
-#endif	/* PIC_LATER */
     (pciio_device_unregister_f 	*) pcibr_device_unregister,
     (pciio_dma_enabled_f		*) pcibr_dma_enabled,
 };
 
 int
-pcibr_dma_enabled(devfs_handle_t pconn_vhdl)
+pcibr_dma_enabled(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
@@ -4857,7 +4157,7 @@
  * parameter 'format' is sent to the console.
  */
 void
-pcibr_debug(uint32_t type, devfs_handle_t vhdl, char *format, ...)
+pcibr_debug(uint32_t type, vertex_hdl_t vhdl, char *format, ...)
 {
     char hwpath[MAXDEVNAME] = "\0";
     char copy_of_hwpath[MAXDEVNAME];
@@ -4865,7 +4165,6 @@
     short widget = -1;
     short slot = -1;
     va_list ap;
-    char *strtok_r(char *string, const char *sepset, char **lasts);
 
     if (pcibr_debug_mask & type) {
         if (vhdl) {
@@ -4873,27 +4172,26 @@
                 char *cp;
 
                 if (strcmp(module, pcibr_debug_module)) {
-		    /* strtok_r() wipes out string, use a copy */
+		    /* use a copy */
                     (void)strcpy(copy_of_hwpath, hwpath);
                     cp = strstr(copy_of_hwpath, "/module/");
                     if (cp) {
-                        char *last = NULL;
                         cp += strlen("/module");
-                        module = strtok_r(cp, "/", &last);
+                        module = strsep(&cp, "/");
                     }
                 }
                 if (pcibr_debug_widget != -1) {
                     cp = strstr(hwpath, "/xtalk/");
                     if (cp) {
                         cp += strlen("/xtalk/");
-                        widget = atoi(cp);
+                        widget = simple_strtoul(cp, NULL, 0);
                     }
                 }
                 if (pcibr_debug_slot != -1) {
                     cp = strstr(hwpath, "/pci/");
                     if (cp) {
                         cp += strlen("/pci/");
-                        slot = atoi(cp);
+                        slot = simple_strtoul(cp, NULL, 0);
                     }
                 }
             }
@@ -4912,9 +4210,38 @@
 	     * Since we have a variable length argument list, we
 	     * need to call printk this way rather than directly
 	     */
-	    va_start(ap, format);
-	    printk(format, ap);
-	    va_end(ap);
+	    {
+		char buffer[500];
+
+		va_start(ap, format);
+		vsnprintf(buffer, 500, format, ap);
+		va_end(ap);
+		buffer[499] = (char)0;	/* just to be safe */
+		printk("%s", buffer);
+	    }
         }
     }
 }
+
+int
+isIO9(nasid_t nasid) {
+	lboard_t *brd = (lboard_t *)KL_CONFIG_INFO(nasid);
+
+	while (brd) {
+		if (brd->brd_flags & LOCAL_MASTER_IO6) {
+			return 1;
+		}
+		brd = KLCF_NEXT(brd);
+	}
+	/* if it's dual ported, check the peer also */
+	nasid = NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer;
+	if (nasid < 0) return 0;
+	brd = (lboard_t *)KL_CONFIG_INFO(nasid);
+	while (brd) {
+		if (brd->brd_flags & LOCAL_MASTER_IO6) {
+			return 1;
+		}
+		brd = KLCF_NEXT(brd);
+	}
+	return 0;
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,26 +27,11 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
 extern int	hubii_check_widget_disabled(nasid_t, int);
-#ifdef BRIDGE_B_DATACORR_WAR
-extern int              ql_bridge_rev_b_war(devfs_handle_t);
-extern int              bridge_rev_b_data_check_disable;
-char                   *rev_b_datacorr_warning =
-"***************************** WARNING! ******************************\n";
-char                   *rev_b_datacorr_mesg =
-"UNRECOVERABLE IO LINK ERROR. CONTACT SERVICE PROVIDER\n";
-#endif
+
 
 /* =====================================================================
  *    ERROR HANDLING
@@ -76,13 +61,9 @@
                                    BRIDGE_ISR_PCIBUS_PIOERR;
 #endif
 
-#if defined (PCIBR_LLP_CONTROL_WAR)
-int                     pcibr_llp_control_war_cnt;
-#endif				/* PCIBR_LLP_CONTROL_WAR */
+int                     pcibr_llp_control_war_cnt; /* PCIBR_LLP_CONTROL_WAR */
 
-/* FIXME: can these arrays be local ? */
-
-struct reg_values xio_cmd_pactyp[] =
+static struct reg_values xio_cmd_pactyp[] =
 {
     {0x0, "RdReq"},
     {0x1, "RdResp"},
@@ -103,7 +84,7 @@
     {0}
 };
 
-struct reg_desc   xio_cmd_bits[] =
+static struct reg_desc   xio_cmd_bits[] =
 {
     {WIDGET_DIDN, -28, "DIDN", "%x"},
     {WIDGET_SIDN, -24, "SIDN", "%x"},
@@ -120,58 +101,7 @@
 
 #define F(s,n)          { 1l<<(s),-(s), n }
 
-struct reg_desc         bridge_int_status_desc[] =
-{
-    F(45, "PCI_X_SPLIT_MES_PE"),/* PIC ONLY */
-    F(44, "PCI_X_SPLIT_EMES"),	/* PIC ONLY */
-    F(43, "PCI_X_SPLIT_TO"),	/* PIC ONLY */
-    F(42, "PCI_X_UNEX_COMP"),	/* PIC ONLY */
-    F(41, "INT_RAM_PERR"),	/* PIC ONLY */
-    F(40, "PCI_X_ARB_ERR"),	/* PIC ONLY */
-    F(39, "PCI_X_REQ_TOUT"),	/* PIC ONLY */
-    F(38, "PCI_X_TABORT"),	/* PIC ONLY */
-    F(37, "PCI_X_PERR"),	/* PIC ONLY */
-    F(36, "PCI_X_SERR"),	/* PIC ONLY */
-    F(35, "PCI_X_MRETRY"),	/* PIC ONLY */
-    F(34, "PCI_X_MTOUT"),	/* PIC ONLY */
-    F(33, "PCI_X_DA_PARITY"),	/* PIC ONLY */
-    F(32, "PCI_X_AD_PARITY"),	/* PIC ONLY */
-    F(31, "MULTI_ERR"),		/* BRIDGE ONLY */
-    F(30, "PMU_ESIZE_EFAULT"),
-    F(29, "UNEXPECTED_RESP"),
-    F(28, "BAD_XRESP_PACKET"),
-    F(27, "BAD_XREQ_PACKET"),
-    F(26, "RESP_XTALK_ERROR"),
-    F(25, "REQ_XTALK_ERROR"),
-    F(24, "INVALID_ADDRESS"),
-    F(23, "UNSUPPORTED_XOP"),
-    F(22, "XREQ_FIFO_OFLOW"),
-    F(21, "LLP_REC_SNERROR"),
-    F(20, "LLP_REC_CBERROR"),
-    F(19, "LLP_RCTY"),
-    F(18, "LLP_TX_RETRY"),
-    F(17, "LLP_TCTY"),
-    F(16, "SSRAM_PERR"),	/* BRIDGE ONLY */
-    F(15, "PCI_ABORT"),
-    F(14, "PCI_PARITY"),
-    F(13, "PCI_SERR"),
-    F(12, "PCI_PERR"),
-    F(11, "PCI_MASTER_TOUT"),
-    F(10, "PCI_RETRY_CNT"),
-    F(9, "XREAD_REQ_TOUT"),
-    F(8, "GIO_BENABLE_ERR"),	/* BRIDGE ONLY */
-    F(7, "INT7"),
-    F(6, "INT6"),
-    F(5, "INT5"),
-    F(4, "INT4"),
-    F(3, "INT3"),
-    F(2, "INT2"),
-    F(1, "INT1"),
-    F(0, "INT0"),
-    {0}
-};
-
-struct reg_values       space_v[] =
+static struct reg_values       space_v[] =
 {
     {PCIIO_SPACE_NONE, "none"},
     {PCIIO_SPACE_ROM, "ROM"},
@@ -189,13 +119,13 @@
     {PCIIO_SPACE_BAD, "BAD"},
     {0}
 };
-struct reg_desc         space_desc[] =
+static struct reg_desc         space_desc[] =
 {
     {0xFF, 0, "space", 0, space_v},
     {0}
 };
 #define	device_desc	device_bits
-struct reg_desc   device_bits[] =
+static struct reg_desc   device_bits[] =
 {
     {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"},
     {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"},
@@ -218,14 +148,14 @@
     {0}
 };
 
-void
+static void
 print_bridge_errcmd(uint32_t cmdword, char *errtype)
 {
     printk("\t    Bridge %s Error Command Word Register ", errtype);
     print_register(cmdword, xio_cmd_bits);
 }
 
-char             *pcibr_isr_errs[] =
+static char             *pcibr_isr_errs[] =
 {
     "", "", "", "", "", "", "", "",
     "08: GIO non-contiguous byte enable in crosstalk packet", /* BRIDGE ONLY */
@@ -279,7 +209,7 @@
 /*
  * display memory directory state
  */
-void
+static void
 pcibr_show_dir_state(paddr_t paddr, char *prefix)
 {
 #ifdef LATER
@@ -428,7 +358,6 @@
 		break;
 
 	    case BRIDGE_ISR_PAGE_FAULT:	    /* bit30	PMU_PAGE_FAULT */
-/*	    case BRIDGE_ISR_PMU_ESIZE_FAULT:   bit30	PMU_ESIZE_FAULT */
 		if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft))
 		    reg_desc = "Map Fault Address";
 		else
@@ -592,31 +521,9 @@
 		printk( "\t%s\n", pcibr_isr_errs[i]);
 	}
     }
-
-#if BRIDGE_ERROR_INTR_WAR
-    if (pcibr_soft->bs_rev_num == BRIDGE_PART_REV_A) {	/* known bridge bug */
-	/*
-	 * Should never receive interrupts for these reasons on Rev 1 bridge
-	 * as they are not enabled. Assert for it.
-	 */
-	ASSERT((int_status & (BRIDGE_IMR_PCI_MST_TIMEOUT |
-			      BRIDGE_ISR_RESP_XTLK_ERR |
-			      BRIDGE_ISR_LLP_TX_RETRY)) == 0);
-    }
-    if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_C) {	/* known bridge bug */
-	/*
-	 * This interrupt is turned off at init time. So, should never
-	 * see this interrupt.
-	 */
-	ASSERT((int_status & BRIDGE_ISR_BAD_XRESP_PKT) == 0);
-    }
-#endif
 }
 
-#define PCIBR_ERRINTR_GROUP(error)	\
-		(( error & (BRIDGE_IRR_PCI_GRP|BRIDGE_IRR_GIO_GRP)
-
-uint32_t
+static uint32_t
 pcibr_errintr_group(uint32_t error)
 {
     uint32_t              group = BRIDGE_IRR_MULTI_CLR;
@@ -741,15 +648,7 @@
     picreg_t                int_status_64;
     int			    number_bits;
     int                     i;
-
-    /* REFERENCED */
     uint64_t		    disable_errintr_mask = 0;
-#ifdef EHE_ENABLE
-    int 		    rv;
-    int 		    error_code = IOECODE_DMA | IOECODE_READ;
-    ioerror_mode_t 	    mode = MODE_DEVERROR;
-    ioerror_t 	            ioe;
-#endif /* EHE_ENABLE */
     nasid_t		    nasid;
 
 
@@ -806,10 +705,6 @@
 	pcibr_soft->bs_errinfo.bserr_toutcnt++;
 	/* Let's go recursive */
 	return(pcibr_error_intr_handler(irq, arg, ep));
-#ifdef LATER
-	timeout(pcibr_error_intr_handler, pcibr_soft, BRIDGE_PIOERR_TIMEOUT);
-#endif
-	return;
     }
 
     /* We read the INT_STATUS register as a 64bit picreg_t for PIC and a
@@ -847,24 +742,6 @@
 	pcibr_pioerr_check(pcibr_soft);
     }
 
-#ifdef BRIDGE_B_DATACORR_WAR
-    if ((pcibr_soft->bs_rev_num == BRIDGE_PART_REV_B) &&
-	(err_status & BRIDGE_IMR_LLP_REC_CBERR)) {
-	if (bridge_rev_b_data_check_disable)
-	    printk(KERN_WARNING "\n%s%s: %s%s\n", rev_b_datacorr_warning,
-		    pcibr_soft->bs_name, rev_b_datacorr_mesg,
-		    rev_b_datacorr_warning);
-	else {
-	    ql_bridge_rev_b_war(pcibr_soft->bs_vhdl);
-	    PRINT_PANIC( "\n%s%s: %s%s\n", rev_b_datacorr_warning,
-		    pcibr_soft->bs_name, rev_b_datacorr_mesg,
-		    rev_b_datacorr_warning);
-	}
-
-	err_status &= ~BRIDGE_IMR_LLP_REC_CBERR;
-    }
-#endif				/* BRIDGE_B_DATACORR_WAR */
-
     if (err_status) {
 	struct bs_errintr_stat_s *bs_estat = pcibr_soft->bs_errintr_stat;
 
@@ -1024,9 +901,8 @@
 	(0x00402000 == (0x00F07F00 & bridge->b_wid_err_cmdword))) {
 	err_status &= ~BRIDGE_ISR_INVLD_ADDR;
     }
-#if defined (PCIBR_LLP_CONTROL_WAR)
     /*
-     * The bridge bug, where the llp_config or control registers
+     * The bridge bug (PCIBR_LLP_CONTROL_WAR), where the llp_config or control registers
      * need to be read back after being written, affects an MP
      * system since there could be small windows between writing
      * the register and reading it back on one cpu while another
@@ -1039,40 +915,9 @@
     if ((err_status & BRIDGE_ISR_INVLD_ADDR) &&
 	((((uint64_t) bridge->b_wid_err_upper << 32) | (bridge->b_wid_err_lower))
 	 == (BRIDGE_INT_RST_STAT & 0xff0))) {
-#if 0
-	if (kdebug)
-	    printk(KERN_NOTICE "%s bridge: ignoring llp/control address interrupt",
-		    pcibr_soft->bs_name);
-#endif
 	pcibr_llp_control_war_cnt++;
 	err_status &= ~BRIDGE_ISR_INVLD_ADDR;
     }
-#endif				/* PCIBR_LLP_CONTROL_WAR */
-
-#ifdef EHE_ENABLE
-    /* Check if this is the RESP_XTALK_ERROR interrupt. 
-     * This can happen due to a failed DMA READ operation.
-     */
-    if (err_status & BRIDGE_ISR_RESP_XTLK_ERR) {
-	/* Phase 1 : Look at the error state in the bridge and further
-	 * down in the device layers.
-	 */
-	(void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_LOOKUP);
-	IOERROR_SETVALUE(&ioe, widgetnum, pcibr_soft->bs_xid);
-	(void)pcibr_error_handler((error_handler_arg_t)pcibr_soft,
-				  error_code,
-				  mode,
-				  &ioe);
-	/* Phase 2 : Perform the action agreed upon in phase 1.
-	 */
-	(void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_ACTION);
-	rv = pcibr_error_handler((error_handler_arg_t)pcibr_soft,
-				 error_code,
-				 mode,
-				 &ioe);
-    }
-    if (rv != IOERROR_HANDLED) {
-#endif /* EHE_ENABLE */
 
     bridge_errors_to_dump |= BRIDGE_ISR_PCIBUS_PIOERR;
 
@@ -1089,25 +934,16 @@
      */
     if (IS_PIC_SOFT(pcibr_soft) && PCIBR_WAR_ENABLED(PV867308, pcibr_soft) &&
         (err_status & (BRIDGE_ISR_LLP_REC_SNERR | BRIDGE_ISR_LLP_REC_CBERR))) {
-        printk("BRIDGE ERR_STATUS 0x%x\n", err_status);
+        printk("BRIDGE ERR_STATUS 0x%lx\n", err_status);
         pcibr_error_dump(pcibr_soft);
-#ifdef LATER
-        machine_error_dump("");
-#endif
         PRINT_PANIC("PCI Bridge Error interrupt killed the system");
     }
 
     if (err_status & BRIDGE_ISR_ERROR_FATAL) {
-#ifdef LATER
-	machine_error_dump("");
-#endif
 	PRINT_PANIC("PCI Bridge Error interrupt killed the system");
 	    /*NOTREACHED */
     }
 
-#ifdef EHE_ENABLE
-    }
-#endif
 
     /*
      * We can't return without re-enabling the interrupt, since
@@ -1137,136 +973,6 @@
     pcibr_soft->bs_errinfo.bserr_intstat = 0;
 }
 
-/*
- * pcibr_addr_toslot
- *      Given the 'pciaddr' find out which slot this address is
- *      allocated to, and return the slot number.
- *      While we have the info handy, construct the
- *      function number, space code and offset as well.
- *
- * NOTE: if this routine is called, we don't know whether
- * the address is in CFG, MEM, or I/O space. We have to guess.
- * This will be the case on PIO stores, where the only way
- * we have of getting the address is to check the Bridge, which
- * stores the PCI address but not the space and not the xtalk
- * address (from which we could get it).
- */
-int
-pcibr_addr_toslot(pcibr_soft_t pcibr_soft,
-		  iopaddr_t pciaddr,
-		  pciio_space_t *spacep,
-		  iopaddr_t *offsetp,
-		  pciio_function_t *funcp)
-{
-    int                     s, f = 0, w;
-    iopaddr_t               base;
-    size_t                  size;
-    pciio_piospace_t        piosp;
-
-    /*
-     * Check if the address is in config space
-     */
-
-    if ((pciaddr >= BRIDGE_CONFIG_BASE) && (pciaddr < BRIDGE_CONFIG_END)) {
-
-	if (pciaddr >= BRIDGE_CONFIG1_BASE)
-	    pciaddr -= BRIDGE_CONFIG1_BASE;
-	else
-	    pciaddr -= BRIDGE_CONFIG_BASE;
-
-	s = pciaddr / BRIDGE_CONFIG_SLOT_SIZE;
-	pciaddr %= BRIDGE_CONFIG_SLOT_SIZE;
-
-	if (funcp) {
-	    f = pciaddr / 0x100;
-	    pciaddr %= 0x100;
-	}
-	if (spacep)
-	    *spacep = PCIIO_SPACE_CFG;
-	if (offsetp)
-	    *offsetp = pciaddr;
-	if (funcp)
-	    *funcp = f;
-
-	return s;
-    }
-    for (s = pcibr_soft->bs_min_slot; s < PCIBR_NUM_SLOTS(pcibr_soft); ++s) {
-	int                     nf = pcibr_soft->bs_slot[s].bss_ninfo;
-	pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos;
-
-	for (f = 0; f < nf; f++) {
-	    pcibr_info_t            pcibr_info = pcibr_infoh[f];
-
-	    if (!pcibr_info)
-		continue;
-	    for (w = 0; w < 6; w++) {
-		if (pcibr_info->f_window[w].w_space == PCIIO_SPACE_NONE) {
-		    continue;
-		}
-		base = pcibr_info->f_window[w].w_base;
-		size = pcibr_info->f_window[w].w_size;
-
-		if ((pciaddr >= base) && (pciaddr < (base + size))) {
-		    if (spacep)
-			*spacep = PCIIO_SPACE_WIN(w);
-		    if (offsetp)
-			*offsetp = pciaddr - base;
-		    if (funcp)
-			*funcp = f;
-		    return s;
-		}			/* endif match */
-	    }				/* next window */
-	}				/* next func */
-    }					/* next slot */
-
-    /*
-     * Check if the address was allocated as part of the
-     * pcibr_piospace_alloc calls.
-     */
-    for (s = pcibr_soft->bs_min_slot; s < PCIBR_NUM_SLOTS(pcibr_soft); ++s) {
-	int                     nf = pcibr_soft->bs_slot[s].bss_ninfo;
-	pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos;
-
-	for (f = 0; f < nf; f++) {
-	    pcibr_info_t            pcibr_info = pcibr_infoh[f];
-
-	    if (!pcibr_info)
-		continue;
-	    piosp = pcibr_info->f_piospace;
-	    while (piosp) {
-		if ((piosp->start <= pciaddr) &&
-		    ((piosp->count + piosp->start) > pciaddr)) {
-		    if (spacep)
-			*spacep = piosp->space;
-		    if (offsetp)
-			*offsetp = pciaddr - piosp->start;
-		    return s;
-		}			/* endif match */
-		piosp = piosp->next;
-	    }				/* next piosp */
-	}				/* next func */
-    }					/* next slot */
-
-    /*
-     * Some other random address on the PCI bus ...
-     * we have no way of knowing whether this was
-     * a MEM or I/O access; so, for now, we just
-     * assume that the low 1G is MEM, the next
-     * 3G is I/O, and anything above the 4G limit
-     * is obviously MEM.
-     */
-
-    if (spacep)
-	*spacep = ((pciaddr < (1ul << 30)) ? PCIIO_SPACE_MEM :
-		   (pciaddr < (4ul << 30)) ? PCIIO_SPACE_IO :
-		   PCIIO_SPACE_MEM);
-    if (offsetp)
-	*offsetp = pciaddr;
-
-    return PCIIO_SLOT_NONE;
-
-}
-
 void
 pcibr_error_cleanup(pcibr_soft_t pcibr_soft, int error_code)
 {
@@ -1286,59 +992,6 @@
     (void) bridge->b_wid_tflush;	/* flushbus */
 }
 
-/*
- * pcibr_error_extract
- *      Given the 'pcibr vertex handle' find out which slot
- *      the bridge status error address (from pcibr_soft info
- *      hanging off the vertex)
- *      allocated to, and return the slot number.
- *      While we have the info handy, construct the
- *      space code and offset as well.
- *
- * NOTE: if this routine is called, we don't know whether
- * the address is in CFG, MEM, or I/O space. We have to guess.
- * This will be the case on PIO stores, where the only way
- * we have of getting the address is to check the Bridge, which
- * stores the PCI address but not the space and not the xtalk
- * address (from which we could get it).
- *
- * XXX- this interface has no way to return the function
- * number on a multifunction card, even though that data
- * is available.
- */
-
-pciio_slot_t
-pcibr_error_extract(devfs_handle_t pcibr_vhdl,
-		    pciio_space_t *spacep,
-		    iopaddr_t *offsetp)
-{
-    pcibr_soft_t            pcibr_soft = 0;
-    iopaddr_t               bserr_addr;
-    bridge_t               *bridge;
-    pciio_slot_t            slot = PCIIO_SLOT_NONE;
-    arbitrary_info_t	    rev;
-
-    /* Do a sanity check as to whether we really got a 
-     * bridge vertex handle.
-     */
-    if (hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &rev) !=
-	GRAPH_SUCCESS) 
-	return(slot);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (pcibr_soft) {
-	bridge = pcibr_soft->bs_base;
-	bserr_addr =
-	    bridge->b_pci_err_lower |
-	    ((uint64_t) (bridge->b_pci_err_upper &
-			   BRIDGE_ERRUPPR_ADDRMASK) << 32);
-
-	slot = pcibr_addr_toslot(pcibr_soft, bserr_addr,
-				 spacep, offsetp, NULL);
-    }
-    return slot;
-}
-
 /*ARGSUSED */
 void
 pcibr_device_disable(pcibr_soft_t pcibr_soft, int devnum)
@@ -1426,7 +1079,7 @@
 {
     int                     retval = IOERROR_HANDLED;
 
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    vertex_hdl_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
     bridge_t               *bridge = pcibr_soft->bs_base;
 
     iopaddr_t               bad_xaddr;
@@ -1806,7 +1459,7 @@
 	 *
 	 * CAUTION: Resetting bit BRIDGE_IRR_PCI_GRP_CLR, acknowledges
 	 *      a group of interrupts. If while handling this error,
-	 *      some other error has occured, that would be
+	 *      some other error has occurred, that would be
 	 *      implicitly cleared by this write.
 	 *      Need a way to ensure we don't inadvertently clear some
 	 *      other errors.
@@ -1837,7 +1490,7 @@
 		     ioerror_mode_t mode,
 		     ioerror_t *ioe)
 {
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    vertex_hdl_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
     bridge_t               *bridge = pcibr_soft->bs_base;
     bridgereg_t             bus_lowaddr, bus_uppraddr;
     int                     retval = 0;
@@ -1874,7 +1527,7 @@
 			BRIDGE_ERRUPPR_ADDRMASK) << 32)));
 
     /*
-     * need to ensure that the xtalk adress in ioe
+     * need to ensure that the xtalk address in ioe
      * maps to PCI error address read from bridge.
      * How to convert PCI address back to Xtalk address ?
      * (better idea: convert XTalk address to PCI address
@@ -1946,7 +1599,7 @@
 		     ioerror_mode_t mode,
 		     ioerror_t *ioe)
 {
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    vertex_hdl_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
     int                     retval;
 
     retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
@@ -1982,34 +1635,12 @@
     pcibr_soft_t            pcibr_soft;
     int                     retval = IOERROR_BADERRORCODE;
 
-#ifdef EHE_ENABLE
-    devfs_handle_t	    xconn_vhdl,pcibr_vhdl;
-    error_state_t	    e_state;
-#endif /* EHE_ENABLE */
-
     pcibr_soft = (pcibr_soft_t) einfo;
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ERROR_HDLR, pcibr_soft->bs_conn,
 		"pcibr_error_handler: pcibr_soft=0x%x, error_code=0x%x\n",
 		pcibr_soft, error_code));
 
-#ifdef EHE_ENABLE
-    xconn_vhdl = pcibr_soft->bs_conn;
-    pcibr_vhdl = pcibr_soft->bs_vhdl;
-
-    e_state = error_state_get(xconn_vhdl);
-    
-    if (error_state_set(pcibr_vhdl, e_state) == 
-	ERROR_RETURN_CODE_CANNOT_SET_STATE)
-	return(IOERROR_UNHANDLED);
-
-    /* If we are in the action handling phase clean out the error state
-     * on the xswitch.
-     */
-    if (e_state == ERROR_STATE_ACTION)
-	(void)error_state_set(xconn_vhdl, ERROR_STATE_NONE);
-#endif /* EHE_ENABLE */
-
 #if DEBUG && ERROR_DEBUG
     printk( "%s: pcibr_error_handler\n", pcibr_soft->bs_name);
 #endif
@@ -2086,11 +1717,6 @@
      * the error from the PIO address.
      */
 
-#if 0
-    if (mode == MODE_DEVPROBE)
-	pio_retval = IOERROR_HANDLED;
-    else {
-#endif
     if (error_code & IOECODE_PIO) {
 	iopaddr_t               bad_xaddr;
 	/*
@@ -2123,9 +1749,6 @@
 	    pio_retval = IOERROR_UNHANDLED;
 	}
     } 
-#if 0
-    } /* MODE_DEVPROBE */
-#endif
 
     /* 
      * If the error was a result of a DMA Write, we tell what bus on the PIC
@@ -2201,37 +1824,3 @@
 	return IOERROR_HANDLED;
     }
 }
-
-
-/*
- * Reenable a device after handling the error.
- * This is called by the lower layers when they wish to be reenabled
- * after an error.
- * Note that each layer would be calling the previous layer to reenable
- * first, before going ahead with their own re-enabling.
- */
-
-int
-pcibr_error_devenable(devfs_handle_t pconn_vhdl, int error_code)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    ASSERT(error_code & IOECODE_PIO);
-
-    /* If the error is not known to be a write,
-     * we have to call devenable.
-     * write errors are isolated to the bridge.
-     */
-    if (!(error_code & IOECODE_WRITE)) {
-	devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-	int                     rc;
-
-	rc = xtalk_error_devenable(xconn_vhdl, pciio_slot, error_code);
-	if (rc != IOERROR_HANDLED)
-	    return rc;
-    }
-    pcibr_error_cleanup(pcibr_soft, error_code);
-    return IOERROR_HANDLED;
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,20 +27,19 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-pcibr_hints_t           pcibr_hints_get(devfs_handle_t, int);
-void                    pcibr_hints_fix_rrbs(devfs_handle_t);
-void                    pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-void			pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
-void                    pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
-void                    pcibr_hints_handsoff(devfs_handle_t);
-void                    pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t);
+pcibr_hints_t           pcibr_hints_get(vertex_hdl_t, int);
+void                    pcibr_hints_fix_rrbs(vertex_hdl_t);
+void                    pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
+void			pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *);
+void                    pcibr_set_rrb_callback(vertex_hdl_t, rrb_alloc_funct_t);
+void                    pcibr_hints_handsoff(vertex_hdl_t);
+void                    pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, uint64_t);
 
 pcibr_hints_t
-pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc)
+pcibr_hints_get(vertex_hdl_t xconn_vhdl, int alloc)
 {
     arbitrary_info_t        ainfo = 0;
     graph_error_t	    rv;
@@ -79,7 +78,7 @@
 }
 
 void
-pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask)
+pcibr_hints_fix_some_rrbs(vertex_hdl_t xconn_vhdl, unsigned mask)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
 
@@ -91,13 +90,13 @@
 }
 
 void
-pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl)
+pcibr_hints_fix_rrbs(vertex_hdl_t xconn_vhdl)
 {
     pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF);
 }
 
 void
-pcibr_hints_dualslot(devfs_handle_t xconn_vhdl,
+pcibr_hints_dualslot(vertex_hdl_t xconn_vhdl,
 		     pciio_slot_t host,
 		     pciio_slot_t guest)
 {
@@ -111,7 +110,7 @@
 }
 
 void
-pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl,
+pcibr_hints_intr_bits(vertex_hdl_t xconn_vhdl,
 		      pcibr_intr_bits_f *xxx_intr_bits)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
@@ -124,7 +123,7 @@
 }
 
 void
-pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
+pcibr_set_rrb_callback(vertex_hdl_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
 
@@ -133,7 +132,7 @@
 }
 
 void
-pcibr_hints_handsoff(devfs_handle_t xconn_vhdl)
+pcibr_hints_handsoff(vertex_hdl_t xconn_vhdl)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
 
@@ -145,13 +144,13 @@
 }
 
 void
-pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
+pcibr_hints_subdevs(vertex_hdl_t xconn_vhdl,
 		    pciio_slot_t slot,
 		    uint64_t subdevs)
 {
     arbitrary_info_t        ainfo = 0;
     char                    sdname[16];
-    devfs_handle_t            pconn_vhdl = GRAPH_VERTEX_NONE;
+    vertex_hdl_t            pconn_vhdl = GRAPH_VERTEX_NONE;
 
     sprintf(sdname, "%s/%d", EDGE_LBL_PCI, slot);
     (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,147 +0,0 @@
-/*
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_defs.h>
-#include <asm/sn/prio.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_private.h>
-
-#ifdef LATER
-
-char *pci_space[] = {"NONE", 
-		     "ROM",
-		     "IO",
-		     "",
-		     "MEM",
-		     "MEM32",
-		     "MEM64",
-		     "CFG",
-		     "WIN0",
-		     "WIN1",
-		     "WIN2",
-		     "WIN3",
-		     "WIN4",
-		     "WIN5",
-		     "",
-		     "BAD"};
-
-void
-idbg_pss_func(pcibr_info_h pcibr_infoh, int func)
-{
-    pcibr_info_t	pcibr_info = pcibr_infoh[func];
-    char		name[MAXDEVNAME];
-    int			win;
-    
-    if (!pcibr_info)
-	return;
-    qprintf("Per-slot Function Info\n");
-    sprintf(name, "%v", pcibr_info->f_vertex);
-    qprintf("\tSlot Name : %s\n",name);
-    qprintf("\tPCI Bus : %d ",pcibr_info->f_bus);
-    qprintf("Slot : %d ", pcibr_info->f_slot);
-    qprintf("Function : %d ", pcibr_info->f_func);
-    qprintf("VendorId : 0x%x " , pcibr_info->f_vendor);
-    qprintf("DeviceId : 0x%x\n", pcibr_info->f_device);
-    sprintf(name, "%v", pcibr_info->f_master);
-    qprintf("\tBus provider : %s\n",name);
-    qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops);
-    qprintf("Error Handler : 0x%x Arg 0x%x\n", 
-	    pcibr_info->f_efunc,pcibr_info->f_einfo);
-    for(win = 0 ; win < 6 ; win++) 
-	qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n",
-		win,pci_space[pcibr_info->f_window[win].w_space],
-		pcibr_info->f_window[win].w_base,
-		pcibr_info->f_window[win].w_size);
-
-    qprintf("\tRom base 0x%x size 0x%x\n", 
-	    pcibr_info->f_rbase,pcibr_info->f_rsize);
-
-    qprintf("\tInterrupt Bit Map\n");
-    qprintf("\t\tPCI Int#\tBridge Pin#\n");
-    for (win = 0 ; win < 4; win++)
-	qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]);
-    qprintf("\n");
-}
-
-
-void
-idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot)
-{
-    pcibr_soft_slot_t	pss;
-    char		slot_conn_name[MAXDEVNAME];
-    int			func;
-
-    pss = &pcibr_soft->bs_slot[slot];
-    qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot);
-    qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no");
-    qprintf("\tHost Slot : %d\n",pss->host_slot);
-    sprintf(slot_conn_name, "%v", pss->slot_conn);
-    qprintf("\tSlot Conn : %s\n",slot_conn_name);	
-    qprintf("\t#Functions : %d\n",pss->bss_ninfo);
-    for (func = 0; func < pss->bss_ninfo; func++)
-	idbg_pss_func(pss->bss_infos,func);
-    qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]);
-    qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base);
-    qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device);
-    qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n",
-	    pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr);
-    
-    qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x"
-	    "d32_base 0x%x d32_flags 0x%x\n",
-	    pss->bss_d64_base, pss->bss_d64_flags,
-	    pss->bss_d32_base, pss->bss_d32_flags);
-    
-    qprintf("\tExt ATEs active ? %s", 
-	    pss->bss_ext_ates_active ? "yes" : "no");
-    qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer);
-    qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow);
-
-    qprintf("\tRRB Info : Valid %d+%d Reserved %d\n",
-	    pcibr_soft->bs_rrb_valid[slot],
-	    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-		
-}
-
-int	ips = 0;
-
-void
-idbg_pss(pcibr_soft_t pcibr_soft)
-{
-    pciio_slot_t	slot;
-
-    
-    if (ips >= 0 && ips < 8)
-	idbg_pss_info(pcibr_soft,ips);
-    else if (ips < 0)
-	for (slot = 0; slot < 8; slot++) 
-	    idbg_pss_info(pcibr_soft,slot);
-    else
-	qprintf("Invalid ips %d\n",ips);
-}
-#endif	/* LATER */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,29 +27,35 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
 #ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
+inline int
+compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr)
+{
+	FIXME("compare_and_swap_ptr : NOT ATOMIC");
+	if (*location == old_ptr) {
+		*location = new_ptr;
+		return(1);
+	}
+	else
+		return(0);
+}
 #endif
 
 unsigned		pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines, int nslots);
-pcibr_intr_t            pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+pcibr_intr_t            pcibr_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t);
 void                    pcibr_intr_free(pcibr_intr_t);
 void              pcibr_setpciint(xtalk_intr_t);
 int                     pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t);
 void                    pcibr_intr_disconnect(pcibr_intr_t);
 
-devfs_handle_t            pcibr_intr_cpu_get(pcibr_intr_t);
+vertex_hdl_t            pcibr_intr_cpu_get(pcibr_intr_t);
 void                    pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
 void                    pcibr_intr_func(intr_arg_t);
 
-extern pcibr_info_t      pcibr_info_get(devfs_handle_t);
+extern pcibr_info_t      pcibr_info_get(vertex_hdl_t);
 
 /* =====================================================================
  *    INTERRUPT MANAGEMENT
@@ -132,6 +138,102 @@
 }
 
 /*
+ *	On SN systems there is a race condition between a PIO read response
+ *	and DMA's.  In rare cases, the read response may beat the DMA, causing
+ *	the driver to think that data in memory is complete and meaningful.
+ *	This code eliminates that race.
+ *	This routine is called by the PIO read routines after doing the read.
+ *	This routine then forces a fake interrupt on another line, which
+ *	is logically associated with the slot that the PIO is addressed to.
+ *	(see sn_dma_flush_init() )
+ *	It then spins while watching the memory location that the interrupt
+ *	is targetted to.  When the interrupt response arrives, we are sure
+ *	that the DMA has landed in memory and it is safe for the driver
+ *	to proceed.
+ */
+
+extern struct sn_flush_nasid_entry flush_nasid_list[MAX_NASIDS];
+
+void
+sn_dma_flush(unsigned long addr) {
+	nasid_t nasid;
+	int wid_num;
+	volatile struct sn_flush_device_list *p;
+	int i,j;
+	int bwin;
+	unsigned long flags;
+
+	nasid = NASID_GET(addr);
+	wid_num = SWIN_WIDGETNUM(addr);
+	bwin = BWIN_WINDOWNUM(addr);
+
+	if (flush_nasid_list[nasid].widget_p == NULL) return;
+	if (bwin > 0) {
+		bwin--;
+		switch (bwin) {
+			case 0:
+				wid_num = ((flush_nasid_list[nasid].iio_itte1) >> 8) & 0xf;
+				break;
+			case 1:
+				wid_num = ((flush_nasid_list[nasid].iio_itte2) >> 8) & 0xf;
+				break;
+			case 2: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte3) >> 8) & 0xf;
+				break;
+			case 3: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte4) >> 8) & 0xf;
+				break;
+			case 4: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte5) >> 8) & 0xf;
+				break;
+			case 5: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte6) >> 8) & 0xf;
+				break;
+			case 6: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte7) >> 8) & 0xf;
+				break;
+		}
+	}
+	if (flush_nasid_list[nasid].widget_p == NULL) return;
+	if (flush_nasid_list[nasid].widget_p[wid_num] == NULL) return;
+	p = &flush_nasid_list[nasid].widget_p[wid_num][0];
+
+	// find a matching BAR
+
+	for (i=0; i<DEV_PER_WIDGET;i++) {
+		for (j=0; j<PCI_ROM_RESOURCE;j++) {
+			if (p->bar_list[j].start == 0) break;
+			if (addr >= p->bar_list[j].start && addr <= p->bar_list[j].end) break;
+		}
+		if (j < PCI_ROM_RESOURCE && p->bar_list[j].start != 0) break;
+		p++;
+	}
+
+	// if no matching BAR, return without doing anything.
+
+	if (i == DEV_PER_WIDGET) return;
+
+	spin_lock_irqsave(&p->flush_lock, flags);
+
+	p->flush_addr = 0;
+
+	// force an interrupt.
+
+	*(bridgereg_t *)(p->force_int_addr) = 1;
+
+	// wait for the interrupt to come back.
+
+	while (p->flush_addr != 0x10f);
+
+	// okay, everything is synched up.
+	spin_unlock_irqrestore(&p->flush_lock, flags);
+
+	return;
+}
+
+EXPORT_SYMBOL(sn_dma_flush);
+
+/*
  *	There are end cases where a deadlock can occur if interrupt 
  *	processing completes and the Bridge b_int_status bit is still set.
  *
@@ -164,51 +266,42 @@
  *	to check if a specific Bridge b_int_status bit is set, and if so,
  *	cause the setting of the corresponding interrupt bit.
  *
- *	On a XBridge (SN1), we do this by writing the appropriate Bridge Force 
- *	Interrupt register. On SN0, or SN1 with an older Bridge, the Bridge 
- *	Force Interrupt register does not exist, so we write the Hub 
- *	INT_PEND_MOD register directly. Likewise for Octane, where we write the 
- *	Heart Set Interrupt Status register directly.
+ *	On a XBridge (SN1) and PIC (SN2), we do this by writing the appropriate Bridge Force 
+ *	Interrupt register.
  */
 void
-pcibr_force_interrupt(pcibr_intr_wrap_t wrap)
+pcibr_force_interrupt(pcibr_intr_t intr)
 {
-#ifdef PIC_LATER
 	unsigned	bit;
-	pcibr_soft_t    pcibr_soft = wrap->iw_soft;
+	unsigned	bits;
+	pcibr_soft_t    pcibr_soft = intr->bi_soft;
 	bridge_t       *bridge = pcibr_soft->bs_base;
 
-	bit = wrap->iw_ibit;
+	bits = intr->bi_ibits;
+	for (bit = 0; bit < 8; bit++) {
+		if (bits & (1 << bit)) {
 
-	PCIBR_DEBUG((PCIBR_DEBUG_INTR, pcibr_soft->bs_vhdl,
-		    "pcibr_force_interrupt: bit=0x%x\n", bit));
+			PCIBR_DEBUG((PCIBR_DEBUG_INTR, pcibr_soft->bs_vhdl,
+		    		"pcibr_force_interrupt: bit=0x%x\n", bit));
 
-	if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) {
-	    bridge->b_force_pin[bit].intr = 1;
-	} else if ((1 << bit) & *wrap->iw_stat) {
-	    cpuid_t	    cpu;
-	    unsigned        intr_bit;
-	    xtalk_intr_t    xtalk_intr =
-				pcibr_soft->bs_intr[bit].bsi_xtalk_intr;
-
-	    intr_bit = (short) xtalk_intr_vector_get(xtalk_intr);
-	    cpu = xtalk_intr_cpuid_get(xtalk_intr);
-	    REMOTE_CPU_SEND_INTR(cpu, intr_bit);
+			if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) {
+	    			bridge->b_force_pin[bit].intr = 1;
+			}
+		}
 	}
-#endif	/* PIC_LATER */
 }
 
 /*ARGSUSED */
 pcibr_intr_t
-pcibr_intr_alloc(devfs_handle_t pconn_vhdl,
+pcibr_intr_alloc(vertex_hdl_t pconn_vhdl,
 		 device_desc_t dev_desc,
 		 pciio_intr_line_t lines,
-		 devfs_handle_t owner_dev)
+		 vertex_hdl_t owner_dev)
 {
     pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pcibr_info);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
     bridge_t               *bridge = pcibr_soft->bs_base;
     int                     is_threaded = 0;
 
@@ -498,25 +591,18 @@
 {
     iopaddr_t		 addr;
     xtalk_intr_vector_t	 vect;
-    devfs_handle_t	 vhdl;
+    vertex_hdl_t	 vhdl;
     bridge_t		*bridge;
+    picreg_t	*int_addr;
 
     addr = xtalk_intr_addr_get(xtalk_intr);
     vect = xtalk_intr_vector_get(xtalk_intr);
     vhdl = xtalk_intr_dev_get(xtalk_intr);
     bridge = (bridge_t *)xtalk_piotrans_addr(vhdl, 0, 0, sizeof(bridge_t), 0);
 
-    if (is_pic(bridge)) {
-	picreg_t	*int_addr;
-	int_addr = (picreg_t *)xtalk_intr_sfarg_get(xtalk_intr);
-	*int_addr = ((PIC_INT_ADDR_FLD & ((uint64_t)vect << 48)) |
+    int_addr = (picreg_t *)xtalk_intr_sfarg_get(xtalk_intr);
+    *int_addr = ((PIC_INT_ADDR_FLD & ((uint64_t)vect << 48)) |
 		     (PIC_INT_ADDR_HOST & addr));
-    } else {
-	bridgereg_t	*int_addr;
-	int_addr = (bridgereg_t *)xtalk_intr_sfarg_get(xtalk_intr);
-	*int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
-		     (BRIDGE_INT_ADDR_FLD & vect));
-    }
 }
 
 /*ARGSUSED */
@@ -582,8 +668,7 @@
 	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_intr->bi_dev,
 			"pcibr_setpciint: int_addr=0x%x, *int_addr=0x%x, "
 			"pcibr_int_bit=0x%x\n", int_addr,
-			(is_pic(bridge) ? 
-			 *(picreg_t *)int_addr : *(bridgereg_t *)int_addr),
+			 *(picreg_t *)int_addr,
 			pcibr_int_bit));
 	}
 
@@ -699,7 +784,7 @@
 	    xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr,
 				pcibr_intr_func, (intr_arg_t) intr_wrap,
 			       (xtalk_intr_setfunc_t)pcibr_setpciint,
-			       (void *)pcibr_int_bit);
+			       (void *)(long)pcibr_int_bit);
 	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_intr->bi_dev,
 			"pcibr_intr_disconnect: now-sharing int_bits=0x%x\n",
 			pcibr_int_bit));
@@ -707,7 +792,7 @@
 }
 
 /*ARGSUSED */
-devfs_handle_t
+vertex_hdl_t
 pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr)
 {
     pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
@@ -780,9 +865,6 @@
     bridge->b_wid_int_lower = NEW_b_wid_int_lower;
     bridge->b_int_host_err = vect;
 
-printk("pcibr_setwidint: b_wid_int_upper 0x%x b_wid_int_lower 0x%x b_int_host_err 0x%x\n",
-	NEW_b_wid_int_upper, NEW_b_wid_int_lower, vect);
-
 }
 
 /*
@@ -842,7 +924,7 @@
  *
  * This is the pcibr interrupt "wrapper" function that is called,
  * in interrupt context, to initiate the interrupt handler(s) registered
- * (via pcibr_intr_alloc/connect) for the occuring interrupt. Non-threaded 
+ * (via pcibr_intr_alloc/connect) for the occurring interrupt. Non-threaded 
  * handlers will be called directly, and threaded handlers will have their 
  * thread woken up.
  */
@@ -957,7 +1039,7 @@
 	     * interrupt to avoid a potential deadlock situation.
 	     */
 	    if (wrap->iw_hdlrcnt == 0) {
-		pcibr_force_interrupt(wrap);
+		pcibr_force_interrupt((pcibr_intr_t) wrap);
 	    }
 	}
 
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c	2003-07-05 18:09:44.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,7 +27,6 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
@@ -41,11 +40,11 @@
 
 void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int, int);
 
-int		  pcibr_wrb_flush(devfs_handle_t);
-int               pcibr_rrb_alloc(devfs_handle_t, int *, int *);
-int               pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *);
-void              pcibr_rrb_flush(devfs_handle_t);
-int		  pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
+int		  pcibr_wrb_flush(vertex_hdl_t);
+int               pcibr_rrb_alloc(vertex_hdl_t, int *, int *);
+int               pcibr_rrb_check(vertex_hdl_t, int *, int *, int *, int *);
+void              pcibr_rrb_flush(vertex_hdl_t);
+int		  pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t);
 
 void		  pcibr_rrb_debug(char *, pcibr_soft_t);
 
@@ -70,17 +69,15 @@
 #define RRB_SIZE (4)			/* sizeof rrb within reg (bits) */
  
 #define RRB_ENABLE_BIT(bridge)		(0x8)  /* [BRIDGE | PIC]_RRB_EN */
-#define NUM_PDEV_BITS(bridge)		(is_pic((bridge)) ? 1 : 2)
-#define NUM_VDEV_BITS(bridge)		(is_pic((bridge)) ? 2 : 1)
-#define NUMBER_VCHANNELS(bridge)	(is_pic((bridge)) ? 4 : 2)
+#define NUM_PDEV_BITS(bridge)		(1)
+#define NUM_VDEV_BITS(bridge)		(2)
+#define NUMBER_VCHANNELS(bridge)	(4)
 #define SLOT_2_PDEV(bridge, slot)	((slot) >> 1)
 #define SLOT_2_RRB_REG(bridge, slot)	((slot) & 0x1)
  
 /* validate that the slot and virtual channel are valid for a given bridge */
 #define VALIDATE_SLOT_n_VCHAN(bridge, s, v) \
-  (is_pic((bridge)) ? \
-    (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && (((v) >= 0) && ((v) <= 3))) ? 1 : 0) : \
-    (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)7)) && (((v) >= 0) && ((v) <= 1))) ? 1 : 0))
+    (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && (((v) >= 0) && ((v) <= 3))) ? 1 : 0)
  
 /*  
  * Count how many RRBs are marked valid for the specified PCI slot
@@ -105,16 +102,7 @@
     pdev_bits = SLOT_2_PDEV(bridge, slot);
     rrb_bits = enable_bit | vchan_bits | pdev_bits;
     
-    if ( is_pic(bridge) ) {
-	tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
+    tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
 
     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
 	if ((tmp & RRB_MASK) == rrb_bits)
@@ -144,16 +132,7 @@
     
     enable_bit = RRB_ENABLE_BIT(bridge);
 
-    if ( is_pic(bridge) ) {
-	tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
+    tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
 
     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
 	if ((tmp & enable_bit) != enable_bit)
@@ -192,17 +171,8 @@
     pdev_bits = SLOT_2_PDEV(bridge, slot);
     rrb_bits = enable_bit | vchan_bits | pdev_bits;
 
-    if ( is_pic(bridge) ) {
-	reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		reg = tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
-    
+    reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
+
     for (rrb_index = 0; ((rrb_index < 8) && (more > 0)); rrb_index++) {
 	if ((tmp & enable_bit) != enable_bit) {
 	    /* clear the rrb and OR in the new rrb into 'reg' */
@@ -213,16 +183,7 @@
 	tmp = (tmp >> RRB_SIZE);
     }
 
-    if ( is_pic(bridge) ) {
-	bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)) = reg;
-	} else {
-		bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-	}
-    }
+    bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
     return (more ? -1 : 0);
 }
  
@@ -255,24 +216,15 @@
     pdev_bits = SLOT_2_PDEV(bridge, slot);
     rrb_bits = enable_bit | vchan_bits | pdev_bits;
 
-    if ( is_pic(bridge) ) {
-	reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		reg = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
-    
+    reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
+
     for (rrb_index = 0; ((rrb_index < 8) && (less > 0)); rrb_index++) {
 	if ((tmp & RRB_MASK) == rrb_bits) {
 	   /*
 	    * the old do_pcibr_rrb_free() code only clears the enable bit
 	    * but I say we should clear the whole rrb (ie):
 	    *	  reg = reg & ~(RRB_MASK << (RRB_SIZE * rrb_index));
-	    * But to be compatable with old code we'll only clear enable.
+	    * But to be compatible with old code we'll only clear enable.
 	    */
 	    reg = reg & ~(RRB_ENABLE_BIT(bridge) << (RRB_SIZE * rrb_index));
 	    clr = clr | (enable_bit << (RRB_SIZE * rrb_index));
@@ -281,16 +233,7 @@
 	tmp = (tmp >> RRB_SIZE);
     }
 
-    if ( is_pic(bridge) ) {
-	bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)) = reg;
-	} else {
-		bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-	}
-    }
+    bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
 
     /* call do_pcibr_rrb_clear() for all the rrbs we've freed */
     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
@@ -337,50 +280,18 @@
      * this RRB must be disabled.
      */
 
-    if ( is_pic(bridge) ) {
-	/* wait until RRB has no outstanduing XIO packets. */
-	while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
-		;				/* XXX- beats on bridge. bad idea? */
-	}
-
-	/* if the RRB has data, drain it. */
-	if (status & BRIDGE_RRB_VALID(rrb)) {
-		bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
-
-		/* wait until RRB is no longer valid. */
-		while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
-			;				/* XXX- beats on bridge. bad idea? */
-		}
-	}
+    /* wait until RRB has no outstanduing XIO packets. */
+    while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
+	;				/* XXX- beats on bridge. bad idea? */
     }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		while ((status = BRIDGE_REG_GET32((&bridge->b_resp_status))) & BRIDGE_RRB_INUSE(rrb)) {
-			;                               /* XXX- beats on bridge. bad idea? */
-		}
-
-		/* if the RRB has data, drain it. */
-		if (status & BRIDGE_RRB_VALID(rrb)) {
-			BRIDGE_REG_SET32((&bridge->b_resp_clear)) = __swab32(BRIDGE_RRB_CLEAR(rrb));
-
-			/* wait until RRB is no longer valid. */
-			while ((status = BRIDGE_REG_GET32((&bridge->b_resp_status))) & BRIDGE_RRB_VALID(rrb)) {
-				;                           /* XXX- beats on bridge. bad idea? */
-			}
-		}
-	} else { /* io_get_sh_swapper(NASID_GET(bridge)) */
-		while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
-			;                               /* XXX- beats on bridge. bad idea? */
-		}
-
-		/* if the RRB has data, drain it. */
-		if (status & BRIDGE_RRB_VALID(rrb)) {
-			bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
-			/* wait until RRB is no longer valid. */
-			while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
-				;                           /* XXX- beats on bridge. bad idea? */
-			}
-		}
+
+    /* if the RRB has data, drain it. */
+    if (status & BRIDGE_RRB_VALID(rrb)) {
+	bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
+
+	/* wait until RRB is no longer valid. */
+	while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
+		;				/* XXX- beats on bridge. bad idea? */
 	}
     }
 }
@@ -399,43 +310,16 @@
     int		 shft = (RRB_SIZE * (rrbn >> 1));
     unsigned long	 ebit = RRB_ENABLE_BIT(bridge) << shft;
 
-    if ( is_pic(bridge) ) {
-	rrbv = *rrbp;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		rrbv = BRIDGE_REG_GET32((&rrbp));
-	} else {
-		rrbv = *rrbp;
-	}
-    }
+    rrbv = *rrbp;
 
     if (rrbv & ebit) {
-    	if ( is_pic(bridge) ) {
-		*rrbp = rrbv & ~ebit;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_SET32((&rrbp)) = __swab32((rrbv & ~ebit));
-		} else {
-			*rrbp = rrbv & ~ebit;
-		}
-	}
+	*rrbp = rrbv & ~ebit;
     }
 
     do_pcibr_rrb_clear(bridge, rrbn);
 
     if (rrbv & ebit) {
-	if ( is_pic(bridge) ) {
-		*rrbp = rrbv;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_SET32((&rrbp)) = __swab32(rrbv);
-		} else {
-			*rrbp = rrbv;
-		}
-	}
+	*rrbp = rrbv;
     }
 }
 
@@ -475,7 +359,7 @@
  * Flush all the rrb's assigned to the specified connection point.
  */
 void
-pcibr_rrb_flush(devfs_handle_t pconn_vhdl)
+pcibr_rrb_flush(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t  pcibr_soft = (pcibr_soft_t)pciio_info_mfast_get(pciio_info);
@@ -510,7 +394,7 @@
  * device hanging off the bridge.
  */
 int
-pcibr_wrb_flush(devfs_handle_t pconn_vhdl)
+pcibr_wrb_flush(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
@@ -546,7 +430,7 @@
  * as best we can and return 0.
  */
 int
-pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
+pcibr_rrb_alloc(vertex_hdl_t pconn_vhdl,
 		int *count_vchan0,
 		int *count_vchan1)
 {
@@ -753,7 +637,7 @@
  */
 
 int
-pcibr_rrb_check(devfs_handle_t pconn_vhdl,
+pcibr_rrb_check(vertex_hdl_t pconn_vhdl,
 		int *count_vchan0,
 		int *count_vchan1,
 		int *count_reserved,
@@ -802,7 +686,7 @@
  */
 
 int
-pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,
+pcibr_slot_initial_rrb_alloc(vertex_hdl_t pcibr_vhdl,
 			     pciio_slot_t slot)
 {
     pcibr_soft_t	 pcibr_soft;
@@ -816,10 +700,10 @@
     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
 
     if (!pcibr_soft)
-	return(EINVAL);
+	return(-EINVAL);
 
     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
-	return(EINVAL);
+	return(-EINVAL);
 
     bridge = pcibr_soft->bs_base;
 
@@ -857,7 +741,13 @@
 
         pcibr_soft->bs_rrb_valid[slot][3] = chan[3];
 
-        return(ENODEV);
+        return(-ENODEV);
+    }
+
+    /* Give back any assigned to empty slots */
+    if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) && !pcibr_soft->bs_slot[slot].has_host) {
+	do_pcibr_rrb_free_all(pcibr_soft, bridge, slot);
+	return(-ENODEV);
     }
 
     for (vchan = 0; vchan < vchan_total; vchan++)
@@ -889,7 +779,7 @@
  */
 
 int
-pcibr_initial_rrb(devfs_handle_t pcibr_vhdl,
+pcibr_initial_rrb(vertex_hdl_t pcibr_vhdl,
 			     pciio_slot_t first, pciio_slot_t last)
 {
     pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c	2003-07-05 18:09:45.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -28,55 +28,44 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
-#include <asm/sn/ate_utils.h>
 
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
-
-extern pcibr_info_t     pcibr_info_get(devfs_handle_t);
-extern int              pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl);
+extern pcibr_info_t     pcibr_info_get(vertex_hdl_t);
+extern int              pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl);
 extern pcibr_info_t     pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-extern int		pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t);
 extern int		pcibr_pcix_rbars_calc(pcibr_soft_t);
 
-int pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
-int pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
-int pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot);
+int pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot);
+int pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
 int pcibr_slot_pcix_rbar_init(pcibr_soft_t pcibr_soft,  pciio_slot_t slot);
-int pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
-int pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
-int pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
+int pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl,
 		 pciio_slot_t slot, int drv_flags);
-int pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
+int pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl,
 		 pciio_slot_t slot, int drv_flags);
-int pcibr_slot_detach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot,
+int pcibr_slot_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot,
                  int drv_flags, char *l1_msg, int *sub_errorp);
-int pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
 static int pcibr_probe_slot(bridge_t *, cfg_p, unsigned int *);
-void pcibr_device_info_free(devfs_handle_t, pciio_slot_t);
+void pcibr_device_info_free(vertex_hdl_t, pciio_slot_t);
 iopaddr_t pcibr_bus_addr_alloc(pcibr_soft_t, pciio_win_info_t, 
                                pciio_space_t, int, int, int);
 void pciibr_bus_addr_free(pcibr_soft_t, pciio_win_info_t);
 cfg_p pcibr_find_capability(cfg_p, unsigned);
-extern uint64_t  do_pcibr_config_get(int, cfg_p, unsigned, unsigned);
-void do_pcibr_config_set(int, cfg_p, unsigned, unsigned, uint64_t); 
+extern uint64_t  do_pcibr_config_get(cfg_p, unsigned, unsigned);
+void do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); 
 
-int pcibr_slot_attach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot,
+int pcibr_slot_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot,
                 int drv_flags, char *l1_msg, int *sub_errorp);
 
 int pcibr_slot_info_return(pcibr_soft_t pcibr_soft, pciio_slot_t slot,
                  pcibr_slot_info_resp_t respp);
 
-extern devfs_handle_t baseio_pci_vhdl;
-int scsi_ctlr_nums_add(devfs_handle_t, devfs_handle_t);
+extern vertex_hdl_t baseio_pci_vhdl;
+int scsi_ctlr_nums_add(vertex_hdl_t, vertex_hdl_t);
 
 
 /* For now .... */
@@ -111,7 +100,7 @@
 #ifdef PIC_LATER
 
 int
-pcibr_slot_startup(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+pcibr_slot_startup(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
 {
     pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     pciio_slot_t                   slot;
@@ -127,11 +116,6 @@
     /* req_slot is the 'external' slot number, convert for internal use */
     slot = PCIBR_SLOT_TO_DEVICE(pcibr_soft, reqp->req_slot);
 
-    /* Do not allow start-up of a slot in a shoehorn */
-    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
-       return(PCI_SLOT_IN_SHOEHORN);
-    }
- 
     /* Check for the valid slot */
     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
         return(PCI_NOT_A_SLOT);
@@ -170,7 +154,7 @@
  *	Software shut-down the PCI slot
  */
 int
-pcibr_slot_shutdown(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+pcibr_slot_shutdown(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
 {
     pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     bridge_t                      *bridge;
@@ -194,11 +178,6 @@
     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
         return(PCI_NOT_A_SLOT);
 
-    /* Do not allow shut-down of a slot in a shoehorn */
-    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
-       return(PCI_SLOT_IN_SHOEHORN);
-    }
-
 #ifdef PIC_LATER
     /* Acquire update access to the bus */
     mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);
@@ -284,7 +263,6 @@
 {
     pcibr_info_t                 pcibr_info = pcibr_infoh[func];
     int                          win;
-    boolean_t is_sys_critical_vertex(devfs_handle_t);
 
     funcp->resp_f_status = 0;
 
@@ -296,9 +274,6 @@
 #if defined(SUPPORT_PRINTING_V_FORMAT)
     sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex);
 #endif
-    if(is_sys_critical_vertex(pcibr_info->f_vertex)) {
-        funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL;
-    }
 
     funcp->resp_f_bus = pcibr_info->f_bus;
     funcp->resp_f_slot = PCIBR_INFO_SLOT_GET_EXT(pcibr_info);
@@ -345,7 +320,6 @@
     reg_p                        b_respp;
     pcibr_slot_info_resp_t       slotp;
     pcibr_slot_func_info_resp_t  funcp;
-    boolean_t is_sys_critical_vertex(devfs_handle_t);
     extern void snia_kmem_free(void *, int);
 
     slotp = snia_kmem_zalloc(sizeof(*slotp), 0);
@@ -368,11 +342,6 @@
     slotp->resp_slot_status = pss->slot_status;
 
     slotp->resp_l1_bus_num = pcibr_widget_to_bus(pcibr_soft->bs_vhdl);
-
-    if (is_sys_critical_vertex(pss->slot_conn)) {
-        slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL;
-    }
-
     slotp->resp_bss_ninfo = pss->bss_ninfo;
 
     for (func = 0; func < pss->bss_ninfo; func++) {
@@ -455,7 +424,7 @@
  *		External SSRAM workaround info
  */
 int
-pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+pcibr_slot_query(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
 {
     pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     pciio_slot_t            slot;
@@ -481,11 +450,6 @@
         return(PCI_NOT_A_SLOT);
     }
 
-    /* Do not allow a query of a slot in a shoehorn */
-    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
-       return(PCI_SLOT_IN_SHOEHORN);
-    }
-
     /* Return information for the requested PCI slot */
     if (slot != PCIIO_SLOT_NONE) {
         if (size < sizeof(*respp)) {
@@ -534,88 +498,6 @@
     return(error);
 }
 
-#if 0
-/*
- * pcibr_slot_reset
- *	Reset the PCI device in the particular slot.
- *
- *      The Xbridge does not comply with the PCI Specification
- *      when resetting an indiviaudl slot.  An individual slot is
- *      is reset by toggling the slot's bit in the Xbridge Control
- *      Register.  The Xbridge will assert the target slot's 
- *      (non-bussed) RST signal, but does not assert the (bussed) 
- *      REQ64 signal as required by the specification.   As
- *      designed, the Xbridge cannot assert the REQ64 signal
- *      becuase it may interfere with a bus transaction in progress.
- *      The practical effects of this Xbridge implementation is
- *      device dependent;  it probably will not adversely effect
- *      32-bit cards, but may disable 64-bit data transfers by those
- *      cards that normally support 64-bit data transfers.  
- *
- *      The Xbridge will assert REQ64 when all four slots are reset
- *      by simultaneously toggling all four slot reset bits in the
- *      Xbridge Control Register.  This is basically a PCI bus reset
- *      and asserting the (bussed) REQ64 signal will not interfere
- *      with any bus transactions in progress.
- *
- *      The Xbridge (and the SN0 Bridge) support resetting only
- *      four PCI bus slots via the (X)bridge Control Register.
- *
- *      To reset an individual slot for the PCI Hot-Plug feature
- *      use the L1 console commands to power-down and then 
- *      power-up the slot, or use the kernel infrastructure
- *      functions to power-down/up the slot when they are
- *      implemented for SN1.
- */
-int
-pcibr_slot_reset(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
-{
-	pcibr_soft_t		 pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-	bridge_t		*bridge;
-	bridgereg_t		 ctrlreg,tmp;
-	volatile bridgereg_t	*wrb_flush;
-
-	if (!pcibr_soft)
-		return(EINVAL);
-
-	if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
-		return(EINVAL);
-
-	/* Enable the DMA operations from this device of the xtalk widget
-	 * (PCI host bridge in this case).
-	 */
-	xtalk_widgetdev_enable(pcibr_soft->bs_conn, slot);
-
-	/* Set the reset slot bit in the bridge's wid control register
-	 * to reset the PCI slot 
-	 */
-	bridge = pcibr_soft->bs_base;
-
-	/* Read the bridge widget control and clear out the reset pin
-	 * bit for the corresponding slot. 
-	 */
-	tmp = ctrlreg = bridge->b_wid_control;
-
-	tmp &= ~BRIDGE_CTRL_RST_PIN(slot); 
-
-	bridge->b_wid_control = tmp;
-	tmp = bridge->b_wid_control;
-
-	/* Restore the old control register back.
-	 * NOTE : PCI card gets reset when the reset pin bit
-	 * changes from 0 (set above) to 1 (going to be set now).
-	 */
-
-	bridge->b_wid_control = ctrlreg;
-
-	/* Flush the write buffers if any !! */
-	wrb_flush = &(bridge->b_wr_req_buf[slot].reg);
-	while (*wrb_flush);
-
-	return(0);
-}
-#endif
-
 #define PROBE_LOCK 0	/* FIXME: we're attempting to lock around accesses
 			 * to b_int_enable.   This hangs pcibr_probe_slot()
 			 */
@@ -627,7 +509,7 @@
  * 	information associated with this particular PCI device.
  */
 int
-pcibr_slot_info_init(devfs_handle_t 	pcibr_vhdl,
+pcibr_slot_info_init(vertex_hdl_t 	pcibr_vhdl,
 		     pciio_slot_t 	slot)
 {
     pcibr_soft_t	    pcibr_soft;
@@ -650,7 +532,7 @@
     int			    nfunc;
     pciio_function_t	    rfunc;
     int			    func;
-    devfs_handle_t	    conn_vhdl;
+    vertex_hdl_t	    conn_vhdl;
     pcibr_soft_slot_t	    slotp;
     
     /* Get the basic software information required to proceed */
@@ -669,10 +551,6 @@
 	return(0);    
     }
 
-    /* Check for a slot with any system critical functions */
-    if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(EPERM);
-
     /* Try to read the device-id/vendor-id from the config space */
     cfgw = pcibr_slot_config_addr(bridge, slot, 0);
 
@@ -701,7 +579,7 @@
     if (vendor == 0xFFFF) 
 	return(ENODEV);			
     
-    htype = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1);
+    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
     nfunc = 1;
     rfunc = PCIIO_FUNC_NONE;
     pfail = 0;
@@ -750,7 +628,7 @@
 	    cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
 	    
 	    device = 0xFFFF & (idword >> 16);
-	    htype = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1);
+	    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
 	    rfunc = func;
 	}
 	htype &= 0x7f;
@@ -803,23 +681,17 @@
 	 * 'min_gnt' and attempt to calculate a latency time. 
 	 *
 	 * NOTE: For now if the device is on the 'real time' arbitration
-	 * ring we dont set the latency timer.  
+	 * ring we don't set the latency timer.  
 	 *
 	 * WAR: SGI's IOC3 and RAD devices target abort if you write a 
 	 * single byte into their config space.  So don't set the Latency
 	 * Timer for these devices
 	 */
 
-	lt_time = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_LATENCY_TIMER, 1);
+	lt_time = do_pcibr_config_get(cfgw, PCI_CFG_LATENCY_TIMER, 1);
 
 	if ((lt_time == 0) && !(bridge->b_device[slot].reg & BRIDGE_DEV_RT) &&
-	    !((vendor == IOC3_VENDOR_ID_NUM) && 
-	      (
-#ifdef PIC_LATER
-	       (device == IOC3_DEVICE_ID_NUM) ||
-	       (device == LINC_DEVICE_ID_NUM) ||
-#endif
-	       (device == 0x5 /* RAD_DEV */)))) {
+				       (device == 0x5 /* RAD_DEV */)) {
 	     unsigned	min_gnt;
 	     unsigned	min_gnt_mult;
 	    
@@ -827,7 +699,7 @@
 	     * needs in increments of 250ns.  But latency timer is in
 	     * PCI clock cycles, so a conversion is needed.
 	     */
-	    min_gnt = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_MIN_GNT, 1);
+	    min_gnt = do_pcibr_config_get(cfgw, PCI_MIN_GNT, 1);
 
 	    if (IS_133MHZ(pcibr_soft))
 		min_gnt_mult = 32;	/* 250ns @ 133MHz in clocks */
@@ -843,7 +715,7 @@
 	    else
 		lt_time = 4 * min_gnt_mult;	  /* 1 micro second */
 
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_LATENCY_TIMER, 1, lt_time);
+	    do_pcibr_config_set(cfgw, PCI_CFG_LATENCY_TIMER, 1, lt_time);
 
 	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl,
                     "pcibr_slot_info_init: set Latency Timer for slot=%d, "
@@ -851,12 +723,27 @@
 		    PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func, lt_time));
 	}
 
-	/* Get the PCI-X capability if running in PCI-X mode.  If the func
-	 * doesnt have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE
-	 * pcibr_info struct so the device driver for that function is not
-	 * called.
+
+	/* In our architecture the setting of the cacheline size isn't 
+	 * beneficial for cards in PCI mode, but in PCI-X mode devices
+	 * can optionally use the cacheline size value for internal 
+	 * device optimizations    (See 7.1.5 of the PCI-X v1.0 spec).
+	 * NOTE: cachline size is in doubleword increments
 	 */
 	if (IS_PCIX(pcibr_soft)) {
+	    if (!do_pcibr_config_get(cfgw, PCI_CFG_CACHE_LINE, 1)) {
+		do_pcibr_config_set(cfgw, PCI_CFG_CACHE_LINE, 1, 0x20);
+		PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl,
+			"pcibr_slot_info_init: set CacheLine for slot=%d, "
+			"func=%d, to 0x20\n",
+			PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func));
+	    }
+
+	    /* Get the PCI-X capability if running in PCI-X mode.  If the func
+	     * doesnt have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE
+	     * pcibr_info struct so the device driver for that function is not
+	     * called.
+	     */
 	    if (!(pcix_cap = pcibr_find_capability(cfgw, PCI_CAP_PCIX))) {
 		printk(KERN_WARNING
 #if defined(SUPPORT_PRINTING_V_FORMAT)
@@ -898,7 +785,7 @@
 	if (func == 0)
 	    slotp->slot_conn = conn_vhdl;
 
-	cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4);
+	cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
 	
 	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
 
@@ -949,7 +836,7 @@
 	     * this could be pushed up into pciio, when we
 	     * start supporting more PCI providers.
 	     */
-	    base = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4);
+	    base = do_pcibr_config_get(wptr, (win * 4), 4);
 
 	    if (base & PCI_BA_IO_SPACE) {
 		/* BASE is in I/O space. */
@@ -975,7 +862,7 @@
 		} else if (base & 0xC0000000) {
 		    base = 0;	/* outside permissable range */
 		} else if ((code == PCI_BA_MEM_64BIT) &&
-			   (do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, ((win + 1)*4), 4) != 0)) {
+			   (do_pcibr_config_get(wptr, ((win + 1)*4), 4) != 0)) {
 		    base = 0;	/* outside permissable range */
 		}
 	    }
@@ -983,8 +870,8 @@
 	    if (base != 0) {	/* estimate size */
 		size = base & -base;
 	    } else {		/* calculate size */
-		do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, ~0);    /* write 1's */
-		size = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4); /* read back */
+		do_pcibr_config_set(wptr, (win * 4), 4, ~0);    /* write 1's */
+		size = do_pcibr_config_get(wptr, (win * 4), 4); /* read back */
 		size &= mask;	/* keep addr */
 		size &= -size;	/* keep lsbit */
 		if (size == 0)
@@ -995,45 +882,9 @@
 	    pcibr_info->f_window[win].w_base = base;
 	    pcibr_info->f_window[win].w_size = size;
 
-#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM)
-	    /*
-	     * IOC3 BASE_ADDR* BUG WORKAROUND
-	     *
-	     
-	     * If we write to BASE1 on the IOC3, the
-	     * data in BASE0 is replaced. The
-	     * original workaround was to remember
-	     * the value of BASE0 and restore it
-	     * when we ran off the end of the BASE
-	     * registers; however, a later
-	     * workaround was added (I think it was
-	     * rev 1.44) to avoid setting up
-	     * anything but BASE0, with the comment
-	     * that writing all ones to BASE1 set
-	     * the enable-parity-error test feature
-	     * in IOC3's SCR bit 14.
-	     *
-	     * So, unless we defer doing any PCI
-	     * space allocation until drivers
-	     * attach, and set up a way for drivers
-	     * (the IOC3 in paricular) to tell us
-	     * generically to keep our hands off
-	     * BASE registers, we gotta "know" about
-	     * the IOC3 here.
-	     *
-	     * Too bad the PCI folks didn't reserve the
-	     * all-zero value for 'no BASE here' (it is a
-	     * valid code for an uninitialized BASE in
-	     * 32-bit PCI memory space).
-	     */
-	    
-	    if ((vendor == IOC3_VENDOR_ID_NUM) &&
-		(device == IOC3_DEVICE_ID_NUM))
-		break;
-#endif
 	    if (code == PCI_BA_MEM_64BIT) {
 		win++;		/* skip upper half */
-		do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, 0);  /* must be zero */
+		do_pcibr_config_set(wptr, (win * 4), 4, 0);  /* must be zero */
 	    }
 	}				/* next win */
     }				/* next func */
@@ -1056,7 +907,7 @@
     int			defend_against_circular_linkedlist = 0;
 
     /* Check to see if there is a capabilities pointer in the cfg header */
-    if (!(do_pcibr_config_get(1, cfgw, PCI_CFG_STATUS, 2) & PCI_STAT_CAP_LIST)) {
+    if (!(do_pcibr_config_get(cfgw, PCI_CFG_STATUS, 2) & PCI_STAT_CAP_LIST)) {
 	return (NULL);
     }
 
@@ -1067,14 +918,14 @@
      * significant bits of the next pointer must be ignored,  so we mask
      * with 0xfc).
      */
-    cap_nxt = (do_pcibr_config_get(1, cfgw, PCI_CAPABILITIES_PTR, 1) & 0xfc);
+    cap_nxt = (do_pcibr_config_get(cfgw, PCI_CAPABILITIES_PTR, 1) & 0xfc);
 
     while (cap_nxt && (defend_against_circular_linkedlist <= 48)) {
-	cap_id = do_pcibr_config_get(1, cfgw, cap_nxt, 1);
+	cap_id = do_pcibr_config_get(cfgw, cap_nxt, 1);
 	if (cap_id == capability) {
 	    return ((cfg_p)((char *)cfgw + cap_nxt));
 	}
-	cap_nxt = (do_pcibr_config_get(1, cfgw, cap_nxt+1, 1) & 0xfc);
+	cap_nxt = (do_pcibr_config_get(cfgw, cap_nxt+1, 1) & 0xfc);
 	defend_against_circular_linkedlist++;
     }
 
@@ -1087,7 +938,7 @@
  * 	with a particular PCI device.
  */
 int
-pcibr_slot_info_free(devfs_handle_t pcibr_vhdl,
+pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl,
                      pciio_slot_t slot)
 {
     pcibr_soft_t	pcibr_soft;
@@ -1223,20 +1074,21 @@
  * 	the base registers in the card.
  */
 int
-pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,
+pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl,
 			   pciio_slot_t	slot)
 {
     pcibr_soft_t	 pcibr_soft;
     pcibr_info_h	 pcibr_infoh;
     pcibr_info_t	 pcibr_info;
     bridge_t		*bridge;
-    size_t               align_slot;
     iopaddr_t            mask;
     int		       	 nbars;
     int		       	 nfunc;
     int			 func;
     int			 win;
     int                  rc = 0;
+    int			 align;
+    int			 align_slot;
 
     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
 
@@ -1275,7 +1127,8 @@
      * the entire "lo" area is only a
      * megabyte, total ...
      */
-    align_slot = (slot < 2) ? 0x200000 : 0x100000;
+    align_slot = 0x100000;
+    align = align_slot;
 
     for (func = 0; func < nfunc; ++func) {
 	cfg_p                   cfgw;
@@ -1300,7 +1153,7 @@
         cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
 	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
 
-	if ((do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0)
+	if ((do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0)
 	    nbars = 2;
 	else
 	    nbars = PCI_CFG_BASE_ADDRS;
@@ -1333,23 +1186,24 @@
 		continue;		/* already allocated */
 	    }
 
+	    align = (win) ? size : align_slot; 
+
+	    if (align < _PAGESZ)
+		align = _PAGESZ;        /* ie. 0x00004000 */
+ 
 	    switch (space) {
 	    case PCIIO_SPACE_IO:
                 base = pcibr_bus_addr_alloc(pcibr_soft,
                                             &pcibr_info->f_window[win],
                                             PCIIO_SPACE_IO,
-                                            0, size, align_slot);
+                                            0, size, align);
                 if (!base)
                     rc = ENOSPC;
 		break;
 		
 	    case PCIIO_SPACE_MEM:
-		if ((do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4) &
+		if ((do_pcibr_config_get(wptr, (win * 4), 4) &
 		     PCI_BA_MEM_LOCATION) == PCI_BA_MEM_1MEG) {
-                    int align = size;           /* ie. 0x00001000 */
-                    
-                    if (align < _PAGESZ)
-                        align = _PAGESZ;        /* ie. 0x00004000 */
  
 		    /* allocate from 20-bit PCI space */
                     base = pcibr_bus_addr_alloc(pcibr_soft,
@@ -1363,7 +1217,7 @@
                     base = pcibr_bus_addr_alloc(pcibr_soft,
                                                 &pcibr_info->f_window[win],
                                                 PCIIO_SPACE_MEM32,
-                                                0, size, align_slot);
+                                                0, size, align);
 		    if (!base) 
 			rc = ENOSPC;
 		}
@@ -1377,7 +1231,7 @@
 			    PCIBR_DEVICE_TO_SLOT(pcibr_soft,slot), win, space));
 	    }
 	    pcibr_info->f_window[win].w_base = base;
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, base);
+	    do_pcibr_config_set(wptr, (win * 4), 4, base);
 
 #if defined(SUPPORT_PRINTING_R_FORMAT)
 	    if (pcibr_debug_mask & PCIBR_DEBUG_BAR) {
@@ -1405,26 +1259,22 @@
 
 	/*
 	 * Allocate space for the EXPANSION ROM
-	 * NOTE: DO NOT DO THIS ON AN IOC3,
-	 * as it blows the system away.
 	 */
 	base = size = 0;
-	if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) ||
-	    (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) {
-
+	{
 	    wptr = cfgw + PCI_EXPANSION_ROM / 4;
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4, 0xFFFFF000);
-	    mask = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4);
+	    do_pcibr_config_set(wptr, 0, 4, 0xFFFFF000);
+	    mask = do_pcibr_config_get(wptr, 0, 4);
 	    if (mask & 0xFFFFF000) {
 		size = mask & -mask;
                 base = pcibr_bus_addr_alloc(pcibr_soft,
                                             &pcibr_info->f_rwindow,
                                             PCIIO_SPACE_MEM32, 
-                                            0, size, align_slot);
+                                            0, size, align);
 		if (!base)
 		    rc = ENOSPC;
 		else {
-		    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4, base);
+		    do_pcibr_config_set(wptr, 0, 4, base);
 		    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_BAR, pcibr_vhdl,
 				"pcibr_slot_addr_space_init: slot=%d, func=%d, "
 				"ROM in [0x%X..0x%X], allocated by pcibr\n",
@@ -1435,7 +1285,7 @@
 	}
 	pcibr_info->f_rbase = base;
 	pcibr_info->f_rsize = size;
-	
+
 	/*
 	 * if necessary, update the board's
 	 * command register to enable decoding
@@ -1449,7 +1299,7 @@
 	/*
 	 * The Adaptec 1160 FC Controller WAR #767995:
 	 * The part incorrectly ignores the upper 32 bits of a 64 bit
-	 * address when decoding references to it's registers so to
+	 * address when decoding references to its registers so to
 	 * keep it from responding to a bus cycle that it shouldn't
 	 * we only use I/O space to get at it's registers.  Don't
 	 * enable memory space accesses on that PCI device.
@@ -1463,7 +1313,7 @@
 
 	pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER;
 
-	pci_cfg_cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4);
+	pci_cfg_cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
 
 #if PCI_FBBE	/* XXX- check here to see if dev can do fast-back-to-back */
 	if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP))
@@ -1471,7 +1321,7 @@
 #endif
 	pci_cfg_cmd_reg &= 0xFFFF;
 	if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg)
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4, 
+	    do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, 
 				pci_cfg_cmd_reg | pci_cfg_cmd_reg_add);
     }				/* next func */
     return(rc);
@@ -1483,7 +1333,7 @@
  */
 
 int
-pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,
+pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl,
 		       pciio_slot_t slot)
 {
     pcibr_soft_t	 pcibr_soft;
@@ -1525,8 +1375,6 @@
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DEVREG, pcibr_vhdl,
 		"pcibr_slot_device_init: Device(%d): %R\n",
 		slot, devreg, device_bits));
-#else
-    printk("pcibr_slot_device_init: Device(%d) 0x%x\n", slot, devreg);
 #endif
     return(0);
 }
@@ -1536,7 +1384,7 @@
  *	Setup the host/guest relations for a PCI slot.
  */
 int
-pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,
+pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl,
 			   pciio_slot_t	slot)
 {
     pcibr_soft_t	pcibr_soft;
@@ -1605,18 +1453,17 @@
  * 	card in this slot.
  */
 int
-pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl,
 			      pciio_slot_t slot,
 			      int          drv_flags)
 {
     pcibr_soft_t	pcibr_soft;
     pcibr_info_h	pcibr_infoh;
     pcibr_info_t	pcibr_info;
-    async_attach_t	aa = NULL;
     int			func;
-    devfs_handle_t	xconn_vhdl, conn_vhdl;
+    vertex_hdl_t	xconn_vhdl, conn_vhdl;
 #ifdef PIC_LATER
-    devfs_handle_t	scsi_vhdl;
+    vertex_hdl_t	scsi_vhdl;
 #endif
     int			nfunc;
     int                 error_func;
@@ -1639,7 +1486,6 @@
     }
     
     xconn_vhdl = pcibr_soft->bs_conn;
-    aa = async_attach_get_info(xconn_vhdl);
 
     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
@@ -1656,13 +1502,6 @@
 
 	conn_vhdl = pcibr_info->f_vertex;
 
-#ifdef LATER
-	/*
-	 * Activate if and when we support cdl.
-	 */
-	if (aa)
-	    async_attach_add_info(conn_vhdl, aa);
-#endif	/* LATER */
 
 	error_func = pciio_device_attach(conn_vhdl, drv_flags);
 
@@ -1728,7 +1567,7 @@
  * 	card in this slot.
  */
 int
-pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl,
 			      pciio_slot_t slot,
 			      int          drv_flags)
 {
@@ -1736,7 +1575,7 @@
     pcibr_info_h	pcibr_infoh;
     pcibr_info_t	pcibr_info;
     int			func;
-    devfs_handle_t	conn_vhdl = GRAPH_VERTEX_NONE;
+    vertex_hdl_t	conn_vhdl = GRAPH_VERTEX_NONE;
     int			nfunc;
     int                 error_func;
     int                 error_slot = 0;
@@ -1811,7 +1650,7 @@
  * 	PCI card on the bus.
  */
 int
-pcibr_slot_attach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_attach(vertex_hdl_t pcibr_vhdl,
 		  pciio_slot_t slot,
 		  int          drv_flags,
 		  char        *l1_msg,
@@ -1850,7 +1689,7 @@
  *	slot-specific freeing that needs to be done.
  */
 int
-pcibr_slot_detach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_detach(vertex_hdl_t pcibr_vhdl,
 		  pciio_slot_t slot,
 		  int          drv_flags,
 		  char        *l1_msg,
@@ -1859,10 +1698,6 @@
     pcibr_soft_t  pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     int		  error;
     
-    /* Make sure that we do not detach a system critical function vertex */
-    if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(PCI_IS_SYS_CRITICAL);
-
     /* Call the device detach function */
     error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
     if (error) {
@@ -1892,61 +1727,6 @@
 }
 
 /*
- * pcibr_is_slot_sys_critical
- *      Check slot for any functions that are system critical.
- *      Return 1 if any are system critical or 0 otherwise.
- *
- *      This function will always return 0 when called by 
- *      pcibr_attach() because the system critical vertices 
- *      have not yet been set in the hwgraph.
- */
-int
-pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,
-                      pciio_slot_t slot)
-{
-    pcibr_soft_t        pcibr_soft;
-    pcibr_info_h        pcibr_infoh;
-    pcibr_info_t        pcibr_info;
-    devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;
-    int                 nfunc;
-    int                 func;
-    boolean_t is_sys_critical_vertex(devfs_handle_t);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (!pcibr_soft)
-	return(EINVAL);
-
-    if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
-	return(EINVAL);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-        pcibr_info = pcibr_infoh[func];
-        if (!pcibr_info)
-            continue;
-
-        if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-            continue;
-
-        conn_vhdl = pcibr_info->f_vertex;
-        if (is_sys_critical_vertex(conn_vhdl)) { 
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-            printk(KERN_WARNING  "%v is a system critical device vertex\n", conn_vhdl);
-#else
-            printk(KERN_WARNING  "%p is a system critical device vertex\n", (void *)conn_vhdl);
-#endif
-            return(1); 
-        }
-
-    }
-
-    return(0);
-}
-
-/*
  * pcibr_probe_slot_pic: read a config space word
  * while trapping any errors; return zero if
  * all went OK, or nonzero if there was an error.
@@ -1984,57 +1764,6 @@
 }
 
 /*
- * pcibr_probe_slot_non_pic: read a config space word
- * while trapping any errors; return zero if
- * all went OK, or nonzero if there was an error.
- * The value read, if any, is passed back
- * through the valp parameter.
- */
-static int
-pcibr_probe_slot_non_pic(bridge_t *bridge,
-                 cfg_p cfg,
-                 unsigned *valp)
-{
-	int                     rv;
-	bridgereg_t             b_old_enable = (bridgereg_t)0, b_new_enable = (bridgereg_t)0;
-	extern int              badaddr_val(volatile void *, int, volatile void *);
-
-        b_old_enable = bridge->b_int_enable;
-        b_new_enable = b_old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-        bridge->b_int_enable = b_new_enable;
-
-	/*
-	 * The xbridge doesn't clear b_err_int_view unless
-	 * multi-err is cleared...
-	 */
-	if (is_xbridge(bridge)) {
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT)
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-	}
-
-        if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {
-	    bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;
-	    (void) bridge->b_wid_tflush;	/* flushbus */
-        }
-	rv = badaddr_val((void *) (((uint64_t)cfg) ^ 4), 4, valp);
-	/*
-	 * The xbridge doesn't set master timeout in b_int_status
-	 * here.  Fortunately it's in error_interrupt_view.
-	 */
-	if (is_xbridge(bridge)) {
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-		rv = 1;		/* unoccupied slot */
-	    }
-	}
-        bridge->b_int_enable = b_old_enable;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    	return(rv);
-}
-
-
-/*
  * pcibr_probe_slot: read a config space word
  * while trapping any errors; return zero if
  * all went OK, or nonzero if there was an error.
@@ -2046,15 +1775,12 @@
 		 cfg_p cfg,
 		 unsigned *valp)
 {
-    if ( is_pic(bridge) )
-	return(pcibr_probe_slot_pic(bridge, cfg, valp));
-    else
-	return(pcibr_probe_slot_non_pic(bridge, cfg, valp));
+    return(pcibr_probe_slot_pic(bridge, cfg, valp));
 }
 
 
 void
-pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
+pcibr_device_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot)
 {
     pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     pcibr_info_t	pcibr_info;
@@ -2079,9 +1805,9 @@
 
         /* Disable memory and I/O BARs */
 	cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
-	cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4);
+	cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
 	cmd_reg &= (PCI_CMD_MEM_SPACE | PCI_CMD_IO_SPACE);
-	do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4, cmd_reg);
+	do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, cmd_reg);
 
         for (bar = 0; bar < PCI_CFG_BASE_ADDRS; bar++) {
             if (pcibr_info->f_window[bar].w_space == PCIIO_SPACE_NONE)
@@ -2142,30 +1868,36 @@
                      pciio_space_t space, int start, int size, int align)
 {
     pciio_win_map_t win_map_p;
+    struct resource *root_resource = NULL;
+    iopaddr_t iopaddr = 0;
 
     switch (space) {
 
         case PCIIO_SPACE_IO:
             win_map_p = &pcibr_soft->bs_io_win_map;
+	    root_resource = &pcibr_soft->bs_io_win_root_resource;
             break;
 
         case PCIIO_SPACE_MEM:
             win_map_p = &pcibr_soft->bs_swin_map;
+	    root_resource = &pcibr_soft->bs_swin_root_resource;
             break;
 
         case PCIIO_SPACE_MEM32:
             win_map_p = &pcibr_soft->bs_mem_win_map;
+	    root_resource = &pcibr_soft->bs_mem_win_root_resource;
             break;
 
         default:
             return 0;
 
     }
-    return pciio_device_win_alloc(win_map_p,
+    iopaddr = pciio_device_win_alloc(root_resource,
 				  win_info_p
 				  ? &win_info_p->w_win_alloc
 				  : NULL,
 				  start, size, align);
+    return(iopaddr);
 }
 
 
@@ -2181,7 +1913,7 @@
  * io_brick_tab[] array defined in ml/SN/iograph.c
  */
 int
-pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl) 
+pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl) 
 {
     pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     xwidgetnum_t	widget = pcibr_soft->bs_xid;
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pciio.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pciio.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pciio.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pciio.c	2003-07-05 18:09:45.000000000 -0700
@@ -4,11 +4,9 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
-#define	USRPCI	0
-
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
@@ -30,27 +28,14 @@
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/io.h>
 #include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/ate_utils.h>
 #include <asm/sn/simulator.h>
 
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
 #define DEBUG_PCIIO
 #undef DEBUG_PCIIO	/* turn this on for yet more console output */
 
 
-#define GET_NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DO_DEL(ptr)	(kfree(ptr))
-
 char                    pciio_info_fingerprint[] = "pciio_info";
 
-cdl_p                   pciio_registry = NULL;
-
 int
 badaddr_val(volatile void *addr, int len, volatile void *ptr)
 {
@@ -97,8 +82,6 @@
 	extern char master_baseio_wid;
 
 	if (master_baseio_nasid < 0) {
-		nasid_t tmp;
-
 		master_baseio_nasid = ia64_sn_get_master_baseio_nasid();
 
 		if ( master_baseio_nasid >= 0 ) {
@@ -109,13 +92,13 @@
 }
 
 int
-hub_dma_enabled(devfs_handle_t xconn_vhdl)
+hub_dma_enabled(vertex_hdl_t xconn_vhdl)
 {
 	return(0);
 }
 
 int
-hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
+hub_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code)
 {
 	return(0);
 }
@@ -153,66 +136,64 @@
  */
 
 #if !defined(DEV_FUNC)
-static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev);
+static pciio_provider_t *pciio_to_provider_fns(vertex_hdl_t dev);
 #endif
 
-pciio_piomap_t          pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
+pciio_piomap_t          pciio_piomap_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
 void                    pciio_piomap_free(pciio_piomap_t);
 caddr_t                 pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t);
 
 void                    pciio_piomap_done(pciio_piomap_t);
-caddr_t                 pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-caddr_t			pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
+caddr_t                 pciio_piotrans_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+caddr_t			pciio_pio_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
 
-iopaddr_t               pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
+iopaddr_t               pciio_piospace_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, size_t, size_t);
+void                    pciio_piospace_free(vertex_hdl_t, pciio_space_t, iopaddr_t, size_t);
 
-pciio_dmamap_t          pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
+pciio_dmamap_t          pciio_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned);
 void                    pciio_dmamap_free(pciio_dmamap_t);
 iopaddr_t               pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-alenlist_t              pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned);
 void                    pciio_dmamap_done(pciio_dmamap_t);
-iopaddr_t               pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
+iopaddr_t               pciio_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
 void			pciio_dmamap_drain(pciio_dmamap_t);
-void			pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void			pciio_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
+void			pciio_dmaaddr_drain(vertex_hdl_t, paddr_t, size_t);
+void			pciio_dmalist_drain(vertex_hdl_t, alenlist_t);
+iopaddr_t               pciio_dma_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
 
-pciio_intr_t            pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+pciio_intr_t            pciio_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t);
 void                    pciio_intr_free(pciio_intr_t);
 int                     pciio_intr_connect(pciio_intr_t, intr_func_t, intr_arg_t);
 void                    pciio_intr_disconnect(pciio_intr_t);
-devfs_handle_t            pciio_intr_cpu_get(pciio_intr_t);
+vertex_hdl_t            pciio_intr_cpu_get(pciio_intr_t);
 
 void			pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t);
 
-void                    pciio_provider_startup(devfs_handle_t);
-void                    pciio_provider_shutdown(devfs_handle_t);
+void                    pciio_provider_startup(vertex_hdl_t);
+void                    pciio_provider_shutdown(vertex_hdl_t);
 
-pciio_endian_t          pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-pciio_priority_t        pciio_priority_set(devfs_handle_t, pciio_priority_t);
-devfs_handle_t            pciio_intr_dev_get(pciio_intr_t);
+pciio_endian_t          pciio_endian_set(vertex_hdl_t, pciio_endian_t, pciio_endian_t);
+pciio_priority_t        pciio_priority_set(vertex_hdl_t, pciio_priority_t);
+vertex_hdl_t            pciio_intr_dev_get(pciio_intr_t);
 
-devfs_handle_t            pciio_pio_dev_get(pciio_piomap_t);
+vertex_hdl_t            pciio_pio_dev_get(pciio_piomap_t);
 pciio_slot_t            pciio_pio_slot_get(pciio_piomap_t);
 pciio_space_t           pciio_pio_space_get(pciio_piomap_t);
 iopaddr_t               pciio_pio_pciaddr_get(pciio_piomap_t);
 ulong                   pciio_pio_mapsz_get(pciio_piomap_t);
 caddr_t                 pciio_pio_kvaddr_get(pciio_piomap_t);
 
-devfs_handle_t            pciio_dma_dev_get(pciio_dmamap_t);
+vertex_hdl_t            pciio_dma_dev_get(pciio_dmamap_t);
 pciio_slot_t            pciio_dma_slot_get(pciio_dmamap_t);
 
-pciio_info_t            pciio_info_chk(devfs_handle_t);
-pciio_info_t            pciio_info_get(devfs_handle_t);
-void                    pciio_info_set(devfs_handle_t, pciio_info_t);
-devfs_handle_t            pciio_info_dev_get(pciio_info_t);
+pciio_info_t            pciio_info_chk(vertex_hdl_t);
+pciio_info_t            pciio_info_get(vertex_hdl_t);
+void                    pciio_info_set(vertex_hdl_t, pciio_info_t);
+vertex_hdl_t            pciio_info_dev_get(pciio_info_t);
 pciio_slot_t            pciio_info_slot_get(pciio_info_t);
 pciio_function_t        pciio_info_function_get(pciio_info_t);
 pciio_vendor_id_t       pciio_info_vendor_id_get(pciio_info_t);
 pciio_device_id_t       pciio_info_device_id_get(pciio_info_t);
-devfs_handle_t            pciio_info_master_get(pciio_info_t);
+vertex_hdl_t            pciio_info_master_get(pciio_info_t);
 arbitrary_info_t        pciio_info_mfast_get(pciio_info_t);
 pciio_provider_t       *pciio_info_pops_get(pciio_info_t);
 error_handler_f	       *pciio_info_efunc_get(pciio_info_t);
@@ -223,30 +204,28 @@
 iopaddr_t		pciio_info_rom_base_get(pciio_info_t);
 size_t			pciio_info_rom_size_get(pciio_info_t);
 
-void                    pciio_init(void);
-int                     pciio_attach(devfs_handle_t);
+int                     pciio_attach(vertex_hdl_t);
 
-void                    pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns);
-void                    pciio_provider_unregister(devfs_handle_t);
-pciio_provider_t       *pciio_provider_fns_get(devfs_handle_t);
+void                    pciio_provider_register(vertex_hdl_t, pciio_provider_t *pciio_fns);
+void                    pciio_provider_unregister(vertex_hdl_t);
+pciio_provider_t       *pciio_provider_fns_get(vertex_hdl_t);
 
 int                     pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned);
-void                    pciio_driver_unregister(char *driver_prefix);
 
-devfs_handle_t            pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
+vertex_hdl_t            pciio_device_register(vertex_hdl_t, vertex_hdl_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
 
-void			pciio_device_unregister(devfs_handle_t);
-pciio_info_t		pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
+void			pciio_device_unregister(vertex_hdl_t);
+pciio_info_t		pciio_device_info_new(pciio_info_t, vertex_hdl_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
 void			pciio_device_info_free(pciio_info_t);
-devfs_handle_t		pciio_device_info_register(devfs_handle_t, pciio_info_t);
-void			pciio_device_info_unregister(devfs_handle_t, pciio_info_t);
-int                     pciio_device_attach(devfs_handle_t, int);
-int			pciio_device_detach(devfs_handle_t, int);
-void                    pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
-
-int                     pciio_reset(devfs_handle_t);
-int                     pciio_write_gather_flush(devfs_handle_t);
-int                     pciio_slot_inuse(devfs_handle_t);
+vertex_hdl_t		pciio_device_info_register(vertex_hdl_t, pciio_info_t);
+void			pciio_device_info_unregister(vertex_hdl_t, pciio_info_t);
+int                     pciio_device_attach(vertex_hdl_t, int);
+int			pciio_device_detach(vertex_hdl_t, int);
+void                    pciio_error_register(vertex_hdl_t, error_handler_f *, error_handler_arg_t);
+
+int                     pciio_reset(vertex_hdl_t);
+int                     pciio_write_gather_flush(vertex_hdl_t);
+int                     pciio_slot_inuse(vertex_hdl_t);
 
 /* =====================================================================
  *    Provider Function Location
@@ -261,7 +240,7 @@
 #if !defined(DEV_FUNC)
 
 static pciio_provider_t *
-pciio_to_provider_fns(devfs_handle_t dev)
+pciio_to_provider_fns(vertex_hdl_t dev)
 {
     pciio_info_t            card_info;
     pciio_provider_t       *provider_fns;
@@ -316,7 +295,7 @@
  */
 
 pciio_piomap_t
-pciio_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
+pciio_piomap_alloc(vertex_hdl_t dev,	/* set up mapping for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
 		   iopaddr_t addr,	/* lowest address (or offset in window) */
@@ -354,7 +333,7 @@
 }
 
 caddr_t
-pciio_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_piotrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
 		    iopaddr_t addr,	/* starting address (or offset in window) */
@@ -366,7 +345,7 @@
 }
 
 caddr_t
-pciio_pio_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_pio_addr(vertex_hdl_t dev,	/* translate for this device */
 	       device_desc_t dev_desc,	/* device descriptor */
 	       pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
 	       iopaddr_t addr,		/* starting address (or offset in window) */
@@ -410,7 +389,7 @@
 }
 
 iopaddr_t
-pciio_piospace_alloc(devfs_handle_t dev,	/* Device requiring space */
+pciio_piospace_alloc(vertex_hdl_t dev,	/* Device requiring space */
 		     device_desc_t dev_desc,	/* Device descriptor */
 		     pciio_space_t space,	/* MEM32/MEM64/IO */
 		     size_t byte_count,	/* Size of mapping */
@@ -423,7 +402,7 @@
 }
 
 void
-pciio_piospace_free(devfs_handle_t dev,	/* Device freeing space */
+pciio_piospace_free(vertex_hdl_t dev,	/* Device freeing space */
 		    pciio_space_t space,	/* Type of space        */
 		    iopaddr_t pciaddr,	/* starting address */
 		    size_t byte_count)
@@ -440,7 +419,7 @@
  */
 
 pciio_dmamap_t
-pciio_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
+pciio_dmamap_alloc(vertex_hdl_t dev,	/* set up mappings for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   size_t byte_count_max,	/* max size of a mapping */
 		   unsigned flags)
@@ -465,15 +444,6 @@
 	(CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
 }
 
-alenlist_t
-pciio_dmamap_list(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_list)
-	(CAST_DMAMAP(pciio_dmamap), alenlist, flags);
-}
-
 void
 pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
 {
@@ -482,7 +452,7 @@
 }
 
 iopaddr_t
-pciio_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_dmatrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    paddr_t paddr,	/* system physical address */
 		    size_t byte_count,	/* length */
@@ -492,18 +462,8 @@
 	(dev, dev_desc, paddr, byte_count, flags);
 }
 
-alenlist_t
-pciio_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
 iopaddr_t
-pciio_dma_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_dma_addr(vertex_hdl_t dev,	/* translate for this device */
 	       device_desc_t dev_desc,	/* device descriptor */
 	       paddr_t paddr,		/* system physical address */
 	       size_t byte_count,	/* length */
@@ -553,14 +513,14 @@
 }
 
 void
-pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
+pciio_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
 {
     DEV_FUNC(dev, dmaaddr_drain)
 	(dev, addr, size);
 }
 
 void
-pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list)
+pciio_dmalist_drain(vertex_hdl_t dev, alenlist_t list)
 {
     DEV_FUNC(dev, dmalist_drain)
 	(dev, list);
@@ -577,10 +537,10 @@
  * Return resource handle in intr_hdl.
  */
 pciio_intr_t
-pciio_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
+pciio_intr_alloc(vertex_hdl_t dev,	/* which Crosstalk device */
 		 device_desc_t dev_desc,	/* device descriptor */
 		 pciio_intr_line_t lines,	/* INTR line(s) to attach */
-		 devfs_handle_t owner_dev)
+		 vertex_hdl_t owner_dev)
 {					/* owner of this interrupt */
     return (pciio_intr_t) DEV_FUNC(dev, intr_alloc)
 	(dev, dev_desc, lines, owner_dev);
@@ -624,7 +584,7 @@
  * Return a hwgraph vertex that represents the CPU currently
  * targeted by an interrupt.
  */
-devfs_handle_t
+vertex_hdl_t
 pciio_intr_cpu_get(pciio_intr_t intr_hdl)
 {
     return INTR_FUNC(intr_hdl, intr_cpu_get)
@@ -663,12 +623,12 @@
  */
 static pciio_info_t
 pciio_cardinfo_get(
-		      devfs_handle_t pciio_vhdl,
+		      vertex_hdl_t pciio_vhdl,
 		      pciio_slot_t pci_slot)
 {
     char                    namebuf[16];
     pciio_info_t	    info = 0;
-    devfs_handle_t	    conn;
+    vertex_hdl_t	    conn;
 
     pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE);
     if (GRAPH_SUCCESS ==
@@ -699,22 +659,16 @@
 /*ARGSUSED */
 int
 pciio_error_handler(
-		       devfs_handle_t pciio_vhdl,
+		       vertex_hdl_t pciio_vhdl,
 		       int error_code,
 		       ioerror_mode_t mode,
 		       ioerror_t *ioerror)
 {
     pciio_info_t            pciio_info;
-    devfs_handle_t            pconn_vhdl;
-#if USRPCI
-    devfs_handle_t            usrpci_v;
-#endif
+    vertex_hdl_t            pconn_vhdl;
     pciio_slot_t            slot;
 
     int                     retval;
-#ifdef EHE_ENABLE
-    error_state_t	    e_state;
-#endif /* EHE_ENABLE */
 
 #if DEBUG && ERROR_DEBUG
     printk("%v: pciio_error_handler\n", pciio_vhdl);
@@ -733,16 +687,6 @@
     if (pciio_info && pciio_info->c_efunc) {
 	pconn_vhdl = pciio_info_dev_get(pciio_info);
 
-#ifdef EHE_ENABLE
-	e_state = error_state_get(pciio_vhdl);
-
-	if (e_state == ERROR_STATE_ACTION)
-	    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);
-
-	if (error_state_set(pconn_vhdl,e_state) == ERROR_RETURN_CODE_CANNOT_SET_STATE)
-	    return(IOERROR_UNHANDLED);
-#endif 
-
 	retval = pciio_info->c_efunc
 	    (pciio_info->c_einfo, error_code, mode, ioerror);
 	if (retval != IOERROR_UNHANDLED)
@@ -770,49 +714,11 @@
 
 		pconn_vhdl = pciio_info_dev_get(pciio_info);
 
-#ifdef EHE_ENABLE
-		e_state = error_state_get(pciio_vhdl);
-
-		if (e_state == ERROR_STATE_ACTION)
-		    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);
-
-		if (error_state_set(pconn_vhdl,e_state) ==
-		    ERROR_RETURN_CODE_CANNOT_SET_STATE)
-		    return(IOERROR_UNHANDLED);
-#endif /* EHE_ENABLE */
-
 		retval = pciio_info->c_efunc
 		    (pciio_info->c_einfo, error_code, mode, ioerror);
 		if (retval != IOERROR_UNHANDLED)
 		    return retval;
 	    }
-
-#if USRPCI
-	    /* If the USRPCI driver is available and
-	     * knows about this connection point,
-	     * deliver the error to it.
-	     *
-	     * OK to use pconn_vhdl here, even though we
-	     * have already UNREF'd it, since we know that
-	     * it is not going away.
-	     */
-	    pconn_vhdl = pciio_info_dev_get(pciio_info);
-	    if (GRAPH_SUCCESS == hwgraph_traverse(pconn_vhdl, EDGE_LBL_USRPCI, &usrpci_v)) {
-		iopaddr_t busaddr;
-		IOERROR_GETVALUE(busaddr, ioerror, busaddr);
-		retval = usrpci_error_handler (usrpci_v, error_code, busaddr);
-		hwgraph_vertex_unref(usrpci_v);
-		if (retval != IOERROR_UNHANDLED) {
-		    /*
-		     * This unref is not needed.  If this code is called often enough,
-		     * the system will crash, due to vertex reference count reaching 0,
-		     * causing vertex to be unallocated.  -jeremy
-		     * hwgraph_vertex_unref(pconn_vhdl);
-		     */
-		    return retval;
-		}
-	    }
-#endif
 	}
     }
 
@@ -829,7 +735,7 @@
  * Startup a crosstalk provider
  */
 void
-pciio_provider_startup(devfs_handle_t pciio_provider)
+pciio_provider_startup(vertex_hdl_t pciio_provider)
 {
     DEV_FUNC(pciio_provider, provider_startup)
 	(pciio_provider);
@@ -839,7 +745,7 @@
  * Shutdown a crosstalk provider
  */
 void
-pciio_provider_shutdown(devfs_handle_t pciio_provider)
+pciio_provider_shutdown(vertex_hdl_t pciio_provider)
 {
     DEV_FUNC(pciio_provider, provider_shutdown)
 	(pciio_provider);
@@ -851,7 +757,7 @@
  * how things will actually appear in memory.
  */
 pciio_endian_t
-pciio_endian_set(devfs_handle_t dev,
+pciio_endian_set(vertex_hdl_t dev,
 		 pciio_endian_t device_end,
 		 pciio_endian_t desired_end)
 {
@@ -880,7 +786,7 @@
  * Specify PCI arbitration priority.
  */
 pciio_priority_t
-pciio_priority_set(devfs_handle_t dev,
+pciio_priority_set(vertex_hdl_t dev,
 		   pciio_priority_t device_prio)
 {
     ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW));
@@ -893,7 +799,7 @@
  * Read value of configuration register
  */
 uint64_t
-pciio_config_get(devfs_handle_t	dev,
+pciio_config_get(vertex_hdl_t	dev,
 		 unsigned	reg,
 		 unsigned	size)
 {
@@ -923,7 +829,7 @@
  * Change value of configuration register
  */
 void
-pciio_config_set(devfs_handle_t	dev,
+pciio_config_set(vertex_hdl_t	dev,
 		 unsigned	reg,
 		 unsigned	size,
 		 uint64_t	value)
@@ -953,7 +859,7 @@
  * Issue a hardware reset to a card.
  */
 int
-pciio_reset(devfs_handle_t dev)
+pciio_reset(vertex_hdl_t dev)
 {
     return DEV_FUNC(dev, reset) (dev);
 }
@@ -962,19 +868,19 @@
  * flush write gather buffers
  */
 int
-pciio_write_gather_flush(devfs_handle_t dev)
+pciio_write_gather_flush(vertex_hdl_t dev)
 {
     return DEV_FUNC(dev, write_gather_flush) (dev);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_intr_dev_get(pciio_intr_t pciio_intr)
 {
     return (pciio_intr->pi_dev);
 }
 
 /****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 pciio_pio_dev_get(pciio_piomap_t pciio_piomap)
 {
     return (pciio_piomap->pp_dev);
@@ -1011,7 +917,7 @@
 }
 
 /****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap)
 {
     return (pciio_dmamap->pd_dev);
@@ -1026,7 +932,7 @@
 /****** Generic pci slot information interfaces ******/
 
 pciio_info_t
-pciio_info_chk(devfs_handle_t pciio)
+pciio_info_chk(vertex_hdl_t pciio)
 {
     arbitrary_info_t        ainfo = 0;
 
@@ -1035,7 +941,7 @@
 }
 
 pciio_info_t
-pciio_info_get(devfs_handle_t pciio)
+pciio_info_get(vertex_hdl_t pciio)
 {
     pciio_info_t            pciio_info;
 
@@ -1051,18 +957,17 @@
 #endif /* DEBUG_PCIIO */
 
     if ((pciio_info != NULL) &&
-	(pciio_info->c_fingerprint != pciio_info_fingerprint)
-	&& (pciio_info->c_fingerprint != NULL)) {
+        (pciio_info->c_fingerprint != pciio_info_fingerprint)
+        && (pciio_info->c_fingerprint != NULL)) {
 
-	return((pciio_info_t)-1); /* Should panic .. */
+        return((pciio_info_t)-1); /* Should panic .. */
     }
-	
 
     return pciio_info;
 }
 
 void
-pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info)
+pciio_info_set(vertex_hdl_t pciio, pciio_info_t pciio_info)
 {
     if (pciio_info != NULL)
 	pciio_info->c_fingerprint = pciio_info_fingerprint;
@@ -1076,7 +981,7 @@
 			 (arbitrary_info_t) pciio_info);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_info_dev_get(pciio_info_t pciio_info)
 {
     return (pciio_info->c_vertex);
@@ -1106,7 +1011,7 @@
     return (pciio_info->c_device);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_info_master_get(pciio_info_t pciio_info)
 {
     return (pciio_info->c_master);
@@ -1172,47 +1077,12 @@
  */
 
 /*
- *    pciioinit: called once during device driver
- *      initializtion if this driver is configured into
- *      the system.
- */
-void
-pciio_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("pciio_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (pciio_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_PCI, "vendor", "device");
-	if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(pciio_registry != NULL);
-}
-
-/*
  *    pciioattach: called for each vertex in the graph
  *      that is a PCI provider.
  */
 /*ARGSUSED */
 int
-pciio_attach(devfs_handle_t pciio)
+pciio_attach(vertex_hdl_t pciio)
 {
 #if DEBUG && ATTACH_DEBUG
 #if defined(SUPPORT_PRINTING_V_FORMAT)
@@ -1228,7 +1098,7 @@
  * Associate a set of pciio_provider functions with a vertex.
  */
 void
-pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns)
+pciio_provider_register(vertex_hdl_t provider, pciio_provider_t *pciio_fns)
 {
     hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns);
 }
@@ -1237,7 +1107,7 @@
  * Disassociate a set of pciio_provider functions with a vertex.
  */
 void
-pciio_provider_unregister(devfs_handle_t provider)
+pciio_provider_unregister(vertex_hdl_t provider)
 {
     arbitrary_info_t        ainfo;
 
@@ -1249,7 +1119,7 @@
  * provider.
  */
 pciio_provider_t       *
-pciio_provider_fns_get(devfs_handle_t provider)
+pciio_provider_fns_get(vertex_hdl_t provider)
 {
     arbitrary_info_t        ainfo = 0;
 
@@ -1265,86 +1135,13 @@
 			 char *driver_prefix,
 			 unsigned flags)
 {
-    /* a driver's init routine might call
-     * pciio_driver_register before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    return cdl_add_driver(pciio_registry,
-			  vendor_id, device_id,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Remove an initialization function.
- */
-void
-pciio_driver_unregister(
-			   char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called register; so
-     * we can assume we have a registry here.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    cdl_del_driver(pciio_registry, driver_prefix, NULL);
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being registered.
- */
-void
-pciio_driver_reg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being unregistered.
- */
-void
-pciio_driver_unreg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-pciio_iterate(char *driver_prefix,
-	      pciio_iter_f * func)
-{
-    /* a driver's init routine might call
-     * pciio_iterate before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    ASSERT(pciio_registry != NULL);
-
-    cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func);
+	return(0);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_device_register(
-		devfs_handle_t connectpt,	/* vertex for /hw/.../pciio/%d */
-		devfs_handle_t master,	/* card's master ASIC (PCI provider) */
+		vertex_hdl_t connectpt,	/* vertex for /hw/.../pciio/%d */
+		vertex_hdl_t master,	/* card's master ASIC (PCI provider) */
 		pciio_slot_t slot,	/* card's slot */
 		pciio_function_t func,	/* card's func */
 		pciio_vendor_id_t vendor_id,
@@ -1356,7 +1153,7 @@
 }
 
 void
-pciio_device_unregister(devfs_handle_t pconn)
+pciio_device_unregister(vertex_hdl_t pconn)
 {
     DEV_FUNC(pconn,device_unregister)(pconn);
 }
@@ -1364,14 +1161,14 @@
 pciio_info_t
 pciio_device_info_new(
 		pciio_info_t pciio_info,
-		devfs_handle_t master,
+		vertex_hdl_t master,
 		pciio_slot_t slot,
 		pciio_function_t func,
 		pciio_vendor_id_t vendor_id,
 		pciio_device_id_t device_id)
 {
     if (!pciio_info)
-	GET_NEW(pciio_info);
+	NEW(pciio_info);
     ASSERT(pciio_info != NULL);
 
     pciio_info->c_slot = slot;
@@ -1396,14 +1193,14 @@
     BZERO((char *)pciio_info,sizeof(pciio_info));
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_device_info_register(
-		devfs_handle_t connectpt,		/* vertex at center of bus */
+		vertex_hdl_t connectpt,		/* vertex at center of bus */
 		pciio_info_t pciio_info)	/* details about the connectpt */
 {
     char		name[32];
-    devfs_handle_t	pconn;
-    int device_master_set(devfs_handle_t, devfs_handle_t);
+    vertex_hdl_t	pconn;
+    int device_master_set(vertex_hdl_t, vertex_hdl_t);
 
     pciio_slot_func_to_name(name,
 			    pciio_info->c_slot,
@@ -1429,25 +1226,15 @@
      */
 
     device_master_set(pconn, pciio_info->c_master);
-
-#if USRPCI
-    /*
-     * Call into usrpci provider to let it initialize for
-     * the given slot.
-     */
-    if (pciio_info->c_slot != PCIIO_SLOT_NONE)
-	usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);
-#endif
-
     return pconn;
 }
 
 void
-pciio_device_info_unregister(devfs_handle_t connectpt,
+pciio_device_info_unregister(vertex_hdl_t connectpt,
 			     pciio_info_t pciio_info)
 {
     char		name[32];
-    devfs_handle_t	pconn;
+    vertex_hdl_t	pconn;
 
     if (!pciio_info)
 	return;
@@ -1470,7 +1257,7 @@
 /* Add the pci card inventory information to the hwgraph
  */
 static void
-pciio_device_inventory_add(devfs_handle_t pconn_vhdl)
+pciio_device_inventory_add(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
 
@@ -1488,7 +1275,7 @@
 
 /*ARGSUSED */
 int
-pciio_device_attach(devfs_handle_t pconn,
+pciio_device_attach(vertex_hdl_t pconn,
 		    int          drv_flags)
 {
     pciio_info_t            pciio_info;
@@ -1507,92 +1294,18 @@
      * pciio_init) have been called; so we
      * can assume here that we have a registry.
      */
-    ASSERT(pciio_registry != NULL);
 
-    return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));
+    return(cdl_add_connpt(vendor_id, device_id, pconn, drv_flags));
 }
 
 int
-pciio_device_detach(devfs_handle_t pconn,
+pciio_device_detach(vertex_hdl_t pconn,
 		    int          drv_flags)
 {
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_del_connpt(pciio_registry, vendor_id, device_id,
-		          pconn, drv_flags));
-
-}
-
-/* SN2 */
-/*
- * Allocate (if necessary) and initialize a PCI window mapping structure.
- */
-pciio_win_map_t
-pciio_device_win_map_new(pciio_win_map_t win_map,
-			 size_t region_size,
-			 size_t page_size)
-{
-	ASSERT((page_size & (page_size - 1)) == 0);
-	ASSERT((region_size & (page_size - 1)) == 0);
-
-	if (win_map == NULL)
-		NEW(win_map);
-
-	/*
-	 * The map array tracks the free ``pages'' in the region.  The worst
-	 * case scenario is when every other page in the region is free --
-	 * e.i. maximum fragmentation.  This leads to (max pages + 1) / 2 + 1
-	 * map entries.  The first "+1" handles the divide by 2 rounding; the
-	 * second handles the need for an end marker sentinel.
-	 */
-	win_map->wm_map = rmallocmap((region_size / page_size + 1) / 2 + 1);
-	win_map->wm_page_size = page_size;
-	ASSERT(win_map->wm_map != NULL);
-
-	return win_map;
-}
-
-/*
- * Free resources associated with a PCI window mapping structure.
- */
-extern void
-pciio_device_win_map_free(pciio_win_map_t win_map)
-{
-	rmfreemap(win_map->wm_map);
-	bzero(win_map, sizeof *win_map);
+    return(0);
 }
 
 /*
- * Populate window map with specified free range.
- */
-void
-pciio_device_win_populate(pciio_win_map_t win_map,
-                          iopaddr_t ioaddr,
-                          size_t size)
-{
-	ASSERT((size & (win_map->wm_page_size - 1)) == 0);
-	ASSERT((ioaddr & (win_map->wm_page_size - 1)) == 0);
-
-	rmfree(win_map->wm_map,
-	       size / win_map->wm_page_size,
-	       (unsigned long)ioaddr / win_map->wm_page_size);
-	       
-}
-/*
  * Allocate space from the specified PCI window mapping resource.  On
  * success record information about the allocation in the supplied window
  * allocation cookie (if non-NULL) and return the address of the allocated
@@ -1609,94 +1322,36 @@
  * and alignment.
  */
 iopaddr_t
-pciio_device_win_alloc(pciio_win_map_t win_map,
+pciio_device_win_alloc(struct resource *root_resource,
 		       pciio_win_alloc_t win_alloc,
 		       size_t start, size_t size, size_t align)
 {
-	unsigned long base;
 
-#ifdef PIC_LATER
-	ASSERT((size & (size - 1)) == 0);
-	ASSERT((align & (align - 1)) == 0);
+	struct resource *new_res;
+	int status = 0;
 
-	/*
-	 * Convert size and alignment to pages.  If size is greated than the
-	 * requested alignment, we bump the alignment up to size; otherwise
-	 * convert the size into a multiple of the alignment request.
-	 */
-	size = (size + win_map->wm_page_size - 1) / win_map->wm_page_size;
-	align = align / win_map->wm_page_size;
-	if (size > align)
-		align = size;
-	else
-		size = (size + align - 1) & ~(align - 1);
-
-	/* XXXX */
-	base = rmalloc_align(win_map->wm_map, size, align, VM_NOSLEEP);
-	if (base == RMALLOC_FAIL)
-		return((iopaddr_t)NULL);
-#else
-    int                 index_page, index_page_align;
-    int                 align_pages, size_pages;
-    int                 alloc_pages, free_pages;
-    int                 addr_align;
-
-    /* Convert PCI bus alignment from bytes to pages */
-    align_pages = align / win_map->wm_page_size;
-
-    /* Convert PCI request from bytes to pages */
-    size_pages = (size / win_map->wm_page_size) +
-                  ((size % win_map->wm_page_size) ? 1 : 0);
-
-    /* Align address with the larger of the size or the requested slot align */
-    if (size_pages > align_pages)
-        align_pages = size_pages;
-  
-    /*
-     * Avoid wasting space by aligning - 1; this will prevent crossing
-     * another alignment boundary.
-     */
-    alloc_pages = size_pages + (align_pages - 1);
+	new_res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP);
 
-    /* Allocate PCI bus space in pages */
-    index_page = (int) rmalloc(win_map->wm_map,
-                               (size_t) alloc_pages);
-
-    /* Error if no PCI bus address space available */
-    if (!index_page)
-        return 0;
-
-    /* PCI bus address index starts at 0 */
-    index_page--;
-
-    /* Align the page offset as requested */
-    index_page_align = (index_page + (align_pages - 1)) -
-                       ((index_page + (align_pages - 1)) % align_pages);
-
-    free_pages = (align_pages - 1) - (index_page_align - index_page);
-
-    /* Free unused PCI bus pages adjusting the index to start at 1 */
-    rmfree(win_map->wm_map, 
-           free_pages,
-           (index_page_align + 1) + size_pages);
-
-    /* Return aligned PCI bus space in bytes */ 
-    addr_align = (index_page_align * win_map->wm_page_size); 
-    base = index_page;
-    size = alloc_pages - free_pages;
-#endif	/* PIC_LATER */
+	status = allocate_resource( root_resource, new_res,
+				    size, align /* Min start addr. */,
+				    root_resource->end, align,
+				    NULL, NULL);
+	if (status) {
+		kfree(new_res);
+		return((iopaddr_t) NULL);
+	}
 
 	/*
 	 * If a window allocation cookie has been supplied, use it to keep
 	 * track of all the allocated space assigned to this window.
 	 */
 	if (win_alloc) {
-		win_alloc->wa_map = win_map;
-		win_alloc->wa_base = base;
+		win_alloc->wa_resource = new_res;
+		win_alloc->wa_base = new_res->start;
 		win_alloc->wa_pages = size;
 	}
 
-	return base * win_map->wm_page_size;
+	return new_res->start;;
 }
 
 /*
@@ -1706,10 +1361,16 @@
 void
 pciio_device_win_free(pciio_win_alloc_t win_alloc)
 {
-	if (win_alloc->wa_pages)
-		rmfree(win_alloc->wa_map->wm_map,
-		       win_alloc->wa_pages,
-		       win_alloc->wa_base);
+
+	int status = 0;
+
+	if (win_alloc->wa_resource) {
+		status = release_resource(win_alloc->wa_resource);
+		if (!status)
+			kfree(win_alloc->wa_resource);
+		else
+			BUG();
+	}
 }
 
 /*
@@ -1728,7 +1389,7 @@
  * cooperating drivers, well, cooperate ...
  */
 void
-pciio_error_register(devfs_handle_t pconn,
+pciio_error_register(vertex_hdl_t pconn,
 		     error_handler_f *efunc,
 		     error_handler_arg_t einfo)
 {
@@ -1746,7 +1407,7 @@
  * vhdl is the vertex for the slot
  */
 int
-pciio_slot_inuse(devfs_handle_t pconn_vhdl)
+pciio_slot_inuse(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
 
@@ -1763,7 +1424,7 @@
 }
 
 int
-pciio_dma_enabled(devfs_handle_t pconn_vhdl)
+pciio_dma_enabled(vertex_hdl_t pconn_vhdl)
 {
 	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);
 }
@@ -1777,7 +1438,7 @@
 
 /*
  * These are complementary Linux interfaces that takes in a pci_dev * as the 
- * first arguement instead of devfs_handle_t.
+ * first arguement instead of vertex_hdl_t.
  */
 iopaddr_t               snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned);
 pciio_dmamap_t          snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned);
@@ -1800,7 +1461,7 @@
 	int *count_vchan0,
 	int *count_vchan1)
 {
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+	vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 
 	return pcibr_rrb_alloc(dev, count_vchan0, count_vchan1);
 }
@@ -1811,7 +1472,7 @@
 	pciio_endian_t device_end,
 	pciio_endian_t desired_end)
 {
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+	vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 	
 	return DEV_FUNC(dev, endian_set)
 		(dev, device_end, desired_end);
@@ -1825,7 +1486,7 @@
                     unsigned flags)
 {                                       /* defined in dma.h */
 
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+    vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 
     /*
      * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be 
@@ -1842,7 +1503,7 @@
                    unsigned flags)
 {                                       /* defined in dma.h */
 
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+    vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 
     /*
      * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pic.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pic.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/pic.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/pic.c	2003-07-05 18:09:45.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,51 +27,195 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
+extern char *bcopy(const char * src, char * dest, int count);
+
 
 #define PCI_BUS_NO_1 1
 
-int pic_devflag = D_MP;
+extern int pcibr_attach2(vertex_hdl_t, bridge_t *, vertex_hdl_t, int, pcibr_soft_t *);
+extern void pcibr_driver_reg_callback(vertex_hdl_t, int, int, int);
+extern void pcibr_driver_unreg_callback(vertex_hdl_t, int, int, int);
 
-extern int pcibr_attach2(devfs_handle_t, bridge_t *, devfs_handle_t, int, pcibr_soft_t *);
-extern void pcibr_driver_reg_callback(devfs_handle_t, int, int, int);
-extern void pcibr_driver_unreg_callback(devfs_handle_t, int, int, int);
 
+/*
+ * copy inventory_t from conn_v to peer_conn_v
+ */
+int
+pic_bus1_inventory_dup(vertex_hdl_t conn_v, vertex_hdl_t peer_conn_v)
+{
+	inventory_t *pinv, *peer_pinv;
+
+	if (hwgraph_info_get_LBL(conn_v, INFO_LBL_INVENT,
+				(arbitrary_info_t *)&pinv) == GRAPH_SUCCESS)
+ {
+		NEW(peer_pinv);
+		bcopy((const char *)pinv, (char *)peer_pinv, sizeof(inventory_t));
+		if (hwgraph_info_add_LBL(peer_conn_v, INFO_LBL_INVENT,
+			    (arbitrary_info_t)peer_pinv) != GRAPH_SUCCESS) {
+			DEL(peer_pinv);
+			return 0;
+		}
+		return 1;
+	}
+
+	printk("pic_bus1_inventory_dup: cannot get INFO_LBL_INVENT from 0x%lx\n ", (uint64_t)conn_v);
+	return 0;
+}
 
-void
-pic_init(void)
+/*
+ * copy xwidget_info_t from conn_v to peer_conn_v
+ */
+int
+pic_bus1_widget_info_dup(vertex_hdl_t conn_v, vertex_hdl_t peer_conn_v,
+							cnodeid_t xbow_peer)
 {
-	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INIT, NULL, "pic_init()\n"));	
+	xwidget_info_t widget_info, peer_widget_info;
+	char peer_path[256];
+	vertex_hdl_t peer_hubv;
+	hubinfo_t peer_hub_info;
+
+	/* get the peer hub's widgetid */
+	peer_hubv = NODEPDA(xbow_peer)->node_vertex;
+	peer_hub_info = NULL;
+	hubinfo_get(peer_hubv, &peer_hub_info);
+	if (peer_hub_info == NULL)
+		return 0;
+
+	if (hwgraph_info_get_LBL(conn_v, INFO_LBL_XWIDGET,
+			(arbitrary_info_t *)&widget_info) == GRAPH_SUCCESS) {
+		NEW(peer_widget_info);
+		peer_widget_info->w_vertex = peer_conn_v;
+		peer_widget_info->w_id = widget_info->w_id;
+		peer_widget_info->w_master = peer_hubv;
+		peer_widget_info->w_masterid = peer_hub_info->h_widgetid;
+		/* structure copy */
+		peer_widget_info->w_hwid = widget_info->w_hwid;
+		peer_widget_info->w_efunc = 0;
+		peer_widget_info->w_einfo = 0;
+		peer_widget_info->w_name = kmalloc(strlen(peer_path) + 1, GFP_KERNEL);
+		strcpy(peer_widget_info->w_name, peer_path);
+
+		if (hwgraph_info_add_LBL(peer_conn_v, INFO_LBL_XWIDGET,
+			(arbitrary_info_t)peer_widget_info) != GRAPH_SUCCESS) {
+				DEL(peer_widget_info);
+				return 0;
+		}
+
+		xwidget_info_set(peer_conn_v, peer_widget_info);
 
-	xwidget_driver_register(PIC_WIDGET_PART_NUM_BUS0,
-			    PIC_WIDGET_MFGR_NUM,
-			    "pic_",
-			    0);
+		return 1;
+	}
+
+	printk("pic_bus1_widget_info_dup: "
+			"cannot get INFO_LBL_XWIDGET from 0x%lx\n", (uint64_t)conn_v);
+	return 0;
 }
 
+/*
+ * If this PIC is attached to two Cbricks ("dual-ported") then
+ * attach each bus to opposite Cbricks.
+ *
+ * If successful, return a new vertex suitable for attaching the PIC bus.
+ * If not successful, return zero and both buses will attach to the
+ * vertex passed into pic_attach().
+ */
+vertex_hdl_t
+pic_bus1_redist(nasid_t nasid, vertex_hdl_t conn_v)
+{
+	cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
+	cnodeid_t xbow_peer = -1;
+	char pathname[256], peer_path[256], tmpbuf[256];
+	char *p;
+	int rc;
+	vertex_hdl_t peer_conn_v;
+	int pos;
+	slabid_t slab;
+
+	if (NODEPDA(cnode)->xbow_peer >= 0) {			/* if dual-ported */
+		/* create a path for this widget on the peer Cbrick */
+		/* pcibr widget hw/module/001c11/slab/0/Pbrick/xtalk/12 */
+		/* sprintf(pathname, "%v", conn_v); */
+		xbow_peer = NASID_TO_COMPACT_NODEID(NODEPDA(cnode)->xbow_peer);
+		pos = hwgfs_generate_path(conn_v, tmpbuf, 256);
+		strcpy(pathname, &tmpbuf[pos]);
+		p = pathname + strlen("hw/module/001c01/slab/0/");
+
+		memset(tmpbuf, 0, 16);
+		format_module_id(tmpbuf, geo_module((NODEPDA(xbow_peer))->geoid), MODULE_FORMAT_BRIEF);
+		slab = geo_slab((NODEPDA(xbow_peer))->geoid);
+		sprintf(peer_path, "module/%s/slab/%d/%s", tmpbuf, (int)slab, p); 
+		
+		/* Look for vertex for this widget on the peer Cbrick.
+		 * Expect GRAPH_NOT_FOUND.
+		 */
+		rc = hwgraph_traverse(hwgraph_root, peer_path, &peer_conn_v);
+		if (GRAPH_SUCCESS == rc)
+			printk("pic_attach: found unexpected vertex: 0x%lx\n",
+								(uint64_t)peer_conn_v);
+		else if (GRAPH_NOT_FOUND != rc) {
+			printk("pic_attach: hwgraph_traverse unexpectedly"
+					" returned 0x%x\n", rc);
+		} else {
+			/* try to add the widget vertex to the peer Cbrick */
+			rc = hwgraph_path_add(hwgraph_root, peer_path, &peer_conn_v);
+
+			if (GRAPH_SUCCESS != rc)
+			    printk("pic_attach: hwgraph_path_add"
+						" failed with 0x%x\n", rc);
+			else {
+			    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
+					"pic_bus1_redist: added vertex %v\n", peer_conn_v)); 
+
+			    /* Now hang appropiate stuff off of the new
+			     * vertex.	We bail out if we cannot add something.
+			     * In that case, we don't remove the newly added
+			     * vertex but that should be safe and we don't
+			     * really expect the additions to fail anyway.
+			     */
+#if 0
+			    if (!pic_bus1_inventory_dup(conn_v, peer_conn_v))
+					return 0;
+			    pic_bus1_device_desc_dup(conn_v, peer_conn_v);
+#endif
+			    if (!pic_bus1_widget_info_dup(conn_v, peer_conn_v, xbow_peer))
+					return 0;
+
+			    return peer_conn_v;
+			}
+		}
+	}
+	return 0;
+}
+
+
 int
-pic_attach(devfs_handle_t conn_v)
+pic_attach(vertex_hdl_t conn_v)
 {
 	int		rc;
 	bridge_t	*bridge0, *bridge1 = (bridge_t *)0;
-	devfs_handle_t	pcibr_vhdl0, pcibr_vhdl1 = (devfs_handle_t)0;
+	vertex_hdl_t	pcibr_vhdl0, pcibr_vhdl1 = (vertex_hdl_t)0;
 	pcibr_soft_t	bus0_soft, bus1_soft = (pcibr_soft_t)0;
+	vertex_hdl_t  conn_v0, conn_v1, peer_conn_v;
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach()\n"));
 
 	bridge0 = (bridge_t *) xtalk_piotrans_addr(conn_v, NULL,
 	                        0, sizeof(bridge_t), 0);
-#ifdef	PCI_BUS_NO_1
 	bridge1 = (bridge_t *)((char *)bridge0 + PIC_BUS1_OFFSET);
-#endif
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
 		    "pic_attach: bridge0=0x%x, bridge1=0x%x\n", 
 		    bridge0, bridge1));
 
+	conn_v0 = conn_v1 = conn_v;
+
+	/* If dual-ported then split the two PIC buses across both Cbricks */
+	if ((peer_conn_v = (pic_bus1_redist(NASID_GET(bridge0), conn_v))))
+		conn_v1 = peer_conn_v;
+
 	/*
 	 * Create the vertex for the PCI buses, which we
 	 * will also use to hold the pcibr_soft and
@@ -84,12 +228,10 @@
 	 * the Bridge registers themselves.
 	 */
 	/* FIXME: what should the hwgraph path look like ? */
-	rc = hwgraph_path_add(conn_v, EDGE_LBL_PCIX_0, &pcibr_vhdl0);
+	rc = hwgraph_path_add(conn_v0, EDGE_LBL_PCIX_0, &pcibr_vhdl0);
 	ASSERT(rc == GRAPH_SUCCESS);
-#ifdef	PCI_BUS_NO_1
-	rc = hwgraph_path_add(conn_v, EDGE_LBL_PCIX_1, &pcibr_vhdl1);
+	rc = hwgraph_path_add(conn_v1, EDGE_LBL_PCIX_1, &pcibr_vhdl1);
 	ASSERT(rc == GRAPH_SUCCESS);
-#endif
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
 		    "pic_attach: pcibr_vhdl0=%v, pcibr_vhdl1=%v\n",
@@ -97,27 +239,17 @@
 
 	/* register pci provider array */
 	pciio_provider_register(pcibr_vhdl0, &pci_pic_provider);
-#ifdef	PCI_BUS_NO_1
 	pciio_provider_register(pcibr_vhdl1, &pci_pic_provider);
-#endif
 
 	pciio_provider_startup(pcibr_vhdl0);
-#ifdef	PCI_BUS_NO_1
 	pciio_provider_startup(pcibr_vhdl1);
-#endif
 
-	pcibr_attach2(conn_v, bridge0, pcibr_vhdl0, 0, &bus0_soft);
-#ifdef	PCI_BUS_NO_1
-	pcibr_attach2(conn_v, bridge1, pcibr_vhdl1, 1, &bus1_soft);
-#endif
+	pcibr_attach2(conn_v0, bridge0, pcibr_vhdl0, 0, &bus0_soft);
+	pcibr_attach2(conn_v1, bridge1, pcibr_vhdl1, 1, &bus1_soft);
 
 	/* save a pointer to the PIC's other bus's soft struct */
-#ifdef	PCI_BUS_NO_1
         bus0_soft->bs_peers_soft = bus1_soft;
         bus1_soft->bs_peers_soft = bus0_soft;
-#else
-        bus0_soft->bs_peers_soft = (pcibr_soft_t)0;
-#endif
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
 		    "pic_attach: bus0_soft=0x%x, bus1_soft=0x%x\n",
@@ -145,10 +277,8 @@
     (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
     (pciio_dmamap_free_f *) pcibr_dmamap_free,
     (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
-    (pciio_dmamap_list_f *) pcibr_dmamap_list,
     (pciio_dmamap_done_f *) pcibr_dmamap_done,
     (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
-    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
     (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
     (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
     (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/sgi_io_init.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/sgi_io_init.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/sgi_io_init.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/sgi_io_init.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,230 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pciba.h>
-#include <linux/smp.h>
-
-extern void mlreset(void);
-extern int init_hcl(void);
-extern void klgraph_hack_init(void);
-extern void hubspc_init(void);
-extern void pciio_init(void);
-extern void pcibr_init(void);
-extern void xtalk_init(void);
-extern void xbow_init(void);
-extern void xbmon_init(void);
-extern void pciiox_init(void);
-extern void pic_init(void);
-extern void usrpci_init(void);
-extern void ioc3_init(void);
-extern void initialize_io(void);
-extern void klhwg_add_all_modules(devfs_handle_t);
-extern void klhwg_add_all_nodes(devfs_handle_t);
-
-void sn_mp_setup(void);
-extern devfs_handle_t hwgraph_root;
-extern void io_module_init(void);
-extern void pci_bus_cvlink_init(void);
-extern void temp_hack(void);
-
-extern int pci_bus_to_hcl_cvlink(void);
-
-/* #define DEBUG_IO_INIT 1 */
-#ifdef DEBUG_IO_INIT
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_IO_INIT */
-
-/*
- * per_hub_init
- *
- * 	This code is executed once for each Hub chip.
- */
-static void
-per_hub_init(cnodeid_t cnode)
-{
-	nasid_t		nasid;
-	nodepda_t	*npdap;
-	ii_icmr_u_t	ii_icmr;
-	ii_ibcr_u_t	ii_ibcr;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	ASSERT(nasid != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
-
-	npdap = NODEPDA(cnode);
-
-#ifdef BRINGUP2
-#if 0
-	while ((REMOTE_HUB_L(nasid, IIO_IFDR)) != 0x2d2d)
-		REMOTE_HUB_S(nasid, IIO_IFDR, 0xadad);
-#endif
-	printk("IIO_IFDR = 0x%x\n", REMOTE_HUB_L(nasid, IIO_IFDR));
-	REMOTE_HUB_S(nasid, IIO_IWEIM, 0x8000);
-#endif
-	/*
-	 * Set the total number of CRBs that can be used.
-	 */
-	ii_icmr.ii_icmr_regval= 0x0;
-	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF;
-	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
-
-	/*
-	 * Set the number of CRBs that both of the BTEs combined
-	 * can use minus 1.
-	 */
-	ii_ibcr.ii_ibcr_regval= 0x0;
-	ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
-	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
-
-	/*
-	 * Set CRB timeout to be 10ms.
-	 */
-#ifdef BRINGUP2
-	REMOTE_HUB_S(nasid, IIO_ICTP, 0xffffff );
-	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
-	REMOTE_HUB_S(nasid, IIO_IDBSS, 0x504);
-	REMOTE_HUB_S(nasid, SH_DEBUG_SELECT, 0x0002DF6D74CF2C70);
-#endif
-
-	/* Initialize error interrupts for this hub. */
-	hub_error_init(cnode);
-}
-
-/*
- * This routine is responsible for the setup of all the IRIX hwgraph style
- * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
- * is called just before the generic Linux PCI layer does its probing (by 
- * platform_pci_fixup aka sn_pci_fixup).
- *
- * It is very IMPORTANT that this call is only made by the Master CPU!
- *
- */
-
-void
-sgi_master_io_infr_init(void)
-{
-	int cnode;
-
-	/*
-	 * Do any early init stuff .. einit_tbl[] etc.
-	 */
-	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
-
-	/*
-	 * initialize the Linux PCI to xwidget vertexes ..
-	 */
-	pci_bus_cvlink_init();
-
-#ifdef BRINGUP
-	/*
-	 * Hack to provide statically initialzed klgraph entries.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n");
-	klgraph_hack_init();
-#endif /* BRINGUP */
-
-	/*
-	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
-	 */
-	mlreset();
-
-	/*
-	 * allowboot() is called by kern/os/main.c in main()
-	 * Emulate allowboot() ...
-	 *   per_cpu_init() - only need per_hub_init()
-	 *   cpu_io_setup() - Nothing to do.
-	 * 
-	 */
-	sn_mp_setup();
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		per_hub_init(cnode);
-	}
-
-	/* We can do headless hub cnodes here .. */
-
-	/*
-	 * io_init[] stuff.
-	 *
-	 * Get SGI IO Infrastructure drivers to init and register with 
-	 * each other etc.
-	 */
-
-	hubspc_init();
-	pciio_init();
-	pcibr_init();
-	pic_init();
-	xtalk_init();
-	xbow_init();
-	xbmon_init();
-	pciiox_init();
-	usrpci_init();
-	ioc3_init();
-
-	/*
-	 *
-	 * Our IO Infrastructure drivers are in place .. 
-	 * Initialize the whole IO Infrastructure .. xwidget/device probes.
-	 *
-	 */
-	initialize_io();
-	pci_bus_to_hcl_cvlink();
-
-#ifdef CONFIG_PCIBA
-	DBG("--> sgi_master_io_infr_init: calling pciba_init()\n");
-#ifndef BRINGUP2
- 	pciba_init();
-#endif
-#endif
-}
-
-/*
- * One-time setup for MP SN.
- * Allocate per-node data, slurp prom klconfig information and
- * convert it to hwgraph information.
- */
-void
-sn_mp_setup(void)
-{
-	cpuid_t		cpu;
-
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		/* Skip holes in CPU space */
-		if (cpu_enabled(cpu)) {
-			init_platform_pda(cpu);
-		}
-	}
-
-	/*
-	 * Initialize platform-dependent vertices in the hwgraph:
-	 *	module
-	 *	node
-	 *	cpu
-	 *	memory
-	 *	slot
-	 *	hub
-	 *	router
-	 *	xbow
-	 */
-
-	io_module_init(); /* Use to be called module_init() .. */
-	klhwg_add_all_modules(hwgraph_root);
-	klhwg_add_all_nodes(hwgraph_root);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/shub.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/shub.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/shub.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/shub.c	2003-07-05 18:09:45.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #ident  "$Revision: 1.167 $"
@@ -15,6 +15,7 @@
 #include <asm/smp.h>
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
+#include <asm/system.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
@@ -97,6 +98,14 @@
 }
 
 static inline void
+shub_mmr_write_iospace(cnodeid_t cnode, shubreg_t reg, uint64_t val)
+{
+	int		   nasid = cnodeid_to_nasid(cnode);
+
+	REMOTE_HUB_S(nasid, reg, val);
+}
+
+static inline void
 shub_mmr_write32(cnodeid_t cnode, shubreg_t reg, uint32_t val)
 {
 	int		   nasid = cnodeid_to_nasid(cnode);
@@ -118,6 +127,14 @@
 	return val;
 }
 
+static inline uint64_t
+shub_mmr_read_iospace(cnodeid_t cnode, shubreg_t reg)
+{
+	int		  nasid = cnodeid_to_nasid(cnode);
+
+	return REMOTE_HUB_L(nasid, reg);
+}
+
 static inline uint32_t
 shub_mmr_read32(cnodeid_t cnode, shubreg_t reg)
 {
@@ -182,12 +199,15 @@
 {
         cnodeid_t       cnode;
         uint64_t        longarg;
-        devfs_handle_t  d;
 	int		nasid;
 
-        if ((d = devfs_get_handle_from_inode(inode)) == NULL)
+#ifdef CONFIG_HWGFS_FS
+        cnode = (cnodeid_t)file->f_dentry->d_fsdata;
+#else
+        cnode = (cnodeid_t)file->private_data;
+#endif
+        if (!cnode)
                 return -ENODEV;
-        cnode = (cnodeid_t)hwgraph_fastinfo_get(d);
 
         switch (cmd) {
 	case SNDRV_SHUB_CONFIGURE:
@@ -231,3 +251,255 @@
 struct file_operations shub_mon_fops = {
 	        ioctl:          shubstats_ioctl,
 };
+
+/*
+ * "linkstatd" kernel thread to export SGI Numalink
+ * stats via /proc/sgi_sn/linkstats
+ */
+static struct s_linkstats {
+	uint64_t	hs_ni_sn_errors[2];
+	uint64_t	hs_ni_cb_errors[2];
+	uint64_t	hs_ni_retry_errors[2];
+	int		hs_ii_up;
+	uint64_t	hs_ii_sn_errors;
+	uint64_t	hs_ii_cb_errors;
+	uint64_t	hs_ii_retry_errors;
+} *sn_linkstats;
+
+static spinlock_t    sn_linkstats_lock;
+static unsigned long sn_linkstats_starttime;
+static unsigned long sn_linkstats_samples;
+static unsigned long sn_linkstats_overflows;
+static unsigned long sn_linkstats_update_msecs;
+
+void
+sn_linkstats_reset(unsigned long msecs)
+{
+	int		    cnode;
+	uint64_t	    iio_wstat;
+	uint64_t	    llp_csr_reg;
+
+	spin_lock(&sn_linkstats_lock);
+	memset(sn_linkstats, 0, numnodes * sizeof(struct s_linkstats));
+	for (cnode=0; cnode < numnodes; cnode++) {
+	    shub_mmr_write(cnode, SH_NI0_LLP_ERR, 0L);
+	    shub_mmr_write(cnode, SH_NI1_LLP_ERR, 0L);
+	    shub_mmr_write_iospace(cnode, IIO_LLP_LOG, 0L);
+
+	    /* zero the II retry counter */
+	    iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT);
+	    iio_wstat &= 0xffffffffff00ffff; /* bits 23:16 */
+	    shub_mmr_write_iospace(cnode, IIO_WSTAT, iio_wstat);
+
+	    /* Check if the II xtalk link is working */
+	    llp_csr_reg = shub_mmr_read_iospace(cnode, IIO_LLP_CSR);
+	    if (llp_csr_reg & IIO_LLP_CSR_IS_UP)
+		sn_linkstats[cnode].hs_ii_up = 1;
+	}
+
+    	sn_linkstats_update_msecs = msecs;
+	sn_linkstats_samples = 0;
+	sn_linkstats_overflows = 0;
+	sn_linkstats_starttime = jiffies;
+	spin_unlock(&sn_linkstats_lock);
+}
+
+int
+linkstatd_thread(void *unused)
+{
+	int		    cnode;
+	int		    overflows;
+	uint64_t	    reg[2];
+	uint64_t	    iio_wstat = 0L;
+	ii_illr_u_t	    illr;
+	struct s_linkstats  *lsp;
+	struct task_struct  *tsk = current;
+
+	daemonize();
+	set_user_nice(tsk, 19);
+	sigfillset(&tsk->blocked);
+	strcpy(tsk->comm, "linkstatd");
+
+	while(1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(sn_linkstats_update_msecs * HZ / 1000);
+
+		spin_lock(&sn_linkstats_lock);
+
+		overflows = 0;
+		for (lsp=sn_linkstats, cnode=0; cnode < numnodes; cnode++, lsp++) {
+			reg[0] = shub_mmr_read(cnode, SH_NI0_LLP_ERR);
+			reg[1] = shub_mmr_read(cnode, SH_NI1_LLP_ERR);
+			if (lsp->hs_ii_up) {
+			    illr = (ii_illr_u_t)shub_mmr_read_iospace(cnode, IIO_LLP_LOG);
+			    iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT);
+			}
+
+			if (!overflows && (
+			    (reg[0] & SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK) == 
+				     SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK ||
+			    (reg[0] & SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK) ==
+			             SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK ||
+			    (reg[1] & SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK) ==
+			             SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK ||
+			    (reg[1] & SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK) ==
+			             SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK ||
+			    (lsp->hs_ii_up && illr.ii_illr_fld_s.i_sn_cnt == IIO_LLP_SN_MAX) ||
+			    (lsp->hs_ii_up && illr.ii_illr_fld_s.i_cb_cnt == IIO_LLP_CB_MAX))) {
+			    overflows = 1;
+			}
+
+#define LINKSTAT_UPDATE(reg, cnt, mask, shift) cnt += (reg & mask) >> shift
+
+			LINKSTAT_UPDATE(reg[0], lsp->hs_ni_sn_errors[0],
+					SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK,
+					SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[1], lsp->hs_ni_sn_errors[1],
+					SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK,
+					SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[0], lsp->hs_ni_cb_errors[0],
+					SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK,
+					SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[1], lsp->hs_ni_cb_errors[1],
+					SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK,
+					SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[0], lsp->hs_ni_retry_errors[0],
+					SH_NI0_LLP_ERR_RETRY_COUNT_MASK,
+					SH_NI0_LLP_ERR_RETRY_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[1], lsp->hs_ni_retry_errors[1],
+					SH_NI1_LLP_ERR_RETRY_COUNT_MASK,
+					SH_NI1_LLP_ERR_RETRY_COUNT_SHFT);
+
+			if (lsp->hs_ii_up) {
+			    /* II sn and cb errors */
+			    lsp->hs_ii_sn_errors += illr.ii_illr_fld_s.i_sn_cnt;
+			    lsp->hs_ii_cb_errors += illr.ii_illr_fld_s.i_cb_cnt;
+			    lsp->hs_ii_retry_errors += (iio_wstat & 0x0000000000ff0000) >> 16;
+
+			    shub_mmr_write(cnode, SH_NI0_LLP_ERR, 0L);
+			    shub_mmr_write(cnode, SH_NI1_LLP_ERR, 0L);
+			    shub_mmr_write_iospace(cnode, IIO_LLP_LOG, 0L);
+
+			    /* zero the II retry counter */
+			    iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT);
+			    iio_wstat &= 0xffffffffff00ffff; /* bits 23:16 */
+			    shub_mmr_write_iospace(cnode, IIO_WSTAT, iio_wstat);
+			}
+		}
+
+		sn_linkstats_samples++;
+		if (overflows)
+		    sn_linkstats_overflows++;
+
+		spin_unlock(&sn_linkstats_lock);
+	}
+}
+
+static char *
+rate_per_minute(uint64_t val, uint64_t secs)
+{
+	static char	buf[16];
+	uint64_t	a=0, b=0, c=0, d=0;
+
+	if (secs) {
+		a = 60 * val / secs;
+		b = 60 * 10 * val / secs - (10 * a);
+		c = 60 * 100 * val / secs - (100 * a) - (10 * b);
+		d = 60 * 1000 * val / secs - (1000 * a) - (100 * b) - (10 * c);
+	}
+	sprintf(buf, "%4lu.%lu%lu%lu", a, b, c, d);
+
+	return buf;
+}
+
+int
+sn_linkstats_get(char *page)
+{
+	int			n = 0;
+	int			cnode;
+	int			nlport;
+	struct s_linkstats	*lsp;
+	nodepda_t		*npda;
+	uint64_t	    	snsum = 0;
+	uint64_t	    	cbsum = 0;
+	uint64_t	    	retrysum = 0;
+	uint64_t	    	snsum_ii = 0;
+	uint64_t	    	cbsum_ii = 0;
+	uint64_t	    	retrysum_ii = 0;
+	uint64_t		secs;
+
+	spin_lock(&sn_linkstats_lock);
+	secs = (jiffies - sn_linkstats_starttime) / HZ;
+
+	n += sprintf(page, "# SGI Numalink stats v1 : %lu samples, %lu o/flows, update %lu msecs\n",
+		sn_linkstats_samples, sn_linkstats_overflows, sn_linkstats_update_msecs);
+
+	n += sprintf(page+n, "%-37s %8s %8s %8s %8s\n",
+		"# Numalink", "sn errs", "cb errs", "cb/min", "retries");
+
+	for (lsp=sn_linkstats, cnode=0; cnode < numnodes; cnode++, lsp++) {
+		npda = NODEPDA(cnode);
+
+		/* two NL links on each SHub */
+		for (nlport=0; nlport < 2; nlport++) {
+			cbsum += lsp->hs_ni_cb_errors[nlport];
+			snsum += lsp->hs_ni_sn_errors[nlport];
+			retrysum += lsp->hs_ni_retry_errors[nlport];
+
+			/* avoid buffer overrun (should be using seq_read API) */
+			if (numnodes > 64)
+				continue;
+
+			n += sprintf(page + n, "/%s/link/%d  %8lu %8lu %8s %8lu\n",
+			    npda->hwg_node_name, nlport+1, lsp->hs_ni_sn_errors[nlport],
+			    lsp->hs_ni_cb_errors[nlport], 
+			    rate_per_minute(lsp->hs_ni_cb_errors[nlport], secs),
+			    lsp->hs_ni_retry_errors[nlport]);
+		}
+
+		/* one II port on each SHub (may not be connected) */
+		if (lsp->hs_ii_up) {
+		    n += sprintf(page + n, "/%s/xtalk   %8lu %8lu %8s %8lu\n",
+			npda->hwg_node_name, lsp->hs_ii_sn_errors,
+			lsp->hs_ii_cb_errors, rate_per_minute(lsp->hs_ii_cb_errors, secs),
+			lsp->hs_ii_retry_errors);
+
+		    snsum_ii += lsp->hs_ii_sn_errors;
+		    cbsum_ii += lsp->hs_ii_cb_errors;
+		    retrysum_ii += lsp->hs_ii_retry_errors;
+		}
+	}
+
+	n += sprintf(page + n, "%-37s %8lu %8lu %8s %8lu\n",
+		"System wide NL totals", snsum, cbsum, 
+		rate_per_minute(cbsum, secs), retrysum);
+
+	n += sprintf(page + n, "%-37s %8lu %8lu %8s %8lu\n",
+		"System wide II totals", snsum_ii, cbsum_ii, 
+		rate_per_minute(cbsum_ii, secs), retrysum_ii);
+
+	spin_unlock(&sn_linkstats_lock);
+
+	return n;
+}
+
+static int __init
+linkstatd_init(void)
+{
+	if (!ia64_platform_is("sn2"))
+		return -ENODEV;
+
+	spin_lock_init(&sn_linkstats_lock);
+	sn_linkstats = kmalloc(numnodes * sizeof(struct s_linkstats), GFP_KERNEL);
+	sn_linkstats_reset(60000UL); /* default 60 second update interval */
+	kernel_thread(linkstatd_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
+
+	return 0;                                                                       
+}
+
+__initcall(linkstatd_init);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/shub_intr.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/shub_intr.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/shub_intr.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/shub_intr.c	2003-07-05 18:09:45.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/types.h>
@@ -30,7 +30,7 @@
 
 /* ARGSUSED */
 void
-hub_intr_init(devfs_handle_t hubv)
+hub_intr_init(vertex_hdl_t hubv)
 {
 }
 
@@ -45,9 +45,9 @@
 }
 
 static hub_intr_t
-do_hub_intr_alloc(devfs_handle_t dev,
+do_hub_intr_alloc(vertex_hdl_t dev,
 		device_desc_t dev_desc,
-		devfs_handle_t owner_dev,
+		vertex_hdl_t owner_dev,
 		int uncond_nothread)
 {
 	cpuid_t		cpu = 0;
@@ -101,17 +101,17 @@
 }
 
 hub_intr_t
-hub_intr_alloc(devfs_handle_t dev,
+hub_intr_alloc(vertex_hdl_t dev,
 		device_desc_t dev_desc,
-		devfs_handle_t owner_dev)
+		vertex_hdl_t owner_dev)
 {
 	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0));
 }
 
 hub_intr_t
-hub_intr_alloc_nothd(devfs_handle_t dev,
+hub_intr_alloc_nothd(vertex_hdl_t dev,
 		device_desc_t dev_desc,
-		devfs_handle_t owner_dev)
+		vertex_hdl_t owner_dev)
 {
 	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1));
 }
@@ -188,18 +188,3 @@
 	ASSERT(rv == 0);
 	intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED;
 }
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-hub_intr_cpu_get(hub_intr_t intr_hdl)
-{
-	cpuid_t cpuid = intr_hdl->i_cpuid;
-
-	ASSERT(cpuid != CPU_NONE);
-
-	return(cpuid_to_vertex(cpuid));
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/shuberror.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/shuberror.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/shuberror.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/shuberror.c	2003-07-05 18:09:45.000000000 -0700
@@ -4,13 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000,2002-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/irq.h>
+#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/smp.h>
 #include <asm/sn/sgi.h>
@@ -27,6 +28,7 @@
 #include <asm/sn/xtalk/xtalk.h>
 #include <asm/sn/pci/pcibr_private.h>
 #include <asm/sn/intr.h>
+#include <asm/sn/ioerror_handling.h>
 #include <asm/sn/ioerror.h>
 #include <asm/sn/sn2/shubio.h>
 #include <asm/sn/bte.h>
@@ -34,21 +36,18 @@
 extern void hubni_eint_init(cnodeid_t cnode);
 extern void hubii_eint_init(cnodeid_t cnode);
 extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
-int hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo);
-int hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo);
-extern void bte_crb_error_handler(devfs_handle_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop);
+int hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo);
+int hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo);
+extern void bte_crb_error_handler(vertex_hdl_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop);
+void print_crb_fields(int crb_num, ii_icrb0_a_u_t icrba,
+	ii_icrb0_b_u_t icrbb, ii_icrb0_c_u_t icrbc,
+	ii_icrb0_d_u_t icrbd, ii_icrb0_e_u_t icrbe);
 
 extern int maxcpus;
+extern error_return_code_t error_state_set(vertex_hdl_t v,error_state_t new_state);
 
 #define HUB_ERROR_PERIOD        (120 * HZ)      /* 2 minutes */
 
-#ifdef BUS_INT_WAR
-void sn_add_polled_interrupt(int irq, int interval);
-void sn_delete_polled_interrupt(int irq);
-extern int bus_int_war_ide_irq;
-#endif
-
-
 void
 hub_error_clear(nasid_t nasid)
 {
@@ -74,9 +73,7 @@
         REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval);
     }
 
-    REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1);
-    idsr = REMOTE_HUB_L(nasid, IIO_IIDSR);
-    REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK)));
+    REMOTE_HUB_S(nasid, IIO_IECLR, -1);
 
 }
 
@@ -117,7 +114,6 @@
  * Returns	: None.
  */
 
-
 void
 hubii_eint_init(cnodeid_t cnode)
 {
@@ -125,33 +121,41 @@
     ii_iidsr_u_t    	hubio_eint;
     hubinfo_t		hinfo; 
     cpuid_t		intr_cpu;
-    devfs_handle_t 	hub_v;
+    vertex_hdl_t 	hub_v;
     int bit_pos_to_irq(int bit);
+    ii_ilcsr_u_t	ilcsr;
 
 
-    hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode);
+    hub_v = (vertex_hdl_t)cnodeid_to_vertex(cnode);
     ASSERT_ALWAYS(hub_v);
     hubinfo_get(hub_v, &hinfo);
 
     ASSERT(hinfo);
     ASSERT(hinfo->h_cnodeid == cnode);
 
+    ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
+    if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) {
+	/*
+	 * HUB II link is not up.  Disable LLP. Clear old errors.
+	 * Enable interrupts to handle BTE errors.
+	 */
+	ilcsr.ii_ilcsr_fld_s.i_llp_en = 0;
+	REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval);
+    }
+
     /* Select a possible interrupt target where there is a free interrupt
      * bit and also reserve the interrupt bit for this IO error interrupt
      */
-    intr_cpu = intr_heuristic(hub_v,0,-1,0,hub_v,
+    intr_cpu = intr_heuristic(hub_v,0,SGI_II_ERROR,0,hub_v,
 			      "HUB IO error interrupt",&bit);
     if (intr_cpu == CPU_NONE) {
 	printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode);
 	return;
     }
 	
-    rv = intr_connect_level(intr_cpu, bit, 0, NULL);
-    request_irq(bit + (intr_cpu << 8), hubii_eint_handler, 0, "SN_hub_error", (void *)hub_v);
-    irq_desc(bit + (intr_cpu << 8))->status |= SN2_IRQ_PER_HUB;
-#ifdef BUS_INT_WAR                                              
-    sn_add_polled_interrupt(bit + (intr_cpu << 8), (0.01 * HZ));
-#endif
+    rv = intr_connect_level(intr_cpu, SGI_II_ERROR, 0, NULL);
+    request_irq(SGI_II_ERROR, hubii_eint_handler, SA_SHIRQ, "SN_hub_error", (void *)hub_v);
+    irq_desc(bit)->status |= SN2_IRQ_PER_HUB;
     ASSERT_ALWAYS(rv >= 0);
     hubio_eint.ii_iidsr_regval = 0;
     hubio_eint.ii_iidsr_fld_s.i_enable = 1;
@@ -167,18 +171,29 @@
 void
 hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
 {
-    devfs_handle_t	hub_v;
+    vertex_hdl_t	hub_v;
     hubinfo_t		hinfo; 
     ii_wstat_u_t	wstat;
     hubreg_t		idsr;
+    ii_ilcsr_u_t	ilcsr;
 
 
     /* two levels of casting avoids compiler warning.!! */
-    hub_v = (devfs_handle_t)(long)(arg); 
+    hub_v = (vertex_hdl_t)(long)(arg); 
     ASSERT(hub_v);
 
     hubinfo_get(hub_v, &hinfo);
     
+    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_ICMR);
+#if 0
+    if (idsr & 0x1) {
+	/* ICMR bit is set .. we are getting into "Spurious Interrupts condition. */
+	printk("Cnode %d II has seen the ICMR condition\n", hinfo->h_cnodeid);
+	printk("***** Please file PV with the above messages *****\n");
+	/* panic("We have to panic to prevent further unknown states ..\n"); */
+    }
+#endif
+	
     /* 
      * Identify the reason for error. 
      */
@@ -218,10 +233,26 @@
 	 * Note: we may never be able to print this, if the II talking
 	 * to Xbow which hosts the console is dead. 
 	 */
-	printk("Hub %d to Xtalk Link failed (II_ECRAZY) Reason: %s", 
-		hinfo->h_cnodeid, reason);
+	ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
+	if (ilcsr.ii_ilcsr_fld_s.i_llp_en == 1) {	/* Link is enabled */
+	    printk("Hub %d, cnode %d to Xtalk Link failed (II_ECRAZY) Reason: %s", 
+		hinfo->h_nasid, hinfo->h_cnodeid, reason);
+	}
     }
 
+
+    /*
+     * Before processing any interrupt related information, clear all
+     * error indication and reenable interrupts.  This will prevent
+     * lost interrupts due to the interrupt handler scanning past a PRB/CRB
+     * which has not errorred yet and then the PRB/CRB goes into error.
+     * Note, PRB errors are cleared individually.
+     */
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xff0000);
+    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK;
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr);
+
+
     /* 
      * It's a toss as to which one among PRB/CRB to check first. 
      * Current decision is based on the severity of the errors. 
@@ -232,14 +263,6 @@
      */
     (void)hubiio_crb_error_handler(hub_v, hinfo);
     (void)hubiio_prb_error_handler(hub_v, hinfo);
-    /*
-     * If we reach here, it indicates crb/prb handlers successfully
-     * handled the error. So, re-enable II to send more interrupt
-     * and return.
-     */
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xffffff);
-    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK;
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr);
 }
 
 /*
@@ -295,6 +318,105 @@
 	"Xtalk Error Packet"
 };
 
+void
+print_crb_fields(int crb_num, ii_icrb0_a_u_t icrba,
+	ii_icrb0_b_u_t icrbb, ii_icrb0_c_u_t icrbc,
+	ii_icrb0_d_u_t icrbd, ii_icrb0_e_u_t icrbe)
+{
+    printk("CRB %d regA\n\t"
+	    "a_iow 0x%x\n\t"
+	    "valid0x%x\n\t"
+	    "Address0x%lx\n\t"
+	    "a_tnum 0x%x\n\t"
+	    "a_sidn 0x%x\n",
+	    crb_num,
+	    icrba.a_iow, 
+	    icrba.a_valid, 
+	    icrba.a_addr, 
+	    icrba.a_tnum, 
+	    icrba.a_sidn);
+    printk("CRB %d regB\n\t"
+	    "b_imsgtype 0x%x\n\t"
+	    "b_imsg 0x%x\n"
+	    "\tb_use_old 0x%x\n\t"
+	    "b_initiator 0x%x\n\t"
+	    "b_exc 0x%x\n"
+	    "\tb_ackcnt 0x%x\n\t"
+	    "b_resp 0x%x\n\t"
+	    "b_ack 0x%x\n"
+	    "\tb_hold 0x%x\n\t"
+	    "b_wb 0x%x\n\t"
+	    "b_intvn 0x%x\n"
+	    "\tb_stall_ib 0x%x\n\t"
+	    "b_stall_int 0x%x\n"
+	    "\tb_stall_bte_0 0x%x\n\t"
+	    "b_stall_bte_1 0x%x\n"
+	    "\tb_error 0x%x\n\t"
+	    "b_lnetuce 0x%x\n\t"
+	    "b_mark 0x%x\n\t"
+	    "b_xerr 0x%x\n",
+	    crb_num,
+	    icrbb.b_imsgtype, 
+	    icrbb.b_imsg, 
+	    icrbb.b_use_old, 
+	    icrbb.b_initiator,
+	    icrbb.b_exc, 
+	    icrbb.b_ackcnt, 
+	    icrbb.b_resp, 
+	    icrbb.b_ack, 
+	    icrbb.b_hold,
+	    icrbb.b_wb, 
+	    icrbb.b_intvn, 
+	    icrbb.b_stall_ib, 
+	    icrbb.b_stall_int,
+	    icrbb.b_stall_bte_0, 
+	    icrbb.b_stall_bte_1, 
+	    icrbb.b_error,
+	    icrbb.b_lnetuce, 
+	    icrbb.b_mark, 
+	    icrbb.b_xerr);
+    printk("CRB %d regC\n\t"
+	    "c_source 0x%x\n\t"
+	    "c_xtsize 0x%x\n\t"
+	    "c_cohtrans 0x%x\n\t"
+	    "c_btenum 0x%x\n\t"
+	    "c_gbr 0x%x\n\t"
+	    "c_doresp 0x%x\n\t"
+	    "c_barrop 0x%x\n\t"
+	    "c_suppl 0x%x\n",
+	    crb_num,
+	    icrbc.c_source,
+	    icrbc.c_xtsize,
+	    icrbc.c_cohtrans,
+	    icrbc.c_btenum,
+	    icrbc.c_gbr,
+	    icrbc.c_doresp,
+	    icrbc.c_barrop,
+	    icrbc.c_suppl);
+    printk("CRB %d regD\n\t"
+	    "d_bteaddr 0x%lx\n\t"
+	    "d_bteop 0x%x\n\t"
+	    "d_pripsc 0x%x\n\t"
+	    "d_pricnt 0x%x\n\t"
+	    "d_sleep 0x%x\n\t",
+	    crb_num,
+	    icrbd.d_bteaddr,
+	    icrbd.d_bteop,
+	    icrbd.d_pripsc,
+	    icrbd.d_pricnt,
+	    icrbd.d_sleep);
+    printk("CRB %d regE\n\t"
+	    "icrbe_timeout 0x%x\n\t"
+	    "icrbe_context 0x%x\n\t"
+	    "icrbe_toutvld 0x%x\n\t"
+	    "icrbe_ctxtvld 0x%x\n\t",
+	    crb_num,
+	    icrbe.icrbe_timeout,
+	    icrbe.icrbe_context,
+	    icrbe.icrbe_toutvld,
+	    icrbe.icrbe_ctxtvld);
+}
+
 /*
  * hubiio_crb_error_handler
  *
@@ -317,7 +439,7 @@
  */
 
 int
-hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
+hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo)
 {
 	cnodeid_t	cnode;
 	nasid_t		nasid;
@@ -335,6 +457,9 @@
 	cnode = NASID_TO_COMPACT_NODEID(nasid);
 
 	/*
+	 * XXX - Add locking for any recovery actions
+	 */
+	/*
 	 * Scan through all CRBs in the Hub, and handle the errors
 	 * in any of the CRBs marked.
 	 */
@@ -373,16 +498,11 @@
 			else /* b_initiator bit 2 gives BTE number */
 				bte_num = (icrbb.b_initiator & 0x4) >> 2;
 
-			/* >>> bte_crb_error_handler needs to be 
-			 * broken into two parts.  The first should
-			 * cleanup the CRB.  The second should wait
-			 * until all bte related CRB's are complete
-			 * and then do the error reset.
-			 */
+			hubiio_crb_free(hinfo, i);
+
 			bte_crb_error_handler(hub_v, bte_num,
 					      i, &ioerror,
 					      icrbd.d_bteop);
-			hubiio_crb_free(hinfo, i);
 			num_errors++;
 			continue;
 		}
@@ -430,6 +550,86 @@
 			IOERROR_SETVALUE(&ioerror, tnum, icrba.a_tnum);
 
 		}
+		if (icrbb.b_error) {
+		    /*
+		     * CRB 'i' has some error. Identify the type of error,
+		     * and try to handle it.
+		     *
+		     */
+		    switch(icrbb.b_ecode) {
+			case IIO_ICRB_ECODE_PERR:
+			case IIO_ICRB_ECODE_WERR:
+			case IIO_ICRB_ECODE_AERR:
+			case IIO_ICRB_ECODE_PWERR:
+			case IIO_ICRB_ECODE_TOUT:
+			case IIO_ICRB_ECODE_XTERR:
+			    printk("Shub II CRB %d: error %s on hub cnodeid: %d",
+				    i, hubiio_crb_errors[icrbb.b_ecode], cnode);
+			    /*
+			     * Any sort of write error is mostly due
+			     * bad programming (Note it's not a timeout.)
+			     * So, invoke hub_iio_error_handler with
+			     * appropriate information.
+			     */
+			    IOERROR_SETVALUE(&ioerror,errortype,icrbb.b_ecode);
+
+			    /* Go through the error bit lookup phase */
+			    if (error_state_set(hub_v, ERROR_STATE_LOOKUP) ==
+				    ERROR_RETURN_CODE_CANNOT_SET_STATE)
+				return(IOERROR_UNHANDLED);
+			    rc = hub_ioerror_handler(
+				    hub_v,
+				    DMA_WRITE_ERROR,
+				    MODE_DEVERROR,
+				    &ioerror);
+			    if (rc == IOERROR_HANDLED) {
+				rc = hub_ioerror_handler(
+					hub_v,
+					DMA_WRITE_ERROR,
+					MODE_DEVREENABLE,
+					&ioerror);
+			    }else {
+				printk("Unable to handle %s on hub %d",
+					hubiio_crb_errors[icrbb.b_ecode],
+					cnode);
+				/* panic; */
+			    }
+			    /* Go to Next error */
+			    print_crb_fields(i, icrba, icrbb, icrbc,
+				    icrbd, icrbe);
+			    hubiio_crb_free(hinfo, i);
+			    continue;
+			case IIO_ICRB_ECODE_PRERR:
+			case IIO_ICRB_ECODE_DERR:
+			    printk("Shub II CRB %d: error %s on hub : %d",
+				    i, hubiio_crb_errors[icrbb.b_ecode], cnode);
+			    /* panic */
+			default:
+			    printk("Shub II CRB error (code : %d) on hub : %d",
+				    icrbb.b_ecode, cnode);
+			    /* panic */
+		    }
+		} 
+		/*
+		 * Error is not indicated via the errcode field
+		 * Check other error indications in this register.
+		 */
+		if (icrbb.b_xerr) {
+		    printk("Shub II CRB %d: Xtalk Packet with error bit set to hub %d",
+			    i, cnode);
+		    /* panic */
+		}
+		if (icrbb.b_lnetuce) {
+		    printk("Shub II CRB %d: Uncorrectable data error detected on data "
+			    " from NUMAlink to node %d",
+			    i, cnode);
+		    /* panic */
+		}
+		print_crb_fields(i, icrba, icrbb, icrbc, icrbd, icrbe);
+
+
+
+
 
 		if (icrbb.b_error) {
 		/* 
@@ -488,7 +688,7 @@
 		
 		default:
 			panic("Fatal error (code : %d) on hub : %d",
-				cnode);
+				icrbb.b_ecode, cnode);
 			/*NOTREACHED*/
 
 		}
@@ -568,7 +768,7 @@
  *      Cleanup involes freeing the PRB register
  */
 static void
-hubii_prb_handler(devfs_handle_t hub_v, hubinfo_t hinfo, int wnum)
+hubii_prb_handler(vertex_hdl_t hub_v, hubinfo_t hinfo, int wnum)
 {
         nasid_t         nasid;
 
@@ -576,13 +776,13 @@
         /*
          * Clear error bit by writing to IECLR register.
          */
-        REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, (1 << wnum));
+        REMOTE_HUB_S(nasid, IIO_IECLR, (1 << wnum));
         /*
          * PIO Write to Widget 'i' got into an error.
          * Invoke hubiio_error_handler with this information.
          */
-        printk( "Hub nasid %d got a PIO Write error from widget %d, cleaning up and continuing",
-                        nasid, wnum);
+        printk( "Hub nasid %d got a PIO Write error from widget %d, "
+				"cleaning up and continuing", nasid, wnum);
         /*
          * XXX
          * It may be necessary to adjust IO PRB counter
@@ -591,7 +791,7 @@
 }
 
 int
-hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
+hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo)
 {
         int             wnum;
         nasid_t         nasid;
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/shubio.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/shubio.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/shubio.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/shubio.c	2003-07-05 18:09:45.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000,2002-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -30,8 +30,8 @@
 #include <asm/sn/sn2/shubio.h>
 
 
-error_state_t error_state_get(devfs_handle_t v);
-error_return_code_t error_state_set(devfs_handle_t v,error_state_t new_state);
+error_state_t error_state_get(vertex_hdl_t v);
+error_return_code_t error_state_set(vertex_hdl_t v,error_state_t new_state);
 
 
 /*
@@ -42,7 +42,7 @@
 /*ARGSUSED*/
 int
 hub_xp_error_handler(
-	devfs_handle_t 	hub_v, 
+	vertex_hdl_t 	hub_v, 
 	nasid_t		nasid, 
 	int		error_code, 
 	ioerror_mode_t	mode, 
@@ -50,7 +50,7 @@
 {
 	/*REFERENCED*/
 	hubreg_t	iio_imem;
-	devfs_handle_t	xswitch;
+	vertex_hdl_t	xswitch;
 	error_state_t	e_state;
 	cnodeid_t	cnode;
 
@@ -148,7 +148,7 @@
  */
 int
 hub_ioerror_handler(
-	devfs_handle_t 	hub_v, 
+	vertex_hdl_t 	hub_v, 
 	int		error_code,
 	int		mode,
 	struct io_error_s	*ioerror)
@@ -158,6 +158,7 @@
 	int		retval = 0;
 	/*REFERENCED*/
 	iopaddr_t 	p;
+	caddr_t 	cp;
 
 	IOERROR_DUMP("hub_ioerror_handler", error_code, mode, ioerror);
 
@@ -193,14 +194,14 @@
 		 * This is typically true for user mode bus errors while
 		 * accessing I/O space.
 		 */
-		 IOERROR_GETVALUE(p,ioerror,vaddr);
-		 if (p){
+		 IOERROR_GETVALUE(cp,ioerror,vaddr);
+		 if (cp){
 		    /* 
 		     * If neither in small window nor in large window range,
 		     * outright reject it.
 		     */
-		    IOERROR_GETVALUE(p,ioerror,vaddr);
-		    if (NODE_SWIN_ADDR(nasid, (paddr_t)p)){
+		    IOERROR_GETVALUE(cp,ioerror,vaddr);
+		    if (NODE_SWIN_ADDR(nasid, (paddr_t)cp)){
 			iopaddr_t	hubaddr;
 			xwidgetnum_t	widgetnum;
 			iopaddr_t	xtalkaddr;
@@ -216,7 +217,7 @@
 			IOERROR_SETVALUE(ioerror,xtalkaddr,xtalkaddr);
 
 
-		    } else if (NODE_BWIN_ADDR(nasid, (paddr_t)p)){
+		    } else if (NODE_BWIN_ADDR(nasid, (paddr_t)cp)){
 			/* 
 			 * Address corresponds to large window space. 
 			 * Convert it to xtalk address.
@@ -428,11 +429,6 @@
 	return retval;
 }
 
-#define L_BITSMINOR 18
-#define L_MAXMAJ 0x1ff
-#define emajor(x) (int )(((unsigned )(x)>>L_BITSMINOR) & L_MAXMAJ)
-#define dev_is_vertex(dev) (emajor((dev_t)(dev)) == 0)
-
 #define INFO_LBL_ERROR_STATE    "error_state"
 
 #define v_error_state_get(v,s)                                          \
@@ -454,12 +450,12 @@
  *                      current state otherwise
  */
 error_state_t
-error_state_get(devfs_handle_t v)
+error_state_get(vertex_hdl_t v)
 {
         error_state_t   s;
 
         /* Check if we have a valid hwgraph vertex */
-        if (!dev_is_vertex(v))
+        if ( v == (vertex_hdl_t)0 )
                 return(ERROR_STATE_NONE);
 
         /* Get the labelled info hanging off the vertex which corresponds
@@ -479,13 +475,13 @@
  *                      ERROR_RETURN_CODE_SUCCESS otherwise
  */
 error_return_code_t
-error_state_set(devfs_handle_t v,error_state_t new_state)
+error_state_set(vertex_hdl_t v,error_state_t new_state)
 {
         error_state_t   old_state;
         boolean_t       replace = B_TRUE;
 
         /* Check if we have a valid hwgraph vertex */
-        if (!dev_is_vertex(v))
+        if ( v == (vertex_hdl_t)0 )
                 return(ERROR_RETURN_CODE_GENERAL_FAILURE);
 
 
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/xbow.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/xbow.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/xbow.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/xbow.c	2003-07-05 18:09:45.000000000 -0700
@@ -4,12 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/interrupt.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/sn2/sn_private.h>
@@ -18,7 +20,6 @@
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
-#include <asm/sn/hack.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/xtalk/xtalk_private.h>
 #include <asm/sn/simulator.h>
@@ -44,8 +45,6 @@
 #define NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
 #define DEL(ptr)	(kfree(ptr))
 
-int                     xbow_devflag = D_MP;
-
 /*
  * This file supports the Xbow chip.  Main functions: initializtion,
  * error handling, and GBR.
@@ -59,9 +58,9 @@
 typedef struct xbow_soft_s *xbow_soft_t;
 
 struct xbow_soft_s {
-    devfs_handle_t            conn;	/* our connection point */
-    devfs_handle_t            vhdl;	/* xbow's private vertex */
-    devfs_handle_t            busv;	/* the xswitch vertex */
+    vertex_hdl_t            conn;	/* our connection point */
+    vertex_hdl_t            vhdl;	/* xbow's private vertex */
+    vertex_hdl_t            busv;	/* the xswitch vertex */
     xbow_t                 *base;	/* PIO pointer to crossbow chip */
     char                   *name;	/* hwgraph name */
 
@@ -89,36 +88,27 @@
  */
 
 void                    xbow_mlreset(xbow_t *);
-void                    xbow_init(void);
-int                     xbow_attach(devfs_handle_t);
-
-int                     xbow_open(devfs_handle_t *, int, int, cred_t *);
-int                     xbow_close(devfs_handle_t, int, int, cred_t *);
-
-int                     xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     xbow_unmap(devfs_handle_t, vhandl_t *);
-int                     xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
+int                     xbow_attach(vertex_hdl_t);
 
 int                     xbow_widget_present(xbow_t *, int);
 static int              xbow_link_alive(xbow_t *, int);
-devfs_handle_t            xbow_widget_lookup(devfs_handle_t, int);
+vertex_hdl_t            xbow_widget_lookup(vertex_hdl_t, int);
 
 void                    xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
 
 
 
-void                    xbow_update_perf_counters(devfs_handle_t);
-xbow_perf_link_t       *xbow_get_perf_counters(devfs_handle_t);
-int                     xbow_enable_perf_counter(devfs_handle_t, int, int, int);
-xbow_link_status_t     *xbow_get_llp_status(devfs_handle_t);
-void                    xbow_update_llp_status(devfs_handle_t);
-
-int                     xbow_disable_llp_monitor(devfs_handle_t);
-int                     xbow_enable_llp_monitor(devfs_handle_t);
-int                     xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t,
+void                    xbow_update_perf_counters(vertex_hdl_t);
+xbow_perf_link_t       *xbow_get_perf_counters(vertex_hdl_t);
+int                     xbow_enable_perf_counter(vertex_hdl_t, int, int, int);
+xbow_link_status_t     *xbow_get_llp_status(vertex_hdl_t);
+void                    xbow_update_llp_status(vertex_hdl_t);
+
+int                     xbow_disable_llp_monitor(vertex_hdl_t);
+int                     xbow_enable_llp_monitor(vertex_hdl_t);
+int                     xbow_prio_bw_alloc(vertex_hdl_t, xwidgetnum_t, xwidgetnum_t,
                                 unsigned long long, unsigned long long);
 static void		xbow_setwidint(xtalk_intr_t);
-void                    idbg_xbowregs(int64_t);
 
 xswitch_reset_link_f    xbow_reset_link;
 
@@ -127,6 +117,32 @@
     xbow_reset_link,
 };
 
+
+static int
+xbow_mmap(struct file * file, struct vm_area_struct * vma)
+{
+        unsigned long           phys_addr;
+        int                     error = 0;
+
+        phys_addr = (unsigned long)file->private_data & ~0xc000000000000000; /* Mask out the Uncache bits */
+        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+        vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
+        error = io_remap_page_range(vma->vm_start, phys_addr,
+                                   vma->vm_end-vma->vm_start,
+                                   vma->vm_page_prot);
+        return(error);
+}
+
+/*
+ * This is the file operation table for the pcibr driver.
+ * As each of the functions are implemented, put the
+ * appropriate function name below.
+ */
+struct file_operations xbow_fops = {
+        .owner		= THIS_MODULE,
+        .mmap		= xbow_mmap,
+};
+
 /*
  *    xbow_mlreset: called at mlreset time if the
  *      platform specific code determines that there is
@@ -144,39 +160,6 @@
 {
 }
 
-/*
- *    xbow_init: called with the rest of the device
- *      driver XXX_init routines. This platform *might*
- *      have a Crossbow chip, or even several, but it
- *      might have none. Register with the crosstalk
- *      generic provider so when we encounter the chip
- *      the right magic happens.
- */
-void
-xbow_init(void)
-{
-
-#if DEBUG && ATTACH_DEBUG
-    printk("xbow_init\n");
-#endif
-
-    xwidget_driver_register(PXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-
-    xwidget_driver_register(XXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-    xwidget_driver_register(XBOW_WIDGET_PART_NUM,
-			    XBOW_WIDGET_MFGR_NUM,
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-}
-
 #ifdef XBRIDGE_REGS_SIM
 /*    xbow_set_simulated_regs: sets xbow regs as needed
  *	for powering through the boot
@@ -213,11 +196,11 @@
 
 /*ARGSUSED */
 int
-xbow_attach(devfs_handle_t conn)
+xbow_attach(vertex_hdl_t conn)
 {
     /*REFERENCED */
-    devfs_handle_t            vhdl;
-    devfs_handle_t            busv;
+    vertex_hdl_t            vhdl;
+    vertex_hdl_t            busv;
     xbow_t                 *xbow;
     xbow_soft_t             soft;
     int                     port;
@@ -274,15 +257,14 @@
      */
 
     /*
-     * We need to teach xbow drivers to provide the right set of
+     * Register a xbow driver with devfs.
      * file ops.
      */
     vhdl = NULL;
-    vhdl = hwgraph_register(conn, EDGE_LBL_XBOW,
-                        0, DEVFS_FL_AUTO_DEVNUM,
-                        0, 0,
-                        S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                        /* &hcl_fops */ (void *)&vhdl, NULL);
+    vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, 0,
+	   DEVFS_FL_AUTO_DEVNUM, 0, 0,
+	   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+	   (struct file_operations *)&xbow_fops, (void *)xbow);
     if (!vhdl) {
         printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n",
                 (void *)conn);
@@ -299,7 +281,7 @@
     soft->base = xbow;
     /* does the universe really need another macro?  */
     /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */
-    hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft);
+    /* hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft); */
 
 #define XBOW_NUM_SUFFIX_FORMAT	"[xbow# %d]"
 
@@ -350,6 +332,14 @@
       */
      intr_hdl = xtalk_intr_alloc(conn, (device_desc_t)0, vhdl);
      ASSERT(intr_hdl != NULL);
+
+        {
+                int irq = ((hub_intr_t)intr_hdl)->i_bit;
+                int cpu = ((hub_intr_t)intr_hdl)->i_cpuid;
+
+                intr_unreserve_level(cpu, irq);
+                ((hub_intr_t)intr_hdl)->i_bit = SGI_XBOW_ERROR;
+        }
  
      xtalk_intr_connect(intr_hdl,
                         (intr_func_t) xbow_errintr_handler,
@@ -357,19 +347,9 @@
                         (xtalk_intr_setfunc_t) xbow_setwidint,
                         (void *) xbow);
 
-#ifdef BUS_INT_WAR_NOT_YET
-     request_irq(CPU_VECTOR_TO_IRQ(((hub_intr_t)intr_hdl)->i_cpuid,
-			((hub_intr_t)intr_hdl)->i_bit),
-			(intr_func_t)xbow_errintr_handler, 0, "XBOW error",
+     request_irq(SGI_XBOW_ERROR, (void *)xbow_errintr_handler, SA_SHIRQ, "XBOW error",
 			(intr_arg_t) soft);
 
-    {
-	void sn_add_polled_interrupt(int, int);
-        sn_add_polled_interrupt(CPU_VECTOR_TO_IRQ(((hub_intr_t)intr_hdl)->i_cpuid,
-                                ((hub_intr_t)intr_hdl)->i_bit), 5000);
-    }
-#endif
-
  
     /*
      * Enable xbow error interrupts
@@ -439,50 +419,14 @@
     return 0;				/* attach successful */
 }
 
-/*ARGSUSED */
-int
-xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    int                     error;
-
-    ASSERT(soft);
-    len = ctob(btoc(len));
-    /* XXX- this ignores the offset!!! */
-    error = v_mapphys(vt, (void *) soft->base, len);
-    return error;
-}
-
-/*ARGSUSED */
-int
-xbow_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    return 0;
-}
-
 /* This contains special-case code for grio. There are plans to make
  * this general sometime in the future, but till then this should
  * be good enough.
  */
 xwidgetnum_t
-xbow_widget_num_get(devfs_handle_t dev)
+xbow_widget_num_get(vertex_hdl_t dev)
 {
-	devfs_handle_t	tdev;
+	vertex_hdl_t	tdev;
 	char		devname[MAXDEVNAME];
 	xwidget_info_t	xwidget_info;
 	int		i;
@@ -512,58 +456,6 @@
 	return XWIDGET_NONE;
 }
 
-int
-xbow_ioctl(devfs_handle_t dev,
-	   int cmd,
-	   void *arg,
-	   int flag,
-	   struct cred *cr,
-	   int *rvalp)
-{
-    devfs_handle_t            vhdl;
-    int                     error = 0;
-
-#if defined (DEBUG)
-    int                     rc;
-    devfs_handle_t            conn;
-    struct xwidget_info_s  *xwidget_info;
-    xbow_soft_t             xbow_soft;
-#endif
-    *rvalp = 0;
-
-    vhdl = dev_to_vhdl(dev);
-#if defined (DEBUG)
-    xbow_soft = xbow_soft_get(vhdl);
-    conn = xbow_soft->conn;
-
-    xwidget_info = xwidget_info_get(conn);
-    ASSERT_ALWAYS(xwidget_info != NULL);
-
-    rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid);
-    ASSERT_ALWAYS(rc != 0);
-#endif
-    switch (cmd) {
-
-    case XBOWIOC_LLP_ERROR_ENABLE:
-	if ((error = xbow_enable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    case XBOWIOC_LLP_ERROR_DISABLE:
-
-	if ((error = xbow_disable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    default:
-	break;
-
-    }
-    return error;
-}
-
 /*
  * xbow_widget_present: See if a device is present
  * on the specified port of this crossbow.
@@ -605,12 +497,12 @@
  *      specified.
  *      If not found, return 0.
  */
-devfs_handle_t
-xbow_widget_lookup(devfs_handle_t vhdl,
+vertex_hdl_t
+xbow_widget_lookup(vertex_hdl_t vhdl,
 		   int widgetnum)
 {
     xswitch_info_t          xswitch_info;
-    devfs_handle_t            conn;
+    vertex_hdl_t            conn;
 
     xswitch_info = xswitch_info_get(vhdl);
     conn = xswitch_info_vhdl_get(xswitch_info, widgetnum);
@@ -660,10 +552,6 @@
 			      XTALK_ADDR_TO_UPPER(addr));
     xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
 
-#ifdef BRINGUP2
-printk("xbow_intr_preset: xb_wid_int_upper 0x%lx xb_wid_int_lower 0x%lx\n",
-	(long)(((0xFF000000 & (vect << 24)) | (0x000F0000 & (targ << 16)) |XTALK_ADDR_TO_UPPER(addr))), (long)XTALK_ADDR_TO_LOWER(addr));
-#endif
 }
 
 #define	XEM_ADD_STR(s)		printk("%s", (s))
@@ -674,48 +562,14 @@
 				    XEM_ADD_NVAR("ioe." #n, p);		\
 				}
 
-#ifdef LATER
-static void
-xem_add_ioe(ioerror_t *ioe)
-{
-    union tmp {
-	ushort stmp;
-	unsigned long long lltmp;
-	cpuid_t cputmp;
-	cnodeid_t cntmp;
-	iopaddr_t iotmp;
-	caddr_t catmp;
-	paddr_t patmp;
-    } tmp;
-
-    XEM_ADD_IOEF(tmp.stmp, errortype);
-    XEM_ADD_IOEF(tmp.stmp, widgetnum);
-    XEM_ADD_IOEF(tmp.stmp, widgetdev);
-    XEM_ADD_IOEF(tmp.cputmp, srccpu);
-    XEM_ADD_IOEF(tmp.cntmp, srcnode);
-    XEM_ADD_IOEF(tmp.cntmp, errnode);
-    XEM_ADD_IOEF(tmp.iotmp, sysioaddr);
-    XEM_ADD_IOEF(tmp.iotmp, xtalkaddr);
-    XEM_ADD_IOEF(tmp.iotmp, busspace);
-    XEM_ADD_IOEF(tmp.iotmp, busaddr);
-    XEM_ADD_IOEF(tmp.catmp, vaddr);
-    XEM_ADD_IOEF(tmp.patmp, memaddr);
-    XEM_ADD_IOEF(tmp.catmp, epc);
-    XEM_ADD_IOEF(tmp.catmp, ef);
-    XEM_ADD_IOEF(tmp.stmp, tnum);
-}
-
-#define XEM_ADD_IOE()   (xem_add_ioe(ioe))
-#endif	/* LATER */
-
-int                     xbow_xmit_retry_errors = 0;
+int                     xbow_xmit_retry_errors;
 
 int
 xbow_xmit_retry_error(xbow_soft_t soft,
 		      int port)
 {
     xswitch_info_t          info;
-    devfs_handle_t            vhdl;
+    vertex_hdl_t            vhdl;
     widget_cfg_t           *wid;
     widgetreg_t             id;
     int                     part;
@@ -865,7 +719,7 @@
 		    link_pend &= ~XB_STAT_XMT_RTRY_ERR;
 		}
 		if (link_pend) {
-		    devfs_handle_t	xwidget_vhdl;
+		    vertex_hdl_t	xwidget_vhdl;
 		    char		*xwidget_name;
 		    
 		    /* Get the widget name corresponding to the current
@@ -917,12 +771,6 @@
 			XEM_ADD_VAR(link_status);
 			XEM_ADD_VAR(link_aux_status);
 
-#ifdef LATER
-			if (dump_ioe) {
-			    XEM_ADD_IOE();
-			    dump_ioe = 0;
-			}
-#endif
 #if !DEBUG
 		    }
 #endif
@@ -987,8 +835,8 @@
 
     xbow_soft_t             soft = (xbow_soft_t) einfo;
     int                     port;
-    devfs_handle_t          conn;
-    devfs_handle_t          busv;
+    vertex_hdl_t          conn;
+    vertex_hdl_t          busv;
 
     xbow_t                 *xbow = soft->base;
     xbowreg_t               wid_stat;
@@ -1240,7 +1088,7 @@
 }
 
 void
-xbow_update_perf_counters(devfs_handle_t vhdl)
+xbow_update_perf_counters(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
@@ -1268,7 +1116,7 @@
 }
 
 xbow_perf_link_t       *
-xbow_get_perf_counters(devfs_handle_t vhdl)
+xbow_get_perf_counters(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_perf_link_t       *xbow_perf_link = xbow_soft->xbow_perflink;
@@ -1277,7 +1125,7 @@
 }
 
 int
-xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter)
+xbow_enable_perf_counter(vertex_hdl_t vhdl, int link, int mode, int counter)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
@@ -1331,7 +1179,7 @@
 }
 
 xbow_link_status_t     *
-xbow_get_llp_status(devfs_handle_t vhdl)
+xbow_get_llp_status(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
@@ -1340,7 +1188,7 @@
 }
 
 void
-xbow_update_llp_status(devfs_handle_t vhdl)
+xbow_update_llp_status(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
@@ -1348,7 +1196,7 @@
     xbwX_stat_t             lnk_sts;
     xbow_aux_link_status_t  aux_sts;
     int                     link;
-    devfs_handle_t	    xwidget_vhdl;
+    vertex_hdl_t	    xwidget_vhdl;
     char		   *xwidget_name;	
 
     xbow = (xbow_t *) xbow_soft->base;
@@ -1382,7 +1230,7 @@
 }
 
 int
-xbow_disable_llp_monitor(devfs_handle_t vhdl)
+xbow_disable_llp_monitor(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     int                     port;
@@ -1397,7 +1245,7 @@
 }
 
 int
-xbow_enable_llp_monitor(devfs_handle_t vhdl)
+xbow_enable_llp_monitor(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
 
@@ -1407,7 +1255,7 @@
 
 
 int
-xbow_reset_link(devfs_handle_t xconn_vhdl)
+xbow_reset_link(vertex_hdl_t xconn_vhdl)
 {
     xwidget_info_t          widget_info;
     xwidgetnum_t            port;
@@ -1430,7 +1278,7 @@
     xbow = XBOW_K1PTR;
 #else
     {
-	devfs_handle_t            xbow_vhdl;
+	vertex_hdl_t            xbow_vhdl;
 	xbow_soft_t             xbow_soft;
 
 	hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl);
@@ -1463,46 +1311,6 @@
     return 0;
 }
 
-/*
- * Dump xbow registers.
- * input parameter is either a pointer to
- * the xbow chip or the vertex handle for
- * an xbow vertex.
- */
-void
-idbg_xbowregs(int64_t regs)
-{
-    xbow_t                 *xbow;
-    int                     i;
-    xb_linkregs_t          *link;
-
-    xbow = (xbow_t *) regs;
-
-#ifdef LATER
-    qprintf("Printing xbow registers starting at 0x%x\n", xbow);
-    qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n",
-	    xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper,
-	    xbow->xb_wid_err_lower, xbow->xb_wid_control,
-	    xbow->xb_wid_req_timeout);
-    qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n",
-	    xbow->xb_wid_int_upper, xbow->xb_wid_int_lower,
-	    xbow->xb_wid_err_cmdword, xbow->xb_wid_llp,
-	    xbow->xb_wid_arb_reload);
-#endif
-
-    for (i = 8; i <= 0xf; i++) {
-	link = &xbow->xb_link(i);
-#ifdef LATER
-	qprintf("Link %d registers\n", i);
-	qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n",
-		link->link_control, link->link_status,
-		link->link_arb_upper, link->link_arb_lower,
-		link->link_aux_status);
-#endif
-    }
-}
-
-
 #define XBOW_ARB_RELOAD_TICKS		25
 					/* granularity: 4 MB/s, max: 124 MB/s */
 #define GRANULARITY			((100 * 1000000) / XBOW_ARB_RELOAD_TICKS)
@@ -1562,7 +1370,7 @@
  * If bandwidth allocation is successful, return success else return failure.
  */
 int
-xbow_prio_bw_alloc(devfs_handle_t vhdl,
+xbow_prio_bw_alloc(vertex_hdl_t vhdl,
 		xwidgetnum_t src_wid,
 		xwidgetnum_t dest_wid,
 		unsigned long long old_alloc_bw,
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/sn2/xtalk.c linux-2.4.22-pre3/arch/ia64/sn/io/sn2/xtalk.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/sn2/xtalk.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/sn2/xtalk.c	2003-07-05 18:09:45.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -37,8 +37,6 @@
 
 char                    widget_info_fingerprint[] = "widget_info";
 
-cdl_p                   xtalk_registry = NULL;
-
 #define	DEV_FUNC(dev,func)	hub_##func
 #define	CAST_PIOMAP(x)		((hub_piomap_t)(x))
 #define	CAST_DMAMAP(x)		((hub_dmamap_t)(x))
@@ -47,71 +45,70 @@
 /* =====================================================================
  *            Function Table of Contents
  */
-xtalk_piomap_t          xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
+xtalk_piomap_t          xtalk_piomap_alloc(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
 void                    xtalk_piomap_free(xtalk_piomap_t);
 caddr_t                 xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t);
 void                    xtalk_piomap_done(xtalk_piomap_t);
-caddr_t                 xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned);
-caddr_t                 xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
+caddr_t                 xtalk_piotrans_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, unsigned);
+caddr_t                 xtalk_pio_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
 void                    xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
 caddr_t                 xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
 static caddr_t          null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-xtalk_dmamap_t          xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
+xtalk_dmamap_t          xtalk_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned);
 void                    xtalk_dmamap_free(xtalk_dmamap_t);
 iopaddr_t               xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);
 alenlist_t              xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);
 void                    xtalk_dmamap_done(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
+iopaddr_t               xtalk_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
+alenlist_t              xtalk_dmatrans_list(vertex_hdl_t, device_desc_t, alenlist_t, unsigned);
 void			xtalk_dmamap_drain(xtalk_dmamap_t);
-void			xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t);
-void			xtalk_dmalist_drain(devfs_handle_t, alenlist_t);
-xtalk_intr_t            xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t);
-xtalk_intr_t            xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t);
+void			xtalk_dmaaddr_drain(vertex_hdl_t, iopaddr_t, size_t);
+void			xtalk_dmalist_drain(vertex_hdl_t, alenlist_t);
+xtalk_intr_t            xtalk_intr_alloc(vertex_hdl_t, device_desc_t, vertex_hdl_t);
+xtalk_intr_t            xtalk_intr_alloc_nothd(vertex_hdl_t, device_desc_t, vertex_hdl_t);
 void                    xtalk_intr_free(xtalk_intr_t);
 int                     xtalk_intr_connect(xtalk_intr_t, intr_func_t, intr_arg_t, xtalk_intr_setfunc_t, void *);
 void                    xtalk_intr_disconnect(xtalk_intr_t);
-devfs_handle_t            xtalk_intr_cpu_get(xtalk_intr_t);
-int                     xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
-int                     xtalk_error_devenable(devfs_handle_t, int, int);
-void                    xtalk_provider_startup(devfs_handle_t);
-void                    xtalk_provider_shutdown(devfs_handle_t);
-devfs_handle_t            xtalk_intr_dev_get(xtalk_intr_t);
+vertex_hdl_t            xtalk_intr_cpu_get(xtalk_intr_t);
+int                     xtalk_error_handler(vertex_hdl_t, int, ioerror_mode_t, ioerror_t *);
+int                     xtalk_error_devenable(vertex_hdl_t, int, int);
+void                    xtalk_provider_startup(vertex_hdl_t);
+void                    xtalk_provider_shutdown(vertex_hdl_t);
+vertex_hdl_t            xtalk_intr_dev_get(xtalk_intr_t);
 xwidgetnum_t            xtalk_intr_target_get(xtalk_intr_t);
 xtalk_intr_vector_t     xtalk_intr_vector_get(xtalk_intr_t);
 iopaddr_t               xtalk_intr_addr_get(struct xtalk_intr_s *);
 void                   *xtalk_intr_sfarg_get(xtalk_intr_t);
-devfs_handle_t            xtalk_pio_dev_get(xtalk_piomap_t);
+vertex_hdl_t            xtalk_pio_dev_get(xtalk_piomap_t);
 xwidgetnum_t            xtalk_pio_target_get(xtalk_piomap_t);
 iopaddr_t               xtalk_pio_xtalk_addr_get(xtalk_piomap_t);
 ulong                   xtalk_pio_mapsz_get(xtalk_piomap_t);
 caddr_t                 xtalk_pio_kvaddr_get(xtalk_piomap_t);
-devfs_handle_t            xtalk_dma_dev_get(xtalk_dmamap_t);
+vertex_hdl_t            xtalk_dma_dev_get(xtalk_dmamap_t);
 xwidgetnum_t            xtalk_dma_target_get(xtalk_dmamap_t);
-xwidget_info_t          xwidget_info_chk(devfs_handle_t);
-xwidget_info_t          xwidget_info_get(devfs_handle_t);
-void                    xwidget_info_set(devfs_handle_t, xwidget_info_t);
-devfs_handle_t            xwidget_info_dev_get(xwidget_info_t);
+xwidget_info_t          xwidget_info_chk(vertex_hdl_t);
+xwidget_info_t          xwidget_info_get(vertex_hdl_t);
+void                    xwidget_info_set(vertex_hdl_t, xwidget_info_t);
+vertex_hdl_t            xwidget_info_dev_get(xwidget_info_t);
 xwidgetnum_t            xwidget_info_id_get(xwidget_info_t);
-devfs_handle_t            xwidget_info_master_get(xwidget_info_t);
+vertex_hdl_t            xwidget_info_master_get(xwidget_info_t);
 xwidgetnum_t            xwidget_info_masterid_get(xwidget_info_t);
 xwidget_part_num_t      xwidget_info_part_num_get(xwidget_info_t);
 xwidget_mfg_num_t       xwidget_info_mfg_num_get(xwidget_info_t);
 char 			*xwidget_info_name_get(xwidget_info_t);
-void                    xtalk_init(void);
-void                    xtalk_provider_register(devfs_handle_t, xtalk_provider_t *);
-void                    xtalk_provider_unregister(devfs_handle_t);
-xtalk_provider_t       *xtalk_provider_fns_get(devfs_handle_t);
+void                    xtalk_provider_register(vertex_hdl_t, xtalk_provider_t *);
+void                    xtalk_provider_unregister(vertex_hdl_t);
+xtalk_provider_t       *xtalk_provider_fns_get(vertex_hdl_t);
 int                     xwidget_driver_register(xwidget_part_num_t, 
 						xwidget_mfg_num_t, 
 						char *, unsigned);
 void                    xwidget_driver_unregister(char *);
-int                     xwidget_register(xwidget_hwid_t, devfs_handle_t, 
-					 xwidgetnum_t, devfs_handle_t, 
-					 xwidgetnum_t, async_attach_t);
-int			xwidget_unregister(devfs_handle_t);
-void                    xwidget_reset(devfs_handle_t);
-char			*xwidget_name_get(devfs_handle_t);
+int                     xwidget_register(xwidget_hwid_t, vertex_hdl_t, 
+					 xwidgetnum_t, vertex_hdl_t, 
+					 xwidgetnum_t);
+int			xwidget_unregister(vertex_hdl_t);
+void                    xwidget_reset(vertex_hdl_t);
+char			*xwidget_name_get(vertex_hdl_t);
 #if !defined(DEV_FUNC)
 /*
  * There is more than one possible provider
@@ -126,7 +123,7 @@
 #define	CAST_INTR(x)		((xtalk_intr_t)(x))
 
 static xtalk_provider_t *
-xwidget_to_provider_fns(devfs_handle_t xconn)
+xwidget_to_provider_fns(vertex_hdl_t xconn)
 {
     xwidget_info_t          widget_info;
     xtalk_provider_t       *provider_fns;
@@ -159,7 +156,7 @@
  */
 
 xtalk_piomap_t
-xtalk_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
+xtalk_piomap_alloc(vertex_hdl_t dev,	/* set up mapping for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
 		   size_t byte_count,
@@ -198,7 +195,7 @@
 
 
 caddr_t
-xtalk_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
+xtalk_piotrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    iopaddr_t xtalk_addr,	/* Crosstalk address */
 		    size_t byte_count,	/* map this many bytes */
@@ -209,7 +206,7 @@
 }
 
 caddr_t
-xtalk_pio_addr(devfs_handle_t dev,	/* translate for this device */
+xtalk_pio_addr(vertex_hdl_t dev,	/* translate for this device */
 	       device_desc_t dev_desc,	/* device descriptor */
 	       iopaddr_t addr,		/* starting address (or offset in window) */
 	       size_t byte_count,	/* map this many bytes */
@@ -326,7 +323,7 @@
  */
 
 xtalk_dmamap_t
-xtalk_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
+xtalk_dmamap_alloc(vertex_hdl_t dev,	/* set up mappings for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   size_t byte_count_max,	/* max size of a mapping */
 		   unsigned flags)
@@ -373,7 +370,7 @@
 
 
 iopaddr_t
-xtalk_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
+xtalk_dmatrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    paddr_t paddr,	/* system physical address */
 		    size_t byte_count,	/* length */
@@ -385,7 +382,7 @@
 
 
 alenlist_t
-xtalk_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
+xtalk_dmatrans_list(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    alenlist_t palenlist,	/* system address/length list */
 		    unsigned flags)
@@ -402,14 +399,14 @@
 }
 
 void
-xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
+xtalk_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
 {
     DEV_FUNC(dev, dmaaddr_drain)
 	(dev, addr, size);
 }
 
 void
-xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list)
+xtalk_dmalist_drain(vertex_hdl_t dev, alenlist_t list)
 {
     DEV_FUNC(dev, dmalist_drain)
 	(dev, list);
@@ -426,9 +423,9 @@
  * Return resource handle in intr_hdl.
  */
 xtalk_intr_t
-xtalk_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
+xtalk_intr_alloc(vertex_hdl_t dev,	/* which Crosstalk device */
 		 device_desc_t dev_desc,	/* device descriptor */
-		 devfs_handle_t owner_dev)
+		 vertex_hdl_t owner_dev)
 {				/* owner of this interrupt */
     return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc)
 	(dev, dev_desc, owner_dev);
@@ -440,9 +437,9 @@
  * Return resource handle in intr_hdl.
  */
 xtalk_intr_t
-xtalk_intr_alloc_nothd(devfs_handle_t dev,	/* which Crosstalk device */
+xtalk_intr_alloc_nothd(vertex_hdl_t dev,	/* which Crosstalk device */
 		 	device_desc_t dev_desc,	/* device descriptor */
-		 	devfs_handle_t owner_dev)	/* owner of this interrupt */
+		 	vertex_hdl_t owner_dev)	/* owner of this interrupt */
 {
     return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)
 	(dev, dev_desc, owner_dev);
@@ -492,11 +489,10 @@
  * Return a hwgraph vertex that represents the CPU currently
  * targeted by an interrupt.
  */
-devfs_handle_t
+vertex_hdl_t
 xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
 {
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
+      return (vertex_hdl_t)0;
 }
 
 
@@ -526,7 +522,7 @@
  */
 int
 xtalk_error_handler(
-		       devfs_handle_t xconn,
+		       vertex_hdl_t xconn,
 		       int error_code,
 		       ioerror_mode_t mode,
 		       ioerror_t *ioerror)
@@ -555,7 +551,7 @@
 #if defined(SUPPORT_PRINTING_V_FORMAT)
     printk(KERN_WARNING "Xbow at %v encountered Fatal error", xconn);
 #else
-    printk(KERN_WARNING "Xbow at 0x%p encountered Fatal error", xconn);
+    printk(KERN_WARNING "Xbow at 0x%p encountered Fatal error", (void *)xconn);
 #endif
     ioerror_dump("xtalk", error_code, mode, ioerror);
 
@@ -563,7 +559,7 @@
 }
 
 int
-xtalk_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
+xtalk_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code)
 {
     return DEV_FUNC(xconn_vhdl, error_devenable) (xconn_vhdl, devnum, error_code);
 }
@@ -577,7 +573,7 @@
  * Startup a crosstalk provider
  */
 void
-xtalk_provider_startup(devfs_handle_t xtalk_provider)
+xtalk_provider_startup(vertex_hdl_t xtalk_provider)
 {
     DEV_FUNC(xtalk_provider, provider_startup)
 	(xtalk_provider);
@@ -588,7 +584,7 @@
  * Shutdown a crosstalk provider
  */
 void
-xtalk_provider_shutdown(devfs_handle_t xtalk_provider)
+xtalk_provider_shutdown(vertex_hdl_t xtalk_provider)
 {
     DEV_FUNC(xtalk_provider, provider_shutdown)
 	(xtalk_provider);
@@ -598,22 +594,22 @@
  * Enable a device on a xtalk widget 
  */
 void
-xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
+xtalk_widgetdev_enable(vertex_hdl_t xconn_vhdl, int devnum)
 {
-    DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum);
+	return;
 }
 
 /* 
  * Shutdown a device on a xtalk widget 
  */
 void
-xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
+xtalk_widgetdev_shutdown(vertex_hdl_t xconn_vhdl, int devnum)
 {
-    DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum);
+	return;
 }
 
 int
-xtalk_dma_enabled(devfs_handle_t xconn_vhdl)
+xtalk_dma_enabled(vertex_hdl_t xconn_vhdl)
 {
     return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl);
 }
@@ -623,7 +619,7 @@
  */
 
 /****** Generic crosstalk interrupt interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
 {
     return (xtalk_intr->xi_dev);
@@ -654,7 +650,7 @@
 }
 
 /****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
 {
     return (xtalk_piomap->xp_dev);
@@ -686,7 +682,7 @@
 
 
 /****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
 {
     return (xtalk_dmamap->xd_dev);
@@ -707,7 +703,7 @@
  * if not, return NULL.
  */
 xwidget_info_t
-xwidget_info_chk(devfs_handle_t xwidget)
+xwidget_info_chk(vertex_hdl_t xwidget)
 {
     arbitrary_info_t        ainfo = 0;
 
@@ -717,28 +713,18 @@
 
 
 xwidget_info_t
-xwidget_info_get(devfs_handle_t xwidget)
+xwidget_info_get(vertex_hdl_t xwidget)
 {
     xwidget_info_t          widget_info;
 
     widget_info = (xwidget_info_t)
 	hwgraph_fastinfo_get(xwidget);
 
-#ifdef	LATER
-    if ((widget_info != NULL) &&
-	(widget_info->w_fingerprint != widget_info_fingerprint))
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	PRINT_PANIC("%v bad xwidget_info", xwidget);
-#else
-	PRINT_PANIC("%x bad xwidget_info", xwidget);
-#endif
-#endif	/* LATER */
-
     return (widget_info);
 }
 
 void
-xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info)
+xwidget_info_set(vertex_hdl_t xwidget, xwidget_info_t widget_info)
 {
     if (widget_info != NULL)
 	widget_info->w_fingerprint = widget_info_fingerprint;
@@ -753,11 +739,11 @@
 			 (arbitrary_info_t) widget_info);
 }
 
-devfs_handle_t
+vertex_hdl_t
 xwidget_info_dev_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_dev_get: null xwidget_info");
     return (xwidget_info->w_vertex);
 }
 
@@ -765,16 +751,16 @@
 xwidget_info_id_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_id_get: null xwidget_info");
     return (xwidget_info->w_id);
 }
 
 
-devfs_handle_t
+vertex_hdl_t
 xwidget_info_master_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_master_get: null xwidget_info");
     return (xwidget_info->w_master);
 }
 
@@ -782,7 +768,7 @@
 xwidget_info_masterid_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_masterid_get: null xwidget_info");
     return (xwidget_info->w_masterid);
 }
 
@@ -790,7 +776,7 @@
 xwidget_info_part_num_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_part_num_get: null xwidget_info");
     return (xwidget_info->w_hwid.part_num);
 }
 
@@ -798,7 +784,7 @@
 xwidget_info_mfg_num_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_mfg_num_get: null xwidget_info");
     return (xwidget_info->w_hwid.mfg_num);
 }
 /* Extract the widget name from the widget information
@@ -808,49 +794,16 @@
 xwidget_info_name_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget info");
+	panic("xwidget_info_name_get: null xwidget_info");
     return(xwidget_info->w_name);
 }
 /****** Generic crosstalk initialization interfaces ******/
 
 /*
- * One-time initialization needed for systems that support crosstalk.
- */
-void
-xtalk_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("xtalk_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (xtalk_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr");
-	if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(xtalk_registry != NULL);
-}
-
-/*
  * Associate a set of xtalk_provider functions with a vertex.
  */
 void
-xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns)
+xtalk_provider_register(vertex_hdl_t provider, xtalk_provider_t *xtalk_fns)
 {
     hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);
 }
@@ -859,7 +812,7 @@
  * Disassociate a set of xtalk_provider functions with a vertex.
  */
 void
-xtalk_provider_unregister(devfs_handle_t provider)
+xtalk_provider_unregister(vertex_hdl_t provider)
 {
     hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);
 }
@@ -869,50 +822,19 @@
  * provider.
  */
 xtalk_provider_t       *
-xtalk_provider_fns_get(devfs_handle_t provider)
+xtalk_provider_fns_get(vertex_hdl_t provider)
 {
     return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));
 }
 
 /*
- * Announce a driver for a particular crosstalk part.
- * Returns 0 on success or -1 on failure.  Failure occurs if the
- * specified hardware already has a driver.
- */
-/*ARGSUSED4 */
-int
-xwidget_driver_register(xwidget_part_num_t part_num,
-			xwidget_mfg_num_t mfg_num,
-			char *driver_prefix,
-			unsigned flags)
-{
-    /* a driver's init routine could call
-     * xwidget_driver_register before the
-     * system calls xtalk_init; so, we
-     * make the call here.
-     */
-    if (xtalk_registry == NULL)
-	xtalk_init();
-
-    return cdl_add_driver(xtalk_registry,
-			  part_num, mfg_num,
-			  driver_prefix, flags, NULL);
-}
-
-/*
  * Inform xtalk infrastructure that a driver is no longer available for
  * handling any widgets.
  */
 void
 xwidget_driver_unregister(char *driver_prefix)
 {
-    /* before a driver calls unregister,
-     * it must have called registger; so we
-     * can assume we have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_del_driver(xtalk_registry, driver_prefix, NULL);
+	return;
 }
 
 /*
@@ -923,9 +845,6 @@
 xtalk_iterate(char *driver_prefix,
 	      xtalk_iter_f *func)
 {
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func);
 }
 
 /*
@@ -939,11 +858,10 @@
  */
 int
 xwidget_register(xwidget_hwid_t hwid,		/* widget's hardware ID */
-		 devfs_handle_t 	widget,		/* widget to initialize */
+		 vertex_hdl_t 	widget,		/* widget to initialize */
 		 xwidgetnum_t 	id,		/* widget's target id (0..f) */
-		 devfs_handle_t 	master,		/* widget's master vertex */
-		 xwidgetnum_t 	targetid,	/* master's target id (9/a) */
-		 async_attach_t aa)
+		 vertex_hdl_t 	master,		/* widget's master vertex */
+		 xwidgetnum_t 	targetid)	/* master's target id (9/a) */
 {			
     xwidget_info_t          widget_info;
     char		    *s,devnm[MAXDEVNAME];
@@ -972,21 +890,11 @@
 
     device_master_set(widget, master);
 
-    /* All the driver init routines (including
-     * xtalk_init) are called before we get into
-     * attaching devices, so we can assume we
-     * have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
     /* 
      * Add pointer to async attach info -- tear down will be done when
      * the particular descendant is done with the info.
      */
-    if (aa)
-	    async_attach_add_info(widget, aa);
-
-    return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
+    return cdl_add_connpt(hwid->part_num, hwid->mfg_num,
                           widget, 0);
 }
 
@@ -995,7 +903,7 @@
  *	Unregister the xtalk device and detach all its hwgraph namespace.
  */
 int
-xwidget_unregister(devfs_handle_t widget)
+xwidget_unregister(vertex_hdl_t widget)
 {
     xwidget_info_t	widget_info;
     xwidget_hwid_t	hwid;
@@ -1011,9 +919,6 @@
     
     hwid = &(widget_info->w_hwid);
 
-    cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                   widget, 0);
-
     /* Clean out the xwidget information */
     (void)kfree(widget_info->w_name);
     BZERO((void *)widget_info, sizeof(widget_info));
@@ -1023,7 +928,7 @@
 }
 
 void
-xwidget_error_register(devfs_handle_t xwidget,
+xwidget_error_register(vertex_hdl_t xwidget,
 		       error_handler_f *efunc,
 		       error_handler_arg_t einfo)
 {
@@ -1039,37 +944,23 @@
  * Issue a link reset to a widget.
  */
 void
-xwidget_reset(devfs_handle_t xwidget)
+xwidget_reset(vertex_hdl_t xwidget)
 {
     xswitch_reset_link(xwidget);
-
 }
 
 
 void
-xwidget_gfx_reset(devfs_handle_t xwidget)
+xwidget_gfx_reset(vertex_hdl_t xwidget)
 {
-    xwidget_info_t info;
-
-    xswitch_reset_link(xwidget);
-    info = xwidget_info_get(xwidget);
-#ifdef LATER
-    ASSERT_ALWAYS(info != NULL);
-#endif
-
-    /*
-     * Enable this for other architectures once we add widget_reset to the
-     * xtalk provider interface.
-     */
-    DEV_FUNC(xtalk_provider, widget_reset)
-	(xwidget_info_master_get(info), xwidget_info_id_get(info));
+	return;
 }
 
 #define ANON_XWIDGET_NAME	"No Name"	/* Default Widget Name */
 
 /* Get the canonical hwgraph  name of xtalk widget */
 char *
-xwidget_name_get(devfs_handle_t xwidget_vhdl)
+xwidget_name_get(vertex_hdl_t xwidget_vhdl)
 {
 	xwidget_info_t  info;
 
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/stubs.c linux-2.4.22-pre3/arch/ia64/sn/io/stubs.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/stubs.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/stubs.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,139 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/ctype.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/slotnum.h>
-#include <asm/sn/vector.h>
-#include <asm/sn/nic.h>
-
-/******
- ****** hack defines ......
- ******/
-
-int pcibr_prefetch_enable_rev, pcibr_wg_enable_rev;
-int default_intr_pri;
-int force_fire_and_forget = 1;
-int ignore_conveyor_override = 0;
-
-devfs_handle_t dummy_vrtx;	/* Needed for cpuid_to_vertex() in hack.h */
-
-
-/* ARGSUSED */
-void hub_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
-        {FIXME("hub_widgetdev_enable");}
-
-/* ARGSUSED */
-void hub_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
-        {FIXME("hub_widgetdev_shutdown");}
-
-/* ARGSUSED */
-void hub_widget_reset(devfs_handle_t hubv, xwidgetnum_t widget)
-        {FIXME("hub_widget_reset");}
-
-boolean_t
-is_sys_critical_vertex(devfs_handle_t x)
-{
-	FIXME("is_sys_critical_vertex : returns 0");
-	return(0);
-}
-
-void *
-snia_kmem_zone_alloc(register zone_t *zone, int flags)
-{
-	FIXME("snia_kmem_zone_alloc : return null");
-	return((void *)0);
-}
-
-void
-snia_kmem_zone_free(register zone_t *zone, void *ptr)
-{
-	FIXME("snia_kmem_zone_free : no-op");
-}
-
-zone_t *
-snia_kmem_zone_init(register int size, char *zone_name)
-{
-	FIXME("snia_kmem_zone_free : returns NULL");
-	return((zone_t *)0);
-}
-
-int
-compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr)
-{
-	FIXME("compare_and_swap_ptr : NOT ATOMIC");
-	if (*location == old_ptr) {
-		*location = new_ptr;
-		return(1);
-	}
-	else
-		return(0);
-}
-
-/* For ml/SN/SN1/slots.c */
-/* ARGSUSED */
-slotid_t get_widget_slotnum(int xbow, int widget)
-        {FIXME("get_widget_slotnum"); return (unsigned char)NULL;}
-
-/* For router */
-int
-router_init(cnodeid_t cnode,int writeid, void *npda_rip)
-        {FIXME("router_init"); return(0);}
-
-/* From io/ioerror_handling.c */
-error_return_code_t
-sys_critical_graph_vertex_add(devfs_handle_t parent, devfs_handle_t child)
-	{FIXME("sys_critical_graph_vertex_add"); return(0);}
-
-/* From io/ioc3.c */
-devfs_handle_t
-ioc3_console_vhdl_get(void)
-	{FIXME("ioc3_console_vhdl_get"); return( (devfs_handle_t)-1);}
-
-void
-nic_vmc_check(devfs_handle_t vhdl, char *nicinfo)
-{
-
-	FIXME("nic_vmc_check\n");
-
-}
-
-char *
-nic_vertex_info_get(devfs_handle_t v)
-{
-	FIXME("nic_vertex_info_get\n");
-	return(NULL);
-}
-
-int
-vector_read_node(net_vec_t dest, nasid_t nasid,
-             int write_id, int address,
-             uint64_t *value)
-{
-	FIXME("vector_read_node\n");
-	return(0);
-}
-
-int
-vector_write_node(net_vec_t dest, nasid_t nasid,
-              int write_id, int address,
-              uint64_t value)
-{
-	FIXME("vector_write_node\n");
-	return(0);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/xbow.c linux-2.4.22-pre3/arch/ia64/sn/io/xbow.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/xbow.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/xbow.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1325 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-#include <asm/sn/simulator.h>
-
-/* #define DEBUG		1 */
-/* #define XBOW_DEBUG	1 */
-
-
-/*
- * Files needed to get the device driver entry points
- */
-
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-
-#include <asm/sn/prio.h>
-#include <asm/sn/hcl_util.h>
-
-
-#define NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DEL(ptr)	(kfree(ptr))
-
-int                     xbow_devflag = D_MP;
-
-/*
- * This file supports the Xbow chip.  Main functions: initializtion,
- * error handling, and GBR.
- */
-
-/*
- * each vertex corresponding to an xbow chip
- * has a "fastinfo" pointer pointing at one
- * of these things.
- */
-typedef struct xbow_soft_s *xbow_soft_t;
-
-struct xbow_soft_s {
-    devfs_handle_t            conn;	/* our connection point */
-    devfs_handle_t            vhdl;	/* xbow's private vertex */
-    devfs_handle_t            busv;	/* the xswitch vertex */
-    xbow_t                 *base;	/* PIO pointer to crossbow chip */
-    char                   *name;	/* hwgraph name */
-
-    xbow_perf_t             xbow_perfcnt[XBOW_PERF_COUNTERS];
-    xbow_perf_link_t        xbow_perflink[MAX_XBOW_PORTS];
-    xbow_link_status_t      xbow_link_status[MAX_XBOW_PORTS];
-    spinlock_t              xbow_perf_lock;
-    int                     link_monitor;
-    widget_cfg_t	   *wpio[MAX_XBOW_PORTS];	/* cached PIO pointer */
-
-    /* Bandwidth allocation state. Bandwidth values are for the
-     * destination port since contention happens there.
-     * Implicit mapping from xbow ports (8..f) -> (0..7) array indices.
-     */
-    spinlock_t		    xbow_bw_alloc_lock;		/* bw allocation lock */
-    unsigned long long	    bw_hiwm[MAX_XBOW_PORTS];	/* hiwater mark values */
-    unsigned long long      bw_cur_used[MAX_XBOW_PORTS]; /* bw used currently */
-};
-
-#define xbow_soft_set(v,i)	hwgraph_fastinfo_set((v), (arbitrary_info_t)(i))
-#define xbow_soft_get(v)	((xbow_soft_t)hwgraph_fastinfo_get((v)))
-
-/*
- * Function Table of Contents
- */
-
-void                    xbow_mlreset(xbow_t *);
-void                    xbow_init(void);
-int                     xbow_attach(devfs_handle_t);
-
-int                     xbow_open(devfs_handle_t *, int, int, cred_t *);
-int                     xbow_close(devfs_handle_t, int, int, cred_t *);
-
-int                     xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     xbow_unmap(devfs_handle_t, vhandl_t *);
-int                     xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
-
-int                     xbow_widget_present(xbow_t *, int);
-static int              xbow_link_alive(xbow_t *, int);
-devfs_handle_t            xbow_widget_lookup(devfs_handle_t, int);
-
-#ifdef LATER
-static void             xbow_setwidint(xtalk_intr_t);
-static void             xbow_errintr_handler(intr_arg_t);
-#endif
-void                    xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
-
-
-
-void                    xbow_update_perf_counters(devfs_handle_t);
-xbow_perf_link_t       *xbow_get_perf_counters(devfs_handle_t);
-int                     xbow_enable_perf_counter(devfs_handle_t, int, int, int);
-xbow_link_status_t     *xbow_get_llp_status(devfs_handle_t);
-void                    xbow_update_llp_status(devfs_handle_t);
-
-int                     xbow_disable_llp_monitor(devfs_handle_t);
-int                     xbow_enable_llp_monitor(devfs_handle_t);
-int                     xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t,
-                                unsigned long long, unsigned long long);
-
-xswitch_reset_link_f    xbow_reset_link;
-
-void                    idbg_xbowregs(int64_t);
-
-xswitch_provider_t      xbow_provider =
-{
-    xbow_reset_link,
-};
-
-/*
- *    xbow_mlreset: called at mlreset time if the
- *      platform specific code determines that there is
- *      a crossbow in a critical path that must be
- *      functional before the driver would normally get
- *      the device properly set up.
- *
- *      what do we need to do, that the boot prom can
- *      not be counted on to have already done, that is
- *      generic across all platforms using crossbows?
- */
-/*ARGSUSED */
-void
-xbow_mlreset(xbow_t * xbow)
-{
-}
-
-/*
- *    xbow_init: called with the rest of the device
- *      driver XXX_init routines. This platform *might*
- *      have a Crossbow chip, or even several, but it
- *      might have none. Register with the crosstalk
- *      generic provider so when we encounter the chip
- *      the right magic happens.
- */
-void
-xbow_init(void)
-{
-
-#if DEBUG && ATTACH_DEBUG
-    printf("xbow_init\n");
-#endif
-
-    xwidget_driver_register(XXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-    xwidget_driver_register(XBOW_WIDGET_PART_NUM,
-			    XBOW_WIDGET_MFGR_NUM,
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-}
-
-#ifdef XBRIDGE_REGS_SIM
-/*    xbow_set_simulated_regs: sets xbow regs as needed
- *	for powering through the boot
- */
-void
-xbow_set_simulated_regs(xbow_t *xbow, int port)
-{
-    /*
-     * turn on link
-     */
-    xbow->xb_link(port).link_status = (1<<31);
-    /*
-     * and give it a live widget too
-     */
-    xbow->xb_link(port).link_aux_status = XB_AUX_STAT_PRESENT;
-    /*
-     * zero the link control reg
-     */
-    xbow->xb_link(port).link_control = 0x0;
-}
-#endif /* XBRIDGE_REGS_SIM */
-
-/*
- *    xbow_attach: the crosstalk provider has
- *      determined that there is a crossbow widget
- *      present, and has handed us the connection
- *      point for that vertex.
- *
- *      We not only add our own vertex, but add
- *      some "xtalk switch" data to the switch
- *      vertex (at the connect point's parent) if
- *      it does not have any.
- */
-
-/*ARGSUSED */
-int
-xbow_attach(devfs_handle_t conn)
-{
-    /*REFERENCED */
-    devfs_handle_t            vhdl;
-    devfs_handle_t            busv;
-    xbow_t                 *xbow;
-    xbow_soft_t             soft;
-    int                     port;
-    xswitch_info_t          info;
-#ifdef LATER
-    xtalk_intr_t            intr_hdl;
-    device_desc_t           dev_desc;
-#endif
-    char                    devnm[MAXDEVNAME], *s;
-    xbowreg_t               id;
-    int                     rev;
-    int			    i;
-    int			    xbow_num;
-	
-#if DEBUG && ATTACH_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT
-    printk("%v: xbow_attach\n", conn);
-#else
-    printk("0x%x: xbow_attach\n", conn);
-#endif
-#endif
-
-    /*
-     * Get a PIO pointer to the base of the crossbow
-     * chip.
-     */
-#ifdef XBRIDGE_REGS_SIM
-    printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: allocating %ld bytes for xbow_s\n", sizeof(xbow_t));
-    xbow = (xbow_t *) kmalloc(sizeof(xbow_t), GFP_KERNEL);
-    /*
-     * turn on ports e and f like in a real live ibrick
-     */
-    xbow_set_simulated_regs(xbow, 0xe);
-    xbow_set_simulated_regs(xbow, 0xf);
-#else
-    xbow = (xbow_t *) xtalk_piotrans_addr(conn, 0, 0, sizeof(xbow_t), 0);
-#endif /* XBRIDGE_REGS_SIM */
-
-    /*
-     * Locate the "switch" vertex: it is the parent
-     * of our connection point.
-     */
-    busv = hwgraph_connectpt_get(conn);
-#if DEBUG && ATTACH_DEBUG
-    printk("xbow_attach: Bus Vertex 0x%p, conn 0x%p, xbow register 0x%p wid= 0x%x\n", busv, conn, xbow, *(volatile u32 *)xbow);
-#endif
-
-    ASSERT(busv != GRAPH_VERTEX_NONE);
-
-    /*
-     * Create our private vertex, and connect our
-     * driver information to it. This makes it possible
-     * for diagnostic drivers to open the crossbow
-     * vertex for access to registers.
-     */
-
-    /*
-     * We need to teach xbow drivers to provide the right set of
-     * file ops.
-     */
-    vhdl = NULL;
-    vhdl = hwgraph_register(conn, EDGE_LBL_XBOW,
-                        0, DEVFS_FL_AUTO_DEVNUM,
-                        0, 0,
-                        S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                        /* &hcl_fops */ (void *)&vhdl, NULL);
-    if (!vhdl) {
-        printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n",
-                (void *)conn);
-    }
-
-    /*
-     * Allocate the soft state structure and attach
-     * it to the xbow's vertex
-     */
-    NEW(soft);
-    soft->conn = conn;
-    soft->vhdl = vhdl;
-    soft->busv = busv;
-    soft->base = xbow;
-    /* does the universe really need another macro?  */
-    /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */
-    hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft);
-
-#define XBOW_NUM_SUFFIX_FORMAT	"[xbow# %d]"
-
-    /* Add xbow number as a suffix to the hwgraph name of the xbow.
-     * This is helpful while looking at the error/warning messages.
-     */
-    xbow_num = 0;
-
-    /*
-     * get the name of this xbow vertex and keep the info.
-     * This is needed during errors and interupts, but as
-     * long as we have it, we can use it elsewhere.
-     */
-    s = dev_to_name(vhdl, devnm, MAXDEVNAME);
-    soft->name = kmalloc(strlen(s) + strlen(XBOW_NUM_SUFFIX_FORMAT) + 1, 
-			    GFP_KERNEL);
-    sprintf(soft->name,"%s"XBOW_NUM_SUFFIX_FORMAT, s,xbow_num);
-
-#ifdef XBRIDGE_REGS_SIM
-    /* my o200/ibrick has id=0x2d002049, but XXBOW_WIDGET_PART_NUM is defined
-     * as 0xd000, so I'm using that for the partnum bitfield.
-     */
-    printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: need xb_wid_id value!!\n");
-    id = 0x2d000049;
-#else
-    id = xbow->xb_wid_id;
-#endif /* XBRIDGE_REGS_SIM */
-    rev = XWIDGET_PART_REV_NUM(id);
-
-    /*
-     * Print the revision if DEBUG, or SHOW_REVS and kdebug,
-     * or the xbow is downrev.
-     *
-     * If xbow is downrev, make it a WARNING that the
-     * Crossbow is DOWNREV: these chips are not good
-     * to have around, and the operator should be told.
-     */
-#ifdef	LATER
-#if !DEBUG
-    if (
-#if SHOW_REVS
-	   (kdebug) ||
-#endif	/* SHOW_REVS */
-	   (rev < XBOW_REV_1_1))
-#endif	/* !DEBUG  */
-	printk("%sCrossbow ASIC: rev %s (code=%d) at %s%s",
-		(rev < XBOW_REV_1_1) ? "DOWNREV " : "",
-		(rev == XBOW_REV_1_0) ? "1.0" :
-		(rev == XBOW_REV_1_1) ? "1.1" :
-		(rev == XBOW_REV_1_2) ? "1.2" :
-		(rev == XBOW_REV_1_3) ? "1.3" :
-		(rev == XBOW_REV_2_0) ? "2.0" :
-		(rev == XXBOW_PART_REV_1_0) ? "Xbridge 1.0" :
-		(rev == XXBOW_PART_REV_2_0) ? "Xbridge 2.0" :
-		"unknown",
-		rev, soft->name,
-		(rev < XBOW_REV_1_1) ? "" : "\n");
-#endif	/* LATER */
-    mutex_spinlock_init(&soft->xbow_perf_lock);
-    soft->xbow_perfcnt[0].xp_perf_reg = &xbow->xb_perf_ctr_a;
-    soft->xbow_perfcnt[1].xp_perf_reg = &xbow->xb_perf_ctr_b;
-
-    /* Initialization for GBR bw allocation */
-    mutex_spinlock_init(&soft->xbow_bw_alloc_lock);
-
-#define	XBOW_8_BIT_PORT_BW_MAX		(400 * 1000 * 1000)	/* 400 MB/s */
-#define XBOW_16_BIT_PORT_BW_MAX		(800 * 1000 * 1000)	/* 800 MB/s */
-
-    /* Set bandwidth hiwatermark and current values */
-    for (i = 0; i < MAX_XBOW_PORTS; i++) {
-	soft->bw_hiwm[i] = XBOW_16_BIT_PORT_BW_MAX;	/* for now */
-	soft->bw_cur_used[i] = 0;
-    }
-
-    /*
-     * Enable xbow error interrupts
-     */
-    xbow->xb_wid_control = (XB_WID_CTRL_REG_ACC_IE | XB_WID_CTRL_XTALK_IE);
-
-    /*
-     * take a census of the widgets present,
-     * leaving notes at the switch vertex.
-     */
-    info = xswitch_info_new(busv);
-
-    for (port = MAX_PORT_NUM - MAX_XBOW_PORTS;
-	 port < MAX_PORT_NUM; ++port) {
-	if (!xbow_link_alive(xbow, port)) {
-#if DEBUG && XBOW_DEBUG
-	    printk(KERN_INFO "0x%p link %d is not alive\n",
-		    busv, port);
-#endif
-	    continue;
-	}
-	if (!xbow_widget_present(xbow, port)) {
-#if DEBUG && XBOW_DEBUG
-	    printk(KERN_INFO "0x%p link %d is alive but no widget is present\n", busv, port);
-#endif
-	    continue;
-	}
-#if DEBUG && XBOW_DEBUG
-	printk(KERN_INFO "0x%p link %d has a widget\n",
-		busv, port);
-#endif
-
-	xswitch_info_link_is_ok(info, port);
-	/*
-	 * Turn some error interrupts on
-	 * and turn others off. The PROM has
-	 * some things turned on we don't
-	 * want to see (bandwidth allocation
-	 * errors for instance); so if it
-	 * is not listed here, it is not on.
-	 */
-	xbow->xb_link(port).link_control =
-	    ( (xbow->xb_link(port).link_control
-	/*
-	 * Turn off these bits; they are non-fatal,
-	 * but we might want to save some statistics
-	 * on the frequency of these errors.
-	 * XXX FIXME XXX
-	 */
-	    & ~XB_CTRL_RCV_CNT_OFLOW_IE
-	    & ~XB_CTRL_XMT_CNT_OFLOW_IE
-	    & ~XB_CTRL_BNDWDTH_ALLOC_IE
-	    & ~XB_CTRL_RCV_IE)
-	/*
-	 * These are the ones we want to turn on.
-	 */
-	    | (XB_CTRL_ILLEGAL_DST_IE
-	    | XB_CTRL_OALLOC_IBUF_IE
-	    | XB_CTRL_XMT_MAX_RTRY_IE
-	    | XB_CTRL_MAXREQ_TOUT_IE
-	    | XB_CTRL_XMT_RTRY_IE
-	    | XB_CTRL_SRC_TOUT_IE) );
-    }
-
-    xswitch_provider_register(busv, &xbow_provider);
-
-    return 0;				/* attach successful */
-}
-
-/*ARGSUSED */
-int
-xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-
-}
-
-/*ARGSUSED */
-int
-xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    int                     error;
-
-    ASSERT(soft);
-    len = ctob(btoc(len));
-    /* XXX- this ignores the offset!!! */
-    error = v_mapphys(vt, (void *) soft->base, len);
-    return error;
-}
-
-/*ARGSUSED */
-int
-xbow_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    return 0;
-}
-
-/* This contains special-case code for grio. There are plans to make
- * this general sometime in the future, but till then this should
- * be good enough.
- */
-xwidgetnum_t
-xbow_widget_num_get(devfs_handle_t dev)
-{
-	devfs_handle_t	tdev;
-	char		devname[MAXDEVNAME];
-	xwidget_info_t	xwidget_info;
-	int		i;
-
-	vertex_to_name(dev, devname, MAXDEVNAME);
-
-	/* If this is a pci controller vertex, traverse up using
-	 * the ".." links to get to the widget.
-	 */
-	if (strstr(devname, EDGE_LBL_PCI) &&
-			strstr(devname, EDGE_LBL_CONTROLLER)) {
-		tdev = dev;
-		for (i=0; i< 2; i++) {
-			if (hwgraph_edge_get(tdev,
-				HWGRAPH_EDGELBL_DOTDOT, &tdev) !=
-					GRAPH_SUCCESS)
-				return XWIDGET_NONE;
-		}
-
-		if ((xwidget_info = xwidget_info_chk(tdev)) != NULL) {
-			return (xwidget_info_id_get(xwidget_info));
-		} else {
-			return XWIDGET_NONE;
-		}
-	}
-
-	return XWIDGET_NONE;
-}
-
-int
-xbow_ioctl(devfs_handle_t dev,
-	   int cmd,
-	   void *arg,
-	   int flag,
-	   struct cred *cr,
-	   int *rvalp)
-{
-    devfs_handle_t            vhdl;
-    int                     error = 0;
-
-#if defined (DEBUG)
-    int                     rc;
-    devfs_handle_t            conn;
-    struct xwidget_info_s  *xwidget_info;
-    xbow_soft_t             xbow_soft;
-#endif
-    *rvalp = 0;
-
-    vhdl = dev_to_vhdl(dev);
-#if defined (DEBUG)
-    xbow_soft = xbow_soft_get(vhdl);
-    conn = xbow_soft->conn;
-
-    xwidget_info = xwidget_info_get(conn);
-    ASSERT_ALWAYS(xwidget_info != NULL);
-
-    rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid);
-    ASSERT_ALWAYS(rc != 0);
-#endif
-    switch (cmd) {
-#ifdef LATER
-    case XBOWIOC_PERF_ENABLE:
-    case XBOWIOC_PERF_DISABLE:
-	{
-	    struct xbow_perfarg_t   xbow_perf_en;
-
-	    if (!_CAP_CRABLE(cr, CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-	    if ((flag & FWRITE) == 0) {
-		error = EBADF;
-		break;
-	    }
-	    if (COPYIN(arg, &xbow_perf_en, sizeof(xbow_perf_en))) {
-		error = EFAULT;
-		break;
-	    }
-	    if (error = xbow_enable_perf_counter(vhdl,
-						 xbow_perf_en.link,
-						 (cmd == XBOWIOC_PERF_DISABLE) ? 0 : xbow_perf_en.mode,
-						 xbow_perf_en.counter)) {
-		error = EINVAL;
-		break;
-	    }
-	    break;
-	}
-#endif
-
-#ifdef LATER
-    case XBOWIOC_PERF_GET:
-	{
-	    xbow_perf_link_t       *xbow_perf_cnt;
-
-	    if ((flag & FREAD) == 0) {
-		error = EBADF;
-		break;
-	    }
-	    xbow_perf_cnt = xbow_get_perf_counters(vhdl);
-	    ASSERT_ALWAYS(xbow_perf_cnt != NULL);
-
-	    if (COPYOUT((void *) xbow_perf_cnt, (void *) arg,
-			MAX_XBOW_PORTS * sizeof(xbow_perf_link_t))) {
-		error = EFAULT;
-		break;
-	    }
-	    break;
-	}
-#endif
-
-    case XBOWIOC_LLP_ERROR_ENABLE:
-	if ((error = xbow_enable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    case XBOWIOC_LLP_ERROR_DISABLE:
-
-	if ((error = xbow_disable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-#ifdef LATER
-    case XBOWIOC_LLP_ERROR_GET:
-	{
-	    xbow_link_status_t     *xbow_llp_status;
-
-	    if ((flag & FREAD) == 0) {
-		error = EBADF;
-		break;
-	    }
-	    xbow_llp_status = xbow_get_llp_status(vhdl);
-	    ASSERT_ALWAYS(xbow_llp_status != NULL);
-
-	    if (COPYOUT((void *) xbow_llp_status, (void *) arg,
-			MAX_XBOW_PORTS * sizeof(xbow_link_status_t))) {
-		error = EFAULT;
-		break;
-	    }
-	    break;
-	}
-#endif
-
-#ifdef LATER
-    case GIOCSETBW:
-	{
-	    grio_ioctl_info_t info;
-	    xwidgetnum_t src_widgetnum, dest_widgetnum;
-
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n",
-			info.prev_vhdl, info.next_vhdl, info.reqbw);
-#endif /* GRIO_DEBUG */
-
-	    src_widgetnum = xbow_widget_num_get(info.prev_vhdl);
-	    dest_widgetnum = xbow_widget_num_get(info.next_vhdl);
-
-	    /* Bandwidth allocation is bi-directional. Since bandwidth
-	     * reservations have already been done at an earlier stage,
-	     * we cannot fail here for lack of bandwidth.
-	     */
-	    xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum,
-			0, info.reqbw);
-	    xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum,
-			0, info.reqbw);
-
-	    break;
-	}
-
-    case GIOCRELEASEBW:
-	{
-	    grio_ioctl_info_t info;
-	    xwidgetnum_t src_widgetnum, dest_widgetnum;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n",
-			info.prev_vhdl, info.next_vhdl, info.reqbw);
-#endif /* GRIO_DEBUG */
-
-	    src_widgetnum = xbow_widget_num_get(info.prev_vhdl);
-	    dest_widgetnum = xbow_widget_num_get(info.next_vhdl);
-
-	    /* Bandwidth reservation is bi-directional. Hence, remove
-	     * bandwidth reservations for both directions.
-	     */
-	    xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum,
-			info.reqbw, (-1 * info.reqbw));
-	    xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum,
-			info.reqbw, (-1 * info.reqbw));
-
-	    break;
-	}
-#endif
-
-    default:
-	break;
-
-    }
-    return error;
-}
-
-/*
- * xbow_widget_present: See if a device is present
- * on the specified port of this crossbow.
- */
-int
-xbow_widget_present(xbow_t * xbow, int port)
-{
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		if ( (port == 14) || (port == 15) ) {
-			return 1;
-		}
-		else {
-			return 0;
-		}
-	}
-	else {
-		return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT;
-	}
-}
-
-static int
-xbow_link_alive(xbow_t * xbow, int port)
-{
-    xbwX_stat_t             xbow_linkstat;
-
-    xbow_linkstat.linkstatus = xbow->xb_link(port).link_status;
-    return (xbow_linkstat.link_alive);
-}
-
-/*
- * xbow_widget_lookup
- *      Lookup the edges connected to the xbow specified, and
- *      retrieve the handle corresponding to the widgetnum
- *      specified.
- *      If not found, return 0.
- */
-devfs_handle_t
-xbow_widget_lookup(devfs_handle_t vhdl,
-		   int widgetnum)
-{
-    xswitch_info_t          xswitch_info;
-    devfs_handle_t            conn;
-
-    xswitch_info = xswitch_info_get(vhdl);
-    conn = xswitch_info_vhdl_get(xswitch_info, widgetnum);
-    return conn;
-}
-
-/*
- * xbow_setwidint: called when xtalk
- * is establishing or migrating our
- * interrupt service.
- */
-#ifdef LATER
-static void
-xbow_setwidint(xtalk_intr_t intr)
-{
-    xwidgetnum_t            targ = xtalk_intr_target_get(intr);
-    iopaddr_t               addr = xtalk_intr_addr_get(intr);
-    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);
-    xbow_t                 *xbow = (xbow_t *) xtalk_intr_sfarg_get(intr);
-
-    xbow_intr_preset((void *) xbow, 0, targ, addr, vect);
-}
-#endif	/* LATER */
-
-/*
- * xbow_intr_preset: called during mlreset time
- * if the platform specific code needs to route
- * an xbow interrupt before the xtalk infrastructure
- * is available for use.
- *
- * Also called from xbow_setwidint, so we don't
- * replicate the guts of the routine.
- *
- * XXX- probably should be renamed xbow_wid_intr_set or
- * something to reduce confusion.
- */
-/*ARGSUSED3 */
-void
-xbow_intr_preset(void *which_widget,
-		 int which_widget_intr,
-		 xwidgetnum_t targ,
-		 iopaddr_t addr,
-		 xtalk_intr_vector_t vect)
-{
-    xbow_t                 *xbow = (xbow_t *) which_widget;
-
-    xbow->xb_wid_int_upper = ((0xFF000000 & (vect << 24)) |
-			      (0x000F0000 & (targ << 16)) |
-			      XTALK_ADDR_TO_UPPER(addr));
-    xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-}
-
-#define	XEM_ADD_STR(s)		printk("%s", (s))
-#define	XEM_ADD_NVAR(n,v)	printk("\t%20s: 0x%x\n", (n), (v))
-#define	XEM_ADD_VAR(v)		XEM_ADD_NVAR(#v,(v))
-#define XEM_ADD_IOEF(n) 	if (IOERROR_FIELDVALID(ioe,n))		    \
-				    XEM_ADD_NVAR("ioe." #n,		    \
-						 IOERROR_GETVALUE(ioe,n))
-
-#ifdef LATER
-static void
-xem_add_ioe(ioerror_t *ioe)
-{
-    XEM_ADD_IOEF(errortype);
-    XEM_ADD_IOEF(widgetnum);
-    XEM_ADD_IOEF(widgetdev);
-    XEM_ADD_IOEF(srccpu);
-    XEM_ADD_IOEF(srcnode);
-    XEM_ADD_IOEF(errnode);
-    XEM_ADD_IOEF(sysioaddr);
-    XEM_ADD_IOEF(xtalkaddr);
-    XEM_ADD_IOEF(busspace);
-    XEM_ADD_IOEF(busaddr);
-    XEM_ADD_IOEF(vaddr);
-    XEM_ADD_IOEF(memaddr);
-    XEM_ADD_IOEF(epc);
-    XEM_ADD_IOEF(ef);
-}
-
-#define XEM_ADD_IOE()	(xem_add_ioe(ioe))
-#endif	/* LATER */
-
-int                     xbow_xmit_retry_errors = 0;
-
-int
-xbow_xmit_retry_error(xbow_soft_t soft,
-		      int port)
-{
-    xswitch_info_t          info;
-    devfs_handle_t            vhdl;
-    widget_cfg_t           *wid;
-    widgetreg_t             id;
-    int                     part;
-    int                     mfgr;
-
-    wid = soft->wpio[port - BASE_XBOW_PORT];
-    if (wid == NULL) {
-	/* If we can't track down a PIO
-	 * pointer to our widget yet,
-	 * leave our caller knowing that
-	 * we are interested in this
-	 * interrupt if it occurs in
-	 * the future.
-	 */
-	info = xswitch_info_get(soft->busv);
-	if (!info)
-	    return 1;
-	vhdl = xswitch_info_vhdl_get(info, port);
-	if (vhdl == GRAPH_VERTEX_NONE)
-	    return 1;
-	wid = (widget_cfg_t *) xtalk_piotrans_addr
-	    (vhdl, 0, 0, sizeof *wid, 0);
-	if (!wid)
-	    return 1;
-	soft->wpio[port - BASE_XBOW_PORT] = wid;
-    }
-    id = wid->w_id;
-    part = XWIDGET_PART_NUM(id);
-    mfgr = XWIDGET_MFG_NUM(id);
-
-    /* If this thing is not a Bridge,
-     * do not activate the WAR, and
-     * tell our caller we do not need
-     * to be called again.
-     */
-    if ((part != BRIDGE_WIDGET_PART_NUM) ||
-	(mfgr != BRIDGE_WIDGET_MFGR_NUM)) {
-		/* FIXME: add Xbridge to the WAR.
-		 * Shouldn't hurt anything.  Later need to
-		 * check if we can remove this.
-                 */
-    		if ((part != XBRIDGE_WIDGET_PART_NUM) ||
-		    (mfgr != XBRIDGE_WIDGET_MFGR_NUM))
-			return 0;
-    }
-
-    /* count how many times we
-     * have picked up after
-     * LLP Transmit problems.
-     */
-    xbow_xmit_retry_errors++;
-
-    /* rewrite the control register
-     * to fix things up.
-     */
-    wid->w_control = wid->w_control;
-    wid->w_control;
-
-    return 1;
-}
-
-void
-xbow_update_perf_counters(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
-    xbow_perf_link_t       *xbow_plink = xbow_soft->xbow_perflink;
-    xbow_perfcount_t        perf_reg;
-    unsigned long           s;
-    int                     link, i;
-
-    for (i = 0; i < XBOW_PERF_COUNTERS; i++, xbow_perf++) {
-	if (xbow_perf->xp_mode == XBOW_MONITOR_NONE)
-	    continue;
-
-	s = mutex_spinlock(&xbow_soft->xbow_perf_lock);
-
-	perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg;
-
-	link = perf_reg.xb_perf.link_select;
-
-	(xbow_plink + link)->xlp_cumulative[xbow_perf->xp_curmode] +=
-	    ((perf_reg.xb_perf.count - xbow_perf->xp_current) & XBOW_COUNTER_MASK);
-	xbow_perf->xp_current = perf_reg.xb_perf.count;
-
-	mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-    }
-    /* Do port /mode multiplexing here */
-
-#ifdef LATER
-    (void) timeout(xbow_update_perf_counters,
-		   (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT);
-#endif
-
-}
-
-xbow_perf_link_t       *
-xbow_get_perf_counters(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_link_t       *xbow_perf_link = xbow_soft->xbow_perflink;
-
-    return xbow_perf_link;
-}
-
-int
-xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
-    xbow_linkctrl_t         xbow_link_ctrl;
-    xbow_t                 *xbow = xbow_soft->base;
-    xbow_perfcount_t        perf_reg;
-    unsigned long           s;
-    int                     i;
-
-    link -= BASE_XBOW_PORT;
-    if ((link < 0) || (link >= MAX_XBOW_PORTS))
-	return -1;
-
-    if ((mode < XBOW_MONITOR_NONE) || (mode > XBOW_MONITOR_DEST_LINK))
-	return -1;
-
-    if ((counter < 0) || (counter >= XBOW_PERF_COUNTERS))
-	return -1;
-
-    s = mutex_spinlock(&xbow_soft->xbow_perf_lock);
-
-    if ((xbow_perf + counter)->xp_mode && mode) {
-	mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-	return -1;
-    }
-    for (i = 0; i < XBOW_PERF_COUNTERS; i++) {
-	if (i == counter)
-	    continue;
-	if (((xbow_perf + i)->xp_link == link) &&
-	    ((xbow_perf + i)->xp_mode)) {
-	    mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-	    return -1;
-	}
-    }
-    xbow_perf += counter;
-
-    xbow_perf->xp_curlink = xbow_perf->xp_link = link;
-    xbow_perf->xp_curmode = xbow_perf->xp_mode = mode;
-
-    xbow_link_ctrl.xbl_ctrlword = xbow->xb_link_raw[link].link_control;
-    xbow_link_ctrl.xb_linkcontrol.perf_mode = mode;
-    xbow->xb_link_raw[link].link_control = xbow_link_ctrl.xbl_ctrlword;
-
-    perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg;
-    perf_reg.xb_perf.link_select = link;
-    *(xbowreg_t *) xbow_perf->xp_perf_reg = perf_reg.xb_counter_val;
-    xbow_perf->xp_current = perf_reg.xb_perf.count;
-
-#ifdef LATER
-    (void) timeout(xbow_update_perf_counters,
-		   (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT);
-#endif
-
-    mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-
-    return 0;
-}
-
-xbow_link_status_t     *
-xbow_get_llp_status(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
-
-    return xbow_llp_status;
-}
-
-void
-xbow_update_llp_status(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
-    xbow_t                 *xbow;
-    xbwX_stat_t             lnk_sts;
-    xbow_aux_link_status_t  aux_sts;
-    int                     link;
-    devfs_handle_t	    xwidget_vhdl;
-    char		   *xwidget_name;	
-
-    xbow = (xbow_t *) xbow_soft->base;
-    for (link = 0; link < MAX_XBOW_PORTS; link++, xbow_llp_status++) {
-	/* Get the widget name corresponding the current link.
-	 * Note : 0 <= link < MAX_XBOW_PORTS(8).
-	 * 	  BASE_XBOW_PORT(0x8) <= xwidget number < MAX_PORT_NUM (0x10)
-	 */
-	xwidget_vhdl = xbow_widget_lookup(xbow_soft->busv,link+BASE_XBOW_PORT);
-	xwidget_name = xwidget_name_get(xwidget_vhdl);
-	aux_sts.aux_linkstatus
-	    = xbow->xb_link_raw[link].link_aux_status;
-	lnk_sts.linkstatus = xbow->xb_link_raw[link].link_status_clr;
-
-	if (lnk_sts.link_alive == 0)
-	    continue;
-
-	xbow_llp_status->rx_err_count +=
-	    aux_sts.xb_aux_linkstatus.rx_err_cnt;
-
-	xbow_llp_status->tx_retry_count +=
-	    aux_sts.xb_aux_linkstatus.tx_retry_cnt;
-
-	if (lnk_sts.linkstatus & ~(XB_STAT_RCV_ERR | XB_STAT_XMT_RTRY_ERR | XB_STAT_LINKALIVE)) {
-#ifdef	LATER
-	    printk(KERN_WARNING  "link %d[%s]: bad status 0x%x\n",
-		    link, xwidget_name, lnk_sts.linkstatus);
-#endif
-	}
-    }
-#ifdef LATER
-    if (xbow_soft->link_monitor)
-	(void) timeout(xbow_update_llp_status,
-		       (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT);
-#endif
-}
-
-int
-xbow_disable_llp_monitor(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    int                     port;
-
-    for (port = 0; port < MAX_XBOW_PORTS; port++) {
-	xbow_soft->xbow_link_status[port].rx_err_count = 0;
-	xbow_soft->xbow_link_status[port].tx_retry_count = 0;
-    }
-
-    xbow_soft->link_monitor = 0;
-    return 0;
-}
-
-int
-xbow_enable_llp_monitor(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-
-#ifdef LATER
-    (void) timeout(xbow_update_llp_status,
-		   (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT);
-#endif
-    xbow_soft->link_monitor = 1;
-    return 0;
-}
-
-
-int
-xbow_reset_link(devfs_handle_t xconn_vhdl)
-{
-    xwidget_info_t          widget_info;
-    xwidgetnum_t            port;
-    xbow_t                 *xbow;
-    xbowreg_t               ctrl;
-    xbwX_stat_t             stat;
-    unsigned                itick;
-    unsigned                dtick;
-    static int              ticks_per_ms = 0;
-
-    if (!ticks_per_ms) {
-	itick = get_timestamp();
-	us_delay(1000);
-	ticks_per_ms = get_timestamp() - itick;
-    }
-    widget_info = xwidget_info_get(xconn_vhdl);
-    port = xwidget_info_id_get(widget_info);
-
-#ifdef XBOW_K1PTR			/* defined if we only have one xbow ... */
-    xbow = XBOW_K1PTR;
-#else
-    {
-	devfs_handle_t            xbow_vhdl;
-	xbow_soft_t             xbow_soft;
-
-	hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl);
-	xbow_soft = xbow_soft_get(xbow_vhdl);
-	xbow = xbow_soft->base;
-    }
-#endif
-
-    /*
-     * This requires three PIOs (reset the link, check for the
-     * reset, restore the control register for the link) plus
-     * 10us to wait for the reset. We allow up to 1ms for the
-     * widget to come out of reset before giving up and
-     * returning a failure.
-     */
-    ctrl = xbow->xb_link(port).link_control;
-    xbow->xb_link(port).link_reset = 0;
-    itick = get_timestamp();
-    while (1) {
-	stat.linkstatus = xbow->xb_link(port).link_status;
-	if (stat.link_alive)
-	    break;
-	dtick = get_timestamp() - itick;
-	if (dtick > ticks_per_ms) {
-	    return -1;			/* never came out of reset */
-	}
-	DELAY(2);			/* don't beat on link_status */
-    }
-    xbow->xb_link(port).link_control = ctrl;
-    return 0;
-}
-
-/*
- * Dump xbow registers.
- * input parameter is either a pointer to
- * the xbow chip or the vertex handle for
- * an xbow vertex.
- */
-void
-idbg_xbowregs(int64_t regs)
-{
-    xbow_t                 *xbow;
-    int                     i;
-    xb_linkregs_t          *link;
-
-#ifdef LATER
-    if (dev_is_vertex((devfs_handle_t) regs)) {
-	devfs_handle_t            vhdl = (devfs_handle_t) regs;
-	xbow_soft_t             soft = xbow_soft_get(vhdl);
-
-	xbow = soft->base;
-    } else
-#endif
-    {
-	xbow = (xbow_t *) regs;
-    }
-
-#ifdef LATER
-    qprintf("Printing xbow registers starting at 0x%x\n", xbow);
-    qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n",
-	    xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper,
-	    xbow->xb_wid_err_lower, xbow->xb_wid_control,
-	    xbow->xb_wid_req_timeout);
-    qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n",
-	    xbow->xb_wid_int_upper, xbow->xb_wid_int_lower,
-	    xbow->xb_wid_err_cmdword, xbow->xb_wid_llp,
-	    xbow->xb_wid_arb_reload);
-#endif
-
-    for (i = 8; i <= 0xf; i++) {
-	link = &xbow->xb_link(i);
-#ifdef LATER
-	qprintf("Link %d registers\n", i);
-	qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n",
-		link->link_control, link->link_status,
-		link->link_arb_upper, link->link_arb_lower,
-		link->link_aux_status);
-#endif
-    }
-}
-
-
-#define XBOW_ARB_RELOAD_TICKS		25
-					/* granularity: 4 MB/s, max: 124 MB/s */
-#define GRANULARITY			((100 * 1000000) / XBOW_ARB_RELOAD_TICKS)
-
-#define XBOW_BYTES_TO_GBR(BYTES_per_s)	(int) (BYTES_per_s / GRANULARITY)
-
-#define XBOW_GBR_TO_BYTES(cnt)		(bandwidth_t) ((cnt) * GRANULARITY)
-
-#define CEILING_BYTES_TO_GBR(gbr, bytes_per_sec)	\
-			((XBOW_GBR_TO_BYTES(gbr) < bytes_per_sec) ? gbr+1 : gbr)
-
-#define XBOW_ARB_GBR_MAX		31
-
-#define ABS(x)				((x > 0) ? (x) : (-1 * x))
-					/* absolute value */
-
-int
-xbow_bytes_to_gbr(bandwidth_t old_bytes_per_sec, bandwidth_t bytes_per_sec)
-{
-    int                     gbr_granted;
-    int                     new_total_gbr;
-    int                     change_gbr;
-    bandwidth_t             new_total_bw;
-
-#ifdef GRIO_DEBUG
-    printf("xbow_bytes_to_gbr: old_bytes_per_sec %lld bytes_per_sec %lld\n",
-		old_bytes_per_sec, bytes_per_sec);
-#endif	/* GRIO_DEBUG */
-
-    gbr_granted = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(old_bytes_per_sec)),
-			old_bytes_per_sec);
-    new_total_bw = old_bytes_per_sec + bytes_per_sec;
-    new_total_gbr = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(new_total_bw)),
-			new_total_bw);
-
-    change_gbr = new_total_gbr - gbr_granted;
-
-#ifdef GRIO_DEBUG
-    printf("xbow_bytes_to_gbr: gbr_granted %d new_total_gbr %d change_gbr %d\n",
-		gbr_granted, new_total_gbr, change_gbr);
-#endif	/* GRIO_DEBUG */
-
-    return (change_gbr);
-}
-
-/* Conversion from GBR to bytes */
-bandwidth_t
-xbow_gbr_to_bytes(int gbr)
-{
-    return (XBOW_GBR_TO_BYTES(gbr));
-}
-
-/* Given the vhdl for the desired xbow, the src and dest. widget ids
- * and the req_bw value, this xbow driver entry point accesses the
- * xbow registers and allocates the desired bandwidth if available.
- *
- * If bandwidth allocation is successful, return success else return failure.
- */
-int
-xbow_prio_bw_alloc(devfs_handle_t vhdl,
-		xwidgetnum_t src_wid,
-		xwidgetnum_t dest_wid,
-		unsigned long long old_alloc_bw,
-		unsigned long long req_bw)
-{
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    volatile xbowreg_t     *xreg;
-    xbowreg_t               mask;
-    unsigned long           s;
-    int                     error = 0;
-    bandwidth_t             old_bw_BYTES, req_bw_BYTES;
-    xbowreg_t               old_xreg;
-    int                     old_bw_GBR, req_bw_GBR, new_bw_GBR;
-
-#ifdef GRIO_DEBUG
-    printf("xbow_prio_bw_alloc: vhdl %d src_wid %d dest_wid %d req_bw %lld\n",
-		(int) vhdl, (int) src_wid, (int) dest_wid, req_bw);
-#endif
-
-    ASSERT(XBOW_WIDGET_IS_VALID(src_wid));
-    ASSERT(XBOW_WIDGET_IS_VALID(dest_wid));
-
-    s = mutex_spinlock(&soft->xbow_bw_alloc_lock);
-
-    /* Get pointer to the correct register */
-    xreg = XBOW_PRIO_ARBREG_PTR(soft->base, dest_wid, src_wid);
-
-    /* Get mask for GBR count value */
-    mask = XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(src_wid);
-
-    req_bw_GBR = xbow_bytes_to_gbr(old_alloc_bw, req_bw);
-    req_bw_BYTES = (req_bw_GBR < 0) ? (-1 * xbow_gbr_to_bytes(ABS(req_bw_GBR)))
-		: xbow_gbr_to_bytes(req_bw_GBR);
-
-#ifdef GRIO_DEBUG
-    printf("req_bw %lld req_bw_BYTES %lld req_bw_GBR %d\n",
-		req_bw, req_bw_BYTES, req_bw_GBR);
-#endif	/* GRIO_DEBUG */
-
-    old_bw_BYTES = soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS];
-    old_xreg = *xreg;
-    old_bw_GBR = (((*xreg) & mask) >> XB_ARB_GBR_SHFT(src_wid));
-
-#ifdef GRIO_DEBUG
-    ASSERT(XBOW_BYTES_TO_GBR(old_bw_BYTES) == old_bw_GBR);
-
-    printf("old_bw_BYTES %lld old_bw_GBR %d\n", old_bw_BYTES, old_bw_GBR);
-
-    printf("req_bw_BYTES %lld old_bw_BYTES %lld soft->bw_hiwm %lld\n",
-		req_bw_BYTES, old_bw_BYTES,
-		soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]);
-	   
-#endif				/* GRIO_DEBUG */
-
-    /* Accept the request only if we don't exceed the destination
-     * port HIWATER_MARK *AND* the max. link GBR arbitration count
-     */
-    if (((old_bw_BYTES + req_bw_BYTES) <=
-		soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]) &&
-		(req_bw_GBR + old_bw_GBR <= XBOW_ARB_GBR_MAX)) {
-
-	new_bw_GBR = (old_bw_GBR + req_bw_GBR);
-
-	/* Set this in the xbow link register */
-	*xreg = (old_xreg & ~mask) | \
-	    (new_bw_GBR << XB_ARB_GBR_SHFT(src_wid) & mask);
-
-	soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS] =
-			xbow_gbr_to_bytes(new_bw_GBR);
-    } else {
-	error = 1;
-    }
-
-    mutex_spinunlock(&soft->xbow_bw_alloc_lock, s);
-
-    return (error);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/xswitch.c linux-2.4.22-pre3/arch/ia64/sn/io/xswitch.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/xswitch.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/xswitch.c	2003-07-05 18:09:45.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -23,8 +23,6 @@
 #define	NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
 #define	DEL(ptr)	(kfree(ptr))
 
-int                     xswitch_devflag = D_MP;
-
 /*
  * This file provides generic support for Crosstalk
  * Switches, in a way that insulates crosstalk providers
@@ -45,9 +43,9 @@
 #define	DEV_FUNC(dev,func)	xwidget_to_provider_fns(dev)->func
 
 static xswitch_provider_t *
-xwidget_to_provider_fns(devfs_handle_t xconn)
+xwidget_to_provider_fns(vertex_hdl_t xconn)
 {
-    devfs_handle_t            busv;
+    vertex_hdl_t            busv;
     xswitch_info_t          xswitch_info;
     xswitch_provider_t      provider_fns;
 
@@ -75,27 +73,18 @@
 struct xswitch_info_s {
     char                   *fingerprint;
     unsigned                census;
-    devfs_handle_t            vhdl[XSWITCH_CENSUS_PORTS];
-    devfs_handle_t            master_vhdl[XSWITCH_CENSUS_PORTS];
+    vertex_hdl_t            vhdl[XSWITCH_CENSUS_PORTS];
+    vertex_hdl_t            master_vhdl[XSWITCH_CENSUS_PORTS];
     xswitch_provider_t     *xswitch_fns;
 };
 
 xswitch_info_t
-xswitch_info_get(devfs_handle_t xwidget)
+xswitch_info_get(vertex_hdl_t xwidget)
 {
     xswitch_info_t          xswitch_info;
 
     xswitch_info = (xswitch_info_t)
 	hwgraph_fastinfo_get(xwidget);
-#ifdef	LATER
-    if ((xswitch_info != NULL) &&
-	(xswitch_info->fingerprint != xswitch_info_fingerprint))
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	PRINT_PANIC("%v xswitch_info_get bad fingerprint", xwidget);
-#else
-	PRINT_PANIC("%x xswitch_info_get bad fingerprint", xwidget);
-#endif
-#endif	/* LATER */
 
     return (xswitch_info);
 }
@@ -103,7 +92,7 @@
 void
 xswitch_info_vhdl_set(xswitch_info_t xswitch_info,
 		      xwidgetnum_t port,
-		      devfs_handle_t xwidget)
+		      vertex_hdl_t xwidget)
 {
 #if XSWITCH_CENSUS_PORT_MIN
     if (port < XSWITCH_CENSUS_PORT_MIN)
@@ -115,15 +104,10 @@
     xswitch_info->vhdl[port - XSWITCH_CENSUS_PORT_MIN] = xwidget;
 }
 
-devfs_handle_t
+vertex_hdl_t
 xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
 		      xwidgetnum_t port)
 {
-#ifdef	LATER
-    if (xswitch_info == NULL)
-	PRINT_PANIC("xswitch_info_vhdl_get: null xswitch_info");
-#endif
-
 #if XSWITCH_CENSUS_PORT_MIN
     if (port < XSWITCH_CENSUS_PORT_MIN)
 	return GRAPH_VERTEX_NONE;
@@ -142,7 +126,7 @@
 void
 xswitch_info_master_assignment_set(xswitch_info_t xswitch_info,
 				   xwidgetnum_t port,
-				   devfs_handle_t master_vhdl)
+				   vertex_hdl_t master_vhdl)
 {
 #if XSWITCH_CENSUS_PORT_MIN
     if (port < XSWITCH_CENSUS_PORT_MIN)
@@ -154,7 +138,7 @@
     xswitch_info->master_vhdl[port - XSWITCH_CENSUS_PORT_MIN] = master_vhdl;
 }
 
-devfs_handle_t
+vertex_hdl_t
 xswitch_info_master_assignment_get(xswitch_info_t xswitch_info,
 				   xwidgetnum_t port)
 {
@@ -169,14 +153,14 @@
 }
 
 void
-xswitch_info_set(devfs_handle_t xwidget, xswitch_info_t xswitch_info)
+xswitch_info_set(vertex_hdl_t xwidget, xswitch_info_t xswitch_info)
 {
     xswitch_info->fingerprint = xswitch_info_fingerprint;
     hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) xswitch_info);
 }
 
 xswitch_info_t
-xswitch_info_new(devfs_handle_t xwidget)
+xswitch_info_new(vertex_hdl_t xwidget)
 {
     xswitch_info_t          xswitch_info;
 
@@ -202,7 +186,7 @@
 }
 
 void
-xswitch_provider_register(devfs_handle_t busv,
+xswitch_provider_register(vertex_hdl_t busv,
 			  xswitch_provider_t * xswitch_fns)
 {
     xswitch_info_t          xswitch_info = xswitch_info_get(busv);
@@ -232,35 +216,8 @@
 }
 
 int
-xswitch_reset_link(devfs_handle_t xconn_vhdl)
+xswitch_reset_link(vertex_hdl_t xconn_vhdl)
 {
     return DEV_FUNC(xconn_vhdl, reset_link)
 	(xconn_vhdl);
 }
-
-/* Given a vertex handle to the xswitch get its logical
- * id.
- */
-int
-xswitch_id_get(devfs_handle_t	xconn_vhdl)
-{
-    arbitrary_info_t 	xbow_num;
-    graph_error_t	rv;
-
-    rv = hwgraph_info_get_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID,&xbow_num);
-    ASSERT(rv == GRAPH_SUCCESS);
-    return(xbow_num);
-}
-
-/* Given a vertex handle to the xswitch set its logical
- * id.
- */
-void
-xswitch_id_set(devfs_handle_t	xconn_vhdl,int xbow_num)
-{
-    graph_error_t	rv;
-
-    rv = hwgraph_info_add_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID,
-			      (arbitrary_info_t)xbow_num);
-    ASSERT(rv == GRAPH_SUCCESS);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/io/xtalk.c linux-2.4.22-pre3/arch/ia64/sn/io/xtalk.c
--- linux-2.4.22-pre2/arch/ia64/sn/io/xtalk.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/io/xtalk.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1024 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-
-/*
- * Implement crosstalk provider operations.  The xtalk* layer provides a
- * platform-independent interface for crosstalk devices.  This layer
- * switches among the possible implementations of a crosstalk adapter.
- *
- * On platforms with only one possible xtalk provider, macros can be
- * set up at the top that cause the table lookups and indirections to
- * completely disappear.
- */
-
-#define	NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define	DEL(ptr)	(kfree(ptr))
-
-char                    widget_info_fingerprint[] = "widget_info";
-
-cdl_p                   xtalk_registry = NULL;
-
-#define	DEV_FUNC(dev,func)	hub_##func
-#define	CAST_PIOMAP(x)		((hub_piomap_t)(x))
-#define	CAST_DMAMAP(x)		((hub_dmamap_t)(x))
-#define	CAST_INTR(x)		((hub_intr_t)(x))
-
-/* =====================================================================
- *            Function Table of Contents
- */
-xtalk_piomap_t          xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
-void                    xtalk_piomap_free(xtalk_piomap_t);
-caddr_t                 xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t);
-void                    xtalk_piomap_done(xtalk_piomap_t);
-caddr_t                 xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned);
-caddr_t                 xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
-void                    xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
-caddr_t                 xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-static caddr_t          null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-xtalk_dmamap_t          xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    xtalk_dmamap_free(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);
-alenlist_t              xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);
-void                    xtalk_dmamap_done(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void			xtalk_dmamap_drain(xtalk_dmamap_t);
-void			xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t);
-void			xtalk_dmalist_drain(devfs_handle_t, alenlist_t);
-xtalk_intr_t            xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t);
-xtalk_intr_t            xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t);
-void                    xtalk_intr_free(xtalk_intr_t);
-int                     xtalk_intr_connect(xtalk_intr_t, xtalk_intr_setfunc_t, void *);
-void                    xtalk_intr_disconnect(xtalk_intr_t);
-devfs_handle_t            xtalk_intr_cpu_get(xtalk_intr_t);
-int                     xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
-int                     xtalk_error_devenable(devfs_handle_t, int, int);
-void                    xtalk_provider_startup(devfs_handle_t);
-void                    xtalk_provider_shutdown(devfs_handle_t);
-devfs_handle_t            xtalk_intr_dev_get(xtalk_intr_t);
-xwidgetnum_t            xtalk_intr_target_get(xtalk_intr_t);
-xtalk_intr_vector_t     xtalk_intr_vector_get(xtalk_intr_t);
-iopaddr_t               xtalk_intr_addr_get(struct xtalk_intr_s *);
-void                   *xtalk_intr_sfarg_get(xtalk_intr_t);
-devfs_handle_t            xtalk_pio_dev_get(xtalk_piomap_t);
-xwidgetnum_t            xtalk_pio_target_get(xtalk_piomap_t);
-iopaddr_t               xtalk_pio_xtalk_addr_get(xtalk_piomap_t);
-ulong                   xtalk_pio_mapsz_get(xtalk_piomap_t);
-caddr_t                 xtalk_pio_kvaddr_get(xtalk_piomap_t);
-devfs_handle_t            xtalk_dma_dev_get(xtalk_dmamap_t);
-xwidgetnum_t            xtalk_dma_target_get(xtalk_dmamap_t);
-xwidget_info_t          xwidget_info_chk(devfs_handle_t);
-xwidget_info_t          xwidget_info_get(devfs_handle_t);
-void                    xwidget_info_set(devfs_handle_t, xwidget_info_t);
-devfs_handle_t            xwidget_info_dev_get(xwidget_info_t);
-xwidgetnum_t            xwidget_info_id_get(xwidget_info_t);
-devfs_handle_t            xwidget_info_master_get(xwidget_info_t);
-xwidgetnum_t            xwidget_info_masterid_get(xwidget_info_t);
-xwidget_part_num_t      xwidget_info_part_num_get(xwidget_info_t);
-xwidget_mfg_num_t       xwidget_info_mfg_num_get(xwidget_info_t);
-char 			*xwidget_info_name_get(xwidget_info_t);
-void                    xtalk_init(void);
-void                    xtalk_provider_register(devfs_handle_t, xtalk_provider_t *);
-void                    xtalk_provider_unregister(devfs_handle_t);
-xtalk_provider_t       *xtalk_provider_fns_get(devfs_handle_t);
-int                     xwidget_driver_register(xwidget_part_num_t, 
-						xwidget_mfg_num_t, 
-						char *, unsigned);
-void                    xwidget_driver_unregister(char *);
-int                     xwidget_register(xwidget_hwid_t, devfs_handle_t, 
-					 xwidgetnum_t, devfs_handle_t, 
-					 xwidgetnum_t, async_attach_t);
-int			xwidget_unregister(devfs_handle_t);
-void                    xwidget_reset(devfs_handle_t);
-char			*xwidget_name_get(devfs_handle_t);
-#if !defined(DEV_FUNC)
-/*
- * There is more than one possible provider
- * for this platform. We need to examine the
- * master vertex of the current vertex for
- * a provider function structure, and indirect
- * through the appropriately named member.
- */
-#define	DEV_FUNC(dev,func)	xwidget_to_provider_fns(dev)->func
-#define	CAST_PIOMAP(x)		((xtalk_piomap_t)(x))
-#define	CAST_DMAMAP(x)		((xtalk_dmamap_t)(x))
-#define	CAST_INTR(x)		((xtalk_intr_t)(x))
-
-static xtalk_provider_t *
-xwidget_to_provider_fns(devfs_handle_t xconn)
-{
-    xwidget_info_t          widget_info;
-    xtalk_provider_t       *provider_fns;
-
-    widget_info = xwidget_info_get(xconn);
-    ASSERT(widget_info != NULL);
-
-    provider_fns = xwidget_info_pops_get(widget_info);
-    ASSERT(provider_fns != NULL);
-
-    return (provider_fns);
-}
-#endif
-
-/*
- * Many functions are not passed their vertex
- * information directly; rather, they must
- * dive through a resource map. These macros
- * are available to coordinate this detail.
- */
-#define	PIOMAP_FUNC(map,func)	DEV_FUNC(map->xp_dev,func)
-#define	DMAMAP_FUNC(map,func)	DEV_FUNC(map->xd_dev,func)
-#define	INTR_FUNC(intr,func)	DEV_FUNC(intr_hdl->xi_dev,func)
-
-/* =====================================================================
- *                    PIO MANAGEMENT
- *
- *      For mapping system virtual address space to
- *      xtalk space on a specified widget
- */
-
-xtalk_piomap_t
-xtalk_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
-		   size_t byte_count,
-		   size_t byte_count_max,	/* maximum size of a mapping */
-		   unsigned flags)
-{				/* defined in sys/pio.h */
-    return (xtalk_piomap_t) DEV_FUNC(dev, piomap_alloc)
-	(dev, dev_desc, xtalk_addr, byte_count, byte_count_max, flags);
-}
-
-
-void
-xtalk_piomap_free(xtalk_piomap_t xtalk_piomap)
-{
-    PIOMAP_FUNC(xtalk_piomap, piomap_free)
-	(CAST_PIOMAP(xtalk_piomap));
-}
-
-
-caddr_t
-xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap,	/* mapping resources */
-		  iopaddr_t xtalk_addr,		/* map for this xtalk address */
-		  size_t byte_count)
-{				/* map this many bytes */
-    return PIOMAP_FUNC(xtalk_piomap, piomap_addr)
-	(CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count);
-}
-
-
-void
-xtalk_piomap_done(xtalk_piomap_t xtalk_piomap)
-{
-    PIOMAP_FUNC(xtalk_piomap, piomap_done)
-	(CAST_PIOMAP(xtalk_piomap));
-}
-
-
-caddr_t
-xtalk_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    iopaddr_t xtalk_addr,	/* Crosstalk address */
-		    size_t byte_count,	/* map this many bytes */
-		    unsigned flags)
-{				/* (currently unused) */
-    return DEV_FUNC(dev, piotrans_addr)
-	(dev, dev_desc, xtalk_addr, byte_count, flags);
-}
-
-caddr_t
-xtalk_pio_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       iopaddr_t addr,		/* starting address (or offset in window) */
-	       size_t byte_count,	/* map this many bytes */
-	       xtalk_piomap_t *mapp,	/* where to return the map pointer */
-	       unsigned flags)
-{					/* PIO flags */
-    xtalk_piomap_t          map = 0;
-    caddr_t                 res;
-
-    if (mapp)
-	*mapp = 0;			/* record "no map used" */
-
-    res = xtalk_piotrans_addr
-	(dev, dev_desc, addr, byte_count, flags);
-    if (res)
-	return res;			/* xtalk_piotrans worked */
-
-    map = xtalk_piomap_alloc
-	(dev, dev_desc, addr, byte_count, byte_count, flags);
-    if (!map)
-	return res;			/* xtalk_piomap_alloc failed */
-
-    res = xtalk_piomap_addr
-	(map, addr, byte_count);
-    if (!res) {
-	xtalk_piomap_free(map);
-	return res;			/* xtalk_piomap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* xtalk_piomap_addr succeeded */
-}
-
-/* =====================================================================
- *            EARLY PIOTRANS SUPPORT
- *
- *      There are places where drivers (mgras, for instance)
- *      need to get PIO translations before the infrastructure
- *      is extended to them (setting up textports, for
- *      instance). These drivers should call
- *      xtalk_early_piotrans_addr with their xtalk ID
- *      information, a sequence number (so we can use the second
- *      mgras for instance), and the usual piotrans parameters.
- *
- *      Machine specific code should provide an implementation
- *      of early_piotrans_addr, and present a pointer to this
- *      function to xtalk_set_early_piotrans_addr so it can be
- *      used by clients without the clients having to know what
- *      platform or what xtalk provider is in use.
- */
-
-static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr;
-
-xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr;
-
-/* xtalk_set_early_piotrans_addr:
- * specify the early_piotrans_addr implementation function.
- */
-void
-xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl)
-{
-    impl_early_piotrans_addr = impl;
-}
-
-/* xtalk_early_piotrans_addr:
- * figure out a PIO address for the "nth" crosstalk widget that
- * matches the specified part and mfgr number. Returns NULL if
- * there is no such widget, or if the requested mapping can not
- * be constructed.
- * Limitations on which crosstalk slots (and busses) are
- * checked, and definitions of the ordering of the search across
- * the crosstalk slots, are defined by the platform.
- */
-caddr_t
-xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
-			  xwidget_mfg_num_t mfg_num,
-			  int which,
-			  iopaddr_t xtalk_addr,
-			  size_t byte_count,
-			  unsigned flags)
-{
-    return impl_early_piotrans_addr
-	(part_num, mfg_num, which, xtalk_addr, byte_count, flags);
-}
-
-/* null_xtalk_early_piotrans_addr:
- * used as the early_piotrans_addr implementation until and
- * unless a real implementation is provided. In DEBUG kernels,
- * we want to know who is calling before the implementation is
- * registered; in non-DEBUG kernels, return NULL representing
- * lack of mapping support.
- */
-/*ARGSUSED */
-static caddr_t
-null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
-			       xwidget_mfg_num_t mfg_num,
-			       int which,
-			       iopaddr_t xtalk_addr,
-			       size_t byte_count,
-			       unsigned flags)
-{
-#if DEBUG
-    PRINT_PANIC("null_xtalk_early_piotrans_addr");
-#endif
-    return NULL;
-}
-
-/* =====================================================================
- *                    DMA MANAGEMENT
- *
- *      For mapping from crosstalk space to system
- *      physical space.
- */
-
-xtalk_dmamap_t
-xtalk_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   size_t byte_count_max,	/* max size of a mapping */
-		   unsigned flags)
-{				/* defined in dma.h */
-    return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-	(dev, dev_desc, byte_count_max, flags);
-}
-
-
-void
-xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap)
-{
-    DMAMAP_FUNC(xtalk_dmamap, dmamap_free)
-	(CAST_DMAMAP(xtalk_dmamap));
-}
-
-
-iopaddr_t
-xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */
-		  paddr_t paddr,	/* map for this address */
-		  size_t byte_count)
-{				/* map this many bytes */
-    return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr)
-	(CAST_DMAMAP(xtalk_dmamap), paddr, byte_count);
-}
-
-
-alenlist_t
-xtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(xtalk_dmamap, dmamap_list)
-	(CAST_DMAMAP(xtalk_dmamap), alenlist, flags);
-}
-
-
-void
-xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap)
-{
-    DMAMAP_FUNC(xtalk_dmamap, dmamap_done)
-	(CAST_DMAMAP(xtalk_dmamap));
-}
-
-
-iopaddr_t
-xtalk_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    paddr_t paddr,	/* system physical address */
-		    size_t byte_count,	/* length */
-		    unsigned flags)
-{				/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_addr)
-	(dev, dev_desc, paddr, byte_count, flags);
-}
-
-
-alenlist_t
-xtalk_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{				/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
-void
-xtalk_dmamap_drain(xtalk_dmamap_t map)
-{
-    DMAMAP_FUNC(map, dmamap_drain)
-	(CAST_DMAMAP(map));
-}
-
-void
-xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
-{
-    DEV_FUNC(dev, dmaaddr_drain)
-	(dev, addr, size);
-}
-
-void
-xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-	(dev, list);
-}
-
-/* =====================================================================
- *                    INTERRUPT MANAGEMENT
- *
- *      Allow crosstalk devices to establish interrupts
- */
-
-/*
- * Allocate resources required for an interrupt as specified in intr_desc.
- * Return resource handle in intr_hdl.
- */
-xtalk_intr_t
-xtalk_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
-		 device_desc_t dev_desc,	/* device descriptor */
-		 devfs_handle_t owner_dev)
-{				/* owner of this interrupt */
-    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc)
-	(dev, dev_desc, owner_dev);
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Unconditionally setup resources to be non-threaded.
- * Return resource handle in intr_hdl.
- */
-xtalk_intr_t
-xtalk_intr_alloc_nothd(devfs_handle_t dev,	/* which Crosstalk device */
-		 	device_desc_t dev_desc,	/* device descriptor */
-		 	devfs_handle_t owner_dev)	/* owner of this interrupt */
-{
-    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)
-	(dev, dev_desc, owner_dev);
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-xtalk_intr_free(xtalk_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_free)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/*
- * Associate resources allocated with a previous xtalk_intr_alloc call with the
- * described handler, arg, name, etc.
- *
- * Returns 0 on success, returns <0 on failure.
- */
-int
-xtalk_intr_connect(xtalk_intr_t intr_hdl,	/* xtalk intr resource handle */
-		   xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */
-		   void *setfunc_arg)	/* arg to setfunc */
-{
-    return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl), setfunc, setfunc_arg);
-}
-
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-xtalk_intr_disconnect(xtalk_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_disconnect)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
-{
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/* =====================================================================
- *                    CONFIGURATION MANAGEMENT
- */
-
-/*
- * Startup a crosstalk provider
- */
-void
-xtalk_provider_startup(devfs_handle_t xtalk_provider)
-{
-    DEV_FUNC(xtalk_provider, provider_startup)
-	(xtalk_provider);
-}
-
-
-/*
- * Shutdown a crosstalk provider
- */
-void
-xtalk_provider_shutdown(devfs_handle_t xtalk_provider)
-{
-    DEV_FUNC(xtalk_provider, provider_shutdown)
-	(xtalk_provider);
-}
-
-/* 
- * Enable a device on a xtalk widget 
- */
-void
-xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
-{
-    DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum);
-}
-
-/* 
- * Shutdown a device on a xtalk widget 
- */
-void
-xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
-{
-    DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum);
-}
-
-int
-xtalk_dma_enabled(devfs_handle_t xconn_vhdl)
-{
-    return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl);
-}
-/*
- * Generic crosstalk functions, for use with all crosstalk providers
- * and all crosstalk devices.
- */
-
-/****** Generic crosstalk interrupt interfaces ******/
-devfs_handle_t
-xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_dev);
-}
-
-xwidgetnum_t
-xtalk_intr_target_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_target);
-}
-
-xtalk_intr_vector_t
-xtalk_intr_vector_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_vector);
-}
-
-iopaddr_t
-xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr)
-{
-    return (xtalk_intr->xi_addr);
-}
-
-void                   *
-xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_sfarg);
-}
-
-/****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
-xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_dev);
-}
-
-xwidgetnum_t
-xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_target);
-}
-
-iopaddr_t
-xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_xtalk_addr);
-}
-
-ulong
-xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_mapsz);
-}
-
-caddr_t
-xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_kvaddr);
-}
-
-
-/****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
-xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
-{
-    return (xtalk_dmamap->xd_dev);
-}
-
-xwidgetnum_t
-xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap)
-{
-    return (xtalk_dmamap->xd_target);
-}
-
-
-/****** Generic crosstalk widget information interfaces ******/
-
-/* xwidget_info_chk:
- * check to see if this vertex is a widget;
- * if so, return its widget_info (if any).
- * if not, return NULL.
- */
-xwidget_info_t
-xwidget_info_chk(devfs_handle_t xwidget)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo);
-    return (xwidget_info_t) ainfo;
-}
-
-
-xwidget_info_t
-xwidget_info_get(devfs_handle_t xwidget)
-{
-    xwidget_info_t          widget_info;
-
-    widget_info = (xwidget_info_t)
-	hwgraph_fastinfo_get(xwidget);
-
-#ifdef	LATER
-    if ((widget_info != NULL) &&
-	(widget_info->w_fingerprint != widget_info_fingerprint))
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	PRINT_PANIC("%v bad xwidget_info", xwidget);
-#else
-	PRINT_PANIC("%x bad xwidget_info", xwidget);
-#endif
-#endif	/* LATER */
-
-    return (widget_info);
-}
-
-void
-xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info)
-{
-    if (widget_info != NULL)
-	widget_info->w_fingerprint = widget_info_fingerprint;
-
-    hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info);
-
-    /* Also, mark this vertex as an xwidget,
-     * and use the widget_info, so xwidget_info_chk
-     * can work (and be fairly efficient).
-     */
-    hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET,
-			 (arbitrary_info_t) widget_info);
-}
-
-devfs_handle_t
-xwidget_info_dev_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_vertex);
-}
-
-xwidgetnum_t
-xwidget_info_id_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_id);
-}
-
-
-devfs_handle_t
-xwidget_info_master_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_master);
-}
-
-xwidgetnum_t
-xwidget_info_masterid_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_masterid);
-}
-
-xwidget_part_num_t
-xwidget_info_part_num_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_hwid.part_num);
-}
-
-xwidget_mfg_num_t
-xwidget_info_mfg_num_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_hwid.mfg_num);
-}
-/* Extract the widget name from the widget information
- * for the xtalk widget.
- */
-char *
-xwidget_info_name_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget info");
-    return(xwidget_info->w_name);
-}
-/****** Generic crosstalk initialization interfaces ******/
-
-/*
- * One-time initialization needed for systems that support crosstalk.
- */
-void
-xtalk_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("xtalk_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (xtalk_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr");
-	if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(xtalk_registry != NULL);
-}
-
-/*
- * Associate a set of xtalk_provider functions with a vertex.
- */
-void
-xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns)
-{
-    hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);
-}
-
-/*
- * Disassociate a set of xtalk_provider functions with a vertex.
- */
-void
-xtalk_provider_unregister(devfs_handle_t provider)
-{
-    hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);
-}
-
-/*
- * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk
- * provider.
- */
-xtalk_provider_t       *
-xtalk_provider_fns_get(devfs_handle_t provider)
-{
-    return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));
-}
-
-/*
- * Announce a driver for a particular crosstalk part.
- * Returns 0 on success or -1 on failure.  Failure occurs if the
- * specified hardware already has a driver.
- */
-/*ARGSUSED4 */
-int
-xwidget_driver_register(xwidget_part_num_t part_num,
-			xwidget_mfg_num_t mfg_num,
-			char *driver_prefix,
-			unsigned flags)
-{
-    /* a driver's init routine could call
-     * xwidget_driver_register before the
-     * system calls xtalk_init; so, we
-     * make the call here.
-     */
-    if (xtalk_registry == NULL)
-	xtalk_init();
-
-    return cdl_add_driver(xtalk_registry,
-			  part_num, mfg_num,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Inform xtalk infrastructure that a driver is no longer available for
- * handling any widgets.
- */
-void
-xwidget_driver_unregister(char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called registger; so we
-     * can assume we have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_del_driver(xtalk_registry, driver_prefix, NULL);
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-xtalk_iterate(char *driver_prefix,
-	      xtalk_iter_f *func)
-{
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func);
-}
-
-/*
- * xwidget_register:
- *	Register a xtalk device (xwidget) by doing the following.
- *      -allocate and initialize xwidget_info data
- *      -allocate a hwgraph vertex with name based on widget number (id)
- *      -look up the widget's initialization function and call it,
- *      or remember the vertex for later initialization.
- *
- */
-int
-xwidget_register(xwidget_hwid_t hwid,		/* widget's hardware ID */
-		 devfs_handle_t 	widget,		/* widget to initialize */
-		 xwidgetnum_t 	id,		/* widget's target id (0..f) */
-		 devfs_handle_t 	master,		/* widget's master vertex */
-		 xwidgetnum_t 	targetid,	/* master's target id (9/a) */
-		 async_attach_t aa)
-{			
-    xwidget_info_t          widget_info;
-    char		    *s,devnm[MAXDEVNAME];
-
-    /* Allocate widget_info and associate it with widget vertex */
-    NEW(widget_info);
-
-    /* Initialize widget_info */
-    widget_info->w_vertex = widget;
-    widget_info->w_id = id;
-    widget_info->w_master = master;
-    widget_info->w_masterid = targetid;
-    widget_info->w_hwid = *hwid;	/* structure copy */
-    widget_info->w_efunc = 0;
-    widget_info->w_einfo = 0;
-    /*
-     * get the name of this xwidget vertex and keep the info.
-     * This is needed during errors and interupts, but as
-     * long as we have it, we can use it elsewhere.
-     */
-    s = dev_to_name(widget,devnm,MAXDEVNAME);
-    widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
-    strcpy(widget_info->w_name,s);
-    
-    xwidget_info_set(widget, widget_info);
-
-    device_master_set(widget, master);
-
-    /* All the driver init routines (including
-     * xtalk_init) are called before we get into
-     * attaching devices, so we can assume we
-     * have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    /* 
-     * Add pointer to async attach info -- tear down will be done when
-     * the particular descendant is done with the info.
-     */
-    if (aa)
-	    async_attach_add_info(widget, aa);
-
-    return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                          widget, 0);
-}
-
-/*
- * xwidget_unregister :
- *	Unregister the xtalk device and detach all its hwgraph namespace.
- */
-int
-xwidget_unregister(devfs_handle_t widget)
-{
-    xwidget_info_t	widget_info;
-    xwidget_hwid_t	hwid;
-
-    /* Make sure that we have valid widget information initialized */
-    if (!(widget_info = xwidget_info_get(widget)))
-	return(1);
-
-    /* Remove the inventory information associated
-     * with the widget.
-     */
-    hwgraph_inventory_remove(widget, -1, -1, -1, -1, -1);
-    
-    hwid = &(widget_info->w_hwid);
-
-    cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                   widget, 0);
-
-    /* Clean out the xwidget information */
-    (void)kfree(widget_info->w_name);
-    BZERO((void *)widget_info, sizeof(widget_info));
-    DEL(widget_info);
-    
-    return(0);
-}
-
-/*
- * Issue a link reset to a widget.
- */
-void
-xwidget_reset(devfs_handle_t xwidget)
-{
-    xswitch_reset_link(xwidget);
-
-}
-
-
-void
-xwidget_gfx_reset(devfs_handle_t xwidget)
-{
-    xwidget_info_t info;
-
-    xswitch_reset_link(xwidget);
-    info = xwidget_info_get(xwidget);
-#ifdef LATER
-    ASSERT_ALWAYS(info != NULL);
-#endif
-
-    /*
-     * Enable this for other architectures once we add widget_reset to the
-     * xtalk provider interface.
-     */
-    DEV_FUNC(xtalk_provider, widget_reset)
-	(xwidget_info_master_get(info), xwidget_info_id_get(info));
-}
-
-#define ANON_XWIDGET_NAME	"No Name"	/* Default Widget Name */
-
-/* Get the canonical hwgraph  name of xtalk widget */
-char *
-xwidget_name_get(devfs_handle_t xwidget_vhdl)
-{
-	xwidget_info_t  info;
-
-	/* If we have a bogus widget handle then return
-	 * a default anonymous widget name.
-	 */
-	if (xwidget_vhdl == GRAPH_VERTEX_NONE)
-	    return(ANON_XWIDGET_NAME);
-	/* Read the widget name stored in the widget info
-	 * for the widget setup during widget initialization.
-	 */
-	info = xwidget_info_get(xwidget_vhdl);
-	ASSERT(info != NULL);
-	return(xwidget_info_name_get(info));
-}
-
-/*
- * xtalk_device_shutdown
- *	Disable  the specified xtalk widget and clean out all the software
- *	state associated with it.
- */
-int
-xtalk_device_shutdown(devfs_handle_t xbus_vhdl, xwidgetnum_t widget)
-{
-	devfs_handle_t	widget_vhdl;
-	char		edge_name[8];
-
-	sprintf(edge_name, "%d", widget);
-	if (hwgraph_traverse(xbus_vhdl, edge_name, &widget_vhdl) 
-	    != GRAPH_SUCCESS)
-		return(1);
-
-	xwidget_unregister(widget_vhdl);
-	
-	return(0);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/Makefile linux-2.4.22-pre3/arch/ia64/sn/kernel/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/Makefile	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/Makefile	2003-07-05 18:09:45.000000000 -0700
@@ -1,6 +1,6 @@
 # arch/ia64/sn/kernel/Makefile
 #
-# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+# Copyright (C) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it 
 # under the terms of version 2 of the GNU General Public License 
@@ -40,21 +40,15 @@
 
 O_TARGET        = sn.o
 
-export-objs = sn_ksyms.o iomv.o
+export-objs = sn_ksyms.o
 
-subdir-$(CONFIG_IA64_SGI_SN1)	= sn1
-subdir-$(CONFIG_IA64_SGI_SN2)	= sn2
+subdir-y			= sn2
 
-obj-y		= probe.o setup.o sn_asm.o sv.o bte.o iomv.o
-obj-$(CONFIG_IA64_SGI_SN1)      += irq.o mca.o
-obj-$(CONFIG_IA64_SGI_SN2)      += irq.o mca.o
+obj-y				= probe.o setup.o sv.o bte.o
+obj-y			        += irq.o mca.o idle.o
+obj-y			        += sn2/sn2.o
 
-obj-$(CONFIG_IA64_SGI_SN1)      += sn1/sn1.o  
-obj-$(CONFIG_IA64_SGI_SN2)      += sn2/sn2.o  
-
-obj-$(CONFIG_IA64_SGI_AUTOTEST) += llsc4.o misctest.o
 obj-$(CONFIG_IA64_GENERIC)      += machvec.o
 obj-$(CONFIG_MODULES)           += sn_ksyms.o
-obj-$(CONFIG_IA64_SGI_SN_BRT)	+= bte_regr_test.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/bte.c linux-2.4.22-pre3/arch/ia64/sn/kernel/bte.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/bte.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/bte.c	2003-07-05 18:09:45.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -38,130 +38,157 @@
 #include <asm/sn/arch.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/pda.h>
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn2/shubio.h>
-#endif
 #include <asm/nodedata.h>
 
 #include <linux/bootmem.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 
-#include <asm/sn/bte_copy.h>
+#include <asm/sn/bte.h>
 
-int bte_offsets[] = { IIO_IBLS0, IIO_IBLS1 };
 
 /*
- * bte_init_node(nodepda, cnode)
+ * The base address of for each set of bte registers.
+ */
+static int bte_offsets[] = { IIO_IBLS0, IIO_IBLS1 };
+
+
+/************************************************************************
+ * Block Transfer Engine copy related functions.
  *
- * Initialize the nodepda structure with BTE base addresses and
- * spinlocks.
+ ***********************************************************************/
+
+
+/*
+ * bte_copy(src, dest, len, mode, notification)
  *
- * NOTE: The kernel parameter btetest will cause the initialization
- * code to reserve blocks of physically contiguous memory to be
- * used by the bte test module.
+ * Use the block transfer engine to move kernel memory from src to dest
+ * using the assigned mode.
+ *
+ * Paramaters:
+ *   src - physical address of the transfer source.
+ *   dest - physical address of the transfer destination.
+ *   len - number of bytes to transfer from source to dest.
+ *   mode - hardware defined.  See reference information
+ *          for IBCT0/1 in the SHUB Programmers Reference
+ *   notification - kernel virtual address of the notification cache
+ *                  line.  If NULL, the default is used and
+ *                  the bte_copy is synchronous.
+ *
+ * NOTE:  This function requires src, dest, and len to
+ * be cacheline aligned.
  */
-void
-bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode)
+bte_result_t
+bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
 {
-	int i;
+	int bte_to_use;
+	u64 transfer_size;
+	struct bteinfo_s *bte;
+	bte_result_t bte_status;
+	unsigned long irq_flags;
 
 
-	/*
-	 * Indicate that all the block transfer engines on this node
-	 * are available.
-	 */
-	for (i = 0; i < BTES_PER_NODE; i++) {
-#ifdef CONFIG_IA64_SGI_SN2
-		/* >>> Don't know why the 0x1800000L is here.  Robin */
-		mynodepda->bte_if[i].bte_base_addr =
-		    (char *)LOCAL_MMR_ADDR(bte_offsets[i] | 0x1800000L);
+	BTE_PRINTK(("bte_copy(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%p)\n",
+		    src, dest, len, mode, notification));
 
-#elif CONFIG_IA64_SGI_SN1
-		mynodepda->bte_if[i].bte_base_addr =
-		    (char *)LOCAL_HUB_ADDR(bte_offsets[i]);
-#else
-#error BTE Not defined for this hardware platform.
-#endif
+	if (len == 0) {
+		return BTE_SUCCESS;
+	}
 
-		/*
-		 * Initialize the notification and spinlock
-		 * so the first transfer can occur.
-		 */
-		mynodepda->bte_if[i].most_rcnt_na =
-		    &(mynodepda->bte_if[i].notify);
-		mynodepda->bte_if[i].notify = 0L;
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-		spin_lock_init(&mynodepda->bte_if[i].spinlock);
-#endif				/* CONFIG_IA64_SGI_BTE_LOCKING */
+	ASSERT(!((len & L1_CACHE_MASK) ||
+		 (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK)));
+	ASSERT(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT));
+
+	do {
+		local_irq_save(irq_flags);
+
+		bte_to_use = 0;
+		/* Attempt to lock one of the BTE interfaces. */
+		while ((bte_to_use < BTES_PER_NODE) &&
+		       BTE_LOCK_IF_AVAIL(bte_to_use)) {
+			bte_to_use++;
+		}
+
+		if (bte_to_use < BTES_PER_NODE) {
+			break;
+		}
+
+		local_irq_restore(irq_flags);
+
+		if (!(mode & BTE_WACQUIRE)) {
+			return BTEFAIL_NOTAVAIL;
+		}
 
-		mynodepda->bte_if[i].bte_test_buf =
-			alloc_bootmem_node(NODE_DATA(cnode), BTE_MAX_XFER);
+		/* Wait until a bte is available. */
+		udelay(10);
+	} while (1);
+
+	bte = pda.cpu_bte_if[bte_to_use];
+	BTE_PRINTKV(("Got a lock on bte %d\n", bte_to_use));
+
+
+	if (notification == NULL) {
+		/* User does not want to be notified. */
+		bte->most_rcnt_na = &bte->notify;
+	} else {
+		bte->most_rcnt_na = notification;
 	}
 
-}
+	/* Calculate the number of cache lines to transfer. */
+	transfer_size = ((len >> L1_CACHE_SHIFT) & BTE_LEN_MASK);
 
+	/* Initialize the notification to a known value. */
+	*bte->most_rcnt_na = -1L;
 
-/*
- * bte_reset_nasid(nasid_t)
- *
- * Does a soft reset of the BTEs on the specified nasid.
- * This is followed by a one-line transfer from each of the
- * virtual interfaces.
- */
-void
-bte_reset_nasid(nasid_t n)
-{
-	ii_ibcr_u_t	ibcr;
+	/* Set the status reg busy bit and transfer length */
+	BTE_PRINTKV(("IBLS - HUB_S(0x%p, 0x%lx)\n",
+		     BTEREG_LNSTAT_ADDR, IBLS_BUSY | transfer_size));
+	HUB_S(BTEREG_LNSTAT_ADDR, (IBLS_BUSY | transfer_size));
+
+	/* Set the source and destination registers */
+	BTE_PRINTKV(("IBSA - HUB_S(0x%p, 0x%lx)\n", BTEREG_SRC_ADDR,
+		     (TO_PHYS(src))));
+	HUB_S(BTEREG_SRC_ADDR, (TO_PHYS(src)));
+	BTE_PRINTKV(("IBDA - HUB_S(0x%p, 0x%lx)\n", BTEREG_DEST_ADDR,
+		     (TO_PHYS(dest))));
+	HUB_S(BTEREG_DEST_ADDR, (TO_PHYS(dest)));
+
+	/* Set the notification register */
+	BTE_PRINTKV(("IBNA - HUB_S(0x%p, 0x%lx)\n", BTEREG_NOTIF_ADDR,
+		     (TO_PHYS(__tpa(bte->most_rcnt_na)))));
+	HUB_S(BTEREG_NOTIF_ADDR, (TO_PHYS(__tpa(bte->most_rcnt_na))));
+
+
+	/* Initiate the transfer */
+	BTE_PRINTK(("IBCT - HUB_S(0x%p, 0x%lx)\n", BTEREG_CTRL_ADDR,
+		     BTE_VALID_MODE(mode)));
+	HUB_S(BTEREG_CTRL_ADDR, BTE_VALID_MODE(mode));
 
-	ibcr.ii_ibcr_regval  = REMOTE_HUB_L(n, IIO_IBCR);
-	ibcr.ii_ibcr_fld_s.i_soft_reset = 1;
-	REMOTE_HUB_S(n, IIO_IBCR, ibcr.ii_ibcr_regval);
-
-	/* One line transfer on virtual interface 0 */
-	REMOTE_HUB_S(n, IIO_IBLS_0, IBLS_BUSY | 1);
-	REMOTE_HUB_S(n, IIO_IBSA_0, TO_PHYS(__pa(&nodepda->bte_cleanup)));
-	REMOTE_HUB_S(n, IIO_IBDA_0,
-		     TO_PHYS(__pa(&nodepda->bte_cleanup[4*L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBNA_0,
-		     TO_PHYS(__pa(&nodepda->bte_cleanup[4*L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBCT_0, BTE_NOTIFY);
-	while (REMOTE_HUB_L(n, IIO_IBLS0)) {
-		/* >>> Need some way out in case of hang... */
+	spin_unlock_irqrestore(&bte->spinlock, irq_flags);
+
+
+	if (notification != NULL) {
+		return BTE_SUCCESS;
 	}
 
-	/* One line transfer on virtual interface 1 */
-	REMOTE_HUB_S(n, IIO_IBLS_1, IBLS_BUSY | 1);
-	REMOTE_HUB_S(n, IIO_IBSA_1, TO_PHYS(__pa(nodepda->bte_cleanup)));
-	REMOTE_HUB_S(n, IIO_IBDA_1,
-		     TO_PHYS(__pa(nodepda->bte_cleanup[4 * L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBNA_1,
-		     TO_PHYS(__pa(nodepda->bte_cleanup[5 * L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBCT_1, BTE_NOTIFY);
-	while (REMOTE_HUB_L(n, IIO_IBLS1)) {
-		/* >>> Need some way out in case of hang... */
+	while (*bte->most_rcnt_na == -1UL) {
 	}
-}
 
 
-/*
- * bte_init_cpu()
- *
- * Initialize the cpupda structure with pointers to the
- * nodepda bte blocks.
- *
- */
-void
-bte_init_cpu(void)
-{
-	/* Called by setup.c as each cpu is being added to the nodepda */
-	if (local_node_data->active_cpu_count & 0x1) {
-		pda.cpu_bte_if[0] = &(nodepda->bte_if[0]);
-		pda.cpu_bte_if[1] = &(nodepda->bte_if[1]);
+	BTE_PRINTKV((" Delay Done.  IBLS = 0x%lx, most_rcnt_na = 0x%lx\n",
+				HUB_L(BTEREG_LNSTAT_ADDR), *bte->most_rcnt_na));
+
+	if (*bte->most_rcnt_na & IBLS_ERROR) {
+		bte_status = *bte->most_rcnt_na & ~IBLS_ERROR;
+		*bte->most_rcnt_na = 0L;
 	} else {
-		pda.cpu_bte_if[0] = &(nodepda->bte_if[1]);
-		pda.cpu_bte_if[1] = &(nodepda->bte_if[0]);
+		bte_status = BTE_SUCCESS;
 	}
+	BTE_PRINTK(("Returning status is 0x%lx and most_rcnt_na is 0x%lx\n",
+				HUB_L(BTEREG_LNSTAT_ADDR), *bte->most_rcnt_na));
+
+	return bte_status;
 }
 
 
@@ -198,15 +225,11 @@
 	char *bteBlock;
 
 	if (len == 0) {
-		return (BTE_SUCCESS);
+		return BTE_SUCCESS;
 	}
 
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-#error bte_unaligned_copy() assumes single BTE selection in bte_copy().
-#else
 	/* temporary buffer used during unaligned transfers */
-	bteBlock = pda.cpu_bte_if[0]->bte_test_buf;
-#endif
+	bteBlock = pda.cpu_bte_if[0]->scratch_buf;
 
 	headBcopySrcOffset = src & L1_CACHE_MASK;
 	destFirstCacheOffset = dest & L1_CACHE_MASK;
@@ -271,15 +294,15 @@
 				headBteLen += footBteLen;
 			} else if (footBcopyLen > 0) {
 				rv = bte_copy(footBteSource,
-					      __pa(bteBlock),
+					      __tpa(bteBlock),
 					      footBteLen, mode, NULL);
 				if (rv != BTE_SUCCESS) {
-					return (rv);
+					return rv;
 				}
 
 
 				memcpy(__va(footBcopyDest),
-				       (char *)bteBlock, footBcopyLen);
+				       (char *) bteBlock, footBcopyLen);
 			}
 		} else {
 			footBcopyLen = 0;
@@ -294,7 +317,7 @@
 				      (len - headBcopyLen -
 				       footBcopyLen), mode, NULL);
 			if (rv != BTE_SUCCESS) {
-				return (rv);
+				return rv;
 			}
 
 		}
@@ -321,14 +344,93 @@
 
 	if (headBcopyLen > 0) {
 		rv = bte_copy(headBteSource,
-			      __pa(bteBlock), headBteLen, mode, NULL);
+			      __tpa(bteBlock), headBteLen, mode, NULL);
 		if (rv != BTE_SUCCESS) {
-			return (rv);
+			return rv;
 		}
 
-		memcpy(__va(headBcopyDest), ((char *)bteBlock +
+		memcpy(__va(headBcopyDest), ((char *) bteBlock +
 					     headBcopySrcOffset),
 		       headBcopyLen);
 	}
-	return (BTE_SUCCESS);
+	return BTE_SUCCESS;
+}
+
+
+/************************************************************************
+ * Block Transfer Engine initialization functions.
+ *
+ ***********************************************************************/
+
+
+/*
+ * bte_init_node(nodepda, cnode)
+ *
+ * Initialize the nodepda structure with BTE base addresses and
+ * spinlocks.
+ */
+void
+bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode)
+{
+	int i;
+
+
+	/*
+	 * Indicate that all the block transfer engines on this node
+	 * are available.
+	 */
+
+	/*
+	 * Allocate one bte_recover_t structure per node.  It holds
+	 * the recovery lock for node.  All the bte interface structures
+	 * will point at this one bte_recover structure to get the lock.
+	 */
+	spin_lock_init(&mynodepda->bte_recovery_lock);
+	init_timer(&mynodepda->bte_recovery_timer);
+	mynodepda->bte_recovery_timer.function = bte_error_handler;
+	mynodepda->bte_recovery_timer.data = (unsigned long) mynodepda;
+
+	for (i = 0; i < BTES_PER_NODE; i++) {
+		/* >>> Don't know why the 0x1800000L is here.  Robin */
+		mynodepda->bte_if[i].bte_base_addr =
+		    (char *) LOCAL_MMR_ADDR(bte_offsets[i] | 0x1800000L);
+
+		/*
+		 * Initialize the notification and spinlock
+		 * so the first transfer can occur.
+		 */
+		mynodepda->bte_if[i].most_rcnt_na =
+		    &(mynodepda->bte_if[i].notify);
+		mynodepda->bte_if[i].notify = 0L;
+		spin_lock_init(&mynodepda->bte_if[i].spinlock);
+
+		mynodepda->bte_if[i].scratch_buf =
+		    alloc_bootmem_node(NODE_DATA(cnode), BTE_MAX_XFER);
+		mynodepda->bte_if[i].bte_cnode = cnode;
+		mynodepda->bte_if[i].bte_error_count = 0;
+		mynodepda->bte_if[i].bte_num = i;
+		mynodepda->bte_if[i].cleanup_active = 0;
+		mynodepda->bte_if[i].bh_error = 0;
+	}
+
+}
+
+/*
+ * bte_init_cpu()
+ *
+ * Initialize the cpupda structure with pointers to the
+ * nodepda bte blocks.
+ *
+ */
+void
+bte_init_cpu(void)
+{
+	/* Called by setup.c as each cpu is being added to the nodepda */
+	if (local_node_data->active_cpu_count & 0x1) {
+		pda.cpu_bte_if[0] = &(nodepda->bte_if[0]);
+		pda.cpu_bte_if[1] = &(nodepda->bte_if[1]);
+	} else {
+		pda.cpu_bte_if[0] = &(nodepda->bte_if[1]);
+		pda.cpu_bte_if[1] = &(nodepda->bte_if[0]);
+	}
 }
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/bte_regr_test.c linux-2.4.22-pre3/arch/ia64/sn/kernel/bte_regr_test.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/bte_regr_test.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/bte_regr_test.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1062 +0,0 @@
-/*
- *
- *
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-
-/***********************************************************************
- * Block Transfer Engine regression tests.
- *
- *	The following set of tests can be used to test for regressions.
- *	It is implemented as a loadable module.
- *
- *	To enable the tests, the kernel must be booted with the
- *	"btetest" command line flag.  If the tests are compiled into the
- *	kernel, additional values may be passed with
- *	"bte_test=t,v,ht,tn,tx,ti,ta,tc"
- *	where:
- *	    t = Bitmask of tests to run.
- *	    v = Level of verbosity.
- *	    ht = Number of seconds to try to force a notification hang.
- *          hu = Number of uSecs to wait until warning of hang.
- *	    tn = Min number of lines to rate test with (2 raised to).
- *	    tx = Max number of lines to rate test with (2 raised to).
- *	    ti = Number of iterations per timing.
- *          ta = Aternate through cpus on each pass.
- *	    tc = Use/Don't Use memcopy
- *
- *	When loaded as a module, each of those values has a seperate
- *	parameter.  Just do a modinfo bte_test.o to get those names
- *	and valid ranges.
- *
- *	Tests are performed in the following order.
- *
- *	Standard Transfer Test - Just transfers a block of initialized
- *	data to a cleared block and ensures that memory before and after
- *	is untouched, but that the body has all the correct values.
- *
- *	Transfer Rate Test - Data is transfered from node to node
- *	to ensure every node is able to BTE data.  Timings are created
- *	for each node.
- *
- *	Notification Hang Test - Attempts to force the Notification
- *	hang problem to arise.  A hang occurs when the BTE fails
- *	to invalidate a processors cache line for the notification
- *	word, resulting in the processor not seeing the updated
- *	value.
- *
- *	Invalid Transfer Test - In this test, we attempt to transfer
- *	data from a valid address to a nasid which does not exist.
- *
- **********************************************************************/
-
-
-#define BTE_TIME 1		/* Needed to ensure bte_copy records
-				 * timings */
-// #define BTE_DEBUG
-// #define BTE_DEBUG_VERBOSE
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <asm/sn/nodepda.h>
-#include <asm/processor.h>
-
-#include <asm/sn/bte_copy.h>
-
-
-/***********************************************************************
- * Local defines, structs, and typedefs.
- *
- **********************************************************************/
-
-
-/*
- * The following struct defines standard transfers to use while
- * testing.
- */
-typedef struct brt_xfer_entry_s {
-	int source_offset;
-	int dest_offset;
-	int length;
-} brt_xfer_entry_t;
-
-/*
- * BRT_TEST_BLOCK_SIZE needs to accomodate the largest transfer that
- * is found in brt_xfer_tests.
- */
-#define BRT_TEST_BLOCK_SIZE 1024
-
-/* Flags for selecting tests to run. */
-#define TEST_REGRESSION		0x00000001	/* Standard Transfer */
-#define TEST_TIME		0x00000002	/* Timed Transfer */
-#define TEST_NOTIFY		0x00000004	/* Notification Hang */
-#define TEST_NONODE		0x00000008	/* Invalid Nasid Xfer */
-
-
-/***********************************************************************
- * Global variables.
- * 
- **********************************************************************/
-
-
-/*
- * bte_setup_time - Time it takes for bte_copy to get locks
- * 		    acquired and values into SHUB registers to start the
- * 		    xfer.
- *
- * bte_transfer_time - Time where hardware is doing the xfer.
- *
- * bte_tear_down_time - Time to unlock and return.
- *
- * bte_execute_time - Time from first call until return.
- */
-volatile static u64 bte_setup_time;
-volatile static u64 bte_transfer_time;
-volatile static u64 bte_tear_down_time;
-volatile static u64 bte_execute_time;
-
-/* Tests to run during standard transfer tests. */
-static brt_xfer_entry_t brt_xfer_tests[] = {
-	{0, 0, 2 * L1_CACHE_BYTES},	/* The ideal case. */
-
-	{0, 0, 35},		/* Symetrical aligned test. */
-	{L1_CACHE_BYTES, L1_CACHE_BYTES, 35},
-	{0, 0, L1_CACHE_BYTES + 35},
-	{L1_CACHE_BYTES, L1_CACHE_BYTES, L1_CACHE_BYTES + 35},
-	{0, 0, (2 * L1_CACHE_BYTES) + 35},
-	{L1_CACHE_BYTES, L1_CACHE_BYTES, (2 * L1_CACHE_BYTES) + 35},
-	{0, 0, (4 * L1_CACHE_BYTES) + 35},
-	{L1_CACHE_BYTES, L1_CACHE_BYTES, (4 * L1_CACHE_BYTES) + 35},
-
-	{(0 + 25), (0 + 25), 35},	/* Symetrical unaligned test. */
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25), 35},
-	{(0 + 25), (0 + 25), L1_CACHE_BYTES + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25),
-	 (L1_CACHE_BYTES + 25) + 35},
-	{(0 + 25), (0 + 25), (2 * L1_CACHE_BYTES) + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25),
-	 (2 * L1_CACHE_BYTES) + 35},
-	{(0 + 25), (0 + 25), (4 * L1_CACHE_BYTES) + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25),
-	 (4 * L1_CACHE_BYTES) + 35},
-
-	{(0 + 25), (0 + 26), 35},	/* Asymetrical unaligned test. */
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26), 35},
-	{(0 + 25), (0 + 26), L1_CACHE_BYTES + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26),
-	 (L1_CACHE_BYTES + 25) + 35},
-	{(0 + 25), (0 + 26), (2 * L1_CACHE_BYTES) + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26),
-	 (2 * L1_CACHE_BYTES) + 35},
-	{(0 + 25), (0 + 26), (4 * L1_CACHE_BYTES) + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26),
-	 (4 * L1_CACHE_BYTES) + 35},
-
-	{0, 0, 0}		/* Terminator */
-};
-
-static atomic_t brt_thread_cnt;	/* Threads in test. */
-volatile static int brt_exit_flag;	/* Flag termination of hang test */
-
-/* command line/module parameters */
-static int selected_tests = 0;
-static int verbose = 0;
-static int hang_timeout = 10;
-static int hang_usec = 12;
-static int tm_min_lines = 1;
-static int tm_max_lines = 3;
-static int tm_iterations = 1;
-static int tm_alternate = 0;
-static int tm_memcpy = 1;
-static int ix_iterations = 1000;
-static int ix_srcnasid = -1;
-
-
-/***********************************************************************
- * Local Function Prototypes.
- * 
- **********************************************************************/
-
-
-static int __init brt_test_init(void);
-static void __exit brt_test_exit(void);
-
-/* Standard Transfer Test related functions. */
-static int brt_tst_std_xfer(void);
-static int brt_std_xfer(char *, char *, int, int, int, int);
-static void brt_hex_dump(char *, int);
-
-/* Timed Transfer Test related functions. */
-static int brt_tst_time_xfers(void);
-static void brt_time_xfer(int, int, int);
-
-/* Notification Hang Test related functions. */
-static int brt_tst_notify_hang(void);
-static int brt_notify_thrd(void *);
-
-/* Transfers to Invalid Nasid Test related functions. */
-static int brt_tst_invalid_xfers(void);
-
-#if !defined(MODULE)
-/* Kernel command line handler. */
-static int __init brt_setup(char *);
-#endif				/* !defined(MODULE) */
-
-
-/***********************************************************************
- * Module Load/Unload.
- * 
- **********************************************************************/
-
-
-#define brt_marker() \
-	printk("**************************************************" \
-	       "**********************.\n"); \
-	printk("\n"); \
-	printk("**************************************************" \
-	       "**********************.\n"); \
-	printk("\n"); \
-	printk("**************************************************" \
-	       "**********************.\n"); \
-	printk("\n");
-
-
-static int __init
-brt_test_init(void)
-{
-	int some_tests_removed;
-
-	if (numnodes < 2) {
-		printk("These tests are best run on multinode "
-		       "systems.\n");
-	}
-
-	if (!pda.cpu_bte_if[0]->bte_test_buf) {
-		some_tests_removed = 0;
-
-		/* Timed Transfers go node-to-node. */
-		if (selected_tests & TEST_TIME) {
-			some_tests_removed = 1;
-			selected_tests &= ~(TEST_TIME);
-		}
-
-		/* Notification Hang runs on all cpus simultaneously */
-		if (selected_tests & TEST_NOTIFY) {
-			some_tests_removed = 1;
-			selected_tests &= ~(TEST_NOTIFY);
-		}
-
-		/* Invalid Tests */
-		if (selected_tests & TEST_NONODE) {
-			some_tests_removed = 1;
-			selected_tests &= ~(TEST_NONODE);
-		}
-
-		if (some_tests_removed) {
-			printk("Test Buffers were not allocated.\n");
-			printk("Please reboot the system and supply "
-			       "the \"btetest\" kernel flag\n");
-			printk("Some tests were removed.\n");
-		}
-	}
-
-	brt_marker();
-
-	printk("brt_test(): Starting.\n");
-
-	if (selected_tests & TEST_REGRESSION) {
-		if (brt_tst_std_xfer()) {
-			printk("Standard Transfers had errors.\n");
-		}
-
-	}
-
-	if (selected_tests & TEST_TIME) {
-		if (tm_min_lines < 0) {
-			tm_min_lines = 0;
-		}
-		if (tm_max_lines < 0) {
-			tm_max_lines = 0;
-		}
-
-		if (tm_max_lines > BTE_LEN_MASK) {
-			tm_max_lines = BTE_LEN_MASK;
-		}
-		if (tm_min_lines > tm_max_lines) {
-			tm_min_lines = tm_max_lines;
-		}
-
-		if (brt_tst_time_xfers()) {
-			printk("Timed transfers had errors.\n");
-		}
-
-	}
-
-	if (selected_tests & TEST_NOTIFY) {
-		if (hang_usec < 8) {
-			hang_usec = 8;
-		}
-		if (hang_usec > 256) {
-			hang_usec = 256;
-		}
-
-		if (brt_tst_notify_hang()) {
-			printk("Notification Hang test had errors.\n");
-		}
-	}
-
-	if (selected_tests & TEST_NONODE) {
-		if (brt_tst_invalid_xfers()) {
-			printk("Invalid Nasid test had errors.\n");
-		}
-	}
-
-	return (1);		/* Prevent module load. */
-}
-
-
-static void __exit
-brt_test_exit(void)
-{
-}
-
-
-/***********************************************************************
- * Standard Transfer Test.
- *	
- *	This test has a table of transfers defined above.  For each
- *	transfer, it calls bte_unaligned_copy.  It compares the actual
- *	result with the expected result.  If they differ, it prints out
- *	information about the transfer and hex dumps the actual block
- *
- **********************************************************************/
-
-
-/*
- * Allocate the needed buffers and then initiate each xfer specified
- * by brt_xfer_tests.
- */
-static int
-brt_tst_std_xfer(void)
-{
-	char *block_1;
-	char *block_2;
-	int iteration = 0;
-	brt_xfer_entry_t *cur_test;
-	int cpu;
-	int err_cnt;
-
-	block_1 = kmalloc(BRT_TEST_BLOCK_SIZE, GFP_KERNEL);
-	ASSERT(!((u64) block_1 & L1_CACHE_MASK));
-	block_2 = kmalloc(BRT_TEST_BLOCK_SIZE, GFP_KERNEL);
-	ASSERT(!((u64) block_2 & L1_CACHE_MASK));
-
-	cur_test = brt_xfer_tests;
-
-	err_cnt = 0;
-	while (cur_test->length) {
-		for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-			set_cpus_allowed(current, (1UL << cpu));
-
-			if (verbose > 1) {
-				printk("Cpu %d Transfering %d from "
-				       "%d to %d.\n",
-				       smp_processor_id(),
-				       cur_test->length,
-				       cur_test->source_offset,
-				       cur_test->dest_offset);
-			}
-
-			err_cnt += brt_std_xfer(block_1, block_2,
-						cur_test->source_offset,
-						cur_test->dest_offset,
-						cur_test->length,
-						++iteration);
-
-		}
-		cur_test++;
-	}
-
-	kfree(block_2);
-	kfree(block_1);
-
-	return ((err_cnt ? 1 : 0));
-}
-
-
-/*
- * Perform a single transfer and ensure the result matches
- * the expected.  Returns the number of differences found.
- *
- * Testing is performed by setting the source buffer to a
- * known value, and zeroing out the destination.
- *
- * After the copy, if the destination has only the known
- * source values at the correct place, we know we had a
- * good transfer.
- *
- */
-static int
-brt_std_xfer(char *src, char *dst,
-	     int src_offset, int dst_offset, int len,
-	     int magic)
-{
-	int i, ret;
-	int err_cnt = 0;
-
-	if (verbose > 3) {
-		printk("brt_test(src=0x%lx, dst=0x%lx, src_offset=%d, "
-		       "dst_offset=%d, len=%d, magic=%d\n",
-		       (u64) src, (u64) dst, src_offset,
-		       dst_offset, len, magic);
-	}
-
-	memset(src, ((magic + 1) & 0xff), BRT_TEST_BLOCK_SIZE);
-	memset((src + src_offset), magic, len);
-	if (verbose > 8) {
-		printk("Before transfer: Source is\n");
-		brt_hex_dump(src, BRT_TEST_BLOCK_SIZE);
-	}
-	memset(dst, 0, BRT_TEST_BLOCK_SIZE);
-	if (verbose > 8) {
-		printk("Before transfer: dest is\n");
-		brt_hex_dump(dst, BRT_TEST_BLOCK_SIZE);
-	}
-
-	ret = BTE_UNALIGNED_COPY(__pa(src + src_offset),
-				 __pa(dst + dst_offset),
-				 len, BTE_NOTIFY);
-	if (ret != BTE_SUCCESS) {
-		printk("brt_test: BTE_UNALIGNED_COPY() error: %d\n", ret);
-		return (1);
-	}
-
-	/* Check head */
-	for (i = 0; i < dst_offset; i++) {
-		if ((dst[i] & 0xff) != 0) {
-			err_cnt++;
-		}
-	}
-	/* Check body */
-	for (i = 0; i < len; i++) {
-		if ((dst[dst_offset + i] & 0xff) != (magic & 0xff)) {
-			err_cnt++;
-		}
-	}
-	/* Check foot */
-	for (i = (dst_offset + len); i < BRT_TEST_BLOCK_SIZE; i++) {
-		if ((dst[i] & 0xff) != 0) {
-			err_cnt++;
-		}
-	}
-
-	if ((verbose > 3) || err_cnt) {
-		printk("brt_test: %d errors during basic "
-		       "transfer test.\n", err_cnt);
-		brt_hex_dump(dst, BRT_TEST_BLOCK_SIZE);
-	}
-
-	return (err_cnt);
-}
-
-
-/*
- * Dump a block of data to console as hex.
- */
-static void
-brt_hex_dump(char *block_to_dump, int block_len)
-{
-	int i;
-	char fmt_line[128];
-	char *fmt_eol = fmt_line;
-
-	for (i = 0; i < block_len; i++) {
-		if (!(i % 16)) {
-			if (i > 0) {
-				printk("%s\n", fmt_line);
-			}
-			sprintf(fmt_line, "0x%lx %05d ",
-				__pa(&block_to_dump[i]), i);
-			fmt_eol = fmt_line;
-		}
-		while (*fmt_eol++) {	/* empty */
-		};
-		fmt_eol--;
-		sprintf(fmt_eol, "%s%02x",
-			(!(i % 4) ? " " : ""), (block_to_dump[i] & 0xff));
-	}
-	printk("%s\n", fmt_line);
-}
-
-
-/***********************************************************************
- * Transfer Rate Test.
- * 
- *	This test migrates to each cpu one at a time.  This is done to
- *	get a complete view of how each of the bte engines is performing
- *	and help ensure that each virtual interface is being used.
- *	NOTE: All virtual interfaces will not necessarily be used.
- *
- *	Now that we have migrated to the desired cpu, we transfer from
- *	our node to all the other nodes (including ourself).  We
- *	accomplish this with both a memcpy and a bte_copy.  Timings
- *	for both are printed.
- *
- **********************************************************************/
-
-
-#define NSEC(x) ((x) * (1000000000UL / local_cpu_data->itc_freq))
-
-
-/*
- * Migrate to each cpu. When on the desired cpu, time transfers to
- * each node by calling brt_time_xfer.
- */
-static int
-brt_tst_time_xfers(void)
-{
-	int tst_cpu;
-	int dest_node;
-	int xfer_lines;
-	int i;
-
-	if (tm_memcpy) {
-		printk("Cpu,Src,Dst,Lines,Stup,Transfr,Fin,Execute,"
-		       "Overall,Memcpy\n");
-	} else {
-		printk("Cpu,Src,Dst,Lines,Stup,Transfr,Fin,Execute,"
-		       "Overall\n");
-	}
-
-	if (tm_alternate) {
-		/* Now transfer from this node to all the others. */
-		for (dest_node = 0; dest_node < numnodes; dest_node++) {
-			for (xfer_lines = tm_min_lines;
-			     xfer_lines <= tm_max_lines;) {
-
-				for (i = 0; i < tm_iterations; i++) {
-					for (tst_cpu = 0;
-					     tst_cpu < smp_num_cpus;
-					     tst_cpu++) {
-						/* Move to the desired CPU. */
-						set_cpus_allowed(current,
-						    (1UL << tst_cpu));
-
-						brt_time_xfer(dest_node,
-							      1,
-							      xfer_lines);
-
-					}
-				}
-				/* Handle a min of 0 */
-				if (xfer_lines < 1) {
-					xfer_lines = 1;
-				} else {
-					xfer_lines *= 2;
-				}
-			}
-		}
-	} else {
-		for (tst_cpu = 0; tst_cpu < smp_num_cpus; tst_cpu++) {
-			/* Move to the desired CPU. */
-			set_cpus_allowed(current, (1UL << tst_cpu));
-
-			/* Now transfer from this node to all the others. */
-			for (dest_node = 0; dest_node < numnodes;
-			     dest_node++) {
-				for (xfer_lines = tm_min_lines;
-				     xfer_lines <= tm_max_lines;) {
-
-					brt_time_xfer(dest_node,
-						      tm_iterations,
-						      xfer_lines);
-
-					/* Handle a min of 0 */
-					if (xfer_lines < 1) {
-						xfer_lines = 1;
-					} else {
-						xfer_lines *= 2;
-					}
-				}
-			}
-		}
-	}
-	return (0);
-}
-
-
-/*
- * Transfer the bte_test_buffer from our node to the specified
- * destination and print out timing results.
- */
-static void
-brt_time_xfer(int dest_node, int iterations, int xfer_lines)
-{
-	int iteration;
-	char *src, *dst;
-	u64 xfer_len, src_phys, dst_phys;
-	u64 itc_before, itc_after, mem_intvl, bte_intvl;
-
-
-	xfer_len = xfer_lines * L1_CACHE_BYTES;
-
-	src = nodepda->bte_if[0].bte_test_buf;
-	src_phys = __pa(src);
-	dst = NODEPDA(dest_node)->bte_if[1].bte_test_buf;
-	dst_phys = __pa(dst);
-	mem_intvl = 0;
-
-	for (iteration = 0; iteration < iterations; iteration++) {
-		if (tm_memcpy) {
-			itc_before = ia64_get_itc();
-			memcpy(dst, src, xfer_len);
-			itc_after = ia64_get_itc();
-			mem_intvl = itc_after - itc_before;
-		}
-
-		itc_before = ia64_get_itc();
-		bte_copy(src_phys, dst_phys, xfer_len, BTE_NOTIFY, NULL);
-		itc_after = ia64_get_itc();
-		bte_intvl = itc_after - itc_before;
-
-		if (tm_memcpy) {
-			printk("%3d,%3d,%3d,%5d,%4ld,%7ld,%3ld,"
-			       "%7ld,%7ld,%7ld\n",
-			       smp_processor_id(), NASID_GET(src),
-			       NASID_GET(dst), xfer_lines,
-			       NSEC(bte_setup_time),
-			       NSEC(bte_transfer_time),
-			       NSEC(bte_tear_down_time),
-			       NSEC(bte_execute_time), NSEC(bte_intvl),
-			       NSEC(mem_intvl));
-		} else {
-			printk("%3d,%3d,%3d,%5d,%4ld,%7ld,%3ld,"
-			       "%7ld,%7ld\n",
-			       smp_processor_id(), NASID_GET(src),
-			       NASID_GET(dst), xfer_lines,
-			       NSEC(bte_setup_time),
-			       NSEC(bte_transfer_time),
-			       NSEC(bte_tear_down_time),
-			       NSEC(bte_execute_time), NSEC(bte_intvl));
-		}
-	}
-
-}
-
-
-/***********************************************************************
- * Notification Hang Test. -- NOTE: Has never actually caused a hang.
- *
- *	The next set of code checks to see if the Notification Hang
- *	occurs.  It does this by starting one thread per cpu, pinning
- *	the thread to its assigned cpu.  After it is pinned, we lock
- *	the associated bte.  Source, Dest, and Notification are
- *	assigned.
- *
- *	Inside of a loop, we set the length and trigger the
- *	transfer. We use the ITC to determine when the transfer should
- *	complete. Whenever the IBLS_BUSY bit is cleared, the transfer
- *	has completed. We occasionally call schedule (Since all CPUs
- *	have a pinned process The machine will be doing nothing but
- *	out tranfers) and loop.
- *
- *	If twice max normal time has passed without seeing the
- *	notification, we check the Length/Status register to see if
- *	IBLS_BUSY is still asserted and length is zero.  This is an
- *	indication of the hang.
- *
- **********************************************************************/
-
-
-/*
- * Launch one thread per cpu.  When all threads are started, sleep
- * the specified timeout and then notify the other threads that it
- * is time to exit.
- */
-static int
-brt_tst_notify_hang(void)
-{
-	int tst_cpu;
-
-	printk("Waiting %d seconds to complete test.\n", hang_timeout);
-
-	atomic_set(&brt_thread_cnt, 0);
-	brt_exit_flag = 0;
-
-	for (tst_cpu = 0; tst_cpu < smp_num_cpus; tst_cpu++) {
-		if ((kernel_thread(brt_notify_thrd,
-				   (void *)(long)tst_cpu, 0)) < 0) {
-			printk("Failed to start thread.\n");
-		}
-	}
-
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(hang_timeout * HZ);
-	set_current_state(TASK_RUNNING);
-
-	printk("Flagging an exit.\n");
-	brt_exit_flag = 1;
-
-	while (atomic_read(&brt_thread_cnt)) {
-		/* Wait until everyone else is done. */
-		schedule();
-	}
-
-	printk("All threads have exited.\n");
-	return (0);
-}
-
-
-/*
- * One of these threads is started per cpu.  Each thread is responsible
- * for loading that cpu's bte interface and then writing to the
- * test buffer.  The transfers are set in a round-robin fashion.
- * The end result is that each test buffer is being written into
- * by the previous node and both cpu's at the same time as the
- * local bte is transferring it to the next node.
- */
-static int
-brt_notify_thrd(void *__bind_cpu)
-{
-	int bind_cpu = (long int)__bind_cpu;
-	int cpu = cpu_logical_map(bind_cpu);
-	nodepda_t *nxt_node;
-	long tmout_itc_intvls;
-	long tmout;
-	long passes;
-	long good_xfer_cnt;
-	u64 src_phys, dst_phys;
-	int i;
-	volatile char *src_buf;
-	u64 *notify;
-
-	atomic_inc(&brt_thread_cnt);
-	daemonize();
-	set_user_nice(current, 19);
-	sigfillset(&current->blocked);
-
-	/* Migrate to the right CPU */
-	set_cpus_allowed(current, 1UL << cpu);
-
-	/* Calculate the uSec timeout itc offset. */
-	tmout_itc_intvls = local_cpu_data->cyc_per_usec * hang_usec;
-
-	if (local_cnodeid() == (numnodes - 1)) {
-		nxt_node = NODEPDA(0);
-	} else {
-		nxt_node = NODEPDA(local_cnodeid() + 1);
-	}
-
-	src_buf = nodepda->bte_if[0].bte_test_buf;
-	src_phys = __pa(src_buf);
-	dst_phys = __pa(nxt_node->bte_if[0].bte_test_buf);
-
-	notify = kmalloc(L1_CACHE_BYTES, GFP_KERNEL);
-	ASSERT(!((u64) notify & L1_CACHE_MASK));
-
-	printk("BTE Hang %d xfer 0x%lx -> 0x%lx, Notify=0x%lx\n",
-	       smp_processor_id(), src_phys, dst_phys, (u64) notify);
-
-	passes = 0;
-	good_xfer_cnt = 0;
-
-	/* Loop until signalled to exit. */
-	while (!brt_exit_flag) {
-		/*
-		 * A hang will prevent further transfers.
-		 * NOTE: Sometimes, it appears like a hang occurred and
-		 * then transfers begin again.  This just means that
-		 * there is NUMA congestion and the hang_usec param
-		 * should be increased.
-		 */
-		if (!(*notify & IBLS_BUSY)) {
-			if ((bte_copy(src_phys,
-				      dst_phys,
-				      4UL * L1_CACHE_BYTES,
-				      BTE_NOTIFY,
-				      (void *)notify)) != BTE_SUCCESS) {
-				printk("<0>Cpu %d Could not "
-				       "allocate a bte.\n",
-				       smp_processor_id());
-				continue;
-			}
-
-			tmout = ia64_get_itc() + tmout_itc_intvls;
-
-			while ((*notify & IBLS_BUSY) &&
-			       (ia64_get_itc() < tmout)) {
-
-
-				/* Push data out with the processor. */
-				for (i = 0; i < (4 * L1_CACHE_BYTES);
-				     i += L1_CACHE_BYTES) {
-					src_buf[i] = (passes % 128);
-				}
-			};
-
-			if (*notify & IBLS_BUSY) {
-				printk("<0>Cpu %d BTE appears to have "
-				       "hung.\n", smp_processor_id());
-			} else {
-				good_xfer_cnt++;
-			}
-		}
-
-		/* Every x passes, take a little break. */
-		if (!(++passes % 40)) {
-			passes = 0;
-			schedule_timeout(0.01 * HZ);
-		}
-	}
-
-	kfree(notify);
-
-	printk("Cpu %d had %ld good passes\n",
-	       smp_processor_id(), good_xfer_cnt);
-
-	atomic_dec(&brt_thread_cnt);
-	return (0);
-}
-
-
-/***********************************************************************
- * Invalid Transfer Test.
- * 
- *	Just transfer from the local node to a nasid which does not
- *	exist.
- *
- *	>>> Potential Problem: on SN1, HUB interrupt doesn't always
- *	occurr.
- *
- **********************************************************************/
-
-
-/*
- * Locate a nasid which doesn't exist.  Perform a bte_copy from that
- * node to our local node.
- */
-static int
-brt_tst_invalid_xfers(void)
-{
-	int i;
-	int free_nasid = -1;
-	int cpu;
-	int error_cnt;
-
-	u64 ret_code;
-
-	if (ix_srcnasid != -1) {
-		free_nasid = ix_srcnasid;
-	} else {
-		/* Only looking for nasids from C-Nodes. */
-		for (i = 0; i < PLAT_MAX_NODE_NUMBER; i += 2) {
-			if (local_node_data->physical_node_map[i] == -1) {
-				free_nasid = i;
-				break;
-			}
-		}
-	}
-
-	if (free_nasid == -1) {
-		printk("tst_invalid_xfers: No free nodes found. "
-		       "Exiting.\n");
-		return (0);
-	}
-
-	printk("tst_invalid_xfers: Using source nasid of %d\n",
-	       free_nasid);
-
-	error_cnt = 0;
-
-	for (i = 0; i < ix_iterations; i++) {
-		if (verbose >= 1) {
-			printk("-------------------------------"
-			       "-------------------------------"
-			       "--------------\n");
-		}
-		if ((verbose >= 1) || !(i % 10)) {
-			printk("  Loop %d\n", i);
-		}
-
-		for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-			set_cpus_allowed(current, (1UL << cpu));
-
-			if (verbose > 1) {
-				printk("Testing with CPU %d\n",
-				       smp_processor_id());
-			}
-
-			/* >>> Need a better means of calculating a
-			 * remote addr. */
-			ret_code = bte_copy(TO_NODE(free_nasid, 0),
-					    __pa(nodepda->bte_if[0].
-						 bte_test_buf),
-					    4 * L1_CACHE_BYTES,
-					    BTE_NOTIFY,
-					    NULL);
-			error_cnt += (ret_code ? 1 : 0);
-		}
-	}
-
-	ret_code = ((error_cnt != (ix_iterations * smp_num_cpus)) ?
-		    1 : 0);
-	return (ret_code);
-}
-
-
-/***********************************************************************
- * Kernel command line handler.
- * 
- **********************************************************************/
-
-
-#if !defined(MODULE)
-static int __init
-brt_setup(char *str)
-{
-	int cur_val;
-
-	if (get_option(&str, &cur_val)) {
-		selected_tests = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		verbose = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		hang_timeout = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		hang_usec = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		tm_min_lines = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		tm_max_lines = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		tm_iterations = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		tm_alternate = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		tm_memcpy = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		ix_iterations = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		ix_srcnasid = cur_val;
-	}
-
-	return (1);
-}
-#endif				/* !defined(MODULE) */
-
-
-/***********************************************************************
- * Module parameters.
- *	
- *	The two supported cases are loadable module parms and kernel
- *	command line support.
- *	
- *	The loadable module options are specified below in the
- *	MODULE_PARM macros and have associated descriptions.
- *	
- *	The kernel command line option is btetest=x[,y[,z]] etc.  The
- *	individual setting order is constant.  NOTE: The btetest flag
- *	is checked for in the bte_init_node function.
- *	
- **********************************************************************/
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Silicon Graphics, Inc.");
-MODULE_DESCRIPTION("Test the Block Transfer Engine(BTE) "
-		   "present on SGI machines.");
-
-MODULE_PARM(selected_tests, "1i");
-MODULE_PARM_DESC(selected_tests, "Bitmask of tests to run.");
-
-MODULE_PARM(verbose, "1i");
-MODULE_PARM_DESC(verbose,
-		 "How much information should be "
-		 "printed during the tests.");
-
-MODULE_PARM(hang_timeout, "1i");
-MODULE_PARM_DESC(hang_timeout,
-		 "Number of seconds to wait for the Bte "
-		 "Notification Failure.");
-
-MODULE_PARM(hang_usec, "1i");
-MODULE_PARM_DESC(hang_usec,
-		 "Number of micro-seconds to wait for the 4-line Bte "
-		 "transfer to complete.");
-
-MODULE_PARM(tm_min_lines, "1i");
-MODULE_PARM_DESC(tm_min_lines, "Minimum number of cache lines"
-		 " to time with.");
-
-MODULE_PARM(tm_max_lines, "1i");
-MODULE_PARM_DESC(tm_max_lines, "Maximum number of cache lines"
-		 " to time with.");
-
-MODULE_PARM(tm_iterations, "1i");
-MODULE_PARM_DESC(tm_iterations, "Rerun each timed transfer this "
-		 "many times.");
-
-MODULE_PARM(tm_alternate, "1i");
-MODULE_PARM_DESC(tm_alternate, "Cycle across cpus between each "
-		 "iteration");
-
-MODULE_PARM(tm_memcpy, "1i");
-MODULE_PARM_DESC(tm_memcpy, "Use memcpy as a comparison to BTE");
-
-MODULE_PARM(ix_iterations, "1i");
-MODULE_PARM_DESC(ix_iterations, "Rerun each transfer from an "
-		 "invalid nasid this many times.");
-
-MODULE_PARM(ix_srcnasid, "1i");
-MODULE_PARM_DESC(ix_srcnasid, "Nasid to attempt xfer from.");
-
-
-#if !defined(MODULE)
-__setup("btetest=", brt_setup);
-#endif				/* !defined(MODULE) */
-
-
-module_init(brt_test_init);
-module_exit(brt_test_exit);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/idle.c linux-2.4.22-pre3/arch/ia64/sn/kernel/idle.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/idle.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/idle.c	2003-07-05 18:09:45.000000000 -0700
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <asm/sn/leds.h>
+#include <asm/sn/simulator.h>
+
+void snidle(int state) {
+	if (state) {
+		if (pda.idle_flag == 0) {
+			/* 
+			 * Turn the activity LED off.
+			 */
+			set_led_bits(0, LED_CPU_ACTIVITY);
+		}
+
+#ifdef CONFIG_IA64_SGI_SN_SIM
+		if (IS_RUNNING_ON_SIMULATOR())
+			SIMULATOR_SLEEP();
+#endif
+
+		pda.idle_flag = 1;
+	} else {
+		/* 
+		 * Turn the activity LED on.
+		 */
+		set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY);
+
+		pda.idle_flag = 0;
+	}
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/iomv.c linux-2.4.22-pre3/arch/ia64/sn/kernel/iomv.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/iomv.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/iomv.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,115 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <asm/io.h>
-#include <linux/module.h>
-
-extern void * sn_io_addr(unsigned long port); /* defined in sn[12]/iomv.c */
-
-/**
- * sn_inb - read a byte from a port
- * @port: port to read from
- *
- * Reads a byte from @port and returns it to the caller.
- */
-unsigned int
-sn_inb (unsigned long port)
-{
-	volatile unsigned char *addr = sn_io_addr(port);
-	unsigned char ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-/**
- * sn_inw - read a word from a port
- * @port: port to read from
- *
- * Reads a word from @port and returns it to the caller.
- */
-unsigned int
-sn_inw (unsigned long port)
-{
-	volatile unsigned short *addr = sn_io_addr(port);
-	unsigned short ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-/**
- * sn_inl - read a word from a port
- * @port: port to read from
- *
- * Reads a word from @port and returns it to the caller.
- */
-unsigned int
-sn_inl (unsigned long port)
-{
-	volatile unsigned int *addr = sn_io_addr(port);
-	unsigned int ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-/**
- * sn_outb - write a byte to a port
- * @port: port to write to
- * @val: value to write
- *
- * Writes @val to @port.
- */
-void
-sn_outb (unsigned char val, unsigned long port)
-{
-	volatile unsigned char *addr = sn_io_addr(port);
-
-	*addr = val;
-}
-
-/**
- * sn_outw - write a word to a port
- * @port: port to write to
- * @val: value to write
- *
- * Writes @val to @port.
- */
-void
-sn_outw (unsigned short val, unsigned long port)
-{
-	volatile unsigned short *addr = sn_io_addr(port);
-
-	*addr = val;
-}
-
-/**
- * sn_outl - write a word to a port
- * @port: port to write to
- * @val: value to write
- *
- * Writes @val to @port.
- */
-void
-sn_outl (unsigned int val, unsigned long port)
-{
-	volatile unsigned int *addr = sn_io_addr(port);
-
-	*addr = val;
-}
-
-EXPORT_SYMBOL(sn_inb);
-EXPORT_SYMBOL(sn_inw);
-EXPORT_SYMBOL(sn_inl);
-EXPORT_SYMBOL(sn_outb);
-EXPORT_SYMBOL(sn_outw);
-EXPORT_SYMBOL(sn_outl);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/irq.c linux-2.4.22-pre3/arch/ia64/sn/kernel/irq.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/irq.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/irq.c	2003-07-05 18:09:46.000000000 -0700
@@ -1,7 +1,7 @@
 /*
- * Platform dependent support for SGI SN1
+ * Platform dependent support for SGI SN
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -32,12 +32,13 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/vmalloc.h>
 #include <asm/current.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/sn/sgi.h>
@@ -49,18 +50,23 @@
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/pci/pciio.h>
 #include <asm/sn/pci/pciio_private.h>
-#ifdef ajmtestintr
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/pci/pcibr_private.h>
-#endif /* ajmtestintr */
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/io.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/driver.h>
 #include <asm/sn/arch.h>
+#include <asm/sn/pda.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
 
 int irq_to_bit_pos(int irq);
+static void force_interrupt(int irq);
+extern void pcibr_force_interrupt(pcibr_intr_t intr);
+extern int sn_force_interrupt_flag;
 
 
 
@@ -88,49 +94,11 @@
 static void
 sn_ack_irq(unsigned int irq)
 {
-#ifdef CONFIG_IA64_SGI_SN1
-	int bit = -1;
-	unsigned long long intpend_val;
-	int subnode;
-#endif
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long event_occurred, mask = 0;
-#endif
 	int nasid;
 
 	irq = irq & 0xff;
 	nasid = smp_physical_node_id();
-#ifdef CONFIG_IA64_SGI_SN1
-	subnode = cpuid_to_subnode(smp_processor_id());
-	if (irq == SGI_UART_IRQ) {
-		intpend_val = REMOTE_HUB_PI_L(nasid, subnode, PI_INT_PEND0);
-		if (intpend_val & (1L<<GFX_INTR_A) ) {
-			bit = GFX_INTR_A;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if ( intpend_val & (1L<<GFX_INTR_B) ) {
-			bit = GFX_INTR_B;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if (intpend_val & (1L<<PG_MIG_INTR) ) {
-			bit = PG_MIG_INTR;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if (intpend_val & (1L<<CC_PEND_A)) {
-			bit = CC_PEND_A;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if (intpend_val & (1L<<CC_PEND_B)) {
-			bit = CC_PEND_B;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		return;
-	}
-	bit = irq_to_bit_pos(irq);
-	REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN2
 	event_occurred = HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid,SH_EVENT_OCCURRED) );
 	if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) {
 		mask |= (1 << SH_EVENT_OCCURRED_UART_INT_SHFT);
@@ -145,34 +113,18 @@
 		mask |= (1 << SH_EVENT_OCCURRED_II_INT1_SHFT);
 	}
 	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED_ALIAS), mask );
-#endif
+	__set_bit(irq, (volatile void *)pda.sn_in_service_ivecs);
 }
 
 static void
 sn_end_irq(unsigned int irq)
 {
-#ifdef CONFIG_IA64_SGI_SN1
-	unsigned long long intpend_val, mask = 0x70L;
-	int subnode;
-#endif
 	int nasid;
-#ifdef CONFIG_IA64_SGI_SN2
+	int ivec;
 	unsigned long event_occurred;
-#endif
 
-	irq = irq & 0xff;
-#ifdef CONFIG_IA64_SGI_SN1
-	if (irq == SGI_UART_IRQ) {
-		nasid = smp_physical_node_id();
-		subnode = cpuid_to_subnode(smp_processor_id());
-		intpend_val = REMOTE_HUB_PI_L(nasid, subnode, PI_INT_PEND0);
-		if (intpend_val & mask) {
-			platform_send_ipi(smp_processor_id(), SGI_UART_IRQ, IA64_IPI_DM_INT, 0);
-		}
-	}
-#endif
-#ifdef CONFIG_IA64_SGI_SN2
-	if (irq == SGI_UART_VECTOR) {
+	ivec = irq & 0xff;
+	if (ivec == SGI_UART_VECTOR) {
 		nasid = smp_physical_node_id();
 		event_occurred = HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid,SH_EVENT_OCCURRED) );
 		// If the UART bit is set here, we may have received an interrupt from the
@@ -182,8 +134,9 @@
 				platform_send_ipi(smp_processor_id(), SGI_UART_VECTOR, IA64_IPI_DM_INT, 0);
 		}
 	}
-#endif
-
+	__clear_bit(ivec, (volatile void *)pda.sn_in_service_ivecs);
+	if (sn_force_interrupt_flag)
+		force_interrupt(irq);
 }
 
 static void
@@ -192,7 +145,7 @@
 }
 
 
-struct hw_interrupt_type irq_type_iosapic_level = {
+struct hw_interrupt_type irq_type_sn = {
 	"SN hub",
 	sn_startup_irq,
 	sn_shutdown_irq,
@@ -204,21 +157,17 @@
 };
 
 
-#define irq_type_sn irq_type_iosapic_level
-struct irq_desc *_sn_irq_desc[NR_CPUS];
-
 struct irq_desc *
 sn_irq_desc(unsigned int irq) {
-	int cpu = irq >> 8;
 
-	irq = irq & 0xff;
+	irq = SN_IVEC_FROM_IRQ(irq);
 
-	return(_sn_irq_desc[cpu] + irq);
+	return(_irq_desc + irq);
 }
 
 u8
 sn_irq_to_vector(u8 irq) {
-	return(irq & 0xff);
+	return(irq);
 }
 
 unsigned int
@@ -226,47 +175,24 @@
 	return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector));
 }
 
-void *kmalloc(size_t, int);
-
 void
 sn_irq_init (void)
 {
 	int i;
 	irq_desc_t *base_desc = _irq_desc;
 
-	for (i=IA64_FIRST_DEVICE_VECTOR; i<NR_IVECS; i++) {
+	for (i=IA64_FIRST_DEVICE_VECTOR; i<NR_IRQS; i++) {
 		if (base_desc[i].handler == &no_irq_type) {
 			base_desc[i].handler = &irq_type_sn;
 		}
 	}
 }
 
-void
-sn_init_irq_desc(void) {
-	int i;
-	irq_desc_t *base_desc = _irq_desc, *p;
-
-	for (i=0; i < NR_CPUS; i++) {
-		p =  page_address(alloc_pages_node(local_cnodeid(), GFP_KERNEL,
-			get_order(sizeof(struct irq_desc) * NR_IVECS) ) );
-		ASSERT(p);
-		memcpy(p, base_desc, sizeof(struct irq_desc) * NR_IVECS);
-		_sn_irq_desc[i] = p;
-	}
-}
-
-
 int
 bit_pos_to_irq(int bit) {
 #define BIT_TO_IRQ 64
 	if (bit > 118) bit = 118;
 
-#ifdef CONFIG_IA64_SGI_SN1
-	if (bit >= GFX_INTR_A && bit <= CC_PEND_B) {
-		return SGI_UART_IRQ;
-	}
-#endif
-
         return bit + BIT_TO_IRQ;
 }
 
@@ -278,53 +204,183 @@
         return bit;
 }
 
-#ifdef ajmtestintr
-
-#include <linux/timer.h>
-struct timer_list intr_test_timer;
-int intr_test_icount[NR_IRQS];
-struct intr_test_reg_struct {
-	pcibr_soft_t pcibr_soft;
-	int slot;
+struct pcibr_intr_list_t {
+	struct pcibr_intr_list_t *next;
+	pcibr_intr_t intr;
 };
-struct intr_test_reg_struct intr_test_registered[NR_IRQS];
+
+static struct pcibr_intr_list_t **pcibr_intr_list;
 
 void
-intr_test_handle_timer(unsigned long data) {
+register_pcibr_intr(int irq, pcibr_intr_t intr) {
+	struct pcibr_intr_list_t *p = kmalloc(sizeof(struct pcibr_intr_list_t), GFP_KERNEL);
+	struct pcibr_intr_list_t *list;
+	int cpu = SN_CPU_FROM_IRQ(irq);
+
+	if (pcibr_intr_list == NULL) {
+		pcibr_intr_list = kmalloc(sizeof(struct pcibr_intr_list_t *) * NR_IRQS, GFP_KERNEL);
+		if (pcibr_intr_list == NULL) 
+			pcibr_intr_list = vmalloc(sizeof(struct pcibr_intr_list_t *) * NR_IRQS);
+		if (pcibr_intr_list == NULL) panic("Could not allocate memory for pcibr_intr_list\n");
+		memset( (void *)pcibr_intr_list, 0, sizeof(struct pcibr_intr_list_t *) * NR_IRQS);
+	}
+	if (pdacpu(cpu).sn_last_irq < irq) {
+		pdacpu(cpu).sn_last_irq = irq;
+	}
+	if (pdacpu(cpu).sn_first_irq > irq) pdacpu(cpu).sn_first_irq = irq;
+	if (!p) panic("Could not allocate memory for pcibr_intr_list_t\n");
+	if ((list = pcibr_intr_list[irq])) {
+		while (list->next) list = list->next;
+		list->next = p;
+		p->next = NULL;
+		p->intr = intr;
+	} else {
+		pcibr_intr_list[irq] = p;
+		p->next = NULL;
+		p->intr = intr;
+	}
+}
+
+void
+force_polled_int(void) {
 	int i;
-	bridge_t	*bridge;
+	struct pcibr_intr_list_t *p;
 
-	for (i=0;i<NR_IRQS;i++) {
-		if (intr_test_registered[i].pcibr_soft) {
-			pcibr_soft_t pcibr_soft = intr_test_registered[i].pcibr_soft;
-			xtalk_intr_t intr = pcibr_soft->bs_intr[intr_test_registered[i].slot].bsi_xtalk_intr;
-			/* send interrupt */
-			bridge = pcibr_soft->bs_base;
-			bridge->b_force_always[intr_test_registered[i].slot].intr = 1;
+	for (i=0; i<NR_IRQS;i++) {
+		p = pcibr_intr_list[i];
+		while (p) {
+			if (p->intr){
+				pcibr_force_interrupt(p->intr);
+			}
+			p = p->next;
 		}
 	}
-	del_timer(&intr_test_timer);
-	intr_test_timer.expires = jiffies + HZ/100;
-	add_timer(&intr_test_timer);
 }
 
-void
-intr_test_set_timer(void) {
-	intr_test_timer.expires = jiffies + HZ/100;
-	intr_test_timer.function = intr_test_handle_timer;
-	add_timer(&intr_test_timer);
+static void
+force_interrupt(int irq) {
+	struct pcibr_intr_list_t *p = pcibr_intr_list[irq];
+
+	while (p) {
+		if (p->intr) {
+			pcibr_force_interrupt(p->intr);
+		}
+		p = p->next;
+	}
+}
+
+/*
+Check for lost interrupts.  If the PIC int_status reg. says that
+an interrupt has been sent, but not handled, and the interrupt
+is not pending in either the cpu irr regs or in the soft irr regs,
+and the interrupt is not in service, then the interrupt may have
+been lost.  Force an interrupt on that pin.  It is possible that
+the interrupt is in flight, so we may generate a spurious interrupt,
+but we should never miss a real lost interrupt.
+*/
+
+static void
+sn_check_intr(int irq, pcibr_intr_t intr) {
+	unsigned long regval;
+	int irr_reg_num;
+	int irr_bit;
+	unsigned long irr_reg;
+
+
+	regval = intr->bi_soft->bs_base->p_int_status_64;
+	irr_reg_num = irq_to_vector(irq) / 64;
+	irr_bit = irq_to_vector(irq) % 64;
+	switch (irr_reg_num) {
+		case 0:
+			irr_reg = ia64_get_irr0();
+			break;
+		case 1:
+			irr_reg = ia64_get_irr1();
+			break;
+		case 2:
+			irr_reg = ia64_get_irr2();
+			break;
+		case 3:
+			irr_reg = ia64_get_irr3();
+			break;
+	}
+	if (!test_bit(irr_bit, &irr_reg) ) {
+		if (!test_bit(irq, pda.sn_soft_irr) ) {
+			if (!test_bit(irq, pda.sn_in_service_ivecs) ) {
+				regval &= 0xff;
+				if (intr->bi_ibits & regval & intr->bi_last_intr) {
+					regval &= ~(intr->bi_ibits & regval);
+					pcibr_force_interrupt(intr);
+				}
+			}
+		}
+	}
+	intr->bi_last_intr = regval;
 }
 
 void
-intr_test_register_irq(int irq, pcibr_soft_t pcibr_soft, int slot) {
-	irq = irq & 0xff;
-	intr_test_registered[irq].pcibr_soft = pcibr_soft;
-	intr_test_registered[irq].slot = slot;
+sn_lb_int_war_check(void) {
+	int i;
+
+	if (pda.sn_first_irq == 0) return;
+	for (i=pda.sn_first_irq;
+		i <= pda.sn_last_irq; i++) {
+			struct pcibr_intr_list_t *p = pcibr_intr_list[i];
+			if (p == NULL) {
+				continue;
+			}
+			while (p) {
+				sn_check_intr(i, p->intr);
+				p = p->next;
+			}
+	}
+}
+
+static inline int
+sn_get_next_bit(void) {
+	int i;
+	int bit;
+
+	for (i = 3; i >= 0; i--) {
+		if (pda.sn_soft_irr[i] != 0) {
+			bit = (i * 64) +  __ffs(pda.sn_soft_irr[i]);
+			__change_bit(bit, (volatile void *)pda.sn_soft_irr);
+			return(bit);
+		}
+	}
+	return IA64_SPURIOUS_INT_VECTOR;
 }
 
 void
-intr_test_handle_intr(int irq, void *junk, struct pt_regs *morejunk) {
-	intr_test_icount[irq]++;
-	printk("RECEIVED %d INTERRUPTS ON IRQ %d\n",intr_test_icount[irq], irq);
+sn_set_tpr(int vector) {
+	if (vector > IA64_LAST_DEVICE_VECTOR || vector < IA64_FIRST_DEVICE_VECTOR) {
+		ia64_set_tpr(vector);
+	} else {
+		ia64_set_tpr(IA64_LAST_DEVICE_VECTOR);
+	}
+}
+
+static inline void
+sn_get_all_ivr(void) {
+	int vector;
+
+	vector = ia64_get_ivr();
+	while (vector != IA64_SPURIOUS_INT_VECTOR) {
+		__set_bit(vector, (volatile void *)pda.sn_soft_irr);
+		ia64_eoi();
+		if (vector > IA64_LAST_DEVICE_VECTOR) return;
+		vector = ia64_get_ivr();
+	}
+}
+	
+int
+sn_get_ivr(void) {
+	int vector;
+
+	vector = sn_get_next_bit();
+	if (vector == IA64_SPURIOUS_INT_VECTOR) {
+		sn_get_all_ivr();
+		vector = sn_get_next_bit();
+	}
+	return vector;
 }
-#endif /* ajmtestintr */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/llsc4.c linux-2.4.22-pre3/arch/ia64/sn/kernel/llsc4.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/llsc4.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/llsc4.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1044 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-#include <linux/kernel_stat.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/efi.h>
-#include <asm/page.h>
-#include <linux/threads.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/leds.h>
-
-#include "llsc4.h"
-
-
-#ifdef STANDALONE
-#include "lock.h"
-#endif
-
-#ifdef INTTEST
-static int	inttest=0;
-#endif
-
-#ifdef IA64_SEMFIX_INSN
-#undef IA64_SEMFIX_INSN
-#endif
-#ifdef IA64_SEMFIX
-#undef IA64_SEMFIX
-#endif
-# define IA64_SEMFIX_INSN
-# define IA64_SEMFIX    ""
-
-#define NOLOCK		0xdead
-#define BGUARD(linei)	(0xbbbb0000 | (linei));
-#define EGUARD(linei)	(0xeeee0000 | (linei));
-#define GUARDLINE(v)	((v)&0xffff)
-
-/*
- * Test parameter table for AUTOTEST
- */
-typedef struct {
-	int	passes;
-	int	linecount;
-	int	linepad;
-} autotest_table_t;
-
-autotest_table_t autotest_table[] = {
-	{50000000,	2,	0x2b4		},
-	{50000000,	16,	0,		},
-	{50000000,	16,	4,		},
-	{50000000,	128,	0x44		},
-	{50000000,	128,	0x84		},
-	{50000000,	128,	0x200		},
-	{50000000,	128,	0x204		},
-	{50000000,	128,	0x2b4		},
-	{50000000,	2,	8*MB+0x2b4	},
-	{50000000,	16,	8*MB+0		},
-	{50000000,	16,	8*MB+4		},
-	{50000000,	128,	8*MB+0x44	},
-	{50000000,	128,	8*MB+0x84	},
-	{50000000,	128,	8*MB+0x200	},
-	{50000000,	128,	8*MB+0x204	},
-	{50000000,	128,	8*MB+0x2b4	},
-	{0}};
-
-/*
- * Array of virtual addresses available for test purposes.
- */
-
-typedef struct {
-	long	vstart;
-	long	vend;
-	long	nextaddr;
-	long	nextinit;
-	int	wrapcount;
-} memmap_t;
-
-#define MAPCHUNKS		128
-memmap_t 	memmap[MAPCHUNKS];
-int		memmapx=0;
-
-typedef struct {
-	void	*addr;
-	long	data[16];
-	long	data_fc[16];
-} capture_line_t;
-
-typedef struct {
-	int	size;
-	void	*blockaddr;
-	void	*shadaddr;
-	long	blockdata[48];
-	long	shaddata[48];
-	long	blockdata_fc[48];
-	long	shaddata_fc[48];
-	long	synerr;
-} capture_t;
-
-/*
- * PORTING NOTE: revisit this statement. On hardware we put mbase at 0 and
- * the rest of the tables have to start at 1MB to skip PROM tables.
- */
-#define THREADPRIVATESZ()	((sizeof(threadprivate_t)+511)/512*512)
-#define THREADPRIVATE(t)	((threadprivate_t*)(((long)mbase)+4096+t*THREADPRIVATESZ()))
-
-#define k_capture		mbase->sk_capture
-#define k_go			mbase->sk_go
-#define k_linecount		mbase->sk_linecount
-#define k_passes		mbase->sk_passes
-#define k_napticks		mbase->sk_napticks
-#define k_stop_on_error		mbase->sk_stop_on_error
-#define k_verbose		mbase->sk_verbose
-#define k_threadprivate		mbase->sk_threadprivate
-#define k_blocks		mbase->sk_blocks
-#define k_iter_msg		mbase->sk_iter_msg
-#define k_vv			mbase->sk_vv
-#define k_linepad		mbase->sk_linepad
-#define k_options		mbase->sk_options
-#define k_testnumber		mbase->sk_testnumber
-#define k_currentpass		mbase->sk_currentpass
-
-static long		blocks[MAX_LINECOUNT];		/* addresses of data blocks */
-static control_t	*mbase;
-static vint		initialized=0;
-
-static unsigned int ran_conf_llsc(int);
-static int  rerr(capture_t *, char *, void *, void *, int, int, int, int, int, int);
-static void dumpline(void *, char *, char *, void *, void *, int);
-static int  checkstop(int, int, uint);
-static void spin(int);
-static void capturedata(capture_t *, uint, void *, void *, int);
-static int  randn(uint max, uint *seed);
-static uint zrandom (uint *zranseed);
-static int  set_lock(uint *, uint);
-static int  clr_lock(uint *, uint);
-static void Speedo(void);
-
-int autotest_enabled=0;
-static int llsctest_number=-1;
-static int errstop_enabled=0;
-static int fail_enabled=0;
-static int l4_opt=0;
-static int selective_trigger=0;
-static int dump_block_addrs_opt=0;
-static lock_t errlock=NOLOCK;
-static private_t init_private[LLSC_MAXCPUS];
-
-static int __init autotest_enable(char *str)
-{
-        autotest_enabled = 1;
-	return 1;
-}
-static int __init set_llscblkadr(char *str)
-{
-	dump_block_addrs_opt = 1;
-	return 1;
-}
-static int __init set_llscselt(char *str)
-{
-	selective_trigger = 1;
-	return 1;
-}
-static int __init set_llsctest(char *str)
-{
-        llsctest_number = simple_strtol(str, &str, 10);
-	if (llsctest_number < 0 || llsctest_number > 15)
-		llsctest_number = -1;
-	return 1;
-}
-static int __init set_llscerrstop(char *str)
-{
-        errstop_enabled = 1;
-	return 1;
-}
-static int __init set_llscfail(char *str)
-{
-        fail_enabled = 8;
-	return 1;
-}
-static int __init set_llscl4(char *str)
-{
-        l4_opt = 1;
-	return 1;
-}
-
-static void print_params(void)
-{
-	printk ("********* Enter AUTOTEST facility on master cpu *************\n");
-	printk ("  Test options:\n");
-	printk ("     llsctest=<n>\t%d\tTest number to run (all = -1)\n", llsctest_number);
-	printk ("     llscerrstop \t%s\tStop on error\n", errstop_enabled ? "on" : "off");
-	printk ("     llscfail    \t%s\tForce a failure to test the trigger & error messages\n", fail_enabled ? "on" : "off");
-	printk ("     llscselt    \t%s\tSelective triger on failures\n", selective_trigger ? "on" : "off");
-	printk ("     llscblkadr  \t%s\tDump data block addresses\n", dump_block_addrs_opt ? "on" : "off");
-	printk ("     llscl4      \t%s\tRun only tests that evict from L4\n", l4_opt ? "on" : "off");
-	printk ("  SEMFIX: %s\n", IA64_SEMFIX);
-	printk ("\n");
-}
-__setup("autotest", autotest_enable);
-__setup("llsctest=", set_llsctest);
-__setup("llscerrstop", set_llscerrstop);
-__setup("llscfail", set_llscfail);
-__setup("llscselt", set_llscselt);
-__setup("llscblkadr", set_llscblkadr);
-__setup("llscl4", set_llscl4);
-
-
-
-static inline int
-set_lock(uint *lock, uint id)
-{
-	uint	old;
-	old = cmpxchg_acq(lock, NOLOCK, id);
-	return (old == NOLOCK);
-}
-
-static inline int
-clr_lock(uint *lock, uint id)
-{
-	uint	old;
-	old = cmpxchg_rel(lock, id, NOLOCK);
-	return (old == id);
-}
-
-static inline void
-init_lock(uint *lock)
-{
-	*lock = NOLOCK;
-}
-
-/*------------------------------------------------------------------------+
-| Routine  :  ran_conf_llsc - ll/sc shared data test                      |
-| Description: This test checks the coherency of shared data              |
-+------------------------------------------------------------------------*/
-static unsigned int
-ran_conf_llsc(int thread)
-{
-	private_t	pval;
-	share_t		sval, sval2;
-	uint		vv, linei, slinei, sharei, pass;
-	long		t;
-	lock_t		lockpat;
-	share_t		*sharecopy;
-	long		verbose, napticks, passes, linecount, lcount;
-	dataline_t	*linep, *slinep;
-	int		s, seed;
-	threadprivate_t	*tp;
-	uint		iter_msg, iter_msg_i=0;
-	int		vv_mask;
-	int		correct_errors;
-	int		errs=0;
-	int		stillbad;
-	capture_t	capdata;
-	private_t	*privp;
-	share_t		*sharep;
-
-
-	linecount = k_linecount;
-	napticks = k_napticks;
-	verbose = k_verbose;
-	passes = k_passes;
-	iter_msg = k_iter_msg;
-	seed = (thread + 1) * 647;
-	tp = THREADPRIVATE(thread);
-	vv_mask = (k_vv>>((thread%16)*4)) & 0xf;
-	correct_errors = k_options&0xff;
-
-	memset (&capdata, 0, sizeof(capdata));
-	for (linei=0; linei<linecount; linei++)
-		tp->private[linei] = thread;	
-
-	for (pass = 1; passes == 0 || pass < passes; pass++) {
-		lockpat = (pass & 0x0fffffff) + (thread <<28);
-		if (lockpat == NOLOCK)
-			continue;
-		tp->threadpasses = pass;
-		if (checkstop(thread, pass, lockpat))
-			return 0;
-		iter_msg_i++;
-		if (iter_msg && iter_msg_i > iter_msg) {
-			printk("Thread %d, Pass %d\n", thread, pass);
-			iter_msg_i = 0;
-		}
-		lcount = 0;
-
-		/*
-		 * Select line to perform operations on.
-		 */
-		linei = randn(linecount, &seed);
-		sharei = randn(2, &seed);
-		slinei = (linei + (linecount/2))%linecount;		/* I dont like this - fix later */
-
-		linep = (dataline_t *)blocks[linei];
-		slinep = (dataline_t *)blocks[slinei];
-		if (sharei == 0)
-			sharecopy = &slinep->share0;
-		else
-			sharecopy = &slinep->share1;
-
-
-		vv = randn(4, &seed);
-		if ((vv_mask & (1<<vv)) == 0)
-			continue;
-
-		if (napticks) {
-			t = randn(napticks, &seed);
-			udelay(t);
-		}
-		privp = &linep->private[thread];
-		sharep = &linep->share[sharei];
-		
-		switch(vv) {
-		case 0:
-			/* Read and verify private count on line. */
-			pval = *privp;
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);
-			if (pval != tp->private[linei]) {
-				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
-				stillbad = (*privp != tp->private[linei]);
-				if (rerr(&capdata, "Private count", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
-					return 1;
-				}
-				if (correct_errors) {
-					tp->private[linei] = *privp;
-				}
-				errs++;
-			}
-			break;
-
-		case 1:
-			/* Read, verify, and increment private count on line. */
-			pval = *privp;
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);
-			if (pval != tp->private[linei]) {
-				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
-				stillbad = (*privp != tp->private[linei]);
-				if (rerr(&capdata, "Private count & inc", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
-					return 1;
-				}
-				errs++;
-			}
-			pval = (pval==255) ? 0 : pval+1;
-			*privp = pval;
-			tp->private[linei] = pval;
-			break;
-
-		case 2:
-			/* Lock line, read and verify shared data. */
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);
-			lcount = 0;
-			while (LOCK(sharei) != 1) {
-				if (checkstop(thread, pass, lockpat))
-					return 0;
-				if (lcount++>1000000) {
-					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
-					stillbad = (GETLOCK(sharei) != 0);
-					rerr(&capdata, "Shared data lock", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
-					return 1;
-				}
-				if ((lcount&0x3fff) == 0)
-					udelay(1000);
-			}
-
-			sval = *sharep;
-			sval2 = *sharecopy;
-			if (pass > 12 && thread == 0 && fail_enabled == 1)
-				sval++;
-			if (sval != sval2) {
-				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
-				stillbad = (*sharep != *sharecopy);
-				if (!stillbad && *sharep != sval && *sharecopy == sval2)
-					stillbad = 2;
-				if (rerr(&capdata, "Shared data", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
-					return 1;
-				}
-				if (correct_errors)
-					*sharep = *sharecopy;
-				errs++;
-			}
-
-
-			if ( (s=UNLOCK(sharei)) != 1) {
-				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
-				stillbad = (GETLOCK(sharei) != lockpat);
-				if (rerr(&capdata, "Shared data unlock", linep, slinep, thread, pass, linei, lockpat, GETLOCK(sharei), stillbad))
-					return 1;
-				if (correct_errors)
-					ZEROLOCK(sharei);	
-				errs++;
-			}
-			break;
-
-		case 3:
-			/* Lock line, read and verify shared data, modify shared data. */
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);
-			lcount = 0;
-			while (LOCK(sharei) != 1) {
-				if (checkstop(thread, pass, lockpat))
-					return 0;
-				if (lcount++>1000000) {
-					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
-					stillbad = (GETLOCK(sharei) != 0);
-					rerr(&capdata, "Shared data lock & inc", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
-					return 1;
-				}
-				if ((lcount&0x3fff) == 0)
-					udelay(1000);
-			}
-			sval = *sharep;
-			sval2 = *sharecopy;
-			if (sval != sval2) {
-				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
-				stillbad = (*sharep != *sharecopy);
-				if (!stillbad && *sharep != sval && *sharecopy == sval2)
-					stillbad = 2;
-				if (rerr(&capdata, "Shared data & inc", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
-					return 1;
-				}
-				errs++;
-			}
-
-			*sharep = lockpat;
-			*sharecopy = lockpat;
-
-
-			if ( (s=UNLOCK(sharei)) != 1) {
-				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
-				stillbad = (GETLOCK(sharei) != lockpat);
-				if (rerr(&capdata, "Shared data & inc unlock", linep, slinep, thread, pass, linei, thread, GETLOCK(sharei), stillbad))
-					return 1;
-				if (correct_errors)
-					ZEROLOCK(sharei);	
-				errs++;
-			}
-			break;
-		}
-	}
-
-	return (errs > 0);
-}
-
-static void
-trigger_la(long val)
-{
-	long	*p;
-
-	p = (long*)0xc0000a0001000020L; /* PI_CPU_NUM */
-	*p = val;
-}
-
-static long
-getsynerr(void)
-{
-	long	err, *errp;
-
-	errp = (long*)0xc0000e0000000340L;	/* SYN_ERR */
-	err = *errp;
-	if (err)
-		*errp = -1L;
-	return (err & ~0x60);
-}
-
-static int
-rerr(capture_t *cap, char *msg, void *lp, void *slp, int thread, int pass, int badlinei, int exp, int found, int stillbad)
-{
-	int		cpu, i, linei;
-	long 		synerr;
-	int		selt;
-
-
-	selt = selective_trigger && stillbad > 1 && 
-			memcmp(cap->blockdata, cap->blockdata_fc, 128) != 0 &&
-			memcmp(cap->shaddata, cap->shaddata_fc, 128) == 0;
-	if (selt) {
-		trigger_la(pass);
-	} else if (selective_trigger) {
-		k_go = ST_STOP;
-		return k_stop_on_error;;
-	}
-
-	spin(1);
-	i = 100;
-	while (i && set_lock(&errlock, 1) != 1) {
-		spin(1);
-		i--;
-	}
-	printk ("\nDataError!: %-20s, test %ld, thread %d, line:%d, pass %d (0x%x), time %ld expected:%x, found:%x\n",
-	    msg, k_testnumber, thread, badlinei, pass, pass, jiffies, exp, found);
-
-	dumpline (lp, "Corrupted data", "D ", cap->blockaddr, cap->blockdata, cap->size);
-#ifdef ZZZ
-	if (memcmp(cap->blockdata, cap->blockdata_fc, 128))
-		dumpline (lp, "Corrupted data", "DF", cap->blockaddr, cap->blockdata_fc, cap->size);
-#endif
-
-	if (cap->shadaddr) {
-		dumpline (slp, "Shadow    data", "S ", cap->shadaddr, cap->shaddata, cap->size);
-#ifdef ZZZ
-		if (memcmp(cap->shaddata, cap->shaddata_fc, 128))
-			dumpline (slp, "Shadow    data", "SF", cap->shadaddr, cap->shaddata_fc, cap->size);
-#endif
-	}
-	
-	printk("Threadpasses: ");
-	for (cpu=0,i=0; cpu<LLSC_MAXCPUS; cpu++)
-		if (k_threadprivate[cpu]->threadpasses) {
-			if (i && (i%8) == 0)
-				printk("\n            : ");
-			printk("  %d:0x%x", cpu, k_threadprivate[cpu]->threadpasses);
-			i++;
-		}
-	printk("\n");
-	
-	for (linei=0; linei<k_linecount; linei++) {
-		int		slinei, g1linei, g2linei, g1err, g2err, sh0err, sh1err;
-		dataline_t	*linep, *slinep;
-
-		slinei = (linei + (k_linecount/2))%k_linecount;
-		linep = (dataline_t *)blocks[linei];
-		slinep = (dataline_t *)blocks[slinei];
-
-		g1linei = GUARDLINE(linep->guard1);
-		g2linei = GUARDLINE(linep->guard2);
-		g1err = (g1linei != linei);
-		g2err = (g2linei != linei);
-		sh0err = (linep->share[0] != slinep->share0);
-		sh1err = (linep->share[1] != slinep->share1);
-
-		if (g1err || g2err || sh0err || sh1err) {
-			printk("Line 0x%lx (%03d), %sG1 0x%lx (%03d), %sG2 0x%lx (%03d), %sSH0 %08x (%08x), %sSH1 %08x (%08x)\n",
-				blocks[linei], linei, 
-				g1err ? "*" : " ", blocks[g1linei], g1linei,
-				g2err ? "*" : " ", blocks[g2linei], g2linei,
-				sh0err ? "*" : " ", linep->share[0], slinep->share0,
-				sh1err ? "*" : " ", linep->share[1], slinep->share1);
-
-
-		}
-	}
-
-	printk("\nData was %sfixed by flushcache\n", (stillbad == 1 ? "**** NOT **** " : " "));
-	synerr = getsynerr();
-	if (synerr)
-		printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr);
-	spin(2);
-	printk("\n\n");
-	clr_lock(&errlock, 1);
-
-	if (errstop_enabled) {
-		local_irq_disable();
-		while(1);
-	}
-	return k_stop_on_error;
-}
-
-
-static void
-dumpline(void *lp, char *str1, char *str2, void *addr, void *data, int size)
-{
-	long *p;
-	int i, off;
-
-	printk("%s at 0x%lx, size %d, block starts at 0x%lx\n", str1, (long)addr, size, (long)lp);
-	p = (long*) data;
-	for (i=0; i<48; i++, p++) {
-		if (i%8 == 0) printk("%2s", i==16 ? str2 : "  ");
-		printk(" %016lx", *p);
-		if ((i&7)==7) printk("\n");
-	}
-	printk("   ");
-	off = (((long)addr) ^ size) & 63L;
-	for (i=0; i<off+size; i++) {
-		printk("%s", (i>=off) ? "--" : "  ");
-		if ((i%8) == 7)
-			printk(" ");
-	}
-
-	off = ((long)addr) & 127;
-	printk(" (line %d)\n", 2+off/64+1);
-}
-
-
-static int
-randn(uint max, uint *seedp)
-{
-	if (max == 1)
-		return(0);
-	else
-		return((int)(zrandom(seedp)>>10) % max);
-}
-
-
-static int
-checkstop(int thread, int pass, uint lockpat)
-{
-	long	synerr;
-
-	if (k_go == ST_RUN)
-		return 0;
-	if (k_go == ST_STOP)
-		return 1;
-
-	if (errstop_enabled) {
-		local_irq_disable();
-		while(1);
-	}
-	synerr = getsynerr();
-	spin(2);
-	if (k_go == ST_STOP)
-		return 1;
-	if (synerr)
-		printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr);
-	return 1;
-}
-
-
-static void
-spin(int j)
-{
-	udelay(j * 500000);
-}
-
-static void
-capturedata(capture_t *cap, uint pass, void *blockaddr, void *shadaddr, int size)
-{
-
-	if (!selective_trigger)
-		trigger_la (pass);
-
-	memcpy (cap->blockdata, CACHEALIGN(blockaddr)-128, 3*128);
-	if (shadaddr) 
-		memcpy (cap->shaddata, CACHEALIGN(shadaddr)-128, 3*128);
-
-	if (k_stop_on_error) {
-		k_go = ST_ERRSTOP;
-	}
-
- 	cap->size = size;
-	cap->blockaddr = blockaddr;
-	cap->shadaddr = shadaddr;
-
-	asm volatile ("fc %0" :: "r"(blockaddr) : "memory");
-	ia64_sync_i();
-	ia64_srlz_d();
-	memcpy (cap->blockdata_fc, CACHEALIGN(blockaddr)-128, 3*128);
-
-	if (shadaddr) {
-		asm volatile ("fc %0" :: "r"(shadaddr) : "memory");
-		ia64_sync_i();
-		ia64_srlz_d();
-		memcpy (cap->shaddata_fc, CACHEALIGN(shadaddr)-128, 3*128);
-	}
-}
-
-int             zranmult = 0x48c27395;
-
-static uint  
-zrandom (uint *seedp)
-{
-        *seedp = (*seedp * zranmult) & 0x7fffffff;
-        return (*seedp);
-}
-
-
-void
-set_autotest_params(void)
-{
-	static int	testnumber=-1;
-
-	if (llsctest_number >= 0) {
-		testnumber = llsctest_number;
-	} else {
-		testnumber++;
-		if (autotest_table[testnumber].passes == 0) {
-			testnumber = 0;
-			dump_block_addrs_opt = 0;
-		}
-	}
-	if (testnumber == 0 && l4_opt) testnumber = 9;
-
-	k_passes = autotest_table[testnumber].passes;
-	k_linepad = autotest_table[testnumber].linepad;
-	k_linecount = autotest_table[testnumber].linecount;
-	k_testnumber = testnumber;
-
-	if (IS_RUNNING_ON_SIMULATOR()) {
-		printk ("llsc start test %ld\n", k_testnumber);
-		k_passes = 1000;
-	}
-}
-
-
-static void
-set_leds(int errs)
-{
-	unsigned char	leds=0;
-
-	/*
-	 * Leds are:
-	 * 	ppppeee-  
-	 *   where
-	 *      pppp = test number
-	 *       eee = error count but top bit is stick
-	 */
-
-	leds =  ((errs&7)<<1) | ((k_testnumber&15)<<4) | (errs ? 0x08 : 0);
-	set_led_bits(leds, LED_MASK_AUTOTEST);
-}
-
-static void
-setup_block_addresses(void)
-{
-	int			i, stride, memmapi;
-	dataline_t		*dp;
-	long			*ip, *ipe;
-
-
-	stride = k_linepad + sizeof(dataline_t);
-	memmapi = 0;
-	for (i=0; i<memmapx; i++) {
-		memmap[i].nextaddr = memmap[i].vstart;
-		memmap[i].nextinit = memmap[i].vstart;
-		memmap[i].wrapcount = 0;
-	}
-
-	for (i=0; i<k_linecount; i++) {
-		blocks[i] = memmap[memmapi].nextaddr;
-		dp = (dataline_t*)blocks[i];
-		memmap[memmapi].nextaddr += (stride & 0xffff);
-		if (memmap[memmapi].nextaddr + sizeof(dataline_t) >= memmap[memmapi].vend) {
-			memmap[memmapi].wrapcount++;
-			memmap[memmapi].nextaddr = memmap[memmapi].vstart + 
-					memmap[memmapi].wrapcount * sizeof(dataline_t);
-		}
-
-		ip = (long*)((memmap[memmapi].nextinit+7)&~7);
-		ipe = (long*)(memmap[memmapi].nextaddr+2*sizeof(dataline_t)+8);
-		while(ip <= ipe && ip < ((long*)memmap[memmapi].vend-8))
-			*ip++ = (long)ip;
-		memmap[memmapi].nextinit = (long) ipe;
-		dp->guard1 = BGUARD(i);
-		dp->guard2 = EGUARD(i);
-		dp->lock[0] = dp->lock[1] = NOLOCK;
-		dp->share[0] = dp->share0 = 0x1111;
-		dp->share[1] = dp->share1 = 0x2222;
-		memcpy(dp->private, init_private, LLSC_MAXCPUS*sizeof(private_t));
-
-
-		if (stride > 16384) {
-			memmapi++;
-			if (memmapi == memmapx)
-				memmapi = 0;
-		}
-	}
-
-}
-
-static void
-dump_block_addrs(void)
-{
-	int	i;
-
-	printk("LLSC TestNumber %ld\n", k_testnumber);
-
-	for (i=0; i<k_linecount; i++) {
-		printk("  %lx", blocks[i]);
-		if (i%4 == 3)
-			printk("\n");
-	}
-	printk("\n");
-}
-
-
-static void
-set_thread_state(int cpuid, int state)
-{
-	if (k_threadprivate[cpuid]->threadstate == TS_KILLED) {
-		set_led_bits(LED_MASK_AUTOTEST, LED_MASK_AUTOTEST);
-		while(1);
-	}
-	k_threadprivate[cpuid]->threadstate = state;
-}
-
-#define MINBLK	(16*1024*1024)
-static int
-build_mem_map(unsigned long start, unsigned long end, void *arg)
-{
-	long	lstart, lend;
-	long	align = 8*MB;
-
-	printk ("LLSC memmap: start 0x%lx, end 0x%lx, (0x%lx - 0x%lx)\n", 
-		start, end, (long) virt_to_page(start), (long) virt_to_page(end-PAGE_SIZE));
-
-	if (memmapx >= MAPCHUNKS || (end-start) < MINBLK)
-		return 0;
-
-	/*
-	 * Start in the middle of the range & find the first non-free page in both directions
-	 * from the midpoint. This is likely to be the bigest free block.
-	 */
-	lend = lstart = start + (end-start)/2;
-	while (lend < end && !PageReserved(virt_to_page(lend)) && virt_to_page(lend)->count.counter == 0)
-		lend += PAGE_SIZE;
-	lend -= PAGE_SIZE;
-
-	while (lstart >= start && !PageReserved(virt_to_page(lstart)) && virt_to_page(lstart)->count.counter == 0)
-		lstart -= PAGE_SIZE;
-	lstart += PAGE_SIZE;
-
-	lstart = (lstart + align -1) /align * align;
-	end = end / align * align;
-	if (lstart >= end)
-		return 0;
-	printk ("     memmap: start 0x%lx, end 0x%lx\n", lstart, end);
-
-	memmap[memmapx].vstart = lstart;
-	memmap[memmapx].vend = end;
-	memmapx++;
-	return 0;
-}
-
-void int_test(void);
-
-int
-llsc_main (int cpuid)
-{
-	int		i, cpu, is_master, repeatcnt=0;
-	unsigned int	preverr=0, errs=0, pass=0;
-	int		automode=0;
-
-#ifdef INTTEST
-	if (inttest)
-		int_test();
-#endif
-
-	if (!autotest_enabled)
-		return 0;
-
-#ifdef CONFIG_SMP
-	is_master = !smp_processor_id();
-#else
-	is_master = 1;
-#endif
-
-
-	if (is_master) {
-		mbase = (control_t*) __get_free_pages(GFP_KERNEL, get_order(4096+THREADPRIVATESZ()*LLSC_MAXCPUS));
-		printk("LLSC: mbase 0x%lx\n", (long)mbase);
-		print_params();
-		if(!IS_RUNNING_ON_SIMULATOR())
-			spin(10);
-		k_currentpass = 0;
-		k_go = ST_IDLE;
-		k_passes = DEF_PASSES;
-		k_napticks = DEF_NAPTICKS;
-		k_stop_on_error = DEF_STOP_ON_ERROR;
-		k_verbose = DEF_VERBOSE;
-		k_linecount = DEF_LINECOUNT;
-		k_iter_msg = DEF_ITER_MSG;
-		k_vv = DEF_VV;
-		k_linepad = DEF_LINEPAD;
-		k_blocks = (void*)blocks;
-		efi_memmap_walk(build_mem_map, 0);
-	
-#ifdef CONFIG_IA64_SGI_AUTOTEST
-		automode = 1;
-#endif
-
-		for (i=0; i<LLSC_MAXCPUS; i++) {
-			k_threadprivate[i] = THREADPRIVATE(i);
-			memset(k_threadprivate[i], 0, sizeof(*k_threadprivate[i]));
-			init_private[i] = i;
-		}
-		mb();
-		initialized = 1;
-	} else {
-		while (initialized == 0)
-			udelay(100);
-	}
-
-loop:
-	if (is_master) {
-		if (automode) {
-			if (!preverr || repeatcnt++ > 5) {
-				set_autotest_params();
-				repeatcnt = 0;
-			}
-		} else {
-			while (k_go == ST_IDLE);
-		}
-
-		k_go = ST_INIT;
-		if (k_linecount > MAX_LINECOUNT) k_linecount = MAX_LINECOUNT;
-		k_linecount = k_linecount & ~1;
-		setup_block_addresses();
-		if (!preverr && dump_block_addrs_opt)
-			dump_block_addrs();
-
-		k_currentpass = pass++;
-		k_go = ST_RUN;
-		if (fail_enabled)
-			fail_enabled--;
-
-	} else {
-		while (k_go != ST_RUN || k_currentpass != pass);
-		pass++;
-	}
-
-
-	set_leds(errs);
-	set_thread_state(cpuid, TS_RUNNING);
-
-	errs += ran_conf_llsc(cpuid);
-	preverr = (k_go == ST_ERRSTOP);
-
-	set_leds(errs);
-	set_thread_state(cpuid, TS_STOPPED);
-
-	if (is_master) {
-		Speedo();
-		for (i=0, cpu=0; cpu<LLSC_MAXCPUS; cpu++) {
-			while (k_threadprivate[cpu]->threadstate == TS_RUNNING) {
-				i++;
-				if (i == 10000) { 
-					k_go = ST_STOP;
-					printk ("  llsc master stopping test number %ld\n", k_testnumber);
-				}
-				if (i > 100000) {
-					k_threadprivate[cpu]->threadstate = TS_KILLED;
-					printk ("  llsc: master killing cpuid %d, running test number %ld\n", 
-							cpu, k_testnumber);
-				}
-				udelay(1000);
-			}
-		}
-	}
-
-	goto loop;
-}
-
-
-static void
-Speedo(void)
-{
-	static int i = 0;
-
-	switch (++i%4) {
-	case 0:
-		printk("|\b");
-		break;
-	case 1:
-		printk("\\\b");
-		break;
-	case 2:
-		printk("-\b");
-		break;
-	case 3:
-		printk("/\b");
-		break;
-	}
-}
-
-#ifdef INTTEST
-
-/* ======================================================================================================== 
- *
- * Some test code to verify that interrupts work
- *
- * Add the following to the arch/ia64/kernel/smp.c after the comment "Reschedule callback"
- * 		if (zzzprint_resched) printk("  cpu %d got interrupt\n", smp_processor_id());
- *
- * Enable the code in arch/ia64/sn/sn1/smp.c to print sending IPIs.
- *
- */
-
-static int __init set_inttest(char *str)
-{
-        inttest = 1;
-	autotest_enabled = 1;
-
-	return 1;
-}	
-
-__setup("inttest=", set_inttest);
-
-int	zzzprint_resched=0;
-
-void
-int_test() {
-	int			mycpu, cpu;
-	static volatile int	control_cpu=0;
-
-	mycpu = smp_processor_id();
-	zzzprint_resched = 2;
-
-	printk("Testing cross interrupts\n");
-	
-	while (control_cpu != smp_num_cpus) {
-		if (mycpu == cpu_logical_map(control_cpu)) {
-			for (cpu=0; cpu<smp_num_cpus; cpu++) {
-				printk("Sending interrupt from %d to %d\n", mycpu, cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-				smp_send_reschedule(cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-				smp_send_reschedule(cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-			}
-			control_cpu++;
-		}
-	}
-
-	zzzprint_resched = 1;
-
-	if (mycpu == cpu_logical_map(smp_num_cpus-1)) {
-		printk("\nTight loop of cpu %d sending ints to cpu 0 (every 100 us)\n", mycpu);
-		udelay(IS_RUNNING_ON_SIMULATOR ? 1000 : 1000000);
-		__cli();
-		while (1) {
-			smp_send_reschedule(0);
-			udelay(100);
-		}
-
-	}
-
-	while(1);
-}
-#endif
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/llsc4.h linux-2.4.22-pre3/arch/ia64/sn/kernel/llsc4.h
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/llsc4.h	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/llsc4.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,107 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifdef STANDALONE
-#include "lock.h"
-#endif
-
-
-#define DEF_NAPTICKS		0
-#define DEF_PASSES		0
-#define DEF_AUTO_PASSES		1000000
-#define DEF_STOP_ON_ERROR	1
-#define DEF_VERBOSE		0
-#define DEF_LINECOUNT		2
-#define DEF_ITER_MSG		0
-#define DEF_VV			0xffffffff
-#define DEF_LINEPAD		0x234
-
-
-
-#define LLSC_MAXCPUS		64
-#define CACHELINE		64
-#define MAX_LINECOUNT		1024
-#define K			1024
-#define	MB			(K*K)
-
-
-#define	uint 		unsigned int
-#define	ushort		unsigned short
-#define	uchar		unsigned char
-#define vint		volatile int
-#define vlong		volatile long
-
-#define LOCKADDR(i)	&linep->lock[(i)]
-#define LOCK(i)		set_lock(LOCKADDR(i), lockpat)
-#define UNLOCK(i)	clr_lock(LOCKADDR(i), lockpat)
-#define GETLOCK(i)	*LOCKADDR(i)
-#define ZEROLOCK(i)	init_lock(LOCKADDR(i))
-
-#define CACHEALIGN(a)	((char*)((long)(a) & ~127L))
-
-typedef uint		guard_t;
-typedef uint		lock_t;
-typedef uint		share_t;
-typedef uchar		private_t;
-
-typedef struct {
-	guard_t		guard1;
-	lock_t		lock[2];
-	share_t		share[2];
-	private_t	private[LLSC_MAXCPUS];
-	share_t		share0;
-	share_t		share1;
-	guard_t		guard2;
-} dataline_t ;
-
-
-#define LINEPAD			k_linepad
-#define LINESTRIDE		(((sizeof(dataline_t)+CACHELINE-1)/CACHELINE)*CACHELINE + LINEPAD)
-
-
-typedef struct {
-	vint		threadstate;
-	uint		threadpasses;
-	private_t	private[MAX_LINECOUNT];
-} threadprivate_t;
-
-typedef struct {
-	vlong		sk_go;		/* 0=idle, 1=init, 2=run */
-	long		sk_linecount;
-	long		sk_passes;
-	long		sk_napticks;
-	long		sk_stop_on_error;
-	long		sk_verbose;
-	long		sk_iter_msg;
-	long		sk_vv;
-	long		sk_linepad;
-	long		sk_options;
-	long		sk_testnumber;
-	vlong		sk_currentpass;
-	void 		*sk_blocks;
-	threadprivate_t	*sk_threadprivate[LLSC_MAXCPUS];
-} control_t;
-
-/* Run state (k_go) constants */
-#define ST_IDLE		0
-#define ST_INIT		1
-#define ST_RUN		2
-#define ST_STOP		3
-#define ST_ERRSTOP	4
-
-
-/* Threadstate constants */
-#define TS_STOPPED	0
-#define	TS_RUNNING	1
-#define TS_KILLED	2
-
-
-
-int llsc_main (int cpuid);
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/machvec.c linux-2.4.22-pre3/arch/ia64/sn/kernel/machvec.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/machvec.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/machvec.c	2003-07-05 18:09:46.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -30,30 +30,5 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 
-#include <linux/config.h>
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define MACHVEC_PLATFORM_NAME	sn1
-#else CONFIG_IA64_SGI_SN1
 #define MACHVEC_PLATFORM_NAME	sn2
-#else
-#error "unknown platform"
-#endif
-
 #include <asm/machvec_init.h>
-#include <asm/io.h>
-#include <linux/pci.h>
-void*
-sn_mk_io_addr_MACRO
-
-dma_addr_t
-sn_pci_map_single_MACRO
-
-int
-sn_pci_map_sg_MACRO
-
-unsigned long
-sn_virt_to_phys_MACRO
-
-void *
-sn_phys_to_virt_MACRO
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/mca.c linux-2.4.22-pre3/arch/ia64/sn/kernel/mca.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/mca.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/mca.c	2003-07-05 18:09:46.000000000 -0700
@@ -2,7 +2,7 @@
  * File:	mca.c
  * Purpose:	SN specific MCA code.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -123,9 +123,7 @@
 static void
 sn_cpei_timer_handler(unsigned long dummy) {
 	sn_cpei_handler(-1, NULL, NULL);
-	del_timer(&sn_cpei_timer);
-	sn_cpei_timer.expires = jiffies + CPEI_INTERVAL;
-        add_timer(&sn_cpei_timer);
+	mod_timer(&sn_cpei_timer, jiffies + CPEI_INTERVAL);
 }
 
 void
@@ -134,27 +132,3 @@
         sn_cpei_timer.function = sn_cpei_timer_handler;
         add_timer(&sn_cpei_timer);
 }
-
-
-
-
-#ifdef ajmtestceintr
-
-struct timer_list sn_ce_timer;
-
-void
-sn_ce_timer_handler(long dummy) {
-	unsigned long *pi_ce_error_inject_reg = 0xc00000092fffff00;
-
-	*pi_ce_error_inject_reg = 0x0000000000000100;
-	del_timer(&sn_ce_timer);
-	sn_ce_timer.expires = jiffies + CPEI_INTERVAL;
-        add_timer(&sn_ce_timer);
-}
-
-sn_init_ce_timer() {
-	sn_ce_timer.expires = jiffies + CPEI_INTERVAL;
-        sn_ce_timer.function = sn_ce_timer_handler;
-        add_timer(&sn_ce_timer);
-}
-#endif /* ajmtestceintr */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/misctest.c linux-2.4.22-pre3/arch/ia64/sn/kernel/misctest.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/misctest.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/misctest.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,371 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/processor.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/timex.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/sn/intr.h>
-#include <asm/hw_irq.h>
-#include <asm/sn/leds.h>
-
-extern	int autotest_enabled;
-long	mcatest=0, debug0, debug1, debug2, debug3;
-
-#define HDELAY(t)	(IS_RUNNING_ON_SIMULATOR() ? udelay(1) : udelay(t))
-
-/* 
- * mcatest
- *	mactest contains a decimal number (RPTT) where
- *		R - flag, if non zero, run forever
- *
- *		P - identifies when to run the test
- *		    0 execute test at cpu 0 early init
- *		    1 execute test at cpu 0 idle
- *		    2 execute test at last (highest numbered) cpu idle
- *		    3 execute test on all cpus at idle
- *
- *		TT- identifies test to run
- *		    01 = MCA via dup TLB dropin
- *		    02 = MCA via garbage address
- *		    03 = lfetch via garbage address
- *		    05 = INIT self
- *		    06 = INIT other cpu
- *		    07 = INIT non-existent cpu
- *		    10 = IPI stress test. Target cpu 0
- *		    11 = IPI stress test. Target all cpus
- *		    12 = TLB stress test
- *		    13 = Park cpu (spinloop)
- *		    14 = One shot TLB test with tlb spinlock
- *		    15 = One shot TLB test
- *		    16 = One shot TLB test sync'ed with RTC
- *		    20 = set led to the cpuid & spin.
- *		    21 = Try mixed cache/uncached refs & see what happens
- *		    22 = Call SAL reboot
- *		    23 = Call PAL halt
- */
-static int __init set_mcatest(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	mcatest = val;
-	return 1;
-}
-__setup("mcatest=", set_mcatest);
-
-static int __init set_debug0(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug0 = val;
-	return 1;
-}
-__setup("debug0=", set_debug0);
-
-static int __init set_debug1(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug1 = val;
-	return 1;
-}
-__setup("debug1=", set_debug1);
-
-static int __init set_debug2(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug2 = val;
-	return 1;
-}
-__setup("debug2=", set_debug2);
-
-static int __init set_debug3(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug3 = val;
-	return 1;
-}
-__setup("debug3=", set_debug3);
-
-static volatile int	go;
-
-static void
-do_sync(int pos) {
-	if (pos != 3)
-		return;
-	else if (smp_processor_id() == 0)
-		go = 1;
-	else
-		while (!go);
-}
-
-static void
-sgi_mcatest_bkpt(void)
-{
-}
-
-
-/*
- * Optional test
- *	pos - 0 called from early init
- *	pos - called when cpu about to go idle (fully initialized
- */
-void
-sgi_mcatest(int pos)
-{
-	long	spos, test, repeat;
-	int	cpu, curcpu, i, n;
-
-	//if (IS_RUNNING_ON_SIMULATOR()) mcatest=1323;
-	repeat = mcatest/1000;
-	spos = (mcatest/100)%10;
-	test = mcatest % 100;
-	curcpu = smp_processor_id();
-
-	if ( mcatest == 0 || !((pos == 0 && spos == 0) ||
-		(pos == 1 && spos == 3) ||
-	        (pos == 1 && spos == 1 && curcpu == 0) ||
-	        (pos == 1 && spos == 2 && curcpu == smp_num_cpus-1)))
-		return;
-	     
-again:
-	if (test == 1 || test == 2 || test == 3) {
-		void zzzmca(int);
-		printk("CPU %d: About to cause unexpected MCA\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		zzzmca(test-1);
-	
-		HDELAY(100000);
-	}
-
-	if (test == 4) {
-		long    result, adrs[] = {0xe0021000009821e0UL, 0xc0003f3000000000UL, 0xc0000081101c0000UL, 0xc00000180e021004UL,  0xc00000180e022004UL, 0xc00000180e023004UL };
-		long    size[] = {1,2,4,8};
-		int     r, i, j, k;
-
-		for (k=0; k<2; k++) {
-			for (i=0; i<6; i++) {
-				for (j=0; j<4; j++) {
-					printk("Probing 0x%lx, size %ld\n", adrs[i], size[j]);
-					result = -1;
-					r = ia64_sn_probe_io_slot (adrs[i], size[j], &result);
-					printk("    status %d, val 0x%lx\n", r, result);
-					udelay(100000);
-				}
-			}
-		}
-
-	}
-
-	if (test == 5) {
-		cpu =  curcpu;
-		printk("CPU %d: About to send INIT to self (cpu %d)\n", curcpu, cpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
-		
-		HDELAY(100000);
-		printk("CPU %d: Returned from INIT\n", curcpu);
-	}
-
-	if (test == 6) {
-		cpu =  curcpu ^ 1;
-		printk("CPU %d: About to send INIT to other cpu (cpu %d)\n", curcpu, cpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 7) {
-		printk("CPU %d: About to send INIT to non-existent cpu\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		sn_send_IPI_phys(0xffff, 0, IA64_IPI_DM_INIT);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 10) {
-		n = IS_RUNNING_ON_SIMULATOR() ? 10 : 10000000;
-		cpu = 0;
-		printk("CPU %d: IPI stress test. Target cpu 0\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		for (i=0; i<n; i++)
-			platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 11) {
-		n = IS_RUNNING_ON_SIMULATOR() ? 100 : 10000000;
-		printk("CPU %d: IPI stress test. Target all cpus\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		for (i=0; i<n; i++)
-			for (cpu=0; cpu<smp_num_cpus; cpu++)
-				if (smp_num_cpus > 2 && cpu != curcpu)
-					platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 12) {
-		long adr = 0xe002200000000000UL;
-		n = IS_RUNNING_ON_SIMULATOR() ? 1000 : 100000;
-		printk("CPU %d: TLB flush stress test\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		for (i=0; i<n; i++)
-			platform_global_tlb_purge(adr, adr+25*PAGE_SIZE, 14);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-	
-	if (test == 13) {
-		printk("CPU %d: Park cpu in spinloop\n", curcpu);
-		while(1);
-	}
-	if (test == 14 || test == 15 || test == 16 || test == 17) {
-		long adr = 0xe002200000000000UL;
-		static int inited=0;
-		if (inited == 0) {
-			if (debug0 == 0) debug0 = 1;
-			repeat = 1;
-			do_sync(spos);
-			if (curcpu >= smp_num_cpus-2) {
-				printk("Parking cpu %d\n", curcpu);
-				local_irq_disable();
-				while(1);
-			} else {
-				printk("Waiting cpu %d\n", curcpu);
-				HDELAY(1000000);
-			}
-			HDELAY(1000000);
-			inited = 1;
-		}
-		if (test == 16 || test == 17) {
-			unsigned long t, shift, mask;
-			mask =  (smp_num_cpus > 16) ? 0x1f : 0xf;
-			shift = 25-debug1;
-			do {
-				t = get_cycles();
-				if (IS_RUNNING_ON_SIMULATOR())
-					t = (t>>8);
-				else
-					t = (t>>shift);
-				t = t & mask;
-			} while (t == curcpu);
-			do {
-				t = get_cycles();
-				if (IS_RUNNING_ON_SIMULATOR())
-					t = (t>>8);
-				else
-					t = (t>>shift);
-				t = t & mask;
-			} while (t != curcpu);
-		}
-		if(debug3) printk("CPU %d: One TLB start\n", curcpu);
-		if (test != 17) platform_global_tlb_purge(adr, adr+PAGE_SIZE*debug0, 14);
-		if(debug3) printk("CPU %d: One TLB flush done\n", curcpu);
-	}
-	if (test == 20) {
-		local_irq_disable();
-		set_led_bits(smp_processor_id(), 0xff);
-		while(1);
-	}
-	if (test == 21) {
-		extern long ia64_mca_stack[];
-		int		i, n;
-		volatile long	*p, *up;
-		p = (volatile long*)__imva(ia64_mca_stack);
-		up = (volatile long*)(__pa(p) | __IA64_UNCACHED_OFFSET);
-
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ get data in cache\n");
-		for (n=0, i=0; i<100; i++)
-			n += *(p+i);
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Make uncached refs to same data\n");
-		for (n=0, i=0; i<100; i++)
-			n += *(up+i);
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ dirty the data via cached refs\n");
-		for (n=0, i=0; i<100; i++)
-			*(p+i) = i;
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Make uncached refs to same data\n");
-		for (n=0, i=0; i<100; i++)
-			n += *(up+i);
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Flushing cache\n");
-		for (n=0, i=0; i<100; i++)
-			ia64_fc((void*)(p+i));
-		printk("ZZZ done\n");
-	}
-	if (test == 21) {
-		int i;
-		volatile long tb, t[10];
-		for (i=0; i<10; i++) {
-			tb = debug3+ia64_get_itc();
-			sgi_mcatest_bkpt();
-			t[i] = ia64_get_itc() - tb;
-		}
-		for (i=0; i<10; i++) {
-			printk("ZZZ NULL  0x%lx\n", t[i]);
-		}
-		for (i=0; i<10; i++) {
-			tb = debug3+ia64_get_itc();
-			ia64_pal_call_static(PAL_MC_DRAIN, 0, 0, 0, 0);
-			t[i] = ia64_get_itc() - tb;
-		}
-		for (i=0; i<10; i++) {
-			printk("ZZZ DRAIN 0x%lx\n", t[i]);
-		}
-	}
-	if (test == 22) {
-		extern void machine_restart(char*);
-		printk("ZZZ machine_restart\n");
-		machine_restart(0);
-	}
-	if (test == 23) {
-		printk("ZZZ ia64_pal_halt_light\n");
-		ia64_pal_halt_light();
-	}
-	if (repeat)
-		goto again;
-
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/probe.c linux-2.4.22-pre3/arch/ia64/sn/kernel/probe.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/probe.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/probe.c	2003-07-05 18:09:46.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  * Platform dependent support for IO probing.
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/setup.c linux-2.4.22-pre3/arch/ia64/sn/kernel/setup.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/setup.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/setup.c	2003-07-05 18:09:46.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -69,21 +69,27 @@
 #include <asm/sn/bte.h>
 #include <asm/sn/clksupport.h>
 #include <asm/sn/sn_sal.h>
-
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn2/shub.h>
-#endif
+
+#define pxm_to_nasid(pxm) ((pxm)<<1)
+
+#define MAX_PHYS_MEMORY		(1UL << 49)	/* 1 TB */
 
 extern void bte_init_node (nodepda_t *, cnodeid_t);
 extern void bte_init_cpu (void);
+extern void sn_timer_init(void);
+extern unsigned long last_time_offset;
+extern void (*ia64_mark_idle)(int);
+extern void snidle(int);
 
 unsigned long sn_rtc_cycles_per_second;   
-unsigned long sn_rtc_usec_per_cyc;
 
 partid_t sn_partid = -1;
 char sn_system_serial_number_string[128];
 u64 sn_partition_serial_number;
 
+short	physical_node_map[MAX_PHYSNODE_ID];
+
 /*
  * This is the address of the RRegs in the HSpace of the global
  * master.  It is used by a hack in serial.c (serial_[in|out],
@@ -92,21 +98,14 @@
  * early_printk won't try to access the UART before
  * master_node_bedrock_address is properly calculated.
  */
-u64 master_node_bedrock_address = 0UL;
+u64 master_node_bedrock_address;
 
 static void sn_init_pdas(char **);
 
-extern struct irq_desc *_sn_irq_desc[];
-
-#if defined(CONFIG_IA64_SGI_SN1)
-extern synergy_da_t	*Synergy_da_indr[];
-#endif
 
 static nodepda_t	*nodepdaindr[MAX_COMPACT_NODES];
 
-#ifdef CONFIG_IA64_SGI_SN2
-irqpda_t		*irqpdaindr[NR_CPUS];
-#endif /* CONFIG_IA64_SGI_SN2 */
+irqpda_t		*irqpdaindr;
 
 
 /*
@@ -133,29 +132,19 @@
  * running in the simulator.  Note that passing zeroes in DRIVE_INFO
  * is sufficient (the IDE driver will autodetect the drive geometry).
  */
+#ifdef CONFIG_IA64_GENERIC
+extern char drive_info[4*16];
+#else
 char drive_info[4*16];
-
-/**
- * sn_map_nr - return the mem_map entry for a given kernel address
- * @addr: kernel address to query
- *
- * Finds the mem_map entry for the kernel address given.  Used by
- * virt_to_page() (asm-ia64/page.h), among other things.
- */
-unsigned long
-sn_map_nr (void *addr)
-{
-	return MAP_NR_DISCONTIG(addr);
-}
+#endif
 
 /**
  * early_sn_setup - early setup routine for SN platforms
  *
- * Sets up an intial console to aid debugging.  Intended primarily
- * for bringup, it's only called if %BRINGUP and %CONFIG_IA64_EARLY_PRINTK
- * are turned on.  See start_kernel() in init/main.c.
+ * Sets up an initial console to aid debugging.  Intended primarily
+ * for bringup.  See start_kernel() in init/main.c.
  */
-#if defined(CONFIG_IA64_EARLY_PRINTK)
+#if defined(CONFIG_IA64_EARLY_PRINTK_SGI_SN) || defined(CONFIG_IA64_SGI_SN_SIM)
 
 void __init
 early_sn_setup(void)
@@ -170,7 +159,7 @@
 
 	/*
 	 * Parse enough of the SAL tables to locate the SAL entry point. Since, console
-	 * IO on SN2 is done via SAL calls, early_printk wont work without this.
+	 * IO on SN2 is done via SAL calls, early_printk won't work without this.
 	 *
 	 * This code duplicates some of the ACPI table parsing that is in efi.c & sal.c.
 	 * Any changes to those file may have to be made hereas well.
@@ -193,21 +182,48 @@
 	}
 
 	if ( IS_RUNNING_ON_SIMULATOR() ) {
-#if defined(CONFIG_IA64_SGI_SN1)
-		master_node_bedrock_address = (u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
-#else
 		master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
-#endif
 		printk(KERN_DEBUG "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address);
 	}
 }
-#endif /* CONFIG_IA64_SGI_SN1 */
+#endif /* CONFIG_IA64_EARLY_PRINTK_SGI_SN */
 
 #ifdef CONFIG_IA64_MCA
 extern int platform_intr_list[];
 #endif
 
 extern nasid_t master_nasid;
+static int shub_1_1_found __initdata;
+
+
+/*
+ * sn_check_for_wars
+ *
+ * Set flag for enabling shub specific wars
+ */
+
+static inline int __init
+is_shub_1_1(int nasid)
+{
+	unsigned long id;
+	int	rev;
+
+	id = REMOTE_HUB_L(nasid, SH_SHUB_ID);
+	rev =  (id & SH_SHUB_ID_REVISION_MASK) >> SH_SHUB_ID_REVISION_SHFT;
+	return rev <= 2;
+}
+
+static void __init
+sn_check_for_wars(void)
+{
+	int	cnode;
+
+	for (cnode=0; cnode< numnodes; cnode++)
+		if (is_shub_1_1(cnodeid_to_nasid(cnode)))
+			shub_1_1_found = 1;
+}
+
+
 
 /**
  * sn_setup - SN platform setup routine
@@ -221,8 +237,18 @@
 sn_setup(char **cmdline_p)
 {
 	long status, ticks_per_sec, drift;
-	int i;
+	int i, pxm;
 	int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
+	extern void io_sh_swapper(int, int);
+	extern nasid_t get_master_baseio_nasid(void);
+	extern void sn_cpu_init(void);
+
+	MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY;
+
+	memset(physical_node_map, -1, sizeof(physical_node_map));
+	for (pxm=0; pxm<MAX_PXM_DOMAINS; pxm++)
+		if (pxm_to_nid_map[pxm] != -1)
+			physical_node_map[pxm_to_nasid(pxm)] = pxm_to_nid_map[pxm];
 
 	printk("SGI SAL version %x.%02x\n", major, minor);
 
@@ -236,21 +262,11 @@
 		panic("PROM version too old\n");
 	}
 
-#ifdef CONFIG_IA64_SGI_SN2
-	{
-		extern void io_sh_swapper(int, int);
-		io_sh_swapper(get_nasid(), 0);
-	}
-#endif
+	io_sh_swapper(get_nasid(), 0);
 
 	master_nasid = get_nasid();
 	(void)get_console_nasid();
-#ifndef CONFIG_IA64_SGI_SN1
-	{
-		extern nasid_t get_master_baseio_nasid(void);
-		(void)get_master_baseio_nasid();
-	}
-#endif
+	(void)get_master_baseio_nasid();
 
 	status = ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, &drift);
 	if (status != 0 || ticks_per_sec < 100000) {
@@ -261,26 +277,12 @@
 	else
 		sn_rtc_cycles_per_second = ticks_per_sec;
 
-#ifdef CONFIG_IA64_SGI_SN1
-	/* PROM has wrong value on SN1 */
-	sn_rtc_cycles_per_second = 990177;
-#endif
-	sn_rtc_usec_per_cyc = ((1000000UL<<IA64_USEC_PER_CYC_SHIFT)
-			       + sn_rtc_cycles_per_second/2) / sn_rtc_cycles_per_second;
-		
-	for (i=0;i<NR_CPUS;i++)
-		_sn_irq_desc[i] = _irq_desc;
-
 	platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_PCE_VECTOR;
 
 
 	if ( IS_RUNNING_ON_SIMULATOR() )
 	{
-#ifdef CONFIG_IA64_SGI_SN2
 		master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
-#else
-		master_node_bedrock_address = (u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
-#endif
 		printk(KERN_DEBUG "sn_setup: setting master_node_bedrock_address to 0x%lx\n",
 		       master_node_bedrock_address);
 	}
@@ -296,6 +298,12 @@
 	 */
 	sn_init_pdas(cmdline_p);
 
+	/*
+	 * Check for WARs.
+	 */
+	sn_check_for_wars();
+
+	ia64_mark_idle = &snidle;
 
 	/* 
 	 * For the bootcpu, we do this here. All other cpus will make the
@@ -303,16 +311,12 @@
 	 */
 	sn_cpu_init();
 
-
 #ifdef CONFIG_SMP
 	init_smp_config();
 #endif
 	screen_info = sn_screen_info;
 
-	/*
-	 * Turn off "floating-point assist fault" warnings by default.
-	 */
-	current->thread.flags |= IA64_THREAD_FPEMU_NOPRINT;
+	sn_timer_init();
 }
 
 /**
@@ -332,19 +336,16 @@
 	if ((PDAADDR&~PAGE_MASK)+sizeof(pda_t) > PAGE_SIZE)
 		panic("overflow of cpu_data page");
 
+	memset(pda.cnodeid_to_nasid_table, -1, sizeof(pda.cnodeid_to_nasid_table));
+	for (cnode=0; cnode<numnodes; cnode++)
+		pda.cnodeid_to_nasid_table[cnode] = pxm_to_nasid(nid_to_pxm_map[cnode]);
+
         /*
          * Allocate & initalize the nodepda for each node.
          */
         for (cnode=0; cnode < numnodes; cnode++) {
 		nodepdaindr[cnode] = alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
 		memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
-
-#if defined(CONFIG_IA64_SGI_SN1)
-		Synergy_da_indr[cnode * 2] = (synergy_da_t *) alloc_bootmem_node(NODE_DATA(cnode), sizeof(synergy_da_t));
-		Synergy_da_indr[cnode * 2 + 1] = (synergy_da_t *) alloc_bootmem_node(NODE_DATA(cnode), sizeof(synergy_da_t));
-		memset(Synergy_da_indr[cnode * 2], 0, sizeof(synergy_da_t));
-		memset(Synergy_da_indr[cnode * 2 + 1], 0, sizeof(synergy_da_t));
-#endif
         }
 
 	/*
@@ -381,7 +382,7 @@
 	int	cpuphyid;
 	int	nasid;
 	int	slice;
-	int	cnode;
+	int	cnode, i;
 
 	/*
 	 * The boot cpu makes this call again after platform initialization is
@@ -402,38 +403,33 @@
 	memset(&pda, 0, sizeof(pda));
 	pda.p_nodepda = nodepdaindr[cnode];
 	pda.led_address = (typeof(pda.led_address)) (LED0 + (slice<<LED_CPU_SHIFT));
-#ifdef LED_WAR
-	pda.led_address = (typeof(pda.led_address)) (LED0 + (slice<<(LED_CPU_SHIFT-1))); /* temp til L1 firmware fixed */
-#endif
 	pda.led_state = LED_ALWAYS_SET;
 	pda.hb_count = HZ/2;
 	pda.hb_state = 0;
 	pda.idle_flag = 0;
+	pda.shub_1_1_found = shub_1_1_found;
 	
+	memset(pda.cnodeid_to_nasid_table, -1, sizeof(pda.cnodeid_to_nasid_table));
+	for (i=0; i<numnodes; i++)
+		pda.cnodeid_to_nasid_table[i] = pxm_to_nasid(nid_to_pxm_map[i]);
+
 	if (local_node_data->active_cpu_count == 1)
 		nodepda->node_first_cpu = cpuid;
 
-#ifdef CONFIG_IA64_SGI_SN1
-	{
-		int	synergy;
-		synergy = cpu_physical_id_to_synergy(cpuphyid);
-		pda.p_subnodepda = &nodepdaindr[cnode]->snpda[synergy];
-	}
-#endif
 
-#ifdef CONFIG_IA64_SGI_SN2
 
 	/*
 	 * We must use different memory allocators for first cpu (bootmem 
 	 * allocator) than for the other cpus (regular allocator).
 	 */
 	if (cpuid == 0)
-		irqpdaindr[cpuid] = alloc_bootmem_node(NODE_DATA(cpuid_to_cnodeid(cpuid)),sizeof(irqpda_t));
-	else
-		irqpdaindr[cpuid] = page_address(alloc_pages_node(local_cnodeid(), GFP_KERNEL, get_order(sizeof(irqpda_t))));
+		irqpdaindr = alloc_bootmem_node(NODE_DATA(cpuid_to_cnodeid(cpuid)),sizeof(irqpda_t));
 
-	memset(irqpdaindr[cpuid], 0, sizeof(irqpda_t));
-	pda.p_irqpda = irqpdaindr[cpuid];
+	memset(irqpdaindr, 0, sizeof(irqpda_t));
+	irqpdaindr->irq_flags[SGI_PCIBR_ERROR] = SN2_IRQ_SHARED;
+	irqpdaindr->irq_flags[SGI_PCIBR_ERROR] |= SN2_IRQ_RESERVED;
+	irqpdaindr->irq_flags[SGI_II_ERROR] = SN2_IRQ_SHARED;
+	irqpdaindr->irq_flags[SGI_II_ERROR] |= SN2_IRQ_RESERVED;
 
 	pda.pio_write_status_addr = (volatile unsigned long *)
 			LOCAL_MMR_ADDR((slice < 2 ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1 ) );
@@ -442,253 +438,9 @@
 
 	if (nodepda->node_first_cpu == cpuid) {
 		int	buddy_nasid;
-		buddy_nasid = cnodeid_to_nasid(local_cnodeid() == numnodes-1 ? 0 : local_cnodeid()+ 1);
+		buddy_nasid = cnodeid_to_nasid(numa_node_id() == numnodes-1 ? 0 : numa_node_id()+ 1);
 		pda.pio_shub_war_cam_addr = (volatile unsigned long*)GLOBAL_MMR_ADDR(nasid, SH_PI_CAM_CONTROL);
 	}
 
-#ifdef BRINGUP2
-	/*
-	 * Zero out the counters used for counting MCAs
-	 *   ZZZZZ temp
-	 */
-	{
-		long	*p;
-		p = (long*)LOCAL_MMR_ADDR(SH_XN_IILB_LB_CMP_ENABLE0);
-		*p = 0;
-		p = (long*)LOCAL_MMR_ADDR(SH_XN_IILB_LB_CMP_ENABLE1);
-		*p = 0;
-	}
-
-#endif
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN1
-	pda.bedrock_rev_id = (volatile unsigned long *) LOCAL_HUB(LB_REV_ID);
-	if (cpuid_to_synergy(cpuid))
-		/* CPU B */
-		pda.pio_write_status_addr = (volatile unsigned long *) GBL_PERF_B_ADDR;
-	else
-		/* CPU A */
-		pda.pio_write_status_addr = (volatile unsigned long *) GBL_PERF_A_ADDR;
-#endif
-
-
 	bte_init_cpu();
 }
-
-
-/**
- * cnodeid_to_cpuid - convert a cnode to a cpuid of a cpu on the node.
- * @cnode: node to get a cpuid from
- *	
- * Returns -1 if no cpus exist on the node.
- * NOTE:BRINGUP ZZZ This is NOT a good way to find cpus on the node.
- * Need a better way!!
- */
-int
-cnodeid_to_cpuid(int cnode) {
-	int cpu;
-
-	for (cpu = 0; cpu < smp_num_cpus; cpu++)
-		if (cpuid_to_cnodeid(cpu) == cnode)
-			break;
-
-	if (cpu == smp_num_cpus) 
-		cpu = -1;
-
-	return cpu;
-}
-
-/**
- * get_cycles - return a non-decreasing timestamp
- *
- * On SN, we use an RTC read for this function
- */
-cycles_t
-get_cycles (void)
-{
-	return GET_RTC_COUNTER();
-}
-
-/**
- * gettimeoffset - number of usecs elapsed since &xtime was last updated
- *
- * This function is used by do_gettimeofday() to determine the number
- * of usecs that have elapsed since the last update to &xtime.  On SN
- * this is accomplished using the RTC built in to each Hub chip; each
- * is guaranteed to be synchronized by the PROM, so a local read will
- * suffice (get_cycles() does this for us).  A snapshot of the RTC value
- * is taken on every timer interrupt and this function more or less
- * subtracts that snapshot value from the current value.
- *
- * Note that if a lot of processing was done during the last timer
- * interrupt then &xtime may be some number of jiffies out of date.
- * This function must account for that.
- */
-unsigned long
-gettimeoffset(void)
-{
-	unsigned long current_rtc_val, local_last_rtc_val;
-	unsigned long usec;
-
-	local_last_rtc_val = last_rtc_val;
-	current_rtc_val = get_cycles();
-	usec = last_itc_lost_usec;
-
-	/* If the RTC has wrapped around, compensate */
-	if (unlikely(current_rtc_val < local_last_rtc_val)) {
-		printk(KERN_NOTICE "RTC wrapped cpu:%d current:0x%lx last:0x%lx\n",
-				smp_processor_id(), current_rtc_val,
-				local_last_rtc_val);
-		current_rtc_val += RTC_MASK;
-	}
-
-	usec += ((current_rtc_val - local_last_rtc_val)*sn_rtc_usec_per_cyc) >> 
-		IA64_USEC_PER_CYC_SHIFT;
-
-	/*
-	 * usec is the number of microseconds into the current clock interval. Every
-	 * clock tick, xtime is advanced by "tick" microseconds. If "usec"
-	 * is allowed to get larger than "tick", the time value returned by gettimeofday
-	 * will go backward.
-	 */
-	if (usec >= tick)
-		usec = tick-1;
-
-	return usec;
-}
-
-#ifdef II_PRTE_TLB_WAR
-long iiprt_lock[16*64] __cacheline_aligned; /* allow for NASIDs up to 64 */
-#endif
-
-#ifdef BUS_INT_WAR
-
-#include <asm/hw_irq.h>
-#include <asm/sn/pda.h>
-
-void ia64_handle_irq (ia64_vector vector, struct pt_regs *regs);
-
-static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
-
-#define IRQCPU(irq)	((irq)>>8)
-
-void
-sn_add_polled_interrupt(int irq, int interval)
-{
-	unsigned long flags, irq_cnt;
-	sn_poll_entry_t	*irq_list;
-
-	irq_list = pdacpu(IRQCPU(irq)).pda_poll_entries;;
-
-	spin_lock_irqsave(&irq_lock, flags);
-	irq_cnt = pdacpu(IRQCPU(irq)).pda_poll_entry_count;
-	irq_list[irq_cnt].irq = irq;
-	irq_list[irq_cnt].interval = interval;
-	irq_list[irq_cnt].tick = interval;
-	pdacpu(IRQCPU(irq)).pda_poll_entry_count++;
-	spin_unlock_irqrestore(&irq_lock, flags);
-
-
-}
-
-void
-sn_delete_polled_interrupt(int irq)
-{
-	unsigned long flags, i, irq_cnt;
-	sn_poll_entry_t	*irq_list;
-
-	irq_list = pdacpu(IRQCPU(irq)).pda_poll_entries;
-
-	spin_lock_irqsave(&irq_lock, flags);
-	irq_cnt = pdacpu(IRQCPU(irq)).pda_poll_entry_count;
-	for (i=0; i<irq_cnt; i++) {
-		if (irq_list[i].irq == irq) {
-			irq_list[i] = irq_list[irq_cnt-1];
-			pdacpu(IRQCPU(irq)).pda_poll_entry_count--;
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&irq_lock, flags);
-}
-
-long sn_int_poll_ticks=50;
-
-void
-sn_irq_poll(int cpu, int reason) 
-{
-	unsigned long flags, i;
-	sn_poll_entry_t	*irq_list;
-
-
-#ifdef CONFIG_SHUB_1_0_SPECIFIC
-	ia64_handle_irq(IA64_IPI_VECTOR, 0);
-#else
-	if (sn_int_poll_ticks == 0)
-		return;
-#endif
-	irq_list = pda.pda_poll_entries;
-
-	for (i=0; i<pda.pda_poll_entry_count; i++, irq_list++) {
-		if (--irq_list->tick <= 0) {
-#ifdef CONFIG_SHUB_1_0_SPECIFIC
-			irq_list->tick = irq_list->interval;
-#else
-			irq_list->tick = sn_int_poll_ticks;
-#endif
-			local_irq_save(flags);
-			ia64_handle_irq(irq_to_vector(irq_list->irq), 0);
-			local_irq_restore(flags);
-		}
-	}
-}	
-
-#define PROCFILENAME	"sn_int_poll_ticks"
-
-static struct proc_dir_entry *proc_op;
-
-
-static int
-read_proc(char *buffer, char **start, off_t off, int count, int *eof, void *data)
-{
-	int len = 0;
-
-	len += sprintf(buffer + len, "Poll hack: interval %ld ticks\n", sn_int_poll_ticks);
-
-	if (len <= off+count) *eof = 1;
-	*start = buffer + off;
-	len   -= off;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
-}
-
-static int
-write_proc (struct file *file, const char *userbuf, unsigned long count, void *data)
-{
-       extern long atoi(char *);
-       char        buf[80];
-
-       if (copy_from_user(buf, userbuf, count < sizeof(buf) ? count : sizeof(buf)))
-           return -EFAULT;
-
-       sn_int_poll_ticks = atoi(buf);
-
-       return count;
-}
-
-
-int __init
-sn_poll_init(void)
-{
-	if ((proc_op = create_proc_entry(PROCFILENAME, 0644, NULL)) == NULL) {
-		printk("%s: unable to create proc entry", PROCFILENAME);
-		return -1;
-	}
-	proc_op->read_proc = read_proc;
-	proc_op->write_proc = write_proc;
-	return 0;
-}
-
-module_init(sn_poll_init);
-#endif
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/Makefile linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/Makefile	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/Makefile	1969-12-31 16:00:00.000000000 -0800
@@ -1,47 +0,0 @@
-#
-# arch/ia64/sn/kernel/sn1/Makefile
-#
-# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify it 
-# under the terms of version 2 of the GNU General Public License 
-# as published by the Free Software Foundation.
-# 
-# This program is distributed in the hope that it would be useful, but 
-# WITHOUT ANY WARRANTY; without even the implied warranty of 
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
-# 
-# Further, this software is distributed without any warranty that it is 
-# free of the rightful claim of any third person regarding infringement 
-# or the like.  Any license provided herein, whether implied or 
-# otherwise, applies only to this software file.  Patent licenses, if 
-# any, provided herein do not apply to combinations of this program with 
-# other software, or any other product whatsoever.
-# 
-# You should have received a copy of the GNU General Public 
-# License along with this program; if not, write the Free Software 
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
-# 
-# Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
-# Mountain View, CA  94043, or:
-# 
-# http://www.sgi.com 
-# 
-# For further information regarding this notice, see: 
-# 
-# http://oss.sgi.com/projects/GenInfo/NoticeExplan
-#
-
-
-EXTRA_CFLAGS    := -DLITTLE_ENDIAN
-
-.S.s:
-	$(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $<
-.S.o:
-	$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
-
-O_TARGET        = sn1.o
-
-obj-y          = cache.o error.o iomv.o synergy.o sn1_smp.o
-
-include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/cache.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/cache.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/cache.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/cache.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,81 +0,0 @@
-/*
- * 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- * 
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- *
- */
-
-#include <linux/kernel.h>
-#include <asm/pgalloc.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/synergy.h>
-#include <asm/delay.h>
-
-#ifndef MB
-#define	MB	(1024*1024)
-#endif
-
-/*
- * Lock for protecting SYN_TAG_DISABLE_WAY.
- * Consider making this a per-FSB lock. 
- */
-static spinlock_t flush_lock = SPIN_LOCK_UNLOCKED;
-
-/**
- * sn_flush_all_caches - flush a range of addresses from all caches (incl. L4)
- * @flush_addr: identity mapped region 7 address to start flushing
- * @bytes: number of bytes to flush
- *
- * Flush a range of addresses from all caches including L4.  All addresses 
- * fully or partially contained within @flush_addr to @flush_addr + @bytes 
- * are flushed from the all caches.
- */
-void
-sn_flush_all_caches(long flush_addr, long bytes)
-{
-	ulong 	addr, baddr, eaddr, bitbucket;
-	int	way, alias;
-
-	/*
-	 * Because of the way synergy implements "fc", this flushes the
-	 * data from all caches on all cpus & L4's on OTHER FSBs. It also
-	 * flushes both cpus on the local FSB. It does NOT flush it from 
-	 * the local FSB.
-	 */
-	flush_icache_range(flush_addr, flush_addr+bytes);
-
-	/*
-	 * Memory DIMMs are a minimum of 256MB and start on 256MB
-	 * boundaries. Convert the start address to an address
-	 * that is between +0MB & +128 of the same DIMM. 
-	 * Then add 8MB to skip the uncached MinState areas if the address
-	 * is on the master node.
-	 */
-	if (bytes > SYNERGY_L4_BYTES_PER_WAY)
-		bytes = SYNERGY_L4_BYTES_PER_WAY;
-	baddr = TO_NODE(smp_physical_node_id(), PAGE_OFFSET + (flush_addr & (128*MB-1)) + 8*MB); 
-	eaddr = (baddr+bytes+SYNERGY_BLOCK_SIZE-1) & ~(SYNERGY_BLOCK_SIZE-1);
-	baddr = baddr & ~(SYNERGY_BLOCK_SIZE-1);
-
-	/*
-	 * Now flush the local synergy.
-	 */
-	spin_lock(&flush_lock);
-	for(way=0; way<SYNERGY_L4_WAYS; way++) {
-		WRITE_LOCAL_SYNERGY_REG(SYN_TAG_DISABLE_WAY, 0xffL ^ (1L<<way));
-		mb();
-		for(alias=0; alias < 9; alias++)
-			for(addr=baddr; addr<eaddr; addr+=SYNERGY_BLOCK_SIZE)
-				bitbucket = *(volatile ulong *)(addr+alias*8*MB);
-		mb();
-	}
-	WRITE_LOCAL_SYNERGY_REG(SYN_TAG_DISABLE_WAY, 0);
-	spin_unlock(&flush_lock);
-
-}
-
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/error.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/error.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/error.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/error.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,187 +0,0 @@
-/*
- * SN1 Platform specific error Support
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/ptrace.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/smp.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-
-/**
- * snia_error_intr_handler - handle SN specific error interrupts
- * @irq: error interrupt received
- * @devid: device causing the interrupt
- * @pt_regs: saved register state
- *
- * This routine is called when certain interrupts occur on SN systems.
- * It will either recover from the situations that caused the interrupt
- * or panic.
- */
-void
-snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs)
-{
-	unsigned long long intpend_val;
-	unsigned long long bit;
-
-	switch (irq) {
-	case SGI_UART_IRQ:
-		/*
-		 * This isn't really an error interrupt.  We're just
-		 * here because we have to do something with them.
-		 * This is probably wrong, and this code will be
-		 * removed.
-		 */
-		intpend_val = LOCAL_HUB_L(PI_INT_PEND0);
-		if ( (bit = ~(1L<<GFX_INTR_A)) ==
-			(intpend_val & ~(1L<<GFX_INTR_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<GFX_INTR_B)) ==
-			(intpend_val & ~(1L<<GFX_INTR_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<PG_MIG_INTR)) ==
-			(intpend_val & ~(1L<<PG_MIG_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<UART_INTR)) ==
-			(intpend_val & ~(1L<<UART_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<CC_PEND_A)) ==
-			(intpend_val & ~(1L<<CC_PEND_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<CC_PEND_B)) ==
-			(intpend_val & ~(1L<<CC_PEND_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		printk("Received SGI_UART_IRQ (65), but no intpend0 bits were set???\n");
-		return;
-	case SGI_HUB_ERROR_IRQ:
-		/*
-		 * These are mostly error interrupts of various
-		 * sorts.  We need to do more than panic here, but
-		 * what the heck, this is bring up.
-		 */
-		intpend_val = LOCAL_HUB_L(PI_INT_PEND1);
-		
-		if ( (bit = ~(1L<<XB_ERROR)) ==
-			(intpend_val & ~(1L<<XB_ERROR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED XB_ERROR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<LB_ERROR)) ==
-			(intpend_val & ~(1L<<LB_ERROR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED LB_ERROR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NACK_INT_A)) ==
-			(intpend_val & ~(1L<<NACK_INT_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NACK_INT_A on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NACK_INT_B)) ==
-			(intpend_val & ~(1L<<NACK_INT_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NACK_INT_B on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<CLK_ERR_INTR)) ==
-			(intpend_val & ~(1L<<CLK_ERR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED CLK_ERR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<COR_ERR_INTR_A)) ==
-			(intpend_val & ~(1L<<COR_ERR_INTR_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED COR_ERR_INTR_A on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<COR_ERR_INTR_B)) ==
-			(intpend_val & ~(1L<<COR_ERR_INTR_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED COR_ERR_INTR_B on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<MD_COR_ERR_INTR)) ==
-			(intpend_val & ~(1L<<MD_COR_ERR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED MD_COR_ERR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NI_ERROR_INTR)) ==
-			(intpend_val & ~(1L<<NI_ERROR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NI_ERROR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<MSC_PANIC_INTR)) ==
-			(intpend_val & ~(1L<<MSC_PANIC_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED MSC_PANIC_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		printk("Received SGI_XB_ERROR_IRQ (182) but no intpend1 bits are set???\n");
-		return;
-	default:
-		printk("Received invalid irq in snia_error_intr_handler()\n");
-	}
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/iomv.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/iomv.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/iomv.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/iomv.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,65 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/sn/simulator.h>
-#include <asm/delay.h>
-#include <asm/sn/pda.h>
-
-/**
- * sn_io_addr - convert an in/out port to an i/o address
- * @port: port to convert
- *
- * Legacy in/out instructions are converted to ld/st instructions
- * on IA64.  This routine will convert a port number into a valid 
- * SN i/o address.  Used by sn_in*() and sn_out*().
- */
-void *
-sn_io_addr(unsigned long port)
-{
-	if (!IS_RUNNING_ON_SIMULATOR()) {
-		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
-	} else {
-		unsigned long io_base;
-		unsigned long addr;
- 
-		/*
- 		 * word align port, but need more than 10 bits
- 		 * for accessing registers in bedrock local block
- 		 * (so we don't do port&0xfff)
- 		 */
-		if ((port >= 0x1f0 && port <= 0x1f7) ||
-			port == 0x3f6 || port == 0x3f7) {
-			io_base = __IA64_UNCACHED_OFFSET | 0x00000FFFFC000000;
-			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
-		} else {
-			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
-		}
-		return(void *) addr;
-	}
-}
-
-/**
- * sn1_mmiob - I/O space memory barrier
- *
- * Acts as a memory mapped I/O barrier for platforms that queue writes to 
- * I/O space.  This ensures that subsequent writes to I/O space arrive after
- * all previous writes.  For most ia64 platforms, this is a simple
- * 'mf.a' instruction.  For other platforms, mmiob() may have to read
- * a chipset register to ensure ordering.
- *
- * On SN1, we wait for the PIO_WRITE_STATUS Bedrock register to clear.
- */
-void
-sn1_mmiob (void)
-{
-	(volatile unsigned long) (*pda.bedrock_rev_id);
-	while (!(volatile unsigned long) (*pda.pio_write_status_addr))
-		udelay(5);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/sn1_smp.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/sn1_smp.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/sn1_smp.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/sn1_smp.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,476 +0,0 @@
-/*
- * SN1 Platform specific SMP Support
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/threads.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mmzone.h>
-
-#include <asm/processor.h>
-#include <asm/irq.h>
-#include <asm/sal.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/hw_irq.h>
-#include <asm/current.h>
-#include <asm/delay.h>
-#include <asm/sn/sn_cpuid.h>
-
-/*
- * The following structure is used to pass params thru smp_call_function
- * to other cpus for flushing TLB ranges.
- */
-typedef struct {
-	union {
-		struct {
-			unsigned long	start;
-			unsigned long	end;
-			unsigned long	nbits;
-			unsigned int	rid;
-			atomic_t	unfinished_count;
-		} ptc;
-		char pad[SMP_CACHE_BYTES];
-	};
-} ptc_params_t;
-
-#define NUMPTC	512
-
-static ptc_params_t	ptcParamArray[NUMPTC] __attribute__((__aligned__(128)));
-
-/* use separate cache lines on ptcParamsNextByCpu to avoid false sharing */
-static ptc_params_t	*ptcParamsNextByCpu[NR_CPUS*16] __attribute__((__aligned__(128)));
-static volatile ptc_params_t	*ptcParamsEmpty __cacheline_aligned;
-
-/*REFERENCED*/
-static spinlock_t ptcParamsLock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
-
-static int ptcInit = 0;
-#ifdef PTCDEBUG
-static int ptcParamsAllBusy = 0;		/* debugging/statistics */
-static int ptcCountBacklog = 0;
-static int ptcBacklog[NUMPTC+1];
-static char ptcParamsCounts[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-static char ptcParamsResults[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-#endif
-
-/*
- * Make smp_send_flush_tlbsmp_send_flush_tlb() a weak reference,
- * so that we get a clean compile with the ia64 patch without the
- * actual SN1 specific code in arch/ia64/kernel/smp.c.
- */
-extern void smp_send_flush_tlb (void) __attribute((weak));
-
-/*
- * The following table/struct is for remembering PTC coherency domains. It
- * is also used to translate sapicid into cpuids. We dont want to start 
- * cpus unless we know their cache domain.
- */
-#ifdef PTC_NOTYET
-sn_sapicid_info_t	sn_sapicid_info[NR_CPUS];
-#endif
-
-/**
- * sn1_ptc_l_range - purge local translation cache
- * @start: start of virtual address range
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Purges the range specified from the local processor's translation cache
- * (as opposed to the translation registers).  Note that more than the specified
- * range *may* be cleared from the cache by some processors.
- *
- * This is probably not good enough, but I don't want to try to make it better 
- * until I get some statistics on a running system. At a minimum, we should only 
- * send IPIs to 1 processor in each TLB domain & have it issue a ptc.g on it's 
- * own FSB. Also, we only have to serialize per FSB, not globally.
- *
- * More likely, we will have to do some work to reduce the frequency of calls to
- * this routine.
- */
-static inline void
-sn1_ptc_l_range(unsigned long start, unsigned long end, unsigned long nbits)
-{
-	do {
-		__asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory");
-		start += (1UL << nbits);
-	} while (start < end);
-	ia64_srlz_d();
-}
-
-/**
- * sn1_received_flush_tlb - cpu tlb flush routine
- *
- * Flushes the TLB of a given processor.
- */
-void
-sn1_received_flush_tlb(void)
-{
-	unsigned long	start, end, nbits;
-	unsigned int	rid, saved_rid;
-	int		cpu = smp_processor_id();
-	int		result;
-	ptc_params_t	*ptcParams;
-
-	ptcParams = ptcParamsNextByCpu[cpu*16];
-	if (ptcParams == ptcParamsEmpty)
-		return;
-
-	do {
-		start = ptcParams->ptc.start;
-		saved_rid = (unsigned int) ia64_get_rr(start);
-		end = ptcParams->ptc.end;
-		nbits = ptcParams->ptc.nbits;
-		rid = ptcParams->ptc.rid;
-
-		if (saved_rid != rid) {
-			ia64_set_rr(start, (unsigned long)rid);
-			ia64_srlz_d();
-		}
-
-		sn1_ptc_l_range(start, end, nbits);
-
-		if (saved_rid != rid) 
-			ia64_set_rr(start, (unsigned long)saved_rid);
-
-		ia64_srlz_i();
-
-		result = atomic_dec(&ptcParams->ptc.unfinished_count);
-#ifdef PTCDEBUG
-		{
-		    int i = ptcParams-&ptcParamArray[0];
-		    ptcParamsResults[cpu][i] = (char) result;
-		    ptcParamsCounts[cpu][i]++;
-		}
-#endif /* PTCDEBUG */
-
-		if (++ptcParams == &ptcParamArray[NUMPTC])
-			ptcParams = &ptcParamArray[0];
-
-	} while (ptcParams != ptcParamsEmpty);
-
-	ptcParamsNextByCpu[cpu*16] = ptcParams;
-}
-
-/**
- * sn1_global_tlb_purge - flush a translation cache range on all processors
- * @start: start of virtual address range to flush
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Flushes the translation cache of all processors from @start to @end.
- */
-void
-sn1_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
-{
-	ptc_params_t	*params;
-	ptc_params_t	*next;
-	unsigned long	irqflags;
-#ifdef PTCDEBUG
-	ptc_params_t	*nextnext;
-	int		backlog = 0;
-#endif
-
-	if (smp_num_cpus == 1) {
-		sn1_ptc_l_range(start, end, nbits);
-		return;
-	}
-
-	if (in_interrupt()) {
-		/*
-		 *  If at interrupt level and cannot get spinlock, 
-		 *  then do something useful by flushing own tlbflush queue
-		 *  so as to avoid a possible deadlock.
-		 */
-		while (!spin_trylock(&ptcParamsLock)) {
-			local_irq_save(irqflags);
-			sn1_received_flush_tlb();
-			local_irq_restore(irqflags);
-			udelay(10);	/* take it easier on the bus */	
-		}
-	} else {
-		spin_lock(&ptcParamsLock);
-	}
-
-	if (!ptcInit) {
-		int cpu;
-		ptcInit = 1;
-		memset(ptcParamArray, 0, sizeof(ptcParamArray));
-		ptcParamsEmpty = &ptcParamArray[0];
-		for (cpu=0; cpu<NR_CPUS; cpu++)
-			ptcParamsNextByCpu[cpu*16] = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-		memset(ptcBacklog, 0, sizeof(ptcBacklog));
-		memset(ptcParamsCounts, 0, sizeof(ptcParamsCounts));
-		memset(ptcParamsResults, 0, sizeof(ptcParamsResults));
-#endif	/* PTCDEBUG */
-	}
-
-	params = (ptc_params_t *) ptcParamsEmpty;
-	next = (ptc_params_t *) ptcParamsEmpty + 1;
-	if (next == &ptcParamArray[NUMPTC])
-		next = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-	nextnext = next + 1;
-	if (nextnext == &ptcParamArray[NUMPTC])
-		nextnext = &ptcParamArray[0];
-
-	if (ptcCountBacklog) {
-		/* quick count of backlog */
-		ptc_params_t *ptr;
-
-		/* check the current pointer to the beginning */
-		ptr = params;
-		while(--ptr >= &ptcParamArray[0]) {
-			if (atomic_read(&ptr->ptc.unfinished_count) == 0)
-				break;
-			++backlog;
-		}
-
-		if (backlog) {
-			/* check the end of the array */
-			ptr = &ptcParamArray[NUMPTC];
-			while (--ptr > params) {
-				if (atomic_read(&ptr->ptc.unfinished_count) == 0)
-					break;
-				++backlog;
-			}
-		}
-		ptcBacklog[backlog]++;
-	}
-#endif	/* PTCDEBUG */
-
-	/* wait for the next entry to clear...should be rare */
-	if (atomic_read(&next->ptc.unfinished_count) > 0) {
-#ifdef PTCDEBUG
-		ptcParamsAllBusy++;
-
-		if (atomic_read(&nextnext->ptc.unfinished_count) == 0) {
-		    if (atomic_read(&next->ptc.unfinished_count) > 0) {
-			panic("\nnonzero next zero nextnext %lx %lx\n",
-			    (long)next, (long)nextnext);
-		    }
-		}
-#endif
-
-		/* it could be this cpu that is behind */
-		local_irq_save(irqflags);
-		sn1_received_flush_tlb();
-		local_irq_restore(irqflags);
-
-		/* now we know it's not this cpu, so just wait */
-		while (atomic_read(&next->ptc.unfinished_count) > 0) {
-			barrier();
-		}
-	}
-
-	params->ptc.start = start;
-	params->ptc.end = end;
-	params->ptc.nbits = nbits;
-	params->ptc.rid = (unsigned int) ia64_get_rr(start);
-	atomic_set(&params->ptc.unfinished_count, smp_num_cpus);
-
-	/* The atomic_set above can hit memory *after* the update
-	 * to ptcParamsEmpty below, which opens a timing window
-	 * that other cpus can squeeze into!
-	 */
-	mb();
-
-	/* everything is ready to process:
-	 *	-- global lock is held
-	 *	-- new entry + 1 is free
-	 *	-- new entry is set up
-	 * so now:
-	 *	-- update the global next pointer
-	 *	-- unlock the global lock
-	 *	-- send IPI to notify other cpus
-	 *	-- process the data ourselves
-	 */
-	ptcParamsEmpty = next;
-	spin_unlock(&ptcParamsLock);
-	smp_send_flush_tlb();
-
-	local_irq_save(irqflags);
-	sn1_received_flush_tlb();
-	local_irq_restore(irqflags);
-
-	/* Currently we don't think global TLB purges need to be atomic.
-	 * All CPUs get sent IPIs, so if they haven't done the purge,
-	 * they're busy with interrupts that are at the IPI level, which is
-	 * priority 15.  We're asserting that any code at that level
-	 * shouldn't be using user TLB entries.  To change this to wait
-	 * for all the flushes to complete, enable the following code.
-	 */
-#if defined(SN1_SYNCHRONOUS_GLOBAL_TLB_PURGE) || defined(BUS_INT_WAR)
-	/* this code is not tested */
-	/* wait for the flush to complete */
-	while (atomic_read(&params->ptc.unfinished_count) > 0)
-		barrier();
-#endif
-}
-
-/**
- * sn_send_IPI_phys - send an IPI to a Nasid and slice
- * @physid: physical cpuid to receive the interrupt.
- * @vector: command to send
- * @delivery_mode: delivery mechanism
- *
- * Sends an IPI (interprocessor interrupt) to the processor specified by
- * @physid
- *
- * @delivery_mode can be one of the following
- *
- * %IA64_IPI_DM_INT - pend an interrupt
- * %IA64_IPI_DM_PMI - pend a PMI
- * %IA64_IPI_DM_NMI - pend an NMI
- * %IA64_IPI_DM_INIT - pend an INIT interrupt
- */
-void
-sn_send_IPI_phys(long physid, int vector, int delivery_mode)
-{
-	long		*p;
-	long		nasid, slice;
-
-	static int 	off[4] = {0x1800080, 0x1800088, 0x1a00080, 0x1a00088};
-
-#ifdef BUS_INT_WAR
-	if (vector != ap_wakeup_vector) {
-		return;
-	}
-#endif
-
-	nasid = cpu_physical_id_to_nasid(physid);
-        slice = cpu_physical_id_to_slice(physid);
-
-	p = (long*)(0xc0000a0000000000LL | (nasid<<33) | off[slice]);
-
-	mb();
-	*p = (delivery_mode << 8) | (vector & 0xff);
-}
-
-
-/**
- * sn1_send_IPI - send an IPI to a processor
- * @cpuid: target of the IPI
- * @vector: command to send
- * @delivery_mode: delivery mechanism
- * @redirect: redirect the IPI?
- *
- * Sends an IPI (interprocessor interrupt) to the processor specified by
- * @cpuid.  @delivery_mode can be one of the following
- *
- * %IA64_IPI_DM_INT - pend an interrupt
- * %IA64_IPI_DM_PMI - pend a PMI
- * %IA64_IPI_DM_NMI - pend an NMI
- * %IA64_IPI_DM_INIT - pend an INIT interrupt
- */
-void
-sn1_send_IPI(int cpuid, int vector, int delivery_mode, int redirect)
-{
-	long		physid;
-
-	physid = cpu_physical_id(cpuid);
-
-	sn_send_IPI_phys(physid, vector, delivery_mode);
-}
-#ifdef CONFIG_SMP
-
-#ifdef PTC_NOTYET
-static void __init
-process_sal_ptc_domain_info(ia64_sal_ptc_domain_info_t *di, int domain)
-{
-	ia64_sal_ptc_domain_proc_entry_t	*pe;
-	int 					i, sapicid, cpuid;
-
-	pe = __va(di->proc_list);
-	for (i=0; i<di->proc_count; i++, pe++) {
-		sapicid = id_eid_to_sapicid(pe->id, pe->eid);
-		cpuid = cpu_logical_id(sapicid);
-		sn_sapicid_info[cpuid].domain = domain;
-		sn_sapicid_info[cpuid].sapicid = sapicid;
-	}
-}
-
-
-static void __init
-process_sal_desc_ptc(ia64_sal_desc_ptc_t *ptc)
-{
-	ia64_sal_ptc_domain_info_t	*di;
-	int i;
-
-	di = __va(ptc->domain_info);
-	for (i=0; i<ptc->num_domains; i++, di++) {
-		process_sal_ptc_domain_info(di, i);	
-	}
-}
-#endif /* PTC_NOTYET */
-
-/**
- * init_sn1_smp_config - setup PTC domains per processor
- */
-void __init
-init_sn1_smp_config(void)
-{
-	if (!ia64_ptc_domain_info)  {
-		printk("SMP: Can't find PTC domain info. Forcing UP mode\n");
-		smp_num_cpus = 1;
-		return;
-	}
-
-#ifdef PTC_NOTYET
-	memset (sn_sapicid_info, -1, sizeof(sn_sapicid_info));
-	process_sal_desc_ptc(ia64_ptc_domain_info);
-#endif
-}
-
-#else /* CONFIG_SMP */
-
-void __init
-init_sn1_smp_config(void)
-{
-
-#ifdef PTC_NOTYET
-	sn_sapicid_info[0].sapicid = hard_smp_processor_id();
-#endif
-}
-
-#endif /* CONFIG_SMP */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/synergy.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/synergy.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn1/synergy.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn1/synergy.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,533 +0,0 @@
-/*
- * SN1 Platform specific synergy Support
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/proc_fs.h>
-
-#include <asm/ptrace.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/smp.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/sn1/synergy.h>
-#include <asm/sn/sndrv.h>
-
-int bit_pos_to_irq(int bit);
-void setclear_mask_b(int irq, int cpuid, int set);
-void setclear_mask_a(int irq, int cpuid, int set);
-void * kmalloc(size_t size, int flags);
-
-static int synergy_perf_initialized = 0;
-
-void
-synergy_intr_alloc(int bit, int cpuid) {
-	return;
-}
-
-int
-synergy_intr_connect(int bit, 
-		int cpuid)
-{
-	int irq;
-	unsigned is_b;
-
-	irq = bit_pos_to_irq(bit);
-
-	is_b = (cpuid_to_slice(cpuid)) & 1;
-	if (is_b) {
-		setclear_mask_b(irq,cpuid,1);
-		setclear_mask_a(irq,cpuid, 0);
-	} else {
-		setclear_mask_a(irq, cpuid, 1);
-		setclear_mask_b(irq, cpuid, 0);
-	}
-	return 0;
-}
-void
-setclear_mask_a(int irq, int cpuid, int set)
-{
-	int synergy;
-	int nasid;
-	int reg_num;
-	unsigned long mask;
-	unsigned long addr;
-	unsigned long reg;
-	unsigned long val;
-	int my_cnode, my_synergy;
-	int target_cnode, target_synergy;
-
-        /*
-         * Perform some idiot checks ..
-         */
-        if ( (irq < 0) || (irq > 255) ||
-                (cpuid < 0) || (cpuid > 512) ) {
-                printk("clear_mask_a: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
-		return;
-	}
-
-	target_cnode = cpuid_to_cnodeid(cpuid);
-	target_synergy = cpuid_to_synergy(cpuid);
-	my_cnode = cpuid_to_cnodeid(smp_processor_id());
-	my_synergy = cpuid_to_synergy(smp_processor_id());
-
-	reg_num = irq / 64;
-	mask = 1;
-	mask <<= (irq % 64);
-	switch (reg_num) {
-		case 0: 
-			reg = VEC_MASK0A;
-			addr = VEC_MASK0A_ADDR;
-			break;
-		case 1: 
-			reg = VEC_MASK1A;
-			addr = VEC_MASK1A_ADDR;
-			break;
-		case 2: 
-			reg = VEC_MASK2A;
-			addr = VEC_MASK2A_ADDR;
-			break;
-		case 3: 
-			reg = VEC_MASK3A;
-			addr = VEC_MASK3A_ADDR;
-			break;
-		default:
-			reg = addr = 0;
-			break;
-	}
-	if (my_cnode == target_cnode && my_synergy == target_synergy) {
-		// local synergy
-		val = READ_LOCAL_SYNERGY_REG(addr);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		WRITE_LOCAL_SYNERGY_REG(addr, val);
-		val = READ_LOCAL_SYNERGY_REG(addr);
-	} else { /* remote synergy */
-		synergy = cpuid_to_synergy(cpuid);
-		nasid = cpuid_to_nasid(cpuid);
-		val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
-	}
-}
-
-void
-setclear_mask_b(int irq, int cpuid, int set)
-{
-	int synergy;
-	int nasid;
-	int reg_num;
-	unsigned long mask;
-	unsigned long addr;
-	unsigned long reg;
-	unsigned long val;
-	int my_cnode, my_synergy;
-	int target_cnode, target_synergy;
-
-	/*
-	 * Perform some idiot checks ..
-	 */
-	if ( (irq < 0) || (irq > 255) ||
-		(cpuid < 0) || (cpuid > 512) ) {
-		printk("clear_mask_b: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
-		return;
-	}
-
-	target_cnode = cpuid_to_cnodeid(cpuid);
-	target_synergy = cpuid_to_synergy(cpuid);
-	my_cnode = cpuid_to_cnodeid(smp_processor_id());
-	my_synergy = cpuid_to_synergy(smp_processor_id());
-
-	reg_num = irq / 64;
-	mask = 1;
-	mask <<= (irq % 64);
-	switch (reg_num) {
-		case 0: 
-			reg = VEC_MASK0B;
-			addr = VEC_MASK0B_ADDR;
-			break;
-		case 1: 
-			reg = VEC_MASK1B;
-			addr = VEC_MASK1B_ADDR;
-			break;
-		case 2: 
-			reg = VEC_MASK2B;
-			addr = VEC_MASK2B_ADDR;
-			break;
-		case 3: 
-			reg = VEC_MASK3B;
-			addr = VEC_MASK3B_ADDR;
-			break;
-		default:
-			reg = addr = 0;
-			break;
-	}
-	if (my_cnode == target_cnode && my_synergy == target_synergy) {
-		// local synergy
-		val = READ_LOCAL_SYNERGY_REG(addr);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		WRITE_LOCAL_SYNERGY_REG(addr, val);
-		val = READ_LOCAL_SYNERGY_REG(addr);
-	} else { /* remote synergy */
-		synergy = cpuid_to_synergy(cpuid);
-		nasid = cpuid_to_nasid(cpuid);
-		val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
-	}
-}
-
-/*
- * Synergy perf stats. Multiplexed via timer_interrupt.
- */
-
-static int
-synergy_perf_append(uint64_t modesel)
-{
-	int		cnode;
-	nodepda_t       *npdap;
-	synergy_perf_t	*p;
-	int		checked = 0;
-	int		err = 0;
-	unsigned long	flags;
-
-	/* bit 45 is enable */
-	modesel |= (1UL << 45);
-
-	for (cnode=0; cnode < numnodes; cnode++) {
-		/* for each node, insert a new synergy_perf entry */
-		if ((npdap = NODEPDA(cnode)) == NULL) {
-			printk("synergy_perf_append: cnode=%d NODEPDA(cnode)==NULL, nodepda=%p\n", cnode, (void *)nodepda);
-			continue;
-		}
-
-		if (npdap->synergy_perf_enabled) {
-			/* user must disable counting to append new events */
-			err = -EBUSY;
-			break;
-		}
-
-		if (!checked && npdap->synergy_perf_data != NULL) {
-			checked = 1;
-			for (p = npdap->synergy_perf_first; ;) {
-				if (p->modesel == modesel)
-					return 0; /* event already registered */
-				if ((p = p->next) == npdap->synergy_perf_first)
-					break;
-			}
-		}
-
-		/* XX use kmem_alloc_node() when it is implemented */
-		p = (synergy_perf_t *)kmalloc(sizeof(synergy_perf_t), GFP_KERNEL);
-		if ((((uint64_t)p) & 7UL) != 0)
-			BUG(); /* bad alignment */
-		if (p == NULL) {
-			err = -ENOMEM;
-			break;
-		}
-		else {
-			memset(p, 0, sizeof(synergy_perf_t));
-			p->modesel = modesel;
-
-			spin_lock_irqsave(&npdap->synergy_perf_lock, flags);
-			if (npdap->synergy_perf_data == NULL) {
-				/* circular list */
-				p->next = p;
-				npdap->synergy_perf_first = p;
-				npdap->synergy_perf_data = p;
-			}
-			else {
-				p->next = npdap->synergy_perf_data->next;
-				npdap->synergy_perf_data->next = p;
-			}
-			spin_unlock_irqrestore(&npdap->synergy_perf_lock, flags);
-		}
-	}
-
-	return err;
-}
-
-static void
-synergy_perf_set_freq(int freq)
-{
-	int		cnode;
-	nodepda_t	*npdap;
-
-	for (cnode=0; cnode < numnodes; cnode++) {
-		if ((npdap = NODEPDA(cnode)) != NULL)
-			npdap->synergy_perf_freq = freq;
-	}
-}
-
-static void
-synergy_perf_set_enable(int enable)
-{
-	int		cnode;
-	nodepda_t	*npdap;
-
-	for (cnode=0; cnode < numnodes; cnode++) {
-		if ((npdap = NODEPDA(cnode)) != NULL)
-			npdap->synergy_perf_enabled = enable;
-	}
-	printk("NOTICE: synergy perf counting %sabled on all nodes\n", enable ? "en" : "dis");
-}
-
-static int
-synergy_perf_size(nodepda_t *npdap)
-{
-	synergy_perf_t	*p;
-	int		n;
-
-	if (npdap->synergy_perf_enabled == 0) {
-		/* no stats to return */
-		return 0;
-	}
-
-	spin_lock_irq(&npdap->synergy_perf_lock);
-	for (n=0, p = npdap->synergy_perf_first; p;) {
-		n++;
-		p = p->next;
-		if (p == npdap->synergy_perf_first)
-			break;
-	}
-	spin_unlock_irq(&npdap->synergy_perf_lock);
-
-	/* bytes == n pairs of {event,counter} */
-	return n * 2 * sizeof(uint64_t);
-}
-
-static int
-synergy_perf_ioctl(struct inode *inode, struct file *file,
-        unsigned int cmd, unsigned long arg)
-{
-	int             cnode;
-	nodepda_t       *npdap;
-	synergy_perf_t	*p;
-	int		intarg;
-	int		fsb;
-	uint64_t	longarg;
-	uint64_t	*stats;
-	int		n;
-	devfs_handle_t	d;
-	arbitrary_info_t info;
-	
-	if ((d = devfs_get_handle_from_inode(inode)) == NULL)
-		return -ENODEV;
-	info = hwgraph_fastinfo_get(d);
-
-	cnode = SYNERGY_PERF_INFO_CNODE(info);
-	fsb = SYNERGY_PERF_INFO_FSB(info);
-	npdap = NODEPDA(cnode);
-
-	switch (cmd) {
-	case SNDRV_GET_SYNERGY_VERSION:
-		/* return int, version of data structure for SNDRV_GET_SYNERGYINFO */
-		intarg = 1; /* version 1 */
-		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
-		    return -EFAULT;
-		break;
-
-	case SNDRV_GET_INFOSIZE:
-		/* return int, sizeof buf needed for SYNERGY_PERF_GET_STATS */
-		intarg = synergy_perf_size(npdap);
-		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
-		    return -EFAULT;
-		break;
-
-	case SNDRV_GET_SYNERGYINFO:
-		/* return array of event/value pairs, this node only */
-		if ((intarg = synergy_perf_size(npdap)) <= 0)
-			return -ENODATA;
-		if ((stats = (uint64_t *)kmalloc(intarg, GFP_KERNEL)) == NULL)
-			return -ENOMEM;
-		spin_lock_irq(&npdap->synergy_perf_lock);
-		for (n=0, p = npdap->synergy_perf_first; p;) {
-			stats[n++] = p->modesel;
-			if (p->intervals > 0)
-			    stats[n++] = p->counts[fsb] * p->total_intervals / p->intervals;
-			else
-			    stats[n++] = 0;
-			p = p->next;
-			if (p == npdap->synergy_perf_first)
-				break;
-		}
-		spin_unlock_irq(&npdap->synergy_perf_lock);
-
-		if (copy_to_user((void *)arg, stats, intarg)) {
-		    kfree(stats);
-		    return -EFAULT;
-		}
-
-		kfree(stats);
-		break;
-
-	case SNDRV_SYNERGY_APPEND:
-		/* reads 64bit event, append synergy perf event to all nodes  */
-		if (copy_from_user(&longarg, (void *)arg, sizeof(longarg)))
-		    return -EFAULT;
-		return synergy_perf_append(longarg);
-		break;
-
-	case SNDRV_GET_SYNERGY_STATUS:
-		/* return int, 1 if enabled else 0 */
-		intarg = npdap->synergy_perf_enabled;
-		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
-		    return -EFAULT;
-		break;
-
-	case SNDRV_SYNERGY_ENABLE:
-		/* read int, if true enable counting else disable */
-		if (copy_from_user(&intarg, (void *)arg, sizeof(intarg)))
-		    return -EFAULT;
-		synergy_perf_set_enable(intarg);
-		break;
-
-	case SNDRV_SYNERGY_FREQ:
-		/* read int, set jiffies per update */ 
-		if (copy_from_user(&intarg, (void *)arg, sizeof(intarg)))
-		    return -EFAULT;
-		if (intarg < 0 || intarg >= HZ)
-			return -EINVAL;
-		synergy_perf_set_freq(intarg);
-		break;
-
-	default:
-		printk("Warning: invalid ioctl %d on synergy mon for cnode=%d fsb=%d\n", cmd, cnode, fsb);
-		return -EINVAL;
-	}
-	return(0);
-}
-
-struct file_operations synergy_mon_fops = {
-        ioctl:		synergy_perf_ioctl,
-};
-
-void
-synergy_perf_update(int cpu)
-{
-	nasid_t		nasid;
-	cnodeid_t       cnode;
-	struct nodepda_s *npdap;
-
-	/*
-	 * synergy_perf_initialized is set by synergy_perf_init()
-	 * which is called last thing by sn_mp_setup(), i.e. well
-	 * after nodepda has been initialized.
-	 */
-	if (!synergy_perf_initialized)
-		return;
-
-	cnode = cpuid_to_cnodeid(cpu);
-	npdap = NODEPDA(cnode);
-
-	if (npdap == NULL || cnode < 0 || cnode >= numnodes)
-		/* this should not happen: still in early io init */
-		return;
-
-#if 0
-	/* use this to check nodepda initialization */
-	if (((uint64_t)npdap) & 0x7) {
-		printk("\nERROR on cpu %d : cnode=%d, npdap == %p, not aligned\n", cpu, cnode, npdap);
-		BUG();
-	}
-#endif
-
-	if (npdap->synergy_perf_enabled == 0 || npdap->synergy_perf_data == NULL) {
-		/* Not enabled, or no events to monitor */
-		return;
-	}
-
-	if (npdap->synergy_inactive_intervals++ % npdap->synergy_perf_freq != 0) {
-		/* don't multiplex on every timer interrupt */
-		return;
-	}
-
-	/*
-	 * Read registers for last interval and increment counters.
-	 * Hold the per-node synergy_perf_lock so concurrent readers get
-	 * consistent values.
-	 */
-	spin_lock_irq(&npdap->synergy_perf_lock);
-
-	nasid = cpuid_to_nasid(cpu);
-	npdap->synergy_active_intervals++;
-	npdap->synergy_perf_data->intervals++;
-	npdap->synergy_perf_data->total_intervals = npdap->synergy_active_intervals;
-
-	npdap->synergy_perf_data->counts[0] += 0xffffffffffUL &
-		REMOTE_SYNERGY_LOAD(nasid, 0, PERF_CNTR0_A);
-
-	npdap->synergy_perf_data->counts[1] += 0xffffffffffUL &
-		REMOTE_SYNERGY_LOAD(nasid, 1, PERF_CNTR0_B);
-
-	/* skip to next in circular list */
-	npdap->synergy_perf_data = npdap->synergy_perf_data->next;
-
-	spin_unlock_irq(&npdap->synergy_perf_lock);
-
-	/* set the counter 0 selection modes for both A and B */
-	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTL0_A, npdap->synergy_perf_data->modesel);
-	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTL0_B, npdap->synergy_perf_data->modesel);
-
-	/* and reset the counter registers to zero */
-	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTR0_A, 0UL);
-	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTR0_B, 0UL);
-}
-
-void
-synergy_perf_init(void)
-{
-	printk("synergy_perf_init(), counting is initially disabled\n");
-	synergy_perf_initialized++;
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/Makefile linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/Makefile
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/Makefile	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/Makefile	2003-07-05 18:09:46.000000000 -0700
@@ -1,7 +1,7 @@
 #
 # arch/ia64/sn/kernel/sn2/Makefile
 #
-# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
+# Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify it 
 # under the terms of version 2 of the GNU General Public License 
@@ -41,7 +41,9 @@
 	$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
 
 O_TARGET        = sn2.o
+export-objs	:= io.o
 
-obj-y          = cache.o iomv.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o
+obj-y		= cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \
+		  prominfo_proc.o timer.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/cache.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/cache.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/cache.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/cache.c	2003-07-05 18:09:46.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  * 
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  *
  */
 
@@ -24,6 +24,5 @@
 sn_flush_all_caches(long flush_addr, long bytes)
 {
 	flush_icache_range(flush_addr, flush_addr+bytes);
+	mb();
 }
-
-
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/io.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/io.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/io.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/io.c	2003-07-05 18:09:46.000000000 -0700
@@ -0,0 +1,91 @@
+/* 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Silicon Graphics, Inc. All rights reserved.
+ *
+ * The generic kernel requires function pointers to these routines, so
+ * we wrap the inlines from asm/ia64/sn/sn2/io.h here.
+ */
+
+#include <asm/sn/sn2/io.h>
+
+unsigned int
+sn_inb (unsigned long port)
+{
+	return __sn_inb(port);
+}
+
+unsigned int
+sn_inw (unsigned long port)
+{
+	return __sn_inw(port);
+}
+
+unsigned int
+sn_inl (unsigned long port)
+{
+	return __sn_inl(port);
+}
+
+void
+sn_outb (unsigned char val, unsigned long port)
+{
+	__sn_outb(val, port);
+}
+
+void
+sn_outw (unsigned short val, unsigned long port)
+{
+	__sn_outw(val, port);
+}
+
+void
+sn_outl (unsigned int val, unsigned long port)
+{
+	__sn_outl(val, port);
+}
+
+unsigned char
+sn_readb (void *addr)
+{
+	return __sn_readb (addr);
+}
+
+unsigned short
+sn_readw (void *addr)
+{
+	return __sn_readw (addr);
+}
+
+unsigned int
+sn_readl (void *addr)
+{
+	return __sn_readl (addr);
+}
+
+unsigned long
+sn_readq (void *addr)
+{
+	return __sn_readq (addr);
+}
+
+
+/* define aliases: */
+
+asm (".global __sn_inb, __sn_inw, __sn_inl");
+asm ("__sn_inb = sn_inb");
+asm ("__sn_inw = sn_inw");
+asm ("__sn_inl = sn_inl");
+
+asm (".global __sn_outb, __sn_outw, __sn_outl");
+asm ("__sn_outb = sn_outb");
+asm ("__sn_outw = sn_outw");
+asm ("__sn_outl = sn_outl");
+
+asm (".global __sn_readb, __sn_readw, __sn_readl, __sn_readq");
+asm ("__sn_readb = sn_readb");
+asm ("__sn_readw = sn_readw");
+asm ("__sn_readl = sn_readl");
+asm ("__sn_readq = sn_readq");
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/iomv.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/iomv.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/iomv.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/iomv.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,68 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/pda.h>
-#include <asm/sn/sn_cpuid.h>
-
-/**
- * sn_io_addr - convert an in/out port to an i/o address
- * @port: port to convert
- *
- * Legacy in/out instructions are converted to ld/st instructions
- * on IA64.  This routine will convert a port number into a valid 
- * SN i/o address.  Used by sn_in*() and sn_out*().
- */
-void *
-sn_io_addr(unsigned long port)
-{
-	if (!IS_RUNNING_ON_SIMULATOR()) {
-		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
-	} else {
-		unsigned long io_base;
-		unsigned long addr;
- 
-		/*
- 		 * word align port, but need more than 10 bits
- 		 * for accessing registers in bedrock local block
- 		 * (so we don't do port&0xfff)
- 		 */
-		if ((port >= 0x1f0 && port <= 0x1f7) ||
-			port == 0x3f6 || port == 0x3f7) {
-			io_base = (0xc000000fcc000000 | ((unsigned long)get_nasid() << 38));
-			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
-		} else {
-			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
-		}
-		return(void *) addr;
-	}
-}
-
-/**
- * sn2_mmiob - I/O space memory barrier
- *
- * Acts as a memory mapped I/O barrier for platforms that queue writes to 
- * I/O space.  This ensures that subsequent writes to I/O space arrive after
- * all previous writes.  For most ia64 platforms, this is a simple
- * 'mf.a' instruction.  For other platforms, mmiob() may have to read
- * a chipset register to ensure ordering.
- *
- * On SN2, we wait for the PIO_WRITE_STATUS SHub register to clear.
- * See PV 871084 for details about the WAR about zero value.
- *
- */
-void
-sn2_mmiob (void)
-{
-	while ((((volatile unsigned long) (*pda.pio_write_status_addr)) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) != 
-				SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
-		udelay(1);
-}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/prominfo_proc.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/prominfo_proc.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/prominfo_proc.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/prominfo_proc.c	2003-07-05 18:09:46.000000000 -0700
@@ -0,0 +1,365 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ *
+ * Module to export the system's Firmware Interface Tables, including
+ * PROM revision numbers, in /proc
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/sn/simulator.h>
+
+/* to lookup nasids */
+#include <asm/sn/sn_cpuid.h>
+
+MODULE_DESCRIPTION("PROM version reporting for /proc");
+MODULE_AUTHOR("Chad Talbott");
+MODULE_LICENSE("GPL");
+
+#undef DEBUG_PROMINFO
+
+#define TRACE_PROMINFO
+
+#if defined(DEBUG_PROMINFO)
+#  define DPRINTK(x...) printk(KERN_DEBUG x)
+#else
+#  define DPRINTK(x...)
+#endif
+
+#if defined(TRACE_PROMINFO) && defined(DEBUG_PROMINFO)
+#  if defined(__GNUC__)
+#    define TRACE()	printk(KERN_DEBUG "%s:%d:%s\n", \
+			       __FILE__, __LINE__, __FUNCTION__)
+#  else
+#    define TRACE()	printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__)
+#  endif
+#else
+#  define TRACE()
+#endif
+
+/* Sub-regions determined by bits in Node Offset */
+#define	LB_PROM_SPACE		0x0000000700000000ul /* Local LB PROM */
+
+#define FIT_SIGNATURE		0x2020205f5449465ful
+/* Standard Intel FIT entry types */
+#define FIT_ENTRY_FIT_HEADER	0x00	/* FIT header entry */
+#define FIT_ENTRY_PAL_B		0x01	/* PAL_B entry */
+/* Entries 0x02 through 0x0D reserved by Intel */
+#define FIT_ENTRY_PAL_A_PROC	0x0E	/* Processor-specific PAL_A entry */
+#define FIT_ENTRY_PAL_A		0x0F	/* PAL_A entry, same as... */
+#define FIT_ENTRY_PAL_A_GEN	0x0F	/* ...Generic PAL_A entry */
+#define FIT_ENTRY_UNUSED	0x7F	/* Unused (reserved by Intel?) */
+/* OEM-defined entries range from 0x10 to 0x7E. */
+#define FIT_ENTRY_SAL_A		0x10	/* SAL_A entry */
+#define FIT_ENTRY_SAL_B		0x11	/* SAL_B entry */
+#define FIT_ENTRY_SALRUNTIME	0x12	/* SAL runtime entry */
+#define FIT_ENTRY_EFI		0x1F	/* EFI entry */
+#define FIT_ENTRY_FPSWA		0x20	/* embedded fpswa entry */
+#define FIT_ENTRY_VMLINUX	0x21	/* embedded vmlinux entry */
+
+#define FIT_MAJOR_SHIFT	(32 + 8)
+#define FIT_MAJOR_MASK	((1 << 8) - 1)
+#define FIT_MINOR_SHIFT	32
+#define FIT_MINOR_MASK	((1 << 8) - 1)
+
+#define FIT_MAJOR(q)	\
+	((unsigned) ((q) >> FIT_MAJOR_SHIFT) & FIT_MAJOR_MASK)
+#define FIT_MINOR(q)	\
+	((unsigned) ((q) >> FIT_MINOR_SHIFT) & FIT_MINOR_MASK)
+
+#define FIT_TYPE_SHIFT	(32 + 16)
+#define FIT_TYPE_MASK	((1 << 7) - 1)
+
+#define FIT_TYPE(q)	\
+	((unsigned) ((q) >> FIT_TYPE_SHIFT) & FIT_TYPE_MASK)
+
+#define FIT_ENTRY(type, maj, min, size)					\
+	((((unsigned long)(maj) & FIT_MAJOR_MASK) << FIT_MAJOR_SHIFT) |	\
+	 (((unsigned long)(min) & FIT_MINOR_MASK) << FIT_MINOR_SHIFT) |	\
+	 (((unsigned long)(type) & FIT_TYPE_MASK) << FIT_TYPE_SHIFT) |	\
+	 (size))
+
+struct fit_type_map_t {
+	unsigned char	type;
+	const char	*name;
+};
+
+static const struct fit_type_map_t fit_entry_types[] = {
+	{ FIT_ENTRY_FIT_HEADER, "FIT Header" },
+	{ FIT_ENTRY_PAL_A_GEN,  "Generic PAL_A" },
+	{ FIT_ENTRY_PAL_A_PROC, "Processor-specific PAL_A" },
+	{ FIT_ENTRY_PAL_A,      "PAL_A" },
+	{ FIT_ENTRY_PAL_B,      "PAL_B" },
+	{ FIT_ENTRY_SAL_A,      "SAL_A" },
+	{ FIT_ENTRY_SAL_B,      "SAL_B" },
+	{ FIT_ENTRY_SALRUNTIME, "SAL runtime" },
+	{ FIT_ENTRY_EFI,	"EFI" },
+	{ FIT_ENTRY_VMLINUX,    "Embedded Linux" },
+	{ FIT_ENTRY_FPSWA,      "Embedded FPSWA" },
+	{ FIT_ENTRY_UNUSED,     "Unused" },
+	{ 0xff,                 "Error" },
+};
+
+static const char *
+fit_type_name(unsigned char type)
+{
+	struct fit_type_map_t const*mapp;
+
+	for (mapp = fit_entry_types; mapp->type != 0xff; mapp++)
+		if (type == mapp->type)
+			return mapp->name;
+
+	if ((type > FIT_ENTRY_PAL_A) && (type < FIT_ENTRY_UNUSED))
+		return "OEM type";
+	if ((type > FIT_ENTRY_PAL_B) && (type < FIT_ENTRY_PAL_A))
+		return "Reserved";
+
+	return "Unknown type";
+}
+
+/* These two routines read the FIT table directly from the FLASH PROM
+ * on a specific node.  The PROM can only be accessed using aligned 64
+ * bit reads, so we do that and then shift and mask the result to get
+ * at each field.
+ */
+static int
+dump_fit_entry(char *page, unsigned long *fentry)
+{
+	unsigned long q1, q2;
+	unsigned type;
+
+	TRACE();
+
+	q1 = readq(fentry);
+	q2 = readq(fentry + 1);
+	type = FIT_TYPE(q2);
+	return sprintf(page, "%02x %-25s %x.%02x %016lx %u\n",
+		       type,
+		       fit_type_name(type),
+		       FIT_MAJOR(q2), FIT_MINOR(q2),
+		       q1,
+		       /* mult by sixteen to get size in bytes */
+		       (unsigned)q2 * 16);
+}
+
+/* We assume that the fit table will be small enough that we can print
+ * the whole thing into one page.  (This is true for our default 16kB
+ * pages -- each entry is about 60 chars wide when printed.)  I read
+ * somewhere that the maximum size of the FIT is 128 entries, so we're
+ * OK except for 4kB pages (and no one is going to do that on SN
+ * anyway).
+ */
+static int
+dump_fit(char *page, unsigned long *fit)
+{
+	unsigned long qw;
+	int nentries;
+	int fentry;
+	char *p;
+
+	TRACE();
+
+	DPRINTK("dumping fit from %p\n", (void *)fit);
+
+	qw = readq(fit);
+	DPRINTK("FIT signature: %016lx (%.8s)\n", qw, (char *)&qw);
+	if (qw != FIT_SIGNATURE)
+		printk(KERN_WARNING "Unrecognized FIT signature");
+
+	qw = readq(fit + 1);
+	nentries = (unsigned)qw;
+	DPRINTK("number of fit entries: %u\n", nentries);
+	/* check that we won't overflow the page -- see comment above */
+	BUG_ON(nentries * 60 > PAGE_SIZE);
+
+	p = page;
+	for (fentry = 0; fentry < nentries; fentry++)
+		/* each FIT entry is two 64 bit words */
+		p += dump_fit_entry(p, fit + 2 * fentry);
+
+	return p - page;
+}
+
+static int
+dump_version(char *page, unsigned long *fit)
+{
+	int nentries;
+	int fentry;
+	unsigned long qw;
+
+	TRACE();
+
+	nentries = (unsigned)readq(fit + 1);
+	BUG_ON(nentries * 60 > PAGE_SIZE);
+
+	for (fentry = 0; fentry < nentries; fentry++) {
+		qw = readq(fit + 2 * fentry + 1);
+		if (FIT_TYPE(qw) == FIT_ENTRY_SAL_A)
+			return sprintf(page, "%x.%02x\n",
+				       FIT_MAJOR(qw), FIT_MINOR(qw));
+	}
+	return 0;
+}
+
+/* same as in proc_misc.c */
+static int
+proc_calc_metrics(char *page, char **start, off_t off, int count, int *eof,
+		  int len)
+{
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
+}
+
+static int
+read_version_entry(char *page, char **start, off_t off, int count, int *eof,
+		   void *data)
+{
+	int len = 0;
+
+	MOD_INC_USE_COUNT;
+	/* data holds the pointer to this node's FIT */
+	len = dump_version(page, (unsigned long *)data);
+	len = proc_calc_metrics(page, start, off, count, eof, len);
+	MOD_DEC_USE_COUNT;
+	return len;
+}
+
+static int
+read_fit_entry(char *page, char **start, off_t off, int count, int *eof,
+	       void *data)
+{
+	int len = 0;
+
+	MOD_INC_USE_COUNT;
+	/* data holds the pointer to this node's FIT */
+	len = dump_fit(page, (unsigned long *)data);
+	len = proc_calc_metrics(page, start, off, count, eof, len);
+	MOD_DEC_USE_COUNT;
+
+	return len;
+}
+
+/* this is a fake FIT that's used on the medusa simulator which
+ * doesn't usually run a complete PROM. 
+ */
+#ifdef CONFIG_IA64_SGI_SN_SIM
+static unsigned long fakefit[] = {
+	/* this is all we need to satisfy the code below */
+	FIT_SIGNATURE,
+	FIT_ENTRY(FIT_ENTRY_FIT_HEADER, 0x02, 0x60, 2),
+	/* dump something arbitrary for
+	 * /proc/sgi_prominfo/nodeX/version */
+	0xbadbeef00fa3ef17ul,
+	FIT_ENTRY(FIT_ENTRY_SAL_A, 0, 0x99, 0x100)
+};	
+#endif
+
+static unsigned long *
+lookup_fit(int nasid)
+{
+	unsigned long *fitp;
+	unsigned long fit_paddr;
+	unsigned long *fit_vaddr;
+
+#ifdef CONFIG_IA64_SGI_SN_SIM
+	if (IS_RUNNING_ON_SIMULATOR())
+		return fakefit;
+#endif
+
+	fitp = (void *)GLOBAL_MMR_ADDR(nasid, LB_PROM_SPACE - 32);
+	DPRINTK("pointer to fit at %p\n", (void *)fitp);
+	fit_paddr = readq(fitp);
+	DPRINTK("fit pointer contains %lx\n", fit_paddr);
+	/* snag just the node-relative offset */
+	fit_paddr &= ~0ul >> (63-35);
+	/* the pointer to the FIT is relative to IA-64 compatibility
+	 * space.  However, the PROM is mapped at a different offset
+	 * in MMR space (both local and global)
+	 */
+	fit_paddr += 0x700000000;
+	fit_vaddr = (void *)GLOBAL_MMR_ADDR(nasid, fit_paddr);
+	DPRINTK("fit at %p\n", (void *)fit_vaddr);
+	return fit_vaddr;
+}
+
+/* module entry points */
+int __init prominfo_init(void);
+void __exit prominfo_exit(void);
+
+module_init(prominfo_init);
+module_exit(prominfo_exit);
+
+static struct proc_dir_entry **proc_entries;
+static struct proc_dir_entry *sgi_prominfo_entry;
+
+#define NODE_NAME_LEN 11
+
+int __init
+prominfo_init(void)
+{
+	struct proc_dir_entry **entp;
+	cnodeid_t cnodeid;
+	nasid_t nasid;
+	char name[NODE_NAME_LEN];
+
+	if (!ia64_platform_is("sn2"))
+		return 0;
+
+	TRACE();
+
+	DPRINTK("running on cpu %d\n", smp_processor_id());
+	DPRINTK("numnodes %d\n", numnodes);
+
+	proc_entries = kmalloc(numnodes * sizeof(struct proc_dir_entry *),
+			       GFP_KERNEL);
+
+	sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL);
+
+	for (cnodeid = 0, entp = proc_entries;
+	     cnodeid < numnodes;
+	     cnodeid++, entp++) {
+		sprintf(name, "node%d", cnodeid);
+		*entp = proc_mkdir(name, sgi_prominfo_entry);
+		nasid = cnodeid_to_nasid(cnodeid);
+		create_proc_read_entry(
+			"fit", 0, *entp, read_fit_entry,
+			lookup_fit(nasid));
+		create_proc_read_entry(
+			"version", 0, *entp, read_version_entry,
+			lookup_fit(nasid));
+	}
+
+	return 0;
+}
+
+void __exit
+prominfo_exit(void)
+{
+	struct proc_dir_entry **entp;
+	unsigned cnodeid;
+	char name[NODE_NAME_LEN];
+
+	TRACE();
+
+	for (cnodeid = 0, entp = proc_entries;
+	     cnodeid < numnodes;
+	     cnodeid++, entp++) {
+		remove_proc_entry("fit", *entp);
+		remove_proc_entry("version", *entp);
+		sprintf(name, "node%d", cnodeid);
+		remove_proc_entry(name, sgi_prominfo_entry);
+	}
+	remove_proc_entry("sgi_prominfo", NULL);
+	kfree(proc_entries);
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/ptc_deadlock.S linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/ptc_deadlock.S	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/ptc_deadlock.S	2003-07-05 18:09:46.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <asm/sn/sn2/shub_mmr.h>
@@ -61,20 +61,22 @@
 	cmp.ne	p6,p0=zeroval,scr2
 (p6)	br.cond.sptk 5b;;
 
-	tbit.nz	p6,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK
+	tbit.nz	p8,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK
 	
 (p7)	st8.rel [ptc1]=data1;;		// Now write PTC1.
 
+5:	ld8.acq	scr1=[piowcphy];;	// Wait for PIOs to complete.
+	extr.u	scr2=scr1,WRITECOUNT,7;;// PIO count
+	cmp.ne	p6,p0=zeroval,scr2
+(p6)	br.cond.sptk 5b
+	
+	tbit.nz	p8,p0=scr1,DEADLOCKBIT;;// Test for DEADLOCK
+
 	mov psr.l=psrsave;;		// Reenable IC
 	srlz.i;;
 	////////////// END   PHYSICAL MODE ////////////////////
 
-(p6)	br.cond.spnt 1b;;		// Repeat if DEADLOCK occurred.
+(p8)	br.cond.spnt 1b;;		// Repeat if DEADLOCK occurred.
 
-5:	ld8.acq	scr1=[piowc];;		// Wait for PIOs to complete.
-	extr.u	scr2=scr1,WRITECOUNT,7;;// PIO count
-	cmp.ne	p6,p0=zeroval,scr2
-(p6)	br.cond.sptk 5b
-	
 	br.ret.sptk	rp
 	.endp sn2_ptc_deadlock_recovery_core
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/sn2_smp.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/sn2_smp.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/sn2_smp.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/sn2_smp.c	2003-07-05 18:09:46.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  * SN2 Platform specific SMP Support
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -79,296 +79,6 @@
 	return ws;
 }
 
-static long use_tlb_hack;
-static volatile unsigned long zz[1024] __attribute__((__aligned__(128)));
-static inline long
-get_itc(void)
-{
-        long ret;                                                                                                           
-        __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret));
-        return ret+1;
-}                                                                                                                           
-
-
-
-#ifdef PTCG_WAR
-/*
- * The following structure is used to pass params thru smp_call_function
- * to other cpus for flushing TLB ranges.
- */
-typedef struct {
-	unsigned long	start;
-	unsigned long	end;
-	unsigned long	nbits;
-	unsigned int	rid;
-	atomic_t	unfinished_count;
-	char		fill[96];
-} ptc_params_t;
-
-#define NUMPTC	512
-
-static ptc_params_t	ptcParamArray[NUMPTC] __attribute__((__aligned__(128)));
-
-/* use separate cache lines on ptcParamsNextByCpu to avoid false sharing */
-static ptc_params_t	*ptcParamsNextByCpu[NR_CPUS*16] __attribute__((__aligned__(128)));
-static volatile ptc_params_t	*ptcParamsEmpty __cacheline_aligned;
-
-/*REFERENCED*/
-static spinlock_t ptcParamsLock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
-
-static int ptcInit = 0;
-#ifdef PTCDEBUG
-static int ptcParamsAllBusy = 0;		/* debugging/statistics */
-static int ptcCountBacklog = 0;
-static int ptcBacklog[NUMPTC+1];
-static char ptcParamsCounts[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-static char ptcParamsResults[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-#endif
-
-/*
- * Make smp_send_flush_tlbsmp_send_flush_tlb() a weak reference,
- * so that we get a clean compile with the ia64 patch without the
- * actual SN1 specific code in arch/ia64/kernel/smp.c.
- */
-extern void smp_send_flush_tlb (void) __attribute((weak));
-
-
-/**
- * sn1_ptc_l_range - purge local translation cache
- * @start: start of virtual address range
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Purges the range specified from the local processor's translation cache
- * (as opposed to the translation registers).  Note that more than the specified
- * range *may* be cleared from the cache by some processors.
- *
- * This is probably not good enough, but I don't want to try to make it better 
- * until I get some statistics on a running system. At a minimum, we should only 
- * send IPIs to 1 processor in each TLB domain & have it issue a ptc.g on it's 
- * own FSB. Also, we only have to serialize per FSB, not globally.
- *
- * More likely, we will have to do some work to reduce the frequency of calls to
- * this routine.
- */
-static inline void
-sn1_ptc_l_range(unsigned long start, unsigned long end, unsigned long nbits)
-{
-	do {
-		__asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory");
-		start += (1UL << nbits);
-	} while (start < end);
-	ia64_srlz_d();
-}
-
-/**
- * sn1_received_flush_tlb - cpu tlb flush routine
- *
- * Flushes the TLB of a given processor.
- */
-void
-sn1_received_flush_tlb(void)
-{
-	unsigned long	start, end, nbits;
-	unsigned int	rid, saved_rid;
-	int		cpu = smp_processor_id();
-	int		result;
-	ptc_params_t	*ptcParams;
-
-	ptcParams = ptcParamsNextByCpu[cpu*16];
-	if (ptcParams == ptcParamsEmpty)
-		return;
-
-	do {
-		start = ptcParams->start;
-		saved_rid = (unsigned int) ia64_get_rr(start);
-		end = ptcParams->end;
-		nbits = ptcParams->nbits;
-		rid = ptcParams->rid;
-
-		if (saved_rid != rid) {
-			ia64_set_rr(start, (unsigned long)rid);
-			ia64_srlz_d();
-		}
-
-		sn1_ptc_l_range(start, end, nbits);
-
-		if (saved_rid != rid) 
-			ia64_set_rr(start, (unsigned long)saved_rid);
-
-		ia64_srlz_i();
-
-		result = atomic_dec(&ptcParams->unfinished_count);
-#ifdef PTCDEBUG
-		{
-		    int i = ptcParams-&ptcParamArray[0];
-		    ptcParamsResults[cpu][i] = (char) result;
-		    ptcParamsCounts[cpu][i]++;
-		}
-#endif /* PTCDEBUG */
-
-		if (++ptcParams == &ptcParamArray[NUMPTC])
-			ptcParams = &ptcParamArray[0];
-
-	} while (ptcParams != ptcParamsEmpty);
-
-	ptcParamsNextByCpu[cpu*16] = ptcParams;
-}
-
-/**
- * sn1_global_tlb_purge - flush a translation cache range on all processors
- * @start: start of virtual address range to flush
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Flushes the translation cache of all processors from @start to @end.
- */
-void
-sn1_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
-{
-	ptc_params_t	*params;
-	ptc_params_t	*next;
-	unsigned long	irqflags;
-#ifdef PTCDEBUG
-	ptc_params_t	*nextnext;
-	int		backlog = 0;
-#endif
-
-	if (smp_num_cpus == 1) {
-		sn1_ptc_l_range(start, end, nbits);
-		return;
-	}
-
-	if (in_interrupt()) {
-		/*
-		 *  If at interrupt level and cannot get spinlock, 
-		 *  then do something useful by flushing own tlbflush queue
-		 *  so as to avoid a possible deadlock.
-		 */
-		while (!spin_trylock(&ptcParamsLock)) {
-			local_irq_save(irqflags);
-			sn1_received_flush_tlb();
-			local_irq_restore(irqflags);
-			udelay(10);	/* take it easier on the bus */	
-		}
-	} else {
-		spin_lock(&ptcParamsLock);
-	}
-
-	if (!ptcInit) {
-		int cpu;
-		ptcInit = 1;
-		memset(ptcParamArray, 0, sizeof(ptcParamArray));
-		ptcParamsEmpty = &ptcParamArray[0];
-		for (cpu=0; cpu<NR_CPUS; cpu++)
-			ptcParamsNextByCpu[cpu*16] = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-		memset(ptcBacklog, 0, sizeof(ptcBacklog));
-		memset(ptcParamsCounts, 0, sizeof(ptcParamsCounts));
-		memset(ptcParamsResults, 0, sizeof(ptcParamsResults));
-#endif	/* PTCDEBUG */
-	}
-
-	params = (ptc_params_t *) ptcParamsEmpty;
-	next = (ptc_params_t *) ptcParamsEmpty + 1;
-	if (next == &ptcParamArray[NUMPTC])
-		next = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-	nextnext = next + 1;
-	if (nextnext == &ptcParamArray[NUMPTC])
-		nextnext = &ptcParamArray[0];
-
-	if (ptcCountBacklog) {
-		/* quick count of backlog */
-		ptc_params_t *ptr;
-
-		/* check the current pointer to the beginning */
-		ptr = params;
-		while(--ptr >= &ptcParamArray[0]) {
-			if (atomic_read(&ptr->unfinished_count) == 0)
-				break;
-			++backlog;
-		}
-
-		if (backlog) {
-			/* check the end of the array */
-			ptr = &ptcParamArray[NUMPTC];
-			while (--ptr > params) {
-				if (atomic_read(&ptr->unfinished_count) == 0)
-					break;
-				++backlog;
-			}
-		}
-		ptcBacklog[backlog]++;
-	}
-#endif	/* PTCDEBUG */
-
-	/* wait for the next entry to clear...should be rare */
-	if (atomic_read(&next->unfinished_count) > 0) {
-#ifdef PTCDEBUG
-		ptcParamsAllBusy++;
-
-		if (atomic_read(&nextnext->unfinished_count) == 0) {
-		    if (atomic_read(&next->unfinished_count) > 0) {
-			panic("\nnonzero next zero nextnext %lx %lx\n",
-			    (long)next, (long)nextnext);
-		    }
-		}
-#endif
-
-		/* it could be this cpu that is behind */
-		local_irq_save(irqflags);
-		sn1_received_flush_tlb();
-		local_irq_restore(irqflags);
-
-		/* now we know it's not this cpu, so just wait */
-		while (atomic_read(&next->unfinished_count) > 0) {
-			barrier();
-		}
-	}
-
-	params->start = start;
-	params->end = end;
-	params->nbits = nbits;
-	params->rid = (unsigned int) ia64_get_rr(start);
-	atomic_set(&params->unfinished_count, smp_num_cpus);
-
-	/* The atomic_set above can hit memory *after* the update
-	 * to ptcParamsEmpty below, which opens a timing window
-	 * that other cpus can squeeze into!
-	 */
-	mb();
-
-	/* everything is ready to process:
-	 *	-- global lock is held
-	 *	-- new entry + 1 is free
-	 *	-- new entry is set up
-	 * so now:
-	 *	-- update the global next pointer
-	 *	-- unlock the global lock
-	 *	-- send IPI to notify other cpus
-	 *	-- process the data ourselves
-	 */
-	ptcParamsEmpty = next;
-	spin_unlock(&ptcParamsLock);
-	smp_send_flush_tlb();
-
-	local_irq_save(irqflags);
-	sn1_received_flush_tlb();
-	local_irq_restore(irqflags);
-
-	/* 
-	 * Since IPIs are polled event (for now), we need to wait til the
-	 * TLB flush has started.
-	 * wait for the flush to complete 
-	 */ 
-	while (atomic_read(&params->unfinished_count) > 0)
-		barrier();
-}
-
-#endif /* PTCG_WAR */
 
 
 /**
@@ -384,19 +94,10 @@
 void
 sn2_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
 {
-	int			cnode, mycnode, nasid;
+	int			cnode, mycnode, nasid, flushed=0;
 	volatile unsigned	long	*ptc0, *ptc1;
 	unsigned long		flags=0, data0, data1;
-	long 		        zzbase, zztime, zztime2;
 
-	/*
-	 * Special case 1 cpu & 1 node. Use local purges.
-	 */
-#ifdef PTCG_WAR
-	sn1_global_tlb_purge(start, end, nbits);
-	return;
-#endif /* PTCG_WAR */
-		
 	data0 = (1UL<<SH_PTC_0_A_SHFT) |
 		(nbits<<SH_PTC_0_PS_SHFT) |
 		((ia64_get_rr(start)>>8)<<SH_PTC_0_RID_SHFT) |
@@ -405,20 +106,9 @@
 	ptc0 = (long*)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_0);
 	ptc1 = (long*)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_1);
 
-	mycnode = local_cnodeid();
+	mycnode = numa_node_id();
 
-	/* 
-	 * For now, we dont want to spin uninterruptibly waiting
-	 * for the lock. Makes hangs hard to debug.
-	 */
-	zzbase = smp_processor_id()*16;
-	zz[zzbase+0] += 0x0000ffff00000001UL;
-
-	local_irq_save(flags);
-	zztime = get_itc();     
-	spin_lock(&sn2_global_ptc_lock);
-	zz[zzbase+0] += 0xffff000000000000UL;
-	zztime2 = get_itc();     
+	spin_lock_irqsave(&sn2_global_ptc_lock, flags);
 
 	do {
 		data1 = start | (1UL<<SH_PTC_1_START_SHFT);
@@ -427,16 +117,16 @@
 				continue;
 			if (cnode == mycnode) {
 				asm volatile ("ptc.ga %0,%1;;srlz.i;;" :: "r"(start), "r"(nbits<<2) : "memory");
-			} else {
+			} else if (current->shared_mm || test_bit(cnode, current->node_history)) {
 				nasid = cnodeid_to_nasid(cnode);
 				ptc0 = CHANGE_NASID(nasid, ptc0);
 				ptc1 = CHANGE_NASID(nasid, ptc1);
 				pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1);
+				flushed = 1;
 			}
 		}
 
-		if (wait_piowc() & SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK) {
-			zz[zzbase+1]++;
+		if (flushed && (wait_piowc() & SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK)) {
 			sn2_ptc_deadlock_recovery(data0, data1);
 		}
 
@@ -444,20 +134,8 @@
 
 	} while (start < end);
 
-	zz[zzbase+0] -= 0xffffffff00000000UL;   
-	zztime2 = get_itc() - zztime2;    
 	spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
 
-	zztime = get_itc() - zztime;    
-
-	zz[zzbase+6] += zztime;                                                                                             
-	if (zztime > zz[zzbase+7])
-	       zz[zzbase+7] = zztime; 
-
-	zz[zzbase+8] += zztime2;                                                                                             
-	if (zztime2 > zz[zzbase+9])
-	       zz[zzbase+9] = zztime2; 
-
 }
 
 /*
@@ -480,7 +158,7 @@
 	ptc1 = (long*)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_1);
 	piows = (long*)pda.pio_write_status_addr;
 
-	mycnode = local_cnodeid();
+	mycnode = numa_node_id();
 
 	for (cnode = 0; cnode < numnodes; cnode++) {
 		if (is_headless_node(cnode) || cnode == mycnode)
@@ -511,16 +189,10 @@
 void
 sn_send_IPI_phys(long physid, int vector, int delivery_mode)
 {
-	long		nasid, slice;
-	long		val;
+	long		nasid, slice, val;
+	unsigned long	flags=0;
 	volatile long	*p;
 
-#if defined(BUS_INT_WAR) && defined(CONFIG_SHUB_1_0_SPECIFIC)
-	if (vector != ap_wakeup_vector && delivery_mode == IA64_IPI_DM_INT) {
-		return;
-	}
-#endif
-
 	nasid = cpu_physical_id_to_nasid(physid);
         slice = cpu_physical_id_to_slice(physid);
 
@@ -532,12 +204,15 @@
 		(0x000feeUL<<SH_IPI_INT_BASE_SHFT);
 
 	mb();
+	if (enable_shub_wars_1_1() ) {
+		spin_lock_irqsave(&sn2_global_ptc_lock, flags);
+	}
 	pio_phys_write_mmr(p, val);
+	if (enable_shub_wars_1_1() ) {
+		wait_piowc();
+		spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
+	}
 
-#ifndef CONFIG_SHUB_1_0_SPECIFIC
-	/* doesnt work on shub 1.0 */
-	wait_piowc();
-#endif
 }
 
 /**
@@ -565,133 +240,3 @@
 
 	sn_send_IPI_phys(physid, vector, delivery_mode);
 }
-
-
-
-/* ----------------------------------------------------------------------------------------------- */
-
-#include <linux/proc_fs.h>
-
-
-static struct proc_dir_entry *ptcg_stats;
-
-static int
-ptcg_read_proc(char *buffer, char **start, off_t off, int count, int *eof, void *data)
-{
-	long cpu, *p, cnt;
-	int len = 0;
-
-	p = (long*)LOCAL_MMR_ADDR(SH_DIAG_MSG_DATA7L);
-	len += sprintf(buffer + len, "PTCG Stats (option 0x%lx)\n", use_tlb_hack);
-
-	len += sprintf(buffer + len, "%-14s", "CPU");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", cpu);
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "flushes");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", zz[cpu*16+0]&0xffffffff);
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "deadlocks");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", zz[cpu*16+1]);
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "aver-us");
-	for (cpu=0; cpu<smp_num_cpus; cpu++) {
-		cnt = zz[cpu*16+0]&0xffffffff;
-		len += sprintf(buffer + len, "%10ld", cnt ? zz[cpu*16+6]/(cnt)/cpu_data(cpu)->cyc_per_usec : 0);
-	}
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "max-us");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", zz[cpu*16+7]/cpu_data(cpu)->cyc_per_usec);
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "iaver-us");
-	for (cpu=0; cpu<smp_num_cpus; cpu++) {
-		cnt = zz[cpu*16+0]&0xffffffff;
-		len += sprintf(buffer + len, "%10ld", cnt ? zz[cpu*16+8]/(cnt)/cpu_data(cpu)->cyc_per_usec : 0);
-	}
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "imax-us");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", zz[cpu*16+9]/cpu_data(cpu)->cyc_per_usec);
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "long-piowc");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", zz[cpu*16+9]);
-	len += sprintf(buffer + len, "\n");
-
-        len += sprintf(buffer + len, "%-14s", "ipi-rp-error");
-        for (cpu=0; cpu<smp_num_cpus; cpu++) {
-                p = (long*)GLOBAL_MMR_ADDR(cpuid_to_nasid(cpu), SH_XN_IILB_LB_CMP_ENABLE0);
-                len += sprintf(buffer + len, "%10ld", *p);
-        }
-	len += sprintf(buffer + len, "\n");
-
-        len += sprintf(buffer + len, "%-14s", "lb-cb-error");
-        for (cpu=0; cpu<smp_num_cpus; cpu++) {
-                p = (long*)GLOBAL_MMR_ADDR(cpuid_to_nasid(cpu), SH_XN_IILB_LB_CMP_ENABLE1);
-                len += sprintf(buffer + len, "%10ld", *p);
-        }
-        len += sprintf(buffer + len, "\n");
-
-
-	if (len <= off+count) *eof = 1;
-	*start = buffer + off;
-	len   -= off;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
-}
-
-
-static int
-ptcg_write_proc (struct file *file, const char *userbuf, unsigned long count, void *data)
-{
-	extern long atoi(char *);
-	char		buf[80];
-	long		val;
-	long		cpu;
-	long		*p;
-
-	if (copy_from_user(buf, userbuf, count < sizeof(buf) ? count : sizeof(buf)))
-		return -EFAULT;
-
-	val = atoi(buf);
-	if (val&4) val |= 1;
-	use_tlb_hack = val;
-
-	memset((void*)zz, 0, sizeof(zz));
-
-	for (cpu=0; cpu<smp_num_cpus; cpu++) {
-		p = (long*)GLOBAL_MMR_ADDR(cpuid_to_nasid(cpu), SH_XN_IILB_LB_CMP_ENABLE0);
-		*p = 0;
-		p = (long*)GLOBAL_MMR_ADDR(cpuid_to_nasid(cpu), SH_XN_IILB_LB_CMP_ENABLE1);
-		*p = 0;
-	}
-	return count;
-}
-
-	
-
-static int
-sn2_ptcg_stats_init(void)
-{
-	if ((ptcg_stats = create_proc_entry("ptcg_stats", 0644, NULL)) == NULL) {
-		printk("unable to create proc entry for ptcg_stats");
-		return -1;
-	}
-	ptcg_stats->read_proc = ptcg_read_proc;
-	ptcg_stats->write_proc = ptcg_write_proc;
-	return 0;
-}
-
-#include <linux/module.h>
-module_init(sn2_ptcg_stats_init);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/sn_proc_fs.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/sn_proc_fs.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/sn_proc_fs.c	2003-07-05 18:09:46.000000000 -0700
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -31,6 +31,7 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 #include <linux/config.h>
+#include <asm/uaccess.h>
 
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
@@ -43,7 +44,7 @@
 	return sprintf(page, "%d\n", sn_local_partid());
 }
 
-struct proc_dir_entry * sgi_proc_dir = NULL;
+static struct proc_dir_entry * sgi_proc_dir;
 
 void
 register_sn_partition_id(void) {
@@ -96,4 +97,99 @@
 	}
 }
 
+// Disable forced interrupts, but leave the code in, just in case.
+int sn_force_interrupt_flag = 0;
+
+static int
+sn_force_interrupt_read_proc(char *page, char **start, off_t off,
+		int count, int *eof, void *data) {
+	if (sn_force_interrupt_flag) {
+		return sprintf(page, "Force interrupt is enabled\n");
+	}
+	return sprintf(page, "Force interrupt is disabled\n");
+}
+
+static int 
+sn_force_interrupt_write_proc(struct file *file, const char *buffer,
+                                        unsigned long count, void *data)
+{
+	if (*buffer == '0') {
+		sn_force_interrupt_flag = 0;
+	} else {
+		sn_force_interrupt_flag = 1;
+	}
+	return 1;
+}
+
+void
+register_sn_force_interrupt(void) {
+	struct proc_dir_entry *entry;
+
+	if (!sgi_proc_dir) {
+		sgi_proc_dir = proc_mkdir("sgi_sn", 0);
+	}
+	entry = create_proc_entry("sn_force_interrupt",0444, sgi_proc_dir);
+	if (entry) {
+		entry->nlink = 1;
+		entry->data = 0;
+		entry->read_proc = sn_force_interrupt_read_proc;
+		entry->write_proc = sn_force_interrupt_write_proc;
+	}
+}
+
+extern int sn_linkstats_get(char *);
+extern int sn_linkstats_reset(unsigned long);
+
+static int
+sn_linkstats_read_proc(char *page, char **start, off_t off,
+		int count, int *eof, void *data) {
+       
+	return sn_linkstats_get(page);
+}
+
+static int 
+sn_linkstats_write_proc(struct file *file, const char *buffer,
+                                        unsigned long count, void *data)
+{
+	char		s[64];
+	unsigned long	msecs;
+	int		e = count;
+
+	if (copy_from_user(s, buffer, count < sizeof(s) ? count : sizeof(s)))
+		e = -EFAULT;
+	else {
+		if (sscanf(s, "%lu", &msecs) != 1 || msecs < 5)
+			/* at least 5 milliseconds between updates */
+			e = -EINVAL;
+		else
+			sn_linkstats_reset(msecs);
+	}
+
+	return e;
+}
+
+void
+register_sn_linkstats(void) {
+	struct proc_dir_entry *entry;
+
+	if (!sgi_proc_dir) {
+		sgi_proc_dir = proc_mkdir("sgi_sn", 0);
+	}
+	entry = create_proc_entry("linkstats", 0444, sgi_proc_dir);
+	if (entry) {
+		entry->nlink = 1;
+		entry->data = 0;
+		entry->read_proc = sn_linkstats_read_proc;
+		entry->write_proc = sn_linkstats_write_proc;
+	}
+}
+
+void
+register_sn_procfs(void) {
+	register_sn_partition_id();
+	register_sn_serial_numbers();
+	register_sn_force_interrupt();
+	register_sn_linkstats();
+}
+
 #endif /* CONFIG_PROC_FS */
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/timer.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/timer.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn2/timer.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn2/timer.c	2003-07-05 18:09:46.000000000 -0700
@@ -0,0 +1,100 @@
+/*
+ * linux/arch/ia64/sn/kernel/sn2/timer.c
+ *
+ * Copyright (C) 2003 Silicon Graphics, Inc.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+
+#include <asm/hw_irq.h>
+#include <asm/system.h>
+
+#include <asm/sn/leds.h>
+#include <asm/sn/clksupport.h>
+
+
+extern unsigned long sn_rtc_cycles_per_second;
+static volatile unsigned long last_wall_rtc;
+
+/**
+ * gettimeoffset - number of usecs elapsed since &xtime was last updated
+ *
+ * This function is used by do_gettimeofday() to determine the number
+ * of usecs that have elapsed since the last update to &xtime.  On SN
+ * this is accomplished using the RTC built in to each Hub chip; each
+ * is guaranteed to be synchronized by the PROM, so a local read will
+ * suffice (GET_RTC_COUNTER() does this for us).  A snapshot of the RTC
+ * value is taken every time wall_jiffies is updated by the
+ * update_wall_time_hook (sn2_update_wall_time) which means we don't
+ * have to adjust for lost jiffies ticks or anything like that.
+ */
+extern unsigned long wall_jiffies; /* from kernel/timer.c */
+
+static volatile long rtc_offset;
+static long rtc_cycles_per_usec;
+static long rtc_per_timer_tick;
+
+unsigned long
+sn_gettimeoffset(void)
+{
+	long current_rtc, elapsed_rtc, old, new_offset;
+
+	do {
+		old = rtc_offset;
+		current_rtc = GET_RTC_COUNTER();
+
+		/*
+		 * Need to address wrapping here!
+		 */
+		elapsed_rtc = (long)(current_rtc - last_wall_rtc);
+
+		/*
+		 * This case is non lethal as the max() will take care of it.
+		 */
+#if 0
+		if (elapsed_rtc < 0) {
+			printk(KERN_ERR "sn_gettimeoffset(): time goes "
+			       "backwards!\n    current_rtc 0x%016lx, "
+			       "last_wall_rtc 0x%016lx, elapsed %08lx, "
+			       "offset %li\n", current_rtc, last_wall_rtc,
+			       elapsed_rtc, max(elapsed_rtc, rtc_offset)/
+			       rtc_cycles_per_usec);
+		}
+#endif
+
+		new_offset = max(elapsed_rtc, old);
+	} while (cmpxchg(&rtc_offset, old, new_offset) != old);
+
+	return new_offset / rtc_cycles_per_usec;
+}
+
+
+void sn2_update_wall_time(void)
+{
+	rtc_offset -= min(rtc_offset, rtc_per_timer_tick);
+	last_wall_rtc = GET_RTC_COUNTER();
+}
+
+
+void sn2_reset_wall_time(void)
+{
+	rtc_offset = 0;
+	last_wall_rtc = GET_RTC_COUNTER();
+}
+
+
+void __init
+sn_timer_init(void)
+{
+	rtc_per_timer_tick = sn_rtc_cycles_per_second / HZ;
+	rtc_cycles_per_usec = sn_rtc_cycles_per_second / 1000000;
+
+	last_wall_rtc = GET_RTC_COUNTER();
+	update_wall_time_hook = sn2_update_wall_time;
+	reset_wall_time_hook = sn2_reset_wall_time;
+	gettimeoffset = sn_gettimeoffset;
+}
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn_asm.S linux-2.4.22-pre3/arch/ia64/sn/kernel/sn_asm.S
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn_asm.S	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn_asm.S	1969-12-31 16:00:00.000000000 -0800
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/config.h>
-#ifdef CONFIG_IA64_SGI_AUTOTEST
-
-// Testing only.
-// Routine will cause MCAs
-//   zzzmca(n)
-//      n=0 MCA via duplicate TLB dropin
-//      n=1 MCA via read of garbage address
-//      n=2 MCA via lfetch read of garbage address
-//
-
-#define ITIR(key, ps)           ((key<<8) | (ps<<2))
-#define TLB_PAGESIZE            28                      // Use 256MB pages for now.
-
-                        .global zzzmca
-                        .proc   zzzmca
-zzzmca:
-                        alloc   loc4       = ar.pfs,2,8,1,0;;
-                        cmp.ne  p6,p0=r32,r0;;
-                        movl    r2=0x2dead
-                        movl    r3=0x3dead
-                        movl    r15=0x15dead
-                        movl    r16=0x16dead
-                        movl    r31=0x31dead
-                        movl    loc0=0x34beef
-                        movl    loc1=0x35beef
-                        movl    loc2=0x36beef
-                        movl    loc3=0x37beef
-                        movl    out0=0x42beef
-
-                        movl    r20=0x32feed;;
-                        mov     ar32=r20
-                        movl    r20=0x36feed;;
-                        mov     ar36=r20
-                        movl    r20=0x65feed;;
-                        mov     ar65=r20
-                        movl    r20=0x66feed;;
-                        mov     ar66=r20
-
-(p6)                    br.cond.sptk    1f
-
-                        rsm      0x2000;;
-                        srlz.d;
-                        mov      r11      = 5
-                        mov      r3       = ITIR(0,TLB_PAGESIZE);;
-                        mov      cr.itir  = r3
-                        mov      r10      = 0;;
-                        itr.d    dtr[r11] = r10;;
-                        mov      r11      = 6
-
-                        itr.d    dtr[r11] = r10;;
-                        br      9f
-
-1:
-			cmp.eq	p6,p7=1,r32
-#ifdef CONFIG_IA64_SGI_SN1
-                        movl    r8=0xe00000fe00000048;;
-#else
-                        movl    r8=0xe0007fb000000048;;
-#endif
-                 (p6)   ld8     r9=[r8]
-                 (p7)   lfetch.fault.nt2  [r8]
-			;;
-                        mf
-			;;
-                        mf.a
-			;;
-                        srlz.d
-
-9:                      mov     ar.pfs=loc4
-                        br.ret.sptk     rp
-
-                        .endp   zzzmca
-
-#endif
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sn_ksyms.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sn_ksyms.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sn_ksyms.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sn_ksyms.c	2003-07-05 18:09:46.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -18,8 +18,8 @@
 #include <asm/sn/intr.h>
 
 #include <linux/mm.h>
-#include <linux/devfs_fs_kernel.h>
-extern devfs_handle_t          base_io_scsi_ctlr_vhdl[];
+#include <asm/sn/sgi.h>
+extern vertex_hdl_t          base_io_scsi_ctlr_vhdl[];
 #include <asm/sn/types.h>
 extern cnodeid_t master_node_get(devfs_handle_t vhdl);
 #include <asm/sn/arch.h>
@@ -31,9 +31,9 @@
  * symbols referenced by the PCIBA module
  */
 #include <asm/sn/invent.h>
-#include <asm/sn/hack.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/pci/pciio.h>
+#include <asm/sn/sn_cpuid.h>
 
 devfs_handle_t
 devfn_to_vertex(unsigned char busnum, unsigned int devfn);
@@ -54,29 +54,26 @@
 EXPORT_SYMBOL(sn_send_IPI_phys);
 
 /* symbols referenced by partitioning modules */
-#include <asm/sn/bte_copy.h>
+#include <asm/sn/bte.h>
+EXPORT_SYMBOL(bte_copy);
 EXPORT_SYMBOL(bte_unaligned_copy);
 #include <asm/sal.h>
 EXPORT_SYMBOL(ia64_sal);
+EXPORT_SYMBOL(physical_node_map);
 
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn_sal.h>
 EXPORT_SYMBOL(sal_lock);
 EXPORT_SYMBOL(sn_partid);
 EXPORT_SYMBOL(sn_local_partid);
 EXPORT_SYMBOL(sn_system_serial_number_string);
 EXPORT_SYMBOL(sn_partition_serial_number);
-#endif
+
+EXPORT_SYMBOL(sn_mmiob);
 
 /* added by tduffy 04.08.01 to fix depmod issues */
 #include <linux/mmzone.h>
 
-#ifdef BUS_INT_WAR
-extern void sn_add_polled_interrupt(int, int);
-extern void sn_delete_polled_interrupt(int);
-EXPORT_SYMBOL(sn_add_polled_interrupt);
-EXPORT_SYMBOL(sn_delete_polled_interrupt);
-#endif
-
 extern nasid_t master_nasid;
 EXPORT_SYMBOL(master_nasid);
+
+EXPORT_SYMBOL(sn_flush_all_caches);
diff -urN linux-2.4.22-pre2/arch/ia64/sn/kernel/sv.c linux-2.4.22-pre3/arch/ia64/sn/kernel/sv.c
--- linux-2.4.22-pre2/arch/ia64/sn/kernel/sv.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/kernel/sv.c	2003-07-05 18:09:46.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This implemenation of synchronization variables is heavily based on
  * one done by Steve Lord <lord@sgi.com>
diff -urN linux-2.4.22-pre2/arch/ia64/sn/tools/make_textsym linux-2.4.22-pre3/arch/ia64/sn/tools/make_textsym
--- linux-2.4.22-pre2/arch/ia64/sn/tools/make_textsym	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/sn/tools/make_textsym	1969-12-31 16:00:00.000000000 -0800
@@ -1,171 +0,0 @@
-#!/bin/sh
-#
-# Build a textsym file for use in the Arium ITP probe.
-#
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
-#
-
-help() {
-cat <<END
-Build a WinDD "symtxt" file for use with the Arium ECM-30 probe.
-
-	Usage: $0 [<vmlinux file> [<output file>]]
-		If no input file is specified, it defaults to vmlinux.
-		If no output file name is specified, it defaults to "textsym".
-END
-exit 1
-}
-
-err () {
-	echo "ERROR - $*" >&2
-	exit 1
-}
-
-
-OPTS="H"
-while getopts "$OPTS" c ; do
-	case $c in
-		H)  help;;
-		\?) help;;
-	esac
-
-done
-shift `expr $OPTIND - 1`
-
-LINUX=${1:-vmlinux}
-TEXTSYM=${2:-${LINUX}.sym}
-TMPSYM=${2:-${LINUX}.sym.tmp}
-trap "/bin/rm -f $TMPSYM" 0
-
-[ -f $VMLINUX ] || help
-
-$OBJDUMP -t $LINUX | egrep -v '__ks' | sort > $TMPSYM
-SN1=`egrep "dig_setup|Synergy_da_indr" $TMPSYM|wc -l`
-
-# Dataprefix and textprefix correspond to the VGLOBAL_BASE and VPERNODE_BASE.
-# Eventually, these values should be:
-#	dataprefix	ffffffff
-#	textprefix	fffffffe
-# but right now they're still changing, so make them dynamic.
-dataprefix=`awk ' / \.data	/ { print substr($1, 0, 8) ; exit ; }' $TMPSYM`
-textprefix=`awk ' / \.text	/ { print substr($1, 0, 8) ; exit ; }' $TMPSYM`
-
-# pipe everything thru sort
-echo "TEXTSYM V1.0"
-(cat <<END 
-GLOBAL | ${textprefix}00000000 | CODE | VEC_VHPT_Translation_0000
-GLOBAL | ${textprefix}00000400 | CODE | VEC_ITLB_0400
-GLOBAL | ${textprefix}00000800 | CODE | VEC_DTLB_0800
-GLOBAL | ${textprefix}00000c00 | CODE | VEC_Alt_ITLB_0c00
-GLOBAL | ${textprefix}00001000 | CODE | VEC_Alt_DTLB_1000
-GLOBAL | ${textprefix}00001400 | CODE | VEC_Data_nested_TLB_1400
-GLOBAL | ${textprefix}00001800 | CODE | VEC_Instruction_Key_Miss_1800
-GLOBAL | ${textprefix}00001c00 | CODE | VEC_Data_Key_Miss_1c00
-GLOBAL | ${textprefix}00002000 | CODE | VEC_Dirty-bit_2000
-GLOBAL | ${textprefix}00002400 | CODE | VEC_Instruction_Access-bit_2400
-GLOBAL | ${textprefix}00002800 | CODE | VEC_Data_Access-bit_2800
-GLOBAL | ${textprefix}00002c00 | CODE | VEC_Break_instruction_2c00
-GLOBAL | ${textprefix}00003000 | CODE | VEC_External_Interrupt_3000
-GLOBAL | ${textprefix}00003400 | CODE | VEC_Reserved_3400
-GLOBAL | ${textprefix}00003800 | CODE | VEC_Reserved_3800
-GLOBAL | ${textprefix}00003c00 | CODE | VEC_Reserved_3c00
-GLOBAL | ${textprefix}00004000 | CODE | VEC_Reserved_4000
-GLOBAL | ${textprefix}00004400 | CODE | VEC_Reserved_4400
-GLOBAL | ${textprefix}00004800 | CODE | VEC_Reserved_4800
-GLOBAL | ${textprefix}00004c00 | CODE | VEC_Reserved_4c00
-GLOBAL | ${textprefix}00005000 | CODE | VEC_Page_Not_Present_5000
-GLOBAL | ${textprefix}00005100 | CODE | VEC_Key_Permission_5100
-GLOBAL | ${textprefix}00005200 | CODE | VEC_Instruction_Access_Rights_5200
-GLOBAL | ${textprefix}00005300 | CODE | VEC_Data_Access_Rights_5300
-GLOBAL | ${textprefix}00005400 | CODE | VEC_General_Exception_5400
-GLOBAL | ${textprefix}00005500 | CODE | VEC_Disabled_FP-Register_5500
-GLOBAL | ${textprefix}00005600 | CODE | VEC_Nat_Consumption_5600
-GLOBAL | ${textprefix}00005700 | CODE | VEC_Speculation_5700
-GLOBAL | ${textprefix}00005800 | CODE | VEC_Reserved_5800
-GLOBAL | ${textprefix}00005900 | CODE | VEC_Debug_5900
-GLOBAL | ${textprefix}00005a00 | CODE | VEC_Unaligned_Reference_5a00
-GLOBAL | ${textprefix}00005b00 | CODE | VEC_Unsupported_Data_Reference_5b00
-GLOBAL | ${textprefix}00005c00 | CODE | VEC_Floating-Point_Fault_5c00
-GLOBAL | ${textprefix}00005d00 | CODE | VEC_Floating_Point_Trap_5d00
-GLOBAL | ${textprefix}00005e00 | CODE | VEC_Lower_Privilege_Tranfer_Trap_5e00
-GLOBAL | ${textprefix}00005f00 | CODE | VEC_Taken_Branch_Trap_5f00
-GLOBAL | ${textprefix}00006000 | CODE | VEC_Single_Step_Trap_6000
-GLOBAL | ${textprefix}00006100 | CODE | VEC_Reserved_6100
-GLOBAL | ${textprefix}00006200 | CODE | VEC_Reserved_6200
-GLOBAL | ${textprefix}00006300 | CODE | VEC_Reserved_6300
-GLOBAL | ${textprefix}00006400 | CODE | VEC_Reserved_6400
-GLOBAL | ${textprefix}00006500 | CODE | VEC_Reserved_6500
-GLOBAL | ${textprefix}00006600 | CODE | VEC_Reserved_6600
-GLOBAL | ${textprefix}00006700 | CODE | VEC_Reserved_6700
-GLOBAL | ${textprefix}00006800 | CODE | VEC_Reserved_6800
-GLOBAL | ${textprefix}00006900 | CODE | VEC_IA-32_Exeception_6900
-GLOBAL | ${textprefix}00006a00 | CODE | VEC_IA-32_Intercept_6a00
-GLOBAL | ${textprefix}00006b00 | CODE | VEC_IA-32_Interrupt_6b00
-GLOBAL | ${textprefix}00006c00 | CODE | VEC_Reserved_6c00
-GLOBAL | ${textprefix}00006d00 | CODE | VEC_Reserved_6d00
-GLOBAL | ${textprefix}00006e00 | CODE | VEC_Reserved_6e00
-GLOBAL | ${textprefix}00006f00 | CODE | VEC_Reserved_6f00
-GLOBAL | ${textprefix}00007000 | CODE | VEC_Reserved_7000
-GLOBAL | ${textprefix}00007100 | CODE | VEC_Reserved_7100
-GLOBAL | ${textprefix}00007200 | CODE | VEC_Reserved_7200
-GLOBAL | ${textprefix}00007300 | CODE | VEC_Reserved_7300
-GLOBAL | ${textprefix}00007400 | CODE | VEC_Reserved_7400
-GLOBAL | ${textprefix}00007500 | CODE | VEC_Reserved_7500
-GLOBAL | ${textprefix}00007600 | CODE | VEC_Reserved_7600
-GLOBAL | ${textprefix}00007700 | CODE | VEC_Reserved_7700
-GLOBAL | ${textprefix}00007800 | CODE | VEC_Reserved_7800
-GLOBAL | ${textprefix}00007900 | CODE | VEC_Reserved_7900
-GLOBAL | ${textprefix}00007a00 | CODE | VEC_Reserved_7a00
-GLOBAL | ${textprefix}00007b00 | CODE | VEC_Reserved_7b00
-GLOBAL | ${textprefix}00007c00 | CODE | VEC_Reserved_7c00
-GLOBAL | ${textprefix}00007d00 | CODE | VEC_Reserved_7d00
-GLOBAL | ${textprefix}00007e00 | CODE | VEC_Reserved_7e00
-GLOBAL | ${textprefix}00007f00 | CODE | VEC_Reserved_7f00
-END
-
-
-awk '
-/__start_gate_section/ {start=1}
-/^'${dataprefix}\|${textprefix}'/ {
-	if ($4 == ".kdb")
-		next
-	if (start && substr($NF,1,1) != "0") {
-		type = substr($0,26,5)
-		if (type == ".text")
-			printf "GLOBAL | %s | CODE | %s\n", $1, $NF
-		else {
-			n = 0
-			s = $(NF-1)
-			while (length(s) > 0) {
-				n = n*16 + substr(s,1,1)
-				s = substr(s,2)
-			}
-			printf "GLOBAL | %s | DATA | %s | %d\n", $1, $NF, n
-		}
-	}
-	if($NF == "_end") 
-		exit
-
-}
-' $TMPSYM ) | egrep -v " __device| __vendor" | awk -v sn1="$SN1" '
-/GLOBAL/ {
-	print $0
-	if (sn1 != 0) {
-		/* 32 bits of sn1 physical addrs, */
-		print substr($0,1,9) "04" substr($0,20,16) "Phy_" substr($0,36)
-	} else {
-		/* 38 bits of sn2 physical addrs, need addr space bits */
-		print substr($0,1,9) "3004" substr($0,20,16) "Phy_" substr($0,36)
-	}
-
-} ' | sort -k3
-
-N=`wc -l $TEXTSYM|awk '{print $1}'`
-echo "Generated TEXTSYM file" >&2
-echo "  $LINUX --> $TEXTSYM" >&2
-echo "  Found $N symbols" >&2
diff -urN linux-2.4.22-pre2/arch/ia64/tools/print_offsets.c linux-2.4.22-pre3/arch/ia64/tools/print_offsets.c
--- linux-2.4.22-pre2/arch/ia64/tools/print_offsets.c	2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.22-pre3/arch/ia64/tools/print_offsets.c	2003-07-05 18:09:46.000000000 -0700
@@ -10,7 +10,7 @@
  * gets translated into an assembly file which, in turn, is processed
  * by awk to generate offsets.h.  So if you make any changes to this
  * file, be sure to verify that the awk procedure still works (see
- * prin_offsets.awk).
+ * print_offsets.awk).
  */
 #include <linux/config.h>
 
diff -urN linux-2.4.22-pre2/arch/ia64/vmlinux.lds.S linux-2.4.22-pre3/arch/ia64/vmlinux.lds.S
--- linux-2.4.22-pre2/arch/ia64/vmlinux.lds.S	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ia64/vmlinux.lds.S	2003-07-05 18:09:46.000000000 -0700
@@ -27,6 +27,7 @@
 
   _text = .;
   _stext = .;
+
   .text : AT(ADDR(.text) - PAGE_OFFSET)
     {
 	*(.text.ivt)
@@ -47,38 +48,48 @@
 
   /* Exception table */
   . = ALIGN(16);
-  __start___ex_table = .;
   __ex_table : AT(ADDR(__ex_table) - PAGE_OFFSET)
-	{ *(__ex_table) }
-  __stop___ex_table = .;
+	{
+	  __start___ex_table = .;
+	  *(__ex_table)
+	  __stop___ex_table = .;
+	}
 
 #if defined(CONFIG_IA64_GENERIC)
   /* Machine Vector */
   . = ALIGN(16);
-  machvec_start = .;
   .machvec : AT(ADDR(.machvec) - PAGE_OFFSET)
-	{ *(.machvec) }
-  machvec_end = .;
+	{
+	  machvec_start = .;
+	  *(.machvec)
+	  machvec_end = .;
+	}
 #endif
 
-  __start___ksymtab = .;	/* Kernel symbol table */
   __ksymtab : AT(ADDR(__ksymtab) - PAGE_OFFSET)
-	{ *(__ksymtab) }
-  __stop___ksymtab = .;
+	{
+	  __start___ksymtab = .;	/* Kernel symbol table */
+	  *(__ksymtab)
+	  __stop___ksymtab = .;
+	}
 
-  __start___kallsyms = .;	/* All kernel symbols for debugging */
   __kallsyms : AT(ADDR(__kallsyms) - PAGE_OFFSET)
-	{ *(__kallsyms) }
-  __stop___kallsyms = .;
+	{
+	  __start___kallsyms = .;	/* All kernel symbols for debugging */
+	  *(__kallsyms)
+	  __stop___kallsyms = .;
+	}
 
   /* Unwind info & table: */
   . = ALIGN(8);
   .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - PAGE_OFFSET)
 	{ *(.IA_64.unwind_info*) }
-  ia64_unw_start = .;
   .IA_64.unwind : AT(ADDR(.IA_64.unwind) - PAGE_OFFSET)
-	{ *(.IA_64.unwind*) }
-  ia64_unw_end = .;
+	{
+	  ia64_unw_start = .;
+	  *(.IA_64.unwind*)
+	  ia64_unw_end = .;
+	}
 
   .rodata : AT(ADDR(.rodata) - PAGE_OFFSET)
 	{ *(.rodata) *(.rodata.*) }
@@ -97,14 +108,18 @@
   .data.init : AT(ADDR(.data.init) - PAGE_OFFSET)
 	{ *(.data.init) }
    . = ALIGN(16);
-  __setup_start = .;
   .setup.init : AT(ADDR(.setup.init) - PAGE_OFFSET)
-        { *(.setup.init) }
-  __setup_end = .;
-  __initcall_start = .;
+        {
+	  __setup_start = .;
+	  *(.setup.init)
+	  __setup_end = .;
+	}
   .initcall.init : AT(ADDR(.initcall.init) - PAGE_OFFSET)
-        { *(.initcall.init) }
-  __initcall_end = .;
+        {
+	  __initcall_start = .;
+	  *(.initcall.init)
+	  __initcall_end = .;
+	}
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
diff -urN linux-2.4.22-pre2/arch/m68k/apollo/config.c linux-2.4.22-pre3/arch/m68k/apollo/config.c
--- linux-2.4.22-pre2/arch/m68k/apollo/config.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/m68k/apollo/config.c	2003-07-05 18:09:46.000000000 -0700
@@ -183,10 +183,6 @@
 	mach_hwclk           = dn_dummy_hwclk; /* */
 	mach_set_clock_mmss  = dn_dummy_set_clock_mmss; /* */
 	mach_process_int     = dn_process_int;
-#ifdef CONFIG_BLK_DEV_FD
-	mach_floppy_init     = dn_dummy_floppy_init;
-	mach_floppy_setup    = dn_dummy_floppy_setup;
-#endif
 	mach_reset	     = dn_dummy_reset;  /* */
 #ifdef CONFIG_DUMMY_CONSOLE
         conswitchp           = &dummy_con;
diff -urN linux-2.4.22-pre2/arch/m68k/config.in linux-2.4.22-pre3/arch/m68k/config.in
--- linux-2.4.22-pre2/arch/m68k/config.in	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/m68k/config.in	2003-07-05 18:09:46.000000000 -0700
@@ -562,4 +562,5 @@
 
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -urN linux-2.4.22-pre2/arch/m68k/kernel/m68k_ksyms.c linux-2.4.22-pre3/arch/m68k/kernel/m68k_ksyms.c
--- linux-2.4.22-pre2/arch/m68k/kernel/m68k_ksyms.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/m68k/kernel/m68k_ksyms.c	2003-07-05 18:09:46.000000000 -0700
@@ -44,7 +44,6 @@
 EXPORT_SYMBOL(mm_ptov);
 EXPORT_SYMBOL(mm_end_of_chunk);
 #endif /* !CONFIG_SINGLE_MEMORY_CHUNK */
-EXPORT_SYMBOL(mm_vtop_fallback);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(kernel_set_cachemode);
diff -urN linux-2.4.22-pre2/arch/m68k/mac/config.c linux-2.4.22-pre3/arch/m68k/mac/config.c
--- linux-2.4.22-pre2/arch/m68k/mac/config.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/m68k/mac/config.c	2003-07-05 18:09:46.000000000 -0700
@@ -91,7 +91,7 @@
 extern void mackbd_leds(unsigned int leds);
 extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode);
 
-extern void mac_hid_init_hw(void);
+extern void __init mac_hid_init_hw(void);
 extern int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode);
 
 #ifdef CONFIG_MAGIC_SYSRQ
@@ -202,6 +202,14 @@
 	restore_flags(cpu_flags);
 }
 
+#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID)
+static int __init mac_keyb_init(void)
+{
+	mac_hid_init_hw();
+	return 0;
+}
+#endif
+
 void __init config_mac(void)
 {
 	if (!MACH_IS_MAC) {
@@ -210,7 +218,7 @@
 
 #ifdef CONFIG_VT
 #ifdef CONFIG_INPUT_ADBHID
-	mach_keyb_init       = mac_hid_init_hw;
+	mach_keyb_init       = mac_keyb_init;
 	mach_kbd_translate   = mac_hid_kbd_translate;
 #ifdef CONFIG_MAGIC_SYSRQ
 #ifdef CONFIG_MAC_ADBKEYCODES
diff -urN linux-2.4.22-pre2/arch/m68k/mm/memory.c linux-2.4.22-pre3/arch/m68k/mm/memory.c
--- linux-2.4.22-pre2/arch/m68k/mm/memory.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/m68k/mm/memory.c	2003-07-05 18:09:46.000000000 -0700
@@ -196,34 +196,6 @@
 	return 0;
 }
 
-static unsigned long transp_transl_matches( unsigned long regval,
-					    unsigned long vaddr )
-{
-    unsigned long base, mask;
-
-    /* enabled? */
-    if (!(regval & 0x8000))
-	return( 0 );
-
-    if (CPU_IS_030) {
-	/* function code match? */
-	base = (regval >> 4) & 7;
-	mask = ~(regval & 7);
-	if (((SUPER_DATA ^ base) & mask) != 0)
-	    return 0;
-    }
-    else {
-	/* must not be user-only */
-	if ((regval & 0x6000) == 0)
-	    return( 0 );
-    }
-
-    /* address match? */
-    base = regval & 0xff000000;
-    mask = ~(regval << 8) & 0xff000000;
-    return (((unsigned long)vaddr ^ base) & mask) == 0;
-}
-
 #if DEBUG_INVALID_PTOV
 int mm_inv_cnt = 5;
 #endif
@@ -253,134 +225,9 @@
 	if (voff == 0)
 		return m68k_memory[i-1].addr + m68k_memory[i-1].size;
 
-	return mm_vtop_fallback(vaddr);
-}
-#endif
-
-/* Separate function to make the common case faster (needs to save less
-   registers) */
-unsigned long mm_vtop_fallback(unsigned long vaddr)
-{
-	/* not in one of the memory chunks; test for applying transparent
-	 * translation */
-
-	if (CPU_IS_030) {
-	    unsigned long ttreg;
-	    
-	    asm volatile( ".chip 68030\n\t"
-			  "pmove %/tt0,%0@\n\t"
-			  ".chip 68k"
-			  : : "a" (&ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	    asm volatile( ".chip 68030\n\t"
-			  "pmove %/tt1,%0@\n\t"
-			  ".chip 68k"
-			  : : "a" (&ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	}
-	else if (CPU_IS_040_OR_060) {
-	    unsigned long ttreg;
-	    
-	    asm volatile( ".chip 68040\n\t"
-			  "movec %%dtt0,%0\n\t"
-			  ".chip 68k"
-			  : "=d" (ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	    asm volatile( ".chip 68040\n\t"
-			  "movec %%dtt1,%0\n\t"
-			  ".chip 68k"
-			  : "=d" (ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	}
-
-	/* no match, too, so get the actual physical address from the MMU. */
-
-	if (CPU_IS_060) {
-	  mm_segment_t fs = get_fs();
-	  unsigned long  paddr;
-
-	  set_fs (MAKE_MM_SEG(SUPER_DATA));
-
-	  /* The PLPAR instruction causes an access error if the translation
-	   * is not possible. To catch this we use the same exception mechanism
-	   * as for user space accesses in <asm/uaccess.h>. */
-	  asm volatile (".chip 68060\n"
-			"1: plpar (%0)\n"
-			".chip 68k\n"
-			"2:\n"
-			".section .fixup,\"ax\"\n"
-			"   .even\n"
-			"3: lea -1,%0\n"
-			"   jra 2b\n"
-			".previous\n"
-			".section __ex_table,\"a\"\n"
-			"   .align 4\n"
-			"   .long 1b,3b\n"
-			".previous"
-			: "=a" (paddr)
-			: "0" (vaddr));
-	  set_fs (fs);
-
-	  return paddr;
-
-	} else if (CPU_IS_040) {
-	  unsigned long mmusr;
-	  mm_segment_t fs = get_fs();
-
-	  set_fs (MAKE_MM_SEG(SUPER_DATA));
-
-	  asm volatile (".chip 68040\n\t"
-			"ptestr (%1)\n\t"
-			"movec %%mmusr, %0\n\t"
-			".chip 68k"
-			: "=r" (mmusr)
-			: "a" (vaddr));
-	  set_fs (fs);
-
-	  if (mmusr & MMU_T_040) {
-	    return (unsigned long)vaddr;	/* Transparent translation */
-	  }
-	  if (mmusr & MMU_R_040)
-	    return (mmusr & PAGE_MASK) | ((unsigned long)vaddr & (PAGE_SIZE-1));
-
-	  printk("VTOP040: bad virtual address %lx (%lx)", vaddr, mmusr);
-	  return -1;
-	} else {
-	  volatile unsigned short temp;
-	  unsigned short mmusr;
-	  unsigned long *descaddr;
-
-	  asm volatile ("ptestr #5,%2@,#7,%0\n\t"
-			"pmove %/psr,%1@"
-			: "=a&" (descaddr)
-			: "a" (&temp), "a" (vaddr));
-	  mmusr = temp;
-
-	  if (mmusr & (MMU_I|MMU_B|MMU_L))
-	    printk("VTOP030: bad virtual address %lx (%x)\n", vaddr, mmusr);
-
-	  descaddr = phys_to_virt((unsigned long)descaddr);
-
-	  switch (mmusr & MMU_NUM) {
-	  case 1:
-	    return (*descaddr & 0xfe000000) | ((unsigned long)vaddr & 0x01ffffff);
-	  case 2:
-	    return (*descaddr & 0xfffc0000) | ((unsigned long)vaddr & 0x0003ffff);
-	  case 3:
-	    return (*descaddr & PAGE_MASK) | ((unsigned long)vaddr & (PAGE_SIZE-1));
-	  default:
-	    printk("VTOP: bad levels (%u) for virtual address %lx\n", 
-		   mmusr & MMU_NUM, vaddr);
-	  }
-	}
-
-	printk("VTOP: bad virtual address %lx\n", vaddr);
 	return -1;
 }
+#endif
 
 #ifndef CONFIG_SINGLE_MEMORY_CHUNK
 unsigned long mm_ptov (unsigned long paddr)
@@ -406,29 +253,6 @@
 			paddr, __builtin_return_address(0));
 	}
 #endif
-	/*
-	 * assume that the kernel virtual address is the same as the
-	 * physical address.
-	 *
-	 * This should be reasonable in most situations:
-	 *  1) They shouldn't be dereferencing the virtual address
-	 *     unless they are sure that it is valid from kernel space.
-	 *  2) The only usage I see so far is converting a page table
-	 *     reference to some non-FASTMEM address space when freeing
-         *     mmaped "/dev/mem" pages.  These addresses are just passed
-	 *     to "free_page", which ignores addresses that aren't in
-	 *     the memory list anyway.
-	 *
-	 */
-
-#ifdef CONFIG_AMIGA
-	/*
-	 * if on an amiga and address is in first 16M, move it 
-	 * to the ZTWO_VADDR range
-	 */
-	if (MACH_IS_AMIGA && paddr < 16*1024*1024)
-		return ZTWO_VADDR(paddr);
-#endif
 	return -1;
 }
 #endif
diff -urN linux-2.4.22-pre2/arch/m68k/mm/motorola.c linux-2.4.22-pre3/arch/m68k/mm/motorola.c
--- linux-2.4.22-pre2/arch/m68k/mm/motorola.c	2001-04-06 10:42:48.000000000 -0700
+++ linux-2.4.22-pre3/arch/m68k/mm/motorola.c	2003-07-05 18:09:46.000000000 -0700
@@ -226,18 +226,6 @@
 		for (i = 0; i < 16; i++)
 			pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
 	}
-	/* Fix the PAGE_NONE value. */
-	if (CPU_IS_040_OR_060) {
-		/* On the 680[46]0 we can use the _PAGE_SUPER bit.  */
-		pgprot_val(protection_map[0]) |= _PAGE_SUPER;
-		pgprot_val(protection_map[VM_SHARED]) |= _PAGE_SUPER;
-	} else {
-		/* Otherwise we must fake it. */
-		pgprot_val(protection_map[0]) &= ~_PAGE_PRESENT;
-		pgprot_val(protection_map[0]) |= _PAGE_FAKE_SUPER;
-		pgprot_val(protection_map[VM_SHARED]) &= ~_PAGE_PRESENT;
-		pgprot_val(protection_map[VM_SHARED]) |= _PAGE_FAKE_SUPER;
-	}
 
 	/*
 	 * Map the physical memory available into the kernel virtual
diff -urN linux-2.4.22-pre2/arch/mips/config-shared.in linux-2.4.22-pre3/arch/mips/config-shared.in
--- linux-2.4.22-pre2/arch/mips/config-shared.in	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/mips/config-shared.in	2003-07-05 18:09:46.000000000 -0700
@@ -800,4 +800,5 @@
 fi
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -urN linux-2.4.22-pre2/arch/mips/kernel/sysmips.c linux-2.4.22-pre3/arch/mips/kernel/sysmips.c
--- linux-2.4.22-pre2/arch/mips/kernel/sysmips.c	2002-11-28 15:53:10.000000000 -0800
+++ linux-2.4.22-pre3/arch/mips/kernel/sysmips.c	2003-07-05 18:09:46.000000000 -0700
@@ -65,7 +65,7 @@
 			return -EFAULT;
 
 		down_write(&uts_sem);
-		strncpy(system_utsname.nodename, name, len);
+		strncpy(system_utsname.nodename, nodename, len);
 		system_utsname.nodename[len] = '\0';
 		up_write(&uts_sem);
 		return 0;
diff -urN linux-2.4.22-pre2/arch/mips64/kernel/syscall.c linux-2.4.22-pre3/arch/mips64/kernel/syscall.c
--- linux-2.4.22-pre2/arch/mips64/kernel/syscall.c	2002-11-28 15:53:10.000000000 -0800
+++ linux-2.4.22-pre3/arch/mips64/kernel/syscall.c	2003-07-05 18:09:46.000000000 -0700
@@ -207,7 +207,7 @@
 			return -EFAULT;
 
 		down_write(&uts_sem);
-		strncpy(system_utsname.nodename, name, len);
+		strncpy(system_utsname.nodename, nodename, len);
 		system_utsname.nodename[len] = '\0';
 		up_write(&uts_sem);
 		return 0;
diff -urN linux-2.4.22-pre2/arch/parisc/config.in linux-2.4.22-pre3/arch/parisc/config.in
--- linux-2.4.22-pre2/arch/parisc/config.in	2002-11-28 15:53:10.000000000 -0800
+++ linux-2.4.22-pre3/arch/parisc/config.in	2003-07-05 18:09:46.000000000 -0700
@@ -196,4 +196,5 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -urN linux-2.4.22-pre2/arch/ppc/config.in linux-2.4.22-pre3/arch/ppc/config.in
--- linux-2.4.22-pre2/arch/ppc/config.in	2003-07-05 18:09:16.000000000 -0700
+++ linux-2.4.22-pre3/arch/ppc/config.in	2003-07-05 18:09:46.000000000 -0700
@@ -438,6 +438,7 @@
 
 source net/bluetooth/Config.in
 
+source crypto/Config.in
 source lib/Config.in
 
 mainmenu_option next_comment
diff -urN linux-2.4.22-pre2/arch/ppc/kernel/cpu_setup_6xx.S linux-2.4.22-pre3/arch/ppc/kernel/cpu_setup_6xx.S
--- linux-2.4.22-pre2/arch/ppc/kernel/cpu_setup_6xx.S	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ppc/kernel/cpu_setup_6xx.S	2003-07-05 18:09:46.000000000 -0700
@@ -248,12 +248,13 @@
 /* Definitions for the table use to save CPU states */
 #define CS_HID0		0
 #define CS_HID1		4
-#define	CS_MSSCR0	8
-#define CS_MSSSR0	12
-#define CS_ICTRL	16
-#define CS_LDSTCR	20
-#define CS_LDSTDB	24
-#define CS_SIZE		28
+#define CS_HID2		8
+#define	CS_MSSCR0	12
+#define CS_MSSSR0	16
+#define CS_ICTRL	20
+#define CS_LDSTCR	24
+#define CS_LDSTDB	28
+#define CS_SIZE		32
 
 	.data
 	.balign	L1_CACHE_LINE_SIZE
@@ -316,6 +317,13 @@
 	/* Backup 750FX specific registers */
 	mfspr	r4,SPRN_HID1
 	stw	r4,CS_HID1(r5)
+	/* If rev 2.x, backup HID2 */
+	mfspr	r3,PVR
+	andi.	r3,r3,0xff00
+	cmpi	cr0,r3,0x0200
+	bne	1f
+	mfspr	r4,SPRN_HID2
+	stw	r4,CS_HID2(r5)
 1:
 	mtcr	r7
 	blr
@@ -395,9 +403,19 @@
 	sync
 2:	bne	cr5,1f
 	/* Restore 750FX specific registers
-	 * that is restore PLL config & switch
-	 * to PLL 0
+	 * that is restore HID2 on rev 2.x and PLL config & switch
+	 * to PLL 0 on all
 	 */
+	/* If rev 2.x, restore HID2 with low voltage bit cleared */
+	mfspr	r3,PVR
+	andi.	r3,r3,0xff00
+	cmpi	cr0,r3,0x0200
+	bne	4f
+	lwz	r4,CS_HID2(r5)
+	rlwinm	r4,r4,0,19,17
+	mtspr	SPRN_HID2,r4
+	sync
+4:
 	lwz	r4,CS_HID1(r5)
 	rlwinm  r5,r4,0,16,14
 	mtspr	SPRN_HID1,r5
diff -urN linux-2.4.22-pre2/arch/ppc/kernel/cputable.c linux-2.4.22-pre3/arch/ppc/kernel/cputable.c
--- linux-2.4.22-pre2/arch/ppc/kernel/cputable.c	2003-07-05 18:09:16.000000000 -0700
+++ linux-2.4.22-pre3/arch/ppc/kernel/cputable.c	2003-07-05 18:09:46.000000000 -0700
@@ -140,16 +140,25 @@
 	32, 32,
 	__setup_cpu_750cx
     },
+    {	/* 750FX rev 1.x */
+    	0xffffff00, 0x70000100, "750FX",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP |
+	CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_750
+    },
     {	/* 750FX rev 2.0 must disable HID0[DPM] */
     	0xffffffff, 0x70000200, "750FX",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
 	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP |
-	CPU_FTR_NO_DPM,
+	CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NO_DPM,
 	COMMON_PPC,
 	32, 32,
 	__setup_cpu_750
     },
-    {	/* 750FX (All revs except 2.0) */
+    {	/* 750FX (All revs > 2.0) */
     	0xffff0000, 0x70000000, "750FX",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
 	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP |
diff -urN linux-2.4.22-pre2/arch/ppc/platforms/pmac_feature.c linux-2.4.22-pre3/arch/ppc/platforms/pmac_feature.c
--- linux-2.4.22-pre2/arch/ppc/platforms/pmac_feature.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ppc/platforms/pmac_feature.c	2003-07-05 18:09:46.000000000 -0700
@@ -1157,9 +1157,6 @@
 	    macio->type != macio_intrepid)
 		return -ENODEV;
 
-	/* XXX Fix handling of 3rd USB controller in Intrepid, move the
-	 * port connect stuff (KL4_*) to the sleep code eventually
-	 */
 	prop = (char *)get_property(node, "AAPL,clock-id", NULL);
 	if (!prop)
 		return -ENODEV;
@@ -1167,6 +1164,8 @@
 		number = 0;
 	else if (strncmp(prop, "usb1u148", 8) == 0)
 		number = 2;
+	else if (strncmp(prop, "usb2u248", 8) == 0)
+		number = 4;
 	else
 		return -ENODEV;
 
@@ -1183,44 +1182,79 @@
 			mdelay(1);
 			LOCK(flags);
 			MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
-		} else {
+		} else if (number == 2) {
 			MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
 			UNLOCK(flags);
 			(void)MACIO_IN32(KEYLARGO_FCR0);
 			mdelay(1);
 			LOCK(flags);
 			MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
+		} else if (number == 4) {
+			MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
+			UNLOCK(flags);
+			(void)MACIO_IN32(KEYLARGO_FCR1);
+			mdelay(1);
+			LOCK(flags);
+			MACIO_BIS(KEYLARGO_FCR0, KL1_USB2_CELL_ENABLE);
+		}
+		if (number < 4) {
+			reg = MACIO_IN32(KEYLARGO_FCR4);
+			reg &=	~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
+				KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
+			reg &=	~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
+				KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
+			MACIO_OUT32(KEYLARGO_FCR4, reg);
+			(void)MACIO_IN32(KEYLARGO_FCR4);
+			udelay(10);
+		} else {
+			reg = MACIO_IN32(KEYLARGO_FCR3);
+			reg &=	~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
+				KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0));
+			reg &=	~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
+				KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1));
+			MACIO_OUT32(KEYLARGO_FCR3, reg);
+			(void)MACIO_IN32(KEYLARGO_FCR3);
+			udelay(10);
 		}
-		reg = MACIO_IN32(KEYLARGO_FCR4);
-		reg &=	~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
-			KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
-		reg &=	~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
-			KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
-		MACIO_OUT32(KEYLARGO_FCR4, reg);
-		(void)MACIO_IN32(KEYLARGO_FCR4);
-		udelay(10);
 	} else {
 		/* Turn OFF */
-		reg = MACIO_IN32(KEYLARGO_FCR4);
-		reg |=	KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
-			KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
-		reg |=	KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
-			KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
-		MACIO_OUT32(KEYLARGO_FCR4, reg);
-		(void)MACIO_IN32(KEYLARGO_FCR4);
-		udelay(1);
+		if (number < 4) {
+			reg = MACIO_IN32(KEYLARGO_FCR4);
+			reg |=	KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
+				KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
+			reg |=	KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
+				KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
+			MACIO_OUT32(KEYLARGO_FCR4, reg);
+			(void)MACIO_IN32(KEYLARGO_FCR4);
+			udelay(1);
+		} else {
+			reg = MACIO_IN32(KEYLARGO_FCR3);
+			reg |=	KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
+				KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0);
+			reg |=	KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
+				KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1);
+			MACIO_OUT32(KEYLARGO_FCR3, reg);
+			(void)MACIO_IN32(KEYLARGO_FCR3);
+			udelay(1);
+		}
 		if (number == 0) {
 			MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
 			(void)MACIO_IN32(KEYLARGO_FCR0);
 			udelay(1);
 			MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
 			(void)MACIO_IN32(KEYLARGO_FCR0);
-		} else {
+		} else if (number == 2) {
 			MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
 			(void)MACIO_IN32(KEYLARGO_FCR0);
 			udelay(1);
 			MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
 			(void)MACIO_IN32(KEYLARGO_FCR0);
+		} else if (number == 4) {
+			MACIO_BIC(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE);
+			(void)MACIO_IN32(KEYLARGO_FCR1);
+			udelay(1);
+			MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
+			(void)MACIO_IN32(KEYLARGO_FCR1);
 		}
 		udelay(1);
 	}
@@ -1928,10 +1962,22 @@
 		PMAC_TYPE_RACKMAC,		rackmac_features,
 		0,
 	},
+	{	"RackMac1,2",			"XServe rev. 2",
+		PMAC_TYPE_RACKMAC,		rackmac_features,
+		0,
+	},
 	{	"PowerMac3,6",			"PowerMac G4 Windtunnel",
 		PMAC_TYPE_WINDTUNNEL,		rackmac_features,
 		0,
 	},
+	{	"PowerBook5,1",			"PowerBook G4 17\"",
+		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
+		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+	},
+	{	"PowerBook6,1",			"PowerBook G4 12\"",
+		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
+		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+	},
 };
 
 /*
@@ -2028,8 +2074,8 @@
 	    	pmac_mb.features = pangea_features;
 		break;
 	    case macio_intrepid:
-		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
-		pmac_mb.model_name = "Unknown Pangea-based";
+		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID;
+		pmac_mb.model_name = "Unknown Intrepid-based";
 	    	pmac_mb.features = intrepid_features;
 	    	break;
 	    default:
diff -urN linux-2.4.22-pre2/arch/ppc/platforms/pmac_pci.c linux-2.4.22-pre3/arch/ppc/platforms/pmac_pci.c
--- linux-2.4.22-pre2/arch/ppc/platforms/pmac_pci.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-pre3/arch/ppc/platforms/pmac_pci.c	2003-07-05 18:09:46.000000000 -0700
@@ -314,6 +314,51 @@
 	early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
 }
 
+/*
+ * Some Apple desktop machines have a NEC PD720100A USB2 controller
+ * on the motherboard. Open Firmware, on these, will disable the
+ * EHCI part of it so it behaves like a pair of OHCI's. This fixup
+ * code re-enables it ;)
+ */
+static void __init
+fixup_nec_usb2(void)
+{
+	struct device_node *nec;
+
+	for (nec = find_devices("usb"); nec != NULL; nec = nec->next) {
+		struct pci_controller *hose;
+		u32 data, *prop;
+		u8 bus, devfn;
+		
+		prop = (u32 *)get_property(nec, "vendor-id", NULL);
+		if (prop == NULL)
+			continue;
+		if (0x1033 != *prop)
+			continue;
+		prop = (u32 *)get_property(nec, "device-id", NULL);
+		if (prop == NULL)
+			continue;
+		if (0x0035 != *prop)
+			continue;
+		prop = (u32 *)get_property(nec, "reg", 0);
+		if (prop == NULL)
+			continue;
+		devfn = (prop[0] >> 8) & 0xff;
+		bus = (prop[0] >> 16) & 0xff;
+		if (PCI_FUNC(devfn) != 0)
+			continue;
+		hose = pci_find_hose_for_OF_device(nec);
+		if (!hose)
+			continue;
+		printk("Found NEC PD720100A USB2 chip, enabling EHCI...\n");
+		early_read_config_dword(hose, bus, devfn, 0xe4, &data);
+		data &= ~1UL;
+		early_write_config_dword(hose, bus, devfn, 0xe4, data);
+		early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE,
+			nec->intrs[0].line);
+	}
+}
+
 void __init
 pmac_find_bridges(void)
 {
@@ -321,6 +366,7 @@
 	add_bridges(find_devices("chaos"));
 	add_bridges(find_devices("pci"));
 	init_p2pbridge();
+	fixup_nec_usb2();
 }
 
 #define GRACKLE_CFA(b, d, o)	(0x80 | ((b) << 8) | ((d) << 16) \
diff -urN linux-2.4.22-pre2/arch/ppc64/config.in linux-2.4.22-pre3/arch/ppc64/config.in
--- linux-2.4.22-pre2/arch/ppc64/config.in	2003-07-05 18:09:16.000000000 -0700
+++ linux-2.4.22-pre3/arch/ppc64/config.in	2003-07-05 18:09:47.000000000 -0700
@@ -236,6 +236,8 @@
 
 source lib/Config.in
 
+source crypto/Config.in
+
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
diff -urN linux-2.4.22-pre2/arch/s390/config.in linux-2.4.22-pre3/arch/s390/config.in
--- linux-2.4.22-pre2/arch/s390/config.in	2002-11-28 15:53:11.000000000 -0800
+++ linux-2.4.22-pre3/arch/s390/config.in	2003-07-05 18:09:47.000000000 -0700
@@ -75,4 +75,5 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -urN linux-2.4.22-pre2/arch/s390/defconfig linux-2.4.22-pre3/arch/s390/defconfig
--- linux-2.4.22-pre2/arch/s390/defconfig	2002-11-28 15:53:11.000000000 -0800
+++ linux-2.4.22-pre3/arch/s390/defconfig	2003-07-05 18:09:47.000000000 -0700
@@ -35,8 +35,8 @@
 CONFIG_MACHCHK_WARNING=y
 CONFIG_CHSC=y
 CONFIG_IPL=y
-# CONFIG_IPL_TAPE is not set
-CONFIG_IPL_VM=y
+CONFIG_IPL_TAPE=y
+# CONFIG_IPL_VM is not set
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
@@ -64,7 +64,7 @@
 CONFIG_DASD=y
 CONFIG_DASD_ECKD=y
 CONFIG_DASD_FBA=y
-# CONFIG_DASD_DIAG is not set
+CONFIG_DASD_DIAG=y
 
 #
 # Multi-device support (RAID and LVM)
@@ -118,7 +118,7 @@
 # CONFIG_TUN is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_TR=y
-# CONFIG_FDDI is not set
+CONFIG_FDDI=y
 
 #
 # S/390 network device drivers
@@ -134,20 +134,98 @@
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 # CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 # CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
 # CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+# CONFIG_IP_NF_AMANDA is not set
+# CONFIG_IP_NF_TFTP is not set
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_MAC=m
+# CONFIG_IP_NF_MATCH_PKTTYPE is not set
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_DSCP is not set
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+# CONFIG_IP_NF_MATCH_HELPER is not set
+CONFIG_IP_NF_MATCH_STATE=m
+# CONFIG_IP_NF_MATCH_CONNTRACK is not set
+# CONFIG_IP_NF_MATCH_UNCLEAN is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+# CONFIG_IP_NF_TARGET_MIRROR is not set
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_NAT_LOCAL=y
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_DSCP is not set
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_IPV6=m
+
+#
+#   IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+# CONFIG_IP6_NF_MATCH_RT is not set
+# CONFIG_IP6_NF_MATCH_OPTS is not set
+# CONFIG_IP6_NF_MATCH_FRAG is not set
+# CONFIG_IP6_NF_MATCH_HL is not set
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
+# CONFIG_IP6_NF_MATCH_AHESP is not set
+# CONFIG_IP6_NF_MATCH_LENGTH is not set
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
 CONFIG_SHARED_IPV6_CARDS=y
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
@@ -158,6 +236,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
@@ -166,7 +249,7 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
+CONFIG_NET_FASTROUTE=y
 # CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
@@ -175,6 +258,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -187,33 +275,38 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
 # CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=m
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
@@ -230,12 +323,14 @@
 # CONFIG_CODA_FS is not set
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
-# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
@@ -247,27 +342,80 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
 #
 CONFIG_PARTITION_ADVANCED=y
 # CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
 CONFIG_IBM_PARTITION=y
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_MSDOS_PARTITION 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_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_LDM_DEBUG=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_EFI_PARTITION=y
 # CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Kernel hacking
 #
 CONFIG_MAGIC_SYSRQ=y
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.22-pre2/arch/s390/kernel/debug.c linux-2.4.22-pre3/arch/s390/kernel/debug.c
--- linux-2.4.22-pre2/arch/s390/kernel/debug.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390/kernel/debug.c	2003-07-05 18:09:47.000000000 -0700
@@ -949,9 +949,21 @@
 	int i;
 	unsigned long flags;
 	mode_t mode = S_IFREG;
+	struct proc_dir_entry *pde;
+
 
 	if (!id)
 		goto out;
+	pde = debug_create_proc_dir_entry(id->proc_root_entry,
+					  view->name, mode,
+					  &debug_inode_ops,
+					  &debug_file_ops);
+	if(!pde){
+		printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name);
+		rc = -1;
+		goto out;
+	}
+
 	spin_lock_irqsave(&id->lock, flags);
 	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
 		if (id->views[i] == NULL)
@@ -962,6 +974,8 @@
 			id->name,view->name);
 		printk(KERN_WARNING 
 			"debug: maximum number of views reached (%i)!\n", i);
+		debug_delete_proc_dir_entry(id->proc_root_entry, pde);
+		
 		rc = -1;
 	}
 	else {
@@ -970,11 +984,7 @@
 			mode |= S_IRUSR;
 		if (view->input_proc)
 			mode |= S_IWUSR;
-		id->proc_entries[i] =
-		    debug_create_proc_dir_entry(id->proc_root_entry,
-						view->name, mode,
-						&debug_inode_ops,
-						&debug_file_ops);
+		id->proc_entries[i] = pde;
 		rc = 0;
 	}
 	spin_unlock_irqrestore(&id->lock, flags);
diff -urN linux-2.4.22-pre2/arch/s390/kernel/head.S linux-2.4.22-pre3/arch/s390/kernel/head.S
--- linux-2.4.22-pre2/arch/s390/kernel/head.S	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390/kernel/head.S	2003-07-05 18:09:47.000000000 -0700
@@ -587,7 +587,7 @@
         .long  .Lduct                   # cr2: dispatchable unit control table
         .long  0                        # cr3: instruction authorization
         .long  0                        # cr4: instruction authorization
-        .long  0                        # cr5:  various things
+        .long  0xffffffff               # cr5: primary-aste origin
         .long  0                        # cr6:  I/O interrupts
         .long  0                        # cr7:  secondary space segment table
         .long  0                        # cr8:  access registers translation
diff -urN linux-2.4.22-pre2/arch/s390/kernel/s390_ksyms.c linux-2.4.22-pre3/arch/s390/kernel/s390_ksyms.c
--- linux-2.4.22-pre2/arch/s390/kernel/s390_ksyms.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390/kernel/s390_ksyms.c	2003-07-05 18:09:47.000000000 -0700
@@ -60,5 +60,8 @@
 EXPORT_SYMBOL(csum_fold);
 EXPORT_SYMBOL(console_mode);
 EXPORT_SYMBOL(console_device);
-EXPORT_SYMBOL(pfix_table);
+EXPORT_SYMBOL(pfix_get_addr);
+EXPORT_SYMBOL(pfix_get_page_addr);
+EXPORT_SYMBOL(get_storage_key);
 EXPORT_SYMBOL_NOVERS(do_call_softirq);
+EXPORT_SYMBOL(sys_wait4);
diff -urN linux-2.4.22-pre2/arch/s390/kernel/setup.c linux-2.4.22-pre3/arch/s390/kernel/setup.c
--- linux-2.4.22-pre2/arch/s390/kernel/setup.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390/kernel/setup.c	2003-07-05 18:09:47.000000000 -0700
@@ -56,7 +56,117 @@
 unsigned long cpu_initialized = 0;
 volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
 
-void* *pfix_table=NULL;
+unsigned long *pfix_table;
+unsigned int __global_storage_key;
+
+unsigned int get_storage_key(void) { return __global_storage_key; }
+
+unsigned long pfix_get_page_addr(void *addr)
+{
+	if (!MACHINE_HAS_PFIX)
+		return (unsigned long) addr;
+
+	return pfix_table[(unsigned long)virt_to_phys(addr)>>PAGE_SHIFT];
+}
+
+unsigned long pfix_get_addr(void *addr)
+{
+	if (!MACHINE_HAS_PFIX)
+		return (unsigned long) addr;
+
+	return pfix_get_page_addr(addr) + ((unsigned long)addr&(PAGE_SIZE-1));
+}
+
+/*
+ * These functions allow to lock and unlock pages in VM. They need
+ * the absolute address of the page to be locked or unlocked. This will
+ * only work if the diag98 option in the user directory is enabled for
+ * the guest.
+ */
+
+/* if result is 0, addr will become the host absolute address */
+static inline int pfix_lock_page(void *addr)
+{
+        int ret;
+
+        __asm__ __volatile__(
+		"   sske  %1,%2\n"    /* set storage key */
+                "   l     0,0(%1)\n"  /* addr into gpr 0 */
+                "   lhi   2,0\n"      /* function code is 0 */
+                "   diag  2,0,0x98\n" /* result in gpr 1 */
+                "   jnz   0f\n"
+		"   lhi   %0,0\n"     /* if cc=0: return 0 */
+	    	"   st    1,0(%1)\n"  /* gpr1 contains host absol. addr */
+		"   j     1f\n"
+		"0: lr    %0,1\n"     /* gpr1 contains error code */
+		"   sske  %1,2\n"     /* reset storage key */
+		"1:\n"
+                : "=d" (ret), "+d" ((unsigned long)addr) : "d" (__global_storage_key) 
+                : "0", "1", "2", "cc" );
+        return ret;
+}
+
+static inline void pfix_unlock_page(unsigned long addr)
+{
+        __asm__ __volatile__(
+                "   lr    0,%0\n"  /* parameter in gpr 0 */
+                "   lhi   2,4\n"   /* function code is 4 */
+                "   diag  2,0,0x98\n" /* result in gpr 1 */
+		"   sske  %0,%1\n"
+                : : "a" (addr), "d" (0)
+                : "0", "1", "2", "cc" );
+}
+
+static void unpfix_all_pages(void)
+{
+        unsigned long i;
+
+	if (!pfix_table)
+		return;
+
+	for (i=0; i<sizeof(pfix_table); i++) {
+		if (pfix_table[i]) {
+			pfix_unlock_page(i << PAGE_SHIFT);
+		}
+	}
+}
+
+static void pfix_all_pages(unsigned long start_pfn, unsigned long max_pfn)
+{
+        unsigned long i,r;
+	unsigned long size;
+
+	size = ((max_pfn - start_pfn) >> PAGE_SHIFT) * sizeof(long);
+	pfix_table = alloc_bootmem(size);
+	if (!pfix_table)
+		return;
+
+	__global_storage_key = 6 << 4;
+	for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) {
+		unsigned long start;
+
+		for(start = memory_chunk[i].addr; 
+		    (start < memory_chunk[i].addr + memory_chunk[i].size &&
+		     start < max_pfn); start += PAGE_SIZE) {
+			unsigned long index;
+
+			index = start >> PAGE_SHIFT;
+			pfix_table[index] = start;
+			r = pfix_lock_page(&pfix_table[index]);
+			if (r) {
+				pfix_table[index] = 0;
+				unpfix_all_pages();
+				free_bootmem((unsigned long)pfix_table, size);
+				machine_flags &= ~128; /* MACHINE_HAS_PFIX=0 */
+				__global_storage_key = 0;
+				printk(KERN_WARNING "Error enabling PFIX at "
+				       "address 0x%08lx.\n", start);
+				return;
+			}
+		}
+        }
+	printk (KERN_INFO "PFIX enabled.\n");
+}
 
 /*
  * Setup options
@@ -303,11 +413,12 @@
         unsigned long memory_start, memory_end;
         char c = ' ', cn, *to = command_line, *from = COMMAND_LINE;
 	struct resource *res;
-	unsigned long start_pfn, end_pfn;
+	unsigned long start_pfn, end_pfn, max_pfn=0;
         static unsigned int smptrap=0;
         unsigned long delay = 0;
 	struct _lowcore *lowcore;
 	int i;
+	static int use_pfix;
 
         if (smptrap)
                 return;
@@ -380,6 +491,14 @@
 			/* now wait for the requested amount of time */
 			udelay(delay);
                 }
+		/*
+		 * "use_pfix" specifies whether we want to fix all pages,
+		 * if possible.
+		 */
+		if (c == ' ' && strncmp(from, "use_pfix", 8) == 0) {
+			use_pfix = 1;
+			from += 8;
+		}
                 cn = *(from++);
                 if (!cn)
                         break;
@@ -394,6 +513,10 @@
                         break;
                 *(to++) = c;
         }
+
+	if (!use_pfix)
+		machine_flags &= ~128; /* MACHINE_HAS_PFIX = 0 */
+
         if (c == ' ' && to > command_line) to--;
         *to = '\0';
         *cmdline_p = command_line;
@@ -429,6 +552,8 @@
 		if (start_chunk < end_chunk)
 			free_bootmem(start_chunk << PAGE_SHIFT,
 				     (end_chunk - start_chunk) << PAGE_SHIFT);
+		if (start_chunk + memory_chunk[i].size > max_pfn)
+			max_pfn = start_chunk + memory_chunk[i].size;
 	}
 
         /*
@@ -487,6 +612,10 @@
 	 */
         paging_init();
 
+	if (MACHINE_HAS_PFIX)
+		/* max_pfn may be smaller than memory_end. */
+		pfix_all_pages(start_pfn, max_pfn);
+
 	res = alloc_bootmem_low(sizeof(struct resource));
 	res->start = 0;
 	res->end = memory_end;
diff -urN linux-2.4.22-pre2/arch/s390/mm/init.c linux-2.4.22-pre3/arch/s390/mm/init.c
--- linux-2.4.22-pre2/arch/s390/mm/init.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390/mm/init.c	2003-07-05 18:09:48.000000000 -0700
@@ -154,11 +154,6 @@
                         if (address >= end_mem)
                                 pte_clear(&pte);
                         set_pte(pg_table, pte);
-			if (address < memory_size) /* do not set storage
-						      key outside the storage
-						      or die */
-				set_access_key(pte); /* switch to our
-							access key */
                         address += PAGE_SIZE;
                 }
         }
diff -urN linux-2.4.22-pre2/arch/s390x/config.in linux-2.4.22-pre3/arch/s390x/config.in
--- linux-2.4.22-pre2/arch/s390x/config.in	2002-11-28 15:53:11.000000000 -0800
+++ linux-2.4.22-pre3/arch/s390x/config.in	2003-07-05 18:09:48.000000000 -0700
@@ -79,4 +79,5 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -urN linux-2.4.22-pre2/arch/s390x/defconfig linux-2.4.22-pre3/arch/s390x/defconfig
--- linux-2.4.22-pre2/arch/s390x/defconfig	2002-11-28 15:53:11.000000000 -0800
+++ linux-2.4.22-pre3/arch/s390x/defconfig	2003-07-05 18:09:48.000000000 -0700
@@ -36,8 +36,8 @@
 CONFIG_MACHCHK_WARNING=y
 CONFIG_CHSC=y
 CONFIG_IPL=y
-# CONFIG_IPL_TAPE is not set
-CONFIG_IPL_VM=y
+CONFIG_IPL_TAPE=y
+# CONFIG_IPL_VM is not set
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
@@ -118,7 +118,7 @@
 # CONFIG_TUN is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_TR=y
-# CONFIG_FDDI is not set
+CONFIG_FDDI=y
 
 #
 # S/390 network device drivers
@@ -134,20 +134,40 @@
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 # CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 # CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
 # CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_IPV6=m
+
+#
+#   IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
 CONFIG_SHARED_IPV6_CARDS=y
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
@@ -158,6 +178,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
@@ -166,7 +191,7 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
+CONFIG_NET_FASTROUTE=y
 # CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
@@ -175,6 +200,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -187,33 +217,38 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
 # CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=m
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
@@ -230,13 +265,17 @@
 # CONFIG_CODA_FS is not set
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
 # CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
-# CONFIG_SMB_FS is not set
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
 # CONFIG_NCPFS_IOCTL_LOCKING is not set
@@ -247,27 +286,80 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
 #
 CONFIG_PARTITION_ADVANCED=y
 # CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
 CONFIG_IBM_PARTITION=y
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_MSDOS_PARTITION is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_LDM_DEBUG=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Kernel hacking
 #
 CONFIG_MAGIC_SYSRQ=y
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/Makefile linux-2.4.22-pre3/arch/s390x/kernel/Makefile
--- linux-2.4.22-pre2/arch/s390x/kernel/Makefile	2002-11-28 15:53:11.000000000 -0800
+++ linux-2.4.22-pre3/arch/s390x/kernel/Makefile	2003-07-05 18:09:48.000000000 -0700
@@ -29,7 +29,7 @@
 #
 obj-$(CONFIG_REMOTE_DEBUG)	+= gdb-stub.o #gdb-low.o 
 
-obj-$(CONFIG_S390_SUPPORT)	+= linux32.o signal32.o ioctl32.o wrapper32.o exec32.o
+obj-$(CONFIG_S390_SUPPORT)	+= linux32.o signal32.o ioctl32.o wrapper32.o exec32.o exec_domain32.o
 obj-$(CONFIG_BINFMT_ELF32)	+= binfmt_elf32.o
 
 .PHONY: asm-offsets.h
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/binfmt_elf32.c linux-2.4.22-pre3/arch/s390x/kernel/binfmt_elf32.c
--- linux-2.4.22-pre2/arch/s390x/kernel/binfmt_elf32.c	2001-04-11 19:02:29.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390x/kernel/binfmt_elf32.c	2003-07-05 18:09:48.000000000 -0700
@@ -87,7 +87,13 @@
 #define ELF_PLATFORM (NULL)
 
 #ifdef __KERNEL__
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex, ibcs2)			\
+do {							\
+	if (ibcs2)                                      \
+		set_personality(PER_SVR4);              \
+	else if (current->personality != PER_LINUX32)   \
+		set_personality(PER_LINUX);             \
+} while (0)
 #endif 
 
 #include "linux32.h"
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/debug.c linux-2.4.22-pre3/arch/s390x/kernel/debug.c
--- linux-2.4.22-pre2/arch/s390x/kernel/debug.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390x/kernel/debug.c	2003-07-05 18:09:48.000000000 -0700
@@ -949,9 +949,21 @@
 	int i;
 	unsigned long flags;
 	mode_t mode = S_IFREG;
+	struct proc_dir_entry *pde;
+
 
 	if (!id)
 		goto out;
+	pde = debug_create_proc_dir_entry(id->proc_root_entry,
+					  view->name, mode,
+					  &debug_inode_ops,
+					  &debug_file_ops);
+	if(!pde){
+		printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name);
+		rc = -1;
+		goto out;
+	}
+
 	spin_lock_irqsave(&id->lock, flags);
 	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
 		if (id->views[i] == NULL)
@@ -962,6 +974,8 @@
 			id->name,view->name);
 		printk(KERN_WARNING 
 			"debug: maximum number of views reached (%i)!\n", i);
+		debug_delete_proc_dir_entry(id->proc_root_entry, pde);
+		
 		rc = -1;
 	}
 	else {
@@ -970,11 +984,7 @@
 			mode |= S_IRUSR;
 		if (view->input_proc)
 			mode |= S_IWUSR;
-		id->proc_entries[i] =
-		    debug_create_proc_dir_entry(id->proc_root_entry,
-						view->name, mode,
-						&debug_inode_ops,
-						&debug_file_ops);
+		id->proc_entries[i] = pde;
 		rc = 0;
 	}
 	spin_unlock_irqrestore(&id->lock, flags);
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/entry.S linux-2.4.22-pre3/arch/s390x/kernel/entry.S
--- linux-2.4.22-pre2/arch/s390x/kernel/entry.S	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390x/kernel/entry.S	2003-07-05 18:09:48.000000000 -0700
@@ -392,7 +392,7 @@
         .long  SYSCALL(sys_oldumount,sys32_oldumount_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys32_setuid16_wrapper)   /* old setuid16 syscall*/
         .long  SYSCALL(sys_ni_syscall,sys32_getuid16)   /* old getuid16 syscall*/
-        .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 25 old stime syscall */
+        .long  SYSCALL(sys_ni_syscall,sys32_stime_wrapper) /* 25 old stime syscall */
         .long  SYSCALL(sys_ptrace,sys32_ptrace_wrapper)
         .long  SYSCALL(sys_alarm,sys32_alarm_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old fstat syscall */
@@ -489,7 +489,7 @@
         .long  SYSCALL(sys_sigreturn_glue,sys32_sigreturn_glue)
         .long  SYSCALL(sys_clone_glue,sys_clone_glue) /* 120 */
         .long  SYSCALL(sys_setdomainname,sys32_setdomainname_wrapper)
-        .long  SYSCALL(sys_newuname,sys32_newuname_wrapper)
+        .long  SYSCALL(s390x_newuname,sys32_newuname_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* modify_ldt for i386 */
         .long  SYSCALL(sys_adjtimex,sys32_adjtimex_wrapper)
         .long  SYSCALL(sys_mprotect,sys32_mprotect_wrapper) /* 125 */
@@ -503,7 +503,7 @@
         .long  SYSCALL(sys_fchdir,sys32_fchdir_wrapper)
         .long  SYSCALL(sys_bdflush,sys32_bdflush_wrapper)
         .long  SYSCALL(sys_sysfs,sys32_sysfs_wrapper)           /* 135 */
-        .long  SYSCALL(sys_personality,sys32_personality_wrapper)
+        .long  SYSCALL(s390x_personality,sys32_personality_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* for afs_syscall */
         .long  SYSCALL(sys_ni_syscall,sys32_setfsuid16_wrapper) /* old setfsuid16 syscall */
         .long  SYSCALL(sys_ni_syscall,sys32_setfsgid16_wrapper) /* old setfsgid16 syscall */
@@ -516,7 +516,7 @@
         .long  SYSCALL(sys_writev,sys32_writev_wrapper)
         .long  SYSCALL(sys_getsid,sys32_getsid_wrapper)
         .long  SYSCALL(sys_fdatasync,sys32_fdatasync_wrapper)
-        .long  SYSCALL(sys_sysctl,sys_ni_syscall)
+        .long  SYSCALL(sys_sysctl,sys32_sysctl_wrapper)
         .long  SYSCALL(sys_mlock,sys32_mlock_wrapper)           /* 150 */
         .long  SYSCALL(sys_munlock,sys32_munlock_wrapper)
         .long  SYSCALL(sys_mlockall,sys32_mlockall_wrapper)
@@ -558,7 +558,7 @@
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* streams1 */
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* streams2 */
         .long  SYSCALL(sys_vfork_glue,sys_vfork_glue) /* 190 */
-        .long  SYSCALL(sys_getrlimit,sys32_old_getrlimit_wrapper)
+        .long  SYSCALL(sys_getrlimit,sys32_getrlimit_wrapper)
 	.long  SYSCALL(sys_mmap2,sys32_mmap2_wrapper)
 	.long  SYSCALL(sys_ni_syscall,sys32_truncate64_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys32_ftruncate64_wrapper)
@@ -589,7 +589,7 @@
         .long  SYSCALL(sys_madvise,sys32_madvise_wrapper)
 	.long  SYSCALL(sys_getdents64,sys32_getdents64_wrapper)/* 220 */
 	.long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
-	.long  SYSCALL(sys_readahead,sys_ni_syscall)
+	.long  SYSCALL(sys_readahead,sys32_readahead)
 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr  */
 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/exec_domain32.c linux-2.4.22-pre3/arch/s390x/kernel/exec_domain32.c
--- linux-2.4.22-pre2/arch/s390x/kernel/exec_domain32.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/s390x/kernel/exec_domain32.c	2003-07-05 18:09:48.000000000 -0700
@@ -0,0 +1,30 @@
+/*
+ * Support for 32-bit Linux for S390 personality.
+ *
+ * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Gerhard Tonn (ton@de.ibm.com)
+ *
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/personality.h>
+#include <linux/sched.h>
+
+struct exec_domain s390_exec_domain;
+
+static int __init
+s390_init (void)
+{
+	s390_exec_domain.name = "Linux/s390";
+	s390_exec_domain.handler = NULL;
+	s390_exec_domain.pers_low = PER_LINUX32;
+	s390_exec_domain.pers_high = PER_LINUX32;
+	s390_exec_domain.signal_map = default_exec_domain.signal_map;
+	s390_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
+	register_exec_domain(&s390_exec_domain);
+	return 0;
+}
+
+__initcall(s390_init);
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/head.S linux-2.4.22-pre3/arch/s390x/kernel/head.S
--- linux-2.4.22-pre2/arch/s390x/kernel/head.S	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390x/kernel/head.S	2003-07-05 18:09:48.000000000 -0700
@@ -548,26 +548,11 @@
 	tm     __LC_CPUID,0xff          # running under VM ?
 	bno    0f-.LPG1(%r13)
         oi     7(%r12),1                # set VM flag
-#
-# we are running under VM, find out if we have PFIX
-#
-	la     %r1,0f-.LPG1(%r13)       # set program check address
-	stg    %r1,__LC_PGM_NEW_PSW+8
-        lghi   %r0,0x4000
-	lghi   %r2,0
-	.long  0x83200098               # diag 2,0,x'0098' - lock page
-	lghi   %r2,4
-	.long  0x83200098               # diag 2,0,x'0098' - unlock page
-	oi     7(%r12),128              # set PFIX flag
 0:      lh     %r0,__LC_CPUID+4         # get cpu version
         chi    %r0,0x7490               # running on a P/390 ?
         bne    1f-.LPG1(%r13)
         oi     7(%r12),4                # set P/390 flag
 1:
-	chi    %r0,0x2084		# new stidp format?
-	bne    2f-.LPG1(%r13)
-	oi     7(%r12),64		# set new stidp flag
-2:	
 
 #
 # find out if we have the MVPG instruction
@@ -601,7 +586,7 @@
         .quad  .Lduct                   # cr2: dispatchable unit control table
         .quad  0                        # cr3: instruction authorization
         .quad  0                        # cr4: instruction authorization
-        .quad  0                        # cr5:  various things
+        .quad  0xffffffffffffffff       # cr5: primary-aste origin
         .quad  0                        # cr6:  I/O interrupts
         .quad  0                        # cr7:  secondary space segment table
         .quad  0                        # cr8:  access registers translation
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/ioctl32.c linux-2.4.22-pre3/arch/s390x/kernel/ioctl32.c
--- linux-2.4.22-pre2/arch/s390x/kernel/ioctl32.c	2002-02-25 11:37:56.000000000 -0800
+++ linux-2.4.22-pre3/arch/s390x/kernel/ioctl32.c	2003-07-05 18:09:48.000000000 -0700
@@ -25,6 +25,11 @@
 #include <linux/ext2_fs.h>
 #include <linux/hdreg.h>
 #include <linux/if_bonding.h>
+#include <linux/loop.h>
+#include <linux/blkpg.h>
+#include <linux/blk.h>
+#include <linux/elevator.h>
+#include <linux/raw.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
 #include <asm/dasd.h>
@@ -373,6 +378,107 @@
 	return sys_ioctl(fd, cmd, arg);
 }
 
+struct loop_info32 {
+	int			lo_number;      /* ioctl r/o */
+	__kernel_dev_t32	lo_device;      /* ioctl r/o */
+	unsigned int		lo_inode;       /* ioctl r/o */
+	__kernel_dev_t32	lo_rdevice;     /* ioctl r/o */
+	int			lo_offset;
+	int			lo_encrypt_type;
+	int			lo_encrypt_key_size;    /* ioctl w/o */
+	int			lo_flags;       /* ioctl r/o */
+	char			lo_name[LO_NAME_SIZE];
+	unsigned char		lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+	unsigned int		lo_init[2];
+	char			reserved[4];
+};
+
+static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct loop_info l;
+	int err = -EINVAL;
+
+	switch(cmd) {
+	case LOOP_SET_STATUS:
+		err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
+		err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
+		err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
+		err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
+		err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset,
+					   8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
+		if (err) {
+			err = -EFAULT;
+		} else {
+			set_fs (KERNEL_DS);
+			err = sys_ioctl (fd, cmd, (unsigned long)&l);
+			set_fs (old_fs);
+		}
+		break;
+	case LOOP_GET_STATUS:
+		set_fs (KERNEL_DS);
+		err = sys_ioctl (fd, cmd, (unsigned long)&l);
+		set_fs (old_fs);
+		if (!err) {
+			err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
+			err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
+			err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
+			err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
+			err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset,
+					   (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
+			if (err)
+				err = -EFAULT;
+		}
+		break;
+	default: {
+		static int count = 0;
+		if (++count <= 20)
+			printk("%s: Unknown loop ioctl cmd, fd(%d) "
+			       "cmd(%08x) arg(%08lx)\n",
+			       __FUNCTION__, fd, cmd, arg);
+	}
+	}
+	return err;
+}
+
+
+struct blkpg_ioctl_arg32 {
+	int op;
+	int flags;
+	int datalen;
+	u32 data;
+};
+                                
+static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg)
+{
+	struct blkpg_ioctl_arg a;
+	struct blkpg_partition p;
+	int err;
+	mm_segment_t old_fs = get_fs();
+	
+	err = get_user(a.op, &arg->op);
+	err |= __get_user(a.flags, &arg->flags);
+	err |= __get_user(a.datalen, &arg->datalen);
+	err |= __get_user((long)a.data, &arg->data);
+	if (err) return err;
+	switch (a.op) {
+	case BLKPG_ADD_PARTITION:
+	case BLKPG_DEL_PARTITION:
+		if (a.datalen < sizeof(struct blkpg_partition))
+			return -EINVAL;
+                if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
+			return -EFAULT;
+		a.data = &p;
+		set_fs (KERNEL_DS);
+		err = sys_ioctl(fd, cmd, (unsigned long)&a);
+		set_fs (old_fs);
+	default:
+		return -EINVAL;
+	}                                        
+	return err;
+}
+
+
 static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	mm_segment_t old_fs = get_fs();
@@ -413,7 +519,19 @@
 	IOCTL32_DEFAULT(BIODASDINFO),
 	IOCTL32_DEFAULT(BIODASDFMT),
 
+	IOCTL32_DEFAULT(BLKROSET),
+	IOCTL32_DEFAULT(BLKROGET),
 	IOCTL32_DEFAULT(BLKRRPART),
+	IOCTL32_DEFAULT(BLKFLSBUF),
+	IOCTL32_DEFAULT(BLKRASET),
+	IOCTL32_DEFAULT(BLKFRASET),
+	IOCTL32_DEFAULT(BLKSECTSET),
+	IOCTL32_DEFAULT(BLKSSZGET),
+	IOCTL32_DEFAULT(BLKBSZGET),
+	IOCTL32_DEFAULT(BLKGETSIZE64),
+
+	IOCTL32_DEFAULT(BLKELVGET),
+	IOCTL32_DEFAULT(BLKELVSET),
 
 	IOCTL32_HANDLER(HDIO_GETGEO, hd_geometry_ioctl),
 
@@ -422,6 +540,7 @@
 	IOCTL32_DEFAULT(TCSETAW),
 	IOCTL32_DEFAULT(TCSETAF),
 	IOCTL32_DEFAULT(TCSBRK),
+	IOCTL32_DEFAULT(TCSBRKP),
 	IOCTL32_DEFAULT(TCXONC),
 	IOCTL32_DEFAULT(TCFLSH),
 	IOCTL32_DEFAULT(TCGETS),
@@ -508,6 +627,10 @@
 
 	IOCTL32_DEFAULT(SIOCGSTAMP),
 
+	IOCTL32_DEFAULT(LOOP_SET_FD),
+	IOCTL32_DEFAULT(LOOP_CLR_FD),
+
+	IOCTL32_DEFAULT(SIOCATMARK),
 	IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
 	IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
 	IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc),
@@ -552,7 +675,18 @@
 	IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl),
 	IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl),
 
-	IOCTL32_HANDLER(BLKGETSIZE, w_long)
+	IOCTL32_HANDLER(LOOP_SET_STATUS, loop_status),
+	IOCTL32_HANDLER(LOOP_GET_STATUS, loop_status),
+
+/* Raw devices */
+	IOCTL32_DEFAULT(RAW_SETBIND),
+	IOCTL32_DEFAULT(RAW_GETBIND),
+
+	IOCTL32_HANDLER(BLKRAGET, w_long),
+	IOCTL32_HANDLER(BLKGETSIZE, w_long),
+	IOCTL32_HANDLER(BLKFRAGET, w_long),
+	IOCTL32_HANDLER(BLKSECTGET, w_long),
+	IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans)
 
 };
 
@@ -604,6 +738,8 @@
 static void ioctl32_insert(struct ioctl32_list *entry)
 {
 	int hash = ioctl32_hash(entry->handler.cmd);
+
+	entry->next = 0;
 	if (!ioctl32_hash_table[hash])
 		ioctl32_hash_table[hash] = entry;
 	else {
@@ -612,10 +748,51 @@
 		while (l->next)
 			l = l->next;
 		l->next = entry;
-		entry->next = 0;
 	}
 }
 
+int register_ioctl32_conversion(unsigned int cmd,
+				int (*handler)(unsigned int, unsigned int,
+					       unsigned long, struct file *))
+{
+	struct ioctl32_list *l, *new;
+	int hash;
+
+	hash = ioctl32_hash(cmd);
+	for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next)
+		if (l->handler.cmd == cmd)
+			return -EBUSY;
+	new = kmalloc(sizeof(struct ioctl32_list), GFP_KERNEL);
+	if (new == NULL)
+		return -ENOMEM;
+	new->handler.cmd = cmd;
+	new->handler.function = (void *) handler;
+	ioctl32_insert(new);
+	return 0;
+}
+
+int unregister_ioctl32_conversion(unsigned int cmd)
+{
+	struct ioctl32_list *p, *l;
+	int hash;
+
+	hash = ioctl32_hash(cmd);
+	p = NULL;
+	for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next) {
+		if (l->handler.cmd == cmd)
+			break;
+		p = l;
+	}
+	if (l == NULL)
+		return -ENOENT;
+	if (p == NULL)
+		ioctl32_hash_table[hash] = l->next;
+	else
+		p->next = l->next;
+	kfree(l);
+	return 0;
+}
+
 static int __init init_ioctl32(void)
 {
 	int i;
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/linux32.c linux-2.4.22-pre3/arch/s390x/kernel/linux32.c
--- linux-2.4.22-pre2/arch/s390x/kernel/linux32.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390x/kernel/linux32.c	2003-07-05 18:09:48.000000000 -0700
@@ -63,6 +63,7 @@
 #include <asm/semaphore.h>
 
 #include <net/scm.h>
+#include <net/sock.h>
 
 #include "linux32.h"
 
@@ -384,18 +385,18 @@
 
 struct shmid64_ds32 {
 	struct ipc64_perm_ds32	shm_perm;
-	unsigned int		__pad1;
+	__kernel_size_t32	shm_segsz;
 	__kernel_time_t32	shm_atime;
-	unsigned int		__pad2;
+	unsigned int		__unused1;
 	__kernel_time_t32	shm_dtime;
-	unsigned int		__pad3;
+	unsigned int		__unused2;
 	__kernel_time_t32	shm_ctime;
-	__kernel_size_t32	shm_segsz;
+	unsigned int		__unused3;
 	__kernel_pid_t32	shm_cpid;
 	__kernel_pid_t32	shm_lpid;
 	unsigned int		shm_nattch;
-	unsigned int		__unused1;
-	unsigned int		__unused2;
+	unsigned int		__unused4;
+	unsigned int		__unused5;
 };
 
                                                         
@@ -504,16 +505,23 @@
 
 static int do_sys32_msgsnd (int first, int second, int third, void *uptr)
 {
-	struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
+	struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf), GFP_USER);
 	struct msgbuf32 *up = (struct msgbuf32 *)uptr;
 	mm_segment_t old_fs;
 	int err;
 
 	if (!p)
 		return -ENOMEM;
-	err = get_user (p->mtype, &up->mtype);
-	err |= __copy_from_user (p->mtext, &up->mtext, second);
-	if (err)
+
+	err = -EINVAL;
+	if (second > MSGMAX || first < 0 || second < 0)
+		goto out;
+
+	err = -EFAULT;
+	if (!uptr)
+		goto out;
+	if (get_user (p->mtype, &up->mtype) ||
+	    __copy_from_user (p->mtext, &up->mtext, second))
 		goto out;
 	old_fs = get_fs ();
 	set_fs (KERNEL_DS);
@@ -532,6 +540,9 @@
 	mm_segment_t old_fs;
 	int err;
 
+	if (first < 0 || second < 0)
+		return -EINVAL;
+
 	if (!version) {
 		struct ipc_kludge_32 *uipck = (struct ipc_kludge_32 *)uptr;
 		struct ipc_kludge_32 ipck;
@@ -546,12 +557,12 @@
 		msgtyp = ipck.msgtyp;
 	}
 	err = -ENOMEM;
-	p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
+	p = kmalloc (second + sizeof (struct msgbuf), GFP_USER);
 	if (!p)
 		goto out;
 	old_fs = get_fs ();
 	set_fs (KERNEL_DS);
-	err = sys_msgrcv (first, p, second + 4, msgtyp, third);
+	err = sys_msgrcv (first, p, second, msgtyp, third);
 	set_fs (old_fs);
 	if (err < 0)
 		goto free_then_out;
@@ -879,27 +890,39 @@
 {
 	switch (cmd) {
 	case F_GETLK:
-	case F_SETLK:
-	case F_SETLKW:
 		{
 			struct flock f;
 			mm_segment_t old_fs;
 			long ret;
 			
-			if(get_flock(&f, (struct flock32 *)arg))
+			if(get_flock(&f, (struct flock32 *)A(arg)))
 				return -EFAULT;
 			old_fs = get_fs(); set_fs (KERNEL_DS);
 			ret = sys_fcntl(fd, cmd, (unsigned long)&f);
 			set_fs (old_fs);
 			if (ret) return ret;
 			if (f.l_start >= 0x7fffffffUL ||
-			    f.l_len >= 0x7fffffffUL ||
 			    f.l_start + f.l_len >= 0x7fffffffUL)
 				return -EOVERFLOW;
-			if(put_flock(&f, (struct flock32 *)arg))
+			if(put_flock(&f, (struct flock32 *)A(arg)))
 				return -EFAULT;
 			return 0;
 		}
+	case F_SETLK:
+	case F_SETLKW:
+		{
+			struct flock f;
+			mm_segment_t old_fs;
+			long ret;
+			
+			if(get_flock(&f, (struct flock32 *)A(arg)))
+				return -EFAULT;
+			old_fs = get_fs(); set_fs (KERNEL_DS);
+			ret = sys_fcntl(fd, cmd, (unsigned long)&f);
+			set_fs (old_fs);
+			if (ret) return ret;
+			return 0;
+		}
 	default:
 		return sys_fcntl(fd, cmd, (unsigned long)arg);
 	}
@@ -2151,15 +2174,17 @@
 	return ret;
 }
 
-#define RLIM_INFINITY32	0x7fffffff
-#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
+#define RLIM_OLD_INFINITY32	0x7fffffff
+#define RLIM_INFINITY32		0xffffffff
+#define RESOURCE32_OLD(x)	((x > RLIM_OLD_INFINITY32) ? RLIM_OLD_INFINITY32 : x)
+#define RESOURCE32(x) 		((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
 
 struct rlimit32 {
 	u32	rlim_cur;
 	u32	rlim_max;
 };
 
-extern asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim);
+extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
 
 asmlinkage int sys32_old_getrlimit(unsigned int resource, struct rlimit32 *rlim)
 {
@@ -2168,7 +2193,23 @@
 	mm_segment_t old_fs = get_fs ();
 	
 	set_fs (KERNEL_DS);
-	ret = sys_old_getrlimit(resource, &r);
+	ret = sys_getrlimit(resource, &r);
+	set_fs (old_fs);
+	if (!ret) {
+		ret = put_user (RESOURCE32_OLD(r.rlim_cur), &rlim->rlim_cur);
+		ret |= __put_user (RESOURCE32_OLD(r.rlim_max), &rlim->rlim_max);
+	}
+	return ret;
+}
+
+asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
+{
+	struct rlimit r;
+	int ret;
+	mm_segment_t old_fs = get_fs ();
+	
+	set_fs (KERNEL_DS);
+	ret = sys_getrlimit(resource, &r);
 	set_fs (old_fs);
 	if (!ret) {
 		ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
@@ -2588,8 +2629,23 @@
 			  CMSG32_ALIGN(sizeof(struct cmsghdr32)));
 		kcmsg32->cmsg_len = clen32;
 
+		switch (kcmsg32->cmsg_type) {
+			/*
+			 * The timestamp type's data needs to be converted
+			 * from 64-bit time values to 32-bit time values
+			*/
+		case SO_TIMESTAMP: {
+			__kernel_time_t32* ptr_time32 = CMSG32_DATA(kcmsg32);
+			__kernel_time_t*   ptr_time   = CMSG_DATA(ucmsg);
+			get_user(*ptr_time32, ptr_time);
+			get_user(*(ptr_time32+1), ptr_time+1);
+			kcmsg32->cmsg_len -= 2*(sizeof(__kernel_time_t) -
+						sizeof(__kernel_time_t32));
+		}
+		default:;
+		}
 		ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
-		wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
+		wp = (((char *)kcmsg32) + CMSG32_ALIGN(kcmsg32->cmsg_len));
 	}
 
 	/* Copy back fixed up data, and adjust pointers. */
@@ -2612,6 +2668,7 @@
 	kmsg->msg_control = (void *) orig_cmsg_uptr;
 }
 
+#if 0
 asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
 {
 	struct socket *sock;
@@ -2721,7 +2778,7 @@
 		sockfd_put(sock);
 	}
 
-	if(uaddr != NULL && err >= 0)
+	if(uaddr != NULL && err >= 0 && kern_msg.msg_namelen)
 		err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
 	if(cmsg_ptr != 0 && err >= 0) {
 		unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
@@ -2737,6 +2794,222 @@
 		return err;
 	return len;
 }
+#endif
+
+/*
+ *	BSD sendmsg interface
+ */
+
+int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags)
+{
+	struct socket *sock;
+	char address[MAX_SOCK_ADDR];
+	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
+	unsigned char ctl[sizeof(struct cmsghdr) + 20];	/* 20 is size of ipv6_pktinfo */
+	unsigned char *ctl_buf = ctl;
+	struct msghdr msg_sys;
+	int err, ctl_len, iov_size, total_len;
+	
+	err = -EFAULT;
+	if (msghdr_from_user32_to_kern(&msg_sys, msg))
+		goto out; 
+
+	sock = sockfd_lookup(fd, &err);
+	if (!sock) 
+		goto out;
+
+	/* do not move before msg_sys is valid */
+	err = -EINVAL;
+	if (msg_sys.msg_iovlen > UIO_MAXIOV)
+		goto out_put;
+
+	/* Check whether to allocate the iovec area*/
+	err = -ENOMEM;
+	iov_size = msg_sys.msg_iovlen * sizeof(struct iovec32);
+	if (msg_sys.msg_iovlen > UIO_FASTIOV) {
+		iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
+		if (!iov)
+			goto out_put;
+	}
+
+	/* This will also move the address data into kernel space */
+	err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ);
+	if (err < 0) 
+		goto out_freeiov;
+	total_len = err;
+
+	err = -ENOBUFS;
+
+	if (msg_sys.msg_controllen > INT_MAX)
+		goto out_freeiov;
+	ctl_len = msg_sys.msg_controllen; 
+	if (ctl_len) 
+	{
+		if (ctl_len > sizeof(ctl))
+		{
+			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
+			if (ctl_buf == NULL) 
+				goto out_freeiov;
+		}
+		else if (ctl_len < sizeof(struct cmsghdr))
+		{
+			/* to get same error message as on 31 bit native */
+			err = EOPNOTSUPP;
+			goto out_freeiov;
+		}
+		err = -EFAULT;
+		if (cmsghdr_from_user32_to_kern(&msg_sys, ctl_buf, ctl_len))
+			goto out_freectl;
+//		msg_sys.msg_control = ctl_buf;
+	}
+	msg_sys.msg_flags = flags;
+
+	if (sock->file->f_flags & O_NONBLOCK)
+		msg_sys.msg_flags |= MSG_DONTWAIT;
+	err = sock_sendmsg(sock, &msg_sys, total_len);
+
+out_freectl:
+	if (ctl_buf != ctl)    
+		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
+out_freeiov:
+	if (iov != iovstack)
+		sock_kfree_s(sock->sk, iov, iov_size);
+out_put:
+	sockfd_put(sock);
+out:       
+	return err;
+}
+
+static __inline__ void
+scm_recv32(struct socket *sock, struct msghdr *msg,
+		struct scm_cookie *scm, int flags, unsigned long cmsg_ptr)
+{
+	if(!msg->msg_control)
+	{
+		if(sock->passcred || scm->fp)
+			msg->msg_flags |= MSG_CTRUNC;
+		scm_destroy(scm);
+		return;
+	}
+	/* If recvmsg processing itself placed some
+	 * control messages into user space, it's is
+	 * using 64-bit CMSG processing, so we need
+	 * to fix it up before we tack on more stuff.
+	 */
+	if((unsigned long) msg->msg_control != cmsg_ptr)
+		cmsg32_recvmsg_fixup(msg, cmsg_ptr);
+	/* Wheee... */
+	if(sock->passcred)
+		put_cmsg32(msg,
+			SOL_SOCKET, SCM_CREDENTIALS,
+			sizeof(scm->creds), &scm->creds);
+	if(!scm->fp)
+		return;
+
+	scm_detach_fds32(msg, scm);
+}
+
+static int  
+sock_recvmsg32(struct socket *sock, struct msghdr *msg, int size, int flags,
+               unsigned long cmsg_ptr)
+{
+	struct scm_cookie scm;
+
+	memset(&scm, 0, sizeof(scm));
+	size = sock->ops->recvmsg(sock, msg, size, flags, &scm);
+	if (size >= 0)
+		scm_recv32(sock, msg, &scm, flags, cmsg_ptr);
+
+	return size;
+}
+
+/*
+ *	BSD recvmsg interface
+ */
+
+int
+sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags)
+{
+	struct socket *sock;
+	struct iovec iovstack[UIO_FASTIOV];
+	struct iovec *iov=iovstack;
+	struct msghdr msg_sys;
+	unsigned long cmsg_ptr;
+	int err, iov_size, total_len, len;
+
+	/* kernel mode address */
+	char addr[MAX_SOCK_ADDR];
+
+	/* user mode address pointers */
+	struct sockaddr *uaddr;
+	int *uaddr_len;
+	
+	err=-EFAULT;
+	if (msghdr_from_user32_to_kern(&msg_sys, msg))
+		goto out;
+
+	sock = sockfd_lookup(fd, &err);
+	if (!sock)
+		goto out;
+
+	err = -EINVAL;
+	if (msg_sys.msg_iovlen > UIO_MAXIOV)
+		goto out_put;
+	
+	/* Check whether to allocate the iovec area*/
+	err = -ENOMEM;
+	iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
+	if (msg_sys.msg_iovlen > UIO_FASTIOV) {
+		iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
+		if (!iov)
+			goto out_put;
+	}
+
+	/*
+	 *	Save the user-mode address (verify_iovec will change the
+	 *	kernel msghdr to use the kernel address space)
+	 */
+	 
+	uaddr = msg_sys.msg_name;
+	uaddr_len = &msg->msg_namelen;
+	err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE);
+	if (err < 0)
+		goto out_freeiov;
+	total_len=err;
+
+	cmsg_ptr = (unsigned long)msg_sys.msg_control;
+	msg_sys.msg_flags = 0;
+	
+	if (sock->file->f_flags & O_NONBLOCK)
+		flags |= MSG_DONTWAIT;
+	err = sock_recvmsg32(sock, &msg_sys, total_len, flags, cmsg_ptr);
+	if (err < 0)
+		goto out_freeiov;
+	len = err;
+
+	if (uaddr != NULL && 
+	/* in order to get same error message as on native 31 bit */
+		msg_sys.msg_namelen > 0) {
+		err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
+		if (err < 0)
+			goto out_freeiov;
+	}
+	err = __put_user(msg_sys.msg_flags, &msg->msg_flags);
+	if (err)
+		goto out_freeiov;
+	err = __put_user((__kernel_size_t32) ((unsigned long)msg_sys.msg_control - cmsg_ptr), &msg->msg_controllen);
+	if (err)
+		goto out_freeiov;
+	err = len;
+
+out_freeiov:
+	if (iov != iovstack)
+		sock_kfree_s(sock->sk, iov, iov_size);
+out_put:
+	sockfd_put(sock);
+out:
+	return err;
+}
 
 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
 				     char *optval, int optlen);
@@ -2820,6 +3093,20 @@
 	if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
 		return do_set_icmpv6_filter(fd, level, optname,
 					    optval, optlen);
+	if (level == SOL_SOCKET && 
+	    (optname == SO_SNDTIMEO || optname == SO_RCVTIMEO)) {
+		long ret;
+		struct timeval tmp;
+		mm_segment_t old_fs;
+
+		if (get_tv32(&tmp, (struct timeval32 *)optval ))
+			return -EFAULT;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		ret = sys_setsockopt(fd, level, optname, (char *) &tmp, sizeof(struct timeval));
+		set_fs(old_fs);
+		return ret; 
+	}
 
 	return sys_setsockopt(fd, level, optname, optval, optlen);
 }
@@ -3669,7 +3956,7 @@
  */
 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
 {
-	return copy_to_user(res32, kres, sizeof(*res32));
+	return copy_to_user(res32, kres, sizeof(*res32)) ? -EFAULT : 0;
 }
 
 /*
@@ -3891,15 +4178,25 @@
 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
 				 __kernel_size_t32 count, u32 poshi, u32 poslo)
 {
+	if ((ssize_t32) count < 0)
+		return -EINVAL; 
 	return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
 asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
 				  __kernel_size_t32 count, u32 poshi, u32 poslo)
 {
+	if ((ssize_t32) count < 0)
+		return -EINVAL; 
 	return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
+extern asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count);
+
+asmlinkage ssize_t32 sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count)
+{
+	return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
+}
 
 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
 
@@ -4344,3 +4641,22 @@
 	return ret;
 }
 
+asmlinkage ssize_t sys_read(unsigned int fd, char * buf, size_t count);
+
+asmlinkage ssize_t32 sys32_read(unsigned int fd, char * buf, size_t count)
+{
+	if ((ssize_t32) count < 0)
+		return -EINVAL; 
+
+	return sys_read(fd, buf, count);
+}
+
+asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count);
+
+asmlinkage ssize_t32 sys32_write(unsigned int fd, char * buf, size_t count)
+{
+	if ((ssize_t32) count < 0)
+		return -EINVAL; 
+
+	return sys_write(fd, buf, count);
+}
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/s390_ksyms.c linux-2.4.22-pre3/arch/s390x/kernel/s390_ksyms.c
--- linux-2.4.22-pre2/arch/s390x/kernel/s390_ksyms.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390x/kernel/s390_ksyms.c	2003-07-05 18:09:48.000000000 -0700
@@ -62,6 +62,20 @@
 EXPORT_SYMBOL(overflowuid);
 EXPORT_SYMBOL(overflowgid);
 
+#ifdef CONFIG_S390_SUPPORT
+/*
+ * Dynamically add/remove 31 bit ioctl conversion functions.
+ */
+extern int register_ioctl32_conversion(unsigned int cmd,
+				       int (*handler)(unsigned int, 
+						      unsigned int,
+						      unsigned long,
+						      struct file *));
+int unregister_ioctl32_conversion(unsigned int cmd);
+EXPORT_SYMBOL(register_ioctl32_conversion);
+EXPORT_SYMBOL(unregister_ioctl32_conversion);
+#endif
+
 /*
  * misc.
  */
@@ -70,5 +84,5 @@
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(console_mode);
 EXPORT_SYMBOL(console_device);
-EXPORT_SYMBOL(pfix_table);
 EXPORT_SYMBOL_NOVERS(do_call_softirq);
+EXPORT_SYMBOL(sys_wait4);
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/setup.c linux-2.4.22-pre3/arch/s390x/kernel/setup.c
--- linux-2.4.22-pre2/arch/s390x/kernel/setup.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390x/kernel/setup.c	2003-07-05 18:09:48.000000000 -0700
@@ -56,8 +56,6 @@
 unsigned long cpu_initialized = 0;
 volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
 
-void* *pfix_table=NULL;
-
 /*
  * Setup options
  */
@@ -319,10 +317,6 @@
 	printk((MACHINE_IS_VM) ?
 	       "We are running under VM (64 bit mode)\n" :
 	       "We are running native (64 bit mode)\n");
-	if (MACHINE_IS_VM)
-		printk((MACHINE_HAS_PFIX) ?
-		       "This machine has PFIX support\n" :
-		       "This machine has no PFIX support\n");
 
         ROOT_DEV = to_kdev_t(0x0100);
         memory_start = (unsigned long) &_end;    /* fixit if use $CODELO etc*/
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/signal.c linux-2.4.22-pre3/arch/s390x/kernel/signal.c
--- linux-2.4.22-pre2/arch/s390x/kernel/signal.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390x/kernel/signal.c	2003-07-05 18:09:48.000000000 -0700
@@ -575,10 +575,7 @@
                                 /* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/signal32.c linux-2.4.22-pre3/arch/s390x/kernel/signal32.c
--- linux-2.4.22-pre2/arch/s390x/kernel/signal32.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390x/kernel/signal32.c	2003-07-05 18:09:48.000000000 -0700
@@ -302,7 +302,7 @@
 		save_fp_regs(&fpregs);
 		__put_user(fpregs.fpc, &sregs->fpregs.fpc);
 		for(i=0; i<NUM_FPRS; i++)
-			err |= __put_user(fpregs.fprs[i].d, &sregs->fpregs.fprs[i].d);  
+			err |= __put_user(fpregs.fprs[i].ui, &sregs->fpregs.fprs[i].d);  
 	}
 	return(err);
 	
@@ -331,7 +331,7 @@
 		(regs->psw.addr&PSW_ADDR_DEBUGCHANGE);
 		__get_user(fpregs.fpc, &sregs->fpregs.fpc);
                 for(i=0; i<NUM_FPRS; i++)
-                        err |= __get_user(fpregs.fprs[i].d, &sregs->fpregs.fprs[i].d);              
+                        err |= __get_user(fpregs.fprs[i].ui, &sregs->fpregs.fprs[i].d);              
 		if(!err)
 			restore_fp_regs(&fpregs);
 	}
@@ -474,6 +474,10 @@
 			goto give_sigsegv;
         }
 
+	/* Set up backchain. */
+	if (__put_user((unsigned int) regs->gprs[15], (unsigned int *) frame))
+		goto give_sigsegv;
+
 	/* Set up registers for signal handler */
 	regs->gprs[15] = (addr_t)frame;
 	regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
@@ -527,6 +531,10 @@
 		                  (u16 *)(frame->retcode));
 	}
 
+	/* Set up backchain. */
+	if (__put_user((unsigned int) regs->gprs[15], (unsigned int *) frame))
+		goto give_sigsegv;
+
 	/* Set up registers for signal handler */
 	regs->gprs[15] = (addr_t)frame;
 	regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
@@ -675,7 +683,7 @@
 				continue;
 
 			switch (signr) {
-			case SIGCONT: case SIGCHLD: case SIGWINCH:
+			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
 				continue;
 
 			case SIGTSTP: case SIGTTIN: case SIGTTOU:
diff -urN linux-2.4.22-pre2/arch/s390x/kernel/wrapper32.S linux-2.4.22-pre3/arch/s390x/kernel/wrapper32.S
--- linux-2.4.22-pre2/arch/s390x/kernel/wrapper32.S	2002-02-25 11:37:56.000000000 -0800
+++ linux-2.4.22-pre3/arch/s390x/kernel/wrapper32.S	2003-07-05 18:09:48.000000000 -0700
@@ -17,14 +17,14 @@
 	llgfr	%r2,%r2			# unsigned int
 	llgtr	%r3,%r3			# char *
 	llgfr	%r4,%r4			# size_t
-	jg	sys_read		# branch to sys_read
+	jg	sys32_read		# branch to sys_read
 
 	.globl  sys32_write_wrapper 
 sys32_write_wrapper:
 	llgfr	%r2,%r2			# unsigned int
 	llgtr	%r3,%r3			# const char *
 	llgfr	%r4,%r4			# size_t
-	jg	sys_write		# branch to system call
+	jg	sys32_write		# branch to system call
 
 	.globl  sys32_open_wrapper 
 sys32_open_wrapper:
@@ -311,6 +311,12 @@
 	llgtr	%r3,%r3			# struct rlimit_emu31 *
 	jg	sys32_old_getrlimit	# branch to system call
 
+	.globl  sys32_getrlimit_wrapper 
+sys32_getrlimit_wrapper:
+	llgfr	%r2,%r2			# unsigned int
+	llgtr	%r3,%r3			# struct rlimit_emu31 *
+	jg	sys32_getrlimit		# branch to system call
+
 	.globl  sys32_mmap2_wrapper 
 sys32_mmap2_wrapper:
 	llgtr	%r2,%r2			# struct mmap_arg_struct_emu31 *
@@ -537,7 +543,7 @@
 	.globl  sys32_newuname_wrapper 
 sys32_newuname_wrapper:
 	llgtr	%r2,%r2			# struct new_utsname *
-	jg	sys_newuname		# branch to system call
+	jg	s390x_newuname		# branch to system call
 
 	.globl  sys32_adjtimex_wrapper 
 sys32_adjtimex_wrapper:
@@ -614,7 +620,7 @@
 	.globl  sys32_personality_wrapper 
 sys32_personality_wrapper:
 	llgfr	%r2,%r2			# unsigned long
-	jg	sys_personality		# branch to system call
+	jg	s390x_personality	# branch to system call
 
 	.globl  sys32_setfsuid16_wrapper 
 sys32_setfsuid16_wrapper:
@@ -1091,3 +1097,13 @@
 	llgtr	%r3,%r3			# struct stat64 *
 	llgfr	%r4,%r4			# long
 	jg	sys32_fstat64		# branch to system call
+
+	.globl	sys32_stime_wrapper
+sys32_stime_wrapper:
+	llgtr	%r2,%r2			# int *
+	jg	sys_stime		# branch to system call
+
+	.globl  sys32_sysctl_wrapper
+sys32_sysctl_wrapper:
+	llgtr   %r2,%r2                 # struct __sysctl_args32 *
+	jg      sys32_sysctl
diff -urN linux-2.4.22-pre2/arch/s390x/mm/init.c linux-2.4.22-pre3/arch/s390x/mm/init.c
--- linux-2.4.22-pre2/arch/s390x/mm/init.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/s390x/mm/init.c	2003-07-05 18:09:48.000000000 -0700
@@ -45,6 +45,28 @@
 pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
 char  empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
 
+static inline int
+__pgd_populate(unsigned long *pgd_slot, unsigned long offset, pmd_t *pmd)
+{
+	if (offset == 0 && 
+	    ((*pgd_slot & _PGD_ENTRY_INV) != 0 ||
+	     (*pgd_slot & _PGD_ENTRY_LEN(2)) == 0)) {
+		/* Set lower pmd, upper pmd is empty. */
+		*pgd_slot = __pa(pmd) | _PGD_ENTRY_MASK |
+				_PGD_ENTRY_OFF(0) | _PGD_ENTRY_LEN(1);
+		return 1;
+	}
+	if (offset == 4 &&
+	    ((*pgd_slot & _PGD_ENTRY_INV) != 0 ||
+	     (*pgd_slot & _PGD_ENTRY_OFF(2)) != 0)) {
+		/* Lower pmd empty, set upper pmd. */
+		*pgd_slot = (__pa(pmd) - 0x2000) | _PGD_ENTRY_MASK |
+				_PGD_ENTRY_OFF(2) | _PGD_ENTRY_LEN(3);
+		return 1;
+	}
+        return 0;
+}
+
 pmd_t *pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
 {
         unsigned long addr = (unsigned long) pgd;
@@ -52,29 +74,42 @@
         unsigned long offset = addr & 4;
 	pmd_t *new, *pmd2;
 	int i;
- 
-        if (offset == 0 && 
-	    ((*pgd_slot & _PGD_ENTRY_INV) != 0 ||
-	     (*pgd_slot & _PGD_ENTRY_LEN(2)) == 0)) {
-                /* Set lower pmd, upper pmd is empty. */
-                *pgd_slot = __pa(pmd) | _PGD_ENTRY_MASK |
-                                _PGD_ENTRY_OFF(0) | _PGD_ENTRY_LEN(1);
-                return pmd;
-        }
-        if (offset == 4 &&
-	    ((*pgd_slot & _PGD_ENTRY_INV) != 0 ||
-	     (*pgd_slot & _PGD_ENTRY_OFF(2)) != 0)) {
-                /* Lower pmd empty, set upper pmd. */
-                *pgd_slot = (__pa(pmd) - 0x2000) | _PGD_ENTRY_MASK |
-                                _PGD_ENTRY_OFF(2) | _PGD_ENTRY_LEN(3);
+
+        /* Check if we can get away with a half-sized pmd. */
+        if (__pgd_populate(pgd_slot, offset, pmd))
                 return pmd;
-        }
+
         /* We have to enlarge the pmd to 16K if we arrive here. */
+        spin_unlock(&mm->page_table_lock);
 	new = (pmd_t *) __get_free_pages(GFP_KERNEL, 2);
-	if (new == NULL) {
+        spin_lock(&mm->page_table_lock);
+
+        /*
+         * Because we dropped the lock, we should re-check the
+         * entry, as somebody else could have populated it..
+         */
+        if (!pgd_none(*pgd)) {
+                if (new)
+                        free_pages((unsigned long) new, 2);
+                pmd_free(pmd);
+                return (pmd_t *) pgd_val(*pgd);
+        }
+
+	if (!new) {
 		pmd_free(pmd);
 		return NULL;
 	}
+
+        /*
+         * Re-check if we can get away with a half-sized pmd. We
+         * dropped the lock so somebody else could have freed the
+         * other half of the pmd.
+         */
+        if (__pgd_populate(pgd_slot, offset, pmd)) {
+                free_pages((unsigned long) new, 2);
+                return pmd;
+        }
+
 	/* Set the PG_arch_1 bit on the first and the third pmd page
            so that pmd_free_fast can recognize pmds that have been
            allocated with an order 2 allocation.  */
@@ -234,11 +269,6 @@
                                         continue;
                                 }
                                 set_pte(pt_dir, pte);
-				if (address < memory_size ) /* do not set storage
-							       key outside the storage
-							       or die */
-					set_access_key(pte); /* switch to our
-								access key */
                                 address += PAGE_SIZE;
                         }
                 }
diff -urN linux-2.4.22-pre2/arch/s390x/vmlinux-shared.lds linux-2.4.22-pre3/arch/s390x/vmlinux-shared.lds
--- linux-2.4.22-pre2/arch/s390x/vmlinux-shared.lds	2002-02-25 11:37:56.000000000 -0800
+++ linux-2.4.22-pre3/arch/s390x/vmlinux-shared.lds	2003-07-05 18:09:48.000000000 -0700
@@ -2,7 +2,7 @@
  * Written by Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
 OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
-OUTPUT_ARCH(s390)
+OUTPUT_ARCH(s390:64-bit)
 ENTRY(_start)
 SECTIONS
 {
diff -urN linux-2.4.22-pre2/arch/s390x/vmlinux.lds linux-2.4.22-pre3/arch/s390x/vmlinux.lds
--- linux-2.4.22-pre2/arch/s390x/vmlinux.lds	2002-02-25 11:37:56.000000000 -0800
+++ linux-2.4.22-pre3/arch/s390x/vmlinux.lds	2003-07-05 18:09:48.000000000 -0700
@@ -2,7 +2,7 @@
  * Written by Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
 OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
-OUTPUT_ARCH(s390)
+OUTPUT_ARCH(s390:64-bit)
 ENTRY(_start)
 SECTIONS
 {
diff -urN linux-2.4.22-pre2/arch/sh/config.in linux-2.4.22-pre3/arch/sh/config.in
--- linux-2.4.22-pre2/arch/sh/config.in	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/sh/config.in	2003-07-05 18:09:49.000000000 -0700
@@ -387,4 +387,5 @@
 fi
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -urN linux-2.4.22-pre2/arch/sh64/Makefile linux-2.4.22-pre3/arch/sh64/Makefile
--- linux-2.4.22-pre2/arch/sh64/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/Makefile	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,91 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2000, 2001  Paolo Alberelli
+# Copyright (C) 2003  Paul Mundt
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# Note that top level Makefile automagically builds dependencies for SUBDIRS
+# but does not automagically clean SUBDIRS. Therefore "archclean" should clean
+# up all, "archdep" does nothing on added SUBDIRS.
+#
+
+cpu-y				:= -mb
+cpu-$(CONFIG_LITTLE_ENDIAN)	:= -ml
+
+cpu-$(CONFIG_CPU_SH5)		+= -m5-32media-nofpu
+
+ifdef CONFIG_LITTLE_ENDIAN
+LDFLAGS		+= -EL  -mshlelf32_linux
+else
+LDFLAGS		+= -EB  -mshelf32_linux
+endif
+
+# No requirements for endianess support from AFLAGS, 'as' always run through gcc
+AFLAGS		+= -m5 -isa=sh64 -traditional
+CFLAGS		+= $(cpu-y)
+
+ENTRY_POINT	= --defsym phys_stext=_stext-0x$(CONFIG_CACHED_MEMORY_OFFSET) \
+		  -e phys_stext
+OBJCOPY		= $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment \
+		  -R .stab -R .stabstr -S
+LD		= $(CROSS_COMPILE)ld $(LDFLAGS)
+
+LINKFLAGS     += -T arch/$(ARCH)/vmlinux.lds  $(ENTRY_POINT)
+
+ifdef LOADADDR
+LINKFLAGS     += -Ttext $(word 1,$(LOADADDR))
+endif
+
+machine-$(CONFIG_SH_CAYMAN)	:= cayman
+machine-$(CONFIG_SH_SIMULATOR)	:= sim
+machine-$(CONFIG_SH_HARP)	:= harp
+
+HEAD := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o
+MAKEROOTFS =
+
+SUBDIRS += $(addprefix arch/$(ARCH)/, kernel mm lib mach-$(machine-y))
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+	      arch/$(ARCH)/mach-$(machine-y)/$(machine-y).o \
+	      $(CORE_FILES) 
+
+LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+LIBS := $(TOPDIR)/arch/$(ARCH)/lib/lib.a $(LIBS) $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+#
+# override the assembly rules
+#
+#.S.o:
+#	$(CC) $(CFLAGS) $(AFLAGS) -c $< -o $*.o
+
+vmlinux: arch/$(ARCH)/vmlinux.lds
+
+arch/$(ARCH)/vmlinux.lds: arch/$(ARCH)/vmlinux.lds.S FORCE
+	$(CPP) $(TOOLCHAIN) $(AFLAGS) -C -P -I$(HPATH) -U$(ARCH) arch/$(ARCH)/vmlinux.lds.S >arch/$(ARCH)/vmlinux.lds
+
+FORCE: ;
+
+zImage: vmlinux
+	@$(MAKEBOOT) zImage
+
+compressed: zImage
+
+zdisk: vmlinux
+	@$(MAKEBOOT) zdisk
+
+archclean:
+#	@$(MAKEBOOT) clean
+
+archmrproper:
+	rm -f arch/$(ARCH)/vmlinux.lds
+
+archdep:
+#	@$(MAKEBOOT) dep
diff -urN linux-2.4.22-pre2/arch/sh64/boot/Makefile linux-2.4.22-pre3/arch/sh64/boot/Makefile
--- linux-2.4.22-pre2/arch/sh64/boot/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/boot/Makefile	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,34 @@
+#
+# arch/shmedia/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002 Stuart Menefy
+#
+
+SYSTEM  =$(TOPDIR)/vmlinux
+
+Image:	$(CONFIGURE) $(SYSTEM)
+	$(OBJCOPY) $(SYSTEM) Image
+
+zImage: $(CONFIGURE) compressed/vmlinux
+	$(OBJCOPY) compressed/vmlinux zImage
+
+compressed/vmlinux: $(TOPDIR)/vmlinux
+	$(MAKE) -C compressed vmlinux
+
+install: $(CONFIGURE) Image
+	sh -x ./install.sh $(KERNELRELEASE) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
+
+zinstall: $(CONFIGURE) zImage
+	sh -x ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
+
+dep:
+
+clean:
+	rm -f tools/build
+	rm -f setup bootsect zImage compressed/vmlinux.out
+	rm -f bsetup bbootsect bzImage compressed/bvmlinux.out
+	@$(MAKE) -C compressed clean
diff -urN linux-2.4.22-pre2/arch/sh64/boot/compressed/Makefile linux-2.4.22-pre3/arch/sh64/boot/compressed/Makefile
--- linux-2.4.22-pre2/arch/sh64/boot/compressed/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/boot/compressed/Makefile	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,57 @@
+#
+# linux/arch/shmedia/boot/compressed/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002 Stuart Menefy
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+
+# This is a temporary work around for a problem with the Linux ld.
+# We can't use the Linux linker, because it doesn't work with binary
+# files, so we use the bard machine linker instead...
+PIGGYLD=sh64-superh-elf-ld -EL # -m shlelf64
+# ...which has the knock on that we need this when doing the final link.
+EXTRAFLAGS=--no-warn-mismatch
+
+HEAD = head.o
+SYSTEM = $(TOPDIR)/vmlinux
+
+OBJECTS = $(HEAD) misc.o cache.o
+
+ZLDFLAGS = -e startup -T vmlinux.lds
+
+#
+# ZIMAGE_OFFSET is the load offset of the compression loader
+# (4M for the kernel plus 64K for this loader)
+#
+ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x$(CONFIG_MEMORY_START)+0x400000+0x10000])
+
+ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS)
+
+all: vmlinux
+
+vmlinux.lds: vmlinux.lds.S
+	$(CPP) -traditional -C -P -I$(HPATH) -Ush vmlinux.lds.S >vmlinux.lds
+
+vmlinux: piggy.o $(OBJECTS) vmlinux.lds
+	$(LD) $(ZLINKFLAGS) $(EXTRAFLAGS) -o vmlinux $(OBJECTS) piggy.o
+
+head.o: head.S
+	$(CC) $(AFLAGS) -traditional -c head.S
+
+piggy.o:	$(SYSTEM)
+	tmppiggy=_tmp_$$$$piggy; \
+	rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
+	$(OBJCOPY) -R .empty_zero_page $(SYSTEM) $$tmppiggy; \
+	gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
+	echo "SECTIONS { .image : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
+	$(PIGGYLD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-sh64 -T $$tmppiggy.lnk; \
+	rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
+
+clean:
+	rm -f vmlinux _tmp_*
diff -urN linux-2.4.22-pre2/arch/sh64/boot/compressed/cache.c linux-2.4.22-pre3/arch/sh64/boot/compressed/cache.c
--- linux-2.4.22-pre2/arch/sh64/boot/compressed/cache.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/boot/compressed/cache.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,39 @@
+/*
+ * arch/shmedia/boot/compressed/cache.c -- simple cache management functions
+ *
+ * Code extracted from sh-ipl+g, sh-stub.c, which has the copyright:
+ *
+ *   This is originally based on an m68k software stub written by Glenn
+ *   Engel at HP, but has changed quite a bit. 
+ *
+ *   Modifications for the SH by Ben Lee and Steve Chamberlain
+ *
+****************************************************************************
+
+		THIS SOFTWARE IS NOT COPYRIGHTED
+
+   HP offers the following for use in the public domain.  HP makes no
+   warranty with regard to the software or it's performance and the
+   user accepts the software "AS IS" with all faults.
+
+   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+#define CACHE_ENABLE      0
+#define CACHE_DISABLE     1
+
+int cache_control(unsigned int command)
+{
+	volatile unsigned int *p = (volatile unsigned int *) 0x80000000;
+	int i;
+
+	for (i = 0; i < (32 * 1024); i += 32) {
+		(void *) *p;
+		p += (32 / sizeof (int));
+	}
+
+	return 0;
+}
diff -urN linux-2.4.22-pre2/arch/sh64/boot/compressed/head.S linux-2.4.22-pre3/arch/sh64/boot/compressed/head.S
--- linux-2.4.22-pre2/arch/sh64/boot/compressed/head.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/boot/compressed/head.S	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,164 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/shmedia/boot/compressed/head.S
+ *
+ * Copied from
+ *   arch/shmedia/kernel/head.S
+ * which carried the copyright:
+ *   Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * Modification for compressed loader:
+ *   Copyright (C) 2002 Stuart Menefy (stuart.menefy@st.com)
+ */
+
+#include <linux/linkage.h>
+#include <asm/registers.h>
+#include <asm/cache.h>
+#include <asm/mmu_context.h>
+
+/*
+ * Fixed TLB entries to identity map the beginning of RAM
+ */
+#define MMUIR_TEXT_H	0x0000000000000003 | CONFIG_MEMORY_START
+			/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
+#define MMUIR_TEXT_L	0x000000000000009a | CONFIG_MEMORY_START
+			/* 512 Mb, Cacheable (Write-back), execute, Not User, Ph. Add. */
+
+#define MMUDR_CACHED_H	0x0000000000000003 | CONFIG_MEMORY_START
+			/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
+#define MMUDR_CACHED_L	0x000000000000015a | CONFIG_MEMORY_START
+			/* 512 Mb, Cacheable (Write-back), read/write, Not User, Ph. Add. */
+
+#define	ICCR0_INIT_VAL	ICCR0_ON | ICCR0_ICI		/* ICE + ICI */
+#define	ICCR1_INIT_VAL	ICCR1_NOLOCK			/* No locking */
+
+#if 1
+#define	OCCR0_INIT_VAL	OCCR0_ON | OCCR0_OCI | OCCR0_WB	/* OCE + OCI + WB */
+#else
+#define	OCCR0_INIT_VAL	OCCR0_OFF
+#endif
+#define	OCCR1_INIT_VAL	OCCR1_NOLOCK			/* No locking */
+	
+	.text
+
+	.global	startup
+startup:
+	/*
+	 * Prevent speculative fetch on device memory due to
+	 * uninitialized target registers.
+	 * This must be executed before the first branch.
+	 */
+	ptabs/u	ZERO, t0
+	ptabs/u	ZERO, t1
+	ptabs/u	ZERO, t2
+	ptabs/u	ZERO, t3
+	ptabs/u	ZERO, t4
+	ptabs/u	ZERO, t5
+	ptabs/u	ZERO, t6
+	ptabs/u	ZERO, t7
+	synci
+
+	/*
+	 * Set initial TLB entries for cached and uncached regions.
+	 * Note: PTA/BLINK is PIC code, PTABS/BLINK isn't !
+	 */
+	/* Clear ITLBs */
+	pta	1f, t1
+	movi	ITLB_FIXED, r21
+	movi	ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22
+1:	putcfg	r21, 0, ZERO		/* Clear MMUIR[n].PTEH.V */
+	addi	r21, TLB_STEP, r21
+        bne	r21, r22, t1
+
+	/* Clear DTLBs */
+	pta	1f, t1
+	movi	DTLB_FIXED, r21
+	movi	DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22
+1:	putcfg	r21, 0, ZERO		/* Clear MMUDR[n].PTEH.V */
+	addi	r21, TLB_STEP, r21
+        bne	r21, r22, t1
+
+	/* Map one big (512Mb) page for ITLB */
+	movi	ITLB_FIXED, r21
+	movi	MMUIR_TEXT_L, r22	/* PTEL first */
+	putcfg	r21, 1, r22		/* Set MMUIR[0].PTEL */
+	movi	MMUIR_TEXT_H, r22	/* PTEH last */
+	putcfg	r21, 0, r22		/* Set MMUIR[0].PTEH */
+	
+	/* Map one big CACHED (512Mb) page for DTLB */
+	movi	DTLB_FIXED, r21
+	movi	MMUDR_CACHED_L, r22	/* PTEL first */
+	putcfg	r21, 1, r22		/* Set MMUDR[0].PTEL */
+	movi	MMUDR_CACHED_H, r22	/* PTEH last */
+	putcfg	r21, 0, r22		/* Set MMUDR[0].PTEH */
+
+	/* ICache */
+	movi	ICCR_BASE, r21
+	movi	ICCR0_INIT_VAL, r22
+	movi	ICCR1_INIT_VAL, r23
+	putcfg	r21, ICCR_REG0, r22
+	putcfg	r21, ICCR_REG1, r23
+	synci
+
+	/* OCache */
+	movi	OCCR_BASE, r21
+	movi	OCCR0_INIT_VAL, r22
+	movi	OCCR1_INIT_VAL, r23
+	putcfg	r21, OCCR_REG0, r22
+	putcfg	r21, OCCR_REG1, r23
+	synco
+	
+	/*
+	 * Enable the MMU.
+	 * From here-on code can be non-PIC.
+	 */
+	movi	SR_HARMLESS | SR_ENABLE_MMU, r22
+	putcon	r22, SSR
+	movi	1f, r22
+	putcon	r22, SPC
+	synco
+	rte				/* And now go into the hyperspace ... */
+1:					/* ... that's the next instruction ! */
+
+	/* Set initial stack pointer */
+	movi	datalabel stack_start, r0
+	ld.l	r0, 0, r15
+
+	/*
+	 * Clear bss
+	 */
+	pt	1f, tr1
+	movi	datalabel __bss_start, r22
+	movi	datalabel _end, r23
+1:	st.l	r22, 0, ZERO 
+	addi	r22, 4, r22
+	bne	r22, r23, tr1
+
+	/*
+	 * Decompress the kernel.
+	 */
+	pt	decompress_kernel, tr0
+	blink	tr0, r18
+
+	/*
+	 * Disable the MMU.
+	 */
+	movi	SR_HARMLESS, r22
+	putcon	r22, SSR
+	movi	1f, r22
+	putcon	r22, SPC
+	synco
+	rte				/* And now go into the hyperspace ... */
+1:					/* ... that's the next instruction ! */
+
+	/* Jump into the decompressed kernel */	
+	movi	datalabel (CONFIG_MEMORY_START + 0x2000)+1, r19
+	ptabs	r19, tr0
+	blink	tr0, r18
+
+	/* Shouldn't return here, but just in case, loop forever */
+	pt	1f, tr0
+1:	blink	tr0, ZERO
diff -urN linux-2.4.22-pre2/arch/sh64/boot/compressed/install.sh linux-2.4.22-pre3/arch/sh64/boot/compressed/install.sh
--- linux-2.4.22-pre2/arch/sh64/boot/compressed/install.sh	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/boot/compressed/install.sh	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# arch/sh/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Russell King
+# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy
+#
+# "make install" script for sh architecture
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+
+if [ -x /sbin/installkernel ]; then
+  exec /sbin/installkernel "$@"
+fi
+
+if [ "$2" = "zImage" ]; then
+# Compressed install
+  echo "Installing compressed kernel"
+  if [ -f $4/vmlinuz-$1 ]; then
+    mv $4/vmlinuz-$1 $4/vmlinuz.old
+  fi
+
+  if [ -f $4/System.map-$1 ]; then
+    mv $4/System.map-$1 $4/System.old
+  fi
+
+  cat $2 > $4/vmlinuz-$1
+  cp $3 $4/System.map-$1
+else
+# Normal install
+  echo "Installing normal kernel"
+  if [ -f $4/vmlinux-$1 ]; then
+    mv $4/vmlinux-$1 $4/vmlinux.old
+  fi
+
+  if [ -f $4/System.map ]; then
+    mv $4/System.map $4/System.old
+  fi
+
+  cat $2 > $4/vmlinux-$1
+  cp $3 $4/System.map
+fi
diff -urN linux-2.4.22-pre2/arch/sh64/boot/compressed/misc.c linux-2.4.22-pre3/arch/sh64/boot/compressed/misc.c
--- linux-2.4.22-pre2/arch/sh64/boot/compressed/misc.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/boot/compressed/misc.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,251 @@
+/*
+ * arch/shmedia/boot/compressed/misc.c
+ * 
+ * This is a collection of several routines from gzip-1.0.3 
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SHmedia from sh by Stuart Menefy, May 2002
+ */
+
+#include <linux/config.h>
+#include <asm/uaccess.h>
+
+/* cache.c */
+#define CACHE_ENABLE      0
+#define CACHE_DISABLE     1
+int cache_control(unsigned int command);
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n)     memset ((s), 0, (n))
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+#define WSIZE 0x8000		/* Window size must be at least 32k, */
+				/* and a power of two */
+
+static uch *inbuf;		/* input buffer */
+static uch window[WSIZE];	/* Sliding window buffer */
+
+static unsigned insize = 0;	/* valid bytes in inbuf */
+static unsigned inptr = 0;	/* index of next byte to be processed in inbuf */
+static unsigned outcnt = 0;	/* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01	/* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02	/* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
+#define ORIG_NAME    0x08	/* bit 3 set: original file name present */
+#define COMMENT      0x10	/* bit 4 set: file comment present */
+#define ENCRYPTED    0x20	/* bit 5 set: file is encrypted */
+#define RESERVED     0xC0	/* bit 6,7:   reserved */
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+static int fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+extern char input_data[];
+extern int input_len;
+
+static long bytes_out = 0;
+static uch *output_data;
+static unsigned long output_ptr = 0;
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+static void puts(const char *);
+
+extern int _text;		/* Defined in vmlinux.lds.S */
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#define HEAP_SIZE             0x10000
+
+#include "../../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+	void *p;
+
+	if (size < 0)
+		error("Malloc error\n");
+	if (free_mem_ptr == 0)
+		error("Memory error\n");
+
+	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
+
+	p = (void *) free_mem_ptr;
+	free_mem_ptr += size;
+
+	if (free_mem_ptr >= free_mem_end_ptr)
+		error("\nOut of memory\n");
+
+	return p;
+}
+
+static void free(void *where)
+{				/* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+	*ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+	free_mem_ptr = (long) *ptr;
+}
+
+void puts(const char *s)
+{
+}
+
+void *memset(void *s, int c, size_t n)
+{
+	int i;
+	char *ss = (char *) s;
+
+	for (i = 0; i < n; i++)
+		ss[i] = c;
+	return s;
+}
+
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+	int i;
+	char *d = (char *) __dest, *s = (char *) __src;
+
+	for (i = 0; i < __n; i++)
+		d[i] = s[i];
+	return __dest;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+	if (insize != 0) {
+		error("ran out of input data\n");
+	}
+
+	inbuf = input_data;
+	insize = input_len;
+	inptr = 1;
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window(void)
+{
+	ulg c = crc;		/* temporary variable */
+	unsigned n;
+	uch *in, *out, ch;
+
+	in = window;
+	out = &output_data[output_ptr];
+	for (n = 0; n < outcnt; n++) {
+		ch = *out++ = *in++;
+		c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
+	}
+	crc = c;
+	bytes_out += (ulg) outcnt;
+	output_ptr += (ulg) outcnt;
+	outcnt = 0;
+	puts(".");
+}
+
+static void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while (1) ;		/* Halt */
+}
+
+#define STACK_SIZE (4096)
+long __attribute__ ((aligned(8))) user_stack[STACK_SIZE];
+long *stack_start = &user_stack[STACK_SIZE];
+
+void decompress_kernel(void)
+{
+	output_data = (uch *) (CONFIG_MEMORY_START + 0x2000);
+	free_mem_ptr = (unsigned long) &_end;
+	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+	makecrc();
+	puts("Uncompressing Linux... ");
+	cache_control(CACHE_ENABLE);
+	gunzip();
+	puts("\n");
+
+#if 0
+	/* When booting from ROM may want to do something like this if the
+	 * boot loader doesn't.
+	 */
+
+	/* Set up the parameters and command line */
+	{
+		volatile unsigned int *parambase =
+		    (int *) (CONFIG_MEMORY_START + 0x1000);
+
+		parambase[0] = 0x1;	/* MOUNT_ROOT_RDONLY */
+		parambase[1] = 0x0;	/* RAMDISK_FLAGS */
+		parambase[2] = 0x0200;	/* ORIG_ROOT_DEV */
+		parambase[3] = 0x0;	/* LOADER_TYPE */
+		parambase[4] = 0x0;	/* INITRD_START */
+		parambase[5] = 0x0;	/* INITRD_SIZE */
+		parambase[6] = 0;
+
+		strcpy((char *) ((int) parambase + 0x100),
+		       "console=ttySC0,38400");
+	}
+#endif
+
+	puts("Ok, booting the kernel.\n");
+
+	cache_control(CACHE_DISABLE);
+}
diff -urN linux-2.4.22-pre2/arch/sh64/boot/compressed/vmlinux.lds.S linux-2.4.22-pre3/arch/sh64/boot/compressed/vmlinux.lds.S
--- linux-2.4.22-pre2/arch/sh64/boot/compressed/vmlinux.lds.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/boot/compressed/vmlinux.lds.S	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,65 @@
+/*
+ * ld script to make compressed SuperH/shmedia Linux kernel+decompression
+		bootstrap
+ * Modified by Stuart Menefy from arch/sh/vmlinux.lds.S written by Niibe Yutaka 
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_LITTLE_ENDIAN
+/* OUTPUT_FORMAT("elf32-sh64l-linux", "elf32-sh64l-linux", "elf32-sh64l-linux") */
+#define NOP 0x6ff0fff0
+#else
+/* OUTPUT_FORMAT("elf32-sh64", "elf32-sh64", "elf32-sh64") */
+#define NOP 0xf0fff06f
+#endif
+
+OUTPUT_FORMAT("elf32-sh64-linux")
+OUTPUT_ARCH(sh)
+ENTRY(_start)
+
+#define ALIGNED_GAP(section, align) (((ADDR(section)+SIZEOF(section)+(align)-1) & ~((align)-1))-ADDR(section))
+#define FOLLOWING(section, align) AT (LOADADDR(section) + ALIGNED_GAP(section,align))
+
+SECTIONS
+{
+  _text = .;			/* Text and read-only data */
+
+  .text : {
+	*(.text)
+	*(.text64)
+	*(.text..SHmedia32)
+	*(.fixup)
+	*(.gnu.warning)
+	} = NOP
+  . = ALIGN(4);
+  .rodata : { *(.rodata) }
+
+  /* There is no 'real' reason for eight byte alignment, four would work
+   * as well, but gdb downloads much (*4) faster with this.
+   */
+  . = ALIGN(8);
+  .image : { *(.image) }
+  . = ALIGN(4);
+  _etext = .;			/* End of text section */
+
+  .data :			/* Data */
+	FOLLOWING(.image, 4)
+	{
+	_data = .;
+	*(.data)
+	}
+  _data_image = LOADADDR(.data);/* Address of data section in ROM */
+
+  _edata = .;			/* End of data section */
+
+  .stack : { stack = .;  _stack = .; }
+
+  . = ALIGN(4);
+  __bss_start = .;		/* BSS */
+  .bss : {
+	*(.bss)
+	}
+  . = ALIGN(4);
+  _end = . ;
+}
diff -urN linux-2.4.22-pre2/arch/sh64/config.in linux-2.4.22-pre3/arch/sh64/config.in
--- linux-2.4.22-pre2/arch/sh64/config.in	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/config.in	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,302 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+mainmenu_name "Linux/SH64 Kernel Configuration"
+
+define_bool CONFIG_SUPERH y
+
+define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+
+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 'System type'
+choice 'SuperH system type'					\
+	"Generic		CONFIG_SH_GENERIC		\
+	 Simulator		CONFIG_SH_SIMULATOR		\
+	 Cayman		        CONFIG_SH_CAYMAN		\
+	 ST50-Harp		CONFIG_SH_HARP" Simulator
+endmenu
+
+mainmenu_option next_comment
+comment 'Processor type and features'
+comment 'Processor options'
+choice 'Processor family'					\
+	"SH-5			CONFIG_CPU_SH5" SH-5
+
+if [ "$CONFIG_CPU_SH5" = "y" ]; then
+   choice 'Processor type' \
+   	"SH5-101		CONFIG_CPU_SUBTYPE_SH5_101	\
+	 SH5-103		CONFIG_CPU_SUBTYPE_SH5_103" SH5-101
+fi
+
+choice 'Endianness' \
+       "Little-Endian		CONFIG_LITTLE_ENDIAN		\
+	Big-Endian		CONFIG_BIG_ENDIAN" Little-Endian
+
+# Use 32-bit addressing for now.
+# EMI based.
+# P2 (UNCACHED) required to use identity mapping
+# P1 (CACHED) assumes non-identity.
+
+#
+# Memory options
+#
+comment 'Memory options'
+
+int 'Memory size (in MB)' CONFIG_MEMORY_SIZE_IN_MB 64
+hex 'Cached Area Offset' CONFIG_CACHED_MEMORY_OFFSET 20000000
+hex 'Uncached Area Offset' CONFIG_UNCACHED_MEMORY_OFFSET 00000000
+hex 'Physical memory start address' CONFIG_MEMORY_START 80000000
+
+#
+# Cache options
+#
+comment 'Cache options'
+bool 'DCache Disabling' CONFIG_DCACHE_DISABLED
+
+if [ "$CONFIG_SH_SIMULATOR" != "y" -a \
+     "$CONFIG_DCACHE_DISABLED" != "y" ]; then
+     choice 'DCache mode'                                 \
+         "Write-back             CONFIG_DCACHE_WRITE_BACK \
+          Write-through          CONFIG_DCACHE_WRITE_THROUGH" Write-back
+fi
+
+bool 'ICache Disabling' CONFIG_ICACHE_DISABLED
+
+#
+# CPU Subtype specific options (errata and such)
+#
+comment 'CPU Subtype specific options'
+if [ "$CONFIG_CPU_SUBTYPE_SH5_101" = "y" ]; then
+  bool "Include workaround for SH5-101 cut2 silicon defect ID2815" CONFIG_SH64_ID2815_WORKAROUND
+fi
+
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+
+define_bool CONFIG_ISA n
+define_bool CONFIG_SBUS n
+
+bool 'Networking support' CONFIG_NET
+
+bool 'PCI support' CONFIG_PCI
+if [ "$CONFIG_SH_SIMULATOR" = "y" ]; then
+  define_bool CONFIG_PCI n
+  define_bool CONFIG_NET n
+fi
+
+if [ "$CONFIG_SH_HARP" = "y" ]; then
+  define_bool CONFIG_PCI n
+  define_bool CONFIG_NET y
+  define_bool CONFIG_NET_PCI y
+fi
+
+if [ "$CONFIG_PCI" = "y" ]; then
+   choice '  PCI access mode' \
+	"BIOS		CONFIG_PCI_GOBIOS	\
+	 Direct		CONFIG_PCI_GODIRECT	\
+	 Any		CONFIG_PCI_GOANY"	Any
+   if [ "$CONFIG_PCI_GOBIOS" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+      define_bool CONFIG_PCI_BIOS y
+   fi
+   if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+      define_bool CONFIG_PCI_DIRECT y
+   fi
+fi
+
+source drivers/pci/Config.in
+
+# bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+# 
+define_bool CONFIG_HOTPLUG n
+
+if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+   source drivers/pcmcia/Config.in
+else
+   define_bool CONFIG_PCMCIA n
+fi
+
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+# bool 'Sysctl support' CONFIG_SYSCTL
+define_bool CONFIG_SYSCTL y
+
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+# source drivers/parport/Config.in
+
+endmenu
+
+# source drivers/mtd/Config.in
+
+source drivers/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+# mainmenu_option next_comment
+# comment 'ATA/IDE/MFM/RLL support'
+# 
+# tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+# 
+# if [ "$CONFIG_IDE" != "n" ]; then
+#   source drivers/ide/Config.in
+# else
+   define_bool CONFIG_BLK_DEV_IDE_MODES n
+   define_bool CONFIG_BLK_DEV_HD n
+# fi
+# endmenu
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+ tristate 'SCSI support' CONFIG_SCSI
+##define_bool CONFIG_SCSI n
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+   source drivers/scsi/Config.in
+fi
+endmenu
+
+# source drivers/ieee1394/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Network device support'
+
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" ]; then
+         source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
+fi
+
+#
+# input before char - char/joystick depends on it. As does USB.
+#
+source drivers/input/Config.in
+
+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
+
+
+# insert for SCIF serial console support 
+tristate 'Serial (SCI, SCIF) support' CONFIG_SH_SCI
+tristate 'Serial (8250, 16450, 16550 or compatible) support' CONFIG_SERIAL
+
+if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_SH_SCI" = "y" ]; then
+   bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE
+fi
+
+
+comment 'Unix 98 PTY support'
+bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
+if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
+   int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
+fi
+if [ "$CONFIG_PARPORT" != "n" ]; then
+   dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
+   if [ "$CONFIG_PRINTER" != "n" ]; then
+      bool '  Support for console on line printer' CONFIG_LP_CONSOLE
+   fi
+   dep_tristate 'Support for user-space parallel port device drivers' CONFIG_PPDEV $CONFIG_PARPORT
+fi
+
+bool 'Heartbeat LED' CONFIG_HEARTBEAT
+dep_bool 'Support for HDSP-253 LED' CONFIG_HDSP253_LED $CONFIG_SH_CAYMAN
+tristate 'DMA controller (DMAC) support' CONFIG_SH_DMA
+bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
+
+mainmenu_option next_comment
+comment 'Watchdog Cards'
+bool 'Watchdog Timer Support' CONFIG_WATCHDOG
+if [ "$CONFIG_WATCHDOG" != "n" ]; then
+   bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
+   dep_tristate '  SuperH Watchdog' CONFIG_SH_WDT $CONFIG_SUPERH
+fi
+endmenu
+
+endmenu
+
+if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
+   source drivers/char/pcmcia/Config.in
+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
+   bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+   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
+# define_bool CONFIG_SOUND n
+
+if [ "$CONFIG_SOUND" != "n" ]; then
+   source drivers/sound/Config.in
+fi
+endmenu
+
+source drivers/usb/Config.in
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+bool 'GDB Stub kernel debug' CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+bool "Debug: audit page tables on return from syscall/exception/interrupt" CONFIG_SH64_PAGE_TABLE_AUDIT
+dep_bool "Debug: report TLB fill/purge activity through /proc/tlb" CONFIG_SH64_PROC_TLB $CONFIG_PROC_FS
+
+endmenu
+
+source lib/Config.in
+source crypto/Config.in
+
diff -urN linux-2.4.22-pre2/arch/sh64/defconfig linux-2.4.22-pre3/arch/sh64/defconfig
--- linux-2.4.22-pre2/arch/sh64/defconfig	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/defconfig	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,467 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_SUPERH=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# System type
+#
+# CONFIG_SH_GENERIC is not set
+# CONFIG_SH_SIMULATOR is not set
+CONFIG_SH_CAYMAN=y
+# CONFIG_SH_HARP is not set
+
+#
+# Processor type and features
+#
+
+#
+# Processor options
+#
+CONFIG_CPU_SH5=y
+CONFIG_CPU_SUBTYPE_SH5_101=y
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+CONFIG_LITTLE_ENDIAN=y
+# CONFIG_BIG_ENDIAN is not set
+
+#
+# Memory options
+#
+CONFIG_MEMORY_SIZE_IN_MB=64
+CONFIG_CACHED_MEMORY_OFFSET=20000000
+CONFIG_UNCACHED_MEMORY_OFFSET=00000000
+CONFIG_MEMORY_START=80000000
+
+#
+# Cache options
+#
+# CONFIG_DCACHE_DISABLED is not set
+CONFIG_DCACHE_WRITE_BACK=y
+# CONFIG_DCACHE_WRITE_THROUGH is not set
+# CONFIG_ICACHE_DISABLED is not set
+
+#
+# CPU Subtype specific options
+#
+CONFIG_SH64_ID2815_WORKAROUND=y
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_STATS=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_STNIC is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_EEPRO100_PIO is not set
+# CONFIG_E100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_SUNDANCE_MMIO is not set
+# CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_SH_SCI=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+
+#
+# Unix 98 PTY support
+#
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+CONFIG_HEARTBEAT=y
+CONFIG_HDSP253_LED=y
+# CONFIG_PSMOUSE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_VIDEO_SELECT is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+CONFIG_FB_KYRO=y
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E1355 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_INTEL is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+# CONFIG_FBCON_CFB8 is not set
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set
+# CONFIG_SH64_PAGE_TABLE_AUDIT is not set
+# CONFIG_SH64_PROC_TLB is not set
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/Makefile linux-2.4.22-pre3/arch/sh64/kernel/Makefile
--- linux-2.4.22-pre2/arch/sh64/kernel/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/Makefile	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,40 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2000, 2001  Paolo Alberelli
+#
+# Makefile for the Linux SH-5 kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.o:
+	$(CC) $(CFLAGS) $(AFLAGS) -c $< -o $*.o
+
+O_TARGET := kernel.o
+
+obj-y   := process.o signal.o entry.o traps.o irq.o irq_intc.o \
+	    ptrace.o setup.o time.o sys_sh64.o semaphore.o sh_ksyms.o
+
+obj-$(CONFIG_HEARTBEAT)		+= led.o
+obj-$(CONFIG_PCI)		+= pci-dma.o pcibios.o
+
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_CPU_SH5)		+= pci_sh5.o
+endif
+
+obj-$(CONFIG_SH_DMA)		+= dma.o
+
+export-objs := sh_ksyms.o
+
+ifndef CONFIG_NOFPU_SUPPORT
+obj-y	+= fpu.o
+endif
+
+all: $(O_TARGET) head.o init_task.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/dma.c linux-2.4.22-pre3/arch/sh64/kernel/dma.c
--- linux-2.4.22-pre2/arch/sh64/kernel/dma.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/dma.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,293 @@
+/*
+ * arch/sh64/kernel/dma.c
+ *
+ * DMA routines for the SH-5 DMAC.
+ *
+ * Copyright (C) 2003  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */ 
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <asm/hardware.h>
+#include <asm/dma.h>
+#include <asm/signal.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+
+typedef struct {
+	unsigned long dev_addr;
+	unsigned long mem_addr;
+
+	unsigned int mode;
+	unsigned int count;
+} dma_info_t;
+
+static dma_info_t dma_info[MAX_DMA_CHANNELS];
+extern spinlock_t dma_spin_lock;
+
+/* arch/sh64/kernel/irq_intc.c */
+extern void make_intc_irq(unsigned int irq);
+
+/* DMAC Interrupts */
+#define DMA_IRQ_DMTE0	18
+#define DMA_IRQ_DERR	22
+
+#define DMAC_COMMON_BASE	(dmac_base + 0x08)
+#define DMAC_SAR_BASE		(dmac_base + 0x10)
+#define DMAC_DAR_BASE		(dmac_base + 0x18)
+#define DMAC_COUNT_BASE		(dmac_base + 0x20)
+#define DMAC_CTRL_BASE		(dmac_base + 0x28)
+#define DMAC_STATUS_BASE	(dmac_base + 0x30)
+
+#define DMAC_SAR(n)	(DMAC_SAR_BASE    + ((n) * 0x28))
+#define DMAC_DAR(n)	(DMAC_DAR_BASE    + ((n) * 0x28))
+#define DMAC_COUNT(n)	(DMAC_COUNT_BASE  + ((n) * 0x28))
+#define DMAC_CTRL(n)	(DMAC_CTRL_BASE   + ((n) * 0x28))
+#define DMAC_STATUS(n)	(DMAC_STATUS_BASE + ((n) * 0x28))
+
+/* DMAC.COMMON Bit Definitions */
+#define DMAC_COMMON_PR	0x00000001	/* Priority */
+					/* Bits 1-2 Reserved */
+#define DMAC_COMMON_ME	0x00000008	/* Master Enable */
+#define DMAC_COMMON_NMI	0x00000010	/* NMI Flag */
+					/* Bits 5-6 Reserved */
+#define DMAC_COMMON_ER	0x00000780	/* Error Response */
+#define DMAC_COMMON_AAE	0x00007800	/* Address Alignment Error */
+					/* Bits 15-63 Reserved */
+
+/* DMAC.SAR Bit Definitions */
+#define DMAC_SAR_ADDR	0xffffffff	/* Source Address */
+
+/* DMAC.DAR Bit Definitions */
+#define DMAC_DAR_ADDR	0xffffffff	/* Destination Address */
+
+/* DMAC.COUNT Bit Definitions */
+#define DMAC_COUNT_CNT	0xffffffff	/* Transfer Count */
+
+/* DMAC.CTRL Bit Definitions */
+#define DMAC_CTRL_TS	0x00000007	/* Transfer Size */
+#define DMAC_CTRL_SI	0x00000018	/* Source Increment */
+#define DMAC_CTRL_DI	0x00000060	/* Destination Increment */
+#define DMAC_CTRL_RS	0x00000780	/* Resource Select */
+#define DMAC_CTRL_IE	0x00000800	/* Interrupt Enable */
+#define DMAC_CTRL_TE	0x00001000	/* Transfer Enable */
+					/* Bits 15-63 Reserved */
+
+/* DMAC.STATUS Bit Definitions */
+#define DMAC_STATUS_TE	0x00000001	/* Transfer End */
+#define DMAC_STATUS_AAE	0x00000002	/* Address Alignment Error */
+					/* Bits 2-63 Reserved */
+
+static unsigned long dmac_base;
+
+void set_dma_count(unsigned int chan, unsigned int count);
+void set_dma_addr(unsigned int chan, unsigned int addr);
+
+static void dma_mte(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int chan = irq - DMA_IRQ_DMTE0;
+	dma_info_t *info = dma_info + chan;
+	u64 status;
+
+	if (info->mode & DMA_MODE_WRITE) {
+		sh64_out64(info->mem_addr & DMAC_SAR_ADDR, DMAC_SAR(chan));
+	} else {
+		sh64_out64(info->mem_addr & DMAC_DAR_ADDR, DMAC_DAR(chan));
+	}
+
+	set_dma_count(chan, info->count);
+
+	/* Clear the TE bit */
+	status = sh64_in64(DMAC_STATUS(chan));
+	status &= ~DMAC_STATUS_TE;
+	sh64_out64(status, DMAC_STATUS(chan));
+}
+
+static struct irqaction irq_dmte = {
+	.handler	= dma_mte,
+	.flags		= SA_INTERRUPT,
+	.name		= "DMA MTE",
+};
+
+static void dma_err(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u64 tmp;
+	u8 chan;
+
+	printk(KERN_NOTICE "DMAC: Got a DMA Error!\n");
+
+	tmp = sh64_in64(DMAC_COMMON_BASE);
+
+	/* Check for the type of error */
+	if ((chan = tmp & DMAC_COMMON_AAE)) {
+		/* It's an address alignment error.. */
+		printk(KERN_NOTICE "DMAC: Alignment error on channel %d, ", chan);
+
+		printk(KERN_NOTICE "SAR: 0x%08llx, DAR: 0x%08llx, COUNT: %lld\n",
+		       (sh64_in64(DMAC_SAR(chan)) & DMAC_SAR_ADDR),
+		       (sh64_in64(DMAC_DAR(chan)) & DMAC_DAR_ADDR),
+		       (sh64_in64(DMAC_COUNT(chan)) & DMAC_COUNT_CNT));
+
+	} else if ((chan = tmp & DMAC_COMMON_ER)) {
+		/* Something else went wrong.. */
+		printk(KERN_NOTICE "DMAC: Error on channel %d\n", chan);
+	}
+	
+	/* Reset the ME bit to clear the interrupt */
+	tmp |= DMAC_COMMON_ME;
+	sh64_out64(tmp, DMAC_COMMON_BASE);
+}
+
+static struct irqaction irq_derr = {
+	.handler	= dma_err,
+	.flags		= SA_INTERRUPT,
+	.name		= "DMA Error",
+};
+
+static inline unsigned long calc_xmit_shift(unsigned int chan)
+{
+	return sh64_in64(DMAC_CTRL(chan)) & 0x03;
+}
+
+void setup_dma(unsigned int chan, dma_info_t *info)
+{
+	unsigned int irq = DMA_IRQ_DMTE0 + chan;
+	dma_info_t *dma = dma_info + chan;
+
+	make_intc_irq(irq);
+	setup_irq(irq, &irq_dmte);
+	dma = info;
+}
+
+void enable_dma(unsigned int chan)
+{
+	u64 ctrl;
+
+	ctrl = sh64_in64(DMAC_CTRL(chan));
+	ctrl |= DMAC_CTRL_TE;
+	sh64_out64(ctrl, DMAC_CTRL(chan));
+}
+
+void disable_dma(unsigned int chan)
+{
+	u64 ctrl;
+
+	ctrl = sh64_in64(DMAC_CTRL(chan));
+	ctrl &= ~DMAC_CTRL_TE;
+	sh64_out64(ctrl, DMAC_CTRL(chan));
+}
+
+void set_dma_mode(unsigned int chan, char mode)
+{
+	dma_info_t *info = dma_info + chan;
+
+	info->mode = mode;
+
+	set_dma_addr(chan, info->mem_addr);
+	set_dma_count(chan, info->count);
+}
+
+void set_dma_addr(unsigned int chan, unsigned int addr)
+{
+	dma_info_t *info = dma_info + chan;
+	unsigned long sar, dar;
+
+	info->mem_addr = addr;
+	sar = (info->mode & DMA_MODE_WRITE) ? info->mem_addr : info->dev_addr;
+	dar = (info->mode & DMA_MODE_WRITE) ? info->dev_addr : info->mem_addr;
+
+	sh64_out64(sar & DMAC_SAR_ADDR, DMAC_SAR(chan));
+	sh64_out64(dar & DMAC_SAR_ADDR, DMAC_DAR(chan));
+}
+
+void set_dma_count(unsigned int chan, unsigned int count)
+{
+	dma_info_t *info = dma_info + chan;
+	u64 tmp;
+
+	info->count = count;
+
+	tmp = (info->count >> calc_xmit_shift(chan)) & DMAC_COUNT_CNT;
+
+	sh64_out64(tmp, DMAC_COUNT(chan));
+}
+
+unsigned long claim_dma_lock(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dma_spin_lock, flags);
+
+	return flags;
+}
+
+void release_dma_lock(unsigned long flags)
+{
+	spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+int get_dma_residue(unsigned int chan)
+{
+	return sh64_in64(DMAC_COUNT(chan) << calc_xmit_shift(chan));
+}
+
+int __init init_dma(void)
+{
+	struct vcr_info vcr;
+	u64 tmp;
+
+	/* Remap the DMAC */
+	dmac_base = onchip_remap(PHYS_DMAC_BLOCK, 1024, "DMAC");
+	if (!dmac_base) {
+		printk(KERN_ERR "Unable to remap DMAC\n");
+		return -ENOMEM;
+	}
+
+	/* Report DMAC.VCR Info */
+	vcr = sh64_get_vcr_info(dmac_base);
+	printk("DMAC: Module ID: 0x%04x, Module version: 0x%04x\n",
+	       vcr.mod_id, vcr.mod_vers);
+
+	/* Set the ME bit */
+	tmp = sh64_in64(DMAC_COMMON_BASE);
+	tmp |= DMAC_COMMON_ME; 
+	sh64_out64(tmp, DMAC_COMMON_BASE);
+
+	/* Enable the DMAC Error Interrupt */
+	make_intc_irq(DMA_IRQ_DERR);
+	setup_irq(DMA_IRQ_DERR, &irq_derr);
+
+	return 0;
+}
+
+static void __exit exit_dma(void)
+{
+	onchip_unmap(dmac_base);
+	free_irq(DMA_IRQ_DERR, 0);
+}
+
+module_init(init_dma);
+module_exit(exit_dma);
+
+MODULE_AUTHOR("Paul Mundt");
+MODULE_DESCRIPTION("DMA API for SH-5 DMAC");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(setup_dma);
+EXPORT_SYMBOL(claim_dma_lock);
+EXPORT_SYMBOL(release_dma_lock);
+EXPORT_SYMBOL(enable_dma);
+EXPORT_SYMBOL(disable_dma);
+EXPORT_SYMBOL(set_dma_mode);
+EXPORT_SYMBOL(set_dma_addr);
+EXPORT_SYMBOL(set_dma_count);
+EXPORT_SYMBOL(get_dma_residue);
+
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/entry.S linux-2.4.22-pre3/arch/sh64/kernel/entry.S
--- linux-2.4.22-pre2/arch/sh64/kernel/entry.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/entry.S	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,2111 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/entry.S
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sys.h>
+
+#include <asm/processor.h>
+#include <asm/registers.h>
+#include <asm/unistd.h>
+
+/*
+ * A few defines that ought to come from sched.h referring
+ * to the task structure. Byte offsets within the task
+ * structure and related flags.
+ */
+#define flags		4
+#define sigpending	8
+#define need_resched	20
+#define ptrace		24
+
+#define PT_TRACESYS	0x00000002
+
+
+/*
+ * SR fields.
+ */
+#define SR_ASID_MASK	0x00ff0000
+#define SR_FD_MASK	0x00008000
+#define SR_SS		0x08000000
+#define SR_BL		0x10000000
+#define SR_MD		0x40000000
+#define SR_MMU		0x80000000
+
+/*
+ * Event code.
+ */
+#define	EVENT_INTERRUPT		0
+#define	EVENT_FAULT_TLB		1
+#define	EVENT_FAULT_NOT_TLB	2
+#define	EVENT_DEBUG		3
+
+/* EXPEVT values */
+#define	RESET_CAUSE		0x20
+#define DEBUGSS_CAUSE		0x980
+
+/*
+ * Frame layout. Quad index.
+ */
+#define	FRAME_T(x)	FRAME_TBASE+(x*8)
+#define	FRAME_R(x)	FRAME_RBASE+(x*8)
+#define	FRAME_S(x)	FRAME_SBASE+(x*8)
+#define FSPC		0
+#define FSSR		1
+#define FSYSCALL_ID	2
+
+/* Arrange the save frame to be a multiple of 32 bytes long */
+#define FRAME_SBASE	0
+#define FRAME_RBASE	(FRAME_SBASE+(3*8))	/* SYSCALL_ID - SSR - SPC */
+#define FRAME_TBASE	(FRAME_RBASE+(63*8))	/* r0 - r62 */
+#define FRAME_PBASE	(FRAME_TBASE+(8*8))	/* t0 -t7 */
+#define	FRAME_SIZE	(FRAME_PBASE+(2*8))	/* pad0-pad1 */
+
+#define FP_FRAME_SIZE	FP_FRAME_BASE+(33*8)	/* dr0 - dr31 + fpscr */
+#define FP_FRAME_BASE	0
+
+#define	SAVED_R2	0*8
+#define	SAVED_R3	1*8
+#define	SAVED_R4	2*8
+#define	SAVED_R5	3*8
+#define	SAVED_R18	4*8
+#define	SAVED_R6	5*8
+#define	SAVED_T0	6*8
+
+/* These are the registers saved in the TLB path that aren't saved in the first
+   level of the normal one. */
+#define	TLB_SAVED_R25	7*8
+#define	TLB_SAVED_T1	8*8
+#define	TLB_SAVED_T2	9*8
+#define	TLB_SAVED_T3	10*8
+#define	TLB_SAVED_T4	11*8
+/* Save R0/R1 : PT-migrating compiler currently dishounours -ffixed-r0 and -ffixed-r1 causing
+   breakage otherwise. */
+#define	TLB_SAVED_R0	12*8
+#define	TLB_SAVED_R1	13*8
+
+#define STI()				\
+	getcon	SR, r6;			\
+	andi	r6, ~0xf0, r6;		\
+	putcon	r6, SR;
+
+	.section	.data, "aw"
+
+#define FAST_TLBMISS_STACK_CACHELINES 4
+#define FAST_TLBMISS_STACK_QUADWORDS (4*FAST_TLBMISS_STACK_CACHELINES)
+
+/* Register back-up area for all exceptions */
+	.balign	32
+	/* Allow for 16 quadwords to be pushed by fast tlbmiss handling
+	 * register saves etc. */
+	.fill FAST_TLBMISS_STACK_QUADWORDS, 8, 0x0
+/* This is 32 byte aligned by construction */
+/* Register back-up area for all exceptions */
+reg_save_area:
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.quad	0
+	.quad   0
+
+/* Save area for RESVEC exceptions. We cannot use reg_save_area because of
+ * reentrancy. Note this area may be accessed via physical address.
+ * Align so this fits a whole single cache line, for ease of purging.
+ */
+	.balign 32,0,32
+resvec_save_area:
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.balign 32,0,32
+
+/* Jump table of 3rd level handlers  */
+trap_jtable:
+	.long	do_exception_error		/* 0x000 */
+	.long	do_exception_error		/* 0x020 */
+	.long	tlb_miss_load				/* 0x040 */
+	.long	tlb_miss_store				/* 0x060 */
+	.long	do_exception_error		/* 0x080 */
+	.long	tlb_miss_load				/* 0x0A0 */
+	.long	tlb_miss_store				/* 0x0C0 */
+	.long	do_address_error_load	/* 0x0E0 */
+	.long	do_address_error_store	/* 0x100 */
+#ifndef CONFIG_NOFPU_SUPPORT
+	.long	do_fpu_error		/* 0x120 */
+#else
+	.long	do_exception_error		/* 0x120 */
+#endif
+	.long	do_exception_error		/* 0x140 */
+	.long	system_call				/* 0x160 */
+	.long	do_reserved_inst		/* 0x180 */
+	.long	do_illegal_slot_inst	/* 0x1A0 */
+	.long	do_NMI			/* 0x1C0 */
+	.long	do_exception_error		/* 0x1E0 */
+	.rept 15
+		.long do_IRQ		/* 0x200 - 0x3C0 */
+	.endr
+	.long	do_exception_error		/* 0x3E0 */
+	.rept 32
+		.long do_IRQ		/* 0x400 - 0x7E0 */
+	.endr
+	.long	fpu_error_or_IRQA			/* 0x800 */
+	.long	fpu_error_or_IRQB			/* 0x820 */
+	.long	do_IRQ			/* 0x840 */
+	.long	do_IRQ			/* 0x860 */
+	.rept 6
+		.long do_exception_error	/* 0x880 - 0x920 */
+	.endr
+	.long	do_software_break_point	/* 0x940 */
+	.long	do_exception_error		/* 0x960 */
+	.long	do_single_step		/* 0x980 */
+
+	.rept 3
+		.long do_exception_error	/* 0x9A0 - 0x9E0 */
+	.endr
+	.long	do_IRQ			/* 0xA00 */
+	.long	do_IRQ			/* 0xA20 */
+	.long	itlb_miss_or_IRQ			/* 0xA40 */
+	.long	do_IRQ			/* 0xA60 */
+	.long	do_IRQ			/* 0xA80 */
+	.long	itlb_miss_or_IRQ			/* 0xAA0 */
+	.long	do_exception_error		/* 0xAC0 */
+	.long	do_address_error_exec	/* 0xAE0 */
+	.rept 8
+		.long do_exception_error	/* 0xB00 - 0xBE0 */
+	.endr
+	.rept 18
+		.long do_IRQ		/* 0xC00 - 0xE20 */
+	.endr
+
+
+/* System calls jump table */
+
+.globl  sys_call_table
+sys_call_table:
+	.long sys_ni_syscall	/* 0  -  old "setup()" system call  */
+	.long sys_exit
+	.long sys_fork
+	.long sys_read
+	.long sys_write
+	.long sys_open		/* 5 */
+	.long sys_close
+	.long sys_waitpid
+	.long sys_creat
+	.long sys_link
+	.long sys_unlink		/* 10 */
+	.long sys_execve
+	.long sys_chdir
+	.long sys_time
+	.long sys_mknod
+	.long sys_chmod		/* 15 */
+	.long sys_lchown16
+	.long sys_ni_syscall	/* old break syscall holder */
+	.long sys_stat
+	.long sys_lseek
+	.long sys_getpid		/* 20 */
+	.long sys_mount
+	.long sys_oldumount
+	.long sys_setuid16
+	.long sys_getuid16
+	.long sys_stime		/* 25 */
+	.long sys_ptrace
+	.long sys_alarm
+	.long sys_fstat
+	.long sys_pause
+	.long sys_utime		/* 30 */
+	.long sys_ni_syscall	/* old stty syscall holder */
+	.long sys_ni_syscall	/* old gtty syscall holder */
+	.long sys_access
+	.long sys_nice
+	.long sys_ni_syscall	/* 35 */
+						/* old ftime syscall holder */
+	.long sys_sync
+	.long sys_kill
+	.long sys_rename
+	.long sys_mkdir
+	.long sys_rmdir		/* 40 */
+	.long sys_dup
+	.long sys_pipe
+	.long sys_times
+	.long sys_ni_syscall	/* old prof syscall holder */
+	.long sys_brk		/* 45 */
+	.long sys_setgid16
+	.long sys_getgid16
+	.long sys_signal
+	.long sys_geteuid16
+	.long sys_getegid16	/* 50 */
+	.long sys_acct
+	.long sys_umount		/* recycled never used phys( */
+	.long sys_ni_syscall	/* old lock syscall holder */
+	.long sys_ioctl
+	.long sys_fcntl		/* 55 */
+	.long sys_ni_syscall	/* old mpx syscall holder */
+	.long sys_setpgid
+	.long sys_ni_syscall	/* old ulimit syscall holder */
+	.long sys_ni_syscall	/* sys_olduname */
+	.long sys_umask		/* 60 */
+	.long sys_chroot
+	.long sys_ustat
+	.long sys_dup2
+	.long sys_getppid
+	.long sys_getpgrp		/* 65 */
+	.long sys_setsid
+	.long sys_sigaction
+	.long sys_sgetmask
+	.long sys_ssetmask
+	.long sys_setreuid16	/* 70 */
+	.long sys_setregid16
+	.long sys_sigsuspend
+	.long sys_sigpending
+	.long sys_sethostname
+	.long sys_setrlimit	/* 75 */
+	.long sys_old_getrlimit
+	.long sys_getrusage
+	.long sys_gettimeofday
+	.long sys_settimeofday
+	.long sys_getgroups16	/* 80 */
+	.long sys_setgroups16
+	.long sys_ni_syscall	/* sys_oldselect */
+	.long sys_symlink
+	.long sys_lstat
+	.long sys_readlink		/* 85 */
+	.long sys_uselib
+	.long sys_swapon
+	.long sys_reboot
+	.long old_readdir
+	.long old_mmap		/* 90 */
+	.long sys_munmap
+	.long sys_truncate
+	.long sys_ftruncate
+	.long sys_fchmod
+	.long sys_fchown16		/* 95 */
+	.long sys_getpriority
+	.long sys_setpriority
+	.long sys_ni_syscall	/* old profil syscall holder */
+	.long sys_statfs
+	.long sys_fstatfs		/* 100 */
+	.long sys_ni_syscall	/* ioperm */
+	.long sys_socketcall	/* Obsolete implementation of socket syscall */
+	.long sys_syslog
+	.long sys_setitimer
+	.long sys_getitimer	/* 105 */
+	.long sys_newstat
+	.long sys_newlstat
+	.long sys_newfstat
+	.long sys_uname
+	.long sys_ni_syscall	/* 110 */ /* iopl */
+	.long sys_vhangup
+	.long sys_ni_syscall	/* idle */
+	.long sys_ni_syscall	/* vm86old */
+	.long sys_wait4
+	.long sys_swapoff		/* 115 */
+	.long sys_sysinfo
+	.long sys_ipc		/* Obsolete ipc syscall implementation */
+	.long sys_fsync
+	.long sys_sigreturn
+	.long sys_clone		/* 120 */
+	.long sys_setdomainname
+	.long sys_newuname
+	.long sys_ni_syscall	/* sys_modify_ldt */
+	.long sys_adjtimex
+	.long sys_mprotect		/* 125 */
+	.long sys_sigprocmask
+	.long sys_create_module
+	.long sys_init_module
+	.long sys_delete_module
+	.long sys_get_kernel_syms	/* 130 */
+	.long sys_quotactl
+	.long sys_getpgid
+	.long sys_fchdir
+	.long sys_bdflush
+	.long sys_sysfs		/* 135 */
+	.long sys_personality
+	.long sys_ni_syscall	/* for afs_syscall */
+	.long sys_setfsuid16
+	.long sys_setfsgid16
+	.long sys_llseek		/* 140 */
+	.long sys_getdents
+	.long sys_select
+	.long sys_flock
+	.long sys_msync
+	.long sys_readv		/* 145 */
+	.long sys_writev
+	.long sys_getsid
+	.long sys_fdatasync
+	.long sys_sysctl
+	.long sys_mlock		/* 150 */
+	.long sys_munlock
+	.long sys_mlockall
+	.long sys_munlockall
+	.long sys_sched_setparam
+	.long sys_sched_getparam   	/* 155 */
+	.long sys_sched_setscheduler
+	.long sys_sched_getscheduler
+	.long sys_sched_yield
+	.long sys_sched_get_priority_max
+	.long sys_sched_get_priority_min  /* 160 */
+	.long sys_sched_rr_get_interval
+	.long sys_nanosleep
+	.long sys_mremap
+	.long sys_setresuid16
+	.long sys_getresuid16	/* 165 */
+	.long sys_ni_syscall	/* vm86 */
+	.long sys_query_module
+	.long sys_poll
+	.long sys_nfsservctl
+	.long sys_setresgid16	/* 170 */
+	.long sys_getresgid16
+	.long sys_prctl
+	.long sys_rt_sigreturn
+	.long sys_rt_sigaction
+	.long sys_rt_sigprocmask	/* 175 */
+	.long sys_rt_sigpending
+	.long sys_rt_sigtimedwait
+	.long sys_rt_sigqueueinfo
+	.long sys_rt_sigsuspend
+	.long sys_pread		/* 180 */
+	.long sys_pwrite
+	.long sys_chown16
+	.long sys_getcwd
+	.long sys_capget
+	.long sys_capset       	/* 185 */
+	.long sys_sigaltstack
+	.long sys_sendfile
+	.long sys_ni_syscall	/* streams1 */
+	.long sys_ni_syscall	/* streams2 */
+	.long sys_vfork        	/* 190 */
+	.long sys_getrlimit
+	.long sys_mmap2
+	.long sys_truncate64
+	.long sys_ftruncate64
+	.long sys_stat64		/* 195 */
+	.long sys_lstat64
+	.long sys_fstat64
+	.long sys_lchown
+	.long sys_getuid
+	.long sys_getgid		/* 200 */
+	.long sys_geteuid
+	.long sys_getegid
+	.long sys_setreuid
+	.long sys_setregid
+	.long sys_getgroups	/* 205 */
+	.long sys_setgroups
+	.long sys_fchown
+	.long sys_setresuid
+	.long sys_getresuid
+	.long sys_setresgid	/* 210 */
+	.long sys_getresgid
+	.long sys_chown
+	.long sys_setuid
+	.long sys_setgid
+	.long sys_setfsuid		/* 215 */
+	.long sys_setfsgid
+	.long sys_pivot_root
+	.long sys_mincore
+	.long sys_madvise
+	.long sys_socket		/* 220 */
+	.long sys_bind
+	.long sys_connect
+	.long sys_listen
+	.long sys_accept
+	.long sys_getsockname	/* 225 */
+	.long sys_getpeername
+	.long sys_socketpair
+	.long sys_send
+	.long sys_sendto
+	.long sys_recv		/* 230*/
+	.long sys_recvfrom
+	.long sys_shutdown
+	.long sys_setsockopt
+	.long sys_getsockopt
+	.long sys_sendmsg		/* 235 */
+	.long sys_recvmsg
+	.long sys_semop		/* New ipc syscall implementation */
+	.long sys_semget
+	.long sys_semctl
+	.long sys_msgsnd		/* 240 */
+	.long sys_msgrcv
+	.long sys_msgget
+	.long sys_msgctl
+	.long sys_shmatcall
+	.long sys_shmdt		/* 245 */
+	.long sys_shmget
+	.long sys_shmctl
+
+	/*
+	 * NOTE!! This doesn't have to be exact - we just have
+	 * to make sure we have _enough_ of the "sys_ni_syscall"
+	 * entries. Don't panic if you notice that this hasn't
+	 * been shrunk every time we add a new system call.
+	 */
+	.rept NR_syscalls-247
+		.long sys_ni_syscall
+	.endr
+
+	.section	.text64, "ax"
+
+/*
+ * --- Exception/Interrupt/Event Handling Section
+ */
+
+/*
+ * VBR and RESVEC blocks.
+ *
+ * First level handler for VBR-based exceptions.
+ *
+ * To avoid waste of space, align to the maximum text block size.
+ * This is assumed to be at most 128 bytes or 32 instructions.
+ * DO NOT EXCEED 32 instructions on the first level handlers !
+ *
+ * Also note that RESVEC is contained within the VBR block
+ * where the room left (1KB - TEXT_SIZE) allows placing
+ * the RESVEC block (at most 512B + TEXT_SIZE). 
+ * 
+ * So first (and only) level handler for RESVEC-based exceptions.
+ *
+ * Where the fault/interrupt is handled (not_a_tlb_miss, tlb_miss
+ * and interrupt) we are a lot tight with register space until
+ * saving onto the stack frame, which is done in handle_exception().
+ *
+ */
+
+#define	TEXT_SIZE 	128
+#define	BLOCK_SIZE 	1664 		/* Dynamic check, 13*128 */
+
+	.balign TEXT_SIZE
+LVBR_block:
+	.space	256, 0			/* Power-on class handler, */
+					/* not required here       */
+not_a_tlb_miss:
+	/* Save original stack pointer into KCR1 */
+	putcon	SP, KCR1
+
+	/* Save other original registers into reg_save_area */
+        _loada  reg_save_area, SP
+	st.q	SP, SAVED_R2, r2
+	st.q	SP, SAVED_R3, r3
+	st.q	SP, SAVED_R4, r4
+	st.q	SP, SAVED_R5, r5
+	st.q	SP, SAVED_R6, r6
+	st.q	SP, SAVED_R18, r18
+	gettr	t0, r3
+	st.q	SP, SAVED_T0, r3
+
+#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT
+	/* This use of DCR is not really legal, but there's nowhere else convenient to store this and it's only for last-resort debug anyway. */
+	movi    0x100, r3
+	putcon  r3, dcr
+#endif
+	
+	/* Set args for Non-debug, Not a TLB miss class handler */
+	getcon	EXPEVT, r2
+	_loada	ret_from_exception, r3
+	ori	r3, 1, r3
+	movi	EVENT_FAULT_NOT_TLB, r4
+	or	SP, ZERO, r5
+	getcon	KCR1, SP
+	_ptar	handle_exception, t0
+	blink	t0, ZERO
+
+	/*
+	 * Instead of the natural .balign 1024 place RESVEC here
+	 * respecting the final 1KB alignment.
+	 */
+	.balign TEXT_SIZE
+	/*
+	 * Instead of '.space 1024-TEXT_SIZE' place the RESVEC
+	 * block making sure the final alignment is correct.
+	 */
+LRESVEC_block:
+	/* Panic handler. Called with MMU off. Possible causes/actions:
+	 * - Reset:		Jump to program start.
+	 * - Single Step:	Turn off Single Step & return.
+	 * - Others:		Call panic handler, passing PC as arg.
+	 *			(this may need to be extended...)
+	 */
+reset_or_panic:
+	putcon	SP, DCR
+	/* First save r0-1 and tr0, as we need to use these */
+	_loada	resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP
+	st.q	SP, 0, r0
+	st.q	SP, 8, r1
+	gettr	t0, r0
+	st.q	SP, 32, r0
+	
+	/* Check cause */
+	getcon	EXPEVT, r0
+	movi	RESET_CAUSE, r1
+	sub	r1, r0, r1		/* r1=0 if reset */
+	_loada	_stext-CONFIG_CACHED_MEMORY_OFFSET, r0
+	ori	r0, 1, r0
+	ptabs	r0, t0
+	beqi	r1, 0, t0		/* Jump to start address if reset */
+
+	getcon	EXPEVT, r0
+	movi	DEBUGSS_CAUSE, r1
+	sub	r1, r0, r1		/* r1=0 if single step */
+	_ptar	single_step_panic, t0
+	beqi	r1, 0, t0		/* jump if single step */
+
+	/* If we get here, we have an unknown panic. Just call the panic
+	 * handler, passing saved PC. We never expect to return, so we can
+	 * use any regs now. */
+	getcon	SPC,r2
+	getcon	SSR,r3
+	getcon	EXPEVT,r4
+	/* Prepare to jump to C - physical address */
+	_loada	panic_handler-CONFIG_CACHED_MEMORY_OFFSET, r1
+	ori	r1, 1, r1
+	ptabs   r1, t0
+	getcon	DCR, SP
+	blink	t0, ZERO
+
+single_step_panic:
+	/* We are in a handler with Single Step set. We need to resume the
+	 * handler, by turning on MMU & turning off Single Step. */
+	getcon	SSR, r0
+	movi	SR_MMU, r1
+	or	r0, r1, r0
+	movi	~SR_SS, r1
+	and	r0, r1, r0
+	putcon	r0, SSR
+	/* Restore EXPEVT, as the rte won't do this */
+	getcon	PEXPEVT, r0
+	putcon	r0, EXPEVT
+	/* Restore regs */
+	ld.q	SP, 32, r0
+	ptabs	r0, tr0
+	ld.q	SP, 0, r0
+	ld.q	SP, 8, r1
+	getcon	DCR, SP
+	synco
+	rte
+
+	.balign	TEXT_SIZE
+debug_exception:
+	/*
+	 * Single step/software_break_point first level handler.
+	 * Called with MMU off, so the first thing we do is enable it
+	 * by doing an rte with appropriate SSR.
+	 */
+	putcon	SP, DCR
+	/* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */
+	_loada	resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP
+
+	/* With the MMU off, we are bypassing the cache, so purge any 
+         * data that will be made stale by the following stores.
+         */
+	ocbp	SP, 0
+	synco
+
+	st.q	SP, 0, r0
+	st.q	SP, 8, r1
+	getcon	SPC, r0
+	st.q	SP, 16, r0
+	getcon	SSR, r0
+	st.q	SP, 24, r0
+
+	/* Enable MMU, block exceptions, set priv mode, disable single step */
+	movi	SR_MMU | SR_BL | SR_MD, r1
+	or	r0, r1, r0
+	movi	~SR_SS, r1
+	and	r0, r1, r0
+	putcon	r0, SSR
+	/* Force control to debug_exception_2 when rte is executed */
+	_loada	debug_exeception_2, r0
+	ori	r0, 1, r0      /* force SHmedia, just in case */
+	putcon	r0, SPC
+	getcon	DCR, SP
+	synco
+	rte
+debug_exeception_2:
+	/* Restore saved regs */
+	putcon	SP, KCR1
+	_loada	resvec_save_area, SP
+	ld.q	SP, 24, r0
+	putcon	r0, SSR
+	ld.q	SP, 16, r0
+	putcon	r0, SPC
+	ld.q	SP, 0, r0
+	ld.q	SP, 8, r1
+
+	/* Save other original registers into reg_save_area */
+        _loada  reg_save_area, SP
+	st.q	SP, SAVED_R2, r2
+	st.q	SP, SAVED_R3, r3
+	st.q	SP, SAVED_R4, r4
+	st.q	SP, SAVED_R5, r5
+	st.q	SP, SAVED_R6, r6
+	st.q	SP, SAVED_R18, r18
+	gettr	t0, r3
+	st.q	SP, SAVED_T0, r3
+
+	/* Set args for debug class handler */
+	getcon	EXPEVT, r2
+	_loada	ret_from_exception, r3
+	ori	r3, 1, r3
+	movi	EVENT_DEBUG, r4
+	or	SP, ZERO, r5
+	getcon	KCR1, SP
+	_ptar	handle_exception, t0
+	blink	t0, ZERO
+
+	.balign	TEXT_SIZE
+debug_interrupt:
+	/*
+	 * Not supported. If we ever get here loop forever
+	 * We may be MMUOFF or MMUON. Just use pic code.
+	 */
+	_ptar	debug_interrupt, t0
+	blink	t0, ZERO
+	.balign	TEXT_SIZE
+
+LRESVEC_block_end:			/* Marker. Unused. */
+tlb_miss:
+	putcon	SP, KCR1
+	_loada	reg_save_area, SP
+	/* SP is guaranteed 32-byte aligned. */
+	st.q	SP, TLB_SAVED_R0 , r0
+	st.q	SP, TLB_SAVED_R1 , r1
+	st.q	SP, SAVED_R2 , r2
+	st.q	SP, SAVED_R3 , r3
+	st.q	SP, SAVED_R4 , r4
+	st.q	SP, SAVED_R5 , r5
+	st.q	SP, SAVED_R6 , r6
+	st.q	SP, SAVED_R18, r18
+
+	/* Save R25 for safety; as/ld may want to use it to achieve the call to
+	 * the code in mm/tlbmiss.c */
+	st.q	SP, TLB_SAVED_R25, r25
+	gettr	tr0, r2
+	gettr	tr1, r3
+	gettr	tr2, r4
+	gettr	tr3, r5
+	gettr	tr4, r18
+	st.q	SP, SAVED_T0 , r2
+	st.q	SP, TLB_SAVED_T1 , r3
+	st.q	SP, TLB_SAVED_T2 , r4
+	st.q	SP, TLB_SAVED_T3 , r5
+	st.q	SP, TLB_SAVED_T4 , r18
+
+	pt	do_fast_page_fault, tr0
+	getcon	SSR, r2
+	getcon	EXPEVT, r3
+	getcon	TEA, r4
+	shlri	r2, 30, r2
+	andi	r2, 1, r2	/* r2 = SSR.MD */
+	blink 	tr0, r18
+
+	pt	fixup_to_invoke_general_handler, tr1
+
+	/* If the fast path handler fixed the fault, just drop through quickly
+	   to the restore code right away to return to the excepting context.
+	   */
+	beqi/u	r2, 0, tr1
+
+fast_tlb_miss_restore:
+	ld.q	SP, SAVED_T0, r2
+	ld.q	SP, TLB_SAVED_T1, r3
+	ld.q	SP, TLB_SAVED_T2, r4
+
+	ld.q	SP, TLB_SAVED_T3, r5
+	ld.q	SP, TLB_SAVED_T4, r18
+
+	ptabs	r2, tr0
+	ptabs	r3, tr1
+	ptabs	r4, tr2
+	ptabs	r5, tr3
+	ptabs	r18, tr4
+
+	ld.q	SP, TLB_SAVED_R0, r0
+	ld.q	SP, TLB_SAVED_R1, r1
+	ld.q	SP, SAVED_R2, r2
+	ld.q	SP, SAVED_R3, r3
+	ld.q	SP, SAVED_R4, r4
+	ld.q	SP, SAVED_R5, r5
+	ld.q	SP, SAVED_R6, r6
+	ld.q	SP, SAVED_R18, r18
+	ld.q	SP, TLB_SAVED_R25, r25
+
+	getcon	KCR1, SP
+	rte
+	nop /* for safety, in case the code is run on sh5-101 cut1.x */
+
+fixup_to_invoke_general_handler:
+
+	/* OK, new method.  Restore stuff that's not expected to get saved into
+	   the 'first-level' reg save area, then just fall through to setting
+	   up the registers and calling the second-level handler. */
+
+	/* 2nd level expects r2,3,4,5,6,18,tr0 to be saved.  So we must restore
+	   r25,tr1-4 and save r6 to get into the right state.  */
+
+	ld.q	SP, TLB_SAVED_T1, r3
+	ld.q	SP, TLB_SAVED_T2, r4
+	ld.q	SP, TLB_SAVED_T3, r5
+	ld.q	SP, TLB_SAVED_T4, r18
+	ld.q	SP, TLB_SAVED_R25, r25
+	
+	ld.q	SP, TLB_SAVED_R0, r0
+	ld.q	SP, TLB_SAVED_R1, r1
+
+	ptabs/u	r3, tr1
+	ptabs/u	r4, tr2
+	ptabs/u	r5, tr3
+	ptabs/u	r18, tr4
+
+#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT
+	/* This use of DCR is not really legal, but there's nowhere else convenient to store this and it's only for last-resort debug anyway. */
+	movi    0x400, r3
+	putcon  r3, dcr
+#endif
+
+	/* Set args for Non-debug, TLB miss class handler */
+	getcon	EXPEVT, r2
+	_loada	ret_from_exception, r3
+	ori	r3, 1, r3
+	movi	EVENT_FAULT_TLB, r4
+	or	SP, ZERO, r5
+	getcon	KCR1, SP
+	_ptar	handle_exception, t0
+	blink	t0, ZERO
+
+/* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE
+   DOES END UP AT VBR+0x600 */
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+#if 0
+	.balign 256
+	nop
+#endif
+	.balign 256
+	/* VBR + 0x600 */
+
+interrupt:
+	/* Save original stack pointer into KCR1 */
+	putcon	SP, KCR1
+
+	/* Save other original registers into reg_save_area */
+        _loada  reg_save_area, SP
+	st.q	SP, SAVED_R2, r2
+	st.q	SP, SAVED_R3, r3
+	st.q	SP, SAVED_R4, r4
+	st.q	SP, SAVED_R5, r5
+	st.q	SP, SAVED_R6, r6
+	st.q	SP, SAVED_R18, r18
+	gettr	t0, r3
+	st.q	SP, SAVED_T0, r3
+
+#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT
+	/* This use of DCR is not really legal, but there's nowhere else convenient to store this and it's only for last-resort debug anyway. */
+	movi    0x600, r3
+	putcon  r3, dcr
+#endif
+
+	/* Set args for interrupt class handler */
+	getcon	INTEVT, r2
+	_loada	ret_from_irq, r3
+	ori	r3, 1, r3
+	movi	EVENT_INTERRUPT, r4
+	or	SP, ZERO, r5
+	getcon	KCR1, SP
+	_ptar	handle_exception, t0
+	blink	t0, ZERO
+	.balign	TEXT_SIZE		/* let's waste the bare minimum */
+
+LVBR_block_end:				/* Marker. Used for total checking */
+	
+
+/*
+ * Second level handler for VBR-based exceptions. Pre-handler.
+ * In common to all stack-frame sensitive handlers.
+ *
+ * Inputs:
+ * (KCR0) Current [current task union]
+ * (KCR1) Original SP
+ * (r2)   INTEVT/EXPEVT
+ * (r3)   appropriate return address
+ * (r4)   Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault, 3=debug)
+ * (r5)   Pointer to reg_save_area
+ * (SP)   Original SP
+ *
+ * Available registers:
+ * (r6)
+ * (r18)
+ * (t0)
+ *
+ */
+handle_exception:
+	/* Common 2nd level handler. */
+
+	/* First thing we need an appropriate stack pointer */
+	getcon	SSR, r6
+	shlri	r6, 30, r6
+	andi	r6, 1, r6
+	_ptar	stack_ok, t0
+	bne	r6, ZERO, t0		/* Original stack pointer is fine */
+
+	/* Set stack pointer for user fault */
+	getcon	KCR0, SP
+	movi	THREAD_SIZE, r6		/* Point to the end */
+	add	SP, r6, SP
+
+stack_ok:
+	/* Make some room for the BASIC frame. */
+	movi	-(FRAME_SIZE), r6
+	add	SP, r6, SP
+
+/* Could do this with no stalling if we had another spare register, but the
+   code below will be OK. */
+	ld.q	r5, SAVED_R2, r6
+	ld.q	r5, SAVED_R3, r18
+	st.q	SP, FRAME_R(2), r6
+	ld.q	r5, SAVED_R4, r6
+	st.q	SP, FRAME_R(3), r18
+	ld.q	r5, SAVED_R5, r18
+	st.q	SP, FRAME_R(4), r6
+	ld.q	r5, SAVED_R6, r6
+	st.q	SP, FRAME_R(5), r18
+	ld.q	r5, SAVED_R18, r18
+	st.q	SP, FRAME_R(6), r6
+	ld.q	r5, SAVED_T0, r6
+	st.q	SP, FRAME_R(18), r18
+	st.q	SP, FRAME_T(0), r6
+
+	/* Keep old SP around */
+	getcon	KCR1, r6
+
+	/* Save the rest of the general purpose registers */
+	st.q	SP, FRAME_R(0), r0
+	st.q	SP, FRAME_R(1), r1
+	st.q	SP, FRAME_R(7), r7
+	st.q	SP, FRAME_R(8), r8
+	st.q	SP, FRAME_R(9), r9
+	st.q	SP, FRAME_R(10), r10
+	st.q	SP, FRAME_R(11), r11
+	st.q	SP, FRAME_R(12), r12
+	st.q	SP, FRAME_R(13), r13
+	st.q	SP, FRAME_R(14), r14
+
+	/* SP is somewhere else */
+	st.q	SP, FRAME_R(15), r6
+
+	st.q	SP, FRAME_R(16), r16
+	st.q	SP, FRAME_R(17), r17
+	/* r18 is saved earlier. */
+	st.q	SP, FRAME_R(19), r19
+	st.q	SP, FRAME_R(20), r20
+	st.q	SP, FRAME_R(21), r21
+	st.q	SP, FRAME_R(22), r22
+	st.q	SP, FRAME_R(23), r23
+	st.q	SP, FRAME_R(24), r24
+	st.q	SP, FRAME_R(25), r25
+	st.q	SP, FRAME_R(26), r26
+	st.q	SP, FRAME_R(27), r27
+	st.q	SP, FRAME_R(28), r28
+	st.q	SP, FRAME_R(29), r29
+	st.q	SP, FRAME_R(30), r30
+	st.q	SP, FRAME_R(31), r31
+	st.q	SP, FRAME_R(32), r32
+	st.q	SP, FRAME_R(33), r33
+	st.q	SP, FRAME_R(34), r34
+	st.q	SP, FRAME_R(35), r35
+	st.q	SP, FRAME_R(36), r36
+	st.q	SP, FRAME_R(37), r37
+	st.q	SP, FRAME_R(38), r38
+	st.q	SP, FRAME_R(39), r39
+	st.q	SP, FRAME_R(40), r40
+	st.q	SP, FRAME_R(41), r41
+	st.q	SP, FRAME_R(42), r42
+	st.q	SP, FRAME_R(43), r43
+	st.q	SP, FRAME_R(44), r44
+	st.q	SP, FRAME_R(45), r45
+	st.q	SP, FRAME_R(46), r46
+	st.q	SP, FRAME_R(47), r47
+	st.q	SP, FRAME_R(48), r48
+	st.q	SP, FRAME_R(49), r49
+	st.q	SP, FRAME_R(50), r50
+	st.q	SP, FRAME_R(51), r51
+	st.q	SP, FRAME_R(52), r52
+	st.q	SP, FRAME_R(53), r53
+	st.q	SP, FRAME_R(54), r54
+	st.q	SP, FRAME_R(55), r55
+	st.q	SP, FRAME_R(56), r56
+	st.q	SP, FRAME_R(57), r57
+	st.q	SP, FRAME_R(58), r58
+	st.q	SP, FRAME_R(59), r59
+	st.q	SP, FRAME_R(60), r60
+	st.q	SP, FRAME_R(61), r61
+	st.q	SP, FRAME_R(62), r62
+
+	/*
+	 * Save the S* registers.
+	 */
+	getcon	SSR, r61
+	st.q	SP, FRAME_S(FSSR), r61
+	getcon	SPC, r62
+	st.q	SP, FRAME_S(FSPC), r62
+	movi	-1, r62			/* Reset syscall_nr */
+	st.q	SP, FRAME_S(FSYSCALL_ID), r62
+
+	/* Save the rest of the target registers */
+	gettr	t1, r6
+	st.q	SP, FRAME_T(1), r6
+	gettr	t2, r6
+	st.q	SP, FRAME_T(2), r6
+	gettr	t3, r6
+	st.q	SP, FRAME_T(3), r6
+	gettr	t4, r6
+	st.q	SP, FRAME_T(4), r6
+	gettr	t5, r6
+	st.q	SP, FRAME_T(5), r6
+	gettr	t6, r6
+	st.q	SP, FRAME_T(6), r6
+	gettr	t7, r6
+	st.q	SP, FRAME_T(7), r6
+
+/*#define POOR_MANS_STRACE 1*/
+	
+#ifdef POOR_MANS_STRACE
+	/* We've pushed all the registers now, so only r2-r4 hold anything
+	 * useful. Move them into callee save registers */
+	or	r2, ZERO, r28
+	or	r3, ZERO, r29
+	or	r4, ZERO, r30
+
+	/* Preserve r2 as the event code */
+	_loada	evt_debug, r3
+	ori	r3, 1, r3
+	ptabs	r3, t0
+
+	/* or	SP, ZERO, r5 */
+	getcon	TRA, r5
+	blink	t0, LINK
+
+	or	r28, ZERO, r2
+	or	r29, ZERO, r3
+	or	r30, ZERO, r4
+#endif
+
+	
+	/* For syscall and debug race condition, get TRA now */
+	getcon	TRA, r5
+	
+	/* We are in a safe position to turn SR.BL off, but set IMASK=0xf
+	 * Also set FD, to catch FPU usage in the kernel.
+	 *
+	 * benedict.gaster@superh.com 29/07/2002
+	 *
+	 * On all SH5-101 revisions it is unsafe to raise the IMASK and at the 
+	 * same time change BL from 1->0, as any pending interrupt of a level
+	 * higher than he previous value of IMASK will leak through and be 
+	 * taken unexpectedly.
+	 *
+	 * To avoid this we raise the IMASK and then issue another PUTCON to
+	 * enable interrupts.
+         */
+	getcon	SR, r6
+	movi	SR_IMASK | SR_FD, r7
+	or	r6, r7, r6
+	putcon	r6, SR
+	movi	SR_UNBLOCK_EXC, r7
+	and	r6, r7, r6
+	putcon	r6, SR
+
+	
+	/* Now call the appropriate 3rd level handler */
+	or	r3, ZERO, LINK
+	_loada	trap_jtable, r3
+	shlri	r2, 3, r2
+	ldx.l	r2, r3, r3
+	shlri	r2, 2, r2
+	ptabs	r3, t0
+	or	SP, ZERO, r3
+	blink	t0, ZERO
+
+/*
+ * Second level handler for VBR-based exceptions. Post-handlers.
+ *
+ * Post-handlers for interrupts (ret_from_irq), exceptions
+ * (ret_from_exception) and common reentrance doors (restore_all
+ * to get back to the original context, ret_from_syscall loop to
+ * check kernel exiting).
+ *
+ * ret_with_reschedule and check_signals are an inner lables of
+ * the ret_from_syscall loop.
+ *
+ * In common to all stack-frame sensitive handlers.
+ *
+ * Inputs:
+ * (SP)   struct pt_regs *, original register's frame pointer (basic)
+ *
+ */
+ret_from_irq:
+	ld.q	SP, FRAME_S(FSSR), r6
+	shlri	r6, 30, r6
+	andi	r6, 1, r6
+	_ptar	restore_all, t0
+	bne	r6, ZERO, t0		/* no further checks */
+	STI()
+	_ptar	ret_with_reschedule, t0
+	blink	t0, ZERO		/* Do not check softirqs */
+	
+ret_from_exception:
+	ld.q	SP, FRAME_S(FSSR), r6
+	shlri	r6, 30, r6
+	andi	r6, 1, r6
+	_ptar	restore_all, t0
+	bne	r6, ZERO, t0		/* no further checks */
+
+	/* Check softirqs */
+
+	/*
+	 * Fall-through:
+	 * _ptar   ret_from_syscall, t0
+	 * blink   t0, ZERO
+	 */
+
+ret_from_syscall:
+	
+ret_with_reschedule:
+	getcon	KCR0, r6
+	ld.l	r6, need_resched, r7
+	_ptar	check_signals, t0
+	beq	r7, ZERO, t0
+
+	_ptar	ret_from_syscall, t0
+	gettr	t0, LINK
+	_loada	schedule, r6
+	ptabs	r6, t0
+	blink	t0, ZERO		/* Call schedule(), return on top */
+
+check_signals:
+	getcon	KCR0, r6
+	ld.l	r6, sigpending, r7
+	_ptar	restore_all, t0
+	beq	r7, ZERO, t0
+
+	_loada	do_signal, r6
+	ptabs	r6, t0
+	or	SP, ZERO, r2
+	or	ZERO, ZERO, r3
+	blink	t0, LINK	    /* Call do_signal(regs, 0), return here */
+	
+#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT
+	/* Check page tables before returning (with obvious performance penalty). */
+	_loada  audit_mm, r6
+	ptabs   r6, t0
+	getcon  expevt, r2
+	getcon  intevt, r3
+	getcon  tra, r4
+	getcon  dcr, r5
+	blink   t0, LINK
+#endif
+
+restore_all:
+	/* Do prefetches */
+	
+	ld.q	SP, FRAME_T(0), r6
+	ld.q	SP, FRAME_T(1), r7
+	ld.q	SP, FRAME_T(2), r8
+	ld.q	SP, FRAME_T(3), r9
+	ptabs	r6, t0
+	ptabs	r7, t1
+	ptabs	r8, t2
+	ptabs	r9, t3
+	ld.q	SP, FRAME_T(4), r6
+	ld.q	SP, FRAME_T(5), r7
+	ld.q	SP, FRAME_T(6), r8
+	ld.q	SP, FRAME_T(7), r9
+	ptabs	r6, t4
+	ptabs	r7, t5
+	ptabs	r8, t6
+	ptabs	r9, t7
+
+	ld.q	SP, FRAME_R(0), r0
+	ld.q	SP, FRAME_R(1), r1
+	ld.q	SP, FRAME_R(2), r2
+	ld.q	SP, FRAME_R(3), r3
+	ld.q	SP, FRAME_R(4), r4
+	ld.q	SP, FRAME_R(5), r5
+	ld.q	SP, FRAME_R(6), r6
+	ld.q	SP, FRAME_R(7), r7
+	ld.q	SP, FRAME_R(8), r8
+	ld.q	SP, FRAME_R(9), r9
+	ld.q	SP, FRAME_R(10), r10
+	ld.q	SP, FRAME_R(11), r11
+	ld.q	SP, FRAME_R(12), r12
+	ld.q	SP, FRAME_R(13), r13
+	ld.q	SP, FRAME_R(14), r14
+
+	ld.q	SP, FRAME_R(16), r16
+	ld.q	SP, FRAME_R(17), r17
+	ld.q	SP, FRAME_R(18), r18
+	ld.q	SP, FRAME_R(19), r19
+	ld.q	SP, FRAME_R(20), r20
+	ld.q	SP, FRAME_R(21), r21
+	ld.q	SP, FRAME_R(22), r22
+	ld.q	SP, FRAME_R(23), r23
+	ld.q	SP, FRAME_R(24), r24
+	ld.q	SP, FRAME_R(25), r25
+	ld.q	SP, FRAME_R(26), r26
+	ld.q	SP, FRAME_R(27), r27
+	ld.q	SP, FRAME_R(28), r28
+	ld.q	SP, FRAME_R(29), r29
+	ld.q	SP, FRAME_R(30), r30
+	ld.q	SP, FRAME_R(31), r31
+	ld.q	SP, FRAME_R(32), r32
+	ld.q	SP, FRAME_R(33), r33
+	ld.q	SP, FRAME_R(34), r34
+	ld.q	SP, FRAME_R(35), r35
+	ld.q	SP, FRAME_R(36), r36
+	ld.q	SP, FRAME_R(37), r37
+	ld.q	SP, FRAME_R(38), r38
+	ld.q	SP, FRAME_R(39), r39
+	ld.q	SP, FRAME_R(40), r40
+	ld.q	SP, FRAME_R(41), r41
+	ld.q	SP, FRAME_R(42), r42
+	ld.q	SP, FRAME_R(43), r43
+	ld.q	SP, FRAME_R(44), r44
+	ld.q	SP, FRAME_R(45), r45
+	ld.q	SP, FRAME_R(46), r46
+	ld.q	SP, FRAME_R(47), r47
+	ld.q	SP, FRAME_R(48), r48
+	ld.q	SP, FRAME_R(49), r49
+	ld.q	SP, FRAME_R(50), r50
+	ld.q	SP, FRAME_R(51), r51
+	ld.q	SP, FRAME_R(52), r52
+	ld.q	SP, FRAME_R(53), r53
+	ld.q	SP, FRAME_R(54), r54
+	ld.q	SP, FRAME_R(55), r55
+	ld.q	SP, FRAME_R(56), r56
+	ld.q	SP, FRAME_R(57), r57
+	ld.q	SP, FRAME_R(58), r58
+
+	getcon	SR, r59
+	movi	SR_BLOCK_EXC, r60
+	or	r59, r60, r59
+	putcon	r59, SR			/* SR.BL = 1, keep nesting out */
+	ld.q	SP, FRAME_S(FSSR), r61
+	ld.q	SP, FRAME_S(FSPC), r62
+	movi	SR_ASID_MASK, r60
+	and	r59, r60, r59
+	andc	r61, r60, r61		/* Clear out older ASID */
+	or	r59, r61, r61		/* Retain current ASID */
+	putcon	r61, SSR
+	putcon	r62, SPC
+
+	/* Ignore FSYSCALL_ID */
+
+	ld.q	SP, FRAME_R(59), r59
+	ld.q	SP, FRAME_R(60), r60
+	ld.q	SP, FRAME_R(61), r61
+	ld.q	SP, FRAME_R(62), r62
+
+	/* Last touch */
+	ld.q	SP, FRAME_R(15), SP
+	rte
+	nop
+
+/*
+ * Third level handlers for VBR-based exceptions. Adapting args to
+ * and/or deflecting to fourth level handlers.
+ *
+ * Fourth level handlers interface.
+ * Most are C-coded handlers directly pointed by the trap_jtable.
+ * (Third = Fourth level)
+ * Inputs:
+ * (r2)   fault/interrupt code, entry number (e.g. NMI = 14,
+ *	  IRL0-3 (0000) = 16, RTLBMISS = 2, SYSCALL = 11, etc ...)
+ * (r3)   struct pt_regs *, original register's frame pointer
+ * (r4)   Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault)
+ * (r5)   TRA control register (for syscall/debug benefit only)
+ * (LINK) return address
+ * (SP)   = r3
+ *
+ * Kernel TLB fault handlers will get a slightly different interface.
+ * (r2)   struct pt_regs *, original register's frame pointer
+ * (r3)   writeaccess, whether it's a store fault as opposed to load fault
+ * (r4)   execaccess, whether it's a ITLB fault as opposed to DTLB fault
+ * (r5)   Effective Address of fault
+ * (LINK) return address
+ * (SP)   = r2
+ *
+ * fpu_error_or_IRQ? is a helper to deflect to the right cause.
+ *
+ */
+tlb_miss_load:
+	or	SP, ZERO, r2
+	or	ZERO, ZERO, r3		/* Read */
+	or	ZERO, ZERO, r4		/* Data */
+	getcon	TEA, r5
+	_ptar	call_do_page_fault, t0
+	beq	ZERO, ZERO, tr0
+
+tlb_miss_store:
+	or	SP, ZERO, r2
+	movi	1, r3			/* Write */
+	or	ZERO, ZERO, r4		/* Data */
+	getcon	TEA, r5
+	_ptar	call_do_page_fault, t0
+	beq	ZERO, ZERO, tr0
+
+itlb_miss_or_IRQ:
+	_ptar	its_IRQ, t0
+	beqi/u	r4, EVENT_INTERRUPT, t0
+	or	SP, ZERO, r2
+	or	ZERO, ZERO, r3		/* Read */
+	movi	1, r4			/* Text */
+	getcon	TEA, r5
+	/* Fall through */
+
+call_do_page_fault:
+	_loada	do_page_fault, r6
+        ptabs	r6, t0
+        blink	t0, ZERO	
+	
+fpu_error_or_IRQA:
+	_ptar	its_IRQ, t0
+	beqi/l	r4, EVENT_INTERRUPT, t0
+#ifndef CONFIG_NOFPU_SUPPORT 
+	_loada	do_fpu_state_restore, r6
+#else
+	_loada	do_exception_error, r6
+#endif
+	ptabs	r6, t0
+	blink	t0, ZERO
+
+fpu_error_or_IRQB:
+	_ptar	its_IRQ, t0
+	beqi/l	r4, EVENT_INTERRUPT, t0
+#ifndef CONFIG_NOFPU_SUPPORT
+	_loada	do_fpu_state_restore, r6
+#else
+	_loada	do_exception_error, r6
+#endif
+	ptabs	r6, t0
+	blink	t0, ZERO
+
+its_IRQ:
+	_loada	do_IRQ, r6
+	ptabs	r6, t0
+	blink	t0, ZERO
+
+/*
+ * system_call/unknown_trap third level handler:
+ * 
+ * Inputs:
+ * (r2)   fault/interrupt code, entry number (TRAP = 11)
+ * (r3)   struct pt_regs *, original register's frame pointer
+ * (r4)   Not used. Event (0=interrupt, 1=TLB miss fault, 2=Not TLB miss fault)
+ * (r5)   TRA Control Reg (0x00xyzzzz: x=1 SYSCALL, y = #args, z=nr)
+ * (SP)   = r3
+ * (LINK) return address: ret_from_exception
+ * (*r3)  Syscall parms: SC#, arg0, arg1, ..., arg5 in order (Saved r2/r7)
+ *
+ * Outputs:
+ * (*r3)  Syscall reply (Saved r2)
+ * (LINK) In case of syscall only it can be scrapped.
+ *        Common second level post handler will be ret_from_syscall.
+ *        Common (non-trace) exit point to that is syscall_ret (saving
+ *        result to r2). Common bad exit point is syscall_bad (returning
+ *        ENOSYS then saved to r2).
+ *
+ */
+
+unknown_trap:
+	/* Unknown Trap or User Trace */
+	_loada	do_unknown_trapa, r6
+	ptabs	r6, t0
+        ld.q    r3, FRAME_R(9), r2	/* r2 = #arg << 16 | syscall # */
+        andi    r2, 0x1ff, r2		/* r2 = syscall # */
+	blink	t0, LINK
+
+	_ptar	syscall_ret, t0
+	blink	t0, ZERO
+
+        /* New syscall implementation*/
+system_call:
+	_ptar	unknown_trap, t0
+        or      r5, ZERO, r4            /* TRA (=r5) -> r4 */
+        shlri   r4, 20, r4
+	bnei	r4, 1, t0		/* unknown_trap if not 0x1yzzzz */
+
+        /* It's a system call */
+	st.q    r3, FRAME_S(FSYSCALL_ID), r5 	/* ID (0x1yzzzz) -> stack */
+	andi    r5, 0x1ff, r5			/* syscall # -> r5	  */
+
+	STI()
+
+	_ptar	syscall_allowed, t0
+	movi	NR_syscalls - 1, r4	/* Last valid */
+	bgeu/l	r4, r5, t0
+
+syscall_bad:
+	/* Return ENOSYS ! */
+	movi	-(ENOSYS), r2		/* Fall-through */
+syscall_ret:
+	st.q	SP, FRAME_R(9), r2	/* Expecting SP back to BASIC frame */
+
+#ifdef POOR_MANS_STRACE
+	/* nothing useful in registers at this point */
+
+	_loada	evt_debug2, r5
+	ori	r5, 1, r5
+	ptabs	r5, t0
+	ld.q	SP, FRAME_R(9), r2
+	or	SP, ZERO, r3
+	blink	t0, LINK
+#endif
+	
+	ld.q	SP, FRAME_S(FSPC), r2
+	addi	r2, 4, r2		/* Move PC, being pre-execution event */
+	st.q	SP, FRAME_S(FSPC), r2
+	_ptar	ret_from_syscall, t0
+	blink	t0, ZERO
+
+
+/*  A different return path for ret_from_fork, because we now need 
+ *  to call schedule_tail with the later kernels. Because prev is
+ *  loaded into r2 by switch_to() means we can just call it straight  away
+ */
+	
+.global	ret_from_fork
+ret_from_fork:
+
+	_loada	schedule_tail,r5
+	ori	r5, 1, r5
+	ptabs	r5, t0
+	blink	t0, LINK
+	
+#ifdef POOR_MANS_STRACE
+	/* nothing useful in registers at this point */
+
+	_loada	evt_debug2, r5
+	ori	r5, 1, r5
+	ptabs	r5, t0
+	ld.q	SP, FRAME_R(9), r2
+	or	SP, ZERO, r3
+	blink	t0, LINK
+#endif
+	
+	ld.q	SP, FRAME_S(FSPC), r2
+	addi	r2, 4, r2		/* Move PC, being pre-execution event */
+	st.q	SP, FRAME_S(FSPC), r2
+	_ptar	ret_from_syscall, t0
+	blink	t0, ZERO
+	
+	
+		
+syscall_allowed:
+	/* Use LINK to deflect the exit point, default is syscall_ret */
+	_ptar	syscall_ret, t0
+	gettr	t0, LINK
+	_ptar	syscall_notrace, t0
+
+	getcon	KCR0, r2
+	ld.l	r2, ptrace, r4
+	andi	r4, PT_TRACESYS, r4
+	beq/l	r4, ZERO, t0
+
+	/* Trace it by calling syscall_trace before and after */
+	_loada	syscall_trace, r4
+	ptabs	r4, t0
+	blink	t0, LINK
+	/* Reload syscall number as r5 is trashed by syscall_trace */
+	ld.q	SP, FRAME_S(FSYSCALL_ID), r5
+	andi	r5, 0x1ff, r5
+
+	_ptar	syscall_ret_trace, t0
+	gettr	t0, LINK
+
+syscall_notrace:
+	/* Now point to the appropriate 4th level syscall handler */
+	_loada	sys_call_table, r4
+	shlli	r5, 2, r5
+	ldx.l	r4, r5, r5
+	ptabs	r5, t0
+
+	/* Prepare original args */
+	ld.q	SP, FRAME_R(2), r2
+	ld.q	SP, FRAME_R(3), r3
+	ld.q	SP, FRAME_R(4), r4
+	ld.q	SP, FRAME_R(5), r5
+	ld.q	SP, FRAME_R(6), r6
+	ld.q	SP, FRAME_R(7), r7
+
+	/* And now the trick for those syscalls requiring regs * ! */
+	or	SP, ZERO, r8
+
+	/* Call it */
+	blink	t0, ZERO	/* LINK is already properly set */
+
+syscall_ret_trace:
+	/* We get back here only if under trace */
+	st.q	SP, FRAME_R(9), r2	/* Save return value */
+
+	/*  ... usage of a pt relative (_ptar _syscall_trace) fails on CDC */
+	_loada	syscall_trace, LINK
+	ptabs	LINK, t0
+	blink	t0, LINK
+
+	/* This needs to be done after any syscall tracing */
+	ld.q	SP, FRAME_S(FSPC), r2
+	addi	r2, 4, r2	/* Move PC, being pre-execution event */
+	st.q	SP, FRAME_S(FSPC), r2
+
+	_ptar	ret_from_syscall, t0
+	blink	t0, ZERO		/* Resume normal return sequence */
+
+/*
+ * --- Switch to running under a particular ASID and return the previous ASID value
+ * --- The caller is assumed to have done a cli before calling this.
+ *
+ * Input r2 : new ASID
+ * Output r2 : old ASID
+ */
+
+	.global switch_and_save_asid
+switch_and_save_asid:
+	getcon	sr, r0
+	movi	255, r4
+	shlli 	r4, 16, r4	/* r4 = mask to select ASID */
+	and	r0, r4, r3	/* r3 = shifted old ASID */
+	andi	r2, 255, r2	/* mask down new ASID */
+	shlli	r2, 16, r2	/* align new ASID against SR.ASID */
+	andc	r0, r4, r0	/* efface old ASID from SR */
+	or	r0, r2, r0	/* insert the new ASID */
+	putcon	r0, ssr
+	_loada	1f, r0
+	putcon	r0, spc
+	rte
+	nop
+1:
+	ptabs	r18, tr0
+	shlri	r3, 16, r2	/* r2 = old ASID */
+	blink tr0, r63
+
+	.global	route_to_panic_handler
+route_to_panic_handler:
+	/* Switch to real mode, goto panic_handler, don't return.  Useful for
+	   last-chance debugging, e.g. if no output wants to go to the console.
+	   */
+
+	_loada	panic_handler - CONFIG_CACHED_MEMORY_OFFSET, r1
+	ptabs	r1, tr0
+	pta	1f, tr1
+	gettr	tr1, r0
+	putcon	r0, spc
+	getcon	sr, r0
+	movi	1, r1
+	shlli	r1, 31, r1
+	andc	r0, r1, r0
+	putcon	r0, ssr
+	rte
+	nop
+1:	/* Now in real mode */
+	blink tr0, r63
+	nop
+
+	.global peek_real_address_q
+peek_real_address_q:
+	/* Two args:
+	   r2 : real mode address to peek
+	   r2(out) : result quadword
+
+	   This is provided as a cheapskate way of manipulating device
+	   registers for debugging (to avoid the need to onchip_remap the debug
+	   module, and to avoid the need to onchip_remap the watchpoint
+	   controller in a way that identity maps sufficient bits to avoid the
+	   SH5-101 cut2 silicon defect).
+
+	   This code is not performance critical
+	*/
+
+	add.l	r2, r63, r2	/* sign extend address */
+	getcon	sr, r0		/* r0 = saved original SR */
+	movi	1, r1
+	shlli	r1, 28, r1
+	or	r0, r1, r1	/* r0 with block bit set */
+	putcon	r1, sr		/* now in critical section */
+	movi	1, r36
+	shlli	r36, 31, r36
+	andc	r1, r36, r1	/* turn sr.mmu off in real mode section */
+
+	putcon	r1, ssr
+	_loada	.peek0 - CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */
+	_loada	1f, r37		/* virtual mode return addr */
+	putcon	r36, spc
+
+	synco
+	rte
+	nop
+
+.peek0:	/* come here in real mode, don't touch caches!!
+           still in critical section (sr.bl==1) */
+	putcon	r0, ssr
+	putcon	r37, spc
+	/* Here's the actual peek.  If the address is bad, all bets are now off
+	 * what will happen (handlers invoked in real-mode = bad news) */
+	ld.q	r2, 0, r2
+	synco
+	rte	/* Back to virtual mode */
+	nop
+
+1:
+	ptabs	r18, tr0
+	blink	tr0, r63
+
+	.global poke_real_address_q
+poke_real_address_q:
+	/* Two args:
+	   r2 : real mode address to poke
+	   r3 : quadword value to write.
+
+	   This is provided as a cheapskate way of manipulating device
+	   registers for debugging (to avoid the need to onchip_remap the debug
+	   module, and to avoid the need to onchip_remap the watchpoint
+	   controller in a way that identity maps sufficient bits to avoid the
+	   SH5-101 cut2 silicon defect).
+
+	   This code is not performance critical
+	*/
+
+	add.l	r2, r63, r2	/* sign extend address */
+	getcon	sr, r0		/* r0 = saved original SR */
+	movi	1, r1
+	shlli	r1, 28, r1
+	or	r0, r1, r1	/* r0 with block bit set */
+	putcon	r1, sr		/* now in critical section */
+	movi	1, r36
+	shlli	r36, 31, r36
+	andc	r1, r36, r1	/* turn sr.mmu off in real mode section */
+
+	/* Bodge : force sr.watch high on return.  Can't understand why else this
+	   isn't happening. */
+	movi	1, r38
+	shlli	r38, 26, r38
+	or	r38, r0, r0
+
+	putcon	r1, ssr
+	_loada	.poke0-CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */
+	_loada	1f, r37		/* virtual mode return addr */
+	putcon	r36, spc
+
+	synco
+	rte
+	nop
+
+.poke0:	/* come here in real mode, don't touch caches!!
+           still in critical section (sr.bl==1) */
+	putcon	r0, ssr
+	putcon	r37, spc
+	/* Here's the actual poke.  If the address is bad, all bets are now off
+	 * what will happen (handlers invoked in real-mode = bad news) */
+	st.q	r2, 0, r3
+	synco
+	rte	/* Back to virtual mode */
+	nop
+
+1:
+	ptabs	r18, tr0
+	blink	tr0, r63
+
+/*
+ * --- User Access Handling Section
+ */
+
+/*
+ * User Access support. It all moved to non inlined Assembler
+ * functions in here.
+ *
+ * __kernel_size_t __copy_user(void *__to, const void *__from,
+ *			       __kernel_size_t __n)
+ *
+ * Inputs:
+ * (r2)  target address
+ * (r3)  source address
+ * (r4)  size in bytes
+ *
+ * Ouputs:
+ * (*r2) target data
+ * (r2)  non-copied bytes
+ *
+ * If a fault occurs on the user pointer, bail out early and return the
+ * number of bytes not copied in r2.
+ * Strategy : for large blocks, call a real memcpy function which can
+ * move >1 byte at a time using unaligned ld/st instructions, and can
+ * manipulate the cache using prefetch + alloco to improve the speed
+ * further.  If a fault occurs in that function, just revert to the
+ * byte-by-byte approach used for small blocks; this is rare so the
+ * performance hit for that case does not matter.
+ *
+ * For small blocks it's not worth the overhead of setting up and calling
+ * the memcpy routine; do the copy a byte at a time.
+ *
+ */
+	.global	__copy_user
+__copy_user:
+	_ptar	__copy_user_byte_by_byte, t1
+	movi	16, r0 ! this value is a best guess, should tune it by benchmarking
+	bge/u	r0, r4, t1
+	_ptar copy_user_memcpy, t0
+	addi	r15, -32, r15
+	/* Save arguments in case we have to fix-up unhandled page fault */
+	st.q	r15, 0, r2
+	st.q	r15, 8, r3
+	st.q	r15, 16, r4
+	st.q	r15, 24, r35 ! r35 is callee-save
+	/* Save LINK in a register to reduce RTS time later (otherwise
+	   ld r15,*,LINK;ptabs LINK;trn;blink trn,r63 becomes a critical path) */
+	ori	LINK, 0, r35
+	blink	t0, LINK
+
+	/* Copy completed normally if we get back here */
+	ptabs	r35, tr0
+	ld.q	r15, 24, r35
+	/* don't restore r2-r4, pointless */
+	/* set result=r2 to zero as the copy must have succeeded. */
+	or	r63, r63, r2
+	addi	r15, 32, r15
+	blink	tr0, r63 ! RTS
+
+	.global __copy_user_fixup
+__copy_user_fixup:
+	/* Restore stack frame */
+	ori	r35, 0, LINK
+	ld.q	r15, 24, r35
+	ld.q	r15, 16, r4
+	ld.q	r15,  8, r3
+	ld.q	r15,  0, r2
+	addi	r15, 32, r15
+	/* Fall through to original code, in the 'same' state we entered with */
+
+/* The slow byte-by-byte method is used if the fast copy traps due to a bad
+   user address.  In that rare case, the speed drop can be tolerated. */
+__copy_user_byte_by_byte:
+	_ptar	___copy_user_exit, t1
+	_ptar	___copy_user1, t0
+	beq/u	r4, r63, t1	/* early exit for zero length copy */
+	sub	r2, r3, r0
+	addi	r0, -1, r0
+
+___copy_user1:
+	ld.b	r3, 0, r5		/* Fault address 1 */
+
+	/* Could rewrite this to use just 1 add, but the second comes 'free'
+	   due to load latency */
+	addi	r3, 1, r3
+	addi	r4, -1, r4		/* No real fixup required */
+___copy_user2:
+	stx.b	r3, r0, r5		/* Fault address 2 */
+	bne     r4, ZERO, t0
+
+___copy_user_exit:
+	or	r4, ZERO, r2
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+/*
+ * __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
+ *
+ * Inputs:
+ * (r2)  target address
+ * (r3)  size in bytes
+ *
+ * Ouputs:
+ * (*r2) zero-ed target data
+ * (r2)  non-zero-ed bytes
+ */
+	.global	__clear_user
+__clear_user:
+	_ptar	___clear_user_exit, t1
+	_ptar	___clear_user1, t0
+	beq/u	r3, r63, t1
+
+___clear_user1:
+	st.b	r2, 0, ZERO		/* Fault address */
+	addi	r2, 1, r2
+	addi	r3, -1, r3		/* No real fixup required */
+	bne     r3, ZERO, t0
+
+___clear_user_exit:
+	or	r3, ZERO, r2
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+/*
+ * int __strncpy_from_user(unsigned long __dest, unsigned long __src,
+ *			   int __count)
+ *
+ * Inputs:
+ * (r2)  target address
+ * (r3)  source address
+ * (r4)  maximum size in bytes
+ *
+ * Ouputs:
+ * (*r2) copied data
+ * (r2)  -EFAULT (in case of faulting)
+ *       copied data (otherwise)
+ */
+	.global	__strncpy_from_user
+__strncpy_from_user:
+	_ptar	___strncpy_from_user1, t0
+	_ptar	___strncpy_from_user_done, t1
+	or	r4, ZERO, r5		/* r5 = original count */
+	beq/u	r4, r63, t1		/* early exit if r4==0 */
+	movi	-(EFAULT), r6		/* r6 = reply, no real fixup */
+	or	ZERO, ZERO, r7		/* r7 = data, clear top byte of data */
+
+___strncpy_from_user1:
+	ld.b	r3, 0, r7		/* Fault address: only in reading */
+	st.b	r2, 0, r7
+	addi	r2, 1, r2
+	addi	r3, 1, r3
+	beq/u	ZERO, r7, t1
+	addi	r4, -1, r4		/* return real number of copied bytes */
+	bne/l	ZERO, r4, t0
+
+___strncpy_from_user_done:
+	sub	r5, r4, r6		/* If done, return copied */
+	
+___strncpy_from_user_exit:
+	or	r6, ZERO, r2
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+/*
+ * extern long __strnlen_user(const char *__s, long __n)
+ *
+ * Inputs:
+ * (r2)  source address
+ * (r3)  source size in bytes
+ *
+ * Ouputs:
+ * (r2)  -EFAULT (in case of faulting)
+ *       string length (otherwise)
+ */
+	.global	__strnlen_user
+__strnlen_user:
+	_ptar	___strnlen_user_set_reply, t0
+	_ptar	___strnlen_user1, t1
+	or	ZERO, ZERO, r5		/* r5 = counter */
+	movi	-(EFAULT), r6		/* r6 = reply, no real fixup */
+	or	ZERO, ZERO, r7		/* r7 = data, clear top byte of data */
+	beq	r3, ZERO, t0
+
+___strnlen_user1:
+	ldx.b	r2, r5, r7		/* Fault address: only in reading */
+	addi	r3, -1, r3		/* No real fixup */
+	addi	r5, 1, r5
+	beq	r3, ZERO, t0
+	bne	r7, ZERO, t1
+! The line below used to be active.  This meant led to a junk byte lying between each pair
+! of entries in the argv & envp structures in memory.  Whilst the program saw the right data
+! via the argv and envp arguments to main, it meant the 'flat' representation visible through
+! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example.
+!	addi	r5, 1, r5		/* Include '\0' */
+
+___strnlen_user_set_reply:
+	or	r5, ZERO, r6		/* If done, return counter */
+	
+___strnlen_user_exit:
+	or	r6, ZERO, r2
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+/*
+ * extern long __get_user_asm_?(void *val, long addr)
+ *
+ * Inputs:
+ * (r2)  dest address
+ * (r3)  source address (in User Space)
+ *
+ * Ouputs:
+ * (r2)  -EFAULT (faulting)
+ *       0 	 (not faulting)
+ */
+	.global	__get_user_asm_b
+__get_user_asm_b:
+	or	r2, ZERO, r4
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___get_user_asm_b1:
+	ld.b	r3, 0, r5		/* r5 = data */
+	st.b	r4, 0, r5
+	or	ZERO, ZERO, r2
+	
+___get_user_asm_b_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__get_user_asm_w
+__get_user_asm_w:
+	or	r2, ZERO, r4
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___get_user_asm_w1:
+	ld.w	r3, 0, r5		/* r5 = data */
+	st.w	r4, 0, r5
+	or	ZERO, ZERO, r2
+	
+___get_user_asm_w_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__get_user_asm_l
+__get_user_asm_l:
+	or	r2, ZERO, r4
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___get_user_asm_l1:
+	ld.l	r3, 0, r5		/* r5 = data */
+	st.l	r4, 0, r5
+	or	ZERO, ZERO, r2
+	
+___get_user_asm_l_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__get_user_asm_q
+__get_user_asm_q:
+	or	r2, ZERO, r4
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___get_user_asm_q1:
+	ld.q	r3, 0, r5		/* r5 = data */
+	st.q	r4, 0, r5
+	or	ZERO, ZERO, r2
+	
+___get_user_asm_q_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+/*
+ * extern long __put_user_asm_?(void *pval, long addr)
+ *
+ * Inputs:
+ * (r2)  kernel pointer to value
+ * (r3)  dest address (in User Space)
+ *
+ * Ouputs:
+ * (r2)  -EFAULT (faulting)
+ *       0 	 (not faulting)
+ */
+	.global	__put_user_asm_b
+__put_user_asm_b:
+	ld.b	r2, 0, r4		/* r4 = data */
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___put_user_asm_b1:
+	st.b	r3, 0, r4
+	or	ZERO, ZERO, r2
+	
+___put_user_asm_b_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__put_user_asm_w
+__put_user_asm_w:
+	ld.w	r2, 0, r4		/* r4 = data */
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___put_user_asm_w1:
+	st.w	r3, 0, r4
+	or	ZERO, ZERO, r2
+	
+___put_user_asm_w_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__put_user_asm_l
+__put_user_asm_l:
+	ld.l	r2, 0, r4		/* r4 = data */
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___put_user_asm_l1:
+	st.l	r3, 0, r4
+	or	ZERO, ZERO, r2
+	
+___put_user_asm_l_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__put_user_asm_q
+__put_user_asm_q:
+	ld.q	r2, 0, r4		/* r4 = data */
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___put_user_asm_q1:
+	st.q	r3, 0, r4
+	or	ZERO, ZERO, r2
+	
+___put_user_asm_q_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+/*
+ * --- Signal Handling Section
+ */
+
+/*
+ * extern long long _sa_default_rt_restorer
+ * extern long long _sa_default_restorer
+ *
+ *		 or, better,
+ *
+ * extern void _sa_default_rt_restorer(void)
+ * extern void _sa_default_restorer(void)
+ *
+ * Code prototypes to do a sys_rt_sigreturn() or sys_sysreturn()
+ * from user space. Copied into user space by signal management.
+ * Both must be quad aligned and 2 quad long (4 instructions).
+ *
+ */
+	.balign 8
+	.global sa_default_rt_restorer
+sa_default_rt_restorer:
+	movi	0x10, r9
+	shori	__NR_rt_sigreturn, r9
+	trapa	r9
+	nop
+	
+	.balign 8
+	.global sa_default_restorer
+sa_default_restorer:
+	movi	0x10, r9
+	shori	__NR_sigreturn, r9
+	trapa	r9
+	nop
+	
+/*
+ * --- __ex_table Section
+ */
+
+/*
+ * User Access Exception Table.
+ */
+	.section	__ex_table,  "a"
+
+	.global asm_uaccess_start	/* Just a marker */
+asm_uaccess_start:
+
+	.long	___copy_user1, ___copy_user_exit
+	.long	___copy_user2, ___copy_user_exit
+	.long	___clear_user1, ___clear_user_exit
+	.long	___strncpy_from_user1, ___strncpy_from_user_exit
+	.long	___strnlen_user1, ___strnlen_user_exit
+	.long	___get_user_asm_b1, ___get_user_asm_b_exit
+	.long	___get_user_asm_w1, ___get_user_asm_w_exit
+	.long	___get_user_asm_l1, ___get_user_asm_l_exit
+	.long	___get_user_asm_q1, ___get_user_asm_q_exit
+	.long	___put_user_asm_b1, ___put_user_asm_b_exit
+	.long	___put_user_asm_w1, ___put_user_asm_w_exit
+	.long	___put_user_asm_l1, ___put_user_asm_l_exit
+	.long	___put_user_asm_q1, ___put_user_asm_q_exit
+
+	.global asm_uaccess_end		/* Just a marker */
+asm_uaccess_end:
+	
+
+
+
+/*
+ * --- .text.init Section
+ */
+
+	.section	.text.init, "ax"
+
+/*
+ * void trap_init (void)
+ *
+ */
+	.global	trap_init
+trap_init:
+	addi	SP, -24, SP			/* Room to save r28/r29/r30 */
+	st.q	SP, 0, r28
+	st.q	SP, 8, r29
+	st.q	SP, 16, r30
+
+	/* Set VBR and RESVEC */
+	_loada	LVBR_block, r19
+	andi	r19, -4, r19			/* reset MMUOFF + reserved */
+	/* For RESVEC exceptions we force the MMU off, which means we need the
+	   physical address. */
+	_loada	LRESVEC_block-CONFIG_CACHED_MEMORY_OFFSET, r20
+	andi	r20, -4, r20			/* reset reserved */
+	ori	r20, 1, r20			/* set MMUOFF */
+	putcon	r19, VBR
+	putcon	r20, RESVEC
+
+	/* Sanity check */
+	_loada	LVBR_block_end, r21
+	andi	r21, -4, r21
+	movi	BLOCK_SIZE, r29			/* r29 = expected size */
+	or	r19, ZERO, r30
+	add	r19, r29, r19
+
+	/*
+	 * Ugly, but better loop forever now than crash afterwards.
+	 * We should print a message, but if we touch LVBR or
+	 * LRESVEC blocks we should not be surprised if we get stuck
+	 * in trap_init().
+	 */
+	_ptar	trap_init_loop, t1
+	gettr	t1, r28				/* r28 = trap_init_loop */
+	sub	r21, r30, r30			/* r30 = actual size */
+
+	/*
+	 * VBR/RESVEC handlers overlap by being bigger than
+	 * allowed. Very bad. Just loop forever.
+	 * (r28) panic/loop address
+	 * (r29) expected size
+	 * (r30) actual size
+	 */
+trap_init_loop:
+	bne	r19, r21, t1
+
+	/* Now that exception vectors are set up reset SR.BL */
+	getcon 	SR, r22
+	movi	SR_UNBLOCK_EXC, r23
+	and	r22, r23, r22
+	putcon	r22, SR
+
+	addi	SP, 24, SP
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/fpu.c linux-2.4.22-pre3/arch/sh64/kernel/fpu.c
--- linux-2.4.22-pre2/arch/sh64/kernel/fpu.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/fpu.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,171 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/fpu.c
+ *
+ * Copyright (C) 2001  Manuela Cirronis, Paolo Alberelli
+ *
+ * Started from SH4 version:
+ *   Copyright (C) 1999, 2000  Kaz Kojima & Niibe Yutaka
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <asm/processor.h>
+#include <asm/user.h>
+#include <asm/io.h>
+
+/*
+ * Initially load the FPU with signalling NANS.  This bit pattern
+ * has the property that no matter whether considered as single or as
+ * double precision, it still represents a signalling NAN.  
+ */
+#define sNAN64		0xFFFFFFFFFFFFFFFF
+
+static struct sh_fpu_hard_struct init_fpuregs = {
+	{ [0 ... 31] = sNAN64 },
+	FPSCR_INIT
+};
+
+inline void fpsave(struct sh_fpu_hard_struct *fpregs)
+{
+	asm volatile("fst.d     %0, (0*8),"  __d(0)  "\n\t"
+		     "fst.d     %0, (1*8),"  __d(2)  "\n\t"
+		     "fst.d     %0, (2*8),"  __d(4)  "\n\t"
+		     "fst.d     %0, (3*8),"  __d(6)  "\n\t"
+		     "fst.d     %0, (4*8),"  __d(8)  "\n\t"
+		     "fst.d     %0, (5*8),"  __d(10) "\n\t"
+		     "fst.d     %0, (6*8),"  __d(12) "\n\t"
+		     "fst.d     %0, (7*8),"  __d(14) "\n\t"
+		     "fst.d     %0, (8*8),"  __d(16) "\n\t"
+		     "fst.d     %0, (9*8),"  __d(18) "\n\t"
+		     "fst.d     %0, (10*8)," __d(20) "\n\t"
+		     "fst.d     %0, (11*8)," __d(22) "\n\t"
+		     "fst.d     %0, (12*8)," __d(24) "\n\t"
+		     "fst.d     %0, (13*8)," __d(26) "\n\t"
+		     "fst.d     %0, (14*8)," __d(28) "\n\t"
+		     "fst.d     %0, (15*8)," __d(30) "\n\t"
+		     "fst.d     %0, (16*8)," __d(32) "\n\t"
+		     "fst.d     %0, (17*8)," __d(34) "\n\t"
+		     "fst.d     %0, (18*8)," __d(36) "\n\t"
+		     "fst.d     %0, (19*8)," __d(38) "\n\t"
+		     "fst.d     %0, (20*8)," __d(40) "\n\t"
+		     "fst.d     %0, (21*8)," __d(42) "\n\t"
+		     "fst.d     %0, (22*8)," __d(44) "\n\t"
+		     "fst.d     %0, (23*8)," __d(46) "\n\t"
+		     "fst.d     %0, (24*8)," __d(48) "\n\t"
+		     "fst.d     %0, (25*8)," __d(50) "\n\t"
+		     "fst.d     %0, (26*8)," __d(52) "\n\t"
+		     "fst.d     %0, (27*8)," __d(54) "\n\t"
+		     "fst.d     %0, (28*8)," __d(56) "\n\t"
+		     "fst.d     %0, (29*8)," __d(58) "\n\t"
+		     "fst.d     %0, (30*8)," __d(60) "\n\t"
+		     "fst.d     %0, (31*8)," __d(62) "\n\t"
+
+		     "_fgetscr  " __f(63) 	     "\n\t"
+		     "fst.s     %0, (32*8)," __f(63) "\n\t"
+		: /* no output */
+		: "r" (fpregs)
+		: "memory");
+}
+
+
+static inline void
+fpload(struct sh_fpu_hard_struct *fpregs)
+{
+	asm volatile("fld.d     %0, (0*8),"  __d(0)  "\n\t"
+		     "fld.d     %0, (1*8),"  __d(2)  "\n\t"
+		     "fld.d     %0, (2*8),"  __d(4)  "\n\t"
+		     "fld.d     %0, (3*8),"  __d(6)  "\n\t"
+		     "fld.d     %0, (4*8),"  __d(8)  "\n\t"
+		     "fld.d     %0, (5*8),"  __d(10) "\n\t"
+		     "fld.d     %0, (6*8),"  __d(12) "\n\t"
+		     "fld.d     %0, (7*8),"  __d(14) "\n\t"
+		     "fld.d     %0, (8*8),"  __d(16) "\n\t"
+		     "fld.d     %0, (9*8),"  __d(18) "\n\t"
+		     "fld.d     %0, (10*8)," __d(20) "\n\t"
+		     "fld.d     %0, (11*8)," __d(22) "\n\t"
+		     "fld.d     %0, (12*8)," __d(24) "\n\t"
+		     "fld.d     %0, (13*8)," __d(26) "\n\t"
+		     "fld.d     %0, (14*8)," __d(28) "\n\t"
+		     "fld.d     %0, (15*8)," __d(30) "\n\t"
+		     "fld.d     %0, (16*8)," __d(32) "\n\t"
+		     "fld.d     %0, (17*8)," __d(34) "\n\t"
+		     "fld.d     %0, (18*8)," __d(36) "\n\t"
+		     "fld.d     %0, (19*8)," __d(38) "\n\t"
+		     "fld.d     %0, (20*8)," __d(40) "\n\t"
+		     "fld.d     %0, (21*8)," __d(42) "\n\t"
+		     "fld.d     %0, (22*8)," __d(44) "\n\t"
+		     "fld.d     %0, (23*8)," __d(46) "\n\t"
+		     "fld.d     %0, (24*8)," __d(48) "\n\t"
+		     "fld.d     %0, (25*8)," __d(50) "\n\t"
+		     "fld.d     %0, (26*8)," __d(52) "\n\t"
+		     "fld.d     %0, (27*8)," __d(54) "\n\t"
+		     "fld.d     %0, (28*8)," __d(56) "\n\t"
+		     "fld.d     %0, (29*8)," __d(58) "\n\t"
+		     "fld.d     %0, (30*8)," __d(60) "\n\t"
+
+		     "fld.s     %0, (32*8)," __f(63) "\n\t"
+		     "_fputscr  " __f(63) 	     "\n\t"
+
+	     	     "fld.d     %0, (31*8)," __d(62) "\n\t"
+		: /* no output */
+		: "r" (fpregs) );
+}
+
+void fpinit(struct sh_fpu_hard_struct *fpregs)
+{
+	*fpregs = init_fpuregs;
+}
+
+asmlinkage void
+do_fpu_error(unsigned long ex, struct pt_regs *regs)
+{
+	struct task_struct *tsk = current;
+
+	regs->pc += 4;
+
+	tsk->thread.trap_no = 11;
+	tsk->thread.error_code = 0;
+	force_sig(SIGFPE, tsk);
+}
+
+
+asmlinkage void
+do_fpu_state_restore(unsigned long ex, struct pt_regs *regs)
+{
+	void die(const char * str, struct pt_regs * regs, long err);
+
+#if 0
+printk("do_fpu_state_restore (pid %d, used_math %d, last_used_math pid %d)\n",
+       current->pid, current->used_math,
+       last_task_used_math ? last_task_used_math->pid : -1);
+#endif
+
+	if (! user_mode(regs))
+		die("FPU used in kernel", regs, ex);
+
+	regs->sr &= ~SR_FD;
+
+	if (last_task_used_math == current)
+		return;
+
+	grab_fpu();
+	if (last_task_used_math != NULL) {
+		/* Other processes fpu state, save away */
+		fpsave(&last_task_used_math->thread.fpu.hard);
+        }
+        last_task_used_math = current;
+        if (current->used_math) {
+                fpload(&current->thread.fpu.hard);
+        } else {
+		/* First time FPU user.  */
+		fpload(&init_fpuregs);
+                current->used_math = 1;
+        }
+	release_fpu();
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/head.S linux-2.4.22-pre3/arch/sh64/kernel/head.S
--- linux-2.4.22-pre2/arch/sh64/kernel/head.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/head.S	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,347 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh5/kernel/head.S
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ *
+ * benedict.gaster@superh.com:	 2nd May 2002
+ *    Moved definition of empty_zero_page to its own section allowing
+ *    it to be placed at an absolute address known at load time.
+ *
+ * lethal@linux-sh.org:          9th May 2003
+ *    Kill off GLOBAL_NAME() usage.
+ */
+
+#include <linux/config.h>
+
+#include <asm/page.h>
+#include <asm/mmu_context.h>
+#include <asm/cache.h>
+#include <asm/tlb.h>
+#include <asm/processor.h>
+#include <asm/registers.h>
+
+/*
+ * MMU defines: TLB boundaries.
+ */
+
+#define MMUIR_FIRST	ITLB_FIXED	
+#define MMUIR_END	ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP
+#define MMUIR_STEP	TLB_STEP
+
+#define MMUDR_FIRST	DTLB_FIXED
+#define MMUDR_END	DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP
+#define MMUDR_STEP	TLB_STEP
+
+/*
+ * MMU defines: Fixed TLBs.
+ */
+#define MMUIR_TEXT_H	0x0000000000000003 | (CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START)
+			/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
+
+#define MMUIR_TEXT_L	0x000000000000009a | (CONFIG_MEMORY_START)
+			/* 512 Mb, Cacheable, Write-back, execute, Not User, Ph. Add. */
+
+#define MMUDR_CACHED_H	0x0000000000000003 | (CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START)
+			/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
+#define MMUDR_CACHED_L	0x000000000000015a | (CONFIG_MEMORY_START)
+			/* 512 Mb, Cacheable, Write-back, read/write, Not User, Ph. Add. */
+
+#ifdef CONFIG_ICACHE_DISABLED
+#define	ICCR0_INIT_VAL	ICCR0_OFF			/* ICACHE off */
+#else
+#define	ICCR0_INIT_VAL	ICCR0_ON | ICCR0_ICI		/* ICE + ICI */
+#endif
+#define	ICCR1_INIT_VAL	ICCR1_NOLOCK			/* No locking */
+
+#if defined (CONFIG_DCACHE_DISABLED)
+#define	OCCR0_INIT_VAL	OCCR0_OFF			   /* D-cache: off  */
+#elif defined (CONFIG_DCACHE_WRITE_THROUGH)
+#define	OCCR0_INIT_VAL	OCCR0_ON | OCCR0_OCI | OCCR0_WT	   /* D-cache: on,   */
+							   /* WT, invalidate */
+#elif defined (CONFIG_DCACHE_WRITE_BACK)
+#define	OCCR0_INIT_VAL	OCCR0_ON | OCCR0_OCI | OCCR0_WB	   /* D-cache: on,   */
+							   /* WB, invalidate */
+#else
+#error preprocessor flag CONFIG_DCACHE_... not recognized!
+#endif
+
+#define	OCCR1_INIT_VAL	OCCR1_NOLOCK			   /* No locking     */
+
+	.section	.empty_zero_page, "aw"
+	.global empty_zero_page
+	
+empty_zero_page:	
+	.long	1		/* MOUNT_ROOT_RDONLY */
+	.long	0		/* RAMDISK_FLAGS */
+	.long	0x0200		/* ORIG_ROOT_DEV */
+	.long	1		/* LOADER_TYPE */
+	.long	0x00360000	/* INITRD_START */
+	.long	0x000a0000	/* INITRD_SIZE */
+	.long	0
+
+	.text	
+	.balign 4096,0,4096	
+
+	.section	.data, "aw"
+	.balign	PAGE_SIZE
+
+	.section	.data, "aw"
+	.balign	PAGE_SIZE
+
+	.global swapper_pg_dir
+swapper_pg_dir:
+	.space PAGE_SIZE, 0
+
+	.global empty_bad_page
+empty_bad_page:
+	.space PAGE_SIZE, 0
+
+	.global empty_bad_pte_table
+empty_bad_pte_table:
+	.space PAGE_SIZE, 0
+
+variables:
+	.global	fpu_in_use
+fpu_in_use:	.quad	0
+
+
+	.section	.text, "ax"
+	.balign L1_CACHE_BYTES
+/*
+ * Condition at the entry of __stext:
+ * . Reset state:
+ *   . SR.FD    = 1		(FPU disabled)
+ *   . SR.BL    = 1		(Exceptions disabled)
+ *   . SR.MD    = 1		(Privileged Mode)
+ *   . SR.MMU   = 0		(MMU Disabled)
+ *   . SR.CD    = 0		(CTC User Visible)
+ *   . SR.IMASK = Undefined	(Interrupt Mask)
+ *
+ * Operations supposed to be performed by __stext:
+ * . prevent speculative fetch onto device memory while MMU is off
+ * . reflect as much as possible SH5 ABI (r15, r26, r27, r18)
+ * . first, save CPU state and set it to something harmless
+ * . any CPU detection and/or endianness settings (?)
+ * . initialize EMI/LMI (but not TMU/RTC/INTC/SCIF): TBD
+ * . set initial TLB entries for cached and uncached regions
+ *   (no fine granularity paging)
+ * . set initial cache state
+ * . enable MMU and caches
+ * . set CPU to a consistent state
+ *   . registers (including stack pointer and current/KCR0)
+ *   . NOT expecting to set Exception handling nor VBR/RESVEC/DCR
+ *     at this stage. This is all to later Linux initialization steps.
+ *   . initialize FPU
+ * . clear BSS
+ * . jump into start_kernel()
+ * . be prepared to hopeless start_kernel() returns.
+ *
+ */
+	.global _stext
+_stext:
+	/*
+	 * Prevent speculative fetch on device memory due to
+	 * uninitialized target registers.
+	 */
+	ptabs/u	ZERO, t0
+	ptabs/u	ZERO, t1
+	ptabs/u	ZERO, t2
+	ptabs/u	ZERO, t3
+	ptabs/u	ZERO, t4
+	ptabs/u	ZERO, t5
+	ptabs/u	ZERO, t6
+	ptabs/u	ZERO, t7
+	synci
+
+	/*
+	 * Set variable/constant pointers according to SH5 ABI.
+	 */
+	_loada	constants, GCDT
+
+	_loada	variables, GVDT
+
+	/*
+	 * Read/Set CPU state. After this block:
+	 * r29 = Initial SR
+	 */
+	getcon	SR, r29
+	movi	SR_HARMLESS, r20
+	putcon	r20, SR
+
+	/*
+	 * Initialize EMI/LMI. To Be Done.
+	 */
+
+	/*
+	 * CPU detection and/or endianness settings (?). To Be Done.
+	 * Pure PIC code here, please ! Just save state into r30.
+         * After this block:
+	 * r30 = CPU type/Platform Endianness
+	 */
+
+	/*
+	 * Set initial TLB entries for cached and uncached regions.
+	 * Note: PTA/BLINK is PIC code, PTABS/BLINK isn't !
+	 */
+	/* Clear ITLBs */
+	_ptar	clear_ITLB, t1
+	movi	MMUIR_FIRST, r21
+	movi	MMUIR_END, r22
+clear_ITLB:
+	putcfg	r21, 0, ZERO		/* Clear MMUIR[n].PTEH.V */
+	addi	r21, MMUIR_STEP, r21
+        bne	r21, r22, t1
+
+	/* Clear DTLBs */
+	_ptar	clear_DTLB, t1
+	movi	MMUDR_FIRST, r21
+	movi	MMUDR_END, r22
+clear_DTLB:
+	putcfg	r21, 0, ZERO		/* Clear MMUDR[n].PTEH.V */
+	addi	r21, MMUDR_STEP, r21
+        bne	r21, r22, t1
+
+	/* Map one big (512Mb) page for ITLB */
+	movi	MMUIR_FIRST, r21
+	movi	MMUIR_TEXT_L, r22	/* PTEL first */
+	putcfg	r21, 1, r22		/* Set MMUIR[0].PTEL */
+	movi	MMUIR_TEXT_H, r22	/* PTEH last */
+	putcfg	r21, 0, r22		/* Set MMUIR[0].PTEH */
+	
+	/* Map one big CACHED (512Mb) page for DTLB */
+	movi	MMUDR_FIRST, r21
+	movi	MMUDR_CACHED_L, r22	/* PTEL first */
+	putcfg	r21, 1, r22		/* Set MMUDR[0].PTEL */
+	movi	MMUDR_CACHED_H, r22	/* PTEH last */
+	putcfg	r21, 0, r22		/* Set MMUDR[0].PTEH */
+	
+	/*
+	 * Set cache behaviours.
+	 */
+	/* ICache */
+	movi	ICCR_BASE, r21
+	movi	ICCR0_INIT_VAL, r22
+	movi	ICCR1_INIT_VAL, r23
+	putcfg	r21, ICCR_REG0, r22
+	putcfg	r21, ICCR_REG1, r23
+
+	/* OCache */
+	movi	OCCR_BASE, r21
+	movi	OCCR0_INIT_VAL, r22
+	movi	OCCR1_INIT_VAL, r23
+	putcfg	r21, OCCR_REG0, r22
+	putcfg	r21, OCCR_REG1, r23
+
+
+	/*
+	 * Enable Caches and MMU. Do the first non-PIC jump.
+         * Now head.S global variables, constants and externs
+	 * can be used.
+	 */
+	getcon	SR, r21
+	movi	SR_ENABLE_MMU, r22
+	or	r21, r22, r21
+	putcon	r21, SSR
+	_loada	hyperspace, r22
+	ori	r22, 1, r22	    /* Make it SHmedia, not required but..*/
+	putcon	r22, SPC
+	synco
+	rte			    /* And now go into the hyperspace ... */
+hyperspace:			    /* ... that's the next instruction !  */
+
+	/*
+	 * Set CPU to a consistent state.
+	 * r31 = FPU support flag
+	 * t0/t7 in use. Others give a chance to loop somewhere safe
+	 */
+	_loada	start_kernel, r32
+	ori	r32, 1, r32
+
+	ptabs	r32, t0		    /* r32 = _start_kernel address        */
+	_ptaru	hopeless, t1
+	_ptaru	hopeless, t2
+	_ptaru	hopeless, t3
+	_ptaru	hopeless, t4
+	_ptaru	hopeless, t5
+	_ptaru	hopeless, t6
+	_ptar	hopeless, t7
+	gettr	t1, r28			/* r28 = hopeless address */
+
+	/* Set initial stack pointer */
+	_loada	init_task_union, SP
+	putcon	SP, KCR0		/* Set current to init_task */
+	movi	THREAD_SIZE, r22	/* Point to the end */
+	add	SP, r22, SP
+
+	/*
+	 * Initialize FPU.
+	 * Keep FPU flag in r31. After this block:	
+	 * r31 = FPU flag
+	 */
+	addi	GVDT, fpu_in_use - variables, r31	/* Temporary */
+
+#ifndef CONFIG_NOFPU_SUPPORT
+	getcon	SR, r21
+	movi	SR_ENABLE_FPU, r22
+	and	r21, r22, r22
+	putcon	r22, SR			/* Try to enable */
+	getcon	SR, r22
+	xor	r21, r22, r21
+	shlri	r21, 15, r21		/* Supposedly 0/1 */
+	st.q	r31, 0 , r21		/* Set fpu_in_use */
+#else
+	movi	0, r21
+	st.q	r31, 0 , r21		/* Set fpu_in_use */
+#endif
+	or	r21, ZERO, r31		/* Set FPU flag at last */
+
+	/*
+	 * Clear bss
+	 */
+	_ptar	clear_quad, t1
+	_loada	__bss_start, r22
+	_loada	_end, r23
+clear_quad:
+	st.q	r22, 0, ZERO 
+	addi	r22, 8, r22
+	bne	r22, r23, t1		/* Both quad aligned, see vmlinux.lds.S */
+	_ptaru	hopeless, t1
+
+	/* Say bye to head.S but be prepared to wrongly get back ... */
+	blink	t0, LINK
+
+	/* If we ever get back here through LINK/t1-t7 */
+	_ptaru	hopeless, t7
+
+hopeless:
+	/*
+	 * Something's badly wrong here. Loop endlessly,
+         * there's nothing more we can do about it.
+	 *
+	 * Note on hopeless: it can be jumped into invariably
+	 * before or after jumping into hyperspace. The only
+	 * requirement is to be PIC called (PTA) before and
+	 * any way (PTA/PTABS) after. According to Virtual
+	 * to Physical mapping a simulator/emulator can easily
+	 * tell where we came here from just looking at hopeless
+	 * (PC) address.
+	 *
+	 * For debugging purposes:
+	 * (r28) hopeless/loop address
+	 * (r29) Original SR
+	 * (r30) CPU type/Platform endianness
+	 * (r31) FPU Support
+	 * (r32) _start_kernel address
+	 */
+	blink	t7, ZERO
+
+
+	.balign L1_CACHE_BYTES
+constants:
+dummyc:	.quad 0
+
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/init_task.c linux-2.4.22-pre3/arch/sh64/kernel/init_task.c
--- linux-2.4.22-pre2/arch/sh64/kernel/init_task.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/init_task.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/init_task.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+
+struct pt_regs fake_swapper_regs;
+
+/*
+ * Initial task structure.
+ *
+ * We need to make sure that this is INIT_TASK_SIZE-byte aligned due
+ * to the way process stacks are handled. This is done by having a
+ * special "init_task" linker map entry..
+ */
+union task_union init_task_union 
+	__attribute__((__section__(".data.init_task"))) =
+		{ INIT_TASK(init_task_union.task) };
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/irq.c linux-2.4.22-pre3/arch/sh64/kernel/irq.c
--- linux-2.4.22-pre2/arch/sh64/kernel/irq.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/irq.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,706 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/irq.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/*
+ * IRQs are in fact implemented a bit like signal handlers for the kernel.
+ * Naturally it's not a 1:1 relation, but there are similarities.
+ */
+
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/smp.h>
+#include <asm/pgalloc.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <linux/irq.h>
+
+/*
+ * Controller mappings for all interrupt sources:
+ */
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
+	{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
+
+/*
+ * Special irq handlers.
+ */
+
+void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * Generic no controller code
+ */
+
+static void enable_none(unsigned int irq) { }
+static unsigned int startup_none(unsigned int irq) { return 0; }
+static void disable_none(unsigned int irq) { }
+static void ack_none(unsigned int irq)
+{
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves, it doesnt deserve
+ * a generic callback i think.
+ */
+	printk("unexpected IRQ trap at irq %02x\n", irq);
+}
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define shutdown_none	disable_none
+#define end_none	enable_none
+
+struct hw_interrupt_type no_irq_type = {
+	"none",
+	startup_none,
+	shutdown_none,
+	enable_none,
+	disable_none,
+	ack_none,
+	end_none
+};
+
+
+/*
+ * do_NMI handles all Non-Maskable Interrupts.
+ */
+asmlinkage void do_NMI(unsigned long vector_num, struct pt_regs * regs)
+{	
+	if (regs->sr & 0x40000000)
+		printk("unexpected NMI trap in system mode\n");
+	else
+		printk("unexpected NMI trap in user mode\n");
+
+	/* No statistics */
+}
+
+
+/*
+ * Generic, controller-independent functions:
+ */
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
+int get_irq_list(char *buf)
+{
+	int i, j;
+	struct irqaction * action;
+	char *p = buf;
+
+	p += sprintf(p, "           ");
+	for (j=0; j<smp_num_cpus; j++)
+		p += sprintf(p, "CPU%d       ",j);
+	*p++ = '\n';
+
+	for (i = 0 ; i < NR_IRQS ; i++) {
+		action = irq_desc[i].action;
+		if (!action) 
+			continue;
+		p += sprintf(p, "%3d: ",i);
+		p += sprintf(p, "%10u ", kstat_irqs(i));
+		p += sprintf(p, " %14s", irq_desc[i].handler->typename);
+		p += irq_describe(p, i);
+		p += sprintf(p, "  %s", action->name);
+
+		for (action=action->next; action; action = action->next)
+			p += sprintf(p, ", %s", action->name);
+		*p++ = '\n';
+	}
+#if 0
+	p += sprintf(p, "NMI: ");
+	for (j = 0; j < smp_num_cpus; j++)
+		p += sprintf(p, "%10u ",
+			atomic_read(&nmi_counter(cpu_logical_map(j))));
+	p += sprintf(p, "\n");
+#endif
+
+	return p - buf;
+}
+#endif
+
+/*
+ * This should really return information about whether
+ * we should do bottom half handling etc. Right now we
+ * end up _always_ checking the bottom half, which is a
+ * waste of time and is not what some drivers would
+ * prefer.
+ */
+int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
+{
+	int status;
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, irq);
+
+	status = 1;	/* Force the "do bottom halves" bit */
+
+        if (!(action->flags & SA_INTERRUPT))
+                __sti();
+
+	do {
+		status |= action->flags;
+		action->handler(irq, action->dev_id, regs);
+		action = action->next;
+	} while (action);
+	if (status & SA_SAMPLE_RANDOM)
+		add_interrupt_randomness(irq);
+
+	__cli();
+
+	irq_exit(cpu, irq);
+
+	return status;
+}
+
+/*
+ * Generic enable/disable code: this just calls
+ * down into the PIC-specific version for the actual
+ * hardware disable after having gotten the irq
+ * controller lock. 
+ */
+
+/**
+ *	disable_irq_nosync - disable an irq without waiting
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. Unlike disable_irq(), this function does not ensure existing
+ *	instances of the IRQ handler have completed before returning.
+ *
+ *	This function may be called from IRQ context.
+ */
+void disable_irq_nosync(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	if (!desc->depth++) {
+		desc->status |= IRQ_DISABLED;
+		desc->handler->disable(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/**
+ *	disable_irq - disable an irq and wait for completion
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. That is for two disables you need two enables. This
+ *	function waits for any pending IRQ handlers for this interrupt
+ *	to complete before returning. If you use this function while
+ *	holding a resource the IRQ handler may need you will deadlock.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+void disable_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+
+	if (!local_irq_count(smp_processor_id())) {
+		do {
+			barrier();
+		} while (irq_desc[irq].status & IRQ_INPROGRESS);
+	}
+}
+
+/**
+ *	enable_irq - enable interrupt handling on an irq
+ *	@irq: Interrupt to enable
+ *
+ *	Re-enables the processing of interrupts on this IRQ line
+ *	providing no disable_irq calls are now in effect.
+ *
+ *	This function may be called from IRQ context.
+ */
+void enable_irq(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	switch (desc->depth) {
+	case 1: {
+		unsigned int status = desc->status & ~IRQ_DISABLED;
+		desc->status = status;
+		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+			desc->status = status | IRQ_REPLAY;
+			hw_resend_irq(desc->handler,irq);
+		}
+		desc->handler->enable(irq);
+		/* fall-through */
+	}
+	default:
+		desc->depth--;
+		break;
+	case 0:
+		printk("enable_irq() unbalanced from %p\n",
+		       __builtin_return_address(0));
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/*
+ * do_IRQ handles all normal device IRQ's.
+ */
+asmlinkage int do_IRQ(unsigned long vector_num, struct pt_regs * regs)
+{	
+	/* 
+	 * We ack quickly, we don't want the irq controller
+	 * thinking we're snobs just because some other CPU has
+	 * disabled global interrupts (we have already done the
+	 * INT_ACK cycles, it's too late to try to pretend to the
+	 * controller that we aren't taking the interrupt).
+	 *
+	 * 0 return value means that this irq is already being
+	 * handled by some other CPU. (or is disabled)
+	 */
+	int irq;
+	int cpu = smp_processor_id();
+	irq_desc_t *desc;
+	struct irqaction * action;
+	unsigned int status;
+
+	irq = irq_demux(vector_num);
+
+	/*
+	 * Should never happen, if it does check
+	 * vectorN_to_IRQ[] against trap_jtable[].
+	 */
+	if (irq == -1) {
+		printk("unexpected IRQ trap at vector %03lx\n", vector_num);
+		return 1;
+	}
+
+	desc = irq_desc + irq;
+
+	kstat.irqs[cpu][irq]++;
+	spin_lock(&desc->lock);
+	desc->handler->ack(irq);
+	/*
+	   REPLAY is when Linux resends an IRQ that was dropped earlier
+	   WAITING is used by probe to mark irqs that are being tested
+	   */
+	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
+	status |= IRQ_PENDING; /* we _want_ to handle it */
+
+	/*
+	 * If the IRQ is disabled for whatever reason, we cannot
+	 * use the action we have.
+	 */
+	action = NULL;
+	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		action = desc->action;
+		status &= ~IRQ_PENDING; /* we commit to handling */
+		status |= IRQ_INPROGRESS; /* we are handling it */
+	}
+	desc->status = status;
+
+	/*
+	 * If there is no IRQ handler or it was disabled, exit early.
+	   Since we set PENDING, if another processor is handling
+	   a different instance of this same irq, the other processor
+	   will take care of it.
+	 */
+	if (!action)
+		goto out;
+
+	/*
+	 * Edge triggered interrupts need to remember
+	 * pending events.
+	 * This applies to any hw interrupts that allow a second
+	 * instance of the same irq to arrive while we are in do_IRQ
+	 * or in the handler. But the code here only handles the _second_
+	 * instance of the irq, not the third or fourth. So it is mostly
+	 * useful for irq hardware that does not mask cleanly in an
+	 * SMP environment.
+	 */
+	for (;;) {
+		spin_unlock(&desc->lock);
+		handle_IRQ_event(irq, regs, action);
+		spin_lock(&desc->lock);
+
+		if (!(desc->status & IRQ_PENDING))
+			break;
+		desc->status &= ~IRQ_PENDING;
+	}
+	desc->status &= ~IRQ_INPROGRESS;
+out:
+	/*
+	 * The ->end() handler has to deal with interrupts which got
+	 * disabled while the handler was running.
+	 */
+	desc->handler->end(irq);
+	spin_unlock(&desc->lock);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+	return 1;
+}
+
+/**
+ *	request_irq - allocate an interrupt line
+ *	@irq: Interrupt line to allocate
+ *	@handler: Function to be called when the IRQ occurs
+ *	@irqflags: Interrupt type flags
+ *	@devname: An ascii name for the claiming device
+ *	@dev_id: A cookie passed back to the handler function
+ *
+ *	This call allocates interrupt resources and enables the
+ *	interrupt line and IRQ handling. From the point this
+ *	call is made your handler function may be invoked. Since
+ *	your handler function must clear any interrupt the board
+ *	raises, you must take care both to initialise your hardware
+ *	and to set up the interrupt handler in the right order.
+ *
+ *	Dev_id must be globally unique. Normally the address of the
+ *	device data structure is used as the cookie. Since the handler
+ *	receives this value it makes sense to use it.
+ *
+ *	If your interrupt is shared you must pass a non NULL dev_id
+ *	as this is required when freeing the interrupt.
+ *
+ *	Flags:
+ *
+ *	SA_SHIRQ		Interrupt is shared
+ *
+ *	SA_INTERRUPT		Disable local interrupts while processing
+ *
+ *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
+ *
+ */
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction * action;
+
+#if 1
+	/*
+	 * Sanity-check: shared interrupts should REALLY pass in
+	 * a real dev-ID, otherwise we'll have trouble later trying
+	 * to figure out which interrupt is which (messes up the
+	 * interrupt freeing logic etc).
+	 */
+	if (irqflags & SA_SHIRQ) {
+		if (!dev_id)
+			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
+	}
+#endif
+
+	if (irq >= NR_IRQS)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action = (struct irqaction *)
+			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+/**
+ *	free_irq - free an interrupt
+ *	@irq: Interrupt line to free
+ *	@dev_id: Device identity to free
+ *
+ *	Remove an interrupt handler. The handler is removed and if the
+ *	interrupt line is no longer in use by any driver it is disabled.
+ *	On a shared IRQ the caller must ensure the interrupt is disabled
+ *	on the card it drives before calling this function. The function
+ *	does not return until any executing interrupts for this IRQ
+ *	have completed.
+ *
+ *	This function may be called from interrupt context.
+ *
+ *	Bugs: Attempting to free an irq in a handler for the same irq hangs
+ *	      the machine.
+ */
+void free_irq(unsigned int irq, void *dev_id)
+{
+	irq_desc_t *desc;
+	struct irqaction **p;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS)
+		return;
+
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	for (;;) {
+		struct irqaction * action = *p;
+		if (action) {
+			struct irqaction **pp = p;
+			p = &action->next;
+			if (action->dev_id != dev_id)
+				continue;
+
+			/* Found it - now remove it from the list of entries */
+			*pp = action->next;
+			if (!desc->action) {
+				desc->status |= IRQ_DISABLED;
+				desc->handler->shutdown(irq);
+			}
+			spin_unlock_irqrestore(&desc->lock,flags);
+			kfree(action);
+			return;
+		}
+		printk("Trying to free free IRQ%d\n",irq);
+		spin_unlock_irqrestore(&desc->lock,flags);
+		return;
+	}
+}
+
+/*
+ * IRQ autodetection code..
+ *
+ * This depends on the fact that any interrupt that
+ * comes in on to an unassigned handler will get stuck
+ * with "IRQ_WAITING" cleared and the interrupt
+ * disabled.
+ */
+
+/**
+ *	probe_irq_on	- begin an interrupt autodetect
+ *
+ *	Commence probing for an interrupt. The interrupts are scanned
+ *	and a mask of potential interrupt lines is returned.
+ *
+ */
+unsigned long probe_irq_on(void)
+{
+	unsigned int i;
+	irq_desc_t *desc;
+	unsigned long val;
+	unsigned long delay;
+
+	/*
+	 * something may have generated an irq long ago and we want to
+	 * flush such a longstanding irq before considering it as spurious.
+	 */
+	for (i = NR_IRQS-1; i >= 0; i--) {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!irq_desc[i].action) {
+			irq_desc[i].handler->startup(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/* Wait for longstanding interrupts to trigger. */
+	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
+		/* about 20ms delay */ synchronize_irq();
+
+	/*
+	 * enable any unassigned irqs
+	 * (we must startup again here because if a longstanding irq
+	 * happened in the previous stage, it may have masked itself)
+	 */
+	for (i = NR_IRQS-1; i >= 0; i--) {
+		desc = irq_desc + 1;
+
+		spin_lock_irq(&desc->lock);
+		if (!desc->action) {
+			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
+			if (desc->handler->startup(i))
+				desc->status |= IRQ_PENDING;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/*
+	 * Wait for spurious interrupts to trigger
+	 */
+	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
+		/* about 100ms delay */ synchronize_irq();
+
+	/*
+	 * Now filter out any obviously spurious interrupts
+	 */
+	val = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			/* It triggered already - consider it spurious. */
+			if (!(status & IRQ_WAITING)) {
+				desc->status = status & ~IRQ_AUTODETECT;
+				desc->handler->shutdown(i);
+			} else
+				if (i < 32)
+					val |= 1 << i;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	return val;
+}
+
+/*
+ * Return the one interrupt that triggered (this can
+ * handle any interrupt source).
+ */
+
+/**
+ *	probe_irq_off   - end an interrupt autodetect
+ *	@val: mask of potential interrupts (unused)
+ *
+ *	Scans the unused interrupt lines and returns the line which
+ *	appears to have triggered the interrupt. If no interrupt was
+ *	found then zero is returned. If more than one interrupt is
+ *	found then minus the first candidate is returned to indicate
+ *	their is doubt.
+ *
+ *	The interrupt probe logic state is returned to its previous
+ *	value.
+ *
+ *	BUGS: When used in a module (which arguably shouldnt happen)
+ *	nothing prevents two IRQ probe callers from overlapping. The
+ *	results of this are non-optimal.
+ */
+int probe_irq_off(unsigned long val)
+{
+	int i, irq_found, nr_irqs;
+
+	nr_irqs = 0;
+	irq_found = 0;
+	for (i=0; i<NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+		if (!(status & IRQ_AUTODETECT))
+			continue;
+
+		if (status & IRQ_AUTODETECT) {
+			if (!(status & IRQ_WAITING)) {
+				if (!nr_irqs)
+					irq_found = i;
+				nr_irqs++;
+			}
+
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	if (nr_irqs > 1)
+		irq_found = -irq_found;
+	return irq_found;
+}
+
+int setup_irq(unsigned int irq, struct irqaction * new)
+{
+	int shared = 0;
+	unsigned long flags;
+	struct irqaction *old, **p;
+	irq_desc_t *desc = irq_desc + irq;
+
+	/*
+	 * Some drivers like serial.c use request_irq() heavily,
+	 * so we have to be careful not to interfere with a
+	 * running system.
+	 */
+	if (new->flags & SA_SAMPLE_RANDOM) {
+		/*
+		 * This function might sleep, we want to call it first,
+		 * outside of the atomic block.
+		 * Yes, this might clear the entropy pool if the wrong
+		 * driver is attempted to be loaded, without actually
+		 * installing a new handler, but is this really a problem,
+		 * only the sysadmin is able to do this.
+		 */
+		rand_initialize_irq(irq);
+	}
+
+	/*
+	 * The following block of code has to be executed atomically
+	 */
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ)) {
+			spin_unlock_irqrestore(&desc->lock,flags);
+			return -EBUSY;
+		}
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	*p = new;
+
+	if (!shared) {
+		desc->depth = 0;
+		desc->status &= ~IRQ_DISABLED;
+		desc->handler->startup(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock,flags);
+
+	/*
+	 * No PROC FS support for interrupts.
+	 * For improvements in this area please check
+	 * the i386 branch.
+	 */
+	return 0;
+}
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
+
+void init_irq_proc(void)
+{
+	/*
+	 * No PROC FS support for interrupts.
+	 * For improvements in this area please check
+	 * the i386 branch.
+	 */
+}
+#endif
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/irq_intc.c linux-2.4.22-pre3/arch/sh64/kernel/irq_intc.c
--- linux-2.4.22-pre2/arch/sh64/kernel/irq_intc.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/irq_intc.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,269 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/irq_intc.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * Interrupt Controller support for SH5 INTC.
+ * Per-interrupt selective. IRLM=0 (Fixed priority) is not
+ * supported being useless without a cascaded interrupt
+ * controller.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+
+#include <asm/hardware.h>
+#include <asm/platform.h>
+#include <asm/bitops.h>		/* this includes also <asm/registers.h */
+				/* which is required to remap register */
+				/* names used into __asm__ blocks...   */
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+/*
+ * Maybe the generic Peripheral block could move to a more
+ * generic include file. INTC Block will be defined here
+ * and only here to make INTC self-contained in a single
+ * file.
+ */
+#define	INTC_BLOCK_OFFSET	0x01000000
+
+/* Base */
+#define INTC_BASE		PHYS_PERIPHERAL_BLOCK + \
+				INTC_BLOCK_OFFSET
+
+/* Address */
+#define INTC_ICR_SET		(intc_virt + 0x0)
+#define INTC_ICR_CLEAR		(intc_virt + 0x8)
+#define INTC_INTPRI_0		(intc_virt + 0x10)
+#define INTC_INTSRC_0		(intc_virt + 0x50)
+#define INTC_INTSRC_1		(intc_virt + 0x58)
+#define INTC_INTREQ_0		(intc_virt + 0x60)
+#define INTC_INTREQ_1		(intc_virt + 0x68)
+#define INTC_INTENB_0		(intc_virt + 0x70)
+#define INTC_INTENB_1		(intc_virt + 0x78)
+#define INTC_INTDSB_0		(intc_virt + 0x80)
+#define INTC_INTDSB_1		(intc_virt + 0x88)
+
+#define INTC_ICR_IRLM		0x1
+#define	INTC_INTPRI_PREGS	8		/* 8 Priority Registers */
+#define	INTC_INTPRI_PPREG	8		/* 8 Priorities per Register */
+
+
+/*
+ * Mapper between the vector ordinal and the IRQ number
+ * passed to kernel/device drivers.
+ */
+int intc_evt_to_irq[(0xE20/0x20)+1] = {
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0x000 - 0x0E0 */
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0x100 - 0x1E0 */
+	 0,  0,  0,  0,  0,  1,  0,  0,	/* 0x200 - 0x2E0 */
+	 2,  0,  0,  3,  0,  0,  0, -1,	/* 0x300 - 0x3E0 */
+	32, 33, 34, 35, 36, 37, 38, -1,	/* 0x400 - 0x4E0 */
+	-1, -1, -1, 63, -1, -1, -1, -1,	/* 0x500 - 0x5E0 */
+	-1, -1, 18, 19, 20, 21, 22, -1,	/* 0x600 - 0x6E0 */
+	39, 40, 41, 42, -1, -1, -1, -1,	/* 0x700 - 0x7E0 */
+	 4,  5,  6,  7, -1, -1, -1, -1,	/* 0x800 - 0x8E0 */
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0x900 - 0x9E0 */
+	12, 13, 14, 15, 16, 17, -1, -1,	/* 0xA00 - 0xAE0 */
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0xB00 - 0xBE0 */
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0xC00 - 0xCE0 */
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0xD00 - 0xDE0 */
+	-1, -1				/* 0xE00 - 0xE20 */
+};
+
+/*
+ * Opposite mapper.
+ */
+static int IRQ_to_vectorN[NR_INTC_IRQS] = {
+	0x12, 0x15, 0x18, 0x1B, 0x40, 0x41, 0x42, 0x43, /*  0- 7 */
+	  -1,   -1,   -1,   -1, 0x50, 0x51, 0x52, 0x53,	/*  8-15 */
+	0x54, 0x55, 0x32, 0x33, 0x34, 0x35, 0x36,   -1, /* 16-23 */
+	  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, /* 24-31 */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x38,	/* 32-39 */
+        0x39, 0x3A, 0x3B,   -1,   -1,   -1,   -1,   -1, /* 40-47 */
+	  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, /* 48-55 */
+	  -1,   -1,   -1,   -1,   -1,   -1,   -1, 0x2B, /* 56-63 */
+	  
+};
+
+static unsigned long intc_virt;
+
+static unsigned int startup_intc_irq(unsigned int irq);
+static void shutdown_intc_irq(unsigned int irq);
+static void enable_intc_irq(unsigned int irq);
+static void disable_intc_irq(unsigned int irq);
+static void mask_and_ack_intc(unsigned int);
+static void end_intc_irq(unsigned int irq);
+
+static struct hw_interrupt_type intc_irq_type = {
+	"INTC",
+	startup_intc_irq,
+	shutdown_intc_irq,
+	enable_intc_irq,
+	disable_intc_irq,
+	mask_and_ack_intc,
+	end_intc_irq
+};
+
+static int irlm;		/* IRL mode */
+
+static unsigned int startup_intc_irq(unsigned int irq)
+{ 
+	enable_intc_irq(irq);
+	return 0; /* never anything pending */
+}
+
+static void shutdown_intc_irq(unsigned int irq)
+{
+	disable_intc_irq(irq);
+}
+
+static void enable_intc_irq(unsigned int irq)
+{
+	unsigned long reg;
+	unsigned long bitmask;
+
+	if ((irq <= IRQ_IRL3) && (irlm == NO_PRIORITY))
+		printk("Trying to use straight IRL0-3 with an encoding platform.\n");
+
+	if (irq < 32) {
+		reg = INTC_INTENB_0;
+		bitmask = 1 << irq;
+	} else {
+		reg = INTC_INTENB_1;
+		bitmask = 1 << (irq - 32);
+	}
+
+	ctrl_outl(bitmask, reg);
+}
+
+static void disable_intc_irq(unsigned int irq)
+{
+	unsigned long reg;
+	unsigned long bitmask;
+
+	if (irq < 32) {
+		reg = INTC_INTDSB_0;
+		bitmask = 1 << irq;
+	} else {
+		reg = INTC_INTDSB_1;
+		bitmask = 1 << (irq - 32);
+	}
+
+	ctrl_outl(bitmask, reg);
+}
+
+static void mask_and_ack_intc(unsigned int irq)
+{
+	disable_intc_irq(irq);
+}
+
+static void end_intc_irq(unsigned int irq)
+{
+	enable_intc_irq(irq);	
+}
+
+/* For future use, if we ever support IRLM=0) */
+void make_intc_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	irq_desc[irq].handler = &intc_irq_type;
+	disable_intc_irq(irq);
+}
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
+int intc_irq_describe(char* p, int irq)
+{
+	if (irq < NR_INTC_IRQS)
+		return sprintf(p, "(0x%3x)", IRQ_to_vectorN[irq]*0x20);
+	else
+		return 0;
+}
+#endif
+
+void __init init_IRQ(void)
+{
+        unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
+	unsigned long reg;
+	unsigned long data;
+	int i;
+
+	intc_virt = onchip_remap(INTC_BASE, 1024, "INTC");
+	if (!intc_virt) {
+		panic("Unable to remap INTC\n");
+	}
+
+
+	/* Set default: per-line enable/disable, priority driven ack/eoi */
+	for (i = 0; i < NR_INTC_IRQS; i++) {
+		if (platform_int_priority[i] != NO_PRIORITY) {
+			irq_desc[i].handler = &intc_irq_type;
+		}
+	}
+
+
+	/* Disable all interrupts and set all priorities to 0 to avoid trouble */
+	ctrl_outl(-1, INTC_INTDSB_0);
+	ctrl_outl(-1, INTC_INTDSB_1);
+
+	for (reg = INTC_INTPRI_0, i = 0; i < INTC_INTPRI_PREGS; i++, reg += 8)
+		ctrl_outl( NO_PRIORITY, reg);
+		
+
+	/* Set IRLM */
+	/* If all the priorities are set to 'no priority', then
+	 * assume we are using encoded mode.
+	 */
+	irlm = platform_int_priority[IRQ_IRL0] + platform_int_priority[IRQ_IRL1] + \
+		platform_int_priority[IRQ_IRL2] + platform_int_priority[IRQ_IRL3];
+
+	if (irlm == NO_PRIORITY) {
+		/* IRLM = 0 */
+		reg = INTC_ICR_CLEAR;
+		i = IRQ_INTA;
+		printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
+	} else {
+		/* IRLM = 1 */
+		reg = INTC_ICR_SET;
+		i = IRQ_IRL0;
+	}
+	ctrl_outl(INTC_ICR_IRLM, reg);
+
+	/* Set interrupt priorities according to platform description */
+	for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
+		data |= platform_int_priority[i] << ((i % INTC_INTPRI_PPREG) * 4);
+		if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
+			/* Upon the 7th, set Priority Register */
+			ctrl_outl(data, reg);
+			data = 0;
+			reg += 8;
+		}
+	}
+
+#ifdef CONFIG_SH_CAYMAN
+	extern void init_cayman_irq(void);
+
+	init_cayman_irq();
+#endif
+
+	/*
+	 * And now let interrupts come in.
+	 * sti() is not enough, we need to
+	 * lower priority, too.
+	 */
+        __asm__ __volatile__("getcon    " __c0 ", %0\n\t"
+                             "and       %0, %1, %0\n\t"
+                             "putcon    %0, " __c0 "\n\t"
+                             : "=&r" (__dummy0)
+                             : "r" (__dummy1));
+}
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/led.c linux-2.4.22-pre3/arch/sh64/kernel/led.c
--- linux-2.4.22-pre2/arch/sh64/kernel/led.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/led.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,69 @@
+/*
+ * arch/sh64/kernel/led.c
+ *
+ * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Flash the LEDs
+ */
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+
+void mach_alphanum(int pos, unsigned char val);
+void mach_led(int pos, int val);
+
+void print_seg(char *file, int line)
+{
+	int i;
+	unsigned int nibble;
+
+	for (i = 0; i < 5; i++) {
+		mach_alphanum(i, file[i]);
+	}
+
+	for (i = 0; i < 3; i++) {
+		nibble = ((line >> (i * 4)) & 0xf);
+		mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48));
+	}
+}
+
+void print_seg_num(unsigned num)
+{
+	int i;
+	unsigned int nibble;
+
+	for (i = 0; i < 8; i++) {
+		nibble = ((num >> (i * 4)) & 0xf);
+
+		mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48));
+	}
+}
+
+/* acts like an actual heart beat -- ie thump-thump-pause... */
+void heartbeat(void)
+{
+	static unsigned int cnt = 0, period = 0, dist = 0;
+
+	if (cnt == 0 || cnt == dist) {
+		mach_led(-1, 1);
+	} else if (cnt == 7 || cnt == dist + 7) {
+		mach_led(-1, 0);
+	}
+
+	if (++cnt > period) {
+		cnt = 0;
+
+		/* 
+		 * The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51, f(inf)->30.
+		 */
+		period = ((672 << FSHIFT) / (5 * avenrun[0] +
+					    (7 << FSHIFT))) + 30;
+		dist = period / 4;
+	}
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/pci-dma.c linux-2.4.22-pre3/arch/sh64/kernel/pci-dma.c
--- linux-2.4.22-pre2/arch/sh64/kernel/pci-dma.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/pci-dma.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,50 @@
+/* 
+ * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
+ * Copyright (C) 2003 Paul Mundt (lethal@linux-sh.org)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Dynamic DMA mapping support.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t *dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC;
+        void *vp;
+
+	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+		gfp |= GFP_DMA;
+
+	ret = (void *)__get_free_pages(gfp, get_order(size));
+
+	/* now call our friend ioremap_nocache to give us an uncached area */
+        vp = ioremap_nocache(virt_to_phys(ret), size);
+
+	if (vp != NULL) {
+		memset(vp, 0, size);
+		*dma_handle = virt_to_bus(ret);
+		dma_cache_wback_inv((unsigned long)ret, size);
+	}
+
+	return vp;
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	void *alloc;
+
+	alloc = bus_to_virt((unsigned long)dma_handle);
+	free_pages((unsigned long)alloc, get_order(size));
+
+	iounmap(vaddr);
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/pci_sh5.c linux-2.4.22-pre3/arch/sh64/kernel/pci_sh5.c
--- linux-2.4.22-pre2/arch/sh64/kernel/pci_sh5.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/pci_sh5.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,607 @@
+/* 
+ * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Support functions for the SH5 PCI hardware.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <asm/pci.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include "pci_sh5.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#  define dprintk(x...)  printk(KERN_DEBUG x)
+#else
+#  define dprintk(x...)  do { } while (0)
+#endif /* DEBUG */
+
+static unsigned long pcicr_virt;
+unsigned long pciio_virt;
+
+static void __init pci_fixup_ide_bases(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
+	 */
+	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+	printk("PCI: IDE base address fixup for %s\n", d->slot_name);
+	for(i=0; i<4; i++) {
+		struct resource *r = &d->resource[i];
+		if ((r->start & ~0x80) == 0x374) {
+			r->start |= 2;
+			r->end = r->start;
+		}
+	}
+}
+
+/* Add future fixups here... */
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,	PCI_ANY_ID,	pci_fixup_ide_bases },
+	{ 0 }
+};
+
+char * __init pcibios_setup(char *str)
+{
+	return str;
+}
+
+/* Rounds a number UP to the nearest power of two. Used for
+ * sizing the PCI window.
+ */
+static u32 __init r2p2(u32 num)
+{
+	int i = 31;
+	u32 tmp = num;
+
+	if (num == 0)
+		return 0;
+
+	do {
+		if (tmp & (1 << 31))
+			break;
+		i--;
+		tmp <<= 1;
+	} while (i >= 0);
+
+	tmp = 1 << i;
+	/* If the original number isn't a power of 2, round it up */
+	if (tmp != num)
+		tmp <<= 1;
+
+	return tmp;
+}
+
+extern unsigned long long memory_start, memory_end;
+
+int __init sh5pci_init(unsigned memStart, unsigned memSize)
+{
+	u32 lsr0;
+	u32 uval;
+
+	pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
+	if (!pcicr_virt) {
+		panic("Unable to remap PCICR\n");
+	}
+
+	pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
+	if (!pciio_virt) {
+		panic("Unable to remap PCIIO\n");
+	}
+
+	dprintk("Register base addres is 0x%08lx\n", pcicr_virt);
+
+	/* Clear snoop registers */
+        SH5PCI_WRITE(CSCR0, 0);
+        SH5PCI_WRITE(CSCR1, 0);
+
+	dprintk("Wrote to reg\n");
+
+        /* Switch off interrupts */
+        SH5PCI_WRITE(INTM,  0);
+        SH5PCI_WRITE(AINTM, 0);
+        SH5PCI_WRITE(PINTM, 0);
+
+        /* Set bus active, take it out of reset */
+        uval = SH5PCI_READ(CR);
+
+	/* Set command Register */
+        SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS);
+
+	uval=SH5PCI_READ(CR);
+        dprintk("CR is actually 0x%08x\n",uval);
+
+        /* Allow it to be a master */
+	/* NB - WE DISABLE I/O ACCESS to stop overlap */
+        /* set WAIT bit to enable stepping, an attempt to improve stability */
+	SH5PCI_WRITE_SHORT(CSR_CMD,
+			    PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_WAIT);
+
+        /* 
+        ** Set translation mapping memory in order to convert the address
+        ** used for the main bus, to the PCI internal address.
+        */
+        SH5PCI_WRITE(MBR,0x40000000);
+
+        /* Always set the max size 512M */
+        SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
+
+        /* 
+        ** I/O addresses are mapped at internal PCI specific address
+        ** as is described into the configuration bridge table.
+        ** These are changed to 0, to allow cards that have legacy 
+        ** io such as vga to function correctly. We set the SH5 IOBAR to
+        ** 256K, which is a bit big as we can only have 64K of address space
+        */
+
+        SH5PCI_WRITE(IOBR,0x0);
+      	
+	dprintk("PCI:Writing 0x%08x to IOBR\n",0);
+
+        /* Set up a 256K window. Totally pointless waste  of address space */
+        SH5PCI_WRITE(IOBMR,0);
+	dprintk("PCI:Writing 0x%08x to IOBMR\n",0);
+
+	/* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec. Ideally, 
+         * we would want to map the I/O region somewhere, but it is so big this is not
+         * that easy!
+         */
+	SH5PCI_WRITE(CSR_IBAR0,~0);
+	/* Set memory size value */
+        memSize = memory_end - memory_start;
+
+        /* Now we set up the mbars so the PCI bus can see the memory of the machine */
+        if (memSize < (1024 * 1024)) {
+                printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%x?\n", memSize);
+                return(-1);
+        }
+
+        /* Set LSR 0 */
+        lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
+        SH5PCI_WRITE(LSR0, lsr0);
+
+	dprintk("PCI:Writing 0x%08x to LSR0\n",lsr0);
+
+        /* Set MBAR 0 */
+        SH5PCI_WRITE(CSR_MBAR0, memory_start);
+        SH5PCI_WRITE(LAR0, memory_start);
+
+
+        SH5PCI_WRITE(CSR_MBAR1,0);
+        SH5PCI_WRITE(LAR1,0);
+        SH5PCI_WRITE(LSR1,0);
+
+	dprintk("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start);         
+	dprintk("PCI:Writing 0x%08llx to LAR0\n",memory_start);         
+
+        /* Enable the PCI interrupts on the device */
+
+#if 1
+        SH5PCI_WRITE(INTM,  ~0);
+        SH5PCI_WRITE(AINTM, ~0);
+        SH5PCI_WRITE(PINTM, ~0);
+#endif
+
+	dprintk("Switching on all error interrupts\n");
+
+        return(0);
+}
+
+
+
+/* Write to config register */
+static int sh5pci_read_config_byte(struct pci_dev *dev, int where,
+				    u8 * val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	*val = SH5PCI_READ_BYTE(PDR + (where & 3));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int sh5pci_read_config_word(struct pci_dev *dev, int where,
+				    u16 * val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	*val = SH5PCI_READ_SHORT(PDR + (where & 2));
+
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int sh5pci_read_config_dword(struct pci_dev *dev, int where,
+				     u32 * val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	*val = SH5PCI_READ(PDR);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int sh5pci_write_config_byte(struct pci_dev *dev, int where,
+				     u8 val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	SH5PCI_WRITE_BYTE(PDR + (where & 3), val);
+
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int sh5pci_write_config_word(struct pci_dev *dev, int where,
+				     u16 val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	SH5PCI_WRITE_SHORT(PDR + (where & 2), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int sh5pci_write_config_dword(struct pci_dev *dev, int where,
+				      u32 val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	SH5PCI_WRITE(PDR, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static struct pci_ops pci_config_ops = {
+	sh5pci_read_config_byte,
+	sh5pci_read_config_word,
+	sh5pci_read_config_dword,
+	sh5pci_write_config_byte,
+	sh5pci_write_config_word,
+	sh5pci_write_config_dword
+};
+
+/* Everything hangs off this */
+static struct pci_bus *pci_root_bus;
+
+
+static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
+{
+	dprintk("swizzle for dev %d on bus %d slot %d pin is %d\n",
+	       dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin);
+	return PCI_SLOT(dev->devfn);
+}
+
+static inline u8 bridge_swizzle(u8 pin, u8 slot) 
+{
+	return (((pin-1) + slot) % 4) + 1;
+}
+
+u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	if (dev->bus->number != 0) {
+		u8 pin = *pinp;
+		do {
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+			/* Move up the chain of bridges. */
+			dev = dev->bus->self;
+		} while (dev->bus->self);
+		*pinp = pin;
+
+		/* The slot is the slot of the last bridge. */
+	}
+
+	return PCI_SLOT(dev->devfn);
+}
+
+/* This needs to be shunted out of here into the board specific bit */
+
+static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	dprintk("map_cayman_irq for dev %d on bus %d slot %d, pin is %d\n",
+	       dev->devfn,dev->bus->number,slot,pin);
+ 
+	if (dev->bus->number == 0) {
+	        switch (slot) {
+	        case 0:
+	          return IRQ_INTA;
+                case 1:
+	          return IRQ_INTB;
+                case 2:
+	          return IRQ_INTC;
+		case 3:
+		  return IRQ_INTD;
+                }
+        }
+
+	if (dev->bus->number == 2) {
+	        switch(slot) {
+	        case 0:
+	          return IRQ_P2INTA;
+                case 1:
+	          return IRQ_P2INTB;
+                }
+        }
+
+	/* FIXME - DO PROPER MAPPING FOR GODS SAKE */
+	return -1;
+}
+
+#ifdef DEBUG
+void print_resource(struct resource *r) 
+{
+	if (r == NULL)
+		return;
+
+	//printk("Resource %s\n",r->name);
+	printk("Start 0x%lx end 0x%lx\n",r->start,r->end);
+}
+
+void print_set_ranges_data(struct pbus_set_ranges_data *ranges)
+{
+
+	if (!ranges) {
+		printk("NO RANGES\n");
+		return;
+	}
+
+	printk("io_start is 0x%lx\n", ranges->io_start);
+	printk("io_end is 0x%lx\n", ranges->io_end);
+	printk("mem_start is 0x%lx\n", ranges->mem_start);
+	printk("mem_end is 0x%lx\n", ranges->mem_end);
+}
+#endif /* DEBUG */
+
+void __init
+  pcibios_fixup_pbus_ranges(struct pci_bus *bus,
+	        struct pbus_set_ranges_data *ranges)
+{
+#ifdef DEBUG
+	int i;
+
+	dprintk("%s, bus number %d\n",__FUNCTION__,bus->number);
+
+	print_set_ranges_data(ranges);
+
+	for (i = 0; i < 2; i++)
+		print_resource(bus->resource[i]);
+#endif
+}
+
+void  pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned pci_int, pci_air, pci_cir, pci_aint;
+
+	pci_int = SH5PCI_READ(INT);
+	pci_cir = SH5PCI_READ(CIR);
+	pci_air = SH5PCI_READ(AIR);
+
+	if (pci_int) {
+		printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
+		printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
+		printk("PCI AIR -> 0x%x\n", pci_air);
+		printk("PCI CIR -> 0x%x\n", pci_cir);
+		SH5PCI_WRITE(INT, ~0);
+	}
+
+	pci_aint = SH5PCI_READ(AINT);
+	if (pci_aint) {
+		printk("PCI ARB INTERRUPT!\n");
+		printk("PCI AINT -> 0x%x\n", pci_aint);
+		printk("PCI AIR -> 0x%x\n", pci_air);
+		printk("PCI CIR -> 0x%x\n", pci_cir);
+		SH5PCI_WRITE(AINT, ~0);
+	}
+
+}
+
+
+void pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+  printk("SERR IRQ\n");
+
+}
+
+#define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1))
+
+static void __init
+pcibios_size_bridge(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
+{
+	struct pbus_set_ranges_data inner;
+	struct pci_dev *dev;
+	struct pci_dev *bridge = bus->self;
+	struct list_head *ln;
+
+	if (!bridge)
+		return;	/* host bridge, nothing to do */
+
+	/* set reasonable default locations for pcibios_align_resource */
+	inner.io_start = PCIBIOS_MIN_IO;
+	inner.mem_start = PCIBIOS_MIN_MEM;
+	inner.io_end = inner.io_start;
+	inner.mem_end = inner.mem_start;
+
+	/* Collect information about how our direct children are layed out. */
+	for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
+		int i;
+		dev = pci_dev_b(ln);
+
+		/* Skip bridges for now */
+		if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
+			continue;
+
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			struct resource res;
+			unsigned long size;
+
+			memcpy(&res, &dev->resource[i], sizeof(res));
+			size = res.end - res.start + 1;
+
+			if (res.flags & IORESOURCE_IO) {
+				res.start = inner.io_end;
+				pcibios_align_resource(dev, &res, size, 0);
+				inner.io_end = res.start + size;
+			} else if (res.flags & IORESOURCE_MEM) {
+				res.start = inner.mem_end;
+				pcibios_align_resource(dev, &res, size, 0);
+				inner.mem_end = res.start + size;
+			}
+		}
+	}
+
+	/* And for all of the subordinate busses. */
+	for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
+		pcibios_size_bridge(pci_bus_b(ln), &inner);
+
+	/* turn the ending locations into sizes (subtract start) */
+	inner.io_end -= inner.io_start;
+	inner.mem_end -= inner.mem_start;
+
+	/* Align the sizes up by bridge rules */
+	inner.io_end = ROUND_UP(inner.io_end, 4*1024) - 1;
+	inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024) - 1;
+
+	/* Adjust the bridge's allocation requirements */
+	bridge->resource[0].end = bridge->resource[0].start + inner.io_end;
+	bridge->resource[1].end = bridge->resource[1].start + inner.mem_end;
+
+	bridge->resource[PCI_BRIDGE_RESOURCES].end =
+	    bridge->resource[PCI_BRIDGE_RESOURCES].start + inner.io_end;
+	bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
+	    bridge->resource[PCI_BRIDGE_RESOURCES+1].start + inner.mem_end;
+
+	/* adjust parent's resource requirements */
+	if (outer) {
+		outer->io_end = ROUND_UP(outer->io_end, 4*1024);
+		outer->io_end += inner.io_end;
+
+		outer->mem_end = ROUND_UP(outer->mem_end, 1*1024*1024);
+		outer->mem_end += inner.mem_end;
+	}
+}
+
+#undef ROUND_UP
+
+static void __init 
+pcibios_size_bridges(void)
+{
+	struct pbus_set_ranges_data outer;
+
+	memset(&outer,0,sizeof(outer));
+	pcibios_size_bridge(pci_root_bus,&outer);
+}
+
+void __init
+common_init_pci(void)
+{
+	pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
+	pcibios_size_bridges();
+	pci_assign_unassigned_resources();
+	pci_fixup_irqs(no_swizzle, map_cayman_irq);
+	//	pci_set_bus_ranges();
+}
+
+void __init pcibios_init(void)
+{
+
+        if (request_irq(IRQ_ERR, pcish5_err_irq,
+                        SA_INTERRUPT, "PCI Error",NULL) < 0) {
+                printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
+		return;
+        }
+
+
+        if (request_irq(IRQ_SERR, pcish5_serr_irq,
+                        SA_INTERRUPT, "PCI SERR interrupt", NULL) < 0) {
+                printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
+		return;
+        }
+
+
+	/* The pci subsytem needs to know where memory is and how much 
+	 * of it there is. I've simply made these globals. A better mechanism
+	 * is probably needed. 
+	 */
+	sh5pci_init(__pa(memory_start),
+		     __pa(memory_end) - __pa(memory_start));
+
+
+	common_init_pci();
+
+#if 0
+	pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
+
+	pci_assign_unassigned_resources();
+
+	pci_fixup_irqs(no_swizzle, map_cayman_irq);
+
+	pci_set_bus_ranges();
+#endif
+
+}
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev = bus->self;
+	int i;
+
+#if 1
+	if(dev) {
+		for(i=0; i<3; i++) {
+			bus->resource[i] =
+				&dev->resource[PCI_BRIDGE_RESOURCES+i];
+			bus->resource[i]->name = bus->name;
+		}
+		bus->resource[0]->flags |= IORESOURCE_IO;
+		bus->resource[1]->flags |= IORESOURCE_MEM;
+
+		/* For now, propogate host limits to the bus;
+		 * we'll adjust them later. */
+
+#if 1
+		bus->resource[0]->end = 64*1024 - 1 ;
+		bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
+		bus->resource[0]->start = PCIBIOS_MIN_IO;
+		bus->resource[1]->start = PCIBIOS_MIN_MEM;
+#else
+		bus->resource[0]->end = 0
+		bus->resource[1]->end = 0
+		bus->resource[0]->start =0
+		  bus->resource[1]->start = 0;
+#endif
+
+#ifdef DEBUG
+		dprintk("in fixup bus resource 0 is:\n");
+		print_resource(bus->resource[0]);
+		dprintk("in fixup bus resource 1 is:\n");
+		print_resource(bus->resource[1]);
+#endif /* DEBUG */
+		
+		/* Turn off downstream PF memory address range by default */
+		bus->resource[2]->start = 1024*1024;
+		bus->resource[2]->end = bus->resource[2]->start - 1;
+	}
+#endif 
+
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/pci_sh5.h linux-2.4.22-pre3/arch/sh64/kernel/pci_sh5.h
--- linux-2.4.22-pre2/arch/sh64/kernel/pci_sh5.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/pci_sh5.h	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,107 @@
+/* 
+ * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Defintions for the SH5 PCI hardware.
+ */
+
+/* Product ID */
+#define PCISH5_PID		0x350d
+
+/* vendor ID */
+#define PCISH5_VID		0x1054
+
+/* Configuration types */
+#define ST_TYPE0                0x00    /* Configuration cycle type 0 */
+#define ST_TYPE1                0x01    /* Configuration cycle type 1 */
+
+/* VCR data */
+#define PCISH5_VCR_STATUS      0x00
+#define PCISH5_VCR_VERSION     0x08
+
+/*
+** ICR register offsets and bits
+*/ 
+#define PCISH5_ICR_CR          0x100   /* PCI control register values */
+#define CR_PBAM                 (1<<12)
+#define CR_PFCS                 (1<<11)
+#define CR_FTO                  (1<<10)
+#define CR_PFE                  (1<<9)
+#define CR_TBS                  (1<<8)
+#define CR_SPUE                 (1<<7)
+#define CR_BMAM                 (1<<6)
+#define CR_HOST                 (1<<5)
+#define CR_CLKEN                (1<<4)
+#define CR_SOCS                 (1<<3)
+#define CR_IOCS                 (1<<2)
+#define CR_RSTCTL               (1<<1)
+#define CR_CFINT                (1<<0)
+#define CR_LOCK_MASK            0xa5000000
+
+#define PCISH5_ICR_INT         0x114   /* Interrupt registert values     */
+#define INT_MADIM               (1<<2)
+
+#define PCISH5_ICR_LSR0        0X104   /* Local space register values    */
+#define PCISH5_ICR_LSR1        0X108   /* Local space register values    */
+#define PCISH5_ICR_LAR0        0x10c   /* Local address register values  */
+#define PCISH5_ICR_LAR1        0x110   /* Local address register values  */
+#define PCISH5_ICR_INTM        0x118   /* Interrupt mask register values                         */
+#define PCISH5_ICR_AIR         0x11c   /* Interrupt error address information register values    */
+#define PCISH5_ICR_CIR         0x120   /* Interrupt error command information register values    */
+#define PCISH5_ICR_AINT        0x130   /* Interrupt error arbiter interrupt register values      */
+#define PCISH5_ICR_AINTM       0x134   /* Interrupt error arbiter interrupt mask register values */
+#define PCISH5_ICR_BMIR        0x138   /* Interrupt error info register of bus master values     */
+#define PCISH5_ICR_PAR         0x1c0   /* Pio address register values                            */
+#define PCISH5_ICR_MBR         0x1c4   /* Memory space bank register values                      */
+#define PCISH5_ICR_IOBR        0x1c8   /* I/O space bank register values                         */
+#define PCISH5_ICR_PINT        0x1cc   /* power management interrupt register values             */
+#define PCISH5_ICR_PINTM       0x1d0   /* power management interrupt mask register values        */
+#define PCISH5_ICR_MBMR        0x1d8   /* memory space bank mask register values                 */
+#define PCISH5_ICR_IOBMR       0x1dc   /* I/O space bank mask register values                    */
+#define PCISH5_ICR_CSCR0       0x210   /* PCI cache snoop control register 0                     */
+#define PCISH5_ICR_CSCR1       0x214   /* PCI cache snoop control register 1                     */
+#define PCISH5_ICR_PDR         0x220   /* Pio data register values                               */
+
+/* These are configs space registers */
+#define PCISH5_ICR_CSR_VID     0x000	/* Vendor id                           */
+#define PCISH5_ICR_CSR_DID     0x002   /* Device id                           */
+#define PCISH5_ICR_CSR_CMD     0x004   /* Command register                    */
+#define PCISH5_ICR_CSR_STATUS  0x006   /* Stautus                             */
+#define PCISH5_ICR_CSR_IBAR0   0x010   /* I/O base address register           */
+#define PCISH5_ICR_CSR_MBAR0   0x014   /* First  Memory base address register */
+#define PCISH5_ICR_CSR_MBAR1   0x018   /* Second Memory base address register */
+
+
+
+/* Base address of registers */
+#define SH5PCI_ICR_BASE (PHYS_PCI_BLOCK + 0x00040000) 
+#define SH5PCI_IO_BASE  (PHYS_PCI_BLOCK + 0x00800000)
+/* #define SH5PCI_VCR_BASE (P2SEG_PCICB_BLOCK + P2SEG)    */
+
+/* Register selection macro */
+#define PCISH5_ICR_REG(x)                ( pcicr_virt + (PCISH5_ICR_##x))
+/* #define PCISH5_VCR_REG(x)                ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */
+
+/* Write I/O functions */
+#define SH5PCI_WRITE(reg,val)        ctrl_outl((u32)(val),PCISH5_ICR_REG(reg))
+#define SH5PCI_WRITE_SHORT(reg,val)  ctrl_outw((u16)(val),PCISH5_ICR_REG(reg))
+#define SH5PCI_WRITE_BYTE(reg,val)   ctrl_outb((u8)(val),PCISH5_ICR_REG(reg))
+
+/* Read I/O functions */
+#define SH5PCI_READ(reg)             ctrl_inl(PCISH5_ICR_REG(reg))
+#define SH5PCI_READ_SHORT(reg)       ctrl_inw(PCISH5_ICR_REG(reg))
+#define SH5PCI_READ_BYTE(reg)        ctrl_inb(PCISH5_ICR_REG(reg))
+
+/* Set PCI config bits */
+#define SET_CONFIG_BITS(bus,devfn,where)  ((((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) | 0x80000000)
+
+/* Set PCI command register */
+#define CONFIG_CMD(dev, where)            SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where)
+
+/* Size converters */
+#define PCISH5_MEM_SIZCONV(x)		  (((x / 0x40000) - 1) << 18)
+#define PCISH5_IO_SIZCONV(x)		  (((x / 0x40000) - 1) << 18)
+
+
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/pcibios.c linux-2.4.22-pre3/arch/sh64/kernel/pcibios.c
--- linux-2.4.22-pre2/arch/sh64/kernel/pcibios.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/pcibios.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,129 @@
+/*
+ * $Id: pcibios.c,v 1.1 2001/08/24 12:38:19 dwmw2 Exp $
+ *
+ * arch/sh/kernel/pcibios.c
+ *
+ * This is GPL'd.
+ *
+ * Provided here are generic versions of:
+ *	pcibios_update_resource()
+ *	pcibios_align_resource()
+ *	pcibios_enable_device()
+ *	pcibios_set_master()
+ *	pcibios_update_irq()
+ *
+ * These functions are collected here to reduce duplication of common
+ * code amongst the many platform-specific PCI support code files.
+ *
+ * Platform-specific files are expected to provide:
+ *	pcibios_fixup_bus()
+ *	pcibios_init()
+ *	pcibios_setup()
+ *	pcibios_fixup_pbus_ranges()
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		new |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
+	
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ */
+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;
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		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);
+			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(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check and set
+ *  the latency timer as it may not be properly set.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", dev->name, lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/process.c linux-2.4.22-pre3/arch/sh64/kernel/process.c
--- linux-2.4.22-pre2/arch/sh64/kernel/process.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/process.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,939 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/process.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ * Started from SH3/4 version:
+ *   Copyright (C) 1999, 2000  Niibe Yutaka & Kaz Kojima
+ *
+ *   In turn started from i386 version:
+ *     Copyright (C) 1995  Linus Torvalds
+ *
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+/* Temporary flags/tests. All to be removed/undefined. BEGIN */
+#define IDLE_TRACE
+#define VM_SHOW_TABLES
+#define VM_TEST_FAULT
+#define VM_TEST_RTLBMISS
+#define VM_TEST_WTLBMISS
+
+#undef VM_SHOW_TABLES
+#undef IDLE_TRACE
+/* Temporary flags/tests. All to be removed/undefined. END */
+
+#define __KERNEL_SYSCALLS__
+#include <stdarg.h>
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/unistd.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/processor.h>		/* includes also <asm/registers.h> */
+#include <asm/mmu_context.h>
+#include <asm/elf.h>
+#include <asm/page.h>
+
+#include <linux/irq.h>
+
+struct task_struct *last_task_used_math = NULL;
+
+#ifdef IDLE_TRACE
+#ifdef VM_SHOW_TABLES
+/* For testing */
+static void print_PTE(long base)
+{
+	int i, skip=0;
+	long long x, y, *p = (long long *) base;
+
+	for (i=0; i< 512; i++, p++){
+		if (*p == 0) {
+			if (!skip) {	
+				skip++;
+				printk("(0s) ");
+			}
+		} else {	
+			skip=0;
+			x = (*p) >> 32;
+			y = (*p) & 0xffffffff;
+			printk("%08Lx%08Lx ", x, y);
+			if (!((i+1)&0x3)) printk("\n");
+		}
+	}
+}
+
+/* For testing */
+static void print_DIR(long base)
+{
+	int i, skip=0;
+	long *p = (long *) base;
+
+	for (i=0; i< 512; i++, p++){
+		if (*p == 0) {
+			if (!skip) {	
+				skip++;
+				printk("(0s) ");
+			}
+		} else {	
+			skip=0;
+			printk("%08lx ", *p);
+			if (!((i+1)&0x7)) printk("\n");
+		}
+	}
+}
+
+/* For testing */
+static void print_vmalloc_first_tables(void)
+{
+
+#define PRESENT	0x800	/* Bit 11 */
+
+	/*
+	 * Do it really dirty by looking at raw addresses,
+         * raw offsets, no types. If we used pgtable/pgalloc
+	 * macros/definitions we could hide potential bugs.
+	 *
+	 * Note that pointers are 32-bit for CDC.
+	 */
+	long pgdt, pmdt, ptet;
+
+	pgdt = (long) &swapper_pg_dir;
+	printk("-->PGD (0x%08lx):\n", pgdt);
+	print_DIR(pgdt);
+	printk("\n");
+
+	/* VMALLOC pool is mapped at 0xc0000000, second (pointer) entry in PGD */
+	pgdt += 4;
+	pmdt = (long) (* (long *) pgdt);
+	if (!(pmdt & PRESENT)) {
+		printk("No PMD\n");
+		return;
+	} else pmdt &= 0xfffff000;
+
+	printk("-->PMD (0x%08lx):\n", pmdt);
+	print_DIR(pmdt);
+	printk("\n");
+
+	/* Get the pmdt displacement for 0xc0000000 */
+	pmdt += 2048;
+
+	/* just look at first two address ranges ... */
+        /* ... 0xc0000000 ... */
+	ptet = (long) (* (long *) pmdt);
+	if (!(ptet & PRESENT)) {
+		printk("No PTE0\n");
+		return;
+	} else ptet &= 0xfffff000;
+
+	printk("-->PTE0 (0x%08lx):\n", ptet);
+	print_PTE(ptet);
+	printk("\n");
+
+        /* ... 0xc0001000 ... */
+	ptet += 4;
+	if (!(ptet & PRESENT)) {
+		printk("No PTE1\n");
+		return;
+	} else ptet &= 0xfffff000;
+	printk("-->PTE1 (0x%08lx):\n", ptet);
+	print_PTE(ptet);
+	printk("\n");
+}
+#else
+#define print_vmalloc_first_tables()
+#endif	/* VM_SHOW_TABLES */
+
+static void test_VM(void)
+{
+	void *a, *b, *c;
+
+#ifdef VM_SHOW_TABLES
+	printk("Initial PGD/PMD/PTE\n");
+#endif
+        print_vmalloc_first_tables();
+
+	printk("Allocating 2 bytes\n");
+	a = vmalloc(2);
+        print_vmalloc_first_tables();
+        
+	printk("Allocating 4100 bytes\n");
+	b = vmalloc(4100);
+        print_vmalloc_first_tables();
+
+	printk("Allocating 20234 bytes\n");
+	c = vmalloc(20234);
+        print_vmalloc_first_tables();
+
+#ifdef VM_TEST_FAULT
+	/* Here you may want to fault ! */
+
+#ifdef VM_TEST_RTLBMISS
+	printk("Ready to fault upon read.\n");
+	if (* (char *) a) {
+		printk("RTLBMISSed on area a !\n");
+	}
+	printk("RTLBMISSed on area a !\n");
+#endif
+
+#ifdef VM_TEST_WTLBMISS
+	printk("Ready to fault upon write.\n");
+	*((char *) b) = 'L';
+	printk("WTLBMISSed on area b !\n");
+#endif
+
+#endif	/* VM_TEST_FAULT */
+
+	printk("Deallocating the 4100 byte chunk\n");
+	vfree(b);
+        print_vmalloc_first_tables();
+
+	printk("Deallocating the 2 byte chunk\n");
+	vfree(a);
+        print_vmalloc_first_tables();
+
+	printk("Deallocating the last chunk\n");
+	vfree(c);
+        print_vmalloc_first_tables();
+}
+
+extern unsigned long volatile jiffies;
+int once = 0;
+unsigned long old_jiffies;
+int pid = -1, pgid = -1;
+
+void idle_trace(void)
+{
+
+	_syscall0(int, getpid)
+	_syscall1(int, getpgid, int, pid)
+
+	if (!once) {
+        	/* VM allocation/deallocation simple test */
+		test_VM();
+		pid = getpid();
+
+        	printk("Got all through to Idle !!\n");
+        	printk("I'm now going to loop forever ...\n");
+        	printk("Any ! below is a timer tick.\n");
+		printk("Any . below is a getpgid system call from pid = %d.\n", pid);
+
+
+        	old_jiffies = jiffies;
+		once++;
+	}
+
+	if (old_jiffies != jiffies) {
+		old_jiffies = jiffies - old_jiffies;
+		switch (old_jiffies) {
+		case 1:
+			printk("!");
+			break;
+		case 2:
+			printk("!!");
+			break;
+		case 3:
+			printk("!!!");
+			break;
+		case 4:
+			printk("!!!!");
+			break;
+		default:
+			printk("(%d!)", (int) old_jiffies);
+		}
+		old_jiffies = jiffies;
+	}
+	pgid = getpgid(pid);
+	printk(".");
+}
+#else
+#define idle_trace()	do { } while (0)
+#endif	/* IDLE_TRACE */
+
+static int hlt_counter = 1;
+
+#define HARD_IDLE_TIMEOUT (HZ / 3)
+
+void disable_hlt(void)
+{
+	hlt_counter++;
+}
+
+void enable_hlt(void)
+{
+	hlt_counter--;
+}
+
+static int __init nohlt_setup(char *__unused)
+{
+	hlt_counter = 1;
+	return 1;
+}
+
+static int __init hlt_setup(char *__unused)
+{
+	hlt_counter = 0;
+	return 1;
+}
+
+__setup("nohlt", nohlt_setup);
+__setup("hlt", hlt_setup);
+
+static inline void hlt(void)
+{
+	if (hlt_counter)
+		return;
+
+	/* 
+	 * FIXME: Is there any reason why we can't just do a "sleep"
+	 * instead of this crap?
+	 */
+	__asm__ __volatile__ (
+		".int %0\n\t"
+		: /* no outputs */
+		: "g" (le32_to_cpu(0x6ff7fff0))
+		: "memory"
+	);
+}
+
+/*
+ * The idle loop on a uniprocessor SH..
+ */ 
+void cpu_idle(void *unused)
+{
+	/* endless idle loop with no priority at all */
+	init_idle();
+	current->nice = 20;
+	current->counter = -100;
+
+	while (1) {
+		while (!current->need_resched) {
+			if (hlt_counter)
+				continue;
+			__sti();
+			idle_trace();
+			hlt();
+		}
+		schedule();
+		check_pgt_cache();
+	}
+}
+
+void machine_restart(char * __unused)
+{
+	extern void phys_stext(void);
+
+	phys_stext();
+}
+
+void machine_halt(void)
+{
+	for (;;);
+}
+
+void machine_power_off(void)
+{
+	enter_deep_standby();
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	unsigned long long ah, al, bh, bl, ch, cl;
+
+	printk("\n");
+
+	ah = (regs->pc) >> 32;
+	al = (regs->pc) & 0xffffffff;
+	bh = (regs->regs[18]) >> 32;
+	bl = (regs->regs[18]) & 0xffffffff;
+	ch = (regs->regs[15]) >> 32;
+	cl = (regs->regs[15]) & 0xffffffff;
+	printk("PC  : %08Lx%08Lx LINK: %08Lx%08Lx SP  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->sr) >> 32;
+	al = (regs->sr) & 0xffffffff;
+        asm volatile ("getcon   " __c13 ", %0" : "=r" (bh));
+        asm volatile ("getcon   " __c13 ", %0" : "=r" (bl));
+	bh = (bh) >> 32;
+	bl = (bl) & 0xffffffff;
+        asm volatile ("getcon   " __c17 ", %0" : "=r" (ch));
+        asm volatile ("getcon   " __c17 ", %0" : "=r" (cl));
+	ch = (ch) >> 32;
+	cl = (cl) & 0xffffffff;
+	printk("SR  : %08Lx%08Lx TEA : %08Lx%08Lx KCR0: %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[0]) >> 32;
+	al = (regs->regs[0]) & 0xffffffff;
+	bh = (regs->regs[1]) >> 32;
+	bl = (regs->regs[1]) & 0xffffffff;
+	ch = (regs->regs[2]) >> 32;
+	cl = (regs->regs[2]) & 0xffffffff;
+	printk("R0  : %08Lx%08Lx R1  : %08Lx%08Lx R2  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[3]) >> 32;
+	al = (regs->regs[3]) & 0xffffffff;
+	bh = (regs->regs[4]) >> 32;
+	bl = (regs->regs[4]) & 0xffffffff;
+	ch = (regs->regs[5]) >> 32;
+	cl = (regs->regs[5]) & 0xffffffff;
+	printk("R3  : %08Lx%08Lx R4  : %08Lx%08Lx R5  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[6]) >> 32;
+	al = (regs->regs[6]) & 0xffffffff;
+	bh = (regs->regs[7]) >> 32;
+	bl = (regs->regs[7]) & 0xffffffff;
+	ch = (regs->regs[8]) >> 32;
+	cl = (regs->regs[8]) & 0xffffffff;
+	printk("R6  : %08Lx%08Lx R7  : %08Lx%08Lx R8  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[9]) >> 32;
+	al = (regs->regs[9]) & 0xffffffff;
+	bh = (regs->regs[10]) >> 32;
+	bl = (regs->regs[10]) & 0xffffffff;
+	ch = (regs->regs[11]) >> 32;
+	cl = (regs->regs[11]) & 0xffffffff;
+	printk("R9  : %08Lx%08Lx R10 : %08Lx%08Lx R11 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[12]) >> 32;
+	al = (regs->regs[12]) & 0xffffffff;
+	bh = (regs->regs[13]) >> 32;
+	bl = (regs->regs[13]) & 0xffffffff;
+	ch = (regs->regs[14]) >> 32;
+	cl = (regs->regs[14]) & 0xffffffff;
+	printk("R12 : %08Lx%08Lx R13 : %08Lx%08Lx R14 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[16]) >> 32;
+	al = (regs->regs[16]) & 0xffffffff;
+	bh = (regs->regs[17]) >> 32;
+	bl = (regs->regs[17]) & 0xffffffff;
+	ch = (regs->regs[19]) >> 32;
+	cl = (regs->regs[19]) & 0xffffffff;
+	printk("R16 : %08Lx%08Lx R17 : %08Lx%08Lx R19 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[20]) >> 32;
+	al = (regs->regs[20]) & 0xffffffff;
+	bh = (regs->regs[21]) >> 32;
+	bl = (regs->regs[21]) & 0xffffffff;
+	ch = (regs->regs[22]) >> 32;
+	cl = (regs->regs[22]) & 0xffffffff;
+	printk("R20 : %08Lx%08Lx R21 : %08Lx%08Lx R22 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[23]) >> 32;
+	al = (regs->regs[23]) & 0xffffffff;
+	bh = (regs->regs[24]) >> 32;
+	bl = (regs->regs[24]) & 0xffffffff;
+	ch = (regs->regs[25]) >> 32;
+	cl = (regs->regs[25]) & 0xffffffff;
+	printk("R23 : %08Lx%08Lx R24 : %08Lx%08Lx R25 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[26]) >> 32;
+	al = (regs->regs[26]) & 0xffffffff;
+	bh = (regs->regs[27]) >> 32;
+	bl = (regs->regs[27]) & 0xffffffff;
+	ch = (regs->regs[28]) >> 32;
+	cl = (regs->regs[28]) & 0xffffffff;
+	printk("R26 : %08Lx%08Lx R27 : %08Lx%08Lx R28 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[29]) >> 32;
+	al = (regs->regs[29]) & 0xffffffff;
+	bh = (regs->regs[30]) >> 32;
+	bl = (regs->regs[30]) & 0xffffffff;
+	ch = (regs->regs[31]) >> 32;
+	cl = (regs->regs[31]) & 0xffffffff;
+	printk("R29 : %08Lx%08Lx R30 : %08Lx%08Lx R31 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[32]) >> 32;
+	al = (regs->regs[32]) & 0xffffffff;
+	bh = (regs->regs[33]) >> 32;
+	bl = (regs->regs[33]) & 0xffffffff;
+	ch = (regs->regs[34]) >> 32;
+	cl = (regs->regs[34]) & 0xffffffff;
+	printk("R32 : %08Lx%08Lx R33 : %08Lx%08Lx R34 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[35]) >> 32;
+	al = (regs->regs[35]) & 0xffffffff;
+	bh = (regs->regs[36]) >> 32;
+	bl = (regs->regs[36]) & 0xffffffff;
+	ch = (regs->regs[37]) >> 32;
+	cl = (regs->regs[37]) & 0xffffffff;
+	printk("R35 : %08Lx%08Lx R36 : %08Lx%08Lx R37 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[38]) >> 32;
+	al = (regs->regs[38]) & 0xffffffff;
+	bh = (regs->regs[39]) >> 32;
+	bl = (regs->regs[39]) & 0xffffffff;
+	ch = (regs->regs[40]) >> 32;
+	cl = (regs->regs[40]) & 0xffffffff;
+	printk("R38 : %08Lx%08Lx R39 : %08Lx%08Lx R40 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[41]) >> 32;
+	al = (regs->regs[41]) & 0xffffffff;
+	bh = (regs->regs[42]) >> 32;
+	bl = (regs->regs[42]) & 0xffffffff;
+	ch = (regs->regs[43]) >> 32;
+	cl = (regs->regs[43]) & 0xffffffff;
+	printk("R41 : %08Lx%08Lx R42 : %08Lx%08Lx R43 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[44]) >> 32;
+	al = (regs->regs[44]) & 0xffffffff;
+	bh = (regs->regs[45]) >> 32;
+	bl = (regs->regs[45]) & 0xffffffff;
+	ch = (regs->regs[46]) >> 32;
+	cl = (regs->regs[46]) & 0xffffffff;
+	printk("R44 : %08Lx%08Lx R45 : %08Lx%08Lx R46 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[47]) >> 32;
+	al = (regs->regs[47]) & 0xffffffff;
+	bh = (regs->regs[48]) >> 32;
+	bl = (regs->regs[48]) & 0xffffffff;
+	ch = (regs->regs[49]) >> 32;
+	cl = (regs->regs[49]) & 0xffffffff;
+	printk("R47 : %08Lx%08Lx R48 : %08Lx%08Lx R49 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[50]) >> 32;
+	al = (regs->regs[50]) & 0xffffffff;
+	bh = (regs->regs[51]) >> 32;
+	bl = (regs->regs[51]) & 0xffffffff;
+	ch = (regs->regs[52]) >> 32;
+	cl = (regs->regs[52]) & 0xffffffff;
+	printk("R50 : %08Lx%08Lx R51 : %08Lx%08Lx R52 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[53]) >> 32;
+	al = (regs->regs[53]) & 0xffffffff;
+	bh = (regs->regs[54]) >> 32;
+	bl = (regs->regs[54]) & 0xffffffff;
+	ch = (regs->regs[55]) >> 32;
+	cl = (regs->regs[55]) & 0xffffffff;
+	printk("R53 : %08Lx%08Lx R54 : %08Lx%08Lx R55 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[56]) >> 32;
+	al = (regs->regs[56]) & 0xffffffff;
+	bh = (regs->regs[57]) >> 32;
+	bl = (regs->regs[57]) & 0xffffffff;
+	ch = (regs->regs[58]) >> 32;
+	cl = (regs->regs[58]) & 0xffffffff;
+	printk("R56 : %08Lx%08Lx R57 : %08Lx%08Lx R58 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[59]) >> 32;
+	al = (regs->regs[59]) & 0xffffffff;
+	bh = (regs->regs[60]) >> 32;
+	bl = (regs->regs[60]) & 0xffffffff;
+	ch = (regs->regs[61]) >> 32;
+	cl = (regs->regs[61]) & 0xffffffff;
+	printk("R59 : %08Lx%08Lx R60 : %08Lx%08Lx R61 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[62]) >> 32;
+	al = (regs->regs[62]) & 0xffffffff;
+	bh = (regs->tregs[0]) >> 32;
+	bl = (regs->tregs[0]) & 0xffffffff;
+	ch = (regs->tregs[1]) >> 32;
+	cl = (regs->tregs[1]) & 0xffffffff;
+	printk("R62 : %08Lx%08Lx T0  : %08Lx%08Lx T1  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->tregs[2]) >> 32;
+	al = (regs->tregs[2]) & 0xffffffff;
+	bh = (regs->tregs[3]) >> 32;
+	bl = (regs->tregs[3]) & 0xffffffff;
+	ch = (regs->tregs[4]) >> 32;
+	cl = (regs->tregs[4]) & 0xffffffff;
+	printk("T2  : %08Lx%08Lx T3  : %08Lx%08Lx T4  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->tregs[5]) >> 32;
+	al = (regs->tregs[5]) & 0xffffffff;
+	bh = (regs->tregs[6]) >> 32;
+	bl = (regs->tregs[6]) & 0xffffffff;
+	ch = (regs->tregs[7]) >> 32;
+	cl = (regs->tregs[7]) & 0xffffffff;
+	printk("T5  : %08Lx%08Lx T6  : %08Lx%08Lx T7  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	/*
+	 * If we're in kernel mode, dump the stack too..
+	 */
+	if (!user_mode(regs)) {
+		extern void show_task(unsigned long *sp);
+		unsigned long sp = regs->regs[15] & 0xffffffff;
+
+		show_task((unsigned long *)sp);
+	}
+}
+
+struct task_struct * alloc_task_struct(void)
+{
+	/* Get task descriptor pages */
+	return (struct task_struct *)
+		__get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE));
+}
+
+void free_task_struct(struct task_struct *p)
+{
+	free_pages((unsigned long) p, get_order(THREAD_SIZE));
+}
+
+/*
+ * Create a kernel thread
+ */
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ */
+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	/* A bit less processor dependent than older sh ... */
+
+	unsigned int reply;
+
+static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp)
+static __inline__ _syscall1(int,exit,int,ret)
+
+	reply = clone(flags | CLONE_VM, 0);
+	if (!reply) {
+		/* Child */
+		reply = exit(fn(arg));
+	}
+
+	return reply;
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+	/* See arch/sparc/kernel/process.c for the precedent for doing this -- RPC.
+	
+	   The SH-5 FPU save/restore approach relies on last_task_used_math
+	   pointing to a live task_struct.  When another task tries to use the
+	   FPU for the 1st time, the FPUDIS trap handling (see
+	   arch/sh64/kernel/fpu.c) will save the existing FPU state to the
+	   FP regs field within last_task_used_math before re-loading the new
+	   task's FPU state (or initialising it if the FPU has been used
+	   before).  So if last_task_used_math is stale, and its page has already been
+	   re-allocated for another use, the consequences are rather grim. Unless we
+	   null it here, there is no other path through which it would get safely
+	   nulled. */
+
+#ifndef CONFIG_NOFPU_SUPPORT
+	if (last_task_used_math == current) {
+		last_task_used_math = NULL;
+	}
+#endif
+}
+
+void flush_thread(void)
+{
+
+	/* As far as I can tell, this function isn't actually called from anywhere.
+	   So why does it have a non-null body for most architectures?? -- RPC */
+	/* Look closer, this is used in fs/exec.c by flush_old_exec() which is
+	   used by binfmt_elf and friends to remove leftover traces of the
+	   previously running executable. -- PFM */
+#ifndef CONFIG_NOFPU_SUPPORT
+	if (last_task_used_math == current) {
+		last_task_used_math = NULL;
+	}
+#endif
+
+	/* if we are a kernel thread, about to change to user thread,
+         * update kreg 
+         */
+	if(current->thread.kregs==&fake_swapper_regs) {
+          current->thread.kregs= 
+             ((struct pt_regs *)(THREAD_SIZE + (unsigned long) current) - 1);
+	}
+}
+
+void release_thread(struct task_struct *dead_task)
+{
+	/* do nothing */
+}
+
+/* Fill in the fpu structure for a core dump.. */
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
+{
+#ifndef CONFIG_NOFPU_SUPPORT
+	int fpvalid;
+	struct task_struct *tsk = current;
+
+	fpvalid = tsk->used_math;
+	if (fpvalid) {
+		if (current == last_task_used_math) {
+			grab_fpu();
+			fpsave(&tsk->thread.fpu.hard);
+			release_fpu();
+			last_task_used_math = 0;
+			regs->sr |= SR_FD;
+		}
+		
+		memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
+	}
+
+	return fpvalid;
+#else
+	return 0; /* Task didn't use the fpu at all. */
+#endif
+}
+
+asmlinkage void ret_from_fork(void);
+
+int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+		unsigned long unused,
+		struct task_struct *p, struct pt_regs *regs)
+{
+	struct pt_regs *childregs;
+	unsigned long long se;			/* Sign extension */
+#ifndef CONFIG_NOFPU_SUPPORT
+	if(last_task_used_math == current) {		
+		grab_fpu();
+		fpsave(&current->thread.fpu.hard);
+		release_fpu();
+		last_task_used_math = NULL;
+		regs->sr |= SR_FD;
+	}
+#endif
+	childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long) p)) - 1;
+	*childregs = *regs;
+
+	if (user_mode(regs)) {
+		childregs->regs[15] = usp;
+		p->thread.kregs = childregs;
+	} else {
+		childregs->regs[15] = (unsigned long)p+THREAD_SIZE;
+		p->thread.kregs = &fake_swapper_regs;
+	}
+
+	childregs->regs[9] = 0; /* Set return value for child */
+	childregs->sr |= SR_FD; /* Invalidate FPU flag */
+
+	p->thread.sp = (unsigned long) childregs;
+	p->thread.pc = (unsigned long) ret_from_fork;
+
+	/*
+	 * Sign extend the edited stack.
+         * Note that thread.pc and thread.pc will stay
+	 * 32-bit wide and context switch must take care
+	 * of NEFF sign extension.
+	 */
+      
+	se = childregs->regs[15];
+	se = (se & NEFF_SIGN) ? (se | NEFF_MASK) : se;
+	childregs->regs[15] = se;
+
+	return 0;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+	dump->magic = CMAGIC;
+	dump->start_code = current->mm->start_code;
+	dump->start_data  = current->mm->start_data;
+	dump->start_stack = regs->regs[15] & ~(PAGE_SIZE - 1);
+	dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT;
+	dump->u_dsize = (current->mm->brk + (PAGE_SIZE-1) - dump->start_data) >> PAGE_SHIFT;
+	dump->u_ssize = (current->mm->start_stack - dump->start_stack +
+			 PAGE_SIZE - 1) >> PAGE_SHIFT;
+	/* Debug registers will come here. */
+
+	dump->regs = *regs;
+
+	dump->u_fpvalid = dump_fpu(regs, &dump->fpu);
+}
+
+/*
+ *	switch_to(x,y) should switch tasks from x to y.
+ *
+ */
+struct task_struct * __switch_to(struct task_struct *prev, struct task_struct *next)
+{
+	/*
+	 * Restore the kernel mode register
+	 *   	KCR0 =  __c17
+	 */
+	asm volatile("putcon	%0, " __c17 "\n"
+		     : /* no output */
+		     :"r" (next));
+	return prev;
+
+}
+
+asmlinkage int sys_fork(unsigned long r2, unsigned long r3,
+			unsigned long r4, unsigned long r5,
+			unsigned long r6, unsigned long r7,
+			struct pt_regs *pregs)
+{
+	return do_fork(SIGCHLD, pregs->regs[15], pregs,0);
+}
+
+asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
+			 unsigned long r4, unsigned long r5,
+			 unsigned long r6, unsigned long r7,
+			 struct pt_regs *pregs)
+{
+	if (!newsp)
+		newsp = pregs->regs[15];
+	return do_fork(clone_flags, newsp, pregs,0);
+}
+
+/*
+ * This is trivial, and on the face of it looks like it
+ * could equally well be done in user mode.
+ *
+ * Not so, for quite unobvious reasons - register pressure.
+ * In user mode vfork() cannot have a stack frame, and if
+ * done by calling the "clone()" system call directly, you
+ * do not have enough call-clobbered registers to hold all
+ * the information you need.
+ */
+asmlinkage int sys_vfork(unsigned long r2, unsigned long r3,
+			 unsigned long r4, unsigned long r5,
+			 unsigned long r6, unsigned long r7,
+			 struct pt_regs *pregs)
+{
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, pregs->regs[15], pregs,0);
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(char *ufilename, char **uargv,
+			  char **uenvp, unsigned long r5,
+			  unsigned long r6, unsigned long r7,
+			  struct pt_regs *pregs)
+{
+	int error;
+	char *filename;
+
+	lock_kernel();
+	filename = getname(ufilename);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+
+	error = do_execve(filename, uargv, uenvp, pregs);
+	if (error == 0)
+		current->ptrace &= ~PT_DTRACE;
+	putname(filename);
+out:
+	unlock_kernel();
+	return error;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+extern void interruptible_sleep_on(wait_queue_head_t *q);
+
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define mid_sched	((unsigned long) interruptible_sleep_on)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long schedule_frame;
+	unsigned long pc;
+
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	/*
+	 * The same comment as on the Alpha applies here, too ...
+	 */
+	pc = thread_saved_pc(&p->thread);
+
+	if (pc >= first_sched && pc < last_sched) {
+
+		schedule_frame = (long) p->thread.sp;
+
+		/* Should we unwind schedule_timeout() ? */
+		if (pc < mid_sched)
+			/* according to disasm:
+			**     48 bytes in case of RH toolchain
+		        */
+			schedule_frame += 48;
+			
+		/*
+		** Unwind schedule(). According to disasm:
+		**    72 bytes in case of RH toolchain
+		** plus 304 bytes of switch_to additional frame.
+		*/
+		schedule_frame += 72 + 304;
+
+#ifdef CS_SAVE_ALL
+		schedule_frame += 256;
+#endif
+		/*
+		 * schedule_frame now according to SLEEP_ON_VAR.
+	 	 * Bad thing is that we have no trace of the waiting
+		 * address (the classical WCHAN). SLEEP_ON_VAR should
+		 * have saved q. From the linked list only we can't get
+		 * the object and first parameter is not saved on stack
+		 * by the ABI. The best we can tell is who called the
+		 * *sleep_on* by returning LINK, which is saved at
+		 * offset 64 on all flavours.
+		 */
+		return (unsigned long)((unsigned long *)schedule_frame)[16];
+	}
+	return pc;
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/ptrace.c linux-2.4.22-pre3/arch/sh64/kernel/ptrace.c
--- linux-2.4.22-pre2/arch/sh64/kernel/ptrace.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/ptrace.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,374 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/ptrace.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * Started from SH3/4 version:
+ *   SuperH version:   Copyright (C) 1999, 2000  Kaz Kojima & Niibe Yutaka
+ *
+ *   Original x86 implementation:
+ *	By Ross Biro 1/23/92
+ *	edited by Linus Torvalds
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/mmu_context.h>
+
+/* This mask defines the bits of the SR which the user is not allowed to
+   change, which are everything except S, Q, M, PR, SZ, FR. */
+#define SR_MASK      (0xffff8cfd)
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/*
+ * This routine will get a word off of the process kernel stack.
+ */
+static inline int get_stack_long(struct task_struct *task, int offset)
+{
+	unsigned char *stack;
+
+	stack = (unsigned char *)(task->thread.kregs);
+	stack += offset;
+	return (*((int *)stack));
+}
+
+static inline unsigned long
+get_fpu_long(struct task_struct *task, unsigned long addr)
+{
+	unsigned long tmp;
+	struct pt_regs *regs;
+	regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1;
+
+	if (!task->used_math) {
+		if (addr == offsetof(struct user_fpu_struct, fpscr)) {
+			tmp = FPSCR_INIT;
+		} else {
+			tmp = 0xffffffffUL; /* matches initial value in fpu.c */
+		}
+		return tmp;
+	}
+
+	if (last_task_used_math == task) {
+		grab_fpu();
+		fpsave(&task->thread.fpu.hard);
+		release_fpu();
+		last_task_used_math = 0;
+		regs->sr |= SR_FD;
+	}
+
+	tmp = ((long *)&task->thread.fpu)[addr / sizeof(unsigned long)];
+	return tmp;
+}
+
+/*
+ * This routine will put a word on the process kernel stack.
+ */
+static inline int put_stack_long(struct task_struct *task, int offset,
+				 unsigned long data)
+{
+	unsigned char *stack;
+
+	stack = (unsigned char *)(task->thread.kregs);
+	stack += offset;
+	*(unsigned long *) stack = data;
+	return 0;
+}
+
+static inline int
+put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
+{
+	struct pt_regs *regs;
+
+	regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1;
+
+	if (!task->used_math) {
+		fpinit(&task->thread.fpu.hard);
+		task->used_math = 1;
+	} else if (last_task_used_math == task) {
+		grab_fpu();
+		fpsave(&task->thread.fpu.hard);
+		release_fpu();
+		last_task_used_math = 0;
+		regs->sr |= SR_FD;
+	}
+
+	((long *)&task->thread.fpu)[addr / sizeof(unsigned long)] = data;
+	return 0;
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child, *tsk = current;
+	int ret;
+
+	lock_kernel();
+	ret = -EPERM;
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+	ret = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out_tsk;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			goto out_tsk;
+	}
+	if (child->p_pptr != tsk)
+		goto out_tsk;
+	switch (request) {
+	/* when I and D space are separate, these will need to be fixed. */
+	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKDATA: {
+		unsigned long tmp;
+		int copied;
+
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		ret = -EIO;
+		if (copied != sizeof(tmp))
+			break;
+		ret = put_user(tmp,(unsigned long *) data);
+		break;
+	}
+
+	/* read the word at location addr in the USER area. */
+	case PTRACE_PEEKUSR: {
+		unsigned long tmp;
+
+		ret = -EIO;
+		if ((addr & 3) || addr < 0)
+			break;
+
+		if (addr < sizeof(struct pt_regs))
+			tmp = get_stack_long(child, addr);
+		else if ((addr >= offsetof(struct user, fpu)) &&
+			 (addr <  offsetof(struct user, u_fpvalid))) {
+			tmp = get_fpu_long(child, addr - offsetof(struct user, fpu));
+		} else if (addr == offsetof(struct user, u_fpvalid)) {
+			tmp = child->used_math;
+		} else {
+			break;
+		}
+		ret = put_user(tmp, (unsigned long *)data);
+		break;
+	}
+
+	/* when I and D space are separate, this will have to be fixed. */
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		ret = 0;
+		if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+			break;
+		ret = -EIO;
+		break;
+
+	case PTRACE_POKEUSR:
+                /* write the word at location addr in the USER area. We must
+                   disallow any changes to certain SR bits or u_fpvalid, since
+                   this could crash the kernel or result in a security
+                   loophole. */
+		ret = -EIO;
+		if ((addr & 3) || addr < 0)
+			break;
+
+		if (addr < sizeof(struct pt_regs)) {
+			/* Ignore change of top 32 bits of SR */
+			if (addr == offsetof (struct pt_regs, sr)+4)
+			{
+				ret = 0;
+				break;
+			}
+			/* If lower 32 bits of SR, ignore non-user bits */
+			if (addr == offsetof (struct pt_regs, sr))
+			{
+				long cursr = get_stack_long(child, addr);
+				data &= ~(SR_MASK);
+				data |= (cursr & SR_MASK); 
+			}
+			ret = put_stack_long(child, addr, data);
+		}
+		else if ((addr >= offsetof(struct user, fpu)) &&
+			 (addr <  offsetof(struct user, u_fpvalid))) {
+			ret = put_fpu_long(child, addr - offsetof(struct user, fpu), data);
+		}
+		break;
+
+	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+	case PTRACE_CONT: { /* restart after signal. */
+		ret = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+		if (request == PTRACE_SYSCALL)
+			child->ptrace |= PT_TRACESYS;
+		else
+			child->ptrace &= ~PT_TRACESYS;
+		child->exit_code = data;
+		wake_up_process(child);
+		ret = 0;
+		break;
+	}
+
+/*
+ * make the child exit.  Best I can do is send it a sigkill. 
+ * perhaps it should be put in the status that it wants to 
+ * exit.
+ */
+	case PTRACE_KILL: {
+		ret = 0;
+		if (child->state == TASK_ZOMBIE)	/* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		wake_up_process(child);
+		break;
+	}
+
+	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+		struct pt_regs *regs;
+
+		ret = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+		child->ptrace &= ~PT_TRACESYS;
+		if ((child->ptrace & PT_DTRACE) == 0) {
+			/* Spurious delayed TF traps may occur */
+			child->ptrace |= PT_DTRACE;
+		}
+
+		regs = child->thread.kregs;
+
+		regs->sr |= SR_SSTEP;	/* auto-resetting upon exception */
+
+		child->exit_code = data;
+		/* give it a chance to run. */
+		wake_up_process(child);
+		ret = 0;
+		break;
+	}
+
+	case PTRACE_DETACH:  /* detach a process that was attached. */
+		ret = ptrace_detach(child, data);
+		break;
+
+	case PTRACE_SETOPTIONS: {
+		if (data & PTRACE_O_TRACESYSGOOD)
+			child->ptrace |= PT_TRACESYSGOOD;
+		else
+			child->ptrace &= ~PT_TRACESYSGOOD;
+
+
+
+		ret = 0;
+		break;
+	}
+	default:
+		ret = -EIO;
+		break;
+	}
+out_tsk:
+	free_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+asmlinkage void syscall_trace(void)
+{
+	struct task_struct *tsk = current;
+
+	if ((tsk->ptrace & (PT_PTRACED|PT_TRACESYS))
+	    != (PT_PTRACED|PT_TRACESYS))
+		return;
+	tsk->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+				    ? 0x80 : 0);
+	tsk->state = TASK_STOPPED;
+	notify_parent(tsk, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (tsk->exit_code) {
+		send_sig(tsk->exit_code, tsk, 1);
+		tsk->exit_code = 0;
+	}
+}
+
+/* Called with interrupts disabled */
+asmlinkage void do_single_step(unsigned long long vec, struct pt_regs *regs)
+{
+	/* This is called after a single step exception (DEBUGSS).
+	   There is no need to change the PC, as it is a post-execution 
+	   exception, as entry.S does not do anything to the PC for DEBUGSS.
+	   We need to clear the Single Step setting in SR to avoid
+	   continually stepping. */
+	__sti();
+	regs->sr &= ~SR_SSTEP;
+	force_sig(SIGTRAP, current);
+}
+
+/* Called with interrupts disabled */
+asmlinkage void do_software_break_point(unsigned long long vec,
+					struct pt_regs *regs)
+{
+	/* We need to forward step the PC, to counteract the backstep done
+           in signal.c. */
+	__sti();
+	force_sig(SIGTRAP, current);
+        regs->pc += 4;
+}
+
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure single step bits etc are not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+        /* nothing to do.. */
+}
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/semaphore.c linux-2.4.22-pre3/arch/sh64/kernel/semaphore.c
--- linux-2.4.22-pre2/arch/sh64/kernel/semaphore.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/semaphore.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,137 @@
+/*
+ * Just taken from alpha implementation.
+ * This can't work well, perhaps.
+ */
+/*
+ *  Generic semaphore code. Buyer beware. Do your own
+ * specific changes in <asm/semaphore-helper.h>
+ */
+
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <asm/semaphore.h>
+#include <asm/semaphore-helper.h>
+
+spinlock_t semaphore_wake_lock;
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit.  ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore.  The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+void __up(struct semaphore *sem)
+{
+	wake_one_more(sem);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function.  Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible.  This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return.  If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+#define DOWN_VAR				\
+	struct task_struct *tsk = current;	\
+	wait_queue_t wait;			\
+	init_waitqueue_entry(&wait, tsk);
+
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	tsk->state = (task_state);					\
+	add_wait_queue(&sem->wait, &wait);				\
+									\
+	/*								\
+	 * Ok, we're set up.  sem->count is known to be less than zero	\
+	 * so we must wait.						\
+	 *								\
+	 * We can let go the lock for purposes of waiting.		\
+	 * We re-acquire it after awaking so as to protect		\
+	 * all semaphore operations.					\
+	 *								\
+	 * If "up()" is called before we call waking_non_zero() then	\
+	 * we will catch it right away.  If it is called later then	\
+	 * we will have to go through a wakeup cycle to catch it.	\
+	 *								\
+	 * Multiple waiters contend for the semaphore lock to see	\
+	 * who gets to gate through and who has to wait some more.	\
+	 */								\
+	for (;;) {
+
+#define DOWN_TAIL(task_state)			\
+		tsk->state = (task_state);	\
+	}					\
+	tsk->state = TASK_RUNNING;		\
+	remove_wait_queue(&sem->wait, &wait);
+
+void __down(struct semaphore * sem)
+{
+	DOWN_VAR
+	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
+	schedule();
+	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+	DOWN_VAR
+	DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+	ret = waking_non_zero_interruptible(sem, tsk);
+	if (ret)
+	{
+		if (ret == 1)
+			/* ret != 0 only if we get interrupted -arca */
+			ret = 0;
+		break;
+	}
+	schedule();
+	DOWN_TAIL(TASK_INTERRUPTIBLE)
+	return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+	return waking_non_zero_trylock(sem);
+}
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/setup.c linux-2.4.22-pre3/arch/sh64/kernel/setup.c
--- linux-2.4.22-pre2/arch/sh64/kernel/setup.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/setup.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,362 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/setup.c
+ *
+ * SH-5 Arch Support
+ *
+ * This file handles the architecture-dependent parts of initialization
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * benedict.gaster@superh.com:   2nd May 2002
+ *    Modified to use the empty_zero_page to pass command line arguments.
+ *
+ * benedict.gaster@superh.com:	 3rd May 2002
+ *    Added support for ramdisk, removing statically linked romfs at the same time.
+ *
+ * lethal@linux-sh.org:          15th May 2003
+ *    Added generic procfs cpuinfo reporting. Make boards just export their name.
+ *
+ * lethal@linux-sh.org:          25th May 2003
+ *    Added generic get_cpu_subtype() for subtype reporting from cpu_data->type.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+#include <linux/bootmem.h>
+#include <linux/console.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/platform.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+
+#ifdef CONFIG_VT
+#include <linux/console.h>
+#endif
+
+struct screen_info screen_info;
+
+/* On a PC this would be initialised as a result of the BIOS detecting the
+ * mouse. */
+unsigned char aux_device_present = 0xaa;
+
+#ifdef CONFIG_BLK_DEV_RAM
+extern int rd_doload;		/* 1 = load ramdisk, 0 = don't load */
+extern int rd_prompt;		/* 1 = prompt for ramdisk, 0 = don't prompt */
+extern int rd_image_start;	/* starting block # of image */
+#endif
+
+extern int root_mountflags;
+extern int _text, _etext, _edata, _end;
+extern char *get_system_type(void);
+extern void platform_setup(void);
+extern void platform_monitor(void);
+extern void platform_reserve(void);
+extern int sh64_cache_init(void);
+extern int sh64_tlb_init(void);
+
+#define RAMDISK_IMAGE_START_MASK  	0x07FF
+#define RAMDISK_PROMPT_FLAG		0x8000
+#define RAMDISK_LOAD_FLAG		0x4000	
+
+#define PARAM ((unsigned char *)empty_zero_page)
+#define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000))
+#define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004))
+#define ORIG_ROOT_DEV (*(unsigned long *) (PARAM+0x008))
+#define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c))
+#define INITRD_START (*(unsigned long *) (PARAM+0x010))
+#define INITRD_SIZE (*(unsigned long *) (PARAM+0x014))
+
+#define COMMAND_LINE ((char *) (PARAM+256))
+#define COMMAND_LINE_SIZE 256	
+
+static char command_line[COMMAND_LINE_SIZE] = { 0, };
+       char saved_command_line[COMMAND_LINE_SIZE];
+unsigned long long memory_start = CONFIG_MEMORY_START;
+unsigned long long memory_end = CONFIG_MEMORY_START + (CONFIG_MEMORY_SIZE_IN_MB * 1024 * 1024);
+
+struct sh_cpuinfo boot_cpu_data = { 
+	.type = CPU_SH5_101,
+};
+
+static inline void parse_mem_cmdline (char ** cmdline_p)
+{
+        char c = ' ', *to = command_line, *from = COMMAND_LINE;
+	int len = 0;
+
+	/* Save unparsed command line copy for /proc/cmdline */
+	memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
+	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+
+	for (;;) {
+	  /*
+	   * "mem=XXX[kKmM]" defines a size of memory.
+	   */
+	        if (c == ' ' && !memcmp(from, "mem=", 4)) {
+		      if (to != command_line)
+			to--;
+		      {
+			unsigned long mem_size;
+			
+			mem_size = memparse(from+4, &from);
+			memory_end = memory_start + mem_size;
+		      }
+		}
+		c = *(from++);
+		if (!c)
+		  break;
+		if (COMMAND_LINE_SIZE <= ++len)
+		  break;
+		*(to++) = c;
+	}
+	*to = '\0';
+
+	*cmdline_p = command_line;
+}
+
+void cpu_relax(void)
+{
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+	unsigned long bootmap_size, i;
+	unsigned long first_pfn, start_pfn, last_pfn, pages;
+
+	/*
+	 * Setup TLB mappings
+	 */
+	sh64_tlb_init();
+
+	/*
+	 * Caches are already initialized by the time we get here, so we just
+	 * fill in cpu_data info for the caches.
+	 */
+	sh64_cache_init();
+
+	platform_setup();
+	platform_monitor();
+
+	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
+
+#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
+
+	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 = __pa(&_text);
+	code_resource.end = __pa(&_etext)-1;
+	data_resource.start = __pa(&_etext);
+	data_resource.end = __pa(&_edata)-1;
+
+	parse_mem_cmdline(cmdline_p);
+
+	/*
+	 * Find the lowest and highest page frame numbers we have available
+	 */
+	first_pfn = PFN_DOWN(memory_start);
+	last_pfn = PFN_DOWN(memory_end);
+	pages = last_pfn - first_pfn;
+
+ 	/*
+	 * Partially used pages are not usable - thus
+	 * we are rounding upwards:
+ 	 */
+	start_pfn = PFN_UP(__pa(&_end));
+	/*
+	 * Find a proper area for the bootmem bitmap. After this
+	 * bootstrap step all allocations (until the page allocator
+	 * is intact) must be done via bootmem_alloc().
+	 */
+	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
+					 first_pfn, 
+					 last_pfn);
+        /*
+         * Round it up.
+         */
+        bootmap_size = PFN_PHYS(PFN_UP(bootmap_size));
+
+	/*
+	 * Register fully available RAM pages with the bootmem allocator.
+	 */
+	free_bootmem(PFN_PHYS(first_pfn), PFN_PHYS(pages));
+
+	/*
+	 * Reserve all kernel sections + bootmem bitmap + a guard page.
+	 */
+	reserve_bootmem(PFN_PHYS(first_pfn),
+		        (PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE) - PFN_PHYS(first_pfn));
+
+	/*
+	 * Reserve platform dependent sections
+	 */
+	platform_reserve();
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (LOADER_TYPE && INITRD_START) {
+		if (INITRD_START + INITRD_SIZE <= (PFN_PHYS(last_pfn))) {
+		        reserve_bootmem(INITRD_START + __MEMORY_START, INITRD_SIZE);
+
+			initrd_start =
+			  (long) INITRD_START ? INITRD_START + PAGE_OFFSET +  __MEMORY_START : 0;
+
+			initrd_end = initrd_start + INITRD_SIZE;
+		} else {
+			printk("initrd extends beyond end of memory "
+			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+				    (long) INITRD_START + INITRD_SIZE,
+				    PFN_PHYS(last_pfn));
+			initrd_start = 0;
+		}
+	}
+#endif
+
+	/*
+	 * Claim all RAM, ROM, and I/O resources.
+	 */
+
+	/* Kernel RAM */
+	request_resource(&iomem_resource, &code_resource);
+	request_resource(&iomem_resource, &data_resource);
+
+	/* Other KRAM space */
+	for (i = 0; i < STANDARD_KRAM_RESOURCES - 2; i++)
+		request_resource(&iomem_resource,
+				 &platform_parms.kram_res_p[i]);
+
+	/* XRAM space */
+	for (i = 0; i < STANDARD_XRAM_RESOURCES; i++)
+		request_resource(&iomem_resource,
+				 &platform_parms.xram_res_p[i]);
+
+	/* ROM space */
+	for (i = 0; i < STANDARD_ROM_RESOURCES; i++)
+		request_resource(&iomem_resource,
+				 &platform_parms.rom_res_p[i]);
+
+	/* I/O space */
+	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+		request_resource(&ioport_resource,
+				 &platform_parms.io_res_p[i]);
+
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+	conswitchp = &vga_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
+#endif
+#endif
+
+	printk("Hardware FPU: %s\n", fpu_in_use ? "enabled" : "disabled");
+
+	paging_init();
+}
+
+void __xchg_called_with_bad_pointer(void)
+{
+	printk(KERN_EMERG "xchg() called with bad pointer !\n");
+}
+
+/*
+ *	Get CPU information
+ */
+static const char *cpu_name[] = {
+	[CPU_SH5_101]	"SH5-101",
+	[CPU_SH5_103]	"SH5-103",
+	[CPU_SH_NONE]	"Unknown",
+};
+
+const char *get_cpu_subtype(void)
+{
+	return cpu_name[boot_cpu_data.type];
+}
+
+#ifdef CONFIG_PROC_FS
+static int show_cpuinfo(struct seq_file *m,void *v)
+{
+	unsigned int cpu = smp_processor_id();
+
+	if (!cpu)
+		seq_printf(m, "machine\t\t: %s\n", get_system_type());
+
+	seq_printf(m, "processor\t: %d\n", cpu);
+	seq_printf(m, "cpu family\t: SH-5\n");
+	seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype());
+
+	seq_printf(m, "icache size\t: %dK-bytes\n",
+		   (boot_cpu_data.icache.ways *
+		    boot_cpu_data.icache.sets *
+		    boot_cpu_data.icache.linesz) >> 10);
+	seq_printf(m, "dcache size\t: %dK-bytes\n",
+		   (boot_cpu_data.dcache.ways *
+		    boot_cpu_data.dcache.sets *
+		    boot_cpu_data.dcache.linesz) >> 10);
+	seq_printf(m, "itlb entries\t: %d\n", boot_cpu_data.itlb.entries);
+	seq_printf(m, "dtlb entries\t: %d\n", boot_cpu_data.dtlb.entries);
+
+#define PRINT_CLOCK(name, value) \
+	seq_printf(m, name " clock\t: %d.%02dMHz\n", \
+		     ((value) / 1000000), ((value) % 1000000)/10000)
+	
+	PRINT_CLOCK("cpu", boot_cpu_data.cpu_clock);
+	PRINT_CLOCK("bus", boot_cpu_data.bus_clock);
+	PRINT_CLOCK("module", boot_cpu_data.module_clock);
+
+        seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
+		     (loops_per_jiffy*HZ+2500)/500000,
+		     ((loops_per_jiffy*HZ+2500)/5000) % 100);
+
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	return (void*)(*pos == 0);
+}
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	return NULL;
+}
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+struct seq_operations cpuinfo_op = {
+	start:	c_start,
+	next:	c_next,
+	stop:	c_stop,
+	show:	show_cpuinfo,
+};
+#endif /* CONFIG_PROC_FS */
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/sh_ksyms.c linux-2.4.22-pre3/arch/sh64/kernel/sh_ksyms.c
--- linux-2.4.22-pre2/arch/sh64/kernel/sh_ksyms.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/sh_ksyms.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,90 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/sh_ksyms.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <linux/config.h>
+
+
+#if 0
+#ifdef CONFIG_MODVERSIONS
+#define EXPORT_SYMTAB 1
+#endif
+#endif
+
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/mca.h>
+#include <linux/sched.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
+
+#include <asm/semaphore.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/checksum.h>
+#include <asm/io.h>
+#include <asm/hardirq.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern int dump_fpu(elf_fpregset_t *);
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
+extern struct drive_info_struct drive_info;
+EXPORT_SYMBOL(drive_info);
+#endif
+
+/* platform dependent support */
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(dump_fpu);
+EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(kernel_thread);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+EXPORT_SYMBOL(strtok);
+EXPORT_SYMBOL(strpbrk);
+EXPORT_SYMBOL(strstr);
+
+#ifdef CONFIG_VT
+EXPORT_SYMBOL(screen_info);
+#endif
+
+EXPORT_SYMBOL_NOVERS(__down);
+EXPORT_SYMBOL_NOVERS(__down_trylock);
+EXPORT_SYMBOL_NOVERS(__up);
+EXPORT_SYMBOL_NOVERS(__put_user_asm_l);
+EXPORT_SYMBOL_NOVERS(__get_user_asm_l);
+EXPORT_SYMBOL_NOVERS(memcmp);
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(strchr);
+EXPORT_SYMBOL_NOVERS(strlen);
+
+EXPORT_SYMBOL(flush_dcache_page);
+
+/* Ugh.  These come in from libgcc.a at link time. */
+
+extern void __sdivsi3(void);
+extern void __muldi3(void);
+extern void __udivsi3(void);
+EXPORT_SYMBOL_NOVERS(__sdivsi3);
+EXPORT_SYMBOL_NOVERS(__muldi3);
+EXPORT_SYMBOL_NOVERS(__udivsi3);
+
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/signal.c linux-2.4.22-pre3/arch/sh64/kernel/signal.c
--- linux-2.4.22-pre2/arch/sh64/kernel/signal.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/signal.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,821 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/signal.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * Started from sh version.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/personality.h>
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+
+#define REG_RET 9
+#define REG_ARG1 2
+#define REG_ARG2 3
+#define REG_SP 15
+#define REG_PR 18
+#define REF_REG_RET regs->regs[REG_RET]
+#define REF_REG_SP regs->regs[REG_SP]
+#define DEREF_REG_PR regs->regs[REG_PR]
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+
+asmlinkage int
+sys_sigsuspend(old_sigset_t mask,
+	       unsigned long r3, unsigned long r4, unsigned long r5,
+	       unsigned long r6, unsigned long r7,
+	       struct pt_regs * regs)
+{
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	REF_REG_RET = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		regs->pc += 4;    /* because sys_sigreturn decrements the pc */
+		if (do_signal (regs, &saveset))
+		{	/* pc now points at signal handler. Need to decrement
+			   it because entry.S will increment it. */
+			regs->pc -= 4;
+			return -EINTR;
+		}
+	}
+}
+
+asmlinkage int
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
+	          unsigned long r4, unsigned long r5, unsigned long r6,
+	          unsigned long r7,
+	          struct pt_regs * regs)
+{
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	REF_REG_RET = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		regs->pc += 4;    /* because sys_sigreturn decrements the pc */
+		if (do_signal (regs, &saveset))
+		{	/* pc now points at signal handler. Need to decrement
+			   it because entry.S will increment it. */
+			regs->pc -= 4;
+			return -EINTR;
+		}
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss,
+	        unsigned long r4, unsigned long r5, unsigned long r6,
+	        unsigned long r7,
+	        struct pt_regs * regs)
+{
+	return do_sigaltstack(uss, uoss, REF_REG_SP);
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe
+{
+	struct sigcontext sc;
+	unsigned long extramask[_NSIG_WORDS-1];
+	long long retcode[2];
+};
+
+struct rt_sigframe
+{
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+	long long retcode[2];
+};
+
+#ifndef CONFIG_NOFPU_SUPPORT
+static inline int
+restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int err = 0;
+	int fpvalid;
+
+	err |= __get_user (fpvalid, &sc->sc_fpvalid); 
+	current->used_math = fpvalid;
+	if (! fpvalid)
+		return err;
+
+	if (current == last_task_used_math) {
+		last_task_used_math = NULL;
+		regs->sr |= SR_FD;
+	}
+
+	err |= __copy_from_user(&current->thread.fpu.hard, &sc->sc_fpregs[0],
+				(sizeof(long long) * 32) + (sizeof(int) * 1));
+
+	return err;
+}
+
+static inline int
+setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int err = 0;
+	int fpvalid;
+
+	fpvalid = current->used_math;
+	err |= __put_user(fpvalid, &sc->sc_fpvalid);
+	if (! fpvalid)
+		return err;
+
+	if (current == last_task_used_math) {
+		grab_fpu();
+		fpsave(&current->thread.fpu.hard);
+		release_fpu();
+		last_task_used_math = NULL;
+		regs->sr |= SR_FD;
+	}
+
+	err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.fpu.hard,
+			      (sizeof(long long) * 32) + (sizeof(int) * 1));
+	current->used_math = 0;
+
+	return err;
+}
+#else
+static inline int
+restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext *sc)
+{}
+static inline int
+setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext *sc)
+{}
+#endif
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, long long *r2_p)
+{
+	unsigned int err = 0;
+
+#define COPY(x)		err |= __get_user(regs->x, &sc->sc_##x)
+
+	COPY(regs[0]);	COPY(regs[1]);	COPY(regs[2]);	COPY(regs[3]);
+	COPY(regs[4]);	COPY(regs[5]);	COPY(regs[6]);	COPY(regs[7]);
+	COPY(regs[8]);	COPY(regs[9]);  COPY(regs[10]);	COPY(regs[11]);
+	COPY(regs[12]);	COPY(regs[13]);	COPY(regs[14]);	COPY(regs[15]);
+	COPY(regs[16]);	COPY(regs[17]);	COPY(regs[18]);	COPY(regs[19]);
+	COPY(regs[20]);	COPY(regs[21]);	COPY(regs[22]);	COPY(regs[23]);
+	COPY(regs[24]);	COPY(regs[25]);	COPY(regs[26]);	COPY(regs[27]);
+	COPY(regs[28]);	COPY(regs[29]);	COPY(regs[30]);	COPY(regs[31]);
+	COPY(regs[32]);	COPY(regs[33]);	COPY(regs[34]);	COPY(regs[35]);
+	COPY(regs[36]);	COPY(regs[37]);	COPY(regs[38]);	COPY(regs[39]);
+	COPY(regs[40]);	COPY(regs[41]);	COPY(regs[42]);	COPY(regs[43]);
+	COPY(regs[44]);	COPY(regs[45]);	COPY(regs[46]);	COPY(regs[47]);
+	COPY(regs[48]);	COPY(regs[49]);	COPY(regs[50]);	COPY(regs[51]);
+	COPY(regs[52]);	COPY(regs[53]);	COPY(regs[54]);	COPY(regs[55]);
+	COPY(regs[56]);	COPY(regs[57]);	COPY(regs[58]);	COPY(regs[59]);
+	COPY(regs[60]);	COPY(regs[61]);	COPY(regs[62]);
+	COPY(tregs[0]);	COPY(tregs[1]);	COPY(tregs[2]);	COPY(tregs[3]);
+	COPY(tregs[4]);	COPY(tregs[5]);	COPY(tregs[6]);	COPY(tregs[7]);
+	COPY(sr);	COPY(pc);
+
+#undef COPY
+
+	/* Must do this last in case it sets regs->sr.fd (i.e. after rest of sr
+	 * has been restored above.) */
+	err |= restore_sigcontext_fpu(regs, sc);
+
+	regs->syscall_nr = -1;		/* disable syscall checks */
+	err |= __get_user(*r2_p, &sc->sc_regs[REG_RET]);
+	return err;
+}
+
+asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3,
+				   unsigned long r4, unsigned long r5,
+				   unsigned long r6, unsigned long r7,
+				   struct pt_regs * regs)
+{
+	struct sigframe *frame = (struct sigframe *) (long) REF_REG_SP;
+	sigset_t set;
+	long long ret;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__get_user(set.sig[0], &frame->sc.oldmask)
+	    || (_NSIG_WORDS > 1
+		&& __copy_from_user(&set.sig[1], &frame->extramask,
+				    sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(regs, &frame->sc, &ret))
+		goto badframe;
+	regs->pc -= 4;
+
+	return (int) ret;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
+				unsigned long r4, unsigned long r5,
+				unsigned long r6, unsigned long r7,
+				struct pt_regs * regs)
+{
+	struct rt_sigframe *frame = (struct rt_sigframe *) (long) REF_REG_SP;
+	sigset_t set;
+	stack_t st;
+	long long ret;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret))
+		goto badframe;
+	regs->pc -= 4;
+
+	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
+		goto badframe;
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, REF_REG_SP);
+
+	return (int) ret;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}	
+
+/*
+ * Set up a signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+		 unsigned long mask)
+{
+	int err = 0;
+
+	/* Do this first, otherwise is this sets sr->fd, that value isn't preserved. */
+	err |= setup_sigcontext_fpu(regs, sc);
+
+#define COPY(x)		err |= __put_user(regs->x, &sc->sc_##x)
+
+	COPY(regs[0]);	COPY(regs[1]);	COPY(regs[2]);	COPY(regs[3]);
+	COPY(regs[4]);	COPY(regs[5]);	COPY(regs[6]);	COPY(regs[7]);
+	COPY(regs[8]);	COPY(regs[9]);	COPY(regs[10]);	COPY(regs[11]);
+	COPY(regs[12]);	COPY(regs[13]);	COPY(regs[14]);	COPY(regs[15]);
+	COPY(regs[16]);	COPY(regs[17]);	COPY(regs[18]);	COPY(regs[19]);
+	COPY(regs[20]);	COPY(regs[21]);	COPY(regs[22]);	COPY(regs[23]);
+	COPY(regs[24]);	COPY(regs[25]);	COPY(regs[26]);	COPY(regs[27]);
+	COPY(regs[28]);	COPY(regs[29]);	COPY(regs[30]);	COPY(regs[31]);
+	COPY(regs[32]);	COPY(regs[33]);	COPY(regs[34]);	COPY(regs[35]);
+	COPY(regs[36]);	COPY(regs[37]);	COPY(regs[38]);	COPY(regs[39]);
+	COPY(regs[40]);	COPY(regs[41]);	COPY(regs[42]);	COPY(regs[43]);
+	COPY(regs[44]);	COPY(regs[45]);	COPY(regs[46]);	COPY(regs[47]);
+	COPY(regs[48]);	COPY(regs[49]);	COPY(regs[50]);	COPY(regs[51]);
+	COPY(regs[52]);	COPY(regs[53]);	COPY(regs[54]);	COPY(regs[55]);
+	COPY(regs[56]);	COPY(regs[57]);	COPY(regs[58]);	COPY(regs[59]);
+	COPY(regs[60]);	COPY(regs[61]);	COPY(regs[62]);
+	COPY(tregs[0]);	COPY(tregs[1]);	COPY(tregs[2]);	COPY(tregs[3]);
+	COPY(tregs[4]);	COPY(tregs[5]);	COPY(tregs[6]);	COPY(tregs[7]);
+	COPY(sr);	COPY(pc);
+
+#undef COPY
+
+	err |= __put_user(mask, &sc->oldmask);
+
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
+{
+	if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	return (void *)((sp - frame_size) & -8ul);
+}
+
+void sa_default_restorer(void);		/* See comments below */
+void sa_default_rt_restorer(void);	/* See comments below */
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+			sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current->exec_domain
+		&& current->exec_domain->signal_invmap
+		&& sig < 32
+		? current->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+
+	/* Give up earlier as i386, in case */
+	if (err)
+		goto give_sigsegv;
+
+	if (_NSIG_WORDS > 1) {
+		err |= __copy_to_user(frame->extramask, &set->sig[1],
+				      sizeof(frame->extramask));
+	}
+
+	/* Give up earlier as i386, in case */
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1;
+
+		/*
+		 * On SH5 all edited pointers are subject to NEFF
+		 */
+		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
+        		 	(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+	} else {
+		/*
+		 * Different approach on SH5.
+	         * . Endianness independent asm code gets placed in entry.S .
+		 *   This is limited to four ASM instructions corresponding
+		 *   to two long longs in size.
+		 * . err checking is done on the else branch only
+		 * . flush_icache_range() is called upon __put_user() only
+		 * . all edited pointers are subject to NEFF
+		 * . being code, linker turns ShMedia bit on, always
+		 *   dereference index -1.
+		 */
+		DEREF_REG_PR = (unsigned long) frame->retcode | 0x01;
+		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
+        		 	(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+
+		if (__copy_to_user(frame->retcode,
+			(unsigned long long)sa_default_restorer & (~1), 16) != 0)
+			goto give_sigsegv;
+
+		/* Cohere the trampoline with the I-cache. */
+		flush_cache_sigtramp(DEREF_REG_PR-1, DEREF_REG_PR-1+16);
+	}
+
+	/*
+	 * Set up registers for signal handler.
+	 * All edited pointers are subject to NEFF.
+	 */
+	regs->regs[REG_SP] = (unsigned long) frame;
+	regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
+        		 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
+	regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
+	regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+	regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc;
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	/* Broken %016Lx */
+	printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
+		signal,
+		current->comm, current->pid, frame,
+		regs->pc >> 32, regs->pc & 0xffffffff,
+		DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			   sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current->exec_domain
+		&& current->exec_domain->signal_invmap
+		&& sig < 32
+		? current->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Give up earlier as i386, in case */
+	if (err)
+		goto give_sigsegv;
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->regs[REG_SP]),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= setup_sigcontext(&frame->uc.uc_mcontext,
+			        regs, set->sig[0]);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Give up earlier as i386, in case */
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1;
+
+		/*
+		 * On SH5 all edited pointers are subject to NEFF
+		 */
+		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
+        		 	(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+	} else {
+		/*
+		 * Different approach on SH5.
+	         * . Endianness independent asm code gets placed in entry.S .
+		 *   This is limited to four ASM instructions corresponding
+		 *   to two long longs in size.
+		 * . err checking is done on the else branch only
+		 * . flush_icache_range() is called upon __put_user() only
+		 * . all edited pointers are subject to NEFF
+		 * . being code, linker turns ShMedia bit on, always
+		 *   dereference index -1.
+		 */
+
+		DEREF_REG_PR = (unsigned long) frame->retcode | 0x01;
+		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
+        		 	(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+
+		if (__copy_to_user(frame->retcode,
+			(unsigned long long)sa_default_rt_restorer & (~1), 16) != 0)
+			goto give_sigsegv;
+
+		flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
+	}
+
+	/*
+	 * Set up registers for signal handler.
+	 * All edited pointers are subject to NEFF.
+	 */
+	regs->regs[REG_SP] = (unsigned long) frame;
+	regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
+        		 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
+	regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
+	regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+	regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc;
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	/* Broken %016Lx */
+	printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
+		signal,
+		current->comm, current->pid, frame,
+		regs->pc >> 32, regs->pc & 0xffffffff,
+		DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+/*
+ * OK, we're invoking a handler
+ */	
+
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
+{
+	/* Are we from a system call? */
+	if (regs->syscall_nr >= 0) {
+		/* If so, check system call restarting.. */
+		switch (regs->regs[REG_RET]) {
+			case -ERESTARTNOHAND:
+				regs->regs[REG_RET] = -EINTR;
+				break;
+
+			case -ERESTARTSYS:
+				if (!(ka->sa.sa_flags & SA_RESTART)) {
+					regs->regs[REG_RET] = -EINTR;
+					break;
+				}
+			/* fallthrough */
+			case -ERESTARTNOINTR:
+				/* Decode syscall # */
+				regs->regs[REG_RET] = regs->syscall_nr;
+				regs->pc -= 4;
+		}
+	}
+
+	/* Set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+int do_signal(struct pt_regs *regs, sigset_t *oldset)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		unsigned long signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Let the debugger run.  */
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				continue;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+			        sig_exit(signr, exit_code, &info);
+				/* NOTREACHED */ 
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (regs->syscall_nr >= 0) {
+		/* Restart the system call - no handlers present */
+		if (regs->regs[REG_RET] == -ERESTARTNOHAND ||
+		    regs->regs[REG_RET] == -ERESTARTSYS ||
+		    regs->regs[REG_RET] == -ERESTARTNOINTR) {
+			/* Decode Syscall # */
+			regs->regs[REG_RET] = regs->syscall_nr;
+			regs->pc -= 4;
+		}
+	}
+	return 0;
+}
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/sys_sh64.c linux-2.4.22-pre3/arch/sh64/kernel/sys_sh64.c
--- linux-2.4.22-pre2/arch/sh64/kernel/sys_sh64.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/sys_sh64.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,309 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/sys_sh64.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/SH5
+ * platform.
+ *
+ * Mostly taken from i386 version.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+#include <asm/ptrace.h>
+
+#define REG_3	3
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way Unix traditionally does this, though.
+ */
+#ifdef NEW_PIPE_IMPLEMENTATION
+asmlinkage int sys_pipe(unsigned long * fildes,
+			unsigned long   dummy_r3,
+			unsigned long   dummy_r4,
+			unsigned long   dummy_r5,
+			unsigned long   dummy_r6,
+			unsigned long   dummy_r7,
+			struct pt_regs * regs)	   /* r8 = pt_regs  forced by entry.S */
+{
+	int fd[2];
+	int ret;
+
+	ret = do_pipe(fd);
+	if (ret == 0)
+		/*
+		 ***********************************************************************  
+		 *   To avoid the copy_to_user we prefer to break the ABIs convention, *
+		 *   packing the valid pair of file IDs into a single register (r3);   *
+		 *   while r2 is the return code as defined by the sh5-ABIs.	       *
+		 *   BE CAREFUL: pipe stub, into glibc, must be aware of this solution *
+		 ***********************************************************************
+
+#ifdef __LITTLE_ENDIAN__
+		regs->regs[REG_3] = (((unsigned long long) fd[1]) << 32) | ((unsigned long long) fd[0]);
+#else
+		regs->regs[REG_3] = (((unsigned long long) fd[0]) << 32) | ((unsigned long long) fd[1]);
+#endif
+
+		*/
+	       /* although not very clever this is endianess independent */
+		regs->regs[REG_3] = (unsigned long long) *((unsigned long long *) fd);
+
+	return ret;
+}
+
+#else
+asmlinkage int sys_pipe(unsigned long * fildes)
+{
+        int fd[2];
+        int error;
+
+        error = do_pipe(fd);
+        if (!error) {
+                if (copy_to_user(fildes, fd, 2*sizeof(int)))
+                        error = -EFAULT;
+        }
+        return error;
+}
+
+#endif
+
+/*
+ * To avoid cache alias, we map the shard page with same color.
+ */
+#define COLOUR_ALIGN(addr)	(((addr)+SHMLBA-1)&~(SHMLBA-1))
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+	unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct *vma;
+
+	if (flags & MAP_FIXED) {
+		/* We do not accept a shared mapping if it would violate
+		 * cache aliasing constraints.
+		 */
+		if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
+			return -EINVAL;
+		return addr;
+	}
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+	if (!addr)
+		addr = TASK_UNMAPPED_BASE;
+
+	if (flags & MAP_PRIVATE)
+		addr = PAGE_ALIGN(addr);
+	else
+		addr = COLOUR_ALIGN(addr);
+
+	for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+		/* At this point:  (!vma || addr < vma->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return -ENOMEM;
+		if (!vma || addr + len <= vma->vm_start)
+			return addr;
+		addr = vma->vm_end;
+		if (!(flags & MAP_PRIVATE))
+			addr = COLOUR_ALIGN(addr);
+	}
+}
+
+asmlinkage long sys_shmatcall(int shmid, void *shmaddr, int shmflg)
+{
+        unsigned long raddr;
+        long err;
+
+        lock_kernel();
+        err = sys_shmat(shmid, shmaddr, shmflg, &raddr);
+        if (err)
+                goto out_shmatcall;
+
+        err = raddr;
+out_shmatcall:
+        unlock_kernel();
+        return err;
+}
+
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+asmlinkage int old_mmap(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	int fd, unsigned long off)
+{
+	if (off & ~PAGE_MASK)
+		return -EINVAL;
+	return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
+}
+
+/*******************************************************************
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls...	   *
+ *								   *
+ * This is really horribly ugly.				   *
+ * ---								   *
+ * True! But this is a obsolete ipc system calls implementation;   *
+ * infact, all ipc system calls are called, such as alpha and	   *
+ * ia64 systems, without the "de-multiplexer" routine (except the  *
+ * shmat syscall that is called by the sys_shmatcall function).    *
+ * ---								   *
+ *								   *
+ *******************************************************************/
+asmlinkage int sys_ipc(uint call, int first, int second,
+		       int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	if (call <= SEMCTL)
+		switch (call) {
+		case SEMOP:
+			return sys_semop (first, (struct sembuf *)ptr, second);
+		case SEMGET:
+			return sys_semget (first, second, third);
+		case SEMCTL: {
+			union semun fourth;
+			if (!ptr)
+				return -EINVAL;
+			if (get_user(fourth.__pad, (void **) ptr))
+				return -EFAULT;
+			return sys_semctl (first, second, third, fourth);
+			}
+		default:
+			return -EINVAL;
+		}
+
+	if (call <= MSGCTL) 
+		switch (call) {
+		case MSGSND:
+			return sys_msgsnd (first, (struct msgbuf *) ptr, 
+					  second, third);
+		case MSGRCV:
+			switch (version) {
+			case 0: {
+				struct ipc_kludge tmp;
+				if (!ptr)
+					return -EINVAL;
+				
+				if (copy_from_user(&tmp,
+						   (struct ipc_kludge *) ptr, 
+						   sizeof (tmp)))
+					return -EFAULT;
+				return sys_msgrcv (first, tmp.msgp, second,
+						   tmp.msgtyp, third);
+				}
+			default:
+				return sys_msgrcv (first,
+						   (struct msgbuf *) ptr,
+						   second, fifth, third);
+			}
+		case MSGGET:
+			return sys_msgget ((key_t) first, second);
+		case MSGCTL:
+			return sys_msgctl (first, second,
+					   (struct msqid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+	if (call <= SHMCTL) 
+		switch (call) {
+		case SHMAT:
+			switch (version) {
+			default: {
+				ulong raddr;
+				ret = sys_shmat (first, (char *) ptr,
+						 second, &raddr);
+				if (ret)
+					return ret;
+				return put_user (raddr, (ulong *) third);
+			}
+			case 1:	/* iBCS2 emulator entry point */
+				if (!segment_eq(get_fs(), get_ds()))
+					return -EINVAL;
+				return sys_shmat (first, (char *) ptr,
+						  second, (ulong *) third);
+			}
+		case SHMDT: 
+			return sys_shmdt ((char *)ptr);
+		case SHMGET:
+			return sys_shmget (first, second, third);
+		case SHMCTL:
+			return sys_shmctl (first, second,
+					   (struct shmid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+	
+	return -EINVAL;
+}
+
+asmlinkage int sys_uname(struct old_utsname * name)
+{
+	int err;
+	if (!name)
+		return -EFAULT;
+	down_read(&uts_sem);
+	err=copy_to_user(name, &system_utsname, sizeof (*name));
+	up_read(&uts_sem);
+	return err?-EFAULT:0;
+}
+
+asmlinkage int sys_pause(void)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	return -ERESTARTNOHAND;
+}
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/time.c linux-2.4.22-pre3/arch/sh64/kernel/time.c
--- linux-2.4.22-pre2/arch/sh64/kernel/time.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/time.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,585 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/time.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ *    Original TMU/RTC code taken from sh version.
+ *    Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
+ *      Some code taken from i386 version.
+ *      Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/registers.h>	 /* required by inline __asm__ stmt. */
+
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+
+#include <linux/timex.h>
+#include <linux/irq.h>
+#include <asm/hardware.h>
+
+#define TMU_TOCR_INIT	0x00
+#define TMU0_TCR_INIT	0x0020
+#define TMU_TSTR_INIT	1
+
+/* RCR1 Bits */
+#define RCR1_CF		0x80	/* Carry Flag             */
+#define RCR1_CIE	0x10	/* Carry Interrupt Enable */
+#define RCR1_AIE	0x08	/* Alarm Interrupt Enable */
+#define RCR1_AF		0x01	/* Alarm Flag             */
+
+/* RCR2 Bits */
+#define RCR2_PEF	0x80	/* PEriodic interrupt Flag */
+#define RCR2_PESMASK	0x70	/* Periodic interrupt Set  */
+#define RCR2_RTCEN	0x08	/* ENable RTC              */
+#define RCR2_ADJ	0x04	/* ADJustment (30-second)  */
+#define RCR2_RESET	0x02	/* Reset bit               */
+#define RCR2_START	0x01	/* Start bit               */
+
+/* Clock, Power and Reset Controller */
+#define	CPRC_BLOCK_OFF	0x01010000
+#define CPRC_BASE	PHYS_PERIPHERAL_BLOCK + CPRC_BLOCK_OFF
+
+#define FRQCR		(cprc_base+0x0)
+#define WTCSR		(cprc_base+0x0018)
+#define STBCR		(cprc_base+0x0030)
+
+/* Time Management Unit */
+#define	TMU_BLOCK_OFF	0x01020000
+#define TMU_BASE	PHYS_PERIPHERAL_BLOCK + TMU_BLOCK_OFF
+#define TMU0_BASE	tmu_base + 0x8 + (0xc * 0x0)
+#define TMU1_BASE	tmu_base + 0x8 + (0xc * 0x1)
+#define TMU2_BASE	tmu_base + 0x8 + (0xc * 0x2)
+
+#define TMU_TOCR	tmu_base+0x0	/* Byte access */
+#define TMU_TSTR	tmu_base+0x4	/* Byte access */
+
+#define TMU0_TCOR	TMU0_BASE+0x0	/* Long access */
+#define TMU0_TCNT	TMU0_BASE+0x4	/* Long access */
+#define TMU0_TCR	TMU0_BASE+0x8	/* Word access */
+
+/* Real Time Clock */
+#define	RTC_BLOCK_OFF	0x01040000
+#define RTC_BASE	PHYS_PERIPHERAL_BLOCK + RTC_BLOCK_OFF
+
+#define R64CNT  	rtc_base+0x00
+#define RSECCNT 	rtc_base+0x04
+#define RMINCNT 	rtc_base+0x08
+#define RHRCNT  	rtc_base+0x0c
+#define RWKCNT  	rtc_base+0x10
+#define RDAYCNT 	rtc_base+0x14
+#define RMONCNT 	rtc_base+0x18
+#define RYRCNT  	rtc_base+0x1c	/* 16bit */
+#define RSECAR  	rtc_base+0x20
+#define RMINAR  	rtc_base+0x24
+#define RHRAR   	rtc_base+0x28
+#define RWKAR   	rtc_base+0x2c
+#define RDAYAR  	rtc_base+0x30
+#define RMONAR  	rtc_base+0x34
+#define RCR1    	rtc_base+0x38
+#define RCR2    	rtc_base+0x3c
+
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+extern rwlock_t xtime_lock;
+#define TICK_SIZE tick
+
+extern unsigned long wall_jiffies;
+extern unsigned long volatile jiffies;
+
+static unsigned long tmu_base, rtc_base, cprc_base;
+
+/* Variables to allow interpolation of time of day to resolution better than a
+ * jiffy. */
+
+/* This is effectively protected by xtime_lock */
+static unsigned long ctc_last_interrupt;
+static unsigned long long usecs_per_jiffy = 1000000/HZ; /* Approximation */
+
+#define CTC_JIFFY_SCALE_SHIFT 40
+
+/* 2**CTC_JIFFY_SCALE_SHIFT / ctc_ticks_per_jiffy */
+static unsigned long long scaled_recip_ctc_ticks_per_jiffy;
+
+/* Estimate number of microseconds that have elapsed since the last timer tick,
+   by scaling the delta that has occured in the CTC register.
+
+   WARNING WARNING WARNING : This algorithm relies on the CTC decrementing at
+   the CPU clock rate.  If the CPU sleeps, the CTC stops counting.  Bear this
+   in mind if enabling SLEEP_WORKS in process.c.  In that case, this algorithm
+   probably needs to use TMU.TCNT0 instead.  This will work even if the CPU is
+   sleeping, though will be coarser.
+
+   FIXME : What if usecs_per_tick is moving around too much, e.g. if an adjtime
+   is running or if the freq or tick arguments of adjtimex are modified after
+   we have calibrated the scaling factor?  This will result in either a jump at
+   the end of a tick period, or a wrap backwards at the start of the next one,
+   if the application is reading the time of day often enough.  I think we
+   ought to do better than this.  For this reason, usecs_per_jiffy is left
+   separated out in the calculation below.  This allows some future hook into
+   the adjtime-related stuff in kernel/timer.c to remove this hazard.
+
+*/
+
+static unsigned long usecs_since_tick(void)
+{
+	unsigned long long current_ctc;
+	long ctc_ticks_since_interrupt;
+	unsigned long long ull_ctc_ticks_since_interrupt;
+	unsigned long result;
+
+	unsigned long long mul1_out;
+	unsigned long long mul1_out_high;
+	unsigned long long mul2_out_low, mul2_out_high;
+	
+	/* Read CTC register */
+	asm ("getcon cr62, %0" : "=r" (current_ctc));
+	/* Note, the CTC counts down on each CPU clock, not up.
+	   Note(2), use long type to get correct wraparound arithmetic when
+	   the counter crosses zero. */
+	ctc_ticks_since_interrupt = (long) ctc_last_interrupt - (long) current_ctc;
+	ull_ctc_ticks_since_interrupt = (unsigned long long) ctc_ticks_since_interrupt;
+
+	/* Inline assembly to do 32x32x32->64 multiplier */
+	asm volatile ("mulu.l %1, %2, %0" :
+	     "=r" (mul1_out) :
+	     "r" (ull_ctc_ticks_since_interrupt), "r" (usecs_per_jiffy));
+	
+	mul1_out_high = mul1_out >> 32;
+
+	asm volatile ("mulu.l %1, %2, %0" :
+	     "=r" (mul2_out_low) :
+	     "r" (mul1_out), "r" (scaled_recip_ctc_ticks_per_jiffy));
+
+#if 1
+	asm volatile ("mulu.l %1, %2, %0" :
+	     "=r" (mul2_out_high) :
+	     "r" (mul1_out_high), "r" (scaled_recip_ctc_ticks_per_jiffy));
+#endif
+
+	result = (unsigned long) (((mul2_out_high << 32) + mul2_out_low) >> CTC_JIFFY_SCALE_SHIFT);
+
+	return result;
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+	unsigned long usec, sec;
+
+	read_lock_irqsave(&xtime_lock, flags);
+	usec = usecs_since_tick();
+	{
+		unsigned long lost = jiffies - wall_jiffies;
+		if (lost)
+			usec += lost * (1000000 / HZ);
+	}
+	sec = xtime.tv_sec;
+	usec += xtime.tv_usec;
+	read_unlock_irqrestore(&xtime_lock, flags);
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq(&xtime_lock);
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_unlock_irq(&xtime_lock);
+}
+
+static int set_rtc_time(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+
+	ctrl_outb(RCR2_RESET, RCR2);  /* Reset pre-scaler & stop RTC */
+
+	cmos_minutes = ctrl_inb(RMINCNT);
+	BCD_TO_BIN(cmos_minutes);
+
+	/*
+	 * since we're only adjusting minutes and seconds,
+	 * don't interfere with hour overflow. This avoids
+	 * messing with unknown time zones but requires your
+	 * RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+		real_minutes += 30;	/* correct for half hour time zone */
+	real_minutes %= 60;
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		BIN_TO_BCD(real_seconds);
+		BIN_TO_BCD(real_minutes);
+		ctrl_outb(real_seconds, RSECCNT);
+		ctrl_outb(real_minutes, RMINCNT);
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_time: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+		retval = -1;
+	}
+
+	ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2);  /* Start RTC */
+
+	return retval;
+}
+
+/* last time the RTC clock got updated */
+static long last_rtc_update = 0;
+
+static inline void sh64_do_profile(unsigned long pc)
+{
+	extern int _stext;
+
+	/* Don't profile cpu_idle..  */
+	if (!prof_buffer || !current->pid)
+		return;
+
+	pc -= (unsigned long) &_stext;
+	pc >>= prof_shift;
+
+	/*
+	 * Don't ignore out-of-bounds PC values silently, put them into the
+	 * last histogram slot, so if present, they will show up as a sharp
+	 * peak.
+	 */
+	if (pc > prof_len - 1)
+		pc = prof_len - 1;
+
+	/* We could just be sloppy and not lock against a re-entry on this
+	   increment, but the profiling code won't always be linked in anyway. */
+	atomic_inc((atomic_t *)&prof_buffer[pc]);
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long long current_ctc;
+	asm ("getcon cr62, %0" : "=r" (current_ctc));
+	ctc_last_interrupt = (unsigned long) current_ctc;
+	
+	do_timer(regs);
+
+	if (!user_mode(regs))
+		sh64_do_profile(regs->pc);
+
+#ifdef CONFIG_HEARTBEAT
+	extern void heartbeat(void);
+
+        heartbeat();
+#endif
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+		if (set_rtc_time(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+}
+
+/*
+ * This is the same as the above, except we _also_ save the current
+ * Time Stamp Counter value at the time of the timer interrupt, so that
+ * we later on can estimate the time of day more exactly.
+ */
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long timer_status;
+
+	/* Clear UNF bit */
+	timer_status = ctrl_inw(TMU0_TCR);
+	timer_status &= ~0x100;
+	ctrl_outw(timer_status, TMU0_TCR);
+	
+	/*
+	 * Here we are in the timer irq handler. We just have irqs locally
+	 * disabled but we don't know if the timer_bh is running on the other
+	 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
+	 * the irq version of write_lock because as just said we have irq
+	 * locally disabled. -arca
+	 */
+	write_lock(&xtime_lock);
+	do_timer_interrupt(irq, NULL, regs);
+	write_unlock(&xtime_lock);
+}
+
+
+static unsigned long get_rtc_time(void)
+{
+	unsigned int sec, min, hr, wk, day, mon, yr, yr100;
+
+ again:
+	do {
+		ctrl_outb(0, RCR1);  /* Clear CF-bit */
+		sec = ctrl_inb(RSECCNT);
+		min = ctrl_inb(RMINCNT);
+		hr  = ctrl_inb(RHRCNT);
+		wk  = ctrl_inb(RWKCNT);
+		day = ctrl_inb(RDAYCNT);
+		mon = ctrl_inb(RMONCNT);
+		yr  = ctrl_inw(RYRCNT);
+		yr100 = (yr >> 8);
+		yr &= 0xff;
+	} while ((ctrl_inb(RCR1) & RCR1_CF) != 0);
+
+	BCD_TO_BIN(yr100);
+	BCD_TO_BIN(yr);
+	BCD_TO_BIN(mon);
+	BCD_TO_BIN(day);
+	BCD_TO_BIN(hr);
+	BCD_TO_BIN(min);
+	BCD_TO_BIN(sec);
+
+	if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
+	    hr > 23 || min > 59 || sec > 59) {
+		printk(KERN_ERR
+		       "SH RTC: invalid value, resetting to 1 Jan 2000\n");
+		ctrl_outb(RCR2_RESET, RCR2);  /* Reset & Stop */
+		ctrl_outb(0, RSECCNT);
+		ctrl_outb(0, RMINCNT);
+		ctrl_outb(0, RHRCNT);
+		ctrl_outb(6, RWKCNT);
+		ctrl_outb(1, RDAYCNT);
+		ctrl_outb(1, RMONCNT);
+		ctrl_outw(0x2000, RYRCNT);
+		ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2);  /* Start */
+		goto again;
+	}
+
+	return mktime(yr100 * 100 + yr, mon, day, hr, min, sec);
+}
+
+static __init unsigned int get_cpu_mhz(void)
+{
+	unsigned int count;
+	unsigned long __dummy;
+	
+	/*
+	** Regardless the toolchain, force the compiler to use the
+	** arbitrary register r3 as a clock tick counter.
+	** NOTE: r3 must be in accordance with rtc_interrupt()
+	*/
+	register unsigned long long  __clock_tick_count __asm__ ("r3");
+
+	sti();
+	do {} while (ctrl_inb(R64CNT) != 0);
+	ctrl_outb(RCR1_CIE, RCR1); /* Enable carry interrupt */
+
+	/*
+	 * r3 is arbitrary. CDC does not support "=z".
+	 */
+	asm volatile("gettr	" __t0 ", %1\n\t"
+		     "and	%2, r63, %2\n\t"
+		     "_pta	4, " __t0 "\n\t"
+		     "addi	%0, 1, %0\n\t"
+		     "beq/l	%2, r63, " __t0 "\n\t"
+		     "ptabs	%1, " __t0 "\n\t"
+		: "=r"(count), "=r" (__dummy), "=r" (__clock_tick_count)
+		: "0" (0));
+	cli();
+	/*
+	 * SH-3:
+	 * CPU clock = 4 stages * loop
+	 * tst    rm,rm      if id ex
+	 * bt/s   1b            if id ex
+	 * add    #1,rd            if id ex
+         *                            (if) pipe line stole
+	 * tst    rm,rm                  if id ex
+         * ....
+	 *
+	 *
+	 * SH-4:
+	 * CPU clock = 6 stages * loop
+	 * I don't know why.
+         * ....
+	 *
+	 * SH-5:
+	 * CPU clock = 2 stages * loop
+         * ....
+	 *
+	 */
+
+#if defined (CONFIG_SH_SIMULATOR)
+	/*
+	 * Let's pretend we are a 5MHz SH-5 to avoid a too
+	 * little timer interval. Also to keep delay
+	 * calibration within a reasonable time.
+	 */
+	return 5000000;
+#elif defined (CONFIG_ICACHE_DISABLED)
+	/*
+	 * Let's pretend we are a 300MHz SH-5.
+	 */
+	return 300000000;
+#else
+	/*
+	 * This really is count by the number of clock cycles
+         * per loop (2) by the ratio between a complete R64CNT
+         * wrap-around (128) and CUI interrupt being raised (64).
+	 */
+	return count*2*2;
+#endif
+}
+
+static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	ctrl_outb(0, RCR1);	/* Disable Carry Interrupts */
+	regs->regs[3] = 1;	/* Using r3 */
+}
+
+static struct irqaction irq0  = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
+static struct irqaction irq1  = { rtc_interrupt, SA_INTERRUPT, 0, "rtc", NULL, NULL};
+
+void __init time_init(void)
+{
+	unsigned int cpu_clock, master_clock, bus_clock, module_clock;
+	unsigned long interval;
+	unsigned long frqcr, ifc, pfc;
+	static int ifc_table[] = { 2, 4, 6, 8, 10, 12, 16, 24 };
+#define bfc_table ifc_table	/* Same */
+#define pfc_table ifc_table	/* Same */
+
+	tmu_base = onchip_remap(TMU_BASE, 1024, "TMU");
+	if (tmu_base == 0UL) {
+		panic("Unable to remap TMU\n");
+	}
+
+	rtc_base = onchip_remap(RTC_BASE, 1024, "RTC");
+	if (rtc_base == 0UL) {
+		panic("Unable to remap RTC\n");
+	}
+
+	cprc_base = onchip_remap(CPRC_BASE, 1024, "CPRC");
+	if (cprc_base == 0UL) {
+		panic("Unable to remap CPRC\n");
+	}
+
+	xtime.tv_sec = get_rtc_time();
+	xtime.tv_usec = 0;
+
+	setup_irq(TIMER_IRQ, &irq0);
+	setup_irq(RTC_IRQ, &irq1);
+
+	/* Check how fast it is.. */
+	cpu_clock = get_cpu_mhz();
+
+	/* FIXME : Are these divides OK?  Note careful order of operations to
+	 * maintain reasonable precision and avoid overflow. */
+	scaled_recip_ctc_ticks_per_jiffy = ((1ULL << CTC_JIFFY_SCALE_SHIFT) / (unsigned long long)(cpu_clock / HZ));
+	
+	disable_irq(RTC_IRQ);
+
+	printk("CPU clock: %d.%02dMHz\n",
+	       (cpu_clock / 1000000), (cpu_clock % 1000000)/10000);
+	{
+		unsigned short bfc;
+		frqcr = ctrl_inl(FRQCR);
+		ifc  = ifc_table[(frqcr>> 6) & 0x0007];
+		bfc  = bfc_table[(frqcr>> 3) & 0x0007];
+		pfc  = pfc_table[(frqcr>> 12) & 0x0007];
+		master_clock = cpu_clock * ifc;
+		bus_clock = master_clock/bfc;
+	}
+
+	printk("Bus clock: %d.%02dMHz\n",
+	       (bus_clock/1000000), (bus_clock % 1000000)/10000);
+	module_clock = master_clock/pfc;
+	printk("Module clock: %d.%02dMHz\n",
+	       (module_clock/1000000), (module_clock % 1000000)/10000);
+	interval = (module_clock/(HZ*4));
+
+	printk("Interval = %ld\n", interval);
+
+	current_cpu_data.cpu_clock    = cpu_clock;
+	current_cpu_data.master_clock = master_clock;
+	current_cpu_data.bus_clock    = bus_clock;
+	current_cpu_data.module_clock = module_clock;
+
+	/* Start TMU0 */
+	ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
+	ctrl_outw(TMU0_TCR_INIT, TMU0_TCR);
+	ctrl_outl(interval, TMU0_TCOR);
+	ctrl_outl(interval, TMU0_TCNT);
+	ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
+}
+
+void enter_deep_standby(void)
+{
+	/* Disable watchdog timer */
+	ctrl_outl(0xa5000000, WTCSR);
+	/* Configure deep standby on sleep */
+	ctrl_outl(0x03, STBCR);
+
+#ifdef CONFIG_SH_CAYMAN
+	{
+		extern void mach_alphanum(int position, unsigned char value);
+		extern void mach_alphanum_brightness(int setting);
+		char halted[] = "Halted. ";
+		int i;
+		mach_alphanum_brightness(6); /* dimmest setting above off */
+		for (i=0; i<8; i++) {
+			mach_alphanum(i, halted[i]);
+		}
+		asm __volatile__ ("synco");
+	}
+#endif
+
+	asm __volatile__ ("sleep");
+	asm __volatile__ ("synci");
+	asm __volatile__ ("nop");
+	asm __volatile__ ("nop");
+	asm __volatile__ ("nop");
+	asm __volatile__ ("nop");
+	panic("Unexpected wakeup!\n");
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/kernel/traps.c linux-2.4.22-pre3/arch/sh64/kernel/traps.c
--- linux-2.4.22-pre2/arch/sh64/kernel/traps.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/kernel/traps.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,263 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/traps.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ */
+
+/*
+ * 'Traps.c' handles hardware traps and faults after we have saved some
+ * state in 'entry.S'.
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include <asm/processor.h>
+
+#undef DEBUG_EXCEPTION
+#ifdef DEBUG_EXCEPTION
+/* implemented in ../lib/dbg.c */
+extern void show_excp_regs(char *fname, int trapnr, int signr,
+			   struct pt_regs *regs);
+#else
+#define show_excp_regs(a, b, c, d)
+#endif
+
+#define DO_ERROR(trapnr, signr, str, name, tsk) \
+asmlinkage void do_##name(unsigned long error_code, struct pt_regs *regs) \
+{ \
+	show_excp_regs(__FUNCTION__, trapnr, signr, regs); \
+	tsk->thread.error_code = error_code; \
+	tsk->thread.trap_no = trapnr; \
+	if (user_mode(regs)) force_sig(signr, tsk); \
+	die_if_no_fixup(str,regs,error_code); \
+}
+
+spinlock_t die_lock;
+
+void die(const char * str, struct pt_regs * regs, long err)
+{
+	console_verbose();
+	spin_lock_irq(&die_lock);
+	printk("%s: %lx\n", str, (err & 0xffffff));
+	show_regs(regs);
+	spin_unlock_irq(&die_lock);
+	do_exit(SIGSEGV);
+}
+
+static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+{
+	if (!user_mode(regs))
+		die(str, regs, err);
+}
+
+static void die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
+{
+	if (!user_mode(regs))
+	{
+		unsigned long fixup;
+		fixup = search_exception_table(regs->pc);
+		if (fixup) {
+			regs->pc = fixup;
+			return;
+		}
+		die(str, regs, err);
+	}
+}
+
+DO_ERROR( 7, SIGSEGV, "address error (load)", address_error_load, current)
+DO_ERROR( 8, SIGSEGV, "address error (store)", address_error_store, current)
+DO_ERROR(13, SIGILL,  "illegal slot instruction", illegal_slot_inst, current)
+DO_ERROR(87, SIGSEGV, "address error (exec)", address_error_exec, current)
+
+#if defined(CONFIG_SH64_ID2815_WORKAROUND)
+/* Table of valid opcodes for SHmedia mode.
+   Form a 10-bit value by concatenating the major/minor opcodes i.e.
+   opcode[31:26,20:16].  The 5 MSBs of this value index into the following
+   array.  The 5 LSBs select the bit in the entry (bit 0 corresponds to
+   LSBs==5'b00000 etc). */
+static unsigned long valid_shmedia_opcodes[32] = {
+	0xeacfff8a,0x6e667676,0x40400000,0x2307150f,
+	0x8000002a,0x88ffaef7,0x40ffff07,0x2300fff3,
+	0x0022003f,0x7766022b,0x00000000,0x00000000,
+	0x88aa000f,0x80ef0022,0x00000000,0x00000000,
+	0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+	0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+	0x20cf80cc,0xffffffff,0xffffffff,0xffffffff,
+	0x002293fe,0xffffffff,0x00000000,0x00000000
+};
+
+void do_reserved_inst(unsigned long error_code, struct pt_regs *regs)
+{
+	/* Workaround SH5-101 cut2 silicon defect #2815 :
+	   in some situations, inter-mode branches from SHcompact -> SHmedia
+	   which should take ITLBMISS or EXECPROT exceptions at the target
+	   falsely take RESINST at the target instead. */
+
+	unsigned long opcode;
+	unsigned long pc, aligned_pc;
+	int get_user_error;
+	int trapnr = 12;
+	int signr = SIGILL;
+	char *exception_name = "reserved_instruction";
+
+	pc = regs->pc;
+	if ((pc & 3) == 1) {
+		/* SHmedia : check for defect.  This requires executable vmas
+		   to be readable too. */
+		aligned_pc = pc & ~3;
+		if (!access_ok(VERIFY_READ, aligned_pc, sizeof(unsigned long))) {
+			get_user_error = -EFAULT;
+		} else {
+			get_user_error = __get_user(opcode, (unsigned long *)aligned_pc);
+		}
+		if (get_user_error >= 0) {
+			unsigned long index, mask;
+			unsigned long major, minor, combined;
+			unsigned long reserved_field;
+			reserved_field = opcode & 0xf; /* These bits are currently reserved as zero in all valid opcodes */
+			major = (opcode >> 26) & 0x3f;
+			minor = (opcode >> 16) & 0xf;
+			combined = (major << 6) | minor;
+			index = combined >> 5;
+			mask = 1UL << (combined & 0x1f);
+			if ((reserved_field == 0) && (valid_shmedia_opcodes[index] & mask)) {
+#if 0
+				printk("Fixed up errata #2815 at PC=%08lx for pid %d (opcode=%08lx)\n",
+					pc, current->pid, opcode);
+#endif
+				/* Now just return to restart the instruction,
+				   because the branch to the instruction will
+				   now be from a SHmedia RTE the silicon defect
+				   won't be triggered. */
+				return;
+			}
+			/* fall through to normal resinst processing */
+		} else {
+			/* Error trying to read opcode.  This typically means a
+			   real fault, not a RESINST any more.  So change the
+			   codes. */
+			trapnr = 87;
+			exception_name = "address error (exec)";
+			signr = SIGSEGV;
+		}
+	}
+	
+	show_excp_regs("do_reserved_inst", trapnr, signr, regs);
+	current->thread.error_code = error_code;
+	current->thread.trap_no = trapnr;
+	if (user_mode(regs)) force_sig(signr, current);
+	die_if_no_fixup(exception_name, regs, error_code);
+}
+
+#else /* CONFIG_SH64_ID2815_WORKAROUND */
+
+/* If the workaround isn't needed, this is just a straightforward reserved
+   instruction */
+DO_ERROR(12, SIGILL,  "reserved instruction", reserved_inst, current)
+
+#endif /* CONFIG_SH64_ID2815_WORKAROUND */
+
+
+#include <asm/system.h>
+
+/* Called with interrupts disabled */
+asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs)
+{
+	PLS();
+	show_excp_regs(__FUNCTION__, -1, -1, regs);
+	die_if_kernel("exception", regs, ex);
+}
+
+int do_unknown_trapa(unsigned long scId, struct pt_regs *regs)
+{	
+	/* Syscall debug */
+        printk("System call ID error: [0x1#args:8 #syscall:16  0x%lx]\n", scId);
+
+	die_if_kernel("unknown trapa", regs, scId);
+
+	return -ENOSYS;
+}
+
+void show_task(unsigned long *sp)
+{
+	unsigned long module_start, module_end;
+	unsigned long kernel_start, kernel_end;
+	unsigned long *stack;
+	extern int _text, _etext;
+	int i = 1;
+
+	kernel_start = (unsigned long)&_text;
+	kernel_end   = (unsigned long)&_etext;
+
+	module_start = VMALLOC_START;
+	module_end   = VMALLOC_END;
+
+	if (!sp) {
+		/*
+		 * If we haven't specified a sane sp, fetch it..
+		 */
+		__asm__ __volatile__ (
+			"or	r15, r63, %0\n\t"
+			"getcon " __c17 ", %1\n\t"
+			: "=r" (module_start),
+			  "=r" (module_end)
+		);
+
+		sp = (unsigned long *)module_start;
+	}
+
+	stack = sp;
+
+	printk("\nCall Trace: ");
+
+	while ((unsigned long)stack & (PAGE_SIZE - 1)) {
+		unsigned long addr = *stack++;
+
+		if ((addr >= kernel_start && addr < kernel_end) ||
+		    (addr >= module_start && addr < module_end)) {
+			/* 
+			 * Do a bit of formatting here.. on an 80 column
+			 * display, 6 entries is the most we can deal with
+			 * per-line, since each address will take up 13 spaces.
+			 */
+			if (i && ((i % 6) == 0))
+				printk("\n       ");
+
+			printk("[<%08lx>] ", addr);
+			i++;
+		}
+	}
+
+	printk("\n");
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+	show_task((unsigned long *)tsk->thread.sp);
+}
+
+void dump_stack(void)
+{
+	show_task(NULL);
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/lib/Makefile linux-2.4.22-pre3/arch/sh64/lib/Makefile
--- linux-2.4.22-pre2/arch/sh64/lib/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/Makefile	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,26 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2000, 2001  Paolo Alberelli
+#
+# Makefile for the SH-5 specific library files..
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#.S.o:
+#	$(CC) $(CFLAGS) $(AFLAGS) -traditional -c $< -o $*.o
+.S.o:
+	$(CC) $(CFLAGS) $(AFLAGS) -c $< -o $*.o
+
+L_TARGET = lib.a
+
+# Panic should really be compiled as PIC
+obj-y  = udelay.o c-checksum.o dbg.o io.o panic.o memcpy.o copy_user_memcpy.o \
+		 page_copy.o page_clear.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/sh64/lib/c-checksum.c linux-2.4.22-pre3/arch/sh64/lib/c-checksum.c
--- linux-2.4.22-pre2/arch/sh64/lib/c-checksum.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/c-checksum.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,330 @@
+/*
+ * arch/sh/lib/csum_parial.c
+ *
+ * This file contains network checksum routines that are better done
+ * in an architecture-specific manner due to speed..
+ */
+
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#if 1
+#define dprintk(x...)
+#else
+#define dprintk(x...) printk(x)
+#endif
+
+static inline unsigned short from64to16(unsigned long long x)
+{
+	/* add up 32-bit words for 33 bits */
+	x = (x & 0xffffffff) + (x >> 32);
+	/* add up 16-bit and 17-bit words for 17+c bits */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up 16-bit and 2-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+static inline unsigned short foldto16(unsigned long x)
+{
+	/* add up 16-bit for 17 bits */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+static inline unsigned short myfoldto16(unsigned long long x)
+{
+	/* Fold down to 32-bits so we don't loose in the typedef-less 
+	   network stack.  */
+	/* 64 to 33 */
+	x = (x & 0xffffffff) + (x >> 32);
+	/* 33 to 32 */
+	x = (x & 0xffffffff) + (x >> 32);
+
+	/* add up 16-bit for 17 bits */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+#define odd(x) ((x)&1)
+/*
+typedef unsigned short u16;
+typedef unsigned  u32;
+*/
+#define U16(x) ntohs(x)
+
+static unsigned long do_moronic_csum(const unsigned char *a16p, int cnt)
+{
+	u32 sum;
+	int oddb;
+
+	/* This algorithm is correct only for those values of cnt < 65536 */
+
+	oddb = odd(cnt);
+	cnt >>= 1;		/* convert to a word count */
+	sum = 0;		/* do a straight two's complement sum */
+	while (cnt--)
+		sum += U16(*a16p++);
+	if (oddb)		/* pick up the odd byte */
+		sum += U16(*a16p++) & (u16) 0xFF00;
+	/* add in the sum of the `carry' bits, making this one's complement */
+	sum = (sum & (u32) 0xFFFF) + ((sum >> 16) & (u32) 0xFFFF);
+	if (sum & (u32) 0x10000)	/* one last possible carry */
+		sum = (sum + 1) & (u32) 0xFFFF;
+	if (sum == (u32) 0xFFFF)	/* remove the -0 ambiguity */
+		sum = (u32) 0;
+	return sum;
+
+}
+
+#if 0
+static inline unsigned long do_csum(const unsigned char *buff, int len)
+{
+	int odd, count;
+	unsigned long long result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = *buff << 8;
+		len--;
+		buff++;
+	}
+	count = len >> 1;	/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;	/* nr of 32-bit words.. */
+		if (count) {
+			if (4 & (unsigned long) buff) {
+				result += *(unsigned int *) buff;
+				count--;
+				len -= 4;
+				buff += 4;
+			}
+			count >>= 1;	/* nr of 64-bit words.. */
+			if (count) {
+				unsigned long carry = 0;
+				do {
+					unsigned long w =
+					    *(unsigned long *) buff;
+					count--;
+					buff += 8;
+					result += carry;
+					result += w;
+					carry = (w > result);
+				} while (count);
+				result += carry;
+				result = (result & 0xffffffff) + (result >> 32);
+			}
+			if (len & 4) {
+				result += *(unsigned int *) buff;
+				buff += 4;
+			}
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += *buff;
+	result = from64to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+      out:
+	return result;
+}
+
+#else
+
+static unsigned long do_csum(const unsigned char *buff, int len)
+{
+	int odd, count;
+	unsigned long result = 0;
+
+	dprintk("do_csum buff %p, len %d (0x%x)\n", buff, len, len);
+#ifdef DEBUG
+	for (i = 0; i < len; i++) {
+		if ((i % 26) == 0)
+			printk("\n");
+		printk("%02X ", buff[i]);
+	}
+#endif
+
+	if (len <= 0)
+		goto out;
+
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = *buff << 8;
+		len--;
+		buff++;
+	}
+	count = len >> 1;	/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;	/* nr of 32-bit words.. */
+		if (count) {
+			unsigned long carry = 0;
+			do {
+				unsigned long w = *(unsigned long *) buff;
+				buff += 4;
+				count--;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += *buff;
+	result = foldto16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+
+	dprintk("\nCHECKSUM is 0x%x\n", result);
+
+      out:
+	return result;
+}
+
+#endif
+
+/* computes the checksum of a memory block at buff, length len,
+   and adds in "sum" (32-bit)  */
+unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum)
+{
+	unsigned long long result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	/* 32+c bits -> 32 bits */
+	result = (result & 0xffffffff) + (result >> 32);
+
+	dprintk("csum_partial, buff %p len %d sum 0x%x result=0x%016Lx\n",
+		buff, len, sum, result);
+
+	return result;
+}
+
+/* Copy while checksumming, otherwise like csum_partial.  */
+unsigned int
+csum_partial_copy(const char *src, char *dst, int len, unsigned int sum)
+{
+	sum = csum_partial(src, len, sum);
+	memcpy(dst, src, len);
+
+	return sum;
+}
+
+/* Copy from userspace and compute checksum.  If we catch an exception
+   then zero the rest of the buffer.  */
+unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len,
+			    unsigned int sum, int *err_ptr)
+{
+	int missing;
+
+	dprintk
+	    ("csum_partial_copy_from_user src %p, dest %p, len %d, sum %08x, err_ptr %p\n",
+	     src, dst, len, sum, err_ptr);
+	missing = copy_from_user(dst, src, len);
+	dprintk("  access_ok %d\n", __access_ok((unsigned long) src, len));
+	dprintk("  missing %d\n", missing);
+	if (missing) {
+		memset(dst + len - missing, 0, missing);
+		*err_ptr = -EFAULT;
+	}
+
+	return csum_partial(dst, len, sum);
+}
+
+/* Copy to userspace and compute checksum.  */
+unsigned int
+csum_partial_copy_to_user(const char *src, char *dst, int len,
+			  unsigned int sum, int *err_ptr)
+{
+	sum = csum_partial(src, len, sum);
+
+	if (copy_to_user(dst, src, len))
+		*err_ptr = -EFAULT;
+
+	return sum;
+}
+
+/*
+ *	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)
+{
+	dprintk("ip_fast_csum %p,%d\n", iph, ihl);
+
+	return ~do_csum(iph, ihl * 4);
+}
+
+unsigned int csum_tcpudp_nofold(unsigned long saddr,
+				unsigned long daddr,
+				unsigned short len,
+				unsigned short proto, unsigned int sum)
+{
+	unsigned long long result;
+
+	dprintk("ntohs(0x%x)=0x%x\n", 0xdead, ntohs(0xdead));
+	dprintk("htons(0x%x)=0x%x\n", 0xdead, htons(0xdead));
+
+	result = ((unsigned long long) saddr +
+		  (unsigned long long) daddr +
+		  (unsigned long long) sum +
+		  ((unsigned long long) ntohs(len) << 16) +
+		  ((unsigned long long) proto << 8));
+
+	/* Fold down to 32-bits so we don't loose in the typedef-less 
+	   network stack.  */
+	/* 64 to 33 */
+	result = (result & 0xffffffff) + (result >> 32);
+	/* 33 to 32 */
+	result = (result & 0xffffffff) + (result >> 32);
+
+	dprintk("%s saddr %x daddr %x len %x proto %x sum %x result %08Lx\n",
+		__FUNCTION__, saddr, daddr, len, proto, sum, result);
+
+	return result;
+}
+
+// Post SIM:
+unsigned int
+csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum)
+{
+	//  unsigned dummy;
+	dprintk("csum_partial_copy_nocheck src %p dst %p len %d\n", src, dst,
+		len);
+
+	return csum_partial_copy(src, dst, len, sum);
+}
diff -urN linux-2.4.22-pre2/arch/sh64/lib/checksum.S linux-2.4.22-pre3/arch/sh64/lib/checksum.S
--- linux-2.4.22-pre2/arch/sh64/lib/checksum.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/checksum.S	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,656 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh5/lib/checksum.S
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli, Stefano D'Andrea
+ *
+ */
+
+/*
+ *
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *              Pentium Pro/II routines:
+ *              Alexander Kjeldaas <astor@guardian.no>
+ *              Finn Arne Gangstad <finnag@guardian.no>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ * Changes:     Ingo Molnar, converted csum_partial_copy() to 2.1 exception
+ *			     handling.
+ *		Andi Kleen,  add zeroing on error
+ *                   converted to pure assembler
+ *
+ * SuperH version:  Copyright (C) 1999  Niibe Yutaka
+ *
+ * SH-5 version:  Copyright (C) 2000  Paolo Alberelli, Stefano D'Andrea
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/errno.h>
+#include <asm/registers.h>
+
+	.section	.text64, "ax"
+/*	
+ * unsigned int csum_partial(const unsigned char *buf,
+ *			     int 	          len,
+ *                           unsigned int         sum);
+ *
+ *
+ * computes a partial checksum, e.g. for TCP/UDP fragments
+ */
+
+/*
+ * SH-5 ABI convention:
+ *    Input parameters:
+ *    		r2  = *buf
+ *    		r3  =  len
+ *    		r4  =  sum	so far computed checksum (may be zero)
+ *    return value must be in:
+ *              r2		returned checksum
+ */
+
+	/*
+	 * Experiments with Ethernet and SLIP connections show that buff
+	 * is aligned on either a 2-byte or 4-byte boundary.  We get at
+	 * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
+	 * Fortunately, it is easy to convert 2-byte alignment to 4-byte
+	 * alignment for the unrolled loop.
+	 */
+
+#ifndef NOTDEF  
+	/* This version of _csum_partial is an easy but unefficient
+	 * implementation. 
+	 * It's mainteined only for historical reasons.	
+	 */
+	.global csum_partial
+csum_partial:
+	_ptar		.byte_footer, t1	/* t1 = .byte_footer         */
+	_ptar		.add_short_loop, t2	/* t2 = checksum eval loop   */
+	_ptar		.exiting, t3		/* t3 = add carry...	     */
+
+	movi		2, r1
+
+	/* we assume buf short aligned */
+	/* Short must be checksummed   */
+.add_short_loop:
+	bgt		r1, r3, t1		/* Size = 1 or 0 (remind)    */
+
+	ld.uw		r2, 0, r7		/* r7 = word to be checksumed*/
+	add		r4, r7, r4
+
+	addi		r2, 2, r2		/* move buf forward...       */
+	addi		r3, -2, r3		/* decrement len             */
+	blink		t2, ZERO		/* goto .add_short_loop      */
+	
+.byte_footer:
+	/* still one byte to be checksummed ? */
+	xor		r7, r7, r7
+	beqi		r3, 0, t3
+	ld.ub		r2, 0, r7		/* r7 = last byte...	     */
+#ifndef __LITTLE_ENDIAN__
+	shlli		r7, 8, r7
+#endif
+
+.exiting:
+	add		r4, r7, r2
+	
+	ptabs		r18, t0
+	blink		t0, ZERO
+
+#else  /* NOTDEF ---------------------------------------------------- */
+
+	.global csum_partial
+csum_partial:
+	movi		32, r8			/* r8 = sizeof(8 * int)   */
+	_ptar		.byte_footer, t1	/* t1 = .byte_footer      */
+	_ptar		.word_footer, t2	/* t2 = .word_footer      */
+	_ptar		.long_footer, t3	/* t3 = .long_footer      */
+	_ptar		.exit, t4		/* t4 = exit point        */
+	_ptar		.long_aligned, t0	/* t0 = .long_aligned	  */
+	or		r2, ZERO, r5		/* r5 = buffer pointer    */
+	or		r3, ZERO, r6		/* r6 = original length   */
+	andi		r2, 2, r7 		
+	beq		r7, ZERO, t0		/* It's buf long aligned */
+
+	/* we assume buf short aligned */
+
+	beqi		r3, 1, t1		/* Size = 1 */
+
+	/* Short must be checksummed */
+	ld.uw		r2, 0, r7		/* r7 = word to be checksumed*/
+	add		r4, r7, r4
+
+	or		ZERO, ZERO, r7
+
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+	addi		r6, -2, r6
+	addi		r5, 2, r5		/* r5 is now long aligned */
+	beq		r6, ZERO, t4		/* Exit if done */
+	
+	or		ZERO, ZERO, r7		/* Clean up r7 */
+	
+.long_aligned:
+	bgt		r8, r6, t3
+	
+	/* 8 Longs to be checksummed */
+	ld.l		r5, 0, r7		/* r7 = data to be checksummed*/
+	add		r4, r7, r4
+	or		ZERO, ZERO, r7
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+	ld.l		r5, 4, r7		/* r7 = data to be checksummed*/
+	add		r4, r7, r4
+	or		ZERO, ZERO, r7
+
+
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+	ld.l		r5, 8, r7		/* r7 = data to be checksummed*/
+	add		r4, r7, r4
+	or		ZERO, ZERO, r7
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+
+	ld.l		r5, 12, r7		/* r7 = data to be checksummed*/
+	add		r4, r7, r4
+	or		ZERO, ZERO, r7
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+
+
+	ld.l		r5, 16, r7		/* r7 = data to be checksummed*/
+	add		r4, r7, r4
+	or		ZERO, ZERO, r7
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+
+	ld.l		r5, 20, r7		/* r7 = data to be checksummed*/
+	add		r4, r7, r4
+	or		ZERO, ZERO, r7
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+
+
+	ld.l		r5, 24, r7		/* r7 = data to be checksummed*/
+	add		r4, r7, r4
+	or		ZERO, ZERO, r7
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+
+
+	ld.l		r5, 28, r7		/* r7 = data to be checksummed*/
+	add		r4, r7, r4
+	or		ZERO, ZERO, r7
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+
+
+	sub		r6, r8, r6
+	add		r5, r8, r5
+	blink		t0, ZERO
+	
+.long_footer:
+	movi		4, r8
+	bgt		r8, r6, t2
+	
+	/* Long to be checksummed */
+	ld.l		r5, 0, r7		/* r7 = data to be checksummed*/
+	add		r4, r7, r4
+	or		ZERO, ZERO, r7
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+
+
+	sub		r6, r8, r6
+	add		r5, r8, r5
+	blink		t3, ZERO
+	
+.word_footer:
+	movi		2, r8
+	bgt		r8, r6, t1
+
+	/* Short to be checksummed */
+	ld.uw		r5, 0, r7		/* r7 = data to be checksummed*/
+	add		r4, r7, r4
+	or		ZERO, ZERO, r7
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+
+
+	sub		r6, r8, r6
+	add		r5, r8, r5
+	
+.byte_footer:
+	beqi		r6, 0, t4
+	/* Short to be checksummed */
+	ld.ub		r5, 0, r7		/* r7 = data to be checksummed*/
+
+#ifndef __LITTLE_ENDIAN__
+	shlli		r7, 8, r7
+#endif
+
+	add		r4, r7, r4
+	or		ZERO, ZERO, r7
+	mshflo.l	r4, r7, r7
+	shlri		r4, 32, r4
+	add		r4, r7, r4		/* Add eventual "carry" */
+
+
+.exit:
+	or		r4, ZERO, r2
+
+	ptabs		r18, t0
+	blink		t0, ZERO
+
+#endif  /*NOTDEF*/
+
+/*
+ * unsigned int csum_partial_copy_generic (const char *src,
+ *					         char *dst,
+ *						 int len, 
+ *						 int sum,
+ *					         int *src_err_ptr,
+ *					         int *dst_err_ptr)
+ *  
+ *
+ *
+ * Copy from ds while checksumming, otherwise like csum_partial
+ *
+ * The macros SRC and DST specify the type of access for the instruction.
+ * thus we can call a custom exception handler for all access types.
+ *
+ * FIXME: could someone double-check whether I haven't mixed up some SRC and
+ *	  DST definitions? It's damn hard to trigger all cases.  I hope I got
+ *	  them all but there's no guarantee.
+ */
+
+/*
+ * SH-5 ABI convention:
+ *    Input parameters:
+ *    		r2  = const char  *src
+ *    		r3  = char	  *dst
+ *    		r4  = int          len
+ *    		r5  = int          sum   so far computed checksum (may be zero)
+ *    		r6  = int         *src_err_ptr
+ *    		r7  = int         *dst_err_ptr
+ *    return value must be in:
+ *              r2	returned checksum
+ */
+
+#ifndef NOTDEF  
+	/* 
+	** This version of _csum_partial_copy_generic is an easy but
+	** unefficient implementation. 
+	** It's mainteined only for historical reasons.	
+	*/
+	.global csum_partial_copy_generic
+csum_partial_copy_generic:
+	_ptar		.gc_byte_footer, t1	/* t1 = .byte_footer         */
+	_ptar		.gc_add_short_loop, t2	/* t2 = checksum eval loop   */
+	_ptar		.gc_exiting, t3		/* t3 = add carry...	     */
+
+	or		r2, ZERO, r20		/* r20 = source pointer      */ 
+	or		r3, ZERO, r21		/* r21 = destination pointer */ 
+
+	movi		2, r1
+
+	/* we assume buf short aligned */
+	/* Short must be checksummed   */
+.gc_add_short_loop:
+
+	bgt		r1, r4, t1		/* Size = 1 or 0 (remind)    */
+
+.src_err_1:
+	ld.uw		r20, 0, r8		/* r8 = word to be checksum. */
+	st.w		r21, 0, r8		/* fill data into DST */
+
+	add		r5, r8, r5
+
+	addi		r20, 2, r20		/* move SRC forward...       */
+	addi		r21, 2, r21		/* move DST forward...       */
+	addi		r4, -2, r4		/* decrement len             */
+	blink		t2, ZERO		/* goto .gc_add_short_loop   */
+	
+.gc_byte_footer:
+	/* still one byte to be checksummed ? */
+	xor		r8, r8, r8
+	beqi		r4, 0, t3
+
+.src_err_2:
+	ld.ub		r20, 0, r8		/* r8 = last byte...	     */
+	st.b		r21, 0, r8
+#ifndef __LITTLE_ENDIAN__
+	shlli		r8, 8, r8
+#endif
+
+.gc_exiting:
+	add		r5, r8, r2
+	
+	ptabs		r18, t0
+	blink		t0, ZERO
+
+	.section	.fixup, "ax"
+
+_csum_partial_copy_generic_dst_err:
+	movi		-(EFAULT), r8		/* r8 = EFAULT reply */
+	st.l		r7, 0, r8		/* *DST_ERR = -EFAULT */
+
+	/* Quiet exit */
+	or		r5, ZERO, r2
+
+	ptabs		r18, t0
+	blink		t0, ZERO
+
+_csum_partial_copy_generic_src_err:
+	movi		-(EFAULT), r8		/* r8 = EFAULT reply */
+	ld.l		r6, 0, r8		/* *SRC_ERR = -EFAULT */
+
+	/*
+	 * Now reset the DST buffer.	
+	 * r20 points to the next DST byte.
+	 * r3 points to the first DST byte.
+	 */
+	_ptar		.quiet_exit, t0
+	_ptar		.src_err_loop, t1
+	beq		r20, r3, t0
+
+.src_err_loop:
+	addi		r20, -1, r20
+	ld.b		r20, 0, ZERO
+	bne		r20, r3, t1
+
+	/* Quiet exit */
+.quiet_exit:
+	or		r5, ZERO, r2
+
+	ptabs		r18, t0
+	blink		t0, ZERO
+
+	.section	__ex_table, "a"
+
+	.global asm_checksum_start	/* Just a marker */
+asm_checksum_start:
+	.long	.src_err_1, _csum_partial_copy_generic_src_err
+	.long	.src_err_2, _csum_partial_copy_generic_src_err
+	.long	.src_err_1+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_2+4, _csum_partial_copy_generic_dst_err
+	.global asm_checksum_end	/* Just a marker */
+asm_checksum_end:
+
+#else  /* NOTDEF -------------------------------------------------------- */
+
+	.global csum_partial_copy_generic
+csum_partial_copy_generic:
+
+	movi		32, r27			/* r27 = sizeof(8 * int) */
+	_ptar		.byte_footer_gc, t1	/* t1 = .byte_footer_gc */
+	_ptar		.word_footer_gc, t2	/* t2 = .word_footer_gc */
+	_ptar		.long_footer_gc, t3	/* t3 = .long_footer_gc */
+	_ptar		.exit_gc, t4		/* t4 = exit point */
+
+	or		r2, ZERO, r24		/* r24 = original SRC pointer */
+	or		r3, ZERO, r20		/* r20 = original DST pointer */
+	or		r4, ZERO, r25		/* r25 = original length */
+	_ptar		.long_aligned_gc, t0
+	andi		r2, 2, r26 		/* check if source it's  */
+	beq		r26, ZERO, t0		/* long aligned 	 */
+
+	/* It's short aligned */
+
+	beqi		r4, 1, t1		/* Size = 1 */
+
+	/* Short must be checksummed */
+.src_err_1:
+	ld.w		r2, 0, r26		/* r26: data to be checksummed*/
+	st.w		r3, 0, r26		/* fill data into DST */
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26, r26
+	shlri		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+	
+	addi		r25, -2, r25
+	addi		r24, 2, r24		/* r24 is now long aligned */
+	addi		r20, 2, r20		/* r20 it's now long aligned */
+	beq		r25, ZERO, t4		/* Exit if done */
+	
+	or		ZERO, ZERO, r26		/* Clean up r26 */
+	
+.long_aligned_gc:
+	bgt		r27, r25, t3
+	
+	/* 8 Longs to be checksummed */
+.src_err_2:
+	ld.l		r24, 0, r26		/* r26: data to be checksummed*/
+	st.l		r20, 0, r26		/* fill data into DST */
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26, r26
+	shlri		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+
+.src_err_3:
+	ld.l		r24, 4, r26		/* r26: data to be checksummed*/
+	st.l		r20, 4, r26		/* fill data into DST */
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26, r26
+	shlri		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+
+.src_err_4:
+	ld.l		r24, 8, r26		/* r26: data to be checksummed*/
+	st.l		r20, 8, r26		/* fill data into DST */
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26, r26
+	shlri		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+
+.src_err_5:
+	ld.l		r24, 12, r26		/* r26: data to be checksummed*/
+	st.l		r20, 12, r26		/* fill data into DST */
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26, r26
+	shlri		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+
+.src_err_6:
+	ld.l		r24, 16, r26		/* r26: data to be checksummed*/
+	st.l		r20, 16, r26		/* fill data into DST */
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26, r26
+	shlri		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+
+.src_err_7:
+	ld.l		r24, 20, r26		/* r26: data to be checksummed*/
+	st.l		r20, 20, r26		/* fill data into DST */
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26,r26
+	shlri 		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+
+.src_err_8:
+	ld.l		r24, 24, r26		/* r26: data to be checksummed*/
+	st.l		r20, 24, r26		/* fill data into DST */
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26, r26
+	shlri		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+
+.src_err_9:
+	ld.l		r24, 28, r26		/* r26: data to be checksummed*/
+	st.l		r20, 28, r26		/* fill data into DST */
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26, r26
+	shlri		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+
+	sub		r25, r27, r25
+	add		r24, r27, r24
+	add		r20, r27, r20
+	blink		t0, ZERO
+	
+.long_footer_gc:
+	movi		4, r27
+	bgt		r27, r25, t2
+	
+	/* Long to be checksummed */
+.src_err_10:
+	ld.l		r24, 0, r26		/* r26: data to be checksummed*/
+	st.l		r20, 0, r26		/* fill data into DST */
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26, r26
+	shlri		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+
+	sub		r25, r27, r25
+	add		r24, r27, r24
+	add		r20, r27, r20
+	blink		t3, ZERO
+	
+.word_footer_gc:
+	movi		2, r27
+	bgt		r27, r25, t1
+
+	/* Short to be checksummed */
+.src_err_11:
+	ld.uw		r24, 0, r26		/* r26: data to be checksummed*/
+	st.w		r20, 0, r26		/* fill data into DST */
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26, r26
+	shlri		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+
+	sub		r25, r27, r25
+	add		r24, r27, r24
+	add		r20, r27, r20
+	
+.byte_footer_gc:
+	beqi		r25, 0, t4
+	/* Short to be checksummed */
+	ld.ub		r24, 0, r26		/* r26: data to be checksummed*/
+.src_err_12:
+	ld.ub		r24, 0, r26		/* r26: data to be checksummed*/
+	st.b		r20, 0, r26		/* fill data into DST */
+
+#ifndef __LITTLE_ENDIAN__
+	shlli		r26, 8, r26
+#endif
+
+	add		r5, r26, r5
+	or		ZERO, ZERO, r26
+	mshflo.l	r5, r26, r26
+	shlri		r5, 32, r5
+	add		r5, r26, r5		/* Add eventual "carry" */
+
+.exit_gc:
+	or		r5, ZERO, r2
+
+	ptabs		r18, t0
+	blink		t0, ZERO
+
+	.section	.fixup, "ax"
+
+_csum_partial_copy_generic_dst_err:
+	movi		-(EFAULT), r21		/* r21 = EFAULT reply */
+	ld.l		r7, 0, r21
+
+	/* Quiet exit */
+	or		r5, ZERO, r2
+
+	ptabs		r18, t0
+	blink		t0, ZERO
+
+_csum_partial_copy_generic_src_err:
+	movi		-(EFAULT), r21		/* r21 = EFAULT reply */
+	ld.l		r6, 0, r21
+
+	/*
+	 * Now reset the DST buffer.	
+	 * r20 points to the next DST byte.
+	 * r3 points to the first DST byte.
+	 */
+	_ptar		.quiet_exit, t0
+	_ptar		.src_err_loop, t1
+	beq		r20, r3, t0
+
+.src_err_loop:
+	addi		r20, -1, r20
+	st.b		r20, 0, ZERO
+	bne		r20, r3, t1
+
+	/* Quiet exit */
+.quiet_exit:
+	or		r5, ZERO, r2
+
+	ptabs		r18, t0
+	blink		t0, ZERO
+
+	.section	__ex_table, "a"
+
+	.global asm_checksum_start	/* Just a marker */
+asm_checksum_start:
+	.long	.src_err_1, _csum_partial_copy_generic_src_err
+	.long	.src_err_2, _csum_partial_copy_generic_src_err
+	.long	.src_err_3, _csum_partial_copy_generic_src_err
+	.long	.src_err_4, _csum_partial_copy_generic_src_err
+	.long	.src_err_5, _csum_partial_copy_generic_src_err
+	.long	.src_err_6, _csum_partial_copy_generic_src_err
+	.long	.src_err_7, _csum_partial_copy_generic_src_err
+	.long	.src_err_8, _csum_partial_copy_generic_src_err
+	.long	.src_err_9, _csum_partial_copy_generic_src_err
+	.long	.src_err_10, _csum_partial_copy_generic_src_err
+	.long	.src_err_11, _csum_partial_copy_generic_src_err
+	.long	.src_err_12, _csum_partial_copy_generic_src_err
+	.long	.src_err_1+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_2+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_3+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_4+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_5+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_6+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_7+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_8+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_9+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_10+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_11+4, _csum_partial_copy_generic_dst_err
+	.long	.src_err_12+4, _csum_partial_copy_generic_dst_err
+
+	.global asm_checksum_end	/* Just a marker */
+asm_checksum_end:
+#endif  /* NOTDEF */
diff -urN linux-2.4.22-pre2/arch/sh64/lib/copy_user_memcpy.S linux-2.4.22-pre3/arch/sh64/lib/copy_user_memcpy.S
--- linux-2.4.22-pre2/arch/sh64/lib/copy_user_memcpy.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/copy_user_memcpy.S	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,211 @@
+!
+! Fast SH memcpy
+!
+! by Toshiyasu Morita (tm@netcom.com)
+! hacked by J"orn Rernnecke (joern.rennecke@superh.com) ("o for o-umlaut)
+! SH5 code Copyright 2002 SuperH Ltd.
+!
+! Entry: ARG0: destination pointer
+!        ARG1: source pointer
+!        ARG2: byte count
+!
+! Exit:  RESULT: destination pointer
+!        any other registers in the range r0-r7: trashed
+!
+! Notes: Usually one wants to do small reads and write a longword, but
+!        unfortunately it is difficult in some cases to concatanate bytes
+!        into a longword on the SH, so this does a longword read and small
+!        writes.
+!
+! This implementation makes two assumptions about how it is called:
+!
+! 1.: If the byte count is nonzero, the address of the last byte to be
+!     copied is unsigned greater than the address of the first byte to
+!     be copied.  This could be easily swapped for a signed comparison,
+!     but the algorithm used needs some comparison.
+!
+! 2.: When there are two or three bytes in the last word of an 11-or-more
+!     bytes memory chunk to b copied, the rest of the word can be read
+!     without side effects.
+!     This could be easily changed by increasing the minumum size of
+!     a fast memcpy and the amount subtracted from r7 before L_2l_loop be 2,
+!     however, this would cost a few extra cyles on average.
+!     For SHmedia, the assumption is that any quadword can be read in its
+!     enirety if at least one byte is included in the copy.
+
+/* Imported into Linux kernel by Richard Curnow.  This is used to implement the
+   __copy_user function in the general case, so it has to be a distinct
+   function from intra-kernel memcpy to allow for exception fix-ups in the
+   event that the user pointer is bad somewhere in the copy (e.g. due to
+   running off the end of the vma).
+
+   Note, this algorithm will be slightly wasteful in the case where the source
+   and destination pointers are equally aligned, because the stlo/sthi pairs
+   could then be merged back into single stores.  If there are a lot of cache
+   misses, this is probably offset by the stall lengths on the preloads.
+
+*/
+
+	.section .text..SHmedia32,"ax"
+	.little
+	.balign 32
+	.global copy_user_memcpy
+	.global copy_user_memcpy_end
+copy_user_memcpy:
+
+#define LDUAQ(P,O,D0,D1) ldlo.q P,O,D0; ldhi.q P,O+7,D1
+#define STUAQ(P,O,D0,D1) stlo.q P,O,D0; sthi.q P,O+7,D1
+#define LDUAL(P,O,D0,D1) ldlo.l P,O,D0; ldhi.l P,O+3,D1
+#define STUAL(P,O,D0,D1) stlo.l P,O,D0; sthi.l P,O+3,D1
+
+	ld.b r3,0,r63
+	pta/l Large,tr0
+	movi 25,r0
+	bgeu/u r4,r0,tr0
+	nsb r4,r0
+	shlli r0,5,r0
+	movi (L1-L0+63*32 + 1) & 0xffff,r1
+	sub r1, r0, r0
+L0:	ptrel r0,tr0
+	add r2,r4,r5
+	ptabs r18,tr1
+	add r3,r4,r6
+	blink tr0,r63
+
+/* Rearranged to make cut2 safe */
+	.balign 8
+L4_7:	/* 4..7 byte memcpy cntd. */
+	stlo.l r2, 0, r0
+	or r6, r7, r6
+	sthi.l r5, -1, r6
+	stlo.l r5, -4, r6
+	blink tr1,r63
+
+	.balign 8
+L1:	/* 0 byte memcpy */
+	nop
+	blink tr1,r63
+	nop
+	nop
+	nop
+	nop
+
+L2_3:	/* 2 or 3 byte memcpy cntd. */
+	st.b r5,-1,r6
+	blink tr1,r63
+
+	/* 1 byte memcpy */
+	ld.b r3,0,r0
+	st.b r2,0,r0
+	blink tr1,r63
+
+L8_15:	/* 8..15 byte memcpy cntd. */
+	stlo.q r2, 0, r0
+	or r6, r7, r6
+	sthi.q r5, -1, r6
+	stlo.q r5, -8, r6
+	blink tr1,r63
+	
+	/* 2 or 3 byte memcpy */
+	ld.b r3,0,r0
+	ld.b r2,0,r63
+	ld.b r3,1,r1
+	st.b r2,0,r0
+	pta/l L2_3,tr0
+	ld.b r6,-1,r6
+	st.b r2,1,r1
+	blink tr0, r63
+
+	/* 4 .. 7 byte memcpy */
+	LDUAL (r3, 0, r0, r1)
+	pta L4_7, tr0
+	ldlo.l r6, -4, r7
+	or r0, r1, r0
+	sthi.l r2, 3, r0
+	ldhi.l r6, -1, r6
+	blink tr0, r63
+
+	/* 8 .. 15 byte memcpy */
+	LDUAQ (r3, 0, r0, r1)
+	pta L8_15, tr0
+	ldlo.q r6, -8, r7
+	or r0, r1, r0
+	sthi.q r2, 7, r0
+	ldhi.q r6, -1, r6
+	blink tr0, r63
+
+	/* 16 .. 24 byte memcpy */
+	LDUAQ (r3, 0, r0, r1)
+	LDUAQ (r3, 8, r8, r9)
+	or r0, r1, r0
+	sthi.q r2, 7, r0
+	or r8, r9, r8
+	sthi.q r2, 15, r8
+	ldlo.q r6, -8, r7
+	ldhi.q r6, -1, r6
+	stlo.q r2, 8, r8
+	stlo.q r2, 0, r0
+	or r6, r7, r6
+	sthi.q r5, -1, r6
+	stlo.q r5, -8, r6
+	blink tr1,r63
+
+Large:
+	ld.b r2, 0, r63
+	pta/l  Loop_ua, tr1
+	ori r3, -8, r7
+	sub r2, r7, r22
+	sub r3, r2, r6
+	add r2, r4, r5
+	ldlo.q r3, 0, r0
+	addi r5, -16, r5
+	movi 64+8, r27 ! could subtract r7 from that.
+	stlo.q r2, 0, r0
+	sthi.q r2, 7, r0
+	ldx.q r22, r6, r0
+	bgtu/l r27, r4, tr1
+
+	addi r5, -48, r27
+	pta/l Loop_line, tr0
+	addi r6, 64, r36
+	addi r6, -24, r19
+	addi r6, -16, r20
+	addi r6, -8, r21
+
+Loop_line:
+	ldx.q r22, r36, r63
+	alloco r22, 32
+	addi r22, 32, r22
+	ldx.q r22, r19, r23
+	sthi.q r22, -25, r0
+	ldx.q r22, r20, r24
+	ldx.q r22, r21, r25
+	stlo.q r22, -32, r0
+	ldx.q r22, r6,  r0
+	sthi.q r22, -17, r23
+	sthi.q r22,  -9, r24
+	sthi.q r22,  -1, r25
+	stlo.q r22, -24, r23
+	stlo.q r22, -16, r24
+	stlo.q r22,  -8, r25
+	bgeu r27, r22, tr0
+
+Loop_ua:
+	addi r22, 8, r22
+	sthi.q r22, -1, r0
+	stlo.q r22, -8, r0
+	ldx.q r22, r6, r0
+	bgtu/l r5, r22, tr1
+
+	add r3, r4, r7
+	ldlo.q r7, -8, r1
+	sthi.q r22, 7, r0
+	ldhi.q r7, -1, r7
+	ptabs r18,tr1
+	stlo.q r22, 0, r0
+	or r1, r7, r1
+	sthi.q r5, 15, r1
+	stlo.q r5, 8, r1
+	blink tr1, r63
+copy_user_memcpy_end:
+	nop
diff -urN linux-2.4.22-pre2/arch/sh64/lib/dbg.c linux-2.4.22-pre3/arch/sh64/lib/dbg.c
--- linux-2.4.22-pre2/arch/sh64/lib/dbg.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/dbg.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,319 @@
+/*--------------------------------------------------------------------------
+--
+-- Identity : Linux50 Debug Funcions
+--
+-- File     : arch/sh64/lib/dbg.C
+--
+-- Copyright 2000, 2001 STMicroelectronics Limited.
+--
+--------------------------------------------------------------------------*/
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/mmu_context.h>
+
+typedef u64 regType_t;
+
+static regType_t getConfigReg(u64 id)
+{
+	register u64 reg __asm__("r2");
+	asm volatile ("getcfg   %1, 0, %0":"=r" (reg):"r"(id));
+	return (reg);
+}
+
+/* ======================================================================= */
+
+static char *szTab[] = { "4k", "64k", "1M", "512M" };
+static char *protTab[] = { "----",
+	"---R",
+	"--X-",
+	"--XR",
+	"-W--",
+	"-W-R",
+	"-WX-",
+	"-WXR",
+	"U---",
+	"U--R",
+	"U-X-",
+	"U-XR",
+	"UW--",
+	"UW-R",
+	"UWX-",
+	"UWXR"
+};
+#define  ITLB_BASE	0x00000000
+#define  DTLB_BASE	0x00800000
+#define  MAX_TLBs		64
+/* PTE High */
+#define  GET_VALID(pte)        ((pte) & 0x1)
+#define  GET_SHARED(pte)       ((pte) & 0x2)
+#define  GET_ASID(pte)         ((pte >> 2) & 0x0ff)
+#define  GET_EPN(pte)          ((pte) & 0xfffff000)
+
+/* PTE Low */
+#define  GET_CBEHAVIOR(pte)    ((pte) & 0x3)
+#define  GET_PAGE_SIZE(pte)    szTab[((pte >> 3) & 0x3)]
+#define  GET_PROTECTION(pte)   protTab[((pte >> 6) & 0xf)]
+#define  GET_PPN(pte)          ((pte) & 0xfffff000)
+
+#define PAGE_1K_MASK           0x00000000
+#define PAGE_4K_MASK           0x00000010
+#define PAGE_64K_MASK          0x00000080
+#define MMU_PAGESIZE_MASK      (PAGE_64K_MASK | PAGE_4K_MASK)
+#define PAGE_1MB_MASK          MMU_PAGESIZE_MASK
+#define PAGE_1K                (1024)
+#define PAGE_4K                (1024 * 4)
+#define PAGE_64K               (1024 * 64)
+#define PAGE_1MB               (1024 * 1024)
+
+#define HOW_TO_READ_TLB_CONTENT  \
+       "[ ID]  PPN         EPN        ASID  Share  CB  P.Size   PROT.\n"
+
+void print_single_tlb(unsigned long tlb, int single_print)
+{
+	regType_t pteH;
+	regType_t pteL;
+	unsigned int valid, shared, asid, epn, cb, ppn;
+	char *pSize;
+	char *pProt;
+
+	/*
+	   ** in case of single print <single_print> is true, this implies:
+	   **   1) print the TLB in any case also if NOT VALID
+	   **   2) print out the header
+	 */
+
+	pteH = getConfigReg(tlb);
+	valid = GET_VALID(pteH);
+	if (single_print)
+		printk(HOW_TO_READ_TLB_CONTENT);
+	else if (!valid)
+		return;
+
+	pteL = getConfigReg(tlb + 1);
+
+	shared = GET_SHARED(pteH);
+	asid = GET_ASID(pteH);
+	epn = GET_EPN(pteH);
+	cb = GET_CBEHAVIOR(pteL);
+	pSize = GET_PAGE_SIZE(pteL);
+	pProt = GET_PROTECTION(pteL);
+	ppn = GET_PPN(pteL);
+	printk("[%c%2ld]  0x%08x  0x%08x  %03d   %02x    %02x   %4s    %s\n",
+	       ((valid) ? ' ' : 'u'), ((tlb & 0x0ffff) / TLB_STEP),
+	       ppn, epn, asid, shared, cb, pSize, pProt);
+}
+
+void print_dtlb(void)
+{
+	int count;
+	unsigned long tlb;
+
+	printk(" ================= SH-5 D-TLBs Status ===================\n");
+	printk(HOW_TO_READ_TLB_CONTENT);
+	tlb = DTLB_BASE;
+	for (count = 0; count < MAX_TLBs; count++, tlb += TLB_STEP)
+		print_single_tlb(tlb, 0);
+	printk
+	    (" =============================================================\n");
+}
+
+void print_itlb(void)
+{
+	int count;
+	unsigned long tlb;
+
+	printk(" ================= SH-5 I-TLBs Status ===================\n");
+	printk(HOW_TO_READ_TLB_CONTENT);
+	tlb = ITLB_BASE;
+	for (count = 0; count < MAX_TLBs; count++, tlb += TLB_STEP)
+		print_single_tlb(tlb, 0);
+	printk
+	    (" =============================================================\n");
+}
+
+/* ======================================================================= */
+
+#include "syscalltab.h"
+
+void evt_debug(int evt, int ret_addr, int event, int tra)
+{
+	int syscallno = tra & 0xff;
+
+	// if (event != 0) printk("<%03x>",evt);
+
+	if ((event == 2) && (evt == 0x160)) {
+		if (syscallno < NUM_SYSCALL_INFO_ENTRIES)
+			printk("Task %d: %s()\n",
+			       current->pid,
+			       syscall_info_table[syscallno].name);
+	}
+}
+
+void evt_debug2(unsigned int ret)
+{
+	printk("Task %d: syscall returns %08x\n", current->pid, ret);
+}
+
+/* ======================================================================= */
+
+void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs)
+{
+
+	unsigned long long ah, al, bh, bl, ch, cl;
+
+	printk("\n");
+	printk("EXCEPTION - %s: task %d; Linux trap # %d; signal = %d\n",
+	       ((from) ? from : "???"), current->pid, trapnr, signr);
+
+	asm volatile ("getcon   " __c5 ", %0":"=r"(ah));
+	asm volatile ("getcon   " __c5 ", %0":"=r"(al));
+	ah = (ah) >> 32;
+	al = (al) & 0xffffffff;
+	asm volatile ("getcon   " __c18 ", %0":"=r"(bh));
+	asm volatile ("getcon   " __c18 ", %0":"=r"(bl));
+	bh = (bh) >> 32;
+	bl = (bl) & 0xffffffff;
+	asm volatile ("getcon   " __c4 ", %0":"=r"(ch));
+	asm volatile ("getcon   " __c4 ", %0":"=r"(cl));
+	ch = (ch) >> 32;
+	cl = (cl) & 0xffffffff;
+	printk("EXPE: %08Lx%08Lx KCR1: %08Lx%08Lx INTE: %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	asm volatile ("getcon   " __c6 ", %0":"=r"(ah));
+	asm volatile ("getcon   " __c6 ", %0":"=r"(al));
+	ah = (ah) >> 32;
+	al = (al) & 0xffffffff;
+	asm volatile ("getcon   " __c9 ", %0":"=r"(bh));
+	asm volatile ("getcon   " __c9 ", %0":"=r"(bl));
+	bh = (bh) >> 32;
+	bl = (bl) & 0xffffffff;
+	asm volatile ("getcon   " __c2 ", %0":"=r"(ch));
+	asm volatile ("getcon   " __c2 ", %0":"=r"(cl));
+	ch = (ch) >> 32;
+	cl = (cl) & 0xffffffff;
+	printk("PEXP: %08Lx%08Lx PSPC: %08Lx%08Lx PSSR: %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->pc) >> 32;
+	al = (regs->pc) & 0xffffffff;
+	bh = (regs->regs[18]) >> 32;
+	bl = (regs->regs[18]) & 0xffffffff;
+	ch = (regs->regs[15]) >> 32;
+	cl = (regs->regs[15]) & 0xffffffff;
+	printk("PC  : %08Lx%08Lx LINK: %08Lx%08Lx SP  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->sr) >> 32;
+	al = (regs->sr) & 0xffffffff;
+	asm volatile ("getcon   " __c13 ", %0":"=r"(bh));
+	asm volatile ("getcon   " __c13 ", %0":"=r"(bl));
+	bh = (bh) >> 32;
+	bl = (bl) & 0xffffffff;
+	asm volatile ("getcon   " __c17 ", %0":"=r"(ch));
+	asm volatile ("getcon   " __c17 ", %0":"=r"(cl));
+	ch = (ch) >> 32;
+	cl = (cl) & 0xffffffff;
+	printk("SR  : %08Lx%08Lx TEA : %08Lx%08Lx KCR0: %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[0]) >> 32;
+	al = (regs->regs[0]) & 0xffffffff;
+	bh = (regs->regs[1]) >> 32;
+	bl = (regs->regs[1]) & 0xffffffff;
+	ch = (regs->regs[2]) >> 32;
+	cl = (regs->regs[2]) & 0xffffffff;
+	printk("R0  : %08Lx%08Lx R1  : %08Lx%08Lx R2  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[3]) >> 32;
+	al = (regs->regs[3]) & 0xffffffff;
+	bh = (regs->regs[4]) >> 32;
+	bl = (regs->regs[4]) & 0xffffffff;
+	ch = (regs->regs[5]) >> 32;
+	cl = (regs->regs[5]) & 0xffffffff;
+	printk("R3  : %08Lx%08Lx R4  : %08Lx%08Lx R5  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[6]) >> 32;
+	al = (regs->regs[6]) & 0xffffffff;
+	bh = (regs->regs[7]) >> 32;
+	bl = (regs->regs[7]) & 0xffffffff;
+	ch = (regs->regs[8]) >> 32;
+	cl = (regs->regs[8]) & 0xffffffff;
+	printk("R6  : %08Lx%08Lx R7  : %08Lx%08Lx R8  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[9]) >> 32;
+	al = (regs->regs[9]) & 0xffffffff;
+	bh = (regs->regs[10]) >> 32;
+	bl = (regs->regs[10]) & 0xffffffff;
+	ch = (regs->regs[11]) >> 32;
+	cl = (regs->regs[11]) & 0xffffffff;
+	printk("R9  : %08Lx%08Lx R10 : %08Lx%08Lx R11 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+	printk("....\n");
+
+	ah = (regs->tregs[0]) >> 32;
+	al = (regs->tregs[0]) & 0xffffffff;
+	bh = (regs->tregs[1]) >> 32;
+	bl = (regs->tregs[1]) & 0xffffffff;
+	ch = (regs->tregs[2]) >> 32;
+	cl = (regs->tregs[2]) & 0xffffffff;
+	printk("T0  : %08Lx%08Lx T1  : %08Lx%08Lx T2  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+	printk("....\n");
+
+	print_dtlb();
+	print_itlb();
+}
+
+/* ======================================================================= */
+
+/*
+** Depending on <base> scan the MMU, Data or Instrction side
+** looking for a valid mapping matching Eaddr & asid.
+** Return -1 if not found or the TLB id entry otherwise.
+** Note: it works only for 4k pages!
+*/
+static unsigned long
+lookup_mmu_side(unsigned long base, unsigned long Eaddr, unsigned long asid)
+{
+	regType_t pteH;
+	unsigned long epn;
+	int count;
+
+	epn = Eaddr & 0xfffff000;
+
+	for (count = 0; count < MAX_TLBs; count++, base += TLB_STEP) {
+		pteH = getConfigReg(base);
+		if (GET_VALID(pteH))
+			if ((unsigned long) GET_EPN(pteH) == epn)
+				if ((unsigned long) GET_ASID(pteH) == asid)
+					break;
+	}
+	return ((unsigned long) ((count < MAX_TLBs) ? base : -1));
+}
+
+unsigned long lookup_dtlb(unsigned long Eaddr)
+{
+	unsigned long asid = get_asid();
+	return (lookup_mmu_side((u64) DTLB_BASE, Eaddr, asid));
+}
+
+unsigned long lookup_itlb(unsigned long Eaddr)
+{
+	unsigned long asid = get_asid();
+	return (lookup_mmu_side((u64) ITLB_BASE, Eaddr, asid));
+}
+
+void print_page(struct page *page)
+{
+	printk("  page[%p] -> index 0x%lx,  count 0x%x,  flags 0x%lx\n",
+	       page, page->index, atomic_read(&page->count), page->flags);
+	printk("       address_space = %p, pages =%ld\n", page->mapping,
+	       page->mapping->nrpages);
+
+}
diff -urN linux-2.4.22-pre2/arch/sh64/lib/io.c linux-2.4.22-pre3/arch/sh64/lib/io.c
--- linux-2.4.22-pre2/arch/sh64/lib/io.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/io.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,201 @@
+/* 
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * This file contains the I/O routines for use on the overdrive board
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#ifdef CONFIG_SH_CAYMAN
+#include <asm/cayman.h>
+#endif
+
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the SuperH architecture, we just read/write the
+ * memory location directly.
+ */
+
+#define dprintk(x...)
+
+//#define io_addr(x)  (((unsigned)(x) & 0x000fffff)| PCI_ST50_IO_ADDR )
+
+#ifdef CONFIG_SH_CAYMAN
+extern unsigned long smsc_virt;
+extern unsigned long pciio_virt;
+#define io_addr(x)  ( ((x)<0x400) ? \
+			(((x) << 2)|smsc_virt) : \
+			((unsigned long)(x)+pciio_virt) )
+#else
+#define io_addr(x)  ((unsigned long)(x)+pciio_virt)
+#endif
+
+unsigned long inb(unsigned long port)
+{
+	unsigned long r;
+
+	r = ctrl_inb(io_addr(port));
+	dprintk("inb(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port));
+	return r;
+}
+
+unsigned long inw(unsigned long port)
+{
+	unsigned long r;
+
+	r = ctrl_inw(io_addr(port));
+	dprintk("inw(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port));
+	return r;
+}
+
+unsigned long inl(unsigned long port)
+{
+	unsigned long r;
+
+	r = ctrl_inl(io_addr(port));
+	dprintk("inl(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port));
+	return r;
+}
+
+void outb(unsigned long value, unsigned long port)
+{
+	dprintk("outb(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port));
+	ctrl_outb(value, io_addr(port));
+}
+
+void outw(unsigned long value, unsigned long port)
+{
+	dprintk("outw(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port));
+	ctrl_outw(value, io_addr(port));
+}
+
+void outl(unsigned long value, unsigned long port)
+{
+	dprintk("outw(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port));
+	ctrl_outl(value, io_addr(port));
+}
+
+/* This is horrible at the moment - needs more work to do something sensible */
+#define IO_DELAY()
+
+#define OUT_DELAY(x,type) \
+void out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();}
+
+#define IN_DELAY(x,type) \
+unsigned type in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;}
+
+#if 1
+OUT_DELAY(b, long) OUT_DELAY(w, long) OUT_DELAY(l, long)
+ IN_DELAY(b, long) IN_DELAY(w, long) IN_DELAY(l, long)
+#endif
+/*  Now for the string version of these functions */
+void outsb(unsigned long port, const void *addr, unsigned long count)
+{
+	int i;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p++) {
+		outb(*p, port);
+	}
+}
+
+void insb(unsigned long port, void *addr, unsigned long count)
+{
+	int i;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p++) {
+		*p = inb(port);
+	}
+}
+
+/* For the 16 and 32 bit string functions, we have to worry about alignment.
+ * The SH does not do unaligned accesses, so we have to read as bytes and
+ * then write as a word or dword. 
+ * This can be optimised a lot more, especially in the case where the data
+ * is aligned
+ */
+
+void outsw(unsigned long port, const void *addr, unsigned long count)
+{
+	int i;
+	unsigned short tmp;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p += 2) {
+		tmp = (*p) | ((*(p + 1)) << 8);
+		outw(tmp, port);
+	}
+}
+
+void insw(unsigned long port, void *addr, unsigned long count)
+{
+	int i;
+	unsigned short tmp;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p += 2) {
+		tmp = inw(port);
+		p[0] = tmp & 0xff;
+		p[1] = (tmp >> 8) & 0xff;
+	}
+}
+
+void outsl(unsigned long port, const void *addr, unsigned long count)
+{
+	int i;
+	unsigned tmp;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p += 4) {
+		tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) |
+		    ((*(p + 3)) << 24);
+		outl(tmp, port);
+	}
+}
+
+void insl(unsigned long port, void *addr, unsigned long count)
+{
+	int i;
+	unsigned tmp;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p += 4) {
+		tmp = inl(port);
+		p[0] = tmp & 0xff;
+		p[1] = (tmp >> 8) & 0xff;
+		p[2] = (tmp >> 16) & 0xff;
+		p[3] = (tmp >> 24) & 0xff;
+
+	}
+}
+
+void memcpy_toio(unsigned long to, const void *from, long count)
+{
+	unsigned char *p = (unsigned char *) from;
+
+	while (count) {
+		count--;
+		writeb(*p++, to++);
+	}
+}
+
+void memcpy_fromio(void *to, unsigned long from, long count)
+{
+	int i;
+	unsigned char *p = (unsigned char *) to;
+
+	for (i = 0; i < count; i++) {
+		p[i] = readb(from);
+		from++;
+	}
+}
diff -urN linux-2.4.22-pre2/arch/sh64/lib/memcpy.c linux-2.4.22-pre3/arch/sh64/lib/memcpy.c
--- linux-2.4.22-pre2/arch/sh64/lib/memcpy.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/memcpy.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,82 @@
+/* 
+ * Copyright (C) 2002 Mark Debbage (Mark.Debbage@superh.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/string.h>
+
+// This is a simplistic optimization of memcpy to increase the
+// granularity of access beyond one byte using aligned 
+// loads and stores. This is not an optimal implementation
+// for SH-5 (especially with regard to prefetching and the cache), 
+// and a better version should be provided later ...
+
+void *memcpy(void *dest, const void *src, size_t count)
+{
+	char *d = (char *) dest, *s = (char *) src;
+
+	if (count >= 32) {
+		int i = 8 - (((unsigned long) d) & 0x7);
+
+		if (i != 8)
+			while (i-- && count--) {
+				*d++ = *s++;
+			}
+
+		if (((((unsigned long) d) & 0x7) == 0) &&
+		    ((((unsigned long) s) & 0x7) == 0)) {
+			while (count >= 32) {
+				unsigned long long t1, t2, t3, t4;
+				t1 = *(unsigned long long *) (s);
+				t2 = *(unsigned long long *) (s + 8);
+				t3 = *(unsigned long long *) (s + 16);
+				t4 = *(unsigned long long *) (s + 24);
+				*(unsigned long long *) (d) = t1;
+				*(unsigned long long *) (d + 8) = t2;
+				*(unsigned long long *) (d + 16) = t3;
+				*(unsigned long long *) (d + 24) = t4;
+				d += 32;
+				s += 32;
+				count -= 32;
+			}
+			while (count >= 8) {
+				*(unsigned long long *) d =
+				    *(unsigned long long *) s;
+				d += 8;
+				s += 8;
+				count -= 8;
+			}
+		}
+
+		if (((((unsigned long) d) & 0x3) == 0) &&
+		    ((((unsigned long) s) & 0x3) == 0)) {
+			while (count >= 4) {
+				*(unsigned long *) d = *(unsigned long *) s;
+				d += 4;
+				s += 4;
+				count -= 4;
+			}
+		}
+
+		if (((((unsigned long) d) & 0x1) == 0) &&
+		    ((((unsigned long) s) & 0x1) == 0)) {
+			while (count >= 2) {
+				*(unsigned short *) d = *(unsigned short *) s;
+				d += 2;
+				s += 2;
+				count -= 2;
+			}
+		}
+	}
+
+	while (count--) {
+		*d++ = *s++;
+	}
+
+	return d;
+}
diff -urN linux-2.4.22-pre2/arch/sh64/lib/old-checksum.c linux-2.4.22-pre3/arch/sh64/lib/old-checksum.c
--- linux-2.4.22-pre2/arch/sh64/lib/old-checksum.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/old-checksum.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,17 @@
+/*
+ * FIXME: old compatibility stuff, will be removed soon.
+ */
+
+#include <net/checksum.h>
+
+unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum)
+{
+	int src_err=0, dst_err=0;
+
+	sum = csum_partial_copy_generic ( src, dst, len, sum, &src_err, &dst_err);
+
+	if (src_err || dst_err)
+		printk("old csum_partial_copy_fromuser(), tell mingo to convert me.\n");
+
+	return sum;
+}
diff -urN linux-2.4.22-pre2/arch/sh64/lib/page_clear.S linux-2.4.22-pre3/arch/sh64/lib/page_clear.S
--- linux-2.4.22-pre2/arch/sh64/lib/page_clear.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/page_clear.S	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,46 @@
+/* Written by Richard P. Curnow, SuperH (UK) Ltd.
+
+   Tight version of memset for the case of just clearing a page.  It turns out
+   that having the alloco's spaced out slightly due to the increment/branch
+   pair causes them to contend less for access to the cache.  Similarly,
+   keeping the stores apart from the allocos causes less contention.  => Do two
+   separate loops.  Do multiple stores per loop to amortise the
+   increment/branch cost a little.
+
+   Parameters:
+   r2 : source effective address (start of page)
+
+   Always clears 4096 bytes.
+  
+*/
+
+	.section .text..SHmedia32,"ax"
+	.little
+
+	.balign 8
+	.global sh64_page_clear
+sh64_page_clear:
+	pta/l 1f, tr1
+	pta/l 2f, tr2
+	ptabs/l r18, tr0
+
+	movi 4096, r7
+	add  r2, r7, r7
+	add  r2, r63, r6
+1:
+	alloco r6, 0
+	addi	r6, 32, r6
+	bgt/l	r7, r6, tr1
+
+	add  r2, r63, r6
+2:
+	st.q  r6,   0, r63
+	st.q  r6,   8, r63
+	st.q  r6,  16, r63
+	st.q  r6,  24, r63
+	addi r6, 32, r6
+	bgt/l r7, r6, tr2
+	
+	blink tr0, r63
+
+
diff -urN linux-2.4.22-pre2/arch/sh64/lib/page_copy.S linux-2.4.22-pre3/arch/sh64/lib/page_copy.S
--- linux-2.4.22-pre2/arch/sh64/lib/page_copy.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/page_copy.S	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,77 @@
+/* Written by Richard P. Curnow, SuperH (UK) Ltd.
+
+   Tight version of mempy for the case of just copying a page.
+   Prefetch strategy empirically optimised against RTL simulations
+   of SH5-101 cut2 eval chip with Cayman board DDR memory.
+
+   Parameters:
+   r2 : source effective address (start of page)
+   r3 : destination effective address (start of page)
+
+   Always copies 4096 bytes.
+  
+   Points to review.
+   * Currently the prefetch is 4 lines ahead and the alloco is 2 lines ahead.
+     It seems like the prefetch needs to be at at least 4 lines ahead to get
+     the data into the cache in time, and the allocos contend with outstanding
+     prefetches for the same cache set, so it's better to have the numbers
+     different.
+   */
+
+	.section .text..SHmedia32,"ax"
+	.little
+
+	.balign 8
+	.global sh64_page_copy
+sh64_page_copy:
+
+	/* Copy 4096 bytes worth of data from r2 to r3.
+	   Do prefetches 4 lines ahead.
+	   Do alloco 2 lines ahead */
+
+	pta 1f, tr1
+	pta 2f, tr2
+	pta 3f, tr3
+	ptabs r18, tr0
+
+	ld.q r2, 0x00, r63
+	ld.q r2, 0x20, r63
+	ld.q r2, 0x40, r63
+	ld.q r2, 0x60, r63
+	alloco r3, 0x00
+	alloco r3, 0x20
+
+	movi 3968, r6
+	add  r3, r6, r6
+	addi r6, 64, r7
+	addi r7, 64, r8
+	sub r2, r3, r60
+	addi r60, 8, r61
+	addi r61, 8, r62
+	addi r62, 8, r23
+	addi r60, 0x80, r22
+
+/* Minimal code size.  The extra branches inside the loop don't cost much
+   because they overlap with the time spent waiting for prefetches to
+   complete. */
+1:
+	bge/u r3, r6, tr2  ! skip prefetch for last 4 lines
+	ldx.q r3, r22, r63 ! prefetch 4 lines hence
+2:
+	bge/u r3, r7, tr3  ! skip alloco for last 2 lines
+	alloco r3, 0x40    ! alloc destination line 2 lines ahead
+3:
+	ldx.q r3, r60, r36
+	ldx.q r3, r61, r37
+	ldx.q r3, r62, r38
+	ldx.q r3, r23, r39
+	st.q  r3,   0, r36
+	st.q  r3,   8, r37
+	st.q  r3,  16, r38
+	st.q  r3,  24, r39
+	addi r3, 32, r3
+	bgt/l r8, r3, tr1
+
+	blink tr0, r63	   ! return
+
+
diff -urN linux-2.4.22-pre2/arch/sh64/lib/panic.c linux-2.4.22-pre3/arch/sh64/lib/panic.c
--- linux-2.4.22-pre2/arch/sh64/lib/panic.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/panic.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,60 @@
+/* Panic handler. MUST BE PIC. BE CAREFUL WHAT YOU DO,
+ * AS THERE ARE NO STATICS AVAILABLE, AND NOWHERE TO GO 
+ * MMU IS OFF!!!!!!!!
+ */
+
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/registers.h>
+
+/* THIS IS A PHYSICAL ADDRESS */
+#define HDSP2534_ADDR (0x04002100)
+
+void
+panic_handler(unsigned long panicPC, unsigned long panicSSR,
+	      unsigned long panicEXPEVT)
+{
+	int i;
+	unsigned nibble;
+
+#ifdef CONFIG_SH_CAYMAN
+
+	while (1) {
+
+		/* This piece of code displays the PC on the LED display */
+		for (i = 0; i < 8; i++) {
+			nibble = ((panicPC >> (i * 4)) & 0xf);
+
+			ctrl_outb(nibble + ((nibble > 9) ? 55 : 48),
+				  HDSP2534_ADDR + 0xe0 + ((7 - i) << 2));
+		}
+
+		for (i = 0; i < 2500000; i++) {
+		}		/* poor man's delay */
+
+		for (i = 0; i < 8; i++) {
+			nibble = ((panicSSR >> (i * 4)) & 0xf);
+
+			ctrl_outb(nibble + ((nibble > 9) ? 55 : 48),
+				  HDSP2534_ADDR + 0xe0 + ((7 - i) << 2));
+		}
+
+		for (i = 0; i < 2500000; i++) {
+		}		/* poor man's delay */
+
+		for (i = 0; i < 8; i++) {
+			nibble = ((panicEXPEVT >> (i * 4)) & 0xf);
+
+			ctrl_outb(nibble + ((nibble > 9) ? 55 : 48),
+				  HDSP2534_ADDR + 0xe0 + ((7 - i) << 2));
+		}
+
+		for (i = 0; i < 2500000; i++) {
+		}		/* poor man's delay */
+	}
+#endif
+
+	/* Never return from the panic handler */
+	for (;;) ;
+
+}
diff -urN linux-2.4.22-pre2/arch/sh64/lib/syscalltab.h linux-2.4.22-pre3/arch/sh64/lib/syscalltab.h
--- linux-2.4.22-pre2/arch/sh64/lib/syscalltab.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/syscalltab.h	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,311 @@
+struct syscall_info {
+  int num_params;
+  const char *name;
+};
+
+struct syscall_info syscall_info_table[]={
+	{ 0,		"setup"		}, /* 0 */
+	{ 1,		"_exit"		}, /* 1 */
+	{ 0,		"fork"		}, /* 2 */
+	{ 3,		"read"		}, /* 3 */
+	{ 3,		"write"		}, /* 4 */
+	{ 3,		"open"		}, /* 5 */
+	{ 1,		"close"		}, /* 6 */
+	{ 3,		"waitpid"	}, /* 7 */
+	{ 2,		"creat"		}, /* 8 */
+	{ 2,		"link"		}, /* 9 */
+	{ 1,		"unlink"	}, /* 10 */
+	{ 3,		"execve"	}, /* 11 */
+	{ 1,		"chdir"		}, /* 12 */
+	{ 1,		"time"		}, /* 13 */
+	{ 3,		"mknod"		}, /* 14 */
+	{ 2,		"chmod"		}, /* 15 */
+	{ 3,		"lchown"	}, /* 16 */
+	{ 0,		"break"		}, /* 17 */
+	{ 2,		"oldstat"	}, /* 18 */
+	{ 3,		"lseek"		}, /* 19 */
+	{ 0,		"getpid"	}, /* 20 */
+	{ 5,		"mount"		}, /* 21 */
+	{ 1,		"oldumount"	}, /* 22 */
+	{ 1,		"setuid"	}, /* 23 */
+	{ 0,		"getuid"	}, /* 24 */
+	{ 1,		"stime"		}, /* 25 */
+	{ 4,		"ptrace"	}, /* 26 */
+	{ 1,		"alarm"		}, /* 27 */
+	{ 2,		"oldfstat"	}, /* 28 */
+	{ 0,		"pause"		}, /* 29 */
+	{ 2,		"utime"		}, /* 30 */
+	{ 2,		"stty"		}, /* 31 */
+	{ 2,		"gtty"		}, /* 32 */
+	{ 2,		"access"	}, /* 33 */
+	{ 1,		"nice"		}, /* 34 */
+	{ 0,		"ftime"		}, /* 35 */
+	{ 0,		"sync"		}, /* 36 */
+	{ 2,		"kill"		}, /* 37 */
+	{ 2,		"rename"	}, /* 38 */
+	{ 2,		"mkdir"		}, /* 39 */
+	{ 1,		"rmdir"		}, /* 40 */
+	{ 1,		"dup"		}, /* 41 */
+	{ 1,		"pipe"		}, /* 42 */
+	{ 1,		"times"		}, /* 43 */
+	{ 0,		"prof"		}, /* 44 */
+	{ 1,		"brk"		}, /* 45 */
+	{ 1,		"setgid"	}, /* 46 */
+	{ 0,		"getgid"	}, /* 47 */
+	{ 3,		"signal"	}, /* 48 */
+	{ 0,		"geteuid"	}, /* 49 */
+	{ 0,		"getegid"	}, /* 50 */
+	{ 1,		"acct"		}, /* 51 */
+	{ 2,		"umount"	}, /* 52 */
+	{ 0,		"lock"		}, /* 53 */
+	{ 3,		"ioctl"		}, /* 54 */
+	{ 3,		"fcntl"		}, /* 55 */
+	{ 0,		"mpx"		}, /* 56 */
+	{ 2,		"setpgid"	}, /* 57 */
+	{ 2,		"ulimit"	}, /* 58 */
+        { 1,	        "oldolduname"	}, /* 59 */
+	{ 1,		"umask"		}, /* 60 */
+	{ 1,		"chroot"	}, /* 61 */
+	{ 2,		"ustat"		}, /* 62 */
+	{ 2,		"dup2"		}, /* 63 */
+	{ 0,		"getppid"	}, /* 64 */
+	{ 0,		"getpgrp"	}, /* 65 */
+	{ 0,		"setsid"	}, /* 66 */
+	{ 3,		"sigaction"	}, /* 67 */
+	{ 0,		"siggetmask"	}, /* 68 */
+	{ 1,		"sigsetmask"	}, /* 69 */
+	{ 2,		"setreuid"	}, /* 70 */
+	{ 2,		"setregid"	}, /* 71 */
+	{ 3,		"sigsuspend"	}, /* 72 */
+	{ 1,		"sigpending"	}, /* 73 */
+	{ 2,	        "sethostname"	}, /* 74 */
+	{ 2,		"setrlimit"	}, /* 75 */
+	{ 2,		"getrlimit"	}, /* 76 */
+	{ 2,		"getrusage"	}, /* 77 */
+	{ 2,	        "gettimeofday"	}, /* 78 */
+	{ 2,	        "settimeofday"	}, /* 79 */
+	{ 2,		"getgroups"	}, /* 80 */
+	{ 2,		"setgroups"	}, /* 81 */
+	{ 1,		"oldselect"	}, /* 82 */
+	{ 2,		"symlink"	}, /* 83 */
+	{ 2,		"oldlstat"	}, /* 84 */
+	{ 3,		"readlink"	}, /* 85 */
+	{ 1,		"uselib"	}, /* 86 */
+	{ 1,		"swapon"	}, /* 87 */
+	{ 3,		"reboot"	}, /* 88 */
+	{ 3,		"readdir"	}, /* 89 */
+	{ 6,		"old_mmap"   	}, /* 90 */
+	{ 2,		"munmap"	}, /* 91 */
+	{ 2,		"truncate"	}, /* 92 */
+	{ 2,		"ftruncate"	}, /* 93 */
+	{ 2,		"fchmod"	}, /* 94 */
+	{ 3,		"fchown"	}, /* 95 */
+	{ 2,	        "getpriority"	}, /* 96 */
+	{ 3,	        "setpriority"	}, /* 97 */
+	{ 4,		"profil"	}, /* 98 */
+	{ 2,		"statfs"	}, /* 99 */
+	{ 2,		"fstatfs"	}, /* 100 */
+	{ 3,		"ioperm"	}, /* 101 */
+	{ 2,		"socketcall"	}, /* 102 */
+	{ 3,		"syslog"	}, /* 103 */
+	{ 3,		"setitimer"	}, /* 104 */
+	{ 2,		"getitimer"	}, /* 105 */
+	{ 2,		"stat"		}, /* 106 */
+	{ 2,		"lstat"		}, /* 107 */
+	{ 2,		"fstat"		}, /* 108 */
+	{ 1,		"olduname"	}, /* 109 */
+	{ 1,		"iopl"		}, /* 110 */
+	{ 0,		"vhangup"	}, /* 111 */
+	{ 0,		"idle"		}, /* 112 */
+	{ 1,		"vm86old"	}, /* 113 */
+	{ 4,		"wait4"		}, /* 114 */
+	{ 1,		"swapoff"	}, /* 115 */
+	{ 1,		"sysinfo"	}, /* 116 */
+	{ 5,		"ipc"		}, /* 117 */
+	{ 1,		"fsync"		}, /* 118 */
+	{ 1,		"sigreturn"	}, /* 119 */
+	{ 2,		"clone"		}, /* 120 */
+	{ 2,	        "setdomainname"	}, /* 121 */
+	{ 1,		"uname"		}, /* 122 */
+	{ 3,		"modify_ldt"	}, /* 123 */
+	{ 1,		"adjtimex"	}, /* 124 */
+	{ 3,		"mprotect"	}, /* 125 */
+	{ 3,	        "sigprocmask"	}, /* 126 */
+	{ 2,	        "create_module"	}, /* 127 */
+	{ 2,	        "init_module"	}, /* 128 */
+	{ 1,	        "delete_module"	}, /* 129 */
+	{ 1,	        "get_kernel_syms"}, /* 130 */
+	{ 4,		"quotactl"	}, /* 131 */
+	{ 1,		"getpgid"	}, /* 132 */
+	{ 1,		"fchdir"	}, /* 133 */
+	{ 0,		"bdflush"	}, /* 134 */
+	{ 3,		"sysfs"		}, /* 135 */
+	{ 1,	        "personality"	}, /* 136 */
+	{ 5,	        "afs_syscall"	}, /* 137 */
+	{ 1,		"setfsuid"	}, /* 138 */
+	{ 1,		"setfsgid"	}, /* 139 */
+	{ 5,		"_llseek"	}, /* 140 */
+	{ 3,		"getdents"	}, /* 141 */
+	{ 5,		"select"	}, /* 142 */
+	{ 2,		"flock"		}, /* 143 */
+	{ 3,		"msync"		}, /* 144 */
+	{ 3,		"readv"		}, /* 145 */
+	{ 3,		"writev"	}, /* 146 */
+	{ 1,		"getsid"	}, /* 147 */
+	{ 1,		"fdatasync"	}, /* 148 */
+	{ 1,		"_sysctl"	}, /* 149 */
+	{ 1,		"mlock"		}, /* 150 */
+	{ 2,		"munlock"	}, /* 151 */
+	{ 2,		"mlockall"	}, /* 152 */
+	{ 1,		"munlockall"	}, /* 153 */
+	{ 0,	        "sched_setparam"}, /* 154 */
+	{ 2,	        "sched_getparam"}, /* 155 */
+	{ 3,	        "sched_setscheduler"}, /* 156 */
+	{ 1,	        "sched_getscheduler"}, /* 157 */
+	{ 0,	        "sched_yield"}, /* 158 */
+	{ 1,            "sched_get_priority_max"}, /* 159 */
+	{ 1,            "sched_get_priority_min"}, /* 160 */
+	{ 2,            "sched_rr_get_interval"}, /* 161 */
+	{ 2,		"nanosleep"	}, /* 162 */
+	{ 4,		"mremap"	}, /* 163 */
+	{ 3,		"setresuid"	}, /* 164 */
+	{ 3,		"getresuid"	}, /* 165 */
+	{ 5,		"vm86"		}, /* 166 */
+	{ 5,	        "query_module"	}, /* 167 */
+	{ 3,		"poll"		}, /* 168 */
+	{ 3,		"nfsservctl"	}, /* 169 */
+	{ 3,		"setresgid"	}, /* 170 */
+	{ 3,		"getresgid"	}, /* 171 */
+	{ 5,		"prctl"		}, /* 172 */
+	{ 1,		"rt_sigreturn"	}, /* 173 */
+	{ 4,	        "rt_sigaction"  }, /* 174 */
+	{ 4,	        "rt_sigprocmask"}, /* 175 */
+	{ 2,	        "rt_sigpending"	}, /* 176 */
+	{ 4,	        "rt_sigtimedwait"}, /* 177 */
+	{ 3,            "rt_sigqueueinfo"}, /* 178 */
+	{ 2,	        "rt_sigsuspend"	}, /* 179 */
+
+	{ 5,		"pread"		}, /* 180 */
+	{ 5,		"pwrite"	}, /* 181 */
+	{ 3,		"chown"		}, /* 182 */
+	{ 2,		"getcwd"	}, /* 183 */
+	{ 2,		"capget"	}, /* 184 */
+	{ 2,		"capset"	}, /* 185 */
+	{ 2,	        "sigaltstack"	}, /* 186 */
+	{ 4,		"sendfile"	}, /* 187 */
+	{ 5,		"SYS_188"	}, /* 188 */
+	{ 5,		"SYS_189"	}, /* 189 */
+	{ 0,		"vfork"		}, /* 190 */
+	{ 5,		"getrlimit"	}, /* 191 */
+	{ 6,		"mmap2"		}, /* 192 */
+	{ 5,		"truncate64"	}, /* 193 */
+	{ 5,		"ftruncate64"	}, /* 194 */
+	{ 2,		"stat64"	}, /* 195 */
+	{ 2,		"lstat64"	}, /* 196 */
+	{ 2,		"fstat64"	}, /* 197 */
+        { 3,		"lchown32"	}, /* 198 */
+        { 0,		"getuid32"	}, /* 199 */
+
+	{ 0,		"getgid32"	}, /* 200 */
+	{ 0,		"geteuid32"	}, /* 201 */
+	{ 0,		"getegid32"	}, /* 202 */
+	{ 2,		"setreuid32"	}, /* 203 */
+	{ 2,		"setregid32"	}, /* 204 */
+	{ 2,		"getgroups32"	}, /* 205 */
+	{ 2,		"setgroups32"	}, /* 206 */
+	{ 3,		"fchown32"	}, /* 207 */
+	{ 3,		"setresuid32"	}, /* 208 */
+	{ 3,		"getresuid32"	}, /* 209 */
+	{ 3,		"setresgid32"	}, /* 210 */
+	{ 3,		"getsetgid32"	}, /* 211 */
+	{ 3,		"chown32"	}, /* 212 */
+	{ 1,		"setuid32"	}, /* 213 */
+	{ 1,		"setgid32"	}, /* 214 */
+	{ 1,		"setfsuid32"	}, /* 215 */
+	{ 1,		"setfsgid32"	}, /* 216 */
+	{ 2,		"pivot_root"	}, /* 217 */
+	{ 3,		"mincore"	}, /* 218 */
+	{ 3,		"madvise"	}, /* 219 */
+	{ 4,		"getdents64"	}, /* 220 */
+	{ 3,		"fcntl64"	}, /* 221 */
+	{ 4,		"SYS_222"	}, /* 222 */
+	{ 4,		"SYS_223"	}, /* 223 */
+	{ 4,		"SYS_224"	}, /* 224 */
+	{ 5,		"SYS_225"	}, /* 225 */
+	{ 5,		"SYS_226"	}, /* 226 */
+	{ 5,		"SYS_227"	}, /* 227 */
+	{ 5,		"SYS_228"	}, /* 228 */
+	{ 5,		"SYS_229"	}, /* 229 */
+	{ 8,		"socket_subcall"}, /* 230 */
+	{ 3,		"socket"	}, /* 231 */
+	{ 3,		"bind"		}, /* 232 */
+	{ 3,		"connect"	}, /* 233 */
+	{ 2,		"listen"	}, /* 234 */
+	{ 3,		"accept"	}, /* 235 */
+	{ 3,	        "getsockname"	}, /* 236 */
+	{ 3,	        "getpeername"	}, /* 237 */
+	{ 4,		"socketpair"	}, /* 238 */
+	{ 4,		"send"		}, /* 239 */
+	{ 4,		"recv"		}, /* 240 */
+	{ 6,		"sendto"	}, /* 241 */
+	{ 6,		"recvfrom"	}, /* 242 */
+	{ 2,		"shutdown"	}, /* 243 */
+	{ 5,		"setsockopt"	}, /* 244 */
+	{ 5,		"getsockopt"	}, /* 245 */
+	{ 5,		"sendmsg"	}, /* 246 */
+	{ 5,		"recvmsg"	}, /* 247 */
+	{ 5,		"SYS_248"	}, /* 248 */
+	{ 5,		"SYS_249"	}, /* 249 */
+	{ 4,		"ipc_subcall"	}, /* 250 */
+	{ 4,		"semop"		}, /* 251 */
+	{ 4,		"semget"	}, /* 252 */
+	{ 4,		"semctl"	}, /* 253 */
+	{ 4,		"ipc_subcall"	}, /* 254 */
+	{ 4,		"ipc_subcall"	}, /* 255 */
+	{ 4,		"ipc_subcall"	}, /* 256 */
+	{ 4,		"ipc_subcall"	}, /* 257 */
+	{ 4,		"ipc_subcall"	}, /* 258 */
+	{ 4,		"ipc_subcall"	}, /* 259 */
+	{ 4,		"ipc_subcall"	}, /* 260 */
+	{ 4,		"msgsnd"	}, /* 261 */
+	{ 4,		"msgrcv"	}, /* 262 */
+	{ 4,		"msgget"	}, /* 263 */
+	{ 4,		"msgctl"	}, /* 264 */
+	{ 4,		"ipc_subcall"	}, /* 265 */
+	{ 4,		"ipc_subcall"	}, /* 266 */
+	{ 4,		"ipc_subcall"	}, /* 267 */
+	{ 4,		"ipc_subcall"	}, /* 268 */
+	{ 4,		"ipc_subcall"	}, /* 269 */
+	{ 4,		"ipc_subcall"	}, /* 270 */
+	{ 4,		"shmat"		}, /* 271 */
+	{ 4,		"shmdt"		}, /* 272 */
+	{ 4,		"shmget"	}, /* 273 */
+	{ 4,		"shmctl"	}, /* 274 */
+	{ 5,		"SYS_275"	}, /* 275 */
+	{ 5,		"SYS_276"	}, /* 276 */
+	{ 5,		"SYS_277"	}, /* 277 */
+	{ 5,		"SYS_278"	}, /* 278 */
+	{ 5,		"SYS_279"	}, /* 279 */
+	{ 8,		"socket_subcall"}, /* 280 */
+	{ 3,		"socket"	}, /* 281 */
+	{ 3,		"bind"		}, /* 282 */
+	{ 3,		"connect"	}, /* 283 */
+	{ 2,		"listen"	}, /* 284 */
+	{ 3,		"accept"	}, /* 285 */
+	{ 3,	        "getsockname"	}, /* 286 */
+	{ 3,	        "getpeername"	}, /* 287 */
+	{ 4,		"socketpair"	}, /* 288 */
+	{ 4,		"send"		}, /* 289 */
+	{ 4,		"recv"		}, /* 290 */
+	{ 6,		"sendto"	}, /* 291 */
+	{ 6,		"recvfrom"	}, /* 292 */
+	{ 2,		"shutdown"	}, /* 293 */
+	{ 5,		"setsockopt"	}, /* 294 */
+	{ 5,		"getsockopt"	}, /* 295 */
+	{ 5,		"sendmsg"	}, /* 296 */
+	{ 5,		"recvmsg"	}, /* 297 */
+	{ 5,		"SYS_298"	}, /* 298 */
+	{ 5,		"SYS_299"	}, /* 299 */
+};
+
+#define NUM_SYSCALL_INFO_ENTRIES (sizeof(syscall_info_table)/sizeof(struct syscall_info))
diff -urN linux-2.4.22-pre2/arch/sh64/lib/udelay.c linux-2.4.22-pre3/arch/sh64/lib/udelay.c
--- linux-2.4.22-pre2/arch/sh64/lib/udelay.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/lib/udelay.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 1993, 2000 Linus Torvalds
+ *
+ * Delay routines, using a pre-computed "loops_per_jiffy" value.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <asm/param.h>
+#include <asm/smp.h>
+#include <linux/delay.h>
+
+/*
+ * Use only for very small delays (< 1 msec). 
+ *
+ * The active part of our cycle counter is only 32-bits wide, and
+ * we're treating the difference between two marks as signed.  On
+ * a 1GHz box, that's about 2 seconds.
+ */
+
+void __delay(int loops)
+{
+	long long dummy;
+	__asm__ __volatile__("gettr	" __t0 ", %1\n\t"
+			     "_pta	4, " __t0 "\n\t"
+			     "addi	%0, -1, %0\n\t"
+			     "bne	%0, r63, " __t0 "\n\t"
+			     "ptabs	%1, " __t0 "\n\t":"=r"(loops),
+			     "=r"(dummy)
+			     :"0"(loops));
+}
+
+void __udelay(unsigned long long usecs, unsigned long lpj)
+{
+	usecs *= (((unsigned long long) HZ << 32) / 1000000) * lpj;
+	__delay((long long) usecs >> 32);
+}
+
+void __ndelay(unsigned long long nsecs, unsigned long lpj)
+{
+	nsecs *= (((unsigned long long) HZ << 32) / 1000000000) * lpj;
+	__delay((long long) nsecs >> 32);
+}
+
+void udelay(unsigned long usecs)
+{
+	__udelay(usecs, loops_per_jiffy);
+}
+
+void ndelay(unsigned long nsecs)
+{
+	__ndelay(nsecs, loops_per_jiffy);
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/mach-cayman/Makefile linux-2.4.22-pre3/arch/sh64/mach-cayman/Makefile
--- linux-2.4.22-pre2/arch/sh64/mach-cayman/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mach-cayman/Makefile	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,15 @@
+#
+# Makefile for the Hitachi Cayman specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+O_TARGET := cayman.o
+
+obj-y := setup.o irq.o
+obj-$(CONFIG_HEARTBEAT)	+= led.o
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.22-pre2/arch/sh64/mach-cayman/irq.c linux-2.4.22-pre3/arch/sh64/mach-cayman/irq.c
--- linux-2.4.22-pre2/arch/sh64/mach-cayman/irq.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mach-cayman/irq.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,188 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/irq_cayman.c
+ *
+ * SH-5 Cayman Interrupt Support
+ *
+ * This file handles the board specific parts of the Cayman interrupt system
+ *
+ * Copyright (C) 2002 Stuart Menefy
+ */
+
+#include <linux/config.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/signal.h>
+#include <asm/cayman.h>
+
+unsigned long epld_virt;
+
+#define EPLD_BASE        0x04002000
+#define EPLD_STATUS_BASE (epld_virt + 0x10)
+#define EPLD_MASK_BASE   (epld_virt + 0x20)
+
+static void cayman_interrupt_smsc(int irq, void *dev_id, struct pt_regs *regs)
+{
+        printk(KERN_INFO "CAYMAN: spurious interrupt\n");
+}
+
+static void cayman_interrupt_pci2(int irq, void *dev_id, struct pt_regs *regs)
+{
+        printk(KERN_INFO "CAYMAN: spurious PCI interrupt, IRQ %d\n", irq);
+}
+
+static struct irqaction cayman_action_smsc = {
+	cayman_interrupt_smsc, SA_INTERRUPT, 0, "Cayman SMSC Mux",
+	NULL, NULL
+};
+
+static struct irqaction cayman_action_pci2 = {
+	cayman_interrupt_pci2, SA_INTERRUPT, 0, "Cayman PCI2 Mux",
+	NULL, NULL
+};
+
+static void enable_cayman_irq(unsigned int irq)
+{
+	unsigned long flags;
+	unsigned long mask;
+	unsigned int reg;
+	unsigned char bit;	
+
+	irq -= START_EXT_IRQS;
+	reg = EPLD_MASK_BASE + ((irq / 8) << 2);
+	bit = 1<<(irq % 8);
+	save_and_cli(flags);
+	mask = ctrl_inl(reg);
+	mask |= bit;
+	ctrl_outl(mask, reg);
+	restore_flags(flags);
+}
+
+void disable_cayman_irq(unsigned int irq)
+{
+	unsigned long flags;
+	unsigned long mask;
+	unsigned int reg;
+	unsigned char bit;	
+
+	irq -= START_EXT_IRQS;
+	reg = EPLD_MASK_BASE + ((irq / 8) << 2);
+	bit = 1<<(irq % 8);
+	save_and_cli(flags);
+	mask = ctrl_inl(reg);
+	mask &= ~bit;
+	ctrl_outl(mask, reg);
+	restore_flags(flags);
+}
+
+static void ack_cayman_irq(unsigned int irq)
+{
+	disable_cayman_irq(irq);
+}
+
+static void end_cayman_irq(unsigned int irq)
+{
+	/* SIM: Note when we upgrade to the new kernel, this will need to be aded:
+	 * if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+	 */
+	enable_cayman_irq(irq);
+}
+
+static unsigned int startup_cayman_irq(unsigned int irq)
+{ 
+	enable_cayman_irq(irq);
+	return 0; /* never anything pending */
+}
+
+static void shutdown_cayman_irq(unsigned int irq)
+{
+	disable_cayman_irq(irq);
+}
+
+struct hw_interrupt_type cayman_irq_type = {
+	"Cayman-IRQ",
+	startup_cayman_irq,
+	shutdown_cayman_irq,
+	enable_cayman_irq,
+	disable_cayman_irq,
+	ack_cayman_irq,
+	end_cayman_irq
+};
+
+int cayman_irq_demux(int evt)
+{
+	int irq = intc_evt_to_irq[evt];
+
+	if (irq == SMSC_IRQ) {
+		unsigned long status;
+		int i;
+
+		status = ctrl_inl(EPLD_STATUS_BASE) &
+			 ctrl_inl(EPLD_MASK_BASE) & 0xff;
+		if (status == 0) {
+			irq = -1;
+		} else {
+			for (i=0; i<8; i++) {
+				if (status & (1<<i))
+					break;
+			}
+			irq = START_EXT_IRQS + i;
+		}
+	}
+
+	if (irq == PCI2_IRQ) {
+		unsigned long status;
+		int i;
+
+		status = ctrl_inl(EPLD_STATUS_BASE + 3 * sizeof(u32)) &
+			 ctrl_inl(EPLD_MASK_BASE + 3 * sizeof(u32)) & 0xff;
+		if (status == 0) {
+			irq = -1;
+		} else {
+			for (i=0; i<8; i++) {
+				if (status & (1<<i))
+					break;
+			}
+			irq = START_EXT_IRQS + (3 * 8) + i;
+		}
+	}
+
+	return irq;
+}
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
+int cayman_irq_describe(char* p, int irq)
+{
+  if (irq < NR_INTC_IRQS) 
+    return intc_irq_describe(p, irq);
+  else if (irq < NR_INTC_IRQS + 8)
+    return sprintf(p, "(SMSC %d)", irq - NR_INTC_IRQS);
+  else if ((irq > NR_INTC_IRQS + 24) && (irq < NR_INTC_IRQS + 32))
+    return sprintf(p, "(PCI2 %d)", irq - (NR_INTC_IRQS + 24)); 
+  else
+    return 0;
+}
+#endif
+
+void init_cayman_irq(void)
+{
+	int i;
+
+	epld_virt = onchip_remap(EPLD_BASE, 1024, "EPLD");
+	if (epld_virt == NULL) {
+		panic("Unable to remap EPLD\n");
+	}
+
+	for (i=0; i<NR_EXT_IRQS; i++) {
+		irq_desc[START_EXT_IRQS + i].handler = &cayman_irq_type;
+	}
+	
+	/* Setup the SMSC interrupt */
+	setup_irq(SMSC_IRQ, &cayman_action_smsc);
+	setup_irq(PCI2_IRQ, &cayman_action_pci2);
+}
diff -urN linux-2.4.22-pre2/arch/sh64/mach-cayman/led.c linux-2.4.22-pre3/arch/sh64/mach-cayman/led.c
--- linux-2.4.22-pre2/arch/sh64/mach-cayman/led.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mach-cayman/led.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,51 @@
+/*
+ * arch/sh64/kernel/led_cayman.c
+ *
+ * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Flash the LEDs
+ */
+#include <asm/io.h>
+
+/*
+** It is supposed these functions to be used for a low level
+** debugging (via Cayman LEDs), hence to be available as soon
+** as possible.
+** Unfortunately Cayman LEDs relies on Cayman EPLD to be mapped
+** (this happen when IRQ are initialized... quite late).
+** These triky dependencies should be removed. Temporary, it
+** may be enough to NOP until EPLD is mapped.
+*/
+
+extern unsigned long epld_virt;
+
+#define LED_ADDR      (epld_virt + 0x008)
+#define HDSP2534_ADDR (epld_virt + 0x100)
+
+void mach_led(int position, int value)
+{
+	if (!epld_virt)
+		return;
+
+	if (value)
+		ctrl_outl(0, LED_ADDR);
+	else
+		ctrl_outl(1, LED_ADDR);
+
+}
+
+void mach_alphanum(int position, unsigned char value)
+{
+	if (!epld_virt)
+		return;
+
+	ctrl_outb(value, HDSP2534_ADDR + 0xe0 + (position << 2));
+}
+
+void mach_alphanum_brightness(int setting)
+{
+	ctrl_outb(setting & 7, HDSP2534_ADDR + 0xc0);
+}
diff -urN linux-2.4.22-pre2/arch/sh64/mach-cayman/setup.c linux-2.4.22-pre3/arch/sh64/mach-cayman/setup.c
--- linux-2.4.22-pre2/arch/sh64/mach-cayman/setup.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mach-cayman/setup.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,209 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/mach-cayman/setup.c
+ *
+ * SH5 Cayman support
+ *
+ * This file handles the architecture-dependent parts of initialization
+ *
+ * Copyright David J. Mckay.
+ * Needs major work!
+ *
+ * benedict.gaster@superh.com:	 3rd May 2002
+ *    Added support for ramdisk, removing statically linked romfs at the same time.
+ *
+ * lethal@linux-sh.org:          15th May 2003
+ *    Use the generic procfs cpuinfo interface, just return a valid board name.
+ */
+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/seq_file.h>
+#include <asm/processor.h>
+#include <asm/platform.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+
+#define RES_COUNT(res) ((sizeof((res))/sizeof(struct resource)))
+
+/*
+ * Platform Dependent Interrupt Priorities.
+ */
+
+/* Using defaults defined in irq.h */
+#define	RES NO_PRIORITY		/* Disabled */
+#define IR0 IRL0_PRIORITY	/* IRLs */
+#define IR1 IRL1_PRIORITY
+#define IR2 IRL2_PRIORITY
+#define IR3 IRL3_PRIORITY
+#define PCA INTA_PRIORITY	/* PCI Ints */
+#define PCB INTB_PRIORITY
+#define PCC INTC_PRIORITY
+#define PCD INTD_PRIORITY
+#define SER TOP_PRIORITY
+#define ERR TOP_PRIORITY
+#define PW0 TOP_PRIORITY
+#define PW1 TOP_PRIORITY
+#define PW2 TOP_PRIORITY
+#define PW3 TOP_PRIORITY
+#define DM0 NO_PRIORITY		/* DMA Ints */
+#define DM1 NO_PRIORITY
+#define DM2 NO_PRIORITY
+#define DM3 NO_PRIORITY
+#define DAE NO_PRIORITY
+#define TU0 TIMER_PRIORITY	/* TMU Ints */
+#define TU1 NO_PRIORITY
+#define TU2 NO_PRIORITY
+#define TI2 NO_PRIORITY
+#define ATI NO_PRIORITY		/* RTC Ints */
+#define PRI NO_PRIORITY
+#define CUI RTC_PRIORITY
+#define ERI SCIF_PRIORITY	/* SCIF Ints */
+#define RXI SCIF_PRIORITY
+#define BRI SCIF_PRIORITY
+#define TXI SCIF_PRIORITY
+#define ITI TOP_PRIORITY	/* WDT Ints */
+
+/* Setup for the SMSC FDC37C935 */
+#define SMSC_BASE               0x04000000
+#define SMSC_CONFIG_PORT_ADDR	0x3f0
+#define SMSC_INDEX_PORT_ADDR	SMSC_CONFIG_PORT_ADDR
+#define SMSC_DATA_PORT_ADDR	0x3f1
+
+#define SMSC_ENTER_CONFIG_KEY	0x55
+#define SMSC_EXIT_CONFIG_KEY	0xaa
+
+#define SMCS_LOGICAL_DEV_INDEX	0x07
+#define SMSC_DEVICE_ID_INDEX	0x20
+#define SMSC_DEVICE_REV_INDEX	0x21
+#define SMSC_ACTIVATE_INDEX	0x30
+#define SMSC_PRIMARY_INT_INDEX	0x70
+#define SMSC_SECONDARY_INT_INDEX 0x72
+
+#define SMSC_KEYBOARD_DEVICE 7
+
+#define SMSC_READ_INDEXED(index) ({ \
+	outb((index), SMSC_INDEX_PORT_ADDR); \
+	inb(SMSC_DATA_PORT_ADDR); })
+#define SMSC_WRITE_INDEXED(val, index) ({ \
+	outb((index), SMSC_INDEX_PORT_ADDR); \
+	outb((val),   SMSC_DATA_PORT_ADDR); })
+
+unsigned long smsc_virt;
+
+/*
+ * Platform dependent structures: maps and parms block.
+ */
+struct resource io_resources[] = {
+	/* To be updated with external devices */
+};
+
+struct resource kram_resources[] = {
+	{ "Kernel code", 0, 0 },	/* These must be last in the array */
+	{ "Kernel data", 0, 0 }		/* These must be last in the array */
+};
+
+struct resource xram_resources[] = {
+	/* To be updated with external devices */
+};
+
+struct resource rom_resources[] = {
+	/* To be updated with external devices */
+};
+
+struct sh64_platform platform_parms = {
+	.readonly_rootfs =	1,
+	.initial_root_dev =	0x0100,
+	.loader_type =		1,
+	.io_res_p =		io_resources,
+	.io_res_count =		RES_COUNT(io_resources),
+	.kram_res_p =		kram_resources,
+	.kram_res_count =	RES_COUNT(kram_resources),
+	.xram_res_p =		xram_resources,
+	.xram_res_count =	RES_COUNT(xram_resources),
+	.rom_res_p =		rom_resources,
+	.rom_res_count =	RES_COUNT(rom_resources),
+};
+
+int platform_int_priority[NR_INTC_IRQS] = {
+	IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD,	/* IRQ  0- 7 */
+	RES, RES, RES, RES, SER, ERR, PW3, PW2,	/* IRQ  8-15 */
+	PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES,	/* IRQ 16-23 */
+	RES, RES, RES, RES, RES, RES, RES, RES,	/* IRQ 24-31 */
+	TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI,	/* IRQ 32-39 */
+	RXI, BRI, TXI, RES, RES, RES, RES, RES,	/* IRQ 40-47 */
+	RES, RES, RES, RES, RES, RES, RES, RES,	/* IRQ 48-55 */
+	RES, RES, RES, RES, RES, RES, RES, ITI,	/* IRQ 56-63 */
+};
+
+static int __init smsc_setup(void)
+{
+	unsigned char devid, devrev;
+
+	smsc_virt = onchip_remap(SMSC_BASE, 1024, "SMSC");
+	if (!smsc_virt) {
+		panic("Unable to remap SMSC\n");
+	}
+
+	/* Initially the chip is in run state */
+	/* Put it into configuration state */
+	outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
+	outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
+
+	/* Read device ID info */
+	devid = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
+	devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
+	printk("SMSC devid %02x rev %02x\n", devid, devrev);
+
+	/* Select the keyboard device */
+	SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
+
+	/* enable it */
+	SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);	
+
+	/* Select the interrupts */
+	/* On a PC keyboard is IRQ1, mouse is IRQ12 */
+	SMSC_WRITE_INDEXED(1, SMSC_PRIMARY_INT_INDEX);
+	SMSC_WRITE_INDEXED(12, SMSC_SECONDARY_INT_INDEX);
+
+	/* Exit the configuraton state */
+	outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
+
+	return 0;
+}
+
+/* This is grotty, but, because kernel is always referenced on the link line
+ * before any devices, this is safe.
+ */
+__initcall(smsc_setup);
+
+void __init platform_setup(void)
+{
+	/* Cayman platform leaves the decision to head.S, for now */
+	platform_parms.fpu_flags = fpu_in_use;
+}
+
+void __init platform_monitor(void)
+{
+	/* Nothing yet .. */
+}
+
+void __init platform_reserve(void)
+{
+	/* Nothing yet .. */
+}
+
+const char *get_system_type(void)
+{
+	return "Hitachi Cayman";
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/mach-harp/Makefile linux-2.4.22-pre3/arch/sh64/mach-harp/Makefile
--- linux-2.4.22-pre2/arch/sh64/mach-harp/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mach-harp/Makefile	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,14 @@
+#
+# Makefile for the ST50 Harp specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+O_TARGET := harp.o
+
+obj-y := setup.o
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.22-pre2/arch/sh64/mach-harp/setup.c linux-2.4.22-pre3/arch/sh64/mach-harp/setup.c
--- linux-2.4.22-pre2/arch/sh64/mach-harp/setup.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mach-harp/setup.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,139 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/mach-harp/setup.c
+ *
+ * SH-5 Simulator Platform Support
+ *
+ * This file handles the architecture-dependent parts of initialization
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * benedict.gaster@superh.com:	 3rd May 2002
+ *    Added support for ramdisk, removing statically linked romfs at the same time. *
+ *
+ * lethal@linux-sh.org:          15th May 2003
+ *    Use the generic procfs cpuinfo interface, just return a valid board name.
+ */
+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <asm/processor.h>
+#include <asm/platform.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+
+#define RES_COUNT(res) ((sizeof((res))/sizeof(struct resource)))
+
+/*
+ * Platform Dependent Interrupt Priorities.
+ */
+
+/* Using defaults defined in irq.h */
+#define	RES NO_PRIORITY		/* Disabled */
+#define IR0 IRL0_PRIORITY	/* IRLs */
+#define IR1 IRL1_PRIORITY
+#define IR2 IRL2_PRIORITY
+#define IR3 IRL3_PRIORITY
+#define PCA INTA_PRIORITY	/* PCI Ints */
+#define PCB INTB_PRIORITY
+#define PCC INTC_PRIORITY
+#define PCD INTD_PRIORITY
+#define SER TOP_PRIORITY
+#define ERR TOP_PRIORITY
+#define PW0 TOP_PRIORITY
+#define PW1 TOP_PRIORITY
+#define PW2 TOP_PRIORITY
+#define PW3 TOP_PRIORITY
+#define DM0 NO_PRIORITY		/* DMA Ints */
+#define DM1 NO_PRIORITY
+#define DM2 NO_PRIORITY
+#define DM3 NO_PRIORITY
+#define DAE NO_PRIORITY
+#define TU0 TIMER_PRIORITY	/* TMU Ints */
+#define TU1 NO_PRIORITY
+#define TU2 NO_PRIORITY
+#define TI2 NO_PRIORITY
+#define ATI NO_PRIORITY		/* RTC Ints */
+#define PRI NO_PRIORITY
+#define CUI RTC_PRIORITY
+#define ERI SCIF_PRIORITY	/* SCIF Ints */
+#define RXI SCIF_PRIORITY
+#define BRI SCIF_PRIORITY
+#define TXI SCIF_PRIORITY
+#define ITI TOP_PRIORITY	/* WDT Ints */
+
+/*
+ * Platform dependent structures: maps and parms block.
+ */
+struct resource io_resources[] = {
+	/* To be updated with external devices */
+};
+
+struct resource kram_resources[] = {
+	{ "Kernel code", 0, 0 },	/* These must be last in the array */
+	{ "Kernel data", 0, 0 }		/* These must be last in the array */
+};
+
+struct resource xram_resources[] = {
+	/* To be updated with external devices */
+};
+
+struct resource rom_resources[] = {
+	/* To be updated with external devices */
+};
+
+struct sh64_platform platform_parms = {
+	.readonly_rootfs =	1,
+	.initial_root_dev =	0x0100,
+	.loader_type =		1,
+	.io_res_p =		io_resources,
+	.io_res_count =		RES_COUNT(io_resources),
+	.kram_res_p =		kram_resources,
+	.kram_res_count =	RES_COUNT(kram_resources),
+	.xram_res_p =		xram_resources,
+	.xram_res_count =	RES_COUNT(xram_resources),
+	.rom_res_p =		rom_resources,
+	.rom_res_count =	RES_COUNT(rom_resources),
+};
+
+int platform_int_priority[NR_INTC_IRQS] = {
+	IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD,	/* IRQ  0- 7 */
+	RES, RES, RES, RES, SER, ERR, PW3, PW2,	/* IRQ  8-15 */
+	PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES,	/* IRQ 16-23 */
+	RES, RES, RES, RES, RES, RES, RES, RES,	/* IRQ 24-31 */
+	TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI,	/* IRQ 32-39 */
+	RXI, BRI, TXI, RES, RES, RES, RES, RES,	/* IRQ 40-47 */
+	RES, RES, RES, RES, RES, RES, RES, RES,	/* IRQ 48-55 */
+	RES, RES, RES, RES, RES, RES, RES, ITI,	/* IRQ 56-63 */
+};
+
+void __init platform_setup(void)
+{
+	/* Harp platform leaves the decision to head.S, for now */
+	platform_parms.fpu_flags = fpu_in_use;
+}
+
+void __init platform_monitor(void)
+{
+	/* Nothing yet .. */
+}
+
+void __init platform_reserve(void)
+{
+	/* Nothing yet .. */
+}
+
+const char *get_system_type(void)
+{
+	return "ST50 Harp";
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/mach-sim/Makefile linux-2.4.22-pre3/arch/sh64/mach-sim/Makefile
--- linux-2.4.22-pre2/arch/sh64/mach-sim/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mach-sim/Makefile	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,14 @@
+#
+# Makefile for the SH-5 Simulator specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+O_TARGET := sim.o
+
+obj-y := setup.o
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.22-pre2/arch/sh64/mach-sim/setup.c linux-2.4.22-pre3/arch/sh64/mach-sim/setup.c
--- linux-2.4.22-pre2/arch/sh64/mach-sim/setup.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mach-sim/setup.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,164 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/mach-sim/setup.c
+ *
+ * ST50 Simulator Platform Support
+ *
+ * This file handles the architecture-dependent parts of initialization
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * lethal@linux-sh.org:          15th May 2003
+ *    Use the generic procfs cpuinfo interface, just return a valid board name.
+ */
+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <asm/addrspace.h>
+#include <asm/processor.h>
+#include <asm/platform.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include "../rootfs/rootfs.h"
+#endif
+
+static	__init void platform_monitor(void);
+static	__init void platform_setup(void);
+static	__init void platform_reserve(void);
+
+
+#define	PHYS_MEMORY	CONFIG_MEMORY_SIZE_IN_MB*1024*1024
+
+#if (PHYS_MEMORY < P1SEG_FOOTPRINT_RAM)
+#error "Invalid kernel configuration. Physical memory below footprint requirements."
+#endif
+
+#define RAM_DISK_START	CONFIG_MEMORY_START+P1SEG_INITRD_BLOCK	/* Top of 4MB */
+#ifdef PLATFORM_ROMFS_SIZE
+#define	RAM_DISK_SIZE	(PAGE_ALIGN(PLATFORM_ROMFS_SIZE))     /* Variable Top */
+#if ((RAM_DISK_START + RAM_DISK_SIZE) > (CONFIG_MEMORY_START + PHYS_MEMORY))
+#error "Invalid kernel configuration. ROM RootFS exceeding physical memory."
+#endif
+#else
+#define RAM_DISK_SIZE	P1SEG_INITRD_BLOCK_SIZE			/* Top of 4MB */
+#endif
+
+#define RES_COUNT(res) ((sizeof((res))/sizeof(struct resource)))
+
+/*
+ * Platform Dependent Interrupt Priorities.
+ */
+
+/* Using defaults defined in irq.h */
+#define	RES NO_PRIORITY		/* Disabled */
+#define IR0 IRL0_PRIORITY	/* IRLs */
+#define IR1 IRL1_PRIORITY
+#define IR2 IRL2_PRIORITY
+#define IR3 IRL3_PRIORITY
+#define PCA INTA_PRIORITY	/* PCI Ints */
+#define PCB INTB_PRIORITY
+#define PCC INTC_PRIORITY
+#define PCD INTD_PRIORITY
+#define SER TOP_PRIORITY
+#define ERR TOP_PRIORITY
+#define PW0 TOP_PRIORITY
+#define PW1 TOP_PRIORITY
+#define PW2 TOP_PRIORITY
+#define PW3 TOP_PRIORITY
+#define DM0 NO_PRIORITY		/* DMA Ints */
+#define DM1 NO_PRIORITY
+#define DM2 NO_PRIORITY
+#define DM3 NO_PRIORITY
+#define DAE NO_PRIORITY
+#define TU0 TIMER_PRIORITY	/* TMU Ints */
+#define TU1 NO_PRIORITY
+#define TU2 NO_PRIORITY
+#define TI2 NO_PRIORITY
+#define ATI NO_PRIORITY		/* RTC Ints */
+#define PRI NO_PRIORITY
+#define CUI RTC_PRIORITY
+#define ERI SCIF_PRIORITY	/* SCIF Ints */
+#define RXI SCIF_PRIORITY
+#define BRI SCIF_PRIORITY
+#define TXI SCIF_PRIORITY
+#define ITI TOP_PRIORITY	/* WDT Ints */
+
+/*
+ * Platform dependent structures: maps and parms block.
+ */
+struct resource io_resources[] = {
+	/* Nothing yet .. */
+};
+
+struct resource kram_resources[] = {
+	{ "Kernel code", 0, 0 },	/* These must be last in the array */
+	{ "Kernel data", 0, 0 }		/* These must be last in the array */
+};
+
+struct resource xram_resources[] = {
+	/* Nothing yet .. */
+};
+
+struct resource rom_resources[] = {
+	/* Nothing yet .. */
+};
+
+struct sh64_platform platform_parms = {
+	.readonly_rootfs =	1,
+	.initial_root_dev =	0x0100,
+	.loader_type =		1,
+	.initrd_start =		RAM_DISK_START,
+	.initrd_size =		RAM_DISK_SIZE,
+	.io_res_p =		io_resources,
+	.io_res_count =		RES_COUNT(io_resources),
+	.kram_res_p =		kram_resources,
+	.kram_res_count =	RES_COUNT(kram_resources),
+	.xram_res_p =		xram_resources,
+	.xram_res_count =	RES_COUNT(xram_resources),
+	.rom_res_p =		rom_resources,
+	.rom_res_count =	RES_COUNT(rom_resources),
+};
+
+int platform_int_priority[NR_IRQS] = {
+	IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD,	/* IRQ  0- 7 */
+	RES, RES, RES, RES, SER, ERR, PW3, PW2,	/* IRQ  8-15 */
+	PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES,	/* IRQ 16-23 */
+	RES, RES, RES, RES, RES, RES, RES, RES,	/* IRQ 24-31 */
+	TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI,	/* IRQ 32-39 */
+	RXI, BRI, TXI, RES, RES, RES, RES, RES,	/* IRQ 40-47 */
+	RES, RES, RES, RES, RES, RES, RES, RES,	/* IRQ 48-55 */
+	RES, RES, RES, RES, RES, RES, RES, ITI,	/* IRQ 56-63 */
+};
+
+void __init platform_setup(void)
+{
+	/* Simulator platform leaves the decision to head.S */
+	platform_parms.fpu_flags = fpu_in_use;
+}
+
+void __init platform_monitor(void)
+{
+	/* Nothing yet .. */
+}
+
+void __init platform_reserve(void)
+{
+	/* Nothing yet .. */
+}
+
+const char *get_system_type(void)
+{
+	return "SH-5 Simulator";
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/mm/Makefile linux-2.4.22-pre3/arch/sh64/mm/Makefile
--- linux-2.4.22-pre2/arch/sh64/mm/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mm/Makefile	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,43 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2000, 2001  Paolo Alberelli
+#
+# Makefile for the sh64-specific parts of the Linux memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+O_TARGET := mm.o
+obj-y := init.o fault.o ioremap.o extable.o cache.o tlbmiss.o tlb.o
+
+# Special flags for tlbmiss.o.  This puts restrictions on the number of
+# caller-save registers that the compiler can target when building this file.
+# This is required because the code is called from a context in entry.S where
+# very few registers have been saved in the exception handler (for speed
+# reasons).
+# The caller save registers that have been saved and which can be used are
+# r2,r3,r4,r5 : argument passing
+# r15, r18 : SP and LINK
+# tr0-4 : allow all caller-save TR's.  The compiler seems to be able to make
+#         use of them, so it's probably beneficial to performance to save them
+#         and have them available for it.
+#
+# The resources not listed below are callee save, i.e. the compiler is free to
+# use any of them and will spill them to the stack itself.
+
+CFLAGS_tlbmiss.o += -ffixed-r7 \
+	-ffixed-r8 -ffixed-r9 -ffixed-r10 -ffixed-r11 -ffixed-r12 \
+	-ffixed-r13 -ffixed-r14 -ffixed-r16 -ffixed-r17 -ffixed-r19 \
+	-ffixed-r20 -ffixed-r21 -ffixed-r22 -ffixed-r23 \
+	-ffixed-r24 -ffixed-r25 -ffixed-r26 -ffixed-r27 \
+	-ffixed-r36 -ffixed-r37 -ffixed-r38 -ffixed-r39 -ffixed-r40 \
+	-ffixed-r41 -ffixed-r42 -ffixed-r43  \
+	-ffixed-r60 -ffixed-r61 -ffixed-r62
+
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/arch/sh64/mm/cache.c linux-2.4.22-pre3/arch/sh64/mm/cache.c
--- linux-2.4.22-pre2/arch/sh64/mm/cache.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mm/cache.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,1087 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/mm/cache.c
+ *
+ * Original version Copyright (C) 2000, 2001  Paolo Alberelli
+ * Second version Copyright (C) benedict.gaster@superh.com 2002
+ * Third version Copyright Richard.Curnow@superh.com 2003
+ * Hacks to third version Copyright (C) 2003 Paul Mundt
+ */
+
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/threads.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/tlb.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+#include <asm/pgalloc.h> /* for flush_itlb_range */
+
+#include <linux/proc_fs.h>
+
+/* This function is in entry.S */
+extern unsigned long switch_and_save_asid(unsigned long new_asid);
+
+/* Wired TLB entry for the D-cache */
+static unsigned long long dtlb_cache_slot;
+
+/**
+ * sh64_cache_init()
+ *
+ * This is pretty much just a straightforward clone of the SH
+ * detect_cpu_and_cache_system().
+ *
+ * This function is responsible for setting up all of the cache
+ * info dynamically as well as taking care of CPU probing and
+ * setting up the relevant subtype data.
+ *
+ * FIXME: For the time being, we only really support the SH5-101
+ * out of the box, and don't support dynamic probing for things
+ * like the SH5-103 or even cut2 of the SH5-101. Implement this
+ * later!
+ */
+int __init sh64_cache_init(void)
+{
+	/*
+	 * First, setup some sane values for the I-cache.
+	 */
+	cpu_data->icache.ways		= 4;
+	cpu_data->icache.sets		= 256;
+	cpu_data->icache.linesz		= L1_CACHE_BYTES;
+
+	/* 
+	 * FIXME: This can probably be cleaned up a bit as well.. for example,
+	 * do we really need the way shift _and_ the way_step_shift ?? Judging
+	 * by the existing code, I would guess no.. is there any valid reason
+	 * why we need to be tracking this around?
+	 */
+	cpu_data->icache.way_shift	= 13;
+	cpu_data->icache.entry_shift	= 5;
+	cpu_data->icache.set_shift	= 4;
+	cpu_data->icache.way_step_shift	= 16;
+	cpu_data->icache.asid_shift	= 2;
+
+	/* 
+	 * way offset = cache size / associativity, so just don't factor in
+	 * associativity in the first place..
+	 */
+	cpu_data->icache.way_ofs	= cpu_data->icache.sets *
+					  cpu_data->icache.linesz;
+
+	cpu_data->icache.asid_mask	= 0x3fc;
+	cpu_data->icache.idx_mask	= 0x1fe0;
+	cpu_data->icache.epn_mask	= 0xffffe000;
+	cpu_data->icache.flags		= 0;
+	
+	/*
+	 * Next, setup some sane values for the D-cache.
+	 *
+	 * On the SH5, these are pretty consistent with the I-cache settings,
+	 * so we just copy over the existing definitions.. these can be fixed
+	 * up later, especially if we add runtime CPU probing.
+	 *
+	 * Though in the meantime it saves us from having to duplicate all of
+	 * the above definitions..
+	 */
+	cpu_data->dcache 		= cpu_data->icache;
+
+	/*
+	 * Setup any cache-related flags here
+	 */
+#if defined(CONFIG_DCACHE_WRITE_THROUGH)
+	set_bit(SH_CACHE_MODE_WT, &(cpu_data->dcache.flags));
+#elif defined(CONFIG_DCACHE_WRITE_BACK)
+	set_bit(SH_CACHE_MODE_WB, &(cpu_data->dcache.flags));
+#endif
+
+	/* 
+	 * We also need to reserve a slot for the D-cache in the DTLB, so we
+	 * do this now ..
+	 */
+	dtlb_cache_slot			= sh64_get_wired_dtlb_entry();
+
+	return 0;
+}
+
+/*##########################################################################*/
+
+/* From here onwards, a rewrite of the implementation,
+   by Richard.Curnow@superh.com.
+
+   The major changes in this compared to the old version are;
+   1. use more selective purging through OCBP instead of using ALLOCO to purge
+      by natural replacement.  This avoids purging out unrelated cache lines
+      that happen to be in the same set.
+   2. exploit the APIs copy_user_page and clear_user_page better
+   3. be more selective about I-cache purging, in particular use invalidate_all
+      more sparingly.
+
+   NOTE : all this code runs in process context.  As long as it's not used in a
+   pre-emptible or SMP kernel, there are no issues with locking, reentrancy
+   etc.  When it gets used in a such a kernel this will have to be addressed.
+   (Note, there is no SMP realisation of sh64 yet.)
+   */
+
+/*##########################################################################
+			       SUPPORT FUNCTIONS
+  ##########################################################################*/
+
+/****************************************************************************/
+/* The following group of functions deal with mapping and unmapping a temporary
+   page into the DTLB slot that have been set aside for our exclusive use. */
+/* In order to accomplish this, we use the generic interface for adding and
+   removing a wired slot entry as defined in arch/sh64/mm/tlb.c */
+/****************************************************************************/
+
+static inline void sh64_setup_dtlb_cache_slot(unsigned long eaddr, unsigned long asid, unsigned long paddr)
+{
+	sh64_setup_tlb_slot(dtlb_cache_slot, eaddr, asid, paddr);
+}
+
+static inline void sh64_teardown_dtlb_cache_slot(void)
+{
+	sh64_teardown_tlb_slot(dtlb_cache_slot);
+}
+
+/****************************************************************************/
+
+#ifndef CONFIG_ICACHE_DISABLED
+
+static void __inline__ sh64_icache_inv_all(void)
+{
+	unsigned long long addr, flag, data;
+	unsigned int flags;
+
+	addr=ICCR0; 
+	flag=ICCR0_ICI; 
+	data=0;
+
+	/* TODO : does this really need to be a critical section? */
+	save_and_cli(flags);
+
+	/* Without %1 it gets unexplicably wrong */
+	asm volatile("getcfg	%3, 0, %0\n\t"
+			"or	%0, %2, %0\n\t"
+			"putcfg	%3, 0, %0\n\t"
+			"synci"
+			: "=&r" (data)
+			: "0" (data), "r" (flag), "r" (addr));
+
+	restore_flags(flags);
+}
+
+static void sh64_icache_inv_kernel_range(unsigned long start, unsigned long end)
+{
+	/* Invalidate range of addresses [start,end] from the I-cache, where
+	 * the addresses lie in the kernel superpage. */
+
+	unsigned long long ullend, addr, aligned_start;
+	/* FIXME : This sign extension needs to be made generic. */
+	aligned_start = (unsigned long long)(signed long long)(signed long) start;
+	aligned_start &= L1_CACHE_ALIGN_MASK;
+	addr = aligned_start;
+	/* FIXME : likewise this one */
+	ullend = (unsigned long long) (signed long long) (signed long) end;
+	while (addr <= ullend) {
+		asm __volatile__ ("icbi %0, 0" : : "r" (addr));
+		addr += L1_CACHE_BYTES;
+	}
+}
+
+static void sh64_icache_inv_user_page(struct vm_area_struct *vma, unsigned long eaddr)
+{
+	/* If we get called, we know that vma->vm_flags contains VM_EXEC.
+	   Also, eaddr is page-aligned. */
+
+	/* For SMP/pre-emptible, this will need to be locked to prevent the
+	   ASID from changing under us if there's a reschedule. */
+
+	unsigned long long addr, end_addr;
+	addr = eaddr;
+	end_addr = addr + PAGE_SIZE;
+
+	
+	/* FIXME : is there any issue using 'current_asid' here?  i.e. can this
+	   ever get called with 'vma->vm_mm->context.asid' != current_asid?
+	   (the normal case would be munmap or a page flush following a COW
+	   break etc, and using current_asid is OK for those.).  If we need to
+	   use vma->vm_mm->context.asid, we'd have to switch ASIDs and run in
+	   the context of the victim. */
+	while (addr < end_addr) {
+		/* Worth unrolling a little */
+		asm __volatile__("icbi %0,  0" : : "r" (addr));
+		asm __volatile__("icbi %0, 32" : : "r" (addr));
+		asm __volatile__("icbi %0, 64" : : "r" (addr));
+		asm __volatile__("icbi %0, 96" : : "r" (addr));
+		addr += 128;
+	}
+	return;
+}
+
+/****************************************************************************/
+
+static void sh64_icache_inv_user_page_range(struct mm_struct *mm,
+			  unsigned long start, unsigned long end)
+{
+	/* Used for invalidating big chunks of I-cache, i.e. assume the range
+	   is whole pages.  If 'start' or 'end' is not page aligned, the code
+	   is conservative and invalidates to the ends of the enclosing pages.
+	   This is functionally OK, just a performance loss. */
+
+	/* See the comments below in sh64_dcache_purge_user_range() regarding
+	   the choice of algorithm.  However, for the I-cache option (2) isn't
+	   available because there are no physical tags so aliases can't be
+	   resolved.  The icbi instruction has to be used through the user
+	   mapping.   Because icbi is cheaper than ocbp on a cache hit, it
+	   would be cheaper to use the selective code for a large range than is
+	   possible with the D-cache.  Just assume 64 for now as a working
+	   figure.
+	   */
+
+	int n_pages;
+
+	if (!mm) return;
+
+	n_pages = ((end - start) >> PAGE_SHIFT);
+	if (n_pages >= 64) {
+		sh64_icache_inv_all();
+	} else {
+		unsigned long aligned_start;
+		unsigned long eaddr;
+		unsigned long after_last_page_start;
+		unsigned long mm_asid, current_asid;
+		unsigned long long flags = 0ULL;
+
+		mm_asid = mm->context & MMU_CONTEXT_ASID_MASK;
+		current_asid = get_asid();
+
+		if (mm_asid != current_asid) {
+			/* Switch ASID and run the invalidate loop under cli */
+			save_and_cli(flags);
+			switch_and_save_asid(mm_asid);
+		}
+
+		aligned_start = start & PAGE_MASK;
+		after_last_page_start = PAGE_SIZE + ((end - 1) & PAGE_MASK);
+
+		while (aligned_start < after_last_page_start) {
+			struct vm_area_struct *vma;
+			unsigned long vma_end;
+			vma = find_vma(mm, aligned_start);
+			if (!vma || (aligned_start <= vma->vm_end)) {
+				/* Avoid getting stuck in an error condition */
+				aligned_start += PAGE_SIZE;
+				continue;
+			}
+			vma_end = vma->vm_end;
+			if (vma->vm_flags & VM_EXEC) {
+				/* Executable */
+				eaddr = aligned_start;
+				while (eaddr < vma_end) {
+					sh64_icache_inv_user_page(vma, eaddr);
+					eaddr += PAGE_SIZE;
+				}
+			}
+			aligned_start = vma->vm_end; /* Skip to start of next region */
+		}
+		if (mm_asid != current_asid) {
+			switch_and_save_asid(current_asid);
+			restore_flags(flags);
+		}
+	}
+}
+
+static void sh64_icache_inv_user_small_range(struct mm_struct *mm,
+						unsigned long start, int len)
+{
+
+	/* Invalidate a small range of user context I-cache, not necessarily
+	   page (or even cache-line) aligned. */
+	
+	unsigned long long eaddr = start;
+	unsigned long long eaddr_end = start + len;
+	unsigned long current_asid, mm_asid;
+	unsigned long long flags;
+	unsigned long long epage_start;
+
+	/* Since this is used inside ptrace, the ASID in the mm context
+	   typically won't match current_asid.  We'll have to switch ASID to do
+	   this.  For safety, and given that the range will be small, do all
+	   this under cli.
+
+	   Note, there is a hazard that the ASID in mm->context is no longer
+	   actually associated with mm, i.e. if the mm->context has started a
+	   new cycle since mm was last active.  However, this is just a
+	   performance issue: all that happens is that we invalidate lines
+	   belonging to another mm, so the owning process has to refill them
+	   when that mm goes live again.  mm itself can't have any cache
+	   entries because there will have been a flush_cache_all when the new
+	   mm->context cycle started. */
+
+	/* Align to start of cache line.  Otherwise, suppose len==8 and start
+	   was at 32N+28 : the last 4 bytes wouldn't get invalidated. */
+	eaddr = start & L1_CACHE_ALIGN_MASK;
+	eaddr_end = start + len;
+
+	save_and_cli(flags);
+	mm_asid = mm->context & MMU_CONTEXT_ASID_MASK;
+	current_asid = switch_and_save_asid(mm_asid);
+
+	epage_start = eaddr & PAGE_MASK;
+	
+	while (eaddr < eaddr_end)
+	{
+		asm __volatile__("icbi %0, 0" : : "r" (eaddr));
+		eaddr += L1_CACHE_BYTES;
+	}
+	switch_and_save_asid(current_asid);
+	restore_flags(flags);
+}
+
+static void sh64_icache_inv_current_user_range(unsigned long start, unsigned long end)
+{
+	/* The icbi instruction never raises ITLBMISS.  i.e. if there's not a
+	   cache hit on the virtual tag the instruction ends there, without a
+	   TLB lookup. */
+
+	unsigned long long aligned_start;
+	unsigned long long ull_end;
+	unsigned long long addr;
+
+	ull_end = end;
+
+	/* Just invalidate over the range using the natural addresses.  TLB
+	   miss handling will be OK (TBC).  Since it's for the current process,
+	   either we're already in the right ASID context, or the ASIDs have
+	   been recycled since we were last active in which case we might just
+	   invalidate another processes I-cache entries : no worries, just a
+	   performance drop for him. */
+	aligned_start = start & L1_CACHE_ALIGN_MASK;
+	addr = aligned_start;
+	while (addr < ull_end) {
+		asm __volatile__ ("icbi %0, 0" : : "r" (addr));
+		asm __volatile__ ("nop");
+		asm __volatile__ ("nop");
+		addr += L1_CACHE_BYTES;
+	}
+}
+
+#endif /* !CONFIG_ICACHE_DISABLED */
+
+/****************************************************************************/
+
+#ifndef CONFIG_DCACHE_DISABLED
+
+/* Buffer used as the target of alloco instructions to purge data from cache
+   sets by natural eviction. -- RPC */
+#define DUMMY_ALLOCO_AREA_SIZE L1_CACHE_SIZE_BYTES + (1024 * 4)
+static unsigned char dummy_alloco_area[DUMMY_ALLOCO_AREA_SIZE] __cacheline_aligned = { 0, };
+
+/****************************************************************************/
+
+static void __inline__ sh64_dcache_purge_sets(int sets_to_purge_base, int n_sets)
+{
+	/* Purge all ways in a particular block of sets, specified by the base
+	   set number and number of sets.  Can handle wrap-around, if that's
+	   needed.  */
+
+	int dummy_buffer_base_set;
+	unsigned long long eaddr, eaddr0, eaddr1;
+	int j;
+	int set_offset;
+
+	dummy_buffer_base_set = ((int)&dummy_alloco_area & cpu_data->dcache.idx_mask) >> cpu_data->dcache.entry_shift;
+	set_offset = sets_to_purge_base - dummy_buffer_base_set;
+
+	for (j=0; j<n_sets; j++, set_offset++) {
+		set_offset &= (cpu_data->dcache.sets - 1);
+		eaddr0 = (unsigned long long)dummy_alloco_area + (set_offset << cpu_data->dcache.entry_shift);
+
+		/* Do one alloco which hits the required set per cache way.  For
+		   write-back mode, this will purge the #ways resident lines.   There's
+		   little point unrolling this loop because the allocos stall more if
+		   they're too close together. */
+		eaddr1 = eaddr0 + cpu_data->dcache.way_ofs * cpu_data->dcache.ways;
+		for (eaddr=eaddr0; eaddr<eaddr1; eaddr+=cpu_data->dcache.way_ofs) {
+			asm __volatile__ ("alloco %0, 0" : : "r" (eaddr));
+		}
+
+		eaddr1 = eaddr0 + cpu_data->dcache.way_ofs * cpu_data->dcache.ways;
+		for (eaddr=eaddr0; eaddr<eaddr1; eaddr+=cpu_data->dcache.way_ofs) {
+			/* Load from each address.  Required because alloco is a NOP if
+			   the cache is write-through.  Write-through is a config option. */
+			if (test_bit(SH_CACHE_MODE_WT, &(cpu_data->dcache.flags)))
+				*(volatile unsigned char *)(int)eaddr;
+		}
+	}
+
+	/* Don't use OCBI to invalidate the lines.  That costs cycles directly.
+	   If the dummy block is just left resident, it will naturally get
+	   evicted as required.  */
+
+	return;
+}
+
+/****************************************************************************/
+
+static void sh64_dcache_purge_all(void)
+{
+	/* Purge the entire contents of the dcache.  The most efficient way to
+	   achieve this is to use alloco instructions on a region of unused
+	   memory equal in size to the cache, thereby causing the current
+	   contents to be discarded by natural eviction.  The alternative,
+	   namely reading every tag, setting up a mapping for the corresponding
+	   page and doing an OCBP for the line, would be much more expensive.
+	   */
+
+	sh64_dcache_purge_sets(0, cpu_data->dcache.sets);
+
+	return;
+
+}
+
+/****************************************************************************/
+
+static void sh64_dcache_purge_kernel_range(unsigned long start, unsigned long end)
+{
+	/* Purge the range of addresses [start,end] from the D-cache.  The
+	   addresses lie in the superpage mapping.  There's no harm if we
+	   overpurge at either end - just a small performance loss. */
+	unsigned long long ullend, addr, aligned_start;
+	/* FIXME : This sign extension needs to be made generic. */
+	aligned_start = (unsigned long long)(signed long long)(signed long) start;
+	aligned_start &= L1_CACHE_ALIGN_MASK;
+	addr = aligned_start;
+	/* FIXME : likewise this one */
+	ullend = (unsigned long long) (signed long long) (signed long) end;
+	while (addr <= ullend) {
+		asm __volatile__ ("ocbp %0, 0" : : "r" (addr));
+		addr += L1_CACHE_BYTES;
+	}
+	return;
+}
+
+/* Assumes this address (+ (2**n_synbits) pages up from it) aren't used for
+   anything else in the kernel */
+#define MAGIC_PAGE0_START 0xffffffffe0000000ULL
+
+static void sh64_dcache_purge_coloured_phy_page(unsigned long paddr, unsigned long eaddr)
+{
+	/* Purge the physical page 'paddr' from the cache.  It's known that any
+	   cache lines requiring attention have the same page colour as the the
+	   address 'eaddr'.
+	   
+	   This relies on the fact that the D-cache matches on physical tags
+	   when no virtual tag matches.  So we create an alias for the original
+	   page and purge through that.  (Alternatively, we could have done
+	   this by switching ASID to match the original mapping and purged
+	   through that, but that involves ASID switching cost + probably a
+	   TLBMISS + refill anyway.)
+	   */
+
+	unsigned long long magic_page_start;
+	unsigned long long magic_eaddr, magic_eaddr_end;
+
+	magic_page_start = MAGIC_PAGE0_START + (eaddr & CACHE_OC_SYN_MASK);
+
+	/* As long as the kernel is not pre-emptible, this doesn't need to be
+	   under cli/sti. */
+
+	sh64_setup_dtlb_cache_slot(magic_page_start, get_asid(), paddr);
+
+	magic_eaddr = magic_page_start;
+	magic_eaddr_end = magic_eaddr + PAGE_SIZE;
+	while (magic_eaddr < magic_eaddr_end) {
+		/* Little point in unrolling this loop - the OCBPs are blocking
+		   and won't go any quicker (i.e. the loop overhead is parallel
+		   to part of the OCBP execution.) */
+		asm __volatile__ ("ocbp %0, 0" : : "r" (magic_eaddr));
+		magic_eaddr += L1_CACHE_BYTES;
+	}
+
+	sh64_teardown_dtlb_cache_slot();
+}
+
+/****************************************************************************/
+
+static void sh64_dcache_purge_phy_page(unsigned long paddr)
+{
+	/* Pure a page given its physical start address, by creating a
+	   temporary 1 page mapping and purging across that.  Even if we know
+	   the virtual address (& vma or mm) of the page, the method here is
+	   more elegant because it avoids issues of coping with page faults on
+	   the purge instructions (i.e. no special-case code required in the
+	   critical path in the TLB miss handling). */
+
+	unsigned long long eaddr_start, eaddr, eaddr_end;
+	int i;
+
+	/* As long as the kernel is not pre-emptible, this doesn't need to be
+	   under cli/sti. */
+
+	eaddr_start = MAGIC_PAGE0_START;
+	for (i=0; i < (1 << CACHE_OC_N_SYNBITS); i++) {
+		sh64_setup_dtlb_cache_slot(eaddr_start, get_asid(), paddr);
+
+		eaddr = eaddr_start;
+		eaddr_end = eaddr + PAGE_SIZE;
+		while (eaddr < eaddr_end) {
+			asm __volatile__ ("ocbp %0, 0" : : "r" (eaddr));
+			eaddr += L1_CACHE_BYTES;
+		}
+
+		sh64_teardown_dtlb_cache_slot();
+		eaddr_start += PAGE_SIZE;
+	}
+}
+
+static void sh64_dcache_purge_virt_page(struct mm_struct *mm, unsigned long eaddr)
+{
+	unsigned long phys;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	pte_t entry;
+
+	pgd = pgd_offset(mm, eaddr);
+	pmd = pmd_offset(pgd, eaddr);
+
+	if (pmd_none(*pmd) || pmd_bad(*pmd))
+		return;
+	
+	pte = pte_offset(pmd, eaddr);
+	entry = *pte;
+
+	if (pte_none(entry) || !pte_present(entry))
+		return;
+	
+	phys = pte_val(entry) & PAGE_MASK;
+
+	sh64_dcache_purge_phy_page(phys);
+}
+
+static void sh64_dcache_purge_user_page(struct mm_struct *mm, unsigned long eaddr)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	pte_t entry;
+	unsigned long paddr;
+	
+	/* NOTE : all the callers of this have mm->page_table_lock held, so the
+	   following page table traversal is safe even on SMP/pre-emptible. */
+
+	if (!mm) return; /* No way to find physical address of page */
+	pgd = pgd_offset(mm, eaddr);
+	if (pgd_bad(*pgd)) return;
+	
+	pmd = pmd_offset(pgd, eaddr);
+	if (pmd_none(*pmd) || pmd_bad(*pmd)) return;
+	
+	pte = pte_offset(pmd, eaddr);
+	entry = *pte;
+	if (pte_none(entry) || !pte_present(entry)) return;
+
+	paddr = pte_val(entry) & PAGE_MASK;
+
+	sh64_dcache_purge_coloured_phy_page(paddr, eaddr);
+
+}
+/****************************************************************************/
+
+static void sh64_dcache_purge_user_range(struct mm_struct *mm,
+			  unsigned long start, unsigned long end)
+{
+	/* There are at least 5 choices for the implementation of this, with
+	   pros (+), cons(-), comments(*):
+	 
+	   1. ocbp each line in the range through the original user's ASID
+	      + no lines spuriously evicted
+	      - tlbmiss handling (must either handle faults on demand => extra
+		special-case code in tlbmiss critical path), or map the page in
+		advance (=> flush_tlb_range in advance to avoid multiple hits)
+	      - ASID switching
+	      - expensive for large ranges
+
+	   2. temporarily map each page in the range to a special effective
+	      address and ocbp through the temporary mapping; relies on the
+	      fact that SH-5 OCB* always do TLB lookup and match on ptags (they
+	      never look at the etags)
+	      + no spurious evictions
+	      - expensive for large ranges
+	      * surely cheaper than (1)
+
+	   3. walk all the lines in the cache, check the tags, if a match
+	      occurs create a page mapping to ocbp the line through
+	      + no spurious evictions
+	      - tag inspection overhead 
+	      - (especially for small ranges)
+	      - potential cost of setting up/tearing down page mapping for
+		every line that matches the range
+	      * cost partly independent of range size
+
+	   4. walk all the lines in the cache, check the tags, if a match
+	      occurs use 4 * alloco to purge the line (+3 other probably
+	      innocent victims) by natural eviction
+	      + no tlb mapping overheads
+	      - spurious evictions
+	      - tag inspection overhead
+
+	   5. implement like flush_cache_all
+	      + no tag inspection overhead
+	      - spurious evictions
+	      - bad for small ranges
+
+	   (1) can be ruled out as more expensive than (2).  (2) appears best
+	   for small ranges.  The choice between (3), (4) and (5) for large
+	   ranges and the range size for the large/small boundary need
+	   benchmarking to determine.
+
+	   For now use approach (2) for small ranges and (5) for large ones.
+
+	   */
+	
+	int n_pages;
+
+	n_pages = ((end - start) >> PAGE_SHIFT);
+	if (n_pages >= 64) {
+#if 1
+		sh64_dcache_purge_all();
+#else
+		unsigned long long set, way;
+		unsigned long mm_asid = mm->context & MMU_CONTEXT_ASID_MASK;
+		for (set = 0; set < cpu_data->dcache.sets; set++) {
+			unsigned long long set_base_config_addr = CACHE_OC_ADDRESS_ARRAY + (set << cpu_data->dcache.set_shift);
+			for (way = 0; way < cpu_data->dcache.ways; way++) {
+				unsigned long long config_addr = set_base_config_addr + (way << cpu_data->dcache.way_step_shift);
+				unsigned long long tag0;
+				unsigned long line_valid;
+
+				asm __volatile__("getcfg %1, 0, %0" : "=r" (tag0) : "r" (config_addr));
+				line_valid = tag0 & SH_CACHE_VALID;
+				if (line_valid) {
+					unsigned long cache_asid;
+					unsigned long epn;
+
+					cache_asid = (tag0 & cpu_data->dcache.asid_mask) >> cpu_data->dcache.asid_shift;
+					/* The next line needs some
+					   explanation.  The virtual tags
+					   encode bits [31:13] of the virtual
+					   address, bit [12] of the 'tag' being
+					   implied by the cache set index. */
+					epn = (tag0 & cpu_data->dcache.epn_mask) | ((set & 0x80) << cpu_data->dcache.entry_shift);
+
+					if ((cache_asid == mm_asid) && (start <= epn) && (epn < end)) {
+						/* TODO : could optimise this
+						   call by batching multiple
+						   adjacent sets together. */
+						sh64_dcache_purge_sets(set, 1);
+						break; /* Don't waste time inspecting other ways for this set */
+					}
+				}
+			}
+		}
+#endif
+	} else {
+		/* 'Small' range */
+		unsigned long aligned_start;
+		unsigned long eaddr;
+		unsigned long last_page_start;
+	
+		aligned_start = start & PAGE_MASK;
+		/* 'end' is 1 byte beyond the end of the range */
+		last_page_start = (end - 1) & PAGE_MASK;
+		
+		eaddr = aligned_start;
+		while (eaddr <= last_page_start) {
+			sh64_dcache_purge_user_page(mm, eaddr);
+			eaddr += PAGE_SIZE;
+		}
+	}
+	return;
+}
+
+static void sh64_dcache_wback_current_user_range(unsigned long start, unsigned long end)
+{
+	unsigned long long aligned_start;
+	unsigned long long ull_end;
+	unsigned long long addr;
+
+	ull_end = end;
+
+	/* Just wback over the range using the natural addresses.  TLB miss
+	   handling will be OK (TBC) : the range has just been written to by
+	   the signal frame setup code, so the PTEs must exist.
+
+	   TODO : with SMP or pre-emptible, run this under cli to guard against
+	   the risk of a reschedule causing a new ASID cycle to begin.
+	   */
+	aligned_start = start & L1_CACHE_ALIGN_MASK;
+	addr = aligned_start;
+	while (addr < ull_end) {
+		asm __volatile__ ("ocbwb %0, 0" : : "r" (addr));
+		addr += L1_CACHE_BYTES;
+	}
+}
+
+#endif /* !CONFIG_DCACHE_DISABLED */
+
+/****************************************************************************/
+
+/* These *MUST* lie in an area of virtual address space that's otherwise unused. */
+#define UNIQUE_EADDR_START 0xc0000000UL
+#define UNIQUE_EADDR_END   0xd0000000UL
+
+static unsigned long sh64_make_unique_eaddr(unsigned long user_eaddr, unsigned long paddr)
+{
+	/* Given a physical address paddr, and a user virtual address
+	   user_eaddr which will eventually be mapped to it, create a one-off
+	   kernel-private eaddr mapped to the same paddr.  This is used for
+	   creating special destination pages for copy_user_page and
+	   clear_user_page */
+
+	static unsigned long current_pointer = UNIQUE_EADDR_START;
+	unsigned long coloured_pointer;
+
+	if (current_pointer == UNIQUE_EADDR_END) {
+		sh64_dcache_purge_all();
+		current_pointer = UNIQUE_EADDR_START;
+	}
+	
+	coloured_pointer = (current_pointer & ~CACHE_OC_SYN_MASK) | (user_eaddr & CACHE_OC_SYN_MASK);
+	sh64_setup_dtlb_cache_slot(coloured_pointer, get_asid(), paddr);
+
+	current_pointer += (PAGE_SIZE << CACHE_OC_N_SYNBITS);
+
+	return coloured_pointer;
+}
+
+/****************************************************************************/
+
+static void sh64_copy_user_page_coloured(void *to, void *from, unsigned long address)
+{
+	void *coloured_to;
+	
+	/* Discard any existing cache entries of the wrong colour.  These are
+	   present quite often, if the kernel has recently used the page
+	   internally, then given it up, then it's been allocated to the user.
+	   */
+	sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long) to);
+
+	coloured_to = (void *) sh64_make_unique_eaddr(address, __pa(to));
+	sh64_page_copy(from, coloured_to);
+	
+	sh64_teardown_dtlb_cache_slot();
+}
+
+static void sh64_clear_user_page_coloured(void *to, unsigned long address)
+{
+	void *coloured_to;
+	
+	/* Discard any existing kernel-originated lines of the wrong colour (as
+	   above) */
+	sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long) to);
+
+	coloured_to = (void *) sh64_make_unique_eaddr(address, __pa(to));
+	sh64_page_clear(coloured_to);
+	
+	sh64_teardown_dtlb_cache_slot();
+}
+
+/****************************************************************************/
+
+/*##########################################################################
+			    EXTERNALLY CALLABLE API. 
+  ##########################################################################*/
+
+/* These functions are described in Documentation/cachetlb.txt.
+   Each one of these functions varies in behaviour depending on whether the
+   I-cache and/or D-cache are configured out.
+
+   Note that the Linux term 'flush' corresponds to what is termed 'purge' in
+   the sh/sh64 jargon for the D-cache, i.e. write back dirty data then
+   invalidate the cache lines, and 'invalidate' for the I-cache.
+   */
+
+#undef FLUSH_TRACE
+
+void flush_cache_all(void)
+{
+	/* Invalidate the entire contents of both caches, after writing back to
+	   memory any dirty data from the D-cache. */
+	sh64_dcache_purge_all();
+	sh64_icache_inv_all();
+}
+
+/****************************************************************************/
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+	/* Invalidate an entire user-address space from both caches, after
+	   writing back dirty data (e.g. for shared mmap etc). */
+
+	/* This could be coded selectively by inspecting all the tags then
+	   doing 4*alloco on any set containing a match (as for
+	   flush_cache_range), but fork/exit/execve (where this is called from)
+	   are expensive anyway. */
+
+	/* Have to do a purge here, despite the comments re I-cache below.
+	   There could be odd-coloured dirty data associated with the mm still
+	   in the cache - if this gets written out through natural eviction
+	   after the kernel has reused the page there will be chaos.
+	   
+	   TODO Perhaps a selective purge is appropriate.
+	   */
+	sh64_dcache_purge_all();
+	
+	/* The mm being torn down won't ever be active again, so any Icache
+	   lines tagged with its ASID won't be visible for the rest of the
+	   lifetime of this ASID cycle.  Before the ASID gets reused, there
+	   will be a flush_cache_all.  This is similar to the lack of action
+	   needed in flush_tlb_mm - see fault.c. */
+#if 0
+	sh64_icache_inv_all();
+#endif
+}
+
+/****************************************************************************/
+
+void flush_cache_range(struct mm_struct *mm, unsigned long start,
+		       unsigned long end)
+{
+	/* Invalidate (from both caches) the range [start,end) of virtual
+	   addresses from the user address space specified by mm, after writing
+	   back any dirty data.
+
+	   Note(1), 'end' is 1 byte beyond the end of the range to flush.
+	   
+	   Note(2), this is called with mm->page_table_lock held.*/
+
+	sh64_dcache_purge_user_range(mm, start, end);
+	sh64_icache_inv_user_page_range(mm, start, end);
+}
+
+/****************************************************************************/
+
+void flush_cache_page(struct vm_area_struct *vma, unsigned long eaddr)
+{
+	/* Invalidate any entries in either cache for the vma within the user
+	   address space vma->vm_mm for the page starting at virtual address
+	   'eaddr'.   This seems to be used primarily in breaking COW.  Note,
+	   the I-cache must be searched too in case the page in question is
+	   both writable and being executed from (e.g. stack trampolines.)
+	   
+	   Note(1), this is called with mm->page_table_lock held.
+	   */
+
+	sh64_dcache_purge_virt_page(vma->vm_mm, eaddr);
+	
+	if (vma->vm_flags & VM_EXEC) {
+		sh64_icache_inv_user_page(vma, eaddr);
+	}
+}
+
+/****************************************************************************/
+
+void flush_page_to_ram(struct page *page)
+{
+	/* This is a depracated API, being replaced by copy/clear_user_page and
+	   flush_dcache_page.  However, parts of the generic code (e.g. ptrace)
+	   still require an implementation of flush_page_to_ram for them to
+	   work properly. 
+	   
+	   The 'page' argument defines a *physical* page.  After the function,
+	   no lines in the D-cache must reference that page, and any dirty
+	   entries in the page must have been written out.  (This is used to
+	   make memory coherent with the cache when the I-cache is about to see
+	   the data etc) -- RPC */
+
+	/* As an elaboration on the above, flush_page_to_ram() is indeed
+	   deprecated, and the majority of users (such as ptrace) are using
+	   this erroneously anyways. As such, there's two different things we
+	   can do here.. namely, we can either nop this out and hope that some
+	   clueless generic code isn't abusing the interface (this is what we
+	   do for sh, and it seems to work just fine), or we can play it safe
+	   (albeit much slower, since we have the added cost of additional
+	   flushing to contend with) and just wrap to the existing
+	   flush_dcache_page() behavior. -- PFM */
+
+	flush_dcache_page(page);
+}
+
+/****************************************************************************/
+
+#ifndef CONFIG_DCACHE_DISABLED
+
+void copy_user_page(void *to, void *from, unsigned long address)
+{
+	/* 'from' and 'to' are kernel virtual addresses (within the superpage
+	   mapping of the physical RAM).  'address' is the user virtual address
+	   where the copy 'to' will be mapped after.  This allows a custom
+	   mapping to be used to ensure that the new copy is placed in the
+	   right cache sets for the user to see it without having to bounce it
+	   out via memory.  Note however : the call to flush_page_to_ram in
+	   (generic)/mm/memory.c:(break_cow) undoes all this good work in that one
+	   very important case!
+
+	   TBD : can we guarantee that on every call, any cache entries for
+	   'from' are in the same colour sets as 'address' also?  i.e. is this
+	   always used just to deal with COW?  (I suspect not). */
+
+	/* There are two possibilities here for when the page 'from' was last accessed:
+	   * by the kernel : this is OK, no purge required.
+	   * by the/a user (e.g. for break_COW) : need to purge.
+
+	   If the potential user mapping at 'address' is the same colour as
+	   'from' there is no need to purge any cache lines from the 'from'
+	   page mapped into cache sets of colour 'address'.  (The copy will be
+	   accessing the page through 'from').
+	   */
+
+	if (((address ^ (unsigned long) from) & CACHE_OC_SYN_MASK) != 0) {
+		sh64_dcache_purge_coloured_phy_page(__pa(from), address);
+	}
+
+	if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0) {
+		/* No synonym problem on destination */
+		sh64_page_copy(from, to);
+	} else {
+		sh64_copy_user_page_coloured(to, from, address);
+	}
+
+	/* Note, don't need to flush 'from' page from the cache again - it's
+	   done anyway by the generic code */
+}
+
+void clear_user_page(void *to, unsigned long address)
+{
+	/* 'to' is a kernel virtual address (within the superpage
+	   mapping of the physical RAM).  'address' is the user virtual address
+	   where the 'to' page will be mapped after.  This allows a custom
+	   mapping to be used to ensure that the new copy is placed in the
+	   right cache sets for the user to see it without having to bounce it
+	   out via memory.
+	*/
+
+	if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0) {
+		/* No synonym problem on destination */
+		sh64_page_clear(to);
+	} else {
+		sh64_clear_user_page_coloured(to, address);
+	}
+}
+
+#endif /* !CONFIG_DCACHE_DISABLED */
+
+/****************************************************************************/
+
+void flush_dcache_page(struct page *page)
+{
+	/* The behaviour of this function is equivalent to that of
+	   flush_page_to_ram above. */
+
+	sh64_dcache_purge_phy_page(page_to_phys(page));
+	wmb();
+}
+
+/****************************************************************************/
+
+void flush_icache_range(unsigned long start, unsigned long end)
+{
+	/* Flush the range [start,end] of kernel virtual adddress space from
+	   the I-cache.  The corresponding range must be purged from the
+	   D-cache also because the SH-5 doesn't have cache snooping between
+	   the caches.  The addresses will be visible through the superpage
+	   mapping, therefore it's guaranteed that there no cache entries for
+	   the range in cache sets of the wrong colour.
+	   
+	   Primarily used for cohering the I-cache after a module has
+	   been loaded.  */
+
+	/* We also make sure to purge the same range from the D-cache since
+	   flush_page_to_ram() won't be doing this for us! */
+
+	sh64_dcache_purge_kernel_range(start, end);
+	wmb();
+	sh64_icache_inv_kernel_range(start, end);
+}
+
+/****************************************************************************/
+
+void flush_icache_user_range(struct vm_area_struct *vma,
+			struct page *page, unsigned long addr, int len)
+{
+	/* Flush the range of user (defined by vma->vm_mm) address space
+	   starting at 'addr' for 'len' bytes from the cache.  The range does
+	   not straddle a page boundary, the unique physical page containing
+	   the range is 'page'.  This seems to be used mainly for invalidating
+	   an address range following a poke into the program text through the
+	   ptrace() call from another process (e.g. for BRK instruction
+	   insertion). */
+
+	sh64_dcache_purge_coloured_phy_page(page_to_phys(page), addr);
+	wmb();
+
+	if (vma->vm_flags & VM_EXEC) {
+		sh64_icache_inv_user_small_range(vma->vm_mm, addr, len);
+	}
+}
+
+/****************************************************************************/
+
+void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	/* Called when a page-cache page is about to be mapped into a user
+	   address space (defined by vma->vm_mm).  Since the SH-5 I-cache
+	   hasn't got physical tags, this doesn't have to do anything.  Empirically, this is OK.
+
+	   Note, SH-5 I-cache entries can legally outlive the ITLB mapping
+	   anyway.  So even if an executable page is dropped by the generic VM
+	   to free a page, we can still execute it from the cache.  (The cache
+	   invalidation occurs as part of flush_cache_range or flush_cache_mm
+	   when the munmap() or exit() finally happens.) -- RPC */
+
+	/* We also want to purge this page from the D-cache, since we can't
+	   rely on flush_page_to_ram() do to do the D-cache purge.
+	   
+	   Yes, this esentially constitutes misuse of flush_icache_page(), but
+	   we need this specifically for do_swap_page() in mm/memory.c for
+	   purging the page from both the I and D-cache. (This is primarily
+	   a performance hack!).
+	   
+	   We can probably do away with this entirely once we get around to
+	   doing selective flushing from update_mmu_cache() once we can
+	   sanely test the page flags for PG_arch_1 (PG_dcache_dirty) to see if
+	   we need to do the D-cache purge. -- PFM */
+
+	sh64_dcache_purge_phy_page(page_to_phys(page));
+	wmb();
+}
+
+/*##########################################################################
+			ARCH/SH64 PRIVATE CALLABLE API. 
+  ##########################################################################*/
+
+void flush_cache_sigtramp(unsigned long start, unsigned long end)
+{
+	/* For the address range [start,end), write back the data from the
+	   D-cache and invalidate the corresponding region of the I-cache for
+	   the current process.  Used to flush signal trampolines on the stack
+	   to make them executable. */
+
+	sh64_dcache_wback_current_user_range(start, end);
+	wmb();
+	sh64_icache_inv_current_user_range(start, end);
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/mm/extable.c linux-2.4.22-pre3/arch/sh64/mm/extable.c
--- linux-2.4.22-pre2/arch/sh64/mm/extable.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mm/extable.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,95 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/mm/extable.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * Completely coherent with i386/sh/...
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+		 const struct exception_table_entry *last,
+		 unsigned long value)
+{
+        while (first <= last) {
+		const struct exception_table_entry *mid;
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+                if (diff == 0)
+                        return mid->fixup;
+                else if (diff < 0)
+
+			/*
+			 * The dicotomic search assumes the same
+			 * upward assignement of linker addresses
+			 * for both .text and __ex_table sections.
+			 * __ex_table entries gets automagically
+			 * ordered.
+			 */
+                        first = mid+1;
+                else
+                        last = mid-1;
+        }
+        return 0;
+}
+
+
+/* Some functions that may trap due to a bad user-mode address have too many loads
+   and stores in them to make it at all practical to label each one and put them all in
+   the main exception table.
+
+   In particular, the fast memcpy routine is like this.  It's fix-up is just to fall back
+   to a slow byte-at-a-time copy, which is handled the conventional way.  So it's functionally
+   OK to just handle any trap occurring in the fast memcpy with that fixup. */
+unsigned long
+check_exception_ranges(unsigned long addr)
+{
+	extern unsigned long copy_user_memcpy, copy_user_memcpy_end, __copy_user_fixup;
+	if ((addr >= (unsigned long) &copy_user_memcpy) && (addr <= (unsigned long) &copy_user_memcpy_end)) {
+		return (unsigned long) &__copy_user_fixup;
+	}
+
+	return 0; /* no match */
+}
+
+
+unsigned long
+search_exception_table(unsigned long addr)
+{
+	unsigned long ret;
+
+	ret = check_exception_ranges(addr);
+	if (ret) return ret;
+
+#ifndef CONFIG_MODULES
+	/* There is only the kernel to search.  */
+	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
+	if (ret) return ret;
+#else
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (mp->ex_table_start == NULL)
+			continue;
+		ret = search_one_table(mp->ex_table_start,
+				       mp->ex_table_end - 1, addr);
+		if (ret) return ret;
+	}
+#endif
+
+	return 0;
+}
diff -urN linux-2.4.22-pre2/arch/sh64/mm/fault.c linux-2.4.22-pre3/arch/sh64/mm/fault.c
--- linux-2.4.22-pre2/arch/sh64/mm/fault.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mm/fault.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,729 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/mm/fault.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003 <Richard.Curnow@superh.com> (/proc/tlb, audit_mm, bug fixes)
+ * Copyright (C) 2003  Paul Mundt
+ *
+ */
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/tlb.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/registers.h>		/* required by inline asm statements */
+
+#if defined(CONFIG_SH64_PROC_TLB)
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+/* Count numbers of tlb refills in each region */
+static unsigned long long calls_to_update_mmu_cache = 0ULL;
+static unsigned long long calls_to_flush_tlb_page   = 0ULL;
+static unsigned long long calls_to_flush_tlb_range  = 0ULL;
+static unsigned long long calls_to_flush_tlb_mm     = 0ULL;
+static unsigned long long calls_to_flush_tlb_all    = 0ULL;
+unsigned long long calls_to_do_slow_page_fault = 0ULL;
+unsigned long long calls_to_do_fast_page_fault = 0ULL;
+
+/* Count size of ranges for flush_tlb_range */
+static unsigned long long flush_tlb_range_1         = 0ULL;
+static unsigned long long flush_tlb_range_2         = 0ULL;
+static unsigned long long flush_tlb_range_3_4       = 0ULL;
+static unsigned long long flush_tlb_range_5_7       = 0ULL;
+static unsigned long long flush_tlb_range_8_11      = 0ULL;
+static unsigned long long flush_tlb_range_12_15     = 0ULL;
+static unsigned long long flush_tlb_range_16_up     = 0ULL;
+
+static unsigned long long page_not_present          = 0ULL;
+
+#endif
+
+extern void die(const char *,struct pt_regs *,long);
+
+#define PFLAG(val,flag)   (( (val) & (flag) ) ? #flag : "" )
+#define PPROT(flag) PFLAG(pgprot_val(prot),flag)
+
+static __inline__ void print_prots(pgprot_t prot)
+{    
+  printk("prot is 0x%08lx\n",pgprot_val(prot));
+
+  printk("%s %s %s %s %s\n",PPROT(_PAGE_SHARED),PPROT(_PAGE_READ),
+	PPROT(_PAGE_EXECUTE),PPROT(_PAGE_WRITE),PPROT(_PAGE_USER));
+}
+
+
+static __inline__ void print_vma(struct vm_area_struct *vma)
+{
+  printk("vma start 0x%08lx\n",vma->vm_start);
+  printk("vma end   0x%08lx\n",vma->vm_end);
+
+  print_prots(vma->vm_page_prot);
+  printk("vm_flags 0x%08lx\n",vma->vm_flags);
+} 
+
+static __inline__ void print_task(struct task_struct *tsk)
+{
+  printk("Task pid %d\n",tsk->pid);
+}
+
+static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address)
+{
+	pgd_t *dir;
+	pmd_t *pmd;
+	pte_t *pte;
+	pte_t entry;
+
+	dir = pgd_offset(mm, address);
+	if (pgd_none(*dir)) {
+		return NULL;
+	}
+
+	pmd = pmd_offset(dir, address);
+	if (pmd_none(*pmd)) {
+		return NULL;
+	}
+
+	pte = pte_offset(pmd, address);
+	entry = *pte;
+
+	if (pte_none(entry)) {
+		return NULL;
+	}
+	if (!pte_present(entry)) {
+		return NULL;
+	}
+
+	return pte;
+}
+
+/*
+ * This routine handles page faults.  It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ */
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
+			      unsigned long textaccess, unsigned long address)
+{
+	struct task_struct *tsk;
+	struct mm_struct *mm;
+	struct vm_area_struct * vma;
+	unsigned long page;
+	unsigned long long lpage;
+	unsigned long fixup;
+	pte_t *pte;
+
+#if defined(CONFIG_SH64_PROC_TLB)
+        ++calls_to_do_slow_page_fault;
+#endif
+
+	/* SIM
+	 * Note this is now called with interrupts still disabled
+	 * This is to cope with being called for a missing IO port
+	 * address with interupts disabled. This should be fixed as
+	 * soon as we have a better 'fast path' miss handler.
+	 *
+	 * Plus take care how you try and debug this stuff.
+	 * For example, writing debug data to a port which you
+	 * have just faulted on is not going to work.
+	 */
+
+	//		printk("fault, address is 0x%08x textaccess %d writeaccess %d\n",
+	//			       address,textaccess,writeaccess);
+
+	/* Temporary plumbing - this will go into entry.S soon.  If the fast
+	   path can service the fault, get out quick. */
+#if 0
+	/* Now on fast path */
+	if (do_fast_page_fault(regs, writeaccess, textaccess, address) == 1) return;
+#endif
+
+	/* Otherwise, there is work to be done to put something into the PTE for the
+	   faulting address */
+
+	tsk = current;
+	mm = tsk->mm;
+
+	/* Not an IO address, so reenable interrupts */
+	sti();
+
+	/*
+	 * If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+	if (in_interrupt() || !mm)
+		goto no_context;
+
+	/* TLB misses upon some cache flushes get done under cli() */
+	down_read(&mm->mmap_sem);
+
+	vma = find_vma(mm, address);
+
+	if (!vma) {
+#ifdef DEBUG_FAULT
+	  print_task(tsk);
+		printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n",
+		       __FUNCTION__,__LINE__,
+		       address,regs->pc,textaccess,writeaccess);
+		show_regs(regs);
+#endif
+		goto bad_area;
+	}
+	if (vma->vm_start <= address) {
+		goto good_area;
+	}
+
+	if (!(vma->vm_flags & VM_GROWSDOWN)) {
+#ifdef DEBUG_FAULT
+		print_task(tsk);
+		printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n",
+		       __FUNCTION__,__LINE__,
+		       address,regs->pc,textaccess,writeaccess);
+		show_regs(regs);
+
+		print_vma(vma);
+#endif
+		goto bad_area;
+	}
+	if (expand_stack(vma, address)) {
+#ifdef DEBUG_FAULT
+		print_task(tsk);
+		printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n",
+		       __FUNCTION__,__LINE__,
+		       address,regs->pc,textaccess,writeaccess);
+		show_regs(regs);
+#endif
+		goto bad_area;
+	}
+/*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+good_area:
+	if (writeaccess) {
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	} else {
+		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+			goto bad_area;
+	}
+
+	if (textaccess) {
+		if (!(vma->vm_flags & VM_EXEC))
+			goto bad_area;
+	}
+
+	/*
+	 * If for any reason at all we couldn't handle the fault,
+	 * make sure we exit gracefully rather than endlessly redo
+	 * the fault.
+	 */
+survive:
+	switch (handle_mm_fault(mm, vma, address, writeaccess)) {
+	case 1:
+		tsk->min_flt++;
+		break;
+	case 2:
+		tsk->maj_flt++;
+		break;
+	case 0:
+		goto do_sigbus;
+	default:
+		goto out_of_memory;
+	}
+	/* If we get here, the page fault has been handled.  Do the TLB refill
+	   now from the newly-setup PTE, to avoid having to fault again right
+	   away on the same instruction. */
+	pte = lookup_pte (mm, address);
+	if (!pte) {
+		/* From empirical evidence, we can get here, due to
+		   !pte_present(pte).  (e.g. if a swap-in occurs, and the page
+		   is swapped back out again before the process that wanted it
+		   gets rescheduled?) */
+		goto no_pte;
+	}
+
+	__do_tlb_refill(address, textaccess, pte);
+
+no_pte:
+
+	up_read(&mm->mmap_sem);
+	return;
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * Fix it, but check if it's kernel or user first..
+ */
+bad_area:
+#ifdef DEBUG_FAULT
+	printk("fault:bad area\n");
+#endif
+	up_read(&mm->mmap_sem);
+
+	if (user_mode(regs)) {
+		tsk->thread.address = address;
+		tsk->thread.error_code = writeaccess;
+		force_sig(SIGSEGV, tsk);
+		return;
+	}
+
+no_context:
+#ifdef DEBUG_FAULT
+	printk("fault:No context\n");
+#endif
+	/* Are we prepared to handle this kernel fault?  */
+	fixup = search_exception_table(regs->pc);
+	if (fixup != 0) {
+		regs->pc = fixup;
+		return;
+	}
+
+/*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ *
+ */
+	if (address < PAGE_SIZE)
+		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+	else
+		printk(KERN_ALERT "Unable to handle kernel paging request");
+	printk(" at virtual address %08lx\n", address);
+	printk(KERN_ALERT "pc = %08Lx%08Lx\n", regs->pc >> 32, regs->pc & 0xffffffff);
+	if (0 == mmu_pdtp_cache) {
+		printk("mmu_pdtp_cache==0!\n");
+	} else {
+		page = pgd_val(*mmu_pdtp_cache);
+		if (page && (page & _PAGE_PRESENT)) {
+			page = (((unsigned long *) page)[address >> PGDIR_SHIFT] & PAGE_MASK);
+			printk(KERN_ALERT "*pmd = %08lx\n", page);
+			if (page && (page & _PAGE_PRESENT)) {
+				page = (((unsigned long *) page)[(address >> PMD_SHIFT) & PMD_MASK] & \
+					 PAGE_MASK);
+				printk(KERN_ALERT "*pte = %08lx\n", page);
+				if (page & (page & _PAGE_PRESENT)) {
+					lpage = ((unsigned long long *) (page)) \
+						 [(address >> PAGE_SHIFT) & PAGE_MASK];
+					printk(KERN_ALERT "pte = %08Lx%08Lx\n",
+							   lpage >> 32, lpage & 0xffffffff);
+				}
+			}
+		}
+	}
+	die("Oops", regs, writeaccess);
+	do_exit(SIGKILL);
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+	if (current->pid == 1) {
+		yield();
+		goto survive;
+	}
+	printk("fault:Out of memory\n");
+	up_read(&mm->mmap_sem);
+	printk("VM: killing process %s\n", tsk->comm);
+	if (user_mode(regs))
+		do_exit(SIGKILL);
+	goto no_context;
+
+do_sigbus:
+	printk("fault:Do sigbus\n");
+	up_read(&mm->mmap_sem);
+
+	/*
+	 * Send a sigbus, regardless of whether we were in kernel
+	 * or user mode.
+	 */
+	tsk->thread.address = address;
+	tsk->thread.error_code = writeaccess;
+	tsk->thread.trap_no = 14;
+	force_sig(SIGBUS, tsk);
+
+	/* Kernel mode? Handle exceptions or die */
+	if (!user_mode(regs))
+		goto no_context;
+}
+
+
+void flush_tlb_all(void);
+
+void update_mmu_cache(struct vm_area_struct * vma,
+			unsigned long address, pte_t pte)
+{
+#if defined(CONFIG_SH64_PROC_TLB)
+        ++calls_to_update_mmu_cache;
+#endif
+	/* This appears to get called once for every pte entry that gets
+	   established => I don't think it's efficient to try refilling the
+	   TLBs with the pages - some may not get accessed even.  Also, for
+	   executable pages, it is impossible to determine reliably here which
+	   TLB they should be mapped into (or both even).
+
+	   So, just do nothing here and handle faults on demand.  In the
+	   TLBMISS handling case, the refill is now done anyway after the pte
+	   has been fixed up, so that deals with most useful cases.
+	   */
+
+	return;
+}
+
+static void __flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	unsigned long long match, pteh=0, lpage;
+	unsigned long tlb;
+	struct mm_struct *mm;
+
+	mm = vma->vm_mm;
+
+	if (mm->context == NO_CONTEXT)
+		return;
+
+	/*
+	 * Sign-extend based on neff.
+	 */
+	lpage = (page & NEFF_SIGN) ? (page | NEFF_MASK) : page;
+	match = ((mm->context & MMU_CONTEXT_ASID_MASK) << PTEH_ASID_SHIFT) | PTEH_VALID;
+	match |= lpage;
+
+        /* Do ITLB : don't bother for pages in non-exectutable VMAs */
+	if (vma->vm_flags & VM_EXEC) {
+		for_each_itlb_entry(tlb) {
+			asm volatile ("getcfg	%1, 0, %0"
+				      : "=r" (pteh)
+				      : "r" (tlb) );
+
+			if (pteh == match) {
+				__flush_tlb_slot(tlb);
+				break;
+			}
+			
+		}
+	}
+
+        /* Do DTLB : any page could potentially be in here. */
+	for_each_dtlb_entry(tlb) {
+		asm volatile ("getcfg	%1, 0, %0"
+			      : "=r" (pteh)
+			      : "r" (tlb) );
+
+		if (pteh == match) {
+			__flush_tlb_slot(tlb);
+			break;
+		}
+		
+	}
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	unsigned long flags;
+
+#if defined(CONFIG_SH64_PROC_TLB)
+        ++calls_to_flush_tlb_page;
+#endif
+
+	if (vma->vm_mm) {
+		page &= PAGE_MASK;
+		save_and_cli(flags);
+		__flush_tlb_page(vma, page);
+		restore_flags(flags);
+	}
+}
+
+void flush_tlb_range(struct mm_struct *mm, unsigned long start,
+		     unsigned long end)
+{
+	unsigned long flags;
+	unsigned long long match, pteh=0, pteh_epn, pteh_low;
+	unsigned long tlb;
+
+#if defined(CONFIG_SH64_PROC_TLB)
+        ++calls_to_flush_tlb_range;
+
+        {
+          unsigned long size = (end - 1) - start;
+          size >>= 12; /* divide by PAGE_SIZE */
+          size++; /* end=start+4096 => 1 page */
+          switch (size) {
+            case  1        : flush_tlb_range_1++;     break;
+            case  2        : flush_tlb_range_2++;     break;
+            case  3 ...  4 : flush_tlb_range_3_4++;   break;
+            case  5 ...  7 : flush_tlb_range_5_7++;   break;
+            case  8 ... 11 : flush_tlb_range_8_11++;  break;
+            case 12 ... 15 : flush_tlb_range_12_15++; break;
+            default        : flush_tlb_range_16_up++; break;
+          }
+        }
+#endif
+
+	if (mm->context == NO_CONTEXT)
+		return;
+
+	save_and_cli(flags);
+
+	start &= PAGE_MASK;
+	end &= PAGE_MASK;
+
+        match = ((mm->context & MMU_CONTEXT_ASID_MASK) << PTEH_ASID_SHIFT) | PTEH_VALID;
+
+        /* Flush ITLB */
+	for_each_itlb_entry(tlb) {
+                asm volatile ("getcfg	%1, 0, %0"
+                              : "=r" (pteh)
+                              : "r" (tlb) );
+                              
+                pteh_epn = pteh & PAGE_MASK;
+                pteh_low = pteh & ~PAGE_MASK;
+
+                if (pteh_low == match && pteh_epn >= start && pteh_epn <= end)
+			__flush_tlb_slot(tlb);
+        }
+
+        /* Flush DTLB */
+	for_each_dtlb_entry(tlb) {
+                asm volatile ("getcfg	%1, 0, %0"
+                              : "=r" (pteh)
+                              : "r" (tlb) );
+                              
+                pteh_epn = pteh & PAGE_MASK;
+                pteh_low = pteh & ~PAGE_MASK;
+
+                if (pteh_low == match && pteh_epn >= start && pteh_epn <= end)
+			__flush_tlb_slot(tlb);
+        }
+
+	restore_flags(flags);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	unsigned long flags;
+
+#if defined(CONFIG_SH64_PROC_TLB)
+        ++calls_to_flush_tlb_mm;
+#endif
+
+	if (mm->context == NO_CONTEXT)
+		return;
+
+	save_and_cli(flags);
+
+	mm->context=NO_CONTEXT;
+	if(mm==current->mm) 
+		activate_context(mm);
+
+	restore_flags(flags);
+	
+}
+
+void flush_tlb_all(void)
+{
+	/* Invalidate all, including shared pages, excluding fixed TLBs */
+
+	unsigned long flags, tlb;
+
+#if defined(CONFIG_SH64_PROC_TLB)
+        ++calls_to_flush_tlb_all;
+#endif
+
+	save_and_cli(flags);
+
+	/* Flush each ITLB entry */
+	for_each_itlb_entry(tlb) {
+		__flush_tlb_slot(tlb);
+	}
+
+	/* Flush each DTLB entry */
+	for_each_dtlb_entry(tlb) {
+		__flush_tlb_slot(tlb);
+	}
+
+	restore_flags(flags);
+}
+
+#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT
+/* Scan the page table structure of an entire struct mm for obvious anomalies. */
+
+static inline int starts_a(unsigned long xx)
+{
+	/* Check if virtual address starts with 'a'.  The kernel's superpage
+	 * lives at a0000000-bfffffff, and the lower part maps the RAM
+	   directly.  So if a kernel pointer doesn't start with it's top nibble
+	   = 'a' (at least up to 256Mb of RAM), it's bad.  - RPC */
+	if (((xx >> 28) & 0xf) == 0xa) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+static inline int is_present(unsigned long x)
+{
+	unsigned long mask = 0x80000000UL | _KERNPG_TABLE;
+	unsigned long y;
+
+	y = x & mask;
+	/* Copy logic from pgtable-3level.h */
+	if (y) return 1;
+	else   return 0;
+}
+
+void audit_mm (unsigned long long expevt, unsigned long long intevt, unsigned long long tra, unsigned long long vec)
+{
+	/* It seems simpler to have pgd,pmd,pte declared as pointers of
+	   appropriate types that we can just apply array indices to.   What
+	   we're doing here didn't fit with the existing macros very well. */
+	typedef unsigned long long my_pte_t;
+	typedef my_pte_t *my_pmd_t;
+	typedef my_pmd_t *my_pgd_t;
+
+#define SHOW_SRC do { \
+	switch (vec) { \
+		case 0x100: case 0x400: \
+			printk("EXPEVT=%08llx TRA=%08llx VEC=%08llx\n", expevt, tra, vec); break; \
+		case 0x600: \
+			printk("INTEVT=%08llx\n", intevt); break; \
+		default: \
+			printk("Source of this syscall/irq/exc unknown\n"); break; \
+	} \
+	} \
+	while (0)
+
+	my_pgd_t *pgd;
+	my_pmd_t *pmd;
+	my_pte_t *pte;
+
+	unsigned long xx_pgd, xx_pmd, xx_pte;
+	int i, j, k;
+	int pid = current->pid;
+	struct mm_struct *mm;
+
+	/* Ought to check for the page_present condition also. */
+
+	mm = current->active_mm;
+	if (in_interrupt() || !mm) return;
+
+	pgd = (my_pgd_t *) mm->pgd;
+	xx_pgd = (unsigned long) pgd;
+
+	if (!starts_a(xx_pgd)) {
+		printk("PID %5d, corrupt mm->pgd = %08lx\n", pid, xx_pgd);
+		SHOW_SRC;
+		return; /* not a lot of point going on. */
+	}
+	
+	for (i=0; i<USER_PTRS_PER_PGD; i++) {
+		pmd = pgd[i];
+		xx_pmd = (unsigned long) pmd;
+		if (xx_pmd == _PGD_EMPTY) continue;
+		if (!is_present(xx_pmd)) {
+			printk("PID %5d, pgd[%d] not present (=%08lx)\n", pid, i, xx_pmd);
+			SHOW_SRC;
+			continue;
+		}
+		
+		if (!starts_a(xx_pmd)) {
+			printk("PID %5d, pgd[%d] corrupted (=%08lx)\n", pid, i, xx_pmd);
+			SHOW_SRC;
+			continue; /* no point scanning further. */
+		}
+
+		for (j=0; j<PTRS_PER_PMD; j++) {
+			pte = pmd[j];
+			xx_pte = (unsigned long) pte;
+			if (xx_pte == _PMD_EMPTY) continue;
+			if (!is_present(xx_pte)) {
+				printk("PID %5d, pmd[%d] not present (=%08lx) (in pgd[%d])\n", pid, j, xx_pte, i);
+				SHOW_SRC;
+				continue;
+			}
+			if (!starts_a(xx_pte)) {
+				printk("PID %5d, pmd[%d] corrupted (=%08lx) (in pgd[%d])\n", pid, j, xx_pte, i);
+				SHOW_SRC;
+				continue; /* no point scanning further. */
+			}
+
+			for (k=0; k<PTRS_PER_PTE; k++) {
+				unsigned long long entry;
+				unsigned long masked_entry;
+				
+				entry = pte[k];
+				
+				/* All user pages should be mapped onto EMI or be absent? */
+				if (entry & _PAGE_PRESENT) {
+					int in_pci, in_emi;
+					masked_entry = (unsigned long) entry & 0xfffff000UL;
+					in_pci = (masked_entry >= 0x40000000UL) && (masked_entry < 0x5fffffffUL);
+					in_emi = (masked_entry >= 0x80000000UL) && (masked_entry < 0x8fffffffUL); /* Assume 256Mb of RAM at most */
+					if (!in_emi && !in_pci) { /* Assume 128Mb of RAM */
+						printk("PID %5d, pte[%d] corrupted (=%08lx%08lx) (in pmd[%d], pgd[%d])\n", pid, k, (unsigned long) (entry>>32), (unsigned long) entry, j, i);
+						SHOW_SRC;
+						continue; /* no point scanning further. */
+					}
+				}
+			}
+		}
+	}
+}
+#endif /* CONFIG_SH64_PAGE_TABLE_AUDIT */
+
+#if defined(CONFIG_SH64_PROC_TLB)
+/* Procfs interface to read the performance information */
+
+static int
+tlb_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, void *data)
+{
+  int len=0;
+  len += sprintf(buf+len, "do_fast_page_fault   called %12lld times\n", calls_to_do_fast_page_fault);
+  len += sprintf(buf+len, "do_slow_page_fault   called %12lld times\n", calls_to_do_slow_page_fault);
+  len += sprintf(buf+len, "update_mmu_cache     called %12lld times\n", calls_to_update_mmu_cache);
+  len += sprintf(buf+len, "flush_tlb_page       called %12lld times\n", calls_to_flush_tlb_page);
+  len += sprintf(buf+len, "flush_tlb_range      called %12lld times\n", calls_to_flush_tlb_range);
+  len += sprintf(buf+len, "flush_tlb_mm         called %12lld times\n", calls_to_flush_tlb_mm);
+  len += sprintf(buf+len, "flush_tlb_all        called %12lld times\n", calls_to_flush_tlb_all);
+  len += sprintf(buf+len, "flush_tlb_range_sizes\n"
+                          " 1      : %12lld\n"
+                          " 2      : %12lld\n"
+                          " 3 -  4 : %12lld\n"
+                          " 5 -  7 : %12lld\n"
+                          " 8 - 11 : %12lld\n"
+                          "12 - 15 : %12lld\n"
+                          "16+     : %12lld\n",
+                          flush_tlb_range_1, flush_tlb_range_2, flush_tlb_range_3_4,
+                          flush_tlb_range_5_7, flush_tlb_range_8_11, flush_tlb_range_12_15,
+                          flush_tlb_range_16_up);
+  len += sprintf(buf+len, "page not present           %12lld times\n", page_not_present);
+  *eof = 1;
+  return len;
+}
+
+static int __init register_proc_tlb(void)
+{
+  create_proc_read_entry("tlb", 0, NULL, tlb_proc_info, NULL);
+  return 0;
+}
+
+__initcall(register_proc_tlb);
+
+#endif
diff -urN linux-2.4.22-pre2/arch/sh64/mm/init.c linux-2.4.22-pre3/arch/sh64/mm/init.c
--- linux-2.4.22-pre2/arch/sh64/mm/init.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mm/init.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,203 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/mm/init.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+
+#include <asm/mmu_context.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/tlb.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#endif
+
+mmu_gather_t mmu_gathers[NR_CPUS];
+
+/*
+ * Cache of MMU context last used.
+ */
+unsigned long mmu_context_cache;
+pgd_t * mmu_pdtp_cache;
+
+static unsigned long totalram_pages = 0;
+static unsigned long totalhigh_pages = 0;
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving an inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+
+extern unsigned char empty_zero_page[PAGE_SIZE];
+extern unsigned char empty_bad_page[PAGE_SIZE];
+extern pte_t empty_bad_pte_table[PTRS_PER_PTE];
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+extern char _text, _etext, _edata, __bss_start, _end;
+extern char __init_begin, __init_end;
+
+/* It'd be good if these lines were in the standard header file. */
+#define START_PFN	(NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT)
+#define MAX_LOW_PFN	(NODE_DATA(0)->bdata->node_low_pfn)
+
+
+void show_mem(void)
+{
+	int i, total = 0, reserved = 0;
+	int shared = 0, cached = 0;
+
+	printk("Mem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+	i = max_mapnr;
+	while (i-- > 0) {
+		total++;
+		if (PageReserved(mem_map+i))
+			reserved++;
+		else if (PageSwapCache(mem_map+i))
+			cached++;
+		else if (page_count(mem_map+i))
+			shared += page_count(mem_map+i) - 1;
+	}
+	printk("%d pages of RAM\n",total);
+	printk("%d reserved pages\n",reserved);
+	printk("%d pages shared\n",shared);
+	printk("%d pages swap cached\n",cached);
+
+	show_buffers();
+}
+
+/*
+ * paging_init() sets up the page tables.
+ *
+ * head.S already did a lot to set up address translation for the kernel.
+ * Here we comes with:
+ * . MMU enabled
+ * . ASID set (SR)
+ * .  some 512MB regions being mapped of which the most relevant here is:
+ *   . CACHED segment (ASID 0 [irrelevant], shared AND NOT user)
+ * . possible variable length regions being mapped as:
+ *   . UNCACHED segment (ASID 0 [irrelevant], shared AND NOT user)
+ * . All of the memory regions are placed, independently from the platform
+ *   on high addresses, above 0x80000000.
+ * . swapper_pg_dir is already cleared out by the .space directive
+ *   in any case swapper does not require a real page directory since
+ *   it's all kernel contained.
+ *
+ * Those pesky NULL-reference errors in the kernel are then
+ * dealt with by not mapping address 0x00000000 at all.
+ *
+ */
+void __init paging_init(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+
+
+	mmu_context_cache = MMU_CONTEXT_FIRST_VERSION;
+
+        /*
+ 	 * All memory is good as ZONE_NORMAL (fall-through) and ZONE_DMA.
+         */
+	zones_size[ZONE_DMA] = MAX_LOW_PFN - START_PFN;
+
+	free_area_init_node(0, NODE_DATA(0), 0,zones_size, __MEMORY_START, 0);
+}
+
+void __init mem_init(void)
+{
+	int codesize, reservedpages, datasize, initsize;
+	int tmp;
+
+	max_mapnr = num_physpages = MAX_LOW_PFN - START_PFN;
+	high_memory = (void *)__va(MAX_LOW_PFN * PAGE_SIZE);
+
+	/*
+         * Clear the zero-page.
+         * This is not required but we might want to re-use
+         * this very page to pass boot parameters, one day.
+         */
+	memset(empty_zero_page, 0, PAGE_SIZE);
+
+	/* this will put all low memory onto the freelists */
+	totalram_pages += free_all_bootmem();
+	reservedpages = 0;
+	for (tmp = 0; tmp < num_physpages; tmp++)
+		/*
+		 * Only count reserved RAM pages
+		 */
+		if (PageReserved(mem_map+tmp))
+			reservedpages++;
+	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
+	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
+	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+	printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
+		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+		max_mapnr << (PAGE_SHIFT-10),
+		codesize >> 10,
+		reservedpages << (PAGE_SHIFT-10),
+		datasize >> 10,
+		initsize >> 10);
+}
+
+void free_initmem(void)
+{
+	unsigned long addr;
+	
+	addr = (unsigned long)(&__init_begin);
+	for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+		ClearPageReserved(mem_map + MAP_NR(addr));
+		set_page_count(mem_map+MAP_NR(addr), 1);
+		free_page(addr);
+		totalram_pages++;
+	}
+	printk ("Freeing unused kernel memory: %ldk freed\n", (&__init_end - &__init_begin) >> 10);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	unsigned long p;
+	for (p = start; p < end; p += PAGE_SIZE) {
+		ClearPageReserved(mem_map + MAP_NR(p));
+		set_page_count(mem_map+MAP_NR(p), 1);
+		free_page(p);
+		totalram_pages++;
+	}
+	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
+void si_meminfo(struct sysinfo *val)
+{
+	val->totalram = totalram_pages;
+	val->sharedram = 0;
+	val->freeram = nr_free_pages();
+	val->bufferram = atomic_read(&buffermem_pages);
+	val->totalhigh = totalhigh_pages;
+	val->freehigh = nr_free_highpages();
+	val->mem_unit = PAGE_SIZE;
+	return;
+}
diff -urN linux-2.4.22-pre2/arch/sh64/mm/ioremap.c linux-2.4.22-pre3/arch/sh64/mm/ioremap.c
--- linux-2.4.22-pre2/arch/sh64/mm/ioremap.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mm/ioremap.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,440 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/mm/ioremap.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ * Mostly derived from arch/sh/mm/ioremap.c which, in turn is mostly
+ * derived from arch/i386/mm/ioremap.c .
+ *
+ *   (C) Copyright 1995 1996 Linus Torvalds
+ */
+
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+#include <asm/pgalloc.h>
+#include <linux/ioport.h>
+#include <linux/bootmem.h>
+#include <linux/proc_fs.h>
+
+/*
+** change to:
+** #define DEBUG_IOREMAP(args)	printk(args)
+** to turn on ioremap trace.
+*/
+#define DEBUG_IOREMAP(args)
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+	unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+
+	DEBUG_IOREMAP(("    %s: pte %x address %x size %x phys_addr %x\n", \
+			__FUNCTION__,pte,address,size,phys_addr));
+
+	do {
+		if (!pte_none(*pte))
+			printk("remap_area_pte: page already exists\n");
+		set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT |
+					_PAGE_READ | _PAGE_WRITE | 
+					_PAGE_DIRTY | _PAGE_ACCESSED |_PAGE_SHARED | flags)));
+		address += PAGE_SIZE;
+		phys_addr += PAGE_SIZE;
+		pte++;
+	} while (address && (address < end));
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
+	unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+
+        DEBUG_IOREMAP(("%s: pmd 0x%08x, addr. 0x%08x, phys. 0x%08x, end 0x%08x pmd 0x%08x\n", \
+	       pmd, address, phys_addr, end));
+
+	phys_addr -= address;
+	do {	 
+
+        DEBUG_IOREMAP(("%s: pmd 0x%08x, addr. 0x%08x, phys. 0x%08x, end 0x%08x pmd 0x%08x\n", \
+	               __FUNCTION__, pmd, address, phys_addr, end));
+
+		pte_t * pte = pte_alloc(&init_mm, pmd, address);
+		if (!pte) {
+			return -ENOMEM;
+		}
+		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+		
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+
+    		DEBUG_IOREMAP(("remap_area_pmd address is 0x%08x phys_addr is 0x%08x end 0x%08x\n", address,phys_addr,end));
+
+
+	} while (address && (address < end));
+	return 0;
+}
+
+static int remap_area_pages(unsigned long address, unsigned long phys_addr,
+				 unsigned long size, unsigned long flags)
+{
+	int error;
+	pgd_t * dir;
+	unsigned long end = address + size;
+
+	phys_addr -= address;
+	dir = pgd_offset(&init_mm, address);
+	flush_cache_all();
+	spin_lock(&init_mm.page_table_lock);    
+	do {
+
+		pmd_t *pmd = pmd_alloc(&init_mm,dir, address);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		if (remap_area_pmd(pmd, address, end - address,
+				   phys_addr + address, flags)) {
+			 break;
+		}
+		error=0;
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (address && (address < end));
+	spin_unlock(&init_mm.page_table_lock);   
+	flush_tlb_all();
+	return 0;
+}
+
+/*
+ * Generic mapping function (not visible outside):
+ */
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ */
+void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+{
+	void * addr;
+	struct vm_struct * area;
+	unsigned long offset, last_addr;
+
+	/* Don't allow wraparound or zero size */
+	last_addr = phys_addr + size - 1;
+	if (!size || last_addr < phys_addr)
+		return NULL;
+
+	/*
+	 * Mappings have to be page-aligned
+	 */
+	offset = phys_addr & ~PAGE_MASK;
+	phys_addr &= PAGE_MASK;
+	size = PAGE_ALIGN(last_addr) - phys_addr;
+
+	/*
+	 * Ok, go for it..
+	 */
+	area = get_vm_area(size, VM_IOREMAP);
+	DEBUG_IOREMAP(("Get vm_area returns 0x%08x addr 0x%08x \n", \
+		      area, area->addr));
+
+	if (!area)
+		return NULL;
+	addr = area->addr;
+	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
+		vfree(addr);
+		return NULL;
+	}
+	return (void *) (offset + (char *)addr);
+}
+
+void iounmap(void *addr)
+{
+	if (((long) addr >= VMALLOC_START) && ((long) addr <= VMALLOC_END))
+		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+}
+
+static struct resource shmedia_iomap = {
+        .name	= "shmedia_iomap",
+	.start	= IOBASE_VADDR,
+	.end	= IOBASE_END - 1,
+};
+
+static void shmedia_mapioaddr(unsigned long pa, unsigned long va);
+static void shmedia_unmapioaddr(unsigned long vaddr);
+static unsigned long shmedia_ioremap(struct resource *res, u32 pa, int sz);
+
+/*
+ * We have the same problem as the SPARC, so lets have the same comment:
+ * Our mini-allocator...
+ * Boy this is gross! We need it because we must map I/O for
+ * timers and interrupt controller before the kmalloc is available.
+ */
+
+#define XNMLN  15
+#define XNRES  10
+
+struct xresource {
+	struct resource xres;   /* Must be first */
+	int xflag;              /* 1 == used */
+	char xname[XNMLN+1];
+};
+
+static struct xresource xresv[XNRES];
+
+static struct xresource *xres_alloc(void)
+{
+        struct xresource *xrp;
+        int n;
+
+        xrp = xresv;
+        for (n = 0; n < XNRES; n++) {
+                if (xrp->xflag == 0) {
+                        xrp->xflag = 1;
+                        return xrp;
+                }
+                xrp++;
+        }
+        return NULL;
+}
+
+static void xres_free(struct xresource *xrp)
+{
+        xrp->xflag = 0;
+}
+
+static struct resource *shmedia_find_resource(struct resource *root,
+					      unsigned long vaddr)
+{
+	struct resource *res;
+
+	for (res = root->child; res; res = res->sibling)
+		if (res->start <= vaddr && res->end >= vaddr)
+			return res;
+
+	return NULL;
+}
+
+static unsigned long shmedia_alloc_io(unsigned long phys, unsigned long size,
+				      const char *name)
+{
+        static int printed_full = 0;
+        struct xresource *xres;
+        struct resource *res;
+        char *tack;
+        int tlen;
+
+        if (name == NULL) name = "???";
+
+        if ((xres = xres_alloc()) != 0) {
+                tack = xres->xname;
+                res = &xres->xres;
+        } else {
+                if (!printed_full) {
+                        printk("%s: done with statics, switching to kmalloc\n",
+			       __FUNCTION__);
+                        printed_full = 1;
+                }
+                tlen = strlen(name);
+                tack = kmalloc(sizeof (struct resource) + tlen + 1, GFP_KERNEL);
+                if (!tack)
+			return -ENOMEM;
+                memset(tack, 0, sizeof(struct resource));
+                res = (struct resource *) tack;
+                tack += sizeof (struct resource);
+        }
+
+        strncpy(tack, name, XNMLN);
+        tack[XNMLN] = 0;
+        res->name = tack;
+
+        return shmedia_ioremap(res, phys, size);
+}
+
+static unsigned long shmedia_ioremap(struct resource *res, u32 pa, int sz)
+{
+        unsigned long offset = ((unsigned long) pa) & (~PAGE_MASK);
+	unsigned long round_sz = (offset + sz + PAGE_SIZE-1) & PAGE_MASK;
+        unsigned long va;
+        unsigned int psz;
+
+        if (allocate_resource(&shmedia_iomap, res, round_sz,
+			      shmedia_iomap.start, shmedia_iomap.end,
+			      PAGE_SIZE, NULL, NULL) != 0) {
+                panic("alloc_io_res(%s): cannot occupy\n",
+                    (res->name != NULL)? res->name: "???");
+        }
+
+        va = res->start;
+        pa &= PAGE_MASK;
+
+	psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE;
+
+	/* log at boot time ... */
+	printk("mapioaddr: %6s  [%2ld page%s]  va 0x%08lx   pa 0x%08x\n",
+	       ((res->name != NULL) ? res->name : "???"),
+	       psz, psz == 1 ? " " : "s", va, pa);
+
+        for (psz = res->end - res->start + 1; psz != 0; psz -= PAGE_SIZE) {
+                shmedia_mapioaddr(pa, va);
+                va += PAGE_SIZE;
+                pa += PAGE_SIZE;
+        }
+
+        res->start += offset;
+        res->end = res->start + sz - 1;         /* not strictly necessary.. */
+
+        return res->start;
+}
+
+static void shmedia_free_io(struct resource *res)
+{
+	unsigned long len = res->end - res->start + 1;
+
+	BUG_ON((len & (PAGE_SIZE - 1)) != 0);
+
+	while (len) {
+		len -= PAGE_SIZE;
+		shmedia_unmapioaddr(res->start + len);
+	}
+
+	release_resource(res);
+}
+
+static void shmedia_mapioaddr(unsigned long pa, unsigned long va)
+{
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	unsigned long flags = 1; /* 1 = CB0-1 device */
+
+
+	DEBUG_IOREMAP(("shmedia_mapiopage pa %08x va %08x\n",  pa, va));
+
+	pgdp = pgd_offset_k(va);
+	if (pgd_none(*pgdp)) {
+		pmdp = alloc_bootmem_low_pages(PTRS_PER_PMD * sizeof(pmd_t));
+		if (pmdp == NULL) panic("No memory for pmd\n");
+		memset(pmdp, 0, PTRS_PER_PGD * sizeof(pmd_t));
+		set_pgd(pgdp, __pgd((unsigned long)pmdp | _KERNPG_TABLE));
+	}
+
+	pmdp = pmd_offset(pgdp, va);
+	if (pmd_none(*pmdp)) {
+		ptep = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t));
+		if (ptep == NULL) panic("No memory for pte\n");
+		clear_page((void *)ptep);
+		set_pmd(pmdp, __pmd((unsigned long)ptep + _PAGE_TABLE));
+	}
+
+	ptep = pte_offset(pmdp, va);
+	set_pte(ptep, mk_pte_phys(pa, __pgprot(_PAGE_PRESENT |
+			_PAGE_READ | _PAGE_WRITE | 
+			_PAGE_DIRTY | _PAGE_ACCESSED |_PAGE_SHARED | flags)));
+}
+
+static void shmedia_unmapioaddr(unsigned long vaddr)
+{
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	pgdp = pgd_offset_k(vaddr);
+	pmdp = pmd_offset(pgdp, vaddr);
+
+	if (pmd_none(*pmdp) || pmd_bad(*pmdp))
+		return;
+
+	ptep = pte_offset(pmdp, vaddr);
+
+	if (pte_none(*ptep) || !pte_present(*ptep))
+		return;
+
+	clear_page((void *)ptep);
+	pte_clear(ptep);
+}
+
+unsigned long onchip_remap(unsigned long phys, unsigned long size, const char *name)
+{
+	if (size < PAGE_SIZE)
+		size = PAGE_SIZE;
+
+	return shmedia_alloc_io(phys, size, name);
+}
+
+void onchip_unmap(unsigned long vaddr)
+{
+	struct resource *res;
+	unsigned int psz;
+
+	res = shmedia_find_resource(&shmedia_iomap, vaddr);
+	if (!res) {
+		printk(KERN_ERR "%s: Failed to free 0x%08lx\n",
+		       __FUNCTION__, vaddr);
+		return;
+	}
+
+        psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE;
+
+        printk(KERN_DEBUG "unmapioaddr: %6s  [%2ld page%s] freed\n",
+	       res->name, psz, psz == 1 ? " " : "s");
+
+	shmedia_free_io(res);
+
+	if ((char *)res >= (char *)xresv &&
+	    (char *)res <  (char *)&xresv[XNRES]) {
+		xres_free((struct xresource *)res);
+	} else {
+		kfree(res);
+	}
+}
+
+#ifdef CONFIG_PROC_FS
+static int
+ioremap_proc_info(char *buf, char **start, off_t fpos, int length, int *eof,
+		  void *data)
+{
+	char *p = buf, *e = buf + length;
+	struct resource *r;
+	const char *nm;
+
+	for (r = ((struct resource *)data)->child; r != NULL; r = r->sibling) {
+		if (p + 32 >= e)        /* Better than nothing */
+			break;
+		if ((nm = r->name) == 0) nm = "???";
+		p += sprintf(p, "%08lx-%08lx: %s\n", r->start, r->end, nm);
+	}
+
+	return p-buf;
+}
+#endif /* CONFIG_PROC_FS */
+
+static int __init register_proc_onchip(void)
+{
+#ifdef CONFIG_PROC_FS
+	create_proc_read_entry("io_map",0,0, ioremap_proc_info, &shmedia_iomap);
+#endif
+	return 0;
+}
+
+__initcall(register_proc_onchip);
diff -urN linux-2.4.22-pre2/arch/sh64/mm/tlb.c linux-2.4.22-pre3/arch/sh64/mm/tlb.c
--- linux-2.4.22-pre2/arch/sh64/mm/tlb.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mm/tlb.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,166 @@
+/*
+ * arch/sh64/mm/tlb.c
+ *
+ * Copyright (C) 2003  Paul Mundt <lethal@linux-sh.org>
+ * Copyright (C) 2003  Richard Curnow <richard.curnow@superh.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */ 
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <asm/page.h>
+#include <asm/tlb.h>
+#include <asm/mmu_context.h>
+
+/**
+ * sh64_tlb_init
+ *
+ * Perform initial setup for the DTLB and ITLB.
+ */
+int __init sh64_tlb_init(void)
+{
+	/* Assign some sane DTLB defaults */
+	cpu_data->dtlb.entries	= 64;
+	cpu_data->dtlb.step	= 0x10;
+
+	cpu_data->dtlb.first	= DTLB_FIXED | cpu_data->dtlb.step;
+	cpu_data->dtlb.next	= cpu_data->dtlb.first;
+
+	cpu_data->dtlb.last	= DTLB_FIXED | 
+				  ((cpu_data->dtlb.entries - 1) * 
+				   cpu_data->dtlb.step);
+
+	/* And again for the ITLB */
+	cpu_data->itlb.entries	= 64;
+	cpu_data->itlb.step	= 0x10;
+
+	cpu_data->itlb.first	= ITLB_FIXED | cpu_data->itlb.step;
+	cpu_data->itlb.next	= cpu_data->itlb.first;
+	cpu_data->itlb.last	= ITLB_FIXED |
+				  ((cpu_data->itlb.entries - 1) *
+				   cpu_data->itlb.step);
+
+	return 0;
+}
+
+/**
+ * sh64_next_free_dtlb_entry
+ *
+ * Find the next available DTLB entry
+ */
+unsigned long long sh64_next_free_dtlb_entry(void)
+{
+	return cpu_data->dtlb.next;
+}
+
+/**
+ * sh64_get_wired_dtlb_entry
+ *
+ * Allocate a wired (locked-in) entry in the DTLB
+ */
+unsigned long long sh64_get_wired_dtlb_entry(void)
+{
+	unsigned long long entry = sh64_next_free_dtlb_entry();
+
+	cpu_data->dtlb.first += cpu_data->dtlb.step;
+	cpu_data->dtlb.next  += cpu_data->dtlb.step;
+
+	return entry;
+}
+
+/**
+ * sh64_put_wired_dtlb_entry
+ *
+ * @entry:	Address of TLB slot.
+ *
+ * Free a wired (locked-in) entry in the DTLB.
+ *
+ * Works like a stack, last one to allocate must be first one to free.
+ */
+int sh64_put_wired_dtlb_entry(unsigned long long entry)
+{
+	__flush_tlb_slot(entry);
+	
+	/*
+	 * We don't do any particularly useful tracking of wired entries,
+	 * so this approach works like a stack .. last one to be allocated
+	 * has to be the first one to be freed.
+	 *
+	 * We could potentially load wired entries into a list and work on
+	 * rebalancing the list periodically (which also entails moving the
+	 * contents of a TLB entry) .. though I have a feeling that this is
+	 * more trouble than it's worth.
+	 */
+
+	/* 
+	 * Entry must be valid .. we don't want any ITLB addresses!
+	 */
+	if (entry <= DTLB_FIXED)
+		return -EINVAL;
+
+	/* 
+	 * Next, check if we're within range to be freed. (ie, must be the
+	 * entry beneath the first 'free' entry!
+	 */
+	if (entry < (cpu_data->dtlb.first - cpu_data->dtlb.step))
+		return -EINVAL;
+
+	/* If we are, then bring this entry back into the list */
+	cpu_data->dtlb.first	-= cpu_data->dtlb.step;
+	cpu_data->dtlb.next	= entry;
+
+	return 0;
+}
+
+/**
+ * sh64_setup_tlb_slot
+ *
+ * @config_addr:	Address of TLB slot.
+ * @eaddr:		Virtual address.
+ * @asid:		Address Space Identifier.
+ * @paddr:		Physical address.
+ *
+ * Load up a virtual<->physical translation for @eaddr<->@paddr in the
+ * pre-allocated TLB slot @config_addr (see sh64_get_wired_dtlb_entry).
+ */
+inline void sh64_setup_tlb_slot(unsigned long long config_addr,
+				unsigned long eaddr,
+				unsigned long asid,
+				unsigned long paddr)
+{
+	unsigned long long pteh, ptel;
+
+	/* Sign extension */
+#if (NEFF == 32)
+	pteh = (unsigned long long)(signed long long)(signed long) eaddr;
+#else
+#error "Can't sign extend more than 32 bits yet"
+#endif
+	pteh &= PAGE_MASK;
+	pteh |= (asid << PTEH_ASID_SHIFT) | PTEH_VALID;
+#if (NEFF == 32)
+	ptel = (unsigned long long)(signed long long)(signed long) paddr;
+#else
+#error "Can't sign extend more than 32 bits yet"
+#endif
+	ptel &= PAGE_MASK;
+	ptel |= (_PAGE_CACHABLE | _PAGE_READ | _PAGE_WRITE);
+
+	asm volatile("putcfg %0, 1, %1\n\t"
+			"putcfg %0, 0, %2\n"
+			: : "r" (config_addr), "r" (ptel), "r" (pteh));
+}
+
+/**
+ * sh64_teardown_tlb_slot
+ *
+ * @config_addr:	Address of TLB slot.
+ *
+ * Teardown any existing mapping in the TLB slot @config_addr.
+ */
+inline void sh64_teardown_tlb_slot(unsigned long long config_addr)
+	__attribute__ ((alias("__flush_tlb_slot")));
+
diff -urN linux-2.4.22-pre2/arch/sh64/mm/tlbmiss.c linux-2.4.22-pre3/arch/sh64/mm/tlbmiss.c
--- linux-2.4.22-pre2/arch/sh64/mm/tlbmiss.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/mm/tlbmiss.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,283 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/mm/tlbmiss.c
+ *
+ * Original code from fault.c
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * Fast PTE->TLB refill path
+ * Copyright (C) 2003 Richard.Curnow@superh.com
+ *
+ * IMPORTANT NOTES :
+ * The do_fast_page_fault function is called from a context in entry.S where very few registers
+ * have been saved.  In particular, the code in this file must be compiled not to use ANY
+ * caller-save regiseters that are not part of the restricted save set.  Also, it means that
+ * code in this file must not make calls to functions elsewhere in the kernel, or else the
+ * excepting context will see corruption in its caller-save registers.  Plus, the entry.S save
+ * area is non-reentrant, so this code has to run with SR.BL==1, i.e. no interrupts taken inside
+ * it and panic on any exception.
+ *
+ */
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+
+#include <asm/system.h>
+#include <asm/tlb.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/registers.h>		/* required by inline asm statements */
+
+/* Callable from fault.c, so not static */
+__inline__ void __do_tlb_refill(unsigned long address, 
+                            unsigned long long is_text_not_data, pte_t *pte)
+{
+	unsigned long long ptel;
+	unsigned long long pteh=0;
+	struct tlb_info *tlbp;
+	unsigned long long next;
+
+	/* Get PTEL first */
+	ptel = pte_val(*pte);
+
+	/*
+	 * Set PTEH register
+	 */
+	pteh = address & MMU_VPN_MASK;
+
+	/* Sign extend based on neff. */
+#if (NEFF == 32)
+	/* Faster sign extension */
+	pteh = (unsigned long long)(signed long long)(signed long)pteh;
+#else
+	/* General case */
+	pteh = (pteh & NEFF_SIGN) ? (pteh | NEFF_MASK) : pteh;
+#endif
+
+	/* Set the ASID. */
+	pteh |= get_asid() << PTEH_ASID_SHIFT;
+     
+	pteh |= PTEH_VALID;
+
+	/* Set PTEL register, set_pte has performed the sign extension */
+	ptel &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
+	ptel |= _PAGE_FLAGS_HARDWARE_DEFAULT; /* add default flags */
+
+	tlbp = is_text_not_data ? &(cpu_data->itlb) : &(cpu_data->dtlb);
+	next = tlbp->next;
+	__flush_tlb_slot(next);
+	asm volatile ("putcfg %0,1,%2\n\n\t"
+		      "putcfg %0,0,%1\n"
+		      :  : "r" (next), "r" (pteh), "r" (ptel) );
+
+	next += TLB_STEP;
+	if (next > tlbp->last) next = tlbp->first;
+	tlbp->next = next;
+
+}
+
+static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long protection_flags, 
+                                unsigned long long textaccess,
+				unsigned long address)
+{
+	pgd_t *dir;
+	pmd_t *pmd;
+	static pte_t *pte;
+	pte_t entry;
+
+	dir = pgd_offset_k(address);
+	pmd = pmd_offset(dir, address);
+
+	
+	if (pmd_none(*pmd)) {
+		return 0;
+	}
+	if (pmd_bad(*pmd)) {
+		pmd_clear(pmd);
+		return 0;
+	}
+	pte = pte_offset(pmd, address);
+	entry = *pte;
+	if (pte_none(entry) || !pte_present(entry)) {
+		return 0;
+	}
+
+	if ((pte_val(entry) & protection_flags) != protection_flags) {
+		return 0;
+	}
+
+        __do_tlb_refill(address, textaccess, pte);
+
+	return 1;
+}
+
+static int handle_tlbmiss(struct mm_struct *mm, unsigned long long protection_flags,
+			unsigned long long textaccess,
+			unsigned long address)
+{	
+	pgd_t *dir;
+	pmd_t *pmd;
+	pte_t *pte;
+	pte_t entry;
+	
+
+	/* NB. The PGD currently only contains a single entry - there is no
+	   page table tree stored for the top half of the address space since
+	   virtual pages in that region should never be mapped in user mode.
+	   (In kernel mode, the only things in that region are the 512Mb super
+	   page (locked in) and I/O device pages (handled by
+	   handle_vmalloc_fault), so no PGD for the upper half is required by
+	   kernel mode either).
+	   
+	   See how mm->pgd is allocated and initialised in pgd_alloc to see why
+	   the next test is necessary.  - RPC */
+	if (address & 0x80000000UL) {
+		/* upper half - never has page table entries. */
+		return 0;
+	}
+	dir = pgd_offset(mm, address);
+	if (pgd_none(*dir)) {
+		return 0;
+	}
+	if (!pgd_present(*dir)) {
+		return 0;
+	}
+
+	pmd = pmd_offset(dir, address);
+	if (pmd_none(*pmd)) {
+		return 0;
+	}
+	if (!pmd_present(*pmd)) {
+		return 0;
+	}
+	pte = pte_offset(pmd, address);
+	entry = *pte;
+	if (pte_none(entry)) {
+		return 0;
+	}
+	if (!pte_present(entry)) {
+		return 0;
+	}
+
+	/* If the page doesn't have sufficient protection bits set to service the
+	   kind of fault being handled, there's not much point doing the TLB refill.
+	   Punt the fault to the general handler. */
+	if ((pte_val(entry) & protection_flags) != protection_flags) {
+		return 0;
+	}
+
+        __do_tlb_refill(address, textaccess, pte);
+
+	return 1;
+}
+
+/* Put all this information into one structure so that everything is just arithmetic
+   relative to a single base address.  This reduces the number of movi/shori pairs needed
+   just to load addresses of static data. */
+struct expevt_lookup {
+	unsigned short protection_flags[8];
+	unsigned char  is_text_access[8];
+	unsigned char  is_write_access[8];
+};
+
+#define PRU (1<<9)
+#define PRW (1<<8)
+#define PRX (1<<7)
+#define PRR (1<<6)
+
+#define DIRTY (_PAGE_DIRTY | _PAGE_ACCESSED)
+#define YOUNG (_PAGE_ACCESSED)
+
+/* Sized as 8 rather than 4 to allow checking the PTE's PRU bit against whether
+   the fault happened in user mode or privileged mode. */
+static struct expevt_lookup expevt_lookup_table = {
+	.protection_flags = {PRX, PRX, 0, 0, PRR, PRR, PRW, PRW},
+	.is_text_access   = {1,   1,   0, 0, 0,   0,   0,   0}
+};
+
+/*
+   This routine handles page faults that can be serviced just by refilling a
+   TLB entry from an existing page table entry.  (This case represents a very
+   large majority of page faults.) Return 1 if the fault was successfully
+   handled.  Return 0 if the fault could not be handled.  (This leads into the
+   general fault handling in fault.c which deals with mapping file-backed
+   pages, stack growth, segmentation faults, swapping etc etc)
+ */
+asmlinkage int do_fast_page_fault(unsigned long long ssr_md, unsigned long long expevt,
+			          unsigned long address)
+{
+	struct task_struct *tsk;
+	struct mm_struct *mm;
+	unsigned long long textaccess;
+	unsigned long long protection_flags;
+	unsigned long long index;
+	unsigned long long expevt4;
+
+	/* The next few lines implement a way of hashing EXPEVT into a small array index
+	   which can be used to lookup parameters specific to the type of TLBMISS being
+	   handled.  Note:
+	   ITLBMISS has EXPEVT==0xa40
+	   RTLBMISS has EXPEVT==0x040
+	   WTLBMISS has EXPEVT==0x060
+	*/
+
+	expevt4 = (expevt >> 4);
+	/* TODO : xor ssr_md into this expression too.  Then we can check that PRU is set
+	   when it needs to be. */
+	index = expevt4 ^ (expevt4 >> 5);
+	index &= 7;
+	protection_flags = expevt_lookup_table.protection_flags[index];
+	textaccess       = expevt_lookup_table.is_text_access[index];
+
+#if (CONFIG_SH64_PROC_TLB)
+	++calls_to_do_fast_page_fault;
+#endif
+
+	/* SIM
+	 * Note this is now called with interrupts still disabled
+	 * This is to cope with being called for a missing IO port
+	 * address with interupts disabled. This should be fixed as
+	 * soon as we have a better 'fast path' miss handler.
+	 *
+	 * Plus take care how you try and debug this stuff.
+	 * For example, writing debug data to a port which you
+	 * have just faulted on is not going to work.
+	 */
+
+	tsk = current;
+	mm = tsk->mm;
+
+	if ((address >= VMALLOC_START && address < VMALLOC_END) ||
+	    (address >= IOBASE_VADDR  && address < IOBASE_END)) {
+		if (ssr_md) {
+			/* Process-contexts can never have this address range mapped */
+			if (handle_vmalloc_fault(mm, protection_flags, textaccess, address)) {
+				return 1;
+			}
+		}
+	} else if (!in_interrupt() && mm) {
+		if (handle_tlbmiss(mm, protection_flags, textaccess, address)) {
+			return 1;
+		}
+	}
+
+	return 0;
+
+}
+
diff -urN linux-2.4.22-pre2/arch/sh64/vmlinux.lds.S linux-2.4.22-pre3/arch/sh64/vmlinux.lds.S
--- linux-2.4.22-pre2/arch/sh64/vmlinux.lds.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/sh64/vmlinux.lds.S	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,158 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh5/vmlinux.lds.S
+ *
+ * ld script to make ST50 Linux kernel
+ * 
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * benedict.gaster@superh.com:	 2nd May 2002
+ *    Add definition of empty_zero_page to be the first page of kernel image.
+ *
+ * benedict.gaster@superh.com:	 3rd May 2002
+ *    Added support for ramdisk, removing statically linked romfs at the same time.
+ *
+ * lethal@linux-sh.org:          9th May 2003
+ *    Kill off GLOBAL_NAME() usage and other CDC-isms.
+ *
+ * lethal@linux-sh.org:         19th May 2003
+ *    Remove support for ancient toolchains.
+ */
+
+#include <linux/config.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/processor.h>
+
+#ifdef NOTDEF
+#ifdef CONFIG_LITTLE_ENDIAN
+OUTPUT_FORMAT("elf32-sh64l-linux", "elf32-sh64l-linux", "elf32-sh64l-linux")
+#else
+OUTPUT_FORMAT("elf32-sh64", "elf32-sh64", "elf32-sh64")
+#endif
+#endif
+
+OUTPUT_ARCH(sh:sh5)
+
+#define C_PHYS(x) AT (ADDR(x) - CONFIG_CACHED_MEMORY_OFFSET)
+#define U_PHYS(x) AT (ADDR(x) - CONFIG_UNCACHED_MEMORY_OFFSET)
+
+ENTRY(__start)
+SECTIONS
+{
+  . = CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START + PAGE_SIZE;
+  _text = .;			/* Text and read-only data */
+  text = .;			/* Text and read-only data */
+	
+  .empty_zero_page : C_PHYS(.empty_zero_page) {
+	*(.empty_zero_page)
+	} = 0
+	
+  .text : C_PHYS(.text) {
+	*(.text)
+	*(.text64)
+        *(.text..SHmedia32)
+	*(.fixup)
+	*(.gnu.warning)
+#ifdef CONFIG_LITTLE_ENDIAN
+	} = 0x6ff0fff0
+#else
+	} = 0xf0fff06f
+#endif
+  .text.lock : C_PHYS(.text.lock) { *(.text.lock) }	/* out-of-line lock text */
+  .rodata : C_PHYS(.rodata) { *(.rodata) *(.rodata.str1.8) }
+  .kstrtab : C_PHYS(.kstrtab) { *(.kstrtab) }
+
+  /* We likely want __ex_table to be Cache Line aligned */
+  . = ALIGN(L1_CACHE_BYTES);		/* Exception table */
+  __start___ex_table = .;
+  __ex_table : C_PHYS(__ex_table) { *(__ex_table) }
+  __stop___ex_table = .;
+
+  __start___ksymtab = .;	/* Kernel symbol table */
+  __ksymtab : C_PHYS(__ksymtab) { *(__ksymtab) }
+  __stop___ksymtab = .;
+
+  _etext = .;			/* End of text section */
+
+  .data : C_PHYS(.data) {			/* Data */
+	*(.data)
+	CONSTRUCTORS
+	}
+
+  _edata = .;			/* End of data section */
+
+  . = ALIGN(INIT_TASK_SIZE);	/* init_task: structure size aligned */
+  .data.init_task : C_PHYS(.data.init_task) { *(.data.init_task) }
+
+  . = ALIGN(PAGE_SIZE);		/* Init code and data */
+  __init_begin = .;
+  .text.init : C_PHYS(.text.init) { *(.text.init) }
+  .data.init : C_PHYS(.data.init) { *(.data.init) }
+  . = ALIGN(L1_CACHE_BYTES);	/* Better if Cache Line aligned */
+  __setup_start = .;
+  .setup.init : C_PHYS(.setup.init) { *(.setup.init) }
+  __setup_end = .;
+  __initcall_start = .;
+  .initcall.init : C_PHYS(.initcall.init) { *(.initcall.init) }
+  __initcall_end = .;
+  . = ALIGN(PAGE_SIZE);
+  __init_end = .;
+
+  . = ALIGN(L1_CACHE_BYTES);
+  .data.cacheline_aligned : C_PHYS(.data.cacheline_aligned) { *(.data.cacheline_aligned) }
+
+  /* Align to the biggest single data representation, head and tail */
+  . = ALIGN(8);
+  __bss_start = .;		/* BSS */
+  .bss : C_PHYS(.bss) {
+	*(.bss)
+	}
+  . = ALIGN(8);
+  _end = . ;
+
+  /* Sections to be discarded */
+  /DISCARD/ : {
+	*(.text.exit)
+	*(.data.exit)
+	*(.exitcall.exit)
+	}
+
+  /* Stabs debugging sections.  */
+  .stab 0 : C_PHYS(.stab) { *(.stab) }
+  .stabstr 0 : C_PHYS(.stabstr) { *(.stabstr) }
+  .stab.excl 0 : C_PHYS(.stab.excl) { *(.stab.excl) }
+  .stab.exclstr 0 : C_PHYS(.stab.exclstr) { *(.stab.exclstr) }
+  .stab.index 0 : C_PHYS(.stab.index) { *(.stab.index) }
+  .stab.indexstr 0 : C_PHYS(.stab.indexstr) { *(.stab.indexstr) }
+  .comment 0 : C_PHYS(.comment) { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging section are relative to the beginning
+     of the section so we begin .debug at 0.  */
+  /* DWARF 1 */
+  .debug          0 : C_PHYS(.debug) { *(.debug) }
+  .line           0 : C_PHYS(.line) { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : C_PHYS(.debug_srcinfo) { *(.debug_srcinfo) }
+  .debug_sfnames  0 : C_PHYS(.debug_sfnames) { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : C_PHYS(.debug_aranges) { *(.debug_aranges) }
+  .debug_pubnames 0 : C_PHYS(.debug_pubnames) { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : C_PHYS(.debug_info) { *(.debug_info) }
+  .debug_abbrev   0 : C_PHYS(.debug_abbrev) { *(.debug_abbrev) }
+  .debug_line     0 : C_PHYS(.debug_line) { *(.debug_line) }
+  .debug_frame    0 : C_PHYS(.debug_frame) { *(.debug_frame) }
+  .debug_str      0 : C_PHYS(.debug_str) { *(.debug_str) }
+  .debug_loc      0 : C_PHYS(.debug_loc) { *(.debug_loc) }
+  .debug_macinfo  0 : C_PHYS(.debug_macinfo) { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : C_PHYS(.debug_weaknames) { *(.debug_weaknames) }
+  .debug_funcnames 0 : C_PHYS(.debug_funcnames) { *(.debug_funcnames) }
+  .debug_typenames 0 : C_PHYS(.debug_typenames) { *(.debug_typenames) }
+  .debug_varnames  0 : C_PHYS(.debug_varnames) { *(.debug_varnames) }
+  /* These must appear regardless of  .  */
+}
diff -urN linux-2.4.22-pre2/arch/sparc/config.in linux-2.4.22-pre3/arch/sparc/config.in
--- linux-2.4.22-pre2/arch/sparc/config.in	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/sparc/config.in	2003-07-05 18:09:49.000000000 -0700
@@ -275,4 +275,5 @@
 
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -urN linux-2.4.22-pre2/arch/sparc/kernel/signal.c linux-2.4.22-pre3/arch/sparc/kernel/signal.c
--- linux-2.4.22-pre2/arch/sparc/kernel/signal.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/sparc/kernel/signal.c	2003-07-05 18:09:49.000000000 -0700
@@ -1131,6 +1131,8 @@
 			line = d_path(map->vm_file->f_dentry,
 				      map->vm_file->f_vfsmnt,
 				      buffer, PAGE_SIZE);
+			if (IS_ERR(line))
+				break;
 		}
 		printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
 			      kdevname(dev), ino);
diff -urN linux-2.4.22-pre2/arch/sparc64/config.in linux-2.4.22-pre3/arch/sparc64/config.in
--- linux-2.4.22-pre2/arch/sparc64/config.in	2002-11-28 15:53:12.000000000 -0800
+++ linux-2.4.22-pre3/arch/sparc64/config.in	2003-07-05 18:09:49.000000000 -0700
@@ -309,4 +309,5 @@
 
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -urN linux-2.4.22-pre2/arch/sparc64/defconfig linux-2.4.22-pre3/arch/sparc64/defconfig
--- linux-2.4.22-pre2/arch/sparc64/defconfig	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/sparc64/defconfig	2003-07-05 18:09:49.000000000 -0700
@@ -104,6 +104,7 @@
 CONFIG_FB_ATY_CT=y
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
+# CONFIG_FB_INTEL is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_3DFX is not set
@@ -292,7 +293,7 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 CONFIG_BLK_DEV_AEC62XX=m
 CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_WDC_ALI15X3 is not set
@@ -365,6 +366,10 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=5000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_AIC79XX is not set
 CONFIG_SCSI_AIC7XXX_OLD=m
 CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y
 CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8
@@ -429,6 +434,7 @@
 CONFIG_IEEE1394_CMP=m
 CONFIG_IEEE1394_AMDTP=m
 # CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
 
 #
 # Network device support
@@ -513,6 +519,7 @@
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 CONFIG_DL2K=m
 CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
 CONFIG_MYRI_SBUS=m
 CONFIG_NS83820=m
 # CONFIG_HAMACHI is not set
@@ -604,6 +611,7 @@
 # CONFIG_HFS_FS is not set
 CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
+CONFIG_HFSPLUS_FS=m
 CONFIG_BFS_FS=m
 CONFIG_EXT3_FS=m
 CONFIG_JBD=m
@@ -832,6 +840,7 @@
 CONFIG_USB_RTL8150=m
 CONFIG_USB_KAWETH=m
 CONFIG_USB_CATC=m
+CONFIG_USB_AX8817X=m
 CONFIG_USB_CDCETHER=m
 CONFIG_USB_USBNET=m
 
@@ -886,6 +895,7 @@
 CONFIG_USB_TIGL=m
 # CONFIG_USB_BRLVGER is not set
 CONFIG_USB_LCD=m
+# CONFIG_USB_SPEEDTOUCH is not set
 
 #
 # Bluetooth support
@@ -898,11 +908,13 @@
 CONFIG_BLUEZ_BNEP=m
 CONFIG_BLUEZ_BNEP_MC_FILTER=y
 CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
+CONFIG_BLUEZ_CMTP=m
 
 #
 # Bluetooth device drivers
 #
 CONFIG_BLUEZ_HCIUSB=m
+CONFIG_BLUEZ_USB_SCO=y
 CONFIG_BLUEZ_USB_ZERO_PACKET=y
 CONFIG_BLUEZ_HCIUART=m
 CONFIG_BLUEZ_HCIUART_H4=y
@@ -931,7 +943,27 @@
 # CONFIG_STACK_DEBUG is not set
 
 #
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
 # Library routines
 #
+CONFIG_CRC32=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
diff -urN linux-2.4.22-pre2/arch/sparc64/kernel/signal.c linux-2.4.22-pre3/arch/sparc64/kernel/signal.c
--- linux-2.4.22-pre2/arch/sparc64/kernel/signal.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/sparc64/kernel/signal.c	2003-07-05 18:09:49.000000000 -0700
@@ -679,6 +679,8 @@
 			line = d_path(map->vm_file->f_dentry,
 				      map->vm_file->f_vfsmnt,
 				      buffer, PAGE_SIZE);
+			if (IS_ERR(line))
+				break;
 		}
 		printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
 			      kdevname(dev), ino);
diff -urN linux-2.4.22-pre2/arch/sparc64/kernel/signal32.c linux-2.4.22-pre3/arch/sparc64/kernel/signal32.c
--- linux-2.4.22-pre2/arch/sparc64/kernel/signal32.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/sparc64/kernel/signal32.c	2003-07-05 18:09:49.000000000 -0700
@@ -1348,6 +1348,8 @@
 			line = d_path(map->vm_file->f_dentry,
 				      map->vm_file->f_vfsmnt,
 				      buffer, PAGE_SIZE);
+			if (IS_ERR(line))
+				break;
 		}
 		printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
 			      kdevname(dev), ino);
diff -urN linux-2.4.22-pre2/arch/sparc64/prom/init.c linux-2.4.22-pre3/arch/sparc64/prom/init.c
--- linux-2.4.22-pre2/arch/sparc64/prom/init.c	1999-12-20 22:05:52.000000000 -0800
+++ linux-2.4.22-pre3/arch/sparc64/prom/init.c	2003-07-05 18:09:49.000000000 -0700
@@ -36,6 +36,7 @@
 	int ints[3];
 	int node;
 	int i = 0;
+	int bufadjust;
 
 	prom_vers = PROM_P1275;
 
@@ -63,9 +64,19 @@
 	if (strncmp (buffer, "OBP ", 4))
 		goto strange_version;
 
-	/* Version field is expected to be 'OBP xx.yy.zz date...' */
+	/*
+	 * Version field is expected to be 'OBP xx.yy.zz date...'
+	 * However, Sun can't stick to this format very well, so
+	 * we need to check for 'OBP  xx.yy.zz date...' and adjust
+	 * accordingly. -spot
+	 */
+
+	if (strncmp (buffer, "OBP  ", 5))
+		bufadjust = 4;
+	else
+		bufadjust = 5;
 
-	p = buffer + 4;
+	p = buffer + bufadjust;
 	while (p && isdigit(*p) && i < 3) {
 		ints[i++] = simple_strtoul(p, NULL, 0);
 		if ((p = strchr(p, '.')) != NULL)
@@ -77,7 +88,7 @@
 	prom_rev = ints[1];
 	prom_prev = (ints[0] << 16) | (ints[1] << 8) | ints[2];
 
-	printk ("PROMLIB: Sun IEEE Boot Prom %s\n", buffer + 4);
+	printk ("PROMLIB: Sun IEEE Boot Prom %s\n", buffer + bufadjust);
 
 	prom_meminit();
 
diff -urN linux-2.4.22-pre2/arch/x86_64/Makefile linux-2.4.22-pre3/arch/x86_64/Makefile
--- linux-2.4.22-pre2/arch/x86_64/Makefile	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/Makefile	2003-07-05 18:09:49.000000000 -0700
@@ -19,7 +19,7 @@
 # 20010105  Andi Kleen, add IA32 compiler.
 #           ....and later removed it again....
 #
-# $Id: Makefile,v 1.32 2003/03/03 16:06:43 ak Exp $
+# $Id: Makefile,v 1.33 2003/05/12 14:36:34 ak Exp $
 
 #
 # early bootup linking needs 32bit. You can either use real 32bit tools
@@ -46,6 +46,7 @@
 CFLAGS += -finline-limit=2000
 # needed for earlier gcc 3.1
 CFLAGS += -fno-strength-reduce
+CFLAGS += -Wno-sign-compare
 #CFLAGS += -g
 ifneq ($(CONFIG_X86_REMOTE_DEBUG),y)
 CFLAGS += -fno-asynchronous-unwind-tables
diff -urN linux-2.4.22-pre2/arch/x86_64/config.in linux-2.4.22-pre3/arch/x86_64/config.in
--- linux-2.4.22-pre2/arch/x86_64/config.in	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/config.in	2003-07-05 18:09:49.000000000 -0700
@@ -112,12 +112,7 @@
 
 bool 'IA32 Emulation' CONFIG_IA32_EMULATION
 
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   dep_bool '  ACPI support' CONFIG_ACPI $CONFIG_PM
-   if [ "$CONFIG_ACPI" != "n" ]; then
-      source drivers/acpi/Config.in
-   fi
-fi
+source drivers/acpi/Config.in
 
 endmenu
 
@@ -232,6 +227,8 @@
 
 source net/bluetooth/Config.in
 
+source crypto/Config.in
+
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
diff -urN linux-2.4.22-pre2/arch/x86_64/defconfig linux-2.4.22-pre3/arch/x86_64/defconfig
--- linux-2.4.22-pre2/arch/x86_64/defconfig	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/defconfig	2003-07-05 18:09:49.000000000 -0700
@@ -65,16 +65,29 @@
 # CONFIG_BINFMT_MISC is not set
 CONFIG_PM=y
 CONFIG_IA32_EMULATION=y
+
+#
+# ACPI Support
+#
 CONFIG_ACPI=y
-CONFIG_ACPI_DEBUG=y
-CONFIG_ACPI_BUSMGR=y
-CONFIG_ACPI_SYS=y
-CONFIG_ACPI_CPU=y
-CONFIG_ACPI_BUTTON=y
-CONFIG_ACPI_AC=y
+# CONFIG_ACPI_HT_ONLY is not set
+CONFIG_ACPI_BOOT=y
+CONFIG_ACPI_BUS=y
+CONFIG_ACPI_INTERPRETER=y
 CONFIG_ACPI_EC=y
-CONFIG_ACPI_CMBATT=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_PCI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_BATTERY=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
 CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_TOSHIBA is not set
+CONFIG_ACPI_DEBUG=y
 
 #
 # Memory Technology Devices (MTD)
@@ -218,7 +231,7 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
@@ -232,13 +245,11 @@
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_PDC202XX_BURST is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_SVWKS is not set
@@ -295,8 +306,10 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
@@ -324,10 +337,13 @@
 # CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SEAGATE is not set
+# CONFIG_SCSI_SIM710 is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
@@ -582,7 +598,6 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
-CONFIG_SIMICSFS=y
 
 #
 # Network File Systems
@@ -703,5 +718,6 @@
 #
 # Library routines
 #
+# CONFIG_CRC32 is not set
 # CONFIG_ZLIB_INFLATE is not set
 # CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.22-pre2/arch/x86_64/ia32/ia32_binfmt.c linux-2.4.22-pre3/arch/x86_64/ia32/ia32_binfmt.c
--- linux-2.4.22-pre2/arch/x86_64/ia32/ia32_binfmt.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/ia32/ia32_binfmt.c	2003-07-05 18:09:49.000000000 -0700
@@ -12,6 +12,7 @@
 #include <linux/rwsem.h>
 #include <linux/sched.h>
 #include <linux/string.h>
+#include <linux/personality.h>
 #include <asm/segment.h> 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
@@ -27,7 +28,7 @@
 
 #define ELF_NAME "elf/i386"
 
-#define IA32_PAGE_OFFSET 0xFFFFe000
+#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
 #define IA32_STACK_TOP IA32_PAGE_OFFSET
 #define ELF_ET_DYN_BASE		(IA32_PAGE_OFFSET/3 + 0x1000000)
 
@@ -243,8 +244,9 @@
 		mpnt->vm_mm = current->mm;
 		mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
 		mpnt->vm_end = IA32_STACK_TOP;
-		mpnt->vm_page_prot = PAGE_COPY_EXEC;
-		mpnt->vm_flags = VM_STACK_FLAGS;
+		mpnt->vm_flags = vm_stack_flags32; 
+		mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ? 
+			PAGE_COPY_EXEC : PAGE_COPY;
 		mpnt->vm_ops = NULL;
 		mpnt->vm_pgoff = 0;
 		mpnt->vm_file = NULL;
diff -urN linux-2.4.22-pre2/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.22-pre3/arch/x86_64/ia32/ia32_ioctl.c
--- linux-2.4.22-pre2/arch/x86_64/ia32/ia32_ioctl.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/ia32/ia32_ioctl.c	2003-07-05 18:09:49.000000000 -0700
@@ -3488,7 +3488,7 @@
 };
 
 #define REF_SYMBOL(handler) if (0) (void)handler;
-#define HANDLE_IOCTL2(cmd,handler) REF_SYMBOL(handler);  asm volatile(".quad %P0, " #handler ",0"::"i" (cmd)); 
+#define HANDLE_IOCTL2(cmd,handler) REF_SYMBOL(handler);  asm volatile(".quad %P0, " #handler ",0"::"n" (cmd)); 
 #define HANDLE_IOCTL(cmd,handler) HANDLE_IOCTL2(cmd,handler)
 #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
 #define IOCTL_TABLE_START void ioctl_dummy(void) { asm volatile("\nioctl_start:\n\t" );
@@ -4555,7 +4555,7 @@
 			       "cmd(%08x){%s} arg(%08x) on %s\n",
 			       current->comm, current->pid,
 			       (int)fd, (unsigned int)cmd, buf, (unsigned int)arg,
-			       fn);
+			       IS_ERR(fn) ? "???" : fn);
 			if (path) 
 				free_page((unsigned long)path); 
 		}
diff -urN linux-2.4.22-pre2/arch/x86_64/ia32/sys_ia32.c linux-2.4.22-pre3/arch/x86_64/ia32/sys_ia32.c
--- linux-2.4.22-pre2/arch/x86_64/ia32/sys_ia32.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/ia32/sys_ia32.c	2003-07-05 18:09:49.000000000 -0700
@@ -16,7 +16,7 @@
  *
  * This file assumes that there is a hole at the end of user address space.
  *
- * $Id: sys_ia32.c,v 1.54 2003/03/24 09:28:26 ak Exp $
+ * $Id: sys_ia32.c,v 1.58 2003/05/09 17:21:17 ak Exp $
  */
 
 #include <linux/config.h>
@@ -845,6 +845,7 @@
 	ret = -EINVAL;
 	if (n < 0)
 		goto out_nofds;
+	size = FDS_BYTES(n);
 
 	if (n > current->files->max_fdset)
 		n = current->files->max_fdset;
@@ -855,7 +856,6 @@
 	 * long-words. 
 	 */
 	ret = -ENOMEM;
-	size = FDS_BYTES(n);
 	bits = kmalloc(6 * size, GFP_KERNEL);
 	if (!bits)
 		goto out_nofds;
@@ -1062,8 +1062,8 @@
 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
 
 struct rlimit32 {
-	int	rlim_cur;
-	int	rlim_max;
+	unsigned	rlim_cur;
+	unsigned	rlim_max;
 };
 
 extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
@@ -1080,6 +1080,10 @@
 	ret = sys_getrlimit(resource, &r);
 	set_fs(old_fs);
 	if (!ret) {
+		if (r.rlim_cur >= 0xffffffff) 
+			r.rlim_cur = RLIM_INFINITY32;
+		if (r.rlim_max >= 0xffffffff) 
+			r.rlim_max = RLIM_INFINITY32;
 		if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) ||
 		    __put_user(RESOURCE32(r.rlim_cur), &rlim->rlim_cur) ||
 		    __put_user(RESOURCE32(r.rlim_max), &rlim->rlim_max))
@@ -1099,9 +1103,13 @@
 	
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
-	ret = sys_old_getrlimit(resource, &r);
+	ret = sys_getrlimit(resource, &r);
 	set_fs(old_fs);
 	if (!ret) {
+		if (r.rlim_cur >= 0x7fffffff) 
+			r.rlim_cur = RLIM_INFINITY32;
+		if (r.rlim_max >= 0x7fffffff) 
+			r.rlim_max = RLIM_INFINITY32;	
 		if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) ||
 		    __put_user(r.rlim_cur, &rlim->rlim_cur) ||
 		    __put_user(r.rlim_max, &rlim->rlim_max))
@@ -1494,7 +1502,11 @@
         u32 totalswap;
         u32 freeswap;
         unsigned short procs;
-        char _f[22];
+	unsigned short pad; 
+        u32 totalhigh;
+        u32 freehigh;
+        u32 mem_unit;
+        char _f[20-2*sizeof(u32)-sizeof(int)];
 };
 
 extern asmlinkage long sys_sysinfo(struct sysinfo *info);
@@ -1520,7 +1532,10 @@
 	    __put_user (s.bufferram, &info->bufferram) ||
 	    __put_user (s.totalswap, &info->totalswap) ||
 	    __put_user (s.freeswap, &info->freeswap) ||
-	    __put_user (s.procs, &info->procs))
+	    __put_user (s.procs, &info->procs) ||
+	    __put_user (s.totalhigh, &info->totalhigh) || 
+	    __put_user (s.freehigh, &info->freehigh) ||
+	    __put_user (s.mem_unit, &info->mem_unit))
 		return -EFAULT;
 	return 0;
 }
@@ -2550,7 +2565,7 @@
 
 static int __init ia32_init (void)
 {
-	printk("IA32 emulation $Id: sys_ia32.c,v 1.54 2003/03/24 09:28:26 ak Exp $\n");  
+	printk("IA32 emulation $Id: sys_ia32.c,v 1.58 2003/05/09 17:21:17 ak Exp $\n");  
 	ia32_exec_domain.signal_map = default_exec_domain.signal_map;
 	ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
 	register_exec_domain(&ia32_exec_domain);
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/Makefile linux-2.4.22-pre3/arch/x86_64/kernel/Makefile
--- linux-2.4.22-pre2/arch/x86_64/kernel/Makefile	2002-11-28 15:53:12.000000000 -0800
+++ linux-2.4.22-pre3/arch/x86_64/kernel/Makefile	2003-07-05 18:09:49.000000000 -0700
@@ -20,7 +20,7 @@
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
 		pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \
-		setup64.o acpitable.o e820.o
+		setup64.o e820.o warmreboot.o
 
 ifdef CONFIG_PCI
 obj-y			+= pci-x86_64.o
@@ -37,6 +37,9 @@
 obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
 obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o
 obj-$(CONFIG_MCE) += bluesmoke.o
+obj-$(CONFIG_ACPI)		+= acpi.o
+obj-$(CONFIG_ACPI_SLEEP)	+= acpi_wakeup.o suspend.o
+ 
 
 include $(TOPDIR)/Rules.make
 
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/acpi.c linux-2.4.22-pre3/arch/x86_64/kernel/acpi.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/acpi.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/x86_64/kernel/acpi.c	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,536 @@
+/*
+ *  acpi.c - Architecture-Specific Low-Level ACPI Support
+ *
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
+ *  Copyright (C) 2001 Patrick Mochel <mochel@osdl.org>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/acpi.h>
+#include <asm/mpspec.h>
+#include <asm/io.h>
+#include <asm/apic.h>
+#include <asm/apicdef.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/io_apic.h>
+#include <asm/proto.h>
+
+
+#define PREFIX			"ACPI: "
+
+
+/* --------------------------------------------------------------------------
+                              Boot-time Configuration
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_BOOT
+
+enum acpi_irq_model_id		acpi_irq_model;
+
+
+/*
+ * Use reserved fixmap pages for physical-to-virtual mappings of ACPI tables.
+ * Note that the same range is used for each table, so tables that need to
+ * persist should be memcpy'd.
+ */
+
+extern unsigned long end_pfn; 
+
+char *
+__acpi_map_table (
+	unsigned long	phys_addr,
+	unsigned long	size)
+{
+#if 0
+	unsigned long	base = 0;
+	unsigned long	mapped_phys = phys_addr;
+	unsigned long	offset = phys_addr & (PAGE_SIZE - 1);
+	unsigned long	mapped_size = PAGE_SIZE - offset;
+	unsigned long	avail_size = mapped_size + (PAGE_SIZE * FIX_ACPI_PAGES);
+	int		idx = FIX_ACPI_BEGIN;
+#endif
+
+	//printk("__acpi_map_table at %lx size %lu\n", phys_addr, size);
+
+	if (!phys_addr || !size)
+		return NULL;
+
+	if (phys_addr < (end_pfn_map << PAGE_SHIFT)) 
+		return __va(phys_addr); 
+
+	panic("acpi mapping beyond end_pfn: %lx > %lx\n", phys_addr, end_pfn_map<<PAGE_SHIFT);
+	      
+
+#if 0
+	base = fix_to_virt(FIX_ACPI_BEGIN);
+
+	set_fixmap(idx, mapped_phys);
+
+	if (size > avail_size)
+		return NULL;
+
+	/* If the table doesn't map completely into the fist page... */
+	if (size > mapped_size) {
+		do {
+			/* Make sure we don't go past our range */
+			if (idx++ == FIX_ACPI_END)
+				return NULL;
+			mapped_phys = mapped_phys + PAGE_SIZE;
+			set_fixmap(idx, mapped_phys);
+			mapped_size = mapped_size + PAGE_SIZE;
+		} while (mapped_size < size);
+	}
+
+	return ((unsigned char *) base + offset);
+#endif
+}
+
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+int acpi_lapic;
+
+static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
+
+
+static int __init
+acpi_parse_madt (
+	unsigned long		phys_addr,
+	unsigned long		size)
+{
+	struct acpi_table_madt	*madt = NULL;
+
+	if (!phys_addr || !size)
+		return -EINVAL;
+
+	madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size);
+	if (!madt) {
+		printk(KERN_WARNING PREFIX "Unable to map MADT\n");
+		return -ENODEV;
+	}
+
+	if (madt->lapic_address)
+		acpi_lapic_addr = (u64) madt->lapic_address;
+
+	printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n",
+		madt->lapic_address);
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_lapic (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_lapic	*processor = NULL;
+
+	processor = (struct acpi_table_lapic*) header;
+	if (!processor)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	mp_register_lapic (
+		processor->id,					   /* APIC ID */
+		processor->flags.enabled);			  /* Enabled? */
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_lapic_addr_ovr (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL;
+
+	lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header;
+	if (!lapic_addr_ovr)
+		return -EINVAL;
+
+	acpi_lapic_addr = lapic_addr_ovr->address;
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_lapic_nmi (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_lapic_nmi *lapic_nmi = NULL;
+
+	lapic_nmi = (struct acpi_table_lapic_nmi*) header;
+	if (!lapic_nmi)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	if (lapic_nmi->lint != 1)
+		printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
+
+	return 0;
+}
+
+#endif /*CONFIG_X86_LOCAL_APIC*/
+
+#ifdef CONFIG_X86_IO_APIC
+
+int acpi_ioapic;
+
+static int __init
+acpi_parse_ioapic (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_ioapic *ioapic = NULL;
+
+	ioapic = (struct acpi_table_ioapic*) header;
+	if (!ioapic)
+		return -EINVAL;
+ 
+	acpi_table_print_madt_entry(header);
+
+	mp_register_ioapic (
+		ioapic->id,
+		ioapic->address,
+		ioapic->global_irq_base);
+ 
+	return 0;
+}
+
+
+static int __init
+acpi_parse_int_src_ovr (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_int_src_ovr *intsrc = NULL;
+
+	intsrc = (struct acpi_table_int_src_ovr*) header;
+	if (!intsrc)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	mp_override_legacy_irq (
+		intsrc->bus_irq,
+		intsrc->flags.polarity,
+		intsrc->flags.trigger,
+		intsrc->global_irq);
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_nmi_src (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_nmi_src *nmi_src = NULL;
+
+	nmi_src = (struct acpi_table_nmi_src*) header;
+	if (!nmi_src)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	/* TBD: Support nimsrc entries? */
+
+	return 0;
+}
+
+#endif /*CONFIG_X86_IO_APIC*/
+
+static int __init
+acpi_parse_hpet (
+	unsigned long		phys_addr,
+	unsigned long		size)
+{
+	struct acpi_table_hpet *hpet_tbl;
+
+	hpet_tbl = __va(phys_addr);
+
+	if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) {
+		printk(KERN_WARNING "acpi: HPET timers must be located in memory.\n");
+		return -1;
+	}
+
+	hpet_address = hpet_tbl->addr.addrl | ((long) hpet_tbl->addr.addrh << 32);
+
+	printk(KERN_INFO "acpi: HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet_address);
+
+	return 0;
+} 
+
+static unsigned long __init
+acpi_scan_rsdp (
+	unsigned long		start,
+	unsigned long		length)
+{
+	unsigned long		offset = 0;
+	unsigned long		sig_len = sizeof("RSD PTR ") - 1;
+
+	/*
+	 * Scan all 16-byte boundaries of the physical memory region for the
+	 * RSDP signature.
+	 */
+	for (offset = 0; offset < length; offset += 16) {
+		if (strncmp((char *) (start + offset), "RSD PTR ", sig_len))
+			continue;
+		return (start + offset);
+	}
+
+	return 0;
+}
+
+
+unsigned long __init
+acpi_find_rsdp (void)
+{
+	unsigned long		rsdp_phys = 0;
+
+	/*
+	 * Scan memory looking for the RSDP signature. First search EBDA (low
+	 * memory) paragraphs and then search upper memory (E0000-FFFFF).
+	 */
+	rsdp_phys = acpi_scan_rsdp (0, 0x400);
+	if (!rsdp_phys)
+		rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF);
+
+	return rsdp_phys;
+}
+
+
+int __init
+acpi_boot_init (void)
+	
+{
+	int			result = 0;
+
+	/*
+	 * The default interrupt routing model is PIC (8259).  This gets
+	 * overriden if IOAPICs are enumerated (below).
+	 */
+	acpi_irq_model = ACPI_IRQ_MODEL_PIC;
+
+	/* 
+	 * Initialize the ACPI boot-time table parser.
+	 */
+	result = acpi_table_init();
+	if (result)
+		return result;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+	/* 
+	 * MADT
+	 * ----
+	 * Parse the Multiple APIC Description Table (MADT), if exists.
+	 * Note that this table provides platform SMP configuration 
+	 * information -- the successor to MPS tables.
+	 */
+
+	result = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
+	if (!result) {
+		printk(KERN_WARNING PREFIX "MADT not present\n");
+		return 0;
+	}
+	else if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing MADT\n");
+		return result;
+	}
+	else if (result > 1) 
+		printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n");
+
+	/* 
+	 * Local APIC
+	 * ----------
+	 * Note that the LAPIC address is obtained from the MADT (32-bit value)
+	 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
+	 */
+
+	result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
+		return result;
+	}
+
+	mp_register_lapic_address(acpi_lapic_addr);
+
+	result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic);
+	if (!result) { 
+		printk(KERN_ERR PREFIX "No LAPIC entries present\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return -ENODEV;
+	}
+	else if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+
+	result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+
+	acpi_lapic = 1;
+
+#endif /*CONFIG_X86_LOCAL_APIC*/
+
+#ifdef CONFIG_X86_IO_APIC
+
+	/* 
+	 * I/O APIC 
+	 * --------
+	 */
+
+	result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
+	if (!result) { 
+		printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
+		return -ENODEV;
+	}
+	else if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
+		return result;
+	}
+
+	/* Build a default routing table for legacy (ISA) interrupts. */
+	mp_config_acpi_legacy_irqs();
+
+	result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+
+	result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+
+	acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
+
+	acpi_ioapic = 1;
+
+#endif /*CONFIG_X86_IO_APIC*/
+
+#ifdef CONFIG_X86_LOCAL_APIC
+	if (acpi_lapic && acpi_ioapic)
+		smp_found_config = 1;
+#endif
+	result = acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
+	if (result < 0) 
+		printk("ACPI: no HPET table found (%d).\n", result); 
+
+	return 0;
+}
+
+#endif /*CONFIG_ACPI_BOOT*/
+
+
+/* --------------------------------------------------------------------------
+                              Low-Level Sleep Support
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_SLEEP
+
+/* address in low memory of the wakeup routine. */
+unsigned long acpi_wakeup_address = 0;
+extern char wakeup_start, wakeup_end;
+
+extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
+
+static void init_low_mapping(void)
+{
+	cpu_pda[0].level4_pgt[0] = cpu_pda[0].level4_pgt[pml4_index(PAGE_OFFSET)];
+	flush_tlb_all();
+}
+
+/**
+ * acpi_save_state_mem - save kernel state
+ *
+ * Create an identity mapped page table and copy the wakeup routine to
+ * low memory.
+ */
+int acpi_save_state_mem (void)
+{
+	init_low_mapping();
+
+	memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start);
+	acpi_copy_wakeup_routine(acpi_wakeup_address);
+
+	return 0;
+}
+
+/**
+ * acpi_save_state_disk - save kernel state to disk
+ *
+ */
+int acpi_save_state_disk (void)
+{
+	return 1;
+}
+
+/*
+ * acpi_restore_state
+ */
+void acpi_restore_state_mem (void)
+{
+	cpu_pda[0].level4_pgt[0] = 0;
+	flush_tlb_all();
+}
+
+/**
+ * acpi_reserve_bootmem - do _very_ early ACPI initialisation
+ *
+ * We allocate a page in low memory for the wakeup
+ * routine for when we come back from a sleep state. The
+ * runtime allocator allows specification of <16M pages, but not
+ * <1M pages.
+ */
+void __init acpi_reserve_bootmem(void)
+{
+	acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
+	if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
+		printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
+	printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
+}
+
+#endif /*CONFIG_ACPI_SLEEP*/
+
+
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/acpi_wakeup.S linux-2.4.22-pre3/arch/x86_64/kernel/acpi_wakeup.S
--- linux-2.4.22-pre2/arch/x86_64/kernel/acpi_wakeup.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/x86_64/kernel/acpi_wakeup.S	2003-07-05 18:09:49.000000000 -0700
@@ -0,0 +1,515 @@
+.text
+#include <linux/linkage.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/msr.h>
+
+# Copyright 2003 Pavel Machek <pavel@suse.cz>, distribute under GPLv2
+#
+# wakeup_code runs in real mode, and at unknown address (determined at run-time).
+# Therefore it must only use relative jumps/calls. 
+#
+# Do we need to deal with A20? It is okay: ACPI specs says A20 must be enabled
+#
+# If physical address of wakeup_code is 0x12345, BIOS should call us with
+# cs = 0x1234, eip = 0x05
+#
+
+
+ALIGN
+	.align	16
+ENTRY(wakeup_start)
+wakeup_code:
+	wakeup_code_start = .
+	.code16
+
+# Running in *copy* of this code, somewhere in low 1MB.
+
+	movb	$0xa1, %al	;  outb %al, $0x80
+	cli
+	cld
+	# setup data segment
+	movw	%cs, %ax
+	movw	%ax, %ds					# Make ds:0 point to wakeup_start
+	movw	%ax, %ss
+	mov	$(wakeup_stack - wakeup_code), %sp		# Private stack is needed for ASUS board
+
+	pushl	$0						# Kill any dangerous flags
+	popfl
+
+	movl	real_magic - wakeup_code, %eax
+	cmpl	$0x12345678, %eax
+	jne	bogus_real_magic
+
+	lcall   $0xc000,$3
+
+ 	movw	$0xb800, %ax
+	movw	%ax,%fs
+	movw	$0x0e00 + 'L', %fs:(0x10)
+
+	movb	$0xa2, %al	;  outb %al, $0x80
+	
+	lidt	%ds:idt_48a - wakeup_code
+	xorl	%eax, %eax
+	movw	%ds, %ax			# (Convert %ds:gdt to a linear ptr)
+	shll	$4, %eax
+	addl	$(gdta - wakeup_code), %eax
+	movl	%eax, gdt_48a +2 - wakeup_code
+	lgdt	%ds:gdt_48a - wakeup_code		# load gdt with whatever is
+						# appropriate
+
+	movl	$1, %eax			# protected mode (PE) bit
+	lmsw	%ax				# This is it!
+	jmp	1f
+1:
+
+	.byte 0x66, 0xea			# prefix + jmpi-opcode
+	.long	wakeup_32 - __START_KERNEL_map
+	.word	__KERNEL_CS
+
+	.code32
+wakeup_32:
+# Running in this code, but at low address; paging is not yet turned on.
+	movb	$0xa5, %al	;  outb %al, $0x80
+
+	/* Check if extended functions are implemented */		
+	movl	$0x80000000, %eax
+	cpuid
+	cmpl	$0x80000000, %eax
+	jbe	bogus_cpu
+	wbinvd
+	mov	$0x80000001, %eax
+	cpuid
+	btl	$29, %edx
+	jnc	bogus_cpu
+	movl	%edx,%edi
+	
+	movw	$__KERNEL_DS, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+
+	movw	$__KERNEL_DS, %ax	
+	movw	%ax, %ss
+
+	mov	$(wakeup_stack - __START_KERNEL_map), %esp
+	movl	saved_magic - __START_KERNEL_map, %eax
+	cmpl	$0x9abcdef0, %eax
+	jne	bogus_32_magic
+
+	/*
+	 * Prepare for entering 64bits mode
+	 */
+
+	/* Enable PAE mode and PGE */
+	xorl	%eax, %eax
+	btsl	$5, %eax
+	btsl	$7, %eax
+	movl	%eax, %cr4
+
+	/* Setup early boot stage 4 level pagetables */
+	movl	$(wakeup_level4_pgt - __START_KERNEL_map), %eax
+	movl	%eax, %cr3
+
+	/* Setup EFER (Extended Feature Enable Register) */
+	movl	$MSR_EFER, %ecx
+	rdmsr
+	/* Fool rdmsr and reset %eax to avoid dependences */
+	xorl	%eax, %eax
+	/* Enable Long Mode */
+	btsl	$_EFER_LME, %eax
+	/* Enable System Call */
+	btsl	$_EFER_SCE, %eax
+
+	/* No Execute supported? */	
+	btl	$20,%edi
+	jnc     1f
+	btsl	$_EFER_NX, %eax
+1:	
+				
+	/* Make changes effective */
+	wrmsr
+	wbinvd
+
+	xorl	%eax, %eax
+	btsl	$31, %eax			/* Enable paging and in turn activate Long Mode */
+	btsl	$0, %eax			/* Enable protected mode */
+	btsl	$1, %eax			/* Enable MP */
+	btsl	$4, %eax			/* Enable ET */
+	btsl	$5, %eax			/* Enable NE */
+	btsl	$16, %eax			/* Enable WP */
+	btsl	$18, %eax			/* Enable AM */
+
+	/* Make changes effective */
+	movl	%eax, %cr0
+	/* At this point:
+		CR4.PAE must be 1
+		CS.L must be 0
+		CR3 must point to PML4
+		Next instruction must be a branch
+		This must be on identity-mapped page
+	*/
+	jmp	reach_compatibility_mode
+reach_compatibility_mode:
+	movw	$0x0e00 + 'i', %ds:(0xb8012)
+	movb	$0xa8, %al	;  outb %al, $0x80; 	
+		
+	/*
+	 * At this point we're in long mode but in 32bit compatibility mode
+	 * with EFER.LME = 1, CS.L = 0, CS.D = 1 (and in turn
+	 * EFER.LMA = 1). Now we want to jump in 64bit mode, to do that we load
+	 * the new gdt/idt that has __KERNEL_CS with CS.L = 1.
+	 */
+
+	movw	$0x0e00 + 'n', %ds:(0xb8014)
+	movb	$0xa9, %al	;  outb %al, $0x80
+	
+	/* Load new GDT with the 64bit segment using 32bit descriptor */
+	movl	$(pGDT32 - __START_KERNEL_map), %eax
+	lgdt	(%eax)
+
+	movl    $(wakeup_jumpvector - __START_KERNEL_map), %eax
+	/* Finally jump in 64bit mode */
+	ljmp	*(%eax)
+
+wakeup_jumpvector:
+	.long	wakeup_long64 - __START_KERNEL_map
+	.word	__KERNEL_CS
+
+.code64
+
+	/*	Hooray, we are in Long 64-bit mode (but still running in low memory) */
+wakeup_long64:
+	/*
+	 * We must switch to a new descriptor in kernel space for the GDT
+	 * because soon the kernel won't have access anymore to the userspace
+	 * addresses where we're currently running on. We have to do that here
+	 * because in 32bit we couldn't load a 64bit linear address.
+	 */
+	lgdt	pGDT64 - __START_KERNEL_map
+
+	movw	$0x0e00 + 'u', %ds:(0xb8016)
+	
+	nop
+	nop
+	movw	$__KERNEL_DS, %ax
+	movw	%ax, %ss	
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movq	saved_esp, %rsp
+
+	movw	$0x0e00 + 'x', %ds:(0xb8018)
+	movq	saved_ebx, %rbx
+	movq	saved_edi, %rdi
+	movq	saved_esi, %rsi
+	movq	saved_ebp, %rbp
+
+	movw	$0x0e00 + '!', %ds:(0xb801a)
+	movq	saved_eip, %rax
+	jmp	%rax
+
+.code32
+
+	.align	64	
+gdta:
+	.word	0, 0, 0, 0			# dummy
+
+	.word	0, 0, 0, 0			# unused
+
+	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
+	.word	0				# base address = 0
+	.word	0x9B00				# code read/exec. ??? Why I need 0x9B00 (as opposed to 0x9A00 in order for this to work?)
+	.word	0x00CF				# granularity = 4096, 386
+						#  (+5th nibble of limit)
+
+	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
+	.word	0				# base address = 0
+	.word	0x9200				# data read/write
+	.word	0x00CF				# granularity = 4096, 386
+						#  (+5th nibble of limit)
+# this is 64bit descriptor for code
+	.word	0xFFFF
+	.word	0
+	.word	0x9A00				# code read/exec
+	.word	0x00AF				# as above, but it is long mode and with D=0
+
+idt_48a:
+	.word	0				# idt limit = 0
+	.word	0, 0				# idt base = 0L
+
+gdt_48a:
+	.word	0x8000				# gdt limit=2048,
+						#  256 GDT entries
+	.word	0, 0				# gdt base (filled in later)
+	
+	
+real_save_gdt:	.word 0
+		.quad 0
+real_magic:	.quad 0
+video_mode:	.quad 0
+
+bogus_real_magic:
+	movb	$0xba,%al	;  outb %al,$0x80		
+	jmp bogus_real_magic
+
+bogus_32_magic:
+	movb	$0xb3,%al	;  outb %al,$0x80
+	jmp bogus_32_magic
+
+bogus_31_magic:
+	movb	$0xb1,%al	;  outb %al,$0x80
+	jmp bogus_31_magic
+
+bogus_cpu:
+	movb	$0xbc,%al	;  outb %al,$0x80
+	jmp bogus_cpu
+
+	
+/* This code uses an extended set of video mode numbers. These include:
+ * Aliases for standard modes
+ *	NORMAL_VGA (-1)
+ *	EXTENDED_VGA (-2)
+ *	ASK_VGA (-3)
+ * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
+ * of compatibility when extending the table. These are between 0x00 and 0xff.
+ */
+#define VIDEO_FIRST_MENU 0x0000
+
+/* Standard BIOS video modes (BIOS number + 0x0100) */
+#define VIDEO_FIRST_BIOS 0x0100
+
+/* VESA BIOS video modes (VESA number + 0x0200) */
+#define VIDEO_FIRST_VESA 0x0200
+
+/* Video7 special modes (BIOS number + 0x0900) */
+#define VIDEO_FIRST_V7 0x0900
+
+# Setting of user mode (AX=mode ID) => CF=success
+mode_seta:
+	movw	%ax, %bx
+#if 0
+	cmpb	$0xff, %ah
+	jz	setalias
+
+	testb	$VIDEO_RECALC>>8, %ah
+	jnz	_setrec
+
+	cmpb	$VIDEO_FIRST_RESOLUTION>>8, %ah
+	jnc	setres
+	
+	cmpb	$VIDEO_FIRST_SPECIAL>>8, %ah
+	jz	setspc
+
+	cmpb	$VIDEO_FIRST_V7>>8, %ah
+	jz	setv7
+#endif
+	
+	cmpb	$VIDEO_FIRST_VESA>>8, %ah
+	jnc	check_vesaa
+#if 0	
+	orb	%ah, %ah
+	jz	setmenu
+#endif
+	
+	decb	%ah
+#	jz	setbios				  Add bios modes later
+
+setbada:	clc
+	ret
+
+check_vesaa:
+	subb	$VIDEO_FIRST_VESA>>8, %bh
+	orw	$0x4000, %bx			# Use linear frame buffer
+	movw	$0x4f02, %ax			# VESA BIOS mode set call
+	int	$0x10
+	cmpw	$0x004f, %ax			# AL=4f if implemented
+	jnz	_setbada				# AH=0 if OK
+
+	stc
+	ret
+
+_setbada: jmp setbada
+
+	.code64
+bogus_magic:
+	movw	$0x0e00 + 'B', %ds:(0xb8018)
+	jmp bogus_magic
+
+bogus_magic2:
+	movw	$0x0e00 + '2', %ds:(0xb8018)
+	jmp bogus_magic2
+	
+
+wakeup_stack_begin:	# Stack grows down
+
+.org	0xff0
+wakeup_stack:		# Just below end of page
+
+ENTRY(wakeup_end)
+	
+##
+# acpi_copy_wakeup_routine
+#
+# Copy the above routine to low memory.
+#
+# Parameters:
+# %rdi:	place to copy wakeup routine to
+#
+# Returned address is location of code in low memory (past data and stack)
+#
+ENTRY(acpi_copy_wakeup_routine)
+	pushq	%rax
+	pushq	%rcx
+	pushq	%rdx
+
+	sgdt	saved_gdt
+	sidt	saved_idt
+	sldt	saved_ldt
+	str	saved_tss
+
+	movq    %cr3, %rdx
+	movq    %rdx, saved_cr3
+	movq    %cr4, %rdx
+	movq    %rdx, saved_cr4
+	movq	%cr0, %rdx
+	movq	%rdx, saved_cr0
+	sgdt    real_save_gdt - wakeup_start (,%rdi)
+	movl	$MSR_EFER, %ecx
+	rdmsr
+	movl	%eax, saved_efer
+	movl	%edx, saved_efer2
+
+#	movq	saved_videomode, %rdx				# FIXME:	 videomode
+	movq	%rdx, video_mode - wakeup_start (,%rdi)
+	movq	$0x12345678, real_magic - wakeup_start (,%rdi)
+	movq	$0x123456789abcdef0, %rdx
+	movq	%rdx, saved_magic
+
+	movl	saved_magic - __START_KERNEL_map, %eax
+	cmpl	$0x9abcdef0, %eax
+	jne	bogus_32_magic
+
+	# make sure %cr4 is set correctly (features, etc)
+	movl	saved_cr4 - __START_KERNEL_map, %eax
+	movq	%rax, %cr4
+
+	movl	saved_cr0 - __START_KERNEL_map, %eax
+	movq	%rax, %cr0
+	jmp	1f		# Flush pipelines
+1:
+	# restore the regs we used
+	popq	%rdx
+	popq	%rcx
+	popq	%rax
+ENTRY(do_suspend_lowlevel_s4bios)
+	ret
+
+	.align 2
+	.p2align 4,,15
+.globl do_suspend_lowlevel
+	.type	do_suspend_lowlevel,@function
+do_suspend_lowlevel:
+.LFB5:
+	subq	$8, %rsp
+.LCFI2:
+	testl	%edi, %edi
+	jne	.L99
+	xorl	%eax, %eax
+	call	save_processor_state
+
+	movq %rsp, saved_context_esp(%rip)
+	movq %rax, saved_context_eax(%rip)
+	movq %rbx, saved_context_ebx(%rip)
+	movq %rcx, saved_context_ecx(%rip)
+	movq %rdx, saved_context_edx(%rip)
+	movq %rbp, saved_context_ebp(%rip)
+	movq %rsi, saved_context_esi(%rip)
+	movq %rdi, saved_context_edi(%rip)
+	movq %r8,  saved_context_r08(%rip)
+	movq %r9,  saved_context_r09(%rip)
+	movq %r10, saved_context_r10(%rip)
+	movq %r11, saved_context_r11(%rip)
+	movq %r12, saved_context_r12(%rip)
+	movq %r13, saved_context_r13(%rip)
+	movq %r14, saved_context_r14(%rip)
+	movq %r15, saved_context_r15(%rip)
+	pushfq ; popq saved_context_eflags(%rip)
+
+	movq	$.L97, saved_eip(%rip)
+
+	movq %rsp,saved_esp
+	movq %rbp,saved_ebp
+	movq %rbx,saved_ebx
+	movq %rdi,saved_edi
+	movq %rsi,saved_esi
+
+	addq	$8, %rsp
+	movl	$3, %edi
+	xorl	%eax, %eax
+	jmp	acpi_enter_sleep_state
+.L97:
+	.p2align 4,,7
+.L99:
+	.align 4
+	movl	$24, %eax
+	movw %ax, %ds
+	movq	saved_context+58(%rip), %rax
+	movq %rax, %cr4
+	movq	saved_context+50(%rip), %rax
+	movq %rax, %cr3
+	movq	saved_context+42(%rip), %rax
+	movq %rax, %cr2
+	movq	saved_context+34(%rip), %rax
+	movq %rax, %cr0
+	pushq saved_context_eflags(%rip) ; popfq
+	movq saved_context_esp(%rip), %rsp
+	movq saved_context_ebp(%rip), %rbp
+	movq saved_context_eax(%rip), %rax
+	movq saved_context_ebx(%rip), %rbx
+	movq saved_context_ecx(%rip), %rcx
+	movq saved_context_edx(%rip), %rdx
+	movq saved_context_esi(%rip), %rsi
+	movq saved_context_edi(%rip), %rdi
+	movq saved_context_r08(%rip), %r8
+	movq saved_context_r09(%rip), %r9
+	movq saved_context_r10(%rip), %r10
+	movq saved_context_r11(%rip), %r11
+	movq saved_context_r12(%rip), %r12
+	movq saved_context_r13(%rip), %r13
+	movq saved_context_r14(%rip), %r14
+	movq saved_context_r15(%rip), %r15
+
+	xorl	%eax, %eax
+	addq	$8, %rsp
+	jmp	restore_processor_state
+.LFE5:
+.Lfe5:
+	.size	do_suspend_lowlevel,.Lfe5-do_suspend_lowlevel
+	
+.data
+ALIGN
+ENTRY(saved_ebp)	.quad	0
+ENTRY(saved_esi)	.quad	0
+ENTRY(saved_edi)	.quad	0
+ENTRY(saved_ebx)	.quad	0
+
+ENTRY(saved_eip)	.quad	0
+ENTRY(saved_esp)	.quad	0
+
+ENTRY(saved_magic)	.quad	0
+
+ALIGN
+# saved registers
+saved_gdt:	.quad	0,0
+saved_idt:	.quad	0,0
+saved_ldt:	.quad	0
+saved_tss:	.quad	0
+
+saved_cr0:	.quad 0
+saved_cr3:	.quad 0
+saved_cr4:	.quad 0
+saved_efer:	.quad 0
+saved_efer2:	.quad 0
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/acpitable.c linux-2.4.22-pre3/arch/x86_64/kernel/acpitable.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/acpitable.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/acpitable.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,304 +0,0 @@
-/*
- *  acpitable.c - x86-64-specific ACPI (1.0 & 2.0) boot-time initialization
- *
- *  Copyright (C) 1999 Andrew Henroid
- *  Copyright (C) 2001 Richard Schaal
- *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
- *  Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
- *  Copyright (C) 2002 Vojtech Pavlik <vojtech@suse.cz>
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/stddef.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <asm/mpspec.h>
-#include <asm/io.h>
-#include <asm/apic.h>
-#include <asm/apicdef.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/fixmap.h>
-
-#include "acpitable.h"
-
-static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT];
-
-extern unsigned long end_pfn;
-static inline int bad_ptr(void *p) 
-{ 
-	if ((unsigned long)p  >> PAGE_SHIFT >= end_pfn) 
-		return 1; 
-	return 0; 	
-} 
-
-/*
- * Checksum an ACPI table.
- */
-
-static unsigned char __init acpi_checksum(void *buffer, int length)
-{
-	unsigned char sum = 0;
-	while (length--)
-		sum += *(unsigned char *)buffer++;
-	return sum;
-}
-
-/*
- * Print an ACPI table header for debugging.
- */
-
-static char __init *acpi_kill_spaces(char *t, char *s, int m)
-{
-	int l = strnlen(s, m);
-	strncpy(t, s, m);
-	t[l] = 0;
-	while (l > 0 && (t[l - 1] == ' ' || t[l - 1] == '\t')) t[--l] = 0;
-	while (t[0] == ' ' || t[0] == '\t') t++;
-	return t;
-}
-
-static void __init acpi_print_table_header(struct acpi_table_header * header)
-{
-	char oem[7], id[9];
-
-	printk(KERN_INFO "acpi: %.4s rev: %d oem: %s id: %s build: %d.%d\n",
-		header->signature, header->revision, acpi_kill_spaces(oem, header->oem_id, 6),
-		acpi_kill_spaces(id, header->oem_table_id, 8), header->oem_revision >> 16,
-		header->oem_revision & 0xffff);
-}
-
-/*
- * Search a block of memory for the RSDP signature
- */
-
-static void* __init acpi_tb_scan_memory_for_rsdp(void *address, int length)
-{
-	u32 offset = 0;
-
-	while (offset < length) {
-		if (strncmp(address, "RSD PTR ", 8) == 0 &&
-		    acpi_checksum(address, RSDP_CHECKSUM_LENGTH) == 0) {
-			printk(KERN_INFO "acpi: RSDP found at address %p\n", address);
-			return address;
-		}
-		offset += RSDP_SCAN_STEP;
-		address += RSDP_SCAN_STEP;
-	}
-	return NULL;
-}
-
-/*
- * Search lower 1_mbyte of memory for the root system descriptor
- * pointer structure. If it is found, set *RSDP to point to it.
- */
-
-static struct acpi_table_rsdp* __init acpi_find_root_pointer(void)
-{
-	struct acpi_table_rsdp *rsdp;
-
-	if ((rsdp = acpi_tb_scan_memory_for_rsdp(__va(LO_RSDP_WINDOW_BASE), LO_RSDP_WINDOW_SIZE)))
-		return rsdp;
-
-	if ((rsdp = acpi_tb_scan_memory_for_rsdp(__va(HI_RSDP_WINDOW_BASE), HI_RSDP_WINDOW_SIZE)))
-		return rsdp;
-
-	return NULL;
-}
-
-static int __init acpi_process_table(u64 table)
-{
-	struct acpi_table_header *header;
-	int type;
-
-	header = __va(table);
-
-	acpi_print_table_header(header);
-
-	if (acpi_checksum(header, header->length)) {
-		printk(KERN_WARNING "acpi: ACPI table at %#lx has invalid checksum.\n", table);
-		return -1;
-	}
-
-	for (type = 0; type < ACPI_TABLE_COUNT; type++)
-		if (!strncmp(header->signature, acpi_table_signatures[type], 4))
-			break;
-
-	if (type == ACPI_TABLE_COUNT || !acpi_boot_ops[type])
-		return 0;
-
-	return acpi_boot_ops[type](header, table);
-}
-
-static int __init acpi_tables_init(void)
-{
-	struct acpi_table_rsdp *rsdp;
-	struct acpi_table_xsdt *xsdt = NULL;
-	struct acpi_table_rsdt *rsdt = NULL;
-	char oem[7];
-	int i;
-
-	if (!(rsdp = acpi_find_root_pointer())) {
-		printk(KERN_ERR "acpi: Couldn't find ACPI root pointer!\n");
-		return -1;
-	}
-
-	printk(KERN_INFO "acpi: RSDP rev: %d oem: %s\n",
-		rsdp->revision, acpi_kill_spaces(oem, rsdp->oem_id, 6));
-
-	if (!acpi_checksum(rsdp, RSDP2_CHECKSUM_LENGTH)
-		&& rsdp->length >= RSDP2_CHECKSUM_LENGTH) {	/* ACPI 2.0 might be present */
-		xsdt = __va(rsdp->xsdt_address);
-		if (bad_ptr(xsdt))
-			return -1; 
-		if (!strncmp(xsdt->header.signature, "XSDT", 4)) {
-			acpi_print_table_header(&xsdt->header);
-			for (i = 0; i < (xsdt->header.length - sizeof(struct acpi_table_header)) / sizeof(u64); i++)
-				if (acpi_process_table(xsdt->entry[i]))
-					return -1;
-			return 0;
-		}
-	}
-
-	rsdt = __va(rsdp->rsdt_address);
-	if (bad_ptr(rsdt))
-		return -1;
-	if (!strncmp(rsdt->header.signature, "RSDT", 4)) {
-		acpi_print_table_header(&rsdt->header);
-		for (i = 0; i < (rsdt->header.length - sizeof(struct acpi_table_header)) / sizeof(u32); i++)
-			if (acpi_process_table(rsdt->entry[i]))
-				return -1;
-		return 0;
-	}
-
-	printk(KERN_WARNING "acpi: No ACPI table directory found.\n");
-	return -1;
-}
-
-static void __init acpi_parse_lapic(struct acpi_table_lapic *local_apic)
-{
-	printk(KERN_INFO "acpi: LAPIC acpi_id: %d id: %d enabled: %d\n",
-		local_apic->acpi_id, local_apic->id, local_apic->flags.enabled);
-}
-
-static void __init acpi_parse_ioapic(struct acpi_table_ioapic *ioapic)
-{
-	printk(KERN_INFO "acpi: IOAPIC id: %d address: %#x global_irq_base: %#x\n",
-		ioapic->id, ioapic->address, ioapic->global_irq_base);
-}
-
-static void __init acpi_parse_int_src_ovr(struct acpi_table_int_src_ovr *intsrc)
-{
-	printk(KERN_INFO "acpi: INT_SRC_OVR bus: %d irq: %d global_irq: %d polarity: %d trigger: %d\n",
-		intsrc->bus, intsrc->bus_irq, intsrc->global_irq, intsrc->flags.polarity, intsrc->flags.trigger);
-}
-
-static void __init acpi_parse_nmi_src(struct acpi_table_nmi_src *nmisrc)
-{
-	printk(KERN_INFO "acpi: NMI_SRC polarity: %d trigger: %d global_irq: %d\n",
-		nmisrc->flags.polarity, nmisrc->flags.trigger, nmisrc->global_irq);
-}
-
-static void __init acpi_parse_lapic_nmi(struct acpi_table_lapic_nmi *localnmi)
-{
-	printk(KERN_INFO "acpi: LAPIC_NMI acpi_id: %d polarity: %d trigger: %d lint: %d\n",
-		localnmi->acpi_id, localnmi->flags.polarity, localnmi->flags.trigger, localnmi->lint);
-}
-
-static void __init acpi_parse_lapic_addr_ovr(struct acpi_table_lapic_addr_ovr *lapic_addr_ovr)
-{
-	printk(KERN_INFO "acpi: LAPIC_ADDR_OVR address: %#lx\n",
-		(unsigned long) lapic_addr_ovr->address);
-}
-
-static void __init acpi_parse_plat_int_src(struct acpi_table_plat_int_src *plintsrc)
-{
-	printk(KERN_INFO "acpi: PLAT_INT_SRC polarity: %d trigger: %d type: %d id: %d eid: %d iosapic_vector: %#x global_irq: %d\n",
-		plintsrc->flags.polarity, plintsrc->flags.trigger, plintsrc->type, plintsrc->id, plintsrc->eid,
-		plintsrc->iosapic_vector, plintsrc->global_irq);
-}
-
-static int __init acpi_parse_madt(struct acpi_table_header *header, unsigned long phys)
-{
-
-	struct acpi_table_madt *madt;
-	struct acpi_madt_entry_header *entry_header;
-	int table_size;
-
-	madt = __va(phys);
-	table_size = header->length - sizeof(*madt);
-	entry_header = (void *)madt + sizeof(*madt);
-
-	while (entry_header && table_size > 0) {
-
-		switch (entry_header->type) {
-			case ACPI_MADT_LAPIC:
-				acpi_parse_lapic((void *) entry_header);
-				break;
-			case ACPI_MADT_IOAPIC:
-				acpi_parse_ioapic((void *) entry_header);
-				break;
-			case ACPI_MADT_INT_SRC_OVR:
-				acpi_parse_int_src_ovr((void *) entry_header);
-				break;
-			case ACPI_MADT_NMI_SRC:
-				acpi_parse_nmi_src((void *) entry_header);
-				break;
-			case ACPI_MADT_LAPIC_NMI:
-				acpi_parse_lapic_nmi((void *) entry_header);
-				break;
-			case ACPI_MADT_LAPIC_ADDR_OVR:
-				acpi_parse_lapic_addr_ovr((void *) entry_header);
-				break;
-			case ACPI_MADT_PLAT_INT_SRC:
-				acpi_parse_plat_int_src((void *) entry_header);
-				break;
-			default:
-				printk(KERN_WARNING "acpi: Unsupported MADT entry type 0x%x\n", entry_header->type);
-				break;
-		}
-
-		table_size -= entry_header->length;
-		entry_header = (void *) entry_header + entry_header->length;
-	}
-
-	printk(KERN_INFO "acpi: Local APIC address %#x\n", madt->lapic_address);
-
-	return 0;
-}
-
-static int __init acpi_parse_hpet(struct acpi_table_header *header, unsigned long phys)
-{
-	struct acpi_table_hpet *hpet_tbl;
-
-	hpet_tbl = __va(phys);
-
-	if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) {
-		printk(KERN_WARNING "acpi: HPET timers must be located in memory.\n");
-		return -1;
-	}
-
-	hpet_address = hpet_tbl->addr.addrl | ((long) hpet_tbl->addr.addrh << 32);
-
-	printk(KERN_INFO "acpi: HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet_address);
-
-	return 0;
-}
-
-/*
- * Configure the processor info using MADT in the ACPI tables. If we fail to
- * configure that, then we use the MPS tables.
- */
-
-void __init config_acpi_tables(void)
-{
-	acpi_boot_ops[ACPI_APIC] = acpi_parse_madt;
-	acpi_boot_ops[ACPI_HPET] = acpi_parse_hpet;
-
-	if (acpi_tables_init())
-		printk(KERN_ERR "acpi: Init failed.\n");
-}
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/apic.c linux-2.4.22-pre3/arch/x86_64/kernel/apic.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/apic.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/apic.c	2003-07-05 18:09:49.000000000 -0700
@@ -591,52 +591,14 @@
 
 static int __init detect_init_APIC (void)
 {
-	u32 h, l, features;
-	extern void get_cpu_vendor(struct cpuinfo_x86*);
-
 	/* Disabled by DMI scan or kernel option? */
 	if (dont_enable_local_apic)
 		return -1;
 
-	/* Workaround for us being called before identify_cpu(). */
-	get_cpu_vendor(&boot_cpu_data);
-
-	switch (boot_cpu_data.x86_vendor) {
-	case X86_VENDOR_AMD:
-		if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1)
-			break;
-		goto no_apic;
-	case X86_VENDOR_INTEL:
-		if (boot_cpu_data.x86 == 6 ||
-		    (boot_cpu_data.x86 == 15 && cpu_has_apic) ||
-		    (boot_cpu_data.x86 == 5 && cpu_has_apic))
-			break;
-		goto no_apic;
-	default:
-		goto no_apic;
-	}
-
+	/* Don't force the APIC if the BIOS didn't enable it. Usually
+	   it is broken in some way. */
 	if (!cpu_has_apic) {
-		/*
-		 * Some BIOSes disable the local APIC in the
-		 * APIC_BASE MSR. This can only be done in
-		 * software for Intel P6 and AMD K7 (Model > 1).
-		 */
-		rdmsr(MSR_IA32_APICBASE, l, h);
-		if (!(l & MSR_IA32_APICBASE_ENABLE)) {
-			printk("Local APIC disabled by BIOS -- reenabling.\n");
-			l &= ~MSR_IA32_APICBASE_BASE;
-			l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
-			wrmsr(MSR_IA32_APICBASE, l, h);
-		}
-	}
-	/*
-	 * The APIC feature bit should now be enabled
-	 * in `cpuid'
-	 */
-	features = cpuid_edx(1);
-	if (!(features & (1 << X86_FEATURE_APIC))) {
-		printk("Could not enable APIC!\n");
+		printk(KERN_INFO "APIC disabled by BIOS.\n");
 		return -1;
 	}
 	set_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability);
@@ -645,15 +607,11 @@
 	if (nmi_watchdog != NMI_NONE)
 		nmi_watchdog = NMI_LOCAL_APIC;
 
-	printk("Found and enabled local APIC!\n");
+	printk(KERN_INFO "Found and enabled local APIC!\n");
 
 	apic_pm_init1();
 
 	return 0;
-
-no_apic:
-	printk("No local APIC present or hardware disabled\n");
-	return -1;
 }
 
 void __init init_apic_mappings(void)
@@ -1065,7 +1023,11 @@
  */
 int __init APIC_init_uniprocessor (void)
 {
-	if (!smp_found_config && !cpu_has_apic) { 
+	if (apic_disabled) 
+		clear_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability); 
+
+	if (!cpu_has_apic) { 
+		printk("No APIC available.\n"); 
 		apic_disabled = 1;
 		return -1;
 	} 
@@ -1103,3 +1065,11 @@
 
 	return 0;
 }
+
+static int disable_local_apic(char *s) 
+{
+	apic_disabled = 1;
+	return 0;
+}
+__setup("nolocalapic", disable_local_apic); 
+
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/bluesmoke.c linux-2.4.22-pre3/arch/x86_64/kernel/bluesmoke.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/bluesmoke.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/bluesmoke.c	2003-07-05 18:09:49.000000000 -0700
@@ -125,6 +125,67 @@
 	return NULL;
 }
 
+static char *transaction[] = { 
+	"instruction", "data", "generic", "reserved"
+}; 
+static char *cachelevel[] = { 
+	"level 0", "level 1", "level 2", "level generic"
+};
+static char *memtrans[] = { 
+	"generic error", "generic read", "generic write", "data read",
+	"data write", "instruction fetch", "prefetch", "snoop",
+	"?", "?", "?", "?", "?", "?", "?"
+};
+static char *partproc[] = { 
+	"local node origin", "local node response", 
+	"local node observed", "generic" 
+};
+static char *timeout[] = { 
+	"request didn't time out",
+	"request timed out"
+};
+static char *memoryio[] = { 
+	"memory access", "res.", "i/o access", "generic"
+}; 
+static char *extendederr[] = { 
+	"ecc error", 
+	"crc error",
+	"sync error",
+	"mst abort",
+	"tgt abort",
+	"gart error",
+	"rmw error",
+	"wdog error",
+	"chipkill ecc error", 
+	"<9>","<10>","<11>","<12>",
+	"<13>","<14>","<15>"
+}; 
+static char *highbits[32] = { 
+	[31] = "previous error lost", 
+	[30] = "error overflow",
+	[29] = "error uncorrected",
+	[28] = "error enable",
+	[27] = "misc error valid",
+	[26] = "error address valid", 
+	[25] = "processor context corrupt", 
+	[24] = "res24",
+	[23] = "res23",
+	/* 22-15 ecc syndrome bits */
+	[14] = "corrected ecc error",
+	[13] = "uncorrected ecc error",
+	[12] = "res12",
+	[11] = "res11",
+	[10] = "res10",
+	[9] = "res9",
+	[8] = "dram scrub error", 
+	[7] = "res7",
+	/* 6-4 ht link number of error */ 
+	[3] = "res3",
+	[2] = "res2",
+	[1] = "err cpu0",
+	[0] = "err cpu1",
+};
+
 static void check_k8_nb(void)
 {
 	struct pci_dev *nb;
@@ -139,20 +200,52 @@
 		return;
 	printk(KERN_ERR "Northbridge status %08x%08x\n",
 	       statushigh,statuslow); 
-	if (statuslow & 0x10) 
-		printk(KERN_ERR "GART error %d\n", statuslow & 0xf); 
-	if (statushigh & (1<<31))
-		printk(KERN_ERR "Lost an northbridge error\n"); 
-	if (statushigh & (1<<25))
-		printk(KERN_EMERG "NB status: unrecoverable\n"); 
+
+	unsigned short errcode = statuslow & 0xffff;	
+	switch (errcode >> 8) { 
+	case 0: 					
+		printk(KERN_ERR "    GART TLB error %s %s\n", 
+		       transaction[(errcode >> 2) & 3], 
+		       cachelevel[errcode & 3]);
+		break;
+	case 1: 
+		if (errcode & (1<<11)) { 
+			printk(KERN_ERR "    bus error %s %s %s %s %s\n",
+			       partproc[(errcode >> 10) & 0x3],
+			       timeout[(errcode >> 9) & 1],
+			       memtrans[(errcode >> 4) & 0xf],
+			       memoryio[(errcode >> 2) & 0x3], 
+			       cachelevel[(errcode & 0x3)]); 
+		} else if (errcode & (1<<8)) { 
+			printk(KERN_ERR "    memory error %s %s %s\n",
+			       memtrans[(errcode >> 4) & 0xf],
+			       transaction[(errcode >> 2) & 0x3],
+			       cachelevel[(errcode & 0x3)]);
+		} else {
+			printk(KERN_ERR "    unknown error code %x\n", errcode); 
+		}
+		break;
+	} 
+	if (statushigh & ((1<<14)|(1<<13)))
+		printk(KERN_ERR "    ECC syndrome bits %x\n", 
+		       (((statuslow >> 24) & 0xff)  << 8) | ((statushigh >> 15) & 0x7f));
+	errcode = (statuslow >> 16) & 0xf;
+	printk(KERN_ERR "    extended error %s\n", extendederr[(statuslow >> 16) & 0xf]); 
+	
+	/* should only print when it was a HyperTransport related error. */
+	printk(KERN_ERR "    link number %x\n", (statushigh >> 4) & 3);
+
+	int i;
+	for (i = 0; i < 32; i++) 
+		if (highbits[i] && (statushigh & (1<<i)))
+			printk(KERN_ERR "    %s\n", highbits[i]); 
+
 	if (statushigh & (1<<26)) { 
 		u32 addrhigh, addrlow; 
 		pci_read_config_dword(nb, 0x54, &addrhigh); 
 		pci_read_config_dword(nb, 0x50, &addrlow); 
-		printk(KERN_ERR "NB error address %08x%08x\n", addrhigh,addrlow); 
+		printk(KERN_ERR "    error address %08x%08x\n", addrhigh,addrlow); 
 	}
-	if (statushigh & (1<<29))
-		printk(KERN_EMERG "Error uncorrected\n"); 
 	statushigh &= ~(1<<31); 
 	pci_write_config_dword(nb, 0x4c, statushigh); 		
 }
@@ -256,22 +349,12 @@
 	machine_check_vector = k8_machine_check; 
 	for (i = 0; i < banks; i++) { 
 		u64 val = ((1UL<<i) & disabled_banks) ? 0 : ~0UL; 
+		if (val && i == 4)
+			val = k8_nb_flags;
 		wrmsrl(MSR_IA32_MC0_CTL+4*i, val);
 		wrmsrl(MSR_IA32_MC0_STATUS+4*i,0); 
 	}
 
-	nb = find_k8_nb(); 
-	if (nb != NULL) {
-		u32 reg, reg2;
-		pci_read_config_dword(nb, 0x40, &reg); 
-		pci_write_config_dword(nb, 0x40, k8_nb_flags);
-		pci_read_config_dword(nb, 0x44, &reg2);
-		pci_write_config_dword(nb, 0x44, reg2); 
-		printk(KERN_INFO "Machine Check for K8 Northbridge %d enabled (%x,%x)\n",
-		       nb->devfn, reg, reg2);
-		ignored_banks |= (1UL<<4); 
-	} 
-
 	set_in_cr4(X86_CR4_MCE);	   	
 
 	if (mcheck_interval && (smp_processor_id() == 0)) { 
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/e820.c linux-2.4.22-pre3/arch/x86_64/kernel/e820.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/e820.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/e820.c	2003-07-05 18:09:49.000000000 -0700
@@ -500,6 +500,7 @@
 extern char command_line[], saved_command_line[];
 extern int fallback_aper_order;
 extern int iommu_setup(char *opt);
+extern int acpi_disabled;
 
 void __init parse_mem_cmdline (char ** cmdline_p)
 {
@@ -537,8 +538,10 @@
 		else if (!memcmp(from,"iommu=",6)) { 
 			iommu_setup(from+6); 
 		} 	
-		
 #endif
+ 		else if (!memcmp(from, "acpi=off", 8))
+  			acpi_disabled = 1;
+		
 	next:
 		c = *(from++);
 		if (!c)
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/head.S linux-2.4.22-pre3/arch/x86_64/kernel/head.S
--- linux-2.4.22-pre2/arch/x86_64/kernel/head.S	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/head.S	2003-07-05 18:09:49.000000000 -0700
@@ -6,7 +6,7 @@
  *  Copyright (C) 2000 Karsten Keil <kkeil@suse.de>
  *  Copyright (C) 2001,2002 Andi Kleen <ak@suse.de>
  *
- *  $Id: head.S,v 1.55 2003/02/11 12:29:15 ak Exp $
+ *  $Id: head.S,v 1.56 2003/05/12 14:38:43 ak Exp $
  */
 
 
@@ -198,6 +198,7 @@
 1:
 	jmp	1b	
 	
+	.globl pGDT32	
 .org 0xf00
 pGDT32:
 	.word	gdt32_end-gdt_table32
@@ -312,10 +313,19 @@
 	.quad	0x0000000000105007		/* -> level2_kernel_pgt (so that __va works even before pagetable_init) */
 
 .org 0xb000
+ENTRY(wakeup_level4_pgt)
+        .quad   0x0000000000102007              /* -> level3_ident_pgt */
+        .fill   255,8,0
+        .quad   0x000000000010a007
+        .fill   254,8,0
+        /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
+        .quad   0x0000000000103007              /* -> level3_kernel_pgt */
+
 .data
 
 .globl SYMBOL_NAME(gdt)
 
+	.globl pGDT64
 	.word 0
 	.align 16
 	.word 0
@@ -340,7 +350,7 @@
 .align 64 /* cacheline aligned, keep this synchronized with asm/desc.h */
 ENTRY(gdt_table)
 	.quad	0x0000000000000000	/* This one is magic */
-	.quad	0x0000000000000000	/* unused */
+	.quad	0x00af9a000000ffff ^ (1<<21)	/* __KERNEL_COMPAT32_CS */	
 	.quad	0x00af9a000000ffff	/* __KERNEL_CS */
 	.quad	0x00cf92000000ffff	/* __KERNEL_DS */
 	.quad	0x00cffe000000ffff	/* __USER32_CS */
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/io_apic.c linux-2.4.22-pre3/arch/x86_64/kernel/io_apic.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/io_apic.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/io_apic.c	2003-07-05 18:09:49.000000000 -0700
@@ -17,6 +17,7 @@
  *					thanks to Eric Gilmore
  *					and Rolf G. Tews
  *					for testing these extensively
+ *	Paul Diefenbaugh	:	Added full ACPI support
  */
 
 #include <linux/mm.h>
@@ -28,6 +29,7 @@
 #include <linux/config.h>
 #include <linux/smp_lock.h>
 #include <linux/mc146818rtc.h>
+#include <linux/acpi.h>
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -1046,6 +1048,10 @@
 	unsigned char old_id;
 	unsigned long flags;
 
+ 	if (acpi_ioapic)
+ 		/* This gets done during IOAPIC enumeration for ACPI. */
+ 		return;
+
 	/*
 	 * Set the IOAPIC ID to the value stored in the MPC table.
 	 */
@@ -1641,8 +1647,7 @@
 	printk("ENABLING IO-APIC IRQs\n");
 
 	/*
-	 * Set up the IO-APIC IRQ routing table by parsing the MP-BIOS
-	 * mptable:
+	 * Set up IO-APIC IRQ routing.
 	 */
 	setup_ioapic_ids_from_mpc();
 	sync_Arb_IDs();
@@ -1651,3 +1656,159 @@
 	check_timer();
 	print_IO_APIC();
 }
+
+
+/* --------------------------------------------------------------------------
+                          ACPI-based IOAPIC Configuration
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_BOOT
+
+#define IO_APIC_MAX_ID		15
+
+int __init io_apic_get_unique_id (int ioapic, int apic_id)
+{
+	struct IO_APIC_reg_00 reg_00;
+	static unsigned long apic_id_map = 0;
+	unsigned long flags;
+	int i = 0;
+
+	/*
+	 * The P4 platform supports up to 256 APIC IDs on two separate APIC 
+	 * buses (one for LAPICs, one for IOAPICs), where predecessors only 
+	 * supports up to 16 on one shared APIC bus.
+	 * 
+	 * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
+	 *      advantage of new APIC bus architecture.
+	 */
+
+	if (!apic_id_map)
+		apic_id_map = phys_cpu_present_map;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	*(int *)&reg_00 = io_apic_read(ioapic, 0);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	if (apic_id >= IO_APIC_MAX_ID) {
+		printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
+			"%d\n", ioapic, apic_id, reg_00.ID);
+		apic_id = reg_00.ID;
+	}
+
+	/*
+	 * Every APIC in a system must have a unique ID or we get lots of nice 
+	 * 'stuck on smp_invalidate_needed IPI wait' messages.
+	 */
+	if (apic_id_map & (1 << apic_id)) {
+
+		for (i = 0; i < IO_APIC_MAX_ID; i++) {
+			if (!(apic_id_map & (1 << i)))
+				break;
+		}
+
+		if (i == IO_APIC_MAX_ID)
+			panic("Max apic_id exceeded!\n");
+
+		printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
+			"trying %d\n", ioapic, apic_id, i);
+
+		apic_id = i;
+	} 
+
+	apic_id_map |= (1 << apic_id);
+
+	if (reg_00.ID != apic_id) {
+		reg_00.ID = apic_id;
+
+		spin_lock_irqsave(&ioapic_lock, flags);
+		io_apic_write(ioapic, 0, *(int *)&reg_00);
+		*(int *)&reg_00 = io_apic_read(ioapic, 0);
+		spin_unlock_irqrestore(&ioapic_lock, flags);
+
+		/* Sanity check */
+		if (reg_00.ID != apic_id)
+			panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic);
+	}
+
+	printk(KERN_INFO "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
+
+	return apic_id;
+}
+
+
+int __init io_apic_get_version (int ioapic)
+{
+	struct IO_APIC_reg_01	reg_01;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	*(int *)&reg_01 = io_apic_read(ioapic, 1);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return reg_01.version;
+}
+
+
+int __init io_apic_get_redir_entries (int ioapic)
+{
+	struct IO_APIC_reg_01	reg_01;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	*(int *)&reg_01 = io_apic_read(ioapic, 1);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return reg_01.entries;
+}
+
+
+int io_apic_set_pci_routing (int ioapic, int pin, int irq)
+{
+	struct IO_APIC_route_entry entry;
+	unsigned long flags;
+
+	if (!IO_APIC_IRQ(irq)) {
+		printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0/n", 
+			ioapic);
+		return -EINVAL;
+	}
+
+	/*
+	 * Generate a PCI IRQ routing entry and program the IOAPIC accordingly.
+	 * Note that we mask (disable) IRQs now -- these get enabled when the
+	 * corresponding device driver registers for this IRQ.
+	 */
+
+	memset(&entry,0,sizeof(entry));
+
+	entry.delivery_mode = dest_LowestPrio;
+	entry.dest_mode = INT_DELIVERY_MODE;
+	entry.dest.logical.logical_dest = TARGET_CPUS;
+	entry.mask = 1;					 /* Disabled (masked) */
+	entry.trigger = 1;				   /* Level sensitive */
+	entry.polarity = 1;					/* Low active */
+
+	add_pin_to_irq(irq, ioapic, pin);
+
+	entry.vector = assign_irq_vector(irq);
+
+	printk(KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> "
+		"IRQ %d)\n", ioapic, 
+		mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq);
+
+	irq_desc[irq].handler = &ioapic_level_irq_type;
+
+	set_intr_gate(entry.vector, interrupt[irq]);
+
+	if (!ioapic && (irq < 16))
+		disable_8259A_irq(irq);
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1));
+	io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0));
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return entry.vector;
+}
+
+#endif /*CONFIG_ACPI_BOOT*/
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/mpparse.c linux-2.4.22-pre3/arch/x86_64/kernel/mpparse.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/mpparse.c	2002-11-28 15:53:12.000000000 -0800
+++ linux-2.4.22-pre3/arch/x86_64/kernel/mpparse.c	2003-07-05 18:09:49.000000000 -0700
@@ -9,12 +9,14 @@
  *		Erich Boleyn	:	MP v1.4 and additional changes.
  *		Alan Cox	:	Added EBDA scanning
  *		Ingo Molnar	:	various cleanups and rewrites
- *	Maciej W. Rozycki	:	Bits for default MP configurations
+ *		Maciej W. Rozycki:	Bits for default MP configurations
+ *		Paul Diefenbaugh:	Added full ACPI support
  */
 
 #include <linux/mm.h>
 #include <linux/irq.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/config.h>
 #include <linux/bootmem.h>
@@ -23,11 +25,13 @@
 #include <linux/mc146818rtc.h>
 
 #include <asm/smp.h>
+#include <asm/acpi.h>
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
 #include <asm/pgalloc.h>
 #include <asm/e820.h>
 #include <asm/proto.h>
+#include <asm/io_apic.h>
 
 /* Have we found an MP table */
 int smp_found_config = 0;
@@ -249,7 +253,11 @@
 
 	printk("APIC at: 0x%X\n",mpc->mpc_lapic);
 
-	/* save the local APIC address, it might be non-default */
+ 	/* 
+ 	 * Save the local APIC address (it might be non-default) -- but only
+ 	 * if we're not using ACPI.
+  	 */
+	if (!acpi_lapic)
 	mp_lapic_addr = mpc->mpc_lapic;
 
 	/*
@@ -261,6 +269,8 @@
 			{
 				struct mpc_config_processor *m=
 					(struct mpc_config_processor *)mpt;
+ 				/* ACPI may have already provided this data */
+				if (!acpi_lapic) 
 				MP_processor_info(m);
 				mpt += sizeof(*m);
 				count += sizeof(*m);
@@ -475,6 +485,19 @@
 void __init get_smp_config (void)
 {
 	struct intel_mp_floating *mpf = mpf_found;
+ 	/*
+ 	 * ACPI may be used to obtain the entire SMP configuration or just to 
+ 	 * enumerate/configure processors (CONFIG_ACPI_HT_ONLY).  Note that 
+ 	 * ACPI supports both logical (e.g. Hyper-Threading) and physical 
+ 	 * processors, where MPS only supports physical.
+ 	 */
+ 	if (acpi_lapic && acpi_ioapic) {
+ 		printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n");
+ 		return;
+ 	}
+ 	else if (acpi_lapic)
+ 		printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n");
+ 
 	printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
 	if (mpf->mpf_feature2 & (1<<7)) {
 		printk("    IMCR and PIC compatibility mode.\n");
@@ -614,3 +637,368 @@
 #endif
 }
 
+
+/* --------------------------------------------------------------------------
+                            ACPI-based MP Configuration
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_BOOT
+
+void __init mp_register_lapic_address (
+	u64			address)
+{
+	mp_lapic_addr = (unsigned long) address;
+
+	set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
+
+	if (boot_cpu_id == -1U)
+		boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID));
+
+	Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid);
+}
+
+
+void __init mp_register_lapic (
+	u8			id, 
+	u8			enabled)
+{
+	struct mpc_config_processor processor;
+	int			boot_cpu = 0;
+	
+	if (id >= MAX_APICS) {
+		printk(KERN_WARNING "Processor #%d invalid (max %d)\n",
+			id, MAX_APICS);
+		return;
+	}
+
+	if (id == boot_cpu_physical_apicid)
+		boot_cpu = 1;
+
+	processor.mpc_type = MP_PROCESSOR;
+	processor.mpc_apicid = id;
+	processor.mpc_apicver = 0x10; /* TBD: lapic version */
+	processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0);
+	processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0);
+	processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | 
+		(boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask;
+	processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
+	processor.mpc_reserved[0] = 0;
+	processor.mpc_reserved[1] = 0;
+
+	MP_processor_info(&processor);
+}
+
+#ifdef CONFIG_X86_IO_APIC
+
+#define MP_ISA_BUS		0
+#define MP_MAX_IOAPIC_PIN	127
+
+struct mp_ioapic_routing {
+	int			apic_id;
+	int			irq_start;
+	int			irq_end;
+	u32			pin_programmed[4];
+} mp_ioapic_routing[MAX_IO_APICS];
+
+
+static int __init mp_find_ioapic (
+	int			irq)
+{
+	int			i = 0;
+
+	/* Find the IOAPIC that manages this IRQ. */
+	for (i = 0; i < nr_ioapics; i++) {
+		if ((irq >= mp_ioapic_routing[i].irq_start)
+			&& (irq <= mp_ioapic_routing[i].irq_end))
+			return i;
+	}
+
+	printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d/n", irq);
+
+	return -1;
+}
+	
+
+void __init mp_register_ioapic (
+	u8			id, 
+	u32			address,
+	u32			irq_base)
+{
+	int			idx = 0;
+
+	if (nr_ioapics >= MAX_IO_APICS) {
+		printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
+			"(found %d)\n", MAX_IO_APICS, nr_ioapics);
+		panic("Recompile kernel with bigger MAX_IO_APICS!\n");
+	}
+	if (!address) {
+		printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
+			" found in MADT table, skipping!\n");
+		return;
+	}
+
+	idx = nr_ioapics++;
+
+	mp_ioapics[idx].mpc_type = MP_IOAPIC;
+	mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE;
+	mp_ioapics[idx].mpc_apicaddr = address;
+
+	set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
+	mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
+	mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
+	
+	/* 
+	 * Build basic IRQ lookup table to facilitate irq->io_apic lookups
+	 * and to prevent reprogramming of IOAPIC pins (PCI IRQs).
+	 */
+	mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid;
+	mp_ioapic_routing[idx].irq_start = irq_base;
+	mp_ioapic_routing[idx].irq_end = irq_base + 
+		io_apic_get_redir_entries(idx);
+
+	printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
+		"IRQ %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, 
+		mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
+		mp_ioapic_routing[idx].irq_start,
+		mp_ioapic_routing[idx].irq_end);
+
+	return;
+}
+
+
+void __init mp_override_legacy_irq (
+	u8			bus_irq,
+	u8			polarity, 
+	u8			trigger, 
+	u32			global_irq)
+{
+	struct mpc_config_intsrc intsrc;
+	int			i = 0;
+	int			found = 0;
+	int			ioapic = -1;
+	int			pin = -1;
+
+	/* 
+	 * Convert 'global_irq' to 'ioapic.pin'.
+	 */
+	ioapic = mp_find_ioapic(global_irq);
+	if (ioapic < 0)
+		return;
+	pin = global_irq - mp_ioapic_routing[ioapic].irq_start;
+
+	/*
+	 * TBD: This check is for faulty timer entries, where the override
+	 *      erroneously sets the trigger to level, resulting in a HUGE 
+	 *      increase of timer interrupts!
+	 */
+	if ((bus_irq == 0) && (global_irq == 2) && (trigger == 3))
+		trigger = 1;
+
+	intsrc.mpc_type = MP_INTSRC;
+	intsrc.mpc_irqtype = mp_INT;
+	intsrc.mpc_irqflag = (trigger << 2) | polarity;
+	intsrc.mpc_srcbus = MP_ISA_BUS;
+	intsrc.mpc_srcbusirq = bus_irq;				       /* IRQ */
+	intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid;	   /* APIC ID */
+	intsrc.mpc_dstirq = pin;				    /* INTIN# */
+
+	Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n", 
+		intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, 
+		(intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 
+		intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq);
+
+	/* 
+	 * If an existing [IOAPIC.PIN -> IRQ] routing entry exists we override it.
+	 * Otherwise create a new entry (e.g. global_irq == 2).
+	 */
+	for (i = 0; i < mp_irq_entries; i++) {
+		if ((mp_irqs[i].mpc_dstapic == intsrc.mpc_dstapic) 
+			&& (mp_irqs[i].mpc_dstirq == intsrc.mpc_dstirq)) {
+			mp_irqs[i] = intsrc;
+			found = 1;
+			break;
+		}
+	}
+	if (!found) {
+		mp_irqs[mp_irq_entries] = intsrc;
+		if (++mp_irq_entries == MAX_IRQ_SOURCES)
+			panic("Max # of irq sources exceeded!\n");
+	}
+
+	return;
+}
+
+
+void __init mp_config_acpi_legacy_irqs (void)
+{
+	struct mpc_config_intsrc intsrc;
+	int			i = 0;
+	int			ioapic = -1;
+
+	/* 
+	 * Fabricate the legacy ISA bus (bus #31).
+	 */
+	mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA;
+	Dprintk("Bus #%d is ISA\n", MP_ISA_BUS);
+
+	/* 
+	 * Locate the IOAPIC that manages the ISA IRQs (0-15). 
+	 */
+	ioapic = mp_find_ioapic(0);
+	if (ioapic < 0)
+		return;
+
+	intsrc.mpc_type = MP_INTSRC;
+	intsrc.mpc_irqflag = 0;					/* Conforming */
+	intsrc.mpc_srcbus = MP_ISA_BUS;
+	intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid;
+
+	/* 
+	 * Use the default configuration for the IRQs 0-15.  These may be
+	 * overriden by (MADT) interrupt source override entries.
+	 */
+	for (i = 0; i < 16; i++) {
+
+		if (i == 2) continue;			/* Don't connect IRQ2 */
+
+		intsrc.mpc_irqtype = i ? mp_INT : mp_ExtINT;   /* 8259A to #0 */
+		intsrc.mpc_srcbusirq = i;		   /* Identity mapped */
+		intsrc.mpc_dstirq = i;
+
+		Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, "
+			"%d-%d\n", intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, 
+			(intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 
+			intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, 
+			intsrc.mpc_dstirq);
+
+		mp_irqs[mp_irq_entries] = intsrc;
+		if (++mp_irq_entries == MAX_IRQ_SOURCES)
+			panic("Max # of irq sources exceeded!\n");
+	}
+
+	return;
+}
+
+
+
+#ifndef CONFIG_ACPI_HT_ONLY
+
+/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
+
+extern FADT_DESCRIPTOR acpi_fadt;
+
+void __init mp_config_ioapic_for_sci(int irq)
+{
+	int ioapic;
+	int ioapic_pin;
+	struct acpi_table_madt* madt;
+	struct acpi_table_int_src_ovr *entry = NULL;
+	void *madt_end;
+	acpi_status status;
+
+	/*
+	 * Ensure that if there is an interrupt source override entry
+	 * for the ACPI SCI, we leave it as is. Unfortunately this involves
+	 * walking the MADT again.
+	 */
+	status = acpi_get_firmware_table("APIC", 1, ACPI_LOGICAL_ADDRESSING,
+		(struct acpi_table_header **) &madt);
+	if (ACPI_SUCCESS(status)) {
+		madt_end = (void *) (unsigned long)madt + madt->header.length;
+
+		entry = (struct acpi_table_int_src_ovr *)
+                ((unsigned long) madt + sizeof(struct acpi_table_madt));
+
+		while ((void *) entry < madt_end) {
+                	if (entry->header.type == ACPI_MADT_INT_SRC_OVR &&
+			    acpi_fadt.sci_int == entry->global_irq)
+                		return;
+
+                	entry = (struct acpi_table_int_src_ovr *)
+                	        ((unsigned long) entry + entry->header.length);
+        	}
+	}
+
+	ioapic = mp_find_ioapic(irq);
+
+	ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
+
+	io_apic_set_pci_routing(ioapic, ioapic_pin, irq);
+}
+
+#endif /*CONFIG_ACPI_HT_ONLY*/
+
+#ifdef CONFIG_ACPI_PCI
+
+void __init mp_parse_prt (void)
+{
+	struct list_head	*node = NULL;
+	struct acpi_prt_entry	*entry = NULL;
+	int			vector = 0;
+	int			ioapic = -1;
+	int			ioapic_pin = 0;
+	int			irq = 0;
+	int			idx, bit = 0;
+
+	/*
+	 * Parsing through the PCI Interrupt Routing Table (PRT) and program
+	 * routing for all static (IOAPIC-direct) entries.
+	 */
+	list_for_each(node, &acpi_prt.entries) {
+		entry = list_entry(node, struct acpi_prt_entry, node);
+
+		/* Need to get irq for dynamic entry */
+		if (entry->link.handle) {
+			irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index);
+			if (!irq)
+				continue;
+		} else
+			irq = entry->link.index;
+
+		irq = entry->link.index;
+		ioapic = mp_find_ioapic(irq);
+		if (ioapic < 0)
+			continue;
+		ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
+
+		/* 
+		 * Avoid pin reprogramming.  PRTs typically include entries  
+		 * with redundant pin->irq mappings (but unique PCI devices);
+		 * we only only program the IOAPIC on the first.
+		 */
+		bit = ioapic_pin % 32;
+		idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
+		if (idx > 3) {
+			printk(KERN_ERR "Invalid reference to IOAPIC pin "
+				"%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 
+				ioapic_pin);
+			continue;
+		}
+		if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
+			printk(KERN_DEBUG "Pin %d-%d already programmed\n",
+				mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
+			entry->irq = irq;
+			continue;
+		}
+
+		mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
+
+		vector = io_apic_set_pci_routing(ioapic, ioapic_pin, irq);
+		if (vector)
+			entry->irq = irq;
+
+		printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> vector 0x%02x"
+			" -> IRQ %d\n", entry->id.segment, entry->id.bus, 
+			entry->id.device, ('A' + entry->pin), 
+			mp_ioapic_routing[ioapic].apic_id, ioapic_pin, vector, 
+			entry->irq);
+	}
+	
+	return;
+}
+
+#endif /*CONFIG_ACPI_PCI*/
+
+#endif /*CONFIG_X86_IO_APIC*/
+
+#endif /*CONFIG_ACPI_BOOT*/
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/pci-dma.c linux-2.4.22-pre3/arch/x86_64/kernel/pci-dma.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/pci-dma.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/pci-dma.c	2003-07-05 18:09:49.000000000 -0700
@@ -37,7 +37,6 @@
  	 */
  	for (i = 0; i < nents; i++ ) {
 		struct scatterlist *s = &sg[i];
-		int flush = (i == nents-1);
 		void *addr = s->address; 
 		if (addr) 
 			BUG_ON(s->page || s->offset); 
@@ -45,8 +44,7 @@
 			addr = page_address(s->page) + s->offset; 
 		else
 			BUG(); 
-		s->dma_address = __pci_map_single(hwdev, addr, s->length,
-						  direction, flush); 
+		s->dma_address = pci_map_single(hwdev, addr, s->length, direction); 
 		if (unlikely(s->dma_address == bad_dma_address))
 			goto error; 
  	}
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/pci-gart.c linux-2.4.22-pre3/arch/x86_64/kernel/pci-gart.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/pci-gart.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/pci-gart.c	2003-07-05 18:09:49.000000000 -0700
@@ -8,7 +8,7 @@
  * See Documentation/DMA-mapping.txt for the interface specification.
  * 
  * Copyright 2002 Andi Kleen, SuSE Labs.
- * $Id: pci-gart.c,v 1.20 2003/03/12 08:23:29 ak Exp $
+ * $Id: pci-gart.c,v 1.24 2003/06/09 05:17:52 ak Exp $
  */
 
 /* 
@@ -90,21 +90,25 @@
 
 static unsigned long next_bit;  /* protected by iommu_bitmap_lock */
 
-static unsigned long alloc_iommu(int size) 
+static unsigned long alloc_iommu(int size, int *flush) 
 { 	
 	unsigned long offset, flags;
 
 	spin_lock_irqsave(&iommu_bitmap_lock, flags);	
 
 	offset = find_next_zero_string(iommu_gart_bitmap,next_bit,iommu_pages,size);
-	if (offset == -1) 
+	if (offset == -1) {
+		*flush = 1;
 	       	offset = find_next_zero_string(iommu_gart_bitmap,0,next_bit,size);
+	}
 	if (offset != -1) { 
 		set_bit_string(iommu_gart_bitmap, offset, size); 
 		next_bit = offset+size; 
-		if (next_bit >= iommu_pages) 
+		if (next_bit >= iommu_pages) { 
+			*flush = 1;
 			next_bit = 0;
 	} 
+	} 
 	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);      
 	return offset;
 } 
@@ -114,7 +118,6 @@
 	unsigned long flags;
 	spin_lock_irqsave(&iommu_bitmap_lock, flags);
 	clear_bit_string(iommu_gart_bitmap, offset, size);
-	next_bit = offset;
 	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
 } 
 
@@ -133,6 +136,7 @@
 void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 			   dma_addr_t *dma_handle)
 {
+	int flush = 0;
 	void *memory;
 	int gfp = GFP_ATOMIC;
 	int i;
@@ -150,9 +154,10 @@
 	if (memory == NULL) {
 		return NULL; 
 	} else {
-		int high = (unsigned long)virt_to_bus(memory) + size
-			>= 0xffffffff;
-		int mmu = high;
+		int high = 0, mmu;
+		if (((unsigned long)virt_to_bus(memory) + size) > 0xffffffffUL)
+			high = 1;
+		mmu = high;
 		if (force_mmu && !(gfp & GFP_DMA)) 
 			mmu = 1;
 		if (no_iommu) { 
@@ -168,7 +173,7 @@
 
 	size >>= PAGE_SHIFT;
 
-	iommu_page = alloc_iommu(size);
+	iommu_page = alloc_iommu(size, &flush);
 	if (iommu_page == -1)
 		goto error; 
 
@@ -183,6 +188,7 @@
 		iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem); 
 	} 
 
+	if (flush)
 	flush_gart();
 	*dma_handle = iommu_bus_base + (iommu_page << PAGE_SHIFT);
 	return memory; 
@@ -199,25 +205,22 @@
 void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 			 void *vaddr, dma_addr_t bus)
 {
-	u64 pte;
 	unsigned long iommu_page;
-	int i;
 
 	size = round_up(size, PAGE_SIZE); 
-	if (bus < iommu_bus_base || bus > iommu_bus_base + iommu_size) { 
-		free_pages((unsigned long)vaddr, get_order(size)); 		
-		return;
-	} 
-	size >>= PAGE_SHIFT;
-	iommu_page = (bus - iommu_bus_base) / PAGE_SIZE;
-	for (i = 0; i < size; i++) {
-		pte = iommu_gatt_base[iommu_page + i];
+	if (bus >= iommu_bus_base && bus <= iommu_bus_base + iommu_size) { 
+		unsigned pages = size >> PAGE_SHIFT;
+		iommu_page = (bus - iommu_bus_base) >> PAGE_SHIFT;
+		vaddr = __va(GPTE_DECODE(iommu_gatt_base[iommu_page]));
+		int i;
+		for (i = 0; i < pages; i++) {
+			u64 pte = iommu_gatt_base[iommu_page + i];
 		BUG_ON((pte & GPTE_VALID) == 0); 
 		iommu_gatt_base[iommu_page + i] = 0; 		
-		free_page((unsigned long) __va(GPTE_DECODE(pte)));
 	} 
-	flush_gart(); 
-	free_iommu(iommu_page, size);
+		free_iommu(iommu_page, pages);
+	}
+	free_pages((unsigned long)vaddr, get_order(size)); 		
 }
 
 #ifdef CONFIG_IOMMU_LEAK
@@ -251,8 +254,7 @@
 	 * Unfortunately the drivers cannot handle this operation properly.
 	 * Return some non mapped prereserved space in the aperture and 
 	 * let the Northbridge deal with it. This will result in garbage
-	 * in the IO operation. When the size exceeds the prereserved space
-	 * memory corruption will occur or random memory will be DMAed 
+	 * in the IO operation. When the size exceeds the prereserved spa	 * memory corruption will occur or random memory will be DMAed 
 	 * out. Hopefully no network devices use single mappings that big.
 	 */ 
 	
@@ -287,9 +289,10 @@
 	return mmu; 
 }
 
-dma_addr_t __pci_map_single(struct pci_dev *dev, void *addr, size_t size,
-			    int dir, int flush)
+dma_addr_t pci_map_single(struct pci_dev *dev, void *addr, size_t size,
+			    int dir)
 { 
+	int flush = 0;
 	unsigned long iommu_page;
 	unsigned long phys_mem, bus;
 	int i, npages;
@@ -302,7 +305,7 @@
 
 	npages = round_up(size + ((u64)addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT;
 
-	iommu_page = alloc_iommu(npages); 
+	iommu_page = alloc_iommu(npages, &flush); 
 	if (iommu_page == -1) {
 		iommu_full(dev, addr, size, dir); 
 		return iommu_bus_base; 
@@ -318,11 +321,6 @@
 		 */
 		iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
 
-#ifdef CONFIG_IOMMU_DEBUG
-		/* paranoia check */
-		BUG_ON(GPTE_DECODE(iommu_gatt_base[iommu_page+i]) != phys_mem); 
-#endif
-
 #ifdef CONFIG_IOMMU_LEAK
 		/* XXX need eventually caller of pci_map_sg */
 		if (iommu_leak_tab) 
@@ -343,12 +341,13 @@
 		      size_t size, int direction)
 {
 	unsigned long iommu_page; 
-	int i, npages;
+	int npages;
 	if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE || 
 	    dma_addr > iommu_bus_base + iommu_size)
 		return;
 	iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;	
 	npages = round_up(size + (dma_addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT;
+	int i;
 	for (i = 0; i < npages; i++) { 
 		iommu_gatt_base[iommu_page + i] = 0; 
 #ifdef CONFIG_IOMMU_LEAK
@@ -356,11 +355,10 @@
 			iommu_leak_tab[iommu_page + i] = 0; 
 #endif
 	}
-	flush_gart(); 
 	free_iommu(iommu_page, npages);
 }
 
-EXPORT_SYMBOL(__pci_map_single);
+EXPORT_SYMBOL(pci_map_single);
 EXPORT_SYMBOL(pci_unmap_single);
 
 static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
@@ -444,7 +442,7 @@
 		u32 ctl; 
 		u32 gatt_reg; 
 
-		gatt_reg = ((u64)gatt) >> 12; 
+		gatt_reg = __pa(gatt) >> 12; 
 		gatt_reg <<= 4; 
 		pci_write_config_dword(dev, 0x98, gatt_reg);
 		pci_read_config_dword(dev, 0x90, &ctl); 
@@ -534,7 +532,19 @@
 	iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
 	bad_dma_address = iommu_bus_base;
 
+	/* 
+         * Unmap the IOMMU part of the GART. The alias of the page is always mapped
+	 * with cache enabled and there is no full cache coherency across the GART
+	 * remapping. The unmapping avoids automatic prefetches from the CPU 
+	 * allocating cache lines in there. All CPU accesses are done via the 
+	 * direct mapping to the backing memory. The GART address is only used by PCI 
+	 * devices. 
+	 */
+	clear_kernel_mapping((unsigned long)__va(iommu_bus_base), iommu_size);
+
 	asm volatile("wbinvd" ::: "memory");
+
+	flush_gart();
 } 
 
 /* iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]]
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/pci-irq.c linux-2.4.22-pre3/arch/x86_64/kernel/pci-irq.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/pci-irq.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/pci-irq.c	2003-07-05 18:09:49.000000000 -0700
@@ -116,7 +116,7 @@
  *  Code for querying and setting of IRQ routes on various interrupt routers.
  */
 
-static void eisa_set_level_irq(unsigned int irq)
+void eisa_set_level_irq(unsigned int irq)
 {
 	unsigned char mask = 1 << (irq & 7);
 	unsigned int port = 0x4d0 + (irq >> 3);
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/pci-pc.c linux-2.4.22-pre3/arch/x86_64/kernel/pci-pc.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/pci-pc.c	2002-11-28 15:53:12.000000000 -0800
+++ linux-2.4.22-pre3/arch/x86_64/kernel/pci-pc.c	2003-07-05 18:09:49.000000000 -0700
@@ -18,6 +18,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/acpi.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
@@ -31,6 +32,14 @@
 struct pci_bus *pci_root_bus;
 struct pci_ops *pci_root_ops;
 
+int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL;
+int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL;
+
+static int pci_using_acpi_prt = 0;
+
+/* XXX: not taken by all accesses currently */
+static spinlock_t pci_config_lock = SPIN_LOCK_UNLOCKED;
+
 /*
  * Direct access to PCI hardware...
  */
@@ -43,6 +52,66 @@
 
 #define CONFIG_CMD(dev, where)   (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
 
+#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
+	(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
+
+static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, 
+			   u32 *value) 
+{
+	unsigned long flags;
+
+	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8);
+
+	switch (len) {
+	case 1:
+		*value = inb(0xCFC + (reg & 3));
+		break;
+	case 2:
+		*value = inw(0xCFC + (reg & 2));
+		break;
+	case 4:
+		*value = inl(0xCFC);
+		break;
+	}
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+{
+	unsigned long flags;
+
+	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+		return -EINVAL;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8);
+
+	switch (len) {
+	case 1:
+		outb((u8)value, 0xCFC + (reg & 3));
+		break;
+	case 2:
+		outw((u16)value, 0xCFC + (reg & 2));
+		break;
+	case 4:
+		outl((u32)value, 0xCFC);
+		break;
+	}
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
 static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
 {
 	outl(CONFIG_CMD(dev,where), 0xCF8);
@@ -106,6 +175,76 @@
 				outb(FUNC(dev->devfn), 0xCF8);					\
 				outb(dev->bus->number, 0xCFA);
 
+#define PCI_CONF2_ADDRESS(dev, reg)	(u16)(0xC000 | (dev << 8) | reg)
+
+static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+{
+	unsigned long flags;
+
+	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
+
+	if (dev & 0x10) 
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outb((u8)(0xF0 | (fn << 1)), 0xCF8);
+	outb((u8)bus, 0xCFA);
+
+	switch (len) {
+	case 1:
+		*value = inb(PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 2:
+		*value = inw(PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 4:
+		*value = inl(PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	}
+
+	outb (0, 0xCF8);
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+{
+	unsigned long flags;
+
+	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+		return -EINVAL;
+
+	if (dev & 0x10) 
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outb((u8)(0xF0 | (fn << 1)), 0xCF8);
+	outb((u8)bus, 0xCFA);
+
+	switch (len) {
+	case 1:
+		outb ((u8)value, PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 2:
+		outw ((u16)value, PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 4:
+		outl ((u32)value, PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	}
+
+	outb (0, 0xCF8);    
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
 static int pci_conf2_read_config_byte(struct pci_dev *dev, int where, u8 *value)
 {
 	SET(dev);
@@ -244,6 +383,23 @@
 
 #endif
 
+struct pci_bus * __devinit pcibios_scan_root(int busnum)
+{
+	struct list_head *list;
+	struct pci_bus *bus;
+
+	list_for_each(list, &pci_root_buses) {
+		bus = pci_bus_b(list);
+		if (bus->number == busnum) {
+			/* Already scanned */
+			return bus;
+		}
+	}
+
+	printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
+
+	return pci_scan_bus(busnum, pci_root_ops, NULL);
+}
 
 /*
  * Several buggy motherboards address only 16 devices and mirror
@@ -387,10 +543,38 @@
 	pci_read_bridge_bases(b);
 }
 
+void __devinit pcibios_config_init(void)
+{
+	/*
+	 * Try all known PCI access methods. Note that we support using 
+	 * both PCI BIOS and direct access, with a preference for direct.
+	 */
+
+#ifdef CONFIG_PCI_DIRECT
+	if ((pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) 
+		&& (pci_root_ops = pci_check_direct())) {
+		if (pci_root_ops == &pci_direct_conf1) {
+			pci_config_read = pci_conf1_read;
+			pci_config_write = pci_conf1_write;
+		}
+		else {
+			pci_config_read = pci_conf2_read;
+			pci_config_write = pci_conf2_write;
+		}
+	} else
+		printk("??? no pci access\n"); 
+#endif
+
+	return;
+}
+
 void __devinit pcibios_init(void)
 {
 	struct pci_ops *dir = NULL;
 
+	if (!pci_root_ops)
+		pcibios_config_init();
+
 #ifdef CONFIG_PCI_DIRECT
 	if (pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2))
 		dir = pci_check_direct();
@@ -403,12 +587,18 @@
 	}
 
 	printk(KERN_INFO "PCI: Probing PCI hardware\n");
-	pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
-	
+#ifdef CONFIG_ACPI_PCI
+ 	if (!acpi_pci_irq_init())
+ 		pci_using_acpi_prt = 1;
+#endif
+ 	if (!pci_using_acpi_prt) {
+ 		pci_root_bus = pcibios_scan_root(0);
 	pcibios_irq_init();
 	pci_scan_mptable(); 
 	pcibios_fixup_peer_bridges();
 	pcibios_fixup_irqs();
+ 	}
+
 	pcibios_resource_survey();
 
 #ifdef CONFIG_GART_IOMMU
@@ -469,6 +659,15 @@
 
 	if ((err = pcibios_enable_resources(dev, mask)) < 0)
 		return err;
+
+#ifdef CONFIG_ACPI_PCI
+	if (pci_using_acpi_prt) {
+		acpi_pci_irq_enable(dev);
+		return 0;
+	}
+#endif
+
 	pcibios_enable_irq(dev);
+
 	return 0;
 }
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/process.c linux-2.4.22-pre3/arch/x86_64/kernel/process.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/process.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/process.c	2003-07-05 18:09:49.000000000 -0700
@@ -9,7 +9,7 @@
  *  X86-64 port
  *	Andi Kleen.
  * 
- *  $Id: process.c,v 1.64 2003/03/31 15:11:26 ak Exp $
+ *  $Id: process.c,v 1.70 2003/06/09 05:18:21 ak Exp $
  */
 
 /*
@@ -159,34 +159,37 @@
 __setup("idle=", idle_setup);
 
 static long no_idt[3];
-static int reboot_mode;
-
-#ifdef CONFIG_SMP
-int reboot_smp = 0;
-static int reboot_cpu = -1;
-#endif
+static enum { 
+	BOOT_BIOS = 'b',
+	BOOT_TRIPLE = 't', 
+	BOOT_KBD = 'k',
+} reboot_type = BOOT_KBD;
+static int reboot_mode = 0; 
+
+/* reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
+   bios	  Use the CPU reboto vector for warm reset
+   warm   Don't set the cold reboot flag
+   cold   Set the cold reboto flag
+   triple Force a triple fault (init)
+   kbd    Use the keyboard controller. cold reset (default)
+ */ 
 static int __init reboot_setup(char *str)
 {
-	while(1) {
+	for (;;) {
 		switch (*str) {
-		case 'w': /* "warm" reboot (no memory testing etc) */
+		case 'w': 
 			reboot_mode = 0x1234;
 			break;
-		case 'c': /* "cold" reboot (with memory testing etc) */
-			reboot_mode = 0x0;
+
+		case 'c':
+			reboot_mode = 0;
 			break;
-#ifdef CONFIG_SMP
-		case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
-			reboot_smp = 1;
-			if (isdigit(str[1]))
-				sscanf(str+1, "%d", &reboot_cpu);		
-			else if (!strncmp(str,"smp",3))
-				sscanf(str+3, "%d", &reboot_cpu); 
-			/* we will leave sorting out the final value 
-			   when we are ready to reboot, since we might not
- 			   have set up boot_cpu_id or smp_num_cpu */
+
+		case 't':
+		case 'b':
+		case 'k':
+			reboot_type = *str;
 			break;
-#endif
 		}
 		if((str = strchr(str,',')) != NULL)
 			str++;
@@ -195,9 +198,34 @@
 	}
 	return 1;
 }
-
 __setup("reboot=", reboot_setup);
 
+/* overwrites random kernel memory. Should not be kernel .text */
+#define WARMBOOT_TRAMP 0x1000UL
+
+static void reboot_warm(void)
+{
+	extern unsigned char warm_reboot[], warm_reboot_end[];
+	printk("warm reboot\n");
+
+	__cli(); 
+		
+	/* restore identity mapping */
+	init_level4_pgt[0] = __pml4(__pa(level3_ident_pgt) | 7); 
+	__flush_tlb_all(); 
+
+	memcpy(__va(WARMBOOT_TRAMP), warm_reboot, warm_reboot_end - warm_reboot); 
+
+	asm volatile( "   pushq $0\n" 		/* ss */
+		     "   pushq $0x2000\n" 	/* rsp */
+	             "   pushfq\n"		/* eflags */
+		     "   pushq %[cs]\n"
+		     "   pushq %[target]\n"
+		     "   iretq" :: 
+		      [cs] "i" (__KERNEL_COMPAT32_CS), 
+		      [target] "b" (WARMBOOT_TRAMP));
+}
+
 static inline void kb_wait(void)
 {
 	int i;
@@ -207,60 +235,76 @@
 			break;
 }
 
-void machine_restart(char * __unused)
+
+#ifdef CONFIG_SMP
+static void smp_halt(void)
 {
-#if CONFIG_SMP
-	int cpuid;
+	int cpuid = safe_smp_processor_id(); 
+	static int first_entry = 1;
 	
-	cpuid = GET_APIC_ID(apic_read(APIC_ID));
+	if (first_entry) { 
+		first_entry = 0;
+		smp_call_function((void *)machine_restart, NULL, 1, 0);		
+	}
 
-	if (reboot_smp) {
+	smp_stop_cpu(); 
 
-		/* check to see if reboot_cpu is valid 
-		   if its not, default to the BSP */
-		if ((reboot_cpu == -1) ||  
-		      (reboot_cpu > (NR_CPUS -1))  || 
-		      !(phys_cpu_present_map & (1<<cpuid))) 
-			reboot_cpu = boot_cpu_id;
-
-		reboot_smp = 0;  /* use this as a flag to only go through this once*/
-		/* re-run this function on the other CPUs
-		   it will fall though this section since we have 
-		   cleared reboot_smp, and do the reboot if it is the
-		   correct CPU, otherwise it halts. */
-		if (reboot_cpu != cpuid)
-			smp_call_function((void *)machine_restart , NULL, 1, 0);
-	}
-
-	/* if reboot_cpu is still -1, then we want a tradional reboot, 
-	   and if we are not running on the reboot_cpu,, halt */
-	if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
+	/* AP calling this. Just halt */
+	if (cpuid != boot_cpu_id) { 
 		for (;;)
-		__asm__ __volatile__ ("hlt");
+			asm("hlt");
 	}
-	/*
-	 * Stop all CPUs and turn off local APICs and the IO-APIC, so
-	 * other OSs see a clean IRQ state.
-	 */
-		smp_send_stop();
+
+	/* Wait for all other CPUs to have run smp_stop_cpu */
+	while (cpu_online_map) 
+		rep_nop(); 
+}
+#endif
+
+void machine_restart(char * __unused)
+{
+	int i;
+
+#if CONFIG_SMP
+	smp_halt();
+#endif
+	__cli();
+
+#ifndef CONFIG_SMP
+	disable_local_APIC();
 #endif
 	disable_IO_APIC();
-	/* Could do reset through the northbridge of the Hammer here. */
 
-	/* rebooting needs to touch the page at absolute addr 0 */
+	__sti();
+
+	/* Tell the BIOS if we want cold or warm reboot */
 	*((unsigned short *)__va(0x472)) = reboot_mode;
+
 	for (;;) {
-		int i;
-		/* First fondle with the keyboard controller. */ 
+		/* Could also try the reset bit in the Hammer NB */
+		switch (reboot_type) { 
+		case BOOT_BIOS:
+			reboot_warm();
+
+		case BOOT_KBD:
+			/* force cold reboot to reinit all hardware*/
 		for (i=0; i<100; i++) {
 			kb_wait();
 			udelay(50);
 			outb(0xfe,0x64);         /* pulse reset low */
 			udelay(50);
 		}
-		/* That didn't work - force a triple fault.. */
+			
+		case BOOT_TRIPLE: 
+			/* force cold reboot to reinit all hardware*/
+			*((unsigned short *)__va(0x472)) = 0;
+
 		__asm__ __volatile__("lidt %0": :"m" (no_idt));
 		__asm__ __volatile__("int3");
+
+			reboot_type = BOOT_KBD;
+			break;
+		}      
 	}
 }
 
@@ -277,7 +321,7 @@
 extern int printk_address(unsigned long); 
 
 /* Prints also some state that isn't saved in the pt_regs */ 
-void show_regs(struct pt_regs * regs)
+void __show_regs(struct pt_regs * regs)
 {
 	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
 	unsigned int fsindex,gsindex;
@@ -318,7 +362,11 @@
 	       fs,fsindex,gs,gsindex,shadowgs); 
 	printk("CS:  %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0); 
 	printk("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
+}
 
+void show_regs(struct pt_regs * regs)
+{
+	show_regs(regs);
 	show_trace(&regs->rsp);
 }
 
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/setup.c linux-2.4.22-pre3/arch/x86_64/kernel/setup.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/setup.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/setup.c	2003-07-05 18:09:50.000000000 -0700
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include <linux/blk.h>
 #include <linux/highmem.h>
 #include <linux/bootmem.h>
@@ -46,6 +47,8 @@
 #include <asm/bootsetup.h>
 #include <asm/proto.h>
 
+int acpi_disabled __initdata = 0;
+
 /*
  * Machine setup..
  */
@@ -271,6 +274,12 @@
 	kernel_end = round_up(__pa_symbol(&_end), PAGE_SIZE);
 	reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY);
 
+#ifdef CONFIG_ACPI_SLEEP
+	/*
+ 	 * Reserve low memory region for sleep support.
+ 	 */
+ 	acpi_reserve_bootmem();
+#endif
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
 	 * Find and reserve possible boot-time SMP configuration:
@@ -284,6 +293,13 @@
 #endif
 
 	paging_init();
+#ifdef CONFIG_ACPI_BOOT
+	/*
+	 * Parse the ACPI tables for possible boot-time SMP configuration.
+	 */
+	if (!acpi_disabled)
+		acpi_boot_init();
+#endif
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
 	 * get boot-time SMP configuration:
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/setup64.c linux-2.4.22-pre3/arch/x86_64/kernel/setup64.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/setup64.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/setup64.c	2003-07-05 18:09:50.000000000 -0700
@@ -3,7 +3,7 @@
  * Copyright (C) 1995  Linus Torvalds
  * Copyright 2001, 2002 SuSE Labs / Andi Kleen.
  * See setup.c for older changelog.
- * $Id: setup64.c,v 1.19 2003/02/21 19:37:21 ak Exp $
+ * $Id: setup64.c,v 1.23 2003/05/16 14:22:27 ak Exp $
  */ 
 #include <linux/config.h>
 #include <linux/init.h>
@@ -18,6 +18,7 @@
 #include <asm/atomic.h>
 #include <asm/mmu_context.h>
 #include <asm/proto.h>
+#include <asm/mman.h>
 
 char x86_boot_params[2048] __initdata = {0,};
 
@@ -31,24 +32,82 @@
 struct desc_ptr gdt_descr = { 0 /* filled in */, (unsigned long) gdt_table }; 
 struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; 
 
+/* When you change the default make sure the no EFER path below sets the 
+   correct flags everywhere. */
 unsigned long __supported_pte_mask = ~0UL; 
-static int do_not_nx = 1; 
+static int do_not_nx __initdata = 0;  
+unsigned long vm_stack_flags = __VM_STACK_FLAGS; 
+unsigned long vm_stack_flags32 = __VM_STACK_FLAGS; 
+unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS; 
+unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS; 
+unsigned long vm_force_exec32 = PROT_EXEC; 
 
 char boot_cpu_stack[IRQSTACKSIZE] __cacheline_aligned;
 
+/* noexec=on|off
+
+on	Enable
+off	Disable
+noforce (default) Don't enable by default for heap/stack/data, 
+	but allow PROT_EXEC to be effective
+
+*/ 
+
 static int __init nonx_setup(char *str)
 {
-	if (!strncmp(str,"off",3)) { 
-		__supported_pte_mask &= ~_PAGE_NX; 
-		do_not_nx = 1; 
-	} else if (!strncmp(str, "on",3)) { 
-		do_not_nx = 0; 
+	if (!strncmp(str, "on",3)) { 
 		__supported_pte_mask |= _PAGE_NX; 
+		do_not_nx = 0; 
+		vm_data_default_flags &= ~VM_EXEC; 
+		vm_stack_flags &= ~VM_EXEC;  
+	} else if (!strncmp(str, "noforce",7) || !strncmp(str,"off",3)) { 
+		do_not_nx = (str[0] == 'o');
+		if (do_not_nx) 
+			__supported_pte_mask &= ~_PAGE_NX; 
+		vm_data_default_flags |= VM_EXEC; 
+		vm_stack_flags |= VM_EXEC;
+	}
+	return 1;
+} 
+
+/* noexec32=opt{,opt} 
+
+Control the no exec default for 32bit processes. Can be also overwritten
+per executable using ELF header flags (e.g. needed for the X server)
+Requires noexec=on or noexec=noforce to be effective.
+
+Valid options: 
+   all,on    Heap,stack,data is non executable. 	
+   off       (default) Heap,stack,data is executable
+   stack     Stack is non executable, heap/data is.
+   force     Don't imply PROT_EXEC for PROT_READ 
+   compat    (default) Imply PROT_EXEC for PROT_READ
+
+*/
+static int __init nonx32_setup(char *str)
+{
+	char *s;
+	while ((s = strsep(&str, ",")) != NULL) { 
+		if (!strcmp(s, "all") || !strcmp(s,"on")) {
+			vm_data_default_flags32 &= ~VM_EXEC; 
+			vm_stack_flags32 &= ~VM_EXEC;  
+		} else if (!strcmp(s, "off")) { 
+			vm_data_default_flags32 |= VM_EXEC; 
+			vm_stack_flags32 |= VM_EXEC;  
+		} else if (!strcmp(s, "stack")) { 
+			vm_data_default_flags32 |= VM_EXEC; 
+			vm_stack_flags32 &= ~VM_EXEC;  		
+		} else if (!strcmp(s, "force")) { 
+			vm_force_exec32 = 0; 
+		} else if (!strcmp(s, "compat")) { 
+			vm_force_exec32 = PROT_EXEC;
+		} 
 	} 
 	return 1;
 } 
 
 __setup("noexec=", nonx_setup); 
+__setup("noexec32=", nonx32_setup);
 
 void pda_init(int cpu)
 { 
@@ -84,6 +143,21 @@
 	wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
 } 
 
+void syscall_init(void)
+{
+	/* 
+	 * LSTAR and STAR live in a bit strange symbiosis.
+	 * They both write to the same internal register. STAR allows to set CS/DS
+	 * but only a 32bit target. LSTAR sets the 64bit rip. 	 
+	 */ 
+	wrmsrl(MSR_STAR,  ((u64)__USER32_CS)<<48  | ((u64)__KERNEL_CS)<<32); 
+	wrmsrl(MSR_LSTAR, system_call); 
+
+#ifdef CONFIG_IA32_EMULATION   		
+	wrmsrl(MSR_CSTAR, ia32_cstar_target); 
+#endif
+}
+
 #define EXCEPTION_STK_ORDER 0 /* >= N_EXCEPTION_STACKS*EXCEPTION_STKSZ */
 char boot_exception_stacks[N_EXCEPTION_STACKS*EXCEPTION_STKSZ];
 
@@ -132,21 +206,13 @@
 
 	asm volatile("pushfq ; popq %%rax ; btr $14,%%rax ; pushq %%rax ; popfq" ::: "eax");
 
-	/* 
-	 * LSTAR and STAR live in a bit strange symbiosis.
-	 * They both write to the same internal register. STAR allows to set CS/DS
-	 * but only a 32bit target. LSTAR sets the 64bit rip. 	 
-	 */ 
-	wrmsrl(MSR_STAR,  ((u64)__USER32_CS)<<48  | ((u64)__KERNEL_CS)<<32); 
-	wrmsrl(MSR_LSTAR, system_call); 
-
-#ifdef CONFIG_IA32_EMULATION   		
-	wrmsrl(MSR_CSTAR, ia32_cstar_target); 
-#endif
+	syscall_init();
 
 		rdmsrl(MSR_EFER, efer); 
 	if (!(efer & EFER_NX) || do_not_nx) { 
 			__supported_pte_mask &= ~_PAGE_NX; 
+	} else { 
+		__supported_pte_mask |= _PAGE_NX; 
 		} 
 
 	t->io_map_base = INVALID_IO_BITMAP_OFFSET;	
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/smp.c linux-2.4.22-pre3/arch/x86_64/kernel/smp.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/smp.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/smp.c	2003-07-05 18:09:50.000000000 -0700
@@ -488,7 +488,7 @@
 	return 0;
 }
 
-static void stop_this_cpu (void * dummy)
+void smp_stop_cpu(void)
 {
 	/*
 	 * Remove this CPU:
@@ -496,8 +496,14 @@
 	clear_bit(smp_processor_id(), &cpu_online_map);
 	__cli();
 	disable_local_APIC();
-	for(;;) __asm__("hlt");
-	for (;;);
+	__sti(); 
+}
+
+static void smp_really_stop_cpu(void *dummy)
+{
+	smp_stop_cpu(); 
+	for (;;) 
+		asm("hlt"); 
 }
 
 /*
@@ -506,12 +512,8 @@
 
 void smp_send_stop(void)
 {
-	smp_call_function(stop_this_cpu, NULL, 1, 0);
-	smp_num_cpus = 1;
-
-	__cli();
-	disable_local_APIC();
-	__sti();
+	smp_call_function(smp_really_stop_cpu, NULL, 1, 0);
+	smp_stop_cpu();
 }
 
 /*
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/suspend.c linux-2.4.22-pre3/arch/x86_64/kernel/suspend.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/suspend.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/x86_64/kernel/suspend.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,169 @@
+/*
+ * Suspend support specific for i386.
+ *
+ * Distribute under GPLv2
+ *
+ * Copyright (c) 2002 Pavel Machek <pavel@suse.cz>
+ * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/poll.h>
+#include <linux/delay.h>
+#include <linux/sysrq.h>
+#include <linux/proc_fs.h>
+#include <linux/irq.h>
+#include <linux/pm.h>
+#include <asm/uaccess.h>
+#include <asm/acpi.h>
+#include <asm/io.h>
+#include <asm/proto.h>
+#include <asm/i387.h>
+#include <asm/desc.h>
+
+void fix_processor_context(void);
+
+/* Image of the saved processor state. If you touch this, fix acpi_wakeup.S. */
+struct saved_context {
+  	u16 ds, es, fs, gs, ss;
+	unsigned long gs_base, gs_kernel_base, fs_base;
+	unsigned long cr0, cr2, cr3, cr4;
+	u16 gdt_pad;
+	u16 gdt_limit;
+	unsigned long gdt_base;
+	u16 idt_pad;
+	u16 idt_limit;
+	unsigned long idt_base;
+	u16 ldt;
+	u16 tss;
+	unsigned long tr;
+	unsigned long safety;
+	unsigned long return_address;
+	unsigned long eflags;
+} __attribute__((packed));
+
+struct saved_context saved_context;
+
+unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx;
+unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi;
+unsigned long saved_context_r08, saved_context_r09, saved_context_r10, saved_context_r11;
+unsigned long saved_context_r12, saved_context_r13, saved_context_r14, saved_context_r15;
+unsigned long saved_context_eflags;
+
+void save_processor_state (void)
+{
+	kernel_fpu_begin();
+
+	/*
+	 * descriptor tables
+	 */
+	asm volatile ("sgdt %0" : "=m" (saved_context.gdt_limit));
+	asm volatile ("sidt %0" : "=m" (saved_context.idt_limit));
+	asm volatile ("sldt %0" : "=m" (saved_context.ldt));
+	asm volatile ("str %0"  : "=m" (saved_context.tr));
+
+	/* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
+	/* EFER should be constant for kernel version, no need to handle it. */
+	/*
+	 * segment registers
+	 */
+	asm volatile ("movw %%ds, %0" : "=m" (saved_context.ds));
+	asm volatile ("movw %%es, %0" : "=m" (saved_context.es));
+	asm volatile ("movw %%fs, %0" : "=m" (saved_context.fs));
+	asm volatile ("movw %%gs, %0" : "=m" (saved_context.gs));
+	asm volatile ("movw %%ss, %0" : "=m" (saved_context.ss));
+
+	rdmsrl(MSR_FS_BASE, saved_context.fs_base);
+	rdmsrl(MSR_GS_BASE, saved_context.gs_base);
+	rdmsrl(MSR_KERNEL_GS_BASE, saved_context.gs_kernel_base);
+
+	/*
+	 * control registers 
+	 */
+	asm volatile ("movq %%cr0, %0" : "=r" (saved_context.cr0));
+	asm volatile ("movq %%cr2, %0" : "=r" (saved_context.cr2));
+	asm volatile ("movq %%cr3, %0" : "=r" (saved_context.cr3));
+	asm volatile ("movq %%cr4, %0" : "=r" (saved_context.cr4));
+}
+
+static void
+do_fpu_end(void)
+{
+        /* restore FPU regs if necessary */
+        kernel_fpu_end();
+}
+
+void restore_processor_state(void)
+{
+	/*
+	 * control registers
+	 */
+	asm volatile ("movq %0, %%cr4" :: "r" (saved_context.cr4));
+	asm volatile ("movq %0, %%cr3" :: "r" (saved_context.cr3));
+	asm volatile ("movq %0, %%cr2" :: "r" (saved_context.cr2));
+	asm volatile ("movq %0, %%cr0" :: "r" (saved_context.cr0));
+
+	/*
+	 * segment registers
+	 */
+	asm volatile ("movw %0, %%ds" :: "r" (saved_context.ds));
+	asm volatile ("movw %0, %%es" :: "r" (saved_context.es));
+	asm volatile ("movw %0, %%fs" :: "r" (saved_context.fs));
+	load_gs_index(saved_context.gs);
+	asm volatile ("movw %0, %%ss" :: "r" (saved_context.ss));
+
+	wrmsrl(MSR_FS_BASE, saved_context.fs_base);
+	wrmsrl(MSR_GS_BASE, saved_context.gs_base);
+	wrmsrl(MSR_KERNEL_GS_BASE, saved_context.gs_kernel_base);
+
+	/*
+	 * now restore the descriptor tables to their proper values
+	 * ltr is done i fix_processor_context().
+	 */
+	asm volatile ("lgdt %0" :: "m" (saved_context.gdt_limit));
+	asm volatile ("lidt %0" :: "m" (saved_context.idt_limit));
+	asm volatile ("lldt %0" :: "m" (saved_context.ldt));
+
+	fix_processor_context();
+
+	do_fpu_end();
+}
+
+#define loaddebug(thread,register) \
+		set_debug((thread)->debugreg[register], register)
+
+void fix_processor_context(void)
+{
+	int cpu = smp_processor_id();
+	struct tss_struct * t = init_tss + cpu;
+
+	set_tss_desc(cpu,t);
+
+	/* clear busy TSS */
+	gdt_cpu_table[cpu].tss.type = 9;
+
+	syscall_init();                      /* This sets MSR_*STAR and related */
+	load_TR(cpu);				/* This does ltr */
+	load_LDT(current->active_mm);		/* This does lldt */
+
+	/*
+	 * Now maybe reload the debug registers
+	 */
+	if (current->thread.debugreg[7]){
+                loaddebug(&current->thread, 0);
+                loaddebug(&current->thread, 1);
+                loaddebug(&current->thread, 2);
+                loaddebug(&current->thread, 3);
+                /* no 4 and 5 */
+                loaddebug(&current->thread, 6);
+                loaddebug(&current->thread, 7);
+	}
+
+}
+
+
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/time.c linux-2.4.22-pre3/arch/x86_64/kernel/time.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/time.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/time.c	2003-07-05 18:09:50.000000000 -0700
@@ -63,6 +63,11 @@
 	return ((hpet_readl(HPET_COUNTER) - vxtime.last) * vxtime.quot) >> 32;
 }
 
+static unsigned int do_gettimeoffset_nop(void)
+{
+	return 0;
+}
+
 unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc;
 
 /*
@@ -482,14 +487,10 @@
 
 static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
 
-extern void __init config_acpi_tables(void);
-
 void __init time_init(void)
 {
 	char *timename;
 
-	config_acpi_tables();
-
 #ifdef HPET_HACK_ENABLE_DANGEROUS
         if (!hpet_address) {
 		printk(KERN_WARNING "time.c: WARNING: Enabling HPET base manually!\n");
@@ -546,12 +547,17 @@
 		} else {
 			timetype = "HPET/TSC";
 			vxtime.mode = VXTIME_TSC;
-			do_gettimeoffset = do_gettimeoffset_tsc;
 		}		
 	} else {
+		if (notsc) { 
+			timetype = "PIT"; 
+			vxtime.mode = VXTIME_STUPID; 
+			do_gettimeoffset = do_gettimeoffset_nop;
+		} else { 
 			timetype = "PIT/TSC";
 			vxtime.mode = VXTIME_TSC;
 	}
+	}
 	printk(KERN_INFO "time.c: Using %s based timekeeping.\n", timetype);
 }
 
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/traps.c linux-2.4.22-pre3/arch/x86_64/kernel/traps.c
--- linux-2.4.22-pre2/arch/x86_64/kernel/traps.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/kernel/traps.c	2003-07-05 18:09:50.000000000 -0700
@@ -7,7 +7,7 @@
  *  Pentium III FXSR, SSE support
  *	Gareth Hughes <gareth@valinux.com>, May 2000
  *
- *  $Id: traps.c,v 1.62 2003/03/14 16:06:35 ak Exp $
+ *  $Id: traps.c,v 1.66 2003/06/09 05:18:21 ak Exp $
  */
 
 /*
@@ -290,7 +290,7 @@
 		rsp = regs->rsp;
 	}
 	printk("CPU %d ", cpu);
-	show_regs(regs);
+	__show_regs(regs);
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		cur->comm, cur->pid, 4096+(unsigned long)cur);
 
@@ -344,6 +344,7 @@
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
+	unsigned long flags;
 	int cpu;
 	console_verbose();
 	bust_spinlocks(1);
@@ -352,6 +353,7 @@
  	notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
 	cpu = safe_smp_processor_id(); 
 	/* racy, but better than risking deadlock. */ 
+	__save_flags(flags); 
 	__cli();
 	if (!spin_trylock(&die_lock)) { 
 		if (cpu == die_owner) 
@@ -362,7 +364,7 @@
 	die_owner = cpu; 
 	show_registers(regs);
 	bust_spinlocks(0);
-	spin_unlock_irq(&die_lock);
+	spin_unlock_irqrestore(&die_lock, flags);
 	do_exit(SIGSEGV);
 }
 
@@ -402,8 +404,11 @@
 		struct task_struct *tsk = current;
 		tsk->thread.error_code = error_code;
 		tsk->thread.trap_no = trapnr;
-		if (exception_trace && trapnr != 3)
-			printk("%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
+		if (exception_trace && !(tsk->ptrace & PT_PTRACED) && 
+		    (tsk->sig->action[signr-1].sa.sa_handler == SIG_IGN ||
+		    (tsk->sig->action[signr-1].sa.sa_handler == SIG_DFL)))
+			printk(KERN_INFO
+			       "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
 			       tsk->comm, tsk->pid, str,
 			       regs->rip,regs->rsp,error_code); 
 		if (info)
@@ -418,7 +423,6 @@
 	{	     
 		unsigned long fixup = search_exception_table(regs->rip);
 		if (fixup) {
-			extern int exception_trace; 
 			regs->rip = fixup;
 		} else	
 			die(str, regs, error_code);
@@ -478,20 +482,25 @@
 			   by the segment reloads in __switch_to. Otherwise
 			   the wake_up could deadlock on scheduler locks. */
 			oops_in_progress++;
-			printk("general protection handler: wrong gs %lx expected %p\n", gs, pda);
+			printk(KERN_EMERG 
+			       "general protection handler: wrong gs %lx expected %p\n", gs, pda);
 			oops_in_progress--; 
 		}
 	}
 #endif
 
 	if (regs->cs & 3) { 		
-		current->thread.error_code = error_code;
-		current->thread.trap_no = 13;
-		if (exception_trace)
-			printk("%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
-			       current->comm, current->pid,
+		struct task_struct *tsk = current;
+		tsk->thread.error_code = error_code;
+		tsk->thread.trap_no = 13;
+		if (exception_trace && !(tsk->ptrace & PT_PTRACED) && 
+		    (tsk->sig->action[SIGSEGV-1].sa.sa_handler == SIG_IGN ||
+		    (tsk->sig->action[SIGSEGV-1].sa.sa_handler == SIG_DFL)))
+			printk(KERN_INFO
+		       "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
+			       tsk->comm, tsk->pid,
 			       regs->rip,regs->rsp,error_code); 
-		force_sig(SIGSEGV, current);
+		force_sig(SIGSEGV, tsk);
 		return;
 	} 
 
@@ -594,7 +603,7 @@
 		rdmsrl(MSR_GS_BASE, gs); 
 		if (gs != (unsigned long)pda) { 
 			wrmsrl(MSR_GS_BASE, pda); 
-			printk("debug handler: wrong gs %lx expected %p\n", gs, pda);
+			printk(KERN_EMERG "debug handler: wrong gs %lx expected %p\n", gs, pda);
 		}
 	}
 #endif
@@ -809,7 +818,7 @@
 #ifndef CONFIG_MCE
 void do_machine_check(struct pt_regs *regs)
 { 
-	printk("Machine check ignored\n");
+	printk(KERN_INFO "Machine check ignored\n");
 } 
 #endif
 
diff -urN linux-2.4.22-pre2/arch/x86_64/kernel/warmreboot.S linux-2.4.22-pre3/arch/x86_64/kernel/warmreboot.S
--- linux-2.4.22-pre2/arch/x86_64/kernel/warmreboot.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/arch/x86_64/kernel/warmreboot.S	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,83 @@
+/*
+ * Switch back to real mode and call the BIOS reboot vector.
+ * This is a trampoline copied around in process.c 
+ * Written 2003 by Andi Kleen, SuSE Labs.	 	
+ */			
+	
+#include <asm/msr.h>
+
+#define R(x) x-warm_reboot(%ebx)
+#define R64(x) x-warm_reboot(%rbx)
+		
+	/* running in identity mapping and in the first 64k of memory
+	   and in compatibility mode. This must be position independent */
+
+	/* Follows 14.7 "Leaving Long Mode" in the AMD x86-64 manual, volume 2
+	   and 8.9.2 "Switching Back to Real-Address Mode" in the Intel IA32
+	   manual, volume 2 */
+
+	/* ebx:	self pointer to warm_reboot */
+
+	.globl warm_reboot
+warm_reboot:
+	addl  %ebx,  R64(real_mode_desc)	/* relocate tables */
+	addl  %ebx,2+R64(warm_gdt_desc)		
+
+	movq  %cr0,%rax
+	btr  $31,%rax		
+	movq %rax,%cr0		/* disable paging */
+	jmp  1f			/* flush prefetch queue */
+	
+	.code32	
+1:	movl $MSR_EFER,%ecx
+	rdmsr
+	andl $~((1<<_EFER_LME)|(1<<_EFER_SCE)|(1<<_EFER_NX)),%eax
+	wrmsr			/* disable long mode in EFER */
+		
+	xorl %eax,%eax
+	movl %eax,%cr3		/* flush tlb */
+
+	/* Running protected mode without paging now */
+	
+	wbinvd			/* flush caches. Needed? */
+
+	lidt R(warm_idt_desc)
+	lgdt R(warm_gdt_desc)
+	
+	movl $0x10,%ecx		/* load segment registers with real mode settings */
+	movl %ecx,%ds
+	movl %ecx,%es
+	movl %ecx,%fs
+	movl %ecx,%gs
+	movl %ecx,%ss
+	
+	lea  R(real_mode_desc),%eax		
+	ljmp *(%eax)
+
+	.code16:
+real_mode:
+	xorl %eax,%eax
+	movl %eax,%cr0
+	
+	/* some people claim $0xf000,0xfff0 is better. Use what 32bit linux uses. */
+	/* code as bytes because gas has problems with it */
+	.byte 	0xea,0xf0,0xff,0x00,0xf0	/* ljmp  0xf000:0xfff0 */
+
+real_mode_desc:
+	.long  real_mode - warm_reboot
+	.short 8	
+warm_gdt_desc:
+	.short 8*3
+	.long warm_gdt - warm_reboot
+warm_gdt:	
+	.quad   0
+	.quad 	0x00009a000000ffff	/* 16-bit real-mode 64k code at 0x00000000 */
+	.quad   0x000092000100ffff	/* 16-bit real-mode 64k data at 0x00000100 */
+	
+warm_idt_desc:
+	.short 0x3ff
+	.long  0
+				
+	.globl warm_reboot_end
+warm_reboot_end:
+
diff -urN linux-2.4.22-pre2/arch/x86_64/mm/fault.c linux-2.4.22-pre3/arch/x86_64/mm/fault.c
--- linux-2.4.22-pre2/arch/x86_64/mm/fault.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/mm/fault.c	2003-07-05 18:09:50.000000000 -0700
@@ -229,9 +229,12 @@
 
 	/* User mode accesses just cause a SIGSEGV */
 	if (error_code & 4) {
-		if (exception_trace) 
-			printk("%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
-					current->comm, current->pid, address, regs->rip,
+		if (exception_trace && !(tsk->ptrace & PT_PTRACED) && 
+		    (tsk->sig->action[SIGSEGV-1].sa.sa_handler == SIG_IGN ||
+		    (tsk->sig->action[SIGSEGV-1].sa.sa_handler == SIG_DFL)))
+			printk(KERN_INFO 
+		       "%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
+					tsk->comm, tsk->pid, address, regs->rip,
 					regs->rsp, error_code);
 	
 		tsk->thread.cr2 = address;
@@ -253,7 +256,7 @@
 		if (0 && exception_trace) 
 		printk(KERN_ERR 
 		       "%s: fixed kernel exception at %lx address %lx err:%ld\n", 
-		       current->comm, regs->rip, address, error_code);
+		       tsk->comm, regs->rip, address, error_code);
 		return;
 	}
 
@@ -265,6 +268,21 @@
 	console_verbose();
 	bust_spinlocks(1); 
 
+	int cpu = safe_smp_processor_id(); 
+	unsigned long flags; 
+	extern int die_owner; 
+	extern spinlock_t die_lock;
+	
+	__save_flags(flags); 
+	__cli(); 
+	if (!spin_trylock(&die_lock)) { 
+		if (cpu == die_owner) 
+			/* nested oops. should stop eventually */;
+		else
+			spin_lock(&die_lock); 
+	}
+	die_owner = cpu; 
+
 	if (address < PAGE_SIZE)
 		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
 	else
@@ -275,6 +293,7 @@
 	dump_pagetable(address);
 	die("Oops", regs, error_code);
 	bust_spinlocks(0); 
+	spin_unlock_irqrestore(&die_lock, flags);
 	do_exit(SIGKILL);
 
 /*
diff -urN linux-2.4.22-pre2/arch/x86_64/mm/init.c linux-2.4.22-pre3/arch/x86_64/mm/init.c
--- linux-2.4.22-pre2/arch/x86_64/mm/init.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/arch/x86_64/mm/init.c	2003-07-05 18:09:50.000000000 -0700
@@ -418,35 +418,31 @@
 #endif
 }
 
-void __init __map_kernel_range(void *address, int len, pgprot_t prot) 
+/* Unmap a kernel mapping if it exists. This is useful to avoid prefetches
+   from the CPU leading to inconsistent cache lines. address and size
+   must be aligned to 2MB boundaries. 
+   Does nothing when the mapping doesn't exist. */
+void __init clear_kernel_mapping(unsigned long address, unsigned long size) 
 { 
-	int i;
-	void *end = address + len;
-	BUG_ON((pgprot_val(prot) & _PAGE_PSE) == 0);
-	address = (void *)((unsigned long)address & LARGE_PAGE_MASK); 
+	unsigned long end = address + size;
+
+	BUG_ON(address & ~LARGE_PAGE_MASK);
+	BUG_ON(size & ~LARGE_PAGE_MASK); 
+	
 	for (; address < end; address += LARGE_PAGE_SIZE) { 
-		pml4_t *pml4;
-		pgd_t *pgd;
-		pmd_t *pmd;
-
-		pml4 = pml4_offset_k((unsigned long) address); 
-		if (pml4_none(*pml4)) { 
-			void *p = (void *)get_zeroed_page(GFP_KERNEL); 
-			if (!p) panic("Cannot map kernel range"); 
-			for (i = 0; i < smp_num_cpus; i++) {
-				set_pml4((pml4_t *)(cpu_pda[i].level4_pgt) + 
-					 pml4_index((unsigned long)address),
-					 mk_kernel_pml4(virt_to_phys(p),KERNPG_TABLE));
-			}
-		} 
-		pgd = pgd_offset_k((unsigned long)address); 
-		if (pgd_none(*pgd)) { 
-			void *p = (void *)get_zeroed_page(GFP_KERNEL); 
-			if (!p) panic("Cannot map kernel range"); 
-			set_pgd(pgd, __mk_pgd(virt_to_phys(p), KERNPG_TABLE));
+		pgd_t *pgd = pgd_offset_k(address);
+		if (!pgd || pgd_none(*pgd))
+			continue; 
+		pmd_t *pmd = pmd_offset(pgd, address);
+		if (!pmd || pmd_none(*pmd))
+			continue; 
+		if (0 == (pmd_val(*pmd) & _PAGE_PSE)) { 
+			/* Could handle this, but it should not happen currently. */
+			printk(KERN_ERR 
+		"clear_kernel_mapping: mapping has been split. will leak memory\n"); 
+			pmd_ERROR(*pmd); 
 		} 
-		pmd = pmd_offset(pgd, (unsigned long) address); 
-		set_pmd(pmd, __mk_pmd(virt_to_phys(address), prot));
+		set_pmd(pmd, __pmd(0)); 		
 	} 
 	__flush_tlb_all(); 
 } 
diff -urN linux-2.4.22-pre2/crypto/Config.in linux-2.4.22-pre3/crypto/Config.in
--- linux-2.4.22-pre2/crypto/Config.in	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/Config.in	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,84 @@
+#
+# Cryptographic API Configuration
+#
+mainmenu_option next_comment
+comment 'Cryptographic options'
+
+if [ "$CONFIG_INET_AH" = "y" -o \
+     "$CONFIG_INET_AH" = "m" -o \
+     "$CONFIG_INET_ESP" = "y" -o \
+     "$CONFIG_INET_ESP" = "m" -o \
+     "$CONFIG_INET6_AH" = "y" -o \
+     "$CONFIG_INET6_AH" = "m" -o \
+     "$CONFIG_INET6_ESP" = "y" -o \
+     "$CONFIG_INET6_ESP" = "m" ]; then
+  define_bool CONFIG_CRYPTO y
+else
+  bool 'Cryptographic API' CONFIG_CRYPTO
+fi
+
+if [ "$CONFIG_CRYPTO" = "y" ]; then
+  if [ "$CONFIG_INET_AH" = "y" -o \
+       "$CONFIG_INET_AH" = "m" -o \
+       "$CONFIG_INET_ESP" = "y" -o \
+       "$CONFIG_INET_ESP" = "m" -o \
+       "$CONFIG_INET6_AH" = "y" -o \
+       "$CONFIG_INET6_AH" = "m" -o \
+       "$CONFIG_INET6_ESP" = "y" -o \
+       "$CONFIG_INET6_ESP" = "m" ]; then
+    define_bool CONFIG_CRYPTO_HMAC y
+  else
+    bool           '  HMAC support' CONFIG_CRYPTO_HMAC
+  fi
+  tristate       '  NULL algorithms' CONFIG_CRYPTO_NULL
+  tristate       '  MD4 digest algorithm' CONFIG_CRYPTO_MD4
+  if [ "$CONFIG_INET_AH" = "y" -o \
+       "$CONFIG_INET_AH" = "m" -o \
+       "$CONFIG_INET_ESP" = "y" -o \
+       "$CONFIG_INET_ESP" = "m" -o \
+       "$CONFIG_INET6_AH" = "y" -o \
+       "$CONFIG_INET6_AH" = "m" -o \
+       "$CONFIG_INET6_ESP" = "y" -o \
+       "$CONFIG_INET6_ESP" = "m" ]; then
+    define_bool CONFIG_CRYPTO_MD5 y
+  else
+    tristate       '  MD5 digest algorithm' CONFIG_CRYPTO_MD5
+  fi
+  if [ "$CONFIG_INET_AH" = "y" -o \
+       "$CONFIG_INET_AH" = "m" -o \
+       "$CONFIG_INET_ESP" = "y" -o \
+       "$CONFIG_INET_ESP" = "m" -o \
+       "$CONFIG_INET6_AH" = "y" -o \
+       "$CONFIG_INET6_AH" = "m" -o \
+       "$CONFIG_INET6_ESP" = "y" -o \
+       "$CONFIG_INET6_ESP" = "m" ]; then
+    define_bool CONFIG_CRYPTO_SHA1 y
+  else
+    tristate       '  SHA1 digest algorithm' CONFIG_CRYPTO_SHA1
+  fi
+  tristate       '  SHA256 digest algorithm' CONFIG_CRYPTO_SHA256
+  tristate       '  SHA384 and SHA512 digest algorithms' CONFIG_CRYPTO_SHA512
+  if [ "$CONFIG_INET_ESP" = "y" -o \
+       "$CONFIG_INET_ESP" = "m" -o \
+       "$CONFIG_INET6_ESP" = "y" -o \
+       "$CONFIG_INET6_ESP" = "m" ]; then
+    define_bool CONFIG_CRYPTO_DES y
+  else
+    tristate       '  DES and Triple DES EDE cipher algorithms' CONFIG_CRYPTO_DES
+  fi
+  tristate       '  Blowfish cipher algorithm' CONFIG_CRYPTO_BLOWFISH
+  tristate       '  Twofish cipher algorithm' CONFIG_CRYPTO_TWOFISH
+  tristate       '  Serpent cipher algorithm' CONFIG_CRYPTO_SERPENT
+  tristate       '  AES cipher algorithms' CONFIG_CRYPTO_AES
+  if [ "$CONFIG_INET_IPCOMP" = "y" -o \
+       "$CONFIG_INET_IPCOMP" = "m" -o \
+       "$CONFIG_INET6_IPCOMP" = "y" -o \
+       "$CONFIG_INET6_IPCOMP" = "m" ]; then
+    define_bool CONFIG_CRYPTO_DEFLATE y
+  else
+    tristate       '  Deflate compression algorithm' CONFIG_CRYPTO_DEFLATE
+  fi
+  tristate       '  Testing module' CONFIG_CRYPTO_TEST
+fi
+
+endmenu
diff -urN linux-2.4.22-pre2/crypto/Makefile linux-2.4.22-pre3/crypto/Makefile
--- linux-2.4.22-pre2/crypto/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/Makefile	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,31 @@
+#
+# Cryptographic API
+#
+
+O_TARGET := crypto.o
+
+export-objs := api.o hmac.o
+
+autoload-crypto-$(CONFIG_KMOD) = autoload.o
+proc-crypto-$(CONFIG_PROC_FS) = proc.o
+
+obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o \
+			$(autoload-crypto-y) $(proc-crypto-y)
+
+obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
+obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
+obj-$(CONFIG_CRYPTO_MD4) += md4.o
+obj-$(CONFIG_CRYPTO_MD5) += md5.o
+obj-$(CONFIG_CRYPTO_SHA1) += sha1.o
+obj-$(CONFIG_CRYPTO_SHA256) += sha256.o
+obj-$(CONFIG_CRYPTO_SHA512) += sha512.o
+obj-$(CONFIG_CRYPTO_DES) += des.o
+obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
+obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o
+obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o
+obj-$(CONFIG_CRYPTO_AES) += aes.o
+obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
+
+obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/crypto/aes.c linux-2.4.22-pre3/crypto/aes.c
--- linux-2.4.22-pre2/crypto/aes.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/aes.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,469 @@
+/* 
+ * Cryptographic API.
+ *
+ * AES Cipher Algorithm.
+ *
+ * Based on Brian Gladman's code.
+ *
+ * Linux developers:
+ *  Alexander Kjeldaas <astor@fast.no>
+ *  Herbert Valerio Riedel <hvr@hvrlab.org>
+ *  Kyle McMartin <kyle@debian.org>
+ *  Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ *   1. distributions of this source code include the above copyright
+ *      notice, this list of conditions and the following disclaimer;
+ *
+ *   2. distributions in binary form include the above copyright
+ *      notice, this list of conditions and the following disclaimer
+ *      in the documentation and/or other associated materials;
+ *
+ *   3. the copyright holder's name is not used to endorse products
+ *      built using this software without specific written permission.
+ *
+ * ALTERNATIVELY, provided that this notice is retained in full, this product
+ * may be distributed under the terms of the GNU General Public License (GPL),
+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and/or fitness for purpose.
+ * ---------------------------------------------------------------------------
+ */
+
+/* Some changes from the Gladman version:
+    s/RIJNDAEL(e_key)/E_KEY/g
+    s/RIJNDAEL(d_key)/D_KEY/g
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <asm/byteorder.h>
+
+#define AES_MIN_KEY_SIZE	16
+#define AES_MAX_KEY_SIZE	32
+
+#define AES_BLOCK_SIZE		16
+
+static inline 
+u32 generic_rotr32 (const u32 x, const unsigned bits)
+{
+	const unsigned n = bits % 32;
+	return (x >> n) | (x << (32 - n));
+}
+
+static inline 
+u32 generic_rotl32 (const u32 x, const unsigned bits)
+{
+	const unsigned n = bits % 32;
+	return (x << n) | (x >> (32 - n));
+}
+
+#define rotl generic_rotl32
+#define rotr generic_rotr32
+
+/*
+ * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) 
+ */
+inline static u8
+byte(const u32 x, const unsigned n)
+{
+	return x >> (n << 3);
+}
+
+#define u32_in(x) le32_to_cpu(*(const u32 *)(x))
+#define u32_out(to, from) (*(u32 *)(to) = cpu_to_le32(from))
+
+struct aes_ctx {
+	int key_length;
+	u32 E[60];
+	u32 D[60];
+};
+
+#define E_KEY ctx->E
+#define D_KEY ctx->D
+
+static u8 pow_tab[256];
+static u8 log_tab[256];
+static u8 sbx_tab[256];
+static u8 isb_tab[256];
+static u32 rco_tab[10];
+static u32 ft_tab[4][256];
+static u32 it_tab[4][256];
+
+static u32 fl_tab[4][256];
+static u32 il_tab[4][256];
+
+static inline u8
+f_mult (u8 a, u8 b)
+{
+	u8 aa = log_tab[a], cc = aa + log_tab[b];
+
+	return pow_tab[cc + (cc < aa ? 1 : 0)];
+}
+
+#define ff_mult(a,b)    (a && b ? f_mult(a, b) : 0)
+
+#define f_rn(bo, bi, n, k)					\
+    bo[n] =  ft_tab[0][byte(bi[n],0)] ^				\
+             ft_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
+             ft_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
+
+#define i_rn(bo, bi, n, k)					\
+    bo[n] =  it_tab[0][byte(bi[n],0)] ^				\
+             it_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
+             it_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
+
+#define ls_box(x)				\
+    ( fl_tab[0][byte(x, 0)] ^			\
+      fl_tab[1][byte(x, 1)] ^			\
+      fl_tab[2][byte(x, 2)] ^			\
+      fl_tab[3][byte(x, 3)] )
+
+#define f_rl(bo, bi, n, k)					\
+    bo[n] =  fl_tab[0][byte(bi[n],0)] ^				\
+             fl_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
+             fl_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
+
+#define i_rl(bo, bi, n, k)					\
+    bo[n] =  il_tab[0][byte(bi[n],0)] ^				\
+             il_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
+             il_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
+
+static void
+gen_tabs (void)
+{
+	u32 i, t;
+	u8 p, q;
+
+	/* log and power tables for GF(2**8) finite field with
+	   0x011b as modular polynomial - the simplest prmitive
+	   root is 0x03, used here to generate the tables */
+
+	for (i = 0, p = 1; i < 256; ++i) {
+		pow_tab[i] = (u8) p;
+		log_tab[p] = (u8) i;
+
+		p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	log_tab[1] = 0;
+
+	for (i = 0, p = 1; i < 10; ++i) {
+		rco_tab[i] = p;
+
+		p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = (i ? pow_tab[255 - log_tab[i]] : 0);
+		q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
+		p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
+		sbx_tab[i] = p;
+		isb_tab[p] = (u8) i;
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = sbx_tab[i];
+
+		t = p;
+		fl_tab[0][i] = t;
+		fl_tab[1][i] = rotl (t, 8);
+		fl_tab[2][i] = rotl (t, 16);
+		fl_tab[3][i] = rotl (t, 24);
+
+		t = ((u32) ff_mult (2, p)) |
+		    ((u32) p << 8) |
+		    ((u32) p << 16) | ((u32) ff_mult (3, p) << 24);
+
+		ft_tab[0][i] = t;
+		ft_tab[1][i] = rotl (t, 8);
+		ft_tab[2][i] = rotl (t, 16);
+		ft_tab[3][i] = rotl (t, 24);
+
+		p = isb_tab[i];
+
+		t = p;
+		il_tab[0][i] = t;
+		il_tab[1][i] = rotl (t, 8);
+		il_tab[2][i] = rotl (t, 16);
+		il_tab[3][i] = rotl (t, 24);
+
+		t = ((u32) ff_mult (14, p)) |
+		    ((u32) ff_mult (9, p) << 8) |
+		    ((u32) ff_mult (13, p) << 16) |
+		    ((u32) ff_mult (11, p) << 24);
+
+		it_tab[0][i] = t;
+		it_tab[1][i] = rotl (t, 8);
+		it_tab[2][i] = rotl (t, 16);
+		it_tab[3][i] = rotl (t, 24);
+	}
+}
+
+#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
+
+#define imix_col(y,x)       \
+    u   = star_x(x);        \
+    v   = star_x(u);        \
+    w   = star_x(v);        \
+    t   = w ^ (x);          \
+   (y)  = u ^ v ^ w;        \
+   (y) ^= rotr(u ^ t,  8) ^ \
+          rotr(v ^ t, 16) ^ \
+          rotr(t,24)
+
+/* initialise the key schedule from the user supplied key */
+
+#define loop4(i)                                    \
+{   t = rotr(t,  8); t = ls_box(t) ^ rco_tab[i];    \
+    t ^= E_KEY[4 * i];     E_KEY[4 * i + 4] = t;    \
+    t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t;    \
+    t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t;    \
+    t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t;    \
+}
+
+#define loop6(i)                                    \
+{   t = rotr(t,  8); t = ls_box(t) ^ rco_tab[i];    \
+    t ^= E_KEY[6 * i];     E_KEY[6 * i + 6] = t;    \
+    t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t;    \
+    t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t;    \
+    t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t;    \
+    t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t;   \
+    t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t;   \
+}
+
+#define loop8(i)                                    \
+{   t = rotr(t,  8); ; t = ls_box(t) ^ rco_tab[i];  \
+    t ^= E_KEY[8 * i];     E_KEY[8 * i + 8] = t;    \
+    t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t;    \
+    t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t;   \
+    t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t;   \
+    t  = E_KEY[8 * i + 4] ^ ls_box(t);    \
+    E_KEY[8 * i + 12] = t;                \
+    t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t;   \
+    t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t;   \
+    t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t;   \
+}
+
+static int
+aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
+{
+	struct aes_ctx *ctx = ctx_arg;
+	u32 i, t, u, v, w;
+
+	if (key_len != 16 && key_len != 24 && key_len != 32) {
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+
+	ctx->key_length = key_len;
+
+	E_KEY[0] = u32_in (in_key);
+	E_KEY[1] = u32_in (in_key + 4);
+	E_KEY[2] = u32_in (in_key + 8);
+	E_KEY[3] = u32_in (in_key + 12);
+
+	switch (key_len) {
+	case 16:
+		t = E_KEY[3];
+		for (i = 0; i < 10; ++i)
+			loop4 (i);
+		break;
+
+	case 24:
+		E_KEY[4] = u32_in (in_key + 16);
+		t = E_KEY[5] = u32_in (in_key + 20);
+		for (i = 0; i < 8; ++i)
+			loop6 (i);
+		break;
+
+	case 32:
+		E_KEY[4] = u32_in (in_key + 16);
+		E_KEY[5] = u32_in (in_key + 20);
+		E_KEY[6] = u32_in (in_key + 24);
+		t = E_KEY[7] = u32_in (in_key + 28);
+		for (i = 0; i < 7; ++i)
+			loop8 (i);
+		break;
+	}
+
+	D_KEY[0] = E_KEY[0];
+	D_KEY[1] = E_KEY[1];
+	D_KEY[2] = E_KEY[2];
+	D_KEY[3] = E_KEY[3];
+
+	for (i = 4; i < key_len + 24; ++i) {
+		imix_col (D_KEY[i], E_KEY[i]);
+	}
+
+	return 0;
+}
+
+/* encrypt a block of text */
+
+#define f_nround(bo, bi, k) \
+    f_rn(bo, bi, 0, k);     \
+    f_rn(bo, bi, 1, k);     \
+    f_rn(bo, bi, 2, k);     \
+    f_rn(bo, bi, 3, k);     \
+    k += 4
+
+#define f_lround(bo, bi, k) \
+    f_rl(bo, bi, 0, k);     \
+    f_rl(bo, bi, 1, k);     \
+    f_rl(bo, bi, 2, k);     \
+    f_rl(bo, bi, 3, k)
+
+static void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in)
+{
+	const struct aes_ctx *ctx = ctx_arg;
+	u32 b0[4], b1[4];
+	const u32 *kp = E_KEY + 4;
+
+	b0[0] = u32_in (in) ^ E_KEY[0];
+	b0[1] = u32_in (in + 4) ^ E_KEY[1];
+	b0[2] = u32_in (in + 8) ^ E_KEY[2];
+	b0[3] = u32_in (in + 12) ^ E_KEY[3];
+
+	if (ctx->key_length > 24) {
+		f_nround (b1, b0, kp);
+		f_nround (b0, b1, kp);
+	}
+
+	if (ctx->key_length > 16) {
+		f_nround (b1, b0, kp);
+		f_nround (b0, b1, kp);
+	}
+
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_lround (b0, b1, kp);
+
+	u32_out (out, b0[0]);
+	u32_out (out + 4, b0[1]);
+	u32_out (out + 8, b0[2]);
+	u32_out (out + 12, b0[3]);
+}
+
+/* decrypt a block of text */
+
+#define i_nround(bo, bi, k) \
+    i_rn(bo, bi, 0, k);     \
+    i_rn(bo, bi, 1, k);     \
+    i_rn(bo, bi, 2, k);     \
+    i_rn(bo, bi, 3, k);     \
+    k -= 4
+
+#define i_lround(bo, bi, k) \
+    i_rl(bo, bi, 0, k);     \
+    i_rl(bo, bi, 1, k);     \
+    i_rl(bo, bi, 2, k);     \
+    i_rl(bo, bi, 3, k)
+
+static void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in)
+{
+	const struct aes_ctx *ctx = ctx_arg;
+	u32 b0[4], b1[4];
+	const int key_len = ctx->key_length;
+	const u32 *kp = D_KEY + key_len + 20;
+
+	b0[0] = u32_in (in) ^ E_KEY[key_len + 24];
+	b0[1] = u32_in (in + 4) ^ E_KEY[key_len + 25];
+	b0[2] = u32_in (in + 8) ^ E_KEY[key_len + 26];
+	b0[3] = u32_in (in + 12) ^ E_KEY[key_len + 27];
+
+	if (key_len > 24) {
+		i_nround (b1, b0, kp);
+		i_nround (b0, b1, kp);
+	}
+
+	if (key_len > 16) {
+		i_nround (b1, b0, kp);
+		i_nround (b0, b1, kp);
+	}
+
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_lround (b0, b1, kp);
+
+	u32_out (out, b0[0]);
+	u32_out (out + 4, b0[1]);
+	u32_out (out + 8, b0[2]);
+	u32_out (out + 12, b0[3]);
+}
+
+
+static struct crypto_alg aes_alg = {
+	.cra_name		=	"aes",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	AES_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct aes_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
+	.cra_u			=	{
+		.cipher = {
+			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
+			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
+			.cia_ivsize		=	AES_BLOCK_SIZE,
+			.cia_setkey	   	= 	aes_set_key,
+			.cia_encrypt	 	=	aes_encrypt,
+			.cia_decrypt	  	=	aes_decrypt
+		}
+	}
+};
+
+static int __init aes_init(void)
+{
+	gen_tabs();
+	return crypto_register_alg(&aes_alg);
+}
+
+static void __exit aes_fini(void)
+{
+	crypto_unregister_alg(&aes_alg);
+}
+
+module_init(aes_init);
+module_exit(aes_fini);
+
+MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
+MODULE_LICENSE("Dual BSD/GPL");
+
diff -urN linux-2.4.22-pre2/crypto/api.c linux-2.4.22-pre3/crypto/api.c
--- linux-2.4.22-pre2/crypto/api.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/api.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,227 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ *
+ * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
+ * and Nettle, by Niels Möller.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/crypto.h>
+#include <linux/errno.h>
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+LIST_HEAD(crypto_alg_list);
+DECLARE_RWSEM(crypto_alg_sem);
+
+static inline int crypto_alg_get(struct crypto_alg *alg)
+{
+	return try_inc_mod_count(alg->cra_module);
+}
+
+static inline void crypto_alg_put(struct crypto_alg *alg)
+{
+	if (alg->cra_module)
+		__MOD_DEC_USE_COUNT(alg->cra_module);
+}
+
+struct crypto_alg *crypto_alg_lookup(const char *name)
+{
+	struct crypto_alg *q, *alg = NULL;
+	
+	down_read(&crypto_alg_sem);
+	
+	list_for_each_entry(q, &crypto_alg_list, cra_list) {
+		if (!(strcmp(q->cra_name, name))) {
+			if (crypto_alg_get(q))
+				alg = q;
+			break;
+		}
+	}
+	
+	up_read(&crypto_alg_sem);
+	return alg;
+}
+
+static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	tfm->crt_flags = 0;
+	
+	switch (crypto_tfm_alg_type(tfm)) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		return crypto_init_cipher_flags(tfm, flags);
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		return crypto_init_digest_flags(tfm, flags);
+		
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		return crypto_init_compress_flags(tfm, flags);
+	
+	default:
+		break;
+	}
+	
+	BUG();
+	return -EINVAL;
+}
+
+static int crypto_init_ops(struct crypto_tfm *tfm)
+{
+	switch (crypto_tfm_alg_type(tfm)) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		return crypto_init_cipher_ops(tfm);
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		return crypto_init_digest_ops(tfm);
+		
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		return crypto_init_compress_ops(tfm);
+	
+	default:
+		break;
+	}
+	
+	BUG();
+	return -EINVAL;
+}
+
+static void crypto_exit_ops(struct crypto_tfm *tfm)
+{
+	switch (crypto_tfm_alg_type(tfm)) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		crypto_exit_cipher_ops(tfm);
+		break;
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		crypto_exit_digest_ops(tfm);
+		break;
+		
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		crypto_exit_compress_ops(tfm);
+		break;
+	
+	default:
+		BUG();
+		
+	}
+}
+
+struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
+{
+	struct crypto_tfm *tfm = NULL;
+	struct crypto_alg *alg;
+
+	alg = crypto_alg_mod_lookup(name);
+	if (alg == NULL)
+		goto out;
+	
+	tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
+	if (tfm == NULL)
+		goto out_put;
+
+	memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize);
+	
+	tfm->__crt_alg = alg;
+	
+	if (crypto_init_flags(tfm, flags))
+		goto out_free_tfm;
+		
+	if (crypto_init_ops(tfm)) {
+		crypto_exit_ops(tfm);
+		goto out_free_tfm;
+	}
+
+	goto out;
+
+out_free_tfm:
+	kfree(tfm);
+	tfm = NULL;
+out_put:
+	crypto_alg_put(alg);
+out:
+	return tfm;
+}
+
+void crypto_free_tfm(struct crypto_tfm *tfm)
+{
+	crypto_exit_ops(tfm);
+	crypto_alg_put(tfm->__crt_alg);
+	kfree(tfm);
+}
+
+int crypto_register_alg(struct crypto_alg *alg)
+{
+	int ret = 0;
+	struct crypto_alg *q;
+	
+	down_write(&crypto_alg_sem);
+	
+	list_for_each_entry(q, &crypto_alg_list, cra_list) {
+		if (!(strcmp(q->cra_name, alg->cra_name))) {
+			ret = -EEXIST;
+			goto out;
+		}
+	}
+	
+	list_add_tail(&alg->cra_list, &crypto_alg_list);
+out:	
+	up_write(&crypto_alg_sem);
+	return ret;
+}
+
+int crypto_unregister_alg(struct crypto_alg *alg)
+{
+	int ret = -ENOENT;
+	struct crypto_alg *q;
+	
+	BUG_ON(!alg->cra_module);
+	
+	down_write(&crypto_alg_sem);
+	list_for_each_entry(q, &crypto_alg_list, cra_list) {
+		if (alg == q) {
+			list_del(&alg->cra_list);
+			ret = 0;
+			goto out;
+		}
+	}
+out:	
+	up_write(&crypto_alg_sem);
+	return ret;
+}
+
+int crypto_alg_available(const char *name, u32 flags)
+{
+	int ret = 0;
+	struct crypto_alg *alg = crypto_alg_mod_lookup(name);
+	
+	if (alg) {
+		crypto_alg_put(alg);
+		ret = 1;
+	}
+	
+	return ret;
+}
+
+static int __init init_crypto(void)
+{
+	printk(KERN_INFO "Initializing Cryptographic API\n");
+	crypto_init_proc();
+	return 0;
+}
+
+__initcall(init_crypto);
+
+EXPORT_SYMBOL_GPL(crypto_register_alg);
+EXPORT_SYMBOL_GPL(crypto_unregister_alg);
+EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
+EXPORT_SYMBOL_GPL(crypto_free_tfm);
+EXPORT_SYMBOL_GPL(crypto_alg_available);
diff -urN linux-2.4.22-pre2/crypto/autoload.c linux-2.4.22-pre3/crypto/autoload.c
--- linux-2.4.22-pre2/crypto/autoload.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/autoload.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,37 @@
+/*
+ * Cryptographic API.
+ *
+ * Algorithm autoloader.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/crypto.h>
+#include <linux/string.h>
+#include <linux/kmod.h>
+#include "internal.h"
+
+/*
+ * A far more intelligent version of this is planned.  For now, just
+ * try an exact match on the name of the algorithm.
+ */
+void crypto_alg_autoload(const char *name)
+{
+	request_module(name);
+}
+
+struct crypto_alg *crypto_alg_mod_lookup(const char *name)
+{
+	struct crypto_alg *alg = crypto_alg_lookup(name);
+	if (alg == NULL) {
+		crypto_alg_autoload(name);
+		alg = crypto_alg_lookup(name);
+	}
+	return alg;
+}
diff -urN linux-2.4.22-pre2/crypto/blowfish.c linux-2.4.22-pre3/crypto/blowfish.c
--- linux-2.4.22-pre2/crypto/blowfish.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/blowfish.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,479 @@
+/* 
+ * Cryptographic API.
+ *
+ * Blowfish Cipher Algorithm, by Bruce Schneier.
+ * http://www.counterpane.com/blowfish.html
+ * 
+ * Adapated from Kerneli implementation.
+ * 
+ * Copyright (c) Herbert Valerio Riedel <hvr@hvrlab.org>
+ * Copyright (c) Kyle McMartin <kyle@debian.org>
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <linux/crypto.h>
+
+#define BF_BLOCK_SIZE 8
+#define BF_MIN_KEY_SIZE 4
+#define BF_MAX_KEY_SIZE 56
+
+struct bf_ctx {
+	u32 p[18];
+	u32 s[1024];
+};
+
+static const u32 bf_pbox[16 + 2] = {
+	0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+	0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+	0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+	0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+	0x9216d5d9, 0x8979fb1b,
+};
+
+static const u32 bf_sbox[256 * 4] = {
+	0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+	0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+	0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+	0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+	0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+	0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+	0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+	0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+	0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+	0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+	0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+	0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+	0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+	0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+	0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+	0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+	0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+	0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+	0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+	0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+	0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+	0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+	0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+	0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+	0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+	0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+	0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+	0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+	0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+	0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+	0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+	0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+	0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+	0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+	0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+	0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+	0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+	0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+	0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+	0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+	0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+	0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+	0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+	0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+	0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+	0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+	0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+	0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+	0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+	0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+	0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+	0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+	0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+	0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+	0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+	0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+	0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+	0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+	0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+	0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+	0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+	0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+	0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+	0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
+	0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+	0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+	0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+	0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+	0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+	0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+	0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+	0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+	0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+	0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+	0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+	0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+	0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+	0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+	0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+	0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+	0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+	0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+	0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+	0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+	0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+	0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+	0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+	0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+	0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+	0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+	0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+	0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+	0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+	0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+	0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+	0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+	0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+	0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+	0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+	0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+	0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+	0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+	0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+	0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+	0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+	0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+	0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+	0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+	0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+	0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+	0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+	0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+	0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+	0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+	0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+	0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+	0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+	0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+	0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+	0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+	0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+	0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+	0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+	0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+	0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+	0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+	0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+	0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
+	0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+	0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+	0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+	0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+	0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+	0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+	0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+	0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+	0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+	0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+	0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+	0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+	0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+	0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+	0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+	0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+	0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+	0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+	0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+	0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+	0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+	0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+	0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+	0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+	0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+	0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+	0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+	0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+	0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+	0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+	0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+	0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+	0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+	0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+	0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+	0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+	0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+	0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+	0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+	0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+	0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+	0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+	0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+	0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+	0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+	0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+	0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+	0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+	0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+	0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+	0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+	0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+	0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+	0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+	0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+	0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+	0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+	0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+	0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+	0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+	0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+	0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+	0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+	0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
+	0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+	0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+	0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+	0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+	0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+	0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+	0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+	0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+	0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+	0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+	0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+	0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+	0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+	0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+	0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+	0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+	0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+	0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+	0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+	0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+	0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+	0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+	0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+	0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+	0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+	0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+	0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+	0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+	0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+	0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+	0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+	0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+	0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+	0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+	0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+	0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+	0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+	0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+	0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+	0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+	0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+	0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+	0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+	0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+	0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+	0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+	0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+	0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+	0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+	0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+	0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+	0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+	0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+	0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+	0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+	0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+	0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+	0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+	0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+	0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+	0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+	0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+	0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+	0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
+};
+
+/* 
+ * Round loop unrolling macros, S is a pointer to a S-Box array
+ * organized in 4 unsigned longs at a row.
+ */
+#define GET32_3(x) (((x) & 0xff))
+#define GET32_2(x) (((x) >> (8)) & (0xff))
+#define GET32_1(x) (((x) >> (16)) & (0xff))
+#define GET32_0(x) (((x) >> (24)) & (0xff))
+
+#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \
+          S[512 + GET32_2(x)]) + S[768 + GET32_3(x)])
+
+#define ROUND(a, b, n)  b ^= P[n]; a ^= bf_F (b)
+
+/*
+ * The blowfish encipher, processes 64-bit blocks.
+ * NOTE: This function MUSTN'T respect endianess 
+ */
+static inline void encrypt_block(struct bf_ctx *bctx, u32 *dst, u32 *src)
+{
+	const u32 *P = bctx->p;
+	const u32 *S = bctx->s;
+	u32 yl = src[0];
+	u32 yr = src[1];
+
+	ROUND(yr, yl, 0);
+	ROUND(yl, yr, 1);
+	ROUND(yr, yl, 2);
+	ROUND(yl, yr, 3);
+	ROUND(yr, yl, 4);
+	ROUND(yl, yr, 5);
+	ROUND(yr, yl, 6);
+	ROUND(yl, yr, 7);
+	ROUND(yr, yl, 8);
+	ROUND(yl, yr, 9);
+	ROUND(yr, yl, 10);
+	ROUND(yl, yr, 11);
+	ROUND(yr, yl, 12);
+	ROUND(yl, yr, 13);
+	ROUND(yr, yl, 14);
+	ROUND(yl, yr, 15);
+
+	yl ^= P[16];
+	yr ^= P[17];
+
+	dst[0] = yr;
+	dst[1] = yl;
+}
+
+static void bf_encrypt(void *ctx, u8 *dst, const u8 *src)
+{
+	const u32 *in_blk = (const u32 *)src;
+	u32 *const out_blk = (u32 *)dst;
+	u32 in32[2], out32[2];
+
+	in32[0] = be32_to_cpu(in_blk[0]);
+	in32[1] = be32_to_cpu(in_blk[1]);
+	encrypt_block(ctx, out32, in32);
+	out_blk[0] = cpu_to_be32(out32[0]);
+	out_blk[1] = cpu_to_be32(out32[1]);
+}
+
+static void bf_decrypt(void *ctx, u8 *dst, const u8 *src)
+{
+	const u32 *in_blk = (const u32 *)src;
+	u32 *const out_blk = (u32 *)dst;
+	const u32 *P = ((struct bf_ctx *)ctx)->p;
+	const u32 *S = ((struct bf_ctx *)ctx)->s;
+	u32 yl = be32_to_cpu(in_blk[0]);
+	u32 yr = be32_to_cpu(in_blk[1]);
+
+	ROUND(yr, yl, 17);
+	ROUND(yl, yr, 16);
+	ROUND(yr, yl, 15);
+	ROUND(yl, yr, 14);
+	ROUND(yr, yl, 13);
+	ROUND(yl, yr, 12);
+	ROUND(yr, yl, 11);
+	ROUND(yl, yr, 10);
+	ROUND(yr, yl, 9);
+	ROUND(yl, yr, 8);
+	ROUND(yr, yl, 7);
+	ROUND(yl, yr, 6);
+	ROUND(yr, yl, 5);
+	ROUND(yl, yr, 4);
+	ROUND(yr, yl, 3);
+	ROUND(yl, yr, 2);
+
+	yl ^= P[1];
+	yr ^= P[0];
+
+	out_blk[0] = cpu_to_be32(yr);
+	out_blk[1] = cpu_to_be32(yl);
+}
+
+/* 
+ * Calculates the blowfish S and P boxes for encryption and decryption.
+ */
+static int bf_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+{
+	short i, j, count;
+	u32 data[2], temp;
+	u32 *P = ((struct bf_ctx *)ctx)->p;
+	u32 *S = ((struct bf_ctx *)ctx)->s;
+
+	/* Copy the initialization s-boxes */
+	for (i = 0, count = 0; i < 256; i++)
+		for (j = 0; j < 4; j++, count++)
+			S[count] = bf_sbox[count];
+
+	/* Set the p-boxes */
+	for (i = 0; i < 16 + 2; i++)
+		P[i] = bf_pbox[i];
+
+	/* Actual subkey generation */
+	for (j = 0, i = 0; i < 16 + 2; i++) {
+		temp = (((u32 )key[j] << 24) |
+			((u32 )key[(j + 1) % keylen] << 16) |
+			((u32 )key[(j + 2) % keylen] << 8) |
+			((u32 )key[(j + 3) % keylen]));
+
+		P[i] = P[i] ^ temp;
+		j = (j + 4) % keylen;
+	}
+
+	data[0] = 0x00000000;
+	data[1] = 0x00000000;
+
+	for (i = 0; i < 16 + 2; i += 2) {
+		encrypt_block((struct bf_ctx *)ctx, data, data);
+
+		P[i] = data[0];
+		P[i + 1] = data[1];
+	}
+
+	for (i = 0; i < 4; i++) {
+		for (j = 0, count = i * 256; j < 256; j += 2, count += 2) {
+			encrypt_block((struct bf_ctx *)ctx, data, data);
+
+			S[count] = data[0];
+			S[count + 1] = data[1];
+		}
+	}
+	
+	/* Bruce says not to bother with the weak key check. */
+	return 0;
+}
+
+static struct crypto_alg alg = {
+	.cra_name		=	"blowfish",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	BF_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct bf_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(alg.cra_list),
+	.cra_u			=	{ .cipher = {
+	.cia_min_keysize	=	BF_MIN_KEY_SIZE,
+	.cia_max_keysize	=	BF_MAX_KEY_SIZE,
+	.cia_ivsize		=	BF_BLOCK_SIZE,
+	.cia_setkey   		= 	bf_setkey,
+	.cia_encrypt 		=	bf_encrypt,
+	.cia_decrypt  		=	bf_decrypt } }
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Blowfish Cipher Algorithm");
diff -urN linux-2.4.22-pre2/crypto/cipher.c linux-2.4.22-pre3/crypto/cipher.c
--- linux-2.4.22-pre2/crypto/cipher.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/cipher.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,417 @@
+/*
+ * Cryptographic API.
+ *
+ * Cipher operations.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.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/kernel.h>
+#include <linux/crypto.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+
+typedef void (cryptfn_t)(void *, u8 *, const u8 *);
+typedef void (procfn_t)(struct crypto_tfm *, u8 *,
+                        u8*, cryptfn_t, int enc, void *);
+
+struct scatter_walk {
+	struct scatterlist	*sg;
+	struct page		*page;
+	void			*data;
+	unsigned int		len_this_page;
+	unsigned int		len_this_segment;
+	unsigned int		offset;
+};
+
+enum km_type crypto_km_types[] = {
+	KM_USER0,
+	KM_USER1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+};
+
+static inline void xor_64(u8 *a, const u8 *b)
+{
+	((u32 *)a)[0] ^= ((u32 *)b)[0];
+	((u32 *)a)[1] ^= ((u32 *)b)[1];
+}
+
+static inline void xor_128(u8 *a, const u8 *b)
+{
+	((u32 *)a)[0] ^= ((u32 *)b)[0];
+	((u32 *)a)[1] ^= ((u32 *)b)[1];
+	((u32 *)a)[2] ^= ((u32 *)b)[2];
+	((u32 *)a)[3] ^= ((u32 *)b)[3];
+}
+
+
+/* Define sg_next is an inline routine now in case we want to change
+   scatterlist to a linked list later. */
+static inline struct scatterlist *sg_next(struct scatterlist *sg)
+{
+	return sg + 1;
+}
+
+void *which_buf(struct scatter_walk *walk, unsigned int nbytes, void *scratch)
+{
+	if (nbytes <= walk->len_this_page &&
+	    (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <=
+	    PAGE_CACHE_SIZE)
+		return walk->data;
+	else
+		return scratch;
+}
+
+static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
+{
+	if (out)
+		memcpy(sgdata, buf, nbytes);
+	else
+		memcpy(buf, sgdata, nbytes);
+}
+
+static void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
+{
+	unsigned int rest_of_page;
+
+	walk->sg = sg;
+
+	walk->page = sg->page;
+	walk->len_this_segment = sg->length;
+
+	rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1));
+	walk->len_this_page = min(sg->length, rest_of_page);
+	walk->offset = sg->offset;
+}
+
+static void scatterwalk_map(struct scatter_walk *walk, int out)
+{
+	walk->data = crypto_kmap(walk->page, out) + walk->offset;
+}
+
+static void scatter_page_done(struct scatter_walk *walk, int out,
+			      unsigned int more)
+{
+	/* walk->data may be pointing the first byte of the next page;
+	   however, we know we transfered at least one byte.  So,
+	   walk->data - 1 will be a virutual address in the mapped page. */
+
+	if (out)
+		flush_dcache_page(walk->page);
+
+	if (more) {
+		walk->len_this_segment -= walk->len_this_page;
+
+		if (walk->len_this_segment) {
+			walk->page++;
+			walk->len_this_page = min(walk->len_this_segment,
+						  (unsigned)PAGE_CACHE_SIZE);
+			walk->offset = 0;
+		}
+		else
+			scatterwalk_start(walk, sg_next(walk->sg));
+	}
+}
+
+static void scatter_done(struct scatter_walk *walk, int out, int more)
+{
+	crypto_kunmap(walk->data, out);
+	if (walk->len_this_page == 0 || !more)
+		scatter_page_done(walk, out, more);
+}
+
+/*
+ * Do not call this unless the total length of all of the fragments 
+ * has been verified as multiple of the block size.
+ */
+static int copy_chunks(void *buf, struct scatter_walk *walk,
+			size_t nbytes, int out)
+{
+	if (buf != walk->data) {
+		while (nbytes > walk->len_this_page) {
+			memcpy_dir(buf, walk->data, walk->len_this_page, out);
+			buf += walk->len_this_page;
+			nbytes -= walk->len_this_page;
+
+			crypto_kunmap(walk->data, out);
+			scatter_page_done(walk, out, 1);
+			scatterwalk_map(walk, out);
+		}
+
+		memcpy_dir(buf, walk->data, nbytes, out);
+	}
+
+	walk->offset += nbytes;
+	walk->len_this_page -= nbytes;
+	walk->len_this_segment -= nbytes;
+	return 0;
+}
+
+/* 
+ * Generic encrypt/decrypt wrapper for ciphers, handles operations across
+ * multiple page boundaries by using temporary blocks.  In user context,
+ * the kernel is given a chance to schedule us once per block.
+ */
+static int crypt(struct crypto_tfm *tfm,
+		 struct scatterlist *dst,
+		 struct scatterlist *src,
+                 unsigned int nbytes, cryptfn_t crfn,
+                 procfn_t prfn, int enc, void *info)
+{
+	struct scatter_walk walk_in, walk_out;
+	const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
+	u8 tmp_src[nbytes > src->length ? bsize : 0];
+	u8 tmp_dst[nbytes > dst->length ? bsize : 0];
+
+	if (!nbytes)
+		return 0;
+
+	if (nbytes % bsize) {
+		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
+		return -EINVAL;
+	}
+
+	scatterwalk_start(&walk_in, src);
+	scatterwalk_start(&walk_out, dst);
+
+	for(;;) {
+		u8 *src_p, *dst_p;
+
+		scatterwalk_map(&walk_in, 0);
+		scatterwalk_map(&walk_out, 1);
+		src_p = which_buf(&walk_in, bsize, tmp_src);
+		dst_p = which_buf(&walk_out, bsize, tmp_dst);
+
+		nbytes -= bsize;
+
+		copy_chunks(src_p, &walk_in, bsize, 0);
+
+		prfn(tfm, dst_p, src_p, crfn, enc, info);
+
+		scatter_done(&walk_in, 0, nbytes);
+
+		copy_chunks(dst_p, &walk_out, bsize, 1);
+		scatter_done(&walk_out, 1, nbytes);
+
+		if (!nbytes)
+			return 0;
+
+		crypto_yield(tfm);
+	}
+}
+
+static void cbc_process(struct crypto_tfm *tfm,
+                        u8 *dst, u8 *src, cryptfn_t fn, int enc, void *info)
+{
+	u8 *iv = info;
+	
+	/* Null encryption */
+	if (!iv)
+		return;
+		
+	if (enc) {
+		tfm->crt_u.cipher.cit_xor_block(iv, src);
+		fn(crypto_tfm_ctx(tfm), dst, iv);
+		memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm));
+	} else {
+		const int need_stack = (src == dst);
+		u8 stack[need_stack ? crypto_tfm_alg_blocksize(tfm) : 0];
+		u8 *buf = need_stack ? stack : dst;
+		
+		fn(crypto_tfm_ctx(tfm), buf, src);
+		tfm->crt_u.cipher.cit_xor_block(buf, iv);
+		memcpy(iv, src, crypto_tfm_alg_blocksize(tfm));
+		if (buf != dst)
+			memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm));
+	}
+}
+
+static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
+                        cryptfn_t fn, int enc, void *info)
+{
+	fn(crypto_tfm_ctx(tfm), dst, src);
+}
+
+static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+{
+	struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;
+	
+	if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) {
+		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	} else
+		return cia->cia_setkey(crypto_tfm_ctx(tfm), key, keylen,
+		                       &tfm->crt_flags);
+}
+
+static int ecb_encrypt(struct crypto_tfm *tfm,
+		       struct scatterlist *dst,
+                       struct scatterlist *src, unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_encrypt,
+	             ecb_process, 1, NULL);
+}
+
+static int ecb_decrypt(struct crypto_tfm *tfm,
+                       struct scatterlist *dst,
+                       struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_decrypt,
+	             ecb_process, 1, NULL);
+}
+
+static int cbc_encrypt(struct crypto_tfm *tfm,
+                       struct scatterlist *dst,
+                       struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_encrypt,
+	             cbc_process, 1, tfm->crt_cipher.cit_iv);
+}
+
+static int cbc_encrypt_iv(struct crypto_tfm *tfm,
+                          struct scatterlist *dst,
+                          struct scatterlist *src,
+                          unsigned int nbytes, u8 *iv)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_encrypt,
+	             cbc_process, 1, iv);
+}
+
+static int cbc_decrypt(struct crypto_tfm *tfm,
+                       struct scatterlist *dst,
+                       struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_decrypt,
+	             cbc_process, 0, tfm->crt_cipher.cit_iv);
+}
+
+static int cbc_decrypt_iv(struct crypto_tfm *tfm,
+                          struct scatterlist *dst,
+                          struct scatterlist *src,
+                          unsigned int nbytes, u8 *iv)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_decrypt,
+	             cbc_process, 0, iv);
+}
+
+static int nocrypt(struct crypto_tfm *tfm,
+                   struct scatterlist *dst,
+                   struct scatterlist *src,
+		   unsigned int nbytes)
+{
+	return -ENOSYS;
+}
+
+static int nocrypt_iv(struct crypto_tfm *tfm,
+                      struct scatterlist *dst,
+                      struct scatterlist *src,
+                      unsigned int nbytes, u8 *iv)
+{
+	return -ENOSYS;
+}
+
+int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	u32 mode = flags & CRYPTO_TFM_MODE_MASK;
+	
+	tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB;
+	if (flags & CRYPTO_TFM_REQ_WEAK_KEY)
+		tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY;
+	
+	return 0;
+}
+
+int crypto_init_cipher_ops(struct crypto_tfm *tfm)
+{
+	int ret = 0;
+	struct crypto_alg *alg = tfm->__crt_alg;
+	struct cipher_tfm *ops = &tfm->crt_cipher;
+
+	ops->cit_setkey = setkey;
+
+	switch (tfm->crt_cipher.cit_mode) {
+	case CRYPTO_TFM_MODE_ECB:
+		ops->cit_encrypt = ecb_encrypt;
+		ops->cit_decrypt = ecb_decrypt;
+		break;
+		
+	case CRYPTO_TFM_MODE_CBC:
+		ops->cit_encrypt = cbc_encrypt;
+		ops->cit_decrypt = cbc_decrypt;
+		ops->cit_encrypt_iv = cbc_encrypt_iv;
+		ops->cit_decrypt_iv = cbc_decrypt_iv;
+		break;
+		
+	case CRYPTO_TFM_MODE_CFB:
+		ops->cit_encrypt = nocrypt;
+		ops->cit_decrypt = nocrypt;
+		ops->cit_encrypt_iv = nocrypt_iv;
+		ops->cit_decrypt_iv = nocrypt_iv;
+		break;
+	
+	case CRYPTO_TFM_MODE_CTR:
+		ops->cit_encrypt = nocrypt;
+		ops->cit_decrypt = nocrypt;
+		ops->cit_encrypt_iv = nocrypt_iv;
+		ops->cit_decrypt_iv = nocrypt_iv;
+		break;
+
+	default:
+		BUG();
+	}
+	
+	if (alg->cra_cipher.cia_ivsize &&
+	    ops->cit_mode != CRYPTO_TFM_MODE_ECB) {
+	    	
+	    	switch (crypto_tfm_alg_blocksize(tfm)) {
+	    	case 8:
+	    		ops->cit_xor_block = xor_64;
+	    		break;
+	    		
+	    	case 16:
+	    		ops->cit_xor_block = xor_128;
+	    		break;
+	    		
+	    	default:
+	    		printk(KERN_WARNING "%s: block size %u not supported\n",
+	    		       crypto_tfm_alg_name(tfm),
+	    		       crypto_tfm_alg_blocksize(tfm));
+	    		ret = -EINVAL;
+	    		goto out;
+	    	}
+	    	
+	    	ops->cit_iv = kmalloc(alg->cra_cipher.cia_ivsize, GFP_KERNEL);
+		if (ops->cit_iv == NULL)
+			ret = -ENOMEM;
+	}
+
+out:	
+	return ret;
+}
+
+void crypto_exit_cipher_ops(struct crypto_tfm *tfm)
+{
+	if (tfm->crt_cipher.cit_iv)
+		kfree(tfm->crt_cipher.cit_iv);
+}
diff -urN linux-2.4.22-pre2/crypto/compress.c linux-2.4.22-pre3/crypto/compress.c
--- linux-2.4.22-pre2/crypto/compress.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/compress.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,63 @@
+/*
+ * Cryptographic API.
+ *
+ * Compression operations.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/types.h>
+#include <linux/crypto.h>
+#include <linux/errno.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include "internal.h"
+
+static int crypto_compress(struct crypto_tfm *tfm,
+                            const u8 *src, unsigned int slen,
+                            u8 *dst, unsigned int *dlen)
+{
+	return tfm->__crt_alg->cra_compress.coa_compress(crypto_tfm_ctx(tfm),
+	                                                 src, slen, dst,
+	                                                 dlen);
+}
+
+static int crypto_decompress(struct crypto_tfm *tfm,
+                             const u8 *src, unsigned int slen,
+                             u8 *dst, unsigned int *dlen)
+{
+	return tfm->__crt_alg->cra_compress.coa_decompress(crypto_tfm_ctx(tfm),
+	                                                   src, slen, dst,
+	                                                   dlen);
+}
+
+int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	return flags ? -EINVAL : 0;
+}
+
+int crypto_init_compress_ops(struct crypto_tfm *tfm)
+{
+	int ret = 0;
+	struct compress_tfm *ops = &tfm->crt_compress;
+	
+	ret = tfm->__crt_alg->cra_compress.coa_init(crypto_tfm_ctx(tfm));
+	if (ret)
+		goto out;
+
+	ops->cot_compress = crypto_compress;
+	ops->cot_decompress = crypto_decompress;
+	
+out:
+	return ret;
+}
+
+void crypto_exit_compress_ops(struct crypto_tfm *tfm)
+{
+	tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm));
+}
diff -urN linux-2.4.22-pre2/crypto/crypto_null.c linux-2.4.22-pre3/crypto/crypto_null.c
--- linux-2.4.22-pre2/crypto/crypto_null.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/crypto_null.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,134 @@
+/* 
+ * Cryptographic API.
+ *
+ * Null algorithms, aka Much Ado About Nothing.
+ *
+ * These are needed for IPsec, and may be useful in general for
+ * testing & debugging.
+ * 
+ * The null cipher is compliant with RFC2410.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <linux/crypto.h>
+
+#define NULL_KEY_SIZE		0
+#define NULL_BLOCK_SIZE		1
+#define NULL_DIGEST_SIZE	0
+
+static int null_compress(void *ctx, const u8 *src, unsigned int slen,
+                         u8 *dst, unsigned int *dlen)
+{ return 0; }
+
+static int null_decompress(void *ctx, const u8 *src, unsigned int slen,
+                           u8 *dst, unsigned int *dlen)
+{ return 0; }
+
+static void null_init(void *ctx)
+{ }
+
+static void null_update(void *ctx, const u8 *data, unsigned int len)
+{ }
+
+static void null_final(void *ctx, u8 *out)
+{ }
+
+static int null_setkey(void *ctx, const u8 *key,
+                       unsigned int keylen, u32 *flags)
+{ return 0; }
+
+static void null_encrypt(void *ctx, u8 *dst, const u8 *src)
+{ }
+
+static void null_decrypt(void *ctx, u8 *dst, const u8 *src)
+{ }
+
+static struct crypto_alg compress_null = {
+	.cra_name		=	"compress_null",
+	.cra_flags		=	CRYPTO_ALG_TYPE_COMPRESS,
+	.cra_blocksize		=	NULL_BLOCK_SIZE,
+	.cra_ctxsize		=	0,
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=       LIST_HEAD_INIT(compress_null.cra_list),
+	.cra_u			=	{ .compress = {
+	.coa_compress 		=	null_compress,
+	.coa_decompress		=	null_decompress } }
+};
+
+static struct crypto_alg digest_null = {
+	.cra_name		=	"digest_null",
+	.cra_flags		=	CRYPTO_ALG_TYPE_DIGEST,
+	.cra_blocksize		=	NULL_BLOCK_SIZE,
+	.cra_ctxsize		=	0,
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=       LIST_HEAD_INIT(digest_null.cra_list),	
+	.cra_u			=	{ .digest = {
+	.dia_digestsize		=	NULL_DIGEST_SIZE,
+	.dia_init   		=	null_init,
+	.dia_update 		=	null_update,
+	.dia_final  		=	null_final } }
+};
+
+static struct crypto_alg cipher_null = {
+	.cra_name		=	"cipher_null",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	NULL_BLOCK_SIZE,
+	.cra_ctxsize		=	0,
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(cipher_null.cra_list),
+	.cra_u			=	{ .cipher = {
+	.cia_min_keysize	=	NULL_KEY_SIZE,
+	.cia_max_keysize	=	NULL_KEY_SIZE,
+	.cia_ivsize		=	0,
+	.cia_setkey		= 	null_setkey,
+	.cia_encrypt		=	null_encrypt,
+	.cia_decrypt		=	null_decrypt } }
+};
+
+static int __init init(void)
+{
+	int ret = 0;
+	
+	ret = crypto_register_alg(&cipher_null);
+	if (ret < 0)
+		goto out;
+
+	ret = crypto_register_alg(&digest_null);
+	if (ret < 0) {
+		crypto_unregister_alg(&cipher_null);
+		goto out;
+	}
+
+	ret = crypto_register_alg(&compress_null);
+	if (ret < 0) {
+		crypto_unregister_alg(&digest_null);
+		crypto_unregister_alg(&cipher_null);
+		goto out;
+	}
+
+out:	
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&compress_null);
+	crypto_unregister_alg(&digest_null);
+	crypto_unregister_alg(&cipher_null);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Null Cryptographic Algorithms");
diff -urN linux-2.4.22-pre2/crypto/deflate.c linux-2.4.22-pre3/crypto/deflate.c
--- linux-2.4.22-pre2/crypto/deflate.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/deflate.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,236 @@
+/* 
+ * Cryptographic API.
+ *
+ * Deflate algorithm (RFC 1951), implemented here primarily for use
+ * by IPCOMP (RFC 3173 & RFC 2394).
+ *
+ * Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ * FIXME: deflate transforms will require up to a total of about 436k of kernel
+ * memory on i386 (390k for compression, the rest for decompression), as the
+ * current zlib kernel code uses a worst case pre-allocation system by default.
+ * This needs to be fixed so that the amount of memory required is properly
+ * related to the  winbits and memlevel parameters.
+ *
+ * The default winbits of 11 should suit most packets, and it may be something
+ * to configure on a per-tfm basis in the future.
+ *
+ * Currently, compression history is not maintained between tfm calls, as
+ * it is not needed for IPCOMP and keeps the code simpler.  It can be
+ * implemented if someone wants it.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/zlib.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/net.h>
+#include <linux/slab.h>
+
+#define DEFLATE_DEF_LEVEL		Z_DEFAULT_COMPRESSION
+#define DEFLATE_DEF_WINBITS		11
+#define DEFLATE_DEF_MEMLEVEL		MAX_MEM_LEVEL
+
+struct deflate_ctx {
+	int comp_initialized;
+	int decomp_initialized;
+	struct z_stream_s comp_stream;
+	struct z_stream_s decomp_stream;
+};
+
+static inline int deflate_gfp(void)
+{
+	return in_softirq() ? GFP_ATOMIC : GFP_KERNEL;
+}
+
+static int deflate_init(void *ctx)
+{
+	return 0;
+}
+
+static void deflate_exit(void *ctx)
+{
+	struct deflate_ctx *dctx = ctx;
+
+	if (dctx->comp_initialized)
+		vfree(dctx->comp_stream.workspace);
+	if (dctx->decomp_initialized)
+		kfree(dctx->decomp_stream.workspace);
+}
+
+/*
+ * Lazy initialization to make interface simple without allocating
+ * un-needed workspaces.  Thus can be called in softirq context.
+ */
+static int deflate_comp_init(struct deflate_ctx *ctx)
+{
+	int ret = 0;
+	struct z_stream_s *stream = &ctx->comp_stream;
+
+	stream->workspace = __vmalloc(zlib_deflate_workspacesize(),
+	                              deflate_gfp()|__GFP_HIGHMEM,
+	                              PAGE_KERNEL);
+	if (!stream->workspace ) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	memset(stream->workspace, 0, zlib_deflate_workspacesize());
+	ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED,
+	                        -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
+	                        Z_DEFAULT_STRATEGY);
+	if (ret != Z_OK) {
+		ret = -EINVAL;
+		goto out_free;
+	}
+	ctx->comp_initialized = 1;
+out:	
+	return ret;
+out_free:
+	vfree(stream->workspace);
+	goto out;
+}
+
+static int deflate_decomp_init(struct deflate_ctx *ctx)
+{
+	int ret = 0;
+	struct z_stream_s *stream = &ctx->decomp_stream;
+
+	stream->workspace = kmalloc(zlib_inflate_workspacesize(),
+	                            deflate_gfp());
+	if (!stream->workspace ) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	memset(stream->workspace, 0, zlib_inflate_workspacesize());
+	ret = zlib_inflateInit2(stream, -DEFLATE_DEF_WINBITS);
+	if (ret != Z_OK) {
+		ret = -EINVAL;
+		goto out_free;
+	}
+	ctx->decomp_initialized = 1;
+out:
+	return ret;
+out_free:
+	kfree(stream->workspace);
+	goto out;
+}
+
+static int deflate_compress(void *ctx, const u8 *src, unsigned int slen,
+	                    u8 *dst, unsigned int *dlen)
+{
+	int ret = 0;
+	struct deflate_ctx *dctx = ctx;
+	struct z_stream_s *stream = &dctx->comp_stream;
+
+	if (!dctx->comp_initialized) {
+		ret = deflate_comp_init(dctx);
+		if (ret)
+			goto out;
+	}
+
+	ret = zlib_deflateReset(stream);
+	if (ret != Z_OK) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	stream->next_in = (u8 *)src;
+	stream->avail_in = slen;
+	stream->next_out = (u8 *)dst;
+	stream->avail_out = *dlen;
+
+	ret = zlib_deflate(stream, Z_FINISH);
+	if (ret != Z_STREAM_END) {
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = 0;
+	*dlen = stream->total_out;
+out:
+	return ret;
+}
+ 
+static int deflate_decompress(void *ctx, const u8 *src, unsigned int slen,
+                              u8 *dst, unsigned int *dlen)
+{
+	
+	int ret = 0;
+	struct deflate_ctx *dctx = ctx;
+	struct z_stream_s *stream = &dctx->decomp_stream;
+
+	if (!dctx->decomp_initialized) {
+		ret = deflate_decomp_init(dctx);
+		if (ret)
+			goto out;
+	}
+
+	ret = zlib_inflateReset(stream);
+	if (ret != Z_OK) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	stream->next_in = (u8 *)src;
+	stream->avail_in = slen;
+	stream->next_out = (u8 *)dst;
+	stream->avail_out = *dlen;
+
+	ret = zlib_inflate(stream, Z_SYNC_FLUSH);
+	/*
+	 * Work around a bug in zlib, which sometimes wants to taste an extra
+	 * byte when being used in the (undocumented) raw deflate mode.
+	 * (From USAGI).
+	 */
+	if (ret == Z_OK && !stream->avail_in && stream->avail_out) {
+		u8 zerostuff = 0;
+		stream->next_in = &zerostuff;
+		stream->avail_in = 1; 
+		ret = zlib_inflate(stream, Z_FINISH);
+	}
+	if (ret != Z_STREAM_END) {
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = 0;
+	*dlen = stream->total_out;
+out:
+	return ret;
+}
+
+static struct crypto_alg alg = {
+	.cra_name		= "deflate",
+	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
+	.cra_ctxsize		= sizeof(struct deflate_ctx),
+	.cra_module		= THIS_MODULE,
+	.cra_list		= LIST_HEAD_INIT(alg.cra_list),
+	.cra_u			= { .compress = {
+	.coa_init		= deflate_init,
+	.coa_exit		= deflate_exit,
+	.coa_compress 		= deflate_compress,
+	.coa_decompress  	= deflate_decompress } }
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Deflate Compression Algorithm for IPCOMP");
+MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
+
diff -urN linux-2.4.22-pre2/crypto/des.c linux-2.4.22-pre3/crypto/des.c
--- linux-2.4.22-pre2/crypto/des.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/des.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,1299 @@
+/* 
+ * Cryptographic API.
+ *
+ * DES & Triple DES EDE Cipher Algorithms.
+ *
+ * Originally released as descore by Dana L. How <how@isl.stanford.edu>.
+ * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel.
+ * Derived from Cryptoapi and Nettle implementations, adapted for in-place
+ * scatterlist interface.  Changed LGPL to GPL per section 3 of the LGPL.
+ *
+ * Copyright (c) 1992 Dana L. How.
+ * Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de> 
+ * Copyright (c) Gisle Sælensminde <gisle@ii.uib.no>
+ * Copyright (C) 2001 Niels Möller.
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <asm/scatterlist.h>
+#include <linux/crypto.h>
+
+#define DES_KEY_SIZE		8
+#define DES_EXPKEY_WORDS	32
+#define DES_BLOCK_SIZE		8
+
+#define DES3_EDE_KEY_SIZE	(3 * DES_KEY_SIZE)
+#define DES3_EDE_EXPKEY_WORDS	(3 * DES_EXPKEY_WORDS)
+#define DES3_EDE_BLOCK_SIZE	DES_BLOCK_SIZE
+
+#define ROR(d,c,o)	((d) = (d) >> (c) | (d) << (o))
+
+struct des_ctx {
+	u8 iv[DES_BLOCK_SIZE];
+	u32 expkey[DES_EXPKEY_WORDS];
+};
+
+struct des3_ede_ctx {
+	u8 iv[DES_BLOCK_SIZE];
+	u32 expkey[DES3_EDE_EXPKEY_WORDS];
+};
+
+static const u32 des_keymap[] = {
+	0x02080008, 0x02082000, 0x00002008, 0x00000000,
+	0x02002000, 0x00080008, 0x02080000, 0x02082008,
+	0x00000008, 0x02000000, 0x00082000, 0x00002008,
+	0x00082008, 0x02002008, 0x02000008, 0x02080000,
+	0x00002000, 0x00082008, 0x00080008, 0x02002000,
+	0x02082008, 0x02000008, 0x00000000, 0x00082000,
+	0x02000000, 0x00080000, 0x02002008, 0x02080008,
+	0x00080000, 0x00002000, 0x02082000, 0x00000008,
+	0x00080000, 0x00002000, 0x02000008, 0x02082008,
+	0x00002008, 0x02000000, 0x00000000, 0x00082000,
+	0x02080008, 0x02002008, 0x02002000, 0x00080008,
+	0x02082000, 0x00000008, 0x00080008, 0x02002000,
+	0x02082008, 0x00080000, 0x02080000, 0x02000008,
+	0x00082000, 0x00002008, 0x02002008, 0x02080000,
+	0x00000008, 0x02082000, 0x00082008, 0x00000000,
+	0x02000000, 0x02080008, 0x00002000, 0x00082008,
+
+	0x08000004, 0x00020004, 0x00000000, 0x08020200,
+	0x00020004, 0x00000200, 0x08000204, 0x00020000,
+	0x00000204, 0x08020204, 0x00020200, 0x08000000,
+	0x08000200, 0x08000004, 0x08020000, 0x00020204,
+	0x00020000, 0x08000204, 0x08020004, 0x00000000,
+	0x00000200, 0x00000004, 0x08020200, 0x08020004,
+	0x08020204, 0x08020000, 0x08000000, 0x00000204,
+	0x00000004, 0x00020200, 0x00020204, 0x08000200,
+	0x00000204, 0x08000000, 0x08000200, 0x00020204,
+	0x08020200, 0x00020004, 0x00000000, 0x08000200,
+	0x08000000, 0x00000200, 0x08020004, 0x00020000,
+	0x00020004, 0x08020204, 0x00020200, 0x00000004,
+	0x08020204, 0x00020200, 0x00020000, 0x08000204,
+	0x08000004, 0x08020000, 0x00020204, 0x00000000,
+	0x00000200, 0x08000004, 0x08000204, 0x08020200,
+	0x08020000, 0x00000204, 0x00000004, 0x08020004,
+
+	0x80040100, 0x01000100, 0x80000000, 0x81040100,
+	0x00000000, 0x01040000, 0x81000100, 0x80040000,
+	0x01040100, 0x81000000, 0x01000000, 0x80000100,
+	0x81000000, 0x80040100, 0x00040000, 0x01000000,
+	0x81040000, 0x00040100, 0x00000100, 0x80000000,
+	0x00040100, 0x81000100, 0x01040000, 0x00000100,
+	0x80000100, 0x00000000, 0x80040000, 0x01040100,
+	0x01000100, 0x81040000, 0x81040100, 0x00040000,
+	0x81040000, 0x80000100, 0x00040000, 0x81000000,
+	0x00040100, 0x01000100, 0x80000000, 0x01040000,
+	0x81000100, 0x00000000, 0x00000100, 0x80040000,
+	0x00000000, 0x81040000, 0x01040100, 0x00000100,
+	0x01000000, 0x81040100, 0x80040100, 0x00040000,
+	0x81040100, 0x80000000, 0x01000100, 0x80040100,
+	0x80040000, 0x00040100, 0x01040000, 0x81000100,
+	0x80000100, 0x01000000, 0x81000000, 0x01040100,
+
+	0x04010801, 0x00000000, 0x00010800, 0x04010000,
+	0x04000001, 0x00000801, 0x04000800, 0x00010800,
+	0x00000800, 0x04010001, 0x00000001, 0x04000800,
+	0x00010001, 0x04010800, 0x04010000, 0x00000001,
+	0x00010000, 0x04000801, 0x04010001, 0x00000800,
+	0x00010801, 0x04000000, 0x00000000, 0x00010001,
+	0x04000801, 0x00010801, 0x04010800, 0x04000001,
+	0x04000000, 0x00010000, 0x00000801, 0x04010801,
+	0x00010001, 0x04010800, 0x04000800, 0x00010801,
+	0x04010801, 0x00010001, 0x04000001, 0x00000000,
+	0x04000000, 0x00000801, 0x00010000, 0x04010001,
+	0x00000800, 0x04000000, 0x00010801, 0x04000801,
+	0x04010800, 0x00000800, 0x00000000, 0x04000001,
+	0x00000001, 0x04010801, 0x00010800, 0x04010000,
+	0x04010001, 0x00010000, 0x00000801, 0x04000800,
+	0x04000801, 0x00000001, 0x04010000, 0x00010800,
+
+	0x00000400, 0x00000020, 0x00100020, 0x40100000,
+	0x40100420, 0x40000400, 0x00000420, 0x00000000,
+	0x00100000, 0x40100020, 0x40000020, 0x00100400,
+	0x40000000, 0x00100420, 0x00100400, 0x40000020,
+	0x40100020, 0x00000400, 0x40000400, 0x40100420,
+	0x00000000, 0x00100020, 0x40100000, 0x00000420,
+	0x40100400, 0x40000420, 0x00100420, 0x40000000,
+	0x40000420, 0x40100400, 0x00000020, 0x00100000,
+	0x40000420, 0x00100400, 0x40100400, 0x40000020,
+	0x00000400, 0x00000020, 0x00100000, 0x40100400,
+	0x40100020, 0x40000420, 0x00000420, 0x00000000,
+	0x00000020, 0x40100000, 0x40000000, 0x00100020,
+	0x00000000, 0x40100020, 0x00100020, 0x00000420,
+	0x40000020, 0x00000400, 0x40100420, 0x00100000,
+	0x00100420, 0x40000000, 0x40000400, 0x40100420,
+	0x40100000, 0x00100420, 0x00100400, 0x40000400,
+
+	0x00800000, 0x00001000, 0x00000040, 0x00801042,
+	0x00801002, 0x00800040, 0x00001042, 0x00801000,
+	0x00001000, 0x00000002, 0x00800002, 0x00001040,
+	0x00800042, 0x00801002, 0x00801040, 0x00000000,
+	0x00001040, 0x00800000, 0x00001002, 0x00000042,
+	0x00800040, 0x00001042, 0x00000000, 0x00800002,
+	0x00000002, 0x00800042, 0x00801042, 0x00001002,
+	0x00801000, 0x00000040, 0x00000042, 0x00801040,
+	0x00801040, 0x00800042, 0x00001002, 0x00801000,
+	0x00001000, 0x00000002, 0x00800002, 0x00800040,
+	0x00800000, 0x00001040, 0x00801042, 0x00000000,
+	0x00001042, 0x00800000, 0x00000040, 0x00001002,
+	0x00800042, 0x00000040, 0x00000000, 0x00801042,
+	0x00801002, 0x00801040, 0x00000042, 0x00001000,
+	0x00001040, 0x00801002, 0x00800040, 0x00000042,
+	0x00000002, 0x00001042, 0x00801000, 0x00800002,
+
+	0x10400000, 0x00404010, 0x00000010, 0x10400010,
+	0x10004000, 0x00400000, 0x10400010, 0x00004010,
+	0x00400010, 0x00004000, 0x00404000, 0x10000000,
+	0x10404010, 0x10000010, 0x10000000, 0x10404000,
+	0x00000000, 0x10004000, 0x00404010, 0x00000010,
+	0x10000010, 0x10404010, 0x00004000, 0x10400000,
+	0x10404000, 0x00400010, 0x10004010, 0x00404000,
+	0x00004010, 0x00000000, 0x00400000, 0x10004010,
+	0x00404010, 0x00000010, 0x10000000, 0x00004000,
+	0x10000010, 0x10004000, 0x00404000, 0x10400010,
+	0x00000000, 0x00404010, 0x00004010, 0x10404000,
+	0x10004000, 0x00400000, 0x10404010, 0x10000000,
+	0x10004010, 0x10400000, 0x00400000, 0x10404010,
+	0x00004000, 0x00400010, 0x10400010, 0x00004010,
+	0x00400010, 0x00000000, 0x10404000, 0x10000010,
+	0x10400000, 0x10004010, 0x00000010, 0x00404000,
+
+	0x00208080, 0x00008000, 0x20200000, 0x20208080,
+	0x00200000, 0x20008080, 0x20008000, 0x20200000,
+	0x20008080, 0x00208080, 0x00208000, 0x20000080,
+	0x20200080, 0x00200000, 0x00000000, 0x20008000,
+	0x00008000, 0x20000000, 0x00200080, 0x00008080,
+	0x20208080, 0x00208000, 0x20000080, 0x00200080,
+	0x20000000, 0x00000080, 0x00008080, 0x20208000,
+	0x00000080, 0x20200080, 0x20208000, 0x00000000,
+	0x00000000, 0x20208080, 0x00200080, 0x20008000,
+	0x00208080, 0x00008000, 0x20000080, 0x00200080,
+	0x20208000, 0x00000080, 0x00008080, 0x20200000,
+	0x20008080, 0x20000000, 0x20200000, 0x00208000,
+	0x20208080, 0x00008080, 0x00208000, 0x20200080,
+	0x00200000, 0x20000080, 0x20008000, 0x00000000,
+	0x00008000, 0x00200000, 0x20200080, 0x00208080,
+	0x20000000, 0x20208000, 0x00000080, 0x20008080,
+};
+
+static const u8 rotors[] = {
+	34, 13,  5, 46, 47, 18, 32, 41, 11, 53, 33, 20,
+	14, 36, 30, 24, 49,  2, 15, 37, 42, 50,  0, 21,
+	38, 48,  6, 26, 39,  4, 52, 25, 12, 27, 31, 40,
+	1, 17, 28, 29, 23, 51, 35,  7,  3, 22,  9, 43,
+
+	41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27,
+	21, 43, 37,  0,  1,  9, 22, 44, 49,  2,  7, 28,
+	45, 55, 13, 33, 46, 11,  6, 32, 19, 34, 38, 47,
+	8, 24, 35, 36, 30,  3, 42, 14, 10, 29, 16, 50,
+
+	55, 34, 26, 38, 11, 39, 53,  5, 32, 45, 54, 41,
+	35,  2, 51, 14, 15, 23, 36,  3,  8, 16, 21, 42,
+	6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52,  4,
+	22,  7, 49, 50, 44, 17,  1, 28, 24, 43, 30,  9,
+
+	12, 48, 40, 52, 25, 53, 38, 19, 46,  6, 11, 55,
+	49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35,  1,
+	20, 26, 41,  4, 45, 39, 34, 31, 47,  5, 13, 18,
+	36, 21,  8,  9,  3,  0, 15, 42,  7,  2, 44, 23,
+
+	26,  5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12,
+	8, 30, 24, 42, 43, 51,  9,  0, 36, 44, 49, 15,
+	34, 40, 55, 18,  6, 53, 48, 45,  4, 19, 27, 32,
+	50, 35, 22, 23, 17, 14, 29,  1, 21, 16,  3, 37,
+
+	40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26,
+	22, 44,  7,  1,  2, 10, 23, 14, 50,  3,  8, 29,
+	48, 54, 12, 32, 20, 38,  5,  6, 18, 33, 41, 46,
+	9, 49, 36, 37,  0, 28, 43, 15, 35, 30, 17, 51,
+
+	54, 33, 25, 41, 38, 13, 27,  4,  6, 48, 53, 40,
+	36,  3, 21, 15, 16, 24, 37, 28,  9, 17, 22, 43,
+	5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31,
+	23,  8, 50, 51, 14, 42,  2, 29, 49, 44,  0, 10,
+
+	11, 47, 39, 55, 52, 27, 41, 18, 20,  5, 38, 54,
+	50, 17, 35, 29, 30,  7, 51, 42, 23,  0, 36,  2,
+	19, 25, 40, 31, 48, 13, 33, 34, 46,  4, 12, 45,
+	37, 22,  9, 10, 28,  1, 16, 43,  8,  3, 14, 24,
+
+	18, 54, 46,  5,  6, 34, 48, 25, 27, 12, 45,  4,
+	2, 24, 42, 36, 37, 14,  3, 49, 30,  7, 43,  9,
+	26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52,
+	44, 29, 16, 17, 35,  8, 23, 50, 15, 10, 21,  0,
+
+	32, 11, 31, 19, 20, 48,  5, 39, 41, 26,  6, 18,
+	16,  7,  1, 50, 51, 28, 17,  8, 44, 21,  2, 23,
+	40, 46,  4, 52, 12, 34, 54, 55, 38, 25, 33, 13,
+	3, 43, 30,  0, 49, 22, 37,  9, 29, 24, 35, 14,
+
+	46, 25, 45, 33, 34,  5, 19, 53, 55, 40, 20, 32,
+	30, 21, 15,  9, 10, 42,  0, 22,  3, 35, 16, 37,
+	54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27,
+	17,  2, 44, 14,  8, 36, 51, 23, 43,  7, 49, 28,
+
+	31, 39,  6, 47, 48, 19, 33, 38, 12, 54, 34, 46,
+	44, 35, 29, 23, 24,  1, 14, 36, 17, 49, 30, 51,
+	11, 45, 32, 27, 40,  5, 25, 26, 13, 53,  4, 41,
+	0, 16,  3, 28, 22, 50, 10, 37,  2, 21,  8, 42,
+
+	45, 53, 20,  4,  5, 33, 47, 52, 26, 11, 48, 31,
+	3, 49, 43, 37,  7, 15, 28, 50,  0,  8, 44, 10,
+	25,  6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55,
+	14, 30, 17, 42, 36,  9, 24, 51, 16, 35, 22,  1,
+
+	6, 38, 34, 18, 19, 47,  4, 13, 40, 25,  5, 45,
+	17,  8,  2, 51, 21, 29, 42,  9, 14, 22,  3, 24,
+	39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12,
+	28, 44,  0,  1, 50, 23,  7, 10, 30, 49, 36, 15,
+
+	20, 52, 48, 32, 33,  4, 18, 27, 54, 39, 19,  6,
+	0, 22, 16, 10, 35, 43,  1, 23, 28, 36, 17,  7,
+	53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26,
+	42,  3, 14, 15,  9, 37, 21, 24, 44,  8, 50, 29,
+
+	27,  6, 55, 39, 40, 11, 25, 34,  4, 46, 26, 13,
+	7, 29, 23, 17, 42, 50,  8, 30, 35, 43, 24, 14,
+	31, 41, 52, 19, 32, 54, 45, 18,  5, 20, 53, 33,
+	49, 10, 21, 22, 16, 44, 28,  0, 51, 15,  2, 36,
+};
+
+static const u8 parity[] = {
+	8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3,
+	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+	4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8,
+};
+
+
+static void des_small_fips_encrypt(u32 *expkey, u8 *dst, const u8 *src)
+{
+	u32 x, y, z;
+	
+	x  = src[7];
+	x <<= 8;
+	x |= src[6];
+	x <<= 8;
+	x |= src[5];
+	x <<= 8;
+	x |= src[4];
+	y  = src[3];
+	y <<= 8;
+	y |= src[2];
+	y <<= 8;
+	y |= src[1];
+	y <<= 8;
+	y |= src[0];
+	z  = ((x >> 004) ^ y) & 0x0F0F0F0FL;
+	x ^= z << 004;
+	y ^= z;
+	z  = ((y >> 020) ^ x) & 0x0000FFFFL;
+	y ^= z << 020;
+	x ^= z;
+	z  = ((x >> 002) ^ y) & 0x33333333L;
+	x ^= z << 002;
+	y ^= z;
+	z  = ((y >> 010) ^ x) & 0x00FF00FFL;
+	y ^= z << 010;
+	x ^= z;
+	x  = x >> 1 | x << 31;
+	z  = (x ^ y) & 0x55555555L;
+	y ^= z;
+	x ^= z;
+	y  = y >> 1 | y << 31;
+	z  = expkey[0];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[1];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[2];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[3];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[4];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[5];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[6];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[7];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[8];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[9];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[10];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[11];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[12];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[13];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[14];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[15];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[16];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[17];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[18];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[19];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[20];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[21];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[22];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[23];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[24];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[25];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[26];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[27];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[28];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[29];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[30];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[31];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	x  = x << 1 | x >> 31;
+	z  = (x ^ y) & 0x55555555L;
+	y ^= z;
+	x ^= z;
+	y  = y << 1 | y >> 31;
+	z  = ((x >> 010) ^ y) & 0x00FF00FFL;
+	x ^= z << 010;
+	y ^= z;
+	z  = ((y >> 002) ^ x) & 0x33333333L;
+	y ^= z << 002;
+	x ^= z;
+	z  = ((x >> 020) ^ y) & 0x0000FFFFL;
+	x ^= z << 020;
+	y ^= z;
+	z  = ((y >> 004) ^ x) & 0x0F0F0F0FL;
+	y ^= z << 004;
+	x ^= z;
+	dst[0] = x;
+	x >>= 8;
+	dst[1] = x;
+	x >>= 8;
+	dst[2] = x;
+	x >>= 8;
+	dst[3] = x;
+	dst[4] = y;
+	y >>= 8;
+	dst[5] = y;
+	y >>= 8;
+	dst[6] = y;
+	y >>= 8;
+	dst[7] = y;
+}
+
+static void des_small_fips_decrypt(u32 *expkey, u8 *dst, const u8 *src)
+{
+	u32 x, y, z;
+	
+	x  = src[7];
+	x <<= 8;
+	x |= src[6];
+	x <<= 8;
+	x |= src[5];
+	x <<= 8;
+	x |= src[4];
+	y  = src[3];
+	y <<= 8;
+	y |= src[2];
+	y <<= 8;
+	y |= src[1];
+	y <<= 8;
+	y |= src[0];
+	z  = ((x >> 004) ^ y) & 0x0F0F0F0FL;
+	x ^= z << 004;
+	y ^= z;
+	z  = ((y >> 020) ^ x) & 0x0000FFFFL;
+	y ^= z << 020;
+	x ^= z;
+	z  = ((x >> 002) ^ y) & 0x33333333L;
+	x ^= z << 002;
+	y ^= z;
+	z  = ((y >> 010) ^ x) & 0x00FF00FFL;
+	y ^= z << 010;
+	x ^= z;
+	x  = x >> 1 | x << 31;
+	z  = (x ^ y) & 0x55555555L;
+	y ^= z;
+	x ^= z;
+	y  = y >> 1 | y << 31;
+	z  = expkey[31];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[30];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[29];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[28];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[27];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[26];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[25];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[24];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[23];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[22];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[21];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[20];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[19];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[18];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[17];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[16];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[15];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[14];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[13];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[12];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[11];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[10];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[9];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[8];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[7];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[6];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[5];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[4];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[3];
+	z ^= y;
+	z  = z << 4 | z >> 28;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[2];
+	z ^= y;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	z  = expkey[1];
+	z ^= x;
+	z  = z << 4 | z >> 28;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+	z  = expkey[0];
+	z ^= x;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+	z >>= 8;
+	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+	x  = x << 1 | x >> 31;
+	z  = (x ^ y) & 0x55555555L;
+	y ^= z;
+	x ^= z;
+	y  = y << 1 | y >> 31;
+	z  = ((x >> 010) ^ y) & 0x00FF00FFL;
+	x ^= z << 010;
+	y ^= z;
+	z  = ((y >> 002) ^ x) & 0x33333333L;
+	y ^= z << 002;
+	x ^= z;
+	z  = ((x >> 020) ^ y) & 0x0000FFFFL;
+	x ^= z << 020;
+	y ^= z;
+	z  = ((y >> 004) ^ x) & 0x0F0F0F0FL;
+	y ^= z << 004;
+	x ^= z;
+	dst[0] = x;
+	x >>= 8;
+	dst[1] = x;
+	x >>= 8;
+	dst[2] = x;
+	x >>= 8;
+	dst[3] = x;
+	dst[4] = y;
+	y >>= 8;
+	dst[5] = y;
+	y >>= 8;
+	dst[6] = y;
+	y >>= 8;
+	dst[7] = y;
+}
+
+/*
+ * RFC2451: Weak key checks SHOULD be performed.
+ */
+static int setkey(u32 *expkey, const u8 *key, unsigned int keylen, u32 *flags)
+{
+	const u8 *k;
+	u8 *b0, *b1;
+	u32 n, w;
+	u8 bits0[56], bits1[56];
+
+	n  = parity[key[0]]; n <<= 4;
+	n |= parity[key[1]]; n <<= 4;
+	n |= parity[key[2]]; n <<= 4;
+	n |= parity[key[3]]; n <<= 4;
+	n |= parity[key[4]]; n <<= 4;
+	n |= parity[key[5]]; n <<= 4;
+	n |= parity[key[6]]; n <<= 4;
+	n |= parity[key[7]];
+	w = 0x88888888L;
+	
+	if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY)
+	    && !((n - (w >> 3)) & w)) {  /* 1 in 10^10 keys passes this test */
+		if (n < 0x41415151) {
+			if (n < 0x31312121) {
+				if (n < 0x14141515) {
+					/* 01 01 01 01 01 01 01 01 */
+					if (n == 0x11111111) goto weak;
+					/* 01 1F 01 1F 01 0E 01 0E */
+					if (n == 0x13131212) goto weak;
+				} else {
+					/* 01 E0 01 E0 01 F1 01 F1 */
+					if (n == 0x14141515) goto weak;
+					/* 01 FE 01 FE 01 FE 01 FE */
+					if (n == 0x16161616) goto weak;
+				}
+			} else {
+				if (n < 0x34342525) {
+					/* 1F 01 1F 01 0E 01 0E 01 */
+					if (n == 0x31312121) goto weak;
+					/* 1F 1F 1F 1F 0E 0E 0E 0E (?) */
+					if (n == 0x33332222) goto weak;
+				} else {
+					/* 1F E0 1F E0 0E F1 0E F1 */
+					if (n == 0x34342525) goto weak;
+					/* 1F FE 1F FE 0E FE 0E FE */
+					if (n == 0x36362626) goto weak;
+				}
+			}
+		} else {
+			if (n < 0x61616161) {
+				if (n < 0x44445555) {
+					/* E0 01 E0 01 F1 01 F1 01 */
+					if (n == 0x41415151) goto weak;
+					/* E0 1F E0 1F F1 0E F1 0E */
+					if (n == 0x43435252) goto weak;
+				} else {
+					/* E0 E0 E0 E0 F1 F1 F1 F1 (?) */
+					if (n == 0x44445555) goto weak;
+					/* E0 FE E0 FE F1 FE F1 FE */
+					if (n == 0x46465656) goto weak;
+				}
+			} else {
+				if (n < 0x64646565) {
+					/* FE 01 FE 01 FE 01 FE 01 */
+					if (n == 0x61616161) goto weak;
+					/* FE 1F FE 1F FE 0E FE 0E */
+					if (n == 0x63636262) goto weak;
+				} else {
+					/* FE E0 FE E0 FE F1 FE F1 */
+					if (n == 0x64646565) goto weak;
+					/* FE FE FE FE FE FE FE FE */
+					if (n == 0x66666666) goto weak;
+				}
+			}
+		}
+	
+		goto not_weak;
+weak:
+		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
+		return -EINVAL;
+	}
+
+not_weak:
+
+	/* explode the bits */
+	n = 56;
+	b0 = bits0;
+	b1 = bits1;
+	
+	do {
+		w = (256 | *key++) << 2;
+		do {
+			--n;
+			b1[n] = 8 & w;
+			w >>= 1;
+			b0[n] = 4 & w;
+		} while ( w >= 16 );
+	} while ( n );
+	
+	/* put the bits in the correct places */
+	n = 16;
+	k = rotors;
+	
+	do {
+		w   = (b1[k[ 0   ]] | b0[k[ 1   ]]) << 4;
+		w  |= (b1[k[ 2   ]] | b0[k[ 3   ]]) << 2;
+		w  |=  b1[k[ 4   ]] | b0[k[ 5   ]];
+		w <<= 8;
+		w  |= (b1[k[ 6   ]] | b0[k[ 7   ]]) << 4;
+		w  |= (b1[k[ 8   ]] | b0[k[ 9   ]]) << 2;
+		w  |=  b1[k[10   ]] | b0[k[11   ]];
+		w <<= 8;
+		w  |= (b1[k[12   ]] | b0[k[13   ]]) << 4;
+		w  |= (b1[k[14   ]] | b0[k[15   ]]) << 2;
+		w  |=  b1[k[16   ]] | b0[k[17   ]];
+		w <<= 8;
+		w  |= (b1[k[18   ]] | b0[k[19   ]]) << 4;
+		w  |= (b1[k[20   ]] | b0[k[21   ]]) << 2;
+		w  |=  b1[k[22   ]] | b0[k[23   ]];
+		expkey[0] = w;
+		
+		w   = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
+		w  |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
+		w  |=  b1[k[ 4+24]] | b0[k[ 5+24]];
+		w <<= 8;
+		w  |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
+		w  |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
+		w  |=  b1[k[10+24]] | b0[k[11+24]];
+		w <<= 8;
+		w  |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
+		w  |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
+		w  |=  b1[k[16+24]] | b0[k[17+24]];
+		w <<= 8;
+		w  |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
+		w  |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
+		w  |=  b1[k[22+24]] | b0[k[23+24]];
+		
+		ROR(w, 4, 28);      /* could be eliminated */
+		expkey[1] = w;
+
+		k += 48;
+		expkey += 2;
+	} while (--n);
+
+	return 0;
+}
+
+static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+{
+	return setkey(((struct des_ctx *)ctx)->expkey, key, keylen, flags);
+}
+
+static void des_encrypt(void *ctx, u8 *dst, const u8 *src)
+{
+	des_small_fips_encrypt(((struct des_ctx *)ctx)->expkey, dst, src);
+}
+
+static void des_decrypt(void *ctx, u8 *dst, const u8 *src)
+{
+	des_small_fips_decrypt(((struct des_ctx *)ctx)->expkey, dst, src);
+}
+
+/* 
+ * RFC2451:
+ *
+ *   For DES-EDE3, there is no known need to reject weak or
+ *   complementation keys.  Any weakness is obviated by the use of
+ *   multiple keys.
+ *
+ *   However, if the first two or last two independent 64-bit keys are
+ *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
+ *   same as DES.  Implementers MUST reject keys that exhibit this
+ *   property.
+ *
+ */
+static int des3_ede_setkey(void *ctx, const u8 *key,
+                           unsigned int keylen, u32 *flags)
+{
+	unsigned int i, off;
+	struct des3_ede_ctx *dctx = ctx;
+
+	if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && 
+	    memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
+	    					DES_KEY_SIZE))) {
+
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
+		return -EINVAL;
+	}
+	
+	for (i = 0, off = 0; i < 3; i++, off += DES_EXPKEY_WORDS,
+							key += DES_KEY_SIZE) {
+		int ret = setkey(&dctx->expkey[off], key, DES_KEY_SIZE, flags);
+		if (ret < 0)
+			return ret;
+	}	
+	return 0;
+}
+
+static void des3_ede_encrypt(void *ctx, u8 *dst, const u8 *src)
+{
+	struct des3_ede_ctx *dctx = ctx;
+	
+	des_small_fips_encrypt(dctx->expkey, dst, src);
+	des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst);
+	des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, dst);
+}
+
+static void des3_ede_decrypt(void *ctx, u8 *dst, const u8 *src)
+{
+	struct des3_ede_ctx *dctx = ctx;
+
+	des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, src);
+	des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst);
+	des_small_fips_decrypt(dctx->expkey, dst, dst);
+}
+
+static struct crypto_alg des_alg = {
+	.cra_name		=	"des",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	DES_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct des_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(des_alg.cra_list),
+	.cra_u			=	{ .cipher = {
+	.cia_min_keysize	=	DES_KEY_SIZE,
+	.cia_max_keysize	=	DES_KEY_SIZE,
+	.cia_ivsize		=	DES_BLOCK_SIZE,
+	.cia_setkey		= 	des_setkey,
+	.cia_encrypt		=	des_encrypt,
+	.cia_decrypt		=	des_decrypt } }
+};
+
+static struct crypto_alg des3_ede_alg = {
+	.cra_name		=	"des3_ede",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	DES3_EDE_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct des3_ede_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(des3_ede_alg.cra_list),
+	.cra_u			=	{ .cipher = {
+	.cia_min_keysize	=	DES3_EDE_KEY_SIZE,
+	.cia_max_keysize	=	DES3_EDE_KEY_SIZE,
+	.cia_ivsize		=	DES3_EDE_BLOCK_SIZE,
+	.cia_setkey	   	= 	des3_ede_setkey,
+	.cia_encrypt	 	=	des3_ede_encrypt,
+	.cia_decrypt	  	=	des3_ede_decrypt } }
+};
+
+static int __init init(void)
+{
+	int ret = 0;
+	
+	ret = crypto_register_alg(&des_alg);
+	if (ret < 0)
+		goto out;
+
+	ret = crypto_register_alg(&des3_ede_alg);
+	if (ret < 0)
+		crypto_unregister_alg(&des_alg);
+out:	
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&des3_ede_alg);
+	crypto_unregister_alg(&des_alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
diff -urN linux-2.4.22-pre2/crypto/digest.c linux-2.4.22-pre3/crypto/digest.c
--- linux-2.4.22-pre2/crypto/digest.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/digest.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,82 @@
+/*
+ * Cryptographic API.
+ *
+ * Digest operations.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+
+static void init(struct crypto_tfm *tfm)
+{
+	tfm->__crt_alg->cra_digest.dia_init(crypto_tfm_ctx(tfm));
+}
+
+static void update(struct crypto_tfm *tfm,
+                   struct scatterlist *sg, unsigned int nsg)
+{
+	unsigned int i;
+	
+	for (i = 0; i < nsg; i++) {
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
+		tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm),
+		                                      p, sg[i].length);
+		crypto_kunmap(p, 0);
+		crypto_yield(tfm);
+	}
+}
+
+static void final(struct crypto_tfm *tfm, u8 *out)
+{
+	tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out);
+}
+
+static void digest(struct crypto_tfm *tfm,
+                   struct scatterlist *sg, unsigned int nsg, u8 *out)
+{
+	unsigned int i;
+
+	tfm->crt_digest.dit_init(tfm);
+		
+	for (i = 0; i < nsg; i++) {
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
+		tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm),
+		                                      p, sg[i].length);
+		crypto_kunmap(p, 0);
+		crypto_yield(tfm);
+	}
+	crypto_digest_final(tfm, out);
+}
+
+int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	return flags ? -EINVAL : 0;
+}
+
+int crypto_init_digest_ops(struct crypto_tfm *tfm)
+{
+	struct digest_tfm *ops = &tfm->crt_digest;
+	
+	ops->dit_init	= init;
+	ops->dit_update	= update;
+	ops->dit_final	= final;
+	ops->dit_digest	= digest;
+	
+	return crypto_alloc_hmac_block(tfm);
+}
+
+void crypto_exit_digest_ops(struct crypto_tfm *tfm)
+{
+	crypto_free_hmac_block(tfm);
+}
diff -urN linux-2.4.22-pre2/crypto/hmac.c linux-2.4.22-pre3/crypto/hmac.c
--- linux-2.4.22-pre2/crypto/hmac.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/hmac.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,134 @@
+/*
+ * Cryptographic API.
+ *
+ * HMAC: Keyed-Hashing for Message Authentication (RFC2104).
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * The HMAC implementation is derived from USAGI.
+ * Copyright (c) 2002 Kazunori Miyazawa <miyazawa@linux-ipv6.org> / USAGI
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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/crypto.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+
+static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen)
+{
+	struct scatterlist tmp;
+	
+	tmp.page = virt_to_page(key);
+	tmp.offset = ((long)key & ~PAGE_MASK);
+	tmp.length = keylen;
+	crypto_digest_digest(tfm, &tmp, 1, key);
+		
+}
+
+int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
+{
+	int ret = 0;
+
+	BUG_ON(!crypto_tfm_alg_blocksize(tfm));
+	
+	tfm->crt_digest.dit_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
+	                                         GFP_KERNEL);
+	if (tfm->crt_digest.dit_hmac_block == NULL)
+		ret = -ENOMEM;
+
+	return ret;
+		
+}
+
+void crypto_free_hmac_block(struct crypto_tfm *tfm)
+{
+	if (tfm->crt_digest.dit_hmac_block)
+		kfree(tfm->crt_digest.dit_hmac_block);
+}
+
+void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
+{
+	unsigned int i;
+	struct scatterlist tmp;
+	char *ipad = tfm->crt_digest.dit_hmac_block;
+	
+	if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
+		hash_key(tfm, key, *keylen);
+		*keylen = crypto_tfm_alg_digestsize(tfm);
+	}
+
+	memset(ipad, 0, crypto_tfm_alg_blocksize(tfm));
+	memcpy(ipad, key, *keylen);
+
+	for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
+		ipad[i] ^= 0x36;
+
+	tmp.page = virt_to_page(ipad);
+	tmp.offset = ((long)ipad & ~PAGE_MASK);
+	tmp.length = crypto_tfm_alg_blocksize(tfm);
+	
+	crypto_digest_init(tfm);
+	crypto_digest_update(tfm, &tmp, 1);
+}
+
+void crypto_hmac_update(struct crypto_tfm *tfm,
+                        struct scatterlist *sg, unsigned int nsg)
+{
+	crypto_digest_update(tfm, sg, nsg);
+}
+
+void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
+                       unsigned int *keylen, u8 *out)
+{
+	unsigned int i;
+	struct scatterlist tmp;
+	char *opad = tfm->crt_digest.dit_hmac_block;
+	
+	if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
+		hash_key(tfm, key, *keylen);
+		*keylen = crypto_tfm_alg_digestsize(tfm);
+	}
+
+	crypto_digest_final(tfm, out);
+
+	memset(opad, 0, crypto_tfm_alg_blocksize(tfm));
+	memcpy(opad, key, *keylen);
+		
+	for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
+		opad[i] ^= 0x5c;
+
+	tmp.page = virt_to_page(opad);
+	tmp.offset = ((long)opad & ~PAGE_MASK);
+	tmp.length = crypto_tfm_alg_blocksize(tfm);
+
+	crypto_digest_init(tfm);
+	crypto_digest_update(tfm, &tmp, 1);
+	
+	tmp.page = virt_to_page(out);
+	tmp.offset = ((long)out & ~PAGE_MASK);
+	tmp.length = crypto_tfm_alg_digestsize(tfm);
+	
+	crypto_digest_update(tfm, &tmp, 1);
+	crypto_digest_final(tfm, out);
+}
+
+void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
+                 struct scatterlist *sg, unsigned int nsg, u8 *out)
+{
+	crypto_hmac_init(tfm, key, keylen);
+	crypto_hmac_update(tfm, sg, nsg);
+	crypto_hmac_final(tfm, key, keylen, out);
+}
+
+EXPORT_SYMBOL_GPL(crypto_hmac_init);
+EXPORT_SYMBOL_GPL(crypto_hmac_update);
+EXPORT_SYMBOL_GPL(crypto_hmac_final);
+EXPORT_SYMBOL_GPL(crypto_hmac);
+
diff -urN linux-2.4.22-pre2/crypto/internal.h linux-2.4.22-pre3/crypto/internal.h
--- linux-2.4.22-pre2/crypto/internal.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/internal.h	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,94 @@
+/*
+ * Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#ifndef _CRYPTO_INTERNAL_H
+#define _CRYPTO_INTERNAL_H
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/kmap_types.h>
+
+extern enum km_type crypto_km_types[];
+
+static inline enum km_type crypto_kmap_type(int out)
+{
+	return crypto_km_types[(in_softirq() ? 2 : 0) + out];
+}
+
+static inline void *crypto_kmap(struct page *page, int out)
+{
+	return kmap_atomic(page, crypto_kmap_type(out));
+}
+
+static inline void crypto_kunmap(void *vaddr, int out)
+{
+	kunmap_atomic(vaddr, crypto_kmap_type(out));
+}
+
+static inline void crypto_yield(struct crypto_tfm *tfm)
+{
+	if (!in_softirq())
+		cond_resched();
+}
+
+static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
+{
+	return (void *)&tfm[1];
+}
+
+struct crypto_alg *crypto_alg_lookup(const char *name);
+
+#ifdef CONFIG_KMOD
+void crypto_alg_autoload(const char *name);
+struct crypto_alg *crypto_alg_mod_lookup(const char *name);
+#else
+static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
+{
+	return crypto_alg_lookup(name);
+}
+#endif
+
+#ifdef CONFIG_CRYPTO_HMAC
+int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
+void crypto_free_hmac_block(struct crypto_tfm *tfm);
+#else
+static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
+{
+	return 0;
+}
+
+static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
+{ }
+#endif
+
+#ifdef CONFIG_PROC_FS
+void __init crypto_init_proc(void);
+#else
+static inline void crypto_init_proc(void)
+{ }
+#endif
+
+int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
+int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
+int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
+
+int crypto_init_digest_ops(struct crypto_tfm *tfm);
+int crypto_init_cipher_ops(struct crypto_tfm *tfm);
+int crypto_init_compress_ops(struct crypto_tfm *tfm);
+
+void crypto_exit_digest_ops(struct crypto_tfm *tfm);
+void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
+void crypto_exit_compress_ops(struct crypto_tfm *tfm);
+
+#endif	/* _CRYPTO_INTERNAL_H */
+
diff -urN linux-2.4.22-pre2/crypto/md4.c linux-2.4.22-pre3/crypto/md4.c
--- linux-2.4.22-pre2/crypto/md4.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/md4.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,250 @@
+/* 
+ * Cryptographic API.
+ *
+ * MD4 Message Digest Algorithm (RFC1320).
+ *
+ * Implementation derived from Andrew Tridgell and Steve French's
+ * CIFS MD4 implementation, and the cryptoapi implementation
+ * originally based on the public domain implementation written
+ * by Colin Plumb in 1993.
+ *
+ * Copyright (c) Andrew Tridgell 1997-1998.
+ * Modified by Steve French (sfrench@us.ibm.com) 2002
+ * Copyright (c) Cryptoapi developers.
+ * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/crypto.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <asm/byteorder.h>
+
+#define MD4_DIGEST_SIZE		16
+#define MD4_HMAC_BLOCK_SIZE	64
+#define MD4_BLOCK_WORDS		16
+#define MD4_HASH_WORDS		4
+
+struct md4_ctx {
+	u32 hash[MD4_HASH_WORDS];
+	u32 block[MD4_BLOCK_WORDS];
+	u64 byte_count;
+};
+
+static inline u32 lshift(u32 x, unsigned int s)
+{
+	x &= 0xFFFFFFFF;
+	return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
+}
+
+static inline u32 F(u32 x, u32 y, u32 z)
+{
+	return (x & y) | ((~x) & z);
+}
+
+static inline u32 G(u32 x, u32 y, u32 z)
+{
+	return (x & y) | (x & z) | (y & z);
+}
+
+static inline u32 H(u32 x, u32 y, u32 z)
+{
+	return x ^ y ^ z;
+}
+                        
+#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s))
+#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (u32)0x5A827999,s))
+#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (u32)0x6ED9EBA1,s))
+
+/* XXX: this stuff can be optimized */
+static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
+{
+	while (words--) {
+		__le32_to_cpus(buf);
+		buf++;
+	}
+}
+
+static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
+{
+	while (words--) {
+		__cpu_to_le32s(buf);
+		buf++;
+	}
+}
+
+static void md4_transform(u32 *hash, u32 const *in)
+{
+	u32 a, b, c, d;
+
+	a = hash[0];
+	b = hash[1];
+	c = hash[2];
+	d = hash[3];
+
+	ROUND1(a, b, c, d, in[0], 3);
+	ROUND1(d, a, b, c, in[1], 7);
+	ROUND1(c, d, a, b, in[2], 11);
+	ROUND1(b, c, d, a, in[3], 19);
+	ROUND1(a, b, c, d, in[4], 3);
+	ROUND1(d, a, b, c, in[5], 7);
+	ROUND1(c, d, a, b, in[6], 11);
+	ROUND1(b, c, d, a, in[7], 19);
+	ROUND1(a, b, c, d, in[8], 3);
+	ROUND1(d, a, b, c, in[9], 7);
+	ROUND1(c, d, a, b, in[10], 11);
+	ROUND1(b, c, d, a, in[11], 19);
+	ROUND1(a, b, c, d, in[12], 3);
+	ROUND1(d, a, b, c, in[13], 7);
+	ROUND1(c, d, a, b, in[14], 11);
+	ROUND1(b, c, d, a, in[15], 19);
+
+	ROUND2(a, b, c, d,in[ 0], 3);
+	ROUND2(d, a, b, c, in[4], 5);
+	ROUND2(c, d, a, b, in[8], 9);
+	ROUND2(b, c, d, a, in[12], 13);
+	ROUND2(a, b, c, d, in[1], 3);
+	ROUND2(d, a, b, c, in[5], 5);
+	ROUND2(c, d, a, b, in[9], 9);
+	ROUND2(b, c, d, a, in[13], 13);
+	ROUND2(a, b, c, d, in[2], 3);
+	ROUND2(d, a, b, c, in[6], 5);
+	ROUND2(c, d, a, b, in[10], 9);
+	ROUND2(b, c, d, a, in[14], 13);
+	ROUND2(a, b, c, d, in[3], 3);
+	ROUND2(d, a, b, c, in[7], 5);
+	ROUND2(c, d, a, b, in[11], 9);
+	ROUND2(b, c, d, a, in[15], 13);
+
+	ROUND3(a, b, c, d,in[ 0], 3);
+	ROUND3(d, a, b, c, in[8], 9);
+	ROUND3(c, d, a, b, in[4], 11);
+	ROUND3(b, c, d, a, in[12], 15);
+	ROUND3(a, b, c, d, in[2], 3);
+	ROUND3(d, a, b, c, in[10], 9);
+	ROUND3(c, d, a, b, in[6], 11);
+	ROUND3(b, c, d, a, in[14], 15);
+	ROUND3(a, b, c, d, in[1], 3);
+	ROUND3(d, a, b, c, in[9], 9);
+	ROUND3(c, d, a, b, in[5], 11);
+	ROUND3(b, c, d, a, in[13], 15);
+	ROUND3(a, b, c, d, in[3], 3);
+	ROUND3(d, a, b, c, in[11], 9);
+	ROUND3(c, d, a, b, in[7], 11);
+	ROUND3(b, c, d, a, in[15], 15);
+
+	hash[0] += a;
+	hash[1] += b;
+	hash[2] += c;
+	hash[3] += d;
+}
+
+static inline void md4_transform_helper(struct md4_ctx *ctx)
+{
+	le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
+	md4_transform(ctx->hash, ctx->block);
+}
+
+static void md4_init(void *ctx)
+{
+	struct md4_ctx *mctx = ctx;
+
+	mctx->hash[0] = 0x67452301;
+	mctx->hash[1] = 0xefcdab89;
+	mctx->hash[2] = 0x98badcfe;
+	mctx->hash[3] = 0x10325476;
+	mctx->byte_count = 0;
+}
+
+static void md4_update(void *ctx, const u8 *data, unsigned int len)
+{
+	struct md4_ctx *mctx = ctx;
+	const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
+
+	mctx->byte_count += len;
+
+	if (avail > len) {
+		memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+		       data, len);
+		return;
+	}
+
+	memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+	       data, avail);
+
+	md4_transform_helper(mctx);
+	data += avail;
+	len -= avail;
+
+	while (len >= sizeof(mctx->block)) {
+		memcpy(mctx->block, data, sizeof(mctx->block));
+		md4_transform_helper(mctx);
+		data += sizeof(mctx->block);
+		len -= sizeof(mctx->block);
+	}
+
+	memcpy(mctx->block, data, len);
+}
+
+static void md4_final(void *ctx, u8 *out)
+{
+	struct md4_ctx *mctx = ctx;
+	const unsigned int offset = mctx->byte_count & 0x3f;
+	char *p = (char *)mctx->block + offset;
+	int padding = 56 - (offset + 1);
+
+	*p++ = 0x80;
+	if (padding < 0) {
+		memset(p, 0x00, padding + sizeof (u64));
+		md4_transform_helper(mctx);
+		p = (char *)mctx->block;
+		padding = 56;
+	}
+
+	memset(p, 0, padding);
+	mctx->block[14] = mctx->byte_count << 3;
+	mctx->block[15] = mctx->byte_count >> 29;
+	le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
+	                  sizeof(u64)) / sizeof(u32));
+	md4_transform(mctx->hash, mctx->block);
+	cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
+	memcpy(out, mctx->hash, sizeof(mctx->hash));
+	memset(mctx, 0, sizeof(*mctx));
+}
+
+static struct crypto_alg alg = {
+	.cra_name	=	"md4",
+	.cra_flags	=	CRYPTO_ALG_TYPE_DIGEST,
+	.cra_blocksize	=	MD4_HMAC_BLOCK_SIZE,
+	.cra_ctxsize	=	sizeof(struct md4_ctx),
+	.cra_module	=	THIS_MODULE,
+	.cra_list       =       LIST_HEAD_INIT(alg.cra_list),	
+	.cra_u		=	{ .digest = {
+	.dia_digestsize	=	MD4_DIGEST_SIZE,
+	.dia_init   	= 	md4_init,
+	.dia_update 	=	md4_update,
+	.dia_final  	=	md4_final } }
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MD4 Message Digest Algorithm");
+
diff -urN linux-2.4.22-pre2/crypto/md5.c linux-2.4.22-pre3/crypto/md5.c
--- linux-2.4.22-pre2/crypto/md5.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/md5.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,244 @@
+/* 
+ * Cryptographic API.
+ *
+ * MD5 Message Digest Algorithm (RFC1321).
+ *
+ * Derived from cryptoapi implementation, originally based on the
+ * public domain implementation written by Colin Plumb in 1993.
+ *
+ * Copyright (c) Cryptoapi developers.
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <asm/byteorder.h>
+
+#define MD5_DIGEST_SIZE		16
+#define MD5_HMAC_BLOCK_SIZE	64
+#define MD5_BLOCK_WORDS		16
+#define MD5_HASH_WORDS		4
+
+#define F1(x, y, z)	(z ^ (x & (y ^ z)))
+#define F2(x, y, z)	F1(z, x, y)
+#define F3(x, y, z)	(x ^ y ^ z)
+#define F4(x, y, z)	(y ^ (x | ~z))
+
+#define MD5STEP(f, w, x, y, z, in, s) \
+	(w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x)
+
+struct md5_ctx {
+	u32 hash[MD5_HASH_WORDS];
+	u32 block[MD5_BLOCK_WORDS];
+	u64 byte_count;
+};
+
+static void md5_transform(u32 *hash, u32 const *in)
+{
+	u32 a, b, c, d;
+
+	a = hash[0];
+	b = hash[1];
+	c = hash[2];
+	d = hash[3];
+
+	MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+	MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+	MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+	MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+	MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+	MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+	MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+	MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+	MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+	MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+	MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+	MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+	MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+	MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+	MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+	MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+	MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+	MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+	MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+	MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+	MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+	MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+	MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+	MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+	MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+	MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+	MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+	MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+	MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+	MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+	MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+	MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+	MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+	MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+	MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+	MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+	MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+	MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+	MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+	MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+	hash[0] += a;
+	hash[1] += b;
+	hash[2] += c;
+	hash[3] += d;
+}
+
+/* XXX: this stuff can be optimized */
+static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
+{
+	while (words--) {
+		__le32_to_cpus(buf);
+		buf++;
+	}
+}
+
+static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
+{
+	while (words--) {
+		__cpu_to_le32s(buf);
+		buf++;
+	}
+}
+
+static inline void md5_transform_helper(struct md5_ctx *ctx)
+{
+	le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
+	md5_transform(ctx->hash, ctx->block);
+}
+
+static void md5_init(void *ctx)
+{
+	struct md5_ctx *mctx = ctx;
+
+	mctx->hash[0] = 0x67452301;
+	mctx->hash[1] = 0xefcdab89;
+	mctx->hash[2] = 0x98badcfe;
+	mctx->hash[3] = 0x10325476;
+	mctx->byte_count = 0;
+}
+
+static void md5_update(void *ctx, const u8 *data, unsigned int len)
+{
+	struct md5_ctx *mctx = ctx;
+	const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
+
+	mctx->byte_count += len;
+
+	if (avail > len) {
+		memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+		       data, len);
+		return;
+	}
+
+	memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+	       data, avail);
+
+	md5_transform_helper(mctx);
+	data += avail;
+	len -= avail;
+
+	while (len >= sizeof(mctx->block)) {
+		memcpy(mctx->block, data, sizeof(mctx->block));
+		md5_transform_helper(mctx);
+		data += sizeof(mctx->block);
+		len -= sizeof(mctx->block);
+	}
+
+	memcpy(mctx->block, data, len);
+}
+
+static void md5_final(void *ctx, u8 *out)
+{
+	struct md5_ctx *mctx = ctx;
+	const unsigned int offset = mctx->byte_count & 0x3f;
+	char *p = (char *)mctx->block + offset;
+	int padding = 56 - (offset + 1);
+
+	*p++ = 0x80;
+	if (padding < 0) {
+		memset(p, 0x00, padding + sizeof (u64));
+		md5_transform_helper(mctx);
+		p = (char *)mctx->block;
+		padding = 56;
+	}
+
+	memset(p, 0, padding);
+	mctx->block[14] = mctx->byte_count << 3;
+	mctx->block[15] = mctx->byte_count >> 29;
+	le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
+	                  sizeof(u64)) / sizeof(u32));
+	md5_transform(mctx->hash, mctx->block);
+	cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
+	memcpy(out, mctx->hash, sizeof(mctx->hash));
+	memset(mctx, 0, sizeof(*mctx));
+}
+
+static struct crypto_alg alg = {
+	.cra_name	=	"md5",
+	.cra_flags	=	CRYPTO_ALG_TYPE_DIGEST,
+	.cra_blocksize	=	MD5_HMAC_BLOCK_SIZE,
+	.cra_ctxsize	=	sizeof(struct md5_ctx),
+	.cra_module	=	THIS_MODULE,
+	.cra_list	=	LIST_HEAD_INIT(alg.cra_list),
+	.cra_u		=	{ .digest = {
+	.dia_digestsize	=	MD5_DIGEST_SIZE,
+	.dia_init   	= 	md5_init,
+	.dia_update 	=	md5_update,
+	.dia_final  	=	md5_final } }
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MD5 Message Digest Algorithm");
diff -urN linux-2.4.22-pre2/crypto/proc.c linux-2.4.22-pre3/crypto/proc.c
--- linux-2.4.22-pre2/crypto/proc.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/proc.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,109 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Procfs information.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/crypto.h>
+#include <linux/rwsem.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+extern struct list_head crypto_alg_list;
+extern struct rw_semaphore crypto_alg_sem;
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	struct list_head *v;
+	loff_t n = *pos;
+
+	down_read(&crypto_alg_sem);
+	list_for_each(v, &crypto_alg_list)
+		if (!n--)
+			return list_entry(v, struct crypto_alg, cra_list);
+	return NULL;
+}
+
+static void *c_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	struct list_head *v = p;
+	
+	(*pos)++;
+	v = v->next;
+	return (v == &crypto_alg_list) ?
+		NULL : list_entry(v, struct crypto_alg, cra_list);
+}
+
+static void c_stop(struct seq_file *m, void *p)
+{
+	up_read(&crypto_alg_sem);
+}
+
+static int c_show(struct seq_file *m, void *p)
+{
+	struct crypto_alg *alg = (struct crypto_alg *)p;
+	
+	seq_printf(m, "name         : %s\n", alg->cra_name);
+	seq_printf(m, "module       : %s\n",
+		   (alg->cra_module ?
+		    alg->cra_module->name :
+		    "kernel"));
+	
+	switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
+		seq_printf(m, "min keysize  : %u\n",
+					alg->cra_cipher.cia_min_keysize);
+		seq_printf(m, "max keysize  : %u\n",
+					alg->cra_cipher.cia_max_keysize);
+		seq_printf(m, "ivsize       : %u\n",
+					alg->cra_cipher.cia_ivsize);
+		break;
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
+		seq_printf(m, "digestsize   : %u\n",
+		           alg->cra_digest.dia_digestsize);
+		break;
+	}
+
+	seq_putc(m, '\n');
+	return 0;
+}
+
+static struct seq_operations crypto_seq_ops = {
+	.start		= c_start,
+	.next		= c_next,
+	.stop		= c_stop,
+	.show		= c_show
+};
+
+static int crypto_info_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &crypto_seq_ops);
+}
+        
+static struct file_operations proc_crypto_ops = {
+	.open		= crypto_info_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release
+};
+
+void __init crypto_init_proc(void)
+{
+	struct proc_dir_entry *proc;
+	
+	proc = create_proc_entry("crypto", 0, NULL);
+	if (proc)
+		proc->proc_fops = &proc_crypto_ops;
+}
diff -urN linux-2.4.22-pre2/crypto/serpent.c linux-2.4.22-pre3/crypto/serpent.c
--- linux-2.4.22-pre2/crypto/serpent.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/serpent.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,507 @@
+/*
+ * Cryptographic API.
+ *
+ * Serpent Cipher Algorithm.
+ *
+ * Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <asm/byteorder.h>
+#include <linux/crypto.h>
+
+/* Key is padded to the maximum of 256 bits before round key generation.
+ * Any key length <= 256 bits (32 bytes) is allowed by the algorithm.
+ */
+
+#define SERPENT_MIN_KEY_SIZE		  0
+#define SERPENT_MAX_KEY_SIZE		 32
+#define SERPENT_EXPKEY_WORDS		132
+#define SERPENT_BLOCK_SIZE		 16
+
+#define PHI 0x9e3779b9UL
+#define ROL(x,r) ((x) = ((x) << (r)) | ((x) >> (32-(r))))
+#define ROR(x,r) ((x) = ((x) >> (r)) | ((x) << (32-(r))))
+
+#define keyiter(a,b,c,d,i,j) \
+        b ^= d; b ^= c; b ^= a; b ^= PHI ^ i; ROL(b,11); k[j] = b;
+
+#define loadkeys(x0,x1,x2,x3,i) \
+	x0=k[i]; x1=k[i+1]; x2=k[i+2]; x3=k[i+3];
+
+#define storekeys(x0,x1,x2,x3,i) \
+	k[i]=x0; k[i+1]=x1; k[i+2]=x2; k[i+3]=x3;
+
+#define K(x0,x1,x2,x3,i)				\
+	x3 ^= k[4*(i)+3];        x2 ^= k[4*(i)+2];	\
+	x1 ^= k[4*(i)+1];        x0 ^= k[4*(i)+0];
+
+#define LK(x0,x1,x2,x3,x4,i)				\
+					ROL(x0,13);	\
+	ROL(x2,3);	x1 ^= x0;	x4  = x0 << 3;	\
+	x3 ^= x2;	x1 ^= x2;			\
+	ROL(x1,1);	x3 ^= x4;			\
+	ROL(x3,7);	x4  = x1;			\
+	x0 ^= x1;	x4 <<= 7;	x2 ^= x3;	\
+	x0 ^= x3;	x2 ^= x4;	x3 ^= k[4*i+3];	\
+	x1 ^= k[4*i+1];	ROL(x0,5);	ROL(x2,22);	\
+	x0 ^= k[4*i+0];	x2 ^= k[4*i+2];
+
+#define KL(x0,x1,x2,x3,x4,i)				\
+	x0 ^= k[4*i+0];	x1 ^= k[4*i+1];	x2 ^= k[4*i+2];	\
+	x3 ^= k[4*i+3];	ROR(x0,5);	ROR(x2,22);	\
+	x4 =  x1;	x2 ^= x3;	x0 ^= x3;	\
+	x4 <<= 7;	x0 ^= x1;	ROR(x1,1);	\
+	x2 ^= x4;	ROR(x3,7);	x4 = x0 << 3;	\
+	x1 ^= x0;	x3 ^= x4;	ROR(x0,13);	\
+	x1 ^= x2;	x3 ^= x2;	ROR(x2,3);
+
+#define S0(x0,x1,x2,x3,x4)				\
+					x4  = x3;	\
+	x3 |= x0;	x0 ^= x4;	x4 ^= x2;	\
+	x4 =~ x4;	x3 ^= x1;	x1 &= x0;	\
+	x1 ^= x4;	x2 ^= x0;	x0 ^= x3;	\
+	x4 |= x0;	x0 ^= x2;	x2 &= x1;	\
+	x3 ^= x2;	x1 =~ x1;	x2 ^= x4;	\
+	x1 ^= x2;
+
+#define S1(x0,x1,x2,x3,x4)				\
+					x4  = x1;	\
+	x1 ^= x0;	x0 ^= x3;	x3 =~ x3;	\
+	x4 &= x1;	x0 |= x1;	x3 ^= x2;	\
+	x0 ^= x3;	x1 ^= x3;	x3 ^= x4;	\
+	x1 |= x4;	x4 ^= x2;	x2 &= x0;	\
+	x2 ^= x1;	x1 |= x0;	x0 =~ x0;	\
+	x0 ^= x2;	x4 ^= x1;
+
+#define S2(x0,x1,x2,x3,x4)				\
+					x3 =~ x3;	\
+	x1 ^= x0;	x4  = x0;	x0 &= x2;	\
+	x0 ^= x3;	x3 |= x4;	x2 ^= x1;	\
+	x3 ^= x1;	x1 &= x0;	x0 ^= x2;	\
+	x2 &= x3;	x3 |= x1;	x0 =~ x0;	\
+	x3 ^= x0;	x4 ^= x0;	x0 ^= x2;	\
+	x1 |= x2;
+
+#define S3(x0,x1,x2,x3,x4)				\
+					x4  = x1;	\
+	x1 ^= x3;	x3 |= x0;	x4 &= x0;	\
+	x0 ^= x2;	x2 ^= x1;	x1 &= x3;	\
+	x2 ^= x3;	x0 |= x4;	x4 ^= x3;	\
+	x1 ^= x0;	x0 &= x3;	x3 &= x4;	\
+	x3 ^= x2;	x4 |= x1;	x2 &= x1;	\
+	x4 ^= x3;	x0 ^= x3;	x3 ^= x2;
+
+#define S4(x0,x1,x2,x3,x4)				\
+					x4  = x3;	\
+	x3 &= x0;	x0 ^= x4;			\
+	x3 ^= x2;	x2 |= x4;	x0 ^= x1;	\
+	x4 ^= x3;	x2 |= x0;			\
+	x2 ^= x1;	x1 &= x0;			\
+	x1 ^= x4;	x4 &= x2;	x2 ^= x3;	\
+	x4 ^= x0;	x3 |= x1;	x1 =~ x1;	\
+	x3 ^= x0;
+
+#define S5(x0,x1,x2,x3,x4)				\
+	x4  = x1;	x1 |= x0;			\
+	x2 ^= x1;	x3 =~ x3;	x4 ^= x0;	\
+	x0 ^= x2;	x1 &= x4;	x4 |= x3;	\
+	x4 ^= x0;	x0 &= x3;	x1 ^= x3;	\
+	x3 ^= x2;	x0 ^= x1;	x2 &= x4;	\
+	x1 ^= x2;	x2 &= x0;			\
+	x3 ^= x2;
+
+#define S6(x0,x1,x2,x3,x4)				\
+					x4  = x1;	\
+	x3 ^= x0;	x1 ^= x2;	x2 ^= x0;	\
+	x0 &= x3;	x1 |= x3;	x4 =~ x4;	\
+	x0 ^= x1;	x1 ^= x2;			\
+	x3 ^= x4;	x4 ^= x0;	x2 &= x0;	\
+	x4 ^= x1;	x2 ^= x3;	x3 &= x1;	\
+	x3 ^= x0;	x1 ^= x2;
+
+#define S7(x0,x1,x2,x3,x4)				\
+					x1 =~ x1;	\
+	x4  = x1;	x0 =~ x0;	x1 &= x2;	\
+	x1 ^= x3;	x3 |= x4;	x4 ^= x2;	\
+	x2 ^= x3;	x3 ^= x0;	x0 |= x1;	\
+	x2 &= x0;	x0 ^= x4;	x4 ^= x3;	\
+	x3 &= x0;	x4 ^= x1;			\
+	x2 ^= x4;	x3 ^= x1;	x4 |= x0;	\
+	x4 ^= x1;
+
+#define SI0(x0,x1,x2,x3,x4)				\
+			x4  = x3;	x1 ^= x0;	\
+	x3 |= x1;	x4 ^= x1;	x0 =~ x0;	\
+	x2 ^= x3;	x3 ^= x0;	x0 &= x1;	\
+	x0 ^= x2;	x2 &= x3;	x3 ^= x4;	\
+	x2 ^= x3;	x1 ^= x3;	x3 &= x0;	\
+	x1 ^= x0;	x0 ^= x2;	x4 ^= x3;
+
+#define SI1(x0,x1,x2,x3,x4)				\
+	x1 ^= x3;	x4  = x0;			\
+	x0 ^= x2;	x2 =~ x2;	x4 |= x1;	\
+	x4 ^= x3;	x3 &= x1;	x1 ^= x2;	\
+	x2 &= x4;	x4 ^= x1;	x1 |= x3;	\
+	x3 ^= x0;	x2 ^= x0;	x0 |= x4;	\
+	x2 ^= x4;	x1 ^= x0;			\
+	x4 ^= x1;
+
+#define SI2(x0,x1,x2,x3,x4)				\
+	x2 ^= x1;	x4  = x3;	x3 =~ x3;	\
+	x3 |= x2;	x2 ^= x4;	x4 ^= x0;	\
+	x3 ^= x1;	x1 |= x2;	x2 ^= x0;	\
+	x1 ^= x4;	x4 |= x3;	x2 ^= x3;	\
+	x4 ^= x2;	x2 &= x1;			\
+	x2 ^= x3;	x3 ^= x4;	x4 ^= x0;
+
+#define SI3(x0,x1,x2,x3,x4)				\
+					x2 ^= x1;	\
+	x4  = x1;	x1 &= x2;			\
+	x1 ^= x0;	x0 |= x4;	x4 ^= x3;	\
+	x0 ^= x3;	x3 |= x1;	x1 ^= x2;	\
+	x1 ^= x3;	x0 ^= x2;	x2 ^= x3;	\
+	x3 &= x1;	x1 ^= x0;	x0 &= x2;	\
+	x4 ^= x3;	x3 ^= x0;	x0 ^= x1;
+
+#define SI4(x0,x1,x2,x3,x4)				\
+	x2 ^= x3;	x4  = x0;	x0 &= x1;	\
+	x0 ^= x2;	x2 |= x3;	x4 =~ x4;	\
+	x1 ^= x0;	x0 ^= x2;	x2 &= x4;	\
+	x2 ^= x0;	x0 |= x4;			\
+	x0 ^= x3;	x3 &= x2;			\
+	x4 ^= x3;	x3 ^= x1;	x1 &= x0;	\
+	x4 ^= x1;	x0 ^= x3;
+
+#define SI5(x0,x1,x2,x3,x4)				\
+			x4  = x1;	x1 |= x2;	\
+	x2 ^= x4;	x1 ^= x3;	x3 &= x4;	\
+	x2 ^= x3;	x3 |= x0;	x0 =~ x0;	\
+	x3 ^= x2;	x2 |= x0;	x4 ^= x1;	\
+	x2 ^= x4;	x4 &= x0;	x0 ^= x1;	\
+	x1 ^= x3;	x0 &= x2;	x2 ^= x3;	\
+	x0 ^= x2;	x2 ^= x4;	x4 ^= x3;
+
+#define SI6(x0,x1,x2,x3,x4)				\
+			x0 ^= x2;			\
+	x4  = x0;	x0 &= x3;	x2 ^= x3;	\
+	x0 ^= x2;	x3 ^= x1;	x2 |= x4;	\
+	x2 ^= x3;	x3 &= x0;	x0 =~ x0;	\
+	x3 ^= x1;	x1 &= x2;	x4 ^= x0;	\
+	x3 ^= x4;	x4 ^= x2;	x0 ^= x1;	\
+	x2 ^= x0;
+
+#define SI7(x0,x1,x2,x3,x4)				\
+	x4  = x3;	x3 &= x0;	x0 ^= x2;	\
+	x2 |= x4;	x4 ^= x1;	x0 =~ x0;	\
+	x1 |= x3;	x4 ^= x0;	x0 &= x2;	\
+	x0 ^= x1;	x1 &= x2;	x3 ^= x2;	\
+	x4 ^= x3;	x2 &= x3;	x3 |= x0;	\
+	x1 ^= x4;	x3 ^= x4;	x4 &= x0;	\
+	x4 ^= x2;
+
+struct serpent_ctx {
+	u8 iv[SERPENT_BLOCK_SIZE];
+	u32 expkey[SERPENT_EXPKEY_WORDS];
+};
+
+static int setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+{
+	u32 *k = ((struct serpent_ctx *)ctx)->expkey;
+	u8  *k8 = (u8 *)k;
+	u32 r0,r1,r2,r3,r4;
+	int i;
+
+	if ((keylen < SERPENT_MIN_KEY_SIZE)
+			|| (keylen > SERPENT_MAX_KEY_SIZE))
+	{
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+
+	/* Copy key, add padding */
+
+	for (i = 0; i < keylen; ++i)
+		k8[i] = key[i];
+	if (i < SERPENT_MAX_KEY_SIZE)
+		k8[i++] = 1;
+	while (i < SERPENT_MAX_KEY_SIZE)
+		k8[i++] = 0;
+
+	/* Expand key using polynomial */
+
+	r0 = le32_to_cpu(k[3]);
+	r1 = le32_to_cpu(k[4]);
+	r2 = le32_to_cpu(k[5]);
+	r3 = le32_to_cpu(k[6]);
+	r4 = le32_to_cpu(k[7]);
+
+	keyiter(le32_to_cpu(k[0]),r0,r4,r2,0,0);
+	keyiter(le32_to_cpu(k[1]),r1,r0,r3,1,1);
+	keyiter(le32_to_cpu(k[2]),r2,r1,r4,2,2);
+	keyiter(le32_to_cpu(k[3]),r3,r2,r0,3,3);
+	keyiter(le32_to_cpu(k[4]),r4,r3,r1,4,4);
+	keyiter(le32_to_cpu(k[5]),r0,r4,r2,5,5);
+	keyiter(le32_to_cpu(k[6]),r1,r0,r3,6,6);
+	keyiter(le32_to_cpu(k[7]),r2,r1,r4,7,7);
+
+	keyiter(k[  0],r3,r2,r0,  8,  8); keyiter(k[  1],r4,r3,r1,  9,  9);
+	keyiter(k[  2],r0,r4,r2, 10, 10); keyiter(k[  3],r1,r0,r3, 11, 11);
+	keyiter(k[  4],r2,r1,r4, 12, 12); keyiter(k[  5],r3,r2,r0, 13, 13);
+	keyiter(k[  6],r4,r3,r1, 14, 14); keyiter(k[  7],r0,r4,r2, 15, 15);
+	keyiter(k[  8],r1,r0,r3, 16, 16); keyiter(k[  9],r2,r1,r4, 17, 17);
+	keyiter(k[ 10],r3,r2,r0, 18, 18); keyiter(k[ 11],r4,r3,r1, 19, 19);
+	keyiter(k[ 12],r0,r4,r2, 20, 20); keyiter(k[ 13],r1,r0,r3, 21, 21);
+	keyiter(k[ 14],r2,r1,r4, 22, 22); keyiter(k[ 15],r3,r2,r0, 23, 23);
+	keyiter(k[ 16],r4,r3,r1, 24, 24); keyiter(k[ 17],r0,r4,r2, 25, 25);
+	keyiter(k[ 18],r1,r0,r3, 26, 26); keyiter(k[ 19],r2,r1,r4, 27, 27);
+	keyiter(k[ 20],r3,r2,r0, 28, 28); keyiter(k[ 21],r4,r3,r1, 29, 29);
+	keyiter(k[ 22],r0,r4,r2, 30, 30); keyiter(k[ 23],r1,r0,r3, 31, 31);
+
+	k += 50;
+
+	keyiter(k[-26],r2,r1,r4, 32,-18); keyiter(k[-25],r3,r2,r0, 33,-17);
+	keyiter(k[-24],r4,r3,r1, 34,-16); keyiter(k[-23],r0,r4,r2, 35,-15);
+	keyiter(k[-22],r1,r0,r3, 36,-14); keyiter(k[-21],r2,r1,r4, 37,-13);
+	keyiter(k[-20],r3,r2,r0, 38,-12); keyiter(k[-19],r4,r3,r1, 39,-11);
+	keyiter(k[-18],r0,r4,r2, 40,-10); keyiter(k[-17],r1,r0,r3, 41, -9);
+	keyiter(k[-16],r2,r1,r4, 42, -8); keyiter(k[-15],r3,r2,r0, 43, -7);
+	keyiter(k[-14],r4,r3,r1, 44, -6); keyiter(k[-13],r0,r4,r2, 45, -5);
+	keyiter(k[-12],r1,r0,r3, 46, -4); keyiter(k[-11],r2,r1,r4, 47, -3);
+	keyiter(k[-10],r3,r2,r0, 48, -2); keyiter(k[ -9],r4,r3,r1, 49, -1);
+	keyiter(k[ -8],r0,r4,r2, 50,  0); keyiter(k[ -7],r1,r0,r3, 51,  1);
+	keyiter(k[ -6],r2,r1,r4, 52,  2); keyiter(k[ -5],r3,r2,r0, 53,  3);
+	keyiter(k[ -4],r4,r3,r1, 54,  4); keyiter(k[ -3],r0,r4,r2, 55,  5);
+	keyiter(k[ -2],r1,r0,r3, 56,  6); keyiter(k[ -1],r2,r1,r4, 57,  7);
+	keyiter(k[  0],r3,r2,r0, 58,  8); keyiter(k[  1],r4,r3,r1, 59,  9);
+	keyiter(k[  2],r0,r4,r2, 60, 10); keyiter(k[  3],r1,r0,r3, 61, 11);
+	keyiter(k[  4],r2,r1,r4, 62, 12); keyiter(k[  5],r3,r2,r0, 63, 13);
+	keyiter(k[  6],r4,r3,r1, 64, 14); keyiter(k[  7],r0,r4,r2, 65, 15);
+	keyiter(k[  8],r1,r0,r3, 66, 16); keyiter(k[  9],r2,r1,r4, 67, 17);
+	keyiter(k[ 10],r3,r2,r0, 68, 18); keyiter(k[ 11],r4,r3,r1, 69, 19);
+	keyiter(k[ 12],r0,r4,r2, 70, 20); keyiter(k[ 13],r1,r0,r3, 71, 21);
+	keyiter(k[ 14],r2,r1,r4, 72, 22); keyiter(k[ 15],r3,r2,r0, 73, 23);
+	keyiter(k[ 16],r4,r3,r1, 74, 24); keyiter(k[ 17],r0,r4,r2, 75, 25);
+	keyiter(k[ 18],r1,r0,r3, 76, 26); keyiter(k[ 19],r2,r1,r4, 77, 27);
+	keyiter(k[ 20],r3,r2,r0, 78, 28); keyiter(k[ 21],r4,r3,r1, 79, 29);
+	keyiter(k[ 22],r0,r4,r2, 80, 30); keyiter(k[ 23],r1,r0,r3, 81, 31);
+
+	k += 50;
+
+	keyiter(k[-26],r2,r1,r4, 82,-18); keyiter(k[-25],r3,r2,r0, 83,-17);
+	keyiter(k[-24],r4,r3,r1, 84,-16); keyiter(k[-23],r0,r4,r2, 85,-15);
+	keyiter(k[-22],r1,r0,r3, 86,-14); keyiter(k[-21],r2,r1,r4, 87,-13);
+	keyiter(k[-20],r3,r2,r0, 88,-12); keyiter(k[-19],r4,r3,r1, 89,-11);
+	keyiter(k[-18],r0,r4,r2, 90,-10); keyiter(k[-17],r1,r0,r3, 91, -9);
+	keyiter(k[-16],r2,r1,r4, 92, -8); keyiter(k[-15],r3,r2,r0, 93, -7);
+	keyiter(k[-14],r4,r3,r1, 94, -6); keyiter(k[-13],r0,r4,r2, 95, -5);
+	keyiter(k[-12],r1,r0,r3, 96, -4); keyiter(k[-11],r2,r1,r4, 97, -3);
+	keyiter(k[-10],r3,r2,r0, 98, -2); keyiter(k[ -9],r4,r3,r1, 99, -1);
+	keyiter(k[ -8],r0,r4,r2,100,  0); keyiter(k[ -7],r1,r0,r3,101,  1);
+	keyiter(k[ -6],r2,r1,r4,102,  2); keyiter(k[ -5],r3,r2,r0,103,  3);
+	keyiter(k[ -4],r4,r3,r1,104,  4); keyiter(k[ -3],r0,r4,r2,105,  5);
+	keyiter(k[ -2],r1,r0,r3,106,  6); keyiter(k[ -1],r2,r1,r4,107,  7);
+	keyiter(k[  0],r3,r2,r0,108,  8); keyiter(k[  1],r4,r3,r1,109,  9);
+	keyiter(k[  2],r0,r4,r2,110, 10); keyiter(k[  3],r1,r0,r3,111, 11);
+	keyiter(k[  4],r2,r1,r4,112, 12); keyiter(k[  5],r3,r2,r0,113, 13);
+	keyiter(k[  6],r4,r3,r1,114, 14); keyiter(k[  7],r0,r4,r2,115, 15);
+	keyiter(k[  8],r1,r0,r3,116, 16); keyiter(k[  9],r2,r1,r4,117, 17);
+	keyiter(k[ 10],r3,r2,r0,118, 18); keyiter(k[ 11],r4,r3,r1,119, 19);
+	keyiter(k[ 12],r0,r4,r2,120, 20); keyiter(k[ 13],r1,r0,r3,121, 21);
+	keyiter(k[ 14],r2,r1,r4,122, 22); keyiter(k[ 15],r3,r2,r0,123, 23);
+	keyiter(k[ 16],r4,r3,r1,124, 24); keyiter(k[ 17],r0,r4,r2,125, 25);
+	keyiter(k[ 18],r1,r0,r3,126, 26); keyiter(k[ 19],r2,r1,r4,127, 27);
+	keyiter(k[ 20],r3,r2,r0,128, 28); keyiter(k[ 21],r4,r3,r1,129, 29);
+	keyiter(k[ 22],r0,r4,r2,130, 30); keyiter(k[ 23],r1,r0,r3,131, 31);
+
+	/* Apply S-boxes */
+
+	S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3, 28); loadkeys(r1,r2,r4,r3, 24);
+	S4(r1,r2,r4,r3,r0); storekeys(r2,r4,r3,r0, 24); loadkeys(r2,r4,r3,r0, 20);
+	S5(r2,r4,r3,r0,r1); storekeys(r1,r2,r4,r0, 20); loadkeys(r1,r2,r4,r0, 16);
+	S6(r1,r2,r4,r0,r3); storekeys(r4,r3,r2,r0, 16); loadkeys(r4,r3,r2,r0, 12);
+	S7(r4,r3,r2,r0,r1); storekeys(r1,r2,r0,r4, 12); loadkeys(r1,r2,r0,r4,  8);
+	S0(r1,r2,r0,r4,r3); storekeys(r0,r2,r4,r1,  8); loadkeys(r0,r2,r4,r1,  4);
+	S1(r0,r2,r4,r1,r3); storekeys(r3,r4,r1,r0,  4); loadkeys(r3,r4,r1,r0,  0);
+	S2(r3,r4,r1,r0,r2); storekeys(r2,r4,r3,r0,  0); loadkeys(r2,r4,r3,r0, -4);
+	S3(r2,r4,r3,r0,r1); storekeys(r0,r1,r4,r2, -4); loadkeys(r0,r1,r4,r2, -8);
+	S4(r0,r1,r4,r2,r3); storekeys(r1,r4,r2,r3, -8); loadkeys(r1,r4,r2,r3,-12);
+	S5(r1,r4,r2,r3,r0); storekeys(r0,r1,r4,r3,-12); loadkeys(r0,r1,r4,r3,-16);
+	S6(r0,r1,r4,r3,r2); storekeys(r4,r2,r1,r3,-16); loadkeys(r4,r2,r1,r3,-20);
+	S7(r4,r2,r1,r3,r0); storekeys(r0,r1,r3,r4,-20); loadkeys(r0,r1,r3,r4,-24);
+	S0(r0,r1,r3,r4,r2); storekeys(r3,r1,r4,r0,-24); loadkeys(r3,r1,r4,r0,-28);
+	k -= 50;
+	S1(r3,r1,r4,r0,r2); storekeys(r2,r4,r0,r3, 22); loadkeys(r2,r4,r0,r3, 18);
+	S2(r2,r4,r0,r3,r1); storekeys(r1,r4,r2,r3, 18); loadkeys(r1,r4,r2,r3, 14);
+	S3(r1,r4,r2,r3,r0); storekeys(r3,r0,r4,r1, 14); loadkeys(r3,r0,r4,r1, 10);
+	S4(r3,r0,r4,r1,r2); storekeys(r0,r4,r1,r2, 10); loadkeys(r0,r4,r1,r2,  6);
+	S5(r0,r4,r1,r2,r3); storekeys(r3,r0,r4,r2,  6); loadkeys(r3,r0,r4,r2,  2);
+	S6(r3,r0,r4,r2,r1); storekeys(r4,r1,r0,r2,  2); loadkeys(r4,r1,r0,r2, -2);
+	S7(r4,r1,r0,r2,r3); storekeys(r3,r0,r2,r4, -2); loadkeys(r3,r0,r2,r4, -6);
+	S0(r3,r0,r2,r4,r1); storekeys(r2,r0,r4,r3, -6); loadkeys(r2,r0,r4,r3,-10);
+	S1(r2,r0,r4,r3,r1); storekeys(r1,r4,r3,r2,-10); loadkeys(r1,r4,r3,r2,-14);
+	S2(r1,r4,r3,r2,r0); storekeys(r0,r4,r1,r2,-14); loadkeys(r0,r4,r1,r2,-18);
+	S3(r0,r4,r1,r2,r3); storekeys(r2,r3,r4,r0,-18); loadkeys(r2,r3,r4,r0,-22);
+	k -= 50;
+	S4(r2,r3,r4,r0,r1); storekeys(r3,r4,r0,r1, 28); loadkeys(r3,r4,r0,r1, 24);
+	S5(r3,r4,r0,r1,r2); storekeys(r2,r3,r4,r1, 24); loadkeys(r2,r3,r4,r1, 20);
+	S6(r2,r3,r4,r1,r0); storekeys(r4,r0,r3,r1, 20); loadkeys(r4,r0,r3,r1, 16);
+	S7(r4,r0,r3,r1,r2); storekeys(r2,r3,r1,r4, 16); loadkeys(r2,r3,r1,r4, 12);
+	S0(r2,r3,r1,r4,r0); storekeys(r1,r3,r4,r2, 12); loadkeys(r1,r3,r4,r2,  8);
+	S1(r1,r3,r4,r2,r0); storekeys(r0,r4,r2,r1,  8); loadkeys(r0,r4,r2,r1,  4);
+	S2(r0,r4,r2,r1,r3); storekeys(r3,r4,r0,r1,  4); loadkeys(r3,r4,r0,r1,  0);
+	S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3,  0);
+
+	return 0;
+}
+
+static void encrypt(void *ctx, u8 *dst, const u8 *src)
+{
+	const u32
+		*k = ((struct serpent_ctx *)ctx)->expkey,
+		*s = (const u32 *)src;
+	u32	*d = (u32 *)dst,
+		r0, r1, r2, r3, r4;
+
+/*
+ * Note: The conversions between u8* and u32* might cause trouble
+ * on architectures with stricter alignment rules than x86
+ */
+
+	r0 = le32_to_cpu(s[0]);
+	r1 = le32_to_cpu(s[1]);
+	r2 = le32_to_cpu(s[2]);
+	r3 = le32_to_cpu(s[3]);
+
+				 K(r0,r1,r2,r3,0);
+	S0(r0,r1,r2,r3,r4);	LK(r2,r1,r3,r0,r4,1);
+	S1(r2,r1,r3,r0,r4);	LK(r4,r3,r0,r2,r1,2);
+	S2(r4,r3,r0,r2,r1);	LK(r1,r3,r4,r2,r0,3);
+	S3(r1,r3,r4,r2,r0);	LK(r2,r0,r3,r1,r4,4);
+	S4(r2,r0,r3,r1,r4);	LK(r0,r3,r1,r4,r2,5);
+	S5(r0,r3,r1,r4,r2);	LK(r2,r0,r3,r4,r1,6);
+	S6(r2,r0,r3,r4,r1);	LK(r3,r1,r0,r4,r2,7);
+	S7(r3,r1,r0,r4,r2);	LK(r2,r0,r4,r3,r1,8);
+	S0(r2,r0,r4,r3,r1);	LK(r4,r0,r3,r2,r1,9);
+	S1(r4,r0,r3,r2,r1);	LK(r1,r3,r2,r4,r0,10);
+	S2(r1,r3,r2,r4,r0);	LK(r0,r3,r1,r4,r2,11);
+	S3(r0,r3,r1,r4,r2);	LK(r4,r2,r3,r0,r1,12);
+	S4(r4,r2,r3,r0,r1);	LK(r2,r3,r0,r1,r4,13);
+	S5(r2,r3,r0,r1,r4);	LK(r4,r2,r3,r1,r0,14);
+	S6(r4,r2,r3,r1,r0);	LK(r3,r0,r2,r1,r4,15);
+	S7(r3,r0,r2,r1,r4);	LK(r4,r2,r1,r3,r0,16);
+	S0(r4,r2,r1,r3,r0);	LK(r1,r2,r3,r4,r0,17);
+	S1(r1,r2,r3,r4,r0);	LK(r0,r3,r4,r1,r2,18);
+	S2(r0,r3,r4,r1,r2);	LK(r2,r3,r0,r1,r4,19);
+	S3(r2,r3,r0,r1,r4);	LK(r1,r4,r3,r2,r0,20);
+	S4(r1,r4,r3,r2,r0);	LK(r4,r3,r2,r0,r1,21);
+	S5(r4,r3,r2,r0,r1);	LK(r1,r4,r3,r0,r2,22);
+	S6(r1,r4,r3,r0,r2);	LK(r3,r2,r4,r0,r1,23);
+	S7(r3,r2,r4,r0,r1);	LK(r1,r4,r0,r3,r2,24);
+	S0(r1,r4,r0,r3,r2);	LK(r0,r4,r3,r1,r2,25);
+	S1(r0,r4,r3,r1,r2);	LK(r2,r3,r1,r0,r4,26);
+	S2(r2,r3,r1,r0,r4);	LK(r4,r3,r2,r0,r1,27);
+	S3(r4,r3,r2,r0,r1);	LK(r0,r1,r3,r4,r2,28);
+	S4(r0,r1,r3,r4,r2);	LK(r1,r3,r4,r2,r0,29);
+	S5(r1,r3,r4,r2,r0);	LK(r0,r1,r3,r2,r4,30);
+	S6(r0,r1,r3,r2,r4);	LK(r3,r4,r1,r2,r0,31);
+	S7(r3,r4,r1,r2,r0);	 K(r0,r1,r2,r3,32);
+
+	d[0] = cpu_to_le32(r0);
+	d[1] = cpu_to_le32(r1);
+	d[2] = cpu_to_le32(r2);
+	d[3] = cpu_to_le32(r3);
+}
+
+static void decrypt(void *ctx, u8 *dst, const u8 *src)
+{
+	const u32
+		*k = ((struct serpent_ctx *)ctx)->expkey,
+		*s = (const u32 *)src;
+	u32	*d = (u32 *)dst,
+		r0, r1, r2, r3, r4;
+
+	r0 = le32_to_cpu(s[0]);
+	r1 = le32_to_cpu(s[1]);
+	r2 = le32_to_cpu(s[2]);
+	r3 = le32_to_cpu(s[3]);
+
+				K(r0,r1,r2,r3,32);
+	SI7(r0,r1,r2,r3,r4);	KL(r1,r3,r0,r4,r2,31);
+	SI6(r1,r3,r0,r4,r2);	KL(r0,r2,r4,r1,r3,30);
+	SI5(r0,r2,r4,r1,r3);	KL(r2,r3,r0,r4,r1,29);
+	SI4(r2,r3,r0,r4,r1);	KL(r2,r0,r1,r4,r3,28);
+	SI3(r2,r0,r1,r4,r3);	KL(r1,r2,r3,r4,r0,27);
+	SI2(r1,r2,r3,r4,r0);	KL(r2,r0,r4,r3,r1,26);
+	SI1(r2,r0,r4,r3,r1);	KL(r1,r0,r4,r3,r2,25);
+	SI0(r1,r0,r4,r3,r2);	KL(r4,r2,r0,r1,r3,24);
+	SI7(r4,r2,r0,r1,r3);	KL(r2,r1,r4,r3,r0,23);
+	SI6(r2,r1,r4,r3,r0);	KL(r4,r0,r3,r2,r1,22);
+	SI5(r4,r0,r3,r2,r1);	KL(r0,r1,r4,r3,r2,21);
+	SI4(r0,r1,r4,r3,r2);	KL(r0,r4,r2,r3,r1,20);
+	SI3(r0,r4,r2,r3,r1);	KL(r2,r0,r1,r3,r4,19);
+	SI2(r2,r0,r1,r3,r4);	KL(r0,r4,r3,r1,r2,18);
+	SI1(r0,r4,r3,r1,r2);	KL(r2,r4,r3,r1,r0,17);
+	SI0(r2,r4,r3,r1,r0);	KL(r3,r0,r4,r2,r1,16);
+	SI7(r3,r0,r4,r2,r1);	KL(r0,r2,r3,r1,r4,15);
+	SI6(r0,r2,r3,r1,r4);	KL(r3,r4,r1,r0,r2,14);
+	SI5(r3,r4,r1,r0,r2);	KL(r4,r2,r3,r1,r0,13);
+	SI4(r4,r2,r3,r1,r0);	KL(r4,r3,r0,r1,r2,12);
+	SI3(r4,r3,r0,r1,r2);	KL(r0,r4,r2,r1,r3,11);
+	SI2(r0,r4,r2,r1,r3);	KL(r4,r3,r1,r2,r0,10);
+	SI1(r4,r3,r1,r2,r0);	KL(r0,r3,r1,r2,r4,9);
+	SI0(r0,r3,r1,r2,r4);	KL(r1,r4,r3,r0,r2,8);
+	SI7(r1,r4,r3,r0,r2);	KL(r4,r0,r1,r2,r3,7);
+	SI6(r4,r0,r1,r2,r3);	KL(r1,r3,r2,r4,r0,6);
+	SI5(r1,r3,r2,r4,r0);	KL(r3,r0,r1,r2,r4,5);
+	SI4(r3,r0,r1,r2,r4);	KL(r3,r1,r4,r2,r0,4);
+	SI3(r3,r1,r4,r2,r0);	KL(r4,r3,r0,r2,r1,3);
+	SI2(r4,r3,r0,r2,r1);	KL(r3,r1,r2,r0,r4,2);
+	SI1(r3,r1,r2,r0,r4);	KL(r4,r1,r2,r0,r3,1);
+	SI0(r4,r1,r2,r0,r3);	K(r2,r3,r1,r4,0);
+
+	d[0] = cpu_to_le32(r2);
+	d[1] = cpu_to_le32(r3);
+	d[2] = cpu_to_le32(r1);
+	d[3] = cpu_to_le32(r4);
+}
+
+static struct crypto_alg serpent_alg = {
+	.cra_name		=	"serpent",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	SERPENT_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct serpent_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(serpent_alg.cra_list),
+	.cra_u			=	{ .cipher = {
+	.cia_min_keysize	=	SERPENT_MIN_KEY_SIZE,
+	.cia_max_keysize	=	SERPENT_MAX_KEY_SIZE,
+	.cia_ivsize		=	SERPENT_BLOCK_SIZE,
+	.cia_setkey   		= 	setkey,
+	.cia_encrypt 		=	encrypt,
+	.cia_decrypt  		=	decrypt } }
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&serpent_alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&serpent_alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Serpent Cipher Algorithm");
+MODULE_AUTHOR("Dag Arne Osvik <osvik@ii.uib.no>");
diff -urN linux-2.4.22-pre2/crypto/sha1.c linux-2.4.22-pre3/crypto/sha1.c
--- linux-2.4.22-pre2/crypto/sha1.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/sha1.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,208 @@
+/*
+ * Cryptographic API.
+ *
+ * SHA1 Secure Hash Algorithm.
+ *
+ * Derived from cryptoapi implementation, adapted for in-place
+ * scatterlist interface.  Originally based on the public domain
+ * implementation written by Steve Reid.
+ *
+ * Copyright (c) Alan Smithee.
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/crypto.h>
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+
+#define SHA1_DIGEST_SIZE	20
+#define SHA1_HMAC_BLOCK_SIZE	64
+
+static inline u32 rol(u32 value, u32 bits)
+{
+	return (((value) << (bits)) | ((value) >> (32 - (bits))));
+}
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+# define blk0(i) block32[i]
+
+#define blk(i) (block32[i&15] = rol(block32[(i+13)&15]^block32[(i+8)&15] \
+    ^block32[(i+2)&15]^block32[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5); \
+                        w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5); \
+                        w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5); \
+                        w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+struct sha1_ctx {
+        u64 count;
+        u32 state[5];
+        u8 buffer[64];
+};
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+static void sha1_transform(u32 *state, const u8 *in)
+{
+	u32 a, b, c, d, e;
+	u32 block32[16];
+
+	/* convert/copy data to workspace */
+	for (a = 0; a < sizeof(block32)/sizeof(u32); a++)
+	  block32[a] = be32_to_cpu (((const u32 *)in)[a]);
+
+	/* Copy context->state[] to working vars */
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+
+	/* 4 rounds of 20 operations each. Loop unrolled. */
+	R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+	R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+	R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+	R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+	R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+	R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+	R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+	R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+	R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+	R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+	R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+	R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+	R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+	R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+	R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+	R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+	R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+	R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+	R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+	R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+	/* Add the working vars back into context.state[] */
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+	state[4] += e;
+	/* Wipe variables */
+	a = b = c = d = e = 0;
+	memset (block32, 0x00, sizeof block32);
+}
+
+static void sha1_init(void *ctx)
+{
+	struct sha1_ctx *sctx = ctx;
+	static const struct sha1_ctx initstate = {
+	  0,
+	  { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 },
+	  { 0, }
+	};
+
+	*sctx = initstate;
+}
+
+static void sha1_update(void *ctx, const u8 *data, unsigned int len)
+{
+	struct sha1_ctx *sctx = ctx;
+	unsigned int i, j;
+
+	j = (sctx->count >> 3) & 0x3f;
+	sctx->count += len << 3;
+
+	if ((j + len) > 63) {
+		memcpy(&sctx->buffer[j], data, (i = 64-j));
+		sha1_transform(sctx->state, sctx->buffer);
+		for ( ; i + 63 < len; i += 64) {
+			sha1_transform(sctx->state, &data[i]);
+		}
+		j = 0;
+	}
+	else i = 0;
+	memcpy(&sctx->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+static void sha1_final(void* ctx, u8 *out)
+{
+	struct sha1_ctx *sctx = ctx;
+	u32 i, j, index, padlen;
+	u64 t;
+	u8 bits[8] = { 0, };
+	static const u8 padding[64] = { 0x80, };
+
+	t = sctx->count;
+	bits[7] = 0xff & t; t>>=8;
+	bits[6] = 0xff & t; t>>=8;
+	bits[5] = 0xff & t; t>>=8;
+	bits[4] = 0xff & t; t>>=8;
+	bits[3] = 0xff & t; t>>=8;
+	bits[2] = 0xff & t; t>>=8;
+	bits[1] = 0xff & t; t>>=8;
+	bits[0] = 0xff & t;
+
+	/* Pad out to 56 mod 64 */
+	index = (sctx->count >> 3) & 0x3f;
+	padlen = (index < 56) ? (56 - index) : ((64+56) - index);
+	sha1_update(sctx, padding, padlen);
+
+	/* Append length */
+	sha1_update(sctx, bits, sizeof bits); 
+
+	/* Store state in digest */
+	for (i = j = 0; i < 5; i++, j += 4) {
+		u32 t2 = sctx->state[i];
+		out[j+3] = t2 & 0xff; t2>>=8;
+		out[j+2] = t2 & 0xff; t2>>=8;
+		out[j+1] = t2 & 0xff; t2>>=8;
+		out[j  ] = t2 & 0xff;
+	}
+
+	/* Wipe context */
+	memset(sctx, 0, sizeof *sctx);
+}
+
+static struct crypto_alg alg = {
+	.cra_name	=	"sha1",
+	.cra_flags	=	CRYPTO_ALG_TYPE_DIGEST,
+	.cra_blocksize	=	SHA1_HMAC_BLOCK_SIZE,
+	.cra_ctxsize	=	sizeof(struct sha1_ctx),
+	.cra_module	=	THIS_MODULE,
+	.cra_list       =       LIST_HEAD_INIT(alg.cra_list),
+	.cra_u		=	{ .digest = {
+	.dia_digestsize	=	SHA1_DIGEST_SIZE,
+	.dia_init   	= 	sha1_init,
+	.dia_update 	=	sha1_update,
+	.dia_final  	=	sha1_final } }
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
diff -urN linux-2.4.22-pre2/crypto/sha256.c linux-2.4.22-pre3/crypto/sha256.c
--- linux-2.4.22-pre2/crypto/sha256.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/sha256.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,362 @@
+/*
+ * Cryptographic API.
+ *
+ * SHA-256, as specified in
+ * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
+ *
+ * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>.
+ *
+ * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/crypto.h>
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+
+#define SHA256_DIGEST_SIZE	32
+#define SHA256_HMAC_BLOCK_SIZE	64
+
+struct sha256_ctx {
+	u32 count[2];
+	u32 state[8];
+	u8 buf[128];
+};
+
+static inline u32 Ch(u32 x, u32 y, u32 z)
+{
+	return ((x & y) ^ (~x & z));
+}
+
+static inline u32 Maj(u32 x, u32 y, u32 z)
+{
+	return ((x & y) ^ (x & z) ^ (y & z));
+}
+
+static inline u32 RORu32(u32 x, u32 y)
+{
+	return (x >> y) | (x << (32 - y));
+}
+
+#define e0(x)       (RORu32(x, 2) ^ RORu32(x,13) ^ RORu32(x,22))
+#define e1(x)       (RORu32(x, 6) ^ RORu32(x,11) ^ RORu32(x,25))
+#define s0(x)       (RORu32(x, 7) ^ RORu32(x,18) ^ (x >> 3))
+#define s1(x)       (RORu32(x,17) ^ RORu32(x,19) ^ (x >> 10))
+
+#define H0         0x6a09e667
+#define H1         0xbb67ae85
+#define H2         0x3c6ef372
+#define H3         0xa54ff53a
+#define H4         0x510e527f
+#define H5         0x9b05688c
+#define H6         0x1f83d9ab
+#define H7         0x5be0cd19
+
+static inline void LOAD_OP(int I, u32 *W, const u8 *input)
+{
+	u32 t1 = input[(4 * I)] & 0xff;
+
+	t1 <<= 8;
+	t1 |= input[(4 * I) + 1] & 0xff;
+	t1 <<= 8;
+	t1 |= input[(4 * I) + 2] & 0xff;
+	t1 <<= 8;
+	t1 |= input[(4 * I) + 3] & 0xff;
+	W[I] = t1;
+}
+
+static inline void BLEND_OP(int I, u32 *W)
+{
+	W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
+}
+
+static void sha256_transform(u32 *state, const u8 *input)
+{
+	u32 a, b, c, d, e, f, g, h, t1, t2;
+	u32 W[64];
+	int i;
+
+	/* load the input */
+	for (i = 0; i < 16; i++)
+		LOAD_OP(i, W, input);
+
+	/* now blend */
+	for (i = 16; i < 64; i++)
+		BLEND_OP(i, W);
+    
+	/* load the state into our registers */
+	a=state[0];  b=state[1];  c=state[2];  d=state[3];
+	e=state[4];  f=state[5];  g=state[6];  h=state[7];
+
+	/* now iterate */
+	t1 = h + e1(e) + Ch(e,f,g) + 0x428a2f98 + W[ 0];
+	t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+	t1 = g + e1(d) + Ch(d,e,f) + 0x71374491 + W[ 1];
+	t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+	t1 = f + e1(c) + Ch(c,d,e) + 0xb5c0fbcf + W[ 2];
+	t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+	t1 = e + e1(b) + Ch(b,c,d) + 0xe9b5dba5 + W[ 3];
+	t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+	t1 = d + e1(a) + Ch(a,b,c) + 0x3956c25b + W[ 4];
+	t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+	t1 = c + e1(h) + Ch(h,a,b) + 0x59f111f1 + W[ 5];
+	t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+	t1 = b + e1(g) + Ch(g,h,a) + 0x923f82a4 + W[ 6];
+	t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+	t1 = a + e1(f) + Ch(f,g,h) + 0xab1c5ed5 + W[ 7];
+	t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
+
+	t1 = h + e1(e) + Ch(e,f,g) + 0xd807aa98 + W[ 8];
+	t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+	t1 = g + e1(d) + Ch(d,e,f) + 0x12835b01 + W[ 9];
+	t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+	t1 = f + e1(c) + Ch(c,d,e) + 0x243185be + W[10];
+	t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+	t1 = e + e1(b) + Ch(b,c,d) + 0x550c7dc3 + W[11];
+	t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+	t1 = d + e1(a) + Ch(a,b,c) + 0x72be5d74 + W[12];
+	t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+	t1 = c + e1(h) + Ch(h,a,b) + 0x80deb1fe + W[13];
+	t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+	t1 = b + e1(g) + Ch(g,h,a) + 0x9bdc06a7 + W[14];
+	t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+	t1 = a + e1(f) + Ch(f,g,h) + 0xc19bf174 + W[15];
+	t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
+
+	t1 = h + e1(e) + Ch(e,f,g) + 0xe49b69c1 + W[16];
+	t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+	t1 = g + e1(d) + Ch(d,e,f) + 0xefbe4786 + W[17];
+	t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+	t1 = f + e1(c) + Ch(c,d,e) + 0x0fc19dc6 + W[18];
+	t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+	t1 = e + e1(b) + Ch(b,c,d) + 0x240ca1cc + W[19];
+	t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+	t1 = d + e1(a) + Ch(a,b,c) + 0x2de92c6f + W[20];
+	t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+	t1 = c + e1(h) + Ch(h,a,b) + 0x4a7484aa + W[21];
+	t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+	t1 = b + e1(g) + Ch(g,h,a) + 0x5cb0a9dc + W[22];
+	t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+	t1 = a + e1(f) + Ch(f,g,h) + 0x76f988da + W[23];
+	t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
+
+	t1 = h + e1(e) + Ch(e,f,g) + 0x983e5152 + W[24];
+	t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+	t1 = g + e1(d) + Ch(d,e,f) + 0xa831c66d + W[25];
+	t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+	t1 = f + e1(c) + Ch(c,d,e) + 0xb00327c8 + W[26];
+	t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+	t1 = e + e1(b) + Ch(b,c,d) + 0xbf597fc7 + W[27];
+	t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+	t1 = d + e1(a) + Ch(a,b,c) + 0xc6e00bf3 + W[28];
+	t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+	t1 = c + e1(h) + Ch(h,a,b) + 0xd5a79147 + W[29];
+	t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+	t1 = b + e1(g) + Ch(g,h,a) + 0x06ca6351 + W[30];
+	t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+	t1 = a + e1(f) + Ch(f,g,h) + 0x14292967 + W[31];
+	t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
+
+	t1 = h + e1(e) + Ch(e,f,g) + 0x27b70a85 + W[32];
+	t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+	t1 = g + e1(d) + Ch(d,e,f) + 0x2e1b2138 + W[33];
+	t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+	t1 = f + e1(c) + Ch(c,d,e) + 0x4d2c6dfc + W[34];
+	t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+	t1 = e + e1(b) + Ch(b,c,d) + 0x53380d13 + W[35];
+	t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+	t1 = d + e1(a) + Ch(a,b,c) + 0x650a7354 + W[36];
+	t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+	t1 = c + e1(h) + Ch(h,a,b) + 0x766a0abb + W[37];
+	t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+	t1 = b + e1(g) + Ch(g,h,a) + 0x81c2c92e + W[38];
+	t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+	t1 = a + e1(f) + Ch(f,g,h) + 0x92722c85 + W[39];
+	t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
+
+	t1 = h + e1(e) + Ch(e,f,g) + 0xa2bfe8a1 + W[40];
+	t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+	t1 = g + e1(d) + Ch(d,e,f) + 0xa81a664b + W[41];
+	t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+	t1 = f + e1(c) + Ch(c,d,e) + 0xc24b8b70 + W[42];
+	t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+	t1 = e + e1(b) + Ch(b,c,d) + 0xc76c51a3 + W[43];
+	t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+	t1 = d + e1(a) + Ch(a,b,c) + 0xd192e819 + W[44];
+	t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+	t1 = c + e1(h) + Ch(h,a,b) + 0xd6990624 + W[45];
+	t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+	t1 = b + e1(g) + Ch(g,h,a) + 0xf40e3585 + W[46];
+	t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+	t1 = a + e1(f) + Ch(f,g,h) + 0x106aa070 + W[47];
+	t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
+
+	t1 = h + e1(e) + Ch(e,f,g) + 0x19a4c116 + W[48];
+	t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+	t1 = g + e1(d) + Ch(d,e,f) + 0x1e376c08 + W[49];
+	t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+	t1 = f + e1(c) + Ch(c,d,e) + 0x2748774c + W[50];
+	t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+	t1 = e + e1(b) + Ch(b,c,d) + 0x34b0bcb5 + W[51];
+	t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+	t1 = d + e1(a) + Ch(a,b,c) + 0x391c0cb3 + W[52];
+	t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+	t1 = c + e1(h) + Ch(h,a,b) + 0x4ed8aa4a + W[53];
+	t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+	t1 = b + e1(g) + Ch(g,h,a) + 0x5b9cca4f + W[54];
+	t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+	t1 = a + e1(f) + Ch(f,g,h) + 0x682e6ff3 + W[55];
+	t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
+
+	t1 = h + e1(e) + Ch(e,f,g) + 0x748f82ee + W[56];
+	t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+	t1 = g + e1(d) + Ch(d,e,f) + 0x78a5636f + W[57];
+	t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+	t1 = f + e1(c) + Ch(c,d,e) + 0x84c87814 + W[58];
+	t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+	t1 = e + e1(b) + Ch(b,c,d) + 0x8cc70208 + W[59];
+	t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+	t1 = d + e1(a) + Ch(a,b,c) + 0x90befffa + W[60];
+	t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+	t1 = c + e1(h) + Ch(h,a,b) + 0xa4506ceb + W[61];
+	t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+	t1 = b + e1(g) + Ch(g,h,a) + 0xbef9a3f7 + W[62];
+	t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+	t1 = a + e1(f) + Ch(f,g,h) + 0xc67178f2 + W[63];
+	t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
+
+	state[0] += a; state[1] += b; state[2] += c; state[3] += d;
+	state[4] += e; state[5] += f; state[6] += g; state[7] += h;
+
+	/* clear any sensitive info... */
+	a = b = c = d = e = f = g = h = t1 = t2 = 0;
+	memset(W, 0, 64 * sizeof(u32));
+}
+
+static void sha256_init(void *ctx)
+{
+	struct sha256_ctx *sctx = ctx;
+	sctx->state[0] = H0;
+	sctx->state[1] = H1;
+	sctx->state[2] = H2;
+	sctx->state[3] = H3;
+	sctx->state[4] = H4;
+	sctx->state[5] = H5;
+	sctx->state[6] = H6;
+	sctx->state[7] = H7;
+	sctx->count[0] = sctx->count[1] = 0;
+	memset(sctx->buf, 0, sizeof(sctx->buf));
+}
+
+static void sha256_update(void *ctx, const u8 *data, unsigned int len)
+{
+	struct sha256_ctx *sctx = ctx;
+	unsigned int i, index, part_len;
+
+	/* Compute number of bytes mod 128 */
+	index = (unsigned int)((sctx->count[0] >> 3) & 0x3f);
+
+	/* Update number of bits */
+	if ((sctx->count[0] += (len << 3)) < (len << 3)) {
+		sctx->count[1]++;
+		sctx->count[1] += (len >> 29);
+	}
+
+	part_len = 64 - index;
+
+	/* Transform as many times as possible. */
+	if (len >= part_len) {
+		memcpy(&sctx->buf[index], data, part_len);
+		sha256_transform(sctx->state, sctx->buf);
+
+		for (i = part_len; i + 63 < len; i += 64)
+			sha256_transform(sctx->state, &data[i]);
+		index = 0;
+	} else {
+		i = 0;
+	}
+	
+	/* Buffer remaining input */
+	memcpy(&sctx->buf[index], &data[i], len-i);
+}
+
+static void sha256_final(void* ctx, u8 *out)
+{
+	struct sha256_ctx *sctx = ctx;
+	u8 bits[8];
+	unsigned int index, pad_len, t;
+	int i, j;
+	const u8 padding[64] = { 0x80, };
+
+	/* Save number of bits */
+	t = sctx->count[0];
+	bits[7] = t; t >>= 8;
+	bits[6] = t; t >>= 8;
+	bits[5] = t; t >>= 8;
+	bits[4] = t;
+	t = sctx->count[1];
+	bits[3] = t; t >>= 8;
+	bits[2] = t; t >>= 8;
+	bits[1] = t; t >>= 8;
+	bits[0] = t;
+
+	/* Pad out to 56 mod 64. */
+	index = (sctx->count[0] >> 3) & 0x3f;
+	pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
+	sha256_update(sctx, padding, pad_len);
+
+	/* Append length (before padding) */
+	sha256_update(sctx, bits, 8);
+
+	/* Store state in digest */
+	for (i = j = 0; i < 8; i++, j += 4) {
+		t = sctx->state[i];
+		out[j+3] = t; t >>= 8;
+		out[j+2] = t; t >>= 8;
+		out[j+1] = t; t >>= 8;
+		out[j  ] = t;
+	}
+
+	/* Zeroize sensitive information. */
+	memset(sctx, 0, sizeof(*sctx));
+}
+
+
+static struct crypto_alg alg = {
+	.cra_name	=	"sha256",
+	.cra_flags	=	CRYPTO_ALG_TYPE_DIGEST,
+	.cra_blocksize	=	SHA256_HMAC_BLOCK_SIZE,
+	.cra_ctxsize	=	sizeof(struct sha256_ctx),
+	.cra_module	=	THIS_MODULE,
+	.cra_list       =       LIST_HEAD_INIT(alg.cra_list),
+	.cra_u		=	{ .digest = {
+	.dia_digestsize	=	SHA256_DIGEST_SIZE,
+	.dia_init   	= 	sha256_init,
+	.dia_update 	=	sha256_update,
+	.dia_final  	=	sha256_final } }
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm");
diff -urN linux-2.4.22-pre2/crypto/sha512.c linux-2.4.22-pre3/crypto/sha512.c
--- linux-2.4.22-pre2/crypto/sha512.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/sha512.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,373 @@
+/* SHA-512 code by Jean-Luc Cooke <jlcooke@certainkey.com>
+ *
+ * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) 2003 Kyle McMartin <kyle@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/crypto.h>
+
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+
+#define SHA384_DIGEST_SIZE 48
+#define SHA512_DIGEST_SIZE 64
+#define SHA384_HMAC_BLOCK_SIZE  96
+#define SHA512_HMAC_BLOCK_SIZE 128
+
+struct sha512_ctx {
+	u64 state[8];
+	u32 count[4];
+	u8 buf[128];
+};
+
+static inline u64 Ch(u64 x, u64 y, u64 z)
+{
+        return ((x & y) ^ (~x & z));
+}
+
+static inline u64 Maj(u64 x, u64 y, u64 z)
+{
+        return ((x & y) ^ (x & z) ^ (y & z));
+}
+
+static inline u64 RORu64(u64 x, u64 y)
+{
+        return (x >> y) | (x << (64 - y));
+}
+
+const u64 sha512_K[80] = {
+        0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+        0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+        0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
+        0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+        0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+        0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+        0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
+        0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+        0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
+        0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+        0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
+        0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+        0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
+        0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+        0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+        0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+        0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
+        0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+        0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
+        0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+        0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
+        0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+        0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
+        0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+        0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+        0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+        0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
+};
+
+#define e0(x)       (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
+#define e1(x)       (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41))
+#define s0(x)       (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7))
+#define s1(x)       (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6))
+
+/* H* initial state for SHA-512 */
+#define H0         0x6a09e667f3bcc908ULL
+#define H1         0xbb67ae8584caa73bULL
+#define H2         0x3c6ef372fe94f82bULL
+#define H3         0xa54ff53a5f1d36f1ULL
+#define H4         0x510e527fade682d1ULL
+#define H5         0x9b05688c2b3e6c1fULL
+#define H6         0x1f83d9abfb41bd6bULL
+#define H7         0x5be0cd19137e2179ULL
+
+/* H'* initial state for SHA-384 */
+#define HP0 0xcbbb9d5dc1059ed8ULL
+#define HP1 0x629a292a367cd507ULL
+#define HP2 0x9159015a3070dd17ULL
+#define HP3 0x152fecd8f70e5939ULL
+#define HP4 0x67332667ffc00b31ULL
+#define HP5 0x8eb44a8768581511ULL
+#define HP6 0xdb0c2e0d64f98fa7ULL
+#define HP7 0x47b5481dbefa4fa4ULL
+
+static inline void LOAD_OP(int I, u64 *W, const u8 *input)
+{
+        u64 t1  = input[(8*I)  ] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+1] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+2] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+3] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+4] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+5] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+6] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+7] & 0xff;
+        W[I] = t1;
+}
+
+static inline void BLEND_OP(int I, u64 *W)
+{
+        W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
+}
+
+static void
+sha512_transform(u64 *state, const u8 *input)
+{
+	u64 a, b, c, d, e, f, g, h, t1, t2;
+	u64 W[80];
+
+	int i;
+
+	/* load the input */
+        for (i = 0; i < 16; i++)
+                LOAD_OP(i, W, input);
+
+        for (i = 16; i < 80; i++) {
+                BLEND_OP(i, W);
+        }
+
+	/* load the state into our registers */
+	a=state[0];   b=state[1];   c=state[2];   d=state[3];  
+	e=state[4];   f=state[5];   g=state[6];   h=state[7];  
+  
+	/* now iterate */
+	for (i=0; i<80; i+=8) {
+		t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i  ] + W[i  ];
+		t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+		t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1];
+		t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+		t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2];
+		t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+		t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3];
+		t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+		t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4];
+		t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+		t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5];
+		t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+		t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6];
+		t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+		t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7];
+		t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
+	}
+  
+	state[0] += a; state[1] += b; state[2] += c; state[3] += d;  
+	state[4] += e; state[5] += f; state[6] += g; state[7] += h;  
+
+	/* erase our data */
+	a = b = c = d = e = f = g = h = t1 = t2 = 0;
+	memset(W, 0, 80 * sizeof(u64));
+}
+
+static void
+sha512_init(void *ctx)
+{
+        struct sha512_ctx *sctx = ctx;
+	sctx->state[0] = H0;
+	sctx->state[1] = H1;
+	sctx->state[2] = H2;
+	sctx->state[3] = H3;
+	sctx->state[4] = H4;
+	sctx->state[5] = H5;
+	sctx->state[6] = H6;
+	sctx->state[7] = H7;
+	sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
+	memset(sctx->buf, 0, sizeof(sctx->buf));
+}
+
+static void
+sha384_init(void *ctx)
+{
+        struct sha512_ctx *sctx = ctx;
+        sctx->state[0] = HP0;
+        sctx->state[1] = HP1;
+        sctx->state[2] = HP2;
+        sctx->state[3] = HP3;
+        sctx->state[4] = HP4;
+        sctx->state[5] = HP5;
+        sctx->state[6] = HP6;
+        sctx->state[7] = HP7;
+        sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
+        memset(sctx->buf, 0, sizeof(sctx->buf));
+}
+
+static void
+sha512_update(void *ctx, const u8 *data, unsigned int len)
+{
+        struct sha512_ctx *sctx = ctx;
+
+	unsigned int i, index, part_len;
+
+	/* Compute number of bytes mod 128 */
+	index = (unsigned int)((sctx->count[0] >> 3) & 0x7F);
+	
+	/* Update number of bits */
+	if ((sctx->count[0] += (len << 3)) < (len << 3)) {
+		if ((sctx->count[1] += 1) < 1)
+			if ((sctx->count[2] += 1) < 1)
+				sctx->count[3]++;
+		sctx->count[1] += (len >> 29);
+	}
+	
+        part_len = 128 - index;
+	
+	/* Transform as many times as possible. */
+	if (len >= part_len) {
+		memcpy(&sctx->buf[index], data, part_len);
+		sha512_transform(sctx->state, sctx->buf);
+
+		for (i = part_len; i + 127 < len; i+=128)
+			sha512_transform(sctx->state, &data[i]);
+
+		index = 0;
+	} else {
+		i = 0;
+	}
+
+	/* Buffer remaining input */
+	memcpy(&sctx->buf[index], &data[i], len - i);
+}
+
+static void
+sha512_final(void *ctx, u8 *hash)
+{
+        struct sha512_ctx *sctx = ctx;
+	
+        const static u8 padding[128] = { 0x80, };
+
+        u32 t;
+	u64 t2;
+        u8 bits[128];
+	unsigned int index, pad_len;
+	int i, j;
+
+        index = pad_len = t = i = j = 0;
+        t2 = 0;
+
+	/* Save number of bits */
+	t = sctx->count[0];
+	bits[15] = t; t>>=8;
+	bits[14] = t; t>>=8;
+	bits[13] = t; t>>=8;
+	bits[12] = t; 
+	t = sctx->count[1];
+	bits[11] = t; t>>=8;
+	bits[10] = t; t>>=8;
+	bits[9 ] = t; t>>=8;
+	bits[8 ] = t; 
+	t = sctx->count[2];
+	bits[7 ] = t; t>>=8;
+	bits[6 ] = t; t>>=8;
+	bits[5 ] = t; t>>=8;
+	bits[4 ] = t; 
+	t = sctx->count[3];
+	bits[3 ] = t; t>>=8;
+	bits[2 ] = t; t>>=8;
+	bits[1 ] = t; t>>=8;
+	bits[0 ] = t; 
+
+	/* Pad out to 112 mod 128. */
+	index = (sctx->count[0] >> 3) & 0x7f;
+	pad_len = (index < 112) ? (112 - index) : ((128+112) - index);
+	sha512_update(sctx, padding, pad_len);
+
+	/* Append length (before padding) */
+	sha512_update(sctx, bits, 16);
+
+	/* Store state in digest */
+	for (i = j = 0; i < 8; i++, j += 8) {
+		t2 = sctx->state[i];
+		hash[j+7] = (char)t2 & 0xff; t2>>=8;
+		hash[j+6] = (char)t2 & 0xff; t2>>=8;
+		hash[j+5] = (char)t2 & 0xff; t2>>=8;
+		hash[j+4] = (char)t2 & 0xff; t2>>=8;
+		hash[j+3] = (char)t2 & 0xff; t2>>=8;
+		hash[j+2] = (char)t2 & 0xff; t2>>=8;
+		hash[j+1] = (char)t2 & 0xff; t2>>=8;
+		hash[j  ] = (char)t2 & 0xff;
+	}
+	
+	/* Zeroize sensitive information. */
+	memset(sctx, 0, sizeof(struct sha512_ctx));
+}
+
+static void sha384_final(void *ctx, u8 *hash)
+{
+        struct sha512_ctx *sctx = ctx;
+        u8 D[64];
+
+        sha512_final(sctx, D);
+
+        memcpy(hash, D, 48);
+        memset(D, 0, 64);
+}
+
+static struct crypto_alg sha512 = {
+        .cra_name       = "sha512",
+        .cra_flags      = CRYPTO_ALG_TYPE_DIGEST,
+        .cra_blocksize  = SHA512_HMAC_BLOCK_SIZE,
+        .cra_ctxsize    = sizeof(struct sha512_ctx),
+        .cra_module     = THIS_MODULE,
+        .cra_list       = LIST_HEAD_INIT(sha512.cra_list),
+        .cra_u          = { .digest = {
+                                .dia_digestsize = SHA512_DIGEST_SIZE,
+                                .dia_init       = sha512_init,
+                                .dia_update     = sha512_update,
+                                .dia_final      = sha512_final }
+        }
+};
+
+static struct crypto_alg sha384 = {
+        .cra_name       = "sha384",
+        .cra_flags      = CRYPTO_ALG_TYPE_DIGEST,
+        .cra_blocksize  = SHA384_HMAC_BLOCK_SIZE,
+        .cra_ctxsize    = sizeof(struct sha512_ctx),
+        .cra_module     = THIS_MODULE,
+        .cra_list       = LIST_HEAD_INIT(sha384.cra_list),
+        .cra_u          = { .digest = {
+                                .dia_digestsize = SHA384_DIGEST_SIZE,
+                                .dia_init       = sha384_init,
+                                .dia_update     = sha512_update,
+                                .dia_final      = sha384_final }
+        }
+};
+
+static int __init init(void)
+{
+        int ret = 0;
+
+        if ((ret = crypto_register_alg(&sha384)) < 0)
+                goto out;
+        if ((ret = crypto_register_alg(&sha512)) < 0)
+                crypto_unregister_alg(&sha384);
+out:
+        return ret;
+}
+
+static void __exit fini(void)
+{
+        crypto_unregister_alg(&sha384);
+        crypto_unregister_alg(&sha512);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms");
diff -urN linux-2.4.22-pre2/crypto/tcrypt.c linux-2.4.22-pre3/crypto/tcrypt.c
--- linux-2.4.22-pre2/crypto/tcrypt.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/tcrypt.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,2418 @@
+/* 
+ * Quick & dirty crypto testing module.
+ *
+ * This will only exist until we have a better testing mechanism
+ * (e.g. a char device).
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/highmem.h>
+#include "tcrypt.h"
+
+/*
+ * Need to kmalloc() memory for testing kmap().
+ */
+#define TVMEMSIZE	4096
+#define XBUFSIZE	32768
+
+/*
+ * Indexes into the xbuf to simulate cross-page access.
+ */
+#define IDX1		37
+#define IDX2		32400
+#define IDX3		1
+#define IDX4		8193
+#define IDX5		22222
+#define IDX6		17101
+#define IDX7		27333
+#define IDX8		3000
+
+static int mode = 0;
+static char *xbuf;
+static char *tvmem;
+
+static char *check[] = {
+	"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
+	"twofish", "serpent", "sha384", "sha512", "md4", "aes", "deflate",
+	 NULL
+};
+
+static void
+hexdump(unsigned char *buf, unsigned int len)
+{
+	while (len--)
+		printk("%02x", *buf++);
+
+	printk("\n");
+}
+
+static void
+test_md5(void)
+{
+	char *p;
+	unsigned int i;
+	struct scatterlist sg[2];
+	char result[128];
+	struct crypto_tfm *tfm;
+	struct md5_testvec *md5_tv;
+	unsigned int tsize;
+
+	printk("\ntesting md5\n");
+
+	tsize = sizeof (md5_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, md5_tv_template, tsize);
+	md5_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("md5", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for md5\n");
+		return;
+	}
+
+	for (i = 0; i < MD5_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = md5_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = strlen(md5_tv[i].plaintext);
+
+		crypto_digest_init(tfm);
+		crypto_digest_update(tfm, sg, 1);
+		crypto_digest_final(tfm, result);
+
+		hexdump(result, crypto_tfm_alg_digestsize(tfm));
+		printk("%s\n",
+		       memcmp(result, md5_tv[i].digest,
+			      crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+		       "pass");
+	}
+
+	printk("\ntesting md5 across pages\n");
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, XBUFSIZE);
+	memcpy(&xbuf[IDX1], "abcdefghijklm", 13);
+	memcpy(&xbuf[IDX2], "nopqrstuvwxyz", 13);
+
+	p = &xbuf[IDX1];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 13;
+
+	p = &xbuf[IDX2];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 13;
+
+	memset(result, 0, sizeof (result));
+	crypto_digest_digest(tfm, sg, 2, result);
+	hexdump(result, crypto_tfm_alg_digestsize(tfm));
+
+	printk("%s\n",
+	       memcmp(result, md5_tv[4].digest,
+		      crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+	crypto_free_tfm(tfm);
+}
+
+#ifdef CONFIG_CRYPTO_HMAC
+static void
+test_hmac_md5(void)
+{
+	char *p;
+	unsigned int i, klen;
+	struct scatterlist sg[2];
+	char result[128];
+	struct crypto_tfm *tfm;
+	struct hmac_md5_testvec *hmac_md5_tv;
+	unsigned int tsize;
+
+	tfm = crypto_alloc_tfm("md5", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for md5\n");
+		return;
+	}
+
+	printk("\ntesting hmac_md5\n");
+	
+	tsize = sizeof (hmac_md5_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		goto out;
+	}
+
+	memcpy(tvmem, hmac_md5_tv_template, tsize);
+	hmac_md5_tv = (void *) tvmem;
+
+	for (i = 0; i < HMAC_MD5_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = hmac_md5_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = strlen(hmac_md5_tv[i].plaintext);
+
+		klen = strlen(hmac_md5_tv[i].key);
+		crypto_hmac(tfm, hmac_md5_tv[i].key, &klen, sg, 1, result);
+
+		hexdump(result, crypto_tfm_alg_digestsize(tfm));
+		printk("%s\n",
+		       memcmp(result, hmac_md5_tv[i].digest,
+			      crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+		       "pass");
+	}
+
+	printk("\ntesting hmac_md5 across pages\n");
+
+	memset(xbuf, 0, XBUFSIZE);
+
+	memcpy(&xbuf[IDX1], "what do ya want ", 16);
+	memcpy(&xbuf[IDX2], "for nothing?", 12);
+
+	p = &xbuf[IDX1];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 16;
+
+	p = &xbuf[IDX2];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 12;
+
+	memset(result, 0, sizeof (result));
+	klen = strlen(hmac_md5_tv[7].key);
+	crypto_hmac(tfm, hmac_md5_tv[7].key, &klen, sg, 2, result);
+	hexdump(result, crypto_tfm_alg_digestsize(tfm));
+
+	printk("%s\n",
+	       memcmp(result, hmac_md5_tv[7].digest,
+		      crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+out:
+	crypto_free_tfm(tfm);
+}
+
+static void
+test_hmac_sha1(void)
+{
+	char *p;
+	unsigned int i, klen;
+	struct crypto_tfm *tfm;
+	struct hmac_sha1_testvec *hmac_sha1_tv;
+	struct scatterlist sg[2];
+	unsigned int tsize;
+	char result[SHA1_DIGEST_SIZE];
+
+	tfm = crypto_alloc_tfm("sha1", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for sha1\n");
+		return;
+	}
+
+	printk("\ntesting hmac_sha1\n");
+
+	tsize = sizeof (hmac_sha1_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		goto out;
+	}
+
+	memcpy(tvmem, hmac_sha1_tv_template, tsize);
+	hmac_sha1_tv = (void *) tvmem;
+
+	for (i = 0; i < HMAC_SHA1_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = hmac_sha1_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = strlen(hmac_sha1_tv[i].plaintext);
+
+		klen = strlen(hmac_sha1_tv[i].key);
+		
+		crypto_hmac(tfm, hmac_sha1_tv[i].key, &klen, sg, 1, result);
+
+		hexdump(result, sizeof (result));
+		printk("%s\n",
+		       memcmp(result, hmac_sha1_tv[i].digest,
+			      crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+		       "pass");
+	}
+
+	printk("\ntesting hmac_sha1 across pages\n");
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, XBUFSIZE);
+
+	memcpy(&xbuf[IDX1], "what do ya want ", 16);
+	memcpy(&xbuf[IDX2], "for nothing?", 12);
+
+	p = &xbuf[IDX1];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 16;
+
+	p = &xbuf[IDX2];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 12;
+
+	memset(result, 0, sizeof (result));
+	klen = strlen(hmac_sha1_tv[7].key);
+	crypto_hmac(tfm, hmac_sha1_tv[7].key, &klen, sg, 2, result);
+	hexdump(result, crypto_tfm_alg_digestsize(tfm));
+
+	printk("%s\n",
+	       memcmp(result, hmac_sha1_tv[7].digest,
+		      crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+out:
+	crypto_free_tfm(tfm);
+}
+
+static void
+test_hmac_sha256(void)
+{
+	char *p;
+	unsigned int i, klen;
+	struct crypto_tfm *tfm;
+	struct hmac_sha256_testvec *hmac_sha256_tv;
+	struct scatterlist sg[2];
+	unsigned int tsize;
+	char result[SHA256_DIGEST_SIZE];
+
+	tfm = crypto_alloc_tfm("sha256", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for sha256\n");
+		return;
+	}
+
+	printk("\ntesting hmac_sha256\n");
+
+	tsize = sizeof (hmac_sha256_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		goto out;
+	}
+
+	memcpy(tvmem, hmac_sha256_tv_template, tsize);
+	hmac_sha256_tv = (void *) tvmem;
+
+	for (i = 0; i < HMAC_SHA256_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = hmac_sha256_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = strlen(hmac_sha256_tv[i].plaintext);
+
+		klen = strlen(hmac_sha256_tv[i].key);
+	
+		hexdump(hmac_sha256_tv[i].key, strlen(hmac_sha256_tv[i].key));
+		crypto_hmac(tfm, hmac_sha256_tv[i].key, &klen, sg, 1, result);
+		hexdump(result, crypto_tfm_alg_digestsize(tfm));
+		printk("%s\n",
+		       memcmp(result, hmac_sha256_tv[i].digest,
+		       crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+	}
+
+out:
+	crypto_free_tfm(tfm);
+}
+
+#endif	/* CONFIG_CRYPTO_HMAC */
+
+static void
+test_md4(void)
+{
+	char *p;
+	unsigned int i;
+	struct scatterlist sg[1];
+	char result[128];
+	struct crypto_tfm *tfm;
+	struct md4_testvec *md4_tv;
+	unsigned int tsize;
+
+	printk("\ntesting md4\n");
+
+	tsize = sizeof (md4_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, md4_tv_template, tsize);
+	md4_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("md4", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for md4\n");
+		return;
+	}
+
+	for (i = 0; i < MD4_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = md4_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = strlen(md4_tv[i].plaintext);
+
+		crypto_digest_digest(tfm, sg, 1, result);
+
+		hexdump(result, crypto_tfm_alg_digestsize(tfm));
+		printk("%s\n",
+		       memcmp(result, md4_tv[i].digest,
+			      crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+		       "pass");
+	}
+
+	crypto_free_tfm(tfm);
+}
+
+static void
+test_sha1(void)
+{
+	char *p;
+	unsigned int i;
+	struct crypto_tfm *tfm;
+	struct sha1_testvec *sha1_tv;
+	struct scatterlist sg[2];
+	unsigned int tsize;
+	char result[SHA1_DIGEST_SIZE];
+
+	printk("\ntesting sha1\n");
+
+	tsize = sizeof (sha1_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, sha1_tv_template, tsize);
+	sha1_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("sha1", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for sha1\n");
+		return;
+	}
+
+	for (i = 0; i < SHA1_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = sha1_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = strlen(sha1_tv[i].plaintext);
+
+		crypto_digest_init(tfm);
+		crypto_digest_update(tfm, sg, 1);
+		crypto_digest_final(tfm, result);
+
+		hexdump(result, crypto_tfm_alg_digestsize(tfm));
+		printk("%s\n",
+		       memcmp(result, sha1_tv[i].digest,
+			      crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+		       "pass");
+	}
+
+	printk("\ntesting sha1 across pages\n");
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, XBUFSIZE);
+	memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28);
+	memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28);
+
+	p = &xbuf[IDX1];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 28;
+
+	p = &xbuf[IDX2];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 28;
+
+	memset(result, 0, sizeof (result));
+	crypto_digest_digest(tfm, sg, 2, result);
+	hexdump(result, crypto_tfm_alg_digestsize(tfm));
+	printk("%s\n",
+	       memcmp(result, sha1_tv[1].digest,
+		      crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+	crypto_free_tfm(tfm);
+}
+
+static void
+test_sha256(void)
+{
+	char *p;
+	unsigned int i;
+	struct crypto_tfm *tfm;
+	struct sha256_testvec *sha256_tv;
+	struct scatterlist sg[2];
+	unsigned int tsize;
+	char result[SHA256_DIGEST_SIZE];
+
+	printk("\ntesting sha256\n");
+
+	tsize = sizeof (sha256_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, sha256_tv_template, tsize);
+	sha256_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("sha256", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for sha256\n");
+		return;
+	}
+
+	for (i = 0; i < SHA256_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = sha256_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = strlen(sha256_tv[i].plaintext);
+
+		crypto_digest_init(tfm);
+		crypto_digest_update(tfm, sg, 1);
+		crypto_digest_final(tfm, result);
+
+		hexdump(result, crypto_tfm_alg_digestsize(tfm));
+		printk("%s\n",
+		       memcmp(result, sha256_tv[i].digest,
+			      crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+		       "pass");
+	}
+
+	printk("\ntesting sha256 across pages\n");
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, XBUFSIZE);
+	memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28);
+	memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28);
+
+	p = &xbuf[IDX1];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 28;
+
+	p = &xbuf[IDX2];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 28;
+
+	memset(result, 0, sizeof (result));
+	crypto_digest_digest(tfm, sg, 2, result);
+	hexdump(result, crypto_tfm_alg_digestsize(tfm));
+	printk("%s\n",
+	       memcmp(result, sha256_tv[1].digest,
+		      crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+		     
+	crypto_free_tfm(tfm);
+}
+
+static void
+test_sha384(void)
+{
+	char *p;
+	unsigned int i;
+	struct crypto_tfm *tfm;
+	struct sha384_testvec *sha384_tv;
+	struct scatterlist sg[2];
+	unsigned int tsize;
+	char result[SHA384_DIGEST_SIZE];
+
+	printk("\ntesting sha384\n");
+
+	tsize = sizeof (sha384_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, sha384_tv_template, tsize);
+	sha384_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("sha384", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for sha384\n");
+		return;
+	}
+
+	for (i = 0; i < SHA384_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = sha384_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = strlen(sha384_tv[i].plaintext);
+
+		crypto_digest_init(tfm);
+		crypto_digest_update(tfm, sg, 1);
+		crypto_digest_final(tfm, result);
+
+		hexdump(result, crypto_tfm_alg_digestsize(tfm));
+		printk("%s\n",
+		       memcmp(result, sha384_tv[i].digest,
+			      crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+		       "pass");
+	}
+
+	crypto_free_tfm(tfm);
+}
+
+static void
+test_sha512(void)
+{
+	char *p;
+	unsigned int i;
+	struct crypto_tfm *tfm;
+	struct sha512_testvec *sha512_tv;
+	struct scatterlist sg[2];
+	unsigned int tsize;
+	char result[SHA512_DIGEST_SIZE];
+
+	printk("\ntesting sha512\n");
+
+	tsize = sizeof (sha512_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, sha512_tv_template, tsize);
+	sha512_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("sha512", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for sha512\n");
+		return;
+	}
+
+	for (i = 0; i < SHA512_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = sha512_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = strlen(sha512_tv[i].plaintext);
+
+		crypto_digest_init(tfm);
+		crypto_digest_update(tfm, sg, 1);
+		crypto_digest_final(tfm, result);
+
+		hexdump(result, crypto_tfm_alg_digestsize(tfm));
+		printk("%s\n",
+		       memcmp(result, sha512_tv[i].digest,
+			      crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+		       "pass");
+	}
+
+	crypto_free_tfm(tfm);
+}
+
+void
+test_des(void)
+{
+	unsigned int ret, i, len;
+	unsigned int tsize;
+	char *p, *q;
+	struct crypto_tfm *tfm;
+	char *key;
+	char res[8];
+	struct des_tv *des_tv;
+	struct scatterlist sg[8];
+
+	printk("\ntesting des encryption\n");
+
+	tsize = sizeof (des_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, des_enc_tv_template, tsize);
+	des_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("des", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for des (default ecb)\n");
+		return;
+	}
+
+	for (i = 0; i < DES_ENC_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+
+		key = des_tv[i].key;
+		tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
+
+		ret = crypto_cipher_setkey(tfm, key, 8);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!des_tv[i].fail)
+				goto out;
+		}
+
+		len = des_tv[i].len;
+
+		p = des_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = len;
+		ret = crypto_cipher_encrypt(tfm, sg, sg, len);
+		if (ret) {
+			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, len);
+
+		printk("%s\n",
+		       memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+
+	}
+
+	printk("\ntesting des ecb encryption across pages\n");
+
+	i = 5;
+	key = des_tv[i].key;
+	tfm->crt_flags = 0;
+
+	hexdump(key, 8);
+
+	ret = crypto_cipher_setkey(tfm, key, 8);
+	if (ret) {
+		printk("setkey() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, sizeof (xbuf));
+	memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8);
+	memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8);
+
+	p = &xbuf[IDX1];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 8;
+
+	p = &xbuf[IDX2];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 8;
+
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
+	if (ret) {
+		printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	printk("page 1\n");
+	q = kmap(sg[0].page) + sg[0].offset;
+	hexdump(q, 8);
+	printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass");
+
+	printk("page 2\n");
+	q = kmap(sg[1].page) + sg[1].offset;
+	hexdump(q, 8);
+	printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass");
+
+	printk("\ntesting des ecb encryption chunking scenario A\n");
+
+	/*
+	 * Scenario A:
+	 * 
+	 *  F1       F2      F3
+	 *  [8 + 6]  [2 + 8] [8]
+	 *       ^^^^^^   ^
+	 *       a    b   c
+	 *
+	 * Chunking should begin at a, then end with b, and
+	 * continue encrypting at an offset of 2 until c.
+	 *
+	 */
+	i = 7;
+
+	key = des_tv[i].key;
+	tfm->crt_flags = 0;
+
+	ret = crypto_cipher_setkey(tfm, key, 8);
+	if (ret) {
+		printk("setkey() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, sizeof (xbuf));
+
+	/* Frag 1: 8 + 6 */
+	memcpy(&xbuf[IDX3], des_tv[i].plaintext, 14);
+
+	/* Frag 2: 2 + 8 */
+	memcpy(&xbuf[IDX4], des_tv[i].plaintext + 14, 10);
+
+	/* Frag 3: 8 */
+	memcpy(&xbuf[IDX5], des_tv[i].plaintext + 24, 8);
+
+	p = &xbuf[IDX3];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 14;
+
+	p = &xbuf[IDX4];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 10;
+
+	p = &xbuf[IDX5];
+	sg[2].page = virt_to_page(p);
+	sg[2].offset = ((long) p & ~PAGE_MASK);
+	sg[2].length = 8;
+
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 32);
+
+	if (ret) {
+		printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	printk("page 1\n");
+	q = kmap(sg[0].page) + sg[0].offset;
+	hexdump(q, 14);
+	printk("%s\n", memcmp(q, des_tv[i].result, 14) ? "fail" : "pass");
+
+	printk("page 2\n");
+	q = kmap(sg[1].page) + sg[1].offset;
+	hexdump(q, 10);
+	printk("%s\n", memcmp(q, des_tv[i].result + 14, 10) ? "fail" : "pass");
+
+	printk("page 3\n");
+	q = kmap(sg[2].page) + sg[2].offset;
+	hexdump(q, 8);
+	printk("%s\n", memcmp(q, des_tv[i].result + 24, 8) ? "fail" : "pass");
+
+	printk("\ntesting des ecb encryption chunking scenario B\n");
+
+	/*
+	 * Scenario B:
+	 * 
+	 *  F1  F2  F3  F4
+	 *  [2] [1] [3] [2 + 8 + 8]
+	 */
+	i = 7;
+
+	key = des_tv[i].key;
+	tfm->crt_flags = 0;
+
+	ret = crypto_cipher_setkey(tfm, key, 8);
+	if (ret) {
+		printk("setkey() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, sizeof (xbuf));
+
+	/* Frag 1: 2 */
+	memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2);
+
+	/* Frag 2: 1 */
+	memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 1);
+
+	/* Frag 3: 3 */
+	memcpy(&xbuf[IDX5], des_tv[i].plaintext + 3, 3);
+
+	/* Frag 4: 2 + 8 + 8 */
+	memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 18);
+
+	p = &xbuf[IDX3];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 2;
+
+	p = &xbuf[IDX4];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 1;
+
+	p = &xbuf[IDX5];
+	sg[2].page = virt_to_page(p);
+	sg[2].offset = ((long) p & ~PAGE_MASK);
+	sg[2].length = 3;
+
+	p = &xbuf[IDX6];
+	sg[3].page = virt_to_page(p);
+	sg[3].offset = ((long) p & ~PAGE_MASK);
+	sg[3].length = 18;
+
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 24);
+
+	if (ret) {
+		printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	printk("page 1\n");
+	q = kmap(sg[0].page) + sg[0].offset;
+	hexdump(q, 2);
+	printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass");
+
+	printk("page 2\n");
+	q = kmap(sg[1].page) + sg[1].offset;
+	hexdump(q, 1);
+	printk("%s\n", memcmp(q, des_tv[i].result + 2, 1) ? "fail" : "pass");
+
+	printk("page 3\n");
+	q = kmap(sg[2].page) + sg[2].offset;
+	hexdump(q, 3);
+	printk("%s\n", memcmp(q, des_tv[i].result + 3, 3) ? "fail" : "pass");
+
+	printk("page 4\n");
+	q = kmap(sg[3].page) + sg[3].offset;
+	hexdump(q, 18);
+	printk("%s\n", memcmp(q, des_tv[i].result + 6, 18) ? "fail" : "pass");
+
+	printk("\ntesting des ecb encryption chunking scenario C\n");
+
+	/*
+	 * Scenario B:
+	 * 
+	 *  F1  F2  F3  F4  F5
+	 *  [2] [2] [2] [2] [8]
+	 */
+	i = 7;
+
+	key = des_tv[i].key;
+	tfm->crt_flags = 0;
+
+	ret = crypto_cipher_setkey(tfm, key, 8);
+	if (ret) {
+		printk("setkey() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, sizeof (xbuf));
+
+	/* Frag 1: 2 */
+	memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2);
+
+	/* Frag 2: 2 */
+	memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 2);
+
+	/* Frag 3: 2 */
+	memcpy(&xbuf[IDX5], des_tv[i].plaintext + 4, 2);
+
+	/* Frag 4: 2 */
+	memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 2);
+
+	/* Frag 5: 8 */
+	memcpy(&xbuf[IDX7], des_tv[i].plaintext + 8, 8);
+
+	p = &xbuf[IDX3];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 2;
+
+	p = &xbuf[IDX4];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 2;
+
+	p = &xbuf[IDX5];
+	sg[2].page = virt_to_page(p);
+	sg[2].offset = ((long) p & ~PAGE_MASK);
+	sg[2].length = 2;
+
+	p = &xbuf[IDX6];
+	sg[3].page = virt_to_page(p);
+	sg[3].offset = ((long) p & ~PAGE_MASK);
+	sg[3].length = 2;
+
+	p = &xbuf[IDX7];
+	sg[4].page = virt_to_page(p);
+	sg[4].offset = ((long) p & ~PAGE_MASK);
+	sg[4].length = 8;
+
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
+
+	if (ret) {
+		printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	printk("page 1\n");
+	q = kmap(sg[0].page) + sg[0].offset;
+	hexdump(q, 2);
+	printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass");
+
+	printk("page 2\n");
+	q = kmap(sg[1].page) + sg[1].offset;
+	hexdump(q, 2);
+	printk("%s\n", memcmp(q, des_tv[i].result + 2, 2) ? "fail" : "pass");
+
+	printk("page 3\n");
+	q = kmap(sg[2].page) + sg[2].offset;
+	hexdump(q, 2);
+	printk("%s\n", memcmp(q, des_tv[i].result + 4, 2) ? "fail" : "pass");
+
+	printk("page 4\n");
+	q = kmap(sg[3].page) + sg[3].offset;
+	hexdump(q, 2);
+	printk("%s\n", memcmp(q, des_tv[i].result + 6, 2) ? "fail" : "pass");
+
+	printk("page 5\n");
+	q = kmap(sg[4].page) + sg[4].offset;
+	hexdump(q, 8);
+	printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass");
+
+	printk("\ntesting des ecb encryption chunking scenario D\n");
+
+	/*
+	 * Scenario D, torture test, one byte per frag.
+	 */
+	i = 7;
+	key = des_tv[i].key;
+	tfm->crt_flags = 0;
+
+	ret = crypto_cipher_setkey(tfm, key, 8);
+	if (ret) {
+		printk("setkey() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, XBUFSIZE);
+
+	xbuf[IDX1] = des_tv[i].plaintext[0];
+	xbuf[IDX2] = des_tv[i].plaintext[1];
+	xbuf[IDX3] = des_tv[i].plaintext[2];
+	xbuf[IDX4] = des_tv[i].plaintext[3];
+	xbuf[IDX5] = des_tv[i].plaintext[4];
+	xbuf[IDX6] = des_tv[i].plaintext[5];
+	xbuf[IDX7] = des_tv[i].plaintext[6];
+	xbuf[IDX8] = des_tv[i].plaintext[7];
+
+	p = &xbuf[IDX1];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 1;
+
+	p = &xbuf[IDX2];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 1;
+
+	p = &xbuf[IDX3];
+	sg[2].page = virt_to_page(p);
+	sg[2].offset = ((long) p & ~PAGE_MASK);
+	sg[2].length = 1;
+
+	p = &xbuf[IDX4];
+	sg[3].page = virt_to_page(p);
+	sg[3].offset = ((long) p & ~PAGE_MASK);
+	sg[3].length = 1;
+
+	p = &xbuf[IDX5];
+	sg[4].page = virt_to_page(p);
+	sg[4].offset = ((long) p & ~PAGE_MASK);
+	sg[4].length = 1;
+
+	p = &xbuf[IDX6];
+	sg[5].page = virt_to_page(p);
+	sg[5].offset = ((long) p & ~PAGE_MASK);
+	sg[5].length = 1;
+
+	p = &xbuf[IDX7];
+	sg[6].page = virt_to_page(p);
+	sg[6].offset = ((long) p & ~PAGE_MASK);
+	sg[6].length = 1;
+
+	p = &xbuf[IDX8];
+	sg[7].page = virt_to_page(p);
+	sg[7].offset = ((long) p & ~PAGE_MASK);
+	sg[7].length = 1;
+
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 8);
+	if (ret) {
+		printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	for (i = 0; i < 8; i++)
+		res[i] = *(char *) (kmap(sg[i].page) + sg[i].offset);
+
+	hexdump(res, 8);
+	printk("%s\n", memcmp(res, des_tv[7].result, 8) ? "fail" : "pass");
+
+	printk("\ntesting des decryption\n");
+
+	tsize = sizeof (des_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+	memcpy(tvmem, des_dec_tv_template, tsize);
+	des_tv = (void *) tvmem;
+
+	for (i = 0; i < DES_DEC_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+
+		key = des_tv[i].key;
+
+		tfm->crt_flags = 0;
+		ret = crypto_cipher_setkey(tfm, key, 8);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		len = des_tv[i].len;
+
+		p = des_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = len;
+
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("des_decrypt() failed flags=%x\n",
+			       tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, len);
+
+		printk("%s\n",
+		       memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+
+	}
+
+	printk("\ntesting des ecb decryption across pages\n");
+
+	i = 6;
+
+	key = des_tv[i].key;
+	tfm->crt_flags = 0;
+
+	ret = crypto_cipher_setkey(tfm, key, 8);
+	if (ret) {
+		printk("setkey() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, sizeof (xbuf));
+	memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8);
+	memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8);
+
+	p = &xbuf[IDX1];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 8;
+
+	p = &xbuf[IDX2];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 8;
+
+	ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
+	if (ret) {
+		printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	printk("page 1\n");
+	q = kmap(sg[0].page) + sg[0].offset;
+	hexdump(q, 8);
+	printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass");
+
+	printk("page 2\n");
+	q = kmap(sg[1].page) + sg[1].offset;
+	hexdump(q, 8);
+	printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass");
+
+	/*
+	 * Scenario E:
+	 * 
+	 *  F1   F2      F3
+	 *  [3]  [5 + 7] [1]
+	 *
+	 */
+	printk("\ntesting des ecb decryption chunking scenario E\n");
+	i = 2;
+
+	key = des_tv[i].key;
+	tfm->crt_flags = 0;
+
+	ret = crypto_cipher_setkey(tfm, key, 8);
+	if (ret) {
+		printk("setkey() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, sizeof (xbuf));
+
+	memcpy(&xbuf[IDX1], des_tv[i].plaintext, 3);
+	memcpy(&xbuf[IDX2], des_tv[i].plaintext + 3, 12);
+	memcpy(&xbuf[IDX3], des_tv[i].plaintext + 15, 1);
+
+	p = &xbuf[IDX1];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 3;
+
+	p = &xbuf[IDX2];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 12;
+
+	p = &xbuf[IDX3];
+	sg[2].page = virt_to_page(p);
+	sg[2].offset = ((long) p & ~PAGE_MASK);
+	sg[2].length = 1;
+
+	ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
+
+	if (ret) {
+		printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	printk("page 1\n");
+	q = kmap(sg[0].page) + sg[0].offset;
+	hexdump(q, 3);
+	printk("%s\n", memcmp(q, des_tv[i].result, 3) ? "fail" : "pass");
+
+	printk("page 2\n");
+	q = kmap(sg[1].page) + sg[1].offset;
+	hexdump(q, 12);
+	printk("%s\n", memcmp(q, des_tv[i].result + 3, 12) ? "fail" : "pass");
+
+	printk("page 3\n");
+	q = kmap(sg[2].page) + sg[2].offset;
+	hexdump(q, 1);
+	printk("%s\n", memcmp(q, des_tv[i].result + 15, 1) ? "fail" : "pass");
+
+	crypto_free_tfm(tfm);
+
+	tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC);
+	if (tfm == NULL) {
+		printk("failed to load transform for des cbc\n");
+		return;
+	}
+
+	printk("\ntesting des cbc encryption\n");
+
+	tsize = sizeof (des_cbc_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+	memcpy(tvmem, des_cbc_enc_tv_template, tsize);
+	des_tv = (void *) tvmem;
+
+	crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
+	crypto_cipher_get_iv(tfm, res, crypto_tfm_alg_ivsize(tfm));
+	
+	if (memcmp(res, des_tv[i].iv, sizeof(res))) {
+		printk("crypto_cipher_[set|get]_iv() failed\n");
+		goto out;
+	}
+	
+	for (i = 0; i < DES_CBC_ENC_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+
+		key = des_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, 8);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		len = des_tv[i].len;
+		p = des_tv[i].plaintext;
+
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = len;
+
+		crypto_cipher_set_iv(tfm, des_tv[i].iv,
+				     crypto_tfm_alg_ivsize(tfm));
+
+		ret = crypto_cipher_encrypt(tfm, sg, sg, len);
+		if (ret) {
+			printk("des_cbc_encrypt() failed flags=%x\n",
+			       tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, len);
+
+		printk("%s\n",
+		       memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+	}
+
+	crypto_free_tfm(tfm);
+
+	/*
+	 * Scenario F:
+	 * 
+	 *  F1       F2      
+	 *  [8 + 5]  [3 + 8]
+	 *
+	 */
+	printk("\ntesting des cbc encryption chunking scenario F\n");
+	i = 4;
+
+	tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC);
+	if (tfm == NULL) {
+		printk("failed to load transform for CRYPTO_ALG_DES_CCB\n");
+		return;
+	}
+
+	tfm->crt_flags = 0;
+	key = des_tv[i].key;
+
+	ret = crypto_cipher_setkey(tfm, key, 8);
+	if (ret) {
+		printk("setkey() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, sizeof (xbuf));
+
+	memcpy(&xbuf[IDX1], des_tv[i].plaintext, 13);
+	memcpy(&xbuf[IDX2], des_tv[i].plaintext + 13, 11);
+
+	p = &xbuf[IDX1];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 13;
+
+	p = &xbuf[IDX2];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 11;
+
+	crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
+
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 24);
+	if (ret) {
+		printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	printk("page 1\n");
+	q = kmap(sg[0].page) + sg[0].offset;
+	hexdump(q, 13);
+	printk("%s\n", memcmp(q, des_tv[i].result, 13) ? "fail" : "pass");
+
+	printk("page 2\n");
+	q = kmap(sg[1].page) + sg[1].offset;
+	hexdump(q, 11);
+	printk("%s\n", memcmp(q, des_tv[i].result + 13, 11) ? "fail" : "pass");
+
+	tsize = sizeof (des_cbc_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+	memcpy(tvmem, des_cbc_dec_tv_template, tsize);
+	des_tv = (void *) tvmem;
+
+	printk("\ntesting des cbc decryption\n");
+
+	for (i = 0; i < DES_CBC_DEC_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+
+		tfm->crt_flags = 0;
+		key = des_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, 8);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		len = des_tv[i].len;
+		p = des_tv[i].plaintext;
+
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = len;
+
+		crypto_cipher_set_iv(tfm, des_tv[i].iv,
+				      crypto_tfm_alg_blocksize(tfm));
+
+		ret = crypto_cipher_decrypt(tfm, sg, sg, len);
+		if (ret) {
+			printk("des_cbc_decrypt() failed flags=%x\n",
+			       tfm->crt_flags);
+			goto out;
+		}
+
+		hexdump(tfm->crt_cipher.cit_iv, 8);
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, len);
+
+		printk("%s\n",
+		       memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+	}
+
+	/*
+	 * Scenario G:
+	 * 
+	 *  F1   F2      
+	 *  [4]  [4]
+	 *
+	 */
+	printk("\ntesting des cbc decryption chunking scenario G\n");
+	i = 3;
+
+	tfm->crt_flags = 0;
+	key = des_tv[i].key;
+
+	ret = crypto_cipher_setkey(tfm, key, 8);
+	if (ret) {
+		printk("setkey() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	/* setup the dummy buffer first */
+	memset(xbuf, 0, sizeof (xbuf));
+	memcpy(&xbuf[IDX1], des_tv[i].plaintext, 4);
+	memcpy(&xbuf[IDX2], des_tv[i].plaintext + 4, 4);
+
+	p = &xbuf[IDX1];
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = ((long) p & ~PAGE_MASK);
+	sg[0].length = 4;
+
+	p = &xbuf[IDX2];
+	sg[1].page = virt_to_page(p);
+	sg[1].offset = ((long) p & ~PAGE_MASK);
+	sg[1].length = 4;
+
+	crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
+
+	ret = crypto_cipher_decrypt(tfm, sg, sg, 8);
+	if (ret) {
+		printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags);
+		goto out;
+	}
+
+	printk("page 1\n");
+	q = kmap(sg[0].page) + sg[0].offset;
+	hexdump(q, 4);
+	printk("%s\n", memcmp(q, des_tv[i].result, 4) ? "fail" : "pass");
+
+	printk("page 2\n");
+	q = kmap(sg[1].page) + sg[1].offset;
+	hexdump(q, 4);
+	printk("%s\n", memcmp(q, des_tv[i].result + 4, 4) ? "fail" : "pass");
+
+      out:
+	crypto_free_tfm(tfm);
+}
+
+void
+test_des3_ede(void)
+{
+	unsigned int ret, i, len;
+	unsigned int tsize;
+	char *p, *q;
+	struct crypto_tfm *tfm;
+	char *key;
+	/*char res[8]; */
+	struct des_tv *des_tv;
+	struct scatterlist sg[8];
+
+	printk("\ntesting des3 ede encryption\n");
+
+	tsize = sizeof (des3_ede_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, des3_ede_enc_tv_template, tsize);
+	des_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("des3_ede", CRYPTO_TFM_MODE_ECB);
+	if (tfm == NULL) {
+		printk("failed to load transform for 3des ecb\n");
+		return;
+	}
+
+	for (i = 0; i < DES3_EDE_ENC_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+
+		key = des_tv[i].key;
+		ret = crypto_cipher_setkey(tfm, key, 24);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!des_tv[i].fail)
+				goto out;
+		}
+
+		len = des_tv[i].len;
+
+		p = des_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = len;
+		ret = crypto_cipher_encrypt(tfm, sg, sg, len);
+		if (ret) {
+			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, len);
+
+		printk("%s\n",
+		       memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+	}
+
+	printk("\ntesting des3 ede decryption\n");
+
+	tsize = sizeof (des3_ede_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, des3_ede_dec_tv_template, tsize);
+	des_tv = (void *) tvmem;
+
+	for (i = 0; i < DES3_EDE_DEC_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+
+		key = des_tv[i].key;
+		ret = crypto_cipher_setkey(tfm, key, 24);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!des_tv[i].fail)
+				goto out;
+		}
+
+		len = des_tv[i].len;
+
+		p = des_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = len;
+		ret = crypto_cipher_decrypt(tfm, sg, sg, len);
+		if (ret) {
+			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, len);
+
+		printk("%s\n",
+		       memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+	}
+
+      out:
+	crypto_free_tfm(tfm);
+}
+
+void
+test_blowfish(void)
+{
+	unsigned int ret, i;
+	unsigned int tsize;
+	char *p, *q;
+	struct crypto_tfm *tfm;
+	char *key;
+	struct bf_tv *bf_tv;
+	struct scatterlist sg[1];
+
+	printk("\ntesting blowfish encryption\n");
+
+	tsize = sizeof (bf_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, bf_enc_tv_template, tsize);
+	bf_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("blowfish", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for blowfish (default ecb)\n");
+		return;
+	}
+
+	for (i = 0; i < BF_ENC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, bf_tv[i].keylen * 8);
+		key = bf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!bf_tv[i].fail)
+				goto out;
+		}
+
+		p = bf_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = bf_tv[i].plen;
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, bf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ?
+			"fail" : "pass");
+	}
+
+	printk("\ntesting blowfish decryption\n");
+
+	tsize = sizeof (bf_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, bf_dec_tv_template, tsize);
+	bf_tv = (void *) tvmem;
+
+	for (i = 0; i < BF_DEC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, bf_tv[i].keylen * 8);
+		key = bf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!bf_tv[i].fail)
+				goto out;
+		}
+
+		p = bf_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = bf_tv[i].plen;
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, bf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ?
+			"fail" : "pass");
+	}
+	
+	crypto_free_tfm(tfm);
+	
+	tfm = crypto_alloc_tfm("blowfish", CRYPTO_TFM_MODE_CBC);
+	if (tfm == NULL) {
+		printk("failed to load transform for blowfish cbc\n");
+		return;
+	}
+
+	printk("\ntesting blowfish cbc encryption\n");
+
+	tsize = sizeof (bf_cbc_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		goto out;
+	}
+	memcpy(tvmem, bf_cbc_enc_tv_template, tsize);
+	bf_tv = (void *) tvmem;
+
+	for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, bf_tv[i].keylen * 8);
+
+		key = bf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		p = bf_tv[i].plaintext;
+
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length =  bf_tv[i].plen;
+
+		crypto_cipher_set_iv(tfm, bf_tv[i].iv,
+				     crypto_tfm_alg_ivsize(tfm));
+
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("blowfish_cbc_encrypt() failed flags=%x\n",
+			       tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, bf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen)
+			? "fail" : "pass");
+	}
+
+	printk("\ntesting blowfish cbc decryption\n");
+
+	tsize = sizeof (bf_cbc_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		goto out;
+	}
+	memcpy(tvmem, bf_cbc_dec_tv_template, tsize);
+	bf_tv = (void *) tvmem;
+
+	for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, bf_tv[i].keylen * 8);
+		key = bf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		p = bf_tv[i].plaintext;
+
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length =  bf_tv[i].plen;
+
+		crypto_cipher_set_iv(tfm, bf_tv[i].iv,
+				     crypto_tfm_alg_ivsize(tfm));
+
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("blowfish_cbc_decrypt() failed flags=%x\n",
+			       tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, bf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen)
+			? "fail" : "pass");
+	}
+
+out:
+	crypto_free_tfm(tfm);
+}
+
+
+void
+test_twofish(void)
+{
+	unsigned int ret, i;
+	unsigned int tsize;
+	char *p, *q;
+	struct crypto_tfm *tfm;
+	char *key;
+	struct tf_tv *tf_tv;
+	struct scatterlist sg[1];
+
+	printk("\ntesting twofish encryption\n");
+
+	tsize = sizeof (tf_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, tf_enc_tv_template, tsize);
+	tf_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("twofish", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for blowfish (default ecb)\n");
+		return;
+	}
+
+	for (i = 0; i < TF_ENC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, tf_tv[i].keylen * 8);
+		key = tf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!tf_tv[i].fail)
+				goto out;
+		}
+
+		p = tf_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = tf_tv[i].plen;
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, tf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ?
+			"fail" : "pass");
+	}
+
+	printk("\ntesting twofish decryption\n");
+
+	tsize = sizeof (tf_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, tf_dec_tv_template, tsize);
+	tf_tv = (void *) tvmem;
+
+	for (i = 0; i < TF_DEC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, tf_tv[i].keylen * 8);
+		key = tf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!tf_tv[i].fail)
+				goto out;
+		}
+
+		p = tf_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = tf_tv[i].plen;
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, tf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ?
+			"fail" : "pass");
+	}
+
+	crypto_free_tfm(tfm);
+	
+	tfm = crypto_alloc_tfm("twofish", CRYPTO_TFM_MODE_CBC);
+	if (tfm == NULL) {
+		printk("failed to load transform for twofish cbc\n");
+		return;
+	}
+
+	printk("\ntesting twofish cbc encryption\n");
+
+	tsize = sizeof (tf_cbc_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		goto out;
+	}
+	memcpy(tvmem, tf_cbc_enc_tv_template, tsize);
+	tf_tv = (void *) tvmem;
+
+	for (i = 0; i < TF_CBC_ENC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, tf_tv[i].keylen * 8);
+
+		key = tf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		p = tf_tv[i].plaintext;
+
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length =  tf_tv[i].plen;
+
+		crypto_cipher_set_iv(tfm, tf_tv[i].iv,
+				     crypto_tfm_alg_ivsize(tfm));
+
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("blowfish_cbc_encrypt() failed flags=%x\n",
+			       tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, tf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen)
+			? "fail" : "pass");
+	}
+
+	printk("\ntesting twofish cbc decryption\n");
+
+	tsize = sizeof (tf_cbc_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		goto out;
+	}
+	memcpy(tvmem, tf_cbc_dec_tv_template, tsize);
+	tf_tv = (void *) tvmem;
+
+	for (i = 0; i < TF_CBC_DEC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, tf_tv[i].keylen * 8);
+
+		key = tf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		p = tf_tv[i].plaintext;
+
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length =  tf_tv[i].plen;
+
+		crypto_cipher_set_iv(tfm, tf_tv[i].iv,
+				     crypto_tfm_alg_ivsize(tfm));
+
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("blowfish_cbc_decrypt() failed flags=%x\n",
+			       tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, tf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen)
+			? "fail" : "pass");
+	}
+
+out:	
+	crypto_free_tfm(tfm);
+}
+
+void
+test_serpent(void)
+{
+	unsigned int ret, i, tsize;
+	u8 *p, *q, *key;
+	struct crypto_tfm *tfm;
+	struct serpent_tv *serp_tv;
+	struct scatterlist sg[1];
+
+	printk("\ntesting serpent encryption\n");
+
+	tfm = crypto_alloc_tfm("serpent", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for serpent (default ecb)\n");
+		return;
+	}
+
+	tsize = sizeof (serpent_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, serpent_enc_tv_template, tsize);
+	serp_tv = (void *) tvmem;
+	for (i = 0; i < SERPENT_ENC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8);
+		key = serp_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!serp_tv[i].fail)
+				goto out;
+		}
+
+		p = serp_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = sizeof(serp_tv[i].plaintext);
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, sizeof(serp_tv[i].result));
+
+		printk("%s\n", memcmp(q, serp_tv[i].result,
+			sizeof(serp_tv[i].result)) ? "fail" : "pass");
+	}
+
+	printk("\ntesting serpent decryption\n");
+
+	tsize = sizeof (serpent_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, serpent_dec_tv_template, tsize);
+	serp_tv = (void *) tvmem;
+	for (i = 0; i < SERPENT_DEC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8);
+		key = serp_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!serp_tv[i].fail)
+				goto out;
+		}
+
+		p = serp_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = sizeof(serp_tv[i].plaintext);
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, sizeof(serp_tv[i].result));
+
+		printk("%s\n", memcmp(q, serp_tv[i].result,
+			sizeof(serp_tv[i].result)) ? "fail" : "pass");
+	}
+
+out:
+	crypto_free_tfm(tfm);
+}
+
+void
+test_aes(void)
+{
+	unsigned int ret, i;
+	unsigned int tsize;
+	char *p, *q;
+	struct crypto_tfm *tfm;
+	char *key;
+	struct aes_tv *aes_tv;
+	struct scatterlist sg[1];
+
+	printk("\ntesting aes encryption\n");
+
+	tsize = sizeof (aes_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, aes_enc_tv_template, tsize);
+	aes_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("aes", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for aes (default ecb)\n");
+		return;
+	}
+
+	for (i = 0; i < AES_ENC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, aes_tv[i].keylen * 8);
+		key = aes_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!aes_tv[i].fail)
+				goto out;
+		}
+
+		p = aes_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = aes_tv[i].plen;
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, aes_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ?
+			"fail" : "pass");
+	}
+	
+	printk("\ntesting aes decryption\n");
+
+	tsize = sizeof (aes_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, aes_dec_tv_template, tsize);
+	aes_tv = (void *) tvmem;
+
+	for (i = 0; i < AES_DEC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, aes_tv[i].keylen * 8);
+		key = aes_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!aes_tv[i].fail)
+				goto out;
+		}
+
+		p = aes_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = aes_tv[i].plen;
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+		if (ret) {
+			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, aes_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ?
+			"fail" : "pass");
+	}
+
+out:
+	crypto_free_tfm(tfm);
+}
+
+static void
+test_deflate(void)
+{
+	unsigned int i;
+	char result[COMP_BUF_SIZE];
+	struct crypto_tfm *tfm;
+	struct comp_testvec *tv;
+	unsigned int tsize;
+
+	printk("\ntesting deflate compression\n");
+
+	tsize = sizeof (deflate_comp_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, deflate_comp_tv_template, tsize);
+	tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("deflate", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for deflate\n");
+		return;
+	}
+
+	for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) {
+		int ilen, ret, dlen = COMP_BUF_SIZE;
+		
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		ilen = tv[i].inlen;
+		ret = crypto_comp_compress(tfm, tv[i].input,
+		                           ilen, result, &dlen);
+		if (ret) {
+			printk("fail: ret=%d\n", ret);
+			continue;
+		}
+		hexdump(result, dlen);
+		printk("%s (ratio %d:%d)\n",
+		       memcmp(result, tv[i].output, dlen) ? "fail" : "pass",
+		       ilen, dlen);
+	}
+
+	printk("\ntesting deflate decompression\n");
+
+	tsize = sizeof (deflate_decomp_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		goto out;
+	}
+
+	memcpy(tvmem, deflate_decomp_tv_template, tsize);
+	tv = (void *) tvmem;
+
+	for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) {
+		int ilen, ret, dlen = COMP_BUF_SIZE;
+		
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		ilen = tv[i].inlen;
+		ret = crypto_comp_decompress(tfm, tv[i].input,
+		                             ilen, result, &dlen);
+		if (ret) {
+			printk("fail: ret=%d\n", ret);
+			continue;
+		}
+		hexdump(result, dlen);
+		printk("%s (ratio %d:%d)\n",
+		       memcmp(result, tv[i].output, dlen) ? "fail" : "pass",
+		       ilen, dlen);
+	}
+out:
+	crypto_free_tfm(tfm);
+}
+
+static void
+test_available(void)
+{
+	char **name = check;
+	
+	while (*name) {
+		printk("alg %s ", *name);
+		printk((crypto_alg_available(*name, 0)) ?
+			"found\n" : "not found\n");
+		name++;
+	}	
+}
+
+static void
+do_test(void)
+{
+	switch (mode) {
+
+	case 0:
+		test_md5();
+		test_sha1();
+		test_des();
+		test_des3_ede();
+		test_md4();
+		test_sha256();
+		test_blowfish();
+		test_twofish();
+		test_serpent();
+		test_aes();
+		test_sha384();
+		test_sha512();
+		test_deflate();
+#ifdef CONFIG_CRYPTO_HMAC
+		test_hmac_md5();
+		test_hmac_sha1();
+		test_hmac_sha256();
+#endif		
+		break;
+
+	case 1:
+		test_md5();
+		break;
+
+	case 2:
+		test_sha1();
+		break;
+
+	case 3:
+		test_des();
+		break;
+
+	case 4:
+		test_des3_ede();
+		break;
+
+	case 5:
+		test_md4();
+		break;
+		
+	case 6:
+		test_sha256();
+		break;
+	
+	case 7:
+		test_blowfish();
+		break;
+
+	case 8:
+		test_twofish();
+		break;
+
+	case 9:
+		test_serpent();
+		break;
+
+	case 10:
+		test_aes();
+		break;
+
+	case 11:
+		test_sha384();
+		break;
+		
+	case 12:
+		test_sha512();
+		break;
+
+	case 13:
+		test_deflate();
+		break;
+
+#ifdef CONFIG_CRYPTO_HMAC
+	case 100:
+		test_hmac_md5();
+		break;
+		
+	case 101:
+		test_hmac_sha1();
+		break;
+	
+	case 102:
+		test_hmac_sha256();
+		break;
+
+#endif
+
+	case 1000:
+		test_available();
+		break;
+		
+	default:
+		/* useful for debugging */
+		printk("not testing anything\n");
+		break;
+	}
+}
+
+static int __init
+init(void)
+{
+	tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL);
+	if (tvmem == NULL)
+		return -ENOMEM;
+
+	xbuf = kmalloc(XBUFSIZE, GFP_KERNEL);
+	if (xbuf == NULL) {
+		kfree(tvmem);
+		return -ENOMEM;
+	}
+
+	do_test();
+
+	kfree(xbuf);
+	kfree(tvmem);
+	return 0;
+}
+
+module_init(init);
+
+MODULE_PARM(mode, "i");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Quick & dirty crypto testing module");
+MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
diff -urN linux-2.4.22-pre2/crypto/tcrypt.h linux-2.4.22-pre3/crypto/tcrypt.h
--- linux-2.4.22-pre2/crypto/tcrypt.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/tcrypt.h	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,1785 @@
+/* 
+ * Quick & dirty crypto testing module.
+ *
+ * This will only exist until we have a better testing mechanism
+ * (e.g. a char device).
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#ifndef _CRYPTO_TCRYPT_H
+#define _CRYPTO_TCRYPT_H
+
+#define MD5_DIGEST_SIZE		16
+#define MD4_DIGEST_SIZE		16
+#define SHA1_DIGEST_SIZE	20
+#define SHA256_DIGEST_SIZE	32
+#define SHA384_DIGEST_SIZE	48
+#define SHA512_DIGEST_SIZE	64
+
+/*
+ * MD4 test vectors from RFC1320
+ */
+#define MD4_TEST_VECTORS	7
+
+struct md4_testvec {
+	char plaintext[128];
+	char digest[MD4_DIGEST_SIZE];
+} md4_tv_template[] = {
+	{ "",
+		{ 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
+		  0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 }
+	},
+	
+	{ "a",
+		{ 0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
+		  0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24 }
+	},
+
+	{ "abc",
+		{ 0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
+		  0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d }
+	},
+	
+	{ "message digest",
+		{ 0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
+		  0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b }
+	},
+	
+	{ "abcdefghijklmnopqrstuvwxyz",
+		{ 0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
+		  0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9 }
+	},
+		
+	{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+		{ 0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
+		  0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4 }
+	},
+	
+	{ "123456789012345678901234567890123456789012345678901234567890123"
+	  "45678901234567890",
+		{ 0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
+		  0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36 }
+	},
+};
+
+/*
+ * MD5 test vectors from RFC1321
+ */
+#define MD5_TEST_VECTORS	7
+
+struct md5_testvec {
+	char plaintext[128];
+	char digest[MD5_DIGEST_SIZE];
+} md5_tv_template[] = {
+	{ "",
+		{ 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
+		  0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
+	        	
+	{ "a",
+		{ 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
+		  0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
+		  
+	{ "abc",
+		{ 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
+		  0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, 
+		  
+	{ "message digest",
+		{ 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
+		  0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
+		  
+	{ "abcdefghijklmnopqrstuvwxyz",
+		{ 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
+		  0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
+		  
+	{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+		{ 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
+		  0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
+		  
+	{ "12345678901234567890123456789012345678901234567890123456789012"
+	  "345678901234567890",
+		{ 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
+		  0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }
+};
+
+#ifdef CONFIG_CRYPTO_HMAC
+/*
+ * HMAC-MD5 test vectors from RFC2202
+ * (These need to be fixed to not use strlen).
+ */
+#define HMAC_MD5_TEST_VECTORS	7
+
+struct hmac_md5_testvec {
+	char key[128];
+	char plaintext[128];
+	char digest[MD5_DIGEST_SIZE];
+};
+
+struct hmac_md5_testvec hmac_md5_tv_template[] =
+{
+	
+	{
+		{ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+		  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00},
+		  
+		"Hi There",
+		
+		{ 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
+		  0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d }
+	},
+	    
+	{
+		{ 'J', 'e', 'f', 'e', 0 },
+		
+		"what do ya want for nothing?",
+		
+		{ 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
+		  0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 }
+	},
+	
+	{
+		{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 },
+		  
+		{ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0x00 },
+		  
+		{ 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
+		  0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }
+	},
+	
+	{
+		{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+		  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 
+		  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00 },
+		  
+		{ 
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0x00 },
+		  
+		{ 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
+		  0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 }
+	},
+	
+	{
+		{ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+		  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00 },
+		  
+		"Test With Truncation",
+		
+		{ 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00,
+		  0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c }
+	},
+	
+	{
+		{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0x00 },
+		  
+		"Test Using Larger Than Block-Size Key - Hash Key First",
+		
+		{ 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
+		  0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd }
+	},
+	
+	{
+		{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0x00 },
+		
+		"Test Using Larger Than Block-Size Key and Larger Than One "
+		"Block-Size Data",
+		
+		{ 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
+		  0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e }
+	},
+	
+	/* cross page test, need to retain key */
+	
+	{
+		{ 'J', 'e', 'f', 'e', 0 },
+		
+		"what do ya want for nothing?",
+		
+		{ 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
+		  0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 }
+	},
+	
+};
+
+	
+/*
+ * HMAC-SHA1 test vectors from RFC2202
+ */
+
+#define HMAC_SHA1_TEST_VECTORS	7
+
+struct hmac_sha1_testvec {
+	char key[128];
+	char plaintext[128];
+	char digest[SHA1_DIGEST_SIZE];
+} hmac_sha1_tv_template[] = {
+	
+	{
+		{ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+		  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+		  0x00},
+		  
+		"Hi There",
+
+		{ 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
+                  0xe2, 0x8b, 0xc0, 0xb6, 0xfb ,0x37, 0x8c, 0x8e, 0xf1,
+                  0x46, 0xbe, 0x00 }
+	},
+	    
+	{
+		{ 'J', 'e', 'f', 'e', 0 },
+		
+		"what do ya want for nothing?",
+
+		{ 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, 
+		  0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 }
+
+	},
+	
+	{
+		{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0x00},
+
+		  
+		{ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0x00 },
+		  
+		{ 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x91, 0xa3, 
+		  0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, 0x63, 0xf1, 0x75, 0xd3 }
+
+	},
+	
+	{
+		{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+		  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 
+		  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00 },
+		  
+		{ 
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0x00 },
+		  
+		{ 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0xbc, 0x84, 
+		  0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, 0x2d, 0x72, 0x35, 0xda }
+
+	},
+	
+	{
+		{ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+		  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+		  0x00 },
+		  
+		"Test With Truncation",
+		
+		{ 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, 
+  		  0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04 }
+
+	},
+	
+	{
+		{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0x00 },
+		  
+		"Test Using Larger Than Block-Size Key - Hash Key First",
+		
+		{ 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70, 
+  		  0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0xed, 0x40, 0x21, 0x12 }
+
+	},
+	
+	{
+		{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0x00 },
+		
+		"Test Using Larger Than Block-Size Key and Larger Than One "
+		"Block-Size Data",
+		
+		{ 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b, 
+		  0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91 }
+	},
+	
+	/* cross page test */
+	{
+		{ 'J', 'e', 'f', 'e', 0 },
+		
+		"what do ya want for nothing?",
+
+		{ 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, 
+		  0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 }
+
+	},
+
+};
+
+/*
+ * HMAC-SHA256 test vectors from
+ * draft-ietf-ipsec-ciph-sha-256-01.txt
+ */
+#define HMAC_SHA256_TEST_VECTORS	10
+
+struct hmac_sha256_testvec {
+	char key[128];
+	char plaintext[128];
+	char digest[SHA256_DIGEST_SIZE];
+} hmac_sha256_tv_template[] = {
+
+	{
+		{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+		  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+		  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+		  0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 },
+		  
+	
+		{ "abc" },
+		
+		{ 0xa2, 0x1b, 0x1f, 0x5d, 0x4c, 0xf4, 0xf7, 0x3a,
+		  0x4d, 0xd9, 0x39, 0x75, 0x0f, 0x7a, 0x06, 0x6a,
+		  0x7f, 0x98, 0xcc, 0x13, 0x1c, 0xb1, 0x6a, 0x66,
+		  0x92, 0x75, 0x90, 0x21, 0xcf, 0xab, 0x81, 0x81 },
+
+	},
+	
+	{
+		{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+		  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+		  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+		   0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 },
+		
+		{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+		
+		{ 0x10, 0x4f, 0xdc, 0x12, 0x57, 0x32, 0x8f, 0x08,
+		  0x18, 0x4b, 0xa7, 0x31, 0x31, 0xc5, 0x3c, 0xae,
+		  0xe6, 0x98, 0xe3, 0x61, 0x19, 0x42, 0x11, 0x49,
+		  0xea, 0x8c, 0x71, 0x24, 0x56, 0x69, 0x7d, 0x30 }
+	},
+
+	{
+		{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+		  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+		  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+		  0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 },
+		
+		{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+		  "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+		
+		{ 0x47, 0x03, 0x05, 0xfc, 0x7e, 0x40, 0xfe, 0x34,
+		  0xd3, 0xee, 0xb3, 0xe7, 0x73, 0xd9, 0x5a, 0xab,
+		  0x73, 0xac, 0xf0, 0xfd, 0x06, 0x04, 0x47, 0xa5,
+		  0xeb, 0x45, 0x95, 0xbf, 0x33, 0xa9, 0xd1, 0xa3 }
+	},
+
+	{
+		{ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+		  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+		  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+		  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00 },
+		
+		{ "Hi There" },
+		
+		{ 0x19, 0x8a, 0x60, 0x7e, 0xb4, 0x4b, 0xfb, 0xc6,
+		  0x99, 0x03, 0xa0, 0xf1, 0xcf, 0x2b, 0xbd, 0xc5,
+		  0xba, 0x0a, 0xa3, 0xf3, 0xd9, 0xae, 0x3c, 0x1c,
+		  0x7a, 0x3b, 0x16, 0x96, 0xa0, 0xb6, 0x8c, 0xf7 }
+	},
+
+	{
+		{ "Jefe" },
+		
+		{ "what do ya want for nothing?" },
+		
+		{ 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
+		  0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
+		  0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
+		  0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 }
+	},
+
+	{
+		{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 },
+		
+		{ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+		  0xdd, 0xdd, 0x00 },
+		
+		{ 0xcd, 0xcb, 0x12, 0x20, 0xd1, 0xec, 0xcc, 0xea,
+		  0x91, 0xe5, 0x3a, 0xba, 0x30, 0x92, 0xf9, 0x62,
+		  0xe5, 0x49, 0xfe, 0x6c, 0xe9, 0xed, 0x7f, 0xdc,
+		  0x43, 0x19, 0x1f, 0xbd, 0xe4, 0x5c, 0x30, 0xb0 }
+	},
+
+	{
+		{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+		  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+		  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+		  0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+		  0x21, 0x22, 0x23, 0x24, 0x25, 0x00 },
+		
+		{ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+		  0xcd, 0xcd, 0x00 },
+		
+		{ 0xd4, 0x63, 0x3c, 0x17, 0xf6, 0xfb, 0x8d, 0x74,
+		  0x4c, 0x66, 0xde, 0xe0, 0xf8, 0xf0, 0x74, 0x55,
+		  0x6e, 0xc4, 0xaf, 0x55, 0xef, 0x07, 0x99, 0x85,
+		  0x41, 0x46, 0x8e, 0xb4, 0x9b, 0xd2, 0xe9, 0x17 }
+	},
+
+	{
+		{ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+		  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+		  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+		  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00 },
+		
+		{ "Test With Truncation" },
+		
+		{ 0x75, 0x46, 0xaf, 0x01, 0x84, 0x1f, 0xc0, 0x9b,
+		  0x1a, 0xb9, 0xc3, 0x74, 0x9a, 0x5f, 0x1c, 0x17,
+		  0xd4, 0xf5, 0x89, 0x66, 0x8a, 0x58, 0x7b, 0x27,
+		  0x00, 0xa9, 0xc9, 0x7c, 0x11, 0x93, 0xcf, 0x42 }
+	},
+	
+	{
+		{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 },
+		
+		{ "Test Using Larger Than Block-Size Key - Hash Key First" },
+		
+		{ 0x69, 0x53, 0x02, 0x5e, 0xd9, 0x6f, 0x0c, 0x09,
+		  0xf8, 0x0a, 0x96, 0xf7, 0x8e, 0x65, 0x38, 0xdb,
+		  0xe2, 0xe7, 0xb8, 0x20, 0xe3, 0xdd, 0x97, 0x0e,
+		  0x7d, 0xdd, 0x39, 0x09, 0x1b, 0x32, 0x35, 0x2f }
+	},
+
+	{
+		{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 },
+		
+		{ "Test Using Larger Than Block-Size Key and Larger Than "
+		  "One Block-Size Data" },
+		
+		{ 0x63, 0x55, 0xac, 0x22, 0xe8, 0x90, 0xd0, 0xa3,
+		  0xc8, 0x48, 0x1a, 0x5c, 0xa4, 0x82, 0x5b, 0xc8,
+		  0x84, 0xd3, 0xe7, 0xa1, 0xff, 0x98, 0xa2, 0xfc,
+		  0x2a, 0xc7, 0xd8, 0xe0, 0x64, 0xc3, 0xb2, 0xe6 }
+	},
+};
+
+
+#endif	/* CONFIG_CRYPTO_HMAC */
+
+/*
+ * SHA1 test vectors  from from FIPS PUB 180-1
+ */
+#define SHA1_TEST_VECTORS	2
+
+struct sha1_testvec {
+	char plaintext[128];
+	char digest[SHA1_DIGEST_SIZE];
+} sha1_tv_template[] = {
+	{ "abc",
+	  { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 
+	    0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C ,0x9C, 0xD0, 0xD8, 0x9D }
+	},
+	        	
+	{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+
+	  { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E ,0xBA, 0xAE,
+	    0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }
+	}
+};
+
+/*
+ * SHA256 test vectors from from NIST
+ */
+#define SHA256_TEST_VECTORS	2
+
+struct sha256_testvec {
+	char plaintext[128];
+	char digest[SHA256_DIGEST_SIZE];
+} sha256_tv_template[] = {
+	{ "abc",
+	  { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
+	    0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
+	    0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
+	    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }
+	},
+	        	
+	{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	  { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
+	    0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
+	    0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
+	    0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
+	},
+};
+
+/*
+ * SHA384 test vectors from from NIST and kerneli
+ */
+#define SHA384_TEST_VECTORS	4
+
+struct sha384_testvec {
+	char plaintext[128];
+	char digest[SHA384_DIGEST_SIZE];
+} sha384_tv_template[] = {
+
+	{ "abc",
+	  { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
+	    0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
+	    0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
+	    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
+	    0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
+	    0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }
+	},
+	
+	{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	  { 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39,
+	    0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39,
+	    0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab,
+	    0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6,
+	    0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f,
+	    0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b  }
+	},
+	
+	{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+	  "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+	  { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
+	    0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
+	    0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
+	    0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
+	    0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
+	    0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39  }
+	},
+	
+	{ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+	  "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+	  { 0x3d, 0x20, 0x89, 0x73, 0xab, 0x35, 0x08, 0xdb,
+	    0xbd, 0x7e, 0x2c, 0x28, 0x62, 0xba, 0x29, 0x0a,
+	    0xd3, 0x01, 0x0e, 0x49, 0x78, 0xc1, 0x98, 0xdc,
+	    0x4d, 0x8f, 0xd0, 0x14, 0xe5, 0x82, 0x82, 0x3a,
+	    0x89, 0xe1, 0x6f, 0x9b, 0x2a, 0x7b, 0xbc, 0x1a,
+	    0xc9, 0x38, 0xe2, 0xd1, 0x99, 0xe8, 0xbe, 0xa4 }
+	},
+};
+
+/*
+ * SHA512 test vectors from from NIST and kerneli
+ */
+#define SHA512_TEST_VECTORS	4
+
+struct sha512_testvec {
+	char plaintext[128];
+	char digest[SHA512_DIGEST_SIZE];
+} sha512_tv_template[] = {
+
+	{ "abc",
+	  { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
+	    0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
+	    0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+	    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
+	    0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
+	    0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+	    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
+	    0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
+	},
+	
+	{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	  { 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a,
+	    0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16,
+	    0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8,
+	    0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35,
+	    0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9,
+	    0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0,
+	    0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03,
+	    0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45 }
+	},
+	
+	{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+	  "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+	  { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
+	    0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
+	    0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
+	    0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
+	    0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
+	    0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
+	    0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
+	    0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
+	},
+	
+	{ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+	  "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+	  { 0x93, 0x0d, 0x0c, 0xef, 0xcb, 0x30, 0xff, 0x11,
+	    0x33, 0xb6, 0x89, 0x81, 0x21, 0xf1, 0xcf, 0x3d,
+	    0x27, 0x57, 0x8a, 0xfc, 0xaf, 0xe8, 0x67, 0x7c,
+	    0x52, 0x57, 0xcf, 0x06, 0x99, 0x11, 0xf7, 0x5d,
+	    0x8f, 0x58, 0x31, 0xb5, 0x6e, 0xbf, 0xda, 0x67,
+	    0xb2, 0x78, 0xe6, 0x6d, 0xff, 0x8b, 0x84, 0xfe,
+	    0x2b, 0x28, 0x70, 0xf7, 0x42, 0xa5, 0x80, 0xd8,
+	    0xed, 0xb4, 0x19, 0x87, 0x23, 0x28, 0x50, 0xc9
+	  }
+	},
+};
+
+/*
+ * DES test vectors.
+ */
+#define DES_ENC_TEST_VECTORS		5
+#define DES_DEC_TEST_VECTORS		2
+#define DES_CBC_ENC_TEST_VECTORS	4
+#define DES_CBC_DEC_TEST_VECTORS	3
+#define DES3_EDE_ENC_TEST_VECTORS	3
+#define DES3_EDE_DEC_TEST_VECTORS	3
+
+struct des_tv {
+	unsigned int len;
+	int fail;
+	char key[24];
+	char iv[8];
+	char plaintext[128];
+	char result[128];
+};
+
+struct des_tv des_enc_tv_template[] = {
+
+	/* From Applied Cryptography */
+	{
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		{ 0 },
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 },
+		{ 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d }
+	},
+	
+	/* Same key, different plaintext block */
+	{
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		{ 0 },
+		{ 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
+		{ 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }
+	},
+	
+	/* Sbox test from NBS */
+	{
+		8, 0,
+		
+		{ 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 },
+		{ 0 },
+		{ 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42 },
+		{ 0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B }
+	},
+	
+	/* Three blocks */
+	{
+		24, 0,
+		
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		
+		{ 0 },
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
+		  0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
+		  0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef },
+
+		{ 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
+		  0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b,
+		  0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90 },		  
+	},
+	
+	/* Weak key */
+	{
+		8, 1,
+		
+		{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
+		{ 0 },
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 },
+		{ 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d }
+	},
+	
+	/* Two blocks -- for testing encryption across pages */
+	{
+		16, 0,
+		
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		
+		{ 0 },
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
+		  0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
+
+		{ 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
+		  0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }
+	},
+
+	/* Two blocks -- for testing decryption across pages */
+	{
+		16, 0,
+		
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		
+		{ 0 },
+		
+		{ 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
+		  0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b },
+		  
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
+		  0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
+	},
+	
+	/* Four blocks -- for testing encryption with chunking */
+	{
+		24, 0,
+		
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		
+		{ 0 },
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
+		  0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
+		  0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef,
+		  0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
+
+		{ 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
+		  0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b,
+		  0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90,
+		  0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b },
+	},
+	
+};
+
+struct des_tv des_dec_tv_template[] = {
+
+	/* From Applied Cryptography */
+	{
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		{ 0 },
+		{ 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d },
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 },
+	},
+	
+	/* Sbox test from NBS */
+	{
+		8, 0,
+
+		{ 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 },
+		{ 0 },
+		{ 0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B },
+		{ 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42 }
+	},
+	
+	/* Two blocks, for chunking test */
+	{
+		16, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		{ 0 },
+		
+		{ 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
+		  0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B },
+		  
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
+		  0xa3, 0x99, 0x7b, 0xca, 0xaf, 0x69, 0xa0, 0xf5 }
+	},
+
+};
+
+struct des_tv des_cbc_enc_tv_template[] = {
+	/* From OpenSSL */
+	{
+		24, 0,
+		
+		{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+		{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+		
+		{ 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, 
+		  0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 
+		  0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 
+		  0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00 },
+		  
+		{ 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, 
+		  0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, 
+		  0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68, 
+		  0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4 }
+	},
+
+	/* FIPS Pub 81 */
+	{
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		{ 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef },
+		{ 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 },
+		{ 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
+		
+	},
+	
+	{
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		{ 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
+		{ 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 },
+		{ 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
+	},
+	
+	{	
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		{ 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
+		{ 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 },
+		{ 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 },
+	},
+	
+	/* Copy of openssl vector for chunk testing */
+	
+	/* From OpenSSL */
+	{
+		24, 0,
+		
+		{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+		{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+		
+		{ 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, 
+		  0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 
+		  0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 
+		  0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00 },
+		  
+		{ 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, 
+		  0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, 
+		  0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68, 
+		  0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4 }
+	},
+
+	
+};
+
+struct des_tv des_cbc_dec_tv_template[] = {
+
+	/* FIPS Pub 81 */
+	{
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		{ 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef },
+		{ 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
+		{ 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 },
+	},
+	
+	{
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		{ 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
+		{ 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
+		{ 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, 
+	},
+	
+	{
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		{ 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
+		{ 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, 
+		{ 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 },
+	},
+	
+	/* Copy of above, for chunk testing */
+	
+	{
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+		{ 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
+		{ 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, 
+		{ 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 },
+	},
+};
+
+/*
+ * We really need some more test vectors, especially for DES3 CBC.
+ */
+struct des_tv des3_ede_enc_tv_template[] = {
+
+	/* These are from openssl */
+	{
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+		  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
+		  
+		{ 0 },
+		
+		{ 0x73, 0x6F, 0x6D, 0x65, 0x64, 0x61, 0x74, 0x61  },
+		
+		{ 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 },
+	},
+	
+	{
+		8, 0,
+		
+		{ 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17,
+		  0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98,
+		  0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57  },
+		 
+		{ 0 },
+		
+		{ 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65  },
+		
+		{ 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30  }
+	},
+	
+
+	{
+		8, 0,
+		
+		{ 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20,
+		  0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01,
+		  0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01  },
+		  
+		{ 0 },
+			  
+		{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  },
+		
+		{ 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b  }	
+	},
+};
+
+struct des_tv des3_ede_dec_tv_template[] = {
+
+	/* These are from openssl */
+	{
+		8, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+		  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
+		  
+		{ 0 },
+		
+		
+		{ 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 },
+		
+		{ 0x73, 0x6F, 0x6D, 0x65, 0x64, 0x61, 0x74, 0x61  },
+	},
+	
+	{
+		8, 0,
+		
+		{ 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17,
+		  0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98,
+		  0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57  },
+		 
+		{ 0 },
+		
+		{ 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30  },
+		
+		{ 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65  },
+		
+	},
+	
+
+	{
+		8, 0,
+		
+		{ 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20,
+		  0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01,
+		  0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01  },
+		  
+		{ 0 },
+			  
+		{ 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b  },
+		
+		{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  },
+	},
+};
+
+/*
+ * Blowfish test vectors.
+ */
+#define BF_ENC_TEST_VECTORS	6
+#define BF_DEC_TEST_VECTORS	6
+#define BF_CBC_ENC_TEST_VECTORS	1
+#define BF_CBC_DEC_TEST_VECTORS	1
+
+struct bf_tv {
+	unsigned int keylen;
+	unsigned int plen;
+	unsigned int rlen;
+	int fail;
+	char key[56];
+	char iv[8];
+	char plaintext[32];
+	char result[32];
+};
+
+struct bf_tv bf_enc_tv_template[] = {
+
+	/* DES test vectors from OpenSSL */
+	{
+		8, 8, 8, 0,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
+		{ 0 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78 },
+	},
+	
+	{
+		8, 8, 8, 0,
+		{ 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E,  },
+		{ 0 },
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
+		{ 0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE },
+	},
+	
+	{
+		8, 8, 8, 0,
+		{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, },
+		{ 0 },
+		{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+		{ 0xE8, 0x7A, 0x24, 0x4E, 0x2C, 0xC8, 0x5E, 0x82 }
+	},
+	
+	/* Vary the keylength... */
+	
+	{
+		16, 8, 8, 0,
+		{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+		  0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F },
+		{ 0 },
+		{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+		{ 0x93, 0x14, 0x28, 0x87, 0xEE, 0x3B, 0xE1, 0x5C }
+	},
+	
+	{
+		21, 8, 8, 0,
+		{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+		  0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F,
+		  0x00, 0x11, 0x22, 0x33, 0x44 },
+		{ 0 },
+		{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+		{ 0xE6, 0xF5, 0x1E, 0xD7, 0x9B, 0x9D, 0xB2, 0x1F }
+	},
+	
+	/* Generated with bf488 */
+	{
+		56, 8, 8, 0,
+		{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+		  0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F,
+		  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+		  0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F, 
+		  0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76, 
+		  0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, 
+		  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+		  { 0 },
+		  { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+		  { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 }
+	}
+	
+};
+
+struct bf_tv bf_dec_tv_template[] = {
+
+	/* DES test vectors from OpenSSL */
+	{
+		8, 8, 8, 0,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
+		{ 0 },
+		{ 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+	},
+	
+	{
+		8, 8, 8, 0,
+		{ 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E,  },
+		{ 0 },
+		{ 0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE },
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }
+	},
+	
+	{
+		8, 8, 8, 0,
+		{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, },
+		{ 0 },
+		{ 0xE8, 0x7A, 0x24, 0x4E, 0x2C, 0xC8, 0x5E, 0x82 },
+		{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }
+	},
+	
+	/* Vary the keylength... */
+	
+	{
+		16, 8, 8, 0,
+		{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+		  0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F },
+		{ 0 },
+		{ 0x93, 0x14, 0x28, 0x87, 0xEE, 0x3B, 0xE1, 0x5C },
+		{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }
+	},
+	
+	{
+		21, 8, 8, 0,
+		{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+		  0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F,
+		  0x00, 0x11, 0x22, 0x33, 0x44 },
+		{ 0 },
+		{ 0xE6, 0xF5, 0x1E, 0xD7, 0x9B, 0x9D, 0xB2, 0x1F },
+		{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }
+	},
+	
+	/* Generated with bf488, using OpenSSL, Libgcrypt and Nettle */
+	{
+		56, 8, 8, 0,
+		{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+		  0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F,
+		  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+		  0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F, 
+		  0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76, 
+		  0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, 
+		  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+		{ 0 },
+		{ 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 },
+		{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }
+	}
+};
+
+struct bf_tv bf_cbc_enc_tv_template[] = {
+
+	/* From OpenSSL */
+	{
+		16, 32, 32, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 },
+		  
+		{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+		
+		{ 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
+		  0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
+		  0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20,
+		  0x66, 0x6F, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 },
+		  
+		{ 0x6B, 0x77, 0xB4, 0xD6, 0x30, 0x06, 0xDE, 0xE6,
+		  0x05, 0xB1, 0x56, 0xE2, 0x74, 0x03, 0x97, 0x93,
+		  0x58, 0xDE, 0xB9, 0xE7, 0x15, 0x46, 0x16, 0xD9,
+		  0x59, 0xF1, 0x65, 0x2B, 0xD5, 0xFF, 0x92, 0xCC }
+	},
+};
+
+struct bf_tv bf_cbc_dec_tv_template[] = {
+
+	/* From OpenSSL */
+	{
+		16, 32, 32, 0,
+		
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 },
+		  
+		{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+		
+		{ 0x6B, 0x77, 0xB4, 0xD6, 0x30, 0x06, 0xDE, 0xE6,
+		  0x05, 0xB1, 0x56, 0xE2, 0x74, 0x03, 0x97, 0x93,
+		  0x58, 0xDE, 0xB9, 0xE7, 0x15, 0x46, 0x16, 0xD9,
+		  0x59, 0xF1, 0x65, 0x2B, 0xD5, 0xFF, 0x92, 0xCC },
+		  
+		{ 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
+		  0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
+		  0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20,
+		  0x66, 0x6F, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 }
+	},
+};
+
+/*
+ * Twofish test vectors.
+ */
+#define TF_ENC_TEST_VECTORS		3
+#define TF_DEC_TEST_VECTORS		3
+#define TF_CBC_ENC_TEST_VECTORS		4
+#define TF_CBC_DEC_TEST_VECTORS		4
+
+struct tf_tv {
+	unsigned int keylen;
+	unsigned int plen;
+	unsigned int rlen;
+	int fail;
+	char key[32];
+	char iv[16];
+	char plaintext[48];
+	char result[48];
+};
+
+struct tf_tv tf_enc_tv_template[] = {
+	{
+		16, 16, 16, 0,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
+		  0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }
+	},
+	{
+		24, 16, 16, 0,
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+		  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
+		{ 0 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF,
+		  0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48 }
+	},
+	{	
+		32, 16, 16, 0,
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+		  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+		  0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
+		{ 0 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8,
+		  0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20 }
+	},
+};
+
+struct tf_tv tf_dec_tv_template[] = {
+	{
+		16, 16, 16, 0,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0 },
+		{ 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
+		  0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+	},
+	{
+		24, 16, 16, 0,
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+		  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
+		{ 0 },
+		{ 0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF,
+		  0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+	},
+	{	
+		32, 16, 16, 0,
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+		  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+		  0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
+		{ 0 },
+		{ 0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8,
+		  0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+	},
+};
+
+struct tf_tv tf_cbc_enc_tv_template[] = {
+	/* Generated with Nettle */
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
+	},
+	
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+	},
+	
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+		  0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+	},
+	
+	{
+		16, 48, 48, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a,
+		  0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19,
+		  0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+		  0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+	},
+};
+
+struct tf_tv tf_cbc_dec_tv_template[] = {
+	/* Reverse of the first four above */
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },		  
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+	},
+	
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
+		{ 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+	},
+	
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+		{ 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+		  0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+	},
+	
+	{
+		16, 48, 48, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a,
+		  0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19,
+		  0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+		  0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+	},
+};
+
+/*
+ * Serpent test vectors.  These are backwards because Serpent writes
+ * octect sequences in right-to-left mode.
+ */
+#define SERPENT_ENC_TEST_VECTORS	4
+#define SERPENT_DEC_TEST_VECTORS	4
+
+struct serpent_tv {
+	unsigned int keylen, fail;
+	u8 key[32], plaintext[16], result[16];
+};
+
+struct serpent_tv serpent_enc_tv_template[] = 
+{
+	{
+		0, 0,
+		{ 0 },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
+		  0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 }
+	},
+	{
+		16, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c,
+		  0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d }
+	},
+	{
+		32, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8,
+		  0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c }
+	},
+	{
+		16, 0,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
+		  0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49}
+	}
+};
+
+struct serpent_tv serpent_dec_tv_template[] = 
+{
+	{
+		0, 0,
+		{ 0 },
+		{ 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
+		  0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+
+	},
+	{
+		16, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c,
+		  0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+	},
+	{
+		32, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+
+		{ 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8,
+		  0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+	},
+	{
+		16, 0,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
+		{ 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
+		  0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49},
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+	}
+};
+
+/*
+ * AES test vectors.
+ */
+#define AES_ENC_TEST_VECTORS 3
+#define AES_DEC_TEST_VECTORS 3
+
+struct aes_tv {
+	unsigned int keylen;
+	unsigned int plen;
+	unsigned int rlen;
+	int fail;
+	char key[32];
+	char iv[8];
+	char plaintext[16];
+	char result[16];
+};
+
+struct aes_tv aes_enc_tv_template[] = { 
+	/* From FIPS-197 */
+	{
+		16, 16, 16, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0 },
+		{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+		  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+		{ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
+		  0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a },
+	},
+	{
+		24, 16, 16, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
+		{ 0 },
+		{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
+		  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+		{ 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
+		  0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 },
+	},
+	{
+		32, 16, 16, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+		{ 0 },
+		{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
+		  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+		{ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
+		  0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 },
+	},
+};
+
+struct aes_tv aes_dec_tv_template[] = { 
+	/* From FIPS-197 */
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0 },
+		{ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
+		  0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a },
+		{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+		  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+	},
+	
+	{
+		24, 16, 16, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
+		{ 0 },
+		{ 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
+		  0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 },
+		{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
+		  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },  
+	},
+	{
+		32, 16, 16, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+		{ 0 },
+		{ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
+		  0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 },
+		{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
+		  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+	},
+};
+
+/*
+ * Compression stuff.
+ */
+#define COMP_BUF_SIZE           512
+
+struct comp_testvec {
+	int inlen, outlen;
+	char input[COMP_BUF_SIZE];
+	char output[COMP_BUF_SIZE];
+};
+
+/*
+ * Deflate test vectors (null-terminated strings).
+ * Params: winbits=11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL.
+ */
+#define DEFLATE_COMP_TEST_VECTORS 2
+#define DEFLATE_DECOMP_TEST_VECTORS 2
+
+struct comp_testvec deflate_comp_tv_template[] = {
+	{
+	  70, 38,
+	  
+	  "Join us now and share the software "
+	  "Join us now and share the software ",
+
+          { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56,
+            0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51,
+            0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9,
+            0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07,
+            0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 
+          },
+	},
+	  
+	{
+	  191, 122,
+	  
+	  "This document describes a compression method based on the DEFLATE"
+	  "compression algorithm.  This document defines the application of "
+	  "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+	  
+	  { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04,
+	    0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09,
+	    0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8,
+	    0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49,
+	    0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27,
+	    0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2,
+	    0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad,
+	    0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4,
+	    0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b,
+	    0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f,
+	    0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf,
+	    0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02,
+	    0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98,
+	    0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a,
+	    0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79,
+	    0xfa, 0x02 },
+	},
+};
+
+struct comp_testvec deflate_decomp_tv_template[] = {
+	{
+	  122, 191,
+	  
+	  { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04,
+	    0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09,
+	    0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8,
+	    0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49,
+	    0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27,
+	    0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2,
+	    0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad,
+	    0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4,
+	    0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b,
+	    0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f,
+	    0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf,
+	    0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02,
+	    0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98,
+	    0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a,
+	    0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79,
+	    0xfa, 0x02 },
+	    
+	    "This document describes a compression method based on the DEFLATE"
+	    "compression algorithm.  This document defines the application of "
+	    "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+	},
+	
+	{
+	  38, 70,
+	  
+          { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56,
+            0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51,
+            0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9,
+            0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07,
+            0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00
+          },
+          
+          "Join us now and share the software "
+	  "Join us now and share the software ",
+	},
+};
+
+#endif	/* _CRYPTO_TCRYPT_H */
diff -urN linux-2.4.22-pre2/crypto/twofish.c linux-2.4.22-pre3/crypto/twofish.c
--- linux-2.4.22-pre2/crypto/twofish.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/crypto/twofish.c	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,900 @@
+/*
+ * Twofish for CryptoAPI
+ *
+ * Originaly Twofish for GPG
+ * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
+ * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
+ *
+ * The original author has disclaimed all copyright interest in this
+ * code and thus put it in the public domain. The subsequent authors 
+ * have put this under the GNU General Public License.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ * USA
+ *
+ * This code is a "clean room" implementation, written from the paper
+ * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
+ * through http://www.counterpane.com/twofish.html
+ *
+ * For background information on multiplication in finite fields, used for
+ * the matrix operations in the key schedule, see the book _Contemporary
+ * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
+ * Third Edition.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+
+
+/* The large precomputed tables for the Twofish cipher (twofish.c)
+ * Taken from the same source as twofish.c
+ * Marc Mutz <Marc@Mutz.com>
+ */
+
+/* These two tables are the q0 and q1 permutations, exactly as described in
+ * the Twofish paper. */
+
+static const u8 q0[256] = {
+   0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
+   0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+   0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
+   0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+   0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
+   0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+   0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
+   0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+   0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
+   0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+   0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
+   0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+   0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
+   0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+   0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
+   0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+   0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
+   0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+   0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
+   0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+   0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
+   0x4A, 0x5E, 0xC1, 0xE0
+};
+
+static const u8 q1[256] = {
+   0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
+   0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+   0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
+   0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+   0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
+   0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+   0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
+   0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+   0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
+   0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+   0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
+   0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+   0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
+   0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+   0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
+   0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+   0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
+   0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+   0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
+   0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+   0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
+   0x55, 0x09, 0xBE, 0x91
+};
+
+/* These MDS tables are actually tables of MDS composed with q0 and q1,
+ * because it is only ever used that way and we can save some time by
+ * precomputing.  Of course the main saving comes from precomputing the
+ * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
+ * things up in these tables we reduce the matrix multiply to four lookups
+ * and three XORs.  Semi-formally, the definition of these tables is:
+ * mds[0][i] = MDS (q1[i] 0 0 0)^T  mds[1][i] = MDS (0 q0[i] 0 0)^T
+ * mds[2][i] = MDS (0 0 q1[i] 0)^T  mds[3][i] = MDS (0 0 0 q0[i])^T
+ * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
+ * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
+ * by Schneier et al, and I'm casually glossing over the byte/word
+ * conversion issues. */
+
+static const u32 mds[4][256] = {
+   {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
+    0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
+    0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
+    0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
+    0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
+    0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
+    0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
+    0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
+    0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
+    0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
+    0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
+    0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
+    0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
+    0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
+    0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
+    0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
+    0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
+    0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
+    0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
+    0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
+    0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
+    0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
+    0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
+    0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
+    0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
+    0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
+    0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
+    0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
+    0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
+    0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
+    0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
+    0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
+    0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
+    0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
+    0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
+    0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
+    0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
+    0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
+    0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
+    0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
+    0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
+    0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
+    0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
+
+   {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
+    0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
+    0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
+    0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
+    0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
+    0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
+    0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
+    0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
+    0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
+    0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
+    0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
+    0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
+    0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
+    0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
+    0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
+    0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
+    0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
+    0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
+    0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
+    0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
+    0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
+    0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
+    0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
+    0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
+    0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
+    0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
+    0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
+    0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
+    0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
+    0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
+    0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
+    0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
+    0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
+    0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
+    0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
+    0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
+    0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
+    0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
+    0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
+    0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
+    0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
+    0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
+    0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
+
+   {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
+    0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
+    0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
+    0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
+    0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
+    0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
+    0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
+    0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
+    0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
+    0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
+    0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
+    0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
+    0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
+    0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
+    0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
+    0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
+    0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
+    0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
+    0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
+    0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
+    0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
+    0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
+    0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
+    0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
+    0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
+    0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
+    0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
+    0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
+    0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
+    0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
+    0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
+    0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
+    0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
+    0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
+    0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
+    0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
+    0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
+    0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
+    0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
+    0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
+    0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
+    0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
+    0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
+
+   {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
+    0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
+    0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
+    0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
+    0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
+    0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
+    0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
+    0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
+    0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
+    0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
+    0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
+    0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
+    0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
+    0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
+    0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
+    0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
+    0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
+    0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
+    0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
+    0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
+    0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
+    0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
+    0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
+    0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
+    0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
+    0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
+    0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
+    0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
+    0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
+    0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
+    0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
+    0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
+    0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
+    0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
+    0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
+    0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
+    0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
+    0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
+    0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
+    0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
+    0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
+    0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
+    0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
+};
+
+/* The exp_to_poly and poly_to_exp tables are used to perform efficient
+ * operations in GF(2^8) represented as GF(2)[x]/w(x) where
+ * w(x)=x^8+x^6+x^3+x^2+1.  We care about doing that because it's part of the
+ * definition of the RS matrix in the key schedule.  Elements of that field
+ * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
+ * which can be represented naturally by bytes (just substitute x=2).  In that
+ * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
+ * multiplication is inefficient without hardware support.  To multiply
+ * faster, I make use of the fact x is a generator for the nonzero elements,
+ * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
+ * some n in 0..254.  Note that that caret is exponentiation in GF(2^8),
+ * *not* polynomial notation.  So if I want to compute pq where p and q are
+ * in GF(2^8), I can just say:
+ *    1. if p=0 or q=0 then pq=0
+ *    2. otherwise, find m and n such that p=x^m and q=x^n
+ *    3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
+ * The translations in steps 2 and 3 are looked up in the tables
+ * poly_to_exp (for step 2) and exp_to_poly (for step 3).  To see this
+ * in action, look at the CALC_S macro.  As additional wrinkles, note that
+ * one of my operands is always a constant, so the poly_to_exp lookup on it
+ * is done in advance; I included the original values in the comments so
+ * readers can have some chance of recognizing that this *is* the RS matrix
+ * from the Twofish paper.  I've only included the table entries I actually
+ * need; I never do a lookup on a variable input of zero and the biggest
+ * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
+ * never sum to more than 491.	I'm repeating part of the exp_to_poly table
+ * so that I don't have to do mod-255 reduction in the exponent arithmetic.
+ * Since I know my constant operands are never zero, I only have to worry
+ * about zero values in the variable operand, and I do it with a simple
+ * conditional branch.	I know conditionals are expensive, but I couldn't
+ * see a non-horrible way of avoiding them, and I did manage to group the
+ * statements so that each if covers four group multiplications. */
+
+static const u8 poly_to_exp[255] = {
+   0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
+   0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
+   0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
+   0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
+   0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
+   0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
+   0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
+   0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
+   0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
+   0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
+   0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
+   0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
+   0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
+   0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
+   0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
+   0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
+   0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
+   0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
+   0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
+   0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
+   0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
+   0x85, 0xC8, 0xA1
+};
+
+static const u8 exp_to_poly[492] = {
+   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
+   0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
+   0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
+   0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
+   0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
+   0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
+   0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
+   0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
+   0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
+   0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
+   0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
+   0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
+   0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
+   0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
+   0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
+   0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
+   0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
+   0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
+   0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
+   0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
+   0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
+   0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
+   0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
+   0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
+   0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
+   0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
+   0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
+   0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
+   0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
+   0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
+   0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
+   0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
+   0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
+   0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
+   0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
+   0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
+   0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
+   0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
+   0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
+   0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
+   0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
+};
+
+
+/* The table constants are indices of
+ * S-box entries, preprocessed through q0 and q1. */
+static const u8 calc_sb_tbl[512] = {
+    0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
+    0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
+    0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
+    0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
+    0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
+    0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
+    0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
+    0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
+    0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
+    0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
+    0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
+    0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
+    0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
+    0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
+    0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
+    0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
+    0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
+    0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
+    0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
+    0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
+    0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
+    0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
+    0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
+    0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
+    0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
+    0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
+    0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
+    0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
+    0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
+    0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
+    0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
+    0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
+    0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
+    0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
+    0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
+    0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
+    0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
+    0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
+    0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
+    0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
+    0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
+    0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
+    0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
+    0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
+    0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
+    0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
+    0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
+    0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
+    0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
+    0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
+    0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
+    0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
+    0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
+    0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
+    0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
+    0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
+    0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
+    0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
+    0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
+    0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
+    0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
+    0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
+    0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
+    0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
+};
+
+/* Macro to perform one column of the RS matrix multiplication.  The
+ * parameters a, b, c, and d are the four bytes of output; i is the index
+ * of the key bytes, and w, x, y, and z, are the column of constants from
+ * the RS matrix, preprocessed through the poly_to_exp table. */
+
+#define CALC_S(a, b, c, d, i, w, x, y, z) \
+   if (key[i]) { \
+      tmp = poly_to_exp[key[i] - 1]; \
+      (a) ^= exp_to_poly[tmp + (w)]; \
+      (b) ^= exp_to_poly[tmp + (x)]; \
+      (c) ^= exp_to_poly[tmp + (y)]; \
+      (d) ^= exp_to_poly[tmp + (z)]; \
+   }
+
+/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
+ * the S vector from CALC_S.  CALC_SB_2 computes a single entry in all
+ * four S-boxes, where i is the index of the entry to compute, and a and b
+ * are the index numbers preprocessed through the q0 and q1 tables
+ * respectively. */
+
+#define CALC_SB_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
+   ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
+   ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
+   ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
+
+/* Macro exactly like CALC_SB_2, but for 192-bit keys. */
+
+#define CALC_SB192_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[q0[(b) ^ sa] ^ se] ^ si]; \
+   ctx->s[1][i] = mds[1][q0[q1[(b) ^ sb] ^ sf] ^ sj]; \
+   ctx->s[2][i] = mds[2][q1[q0[(a) ^ sc] ^ sg] ^ sk]; \
+   ctx->s[3][i] = mds[3][q1[q1[(a) ^ sd] ^ sh] ^ sl];
+
+/* Macro exactly like CALC_SB_2, but for 256-bit keys. */
+
+#define CALC_SB256_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
+   ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
+   ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
+   ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
+
+/* Macros to calculate the whitening and round subkeys.  CALC_K_2 computes the
+ * last two stages of the h() function for a given index (either 2i or 2i+1).
+ * a, b, c, and d are the four bytes going into the last two stages.  For
+ * 128-bit keys, this is the entire h() function and a and c are the index
+ * preprocessed through q0 and q1 respectively; for longer keys they are the
+ * output of previous stages.  j is the index of the first key byte to use.
+ * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
+ * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
+ * rotations.  Its parameters are: a, the array to write the results into,
+ * j, the index of the first output entry, k and l, the preprocessed indices
+ * for index 2i, and m and n, the preprocessed indices for index 2i+1.
+ * CALC_K192_2 expands CALC_K_2 to handle 192-bit keys, by doing an
+ * additional lookup-and-XOR stage.  The parameters a, b, c and d are the
+ * four bytes going into the last three stages.  For 192-bit keys, c = d
+ * are the index preprocessed through q0, and a = b are the index
+ * preprocessed through q1; j is the index of the first key byte to use.
+ * CALC_K192 is identical to CALC_K but for using the CALC_K192_2 macro
+ * instead of CALC_K_2.
+ * CALC_K256_2 expands CALC_K192_2 to handle 256-bit keys, by doing an
+ * additional lookup-and-XOR stage.  The parameters a and b are the index
+ * preprocessed through q0 and q1 respectively; j is the index of the first
+ * key byte to use.  CALC_K256 is identical to CALC_K but for using the
+ * CALC_K256_2 macro instead of CALC_K_2. */
+
+#define CALC_K_2(a, b, c, d, j) \
+     mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
+   ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
+   ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
+   ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
+
+#define CALC_K(a, j, k, l, m, n) \
+   x = CALC_K_2 (k, l, k, l, 0); \
+   y = CALC_K_2 (m, n, m, n, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K192_2(a, b, c, d, j) \
+   CALC_K_2 (q0[a ^ key[(j) + 16]], \
+	     q1[b ^ key[(j) + 17]], \
+	     q0[c ^ key[(j) + 18]], \
+	     q1[d ^ key[(j) + 19]], j)
+
+#define CALC_K192(a, j, k, l, m, n) \
+   x = CALC_K192_2 (l, l, k, k, 0); \
+   y = CALC_K192_2 (n, n, m, m, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K256_2(a, b, j) \
+   CALC_K192_2 (q1[b ^ key[(j) + 24]], \
+	        q1[a ^ key[(j) + 25]], \
+	        q0[a ^ key[(j) + 26]], \
+	        q0[b ^ key[(j) + 27]], j)
+
+#define CALC_K256(a, j, k, l, m, n) \
+   x = CALC_K256_2 (k, l, 0); \
+   y = CALC_K256_2 (m, n, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+
+/* Macros to compute the g() function in the encryption and decryption
+ * rounds.  G1 is the straight g() function; G2 includes the 8-bit
+ * rotation for the high 32-bit word. */
+
+#define G1(a) \
+     (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
+   ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
+
+#define G2(b) \
+     (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
+   ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
+
+/* Encryption and decryption Feistel rounds.  Each one calls the two g()
+ * macros, does the PHT, and performs the XOR and the appropriate bit
+ * rotations.  The parameters are the round number (used to select subkeys),
+ * and the four 32-bit chunks of the text. */
+
+#define ENCROUND(n, a, b, c, d) \
+   x = G1 (a); y = G2 (b); \
+   x += y; y += x + ctx->k[2 * (n) + 1]; \
+   (c) ^= x + ctx->k[2 * (n)]; \
+   (c) = ((c) >> 1) + ((c) << 31); \
+   (d) = (((d) << 1)+((d) >> 31)) ^ y
+
+#define DECROUND(n, a, b, c, d) \
+   x = G1 (a); y = G2 (b); \
+   x += y; y += x; \
+   (d) ^= y + ctx->k[2 * (n) + 1]; \
+   (d) = ((d) >> 1) + ((d) << 31); \
+   (c) = (((c) << 1)+((c) >> 31)); \
+   (c) ^= (x + ctx->k[2 * (n)])
+
+/* Encryption and decryption cycles; each one is simply two Feistel rounds
+ * with the 32-bit chunks re-ordered to simulate the "swap" */
+
+#define ENCCYCLE(n) \
+   ENCROUND (2 * (n), a, b, c, d); \
+   ENCROUND (2 * (n) + 1, c, d, a, b)
+
+#define DECCYCLE(n) \
+   DECROUND (2 * (n) + 1, c, d, a, b); \
+   DECROUND (2 * (n), a, b, c, d)
+
+/* Macros to convert the input and output bytes into 32-bit words,
+ * and simultaneously perform the whitening step.  INPACK packs word
+ * number n into the variable named by x, using whitening subkey number m.
+ * OUTUNPACK unpacks word number n from the variable named by x, using
+ * whitening subkey number m. */
+
+#define INPACK(n, x, m) \
+   x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
+     ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
+
+#define OUTUNPACK(n, x, m) \
+   x ^= ctx->w[m]; \
+   out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
+   out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
+
+#define TF_MIN_KEY_SIZE 16
+#define TF_MAX_KEY_SIZE 32
+#define TF_BLOCK_SIZE 16
+
+/* Structure for an expanded Twofish key.  s contains the key-dependent
+ * S-boxes composed with the MDS matrix; w contains the eight "whitening"
+ * subkeys, K[0] through K[7].	k holds the remaining, "round" subkeys.  Note
+ * that k[i] corresponds to what the Twofish paper calls K[i+8]. */
+struct twofish_ctx {
+   u32 s[4][256], w[8], k[32];
+};
+
+/* Perform the key setup. */
+static int twofish_setkey(void *cx, const u8 *key,
+                          unsigned int key_len, u32 *flags)
+{
+	
+	struct twofish_ctx *ctx = cx;
+
+	int i, j, k;
+
+	/* Temporaries for CALC_K. */
+	u32 x, y;
+
+	/* The S vector used to key the S-boxes, split up into individual bytes.
+	 * 128-bit keys use only sa through sh; 256-bit use all of them. */
+	u8 sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
+	u8 si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
+
+	/* Temporary for CALC_S. */
+	u8 tmp;
+
+	/* Check key length. */
+	if (key_len != 16 && key_len != 24 && key_len != 32)
+		return -EINVAL; /* unsupported key length */
+
+	/* Compute the first two words of the S vector.  The magic numbers are
+	 * the entries of the RS matrix, preprocessed through poly_to_exp. The
+	 * numbers in the comments are the original (polynomial form) matrix
+	 * entries. */
+	CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+	CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+	CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+	CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+	CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+	CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+	CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+	CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+	CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+	CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+	CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+	CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+	CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+	CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+	CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+	CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+	if (key_len == 24 || key_len == 32) { /* 192- or 256-bit key */
+		/* Calculate the third word of the S vector */
+		CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+		CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+		CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+		CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+		CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+		CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+		CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+		CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+	}
+
+	if (key_len == 32) { /* 256-bit key */
+		/* Calculate the fourth word of the S vector */
+		CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+		CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+		CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+		CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+		CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+		CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+		CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+		CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+		/* Compute the S-boxes. */
+		for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+			CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+		}
+
+		/* Calculate whitening and round subkeys.  The constants are
+		 * indices of subkeys, preprocessed through q0 and q1. */
+		CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+		CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+		CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+		CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+		CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+		CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+		CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+		CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+		CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+		CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+		CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+		CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+		CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+		CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+		CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+		CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+		CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+		CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+		CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+		CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+	} else if (key_len == 24) { /* 192-bit key */
+		/* Compute the S-boxes. */
+		for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+		        CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+		}
+
+		/* Calculate whitening and round subkeys.  The constants are
+		 * indices of subkeys, preprocessed through q0 and q1. */
+		CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+		CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+		CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+		CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+		CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+		CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+		CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+		CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+		CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+		CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+		CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+		CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+		CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+		CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+		CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+		CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+		CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+		CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+		CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+		CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+	} else { /* 128-bit key */
+		/* Compute the S-boxes. */
+		for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+			CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+		}
+
+		/* Calculate whitening and round subkeys.  The constants are
+		 * indices of subkeys, preprocessed through q0 and q1. */
+		CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+		CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+		CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+		CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+		CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+		CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+		CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+		CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+		CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+		CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+		CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
+		CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+		CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
+		CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+		CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+		CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
+		CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+		CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+		CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
+		CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+	}
+
+	return 0;
+}
+
+/* Encrypt one block.  in and out may be the same. */
+static void twofish_encrypt(void *cx, u8 *out, const u8 *in)
+{
+	struct twofish_ctx *ctx = cx;
+
+	/* The four 32-bit chunks of the text. */
+	u32 a, b, c, d;
+	
+	/* Temporaries used by the round function. */
+	u32 x, y;
+
+	/* Input whitening and packing. */
+	INPACK (0, a, 0);
+	INPACK (1, b, 1);
+	INPACK (2, c, 2);
+	INPACK (3, d, 3);
+	
+	/* Encryption Feistel cycles. */
+	ENCCYCLE (0);
+	ENCCYCLE (1);
+	ENCCYCLE (2);
+	ENCCYCLE (3);
+	ENCCYCLE (4);
+	ENCCYCLE (5);
+	ENCCYCLE (6);
+	ENCCYCLE (7);
+	
+	/* Output whitening and unpacking. */
+	OUTUNPACK (0, c, 4);
+	OUTUNPACK (1, d, 5);
+	OUTUNPACK (2, a, 6);
+	OUTUNPACK (3, b, 7);
+	
+}
+
+/* Decrypt one block.  in and out may be the same. */
+static void twofish_decrypt(void *cx, u8 *out, const u8 *in)
+{
+	struct twofish_ctx *ctx = cx;
+  
+	/* The four 32-bit chunks of the text. */
+	u32 a, b, c, d;
+	
+	/* Temporaries used by the round function. */
+	u32 x, y;
+	
+	/* Input whitening and packing. */
+	INPACK (0, c, 4);
+	INPACK (1, d, 5);
+	INPACK (2, a, 6);
+	INPACK (3, b, 7);
+	
+	/* Encryption Feistel cycles. */
+	DECCYCLE (7);
+	DECCYCLE (6);
+	DECCYCLE (5);
+	DECCYCLE (4);
+	DECCYCLE (3);
+	DECCYCLE (2);
+	DECCYCLE (1);
+	DECCYCLE (0);
+
+	/* Output whitening and unpacking. */
+	OUTUNPACK (0, a, 0);
+	OUTUNPACK (1, b, 1);
+	OUTUNPACK (2, c, 2);
+	OUTUNPACK (3, d, 3);
+
+}
+
+static struct crypto_alg alg = {
+	.cra_name           =   "twofish",
+	.cra_flags          =   CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize      =   TF_BLOCK_SIZE,
+	.cra_ctxsize        =   sizeof(struct twofish_ctx),
+	.cra_module         =   THIS_MODULE,
+	.cra_list           =   LIST_HEAD_INIT(alg.cra_list),
+	.cra_u              =   { .cipher = {
+	.cia_min_keysize    =   TF_MIN_KEY_SIZE,
+	.cia_max_keysize    =   TF_MAX_KEY_SIZE,
+	.cia_ivsize         =   TF_BLOCK_SIZE,
+	.cia_setkey         =   twofish_setkey,
+	.cia_encrypt        =   twofish_encrypt,
+	.cia_decrypt        =   twofish_decrypt } }
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION ("Twofish Cipher Algorithm");
diff -urN linux-2.4.22-pre2/drivers/acorn/block/fd1772.c linux-2.4.22-pre3/drivers/acorn/block/fd1772.c
--- linux-2.4.22-pre2/drivers/acorn/block/fd1772.c	2002-11-28 15:53:12.000000000 -0800
+++ linux-2.4.22-pre3/drivers/acorn/block/fd1772.c	2003-07-05 18:09:50.000000000 -0700
@@ -1567,26 +1567,26 @@
 
 int fd1772_init(void)
 {
-	int err;
-	int i;
+	int i, err;
 
 	if (!machine_is_archimedes())
 		return 0;
 
-	if (register_blkdev(MAJOR_NR, "fd", &floppy_fops)) {
+	err = register_blkdev(MAJOR_NR, "fd", &floppy_fops);
+	if (err) {
 		printk("Unable to get major %d for floppy\n", MAJOR_NR);
-		return 1;
+		goto err_out;
 	}
 
+	err = -EBUSY;
 	if (request_dma(FLOPPY_DMA, "fd1772")) {
 		printk("Unable to grab DMA%d for the floppy (1772) driver\n", FLOPPY_DMA);
-		return 1;
+		goto err_blkdev;
 	};
 
 	if (request_dma(FIQ_FD1772, "fd1772 end")) {
 		printk("Unable to grab DMA%d for the floppy (1772) driver\n", FIQ_FD1772);
-		err = 1; /* XXX */
-		goto cleanup_dma;
+		goto err_dma1;
 	};
 
 	/* initialize variables */
@@ -1596,16 +1596,15 @@
 	BufferDrive = BufferSide = BufferTrack = -1;
 	/* Atari uses 512 - I want to eventually cope with 1K sectors */
 	DMABuffer = (char *)kmalloc((FD1772_MAX_SECTORS+1)*512,GFP_KERNEL);
-	if (DMABuffer == NULL)
-		goto cleanup_dma;
 	TrackBuffer = DMABuffer + 512;
 #else
 	/* Allocate memory for the DMAbuffer - on the Atari this takes it
 	   out of some special memory... */
 	DMABuffer = (char *) kmalloc(2048);	/* Copes with pretty large sectors */
-	if (DMABuffer == NULL)
-		goto cleanup_dma;
 #endif
+	if (DMABuffer == NULL)
+		goto err_dma2;
+
 	enable_dma(FIQ_FD1772);	/* This inserts a call to our command end routine */
 	for (i = 0; i < FD_MAX_UNITS; i++) {
 		unit[i].track = -1;
@@ -1624,7 +1623,13 @@
 	config_types();
 
 	return 0;
-cleanup_dma:
+
+ err_dma2:
+	free_dma(FIQ_FD1772);
+ err_dma1:
 	free_dma(FLOPPY_DMA);
+ err_blkdev:
+	unregister_blkdev(MAJOR_NR, &floppy_fops);
+ err_out:
 	return err;
 }
diff -urN linux-2.4.22-pre2/drivers/acorn/char/Makefile linux-2.4.22-pre3/drivers/acorn/char/Makefile
--- linux-2.4.22-pre2/drivers/acorn/char/Makefile	2001-08-12 10:38:48.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/char/Makefile	2003-07-05 18:09:50.000000000 -0700
@@ -24,7 +24,9 @@
 obj-arc		:= keyb_arc.o
 obj-rpc		:= keyb_ps2.o
 obj-clps7500	:= keyb_ps2.o defkeymap-acorn.o
+obj-riscstation := keyb_ps2.o defkeymap-acorn.o
 
+obj-$(CONFIG_7K5MOUSE)		+= mouse_ps2.o
 obj-$(CONFIG_RPCMOUSE)		+= mouse_rpc.o
 obj-$(CONFIG_ATOMWIDE_SERIAL)	+= serial-atomwide.o
 obj-$(CONFIG_DUALSP_SERIAL)	+= serial-dualsp.o
diff -urN linux-2.4.22-pre2/drivers/acorn/char/i2c.c linux-2.4.22-pre3/drivers/acorn/char/i2c.c
--- linux-2.4.22-pre2/drivers/acorn/char/i2c.c	2001-03-02 18:38:37.000000000 -0800
+++ linux-2.4.22-pre3/drivers/acorn/char/i2c.c	2003-07-05 18:09:50.000000000 -0700
@@ -14,6 +14,9 @@
  */
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/miscdevice.h>
+#include <linux/rtc.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 
@@ -21,15 +24,19 @@
 #include <asm/io.h>
 #include <asm/hardware/ioc.h>
 #include <asm/system.h>
+#include <asm/uaccess.h>
 
 #include "pcf8583.h"
 
-extern unsigned long
-mktime(unsigned int year, unsigned int mon, unsigned int day,
-       unsigned int hour, unsigned int min, unsigned int sec);
 extern int (*set_rtc)(void);
 
 static struct i2c_client *rtc_client;
+static const unsigned char days_in_mon[] = 
+	{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+static unsigned int rtc_epoch = 1900;
+
+#define CMOS_CHECKSUM	(63)
+#define CMOS_YEAR	(64 + 128)
 
 static inline int rtc_command(int cmd, void *data)
 {
@@ -44,12 +51,10 @@
 /*
  * Read the current RTC time and date, and update xtime.
  */
-static void get_rtc_time(void)
+static void get_rtc_time(struct rtc_tm *rtctm, unsigned int *year)
 {
-	unsigned char ctrl;
-	unsigned char year;
-	struct rtc_tm rtctm;
-	struct mem rtcmem = { 0xc0, 1, &year };
+	unsigned char ctrl, yr[2];
+	struct mem rtcmem = { CMOS_YEAR, sizeof(yr), yr };
 
 	/*
 	 * Ensure that the RTC is running.
@@ -73,22 +78,53 @@
 	if (rtc_command(MEM_READ, &rtcmem))
 		return;
 
-	if (rtc_command(RTC_GETDATETIME, &rtctm))
+	if (rtc_command(RTC_GETDATETIME, rtctm))
 		return;
 
-	if (year < 70)
-		year += 100;
+	*year = yr[1] * 100 + yr[0];
+}
+
+static int set_rtc_time(struct rtc_tm *rtctm, unsigned int year)
+{
+	unsigned char yr[2], leap, chk;
+	struct mem cmos_year  = { CMOS_YEAR, sizeof(yr), yr };
+	struct mem cmos_check = { CMOS_CHECKSUM, 1, &chk };
+	int ret;
+
+	leap = (!(year % 4) && (year % 100)) || !(year % 400);
+
+	if (rtctm->mon > 12 || rtctm->mday == 0)
+		return -EINVAL;
+
+	if (rtctm->mday > (days_in_mon[rtctm->mon] + (rtctm->mon == 2 && leap)))
+		return -EINVAL;
+
+	if (rtctm->hours >= 24 || rtctm->mins >= 60 || rtctm->secs >= 60)
+		return -EINVAL;
 
-	xtime.tv_usec = rtctm.cs * 10000;
-	xtime.tv_sec  = mktime(1900 + year, rtctm.mon, rtctm.mday,
-			       rtctm.hours, rtctm.mins, rtctm.secs);
+	ret = rtc_command(RTC_SETDATETIME, rtctm);
+	if (ret == 0) {
+		rtc_command(MEM_READ, &cmos_check);
+		rtc_command(MEM_READ, &cmos_year);
+
+		chk -= yr[1] + yr[0];
+
+		yr[1] = year / 100;
+		yr[0] = year % 100;
+
+		chk += yr[1] + yr[0];
+
+		rtc_command(MEM_WRITE, &cmos_year);
+		rtc_command(MEM_WRITE, &cmos_check);
+	}
+	return ret;
 }
 
 /*
  * Set the RTC time only.  Note that
  * we do not touch the date.
  */
-static int set_rtc_time(void)
+static int k_set_rtc_time(void)
 {
 	struct rtc_tm new_rtctm, old_rtctm;
 	unsigned long nowtime = xtime.tv_sec;
@@ -110,13 +146,70 @@
 	 * [ rtc: 1/1/2000 23:58:00, real 2/1/2000 00:01:00,
 	 *   rtc gets set to 1/1/2000 00:01:00 ]
 	 */
-	if ((old_rtctm.hours == 23 && old_rtctm.mins  == 59) ||
-	    (new_rtctm.hours == 23 && new_rtctm.mins  == 59))
+	if ((old_rtctm.hours == 23 && old_rtctm.mins == 59) ||
+	    (new_rtctm.hours == 23 && new_rtctm.mins == 59))
 		return 1;
 
 	return rtc_command(RTC_SETTIME, &new_rtctm);
 }
 
+static int rtc_ioctl(struct inode *inode, struct file *file,
+		     unsigned int cmd, unsigned long arg)
+{
+	unsigned int year;
+	struct rtc_time rtctm;
+	struct rtc_tm rtc_raw;
+
+	switch (cmd) {
+	case RTC_ALM_READ:
+	case RTC_ALM_SET:
+		break;
+
+	case RTC_RD_TIME:
+		get_rtc_time(&rtc_raw, &year);
+		rtctm.tm_sec  = rtc_raw.secs;
+		rtctm.tm_min  = rtc_raw.mins;
+		rtctm.tm_hour = rtc_raw.hours;
+		rtctm.tm_mday = rtc_raw.mday;
+		rtctm.tm_mon  = rtc_raw.mon - 1; /* month starts at 0 */
+		rtctm.tm_year = year - 1900; /* starts at 1900 */
+		return copy_to_user((void *)arg, &rtctm, sizeof(rtctm))
+				 ? -EFAULT : 0;
+
+	case RTC_SET_TIME:
+		if (!capable(CAP_SYS_TIME))
+			return -EACCES;
+
+		if (copy_from_user(&rtctm, (void *)arg, sizeof(rtctm)))
+			return -EFAULT;
+		rtc_raw.secs     = rtctm.tm_sec;
+		rtc_raw.mins     = rtctm.tm_min;
+		rtc_raw.hours    = rtctm.tm_hour;
+		rtc_raw.mday     = rtctm.tm_mday;
+		rtc_raw.mon      = rtctm.tm_mon + 1;
+		rtc_raw.year_off = 2;
+		year             = rtctm.tm_year + 1900;
+		return set_rtc_time(&rtc_raw, year);
+		break;
+
+	case RTC_EPOCH_READ:
+		return put_user(rtc_epoch, (unsigned long *)arg);
+
+	}
+	return -EINVAL;
+}
+
+static struct file_operations rtc_fops = {
+	ioctl:	rtc_ioctl,
+};
+
+static struct miscdevice rtc_dev = {
+	minor:	RTC_MINOR,
+	name:	"rtc",
+	fops:	&rtc_fops,
+};
+
+/* IOC / IOMD i2c driver */
 
 #define FORCE_ONES	0xdc
 #define SCL		0x02
@@ -184,9 +277,16 @@
 {
 	if (client->id == I2C_DRIVERID_PCF8583 &&
 	    client->addr == 0x50) {
+		struct rtc_tm rtctm;
+		unsigned int year;
+
 		rtc_client = client;
-		get_rtc_time();
-		set_rtc = set_rtc_time;
+		get_rtc_time(&rtctm, &year);
+
+		xtime.tv_usec = rtctm.cs * 10000;
+		xtime.tv_sec  = mktime(year, rtctm.mon, rtctm.mday,
+				       rtctm.hours, rtctm.mins, rtctm.secs);
+		set_rtc = k_set_rtc_time;
 	}
 
 	return 0;
@@ -212,9 +312,16 @@
 
 static int __init i2c_ioc_init(void)
 {
+	int ret;
+
 	force_ones = FORCE_ONES | SCL | SDA;
 
-	return i2c_bit_add_bus(&ioc_ops);
+	ret = i2c_bit_add_bus(&ioc_ops);
+
+	if (ret >= 0)
+		misc_register(&rtc_dev);
+
+	return ret;
 }
 
 __initcall(i2c_ioc_init);
diff -urN linux-2.4.22-pre2/drivers/acorn/char/keyb_arc.c linux-2.4.22-pre3/drivers/acorn/char/keyb_arc.c
--- linux-2.4.22-pre2/drivers/acorn/char/keyb_arc.c	2001-08-12 10:38:48.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/char/keyb_arc.c	2003-07-05 18:09:50.000000000 -0700
@@ -419,12 +419,51 @@
 		disable_irq(irq);
 }
 
+static int a5kkbd_setkeycode(unsigned int scancode, unsigned int keycode)
+{
+	return -EINVAL;
+}
+
+static int a5kkbd_getkeycode(unsigned int scancode)
+{
+	return -EINVAL;
+}
+
+static int a5kkbd_translate(unsigned char scancode, unsigned char *keycode, char rawmode)
+{
+	*keycode = scancode;
+	return 1;
+}
+
+static char a5kkbd_unexpected_up(unsigned char keycode)
+{
+	return 0200;
+}
+
+static int a5kkbd_rate(struct kbd_repeat *rep)
+{
+	return -EINVAL;
+}
+
 #ifdef CONFIG_KBDMOUSE
 static struct busmouse a5kkbd_mouse = {
 	6, "kbdmouse", NULL, NULL, NULL, 7
 };
 #endif
 
+struct kbd_ops_struct a5k_kbd_ops = {
+	k_setkeycode:		a5kkbd_setkeycode,
+	k_getkeycode:		a5kkbd_getkeycode,
+	k_translate:		a5kkbd_translate,
+	k_unexpected_up:	a5kkbd_unexpected_up,
+	k_leds:			a5kkbd_leds,
+	k_rate:			a5kkbd_rate,
+#ifdef CONFIG_MAGIC_SYSRQ
+	k_sysrq_xlate:		a5kkbd_sysrq_xlate,
+	k_sysrq_key:		13,
+#endif
+};
+
 void __init a5kkbd_init_hw (void)
 {
 	if (request_irq (IRQ_KEYBOARDTX, a5kkbd_tx, 0, "keyboard", NULL) != 0)
diff -urN linux-2.4.22-pre2/drivers/acorn/char/mouse_ps2.c linux-2.4.22-pre3/drivers/acorn/char/mouse_ps2.c
--- linux-2.4.22-pre2/drivers/acorn/char/mouse_ps2.c	2002-11-28 15:53:12.000000000 -0800
+++ linux-2.4.22-pre3/drivers/acorn/char/mouse_ps2.c	2003-07-05 18:09:50.000000000 -0700
@@ -1,8 +1,6 @@
 /* 
  * Driver for PS/2 mouse on IOMD interface
  */
-
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
@@ -294,3 +292,6 @@
 
 	return 0;
 }
+
+module_init(psaux_init);
+
diff -urN linux-2.4.22-pre2/drivers/acorn/char/serial-atomwide.c linux-2.4.22-pre3/drivers/acorn/char/serial-atomwide.c
--- linux-2.4.22-pre2/drivers/acorn/char/serial-atomwide.c	2000-09-18 15:15:22.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/char/serial-atomwide.c	2003-07-05 18:09:50.000000000 -0700
@@ -12,15 +12,28 @@
  *   07-05-1996	RMK	Altered for greater number of cards.
  *   30-07-1996	RMK	Now uses generic card code.
  */
-#define MY_CARD_LIST { MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL }
-#define MY_NUMPORTS 3
-#define MY_BAUD_BASE (7372800 / 16)
-#define MY_BASE_ADDRESS(ec) \
-	ecard_address ((ec), ECARD_IOC, ECARD_SLOW) + (0x2000 >> 2)
-#define MY_PORT_ADDRESS(port,cardaddr) \
-	((cardaddr) + 0x200 - (port) * 0x100)
+#include <linux/ioport.h>
+#include <asm/ecard.h>
 
-#define INIT serial_card_atomwide_init
-#define EXIT serial_card_atomwide_exit
+#define MAX_PORTS       3
+
+struct serial_card_type {
+	unsigned int	num_ports;
+	unsigned int	baud_base;
+	unsigned int	type;
+	unsigned int	offset[MAX_PORTS];
+};
+
+static struct serial_card_type atomwide_type = {
+	.num_ports	= 3,
+	.baud_base	= 7372800 / 16,
+	.type		= ECARD_RES_IOCSLOW,
+	.offset 	= { 0x2800, 0x2400, 0x2000 },
+};
+
+static const struct ecard_id serial_cids[] = {
+	{ MANU_ATOMWIDE,	PROD_ATOMWIDE_3PSERIAL, &atomwide_type	},
+	{ 0xffff, 0xffff }
+};
 
 #include "serial-card.c"
diff -urN linux-2.4.22-pre2/drivers/acorn/char/serial-card.c linux-2.4.22-pre3/drivers/acorn/char/serial-card.c
--- linux-2.4.22-pre2/drivers/acorn/char/serial-card.c	2001-09-13 15:21:32.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/char/serial-card.c	2003-07-05 18:09:50.000000000 -0700
@@ -27,106 +27,110 @@
  */
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
 #include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
+#include <asm/io.h>
 #include <asm/ecard.h>
 #include <asm/string.h>
 
-#ifndef NUM_SERIALS
-#define NUM_SERIALS	MY_NUMPORTS * MAX_ECARDS
-#endif
-
-#ifdef MODULE
-static int __serial_ports[NUM_SERIALS];
-static int __serial_pcount;
-static int __serial_addr[NUM_SERIALS];
-static struct expansion_card *expcard[MAX_ECARDS];
-#define ADD_ECARD(ec,card) expcard[(card)] = (ec)
-#define ADD_PORT(port,addr)					\
-	do {							\
-		__serial_ports[__serial_pcount] = (port);	\
-		__serial_addr[__serial_pcount] = (addr);	\
-		__serial_pcount += 1;				\
-	} while (0)
-#else
-#define ADD_ECARD(ec,card)
-#define ADD_PORT(port,addr)
-#endif
+struct serial_card_info {
+	unsigned int	num_ports;
+	int		ports[MAX_PORTS];
+};
 
-static const card_ids serial_cids[] = { MY_CARD_LIST, { 0xffff, 0xffff } };
-
-static inline int serial_register_onedev (unsigned long port, int irq)
+static inline int
+serial_register_onedev(unsigned long baddr, void *vaddr, int irq, unsigned int baud_base)
 {
-    struct serial_struct req;
+	struct serial_struct req;
 
-    memset(&req, 0, sizeof(req));
-    req.baud_base = MY_BAUD_BASE;
-    req.irq = irq;
-    req.port = port;
-    req.flags = 0;
+	memset(&req, 0, sizeof(req));
+	req.irq 		= irq;
+	req.flags		= UPF_AUTOPROBE | UPF_RESOURCES |
+				  UPF_SHARE_IRQ;
+	req.baud_base		= baud_base;
+	req.io_type		= UPIO_MEM;
+	req.iomem_base		= vaddr;
+	req.iomem_reg_shift	= 2;
+	req.iomap_base		= baddr;
 
-    return register_serial(&req);
+	return register_serial(&req);
 }
 
-static int __init INIT (void)
+static int __devinit
+serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
-    int card = 0;
-
-    ecard_startfind ();
+	struct serial_card_info *info;
+	struct serial_card_type *type = id->data;
+	unsigned long bus_addr;
+	unsigned char *virt_addr;
+	unsigned int port;
+
+	info = kmalloc(sizeof(struct serial_card_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	memset(info, 0, sizeof(struct serial_card_info));
+	info->num_ports = type->num_ports;
+
+	ecard_set_drvdata(ec, info);
+
+	bus_addr = ec->resource[type->type].start;
+	virt_addr = ioremap(bus_addr, ec->resource[type->type].end - bus_addr + 1);
+	if (!virt_addr) {
+		kfree(info);
+		return -ENOMEM;
+	}
 
-    do {
-	struct expansion_card *ec;
-	unsigned long cardaddr;
-	int port;
+	for (port = 0; port < info->num_ports; port ++) {
+		unsigned long baddr = bus_addr + type->offset[port];
+		unsigned char *vaddr = virt_addr + type->offset[port];
 
-	ec = ecard_find (0, serial_cids);
-	if (!ec)
-	    break;
+		info->ports[port] = serial_register_onedev(baddr, vaddr,
+						ec->irq, type->baud_base);
+	}
 
-	cardaddr = MY_BASE_ADDRESS(ec);
+	return 0;
+}
 
-	for (port = 0; port < MY_NUMPORTS; port ++) {
-	    unsigned long address;
-	    int line;
+static void __devexit serial_card_remove(struct expansion_card *ec)
+{
+	struct serial_card_info *info = ecard_get_drvdata(ec);
+	int i;
 
-	    address = MY_PORT_ADDRESS(port, cardaddr);
+	ecard_set_drvdata(ec, NULL);
 
-	    line = serial_register_onedev (address, ec->irq);
-	    if (line < 0)
-		break;
-	    ADD_PORT(line, address);
-	}
+	for (i = 0; i < info->num_ports; i++)
+		if (info->ports[i] > 0)
+			unregister_serial(info->ports[i]);
 
-	if (port) {
-	    ecard_claim (ec);
-	    ADD_ECARD(ec, card);
-	} else
-	    break;
-    } while (++card < MAX_ECARDS);
-    return card ? 0 : -ENODEV;
+	kfree(info);
 }
 
-static void __exit EXIT (void)
+static struct ecard_driver serial_card_driver = {
+	.probe		= serial_card_probe,
+	.remove 	= __devexit_p(serial_card_remove),
+	.id_table	= serial_cids,
+};
+
+static int __init serial_card_init(void)
 {
-#ifdef MODULE
-    int i;
+	return ecard_register_driver(&serial_card_driver);
+}
 
-    for (i = 0; i < __serial_pcount; i++) {
-	unregister_serial(__serial_ports[i]);
-	release_region(__serial_addr[i], 8);
-    }
-
-    for (i = 0; i < MAX_ECARDS; i++)
-	if (expcard[i])
-	    ecard_release (expcard[i]);
-#endif
+static void __exit serial_card_exit(void)
+{
+	ecard_remove_driver(&serial_card_driver);
 }
 
 EXPORT_NO_SYMBOLS;
 
+MODULE_AUTHOR("Russell King");
 MODULE_LICENSE("GPL");
 
-module_init(INIT);
-module_exit(EXIT);
+module_init(serial_card_init);
+module_exit(serial_card_exit);
diff -urN linux-2.4.22-pre2/drivers/acorn/char/serial-dualsp.c linux-2.4.22-pre3/drivers/acorn/char/serial-dualsp.c
--- linux-2.4.22-pre2/drivers/acorn/char/serial-dualsp.c	2000-09-18 15:15:22.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/char/serial-dualsp.c	2003-07-05 18:09:50.000000000 -0700
@@ -10,15 +10,28 @@
  *  Changelog:
  *   30-07-1996	RMK	Created
  */
-#define MY_CARD_LIST { MANU_SERPORT, PROD_SERPORT_DSPORT }
-#define MY_NUMPORTS 2
-#define MY_BAUD_BASE (3686400 / 16)
-#define MY_BASE_ADDRESS(ec) \
-	ecard_address (ec, ECARD_IOC, ECARD_SLOW) + (0x2000 >> 2)
-#define MY_PORT_ADDRESS(port,cardaddress) \
-	((cardaddress) + (port) * 8)
+#include <linux/ioport.h>
+#include <asm/ecard.h>
 
-#define INIT serial_card_dualsp_init
-#define EXIT serial_card_dualsp_exit
+#define MAX_PORTS       3
+
+struct serial_card_type {
+	unsigned int	num_ports;
+	unsigned int	baud_base;
+	unsigned int	type;
+	unsigned int	offset[MAX_PORTS];
+};
+
+static struct serial_card_type serport_type = {
+	.num_ports	= 2,
+	.baud_base	= 3686400 / 16,
+	.type		= ECARD_RES_IOCSLOW,
+	.offset 	= { 0x2000, 0x2020 },
+};
+
+static const struct ecard_id serial_cids[] = {
+	{ MANU_SERPORT, 	PROD_SERPORT_DSPORT,	&serport_type	},
+	{ 0xffff, 0xffff }
+};
 
 #include "serial-card.c"
diff -urN linux-2.4.22-pre2/drivers/acorn/net/ether1.c linux-2.4.22-pre3/drivers/acorn/net/ether1.c
--- linux-2.4.22-pre2/drivers/acorn/net/ether1.c	2001-09-13 15:21:32.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/net/ether1.c	2003-07-05 18:09:50.000000000 -0700
@@ -647,6 +647,11 @@
 {
 	struct ether1_priv *priv = (struct ether1_priv *)dev->priv;
 
+	if (!is_valid_ether_addr(dev->dev_addr)) {
+		printk("%s: invalid ethernet MAC address\n", dev->name);
+		return -EINVAL;
+	}
+
 	if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev))
 		return -EAGAIN;
 
@@ -684,7 +689,6 @@
 ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
 {
 	struct ether1_priv *priv = (struct ether1_priv *)dev->priv;
-	int len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
 	int tmp, tst, nopaddr, txaddr, tbdaddr, dataddr;
 	unsigned long flags;
 	tx_t tx;
@@ -702,19 +706,25 @@
 			priv->restart = 0;
 	}
 
+	if (skb->len < ETH_ZLEN) {
+		skb = skb_padto(skb, ETH_ZLEN);
+		if (!skb)
+			goto out;
+	}
+
 	/*
 	 * insert packet followed by a nop
 	 */
 	txaddr = ether1_txalloc (dev, TX_SIZE);
 	tbdaddr = ether1_txalloc (dev, TBD_SIZE);
-	dataddr = ether1_txalloc (dev, len);
+	dataddr = ether1_txalloc (dev, skb->len);
 	nopaddr = ether1_txalloc (dev, NOP_SIZE);
 
 	tx.tx_status = 0;
 	tx.tx_command = CMD_TX | CMD_INTR;
 	tx.tx_link = nopaddr;
 	tx.tx_tbdoffset = tbdaddr;
-	tbd.tbd_opts = TBD_EOL | len;
+	tbd.tbd_opts = TBD_EOL | skb->len;
 	tbd.tbd_link = I82586_NULL;
 	tbd.tbd_bufl = dataddr;
 	tbd.tbd_bufh = 0;
@@ -725,7 +735,7 @@
 	save_flags_cli(flags);
 	ether1_writebuffer (dev, &tx, txaddr, TX_SIZE);
 	ether1_writebuffer (dev, &tbd, tbdaddr, TBD_SIZE);
-	ether1_writebuffer (dev, skb->data, dataddr, len);
+	ether1_writebuffer (dev, skb->data, dataddr, skb->len);
 	ether1_writebuffer (dev, &nop, nopaddr, NOP_SIZE);
 	tmp = priv->tx_link;
 	priv->tx_link = nopaddr;
@@ -747,6 +757,7 @@
 	if (tst == -1)
 		netif_stop_queue(dev);
 
+ out:
 	return 0;
 }
 
@@ -971,6 +982,23 @@
 	return &priv->stats;
 }
 
+static int
+ether1_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	/*
+	 * We'll set the MAC address on the chip when we open it.
+	 */
+
+	return 0;
+}
+
 /*
  * Set or clear the multicast filter for this adaptor.
  * num_addrs == -1	Promiscuous mode, receive all packets.
@@ -1038,6 +1066,7 @@
 	dev->hard_start_xmit    = ether1_sendpacket;
 	dev->get_stats		= ether1_getstats;
 	dev->set_multicast_list = ether1_setmulticastlist;
+	dev->set_mac_address	= ether1_set_mac_address;
 	dev->tx_timeout		= ether1_timeout;
 	dev->watchdog_timeo	= 5 * HZ / 100;
 	return 0;
diff -urN linux-2.4.22-pre2/drivers/acorn/net/ether3.c linux-2.4.22-pre3/drivers/acorn/net/ether3.c
--- linux-2.4.22-pre2/drivers/acorn/net/ether3.c	2001-09-13 15:21:32.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/net/ether3.c	2003-07-05 18:09:50.000000000 -0700
@@ -417,6 +417,9 @@
 static int
 ether3_open(struct net_device *dev)
 {
+	if (!is_valid_ether_addr(dev->dev_addr))
+		return -EINVAL;
+
 	if (request_irq(dev->irq, ether3_interrupt, 0, "ether3", dev))
 		return -EAGAIN;
 
@@ -460,6 +463,23 @@
 	return &priv->stats;
 }
 
+static int
+ether3_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	/*
+	 * We'll set the MAC address on the chip when we open it.
+	 */
+
+	return 0;
+}
+
 /*
  * Set or clear promiscuous/multicast mode filter for this adaptor.
  *
@@ -531,6 +551,12 @@
 		return 0;
 	}
 
+	if (skb->len != length) {
+		skb = skb_padto(skb, length);
+		if (!skb)
+			goto out;
+	}
+
 	next_ptr = (priv->tx_head + 1) & 15;
 
 	save_flags_cli(flags);
@@ -572,6 +598,7 @@
 	if (priv->tx_tail == next_ptr)
 		netif_stop_queue(dev);
 
+ out:
 	return 0;
 }
 
@@ -718,7 +745,7 @@
 	/*
 	 * Don't print this message too many times...
 	 */
-	if (jiffies - last_warned > 30 * HZ) {
+	if (time_after(jiffies, last_warned + 10 * HZ)) {
 		last_warned = jiffies;
 		printk("%s: memory squeeze, dropping packet.\n", dev->name);
 	}
@@ -875,6 +902,7 @@
 	dev->hard_start_xmit	= ether3_sendpacket;
 	dev->get_stats		= ether3_getstats;
 	dev->set_multicast_list	= ether3_setmulticastlist;
+	dev->set_mac_address	= ether3_set_mac_address;
 	dev->tx_timeout		= ether3_timeout;
 	dev->watchdog_timeo	= 5 * HZ / 100;
 	return 0;
diff -urN linux-2.4.22-pre2/drivers/acorn/net/etherh.c linux-2.4.22-pre3/drivers/acorn/net/etherh.c
--- linux-2.4.22-pre2/drivers/acorn/net/etherh.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/net/etherh.c	2003-07-05 18:09:50.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/drivers/acorn/net/etherh.c
  *
- *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2000-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -23,6 +23,7 @@
  *  12-10-1999  CK/TEW		EtherM driver first release
  *  21-12-2000	TTC		EtherH/EtherM integration
  *  25-12-2000	RMK	1.08	Clean integration of EtherM into this driver.
+ *  03-01-2002	RMK	1.09	Always enable IRQs if we're in the nic slot.
  */
 
 #include <linux/module.h>
@@ -64,13 +65,18 @@
 	{ 0xffff,   0xffff }
 };
 
+struct etherh_priv {
+	unsigned int	id;
+	unsigned int	ctrl_port;
+	unsigned int	ctrl;
+};
 
 MODULE_AUTHOR("Russell King");
 MODULE_DESCRIPTION("EtherH/EtherM driver");
 MODULE_LICENSE("GPL");
 
 static char version[] __initdata =
-	"EtherH/EtherM Driver (c) 2000 Russell King v1.08\n";
+	"EtherH/EtherM Driver (c) 2002 Russell King v1.09\n";
 
 #define ETHERH500_DATAPORT	0x200	/* MEMC */
 #define ETHERH500_NS8390	0x000	/* MEMC */
@@ -97,18 +103,61 @@
 #define ETHERM_TX_START_PAGE	64
 #define ETHERM_STOP_PAGE	127
 
-/* --------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------ */
+
+static inline void etherh_set_ctrl(struct etherh_priv *eh, unsigned int mask)
+{
+	eh->ctrl |= mask;
+	outb(eh->ctrl, eh->ctrl_port);
+}
+
+static inline void etherh_clr_ctrl(struct etherh_priv *eh, unsigned int mask)
+{
+	eh->ctrl &= ~mask;
+	outb(eh->ctrl, eh->ctrl_port);
+}
+
+static inline unsigned int etherh_get_stat(struct etherh_priv *eh)
+{
+	return inb(eh->ctrl_port);
+}
+
+
+
+
+static void etherh_irq_enable(ecard_t *ec, int irqnr)
+{
+	struct etherh_priv *eh = ec->irq_data;
+
+	etherh_set_ctrl(eh, ETHERH_CP_IE);
+}
+
+static void etherh_irq_disable(ecard_t *ec, int irqnr)
+{
+	struct etherh_priv *eh = ec->irq_data;
+
+	etherh_clr_ctrl(eh, ETHERH_CP_IE);
+}
+
+static expansioncard_ops_t etherh_ops = {
+	irqenable:	etherh_irq_enable,
+	irqdisable:	etherh_irq_disable,
+};
+
+
+
 
 static void
 etherh_setif(struct net_device *dev)
 {
 	struct ei_device *ei_local = (struct ei_device *) dev->priv;
+	struct etherh_priv *eh = (struct etherh_priv *)dev->rmem_start;
 	unsigned long addr, flags;
 
 	save_flags_cli(flags);
 
 	/* set the interface type */
-	switch (dev->mem_end) {
+	switch (eh->id) {
 	case PROD_I3_ETHERLAN600:
 	case PROD_I3_ETHERLAN600A:
 		addr = dev->base_addr + EN0_RCNTHI;
@@ -124,14 +173,13 @@
 		break;
 
 	case PROD_I3_ETHERLAN500:
-		addr = dev->rmem_start;
-
 		switch (dev->if_port) {
 		case IF_PORT_10BASE2:
-			outb(inb(addr) & ~ETHERH_CP_IF, addr);
+			etherh_clr_ctrl(eh, ETHERH_CP_IF);
 			break;
+
 		case IF_PORT_10BASET:
-			outb(inb(addr) | ETHERH_CP_IF, addr);
+			etherh_set_ctrl(eh, ETHERH_CP_IF);
 			break;
 		}
 		break;
@@ -147,9 +195,10 @@
 etherh_getifstat(struct net_device *dev)
 {
 	struct ei_device *ei_local = (struct ei_device *) dev->priv;
+	struct etherh_priv *eh = (struct etherh_priv *)dev->rmem_start;
 	int stat = 0;
 
-	switch (dev->mem_end) {
+	switch (eh->id) {
 	case PROD_I3_ETHERLAN600:
 	case PROD_I3_ETHERLAN600A:
 		switch (dev->if_port) {
@@ -168,7 +217,7 @@
 			stat = 1;
 			break;
 		case IF_PORT_10BASET:
-			stat = inb(dev->rmem_start) & ETHERH_CP_HEARTBEAT;
+			stat = etherh_get_stat(eh) & ETHERH_CP_HEARTBEAT;
 			break;
 		}
 		break;
@@ -251,7 +300,13 @@
 		return;
 	}
 
-	ei_local->dmaing |= 1;
+	/*
+	 * Make sure we have a round number of bytes if we're in word mode.
+	 */
+	if (count & 1 && ei_local->word16)
+		count++;
+
+	ei_local->dmaing = 1;
 
 	addr = dev->base_addr;
 	dma_addr = dev->mem_start;
@@ -291,7 +346,7 @@
 		}
 
 	outb (ENISR_RDC, addr + EN0_ISR);
-	ei_local->dmaing &= ~1;
+	ei_local->dmaing = 0;
 }
 
 /*
@@ -311,7 +366,7 @@
 		return;
 	}
 
-	ei_local->dmaing |= 1;
+	ei_local->dmaing = 1;
 
 	addr = dev->base_addr;
 	dma_addr = dev->mem_start;
@@ -332,7 +387,7 @@
 		insb (dma_addr, buf, count);
 
 	outb (ENISR_RDC, addr + EN0_ISR);
-	ei_local->dmaing &= ~1;
+	ei_local->dmaing = 0;
 }
 
 /*
@@ -351,7 +406,7 @@
 		return;
 	}
 
-	ei_local->dmaing |= 1;
+	ei_local->dmaing = 1;
 
 	addr = dev->base_addr;
 	dma_addr = dev->mem_start;
@@ -369,7 +424,7 @@
 		insb (dma_addr, hdr, sizeof (*hdr));
 
 	outb (ENISR_RDC, addr + EN0_ISR);
-	ei_local->dmaing &= ~1;
+	ei_local->dmaing = 0;
 }
 
 /*
@@ -385,6 +440,12 @@
 {
 	struct ei_device *ei_local = (struct ei_device *) dev->priv;
 
+	if (!is_valid_ether_addr(dev->dev_addr)) {
+		printk(KERN_WARNING "%s: invalid ethernet address\n",
+			dev->name);
+		return -EINVAL;
+	}
+
 	if (request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))
 		return -EAGAIN;
 
@@ -427,22 +488,22 @@
 	return 0;
 }
 
-static void etherh_irq_enable(ecard_t *ec, int irqnr)
+static int
+etherh_set_mac_address(struct net_device *dev, void *p)
 {
-	unsigned int ctrl_addr = (unsigned int)ec->irq_data;
-	outb(inb(ctrl_addr) | ETHERH_CP_IE, ctrl_addr);
-}
+	struct sockaddr *addr = p;
 
-static void etherh_irq_disable(ecard_t *ec, int irqnr)
-{
-	unsigned int ctrl_addr = (unsigned int)ec->irq_data;
-	outb(inb(ctrl_addr) & ~ETHERH_CP_IE, ctrl_addr);
-}
+	if (netif_running(dev))
+		return -EBUSY;
 
-static expansioncard_ops_t etherh_ops = {
-	irqenable:	etherh_irq_enable,
-	irqdisable:	etherh_irq_disable,
-};
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	/*
+	 * We'll set the MAC address on the chip when we open it.
+	 */
+
+	return 0;
+}
 
 /*
  * Initialisation
@@ -460,11 +521,13 @@
  * Read the ethernet address string from the on board rom.
  * This is an ascii string...
  */
-static int __init etherh_addr(char *addr, struct expansion_card *ec)
+static void __init etherh_addr(char *addr, struct expansion_card *ec)
 {
 	struct in_chunk_dir cd;
 	char *s;
 	
+	memset(addr, 0, 6);
+
 	if (ecard_readchunk(&cd, ec, 0xf5, 0) && (s = strchr(cd.d.string, '('))) {
 		int i;
 		for (i = 0; i < 6; i++) {
@@ -472,31 +535,25 @@
 			if (*s != (i == 5? ')' : ':'))
 				break;
 		}
-		if (i == 6)
-			return 0;
 	}
-	return -ENODEV;
 }
 
 /*
  * Create an ethernet address from the system serial number.
  */
-static int __init etherm_addr(char *addr)
+static void __init etherm_addr(char *addr)
 {
 	unsigned int serial;
 
-	if (system_serial_low == 0 && system_serial_high == 0)
-		return -ENODEV;
-
 	serial = system_serial_low | system_serial_high;
-
-	addr[0] = 0;
-	addr[1] = 0;
-	addr[2] = 0xa4;
-	addr[3] = 0x10 + (serial >> 24);
-	addr[4] = serial >> 16;
-	addr[5] = serial >> 8;
-	return 0;
+	if (serial != 0) {
+		addr[0] = 0;
+		addr[1] = 0;
+		addr[2] = 0xa4;
+		addr[3] = 0x10 + (serial >> 24);
+		addr[4] = serial >> 16;
+		addr[5] = serial >> 8;
+	}
 }
 
 static u32 etherh_regoffsets[16];
@@ -506,6 +563,7 @@
 {
 	struct ei_device *ei_local;
 	struct net_device *dev;
+	struct etherh_priv *eh;
 	const char *dev_type;
 	int i, size;
 
@@ -517,42 +575,50 @@
 	if (!dev)
 		goto out;
 
+	eh = kmalloc(sizeof(struct etherh_priv), GFP_KERNEL);
+	if (!eh)
+		goto out_nopriv;
+
 	SET_MODULE_OWNER(dev);
 
-	dev->open	= etherh_open;
-	dev->stop	= etherh_close;
-	dev->set_config	= etherh_set_config;
-	dev->irq	= ec->irq;
-	dev->base_addr	= ecard_address(ec, ECARD_MEMC, 0);
-	dev->mem_end	= ec->cid.product;
+	dev->open		= etherh_open;
+	dev->stop		= etherh_close;
+	dev->set_mac_address	= etherh_set_mac_address;
+	dev->set_config		= etherh_set_config;
+	dev->irq		= ec->irq;
+	dev->base_addr		= ecard_address(ec, ECARD_MEMC, 0);
+	dev->rmem_start		= (unsigned long)eh;
+
+	/*
+	 * IRQ and control port handling
+	 */
 	ec->ops		= &etherh_ops;
+	ec->irq_data	= eh;
+	eh->ctrl	= 0;
+	eh->id		= ec->cid.product;
 
 	switch (ec->cid.product) {
 	case PROD_ANT_ETHERM:
-		if (etherm_addr(dev->dev_addr))
-			goto free;
+		etherm_addr(dev->dev_addr);
 		dev->base_addr += ETHERM_NS8390;
 		dev->mem_start  = dev->base_addr + ETHERM_DATAPORT;
-		ec->irq_data    = (void *)(dev->base_addr + ETHERM_CTRLPORT);
+		eh->ctrl_port   = dev->base_addr + ETHERM_CTRLPORT;
 		break;
 
 	case PROD_I3_ETHERLAN500:
-		if (etherh_addr(dev->dev_addr, ec))
-			goto free;
+		etherh_addr(dev->dev_addr, ec);
 		dev->base_addr += ETHERH500_NS8390;
 		dev->mem_start  = dev->base_addr + ETHERH500_DATAPORT;
-		dev->rmem_start = (unsigned long)
-		ec->irq_data    = (void *)ecard_address (ec, ECARD_IOC, ECARD_FAST)
+		eh->ctrl_port   = ecard_address (ec, ECARD_IOC, ECARD_FAST)
 				  + ETHERH500_CTRLPORT;
 		break;
 
 	case PROD_I3_ETHERLAN600:
 	case PROD_I3_ETHERLAN600A:
-		if (etherh_addr(dev->dev_addr, ec))
-			goto free;
+		etherh_addr(dev->dev_addr, ec);
 		dev->base_addr += ETHERH600_NS8390;
-		dev->mem_start = dev->base_addr + ETHERH600_DATAPORT;
-		ec->irq_data   = (void *)(dev->base_addr + ETHERH600_CTRLPORT);
+		dev->mem_start  = dev->base_addr + ETHERH600_DATAPORT;
+		eh->ctrl_port   = dev->base_addr + ETHERH600_CTRLPORT;
 		break;
 
 	default:
@@ -572,6 +638,12 @@
 		goto release;
 
 	/*
+	 * If we're in the NIC slot, make sure the IRQ is enabled
+	 */
+	if (dev->irq == 11)
+		etherh_set_ctrl(eh, ETHERH_CP_IE);
+
+	/*
 	 * Unfortunately, ethdev_init eventually calls
 	 * ether_setup, which re-writes dev->flags.
 	 */
@@ -636,6 +708,8 @@
 release:
 	release_region(dev->base_addr, 16);
 free:
+	kfree(eh);
+out_nopriv:
 	unregister_netdev(dev);
 	kfree(dev);
 out:
@@ -696,6 +770,7 @@
 		}
 		if (e_card[i]) {
 			e_card[i]->ops = NULL;
+			kfree(e_card[i]->irq_data);
 			ecard_release(e_card[i]);
 			e_card[i] = NULL;
 		}
diff -urN linux-2.4.22-pre2/drivers/acorn/scsi/arxescsi.c linux-2.4.22-pre3/drivers/acorn/scsi/arxescsi.c
--- linux-2.4.22-pre2/drivers/acorn/scsi/arxescsi.c	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/scsi/arxescsi.c	2003-07-05 18:09:50.000000000 -0700
@@ -37,16 +37,22 @@
 
 #include "../../scsi/sd.h"
 #include "../../scsi/hosts.h"
-#include "arxescsi.h"
+#include <scsi/scsicam.h>
 #include "fas216.h"
+#include "scsi.h"
 
-/* Hmm - this should go somewhere else */
-#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE)
+struct arxescsi_info {
+	FAS216_Info		info;
+	struct expansion_card	*ec;
+	unsigned int		dmaarea;	/* Pseudo DMA area	*/
+};
 
-/* Configuration */
-#define ARXESCSI_XTALFREQ		24
-#define ARXESCSI_ASYNC_PERIOD		200
-#define ARXESCSI_SYNC_DEPTH		0
+#define DMADATA_OFFSET	(0x200/4)
+
+#define DMASTAT_OFFSET	(0x600/4)
+#define DMASTAT_DRQ	(1 << 0)
+
+#define CSTATUS_IRQ	(1 << 0)
 
 /*
  * List of devices that the driver will recognise
@@ -56,11 +62,7 @@
 /*
  * Version
  */
-#define VER_MAJOR	0
-#define VER_MINOR	1
-#define VER_PATCH	1
-
-static struct expansion_card *ecs[MAX_ECARDS];
+#define VERSION "1.10 (22/01/2003 2.4.19-rmk5)"
 
 /*
  * Function: int arxescsi_dma_setup(host, SCpnt, direction, min_type)
@@ -157,7 +159,7 @@
 void arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
 			fasdmadir_t direction, int transfer)
 {
-	ARXEScsi_Info *info = (ARXEScsi_Info *)host->hostdata;
+	struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata;
 	unsigned int length, io, error=0;
 	unsigned char *addr;
 
@@ -182,7 +184,7 @@
 				if (getb(io, 4) & STAT_INT)
 					break;
 	 
-				if (!(getb(io, 48) & CSTATUS_IRQ))
+				if (!(getb(io, 48) & DMASTAT_DRQ))
 					continue;
 
 				word = *addr | *(addr + 1) << 8;
@@ -205,7 +207,7 @@
 					break;
 				}
 	    
-				if (!(getb(io, 48) & CSTATUS_IRQ))
+				if (!(getb(io, 48) & DMASTAT_DRQ))
 					continue;
 
 				insw(info->dmaarea, addr, 256 >> 1);
@@ -221,7 +223,7 @@
 				if (getb(io, 4) & STAT_INT)
 					break;
 
-				if (!(getb(io, 48) & CSTATUS_IRQ))
+				if (!(getb(io, 48) & DMASTAT_DRQ))
 					continue;
 
 				word = getw(io, 16);
@@ -248,96 +250,6 @@
 }
 
 /*
- * Function: int arxescsi_detect(Scsi_Host_Template * tpnt)
- * Purpose : initialises ARXE SCSI driver
- * Params  : tpnt - template for this SCSI adapter
- * Returns : >0 if host found, 0 otherwise.
- */
-int arxescsi_detect(Scsi_Host_Template *tpnt)
-{
-	static const card_ids arxescsi_cids[] = { ARXESCSI_LIST, { 0xffff, 0xffff} };
-	int count = 0;
-	struct Scsi_Host *host;
-  
-	tpnt->proc_name = "arxescsi";
-	memset(ecs, 0, sizeof (ecs));
-
-	ecard_startfind();
-
-	while (1) {
-	    	ARXEScsi_Info *info;
-
-		ecs[count] = ecard_find(0, arxescsi_cids);
-		if (!ecs[count])
-			break;
-
-		ecard_claim(ecs[count]);
-		
-		host = scsi_register(tpnt, sizeof (ARXEScsi_Info));
-		if (!host) {
-			ecard_release(ecs[count]);
-			break;
-		}
-
-		host->io_port = ecard_address(ecs[count], ECARD_MEMC, 0) + 0x0800;
-		host->irq = NO_IRQ;
-		host->dma_channel = NO_DMA;
-		host->can_queue = 0; /* no command queueing */
-		info = (ARXEScsi_Info *)host->hostdata;
-
-		info->info.scsi.io_port		= host->io_port;
-		info->info.scsi.irq		= host->irq;
-		info->info.scsi.io_shift	= 3;
-		info->info.ifcfg.clockrate	= ARXESCSI_XTALFREQ;
-		info->info.ifcfg.select_timeout = 255;
-		info->info.ifcfg.asyncperiod	= ARXESCSI_ASYNC_PERIOD;
-		info->info.ifcfg.sync_max_depth	= ARXESCSI_SYNC_DEPTH;
-		info->info.ifcfg.cntl3		= CNTL3_FASTSCSI | CNTL3_FASTCLK;
-		info->info.ifcfg.disconnect_ok	= 0;
-		info->info.ifcfg.wide_max_size	= 0;
-		info->info.dma.setup		= arxescsi_dma_setup;
-		info->info.dma.pseudo		= arxescsi_dma_pseudo;
-		info->info.dma.stop		= arxescsi_dma_stop;
-		info->dmaarea			= host->io_port + 128;
-		info->cstatus			= host->io_port + 384;
-		
-		ecs[count]->irqaddr = (unsigned char *)BUS_ADDR(host->io_port);
-		ecs[count]->irqmask = CSTATUS_IRQ;
-
-		request_region(host->io_port      , 120, "arxescsi-fas");
-		request_region(host->io_port + 128, 384, "arxescsi-dma");
-
-		printk("scsi%d: Has no interrupts - using polling mode\n",
-		       host->host_no);
-
-		fas216_init(host);
-		++count;
-	}
-	return count;
-}
-
-/*
- * Function: int arxescsi_release(struct Scsi_Host * host)
- * Purpose : releases all resources used by this adapter
- * Params  : host - driver host structure to return info for.
- * Returns : nothing
- */
-int arxescsi_release(struct Scsi_Host *host)
-{
-	int i;
-
-	fas216_release(host);
-
-	release_region(host->io_port, 120);
-	release_region(host->io_port + 128, 384);
-
-	for (i = 0; i < MAX_ECARDS; i++)
-		if (ecs[i] && host->io_port == (ecard_address(ecs[i], ECARD_MEMC, 0) + 0x0800))
-			ecard_release(ecs[i]);
-	return 0;
-}
-
-/*
  * Function: const char *arxescsi_info(struct Scsi_Host * host)
  * Purpose : returns a descriptive string about this interface,
  * Params  : host - driver host structure to return info for.
@@ -345,13 +257,12 @@
  */
 const char *arxescsi_info(struct Scsi_Host *host)
 {
-	ARXEScsi_Info *info = (ARXEScsi_Info *)host->hostdata;
-	static char string[100], *p;
+	struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata;
+	static char string[150];
 
-	p = string;
-	p += sprintf(p, "%s ", host->hostt->name);
-	p += fas216_info(&info->info, p);
-	p += sprintf(p, "v%d.%d.%d", VER_MAJOR, VER_MINOR, VER_PATCH);
+	sprintf(string, "%s (%s) in slot %d v%s",
+		host->hostt->name, info->info.scsi.type, info->ec->slot_no,
+		VERSION);
 
 	return string;
 }
@@ -374,26 +285,20 @@
 			    int length, int host_no, int inout)
 {
 	int pos, begin;
-	struct Scsi_Host *host = scsi_hostlist;
-	ARXEScsi_Info *info;
+	struct Scsi_Host *host;
+	struct arxescsi_info *info;
 	Scsi_Device *scd;
 
-	while (host) {
-		if (host->host_no == host_no)
-			break;
-		host = host->next;
-	}
+	host = scsi_host_hn_get(host_no);
 	if (!host)
 		return 0;
 
-	info = (ARXEScsi_Info *)host->hostdata;
+	info = (struct arxescsi_info *)host->hostdata;
 	if (inout == 1)
 		return -EINVAL;
 
 	begin = 0;
-	pos = sprintf(buffer,
-			"ARXE 16-bit SCSI driver version %d.%d.%d\n",
-			VER_MAJOR, VER_MINOR, VER_PATCH);
+	pos = sprintf(buffer, "ARXE 16-bit SCSI driver v%s\n", VERSION);
 	pos += fas216_print_host(&info->info, buffer + pos);
 	pos += fas216_print_stats(&info->info, buffer + pos);
 
@@ -418,11 +323,156 @@
 	return pos;
 }
 
-static Scsi_Host_Template arxescsi_template = ARXEScsi;
+static int arxescsi_probe(struct expansion_card *ec);
+
+/*
+ * Function: int arxescsi_detect(Scsi_Host_Template * tpnt)
+ * Purpose : initialises ARXE SCSI driver
+ * Params  : tpnt - template for this SCSI adapter
+ * Returns : >0 if host found, 0 otherwise.
+ */
+static int arxescsi_detect(Scsi_Host_Template *tpnt)
+{
+	static const card_ids arxescsi_cids[] = { ARXESCSI_LIST, { 0xffff, 0xffff} };
+	int count = 0, ret;
+  
+	ecard_startfind();
+
+	while (1) {
+		struct expansion_card *ec;
+		ec = ecard_find(0, arxescsi_cids);
+		if (!ec)
+			break;
+
+		ecard_claim(ec);
+		ret = arxescsi_probe(ec);
+		if (ret) {
+			ecard_release(ec);
+			break;
+		}
+		++count;
+	}
+	return count;
+}
+
+static void arxescsi_remove(struct Scsi_Host *host);
+
+/*
+ * Function: int arxescsi_release(struct Scsi_Host * host)
+ * Purpose : releases all resources used by this adapter
+ * Params  : host - driver host structure to return info for.
+ * Returns : nothing
+ */
+static int arxescsi_release(struct Scsi_Host *host)
+{
+	arxescsi_remove(host);
+	return 0;
+}
+
+static Scsi_Host_Template arxescsi_template = {
+	.module				= THIS_MODULE,
+	.proc_info			= arxescsi_proc_info,
+	.name				= "ARXE SCSI card",
+	.detect				= arxescsi_detect,
+	.release			= arxescsi_release,
+	.info				= arxescsi_info,
+	.bios_param			= scsicam_bios_param,
+	.command			= fas216_command,
+	.queuecommand			= fas216_queue_command,
+	.eh_host_reset_handler		= fas216_eh_host_reset,
+	.eh_bus_reset_handler		= fas216_eh_bus_reset,
+	.eh_device_reset_handler	= fas216_eh_device_reset,
+	.eh_abort_handler		= fas216_eh_abort,
+	.use_new_eh_code		= 1,
+
+	.can_queue			= 0,
+	.this_id			= 7,
+	.sg_tablesize			= SG_ALL,
+	.cmd_per_lun			= 1,
+	.use_clustering			= DISABLE_CLUSTERING,
+	.proc_name			= "arxescsi",
+};
+
+static int
+arxescsi_probe(struct expansion_card *ec)
+{
+	struct Scsi_Host *host;
+	struct arxescsi_info *info;
+	unsigned long base;
+	int ret;
+
+	base = ecard_address(ec, ECARD_MEMC, 0) + 0x0800;
+
+	if (!request_region(base, 512, "arxescsi")) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	host = scsi_register(&arxescsi_template, sizeof(struct arxescsi_info));
+	if (!host) {
+		ret = -ENOMEM;
+		goto out_region;
+	}
+
+	host->io_port = base;
+	host->irq = NO_IRQ;
+	host->dma_channel = NO_DMA;
+
+	info = (struct arxescsi_info *)host->hostdata;
+	info->ec = ec;
+	info->dmaarea = base + DMADATA_OFFSET;
+
+	info->info.scsi.io_port		= host->io_port;
+	info->info.scsi.irq		= NO_IRQ;
+	info->info.scsi.io_shift	= 3;
+	info->info.ifcfg.clockrate	= 24; /* MHz */
+	info->info.ifcfg.select_timeout = 255;
+	info->info.ifcfg.asyncperiod	= 200; /* ns */
+	info->info.ifcfg.sync_max_depth	= 0;
+	info->info.ifcfg.cntl3		= CNTL3_FASTSCSI | CNTL3_FASTCLK;
+	info->info.ifcfg.disconnect_ok	= 0;
+	info->info.ifcfg.wide_max_size	= 0;
+	info->info.ifcfg.capabilities	= FASCAP_PSEUDODMA;
+	info->info.dma.setup		= arxescsi_dma_setup;
+	info->info.dma.pseudo		= arxescsi_dma_pseudo;
+	info->info.dma.stop		= arxescsi_dma_stop;
+
+	ec->irqaddr = (unsigned char *)ioaddr(base);
+	ec->irqmask = CSTATUS_IRQ;
+
+	ret = fas216_init(host);
+	if (ret)
+		goto out_unregister;
+
+	ret = fas216_add(host);
+	if (ret == 0)
+		goto out;
+
+	fas216_release(host);
+ out_unregister:
+	scsi_unregister(host);
+ out_region:
+	release_region(base, 512);
+ out:
+	return ret;
+}
+
+static void arxescsi_remove(struct Scsi_Host *host)
+{
+	struct arxescsi_info *info;
+
+	info = (struct arxescsi_info *)host->hostdata;
+
+	fas216_remove(host);
+
+	release_region(host->io_port, 512);
+
+	ecard_release(info->ec);
+	fas216_release(host);
+}
 
 static int __init init_arxe_scsi_driver(void)
 {
-        arxescsi_template.module = THIS_MODULE;
 	scsi_register_module(MODULE_SCSI_HA, &arxescsi_template);
 	if (arxescsi_template.present)
 		return 0;
diff -urN linux-2.4.22-pre2/drivers/acorn/scsi/arxescsi.h linux-2.4.22-pre3/drivers/acorn/scsi/arxescsi.h
--- linux-2.4.22-pre2/drivers/acorn/scsi/arxescsi.h	2000-05-12 11:21:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/scsi/arxescsi.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,82 +0,0 @@
-/*
- * ARXE SCSI card driver
- *
- * Copyright (C) 1997-2000 Russell King
- *
- * Changes to support ARXE 16-bit SCSI card by Stefan Hanske
- */
-#ifndef ARXE_SCSI_H
-#define ARXE_SCSI_H
-
-#define MANU_ARXE 	0x0041
-#define PROD_ARXE_SCSI	0x00be
-
-extern int arxescsi_detect (Scsi_Host_Template *);
-extern int arxescsi_release (struct Scsi_Host *);
-extern const char *arxescsi_info (struct Scsi_Host *);
-extern int arxescsi_proc_info (char *buffer, char **start, off_t offset,
-				int length, int hostno, int inout);
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-
-#ifndef CAN_QUEUE
-/*
- * Default queue size
- */
-#define CAN_QUEUE	1
-#endif
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN	1
-#endif
-
-#ifndef SCSI_ID
-/*
- * Default SCSI host ID
- */
-#define SCSI_ID		7
-#endif
-
-#include <scsi/scsicam.h>
-
-#include "fas216.h"
-
-#define ARXEScsi {					\
-proc_info:			arxescsi_proc_info,	\
-name:				"ARXE SCSI card",	\
-detect:				arxescsi_detect,	\
-release:			arxescsi_release,	\
-info:				arxescsi_info,		\
-bios_param:			scsicam_bios_param,	\
-can_queue:			CAN_QUEUE,		\
-this_id:			SCSI_ID,		\
-sg_tablesize:			SG_ALL,			\
-cmd_per_lun:			CMD_PER_LUN,		\
-use_clustering:			DISABLE_CLUSTERING,	\
-command:			fas216_command,		\
-queuecommand:			fas216_queue_command,	\
-eh_host_reset_handler:		fas216_eh_host_reset,	\
-eh_bus_reset_handler:		fas216_eh_bus_reset,	\
-eh_device_reset_handler:	fas216_eh_device_reset,	\
-eh_abort_handler:		fas216_eh_abort,	\
-use_new_eh_code:		1			\
-	}
-
-#ifndef HOSTS_C
-
-typedef struct {
-    FAS216_Info info;
-
-    /* other info... */
-    unsigned int	cstatus;	/* card status register	*/
-    unsigned int	dmaarea;	/* Pseudo DMA area	*/
-} ARXEScsi_Info;
-
-#define CSTATUS_IRQ	(1 << 0)
-#define CSTATUS_DRQ	(1 << 0)
-
-#endif /* HOSTS_C */
-
-#endif /* ARXE_SCSI_H */
diff -urN linux-2.4.22-pre2/drivers/acorn/scsi/cumana_2.c linux-2.4.22-pre3/drivers/acorn/scsi/cumana_2.c
--- linux-2.4.22-pre2/drivers/acorn/scsi/cumana_2.c	2001-11-04 09:31:57.000000000 -0800
+++ linux-2.4.22-pre3/drivers/acorn/scsi/cumana_2.c	2003-07-05 18:09:50.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/drivers/acorn/scsi/cumana_2.c
  *
- *  Copyright (C) 1997-2000 Russell King
+ *  Copyright (C) 1997-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -23,8 +23,6 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/unistd.h>
-#include <linux/stat.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -38,14 +36,10 @@
 #include "../../scsi/sd.h"
 #include "../../scsi/hosts.h"
 #include "fas216.h"
+#include "scsi.h"
 
 #include <scsi/scsicam.h>
 
-/* Configuration */
-#define CUMANASCSI2_XTALFREQ		40
-#define CUMANASCSI2_ASYNC_PERIOD	200
-#define CUMANASCSI2_SYNC_DEPTH		7
-
 /*
  * List of devices that the driver will recognise
  */
@@ -76,11 +70,7 @@
 /*
  * Version
  */
-#define VER_MAJOR	0
-#define VER_MINOR	0
-#define VER_PATCH	4
-
-static struct expansion_card *ecs[MAX_ECARDS];
+#define VERSION "1.00 (13/11/2002 2.4.19-rmk5)"
 
 /*
  * Use term=0,1,0,0,0 to turn terminators on/off
@@ -89,16 +79,16 @@
 
 #define NR_SG	256
 
-typedef struct {
-	FAS216_Info info;
-
-	/* other info... */
-	unsigned int	status;		/* card status register	*/
-	unsigned int	alatch;		/* Control register	*/
-	unsigned int	terms;		/* Terminator state	*/
-	unsigned int	dmaarea;	/* Pseudo DMA area	*/
-	struct scatterlist sg[NR_SG];	/* Scatter DMA list	*/
-} CumanaScsi2_Info;
+struct cumanascsi2_info {
+	FAS216_Info		info;
+	struct expansion_card	*ec;
+
+	unsigned int		status;		/* card status register	*/
+	unsigned int		alatch;		/* Control register	*/
+	unsigned int		terms;		/* Terminator state	*/
+	unsigned int		dmaarea;	/* Pseudo DMA area	*/
+	struct scatterlist	sg[NR_SG];	/* Scatter DMA list	*/
+};
 
 #define CSTATUS_IRQ	(1 << 0)
 #define CSTATUS_DRQ	(1 << 1)
@@ -128,12 +118,8 @@
 }
 
 static const expansioncard_ops_t cumanascsi_2_ops = {
-	cumanascsi_2_irqenable,
-	cumanascsi_2_irqdisable,
-	NULL,
-	NULL,
-	NULL,
-	NULL
+	.irqenable	= cumanascsi_2_irqenable,
+	.irqdisable	= cumanascsi_2_irqdisable,
 };
 
 /* Prototype: void cumanascsi_2_terminator_ctl(host, on_off)
@@ -144,7 +130,7 @@
 static void
 cumanascsi_2_terminator_ctl(struct Scsi_Host *host, int on_off)
 {
-	CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata;
+	struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
 
 	if (on_off) {
 		info->terms = 1;
@@ -164,9 +150,7 @@
 static void
 cumanascsi_2_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
-
-	fas216_intr(host);
+	fas216_intr(dev_id);
 }
 
 /* Prototype: fasdmatype_t cumanascsi_2_dma_setup(host, SCpnt, direction, min_type)
@@ -181,36 +165,30 @@
 cumanascsi_2_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
 		       fasdmadir_t direction, fasdmatype_t min_type)
 {
-	CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata;
+	struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
 	int dmach = host->dma_channel;
 
 	outb(ALATCH_DIS_DMA, info->alatch);
 
 	if (dmach != NO_DMA &&
 	    (min_type == fasdma_real_all || SCp->this_residual >= 512)) {
-		int bufs = SCp->buffers_residual;
-		int pci_dir, dma_dir, alatch_dir;
+		int bufs, map_dir, dma_dir, alatch_dir;
 
-		if (bufs)
-			memcpy(info->sg + 1, SCp->buffer + 1,
-				sizeof(struct scatterlist) * bufs);
-		info->sg[0].address = SCp->ptr;
-		info->sg[0].page    = NULL;
-		info->sg[0].length  = SCp->this_residual;
+		bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG);
 
 		if (direction == DMA_OUT)
-			pci_dir = PCI_DMA_TODEVICE,
+			map_dir = PCI_DMA_TODEVICE,
 			dma_dir = DMA_MODE_WRITE,
 			alatch_dir = ALATCH_DMA_OUT;
 		else
-			pci_dir = PCI_DMA_FROMDEVICE,
+			map_dir = PCI_DMA_FROMDEVICE,
 			dma_dir = DMA_MODE_READ,
 			alatch_dir = ALATCH_DMA_IN;
 
-		pci_map_sg(NULL, info->sg, bufs + 1, pci_dir);
+		pci_map_sg(NULL, info->sg, bufs, map_dir);
 
 		disable_dma(dmach);
-		set_dma_sg(dmach, info->sg, bufs + 1);
+		set_dma_sg(dmach, info->sg, bufs);
 		outb(alatch_dir, info->alatch);
 		set_dma_mode(dmach, dma_dir);
 		enable_dma(dmach);
@@ -238,7 +216,7 @@
 cumanascsi_2_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
 			fasdmadir_t direction, int transfer)
 {
-	CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata;
+	struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
 	unsigned int length;
 	unsigned char *addr;
 
@@ -271,7 +249,7 @@
 				unsigned int status = inb(info->status);
 
 				if (status & STATUS_INT)
-					goto end;
+					return;
 	    
 				if (!(status & STATUS_DRQ))
 					continue;
@@ -287,7 +265,7 @@
 			unsigned int status = inb(info->status);
 
 			if (status & STATUS_INT)
-				goto end;
+				return;
 
 			if (!(status & STATUS_DRQ))
 				continue;
@@ -300,8 +278,6 @@
 			}
 		}
 	}
-
-end:
 }
 
 /* Prototype: int cumanascsi_2_dma_stop(host, SCpnt)
@@ -312,124 +288,13 @@
 static void
 cumanascsi_2_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp)
 {
-	CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata;
+	struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
 	if (host->dma_channel != NO_DMA) {
 		outb(ALATCH_DIS_DMA, info->alatch);
 		disable_dma(host->dma_channel);
 	}
 }
 
-/* Prototype: int cumanascsi_2_detect(Scsi_Host_Template * tpnt)
- * Purpose  : initialises Cumana SCSI 2 driver
- * Params   : tpnt - template for this SCSI adapter
- * Returns  : >0 if host found, 0 otherwise.
- */
-int
-cumanascsi_2_detect(Scsi_Host_Template *tpnt)
-{
-	static const card_ids cumanascsi_2_cids[] =
-			{ CUMANASCSI2_LIST, { 0xffff, 0xffff} };
-	int count = 0;
-	struct Scsi_Host *host;
-  
-	tpnt->proc_name = "cumanascs2";
-	memset(ecs, 0, sizeof (ecs));
-
-	ecard_startfind();
-
-	while (1) {
-	    	CumanaScsi2_Info *info;
-
-		ecs[count] = ecard_find(0, cumanascsi_2_cids);
-		if (!ecs[count])
-			break;
-
-		ecard_claim(ecs[count]);
-
-		host = scsi_register(tpnt, sizeof (CumanaScsi2_Info));
-		if (!host) {
-			ecard_release(ecs[count]);
-			break;
-		}
-
-		host->io_port = ecard_address(ecs[count], ECARD_MEMC, 0);
-		host->irq = ecs[count]->irq;
-		host->dma_channel = ecs[count]->dma;
-		info = (CumanaScsi2_Info *)host->hostdata;
-
-		info->terms			= term[count] ? 1 : 0;
-		cumanascsi_2_terminator_ctl(host, info->terms);
-
-		info->info.scsi.io_port		= host->io_port + CUMANASCSI2_FAS216_OFFSET;
-		info->info.scsi.io_shift	= CUMANASCSI2_FAS216_SHIFT;
-		info->info.scsi.irq		= host->irq;
-		info->info.ifcfg.clockrate	= CUMANASCSI2_XTALFREQ;
-		info->info.ifcfg.select_timeout	= 255;
-		info->info.ifcfg.asyncperiod	= CUMANASCSI2_ASYNC_PERIOD;
-		info->info.ifcfg.sync_max_depth	= CUMANASCSI2_SYNC_DEPTH;
-		info->info.ifcfg.cntl3		= CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
-		info->info.ifcfg.disconnect_ok	= 1;
-		info->info.ifcfg.wide_max_size	= 0;
-		info->info.dma.setup		= cumanascsi_2_dma_setup;
-		info->info.dma.pseudo		= cumanascsi_2_dma_pseudo;
-		info->info.dma.stop		= cumanascsi_2_dma_stop;
-		info->dmaarea			= host->io_port + CUMANASCSI2_PSEUDODMA;
-		info->status			= host->io_port + CUMANASCSI2_STATUS;
-		info->alatch			= host->io_port + CUMANASCSI2_ALATCH;
-
-		ecs[count]->irqaddr	= (unsigned char *)ioaddr(info->status);
-		ecs[count]->irqmask	= STATUS_INT;
-		ecs[count]->irq_data	= (void *)info->alatch;
-		ecs[count]->ops		= (expansioncard_ops_t *)&cumanascsi_2_ops;
-
-		request_region(host->io_port + CUMANASCSI2_FAS216_OFFSET,
-			       16 << CUMANASCSI2_FAS216_SHIFT, "cumanascsi2-fas");
-
-		if (host->irq != NO_IRQ &&
-		    request_irq(host->irq, cumanascsi_2_intr,
-				SA_INTERRUPT, "cumanascsi2", host)) {
-			printk("scsi%d: IRQ%d not free, interrupts disabled\n",
-			       host->host_no, host->irq);
-			host->irq = NO_IRQ;
-			info->info.scsi.irq = NO_IRQ;
-		}
-
-		if (host->dma_channel != NO_DMA &&
-		    request_dma(host->dma_channel, "cumanascsi2")) {
-			printk("scsi%d: DMA%d not free, DMA disabled\n",
-			       host->host_no, host->dma_channel);
-			host->dma_channel = NO_DMA;
-		}
-
-		fas216_init(host);
-		++count;
-	}
-	return count;
-}
-
-/* Prototype: int cumanascsi_2_release(struct Scsi_Host * host)
- * Purpose  : releases all resources used by this adapter
- * Params   : host - driver host structure to return info for.
- */
-int cumanascsi_2_release(struct Scsi_Host *host)
-{
-	int i;
-
-	fas216_release(host);
-
-	if (host->irq != NO_IRQ)
-		free_irq(host->irq, host);
-	if (host->dma_channel != NO_DMA)
-		free_dma(host->dma_channel);
-	release_region(host->io_port + CUMANASCSI2_FAS216_OFFSET,
-		       16 << CUMANASCSI2_FAS216_SHIFT);
-
-	for (i = 0; i < MAX_ECARDS; i++)
-		if (ecs[i] && host->io_port == ecard_address (ecs[i], ECARD_MEMC, 0))
-			ecard_release (ecs[i]);
-	return 0;
-}
-
 /* Prototype: const char *cumanascsi_2_info(struct Scsi_Host * host)
  * Purpose  : returns a descriptive string about this interface,
  * Params   : host - driver host structure to return info for.
@@ -437,15 +302,12 @@
  */
 const char *cumanascsi_2_info(struct Scsi_Host *host)
 {
-	CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata;
-	static char string[100], *p;
+	struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
+	static char string[150];
 
-	p = string;
-	p += sprintf(p, "%s ", host->hostt->name);
-	p += fas216_info(&info->info, p);
-	p += sprintf(p, "v%d.%d.%d terminators o%s",
-		     VER_MAJOR, VER_MINOR, VER_PATCH,
-		     info->terms ? "n" : "ff");
+	sprintf(string, "%s (%s) in slot %d v%s terminators o%s",
+		host->hostt->name, info->info.scsi.type, info->ec->slot_no,
+		VERSION, info->terms ? "n" : "ff");
 
 	return string;
 }
@@ -498,28 +360,21 @@
 			    int length, int host_no, int inout)
 {
 	int pos, begin;
-	struct Scsi_Host *host = scsi_hostlist;
-	CumanaScsi2_Info *info;
+	struct Scsi_Host *host;
+	struct cumanascsi2_info *info;
 	Scsi_Device *scd;
 
-	while (host) {
-		if (host->host_no == host_no)
-			break;
-		host = host->next;
-	}
+	host = scsi_host_hn_get(host_no);
 	if (!host)
 		return 0;
 
 	if (inout == 1)
 		return cumanascsi_2_set_proc_info(host, buffer, length);
 
-	info = (CumanaScsi2_Info *)host->hostdata;
+	info = (struct cumanascsi2_info *)host->hostdata;
 
 	begin = 0;
-	pos = sprintf(buffer,
-			"Cumana SCSI II driver version %d.%d.%d\n",
-			VER_MAJOR, VER_MINOR, VER_PATCH);
-
+	pos = sprintf(buffer, "Cumana SCSI II driver v%s\n", VERSION);
 	pos += fas216_print_host(&info->info, buffer + pos);
 	pos += sprintf(buffer + pos, "Term    : o%s\n",
 			info->terms ? "n" : "ff");
@@ -556,28 +411,194 @@
 	return pos;
 }
 
+static int cumanascsi2_probe(struct expansion_card *ec);
+
+/* Prototype: int cumanascsi_2_detect(Scsi_Host_Template * tpnt)
+ * Purpose  : initialises Cumana SCSI 2 driver
+ * Params   : tpnt - template for this SCSI adapter
+ * Returns  : >0 if host found, 0 otherwise.
+ */
+static int
+cumanascsi_2_detect(Scsi_Host_Template *tpnt)
+{
+	static const card_ids cumanascsi_2_cids[] =
+			{ CUMANASCSI2_LIST, { 0xffff, 0xffff} };
+	int count = 0, ret;
+
+	ecard_startfind();
+
+	while (1) {
+	    	struct expansion_card *ec;
+
+		ec = ecard_find(0, cumanascsi_2_cids);
+		if (!ec)
+			break;
+
+		ecard_claim(ec);
+		ret = cumanascsi2_probe(ec);
+		if (ret) {
+			ecard_release(ec);
+			break;
+		}
+
+		++count;
+	}
+	return count;
+}
+
+static void cumanascsi2_remove(struct Scsi_Host *host);
+
+/* Prototype: int cumanascsi_2_release(struct Scsi_Host * host)
+ * Purpose  : releases all resources used by this adapter
+ * Params   : host - driver host structure to return info for.
+ */
+static int cumanascsi_2_release(struct Scsi_Host *host)
+{
+	cumanascsi2_remove(host);
+	return 0;
+}
+
 static Scsi_Host_Template cumanascsi2_template = {
-	module:				THIS_MODULE,
-	proc_info:			cumanascsi_2_proc_info,
-	name:				"Cumana SCSI II",
-	detect:				cumanascsi_2_detect,
-	release:			cumanascsi_2_release,
-	info:				cumanascsi_2_info,
-	bios_param:			scsicam_bios_param,
-	can_queue:			1,
-	this_id:			7,
-	sg_tablesize:			SG_ALL,
-	cmd_per_lun:			1,
-	use_clustering:			DISABLE_CLUSTERING,
-	command:			fas216_command,
-	queuecommand:			fas216_queue_command,
-	eh_host_reset_handler:		fas216_eh_host_reset,
-	eh_bus_reset_handler:		fas216_eh_bus_reset,
-	eh_device_reset_handler:	fas216_eh_device_reset,
-	eh_abort_handler:		fas216_eh_abort,
-	use_new_eh_code:		1
+	.module				= THIS_MODULE,
+	.proc_info			= cumanascsi_2_proc_info,
+	.name				= "Cumana SCSI II",
+	.detect				= cumanascsi_2_detect,
+	.release			= cumanascsi_2_release,
+	.info				= cumanascsi_2_info,
+	.bios_param			= scsicam_bios_param,
+	.command			= fas216_command,
+	.queuecommand			= fas216_queue_command,
+	.eh_host_reset_handler		= fas216_eh_host_reset,
+	.eh_bus_reset_handler		= fas216_eh_bus_reset,
+	.eh_device_reset_handler	= fas216_eh_device_reset,
+	.eh_abort_handler		= fas216_eh_abort,
+	.use_new_eh_code		= 1,
+
+	.can_queue			= 1,
+	.this_id			= 7,
+	.sg_tablesize			= SG_ALL,
+	.cmd_per_lun			= 1,
+	.use_clustering			= DISABLE_CLUSTERING,
+	.proc_name			= "cumanascsi2",
 };
 
+static int
+cumanascsi2_probe(struct expansion_card *ec)
+{
+	struct Scsi_Host *host;
+    	struct cumanascsi2_info *info;
+    	unsigned long base;
+    	int ret;
+
+    	base = ecard_address(ec, ECARD_MEMC, 0);
+
+	if (request_region(base + CUMANASCSI2_FAS216_OFFSET,
+			   16 << CUMANASCSI2_FAS216_SHIFT, "cumanascsi2-fas")) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	host = scsi_register(&cumanascsi2_template,
+			     sizeof(struct cumanascsi2_info));
+	if (!host) {
+		ret = -ENOMEM;
+		goto out_region;
+	}
+
+	host->io_port = base;
+	host->irq = ec->irq;
+	host->dma_channel = ec->dma;
+
+	info = (struct cumanascsi2_info *)host->hostdata;
+	info->ec	= ec;
+	info->dmaarea	= base + CUMANASCSI2_PSEUDODMA;
+	info->status	= base + CUMANASCSI2_STATUS;
+	info->alatch	= base + CUMANASCSI2_ALATCH;
+
+	ec->irqaddr	= (unsigned char *)ioaddr(info->status);
+	ec->irqmask	= STATUS_INT;
+	ec->irq_data	= (void *)base + CUMANASCSI2_ALATCH;
+	ec->ops		= (expansioncard_ops_t *)&cumanascsi_2_ops;
+
+	cumanascsi_2_terminator_ctl(host, term[ec->slot_no]);
+
+	info->info.scsi.io_port		= base + CUMANASCSI2_FAS216_OFFSET;
+	info->info.scsi.io_shift	= CUMANASCSI2_FAS216_SHIFT;
+	info->info.scsi.irq		= host->irq;
+	info->info.ifcfg.clockrate	= 40; /* MHz */
+	info->info.ifcfg.select_timeout	= 255;
+	info->info.ifcfg.asyncperiod	= 200; /* ns */
+	info->info.ifcfg.sync_max_depth	= 7;
+	info->info.ifcfg.cntl3		= CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
+	info->info.ifcfg.disconnect_ok	= 1;
+	info->info.ifcfg.wide_max_size	= 0;
+	info->info.ifcfg.capabilities	= 0;
+	info->info.dma.setup		= cumanascsi_2_dma_setup;
+	info->info.dma.pseudo		= cumanascsi_2_dma_pseudo;
+	info->info.dma.stop		= cumanascsi_2_dma_stop;
+
+	ret = fas216_init(host);
+	if (ret)
+		goto out_free;
+
+	ret = request_irq(host->irq, cumanascsi_2_intr,
+			SA_INTERRUPT, "cumanascsi2", &info->info);
+	if (ret) {
+		printk("scsi%d: IRQ%d not free: %d\n",
+		       host->host_no, host->irq, ret);
+		goto out_release;
+	}
+
+	if (host->dma_channel != NO_DMA) {
+		if (request_dma(host->dma_channel, "cumanascsi2")) {
+			printk("scsi%d: DMA%d not free, using PIO\n",
+			       host->host_no, host->dma_channel);
+			host->dma_channel = NO_DMA;
+		} else {
+			set_dma_speed(host->dma_channel, 180);
+			info->info.ifcfg.capabilities |= FASCAP_DMA;
+		}
+	}
+
+	ret = fas216_add(host);
+	if (ret == 0)
+		goto out;
+
+	if (host->dma_channel != NO_DMA)
+		free_dma(host->dma_channel);
+	free_irq(host->irq, host);
+
+ out_release:
+	fas216_release(host);
+
+ out_free:
+	scsi_unregister(host);
+
+ out_region:
+	release_region(base + CUMANASCSI2_FAS216_OFFSET,
+		       16 << CUMANASCSI2_FAS216_SHIFT);
+
+ out:
+	return ret;
+}
+
+static void cumanascsi2_remove(struct Scsi_Host *host)
+{
+	struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
+
+	fas216_remove(host);
+
+	if (host->dma_channel != NO_DMA)
+		free_dma(host->dma_channel);
+	free_irq(host->irq, host);
+
+	release_region(host->io_port + CUMANASCSI2_FAS216_OFFSET,
+		       16 << CUMANASCSI2_FAS216_SHIFT);
+
+	fas216_release(host);
+	ecard_release(info->ec);
+}
+
 static int __init cumanascsi2_init(void)
 {
 	scsi_register_module(MODULE_SCSI_HA, &cumanascsi2_template);
diff -urN linux-2.4.22-pre2/drivers/acorn/scsi/eesox.c linux-2.4.22-pre3/drivers/acorn/scsi/eesox.c
--- linux-2.4.22-pre2/drivers/acorn/scsi/eesox.c	2001-11-04 09:31:57.000000000 -0800
+++ linux-2.4.22-pre3/drivers/acorn/scsi/eesox.c	2003-07-05 18:09:50.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/drivers/acorn/scsi/eesox.c
  *
- *  Copyright (C) 1997-2000 Russell King
+ *  Copyright (C) 1997-2003 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -29,8 +29,6 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/unistd.h>
-#include <linux/stat.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -44,14 +42,10 @@
 #include "../../scsi/sd.h"
 #include "../../scsi/hosts.h"
 #include "fas216.h"
+#include "scsi.h"
 
 #include <scsi/scsicam.h>
 
-/* Configuration */
-#define EESOX_XTALFREQ		40
-#define EESOX_ASYNC_PERIOD	200
-#define EESOX_SYNC_DEPTH	7
-
 /*
  * List of devices that the driver will recognise
  */
@@ -60,7 +54,7 @@
 #define EESOX_FAS216_OFFSET	0xc00
 #define EESOX_FAS216_SHIFT	3
 
-#define EESOX_STATUS		0xa00
+#define EESOX_DMASTAT		0xa00
 #define EESOX_STAT_INTR		0x01
 #define EESOX_STAT_DMA		0x02
 
@@ -69,16 +63,12 @@
 #define EESOX_TERM_ENABLE	0x02
 #define EESOX_RESET		0x01
 
-#define EESOX_DMA_OFFSET	0xe00
+#define EESOX_DMADATA		0xe00
 
 /*
  * Version
  */
-#define VER_MAJOR	0
-#define VER_MINOR	0
-#define VER_PATCH	3
-
-static struct expansion_card *ecs[MAX_ECARDS];
+#define VERSION "1.10 (22/01/2003 2.4.19-rmk5)"
 
 /*
  * Use term=0,1,0,0,0 to turn terminators on/off
@@ -87,20 +77,15 @@
 
 #define NR_SG	256
 
-struct control {
-	unsigned int	io_port;
-	unsigned int	control;
+struct eesoxscsi_info {
+	FAS216_Info		info;
+	struct expansion_card	*ec;
+
+	unsigned int		ctl_port;
+	unsigned int		control;
+	struct scatterlist	sg[NR_SG];	/* Scatter DMA list	*/
 };
 
-typedef struct {
-	FAS216_Info info;
-
-	struct control control;
-
-	unsigned int	dmaarea;	/* Pseudo DMA area	*/
-	struct scatterlist sg[NR_SG];	/* Scatter DMA list	*/
-} EESOXScsi_Info;
-
 /* Prototype: void eesoxscsi_irqenable(ec, irqnr)
  * Purpose  : Enable interrupts on EESOX SCSI card
  * Params   : ec    - expansion card structure
@@ -109,11 +94,11 @@
 static void
 eesoxscsi_irqenable(struct expansion_card *ec, int irqnr)
 {
-	struct control *control = (struct control *)ec->irq_data;
+	struct eesoxscsi_info *info = (struct eesoxscsi_info *)ec->irq_data;
 
-	control->control |= EESOX_INTR_ENABLE;
+	info->control |= EESOX_INTR_ENABLE;
 
-	outb(control->control, control->io_port);
+	outb(info->control, info->ctl_port);
 }
 
 /* Prototype: void eesoxscsi_irqdisable(ec, irqnr)
@@ -124,20 +109,16 @@
 static void
 eesoxscsi_irqdisable(struct expansion_card *ec, int irqnr)
 {
-	struct control *control = (struct control *)ec->irq_data;
+	struct eesoxscsi_info *info = (struct eesoxscsi_info *)ec->irq_data;
 
-	control->control &= ~EESOX_INTR_ENABLE;
+	info->control &= ~EESOX_INTR_ENABLE;
 
-	outb(control->control, control->io_port);
+	outb(info->control, info->ctl_port);
 }
 
 static const expansioncard_ops_t eesoxscsi_ops = {
-	eesoxscsi_irqenable,
-	eesoxscsi_irqdisable,
-	NULL,
-	NULL,
-	NULL,
-	NULL
+	.irqenable	= eesoxscsi_irqenable,
+	.irqdisable	= eesoxscsi_irqdisable,
 };
 
 /* Prototype: void eesoxscsi_terminator_ctl(*host, on_off)
@@ -148,17 +129,17 @@
 static void
 eesoxscsi_terminator_ctl(struct Scsi_Host *host, int on_off)
 {
-	EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata;
+	struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
 	unsigned long flags;
 
 	save_flags_cli(flags);
 	if (on_off)
-		info->control.control |= EESOX_TERM_ENABLE;
+		info->control |= EESOX_TERM_ENABLE;
 	else
-		info->control.control &= ~EESOX_TERM_ENABLE;
-	restore_flags(flags);
+		info->control &= ~EESOX_TERM_ENABLE;
 
-	outb(info->control.control, info->control.io_port);
+	outb(info->control, info->ctl_port);
+	restore_flags(flags);
 }
 
 /* Prototype: void eesoxscsi_intr(irq, *dev_id, *regs)
@@ -170,9 +151,7 @@
 static void
 eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
-
-	fas216_intr(host);
+	fas216_intr(dev_id);
 }
 
 /* Prototype: fasdmatype_t eesoxscsi_dma_setup(host, SCpnt, direction, min_type)
@@ -187,32 +166,26 @@
 eesoxscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
 		       fasdmadir_t direction, fasdmatype_t min_type)
 {
-	EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata;
+	struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
 	int dmach = host->dma_channel;
 
 	if (dmach != NO_DMA &&
 	    (min_type == fasdma_real_all || SCp->this_residual >= 512)) {
-		int bufs = SCp->buffers_residual;
-		int pci_dir, dma_dir;
+		int bufs, map_dir, dma_dir;
 
-		if (bufs)
-			memcpy(info->sg + 1, SCp->buffer + 1,
-				sizeof(struct scatterlist) * bufs);
-		info->sg[0].address = SCp->ptr;
-		info->sg[0].page    = NULL;
-		info->sg[0].length  = SCp->this_residual;
+		bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG);
 
 		if (direction == DMA_OUT)
-			pci_dir = PCI_DMA_TODEVICE,
+			map_dir = PCI_DMA_TODEVICE,
 			dma_dir = DMA_MODE_WRITE;
 		else
-			pci_dir = PCI_DMA_FROMDEVICE,
+			map_dir = PCI_DMA_FROMDEVICE,
 			dma_dir = DMA_MODE_READ;
 
-		pci_map_sg(NULL, info->sg, bufs + 1, pci_dir);
+		pci_map_sg(NULL, info->sg, bufs, map_dir);
 
 		disable_dma(dmach);
-		set_dma_sg(dmach, info->sg, bufs + 1);
+		set_dma_sg(dmach, info->sg, bufs);
 		set_dma_mode(dmach, dma_dir);
 		enable_dma(dmach);
 		return fasdma_real_all;
@@ -225,215 +198,174 @@
 	return fasdma_pseudo;
 }
 
-static void
-eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
-		     fasdmadir_t dir, int transfer_size)
+static void eesoxscsi_buffer_in(void *buf, int length, unsigned long base)
 {
-	EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata;
-	unsigned int status;
-	unsigned int length = SCp->this_residual;
-	union {
-		unsigned char *c;
-		unsigned short *s;
-		unsigned long *l;
-	} buffer;
+	const unsigned long reg_fas = base + EESOX_FAS216_OFFSET;
+	const unsigned long reg_dmastat = base + EESOX_DMASTAT;
+	const unsigned long reg_dmadata = base + EESOX_DMADATA;
+
+	do {
+		unsigned int status;
+
+		/*
+		 * Interrupt request?
+		 */
+		status = inb(reg_fas + (REG_STAT << EESOX_FAS216_SHIFT));
+		if (status & STAT_INT)
+			break;
 
-	buffer.c = SCp->ptr;
+		/*
+		 * DMA request active?
+		 */
+		status = inb(reg_dmastat);
+		if (!(status & EESOX_STAT_DMA))
+			continue;
+
+		/*
+		 * Get number of bytes in FIFO
+		 */
+		status = inb(reg_fas + (REG_CFIS << EESOX_FAS216_SHIFT)) & CFIS_CF;
+		if (status > 16)
+			status = 16;
+		if (status > length)
+			status = length;
+
+		/*
+		 * Align buffer.
+		 */
+		if (((u32)buf) & 2 && status >= 2) {
+			*((u16 *)buf)++ = inw(reg_dmadata);
+			status -= 2;
+			length -= 2;
+		}
 
-	status = inb(host->io_port + EESOX_STATUS);
-	if (dir == DMA_IN) {
-		while (length > 8) {
-			if (status & EESOX_STAT_DMA) {
-				unsigned long l1, l2;
-
-				l1 = inw(info->dmaarea);
-				l1 |= inw(info->dmaarea) << 16;
-				l2 = inw(info->dmaarea);
-				l2 |= inw(info->dmaarea) << 16;
-				*buffer.l++ = l1;
-				*buffer.l++ = l2;
-				length -= 8;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
-		}
-
-		while (length > 1) {
-			if (status & EESOX_STAT_DMA) {
-				*buffer.s++ = inw(info->dmaarea);
-				length -= 2;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
-		}
-
-		while (length > 0) {
-			if (status & EESOX_STAT_DMA) {
-				*buffer.c++ = inw(info->dmaarea);
-				length -= 1;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
+		if (status >= 8) {
+			unsigned long l1, l2;
+
+			l1 = inw(reg_dmadata);
+			l1 |= inw(reg_dmadata) << 16;
+			l2 = inw(reg_dmadata);
+			l2 |= inw(reg_dmadata) << 16;
+			*((u32 *)buf)++ = l1;
+			*((u32 *)buf)++ = l2;
+			length -= 8;
+			continue;
 		}
-	} else {
-		while (length > 8) {
-			if (status & EESOX_STAT_DMA) {
-				unsigned long l1, l2;
-
-				l1 = *buffer.l++;
-				l2 = *buffer.l++;
-
-				outw(l1, info->dmaarea);
-				outw(l1 >> 16, info->dmaarea);
-				outw(l2, info->dmaarea);
-				outw(l2 >> 16, info->dmaarea);
-				length -= 8;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
-		}
-
-		while (length > 1) {
-			if (status & EESOX_STAT_DMA) {
-				outw(*buffer.s++, info->dmaarea);
-				length -= 2;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
-		}
-
-		while (length > 0) {
-			if (status & EESOX_STAT_DMA) {
-				outw(*buffer.c++, info->dmaarea);
-				length -= 1;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
+
+		if (status >= 4) {
+			unsigned long l1;
+
+			l1 = inw(reg_dmadata);
+			l1 |= inw(reg_dmadata) << 16;
+			*((u32 *)buf)++ = l1;
+			length -= 4;
+			continue;
 		}
-	}
-end:
-}
 
-/* Prototype: int eesoxscsi_dma_stop(host, SCpnt)
- * Purpose  : stops DMA/PIO
- * Params   : host  - host
- *	      SCpnt - command
- */
-static void
-eesoxscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp)
-{
-	if (host->dma_channel != NO_DMA)
-		disable_dma(host->dma_channel);
+		if (status >= 2) {
+			*((u16 *)buf)++ = inw(reg_dmadata);
+			length -= 2;
+		}
+	} while (length);
 }
 
-/* Prototype: int eesoxscsi_detect(Scsi_Host_Template * tpnt)
- * Purpose  : initialises EESOX SCSI driver
- * Params   : tpnt - template for this SCSI adapter
- * Returns  : >0 if host found, 0 otherwise.
- */
-int
-eesoxscsi_detect(Scsi_Host_Template *tpnt)
+static void eesoxscsi_buffer_out(void *buf, int length, unsigned long base)
 {
-	static const card_ids eesoxscsi_cids[] =
-			{ EESOXSCSI_LIST, { 0xffff, 0xffff} };
-	int count = 0;
-	struct Scsi_Host *host;
-  
-	tpnt->proc_name = "eesox";
-	memset(ecs, 0, sizeof (ecs));
-
-	ecard_startfind();
+	const unsigned long reg_fas = base + EESOX_FAS216_OFFSET;
+	const unsigned long reg_dmastat = base + EESOX_DMASTAT;
+	const unsigned long reg_dmadata = base + EESOX_DMADATA;
 
-	while(1) {
-	    	EESOXScsi_Info *info;
+	do {
+		unsigned int status;
 
-		ecs[count] = ecard_find(0, eesoxscsi_cids);
-		if (!ecs[count])
+		/*
+		 * Interrupt request?
+		 */
+		status = inb(reg_fas + (REG_STAT << EESOX_FAS216_SHIFT));
+		if (status & STAT_INT)
 			break;
 
-		ecard_claim(ecs[count]);
+		/*
+		 * DMA request active?
+		 */
+		status = inb(reg_dmastat);
+		if (!(status & EESOX_STAT_DMA))
+			continue;
+
+		/*
+		 * Get number of bytes in FIFO
+		 */
+		status = inb(reg_fas + (REG_CFIS << EESOX_FAS216_SHIFT)) & CFIS_CF;
+		if (status > 16)
+			status = 16;
+		status = 16 - status;
+		if (status > length)
+			status = length;
+
+		/*
+		 * Align buffer.
+		 */
+		if (((u32)buf) & 2 && status >= 2) {
+			outw(*((u16 *)buf)++, reg_dmadata);
+			status -= 2;
+			length -= 2;
+		}
 
-		host = scsi_register(tpnt, sizeof (EESOXScsi_Info));
-		if (!host) {
-			ecard_release(ecs[count]);
-			break;
+		if (status >= 8) {
+			unsigned long l1, l2;
+
+			l1 = *((u32 *)buf)++;
+			l2 = *((u32 *)buf)++;
+
+			outw(l1, reg_dmadata);
+			outw(l1 >> 16, reg_dmadata);
+			outw(l2, reg_dmadata);
+			outw(l2 >> 16, reg_dmadata);
+			status -= 8;
+			length -= 8;
+			continue;
 		}
 
-		host->io_port = ecard_address(ecs[count], ECARD_IOC, ECARD_FAST);
-		host->irq = ecs[count]->irq;
-		host->dma_channel = ecs[count]->dma;
-		info = (EESOXScsi_Info *)host->hostdata;
-
-		info->control.io_port = host->io_port + EESOX_CONTROL;
-		info->control.control = term[count] ? EESOX_TERM_ENABLE : 0;
-		outb(info->control.control, info->control.io_port);
-
-		ecs[count]->irqaddr = (unsigned char *)
-			    ioaddr(host->io_port + EESOX_STATUS);
-		ecs[count]->irqmask = EESOX_STAT_INTR;
-		ecs[count]->irq_data = &info->control;
-		ecs[count]->ops = (expansioncard_ops_t *)&eesoxscsi_ops;
-
-		info->info.scsi.io_port		= host->io_port + EESOX_FAS216_OFFSET;
-		info->info.scsi.io_shift	= EESOX_FAS216_SHIFT;
-		info->info.scsi.irq		= host->irq;
-		info->info.ifcfg.clockrate	= EESOX_XTALFREQ;
-		info->info.ifcfg.select_timeout	= 255;
-		info->info.ifcfg.asyncperiod	= EESOX_ASYNC_PERIOD;
-		info->info.ifcfg.sync_max_depth	= EESOX_SYNC_DEPTH;
-		info->info.ifcfg.cntl3		= CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
-		info->info.ifcfg.disconnect_ok	= 1;
-		info->info.ifcfg.wide_max_size	= 0;
-		info->info.dma.setup		= eesoxscsi_dma_setup;
-		info->info.dma.pseudo		= eesoxscsi_dma_pseudo;
-		info->info.dma.stop		= eesoxscsi_dma_stop;
-		info->dmaarea			= host->io_port + EESOX_DMA_OFFSET;
-
-		request_region(host->io_port + EESOX_FAS216_OFFSET,
-				16 << EESOX_FAS216_SHIFT, "eesox2-fas");
-
-		if (host->irq != NO_IRQ &&
-		    request_irq(host->irq, eesoxscsi_intr,
-				SA_INTERRUPT, "eesox", host)) {
-			printk("scsi%d: IRQ%d not free, interrupts disabled\n",
-			       host->host_no, host->irq);
-			host->irq = NO_IRQ;
+		if (status >= 4) {
+			unsigned long l1;
+
+			l1 = *((u32 *)buf)++;
+			outw(l1, reg_dmadata);
+			outw(l1 >> 16, reg_dmadata);
+			status -= 4;
+			length -= 4;
+			continue;
 		}
 
-		if (host->dma_channel != NO_DMA &&
-		    request_dma(host->dma_channel, "eesox")) {
-			printk("scsi%d: DMA%d not free, DMA disabled\n",
-			       host->host_no, host->dma_channel);
-			host->dma_channel = NO_DMA;
+		if (status >= 2) {
+			outw(*((u16 *)buf)++, reg_dmadata);
+			length -= 2;
 		}
+	} while (length);
+}
 
-		fas216_init(host);
-		++count;
+static void
+eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
+		     fasdmadir_t dir, int transfer_size)
+{
+	unsigned int base = host->io_port;
+	if (dir == DMA_IN) {
+		eesoxscsi_buffer_in(SCp->ptr, SCp->this_residual, base);
+	} else {
+		eesoxscsi_buffer_out(SCp->ptr, SCp->this_residual, base);
 	}
-	return count;
 }
 
-/* Prototype: int eesoxscsi_release(struct Scsi_Host * host)
- * Purpose  : releases all resources used by this adapter
- * Params   : host - driver host structure to return info for.
+/* Prototype: int eesoxscsi_dma_stop(host, SCpnt)
+ * Purpose  : stops DMA/PIO
+ * Params   : host  - host
+ *	      SCpnt - command
  */
-int eesoxscsi_release(struct Scsi_Host *host)
+static void
+eesoxscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp)
 {
-	int i;
-
-	fas216_release(host);
-
-	if (host->irq != NO_IRQ)
-		free_irq(host->irq, host);
 	if (host->dma_channel != NO_DMA)
-		free_dma(host->dma_channel);
-	release_region(host->io_port + EESOX_FAS216_OFFSET, 16 << EESOX_FAS216_SHIFT);
-
-	for (i = 0; i < MAX_ECARDS; i++)
-		if (ecs[i] &&
-		    host->io_port == ecard_address(ecs[i], ECARD_IOC, ECARD_FAST))
-			ecard_release(ecs[i]);
-	return 0;
+		disable_dma(host->dma_channel);
 }
 
 /* Prototype: const char *eesoxscsi_info(struct Scsi_Host * host)
@@ -443,15 +375,12 @@
  */
 const char *eesoxscsi_info(struct Scsi_Host *host)
 {
-	EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata;
-	static char string[100], *p;
+	struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
+	static char string[150];
 
-	p = string;
-	p += sprintf(p, "%s ", host->hostt->name);
-	p += fas216_info(&info->info, p);
-	p += sprintf(p, "v%d.%d.%d terminators o%s",
-		     VER_MAJOR, VER_MINOR, VER_PATCH,
-		     info->control.control & EESOX_TERM_ENABLE ? "n" : "ff");
+	sprintf(string, "%s (%s) in slot %d v%s terminators o%s",
+		host->hostt->name, info->info.scsi.type, info->ec->slot_no,
+		VERSION, info->control & EESOX_TERM_ENABLE ? "n" : "ff");
 
 	return string;
 }
@@ -504,43 +433,37 @@
 			    int length, int host_no, int inout)
 {
 	int pos, begin;
-	struct Scsi_Host *host = scsi_hostlist;
-	EESOXScsi_Info *info;
+	struct Scsi_Host *host;
+	struct eesoxscsi_info *info;
 	Scsi_Device *scd;
 
-	while (host) {
-		if (host->host_no == host_no)
-			break;
-		host = host->next;
-	}
+	host = scsi_host_hn_get(host_no);
 	if (!host)
 		return 0;
 
 	if (inout == 1)
 		return eesoxscsi_set_proc_info(host, buffer, length);
 
-	info = (EESOXScsi_Info *)host->hostdata;
+	info = (struct eesoxscsi_info *)host->hostdata;
 
 	begin = 0;
-	pos = sprintf(buffer,
-			"EESOX SCSI driver version %d.%d.%d\n",
-			VER_MAJOR, VER_MINOR, VER_PATCH);
+	pos = sprintf(buffer, "EESOX SCSI driver v%s\n", VERSION);
 	pos += fas216_print_host(&info->info, buffer + pos);
 	pos += sprintf(buffer + pos, "Term    : o%s\n",
-			info->control.control & EESOX_TERM_ENABLE ? "n" : "ff");
+			info->control & EESOX_TERM_ENABLE ? "n" : "ff");
 
 	pos += fas216_print_stats(&info->info, buffer + pos);
 
-	pos += sprintf (buffer+pos, "\nAttached devices:\n");
+	pos += sprintf(buffer+pos, "\nAttached devices:\n");
 
 	for (scd = host->host_queue; scd; scd = scd->next) {
 		int len;
 
-		proc_print_scsidevice (scd, buffer, &len, pos);
+		proc_print_scsidevice(scd, buffer, &len, pos);
 		pos += len;
-		pos += sprintf (buffer+pos, "Extensions: ");
+		pos += sprintf(buffer+pos, "Extensions: ");
 		if (scd->tagged_supported)
-			pos += sprintf (buffer+pos, "TAG %sabled [%d] ",
+			pos += sprintf(buffer+pos, "TAG %sabled [%d] ",
 					scd->tagged_queue ? "en" : "dis",
 					scd->current_tag);
 		pos += sprintf (buffer+pos, "\n");
@@ -558,28 +481,188 @@
 	return pos;
 }
 
+static int eesoxscsi_probe(struct expansion_card *ec);
+
+/* Prototype: int eesoxscsi_detect(Scsi_Host_Template * tpnt)
+ * Purpose  : initialises EESOX SCSI driver
+ * Params   : tpnt - template for this SCSI adapter
+ * Returns  : >0 if host found, 0 otherwise.
+ */
+static int eesoxscsi_detect(Scsi_Host_Template *tpnt)
+{
+	static const card_ids eesoxscsi_cids[] =
+			{ EESOXSCSI_LIST, { 0xffff, 0xffff} };
+	struct expansion_card *ec;
+	int count = 0, ret;
+  
+	ecard_startfind();
+
+	while(1) {
+		ec = ecard_find(0, eesoxscsi_cids);
+		if (!ec)
+			break;
+
+		ecard_claim(ec);
+
+		ret = eesoxscsi_probe(ec);
+		if (ret) {
+			ecard_release(ec);
+			break;
+		}
+		++count;
+	}
+	return count;
+}
+
+static void eesoxscsi_remove(struct Scsi_Host *host);
+
+/* Prototype: int eesoxscsi_release(struct Scsi_Host * host)
+ * Purpose  : releases all resources used by this adapter
+ * Params   : host - driver host structure to return info for.
+ */
+static int eesoxscsi_release(struct Scsi_Host *host)
+{
+	eesoxscsi_remove(host);
+	return 0;
+}
+
 static Scsi_Host_Template eesox_template = {
-	module:				THIS_MODULE,
-	proc_info:			eesoxscsi_proc_info,
-	name:				"EESOX SCSI",
-	detect:				eesoxscsi_detect,
-	release:			eesoxscsi_release,
-	info:				eesoxscsi_info,
-	bios_param:			scsicam_bios_param,
-	can_queue:			1,
-	this_id:			7,
-	sg_tablesize:			SG_ALL,
-	cmd_per_lun:			1,
-	use_clustering:			DISABLE_CLUSTERING,
-	command:			fas216_command,
-	queuecommand:			fas216_queue_command,
-	eh_host_reset_handler:		fas216_eh_host_reset,
-	eh_bus_reset_handler:		fas216_eh_bus_reset,
-	eh_device_reset_handler:	fas216_eh_device_reset,
-	eh_abort_handler:		fas216_eh_abort,
-	use_new_eh_code:		1
+	.module				= THIS_MODULE,
+	.proc_info			= eesoxscsi_proc_info,
+	.name				= "EESOX SCSI",
+	.detect				= eesoxscsi_detect,
+	.release			= eesoxscsi_release,
+	.info				= eesoxscsi_info,
+	.bios_param			= scsicam_bios_param,
+	.command			= fas216_command,
+	.queuecommand			= fas216_queue_command,
+	.eh_host_reset_handler		= fas216_eh_host_reset,
+	.eh_bus_reset_handler		= fas216_eh_bus_reset,
+	.eh_device_reset_handler	= fas216_eh_device_reset,
+	.eh_abort_handler		= fas216_eh_abort,
+	.use_new_eh_code		= 1,
+
+	.can_queue			= 1,
+	.this_id			= 7,
+	.sg_tablesize			= SG_ALL,
+	.cmd_per_lun			= 1,
+	.use_clustering			= DISABLE_CLUSTERING,
+	.proc_name			= "eesox",
 };
 
+static int
+eesoxscsi_probe(struct expansion_card *ec)
+{
+	struct Scsi_Host *host;
+	struct eesoxscsi_info *info;
+	unsigned long base;
+	int ret;
+
+	base = ecard_address(ec, ECARD_IOC, ECARD_FAST);
+
+	if (!request_region(base + EESOX_FAS216_OFFSET,
+			    16 << EESOX_FAS216_SHIFT, "eesox2-fas")) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	host = scsi_register(&eesox_template,
+			     sizeof(struct eesoxscsi_info));
+	if (!host) {
+		ret = -ENOMEM;
+		goto out_region;
+	}
+
+	host->io_port	  = base;
+	host->irq	  = ec->irq;
+	host->dma_channel = ec->dma;
+
+	info = (struct eesoxscsi_info *)host->hostdata;
+	info->ec	= ec;
+	info->ctl_port	= base + EESOX_CONTROL;
+	info->control	= term[ec->slot_no] ? EESOX_TERM_ENABLE : 0;
+	outb(info->control, info->ctl_port);
+
+	ec->irqaddr	= (unsigned char *)ioaddr(base + EESOX_DMASTAT);
+	ec->irqmask	= EESOX_STAT_INTR;
+	ec->irq_data	= info;
+	ec->ops		= (expansioncard_ops_t *)&eesoxscsi_ops;
+
+	info->info.scsi.io_port		= base + EESOX_FAS216_OFFSET;
+	info->info.scsi.io_shift	= EESOX_FAS216_SHIFT;
+	info->info.scsi.irq		= host->irq;
+	info->info.ifcfg.clockrate	= 40; /* MHz */
+	info->info.ifcfg.select_timeout	= 255;
+	info->info.ifcfg.asyncperiod	= 200; /* ns */
+	info->info.ifcfg.sync_max_depth	= 7;
+	info->info.ifcfg.cntl3		= CNTL3_FASTSCSI | CNTL3_FASTCLK;
+	info->info.ifcfg.disconnect_ok	= 1;
+	info->info.ifcfg.wide_max_size	= 0;
+	info->info.ifcfg.capabilities	= FASCAP_PSEUDODMA;
+	info->info.dma.setup		= eesoxscsi_dma_setup;
+	info->info.dma.pseudo		= eesoxscsi_dma_pseudo;
+	info->info.dma.stop		= eesoxscsi_dma_stop;
+
+	ret = fas216_init(host);
+	if (ret)
+		goto out_free;
+
+	ret = request_irq(host->irq, eesoxscsi_intr, 0, "eesox", &info->info);
+	if (ret) {
+		printk("scsi%d: IRQ%d not free: %d\n",
+		       host->host_no, host->irq, ret);
+		goto out_remove;
+	}
+
+	if (host->dma_channel != NO_DMA) {
+		if (request_dma(host->dma_channel, "eesox")) {
+			printk("scsi%d: DMA%d not free, DMA disabled\n",
+			       host->host_no, host->dma_channel);
+			host->dma_channel = NO_DMA;
+		} else {
+			set_dma_speed(host->dma_channel, 180);
+			info->info.ifcfg.capabilities |= FASCAP_DMA;
+			info->info.ifcfg.cntl3 |= CNTL3_BS8;
+		}
+	}
+
+	ret = fas216_add(host);
+	if (ret == 0)
+		goto out;
+
+	if (host->dma_channel != NO_DMA)
+		free_dma(host->dma_channel);
+	free_irq(host->irq, host);
+
+ out_remove:
+	fas216_remove(host);
+
+ out_free:
+	scsi_unregister(host);
+
+ out_region:
+	release_region(base + EESOX_FAS216_OFFSET, 16 << EESOX_FAS216_SHIFT);
+
+ out:
+	return ret;
+}
+
+static void eesoxscsi_remove(struct Scsi_Host *host)
+{
+	struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
+
+	fas216_remove(host);
+
+	if (host->dma_channel != NO_DMA)
+		free_dma(host->dma_channel);
+	free_irq(host->irq, host);
+
+	release_region(host->io_port + EESOX_FAS216_OFFSET, 16 << EESOX_FAS216_SHIFT);
+
+	fas216_release(host);
+	ecard_release(info->ec);
+}
+
 static int __init eesox_init(void)
 {
 	scsi_register_module(MODULE_SCSI_HA, &eesox_template);
diff -urN linux-2.4.22-pre2/drivers/acorn/scsi/fas216.c linux-2.4.22-pre3/drivers/acorn/scsi/fas216.c
--- linux-2.4.22-pre2/drivers/acorn/scsi/fas216.c	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/scsi/fas216.c	2003-07-05 18:09:50.000000000 -0700
@@ -1,7 +1,7 @@
 /*
- *  linux/arch/arm/drivers/scsi/fas216.c
+ *  linux/drivers/acorn/scsi/fas216.c
  *
- *  Copyright (C) 1997-2000 Russell King
+ *  Copyright (C) 1997-2003 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -10,7 +10,7 @@
  * Based on information in qlogicfas.c by Tom Zerucha, Michael Griffith, and
  * other sources, including:
  *   the AMD Am53CF94 data sheet
- *   the AMD Am53C94 data sheet 
+ *   the AMD Am53C94 data sheet
  *
  * This is a generic driver.  To use it, have a look at cumana_2.c.  You
  * should define your own structure that overlays FAS216_Info, eg:
@@ -33,9 +33,6 @@
  *  02-04-2000	RMK	Converted to use the new error handling, and
  *			automatically request sense data upon check
  *			condition status from targets.
- *
- * Todo:
- *  - allow individual devices to enable sync xfers.
  */
 #include <linux/module.h>
 #include <linux/blk.h>
@@ -44,25 +41,20 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/unistd.h>
-#include <linux/stat.h>
 #include <linux/delay.h>
+#include <linux/bitops.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/ecard.h>
 
-#define FAS216_C
-
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
 #include "fas216.h"
-
-#define VER_MAJOR	0
-#define VER_MINOR	0
-#define VER_PATCH	5
+#include "scsi.h"
 
 /* NOTE: SCSI2 Synchronous transfers *require* DMA according to
  *  the data sheet.  This restriction is crazy, especially when
@@ -88,35 +80,68 @@
  *  I was thinking that this was a good chip until I found this restriction ;(
  */
 #define SCSI2_SYNC
-#undef  SCSI2_WIDE
 #undef  SCSI2_TAG
 
 #undef DEBUG_CONNECT
-#undef DEBUG_BUSSERVICE
-#undef DEBUG_FUNCTIONDONE
 #undef DEBUG_MESSAGES
 
 #undef CHECK_STRUCTURE
 
-static struct { int stat, ssr, isr, ph; } list[8];
-static int ptr;
+#ifndef ABORT_TAG
+#define ABORT_TAG	0x0d
+#endif
+
+#define LOG_CONNECT		(1 << 0)
+#define LOG_BUSSERVICE		(1 << 1)
+#define LOG_FUNCTIONDONE	(1 << 2)
+#define LOG_MESSAGES		(1 << 3)
+#define LOG_BUFFER		(1 << 4)
+#define LOG_ERROR		(1 << 8)
+
+static int level_mask = LOG_ERROR;
+
+MODULE_PARM(level_mask, "i");
+
+static inline unsigned char fas216_readb(FAS216_Info *info, unsigned int reg)
+{
+	unsigned int off = reg << info->scsi.io_shift;
+
+	return inb(info->scsi.io_port + off);
+}
+
+static inline void fas216_writeb(FAS216_Info *info, unsigned int reg, unsigned int val)
+{
+	unsigned int off = reg << info->scsi.io_shift;
+
+	outb(val, info->scsi.io_port + off);
+}
 
 static void fas216_dumpstate(FAS216_Info *info)
 {
 	unsigned char is, stat, inst;
 
-	is   = inb(REG_IS(info));
-	stat = inb(REG_STAT(info));
-	inst = inb(REG_INST(info));
+	is   = fas216_readb(info, REG_IS);
+	stat = fas216_readb(info, REG_STAT);
+	inst = fas216_readb(info, REG_INST);
 	
 	printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
 	       " INST=%02X IS=%02X CFIS=%02X",
-		inb(REG_CTCL(info)), inb(REG_CTCM(info)),
-		inb(REG_CMD(info)),  stat, inst, is,
-		inb(REG_CFIS(info)));
+		fas216_readb(info, REG_CTCL),
+		fas216_readb(info, REG_CTCM),
+		fas216_readb(info, REG_CMD),  stat, inst, is,
+		fas216_readb(info, REG_CFIS));
 	printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n",
-		inb(REG_CNTL1(info)), inb(REG_CNTL2(info)),
-		inb(REG_CNTL3(info)), inb(REG_CTCH(info)));
+		fas216_readb(info, REG_CNTL1),
+		fas216_readb(info, REG_CNTL2),
+		fas216_readb(info, REG_CNTL3),
+		fas216_readb(info, REG_CTCH));
+}
+
+static void print_SCp(Scsi_Pointer *SCp, const char *prefix, const char *suffix)
+{
+	printk("%sptr %p this_residual 0x%x buffer %p buffers_residual 0x%x%s",
+		prefix, SCp->ptr, SCp->this_residual, SCp->buffer,
+		SCp->buffers_residual, suffix);
 }
 
 static void fas216_dumpinfo(FAS216_Info *info)
@@ -135,13 +160,9 @@
 		info->scsi.io_port, info->scsi.io_shift, info->scsi.irq,
 		info->scsi.cfg[0], info->scsi.cfg[1], info->scsi.cfg[2],
 		info->scsi.cfg[3]);
-	printk("           type=%p phase=%X reconnected={ target=%d lun=%d tag=%d }\n",
-		info->scsi.type, info->scsi.phase,
-		info->scsi.reconnected.target,
-		info->scsi.reconnected.lun, info->scsi.reconnected.tag);
-	printk("           SCp={ ptr=%p this_residual=%X buffer=%p buffers_residual=%X }\n",
-		info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
-		info->scsi.SCp.buffer, info->scsi.SCp.buffers_residual);
+	printk("           type=%p phase=%X\n",
+		info->scsi.type, info->scsi.phase);
+	print_SCp(&info->scsi.SCp, "           SCp={ ", " }\n");
 	printk("      msgs async_stp=%X disconnectable=%d aborting=%d }\n",
 		info->scsi.async_stp,
 		info->scsi.disconnectable, info->scsi.aborting);
@@ -155,7 +176,7 @@
 		info->ifcfg.clockrate, info->ifcfg.select_timeout,
 		info->ifcfg.asyncperiod, info->ifcfg.sync_max_depth);
 	for (i = 0; i < 8; i++) {
-		printk("    busyluns[%d]=%X dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
+		printk("    busyluns[%d]=%02x dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
 			i, info->busyluns[i], i,
 			info->device[i].disconnect_ok, info->device[i].stp,
 			info->device[i].sof, info->device[i].sync_state);
@@ -203,21 +224,24 @@
 
 static const char *fas216_drv_phase(FAS216_Info *info)
 {
-	switch (info->scsi.phase) {
-	case PHASE_IDLE:		return "idle";
-	case PHASE_SELECTION:		return "selection";
-	case PHASE_COMMAND:		return "command";
-	case PHASE_RECONNECTED:		return "reconnected";
-	case PHASE_DATAOUT:		return "data out";
-	case PHASE_DATAIN:		return "data in";
-	case PHASE_MSGIN:		return "message in";
-	case PHASE_MSGIN_DISCONNECT:	return "disconnect";
-	case PHASE_MSGOUT_EXPECT:	return "expect message out";
-	case PHASE_MSGOUT:		return "message out";
-	case PHASE_STATUS:		return "status";
-	case PHASE_DONE:		return "done";
-	default:			return "???";
-	}
+	static const char *phases[] = {
+		[PHASE_IDLE]		= "idle",
+		[PHASE_SELECTION]	= "selection",
+		[PHASE_COMMAND]		= "command",
+		[PHASE_DATAOUT]		= "data out",
+		[PHASE_DATAIN]		= "data in",
+		[PHASE_MSGIN]		= "message in",
+		[PHASE_MSGIN_DISCONNECT]= "disconnect",
+		[PHASE_MSGOUT_EXPECT]	= "expect message out",
+		[PHASE_MSGOUT]		= "message out",
+		[PHASE_STATUS]		= "status",
+		[PHASE_DONE]		= "done",
+	};
+
+	if (info->scsi.phase < ARRAY_SIZE(phases) &&
+	    phases[info->scsi.phase])
+		return phases[info->scsi.phase];
+	return "???";
 }
 
 static char fas216_target(FAS216_Info *info)
@@ -228,56 +252,128 @@
 		return 'H';
 }
 
+static void
+fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap)
+{
+	static char buf[1024];
+
+	vsnprintf(buf, sizeof(buf), fmt, ap);
+	printk("scsi%d.%c: %s", info->host->host_no, target, buf);
+}
+
+static void
+fas216_log_command(FAS216_Info *info, int level, Scsi_Cmnd *SCpnt, char *fmt, ...)
+{
+	va_list args;
+
+	if (level != 0 && !(level & level_mask))
+		return;
+
+	va_start(args, fmt);
+	fas216_do_log(info, '0' + SCpnt->target, fmt, args);
+	va_end(args);
+
+	printk("CDB: ");
+	print_command(SCpnt->cmnd);
+}
+
+static void
+fas216_log_target(FAS216_Info *info, int level, int target, char *fmt, ...)
+{
+	va_list args;
+
+	if (level != 0 && !(level & level_mask))
+		return;
+
+	if (target < 0)
+		target = 'H';
+	else
+		target += '0';
+
+	va_start(args, fmt);
+	fas216_do_log(info, target, fmt, args);
+	va_end(args);
+
+	printk("\n");
+}
+
+static void fas216_log(FAS216_Info *info, int level, char *fmt, ...)
+{
+	va_list args;
+
+	if (level != 0 && !(level & level_mask))
+		return;
+
+	va_start(args, fmt);
+	fas216_do_log(info, fas216_target(info), fmt, args);
+	va_end(args);
+
+	printk("\n");
+}
+
+#define PH_SIZE	32
+
+static struct { int stat, ssr, isr, ph; } ph_list[PH_SIZE];
+static int ph_ptr;
+
 static void add_debug_list(int stat, int ssr, int isr, int ph)
 {
-	list[ptr].stat = stat;
-	list[ptr].ssr = ssr;
-	list[ptr].isr = isr;
-	list[ptr].ph = ph;
+	ph_list[ph_ptr].stat = stat;
+	ph_list[ph_ptr].ssr = ssr;
+	ph_list[ph_ptr].isr = isr;
+	ph_list[ph_ptr].ph = ph;
+
+	ph_ptr = (ph_ptr + 1) & (PH_SIZE-1);
+}
+
+static struct { int command; void *from; } cmd_list[8];
+static int cmd_ptr;
+
+static void fas216_cmd(FAS216_Info *info, unsigned int command)
+{
+	cmd_list[cmd_ptr].command = command;
+	cmd_list[cmd_ptr].from = __builtin_return_address(0);
+
+	cmd_ptr = (cmd_ptr + 1) & 7;
 
-	ptr = (ptr + 1) & 7;
+	fas216_writeb(info, REG_CMD, command);
 }
 
 static void print_debug_list(void)
 {
 	int i;
 
-	i = ptr;
+	i = ph_ptr;
 
-	printk(KERN_ERR "SCSI IRQ trail: ");
+	printk(KERN_ERR "SCSI IRQ trail\n");
 	do {
-		printk("%02X:%02X:%02X:%1X ",
-			list[i].stat, list[i].ssr,
-			list[i].isr, list[i].ph);
+		printk(" %02x:%02x:%02x:%1x",
+			ph_list[i].stat, ph_list[i].ssr,
+			ph_list[i].isr, ph_list[i].ph);
+		i = (i + 1) & (PH_SIZE - 1);
+		if (((i ^ ph_ptr) & 7) == 0)
+			printk("\n");
+	} while (i != ph_ptr);
+	if ((i ^ ph_ptr) & 7)
+		printk("\n");
+
+	i = cmd_ptr;
+	printk(KERN_ERR "FAS216 commands: ");
+	do {
+		printk("%02x:%p ", cmd_list[i].command, cmd_list[i].from);
 		i = (i + 1) & 7;
-	} while (i != ptr);
+	} while (i != cmd_ptr);
 	printk("\n");
 }
 
 static void fas216_done(FAS216_Info *info, unsigned int result);
 
-/* Function: int fas216_clockrate(unsigned int clock)
- * Purpose : calculate correct value to be written into clock conversion
- *	     factor register.
- * Params  : clock - clock speed in MHz
- * Returns : CLKF_ value
- */
-static int fas216_clockrate(int clock)
-{
-	if (clock <= 10 || clock > 40) {
-		printk(KERN_CRIT
-		       "fas216: invalid clock rate: check your driver!\n");
-		clock = -1;
-	} else
-		clock = ((clock - 1) / 5 + 1) & 7;
-
-	return clock;
-}
-
-/* Function: unsigned short fas216_get_last_msg(FAS216_Info *info, int pos)
- * Purpose : retrieve a last message from the list, using position in fifo
- * Params  : info - interface to search
- *         : pos  - current fifo position
+/**
+ * fas216_get_last_msg - retrive last message from the list
+ * @info: interface to search
+ * @pos: current fifo position
+ *
+ * Retrieve a last message from the list, using position in fifo.
  */
 static inline unsigned short
 fas216_get_last_msg(FAS216_Info *info, int pos)
@@ -298,22 +394,21 @@
 			packed_msg = msg->msg[0];
 	}
 
-#ifdef DEBUG_MESSAGES
-	printk("Message: %04X found at position %02X\n",
-		packed_msg, pos);
-#endif
+	fas216_log(info, LOG_MESSAGES,
+		"Message: %04x found at position %02x\n", packed_msg, pos);
+
 	return packed_msg;
 }
 
-/* Function: int fas216_syncperiod(FAS216_Info *info, int ns)
- * Purpose : Calculate value to be loaded into the STP register
- *           for a given period in ns
- * Params  : info - state structure for interface connected to device
- *         : ns   - period in ns (between subsequent bytes)
- * Returns : Value suitable for REG_STP
+/**
+ * fas216_syncperiod - calculate STP register value
+ * @info: state structure for interface connected to device
+ * @ns: period in ns (between subsequent bytes)
+ *
+ * Calculate value to be loaded into the STP register for a given period
+ * in ns. Returns a value suitable for REG_STP.
  */
-static int
-fas216_syncperiod(FAS216_Info *info, int ns)
+static int fas216_syncperiod(FAS216_Info *info, int ns)
 {
 	int value = (info->ifcfg.clockrate * ns) / 1000;
 
@@ -327,23 +422,28 @@
 	return value & 31;
 }
 
-/* Function: void fas216_set_sync(FAS216_Info *info, int target)
- * Purpose : Correctly setup FAS216 chip for specified transfer period.
- * Params  : info   - state structure for interface
- *         : target - target
+/**
+ * fas216_set_sync - setup FAS216 chip for specified transfer period.
+ * @info: state structure for interface connected to device
+ * @target: target
+ *
+ * Correctly setup FAS216 chip for specified transfer period.
  * Notes   : we need to switch the chip out of FASTSCSI mode if we have
  *           a transfer period >= 200ns - otherwise the chip will violate
  *           the SCSI timings.
  */
-static void
-fas216_set_sync(FAS216_Info *info, int target)
+static void fas216_set_sync(FAS216_Info *info, int target)
 {
-	outb(info->device[target].sof, REG_SOF(info));
-	outb(info->device[target].stp, REG_STP(info));
+	unsigned int cntl3;
+
+	fas216_writeb(info, REG_SOF, info->device[target].sof);
+	fas216_writeb(info, REG_STP, info->device[target].stp);
+
+	cntl3 = info->scsi.cfg[2];
 	if (info->device[target].period >= (200 / 4))
-		outb(info->scsi.cfg[2] & ~CNTL3_FASTSCSI, REG_CNTL3(info));
-	else
-		outb(info->scsi.cfg[2], REG_CNTL3(info));
+		cntl3 = cntl3 & ~CNTL3_FASTSCSI;
+
+	fas216_writeb(info, REG_CNTL3, cntl3);
 }
 
 /* Synchronous transfer support
@@ -364,19 +464,20 @@
  *  Using the correct method assures compatibility with wide data
  *  transfers and future enhancements.
  *
- * We will always initiate a synchronous transfer negociation request on
+ * We will always initiate a synchronous transfer negotiation request on
  * every INQUIRY or REQUEST SENSE message, unless the target itself has
- * at some point performed a synchronous transfer negociation request, or
+ * at some point performed a synchronous transfer negotiation request, or
  * we have synchronous transfers disabled for this device.
  */
 
-/* Function: void fas216_handlesync(FAS216_Info *info, char *msg)
- * Purpose : Handle a synchronous transfer message from the target
- * Params  : info - state structure for interface
- *         : msg  - message from target
+/**
+ * fas216_handlesync - Handle a synchronous transfer message
+ * @info: state structure for interface
+ * @msg: message from target
+ *
+ * Handle a synchronous transfer message from the target
  */
-static void
-fas216_handlesync(FAS216_Info *info, char *msg)
+static void fas216_handlesync(FAS216_Info *info, char *msg)
 {
 	struct fas216_device *dev = &info->device[info->SCpnt->target];
 	enum { sync, async, none, reject } res = none;
@@ -392,7 +493,7 @@
 		 *  message with a MESSAGE REJECT message.
 		 *
 		 * Hence, if we get this condition, we disable
-		 * negociation for this device.
+		 * negotiation for this device.
 		 */
 		if (dev->sync_state == neg_inprogress) {
 			dev->sync_state = neg_invalid;
@@ -410,14 +511,14 @@
 			res = reject;
 			break;
 
-		/* We were not negociating a synchronous transfer,
-		 * but the device sent us a negociation request.
+		/* We were not negotiating a synchronous transfer,
+		 * but the device sent us a negotiation request.
 		 * Honour the request by sending back a SDTR
 		 * message containing our capability, limited by
 		 * the targets capability.
 		 */
 		default:
-			outb(CMD_SETATN, REG_CMD(info));
+			fas216_cmd(info, CMD_SETATN);
 			if (msg[4] > info->ifcfg.sync_max_depth)
 				msg[4] = info->ifcfg.sync_max_depth;
 			if (msg[3] < 1000 / info->ifcfg.clockrate)
@@ -436,7 +537,7 @@
 			res = sync;
 			break;
 
-		/* We initiated the synchronous transfer negociation,
+		/* We initiated the synchronous transfer negotiation,
 		 * and have successfully received a response from the
 		 * target.  The synchronous transfer agreement has been
 		 * reached.  Note: if the values returned are out of our
@@ -465,7 +566,7 @@
 		break;
 
 	case reject:
-		outb(CMD_SETATN, REG_CMD(info));
+		fas216_cmd(info, CMD_SETATN);
 		msgqueue_flush(&info->scsi.msgs);
 		msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
 		info->scsi.phase = PHASE_MSGOUT_EXPECT;
@@ -482,332 +583,277 @@
 	}
 }
 
-/* Function: void fas216_handlewide(FAS216_Info *info, char *msg)
- * Purpose : Handle a wide transfer message from the target
- * Params  : info - state structure for interface
- *         : msg  - message from target
+/**
+ * fas216_updateptrs - update data pointers after transfer suspended/paused
+ * @info: interface's local pointer to update
+ * @bytes_transferred: number of bytes transferred
+ *
+ * Update data pointers after transfer suspended/paused
  */
-static void
-fas216_handlewide(FAS216_Info *info, char *msg)
+static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
 {
-	struct fas216_device *dev = &info->device[info->SCpnt->target];
-	enum { wide, bit8, none, reject } res = none;
+	Scsi_Pointer *SCp = &info->scsi.SCp;
 
-#ifdef SCSI2_WIDE
-	switch (msg[0]) {
-	case MESSAGE_REJECT:
-		/* Wide transfer request failed.
-		 * Note: SCSI II r10:
-		 *
-		 *  SCSI devices that are capable of wide
-		 *  data transfers shall not respond to a
-		 *  WDTR message with a MESSAGE REJECT message.
-		 *
-		 * Hence, if we get this condition, we never
-		 * reattempt negociation for this device.
-		 */
-		if (dev->wide_state == neg_inprogress) {
-			dev->wide_state = neg_invalid;
-			res = bit8;
-		}
-		break;
+	fas216_checkmagic(info);
 
-	case EXTENDED_MESSAGE:
-		switch (dev->wide_state) {
-		/* We don't accept wide data transfer requests.
-		 * Respond with a MESSAGE REJECT to prevent a
-		 * wide data transfer agreement from being reached.
-		 */
-		case neg_invalid:
-			res = reject;
-			break;
+	BUG_ON(bytes_transferred < 0);
 
-		/* We were not negociating a wide data transfer,
-		 * but the device sent is a negociation request.
-		 * Honour the request by sending back a WDTR
-		 * message containing our capability, limited by
-		 * the targets capability.
-		 */
-		default:
-			outb(CMD_SETATN, REG_CMD(info));
-			if (msg[3] > info->ifcfg.wide_max_size)
-				msg[3] = info->ifcfg.wide_max_size;
+	info->SCpnt->request_bufflen -= bytes_transferred;
 
-			msgqueue_flush(&info->scsi.msgs);
-			msgqueue_addmsg(&info->scsi.msgs, 4,
-					EXTENDED_MESSAGE, 2, EXTENDED_WDTR,
-					msg[3]);
-			info->scsi.phase = PHASE_MSGOUT_EXPECT;
-			res = wide;
+	while (bytes_transferred != 0) {
+		if (SCp->this_residual > bytes_transferred)
 			break;
-
-		/* We initiated the wide data transfer negociation,
-		 * and have successfully received a response from the
-		 * target.  The synchronous transfer agreement has been
-		 * reached.  Note: if the values returned are out of our
-		 * bounds, we must reject the message.
+		/*
+		 * We have used up this buffer.  Move on to the
+		 * next buffer.
 		 */
-		case neg_inprogress:
-			res = reject;
-			if (msg[3] <= info->ifcfg.wide_max_size) {
-				dev->wide_state = neg_complete;
-				res = wide;
-			}
-			break;
+		bytes_transferred -= SCp->this_residual;
+		if (!next_SCp(SCp) && bytes_transferred) {
+			printk(KERN_WARNING "scsi%d.%c: out of buffers\n",
+				info->host->host_no, '0' + info->SCpnt->target);
+			return;
 		}
 	}
-#else
-	res = reject;
-#endif
-
-	switch (res) {
-	case wide:
-		dev->wide_xfer = msg[3];
-		break;
-
-	case reject:
-		outb(CMD_SETATN, REG_CMD(info));
-		msgqueue_flush(&info->scsi.msgs);
-		msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
-		info->scsi.phase = PHASE_MSGOUT_EXPECT;
-
-	case bit8:
-		dev->wide_xfer = 0;
-		break;
 
-	case none:
-		break;
-	}
+	SCp->this_residual -= bytes_transferred;
+	if (SCp->this_residual)
+		SCp->ptr += bytes_transferred;
+	else
+		SCp->ptr = NULL;
 }
 
-/* Function: void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
- * Purpose : update data pointers after transfer suspended/paused
- * Params  : info              - interface's local pointer to update
- *           bytes_transferred - number of bytes transferred
+/**
+ * fas216_pio - transfer data off of/on to card using programmed IO
+ * @info: interface to transfer data to/from
+ * @direction: direction to transfer data (DMA_OUT/DMA_IN)
+ *
+ * Transfer data off of/on to card using programmed IO.
+ * Notes: this is incredibly slow.
  */
-static void
-fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
+static void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
 {
-	unsigned char *ptr;
-	unsigned int residual;
+	Scsi_Pointer *SCp = &info->scsi.SCp;
 
 	fas216_checkmagic(info);
 
-	ptr = info->scsi.SCp.ptr;
-	residual = info->scsi.SCp.this_residual;
-
-	info->SCpnt->request_bufflen -= bytes_transferred;
-
-	while (residual <= bytes_transferred && bytes_transferred) {
-		/* We have used up this buffer */
-		bytes_transferred -= residual;
-		if (info->scsi.SCp.buffers_residual) {
-			info->scsi.SCp.buffer++;
-			info->scsi.SCp.buffers_residual--;
-			ptr = (unsigned char *)info->scsi.SCp.buffer->address;
-			residual = info->scsi.SCp.buffer->length;
-		} else {
-			ptr = NULL;
-			residual = 0;
-		}
-	}
+	if (direction == DMA_OUT)
+		fas216_writeb(info, REG_FF, get_next_SCp_byte(SCp));
+	else
+		put_next_SCp_byte(SCp, fas216_readb(info, REG_FF));
 
-	residual -= bytes_transferred;
-	ptr += bytes_transferred;
+	if (SCp->this_residual == 0)
+		next_SCp(SCp);
+}
 
-	if (residual == 0)
-		ptr = NULL;
+static void fas216_set_stc(FAS216_Info *info, unsigned int length)
+{
+	fas216_writeb(info, REG_STCL, length);
+	fas216_writeb(info, REG_STCM, length >> 8);
+	fas216_writeb(info, REG_STCH, length >> 16);
+}
 
-	info->scsi.SCp.ptr = ptr;
-	info->scsi.SCp.this_residual = residual;
+static unsigned int fas216_get_ctc(FAS216_Info *info)
+{
+	return fas216_readb(info, REG_CTCL) +
+	       (fas216_readb(info, REG_CTCM) << 8) +
+	       (fas216_readb(info, REG_CTCH) << 16);
 }
 
-/* Function: void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
- * Purpose : transfer data off of/on to card using programmed IO
- * Params  : info      - interface to transfer data to/from
- *           direction - direction to transfer data (DMA_OUT/DMA_IN)
- * Notes   : this is incredibly slow
+/**
+ * fas216_cleanuptransfer - clean up after a transfer has completed.
+ * @info: interface to clean up
+ *
+ * Update the data pointers according to the number of bytes transferred
+ * on the SCSI bus.
  */
-static void
-fas216_pio(FAS216_Info *info, fasdmadir_t direction)
+static void fas216_cleanuptransfer(FAS216_Info *info)
 {
-	unsigned int residual;
-	char *ptr;
+	unsigned long total, residual, fifo;
+	fasdmatype_t dmatype = info->dma.transfer_type;
 
-	fas216_checkmagic(info);
+	info->dma.transfer_type = fasdma_none;
 
-	residual = info->scsi.SCp.this_residual;
-	ptr = info->scsi.SCp.ptr;
+	/*
+	 * PIO transfers do not need to be cleaned up.
+	 */
+	if (dmatype == fasdma_pio || dmatype == fasdma_none)
+		return;
 
-	if (direction == DMA_OUT)
-		outb(*ptr++, REG_FF(info));
+	if (dmatype == fasdma_real_all)
+		total = info->SCpnt->request_bufflen;
 	else
-		*ptr++ = inb(REG_FF(info));
+		total = info->scsi.SCp.this_residual;
 
-	residual -= 1;
+	residual = fas216_get_ctc(info);
 
-	if (residual == 0) {
-		if (info->scsi.SCp.buffers_residual) {
-			info->scsi.SCp.buffer++;
-			info->scsi.SCp.buffers_residual--;
-			ptr = (unsigned char *)info->scsi.SCp.buffer->address;
-			residual = info->scsi.SCp.buffer->length;
-		} else {
-			ptr = NULL;
-			residual = 0;
-		}
-	}
+	fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
 
-	info->scsi.SCp.ptr = ptr;
-	info->scsi.SCp.this_residual = residual;
+	fas216_log(info, LOG_BUFFER, "cleaning up from previous "
+		   "transfer: length 0x%06x, residual 0x%x, fifo %d",
+		   total, residual, fifo);
+
+	/*
+	 * If we were performing Data-Out, the transfer counter
+	 * counts down each time a byte is transferred by the
+	 * host to the FIFO.  This means we must include the
+	 * bytes left in the FIFO from the transfer counter.
+	 */
+	if (info->scsi.phase == PHASE_DATAOUT)
+		residual += fifo;
+
+	fas216_updateptrs(info, total - residual);
 }
 
-/* Function: void fas216_starttransfer(FAS216_Info *info,
- *				       fasdmadir_t direction)
- * Purpose : Start a DMA/PIO transfer off of/on to card
- * Params  : info      - interface from which device disconnected from
- *           direction - transfer direction (DMA_OUT/DMA_IN)
+/**
+ * fas216_transfer - Perform a DMA/PIO transfer off of/on to card
+ * @info: interface from which device disconnected from
+ *
+ * Start a DMA/PIO transfer off of/on to card
  */
-static void
-fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction, int flush_fifo)
+static void fas216_transfer(FAS216_Info *info)
 {
+	fasdmadir_t direction;
 	fasdmatype_t dmatype;
 
-	fas216_checkmagic(info);
-
-	info->scsi.phase = (direction == DMA_OUT) ?
-				PHASE_DATAOUT : PHASE_DATAIN;
-
-	if (info->dma.transfer_type != fasdma_none &&
-	    info->dma.transfer_type != fasdma_pio) {
-		unsigned long total, residual;
-
-		if (info->dma.transfer_type == fasdma_real_all)
-			total = info->SCpnt->request_bufflen;
-		else
-			total = info->scsi.SCp.this_residual;
-
-		residual = (inb(REG_CFIS(info)) & CFIS_CF) +
-			    inb(REG_CTCL(info)) +
-			    (inb(REG_CTCM(info)) << 8) +
-			    (inb(REG_CTCH(info)) << 16);
-		fas216_updateptrs(info, total - residual);
-	}
-	info->dma.transfer_type = fasdma_none;
+	fas216_log(info, LOG_BUFFER,
+		   "starttransfer: buffer %p length 0x%06x reqlen 0x%06x",
+		   info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
+		   info->SCpnt->request_bufflen);
 
 	if (!info->scsi.SCp.ptr) {
-		printk("scsi%d.%c: null buffer passed to "
-			"fas216_starttransfer\n", info->host->host_no,
-			fas216_target(info));
+		fas216_log(info, LOG_ERROR, "null buffer passed to "
+			   "fas216_starttransfer");
+		print_SCp(&info->scsi.SCp, "SCp: ", "\n");
+		print_SCp(&info->SCpnt->SCp, "Cmnd SCp: ", "\n");
 		return;
 	}
 
-	/* flush FIFO */
-	if (flush_fifo)
-		outb(CMD_FLUSHFIFO, REG_CMD(info));
-
 	/*
-	 * Default to PIO mode or DMA mode if we have a synchronous
-	 * transfer agreement.
+	 * If we have a synchronous transfer agreement in effect, we must
+	 * use DMA mode.  If we are using asynchronous transfers, we may
+	 * use DMA mode or PIO mode.
 	 */
-	if (info->device[info->SCpnt->target].sof && info->dma.setup)
+	if (info->device[info->SCpnt->target].sof)
 		dmatype = fasdma_real_all;
 	else
 		dmatype = fasdma_pio;
 
+	if (info->scsi.phase == PHASE_DATAOUT)
+		direction = DMA_OUT;
+	else
+		direction = DMA_IN;
+
 	if (info->dma.setup)
 		dmatype = info->dma.setup(info->host, &info->scsi.SCp,
 					  direction, dmatype);
 	info->dma.transfer_type = dmatype;
 
+	if (dmatype == fasdma_real_all)
+		fas216_set_stc(info, info->SCpnt->request_bufflen);
+	else
+		fas216_set_stc(info, info->scsi.SCp.this_residual);
+
 	switch (dmatype) {
 	case fasdma_pio:
-		outb(0, REG_SOF(info));
-		outb(info->scsi.async_stp, REG_STP(info));
-		outb(info->scsi.SCp.this_residual, REG_STCL(info));
-		outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
-		outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
-		outb(CMD_TRANSFERINFO, REG_CMD(info));
+		fas216_log(info, LOG_BUFFER, "PIO transfer");
+		fas216_writeb(info, REG_SOF, 0);
+		fas216_writeb(info, REG_STP, info->scsi.async_stp);
+		fas216_cmd(info, CMD_TRANSFERINFO);
 		fas216_pio(info, direction);
 		break;
 
 	case fasdma_pseudo:
-		outb(info->scsi.SCp.this_residual, REG_STCL(info));
-		outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
-		outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
-		outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
+		fas216_log(info, LOG_BUFFER, "pseudo transfer");
+		fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
 		info->dma.pseudo(info->host, &info->scsi.SCp,
 				 direction, info->SCpnt->transfersize);
 		break;
 
 	case fasdma_real_block:
-		outb(info->scsi.SCp.this_residual, REG_STCL(info));
-		outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
-		outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
-		outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
+		fas216_log(info, LOG_BUFFER, "block dma transfer");
+		fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
 		break;
 
 	case fasdma_real_all:
-		outb(info->SCpnt->request_bufflen, REG_STCL(info));
-		outb(info->SCpnt->request_bufflen >> 8, REG_STCM(info));
-		outb(info->SCpnt->request_bufflen >> 16, REG_STCH(info));
-		outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
+		fas216_log(info, LOG_BUFFER, "total dma transfer");
+		fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
 		break;
 
 	default:
-		printk(KERN_ERR "scsi%d.%d: invalid FAS216 DMA type\n",
-		       info->host->host_no, fas216_target(info));
+		fas216_log(info, LOG_BUFFER | LOG_ERROR,
+			   "invalid FAS216 DMA type");
 		break;
 	}
 }
 
-/* Function: void fas216_stoptransfer(FAS216_Info *info)
- * Purpose : Stop a DMA transfer onto / off of the card
- * Params  : info      - interface from which device disconnected from
+/**
+ * fas216_stoptransfer - Stop a DMA transfer onto / off of the card
+ * @info: interface from which device disconnected from
+ *
+ * Called when we switch away from DATA IN or DATA OUT phases.
  */
-static void
-fas216_stoptransfer(FAS216_Info *info)
+static void fas216_stoptransfer(FAS216_Info *info)
 {
 	fas216_checkmagic(info);
 
-	if (info->dma.transfer_type != fasdma_none &&
-	    info->dma.transfer_type != fasdma_pio) {
-		unsigned long total, residual;
+	if (info->dma.transfer_type == fasdma_real_all ||
+	    info->dma.transfer_type == fasdma_real_block)
+		info->dma.stop(info->host, &info->scsi.SCp);
 
-		if ((info->dma.transfer_type == fasdma_real_all ||
-		     info->dma.transfer_type == fasdma_real_block) &&
-		    info->dma.stop)
-			info->dma.stop(info->host, &info->scsi.SCp);
+	fas216_cleanuptransfer(info);
 
-		if (info->dma.transfer_type == fasdma_real_all)
-			total = info->SCpnt->request_bufflen;
-		else
-			total = info->scsi.SCp.this_residual;
+	if (info->scsi.phase == PHASE_DATAIN) {
+		unsigned int fifo;
 
-		residual = (inb(REG_CFIS(info)) & CFIS_CF) +
-			    inb(REG_CTCL(info)) +
-			    (inb(REG_CTCM(info)) << 8) +
-			    (inb(REG_CTCH(info)) << 16);
-		fas216_updateptrs(info, total - residual);
-		info->dma.transfer_type = fasdma_none;
+		/*
+		 * If we were performing Data-In, then the FIFO counter
+		 * contains the number of bytes not transferred via DMA
+		 * from the on-board FIFO.  Read them manually.
+		 */
+		fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
+		while (fifo && info->scsi.SCp.ptr) {
+			*info->scsi.SCp.ptr = fas216_readb(info, REG_FF);
+			fas216_updateptrs(info, 1);
+			fifo--;
+		}
+	} else {
+		/*
+		 * After a Data-Out phase, there may be unsent
+		 * bytes left in the FIFO.  Flush them out.
+		 */
+		fas216_cmd(info, CMD_FLUSHFIFO);
 	}
-	if (info->scsi.phase == PHASE_DATAOUT)
-		outb(CMD_FLUSHFIFO, REG_CMD(info));
 }
 
-/* Function: void fas216_disconnected_intr(FAS216_Info *info)
- * Purpose : handle device disconnection
- * Params  : info - interface from which device disconnected from
+static void fas216_aborttransfer(FAS216_Info *info)
+{
+	fas216_checkmagic(info);
+
+	if (info->dma.transfer_type == fasdma_real_all ||
+	    info->dma.transfer_type == fasdma_real_block)
+		info->dma.stop(info->host, &info->scsi.SCp);
+
+	info->dma.transfer_type = fasdma_none;
+	fas216_cmd(info, CMD_FLUSHFIFO);
+}
+
+static void fas216_kick(FAS216_Info *info);
+
+/**
+ * fas216_disconnected_intr - handle device disconnection
+ * @info: interface from which device disconnected from
+ *
+ * Handle device disconnection
  */
-static void
-fas216_disconnect_intr(FAS216_Info *info)
+static void fas216_disconnect_intr(FAS216_Info *info)
 {
+	unsigned long flags;
+
 	fas216_checkmagic(info);
 
-#ifdef DEBUG_CONNECT
-	printk("scsi%d.%c: disconnect phase=%02X\n", info->host->host_no,
-		fas216_target(info), info->scsi.phase);
-#endif
+	fas216_log(info, LOG_CONNECT, "disconnect phase=%02x",
+		   info->scsi.phase);
+
 	msgqueue_flush(&info->scsi.msgs);
 
 	switch (info->scsi.phase) {
@@ -817,11 +863,13 @@
 		break;
 
 	case PHASE_MSGIN_DISCONNECT:		/* message in - disconnecting		*/
-		outb(CMD_ENABLESEL, REG_CMD(info));
 		info->scsi.disconnectable = 1;
-		info->scsi.reconnected.tag = 0;
 		info->scsi.phase = PHASE_IDLE;
 		info->stats.disconnects += 1;
+		spin_lock_irqsave(&info->host_lock, flags);
+		if (info->scsi.phase == PHASE_IDLE)
+			fas216_kick(info);
+		spin_unlock_irqrestore(&info->host_lock, flags);
 		break;
 
 	case PHASE_DONE:			/* at end of command - complete		*/
@@ -845,295 +893,131 @@
 	}
 }
 
-/* Function: void fas216_reselected_intr(FAS216_Info *info)
- * Purpose : Start reconnection of a device
- * Params  : info - interface which was reselected
+/**
+ * fas216_reselected_intr - start reconnection of a device
+ * @info: interface which was reselected
+ *
+ * Start reconnection of a device
  */
 static void
 fas216_reselected_intr(FAS216_Info *info)
 {
-	unsigned char target, identify_msg, ok;
+	unsigned int cfis, i;
+	unsigned char msg[4];
+	unsigned char target, lun, tag;
 
 	fas216_checkmagic(info);
 
-	if ((info->scsi.phase == PHASE_SELECTION ||
-	     info->scsi.phase == PHASE_SELSTEPS) && info->SCpnt) {
-		Scsi_Cmnd *SCpnt = info->SCpnt;
+	if (info->scsi.phase == PHASE_SELECTION ||
+	    info->scsi.phase == PHASE_SELSTEPS) {
+		fas216_log(info, LOG_ERROR, "wrong phase in reselected_intr\n");
+		return;
+	}
 
-		info->origSCpnt = SCpnt;
-		info->SCpnt = NULL;
+	cfis = fas216_readb(info, REG_CFIS);
 
-		if (info->device[SCpnt->target].wide_state == neg_inprogress)
-			info->device[SCpnt->target].wide_state = neg_wait;
-		if (info->device[SCpnt->target].sync_state == neg_inprogress)
-			info->device[SCpnt->target].sync_state = neg_wait;
-	}
+	fas216_log(info, LOG_CONNECT, "reconnect phase=%02x cfis=%02x",
+		   info->scsi.phase, cfis);
 
-#ifdef DEBUG_CONNECT
-	printk("scsi%d.%c: reconnect phase=%02X\n", info->host->host_no,
-		fas216_target(info), info->scsi.phase);
-#endif
+	cfis &= CFIS_CF;
 
-	if ((inb(REG_CFIS(info)) & CFIS_CF) != 2) {
+	if (cfis < 2 || cfis > 4) {
 		printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n",
 			info->host->host_no);
-		outb(CMD_SETATN, REG_CMD(info));
-		outb(CMD_MSGACCEPTED, REG_CMD(info));
-		msgqueue_flush(&info->scsi.msgs);
-		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
-		info->scsi.phase = PHASE_MSGOUT_EXPECT;
-		return;
-	}
-
-	target = inb(REG_FF(info));
-	identify_msg = inb(REG_FF(info));
-
-	ok = 1;
-	if (!(target & (1 << info->host->this_id))) {
-		printk(KERN_ERR "scsi%d.H: invalid host id on reselect\n", info->host->host_no);
-		ok = 0;
+		goto bad_message;
 	}
 
-	if (!(identify_msg & 0x80)) {
-		printk(KERN_ERR "scsi%d.H: no IDENTIFY message on reselect, got msg %02X\n",
-			info->host->host_no, identify_msg);
-		ok = 0;
-	}
+	for (i = 0; i < cfis; i++)
+		msg[i] = fas216_readb(info, REG_FF);
 
-	if (!ok) {
-		/*
-		 * Something went wrong - send an initiator error to
-		 * the target.
-		 */
-		outb(CMD_SETATN, REG_CMD(info));
-		outb(CMD_MSGACCEPTED, REG_CMD(info));
-		msgqueue_flush(&info->scsi.msgs);
-		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
-		info->scsi.phase = PHASE_MSGOUT_EXPECT;
-		return;
-	}
+	if (!(msg[0] & (1 << info->host->this_id)) ||
+	    !(msg[1] & 0x80))
+		goto initiator_error;
 
-	target &= ~(1 << info->host->this_id);
-	switch (target) {
-	case   1:  target = 0; break;
-	case   2:  target = 1; break;
-	case   4:  target = 2; break;
-	case   8:  target = 3; break;
-	case  16:  target = 4; break;
-	case  32:  target = 5; break;
-	case  64:  target = 6; break;
-	case 128:  target = 7; break;
-	default:   target = info->host->this_id; break;
-	}
-
-	identify_msg &= 7;
-	info->scsi.reconnected.target = target;
-	info->scsi.reconnected.lun    = identify_msg;
-	info->scsi.reconnected.tag    = 0;
-
-	ok = 0;
-	if (info->scsi.disconnectable && info->SCpnt &&
-	    info->SCpnt->target == target && info->SCpnt->lun == identify_msg)
-		ok = 1;
+	target = msg[0] & ~(1 << info->host->this_id);
+	target = ffs(target) - 1;
+	lun = msg[1] & 7;
+	tag = 0;
 
-	if (!ok && queue_probetgtlun(&info->queues.disconnected, target, identify_msg))
-		ok = 1;
+	if (cfis >= 3) {
+		if (msg[2] != SIMPLE_QUEUE_TAG)
+			goto initiator_error;
 
-	msgqueue_flush(&info->scsi.msgs);
-	if (ok) {
-		info->scsi.phase = PHASE_RECONNECTED;
-		outb(target, REG_SDID(info));
-	} else {
-		/*
-		 * Our command structure not found - abort the
-		 * command on the target.  Since we have no
-		 * record of this command, we can't send
-		 * an INITIATOR DETECTED ERROR message.
-		 */
-		outb(CMD_SETATN, REG_CMD(info));
-		msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
-		info->scsi.phase = PHASE_MSGOUT_EXPECT;
+		tag = msg[3];
 	}
 
-	outb(CMD_MSGACCEPTED, REG_CMD(info));
-}
-
-/* Function: void fas216_finish_reconnect(FAS216_Info *info)
- * Purpose : finish reconnection sequence for device
- * Params  : info - interface which caused function done interrupt
- */
-static void
-fas216_finish_reconnect(FAS216_Info *info)
-{
-	fas216_checkmagic(info);
+	/* set up for synchronous transfers */
+	fas216_writeb(info, REG_SDID, target);
+	fas216_set_sync(info, target);
+	msgqueue_flush(&info->scsi.msgs);
 
-#ifdef DEBUG_CONNECT
-	printk("Connected: %1X %1X %02X, reconnected: %1X %1X %02X\n",
-		info->SCpnt->target, info->SCpnt->lun, info->SCpnt->tag,
-		info->scsi.reconnected.target, info->scsi.reconnected.lun,
-		info->scsi.reconnected.tag);
-#endif
+	fas216_log(info, LOG_CONNECT, "Reconnected: target %1x lun %1x tag %02x",
+		   target, lun, tag);
 
 	if (info->scsi.disconnectable && info->SCpnt) {
 		info->scsi.disconnectable = 0;
-		if (info->SCpnt->target == info->scsi.reconnected.target &&
-		    info->SCpnt->lun    == info->scsi.reconnected.lun &&
-		    info->SCpnt->tag    == info->scsi.reconnected.tag) {
-#ifdef DEBUG_CONNECT
-			printk("scsi%d.%c: reconnected",
-				info->host->host_no, fas216_target(info));
-#endif
+		if (info->SCpnt->target == target &&
+		    info->SCpnt->lun    == lun &&
+		    info->SCpnt->tag    == tag) {
+			fas216_log(info, LOG_CONNECT, "reconnected previously connected command");
 		} else {
 			queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
-#ifdef DEBUG_CONNECT
-			printk("scsi%d.%c: had to move command to disconnected queue\n",
-				info->host->host_no, fas216_target(info));
-#endif
+			fas216_log(info, LOG_CONNECT, "had to move command to disconnected queue");
 			info->SCpnt = NULL;
 		}
 	}
 	if (!info->SCpnt) {
 		info->SCpnt = queue_remove_tgtluntag(&info->queues.disconnected,
-					info->scsi.reconnected.target,
-					info->scsi.reconnected.lun,
-					info->scsi.reconnected.tag);
-#ifdef DEBUG_CONNECT
-		printk("scsi%d.%c: had to get command",
-			info->host->host_no, fas216_target(info));
-#endif
+					target, lun, tag);
+		fas216_log(info, LOG_CONNECT, "had to get command");
 	}
-	if (!info->SCpnt) {
-		outb(CMD_SETATN, REG_CMD(info));
-		msgqueue_flush(&info->scsi.msgs);
-#if 0
-		if (info->scsi.reconnected.tag)
-			msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, info->scsi.reconnected.tag);
-		else
-#endif
-			msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
-		info->scsi.phase = PHASE_MSGOUT_EXPECT;
-		info->scsi.aborting = 1;
-	} else {
+
+	if (info->SCpnt) {
 		/*
 		 * Restore data pointer from SAVED data pointer
 		 */
 		info->scsi.SCp = info->SCpnt->SCp;
-#ifdef DEBUG_CONNECT
-		printk(", data pointers: [%p, %X]",
-			info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
-#endif
-	}
-#ifdef DEBUG_CONNECT
-	printk("\n");
-#endif
-}
 
-static int fas216_wait_cmd(FAS216_Info *info, int cmd)
-{
-	int tout;
-	int stat;
-
-	outb(cmd, REG_CMD(info));
+		fas216_log(info, LOG_CONNECT, "data pointers: [%p, %X]",
+			info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
+		info->scsi.phase = PHASE_MSGIN;
+	} else {
+		/*
+		 * Our command structure not found - abort the
+		 * command on the target.  Since we have no
+		 * record of this command, we can't send
+		 * an INITIATOR DETECTED ERROR message.
+		 */
+		fas216_cmd(info, CMD_SETATN);
 
-	for (tout = 1000; tout; tout -= 1) {
-		stat = inb(REG_STAT(info));
-		if (stat & STAT_INT)
-			break;
-		udelay(1);
+		if (tag)
+			msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, tag);
+		else
+			msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
+		info->scsi.phase = PHASE_MSGOUT_EXPECT;
+		info->scsi.aborting = 1;
 	}
 
-	return stat;
-}
-
-static int fas216_get_msg_byte(FAS216_Info *info)
-{
-	int stat;
-
-	stat = fas216_wait_cmd(info, CMD_MSGACCEPTED);
-
-	if ((stat & STAT_INT) == 0)
-		goto timedout;
-
-	if ((stat & STAT_BUSMASK) != STAT_MESGIN)
-		goto unexpected_phase_change;
-
-	inb(REG_INST(info));
-
-	stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);
-
-	if ((stat & STAT_INT) == 0)
-		goto timedout;
-
-	if ((stat & STAT_BUSMASK) != STAT_MESGIN)
-		goto unexpected_phase_change;
-
-	inb(REG_INST(info));
-
-	return inb(REG_FF(info));
-
-timedout:
-	printk("scsi%d.%c: timed out waiting for message byte\n",
-		info->host->host_no, fas216_target(info));
-	return -1;
-
-unexpected_phase_change:
-	printk("scsi%d.%c: unexpected phase change: status = %02X\n",
-		info->host->host_no, fas216_target(info), stat);
+	fas216_cmd(info, CMD_MSGACCEPTED);
+	return;
 
-	return -2;
+ initiator_error:
+	printk(KERN_ERR "scsi%d.H: error during reselection: bytes",
+		info->host->host_no);
+	for (i = 0; i < cfis; i++)
+		printk(" %02x", msg[i]);
+	printk("\n");
+ bad_message:
+	fas216_cmd(info, CMD_SETATN);
+	msgqueue_flush(&info->scsi.msgs);
+	msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
+	info->scsi.phase = PHASE_MSGOUT_EXPECT;
+	fas216_cmd(info, CMD_MSGACCEPTED);
 }
 
-/* Function: void fas216_message(FAS216_Info *info)
- * Purpose : handle a function done interrupt from FAS216 chip
- * Params  : info - interface which caused function done interrupt
- */
-static void fas216_message(FAS216_Info *info)
+static void fas216_parse_message(FAS216_Info *info, unsigned char *message, int msglen)
 {
-	unsigned char *message = info->scsi.message;
-	unsigned int msglen = 1, i;
-	int msgbyte = 0;
-
-	fas216_checkmagic(info);
-
-	message[0] = inb(REG_FF(info));
-
-	if (message[0] == EXTENDED_MESSAGE) {
-		msgbyte = fas216_get_msg_byte(info);
-
-		if (msgbyte >= 0) {
-			message[1] = msgbyte;
-
-			for (msglen = 2; msglen < message[1] + 2; msglen++) {
-				msgbyte = fas216_get_msg_byte(info);
-
-				if (msgbyte >= 0)
-					message[msglen] = msgbyte;
-				else
-					break;
-			}
-		}
-	}
-
-	info->scsi.msglen = msglen;
-
-#ifdef DEBUG_MESSAGES
-	{
-		int i;
-
-		printk("scsi%d.%c: message in: ",
-			info->host->host_no, fas216_target(info));
-		for (i = 0; i < msglen; i++)
-			printk("%02X ", message[i]);
-		printk("\n");
-	}
-#endif
-
-	if (info->scsi.phase == PHASE_RECONNECTED) {
-		if (message[0] == SIMPLE_QUEUE_TAG)
-			info->scsi.reconnected.tag = message[1];
-		fas216_finish_reconnect(info);
-		info->scsi.phase = PHASE_MSGIN;
-	}
+	int i;
 
 	switch (message[0]) {
 	case COMMAND_COMPLETE:
@@ -1159,11 +1043,9 @@
 		 */
 		info->SCpnt->SCp = info->scsi.SCp;
 		info->SCpnt->SCp.sent_command = 0;
-#if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
-		printk("scsi%d.%c: save data pointers: [%p, %X]\n",
-			info->host->host_no, fas216_target(info),
+		fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
+			"save data pointers: [%p, %X]",
 			info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
-#endif
 		break;
 
 	case RESTORE_POINTERS:
@@ -1174,11 +1056,9 @@
 		 * Restore current data pointer from SAVED data pointer
 		 */
 		info->scsi.SCp = info->SCpnt->SCp;
-#if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
-		printk("scsi%d.%c: restore data pointers: [%p, %X]\n",
-			info->host->host_no, fas216_target(info),
+		fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
+			"restore data pointers: [%p, 0x%x]",
 			info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
-#endif
 		break;
 
 	case DISCONNECT:
@@ -1197,13 +1077,8 @@
 			fas216_handlesync(info, message);
 			break;
 
-		case EXTENDED_MESSAGE | EXTENDED_WDTR << 8:
-			fas216_handlewide(info, message);
-			break;
-
 		default:
-			printk("scsi%d.%c: reject, last message %04X\n",
-				info->host->host_no, fas216_target(info),
+			fas216_log(info, 0, "reject, last message 0x%04x",
 				fas216_get_last_msg(info, info->scsi.msgin_fifo));
 		}
 		break;
@@ -1211,29 +1086,15 @@
 	case NOP:
 		break;
 
-	case SIMPLE_QUEUE_TAG:
-		if (msglen < 2)
-			goto unrecognised;
-
-		/* handled above - print a warning since this is untested */
-		printk("scsi%d.%c: reconnect queue tag %02X\n",
-			info->host->host_no, fas216_target(info),
-			message[1]);
-		break;
-
 	case EXTENDED_MESSAGE:
 		if (msglen < 3)
 			goto unrecognised;
 
 		switch (message[2]) {
-		case EXTENDED_SDTR:	/* Sync transfer negociation request/reply */
+		case EXTENDED_SDTR:	/* Sync transfer negotiation request/reply */
 			fas216_handlesync(info, message);
 			break;
 
-		case EXTENDED_WDTR:	/* Wide transfer negociation request/reply */
-			fas216_handlewide(info, message);
-			break;
-
 		default:
 			goto unrecognised;
 		}
@@ -1242,12 +1103,10 @@
 	default:
 		goto unrecognised;
 	}
-	outb(CMD_MSGACCEPTED, REG_CMD(info));
 	return;
 
 unrecognised:
-	printk("scsi%d.%c: unrecognised message, rejecting\n",
-		info->host->host_no, fas216_target(info));
+	fas216_log(info, 0, "unrecognised message, rejecting");
 	printk("scsi%d.%c: message was", info->host->host_no, fas216_target(info));
 	for (i = 0; i < msglen; i++)
 		printk("%s%02X", i & 31 ? " " : "\n  ", message[i]);
@@ -1258,19 +1117,138 @@
 	 * I can't use SETATN since the chip gives me an
 	 * invalid command interrupt when I do.  Weird.
 	 */
-outb(CMD_NOP, REG_CMD(info));
+fas216_cmd(info, CMD_NOP);
 fas216_dumpstate(info);
-	outb(CMD_SETATN, REG_CMD(info));
+	fas216_cmd(info, CMD_SETATN);
 	msgqueue_flush(&info->scsi.msgs);
 	msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
 	info->scsi.phase = PHASE_MSGOUT_EXPECT;
 fas216_dumpstate(info);
-	outb(CMD_MSGACCEPTED, REG_CMD(info));
 }
 
-/* Function: void fas216_send_command(FAS216_Info *info)
- * Purpose : send a command to a target after all message bytes have been sent
- * Params  : info - interface which caused bus service
+static int fas216_wait_cmd(FAS216_Info *info, int cmd)
+{
+	int tout;
+	int stat;
+
+	fas216_cmd(info, cmd);
+
+	for (tout = 1000; tout; tout -= 1) {
+		stat = fas216_readb(info, REG_STAT);
+		if (stat & (STAT_INT|STAT_PARITYERROR))
+			break;
+		udelay(1);
+	}
+
+	return stat;
+}
+
+static int fas216_get_msg_byte(FAS216_Info *info)
+{
+	unsigned int stat = fas216_wait_cmd(info, CMD_MSGACCEPTED);
+
+	if ((stat & STAT_INT) == 0)
+		goto timedout;
+
+	if ((stat & STAT_BUSMASK) != STAT_MESGIN)
+		goto unexpected_phase_change;
+
+	fas216_readb(info, REG_INST);
+
+	stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);
+
+	if ((stat & STAT_INT) == 0)
+		goto timedout;
+
+	if (stat & STAT_PARITYERROR)
+		goto parity_error;
+
+	if ((stat & STAT_BUSMASK) != STAT_MESGIN)
+		goto unexpected_phase_change;
+
+	fas216_readb(info, REG_INST);
+
+	return fas216_readb(info, REG_FF);
+
+timedout:
+	fas216_log(info, LOG_ERROR, "timed out waiting for message byte");
+	return -1;
+
+unexpected_phase_change:
+	fas216_log(info, LOG_ERROR, "unexpected phase change: status = %02x", stat);
+	return -2;
+
+parity_error:
+	fas216_log(info, LOG_ERROR, "parity error during message in phase");
+	return -3;
+}
+
+/**
+ * fas216_message - handle a function done interrupt from FAS216 chip
+ * @info: interface which caused function done interrupt
+ *
+ * Handle a function done interrupt from FAS216 chip
+ */
+static void fas216_message(FAS216_Info *info)
+{
+	unsigned char *message = info->scsi.message;
+	unsigned int msglen = 1;
+	int msgbyte = 0;
+
+	fas216_checkmagic(info);
+
+	message[0] = fas216_readb(info, REG_FF);
+
+	if (message[0] == EXTENDED_MESSAGE) {
+		msgbyte = fas216_get_msg_byte(info);
+
+		if (msgbyte >= 0) {
+			message[1] = msgbyte;
+
+			for (msglen = 2; msglen < message[1] + 2; msglen++) {
+				msgbyte = fas216_get_msg_byte(info);
+
+				if (msgbyte >= 0)
+					message[msglen] = msgbyte;
+				else
+					break;
+			}
+		}
+	}
+
+	if (msgbyte == -3)
+		goto parity_error;
+
+#ifdef DEBUG_MESSAGES
+	{
+		int i;
+
+		printk("scsi%d.%c: message in: ",
+			info->host->host_no, fas216_target(info));
+		for (i = 0; i < msglen; i++)
+			printk("%02X ", message[i]);
+		printk("\n");
+	}
+#endif
+
+	fas216_parse_message(info, message, msglen);
+	fas216_cmd(info, CMD_MSGACCEPTED);
+	return;
+
+parity_error:
+	fas216_cmd(info, CMD_SETATN);
+	msgqueue_flush(&info->scsi.msgs);
+	msgqueue_addmsg(&info->scsi.msgs, 1, MSG_PARITY_ERROR);
+	info->scsi.phase = PHASE_MSGOUT_EXPECT;
+	fas216_cmd(info, CMD_MSGACCEPTED);
+	return;
+}
+
+/**
+ * fas216_send_command - send command after all message bytes have been sent
+ * @info: interface which caused bus service
+ *
+ * Send a command to a target after all message bytes have been sent
  */
 static void fas216_send_command(FAS216_Info *info)
 {
@@ -1278,22 +1256,24 @@
 
 	fas216_checkmagic(info);
 
-	outb(CMD_NOP|CMD_WITHDMA, REG_CMD(info));
-	outb(CMD_FLUSHFIFO, REG_CMD(info));
+	fas216_cmd(info, CMD_NOP|CMD_WITHDMA);
+	fas216_cmd(info, CMD_FLUSHFIFO);
 
 	/* load command */
 	for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++)
-		outb(info->SCpnt->cmnd[i], REG_FF(info));
+		fas216_writeb(info, REG_FF, info->SCpnt->cmnd[i]);
 
-	outb(CMD_TRANSFERINFO, REG_CMD(info));
+	fas216_cmd(info, CMD_TRANSFERINFO);
 
 	info->scsi.phase = PHASE_COMMAND;
 }
 
-/* Function: void fas216_send_messageout(FAS216_Info *info, int start)
- * Purpose : handle bus service to send a message
- * Params  : info - interface which caused bus service
- * Note    : We do not allow the device to change the data direction!
+/**
+ * fas216_send_messageout - handle bus service to send a message
+ * @info: interface which caused bus service
+ *
+ * Handle bus service to send a message.
+ * Note: We do not allow the device to change the data direction!
  */
 static void fas216_send_messageout(FAS216_Info *info, int start)
 {
@@ -1301,7 +1281,7 @@
 
 	fas216_checkmagic(info);
 
-	outb(CMD_FLUSHFIFO, REG_CMD(info));
+	fas216_cmd(info, CMD_FLUSHFIFO);
 
 	if (tot_msglen) {
 		struct message *msg;
@@ -1311,42 +1291,43 @@
 			int i;
 
 			for (i = start; i < msg->length; i++)
-				outb(msg->msg[i], REG_FF(info));
+				fas216_writeb(info, REG_FF, msg->msg[i]);
 
-			msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
+			msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
 			start = 0;
 		}
 	} else
-		outb(NOP, REG_FF(info));
+		fas216_writeb(info, REG_FF, NOP);
 
-	outb(CMD_TRANSFERINFO, REG_CMD(info));
+	fas216_cmd(info, CMD_TRANSFERINFO);
 
 	info->scsi.phase = PHASE_MSGOUT;
 }
 
-/* Function: void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
- * Purpose : handle a bus service interrupt from FAS216 chip
- * Params  : info - interface which caused bus service interrupt
- *           stat - Status register contents
- *           ssr  - SCSI Status register contents
+/**
+ * fas216_busservice_intr - handle bus service interrupt from FAS216 chip
+ * @info: interface which caused bus service interrupt
+ * @stat: Status register contents
+ * @is: SCSI Status register contents
+ *
+ * Handle a bus service interrupt from FAS216 chip
  */
-static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
+static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int is)
 {
 	fas216_checkmagic(info);
 
-#ifdef DEBUG_BUSSERVICE
-	printk("scsi%d.%c: bus service: stat=%02X ssr=%02X phase=%02X\n",
-		info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase);
-#endif
+	fas216_log(info, LOG_BUSSERVICE,
+		   "bus service: stat=%02x is=%02x phase=%02x",
+		   stat, is, info->scsi.phase);
 
 	switch (info->scsi.phase) {
 	case PHASE_SELECTION:
-		if ((ssr & IS_BITS) != 1)
+		if ((is & IS_BITS) != IS_MSGBYTESENT)
 			goto bad_is;
 		break;
 
 	case PHASE_SELSTEPS:
-		switch (ssr & IS_BITS) {
+		switch (is & IS_BITS) {
 		case IS_SELARB:
 		case IS_MSGBYTESENT:
 			goto bad_is;
@@ -1365,42 +1346,36 @@
 		break;
 	}
 
-	outb(CMD_NOP, REG_CMD(info));
+	fas216_cmd(info, CMD_NOP);
 
 #define STATE(st,ph) ((ph) << 3 | (st))
 	/* This table describes the legal SCSI state transitions,
 	 * as described by the SCSI II spec.
 	 */
 	switch (STATE(stat & STAT_BUSMASK, info->scsi.phase)) {
-						/* Reselmsgin   -> Data In	*/
-	case STATE(STAT_DATAIN, PHASE_RECONNECTED):
-		fas216_finish_reconnect(info);
 	case STATE(STAT_DATAIN, PHASE_SELSTEPS):/* Sel w/ steps -> Data In      */
-	case STATE(STAT_DATAIN, PHASE_DATAIN):  /* Data In      -> Data In      */
 	case STATE(STAT_DATAIN, PHASE_MSGOUT):  /* Message Out  -> Data In      */
 	case STATE(STAT_DATAIN, PHASE_COMMAND): /* Command      -> Data In      */
 	case STATE(STAT_DATAIN, PHASE_MSGIN):   /* Message In   -> Data In      */
-		fas216_starttransfer(info, DMA_IN, 0);
+		info->scsi.phase = PHASE_DATAIN;
+		fas216_transfer(info);
 		return;
 
+	case STATE(STAT_DATAIN, PHASE_DATAIN):  /* Data In      -> Data In      */
 	case STATE(STAT_DATAOUT, PHASE_DATAOUT):/* Data Out     -> Data Out     */
-		fas216_starttransfer(info, DMA_OUT, 0);
+		fas216_cleanuptransfer(info);
+		fas216_transfer(info);
 		return;
 
-						/* Reselmsgin   -> Data Out     */
-	case STATE(STAT_DATAOUT, PHASE_RECONNECTED):
-		fas216_finish_reconnect(info);
 	case STATE(STAT_DATAOUT, PHASE_SELSTEPS):/* Sel w/ steps-> Data Out     */
 	case STATE(STAT_DATAOUT, PHASE_MSGOUT): /* Message Out  -> Data Out     */
 	case STATE(STAT_DATAOUT, PHASE_COMMAND):/* Command      -> Data Out     */
 	case STATE(STAT_DATAOUT, PHASE_MSGIN):  /* Message In   -> Data Out     */
-		fas216_starttransfer(info, DMA_OUT, 1);
+		fas216_cmd(info, CMD_FLUSHFIFO);
+		info->scsi.phase = PHASE_DATAOUT;
+		fas216_transfer(info);
 		return;
 
-						/* Reselmsgin   -> Status       */
-	case STATE(STAT_STATUS, PHASE_RECONNECTED):
-		fas216_finish_reconnect(info);
-		goto status;
 	case STATE(STAT_STATUS, PHASE_DATAOUT): /* Data Out     -> Status       */
 	case STATE(STAT_STATUS, PHASE_DATAIN):  /* Data In      -> Status       */
 		fas216_stoptransfer(info);
@@ -1408,8 +1383,7 @@
 	case STATE(STAT_STATUS, PHASE_MSGOUT):  /* Message Out  -> Status       */
 	case STATE(STAT_STATUS, PHASE_COMMAND): /* Command      -> Status       */
 	case STATE(STAT_STATUS, PHASE_MSGIN):   /* Message In   -> Status       */
-	status:
-		outb(CMD_INITCMDCOMPLETE, REG_CMD(info));
+		fas216_cmd(info, CMD_INITCMDCOMPLETE);
 		info->scsi.phase = PHASE_STATUS;
 		return;
 
@@ -1419,32 +1393,59 @@
 	case STATE(STAT_MESGIN, PHASE_COMMAND):	/* Command	-> Message In	*/
 	case STATE(STAT_MESGIN, PHASE_SELSTEPS):/* Sel w/ steps -> Message In   */
 	case STATE(STAT_MESGIN, PHASE_MSGOUT):  /* Message Out  -> Message In   */
-		info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
-		outb(CMD_FLUSHFIFO, REG_CMD(info));
-		outb(CMD_TRANSFERINFO, REG_CMD(info));
+		info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
+		fas216_cmd(info, CMD_FLUSHFIFO);
+		fas216_cmd(info, CMD_TRANSFERINFO);
 		info->scsi.phase = PHASE_MSGIN;
 		return;
 
-						/* Reselmsgin   -> Message In   */
-	case STATE(STAT_MESGIN, PHASE_RECONNECTED):
 	case STATE(STAT_MESGIN, PHASE_MSGIN):
-		info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
-		outb(CMD_TRANSFERINFO, REG_CMD(info));
+		info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
+		fas216_cmd(info, CMD_TRANSFERINFO);
 		return;
 
-						/* Reselmsgin   -> Command      */
-	case STATE(STAT_COMMAND, PHASE_RECONNECTED):
-		fas216_finish_reconnect(info);
 	case STATE(STAT_COMMAND, PHASE_MSGOUT): /* Message Out  -> Command      */
 	case STATE(STAT_COMMAND, PHASE_MSGIN):  /* Message In   -> Command      */
 		fas216_send_command(info);
 		info->scsi.phase = PHASE_COMMAND;
 		return;
-						/* Selection    -> Message Out  */
+
+
+	/*
+	 * Selection    -> Message Out
+	 */
 	case STATE(STAT_MESGOUT, PHASE_SELECTION):
 		fas216_send_messageout(info, 1);
 		return;
-						/* Any          -> Message Out  */
+
+	/*
+	 * Message Out  -> Message Out
+	 */
+	case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
+	case STATE(STAT_MESGOUT, PHASE_MSGOUT):
+		/*
+		 * If we get another message out phase, this usually
+		 * means some parity error occurred.  Resend complete
+		 * set of messages.  If we have more than one byte to
+		 * send, we need to assert ATN again.
+		 */
+		if (info->device[info->SCpnt->target].parity_check) {
+			/*
+			 * We were testing... good, the device
+			 * supports parity checking.
+			 */
+			info->device[info->SCpnt->target].parity_check = 0;
+			info->device[info->SCpnt->target].parity_enabled = 1;
+			fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
+		}
+
+		if (msgqueue_msglength(&info->scsi.msgs) > 1)
+			fas216_cmd(info, CMD_SETATN);
+		/*FALLTHROUGH*/
+
+	/*
+	 * Any          -> Message Out
+	 */
 	case STATE(STAT_MESGOUT, PHASE_MSGOUT_EXPECT):
 		fas216_send_messageout(info, 0);
 		return;
@@ -1463,30 +1464,13 @@
 		printk(KERN_ERR "scsi%d.%c: "
 			"target trying to receive more command bytes\n",
 			info->host->host_no, fas216_target(info));
-		outb(CMD_SETATN, REG_CMD(info));
-		outb(15, REG_STCL(info));
-		outb(0, REG_STCM(info));
-		outb(0, REG_STCH(info));
-		outb(CMD_PADBYTES | CMD_WITHDMA, REG_CMD(info));
+		fas216_cmd(info, CMD_SETATN);
+		fas216_set_stc(info, 15);
+		fas216_cmd(info, CMD_PADBYTES | CMD_WITHDMA);
 		msgqueue_flush(&info->scsi.msgs);
 		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
 		info->scsi.phase = PHASE_MSGOUT_EXPECT;
 		return;
-
-						/* Selection    -> Message Out  */
-	case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
-	case STATE(STAT_MESGOUT, PHASE_MSGOUT): /* Message Out  -> Message Out  */
-		/* If we get another message out phase, this
-		 * usually means some parity error occurred.
-		 * Resend complete set of messages.  If we have
-		 * more than 1 byte to send, we need to assert
-		 * ATN again.
-		 */
-		if (msgqueue_msglength(&info->scsi.msgs) > 1)
-			outb(CMD_SETATN, REG_CMD(info));
-
-		fas216_send_messageout(info, 0);
-		return;
 	}
 
 	if (info->scsi.phase == PHASE_MSGIN_DISCONNECT) {
@@ -1494,11 +1478,11 @@
 			info->host->host_no, fas216_target(info),
 			fas216_bus_phase(stat));
 		msgqueue_flush(&info->scsi.msgs);
-		outb(CMD_SETATN, REG_CMD(info));
+		fas216_cmd(info, CMD_SETATN);
 		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
 		info->scsi.phase = PHASE_MSGOUT_EXPECT;
 		info->scsi.aborting = 1;
-		outb(CMD_TRANSFERINFO, REG_CMD(info));
+		fas216_cmd(info, CMD_TRANSFERINFO);
 		return;
 	}
 	printk(KERN_ERR "scsi%d.%c: bus phase %s after %s?\n",
@@ -1509,191 +1493,245 @@
 	return;
 
 bad_is:
-	printk("scsi%d.%c: bus service at step %d?\n",
-		info->host->host_no, fas216_target(info),
-		ssr & IS_BITS);
+	fas216_log(info, 0, "bus service at step %d?", is & IS_BITS);
+	fas216_dumpstate(info);
 	print_debug_list();
 
 	fas216_done(info, DID_ERROR);
 }
 
-/* Function: void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
- * Purpose : handle a function done interrupt from FAS216 chip
- * Params  : info - interface which caused function done interrupt
- *           stat - Status register contents
- *           ssr  - SCSI Status register contents
+/**
+ * fas216_funcdone_intr - handle a function done interrupt from FAS216 chip
+ * @info: interface which caused function done interrupt
+ * @stat: Status register contents
+ * @is: SCSI Status register contents
+ *
+ * Handle a function done interrupt from FAS216 chip
  */
-static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
+static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int is)
 {
-	int status, message;
+	unsigned int fifo_len = fas216_readb(info, REG_CFIS) & CFIS_CF;
 
 	fas216_checkmagic(info);
 
-#ifdef DEBUG_FUNCTIONDONE
-	printk("scsi%d.%c: function done: stat=%X ssr=%X phase=%02X\n",
-		info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase);
-#endif
+	fas216_log(info, LOG_FUNCTIONDONE,
+		   "function done: stat=%02x is=%02x phase=%02x",
+		   stat, is, info->scsi.phase);
+
 	switch (info->scsi.phase) {
 	case PHASE_STATUS:			/* status phase - read status and msg	*/
-		status = inb(REG_FF(info));
-		message = inb(REG_FF(info));
-		info->scsi.SCp.Message = message;
-		info->scsi.SCp.Status = status;
+		if (fifo_len != 2) {
+			fas216_log(info, 0, "odd number of bytes in FIFO: %d", fifo_len);
+		}
+		/*
+		 * Read status then message byte.
+		 */
+		info->scsi.SCp.Status = fas216_readb(info, REG_FF);
+		info->scsi.SCp.Message = fas216_readb(info, REG_FF);
 		info->scsi.phase = PHASE_DONE;
-		outb(CMD_MSGACCEPTED, REG_CMD(info));
+		fas216_cmd(info, CMD_MSGACCEPTED);
+		break;
+
+	case PHASE_IDLE:
+	case PHASE_SELECTION:
+	case PHASE_SELSTEPS:
 		break;
 
-	case PHASE_IDLE:			/* reselected?				*/
 	case PHASE_MSGIN:			/* message in phase			*/
-	case PHASE_RECONNECTED:			/* reconnected command			*/
 		if ((stat & STAT_BUSMASK) == STAT_MESGIN) {
-			info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
+			info->scsi.msgin_fifo = fifo_len;
 			fas216_message(info);
 			break;
 		}
 
 	default:
-		printk("scsi%d.%c: internal phase %s for function done?"
-			"  What do I do with this?\n",
-			info->host->host_no, fas216_target(info),
+		fas216_log(info, 0, "internal phase %s for function done?"
+			"  What do I do with this?",
 			fas216_drv_phase(info));
 	}
 }
 
-/* Function: void fas216_intr(struct Scsi_Host *instance)
- * Purpose : handle interrupts from the interface to progress a command
- * Params  : instance - interface to service
+static void fas216_bus_reset(FAS216_Info *info)
+{
+	neg_t sync_state;
+	int i;
+
+	msgqueue_flush(&info->scsi.msgs);
+
+	sync_state = neg_invalid;
+
+#ifdef SCSI2_SYNC
+	if (info->ifcfg.capabilities & (FASCAP_DMA|FASCAP_PSEUDODMA))
+		sync_state = neg_wait;
+#endif
+
+	info->scsi.phase = PHASE_IDLE;
+	info->SCpnt = NULL; /* bug! */
+	memset(&info->scsi.SCp, 0, sizeof(info->scsi.SCp));
+
+	for (i = 0; i < 8; i++) {
+		info->device[i].disconnect_ok	= info->ifcfg.disconnect_ok;
+		info->device[i].sync_state	= sync_state;
+		info->device[i].period		= info->ifcfg.asyncperiod / 4;
+		info->device[i].stp		= info->scsi.async_stp;
+		info->device[i].sof		= 0;
+		info->device[i].wide_xfer	= 0;
+	}
+
+	info->rst_bus_status = 1;
+	wake_up(&info->eh_wait);
+}
+
+/**
+ * fas216_intr - handle interrupts to progress a command
+ * @info: interface to service
+ *
+ * Handle interrupts from the interface to progress a command
  */
-void fas216_intr(struct Scsi_Host *instance)
+void fas216_intr(FAS216_Info *info)
 {
-	FAS216_Info *info = (FAS216_Info *)instance->hostdata;
-	unsigned char isr, ssr, stat;
+	unsigned char inst, is, stat;
 
 	fas216_checkmagic(info);
 
-	stat = inb(REG_STAT(info));
-	ssr = inb(REG_IS(info));
-	isr = inb(REG_INST(info));
+	stat = fas216_readb(info, REG_STAT);
+	is = fas216_readb(info, REG_IS);
+	inst = fas216_readb(info, REG_INST);
 
-	add_debug_list(stat, ssr, isr, info->scsi.phase);
+	add_debug_list(stat, is, inst, info->scsi.phase);
 
 	if (stat & STAT_INT) {
-		if (isr & INST_BUSRESET) {
-			printk(KERN_DEBUG "scsi%d.H: bus reset detected\n", instance->host_no);
-			scsi_report_bus_reset(instance, 0);
-		} else if (isr & INST_ILLEGALCMD) {
-			printk(KERN_CRIT "scsi%d.H: illegal command given\n", instance->host_no);
+		if (inst & INST_BUSRESET) {
+			fas216_log(info, 0, "bus reset detected");
+			fas216_bus_reset(info);
+			scsi_report_bus_reset(info->host, 0);
+		} else if (inst & INST_ILLEGALCMD) {
+			fas216_log(info, LOG_ERROR, "illegal command given\n");
 			fas216_dumpstate(info);
-		} else if (isr & INST_DISCONNECT)
+			print_debug_list();
+		} else if (inst & INST_DISCONNECT)
 			fas216_disconnect_intr(info);
-		else if (isr & INST_RESELECTED)		/* reselected			*/
+		else if (inst & INST_RESELECTED)	/* reselected			*/
 			fas216_reselected_intr(info);
-		else if (isr & INST_BUSSERVICE)		/* bus service request		*/
-			fas216_busservice_intr(info, stat, ssr);
-		else if (isr & INST_FUNCDONE)		/* function done		*/
-			fas216_funcdone_intr(info, stat, ssr);
+		else if (inst & INST_BUSSERVICE)	/* bus service request		*/
+			fas216_busservice_intr(info, stat, is);
+		else if (inst & INST_FUNCDONE)		/* function done		*/
+			fas216_funcdone_intr(info, stat, is);
 		else
-		    	printk("scsi%d.%c: unknown interrupt received:"
-				" phase %s isr %02X ssr %02X stat %02X\n",
-				instance->host_no, fas216_target(info),
-				fas216_drv_phase(info), isr, ssr, stat);
+		    	fas216_log(info, 0, "unknown interrupt received:"
+				" phase %s inst %02X is %02X stat %02X",
+				fas216_drv_phase(info), inst, is, stat);
 	}
 }
 
-/* Function: void fas216_kick(FAS216_Info *info)
- * Purpose : kick a command to the interface - interface should be idle
- * Params  : info - our host interface to kick
- * Notes   : Interrupts are always disabled!
- */
-static void fas216_kick(FAS216_Info *info)
+static void __fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
 {
-	Scsi_Cmnd *SCpnt = NULL;
-	int tot_msglen, from_queue = 0, disconnect_ok;
+	int tot_msglen;
 
-	fas216_checkmagic(info);
+	/* following what the ESP driver says */
+	fas216_set_stc(info, 0);
+	fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
 
-	/*
-	 * Obtain the next command to process.
-	 */
-	do {
-		if (info->reqSCpnt) {
-			SCpnt = info->reqSCpnt;
-			info->reqSCpnt = NULL;
-			break;
-		}
+	/* flush FIFO */
+	fas216_cmd(info, CMD_FLUSHFIFO);
 
-		if (info->origSCpnt) {
-			SCpnt = info->origSCpnt;
-			info->origSCpnt = NULL;
-			break;
+	/* load bus-id and timeout */
+	fas216_writeb(info, REG_SDID, BUSID(SCpnt->target));
+	fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
+
+	/* synchronous transfers */
+	fas216_set_sync(info, SCpnt->target);
+
+	tot_msglen = msgqueue_msglength(&info->scsi.msgs);
+
+#ifdef DEBUG_MESSAGES
+	{
+		struct message *msg;
+		int msgnr = 0, i;
+
+		printk("scsi%d.%c: message out: ",
+			info->host->host_no, '0' + SCpnt->target);
+		while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
+			printk("{ ");
+			for (i = 0; i < msg->length; i++)
+				printk("%02x ", msg->msg[i]);
+			printk("} ");
 		}
+		printk("\n");
+	}
+#endif
 
-		/* retrieve next command */
-		if (!SCpnt) {
-			SCpnt = queue_remove_exclude(&info->queues.issue,
-						     info->busyluns);
-			from_queue = 1;
-			break;
+	if (tot_msglen == 1 || tot_msglen == 3) {
+		/*
+		 * We have an easy message length to send...
+		 */
+		struct message *msg;
+		int msgnr = 0, i;
+
+		info->scsi.phase = PHASE_SELSTEPS;
+
+		/* load message bytes */
+		while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
+			for (i = 0; i < msg->length; i++)
+				fas216_writeb(info, REG_FF, msg->msg[i]);
+			msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
 		}
-	} while (0);
 
-	if (!SCpnt) /* no command pending - just exit */
-		return;
+		/* load command */
+		for (i = 0; i < SCpnt->cmd_len; i++)
+			fas216_writeb(info, REG_FF, SCpnt->cmnd[i]);
 
-	if (info->scsi.disconnectable && info->SCpnt) {
-		queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
-		info->scsi.disconnectable = 0;
-		info->SCpnt = NULL;
-		printk("scsi%d.%c: moved command to disconnected queue\n",
-			info->host->host_no, fas216_target(info));
+		if (tot_msglen == 1)
+			fas216_cmd(info, CMD_SELECTATN);
+		else
+			fas216_cmd(info, CMD_SELECTATN3);
+	} else {
+		/*
+		 * We have an unusual number of message bytes to send.
+		 *  Load first byte into fifo, and issue SELECT with ATN and
+		 *  stop steps.
+		 */
+		struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
+
+		fas216_writeb(info, REG_FF, msg->msg[0]);
+		msg->fifo = 1;
+
+		fas216_cmd(info, CMD_SELECTATNSTOP);
 	}
+}
+
+/*
+ * Decide whether we need to perform a parity test on this device.
+ * Can also be used to force parity error conditions during initial
+ * information transfer phase (message out) for test purposes.
+ */
+static int parity_test(FAS216_Info *info, int target)
+{
+#if 0
+	if (target == 3) {
+		info->device[target].parity_check = 0;
+		return 1;
+	}
+#endif
+	return info->device[target].parity_check;
+}
+
+static void fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+{
+	int disconnect_ok;
 
 	/*
 	 * claim host busy
 	 */
 	info->scsi.phase = PHASE_SELECTION;
-	info->SCpnt = SCpnt;
 	info->scsi.SCp = SCpnt->SCp;
+	info->SCpnt = SCpnt;
 	info->dma.transfer_type = fasdma_none;
 
-#ifdef DEBUG_CONNECT
-	printk("scsi%d.%c: starting cmd %02X",
-		info->host->host_no, '0' + SCpnt->target,
-		SCpnt->cmnd[0]);
-#endif
-
-	if (from_queue) {
-#ifdef SCSI2_TAG
-		/*
-		 * tagged queuing - allocate a new tag to this command
-		 */
-		if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE &&
-		    SCpnt->cmnd[0] != INQUIRY) {
-		    SCpnt->device->current_tag += 1;
-			if (SCpnt->device->current_tag == 0)
-			    SCpnt->device->current_tag = 1;
-				SCpnt->tag = SCpnt->device->current_tag;
-		} else
-#endif
-			set_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
-
-		info->stats.removes += 1;
-		switch (SCpnt->cmnd[0]) {
-		case WRITE_6:
-		case WRITE_10:
-		case WRITE_12:
-			info->stats.writes += 1;
-			break;
-		case READ_6:
-		case READ_10:
-		case READ_12:
-			info->stats.reads += 1;
-			break;
-		default:
-			info->stats.miscs += 1;
-			break;
-		}
-	}
+	if (parity_test(info, SCpnt->target))
+		fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_PTE);
+	else
+		fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
 
 	/*
 	 * Don't allow request sense commands to disconnect.
@@ -1714,15 +1752,6 @@
 		msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, SCpnt->tag);
 
 	do {
-#ifdef SCSI2_WIDE
-		if (info->device[SCpnt->target].wide_state == neg_wait) {
-			info->device[SCpnt->target].wide_state = neg_inprogress;
-			msgqueue_addmsg(&info->scsi.msgs, 4,
-					EXTENDED_MESSAGE, 2, EXTENDED_WDTR,
-					info->ifcfg.wide_max_size);
-			break;
-		}
-#endif
 #ifdef SCSI2_SYNC
 		if ((info->device[SCpnt->target].sync_state == neg_wait ||
 		     info->device[SCpnt->target].sync_state == neg_complete) &&
@@ -1738,100 +1767,202 @@
 #endif
 	} while (0);
 
+	__fas216_start_command(info, SCpnt);
+}
+
+static void fas216_allocate_tag(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+{
+#ifdef SCSI2_TAG
+	/*
+	 * tagged queuing - allocate a new tag to this command
+	 */
+	if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE &&
+	    SCpnt->cmnd[0] != INQUIRY) {
+	    SCpnt->device->current_tag += 1;
+		if (SCpnt->device->current_tag == 0)
+		    SCpnt->device->current_tag = 1;
+			SCpnt->tag = SCpnt->device->current_tag;
+	} else
+#endif
+		set_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
+
+	info->stats.removes += 1;
+	switch (SCpnt->cmnd[0]) {
+	case WRITE_6:
+	case WRITE_10:
+	case WRITE_12:
+		info->stats.writes += 1;
+		break;
+	case READ_6:
+	case READ_10:
+	case READ_12:
+		info->stats.reads += 1;
+		break;
+	default:
+		info->stats.miscs += 1;
+		break;
+	}
+}
+
+static void fas216_do_bus_device_reset(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+{
+	struct message *msg;
+
+	/*
+	 * claim host busy
+	 */
+	info->scsi.phase = PHASE_SELECTION;
+	info->scsi.SCp = SCpnt->SCp;
+	info->SCpnt = SCpnt;
+	info->dma.transfer_type = fasdma_none;
+
+	fas216_log(info, LOG_ERROR, "sending bus device reset");
+
+	msgqueue_flush(&info->scsi.msgs);
+	msgqueue_addmsg(&info->scsi.msgs, 1, BUS_DEVICE_RESET);
+
 	/* following what the ESP driver says */
-	outb(0, REG_STCL(info));
-	outb(0, REG_STCM(info));
-	outb(0, REG_STCH(info));
-	outb(CMD_NOP | CMD_WITHDMA, REG_CMD(info));
+	fas216_set_stc(info, 0);
+	fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
 
 	/* flush FIFO */
-	outb(CMD_FLUSHFIFO, REG_CMD(info));
+	fas216_cmd(info, CMD_FLUSHFIFO);
 
 	/* load bus-id and timeout */
-	outb(BUSID(SCpnt->target), REG_SDID(info));
-	outb(info->ifcfg.select_timeout, REG_STIM(info));
+	fas216_writeb(info, REG_SDID, BUSID(SCpnt->target));
+	fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
 
 	/* synchronous transfers */
 	fas216_set_sync(info, SCpnt->target);
 
-	tot_msglen = msgqueue_msglength(&info->scsi.msgs);
+	msg = msgqueue_getmsg(&info->scsi.msgs, 0);
 
-#ifdef DEBUG_MESSAGES
-	{
-		struct message *msg;
-		int msgnr = 0, i;
+	fas216_writeb(info, REG_FF, BUS_DEVICE_RESET);
+	msg->fifo = 1;
 
-		printk("scsi%d.%c: message out: ",
-			info->host->host_no, '0' + SCpnt->target);
-		while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
-			printk("{ ");
-			for (i = 0; i < msg->length; i++)
-				printk("%02x ", msg->msg[i]);
-			printk("} ");
+	fas216_cmd(info, CMD_SELECTATNSTOP);
+}
+
+/**
+ * fas216_kick - kick a command to the interface
+ * @info: our host interface to kick
+ *
+ * Kick a command to the interface, interface should be idle.
+ * Notes: Interrupts are always disabled!
+ */
+static void fas216_kick(FAS216_Info *info)
+{
+	Scsi_Cmnd *SCpnt = NULL;
+#define TYPE_OTHER	0
+#define TYPE_RESET	1
+#define TYPE_QUEUE	2
+	int where_from = TYPE_OTHER;
+
+	fas216_checkmagic(info);
+
+	/*
+	 * Obtain the next command to process.
+	 */
+	do {
+		if (info->rstSCpnt) {
+			SCpnt = info->rstSCpnt;
+			/* don't remove it */
+			where_from = TYPE_RESET;
+			break;
 		}
-		printk("\n");
-	}
-#endif
 
-	if (tot_msglen == 1 || tot_msglen == 3) {
-		/*
-		 * We have an easy message length to send...
-		 */
-		struct message *msg;
-		int msgnr = 0, i;
+		if (info->reqSCpnt) {
+			SCpnt = info->reqSCpnt;
+			info->reqSCpnt = NULL;
+			break;
+		}
 
-		info->scsi.phase = PHASE_SELSTEPS;
+		if (info->origSCpnt) {
+			SCpnt = info->origSCpnt;
+			info->origSCpnt = NULL;
+			break;
+		}
 
-		/* load message bytes */
-		while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
-			for (i = 0; i < msg->length; i++)
-				outb(msg->msg[i], REG_FF(info));
-			msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
+		/* retrieve next command */
+		if (!SCpnt) {
+			SCpnt = queue_remove_exclude(&info->queues.issue,
+						     info->busyluns);
+			where_from = TYPE_QUEUE;
+			break;
 		}
+	} while (0);
 
-		/* load command */
-		for (i = 0; i < SCpnt->cmd_len; i++)
-			outb(SCpnt->cmnd[i], REG_FF(info));
-
-		if (tot_msglen == 1)
-			outb(CMD_SELECTATN, REG_CMD(info));
-		else
-			outb(CMD_SELECTATN3, REG_CMD(info));
-	} else {
+	if (!SCpnt) {
 		/*
-		 * We have an unusual number of message bytes to send.
-		 *  Load first byte into fifo, and issue SELECT with ATN and
-		 *  stop steps.
+		 * no command pending, so enable reselection.
 		 */
-		struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
+		fas216_cmd(info, CMD_ENABLESEL);
+		return;
+	}
 
-		outb(msg->msg[0], REG_FF(info));
-		msg->fifo = 1;
+	/*
+	 * We're going to start a command, so disable reselection
+	 */
+	fas216_cmd(info, CMD_DISABLESEL);
+
+	if (info->scsi.disconnectable && info->SCpnt) {
+		fas216_log(info, LOG_CONNECT,
+			"moved command for %d to disconnected queue",
+			info->SCpnt->target);
+		queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
+		info->scsi.disconnectable = 0;
+		info->SCpnt = NULL;
+	}
 
-		outb(CMD_SELECTATNSTOP, REG_CMD(info));
+	fas216_log_command(info, LOG_CONNECT | LOG_MESSAGES, SCpnt, "starting ");
+
+	switch (where_from) {
+	case TYPE_QUEUE:
+		fas216_allocate_tag(info, SCpnt);
+	case TYPE_OTHER:
+		fas216_start_command(info, SCpnt);
+		break;
+	case TYPE_RESET:
+		fas216_do_bus_device_reset(info, SCpnt);
+		break;
 	}
 
-#ifdef DEBUG_CONNECT
-	printk(", data pointers [%p, %X]\n",
+	fas216_log(info, LOG_CONNECT, "select: data pointers [%p, %X]",
 		info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
-#endif
-	/* should now get either DISCONNECT or (FUNCTION DONE with BUS SERVICE) intr */
+
+	/*
+	 * should now get either DISCONNECT or
+	 * (FUNCTION DONE with BUS SERVICE) interrupt
+	 */
+}
+
+/*
+ * Clean up from issuing a BUS DEVICE RESET message to a device.
+ */
+static void
+fas216_devicereset_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
+{
+	fas216_log(info, LOG_ERROR, "fas216 device reset complete");
+
+	info->rstSCpnt = NULL;
+	info->rst_dev_status = 1;
+	wake_up(&info->eh_wait);
 }
 
-/* Function: void fas216_rq_sns_done(info, SCpnt, result)
- * Purpose : Finish processing automatic request sense command
- * Params  : info   - interface that completed
- *	     SCpnt  - command that completed
- *	     result - driver byte of result
+/**
+ * fas216_rq_sns_done - Finish processing automatic request sense command
+ * @info: interface that completed
+ * @SCpnt: command that completed
+ * @result: driver byte of result
+ *
+ * Finish processing automatic request sense command
  */
 static void
 fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
 {
-#ifdef DEBUG_CONNECT
-	printk("scsi%d.%c: request sense complete, result=%04X%02X%02X\n",
-		info->host->host_no, '0' + SCpnt->target, result,
-		SCpnt->SCp.Message, SCpnt->SCp.Status);
-#endif
+	fas216_log_target(info, LOG_CONNECT, SCpnt->target,
+		   "request sense complete, result=0x%04x%02x%02x",
+		   result, SCpnt->SCp.Message, SCpnt->SCp.Status);
 
 	if (result != DID_OK || SCpnt->SCp.Status != GOOD)
 		/*
@@ -1840,7 +1971,8 @@
 		 * confuse the higher levels.
 		 */
 		memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
-
+//printk("scsi%d.%c: sense buffer: ", info->host->host_no, '0' + SCpnt->target);
+//{ int i; for (i = 0; i < 32; i++) printk("%02x ", SCpnt->sense_buffer[i]); printk("\n"); }
 	/*
 	 * Note that we don't set SCpnt->result, since that should
 	 * reflect the status of the command that we were asked by
@@ -1850,11 +1982,13 @@
 	SCpnt->scsi_done(SCpnt);
 }
 
-/* Function: void fas216_std_done(info, SCpnt, result)
- * Purpose : Finish processing of standard command
- * Params  : info   - interface that completed
- *	     SCpnt  - command that completed
- *	     result - driver byte of result
+/**
+ * fas216_std_done - finish processing of standard command
+ * @info: interface that completed
+ * @SCpnt: command that completed
+ * @result: driver byte of result
+ *
+ * Finish processing of standard command
  */
 static void
 fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
@@ -1864,31 +1998,29 @@
 	SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 |
 			info->scsi.SCp.Status;
 
-#ifdef DEBUG_CONNECT
-	printk("scsi%d.%c: command complete, result=%08X, command=",
-		info->host->host_no, '0' + SCpnt->target, SCpnt->result);
-	print_command(SCpnt->cmnd);
-#endif
+	fas216_log_command(info, LOG_CONNECT, SCpnt,
+		"command complete, result=0x%08x ", SCpnt->result);
 
 	/*
-	 * If the driver detected an error, or the command
-	 * was request sense, then we're all done.
+	 * If the driver detected an error, we're all done.
 	 */
-	if (result != DID_OK || SCpnt->cmnd[0] == REQUEST_SENSE)
+	if (host_byte(SCpnt->result) != DID_OK ||
+	    msg_byte(SCpnt->result) != COMMAND_COMPLETE)
 		goto done;
 
 	/*
-	 * If the command returned CHECK_CONDITION status,
-	 * request the sense information.
+	 * If the command returned CHECK_CONDITION or COMMAND_TERMINATED
+	 * status, request the sense information.
 	 */
-	if (info->scsi.SCp.Status == CHECK_CONDITION)
+	if (status_byte(SCpnt->result) == CHECK_CONDITION ||
+	    status_byte(SCpnt->result) == COMMAND_TERMINATED)
 		goto request_sense;
 
 	/*
 	 * If the command did not complete with GOOD status,
 	 * we are all done here.
 	 */
-	if (info->scsi.SCp.Status != GOOD)
+	if (status_byte(SCpnt->result) != GOOD)
 		goto done;
 
 	/*
@@ -1902,24 +2034,38 @@
 		switch (SCpnt->cmnd[0]) {
 		case INQUIRY:
 		case START_STOP:
-//		case READ_CAPACITY:
 		case MODE_SENSE:
 			break;
 
 		default:
 			printk(KERN_ERR "scsi%d.%c: incomplete data transfer "
-				"detected: res=%08X ptr=%p len=%X command=",
+				"detected: res=%08X ptr=%p len=%X CDB: ",
 				info->host->host_no, '0' + SCpnt->target,
 				SCpnt->result, info->scsi.SCp.ptr,
 				info->scsi.SCp.this_residual);
 			print_command(SCpnt->cmnd);
+			SCpnt->result &= ~(255 << 16);
+			SCpnt->result |= DID_BAD_TARGET << 16;
+			goto request_sense;
 		}
 	}
 
-done:	SCpnt->scsi_done(SCpnt);
-	return;
+done:
+	if (SCpnt->scsi_done) {
+		SCpnt->scsi_done(SCpnt);
+		return;
+	}
+
+	panic("scsi%d.H: null scsi_done function in fas216_done",
+		info->host->host_no);
+
 
 request_sense:
+	if (SCpnt->cmnd[0] == REQUEST_SENSE)
+		goto done;
+
+	fas216_log_target(info, LOG_CONNECT, SCpnt->target,
+			  "requesting sense");
 	memset(SCpnt->cmnd, 0, sizeof (SCpnt->cmnd));
 	SCpnt->cmnd[0] = REQUEST_SENSE;
 	SCpnt->cmnd[1] = SCpnt->lun << 5;
@@ -1931,6 +2077,7 @@
 	SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer);
 	SCpnt->SCp.Message = 0;
 	SCpnt->SCp.Status = 0;
+	SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer);
 	SCpnt->sc_data_direction = SCSI_DATA_READ;
 	SCpnt->use_sg = 0;
 	SCpnt->tag = 0;
@@ -1947,15 +2094,18 @@
 	info->reqSCpnt = SCpnt;
 }
 
-/* Function: void fas216_done(FAS216_Info *info, unsigned int result)
- * Purpose : complete processing for current command
- * Params  : info   - interface that completed
- *	     result - driver byte of result
+/**
+ * fas216_done - complete processing for current command
+ * @info: interface that completed
+ * @result: driver byte of result
+ *
+ * Complete processing for current command
  */
 static void fas216_done(FAS216_Info *info, unsigned int result)
 {
 	void (*fn)(FAS216_Info *, Scsi_Cmnd *, unsigned int);
 	Scsi_Cmnd *SCpnt;
+	unsigned long flags;
 
 	fas216_checkmagic(info);
 
@@ -1966,12 +2116,8 @@
 	info->SCpnt = NULL;
     	info->scsi.phase = PHASE_IDLE;
 
-	if (!SCpnt->scsi_done)
-		goto no_done;
-
 	if (info->scsi.aborting) {
-		printk("scsi%d.%c: uncaught abort - returning DID_ABORT\n",
-			info->host->host_no, fas216_target(info));
+		fas216_log(info, 0, "uncaught abort - returning DID_ABORT");
 		result = DID_ABORT;
 		info->scsi.aborting = 0;
 	}
@@ -1982,7 +2128,7 @@
 	 */
 	if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
 		printk("scsi%d.%c: zero bytes left to transfer, but "
-		       "buffer pointer still valid: ptr=%p len=%08x command=",
+		       "buffer pointer still valid: ptr=%p len=%08x CDB: ",
 		       info->host->host_no, '0' + SCpnt->target,
 		       info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
 		info->scsi.SCp.ptr = NULL;
@@ -1994,29 +2140,33 @@
 	 * the sense information, fas216_kick will re-assert the busy
 	 * status.
 	 */
+	info->device[SCpnt->target].parity_check = 0;
 	clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
 
 	fn = (void (*)(FAS216_Info *, Scsi_Cmnd *, unsigned int))SCpnt->host_scribble;
 	fn(info, SCpnt, result);
 
-	if (info->scsi.irq != NO_IRQ)
-		fas216_kick(info);
+	if (info->scsi.irq != NO_IRQ) {
+		spin_lock_irqsave(&info->host_lock, flags);
+		if (info->scsi.phase == PHASE_IDLE)
+			fas216_kick(info);
+		spin_unlock_irqrestore(&info->host_lock, flags);
+	}
 	return;
 
 no_command:
 	panic("scsi%d.H: null command in fas216_done",
 		info->host->host_no);
-no_done:
-	panic("scsi%d.H: null scsi_done function in fas216_done",
-		info->host->host_no);
 }
 
-/* Function: int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
- * Purpose : queue a command for adapter to process.
- * Params  : SCpnt - Command to queue
- *	     done  - done function to call once command is complete
- * Returns : 0 - success, else error
- * Notes   : io_request_lock is held, interrupts are disabled.
+/**
+ * fas216_queue_command - queue a command for adapter to process.
+ * @SCpnt: Command to queue
+ * @done: done function to call once command is complete
+ *
+ * Queue a command for adapter to process.
+ * Returns: 0 on success, else error.
+ * Notes: io_request_lock is held, interrupts are disabled.
  */
 int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
@@ -2025,61 +2175,20 @@
 
 	fas216_checkmagic(info);
 
-#ifdef DEBUG_CONNECT
-	printk("scsi%d.%c: received queuable command (%p) %02X\n",
-		SCpnt->host->host_no, '0' + SCpnt->target,
-		SCpnt, SCpnt->cmnd[0]);
-#endif
+	fas216_log_command(info, LOG_CONNECT, SCpnt,
+			   "received command (%p) ", SCpnt);
 
 	SCpnt->scsi_done = done;
 	SCpnt->host_scribble = (void *)fas216_std_done;
 	SCpnt->result = 0;
-	SCpnt->SCp.Message = 0;
-	SCpnt->SCp.Status = 0;
-
-	if (SCpnt->use_sg) {
-		unsigned long len = 0;
-		int buf;
-
-		SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
-		SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
-		SCpnt->SCp.ptr = (char *) SCpnt->SCp.buffer->address;
-		SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
-		/*
-		 * Calculate correct buffer length.  Some commands
-		 * come in with the wrong request_bufflen.
-		 */
-		for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
-			len += SCpnt->SCp.buffer[buf].length;
-
-		if (SCpnt->request_bufflen != len)
-			printk(KERN_WARNING "scsi%d.%c: bad request buffer "
-			       "length %d, should be %ld\n", info->host->host_no,
-			       '0' + SCpnt->target, SCpnt->request_bufflen, len);
-		SCpnt->request_bufflen = len;
-	} else {
-		SCpnt->SCp.buffer = NULL;
-		SCpnt->SCp.buffers_residual = 0;
-		SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
-		SCpnt->SCp.this_residual = SCpnt->request_bufflen;
-	}
 
-	/*
-	 * If the upper SCSI layers pass a buffer, but zero length,
-	 * we aren't interested in the buffer pointer.
-	 */
-	if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
-#if 0
-		printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
-		       "command ", info->host->host_no, '0' + SCpnt->target);
-		print_command(SCpnt->cmnd);
-#endif
-		SCpnt->SCp.ptr = NULL;
-	}
+	init_SCp(SCpnt);
 
 	info->stats.queues += 1;
 	SCpnt->tag = 0;
 
+	spin_lock(&info->host_lock);
+
 	/*
 	 * Add command into execute queue and let it complete under
 	 * whatever scheme we're using.
@@ -2090,15 +2199,21 @@
 	 * If we successfully added the command,
 	 * kick the interface to get it moving.
 	 */
-	if (result == 0 && (!info->SCpnt || info->scsi.disconnectable))
+	if (result == 0 && info->scsi.phase == PHASE_IDLE)
 		fas216_kick(info);
+	spin_unlock(&info->host_lock);
+
+	fas216_log_target(info, LOG_CONNECT, -1, "queue %s",
+		result ? "failure" : "success");
 
 	return result;
 }
 
-/* Function: void fas216_internal_done(Scsi_Cmnd *SCpnt)
- * Purpose : trigger restart of a waiting thread in fas216_command
- * Params  : SCpnt - Command to wake
+/**
+ * fas216_internal_done - trigger restart of a waiting thread in fas216_command
+ * @SCpnt: Command to wake
+ *
+ * Trigger restart of a waiting thread in fas216_command
  */
 static void fas216_internal_done(Scsi_Cmnd *SCpnt)
 {
@@ -2109,11 +2224,13 @@
 	info->internal_done = 1;
 }
 
-/* Function: int fas216_command(Scsi_Cmnd *SCpnt)
- * Purpose : queue a command for adapter to process.
- * Params  : SCpnt - Command to queue
- * Returns : scsi result code
- * Notes   : io_request_lock is held, interrupts are disabled.
+/**
+ * fas216_command - queue a command for adapter to process.
+ * @SCpnt: Command to queue
+ *
+ * Queue a command for adapter to process.
+ * Returns: scsi result code.
+ * Notes: io_request_lock is held, interrupts are disabled.
  */
 int fas216_command(Scsi_Cmnd *SCpnt)
 {
@@ -2125,8 +2242,7 @@
 	 * We should only be using this if we don't have an interrupt.
 	 * Provide some "incentive" to use the queueing code.
 	 */
-	if (info->scsi.irq != NO_IRQ)
-		BUG();
+	BUG_ON(info->scsi.irq != NO_IRQ);
 
 	info->internal_done = 0;
 	fas216_queue_command(SCpnt, fas216_internal_done);
@@ -2148,9 +2264,9 @@
 		 * and go to sleep if we know that the device is going
 		 * to be some time (eg, disconnected).
 		 */
-		if (inb(REG_STAT(info)) & STAT_INT) {
+		if (fas216_readb(info, REG_STAT) & STAT_INT) {
 			spin_lock_irq(&io_request_lock);
-			fas216_intr(info->host);
+			fas216_intr(info);
 			spin_unlock_irq(&io_request_lock);
 		}
 	}
@@ -2160,23 +2276,42 @@
 	return SCpnt->result;
 }
 
-enum res_abort {
-	res_failed,		/* unable to abort		*/
+/*
+ * Error handler timeout function.  Indicate that we timed out,
+ * and wake up any error handler process so it can continue.
+ */
+static void fas216_eh_timer(unsigned long data)
+{
+	FAS216_Info *info = (FAS216_Info *)data;
+
+	fas216_log(info, LOG_ERROR, "error handling timed out\n");
+
+	del_timer(&info->eh_timer);
+
+	if (info->rst_bus_status == 0)
+		info->rst_bus_status = -1;
+	if (info->rst_dev_status == 0)
+		info->rst_dev_status = -1;
+
+	wake_up(&info->eh_wait);
+}
+
+enum res_find {
+	res_failed,		/* not found			*/
 	res_success,		/* command on issue queue	*/
-	res_success_clear,	/* command marked tgt/lun busy	*/
 	res_hw_abort		/* command on disconnected dev	*/
 };
 
-/*
- * Prototype: enum res_abort fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
- * Purpose  : decide how to abort a command
- * Params   : SCpnt - command to abort
- * Returns  : abort status
+/**
+ * fas216_do_abort - decide how to abort a command
+ * @SCpnt: command to abort
+ *
+ * Decide how to abort a command.
+ * Returns: abort status
  */
-static enum res_abort
-fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static enum res_find fas216_find_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
 {
-	enum res_abort res = res_failed;
+	enum res_find res = res_failed;
 
 	if (queue_remove_cmd(&info->queues.issue, SCpnt)) {
 		/*
@@ -2224,19 +2359,22 @@
 		 * been set.
 		 */
 		info->origSCpnt = NULL;
+		clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
 		printk("waiting for execution ");
-		res = res_success_clear;
+		res = res_success;
 	} else
 		printk("unknown ");
 
 	return res;
 }
 
-/* Function: int fas216_eh_abort(Scsi_Cmnd *SCpnt)
- * Purpose : abort this command
- * Params  : SCpnt - command to abort
- * Returns : FAILED if unable to abort
- * Notes   : io_request_lock is taken, and irqs are disabled
+/**
+ * fas216_eh_abort - abort this command
+ * @SCpnt: command to abort
+ *
+ * Abort this command.
+ * Returns: FAILED if unable to abort
+ * Notes: io_request_lock is taken, and irqs are disabled
  */
 int fas216_eh_abort(Scsi_Cmnd *SCpnt)
 {
@@ -2247,22 +2385,15 @@
 
 	info->stats.aborts += 1;
 
+	printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no);
+	print_command(SCpnt->data_cmnd);
+
 	print_debug_list();
 	fas216_dumpstate(info);
-	fas216_dumpinfo(info);
 
-	printk(KERN_WARNING "scsi%d: abort ", info->host->host_no);
-
-	switch (fas216_do_abort(info, SCpnt)) {
-	/*
-	 * We managed to find the command and cleared it out.
-	 * We do not expect the command to be executing on the
-	 * target, but we have set the busylun bit.
-	 */
-	case res_success_clear:
-		printk("clear ");
-		clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
+	printk(KERN_WARNING "scsi%d: abort %p ", info->host->host_no, SCpnt);
 
+	switch (fas216_find_command(info, SCpnt)) {
 	/*
 	 * We found the command, and cleared it out.  Either
 	 * the command is still known to be executing on the
@@ -2293,155 +2424,195 @@
 	return result;
 }
 
-/* Function: void fas216_reset_state(FAS216_Info *info)
- * Purpose : Initialise driver internal state
- * Params  : info - state to initialise
+/**
+ * fas216_eh_device_reset - Reset the device associated with this command
+ * @SCpnt: command specifing device to reset
+ *
+ * Reset the device associated with this command.
+ * Returns: FAILED if unable to reset.
+ * Notes: We won't be re-entered, so we'll only have one device
+ * reset on the go at one time.
  */
-static void fas216_reset_state(FAS216_Info *info)
+int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
 {
-	neg_t sync_state, wide_state;
-	int i;
+	FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
+	unsigned long flags;
+	int i, res = FAILED, target = SCpnt->target;
 
-	fas216_checkmagic(info);
+	fas216_log(info, LOG_ERROR, "device reset for target %d", target);
 
-	/*
-	 * Clear out all stale info in our state structure
-	 */
-	memset(info->busyluns, 0, sizeof(info->busyluns));
-	msgqueue_flush(&info->scsi.msgs);
-	info->scsi.reconnected.target = 0;
-	info->scsi.reconnected.lun = 0;
-	info->scsi.reconnected.tag = 0;
-	info->scsi.disconnectable = 0;
-	info->scsi.aborting = 0;
-	info->scsi.phase = PHASE_IDLE;
-	info->scsi.async_stp =
-			fas216_syncperiod(info, info->ifcfg.asyncperiod);
+	spin_lock_irqsave(&info->host_lock, flags);
 
-	if (info->ifcfg.wide_max_size == 0)
-		wide_state = neg_invalid;
-	else
-#ifdef SCSI2_WIDE
-		wide_state = neg_wait;
-#else
-		wide_state = neg_invalid;
-#endif
+	do {
+		/*
+		 * If we are currently connected to a device, and
+		 * it is the device we want to reset, there is
+		 * nothing we can do here.  Chances are it is stuck,
+		 * and we need a bus reset.
+		 */
+		if (info->SCpnt && !info->scsi.disconnectable &&
+		    info->SCpnt->target == SCpnt->target)
+			break;
 
-	if (info->host->dma_channel == NO_DMA || !info->dma.setup)
-		sync_state = neg_invalid;
-	else
-#ifdef SCSI2_SYNC
-		sync_state = neg_wait;
-#else
-		sync_state = neg_invalid;
-#endif
+		/*
+		 * We're going to be resetting this device.  Remove
+		 * all pending commands from the driver.  By doing
+		 * so, we guarantee that we won't touch the command
+		 * structures except to process the reset request.
+		 */
+		queue_remove_all_target(&info->queues.issue, target);
+		queue_remove_all_target(&info->queues.disconnected, target);
+		if (info->origSCpnt && info->origSCpnt->target == target)
+			info->origSCpnt = NULL;
+		if (info->reqSCpnt && info->reqSCpnt->target == target)
+			info->reqSCpnt = NULL;
+		for (i = 0; i < 8; i++)
+			clear_bit(target * 8 + i, info->busyluns);
 
-	for (i = 0; i < 8; i++) {
-		info->device[i].disconnect_ok	= info->ifcfg.disconnect_ok;
-		info->device[i].sync_state	= sync_state;
-		info->device[i].wide_state	= wide_state;
-		info->device[i].period		= info->ifcfg.asyncperiod / 4;
-		info->device[i].stp		= info->scsi.async_stp;
-		info->device[i].sof		= 0;
-		info->device[i].wide_xfer	= 0;
-	}
+		/*
+		 * Hijack this SCSI command structure to send
+		 * a bus device reset message to this device.
+		 */
+		SCpnt->host_scribble = (void *)fas216_devicereset_done;
 
-	/*
-	 * Drain all commands on disconnected queue
-	 */
-	while (queue_remove(&info->queues.disconnected) != NULL);
+		info->rst_dev_status = 0;
+		info->rstSCpnt = SCpnt;
 
-	/*
-	 * Remove executing commands.
-	 */
-	info->SCpnt     = NULL;
-	info->reqSCpnt  = NULL;
-	info->origSCpnt = NULL;
-}
+		if (info->scsi.phase == PHASE_IDLE)
+			fas216_kick(info);
 
-/* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
- * Purpose : Reset the device associated with this command
- * Params  : SCpnt - command specifing device to reset
- * Returns : FAILED if unable to reset
- */
-int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
-{
-	FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
+		mod_timer(&info->eh_timer, 30 * HZ);
+		spin_unlock_irqrestore(&info->host_lock, flags);
+
+		/*
+		 * Wait up to 30 seconds for the reset to complete.
+		 */
+		wait_event(info->eh_wait, info->rst_dev_status);
+
+		del_timer_sync(&info->eh_timer);
+		spin_lock_irqsave(&info->host_lock, flags);
+		info->rstSCpnt = NULL;
+
+		if (info->rst_dev_status == 1)
+			res = SUCCESS;
+	} while (0);
+
+	SCpnt->host_scribble = NULL;
+	spin_unlock_irqrestore(&info->host_lock, flags);
+
+	fas216_log(info, LOG_ERROR, "device reset complete: %s\n",
+		   res == SUCCESS ? "success" : "failed");
 
-	printk("scsi%d.%c: "__FUNCTION__": called\n",
-		info->host->host_no, '0' + SCpnt->target);
-	return FAILED;
+	return res;
 }
 
-/* Function: int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
- * Purpose : Reset the bus associated with the command
- * Params  : SCpnt - command specifing bus to reset
- * Returns : FAILED if unable to reset
- * Notes   : io_request_lock is taken, and irqs are disabled
+/**
+ * fas216_eh_bus_reset - Reset the bus associated with the command
+ * @SCpnt: command specifing bus to reset
+ *
+ * Reset the bus associated with the command.
+ * Returns: FAILED if unable to reset.
+ * Notes: Further commands are blocked.
  */
 int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
 {
 	FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
-	int result = FAILED;
+	unsigned long flags;
+	Scsi_Device *SDpnt;
 
 	fas216_checkmagic(info);
+	fas216_log(info, LOG_ERROR, "resetting bus");
 
 	info->stats.bus_resets += 1;
 
-	printk("scsi%d.%c: "__FUNCTION__": resetting bus\n",
-		info->host->host_no, '0' + SCpnt->target);
+	spin_lock_irqsave(&info->host_lock, flags);
 
 	/*
-	 * Attempt to stop all activity on this interface.
+	 * Stop all activity on this interface.
 	 */
-	outb(info->scsi.cfg[2], REG_CNTL3(info));
-	fas216_stoptransfer(info);
+	fas216_aborttransfer(info);
+	fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
 
 	/*
-	 * Clear any pending interrupts
+	 * Clear any pending interrupts.
 	 */
-	while (inb(REG_STAT(info)) & STAT_INT)
-		inb(REG_INST(info));
+	while (fas216_readb(info, REG_STAT) & STAT_INT)
+		fas216_readb(info, REG_INST);
+
+	info->rst_bus_status = 0;
 
 	/*
-	 * Reset the SCSI bus
+	 * For each attached hard-reset device, clear out
+	 * all command structures.  Leave the running
+	 * command in place.
 	 */
-	outb(CMD_RESETSCSI, REG_CMD(info));
-	udelay(5);
+	for (SDpnt = info->host->host_queue; SDpnt; SDpnt = SDpnt->next) {
+		int i;
+
+		if (SDpnt->soft_reset)
+			continue;
+
+		queue_remove_all_target(&info->queues.issue, SDpnt->id);
+		queue_remove_all_target(&info->queues.disconnected, SDpnt->id);
+		if (info->origSCpnt && info->origSCpnt->target == SDpnt->id)
+			info->origSCpnt = NULL;
+		if (info->reqSCpnt && info->reqSCpnt->target == SDpnt->id)
+			info->reqSCpnt = NULL;
+		info->SCpnt = NULL;
+
+		for (i = 0; i < 8; i++)
+			clear_bit(SDpnt->id * 8 + i, info->busyluns);
+	}
+
+	info->scsi.phase = PHASE_IDLE;
 
 	/*
-	 * Clear reset interrupt
+	 * Reset the SCSI bus.  Device cleanup happens in
+	 * the interrupt handler.
 	 */
-	if (inb(REG_STAT(info)) & STAT_INT &&
-	    inb(REG_INST(info)) & INST_BUSRESET)
-		result = SUCCESS;
+	fas216_cmd(info, CMD_RESETSCSI);
 
-	fas216_reset_state(info);
+	mod_timer(&info->eh_timer, jiffies + HZ);
+	spin_unlock_irqrestore(&info->host_lock, flags);
 
-	return result;
+	/*
+	 * Wait one second for the interrupt.
+	 */
+	wait_event(info->eh_wait, info->rst_bus_status);
+	del_timer_sync(&info->eh_timer);
+
+	fas216_log(info, LOG_ERROR, "bus reset complete: %s\n",
+		   info->rst_bus_status == 1 ? "success" : "failed");
+
+	return info->rst_bus_status == 1 ? SUCCESS : FAILED;
 }
 
-/* Function: void fas216_init_chip(FAS216_Info *info)
- * Purpose : Initialise FAS216 state after reset
- * Params  : info - state structure for interface
+/**
+ * fas216_init_chip - Initialise FAS216 state after reset
+ * @info: state structure for interface
+ *
+ * Initialise FAS216 state after reset
  */
 static void fas216_init_chip(FAS216_Info *info)
 {
-	outb(fas216_clockrate(info->ifcfg.clockrate), REG_CLKF(info));
-	outb(info->scsi.cfg[0], REG_CNTL1(info));
-	outb(info->scsi.cfg[1], REG_CNTL2(info));
-	outb(info->scsi.cfg[2], REG_CNTL3(info));
-	outb(info->ifcfg.select_timeout, REG_STIM(info));
-	outb(0, REG_SOF(info));
-	outb(info->scsi.async_stp, REG_STP(info));
-	outb(info->scsi.cfg[0], REG_CNTL1(info));
+	unsigned int clock = ((info->ifcfg.clockrate - 1) / 5 + 1) & 7;
+	fas216_writeb(info, REG_CLKF, clock);
+	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
+	fas216_writeb(info, REG_CNTL2, info->scsi.cfg[1]);
+	fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
+	fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
+	fas216_writeb(info, REG_SOF, 0);
+	fas216_writeb(info, REG_STP, info->scsi.async_stp);
+	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
 }
 
-/* Function: int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
- * Purpose : Reset the host associated with this command
- * Params  : SCpnt - command specifing host to reset
- * Returns : FAILED if unable to reset
- * Notes   : io_request_lock is taken, and irqs are disabled
+/**
+ * fas216_eh_host_reset - Reset the host associated with this command
+ * @SCpnt: command specifing host to reset
+ *
+ * Reset the host associated with this command.
+ * Returns: FAILED if unable to reset.
+ * Notes: io_request_lock is taken, and irqs are disabled
  */
 int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
 {
@@ -2449,13 +2620,13 @@
 
 	fas216_checkmagic(info);
 
-	printk("scsi%d.%c: "__FUNCTION__": resetting host\n",
-		info->host->host_no, '0' + SCpnt->target);
+	printk("scsi%d.%c: %s: resetting host\n",
+		info->host->host_no, '0' + SCpnt->target, __FUNCTION__);
 
 	/*
 	 * Reset the SCSI chip.
 	 */
-	outb(CMD_RESETCHIP, REG_CMD(info));
+	fas216_cmd(info, CMD_RESETCHIP);
 
 	/*
 	 * Ugly ugly ugly!
@@ -2464,13 +2635,13 @@
 	 * IRQs after the sleep.
 	 */
 	spin_unlock_irq(&io_request_lock);
-	scsi_sleep(25*HZ/100);
+	scsi_sleep(50 * HZ/100);
 	spin_lock_irq(&io_request_lock);
 
 	/*
 	 * Release the SCSI reset.
 	 */
-	outb(CMD_NOP, REG_CMD(info));
+	fas216_cmd(info, CMD_NOP);
 
 	fas216_init_chip(info);
 
@@ -2502,56 +2673,56 @@
 	/*
 	 * Reset the chip.
 	 */
-	outb(CMD_RESETCHIP, REG_CMD(info));
+	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
 	udelay(50);
-	outb(CMD_NOP, REG_CMD(info));
+	fas216_writeb(info, REG_CMD, CMD_NOP);
 
 	/*
 	 * Check to see if control reg 2 is present.
 	 */
-	outb(0, REG_CNTL3(info));
-	outb(CNTL2_S2FE, REG_CNTL2(info));
+	fas216_writeb(info, REG_CNTL3, 0);
+	fas216_writeb(info, REG_CNTL2, CNTL2_S2FE);
 
 	/*
 	 * If we are unable to read back control reg 2
 	 * correctly, it is not present, and we have a
 	 * NCR53C90.
 	 */
-	if ((inb(REG_CNTL2(info)) & (~0xe0)) != CNTL2_S2FE)
+	if ((fas216_readb(info, REG_CNTL2) & (~0xe0)) != CNTL2_S2FE)
 		return TYPE_NCR53C90;
 
 	/*
 	 * Now, check control register 3
 	 */
-	outb(0, REG_CNTL2(info));
-	outb(0, REG_CNTL3(info));
-	outb(5, REG_CNTL3(info));
+	fas216_writeb(info, REG_CNTL2, 0);
+	fas216_writeb(info, REG_CNTL3, 0);
+	fas216_writeb(info, REG_CNTL3, 5);
 
 	/*
 	 * If we are unable to read the register back
 	 * correctly, we have a NCR53C90A
 	 */
-	if (inb(REG_CNTL3(info)) != 5)
+	if (fas216_readb(info, REG_CNTL3) != 5)
 		return TYPE_NCR53C90A;
 
 	/*
 	 * Now read the ID from the chip.
 	 */
-	outb(0, REG_CNTL3(info));
+	fas216_writeb(info, REG_CNTL3, 0);
 
-	outb(CNTL3_ADIDCHK, REG_CNTL3(info));
-	outb(0, REG_CNTL3(info));
+	fas216_writeb(info, REG_CNTL3, CNTL3_ADIDCHK);
+	fas216_writeb(info, REG_CNTL3, 0);
 
-	outb(CMD_RESETCHIP, REG_CMD(info));
-	udelay(5);
-	outb(CMD_WITHDMA | CMD_NOP, REG_CMD(info));
+	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
+	udelay(50);
+	fas216_writeb(info, REG_CMD, CMD_WITHDMA | CMD_NOP);
 
-	outb(CNTL2_ENF, REG_CNTL2(info));
-	outb(CMD_RESETCHIP, REG_CMD(info));
-	udelay(5);
-	outb(CMD_NOP, REG_CMD(info));
+	fas216_writeb(info, REG_CNTL2, CNTL2_ENF);
+	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
+	udelay(50);
+	fas216_writeb(info, REG_CMD, CMD_NOP);
 
-	rev     = inb(REG1_ID(info));
+	rev     = fas216_readb(info, REG_ID);
 	family  = rev >> 3;
 	rev    &= 7;
 
@@ -2577,33 +2748,106 @@
 	return TYPE_NCR53C9x;
 }
 
-/* Function: int fas216_init(struct Scsi_Host *instance)
- * Purpose : initialise FAS/NCR/AMD SCSI ic.
- * Params  : instance - a driver-specific filled-out structure
- * Returns : 0 on success
+/**
+ * fas216_reset_state - Initialise driver internal state
+ * @info: state to initialise
+ *
+ * Initialise driver internal state
  */
-int fas216_init(struct Scsi_Host *instance)
+static void fas216_reset_state(FAS216_Info *info)
 {
-	FAS216_Info *info = (FAS216_Info *)instance->hostdata;
-	int type;
+	int i;
+
+	fas216_checkmagic(info);
+
+	fas216_bus_reset(info);
 
-	info->magic_start = MAGIC;
-	info->magic_end   = MAGIC;
-	info->host        = instance;
-	info->scsi.cfg[0] = instance->this_id;
-	info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE;
-	info->scsi.cfg[2] = info->ifcfg.cntl3 | CNTL3_ADIDCHK | CNTL3_G2CB;
+	/*
+	 * Clear out all stale info in our state structure
+	 */
+	memset(info->busyluns, 0, sizeof(info->busyluns));
+	info->scsi.disconnectable = 0;
+	info->scsi.aborting = 0;
+
+	for (i = 0; i < 8; i++) {
+		info->device[i].parity_enabled	= 0;
+		info->device[i].parity_check	= 1;
+	}
+
+	/*
+	 * Drain all commands on disconnected queue
+	 */
+	while (queue_remove(&info->queues.disconnected) != NULL);
+
+	/*
+	 * Remove executing commands.
+	 */
+	info->SCpnt     = NULL;
+	info->reqSCpnt  = NULL;
+	info->rstSCpnt  = NULL;
+	info->origSCpnt = NULL;
+}
+
+/**
+ * fas216_init - initialise FAS/NCR/AMD SCSI structures.
+ * @host: a driver-specific filled-out structure
+ *
+ * Initialise FAS/NCR/AMD SCSI structures.
+ * Returns: 0 on success
+ */
+int fas216_init(struct Scsi_Host *host)
+{
+	FAS216_Info *info = (FAS216_Info *)host->hostdata;
+
+	info->magic_start    = MAGIC;
+	info->magic_end      = MAGIC;
+	info->host           = host;
+	info->scsi.cfg[0]    = host->this_id | CNTL1_PERE;
+	info->scsi.cfg[1]    = CNTL2_ENF | CNTL2_S2FE;
+	info->scsi.cfg[2]    = info->ifcfg.cntl3 |
+			       CNTL3_ADIDCHK | CNTL3_QTAG | CNTL3_G2CB | CNTL3_LBTM;
+	info->scsi.async_stp = fas216_syncperiod(info, info->ifcfg.asyncperiod);
+
+	info->rst_dev_status = -1;
+	info->rst_bus_status = -1;
+	init_waitqueue_head(&info->eh_wait);
+	init_timer(&info->eh_timer);
+	info->eh_timer.data  = (unsigned long)info;
+	info->eh_timer.function = fas216_eh_timer;
+	
+	spin_lock_init(&info->host_lock);
 
 	memset(&info->stats, 0, sizeof(info->stats));
 
 	msgqueue_initialise(&info->scsi.msgs);
 
 	if (!queue_initialise(&info->queues.issue))
-		return 1;
+		return -ENOMEM;
 
 	if (!queue_initialise(&info->queues.disconnected)) {
 		queue_free(&info->queues.issue);
-		return 1;
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/**
+ * fas216_add - initialise FAS/NCR/AMD SCSI ic.
+ * @host: a driver-specific filled-out structure
+ *
+ * Initialise FAS/NCR/AMD SCSI ic.
+ * Returns: 0 on success
+ */
+int fas216_add(struct Scsi_Host *host)
+{
+	FAS216_Info *info = (FAS216_Info *)host->hostdata;
+	int type;
+
+	if (info->ifcfg.clockrate <= 10 || info->ifcfg.clockrate > 40) {
+		printk(KERN_CRIT "fas216: invalid clock rate %u MHz\n",
+			info->ifcfg.clockrate);
+		return -EINVAL;
 	}
 
 	fas216_reset_state(info);
@@ -2622,78 +2866,53 @@
 	 * the resulting reset interrupt, so mask it
 	 * out.
 	 */
-	outb(info->scsi.cfg[0] | CNTL1_DISR, REG_CNTL1(info));
-	outb(CMD_RESETSCSI, REG_CMD(info));
+	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_DISR);
+	fas216_writeb(info, REG_CMD, CMD_RESETSCSI);
 
 	/*
 	 * scsi standard says wait 250ms
 	 */
 	spin_unlock_irq(&io_request_lock);
-	scsi_sleep(25*HZ/100);
+	scsi_sleep(100*HZ/100);
 	spin_lock_irq(&io_request_lock);
 
-	outb(info->scsi.cfg[0], REG_CNTL1(info));
-	inb(REG_INST(info));
+	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
+	fas216_readb(info, REG_INST);
 
 	fas216_checkmagic(info);
 
 	return 0;
 }
 
-/* Function: int fas216_release(struct Scsi_Host *instance)
- * Purpose : release all resources and put everything to bed for
- *           FAS/NCR/AMD SCSI ic.
- * Params  : instance - a driver-specific filled-out structure
- * Returns : 0 on success
- */
-int fas216_release(struct Scsi_Host *instance)
+void fas216_remove(struct Scsi_Host *host)
 {
-	FAS216_Info *info = (FAS216_Info *)instance->hostdata;
+	FAS216_Info *info = (FAS216_Info *)host->hostdata;
 
 	fas216_checkmagic(info);
 
-	outb(CMD_RESETCHIP, REG_CMD(info));
-	queue_free(&info->queues.disconnected);
-	queue_free(&info->queues.issue);
-
-	return 0;
+	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
 }
 
-/*
- * Function: int fas216_info(FAS216_Info *info, char *buffer)
- * Purpose : generate a string containing information about this
- *	     host.
- * Params  : info   - FAS216 host information
- *	     buffer - string buffer to build string
- * Returns : size of built string
+/**
+ * fas216_release - release all resources for FAS/NCR/AMD SCSI ic.
+ * @host: a driver-specific filled-out structure
+ *
+ * release all resources and put everything to bed for FAS/NCR/AMD SCSI ic.
  */
-int fas216_info(FAS216_Info *info, char *buffer)
+void fas216_release(struct Scsi_Host *host)
 {
-	char *p = buffer;
+	FAS216_Info *info = (FAS216_Info *)host->hostdata;
 
-	p += sprintf(p, "(%s) at port 0x%08lX ",
-		     info->scsi.type, info->host->io_port);
-
-	if (info->host->irq != NO_IRQ)
-		p += sprintf(p, "irq %d ", info->host->irq);
-	else
-		p += sprintf(p, "no irq ");
-
-	if (info->host->dma_channel != NO_DMA)
-		p += sprintf(p, "dma %d ", info->host->dma_channel);
-	else
-		p += sprintf(p, "no dma ");
-
-	return p - buffer;
+	queue_free(&info->queues.disconnected);
+	queue_free(&info->queues.issue);
 }
 
 int fas216_print_host(FAS216_Info *info, char *buffer)
 {
-	
 	return sprintf(buffer,
 			"\n"
 			"Chip    : %s\n"
-			" Address: 0x%08lX\n"
+			" Address: 0x%08lx\n"
 			" IRQ    : %d\n"
 			" DMA    : %d\n",
 			info->scsi.type, info->host->io_port,
@@ -2702,8 +2921,9 @@
 
 int fas216_print_stats(FAS216_Info *info, char *buffer)
 {
-	return sprintf(buffer,
-			"\n"
+	char *p = buffer;
+
+	p += sprintf(p, "\n"
 			"Command Statistics:\n"
 			" Queued     : %u\n"
 			" Issued     : %u\n"
@@ -2720,6 +2940,8 @@
 			info->stats.writes,	 info->stats.miscs,
 			info->stats.disconnects, info->stats.aborts,
 			info->stats.bus_resets,	 info->stats.host_resets);
+
+	return p - buffer;
 }
 
 int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer)
@@ -2738,7 +2960,9 @@
 			     scd->tagged_queue ? "en" : "dis",
 			     scd->current_tag);
 
-	p += sprintf(p, "\n  Transfers : %d-bit ",
+	p += sprintf(p, "%s\n", dev->parity_enabled ? "parity" : "");
+
+	p += sprintf(p, "  Transfers : %d-bit ",
 		     8 << dev->wide_xfer);
 
 	if (dev->sof)
@@ -2750,11 +2974,12 @@
 	return p - buffer;
 }
 
-EXPORT_SYMBOL(fas216_info);
 EXPORT_SYMBOL(fas216_init);
+EXPORT_SYMBOL(fas216_add);
 EXPORT_SYMBOL(fas216_queue_command);
 EXPORT_SYMBOL(fas216_command);
 EXPORT_SYMBOL(fas216_intr);
+EXPORT_SYMBOL(fas216_remove);
 EXPORT_SYMBOL(fas216_release);
 EXPORT_SYMBOL(fas216_eh_abort);
 EXPORT_SYMBOL(fas216_eh_device_reset);
diff -urN linux-2.4.22-pre2/drivers/acorn/scsi/fas216.h linux-2.4.22-pre3/drivers/acorn/scsi/fas216.h
--- linux-2.4.22-pre2/drivers/acorn/scsi/fas216.h	2000-09-18 15:15:22.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/scsi/fas216.h	2003-07-05 18:09:50.000000000 -0700
@@ -22,18 +22,18 @@
 /* FAS register definitions */
 
 /* transfer count low */
-#define REG_CTCL(x)		((x)->scsi.io_port)
-#define REG_STCL(x)		((x)->scsi.io_port)
+#define REG_CTCL		(0)
+#define REG_STCL		(0)
 
 /* transfer count medium */
-#define REG_CTCM(x)		((x)->scsi.io_port + (1 << (x)->scsi.io_shift))
-#define REG_STCM(x)		((x)->scsi.io_port + (1 << (x)->scsi.io_shift))
+#define REG_CTCM		(1)
+#define REG_STCM		(1)
 
 /* fifo data */
-#define REG_FF(x)		((x)->scsi.io_port + (2 << (x)->scsi.io_shift))
+#define REG_FF			(2)
 
 /* command */
-#define REG_CMD(x)		((x)->scsi.io_port + (3 << (x)->scsi.io_shift))
+#define REG_CMD			(3)
 #define CMD_NOP			0x00
 #define CMD_FLUSHFIFO		0x01
 #define CMD_RESETCHIP		0x02
@@ -57,7 +57,7 @@
 #define CMD_WITHDMA		0x80
 
 /* status register (read) */
-#define REG_STAT(x)		((x)->scsi.io_port + (4 << (x)->scsi.io_shift))
+#define REG_STAT		(4)
 #define STAT_IO			(1 << 0)			/* IO phase		*/
 #define STAT_CD			(1 << 1)			/* CD phase		*/
 #define STAT_MSG		(1 << 2)			/* MSG phase		*/
@@ -76,11 +76,11 @@
 #define STAT_MESGIN		(STAT_MSG|STAT_CD|STAT_IO)	/* Message In		*/
 
 /* bus ID for select / reselect */
-#define REG_SDID(x)		((x)->scsi.io_port + (4 << (x)->scsi.io_shift))
+#define REG_SDID		(4)
 #define BUSID(target)		((target) & 7)
 
 /* Interrupt status register (read) */
-#define REG_INST(x)		((x)->scsi.io_port + (5 << (x)->scsi.io_shift))
+#define REG_INST		(5)
 #define INST_SELWOATN		(1 << 0)			/* Select w/o ATN	*/
 #define INST_SELATN		(1 << 1)			/* Select w/ATN		*/
 #define INST_RESELECTED		(1 << 2)			/* Reselected		*/
@@ -91,10 +91,10 @@
 #define INST_BUSRESET		(1 << 7)			/* SCSI Bus reset	*/
 
 /* Timeout register (write) */
-#define REG_STIM(x)		((x)->scsi.io_port + (5 << (x)->scsi.io_shift))
+#define REG_STIM		(5)
 
 /* Sequence step register (read) */
-#define REG_IS(x)		((x)->scsi.io_port + (6 << (x)->scsi.io_shift))
+#define REG_IS			(6)
 #define IS_BITS			0x07
 #define IS_SELARB		0x00				/* Select & Arb ok	*/
 #define IS_MSGBYTESENT		0x01				/* One byte message sent*/
@@ -104,18 +104,18 @@
 #define IS_SOF			0x08				/* Sync off flag	*/
 
 /* Transfer period step (write) */
-#define REG_STP(x)		((x)->scsi.io_port + (6 << (x)->scsi.io_shift))
+#define REG_STP			(6)
 
 /* Synchronous Offset (write) */
-#define REG_SOF(x)		((x)->scsi.io_port + (7 << (x)->scsi.io_shift))
+#define REG_SOF			(7)
 
 /* Fifo state register (read) */
-#define REG_CFIS(x)		((x)->scsi.io_port + (7 << (x)->scsi.io_shift))
+#define REG_CFIS		(7)
 #define CFIS_CF			0x1f				/* Num bytes in FIFO	*/
 #define CFIS_IS			0xe0				/* Step			*/
 
 /* config register 1 */
-#define REG_CNTL1(x)		((x)->scsi.io_port + (8 << (x)->scsi.io_shift))
+#define REG_CNTL1		(8)
 #define CNTL1_CID		(7 << 0)			/* Chip ID			*/
 #define CNTL1_STE		(1 << 3)			/* Self test enable		*/
 #define CNTL1_PERE		(1 << 4)			/* Parity enable reporting en.	*/
@@ -124,7 +124,7 @@
 #define CNTL1_ETM		(1 << 7)			/* Extended Timing Mode		*/
 
 /* Clock conversion factor (read) */
-#define REG_CLKF(x)		((x)->scsi.io_port + (9 << (x)->scsi.io_shift))
+#define REG_CLKF		(9)
 #define CLKF_F37MHZ		0x00				/* 35.01 - 40 MHz		*/
 #define CLKF_F10MHZ		0x02				/* 10 MHz			*/
 #define CLKF_F12MHZ		0x03				/* 10.01 - 15 MHz		*/
@@ -134,13 +134,13 @@
 #define CLKF_F32MHZ		0x07				/* 30.01 - 35 MHz		*/
 
 /* Chip test register (write) */
-#define REG0_FTM(x)		((x)->scsi.io_port + (10 << (x)->scsi.io_shift))
+#define REG_FTM			(10)
 #define TEST_FTM		0x01				/* Force target mode		*/
 #define TEST_FIM		0x02				/* Force initiator mode		*/
 #define TEST_FHI		0x04				/* Force high impedance mode	*/
 
 /* Configuration register 2 (read/write) */
-#define REG_CNTL2(x)		((x)->scsi.io_port + (11 << (x)->scsi.io_shift))
+#define REG_CNTL2		(11)
 #define CNTL2_PGDP		(1 << 0)			/* Pass Th/Generate Data Parity	*/
 #define CNTL2_PGRP		(1 << 1)			/* Pass Th/Generate Reg Parity	*/
 #define CNTL2_ACDPE		(1 << 2)			/* Abort on Cmd/Data Parity Err	*/
@@ -151,7 +151,7 @@
 #define CNTL2_DAE		(1 << 7)			/* Data Alignment Enable	*/
 
 /* Configuration register 3 (read/write) */
-#define REG_CNTL3(x)		((x)->scsi.io_port + (12 << (x)->scsi.io_shift))
+#define REG_CNTL3		(12)
 #define CNTL3_BS8		(1 << 0)			/* Burst size 8			*/
 #define CNTL3_MDM		(1 << 1)			/* Modify DMA mode		*/
 #define CNTL3_LBTM		(1 << 2)			/* Last Byte Transfer mode	*/
@@ -162,14 +162,14 @@
 #define CNTL3_ADIDCHK		(1 << 7)			/* Additional ID check		*/
 
 /* High transfer count (read/write) */
-#define REG_CTCH(x)		((x)->scsi.io_port + (14 << (x)->scsi.io_shift))
-#define REG_STCH(x)		((x)->scsi.io_port + (14 << (x)->scsi.io_shift))
+#define REG_CTCH		(14)
+#define REG_STCH		(14)
 
-/* ID reigster (read only) */
-#define REG1_ID(x)		((x)->scsi.io_port + (14 << (x)->scsi.io_shift))
+/* ID register (read only) */
+#define REG_ID			(14)
 
 /* Data alignment */
-#define REG0_DAL(x)		((x)->scsi.io_port + (15 << (x)->scsi.io_shift))
+#define REG_DAL			(15)
 
 typedef enum {
 	PHASE_IDLE,					/* we're not planning on doing anything	*/
@@ -177,7 +177,6 @@
 	PHASE_SELSTEPS,					/* selection with command steps		*/
 	PHASE_COMMAND,					/* command sent				*/
 	PHASE_MESSAGESENT,				/* selected, and we're sending cmd	*/
-	PHASE_RECONNECTED,				/* reconnected				*/
 	PHASE_DATAOUT,					/* data out to device			*/
 	PHASE_DATAIN,					/* data in from device			*/
 	PHASE_MSGIN,					/* message in from device		*/
@@ -212,27 +211,36 @@
 #define MAGIC	0x441296bdUL
 #define NR_MSGS	8
 
+#define FASCAP_DMA		(1 << 0)
+#define FASCAP_PSEUDODMA	(1 << 1)
+
 typedef struct {
 	unsigned long		magic_start;
+	spinlock_t		host_lock;
 	struct Scsi_Host	*host;			/* host					*/
 	Scsi_Cmnd		*SCpnt;			/* currently processing command		*/
 	Scsi_Cmnd		*origSCpnt;		/* original connecting command		*/
 	Scsi_Cmnd		*reqSCpnt;		/* request sense command		*/
+	Scsi_Cmnd		*rstSCpnt;		/* reset command			*/
+	Scsi_Cmnd		*pending_SCpnt[8];	/* per-device pending commands		*/
+	int			next_pending;		/* next pending device			*/
+
+	/*
+	 * Error recovery
+	 */
+	wait_queue_head_t	eh_wait;
+	struct timer_list	eh_timer;
+	unsigned int		rst_dev_status;
+	unsigned int		rst_bus_status;
 
 	/* driver information */
 	struct {
+		phase_t		phase;			/* current phase			*/
 		unsigned int	io_port;		/* base address of FAS216		*/
 		unsigned int	io_shift;		/* shift to adjust reg offsets by	*/
-		unsigned int	irq;			/* interrupt				*/
 		unsigned char	cfg[4];			/* configuration registers		*/
 		const char	*type;			/* chip type				*/
-		phase_t		phase;			/* current phase			*/
-
-		struct {
-			unsigned char	target;		/* reconnected target			*/
-			unsigned char	lun;		/* reconnected lun			*/
-			unsigned char	tag;		/* reconnected tag			*/
-		} reconnected;
+		unsigned int	irq;			/* interrupt				*/
 
 		Scsi_Pointer	SCp;			/* current commands data pointer	*/
 
@@ -241,7 +249,6 @@
 		unsigned int	async_stp;		/* Async transfer STP value		*/
 		unsigned char	msgin_fifo;		/* bytes in fifo at time of message in	*/
 		unsigned char	message[256];		/* last message received from device	*/
-		unsigned int	msglen;			/* length of last message received	*/
 
 		unsigned char	disconnectable:1;	/* this command can be disconnected	*/
 		unsigned char	aborting:1;		/* aborting command			*/
@@ -269,6 +276,7 @@
 		unsigned char	wide_max_size;		/* Maximum wide transfer size		*/
 		unsigned char	cntl3;			/* Control Reg 3			*/
 		unsigned int	asyncperiod;		/* Async transfer period (ns)		*/
+		unsigned int	capabilities;		/* driver capabilities			*/
 		unsigned int	disconnect_ok:1;	/* Disconnects allowed?			*/
 	} ifcfg;
 
@@ -281,6 +289,8 @@
 	/* per-device info */
 	struct fas216_device {
 		unsigned char	disconnect_ok:1;	/* device can disconnect		*/
+		unsigned char	parity_enabled:1;	/* parity checking enabled		*/
+		unsigned char	parity_check:1;		/* need to check parity checking	*/
 		unsigned char	period;			/* sync xfer period in (*4ns)		*/
 		unsigned char	stp;			/* synchronous transfer period		*/
 		unsigned char	sof;			/* synchronous offset register		*/
@@ -300,31 +310,22 @@
 
 	/* miscellaneous */
 	int			internal_done;		/* flag to indicate request done */
-
 	unsigned long		magic_end;
 } FAS216_Info;
 
 /* Function: int fas216_init (struct Scsi_Host *instance)
- * Purpose : initialise FAS/NCR/AMD SCSI ic.
+ * Purpose : initialise FAS/NCR/AMD SCSI structures.
  * Params  : instance - a driver-specific filled-out structure
  * Returns : 0 on success
  */
 extern int fas216_init (struct Scsi_Host *instance);
 
-/* Function: int fas216_abort (Scsi_Cmnd *SCpnt)
- * Purpose : abort a command if something horrible happens.
- * Params  : SCpnt - Command that is believed to be causing a problem.
- * Returns : one of SCSI_ABORT_ macros.
- */
-extern int fas216_abort (Scsi_Cmnd *);
-
-/* Function: int fas216_reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
- * Purpose : resets the adapter if something horrible happens.
- * Params  : SCpnt - Command that is believed to be causing a problem.
- *	     reset_flags - flags indicating reset type that is believed to be required.
- * Returns : one of SCSI_RESET_ macros, or'd with the SCSI_RESET_*_RESET macros.
+/* Function: int fas216_add (struct Scsi_Host *instance)
+ * Purpose : initialise FAS/NCR/AMD SCSI ic.
+ * Params  : instance - a driver-specific filled-out structure
+ * Returns : 0 on success
  */
-extern int fas216_reset (Scsi_Cmnd *, unsigned int);
+extern int fas216_add (struct Scsi_Host *instance);
 
 /* Function: int fas216_queue_command (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
  * Purpose : queue a command for adapter to process.
@@ -341,20 +342,21 @@
  */
 extern int fas216_command (Scsi_Cmnd *);
 
-/* Function: void fas216_intr (struct Scsi_Host *instance)
+/* Function: void fas216_intr (FAS216_Info *info)
  * Purpose : handle interrupts from the interface to progress a command
- * Params  : instance - interface to service
+ * Params  : info - interface to service
  */
-extern void fas216_intr (struct Scsi_Host *instance);
+extern void fas216_intr (FAS216_Info *info);
+
+extern void fas216_remove (struct Scsi_Host *instance);
 
 /* Function: int fas216_release (struct Scsi_Host *instance)
  * Purpose : release all resources and put everything to bed for FAS/NCR/AMD SCSI ic.
  * Params  : instance - a driver-specific filled-out structure
  * Returns : 0 on success
  */
-extern int fas216_release (struct Scsi_Host *instance);
+extern void fas216_release (struct Scsi_Host *instance);
 
-extern int fas216_info(FAS216_Info *info, char *buffer);
 extern int fas216_print_host(FAS216_Info *info, char *buffer);
 extern int fas216_print_stats(FAS216_Info *info, char *buffer);
 extern int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer);
diff -urN linux-2.4.22-pre2/drivers/acorn/scsi/powertec.c linux-2.4.22-pre3/drivers/acorn/scsi/powertec.c
--- linux-2.4.22-pre2/drivers/acorn/scsi/powertec.c	2001-11-04 09:31:57.000000000 -0800
+++ linux-2.4.22-pre3/drivers/acorn/scsi/powertec.c	2003-07-05 18:09:50.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/drivers/acorn/scsi/powertec.c
  *
- *  Copyright (C) 1997-2000 Russell King
+ *  Copyright (C) 1997-2003 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -26,8 +26,6 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/unistd.h>
-#include <linux/stat.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -41,14 +39,10 @@
 #include "../../scsi/sd.h"
 #include "../../scsi/hosts.h"
 #include "fas216.h"
+#include "scsi.h"
 
 #include <scsi/scsicam.h>
 
-/* Configuration */
-#define POWERTEC_XTALFREQ	40
-#define POWERTEC_ASYNC_PERIOD	200
-#define POWERTEC_SYNC_DEPTH	7
-
 /*
  * List of devices that the driver will recognise
  */
@@ -70,33 +64,23 @@
 #define POWERTEC_INTR_ENABLE	1
 #define POWERTEC_INTR_DISABLE	0
 
-/*
- * Version
- */
-#define VER_MAJOR	0
-#define VER_MINOR	0
-#define VER_PATCH	5
-
-static struct expansion_card *ecs[MAX_ECARDS];
+#define VERSION	"1.10 (22/01/2003 2.4.19-rmk5)"
 
 /*
- * Use term=0,1,0,0,0 to turn terminators on/off
+ * Use term=0,1,0,0,0 to turn terminators on/off.
+ * One entry per slot.
  */
 static int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 };
 
 #define NR_SG	256
 
-typedef struct {
+struct powertec_info {
 	FAS216_Info info;
-
-	struct {
-		unsigned int term_port;
-		unsigned int terms;
-	} control;
-
-	/* other info... */
-	struct scatterlist sg[NR_SG];	/* Scatter DMA list	*/
-} PowerTecScsi_Info;
+	struct expansion_card	*ec;
+	unsigned int		term_port;
+	unsigned int		term_ctl;
+	struct scatterlist	sg[NR_SG];
+};
 
 /* Prototype: void powertecscsi_irqenable(ec, irqnr)
  * Purpose  : Enable interrupts on Powertec SCSI card
@@ -123,12 +107,8 @@
 }
 
 static const expansioncard_ops_t powertecscsi_ops = {
-	powertecscsi_irqenable,
-	powertecscsi_irqdisable,
-	NULL,
-	NULL,
-	NULL,
-	NULL
+	.irqenable	= powertecscsi_irqenable,
+	.irqdisable	= powertecscsi_irqdisable,
 };
 
 /* Prototype: void powertecscsi_terminator_ctl(host, on_off)
@@ -139,14 +119,10 @@
 static void
 powertecscsi_terminator_ctl(struct Scsi_Host *host, int on_off)
 {
-	PowerTecScsi_Info *info = (PowerTecScsi_Info *)host->hostdata;
-
-	if (on_off)
-		info->control.terms = POWERTEC_TERM_ENABLE;
-	else
-		info->control.terms = 0;
+	struct powertec_info *info = (struct powertec_info *)host->hostdata;
 
-	outb(info->control.terms, info->control.term_port);
+	info->term_ctl = on_off ? POWERTEC_TERM_ENABLE : 0;
+	outb(info->term_ctl, info->term_port);
 }
 
 /* Prototype: void powertecscsi_intr(irq, *dev_id, *regs)
@@ -158,9 +134,7 @@
 static void
 powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
-
-	fas216_intr(host);
+	fas216_intr(dev_id);
 }
 
 /* Prototype: fasdmatype_t powertecscsi_dma_setup(host, SCpnt, direction, min_type)
@@ -175,32 +149,26 @@
 powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
 		       fasdmadir_t direction, fasdmatype_t min_type)
 {
-	PowerTecScsi_Info *info = (PowerTecScsi_Info *)host->hostdata;
+	struct powertec_info *info = (struct powertec_info *)host->hostdata;
 	int dmach = host->dma_channel;
 
-	if (dmach != NO_DMA &&
-	    (min_type == fasdma_real_all || SCp->this_residual >= 512)) {
-		int bufs = SCp->buffers_residual;
-		int pci_dir, dma_dir;
-
-		if (bufs)
-			memcpy(info->sg + 1, SCp->buffer + 1,
-				sizeof(struct scatterlist) * bufs);
-		info->sg[0].address = SCp->ptr;
-		info->sg[0].page    = NULL;
-		info->sg[0].length  = SCp->this_residual;
+	if (info->info.ifcfg.capabilities & FASCAP_DMA &&
+	    min_type == fasdma_real_all) {
+		int bufs, map_dir, dma_dir;
+
+		bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG);
 
 		if (direction == DMA_OUT)
-			pci_dir = PCI_DMA_TODEVICE,
+			map_dir = PCI_DMA_TODEVICE,
 			dma_dir = DMA_MODE_WRITE;
 		else
-			pci_dir = PCI_DMA_FROMDEVICE,
+			map_dir = PCI_DMA_FROMDEVICE,
 			dma_dir = DMA_MODE_READ;
 
-		pci_map_sg(NULL, info->sg, bufs + 1, pci_dir);
+		pci_map_sg(NULL, info->sg, bufs, map_dir);
 
 		disable_dma(dmach);
-		set_dma_sg(dmach, info->sg, bufs + 1);
+		set_dma_sg(dmach, info->sg, bufs);
 		set_dma_mode(dmach, dma_dir);
 		enable_dma(dmach);
 		return fasdma_real_all;
@@ -225,122 +193,6 @@
 		disable_dma(host->dma_channel);
 }
 
-/* Prototype: int powertecscsi_detect(Scsi_Host_Template * tpnt)
- * Purpose  : initialises PowerTec SCSI driver
- * Params   : tpnt - template for this SCSI adapter
- * Returns  : >0 if host found, 0 otherwise.
- */
-int
-powertecscsi_detect(Scsi_Host_Template *tpnt)
-{
-	static const card_ids powertecscsi_cids[] =
-			{ POWERTECSCSI_LIST, { 0xffff, 0xffff} };
-	int count = 0;
-	struct Scsi_Host *host;
-  
-	tpnt->proc_name = "powertec";
-	memset(ecs, 0, sizeof (ecs));
-
-	ecard_startfind();
-
-	while (1) {
-	    	PowerTecScsi_Info *info;
-
-		ecs[count] = ecard_find(0, powertecscsi_cids);
-		if (!ecs[count])
-			break;
-
-		ecard_claim(ecs[count]);
-
-		host = scsi_register(tpnt, sizeof (PowerTecScsi_Info));
-		if (!host) {
-			ecard_release(ecs[count]);
-			break;
-		}
-
-		host->io_port = ecard_address(ecs[count], ECARD_IOC, ECARD_FAST);
-		host->irq = ecs[count]->irq;
-		host->dma_channel = ecs[count]->dma;
-		info = (PowerTecScsi_Info *)host->hostdata;
-
-		if (host->dma_channel != NO_DMA)
-			set_dma_speed(host->dma_channel, 180);
-
-		info->control.term_port = host->io_port + POWERTEC_TERM_CONTROL;
-		info->control.terms = term[count] ? POWERTEC_TERM_ENABLE : 0;
-		powertecscsi_terminator_ctl(host, info->control.terms);
-
-		info->info.scsi.io_port	=
-				host->io_port + POWERTEC_FAS216_OFFSET;
-		info->info.scsi.io_shift= POWERTEC_FAS216_SHIFT;
-		info->info.scsi.irq		= host->irq;
-		info->info.ifcfg.clockrate	= POWERTEC_XTALFREQ;
-		info->info.ifcfg.select_timeout	= 255;
-		info->info.ifcfg.asyncperiod	= POWERTEC_ASYNC_PERIOD;
-		info->info.ifcfg.sync_max_depth	= POWERTEC_SYNC_DEPTH;
-		info->info.ifcfg.cntl3		= CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
-		info->info.ifcfg.disconnect_ok	= 1;
-		info->info.ifcfg.wide_max_size	= 0;
-		info->info.dma.setup		= powertecscsi_dma_setup;
-		info->info.dma.pseudo		= NULL;
-		info->info.dma.stop		= powertecscsi_dma_stop;
-
-		ecs[count]->irqaddr	= (unsigned char *)
-			    ioaddr(host->io_port + POWERTEC_INTR_STATUS);
-		ecs[count]->irqmask	= POWERTEC_INTR_BIT;
-		ecs[count]->irq_data	= (void *)
-			    (host->io_port + POWERTEC_INTR_CONTROL);
-		ecs[count]->ops		= (expansioncard_ops_t *)&powertecscsi_ops;
-
-		request_region(host->io_port + POWERTEC_FAS216_OFFSET,
-			       16 << POWERTEC_FAS216_SHIFT, "powertec2-fas");
-
-		if (host->irq != NO_IRQ &&
-		    request_irq(host->irq, powertecscsi_intr,
-				SA_INTERRUPT, "powertec", host)) {
-			printk("scsi%d: IRQ%d not free, interrupts disabled\n",
-			       host->host_no, host->irq);
-			host->irq = NO_IRQ;
-			info->info.scsi.irq = NO_IRQ;
-		}
-
-		if (host->dma_channel != NO_DMA &&
-		    request_dma(host->dma_channel, "powertec")) {
-			printk("scsi%d: DMA%d not free, DMA disabled\n",
-			       host->host_no, host->dma_channel);
-			host->dma_channel = NO_DMA;
-		}
-
-		fas216_init(host);
-		++count;
-	}
-	return count;
-}
-
-/* Prototype: int powertecscsi_release(struct Scsi_Host * host)
- * Purpose  : releases all resources used by this adapter
- * Params   : host - driver host structure to return info for.
- */
-int powertecscsi_release(struct Scsi_Host *host)
-{
-	int i;
-
-	fas216_release(host);
-
-	if (host->irq != NO_IRQ)
-		free_irq(host->irq, host);
-	if (host->dma_channel != NO_DMA)
-		free_dma(host->dma_channel);
-	release_region(host->io_port + POWERTEC_FAS216_OFFSET,
-		       16 << POWERTEC_FAS216_SHIFT);
-
-	for (i = 0; i < MAX_ECARDS; i++)
-		if (ecs[i] &&
-		    host->io_port == ecard_address(ecs[i], ECARD_IOC, ECARD_FAST))
-			ecard_release(ecs[i]);
-	return 0;
-}
-
 /* Prototype: const char *powertecscsi_info(struct Scsi_Host * host)
  * Purpose  : returns a descriptive string about this interface,
  * Params   : host - driver host structure to return info for.
@@ -348,15 +200,12 @@
  */
 const char *powertecscsi_info(struct Scsi_Host *host)
 {
-	PowerTecScsi_Info *info = (PowerTecScsi_Info *)host->hostdata;
-	static char string[100], *p;
+	struct powertec_info *info = (struct powertec_info *)host->hostdata;
+	static char string[150];
 
-	p = string;
-	p += sprintf(p, "%s ", host->hostt->name);
-	p += fas216_info(&info->info, p);
-	p += sprintf(p, "v%d.%d.%d terminators o%s",
-		     VER_MAJOR, VER_MINOR, VER_PATCH,
-		     info->control.terms ? "n" : "ff");
+	sprintf(string, "%s (%s) in slot %d v%s terminators o%s",
+	        host->hostt->name, info->info.scsi.type, info->ec->slot_no,
+	        VERSION, info->term_ctl ? "n" : "ff");
 
 	return string;
 }
@@ -409,31 +258,25 @@
 			    int length, int host_no, int inout)
 {
 	int pos, begin;
-	struct Scsi_Host *host = scsi_hostlist;
-	PowerTecScsi_Info *info;
+	struct Scsi_Host *host;
+	struct powertec_info *info;
 	Scsi_Device *scd;
 
-	while (host) {
-		if (host->host_no == host_no)
-			break;
-		host = host->next;
-	}
+	host = scsi_host_hn_get(host_no);
 	if (!host)
 		return 0;
 
 	if (inout == 1)
 		return powertecscsi_set_proc_info(host, buffer, length);
 
-	info = (PowerTecScsi_Info *)host->hostdata;
+	info = (struct powertec_info *)host->hostdata;
 
 	begin = 0;
-	pos = sprintf(buffer,
-			"PowerTec SCSI driver version %d.%d.%d\n",
-			VER_MAJOR, VER_MINOR, VER_PATCH);
+	pos = sprintf(buffer, "PowerTec SCSI driver v%s\n", VERSION);
 
 	pos += fas216_print_host(&info->info, buffer + pos);
 	pos += sprintf(buffer + pos, "Term    : o%s\n",
-			info->control.terms ? "n" : "ff");
+			info->term_ctl ? "n" : "ff");
 
 	pos += fas216_print_stats(&info->info, buffer + pos);
 
@@ -458,28 +301,186 @@
 	return pos;
 }
 
+static int powertecscsi_probe(struct expansion_card *ec);
+
+/* Prototype: int powertecscsi_detect(Scsi_Host_Template * tpnt)
+ * Purpose  : initialises PowerTec SCSI driver
+ * Params   : tpnt - template for this SCSI adapter
+ * Returns  : >0 if host found, 0 otherwise.
+ */
+static int powertecscsi_detect(Scsi_Host_Template *tpnt)
+{
+	static const card_ids powertecscsi_cids[] =
+			{ POWERTECSCSI_LIST, { 0xffff, 0xffff} };
+	struct expansion_card *ec;
+	int count = 0, ret;
+
+	ecard_startfind();
+
+	while (1) {
+		ec = ecard_find(0, powertecscsi_cids);
+		if (!ec)
+			break;
+
+		ecard_claim(ec);
+
+		ret = powertecscsi_probe(ec);
+		if (ret) {
+			ecard_release(ec);
+			break;
+		}
+		++count;
+	}
+	return count;
+}
+
+static void powertecscsi_remove(struct Scsi_Host *host);
+
+/* Prototype: int powertecscsi_release(struct Scsi_Host * host)
+ * Purpose  : releases all resources used by this adapter
+ * Params   : host - driver host structure to return info for.
+ */
+static int powertecscsi_release(struct Scsi_Host *host)
+{
+	powertecscsi_remove(host);
+	return 0;
+}
+
 static Scsi_Host_Template powertecscsi_template = {
-	module:				THIS_MODULE,
-	proc_info:			powertecscsi_proc_info,
-	name:				"PowerTec SCSI",
-	detect:				powertecscsi_detect,
-	release:			powertecscsi_release,
-	info:				powertecscsi_info,
-	bios_param:			scsicam_bios_param,
-	can_queue:			1,
-	this_id:			7,
-	sg_tablesize:			SG_ALL,
-	cmd_per_lun:			1,
-	use_clustering:			ENABLE_CLUSTERING,
-	command:			fas216_command,
-	queuecommand:			fas216_queue_command,
-	eh_host_reset_handler:		fas216_eh_host_reset,
-	eh_bus_reset_handler:		fas216_eh_bus_reset,
-	eh_device_reset_handler:	fas216_eh_device_reset,
-	eh_abort_handler:		fas216_eh_abort,
-	use_new_eh_code:		1
+	.module				= THIS_MODULE,
+	.proc_info			= powertecscsi_proc_info,
+	.name				= "PowerTec SCSI",
+	.detect				= powertecscsi_detect,
+	.release			= powertecscsi_release,
+	.info				= powertecscsi_info,
+	.bios_param			= scsicam_bios_param,
+	.command			= fas216_command,
+	.queuecommand			= fas216_queue_command,
+	.eh_host_reset_handler		= fas216_eh_host_reset,
+	.eh_bus_reset_handler		= fas216_eh_bus_reset,
+	.eh_device_reset_handler	= fas216_eh_device_reset,
+	.eh_abort_handler		= fas216_eh_abort,
+	.use_new_eh_code		= 1,
+
+	.can_queue			= 1,
+	.this_id			= 7,
+	.sg_tablesize			= SG_ALL,
+	.cmd_per_lun			= 1,
+	.use_clustering			= ENABLE_CLUSTERING,
+	.proc_name			= "powertec",
 };
 
+static int
+powertecscsi_probe(struct expansion_card *ec)
+{
+	struct Scsi_Host *host;
+    	struct powertec_info *info;
+    	unsigned long base;
+	int ret;
+
+	base = ecard_address(ec, ECARD_IOC, ECARD_FAST);
+
+	request_region(base + POWERTEC_FAS216_OFFSET,
+		       16 << POWERTEC_FAS216_SHIFT, "powertec2-fas");
+
+	host = scsi_register(&powertecscsi_template,
+			     sizeof (struct powertec_info));
+	if (!host) {
+		ret = -ENOMEM;
+		goto out_region;
+	}
+
+	host->io_port	  = base;
+	host->irq	  = ec->irq;
+	host->dma_channel = ec->dma;
+
+	ec->irqaddr	= (unsigned char *)ioaddr(base + POWERTEC_INTR_STATUS);
+	ec->irqmask	= POWERTEC_INTR_BIT;
+	ec->irq_data	= (void *)(base + POWERTEC_INTR_CONTROL);
+	ec->ops		= (expansioncard_ops_t *)&powertecscsi_ops;
+
+	info = (struct powertec_info *)host->hostdata;
+	info->ec = ec;
+	info->term_port = base + POWERTEC_TERM_CONTROL;
+	powertecscsi_terminator_ctl(host, term[ec->slot_no]);
+
+	info->info.scsi.io_port		= host->io_port + POWERTEC_FAS216_OFFSET;
+	info->info.scsi.io_shift	= POWERTEC_FAS216_SHIFT;
+	info->info.scsi.irq		= host->irq;
+	info->info.ifcfg.clockrate	= 40; /* MHz */
+	info->info.ifcfg.select_timeout	= 255;
+	info->info.ifcfg.asyncperiod	= 200; /* ns */
+	info->info.ifcfg.sync_max_depth	= 7;
+	info->info.ifcfg.cntl3		= CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
+	info->info.ifcfg.disconnect_ok	= 1;
+	info->info.ifcfg.wide_max_size	= 0;
+	info->info.ifcfg.capabilities	= 0;
+	info->info.dma.setup		= powertecscsi_dma_setup;
+	info->info.dma.pseudo		= NULL;
+	info->info.dma.stop		= powertecscsi_dma_stop;
+
+	ret = fas216_init(host);
+	if (ret)
+		goto out_free;
+
+	ret = request_irq(host->irq, powertecscsi_intr,
+			  SA_INTERRUPT, "powertec", &info->info);
+	if (ret) {
+		printk("scsi%d: IRQ%d not free: %d\n",
+		       host->host_no, host->irq, ret);
+		goto out_release;
+	}
+
+	if (host->dma_channel != NO_DMA) {
+		if (request_dma(host->dma_channel, "powertec")) {
+			printk("scsi%d: DMA%d not free, using PIO\n",
+			       host->host_no, host->dma_channel);
+			host->dma_channel = NO_DMA;
+		} else {
+			set_dma_speed(host->dma_channel, 180);
+			info->info.ifcfg.capabilities |= FASCAP_DMA;
+		}
+	}
+
+	ret = fas216_add(host);
+	if (ret == 0)
+		goto out;
+
+	if (host->dma_channel != NO_DMA)
+		free_dma(host->dma_channel);
+	free_irq(host->irq, host);
+
+ out_release:
+	fas216_release(host);
+
+ out_free:
+	scsi_unregister(host);
+
+ out_region:
+	release_region(base + POWERTEC_FAS216_OFFSET,
+		       16 << POWERTEC_FAS216_SHIFT);
+
+ out:
+	return ret;
+}
+
+static void powertecscsi_remove(struct Scsi_Host *host)
+{
+    	struct powertec_info *info = (struct powertec_info *)host->hostdata;
+
+	fas216_remove(host);
+
+	if (host->dma_channel != NO_DMA)
+		free_dma(host->dma_channel);
+	free_irq(host->irq, info);
+
+	release_region(host->io_port + POWERTEC_FAS216_OFFSET,
+		       16 << POWERTEC_FAS216_SHIFT);
+
+	fas216_release(host);
+	ecard_release(info->ec);
+}
+
 static int __init powertecscsi_init(void)
 {
 	scsi_register_module(MODULE_SCSI_HA, &powertecscsi_template);
diff -urN linux-2.4.22-pre2/drivers/acorn/scsi/queue.c linux-2.4.22-pre3/drivers/acorn/scsi/queue.c
--- linux-2.4.22-pre2/drivers/acorn/scsi/queue.c	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/scsi/queue.c	2003-07-05 18:09:50.000000000 -0700
@@ -229,6 +229,27 @@
 }
 
 /*
+ * Function: queue_remove_all_target(queue, target)
+ * Purpose : remove all SCSI commands from the queue for a specified target
+ * Params  : queue  - queue to remove command from
+ *           target - target device id
+ * Returns : nothing
+ */
+void queue_remove_all_target(Queue_t *queue, int target)
+{
+	unsigned long flags;
+	struct list_head *l;
+
+	spin_lock_irqsave(&queue->queue_lock, flags);
+	list_for_each(l, &queue->head) {
+		QE_t *q = list_entry(l, QE_t, list);
+		if (q->SCpnt->target == target)
+			__queue_remove(queue, l);
+	}
+	spin_unlock_irqrestore(&queue->queue_lock, flags);
+}
+
+/*
  * Function: int queue_probetgtlun (queue, target, lun)
  * Purpose : check to see if we have a command in the queue for the specified
  *	     target/lun.
@@ -290,6 +311,7 @@
 EXPORT_SYMBOL(queue_remove_exclude);
 EXPORT_SYMBOL(queue_remove_tgtluntag);
 EXPORT_SYMBOL(queue_remove_cmd);
+EXPORT_SYMBOL(queue_remove_all_target);
 EXPORT_SYMBOL(queue_probetgtlun);
 
 MODULE_AUTHOR("Russell King");
diff -urN linux-2.4.22-pre2/drivers/acorn/scsi/queue.h linux-2.4.22-pre3/drivers/acorn/scsi/queue.h
--- linux-2.4.22-pre2/drivers/acorn/scsi/queue.h	2000-09-18 15:15:22.000000000 -0700
+++ linux-2.4.22-pre3/drivers/acorn/scsi/queue.h	2003-07-05 18:09:50.000000000 -0700
@@ -74,6 +74,15 @@
 extern Scsi_Cmnd *queue_remove_tgtluntag (Queue_t *queue, int target, int lun, int tag);
 
 /*
+ * Function: queue_remove_all_target(queue, target)
+ * Purpose : remove all SCSI commands from the queue for a specified target
+ * Params  : queue  - queue to remove command from
+ *           target - target device id
+ * Returns : nothing
+ */
+extern void queue_remove_all_target(Queue_t *queue, int target);
+
+/*
  * Function: int queue_probetgtlun (queue, target, lun)
  * Purpose : check to see if we have a command in the queue for the specified
  *	     target/lun.
diff -urN linux-2.4.22-pre2/drivers/acorn/scsi/scsi.h linux-2.4.22-pre3/drivers/acorn/scsi/scsi.h
--- linux-2.4.22-pre2/drivers/acorn/scsi/scsi.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/drivers/acorn/scsi/scsi.h	2003-07-05 18:09:50.000000000 -0700
@@ -0,0 +1,123 @@
+/*
+ *  linux/drivers/acorn/scsi/scsi.h
+ *
+ *  Copyright (C) 2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Commonly used scsi driver functions.
+ */
+
+#define BELT_AND_BRACES
+
+/*
+ * The scatter-gather list handling.  This contains all
+ * the yucky stuff that needs to be fixed properly.
+ */
+static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int max)
+{
+	int bufs = SCp->buffers_residual;
+
+	BUG_ON(bufs + 1 > max);
+
+	sg->address = SCp->ptr;
+	sg->length = SCp->this_residual;
+
+	if (bufs)
+		memcpy(sg + 1, SCp->buffer + 1,
+		       sizeof(struct scatterlist) * bufs);
+	return bufs + 1;
+}
+
+static inline int next_SCp(Scsi_Pointer *SCp)
+{
+	int ret = SCp->buffers_residual;
+	if (ret) {
+		SCp->buffer++;
+		SCp->buffers_residual--;
+		SCp->ptr = (unsigned char *)SCp->buffer->address;
+		SCp->this_residual = SCp->buffer->length;
+	} else {
+		SCp->ptr = NULL;
+		SCp->this_residual = 0;
+	}
+	return ret;
+}
+
+static inline unsigned char get_next_SCp_byte(Scsi_Pointer *SCp)
+{
+	char c = *SCp->ptr;
+
+	SCp->ptr += 1;
+	SCp->this_residual -= 1;
+
+	return c;
+}
+
+static inline void put_next_SCp_byte(Scsi_Pointer *SCp, unsigned char c)
+{
+	*SCp->ptr = c;
+	SCp->ptr += 1;
+	SCp->this_residual -= 1;
+}
+
+static inline void init_SCp(Scsi_Cmnd *SCpnt)
+{
+	memset(&SCpnt->SCp, 0, sizeof(struct scsi_pointer));
+
+	if (SCpnt->use_sg) {
+		unsigned long len = 0;
+		int buf;
+
+		SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
+		SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
+		SCpnt->SCp.ptr = (char *) SCpnt->SCp.buffer->address;
+		SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
+
+#ifdef BELT_AND_BRACES
+		/*
+		 * Calculate correct buffer length.  Some commands
+		 * come in with the wrong request_bufflen.
+		 */
+		for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
+			len += SCpnt->SCp.buffer[buf].length;
+
+		if (SCpnt->request_bufflen != len)
+			printk(KERN_WARNING "scsi%d.%c: bad request buffer "
+			       "length %d, should be %ld\n", SCpnt->host->host_no,
+			       '0' + SCpnt->target, SCpnt->request_bufflen, len);
+		SCpnt->request_bufflen = len;
+#endif
+	} else {
+		SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
+		SCpnt->SCp.this_residual = SCpnt->request_bufflen;
+	}
+
+	/*
+	 * If the upper SCSI layers pass a buffer, but zero length,
+	 * we aren't interested in the buffer pointer.
+	 */
+	if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
+#if 0 //def BELT_AND_BRACES
+		printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
+		       "command ", SCpnt->host->host_no, '0' + SCpnt->target);
+		print_command(SCpnt->cmnd);
+#endif
+		SCpnt->SCp.ptr = NULL;
+	}
+}
+
+static inline struct Scsi_Host *scsi_host_hn_get(int host_no)
+{
+	struct Scsi_Host *host = scsi_hostlist;
+
+	while (host) {
+		if (host->host_no == host_no)
+			break;
+		host = host->next;
+	}
+
+	return host;
+}
diff -urN linux-2.4.22-pre2/drivers/atm/Config.in linux-2.4.22-pre3/drivers/atm/Config.in
--- linux-2.4.22-pre2/drivers/atm/Config.in	2003-07-05 18:09:17.000000000 -0700
+++ linux-2.4.22-pre3/drivers/atm/Config.in	2003-07-05 18:09:55.000000000 -0700
@@ -94,7 +94,7 @@
 fi
 if [ "$CONFIG_PCI" = "y" ]; then
   tristate 'ForeRunner HE Series' CONFIG_ATM_HE
-  if [ "$CONFIG_ATM_HE" = "y" ]; then
+  if [ "$CONFIG_ATM_HE" != "n" ]; then
     bool 'Use S/UNI PHY driver' CONFIG_ATM_HE_USE_SUNI
   fi
 fi
diff -urN linux-2.4.22-pre2/drivers/atm/eni.c linux-2.4.22-pre3/drivers/atm/eni.c
--- linux-2.4.22-pre2/drivers/atm/eni.c	2001-12-21 09:41:53.000000000 -0800
+++ linux-2.4.22-pre3/drivers/atm/eni.c	2003-07-05 18:09:55.000000000 -0700
@@ -1101,9 +1101,9 @@
 	dma_rd = eni_in(MID_DMA_RD_TX);
 	dma_size = 3; /* JK for descriptor and final fill, plus final size
 			 mis-alignment fix */
-DPRINTK("iovcnt = %d\n",ATM_SKB(skb)->iovcnt);
-	if (!ATM_SKB(skb)->iovcnt) dma_size += 5;
-	else dma_size += 5*ATM_SKB(skb)->iovcnt;
+DPRINTK("iovcnt = %d\n",skb_shinfo(skb)->nr_frags);
+	if (!skb_shinfo(skb)->nr_frags) dma_size += 5;
+	else dma_size += 5*(skb_shinfo(skb)->nr_frags+1);
 	if (dma_size > TX_DMA_BUF) {
 		printk(KERN_CRIT DEV_LABEL "(itf %d): needs %d DMA entries "
 		    "(got only %d)\n",vcc->dev->number,dma_size,TX_DMA_BUF);
@@ -1124,15 +1124,20 @@
 	     MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) |
 	     MID_DT_JK;
 	j++;
-	if (!ATM_SKB(skb)->iovcnt)
+	if (!skb_shinfo(skb)->nr_frags)
 		if (aal5) put_dma(tx->index,eni_dev->dma,&j,paddr,skb->len);
 		else put_dma(tx->index,eni_dev->dma,&j,paddr+4,skb->len-4);
 	else {
 DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */
-		for (i = 0; i < ATM_SKB(skb)->iovcnt; i++)
-			put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
-			    ((struct iovec *) skb->data)[i].iov_base,
-			    ((struct iovec *) skb->data)[i].iov_len);
+		for (i = -1; i < skb_shinfo(skb)->nr_frags; i++)
+			if (i == -1)
+				put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
+				    skb->data,
+				    skb->len - skb->data_len);
+			else
+				put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
+				    skb_shinfo(skb)->frags[i].page + skb_shinfo(skb)->frags[i].page_offset,
+				    skb_shinfo(skb)->frags[i].size);
 	}
 	if (skb->len & 3)
 		put_dma(tx->index,eni_dev->dma,&j,zeroes,4-(skb->len & 3));
diff -urN linux-2.4.22-pre2/drivers/atm/he.c linux-2.4.22-pre3/drivers/atm/he.c
--- linux-2.4.22-pre2/drivers/atm/he.c	2003-07-05 18:09:17.000000000 -0700
+++ linux-2.4.22-pre3/drivers/atm/he.c	2003-07-05 18:09:55.000000000 -0700
@@ -51,7 +51,7 @@
 	4096 supported 'connections'
 	group 0 is used for all traffic
 	interrupt queue 0 is used for all interrupts
-	aal0 support for receive only
+	aal0 support (based on work from ulrich.u.muller@nokia.com)
 
  */
 
@@ -77,17 +77,8 @@
 #include <linux/atmdev.h>
 #include <linux/atm.h>
 #include <linux/sonet.h>
-#ifndef ATM_OC12_PCR
-#define ATM_OC12_PCR (622080000/1080*1040/8/53)
-#endif
-
-#ifdef BUS_INT_WAR
-void sn_add_polled_interrupt(int irq, int interval);
-void sn_delete_polled_interrupt(int irq);
-#endif
 
 #define USE_TASKLET
-#define USE_HE_FIND_VCC
 #undef USE_SCATTERGATHER
 #undef USE_CHECKSUM_HW			/* still confused about this */
 #define USE_RBPS
@@ -96,16 +87,30 @@
 #define USE_TPD_POOL
 /* #undef CONFIG_ATM_HE_USE_SUNI */
 
-/* 2.2 kernel support */
+/* compatibility */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
+typedef void irqreturn_t;
+#define IRQ_NONE
+#define IRQ_HANDLED
+#define IRQ_RETVAL(x)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
+#define __devexit_p(func)		func
+#endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)
-#define dev_kfree_skb_irq(skb)		dev_kfree_skb(skb)
-#define dev_kfree_skb_any(skb)		dev_kfree_skb(skb)
-#undef USE_TASKLET
+#ifndef MODULE_LICENSE
+#define MODULE_LICENSE(x)
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
-#define set_current_state(x)		current->state = (x);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
+#define pci_set_drvdata(pci_dev, data)	(pci_dev)->driver_data = (data)
+#define pci_get_drvdata(pci_dev)	(pci_dev)->driver_data
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,44)
+#define pci_pool_create(a, b, c, d, e)	pci_pool_create(a, b, c, d, e, SLAB_KERNEL)
 #endif
 
 #include "he.h"
@@ -114,16 +119,13 @@
 
 #include <linux/atm_he.h>
 
-#define hprintk(fmt,args...)	printk(DEV_LABEL "%d: " fmt, he_dev->number, args)
-#define hprintk1(fmt)		printk(DEV_LABEL "%d: " fmt, he_dev->number)
+#define hprintk(fmt,args...)	printk(KERN_ERR DEV_LABEL "%d: " fmt, he_dev->number , ##args)
 
 #undef DEBUG
 #ifdef DEBUG
-#define HPRINTK(fmt,args...)	hprintk(fmt,args)
-#define HPRINTK1(fmt)		hprintk1(fmt)
+#define HPRINTK(fmt,args...)	printk(KERN_DEBUG DEV_LABEL "%d: " fmt, he_dev->number , ##args)
 #else
-#define HPRINTK(fmt,args...)
-#define HPRINTK1(fmt,args...)
+#define HPRINTK(fmt,args...)	do { } while (0)
 #endif /* DEBUG */
 
 
@@ -131,10 +133,6 @@
 
 static char *version = "$Id: he.c,v 1.18 2003/05/06 22:57:15 chas Exp $";
 
-/* defines */
-#define ALIGN_ADDRESS(addr, alignment) \
-	((((unsigned long) (addr)) + (((unsigned long) (alignment)) - 1)) & ~(((unsigned long) (alignment)) - 1))
-
 /* declarations */
 
 static int he_open(struct atm_vcc *vcc, short vpi, int vci);
@@ -142,11 +140,7 @@
 static int he_send(struct atm_vcc *vcc, struct sk_buff *skb);
 static int he_sg_send(struct atm_vcc *vcc, unsigned long start, unsigned long size);
 static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,69)
 static irqreturn_t he_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
-#else
-static void he_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
-#endif
 static void he_tasklet(unsigned long data);
 static int he_proc_read(struct atm_dev *dev,loff_t *pos,char *page);
 static int he_start(struct atm_dev *dev);
@@ -168,25 +162,18 @@
 
 static struct atmdev_ops he_ops =
 {
-   open:	he_open,
-   close:	he_close,	
-   ioctl:	he_ioctl,	
-   send:	he_send,
-   sg_send:	he_sg_send,	
-   phy_put:	he_phy_put,
-   phy_get:	he_phy_get,
-   proc_read:	he_proc_read,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,1)
-   owner:	THIS_MODULE
-#endif
+	.open =		he_open,
+	.close =	he_close,	
+	.ioctl =	he_ioctl,	
+	.send =		he_send,
+	.sg_send =	he_sg_send,	
+	.phy_put =	he_phy_put,
+	.phy_get =	he_phy_get,
+	.proc_read =	he_proc_read,
+	.owner =	THIS_MODULE
 };
 
-/* see the comments in he.h about global_lock */
-
-#define HE_SPIN_LOCK(dev, flags)	spin_lock_irqsave(&(dev)->global_lock, flags)
-#define HE_SPIN_UNLOCK(dev, flags)	spin_unlock_irqrestore(&(dev)->global_lock, flags)
-
-#define he_writel(dev, val, reg)	do { writel(val, (dev)->membase + (reg)); wmb(); } while(0)
+#define he_writel(dev, val, reg)	do { writel(val, (dev)->membase + (reg)); wmb(); } while (0)
 #define he_readl(dev, reg)		readl((dev)->membase + (reg))
 
 /* section 2.12 connection memory access */
@@ -200,7 +187,7 @@
 	(void) he_readl(he_dev, CON_DAT);
 #endif
 	he_writel(he_dev, flags | CON_CTL_WRITE | CON_CTL_ADDR(addr), CON_CTL);
-	while(he_readl(he_dev, CON_CTL) & CON_CTL_BUSY);
+	while (he_readl(he_dev, CON_CTL) & CON_CTL_BUSY);
 }
 
 #define he_writel_rcm(dev, val, reg) 				\
@@ -216,7 +203,7 @@
 he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags)
 {
 	he_writel(he_dev, flags | CON_CTL_READ | CON_CTL_ADDR(addr), CON_CTL);
-	while(he_readl(he_dev, CON_CTL) & CON_CTL_BUSY);
+	while (he_readl(he_dev, CON_CTL) & CON_CTL_BUSY);
 	return he_readl(he_dev, CON_DAT);
 }
 
@@ -232,26 +219,26 @@
 
 /* figure 2.2 connection id */
 
-#define he_mkcid(dev, vpi, vci)		(((vpi<<(dev)->vcibits) | vci) & 0x1fff)
+#define he_mkcid(dev, vpi, vci)		(((vpi << (dev)->vcibits) | vci) & 0x1fff)
 
 /* 2.5.1 per connection transmit state registers */
 
 #define he_writel_tsr0(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 0)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 0)
 #define he_readl_tsr0(dev, cid) \
-		he_readl_tcm(dev, CONFIG_TSRA | (cid<<3) | 0)
+		he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 0)
 
 #define he_writel_tsr1(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 1)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 1)
 
 #define he_writel_tsr2(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 2)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 2)
 
 #define he_writel_tsr3(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 3)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 3)
 
 #define he_writel_tsr4(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 4)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 4)
 
 	/* from page 2-20
 	 *
@@ -262,43 +249,43 @@
 	 */
 
 #define he_writel_tsr4_upper(dev, val, cid) \
-		he_writel_internal(dev, val, CONFIG_TSRA | (cid<<3) | 4, \
+		he_writel_internal(dev, val, CONFIG_TSRA | (cid << 3) | 4, \
 							CON_CTL_TCM \
 							| CON_BYTE_DISABLE_2 \
 							| CON_BYTE_DISABLE_1 \
 							| CON_BYTE_DISABLE_0)
 
 #define he_readl_tsr4(dev, cid) \
-		he_readl_tcm(dev, CONFIG_TSRA | (cid<<3) | 4)
+		he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 4)
 
 #define he_writel_tsr5(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 5)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 5)
 
 #define he_writel_tsr6(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 6)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 6)
 
 #define he_writel_tsr7(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 7)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 7)
 
 
 #define he_writel_tsr8(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 0)
+		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 0)
 
 #define he_writel_tsr9(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 1)
+		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 1)
 
 #define he_writel_tsr10(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 2)
+		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 2)
 
 #define he_writel_tsr11(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 3)
+		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 3)
 
 
 #define he_writel_tsr12(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRC | (cid<<1) | 0)
+		he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 0)
 
 #define he_writel_tsr13(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRC | (cid<<1) | 1)
+		he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 1)
 
 
 #define he_writel_tsr14(dev, val, cid) \
@@ -314,30 +301,30 @@
 /* 2.7.1 per connection receive state registers */
 
 #define he_writel_rsr0(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 0)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 0)
 #define he_readl_rsr0(dev, cid) \
-		he_readl_rcm(dev, 0x00000 | (cid<<3) | 0)
+		he_readl_rcm(dev, 0x00000 | (cid << 3) | 0)
 
 #define he_writel_rsr1(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 1)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 1)
 
 #define he_writel_rsr2(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 2)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 2)
 
 #define he_writel_rsr3(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 3)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 3)
 
 #define he_writel_rsr4(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 4)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 4)
 
 #define he_writel_rsr5(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 5)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 5)
 
 #define he_writel_rsr6(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 6)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 6)
 
 #define he_writel_rsr7(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 7)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 7)
 
 static __inline__ struct atm_vcc*
 he_find_vcc(struct he_dev *he_dev, unsigned cid)
@@ -347,7 +334,7 @@
 	int vci;
 
 	vpi = cid >> he_dev->vcibits;
-	vci = cid & ((1<<he_dev->vcibits)-1);
+	vci = cid & ((1 << he_dev->vcibits) - 1);
 
 	for (vcc = he_dev->atm_dev->vccs; vcc; vcc = vcc->next)
 		if (vcc->vci == vci && vcc->vpi == vpi
@@ -359,49 +346,58 @@
 static int __devinit
 he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
 {
-	struct atm_dev *atm_dev;
-	struct he_dev *he_dev;
+	struct atm_dev *atm_dev = NULL;
+	struct he_dev *he_dev = NULL;
+	int err = 0;
 
 	printk(KERN_INFO "he: %s\n", version);
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,43)
-	if (pci_enable_device(pci_dev)) return -EIO;
-#endif
-	if (pci_set_dma_mask(pci_dev, HE_DMA_MASK) != 0)
-	{
-		printk(KERN_WARNING "he: no suitable dma available\n");
+	if (pci_enable_device(pci_dev))
 		return -EIO;
+	if (pci_set_dma_mask(pci_dev, HE_DMA_MASK) != 0) {
+		printk(KERN_WARNING "he: no suitable dma available\n");
+		err = -EIO;
+		goto init_one_failure;
 	}
 
 	atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, 0);
-	if (!atm_dev) return -ENODEV;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,3)
+	if (!atm_dev) {
+		err = -ENODEV;
+		goto init_one_failure;
+	}
 	pci_set_drvdata(pci_dev, atm_dev);
-#else
-	pci_dev->driver_data = atm_dev;
-#endif
 
 	he_dev = (struct he_dev *) kmalloc(sizeof(struct he_dev),
 							GFP_KERNEL);
-	if (!he_dev) return -ENOMEM;
+	if (!he_dev) {
+		err = -ENOMEM;
+		goto init_one_failure;
+	}
 	memset(he_dev, 0, sizeof(struct he_dev));
 
 	he_dev->pci_dev = pci_dev;
 	he_dev->atm_dev = atm_dev;
 	he_dev->atm_dev->dev_data = he_dev;
 	HE_DEV(atm_dev) = he_dev;
-	he_dev->number = atm_dev->number;	/* was devs */
+	he_dev->number = atm_dev->number;
 	if (he_start(atm_dev)) {
-		atm_dev_deregister(atm_dev);
 		he_stop(he_dev);
-		kfree(he_dev);
-		return -ENODEV;
+		err = -ENODEV;
+		goto init_one_failure;
 	}
 	he_dev->next = NULL;
-	if (he_devs) he_dev->next = he_devs;
+	if (he_devs)
+		he_dev->next = he_devs;
 	he_devs = he_dev;
-
 	return 0;
+
+init_one_failure:
+	if (atm_dev)
+		atm_dev_deregister(atm_dev);
+	if (he_dev)
+		kfree(he_dev);
+	pci_disable_device(pci_dev);
+	return err;
 }
 
 static void __devexit
@@ -410,11 +406,7 @@
 	struct atm_dev *atm_dev;
 	struct he_dev *he_dev;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,3)
 	atm_dev = pci_get_drvdata(pci_dev);
-#else
-	atm_dev = pci_dev->driver_data;
-#endif
 	he_dev = HE_DEV(atm_dev);
 
 	/* need to remove from he_devs */
@@ -423,129 +415,120 @@
 	atm_dev_deregister(atm_dev);
 	kfree(he_dev);
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,3)
 	pci_set_drvdata(pci_dev, NULL);
-#else
-	pci_dev->driver_data = NULL;
-#endif
+	pci_disable_device(pci_dev);
 }
 
 
 static unsigned
 rate_to_atmf(unsigned rate)		/* cps to atm forum format */
 {
-#define NONZERO (1<<14)
+#define NONZERO (1 << 14)
 
-        unsigned exp = 0;
+	unsigned exp = 0;
 
-        if (rate == 0) return(0);
+	if (rate == 0)
+		return 0;
 
-        rate <<= 9;
-        while (rate > 0x3ff)
-        {
-                ++exp;
-                rate >>= 1;
-        }
+	rate <<= 9;
+	while (rate > 0x3ff) {
+		++exp;
+		rate >>= 1;
+	}
 
-        return (NONZERO | (exp << 9) | (rate & 0x1ff));
+	return (NONZERO | (exp << 9) | (rate & 0x1ff));
 }
 
 static void __init
 he_init_rx_lbfp0(struct he_dev *he_dev)
 {
-        unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-        unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-        unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-        unsigned row_offset = he_dev->r0_startrow * he_dev->bytes_per_row;
-        
+	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
+	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
+	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
+	unsigned row_offset = he_dev->r0_startrow * he_dev->bytes_per_row;
+	
 	lbufd_index = 0;
-        lbm_offset = he_readl(he_dev, RCMLBM_BA);
+	lbm_offset = he_readl(he_dev, RCMLBM_BA);
 
 	he_writel(he_dev, lbufd_index, RLBF0_H);
 
-        for (i = 0, lbuf_count = 0; i < he_dev->r0_numbuffs; ++i)
-        {
+	for (i = 0, lbuf_count = 0; i < he_dev->r0_numbuffs; ++i) {
 		lbufd_index += 2;
-                lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
+		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
 
 		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
 		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
 
-                if (++lbuf_count == lbufs_per_row)
-                {
-                        lbuf_count = 0;
-                        row_offset += he_dev->bytes_per_row;
-                }
+		if (++lbuf_count == lbufs_per_row) {
+			lbuf_count = 0;
+			row_offset += he_dev->bytes_per_row;
+		}
 		lbm_offset += 4;
-        }
-                
-        he_writel(he_dev, lbufd_index - 2, RLBF0_T);
+	}
+		
+	he_writel(he_dev, lbufd_index - 2, RLBF0_T);
 	he_writel(he_dev, he_dev->r0_numbuffs, RLBF0_C);
 }
 
 static void __init
 he_init_rx_lbfp1(struct he_dev *he_dev)
 {
-        unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-        unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-        unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-        unsigned row_offset = he_dev->r1_startrow * he_dev->bytes_per_row;
-        
+	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
+	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
+	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
+	unsigned row_offset = he_dev->r1_startrow * he_dev->bytes_per_row;
+	
 	lbufd_index = 1;
-        lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
+	lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
 
 	he_writel(he_dev, lbufd_index, RLBF1_H);
 
-        for (i = 0, lbuf_count = 0; i < he_dev->r1_numbuffs; ++i)
-        {
+	for (i = 0, lbuf_count = 0; i < he_dev->r1_numbuffs; ++i) {
 		lbufd_index += 2;
-                lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
+		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
 
 		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
 		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
 
-                if (++lbuf_count == lbufs_per_row)
-                {
-                        lbuf_count = 0;
-                        row_offset += he_dev->bytes_per_row;
-                }
+		if (++lbuf_count == lbufs_per_row) {
+			lbuf_count = 0;
+			row_offset += he_dev->bytes_per_row;
+		}
 		lbm_offset += 4;
-        }
-                
-        he_writel(he_dev, lbufd_index - 2, RLBF1_T);
+	}
+		
+	he_writel(he_dev, lbufd_index - 2, RLBF1_T);
 	he_writel(he_dev, he_dev->r1_numbuffs, RLBF1_C);
 }
 
 static void __init
 he_init_tx_lbfp(struct he_dev *he_dev)
 {
-        unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-        unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-        unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-        unsigned row_offset = he_dev->tx_startrow * he_dev->bytes_per_row;
-        
+	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
+	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
+	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
+	unsigned row_offset = he_dev->tx_startrow * he_dev->bytes_per_row;
+	
 	lbufd_index = he_dev->r0_numbuffs + he_dev->r1_numbuffs;
-        lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
+	lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
 
 	he_writel(he_dev, lbufd_index, TLBF_H);
 
-        for (i = 0, lbuf_count = 0; i < he_dev->tx_numbuffs; ++i)
-        {
+	for (i = 0, lbuf_count = 0; i < he_dev->tx_numbuffs; ++i) {
 		lbufd_index += 1;
-                lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
+		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
 
 		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
 		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
 
-                if (++lbuf_count == lbufs_per_row)
-                {
-                        lbuf_count = 0;
-                        row_offset += he_dev->bytes_per_row;
-                }
+		if (++lbuf_count == lbufs_per_row) {
+			lbuf_count = 0;
+			row_offset += he_dev->bytes_per_row;
+		}
 		lbm_offset += 2;
-        }
-                
-        he_writel(he_dev, lbufd_index - 1, TLBF_T);
+	}
+		
+	he_writel(he_dev, lbufd_index - 1, TLBF_T);
 }
 
 static int __init
@@ -553,9 +536,8 @@
 {
 	he_dev->tpdrq_base = pci_alloc_consistent(he_dev->pci_dev,
 		CONFIG_TPDRQ_SIZE * sizeof(struct he_tpdrq), &he_dev->tpdrq_phys);
-	if (he_dev->tpdrq_base == NULL) 
-	{
-		hprintk1("failed to alloc tpdrq\n");
+	if (he_dev->tpdrq_base == NULL) {
+		hprintk("failed to alloc tpdrq\n");
 		return -ENOMEM;
 	}
 	memset(he_dev->tpdrq_base, 0,
@@ -579,7 +561,7 @@
 
 	/* 5.1.7 cs block initialization */
 
-	for(reg = 0; reg < 0x20; ++reg)
+	for (reg = 0; reg < 0x20; ++reg)
 		he_writel_mbox(he_dev, 0x0, CS_STTIM0 + reg);
 
 	/* rate grid timer reload values */
@@ -588,8 +570,7 @@
 	rate = he_dev->atm_dev->link_rate;
 	delta = rate / 16 / 2;
 
-	for(reg = 0; reg < 0x10; ++reg)
-	{
+	for (reg = 0; reg < 0x10; ++reg) {
 		/* 2.4 internal transmit function
 		 *
 	 	 * we initialize the first row in the rate grid.
@@ -601,8 +582,7 @@
 		rate -= delta;
 	}
 
-	if (he_is622(he_dev))
-	{
+	if (he_is622(he_dev)) {
 		/* table 5.2 (4 cells per lbuf) */
 		he_writel_mbox(he_dev, 0x000800fa, CS_ERTHR0);
 		he_writel_mbox(he_dev, 0x000c33cb, CS_ERTHR1);
@@ -631,9 +611,7 @@
 		/* table 5.9 */
 		he_writel_mbox(he_dev, 0x5, CS_OTPPER);
 		he_writel_mbox(he_dev, 0x14, CS_OTWPER);
-	}
-	else
-	{
+	} else {
 		/* table 5.1 (4 cells per lbuf) */
 		he_writel_mbox(he_dev, 0x000400ea, CS_ERTHR0);
 		he_writel_mbox(he_dev, 0x00063388, CS_ERTHR1);
@@ -662,26 +640,29 @@
 		/* table 5.9 */
 		he_writel_mbox(he_dev, 0x6, CS_OTPPER);
 		he_writel_mbox(he_dev, 0x1e, CS_OTWPER);
-
 	}
 
 	he_writel_mbox(he_dev, 0x8, CS_OTTLIM);
 
-	for(reg = 0; reg < 0x8; ++reg)
+	for (reg = 0; reg < 0x8; ++reg)
 		he_writel_mbox(he_dev, 0x0, CS_HGRRT0 + reg);
 
 }
 
-static void __init
+static int __init
 he_init_cs_block_rcm(struct he_dev *he_dev)
 {
-	unsigned rategrid[16][16];
+	unsigned (*rategrid)[16][16];
 	unsigned rate, delta;
 	int i, j, reg;
 
 	unsigned rate_atmf, exp, man;
 	unsigned long long rate_cps;
-        int mult, buf, buf_limit = 4;
+	int mult, buf, buf_limit = 4;
+
+	rategrid = kmalloc( sizeof(unsigned) * 16 * 16, GFP_KERNEL);
+	if (!rategrid)
+		return -ENOMEM;
 
 	/* initialize rate grid group table */
 
@@ -711,18 +692,17 @@
 	 * in order to construct the rate to group table below
 	 */
 
-	for (j = 0; j < 16; j++)
-	{
-		rategrid[0][j] = rate;
+	for (j = 0; j < 16; j++) {
+		(*rategrid)[0][j] = rate;
 		rate -= delta;
 	}
 
 	for (i = 1; i < 16; i++)
 		for (j = 0; j < 16; j++)
 			if (i > 14)
-				rategrid[i][j] = rategrid[i - 1][j] / 4;
+				(*rategrid)[i][j] = (*rategrid)[i - 1][j] / 4;
 			else
-				rategrid[i][j] = rategrid[i - 1][j] / 2;
+				(*rategrid)[i][j] = (*rategrid)[i - 1][j] / 2;
 
 	/*
 	 * 2.4 transmit internal function
@@ -733,8 +713,7 @@
 	 */
 
 	rate_atmf = 0;
-	while (rate_atmf < 0x400)
-	{
+	while (rate_atmf < 0x400) {
 		man = (rate_atmf & 0x1f) << 4;
 		exp = rate_atmf >> 5;
 
@@ -744,12 +723,12 @@
 		*/
 		rate_cps = (unsigned long long) (1 << exp) * (man + 512) >> 9;
 
-		if (rate_cps < 10) rate_cps = 10;
-				/* 2.2.1 minimum payload rate is 10 cps */
+		if (rate_cps < 10)
+			rate_cps = 10;	/* 2.2.1 minimum payload rate is 10 cps */
 
 		for (i = 255; i > 0; i--)
-			if (rategrid[i/16][i%16] >= rate_cps) break;
-				/* pick nearest rate instead? */
+			if ((*rategrid)[i/16][i%16] >= rate_cps)
+				break;	 /* pick nearest rate instead? */
 
 		/*
 		 * each table entry is 16 bits: (rate grid index (8 bits)
@@ -758,28 +737,37 @@
 		 */
 
 #ifdef notdef
-                buf = rate_cps * he_dev->tx_numbuffs /
+		buf = rate_cps * he_dev->tx_numbuffs /
 				(he_dev->atm_dev->link_rate * 2);
 #else
 		/* this is pretty, but avoids _divdu3 and is mostly correct */
-                buf = 0;
-                mult = he_dev->atm_dev->link_rate / ATM_OC3_PCR;
-                if (rate_cps > (68 * mult)) buf = 1;
-                if (rate_cps > (136 * mult)) buf = 2;
-                if (rate_cps > (204 * mult)) buf = 3;
-                if (rate_cps > (272 * mult)) buf = 4;
+		mult = he_dev->atm_dev->link_rate / ATM_OC3_PCR;
+		if (rate_cps > (272 * mult))
+			buf = 4;
+		else if (rate_cps > (204 * mult))
+			buf = 3;
+		else if (rate_cps > (136 * mult))
+			buf = 2;
+		else if (rate_cps > (68 * mult))
+			buf = 1;
+		else
+			buf = 0;
 #endif
-                if (buf > buf_limit) buf = buf_limit;
-		reg = (reg<<16) | ((i<<8) | buf);
+		if (buf > buf_limit)
+			buf = buf_limit;
+		reg = (reg << 16) | ((i << 8) | buf);
 
 #define RTGTBL_OFFSET 0x400
 	  
 		if (rate_atmf & 0x1)
 			he_writel_rcm(he_dev, reg,
-				CONFIG_RCMABR + RTGTBL_OFFSET + (rate_atmf>>1));
+				CONFIG_RCMABR + RTGTBL_OFFSET + (rate_atmf >> 1));
 
 		++rate_atmf;
 	}
+
+	kfree(rategrid);
+	return 0;
 }
 
 static int __init
@@ -790,39 +778,31 @@
 #ifdef USE_RBPS
 	/* small buffer pool */
 #ifdef USE_RBPS_POOL
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,44)
-	he_dev->rbps_pool = pci_pool_create("rbps", he_dev->pci_dev,
-			CONFIG_RBPS_BUFSIZE, 8, 0, SLAB_KERNEL);
-#else
 	he_dev->rbps_pool = pci_pool_create("rbps", he_dev->pci_dev,
 			CONFIG_RBPS_BUFSIZE, 8, 0);
-#endif
-	if (he_dev->rbps_pool == NULL)
-	{
-		hprintk1("unable to create rbps pages\n");
+	if (he_dev->rbps_pool == NULL) {
+		hprintk("unable to create rbps pages\n");
 		return -ENOMEM;
 	}
 #else /* !USE_RBPS_POOL */
 	he_dev->rbps_pages = pci_alloc_consistent(he_dev->pci_dev,
 		CONFIG_RBPS_SIZE * CONFIG_RBPS_BUFSIZE, &he_dev->rbps_pages_phys);
 	if (he_dev->rbps_pages == NULL) {
-		hprintk1("unable to create rbps page pool\n");
+		hprintk("unable to create rbps page pool\n");
 		return -ENOMEM;
 	}
 #endif /* USE_RBPS_POOL */
 
 	he_dev->rbps_base = pci_alloc_consistent(he_dev->pci_dev,
 		CONFIG_RBPS_SIZE * sizeof(struct he_rbp), &he_dev->rbps_phys);
-	if (he_dev->rbps_base == NULL)
-	{
-		hprintk1("failed to alloc rbps\n");
+	if (he_dev->rbps_base == NULL) {
+		hprintk("failed to alloc rbps\n");
 		return -ENOMEM;
 	}
 	memset(he_dev->rbps_base, 0, CONFIG_RBPS_SIZE * sizeof(struct he_rbp));
 	he_dev->rbps_virt = kmalloc(CONFIG_RBPS_SIZE * sizeof(struct he_virt), GFP_KERNEL);
 
-	for (i = 0; i < CONFIG_RBPS_SIZE; ++i)
-	{
+	for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
 		dma_addr_t dma_handle;
 		void *cpuaddr;
 
@@ -840,7 +820,7 @@
 		he_dev->rbps_base[i].phys = dma_handle;
 
 	}
-	he_dev->rbps_tail = &he_dev->rbps_base[CONFIG_RBPS_SIZE-1];
+	he_dev->rbps_tail = &he_dev->rbps_base[CONFIG_RBPS_SIZE - 1];
 
 	he_writel(he_dev, he_dev->rbps_phys, G0_RBPS_S + (group * 32));
 	he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail),
@@ -849,7 +829,7 @@
 						G0_RBPS_BS + (group * 32));
 	he_writel(he_dev,
 			RBP_THRESH(CONFIG_RBPS_THRESH) |
-			RBP_QSIZE(CONFIG_RBPS_SIZE-1) |
+			RBP_QSIZE(CONFIG_RBPS_SIZE - 1) |
 			RBP_INT_ENB,
 						G0_RBPS_QI + (group * 32));
 #else /* !USE_RBPS */
@@ -862,40 +842,31 @@
 
 	/* large buffer pool */
 #ifdef USE_RBPL_POOL
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,44)
-	he_dev->rbpl_pool = pci_pool_create("rbpl", he_dev->pci_dev,
-			CONFIG_RBPL_BUFSIZE, 8, 0, SLAB_KERNEL);
-#else
 	he_dev->rbpl_pool = pci_pool_create("rbpl", he_dev->pci_dev,
 			CONFIG_RBPL_BUFSIZE, 8, 0);
-#endif
-	if (he_dev->rbpl_pool == NULL)
-	{
-		hprintk1("unable to create rbpl pool\n");
+	if (he_dev->rbpl_pool == NULL) {
+		hprintk("unable to create rbpl pool\n");
 		return -ENOMEM;
 	}
 #else /* !USE_RBPL_POOL */
 	he_dev->rbpl_pages = (void *) pci_alloc_consistent(he_dev->pci_dev,
 		CONFIG_RBPL_SIZE * CONFIG_RBPL_BUFSIZE, &he_dev->rbpl_pages_phys);
-	if (he_dev->rbpl_pages == NULL)
-	{
-		hprintk1("unable to create rbpl pages\n");
+	if (he_dev->rbpl_pages == NULL) {
+		hprintk("unable to create rbpl pages\n");
 		return -ENOMEM;
 	}
 #endif /* USE_RBPL_POOL */
 
 	he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev,
 		CONFIG_RBPL_SIZE * sizeof(struct he_rbp), &he_dev->rbpl_phys);
-	if (he_dev->rbpl_base == NULL)
-	{
-		hprintk1("failed to alloc rbpl\n");
+	if (he_dev->rbpl_base == NULL) {
+		hprintk("failed to alloc rbpl\n");
 		return -ENOMEM;
 	}
 	memset(he_dev->rbpl_base, 0, CONFIG_RBPL_SIZE * sizeof(struct he_rbp));
 	he_dev->rbpl_virt = kmalloc(CONFIG_RBPL_SIZE * sizeof(struct he_virt), GFP_KERNEL);
 
-	for (i = 0; i < CONFIG_RBPL_SIZE; ++i)
-	{
+	for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
 		dma_addr_t dma_handle;
 		void *cpuaddr;
 
@@ -911,9 +882,8 @@
 		he_dev->rbpl_virt[i].virt = cpuaddr;
 		he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF);
 		he_dev->rbpl_base[i].phys = dma_handle;
-
 	}
-	he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE-1];
+	he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE - 1];
 
 	he_writel(he_dev, he_dev->rbpl_phys, G0_RBPL_S + (group * 32));
 	he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail),
@@ -922,7 +892,7 @@
 						G0_RBPL_BS + (group * 32));
 	he_writel(he_dev,
 			RBP_THRESH(CONFIG_RBPL_THRESH) |
-			RBP_QSIZE(CONFIG_RBPL_SIZE-1) |
+			RBP_QSIZE(CONFIG_RBPL_SIZE - 1) |
 			RBP_INT_ENB,
 						G0_RBPL_QI + (group * 32));
 
@@ -930,9 +900,8 @@
 
 	he_dev->rbrq_base = pci_alloc_consistent(he_dev->pci_dev,
 		CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), &he_dev->rbrq_phys);
-	if (he_dev->rbrq_base == NULL)
-	{
-		hprintk1("failed to allocate rbrq\n");
+	if (he_dev->rbrq_base == NULL) {
+		hprintk("failed to allocate rbrq\n");
 		return -ENOMEM;
 	}
 	memset(he_dev->rbrq_base, 0, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq));
@@ -941,15 +910,13 @@
 	he_writel(he_dev, he_dev->rbrq_phys, G0_RBRQ_ST + (group * 16));
 	he_writel(he_dev, 0, G0_RBRQ_H + (group * 16));
 	he_writel(he_dev,
-		RBRQ_THRESH(CONFIG_RBRQ_THRESH) | RBRQ_SIZE(CONFIG_RBRQ_SIZE-1),
+		RBRQ_THRESH(CONFIG_RBRQ_THRESH) | RBRQ_SIZE(CONFIG_RBRQ_SIZE - 1),
 						G0_RBRQ_Q + (group * 16));
-	if (irq_coalesce)
-	{
-		hprintk1("coalescing interrupts\n");
+	if (irq_coalesce) {
+		hprintk("coalescing interrupts\n");
 		he_writel(he_dev, RBRQ_TIME(768) | RBRQ_COUNT(7),
 						G0_RBRQ_I + (group * 16));
-	}
-	else
+	} else
 		he_writel(he_dev, RBRQ_TIME(0) | RBRQ_COUNT(1),
 						G0_RBRQ_I + (group * 16));
 
@@ -957,9 +924,8 @@
 
 	he_dev->tbrq_base = pci_alloc_consistent(he_dev->pci_dev,
 		CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq), &he_dev->tbrq_phys);
-	if (he_dev->tbrq_base == NULL)
-	{
-		hprintk1("failed to allocate tbrq\n");
+	if (he_dev->tbrq_base == NULL) {
+		hprintk("failed to allocate tbrq\n");
 		return -ENOMEM;
 	}
 	memset(he_dev->tbrq_base, 0, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq));
@@ -982,11 +948,10 @@
 	/* 2.9.3.5  tail offset for each interrupt queue is located after the
 		    end of the interrupt queue */
 
-        he_dev->irq_base = pci_alloc_consistent(he_dev->pci_dev,
+	he_dev->irq_base = pci_alloc_consistent(he_dev->pci_dev,
 			(CONFIG_IRQ_SIZE+1) * sizeof(struct he_irq), &he_dev->irq_phys);
-	if (he_dev->irq_base == NULL)
-	{
-		hprintk1("failed to allocate irq\n");
+	if (he_dev->irq_base == NULL) {
+		hprintk("failed to allocate irq\n");
 		return -ENOMEM;
 	}
 	he_dev->irq_tailoffset = (unsigned *)
@@ -995,7 +960,7 @@
 	he_dev->irq_head = he_dev->irq_base;
 	he_dev->irq_tail = he_dev->irq_base;
 
-	for(i=0; i < CONFIG_IRQ_SIZE; ++i)
+	for (i = 0; i < CONFIG_IRQ_SIZE; ++i)
 		he_dev->irq_base[i].isw = ITYPE_INVALID;
 
 	he_writel(he_dev, he_dev->irq_phys, IRQ0_BASE);
@@ -1027,27 +992,21 @@
 	he_writel(he_dev, 0x0, GRP_54_MAP);
 	he_writel(he_dev, 0x0, GRP_76_MAP);
 
-	if (request_irq(he_dev->pci_dev->irq, he_irq_handler, SA_INTERRUPT|SA_SHIRQ, DEV_LABEL, he_dev))
-	{
+	if (request_irq(he_dev->pci_dev->irq, he_irq_handler, SA_INTERRUPT|SA_SHIRQ, DEV_LABEL, he_dev)) {
 		hprintk("irq %d already in use\n", he_dev->pci_dev->irq);
 		return -EINVAL;
-        }   
+	}   
 
 	he_dev->irq = he_dev->pci_dev->irq;
 
-#ifdef BUS_INT_WAR
-        HPRINTK("sn_add_polled_interrupt(irq %d, 1)\n", he_dev->irq);
-        sn_add_polled_interrupt(he_dev->irq, 1);
-#endif
-
 	return 0;
 }
 
 static int __init
 he_start(struct atm_dev *dev)
 {
-        struct he_dev *he_dev;
-        struct pci_dev *pci_dev;
+	struct he_dev *he_dev;
+	struct pci_dev *pci_dev;
 
 	u16 command;
 	u32 gen_cntl_0, host_cntl, lb_swap;
@@ -1057,14 +1016,10 @@
 	unsigned int status, reg;
 	int i, group;
 
-        he_dev = HE_DEV(dev);
-        pci_dev = he_dev->pci_dev;
+	he_dev = HE_DEV(dev);
+	pci_dev = he_dev->pci_dev;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,3)
 	he_dev->membase = pci_dev->resource[0].start;
-#else
-	he_dev->membase = pci_dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
-#endif
 	HPRINTK("membase = 0x%lx  irq = %d.\n", he_dev->membase, pci_dev->irq);
 
 	/*
@@ -1072,47 +1027,40 @@
 	 */
 
 	/* 4.3 pci bus controller-specific initialization */
-	if (pci_read_config_dword(pci_dev, GEN_CNTL_0, &gen_cntl_0) != 0)
-	{
-		hprintk1("can't read GEN_CNTL_0\n");
+	if (pci_read_config_dword(pci_dev, GEN_CNTL_0, &gen_cntl_0) != 0) {
+		hprintk("can't read GEN_CNTL_0\n");
 		return -EINVAL;
 	}
 	gen_cntl_0 |= (MRL_ENB | MRM_ENB | IGNORE_TIMEOUT);
-	if (pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0) != 0)
-	{
-		hprintk1("can't write GEN_CNTL_0.\n");
+	if (pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0) != 0) {
+		hprintk("can't write GEN_CNTL_0.\n");
 		return -EINVAL;
 	}
 
-	if (pci_read_config_word(pci_dev, PCI_COMMAND, &command) != 0)
-	{
-		hprintk1("can't read PCI_COMMAND.\n");
+	if (pci_read_config_word(pci_dev, PCI_COMMAND, &command) != 0) {
+		hprintk("can't read PCI_COMMAND.\n");
 		return -EINVAL;
 	}
 
 	command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
-	if (pci_write_config_word(pci_dev, PCI_COMMAND, command) != 0)
-	{
-		hprintk1("can't enable memory.\n");
+	if (pci_write_config_word(pci_dev, PCI_COMMAND, command) != 0) {
+		hprintk("can't enable memory.\n");
 		return -EINVAL;
 	}
 
-	if (pci_read_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, &cache_size))
-	{
-		hprintk1("can't read cache line size?\n");
+	if (pci_read_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, &cache_size)) {
+		hprintk("can't read cache line size?\n");
 		return -EINVAL;
 	}
 
-	if (cache_size < 16)
-	{
+	if (cache_size < 16) {
 		cache_size = 16;
 		if (pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, cache_size))
 			hprintk("can't set cache line size to %d\n", cache_size);
 	}
 
-	if (pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &timer))
-	{
-		hprintk1("can't read latency timer?\n");
+	if (pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &timer)) {
+		hprintk("can't read latency timer?\n");
 		return -EINVAL;
 	}
 
@@ -1125,8 +1073,7 @@
 	 *
 	 */ 
 #define LAT_TIMER 209
-	if (timer < LAT_TIMER)
-	{
+	if (timer < LAT_TIMER) {
 		HPRINTK("latency timer was %d, setting to %d\n", timer, LAT_TIMER);
 		timer = LAT_TIMER;
 		if (pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, timer))
@@ -1134,19 +1081,18 @@
 	}
 
 	if (!(he_dev->membase = (unsigned long) ioremap(he_dev->membase, HE_REGMAP_SIZE))) {
-		hprintk1("can't set up page mapping\n");
+		hprintk("can't set up page mapping\n");
 		return -EINVAL;
 	}
-	      
+
 	/* 4.4 card reset */
 	he_writel(he_dev, 0x0, RESET_CNTL);
 	he_writel(he_dev, 0xff, RESET_CNTL);
 
 	udelay(16*1000);	/* 16 ms */
 	status = he_readl(he_dev, RESET_CNTL);
-	if ((status & BOARD_RST_STATUS) == 0)
-	{
-		hprintk1("reset failed\n");
+	if ((status & BOARD_RST_STATUS) == 0) {
+		hprintk("reset failed\n");
 		return -EINVAL;
 	}
 
@@ -1157,23 +1103,23 @@
 	else
 		gen_cntl_0 &= ~ENBL_64;
 
-	if (disable64 == 1)
-	{
-		hprintk1("disabling 64-bit pci bus transfers\n");
+	if (disable64 == 1) {
+		hprintk("disabling 64-bit pci bus transfers\n");
 		gen_cntl_0 &= ~ENBL_64;
 	}
 
-	if (gen_cntl_0 & ENBL_64) hprintk1("64-bit transfers enabled\n");
+	if (gen_cntl_0 & ENBL_64)
+		hprintk("64-bit transfers enabled\n");
 
 	pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0);
 
 	/* 4.7 read prom contents */
-	for(i=0; i<PROD_ID_LEN; ++i)
+	for (i = 0; i < PROD_ID_LEN; ++i)
 		he_dev->prod_id[i] = read_prom_byte(he_dev, PROD_ID + i);
 
 	he_dev->media = read_prom_byte(he_dev, MEDIA);
 
-	for(i=0; i<6; ++i)
+	for (i = 0; i < 6; ++i)
 		dev->esi[i] = read_prom_byte(he_dev, MAC_ADDR + i);
 
 	hprintk("%s%s, %x:%x:%x:%x:%x:%x\n",
@@ -1210,7 +1156,8 @@
 	he_writel(he_dev, lb_swap, LB_SWAP);
 
 	/* 4.10 initialize the interrupt queues */
-	if ((err = he_init_irq(he_dev)) != 0) return err;
+	if ((err = he_init_irq(he_dev)) != 0)
+		return err;
 
 #ifdef USE_TASKLET
 	tasklet_init(&he_dev->tasklet, he_tasklet, (unsigned long) he_dev);
@@ -1263,27 +1210,23 @@
 	he_dev->vcibits = CONFIG_DEFAULT_VCIBITS;
 	he_dev->vpibits = CONFIG_DEFAULT_VPIBITS;
 
-	if (nvpibits != -1 && nvcibits != -1 && nvpibits+nvcibits != HE_MAXCIDBITS)
-	{
+	if (nvpibits != -1 && nvcibits != -1 && nvpibits+nvcibits != HE_MAXCIDBITS) {
 		hprintk("nvpibits + nvcibits != %d\n", HE_MAXCIDBITS);
 		return -ENODEV;
 	}
 
-	if (nvpibits != -1)
-	{
+	if (nvpibits != -1) {
 		he_dev->vpibits = nvpibits;
 		he_dev->vcibits = HE_MAXCIDBITS - nvpibits;
 	}
 
-	if (nvcibits != -1)
-	{
+	if (nvcibits != -1) {
 		he_dev->vcibits = nvcibits;
 		he_dev->vpibits = HE_MAXCIDBITS - nvcibits;
 	}
 
 
-	if (he_is622(he_dev))
-	{
+	if (he_is622(he_dev)) {
 		he_dev->cells_per_row = 40;
 		he_dev->bytes_per_row = 2048;
 		he_dev->r0_numrows = 256;
@@ -1292,9 +1235,7 @@
 		he_dev->r0_startrow = 0;
 		he_dev->tx_startrow = 256;
 		he_dev->r1_startrow = 768;
-	}
-	else
-	{
+	} else {
 		he_dev->cells_per_row = 20;
 		he_dev->bytes_per_row = 1024;
 		he_dev->r0_numrows = 512;
@@ -1309,15 +1250,18 @@
 	he_dev->buffer_limit = 4;
 	he_dev->r0_numbuffs = he_dev->r0_numrows *
 				he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	if (he_dev->r0_numbuffs > 2560) he_dev->r0_numbuffs = 2560;
+	if (he_dev->r0_numbuffs > 2560)
+		he_dev->r0_numbuffs = 2560;
 
 	he_dev->r1_numbuffs = he_dev->r1_numrows *
 				he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	if (he_dev->r1_numbuffs > 2560) he_dev->r1_numbuffs = 2560;
+	if (he_dev->r1_numbuffs > 2560)
+		he_dev->r1_numbuffs = 2560;
 
 	he_dev->tx_numbuffs = he_dev->tx_numrows *
 				he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	if (he_dev->tx_numbuffs > 5120) he_dev->tx_numbuffs = 5120;
+	if (he_dev->tx_numbuffs > 5120)
+		he_dev->tx_numbuffs = 5120;
 
 	/* 5.1.2 configure hardware dependent registers */
 
@@ -1355,15 +1299,15 @@
 	he_writel(he_dev, 0x0, TXAAL5_PROTO);
 
 	he_writel(he_dev, PHY_INT_ENB |
-		(he_is622(he_dev) ? PTMR_PRE(67-1) : PTMR_PRE(50-1)),
+		(he_is622(he_dev) ? PTMR_PRE(67 - 1) : PTMR_PRE(50 - 1)),
 								RH_CONFIG);
 
 	/* 5.1.3 initialize connection memory */
 
-	for(i=0; i < TCM_MEM_SIZE; ++i)
+	for (i = 0; i < TCM_MEM_SIZE; ++i)
 		he_writel_tcm(he_dev, 0, i);
 
-	for(i=0; i < RCM_MEM_SIZE; ++i)
+	for (i = 0; i < RCM_MEM_SIZE; ++i)
 		he_writel_rcm(he_dev, 0, i);
 
 	/*
@@ -1453,8 +1397,7 @@
 
 	/* 5.1.5 initialize intermediate receive queues */
 
-	if (he_is622(he_dev))
-	{
+	if (he_is622(he_dev)) {
 		he_writel(he_dev, 0x000f, G0_INMQ_S);
 		he_writel(he_dev, 0x200f, G0_INMQ_L);
 
@@ -1478,9 +1421,7 @@
 
 		he_writel(he_dev, 0x007f, G7_INMQ_S);
 		he_writel(he_dev, 0x207f, G7_INMQ_L);
-	}
-	else
-	{
+	} else {
 		he_writel(he_dev, 0x0000, G0_INMQ_S);
 		he_writel(he_dev, 0x0008, G0_INMQ_L);
 
@@ -1519,23 +1460,18 @@
 
 	/* 5.1.8 cs block connection memory initialization */
 	
-	he_init_cs_block_rcm(he_dev);
+	if (he_init_cs_block_rcm(he_dev) < 0)
+		return -ENOMEM;
 
 	/* 5.1.10 initialize host structures */
 
 	he_init_tpdrq(he_dev);
 
 #ifdef USE_TPD_POOL
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,44)
-	he_dev->tpd_pool = pci_pool_create("tpd", he_dev->pci_dev,
-		sizeof(struct he_tpd), TPD_ALIGNMENT, 0, SLAB_KERNEL);
-#else
 	he_dev->tpd_pool = pci_pool_create("tpd", he_dev->pci_dev,
 		sizeof(struct he_tpd), TPD_ALIGNMENT, 0);
-#endif
-	if (he_dev->tpd_pool == NULL)
-	{
-		hprintk1("unable to create tpd pci_pool\n");
+	if (he_dev->tpd_pool == NULL) {
+		hprintk("unable to create tpd pci_pool\n");
 		return -ENOMEM;         
 	}
 
@@ -1546,21 +1482,19 @@
 	if (!he_dev->tpd_base)
 		return -ENOMEM;
 
-	for(i = 0; i < CONFIG_NUMTPDS; ++i)
-	{
+	for (i = 0; i < CONFIG_NUMTPDS; ++i) {
 		he_dev->tpd_base[i].status = (i << TPD_ADDR_SHIFT);
 		he_dev->tpd_base[i].inuse = 0;
 	}
 		
 	he_dev->tpd_head = he_dev->tpd_base;
-	he_dev->tpd_end = &he_dev->tpd_base[CONFIG_NUMTPDS-1];
+	he_dev->tpd_end = &he_dev->tpd_base[CONFIG_NUMTPDS - 1];
 #endif
 
 	if (he_init_group(he_dev, 0) != 0)
 		return -ENOMEM;
 
-	for (group = 1; group < HE_NUM_GROUPS; ++group)
-	{
+	for (group = 1; group < HE_NUM_GROUPS; ++group) {
 		he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32));
 		he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32));
 		he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32));
@@ -1590,9 +1524,8 @@
 
 	he_dev->hsp = pci_alloc_consistent(he_dev->pci_dev,
 				sizeof(struct he_hsp), &he_dev->hsp_phys);
-	if (he_dev->hsp == NULL)
-	{
-		hprintk1("failed to allocate host status page\n");
+	if (he_dev->hsp == NULL) {
+		hprintk("failed to allocate host status page\n");
 		return -ENOMEM;
 	}
 	memset(he_dev->hsp, 0, sizeof(struct he_hsp));
@@ -1606,8 +1539,7 @@
 		he_dev->atm_dev->phy->start(he_dev->atm_dev);
 #endif /* CONFIG_ATM_HE_USE_SUNI */
 
-	if (sdh)
-	{
+	if (sdh) {
 		/* this really should be in suni.c but for now... */
 
 		int val;
@@ -1627,20 +1559,7 @@
 	reg |= RX_ENABLE;
 	he_writel(he_dev, reg, RC_CONFIG);
 
-#ifndef USE_HE_FIND_VCC
-	he_dev->he_vcc_table = kmalloc(sizeof(struct he_vcc_table) * 
-			(1 << (he_dev->vcibits + he_dev->vpibits)), GFP_KERNEL);
-	if (he_dev->he_vcc_table == NULL)
-	{
-		hprintk1("failed to alloc he_vcc_table\n");
-		return -ENOMEM;
-	}
-	memset(he_dev->he_vcc_table, 0, sizeof(struct he_vcc_table) *
-				(1 << (he_dev->vcibits + he_dev->vpibits)));
-#endif
-
-	for (i = 0; i < HE_NUM_CS_STPER; ++i)
-	{
+	for (i = 0; i < HE_NUM_CS_STPER; ++i) {
 		he_dev->cs_stper[i].inuse = 0;
 		he_dev->cs_stper[i].pcr = -1;
 	}
@@ -1654,8 +1573,8 @@
 
 	he_dev->irq_peak = 0;
 	he_dev->rbrq_peak = 0;
-        he_dev->rbpl_peak = 0;
-        he_dev->tbrq_peak = 0;
+	he_dev->rbpl_peak = 0;
+	he_dev->tbrq_peak = 0;
 
 	HPRINTK("hell bent for leather!\n");
 
@@ -1673,8 +1592,7 @@
 
 	/* disable interrupts */
 
-	if (he_dev->membase)
-	{
+	if (he_dev->membase) {
 		pci_read_config_dword(pci_dev, GEN_CNTL_0, &gen_cntl_0);
 		gen_cntl_0 &= ~(INT_PROC_ENBL | INIT_ENB);
 		pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0);
@@ -1700,12 +1618,7 @@
 #endif /* CONFIG_ATM_HE_USE_SUNI */
 
 	if (he_dev->irq)
-	{
-#ifdef BUS_INT_WAR
-		sn_delete_polled_interrupt(he_dev->irq);
-#endif
 		free_irq(he_dev->irq, he_dev);
-	}
 
 	if (he_dev->irq_base)
 		pci_free_consistent(he_dev->pci_dev, (CONFIG_IRQ_SIZE+1)
@@ -1715,11 +1628,9 @@
 		pci_free_consistent(he_dev->pci_dev, sizeof(struct he_hsp),
 						he_dev->hsp, he_dev->hsp_phys);
 
-	if (he_dev->rbpl_base)
-	{
+	if (he_dev->rbpl_base) {
 #ifdef USE_RBPL_POOL
-		for (i=0; i<CONFIG_RBPL_SIZE; ++i)
-		{
+		for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
 			void *cpuaddr = he_dev->rbpl_virt[i].virt;
 			dma_addr_t dma_handle = he_dev->rbpl_base[i].phys;
 
@@ -1739,11 +1650,9 @@
 #endif
 
 #ifdef USE_RBPS
-	if (he_dev->rbps_base)
-	{
+	if (he_dev->rbps_base) {
 #ifdef USE_RBPS_POOL
-		for (i=0; i<CONFIG_RBPS_SIZE; ++i)
-		{
+		for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
 			void *cpuaddr = he_dev->rbps_virt[i].virt;
 			dma_addr_t dma_handle = he_dev->rbps_base[i].phys;
 
@@ -1785,19 +1694,14 @@
 							he_dev->tpd_base, he_dev->tpd_base_phys);
 #endif
 
-#ifndef USE_HE_FIND_VCC
-	if (he_dev->he_vcc_table)
-		kfree(he_dev->he_vcc_table);
-#endif
-
-	if (he_dev->pci_dev)
-	{
+	if (he_dev->pci_dev) {
 		pci_read_config_word(he_dev->pci_dev, PCI_COMMAND, &command);
 		command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
 		pci_write_config_word(he_dev->pci_dev, PCI_COMMAND, command);
 	}
 	
-	if (he_dev->membase) iounmap((void *) he_dev->membase);
+	if (he_dev->membase)
+		iounmap((void *) he_dev->membase);
 }
 
 static struct he_tpd *
@@ -1821,8 +1725,7 @@
 #else
 	int i;
 
-	for(i = 0; i < CONFIG_NUMTPDS; ++i)
-	{
+	for (i = 0; i < CONFIG_NUMTPDS; ++i) {
 		++he_dev->tpd_head;
 		if (he_dev->tpd_head > he_dev->tpd_end) {
 			he_dev->tpd_head = he_dev->tpd_base;
@@ -1843,7 +1746,7 @@
 }
 
 #define AAL5_LEN(buf,len) 						\
-			((((unsigned char *)(buf))[(len)-6]<<8) |	\
+			((((unsigned char *)(buf))[(len)-6] << 8) |	\
 				(((unsigned char *)(buf))[(len)-5]))
 
 /* 2.10.1.2 receive
@@ -1853,7 +1756,7 @@
  */
 
 #define TCP_CKSUM(buf,len) 						\
-			((((unsigned char *)(buf))[(len)-2]<<8) |	\
+			((((unsigned char *)(buf))[(len)-2] << 8) |	\
 				(((unsigned char *)(buf))[(len-1)]))
 
 static int
@@ -1868,12 +1771,11 @@
 	struct sk_buff *skb;
 	struct atm_vcc *vcc = NULL;
 	struct he_vcc *he_vcc;
-	struct iovec *iov;
+	struct he_iovec *iov;
 	int pdus_assembled = 0;
 	int updated = 0;
 
-	while (he_dev->rbrq_head != rbrq_tail)
-	{
+	while (he_dev->rbrq_head != rbrq_tail) {
 		++updated;
 
 		HPRINTK("%p rbrq%d 0x%x len=%d cid=0x%x %s%s%s%s%s%s\n",
@@ -1898,15 +1800,11 @@
 		buf_len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4;
 		cid = RBRQ_CID(he_dev->rbrq_head);
 
-#ifdef USE_HE_FIND_VCC
 		if (cid != lastcid)
 			vcc = he_find_vcc(he_dev, cid);
 		lastcid = cid;
-#else
-		vcc = HE_LOOKUP_VCC(he_dev, cid);
-#endif
-		if (vcc == NULL)
-		{
+
+		if (vcc == NULL) {
 			hprintk("vcc == NULL  (cid 0x%x)\n", cid);
 			if (!RBRQ_HBUF_ERR(he_dev->rbrq_head))
 					rbp->status &= ~RBP_LOANED;
@@ -1915,32 +1813,25 @@
 		}
 
 		he_vcc = HE_VCC(vcc);
-		if (he_vcc == NULL)
-		{
+		if (he_vcc == NULL) {
 			hprintk("he_vcc == NULL  (cid 0x%x)\n", cid);
 			if (!RBRQ_HBUF_ERR(he_dev->rbrq_head))
 					rbp->status &= ~RBP_LOANED;
 			goto next_rbrq_entry;
 		}
 
-		if (RBRQ_HBUF_ERR(he_dev->rbrq_head))
-		{
+		if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
 			hprintk("HBUF_ERR!  (cid 0x%x)\n", cid);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,99)
-				++vcc->stats->rx_drop;
-#else
 				atomic_inc(&vcc->stats->rx_drop);
-#endif
 			goto return_host_buffers;
 		}
 
-		he_vcc->iov_tail->iov_base = (void *) RBRQ_ADDR(he_dev->rbrq_head);
+		he_vcc->iov_tail->iov_base = RBRQ_ADDR(he_dev->rbrq_head);
 		he_vcc->iov_tail->iov_len = buf_len;
 		he_vcc->pdu_len += buf_len;
 		++he_vcc->iov_tail;
 
-		if (RBRQ_CON_CLOSED(he_dev->rbrq_head))
-		{
+		if (RBRQ_CON_CLOSED(he_dev->rbrq_head)) {
 			lastcid = -1;
 			HPRINTK("wake_up rx_waitq  (cid 0x%x)\n", cid);
 			wake_up(&he_vcc->rx_waitq);
@@ -1948,59 +1839,42 @@
 		}
 
 #ifdef notdef
-		if (he_vcc->iov_tail - he_vcc->iov_head > 32)
-		{
+		if ((he_vcc->iov_tail - he_vcc->iov_head) > HE_MAXIOV) {
 			hprintk("iovec full!  cid 0x%x\n", cid);
 			goto return_host_buffers;
 		}
 #endif
-		if (!RBRQ_END_PDU(he_dev->rbrq_head)) goto next_rbrq_entry;
+		if (!RBRQ_END_PDU(he_dev->rbrq_head))
+			goto next_rbrq_entry;
 
 		if (RBRQ_LEN_ERR(he_dev->rbrq_head)
-				|| RBRQ_CRC_ERR(he_dev->rbrq_head))
-		{
+				|| RBRQ_CRC_ERR(he_dev->rbrq_head)) {
 			HPRINTK("%s%s (%d.%d)\n",
 				RBRQ_CRC_ERR(he_dev->rbrq_head)
 							? "CRC_ERR " : "",
 				RBRQ_LEN_ERR(he_dev->rbrq_head)
 							? "LEN_ERR" : "",
 							vcc->vpi, vcc->vci);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,99)
-			++vcc->stats->rx_err;
-#else
 			atomic_inc(&vcc->stats->rx_err);
-#endif
 			goto return_host_buffers;
 		}
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,15)
 		skb = atm_alloc_charge(vcc, he_vcc->pdu_len + rx_skb_reserve,
 							GFP_ATOMIC);
-#else
-		if (!atm_charge(vcc, atm_pdu2truesize(he_vcc->pdu_len + rx_skb_reserve)))
-			skb = NULL;
-		else
-		{
-			skb = alloc_skb(he_vcc->pdu_len + rx_skb_reserve, GFP_ATOMIC);
-			if (!skb) atm_return(vcc,
-				atm_pdu2truesize(he_vcc->pdu_len + rx_skb_reserve));
-		}
-#endif
-		if (!skb)
-		{
+		if (!skb) {
 			HPRINTK("charge failed (%d.%d)\n", vcc->vpi, vcc->vci);
 			goto return_host_buffers;
 		}
 
-		if (rx_skb_reserve > 0) skb_reserve(skb, rx_skb_reserve);
+		if (rx_skb_reserve > 0)
+			skb_reserve(skb, rx_skb_reserve);
 
 		do_gettimeofday(&skb->stamp);
 
-		for(iov = he_vcc->iov_head;
-				iov < he_vcc->iov_tail; ++iov)
-		{
+		for (iov = he_vcc->iov_head;
+				iov < he_vcc->iov_tail; ++iov) {
 #ifdef USE_RBPS
-			if ((u32)iov->iov_base & RBP_SMALLBUF)
+			if (iov->iov_base & RBP_SMALLBUF)
 				memcpy(skb_put(skb, iov->iov_len),
 					he_dev->rbps_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len);
 			else
@@ -2009,8 +1883,7 @@
 					he_dev->rbpl_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len);
 		}
 
-		switch(vcc->qos.aal)
-		{
+		switch (vcc->qos.aal) {
 			case ATM_AAL0:
 				/* 2.10.1.5 raw cell receive */
 				skb->len = ATM_AAL0_SDU;
@@ -2022,8 +1895,7 @@
 				skb->len = AAL5_LEN(skb->data, he_vcc->pdu_len);
 				skb->tail = skb->data + skb->len;
 #ifdef USE_CHECKSUM_HW
-				if (vcc->vpi == 0 && vcc->vci >= ATM_NOT_RSV_VCI) 
-				{
+				if (vcc->vpi == 0 && vcc->vci >= ATM_NOT_RSV_VCI) {
 					skb->ip_summed = CHECKSUM_HW;
 					skb->csum = TCP_CKSUM(skb->data,
 							he_vcc->pdu_len);
@@ -2042,20 +1914,15 @@
 #endif
 		vcc->push(vcc, skb);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,99)
-		++vcc->stats->rx;
-#else
 		atomic_inc(&vcc->stats->rx);
-#endif
 
 return_host_buffers:
 		++pdus_assembled;
 
-		for(iov = he_vcc->iov_head;
-				iov < he_vcc->iov_tail; ++iov)
-		{
+		for (iov = he_vcc->iov_head;
+				iov < he_vcc->iov_tail; ++iov) {
 #ifdef USE_RBPS
-			if ((u32)iov->iov_base & RBP_SMALLBUF)
+			if (iov->iov_base & RBP_SMALLBUF)
 				rbp = &he_dev->rbps_base[RBP_INDEX(iov->iov_base)];
 			else
 #endif
@@ -2074,9 +1941,9 @@
 
 	}
 
-	if (updated)
-	{
-		if (updated > he_dev->rbrq_peak) he_dev->rbrq_peak = updated;
+	if (updated) {
+		if (updated > he_dev->rbrq_peak)
+			he_dev->rbrq_peak = updated;
 
 		he_writel(he_dev, RBRQ_MASK(he_dev->rbrq_head),
 						G0_RBRQ_H + (group * 16));
@@ -2102,8 +1969,7 @@
 
 	/* 2.1.6 transmit buffer return queue */
 
-	while (he_dev->tbrq_head != tbrq_tail)
-	{
+	while (he_dev->tbrq_head != tbrq_tail) {
 		++updated;
 
 		HPRINTK("tbrq%d 0x%x%s%s\n",
@@ -2114,19 +1980,16 @@
 #ifdef USE_TPD_POOL
 		tpd = NULL;
 		p = &he_dev->outstanding_tpds;
-		while ((p = p->next) != &he_dev->outstanding_tpds)
-		{
+		while ((p = p->next) != &he_dev->outstanding_tpds) {
 			struct he_tpd *__tpd = list_entry(p, struct he_tpd, entry);
-			if (TPD_ADDR(__tpd->status) == TBRQ_TPD(he_dev->tbrq_head))
-			{
+			if (TPD_ADDR(__tpd->status) == TBRQ_TPD(he_dev->tbrq_head)) {
 				tpd = __tpd;
 				list_del(&__tpd->entry);
 				break;
 			}
 		}
 
-		if (tpd == NULL)
-		{
+		if (tpd == NULL) {
 			hprintk("unable to locate tpd for dma buffer %x\n",
 						TBRQ_TPD(he_dev->tbrq_head));
 			goto next_tbrq_entry;
@@ -2135,8 +1998,7 @@
 		tpd = &he_dev->tpd_base[ TPD_INDEX(TBRQ_TPD(he_dev->tbrq_head)) ];
 #endif
 
-		if (TBRQ_EOS(he_dev->tbrq_head))
-		{
+		if (TBRQ_EOS(he_dev->tbrq_head)) {
 			HPRINTK("wake_up(tx_waitq) cid 0x%x\n",
 				he_mkcid(he_dev, tpd->vcc->vpi, tpd->vcc->vci));
 			if (tpd->vcc)
@@ -2145,19 +2007,18 @@
 			goto next_tbrq_entry;
 		}
 
-		for(slot = 0; slot < TPD_MAXIOV; ++slot)
-		{
+		for (slot = 0; slot < TPD_MAXIOV; ++slot) {
 			if (tpd->iovec[slot].addr)
 				pci_unmap_single(he_dev->pci_dev,
 					tpd->iovec[slot].addr,
 					tpd->iovec[slot].len & TPD_LEN_MASK,
 							PCI_DMA_TODEVICE);
-			if (tpd->iovec[slot].len & TPD_LST) break;
+			if (tpd->iovec[slot].len & TPD_LST)
+				break;
 				
 		}
 
-		if (tpd->skb)	/* && !TBRQ_MULTIPLE(he_dev->tbrq_head) */
-		{
+		if (tpd->skb) {	/* && !TBRQ_MULTIPLE(he_dev->tbrq_head) */
 			if (tpd->vcc && tpd->vcc->pop)
 				tpd->vcc->pop(tpd->vcc, tpd->skb);
 			else
@@ -2166,7 +2027,8 @@
 
 next_tbrq_entry:
 #ifdef USE_TPD_POOL
-		if (tpd) pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
+		if (tpd)
+			pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
 #else
 		tpd->inuse = 0;
 #endif
@@ -2175,9 +2037,9 @@
 					TBRQ_MASK(++he_dev->tbrq_head));
 	}
 
-	if (updated)
-	{
-		if (updated > he_dev->tbrq_peak) he_dev->tbrq_peak = updated;
+	if (updated) {
+		if (updated > he_dev->tbrq_peak)
+			he_dev->tbrq_peak = updated;
 
 		he_writel(he_dev, TBRQ_MASK(he_dev->tbrq_head),
 						G0_TBRQ_H + (group * 16));
@@ -2198,8 +2060,7 @@
 	rbpl_head = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base |
 					RBPL_MASK(he_readl(he_dev, G0_RBPL_S)));
 
-	for(;;)
-	{
+	for (;;) {
 		newtail = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base |
 						RBPL_MASK(he_dev->rbpl_tail+1));
 
@@ -2210,13 +2071,12 @@
 		newtail->status |= RBP_LOANED;
 		he_dev->rbpl_tail = newtail;
 		++moved;
-
 	} 
 
 	if (moved) {
 		he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), G0_RBPL_T);
 #ifdef CONFIG_IA64_SGI_SN2
-                (void) he_readl(he_dev, G0_RBPL_T);
+		(void) he_readl(he_dev, G0_RBPL_T);
 #endif
 	}
 }
@@ -2232,8 +2092,7 @@
 	rbps_head = (struct he_rbp *) ((unsigned long)he_dev->rbps_base |
 					RBPS_MASK(he_readl(he_dev, G0_RBPS_S)));
 
-	for(;;)
-	{
+	for (;;) {
 		newtail = (struct he_rbp *) ((unsigned long)he_dev->rbps_base |
 						RBPS_MASK(he_dev->rbps_tail+1));
 
@@ -2244,13 +2103,12 @@
 		newtail->status |= RBP_LOANED;
 		he_dev->rbps_tail = newtail;
 		++moved;
-
 	} 
 
 	if (moved) {
 		he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), G0_RBPS_T);
 #ifdef CONFIG_IA64_SGI_SN2
-                (void) he_readl(he_dev, G0_RBPS_T);
+		(void) he_readl(he_dev, G0_RBPS_T);
 #endif
 	}
 }
@@ -2266,23 +2124,21 @@
 
 	HPRINTK("tasklet (0x%lx)\n", data);
 #ifdef USE_TASKLET
-	HE_SPIN_LOCK(he_dev, flags);
+	spin_lock_irqsave(&he_dev->global_lock, flags);
 #endif
 
-	while(he_dev->irq_head != he_dev->irq_tail)
-	{
+	while (he_dev->irq_head != he_dev->irq_tail) {
 		++updated;
 
 		type = ITYPE_TYPE(he_dev->irq_head->isw);
 		group = ITYPE_GROUP(he_dev->irq_head->isw);
 
-		switch (type)
-		{
+		switch (type) {
 			case ITYPE_RBRQ_THRESH:
-				hprintk("rbrq%d threshold\n", group);
+				HPRINTK("rbrq%d threshold\n", group);
+				/* fall through */
 			case ITYPE_RBRQ_TIMER:
-				if (he_service_rbrq(he_dev, group))
-				{
+				if (he_service_rbrq(he_dev, group)) {
 					he_service_rbpl(he_dev, group);
 #ifdef USE_RBPS
 					he_service_rbps(he_dev, group);
@@ -2290,7 +2146,8 @@
 				}
 				break;
 			case ITYPE_TBRQ_THRESH:
-				hprintk("tbrq%d threshold\n", group);
+				HPRINTK("tbrq%d threshold\n", group);
+				/* fall through */
 			case ITYPE_TPD_COMPLETE:
 				he_service_tbrq(he_dev, group);
 				break;
@@ -2303,43 +2160,38 @@
 #endif /* USE_RBPS */
 				break;
 			case ITYPE_PHY:
+				HPRINTK("phy interrupt\n");
 #ifdef CONFIG_ATM_HE_USE_SUNI
-				HE_SPIN_UNLOCK(he_dev, flags);
+				spin_unlock_irqrestore(&he_dev->global_lock, flags);
 				if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->interrupt)
 					he_dev->atm_dev->phy->interrupt(he_dev->atm_dev);
-				HE_SPIN_LOCK(he_dev, flags);
+				spin_lock_irqsave(&he_dev->global_lock, flags);
 #endif
-				HPRINTK1("phy interrupt\n");
 				break;
 			case ITYPE_OTHER:
-				switch (type|group)
-				{
+				switch (type|group) {
 					case ITYPE_PARITY:
-						hprintk1("parity error\n");
+						hprintk("parity error\n");
 						break;
 					case ITYPE_ABORT:
 						hprintk("abort 0x%x\n", he_readl(he_dev, ABORT_ADDR));
 						break;
 				}
 				break;
-			default:
-				if (he_dev->irq_head->isw == ITYPE_INVALID)
-				{
-					/* see 8.1.1 -- check all queues */
+			case ITYPE_TYPE(ITYPE_INVALID):
+				/* see 8.1.1 -- check all queues */
 
-					HPRINTK("isw not updated 0x%x\n",
-						he_dev->irq_head->isw);
+				HPRINTK("isw not updated 0x%x\n", he_dev->irq_head->isw);
 
-					he_service_rbrq(he_dev, 0);
-					he_service_rbpl(he_dev, 0);
+				he_service_rbrq(he_dev, 0);
+				he_service_rbpl(he_dev, 0);
 #ifdef USE_RBPS
-					he_service_rbps(he_dev, 0);
+				he_service_rbps(he_dev, 0);
 #endif /* USE_RBPS */
-					he_service_tbrq(he_dev, 0);
-				}
-				else
-					hprintk("bad isw = 0x%x?\n",
-						he_dev->irq_head->isw);
+				he_service_tbrq(he_dev, 0);
+				break;
+			default:
+				hprintk("bad isw 0x%x?\n", he_dev->irq_head->isw);
 		}
 
 		he_dev->irq_head->isw = ITYPE_INVALID;
@@ -2347,9 +2199,9 @@
 		he_dev->irq_head = (struct he_irq *) NEXT_ENTRY(he_dev->irq_base, he_dev->irq_head, IRQ_MASK);
 	}
 
-	if (updated)
-	{
-		if (updated > he_dev->irq_peak) he_dev->irq_peak = updated;
+	if (updated) {
+		if (updated > he_dev->irq_peak)
+			he_dev->irq_peak = updated;
 
 		he_writel(he_dev,
 			IRQ_SIZE(CONFIG_IRQ_SIZE) |
@@ -2358,15 +2210,11 @@
 		(void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata */
 	}
 #ifdef USE_TASKLET
-	HE_SPIN_UNLOCK(he_dev, flags);
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 #endif
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,69)
-static irq_return_t
-#else
-static void
-#endif
+static irqreturn_t
 he_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned long flags;
@@ -2374,20 +2222,15 @@
 	int handled = 0;
 
 	if (he_dev == NULL)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,69)
 		return IRQ_NONE;
-#else
-		return;
-#endif
 
-	HE_SPIN_LOCK(he_dev, flags);
+	spin_lock_irqsave(&he_dev->global_lock, flags);
 
 	he_dev->irq_tail = (struct he_irq *) (((unsigned long)he_dev->irq_base) |
 						(*he_dev->irq_tailoffset << 2));
 
-	if (he_dev->irq_tail == he_dev->irq_head)
-	{
-		HPRINTK1("tailoffset not updated?\n");
+	if (he_dev->irq_tail == he_dev->irq_head) {
+		HPRINTK("tailoffset not updated?\n");
 		he_dev->irq_tail = (struct he_irq *) ((unsigned long)he_dev->irq_base |
 			((he_readl(he_dev, IRQ0_BASE) & IRQ_MASK) << 2));
 		(void) he_readl(he_dev, INT_FIFO);	/* 8.1.2 controller errata */
@@ -2395,11 +2238,10 @@
 
 #ifdef DEBUG
 	if (he_dev->irq_head == he_dev->irq_tail /* && !IRQ_PENDING */)
-		hprintk1("spurious (or shared) interrupt?\n");
+		hprintk("spurious (or shared) interrupt?\n");
 #endif
 
-	if (he_dev->irq_head != he_dev->irq_tail)
-	{
+	if (he_dev->irq_head != he_dev->irq_tail) {
 		handled = 1;
 #ifdef USE_TASKLET
 		tasklet_schedule(&he_dev->tasklet);
@@ -2412,12 +2254,8 @@
 		(void) he_readl(he_dev, INT_FIFO);
 #endif
 	}
-	HE_SPIN_UNLOCK(he_dev, flags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,69)
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 	return IRQ_RETVAL(handled);
-#else
-	return;
-#endif
 
 }
 
@@ -2440,14 +2278,12 @@
 	 * head for every enqueue would be unnecessarily slow)
 	 */
 
-	if (new_tail == he_dev->tpdrq_head)
-	{
+	if (new_tail == he_dev->tpdrq_head) {
 		he_dev->tpdrq_head = (struct he_tpdrq *)
 			(((unsigned long)he_dev->tpdrq_base) |
 				TPDRQ_MASK(he_readl(he_dev, TPDRQ_B_H)));
 
-		if (new_tail == he_dev->tpdrq_head)
-		{
+		if (new_tail == he_dev->tpdrq_head) {
 			hprintk("tpdrq full (cid 0x%x)\n", cid);
 			/*
 			 * FIXME
@@ -2455,17 +2291,12 @@
 			 * after service_tbrq, service the backlog
 			 * for now, we just drop the pdu
 			 */
-			if (tpd->skb)
-			{
+			if (tpd->skb) {
 				if (tpd->vcc->pop)
 					tpd->vcc->pop(tpd->vcc, tpd->skb);
 				else
 					dev_kfree_skb_any(tpd->skb);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,99)
-				++tpd->vcc->stats->tx_err;
-#else
 				atomic_inc(&tpd->vcc->stats->tx_err);
-#endif
 			}
 #ifdef USE_TPD_POOL
 			pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
@@ -2505,29 +2336,24 @@
 	unsigned cid, rsr0, rsr1, rsr4, tsr0, tsr0_aal, tsr4, period, reg, clock;
 
 	
-	if ((err = atm_find_ci(vcc, &vpi, &vci)))
-	{
+	if ((err = atm_find_ci(vcc, &vpi, &vci))) {
 		HPRINTK("atm_find_ci err = %d\n", err);
 		return err;
 	}
-	if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC) return 0;
+	if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
+		return 0;
 	vcc->vpi = vpi;
 	vcc->vci = vci;
 
 	HPRINTK("open vcc %p %d.%d\n", vcc, vpi, vci);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
-	vcc->flags |= ATM_VF_ADDR;
-#else
 	set_bit(ATM_VF_ADDR, &vcc->flags);
-#endif
 
 	cid = he_mkcid(he_dev, vpi, vci);
 
 	he_vcc = (struct he_vcc *) kmalloc(sizeof(struct he_vcc), GFP_ATOMIC);
-	if (he_vcc == NULL)
-	{
-		hprintk1("unable to allocate he_vcc during open\n");
+	if (he_vcc == NULL) {
+		hprintk("unable to allocate he_vcc during open\n");
 		return -ENOMEM;
 	}
 
@@ -2535,30 +2361,23 @@
 	he_vcc->pdu_len = 0;
 	he_vcc->rc_index = -1;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
-	init_waitqueue(&he_vcc->rx_waitq);
-	init_waitqueue(&he_vcc->tx_waitq);
-#else
 	init_waitqueue_head(&he_vcc->rx_waitq);
 	init_waitqueue_head(&he_vcc->tx_waitq);
-#endif
 
 	HE_VCC(vcc) = he_vcc;
 
-	if (vcc->qos.txtp.traffic_class != ATM_NONE)
-	{
+	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
 		int pcr_goal;
 
-                pcr_goal = atm_pcr_goal(&vcc->qos.txtp);
-                if (pcr_goal == 0)
-                        pcr_goal = he_dev->atm_dev->link_rate;
-                if (pcr_goal < 0)	/* means round down, technically */
-                        pcr_goal = -pcr_goal;
+		pcr_goal = atm_pcr_goal(&vcc->qos.txtp);
+		if (pcr_goal == 0)
+			pcr_goal = he_dev->atm_dev->link_rate;
+		if (pcr_goal < 0)	/* means round down, technically */
+			pcr_goal = -pcr_goal;
 
 		HPRINTK("open tx cid 0x%x pcr_goal %d\n", cid, pcr_goal);
 
-		switch (vcc->qos.aal)
-		{
+		switch (vcc->qos.aal) {
 			case ATM_AAL5:
 				tsr0_aal = TSR0_AAL5;
 				tsr4 = TSR4_AAL5;
@@ -2572,19 +2391,17 @@
 				goto open_failed;
 		}
 
-		HE_SPIN_LOCK(he_dev, flags);
+		spin_lock_irqsave(&he_dev->global_lock, flags);
 		tsr0 = he_readl_tsr0(he_dev, cid);
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
-		if (TSR0_CONN_STATE(tsr0) != 0)
-		{
+		if (TSR0_CONN_STATE(tsr0) != 0) {
 			hprintk("cid 0x%x not idle (tsr0 = 0x%x)\n", cid, tsr0);
 			err = -EBUSY;
 			goto open_failed;
 		}
 
-		switch(vcc->qos.txtp.traffic_class)
-		{
+		switch (vcc->qos.txtp.traffic_class) {
 			case ATM_UBR:
 				/* 2.3.3.1 open connection ubr */
 
@@ -2603,18 +2420,17 @@
 					goto open_failed;
 				}
 
-				HE_SPIN_LOCK(he_dev, flags);			/* also protects he_dev->cs_stper[] */
+				spin_lock_irqsave(&he_dev->global_lock, flags);			/* also protects he_dev->cs_stper[] */
 
 				/* find an unused cs_stper register */
-				for(reg = 0; reg < HE_NUM_CS_STPER; ++reg)
+				for (reg = 0; reg < HE_NUM_CS_STPER; ++reg)
 					if (he_dev->cs_stper[reg].inuse == 0 || 
-						he_dev->cs_stper[reg].pcr == pcr_goal)
-					break;
+					    he_dev->cs_stper[reg].pcr == pcr_goal)
+							break;
 
-				if (reg == HE_NUM_CS_STPER)
-				{
+				if (reg == HE_NUM_CS_STPER) {
 					err = -EBUSY;
-					HE_SPIN_UNLOCK(he_dev, flags);
+					spin_unlock_irqrestore(&he_dev->global_lock, flags);
 					goto open_failed;
 				}
 
@@ -2632,7 +2448,7 @@
 
 				he_writel_mbox(he_dev, rate_to_atmf(period/2),
 							CS_STPER0 + reg);
-				HE_SPIN_UNLOCK(he_dev, flags);
+				spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 				tsr0 = TSR0_CBR | TSR0_GROUP(0) | tsr0_aal |
 							TSR0_RC_INDEX(reg);
@@ -2643,7 +2459,7 @@
 				goto open_failed;
 		}
 
-		HE_SPIN_LOCK(he_dev, flags);
+		spin_lock_irqsave(&he_dev->global_lock, flags);
 
 		he_writel_tsr0(he_dev, tsr0, cid);
 		he_writel_tsr4(he_dev, tsr4 | 1, cid);
@@ -2665,18 +2481,16 @@
 #ifdef CONFIG_IA64_SGI_SN2
 		(void) he_readl_tsr0(he_dev, cid);
 #endif
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 	}
 
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE)
-	{
+	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
 		unsigned aal;
 
 		HPRINTK("open rx cid 0x%x (rx_waitq %p)\n", cid,
 		 				&HE_VCC(vcc)->rx_waitq);
 
-		switch (vcc->qos.aal)
-		{
+		switch (vcc->qos.aal) {
 			case ATM_AAL5:
 				aal = RSR0_AAL5;
 				break;
@@ -2688,12 +2502,11 @@
 				goto open_failed;
 		}
 
-		HE_SPIN_LOCK(he_dev, flags);
+		spin_lock_irqsave(&he_dev->global_lock, flags);
 
 		rsr0 = he_readl_rsr0(he_dev, cid);
-		if (rsr0 & RSR0_OPEN_CONN)
-		{
-			HE_SPIN_UNLOCK(he_dev, flags);
+		if (rsr0 & RSR0_OPEN_CONN) {
+			spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 			hprintk("cid 0x%x not idle (rsr0 = 0x%x)\n", cid, rsr0);
 			err = -EBUSY;
@@ -2711,45 +2524,32 @@
 				(RSR0_EPD_ENABLE|RSR0_PPD_ENABLE) : 0;
 
 #ifdef USE_CHECKSUM_HW
-		if (vpi == 0 && vci >= ATM_NOT_RSV_VCI) rsr0 |= RSR0_TCP_CKSUM;
+		if (vpi == 0 && vci >= ATM_NOT_RSV_VCI)
+			rsr0 |= RSR0_TCP_CKSUM;
 #endif
 
 		he_writel_rsr4(he_dev, rsr4, cid);
 		he_writel_rsr1(he_dev, rsr1, cid);
 		/* 5.1.11 last parameter initialized should be
-		          the open/closed indication in rsr0 */
+			  the open/closed indication in rsr0 */
 		he_writel_rsr0(he_dev,
 			rsr0 | RSR0_START_PDU | RSR0_OPEN_CONN | aal, cid);
 #ifdef CONFIG_IA64_SGI_SN2
 		(void) he_readl_rsr0(he_dev, cid);
 #endif
 
-		HE_SPIN_UNLOCK(he_dev, flags);
-
-#ifndef USE_HE_FIND_VCC
-		HE_LOOKUP_VCC(he_dev, cid) = vcc;
-#endif
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 	}
 
 open_failed:
 
-	if (err)
-	{
-		if (he_vcc) kfree(he_vcc);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
-		vcc->flags &= ~ATM_VF_ADDR;
-#else
+	if (err) {
+		if (he_vcc)
+			kfree(he_vcc);
 		clear_bit(ATM_VF_ADDR, &vcc->flags);
-#endif
 	}
 	else
-	{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
-		vcc->flags |= ATM_VF_READY;
-#else
 		set_bit(ATM_VF_READY, &vcc->flags);
-#endif
-	}
 
 	return err;
 }
@@ -2758,11 +2558,7 @@
 he_close(struct atm_vcc *vcc)
 {
 	unsigned long flags;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,1)
 	DECLARE_WAITQUEUE(wait, current);
-#else
-	struct wait_queue wait = { current, NULL };
-#endif
 	struct he_dev *he_dev = HE_DEV(vcc->dev);
 	struct he_tpd *tpd;
 	unsigned cid;
@@ -2772,15 +2568,10 @@
 
 	HPRINTK("close vcc %p %d.%d\n", vcc, vcc->vpi, vcc->vci);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
-	vcc->flags &= ~ATM_VF_READY;
-#else
 	clear_bit(ATM_VF_READY, &vcc->flags);
-#endif
 	cid = he_mkcid(he_dev, vcc->vpi, vcc->vci);
 
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE)
-	{
+	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
 		int timeout;
 
 		HPRINTK("close rx cid 0x%x\n", cid);
@@ -2789,9 +2580,8 @@
 
 		/* wait for previous close (if any) to finish */
 
-		HE_SPIN_LOCK(he_dev, flags);
-		while(he_readl(he_dev, RCC_STAT) & RCC_BUSY)
-		{
+		spin_lock_irqsave(&he_dev->global_lock, flags);
+		while (he_readl(he_dev, RCC_STAT) & RCC_BUSY) {
 			HPRINTK("close cid 0x%x RCC_BUSY\n", cid);
 			udelay(250);
 		}
@@ -2804,7 +2594,7 @@
 		(void) he_readl_rsr0(he_dev, cid);
 #endif
 		he_writel_mbox(he_dev, cid, RXCON_CLOSE);
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 		timeout = schedule_timeout(30*HZ);
 
@@ -2814,15 +2604,11 @@
 		if (timeout == 0)
 			hprintk("close rx timeout cid 0x%x\n", cid);
 
-#ifndef USE_HE_FIND_VCC
-		HE_LOOKUP_VCC(he_dev, cid) = NULL;
-#endif
 		HPRINTK("close rx cid 0x%x complete\n", cid);
 
 	}
 
-	if (vcc->qos.txtp.traffic_class != ATM_NONE)
-	{
+	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
 		volatile unsigned tsr4, tsr0;
 		int timeout;
 
@@ -2837,31 +2623,30 @@
 		 * TBRQ, the host issues the close command to the adapter.
 		 */
 
-		while (((tx_inuse = atomic_read(&vcc->sk->wmem_alloc)) > 0)
-							&& (retry < MAX_RETRY))
-		{
+		while (((tx_inuse = atomic_read(&vcc->sk->wmem_alloc)) > 0) &&
+		       (retry < MAX_RETRY)) {
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			(void) schedule_timeout(sleep);
 			set_current_state(TASK_RUNNING);
-			if (sleep < HZ) sleep = sleep * 2;
+			if (sleep < HZ)
+				sleep = sleep * 2;
 
 			++retry;
 		}
 
-		if (tx_inuse) hprintk("close tx cid 0x%x tx_inuse = %d\n",
-								cid, tx_inuse);
+		if (tx_inuse)
+			hprintk("close tx cid 0x%x tx_inuse = %d\n", cid, tx_inuse);
 
 		/* 2.3.1.1 generic close operations with flush */
 
-		HE_SPIN_LOCK(he_dev, flags);
+		spin_lock_irqsave(&he_dev->global_lock, flags);
 		he_writel_tsr4_upper(he_dev, TSR4_FLUSH_CONN, cid);
 					/* also clears TSR4_SESSION_ENDED */
 #ifdef CONFIG_IA64_SGI_SN2
 		(void) he_readl_tsr4(he_dev, cid);
 #endif
 
-		switch(vcc->qos.txtp.traffic_class)
-		{
+		switch (vcc->qos.txtp.traffic_class) {
 			case ATM_UBR:
 				he_writel_tsr1(he_dev, 
 					TSR1_MCR(rate_to_atmf(200000))
@@ -2872,10 +2657,8 @@
 				break;
 		}
 
-
 		tpd = __alloc_tpd(he_dev);
-		if (tpd == NULL)
-		{
+		if (tpd == NULL) {
 			hprintk("close tx he_alloc_tpd failed cid 0x%x\n", cid);
 			goto close_tx_incomplete;
 		}
@@ -2887,37 +2670,33 @@
 		add_wait_queue(&he_vcc->tx_waitq, &wait);
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		__enqueue_tpd(he_dev, tpd, cid);
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 		timeout = schedule_timeout(30*HZ);
 
 		remove_wait_queue(&he_vcc->tx_waitq, &wait);
 		set_current_state(TASK_RUNNING);
 
-		if (timeout == 0)
-		{
+		spin_lock_irqsave(&he_dev->global_lock, flags);
+
+		if (timeout == 0) {
 			hprintk("close tx timeout cid 0x%x\n", cid);
 			goto close_tx_incomplete;
 		}
 
-		HE_SPIN_LOCK(he_dev, flags);
-		while (!((tsr4 = he_readl_tsr4(he_dev, cid))
-							& TSR4_SESSION_ENDED))
-		{
+		while (!((tsr4 = he_readl_tsr4(he_dev, cid)) & TSR4_SESSION_ENDED)) {
 			HPRINTK("close tx cid 0x%x !TSR4_SESSION_ENDED (tsr4 = 0x%x)\n", cid, tsr4);
 			udelay(250);
 		}
 
-		while (TSR0_CONN_STATE(tsr0 = he_readl_tsr0(he_dev, cid)) != 0)
-		{
+		while (TSR0_CONN_STATE(tsr0 = he_readl_tsr0(he_dev, cid)) != 0) {
 			HPRINTK("close tx cid 0x%x TSR0_CONN_STATE != 0 (tsr0 = 0x%x)\n", cid, tsr0);
 			udelay(250);
 		}
 
 close_tx_incomplete:
 
-		if (vcc->qos.txtp.traffic_class == ATM_CBR)
-		{
+		if (vcc->qos.txtp.traffic_class == ATM_CBR) {
 			int reg = he_vcc->rc_index;
 
 			HPRINTK("cs_stper reg = %d\n", reg);
@@ -2929,18 +2708,14 @@
 
 			he_dev->total_bw -= he_dev->cs_stper[reg].pcr;
 		}
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 		HPRINTK("close tx cid 0x%x complete\n", cid);
 	}
 
 	kfree(he_vcc);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
-	vcc->flags &= ~ATM_VF_ADDR;
-#else
 	clear_bit(ATM_VF_ADDR, &vcc->flags);
-#endif
 }
 
 static int
@@ -2969,66 +2744,51 @@
 	HPRINTK("send %d.%d\n", vcc->vpi, vcc->vci);
 
 	if ((skb->len > HE_TPD_BUFSIZE) ||
-		((vcc->qos.aal == ATM_AAL0) && (skb->len != ATM_AAL0_SDU)))
-	{
+	    ((vcc->qos.aal == ATM_AAL0) && (skb->len != ATM_AAL0_SDU))) {
 		hprintk("buffer too large (or small) -- %d bytes\n", skb->len );
 		if (vcc->pop)
 			vcc->pop(vcc, skb);
 		else
 			dev_kfree_skb_any(skb);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,99)
-		++vcc->stats->tx_err;
-#else
 		atomic_inc(&vcc->stats->tx_err);
-#endif
 		return -EINVAL;
 	}
 
 #ifndef USE_SCATTERGATHER
-	if (skb_shinfo(skb)->nr_frags)
-	{
-		hprintk1("no scatter/gather support\n");
+	if (skb_shinfo(skb)->nr_frags) {
+		hprintk("no scatter/gather support\n");
 		if (vcc->pop)
 			vcc->pop(vcc, skb);
 		else
 			dev_kfree_skb_any(skb);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,99)
-		++vcc->stats->tx_err;
-#else
 		atomic_inc(&vcc->stats->tx_err);
-#endif
 		return -EINVAL;
 	}
 #endif
-	HE_SPIN_LOCK(he_dev, flags);
+	spin_lock_irqsave(&he_dev->global_lock, flags);
 
 	tpd = __alloc_tpd(he_dev);
-	if (tpd == NULL)
-	{
+	if (tpd == NULL) {
 		if (vcc->pop)
 			vcc->pop(vcc, skb);
 		else
 			dev_kfree_skb_any(skb);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,99)
-		++vcc->stats->tx_err;
-#else
 		atomic_inc(&vcc->stats->tx_err);
-#endif
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 		return -ENOMEM;
 	}
 
 	if (vcc->qos.aal == ATM_AAL5)
 		tpd->status |= TPD_CELLTYPE(TPD_USERCELL);
-	else
-	{
+	else {
 		char *pti_clp = (void *) (skb->data + 3);
 		int clp, pti;
 
 		pti = (*pti_clp & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT; 
 		clp = (*pti_clp & ATM_HDR_CLP);
 		tpd->status |= TPD_CELLTYPE(pti);
-		if (clp) tpd->status |= TPD_CLP;
+		if (clp)
+			tpd->status |= TPD_CLP;
 
 		skb_pull(skb, ATM_AAL0_SDU - ATM_CELL_PAYLOAD);
 	}
@@ -3039,12 +2799,10 @@
 	tpd->iovec[slot].len = skb->len - skb->data_len;
 	++slot;
 
-	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-	{
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
-		if (slot == TPD_MAXIOV)		/* send tpd; start new tpd */
-		{
+		if (slot == TPD_MAXIOV) {	/* queue tpd; start new tpd */
 			tpd->vcc = vcc;
 			tpd->skb = NULL;	/* not the last fragment
 						   so dont ->push() yet */
@@ -3052,18 +2810,13 @@
 
 			__enqueue_tpd(he_dev, tpd, cid);
 			tpd = __alloc_tpd(he_dev);
-			if (tpd == NULL)
-			{
+			if (tpd == NULL) {
 				if (vcc->pop)
 					vcc->pop(vcc, skb);
 				else
 					dev_kfree_skb_any(skb);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,99)
-				++vcc->stats->tx_err;
-#else
 				atomic_inc(&vcc->stats->tx_err);
-				HE_SPIN_UNLOCK(he_dev, flags);
-#endif
+				spin_unlock_irqrestore(&he_dev->global_lock, flags);
 				return -ENOMEM;
 			}
 			tpd->status |= TPD_USERCELL;
@@ -3078,7 +2831,7 @@
 
 	}
 
-	tpd->iovec[slot-1].len |= TPD_LST;
+	tpd->iovec[slot - 1].len |= TPD_LST;
 #else
 	tpd->address0 = pci_map_single(he_dev->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE);
 	tpd->length0 = skb->len | TPD_LST;
@@ -3091,13 +2844,9 @@
 	ATM_SKB(skb)->vcc = vcc;
 
 	__enqueue_tpd(he_dev, tpd, cid);
-	HE_SPIN_UNLOCK(he_dev, flags);
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,99)
-	++vcc->stats->tx;
-#else
 	atomic_inc(&vcc->stats->tx);
-#endif
 
 	return 0;
 }
@@ -3110,16 +2859,15 @@
 	struct he_ioctl_reg reg;
 	int err = 0;
 
-	switch (cmd)
-	{
+	switch (cmd) {
 		case HE_GET_REG:
-			if (!capable(CAP_NET_ADMIN)) return -EPERM;
+			if (!capable(CAP_NET_ADMIN))
+				return -EPERM;
 
 			copy_from_user(&reg, (struct he_ioctl_reg *) arg,
 						sizeof(struct he_ioctl_reg));
-			HE_SPIN_LOCK(he_dev, flags);
-			switch (reg.type)
-			{
+			spin_lock_irqsave(&he_dev->global_lock, flags);
+			switch (reg.type) {
 				case HE_REGTYPE_PCI:
 					reg.val = he_readl(he_dev, reg.addr);
 					break;
@@ -3139,8 +2887,9 @@
 					err = -EINVAL;
 					break;
 			}
-			HE_SPIN_UNLOCK(he_dev, flags);
-			if (err == 0) copy_to_user((struct he_ioctl_reg *) arg, &reg,
+			spin_unlock_irqrestore(&he_dev->global_lock, flags);
+			if (err == 0)
+				copy_to_user((struct he_ioctl_reg *) arg, &reg,
 							sizeof(struct he_ioctl_reg));
 			break;
 		default:
@@ -3148,7 +2897,7 @@
 			if (atm_dev->phy && atm_dev->phy->ioctl)
 				err = atm_dev->phy->ioctl(atm_dev, cmd, arg);
 #else /* CONFIG_ATM_HE_USE_SUNI */
-			return -EINVAL;
+			err = -EINVAL;
 #endif /* CONFIG_ATM_HE_USE_SUNI */
 			break;
 	}
@@ -3164,15 +2913,15 @@
 
 	HPRINTK("phy_put(val 0x%x, addr 0x%lx)\n", val, addr);
 
-	HE_SPIN_LOCK(he_dev, flags);
-        he_writel(he_dev, val, FRAMER + (addr*4));
+	spin_lock_irqsave(&he_dev->global_lock, flags);
+	he_writel(he_dev, val, FRAMER + (addr*4));
 #ifdef CONFIG_IA64_SGI_SN2
 	(void) he_readl(he_dev, FRAMER + (addr*4));
 #endif
-	HE_SPIN_UNLOCK(he_dev, flags);
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 }
  
-        
+	
 static unsigned char
 he_phy_get(struct atm_dev *atm_dev, unsigned long addr)
 { 
@@ -3180,9 +2929,9 @@
 	struct he_dev *he_dev = HE_DEV(atm_dev);
 	unsigned reg;
 
-	HE_SPIN_LOCK(he_dev, flags);
-        reg = he_readl(he_dev, FRAMER + (addr*4));
-	HE_SPIN_UNLOCK(he_dev, flags);
+	spin_lock_irqsave(&he_dev->global_lock, flags);
+	reg = he_readl(he_dev, FRAMER + (addr*4));
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 	HPRINTK("phy_get(addr 0x%lx) =0x%x\n", addr, reg);
 	return reg;
@@ -3197,7 +2946,7 @@
 #ifdef notdef
 	struct he_rbrq *rbrq_tail;
 	struct he_tpdrq *tpdrq_head;
-        int rbpl_head, rbpl_tail;
+	int rbpl_head, rbpl_tail;
 #endif
 	static long mcc = 0, oec = 0, dcc = 0, cec = 0;
 
@@ -3213,12 +2962,12 @@
 	if (!left--)
 		return sprintf(page, "Mismatched Cells  VPI/VCI Not Open  Dropped Cells  RCM Dropped Cells\n");
 
-	HE_SPIN_LOCK(he_dev, flags);
+	spin_lock_irqsave(&he_dev->global_lock, flags);
 	mcc += he_readl(he_dev, MCC);
 	oec += he_readl(he_dev, OEC);
 	dcc += he_readl(he_dev, DCC);
 	cec += he_readl(he_dev, CEC);
-	HE_SPIN_UNLOCK(he_dev, flags);
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 	if (!left--)
 		return sprintf(page, "%16ld  %16ld  %13ld  %17ld\n\n", 
@@ -3242,11 +2991,12 @@
 
 
 #ifdef notdef
-        rbpl_head = RBPL_MASK(he_readl(he_dev, G0_RBPL_S));
-        rbpl_tail = RBPL_MASK(he_readl(he_dev, G0_RBPL_T));
+	rbpl_head = RBPL_MASK(he_readl(he_dev, G0_RBPL_S));
+	rbpl_tail = RBPL_MASK(he_readl(he_dev, G0_RBPL_T));
 
 	inuse = rbpl_head - rbpl_tail;
-	if (inuse < 0) inuse += CONFIG_RBPL_SIZE * sizeof(struct he_rbp);
+	if (inuse < 0)
+		inuse += CONFIG_RBPL_SIZE * sizeof(struct he_rbp);
 	inuse /= sizeof(struct he_rbp);
 
 	if (!left--)
@@ -3287,32 +3037,31 @@
 	he_writel(he_dev, val, HOST_CNTL);
        
 	/* Send READ instruction */
-	for (i=0; i<sizeof(readtab)/sizeof(readtab[0]); i++) {
+	for (i = 0; i < sizeof(readtab)/sizeof(readtab[0]); i++) {
 		he_writel(he_dev, val | readtab[i], HOST_CNTL);
 		udelay(EEPROM_DELAY);
 	}
        
-        /* Next, we need to send the byte address to read from */
-	for (i=7; i>=0; i--) {
+	/* Next, we need to send the byte address to read from */
+	for (i = 7; i >= 0; i--) {
 		he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL);
 		udelay(EEPROM_DELAY);
 		he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL);
 		udelay(EEPROM_DELAY);
 	}
        
-	j=0;
+	j = 0;
 
 	val &= 0xFFFFF7FF;      /* Turn off write enable */
 	he_writel(he_dev, val, HOST_CNTL);
        
 	/* Now, we can read data from the EEPROM by clocking it in */
-	for (i=7; i>=0; i--) {
+	for (i = 7; i >= 0; i--) {
 		he_writel(he_dev, val | clocktab[j++], HOST_CNTL);
-	        udelay(EEPROM_DELAY);
-	        tmp_read = he_readl(he_dev, HOST_CNTL);
-	        byte_read |= (unsigned char)
-	                        ((tmp_read & ID_DOUT)
-	                         >> ID_DOFFSET << i);
+		udelay(EEPROM_DELAY);
+		tmp_read = he_readl(he_dev, HOST_CNTL);
+		byte_read |= (unsigned char)
+			   ((tmp_read & ID_DOUT) >> ID_DOFFSET << i);
 		he_writel(he_dev, val | clocktab[j++], HOST_CNTL);
 		udelay(EEPROM_DELAY);
 	}
@@ -3320,9 +3069,10 @@
 	he_writel(he_dev, val | ID_CS, HOST_CNTL);
 	udelay(EEPROM_DELAY);
 
-        return (byte_read);
+	return byte_read;
 }
 
+MODULE_LICENSE("GPL");
 MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
 MODULE_DESCRIPTION("ForeRunnerHE ATM Adapter driver");
 MODULE_PARM(disable64, "h");
@@ -3338,82 +3088,28 @@
 MODULE_PARM(sdh, "i");
 MODULE_PARM_DESC(sdh, "use SDH framing (default 0)");
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,1)
 static struct pci_device_id he_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_HE, PCI_ANY_ID, PCI_ANY_ID,
 	  0, 0, 0 },
-        { 0, }
+	{ 0, }
 };
 
 static struct pci_driver he_driver = {
 	.name =		"he",
 	.probe =	he_init_one,
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,9)
 	.remove =	__devexit_p(he_remove_one),
-#else
-	.remove =	he_remove_one,
-#endif
 	.id_table =	he_pci_tbl,
 };
 
 static int __init he_init(void)
 {
-        return pci_module_init(&he_driver);
+	return pci_module_init(&he_driver);
 }
 
 static void __exit he_cleanup(void)
 {
-        pci_unregister_driver(&he_driver);
+	pci_unregister_driver(&he_driver);
 }
 
 module_init(he_init);
 module_exit(he_cleanup);
-#else
-static int __init
-he_init()
-{
-	if (!pci_present())
-		return -EIO;
-
-#ifdef CONFIG_ATM_HE_USE_SUNI_MODULE
-	/* request_module("suni"); */
-#endif
-
-	pci_dev = NULL;
-	while ((pci_dev = pci_find_device(PCI_VENDOR_ID_FORE,
-					PCI_DEVICE_ID_FORE_HE, pci_dev)) != NULL)
-		if (he_init_one(pci_dev, NULL) == 0)
-			++ndevs;
-
-	return (ndevs ? 0 : -ENODEV);
-}
-
-static void __devexit
-he_cleanup(void)
-{
-	while (he_devs)
-	{
-		struct he_dev *next = he_devs->next;
-		he_stop(he_devs);
-		atm_dev_deregister(he_devs->atm_dev);
-		kfree(he_devs);
-
-		he_devs = next;
-	}
-
-}
-
-int init_module(void)
-{
-	return he_init();
-}
-
-void cleanup_module(void)
-{
-	he_cleanup();
-}
-#endif
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,7)
-MODULE_LICENSE("GPL");
-#endif
diff -urN linux-2.4.22-pre2/drivers/atm/he.h linux-2.4.22-pre3/drivers/atm/he.h
--- linux-2.4.22-pre2/drivers/atm/he.h	2003-07-05 18:09:17.000000000 -0700
+++ linux-2.4.22-pre3/drivers/atm/he.h	2003-07-05 18:09:55.000000000 -0700
@@ -355,21 +355,24 @@
 	struct he_dev *next;
 };
 
+struct he_iovec
+{
+	u32 iov_base;
+	u32 iov_len;
+};
+
+#define HE_MAXIOV 20
+
 struct he_vcc
 {
-	struct iovec iov_head[32];
-	struct iovec *iov_tail;
+	struct he_iovec iov_head[HE_MAXIOV];
+	struct he_iovec *iov_tail;
 	int pdu_len;
 
 	int rc_index;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
-	struct wait_queue *rx_waitq;
-	atruct wait_queue *tx_waitq;
-#else
 	wait_queue_head_t rx_waitq;
 	wait_queue_head_t tx_waitq;
-#endif
 };
 
 #define HE_VCC(vcc)	((struct he_vcc *)(vcc->dev_data))
diff -urN linux-2.4.22-pre2/drivers/atm/horizon.c linux-2.4.22-pre3/drivers/atm/horizon.c
--- linux-2.4.22-pre2/drivers/atm/horizon.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/drivers/atm/horizon.c	2003-07-05 18:09:55.000000000 -0700
@@ -1765,17 +1765,20 @@
   
   {
     unsigned int tx_len = skb->len;
-    unsigned int tx_iovcnt = ATM_SKB(skb)->iovcnt;
+    unsigned int tx_iovcnt = skb_shinfo(skb)->nr_frags;
     // remember this so we can free it later
     dev->tx_skb = skb;
     
     if (tx_iovcnt) {
       // scatter gather transfer
       dev->tx_regions = tx_iovcnt;
-      dev->tx_iovec = (struct iovec *) skb->data;
+      dev->tx_iovec = 0;		/* @@@ needs rewritten */
       dev->tx_bytes = 0;
       PRINTD (DBG_TX|DBG_BUS, "TX start scatter-gather transfer (iovec %p, len %d)",
 	      skb->data, tx_len);
+      tx_release (dev);
+      hrz_kfree_skb (skb);
+      return -EIO;
     } else {
       // simple transfer
       dev->tx_regions = 0;
diff -urN linux-2.4.22-pre2/drivers/atm/idt77252.c linux-2.4.22-pre3/drivers/atm/idt77252.c
--- linux-2.4.22-pre2/drivers/atm/idt77252.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/drivers/atm/idt77252.c	2003-07-05 18:09:55.000000000 -0700
@@ -1988,7 +1988,7 @@
 		return -EINVAL;
 	}
 
-	if (ATM_SKB(skb)->iovcnt != 0) {
+	if (skb_shinfo(skb)->nr_frags != 0) {
 		printk("%s: No scatter-gather yet.\n", card->name);
 		atomic_inc(&vcc->stats->tx_err);
 		dev_kfree_skb(skb);
@@ -2025,8 +2025,7 @@
 		atomic_inc(&vcc->stats->tx_err);
 		return -ENOMEM;
 	}
-	atomic_add(skb->truesize + ATM_PDU_OVHD, &vcc->sk->wmem_alloc);
-	ATM_SKB(skb)->iovcnt = 0;
+	atomic_add(skb->truesize, &vcc->sk->wmem_alloc);
 
 	memcpy(skb_put(skb, 52), cell, 52);
 
diff -urN linux-2.4.22-pre2/drivers/atm/iphase.c linux-2.4.22-pre3/drivers/atm/iphase.c
--- linux-2.4.22-pre2/drivers/atm/iphase.c	2003-07-05 18:09:17.000000000 -0700
+++ linux-2.4.22-pre3/drivers/atm/iphase.c	2003-07-05 18:09:55.000000000 -0700
@@ -1186,7 +1186,6 @@
 	skb_put(skb,len);  
         // pwang_test
         ATM_SKB(skb)->vcc = vcc;
-        ATM_SKB(skb)->iovcnt = 0;
         ATM_DESC(skb) = desc;        
 	skb_queue_tail(&iadev->rx_dma_q, skb);  
 
@@ -2972,7 +2971,7 @@
 	                 dev_kfree_skb_any(skb);
 	           return 0;
 	   }
-	   kfree(skb);
+	   dev_kfree_skb_any(skb);
 	   skb = newskb;
         }       
 	/* Get a descriptor number from our free descriptor queue  
diff -urN linux-2.4.22-pre2/drivers/atm/lanai.c linux-2.4.22-pre3/drivers/atm/lanai.c
--- linux-2.4.22-pre2/drivers/atm/lanai.c	2002-11-28 15:53:12.000000000 -0800
+++ linux-2.4.22-pre3/drivers/atm/lanai.c	2003-07-05 18:09:55.000000000 -0700
@@ -2842,7 +2842,6 @@
 	phy_get:	NULL,
 	feedback:	NULL,
 	change_qos:	lanai_change_qos,
-	free_rx_skb:	NULL,
 	proc_read:	lanai_proc_read
 };
 
diff -urN linux-2.4.22-pre2/drivers/atm/nicstar.c linux-2.4.22-pre3/drivers/atm/nicstar.c
--- linux-2.4.22-pre2/drivers/atm/nicstar.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/drivers/atm/nicstar.c	2003-07-05 18:09:55.000000000 -0700
@@ -941,9 +941,14 @@
       return error;
    }
       
-   if (ns_parse_mac(mac[i], card->atmdev->esi))
+   if (ns_parse_mac(mac[i], card->atmdev->esi)) {
       nicstar_read_eprom(card->membase, NICSTAR_EPROM_MAC_ADDR_OFFSET,
                          card->atmdev->esi, 6);
+      if (memcmp(card->atmdev->esi, "\x00\x00\x00\x00\x00\x00", 6) == 0) {
+         nicstar_read_eprom(card->membase, NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT,
+                         card->atmdev->esi, 6);
+      }
+   }
 
    printk("nicstar%d: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n", i,
           card->atmdev->esi[0], card->atmdev->esi[1], card->atmdev->esi[2],
@@ -1659,9 +1664,9 @@
 	        card->index);
          iovb = vc->rx_iov;
          recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data,
-	                       ATM_SKB(iovb)->iovcnt);
-         ATM_SKB(iovb)->iovcnt = 0;
-         ATM_SKB(iovb)->vcc = NULL;
+	                       NS_SKB(iovb)->iovcnt);
+         NS_SKB(iovb)->iovcnt = 0;
+         NS_SKB(iovb)->vcc = NULL;
          ns_grab_int_lock(card, flags);
          recycle_iov_buf(card, iovb);
          spin_unlock_irqrestore(&card->int_lock, flags);
@@ -1859,7 +1864,7 @@
       return -EINVAL;
    }
    
-   if (ATM_SKB(skb)->iovcnt != 0)
+   if (skb_shinfo(skb)->nr_frags != 0)
    {
       printk("nicstar%d: No scatter-gather yet.\n", card->index);
       atomic_inc(&vcc->stats->tx_err);
@@ -2284,30 +2289,30 @@
 	    }
 	 }
       vc->rx_iov = iovb;
-      ATM_SKB(iovb)->iovcnt = 0;
+      NS_SKB(iovb)->iovcnt = 0;
       iovb->len = 0;
       iovb->tail = iovb->data = iovb->head;
-      ATM_SKB(iovb)->vcc = vcc;
+      NS_SKB(iovb)->vcc = vcc;
       /* IMPORTANT: a pointer to the sk_buff containing the small or large
                     buffer is stored as iovec base, NOT a pointer to the 
 	            small or large buffer itself. */
    }
-   else if (ATM_SKB(iovb)->iovcnt >= NS_MAX_IOVECS)
+   else if (NS_SKB(iovb)->iovcnt >= NS_MAX_IOVECS)
    {
       printk("nicstar%d: received too big AAL5 SDU.\n", card->index);
       atomic_inc(&vcc->stats->rx_err);
       recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, NS_MAX_IOVECS);
-      ATM_SKB(iovb)->iovcnt = 0;
+      NS_SKB(iovb)->iovcnt = 0;
       iovb->len = 0;
       iovb->tail = iovb->data = iovb->head;
-      ATM_SKB(iovb)->vcc = vcc;
+      NS_SKB(iovb)->vcc = vcc;
    }
-   iov = &((struct iovec *) iovb->data)[ATM_SKB(iovb)->iovcnt++];
+   iov = &((struct iovec *) iovb->data)[NS_SKB(iovb)->iovcnt++];
    iov->iov_base = (void *) skb;
    iov->iov_len = ns_rsqe_cellcount(rsqe) * 48;
    iovb->len += iov->iov_len;
 
-   if (ATM_SKB(iovb)->iovcnt == 1)
+   if (NS_SKB(iovb)->iovcnt == 1)
    {
       if (skb->list != &card->sbpool.queue)
       {
@@ -2321,7 +2326,7 @@
          return;
       }
    }
-   else /* ATM_SKB(iovb)->iovcnt >= 2 */
+   else /* NS_SKB(iovb)->iovcnt >= 2 */
    {
       if (skb->list != &card->lbpool.queue)
       {
@@ -2330,7 +2335,7 @@
          which_list(card, skb);
          atomic_inc(&vcc->stats->rx_err);
          recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data,
-	                       ATM_SKB(iovb)->iovcnt);
+	                       NS_SKB(iovb)->iovcnt);
          vc->rx_iov = NULL;
          recycle_iov_buf(card, iovb);
 	 return;
@@ -2354,7 +2359,7 @@
             printk(".\n");
          atomic_inc(&vcc->stats->rx_err);
          recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data,
-	   ATM_SKB(iovb)->iovcnt);
+	   NS_SKB(iovb)->iovcnt);
 	 vc->rx_iov = NULL;
          recycle_iov_buf(card, iovb);
 	 return;
@@ -2362,7 +2367,7 @@
 
       /* By this point we (hopefully) have a complete SDU without errors. */
 
-      if (ATM_SKB(iovb)->iovcnt == 1)	/* Just a small buffer */
+      if (NS_SKB(iovb)->iovcnt == 1)	/* Just a small buffer */
       {
          /* skb points to a small buffer */
          if (!atm_charge(vcc, skb->truesize))
@@ -2384,7 +2389,7 @@
             atomic_inc(&vcc->stats->rx);
          }
       }
-      else if (ATM_SKB(iovb)->iovcnt == 2)	/* One small plus one large buffer */
+      else if (NS_SKB(iovb)->iovcnt == 2)	/* One small plus one large buffer */
       {
          struct sk_buff *sb;
 
@@ -2461,7 +2466,7 @@
                printk("nicstar%d: Out of huge buffers.\n", card->index);
                atomic_inc(&vcc->stats->rx_drop);
                recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data,
-	                             ATM_SKB(iovb)->iovcnt);
+	                             NS_SKB(iovb)->iovcnt);
                vc->rx_iov = NULL;
                recycle_iov_buf(card, iovb);
                return;
@@ -2499,7 +2504,7 @@
 
          if (!atm_charge(vcc, hb->truesize))
 	 {
-            recycle_iovec_rx_bufs(card, iov, ATM_SKB(iovb)->iovcnt);
+            recycle_iovec_rx_bufs(card, iov, NS_SKB(iovb)->iovcnt);
             if (card->hbpool.count < card->hbnr.max)
             {
                skb_queue_tail(&card->hbpool.queue, hb);
@@ -2522,7 +2527,7 @@
                         0, 0);
 
             /* Copy all large buffers to the huge buffer and free them */
-            for (j = 1; j < ATM_SKB(iovb)->iovcnt; j++)
+            for (j = 1; j < NS_SKB(iovb)->iovcnt; j++)
             {
                lb = (struct sk_buff *) iov->iov_base;
                tocopy = MIN(remaining, iov->iov_len);
diff -urN linux-2.4.22-pre2/drivers/atm/nicstar.h linux-2.4.22-pre3/drivers/atm/nicstar.h
--- linux-2.4.22-pre2/drivers/atm/nicstar.h	2001-10-25 13:53:46.000000000 -0700
+++ linux-2.4.22-pre3/drivers/atm/nicstar.h	2003-07-05 18:09:55.000000000 -0700
@@ -96,6 +96,7 @@
 /* ESI stuff ******************************************************************/
 
 #define NICSTAR_EPROM_MAC_ADDR_OFFSET 0x6C
+#define NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT 0xF6
 
 
 /* #defines *******************************************************************/
@@ -749,6 +750,15 @@
 } vc_map;
 
 
+struct ns_skb_data
+{
+	struct atm_vcc *vcc;
+	int iovcnt;
+};
+
+#define NS_SKB(skb) (((struct ns_skb_data *) (skb)->cb))
+
+
 typedef struct ns_dev
 {
    int index;				/* Card ID to the device driver */
diff -urN linux-2.4.22-pre2/drivers/atm/zatm.c linux-2.4.22-pre3/drivers/atm/zatm.c
--- linux-2.4.22-pre2/drivers/atm/zatm.c	2001-09-14 14:40:00.000000000 -0700
+++ linux-2.4.22-pre3/drivers/atm/zatm.c	2003-07-05 18:09:56.000000000 -0700
@@ -827,10 +827,10 @@
 	vcc = ATM_SKB(skb)->vcc;
 	zatm_dev = ZATM_DEV(vcc->dev);
 	zatm_vcc = ZATM_VCC(vcc);
-	EVENT("iovcnt=%d\n",ATM_SKB(skb)->iovcnt,0);
+	EVENT("iovcnt=%d\n",skb_shinfo(skb)->nr_frags,0);
 	save_flags(flags);
 	cli();
-	if (!ATM_SKB(skb)->iovcnt) {
+	if (!skb_shinfo(skb)->nr_frags) {
 		if (zatm_vcc->txing == RING_ENTRIES-1) {
 			restore_flags(flags);
 			return RING_BUSY;
diff -urN linux-2.4.22-pre2/drivers/block/cciss.c linux-2.4.22-pre3/drivers/block/cciss.c
--- linux-2.4.22-pre2/drivers/block/cciss.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/drivers/block/cciss.c	2003-07-05 18:09:56.000000000 -0700
@@ -44,12 +44,12 @@
 #include <linux/genhd.h>
 
 #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "HP CISS Driver (v 2.4.42)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,42)
+#define DRIVER_NAME "HP CISS Driver (v 2.4.44)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,44)
 
 /* Embedded module documentation macros - see modules.h */
 MODULE_AUTHOR("Charles M. White III - Hewlett-Packard Company");
-MODULE_DESCRIPTION("Driver for HP SA5xxx SA6xxx Controllers version 2.4.42");
+MODULE_DESCRIPTION("Driver for HP SA5xxx SA6xxx Controllers version 2.4.44");
 MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"); 
 MODULE_LICENSE("GPL");
 
@@ -73,6 +73,8 @@
                         0x0E11, 0x409B, 0, 0, 0},
 	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
                         0x0E11, 0x409C, 0, 0, 0},
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
+                        0x0E11, 0x409D, 0, 0, 0},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
@@ -90,11 +92,13 @@
 	{ 0x40830E11, "Smart Array 5312", &SA5B_access},
 	{ 0x409A0E11, "Smart Array 641", &SA5_access},
 	{ 0x409B0E11, "Smart Array 642", &SA5_access},
-	{ 0x409C0E11, "Smart Array 6400", &SA5_access},
+	{ 0x409C0E11, "Smart Array 6402", &SA5_access},
+	{ 0x409C0E11, "Smart Array 6404/256", &SA5_access},
 };
 
 /* How long to wait (in millesconds) for board to go into simple mode */
-#define MAX_CONFIG_WAIT 1000 
+#define MAX_CONFIG_WAIT 30000 
+#define MAX_IOCTL_CONFIG_WAIT 1000
 
 /*define how many times we will try a command because of bus resets */
 #define MAX_CMD_RETRIES 3
@@ -103,7 +107,7 @@
 #define NR_CMDS		 128 /* #commands that can be outstanding */
 #define MAX_CTLR 8
 
-#define CCISS_DMA_MASK	0xFFFFFFFF	/* 32 bit DMA */
+#define CCISS_DMA_MASK 0xFFFFFFFFFFFFFFFF /* 64 bit DMA */
 
 static ctlr_info_t *hba[MAX_CTLR];
 
@@ -578,7 +582,7 @@
                         &(c->cfgtable->HostWrite.CoalIntCount));
 		writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
-		for(i=0;i<MAX_CONFIG_WAIT;i++) {
+		for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
 			if (!(readl(c->vaddr + SA5_DOORBELL) 
 					& CFGTBL_ChangeReq))
 				break;
@@ -586,8 +590,11 @@
 			udelay(1000);
 		}	
 		spin_unlock_irqrestore(&io_request_lock, flags);
-		if (i >= MAX_CONFIG_WAIT)
-			return -EFAULT;
+		if (i >= MAX_IOCTL_CONFIG_WAIT)
+			/* there is an unlikely case where this can happen,
+			 * involving hot replacing a failed 144 GB drive in a 
+			 * RAID 5 set just as we attempt this ioctl. */
+			return -EAGAIN;
                 return 0;
         }
 	case CCISS_GETNODENAME:
@@ -627,7 +634,7 @@
 			
 		writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
-		for(i=0;i<MAX_CONFIG_WAIT;i++) {
+		for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
 			if (!(readl(c->vaddr + SA5_DOORBELL) 
 					& CFGTBL_ChangeReq))
 				break;
@@ -635,8 +642,11 @@
 			udelay(1000);
 		}	
 		spin_unlock_irqrestore(&io_request_lock, flags);
-		if (i >= MAX_CONFIG_WAIT)
-			return -EFAULT;
+		if (i >= MAX_IOCTL_CONFIG_WAIT)
+			/* there is an unlikely case where this can happen,
+			 * involving hot replacing a failed 144 GB drive in a 
+			 * RAID 5 set just as we attempt this ioctl. */
+			return -EAGAIN;
                 return 0;
         }
 
@@ -1345,15 +1355,7 @@
 			sizeof(ReportLunData_struct), 0, 0, 0 );
 
 	if (return_code == IO_OK) {
-		/* printk("LUN Data\n--------------------------\n"); */
-		listlength |= (0xff &
-			(unsigned int)(ld_buff->LUNListLength[0])) << 24;
-		listlength |= (0xff &
-			(unsigned int)(ld_buff->LUNListLength[1])) << 16;
-		listlength |= (0xff &
-			(unsigned int)(ld_buff->LUNListLength[2])) << 8;
-		listlength |= 0xff &
-			(unsigned int)(ld_buff->LUNListLength[3]);
+		listlength = be32_to_cpu(*((__u32 *) &ld_buff->LUNListLength[0]));
 	} else {
 		/* reading number of logical volumes failed */
 		printk(KERN_WARNING "cciss: report logical volume"
@@ -2435,25 +2437,54 @@
 	c->io_mem_addr = 0;
 	c->io_mem_length = 0;
 }
+static int find_PCI_BAR_index(struct pci_dev *pdev,
+               unsigned long pci_bar_addr)
+{
+	int i, offset, mem_type, bar_type;
+	if (pci_bar_addr == PCI_BASE_ADDRESS_0) /* looking for BAR zero? */
+		return 0;
+	offset = 0;
+	for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
+		bar_type = pci_resource_flags(pdev, i) &
+			PCI_BASE_ADDRESS_SPACE; 
+		if (bar_type == PCI_BASE_ADDRESS_SPACE_IO)
+			offset += 4;
+		else {
+			mem_type = pci_resource_flags(pdev, i) &
+				PCI_BASE_ADDRESS_MEM_TYPE_MASK; 
+			switch (mem_type) {
+				case PCI_BASE_ADDRESS_MEM_TYPE_32:
+				case PCI_BASE_ADDRESS_MEM_TYPE_1M:
+					offset += 4; /* 32 bit */
+					break;
+				case PCI_BASE_ADDRESS_MEM_TYPE_64:
+					offset += 8;
+					break;
+				case PCI_BASE_ADDRESS_MEM_PREFETCH:
+				break;
+			}
+		}
+		if (offset == pci_bar_addr - PCI_BASE_ADDRESS_0)
+			return i+1;
+	}
+	return -1;
+}
+			
 static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 {
 	ushort vendor_id, device_id, command;
 	unchar cache_line_size, latency_timer;
 	unchar irq, revision;
-	uint addr[6];
 	__u32 board_id;
-	int cfg_offset;
-	int cfg_base_addr;
-	int cfg_base_addr_index;
+	__u64 cfg_offset;
+	__u32 cfg_base_addr;
+	__u64 cfg_base_addr_index;
 	int i;
 
 	vendor_id = pdev->vendor;
 	device_id = pdev->device;
 	irq = pdev->irq;
 
-	for(i=0; i<6; i++)
-		addr[i] = pdev->resource[i].start;
-
 	if (pci_enable_device(pdev)) {
 		printk(KERN_ERR "cciss: Unable to Enable PCI device\n");
 		return -1;
@@ -2479,12 +2510,12 @@
 		return -1;
 	}
 	/* search for our IO range so we can protect it */
-	for (i=0; i<6; i++) {
+	for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
 		/* is this an IO range */
-		if (pdev->resource[i].flags & 0x01) {
-			c->io_mem_addr = pdev->resource[i].start;
-			c->io_mem_length = pdev->resource[i].end -
-				pdev->resource[i].start +1; 
+		if (pci_resource_flags(pdev, i) & 0x01) {
+			c->io_mem_addr = pci_resource_start(pdev, i);
+			c->io_mem_length = pci_resource_end(pdev, i) -
+				pci_resource_start(pdev, i) + 1; 
 #ifdef CCISS_DEBUG
 			printk("IO value found base_addr[%d] %lx %lx\n", i,
 				c->io_mem_addr, c->io_mem_length);
@@ -2508,7 +2539,7 @@
 	printk("device_id = %x\n", device_id);
 	printk("command = %x\n", command);
 	for(i=0; i<6; i++)
-		printk("addr[%d] = %x\n", i, addr[i]);
+		printk("addr[%d] = %x\n", i, pci_resource_start(pdev, i);
 	printk("revision = %x\n", revision);
 	printk("irq = %x\n", irq);
 	printk("cache_line_size = %x\n", cache_line_size);
@@ -2523,7 +2554,7 @@
          *   table
 	 */
 
-	c->paddr = addr[0] ; /* addressing mode bits already removed */
+	c->paddr = pci_resource_start(pdev, 0); /* addressing mode bits already removed */
 #ifdef CCISS_DEBUG
 	printk("address 0 = %x\n", c->paddr);
 #endif /* CCISS_DEBUG */ 
@@ -2532,21 +2563,27 @@
 	/* get the address index number */
 	cfg_base_addr = readl(c->vaddr + SA5_CTCFG_OFFSET);
 	/* I am not prepared to deal with a 64 bit address value */
-	cfg_base_addr &= 0xffff;
+	cfg_base_addr &= (__u32) 0x0000ffff;
 #ifdef CCISS_DEBUG
 	printk("cfg base address = %x\n", cfg_base_addr);
 #endif /* CCISS_DEBUG */
-	cfg_base_addr_index = (cfg_base_addr  - PCI_BASE_ADDRESS_0)/4;
+	cfg_base_addr_index =
+		find_PCI_BAR_index(pdev, cfg_base_addr);
 #ifdef CCISS_DEBUG
 	printk("cfg base address index = %x\n", cfg_base_addr_index);
 #endif /* CCISS_DEBUG */
+	if (cfg_base_addr_index == -1) {
+		printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n");
+		release_io_mem(hba[i]);
+		return -1;
+	}
 
 	cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET);
 #ifdef CCISS_DEBUG
 	printk("cfg offset = %x\n", cfg_offset);
 #endif /* CCISS_DEBUG */
 	c->cfgtable = (CfgTable_struct *) 
-		remap_pci_mem((addr[cfg_base_addr_index] & 0xfffffff0)
+		remap_pci_mem(pci_resource_start(pdev, cfg_base_addr_index)
 				+ cfg_offset, sizeof(CfgTable_struct));
 	c->board_id = board_id;
 
@@ -2583,11 +2620,17 @@
 		&(c->cfgtable->HostWrite.TransportRequest));
 	writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
+	/* Here, we wait, possibly for a long time, (4 secs or more). 
+	 * In some unlikely cases, (e.g. A failed 144 GB drive in a 
+	 * RAID 5 set was hot replaced just as we're coming in here) it 
+	 * can take that long.  Normally (almost always) we will wait 
+	 * less than 1 sec. */
 	for(i=0;i<MAX_CONFIG_WAIT;i++) {
 		if (!(readl(c->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
 			break;
 		/* delay and try again */
-		udelay(1000);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
 	}	
 
 #ifdef CCISS_DEBUG
@@ -2661,10 +2704,7 @@
 		printk("LUN Data\n--------------------------\n");
 #endif /* CCISS_DEBUG */ 
 
-		listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24;
-		listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16;
-		listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8;	
-		listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]);
+		listlength = be32_to_cpu(*((__u32 *) &ld_buff->LUNListLength[0]));
 	} else { /* reading number of logical volumes failed */
 		printk(KERN_WARNING "cciss: report logical volume"
 			" command failed\n");
@@ -2834,17 +2874,6 @@
 	hba[i]->ctlr = i;
 	hba[i]->pdev = pdev;
 
-	/* configure PCI DMA stuff */
-	if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff))
-		printk("cciss: using DAC cycles\n");
-	else if (!pci_set_dma_mask(pdev, (u64) 0xffffffff))
-		printk("cciss: not using DAC cycles\n");
-	else {
-		printk("cciss: no suitable DMA available\n");
-		free_hba(i);
-		return -ENODEV;
-	}
-		
 	if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &cciss_fops)) {
 		printk(KERN_ERR "cciss:  Unable to get major number "
 			"%d for %s\n", MAJOR_NR+i, hba[i]->devname);
@@ -3021,12 +3050,8 @@
 
 	printk(KERN_INFO DRIVER_NAME "\n");
 	/* Register for out PCI devices */
-	if (pci_register_driver(&cciss_pci_driver) > 0 )
-		return 0;
-	else 
-		return -ENODEV;
-
- }
+	return pci_module_init(&cciss_pci_driver);
+}
 
 EXPORT_NO_SYMBOLS;
 static int __init init_cciss_module(void)
diff -urN linux-2.4.22-pre2/drivers/block/cciss.h linux-2.4.22-pre3/drivers/block/cciss.h
--- linux-2.4.22-pre2/drivers/block/cciss.h	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/drivers/block/cciss.h	2003-07-05 18:09:56.000000000 -0700
@@ -45,8 +45,8 @@
 	char	firm_ver[4]; // Firmware version 
 	struct pci_dev *pdev;
 	__u32	board_id;
-	ulong   vaddr;
-	__u32	paddr;	
+	unsigned long vaddr;
+	unsigned long paddr;	
 	unsigned long io_mem_addr;
 	unsigned long io_mem_length;
 	CfgTable_struct *cfgtable;
diff -urN linux-2.4.22-pre2/drivers/block/floppy.c linux-2.4.22-pre3/drivers/block/floppy.c
--- linux-2.4.22-pre2/drivers/block/floppy.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/drivers/block/floppy.c	2003-07-05 18:09:56.000000000 -0700
@@ -482,6 +482,7 @@
 
 static int floppy_sizes[256];
 static int floppy_blocksizes[256];
+static int floppy_maxsectors[256];
 
 /*
  * The driver is trying to determine the correct media format
@@ -622,7 +623,8 @@
 static void is_alive(const char *message)
 {
 	/* this routine checks whether the floppy driver is "alive" */
-	if (fdc_busy && command_status < 2 && !timer_pending(&fd_timeout)){
+	if (test_bit(0, &fdc_busy) && command_status < 2
+	    && !timer_pending(&fd_timeout)){
 		DPRINT("timeout handler died: %s\n",message);
 	}
 }
@@ -650,7 +652,7 @@
 #define CURRENTD -1
 #define MAXTIMEOUT -2
 
-static void reschedule_timeout(int drive, const char *message, int marg)
+static void __reschedule_timeout(int drive, const char *message, int marg)
 {
 	if (drive == CURRENTD)
 		drive = current_drive;
@@ -669,6 +671,16 @@
 	timeout_message = message;
 }
 
+
+static void reschedule_timeout(int drive, const char *message, int marg)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	__reschedule_timeout(drive, message, marg);
+	spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
 static int maximum(int a, int b)
 {
 	if (a > b)
@@ -897,7 +909,7 @@
 	}
 	command_status = FD_COMMAND_NONE;
 
-	reschedule_timeout(drive, "lock fdc", 0);
+	__reschedule_timeout(drive, "lock fdc", 0);
 	set_fdc(drive);
 	return 0;
 }
@@ -911,17 +923,23 @@
 /* unlocks the driver */
 static inline void unlock_fdc(void)
 {
+	unsigned long flags;
+
 	raw_cmd = 0;
-	if (!fdc_busy)
+	if (!test_bit(0, &fdc_busy))
 		DPRINT("FDC access conflict!\n");
 
 	if (DEVICE_INTR)
 		DPRINT("device interrupt still active at FDC release: %p!\n",
 			DEVICE_INTR);
 	command_status = FD_COMMAND_NONE;
+	spin_lock_irqsave(&io_request_lock, flags);
 	del_timer(&fd_timeout);
 	cont = NULL;
 	clear_bit(0, &fdc_busy);
+	if (!QUEUE_EMPTY)
+		do_fd_request(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	spin_unlock_irqrestore(&io_request_lock, flags);
 	floppy_release_irq_and_dma();
 	wake_up(&fdc_wait);
 }
@@ -1000,9 +1018,13 @@
 
 static void cancel_activity(void)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&io_request_lock, flags);
 	CLEAR_INTR;
 	floppy_tq.routine = (void *)(void *) empty;
 	del_timer(&fd_timer);
+	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
 /* this function makes sure that the disk stays in the drive during the
@@ -2986,7 +3008,7 @@
 		printk("sect=%ld cmd=%d\n", CURRENT->sector, CURRENT->cmd);
 		return;
 	}
-	if (fdc_busy){
+	if (test_bit(0, &fdc_busy)) {
 		/* fdc busy, this new request will be treated when the
 		   current one is done */
 		is_alive("do fd request, old request running");
@@ -3878,7 +3900,7 @@
 			/* auto-sensing */
 			int size = floppy_blocksizes[MINOR(dev)];
 			if (!size)
-				size = 1024;
+				size = 512;
 			if (!(bh = getblk(dev,0,size))){
 				process_fd_request();
 				return -ENXIO;
@@ -4170,14 +4192,19 @@
 		return -EBUSY;
 	}
 
-	for (i=0; i<256; i++)
+	for (i=0; i<256; i++) {
 		if (ITYPE(i))
 			floppy_sizes[i] = (floppy_type[ITYPE(i)].size+1) >> 1;
 		else
 			floppy_sizes[i] = MAX_DISK_SIZE;
 
+		floppy_blocksizes[i] = 512;
+		floppy_maxsectors[i] = 64;
+	}
+
 	blk_size[MAJOR_NR] = floppy_sizes;
 	blksize_size[MAJOR_NR] = floppy_blocksizes;
+	max_sectors[MAJOR_NR] = floppy_maxsectors;
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
 	reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
 	config_types();
diff -urN linux-2.4.22-pre2/drivers/block/ll_rw_blk.c linux-2.4.22-pre3/drivers/block/ll_rw_blk.c
--- linux-2.4.22-pre2/drivers/block/ll_rw_blk.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/drivers/block/ll_rw_blk.c	2003-07-05 18:09:56.000000000 -0700
@@ -176,11 +176,12 @@
 {
 	int count = q->nr_requests;
 
-	count -= __blk_cleanup_queue(&q->rq[READ]);
-	count -= __blk_cleanup_queue(&q->rq[WRITE]);
+	count -= __blk_cleanup_queue(&q->rq);
 
 	if (count)
 		printk("blk_cleanup_queue: leaked requests (%d)\n", count);
+	if (atomic_read(&q->nr_sectors))
+		printk("blk_cleanup_queue: leaked sectors (%d)\n", atomic_read(&q->nr_sectors));
 
 	memset(q, 0, sizeof(*q));
 }
@@ -215,6 +216,24 @@
 }
 
 /**
+ * blk_queue_throttle_sectors - indicates you will call sector throttling funcs
+ * @q:       The queue which this applies to.
+ * @active:  A flag indication if you want sector throttling on
+ *
+ * Description:
+ * The sector throttling code allows us to put a limit on the number of
+ * sectors pending io to the disk at a given time, sending @active nonzero
+ * indicates you will call blk_started_sectors and blk_finished_sectors in
+ * addition to calling blk_started_io and blk_finished_io in order to
+ * keep track of the number of sectors in flight.
+ **/
+ 
+void blk_queue_throttle_sectors(request_queue_t * q, int active)
+{
+	q->can_throttle = active;
+}
+
+/**
  * blk_queue_make_request - define an alternate make_request function for a device
  * @q:  the request queue for the device to be affected
  * @mfn: the alternate make_request function
@@ -389,7 +408,7 @@
  *
  * Returns the (new) number of requests which the queue has available.
  */
-int blk_grow_request_list(request_queue_t *q, int nr_requests)
+int blk_grow_request_list(request_queue_t *q, int nr_requests, int max_queue_sectors)
 {
 	unsigned long flags;
 	/* Several broken drivers assume that this function doesn't sleep,
@@ -399,21 +418,34 @@
 	spin_lock_irqsave(&io_request_lock, flags);
 	while (q->nr_requests < nr_requests) {
 		struct request *rq;
-		int rw;
 
 		rq = kmem_cache_alloc(request_cachep, SLAB_ATOMIC);
 		if (rq == NULL)
 			break;
 		memset(rq, 0, sizeof(*rq));
 		rq->rq_status = RQ_INACTIVE;
-		rw = q->nr_requests & 1;
-		list_add(&rq->queue, &q->rq[rw].free);
-		q->rq[rw].count++;
+ 		list_add(&rq->queue, &q->rq.free);
+ 		q->rq.count++;
+
 		q->nr_requests++;
 	}
+
+ 	/*
+ 	 * Wakeup waiters after both one quarter of the
+ 	 * max-in-fligh queue and one quarter of the requests
+ 	 * are available again.
+ 	 */
+
 	q->batch_requests = q->nr_requests / 4;
 	if (q->batch_requests > 32)
 		q->batch_requests = 32;
+ 	q->batch_sectors = max_queue_sectors / 4;
+ 
+ 	q->max_queue_sectors = max_queue_sectors;
+ 
+ 	BUG_ON(!q->batch_sectors);
+ 	atomic_set(&q->nr_sectors, 0);
+
 	spin_unlock_irqrestore(&io_request_lock, flags);
 	return q->nr_requests;
 }
@@ -422,23 +454,27 @@
 {
 	struct sysinfo si;
 	int megs;		/* Total memory, in megabytes */
-	int nr_requests;
-
-	INIT_LIST_HEAD(&q->rq[READ].free);
-	INIT_LIST_HEAD(&q->rq[WRITE].free);
-	q->rq[READ].count = 0;
-	q->rq[WRITE].count = 0;
+ 	int nr_requests, max_queue_sectors = MAX_QUEUE_SECTORS;
+  
+ 	INIT_LIST_HEAD(&q->rq.free);
+	q->rq.count = 0;
 	q->nr_requests = 0;
 
 	si_meminfo(&si);
 	megs = si.totalram >> (20 - PAGE_SHIFT);
-	nr_requests = 128;
-	if (megs < 32)
-		nr_requests /= 2;
-	blk_grow_request_list(q, nr_requests);
+ 	nr_requests = MAX_NR_REQUESTS;
+ 	if (megs < 30) {
+  		nr_requests /= 2;
+ 		max_queue_sectors /= 2;
+ 	}
+ 	/* notice early if anybody screwed the defaults */
+ 	BUG_ON(!nr_requests);
+ 	BUG_ON(!max_queue_sectors);
+ 
+ 	blk_grow_request_list(q, nr_requests, max_queue_sectors);
+
+ 	init_waitqueue_head(&q->wait_for_requests);
 
-	init_waitqueue_head(&q->wait_for_requests[0]);
-	init_waitqueue_head(&q->wait_for_requests[1]);
 	spin_lock_init(&q->queue_lock);
 }
 
@@ -491,6 +527,8 @@
 	q->plug_tq.routine	= &generic_unplug_device;
 	q->plug_tq.data		= q;
 	q->plugged        	= 0;
+	q->can_throttle		= 0;
+
 	/*
 	 * These booleans describe the queue properties.  We set the
 	 * default (and most common) values here.  Other drivers can
@@ -511,9 +549,10 @@
 static struct request *get_request(request_queue_t *q, int rw)
 {
 	struct request *rq = NULL;
-	struct request_list *rl = q->rq + rw;
+	struct request_list *rl;
 
-	if (!list_empty(&rl->free)) {
+	rl = &q->rq;
+	if (!list_empty(&rl->free) && !blk_oversized_queue(q)) {
 		rq = blkdev_free_rq(&rl->free);
 		list_del(&rq->queue);
 		rl->count--;
@@ -522,34 +561,23 @@
 		rq->special = NULL;
 		rq->q = q;
 	}
-
 	return rq;
 }
 
 /*
- * Here's the request allocation design:
+ * Here's the request allocation design, low latency version:
  *
  * 1: Blocking on request exhaustion is a key part of I/O throttling.
  * 
  * 2: We want to be `fair' to all requesters.  We must avoid starvation, and
  *    attempt to ensure that all requesters sleep for a similar duration.  Hence
  *    no stealing requests when there are other processes waiting.
- * 
- * 3: We also wish to support `batching' of requests.  So when a process is
- *    woken, we want to allow it to allocate a decent number of requests
- *    before it blocks again, so they can be nicely merged (this only really
- *    matters if the process happens to be adding requests near the head of
- *    the queue).
- * 
- * 4: We want to avoid scheduling storms.  This isn't really important, because
- *    the system will be I/O bound anyway.  But it's easy.
- * 
- *    There is tension between requirements 2 and 3.  Once a task has woken,
- *    we don't want to allow it to sleep as soon as it takes its second request.
- *    But we don't want currently-running tasks to steal all the requests
- *    from the sleepers.  We handle this with wakeup hysteresis around
- *    0 .. batch_requests and with the assumption that request taking is much,
- *    much faster than request freeing.
+ *
+ * There used to be more here, attempting to allow a process to send in a
+ * number of requests once it has woken up.  But, there's no way to 
+ * tell if a process has just been woken up, or if it is a new process
+ * coming in to steal requests from the waiters.  So, we give up and force
+ * everyone to wait fairly.
  * 
  * So here's what we do:
  * 
@@ -561,28 +589,23 @@
  * 
  *  When a process wants a new request:
  * 
- *    b) If free_requests == 0, the requester sleeps in FIFO manner.
- * 
- *    b) If 0 <  free_requests < batch_requests and there are waiters,
- *       we still take a request non-blockingly.  This provides batching.
- *
- *    c) If free_requests >= batch_requests, the caller is immediately
- *       granted a new request.
+ *    b) If free_requests == 0, the requester sleeps in FIFO manner, and
+ *       the queue full condition is set.  The full condition is not
+ *       cleared until there are no longer any waiters.  Once the full
+ *       condition is set, all new io must wait, hopefully for a very
+ *       short period of time.
  * 
  *  When a request is released:
  * 
- *    d) If free_requests < batch_requests, do nothing.
- * 
- *    f) If free_requests >= batch_requests, wake up a single waiter.
+ *    c) If free_requests < batch_requests, do nothing.
  * 
- *   The net effect is that when a process is woken at the batch_requests level,
- *   it will be able to take approximately (batch_requests) requests before
- *   blocking again (at the tail of the queue).
- * 
- *   This all assumes that the rate of taking requests is much, much higher
- *   than the rate of releasing them.  Which is very true.
+ *    d) If free_requests >= batch_requests, wake up a single waiter.
  *
- * -akpm, Feb 2002.
+ *   As each waiter gets a request, he wakes another waiter.  We do this
+ *   to prevent a race where an unplug might get run before a request makes
+ *   it's way onto the queue.  The result is a cascade of wakeups, so delaying
+ *   the initial wakeup until we've got batch_requests available helps avoid
+ *   wakeups where there aren't any requests available yet.
  */
 
 static struct request *__get_request_wait(request_queue_t *q, int rw)
@@ -590,21 +613,37 @@
 	register struct request *rq;
 	DECLARE_WAITQUEUE(wait, current);
 
-	add_wait_queue(&q->wait_for_requests[rw], &wait);
+	add_wait_queue_exclusive(&q->wait_for_requests, &wait);
+
 	do {
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		generic_unplug_device(q);
-		if (q->rq[rw].count == 0)
-			schedule();
 		spin_lock_irq(&io_request_lock);
+		if (blk_oversized_queue(q)) {
+			__generic_unplug_device(q);
+			spin_unlock_irq(&io_request_lock);
+			schedule();
+			spin_lock_irq(&io_request_lock);
+		}
 		rq = get_request(q, rw);
 		spin_unlock_irq(&io_request_lock);
 	} while (rq == NULL);
-	remove_wait_queue(&q->wait_for_requests[rw], &wait);
+	remove_wait_queue(&q->wait_for_requests, &wait);
 	current->state = TASK_RUNNING;
+
 	return rq;
 }
 
+static void get_request_wait_wakeup(request_queue_t *q, int rw)
+{
+	/*
+	 * avoid losing an unplug if a second __get_request_wait did the
+	 * generic_unplug_device while our __get_request_wait was running
+	 * w/o the queue_lock held and w/ our request out of the queue.
+	 */	
+	if (waitqueue_active(&q->wait_for_requests))
+		wake_up(&q->wait_for_requests);
+}
+
 /* RO fail safe mechanism */
 
 static long ro_bits[MAX_BLKDEV][8];
@@ -818,7 +857,6 @@
 void blkdev_release_request(struct request *req)
 {
 	request_queue_t *q = req->q;
-	int rw = req->cmd;
 
 	req->rq_status = RQ_INACTIVE;
 	req->q = NULL;
@@ -828,9 +866,17 @@
 	 * assume it has free buffers and check waiters
 	 */
 	if (q) {
-		list_add(&req->queue, &q->rq[rw].free);
-		if (++q->rq[rw].count >= q->batch_requests)
-			wake_up(&q->wait_for_requests[rw]);
+		int oversized_batch = 0;
+
+		if (q->can_throttle)
+			oversized_batch = blk_oversized_queue_batch(q);
+		q->rq.count++;
+		list_add(&req->queue, &q->rq.free);
+		if (q->rq.count >= q->batch_requests && !oversized_batch) {
+			smp_mb();
+			if (waitqueue_active(&q->wait_for_requests))
+				wake_up(&q->wait_for_requests);
+		}
 	}
 }
 
@@ -908,6 +954,7 @@
 	struct list_head *head, *insert_here;
 	int latency;
 	elevator_t *elevator = &q->elevator;
+	int should_wake = 0;
 
 	count = bh->b_size >> 9;
 	sector = bh->b_rsector;
@@ -948,7 +995,6 @@
 	 */
 	max_sectors = get_max_sectors(bh->b_rdev);
 
-again:
 	req = NULL;
 	head = &q->queue_head;
 	/*
@@ -957,7 +1003,9 @@
 	 */
 	spin_lock_irq(&io_request_lock);
 
+again:
 	insert_here = head->prev;
+
 	if (list_empty(head)) {
 		q->plug_device_fn(q, bh->b_rdev); /* is atomic */
 		goto get_rq;
@@ -976,6 +1024,7 @@
 			req->bhtail = bh;
 			req->nr_sectors = req->hard_nr_sectors += count;
 			blk_started_io(count);
+			blk_started_sectors(req, count);
 			drive_stat_acct(req->rq_dev, req->cmd, count, 0);
 			req_new_io(req, 1, count);
 			attempt_back_merge(q, req, max_sectors, max_segments);
@@ -998,6 +1047,7 @@
 			req->sector = req->hard_sector = sector;
 			req->nr_sectors = req->hard_nr_sectors += count;
 			blk_started_io(count);
+			blk_started_sectors(req, count);
 			drive_stat_acct(req->rq_dev, req->cmd, count, 0);
 			req_new_io(req, 1, count);
 			attempt_front_merge(q, head, req, max_sectors, max_segments);
@@ -1030,7 +1080,7 @@
 		 * See description above __get_request_wait()
 		 */
 		if (rw_ahead) {
-			if (q->rq[rw].count < q->batch_requests) {
+			if (q->rq.count < q->batch_requests || blk_oversized_queue_batch(q)) {
 				spin_unlock_irq(&io_request_lock);
 				goto end_io;
 			}
@@ -1042,6 +1092,9 @@
 			if (req == NULL) {
 				spin_unlock_irq(&io_request_lock);
 				freereq = __get_request_wait(q, rw);
+				head = &q->queue_head;
+				spin_lock_irq(&io_request_lock);
+				should_wake = 1;
 				goto again;
 			}
 		}
@@ -1064,10 +1117,13 @@
 	req->start_time = jiffies;
 	req_new_io(req, 0, count);
 	blk_started_io(count);
+	blk_started_sectors(req, count);
 	add_request(q, req, insert_here);
 out:
 	if (freereq)
 		blkdev_release_request(freereq);
+	if (should_wake)
+		get_request_wait_wakeup(q, rw);
 	spin_unlock_irq(&io_request_lock);
 	return 0;
 end_io:
@@ -1196,8 +1252,15 @@
 	bh->b_rdev = bh->b_dev;
 	bh->b_rsector = bh->b_blocknr * count;
 
+	get_bh(bh);
 	generic_make_request(rw, bh);
 
+	/* fix race condition with wait_on_buffer() */
+	smp_mb(); /* spin_unlock may have inclusive semantics */
+	if (waitqueue_active(&bh->b_wait))
+		wake_up(&bh->b_wait);
+
+	put_bh(bh);
 	switch (rw) {
 		case WRITE:
 			kstat.pgpgout += count;
@@ -1350,6 +1413,7 @@
 	if ((bh = req->bh) != NULL) {
 		nsect = bh->b_size >> 9;
 		blk_finished_io(nsect);
+		blk_finished_sectors(req, nsect);
 		req->bh = bh->b_reqnext;
 		bh->b_reqnext = NULL;
 		bh->b_end_io(bh, uptodate);
@@ -1509,6 +1573,7 @@
 EXPORT_SYMBOL(blk_get_queue);
 EXPORT_SYMBOL(blk_cleanup_queue);
 EXPORT_SYMBOL(blk_queue_headactive);
+EXPORT_SYMBOL(blk_queue_throttle_sectors);
 EXPORT_SYMBOL(blk_queue_make_request);
 EXPORT_SYMBOL(generic_make_request);
 EXPORT_SYMBOL(blkdev_release_request);
diff -urN linux-2.4.22-pre2/drivers/block/loop.c linux-2.4.22-pre3/drivers/block/loop.c
--- linux-2.4.22-pre2/drivers/block/loop.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/drivers/block/loop.c	2003-07-05 18:09:56.000000000 -0700
@@ -682,7 +682,7 @@
 	lo->ioctl = NULL;
 	figure_loop_size(lo);
 	lo->old_gfp_mask = inode->i_mapping->gfp_mask;
-	inode->i_mapping->gfp_mask = GFP_NOIO;
+	inode->i_mapping->gfp_mask &= ~(__GFP_IO|__GFP_FS);
 
 	bs = 0;
 	if (blksize_size[MAJOR(lo_device)])
diff -urN linux-2.4.22-pre2/drivers/block/swim3.c linux-2.4.22-pre3/drivers/block/swim3.c
--- linux-2.4.22-pre2/drivers/block/swim3.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/drivers/block/swim3.c	2003-07-05 18:09:56.000000000 -0700
@@ -2,7 +2,7 @@
  * Driver for the SWIM3 (Super Woz Integrated Machine 3)
  * floppy controller found on Power Macintoshes.
  *
- * Copyright (C) 1996 Paul Mackerras.
+ * Copyright (C) 1996-2003 Paul Mackerras.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -146,7 +146,7 @@
 #define RELAX		3	/* also eject in progress */
 #define READ_DATA_0	4
 #define TWOMEG_DRIVE	5
-#define SINGLE_SIDED	6
+#define SINGLE_SIDED	6	/* drive or diskette is 4MB type? */
 #define DRIVE_PRESENT	7
 #define DISK_IN		8
 #define WRITE_PROT	9
@@ -186,6 +186,7 @@
 	int	req_sector;	/* sector number ditto */
 	int	scount;		/* # sectors we're transferring at present */
 	int	retries;
+	int	settle_time;
 	int	secpercyl;	/* disk geometry information */
 	int	secpertrack;
 	int	total_secs;
@@ -233,6 +234,7 @@
 static void act(struct floppy_state *fs);
 static void scan_timeout(unsigned long data);
 static void seek_timeout(unsigned long data);
+static void settle_timeout(unsigned long data);
 static void xfer_timeout(unsigned long data);
 static void swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 /*static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs);*/
@@ -275,7 +277,6 @@
 	udelay(2);
 	out_8(&sw->select, sw->select & ~LSTRB);
 	udelay(1);
-	out_8(&sw->select, RELAX);
 }
 
 static int swim3_readbit(struct floppy_state *fs, int bit)
@@ -284,9 +285,8 @@
 	int stat;
 
 	swim3_select(fs, bit);
-	udelay(10);
+	udelay(1);
 	stat = in_8(&sw->status);
-	out_8(&sw->select, RELAX);
 	return (stat & DATA) == 0;
 }
 
@@ -377,13 +377,13 @@
 static inline void scan_track(struct floppy_state *fs)
 {
 	volatile struct swim3 *sw = fs->swim3;
-	int xx;
 
 	swim3_select(fs, READ_DATA_0);
-	xx = sw->intr;		/* clear SEEN_SECTOR bit */
+	in_8(&sw->intr);		/* clear SEEN_SECTOR bit */
+	in_8(&sw->error);
+	out_8(&sw->intr_enable, SEEN_SECTOR);
 	out_8(&sw->control_bis, DO_ACTION);
 	/* enable intr when track found */
-	out_8(&sw->intr_enable, ERROR_INTR | SEEN_SECTOR);
 	set_timeout(fs, HZ, scan_timeout);	/* enable timeout */
 }
 
@@ -398,12 +398,14 @@
 		swim3_action(fs, SEEK_NEGATIVE);
 		sw->nseek = -n;
 	}
-	fs->expect_cyl = (fs->cur_cyl > 0)? fs->cur_cyl + n: -1;
+	fs->expect_cyl = (fs->cur_cyl >= 0)? fs->cur_cyl + n: -1;
 	swim3_select(fs, STEP);
-	out_8(&sw->control_bis, DO_SEEK);
+	in_8(&sw->error);
 	/* enable intr when seek finished */
-	out_8(&sw->intr_enable, ERROR_INTR | SEEK_DONE);
-	set_timeout(fs, HZ/2, seek_timeout);	/* enable timeout */
+	out_8(&sw->intr_enable, SEEK_DONE);
+	out_8(&sw->control_bis, DO_SEEK);
+	set_timeout(fs, 3*HZ, seek_timeout);	/* enable timeout */
+	fs->settle_time = 0;
 }
 
 static inline void init_dma(struct dbdma_cmd *cp, int cmd,
@@ -451,18 +453,21 @@
 	}
 	++cp;
 	out_le16(&cp->command, DBDMA_STOP);
+	out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
+	in_8(&sw->error);
+	out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
+	if (CURRENT->cmd == WRITE)
+		out_8(&sw->control_bis, WRITE_SECTORS);
+	in_8(&sw->intr);
 	out_le32(&dr->control, (RUN << 16) | RUN);
-	out_8(&sw->control_bis,
-	      (CURRENT->cmd == WRITE? WRITE_SECTORS: 0) | DO_ACTION);
 	/* enable intr when transfer complete */
-	out_8(&sw->intr_enable, ERROR_INTR | TRANSFER_DONE);
+	out_8(&sw->intr_enable, TRANSFER_DONE);
+	out_8(&sw->control_bis, DO_ACTION);
 	set_timeout(fs, 2*HZ, xfer_timeout);	/* enable timeout */
 }
 
 static void act(struct floppy_state *fs)
 {
-	volatile struct swim3 *sw = fs->swim3;
-
 	for (;;) {
 		switch (fs->state) {
 		case idle:
@@ -495,20 +500,10 @@
 			return;
 
 		case settling:
-			/* wait for SEEK_COMPLETE to become true */
-			swim3_select(fs, SEEK_COMPLETE);
-			udelay(10);
-			out_8(&sw->intr_enable, ERROR_INTR | DATA_CHANGED);
-			in_8(&sw->intr);	/* clear DATA_CHANGED */
-			if (in_8(&sw->status) & DATA) {
-				/* seek_complete is not yet true */
-				set_timeout(fs, HZ/2, seek_timeout);
-				return;
-			}
-			out_8(&sw->intr_enable, 0);
-			in_8(&sw->intr);
-			fs->state = locating;
-			break;
+			/* check for SEEK_COMPLETE after 30ms */
+			fs->settle_time = (HZ + 32) / 33;
+			set_timeout(fs, fs->settle_time, settle_timeout);
+			return;
 
 		case do_transfer:
 			if (fs->cur_cyl != fs->req_cyl) {
@@ -540,7 +535,7 @@
 	volatile struct swim3 *sw = fs->swim3;
 
 	fs->timeout_pending = 0;
-	out_8(&sw->control_bic, DO_ACTION);
+	out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
 	out_8(&sw->select, RELAX);
 	out_8(&sw->intr_enable, 0);
 	fs->cur_cyl = -1;
@@ -560,20 +555,34 @@
 	volatile struct swim3 *sw = fs->swim3;
 
 	fs->timeout_pending = 0;
-	if (fs->state == settling) {
-		printk(KERN_ERR "swim3: MSI sel=%x ctrl=%x stat=%x intr=%x ie=%x\n",
-		       sw->select, sw->control, sw->status, sw->intr, sw->intr_enable);
-	}
 	out_8(&sw->control_bic, DO_SEEK);
 	out_8(&sw->select, RELAX);
 	out_8(&sw->intr_enable, 0);
-	if (fs->state == settling && swim3_readbit(fs, SEEK_COMPLETE)) {
-		/* printk(KERN_DEBUG "swim3: missed settling interrupt\n"); */
+	printk(KERN_ERR "swim3: seek timeout\n");
+	end_request(0);
+	fs->state = idle;
+	start_request(fs);
+}
+
+static void settle_timeout(unsigned long data)
+{
+	struct floppy_state *fs = (struct floppy_state *) data;
+	volatile struct swim3 *sw = fs->swim3;
+
+	fs->timeout_pending = 0;
+	if (swim3_readbit(fs, SEEK_COMPLETE)) {
+		out_8(&sw->select, RELAX);
 		fs->state = locating;
 		act(fs);
 		return;
 	}
-	printk(KERN_ERR "swim3: seek timeout\n");
+	out_8(&sw->select, RELAX);
+	if (fs->settle_time < 2*HZ) {
+		++fs->settle_time;
+		set_timeout(fs, 1, settle_timeout);
+		return;
+	}
+	printk(KERN_ERR "swim3: seek settle timeout\n");
 	end_request(0);
 	fs->state = idle;
 	start_request(fs);
@@ -586,9 +595,13 @@
 	struct dbdma_regs *dr = fs->dma;
 	struct dbdma_cmd *cp = fs->dma_cmd;
 	unsigned long s;
+	int n;
 
 	fs->timeout_pending = 0;
 	st_le32(&dr->control, RUN << 16);
+	/* We must wait a bit for dbdma to stop */
+	for (n = 0; (in_le32(&dr->status) & ACTIVE) && n < 1000; n++)
+		udelay(1);
 	out_8(&sw->intr_enable, 0);
 	out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION);
 	out_8(&sw->select, RELAX);
@@ -616,18 +629,15 @@
 	struct dbdma_regs *dr;
 	struct dbdma_cmd *cp;
 
-	err = in_8(&sw->error);
 	intr = in_8(&sw->intr);
-#if 0
-	printk("swim3 intr state=%d intr=%x err=%x\n", fs->state, intr, err);
-#endif
+	err = (intr & ERROR_INTR)? in_8(&sw->error): 0;
 	if ((intr & ERROR_INTR) && fs->state != do_transfer)
 		printk(KERN_ERR "swim3_interrupt, state=%d, cmd=%x, intr=%x, err=%x\n",
 		       fs->state, CURRENT->cmd, intr, err);
 	switch (fs->state) {
 	case locating:
 		if (intr & SEEN_SECTOR) {
-			out_8(&sw->control_bic, DO_ACTION);
+			out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
 			out_8(&sw->select, RELAX);
 			out_8(&sw->intr_enable, 0);
 			del_timer(&fs->timeout);
@@ -677,19 +687,33 @@
 	case do_transfer:
 		if ((intr & (ERROR_INTR | TRANSFER_DONE)) == 0)
 			break;
-		dr = fs->dma;
-		cp = fs->dma_cmd;
-		/* We must wait a bit for dbdma to complete */
-		for (n=0; (in_le32(&dr->status) & ACTIVE) && n < 1000; n++)
-			udelay(10);
-		DBDMA_DO_STOP(dr);
 		out_8(&sw->intr_enable, 0);
 		out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION);
 		out_8(&sw->select, RELAX);
 		del_timer(&fs->timeout);
 		fs->timeout_pending = 0;
+		dr = fs->dma;
+		cp = fs->dma_cmd;
 		if (CURRENT->cmd == WRITE)
 			++cp;
+		/*
+		 * Check that the main data transfer has finished.
+		 * On writing, the swim3 sometimes doesn't use
+		 * up all the bytes of the postamble, so we can still
+		 * see DMA active here.  That doesn't matter as long
+		 * as all the sector data has been transferred.
+		 */
+		if ((intr & ERROR_INTR) == 0 && cp->xfer_status == 0) {
+			/* wait a little while for DMA to complete */
+			for (n = 0; n < 100; ++n) {
+				if (cp->xfer_status != 0)
+					break;
+				udelay(1);
+				barrier();
+			}
+		}
+		/* turn off DMA */
+		out_le32(&dr->control, (RUN | PAUSE) << 16);
 		stat = ld_le16(&cp->xfer_status);
 		resid = ld_le16(&cp->res_count);
 		if (intr & ERROR_INTR) {
@@ -796,16 +820,19 @@
 	if (err)
 		return err;
 	swim3_action(fs, EJECT);
-	for (n = 2*HZ; n > 0; --n) {
-		if (swim3_readbit(fs, RELAX))
-			break;
+	for (n = 20; n > 0; --n) {
 		if (signal_pending(current)) {
 			err = -EINTR;
 			break;
 		}
+		swim3_select(fs, RELAX);
 		current->state = TASK_INTERRUPTIBLE;
 		schedule_timeout(1);
+		if (swim3_readbit(fs, DISK_IN) == 0)
+			break;
 	}
+	swim3_select(fs, RELAX);
+	udelay(150);
 	fs->ejected = 1;
 	release_drive(fs);
 	return err;
@@ -865,29 +892,31 @@
 	if (fs->ref_count == 0) {
 		if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
 			return -ENXIO;
-		out_8(&sw->mode, 0x95);
-		out_8(&sw->control_bic, 0xff);
 		out_8(&sw->setup, S_IBM_DRIVE | S_FCLK_DIV2);
+		out_8(&sw->control_bic, 0xff);
+		out_8(&sw->mode, 0x95);
 		udelay(10);
 		out_8(&sw->intr_enable, 0);
 		out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE);
 		swim3_action(fs, MOTOR_ON);
 		fs->write_prot = -1;
 		fs->cur_cyl = -1;
-		for (n = HZ; n > 0; --n) {
-			if (swim3_readbit(fs, SEEK_COMPLETE))
+		for (n = 0; n < 2 * HZ; ++n) {
+			if (n >= HZ/30 && swim3_readbit(fs, SEEK_COMPLETE))
 				break;
 			if (signal_pending(current)) {
 				err = -EINTR;
 				break;
 			}
+			swim3_select(fs, RELAX);
 			current->state = TASK_INTERRUPTIBLE;
 			schedule_timeout(1);
 		}
 		if (err == 0 && (swim3_readbit(fs, SEEK_COMPLETE) == 0
 				 || swim3_readbit(fs, DISK_IN) == 0))
 			err = -ENXIO;
-		swim3_action(fs, 9);
+		swim3_action(fs, SETMFM);
+		swim3_select(fs, RELAX);
 
 	} else if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
 		return -EBUSY;
@@ -910,6 +939,7 @@
 		if (fs->ref_count == 0) {
 			swim3_action(fs, MOTOR_OFF);
 			out_8(&sw->control_bic, DRIVE_ENABLE | INTR_ENABLE);
+			swim3_select(fs, RELAX);
 		}
 		return err;
 	}
@@ -936,6 +966,7 @@
 	if (fs->ref_count > 0 && --fs->ref_count == 0) {
 		swim3_action(fs, MOTOR_OFF);
 		out_8(&sw->control_bic, 0xff);
+		swim3_select(fs, RELAX);
 	}
 	return 0;
 }
@@ -970,15 +1001,17 @@
 	sw = fs->swim3;
 	grab_drive(fs, revalidating, 0);
 	out_8(&sw->intr_enable, 0);
-	out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE);
-	swim3_action(fs, MOTOR_ON);
+	out_8(&sw->control_bis, DRIVE_ENABLE);
+	swim3_action(fs, MOTOR_ON);	/* necessary? */
 	fs->write_prot = -1;
 	fs->cur_cyl = -1;
+	mdelay(1);
 	for (n = HZ; n > 0; --n) {
 		if (swim3_readbit(fs, SEEK_COMPLETE))
 			break;
 		if (signal_pending(current))
 			break;
+		swim3_select(fs, RELAX);
 		current->state = TASK_INTERRUPTIBLE;
 		schedule_timeout(1);
 	}
@@ -988,8 +1021,9 @@
 		swim3_action(fs, MOTOR_OFF);
 	else {
 		fs->ejected = 0;
-		swim3_action(fs, 9);
+		swim3_action(fs, SETMFM);
 	}
+	swim3_select(fs, RELAX);
 
 	release_drive(fs);
 	return ret;
diff -urN linux-2.4.22-pre2/drivers/char/Config.in linux-2.4.22-pre3/drivers/char/Config.in
--- linux-2.4.22-pre2/drivers/char/Config.in	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/drivers/char/Config.in	2003-07-05 18:09:56.000000000 -0700
@@ -161,6 +161,9 @@
 if [ "$CONFIG_PPC64" ] ; then 
    bool 'pSeries Hypervisor Virtual Console support' CONFIG_HVC_CONSOLE
 fi
+if [ "$CONFIG_ALL_PPC" = "y" ]; then
+   tristate 'Total Impact briQ front panel driver' CONFIG_BRIQ_PANEL
+fi
 
 source drivers/i2c/Config.in
 
diff -urN linux-2.4.22-pre2/drivers/char/Makefile linux-2.4.22-pre3/drivers/char/Makefile
--- linux-2.4.22-pre2/drivers/char/Makefile	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-pre3/drivers/char/Makefile	2003-07-05 18:09:56.000000000 -0700
@@ -248,6 +248,7 @@
 obj-$(CONFIG_INTEL_RNG) += i810_rng.o
 obj-$(CONFIG_AMD_RNG) += amd768_rng.o
 obj-$(CONFIG_AMD_PM768) += amd76x_pm.o
+obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
 
 obj-$(CONFIG_ITE_GPIO) += ite_gpio.o
 obj-$(CONFIG_AU1000_GPIO) += au1000_gpio.o
diff -urN linux-2.4.22-pre2/drivers/char/briq_panel.c linux-2.4.22-pre3/drivers/char/briq_panel.c
--- linux-2.4.22-pre2/drivers/char/briq_panel.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/drivers/char/briq_panel.c	2003-07-05 18:09:56.000000000 -0700
@@ -0,0 +1,251 @@
+/*
+ * Drivers for the Total Impact PPC based computer "BRIQ"
+ * by Dr. Karsten Jeppesen
+ *
+ *
+ * 010407		Coding started
+ * 
+ * 04/20/2002	1.1	Adapted to 2.4, small cleanups
+ */
+
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/timer.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#define		TOTALIMPACT_VFD_MINOR	156
+#define		VFD_IOPORT		0x0390
+#define		LED_IOPORT		0x0398
+#define		TI_VER                  "1.1 (04/20/2002)"
+#define		TI_MSG0			"Loading Linux"
+
+static int		vfd_is_open;
+static unsigned char	vfd[40];
+static int		vfd_cursor;
+static unsigned char	ledpb, led;
+
+
+static void UpdateVFD( void )
+{
+	int	i;
+	outb(0x02, VFD_IOPORT);	/* cursor home */
+	for (i=0; i<20; i++) outb(vfd[i], VFD_IOPORT + 1);
+	outb(0xc0, VFD_IOPORT); /* cursor to next line */
+	for (i=20; i<40; i++) outb(vfd[i], VFD_IOPORT + 1);
+
+}
+
+static void SetLED( char state)
+{
+	if ( state == 'R' ) led = 0x01;
+	else if ( state == 'G' ) led = 0x02;
+	else if ( state == 'Y' ) led = 0x03;
+	else if ( state == 'X' ) led = 0x00;
+	outb(led, LED_IOPORT);
+}
+
+static int do_open(struct inode *ino, struct file *filep)
+{
+	if (vfd_is_open) return -EBUSY;
+	MOD_INC_USE_COUNT;
+	vfd_is_open = 1;
+	return(0);
+}
+
+static int do_release(struct inode *ino, struct file *filep)
+{
+	if (!vfd_is_open) return -ENODEV;
+	MOD_DEC_USE_COUNT;
+	vfd_is_open = 0;
+	return(0);
+}
+
+
+static ssize_t do_read(struct file *file, char *buf, size_t count,
+			 loff_t *ppos)
+{
+	unsigned short c;
+	unsigned char cp;
+
+	/*  Can't seek (pread) on this device  */
+	if (ppos != &file->f_pos) return -ESPIPE;
+	if (!vfd_is_open) return -ENODEV;
+	c = (inb( LED_IOPORT ) & 0x000c) | (ledpb & 0x0003);
+	SetLED(' ');
+	if ((!(ledpb & 0x0004)) && (c & 0x0004))
+	{	/* upper button released */
+		cp = ' ';
+		ledpb = c;
+		if (copy_to_user(buf, &cp, 1)) return -EFAULT;
+		return(1);
+	}
+	else if ((!(ledpb & 0x0008)) && (c & 0x0008))
+	{	/* lower button released */
+		cp = '\r';
+		ledpb = c;
+		if (copy_to_user(buf, &cp, 1)) return -EFAULT;
+		return(1);
+	} else
+	{
+		ledpb = c;
+		return(0);
+	}
+}
+
+
+static void ScrollVFD( void )
+{
+	int	i;
+	for (i=0; i<20; i++)
+	{
+		vfd[i] = vfd[i+20];
+		vfd[i+20] = ' ';
+	}
+	vfd_cursor = 20;
+}
+
+
+static ssize_t do_write(struct file *file, const char *buf, size_t len,
+			  loff_t *ppos)
+{
+	size_t		indx = len;
+	int		i, esc=0;
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos) return -ESPIPE;
+	if (!vfd_is_open) return -EBUSY;
+	for (;;)
+	{
+		if (!indx) break;
+		if (esc)
+		{
+			SetLED(*buf);
+			esc = 0;
+		}
+		else if (*buf == 27)
+		{
+			esc = 1;
+		}
+		else if (*buf == 12)
+		{ /* do a form feed */
+			for (i=0; i<40; i++) vfd[i] = ' ';
+			vfd_cursor = 0;
+		}
+		else if (*buf == 10)
+		{
+			if (vfd_cursor < 20) vfd_cursor = 20;
+			else if (vfd_cursor < 40) vfd_cursor = 40;
+			else if (vfd_cursor < 60) vfd_cursor = 60;
+			if (vfd_cursor > 59) ScrollVFD();
+		}
+		else
+		{
+			/* just a character */
+			if (vfd_cursor > 39) ScrollVFD();
+			vfd[vfd_cursor++] = *buf;
+		}
+		indx--;
+		buf++;
+	}
+	UpdateVFD();
+	return len;
+}
+
+
+static struct file_operations vfd_fops = {
+	read:		do_read,	/* Read */
+	write:		do_write,	/* Write */
+	open:		do_open,	/* Open */
+	release:	do_release,	/* Release */
+};
+
+
+static struct miscdevice ti_vfd_miscdev = {
+	TOTALIMPACT_VFD_MINOR,
+	"vfd",
+	&vfd_fops
+};
+
+
+static int __init briq_panel_init(void)
+{
+	struct device_node *root = find_path_device("/");
+	char *machine;
+	int i;
+
+	machine = get_property(root, "model", NULL);
+	if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0)
+		return -ENODEV;
+
+	printk(KERN_INFO "ti_briq: v%s Dr. Karsten Jeppesen (kj@totalimpact.com)\n", TI_VER);
+
+	if (!request_region( VFD_IOPORT, 4, "BRIQ Front Panel"))
+		return -EBUSY;
+	if (!request_region( LED_IOPORT, 2, "BRIQ Front Panel")) {
+		release_region(VFD_IOPORT, 4);
+		return -EBUSY;
+	}
+	ledpb = inb( LED_IOPORT ) & 0x000c;
+
+	if (misc_register(&ti_vfd_miscdev) < 0) {
+		release_region(VFD_IOPORT, 4);
+		release_region(LED_IOPORT, 2);
+		return -EBUSY;
+	}
+
+	outb(0x38, VFD_IOPORT);	/* Function set */
+	outb(0x01, VFD_IOPORT);	/* Clear display */
+	outb(0x0c, VFD_IOPORT);	/* Display on */
+	outb(0x06, VFD_IOPORT);	/* Entry normal */
+	for (i=0; i<40; i++) vfd[i]=' ';
+#ifndef MODULE
+	vfd[0] = 'L';
+	vfd[1] = 'o';
+	vfd[2] = 'a';
+	vfd[3] = 'd';
+	vfd[4] = 'i';
+	vfd[5] = 'n';
+	vfd[6] = 'g';
+	vfd[7] = ' ';
+	vfd[8] = '.';
+	vfd[9] = '.';
+	vfd[10] = '.';
+#endif /* !MODULE */	
+	UpdateVFD();
+
+	return 0;
+}
+
+
+static void __exit briq_panel_exit(void)
+{
+	misc_deregister(&ti_vfd_miscdev);
+	release_region(VFD_IOPORT, 4);
+	release_region(LED_IOPORT, 2);
+}
+
+
+module_init(briq_panel_init);
+module_exit(briq_panel_exit);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Karsten Jeppesen <karsten@jeppesens.com>");
+MODULE_DESCRIPTION("Driver for the Total Impact briQ front panel");
+EXPORT_NO_SYMBOLS;
diff -urN linux-2.4.22-pre2/drivers/char/rocket_int.h linux-2.4.22-pre3/drivers/char/rocket_int.h
--- linux-2.4.22-pre2/drivers/char/rocket_int.h	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/char/rocket_int.h	2003-07-05 18:09:57.000000000 -0700
@@ -7,6 +7,8 @@
  * 
  * Copyright 1994 Comtrol Corporation.    All Rights Reserved.
  * 
+ * Erroneously clashing license removed. This file is GPL
+ * (Kurt Robideau, Comtrol Corp, 20030610)
  * This driver is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
@@ -16,7 +18,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
  */
 
 /*
diff -urN linux-2.4.22-pre2/drivers/char/sh-sci.c linux-2.4.22-pre3/drivers/char/sh-sci.c
--- linux-2.4.22-pre2/drivers/char/sh-sci.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/drivers/char/sh-sci.c	2003-07-05 18:09:57.000000000 -0700
@@ -280,7 +280,7 @@
 	if (cflag & CRTSCTS) {
 		fcr_val |= SCFCR_MCE;
 	} else {
-		ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */
+		sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */
 	}
 	sci_out(port, SCFCR, fcr_val);
 }
@@ -811,7 +811,7 @@
 static int sci_open(struct tty_struct * tty, struct file * filp)
 {
 	struct sci_port *port;
-	int retval, line;
+	int retval = 0, line;
 
 	line = MINOR(tty->device) - SCI_MINOR_START;
 
@@ -820,6 +820,14 @@
 
 	port = &sci_ports[line];
 
+#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
+	if (port->base == 0) {
+		port->base = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
+		if (!port->base)
+			goto failed_1;
+	}
+#endif
+
 	tty->driver_data = port;
 	port->gs.tty = tty;
 	port->gs.count++;
@@ -1202,6 +1210,12 @@
 
 	sercons_port = &sci_ports[co->index];
 
+#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
+	sercons_port->base = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
+	if (!sercons_port->base)
+		return -EINVAL;
+#endif
+
 	if (options) {
 		baud = simple_strtoul(options, NULL, 10);
 		s = options;
diff -urN linux-2.4.22-pre2/drivers/char/sh-sci.h linux-2.4.22-pre3/drivers/char/sh-sci.h
--- linux-2.4.22-pre2/drivers/char/sh-sci.h	2001-06-27 13:55:29.000000000 -0700
+++ linux-2.4.22-pre3/drivers/char/sh-sci.h	2003-07-05 18:09:57.000000000 -0700
@@ -26,6 +26,7 @@
 #define SH3_IRDA_IRQS { 52,  53,  55,  54 }
 #define SH4_SCIF_IRQS { 40,  41,  43,  42 }
 #define STB1_SCIF1_IRQS {23, 24,  26,  25 }
+#define SH5_SCIF_IRQS  { 39,  40,  42 }
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7708)
 # define SCI_NPORTS 1
@@ -70,6 +71,25 @@
 # define SCIF_ORER 0x0001   /* overrun error bit */
 # define SCSCR_INIT(port)          0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
 # define SCIF_ONLY
+
+#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
+# include <asm/hardware.h>
+# define SCIF_BASE_ADDR    0x01030000 
+# define SCIF_ADDR_SH5     PHYS_PERIPHERAL_BLOCK+SCIF_BASE_ADDR
+# define SCIF_PTR2_OFFS    0x0000020
+# define SCIF_LSR2_OFFS    0x0000024
+# define SCI_NPORTS 1
+# define SCI_INIT { \
+  { {}, PORT_SCIF, 0, \
+     SH5_SCIF_IRQS, sci_init_pins_scif }  \
+}
+# define SCSPTR2           (SCIF_ADDR_SH5+SCIF_PTR2_OFFS) /* 16 bit SCIF */
+# define SCLSR2            (SCIF_ADDR_SH5+SCIF_LSR2_OFFS) /* 16 bit SCIF */
+# define SCSCR_INIT(port)  0x38                           /* TIE=0,RIE=0,
+							     TE=1,RE=1,REIE=1 */
+# define SCIF_ONLY
+
+
 #else
 # error CPU subtype not defined
 #endif
@@ -271,7 +291,8 @@
 SCIx_FNS(SCxRDR, 0x0a,  8, 0x14,  8, 0x0A,  8, 0x14,  8)
 SCIF_FNS(SCFCR,                      0x0c,  8, 0x18, 16)
 SCIF_FNS(SCFDR,                      0x0e, 16, 0x1C, 16)
-SCIF_FNS(SCLSR,                         0,  0, 0x24, 16)
+SCIF_FNS(SCSPTR,                     und, und, 0x20, 16)
+SCIF_FNS(SCLSR,                      und, und, 0x24, 16)
 
 #define sci_in(port, reg) sci_##reg##_in(port)
 #define sci_out(port, reg, value) sci_##reg##_out(port, value)
@@ -316,6 +337,12 @@
 		return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
 
 }
+#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
+static inline int sci_rxd_in(struct sci_port *port)
+{
+         return sci_in(port, SCSPTR)&0x0001 ? 1 : 0; /* SCIF */
+}
+
 #endif
 
 /*
diff -urN linux-2.4.22-pre2/drivers/char/sonypi.c linux-2.4.22-pre3/drivers/char/sonypi.c
--- linux-2.4.22-pre2/drivers/char/sonypi.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/char/sonypi.c	2003-07-05 18:09:57.000000000 -0700
@@ -120,9 +120,9 @@
 
 static int ec_read16(u8 addr, u16 *value) {
 	u8 val_lb, val_hb;
-	if (ec_read(addr, &val_lb))
+	if (sonypi_ec_read(addr, &val_lb))
 		return -1;
-	if (ec_read(addr + 1, &val_hb))
+	if (sonypi_ec_read(addr + 1, &val_hb))
 		return -1;
 	*value = val_lb | (val_hb << 8);
 	return 0;
@@ -152,11 +152,11 @@
 }
 
 static void __devinit sonypi_type2_srs(void) {
-	if (ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8))
+	if (sonypi_ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8))
 		printk(KERN_WARNING "ec_write failed\n");
-	if (ec_write(SONYPI_SLOB,  sonypi_device.ioport1 & 0x00FF))
+	if (sonypi_ec_write(SONYPI_SLOB,  sonypi_device.ioport1 & 0x00FF))
 		printk(KERN_WARNING "ec_write failed\n");
-	if (ec_write(SONYPI_SIRQ,  sonypi_device.bits))
+	if (sonypi_ec_write(SONYPI_SIRQ,  sonypi_device.bits))
 		printk(KERN_WARNING "ec_write failed\n");
 	udelay(10);
 }
@@ -175,11 +175,11 @@
 }
 
 static void sonypi_type2_dis(void) {
-	if (ec_write(SONYPI_SHIB, 0))
+	if (sonypi_ec_write(SONYPI_SHIB, 0))
 		printk(KERN_WARNING "ec_write failed\n");
-	if (ec_write(SONYPI_SLOB, 0))
+	if (sonypi_ec_write(SONYPI_SLOB, 0))
 		printk(KERN_WARNING "ec_write failed\n");
-	if (ec_write(SONYPI_SIRQ, 0))
+	if (sonypi_ec_write(SONYPI_SIRQ, 0))
 		printk(KERN_WARNING "ec_write failed\n");
 }
 
@@ -265,7 +265,7 @@
 
 	for (j = 5; j > 0; j--) {
 
-		while (sonypi_call2(0x91, 0x1) != 0) {
+		while (sonypi_call2(0x91, 0x1)) {
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			schedule_timeout(1);
 		}
@@ -277,7 +277,7 @@
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			schedule_timeout(1);
 		}
-		if (i != 0)
+		if (i)
 			break;
 	}
 	
@@ -293,14 +293,12 @@
 /* sets the bluetooth subsystem power state */
 static void sonypi_setbluetoothpower(u8 state) {
 
-	state = (state != 0);
-	if (sonypi_device.bluetooth_power && state) 
-		return;
-	if (!sonypi_device.bluetooth_power && !state) 
+	state = !!state;
+	if (sonypi_device.bluetooth_power == state) 
 		return;
 	
 	sonypi_call2(0x96, state);
-	sonypi_call1(0x93);
+	sonypi_call1(0x82);
 	sonypi_device.bluetooth_power = state;
 }
 
@@ -312,10 +310,6 @@
 	v1 = inb_p(sonypi_device.ioport1);
 	v2 = inb_p(sonypi_device.ioport2);
 
-	if (verbose > 1)
-		printk(KERN_INFO 
-		       "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2);
-
 	for (i = 0; sonypi_eventtypes[i].model; i++) {
 		if (sonypi_device.model != sonypi_eventtypes[i].model)
 			continue;
@@ -337,7 +331,11 @@
 	return;
 
 found:
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+	if (verbose > 1)
+		printk(KERN_INFO 
+		       "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2);
+
+#ifdef SONYPI_USE_INPUT
 	if (useinput) {
 		struct input_dev *jog_dev = &sonypi_device.jog_dev;
 		if (event == SONYPI_EVENT_JOGDIAL_PRESSED)
@@ -351,7 +349,7 @@
 			 (event == SONYPI_EVENT_JOGDIAL_DOWN_PRESSED))
 			input_report_rel(jog_dev, REL_WHEEL, -1);
 	}
-#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */
+#endif /* SONYPI_USE_INPUT */
 	sonypi_pushq(event);
 }
 
@@ -507,7 +505,7 @@
 	down(&sonypi_device.lock);
 	switch (cmd) {
 	case SONYPI_IOCGBRT:
-		if (ec_read(SONYPI_LCD_LIGHT, &val8)) {
+		if (sonypi_ec_read(SONYPI_LCD_LIGHT, &val8)) {
 			ret = -EIO;
 			break;
 		}
@@ -519,7 +517,7 @@
 			ret = -EFAULT;
 			break;
 		}
-		if (ec_write(SONYPI_LCD_LIGHT, val8))
+		if (sonypi_ec_write(SONYPI_LCD_LIGHT, val8))
 			ret = -EIO;
 		break;
 	case SONYPI_IOCGBAT1CAP:
@@ -555,7 +553,7 @@
 			ret = -EFAULT;
 		break;
 	case SONYPI_IOCGBATFLAGS:
-		if (ec_read(SONYPI_BAT_FLAGS, &val8)) {
+		if (sonypi_ec_read(SONYPI_BAT_FLAGS, &val8)) {
 			ret = -EIO;
 			break;
 		}
@@ -611,18 +609,14 @@
 			sonypi_type2_dis();
 		else
 			sonypi_type1_dis();
-#ifndef CONFIG_ACPI
 		/* disable ACPI mode */
-		if (fnkeyinit)
+		if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
 			outb(0xf1, 0xb2);
-#endif
 		break;
 	case PM_RESUME:
-#ifndef CONFIG_ACPI
 		/* Enable ACPI mode to get Fn key events */
-		if (fnkeyinit)
+		if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
 			outb(0xf0, 0xb2);
-#endif
 		if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
 			sonypi_type2_srs();
 		else
@@ -696,36 +690,44 @@
 	}
 
 	for (i = 0; irq_list[i].irq; i++) {
-		if (!request_irq(irq_list[i].irq, sonypi_irq, 
-				 SA_SHIRQ, "sonypi", sonypi_irq)) {
-			sonypi_device.irq = irq_list[i].irq;
-			sonypi_device.bits = irq_list[i].bits;
+
+		sonypi_device.irq = irq_list[i].irq;
+		sonypi_device.bits = irq_list[i].bits;
+
+		/* Enable sonypi IRQ settings */
+		if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
+			sonypi_type2_srs();
+		else
+			sonypi_type1_srs();
+
+		sonypi_call1(0x82);
+		sonypi_call2(0x81, 0xff);
+		if (compat)
+			sonypi_call1(0x92); 
+		else
+			sonypi_call1(0x82);
+
+		/* Now try requesting the irq from the system */
+		if (!request_irq(sonypi_device.irq, sonypi_irq, 
+				 SA_SHIRQ, "sonypi", sonypi_irq))
 			break;
-		}
+
+		/* If request_irq failed, disable sonypi IRQ settings */
+		if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
+			sonypi_type2_dis();
+		else
+			sonypi_type1_dis();
 	}
-	if (!sonypi_device.irq ) {
+
+	if (!irq_list[i].irq) {
 		printk(KERN_ERR "sonypi: request_irq failed\n");
 		ret = -ENODEV;
 		goto out3;
 	}
 
-#ifndef CONFIG_ACPI
 	/* Enable ACPI mode to get Fn key events */
-	if (fnkeyinit)
+	if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
 		outb(0xf0, 0xb2);
-#endif
-
-	if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
-		sonypi_type2_srs();
-	else
-		sonypi_type1_srs();
-
-	sonypi_call1(0x82);
-	sonypi_call2(0x81, 0xff);
-	if (compat)
-		sonypi_call1(0x92); 
-	else
-		sonypi_call1(0x82);
 
 	printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver v%d.%d.\n",
 	       SONYPI_DRIVER_MAJORVERSION,
@@ -748,7 +750,7 @@
 		printk(KERN_INFO "sonypi: device allocated minor is %d\n",
 		       sonypi_misc_device.minor);
 
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#ifdef SONYPI_USE_INPUT
 	if (useinput) {
 		/* Initialize the Input Drivers: */
 		sonypi_device.jog_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
@@ -765,7 +767,7 @@
 			sonypi_device.jog_dev.name,
 			sonypi_device.jog_dev.number);
 	}
-#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */
+#endif /* SONYPI_USE_INPUT */
 
 #ifdef CONFIG_PM
 	sonypi_device.pm = pm_register(PM_PCI_DEV, 0, sonypi_pm_callback);
@@ -789,12 +791,12 @@
 
 	sonypi_call2(0x81, 0); /* make sure we don't get any more events */
 	
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#ifdef SONYPI_USE_INPUT
 	if (useinput) {
 		input_unregister_device(&sonypi_device.jog_dev);
 		kfree(sonypi_device.jog_dev.name);
 	}
-#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */
+#endif /* SONYPI_USE_INPUT */
 
 	if (camera)
 		sonypi_camera_off();
@@ -802,11 +804,9 @@
 		sonypi_type2_dis();
 	else
 		sonypi_type1_dis();
-#ifndef CONFIG_ACPI
 	/* disable ACPI mode */
-	if (fnkeyinit)
+	if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
 		outb(0xf1, 0xb2);
-#endif
 	free_irq(sonypi_device.irq, sonypi_irq);
 	release_region(sonypi_device.ioport1, sonypi_device.region_size);
 	misc_deregister(&sonypi_misc_device);
diff -urN linux-2.4.22-pre2/drivers/char/sonypi.h linux-2.4.22-pre3/drivers/char/sonypi.h
--- linux-2.4.22-pre2/drivers/char/sonypi.h	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/char/sonypi.h	2003-07-05 18:09:57.000000000 -0700
@@ -37,7 +37,7 @@
 #ifdef __KERNEL__
 
 #define SONYPI_DRIVER_MAJORVERSION	 1
-#define SONYPI_DRIVER_MINORVERSION	18
+#define SONYPI_DRIVER_MINORVERSION	20
 
 #define SONYPI_DEVICE_MODEL_TYPE1	1
 #define SONYPI_DEVICE_MODEL_TYPE2	2
@@ -335,6 +335,15 @@
 	unsigned char buf[SONYPI_BUF_SIZE];
 };
 
+/* We enable input subsystem event forwarding if the input 
+ * subsystem is compiled in, but only if sonypi is not into the
+ * kernel and input as a module... */
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#if ! (defined(CONFIG_SONYPI) && defined(CONFIG_INPUT_MODULE))
+#define SONYPI_USE_INPUT
+#endif
+#endif
+
 /* The name of the Jog Dial for the input device drivers */
 #define SONYPI_INPUTNAME	"Sony VAIO Jog Dial"
 
@@ -351,7 +360,7 @@
 	struct sonypi_queue queue;
 	int open_count;
 	int model;
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#ifdef SONYPI_USE_INPUT
 	struct input_dev jog_dev;
 #endif
 #ifdef CONFIG_PM
@@ -373,14 +382,30 @@
 #ifdef CONFIG_ACPI
 #include <linux/acpi.h>
 #if (ACPI_CA_VERSION > 0x20021121)
-#define USE_ACPI
+#ifdef CONFIG_ACPI_EC
+#define SONYPI_USE_ACPI
+#endif
 #endif
 #endif /* CONFIG_ACPI */
 
-#ifndef USE_ACPI
+#ifdef CONFIG_ACPI
+#ifdef SONYPI_USE_ACPI
+extern int acpi_disabled;
+#define SONYPI_ACPI_ACTIVE (!acpi_disabled)
+#else
+#define SONYPI_ACPI_ACTIVE 1
+#endif
+#else /* CONFIG_ACPI */
+#define SONYPI_ACPI_ACTIVE 0
+#endif /* CONFIG_ACPI */
+
 extern int verbose;
 
-static inline int ec_write(u8 addr, u8 value) {
+static inline int sonypi_ec_write(u8 addr, u8 value) {
+#ifdef SONYPI_USE_ACPI
+	if (!acpi_disabled)
+		return ec_write(addr, value);
+#endif
 	wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
 	outb_p(0x81, SONYPI_CST_IOPORT);
 	wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
@@ -391,7 +416,11 @@
 	return 0;
 }
 
-static inline int ec_read(u8 addr, u8 *value) {
+static inline int sonypi_ec_read(u8 addr, u8 *value) {
+#ifdef SONYPI_USE_ACPI
+	if (!acpi_disabled)
+		return ec_read(addr, value);
+#endif
 	wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
 	outb_p(0x80, SONYPI_CST_IOPORT);
 	wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
@@ -400,7 +429,6 @@
 	*value = inb_p(SONYPI_DATA_IOPORT);
 	return 0;
 }
-#endif /* ! USE_ACPI */
 
 #endif /* __KERNEL__ */
 
diff -urN linux-2.4.22-pre2/drivers/char/sysrq.c linux-2.4.22-pre3/drivers/char/sysrq.c
--- linux-2.4.22-pre2/drivers/char/sysrq.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.22-pre3/drivers/char/sysrq.c	2003-07-05 18:09:57.000000000 -0700
@@ -372,9 +372,9 @@
 /* key2index calculation, -1 on invalid index */
 static __inline__ int sysrq_key_table_key2index(int key) {
 	int retval;
-	if ((key >= '0') & (key <= '9')) {
+	if ((key >= '0') && (key <= '9')) {
 		retval = key - '0';
-	} else if ((key >= 'a') & (key <= 'z')) {
+	} else if ((key >= 'a') && (key <= 'z')) {
 		retval = key + 10 - 'a';
 	} else {
 		retval = -1;
diff -urN linux-2.4.22-pre2/drivers/gsc/dino.c linux-2.4.22-pre3/drivers/gsc/dino.c
--- linux-2.4.22-pre2/drivers/gsc/dino.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/gsc/dino.c	2003-07-05 18:09:57.000000000 -0700
@@ -251,7 +251,7 @@
 	unsigned long flags; \
 	spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
 	/* tell HW which IO Port address */ \
-	gsc_writel((u32) addr & ~3, d->base_addr + DINO_PCI_ADDR); \
+	gsc_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
 	/* generate I/O PORT read cycle */ \
 	v = gsc_read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \
 	spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
@@ -267,7 +267,7 @@
 { \
 	unsigned long flags; \
 	spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
-	/* tell HW which CFG address */ \
+	/* tell HW which IO port address */ \
 	gsc_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
 	/* generate cfg write cycle */ \
 	gsc_write##type(cpu_to_le##size(val), d->base_addr+DINO_IO_DATA+(addr&mask)); \
@@ -467,7 +467,7 @@
  * to set up the addresses of the devices on this bus.
  */
 #define _8MB 0x00800000UL
-static void __init
+static int __init
 dino_card_setup(struct pci_bus *bus, unsigned long base_addr)
 {
 	int i;
@@ -482,7 +482,7 @@
 				0xffffffffffffffffUL &~ _8MB, _8MB,
 				NULL, NULL) < 0) {
 		printk(KERN_WARNING "Dino: Failed to allocate memory region\n");
-		return;
+		return -ENODEV;
 	}
 	bus->resource[1] = res;
 	bus->resource[0] = &(dino_dev->hba.io_space);
@@ -495,6 +495,7 @@
 	gsc_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
 
 	pcibios_assign_unassigned_resources(bus);
+	return 0;
 }
 
 static void __init
diff -urN linux-2.4.22-pre2/drivers/ide/Config.in linux-2.4.22-pre3/drivers/ide/Config.in
--- linux-2.4.22-pre2/drivers/ide/Config.in	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/Config.in	2003-07-05 18:09:57.000000000 -0700
@@ -47,7 +47,7 @@
 	    dep_tristate '    AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_tristate '    ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3 $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_mbool    '      ALI M15x3 WDC support (DANGEROUS)' CONFIG_WDC_ALI15X3 $CONFIG_BLK_DEV_ALI15X3
-	    dep_tristate '    AMD Viper support' CONFIG_BLK_DEV_AMD74XX $CONFIG_BLK_DEV_IDEDMA_PCI
+	    dep_tristate '    AMD and nVidia IDE support' CONFIG_BLK_DEV_AMD74XX $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_mbool    '      AMD Viper ATA-66 Override' CONFIG_AMD74XX_OVERRIDE $CONFIG_BLK_DEV_AMD74XX
 	    dep_tristate '    CMD64{3|6|8|9} chipset support' CONFIG_BLK_DEV_CMD64X $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_tristate '    Compaq Triflex IDE support' CONFIG_BLK_DEV_TRIFLEX $CONFIG_BLK_DEV_IDEDMA_PCI
@@ -63,7 +63,7 @@
 	    dep_tristate '    NS87415 chipset support' CONFIG_BLK_DEV_NS87415 $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_tristate '    OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 $CONFIG_EXPERIMENTAL
 	    dep_tristate '    PROMISE PDC202{46|62|65|67} support' CONFIG_BLK_DEV_PDC202XX_OLD $CONFIG_BLK_DEV_IDEDMA_PCI
-	    dep_mbool    '      Special UDMA Feature' CONFIG_PDC202XX_BURST $CONFIG_BLK_DEV_PDC202XX_OLD $CONFIG_BLK_DEV_IDEDMA_PCI
+	    dep_mbool     '      Special UDMA Feature' CONFIG_PDC202XX_BURST $CONFIG_BLK_DEV_PDC202XX_OLD $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_tristate '    PROMISE PDC202{68|69|70|71|75|76|77} support' CONFIG_BLK_DEV_PDC202XX_NEW $CONFIG_BLK_DEV_IDEDMA_PCI
 	    if [ "$CONFIG_BLK_DEV_PDC202XX_OLD" = "y" -o "$CONFIG_BLK_DEV_PDC202XX_OLD" = "m" -o "$CONFIG_BLK_DEV_PDC202XX_NEW" = "y" -o "$CONFIG_BLK_DEV_PDC202XX_NEW" = "m" ]; then
 	        bool     '    Special FastTrak Feature' CONFIG_PDC202XX_FORCE
diff -urN linux-2.4.22-pre2/drivers/ide/Makefile linux-2.4.22-pre3/drivers/ide/Makefile
--- linux-2.4.22-pre2/drivers/ide/Makefile	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/Makefile	2003-07-05 18:09:57.000000000 -0700
@@ -8,7 +8,6 @@
 # In the future, some of these should be built conditionally.
 #
 
-O_TARGET := idedriver.o
 
 export-objs := ide-iops.o ide-taskfile.o ide-proc.o ide.o ide-probe.o ide-dma.o ide-lib.o setup-pci.o ide-io.o ide-disk.o
 
@@ -29,24 +28,25 @@
 
 # Core IDE code - must come before legacy
 
-obj-$(CONFIG_BLK_DEV_IDE)		+= ide-probe.o ide-geometry.o ide-iops.o ide-taskfile.o ide.o ide-lib.o ide-io.o ide-default.o
-obj-$(CONFIG_BLK_DEV_IDEDISK)		+= ide-disk.o
-obj-$(CONFIG_BLK_DEV_IDECD)		+= ide-cd.o
-obj-$(CONFIG_BLK_DEV_IDETAPE)		+= ide-tape.o
-obj-$(CONFIG_BLK_DEV_IDEFLOPPY)		+= ide-floppy.o
+ide-core-objs	:= ide-iops.o ide-taskfile.o ide.o ide-lib.o ide-io.o ide-default.o ide-proc.o
+ide-detect-objs	:= ide-probe.o ide-geometry.o
+
 
 ifeq ($(CONFIG_BLK_DEV_IDEPCI),y)
-obj-$(CONFIG_BLK_DEV_IDE)		+= setup-pci.o
+ide-core-objs += setup-pci.o
 endif
 ifeq ($(CONFIG_BLK_DEV_IDEDMA_PCI),y)
-obj-$(CONFIG_BLK_DEV_IDE)		+= ide-dma.o
+ide-core-objs += ide-dma.o
 endif
-obj-$(CONFIG_BLK_DEV_ISAPNP)		+= ide-pnp.o
 
+# Initialisation order:
+#	Core sets up
+#	Legacy drivers may register a callback
+#	Drivers are pre initialised
+#	Probe inits the drivers and driver callbacks
+#	Raid scans the devices
 
-ifeq ($(CONFIG_BLK_DEV_IDE),y)
-obj-$(CONFIG_PROC_FS)			+= ide-proc.o
-endif
+obj-$(CONFIG_BLK_DEV_IDE)		+= ide-core.o
 
 ifeq ($(CONFIG_BLK_DEV_IDE),y)
   obj-y		+= legacy/idedriver-legacy.o
@@ -58,10 +58,28 @@
   endif
 endif
 
+obj-$(CONFIG_BLK_DEV_ISAPNP) 		+= ide-pnp.o
+
+obj-$(CONFIG_BLK_DEV_IDEDISK)		+= ide-disk.o
+obj-$(CONFIG_BLK_DEV_IDECD)		+= ide-cd.o
+obj-$(CONFIG_BLK_DEV_IDETAPE)		+= ide-tape.o
+obj-$(CONFIG_BLK_DEV_IDEFLOPPY)		+= ide-floppy.o
+
+obj-$(CONFIG_BLK_DEV_IDE) += ide-detect.o
 
 ifeq ($(CONFIG_BLK_DEV_IDE),y)
 # RAID must be last of all
   obj-y		+= raid/idedriver-raid.o
 endif
 
+list-multi	:= ide-core.o ide-detect.o
+O_TARGET := idedriver.o
+
 include $(TOPDIR)/Rules.make
+
+ide-core.o:	$(ide-core-objs)
+	$(LD) -r -o $@ $(ide-core-objs)
+
+ide-detect.o:	$(ide-detect-objs)
+	$(LD) -r -o $@ $(ide-detect-objs)
+
diff -urN linux-2.4.22-pre2/drivers/ide/ide-default.c linux-2.4.22-pre3/drivers/ide/ide-default.c
--- linux-2.4.22-pre2/drivers/ide/ide-default.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/ide-default.c	2003-07-05 18:09:57.000000000 -0700
@@ -85,13 +85,10 @@
 	return ret;
 }
 
-MODULE_DESCRIPTION("IDE Default Driver");
-
 int idedefault_init (void)
 {
 	ide_register_module(&idedefault_module);
 	return 0;
 }
 
-module_init(idedefault_init);
 MODULE_LICENSE("GPL");
diff -urN linux-2.4.22-pre2/drivers/ide/ide-dma.c linux-2.4.22-pre3/drivers/ide/ide-dma.c
--- linux-2.4.22-pre2/drivers/ide/ide-dma.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/ide-dma.c	2003-07-05 18:09:57.000000000 -0700
@@ -528,9 +528,10 @@
  *	the driver to resolve the problem, if a DMA transfer is still
  *	in progress we continue to wait (arguably we need to add a 
  *	secondary 'I dont care what the drive thinks' timeout here)
- *	Finally if we have an interrupt but for some reason got the
- *	timeout first we complete the I/O. This can occur if an 
- *	interrupt is lost or due to bugs.
+ *	Finally if we have an interrupt we let it complete the I/O.
+ *	But only one time - we clear expiry and if it's still not
+ *	completed after WAIT_CMD, we error and retry in PIO.
+ *	This can occur if an interrupt is lost or due to hang or bugs.
  */
  
 static int dma_timer_expiry (ide_drive_t *drive)
@@ -544,22 +545,24 @@
 	if ((dma_stat & 0x18) == 0x18)	/* BUSY Stupid Early Timer !! */
 		return WAIT_CMD;
 
-	HWGROUP(drive)->expiry = NULL;	/* one free ride for now */
+	/*
+	 * Clear the expiry handler in case we decide to wait more,
+	 * next time timer expires it is an error 
+	 */
+	HWGROUP(drive)->expiry = NULL;
 
 	/* 1 dmaing, 2 error, 4 intr */
 	
-	if (dma_stat & 2) {	/* ERROR */
-		(void) hwif->ide_dma_end(drive);
-		return DRIVER(drive)->error(drive,
-			"dma_timer_expiry", hwif->INB(IDE_STATUS_REG));
-	}
+	if (dma_stat & 2)	/* ERROR */
+		return -1;
+
 	if (dma_stat & 1)	/* DMAing */
 		return WAIT_CMD;
 
 	if (dma_stat & 4)	/* Got an Interrupt */
-		HWGROUP(drive)->handler(drive);
+		return WAIT_CMD;
 
-	return 0;
+	return 0;	/* Unknown status -- reset the bus */
 }
 
 /**
diff -urN linux-2.4.22-pre2/drivers/ide/ide-io.c linux-2.4.22-pre3/drivers/ide/ide-io.c
--- linux-2.4.22-pre2/drivers/ide/ide-io.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/ide-io.c	2003-07-05 18:09:58.000000000 -0700
@@ -896,15 +896,18 @@
 	ide_do_request(q->queuedata, IDE_NO_IRQ);
 }
 
+EXPORT_SYMBOL(do_ide_request);
+
 /*
  * un-busy the hwgroup etc, and clear any pending DMA status. we want to
  * retry the current request in pio mode instead of risking tossing it
  * all away
  */
-void ide_dma_timeout_retry(ide_drive_t *drive)
+static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	struct request *rq;
+	ide_startstop_t ret = ide_stopped;
 
 	/*
 	 * end current dma transaction
@@ -914,8 +917,16 @@
 	/*
 	 * complain a little, later we might remove some of this verbosity
 	 */
-	printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
-	(void) hwif->ide_dma_timeout(drive);
+
+	if (error < 0) {
+		printk(KERN_ERR "%s: error waiting for DMA\n", drive->name);
+		(void)HWIF(drive)->ide_dma_end(drive);
+		ret = DRIVER(drive)->error(drive, "dma timeout retry",
+				hwif->INB(IDE_STATUS_REG));
+	} else {
+		printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+		(void) hwif->ide_dma_timeout(drive);
+	}
 
 	/*
 	 * disable dma for now, but remember that we did so because of
@@ -938,9 +949,9 @@
 	rq->current_nr_sectors = rq->bh->b_size >> 9;
 	rq->hard_cur_sectors = rq->current_nr_sectors;
 	rq->buffer = rq->bh->b_data;
-}
 
-EXPORT_SYMBOL(ide_dma_timeout_retry);
+	return ret;
+}
 
 /**
  *	ide_timer_expiry	-	handle lack of an IDE interrupt
@@ -962,10 +973,9 @@
 	ide_handler_t	*handler;
 	ide_expiry_t	*expiry;
  	unsigned long	flags;
-	unsigned long	wait;
+	unsigned long	wait = -1;
 
 	spin_lock_irqsave(&io_request_lock, flags);
-	del_timer(&hwgroup->timer);
 
 	if ((handler = hwgroup->handler) == NULL) {
 		/*
@@ -992,7 +1002,7 @@
 			}
 			if ((expiry = hwgroup->expiry) != NULL) {
 				/* continue */
-				if ((wait = expiry(drive)) != 0) {
+				if ((wait = expiry(drive)) > 0) {
 					/* reset timer */
 					hwgroup->timer.expires  = jiffies + wait;
 					add_timer(&hwgroup->timer);
@@ -1028,16 +1038,15 @@
 				startstop = handler(drive);
 			} else {
 				if (drive->waiting_for_dma) {
-					startstop = ide_stopped;
-					ide_dma_timeout_retry(drive);
+					startstop = ide_dma_timeout_retry(drive, wait);
 				} else {
 					startstop = DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG));
 				}
 			}
 			set_recovery_timer(hwif);
 			drive->service_time = jiffies - drive->service_start;
-			enable_irq(hwif->irq);
 			spin_lock_irq(&io_request_lock);
+			enable_irq(hwif->irq);
 			if (startstop == ide_stopped)
 				hwgroup->busy = 0;
 		}
diff -urN linux-2.4.22-pre2/drivers/ide/ide-pnp.c linux-2.4.22-pre3/drivers/ide/ide-pnp.c
--- linux-2.4.22-pre2/drivers/ide/ide-pnp.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/ide-pnp.c	2003-07-05 18:09:58.000000000 -0700
@@ -16,6 +16,7 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
  */
 
+#include <linux/module.h>
 #include <linux/ide.h>
 #include <linux/init.h>
 
@@ -98,7 +99,7 @@
  * Probe for ISA PnP IDE interfaces.
  */
 
-void __init pnpide_init(int enable)
+static void pnpide_init(int enable)
 {
 	struct pci_dev *dev = NULL;
 	struct pnp_dev_t *dev_type;
@@ -155,3 +156,26 @@
 		}
 	}
 }
+
+static void __init pnpide_begin(void)
+{
+	pnpide_init(1);
+}
+
+static int pnpide_init_module(void)
+{
+	ide_register_driver(pnpide_begin);
+	return 0;
+}
+
+static void pnpide_unload(void)
+{
+	pnpide_init(0);
+}
+
+module_init(pnpide_init_module);
+module_exit(pnpide_unload);
+
+MODULE_AUTHOR("Andrey Panin");
+MODULE_DESCRIPTION("Enabler for ISAPNP IDE devices");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.22-pre2/drivers/ide/ide-probe.c linux-2.4.22-pre3/drivers/ide/ide-probe.c
--- linux-2.4.22-pre2/drivers/ide/ide-probe.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/ide-probe.c	2003-07-05 18:09:58.000000000 -0700
@@ -971,6 +971,7 @@
 
 	q->queuedata = HWGROUP(drive);
 	blk_init_queue(q, do_ide_request);
+	blk_queue_throttle_sectors(q, 1);
 }
 
 #undef __IRQ_HELL_SPIN
diff -urN linux-2.4.22-pre2/drivers/ide/ide-proc.c linux-2.4.22-pre3/drivers/ide/ide-proc.c
--- linux-2.4.22-pre2/drivers/ide/ide-proc.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/ide-proc.c	2003-07-05 18:09:58.000000000 -0700
@@ -982,16 +982,11 @@
 void proc_ide_destroy(void)
 {
 #ifdef CONFIG_BLK_DEV_IDEPCI
-	ide_pci_host_proc_t *p = ide_pci_host_proc_list;
-	char name[32];
+	ide_pci_host_proc_t *p;
 
-	while ((p->name != NULL) && (p->set) && (p->get_info != NULL)) {
-		name[0] = '\0';
-		sprintf(name, "ide/%s", p->name);
+	for (p = ide_pci_host_proc_list; p; p = p->next) {
 		if (p->set == 2)
 			remove_proc_entry(p->name, p->parent);
-		if (p->next == NULL) break;
-		p = p->next;
 	}
 #endif /* CONFIG_BLK_DEV_IDEPCI */
 	remove_proc_entry("ide/drivers", proc_ide_root);
diff -urN linux-2.4.22-pre2/drivers/ide/ide.c linux-2.4.22-pre3/drivers/ide/ide.c
--- linux-2.4.22-pre2/drivers/ide/ide.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/ide.c	2003-07-05 18:09:58.000000000 -0700
@@ -1414,6 +1414,8 @@
 #endif		
 }
 
+EXPORT_SYMBOL_GPL(ide_add_generic_settings);
+
 /*
  * Delay for *at least* 50ms.  As we don't know how much time is left
  * until the next tick occurs, we wait an extra tick to be safe.
@@ -2110,8 +2112,8 @@
 #ifdef CONFIG_BLK_DEV_CMD640
 			case -14: /* "cmd640_vlb" */
 			{
-				extern int cmd640_vlb; /* flag for cmd640.c */
-				cmd640_vlb = 1;
+				extern void init_cmd640_vlb (void);
+				init_cmd640_vlb();
 				goto done;
 			}
 #endif /* CONFIG_BLK_DEV_CMD640 */
@@ -2210,6 +2212,37 @@
 }
 
 /*
+ *	Legacy interface registration
+ */
+#define NUM_DRIVER		32
+
+/*
+ *	Yes this is moronically simple, but why not - it works!
+ */
+
+static __initdata ide_driver_call ide_scan[NUM_DRIVER];
+
+void __init ide_register_driver(ide_driver_call scan)
+{
+	static int ide_scans = 0;
+	if(ide_scans == NUM_DRIVER)
+		panic("Too many IDE drivers");
+	ide_scan[ide_scans++]=scan;
+}
+
+EXPORT_SYMBOL(ide_register_driver);
+
+static void __init ide_scan_drivers(void)
+{
+	int i = 0;
+	while(ide_scan[i])
+	{
+		(ide_scan[i])();
+		i++;
+	}
+}
+
+/*
  * probe_for_hwifs() finds/initializes "known" IDE interfaces
  */
 static void __init probe_for_hwifs (void)
@@ -2220,25 +2253,17 @@
 		ide_scan_pcibus(ide_scan_direction);
 	}
 #endif /* CONFIG_BLK_DEV_IDEPCI */
+	ide_scan_drivers();
 
+	/*
+	 *	Unconverted drivers
+	 */	
 #ifdef CONFIG_ETRAX_IDE
 	{
 		extern void init_e100_ide(void);
 		init_e100_ide();
 	}
 #endif /* CONFIG_ETRAX_IDE */
-#ifdef CONFIG_BLK_DEV_CMD640
-	{
-		extern void ide_probe_for_cmd640x(void);
-		ide_probe_for_cmd640x();
-	}
-#endif /* CONFIG_BLK_DEV_CMD640 */
-#ifdef CONFIG_BLK_DEV_PDC4030
-	{
-		extern int ide_probe_for_pdc4030(void);
-		(void) ide_probe_for_pdc4030();
-	}
-#endif /* CONFIG_BLK_DEV_PDC4030 */
 #ifdef CONFIG_BLK_DEV_IDE_PMAC
 	{
 		extern void pmac_ide_probe(void);
@@ -2293,12 +2318,6 @@
 		buddha_init();
 	}
 #endif /* CONFIG_BLK_DEV_BUDDHA */
-#if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP)
-	{
-		extern void pnpide_init(int enable);
-		pnpide_init(1);
-	}
-#endif /* CONFIG_BLK_DEV_ISAPNP */
 }
 
 void __init ide_init_builtin_subdrivers (void)
@@ -2355,6 +2374,10 @@
 void __init ide_init_builtin_drivers (void)
 {
 	/*
+	 * Attach null driver
+	 */
+	idedefault_init();
+	/*
 	 * Probe for special PCI and other "known" interface chipsets
 	 */
 	probe_for_hwifs ();
@@ -2604,9 +2627,6 @@
 		up(&ide_setting_sem);
 		return 1;
 	}
-#if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP) && defined(MODULE)
-	pnpide_init(0);
-#endif /* CONFIG_BLK_DEV_ISAPNP */
 #ifdef CONFIG_PROC_FS
 	ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc);
 	ide_remove_proc_entries(drive->proc, generic_subdriver_entries);
diff -urN linux-2.4.22-pre2/drivers/ide/legacy/pdc4030.c linux-2.4.22-pre3/drivers/ide/legacy/pdc4030.c
--- linux-2.4.22-pre2/drivers/ide/legacy/pdc4030.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/legacy/pdc4030.c	2003-07-05 18:09:58.000000000 -0700
@@ -147,8 +147,6 @@
 	return pdc4030_cmd(drive, PROMISE_IDENTIFY);
 }
 
-int enable_promise_support;
-
 /*
  * setup_pdc4030()
  * Completes the setup of a Promise DC4030 controller card, once found.
@@ -308,11 +306,6 @@
 	unsigned int	index;
 	ide_hwif_t	*hwif;
 
-#ifndef MODULE
-	if (enable_promise_support == 0)
-		return;
-#endif
-
 	for (index = 0; index < MAX_HWIFS; index++) {
 		hwif = &ide_hwifs[index];
 		if (hwif->chipset == ide_unknown && detect_pdc4030(hwif)) {
@@ -362,7 +355,7 @@
 
 void __init init_pdc4030(void)
 {
-	enable_promise_support = 1;
+	ide_register_driver(ide_probe_for_pdc4030);
 }
 
 #else
@@ -373,9 +366,6 @@
 
 int __init pdc4030_mod_init(void)
 {
-	if (enable_promise_support == 0)
-		enable_promise_support = 1;
-
 	if (!ide_probe_for_pdc4030())
 		return -ENODEV;
         return 0;
@@ -387,9 +377,6 @@
 	unsigned int    index;
 	ide_hwif_t      *hwif;
 
-	if (enable_promise_support == 0)
-		return;
- 
 	for (index = 0; index < MAX_HWIFS; index++) {
 		hwif = &ide_hwifs[index];
 		if (hwif->chipset == ide_pdc4030) {
@@ -400,7 +387,6 @@
 				release_pdc4030(hwif, NULL);
                 }
         }
-	enable_promise_support = 0;
 }
 module_exit(pdc4030_mod_exit);
 #endif
diff -urN linux-2.4.22-pre2/drivers/ide/pci/cmd640.c linux-2.4.22-pre3/drivers/ide/pci/cmd640.c
--- linux-2.4.22-pre2/drivers/ide/pci/cmd640.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/pci/cmd640.c	2003-07-05 18:09:58.000000000 -0700
@@ -102,6 +102,7 @@
 #define CMD640_PREFETCH_MASKS 1
 
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
@@ -120,7 +121,8 @@
 /*
  * This flag is set in ide.c by the parameter:  ide0=cmd640_vlb
  */
-int cmd640_vlb = 0;
+
+static int cmd640_vlb = 0;
 
 /*
  * CMD640 specific registers definition.
@@ -716,7 +718,7 @@
 /*
  * Probe for a cmd640 chipset, and initialize it if found.  Called from ide.c
  */
-int __init ide_probe_for_cmd640x (void)
+static void __init ide_probe_for_cmd640x (void)
 {
 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 	int second_port_toggled = 0;
@@ -731,13 +733,13 @@
 	} else {
 		cmd640_vlb = 0;
 		/* Find out what kind of PCI probing is supported otherwise
-		   Justin Gibbs will sulk.. */
+		   we break some Adaptec cards...  */
 		if (pci_conf1() && probe_for_cmd640_pci1())
 			bus_type = "PCI (type1)";
 		else if (pci_conf2() && probe_for_cmd640_pci2())
 			bus_type = "PCI (type2)";
 		else
-			return 0;
+			return;
 	}
 	/*
 	 * Undocumented magic (there is no 0x5b reg in specs)
@@ -745,7 +747,7 @@
 	put_cmd640_reg(0x5b, 0xbd);
 	if (get_cmd640_reg(0x5b) != 0xbd) {
 		printk(KERN_ERR "ide: cmd640 init failed: wrong value in reg 0x5b\n");
-		return 0;
+		return;
 	}
 	put_cmd640_reg(0x5b, 0);
 
@@ -760,7 +762,7 @@
 	cmd640_chip_version = cfr & CFR_DEVREV;
 	if (cmd640_chip_version == 0) {
 		printk ("ide: bad cmd640 revision: %d\n", cmd640_chip_version);
-		return 0;
+		return;
 	}
 
 	/*
@@ -874,6 +876,28 @@
 #ifdef CMD640_DUMP_REGS
 	CMD640_DUMP_REGS;
 #endif
-	return 1;
+	return;
+}
+
+static int __init cmd640_init(void)
+{
+	ide_register_driver(ide_probe_for_cmd640x);
+	return 0;
+}
+
+/*
+ *	Called by the IDE core when compiled in and cmd640=vlb is
+ *	selected.
+ */
+void init_cmd640_vlb(void)
+{
+	cmd640_vlb = 1;
 }
 
+module_init(cmd640_init);
+
+MODULE_AUTHOR("See Source");
+MODULE_DESCRIPTION("IDE support for CMD640 controller");
+MODULE_PARM(cmd640_vlb, "i");
+MODULE_PARM_DESC(cmd640_vlb, "Set to enable scanning for VLB controllers");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.22-pre2/drivers/ide/pci/generic.c linux-2.4.22-pre3/drivers/ide/pci/generic.c
--- linux-2.4.22-pre2/drivers/ide/pci/generic.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/pci/generic.c	2003-07-05 18:09:58.000000000 -0700
@@ -140,6 +140,7 @@
 	{ PCI_VENDOR_ID_HINT,   PCI_DEVICE_ID_HINT_VXPROII_IDE,    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
 	{ PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C561,          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
 	{ PCI_VENDOR_ID_OPTI,   PCI_DEVICE_ID_OPTI_82C558,         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
+	{ PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_PICCOLO,	   PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
 	{ 0, },
 };
 
diff -urN linux-2.4.22-pre2/drivers/ide/pci/generic.h linux-2.4.22-pre3/drivers/ide/pci/generic.h
--- linux-2.4.22-pre2/drivers/ide/pci/generic.h	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/pci/generic.h	2003-07-05 18:09:58.000000000 -0700
@@ -127,6 +127,19 @@
 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
 		.bootable	= ON_BOARD,
 		.extra		= 0,
+	},{	/* 9 */
+		.vendor		= PCI_VENDOR_ID_TOSHIBA,
+		.device		= PCI_DEVICE_ID_TOSHIBA_PICCOLO,
+		.name		= "Piccolo",
+		.init_chipset	= init_chipset_generic,
+		.init_iops	= NULL,
+		.init_hwif	= init_hwif_generic,
+		.init_dma	= init_dma_generic,
+		.channels	= 2,
+		.autodma	= NOAUTODMA,
+		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+		.bootable	= ON_BOARD,
+		.extra		= 0,
 	},{
 		.vendor		= 0,
 		.device		= 0,
diff -urN linux-2.4.22-pre2/drivers/ide/pci/hpt366.c linux-2.4.22-pre3/drivers/ide/pci/hpt366.c
--- linux-2.4.22-pre2/drivers/ide/pci/hpt366.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/pci/hpt366.c	2003-07-05 18:09:59.000000000 -0700
@@ -484,9 +484,12 @@
 {
 	u8 speed = ide_dma_speed(drive, hpt3xx_ratemask(drive));
 
-	if (!(speed))
+	if (!speed)
 		return 0;
 
+	if (pci_get_drvdata(HWIF(drive)->pci_dev) == NULL)
+		return 0;
+		
 	(void) hpt3xx_tune_chipset(drive, speed);
 	return ide_dma_enable(drive);
 }
@@ -919,6 +922,8 @@
 	 * Currently we always set up the PLL for the 372N
 	 */
 	 
+	pci_set_drvdata(dev, NULL);
+	
 	if(is_372n)
 	{
 		printk(KERN_INFO "hpt: HPT372N detected, using 372N timing.\n");
@@ -957,6 +962,7 @@
 				pci_set_drvdata(dev, (void *) thirty_three_base_hpt370);
 			printk("HPT37X: using 33MHz PCI clock\n");
 		} else if (pll == F_LOW_PCI_40) {
+			/* Unsupported */
 		} else if (pll == F_LOW_PCI_50) {
 			if (hpt_minimum_revision(dev,8))
 				pci_set_drvdata(dev, NULL);
@@ -971,7 +977,6 @@
 			if (hpt_minimum_revision(dev,8))
 			{
 				printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n");
-				pci_set_drvdata(dev, NULL);
 			}
 			else if (hpt_minimum_revision(dev,5))
 				pci_set_drvdata(dev, (void *) sixty_six_base_hpt372);
@@ -996,6 +1001,11 @@
 	if (pci_get_drvdata(dev)) 
 		goto init_hpt37X_done;
 	
+	if (hpt_minimum_revision(dev,8))
+	{
+		printk(KERN_ERR "HPT374: Only 33MHz PCI timings are supported.\n");
+		return -EOPNOTSUPP;
+	}
 	/*
 	 * adjust PLL based upon PCI clock, enable it, and wait for
 	 * stabilization.
@@ -1021,9 +1031,7 @@
 				pci_write_config_dword(dev, 0x5c, 
 						       pll & ~0x100);
 				pci_write_config_byte(dev, 0x5b, 0x21);
-				if (hpt_minimum_revision(dev,8))
-					return -EOPNOTSUPP;
-				else if (hpt_minimum_revision(dev,5))
+				if (hpt_minimum_revision(dev,5))
 					pci_set_drvdata(dev, (void *) fifty_base_hpt372);
 				else if (hpt_minimum_revision(dev,4))
 					pci_set_drvdata(dev, (void *) fifty_base_hpt370a);
@@ -1334,7 +1342,7 @@
 	struct pci_dev *findev = NULL;
 	u8 pin1 = 0, pin2 = 0;
 	unsigned int class_rev;
-	char *chipset_names[] = {"HPT366", "HPT366",  "HPT368",
+	static char *chipset_names[] = {"HPT366", "HPT366",  "HPT368",
 				 "HPT370", "HPT370A", "HPT372"};
 
 	if (PCI_FUNC(dev->devfn) & 1)
@@ -1349,7 +1357,8 @@
 	if(d->device == PCI_DEVICE_ID_TTI_HPT372N)
 		class_rev = 5;
 		
-	strcpy(d->name, chipset_names[class_rev]);
+	if(class_rev < 6)
+		d->name = chipset_names[class_rev];
 
 	switch(class_rev) {
 		case 5:
diff -urN linux-2.4.22-pre2/drivers/ide/pci/pdc202xx_new.h linux-2.4.22-pre3/drivers/ide/pci/pdc202xx_new.h
--- linux-2.4.22-pre2/drivers/ide/pci/pdc202xx_new.h	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/pci/pdc202xx_new.h	2003-07-05 18:09:59.000000000 -0700
@@ -255,7 +255,7 @@
 		.vendor		= PCI_VENDOR_ID_PROMISE,
 		.device		= PCI_DEVICE_ID_PROMISE_20275,
 		.name		= "PDC20275",
-		.init_setup	= init_setup_pdcnew,
+		.init_setup	= init_setup_pdc20276,
 		.init_chipset	= init_chipset_pdcnew,
 		.init_iops	= NULL,
 		.init_hwif	= init_hwif_pdc202new,
@@ -287,7 +287,7 @@
 		.vendor		= PCI_VENDOR_ID_PROMISE,
 		.device		= PCI_DEVICE_ID_PROMISE_20277,
 		.name		= "PDC20277",
-		.init_setup	= init_setup_pdcnew,
+		.init_setup	= init_setup_pdc20276,
 		.init_chipset	= init_chipset_pdcnew,
 		.init_iops	= NULL,
 		.init_hwif	= init_hwif_pdc202new,
diff -urN linux-2.4.22-pre2/drivers/ide/pci/pdc202xx_old.c linux-2.4.22-pre3/drivers/ide/pci/pdc202xx_old.c
--- linux-2.4.22-pre2/drivers/ide/pci/pdc202xx_old.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/pci/pdc202xx_old.c	2003-07-05 18:09:59.000000000 -0700
@@ -168,9 +168,6 @@
 		pdc202xx_pio_verbose(reg64h),
 		pdc202xx_pio_verbose(reg68h),
 		pdc202xx_pio_verbose(reg6ch));
-#if 0
-	p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n");
-#endif
 	return (char *)p;
 }
 
@@ -635,42 +632,7 @@
 	
 	pdc202xx_reset_host(hwif);
 	pdc202xx_reset_host(mate);
-#if 0
-	/*
-	 * FIXME: Have to kick all the drives again :-/
-	 * What a pain in the ACE!
-	 */
-	if (hwif->present) {
-		u16 hunit = 0;
-		hwif->initializing = 1;
-		for (hunit = 0; hunit < MAX_DRIVES; ++hunit) {
-			ide_drive_t *hdrive = &hwif->drives[hunit];
-			if (hdrive->present) {
-				if (hwif->ide_dma_check)
-					hwif->ide_dma_check(hdrive);
-				else
-					hwif->tuneproc(hdrive, 5);
-			}
-		}
-		hwif->initializing = 0;
-	}
-	if (mate->present) {
-		u16 munit = 0;
-		mate->initializing = 1;
-		for (munit = 0; munit < MAX_DRIVES; ++munit) {
-			ide_drive_t *mdrive = &mate->drives[munit];
-			if (mdrive->present) {
-				if (mate->ide_dma_check) 
-					mate->ide_dma_check(mdrive);
-				else
-					mate->tuneproc(mdrive, 5);
-			}
-		}
-		mate->initializing = 0;
-	}
-#else
 	hwif->tuneproc(drive, 5);
-#endif
 }
 
 /*
@@ -726,20 +688,6 @@
 	 * reset leaves the timing registers intact,
 	 * but resets the drives.
 	 */
-#if 0
-	if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) ||
-	    (dev->device == PCI_DEVICE_ID_PROMISE_20265) ||
-	    (dev->device == PCI_DEVICE_ID_PROMISE_20263) ||
-	    (dev->device == PCI_DEVICE_ID_PROMISE_20262)) {
-		unsigned long high_16	= pci_resource_start(dev, 4);
-		byte udma_speed_flag	= inb(high_16 + 0x001f);
-		outb(udma_speed_flag | 0x10, high_16 + 0x001f);
-		mdelay(100);
-		outb(udma_speed_flag & ~0x10, high_16 + 0x001f);
-		mdelay(2000);	/* 2 seconds ?! */
-	}
-
-#endif
 	return dev->irq;
 }
 
@@ -859,18 +807,6 @@
 		}
 	}
 
-#if 0
-        if (dev->device == PCI_DEVICE_ID_PROMISE_20262)
-        if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
-             (tmp & e->mask) != e->val))
-
-        if (d->enablebits[0].reg != d->enablebits[1].reg) {
-                d->enablebits[0].reg    = d->enablebits[1].reg;
-                d->enablebits[0].mask   = d->enablebits[1].mask;
-                d->enablebits[0].val    = d->enablebits[1].val;
-        }
-#endif
-
 	ide_setup_pci_device(dev, d);
 }
 
@@ -884,22 +820,6 @@
 			"attached to I2O RAID controller.\n");
 		return;
 	}
-
-#if 0
-        {
-                u8 pri = 0, sec = 0;
-
-        if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
-             (tmp & e->mask) != e->val))
-
-        if (d->enablebits[0].reg != d->enablebits[1].reg) {
-                d->enablebits[0].reg    = d->enablebits[1].reg;
-                d->enablebits[0].mask   = d->enablebits[1].mask;
-                d->enablebits[0].val    = d->enablebits[1].val;
-        }
-        }
-#endif
-
 	ide_setup_pci_device(dev, d);
 }
 
diff -urN linux-2.4.22-pre2/drivers/ide/pci/siimage.c linux-2.4.22-pre3/drivers/ide/pci/siimage.c
--- linux-2.4.22-pre2/drivers/ide/pci/siimage.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/pci/siimage.c	2003-07-05 18:09:59.000000000 -0700
@@ -1,10 +1,24 @@
 /*
- * linux/drivers/ide/pci/siimage.c		Version 1.02	Jan 30, 2003
+ * linux/drivers/ide/pci/siimage.c		Version 1.06	June 11, 2003
  *
  * Copyright (C) 2001-2002	Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2003		Red Hat <alan@redhat.com>
  *
  *  May be copied or modified under the terms of the GNU General Public License
+ *
+ *  Documentation available under NDA only
+ *
+ *
+ *  FAQ Items:
+ *	If you are using Marvell SATA-IDE adapters with Maxtor drives
+ *	ensure the system is set up for ATA100/UDMA5 not UDMA6.
+ *
+ *	If you are using WD drives with SATA bridges you must set the
+ *	drive to "Single". "Master" will hang
+ *
+ *	If you have strange problems with nVidia chipset systems please
+ *	see the SI support documentation and update your system BIOS
+ *	if neccessary
  */
 
 #include <linux/config.h>
@@ -30,12 +44,102 @@
 static struct pci_dev *siimage_devs[SIIMAGE_MAX_DEVS];
 static int n_siimage_devs;
 
-static char * print_siimage_get_info (char *buf, struct pci_dev *dev, int index)
+/**
+ *	pdev_is_sata		-	check if device is SATA
+ *	@pdev:	PCI device to check
+ *	
+ *	Returns true if this is a SATA controller
+ */
+ 
+static int pdev_is_sata(struct pci_dev *pdev)
+{
+	switch(pdev->device)
+	{
+		case PCI_DEVICE_ID_SII_3112:
+		case PCI_DEVICE_ID_SII_1210SA:
+			return 1;
+		case PCI_DEVICE_ID_SII_680:
+			return 0;
+	}
+	BUG();
+}
+ 
+/**
+ *	is_sata			-	check if hwif is SATA
+ *	@hwif:	interface to check
+ *	
+ *	Returns true if this is a SATA controller
+ */
+ 
+static inline int is_sata(ide_hwif_t *hwif)
+{
+	return pdev_is_sata(hwif->pci_dev);
+}
+
+/**
+ *	siimage_selreg		-	return register base
+ *	@hwif: interface
+ *	@r: config offset
+ *
+ *	Turn a config register offset into the right address in either
+ *	PCI space or MMIO space to access the control register in question
+ *	Thankfully this is a configuration operation so isnt performance
+ *	criticial. 
+ */
+ 
+static unsigned long siimage_selreg(ide_hwif_t *hwif, int r)
+{
+	unsigned long base = (unsigned long)hwif->hwif_data;
+	base += 0xA0 + r;
+	if(hwif->mmio)
+		base += (hwif->channel << 6);
+	else
+		base += (hwif->channel << 4);
+	return base;
+}
+	
+/**
+ *	siimage_seldev		-	return register base
+ *	@hwif: interface
+ *	@r: config offset
+ *
+ *	Turn a config register offset into the right address in either
+ *	PCI space or MMIO space to access the control register in question
+ *	including accounting for the unit shift.
+ */
+ 
+static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
+{
+	ide_hwif_t *hwif	= HWIF(drive);
+	unsigned long base = (unsigned long)hwif->hwif_data;
+	base += 0xA0 + r;
+	if(hwif->mmio)
+		base += (hwif->channel << 6);
+	else
+		base += (hwif->channel << 4);
+	base |= drive->select.b.unit << drive->select.b.unit;
+	return base;
+}
+	
+/**
+ *	print_siimage_get_info	-	print minimal proc information
+ *	@buf: buffer to write into (kernel space)
+ *	@dev: PCI device we are describing
+ *	@index: Controller number
+ *
+ *	Print the basic information for the state of the CMD680/SI3112
+ *	channel. We don't actually dump a lot of information out for
+ *	this controller although we could expand it if we needed.
+ */
+ 
+static char *print_siimage_get_info (char *buf, struct pci_dev *dev, int index)
 {
 	char *p		= buf;
 	u8 mmio		= (pci_get_drvdata(dev) != NULL) ? 1 : 0;
-	unsigned long bmdma	= (mmio) ? ((unsigned long) pci_get_drvdata(dev)) :
-				    (pci_resource_start(dev, 4));
+	unsigned long bmdma = pci_resource_start(dev, 4);
+	
+	if(mmio)
+		bmdma = pci_resource_start(dev, 5);
 
 	p += sprintf(p, "\nController: %d\n", index);
 	p += sprintf(p, "SiI%x Chipset.\n", dev->device);
@@ -43,18 +147,20 @@
 		p += sprintf(p, "MMIO Base 0x%lx\n", bmdma);
 	p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma);
 	p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma+8);
-
-	p += sprintf(p, "--------------- Primary Channel "
-			"---------------- Secondary Channel "
-			"-------------\n");
-	p += sprintf(p, "--------------- drive0 --------- drive1 "
-			"-------- drive0 ---------- drive1 ------\n");
-	p += sprintf(p, "PIO Mode:       %s                %s"
-			"               %s                 %s\n",
-			"?", "?", "?", "?");
 	return (char *)p;
 }
 
+/**
+ *	siimage_get_info	-	proc callback
+ *	@buffer: kernel buffer to complete
+ *	@addr: written with base of data to return
+ *	offset: seek offset
+ *	count: bytes to fill in 
+ *
+ *	Called when the user reads data from the virtual file for this
+ *	controller from /proc
+ */
+ 
 static int siimage_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p = buffer;
@@ -89,44 +195,56 @@
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 mode	= 0, scsc = 0;
+	unsigned long base = (unsigned long) hwif->hwif_data;
 
 	if (hwif->mmio)
-		scsc = hwif->INB(HWIFADDR(0x4A));
+		scsc = hwif->INB(base + 0x4A);
 	else
 		pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
 
-	switch(hwif->pci_dev->device) {
-		case PCI_DEVICE_ID_SII_3112:
-			return 4;
-		case PCI_DEVICE_ID_SII_680:
-			if ((scsc & 0x30) == 0x10)	/* 133 */
-				mode = 4;
-			else if ((scsc & 0x30) == 0x20)	/* 2xPCI */
-				mode = 4;
-			else if ((scsc & 0x30) == 0x00)	/* 100 */
-				mode = 3;
-			else 	/* Disabled ? */
-				BUG();
-			break;
-		default:	return 0;
+	if(is_sata(hwif))
+	{
+		if(strstr(drive->id->model, "Maxtor"))
+			return 3;
+		return 4;
 	}
+	
+	if ((scsc & 0x30) == 0x10)	/* 133 */
+		mode = 4;
+	else if ((scsc & 0x30) == 0x20)	/* 2xPCI */
+		mode = 4;
+	else if ((scsc & 0x30) == 0x00)	/* 100 */
+		mode = 3;
+	else 	/* Disabled ? */
+		BUG();
+
 	if (!eighty_ninty_three(drive))
 		mode = min(mode, (u8)1);
 	return mode;
 }
 
+/**
+ *	siimage_taskfile_timing	-	turn timing data to a mode
+ *	@hwif: interface to query
+ *
+ *	Read the timing data for the interface and return the 
+ *	mode that is being used.
+ */
+ 
 static byte siimage_taskfile_timing (ide_hwif_t *hwif)
 {
 	u16 timing	= 0x328a;
+	unsigned long addr = siimage_selreg(hwif, 2);
 
 	if (hwif->mmio)
-		timing = hwif->INW(SELADDR(2));
+		timing = hwif->INW(addr);
 	else
-		pci_read_config_word(hwif->pci_dev, SELREG(2), &timing);
+		pci_read_config_word(hwif->pci_dev, addr, &timing);
 
 	switch (timing) {
 		case 0x10c1:	return 4;
 		case 0x10c3:	return 3;
+		case 0x1104:
 		case 0x1281:	return 2;
 		case 0x2283:	return 1;
 		case 0x328a:
@@ -140,37 +258,82 @@
  *	@mode_wanted: the target operating mode
  *
  *	Load the timing settings for this device mode into the
- *	controller
+ *	controller. If we are in PIO mode 3 or 4 turn on IORDY
+ *	monitoring (bit 9). The TF timing is bits 31:16
  */
  
 static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	u16 speedt		= 0;
-	u8 unit			= drive->select.b.unit;
-
-	if (hwif->mmio)
-		speedt = hwif->INW(SELADDR(0x04|(unit<<unit)));
-	else
-		pci_read_config_word(dev, SELADDR(0x04|(unit<<unit)), &speedt);
-
+	u32 speedt		= 0;
+	u16 speedp		= 0;
+	unsigned long addr	= siimage_seldev(drive, 0x04);
+	unsigned long tfaddr	= siimage_selreg(hwif, 0x02);
+	
 	/* cheat for now and use the docs */
-//	switch(siimage_taskfile_timing(hwif)) {
 	switch(mode_wanted) {
-		case 4:		speedt = 0x10c1; break;
-		case 3:		speedt = 0x10C3; break;
-		case 2:		speedt = 0x1104; break;
-		case 1:		speedt = 0x2283; break;
+		case 4:	
+			speedp = 0x10c1; 
+			speedt = 0x10c1;
+			break;
+		case 3:	
+			speedp = 0x10C3; 
+			speedt = 0x10C3;
+			break;
+		case 2:	
+			speedp = 0x1104; 
+			speedt = 0x1281;
+			break;
+		case 1:		
+			speedp = 0x2283; 
+			speedt = 0x1281;
+			break;
 		case 0:
-		default:	speedt = 0x328A; break;
+		default:
+			speedp = 0x328A; 
+			speedt = 0x328A;
+			break;
 	}
 	if (hwif->mmio)
-		hwif->OUTW(speedt, SELADDR(0x04|(unit<<unit)));
+	{
+		hwif->OUTW(speedt, addr);
+		hwif->OUTW(speedp, tfaddr);
+		/* Now set up IORDY */
+		if(mode_wanted == 3 || mode_wanted == 4)
+			hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2);
+		else
+			hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2);
+	}
 	else
-		pci_write_config_word(dev, SELADDR(0x04|(unit<<unit)), speedt);
+	{
+		pci_write_config_word(hwif->pci_dev, addr, speedp);
+		pci_write_config_word(hwif->pci_dev, tfaddr, speedt);
+		pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp);
+		speedp &= ~0x200;
+		/* Set IORDY for mode 3 or 4 */
+		if(mode_wanted == 3 || mode_wanted == 4)
+			speedp |= 0x200;
+		pci_write_config_word(hwif->pci_dev, tfaddr-2, speedp);
+	}
 }
 
+/**
+ *	config_siimage_chipset_for_pio	-	set drive timings
+ *	@drive: drive to tune
+ *	@speed we want
+ *
+ *	Compute the best pio mode we can for a given device. Also honour
+ *	the timings for the driver when dealing with mixed devices. Some
+ *	of this is ugly but its all wrapped up here
+ *
+ *	The SI680 can also do VDMA - we need to start using that
+ *
+ *	FIXME: we use the BIOS channel timings to avoid driving the task
+ *	files too fast at the disk. We need to compute the master/slave
+ *	drive PIO mode properly so that we can up the speed on a hotplug
+ *	system.
+ */
+ 
 static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed)
 {
 	u8 channel_timings	= siimage_taskfile_timing(HWIF(drive));
@@ -191,6 +354,16 @@
 	config_siimage_chipset_for_pio(drive, set_speed);
 }
 
+/**
+ *	siimage_tune_chipset	-	set controller timings
+ *	@drive: Drive to set up
+ *	@xferspeed: speed we want to achieve
+ *
+ *	Tune the SII chipset for the desired mode. If we can't achieve
+ *	the desired mode then tune for a lower one, but ultimately
+ *	make the thing work.
+ */
+ 
 static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
 {
 	u8 ultra6[]		= { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
@@ -200,30 +373,32 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	u16 ultra = 0, multi	= 0;
 	u8 mode = 0, unit	= drive->select.b.unit;
-	u8 speed	= ide_rate_filter(siimage_ratemask(drive), xferspeed);
+	u8 speed		= ide_rate_filter(siimage_ratemask(drive), xferspeed);
+	unsigned long base	= (unsigned long)hwif->hwif_data;
 	u8 scsc = 0, addr_mask	= ((hwif->channel) ?
 				    ((hwif->mmio) ? 0xF4 : 0x84) :
 				    ((hwif->mmio) ? 0xB4 : 0x80));
+				    
+	unsigned long ma	= siimage_seldev(drive, 0x08);
+	unsigned long ua	= siimage_seldev(drive, 0x0C);
 
 	if (hwif->mmio) {
-		scsc = hwif->INB(HWIFADDR(0x4A));
-		mode = hwif->INB(HWIFADDR(addr_mask));
-		multi = hwif->INW(SELADDR(0x08|(unit<<unit)));
-		ultra = hwif->INW(SELADDR(0x0C|(unit<<unit)));
+		scsc = hwif->INB(base + 0x4A);
+		mode = hwif->INB(base + addr_mask);
+		multi = hwif->INW(ma);
+		ultra = hwif->INW(ua);
 	} else {
 		pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
 		pci_read_config_byte(hwif->pci_dev, addr_mask, &mode);
-		pci_read_config_word(hwif->pci_dev,
-				SELREG(0x08|(unit<<unit)), &multi);
-		pci_read_config_word(hwif->pci_dev,
-				SELREG(0x0C|(unit<<unit)), &ultra);
+		pci_read_config_word(hwif->pci_dev, ma, &multi);
+		pci_read_config_word(hwif->pci_dev, ua, &ultra);
 	}
 
 	mode &= ~((unit) ? 0x30 : 0x03);
 	ultra &= ~0x3F;
 	scsc = ((scsc & 0x30) == 0x00) ? 0 : 1;
 
-	scsc = (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) ? 1 : scsc;
+	scsc = is_sata(hwif) ? 1 : scsc;
 
 	switch(speed) {
 		case XFER_PIO_4:
@@ -259,20 +434,26 @@
 	}
 
 	if (hwif->mmio) {
-		hwif->OUTB(mode, HWIFADDR(addr_mask));
-		hwif->OUTW(multi, SELADDR(0x08|(unit<<unit)));
-		hwif->OUTW(ultra, SELADDR(0x0C|(unit<<unit)));
+		hwif->OUTB(mode, base + addr_mask);
+		hwif->OUTW(multi, ma);
+		hwif->OUTW(ultra, ua);
 	} else {
 		pci_write_config_byte(hwif->pci_dev, addr_mask, mode);
-		pci_write_config_word(hwif->pci_dev,
-				SELREG(0x08|(unit<<unit)), multi);
-		pci_write_config_word(hwif->pci_dev,
-				SELREG(0x0C|(unit<<unit)), ultra);
+		pci_write_config_word(hwif->pci_dev, ma, multi);
+		pci_write_config_word(hwif->pci_dev, ua, ultra);
 	}
-
 	return (ide_config_drive_speed(drive, speed));
 }
 
+/**
+ *	config_chipset_for_dma	-	configure for DMA
+ *	@drive: drive to configure
+ *
+ *	Called by the IDE layer when it wants the timings set up.
+ *	For the CMD680 we also need to set up the PIO timings and
+ *	enable DMA.
+ */
+ 
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
 	u8 speed	= ide_dma_speed(drive, siimage_ratemask(drive));
@@ -291,6 +472,16 @@
 	return ide_dma_enable(drive);
 }
 
+/**
+ *	siimage_configure_drive_for_dma	-	set up for DMA transfers
+ *	@drive: drive we are going to set up
+ *
+ *	Set up the drive for DMA, tune the controller and drive as 
+ *	required. If the drive isn't suitable for DMA or we hit
+ *	other problems then we will drop down to PIO and set up
+ *	PIO appropriately
+ */
+ 
 static int siimage_config_drive_for_dma (ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
@@ -340,18 +531,28 @@
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 dma_altstat		= 0;
+	unsigned long addr	= siimage_selreg(hwif, 1);
 
 	/* return 1 if INTR asserted */
 	if ((hwif->INB(hwif->dma_status) & 4) == 4)
 		return 1;
 
 	/* return 1 if Device INTR asserted */
-	pci_read_config_byte(hwif->pci_dev, SELREG(1), &dma_altstat);
+	pci_read_config_byte(hwif->pci_dev, addr, &dma_altstat);
 	if (dma_altstat & 8)
 		return 0;	//return 1;
 	return 0;
 }
 
+/**
+ *	siimage_mmio_ide_dma_count	-	DMA bytes done
+ *	@drive
+ *
+ *	If we are doing VDMA the CMD680 requires a little bit
+ *	of more careful handling and we have to read the counts
+ *	off ourselves. For non VDMA life is normal.
+ */
+ 
 static int siimage_mmio_ide_dma_count (ide_drive_t *drive)
 {
 #ifdef SIIMAGE_VIRTUAL_DMAPIO
@@ -359,9 +560,10 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	u32 count		= (rq->nr_sectors * SECTOR_SIZE);
 	u32 rcount		= 0;
+	unsigned long addr	= siimage_selreg(hwif, 0x1C);
 
-	hwif->OUTL(count, SELADDR(0x1C));
-	rcount = hwif->INL(SELADDR(0x1C));
+	hwif->OUTL(count, addr);
+	rcount = hwif->INL(addr);
 
 	printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n",
 		drive->name, count, rcount, rq->nr_sectors);
@@ -370,13 +572,22 @@
 	return __ide_dma_count(drive);
 }
 
-/* returns 1 if dma irq issued, 0 otherwise */
+/**
+ *	siimage_mmio_ide_dma_test_irq	-	check we caused an IRQ
+ *	@drive: drive we are testing
+ *
+ *	Check if we caused an IDE DMA interrupt. We may also have caused
+ *	SATA status interrupts, if so we clean them up and continue.
+ */
+ 
 static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
+	unsigned long base	= (unsigned long)hwif->hwif_data;
+	unsigned long addr	= siimage_selreg(hwif, 0x1);
 
 	if (SATA_ERROR_REG) {
-		u32 ext_stat = hwif->INL(HWIFADDR(0x10));
+		u32 ext_stat = hwif->INL(base + 0x10);
 		u8 watchdog = 0;
 		if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
 			u32 sata_error = hwif->INL(SATA_ERROR_REG);
@@ -403,7 +614,7 @@
 		return 1;
 
 	/* return 1 if Device INTR asserted */
-	if ((hwif->INB(SELADDR(1)) & 8) == 8)
+	if ((hwif->INB(addr) & 8) == 8)
 		return 0;	//return 1;
 
 	return 0;
@@ -412,9 +623,6 @@
 static int siimage_mmio_ide_dma_verbose (ide_drive_t *drive)
 {
 	int temp = __ide_dma_verbose(drive);
-#if 0
-	drive->using_dma = 0;
-#endif
 	return temp;
 }
 
@@ -432,11 +640,12 @@
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u32 stat_config		= 0;
+	unsigned long addr	= siimage_selreg(hwif, 0);
 
 	if (hwif->mmio) {
-		stat_config = hwif->INL(SELADDR(0));
+		stat_config = hwif->INL(addr);
 	} else
-		pci_read_config_dword(hwif->pci_dev, SELREG(0), &stat_config);
+		pci_read_config_dword(hwif->pci_dev, addr, &stat_config);
 
 	switch (state) {
 		case BUSSTATE_ON:
@@ -458,6 +667,14 @@
 	return 0;
 }
 
+/**
+ *	siimage_reset_poll	-	wait for sata reset
+ *	@drive: drive we are resetting
+ *
+ *	Poll the SATA phy and see whether it has come back from the dead
+ *	yet.
+ */
+ 
 static int siimage_reset_poll (ide_drive_t *drive)
 {
 	if (SATA_STATUS_REG) {
@@ -488,7 +705,8 @@
 	if (drive->media != ide_disk)
 		return;
 
-	if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_SII_3112) {
+	if (is_sata(HWIF(drive)))
+	{
 		drive->special.b.set_geometry = 0;
 		drive->special.b.recalibrate = 0;
 	}
@@ -506,19 +724,21 @@
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 reset		= 0;
+	unsigned long addr	= siimage_selreg(hwif, 0);
 
 	if (hwif->mmio) {
-		reset = hwif->INB(SELADDR(0));
-		hwif->OUTB((reset|0x03), SELADDR(0));
+		reset = hwif->INB(addr);
+		hwif->OUTB((reset|0x03), addr);
+		/* FIXME:posting */
 		udelay(25);
-		hwif->OUTB(reset, SELADDR(0));
-		(void) hwif->INB(SELADDR(0));
+		hwif->OUTB(reset, addr);
+		(void) hwif->INB(addr);
 	} else {
-		pci_read_config_byte(hwif->pci_dev, SELREG(0), &reset);
-		pci_write_config_byte(hwif->pci_dev, SELREG(0), reset|0x03);
+		pci_read_config_byte(hwif->pci_dev, addr, &reset);
+		pci_write_config_byte(hwif->pci_dev, addr, reset|0x03);
 		udelay(25);
-		pci_write_config_byte(hwif->pci_dev, SELREG(0), reset);
-		pci_read_config_byte(hwif->pci_dev, SELREG(0), &reset);
+		pci_write_config_byte(hwif->pci_dev, addr, reset);
+		pci_read_config_byte(hwif->pci_dev, addr, &reset);
 	}
 
 	if (SATA_STATUS_REG) {
@@ -546,11 +766,11 @@
  
 static void proc_reports_siimage (struct pci_dev *dev, u8 clocking, const char *name)
 {
-	if (dev->device == PCI_DEVICE_ID_SII_3112)
+	if(pdev_is_sata(dev))
 		goto sata_skip;
 
 	printk(KERN_INFO "%s: BASE CLOCK ", name);
-	clocking &= ~0x03;
+	clocking &= 0x03;
 	switch(clocking) {
 		case 0x03: printk("DISABLED !\n"); break;
 		case 0x02: printk("== 2X PCI \n"); break;
@@ -570,10 +790,20 @@
 #endif /* DISPLAY_SIIMAGE_TIMINGS && CONFIG_PROC_FS */
 }
 
+/**
+ *	setup_mmio_siimage	-	switch an SI controller into MMIO
+ *	@dev: PCI device we are configuring
+ *	@name: device name
+ *
+ *	Attempt to put the device into mmio mode. There are some slight
+ *	complications here with certain systems where the mmio bar isnt
+ *	mapped so we have to be sure we can fall back to I/O.
+ */
+ 
 static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
 {
 	unsigned long bar5	= pci_resource_start(dev, 5);
-	unsigned long len5	= pci_resource_len(dev, 5);
+	unsigned long barsize	= pci_resource_len(dev, 5);
 	u8 tmpbyte	= 0;
 	unsigned long addr;
 	void *ioaddr;
@@ -584,34 +814,37 @@
 	 *	spaces.
 	 */
 	 
-	if(check_mem_region(bar5, len5)!=0)
+	if(!request_mem_region(bar5, barsize, name))
 	{
 		printk(KERN_WARNING "siimage: IDE controller MMIO ports not available.\n");
 		return 0;
 	}
 		
-	ioaddr = ioremap_nocache(bar5, len5);
+	ioaddr = ioremap(bar5, barsize);
 
 	if (ioaddr == NULL)
+	{
+		release_mem_region(bar5, barsize);
 		return 0;
+	}
 
 	pci_set_master(dev);
 	pci_set_drvdata(dev, ioaddr);
 	addr = (unsigned long) ioaddr;
 
-	if (dev->device == PCI_DEVICE_ID_SII_3112) {
-		writel(0, DEVADDR(0x148));
-		writel(0, DEVADDR(0x1C8));
+	if (pdev_is_sata(dev)) {
+		writel(0, addr + 0x148);
+		writel(0, addr + 0x1C8);
 	}
 
-	writeb(0, DEVADDR(0xB4));
-	writeb(0, DEVADDR(0xF4));
-	tmpbyte = readb(DEVADDR(0x4A));
+	writeb(0, addr + 0xB4);
+	writeb(0, addr + 0xF4);
+	tmpbyte = readb(addr + 0x4A);
 
 	switch(tmpbyte & 0x30) {
 		case 0x00:
 			/* In 100 MHz clocking, try and switch to 133 */
-			writeb(tmpbyte|0x10, DEVADDR(0x4A));
+			writeb(tmpbyte|0x10, addr + 0x4A);
 			break;
 		case 0x10:
 			/* On 133Mhz clocking */
@@ -622,34 +855,43 @@
 		case 0x30:
 			/* Clocking is disabled */
 			/* 133 clock attempt to force it on */
-			writeb(tmpbyte & ~0x20, DEVADDR(0x4A));
+			writeb(tmpbyte & ~0x20, addr + 0x4A);
 			break;
 	}
 	
-	writeb(0x72, DEVADDR(0xA1));
-	writew(0x328A, DEVADDR(0xA2));
-	writel(0x62DD62DD, DEVADDR(0xA4));
-	writel(0x43924392, DEVADDR(0xA8));
-	writel(0x40094009, DEVADDR(0xAC));
-	writeb(0x72, DEVADDR(0xE1));
-	writew(0x328A, DEVADDR(0xE2));
-	writel(0x62DD62DD, DEVADDR(0xE4));
-	writel(0x43924392, DEVADDR(0xE8));
-	writel(0x40094009, DEVADDR(0xEC));
-
-	if (dev->device == PCI_DEVICE_ID_SII_3112) {
-		writel(0xFFFF0000, DEVADDR(0x108));
-		writel(0xFFFF0000, DEVADDR(0x188));
-		writel(0x00680000, DEVADDR(0x148));
-		writel(0x00680000, DEVADDR(0x1C8));
+	writeb(      0x72, addr + 0xA1);
+	writew(    0x328A, addr + 0xA2);
+	writel(0x62DD62DD, addr + 0xA4);
+	writel(0x43924392, addr + 0xA8);
+	writel(0x40094009, addr + 0xAC);
+	writeb(      0x72, addr + 0xE1);
+	writew(    0x328A, addr + 0xE2);
+	writel(0x62DD62DD, addr + 0xE4);
+	writel(0x43924392, addr + 0xE8);
+	writel(0x40094009, addr + 0xEC);
+
+	if (pdev_is_sata(dev)) {
+		writel(0xFFFF0000, addr + 0x108);
+		writel(0xFFFF0000, addr + 0x188);
+		writel(0x00680000, addr + 0x148);
+		writel(0x00680000, addr + 0x1C8);
 	}
 
-	tmpbyte = readb(DEVADDR(0x4A));
+	tmpbyte = readb(addr + 0x4A);
 
-	proc_reports_siimage(dev, (tmpbyte>>=4), name);
+	proc_reports_siimage(dev, (tmpbyte>>4), name);
 	return 1;
 }
 
+/**
+ *	init_chipset_siimage	-	set up an SI device
+ *	@dev: PCI device
+ *	@name: device name
+ *
+ *	Perform the initial PCI set up for this device. Attempt to switch
+ *	to 133MHz clocking if the system isn't already set up to do it.
+ */
+
 static unsigned int __init init_chipset_siimage (struct pci_dev *dev, const char *name)
 {
 	u32 class_rev	= 0;
@@ -686,115 +928,134 @@
 			break;
 	}
 
-	pci_read_config_byte(dev, 0x8A, &tmpbyte);
-	pci_write_config_byte(dev, 0xA1, 0x72);
-	pci_write_config_word(dev, 0xA2, 0x328A);
+	pci_read_config_byte(dev,   0x8A, &tmpbyte);
+
+	pci_write_config_byte(dev,  0xA1, 0x72);
+	pci_write_config_word(dev,  0xA2, 0x328A);
 	pci_write_config_dword(dev, 0xA4, 0x62DD62DD);
 	pci_write_config_dword(dev, 0xA8, 0x43924392);
 	pci_write_config_dword(dev, 0xAC, 0x40094009);
-	pci_write_config_byte(dev, 0xB1, 0x72);
-	pci_write_config_word(dev, 0xB2, 0x328A);
+	pci_write_config_byte(dev,  0xB1, 0x72);
+	pci_write_config_word(dev,  0xB2, 0x328A);
 	pci_write_config_dword(dev, 0xB4, 0x62DD62DD);
 	pci_write_config_dword(dev, 0xB8, 0x43924392);
 	pci_write_config_dword(dev, 0xBC, 0x40094009);
 
-	pci_read_config_byte(dev, 0x8A, &tmpbyte);
-	proc_reports_siimage(dev, (tmpbyte>>=4), name);
+	proc_reports_siimage(dev, (tmpbyte>>4), name);
 	return 0;
 }
 
+/**
+ *	init_mmio_iops_siimage	-	set up the iops for MMIO
+ *	@hwif: interface to set up
+ *
+ *	The basic setup here is fairly simple, we can use standard MMIO
+ *	operations. However we do have to set the taskfile register offsets
+ *	by hand as there isnt a standard defined layout for them this
+ *	time.
+ *
+ *	The hardware supports buffered taskfiles and also some rather nice
+ *	extended PRD tables. Unfortunately right now we don't.
+ */
+ 
 static void __init init_mmio_iops_siimage (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev	= hwif->pci_dev;
-	unsigned long addr	= (unsigned long) pci_get_drvdata(hwif->pci_dev);
+	void *addr		= pci_get_drvdata(dev);
 	u8 ch			= hwif->channel;
-//	u16 i			= 0;
-	hw_regs_t hw;
+	hw_regs_t		hw;
+	unsigned long		base;
+
+	/*
+	 *	Fill in the basic HWIF bits
+	 */
 
 	default_hwif_mmiops(hwif);
+	hwif->hwif_data			= addr;
+
+	/*
+	 *	Now set up the hw. We have to do this ourselves as
+	 *	the MMIO layout isnt the same as the the standard port
+	 *	based I/O
+	 */
+	 
 	memset(&hw, 0, sizeof(hw_regs_t));
+	hw.priv				= addr;
 
-#if 1
-#ifdef SIIMAGE_BUFFERED_TASKFILE
-	hw.io_ports[IDE_DATA_OFFSET]	= DEVADDR((ch) ? 0xD0 : 0x90);
-	hw.io_ports[IDE_ERROR_OFFSET]	= DEVADDR((ch) ? 0xD1 : 0x91);
-	hw.io_ports[IDE_NSECTOR_OFFSET]	= DEVADDR((ch) ? 0xD2 : 0x92);
-	hw.io_ports[IDE_SECTOR_OFFSET]	= DEVADDR((ch) ? 0xD3 : 0x93);
-	hw.io_ports[IDE_LCYL_OFFSET]	= DEVADDR((ch) ? 0xD4 : 0x94);
-	hw.io_ports[IDE_HCYL_OFFSET]	= DEVADDR((ch) ? 0xD5 : 0x95);
-	hw.io_ports[IDE_SELECT_OFFSET]	= DEVADDR((ch) ? 0xD6 : 0x96);
-	hw.io_ports[IDE_STATUS_OFFSET]	= DEVADDR((ch) ? 0xD7 : 0x97);
-	hw.io_ports[IDE_CONTROL_OFFSET]	= DEVADDR((ch) ? 0xDA : 0x9A);
-#else /* ! SIIMAGE_BUFFERED_TASKFILE */
-	hw.io_ports[IDE_DATA_OFFSET]	= DEVADDR((ch) ? 0xC0 : 0x80);
-	hw.io_ports[IDE_ERROR_OFFSET]	= DEVADDR((ch) ? 0xC1 : 0x81);
-	hw.io_ports[IDE_NSECTOR_OFFSET]	= DEVADDR((ch) ? 0xC2 : 0x82);
-	hw.io_ports[IDE_SECTOR_OFFSET]	= DEVADDR((ch) ? 0xC3 : 0x83);
-	hw.io_ports[IDE_LCYL_OFFSET]	= DEVADDR((ch) ? 0xC4 : 0x84);
-	hw.io_ports[IDE_HCYL_OFFSET]	= DEVADDR((ch) ? 0xC5 : 0x85);
-	hw.io_ports[IDE_SELECT_OFFSET]	= DEVADDR((ch) ? 0xC6 : 0x86);
-	hw.io_ports[IDE_STATUS_OFFSET]	= DEVADDR((ch) ? 0xC7 : 0x87);
-	hw.io_ports[IDE_CONTROL_OFFSET]	= DEVADDR((ch) ? 0xCA : 0x8A);
-#endif /* SIIMAGE_BUFFERED_TASKFILE */
-#else
-#ifdef SIIMAGE_BUFFERED_TASKFILE
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-		hw.io_ports[i] = DEVADDR((ch) ? 0xD0 : 0x90)|(i);
-	hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xDA : 0x9A);
-#else /* ! SIIMAGE_BUFFERED_TASKFILE */
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-		hw.io_ports[i] = DEVADDR((ch) ? 0xC0 : 0x80)|(i);
-	hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xCA : 0x8A);
-#endif /* SIIMAGE_BUFFERED_TASKFILE */
-#endif
+	base				= (unsigned long)addr;
+	if(ch)
+		base += 0xC0;
+	else
+		base += 0x80;
 
-#if 0
-	printk(KERN_DEBUG "%s: ", hwif->name);
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-		printk("0x%08x ", DEVADDR((ch) ? 0xC0 : 0x80)|(i));
-	printk("0x%08x ", DEVADDR((ch) ? 0xCA : 0x8A)|(i));
-#endif
+	/*
+	 *	The buffered task file doesn't have status/control
+	 *	so we can't currently use it sanely since we want to
+	 *	use LBA48 mode.
+	 */	
+//	base += 0x10;
+//      hwif->addressing = 1;
+
+	hw.io_ports[IDE_DATA_OFFSET]	= base;
+	hw.io_ports[IDE_ERROR_OFFSET]	= base + 1;
+	hw.io_ports[IDE_NSECTOR_OFFSET]	= base + 2;
+	hw.io_ports[IDE_SECTOR_OFFSET]	= base + 3;
+	hw.io_ports[IDE_LCYL_OFFSET]	= base + 4;
+	hw.io_ports[IDE_HCYL_OFFSET]	= base + 5;
+	hw.io_ports[IDE_SELECT_OFFSET]	= base + 6;
+	hw.io_ports[IDE_STATUS_OFFSET]	= base + 7;
+	hw.io_ports[IDE_CONTROL_OFFSET]	= base + 10;
 
 	hw.io_ports[IDE_IRQ_OFFSET]	= 0;
 
-        if (dev->device == PCI_DEVICE_ID_SII_3112) {
-		hw.sata_scr[SATA_STATUS_OFFSET]	= DEVADDR((ch) ? 0x184 : 0x104);
-		hw.sata_scr[SATA_ERROR_OFFSET]	= DEVADDR((ch) ? 0x188 : 0x108);
-		hw.sata_scr[SATA_CONTROL_OFFSET]= DEVADDR((ch) ? 0x180 : 0x100);
-		hw.sata_misc[SATA_MISC_OFFSET]	= DEVADDR((ch) ? 0x1C0 : 0x140);
-		hw.sata_misc[SATA_PHY_OFFSET]	= DEVADDR((ch) ? 0x1C4 : 0x144);
-		hw.sata_misc[SATA_IEN_OFFSET]	= DEVADDR((ch) ? 0x1C8 : 0x148);
+        if (pdev_is_sata(dev)) {
+        	base = (unsigned long) addr;
+        	if(ch)
+        		base += 0x80;
+		hw.sata_scr[SATA_STATUS_OFFSET]	= base + 0x104;
+		hw.sata_scr[SATA_ERROR_OFFSET]	= base + 0x108;
+		hw.sata_scr[SATA_CONTROL_OFFSET]= base + 0x100;
+		hw.sata_misc[SATA_MISC_OFFSET]	= base + 0x140;
+		hw.sata_misc[SATA_PHY_OFFSET]	= base + 0x144;
+		hw.sata_misc[SATA_IEN_OFFSET]	= base + 0x148;
 	}
 
-	hw.priv				= (void *) addr;
-//	hw.priv				= pci_get_drvdata(hwif->pci_dev);
 	hw.irq				= hwif->pci_dev->irq;
 
 	memcpy(&hwif->hw, &hw, sizeof(hw));
 	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
 
-	if (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) {
+	if (is_sata(hwif)) {
 		memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr));
 		memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc));
 	}
 
-#ifdef SIIMAGE_BUFFERED_TASKFILE
-        hwif->addressing = 1;
-#endif /* SIIMAGE_BUFFERED_TASKFILE */
 	hwif->irq			= hw.irq;
-	hwif->hwif_data			= pci_get_drvdata(hwif->pci_dev);
+
+       	base = (unsigned long) addr;
 
 #ifdef SIIMAGE_LARGE_DMA
-	hwif->dma_base			= DEVADDR((ch) ? 0x18 : 0x10);
-	hwif->dma_base2			= DEVADDR((ch) ? 0x08 : 0x00);
-	hwif->dma_prdtable		= (hwif->dma_base2 + 4);
+/* Watch the brackets - even Ken and Dennis get some language design wrong */
+	hwif->dma_base			= base + (ch ? 0x18 : 0x10);
+	hwif->dma_base2			= base + (ch ? 0x08 : 0x00);
+	hwif->dma_prdtable		= hwif->dma_base2 + 4;
 #else /* ! SIIMAGE_LARGE_DMA */
-	hwif->dma_base			= DEVADDR((ch) ? 0x08 : 0x00);
-	hwif->dma_base2			= DEVADDR((ch) ? 0x18 : 0x10);
+	hwif->dma_base			= base + (ch ? 0x08 : 0x00);
+	hwif->dma_base2			= base + (ch ? 0x18 : 0x10);
 #endif /* SIIMAGE_LARGE_DMA */
 	hwif->mmio			= 2;
 }
 
+/**
+ *	init_iops_siimage	-	set up iops
+ *	@hwif: interface to set up
+ *
+ *	Do the basic setup for the SIIMAGE hardware interface
+ *	and then do the MMIO setup if we can. This is the first
+ *	look in we get for setting up the hwif so that we
+ *	can get the iops right before using them.
+ */
+ 
 static void __init init_iops_siimage (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev	= hwif->pci_dev;
@@ -802,27 +1063,47 @@
 
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
+	
+	hwif->hwif_data = 0;
 
 	hwif->rqsize = 128;
-	if ((dev->device == PCI_DEVICE_ID_SII_3112) && (!(class_rev)))
-		hwif->rqsize = 16;
+	if (is_sata(hwif))
+		hwif->rqsize = 15;
 
 	if (pci_get_drvdata(dev) == NULL)
 		return;
 	init_mmio_iops_siimage(hwif);
 }
 
+/**
+ *	ata66_siimage	-	check for 80 pin cable
+ *	@hwif: interface to check
+ *
+ *	Check for the presence of an ATA66 capable cable on the
+ *	interface.
+ */
+ 
 static unsigned int __init ata66_siimage (ide_hwif_t *hwif)
 {
+	unsigned long addr = siimage_selreg(hwif, 0);
 	if (pci_get_drvdata(hwif->pci_dev) == NULL) {
 		u8 ata66 = 0;
-		pci_read_config_byte(hwif->pci_dev, SELREG(0), &ata66);
+		pci_read_config_byte(hwif->pci_dev, addr, &ata66);
 		return (ata66 & 0x01) ? 1 : 0;
 	}
 
-	return (hwif->INB(SELADDR(0)) & 0x01) ? 1 : 0;
+	return (hwif->INB(addr) & 0x01) ? 1 : 0;
 }
 
+/**
+ *	init_hwif_siimage	-	set up hwif structs
+ *	@hwif: interface to set up
+ *
+ *	We do the basic set up of the interface structure. The SIIMAGE
+ *	requires several custom handlers so we override the default
+ *	ide DMA handlers appropriately
+ */
+ 
 static void __init init_hwif_siimage (ide_hwif_t *hwif)
 {
 	hwif->autodma = 0;
@@ -833,7 +1114,7 @@
 	hwif->reset_poll = &siimage_reset_poll;
 	hwif->pre_reset = &siimage_pre_reset;
 
-	if(hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112)
+	if(is_sata(hwif))
 		hwif->busproc   = &siimage_busproc;
 
 	if (!hwif->dma_base) {
@@ -846,7 +1127,7 @@
 	hwif->mwdma_mask = 0x07;
 	hwif->swdma_mask = 0x07;
 
-	if (hwif->pci_dev->device != PCI_DEVICE_ID_SII_3112)
+	if (!is_sata(hwif))
 		hwif->atapi_dma = 1;
 
 	hwif->ide_dma_check = &siimage_config_drive_for_dma;
@@ -860,12 +1141,26 @@
 	} else {
 		hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq;
 	}
-	if (!noautodma)
-		hwif->autodma = 1;
+	
+	/*
+	 *	The BIOS often doesn't set up DMA on this controller
+	 *	so we always do it.
+	 */
+
+	hwif->autodma = 1;
 	hwif->drives[0].autodma = hwif->autodma;
 	hwif->drives[1].autodma = hwif->autodma;
 }
 
+/**
+ *	init_dma_siimage	-	set up IDE DMA
+ *	@hwif: interface
+ *	@dmabase: DMA base address to use
+ *	
+ *	For the SI chips this requires no special set up so we can just
+ *	let the IDE DMA core do the usual work.
+ */
+ 
 static void __init init_dma_siimage (ide_hwif_t *hwif, unsigned long dmabase)
 {
 	ide_setup_dma(hwif, dmabase, 8);
@@ -874,6 +1169,15 @@
 extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
 
 
+/**
+ *	siimage_init_one	-	pci layer discovery entry
+ *	@dev: PCI device
+ *	@id: ident table entry
+ *
+ *	Called by the PCI code when it finds an SI680 or SI3112 controller.
+ *	We then use the IDE PCI generic helper to do most of the work.
+ */
+ 
 static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	ide_pci_device_t *d = &siimage_chipsets[id->driver_data];
@@ -887,6 +1191,7 @@
 static struct pci_device_id siimage_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
 	{ 0, },
 };
 
diff -urN linux-2.4.22-pre2/drivers/ide/pci/siimage.h linux-2.4.22-pre3/drivers/ide/pci/siimage.h
--- linux-2.4.22-pre2/drivers/ide/pci/siimage.h	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/pci/siimage.h	2003-07-05 18:09:59.000000000 -0700
@@ -13,12 +13,6 @@
 #undef SIIMAGE_BUFFERED_TASKFILE
 #undef SIIMAGE_LARGE_DMA
 
-#if 0
-typedef struct ide_io_ops_s siimage_iops {
-
-}
-#endif
-
 #define SII_DEBUG 0
 
 #if SII_DEBUG
@@ -27,12 +21,6 @@
 #define siiprintk(x...)
 #endif
 
-#define ADJREG(B,R)	((B)|(R)|((hwif->channel)<<(4+(2*(!!hwif->mmio)))))
-#define SELREG(R)	ADJREG((0xA0),(R))
-#define SELADDR(R)	((((unsigned long)hwif->hwif_data)*(!!hwif->mmio))|SELREG((R)))
-#define HWIFADDR(R)	((((unsigned long)hwif->hwif_data)*(!!hwif->mmio))|(R))
-#define DEVADDR(R)	(((unsigned long) pci_get_drvdata(dev))|(R))
-
 
 #if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
@@ -85,6 +73,19 @@
 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
 		.bootable	= ON_BOARD,
 		.extra		= 0,
+	},{	/* 2 */
+		.vendor		= PCI_VENDOR_ID_CMD,
+		.device		= PCI_DEVICE_ID_SII_1210SA,
+		.name		= "Adaptec AAR-1210SA",
+		.init_chipset	= init_chipset_siimage,
+		.init_iops	= init_iops_siimage,
+		.init_hwif	= init_hwif_siimage,
+		.init_dma	= init_dma_siimage,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+		.bootable	= ON_BOARD,
+		.extra		= 0,
 	},{
 		.vendor		= 0,
 		.device		= 0,
diff -urN linux-2.4.22-pre2/drivers/ide/pci/sis5513.c linux-2.4.22-pre3/drivers/ide/pci/sis5513.c
--- linux-2.4.22-pre2/drivers/ide/pci/sis5513.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/pci/sis5513.c	2003-07-05 18:09:59.000000000 -0700
@@ -1,8 +1,9 @@
 /*
- * linux/drivers/ide/pci/sis5513.c		Version 0.14ac	Sept 11, 2002
+ * linux/drivers/ide/pci/sis5513.c	Version 0.16ac+vp	Jun 18, 2003
  *
  * Copyright (C) 1999-2000	Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2002		Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
+ * Copyright (C) 2003		Vojtech Pavlik <vojtech@suse.cz>
  * May be copied or modified under the terms of the GNU General Public License
  *
  *
@@ -14,31 +15,33 @@
  *			  for checking code correctness, providing patches.
  *
  *
- * Original tests and design on the SiS620/5513 chipset.
- * ATA100 tests and design on the SiS735/5513 chipset.
+ * Original tests and design on the SiS620 chipset.
+ * ATA100 tests and design on the SiS735 chipset.
  * ATA16/33 support from specs
  * ATA133 support for SiS961/962 by L.C. Chang <lcchang@sis.com.tw>
+ * ATA133 961/962/963 fixes by Vojtech Pavlik <vojtech@suse.cz>
  *
  * Documentation:
- *	SiS chipset documentation available under NDA to companies not
- *	individuals only.
+ *	SiS chipset documentation available under NDA to companies only
+ *      (not to individuals).
  */
 
 /*
- * Notes/Special cases:
- * - SiS5513 derivatives usually have the same PCI IDE register layout when
- *  supporting the same UDMA modes.
- * - There are exceptions :
- *  . SiS730 and SiS550 use the same layout than ATA_66 chipsets but support
- *   ATA_100
- *  . ATA_133 capable chipsets mark a shift in SiS chipset designs : previously
- *   south and northbridge were integrated, making IDE (a southbridge function)
- *   capabilities easily deduced from the northbridge PCI id. With ATA_133,
- *   chipsets started to be split in the usual north/south bridges chips
- *   -> the driver needs to detect the correct southbridge when faced to newest
- *   northbridges.
- *  . On ATA133 capable chipsets when bit 30 of dword at 0x54 is 1 the
- *   configuration space is moved from 0x40 to 0x70.
+ * The original SiS5513 comes from a SiS5511/55112/5513 chipset. The original
+ * SiS5513 was also used in the SiS5596/5513 chipset. Thus if we see a SiS5511
+ * or SiS5596, we can assume we see the first MWDMA-16 capable SiS5513 chip.
+ *
+ * Later SiS chipsets integrated the 5513 functionality into the NorthBridge,
+ * starting with SiS5571 and up to SiS745. The PCI ID didn't change, though. We
+ * can figure out that we have a more modern and more capable 5513 by looking
+ * for the respective NorthBridge IDs.
+ *
+ * Even later (96x family) SiS chipsets use the MuTIOL link and place the 5513
+ * into the SouthBrige. Here we cannot rely on looking up the NorthBridge PCI
+ * ID, while the now ATA-133 capable 5513 still has the same PCI ID.
+ * Fortunately the 5513 can be 'unmasked' by fiddling with some config space
+ * bits, changing its device id to the true one - 5517 for 961 and 5518 for
+ * 962/963.
  */
 
 #include <linux/config.h>
@@ -57,94 +60,23 @@
 #include <linux/init.h>
 #include <linux/ide.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 
+#include "ide-timing.h"
 #include "ide_modes.h"
 #include "sis5513.h"
 
-/* When DEBUG is defined it outputs initial PCI config register
-   values and changes made to them by the driver */
-// #define DEBUG
-/* When BROKEN_LEVEL is defined it limits the DMA mode
-   at boot time to its value */
-// #define BROKEN_LEVEL XFER_SW_DMA_0
-
-/* Miscellaneous flags */
-#define SIS5513_LATENCY		0x01
-
 /* registers layout and init values are chipset family dependant */
-/* 1/ define families */
-#define ATA_00		0x00
+
 #define ATA_16		0x01
 #define ATA_33		0x02
 #define ATA_66		0x03
-#define ATA_100a	0x04 // SiS730 is ATA100 with ATA66 layout
+#define ATA_100a	0x04 // SiS730/SiS550 is ATA100 with ATA66 layout
 #define ATA_100		0x05
 #define ATA_133a	0x06 // SiS961b with 133 support
-#define ATA_133		0x07 // SiS962
-/* 2/ variable holding the controller chipset family value */
-static u8 chipset_family;
-
-
-/*
- * Debug code: following IDE config registers' changes
- */
-#ifdef DEBUG
-/* Copy of IDE Config registers fewer will be used
- * Some odd chipsets hang if unused registers are accessed
- * -> We only access them in #DEBUG code (then we'll see if SiS did
- * it right from day one) */
-static u8 ide_regs_copy[0xff];
-
-/* Read config registers, print differences from previous read */
-static void sis5513_load_verify_registers(struct pci_dev* dev, char* info) {
-	int i;
-	u8 reg_val;
-	u8 changed=0;
-
-	printk("SIS5513: %s, changed registers:\n", info);
-	for(i=0; i<=0xff; i++) {
-		pci_read_config_byte(dev, i, &reg_val);
-		if (reg_val != ide_regs_copy[i]) {
-			printk("%02x: %02x -> %02x\n",
-			       i, ide_regs_copy[i], reg_val);
-			ide_regs_copy[i]=reg_val;
-			changed=1;
-		}
-	}
-
-	if (!changed) {
-		printk("none\n");
-	}
-}
-
-/* Load config registers, no printing */
-static void sis5513_load_registers(struct pci_dev* dev) {
-	int i;
-
-	for(i=0; i<=0xff; i++) {
-		pci_read_config_byte(dev, i, &(ide_regs_copy[i]));
-	}
-}
-
-/* Print config space registers a la "lspci -vxxx" */
-static void sis5513_print_registers(struct pci_dev* dev, char* marker) {
-	int i,j;
-
-	sis5513_load_registers(dev);
-	printk("SIS5513 %s\n", marker);
-
-	for(i=0; i<=0xf; i++) {
-		printk("SIS5513 dump: %d" "0:", i);
-		for(j=0; j<=0xf; j++) {
-			printk(" %02x", ide_regs_copy[(i<<16)+j]);
-		}
-		printk("\n");
-	}
-}
-#endif
+#define ATA_133		0x07 // SiS962/963
 
+static u8 chipset_family;
 
 /*
  * Devices supported
@@ -155,41 +87,38 @@
 	u8 chipset_family;
 	u8 flags;
 } SiSHostChipInfo[] = {
-	{ "SiS752",	PCI_DEVICE_ID_SI_752,	ATA_133,	0 },
-	{ "SiS751",	PCI_DEVICE_ID_SI_751,	ATA_133,	0 },
-	{ "SiS750",	PCI_DEVICE_ID_SI_750,	ATA_133,	0 },
-	{ "SiS748",	PCI_DEVICE_ID_SI_748,	ATA_133,	0 },
-	{ "SiS746",	PCI_DEVICE_ID_SI_746,	ATA_133,	0 },
-	{ "SiS745",	PCI_DEVICE_ID_SI_745,	ATA_133,	0 },
-	{ "SiS740",	PCI_DEVICE_ID_SI_740,	ATA_100,	0 },
-	{ "SiS735",	PCI_DEVICE_ID_SI_735,	ATA_100,	SIS5513_LATENCY },
-	{ "SiS730",	PCI_DEVICE_ID_SI_730,	ATA_100a,	SIS5513_LATENCY },
-	{ "SiS652",	PCI_DEVICE_ID_SI_652,	ATA_133,	0 },
-	{ "SiS651",	PCI_DEVICE_ID_SI_651,	ATA_133,	0 },
-	{ "SiS650",	PCI_DEVICE_ID_SI_650,	ATA_133,	0 },
-	{ "SiS648",	PCI_DEVICE_ID_SI_648,	ATA_133,	0 },
-	{ "SiS646",	PCI_DEVICE_ID_SI_646,	ATA_133,	0 },
-	{ "SiS645",	PCI_DEVICE_ID_SI_645,	ATA_133,	0 },
-	{ "SiS635",	PCI_DEVICE_ID_SI_635,	ATA_100,	SIS5513_LATENCY },
-	{ "SiS640",	PCI_DEVICE_ID_SI_640,	ATA_66,		SIS5513_LATENCY },
-	{ "SiS630",	PCI_DEVICE_ID_SI_630,	ATA_66,		SIS5513_LATENCY },
-	{ "SiS620",	PCI_DEVICE_ID_SI_620,	ATA_66,		SIS5513_LATENCY },
-	{ "SiS550",	PCI_DEVICE_ID_SI_550,	ATA_100a,	0},
-	{ "SiS540",	PCI_DEVICE_ID_SI_540,	ATA_66,		0},
-	{ "SiS530",	PCI_DEVICE_ID_SI_530,	ATA_66,		0},
-	{ "SiS5600",	PCI_DEVICE_ID_SI_5600,	ATA_33,		0},
-	{ "SiS5598",	PCI_DEVICE_ID_SI_5598,	ATA_33,		0},
-	{ "SiS5597",	PCI_DEVICE_ID_SI_5597,	ATA_33,		0},
-	{ "SiS5591",	PCI_DEVICE_ID_SI_5591,	ATA_33,		0},
-	{ "SiS5513",	PCI_DEVICE_ID_SI_5513,	ATA_16,		0},
-	{ "SiS5511",	PCI_DEVICE_ID_SI_5511,	ATA_16,		0},
+	{ "SiS745",	PCI_DEVICE_ID_SI_745,	ATA_100  },
+	{ "SiS735",	PCI_DEVICE_ID_SI_735,	ATA_100  },
+	{ "SiS733",	PCI_DEVICE_ID_SI_733,	ATA_100  },
+	{ "SiS635",	PCI_DEVICE_ID_SI_635,	ATA_100  },
+	{ "SiS633",	PCI_DEVICE_ID_SI_633,	ATA_100  },
+
+	{ "SiS730",	PCI_DEVICE_ID_SI_730,	ATA_100a },
+	{ "SiS550",	PCI_DEVICE_ID_SI_550,	ATA_100a },
+
+	{ "SiS640",	PCI_DEVICE_ID_SI_640,	ATA_66   },
+	{ "SiS630",	PCI_DEVICE_ID_SI_630,	ATA_66   },
+	{ "SiS620",	PCI_DEVICE_ID_SI_620,	ATA_66   },
+	{ "SiS540",	PCI_DEVICE_ID_SI_540,	ATA_66   },
+	{ "SiS530",	PCI_DEVICE_ID_SI_530,	ATA_66   },
+
+	{ "SiS5600",	PCI_DEVICE_ID_SI_5600,	ATA_33   },
+	{ "SiS5598",	PCI_DEVICE_ID_SI_5598,	ATA_33   },
+	{ "SiS5597",	PCI_DEVICE_ID_SI_5597,	ATA_33   },
+	{ "SiS5591/2",	PCI_DEVICE_ID_SI_5591,	ATA_33   },
+	{ "SiS5582",	PCI_DEVICE_ID_SI_5582,	ATA_33   },
+	{ "SiS5581",	PCI_DEVICE_ID_SI_5581,	ATA_33   },
+
+	{ "SiS5596",	PCI_DEVICE_ID_SI_5596,	ATA_16   },
+	{ "SiS5571",	PCI_DEVICE_ID_SI_5571,	ATA_16   },
+	{ "SiS551x",	PCI_DEVICE_ID_SI_5511,	ATA_16   },
 };
 
 /* Cycle time bits and values vary across chip dma capabilities
    These three arrays hold the register layout and the values to set.
    Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */
 
-/* {ATA_00, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */
+/* {0, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */
 static u8 cycle_time_offset[] = {0,0,5,4,4,0,0};
 static u8 cycle_time_range[] = {0,0,2,3,3,4,4};
 static u8 cycle_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = {
@@ -248,8 +177,6 @@
 	{40,12,4,12,5,34,12,5},
 };
 
-static struct pci_dev *host_dev = NULL;
-
 /*
  * Printing configuration
  */
@@ -257,8 +184,8 @@
 static char* chipset_capability[] = {
 	"ATA", "ATA 16",
 	"ATA 33", "ATA 66",
-	"ATA 100", "ATA 100",
-	"ATA 133", "ATA 133"
+	"ATA 100 (1st gen)", "ATA 100 (2nd gen)",
+	"ATA 133 (1st gen)", "ATA 133 (2nd gen)"
 };
 
 #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
@@ -331,8 +258,9 @@
 			// Configuration space remapped to 0x70
 			drive_pci = 0x70;
 		}
-		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+8*pos, &regdw0);
-		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+8*pos+4, &regdw1);
+		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos, &regdw0);
+		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos+8, &regdw1);
+
 		p += sprintf(p, "Drive %d:\n", pos);
 	}
 
@@ -357,8 +285,7 @@
 			case ATA_100a:	p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break;
 			case ATA_100:
 			case ATA_133a:	p += sprintf(p, cycle_time[reg01 & 0x0F]); break;
-			case ATA_133:
-			default:	p += sprintf(p, "133+ ?"); break;
+			default:	p += sprintf(p, "?"); break;
 		}
 		p += sprintf(p, " \t UDMA Cycle Time    ");
 		switch(chipset_family) {
@@ -367,42 +294,39 @@
 			case ATA_100a:	p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break;
 			case ATA_100:
 			case ATA_133a:  p += sprintf(p, cycle_time[reg11 & 0x0F]); break;
-			case ATA_133:
-			default:	p += sprintf(p, "133+ ?"); break;
+			default:	p += sprintf(p, "?"); break;
 		}
 		p += sprintf(p, "\n");
 	}
 
+
+	if (chipset_family < ATA_133) {	/* else case TODO */
+
 /* Data Active */
-	p += sprintf(p, "                Data Active Time   ");
-	switch(chipset_family) {
-		case ATA_00:
-		case ATA_16: /* confirmed */
-		case ATA_33:
-		case ATA_66:
-		case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break;
-		case ATA_100:
-		case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break;
-		case ATA_133:
-		default: p += sprintf(p, "133+ ?"); break;
-	}
-	p += sprintf(p, " \t Data Active Time   ");
-	switch(chipset_family) {
-		case ATA_00:
-		case ATA_16:
-		case ATA_33:
-		case ATA_66:
-		case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break;
-		case ATA_100:
-		case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break;
-		case ATA_133:
-		default: p += sprintf(p, "133+ ?"); break;
-	}
-	p += sprintf(p, "\n");
+		p += sprintf(p, "                Data Active Time   ");
+		switch(chipset_family) {
+			case ATA_16: /* confirmed */
+			case ATA_33:
+			case ATA_66:
+			case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break;
+			case ATA_100:
+			case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break;
+			default: p += sprintf(p, "?"); break;
+		}
+		p += sprintf(p, " \t Data Active Time   ");
+		switch(chipset_family) {
+			case ATA_16:
+			case ATA_33:
+			case ATA_66:
+			case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break;
+			case ATA_100:
+			case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break;
+			default: p += sprintf(p, "?"); break;
+		}
+		p += sprintf(p, "\n");
 
 /* Data Recovery */
 	/* warning: may need (reg&0x07) for pre ATA66 chips */
-	if (chipset_family < ATA_133) {
 		p += sprintf(p, "                Data Recovery Time %s \t Data Recovery Time %s\n",
 			     recovery_time[reg00 & 0x0f], recovery_time[reg10 & 0x0f]);
 	}
@@ -430,7 +354,6 @@
 
 	p += sprintf(p, "\nSiS 5513 ");
 	switch(chipset_family) {
-		case ATA_00: p += sprintf(p, "Unknown???"); break;
 		case ATA_16: p += sprintf(p, "DMA 16"); break;
 		case ATA_33: p += sprintf(p, "Ultra 33"); break;
 		case ATA_66: p += sprintf(p, "Ultra 66"); break;
@@ -497,39 +420,16 @@
 
 	len = (p - buffer) - offset;
 	*addr = buffer + offset;
-	
+
 	return len > count ? count : len;
 }
 #endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
 
 static u8 sis5513_ratemask (ide_drive_t *drive)
 {
-#if 0
 	u8 rates[] = { 0, 0, 1, 2, 3, 3, 4, 4 };
 	u8 mode = rates[chipset_family];
-#else
-	u8 mode;
 
-	switch(chipset_family) {
-		case ATA_133:
-		case ATA_133a:
-			mode = 4;
-			break;
-		case ATA_100:
-		case ATA_100a:
-			mode = 3;
-			break;
-		case ATA_66:
-			mode = 2;
-			break;
-		case ATA_33:
-			return 1;
-		case ATA_16:
-                case ATA_00:	
-		default:
-			return 0;
-	}
-#endif
 	if (!eighty_ninty_three(drive))
 		mode = min(mode, (u8)1);
 	return mode;
@@ -547,20 +447,12 @@
 	u8 reg4bh		= 0;
 	u8 rw_prefetch		= (0x11 << drive->dn);
 
-#ifdef DEBUG
-	printk("SIS5513: config_drive_art_rwp, drive %d\n", drive->dn);
-	sis5513_load_verify_registers(dev, "config_drive_art_rwp start");
-#endif
-
 	if (drive->media != ide_disk)
 		return;
 	pci_read_config_byte(dev, 0x4b, &reg4bh);
 
 	if ((reg4bh & rw_prefetch) != rw_prefetch)
 		pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);
-#ifdef DEBUG
-	sis5513_load_verify_registers(dev, "config_drive_art_rwp end");
-#endif
 }
 
 
@@ -575,10 +467,6 @@
 	u16 eide_pio_timing[6] = {600, 390, 240, 180, 120, 90};
 	u16 xfer_pio = drive->id->eide_pio_modes;
 
-#ifdef DEBUG
-	sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");
-#endif
-
 	config_drive_art_rwp(drive);
 	pio = ide_get_best_pio_mode(drive, 255, pio, NULL);
 
@@ -598,12 +486,6 @@
 
 	timing = (xfer_pio >= pio) ? xfer_pio : pio;
 
-#ifdef DEBUG
-	printk("SIS5513: config_drive_art_rwp_pio, "
-		"drive %d, pio %d, timing %d\n",
-	       drive->dn, pio, timing);
-#endif
-
 	/* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */
 	drive_pci = 0x40;
 	/* In SiS962 case drives sit at (0x40 or 0x70) + 8*drive->dn) */
@@ -649,41 +531,24 @@
 		pci_read_config_dword(dev, drive_pci, &test3);
 		test3 &= 0xc0c00fff;
 		if (test3 & 0x08) {
-			test3 |= (unsigned long)ini_time_value[ATA_133-ATA_00][timing] << 12;
-			test3 |= (unsigned long)act_time_value[ATA_133-ATA_00][timing] << 16;
-			test3 |= (unsigned long)rco_time_value[ATA_133-ATA_00][timing] << 24;
+			test3 |= (unsigned long)ini_time_value[ATA_133][timing] << 12;
+			test3 |= (unsigned long)act_time_value[ATA_133][timing] << 16;
+			test3 |= (unsigned long)rco_time_value[ATA_133][timing] << 24;
 		} else {
-			test3 |= (unsigned long)ini_time_value[ATA_100-ATA_00][timing] << 12;
-			test3 |= (unsigned long)act_time_value[ATA_100-ATA_00][timing] << 16;
-			test3 |= (unsigned long)rco_time_value[ATA_100-ATA_00][timing] << 24;
+			test3 |= (unsigned long)ini_time_value[ATA_100][timing] << 12;
+			test3 |= (unsigned long)act_time_value[ATA_100][timing] << 16;
+			test3 |= (unsigned long)rco_time_value[ATA_100][timing] << 24;
 		}
 		pci_write_config_dword(dev, drive_pci, test3);
 	}
-
-#ifdef DEBUG
-	sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");
-#endif
 }
 
 static int config_chipset_for_pio (ide_drive_t *drive, u8 pio)
 {
-#if 0
+	if (pio == 255)
+		pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
 	config_art_rwp_pio(drive, pio);
-	return ide_config_drive_speed(drive, (XFER_PIO_0 + pio));
-#else
-	u8 speed;
-
-	switch(pio) {
-		case 4:		speed = XFER_PIO_4; break;
-		case 3:		speed = XFER_PIO_3; break;
-		case 2:		speed = XFER_PIO_2; break;
-		case 1:		speed = XFER_PIO_1; break;
-		default:	speed = XFER_PIO_0; break;
-	}
-
-	config_art_rwp_pio(drive, pio);
-	return ide_config_drive_speed(drive, speed);
-#endif
+	return ide_config_drive_speed(drive, XFER_PIO_0 + min_t(u8, pio, 4));
 }
 
 static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
@@ -694,24 +559,8 @@
 	u8 drive_pci, reg, speed;
 	u32 regdw;
 
-#ifdef DEBUG
-	sis5513_load_verify_registers(dev, "sis5513_tune_chipset start");
-#endif
-
-#ifdef BROKEN_LEVEL
-#ifdef DEBUG
-	printk("SIS5513: BROKEN_LEVEL activated, speed=%d -> speed=%d\n", xferspeed, BROKEN_LEVEL);
-#endif
-	if (xferspeed > BROKEN_LEVEL) xferspeed = BROKEN_LEVEL;
-#endif
-
 	speed = ide_rate_filter(sis5513_ratemask(drive), xferspeed);
 
-#ifdef DEBUG
-	printk("SIS5513: sis5513_tune_chipset, drive %d, speed %d\n",
-	       drive->dn, xferspeed);
-#endif
-
 	/* See config_art_rwp_pio for drive pci config registers */
 	drive_pci = 0x40;
 	if (chipset_family >= ATA_133) {
@@ -750,14 +599,14 @@
 				regdw &= 0xfffff00f;
 				/* check if ATA133 enable */
 				if (regdw & 0x08) {
-					regdw |= (unsigned long)cycle_time_value[ATA_133-ATA_00][speed-XFER_UDMA_0] << 4;
-					regdw |= (unsigned long)cvs_time_value[ATA_133-ATA_00][speed-XFER_UDMA_0] << 8;
+					regdw |= (unsigned long)cycle_time_value[ATA_133][speed-XFER_UDMA_0] << 4;
+					regdw |= (unsigned long)cvs_time_value[ATA_133][speed-XFER_UDMA_0] << 8;
 				} else {
 				/* if ATA133 disable, we should not set speed above UDMA5 */
 					if (speed > XFER_UDMA_5)
 						speed = XFER_UDMA_5;
-					regdw |= (unsigned long)cycle_time_value[ATA_100-ATA_00][speed-XFER_UDMA_0] << 4;
-					regdw |= (unsigned long)cvs_time_value[ATA_100-ATA_00][speed-XFER_UDMA_0] << 8;
+					regdw |= (unsigned long)cycle_time_value[ATA_100][speed-XFER_UDMA_0] << 4;
+					regdw |= (unsigned long)cvs_time_value[ATA_100][speed-XFER_UDMA_0] << 8;
 				}
 				pci_write_config_dword(dev, (unsigned long)drive_pci, regdw);
 			} else {
@@ -767,7 +616,7 @@
 				reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family]))
 					 << cycle_time_offset[chipset_family]);
 				/* set reg cycle time bits */
-				reg |= cycle_time_value[chipset_family-ATA_00][speed-XFER_UDMA_0]
+				reg |= cycle_time_value[chipset_family][speed-XFER_UDMA_0]
 					<< cycle_time_offset[chipset_family];
 				pci_write_config_byte(dev, drive_pci+1, reg);
 			}
@@ -786,9 +635,7 @@
 		case XFER_PIO_0:
 		default:	 return((int) config_chipset_for_pio(drive, 0));	
 	}
-#ifdef DEBUG
-	sis5513_load_verify_registers(dev, "sis5513_tune_chipset end");
-#endif
+
 	return ((int) ide_config_drive_speed(drive, speed));
 }
 
@@ -867,71 +714,121 @@
 	return sis5513_config_drive_xfer_rate(drive);
 }
 
+/*
+  Future simpler config_xfer_rate :
+   When ide_find_best_mode is made bad-drive aware
+   - remove config_drive_xfer_rate and config_chipset_for_dma,
+   - replace config_xfer_rate with the following
+
+static int sis5513_config_xfer_rate (ide_drive_t *drive)
+{
+	u16 w80 = HWIF(drive)->udma_four;
+	u16 speed;
+
+	config_drive_art_rwp(drive);
+	config_art_rwp_pio(drive, 5);
+
+	speed = ide_find_best_mode(drive,
+		XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
+		(chipset_family >= ATA_33 ? XFER_UDMA : 0) |
+		(w80 && chipset_family >= ATA_66 ? XFER_UDMA_66 : 0) |
+		(w80 && chipset_family >= ATA_100a ? XFER_UDMA_100 : 0) |
+		(w80 && chipset_family >= ATA_133a ? XFER_UDMA_133 : 0));
+
+	sis5513_tune_chipset(drive, speed);
+
+	if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
+		return HWIF(drive)->ide_dma_on(drive);
+	return HWIF(drive)->ide_dma_off_quietly(drive);
+}
+*/
+
 /* Chip detection and general config */
 static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name)
 {
 	struct pci_dev *host;
 	int i = 0;
 
-	/* Find the chip */
-	for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !host_dev; i++) {
-		host = pci_find_device (PCI_VENDOR_ID_SI,
-					SiSHostChipInfo[i].host_id,
-					NULL);
+	chipset_family = 0;
+
+	for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !chipset_family; i++) {
+
+		host = pci_find_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL);
+
 		if (!host)
 			continue;
 
-		host_dev = host;
 		chipset_family = SiSHostChipInfo[i].chipset_family;
+
+		/* Special case for SiS630 : 630S/ET is ATA_100a */
+		if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) {
+			u8 hostrev;
+			pci_read_config_byte(host, PCI_REVISION_ID, &hostrev);
+			if (hostrev >= 0x30)
+				chipset_family = ATA_100a;
+		}
 	
-		/* check 100/133 chipset family */
-		if (chipset_family == ATA_133) {
-			u32 reg54h;
-			u16 reg02h;
-			pci_read_config_dword(dev, 0x54, &reg54h);
-			pci_write_config_dword(dev, 0x54, (reg54h & 0x7fffffff));
-			pci_read_config_word(dev, 0x02, &reg02h);
-			pci_write_config_dword(dev, 0x54, reg54h);
-			/* devid 5518 here means SiS962 or later
-			   which supports ATA133 */
-			if (reg02h != 0x5518) {
-				u8 reg49h;
-				unsigned long sbrev;
-				/* SiS961 family */
-
-		/*
-		 * FIXME !!! GAK!!!!!!!!!! PCI DIRECT POKING 
-		 */
-				outl(0x80001008, 0x0cf8);
-				sbrev = inl(0x0cfc);
+		printk(KERN_INFO "SIS5513: %s %s controller\n",
+			 SiSHostChipInfo[i].name, chipset_capability[chipset_family]);
+	}
 
-				pci_read_config_byte(dev, 0x49, &reg49h);
-				if (((sbrev & 0xff) == 0x10) && (reg49h & 0x80))
-					chipset_family = ATA_133a;
-				else
-					chipset_family = ATA_100;
+	if (!chipset_family) { /* Belongs to pci-quirks */
+
+			u32 idemisc;
+			u16 trueid;
+
+			/* Disable ID masking and register remapping */
+			pci_read_config_dword(dev, 0x54, &idemisc);
+			pci_write_config_dword(dev, 0x54, (idemisc & 0x7fffffff));
+			pci_read_config_word(dev, PCI_DEVICE_ID, &trueid);
+			pci_write_config_dword(dev, 0x54, idemisc);
+
+			if (trueid == 0x5518) {
+				printk(KERN_INFO "SIS5513: SiS 962/963 MuTIOL IDE UDMA133 controller\n");
+				chipset_family = ATA_133;
 			}
-		}
-		printk(SiSHostChipInfo[i].name);
-		printk("    %s controller", chipset_capability[chipset_family]);
-		printk("\n");
+	}
 
-#ifdef DEBUG
-		sis5513_print_registers(dev, "pci_init_sis5513 start");
-#endif
+	if (!chipset_family) { /* Belongs to pci-quirks */
 
-		if (SiSHostChipInfo[i].flags & SIS5513_LATENCY) {
-			u8 latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */
-			pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
-		}
+			struct pci_dev *lpc_bridge;
+			u16 trueid;
+			u8 prefctl;
+			u8 idecfg;
+			u8 sbrev;
+
+			pci_read_config_byte(dev, 0x4a, &idecfg);
+			pci_write_config_byte(dev, 0x4a, idecfg | 0x10);
+			pci_read_config_word(dev, PCI_DEVICE_ID, &trueid);
+			pci_write_config_byte(dev, 0x4a, idecfg);
+
+			if (trueid == 0x5517) { /* SiS 961/961B */
+
+				lpc_bridge = pci_find_slot(0x00, 0x10); /* Bus 0, Dev 2, Fn 0 */
+				pci_read_config_byte(lpc_bridge, PCI_REVISION_ID, &sbrev);
+				pci_read_config_byte(dev, 0x49, &prefctl);
+
+				if (sbrev == 0x10 && (prefctl & 0x80)) {
+					printk(KERN_INFO "SIS5513: SiS 961B MuTIOL IDE UDMA133 controller\n");
+					chipset_family = ATA_133a;
+				} else {
+					printk(KERN_INFO "SIS5513: SiS 961 MuTIOL IDE UDMA100 controller\n");
+					chipset_family = ATA_100;
+				}
+			}
 	}
 
+	if (!chipset_family)
+		return -1;
+
 	/* Make general config ops here
 	   1/ tell IDE channels to operate in Compatibility mode only
 	   2/ tell old chips to allow per drive IDE timings */
-	if (host_dev) {
+
+	{
 		u8 reg;
 		u16 regw;
+
 		switch(chipset_family) {
 			case ATA_133:
 				/* SiS962 operation mode */
@@ -944,6 +841,8 @@
 				break;
 			case ATA_133a:
 			case ATA_100:
+				/* Fixup latency */
+				pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
 				/* Set compatibility bit */
 				pci_read_config_byte(dev, 0x49, &reg);
 				if (!(reg & 0x01)) {
@@ -952,6 +851,9 @@
 				break;
 			case ATA_100a:
 			case ATA_66:
+				/* Fixup latency */
+				pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10);
+
 				/* On ATA_66 chips the bit was elsewhere */
 				pci_read_config_byte(dev, 0x52, &reg);
 				if (!(reg & 0x04)) {
@@ -972,8 +874,6 @@
 					pci_write_config_byte(dev, 0x52, reg|0x08);
 				}
 				break;
-			case ATA_00:
-			default: break;
 		}
 
 #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
@@ -984,9 +884,7 @@
 		}
 #endif
 	}
-#ifdef DEBUG
-	sis5513_load_verify_registers(dev, "pci_init_sis5513 end");
-#endif
+
 	return 0;
 }
 
@@ -1029,7 +927,7 @@
 	hwif->mwdma_mask = 0x07;
 	hwif->swdma_mask = 0x07;
 
-	if (!host_dev)
+	if (!chipset_family)
 		return;
 
 	if (!(hwif->udma_four))
@@ -1087,7 +985,7 @@
 module_init(sis5513_ide_init);
 module_exit(sis5513_ide_exit);
 
-MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick");
+MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick, Vojtech Pavlik");
 MODULE_DESCRIPTION("PCI driver module for SIS IDE");
 MODULE_LICENSE("GPL");
 
@@ -1095,13 +993,10 @@
 
 /*
  * TODO:
- *	- Get ridden of SisHostChipInfo[] completness dependancy.
- *	- Study drivers/ide/ide-timing.h.
- *	- Are there pre-ATA_16 SiS5513 chips ? -> tune init code for them
- *	  or remove ATA_00 define
+ *	- CLEANUP
+ *	- Use drivers/ide/ide-timing.h !
  *	- More checks in the config registers (force values instead of
  *	  relying on the BIOS setting them correctly).
  *	- Further optimisations ?
  *	  . for example ATA66+ regs 0x48 & 0x4A
  */
-
diff -urN linux-2.4.22-pre2/drivers/ide/raid/hptraid.c linux-2.4.22-pre3/drivers/ide/raid/hptraid.c
--- linux-2.4.22-pre2/drivers/ide/raid/hptraid.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/raid/hptraid.c	2003-07-05 18:09:59.000000000 -0700
@@ -17,7 +17,30 @@
 	Copyright (C) 1994-96 Marc ZYNGIER <zyngier@ufr-info-p7.ibp.fr>
    Based on work done by Søren Schmidt for FreeBSD
 
-   
+   Changelog:
+   15.06.2003 wweissmann@gmx.at
+   	* correct values of raid-1 superbock
+	* re-add check for availability of all disks
+	* fix offset bug in raid-1 (introduced in raid 0+1 implementation)
+
+   14.06.2003 wweissmann@gmx.at
+   	* superblock has wrong "disks" value on raid-1
+   	* fixup for raid-1 disknumbering
+	* do _NOT_ align size to 255*63 boundary
+		I WILL NOT USE FDISK TO DETERMINE THE VOLUME SIZE.
+		I WILL NOT USE FDISK TO DETERMINE THE VOLUME SIZE.
+		I WILL NOT USE FDISK TO DETERMINE THE VOLUME SIZE.
+		I WILL NOT ...
+
+   13.06.2003 wweissmann@gmx.at
+   	* raid 0+1 support
+	* check if all disks of an array are available
+	* bump version number
+
+   29.05.2003 wweissmann@gmx.at
+   	* release no more devices than available on unload
+	* remove static variables in raid-1 read path
+
 */
 
 #include <linux/module.h>
@@ -34,6 +57,8 @@
 #include <asm/uaccess.h>
 
 #include "ataraid.h"
+#include "hptraid.h"
+
 
 static int hptraid_open(struct inode * inode, struct file * filp);
 static int hptraid_release(struct inode * inode, struct file * filp);
@@ -41,26 +66,30 @@
 static int hptraidspan_make_request (request_queue_t *q, int rw, struct buffer_head * bh);
 static int hptraid0_make_request (request_queue_t *q, int rw, struct buffer_head * bh);
 static int hptraid1_make_request (request_queue_t *q, int rw, struct buffer_head * bh);
+static int hptraid01_make_request (request_queue_t *q, int rw, struct buffer_head * bh);
 
 
 
 struct hptdisk {
-	kdev_t	device;
+	kdev_t	device;		/* disk-ID/raid 0+1 volume-ID */
 	unsigned long sectors;
 	struct block_device *bdev;
 	unsigned long last_pos;
 };
 
 struct hptraid {
-	unsigned int stride;
-	unsigned int disks;
-	unsigned long sectors;
+	unsigned int stride;	/* stripesize */
+	unsigned int disks;	/* number of disks in array */
+	unsigned long sectors;	/* disksize in sectors */
         u_int32_t magic_0;
+        u_int32_t magic_1;
 	struct geom geom;
 	
+	int previous;		/* most recently accessed disk in mirror */
 	struct hptdisk disk[8];
-	unsigned long cutoff[8];
+	unsigned long cutoff[8];	/* raid 0 cutoff */
 	unsigned int cutoff_disks[8];	
+	struct hptraid * raid01;	/* sub arrays for raid 0+1 */
 };
 
 struct hptraid_dev {
@@ -109,9 +138,30 @@
 	make_request:		hptraid1_make_request
 };
 
+
+static struct raid_device_operations hptraid01_ops = {
+	open:                   hptraid_open,
+	release:                hptraid_release,
+	ioctl:			hptraid_ioctl,
+	make_request:		hptraid01_make_request
+};
+
+static __init struct {
+	struct raid_device_operations *op;
+	u_int8_t type;
+	char label[8];
+} oplist[] = {
+	{&hptraid0_ops, HPT_T_RAID_0, "RAID 0"},
+	{&hptraid1_ops, HPT_T_RAID_1, "RAID 1"},
+	{&hptraidspan_ops, HPT_T_SPAN, "SPAN"},
+	{&hptraid01_ops, HPT_T_RAID_01_RAID_0, "RAID 0+1"},
+	{0, 0}
+};
+
 static struct hptraid raid[14];
 
-static int hptraid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static int hptraid_ioctl(struct inode *inode, struct file *file,
+		unsigned int cmd, unsigned long arg)
 {
 	unsigned int minor;
 	unsigned char val;
@@ -185,7 +235,10 @@
 	device = (bh->b_rdev >> SHIFT)&MAJOR_MASK;
 	thisraid = &raid[device];
 
-	/* Partitions need adding of the start sector of the partition to the requested sector */
+	/*
+	 * Partitions need adding of the start sector of the partition to the
+	 * requested sector
+	 */
 	
 	rsect += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect;
 
@@ -216,58 +269,58 @@
 	return 1;
 }
 
-static int hptraid0_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
+static int hptraid0_compute_request (struct hptraid *thisraid,
+		request_queue_t *q,
+		int rw, struct buffer_head * bh)
 {
-	unsigned long rsect;
 	unsigned long rsect_left,rsect_accum = 0;
 	unsigned long block;
 	unsigned int disk=0,real_disk=0;
 	int i;
-	int device;
-	struct hptraid *thisraid;
-
-	rsect = bh->b_rsector;
 
-	/* Ok. We need to modify this sector number to a new disk + new sector number. 
+	/* Ok. We need to modify this sector number to a new disk + new sector
+	 * number. 
 	 * If there are disks of different sizes, this gets tricky. 
 	 * Example with 3 disks (1Gb, 4Gb and 5 GB):
 	 * The first 3 Gb of the "RAID" are evenly spread over the 3 disks.
-	 * Then things get interesting. The next 2Gb (RAID view) are spread across disk 2 and 3
-	 * and the last 1Gb is disk 3 only.
+	 * Then things get interesting. The next 2Gb (RAID view) are spread
+	 * across disk 2 and 3 and the last 1Gb is disk 3 only.
 	 *
-	 * the way this is solved is like this: We have a list of "cutoff" points where everytime
-	 * a disk falls out of the "higher" count, we mark the max sector. So once we pass a cutoff
-	 * point, we have to divide by one less.
+	 * the way this is solved is like this: We have a list of "cutoff"
+	 * points where everytime a disk falls out of the "higher" count, we
+	 * mark the max sector. So once we pass a cutoff point, we have to
+	 * divide by one less.
 	 */
 	
-	device = (bh->b_rdev >> SHIFT)&MAJOR_MASK;
-	thisraid = &raid[device];
 	if (thisraid->stride==0)
 		thisraid->stride=1;
 
-	/* Partitions need adding of the start sector of the partition to the requested sector */
-	
-	rsect += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect;
-
-	/* Woops we need to split the request to avoid crossing a stride barrier */
-	if ((rsect/thisraid->stride) != ((rsect+(bh->b_size/512)-1)/thisraid->stride)) {
+	/*
+	 * Woops we need to split the request to avoid crossing a stride
+	 * barrier
+	 */
+	if ((bh->b_rsector/thisraid->stride) !=
+			((bh->b_rsector+(bh->b_size/512)-1)/thisraid->stride)) {
 		return -1;
 	}
 			
-	rsect_left = rsect;
+	rsect_left = bh->b_rsector;;
 	
 	for (i=0;i<8;i++) {
 		if (thisraid->cutoff_disks[i]==0)
 			break;
-		if (rsect > thisraid->cutoff[i]) {
+		if (bh->b_rsector > thisraid->cutoff[i]) {
 			/* we're in the wrong area so far */
 			rsect_left -= thisraid->cutoff[i];
-			rsect_accum += thisraid->cutoff[i]/thisraid->cutoff_disks[i];
+			rsect_accum += thisraid->cutoff[i] /
+				thisraid->cutoff_disks[i];
 		} else {
 			block = rsect_left / thisraid->stride;
 			disk = block % thisraid->cutoff_disks[i];
-			block = (block / thisraid->cutoff_disks[i]) * thisraid->stride;
-			rsect = rsect_accum + (rsect_left % thisraid->stride) + block;
+			block = (block / thisraid->cutoff_disks[i]) *
+				thisraid->stride;
+			bh->b_rsector = rsect_accum +
+				(rsect_left % thisraid->stride) + block;
 			break;
 		}
 	}
@@ -286,7 +339,7 @@
 	
 	/* All but the first disk have a 10 sector offset */
 	if (i>0)
-		rsect+=10;
+		bh->b_rsector+=10;
 		
 	
 	/*
@@ -295,7 +348,6 @@
 	 */
 	 
 	bh->b_rdev = thisraid->disk[disk].device;
-	bh->b_rsector = rsect;
 
 	/*
 	 * Let the main block layer submit the IO and resolve recursion:
@@ -303,12 +355,39 @@
 	return 1;
 }
 
+static int hptraid0_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
+{
+	unsigned long rsect;
+	int device;
+
+	/*
+	 * save the sector, it must be restored before a request-split
+	 * is performed
+	 */
+	rsect = bh->b_rsector;
+
+	/*
+	 * Partitions need adding of the start sector of the partition to the
+	 * requested sector
+	 */
+	
+	bh->b_rsector += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect;
+
+	device = (bh->b_rdev >> SHIFT)&MAJOR_MASK;
+	if( hptraid0_compute_request(raid+device, q, rw, bh) != 1 ) {
+			/* request must be split => restore sector */
+		bh->b_rsector = rsect;
+		return -1;
+	}
+
+	return 1;
+}
+
 static int hptraid1_read_request (request_queue_t *q, int rw, struct buffer_head * bh)
 {
 	int device;
 	int dist;
 	int bestsofar,bestdist,i;
-	static int previous;
 
 	/* Reads are simple in principle. Pick a disk and go. 
 	   Initially I cheat by just picking the one which the last known
@@ -331,11 +410,15 @@
 			dist = -dist;
 		if (dist>4095)
 			dist=4095;
-		
-		if (bestdist==dist) {  /* it's a tie; try to do some read balancing */
-			if ((previous>bestsofar)&&(previous<=i))  
+
+		  /* it's a tie; try to do some read balancing */
+		if (bestdist==dist) {
+			if ( (raid[device].previous>bestsofar) &&
+					(raid[device].previous<=i) )  
 				bestsofar = i;
-			previous = (previous + 1) % raid[device].disks;
+			raid[device].previous =
+				(raid[device].previous + 1) %
+				raid[device].disks;
 		} else if (bestdist>dist) {
 			bestdist = dist;
 			bestsofar = i;
@@ -343,7 +426,6 @@
 	
 	}
 	
-	bh->b_rsector += bestsofar?10:0;
 	bh->b_rdev = raid[device].disk[bestsofar].device; 
 	raid[device].disk[bestsofar].last_pos = bh->b_rsector+(bh->b_size>>9);
 
@@ -377,24 +459,49 @@
 		if (!bh1)
 			BUG();
 	
-		/* dupe the bufferhead and update the parts that need to be different */
+		/*
+		 * dupe the bufferhead and update the parts that need to be
+		 * different
+		 */
 		memcpy(bh1, bh, sizeof(*bh));
 		
 		bh1->b_end_io = ataraid_end_request;
 		bh1->b_private = private;
-		bh1->b_rsector += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect+(i==0?0:10); /* partition offset */
+		bh1->b_rsector += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect; /* partition offset */
 		bh1->b_rdev = raid[device].disk[i].device;
 
 		/* update the last known head position for the drive */
 		raid[device].disk[i].last_pos = bh1->b_rsector+(bh1->b_size>>9);
 
+		if( raid[device].raid01 ) {
+			if( hptraid0_compute_request(
+						raid[device].raid01 +
+							(bh1->b_rdev-1),
+						q, rw, bh1) != 1 ) {
+				/*
+				 * If a split is requested then it is requested
+				 * in the first iteration. This is true because
+				 * of the cutoff is not used in raid 0+1.
+				 */
+				if(unlikely(i)) {
+					BUG();
+				}
+				else {
+					kfree(private);
+					return -1;
+				}
+			}
+		}
 		generic_make_request(rw,bh1);
 	}
 	return 0;
 }
 
 static int hptraid1_make_request (request_queue_t *q, int rw, struct buffer_head * bh) {
-	/* Read and Write are totally different cases; split them totally here */
+	/*
+	 * Read and Write are totally different cases; split them totally
+	 * here
+	 */
 	if (rw==READA)
 		rw = READ;
 	
@@ -404,7 +511,43 @@
 		return hptraid1_write_request(q,rw,bh);
 }
 
-#include "hptraid.h"
+static int hptraid01_read_request (request_queue_t *q, int rw, struct buffer_head * bh)
+{
+	int rsector=bh->b_rsector;
+	int rdev=bh->b_rdev;
+
+		/* select mirror volume */
+	hptraid1_read_request(q, rw, bh);
+
+		/* stripe volume is selected by "bh->b_rdev" */
+	if( hptraid0_compute_request(
+				raid[(bh->b_rdev >> SHIFT)&MAJOR_MASK].
+					raid01 + (bh->b_rdev-1) ,
+				q, rw, bh) != 1 ) {
+
+			/* request must be split => restore sector and device */
+		bh->b_rsector = rsector;
+		bh->b_rdev = rdev;
+		return -1;
+
+	}
+
+	return 1;
+}
+
+static int hptraid01_make_request (request_queue_t *q, int rw, struct buffer_head * bh) {
+	/*
+	 * Read and Write are totally different cases; split them totally
+	 * here
+	 */
+	if (rw==READA)
+		rw = READ;
+	
+	if (rw==READ)
+		return hptraid01_read_request(q,rw,bh);
+	else
+		return hptraid1_write_request(q,rw,bh);
+}
 
 static int read_disk_sb (int major, int minor, unsigned char *buffer,int bufsize)
 {
@@ -456,77 +599,140 @@
 	return lba;
 }
 
-static void __init probedisk(struct hptraid_dev *disk, int device, u_int8_t type)
+static void writeentry(struct hptraid * raid, struct hptraid_dev * disk,
+		int index, struct highpoint_raid_conf * prom) {
+
+	int j=0;
+	struct gendisk *gd;
+	struct block_device *bdev;
+
+	bdev = bdget(MKDEV(disk->major,disk->minor));
+	if (bdev && blkdev_get(bdev,FMODE_READ|FMODE_WRITE,0,BDEV_RAW) == 0) {
+		raid->disk[index].bdev = bdev;
+        	/*
+		 * This is supposed to prevent others from stealing our
+		 * underlying disks now blank the /proc/partitions table for 
+		 * the wrong partition table, so that scripts don't
+		 * accidentally mount it and crash the kernel
+		 */
+		 /* XXX: the 0 is an utter hack  --hch */
+		gd=get_gendisk(MKDEV(disk->major, 0));
+		if (gd!=NULL) {
+ 			if (gd->major==disk->major)
+ 				for (j=1+(disk->minor<<gd->minor_shift);
+					j<((disk->minor+1)<<gd->minor_shift);
+					j++) gd->part[j].nr_sects=0;					
+		}
+        }
+	raid->disk[index].device = MKDEV(disk->major,disk->minor);
+	raid->disk[index].sectors = maxsectors(disk->major,disk->minor);
+	raid->stride = (1<<prom->raid0_shift);
+	raid->disks = prom->raid_disks;
+	raid->sectors = prom->total_secs;
+	raid->sectors += raid->sectors&1?1:0;
+	raid->magic_0=prom->magic_0;
+	raid->magic_1=prom->magic_1;
+
+}
+
+static int probedisk(struct hptraid_dev *disk, int device, u_int8_t type)
 {
-	int i;
+	int i, j;
         struct highpoint_raid_conf *prom;
 	static unsigned char block[4096];
-	struct block_device *bdev;
 	
  	if (disk->device != -1)	/* disk is occupied? */
- 		return;
+ 		return 0;
  
  	if (maxsectors(disk->major,disk->minor)==0)
-		return;
+		return 0;
 	
         if (read_disk_sb(disk->major,disk->minor,(unsigned char*)&block,sizeof(block)))
-        	return;
+        	return 0;
                                                                                                                  
         prom = (struct highpoint_raid_conf*)&block[512];
                 
         if (prom->magic!=  0x5a7816f0)
-        	return;
+        	return 0;
         switch (prom->type) {
 		case HPT_T_SPAN:
 		case HPT_T_RAID_0:
 		case HPT_T_RAID_1:
+		case HPT_T_RAID_01_RAID_0:
 			if(prom->type != type)
-				return;
+				return 0;
 			break;
 		default:
-			printk(KERN_INFO "hptraid: only SPAN, RAID0 and RAID1 is currently supported \n");
-			return;
+			printk(KERN_INFO "hptraid: unknown raid level-id %i\n",
+					prom->type);
+			return 0;
         }
 
  		/* disk from another array? */
- 	if(raid[device].disks && prom->magic_0 != raid[device].magic_0)
- 		return;
+	if (raid[device].disks) {	/* only check if raid is not empty */
+		if (type == HPT_T_RAID_01_RAID_0 ) {
+			if( prom->magic_1 != raid[device].magic_1) {
+				return 0;
+			}
+		}
+		else if (prom->magic_0 != raid[device].magic_0) {
+				return 0;
+		}
+	}
 
 	i = prom->disk_number;
 	if (i<0)
-		return;
+		return 0;
 	if (i>8) 
-		return;
+		return 0;
 
-	bdev = bdget(MKDEV(disk->major,disk->minor));
-	if (bdev && blkdev_get(bdev,FMODE_READ|FMODE_WRITE,0,BDEV_RAW) == 0) {
-        	int j=0;
-        	struct gendisk *gd;
-		raid[device].disk[i].bdev = bdev;
-        	/* This is supposed to prevent others from stealing our underlying disks */
-		/* now blank the /proc/partitions table for the wrong partition table,
-		   so that scripts don't accidentally mount it and crash the kernel */
-		 /* XXX: the 0 is an utter hack  --hch */
-		gd=get_gendisk(MKDEV(disk->major, 0));
-		if (gd!=NULL) {
- 			if (gd->major==disk->major)
- 				for (j=1+(disk->minor<<gd->minor_shift);
-					j<((disk->minor+1)<<gd->minor_shift);
-					j++) gd->part[j].nr_sects=0;					
+	if ( type == HPT_T_RAID_01_RAID_0 ) {
+
+			/* allocate helper raid devices for level 0+1 */
+		if (raid[device].raid01 == NULL ) {
+
+			raid[device].raid01=
+				kmalloc(2 * sizeof(struct hptraid),GFP_KERNEL);
+			if ( raid[device].raid01 == NULL ) {
+				printk(KERN_ERR "hptraid: out of memory\n");
+				raid[device].disks=-1;
+				return -ENOMEM;
+			}
+			memset(raid[device].raid01, 0,
+					2 * sizeof(struct hptraid));
 		}
-        }
-	raid[device].disk[i].device = MKDEV(disk->major,disk->minor);
-	raid[device].disk[i].sectors = maxsectors(disk->major,disk->minor);
-	raid[device].stride = (1<<prom->raid0_shift);
-	raid[device].disks = prom->raid_disks;
-	raid[device].sectors = prom->total_secs-(prom->total_secs%(255*63));
-	raid[device].sectors += raid[device].sectors&1?1:0;
-	raid[device].magic_0=prom->magic_0;
+
+			/* find free sub-stucture */
+		for (j=0; j<2; j++) {
+			if ( raid[device].raid01[j].disks == 0 ||
+			     raid[device].raid01[j].magic_0 == prom->magic_0 )
+			{
+				writeentry(raid[device].raid01+j, disk,
+						i, prom);
+				break;
+			}
+		}
+
+			/* no free slot */
+		if(j == 2)
+			return 0;
+
+		raid[device].stride=raid[device].raid01[j].stride;
+		raid[device].disks=j+1;
+		raid[device].sectors=raid[device].raid01[j].sectors;
+		raid[device].disk[j].sectors=raid[device].raid01[j].sectors;
+		raid[device].magic_1=prom->magic_1;
+	}
+	else {
+		writeentry(raid+device, disk, i, prom);
+	}
+
 	disk->device=device;
 			
+	return 1;
 }
 
-static void __init fill_cutoff(int device)
+static void fill_cutoff(struct hptraid * device)
 {
 	int i,j;
 	unsigned long smallest;
@@ -537,111 +743,154 @@
 	for (i=0;i<8;i++) {
 		smallest = ~0;
 		for (j=0;j<8;j++) 
-			if ((raid[device].disk[j].sectors < smallest) && (raid[device].disk[j].sectors>bar))
-				smallest = raid[device].disk[j].sectors;
+			if ((device->disk[j].sectors < smallest) && (device->disk[j].sectors>bar))
+				smallest = device->disk[j].sectors;
 		count = 0;
 		for (j=0;j<8;j++) 
-			if (raid[device].disk[j].sectors >= smallest)
+			if (device->disk[j].sectors >= smallest)
 				count++;
 		
 		smallest = smallest * count;		
 		bar = smallest;
-		raid[device].cutoff[i] = smallest;
-		raid[device].cutoff_disks[i] = count;
+		device->cutoff[i] = smallest;
+		device->cutoff_disks[i] = count;
 		
 	}
 }
 
+static int count_disks(struct hptraid * raid) {
+	int i, count=0;
+	for (i=0;i<8;i++) {
+		if (raid->disk[i].device!=0) {
+			printk(KERN_INFO "Drive %i is %li Mb \n",
+				i,raid->disk[i].sectors/2048);
+			count++;
+		}
+	}
+	return count;
+}
+
+static void raid1_fixup(struct hptraid * raid) {
+	int i, count=0;
+	for (i=0;i<8;i++) {
+			/* disknumbers and total disks values are bogus */
+		if (raid->disk[i].device!=0) {
+			raid->disk[count]=raid->disk[i];
+			if(i > count) {
+				memset(raid->disk+i, 0, sizeof(struct hptdisk));
+			}
+			count++;
+		}
+	}
+	raid->disks=count;
+}
 
-static __init int hptraid_init_one(int device, u_int8_t type)
+static int hptraid_init_one(int device, u_int8_t type, const char * label)
 {
 	int i,count;
-
 	memset(raid+device, 0, sizeof(struct hptraid));
-	for(i=0; i < 14; i++) {
-		probedisk(devlist+i, device, type);
+	for (i=0; i < 14; i++) {
+		if( probedisk(devlist+i, device, type) < 0 )
+			return -EINVAL;
+	}
+
+	/* Initialize raid levels */
+	switch (type) {
+		case HPT_T_RAID_0:
+			fill_cutoff(raid+device);
+			break;
+
+		case HPT_T_RAID_1:
+			raid1_fixup(raid+device);
+			break;
+
+		case HPT_T_RAID_01_RAID_0:
+			for(i=0; i < 2 && raid[device].raid01 && 
+					raid[device].raid01[i].disks; i++) {
+				fill_cutoff(raid[device].raid01+i);
+					/* initialize raid 0+1 volumes */
+				raid[device].disk[i].device=i+1;
+			}
+			break;
 	}
 
-	if(type == HPT_T_RAID_0)
-		fill_cutoff(device);
-	
 	/* Initialize the gendisk structure */
 	
 	ataraid_register_disk(device,raid[device].sectors);
 
-	count=0;
+	/* Verify that we have all disks */
+
+	count=count_disks(raid+device);
 		
-	for (i=0;i<8;i++) {
-		if (raid[device].disk[i].device!=0) {
-			printk(KERN_INFO "Drive %i is %li Mb \n",
-				i,raid[device].disk[i].sectors/2048);
-			count++;
-		}
+	if (count != raid[device].disks) {
+		printk(KERN_INFO "%s consists of %i drives but found %i drives\n",
+				label, raid[device].disks, count);
+		return -ENODEV;
 	}
-	if (count) {
-		printk(KERN_INFO "Raid array consists of %i drives. \n",count);
+	else if (count) {
+		printk(KERN_INFO "%s consists of %i drives.\n",
+				label, count);
+		if (type == HPT_T_RAID_01_RAID_0 ) {
+			for(i=0;i<raid[device].disks;i++) {
+				count=count_disks(raid[device].raid01+i);
+				if(count == raid[device].raid01[i].disks) {
+					printk(KERN_ERR "Sub-Raid %i array consists of %i drives.\n",
+							i, count);
+				}
+				else {
+					printk(KERN_ERR "Sub-Raid %i array consists of %i drives but found %i disk members.\n",
+							i, raid[device].raid01[i].disks,
+							count);
+					return -ENODEV;
+				}
+			}
+		}
 		return 0;
-	} else {
-		printk(KERN_INFO "No raid array found\n");
-		return -ENODEV;
 	}
 	
+	return -ENODEV; /* No more raid volumes */
 }
 
-static __init int hptraid_init(void)
+static int hptraid_init(void)
 {
- 	int retval,device,count=0;
+ 	int retval=-ENODEV;
+	int device,i,count=0;
   	
-	printk(KERN_INFO "Highpoint HPT370 Softwareraid driver for linux version 0.01-ww1\n");
+	printk(KERN_INFO "Highpoint HPT370 Softwareraid driver for linux version 0.02\n");
 
- 	do
- 	{
- 		device=ataraid_get_device(&hptraid0_ops);
- 		if (device<0)
- 			return (count?0:-ENODEV);
- 		retval = hptraid_init_one(device, HPT_T_RAID_0);
- 		if (retval)
- 			ataraid_release_device(device);
- 		else
- 			count++;
- 	} while(!retval);
- 	do
- 	{
- 		device=ataraid_get_device(&hptraid1_ops);
- 		if (device<0)
- 			return (count?0:-ENODEV);
- 		retval = hptraid_init_one(device, HPT_T_RAID_1);
- 		if (retval)
- 			ataraid_release_device(device);
- 		else
- 			count++;
- 	} while(!retval);
- 	do
- 	{
- 		device=ataraid_get_device(&hptraidspan_ops);
- 		if (device<0)
- 			return (count?0:-ENODEV);
- 		retval = hptraid_init_one(device, HPT_T_SPAN);
- 		if (retval)
- 			ataraid_release_device(device);
- 		else
- 			count++;
- 	} while(!retval);
+	for(i=0; oplist[i].op; i++) {
+		do
+		{
+			device=ataraid_get_device(oplist[i].op);
+			if (device<0)
+				return (count?0:-ENODEV);
+			retval = hptraid_init_one(device, oplist[i].type,
+					oplist[i].label);
+			if (retval)
+				ataraid_release_device(device);
+			else
+				count++;
+		} while(!retval);
+	}
  	return (count?0:retval);
 }
 
 static void __exit hptraid_exit (void)
 {
 	int i,device;
-	for (device = 0; device<16; device++) {
+	for (device = 0; device<14; device++) {
 		for (i=0;i<8;i++)  {
 			struct block_device *bdev = raid[device].disk[i].bdev;
 			raid[device].disk[i].bdev = NULL;
 			if (bdev)
 				blkdev_put(bdev, BDEV_RAW);
 		}       
-		if (raid[device].sectors)
+		if (raid[device].sectors) {
 			ataraid_release_device(device);
+			if( raid[device].raid01 ) {
+				kfree(raid[device].raid01);
+			}
+		}
 	}
 }
 
diff -urN linux-2.4.22-pre2/drivers/ide/setup-pci.c linux-2.4.22-pre3/drivers/ide/setup-pci.c
--- linux-2.4.22-pre2/drivers/ide/setup-pci.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ide/setup-pci.c	2003-07-05 18:09:59.000000000 -0700
@@ -137,7 +137,7 @@
 				"native PCI mode\n", name);
 			return -EOPNOTSUPP;
 		}
-		printk("%s: placing both ports into native PCI mode\n", name);
+		printk(KERN_INFO "%s: placing both ports into native PCI mode\n", name);
 		(void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5);
 		if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
 		    (progif & 5) != 5) {
@@ -183,10 +183,9 @@
 second_chance_to_dma:
 #endif /* CONFIG_BLK_DEV_IDEDMA_FORCED */
 
-	if ((hwif->mmio) && (hwif->dma_base))
+	if (hwif->mmio && hwif->dma_base)
 		return hwif->dma_base;
-
-	if (hwif->mate && hwif->mate->dma_base) {
+	else if (hwif->mate && hwif->mate->dma_base) {
 		dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
 	} else {
 		dma_base = (hwif->mmio) ?
diff -urN linux-2.4.22-pre2/drivers/ieee1394/Config.in linux-2.4.22-pre3/drivers/ieee1394/Config.in
--- linux-2.4.22-pre2/drivers/ieee1394/Config.in	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/Config.in	2003-07-05 18:09:59.000000000 -0700
@@ -40,6 +40,7 @@
 	fi
 
 	bool 'Excessive debugging output' CONFIG_IEEE1394_VERBOSEDEBUG
+	bool "OUI Database built-in" CONFIG_IEEE1394_OUI_DB
     fi
     endmenu
 fi
diff -urN linux-2.4.22-pre2/drivers/ieee1394/Makefile linux-2.4.22-pre3/drivers/ieee1394/Makefile
--- linux-2.4.22-pre2/drivers/ieee1394/Makefile	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/Makefile	2003-07-05 18:09:59.000000000 -0700
@@ -8,7 +8,7 @@
 
 list-multi := ieee1394.o
 ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
-		 highlevel.o csr.o nodemgr.o dma.o iso.o
+		 highlevel.o csr.o nodemgr.o oui.o dma.o iso.o
 
 obj-$(CONFIG_IEEE1394) += ieee1394.o
 obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o
@@ -25,3 +25,7 @@
 
 ieee1394.o: $(ieee1394-objs)
 	$(LD) $(LDFLAGS) -r -o $@ $(ieee1394-objs)
+
+oui.o: oui.c
+oui.c: oui.db oui2c.sh
+	$(CONFIG_SHELL) oui2c.sh < oui.db > $@
diff -urN linux-2.4.22-pre2/drivers/ieee1394/amdtp.c linux-2.4.22-pre3/drivers/ieee1394/amdtp.c
--- linux-2.4.22-pre2/drivers/ieee1394/amdtp.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/amdtp.c	2003-07-05 18:09:59.000000000 -0700
@@ -732,7 +732,7 @@
 
 	/* Fill IEEE1394 headers */
 	packet->db->header_desc.header[0] =
-		(SPEED_100 << 16) | (0x01 << 14) | 
+		(IEEE1394_SPEED_100 << 16) | (0x01 << 14) | 
 		(s->iso_channel << 8) | (TCODE_ISO_DATA << 4);
 	packet->db->header_desc.header[1] = size << 16;
 	
diff -urN linux-2.4.22-pre2/drivers/ieee1394/cmp.c linux-2.4.22-pre3/drivers/ieee1394/cmp.c
--- linux-2.4.22-pre2/drivers/ieee1394/cmp.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/cmp.c	2003-07-05 18:09:59.000000000 -0700
@@ -137,7 +137,7 @@
 	}
 
 	ch->host = host;
-	ch->u.ompr.rate = SPEED_100;
+	ch->u.ompr.rate = IEEE1394_SPEED_100;
 	ch->u.ompr.bcast_channel_base = 63;
 	ch->u.ompr.nplugs = 2;
 
diff -urN linux-2.4.22-pre2/drivers/ieee1394/csr.h linux-2.4.22-pre3/drivers/ieee1394/csr.h
--- linux-2.4.22-pre2/drivers/ieee1394/csr.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/csr.h	2003-07-05 18:09:59.000000000 -0700
@@ -2,6 +2,10 @@
 #ifndef _IEEE1394_CSR_H
 #define _IEEE1394_CSR_H
 
+#ifdef CONFIG_PREEMPT
+#include <linux/sched.h>
+#endif
+
 #define CSR_REGISTER_BASE  0xfffff0000000ULL
 
 /* register offsets relative to CSR_REGISTER_BASE */
diff -urN linux-2.4.22-pre2/drivers/ieee1394/dma.c linux-2.4.22-pre3/drivers/ieee1394/dma.c
--- linux-2.4.22-pre2/drivers/ieee1394/dma.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/dma.c	2003-07-05 18:09:59.000000000 -0700
@@ -30,7 +30,7 @@
 	prog->n_pages = n_bytes / PAGE_SIZE;
 
 	prog->kvirt = pci_alloc_consistent(dev, prog->n_pages * PAGE_SIZE, &prog->bus_addr);
-	if(!prog->kvirt) {
+	if (!prog->kvirt) {
 		printk(KERN_ERR "dma_prog_region_alloc: pci_alloc_consistent() failed\n");
 		dma_prog_region_free(prog);
 		return -ENOMEM;
@@ -43,7 +43,7 @@
 
 void dma_prog_region_free(struct dma_prog_region *prog)
 {
-	if(prog->kvirt) {
+	if (prog->kvirt) {
 		pci_free_consistent(prog->dev, prog->n_pages * PAGE_SIZE, prog->kvirt, prog->bus_addr);
 	}
 
@@ -74,7 +74,7 @@
 	n_pages = n_bytes / PAGE_SIZE;
 
 	dma->kvirt = vmalloc_32(n_pages * PAGE_SIZE);
-	if(!dma->kvirt) {
+	if (!dma->kvirt) {
 		printk(KERN_ERR "dma_region_alloc: vmalloc_32() failed\n");
 		goto err;
 	}
@@ -86,7 +86,7 @@
 
 	/* allocate scatter/gather list */
 	dma->sglist = kmalloc(dma->n_pages * sizeof(struct scatterlist), GFP_KERNEL);
-	if(!dma->sglist) {
+	if (!dma->sglist) {
 		printk(KERN_ERR "dma_region_alloc: kmalloc(sglist) failed\n");
 		goto err;
 	}
@@ -95,7 +95,7 @@
 	memset(dma->sglist, 0, dma->n_pages * sizeof(struct scatterlist));
 
 	/* fill scatter/gather list with pages */
-	for(i = 0; i < dma->n_pages; i++) {
+	for (i = 0; i < dma->n_pages; i++) {
 		unsigned long va = (unsigned long) dma->kvirt + i * PAGE_SIZE;
 			
 		dma->sglist[i].page = vmalloc_to_page((void *)va);
@@ -105,7 +105,7 @@
 	/* map sglist to the IOMMU */
 	dma->n_dma_pages = pci_map_sg(dev, &dma->sglist[0], dma->n_pages, direction);
 
-	if(dma->n_dma_pages == 0) {
+	if (dma->n_dma_pages == 0) {
 		printk(KERN_ERR "dma_region_alloc: pci_map_sg() failed\n");
 		goto err;
 	}
@@ -122,18 +122,18 @@
 
 void dma_region_free(struct dma_region *dma)
 {
-	if(dma->n_dma_pages) {
+	if (dma->n_dma_pages) {
 		pci_unmap_sg(dma->dev, dma->sglist, dma->n_pages, dma->direction);
 		dma->n_dma_pages = 0;
 		dma->dev = NULL;
 	}
 
-	if(dma->sglist) {
+	if (dma->sglist) {
 		kfree(dma->sglist);
 		dma->sglist = NULL;
 	}
 
-	if(dma->kvirt) {
+	if (dma->kvirt) {
 		vfree(dma->kvirt);
 		dma->kvirt = NULL;
 		dma->n_pages = 0;
@@ -147,8 +147,8 @@
 	int i;
 	unsigned long off = offset;
 
-	for(i = 0; i < dma->n_dma_pages; i++) {
-		if(off < sg_dma_len(&dma->sglist[i])) {
+	for (i = 0; i < dma->n_dma_pages; i++) {
+		if (off < sg_dma_len(&dma->sglist[i])) {
 			*rem = off;
 			return i;
 		}
@@ -172,7 +172,7 @@
 	int first, last;
 	unsigned long rem;
 
-	if(!len)
+	if (!len)
 		len = 1;
 
 	first = dma_region_find(dma, offset, &rem);
@@ -192,10 +192,10 @@
 
 	struct dma_region *dma = (struct dma_region*) area->vm_private_data;
 
-	if(!dma->kvirt)
+	if (!dma->kvirt)
 		goto out;
 
-	if( (address < (unsigned long) area->vm_start) ||
+	if ( (address < (unsigned long) area->vm_start) ||
 	    (address > (unsigned long) area->vm_start + (PAGE_SIZE * dma->n_pages)) )
 		goto out;
 
@@ -215,16 +215,16 @@
 {
 	unsigned long size;
 
-	if(!dma->kvirt)
+	if (!dma->kvirt)
 		return -EINVAL;
 
 	/* must be page-aligned */
-	if(vma->vm_pgoff != 0)
+	if (vma->vm_pgoff != 0)
 		return -EINVAL;
 
 	/* check the length */
 	size = vma->vm_end - vma->vm_start;
-	if(size > (PAGE_SIZE * dma->n_pages))
+	if (size > (PAGE_SIZE * dma->n_pages))
 		return -EINVAL;
 
 	vma->vm_ops = &dma_region_vm_ops;
diff -urN linux-2.4.22-pre2/drivers/ieee1394/dma.h linux-2.4.22-pre3/drivers/ieee1394/dma.h
--- linux-2.4.22-pre2/drivers/ieee1394/dma.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/dma.h	2003-07-05 18:09:59.000000000 -0700
@@ -76,7 +76,7 @@
 /* round up a number of bytes to be a multiple of the PAGE_SIZE */
 static inline unsigned long round_up_to_page(unsigned long len)
 {
-	if(len % PAGE_SIZE)
+	if (len % PAGE_SIZE)
 		len += PAGE_SIZE - (len % PAGE_SIZE);
 	return len;
 }
diff -urN linux-2.4.22-pre2/drivers/ieee1394/dv1394-private.h linux-2.4.22-pre3/drivers/ieee1394/dv1394-private.h
--- linux-2.4.22-pre2/drivers/ieee1394/dv1394-private.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/dv1394-private.h	2003-07-05 18:09:59.000000000 -0700
@@ -97,7 +97,7 @@
 	omi->q[3] = 0;
 	
 	/* IT packet header */
-	omi->q[4] = cpu_to_le32(  (0x0 << 16)  /* DMA_SPEED_100 */
+	omi->q[4] = cpu_to_le32(  (0x0 << 16)  /* IEEE1394_SPEED_100 */
 				  | (tag << 14)
 				  | (channel << 8)
 				  | (TCODE_ISO_DATA << 4) 
@@ -129,10 +129,10 @@
 	u32 temp = 0;
 	temp |= 1 << 28; /* OUTPUT_LAST */
 
-	if(want_timestamp) /* controller will update timestamp at DMA time */
+	if (want_timestamp) /* controller will update timestamp at DMA time */
 		temp |= 1 << 27;
 
-	if(want_interrupt)
+	if (want_interrupt)
 		temp |= 3 << 20;
 
 	temp |= 3 << 18; /* must take branch */
diff -urN linux-2.4.22-pre2/drivers/ieee1394/dv1394.c linux-2.4.22-pre3/drivers/ieee1394/dv1394.c
--- linux-2.4.22-pre2/drivers/ieee1394/dv1394.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/dv1394.c	2003-07-05 18:09:59.000000000 -0700
@@ -114,7 +114,7 @@
 
 #include "ieee1394.h"
 #include "ieee1394_types.h"
-#include "ieee1394_hotplug.h"
+#include "nodemgr.h"
 #include "hosts.h"
 #include "ieee1394_core.h"
 #include "highlevel.h"	
@@ -209,14 +209,14 @@
 static struct frame* frame_new(unsigned int frame_num, struct video_card *video)
 {
 	struct frame *f = kmalloc(sizeof(*f), GFP_KERNEL);
-	if(!f)
+	if (!f)
 		return NULL;
 
 	f->video = video;
 	f->frame_num = frame_num;
 
 	f->header_pool = pci_alloc_consistent(f->video->ohci->dev, PAGE_SIZE, &f->header_pool_dma);
-	if(!f->header_pool) {
+	if (!f->header_pool) {
 		printk(KERN_ERR "dv1394: failed to allocate CIP header pool\n");
 		kfree(f);
 		return NULL;
@@ -232,7 +232,7 @@
 	f->descriptor_pool = pci_alloc_consistent(f->video->ohci->dev,
 						  f->descriptor_pool_size,
 						  &f->descriptor_pool_dma);
-	if(!f->descriptor_pool) {
+	if (!f->descriptor_pool) {
 		pci_free_consistent(f->video->ohci->dev, PAGE_SIZE, f->header_pool, f->header_pool_dma);
 		kfree(f);
 		return NULL;
@@ -292,12 +292,12 @@
 
 
 
-	if(video->pal_or_ntsc == DV1394_PAL)
+	if (video->pal_or_ntsc == DV1394_PAL)
 		packets_per_frame = DV1394_PAL_PACKETS_PER_FRAME;
 	else
 		packets_per_frame = DV1394_NTSC_PACKETS_PER_FRAME;
 
-	while( full_packets < packets_per_frame ) {
+	while ( full_packets < packets_per_frame ) {
 		empty_packet = first_packet = last_packet = mid_packet = 0;
 
 		data_p = f->data + full_packets * 480;
@@ -308,7 +308,7 @@
 
 		/* note: these should NOT cross a page boundary (DMA restriction) */
 
-		if(f->n_packets >= MAX_PACKETS) {
+		if (f->n_packets >= MAX_PACKETS) {
 			printk(KERN_ERR "dv1394: FATAL ERROR: max packet count exceeded\n");
 			return;
 		}
@@ -324,7 +324,7 @@
 		
 
 		/* the whole CIP pool fits on one page, so no worries about boundaries */
-		if( ((unsigned long) &(f->header_pool[f->n_packets]) - (unsigned long) f->header_pool) 
+		if ( ((unsigned long) &(f->header_pool[f->n_packets]) - (unsigned long) f->header_pool) 
 		    > PAGE_SIZE) {
 			printk(KERN_ERR "dv1394: FATAL ERROR: no room to allocate CIP header\n");
 			return;
@@ -339,7 +339,7 @@
 		
 		/* is this an empty packet? */
 
-		if(video->cip_accum > (video->cip_d - video->cip_n)) {
+		if (video->cip_accum > (video->cip_d - video->cip_n)) {
 			empty_packet = 1;
 			payload_size = 8;
 			video->cip_accum -= (video->cip_d - video->cip_n);
@@ -372,7 +372,7 @@
 				   the timestamp before DMA starts on the next frame.
 		*/
 		
-		if(f->n_packets == 0) {
+		if (f->n_packets == 0) {
 			first_packet = 1;
 		} else if ( full_packets == (packets_per_frame-1) ) {
 			last_packet = 1;
@@ -391,12 +391,12 @@
 		   need a timestamp. */
 
 		/* first packet in the frame needs a timestamp */
-		if(first_packet) {
+		if (first_packet) {
 			f->cip_syt1 = cip;
-			if(empty_packet)
+			if (empty_packet)
 				first_packet_empty = 1;
 
-		} else if(first_packet_empty && (f->n_packets == 1) ) {
+		} else if (first_packet_empty && (f->n_packets == 1) ) {
 			/* if the first packet was empty, the second
 			   packet's CIP header also needs a timestamp */
 			f->cip_syt2 = cip;
@@ -410,7 +410,7 @@
 				0xFFFF /* the timestamp is filled in later */);
 		
 		/* advance counter, only for full packets */
-		if( ! empty_packet )
+		if ( ! empty_packet )
 			video->continuity_counter++;
 
 		/******************************/
@@ -420,7 +420,7 @@
 		/* first descriptor - OUTPUT_MORE_IMMEDIATE, for the controller's IT header */
 		fill_output_more_immediate( &(block->u.out.omi), 1, video->channel, 0, payload_size);
 
-		if(empty_packet) {
+		if (empty_packet) {
 			/* second descriptor - OUTPUT_LAST for CIP header */
 			fill_output_last( &(block->u.out.u.empty.ol),
 
@@ -433,18 +433,18 @@
 					  sizeof(struct CIP_header), /* data size */
 					  cip_dma);
 			
-			if(first_packet)
+			if (first_packet)
 				f->frame_begin_timestamp = &(block->u.out.u.empty.ol.q[3]);
-			else if(mid_packet)
+			else if (mid_packet)
 				f->mid_frame_timestamp = &(block->u.out.u.empty.ol.q[3]);
-			else if(last_packet) {
+			else if (last_packet) {
 				f->frame_end_timestamp = &(block->u.out.u.empty.ol.q[3]);
 				f->frame_end_branch = &(block->u.out.u.empty.ol.q[2]);
 			}
 
 			branch_address = &(block->u.out.u.empty.ol.q[2]);
 			n_descriptors = 3;
-			if(first_packet)
+			if (first_packet)
 				f->first_n_descriptors = n_descriptors;
 
 		} else { /* full packet */
@@ -460,7 +460,7 @@
 			   we need to split it into two DMA descriptors */
 
 			/* does the 480-byte data payload cross a page boundary? */
-			if( (PAGE_SIZE- ((unsigned long)data_p % PAGE_SIZE) ) < 480 ) {
+			if ( (PAGE_SIZE- ((unsigned long)data_p % PAGE_SIZE) ) < 480 ) {
 
 				/* page boundary crossed */
 
@@ -487,11 +487,11 @@
 						  dma_region_offset_to_bus(&video->dv_buf,
 									   data_p + PAGE_SIZE - (data_p % PAGE_SIZE) - (unsigned long) video->dv_buf.kvirt));
 
-				if(first_packet)
+				if (first_packet)
 					f->frame_begin_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]);
-				else if(mid_packet)
+				else if (mid_packet)
 					f->mid_frame_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]);
-				else if(last_packet) {
+				else if (last_packet) {
 					f->frame_end_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]);
 					f->frame_end_branch = &(block->u.out.u.full.u.cross.ol.q[2]);
 				}
@@ -499,7 +499,7 @@
 				branch_address = &(block->u.out.u.full.u.cross.ol.q[2]);
 
 				n_descriptors = 5;
-				if(first_packet)
+				if (first_packet)
 					f->first_n_descriptors = n_descriptors;
 				
 				full_packets++;
@@ -522,11 +522,11 @@
 						  dma_region_offset_to_bus(&video->dv_buf,
 									   data_p - (unsigned long) video->dv_buf.kvirt));
 				
-				if(first_packet)
+				if (first_packet)
 					f->frame_begin_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]);
-				else if(mid_packet)
+				else if (mid_packet)
 					f->mid_frame_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]);
-				else if(last_packet) {
+				else if (last_packet) {
 					f->frame_end_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]);
 					f->frame_end_branch = &(block->u.out.u.full.u.nocross.ol.q[2]);
 				}
@@ -534,7 +534,7 @@
 				branch_address = &(block->u.out.u.full.u.nocross.ol.q[2]);
 
 				n_descriptors = 4;
-				if(first_packet)
+				if (first_packet)
 					f->first_n_descriptors = n_descriptors;
 
 				full_packets++;
@@ -546,7 +546,7 @@
 
 		/* note: we are not linked into the active DMA chain yet */
 
-		if(last_branch_address) {
+		if (last_branch_address) {
 			*(last_branch_address) = cpu_to_le32(block_dma | n_descriptors);
 		}
 
@@ -572,7 +572,7 @@
 	video->n_clear_frames--;
 
 	last_frame = video->first_clear_frame - 1;
-	if(last_frame == -1)
+	if (last_frame == -1)
 		last_frame = video->n_frames-1;
 
 	video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames;
@@ -586,11 +586,11 @@
 		   (unsigned long) f->frame_end_timestamp, 
 		   (unsigned long) f->frame_end_branch);
 	
-	if(video->active_frame != -1) {
+	if (video->active_frame != -1) {
 
 		/* if DMA is already active, we are almost done */
 		/* just link us onto the active DMA chain */
-		if(video->frames[last_frame]->frame_end_branch) {
+		if (video->frames[last_frame]->frame_end_branch) {
 			u32 temp;
 
 			/* point the previous frame's tail to this frame's head */
@@ -658,11 +658,11 @@
 		f->assigned_timestamp = (ts_cyc&0xF) << 12;
 
 		/* now actually write the timestamp into the appropriate CIP headers */
-		if(f->cip_syt1) {
+		if (f->cip_syt1) {
 			f->cip_syt1->b[6] = f->assigned_timestamp >> 8;
 			f->cip_syt1->b[7] = f->assigned_timestamp & 0xFF;
 		}
-		if(f->cip_syt2) {
+		if (f->cip_syt2) {
 			f->cip_syt2->b[6] = f->assigned_timestamp >> 8;
 			f->cip_syt2->b[7] = f->assigned_timestamp & 0xFF;
 		}
@@ -714,10 +714,10 @@
 		{
 			/* check if DMA is really running */
 			int i = 0;
-			while(i < 20) {
+			while (i < 20) {
 				mb();
 				mdelay(1);
-				if(reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) {
+				if (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) {
 					printk("DMA ACTIVE after %d msec\n", i);
 					break;
 				}
@@ -729,7 +729,7 @@
 			       reg_read(video->ohci, video->ohci_IsoXmitCommandPtr)
 			       );
 			
-			if( ! (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) &  (1 << 10)) ) {
+			if ( ! (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) &  (1 << 10)) ) {
 				printk("DMA did NOT go active after 20ms, event = %x\n", 
 				       reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & 0x1F);
 			} else
@@ -829,14 +829,14 @@
 		{
 			int i;
 		
-			for(i = 0; i < 1000; ++i) {
+			for (i = 0; i < 1000; ++i) {
 				mdelay(1);
-				if(reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) {
+				if (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) {
 					printk("DMA ACTIVE after %d msec\n", i);
 					break;
 				}
 			}
-			if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) &  (1 << 11) ) {
+			if ( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) &  (1 << 11) ) {
 				printk("DEAD, event = %x\n", 
 					   reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F);
 			} else
@@ -844,7 +844,7 @@
 		}
 #endif
 	} 
-	else if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) &  (1 << 11) ) {
+	else if ( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) &  (1 << 11) ) {
 		debug_printk("DEAD, event = %x\n", 
 			     reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F);
 
@@ -920,36 +920,36 @@
 	int retval = -EINVAL;
 
 	debug_printk("dv1394: initialising %d\n", video->id);
-	if(init->api_version != DV1394_API_VERSION)
+	if (init->api_version != DV1394_API_VERSION)
 		return -EINVAL;
 	
 	/* first sanitize all the parameters */
-	if( (init->n_frames < 2) || (init->n_frames > DV1394_MAX_FRAMES) )
+	if ( (init->n_frames < 2) || (init->n_frames > DV1394_MAX_FRAMES) )
 		return -EINVAL;
 
-	if( (init->format != DV1394_NTSC) && (init->format != DV1394_PAL) )
+	if ( (init->format != DV1394_NTSC) && (init->format != DV1394_PAL) )
 		return -EINVAL;
 
-	if( (init->syt_offset == 0) || (init->syt_offset > 50) )
+	if ( (init->syt_offset == 0) || (init->syt_offset > 50) )
 		/* default SYT offset is 3 cycles */
 		init->syt_offset = 3;
 
-	if( (init->channel > 63) || (init->channel < 0) )
+	if ( (init->channel > 63) || (init->channel < 0) )
 		init->channel = 63;
 
 	chan_mask = (u64)1 << init->channel;
 
 	/* calculate what size DMA buffer is needed */
-	if(init->format == DV1394_NTSC)
+	if (init->format == DV1394_NTSC)
 		new_buf_size = DV1394_NTSC_FRAME_SIZE * init->n_frames;
 	else
 		new_buf_size = DV1394_PAL_FRAME_SIZE * init->n_frames;
 
 	/* round up to PAGE_SIZE */
-	if(new_buf_size % PAGE_SIZE) new_buf_size += PAGE_SIZE - (new_buf_size % PAGE_SIZE);
+	if (new_buf_size % PAGE_SIZE) new_buf_size += PAGE_SIZE - (new_buf_size % PAGE_SIZE);
 
 	/* don't allow the user to allocate the DMA buffer more than once */
-	if(video->dv_buf.kvirt && video->dv_buf_size != new_buf_size) {
+	if (video->dv_buf.kvirt && video->dv_buf_size != new_buf_size) {
 		printk("dv1394: re-sizing the DMA buffer is not allowed\n");
 		return -EINVAL;
 	}
@@ -961,7 +961,7 @@
 	
 	/* try to claim the ISO channel */
 	spin_lock_irqsave(&video->ohci->IR_channel_lock, flags);
-	if(video->ohci->ISO_channel_usage & chan_mask) {
+	if (video->ohci->ISO_channel_usage & chan_mask) {
 		spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags);
 		retval = -EBUSY;
 		goto err;
@@ -989,7 +989,7 @@
 	video->current_packet = -1;
 	video->first_frame = 0;
 
-	if(video->pal_or_ntsc == DV1394_NTSC) {
+	if (video->pal_or_ntsc == DV1394_NTSC) {
 		video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_NTSC;
 		video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_NTSC;
 		video->frame_size = DV1394_NTSC_FRAME_SIZE;
@@ -1003,7 +1003,7 @@
 	
 	/* find and claim DMA contexts on the OHCI card */
 
-	if(video->ohci_it_ctx == -1) {
+	if (video->ohci_it_ctx == -1) {
 		ohci1394_init_iso_tasklet(&video->it_tasklet, OHCI_ISO_TRANSMIT,
 					  it_tasklet_func, (unsigned long) video);
 
@@ -1017,7 +1017,7 @@
 		debug_printk("dv1394: claimed IT DMA context %d\n", video->ohci_it_ctx);
 	}
 
-	if(video->ohci_ir_ctx == -1) {
+	if (video->ohci_ir_ctx == -1) {
 		ohci1394_init_iso_tasklet(&video->ir_tasklet, OHCI_ISO_RECEIVE,
 					  ir_tasklet_func, (unsigned long) video);
 
@@ -1031,20 +1031,20 @@
 	}
 	
 	/* allocate struct frames */
-	for(i = 0; i < init->n_frames; i++) {
+	for (i = 0; i < init->n_frames; i++) {
 		video->frames[i] = frame_new(i, video);
 
-		if(!video->frames[i]) {
+		if (!video->frames[i]) {
 			printk(KERN_ERR "dv1394: Cannot allocate frame structs\n");
 			retval = -ENOMEM;
 			goto err;
 		}
 	}
 
-	if(!video->dv_buf.kvirt) {
+	if (!video->dv_buf.kvirt) {
 		/* allocate the ringbuffer */
 		retval = dma_region_alloc(&video->dv_buf, new_buf_size, video->ohci->dev, PCI_DMA_TODEVICE);
-		if(retval)
+		if (retval)
 			goto err;
 					  
 		video->dv_buf_size = new_buf_size;
@@ -1055,10 +1055,10 @@
 	}
 	
 	/* set up the frame->data pointers */
-	for(i = 0; i < video->n_frames; i++)
+	for (i = 0; i < video->n_frames; i++)
 		video->frames[i]->data = (unsigned long) video->dv_buf.kvirt + i * video->frame_size;
 
-	if(!video->packet_buf.kvirt) {
+	if (!video->packet_buf.kvirt) {
 		/* allocate packet buffer */
 		video->packet_buf_size = sizeof(struct packet) * video->n_frames * MAX_PACKETS;
 		if (video->packet_buf_size % PAGE_SIZE)
@@ -1066,7 +1066,7 @@
 		
 		retval = dma_region_alloc(&video->packet_buf, video->packet_buf_size,
 					  video->ohci->dev, PCI_DMA_FROMDEVICE);
-		if(retval)
+		if (retval)
 			goto err;
 		
 		debug_printk("dv1394: Allocated %d packets in buffer, total %u pages (%u DMA pages), %lu bytes\n", 
@@ -1132,11 +1132,11 @@
 
 	video->dma_running = 0;
 
-	if( (video->ohci_it_ctx == -1) && (video->ohci_ir_ctx == -1) )
+	if ( (video->ohci_it_ctx == -1) && (video->ohci_ir_ctx == -1) )
 		goto out;
 
 	/* stop DMA if in progress */
-	if( (video->active_frame != -1) ||
+	if ( (video->active_frame != -1) ||
 	    (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) ||
 	    (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) &  (1 << 10)) ) {
 
@@ -1150,12 +1150,12 @@
 		
 		/* wait until DMA really stops */
 		i = 0;
-		while(i < 1000) {
+		while (i < 1000) {
 				
 			/* wait 0.1 millisecond */
 			udelay(100); 
 			
-			if( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) ||
+			if ( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) ||
 			    (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear)  & (1 << 10)) ) {
 				/* still active */
 				debug_printk("dv1394: stop_dma: DMA not stopped yet\n" );
@@ -1168,7 +1168,7 @@
 			i++;
 		}
 			
-		if(i == 1000) {
+		if (i == 1000) {
 			printk(KERN_ERR "dv1394: stop_dma: DMA still going after %d ms!\n", i/10);
 		}
 	}
@@ -1191,7 +1191,7 @@
 	stop_dma(video);
 	
 	/* release the DMA contexts */
-	if(video->ohci_it_ctx != -1) {
+	if (video->ohci_it_ctx != -1) {
 		video->ohci_IsoXmitContextControlSet = 0;
 		video->ohci_IsoXmitContextControlClear = 0;
 		video->ohci_IsoXmitCommandPtr = 0;
@@ -1205,7 +1205,7 @@
 		video->ohci_it_ctx = -1;
 	}
 
-	if(video->ohci_ir_ctx != -1) {
+	if (video->ohci_ir_ctx != -1) {
 		video->ohci_IsoRcvContextControlSet = 0;
 		video->ohci_IsoRcvContextControlClear = 0;
 		video->ohci_IsoRcvCommandPtr = 0;
@@ -1221,7 +1221,7 @@
 	}
 
 	/* release the ISO channel */
-	if(video->channel != -1) {
+	if (video->channel != -1) {
 		u64 chan_mask;
 		unsigned long flags;
 		
@@ -1235,8 +1235,8 @@
 	}
 	
 	/* free the frame structs */
-	for(i = 0; i < DV1394_MAX_FRAMES; i++) {
-		if(video->frames[i])
+	for (i = 0; i < DV1394_MAX_FRAMES; i++) {
+		if (video->frames[i])
 			frame_delete(video->frames[i]);
 		video->frames[i] = NULL;
 	}
@@ -1246,7 +1246,7 @@
 	/* we can't free the DMA buffer unless it is guaranteed that
 	   no more user-space mappings exist */
 	
-	if(free_dv_buf) {
+	if (free_dv_buf) {
 		dma_region_free(&video->dv_buf);
 		video->dv_buf_size = 0;
 	}
@@ -1290,9 +1290,9 @@
 	/* serialize mmap */
 	down(&video->sem);
 
-	if( ! video_card_initialized(video) ) {
+	if ( ! video_card_initialized(video) ) {
 		retval = do_dv1394_init_default(video);
-		if(retval)
+		if (retval)
 			goto out;
 	}
 
@@ -1314,14 +1314,14 @@
 	poll_wait(file, &video->waitq, wait);
 
 	spin_lock_irqsave(&video->spinlock, flags);
-	if( video->n_frames == 0 ) {
+	if ( video->n_frames == 0 ) {
 
-	} else if( video->active_frame == -1 ) {
+	} else if ( video->active_frame == -1 ) {
 		/* nothing going on */
 		mask |= POLLOUT;
 	} else {
 		/* any clear/ready buffers? */
-		if(video->n_clear_frames >0)
+		if (video->n_clear_frames >0)
 			mask |= POLLOUT | POLLIN;
 	}
 	spin_unlock_irqrestore(&video->spinlock, flags);
@@ -1353,17 +1353,17 @@
 	int target_frame;
 
 	/* serialize this to prevent multi-threaded mayhem */
-	if(file->f_flags & O_NONBLOCK) {
-		if(down_trylock(&video->sem))
+	if (file->f_flags & O_NONBLOCK) {
+		if (down_trylock(&video->sem))
 			return -EAGAIN;
 	} else {
-		if(down_interruptible(&video->sem))
+		if (down_interruptible(&video->sem))
 			return -ERESTARTSYS;
 	}
 
-	if( !video_card_initialized(video) ) {
+	if ( !video_card_initialized(video) ) {
 		ret = do_dv1394_init_default(video);
-		if(ret) {
+		if (ret) {
 			up(&video->sem);
 			return ret;
 		}
@@ -1372,7 +1372,7 @@
 	ret = 0;
 	add_wait_queue(&video->waitq, &wait);
 	
-	while(count > 0) {
+	while (count > 0) {
 
 		/* must set TASK_INTERRUPTIBLE *before* checking for free
 		   buffers; otherwise we could miss a wakeup if the interrupt
@@ -1386,7 +1386,7 @@
 		
 		spin_unlock_irqrestore(&video->spinlock, flags);
 
-		if(video->frames[target_frame]->state == FRAME_CLEAR) {
+		if (video->frames[target_frame]->state == FRAME_CLEAR) {
 
 			/* how much room is left in the target frame buffer */
 			cnt = video->frame_size - (video->write_off - target_frame * video->frame_size);
@@ -1396,12 +1396,12 @@
 			cnt = 0;
 		}
 
-		if(cnt > count)
+		if (cnt > count)
 			cnt = count;
 
 		if (cnt <= 0) { 
 			/* no room left, gotta wait */
-			if(file->f_flags & O_NONBLOCK) {
+			if (file->f_flags & O_NONBLOCK) {
 				if (!ret)
 					ret = -EAGAIN;
 				break;
@@ -1417,8 +1417,8 @@
 			continue; /* start over from 'while(count > 0)...' */
 		}
 
-		if(copy_from_user(video->dv_buf.kvirt + video->write_off, buffer, cnt)) {
-			if(!ret)
+		if (copy_from_user(video->dv_buf.kvirt + video->write_off, buffer, cnt)) {
+			if (!ret)
 				ret = -EFAULT;
 			break;
 		}
@@ -1429,7 +1429,7 @@
 		buffer += cnt;
 		ret += cnt;
 
-		if(video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames))
+		if (video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames))
 				frame_prepare(video, target_frame);
 	}
 	
@@ -1450,17 +1450,17 @@
 	int target_frame;
 
 	/* serialize this to prevent multi-threaded mayhem */
-	if(file->f_flags & O_NONBLOCK) {
-		if(down_trylock(&video->sem))
+	if (file->f_flags & O_NONBLOCK) {
+		if (down_trylock(&video->sem))
 			return -EAGAIN;
 	} else {
-		if(down_interruptible(&video->sem))
+		if (down_interruptible(&video->sem))
 			return -ERESTARTSYS;
 	}
 
-	if( !video_card_initialized(video) ) {
+	if ( !video_card_initialized(video) ) {
 		ret = do_dv1394_init_default(video);
-		if(ret) {
+		if (ret) {
 			up(&video->sem);
 			return ret;
 		}
@@ -1474,7 +1474,7 @@
 	ret = 0;
 	add_wait_queue(&video->waitq, &wait);
 
-	while(count > 0) {
+	while (count > 0) {
 
 		/* must set TASK_INTERRUPTIBLE *before* checking for free
 		   buffers; otherwise we could miss a wakeup if the interrupt
@@ -1488,7 +1488,7 @@
 
 		spin_unlock_irqrestore(&video->spinlock, flags);
 
-		if(target_frame >= 0 &&
+		if (target_frame >= 0 &&
 			video->n_clear_frames > 0 &&
 			video->frames[target_frame]->state == FRAME_CLEAR) {
 
@@ -1500,12 +1500,12 @@
 			cnt = 0;
 		}
 
-		if(cnt > count)
+		if (cnt > count)
 			cnt = count;
 
 		if (cnt <= 0) { 
 			/* no room left, gotta wait */
-			if(file->f_flags & O_NONBLOCK) {
+			if (file->f_flags & O_NONBLOCK) {
 				if (!ret)
 					ret = -EAGAIN;
 				break;
@@ -1521,8 +1521,8 @@
 			continue; /* start over from 'while(count > 0)...' */
 		}
 
-		if(copy_to_user(buffer, video->dv_buf.kvirt + video->write_off, cnt)) {
-				if(!ret)
+		if (copy_to_user(buffer, video->dv_buf.kvirt + video->write_off, cnt)) {
+				if (!ret)
 					ret = -EFAULT;
 				break;
 		}
@@ -1533,7 +1533,7 @@
 		buffer += cnt;
 		ret += cnt;
 
-		if(video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) {
+		if (video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) {
 			spin_lock_irqsave(&video->spinlock, flags);
 			video->n_clear_frames--;
 			video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames;
@@ -1563,11 +1563,11 @@
 	DECLARE_WAITQUEUE(wait, current);
 
 	/* serialize this to prevent multi-threaded mayhem */
-	if(file->f_flags & O_NONBLOCK) {
-		if(down_trylock(&video->sem))
+	if (file->f_flags & O_NONBLOCK) {
+		if (down_trylock(&video->sem))
 			return -EAGAIN;
 	} else {
-		if(down_interruptible(&video->sem))
+		if (down_interruptible(&video->sem))
 			return -ERESTARTSYS;
 	}
 
@@ -1577,20 +1577,20 @@
 	case DV1394_IOC_SUBMIT_FRAMES: {
 		unsigned int n_submit;
 
-		if( !video_card_initialized(video) ) {
+		if ( !video_card_initialized(video) ) {
 			ret = do_dv1394_init_default(video);
-			if(ret)
+			if (ret)
 				goto out;
 		}
 
 		n_submit = (unsigned int) arg;
 
-		if(n_submit > video->n_frames) {
+		if (n_submit > video->n_frames) {
 			ret = -EINVAL;
 			goto out;
 		}
 			
-		while(n_submit > 0) {
+		while (n_submit > 0) {
 
 			add_wait_queue(&video->waitq, &wait);
 			set_current_state(TASK_INTERRUPTIBLE);
@@ -1598,11 +1598,11 @@
 			spin_lock_irqsave(&video->spinlock, flags);
 
 			/* wait until video->first_clear_frame is really CLEAR */
-			while(video->frames[video->first_clear_frame]->state != FRAME_CLEAR) {
+			while (video->frames[video->first_clear_frame]->state != FRAME_CLEAR) {
 
 				spin_unlock_irqrestore(&video->spinlock, flags);
 					
-				if(signal_pending(current)) {
+				if (signal_pending(current)) {
 					remove_wait_queue(&video->waitq, &wait);
 					set_current_state(TASK_RUNNING);
 					ret = -EINTR;
@@ -1631,7 +1631,7 @@
 	case DV1394_IOC_WAIT_FRAMES: {
 		unsigned int n_wait;
 
-		if( !video_card_initialized(video) ) {
+		if ( !video_card_initialized(video) ) {
 			ret = -EINVAL;
 			goto out;
 		}
@@ -1642,7 +1642,7 @@
 		   never actually have n_frames clear frames; at most only
 		   n_frames - 1 */
 
-		if(n_wait > (video->n_frames-1) ) {
+		if (n_wait > (video->n_frames-1) ) {
 			ret = -EINVAL;
 			goto out;
 		}
@@ -1652,11 +1652,11 @@
 		
 		spin_lock_irqsave(&video->spinlock, flags);
 
-		while(video->n_clear_frames < n_wait) {
+		while (video->n_clear_frames < n_wait) {
 			
 			spin_unlock_irqrestore(&video->spinlock, flags);
 					
-			if(signal_pending(current)) {
+			if (signal_pending(current)) {
 				remove_wait_queue(&video->waitq, &wait);
 				set_current_state(TASK_RUNNING);
 				ret = -EINTR;
@@ -1680,7 +1680,7 @@
 	case DV1394_IOC_RECEIVE_FRAMES: {
 		unsigned int n_recv;
 
-		if( !video_card_initialized(video) ) {
+		if ( !video_card_initialized(video) ) {
 			ret = -EINVAL;
 			goto out;
 		}
@@ -1688,7 +1688,7 @@
 		n_recv = (unsigned int) arg;
 
 		/* at least one frame must be active */
-		if(n_recv > (video->n_frames-1) ) {
+		if (n_recv > (video->n_frames-1) ) {
 			ret = -EINVAL;
 			goto out;
 		}
@@ -1711,9 +1711,9 @@
 	}
 	case DV1394_START_RECEIVE:
 	case DV1394_IOC_START_RECEIVE: {
-		if( !video_card_initialized(video) ) {
+		if ( !video_card_initialized(video) ) {
 			ret = do_dv1394_init_default(video);
-			if(ret)
+			if (ret)
 				goto out;
 		}
 	
@@ -1729,10 +1729,10 @@
 	case DV1394_INIT:
 	case DV1394_IOC_INIT: {
 		struct dv1394_init init;
-		if(arg == (unsigned long) NULL) {
+		if (arg == (unsigned long) NULL) {
 			ret = do_dv1394_init_default(video);
 		} else {
-			if(copy_from_user(&init, (void*)arg, sizeof(init))) {
+			if (copy_from_user(&init, (void*)arg, sizeof(init))) {
 				ret = -EFAULT;
 				goto out;
 			}
@@ -1750,7 +1750,7 @@
         case DV1394_IOC_GET_STATUS: {
 		struct dv1394_status status;
 
-		if( !video_card_initialized(video) ) {
+		if ( !video_card_initialized(video) ) {
 			ret = -EINVAL;
 			goto out;
 		}
@@ -1778,7 +1778,7 @@
 			
 		spin_unlock_irqrestore(&video->spinlock, flags);
 
-		if(copy_to_user((void*)arg, &status, sizeof(status))) {
+		if (copy_to_user((void*)arg, &status, sizeof(status))) {
 			ret = -EFAULT;
 			goto out;
 		}
@@ -1806,7 +1806,7 @@
 
 	/* if the device was opened through devfs, then file->private_data
 	   has already been set to video by devfs */
-	if(file->private_data) {
+	if (file->private_data) {
 		video = (struct video_card*) file->private_data;
 		
 	} else {
@@ -1816,11 +1816,11 @@
 		unsigned long flags;
 		
 		spin_lock_irqsave(&dv1394_cards_lock, flags);
-		if(!list_empty(&dv1394_cards)) {
+		if (!list_empty(&dv1394_cards)) {
 			struct video_card *p;
 			list_for_each(lh, &dv1394_cards) {
 				p = list_entry(lh, struct video_card, list);
-				if((p->id) == ieee1394_file_to_instance(file)) {
+				if ((p->id) == ieee1394_file_to_instance(file)) {
 					video = p;
 					break;
 				}
@@ -1828,7 +1828,7 @@
 		}
 		spin_unlock_irqrestore(&dv1394_cards_lock, flags);
 
-		if(!video) {
+		if (!video) {
 			debug_printk("dv1394: OHCI card %d not found", ieee1394_file_to_instance(file));
 			return -ENODEV;
 		}
@@ -1838,7 +1838,7 @@
 	
 #ifndef DV1394_ALLOW_MORE_THAN_ONE_OPEN
 
-	if( test_and_set_bit(0, &video->open) ) {
+	if ( test_and_set_bit(0, &video->open) ) {
 		/* video is already open by someone else */
 		return -EBUSY;
  	}
@@ -1980,10 +1980,10 @@
 	struct dv1394_procfs_entry *p;
 		
 	spin_lock( &dv1394_procfs_lock);
-	if(!list_empty(&dv1394_procfs)) {
+	if (!list_empty(&dv1394_procfs)) {
 		list_for_each(lh, &dv1394_procfs) {
 			p = list_entry(lh, struct dv1394_procfs_entry, list);
-			if(!strncmp(p->name, name, sizeof(p->name))) {
+			if (!strncmp(p->name, name, sizeof(p->name))) {
 				spin_unlock( &dv1394_procfs_lock);
 				return p;
 			}
@@ -2000,7 +2000,7 @@
 	struct dv1394_procfs_entry *parent;
 
 	p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL);
-	if(!p) {
+	if (!p) {
 		printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n");
 		goto err;
 	}
@@ -2052,7 +2052,7 @@
 	struct dv1394_procfs_entry *p;
 
 	p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL);
-	if(!p) {
+	if (!p) {
 		printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n");
 		goto err;
 	}
@@ -2113,7 +2113,7 @@
 
 	spin_lock(&video->spinlock);
 
-	if(!video->dma_running)
+	if (!video->dma_running)
 		goto out;
 
 	irq_printk("ContextControl = %08x, CommandPtr = %08x\n", 
@@ -2122,24 +2122,24 @@
 	       );
 
 	
-	if( (video->ohci_it_ctx != -1) &&
+	if ( (video->ohci_it_ctx != -1) &&
 	    (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) {
 
 		struct frame *f;
 		unsigned int frame, i;
 
 		
-		if(video->active_frame == -1)
+		if (video->active_frame == -1)
 			frame = 0;
 		else
 			frame = video->active_frame;
 
 		/* check all the DMA-able frames */
-		for(i = 0; i < video->n_frames; i++, frame = (frame+1) % video->n_frames) {
+		for (i = 0; i < video->n_frames; i++, frame = (frame+1) % video->n_frames) {
 
 			irq_printk("IRQ checking frame %d...", frame);
 			f = video->frames[frame];
-			if(f->state != FRAME_READY) {
+			if (f->state != FRAME_READY) {
 				irq_printk("clear, skipping\n");
 				/* we don't own this frame */
 				continue;
@@ -2148,7 +2148,7 @@
 			irq_printk("DMA\n");
 
 			/* check the frame begin semaphore to see if we can free the previous frame */
-			if( *(f->frame_begin_timestamp) ) {
+			if ( *(f->frame_begin_timestamp) ) {
 				int prev_frame;
 				struct frame *prev_f;
 
@@ -2158,13 +2158,13 @@
 				irq_printk("  BEGIN\n");
 
 				prev_frame = frame - 1;
-				if(prev_frame == -1)
+				if (prev_frame == -1)
 					prev_frame += video->n_frames;
 				prev_f = video->frames[prev_frame];
 				
 				/* make sure we can actually garbage collect
 				   this frame */
-				if( (prev_f->state == FRAME_READY) &&
+				if ( (prev_f->state == FRAME_READY) &&
 				    prev_f->done && (!f->done) ) 
 				{
 					frame_reset(prev_f);
@@ -2182,7 +2182,7 @@
 
 		     
 			/* see if we need to set the timestamp for the next frame */
-			if( *(f->mid_frame_timestamp) ) {
+			if ( *(f->mid_frame_timestamp) ) {
 				struct frame *next_frame;
 				u32 begin_ts, ts_cyc, ts_off;
 
@@ -2197,7 +2197,7 @@
 				/* prepare next frame and assign timestamp */
 				next_frame = video->frames[ (frame+1) % video->n_frames ];
 
-				if(next_frame->state == FRAME_READY) {
+				if (next_frame->state == FRAME_READY) {
 					irq_printk("  MIDDLE - next frame is ready, good\n");
 				} else {
 					debug_printk("dv1394: Underflow! At least one frame has been dropped.\n");
@@ -2216,11 +2216,11 @@
 				ts_off %= 3072;
 
 				next_frame->assigned_timestamp = ((ts_cyc&0xF) << 12) + ts_off;
-				if(next_frame->cip_syt1) {
+				if (next_frame->cip_syt1) {
 					next_frame->cip_syt1->b[6] = next_frame->assigned_timestamp >> 8;
 					next_frame->cip_syt1->b[7] = next_frame->assigned_timestamp & 0xFF;
 				}
-				if(next_frame->cip_syt2) {
+				if (next_frame->cip_syt2) {
 					next_frame->cip_syt2->b[6] = next_frame->assigned_timestamp >> 8;
 					next_frame->cip_syt2->b[7] = next_frame->assigned_timestamp & 0xFF;
 				}
@@ -2228,7 +2228,7 @@
 			}
 
 			/* see if the frame looped */
-			if( *(f->frame_end_timestamp) ) {
+			if ( *(f->frame_end_timestamp) ) {
 
 				*(f->frame_end_timestamp) = 0;
 
@@ -2239,10 +2239,10 @@
 
 
 		
-		} /* for(each frame) */
+		} /* for (each frame) */
 	}
 
-	if(wake) {
+	if (wake) {
 		kill_fasync(&video->fasync, SIGIO, POLL_OUT);
 		
 		/* wake readers/writers/ioctl'ers */
@@ -2260,10 +2260,10 @@
 
 	spin_lock(&video->spinlock);
 
-	if(!video->dma_running)
+	if (!video->dma_running)
 		goto out;
 	
-	if( (video->ohci_ir_ctx != -1) &&
+	if ( (video->ohci_ir_ctx != -1) &&
 	    (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) )
 	{ 
 
@@ -2298,16 +2298,15 @@
 			/* get the descriptor based on packet_buffer cursor */
 			f = video->frames[video->current_packet / MAX_PACKETS];
 			block = &(f->descriptor_pool[video->current_packet % MAX_PACKETS]);
-			xferstatus = le16_to_cpu(block->u.in.il.q[3] >> 16);
+			xferstatus = le32_to_cpu(block->u.in.il.q[3]) >> 16;
 			xferstatus &= 0x1F;
+			irq_printk("ir_tasklet_func: xferStatus/resCount [%d] = 0x%08x\n", i, le32_to_cpu(block->u.in.il.q[3]) );
 
 			/* get the current frame */
 			f = video->frames[video->active_frame];
 		
 			/* exclude empty packet */
 			if (packet_length > 8 && xferstatus == 0x11) {
-				irq_printk("ir_tasklet_func: xferStatus/resCount [%d] = 0x%08x\n", i, le32_to_cpu(block->u.in.il.q[3]) );
-			
 				/* check for start of frame */
 				/* DRD> Changed to check section type ([0]>>5==0) 
 				   and dif sequence ([1]>>4==0) */
@@ -2384,12 +2383,12 @@
 			prev_i = (next_i == 0) ? (MAX_PACKETS * video->n_frames - 1) : (next_i - 1);
 			f = video->frames[prev_i / MAX_PACKETS];
 			prev = &(f->descriptor_pool[prev_i % MAX_PACKETS]);
-			if(prev_i % (MAX_PACKETS/2)) {
+			if (prev_i % (MAX_PACKETS/2)) {
 				prev->u.in.il.q[0] &= ~(3 << 20); /* no interrupt */
 			} else {
 				prev->u.in.il.q[0] |= 3 << 20; /* enable interrupt */
 			}
-			prev->u.in.il.q[2] =  (cpu_to_le32(next_dma) | 1); /* set Z=1 */
+			prev->u.in.il.q[2] = cpu_to_le32(next_dma | 1); /* set Z=1 */
 			wmb();
 
 			/* wake up DMA in case it fell asleep */
@@ -2404,7 +2403,7 @@
 		
 	} /* receive interrupt */
 	
-	if(wake) {
+	if (wake) {
 		kill_fasync(&video->fasync, SIGIO, POLL_IN);
 
 		/* wake readers/writers/ioctl'ers */
@@ -2438,10 +2437,10 @@
 	struct dv1394_devfs_entry *p;
 
 	spin_lock( &dv1394_devfs_lock);
-	if(!list_empty(&dv1394_devfs)) {
+	if (!list_empty(&dv1394_devfs)) {
 		list_for_each(lh, &dv1394_devfs) {
 			p = list_entry(lh, struct dv1394_devfs_entry, list);
-			if(!strncmp(p->name, name, sizeof(p->name))) {
+			if (!strncmp(p->name, name, sizeof(p->name))) {
 				goto found;
 			}
 		}
@@ -2461,7 +2460,7 @@
 	struct dv1394_devfs_entry *parent;
 
 	p = kmalloc(sizeof(struct dv1394_devfs_entry), GFP_KERNEL);
-	if(!p) {
+	if (!p) {
 		printk(KERN_ERR "dv1394: cannot allocate dv1394_devfs_entry\n");
 		goto err;
 	}
@@ -2515,7 +2514,7 @@
 	struct dv1394_devfs_entry *p;
 
 	p = kmalloc(sizeof(struct dv1394_devfs_entry), GFP_KERNEL);
-	if(!p) {
+	if (!p) {
 		printk(KERN_ERR "dv1394: cannot allocate dv1394_devfs_entry\n");
 		goto err;
 	}
@@ -2594,7 +2593,7 @@
 	int i;
 
 	video = kmalloc(sizeof(struct video_card), GFP_KERNEL);
-	if(!video) {
+	if (!video) {
 		printk(KERN_ERR "dv1394: cannot allocate video_card\n");
 		goto err;
 	}
@@ -2638,7 +2637,7 @@
 		goto err_free;
 #endif
 
-	for(i = 0; i < DV1394_MAX_FRAMES; i++)
+	for (i = 0; i < DV1394_MAX_FRAMES; i++)
 		video->frames[i] = NULL;
 
 	dma_region_init(&video->dv_buf);
@@ -2712,10 +2711,10 @@
 
 	/* find the corresponding video_cards */
 	spin_lock_irqsave(&dv1394_cards_lock, flags);
-	if(!list_empty(&dv1394_cards)) {
+	if (!list_empty(&dv1394_cards)) {
 		list_for_each_safe(lh, templh, &dv1394_cards) {
 			video = list_entry(lh, struct video_card, list);
-			if((video->id >> 2) == ohci->id)
+			if ((video->id >> 2) == ohci->id)
 				dv1394_un_init(video);
 		}
 	}
@@ -2805,32 +2804,32 @@
 
 	/* find the corresponding video_cards */
 	spin_lock_irqsave(&dv1394_cards_lock, flags);
-	if(!list_empty(&dv1394_cards)) {
+	if (!list_empty(&dv1394_cards)) {
 		list_for_each(lh, &dv1394_cards) {
 			video = list_entry(lh, struct video_card, list);
-			if((video->id >> 2) == ohci->id)
+			if ((video->id >> 2) == ohci->id)
 				break;
 		}
 	}
 	spin_unlock_irqrestore(&dv1394_cards_lock, flags);
 
-	if(!video)
+	if (!video)
 		return;
 
 	
 	spin_lock_irqsave(&video->spinlock, flags);
 
-	if(!video->dma_running)
+	if (!video->dma_running)
 		goto out;
 
 	/* check IT context */
-	if(video->ohci_it_ctx != -1) {
+	if (video->ohci_it_ctx != -1) {
 		u32 ctx;
 		
 		ctx = reg_read(video->ohci, video->ohci_IsoXmitContextControlSet);
 
-		/* if(RUN but not ACTIVE) */
-		if( (ctx & (1<<15)) &&
+		/* if (RUN but not ACTIVE) */
+		if ( (ctx & (1<<15)) &&
 		    !(ctx & (1<<10)) ) {
 
 			debug_printk("dv1394: IT context stopped due to bus reset; waking it up\n");
@@ -2860,13 +2859,13 @@
 	}
 	
 	/* check IR context */
-	if(video->ohci_ir_ctx != -1) {
+	if (video->ohci_ir_ctx != -1) {
 		u32 ctx;
 		
 		ctx = reg_read(video->ohci, video->ohci_IsoRcvContextControlSet);
 
-		/* if(RUN but not ACTIVE) */
-		if( (ctx & (1<<15)) &&
+		/* if (RUN but not ACTIVE) */
+		if ( (ctx & (1<<15)) &&
 		    !(ctx & (1<<10)) ) {
 
 			debug_printk("dv1394: IR context stopped due to bus reset; waking it up\n");
diff -urN linux-2.4.22-pre2/drivers/ieee1394/dv1394.h linux-2.4.22-pre3/drivers/ieee1394/dv1394.h
--- linux-2.4.22-pre2/drivers/ieee1394/dv1394.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/dv1394.h	2003-07-05 18:09:59.000000000 -0700
@@ -64,7 +64,7 @@
 
 	   ioctl(fd, DV1394_INIT, &init);
 
-	   while(1) {
+	   while (1) {
 	          read( <a raw DV file>, buf, DV1394_NTSC_FRAME_SIZE );
 		  write( <the dv1394 FD>, buf, DV1394_NTSC_FRAME_SIZE );
            }
@@ -145,7 +145,7 @@
    (checks of system call return values omitted for brevity; always
    check return values in your code!)
    
-   while( frames left ) {
+   while ( frames left ) {
    
     struct pollfd *pfd = ...;
 
@@ -157,15 +157,15 @@
     
     poll(pfd, 1, -1); (or select(); add a timeout if you want)
 
-    if(pfd->revents) {
+    if (pfd->revents) {
          struct dv1394_status status;
 	 
          ioctl(dv1394_fd, DV1394_GET_STATUS, &status);
 
-	 if(status.dropped_frames > 0) {
+	 if (status.dropped_frames > 0) {
 	      reset_dv1394();
          } else {
-              for(int i = 0; i < status.n_clear_frames; i++) {
+              for (int i = 0; i < status.n_clear_frames; i++) {
 	          copy_DV_frame();
               }
          }
diff -urN linux-2.4.22-pre2/drivers/ieee1394/eth1394.c linux-2.4.22-pre3/drivers/ieee1394/eth1394.c
--- linux-2.4.22-pre2/drivers/ieee1394/eth1394.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/eth1394.c	2003-07-05 18:10:00.000000000 -0700
@@ -3,6 +3,7 @@
  * 
  * Copyright (C) 2001 Ben Collins <bcollins@debian.org>
  *               2000 Bonin Franck <boninf@free.fr>
+ *               2003 Steve Kinneberg <kinnebergsteve@acmsystems.com>
  *
  * Mainly based on work by Emanuel Pirker and Andreas E. Bombe
  *
@@ -21,22 +22,27 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-/* State of this driver:
- *
- * This driver intends to support RFC 2734, which describes a method for
+/* This driver intends to support RFC 2734, which describes a method for
  * transporting IPv4 datagrams over IEEE-1394 serial busses. This driver
  * will ultimately support that method, but currently falls short in
- * several areas. A few issues are:
+ * several areas.
+ *
+ * TODO:
+ * RFC 2734 related:
+ * - Add Config ROM entry
+ * - Add MCAP. Limited Multicast exists only to 224.0.0.1 and 224.0.0.2.
  *
- *   - Does not support send/recv over Async streams using GASP
- *     packet formats, as per the RFC for ARP requests.
- *   - Does not yet support fragmented packets.
- *   - Relies on hardware address being equal to the nodeid for some things.
- *   - Does not support multicast
- *   - Hardcoded address for sending packets, instead of using discovery
- *     (ARP, see first item)
+ * Non-RFC 2734 related:
+ * - Fix bug related to fragmented broadcast datagrams
+ * - Move generic GASP reception to core 1394 code
+ * - Convert kmalloc/kfree for link fragments to use kmem_cache_* instead
+ * - Stability improvements
+ * - Performance enhancements
+ * - Change hardcoded 1394 bus address region to a dynamic memory space allocation
+ * - Consider garbage collecting old partial datagrams after X amount of time
  */
 
+
 #include <linux/module.h>
 
 #include <linux/sched.h>
@@ -53,9 +59,12 @@
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/ip.h>
+#include <linux/in.h>
 #include <linux/tcp.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
+#include <linux/ethtool.h>
+#include <asm/uaccess.h>
 #include <asm/delay.h>
 #include <asm/semaphore.h>
 #include <net/arp.h>
@@ -66,49 +75,183 @@
 #include "ieee1394.h"
 #include "highlevel.h"
 #include "iso.h"
+#include "nodemgr.h"
 #include "eth1394.h"
 
 #define ETH1394_PRINT_G(level, fmt, args...) \
-	printk(level ETHER1394_DRIVER_NAME": "fmt, ## args)
+	printk(level "%s: " fmt, driver_name, ## args)
 
 #define ETH1394_PRINT(level, dev_name, fmt, args...) \
-	printk(level ETHER1394_DRIVER_NAME": %s: " fmt, dev_name, ## args)
+	printk(level "%s: %s: " fmt, driver_name, dev_name, ## args)
 
 #define DEBUG(fmt, args...) \
-	printk(KERN_ERR fmt, ## args)
+	printk(KERN_ERR "%s:%s[%d]: " fmt "\n", driver_name, __FUNCTION__, __LINE__, ## args)
+#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
 
 static char version[] __devinitdata =
-	"$Rev: 906 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 970 $ Ben Collins <bcollins@debian.org>";
+
+struct fragment_info {
+	struct list_head list;
+	int offset;
+	int len;
+};
+
+struct partial_datagram {
+	struct list_head list;
+	u16 dgl;
+	u16 dg_size;
+	u16 ether_type;
+	struct sk_buff *skb;
+	char *pbuf;
+	struct list_head frag_info;
+};
 
 /* Our ieee1394 highlevel driver */
-#define ETHER1394_DRIVER_NAME "ether1394"
+static const char driver_name[] = "eth1394";
 
 static kmem_cache_t *packet_task_cache;
 
 static struct hpsb_highlevel eth1394_highlevel;
 
 /* Use common.lf to determine header len */
-static int hdr_type_len[] = {
+static const int hdr_type_len[] = {
 	sizeof (struct eth1394_uf_hdr),
 	sizeof (struct eth1394_ff_hdr),
 	sizeof (struct eth1394_sf_hdr),
 	sizeof (struct eth1394_sf_hdr)
 };
 
+static const u16 eth1394_speedto_maxpayload[] = {
+/*     S100, S200, S400, S800, S1600, S3200 */
+	512, 1024, 2048, 4096,  8192, 16384
+};
+
 MODULE_AUTHOR("Ben Collins (bcollins@debian.org)");
 MODULE_DESCRIPTION("IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)");
 MODULE_LICENSE("GPL");
 
+/* The max_partial_datagrams parameter is the maximum number of fragmented
+ * datagrams per node that eth1394 will keep in memory.  Providing an upper
+ * bound allows us to limit the amount of memory that partial datagrams
+ * consume in the event that some partial datagrams are never completed.  This
+ * should probably change to a sysctl item or the like if possible.
+ */
+MODULE_PARM(max_partial_datagrams, "i");
+MODULE_PARM_DESC(max_partial_datagrams,
+		 "Maximum number of partially received fragmented datagrams "
+		 "(default = 25).");
+static int max_partial_datagrams = 25;
+
+
+static int ether1394_header(struct sk_buff *skb, struct net_device *dev,
+			    unsigned short type, void *daddr, void *saddr,
+			    unsigned len);
+static int ether1394_rebuild_header(struct sk_buff *skb);
+static int ether1394_header_parse(struct sk_buff *skb, unsigned char *haddr);
+static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh);
+static void ether1394_header_cache_update(struct hh_cache *hh,
+					  struct net_device *dev,
+					  unsigned char * haddr);
+static int ether1394_mac_addr(struct net_device *dev, void *p);
+
+static inline void purge_partial_datagram(struct list_head *old);
+static int ether1394_tx(struct sk_buff *skb, struct net_device *dev);
 static void ether1394_iso(struct hpsb_iso *iso);
 
+static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr);
+
+static void eth1394_iso_shutdown(struct eth1394_priv *priv)
+{
+	priv->bc_state = ETHER1394_BC_CLOSED;
+
+	if (priv->iso != NULL) {
+		hpsb_iso_shutdown(priv->iso);
+		priv->iso = NULL;
+	}
+}
+
+static int ether1394_init_bc(struct net_device *dev)
+{
+	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+
+	/* First time sending?  Need a broadcast channel for ARP and for
+	 * listening on */
+	if (priv->bc_state == ETHER1394_BC_CHECK) {
+		quadlet_t bc;
+
+		/* Get the local copy of the broadcast channel and check its
+		 * validity (the IRM should validate it for us) */
+
+		bc = priv->host->csr.broadcast_channel;
+
+		if ((bc & 0xc0000000) != 0xc0000000) {
+			/* broadcast channel not validated yet */
+			ETH1394_PRINT(KERN_WARNING, dev->name,
+				      "Error BROADCAST_CHANNEL register valid "
+				      "bit not set, can't send IP traffic\n");
+
+			if (!in_interrupt())
+				eth1394_iso_shutdown(priv);
+
+			return -EAGAIN;
+		}
+		if (priv->broadcast_channel != (bc & 0x3f)) {
+			/* This really shouldn't be possible, but just in case
+			 * the IEEE 1394 spec changes regarding broadcast
+			 * channels in the future. */
+
+			if (in_interrupt())
+				return -EAGAIN;
+
+			eth1394_iso_shutdown(priv);
+
+			priv->broadcast_channel = bc & 0x3f;
+			ETH1394_PRINT(KERN_INFO, dev->name,
+				      "Changing to broadcast channel %d...\n",
+				      priv->broadcast_channel);
+
+			priv->iso = hpsb_iso_recv_init(priv->host, 16 * 4096,
+						       16, priv->broadcast_channel,
+						       1, ether1394_iso);
+			if (priv->iso == NULL) {
+				ETH1394_PRINT(KERN_ERR, dev->name,
+					      "failed to change broadcast "
+					      "channel\n");
+				return -EAGAIN;
+			}
+		}
+		if (hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) {
+			ETH1394_PRINT(KERN_ERR, dev->name,
+				      "Could not start data stream reception\n");
+
+			if (!in_interrupt())
+				eth1394_iso_shutdown(priv);
+
+			return -EAGAIN;
+		}
+		priv->bc_state = ETHER1394_BC_OPENED;
+	}
+    
+	return 0;
+}
 
 /* This is called after an "ifup" */
 static int ether1394_open (struct net_device *dev)
 {
 	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+	unsigned long flags;
+	int ret;
 
 	/* Set the spinlock before grabbing IRQ! */
 	priv->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_irqsave(&priv->lock, flags);
+	ret = ether1394_init_bc(dev);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (ret)
+		return ret;
 
 	netif_start_queue (dev);
 	return 0;
@@ -139,116 +282,35 @@
 	netif_wake_queue (dev);
 }
 
-/* We need to encapsulate the standard header with our own. We use the
- * ethernet header's proto for our own.
- *
- * XXX: This is where we need to create a list of skb's for fragmented
- * packets.  */
-static inline void ether1394_encapsulate (struct sk_buff *skb, struct net_device *dev,
-                                          int proto, struct packet_task *ptask)
-{
-	union eth1394_hdr *hdr =
-		(union eth1394_hdr *)skb_push (skb, hdr_type_len[ETH1394_HDR_LF_UF]);
-
-	hdr->words.word1 = 0;
-	hdr->common.lf = ETH1394_HDR_LF_UF;
-	hdr->words.word1 = htons(hdr->words.word1);
-	hdr->uf.ether_type = proto;
-
-	/* Set the transmission type for the packet.  Right now only ARP
-	 * packets are sent via GASP.  IP broadcast and IP multicast are not
-	 * yet supported properly, they too should use GASP. */
-	switch(proto) {
-	case __constant_htons(ETH_P_ARP):
-		ptask->tx_type = ETH1394_GASP;
-		break;
-	default:
-		ptask->tx_type = ETH1394_WRREQ;
-	}
-	return;
-}
-
-/* Convert a standard ARP packet to 1394 ARP. The first 8 bytes (the
- * entire arphdr) is the same format as the ip1394 header, so they
- * overlap. The rest needs to be munged a bit. The remainder of the
- * arphdr is formatted based on hwaddr len and ipaddr len. We know what
- * they'll be, so it's easy to judge.  */
-static inline void ether1394_arp_to_1394arp (struct sk_buff *skb, struct net_device *dev)
-{
-	struct eth1394_priv *priv =
-		(struct eth1394_priv *)(dev->priv);
-	u16 phy_id = NODEID_TO_NODE(priv->host->node_id);
-
-	unsigned char *arp_ptr = (unsigned char *)skb->data;
-	struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data;
-	unsigned char arp_data[2*(dev->addr_len+4)];
-
-	/* Copy the main data that we need */
-	memcpy (arp_data, arp_ptr + sizeof(struct arphdr), sizeof (arp_data));
-
-	/* Extend the buffer enough for our new header */
-	skb_put (skb, sizeof (struct eth1394_arp) -
-		 (sizeof (arp_data) + sizeof (struct arphdr)));
-
-#define PROCESS_MEMBER(ptr,val,len) \
-  memcpy (val, ptr, len); ptr += len
-	arp_ptr = arp_data + arp1394->hw_addr_len;
-	PROCESS_MEMBER (arp_ptr, &arp1394->sip, arp1394->ip_addr_len);
-	arp_ptr += arp1394->hw_addr_len;
-	PROCESS_MEMBER (arp_ptr, &arp1394->tip, arp1394->ip_addr_len);
-#undef PROCESS_MEMBER
-
-	/* Now add our own flavor of arp header fields to the orig one */
-	arp1394->hw_addr_len	= IP1394_HW_ADDR_LEN;
-	arp1394->hw_type	= __constant_htons (ARPHRD_IEEE1394);
-	arp1394->s_uniq_id	= cpu_to_le64 (priv->eui[phy_id]);
-	arp1394->max_rec	= priv->max_rec[phy_id];
-	arp1394->sspd		= priv->sspd[phy_id];
-	arp1394->fifo_hi	= htons (priv->fifo_hi[phy_id]);
-	arp1394->fifo_lo	= htonl (priv->fifo_lo[phy_id]);
-
-	return;
-}
-
 static int ether1394_change_mtu(struct net_device *dev, int new_mtu)
 {
-	if ((new_mtu < 68) || (new_mtu > ETHER1394_REGION_ADDR_LEN))
+	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+	int phy_id = NODEID_TO_NODE(priv->host->node_id);
+
+	if ((new_mtu < 68) || (new_mtu > MIN(ETH_DATA_LEN, (priv->maxpayload[phy_id] -
+					  (sizeof(union eth1394_hdr) +
+					   ETHER1394_GASP_OVERHEAD)))))
 		return -EINVAL;
 	dev->mtu = new_mtu;
 	return 0;
 }
 
-static inline void ether1394_register_limits (int nodeid, unsigned char max_rec,
-				       unsigned char sspd, u64 eui, u16 fifo_hi,
-				       u32 fifo_lo, struct eth1394_priv *priv)
+static inline void ether1394_register_limits(int nodeid, u16 maxpayload,
+					     unsigned char sspd, u64 eui, u64 fifo,
+					     struct eth1394_priv *priv)
 {
-	int i;
-
 	if (nodeid < 0 || nodeid >= ALL_NODES) {
 		ETH1394_PRINT_G (KERN_ERR, "Cannot register invalid nodeid %d\n", nodeid);
 		return;
 	}
 
-	priv->max_rec[nodeid]	= max_rec;
-	priv->sspd[nodeid]	= sspd;
-	priv->fifo_hi[nodeid]	= fifo_hi;
-	priv->fifo_lo[nodeid]	= fifo_lo;
-	priv->eui[nodeid]	= eui;
-
-	/* 63 is used for broadcasts to all hosts. It is equal to the
-	 * minimum of all registered nodes. A registered node is one with
-	 * a nonzero offset. Set the values rediculously high to start. We
-	 * know we have atleast one to change the default to.  */
-	sspd = 0xff;
-	max_rec = 0xff;
-	for (i = 0; i < ALL_NODES; i++) {
-		if (!priv->fifo_hi && !priv->fifo_lo) continue; /* Unregistered */
-		if (priv->max_rec[i] < max_rec) max_rec = priv->max_rec[i];
-		if (priv->sspd[i] < sspd) sspd = priv->sspd[i];
-	}
+	priv->maxpayload[nodeid]	= maxpayload;
+	priv->sspd[nodeid]		= sspd;
+	priv->fifo[nodeid]		= fifo;
+	priv->eui[nodeid]		= eui;
 
-	priv->max_rec[ALL_NODES] = max_rec;
-	priv->sspd[ALL_NODES] = sspd;
+	priv->maxpayload[ALL_NODES] = min(priv->maxpayload[ALL_NODES], maxpayload);
+	priv->sspd[ALL_NODES] = min(priv->sspd[ALL_NODES], sspd);
 
 	return;
 }
@@ -256,40 +318,65 @@
 static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
 {
 	unsigned long flags;
+	int i;
 	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
-	int phy_id = NODEID_TO_NODE(priv->host->node_id);
 	struct hpsb_host *host = priv->host;
+	int phy_id = NODEID_TO_NODE(host->node_id);
+	u64 guid = (u64)(((u64)be32_to_cpu(host->csr.rom[3]) << 32) |
+			  be32_to_cpu(host->csr.rom[4]));
+	u16 maxpayload = 1 << (((be32_to_cpu(host->csr.rom[2]) >> 12) & 0xf) + 1);
 
 	spin_lock_irqsave (&priv->lock, flags);
 
 	/* Clear the speed/payload/offset tables */
-	memset (priv->max_rec, 0, sizeof (priv->max_rec));
+	memset (priv->maxpayload, 0, sizeof (priv->maxpayload));
 	memset (priv->sspd, 0, sizeof (priv->sspd));
-	memset (priv->fifo_hi, 0, sizeof (priv->fifo_hi));
-	memset (priv->fifo_lo, 0, sizeof (priv->fifo_lo));
+	memset (priv->fifo, 0, sizeof (priv->fifo));
+
+#if 1
+/* Compile this out to make testing of fragmented broadcast datagrams
+ * easier. */
+	priv->sspd[ALL_NODES] = IEEE1394_SPEED_MAX;
+	priv->maxpayload[ALL_NODES] = eth1394_speedto_maxpayload[IEEE1394_SPEED_MAX];
+#else
+	priv->sspd[ALL_NODES] = IEEE1394_SPEED_100;
+	priv->maxpayload[ALL_NODES] = eth1394_speedto_maxpayload[IEEE1394_SPEED_100];
+#endif
 
 	priv->bc_state = ETHER1394_BC_CHECK;
 
 	/* Register our limits now */
-	ether1394_register_limits (phy_id, (be32_to_cpu(host->csr.rom[2]) >> 12) & 0xf,
-				   host->speed_map[(phy_id << 6) + phy_id],
-				   (u64)(((u64)be32_to_cpu(host->csr.rom[3]) << 32) |
-				   be32_to_cpu(host->csr.rom[4])),
-				   ETHER1394_REGION_ADDR >> 32,
-				   ETHER1394_REGION_ADDR & 0xffffffff, priv);
-
-	/* We'll use our max_rec as the default mtu */
-	if (set_mtu)
-		dev->mtu = (1 << (priv->max_rec[phy_id] + 1)) - /* mtu = max_rec - */
-			(sizeof (union eth1394_hdr) + 8);	/* (hdr + GASP) */
-
-	/* Set our hardware address while we're at it */
-	*(nodeid_t *)dev->dev_addr = htons (host->node_id);
+	ether1394_register_limits(phy_id, maxpayload,
+				  host->speed_map[(phy_id << 6) + phy_id],
+				  guid, ETHER1394_REGION_ADDR, priv);
+
+	/* We'll use our maxpayload as the default mtu */
+	if (set_mtu) {
+		dev->mtu = MIN(ETH_DATA_LEN, priv->maxpayload[phy_id] -
+					     (sizeof(union eth1394_hdr) +
+					     ETHER1394_GASP_OVERHEAD));
+
+		/* Set our hardware address while we're at it */
+		*(u64*)dev->dev_addr = guid;
+		*(u64*)dev->broadcast = ~0x0ULL;
+	}
 
 	spin_unlock_irqrestore (&priv->lock, flags);
-}
 
-static int ether1394_tx (struct sk_buff *skb, struct net_device *dev);
+	for (i = 0; i < ALL_NODES; i++) {
+		struct list_head *lh, *n;
+
+		spin_lock_irqsave(&priv->pdg[i].lock, flags);
+		if (!set_mtu) {
+			list_for_each_safe(lh, n, &priv->pdg[i].list) {
+				purge_partial_datagram(lh);
+			}
+		}
+		INIT_LIST_HEAD(&(priv->pdg[i].list));
+		priv->pdg[i].sz = 0;
+		spin_unlock_irqrestore(&priv->pdg[i].lock, flags);
+	}
+}
 
 /* This function is called by register_netdev */
 static int ether1394_init_dev (struct net_device *dev)
@@ -302,11 +389,23 @@
 	dev->tx_timeout		= ether1394_tx_timeout;
 	dev->change_mtu		= ether1394_change_mtu;
 
+	dev->hard_header	= ether1394_header;
+	dev->rebuild_header	= ether1394_rebuild_header;
+	dev->hard_header_cache	= ether1394_header_cache;
+	dev->header_cache_update= ether1394_header_cache_update;
+	dev->hard_header_parse	= ether1394_header_parse;
+	dev->set_mac_address	= ether1394_mac_addr;
+	dev->do_ioctl		= ether1394_do_ioctl;
+
 	/* Some constants */
 	dev->watchdog_timeo	= ETHER1394_TIMEOUT;
-	dev->flags		= IFF_BROADCAST; /* TODO: Support MCAP */
-	dev->features		= NETIF_F_NO_CSUM|NETIF_F_SG|NETIF_F_HIGHDMA|NETIF_F_FRAGLIST;
-	dev->addr_len		= 2;
+	dev->flags		= IFF_BROADCAST | IFF_MULTICAST;
+        /* !! If data corruption or untrackable kernel panics occur, try
+         * removing NETIF_F_FRAGLIST !! */
+	dev->features		= NETIF_F_HIGHDMA | NETIF_F_FRAGLIST;
+	dev->addr_len		= ETH1394_ALEN;
+	dev->hard_header_len 	= ETH1394_HLEN;
+	dev->type		= ARPHRD_IEEE1394;
 
 	ether1394_reset_priv (dev, 1);
 
@@ -320,6 +419,7 @@
  */
 static void ether1394_add_host (struct hpsb_host *host)
 {
+	int i;
 	struct host_info *hi = NULL;
 	struct net_device *dev = NULL;
 	struct eth1394_priv *priv;
@@ -328,10 +428,17 @@
 	if (version_printed++ == 0)
 		ETH1394_PRINT_G (KERN_INFO, "%s\n", version);
 
+	/* We should really have our own alloc_hpsbdev() function in
+	 * net_init.c instead of calling the one for ethernet then hijacking
+	 * it for ourselves.  That way we'd be a real networking device. */
 	dev = alloc_etherdev(sizeof (struct eth1394_priv));
 
-	if (dev == NULL)
+	if (dev == NULL) {
+		ETH1394_PRINT_G (KERN_ERR, "Out of memory trying to allocate "
+				 "etherdevice for IEEE 1394 device %s-%d\n",
+				 host->driver->name, host->id);
 		goto out;
+        }
 
 	SET_MODULE_OWNER(dev);
 
@@ -342,10 +449,20 @@
 	priv->host = host;
 	spin_lock_init(&priv->lock);
 
+	for (i = 0; i < ALL_NODES; i++) {
+                spin_lock_init(&priv->pdg[i].lock);
+		INIT_LIST_HEAD(&priv->pdg[i].list);
+		priv->pdg[i].sz = 0;
+	}
+
 	hi = hpsb_create_hostinfo(&eth1394_highlevel, host, sizeof(*hi));
 
-	if (hi == NULL)
+	if (hi == NULL) {
+		ETH1394_PRINT_G (KERN_ERR, "Out of memory trying to create "
+				 "hostinfo for IEEE 1394 device %s-%d\n",
+				 host->driver->name, host->id);
 		goto out;
+        }
 
 	if (register_netdev (dev)) {
 		ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n");
@@ -359,10 +476,10 @@
 	hi->dev = dev;
 
 	/* Ignore validity in hopes that it will be set in the future.  It'll
-	 * check it on transmit. */
+	 * be checked when the eth device is opened. */
 	priv->broadcast_channel = host->csr.broadcast_channel & 0x3f;
 
-	priv->iso = hpsb_iso_recv_init(host, 8 * 4096, 8, priv->broadcast_channel,
+	priv->iso = hpsb_iso_recv_init(host, 16 * 4096, 16, priv->broadcast_channel,
 				       1, ether1394_iso);
 	if (priv->iso == NULL) {
 		priv->bc_state = ETHER1394_BC_CLOSED;
@@ -371,12 +488,10 @@
 
 out:
 	if (dev != NULL)
-		kfree (dev);
+		kfree(dev);
 	if (hi)
 		hpsb_destroy_hostinfo(&eth1394_highlevel, host);
 
-	ETH1394_PRINT_G (KERN_ERR, "Out of memory\n");
-
 	return;
 }
 
@@ -389,10 +504,12 @@
 		struct eth1394_priv *priv = (struct eth1394_priv *)hi->dev->priv;
 
 		priv->bc_state = ETHER1394_BC_CLOSED;
-		unregister_netdev (hi->dev);
-		hpsb_iso_shutdown(priv->iso);
+		eth1394_iso_shutdown(priv);
 
-		kfree (hi->dev);
+		if (hi->dev) {
+			unregister_netdev (hi->dev);
+			kfree(hi->dev);
+		}
 	}
 
 	return;
@@ -416,26 +533,140 @@
 	netif_wake_queue (dev);
 }
 
+/******************************************
+ * HW Header net device functions
+ ******************************************/
+/* These functions have been adapted from net/ethernet/eth.c */
+
+
+/* Create a fake MAC header for an arbitrary protocol layer.
+ * saddr=NULL means use device source address
+ * daddr=NULL means leave destination address (eg unresolved arp). */
+static int ether1394_header(struct sk_buff *skb, struct net_device *dev,
+			    unsigned short type, void *daddr, void *saddr,
+			    unsigned len)
+{
+	struct eth1394hdr *eth = (struct eth1394hdr *)skb_push(skb, ETH1394_HLEN);
+
+	eth->h_proto = htons(type);
+
+	if (dev->flags & (IFF_LOOPBACK|IFF_NOARP)) 
+	{
+		memset(eth->h_dest, 0, dev->addr_len);
+		return(dev->hard_header_len);
+	}
+
+	if (daddr)
+	{
+		memcpy(eth->h_dest,daddr,dev->addr_len);
+		return dev->hard_header_len;
+	}
+	
+	return -dev->hard_header_len;
+
+}
+
+
+/* Rebuild the faked MAC header. This is called after an ARP
+ * (or in future other address resolution) has completed on this
+ * sk_buff. We now let ARP fill in the other fields.
+ *
+ * This routine CANNOT use cached dst->neigh!
+ * Really, it is used only when dst->neigh is wrong.
+ */
+static int ether1394_rebuild_header(struct sk_buff *skb)
+{
+	struct eth1394hdr *eth = (struct eth1394hdr *)skb->data;
+	struct net_device *dev = skb->dev;
+
+	switch (eth->h_proto)
+	{
+#ifdef CONFIG_INET
+	case __constant_htons(ETH_P_IP):
+ 		return arp_find((unsigned char*)&eth->h_dest, skb);
+#endif	
+	default:
+		printk(KERN_DEBUG
+		       "%s: unable to resolve type %X addresses.\n", 
+		       dev->name, (int)eth->h_proto);
+		break;
+	}
+
+	return 0;
+}
+
+static int ether1394_header_parse(struct sk_buff *skb, unsigned char *haddr)
+{
+	struct net_device *dev = skb->dev;
+	memcpy(haddr, dev->dev_addr, ETH1394_ALEN);
+	return ETH1394_ALEN;
+}
+
+
+static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh)
+{
+	unsigned short type = hh->hh_type;
+	struct eth1394hdr *eth = (struct eth1394hdr*)(((u8*)hh->hh_data) + 6);
+	struct net_device *dev = neigh->dev;
+
+	if (type == __constant_htons(ETH_P_802_3)) {
+		return -1;
+	}
+
+	eth->h_proto = type;
+	memcpy(eth->h_dest, neigh->ha, dev->addr_len);
+	
+	hh->hh_len = ETH1394_HLEN;
+	return 0;
+}
+
+/* Called by Address Resolution module to notify changes in address. */
+static void ether1394_header_cache_update(struct hh_cache *hh,
+					  struct net_device *dev,
+					  unsigned char * haddr)
+{
+	memcpy(((u8*)hh->hh_data) + 6, haddr, dev->addr_len);
+}
+
+static int ether1394_mac_addr(struct net_device *dev, void *p)
+{
+	if (netif_running(dev))
+		return -EBUSY;
+
+	/* Not going to allow setting the MAC address, we really need to use
+	 * the real one suppliled by the hardware */
+	 return -EINVAL;
+ }
+
+
+
+/******************************************
+ * Datagram reception code
+ ******************************************/
+
 /* Copied from net/ethernet/eth.c */
-static inline unsigned short ether1394_type_trans(struct sk_buff *skb, struct net_device *dev)
+static inline u16 ether1394_type_trans(struct sk_buff *skb,
+				       struct net_device *dev)
 {
-	struct ethhdr *eth;
+	struct eth1394hdr *eth;
 	unsigned char *rawp;
 
 	skb->mac.raw = skb->data;
-	skb_pull (skb, ETH_HLEN);
-	eth = skb->mac.ethernet;
-#if 0
-	if(*eth->h_dest & 1) {
-		if(memcmp(eth->h_dest, dev->broadcast, dev->addr_len)==0)
+	skb_pull (skb, ETH1394_HLEN);
+	eth = (struct eth1394hdr*)skb->mac.raw;
+
+	if (*eth->h_dest & 1) {
+		if (memcmp(eth->h_dest, dev->broadcast, dev->addr_len)==0)
 			skb->pkt_type = PACKET_BROADCAST;
+#if 0
 		else
 			skb->pkt_type = PACKET_MULTICAST;
+#endif
 	} else {
-		if(memcmp(eth->h_dest, dev->dev_addr, dev->addr_len))
+		if (memcmp(eth->h_dest, dev->dev_addr, dev->addr_len))
 			skb->pkt_type = PACKET_OTHERHOST;
         }
-#endif
+
 	if (ntohs (eth->h_proto) >= 1536)
 		return eth->h_proto;
 
@@ -449,102 +680,376 @@
 
 /* Parse an encapsulated IP1394 header into an ethernet frame packet.
  * We also perform ARP translation here, if need be.  */
-static inline unsigned short ether1394_parse_encap (struct sk_buff *skb, struct net_device *dev,
-					     nodeid_t srcid, nodeid_t destid)
+static inline u16 ether1394_parse_encap(struct sk_buff *skb,
+					struct net_device *dev,
+					nodeid_t srcid, nodeid_t destid,
+					u16 ether_type)
 {
-	union eth1394_hdr *hdr = (union eth1394_hdr *)skb->data;
-	unsigned char src_hw[ETH_ALEN], dest_hw[ETH_ALEN];
+	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+	u64 dest_hw;
 	unsigned short ret = 0;
 
 	/* Setup our hw addresses. We use these to build the
 	 * ethernet header.  */
-	*(u16 *)dest_hw = htons(destid);
-	*(u16 *)src_hw = htons(srcid);
-
-	/* Remove the encapsulation header */
-	hdr->words.word1 = ntohs(hdr->words.word1);
-	skb_pull (skb, hdr_type_len[hdr->common.lf]);
+	if (destid == (LOCAL_BUS | ALL_NODES))
+		dest_hw = ~0ULL;  /* broadcast */
+	else
+		dest_hw = priv->eui[NODEID_TO_NODE(destid)];
 
 	/* If this is an ARP packet, convert it. First, we want to make
 	 * use of some of the fields, since they tell us a little bit
 	 * about the sending machine.  */
-	if (hdr->uf.ether_type == __constant_htons (ETH_P_ARP)) {
+	if (ether_type == __constant_htons (ETH_P_ARP)) {
 		unsigned long flags;
-		u16 phy_id = NODEID_TO_NODE(srcid);
-		struct eth1394_priv *priv =
-			(struct eth1394_priv *)dev->priv;
-		struct eth1394_arp arp1394;
+		struct eth1394_arp *arp1394 = (struct eth1394_arp*)skb->data;
 		struct arphdr *arp = (struct arphdr *)skb->data;
 		unsigned char *arp_ptr = (unsigned char *)(arp + 1);
+		u64 fifo_addr = (u64)ntohs(arp1394->fifo_hi) << 32 |
+			ntohl(arp1394->fifo_lo);
+		u8 host_max_rec = (be32_to_cpu(priv->host->csr.rom[2]) >>
+				   12) & 0xf;
+		u8 max_rec = min(host_max_rec, (u8)(arp1394->max_rec));
+		u16 maxpayload = min(eth1394_speedto_maxpayload[arp1394->sspd],
+				     (u16)(1 << (max_rec + 1)));
 
-		memcpy (&arp1394, arp, sizeof (struct eth1394_arp));
 
 		/* Update our speed/payload/fifo_offset table */
 		spin_lock_irqsave (&priv->lock, flags);
-		ether1394_register_limits (phy_id, arp1394.max_rec, arp1394.sspd,
-					   le64_to_cpu (arp1394.s_uniq_id),
-					   ntohs (arp1394.fifo_hi),
-					   ntohl (arp1394.fifo_lo), priv);
+		ether1394_register_limits(NODEID_TO_NODE(srcid), maxpayload,
+					  arp1394->sspd, arp1394->s_uniq_id,
+					  fifo_addr, priv);
 		spin_unlock_irqrestore (&priv->lock, flags);
 
-#define PROCESS_MEMBER(ptr,val,len) \
-  memcpy (ptr, val, len); ptr += len
-                PROCESS_MEMBER (arp_ptr, src_hw, dev->addr_len);
-                PROCESS_MEMBER (arp_ptr, &arp1394.sip, 4);
-                PROCESS_MEMBER (arp_ptr, dest_hw, dev->addr_len);
-                PROCESS_MEMBER (arp_ptr, &arp1394.tip, 4);
-#undef PROCESS_MEMBER
-
-		arp->ar_hln = dev->addr_len;
-		arp->ar_hrd = __constant_htons (ARPHRD_ETHER);
-
-		skb_trim (skb, sizeof (struct arphdr) + 2*(dev->addr_len+4));
+		/* Now that we're done with the 1394 specific stuff, we'll
+		 * need to alter some of the data.  Believe it or not, all
+		 * that needs to be done is sender_IP_address needs to be
+		 * moved, the destination hardware address get stuffed
+		 * in and the hardware address length set to 8.
+		 *
+		 * IMPORTANT: The code below overwrites 1394 specific data
+		 * needed above data so keep the call to
+		 * ether1394_register_limits() before munging the data for the
+		 * higher level IP stack. */
+
+		arp->ar_hln = 8;
+		arp_ptr += arp->ar_hln;		/* skip over sender unique id */
+		*(u32*)arp_ptr = arp1394->sip;	/* move sender IP addr */
+		arp_ptr += arp->ar_pln;		/* skip over sender IP addr */
+
+		if (arp->ar_op == 1)
+			/* just set ARP req target unique ID to 0 */
+			memset(arp_ptr, 0, ETH1394_ALEN);
+		else
+			memcpy(arp_ptr, dev->dev_addr, ETH1394_ALEN);
 	}
 
 	/* Now add the ethernet header. */
-	if (dev->hard_header (skb, dev, __constant_ntohs (hdr->uf.ether_type),
-			      dest_hw, src_hw, skb->len) >= 0)
+	if (dev->hard_header (skb, dev, __constant_ntohs (ether_type),
+			      &dest_hw, NULL, skb->len) >= 0)
 		ret = ether1394_type_trans(skb, dev);
 
 	return ret;
 }
 
+static inline int fragment_overlap(struct list_head *frag_list, int offset, int len)
+{
+	struct list_head *lh;
+	struct fragment_info *fi;
+
+	list_for_each(lh, frag_list) {
+		fi = list_entry(lh, struct fragment_info, list);
+
+		if ( ! ((offset > (fi->offset + fi->len - 1)) ||
+		       ((offset + len - 1) < fi->offset)))
+			return 1;
+	}
+	return 0;
+}
+
+static inline struct list_head *find_partial_datagram(struct list_head *pdgl, int dgl)
+{
+	struct list_head *lh;
+	struct partial_datagram *pd;
+
+	list_for_each(lh, pdgl) {
+		pd = list_entry(lh, struct partial_datagram, list);
+		if (pd->dgl == dgl)
+			return lh;
+	}
+	return NULL;
+}
+
+/* Assumes that new fragment does not overlap any existing fragments */
+static inline int new_fragment(struct list_head *frag_info, int offset, int len)
+{
+	struct list_head *lh;
+	struct fragment_info *fi, *fi2, *new;
+
+	list_for_each(lh, frag_info) {
+		fi = list_entry(lh, struct fragment_info, list);
+		if ((fi->offset + fi->len) == offset) {
+			/* The new fragment can be tacked on to the end */
+			fi->len += len;
+			/* Did the new fragment plug a hole? */
+			fi2 = list_entry(lh->next, struct fragment_info, list);
+			if ((fi->offset + fi->len) == fi2->offset) {
+				/* glue fragments together */
+				fi->len += fi2->len;
+				list_del(lh->next);
+				kfree(fi2);
+			}
+			return 0;
+		} else if ((offset + len) == fi->offset) {
+			/* The new fragment can be tacked on to the beginning */
+			fi->offset = offset;
+			fi->len += len;
+			/* Did the new fragment plug a hole? */
+			fi2 = list_entry(lh->prev, struct fragment_info, list);
+			if ((fi2->offset + fi2->len) == fi->offset) {
+				/* glue fragments together */
+				fi2->len += fi->len;
+				list_del(lh);
+				kfree(fi);
+			}
+			return 0;
+		} else if (offset > (fi->offset + fi->len)) {
+			break;
+		} else if ((offset + len) < fi->offset) {
+			lh = lh->prev;
+			break;
+		}
+	}
+
+	new = kmalloc(sizeof(struct fragment_info), GFP_ATOMIC);
+	if (!new) 
+		return -ENOMEM;
+
+	new->offset = offset;
+	new->len = len;
+
+	list_add(&new->list, lh);
+
+	return 0;
+}
+
+static inline int new_partial_datagram(struct net_device *dev,
+				       struct list_head *pdgl, int dgl,
+				       int dg_size, char *frag_buf,
+				       int frag_off, int frag_len)
+{
+	struct partial_datagram *new;
+
+	new = kmalloc(sizeof(struct partial_datagram), GFP_ATOMIC);
+	if (!new)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&new->frag_info);
+
+	if (new_fragment(&new->frag_info, frag_off, frag_len) < 0) {
+		kfree(new);
+		return -ENOMEM;
+	}
+
+	new->dgl = dgl;
+	new->dg_size = dg_size;
+
+	new->skb = dev_alloc_skb(dg_size + dev->hard_header_len + 15);
+	if (!new->skb) {
+		struct fragment_info *fi = list_entry(new->frag_info.next,
+						      struct fragment_info,
+						      list);
+		kfree(fi);
+		kfree(new);
+		return -ENOMEM;
+	}
+
+	skb_reserve(new->skb, (dev->hard_header_len + 15) & ~15);
+	new->pbuf = skb_put(new->skb, dg_size);
+	memcpy(new->pbuf + frag_off, frag_buf, frag_len);
+
+	list_add(&new->list, pdgl);
+
+	return 0;
+}
+
+static inline int update_partial_datagram(struct list_head *pdgl, struct list_head *lh,
+					  char *frag_buf, int frag_off, int frag_len)
+{
+	struct partial_datagram *pd = list_entry(lh, struct partial_datagram, list);
+
+	if (new_fragment(&pd->frag_info, frag_off, frag_len) < 0) {
+		return -ENOMEM;
+	}
+
+	memcpy(pd->pbuf + frag_off, frag_buf, frag_len);
+
+	/* Move list entry to beginnig of list so that oldest partial
+	 * datagrams percolate to the end of the list */
+	list_del(lh);
+	list_add(lh, pdgl);
+
+	return 0;
+}
+
+static inline void purge_partial_datagram(struct list_head *old)
+{
+	struct partial_datagram *pd = list_entry(old, struct partial_datagram, list);
+	struct list_head *lh, *n;
+
+	list_for_each_safe(lh, n, &pd->frag_info) {
+		struct fragment_info *fi = list_entry(lh, struct fragment_info, list);
+		list_del(lh);
+		kfree(fi);
+	}
+	list_del(old);
+	kfree_skb(pd->skb);
+	kfree(pd);
+}
+
+static inline int is_datagram_complete(struct list_head *lh, int dg_size)
+{
+	struct partial_datagram *pd = list_entry(lh, struct partial_datagram, list);
+	struct fragment_info *fi = list_entry(pd->frag_info.next,
+					      struct fragment_info, list);
+
+	return (fi->len == dg_size);
+}
+
 /* Packet reception. We convert the IP1394 encapsulation header to an
  * ethernet header, and fill it with some of our other fields. This is
  * an incoming packet from the 1394 bus.  */
-static int ether1394_write (struct hpsb_host *host, int srcid, int destid,
-			    quadlet_t *data, u64 addr, unsigned int len, u16 fl)
+static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
+				  char *buf, int len)
 {
 	struct sk_buff *skb;
-	char *buf = (char *)data;
 	unsigned long flags;
-	struct host_info *hi = hpsb_get_hostinfo(&eth1394_highlevel, host);
-	struct net_device *dev;
 	struct eth1394_priv *priv;
+	union eth1394_hdr *hdr = (union eth1394_hdr *)buf;
+	u16 ether_type = 0;  /* initialized to clear warning */
+	int hdr_len;
 
-	if (hi == NULL) {
-		ETH1394_PRINT_G (KERN_ERR, "Could not find net device for host %p\n",
-				 host);
-		return RCODE_ADDRESS_ERROR;
-	}
+	priv = (struct eth1394_priv *)dev->priv;
 
-	dev = hi->dev;
+	/* First, did we receive a fragmented or unfragmented datagram? */
+	hdr->words.word1 = ntohs(hdr->words.word1);
 
-	priv = (struct eth1394_priv *)dev->priv;
+	hdr_len = hdr_type_len[hdr->common.lf];
 
-	/* A packet has been received by the ieee1394 bus. Build an skbuff
-	 * around it so we can pass it to the high level network layer. */
+	if (hdr->common.lf == ETH1394_HDR_LF_UF) {
+		/* An unfragmented datagram has been received by the ieee1394
+		 * bus. Build an skbuff around it so we can pass it to the
+		 * high level network layer. */
 
-	skb = dev_alloc_skb (len + dev->hard_header_len + 15);
-	if (!skb) {
-		HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n");
-		priv->stats.rx_dropped++;
-		return RCODE_ADDRESS_ERROR;
-	}
+		skb = dev_alloc_skb(len + dev->hard_header_len + 15);
+		if (!skb) {
+			HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n");
+			priv->stats.rx_dropped++;
+			return -1;
+		}
+		skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
+		memcpy(skb_put(skb, len - hdr_len), buf + hdr_len, len - hdr_len);
+		ether_type = hdr->uf.ether_type;
+	} else {
+		/* A datagram fragment has been received, now the fun begins. */
 
-	skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
+		struct list_head *pdgl, *lh;
+		struct partial_datagram *pd;
+		int fg_off;
+		int fg_len = len - hdr_len;
+		int dg_size;
+		int dgl;
+		int retval;
+		int sid = NODEID_TO_NODE(srcid);
+                struct pdg_list *pdg = &(priv->pdg[sid]);
+
+		hdr->words.word3 = ntohs(hdr->words.word3);
+		/* The 4th header word is reserved so no need to do ntohs() */
+
+		if (hdr->common.lf == ETH1394_HDR_LF_FF) {
+			ether_type = hdr->ff.ether_type;
+			dgl = hdr->ff.dgl;
+			dg_size = hdr->ff.dg_size + 1;
+			fg_off = 0;
+		} else {
+			hdr->words.word2 = ntohs(hdr->words.word2);
+			dgl = hdr->sf.dgl;
+			dg_size = hdr->sf.dg_size + 1;
+			fg_off = hdr->sf.fg_off;
+		}
+		spin_lock_irqsave(&pdg->lock, flags);
 
-	memcpy (skb_put (skb, len), buf, len);
+		pdgl = &(pdg->list);
+		lh = find_partial_datagram(pdgl, dgl);
+
+		if (lh == NULL) {
+			if (pdg->sz == max_partial_datagrams) {
+				/* remove the oldest */
+				purge_partial_datagram(pdgl->prev);
+				pdg->sz--;
+			}
+            
+			retval = new_partial_datagram(dev, pdgl, dgl, dg_size,
+						      buf + hdr_len, fg_off,
+						      fg_len);
+			if (retval < 0) {
+				spin_unlock_irqrestore(&pdg->lock, flags);
+				goto bad_proto;
+			}
+			pdg->sz++;
+			lh = find_partial_datagram(pdgl, dgl);
+		} else {
+			struct partial_datagram *pd;
+
+			pd = list_entry(lh, struct partial_datagram, list);
+
+			if (fragment_overlap(&pd->frag_info, fg_off, fg_len)) {
+				/* Overlapping fragments, obliterate old
+				 * datagram and start new one. */
+				purge_partial_datagram(lh);
+				retval = new_partial_datagram(dev, pdgl, dgl,
+							      dg_size,
+							      buf + hdr_len,
+							      fg_off, fg_len);
+				if (retval < 0) {
+					pdg->sz--;
+					spin_unlock_irqrestore(&pdg->lock, flags);
+					goto bad_proto;
+				}
+			} else {
+				retval = update_partial_datagram(pdgl, lh,
+								 buf + hdr_len,
+								 fg_off, fg_len);
+				if (retval < 0) {
+					/* Couldn't save off fragment anyway
+					 * so might as well obliterate the
+					 * datagram now. */
+					purge_partial_datagram(lh);
+					pdg->sz--;
+					spin_unlock_irqrestore(&pdg->lock, flags);
+					goto bad_proto;
+				}
+			} /* fragment overlap */
+		} /* new datagram or add to existing one */
+
+		pd = list_entry(lh, struct partial_datagram, list);
+
+		if (hdr->common.lf == ETH1394_HDR_LF_FF) {
+			pd->ether_type = ether_type;
+		}
+
+		if (is_datagram_complete(lh, dg_size)) {
+			ether_type = pd->ether_type;
+			pdg->sz--;
+			skb = skb_get(pd->skb);
+			purge_partial_datagram(lh);
+			spin_unlock_irqrestore(&pdg->lock, flags);
+		} else {
+			/* Datagram is not complete, we're done for the
+			 * moment. */
+			spin_unlock_irqrestore(&pdg->lock, flags);
+			return 0;
+		}
+	} /* unframgented datagram or fragmented one */
 
 	/* Write metadata, and then pass to the receive level */
 	skb->dev = dev;
@@ -554,9 +1059,11 @@
 	 * converting to an ethernet frame header, aswell as arp
 	 * conversion if needed. ARP conversion is easier in this
 	 * direction, since we are using ethernet as our backend.  */
-	skb->protocol = ether1394_parse_encap (skb, dev, srcid, destid);
+	skb->protocol = ether1394_parse_encap(skb, dev, srcid, destid,
+					      ether_type);
 
-	spin_lock_irqsave (&priv->lock, flags);
+
+	spin_lock_irqsave(&priv->lock, flags);
 	if (!skb->protocol) {
 		priv->stats.rx_errors++;
 		priv->stats.rx_dropped++;
@@ -564,8 +1071,7 @@
 		goto bad_proto;
 	}
 
-	netif_stop_queue(dev);
-	if (netif_rx (skb) == NET_RX_DROP) {
+	if (netif_rx(skb) == NET_RX_DROP) {
 		priv->stats.rx_errors++;
 		priv->stats.rx_dropped++;
 		goto bad_proto;
@@ -576,20 +1082,36 @@
 	priv->stats.rx_bytes += skb->len;
 
 bad_proto:
-	netif_start_queue(dev);
-	spin_unlock_irqrestore (&priv->lock, flags);
+	if (netif_queue_stopped(dev))
+		netif_wake_queue(dev);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	dev->last_rx = jiffies;
 
-	return RCODE_COMPLETE;
+	return 0;
+}
+
+static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
+			   quadlet_t *data, u64 addr, unsigned int len, u16 flags)
+{
+	struct host_info *hi = hpsb_get_hostinfo(&eth1394_highlevel, host);
+
+	if (hi == NULL) {
+		ETH1394_PRINT_G(KERN_ERR, "Could not find net device for host %s\n",
+				host->driver->name);
+		return RCODE_ADDRESS_ERROR;
+	}
+
+	if (ether1394_data_handler(hi->dev, srcid, destid, (char*)data, len))
+		return RCODE_ADDRESS_ERROR;
+	else
+		return RCODE_COMPLETE;
 }
 
 static void ether1394_iso(struct hpsb_iso *iso)
 {
-	struct sk_buff *skb;
 	quadlet_t *data;
 	char *buf;
-	unsigned long flags;
 	struct host_info *hi = hpsb_get_hostinfo(&eth1394_highlevel, iso->host);
 	struct net_device *dev;
 	struct eth1394_priv *priv;
@@ -600,15 +1122,15 @@
 	int nready;
 
 	if (hi == NULL) {
-		ETH1394_PRINT_G (KERN_ERR, "Could not find net device for host %s\n",
-				 iso->host->driver->name);
+		ETH1394_PRINT_G(KERN_ERR, "Could not find net device for host %s\n",
+				iso->host->driver->name);
 		return;
 	}
 
 	dev = hi->dev;
 
 	nready = hpsb_iso_n_ready(iso);
-	for(i = 0; i < nready; i++) {
+	for (i = 0; i < nready; i++) {
 		struct hpsb_iso_packet_info *info = &iso->infos[iso->first_packet + i];
 		data = (quadlet_t*) (iso->data_buf.kvirt + info->offset);
 
@@ -622,186 +1144,331 @@
 
 		priv = (struct eth1394_priv *)dev->priv;
 
-		if (info->channel != priv->broadcast_channel ||
-		    specifier_id != ETHER1394_GASP_SPECIFIER_ID) {
+		if (info->channel != (iso->host->csr.broadcast_channel & 0x3f) ||
+		   specifier_id != ETHER1394_GASP_SPECIFIER_ID) {
 			/* This packet is not for us */
 			continue;
 		}
+		ether1394_data_handler(dev, source_id, LOCAL_BUS | ALL_NODES,
+				       buf, len);
+	}
 
-		/* A packet has been received by the ieee1394 bus. Build an skbuff
-		 * around it so we can pass it to the high level network layer. */
-		skb = dev_alloc_skb (len + dev->hard_header_len + 15);
-		if (!skb) {
-			HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n");
-			priv->stats.rx_dropped++;
-			break;
-		}
+	hpsb_iso_recv_release_packets(iso, i);
 
-		skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
+	dev->last_rx = jiffies;
+}
 
-		memcpy (skb_put (skb, len), buf, len);
+/******************************************
+ * Datagram transmission code
+ ******************************************/
+
+/* Convert a standard ARP packet to 1394 ARP. The first 8 bytes (the entire
+ * arphdr) is the same format as the ip1394 header, so they overlap.  The rest
+ * needs to be munged a bit.  The remainder of the arphdr is formatted based
+ * on hwaddr len and ipaddr len.  We know what they'll be, so it's easy to
+ * judge.  
+ *
+ * Now that the EUI is used for the hardware address all we need to do to make
+ * this work for 1394 is to insert 2 quadlets that contain max_rec size,
+ * speed, and unicast FIFO address information between the sender_unique_id
+ * and the IP addresses.
+ */
+static inline void ether1394_arp_to_1394arp(struct sk_buff *skb,
+					    struct net_device *dev)
+{
+	struct eth1394_priv *priv = (struct eth1394_priv *)(dev->priv);
+	u16 phy_id = NODEID_TO_NODE(priv->host->node_id);
 
-		/* Write metadata, and then pass to the receive level */
-		skb->dev = dev;
-		skb->ip_summed = CHECKSUM_UNNECESSARY;	/* don't check it */
-
-		/* Parse the encapsulation header. This actually does the job of
-		 * converting to an ethernet frame header, aswell as arp
-		 * conversion if needed. ARP conversion is easier in this
-		 * direction, since we are using ethernet as our backend.  */
-		skb->protocol = ether1394_parse_encap (skb, dev, source_id,
-						       LOCAL_BUS | ALL_NODES);
+	struct arphdr *arp = (struct arphdr *)skb->data;
+	unsigned char *arp_ptr = (unsigned char *)(arp + 1);
+	struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data;
 
-		spin_lock_irqsave (&priv->lock, flags);
-		if (!skb->protocol) {
-			priv->stats.rx_errors++;
-			priv->stats.rx_dropped++;
-			dev_kfree_skb_any(skb);
-			goto bad_proto;
-		}
+	/* Believe it or not, all that need to happen is sender IP get moved
+	 * and set hw_addr_len, max_rec, sspd, fifo_hi and fifo_lo.  */
+	arp1394->hw_addr_len	= 16;
+	arp1394->sip		= *(u32*)(arp_ptr + ETH1394_ALEN);
+	arp1394->max_rec	= (be32_to_cpu(priv->host->csr.rom[2]) >> 12) & 0xf;
+	arp1394->sspd		= priv->sspd[phy_id];
+	arp1394->fifo_hi	= htons (priv->fifo[phy_id] >> 32);
+	arp1394->fifo_lo	= htonl (priv->fifo[phy_id] & ~0x0);
 
-		netif_stop_queue(dev);
-		if (netif_rx (skb) == NET_RX_DROP) {
-			priv->stats.rx_errors++;
-			priv->stats.rx_dropped++;
-			goto bad_proto;
-		}
+	return;
+}
 
-		/* Statistics */
-		priv->stats.rx_packets++;
-		priv->stats.rx_bytes += skb->len;
+/* We need to encapsulate the standard header with our own. We use the
+ * ethernet header's proto for our own. */
+static inline unsigned int ether1394_encapsulate_prep(unsigned int max_payload,
+						      int proto,
+						      union eth1394_hdr *hdr,
+						      u16 dg_size, u16 dgl)
+{
+	unsigned int adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_UF];
+
+	/* Does it all fit in one packet? */
+	if (dg_size <= adj_max_payload) {
+		hdr->uf.lf = ETH1394_HDR_LF_UF;
+		hdr->uf.ether_type = proto;
+	} else {
+		hdr->ff.lf = ETH1394_HDR_LF_FF;
+		hdr->ff.ether_type = proto;
+		hdr->ff.dg_size = dg_size - 1;
+		hdr->ff.dgl = dgl;
+		adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF];
+	}
+	return((dg_size + (adj_max_payload - 1)) / adj_max_payload);
+}
 
-	bad_proto:
-		spin_unlock_irqrestore (&priv->lock, flags);
+static inline unsigned int ether1394_encapsulate(struct sk_buff *skb,
+						 unsigned int max_payload,
+						 union eth1394_hdr *hdr)
+{
+	union eth1394_hdr *bufhdr;
+	int ftype = hdr->common.lf;
+	int hdrsz = hdr_type_len[ftype];
+	unsigned int adj_max_payload = max_payload - hdrsz;
+
+	switch(ftype) {
+	case ETH1394_HDR_LF_UF:
+		bufhdr = (union eth1394_hdr *)skb_push(skb, hdrsz);
+		bufhdr->words.word1 = htons(hdr->words.word1);
+		bufhdr->words.word2 = hdr->words.word2;
+		break;
+
+	case ETH1394_HDR_LF_FF:
+		bufhdr = (union eth1394_hdr *)skb_push(skb, hdrsz);
+		bufhdr->words.word1 = htons(hdr->words.word1);
+		bufhdr->words.word2 = hdr->words.word2;
+		bufhdr->words.word3 = htons(hdr->words.word3);
+		bufhdr->words.word4 = 0;
+
+		/* Set frag type here for future interior fragments */
+		hdr->common.lf = ETH1394_HDR_LF_IF;
+		hdr->sf.fg_off = 0;
+		break;
+		
+	default:
+		hdr->sf.fg_off += adj_max_payload;
+		bufhdr = (union eth1394_hdr *)skb_pull(skb, adj_max_payload);
+		if (max_payload >= skb->len)
+			hdr->common.lf = ETH1394_HDR_LF_LF;
+		bufhdr->words.word1 = htons(hdr->words.word1);
+		bufhdr->words.word2 = htons(hdr->words.word2);
+		bufhdr->words.word3 = htons(hdr->words.word3);
+		bufhdr->words.word4 = 0;
 	}
 
-	hpsb_iso_recv_release_packets(iso, i);
+	return min(max_payload, skb->len);
+}
 
-	netif_start_queue(dev);
-	
-	dev->last_rx = jiffies;
+static inline struct hpsb_packet *ether1394_alloc_common_packet(struct hpsb_host *host)
+{
+	struct hpsb_packet *p;
 
-	return;
+	p = alloc_hpsb_packet(0);
+	if (p) {
+		p->host = host;
+		p->data = NULL;
+		p->generation = get_hpsb_generation(host);
+		p->type = hpsb_async;
+	}
+	return p;
 }
 
+static inline int ether1394_prep_write_packet(struct hpsb_packet *p,
+					      struct hpsb_host *host,
+					      nodeid_t node, u64 addr,
+					      void * data, int tx_len)
+{
+	p->node_id = node;
+	p->data = NULL;
+
+	p->tcode = TCODE_WRITEB;
+	p->header[1] = (host->node_id << 16) | (addr >> 32);
+	p->header[2] = addr & 0xffffffff;
+
+	p->header_size = 16;
+	p->expect_response = 1;
+
+	if (hpsb_get_tlabel(p, !in_interrupt())) {
+		ETH1394_PRINT_G(KERN_ERR, "No more tlabels left while sending "
+				"to node " NODE_BUS_FMT "\n", NODE_BUS_ARGS(node));
+		return -1;
+	}		
+	p->header[0] = (p->node_id << 16) | (p->tlabel << 10)
+		| (1 << 8) | (TCODE_WRITEB << 4);
+
+	p->header[3] = tx_len << 16;
+	p->data_size = tx_len + (tx_len % 4 ? 4 - (tx_len % 4) : 0);
+	p->data = (quadlet_t*)data;
 
-/* This function is our scheduled write */
-static void hpsb_write_sched (void *__ptask)
+	return 0;
+}
+
+static inline void ether1394_prep_gasp_packet(struct hpsb_packet *p,
+					      struct eth1394_priv *priv,
+					      struct sk_buff *skb, int length)
 {
-	struct packet_task *ptask = (struct packet_task *)__ptask;
-	struct sk_buff *skb = ptask->skb;
-	struct net_device *dev = ptask->skb->dev;
-	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
-	unsigned long flags;
-	int status;
- 
+	p->header_size = 4;
+	p->tcode = TCODE_STREAM_DATA;
+
+	p->header[0] = (length << 16) | (3 << 14)
+		| ((priv->broadcast_channel) << 8)
+		| (TCODE_STREAM_DATA << 4);
+	p->data_size = length;
+	p->data = ((quadlet_t*)skb->data) - 2;
+	p->data[0] = cpu_to_be32((priv->host->node_id << 16) |
+				      ETHER1394_GASP_SPECIFIER_ID_HI);
+	p->data[1] = cpu_to_be32((ETHER1394_GASP_SPECIFIER_ID_LO << 24) |
+				      ETHER1394_GASP_VERSION);
+
+	/* Setting the node id to ALL_NODES (not LOCAL_BUS | ALL_NODES)
+	 * prevents hpsb_send_packet() from setting the speed to an arbitrary
+	 * value based on packet->node_id if packet->node_id is not set. */
+	p->node_id = ALL_NODES;
+	p->speed_code = priv->sspd[ALL_NODES];
+}
+
+static inline void ether1394_free_packet(struct hpsb_packet *packet)
+{
+	if (packet->tcode != TCODE_STREAM_DATA)
+		hpsb_free_tlabel(packet);
+	packet->data = NULL;
+	free_hpsb_packet(packet);
+}
+
+static void ether1394_complete_cb(void *__ptask);
+
+static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
+{
+	struct eth1394_priv *priv = ptask->priv;
+	struct hpsb_packet *packet = NULL;
+
+	packet = ether1394_alloc_common_packet(priv->host);
+	if (!packet)
+		return -1;
+
 	if (ptask->tx_type == ETH1394_GASP) {
-		status  = hpsb_send_gasp(priv->host, priv->broadcast_channel,
-					 get_hpsb_generation(priv->host),
-					 (quadlet_t *)skb->data, skb->len,
-					 ETHER1394_GASP_SPECIFIER_ID,
-					 ETHER1394_GASP_VERSION);
-	} else {
-		status = hpsb_write(priv->host, ptask->dest_node,
-				    get_hpsb_generation(priv->host),
-				    ptask->addr, (quadlet_t *)skb->data,
-				    skb->len);
+		int length = tx_len + (2 * sizeof(quadlet_t));
+
+		ether1394_prep_gasp_packet(packet, priv, ptask->skb, length);
+	} else if (ether1394_prep_write_packet(packet, priv->host,
+					       ptask->dest_node,
+					       ptask->addr, ptask->skb->data,
+					       tx_len)) {
+		goto fail;
 	}
 
+	ptask->packet = packet;
+	hpsb_set_packet_complete_task(ptask->packet, ether1394_complete_cb,
+				      ptask);
+
+	if (hpsb_send_packet(packet))
+		return 0;
+
+fail:
+	if (packet)
+		ether1394_free_packet(packet);
 
+	return -1;
+}
+
+
+/* Task function to be run when a datagram transmission is completed */
+static inline void ether1394_dg_complete(struct packet_task *ptask, int fail)
+{
+	struct sk_buff *skb = ptask->skb;
+	struct net_device *dev = skb->dev;
+	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+        unsigned long flags;
+		
 	/* Statistics */
-	spin_lock_irqsave (&priv->lock, flags);
-	if (!status) {
-		priv->stats.tx_bytes += skb->len;
-		priv->stats.tx_packets++;
-	} else {
-		//printk("Failed in hpsb_write_sched\n");
+	if (fail) {
+		spin_lock_irqsave(&priv->lock, flags);
 		priv->stats.tx_dropped++;
 		priv->stats.tx_errors++;
-		if (netif_queue_stopped (dev))
-			netif_wake_queue (dev);
+		spin_unlock_irqrestore(&priv->lock, flags);
+	} else {
+		spin_lock_irqsave(&priv->lock, flags);
+		priv->stats.tx_bytes += skb->len;
+		priv->stats.tx_packets++;
+		spin_unlock_irqrestore(&priv->lock, flags);
 	}
-	spin_unlock_irqrestore (&priv->lock, flags);
 
-	dev->trans_start = jiffies;
-	dev_kfree_skb(skb);
+	dev_kfree_skb_any(skb);
 	kmem_cache_free(packet_task_cache, ptask);
+}
 
-	return;
+
+/* Callback for when a packet has been sent and the status of that packet is
+ * known */
+static void ether1394_complete_cb(void *__ptask)
+{
+	struct packet_task *ptask = (struct packet_task *)__ptask;
+	struct hpsb_packet *packet = ptask->packet;
+	int fail = 0;
+
+	if (packet->tcode != TCODE_STREAM_DATA)
+		fail = hpsb_packet_success(packet);
+
+	ether1394_free_packet(packet);
+
+	ptask->outstanding_pkts--;
+	if (ptask->outstanding_pkts > 0 && !fail)
+	{
+		int tx_len;
+
+		/* Add the encapsulation header to the fragment */
+		tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload,
+					       &ptask->hdr);
+		if (ether1394_send_packet(ptask, tx_len))
+			ether1394_dg_complete(ptask, 1);
+	} else {
+		ether1394_dg_complete(ptask, fail);
+	}
 }
 
+
+
 /* Transmit a packet (called by kernel) */
 static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
 {
-	int kmflags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL;
-	struct ethhdr *eth;
+	int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
+	struct eth1394hdr *eth;
 	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
 	int proto;
 	unsigned long flags;
 	nodeid_t dest_node;
-	u64 addr;
-	struct packet_task *ptask = NULL;
+	eth1394_tx_type tx_type;
 	int ret = 0;
+	unsigned int tx_len;
+	unsigned int max_payload;
+	u16 dg_size;
+	u16 dgl;
+	struct packet_task *ptask;
+	struct node_entry *ne;
+
+	ptask = kmem_cache_alloc(packet_task_cache, kmflags);
+	if (ptask == NULL) {
+		ret = -ENOMEM;
+		goto fail;
+	}
 
 	spin_lock_irqsave (&priv->lock, flags);
 	if (priv->bc_state == ETHER1394_BC_CLOSED) {
 		ETH1394_PRINT(KERN_ERR, dev->name,
-			      "Cannot send packet, no broadcast channel available.");
+			      "Cannot send packet, no broadcast channel available.\n");
 		ret = -EAGAIN;
+		spin_unlock_irqrestore (&priv->lock, flags);
 		goto fail;
 	}
 
-	/* First time sending?  Need a broadcast channel for ARP and for
-	 * listening on */
 	if (priv->bc_state == ETHER1394_BC_CHECK) {
-		quadlet_t bc;
-
-		/* Get the local copy of the broadcast channel and check its
-		 * validity (the IRM should validate it for us) */
-
-		bc = priv->host->csr.broadcast_channel;
-
-		if ((bc & 0xc0000000) != 0xc0000000) {
-			/* broadcast channel not validated yet */
-			ETH1394_PRINT(KERN_WARNING, dev->name,
-				      "Error BROADCAST_CHANNEL register valid "
-				      "bit not set, can't send IP traffic\n");
-			hpsb_iso_shutdown(priv->iso);
-			priv->bc_state = ETHER1394_BC_CLOSED;
-			ret = -EAGAIN;
+		if (ether1394_init_bc(dev)) {
 			spin_unlock_irqrestore (&priv->lock, flags);
 			goto fail;
 		}
-		if (priv->broadcast_channel != (bc & 0x3f)) {
-			/* This really shouldn't be possible, but just in case
-			 * the IEEE 1394 spec changes regarding broadcast
-			 * channels in the future. */
-			hpsb_iso_shutdown(priv->iso);
-
-			priv->broadcast_channel = bc & 0x3f;
-			ETH1394_PRINT(KERN_WARNING, dev->name,
-				      "Changing to broadcast channel %d...\n",
-				      priv->broadcast_channel);
-
-			priv->iso = hpsb_iso_recv_init(priv->host, 8 * 4096,
-						       8, priv->broadcast_channel,
-						       1, ether1394_iso);
-			if (priv->iso == NULL) {
-				ret = -EAGAIN;
-				goto fail;
-			}
-		}
-		if (hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) {
-			ETH1394_PRINT(KERN_ERR, dev->name,
-				      "Could not start async reception\n");
-			hpsb_iso_shutdown(priv->iso);
-			priv->bc_state = ETHER1394_BC_CLOSED;
-			ret = -EAGAIN;
-			spin_unlock_irqrestore (&priv->lock, flags);
-			goto fail;
-		}
-		priv->bc_state = ETHER1394_BC_OPENED;
 	}
+
 	spin_unlock_irqrestore (&priv->lock, flags);
 
 	if ((skb = skb_share_check (skb, kmflags)) == NULL) {
@@ -809,70 +1476,160 @@
 		goto fail;
 	}
 
-	/* Get rid of the ethernet header, but save a pointer */
-	eth = (struct ethhdr *)skb->data;
-	skb_pull (skb, ETH_HLEN);
-
-	/* Save the destination id, and proto for our encapsulation, then
-	 * toss the ethernet header aside like the cheap whore it is.  */
-	dest_node = ntohs (*(nodeid_t *)(eth->h_dest));
+	/* Get rid of the fake eth1394 header, but save a pointer */
+	eth = (struct eth1394hdr*)skb->data;
+	skb_pull(skb, ETH1394_HLEN);
+
+	ne = hpsb_guid_get_entry(be64_to_cpu(*(u64*)eth->h_dest));
+	if (!ne)
+		dest_node = LOCAL_BUS | ALL_NODES;
+	else
+		dest_node = ne->nodeid;
+
 	proto = eth->h_proto;
 
 	/* If this is an ARP packet, convert it */
 	if (proto == __constant_htons (ETH_P_ARP))
 		ether1394_arp_to_1394arp (skb, dev);
 
-	ptask = kmem_cache_alloc(packet_task_cache, kmflags);
-	if (ptask == NULL) {
-		ret = -ENOMEM;
-		goto fail;
+	max_payload = priv->maxpayload[NODEID_TO_NODE(dest_node)];
+
+	/* This check should be unnecessary, but we'll keep it for safety for
+	 * a while longer. */
+	if (max_payload < 512) {
+		ETH1394_PRINT(KERN_WARNING, dev->name,
+			      "max_payload too small: %d   (setting to 512)\n",
+			      max_payload);
+		max_payload = 512;
 	}
 
-	/* Now add our encapsulation header */
-	ether1394_encapsulate (skb, dev, proto, ptask);
+	/* Set the transmission type for the packet.  ARP packets and IP
+	 * broadcast packets are sent via GASP. */
+	if (memcmp(eth->h_dest, dev->broadcast, ETH1394_ALEN) == 0 ||
+	    proto == __constant_htons(ETH_P_ARP) ||
+	    (proto == __constant_htons(ETH_P_IP) &&
+	     IN_MULTICAST(__constant_ntohl(skb->nh.iph->daddr)))) {
+		tx_type = ETH1394_GASP;
+                max_payload -= ETHER1394_GASP_OVERHEAD;
+	} else {
+		tx_type = ETH1394_WRREQ;
+	}
 
-	/* TODO: The above encapsulate function needs to recognize when a
-	 * packet needs to be split for a specified node. It should create
-	 * a list of skb's that we could then iterate over for the below
-	 * call to schedule our writes.  */
-
-	/* XXX: Right now we accept that we don't exactly follow RFC. When
-	 * we do, we will send ARP requests via GASP format, and so we won't
-	 * need this hack.  */
+	dg_size = skb->len;
 
 	spin_lock_irqsave (&priv->lock, flags);
-	addr = (u64)priv->fifo_hi[NODEID_TO_NODE(dest_node)] << 32 |
-		priv->fifo_lo[NODEID_TO_NODE(dest_node)];
+	dgl = priv->dgl[NODEID_TO_NODE(dest_node)];
+	if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF])
+		priv->dgl[NODEID_TO_NODE(dest_node)]++;
 	spin_unlock_irqrestore (&priv->lock, flags);
 
-	if (!addr)
-		addr = ETHER1394_REGION_ADDR;
-
+	ptask->hdr.words.word1 = 0;
+	ptask->hdr.words.word2 = 0;
+	ptask->hdr.words.word3 = 0;
+	ptask->hdr.words.word4 = 0;
 	ptask->skb = skb;
-	ptask->addr = addr;
-	ptask->dest_node = dest_node;
-	/* TODO: When 2.4 is out of the way, give each of our ethernet
-	 * dev's a workqueue to handle these.  */
-	INIT_TQUEUE(&ptask->tq, hpsb_write_sched, ptask);
-	schedule_task(&ptask->tq);
+	ptask->priv = priv;
+	ptask->tx_type = tx_type;
+
+	if (tx_type != ETH1394_GASP) {
+		u64 addr;
+
+		/* This test is just temporary until ConfigROM support has
+		 * been added to eth1394.  Until then, we need an ARP packet
+		 * after a bus reset from the current destination node so that
+		 * we can get FIFO information. */
+		if (priv->fifo[NODEID_TO_NODE(dest_node)] == 0ULL) {
+			ret = -EAGAIN;
+			goto fail;
+		}
+
+		spin_lock_irqsave(&priv->lock, flags);
+		addr = priv->fifo[NODEID_TO_NODE(dest_node)];
+		spin_unlock_irqrestore(&priv->lock, flags);
+
+		ptask->addr = addr;
+		ptask->dest_node = dest_node;
+	}
+
+	ptask->tx_type = tx_type;
+	ptask->max_payload = max_payload;
+        ptask->outstanding_pkts = ether1394_encapsulate_prep(max_payload, proto,
+							     &ptask->hdr, dg_size,
+							     dgl);
 
+	/* Add the encapsulation header to the fragment */
+	tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr);
+	dev->trans_start = jiffies;
+	if (ether1394_send_packet(ptask, tx_len))
+		goto fail;
+
+	netif_wake_queue(dev);
 	return 0;
 fail:
-	printk("Failed in ether1394_tx\n");
+	if (ptask)
+		kmem_cache_free(packet_task_cache, ptask);
 
 	if (skb != NULL)
-		dev_kfree_skb (skb);
+		dev_kfree_skb(skb);
 
 	spin_lock_irqsave (&priv->lock, flags);
 	priv->stats.tx_dropped++;
 	priv->stats.tx_errors++;
-	if (netif_queue_stopped (dev))
-		netif_wake_queue (dev);
 	spin_unlock_irqrestore (&priv->lock, flags);
 
+	if (netif_queue_stopped(dev))
+		netif_wake_queue(dev);
+
 	return 0;  /* returning non-zero causes serious problems */
 }
 
+static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	switch(cmd) {
+		case SIOCETHTOOL:
+			return ether1394_ethtool_ioctl(dev, (void *) ifr->ifr_data);
+
+		case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
+		case SIOCGMIIREG:		/* Read MII PHY register. */
+		case SIOCSMIIREG:		/* Write MII PHY register. */
+		default:
+			return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	u32 ethcmd;
+
+	if (get_user(ethcmd, (u32 *)useraddr))
+		return -EFAULT;
+
+	switch (ethcmd) {
+		case ETHTOOL_GDRVINFO: {
+			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+			strcpy (info.driver, driver_name);
+			strcpy (info.version, "$Rev: 970 $");
+			/* FIXME XXX provide sane businfo */
+			strcpy (info.bus_info, "ieee1394");
+			if (copy_to_user (useraddr, &info, sizeof (info)))
+				return -EFAULT;
+			break;
+		}
+		case ETHTOOL_GSET:
+		case ETHTOOL_SSET:
+		case ETHTOOL_NWAY_RST:
+		case ETHTOOL_GLINK:
+		case ETHTOOL_GMSGLVL:
+		case ETHTOOL_SMSGLVL:
+		default:
+			return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
 /* Function for incoming 1394 packets */
 static struct hpsb_address_ops addr_ops = {
 	.write =	ether1394_write,
@@ -880,7 +1637,7 @@
 
 /* Ieee1394 highlevel driver functions */
 static struct hpsb_highlevel eth1394_highlevel = {
-	.name =		ETHER1394_DRIVER_NAME,
+	.name =		driver_name,
 	.add_host =	ether1394_add_host,
 	.remove_host =	ether1394_remove_host,
 	.host_reset =	ether1394_host_reset,
diff -urN linux-2.4.22-pre2/drivers/ieee1394/eth1394.h linux-2.4.22-pre3/drivers/ieee1394/eth1394.h
--- linux-2.4.22-pre2/drivers/ieee1394/eth1394.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/eth1394.h	2003-07-05 18:10:00.000000000 -0700
@@ -24,6 +24,8 @@
 #ifndef __ETH1394_H
 #define __ETH1394_H
 
+#include "ieee1394.h"
+
 /* Register for incoming packets. This is 8192 bytes, which supports up to
  * 1600mbs. We'll need to change this if that ever becomes "small" :)  */
 #define ETHER1394_REGION_ADDR_LEN	8192
@@ -32,27 +34,38 @@
 
 /* GASP identifier numbers for IPv4 over IEEE 1394 */
 #define ETHER1394_GASP_SPECIFIER_ID	0x00005E
+#define ETHER1394_GASP_SPECIFIER_ID_HI	((ETHER1394_GASP_SPECIFIER_ID >> 8) & 0xffff)
+#define ETHER1394_GASP_SPECIFIER_ID_LO	(ETHER1394_GASP_SPECIFIER_ID & 0xff)
 #define ETHER1394_GASP_VERSION		1
 
+#define ETHER1394_GASP_OVERHEAD (2 * sizeof(quadlet_t))  /* GASP header overhead */
+
 /* Node set == 64 */
 #define NODE_SET			(ALL_NODES + 1)
 
 enum eth1394_bc_states { ETHER1394_BC_CLOSED, ETHER1394_BC_OPENED,
 			 ETHER1394_BC_CHECK };
 
+struct pdg_list {
+	struct list_head list;		/* partial datagram list per node */
+	unsigned int sz;		/* partial datagram list size per node	*/
+	spinlock_t lock;		/* partial datagram lock		*/
+};
+
 /* Private structure for our ethernet driver */
 struct eth1394_priv {
 	struct net_device_stats stats;	/* Device stats			 */
 	struct hpsb_host *host;		/* The card for this dev	 */
-	unsigned char max_rec[NODE_SET];/* Max payload per node		 */
+	u16 maxpayload[NODE_SET];	/* Max payload per node		 */
 	unsigned char sspd[NODE_SET];	/* Max speed per node		 */
-	u16 fifo_hi[ALL_NODES];		/* 16bit hi fifo offset per node */
-	u32 fifo_lo[ALL_NODES];		/* 32bit lo fifo offset per node */
+	u64 fifo[ALL_NODES];		/* FIFO offset per node		 */
 	u64 eui[ALL_NODES];		/* EUI-64 per node		 */
 	spinlock_t lock;		/* Private lock			 */
 	int broadcast_channel;		/* Async stream Broadcast Channel */
 	enum eth1394_bc_states bc_state; /* broadcast channel state	 */
 	struct hpsb_iso *iso;		/* Async stream recv handle	 */
+	struct pdg_list pdg[ALL_NODES]; /* partial RX datagram lists     */
+	int dgl[NODE_SET];              /* Outgoing datagram label per node */
 };
 
 struct host_info {
@@ -60,16 +73,22 @@
 	struct net_device *dev;
 };
 
-typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type;
 
-/* This is our task struct. It's used for the packet complete callback.  */
-struct packet_task {
-	struct sk_buff *skb;	/* Socket buffer we are sending */
-	nodeid_t dest_node;	/* Destination of the packet */
-	u64 addr;		/* Address */
-	struct tq_struct tq;	/* The task */
-	eth1394_tx_type tx_type;	/* Send data via GASP or Write Req. */
-};
+/* Define a fake hardware header format for the networking core.  Note that
+ * header size cannot exceed 16 bytes as that is the size of the header cache.
+ * Also, we do not need the source address in the header so we omit it and
+ * keep the header to under 16 bytes */
+#define ETH1394_ALEN (8)
+#define ETH1394_HLEN (10)
+
+struct eth1394hdr {
+	unsigned char	h_dest[ETH1394_ALEN];	/* destination eth1394 addr	*/
+	unsigned short	h_proto;		/* packet type ID field	*/
+}  __attribute__((packed));
+
+
+
+typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type;
 
 /* IP1394 headers */
 #include <asm/byteorder.h>
@@ -77,14 +96,14 @@
 /* Unfragmented */
 #if defined __BIG_ENDIAN_BITFIELD
 struct eth1394_uf_hdr {
-	u8 lf:2;
+	u16 lf:2;
 	u16 res:14;
 	u16 ether_type;		/* Ethernet packet type */
 } __attribute__((packed));
 #elif defined __LITTLE_ENDIAN_BITFIELD
 struct eth1394_uf_hdr {
 	u16 res:14;
-	u8 lf:2;
+	u16 lf:2;
 	u16 ether_type;
 } __attribute__((packed));
 #else
@@ -94,8 +113,8 @@
 /* First fragment */
 #if defined __BIG_ENDIAN_BITFIELD
 struct eth1394_ff_hdr {
-	u8 lf:2;
-	u8 res1:2;
+	u16 lf:2;
+	u16 res1:2;
 	u16 dg_size:12;		/* Datagram size */
 	u16 ether_type;		/* Ethernet packet type */
 	u16 dgl;		/* Datagram label */
@@ -104,8 +123,8 @@
 #elif defined __LITTLE_ENDIAN_BITFIELD
 struct eth1394_ff_hdr {
 	u16 dg_size:12;
-	u8 res1:2;
-	u8 lf:2;
+	u16 res1:2;
+	u16 lf:2;
 	u16 ether_type;
 	u16 dgl;
 	u16 res2;
@@ -117,21 +136,21 @@
 /* XXX: Subsequent fragments, including last */
 #if defined __BIG_ENDIAN_BITFIELD
 struct eth1394_sf_hdr {
-	u8 lf:2;
-	u8 res1:2;
+	u16 lf:2;
+	u16 res1:2;
 	u16 dg_size:12;		/* Datagram size */
-	u8 res2:6;
-	u16 fg_off:10;		/* Fragment offset */
+	u16 res2:4;
+	u16 fg_off:12;		/* Fragment offset */
 	u16 dgl;		/* Datagram label */
 	u16 res3;
 } __attribute__((packed));
 #elif defined __LITTLE_ENDIAN_BITFIELD
 struct eth1394_sf_hdr {
 	u16 dg_size:12;
-	u8 res1:2;
-	u8 lf:2;
-	u16 fg_off:10;
-	u8 res2:6;
+	u16 res1:2;
+	u16 lf:2;
+	u16 fg_off:12;
+	u16 res2:4;
 	u16 dgl;
 	u16 res3;
 } __attribute__((packed));
@@ -141,13 +160,13 @@
 
 #if defined __BIG_ENDIAN_BITFIELD
 struct eth1394_common_hdr {
-	u8 lf:2;
+	u16 lf:2;
 	u16 pad1:14;
 } __attribute__((packed));
 #elif defined __LITTLE_ENDIAN_BITFIELD
 struct eth1394_common_hdr {
 	u16 pad1:14;
-	u8 lf:2;
+	u16 lf:2;
 } __attribute__((packed));
 #else
 #error Unknown bit field type
@@ -199,4 +218,17 @@
 /* Network timeout */
 #define ETHER1394_TIMEOUT	100000
 
+/* This is our task struct. It's used for the packet complete callback.  */
+struct packet_task {
+	struct sk_buff *skb;
+	int outstanding_pkts;
+	eth1394_tx_type tx_type;
+	int max_payload;
+	struct hpsb_packet *packet;
+	struct eth1394_priv *priv;
+	union eth1394_hdr hdr;
+	u64 addr;
+	u16 dest_node;
+};
+
 #endif /* __ETH1394_H */
diff -urN linux-2.4.22-pre2/drivers/ieee1394/highlevel.c linux-2.4.22-pre3/drivers/ieee1394/highlevel.c
--- linux-2.4.22-pre2/drivers/ieee1394/highlevel.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/highlevel.c	2003-07-05 18:10:00.000000000 -0700
@@ -205,6 +205,29 @@
 }
 
 
+struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key)
+{
+	struct list_head *lh;
+	struct hl_host_info *hi;
+	struct hpsb_host *host = NULL;
+
+	if (!hl)
+		return NULL;
+
+	read_lock(&hl->host_info_lock);
+	list_for_each (lh, &hl->host_info_list) {
+		hi = list_entry(lh, struct hl_host_info, list);
+		if (hi->key == key) {
+			host = hi->host;
+			break;
+		}
+	}
+	read_unlock(&hl->host_info_lock);
+
+	return host;
+}
+
+
 void hpsb_register_highlevel(struct hpsb_highlevel *hl)
 {
 	struct list_head *lh;
diff -urN linux-2.4.22-pre2/drivers/ieee1394/highlevel.h linux-2.4.22-pre3/drivers/ieee1394/highlevel.h
--- linux-2.4.22-pre2/drivers/ieee1394/highlevel.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/highlevel.h	2003-07-05 18:10:00.000000000 -0700
@@ -155,19 +155,28 @@
 
 /* Retrieve a hostinfo pointer bound to this driver/host */
 void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
+
 /* Allocate a hostinfo pointer of data_size bound to this driver/host */
 void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
 			   size_t data_size);
+
 /* Free and remove the hostinfo pointer bound to this driver/host */
 void hpsb_destroy_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
+
 /* Set an alternate lookup key for the hostinfo bound to this driver/host */
 void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host, unsigned long key);
+
 /* Retrieve the alternate lookup key for the hostinfo bound to this driver/host */
 unsigned long hpsb_get_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host);
-/* Retrive a hostinfo pointer bound to this driver using its alternate key */
+
+/* Retrieve a hostinfo pointer bound to this driver using its alternate key */
 void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key);
+
 /* Set the hostinfo pointer to something useful. Usually follows a call to
  * hpsb_create_hostinfo, where the size is 0. */
 int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, void *data);
 
+/* Retrieve hpsb_host using a highlevel handle and a key */
+struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key);
+
 #endif /* IEEE1394_HIGHLEVEL_H */
diff -urN linux-2.4.22-pre2/drivers/ieee1394/ieee1394.h linux-2.4.22-pre3/drivers/ieee1394/ieee1394.h
--- linux-2.4.22-pre2/drivers/ieee1394/ieee1394.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/ieee1394.h	2003-07-05 18:10:00.000000000 -0700
@@ -46,18 +46,17 @@
 #define ACKX_TIMEOUT             (-4)
 
 
-#define SPEED_100		0x00
-#define SPEED_200		0x01
-#define SPEED_400		0x02
-#define SPEED_800		0x03
-#define SPEED_1600		0x04
-#define SPEED_3200		0x05
+#define IEEE1394_SPEED_100		0x00
+#define IEEE1394_SPEED_200		0x01
+#define IEEE1394_SPEED_400		0x02
+#define IEEE1394_SPEED_800		0x03
+#define IEEE1394_SPEED_1600		0x04
+#define IEEE1394_SPEED_3200		0x05
 /* The current highest tested speed supported by the subsystem */
-#define SPEED_MAX		SPEED_800
+#define IEEE1394_SPEED_MAX		IEEE1394_SPEED_800
 
 /* Maps speed values above to a string representation */
 extern const char *hpsb_speedto_str[];
-extern const u8 hpsb_speedto_maxrec[];
 
 
 #define SELFID_PWRCL_NO_POWER    0x0
diff -urN linux-2.4.22-pre2/drivers/ieee1394/ieee1394_core.c linux-2.4.22-pre3/drivers/ieee1394/ieee1394_core.c
--- linux-2.4.22-pre2/drivers/ieee1394/ieee1394_core.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/ieee1394_core.c	2003-07-05 18:10:00.000000000 -0700
@@ -41,7 +41,6 @@
 #include "ieee1394_transactions.h"
 #include "csr.h"
 #include "nodemgr.h"
-#include "ieee1394_hotplug.h"
 #include "dma.h"
 #include "iso.h"
 
@@ -59,7 +58,6 @@
 
 /* Some globals used */
 const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
-const u8 hpsb_speedto_maxrec[] = {   0x7,    0x8,    0x9,   0x10,    0x11,    0x12 };
 
 static void dump_packet(const char *text, quadlet_t *data, int size)
 {
@@ -78,9 +76,12 @@
 static void run_packet_complete(struct hpsb_packet *packet)
 {
 	if (packet->complete_routine != NULL) {
-		packet->complete_routine(packet->complete_data);
+		void (*complete_routine)(void*) = packet->complete_routine;
+		void *complete_data = packet->complete_data;
+
 		packet->complete_routine = NULL;
 		packet->complete_data = NULL;
+		complete_routine(complete_data);
 	}
 	return;
 }
@@ -285,7 +286,7 @@
 
         for (i = 0; i < (nodecount * 64); i += 64) {
                 for (j = 0; j < nodecount; j++) {
-                        map[i+j] = SPEED_MAX;
+                        map[i+j] = IEEE1394_SPEED_MAX;
                 }
         }
 
@@ -454,7 +455,7 @@
 	struct hpsb_packet *packet;
 	int retval = 0;
 
-	if(rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 ||
+	if (rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 ||
 	   (rootid == -1 && gapcnt == -1)) {
 		HPSB_DEBUG("Invalid Parameter: rootid = %d   gapcnt = %d",
 			   rootid, gapcnt);
@@ -466,22 +467,21 @@
 		return -ENOMEM;
 
 	packet->host = host;
-	packet->header_size = 16;
+	packet->header_size = 8;
 	packet->data_size = 0;
 	packet->expect_response = 0;
 	packet->no_waiter = 0;
 	packet->type = hpsb_raw;
 	packet->header[0] = 0;
-	if(rootid != -1)
+	if (rootid != -1)
 		packet->header[0] |= rootid << 24 | 1 << 23;
-	if(gapcnt != -1)
+	if (gapcnt != -1)
 		packet->header[0] |= gapcnt << 16 | 1 << 22;
 
 	packet->header[1] = ~packet->header[0];
 
 	packet->generation = get_hpsb_generation(host);
 
-	HPSB_DEBUG("Sending PHY configuration packet (I hope)...");
 	if (!hpsb_send_packet(packet)) {
 		retval = -EINVAL;
 		goto fail;
@@ -936,7 +936,7 @@
 {
         unsigned long flags;
         struct hpsb_packet *packet;
-        struct list_head *lh;
+        struct list_head *lh, *tlh;
         LIST_HEAD(llist);
 
         host->driver->devctl(host, CANCEL_REQUESTS, 0);
@@ -946,8 +946,9 @@
         INIT_LIST_HEAD(&host->pending_packets);
         spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 
-        list_for_each(lh, &llist) {
+        list_for_each_safe(lh, tlh, &llist) {
                 packet = list_entry(lh, struct hpsb_packet, list);
+                list_del(&packet->list);
                 packet->state = hpsb_complete;
                 packet->ack_code = ACKX_ABORTED;
                 up(&packet->state_change);
@@ -960,7 +961,7 @@
         unsigned long flags;
         struct hpsb_packet *packet;
         unsigned long expire;
-        struct list_head *lh, *next;
+        struct list_head *lh, *next, *tlh;
         LIST_HEAD(expiredlist);
 
         spin_lock_irqsave(&host->csr.lock, flags);
@@ -988,8 +989,9 @@
 
         spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 
-        list_for_each(lh, &expiredlist) {
+        list_for_each_safe(lh, tlh, &expiredlist) {
                 packet = list_entry(lh, struct hpsb_packet, list);
+                list_del(&packet->list);
                 packet->state = hpsb_complete;
                 packet->ack_code = ACKX_TIMEOUT;
                 up(&packet->state_change);
@@ -1027,12 +1029,12 @@
 {
 	int retval;
 
-	if( (blocknum < 0) || (blocknum > 15) )
+	if ( (blocknum < 0) || (blocknum > 15) )
 		return -EINVAL;
 
 	write_lock(&ieee1394_chardevs_lock);
 
-	if(ieee1394_chardevs[blocknum].file_ops == NULL) {
+	if (ieee1394_chardevs[blocknum].file_ops == NULL) {
 		/* grab the minor block */
 		ieee1394_chardevs[blocknum].file_ops = file_ops;
 		ieee1394_chardevs[blocknum].module = module;
@@ -1051,12 +1053,12 @@
 /* release a block of minor numbers */
 void ieee1394_unregister_chardev(int blocknum)
 {
-	if( (blocknum < 0) || (blocknum > 15) )
+	if ( (blocknum < 0) || (blocknum > 15) )
 		return;
 
 	write_lock(&ieee1394_chardevs_lock);
 
-	if(ieee1394_chardevs[blocknum].file_ops) {
+	if (ieee1394_chardevs[blocknum].file_ops) {
 		ieee1394_chardevs[blocknum].file_ops = NULL;
 		ieee1394_chardevs[blocknum].module = NULL;
 	}
@@ -1093,7 +1095,7 @@
 		goto out;
 
 	/* don't need try_inc_mod_count if the driver is non-modular */
-	if(*module && (try_inc_mod_count(*module) == 0))
+	if (*module && (try_inc_mod_count(*module) == 0))
 		goto out;
 
 	/* success! */
@@ -1137,7 +1139,7 @@
 
 	/* look up the driver */
 
-	if(ieee1394_get_chardev(blocknum, &module, &file_ops) == 0)
+	if (ieee1394_get_chardev(blocknum, &module, &file_ops) == 0)
 		return -ENODEV;
 
 	/* redirect all subsequent requests to the driver's
@@ -1150,7 +1152,7 @@
 	/* follow through with the open() */
 	retval = file_ops->open(inode, file);
 
-	if(retval == 0) {
+	if (retval == 0) {
 		
 		/* If the open() succeeded, then ieee1394 will be left
 		   with an extra module reference, so we discard it here.
@@ -1162,7 +1164,7 @@
 		   dropped by the VFS when the file is released.
 		*/
 		
-		if(THIS_MODULE)
+		if (THIS_MODULE)
 			__MOD_DEC_USE_COUNT((struct module*) THIS_MODULE);
 		
 		/* note that if ieee1394 is compiled into the kernel,
@@ -1175,7 +1177,7 @@
 		   extra reference we gave to the task-specific
 		   driver */
 		
-		if(module)
+		if (module)
 			__MOD_DEC_USE_COUNT(module);
 	
 		/* point the file's f_ops back to ieee1394. The VFS will then
@@ -1256,7 +1258,6 @@
 
 /** ieee1394_core.c **/
 EXPORT_SYMBOL(hpsb_speedto_str);
-EXPORT_SYMBOL(hpsb_speedto_maxrec);
 EXPORT_SYMBOL(hpsb_set_packet_complete_task);
 EXPORT_SYMBOL(alloc_hpsb_packet);
 EXPORT_SYMBOL(free_hpsb_packet);
@@ -1297,6 +1298,7 @@
 EXPORT_SYMBOL(hpsb_listen_channel);
 EXPORT_SYMBOL(hpsb_unlisten_channel);
 EXPORT_SYMBOL(hpsb_get_hostinfo);
+EXPORT_SYMBOL(hpsb_get_host_bykey);
 EXPORT_SYMBOL(hpsb_create_hostinfo);
 EXPORT_SYMBOL(hpsb_destroy_hostinfo);
 EXPORT_SYMBOL(hpsb_set_hostinfo_key);
diff -urN linux-2.4.22-pre2/drivers/ieee1394/ieee1394_core.h linux-2.4.22-pre3/drivers/ieee1394/ieee1394_core.h
--- linux-2.4.22-pre2/drivers/ieee1394/ieee1394_core.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/ieee1394_core.h	2003-07-05 18:10:00.000000000 -0700
@@ -34,7 +34,7 @@
         } __attribute__((packed)) state;
 
         /* These are core internal. */
-        char tlabel;
+        signed char tlabel;
         char ack_code;
         char tcode;
 
diff -urN linux-2.4.22-pre2/drivers/ieee1394/ieee1394_hotplug.h linux-2.4.22-pre3/drivers/ieee1394/ieee1394_hotplug.h
--- linux-2.4.22-pre2/drivers/ieee1394/ieee1394_hotplug.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/ieee1394_hotplug.h	2003-07-05 18:10:00.000000000 -0700
@@ -1,8 +1,7 @@
 #ifndef _IEEE1394_HOTPLUG_H
 #define _IEEE1394_HOTPLUG_H
 
-#include "ieee1394_core.h"
-#include "nodemgr.h"
+#include <linux/types.h>
 
 #define IEEE1394_MATCH_VENDOR_ID	0x0001
 #define IEEE1394_MATCH_MODEL_ID		0x0002
@@ -26,57 +25,4 @@
 	void *driver_data;
 };
 
-struct hpsb_protocol_driver {
-	/* The name of the driver, e.g. SBP2 or IP1394 */
-	const char *name;
-
-	/* 
-	 * The device id table describing the protocols and/or devices
-	 * supported by this driver.  This is used by the nodemgr to
-	 * decide if a driver could support a given node, but the
-	 * probe function below can implement further protocol
-	 * dependent or vendor dependent checking.
-	 */
-	struct ieee1394_device_id *id_table;
-
-	/* 
-	 * The probe function is called when a device is added to the
-	 * bus and the nodemgr finds a matching entry in the drivers
-	 * device id table or when registering this driver and a
-	 * previously unhandled device can be handled.  The driver may
-	 * decline to handle the device based on further investigation
-	 * of the device (or whatever reason) in which case a negative
-	 * error code should be returned, otherwise 0 should be
-	 * returned. The driver may use the driver_data field in the
-	 * unit directory to store per device driver specific data.
-	 */
-	int (*probe)(struct unit_directory *ud);
-
-	/* 
-	 * The disconnect function is called when a device is removed
-	 * from the bus or if it wasn't possible to read the guid
-	 * after the last bus reset.
-	 */
-	void (*disconnect)(struct unit_directory *ud);
-
-	/* 
-	 * The update function is called when the node has just
-	 * survived a bus reset, i.e. it is still present on the bus.
-	 * However, it may be necessary to reestablish the connection
-	 * or login into the node again, depending on the protocol.
-	 */
-	void (*update)(struct unit_directory *ud);
-
-	/* Driver in list of all registered drivers */
-	struct list_head list;
-
-	/* The list of unit directories managed by this driver */
-	struct list_head unit_directories;
-};
-
-int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
-void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
-
-void hpsb_release_unit_directory(struct unit_directory *ud);
-
 #endif /* _IEEE1394_HOTPLUG_H */
diff -urN linux-2.4.22-pre2/drivers/ieee1394/ieee1394_transactions.c linux-2.4.22-pre3/drivers/ieee1394/ieee1394_transactions.c
--- linux-2.4.22-pre2/drivers/ieee1394/ieee1394_transactions.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/ieee1394_transactions.c	2003-07-05 18:10:00.000000000 -0700
@@ -95,7 +95,7 @@
         packet->data_size = 0;
         packet->expect_response = 0;
         packet->type = hpsb_raw;             /* No CRC added */
-        packet->speed_code = SPEED_100; /* Force speed to be 100Mbps */
+        packet->speed_code = IEEE1394_SPEED_100; /* Force speed to be 100Mbps */
 }
 
 static void fill_async_stream_packet(struct hpsb_packet *packet, int length,
@@ -147,6 +147,8 @@
 	spin_lock_irqsave(&tp->lock, flags);
 	
 	packet->tlabel = find_next_zero_bit(tp->pool, 64, tp->next);
+	if (packet->tlabel > 63)
+		packet->tlabel = find_first_zero_bit(tp->pool, 64);
 	tp->next = (packet->tlabel + 1) % 64;
 	/* Should _never_ happen */
 	BUG_ON(test_and_set_bit(packet->tlabel, tp->pool));
@@ -573,10 +575,6 @@
 		   quadlet_t *buffer, size_t length, u32 specifier_id,
 		   unsigned int version)
 {
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
-	int i;
-#endif
-
 	struct hpsb_packet *packet;
 	int retval = 0;
 	u16 specifier_id_hi = (specifier_id & 0x00ffff00) >> 8;
@@ -604,14 +602,6 @@
 
 	memcpy(&(packet->data[2]), buffer, length - 4);
 
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
-	HPSB_DEBUG("GASP: packet->header_size = %d", packet->header_size);
-	HPSB_DEBUG("GASP: packet->data_size = %d", packet->data_size);
-
-	for(i=0; i<(packet->data_size/4); i++)
-		HPSB_DEBUG("GASP: data[%d]: 0x%08x", i*4, be32_to_cpu(packet->data[i]));
-#endif
-
 	packet->generation = generation;
 
 	packet->no_waiter = 1;
diff -urN linux-2.4.22-pre2/drivers/ieee1394/ieee1394_types.h linux-2.4.22-pre3/drivers/ieee1394/ieee1394_types.h
--- linux-2.4.22-pre2/drivers/ieee1394/ieee1394_types.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/ieee1394_types.h	2003-07-05 18:10:00.000000000 -0700
@@ -19,6 +19,15 @@
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 #endif
 
+#ifndef BITS_TO_LONGS	/* < 2.4.21-pre6 */
+#define BITS_TO_LONGS(bits) \
+	(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
+#define DECLARE_BITMAP(name,bits) \
+	unsigned long name[BITS_TO_LONGS(bits)]
+#define CLEAR_BITMAP(name,bits) \
+	memset(name, 0, BITS_TO_LONGS(bits)*sizeof(unsigned long))
+#endif
+
 
 /* Transaction Label handling */
 struct hpsb_tlabel_pool {
@@ -36,7 +45,7 @@
 	(_tp)->next = 0;			\
 	(_tp)->allocations = 0;			\
 	sema_init(&(_tp)->count, 63);		\
-} while(0)
+} while (0)
 
 
 typedef u32 quadlet_t;
diff -urN linux-2.4.22-pre2/drivers/ieee1394/iso.c linux-2.4.22-pre3/drivers/ieee1394/iso.c
--- linux-2.4.22-pre2/drivers/ieee1394/iso.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/iso.c	2003-07-05 18:10:00.000000000 -0700
@@ -10,6 +10,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/sched.h>
 #include "iso.h"
 
 void hpsb_iso_stop(struct hpsb_iso *iso)
@@ -24,7 +25,7 @@
 
 void hpsb_iso_shutdown(struct hpsb_iso *iso)
 {
-	if(iso->flags & HPSB_ISO_DRIVER_INIT) {
+	if (iso->flags & HPSB_ISO_DRIVER_INIT) {
 		hpsb_iso_stop(iso);
 		iso->host->driver->isoctl(iso, iso->type == HPSB_ISO_XMIT ?
 					  XMIT_SHUTDOWN : RECV_SHUTDOWN, 0);
@@ -32,7 +33,6 @@
 	}
 
 	dma_region_free(&iso->data_buf);
-	kfree(iso->infos);
 	kfree(iso);
 }
 
@@ -47,7 +47,7 @@
 	int dma_direction;
 
 	/* make sure driver supports the ISO API */
-	if(!host->driver->isoctl) {
+	if (!host->driver->isoctl) {
 		printk(KERN_INFO "ieee1394: host driver '%s' does not support the rawiso API\n",
 		       host->driver->name);
 		return NULL;
@@ -55,29 +55,26 @@
 
 	/* sanitize parameters */
 
-	if(buf_packets < 2)
+	if (buf_packets < 2)
 		buf_packets = 2;
 
-	if(irq_interval < 1 || irq_interval > buf_packets / 2)
+	if (irq_interval < 1 || irq_interval > buf_packets / 2)
 		irq_interval = buf_packets / 2;
 
-	if(channel < -1 || channel >= 64)
+	if (channel < -1 || channel >= 64)
 		return NULL;
 
 	/* channel = -1 is OK for multi-channel recv but not for xmit */
-	if(type == HPSB_ISO_XMIT && channel < 0)
+	if (type == HPSB_ISO_XMIT && channel < 0)
 		return NULL;
 
 	/* allocate and write the struct hpsb_iso */
 
-	iso = kmalloc(sizeof(*iso), SLAB_KERNEL);
-	if(!iso)
+	iso = kmalloc(sizeof(*iso) + buf_packets * sizeof(struct hpsb_iso_packet_info), GFP_KERNEL);
+	if (!iso)
 		return NULL;
 
-	/* allocate ringbuffer of packet descriptors */
-	iso->infos = kmalloc(buf_packets * sizeof(struct hpsb_iso_packet_info), SLAB_KERNEL);
-	if(!iso->infos)
-		return NULL;
+	iso->infos = (struct hpsb_iso_packet_info *)(iso + 1);
 
 	iso->type = type;
 	iso->host = host;
@@ -93,7 +90,7 @@
 	iso->first_packet = 0;
 	spin_lock_init(&iso->lock);
 
-	if(iso->type == HPSB_ISO_XMIT) {
+	if (iso->type == HPSB_ISO_XMIT) {
 		iso->n_ready_packets = iso->buf_packets;
 		dma_direction = PCI_DMA_TODEVICE;
 	} else {
@@ -106,7 +103,7 @@
 	iso->prebuffer = 0;
 
 	/* allocate the packet buffer */
-	if(dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction))
+	if (dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction))
 		goto err;
 
 	return iso;
@@ -140,13 +137,13 @@
 	struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT,
 						    data_buf_size, buf_packets,
 						    channel, irq_interval, callback);
-	if(!iso)
+	if (!iso)
 		return NULL;
 
 	iso->speed = speed;
 
 	/* tell the driver to start working */
-	if(host->driver->isoctl(iso, XMIT_INIT, 0))
+	if (host->driver->isoctl(iso, XMIT_INIT, 0))
 		goto err;
 
 	iso->flags |= HPSB_ISO_DRIVER_INIT;
@@ -167,11 +164,11 @@
 	struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV,
 						    data_buf_size, buf_packets,
 						    channel, irq_interval, callback);
-	if(!iso)
+	if (!iso)
 		return NULL;
 
 	/* tell the driver to start working */
-	if(host->driver->isoctl(iso, RECV_INIT, 0))
+	if (host->driver->isoctl(iso, RECV_INIT, 0))
 		goto err;
 
 	iso->flags |= HPSB_ISO_DRIVER_INIT;
@@ -184,21 +181,21 @@
 
 int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel)
 {
-	if(iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
+	if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
 		return -EINVAL;
 	return iso->host->driver->isoctl(iso, RECV_LISTEN_CHANNEL, channel);
 }
 
 int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel)
 {
-       if(iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
+       if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
                return -EINVAL;
        return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel);
 }
 
 int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask)
 {
-	if(iso->type != HPSB_ISO_RECV || iso->channel != -1)
+	if (iso->type != HPSB_ISO_RECV || iso->channel != -1)
 		return -EINVAL;
 	return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask);
 }
@@ -206,7 +203,7 @@
 static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle)
 {
 	int retval = iso->host->driver->isoctl(iso, XMIT_START, cycle);
-	if(retval)
+	if (retval)
 		return retval;
 
 	iso->flags |= HPSB_ISO_DRIVER_STARTED;
@@ -215,25 +212,25 @@
 
 int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer)
 {
-	if(iso->type != HPSB_ISO_XMIT)
+	if (iso->type != HPSB_ISO_XMIT)
 		return -1;
 
-	if(iso->flags & HPSB_ISO_DRIVER_STARTED)
+	if (iso->flags & HPSB_ISO_DRIVER_STARTED)
 		return 0;
 
-	if(cycle < -1)
+	if (cycle < -1)
 		cycle = -1;
-	else if(cycle >= 8000)
+	else if (cycle >= 8000)
 		cycle %= 8000;
 
 	iso->xmit_cycle = cycle;
 
-	if(prebuffer < 0)
+	if (prebuffer < 0)
 		prebuffer = iso->buf_packets;
-	else if(prebuffer == 0)
+	else if (prebuffer == 0)
 		prebuffer = 1;
 
-	if(prebuffer > iso->buf_packets)
+	if (prebuffer > iso->buf_packets)
 		prebuffer = iso->buf_packets;
 
 	iso->prebuffer = prebuffer;
@@ -250,20 +247,20 @@
 	int retval = 0;
 	int isoctl_args[3];
 
-	if(iso->type != HPSB_ISO_RECV)
+	if (iso->type != HPSB_ISO_RECV)
 		return -1;
 
-	if(iso->flags & HPSB_ISO_DRIVER_STARTED)
+	if (iso->flags & HPSB_ISO_DRIVER_STARTED)
 		return 0;
 
-	if(cycle < -1)
+	if (cycle < -1)
 		cycle = -1;
-	else if(cycle >= 8000)
+	else if (cycle >= 8000)
 		cycle %= 8000;
 
 	isoctl_args[0] = cycle;
 	
-	if(tag_mask < 0)
+	if (tag_mask < 0)
 		/* match all tags */
 		tag_mask = 0xF;
 	isoctl_args[1] = tag_mask;
@@ -271,7 +268,7 @@
 	isoctl_args[2] = sync;
 
 	retval = iso->host->driver->isoctl(iso, RECV_START, (unsigned long) &isoctl_args[0]);
-	if(retval)
+	if (retval)
 		return retval;
 
 	iso->flags |= HPSB_ISO_DRIVER_STARTED;
@@ -285,15 +282,15 @@
 				     unsigned int offset, unsigned short len,
 				     unsigned int *out_offset, unsigned short *out_len)
 {
-	if(offset >= iso->buf_size)
+	if (offset >= iso->buf_size)
 		return -EFAULT;
 
 	/* make sure the packet does not go beyond the end of the buffer */
-	if(offset + len > iso->buf_size)
+	if (offset + len > iso->buf_size)
 		return -EFAULT;
 
 	/* check for wrap-around */
-	if(offset + len < offset)
+	if (offset + len < offset)
 		return -EFAULT;
 
 	/* now we can trust 'offset' and 'length' */
@@ -310,18 +307,18 @@
 	unsigned long flags;
 	int rv;
 
-	if(iso->type != HPSB_ISO_XMIT)
+	if (iso->type != HPSB_ISO_XMIT)
 		return -EINVAL;
 
 	/* is there space in the buffer? */
-	if(iso->n_ready_packets <= 0) {
+	if (iso->n_ready_packets <= 0) {
 		return -EBUSY;
 	}
 
 	info = &iso->infos[iso->first_packet];
 
 	/* check for bogus offset/length */
-	if(hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len))
+	if (hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len))
 		return -EFAULT;
 
 	info->tag = tag;
@@ -330,7 +327,7 @@
 	spin_lock_irqsave(&iso->lock, flags);
 
 	rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long) info);
-	if(rv)
+	if (rv)
 		goto out;
 
 	/* increment cursors */
@@ -338,9 +335,9 @@
 	iso->xmit_cycle = (iso->xmit_cycle+1) % 8000;
 	iso->n_ready_packets--;
 
-	if(iso->prebuffer != 0) {
+	if (iso->prebuffer != 0) {
 		iso->prebuffer--;
-		if(iso->prebuffer <= 0) {
+		if (iso->prebuffer <= 0) {
 			iso->prebuffer = 0;
 			rv = do_iso_xmit_start(iso, iso->start_cycle);
 		}
@@ -353,7 +350,7 @@
 
 int hpsb_iso_xmit_sync(struct hpsb_iso *iso)
 {
-	if(iso->type != HPSB_ISO_XMIT)
+	if (iso->type != HPSB_ISO_XMIT)
 		return -EINVAL;
 
 	return wait_event_interruptible(iso->waitq, hpsb_iso_n_ready(iso) == iso->buf_packets);
@@ -374,7 +371,7 @@
 	iso->n_ready_packets++;
 	iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets;
 
-	if(iso->n_ready_packets == iso->buf_packets || error != 0) {
+	if (iso->n_ready_packets == iso->buf_packets || error != 0) {
 		/* the buffer has run empty! */
 		atomic_inc(&iso->overflows);
 	}
@@ -388,7 +385,7 @@
 	unsigned long flags;
 	spin_lock_irqsave(&iso->lock, flags);
 
-	if(iso->n_ready_packets == iso->buf_packets) {
+	if (iso->n_ready_packets == iso->buf_packets) {
 		/* overflow! */
 		atomic_inc(&iso->overflows);
 	} else {
@@ -413,14 +410,14 @@
 	unsigned int i;
 	int rv = 0;
 
-	if(iso->type != HPSB_ISO_RECV)
+	if (iso->type != HPSB_ISO_RECV)
 		return -1;
 
 	spin_lock_irqsave(&iso->lock, flags);
-	for(i = 0; i < n_packets; i++) {
+	for (i = 0; i < n_packets; i++) {
 		rv = iso->host->driver->isoctl(iso, RECV_RELEASE,
 					       (unsigned long) &iso->infos[iso->first_packet]);
-		if(rv)
+		if (rv)
 			break;
 
 		iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
@@ -434,6 +431,6 @@
 {
 	wake_up_interruptible(&iso->waitq);
 
-	if(iso->callback)
+	if (iso->callback)
 		iso->callback(iso);
 }
diff -urN linux-2.4.22-pre2/drivers/ieee1394/iso.h linux-2.4.22-pre3/drivers/ieee1394/iso.h
--- linux-2.4.22-pre2/drivers/ieee1394/iso.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/iso.h	2003-07-05 18:10:00.000000000 -0700
@@ -66,7 +66,7 @@
 	/* wait for buffer space */
 	wait_queue_head_t waitq;
 
-	int speed; /* SPEED_100, 200, or 400 */
+	int speed; /* IEEE1394_SPEED_100, 200, or 400 */
 	int channel; /* -1 if multichannel */
 
 	/* greatest # of packets between interrupts - controls
@@ -79,9 +79,6 @@
 	/* size of data_buf, in bytes (always a multiple of PAGE_SIZE) */
 	unsigned int buf_size;
 
-	/* ringbuffer of packet descriptors in regular kernel memory */
-	struct hpsb_iso_packet_info *infos;
-
 	/* # of packets in the ringbuffer */
 	unsigned int buf_packets;
 
@@ -118,6 +115,11 @@
 	/* cycle at which next packet will be transmitted,
 	   -1 if not known */
 	int xmit_cycle;
+
+	/* ringbuffer of packet descriptors in regular kernel memory
+	 * XXX Keep this last, since we use over-allocated memory from
+	 * this entry to fill this field. */
+	struct hpsb_iso_packet_info *infos;
 };
 
 /* functions available to high-level drivers (e.g. raw1394) */
diff -urN linux-2.4.22-pre2/drivers/ieee1394/nodemgr.c linux-2.4.22-pre3/drivers/ieee1394/nodemgr.c
--- linux-2.4.22-pre2/drivers/ieee1394/nodemgr.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/nodemgr.c	2003-07-05 18:10:00.000000000 -0700
@@ -23,9 +23,9 @@
 
 #include "ieee1394_types.h"
 #include "ieee1394.h"
+#include "nodemgr.h"
 #include "hosts.h"
 #include "ieee1394_transactions.h"
-#include "ieee1394_hotplug.h"
 #include "highlevel.h"
 #include "csr.h"
 #include "nodemgr.h"
@@ -92,15 +92,26 @@
 
 #ifdef CONFIG_PROC_FS
 
-#define PUTF(fmt, args...) out += sprintf(out, fmt, ## args)
+#define PUTF(fmt, args...)				\
+do {							\
+	len += sprintf(page + len, fmt, ## args);	\
+	pos = begin + len;				\
+	if (pos < off) {				\
+		len = 0;				\
+		begin = pos;				\
+	}						\
+	if (pos > off + count)				\
+		goto done_proc;				\
+} while (0)
+
 
 static int raw1394_read_proc(char *page, char **start, off_t off,
 			     int count, int *eof, void *data)
 {
 	struct list_head *lh;
 	struct node_entry *ne;
-	int len;
-	char *out = page;
+	off_t begin = 0, pos = 0;
+	int len = 0;
 
 	if (down_interruptible(&nodemgr_serialize))
 		return -EINTR;
@@ -180,18 +191,18 @@
 
 	}
 
+done_proc:
 	up(&nodemgr_serialize);
 
-	len = out - page;
-	len -= off;
-	if (len < count) {
+	*start = page + (off - begin);
+	len -= (off - begin);
+	if (len > count)
+		len = count;
+	else {
 		*eof = 1;
 		if (len <= 0)
 			return 0;
-	} else
-		len = count;
-
-        *start = page + off;
+	}
 
 	return len;
 }
@@ -1231,12 +1242,12 @@
 	/* If there is no bus manager then we should set the root node's
 	 * force_root bit to promote bus stability per the 1394
 	 * spec. (8.4.2.6) */
-	if (host->busmgr_id == 0x3f && host->node_count > 1)
+	if (host->busmgr_id == 0xffff && host->node_count > 1)
 	{
 		u16 root_node = host->node_count - 1;
-		struct node_entry *ne = hpsb_nodeid_get_entry(host, root_node);
+		struct node_entry *ne = find_entry_by_nodeid(host, root_node | LOCAL_BUS);
 
-		if (ne->busopt.cmc)
+		if (ne && ne->busopt.cmc)
 			hpsb_send_phy_config(host, root_node, -1);
 		else {
 			HPSB_DEBUG("The root node is not cycle master capable; "
diff -urN linux-2.4.22-pre2/drivers/ieee1394/nodemgr.h linux-2.4.22-pre3/drivers/ieee1394/nodemgr.h
--- linux-2.4.22-pre2/drivers/ieee1394/nodemgr.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/nodemgr.h	2003-07-05 18:10:00.000000000 -0700
@@ -20,6 +20,9 @@
 #ifndef _IEEE1394_NODEMGR_H
 #define _IEEE1394_NODEMGR_H
 
+#include "ieee1394_core.h"
+#include "ieee1394_hotplug.h"
+
 #define CONFIG_ROM_BUS_INFO_LENGTH(q)		((q) >> 24)
 #define CONFIG_ROM_BUS_CRC_LENGTH(q)		(((q) >> 16) & 0xff)
 #define CONFIG_ROM_BUS_CRC(q)			((q) & 0xffff)
@@ -152,6 +155,58 @@
 	quadlet_t quadlets[0];
 };
 
+struct hpsb_protocol_driver {
+	/* The name of the driver, e.g. SBP2 or IP1394 */
+	const char *name;
+
+	/*
+	 * The device id table describing the protocols and/or devices
+	 * supported by this driver.  This is used by the nodemgr to
+	 * decide if a driver could support a given node, but the
+	 * probe function below can implement further protocol
+	 * dependent or vendor dependent checking.
+	 */
+	struct ieee1394_device_id *id_table;
+
+	/*
+	 * The probe function is called when a device is added to the
+	 * bus and the nodemgr finds a matching entry in the drivers
+	 * device id table or when registering this driver and a
+	 * previously unhandled device can be handled.  The driver may
+	 * decline to handle the device based on further investigation
+	 * of the device (or whatever reason) in which case a negative
+	 * error code should be returned, otherwise 0 should be
+	 * returned. The driver may use the driver_data field in the
+	 * unit directory to store per device driver specific data.
+	 */
+	int (*probe)(struct unit_directory *ud);
+
+	/*
+	 * The disconnect function is called when a device is removed
+	 * from the bus or if it wasn't possible to read the guid
+	 * after the last bus reset.
+	 */
+	void (*disconnect)(struct unit_directory *ud);
+
+	/*
+	 * The update function is called when the node has just
+	 * survived a bus reset, i.e. it is still present on the bus.
+	 * However, it may be necessary to reestablish the connection
+	 * or login into the node again, depending on the protocol.
+	 */
+	void (*update)(struct unit_directory *ud);
+
+	/* Driver in list of all registered drivers */
+	struct list_head list;
+
+	/* The list of unit directories managed by this driver */
+	struct list_head unit_directories;
+};
+
+int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
+void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
+void hpsb_release_unit_directory(struct unit_directory *ud);
+
 static inline int hpsb_node_entry_valid(struct node_entry *ne)
 {
 	return ne->generation == get_hpsb_generation(ne->host);
diff -urN linux-2.4.22-pre2/drivers/ieee1394/ohci1394.c linux-2.4.22-pre3/drivers/ieee1394/ohci1394.c
--- linux-2.4.22-pre2/drivers/ieee1394/ohci1394.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/ohci1394.c	2003-07-05 18:10:00.000000000 -0700
@@ -164,7 +164,7 @@
 printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
 
 static char version[] __devinitdata =
-	"$Rev: 896 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 952 $ Ben Collins <bcollins@debian.org>";
 
 /* Module Parameters */
 MODULE_PARM(phys_dma,"i");
@@ -428,7 +428,7 @@
         d->buf_ind = 0;
         d->buf_offset = 0;
 
-	if(d->type == DMA_CTX_ISO) {
+	if (d->type == DMA_CTX_ISO) {
 		/* Clear contextControl */
 		reg_write(ohci, d->ctrlClear, 0xffffffff);
 
@@ -470,7 +470,7 @@
 	INIT_LIST_HEAD(&d->fifo_list);
 	INIT_LIST_HEAD(&d->pending_list);
 
-	if(d->type == DMA_CTX_ISO) {
+	if (d->type == DMA_CTX_ISO) {
 		/* enable interrupts */
 		reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1 << d->ctx);
 	}
@@ -490,8 +490,8 @@
 	DBGMSG(ohci->id,"Iso contexts reg: %08x implemented: %08x", reg, tmp);
 
 	/* Count the number of contexts */
-	for(i=0; i<32; i++) {
-	    	if(tmp & 1) ctx++;
+	for (i=0; i<32; i++) {
+	    	if (tmp & 1) ctx++;
 		tmp >>= 1;
 	}
 	return ctx;
@@ -623,8 +623,10 @@
 	u32 cycleTimer;
 	int idx = d->prg_ind;
 
-	DBGMSG(ohci->id, "Inserting packet for node %d, tlabel=%d, tcode=0x%x, speed=%d",
-			packet->node_id, packet->tlabel, packet->tcode, packet->speed_code);
+	DBGMSG(ohci->id, "Inserting packet for node " NODE_BUS_FMT
+	       ", tlabel=%d, tcode=0x%x, speed=%d",
+	       NODE_BUS_ARGS(packet->node_id), packet->tlabel,
+	       packet->tcode, packet->speed_code);
 
 	d->prg_cpu[idx]->begin.address = 0;
 	d->prg_cpu[idx]->begin.branchAddress = 0;
@@ -854,8 +856,8 @@
 		 * case. I don't see anyone sending ISO packets from
 		 * interrupt context anyway... */
 		
-		if(ohci->it_legacy_context.ohci == NULL) {
-			if(in_interrupt()) {
+		if (ohci->it_legacy_context.ohci == NULL) {
+			if (in_interrupt()) {
 				PRINT(KERN_ERR, ohci->id, 
 				      "legacy IT context cannot be initialized during interrupt");
 				return 0;
@@ -1081,7 +1083,7 @@
                 spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
                 DBGMSG(ohci->id, "Listening disabled on channel %d", arg);
 
-		if(ohci->ir_legacy_channels == 0) {
+		if (ohci->ir_legacy_channels == 0) {
 			free_dma_rcv_ctx(&ohci->ir_legacy_context);
 			DBGMSG(ohci->id, "ISO receive legacy context deactivated");
 		}
@@ -1169,7 +1171,7 @@
 	int ret = -ENOMEM;
 
 	recv = kmalloc(sizeof(*recv), SLAB_KERNEL);
-	if(!recv)
+	if (!recv)
 		return -ENOMEM;
 
 	iso->hostdata = recv;
@@ -1181,7 +1183,7 @@
 	/* use buffer-fill mode, unless irq_interval is 1
 	   (note: multichannel requires buffer-fill) */
 
-	if(iso->irq_interval == 1 && iso->channel != -1) {
+	if (iso->irq_interval == 1 && iso->channel != -1) {
 		recv->dma_mode = PACKET_PER_BUFFER_MODE;
 	} else {
 		recv->dma_mode = BUFFER_FILL_MODE;
@@ -1189,12 +1191,12 @@
 
 	/* set nblocks, buf_stride, block_irq_interval */
 
-	if(recv->dma_mode == BUFFER_FILL_MODE) {
+	if (recv->dma_mode == BUFFER_FILL_MODE) {
 		recv->buf_stride = PAGE_SIZE;
 
 		/* one block per page of data in the DMA buffer, minus the final guard page */
 		recv->nblocks = iso->buf_size/PAGE_SIZE - 1;
-		if(recv->nblocks < 3) {
+		if (recv->nblocks < 3) {
 			DBGMSG(ohci->id, "ohci_iso_recv_init: DMA buffer too small");
 			goto err;
 		}
@@ -1202,9 +1204,9 @@
 		/* iso->irq_interval is in packets - translate that to blocks */
 		/* (err, sort of... 1 is always the safest value) */
 		recv->block_irq_interval = iso->irq_interval / recv->nblocks;
-		if(recv->block_irq_interval*4 > recv->nblocks)
+		if (recv->block_irq_interval*4 > recv->nblocks)
 			recv->block_irq_interval = recv->nblocks/4;
-		if(recv->block_irq_interval < 1)
+		if (recv->block_irq_interval < 1)
 			recv->block_irq_interval = 1;
 
 	} else {
@@ -1218,10 +1220,10 @@
 
 		max_packet_size = iso->buf_size / iso->buf_packets;
 
-		for(recv->buf_stride = 8; recv->buf_stride < max_packet_size;
+		for (recv->buf_stride = 8; recv->buf_stride < max_packet_size;
 		    recv->buf_stride *= 2);
 	
-		if(recv->buf_stride*iso->buf_packets > iso->buf_size ||
+		if (recv->buf_stride*iso->buf_packets > iso->buf_size ||
 		   recv->buf_stride > PAGE_SIZE) {
 			/* this shouldn't happen, but anyway... */
 			DBGMSG(ohci->id, "ohci_iso_recv_init: problem choosing a buffer stride");
@@ -1250,7 +1252,7 @@
 				  ohci_iso_recv_packetperbuf_task,
 				  (unsigned long) iso);
 
-	if(ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0)
+	if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0)
 		goto err;
 
 	recv->task_active = 1;
@@ -1262,7 +1264,7 @@
 	recv->CommandPtr = OHCI1394_IsoRcvCommandPtr + 32 * ctx;
 	recv->ContextMatch = OHCI1394_IsoRcvContextMatch + 32 * ctx;
 
-	if(iso->channel == -1) {
+	if (iso->channel == -1) {
 		/* clear multi-channel selection mask */
 		reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiClear, 0xFFFFFFFF);
 		reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoClear, 0xFFFFFFFF);
@@ -1300,7 +1302,7 @@
 {
 	struct ohci_iso_recv *recv = iso->hostdata;
 
-	if(recv->task_active) {
+	if (recv->task_active) {
 		ohci_iso_recv_stop(iso);
 		ohci1394_unregister_iso_tasklet(recv->ohci, &recv->task);
 		recv->task_active = 0;
@@ -1370,7 +1372,7 @@
 	struct ohci_iso_recv *recv = iso->hostdata;
 	int reg, i;
 
-	if(channel < 32) {
+	if (channel < 32) {
 		reg = listen ? OHCI1394_IRMultiChanMaskLoSet : OHCI1394_IRMultiChanMaskLoClear;
 		i = channel;
 	} else {
@@ -1390,14 +1392,14 @@
 	struct ohci_iso_recv *recv = iso->hostdata;
 	int i;
 
-	for(i = 0; i < 64; i++) {
-		if(mask & (1ULL << i)) {
-			if(i < 32)
+	for (i = 0; i < 64; i++) {
+		if (mask & (1ULL << i)) {
+			if (i < 32)
 				reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoSet, (1 << i));
 			else
 				reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiSet, (1 << (i-32)));
 		} else {
-			if(i < 32)
+			if (i < 32)
 				reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoClear, (1 << i));
 			else
 				reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiClear, (1 << (i-32)));
@@ -1420,7 +1422,7 @@
 	/* always keep ISO headers */
 	command = (1 << 30);
 
-	if(recv->dma_mode == BUFFER_FILL_MODE)
+	if (recv->dma_mode == BUFFER_FILL_MODE)
 		command |= (1 << 31);
 
 	reg_write(recv->ohci, recv->ContextControlSet, command);
@@ -1428,7 +1430,7 @@
 	/* match on specified tags */
 	contextMatch = tag_mask << 28;
 
-	if(iso->channel == -1) {
+	if (iso->channel == -1) {
 		/* enable multichannel reception */
 		reg_write(recv->ohci, recv->ContextControlSet, (1 << 28));
 	} else {
@@ -1436,7 +1438,7 @@
 		contextMatch |= iso->channel;
 	}
 
-	if(cycle != -1) {
+	if (cycle != -1) {
 		u32 seconds;
 		
 		/* enable cycleMatch */
@@ -1457,7 +1459,7 @@
 		contextMatch |= cycle << 12;
 	}
 
-	if(sync != -1) {
+	if (sync != -1) {
 		/* set sync flag on first DMA descriptor */
 		struct dma_cmd *cmd = &recv->block[recv->block_dma];
 		cmd->control |= DMA_CTL_WAIT;
@@ -1489,7 +1491,7 @@
 	reg_read(recv->ohci, OHCI1394_IsochronousCycleTimer);
 
 	/* check RUN */
-	if(!(reg_read(recv->ohci, recv->ContextControlSet) & 0x8000)) {
+	if (!(reg_read(recv->ohci, recv->ContextControlSet) & 0x8000)) {
 		PRINT(KERN_ERR, recv->ohci->id,
 		      "Error starting IR DMA (ContextControl 0x%08x)\n",
 		      reg_read(recv->ohci, recv->ContextControlSet));
@@ -1514,6 +1516,7 @@
 	   so disable branch and enable interrupt */
 	next->branchAddress = 0;
 	next->control |= cpu_to_le32(3 << 20);
+	next->status = cpu_to_le32(recv->buf_stride);
 
 	/* link prev to next */	
 	prev->branchAddress = cpu_to_le32(dma_prog_region_offset_to_bus(&recv->prog,
@@ -1521,7 +1524,7 @@
 					  | 1); /* Z=1 */
 
 	/* disable interrupt on previous DMA descriptor, except at intervals */
-	if((prev_i % recv->block_irq_interval) == 0) {
+	if ((prev_i % recv->block_irq_interval) == 0) {
 		prev->control |= cpu_to_le32(3 << 20); /* enable interrupt */
 	} else {
 		prev->control &= cpu_to_le32(~(3<<20)); /* disable interrupt */
@@ -1541,7 +1544,7 @@
 	len = info->len;
 
 	/* add the wasted space for padding to 4 bytes */
-	if(len % 4)
+	if (len % 4)
 		len += 4 - (len % 4);
 
 	/* add 8 bytes for the OHCI DMA data format overhead */
@@ -1550,7 +1553,7 @@
 	recv->released_bytes += len;
 
 	/* have we released enough memory for one block? */
-	while(recv->released_bytes > recv->buf_stride) {
+	while (recv->released_bytes > recv->buf_stride) {
 		ohci_iso_recv_release_block(recv, recv->block_reader);
 		recv->block_reader = (recv->block_reader + 1) % recv->nblocks;
 		recv->released_bytes -= recv->buf_stride;
@@ -1560,7 +1563,7 @@
 static inline void ohci_iso_recv_release(struct hpsb_iso *iso, struct hpsb_iso_packet_info *info)
 {
 	struct ohci_iso_recv *recv = iso->hostdata;
-	if(recv->dma_mode == BUFFER_FILL_MODE) {
+	if (recv->dma_mode == BUFFER_FILL_MODE) {
 		ohci_iso_recv_bufferfill_release(recv, info);
 	} else {
 		ohci_iso_recv_release_block(recv, info - iso->infos);
@@ -1573,7 +1576,7 @@
 	int wake = 0;
 	int runaway = 0;
 		
-	while(1) {
+	while (1) {
 		/* we expect the next parsable packet to begin at recv->dma_offset */
 		/* note: packet layout is as shown in section 10.6.1.1 of the OHCI spec */
 		
@@ -1586,7 +1589,7 @@
 		unsigned int this_block = recv->dma_offset/recv->buf_stride;
 
 		/* don't loop indefinitely */
-		if(runaway++ > 100000) {
+		if (runaway++ > 100000) {
 			atomic_inc(&iso->overflows);
 			PRINT(KERN_ERR, recv->ohci->id,
 			      "IR DMA error - Runaway during buffer parsing!\n");
@@ -1594,7 +1597,7 @@
 		}
 
 		/* stop parsing once we arrive at block_dma (i.e. don't get ahead of DMA) */
-		if(this_block == recv->block_dma)
+		if (this_block == recv->block_dma)
 			break;
 
 		wake = 1;
@@ -1606,7 +1609,7 @@
 		
 		len = p[recv->dma_offset+2] | (p[recv->dma_offset+3] << 8);
 
-		if(len > 4096) {
+		if (len > 4096) {
 			PRINT(KERN_ERR, recv->ohci->id,
 			      "IR DMA error - bogus 'len' value %u\n", len);
 		}
@@ -1619,7 +1622,7 @@
 		recv->dma_offset += 4;
 		
 		/* check for wrap-around */
-		if(recv->dma_offset >= recv->buf_stride*recv->nblocks) {
+		if (recv->dma_offset >= recv->buf_stride*recv->nblocks) {
 			recv->dma_offset -= recv->buf_stride*recv->nblocks;
 		}
 
@@ -1630,12 +1633,12 @@
 		recv->dma_offset += len;
 
 		/* payload is padded to 4 bytes */
-		if(len % 4) { 
+		if (len % 4) { 
 			recv->dma_offset += 4 - (len%4);
 		}
 
 		/* check for wrap-around */
-		if(recv->dma_offset >= recv->buf_stride*recv->nblocks) {
+		if (recv->dma_offset >= recv->buf_stride*recv->nblocks) {
 			/* uh oh, the packet data wraps from the last
                            to the first DMA block - make the packet
                            contiguous by copying its "tail" into the
@@ -1644,7 +1647,7 @@
 			int guard_off = recv->buf_stride*recv->nblocks;
 			int tail_len = len - (guard_off - offset);
 
-			if(tail_len > 0  && tail_len < recv->buf_stride) {
+			if (tail_len > 0  && tail_len < recv->buf_stride) {
 				memcpy(iso->data_buf.kvirt + guard_off,
 				       iso->data_buf.kvirt,
 				       tail_len);
@@ -1661,14 +1664,14 @@
 		recv->dma_offset += 4;
 
 		/* check for wrap-around */
-		if(recv->dma_offset >= recv->buf_stride*recv->nblocks) {
+		if (recv->dma_offset >= recv->buf_stride*recv->nblocks) {
 			recv->dma_offset -= recv->buf_stride*recv->nblocks;
 		}
 
 		hpsb_iso_packet_received(iso, offset, len, cycle, channel, tag, sy);
 	}
 
-	if(wake)
+	if (wake)
 		hpsb_iso_wake(iso);
 }
 
@@ -1680,7 +1683,7 @@
 	int loop;
 
 	/* loop over all blocks */
-	for(loop = 0; loop < recv->nblocks; loop++) {
+	for (loop = 0; loop < recv->nblocks; loop++) {
 		
 		/* check block_dma to see if it's done */
 		
@@ -1694,18 +1697,18 @@
 
 		unsigned char event = xferstatus & 0x1F;
 
-		if(!event) {
+		if (!event) {
 			/* nothing has happened to this block yet */
 			break;
 		}
 
-		if(event != 0x11) {
+		if (event != 0x11) {
 			atomic_inc(&iso->overflows);
 			PRINT(KERN_ERR, recv->ohci->id,
 			      "IR DMA error - OHCI error code 0x%02x\n", event);
 		}
 
-		if(rescount != 0) {
+		if (rescount != 0) {
 			/* the card is still writing to this block;
 			   we can't touch it until it's done */
 			break;
@@ -1722,7 +1725,7 @@
 		/* advance block_dma */
 		recv->block_dma = (recv->block_dma + 1) % recv->nblocks;
 
-		if((recv->block_dma+1) % recv->nblocks == recv->block_reader) {
+		if ((recv->block_dma+1) % recv->nblocks == recv->block_reader) {
 			atomic_inc(&iso->overflows);
 			DBGMSG(recv->ohci->id, "ISO reception overflow - "
 			       "ran out of DMA blocks");
@@ -1741,7 +1744,7 @@
 	int wake = 0;
 	
 	/* loop over the entire buffer */
-	for(count = 0; count < recv->nblocks; count++) {
+	for (count = 0; count < recv->nblocks; count++) {
 		u32 packet_len = 0;
 		
 		/* pointer to the DMA descriptor */
@@ -1753,21 +1756,21 @@
 
 		unsigned char event = xferstatus & 0x1F;
 
-		if(!event) {
+		if (!event) {
 			/* this packet hasn't come in yet; we are done for now */
 			goto out;
 		}
 		
-		if(event == 0x11) {
+		if (event == 0x11) {
 			/* packet received successfully! */
 			
 			/* rescount is the number of bytes *remaining* in the packet buffer,
 			   after the packet was written */
 			packet_len = recv->buf_stride - rescount;
 
-		} else if(event == 0x02) {
+		} else if (event == 0x02) {
 			PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - packet too long for buffer\n");
-		} else if(event) {
+		} else if (event) {
 			PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - OHCI error code 0x%02x\n", event);
 		}
 
@@ -1806,7 +1809,7 @@
 	}
 
 out:
-	if(wake)
+	if (wake)
 		hpsb_iso_wake(iso);
 }
 
@@ -1850,7 +1853,7 @@
 	int ret = -ENOMEM;
 
 	xmit = kmalloc(sizeof(*xmit), SLAB_KERNEL);
-	if(!xmit)
+	if (!xmit)
 		return -ENOMEM;
 
 	iso->hostdata = xmit;
@@ -1861,13 +1864,13 @@
 
 	prog_size = sizeof(struct iso_xmit_cmd) * iso->buf_packets;
 
-	if(dma_prog_region_alloc(&xmit->prog, prog_size, xmit->ohci->dev))
+	if (dma_prog_region_alloc(&xmit->prog, prog_size, xmit->ohci->dev))
 		goto err;
 
 	ohci1394_init_iso_tasklet(&xmit->task, OHCI_ISO_TRANSMIT,
 				  ohci_iso_xmit_task, (unsigned long) iso);
 
-	if(ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0)
+	if (ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0)
 		goto err;
 
 	xmit->task_active = 1;
@@ -1893,7 +1896,7 @@
 	reg_write(xmit->ohci, OHCI1394_IsoXmitIntMaskClear, 1 << xmit->task.context);
 
 	/* halt DMA */
-	if(ohci1394_stop_context(xmit->ohci, xmit->ContextControlClear, NULL)) {
+	if (ohci1394_stop_context(xmit->ohci, xmit->ContextControlClear, NULL)) {
 		/* XXX the DMA context will lock up if you try to send too much data! */
 		PRINT(KERN_ERR, xmit->ohci->id,
 		      "you probably exceeded the OHCI card's bandwidth limit - "
@@ -1905,7 +1908,7 @@
 {
 	struct ohci_iso_xmit *xmit = iso->hostdata;
 
-	if(xmit->task_active) {
+	if (xmit->task_active) {
 		ohci_iso_xmit_stop(iso);
 		ohci1394_unregister_iso_tasklet(xmit->ohci, &xmit->task);
 		xmit->task_active = 0;
@@ -1924,7 +1927,7 @@
 	int count;
 
 	/* check the whole buffer if necessary, starting at pkt_dma */
-	for(count = 0; count < iso->buf_packets; count++) {
+	for (count = 0; count < iso->buf_packets; count++) {
 		int cycle;
 
 		/* DMA descriptor */
@@ -1934,12 +1937,12 @@
 		u16 xferstatus = le32_to_cpu(cmd->output_last.status) >> 16;
 		u8  event = xferstatus & 0x1F;
 
-		if(!event) {
+		if (!event) {
 			/* packet hasn't been sent yet; we are done for now */
 			break;
 		}
 
-		if(event != 0x11)
+		if (event != 0x11)
 			PRINT(KERN_ERR, xmit->ohci->id,
 			      "IT DMA error - OHCI error code 0x%02x\n", event);
 		
@@ -1956,7 +1959,7 @@
 		cmd->output_last.status = 0;
 	}
 
-	if(wake)
+	if (wake)
 		hpsb_iso_wake(iso);
 }
 
@@ -1973,7 +1976,7 @@
 
 	/* check that the packet doesn't cross a page boundary
 	   (we could allow this if we added OUTPUT_MORE descriptor support) */
-	if(cross_bound(info->offset, info->len)) {
+	if (cross_bound(info->offset, info->len)) {
 		PRINT(KERN_ERR, xmit->ohci->id,
 		      "rawiso xmit: packet %u crosses a page boundary",
 		      iso->first_packet);
@@ -2036,7 +2039,7 @@
 		dma_prog_region_offset_to_bus(&xmit->prog, sizeof(struct iso_xmit_cmd) * next_i) | 3);
 
 	/* disable interrupt, unless required by the IRQ interval */
-	if(prev_i % iso->irq_interval) {
+	if (prev_i % iso->irq_interval) {
 		prev->output_last.control &= cpu_to_le32(~(3 << 20)); /* no interrupt */
 	} else {
 		prev->output_last.control |= cpu_to_le32(3 << 20); /* enable interrupt */
@@ -2068,7 +2071,7 @@
 		  dma_prog_region_offset_to_bus(&xmit->prog, iso->pkt_dma * sizeof(struct iso_xmit_cmd)) | 3);
 
 	/* cycle match */
-	if(cycle != -1) {
+	if (cycle != -1) {
 		u32 start = cycle & 0x1FFF;
 		
 		/* 'cycle' is only mod 8000, but we also need two 'seconds' bits -
@@ -2094,7 +2097,7 @@
 	udelay(100);
 
 	/* check the RUN bit */
-	if(!(reg_read(xmit->ohci, xmit->ContextControlSet) & 0x8000)) {
+	if (!(reg_read(xmit->ohci, xmit->ContextControlSet) & 0x8000)) {
 		PRINT(KERN_ERR, xmit->ohci->id, "Error starting IT DMA (ContextControl 0x%08x)\n",
 		      reg_read(xmit->ohci, xmit->ContextControlSet));
 		return -1;
@@ -2451,7 +2454,7 @@
 				reg_write(ohci,OHCI1394_PhyReqFilterLoSet, 0x00000000);
 			}
 
-			DBGMSG(ohci->id, "PhyReqFilter=%08x%08x\n",
+			DBGMSG(ohci->id, "PhyReqFilter=%08x%08x",
 			       reg_read(ohci,OHCI1394_PhyReqFilterHiSet),
 			       reg_read(ohci,OHCI1394_PhyReqFilterLoSet));
 
@@ -2699,19 +2702,29 @@
 
 #ifdef OHCI1394_DEBUG
 		if (datasize)
-			DBGMSG(ohci->id,
-			       "Packet sent to node %d tcode=0x%X tLabel="
-			       "0x%02X ack=0x%X spd=%d dataLength=%d ctx=%d", 
-                                (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])
-                                        >>16)&0x3f,
-                                (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])
-                                        >>4)&0xf,
-                                (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])
-                                        >>10)&0x3f,
-                                status&0x1f, (status>>5)&0x3, 
-                                le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3])
-                                        >>16,
-                                d->ctx);
+			if (((le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf) == 0xa)
+				DBGMSG(ohci->id,
+				       "Stream packet sent to channel %d tcode=0x%X "
+				       "ack=0x%X spd=%d dataLength=%d ctx=%d", 
+				       (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>8)&0x3f,
+				       (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf,
+				       status&0x1f, (status>>5)&0x3, 
+				       le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])>>16,
+				       d->ctx);
+			else
+				DBGMSG(ohci->id,
+				       "Packet sent to node %d tcode=0x%X tLabel="
+				       "%d ack=0x%X spd=%d dataLength=%d ctx=%d", 
+				       (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])
+                                        	>>16)&0x3f,
+				       (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])
+                                        	>>4)&0xf,
+				       (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])
+                                        	>>10)&0x3f,
+				       status&0x1f, (status>>5)&0x3, 
+				       le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3])
+				       		>>16,
+				       d->ctx);
 		else 
 			DBGMSG(ohci->id,
 			       "Packet sent to node %d tcode=0x%X tLabel="
@@ -2806,7 +2819,7 @@
 
 	DBGMSG(d->ohci->id, "Freeing dma_rcv_ctx %d", d->ctx);
 
-	if(d->ctrlClear) {
+	if (d->ctrlClear) {
 		ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
 
 		if (d->type == DMA_CTX_ISO) {
@@ -2968,7 +2981,7 @@
 
 	DBGMSG(d->ohci->id, "Freeing dma_trm_ctx %d", d->ctx);
 
-	if(d->ctrlClear) {
+	if (d->ctrlClear) {
 		ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
 
 		if (d->type == DMA_CTX_ISO) {
@@ -3164,7 +3177,7 @@
 	struct config_rom_ptr cr;
 
 	memset(&cr, 0, sizeof(cr));
-	memset(ohci->csr_config_rom_cpu, 0, sizeof (ohci->csr_config_rom_cpu));
+	memset(ohci->csr_config_rom_cpu, 0, OHCI_CONFIG_ROM_LEN);
 
 	cr.data = ohci->csr_config_rom_cpu;
 
@@ -3259,7 +3272,7 @@
 	PRINT_G(KERN_ERR, fmt , ## args);	\
         ohci1394_pci_remove(dev);               \
 	return err;				\
-} while(0)
+} while (0)
 
 static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
 					const struct pci_device_id *ent)
@@ -3528,6 +3541,16 @@
 	}
 }
 
+
+#ifdef  CONFIG_PM
+static int ohci1394_pci_resume (struct pci_dev *dev)
+{
+	pci_enable_device(dev);
+	return 0;
+}
+#endif
+
+
 #define PCI_CLASS_FIREWIRE_OHCI     ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)
 
 static struct pci_device_id ohci1394_pci_tbl[] __devinitdata = {
@@ -3549,6 +3572,10 @@
 	.id_table =	ohci1394_pci_tbl,
 	.probe =	ohci1394_pci_probe,
 	.remove =	ohci1394_pci_remove,
+
+#ifdef  CONFIG_PM
+	.resume =	ohci1394_pci_resume,
+#endif  /* PM */
 };
 
 
@@ -3608,8 +3635,8 @@
 		usage = &ohci->ir_ctx_usage;
 
 		/* only one receive context can be multichannel (OHCI sec 10.4.1) */
-		if(tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) {
-			if(test_and_set_bit(0, &ohci->ir_multichannel_used)) {
+		if (tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) {
+			if (test_and_set_bit(0, &ohci->ir_multichannel_used)) {
 				return r;
 			}
 		}
@@ -3644,7 +3671,7 @@
 	else {
 		clear_bit(tasklet->context, &ohci->ir_ctx_usage);
 
-		if(tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) {
+		if (tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) {
 			clear_bit(0, &ohci->ir_multichannel_used);
 		}
 	}
diff -urN linux-2.4.22-pre2/drivers/ieee1394/oui.db linux-2.4.22-pre3/drivers/ieee1394/oui.db
--- linux-2.4.22-pre2/drivers/ieee1394/oui.db	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/drivers/ieee1394/oui.db	2003-07-05 18:10:00.000000000 -0700
@@ -0,0 +1,4931 @@
+000000 XEROX CORPORATION
+000001 XEROX CORPORATION
+000002 XEROX CORPORATION
+000003 XEROX CORPORATION
+000004 XEROX CORPORATION
+000005 XEROX CORPORATION
+000006 XEROX CORPORATION
+000007 XEROX CORPORATION
+000008 XEROX CORPORATION
+000009 XEROX CORPORATION
+00000A OMRON TATEISI ELECTRONICS CO.
+00000B MATRIX CORPORATION
+00000C CISCO SYSTEMS, INC.
+00000D FIBRONICS LTD.
+00000E FUJITSU LIMITED
+00000F NEXT, INC.
+000010 SYTEK INC.
+000011 NORMEREL SYSTEMES
+000012 INFORMATION TECHNOLOGY LIMITED
+000013 CAMEX
+000014 NETRONIX
+000015 DATAPOINT CORPORATION
+000016 DU PONT PIXEL SYSTEMS     .
+000017 TEKELEC
+000018 WEBSTER COMPUTER CORPORATION
+000019 APPLIED DYNAMICS INTERNATIONAL
+00001A ADVANCED MICRO DEVICES
+00001B NOVELL INC.
+00001C BELL TECHNOLOGIES
+00001D CABLETRON SYSTEMS, INC.
+00001E TELSIST INDUSTRIA ELECTRONICA
+00001F Telco Systems, Inc.
+000020 DATAINDUSTRIER DIAB AB
+000021 SUREMAN COMP. & COMMUN. CORP.
+000022 VISUAL TECHNOLOGY INC.
+000023 ABB INDUSTRIAL SYSTEMS AB
+000024 CONNECT AS
+000025 RAMTEK CORP.
+000026 SHA-KEN CO., LTD.
+000027 JAPAN RADIO COMPANY
+000028 PRODIGY SYSTEMS CORPORATION
+000029 IMC NETWORKS CORP.
+00002A TRW - SEDD/INP
+00002B CRISP AUTOMATION, INC
+00002C AUTOTOTE LIMITED
+00002D CHROMATICS INC
+00002E SOCIETE EVIRA
+00002F TIMEPLEX INC.
+000030 VG LABORATORY SYSTEMS LTD
+000031 QPSX COMMUNICATIONS PTY LTD
+000032 Marconi plc
+000033 EGAN MACHINERY COMPANY
+000034 NETWORK RESOURCES CORPORATION
+000035 SPECTRAGRAPHICS CORPORATION
+000036 ATARI CORPORATION
+000037 OXFORD METRICS LIMITED
+000038 CSS LABS
+000039 TOSHIBA CORPORATION
+00003A CHYRON CORPORATION
+00003B i Controls, Inc.
+00003C AUSPEX SYSTEMS INC.
+00003D UNISYS
+00003E SIMPACT
+00003F SYNTREX, INC.
+000040 APPLICON, INC.
+000041 ICE CORPORATION
+000042 METIER MANAGEMENT SYSTEMS LTD.
+000043 MICRO TECHNOLOGY
+000044 CASTELLE CORPORATION
+000045 FORD AEROSPACE & COMM. CORP.
+000046 OLIVETTI NORTH AMERICA
+000047 NICOLET INSTRUMENTS CORP.
+000048 SEIKO EPSON CORPORATION
+000049 APRICOT COMPUTERS, LTD
+00004A ADC CODENOLL TECHNOLOGY CORP.
+00004B ICL DATA OY
+00004C NEC CORPORATION
+00004D DCI CORPORATION
+00004E AMPEX CORPORATION
+00004F LOGICRAFT, INC.
+000050 RADISYS CORPORATION
+000051 HOB ELECTRONIC GMBH & CO. KG
+000052 Intrusion.com, Inc.
+000053 COMPUCORP
+000054 MODICON, INC.
+000055 COMMISSARIAT A L`ENERGIE ATOM.
+000056 DR. B. STRUCK
+000057 SCITEX CORPORATION LTD.
+000058 RACORE COMPUTER PRODUCTS INC.
+000059 HELLIGE GMBH
+00005A SysKonnect GmbH
+00005B ELTEC ELEKTRONIK AG
+00005C TELEMATICS INTERNATIONAL INC.
+00005D CS TELECOM
+00005E USC INFORMATION SCIENCES INST
+00005F SUMITOMO ELECTRIC IND., LTD.
+000060 KONTRON ELEKTRONIK GMBH
+000061 GATEWAY COMMUNICATIONS
+000062 BULL HN INFORMATION SYSTEMS
+000063 DR.ING.SEUFERT GMBH
+000064 YOKOGAWA DIGITAL COMPUTER CORP
+000065 NETWORK ASSOCIATES, INC.
+000066 TALARIS SYSTEMS, INC.
+000067 SOFT * RITE, INC.
+000068 ROSEMOUNT CONTROLS
+000069 CONCORD COMMUNICATIONS INC
+00006A COMPUTER CONSOLES INC.
+00006B SILICON GRAPHICS INC./MIPS
+00006D CRAY COMMUNICATIONS, LTD.
+00006E ARTISOFT, INC.
+00006F MADGE NETWORKS LTD.
+000070 HCL LIMITED
+000071 ADRA SYSTEMS INC.
+000072 MINIWARE TECHNOLOGY
+000073 SIECOR CORPORATION
+000074 RICOH COMPANY LTD.
+000075 Nortel Networks
+000076 ABEKAS VIDEO SYSTEM
+000077 INTERPHASE CORPORATION
+000078 LABTAM LIMITED
+000079 NETWORTH INCORPORATED
+00007A DANA COMPUTER INC.
+00007B RESEARCH MACHINES
+00007C AMPERE INCORPORATED
+00007D SUN MICROSYSTEMS, INC.
+00007E CLUSTRIX CORPORATION
+00007F LINOTYPE-HELL AG
+000080 CRAY COMMUNICATIONS A/S
+000081 BAY NETWORKS
+000082 LECTRA SYSTEMES SA
+000083 TADPOLE TECHNOLOGY PLC
+000084 SUPERNET
+000085 CANON INC.
+000086 MEGAHERTZ CORPORATION
+000087 HITACHI, LTD.
+000088 COMPUTER NETWORK TECH. CORP.
+000089 CAYMAN SYSTEMS INC.
+00008A DATAHOUSE INFORMATION SYSTEMS
+00008B INFOTRON
+00008C ALLOY COMPUTER PRODUCTS, INC.
+00008D VERDIX CORPORATION
+00008E SOLBOURNE COMPUTER, INC.
+00008F RAYTHEON COMPANY
+000090 MICROCOM
+000091 ANRITSU CORPORATION
+000092 COGENT DATA TECHNOLOGIES
+000093 PROTEON INC.
+000094 ASANTE TECHNOLOGIES
+000095 SONY TEKTRONIX CORP.
+000096 MARCONI ELECTRONICS LTD.
+000097 EPOCH SYSTEMS
+000098 CROSSCOMM CORPORATION
+000099 MTX, INC.
+00009A RC COMPUTER A/S
+00009B INFORMATION INTERNATIONAL, INC
+00009C ROLM MIL-SPEC COMPUTERS
+00009D LOCUS COMPUTING CORPORATION
+00009E MARLI S.A.
+00009F AMERISTAR TECHNOLOGIES INC.
+0000A0 TOKYO SANYO ELECTRIC CO. LTD.
+0000A1 MARQUETTE ELECTRIC CO.
+0000A2 BAY NETWORKS
+0000A3 NETWORK APPLICATION TECHNOLOGY
+0000A4 ACORN COMPUTERS LIMITED
+0000A5 COMPATIBLE SYSTEMS CORP.
+0000A6 NETWORK GENERAL CORPORATION
+0000A7 NETWORK COMPUTING DEVICES INC.
+0000A8 STRATUS COMPUTER INC.
+0000A9 NETWORK SYSTEMS CORP.
+0000AA XEROX CORPORATION
+0000AB LOGIC MODELING CORPORATION
+0000AC CONWARE COMPUTER CONSULTING
+0000AD BRUKER INSTRUMENTS INC.
+0000AE DASSAULT ELECTRONIQUE
+0000AF NUCLEAR DATA INSTRUMENTATION
+0000B0 RND-RAD NETWORK DEVICES
+0000B1 ALPHA MICROSYSTEMS INC.
+0000B2 TELEVIDEO SYSTEMS, INC.
+0000B3 CIMLINC INCORPORATED
+0000B4 EDIMAX COMPUTER COMPANY
+0000B5 DATABILITY SOFTWARE SYS. INC.
+0000B6 MICRO-MATIC RESEARCH
+0000B7 DOVE COMPUTER CORPORATION
+0000B8 SEIKOSHA CO., LTD.
+0000B9 MCDONNELL DOUGLAS COMPUTER SYS
+0000BA SIIG, INC.
+0000BB TRI-DATA
+0000BC ALLEN-BRADLEY CO. INC.
+0000BD MITSUBISHI CABLE COMPANY
+0000BE THE NTI GROUP
+0000BF SYMMETRIC COMPUTER SYSTEMS
+0000C0 WESTERN DIGITAL CORPORATION
+0000C1 Madge Networks Ltd.
+0000C2 INFORMATION PRESENTATION TECH.
+0000C3 HARRIS CORP COMPUTER SYS DIV
+0000C4 WATERS DIV. OF MILLIPORE
+0000C5 FARALLON COMPUTING/NETOPIA
+0000C6 EON SYSTEMS
+0000C7 ARIX CORPORATION
+0000C8 ALTOS COMPUTER SYSTEMS
+0000C9 EMULEX CORPORATION
+0000CA APPLITEK
+0000CB COMPU-SHACK ELECTRONIC GMBH
+0000CC DENSAN CO., LTD.
+0000CD Centrecom Systems, Ltd.
+0000CE MEGADATA CORP.
+0000CF HAYES MICROCOMPUTER PRODUCTS
+0000D0 DEVELCON ELECTRONICS LTD.
+0000D1 ADAPTEC INCORPORATED
+0000D2 SBE, INC.
+0000D3 WANG LABORATORIES INC.
+0000D4 PURE DATA LTD.
+0000D5 MICROGNOSIS INTERNATIONAL
+0000D6 PUNCH LINE HOLDING
+0000D7 DARTMOUTH COLLEGE
+0000D8 NOVELL, INC.
+0000D9 NIPPON TELEGRAPH & TELEPHONE
+0000DA ATEX
+0000DB BRITISH TELECOMMUNICATIONS PLC
+0000DC HAYES MICROCOMPUTER PRODUCTS
+0000DD TCL INCORPORATED
+0000DE CETIA
+0000DF BELL & HOWELL PUB SYS DIV
+0000E0 QUADRAM CORP.
+0000E1 GRID SYSTEMS
+0000E2 ACER TECHNOLOGIES CORP.
+0000E3 INTEGRATED MICRO PRODUCTS LTD
+0000E4 IN2 GROUPE INTERTECHNIQUE
+0000E5 SIGMEX LTD.
+0000E6 APTOR PRODUITS DE COMM INDUST
+0000E7 STAR GATE TECHNOLOGIES
+0000E8 ACCTON TECHNOLOGY CORP.
+0000E9 ISICAD, INC.
+0000EA UPNOD AB
+0000EB MATSUSHITA COMM. IND. CO. LTD.
+0000EC MICROPROCESS
+0000ED APRIL
+0000EE NETWORK DESIGNERS, LTD.
+0000EF KTI
+0000F0 SAMSUNG ELECTRONICS CO., LTD.
+0000F1 MAGNA COMPUTER CORPORATION
+0000F2 SPIDER COMMUNICATIONS
+0000F3 GANDALF DATA LIMITED
+0000F4 ALLIED TELESYN INTERNATIONAL
+0000F5 DIAMOND SALES LIMITED
+0000F6 APPLIED MICROSYSTEMS CORP.
+0000F7 YOUTH KEEP ENTERPRISE CO LTD
+0000F8 DIGITAL EQUIPMENT CORPORATION
+0000F9 QUOTRON SYSTEMS INC.
+0000FA MICROSAGE COMPUTER SYSTEMS INC
+0000FB RECHNER ZUR KOMMUNIKATION
+0000FC MEIKO
+0000FD HIGH LEVEL HARDWARE
+0000FE ANNAPOLIS MICRO SYSTEMS
+0000FF CAMTEC ELECTRONICS LTD.
+000100 EQUIP'TRANS
+000102 3COM CORPORATION
+000103 3COM CORPORATION
+000104 DVICO Co., Ltd.
+000105 BECKHOFF GmbH
+000106 Tews Datentechnik GmbH
+000107 Leiser GmbH
+000108 AVLAB Technology, Inc.
+000109 Nagano Japan Radio Co., Ltd.
+00010A CIS TECHNOLOGY INC.
+00010B Space CyberLink, Inc.
+00010C System Talks Inc.
+00010D CORECO, INC.
+00010E Bri-Link Technologies Co., Ltd
+00010F Nishan Systems, Inc.
+000110 Gotham Networks
+000111 iDigm Inc.
+000112 Shark Multimedia Inc.
+000113 OLYMPUS OPTICAL CO., LTD.
+000114 KANDA TSUSHIN KOGYO CO., LTD.
+000115 EXTRATECH CORPORATION
+000116 Netspect Technologies, Inc.
+000117 CANAL +
+000118 EZ Digital Co., Ltd.
+000119 Action Controls Pty. Ltd.
+00011A EEH DataLink GmbH
+00011B Unizone Technologies, Inc.
+00011C Universal Talkware Corporation
+00011D Centillium Communications
+00011E Precidia Technologies, Inc.
+00011F RC Networks, Inc.
+000120 OSCILLOQUARTZ S.A.
+000121 RapidStream Inc.
+000122 Trend Communications, Ltd.
+000123 DIGITAL ELECTRONICS CORP.
+000124 Acer Incorporated
+000125 YAESU MUSEN CO., LTD.
+000126 PAC Labs
+000127 The OPEN Group Limited
+000128 EnjoyWeb, Inc.
+000129 DFI Inc.
+00012A Telematica Sistems Inteligente
+00012B TELENET Co., Ltd.
+00012C Aravox Technologies, Inc.
+00012D Komodo Technology
+00012E PC Partner Ltd.
+00012F Twinhead International Corp
+000130 Extreme Networks
+000131 Detection Systems, Inc.
+000132 Dranetz - BMI
+000133 KYOWA Electronic Instruments C
+000134 SIG Positec Systems AG
+000135 KDC Corp.
+000136 CyberTAN Technology, Inc.
+000137 IT Farm Corporation
+000138 XAVi Technologies Corp.
+000139 Point Multimedia Systems
+00013A SHELCAD COMMUNICATIONS, LTD.
+00013B BNA SYSTEMS
+00013C TIW SYSTEMS
+00013D RiscStation Ltd.
+00013E Ascom Tateco AB
+00013F Neighbor World Co., Ltd.
+000140 Sendtek Corporation
+000141 CABLE PRINT
+000142 Cisco Systems, Inc.
+000143 Cisco Systems, Inc.
+000144 Cereva Networks, Inc.
+000145 WINSYSTEMS, INC.
+000146 Tesco Controls, Inc.
+000147 Zhone Technologies
+000148 X-traWeb Inc.
+000149 T.D.T. Transfer Data Test GmbH
+00014A SONY COMPUTER SCIENCE LABS., I
+00014B Ennovate Networks, Inc.
+00014C Berkeley Process Control
+00014D Shin Kin Enterprises Co., Ltd
+00014E WIN Enterprises, Inc.
+00014F LUMINOUS Networks, Inc.
+000150 GILAT COMMUNICATIONS, LTD.
+000151 Ensemble Communications
+000152 CHROMATEK INC.
+000153 ARCHTEK TELECOM CORPORATION
+000154 G3M Corporation
+000155 Promise Technology, Inc.
+000156 FIREWIREDIRECT.COM, INC.
+000157 SYSWAVE CO., LTD
+000158 Electro Industries/Gauge Tech
+000159 S1 Corporation
+00015A Digital Video Broadcasting
+00015B ITALTEL S.p.A/RF-UP-I
+00015C CADANT INC.
+00015D Pirus Networks
+00015E BEST TECHNOLOGY CO., LTD.
+00015F DIGITAL DESIGN GmbH
+000160 ELMEX Co., LTD.
+000161 Meta Machine Technology
+000162 Cygnet Technologies, Inc.
+000163 Cisco Systems, Inc.
+000164 Cisco Systems, Inc.
+000165 AirSwitch Corporation
+000166 TC GROUP A/S
+000167 HIOKI E.E. CORPORATION
+000168 VITANA CORPORATION
+000169 Celestix Networks Pte Ltd.
+00016A ALITEC
+00016B LightChip, Inc.
+00016C FOXCONN
+00016D Triton Network Systems
+00016E Conklin Corporation
+00016F HAITAI ELECTRONICS CO., LTD.
+000170 ESE Embedded System Engineer'g
+000171 Allied Data Technologies
+000172 TechnoLand Co., LTD.
+000173 JNI Corporation
+000174 CyberOptics Corporation
+000175 Radiant Communications Corp.
+000176 Orient Silver Enterprises
+000177 EDSL
+000178 MARGI Systems, Inc.
+000179 WIRELESS TECHNOLOGY, INC.
+00017A Chengdu Maipu Electric Industrial Co., Ltd.
+00017B Heidelberger Druckmaschinen AG
+00017C AG-E GmbH
+00017D ThermoQuest
+00017E ADTEK System Science Co., Ltd.
+00017F Experience Music Project
+000180 AOpen, Inc.
+000181 Nortel Networks
+000182 DICA TECHNOLOGIES AG
+000183 ANITE TELECOMS
+000184 SIEB & MEYER AG
+000185 Aloka Co., Ltd.
+000186 DISCH GmbH
+000187 i2SE GmbH
+000188 LXCO Technologies ag
+000189 Refraction Technology, Inc.
+00018A ROI COMPUTER AG
+00018B NetLinks Co., Ltd.
+00018C Mega Vision
+00018D AudeSi Technologies
+00018E Logitec Corporation
+00018F Kenetec, Inc.
+000190 SMK-M
+000191 SYRED Data Systems
+000192 Texas Digital Systems
+000193 Hanbyul Telecom Co., Ltd.
+000194 Capital Equipment Corporation
+000195 Sena Technologies, Inc.
+000196 Cisco Systems, Inc.
+000197 Cisco Systems, Inc.
+000198 Darim Vision
+000199 HeiSei Electronics
+00019A LEUNIG GmbH
+00019B Kyoto Microcomputer Co., Ltd.
+00019C JDS Uniphase Inc.
+00019D E-Control Systems, Inc.
+00019E ESS Technology, Inc.
+00019F Phonex Broadband
+0001A0 Infinilink Corporation
+0001A1 Mag-Tek, Inc.
+0001A2 Logical Co., Ltd.
+0001A3 GENESYS LOGIC, INC.
+0001A4 Microlink Corporation
+0001A5 Nextcomm, Inc.
+0001A6 Scientific-Atlanta Arcodan A/S
+0001A7 UNEX TECHNOLOGY CORPORATION
+0001A8 Welltech Computer Co., Ltd.
+0001A9 BMW AG
+0001AA Airspan Communications, Ltd.
+0001AB Main Street Networks
+0001AC Sitara Networks, Inc.
+0001AD Coach Master International  d.b.a. CMI Worldwide, Inc.
+0001AE Trex Enterprises
+0001AF Motorola Computer Group
+0001B0 Fulltek Technology Co., Ltd.
+0001B1 General Bandwidth
+0001B2 Digital Processing Systems, Inc.
+0001B3 Precision Electronic Manufacturing
+0001B4 Wayport, Inc.
+0001B5 Turin Networks, Inc.
+0001B6 SAEJIN T&M Co., Ltd.
+0001B7 Centos, Inc.
+0001B8 Netsensity, Inc.
+0001B9 SKF Condition Monitoring
+0001BA IC-Net, Inc.
+0001BB Frequentis
+0001BC Brains Corporation
+0001BD Peterson Electro-Musical Products, Inc.
+0001BE Gigalink Co., Ltd.
+0001BF Teleforce Co., Ltd.
+0001C0 CompuLab, Ltd.
+0001C1 Exbit Technology
+0001C2 ARK Research Corp.
+0001C3 Acromag, Inc.
+0001C4 NeoWave, Inc.
+0001C5 Simpler Networks
+0001C6 Quarry Technologies
+0001C7 Cisco Systems, Inc.
+0001C8 THOMAS CONRAD CORP.
+0001C8 CONRAD CORP.
+0001C9 Cisco Systems, Inc.
+0001CA Geocast Network Systems, Inc.
+0001CB NetGame, Ltd.
+0001CC Japan Total Design Communication Co., Ltd.
+0001CD ARtem
+0001CE Custom Micro Products, Ltd.
+0001CF Alpha Data Parallel Systems, Ltd.
+0001D0 VitalPoint, Inc.
+0001D1 CoNet Communications, Inc.
+0001D2 MacPower Peripherals, Ltd.
+0001D3 PAXCOMM, Inc.
+0001D4 Leisure Time, Inc.
+0001D5 HAEDONG INFO & COMM CO., LTD
+0001D6 MAN Roland Druckmaschinen AG
+0001D7 F5 Networks, Inc.
+0001D8 Teltronics, Inc.
+0001D9 Sigma, Inc.
+0001DA WINCOMM Corporation
+0001DB Freecom Technologies GmbH
+0001DC Activetelco
+0001DD Avail Networks
+0001DE Trango Systems, Inc.
+0001DF ISDN Communications, Ltd.
+0001E0 Fast Systems, Inc.
+0001E1 Kinpo Electronics, Inc.
+0001E2 Ando Electric Corporation
+0001E3 Siemens AG
+0001E4 Sitera, Inc.
+0001E5 Supernet, Inc.
+0001E6 Hewlett-Packard Company
+0001E7 Hewlett-Packard Company
+0001E8 Force10 Networks, Inc.
+0001E9 Litton Marine Systems B.V.
+0001EA Cirilium Corp.
+0001EB C-COM Corporation
+0001EC Ericsson Group
+0001ED SETA Corp.
+0001EE Comtrol Europe, Ltd.
+0001EF Camtel Technology Corp.
+0001F0 Tridium, Inc.
+0001F1 Innovative Concepts, Inc.
+0001F3 QPS, Inc.
+0001F4 Enterasys Networks
+0001F5 ERIM S.A.
+0001F6 Association of Musical Electronics Industry
+0001F7 Image Display Systems, Inc.
+0001F8 Adherent Systems, Ltd.
+0001F9 TeraGlobal Communications Corp.
+0001FA HOROSCAS
+0001FB DoTop Technology, Inc.
+0001FC Keyence Corporation
+0001FD Digital Voice Systems, Inc.
+0001FE DIGITAL EQUIPMENT CORPORATION
+0001FF Data Direct Networks, Inc.
+000200 Net & Sys Co., Ltd.
+000201 IFM Electronic gmbh
+000202 Amino Communications, Ltd.
+000203 Woonsang Telecom, Inc.
+000204 Bodmann Industries Elektronik GmbH
+000205 Hitachi Denshi, Ltd.
+000206 Telital R&D Denmark A/S
+000208 Unify Networks, Inc.
+000209 Shenzhen SED Information Technology Co., Ltd.
+00020A Gefran Spa
+00020B Native Networks, Inc.
+00020C Metro-Optix
+00020D Micronpc.com
+00020E Laurel Networks, Inc.
+00020F AATR
+000210 Fenecom
+000211 Nature Worldwide Technology Corp.
+000212 SierraCom
+000213 S.D.E.L.
+000214 DTVRO
+000215 Cotas Computer Technology A/B
+000216 Cisco Systems, Inc.
+000217 Cisco Systems, Inc.
+000218 Advanced Scientific Corp
+000219 Paralon Technologies
+00021A Zuma Networks
+00021B Kollmorgen-Servotronix
+00021C Network Elements, Inc.
+00021D Data General Communication Ltd.
+00021E SIMTEL S.R.L.
+00021F Aculab PLC
+000220 Canon Aptex, Inc.
+000221 DSP Application, Ltd.
+000222 Chromisys, Inc.
+000223 ClickTV
+000224 Lantern Communications, Inc.
+000225 Certus Technology, Inc.
+000226 XESystems, Inc.
+000227 ESD GmbH
+000228 Necsom, Ltd.
+000229 Adtec Corporation
+00022A Asound Electronic
+00022B Tamura Electric Works, Ltd.
+00022C ABB Bomem, Inc.
+00022D Agere Systems
+00022E TEAC Corp. R& D
+00022F P-Cube, Ltd.
+000230 Intersoft Electronics
+000231 Ingersoll-Rand
+000232 Avision, Inc.
+000233 Mantra Communications, Inc.
+000234 Imperial Technology, Inc.
+000235 Paragon Networks International
+000236 INIT GmbH
+000237 Cosmo Research Corp.
+000238 Serome Technology, Inc.
+000239 Visicom
+00023A ZSK Stickmaschinen GmbH
+00023B Redback Networks
+00023C Creative Technology, Ltd.
+00023D NuSpeed, Inc.
+00023E Selta Telematica S.p.a
+00023F Compal Electronics, Inc.
+000240 Seedek Co., Ltd.
+000241 Amer.com
+000242 Videoframe Systems
+000243 Raysis Co., Ltd.
+000244 SURECOM Technology Co.
+000245 Lampus Co, Ltd.
+000246 All-Win Tech Co., Ltd.
+000247 Great Dragon Information Technology (Group) Co., Ltd.
+000248 Pila GmbH & Co.
+000249 Aviv Infocom Co, Ltd.
+00024A Cisco Systems, Inc.
+00024B Cisco Systems, Inc.
+00024C SiByte, Inc.
+00024D Mannesman Dematic Colby Pty. Ltd.
+00024E Datacard Group
+00024F IPM Datacom S.R.L.
+000250 Geyser Networks, Inc.
+000251 Soma Networks
+000252 Carrier Corporation
+000253 Televideo, Inc.
+000254 WorldGate
+000255 IBM Corporation
+000256 Alpha Processor, Inc.
+000257 Microcom Corp.
+000258 Flying Packets Communications
+000259 Tsann Kuen China (Shanghai)Enterprise Co., Ltd. IT Group
+00025A Catena Networks
+00025B Cambridge Silicon Radio
+00025C SCI Systems (Kunshan) Co., Ltd.
+00025E High Technology Ltd
+00025F Nortel Networks
+000260 Accordion Networks, Inc.
+000261 i3 Micro Technology AB
+000262 Soyo Group Soyo Com Tech Co., Ltd
+000263 UPS Manufacturing SRL
+000264 AudioRamp.com
+000265 Virditech Co. Ltd.
+000266 Thermalogic Corporation
+000267 NODE RUNNER, INC.
+000268 Harris Government Communications
+000269 Nadatel Co., Ltd
+00026A Cocess Telecom Co., Ltd.
+00026B BCM Computers Co., Ltd.
+00026C Philips CFT
+00026D Adept Telecom
+00026E NeGeN Access, Inc.
+00026F Senao International Co., Ltd.
+000270 Crewave Co., Ltd.
+000271 Vpacket Communications
+000272 CC&C Technologies, Inc.
+000273 Coriolis Networks
+000274 Tommy Technologies Corp.
+000275 SMART Technologies, Inc.
+000276 Primax Electronics Ltd.
+000277 Cash Systemes Industrie
+000278 Samsung Electro-Mechanics Co., Ltd.
+000279 Control Applications, Ltd.
+00027A IOI Technology Corporation
+00027B Amplify Net, Inc.
+00027C Trilithic, Inc.
+00027D Cisco Systems, Inc.
+00027E Cisco Systems, Inc.
+00027F ask-technologies.com
+000280 Mu Net, Inc.
+000281 Red-M (Communications) Ltd.
+000282 ViaClix, Inc.
+000283 Spectrum Controls, Inc.
+000284 Alstom T&D P&C
+000285 Riverstone Networks
+000286 Occam Networks
+000287 Adapcom
+000288 GLOBAL VILLAGE COMMUNICATION
+000289 DNE Technologies
+00028A Ambit Microsystems Corporation
+00028B VDSL Systems OY
+00028C Micrel-Synergy Semiconductor
+00028D Movita Technologies, Inc.
+00028E Rapid 5 Networks, Inc.
+00028F Globetek, Inc.
+000290 Woorigisool, Inc.
+000291 Open Network Co., Ltd.
+000292 Logic Innovations, Inc.
+000293 Solid Data Systems
+000294 Tokyo Sokushin Co., Ltd.
+000295 IP.Access Limited
+000296 Lectron Co,. Ltd.
+000297 C-COR.net
+000298 Broadframe Corporation
+000299 Apex, Inc.
+00029A Storage Apps
+00029B Kreatel Communications AB
+00029D Merix Corp.
+00029E Information Equipment Co., Ltd.
+00029F L-3 Communication Aviation Recorders
+0002A0 Flatstack Ltd.
+0002A1 World Wide Packets
+0002A2 Hilscher GmbH
+0002A3 ABB Power Automation
+0002A4 AddPac Technology Co., Ltd.
+0002A5 Compaq Computer Corporation
+0002A6 Effinet Systems Co., Ltd.
+0002A7 Vivace Networks
+0002A8 Air Link Technology
+0002A9 RACOM, s.r.o.
+0002AA PLcom Co., Ltd.
+0002AB CTC Union Technologies Co., Ltd.
+0002AC 3PAR data
+0002AD Asahi Optical Co., Ltd.
+0002AE Scannex Electronics Ltd.
+0002AF TeleCruz Technology, Inc.
+0002B0 Hokubu Communication & Industrial Co., Ltd.
+0002B1 Anritsu, Ltd.
+0002B2 Cablevision
+0002B3 Intel Corporation
+0002B4 DAPHNE
+0002B5 Avnet, Inc.
+0002B6 Acrosser Technology Co., Ltd.
+0002B7 Watanabe Electric Industry Co., Ltd.
+0002B8 WHI KONSULT AB
+0002B9 Cisco Systems, Inc.
+0002BA Cisco Systems, Inc.
+0002BB Continuous Computing
+0002BC LVL 7 Systems, Inc.
+0002BD Bionet Co., Ltd.
+0002BE Totsu Engineering, Inc.
+0002BF dotRocket, Inc.
+0002C0 Bencent Tzeng Industry Co., Ltd.
+0002C1 Innovative Electronic Designs, Inc.
+0002C2 Net Vision Telecom
+0002C3 Arelnet Ltd.
+0002C4 Vector International BUBA
+0002C5 Evertz Microsystems Ltd.
+0002C6 Data Track Technology PLC
+0002C7 ALPS ELECTRIC Co., Ltd.
+0002C8 Technocom Communications Technology (pte) Ltd
+0002C9 Mellanox Technologies
+0002CA EndPoints, Inc.
+0002CB TriState Ltd.
+0002CC M.C.C.I
+0002CD TeleDream, Inc.
+0002CE FoxJet, Inc.
+0002CF ZyGate Communications, Inc.
+0002D0 Comdial Corporation
+0002D1 Vivotek, Inc.
+0002D2 Workstation AG
+0002D3 NetBotz, Inc.
+0002D4 PDA Peripherals, Inc.
+0002D5 ACR
+0002D6 NICE Systems
+0002D7 EMPEG Ltd
+0002D8 BRECIS Communications Corporation
+0002D9 Reliable Controls
+0002DA ExiO Communications, Inc.
+0002DB NETSEC
+0002DC Fujitsu General Limited
+0002DD Bromax Communications, Ltd.
+0002DE Astrodesign, Inc.
+0002DF Net Com Systems, Inc.
+0002E0 ETAS GmbH
+0002E1 Integrated Network Corporation
+0002E2 NDC Infared Engineering
+0002E3 LITE-ON Communications, Inc.
+0002E4 JC HYUN Systems, Inc.
+0002E5 Timeware Ltd.
+0002E6 Gould Instrument Systems, Inc.
+0002E7 CAB GmbH & Co KG
+0002E8 E.D.&A.
+0002E9 CS Systemes De Securite - C3S
+0002EA Videonics, Inc.
+0002EB Easent Communications
+0002EC Maschoff Design Engineering
+0002ED DXO Telecom Co., Ltd.
+0002EE Nokia Danmark A/S
+0002EF CCC Network Systems Group Ltd.
+0002F0 AME Optimedia Technology Co., Ltd.
+0002F1 Pinetron Co., Ltd.
+0002F2 eDevice, Inc.
+0002F3 Media Serve Co., Ltd.
+0002F4 PCTEL, Inc.
+0002F5 VIVE Synergies, Inc.
+0002F6 Equipe Communications
+0002F7 ARM
+0002F8 SEAKR Engineering, Inc.
+0002F9 Mimos Semiconductor SDN BHD
+0002FA DX Antenna Co., Ltd.
+0002FB Baumuller Aulugen-Systemtechnik GmbH
+0002FC Cisco Systems, Inc.
+0002FD Cisco Systems, Inc.
+0002FE Viditec, Inc.
+0002FF Handan Broad InfoCom
+000300 NetContinuum, Inc.
+000301 Avantas Networks Corporation
+000302 Oasys Telecom, Inc.
+000303 JAMA Electronics Co., Ltd.
+000304 Pacific Broadband Communications
+000305 Smart Network Devices GmbH
+000306 Fusion In Tech Co., Ltd.
+000307 Secure Works, Inc.
+000308 AM Communications, Inc.
+000309 Texcel Technology PLC
+00030A Argus Technologies
+00030B Hunter Technology, Inc.
+00030C Telesoft Technologies Ltd.
+00030D Uniwill Computer Corp.
+00030E Core Communications Co., Ltd.
+00030F Legend Digital China Ltd.
+000310 Link Evolution Corp.
+000311 Micro Technology Co., Ltd.
+000312 TR-Systemtechnik GmbH
+000313 Access Media SPA
+000314 Teleware Network Systems
+000315 Cidco Incorporated
+000316 Nobell Communications, Inc.
+000317 Merlin Systems, Inc.
+000318 Cyras Systems, Inc.
+000319 Infineon AG
+00031A Beijing Broad Telecom Ltd., China
+00031B Cellvision Systems, Inc.
+00031C Svenska Hardvarufabriken AB
+00031D Taiwan Commate Computer, Inc.
+00031E Optranet, Inc.
+00031F Condev Ltd.
+000320 Xpeed, Inc.
+000321 Reco Research Co., Ltd.
+000322 IDIS Co., Ltd.
+000323 Cornet Technology, Inc.
+000324 Tottori SANYO Electric Co., Ltd.
+000325 Arima Computer Corp.
+000326 Iwasaki Information Systems Co., Ltd.
+000327 ACT'L
+000328 Mace Group, Inc.
+000329 F3, Inc.
+00032A UniData Communication Systems, Inc.
+00032B GAI Datenfunksysteme GmbH
+00032C ABB Industrie AG
+00032D IBASE Technology, Inc.
+00032E Scope Information Management, Ltd.
+00032F Global Sun Technology, Inc.
+000330 Imagenics, Co., Ltd.
+000331 Cisco Systems, Inc.
+000332 Cisco Systems, Inc.
+000333 Digitel Co., Ltd.
+000334 Newport Electronics
+000335 Mirae Technology
+000336 Zetes Technologies
+000337 Vaone, Inc.
+000338 Oak Technology
+000339 Eurologic Systems, Ltd.
+00033A Silicon Wave, Inc.
+00033B TAMI Tech Co., Ltd.
+00033C Daiden Co., Ltd.
+00033D ILSHin Lab
+00033E Tateyama System Laboratory Co., Ltd.
+00033F BigBand Networks, Ltd.
+000340 Floware Wireless Systems, Ltd.
+000341 Axon Digital Design
+000342 Nortel Networks
+000343 Martin Professional A/S
+000344 Tietech.Co., Ltd.
+000345 Routrek Networks Corporation
+000346 Hitachi Kokusai Electric, Inc.
+000347 Intel Corporation
+000348 Norscan Instruments, Ltd.
+000349 Vidicode Datacommunicatie B.V.
+00034A RIAS Corporation
+00034B Nortel Networks
+00034C Shanghai DigiVision Technology Co., Ltd.
+00034D Chiaro Networks, Ltd.
+00034E Pos Data Company, Ltd.
+00034F Sur-Gard Security
+000350 BTICINO SPA
+000351 Diebold, Inc.
+000352 Colubris Networks
+000353 Mitac, Inc.
+000354 Fiber Logic Communications
+000355 TeraBeam Internet Systems
+000356 Wincor Nixdorf GmbH & Co KG
+000357 Intervoice-Brite, Inc.
+000358 iCable System Co., Ltd.
+000359 DigitalSis
+00035A Phototron Limited
+00035B BridgeWave Communications
+00035C Saint Song Corp.
+00035D Bosung Hi-Net Co., Ltd.
+00035E Metropolitan Area Networks, Inc.
+00035F Schuehle Mess - und. Kontrollsysteme
+000360 PAC Interactive Technology, Inc.
+000361 Widcomm, Inc.
+000362 Vodtel Communications, Inc.
+000363 Miraesys Co., Ltd.
+000364 Scenix Semiconductor, Inc.
+000365 Kira Information & Communications, Ltd.
+000366 ASM Pacific Technology
+000367 Jasmine Networks, Inc.
+000368 Embedone Co., Ltd.
+000369 Nippon Antenna Co., Ltd.
+00036A Mainnet, Ltd.
+00036B Cisco Systems, Inc.
+00036C Cisco Systems, Inc.
+00036D Runtop, Inc.
+00036E Nicon Systems (Pty) Limited
+00036F Telsey SPA
+000370 NXTV, Inc.
+000371 Acomz Networks Corp.
+000372 ULAN
+000373 Aselsan A.S
+000374 Hunter Watertech
+000375 NetMedia, Inc.
+000376 Graphtec Technology, Inc.
+000377 Gigabit Wireless
+000378 HUMAX Co., Ltd.
+000379 Proscend Communications, Inc.
+00037A Taiyo Yuden Co., Ltd.
+00037B IDEC IZUMI Corporation
+00037C Coax Media
+00037D Stellcom
+00037E PORTech Communications, Inc.
+00037F Atheros Communications, Inc.
+000381 Ingenico International
+000382 A-One Co., Ltd.
+000383 Metera Networks, Inc.
+000384 AETA
+000385 Actelis Networks, Inc.
+000386 Ho Net, Inc.
+000387 Blaze Network Products
+000388 Fastfame Technology Co., Ltd.
+000389 Plantronics
+00038A America Online, Inc.
+00038B PLUS-ONE I&T, Inc.
+00038C Total Impact
+00038D PCS Revenue Control Systems, Inc.
+00038E Atoga Systems, Inc.
+00038F Weinschel Corporation
+000390 Digital Video Communications, Inc.
+000392 Hyundai Teletek Co., Ltd.
+000393 Apple Computer, Inc.
+000394 Connect One
+000395 California Amplifier
+000396 EZ Cast Co., Ltd.
+000397 Watchfront Electronics
+000398 WISI
+000399 Dongju Informations & Communications Co., Ltd.
+00039A nSine, Ltd.
+00039B NetChip Technology, Inc.
+00039C OptiMight Communications, Inc.
+00039D Acer Communications & Multimedia, Inc.
+00039E Tera System Co., Ltd.
+00039F Cisco Systems, Inc.
+0003A0 Cisco Systems, Inc.
+0003A1 HIPER Information & Communication, Inc.
+0003A2 Catapult Communications
+0003A3 MAVIX, Ltd.
+0003A4 Data Storage and Information Management
+0003A5 Medea Corporation
+0003A7 Unixtar Technology, Inc.
+0003A8 IDOT Computers, Inc.
+0003A9 AXCENT Media AG
+0003AA Watlow
+0003AB Bridge Information Systems
+0003AC Fronius Schweissmaschinen
+0003AD Emerson Energy Systems AB
+0003AE Allied Advanced Manufacturing Pte, Ltd.
+0003AF Paragea Communications
+0003B0 Xsense Technology Corp.
+0003B1 Abbott Laboratories HPD
+0003B2 Radware
+0003B3 IA Link Systems Co., Ltd.
+0003B4 Macrotek International Corp.
+0003B5 Entra Technology Co.
+0003B6 QSI Corporation
+0003B7 ZACCESS Systems
+0003B8 NetKit Solutions, LLC
+0003B9 Hualong Telecom Co., Ltd.
+0003BA Sun Microsystems
+0003BB Signal Communications Limited
+0003BC COT GmbH
+0003BD OmniCluster Technologies, Inc.
+0003BE Netility
+0003BF Centerpoint Broadband Technologies, Inc.
+0003C0 RFTNC Co., Ltd.
+0003C1 Packet Dynamics Ltd
+0003C2 Solphone K.K.
+0003C3 Micronik Multimedia
+0003C4 Tomra Systems ASA
+0003C5 Mobotix AG
+0003C6 ICUE Systems, Inc.
+0003C7 hopf Elektronik GmbH
+0003C8 CML Emergency Services
+0003C9 TECOM Co., Ltd.
+0003CA MTS Systems Corp.
+0003CB Nippon Systems Development Co., Ltd.
+0003CC Momentum Computer, Inc.
+0003CD Clovertech, Inc.
+0003CE ETEN Technologies, Inc.
+0003CF Muxcom, Inc.
+0003D0 KOANKEISO Co., Ltd.
+0003D1 Takaya Corporation
+0003D2 Crossbeam Systems, Inc.
+0003D3 Internet Energy Systems, Inc.
+0003D4 Alloptic, Inc.
+0003D5 Advanced Communications Co., Ltd.
+0003D6 RADVision, Ltd.
+0003D7 NextNet Wireless, Inc.
+0003D8 iMPath Networks, Inc.
+0003D9 Secheron SA
+0003DA Takamisawa Cybernetics Co., Ltd.
+0003DB Apogee Electronics Corp.
+0003DC Lexar Media, Inc.
+0003DD Comark Corp.
+0003DE OTC Wireless
+0003DF Desana Systems
+0003E0 RadioFrame Networks, Inc.
+0003E1 Winmate Communication, Inc.
+0003E2 Comspace Corporation
+0003E3 Cisco Systems, Inc.
+0003E4 Cisco Systems, Inc.
+0003E5 Hermstedt SG
+0003E6 Entone Technologies, Inc.
+0003E7 Logostek Co. Ltd.
+0003E8 Wavelength Digital Limited
+0003E9 Akara Canada, Inc.
+0003EA Mega System Technologies, Inc.
+0003EB Atrica
+0003EC ICG Research, Inc.
+0003ED Shinkawa Electric Co., Ltd.
+0003EE MKNet Corporation
+0003EF Oneline AG
+0003F0 Redfern Broadband Networks
+0003F1 Cicada Semiconductor, Inc.
+0003F2 Seneca Networks
+0003F3 Dazzle Multimedia, Inc.
+0003F4 NetBurner
+0003F5 Chip2Chip
+0003F6 Allegro Networks, Inc.
+0003F7 Plast-Control GmbH
+0003F8 SanCastle Technologies, Inc.
+0003F9 Pleiades Communications, Inc.
+0003FA TiMetra Networks
+0003FB Toko Seiki Company, Ltd.
+0003FC Intertex Data AB
+0003FD Cisco Systems, Inc.
+0003FE Cisco Systems, Inc.
+0003FF Connectix
+000400 LEXMARK INTERNATIONAL, INC.
+000401 Osaki Electric Co., Ltd.
+000402 Nexsan Technologies, Ltd.
+000403 Nexsi Corporation
+000404 Makino Milling Machine Co., Ltd.
+000405 ACN Technologies
+000406 Fa. Metabox AG
+000407 Topcon Positioning Systems, Inc.
+000408 Sanko Electronics Co., Ltd.
+000409 Cratos Networks
+00040A Sage Systems
+00040B 3com Europe Ltd.
+00040C KANNO Work's Ltd.
+00040D Avaya, Inc.
+00040E AVM GmbH
+00040F Asus Network Technologies, Inc.
+000410 Spinnaker Networks, Inc.
+000411 Inkra Networks, Inc.
+000412 WaveSmith Networks, Inc.
+000413 SNOM Technology AG
+000414 Umezawa Musen Denki Co., Ltd.
+000415 Rasteme Systems Co., Ltd.
+000416 Parks S/A Comunicacoes Digitais
+000417 ELAU AG
+000418 Teltronic S.A.U.
+000419 Fibercycle Networks, Inc.
+00041A ines GmbH
+00041B Digital Interfaces Ltd.
+00041C ipDialog, Inc.
+00041D Corega of America
+00041E Shikoku Instrumentation Co., Ltd.
+00041F Sony Computer Entertainment, Inc.
+000420 Slim Devices, Inc.
+000421 Ocular Networks
+000422 Gordon Kapes, Inc.
+000423 Intel Corporation
+000424 TMC s.r.l.
+000425 Atmel Corporation
+000426 Autosys
+000427 Cisco Systems, Inc.
+000428 Cisco Systems, Inc.
+000429 Pixord Corporation
+00042A Wireless Networks, Inc.
+00042B IT Access Co., Ltd.
+00042C Minet, Inc.
+00042D Sarian Systems, Ltd.
+00042E Netous Technologies, Ltd.
+00042F International Communications Products, Inc.
+000430 Netgem
+000431 Play Industries
+000432 Voyetra Turtle Beach, Inc.
+000433 Cyberboard A/S
+000434 Accelent Systems, Inc.
+000435 Comptek International, Inc.
+000436 ELANsat Technologies, Inc.
+000437 Powin Information Technology, Inc.
+000438 Nortel Networks
+000439 Rosco Entertainment Technology, Inc.
+00043A Intelligent Telecommunications, Inc.
+00043B Lava Computer Mfg., Inc.
+00043C SONOS Co., Ltd.
+00043D INDEL AG
+00043E Telencomm
+00043F Electronic Systems Technology, Inc.
+000440 cyberPIXIE, Inc.
+000441 Half Dome Systems, Inc.
+000442 NACT
+000443 Agilent Technologies, Inc.
+000444 Wireless Home
+000445 LMS Skalar Instruments GmbH
+000446 CYZENTECH Co., Ltd.
+000447 Acrowave Systems Co., Ltd.
+000448 Polaroid Professional Imaging
+000449 Mapletree Networks
+00044A iPolicy Networks, Inc.
+00044B NVIDIA
+00044C JENOPTIK
+00044D Cisco Systems, Inc.
+00044E Cisco Systems, Inc.
+00044F Leukhardt Systemelektronik GmbH
+000450 DMD Computers SRL
+000451 Medrad, Inc.
+000452 RocketLogix, Inc.
+000453 Yotta Yotta, Inc.
+000454 Quadriga UK
+000455 ANTARA.net
+000456 PipingHot Networks
+000457 Universal Access Technology, Inc.
+000458 Fusion X Co., Ltd.
+000459 Veristar Corporation
+00045A The Linksys Group, Inc.
+00045B Techsan Electronics Co., Ltd.
+00045C Mobiwave Pte Ltd
+00045D BEKA Elektronik
+00045E Poly Trax Information Technology AG
+00045F Evalue Technology, Inc.
+000460 Knilink Technology, Inc.
+000461 EPOX Computer Co., Ltd.
+000462 DAKOS Data & Communication Co., Ltd.
+000463 Philips Communication Security & Imaging
+000464 Fantasma Networks, Inc.
+000465 ist isdn support tecknik GmbH
+000466 ARMITEL Co.
+000467 Wuhan Research Institute
+000468 Vivity, Inc.
+000469 Innocom, Inc.
+00046A Navini Networks
+00046B Palm Wireless, Inc.
+00046C Cyber Technology Co., Ltd.
+00046D Cisco Systems, Inc.
+00046E Cisco Systems, Inc.
+00046F Digitel S/A Industria Eletronica
+000470 ipUnplugged AB
+000471 IPrad
+000472 Telelynx, Inc.
+000473 Photonex Corporation
+000474 LEGRAND
+000475 3 Com Corporation
+000476 3 Com Corporation
+000477 e-Appliance Corp.
+000478 G. Star Technology Corporation
+000479 Radius Co., Ltd.
+00047A AXXESSIT ASA
+00047B Schlumberger
+00047C Skidata AG
+00047D Pelco
+00047E NKF Electronics
+00047F Chr. Mayr GmbH & Co. KG
+000480 Foundry Networks, Inc.
+000481 Econolite Control Products, Inc.
+000482 MediaLogic Corp.
+000483 Deltron Technology, Inc.
+000484 Amann GmbH
+000485 PicoLight
+000486 ITTC, University of Kansas
+000487 Cogency Semiconductor, Inc.
+000488 Eurotherm Action Incorporated.
+000489 YAFO Networks, Inc.
+00048A Temia Vertriebs GmbH
+00048B Poscon Corporation
+00048C Nayna Networks, Inc.
+00048D Tone Commander Systems, Inc.
+00048E Ohm Tech Labs, Inc.
+00048F TD Systems Corp.
+000490 Optical Access
+000491 Technovision, Inc.
+000492 Hive Internet, Ltd.
+000493 Tsinghua Unisplendour Co., Ltd.
+000494 Breezecom, Ltd.
+000495 Tejas Networks
+000496 Extreme Networks
+000497 MacroSystem Digital Video AG
+000499 Chino Corporation
+00049A Cisco Systems, Inc.
+00049B Cisco Systems, Inc.
+00049C Surgient Networks, Inc.
+00049D Ipanema Technologies
+00049E Wirelink Co., Ltd.
+00049F Metrowerks
+0004A0 Verity Instruments, Inc.
+0004A1 Pathway Connectivity
+0004A2 L.S.I. Japan Co., Ltd.
+0004A3 Microchip Technology, Inc.
+0004A4 NetEnabled, Inc.
+0004A5 Barco Projection Systems NV
+0004A6 SAF Tehnika Ltd.
+0004A7 FabiaTech Corporation
+0004A8 Broadmax Technologies, Inc.
+0004A9 SandStream Technologies, Inc.
+0004AA Jetstream Communications
+0004AB Comverse Network Systems, Inc.
+0004AC IBM CORP.
+0004AD Malibu Networks
+0004AE Liquid Metronics
+0004AF Digital Fountain, Inc.
+0004B0 ELESIGN Co., Ltd.
+0004B1 Signal Technology, Inc.
+0004B2 ESSEGI SRL
+0004B3 Videotek, Inc.
+0004B4 CIAC
+0004B5 Equitrac Corporation
+0004B6 Tellumat (Pty) Ltd.
+0004B7 AMB i.t. Holding
+0004B8 Kumahira Co., Ltd.
+0004B9 S.I. Soubou, Inc.
+0004BA KDD Media Will Corporation
+0004BB Bardac Corporation
+0004BC Giantec, Inc.
+0004BD Motorola BCS
+0004BE OptXCon, Inc.
+0004BF Versa Logic Corp.
+0004C0 Cisco Systems, Inc.
+0004C1 Cisco Systems, Inc.
+0004C2 Magnipix, Inc.
+0004C3 CASTOR Informatique
+0004C4 Allen & Health
+0004C5 ASE Technologies, USA
+0004C6 Yamaha Motor Co., Ltd.
+0004C7 NetMount
+0004C8 LIBA Maschinefabrik GmbH
+0004C9 Micro Electron Co., Ltd.
+0004CA FreeMs Corp.
+0004CB Tdsoft Communication, Ltd.
+0004CC Peek Traffic BV.
+0004CD Informedia Research Group
+0004CE Patria Ailon
+0004CF Seagate Technology
+0004D0 Softlink s.r.o.
+0004D1 Drew Technologies, Inc.
+0004D2 Adcon Telemetry AG
+0004D3 Toyokeiki Co., Ltd.
+0004D4 Proview Electronics Co., Ltd.
+0004D5 Hitachi Communication Systems, Inc.
+0004D6 Takagi Industrial Co., Ltd.
+0004D7 Omitec Instrumentation Ltd.
+0004D8 IPWireless, Inc.
+0004D9 Titan Electronics, Inc.
+0004DA Relax Technology, Inc.
+0004DB Tellus Group Corp.
+0004DC Nortel Networks
+0004DD Cisco Systems, Inc.
+0004DE Cisco Systems, Inc.
+0004DF Teracom Telematica Ltda.
+0004E0 Procket Networks
+0004E1 Infinior Microsystems
+0004E2 SMC Networks, Inc.
+0004E3 Accton Technology Corp.
+0004E4 Daeryung Ind., Inc.
+0004E5 Glonet Systems, Inc.
+0004E6 Banyan Network Private Limited
+0004E7 Lightpointe Communications, Inc
+0004E8 IER, Inc.
+0004E9 Infiniswitch Corporation
+0004EA Hewlett-Packard Company
+0004EB Paxonet Communications, Inc.
+0004EC Memobox SA
+0004ED Billion Electric Co., Ltd.
+0004EE Lincoln Electric Company
+0004EF Polestar Corp.
+0004F0 International Computers, Ltd
+0004F1 WhereNet
+0004F2 Circa Communications, Ltd.
+0004F3 FS FORTH-SYSTEME GmbH
+0004F4 Infinite Electronics Inc.
+0004F5 SnowShore Networks, Inc.
+0004F6 Amphus
+0004F7 Omega Band, Inc.
+0004F8 QUALICABLE TV Industria E Com., Ltda
+0004F9 Xtera Communications, Inc.
+0004FA MIST Inc.
+0004FB Commtech, Inc.
+0004FC Stratus Computer (DE), Inc.
+0004FD Japan Control Engineering Co., Ltd.
+0004FE Pelago Networks
+0004FF Acronet Co., Ltd.
+000500 Cisco Systems, Inc.
+000501 Cisco Systems, Inc.
+000502 APPLE COMPUTER
+000503 ICONAG
+000504 Naray Information & Communication Enterprise
+000505 Systems Integration Solutions, Inc.
+000506 Reddo Networks AB
+000507 Fine Appliance Corp.
+000508 Inetcam, Inc.
+000509 AVOC Nishimura Ltd.
+00050A ICS Spa
+00050B SICOM Systems, Inc.
+00050C Network Photonics, Inc.
+00050D Midstream Technologies, Inc.
+00050E 3ware, Inc.
+00050F Tanaka S/S Ltd.
+000510 Infinite Shanghai Communication Terminals Ltd.
+000511 Complementaty Technologies Ltd
+000512 MeshNetworks, Inc.
+000513 VTLinx Multimedia Systems, Inc.
+000514 KDT Systems Co., Ltd.
+000515 Nuark Co., Ltd.
+000516 SMART Modular Technologies
+000517 Shellcomm, Inc.
+000518 Jupiters Technology
+000519 Siemens Building Technologies AG,
+00051A 3Com Europe Ltd.
+00051B Magic Control Technology Corporation
+00051C Xnet Technology Corp.
+00051D Airocon, Inc.
+00051E Rhapsody Networks
+00051F Taijin Media Co., Ltd.
+000520 Smartronix, Inc.
+000521 Control Microsystems
+000522 LEA*D Corporation, Inc.
+000523 AVL List GmbH
+000524 BTL System (HK) Limited
+000525 Puretek Industrial Co., Ltd.
+000526 IPAS GmbH
+000527 SJ Tek Co. Ltd
+000528 New Focus, Inc.
+000529 Shanghai Broadan Communication Technology Co., Ltd
+00052A Ikegami Tsushinki Co., Ltd.
+00052B HORIBA, Ltd.
+00052C Supreme Magic Corporation
+00052D Zoltrix International Limited
+00052E Cinta Networks
+00052F Leviton Voice and Data
+000530 Andiamo Systems, Inc.
+000531 Cisco Systems, Inc.
+000532 Cisco Systems, Inc.
+000533 Sanera Systems, Inc.
+000534 Northstar Engineering Ltd.
+000535 Chip PC Ltd.
+000536 Danam Communications, Inc.
+000537 Nets Technology Co., Ltd.
+000538 Merilus, Inc.
+000539 A Brand New World in Sweden AB
+00053A Willowglen Services Pte Ltd
+00053B Harbour Networks Ltd., Co. Beijing
+00053C Xircom
+00053D Agere Systems
+00053E KID Systeme GmbH
+00053F VisionTek, Inc.
+000540 FAST Corporation
+000541 Advanced Systems Co., Ltd.
+000542 Otari, Inc.
+000543 IQ Wireless GmbH
+000544 Valley Technologies, Inc.
+000545 Internet Photonics
+000546 KDD Network Systems Co., Ltd.
+000547 Starent Networks
+000548 Disco Corporation
+000549 Salira Optical Network Systems
+00054A Ario Data Networks, Inc.
+00054B Micro Innovation AG
+00054C RF Innovations Pty Ltd
+00054D Brans Technologies, Inc.
+00054E Philips Components
+000550 Digi-Tech Communications Limited
+000551 F & S Elektronik Systeme GmbH
+000552 Xycotec Computer GmbH
+000553 DVC Company, Inc.
+000554 Rangestar Wireless
+000555 Japan Cash Machine Co., Ltd.
+000556 360 Systems
+000557 Agile TV Corporation
+000558 Synchronous, Inc.
+000559 Intracom S.A.
+00055A Power Dsine Ltd.
+00055B Charles Industries, Ltd.
+00055C Kowa Company, Ltd.
+00055D D-Link Systems, Inc.
+00055E Cisco Systems, Inc.
+00055F Cisco Systems, Inc.
+000560 LEADER COMM.CO., LTD
+000561 nac Image Technology, Inc.
+000562 Digital View Limited
+000563 J-Works, Inc.
+000564 Tsinghua Bitway Co., Ltd.
+000565 Tailyn Communication Company Ltd.
+000566 Secui.com Corporation
+000567 Etymonic Design, Inc.
+000568 Piltofish Networks AB
+000569 VMWARE, Inc.
+00056B C.P. Technology Co., Ltd.
+00056C Hung Chang Co., Ltd.
+00056D Pacific Corporation
+00056E National Enhance Technology, Inc.
+00056F Innomedia Technologies Pvt. Ltd.
+000570 Baydel Ltd.
+000571 Seiwa Electronics Co.
+000572 Deonet Co., Ltd.
+000573 Cisco Systems, Inc.
+000574 Cisco Systems, Inc.
+000575 CDS-Electronics BV
+000576 NSM Technology Ltd.
+000577 SM Information & Communication
+000579 Universal Control Solution Corp.
+00057A Hatteras Networks
+00057B Chung Nam Electronic Co., Ltd.
+00057C RCO Security AB
+00057D Sun Communications, Inc.
+00057E Eckelmann Steuerungstechnik GmbH
+00057F Acqis Technology
+000580 Fibrolan Ltd.
+000581 Snell & Wilcox Ltd.
+000582 ClearCube Technology
+000583 ImageCom Limited
+000584 AbsoluteValue Systems, Inc.
+000585 Juniper Networks, Inc.
+000586 Lucent Technologies
+000587 Locus, Incorporated
+000588 Sensoria Corp.
+000589 National Datacomputer
+00058A Netcom Co., Ltd.
+00058B IPmental, Inc.
+00058C Opentech Inc.
+00058D Lynx Photonic Networks, Inc.
+00058E Ahead Communications System GmbH
+00058F CLCsoft co.
+000590 Ascom Business Systems
+000591 Active Silicon Ltd.
+000592 Pultex Corp.
+000593 Grammar Engine Inc.
+000594 IXXAT Automation GmbH
+000595 Alesis Corporation
+000596 Genotech Co., Ltd.
+000597 Eagle Traffic Control Systems
+000598 CRONOS S.r.l.
+000599 PEI Electronics, Inc.
+00059A Cisco Systems, Inc.
+00059B Cisco Systems, Inc.
+00059C Kleinknecht GmbH, Ing. Buero
+00059D Daniel Computing Systems, Inc.
+00059E Zinwell Corporation
+00059F Yotta Networks, Inc.
+0005A0 MOBILINE Kft.
+0005A1 Zenocom
+0005A2 CELOX Networks
+0005A3 QEI, Inc.
+0005A4 Lucid Voice Ltd.
+0005A5 KOTT
+0005A6 Extron Electronics
+0005A7 Hyperchip, Inc.
+0005A8 WYLE ELECTRONICS
+0005A9 Princeton Networks, Inc.
+0005AA Moore Industries Int.
+0005AB Cyber Fone, Inc.
+0005AC Northern Digital, Inc.
+0005AD Topspin Communications, Inc.
+0005AE Mediaport USA
+0005AF InnoScan Computing A/S
+0005B0 Korea Computer Technology Co., Ltd.
+0005B1 ASB Technology BV
+0005B2 Medison Co., Ltd.
+0005B3 Asahi-Engineering Co., Ltd.
+0005B4 Aceex Corporation
+0005B5 Broadcom Technologies
+0005B6 INSYS Microelectronics GmbH
+0005B7 Arbor Technology Corp.
+0005B8 Electronic Design Associates, Inc.
+0005B9 Airvana, Inc.
+0005BA Area Netwoeks, Inc.
+0005BC Resorsys Ltd.
+0005BD ROAX BV
+0005BE Kongsberg Seatex AS
+0005BF JustEzy Technology, Inc.
+0005C0 Digital Network Alacarte Co., Ltd.
+0005C1 A-Kyung Motion, Inc.
+0005C2 Digital Archway, Inc.
+0005C3 Pacific Instruments, Inc.
+0005C4 Telect, Inc.
+0005C5 Flaga HF
+0005C6 Triz Communications
+0005C7 I/F-COM A/S
+0005C8 VERYTECH
+0005C9 LG Innotek
+0005CA Hitron Technology, Inc.
+0005CB ROIS Technologies, Inc.
+0005CC Sumtel Communications, Inc.
+0005CD Nippon Columbia
+0005CE Prolink Microsystems Corporation
+0005CF Thunder River Technologies, Inc.
+0005D0 Solinet Systems
+0005D1 Metavector Technologies
+0005D2 DAP Technologies
+0005D3 CAC, Inc.
+0005D4 FutureSmart Networks, Inc.
+0005D5 Speedcom Wireless
+0005D6 Titan Wireless
+0005D7 Vista Imaging, Inc.
+0005D8 Arescom, Inc.
+0005D9 Techno Valley, Inc.
+0005DA Apex Automationstechnik
+0005DB Nentec GmbH
+0005DC Cisco Systems, Inc.
+0005DD Cisco Systems, Inc.
+0005DE Gi Fone Korea, Inc.
+0005DF Electronic Innovation, Inc.
+0005E0 Empirix Corp.
+0005E1 Trellis Photonics, Ltd.
+0005E2 Creativ Network Technologies
+0005E3 LightSand Communications, Inc.
+0005E4 Red Lion Controls L.P.
+0005E5 Renishaw PLC
+0005E6 Egenera, Inc.
+0005E7 Netrake
+0005E8 TurboWave, Inc.
+0005E9 Unicess Networks, Inc.
+0005EA Viewcast Corporation
+0005EB Blue Ridge Networks, Inc.
+0005EC Mosaic Systems Inc.
+0005ED Technikum Joanneaum GmbH
+0005EE BEWATOR Group
+0005EF ADOIR Digital Technology
+0005F0 SATEC
+0005F1 VRcom, Inc.
+0005F2 Power R, Inc.
+0005F3 Weboyn
+0005F4 SystemBase Co., Ltd.
+0005F5 OYO Geospace Corp.
+0005F6 Young Chang Co. Ltd.
+0005F7 Analog Devices, Inc.
+0005F8 Real Time Access, Inc.
+0005F9 Diva Systems
+0005FA IPOptical, Inc.
+0005FB Sharegate
+0005FC Schenck Pegasus Corp.
+0005FD PacketLight Networks Ltd.
+0005FE Traficon N.V.
+0005FF SNS Solutions, Inc.
+000600 Tokyo Electronic Industry Co., Ltd.
+000601 Otanikeiki Co., Ltd.
+000602 Cirkitech Electronics Co.
+000603 Baker Hughes
+000604 @Track Communications, Inc.
+000605 Inncom International, Inc.
+000606 RapidWan, Inc.
+000607 Omni-Directional Control Technology Inc.
+000608 At-Sky SAS
+000609 Crossport Systems
+00060A Blue2space.com
+00060B Paceline Systems Corporation
+00060C Melco Industries, Inc.
+00060D Wave7 Optics
+00060E IGSYS Systems, Inc.
+00060F Narad Networks Inc
+000610 Abeona Networks Inc
+000611 Zeus Wireless, Inc.
+000612 Accusys, Inc.
+000613 Kawasaki Steel Corporation
+000614 Prism Holdings
+000615 Kimoto Electric Co., Ltd.
+000616 Tel Net Co., Ltd.
+000617 Redswitch Inc.
+000618 DigiPower Manufacturing Inc.
+000619 Connection Technology Systems
+00061A Zetari Inc.
+00061B Portable Systems, IBM Japan Co, Ltd
+00061C Hoshino Metal Industries, Ltd.
+00061D MIP Telecom, Inc.
+00061E Maxan Systems
+00061F Vision Components GmbH
+000620 Serial System Ltd.
+000621 Hinox, Co., Ltd.
+000622 Chung Fu Chen Yeh Enterprise Corp.
+000623 MGE UPS Systems France
+000624 Gentner Communications
+000625 The Linksys Group, Inc.
+000626 MWE GmbH
+000627 Uniwide Technologies, Inc.
+000628 Cisco Systems, Inc.
+000629 IBM CORPORATION
+00062A Cisco Systems, Inc.
+00062B INTRASERVER TECHNOLOGY
+00062C Network Robots, Inc.
+00062D TouchStar Technologies, L.L.C.
+00062E Aristos Logic Corp.
+00062F Pivotech Systems Inc.
+000630 Adtranz Sweden
+000631 Optical Solutions, Inc.
+000632 Mesco Engineering GmbH
+000633 Heimann Biometric Systems GmbH
+000634 GTE Airfone Inc.
+000635 PacketAir Networks, Inc.
+000636 Jedai Broadband Networks
+000637 Toptrend-Meta Information (ShenZhen) Inc.
+000638 Sungjin C&C Co., Ltd.
+000639 Newtec
+00063A Dura Micro, Inc.
+00063B Lineo Canada Corp.
+00063C NMI Electronics Ltd
+00063D Microwave Data Systems Inc.
+00063E Opthos Inc.
+00063F Everex Communications Inc.
+000640 White Rock Networks
+000641 ITCN
+000642 Genetel Systems Inc.
+000643 SONO Computer Co., Ltd.
+000644 NEIX Inc.
+000645 Meisei Electric Co. Ltd.
+000646 ShenZhen XunBao Network Technology Co Ltd
+000647 Etrali S.A.
+000648 Seedsware, Inc.
+000649 Quante
+00064A Honeywell Co., Ltd. (KOREA)
+00064B Alexon Co., Ltd.
+00064C Invicta Networks, Inc.
+00064D Sencore
+00064E Broad Net Technology Inc.
+00064F PRO-NETS Technology Corporation
+000650 Tiburon Networks, Inc.
+000651 Aspen Networks Inc.
+000652 Cisco Systems, Inc.
+000653 Cisco Systems, Inc.
+000654 Maxxio Technologies
+000655 Yipee, Inc.
+000656 Tactel AB
+000657 Market Central, Inc.
+000658 Helmut Fischer GmbH & Co. KG
+000659 EAL (Apeldoorn) B.V.
+00065A Strix Systems
+00065B Dell Computer Corp.
+00065C Malachite Technologies, Inc.
+00065D Heidelberg Web Systems
+00065E Photuris, Inc.
+00065F ECI Telecom - NGTS Ltd.
+000660 NADEX Co., Ltd.
+000661 NIA Home Technologies Corp.
+000662 MBM Technology Ltd.
+000663 Human Technology Co., Ltd.
+000664 Fostex Corporation
+000665 Summy Gikem, Inc.
+000666 Roving Networks
+000667 Tripp Lite
+000668 Vicon Industries Inc.
+000669 Datasound Laboratories Ltd
+00066A InfiniCon Systems, Inc.
+00066B Sysmex Corporation
+00066C Robinson Corporation
+00066D Compuprint S.P.A.
+00066E Delta Electronics, Inc.
+00066F Korea Data Systems
+000670 Upponetti Oy
+000671 Softing AG
+000672 Netezza
+000673 Optelecom, Inc.
+000674 Spectrum Control, Inc.
+000675 Banderacom, Inc.
+000676 Novra Technologies, Inc.
+000677 SICK AG
+000678 Marantz Japan, Inc.
+000679 Konami Corporation
+00067A JMP Systems
+00067B Toplink C&C Corporation
+00067C CISCO SYSTEMS, INC.
+00067D Takasago Ltd.
+0006C1 CISCO SYSTEMS, INC.
+000701 RACAL-DATACOM
+000800 MULTITECH SYSTEMS, INC.
+0008C7 COMPAQ COMPUTER CORPORATION
+000A27 Apple Computer, Inc.
+001000 CABLE TELEVISION
+001001 MCK COMMUNICATIONS
+001002 ACTIA
+001003 IMATRON, INC.
+001004 THE BRANTLEY COILE COMPANY,INC
+001005 UEC COMMERCIAL
+001006 RACAL RECORDERS LTD.
+001007 CISCO SYSTEMS, INC.
+001008 VIENNA SYSTEMS CORPORATION
+001009 HORO QUARTZ
+00100A WILLIAMS COMMUNICATIONS GROUP
+00100B CISCO SYSTEMS, INC.
+00100C ITO CO., LTD.
+00100D CISCO SYSTEMS, INC.
+00100E MICRO LINEAR COPORATION
+00100F INDUSTRIAL CPU SYSTEMS
+001010 INITIO CORPORATION
+001011 CISCO SYSTEMS, INC.
+001012 PROCESSOR SYSTEMS (I) PVT LTD
+001013 INDUSTRIAL COMPUTER SOURCE
+001014 CISCO SYSTEMS, INC.
+001015 OOMON INC.
+001016 T.SQWARE
+001017 MICOS GMBH
+001018 BROADCOM CORPORATION
+001019 SIRONA DENTAL SYSTEMS
+00101A PICTURETEL CORP.
+00101B CORNET TECHNOLOGY, INC.
+00101C OHM TECHNOLOGIES INTL, LLC
+00101D WINBOND ELECTRONICS CORP.
+00101E MATSUSHITA ELECTRONIC
+00101F CISCO SYSTEMS, INC.
+001020 WELCH ALLYN, DATA COLLECTION
+001021 ENCANTO NETWORKS, INC.
+001022 SATCOM MEDIA CORPORATION
+001023 FLOWWISE NETWORKS, INC.
+001024 NAGOYA ELECTRIC WORKS CO., LTD
+001025 GRAYHILL INC.
+001026 ACCELERATED NETWORKS, INC.
+001027 L-3 COMMUNICATIONS EAST
+001028 COMPUTER TECHNICA, INC.
+001029 CISCO SYSTEMS, INC.
+00102A ZF MICROSYSTEMS, INC.
+00102B UMAX DATA SYSTEMS, INC.
+00102C Lasat Networks A/S
+00102D HITACHI SOFTWARE ENGINEERING
+00102E NETWORK SYSTEMS & TECHNOLOGIES
+00102F CISCO SYSTEMS, INC.
+001030 WI-LAN, INC.
+001031 OBJECTIVE COMMUNICATIONS, INC.
+001032 ALTA TECHNOLOGY
+001033 ACCESSLAN COMMUNICATIONS, INC.
+001034 GNP COMPUTERS
+001035 ELITEGROUP COMPUTER
+001036 INTER-TEL INTEGRATED SYSTEMS
+001037 CYQ'VE TECHNOLOGY CO., LTD.
+001038 MICRO RESEARCH INSTITUTE, INC.
+001039 VECTRON SYSTEMS GMBH
+00103A DIAMOND NETWORK TECH
+00103B HIPPI NETWORKING FORUM
+00103C IC ENSEMBLE, INC.
+00103D PHASECOM, LTD.
+00103E NETSCHOOLS CORPORATION
+00103F TOLLGRADE COMMUNICATIONS, INC.
+001040 INTERMEC CORPORATION
+001041 BRISTOL BABCOCK, INC.
+001042 ALACRITECH
+001043 A2 CORPORATION
+001044 INNOLABS CORPORATION
+001045 Nortel Networks
+001046 ALCORN MCBRIDE INC.
+001047 ECHO ELETRIC CO. LTD.
+001048 HTRC AUTOMATION, INC.
+001049 SHORELINE TELEWORKS, INC.
+00104A THE PARVUC CORPORATION
+00104B 3COM CORPORATION
+00104C COMPUTER ACCESS TECHNOLOGY
+00104D SURTEC INDUSTRIES, INC.
+00104E CEOLOGIC
+00104F STORAGE TECHNOLOGY CORPORATION
+001050 RION CO., LTD.
+001051 CMICRO CORPORATION
+001052 METTLER-TOLEDO (ALBSTADT) GMBH
+001053 COMPUTER TECHNOLOGY CORP.
+001054 CISCO SYSTEMS, INC.
+001055 FUJITSU MICROELECTRONICS, INC.
+001056 SODICK CO., LTD.
+001057 Rebel.com, Inc.
+001058 ARROWPOINT COMMUNICATIONS,INC.
+001059 DIABLO RESEARCH CO. LLC
+00105A 3COM CORPORATION
+00105B NET INSIGHT AB
+00105C QUANTUM DESIGNS (H.K.) LTD.
+00105D DRAGER, BUSINESS UNIT
+00105E HEKIMIAN LABORATORIES, INC.
+00105F IN-SNEC
+001060 BILLIONTON SYSTEMS, INC.
+001061 HOSTLINK CORP.
+001062 NX SERVER, ILNC.
+001063 STARGUIDE DIGITAL NETWORKS
+001064 DIGITAL EQUIPMENT CORP.
+001065 RADYNE CORPORATION
+001066 ADVANCED CONTROL SYSTEMS, INC.
+001067 REDBACK NETWORKS, INC.
+001068 COMOS TELECOM
+001069 HELIOSS COMMUNICATIONS, INC.
+00106A DIGITAL MICROWAVE CORPORATION
+00106B SONUS NETWORKS, INC.
+00106C INFRATEC PLUS GMBH
+00106D INTEGRITY COMMUNICATIONS, INC.
+00106E TADIRAN COM. LTD.
+00106F TRENTON TECHNOLOGY INC.
+001070 CARADON TREND LTD.
+001071 ADVANET INC.
+001072 GVN TECHNOLOGIES, INC.
+001073 TECHNOBOX, INC.
+001074 ATEN INTERNATIONAL CO., LTD.
+001075 Maxtor Corporation
+001076 EUREM GMBH
+001077 SAF DRIVE SYSTEMS, LTD.
+001078 NUERA COMMUNICATIONS, INC.
+001079 CISCO SYSTEMS, INC.
+00107A AMBICOM, INC.
+00107B CISCO SYSTEMS, INC.
+00107C P-COM, INC.
+00107D AURORA COMMUNICATIONS, LTD.
+00107E BACHMANN ELECTRONIC GMBH
+00107F CRESTRON ELECTRONICS, INC.
+001080 METAWAVE COMMUNICATIONS
+001081 DPS, INC.
+001082 JNA TELECOMMUNICATIONS LIMITED
+001083 HEWLETT-PACKARD COMPANY
+001084 K-BOT COMMUNICATIONS
+001085 POLARIS COMMUNICATIONS, INC.
+001086 ATTO TECHNOLOGY, INC.
+001087 Xstreamis PLC
+001088 AMERICAN NETWORKS INC.
+001089 WEBSONIC
+00108A TERALOGIC, INC.
+00108B LASERANIMATION SOLLINGER GMBH
+00108C FUJITSU TELECOMMUNICATIONS
+00108D JOHNSON CONTROLS, INC.
+00108E HUGH SYMONS CONCEPT
+00108F RAPTOR SYSTEMS
+001090 CIMETRICS, INC.
+001091 NO WIRES NEEDED BV
+001092 NETCORE INC.
+001093 CMS COMPUTERS, LTD.
+001094 ADTECH, INC.
+001095 THOMSON CONSUMER ELECTRONICS
+001096 TRACEWELL SYSTEMS, INC.
+001097 WINNET METROPOLITAN
+001098 STARNET TECHNOLOGIES, INC.
+001099 INNOMEDIA, INC.
+00109A NETLINE
+00109B VIXEL CORPORATION
+00109C M-SYSTEM CO., LTD.
+00109D CLARINET SYSTEMS, INC.
+00109E AWARE, INC.
+00109F PAVO, INC.
+0010A0 INNOVEX TECHNOLOGIES, INC.
+0010A1 KENDIN SEMICONDUCTOR, INC.
+0010A2 TNS
+0010A3 OMNITRONIX, INC.
+0010A4 XIRCOM
+0010A5 OXFORD INSTRUMENTS
+0010A6 CISCO SYSTEMS, INC.
+0010A7 UNEX TECHNOLOGY CORPORATION
+0010A8 RELIANCE COMPUTER CORP.
+0010A9 ADHOC TECHNOLOGIES
+0010AA MEDIA4, INC.
+0010AB KOITO INDUSTRIES, LTD.
+0010AC IMCI TECHNOLOGIES
+0010AD SOFTRONICS USB, INC.
+0010AE SHINKO ELECTRIC INDUSTRIES CO.
+0010AF TAC SYSTEMS, INC.
+0010B0 MERIDIAN TECHNOLOGY CORP.
+0010B1 FOR-A CO., LTD.
+0010B2 COACTIVE AESTHETICS
+0010B3 NOKIA MULTIMEDIA TERMINALS
+0010B4 ATMOSPHERE NETWORKS
+0010B5 ACCTON TECHNOLOGY CORPORATION
+0010B6 ENTRATA COMMUNICATIONS CORP.
+0010B7 COYOTE TECHNOLOGIES, LLC
+0010B8 ISHIGAKI COMPUTER SYSTEM CO.
+0010B9 MAXTOR CORP.
+0010BA MARTINHO-DAVIS SYSTEMS, INC.
+0010BB DATA & INFORMATION TECHNOLOGY
+0010BC Nortel Networks
+0010BD THE TELECOMMUNICATION
+0010BE TELEXIS CORP.
+0010BF INTER AIR WIRELESS
+0010C0 ARMA, INC.
+0010C1 OI ELECTRIC CO., LTD.
+0010C2 WILLNET, INC.
+0010C3 CSI-CONTROL SYSTEMS
+0010C4 MEDIA LINKS CO., LTD.
+0010C5 PROTOCOL TECHNOLOGIES, INC.
+0010C6 USI
+0010C7 DATA TRANSMISSION NETWORK
+0010C8 COMMUNICATIONS ELECTRONICS
+0010C9 MITSUBISHI ELECTRONICS
+0010CA INTEGRAL ACCESS
+0010CB FACIT K.K.
+0010CC CLP COMPUTER LOGISTIK
+0010CD INTERFACE CONCEPT
+0010CE VOLAMP, LTD.
+0010CF FIBERLANE COMMUNICATIONS
+0010D0 WITCOM, LTD.
+0010D1 Top Layer Networks, Inc.
+0010D2 NITTO TSUSHINKI CO., LTD
+0010D3 GRIPS ELECTRONIC GMBH
+0010D4 STORAGE COMPUTER CORPORATION
+0010D5 IMASDE CANARIAS, S.A.
+0010D6 ITT A/CD
+0010D7 ARGOSY RESEARCH INC.
+0010D8 CALISTA
+0010D9 IBM JAPAN, FUJISAWA MT+D
+0010DA MOTION ENGINEERING, INC.
+0010DB NETSCREEN TECHNOLOGIES, INC.
+0010DC MICRO-STAR INTERNATIONAL
+0010DD ENABLE SEMICONDUCTOR, INC.
+0010DE INTERNATIONAL DATACASTING
+0010DF RISE COMPUTER INC.
+0010E0 COBALT MICROSERVER, INC.
+0010E1 S.I. TECH, INC.
+0010E2 ARRAYCOMM, INC.
+0010E3 COMPAQ COMPUTER CORPORATION
+0010E4 NSI CORPORATION
+0010E5 SOLECTRON TEXAS
+0010E6 APPLIED INTELLIGENT
+0010E7 BREEZECOM
+0010E8 TELOCITY, INCORPORATED
+0010E9 RAIDTEC LTD.
+0010EA ADEPT TECHNOLOGY
+0010EB SELSIUS SYSTEMS, ILNC.
+0010EC RPCG, LLC
+0010ED SUNDANCE TECHNOLOGY, INC.
+0010EE CTI PRODUCTS, INC.
+0010EF DB NETWORKS, INC.
+0010F0 RITTAL-WERK RUDOLF LOH
+0010F1 I-O CORPORATION
+0010F2 ANTEC
+0010F3 NEXCOM INTERNATIONAL CO., LTD.
+0010F4 VERTICAL NETWORKS, INC.
+0010F5 AMHERST SYSTEMS, INC.
+0010F6 CISCO SYSTEMS, INC.
+0010F7 IRIICHI TECHNOLOGIES
+0010F8 KENWOOD TMI CORPORATION
+0010F9 UNIQUE SYSTEMS, INC.
+0010FA ZAYANTE, INC.
+0010FB ZIDA TECHNOLOGIES LIMITED
+0010FC BROADBAND NETWORKS, INC.
+0010FD COCOM A/S
+0010FE DIGITAL EQUIPMENT CORPORATION
+0010FF CISCO SYSTEMS, INC.
+001C7C PERQ SYSTEMS CORPORATION
+002000 LEXMARK INTERNATIONAL, INC.
+002001 DSP SOLUTIONS, INC.
+002002 SERITECH ENTERPRISE CO., LTD.
+002003 PIXEL POWER LTD.
+002004 YAMATAKE-HONEYWELL CO., LTD.
+002005 SIMPLE TECHNOLOGY
+002006 GARRETT COMMUNICATIONS, INC.
+002007 SFA, INC.
+002008 CABLE & COMPUTER TECHNOLOGY
+002009 PACKARD BELL ELEC., INC.
+00200A SOURCE-COMM CORP.
+00200B OCTAGON SYSTEMS CORP.
+00200C ADASTRA SYSTEMS CORP.
+00200D CARL ZEISS
+00200E SATELLITE TECHNOLOGY MGMT, INC
+00200F TANBAC CO., LTD.
+002010 JEOL SYSTEM TECHNOLOGY CO. LTD
+002011 CANOPUS CO., LTD.
+002012 CAMTRONICS MEDICAL SYSTEMS
+002013 DIVERSIFIED TECHNOLOGY, INC.
+002014 GLOBAL VIEW CO., LTD.
+002015 ACTIS COMPUTER SA
+002016 SHOWA ELECTRIC WIRE & CABLE CO
+002017 ORBOTECH
+002018 CIS TECHNOLOGY INC.
+002019 OHLER GMBH
+00201A N-BASE SWITCH COMMUNICATIONS
+00201B NORTHERN TELECOM/NETWORK
+00201C EXCEL, INC.
+00201D KATANA PRODUCTS
+00201E NETQUEST CORPORATION
+00201F BEST POWER TECHNOLOGY, INC.
+002020 MEGATRON COMPUTER INDUSTRIES
+002021 ALGORITHMS SOFTWARE PVT. LTD.
+002022 TEKNIQUE, INC.
+002023 T.C. TECHNOLOGIES PTY. LTD
+002024 PACIFIC COMMUNICATION SCIENCES
+002025 CONTROL TECHNOLOGY, INC.
+002026 AMKLY SYSTEMS, INC.
+002027 MING FORTUNE INDUSTRY CO., LTD
+002028 WEST EGG SYSTEMS, INC.
+002029 TELEPROCESSING PRODUCTS, INC.
+00202A N.V. DZINE
+00202B ADVANCED TELECOMMUNICATIONS
+00202C WELLTRONIX CO., LTD.
+00202D TAIYO CORPORATION
+00202E DAYSTAR DIGITAL
+00202F ZETA COMMUNICATIONS, LTD.
+002030 ANALOG & DIGITAL SYSTEMS
+002031 ERTEC GMBH
+002032 ALCATEL TAISEL
+002033 SYNAPSE TECHNOLOGIES, INC.
+002034 ROTEC INDUSTRIEAUTOMATION GMBH
+002035 IBM CORPORATION
+002036 BMC SOFTWARE
+002037 SEAGATE TECHNOLOGY
+002038 VME MICROSYSTEMS INTERNATIONAL
+002039 SCINETS
+00203A DIGITAL BI0METRICS INC.
+00203B WISDM LTD.
+00203C EUROTIME AB
+00203D NOVAR ELECTRONICS CORPORATION
+00203E LOGICAN TECHNOLOGIES, INC.
+00203F JUKI CORPORATION
+002040 Motorola Broadband Communications Sector
+002041 DATA NET
+002042 DATAMETRICS CORP.
+002043 NEURON COMPANY LIMITED
+002044 GENITECH PTY LTD
+002045 ION Networks, Inc.
+002046 CIPRICO, INC.
+002047 STEINBRECHER CORP.
+002048 Marconi Communications
+002049 COMTRON, INC.
+00204A PRONET GMBH
+00204B AUTOCOMPUTER CO., LTD.
+00204C MITRON COMPUTER PTE LTD.
+00204D INOVIS GMBH
+00204E NETWORK SECURITY SYSTEMS, INC.
+00204F DEUTSCHE AEROSPACE AG
+002050 KOREA COMPUTER INC.
+002051 PHOENIX DATA COMMUNUNICATIONS
+002052 RAGULA SYSTEMS
+002053 HUNTSVILLE MICROSYSTEMS, INC.
+002054 EASTERN RESEARCH, INC.
+002055 ALTECH CO., LTD.
+002056 NEOPRODUCTS
+002057 TITZE DATENTECHNIK GMBH
+002058 ALLIED SIGNAL INC.
+002059 MIRO COMPUTER PRODUCTS AG
+00205A COMPUTER IDENTICS
+00205B SKYLINE TECHNOLOGY
+00205C INTERNET SYSTEMS/ FLORIDA INC.
+00205D NANOMATIC OY
+00205E CASTLE ROCK, INC.
+00205F GAMMADATA COMPUTER GMBH
+002060 ALCATEL ITALIA S.P.A.
+002061 DYNATECH COMMUNICATIONS, INC.
+002062 SCORPION LOGIC, LTD.
+002063 WIPRO INFOTECH LTD.
+002064 PROTEC MICROSYSTEMS, INC.
+002065 SUPERNET NETWORKING INC.
+002066 GENERAL MAGIC, INC.
+002068 ISDYNE
+002069 ISDN SYSTEMS CORPORATION
+00206A OSAKA COMPUTER CORP.
+00206B MINOLTA CO., LTD.
+00206C EVERGREEN TECHNOLOGY CORP.
+00206D DATA RACE, INC.
+00206E XACT, INC.
+00206F FLOWPOINT CORPORATION
+002070 HYNET, LTD.
+002071 IBR GMBH
+002072 WORKLINK INNOVATIONS
+002073 FUSION SYSTEMS CORPORATION
+002074 SUNGWOON SYSTEMS
+002075 MOTOROLA COMMUNICATION ISRAEL
+002076 REUDO CORPORATION
+002077 KARDIOS SYSTEMS CORP.
+002078 RUNTOP, INC.
+002079 MIKRON GMBH
+00207A WISE COMMUNICATIONS, INC.
+00207B LEVEL ONE COMMUNICATIONS
+00207C AUTEC GMBH
+00207D ADVANCED COMPUTER APPLICATIONS
+00207E FINECOM CO., LTD.
+00207F KYOEI SANGYO CO., LTD.
+002080 SYNERGY (UK) LTD.
+002081 TITAN ELECTRONICS
+002082 ONEAC CORPORATION
+002083 PRESTICOM INCORPORATED
+002084 OCE PRINTING SYSTEMS, GMBH
+002085 EXIDE ELECTRONICS
+002086 MICROTECH ELECTRONICS LIMITED
+002087 MEMOTEC COMMUNICATIONS CORP.
+002088 GLOBAL VILLAGE COMMUNICATION
+002089 T3PLUS NETWORKING, INC.
+00208A SONIX COMMUNICATIONS, LTD.
+00208B LAPIS TECHNOLOGIES, INC.
+00208C GALAXY NETWORKS, INC.
+00208D CMD TECHNOLOGY
+00208E CHEVIN SOFTWARE ENG. LTD.
+00208F ECI TELECOM LTD.
+002090 ADVANCED COMPRESSION
+002091 J125, NATIONAL SECURITY AGENCY
+002092 CHESS ENGINEERING B.V.
+002093 LANDINGS TECHNOLOGY CORP.
+002094 CUBIX CORPORATION
+002095 RIVA ELECTRONICS
+002096 SIEBE ENVIRONMENTAL CONTROLS
+002097 APPLIED SIGNAL TECHNOLOGY
+002098 HECTRONIC AB
+002099 BON ELECTRIC CO., LTD.
+00209A THE 3DO COMPANY
+00209B ERSAT ELECTRONIC GMBH
+00209C PRIMARY ACCESS CORP.
+00209D LIPPERT AUTOMATIONSTECHNIK
+00209E BROWN'S OPERATING SYSTEM
+00209F MERCURY COMPUTER SYSTEMS, INC.
+0020A0 OA LABORATORY CO., LTD.
+0020A1 DOVATRON
+0020A2 GALCOM NETWORKING LTD.
+0020A3 DIVICOM INC.
+0020A4 MULTIPOINT NETWORKS
+0020A5 API ENGINEERING
+0020A6 PROXIM, INC.
+0020A7 PAIRGAIN TECHNOLOGIES, INC.
+0020A8 SAST TECHNOLOGY CORP.
+0020A9 WHITE HORSE INDUSTRIAL
+0020AA DIGIMEDIA VISION LTD.
+0020AB MICRO INDUSTRIES CORP.
+0020AC INTERFLEX DATENSYSTEME GMBH
+0020AD LINQ SYSTEMS
+0020AE ORNET DATA COMMUNICATION TECH.
+0020AF 3COM CORPORATION
+0020B0 GATEWAY DEVICES, INC.
+0020B1 COMTECH RESEARCH INC.
+0020B2 GKD GESELLSCHAFT FUR
+0020B3 SCLTEC COMMUNICATIONS SYSTEMS
+0020B4 TERMA ELEKTRONIK AS
+0020B5 YASKAWA ELECTRIC CORPORATION
+0020B6 AGILE NETWORKS, INC.
+0020B7 NAMAQUA COMPUTERWARE
+0020B8 PRIME OPTION, INC.
+0020B9 METRICOM, INC.
+0020BA CENTER FOR HIGH PERFORMANCE
+0020BB ZAX CORPORATION
+0020BC JTEC PTY LTD.
+0020BD NIOBRARA R & D CORPORATION
+0020BE LAN ACCESS CORP.
+0020BF AEHR TEST SYSTEMS
+0020C0 PULSE ELECTRONICS, INC.
+0020C1 TAIKO ELECTRIC WORKS, LTD.
+0020C2 TEXAS MEMORY SYSTEMS, INC.
+0020C3 COUNTER SOLUTIONS LTD.
+0020C4 INET,INC.
+0020C5 EAGLE TECHNOLOGY
+0020C6 NECTEC
+0020C7 AKAI Professional M.I. Corp.
+0020C8 LARSCOM INCORPORATED
+0020C9 VICTRON BV
+0020CA DIGITAL OCEAN
+0020CB PRETEC ELECTRONICS CORP.
+0020CC DIGITAL SERVICES, LTD.
+0020CD HYBRID NETWORKS, INC.
+0020CE LOGICAL DESIGN GROUP, INC.
+0020CF TEST & MEASUREMENT SYSTEMS INC
+0020D0 VERSALYNX CORPORATION
+0020D1 MICROCOMPUTER SYSTEMS (M) SDN.
+0020D2 RAD DATA COMMUNICATIONS, LTD.
+0020D3 OST (OUEST STANDARD TELEMATIQU
+0020D4 CABLETRON - ZEITTNET INC.
+0020D5 VIPA GMBH
+0020D6 BREEZECOM
+0020D7 JAPAN MINICOMPUTER SYSTEMS CO.
+0020D8 NETWAVE TECHNOLOGIES, INC.
+0020D9 PANASONIC TECHNOLOGIES, INC./
+0020DA XYLAN CORPORATION
+0020DB XNET TECHNOLOGY, INC.
+0020DC DENSITRON TAIWAN LTD.
+0020DD AWA LTD.
+0020DE JAPAN DIGITAL LABORAT'Y CO.LTD
+0020DF KYOSAN ELECTRIC MFG. CO., LTD.
+0020E0 PREMAX ELECTRONICS, INC.
+0020E1 ALAMAR ELECTRONICS
+0020E2 INFORMATION RESOURCE
+0020E3 MCD KENCOM CORPORATION
+0020E4 HSING TECH ENTERPRISE CO., LTD
+0020E5 APEX DATA, INC.
+0020E6 LIDKOPING MACHINE TOOLS AB
+0020E7 B&W NUCLEAR SERVICE COMPANY
+0020E8 DATATREK CORPORATION
+0020E9 DANTEL
+0020EA EFFICIENT NETWORKS, INC.
+0020EB CINCINNATI MICROWAVE, INC.
+0020EC TECHWARE SYSTEMS CORP.
+0020ED GIGA-BYTE TECHNOLOGY CO., LTD.
+0020EE GTECH CORPORATION
+0020EF USC CORPORATION
+0020F0 UNIVERSAL MICROELECTRONICS CO.
+0020F1 ALTOS INDIA LIMITED
+0020F2 SUN MICROSYSTEMS, INC.
+0020F3 RAYNET CORPORATION
+0020F4 SPECTRIX CORPORATION
+0020F5 PANDATEL AG
+0020F6 NET TEK  AND KARLNET, INC.
+0020F7 CYBERDATA
+0020F8 CARRERA COMPUTERS, INC.
+0020F9 PARALINK NETWORKS, INC.
+0020FA GDE SYSTEMS, INC.
+0020FB OCTEL COMMUNICATIONS CORP.
+0020FC MATROX
+0020FD ITV TECHNOLOGIES, INC.
+0020FE TOPWARE INC. / GRAND COMPUTER
+0020FF SYMMETRICAL TECHNOLOGIES
+003000 ALLWELL TECHNOLOGY CORP.
+003001 SMP
+003002 Expand Networks
+003003 Phasys Ltd.
+003004 LEADTEK RESEARCH INC.
+003005 Fujitsu Siemens Computers
+003006 SUPERPOWER COMPUTER
+003007 OPTI, INC.
+003008 AVIO DIGITAL, INC.
+003009 Tachion Networks, Inc.
+00300A AZTECH SYSTEMS LTD.
+00300B mPHASE Technologies, Inc.
+00300C CONGRUENCY, LTD.
+00300D MMC Technology, Inc.
+00300E Klotz Digital AG
+00300F IMT - Information Management T
+003010 VISIONETICS INTERNATIONAL
+003011 HMS FIELDBUS SYSTEMS AB
+003012 DIGITAL ENGINEERING LTD.
+003013 NEC Corporation
+003014 DIVIO, INC.
+003015 CP CLARE CORP.
+003016 ISHIDA CO., LTD.
+003017 TERASTACK LTD.
+003018 Jetway Information Co., Ltd.
+003019 CISCO SYSTEMS, INC.
+00301A SMARTBRIDGES PTE. LTD.
+00301B SHUTTLE, INC.
+00301C ALTVATER AIRDATA SYSTEMS
+00301D SKYSTREAM, INC.
+00301E 3COM Europe Ltd.
+00301F OPTICAL NETWORKS, INC.
+003020 TSI, Inc..
+003021 HSING TECH. ENTERPRISE CO.,LTD
+003022 Fong Kai Industrial Co., Ltd.
+003023 COGENT COMPUTER SYSTEMS, INC.
+003024 CISCO SYSTEMS, INC.
+003025 CHECKOUT COMPUTER SYSTEMS, LTD
+003026 HEITEL
+003027 KERBANGO, INC.
+003028 FASE Saldatura srl
+003029 OPICOM
+00302A SOUTHERN INFORMATION
+00302B INALP NETWORKS, INC.
+00302C SYLANTRO SYSTEMS CORPORATION
+00302D QUANTUM BRIDGE COMMUNICATIONS
+00302E Hoft & Wessel AG
+00302F Smiths Industries
+003030 HARMONIX CORPORATION
+003031 LIGHTWAVE COMMUNICATIONS, INC.
+003032 MAGICRAM, INC.
+003033 ORIENT TELECOM CO., LTD.
+003036 RMP ELEKTRONIKSYSTEME GMBH
+003037 Packard Bell Nec Services
+003038 XCP, INC.
+003039 SOFTBOOK PRESS
+00303A MAATEL
+00303B PowerCom Technology
+00303C ONNTO CORP.
+00303D IVA CORPORATION
+00303E Radcom Ltd.
+00303F TurboComm Tech Inc.
+003040 CISCO SYSTEMS, INC.
+003041 SAEJIN T & M CO., LTD.
+003042 DeTeWe-Deutsche Telephonwerke
+003043 IDREAM TECHNOLOGIES, PTE. LTD.
+003044 Portsmith LLC
+003045 Village Networks, Inc. (VNI)
+003046 Controlled Electronic Manageme
+003047 NISSEI ELECTRIC CO., LTD.
+003048 Supermicro Computer, Inc.
+003049 BRYANT TECHNOLOGY, LTD.
+00304A FRAUNHOFER INSTITUTE IMS
+00304B ORBACOM SYSTEMS, INC.
+00304C APPIAN COMMUNICATIONS, INC.
+00304D ESI
+00304E BUSTEC PRODUCTION LTD.
+00304F PLANET Technology Corporation
+003050 Versa Technology
+003051 ORBIT AVIONIC & COMMUNICATION
+003052 ELASTIC NETWORKS
+003053 Basler AG
+003054 CASTLENET TECHNOLOGY, INC.
+003055 Hitachi Semiconductor America,
+003056 Beck IPC GmbH
+003057 E-Tel Corporation
+003058 API MOTION
+003059 DIGITAL-LOGIC AG
+00305A TELGEN CORPORATION
+00305B MODULE DEPARTMENT
+00305C SMAR Laboratories Corp.
+00305D DIGITRA SYSTEMS, INC.
+00305E Abelko Innovation
+00305F IMACON APS
+003060 STARMATIX, INC.
+003061 MobyTEL
+003062 PATH 1 NETWORK TECHNOL'S INC.
+003063 SANTERA SYSTEMS, INC.
+003064 ADLINK TECHNOLOGY, INC.
+003065 APPLE COMPUTER, INC.
+003066 DIGITAL WIRELESS CORPORATION
+003067 BIOSTAR MICROTECH INT'L CORP.
+003068 CYBERNETICS TECH. CO., LTD.
+003069 IMPACCT TECHNOLOGY CORP.
+00306A PENTA MEDIA CO., LTD.
+00306B CMOS SYSTEMS, INC.
+00306C Hitex Holding GmbH
+00306D LUCENT TECHNOLOGIES
+00306E HEWLETT PACKARD
+00306F SEYEON TECH. CO., LTD.
+003070 1Net Corporation
+003071 Cisco Systems, Inc.
+003072 INTELLIBYTE INC.
+003073 International Microsystems, In
+003074 EQUIINET LTD.
+003075 ADTECH
+003076 Akamba Corporation
+003077 ONPREM NETWORKS
+003078 Cisco Systems, Inc.
+003079 CQOS, INC.
+00307A Advanced Technology & Systems
+00307B Cisco Systems, Inc.
+00307C ADID SA
+00307D GRE AMERICA, INC.
+00307E Redflex Communication Systems
+00307F IRLAN LTD.
+003080 CISCO SYSTEMS, INC.
+003081 ALTOS C&C
+003082 TAIHAN ELECTRIC WIRE CO., LTD.
+003083 Ivron Systems
+003084 ALLIED TELESYN INTERNAIONAL
+003085 CISCO SYSTEMS, INC.
+003086 Transistor Devices, Inc.
+003087 VEGA GRIESHABER KG
+003088 Siara Systems, Inc.
+003089 Spectrapoint Wireless, LLC
+00308A NICOTRA SISTEMI S.P.A
+00308B Brix Networks
+00308C ADVANCED DIGITAL INFORMATION
+00308D PINNACLE SYSTEMS, INC.
+00308E CROSS MATCH TECHNOLOGIES, INC.
+00308F MICRILOR, Inc.
+003090 CYRA TECHNOLOGIES, INC.
+003091 TAIWAN FIRST LINE ELEC. CORP.
+003092 ModuNORM GmbH
+003093 SONNET TECHNOLOGIES, INC.
+003094 Cisco Systems, Inc.
+003095 Procomp Informatics, Ltd.
+003096 CISCO SYSTEMS, INC.
+003097 EXOMATIC AB
+003098 Global Converging Technologies
+003099 BOENIG UND KALLENBACH OHG
+00309A ASTRO TERRA CORP.
+00309B Smartware
+00309C Timing Applications, Inc.
+00309D Nimble Microsystems, Inc.
+00309E WORKBIT CORPORATION.
+00309F AMBER NETWORKS
+0030A0 TYCO SUBMARINE SYSTEMS, LTD.
+0030A1 OPTI TECH CO., LTD.
+0030A2 Lightner Engineering
+0030A3 CISCO SYSTEMS, INC.
+0030A4 Woodwind Communications System
+0030A5 ACTIVE POWER
+0030A6 VIANET TECHNOLOGIES, LTD.
+0030A7 SCHWEITZER ENGINEERING
+0030A8 OL'E COMMUNICATIONS, INC.
+0030A9 Netiverse, Inc.
+0030AA AXUS MICROSYSTEMS, INC.
+0030AB DELTA NETWORKS, INC.
+0030AC Systeme Lauer GmbH & Co., Ltd.
+0030AD SHANGHAI COMMUNICATION
+0030AE Times N System, Inc.
+0030AF Honeywell Reqelsysteme GmbH
+0030B0 Convergenet Technologies
+0030B1 GOC GESELLSCHAFT FUR OPTISCHE
+0030B2 WESCAM - HEALDSBURG
+0030B3 San Valley Systems, Inc.
+0030B4 INTERSIL CORP.
+0030B5 Tadiran Microwave Networks
+0030B6 CISCO SYSTEMS, INC.
+0030B7 Teletrol Systems, Inc.
+0030B8 RiverDelta Networks
+0030B9 ECTEL
+0030BA AC&T SYSTEM CO., LTD.
+0030BB CacheFlow, Inc.
+0030BC Optronic AG
+0030BD BELKIN COMPONENTS
+0030BE City-Net Technology, Inc.
+0030BF MULTIDATA GMBH
+0030C0 Lara Technology, Inc.
+0030C1 HEWLETT-PACKARD
+0030C2 COMONE
+0030C3 FLUECKIGER ELEKTRONIK AG
+0030C4 Niigata Canotec Co., Inc.
+0030C5 CADENCE DESIGN SYSTEMS
+0030C6 CONTROL SOLUTIONS, INC.
+0030C7 MACROMATE CORP.
+0030C8 GAD LINE, LTD.
+0030C9 LuxN, N
+0030CA Discovery Com
+0030CB OMNI FLOW COMPUTERS, INC.
+0030CC Tenor Networks, Inc.
+0030CD CONEXANT SYSTEMS, INC.
+0030CE Zaffire
+0030CF TWO TECHNOLOGIES, INC.
+0030D1 INOVA CORPORATION
+0030D2 WIN TECHNOLOGIES, CO., LTD.
+0030D3 Agilent Technologies
+0030D4 COMTIER
+0030D5 DResearch GmbH
+0030D6 MSC VERTRIEBS GMBH
+0030D7 Innovative Systems, L.L.C.
+0030D8 SITEK
+0030D9 DATACORE SOFTWARE CORP.
+0030DA COMTREND CO.
+0030DB Mindready Solutions, Inc.
+0030DC RIGHTECH CORPORATION
+0030DD INDIGITA CORPORATION
+0030DE WAGO Kontakttechnik GmbH
+0030DF KB/TEL TELECOMUNICACIONES
+0030E0 OXFORD SEMICONDUCTOR LTD.
+0030E1 ACROTRON SYSTEMS, INC.
+0030E2 GARNET SYSTEMS CO., LTD.
+0030E3 SEDONA NETWORKS CORP.
+0030E4 CHIYODA SYSTEM RIKEN
+0030E5 Amper Datos S.A.
+0030E6 SIEMENS MEDICAL SYSTEMS
+0030E7 CNF MOBILE SOLUTIONS, INC.
+0030E8 ENSIM CORP.
+0030E9 GMA COMMUNICATION MANUFACT'G
+0030EA TeraForce Technology Corporation
+0030EB TURBONET COMMUNICATIONS, INC.
+0030EC BORGARDT
+0030ED Expert Magnetics Corp.
+0030EE DSG Technology, Inc.
+0030EF NEON TECHNOLOGY, INC.
+0030F0 Uniform Industrial Corp.
+0030F1 Accton Technology Corp.
+0030F2 CISCO SYSTEMS, INC.
+0030F3 At Work Computers
+0030F4 STARDOT TECHNOLOGIES
+0030F5 Wild Lab. Ltd.
+0030F6 SECURELOGIX CORPORATION
+0030F7 RAMIX INC.
+0030F8 Dynapro Systems, Inc.
+0030F9 Sollae Systems Co., Ltd.
+0030FA TELICA, INC.
+0030FB AZS Technology AG
+0030FC Terawave Communications, Inc.
+0030FD INTEGRATED SYSTEMS DESIGN
+0030FE DSA GmbH
+0030FF DATAFAB SYSTEMS, INC.
+004000 PCI COMPONENTES DA AMZONIA LTD
+004001 ZYXEL COMMUNICATIONS, INC.
+004002 PERLE SYSTEMS LIMITED
+004003 WESTINGHOUSE PROCESS CONTROL
+004004 ICM CO. LTD.
+004005 ANI COMMUNICATIONS INC.
+004006 SAMPO TECHNOLOGY CORPORATION
+004007 TELMAT INFORMATIQUE
+004008 A PLUS INFO CORPORATION
+004009 TACHIBANA TECTRON CO., LTD.
+00400A PIVOTAL TECHNOLOGIES, INC.
+00400B CISCO SYSTEMS, INC.
+00400C GENERAL MICRO SYSTEMS, INC.
+00400D LANNET DATA COMMUNICATIONS,LTD
+00400E MEMOTEC COMMUNICATIONS, INC.
+00400F DATACOM TECHNOLOGIES
+004010 SONIC SYSTEMS, INC.
+004011 ANDOVER CONTROLS CORPORATION
+004012 WINDATA, INC.
+004013 NTT DATA COMM. SYSTEMS CORP.
+004014 COMSOFT GMBH
+004015 ASCOM INFRASYS AG
+004016 HADAX ELECTRONICS, INC.
+004017 XCD INC.
+004018 ADOBE SYSTEMS, INC.
+004019 AEON SYSTEMS, INC.
+00401A FUJI ELECTRIC CO., LTD.
+00401B PRINTER SYSTEMS CORP.
+00401C AST RESEARCH, INC.
+00401D INVISIBLE SOFTWARE, INC.
+00401E ICC
+00401F COLORGRAPH LTD
+004020 PINACL COMMUNICATION
+004021 RASTER GRAPHICS
+004022 KLEVER COMPUTERS, INC.
+004023 LOGIC CORPORATION
+004024 COMPAC INC.
+004025 MOLECULAR DYNAMICS
+004026 MELCO, INC.
+004027 SMC MASSACHUSETTS, INC.
+004028 NETCOMM LIMITED
+004029 COMPEX
+00402A CANOGA-PERKINS
+00402B TRIGEM COMPUTER, INC.
+00402C ISIS DISTRIBUTED SYSTEMS, INC.
+00402D HARRIS ADACOM CORPORATION
+00402E PRECISION SOFTWARE, INC.
+00402F XLNT DESIGNS INC.
+004030 GK COMPUTER
+004031 KOKUSAI ELECTRIC CO., LTD
+004032 DIGITAL COMMUNICATIONS
+004033 ADDTRON TECHNOLOGY CO., LTD.
+004034 BUSTEK CORPORATION
+004035 OPCOM
+004036 TRIBE COMPUTER WORKS, INC.
+004037 SEA-ILAN, INC.
+004038 TALENT ELECTRIC INCORPORATED
+004039 OPTEC DAIICHI DENKO CO., LTD.
+00403A IMPACT TECHNOLOGIES
+00403B SYNERJET INTERNATIONAL CORP.
+00403C FORKS, INC.
+00403D TERADATA
+00403E RASTER OPS CORPORATION
+00403F SSANGYONG COMPUTER SYSTEMS
+004040 RING ACCESS, INC.
+004041 FUJIKURA LTD.
+004042 N.A.T. GMBH
+004043 NOKIA TELECOMMUNICATIONS
+004044 QNIX COMPUTER CO., LTD.
+004045 TWINHEAD CORPORATION
+004046 UDC RESEARCH LIMITED
+004047 WIND RIVER SYSTEMS
+004048 SMD INFORMATICA S.A.
+004049 TEGIMENTA AG
+00404A WEST AUSTRALIAN DEPARTMENT
+00404B MAPLE COMPUTER SYSTEMS
+00404C HYPERTEC PTY LTD.
+00404D TELECOMMUNICATIONS TECHNIQUES
+00404E FLUENT, INC.
+00404F SPACE & NAVAL WARFARE SYSTEMS
+004050 IRONICS, INCORPORATED
+004051 GRACILIS, INC.
+004052 STAR TECHNOLOGIES, INC.
+004053 AMPRO COMPUTERS
+004054 CONNECTION MACHINES SERVICES
+004055 METRONIX GMBH
+004056 MCM JAPAN LTD.
+004057 LOCKHEED - SANDERS
+004058 KRONOS, INC.
+004059 YOSHIDA KOGYO K. K.
+00405A GOLDSTAR INFORMATION & COMM.
+00405B FUNASSET LIMITED
+00405C FUTURE SYSTEMS, INC.
+00405D STAR-TEK, INC.
+00405E NORTH HILLS ISRAEL
+00405F AFE COMPUTERS LTD.
+004060 COMENDEC LTD
+004061 DATATECH ENTERPRISES CO., LTD.
+004062 E-SYSTEMS, INC./GARLAND DIV.
+004063 VIA TECHNOLOGIES, INC.
+004064 KLA INSTRUMENTS CORPORATION
+004065 GTE SPACENET
+004066 HITACHI CABLE, LTD.
+004067 OMNIBYTE CORPORATION
+004068 EXTENDED SYSTEMS
+004069 LEMCOM SYSTEMS, INC.
+00406A KENTEK INFORMATION SYSTEMS,INC
+00406B SYSGEN
+00406C COPERNIQUE
+00406D LANCO, INC.
+00406E COROLLARY, INC.
+00406F SYNC RESEARCH INC.
+004070 INTERWARE CO., LTD.
+004071 ATM COMPUTER GMBH
+004072 APPLIED INNOVATION, INC.
+004073 BASS ASSOCIATES
+004074 CABLE AND WIRELESS
+004075 M-TRADE (UK) LTD
+004076 Sun Conversion Technologies
+004077 MAXTON TECHNOLOGY CORPORATION
+004078 WEARNES AUTOMATION PTE LTD
+004079 JUKO MANUFACTURE COMPANY, LTD.
+00407A SOCIETE D'EXPLOITATION DU CNIT
+00407B SCIENTIFIC ATLANTA
+00407C QUME CORPORATION
+00407D EXTENSION TECHNOLOGY CORP.
+00407E EVERGREEN SYSTEMS, INC.
+00407F AGEMA INFRARED SYSTEMS AB
+004080 ATHENIX CORPORATION
+004081 MANNESMANN SCANGRAPHIC GMBH
+004082 LABORATORY EQUIPMENT CORP.
+004083 TDA INDUSTRIA DE PRODUTOS
+004084 HONEYWELL INC.
+004085 SAAB INSTRUMENTS AB
+004086 MICHELS & KLEBERHOFF COMPUTER
+004087 UBITREX CORPORATION
+004088 MOBIUS TECHNOLOGIES, INC.
+004089 MEIDENSHA CORPORATION
+00408A TPS TELEPROCESSING SYS. GMBH
+00408B RAYLAN CORPORATION
+00408C AXIS COMMUNICATIONS AB
+00408D THE GOODYEAR TIRE & RUBBER CO.
+00408E DIGILOG, INC.
+00408F WM-DATA MINFO AB
+004090 ANSEL COMMUNICATIONS
+004091 PROCOMP INDUSTRIA ELETRONICA
+004092 ASP COMPUTER PRODUCTS, INC.
+004093 PAXDATA NETWORKS LTD.
+004094 SHOGRAPHICS, INC.
+004095 R.P.T. INTERGROUPS INT'L LTD.
+004096 Aironet Wireless Communication
+004097 DATEX DIVISION OF
+004098 DRESSLER GMBH & CO.
+004099 NEWGEN SYSTEMS CORP.
+00409A NETWORK EXPRESS, INC.
+00409B HAL COMPUTER SYSTEMS INC.
+00409C TRANSWARE
+00409D DIGIBOARD, INC.
+00409E CONCURRENT TECHNOLOGIES  LTD.
+00409F LANCAST/CASAT TECHNOLOGY, INC.
+0040A0 GOLDSTAR CO., LTD.
+0040A1 ERGO COMPUTING
+0040A2 KINGSTAR TECHNOLOGY INC.
+0040A3 MICROUNITY SYSTEMS ENGINEERING
+0040A4 ROSE ELECTRONICS
+0040A5 CLINICOMP INTL.
+0040A6 Cray, Inc.
+0040A7 ITAUTEC PHILCO S.A.
+0040A8 IMF INTERNATIONAL LTD.
+0040A9 DATACOM INC.
+0040AA VALMET AUTOMATION INC.
+0040AB ROLAND DG CORPORATION
+0040AC SUPER WORKSTATION, INC.
+0040AD SMA REGELSYSTEME GMBH
+0040AE DELTA CONTROLS, INC.
+0040AF DIGITAL PRODUCTS, INC.
+0040B0 BYTEX CORPORATION, ENGINEERING
+0040B1 CODONICS INC.
+0040B2 SYSTEMFORSCHUNG
+0040B3 PAR MICROSYSTEMS CORPORATION
+0040B4 NEXTCOM K.K.
+0040B5 VIDEO TECHNOLOGY COMPUTERS LTD
+0040B6 COMPUTERM  CORPORATION
+0040B7 STEALTH COMPUTER SYSTEMS
+0040B8 IDEA ASSOCIATES
+0040B9 MACQ ELECTRONIQUE SA
+0040BA ALLIANT COMPUTER SYSTEMS CORP.
+0040BB GOLDSTAR CABLE CO., LTD.
+0040BC ALGORITHMICS LTD.
+0040BD STARLIGHT NETWORKS, INC.
+0040BE BOEING DEFENSE & SPACE
+0040BF CHANNEL SYSTEMS INTERN'L INC.
+0040C0 VISTA CONTROLS CORPORATION
+0040C1 BIZERBA-WERKE WILHEIM KRAUT
+0040C2 APPLIED COMPUTING DEVICES
+0040C3 FISCHER AND PORTER CO.
+0040C4 KINKEI SYSTEM CORPORATION
+0040C5 MICOM COMMUNICATIONS INC.
+0040C6 FIBERNET RESEARCH, INC.
+0040C7 RUBY TECH CORPORATION
+0040C8 MILAN TECHNOLOGY CORPORATION
+0040C9 NCUBE
+0040CA FIRST INTERNAT'L COMPUTER, INC
+0040CB LANWAN TECHNOLOGIES
+0040CC SILCOM MANUF'G TECHNOLOGY INC.
+0040CD TERA MICROSYSTEMS, INC.
+0040CE NET-SOURCE, INC.
+0040CF STRAWBERRY TREE, INC.
+0040D0 MITAC INTERNATIONAL CORP.
+0040D1 FUKUDA DENSHI CO., LTD.
+0040D2 PAGINE CORPORATION
+0040D3 KIMPSION INTERNATIONAL CORP.
+0040D4 GAGE TALKER CORP.
+0040D5 SARTORIUS AG
+0040D6 LOCAMATION B.V.
+0040D7 STUDIO GEN INC.
+0040D8 OCEAN OFFICE AUTOMATION LTD.
+0040D9 AMERICAN MEGATRENDS INC.
+0040DA TELSPEC LTD
+0040DB ADVANCED TECHNICAL SOLUTIONS
+0040DC TRITEC ELECTRONIC GMBH
+0040DD HONG TECHNOLOGIES
+0040DE ELETTRONICA SAN GIORGIO
+0040DF DIGALOG SYSTEMS, INC.
+0040E0 ATOMWIDE LTD.
+0040E1 MARNER INTERNATIONAL, INC.
+0040E2 MESA RIDGE TECHNOLOGIES, INC.
+0040E3 QUIN SYSTEMS LTD
+0040E4 E-M TECHNOLOGY, INC.
+0040E5 SYBUS CORPORATION
+0040E6 C.A.E.N.
+0040E7 ARNOS INSTRUMENTS & COMPUTER
+0040E8 CHARLES RIVER DATA SYSTEMS,INC
+0040E9 ACCORD SYSTEMS, INC.
+0040EA PLAIN TREE SYSTEMS INC
+0040EB MARTIN MARIETTA CORPORATION
+0040EC MIKASA SYSTEM ENGINEERING
+0040ED NETWORK CONTROLS INT'NATL INC.
+0040EE OPTIMEM
+0040EF HYPERCOM, INC.
+0040F0 MICRO SYSTEMS, INC.
+0040F1 CHUO ELECTRONICS CO., LTD.
+0040F2 JANICH & KLASS COMPUTERTECHNIK
+0040F3 NETCOR
+0040F4 CAMEO COMMUNICATIONS, INC.
+0040F5 OEM ENGINES
+0040F6 KATRON COMPUTERS INC.
+0040F7 POLAROID MEDICAL IMAGING SYS.
+0040F8 SYSTEMHAUS DISCOM
+0040F9 COMBINET
+0040FA MICROBOARDS, INC.
+0040FB CASCADE COMMUNICATIONS CORP.
+0040FC IBR COMPUTER TECHNIK GMBH
+0040FD LXE
+0040FE SYMPLEX COMMUNICATIONS
+0040FF TELEBIT CORPORATION
+005000 NEXO COMMUNICATIONS, INC.
+005001 YAMASHITA SYSTEMS CORP.
+005002 OMNISEC AG
+005003 GRETAG MACBETH AG
+005004 3COM CORPORATION
+005006 TAC AB
+005007 SIEMENS TELECOMMUNICATION
+005008 TIVA MICROCOMPUTER CORP. (TMC)
+005009 PHILIPS BROADBAND NETWORKS
+00500A IRIS TECHNOLOGIES, INC.
+00500B CISCO SYSTEMS, INC.
+00500C ETEK LABS, INC.
+00500D SATORI ELECTORIC CO., LTD.
+00500E CHROMATIS NETWORKS,INC.
+00500F CISCO SYSTEMS, INC.
+005010 NOVANET LEARNING, INC.
+005012 CBL - GMBH
+005013 Chaparral Technologies, Inc.
+005014 CISCO SYSTEMS, INC.
+005015 BRIGHT STAR ENGINEERING
+005016 SST/WOODHEAD INDUSTRIES
+005017 RSR S.R.L.
+005018 ADVANCED MULTIMEDIA INTERNET
+005019 SPRING TIDE NETWORKS, INC.
+00501A UISIQN
+00501B ABL CANADA, INC.
+00501C JATOM SYSTEMS, INC.
+00501E MIRANDA TECHNOLOGIES, INC.
+00501F MRG SYSTEMS, LTD.
+005020 MEDIASTAR CO., LTD.
+005021 EIS INTERNATIONAL, INC.
+005022 ZONET TECHNOLOGY, INC.
+005023 PG DESIGN ELECTRONICS, INC.
+005024 NAVIC SYSTEMS, INC.
+005026 COSYSTEMS, INC.
+005027 GENICOM CORPORATION
+005028 AVAL COMMUNICATIONS
+005029 1394 PRINTER WORKING GROUP
+00502A CISCO SYSTEMS, INC.
+00502B GENRAD LTD.
+00502C SOYO COMPUTER, INC.
+00502D ACCEL, INC.
+00502E CAMBEX CORPORATION
+00502F TOLLBRIDGE TECHNOLOGIES, INC.
+005030 FUTURE PLUS SYSTEMS
+005031 AEROFLEX LABORATORIES, INC.
+005032 PICAZO COMMUNICATIONS, INC.
+005033 MAYAN NETWORKS
+005036 NETCAM, LTD.
+005037 KOGA ELECTRONICS CO.
+005038 DAIN TELECOM CO., LTD.
+005039 MARINER NETWORKS
+00503A DATONG ELECTRONICS LTD.
+00503B MEDIAFIRE CORPORATION
+00503C TSINGHUA NOVEL ELECTRONICS
+00503E CISCO SYSTEMS, INC.
+00503F ANCHOR GAMES
+005040 EMWARE, INC.
+005041 CTX OPTO ELECTRONIC CORP.
+005042 SCI MANUFACTURING
+005043 MARVELL SEMICONDUCTOR, INC.
+005044 ASACA CORPORATION
+005045 RIOWORKS SOLUTIONS, INC.
+005046 MENICX INTERNATIONAL CO., LTD.
+005048 INFOLIBRIA
+005049 ELLACOYA NETWORKS, INC.
+00504A ELTECO A.S.
+00504B BARCONET N.V.
+00504C GALIL MOTION CONTROL, INC.
+00504D TOKYO ELECTRON DEVICE LTD.
+00504E SIERRA MONITOR CORP.
+00504F OLENCOM ELECTRONICS
+005050 CISCO SYSTEMS, INC.
+005051 IWATSU ELECTRIC CO., LTD.
+005052 TIARA NETWORKS, INC.
+005053 CISCO SYSTEMS, INC.
+005054 CISCO SYSTEMS, INC.
+005055 DOMS A/S
+005056 VMWARE, INC.
+005057 BROADBAND ACCESS SYSTEMS
+005058 VEGASTREAM LIMITED
+005059 SUITE TECHNOLOGY SYSTEMS
+00505A NETWORK ALCHEMY, INC.
+00505B KAWASAKI LSI U.S.A., INC.
+00505C TUNDO CORPORATION
+00505E DIGITEK MICROLOGIC S.A.
+00505F BRAND INNOVATORS
+005060 TANDBERG TELECOM AS
+005062 KOUWELL ELECTRONICS CORP.  **
+005063 OY COMSEL SYSTEM AB
+005064 CAE ELECTRONICS
+005065 DENSEI-LAMBAD Co., Ltd.
+005066 ATECOM GMBH ADVANCED
+005067 AEROCOMM, INC.
+005068 ELECTRONIC INDUSTRIES
+005069 PIXSTREAM INCORPORATED
+00506A EDEVA, INC.
+00506B SPX-ATEG
+00506C G & L BEIJER ELECTRONICS AB
+00506D VIDEOJET SYSTEMS
+00506E CORDER ENGINEERING CORPORATION
+00506F G-CONNECT
+005070 CHAINTECH COMPUTER CO., LTD.
+005071 AIWA CO., LTD.
+005072 CORVIS CORPORATION
+005073 CISCO SYSTEMS, INC.
+005074 ADVANCED HI-TECH CORP.
+005075 KESTREL SOLUTIONS
+005076 IBM
+005077 PROLIFIC TECHNOLOGY, INC.
+005078 MEGATON HOUSE, LTD.
+00507A XPEED, INC.
+00507B MERLOT COMMUNICATIONS
+00507C VIDEOCON AG
+00507D IFP
+00507E NEWER TECHNOLOGY
+00507F DRAYTEK CORP.
+005080 CISCO SYSTEMS, INC.
+005081 MURATA MACHINERY, LTD.
+005082 FORESSON CORPORATION
+005083 GILBARCO, INC.
+005084 ATL PRODUCTS
+005086 TELKOM SA, LTD.
+005087 TERASAKI ELECTRIC CO., LTD.
+005088 AMANO CORPORATION
+005089 SAFETY MANAGEMENT SYSTEMS
+00508B COMPAQ COMPUTER CORPORATION
+00508C RSI SYSTEMS
+00508D ABIT COMPUTER CORPORATION
+00508E OPTIMATION, INC.
+00508F ASITA TECHNOLOGIES INT'L LTD.
+005090 DCTRI
+005091 NETACCESS, INC.
+005092 RIGAKU INDUSTRIAL CORPORATION
+005093 BOEING
+005094 PACE MICRO TECHNOLOGY PLC
+005095 PERACOM NETWORKS
+005096 SALIX TECHNOLOGIES, INC.
+005097 MMC-EMBEDDED
+005098 GLOBALOOP, LTD.
+005099 3COM EUROPE, LTD.
+00509A TAG ELECTRONIC SYSTEMS
+00509B SWITCHCORE AB
+00509C BETA RESEARCH
+00509D THE INDUSTREE B.V.
+00509E LES TECHNOLOGIES
+00509F HORIZON COMPUTER
+0050A0 DELTA COMPUTER SYSTEMS, INC.
+0050A1 CARLO GAVAZZI, INC.
+0050A2 CISCO SYSTEMS, INC.
+0050A3 TRANSMEDIA COMMUNICATIONS, INC
+0050A4 IO TECH, INC.
+0050A5 CAPITOL BUSINESS SYSTEMS, LTD.
+0050A6 OPTRONICS
+0050A7 CISCO SYSTEMS, INC.
+0050A8 OPENCON SYSTEMS, INC.
+0050A9 MOLDAT WIRELESS TECHNOLGIES
+0050AA KONICA CORPORATION
+0050AB NALTEC, INC.
+0050AC MAPLE COMPUTER CORPORATION
+0050AD COMMUNIQUE WIRELESS CORP.
+0050AE IWAKI ELECTRONICS CO., LTD.
+0050AF INTERGON, INC.
+0050B0 TECHNOLOGY ATLANTA CORPORATION
+0050B1 GIDDINGS & LEWIS
+0050B2 BRODEL AUTOMATION
+0050B3 VOICEBOARD CORPORATION
+0050B4 SATCHWELL CONTROL SYSTEMS, LTD
+0050B5 FICHET-BAUCHE
+0050B6 GOOD WAY IND. CO., LTD.
+0050B7 BOSER TECHNOLOGY CO., LTD.
+0050B8 INOVA COMPUTERS GMBH & CO. KG
+0050B9 XITRON TECHNOLOGIES, INC.
+0050BA D-LINK
+0050BB CMS TECHNOLOGIES
+0050BC HAMMER STORAGE SOLUTIONS
+0050BD CISCO SYSTEMS, INC.
+0050BE FAST MULTIMEDIA AG
+0050BF MOTOTECH INC.
+0050C0 GATAN, INC.
+0050C1 GEMFLEX NETWORKS, LTD.
+0050C2 IEEE REGISTRATION AUTHORITY
+0050C4 IMD
+0050C5 ADS TECHNOLOGIES, INC.
+0050C6 LOOP TELECOMMUNICATION
+0050C8 ADDONICS COMMUNICATIONS, INC.
+0050C9 MASPRO DENKOH CORP.
+0050CA NET TO NET TECHNOLOGIES
+0050CB JETTER
+0050CC XYRATEX
+0050CD DIGIANSWER A/S
+0050CE LG INTERNATIONAL CORP.
+0050CF VANLINK COMMUNICATION
+0050D0 MINERVA SYSTEMS
+0050D1 CISCO SYSTEMS, INC.
+0050D2 BAE Systems Canada, Inc.
+0050D3 DIGITAL AUDIO
+0050D4 JOOHONG INFORMATION &
+0050D5 AD SYSTEMS CORP.
+0050D6 ATLAS COPCO TOOLS AB
+0050D7 TELSTRAT
+0050D8 UNICORN COMPUTER CORP.
+0050D9 ENGETRON-ENGENHARIA ELETRONICA
+0050DA 3COM CORPORATION
+0050DB CONTEMPORARY CONTROL
+0050DC TAS TELEFONBAU A. SCHWABE
+0050DD SERRA SOLDADURA, S.A.
+0050DE SIGNUM SYSTEMS CORP.
+0050DF AIRFIBER, INC.
+0050E1 NS TECH ELECTRONICS SDN BHD
+0050E2 CISCO SYSTEMS, INC.
+0050E3 TELEGATE
+0050E4 APPLE COMPUTER, INC.
+0050E6 HAKUSAN CORPORATION
+0050E7 PARADISE INNOVATIONS (ASIA)
+0050E8 NOMADIX INC.
+0050EA XEL COMMUNICTIONS, INC.
+0050EB ALPHA-TOP CORPORATION
+0050EC OLICOM A/S
+0050ED ANDA NETWORKS
+0050EE TEK DIGITEL CORPORATION
+0050EF SPE SYSTEMHAUS GMBH
+0050F0 CISCO SYSTEMS, INC.
+0050F1 LIBIT SIGNAL PROCESSING, LTD.
+0050F2 MICROSOFT CORP.
+0050F3 GLOBAL NET INFORMATION CO.,LTD
+0050F4 SIGMATEK GMBH & CO. KG
+0050F6 PAN-INTERNATIONAL
+0050F7 VENTURE MANUFACTURING
+0050F8 ENTREGA TECHNOLOGIES, INC.
+0050FA OXTEL, LTD.
+0050FB VSK ELECTRONICS
+0050FC EDIMAX TECHNOLOGY CO., LTD.
+0050FD ISIONCOMM CO., LTD.
+0050FE PCTVNET ASA
+0050FF HAKKO ELECTRONICS CO., LTD.
+006000 XYCOM INC.
+006001 INNOSYS, INC.
+006002 SCREEN SUBTITLING SYSTEMS, LTD
+006003 TERAOKA WEIGH SYSTEM PTE, LTD.
+006004 COMPUTADORES MODULARES SA
+006005 FEEDBACK DATA LTD.
+006006 SOTEC CO., LTD
+006007 ACRES GAMING, INC.
+006008 3COM CORPORATION
+006009 CISCO SYSTEMS, INC.
+00600A SORD COMPUTER CORPORATION
+00600B LOGWARE GMBH
+00600C APPLIED DATA SYSTEMS, INC.
+00600D MICRODESIGN GMBH
+00600E WAVENET INTERNATIONAL, INC.
+00600F WESTELL, INC.
+006010 NETWORK MACHINES, INC.
+006011 CRYSTAL SEMICONDUCTOR CORP.
+006012 POWER COMPUTING CORPORATION
+006013 NETSTAL MASCHINEN AG
+006014 EDEC CO., LTD.
+006015 NET2NET CORPORATION
+006016 CLARIION
+006017 TOKIMEC INC.
+006018 STELLAR ONE CORPORATION
+006019 BOEHRINGER MANNHEIM CORP.
+00601A KEITHLEY INSTRUMENTS
+00601B MESA ELECTRONICS
+00601C TELXON CORPORATION
+00601D LUCENT TECHNOLOGIES
+00601E SOFTLAB, INC.
+00601F STALLION TECHNOLOGIES
+006020 PIVOTAL NETWORKING, INC.
+006021 DSC CORPORATION
+006022 VICOM SYSTEMS, INC.
+006023 PERICOM SEMICONDUCTOR CORP.
+006024 GRADIENT TECHNOLOGIES, INC.
+006025 ACTIVE IMAGING PLC
+006026 VIKING COMPONENTS, INC.
+006027 Superior Modular Products
+006028 MACROVISION CORPORATION
+006029 CARY PERIPHERALS INC.
+00602A SYMICRON COMPUTER
+00602B PEAK AUDIO
+00602C LINX DATA TERMINALS, INC.
+00602D ALERTON TECHNOLOGIES, INC.
+00602E CYCLADES CORPORATION
+00602F CISCO SYSTEMS, INC.
+006030 VILLAGE TRONIC
+006031 HRK SYSTEMS
+006032 I-CUBE, INC.
+006033 ACUITY IMAGING, INC.
+006034 ROBERT BOSCH GMBH
+006035 DALLAS SEMICONDUCTOR, INC.
+006036 AUSTRIAN RESEARCH CENTER
+006037 PHILIPS SEMICONDUCTORS
+006038 Nortel Networks
+006039 SANCOM TECHNOLOGY, INC.
+00603A QUICK CONTROLS LTD.
+00603B AMTEC SPA
+00603C HAGIWARA SYS-COM CO., LTD.
+00603D 3CX
+00603E CISCO SYSTEMS, INC.
+00603F PATAPSCO DESIGNS
+006040 NETRO CORP.
+006041 Yokogawa Electric Corporation
+006042 TKS (USA), INC.
+006043 COMSOFT SYSTEMS, INC.
+006044 LITTON/POLY-SCIENTIFIC
+006045 PATHLIGHT TECHNOLOGIES
+006046 VMETRO, INC.
+006047 CISCO SYSTEMS, INC.
+006048 EMC CORPORATION
+006049 VINA TECHNOLOGIES
+00604A SAIC IDEAS GROUP
+00604B BIODATA GMBH
+00604C SAT
+00604D MMC NETWORKS, INC.
+00604E CYCLE COMPUTER CORPORATION, INC.
+00604F SUZUKI MFG. CO., LTD.
+006050 INTERNIX INC.
+006051 QUALITY SEMICONDUCTOR
+006052 PERIPHERALS ENTERPRISE CO., L.
+006053 TOYODA MACHINE WORKS, LTD.
+006054 CONTROLWARE GMBH
+006055 CORNELL UNIVERSITY
+006056 NETWORK TOOLS, INC.
+006057 MURATA MANUFACTURING CO., LTD.
+006058 COPPER MOUNTAIN
+006059 TECHNICAL COMMUNICATIONS CORP.
+00605A CELCORE, INC.
+00605B INTRASERVER TECHNOLOGY INC.
+00605C CISCO SYSTEMS, INC.
+00605D SCANIVALVE CORP.
+00605E LIBERTY TECHNOLOGY NETWORKING
+00605F NIPPON UNISOFT CORPORATION
+006060 DAWNING TECHNOLOGIES, INC.
+006061 WHISTLE COMMUNICATIONS CORP.
+006062 TELESYNC, INC.
+006063 PSION DACOM PLC.
+006064 NETCOMM LIMITED
+006065 BERNECKER & RAINER
+006066 LACROIX TECHNOLGIE
+006067 ACER NETXUS INC.
+006068 EICON TECHNOLOGY CORPORATION
+006069 BROCADE COMMUNICATIONS SYSTEMS
+00606A MITSUBISHI WIRELESS COMM. INC.
+00606B AICHI ELECTRONICS CO.,LTD.
+00606C ARESCOM
+00606D DIGITAL EQUIPMENT CORP.
+00606E DAVICOM SEMICONDUCTOR, INC.
+00606F CLARION CORPORATION OF AMERICA
+006070 CISCO SYSTEMS, INC.
+006071 MIDAS LAB, INC.
+006072 VXL INSTRUMENTS, LIMITED
+006073 REDCREEK COMMUNICATIONS, INC.
+006074 QSC AUDIO PRODUCTS
+006075 PENTEK, INC.
+006076 SCHLUMBERGER TECHNOLOGIES
+006077 PRISA NETWORKS
+006078 POWER MEASUREMENT LTD.
+006079 WAVEPHORE NETWORKS, INC.
+00607A DVS GMBH
+00607B FORE SYSTEMS, INC.
+00607C WAVEACCESS, LTD.
+00607D SENTIENT NETWORKS INC.
+00607E GIGALABS, INC.
+00607F AURORA TECHNOLOGIES, INC.
+006080 MICROTRONIX DATACOM LTD.
+006081 TV/COM INTERNATIONAL
+006082 NOVALINK TECHNOLOGIES, INC.
+006083 CISCO SYSTEMS, INC.
+006084 DIGITAL VIDEO
+006085 STORAGE CONCEPTS
+006086 LOGIC REPLACEMENT TECH. LTD.
+006087 KANSAI ELECTRIC CO., LTD.
+006088 WHITE MOUNTAIN DSP, INC.
+006089 XATA
+00608A CITADEL COMPUTER
+00608B CONFERTECH INTERNATIONAL
+00608C 3COM CORPORATION
+00608D UNIPULSE CORP.
+00608E HE ELECTRONICS, TECHNOLOGIE &
+00608F TEKRAM TECHNOLOGY CO., LTD.
+006090 ABLE COMMUNICATIONS, INC.
+006091 FIRST PACIFIC NETWORKS, INC.
+006092 MICRO/SYS, INC.
+006093 VARIAN
+006094 IBM CORP.
+006095 ACCU-TIME SYSTEMS, INC.
+006096 T.S. MICROTECH INC.
+006097 3COM CORPORATION
+006098 HT COMMUNICATIONS
+006099 LAN MEDIA CORPORATION
+00609A NJK TECHNO CO.
+00609B ASTRO-MED, INC.
+00609C PERKIN-ELMER CORPORATION
+00609D PMI FOOD EQUIPMENT GROUP
+00609E X3 - INFORMATION TECHNOLOGY
+00609F PHAST CORPORATION
+0060A0 SWITCHED NETWORK
+0060A1 VPNET
+0060A2 NIHON UNISYS LIMITED CO.
+0060A3 CONTINUUM TECHNOLOGY CORP.
+0060A4 GRINAKER SYSTEM TECHNOLOGIES
+0060A5 PERFORMANCE TELECOM CORP.
+0060A6 PARTICLE MEASURING SYSTEMS
+0060A7 MICROSENS GMBH & CO. KG
+0060A8 TIDOMAT AB
+0060A9 GESYTEC MBH
+0060AA INTELLIGENT DEVICES INC. (IDI)
+0060AB LARSCOM INCORPORATED
+0060AC RESILIENCE CORPORATION
+0060AD MEGACHIPS CORPORATION
+0060AE TRIO INFORMATION SYSTEMS AB
+0060AF PACIFIC MICRO DATA, INC.
+0060B0 HEWLETT-PACKARD CO.
+0060B1 INPUT/OUTPUT, INC.
+0060B2 PROCESS CONTROL CORP.
+0060B3 Z-COM, INC.
+0060B4 GLENAYRE R&D INC.
+0060B5 KEBA GMBH
+0060B6 LAND COMPUTER CO., LTD.
+0060B7 CHANNELMATIC, INC.
+0060B8 CORELIS INC.
+0060B9 NITSUKO CORPORATION
+0060BA SAHARA NETWORKS, INC.
+0060BB CABLETRON - NETLINK, INC.
+0060BC KEUNYOUNG ELECTRONICS &
+0060BD HUBBELL-PULSECOM
+0060BE WEBTRONICS
+0060BF MACRAIGOR SYSTEMS, INC.
+0060C0 NERA AS
+0060C1 WAVESPAN CORPORATION
+0060C2 MPL AG
+0060C3 NETVISION CORPORATION
+0060C4 SOLITON SYSTEMS K.K.
+0060C5 ANCOT CORP.
+0060C6 DCS AG
+0060C7 AMATI COMMUNICATIONS CORP.
+0060C8 KUKA WELDING SYSTEMS & ROBOTS
+0060C9 CONTROLNET, INC.
+0060CA HARMONIC SYSTEMS INCORPORATED
+0060CB HITACHI ZOSEN CORPORATION
+0060CC EMTRAK, INCORPORATED
+0060CD VIDEOSERVER, INC.
+0060CE ACCLAIM COMMUNICATIONS
+0060CF ALTEON NETWORKS, INC.
+0060D0 SNMP RESEARCH INCORPORATED
+0060D1 CASCADE COMMUNICATIONS
+0060D2 LUCENT TECHNOLOGIES TAIWAN
+0060D3 AT&T
+0060D4 ELDAT COMMUNICATION LTD.
+0060D5 MIYACHI TECHNOS CORP.
+0060D6 NOVATEL WIRELESS TECHNOLOGIES
+0060D7 ECOLE POLYTECHNIQUE FEDERALE
+0060D8 ELMIC SYSTEMS, INC.
+0060D9 TRANSYS NETWORKS INC.
+0060DA JBM ELECTRONICS CO.
+0060DB NTP ELEKTRONIK A/S
+0060DC TOYO COMMUNICATION EQUIPMENT
+0060DD MYRICOM, INC.
+0060DE KAYSER-THREDE GMBH
+0060DF INRANGE TECHNOLOGIES CORP.
+0060E0 AXIOM TECHNOLOGY CO., LTD.
+0060E1 ORCKIT COMMUNICATIONS LTD.
+0060E2 QUEST ENGINEERING & DEV.
+0060E3 ARBIN INSTRUMENTS
+0060E4 COMPUSERVE, INC.
+0060E5 FUJI AUTOMATION CO., LTD.
+0060E6 SHOMITI SYSTEMS INCORPORATED
+0060E7 RANDATA
+0060E8 HITACHI COMPUTER PRODUCTS
+0060E9 ATOP TECHNOLOGIES, INC.
+0060EA STREAMLOGIC
+0060EB FOURTHTRACK SYSTEMS
+0060EC HERMARY OPTO ELECTRONICS INC.
+0060ED RICARDO TEST AUTOMATION LTD.
+0060EE APOLLO
+0060EF FLYTECH TECHNOLOGY CO., LTD.
+0060F0 JOHNSON & JOHNSON MEDICAL, INC
+0060F1 EXP COMPUTER, INC.
+0060F2 LASERGRAPHICS, INC.
+0060F3 NETCOM SYSTEMS, INC.
+0060F4 ADVANCED COMPUTER SOLUTIONS,
+0060F5 ICON WEST, INC.
+0060F6 NEXTEST COMMUNICATION
+0060F7 DATAFUSION SYSTEMS
+0060F8 LORAN INTERNATIONAL TECHN. INC
+0060F9 DIAMOND LANE COMMUNICATIONS
+0060FA EDUCATIONAL TECHNOLOGY
+0060FB PACKETEER, INC.
+0060FC CONSERVATION THROUGH
+0060FD NETICS, INC.
+0060FE LYNX SYSTEM DEVELOPERS, INC.
+0060FF QUVIS, INC.
+0070B0 M/A-COM INC. COMPANIES
+0070B3 DATA RECALL LTD.
+008000 MULTITECH SYSTEMS, INC.
+008001 PERIPHONICS CORPORATION
+008002 SATELCOM (UK) LTD
+008003 HYTEC ELECTRONICS LTD.
+008004 ANTLOW COMMUNICATIONS, LTD.
+008005 CACTUS COMPUTER INC.
+008006 COMPUADD CORPORATION
+008007 DLOG NC-SYSTEME
+008008 DYNATECH COMPUTER SYSTEMS
+008009 JUPITER SYSTEMS, INC.
+00800A JAPAN COMPUTER CORP.
+00800B CSK CORPORATION
+00800C VIDECOM LIMITED
+00800D VOSSWINKEL F.U.
+00800E ATLANTIX CORPORATION
+00800F STANDARD MICROSYSTEMS
+008010 COMMODORE INTERNATIONAL
+008011 DIGITAL SYSTEMS INT'L. INC.
+008012 INTEGRATED MEASUREMENT SYSTEMS
+008013 THOMAS-CONRAD CORPORATION
+008014 ESPRIT SYSTEMS
+008015 SEIKO SYSTEMS, INC.
+008016 WANDEL AND GOLTERMANN
+008017 PFU LIMITED
+008018 KOBE STEEL, LTD.
+008019 DAYNA COMMUNICATIONS, INC.
+00801A BELL ATLANTIC
+00801B KODIAK TECHNOLOGY
+00801C NEWPORT SYSTEMS SOLUTIONS
+00801D INTEGRATED INFERENCE MACHINES
+00801E XINETRON, INC.
+00801F KRUPP ATLAS ELECTRONIK GMBH
+008020 NETWORK PRODUCTS
+008021 NEWBRIDGE RESEARCH CORP.
+008022 SCAN-OPTICS
+008023 INTEGRATED BUSINESS NETWORKS
+008024 KALPANA, INC.
+008025 STOLLMANN GMBH
+008026 NETWORK PRODUCTS CORPORATION
+008027 ADAPTIVE SYSTEMS, INC.
+008028 TRADPOST (HK) LTD
+008029 EAGLE TECHNOLOGY, INC.
+00802A TEST SYSTEMS & SIMULATIONS INC
+00802B INTEGRATED MARKETING CO
+00802C THE SAGE GROUP PLC
+00802D XYLOGICS INC
+00802E CASTLE ROCK COMPUTING
+00802F NATIONAL INSTRUMENTS CORP.
+008030 NEXUS ELECTRONICS
+008031 BASYS, CORP.
+008032 ACCESS CO., LTD.
+008033 FORMATION, INC.
+008034 SMT GOUPIL
+008035 TECHNOLOGY WORKS, INC.
+008036 REFLEX MANUFACTURING SYSTEMS
+008037 Ericsson Group
+008038 DATA RESEARCH & APPLICATIONS
+008039 ALCATEL STC AUSTRALIA
+00803A VARITYPER, INC.
+00803B APT COMMUNICATIONS, INC.
+00803C TVS ELECTRONICS LTD
+00803D SURIGIKEN CO.,  LTD.
+00803E SYNERNETICS
+00803F TATUNG COMPANY
+008040 JOHN FLUKE MANUFACTURING CO.
+008041 VEB KOMBINAT ROBOTRON
+008042 FORCE COMPUTERS
+008043 NETWORLD, INC.
+008044 SYSTECH COMPUTER CORP.
+008045 MATSUSHITA ELECTRIC IND. CO
+008046 UNIVERSITY OF TORONTO
+008047 IN-NET CORP.
+008048 COMPEX INCORPORATED
+008049 NISSIN ELECTRIC CO., LTD.
+00804A PRO-LOG
+00804B EAGLE TECHNOLOGIES PTY.LTD.
+00804C CONTEC CO., LTD.
+00804D CYCLONE MICROSYSTEMS, INC.
+00804E APEX COMPUTER COMPANY
+00804F DAIKIN INDUSTRIES, LTD.
+008050 ZIATECH CORPORATION
+008051 FIBERMUX
+008052 TECHNICALLY ELITE CONCEPTS
+008053 INTELLICOM, INC.
+008054 FRONTIER TECHNOLOGIES CORP.
+008055 FERMILAB
+008056 SPHINX ELEKTRONIK GMBH
+008057 ADSOFT, LTD.
+008058 PRINTER SYSTEMS CORPORATION
+008059 STANLEY ELECTRIC CO., LTD
+00805A TULIP COMPUTERS INTERNAT'L B.V
+00805B CONDOR SYSTEMS, INC.
+00805C AGILIS CORPORATION
+00805D CANSTAR
+00805E LSI LOGIC CORPORATION
+00805F COMPAQ COMPUTER CORPORATION
+008060 NETWORK INTERFACE CORPORATION
+008061 LITTON SYSTEMS, INC.
+008062 INTERFACE  CO.
+008063 RICHARD HIRSCHMANN GMBH & CO.
+008064 WYSE TECHNOLOGY
+008065 CYBERGRAPHIC SYSTEMS PTY LTD.
+008066 ARCOM CONTROL SYSTEMS, LTD.
+008067 SQUARE D COMPANY
+008068 YAMATECH SCIENTIFIC LTD.
+008069 COMPUTONE SYSTEMS
+00806A ERI (EMPAC RESEARCH INC.)
+00806B SCHMID TELECOMMUNICATION
+00806C CEGELEC PROJECTS LTD
+00806D CENTURY SYSTEMS CORP.
+00806E NIPPON STEEL CORPORATION
+00806F ONELAN LTD.
+008070 COMPUTADORAS MICRON
+008071 SAI TECHNOLOGY
+008072 MICROPLEX SYSTEMS LTD.
+008073 DWB ASSOCIATES
+008074 FISHER CONTROLS
+008075 PARSYTEC GMBH
+008076 MCNC
+008077 BROTHER INDUSTRIES, LTD.
+008078 PRACTICAL PERIPHERALS, INC.
+008079 MICROBUS DESIGNS LTD.
+00807A AITECH SYSTEMS LTD.
+00807B ARTEL COMMUNICATIONS CORP.
+00807C FIBERCOM, INC.
+00807D EQUINOX SYSTEMS INC.
+00807E SOUTHERN PACIFIC LTD.
+00807F DY-4 INCORPORATED
+008080 DATAMEDIA CORPORATION
+008081 KENDALL SQUARE RESEARCH CORP.
+008082 PEP MODULAR COMPUTERS GMBH
+008083 AMDAHL
+008084 THE CLOUD INC.
+008085 H-THREE SYSTEMS CORPORATION
+008086 COMPUTER GENERATION INC.
+008087 OKI ELECTRIC INDUSTRY CO., LTD
+008088 VICTOR COMPANY OF JAPAN, LTD.
+008089 TECNETICS (PTY) LTD.
+00808A SUMMIT MICROSYSTEMS CORP.
+00808B DACOLL LIMITED
+00808C NetScout Systems, Inc.
+00808D WESTCOAST TECHNOLOGY B.V.
+00808E RADSTONE TECHNOLOGY
+00808F C. ITOH ELECTRONICS, INC.
+008090 MICROTEK INTERNATIONAL, INC.
+008091 TOKYO ELECTRIC CO.,LTD
+008092 JAPAN COMPUTER INDUSTRY, INC.
+008093 XYRON CORPORATION
+008094 ALFA LAVAL AUTOMATION AB
+008095 BASIC MERTON HANDELSGES.M.B.H.
+008096 HUMAN DESIGNED SYSTEMS, INC.
+008097 CENTRALP AUTOMATISMES
+008098 TDK CORPORATION
+008099 KLOCKNER MOELLER IPC
+00809A NOVUS NETWORKS LTD
+00809B JUSTSYSTEM CORPORATION
+00809C LUXCOM, INC.
+00809D Commscraft Ltd.
+00809E DATUS GMBH
+00809F ALCATEL BUSINESS SYSTEMS
+0080A0 EDISA HEWLETT PACKARD S/A
+0080A1 MICROTEST, INC.
+0080A2 CREATIVE ELECTRONIC SYSTEMS
+0080A3 LANTRONIX
+0080A4 LIBERTY ELECTRONICS
+0080A5 SPEED INTERNATIONAL
+0080A6 REPUBLIC TECHNOLOGY, INC.
+0080A7 MEASUREX CORP.
+0080A8 VITACOM CORPORATION
+0080A9 CLEARPOINT RESEARCH
+0080AA MAXPEED
+0080AB DUKANE NETWORK INTEGRATION
+0080AC IMLOGIX, DIVISION OF GENESYS
+0080AD CNET TECHNOLOGY, INC.
+0080AE HUGHES NETWORK SYSTEMS
+0080AF ALLUMER CO., LTD.
+0080B0 ADVANCED INFORMATION
+0080B1 SOFTCOM A/S
+0080B2 NETWORK EQUIPMENT TECHNOLOGIES
+0080B3 AVAL DATA CORPORATION
+0080B4 SOPHIA SYSTEMS
+0080B5 UNITED NETWORKS INC.
+0080B6 THEMIS COMPUTER
+0080B7 STELLAR COMPUTER
+0080B8 BUG, INCORPORATED
+0080B9 ARCHE TECHNOLIGIES INC.
+0080BA SPECIALIX (ASIA) PTE, LTD
+0080BB HUGHES LAN SYSTEMS
+0080BC HITACHI ENGINEERING CO., LTD
+0080BD THE FURUKAWA ELECTRIC CO., LTD
+0080BE ARIES RESEARCH
+0080BF TAKAOKA ELECTRIC MFG. CO. LTD.
+0080C0 PENRIL DATACOMM
+0080C1 LANEX CORPORATION
+0080C2 IEEE 802 COMMITTEE
+0080C3 BICC INFORMATION SYSTEMS & SVC
+0080C4 DOCUMENT TECHNOLOGIES, INC.
+0080C5 NOVELLCO DE MEXICO
+0080C6 NATIONAL DATACOMM CORPORATION
+0080C7 XIRCOM
+0080C8 D-LINK SYSTEMS, INC.
+0080C9 ALBERTA MICROELECTRONIC CENTRE
+0080CA NETCOM RESEARCH INCORPORATED
+0080CB FALCO DATA PRODUCTS
+0080CC MICROWAVE BYPASS SYSTEMS
+0080CD MICRONICS COMPUTER, INC.
+0080CE BROADCAST TELEVISION SYSTEMS
+0080CF EMBEDDED PERFORMANCE INC.
+0080D0 COMPUTER PERIPHERALS, INC.
+0080D1 KIMTRON CORPORATION
+0080D2 SHINNIHONDENKO CO., LTD.
+0080D3 SHIVA CORP.
+0080D4 CHASE RESEARCH LTD.
+0080D5 CADRE TECHNOLOGIES
+0080D6 NUVOTECH, INC.
+0080D7 FANTUM ENGINEERING, INC.
+0080D8 NETWORK PERIPHERALS INC.
+0080D9 EMK ELEKTRONIK
+0080DA BRUEL & KJAER
+0080DB GRAPHON CORPORATION
+0080DC PICKER INTERNATIONAL
+0080DD GMX INC/GIMIX
+0080DE GIPSI S.A.
+0080DF ADC CODENOLL TECHNOLOGY CORP.
+0080E0 XTP SYSTEMS, INC.
+0080E1 STMICROELECTRONICS
+0080E2 T.D.I. CO., LTD.
+0080E3 CORAL NETWORK CORPORATION
+0080E4 NORTHWEST DIGITAL SYSTEMS, INC
+0080E5 MYLEX CORPORATION
+0080E6 PEER NETWORKS, INC.
+0080E7 LYNWOOD SCIENTIFIC DEV. LTD.
+0080E8 CUMULUS CORPORATIION
+0080E9 MADGE NETWORKS
+0080EA ADVA Optical Networking Ltd.
+0080EB COMPCONTROL B.V.
+0080EC SUPERCOMPUTING SOLUTIONS, INC.
+0080ED IQ TECHNOLOGIES, INC.
+0080EE THOMSON CSF
+0080EF RATIONAL
+0080F0 KYUSHU MATSUSHITA ELECTRIC CO.
+0080F1 OPUS SYSTEMS
+0080F2 RAYCOM SYSTEMS INC
+0080F3 SUN ELECTRONICS CORP.
+0080F4 TELEMECANIQUE ELECTRIQUE
+0080F5 QUANTEL LTD
+0080F6 SYNERGY MICROSYSTEMS
+0080F7 ZENITH ELECTRONICS
+0080F8 MIZAR, INC.
+0080F9 HEURIKON CORPORATION
+0080FA RWT GMBH
+0080FB BVM LIMITED
+0080FC AVATAR CORPORATION
+0080FD EXSCEED CORPRATION
+0080FE AZURE TECHNOLOGIES, INC.
+0080FF SOC. DE TELEINFORMATIQUE RTC
+009000 DIAMOND MULTIMEDIA
+009001 NISHIMU ELCTRONICS INDUSTRIES
+009002 ALLGON AB
+009003 APLIO
+009004 3COM EUROPE LTD.
+009005 PROTECH SYSTEMS CO., LTD.
+009006 HAMAMATSU PHOTONICS K.K.
+009007 DOMEX TECHNOLOGY CORP.
+009008 HAN A SYSTEMS, INC.
+009009 i Controls, Inc.
+00900A PROTON ELECTRONIC INDUSTRIAL
+00900B LANNER ELECTRONICS, INC.
+00900C CISCO SYSTEMS, INC.
+00900D OVERLAND DATA INC.
+00900E HANDLINK TECHNOLOGIES, INC.
+00900F KAWASAKI HEAVY INDUSTRIES, LTD
+009010 SIMULATION LABORATORIES, INC.
+009011 WAVTRACE, INC.
+009012 GLOBESPAN SEMICONDUCTOR, INC.
+009013 SAMSAN CORP.
+009014 ROTORK INSTRUMENTS, LTD.
+009015 CENTIGRAM COMMUNICATIONS CORP.
+009016 ZAC
+009017 ZYPCOM, INC.
+009018 ITO ELECTRIC INDUSTRY CO, LTD.
+009019 HERMES ELECTRONICS CO., LTD.
+00901A UNISPHERE SOLUTIONS
+00901B DIGITAL CONTROLS
+00901C MPS SOFTWARE GMBH
+00901D PEC (NZ) LTD.
+00901E SELESTA INGEGNE RIA S.P.A.
+00901F ADTEC PRODUCTIONS, INC.
+009020 PHILIPS ANALYTICAL X-RAY B.V.
+009021 CISCO SYSTEMS, INC.
+009022 IVEX
+009023 ZILOG INC.
+009024 PIPELINKS, INC.
+009025 VISION SYSTEMS LTD. PTY
+009026 ADVANCED SWITCHING
+009027 INTEL CORPORATION
+009028 NIPPON SIGNAL CO., LTD.
+009029 CRYPTO AG
+00902A COMMUNICATION DEVICES, INC.
+00902B CISCO SYSTEMS, INC.
+00902C DATA & CONTROL EQUIPMENT LTD.
+00902D DATA ELECTRONICS
+00902E NAMCO LIMITED
+00902F NETCORE SYSTEMS, INC.
+009030 HONEYWELL-DATING
+009031 MYSTICOM, LTD.
+009032 PELCOMBE GROUP LTD.
+009033 INNOVAPHONE GMBH
+009034 IMAGIC, INC.
+009035 ALPHA TELECOM, INC.
+009036 ENS, INC.
+009037 ACUCOMM, INC.
+009038 FOUNTAIN TECHNOLOGIES, INC.
+009039 SHASTA NETWORKS
+00903A NIHON MEDIA TOOL INC.
+00903B TRIEMS RESEARCH LAB, INC.
+00903C ATLANTIC NETWORK SYSTEMS
+00903D BIOPAC SYSTEMS, INC.
+00903E N.V. PHILIPS INDUSTRIAL
+00903F AZTEC RADIOMEDIA
+009040 CASTLE NETWORKS, INC.
+009041 APPLIED DIGITAL ACCESS
+009042 ECCS
+009043 NICHIBEI DENSHI CO., LTD.
+009044 ASSURED DIGITAL, INC.
+009045 MARIPOSA TECHNOLOGY
+009046 DEXDYNE, LTD.
+009047 GIGA FAST E. LTD.
+009048 ZEAL CORPORATION
+009049 ENTRIDIA CORPORATION
+00904A CONCUR SYSTEM TECHNOLOGIES
+00904B GEMTEK TECHNOLOGY CO., LTD.
+00904C EPIGRAM, INC.
+00904D SPEC S.A.
+00904E DELEM BV
+00904F ABB POWER T&D COMPANY, INC.
+009050 TELESTE OY
+009051 ULTIMATE TECHNOLOGY CORP.
+009052 SELCOM ELETTRONICA S.R.L.
+009053 DAEWOO ELECTRONICS CO., LTD.
+009054 INNOVATIVE SEMICONDUCTORS, INC
+009055 PARKER HANNIFIN CORPORATION
+009056 TELESTREAM, INC.
+009057 AANETCOM, INC.
+009058 ULTRA ELECTRONICS LTD.
+009059 TELECOM DEVICE K.K.
+00905A DEARBORN GROUP, INC.
+00905B RAYMOND AND LAE ENGINEERING
+00905C EDMI
+00905D NETCOM SICHERHEITSTECHNIK GMBH
+00905E RAULAND-BORG CORPORATION
+00905F CISCO SYSTEMS, INC.
+009060 SYSTEM CREATE CORP.
+009061 PACIFIC RESEARCH & ENGINEERING
+009062 ICP VORTEX COMPUTERSYSTEME
+009063 COHERENT COMMUNICATIONS
+009064 THOMSON BROADCAST SYSTEMS
+009065 FINISAR CORPORATION
+009066 Troika Networks, Inc.
+009067 WALKABOUT COMPUTERS, INC.
+009068 DVT CORP.
+009069 JUNIPER NETWORKS, INC.
+00906A TURNSTONE SYSTEMS, INC.
+00906B APPLIED RESOURCES, INC.
+00906C GWT GLOBAL WEIGHING
+00906D CISCO SYSTEMS, INC.
+00906E PRAXON, INC.
+00906F CISCO SYSTEMS, INC.
+009070 NEO NETWORKS, INC.
+009071 BADGER TECHNOLOGY, INC.
+009072 SIMRAD AS
+009073 GAIO TECHNOLOGY
+009074 ARGON NETWORKS, INC.
+009075 NEC DO BRASIL S.A.
+009076 FMT AIRCRAFT GATE SUPPORT
+009077 ADVANCED FIBRE COMMUNICATIONS
+009078 MER TELEMANAGEMENT
+009079 CLEARONE INC.
+00907A SPECTRALINK CORP.
+00907B E-TECH, INC.
+00907C DIGITALCAST, INC.
+00907D HOME WIRELESS NETWORKS
+00907E VETRONIX CORP.
+00907F WATCHGUARD TECHNOLOGIES, INC.
+009080 NOT LIMITED, INC.
+009081 ALOHA NETWORKS, INC.
+009082 FORCE INSTITUTE
+009083 TURBO COMMUNICATION, INC.
+009084 ATECH SYSTEM
+009085 GOLDEN ENTERPRISES, INC.
+009086 CISCO SYSTEMS, INC.
+009087 ITIS
+009088 BAXALL SECURITY LTD.
+009089 SOFTCOM MICROSYSTEMS, INC.
+00908A BAYLY COMMUNICATIONS, INC.
+00908B CELL COMPUTING, INC.
+00908C ETREND ELECTRONICS, INC.
+00908D VICKERS ELECTRONICS SYSTEMS
+00908E Nortel Networks Broadband Access
+00908F AUDIOCODES LTD.
+009090 I-BUS
+009091 DIGITALSCAPE, INC.
+009092 CISCO SYSTEMS, INC.
+009093 NANAO CORPORATION
+009094 OSPREY TECHNOLOGIES, INC.
+009095 UNIVERSAL AVIONICS
+009096 ASKEY COMPUTER CORP.
+009097 SYCAMORE NETWORKS
+009098 SBC DESIGNS, INC.
+009099 ALLIED TELESIS,K.K.
+00909A ONE WORLD SYSTEMS, INC.
+00909B MARKPOINT AB
+00909C COMBOX, LTD.
+00909D GSE SYSTEMS, INC.
+00909E DELPHI ENGINEERING GROUP
+00909F DIGI-DATA CORPORATION
+0090A0 8X8 INC.
+0090A1 FLYING PIG SYSTEMS, LTD.
+0090A2 CYBERTAN TECHNOLOGY, INC.
+0090A3 MEDIALINCS CO., LTD.
+0090A4 ALTIGA NETWORKS
+0090A5 SPECTRA LOGIC
+0090A6 CISCO SYSTEMS, INC.
+0090A7 CLIENTEC CORPORATION
+0090A8 NINETILES NETWORKS LTD.
+0090A9 WESTERN DIGITAL
+0090AA INDIGO ACTIVE VISION
+0090AB CISCO SYSTEMS, INC.
+0090AC OPTIVISION, INC.
+0090AD ASPECT ELECTRONICS, INC.
+0090AE ITALTEL SPA
+0090AF J. MORITA MFG. CORP.
+0090B0 VADEM
+0090B1 CISCO SYSTEMS, INC.
+0090B2 AVICI SYSTEMS INC.
+0090B3 AGRANAT SYSTEMS
+0090B4 WILLOWBROOK TECHNOLOGIES
+0090B5 NIKON CORPORATION
+0090B6 FIBEX SYSTEMS
+0090B7 DIGITAL LIGHTWAVE, INC.
+0090B8 ROHDE & SCHWARZ GMBH & CO. KG
+0090B9 BERAN INSTRUMENTS LTD.
+0090BA VALID NETWORKS, INC.
+0090BB TAINET COMMUNICATION SYSTEM
+0090BC TELEMANN CO., LTD.
+0090BD OMNIA COMMUNICATIONS, INC.
+0090BE IBC/INTEGRATED BUSINESS
+0090BF CISCO SYSTEMS, INC.
+0090C0 K.J. LAW ENGINEERS, INC.
+0090C1 EDA INDUSTRIES
+0090C2 JK MICROSYSTEMS, INC.
+0090C3 TOPIC SEMICONDUCTOR CORP.
+0090C4 JAVELIN SYSTEMS, INC.
+0090C5 INTERNET MAGIC, INC.
+0090C6 OPTIM SYSTEMS, INC.
+0090C7 ICOM INC.
+0090C8 WAVERIDER COMMUNICATIONS
+0090C9 PRODUCTIVITY ENHANCEMENT
+0090CA ACCORD VIDEO
+0090CB WIRELESS ONLINE, INC.
+0090CC PLANEX COMMUNICATIONS, INC.
+0090CD ENT-EMPRESA NACIONAL
+0090CE TETRA GMBH
+0090CF NORTEL
+0090D0 ALCATEL BELL
+0090D1 LEICHU ENTERPRISE CO., LTD.
+0090D2 ARTEL VIDEO SYSTEMS
+0090D3 GIESECKE & DEVRIENT GMBH
+0090D4 BINDVIEW DEVELOPMENT CORP.
+0090D5 EUPHONIX, INC.
+0090D6 CRYSTAL GROUP
+0090D7 NETBOOST CORP.
+0090D8 WHITECROSS SYSTEMS
+0090D9 CISCO SYSTEMS, INC.
+0090DA DYNARC, INC.
+0090DB NEXT LEVEL COMMUNICATIONS
+0090DC TECO INFORMATION SYSTEMS
+0090DD THE MIHARU COMMUNICATIONS
+0090DE CARDKEY SYSTEMS, INC.
+0090DF MITSUBISHI CHEMICAL
+0090E0 SYSTRAN CORP.
+0090E1 TELENA S.P.A.
+0090E2 DISTRIBUTED PROCESSING
+0090E3 AVEX ELECTRONICS INC.
+0090E4 NEC AMERICA, INC.
+0090E5 TEKNEMA, INC.
+0090E6 ACER LABORATORIES, INC.
+0090E7 HORSCH ELEKTRONIK AG
+0090E8 MOXA TECHNOLOGIES CORP., LTD.
+0090E9 JANZ COMPUTER AG
+0090EA ALPHA TECHNOLOGIES, INC.
+0090EB SENTRY TELECOM SYSTEMS
+0090EC PYRESCOM
+0090ED CENTRAL SYSTEM RESEARCH
+0090EE PERSONAL COMMUNICATIONS
+0090EF INTEGRIX, INC.
+0090F0 HARMONIC LIGHTWAVES, LTD.
+0090F1 DOT HILL SYSTEMS CORPORATION
+0090F2 CISCO SYSTEMS, INC.
+0090F3 ASPECT COMMUNICATIONS
+0090F4 LIGHTNING INSTRUMENTATION
+0090F5 CLEVO CO.
+0090F6 ESCALATE NETWORKS, INC.
+0090F7 NBASE COMMUNICATIONS LTD.
+0090F8 MEDIATRIX TELECOM
+0090F9 LEITCH
+0090FA GIGANET, INC.
+0090FB PORTWELL, INC.
+0090FC NETWORK COMPUTING DEVICES
+0090FD COPPERCOM, INC.
+0090FE ELECOM CO., LTD.  (LANEED DIV.
+0090FF TELLUS TECHNOLOGY INC.
+009D8E CARDIAC RECORDERS, INC.
+00A000 CENTILLION NETWORKS, INC.
+00A001 WATKINS-JOHNSON COMPANY
+00A002 LEEDS & NORTHRUP AUSTRALIA
+00A003 STAEFA CONTROL SYSTEM
+00A004 NETPOWER, INC.
+00A005 DANIEL INSTRUMENTS, LTD.
+00A006 IMAGE DATA PROCESSING
+00A007 APEXX TECHNOLOGY, INC.
+00A008 NETCORP
+00A009 WHITETREE NETWORK
+00A00A R.D.C. COMMUNICATION
+00A00B COMPUTEX CO., LTD.
+00A00C KINGMAX TECHNOLOGY, INC.
+00A00D THE PANDA PROJECT
+00A00E VISUAL NETWORKS, INC.
+00A00F Broadband Technologies
+00A010 SYSLOGIC DATENTECHNIK AG
+00A011 MUTOH INDUSTRIES LTD.
+00A012 B.A.T.M. ADVANCED TECHNOLOGIES
+00A013 TELTREND LTD.
+00A014 CSIR
+00A015 WYLE
+00A016 MICROPOLIS CORP.
+00A017 J B M CORPORATION
+00A018 CREATIVE CONTROLLERS, INC.
+00A019 NEBULA CONSULTANTS, INC.
+00A01A BINAR ELEKTRONIK AB
+00A01B PREMISYS COMMUNICATIONS, INC.
+00A01C NASCENT NETWORKS CORPORATION
+00A01D SIXNET
+00A01E EST CORPORATION
+00A01F TRICORD SYSTEMS, INC.
+00A020 CITICORP/TTI
+00A021 GENERAL DYNAMICS-
+00A022 CENTRE FOR DEVELOPMENT OF
+00A023 APPLIED CREATIVE TECHNOLOGY,
+00A024 3COM CORPORATION
+00A025 REDCOM LABS INC.
+00A026 TELDAT, S.A.
+00A027 FIREPOWER SYSTEMS, INC.
+00A028 CONNER PERIPHERALS
+00A029 COULTER CORPORATION
+00A02A TRANCELL SYSTEMS
+00A02B TRANSITIONS RESEARCH CORP.
+00A02C INTERWAVE COMMUNICATIONS
+00A02D 1394 Trade Association
+00A02E BRAND COMMUNICATIONS, LTD.
+00A02F PIRELLI CAVI
+00A030 CAPTOR NV/SA
+00A031 HAZELTINE CORPORATION, MS 1-17
+00A032 GES SINGAPORE PTE. LTD.
+00A033 IMC MESS-SYSTEME GMBH
+00A034 AXEL
+00A035 CYLINK CORPORATION
+00A036 APPLIED NETWORK TECHNOLOGY
+00A037 DATASCOPE CORPORATION
+00A038 EMAIL ELECTRONICS
+00A039 ROSS TECHNOLOGY, INC.
+00A03A KUBOTEK CORPORATION
+00A03B TOSHIN ELECTRIC CO., LTD.
+00A03C EG&G NUCLEAR INSTRUMENTS
+00A03D OPTO - 22
+00A03E ATM FORUM
+00A03F COMPUTER SOCIETY MICROPROCES'R
+00A040 APPLE COMPUTER
+00A041 LEYBOLD-INFICON
+00A042 SPUR PRODUCTS CORP.
+00A043 AMERICAN TECHNOLOGY LABS, INC.
+00A044 NTT INTELLIGENT TECHNOLOGY
+00A045 PHOENIX CONTACT GMBH & CO.
+00A046 SCITEX CORP. LTD.
+00A047 INTEGRATED FITNESS CORP.
+00A048 QUESTECH, LTD.
+00A049 DIGITECH INDUSTRIES, INC.
+00A04A NISSHIN ELECTRIC CO., LTD.
+00A04B TFL LAN INC.
+00A04C INNOVATIVE SYSTEMS & TECH. INC
+00A04D EDA INSTRUMENTS, INC.
+00A04E VOELKER TECHNOLOGIES, INC.
+00A04F AMERITEC CORP.
+00A050 CYPRESS SEMICONDUCTOR
+00A051 ANGIA COMMUNICATIONS. INC.
+00A052 STANILITE ELECTRONICS PTY. LTD
+00A053 COMPACT DEVICES, INC.
+00A055 LINKTECH, INC.
+00A056 MICROPROSS
+00A057 ELSA AG
+00A058 GLORY, LTD.
+00A059 HAMILTON HALLMARK
+00A05A KOFAX IMAGE PRODUCTS
+00A05B MARQUIP, INC.
+00A05C INVENTORY CONVERSION, INC./
+00A05D CS COMPUTER SYSTEME GMBH
+00A05E MYRIAD LOGIC INC.
+00A05F BTG ENGINEERING BV
+00A060 ACER PERIPHERALS, INC.
+00A061 PURITAN BENNETT
+00A062 AES PRODATA
+00A063 JRL SYSTEMS, INC.
+00A064 KVB/ANALECT
+00A065 NEXLAND, INC.
+00A066 ISA CO., LTD.
+00A067 NETWORK SERVICES GROUP
+00A068 BHP LIMITED
+00A069 TrueTime
+00A06A VERILINK CORP.
+00A06B DMS DORSCH MIKROSYSTEM GMBH
+00A06C SHINDENGEN ELECTRIC MFG.
+00A06D MANNESMANN TALLY CORPORATION
+00A06E AUSTRON, INC.
+00A06F THE APPCON GROUP, INC.
+00A070 COASTCOM
+00A071 VIDEO LOTTERY TECHNOLOGIES,INC
+00A072 OVATION SYSTEMS LTD.
+00A073 COM21, INC.
+00A074 PERCEPTION TECHNOLOGY
+00A075 MICRON TECHNOLOGY, INC.
+00A076 CARDWARE LAB, INC.
+00A077 FUJITSU NEXION, INC.
+00A078 Marconi Communications
+00A079 ALPS ELECTRIC (USA), INC.
+00A07A ADVANCED PERIPHERALS
+00A07B DAWN COMPUTER INCORPORATION
+00A07C TONYANG NYLON CO., LTD.
+00A07D SEEQ TECHNOLOGY, INC.
+00A07E AVID TECHNOLOGY, INC.
+00A07F GSM-SYNTEL, LTD.
+00A080 ANTARES MICROSYSTEMS
+00A081 ALCATEL DATA NETWORKS
+00A082 NKT ELEKTRONIK A/S
+00A083 ASIMMPHONY TURKEY
+00A084 DATAPLEX PTY. LTD.
+00A086 AMBER WAVE SYSTEMS, INC.
+00A087 MITEL SEMICONDUCTOR, LTD.
+00A088 ESSENTIAL COMMUNICATIONS
+00A089 XPOINT TECHNOLOGIES, INC.
+00A08A BROOKTROUT TECHNOLOGY, INC.
+00A08B ASTON ELECTRONIC DESIGNS LTD.
+00A08C MULTIMEDIA LANS, INC.
+00A08D JACOMO CORPORATION
+00A08E Nokia Internet Communications
+00A08F DESKNET SYSTEMS, INC.
+00A090 TIMESTEP CORPORATION
+00A091 APPLICOM INTERNATIONAL
+00A092 H. BOLLMANN MANUFACTURERS, LTD
+00A093 B/E AEROSPACE
+00A094 COMSAT CORPORATION
+00A095 ACACIA NETWORKS, INC.
+00A096 MITSUMI ELECTRIC CO., LTD.
+00A097 JC INFORMATION SYSTEMS
+00A098 NETWORK APPLIANCE CORP.
+00A099 K-NET LTD.
+00A09A NIHON KOHDEN AMERICA
+00A09B QPSX COMMUNICATIONS, LTD.
+00A09C XYPLEX, INC.
+00A09D JOHNATHON FREEMAN TECHNOLOGIES
+00A09E ICTV
+00A09F COMMVISION CORP.
+00A0A0 COMPACT DATA, LTD.
+00A0A1 EPIC DATA INC.
+00A0A2 DIGICOM S.P.A.
+00A0A3 RELIABLE POWER METERS
+00A0A4 MICROS SYSTEMS, INC.
+00A0A5 TEKNOR MICROSYSTEME, INC.
+00A0A6 M.I. SYSTEMS, K.K.
+00A0A7 VORAX CORPORATION
+00A0A8 RENEX CORPORATION
+00A0A9 GN NETTEST (CANADA) INC.
+00A0AA SPACELABS MEDICAL
+00A0AB NETCS INFORMATIONSTECHNIK GMBH
+00A0AC GILAT SATELLITE NETWORKS, LTD.
+00A0AD MARCONI SPA
+00A0AE NUCOM SYSTEMS, INC.
+00A0AF WMS INDUSTRIES
+00A0B0 I-O DATA DEVICE, INC.
+00A0B1 FIRST VIRTUAL CORPORATION
+00A0B2 SHIMA SEIKI
+00A0B3 ZYKRONIX
+00A0B4 TEXAS MICROSYSTEMS, INC.
+00A0B5 3H TECHNOLOGY
+00A0B6 SANRITZ AUTOMATION CO., LTD.
+00A0B7 CORDANT, INC.
+00A0B8 SYMBIOS LOGIC INC.
+00A0B9 EAGLE TECHNOLOGY, INC.
+00A0BA PATTON ELECTRONICS CO.
+00A0BB HILAN GMBH
+00A0BC VIASAT, INCORPORATED
+00A0BD I-TECH CORP.
+00A0BE INTEGRATED CIRCUIT SYSTEMS,INC
+00A0BF WIRELESS DATA GROUP MOTOROLA
+00A0C0 DIGITAL LINK CORP.
+00A0C1 ORTIVUS MEDICAL AB
+00A0C2 R.A. SYSTEMS CO., LTD.
+00A0C3 UNICOMPUTER GMBH
+00A0C4 CRISTIE ELECTRONICS LTD.
+00A0C5 ZYXEL COMMUNICATION
+00A0C6 QUALCOMM INCORPORATED
+00A0C7 TADIRAN TELECOMMUNICATIONS
+00A0C8 ADTRAN INC.
+00A0C9 INTEL CORPORATION - HF1-06
+00A0CA FUJITSU DENSO LTD.
+00A0CB ARK TELECOMMUNICATIONS, INC.
+00A0CC LITE-ON COMMUNICATIONS, INC.
+00A0CD DR. JOHANNES HEIDENHAIN GMBH
+00A0CE ASTROCOM CORPORATION
+00A0CF SOTAS, INC.
+00A0D0 TEN X TECHNOLOGY, INC.
+00A0D1 INVENTEC CORPORATION
+00A0D2 ALLIED TELESIS INTERNATIONAL
+00A0D3 INSTEM COMPUTER SYSTEMS, LTD.
+00A0D4 RADIOLAN,  INC.
+00A0D5 SIERRA WIRELESS INC.
+00A0D6 SBE, INC.
+00A0D7 KASTEN CHASE APPLIED RESEARCH
+00A0D8 SPECTRA - TEK
+00A0D9 CONVEX COMPUTER CORPORATION
+00A0DA INTEGRATED SYSTEMS
+00A0DB FISHER & PAYKEL PRODUCTION
+00A0DC O.N. ELECTRONIC CO., LTD.
+00A0DD AZONIX CORPORATION
+00A0DE YAMAHA CORPORATION
+00A0DF STS TECHNOLOGIES, INC.
+00A0E0 TENNYSON TECHNOLOGIES PTY LTD
+00A0E1 WESTPORT RESEARCH
+00A0E2 KEISOKU GIKEN CORP.
+00A0E3 XKL SYSTEMS CORP.
+00A0E4 OPTIQUEST
+00A0E5 NHC COMMUNICATIONS
+00A0E6 DIALOGIC CORPORATION
+00A0E7 CENTRAL DATA CORPORATION
+00A0E8 REUTERS HOLDINGS PLC
+00A0E9 ELECTRONIC RETAILING SYSTEMS
+00A0EA ETHERCOM CORP.
+00A0EB FASTCOMM COMMUNICATIONS CORP.
+00A0EC TRANSMITTON LTD.
+00A0ED PRI AUTOMATION
+00A0EE NASHOBA NETWORKS
+00A0EF LUCIDATA LTD.
+00A0F0 TORONTO MICROELECTRONICS INC.
+00A0F1 MTI
+00A0F2 INFOTEK COMMUNICATIONS, INC.
+00A0F3 STAUBLI
+00A0F4 GE
+00A0F5 RADGUARD LTD.
+00A0F6 AUTOGAS SYSTEMS, INC.
+00A0F7 V.I COMPUTER CORP.
+00A0F8 SYMBOL TECHNOLOGIES, INC.
+00A0F9 BINTEC COMMUNICATIONS GMBH
+00A0FA Marconi Communication GmbH
+00A0FB TORAY ENGINEERING CO., LTD.
+00A0FC IMAGE SCIENCES, INC.
+00A0FD SCITEX DIGITAL PRINTING, INC.
+00A0FE BOSTON TECHNOLOGY, INC.
+00A0FF TELLABS OPERATIONS, INC.
+00AA00 INTEL CORPORATION
+00AA01 INTEL CORPORATION
+00AA02 INTEL CORPORATION
+00AA3C OLIVETTI TELECOM SPA (OLTECO)
+00B009 Grass Valley Group
+00B017 InfoGear Technology Corp.
+00B019 Casi-Rusco
+00B01C Westport Technologies
+00B01E Rantic Labs, Inc.
+00B02A ORSYS GmbH
+00B02D ViaGate Technologies, Inc.
+00B03B HiQ Networks
+00B048 Marconi Communications Inc.
+00B04A Cisco Systems, Inc.
+00B052 Intellon Corporation
+00B064 Cisco Systems, Inc.
+00B069 Honewell Oy
+00B06D Jones Futurex Inc.
+00B080 Mannesmann Ipulsys B.V.
+00B086 LocSoft Limited
+00B08E Cisco Systems, Inc.
+00B091 Transmeta Corp.
+00B094 Alaris, Inc.
+00B09A Morrow Technologies Corp.
+00B09D Point Grey Research Inc.
+00B0AC SIAE-Microelettronica S.p.A.
+00B0AE Symmetricom
+00B0B3 Xstreamis PLC
+00B0C2 Cisco Systems, Inc.
+00B0C7 Tellabs Operations, Inc.
+00B0CE TECHNOLOGY RESCUE
+00B0D0 Dell Computer Corp.
+00B0DB Nextcell, Inc.
+00B0DF Reliable Data Technology, Inc.
+00B0E7 British Federal Ltd.
+00B0EC EACEM
+00B0EE Ajile Systems, Inc.
+00B0F0 CALY NETWORKS
+00B0F5 NetWorth Technologies, Inc.
+00BB01 OCTOTHORPE CORP.
+00BBF0 UNGERMANN-BASS INC.
+00C000 LANOPTICS, LTD.
+00C001 DIATEK PATIENT MANAGMENT
+00C002 SERCOMM CORPORATION
+00C003 GLOBALNET COMMUNICATIONS
+00C004 JAPAN BUSINESS COMPUTER CO.LTD
+00C005 LIVINGSTON ENTERPRISES, INC.
+00C006 NIPPON AVIONICS CO., LTD.
+00C007 PINNACLE DATA SYSTEMS, INC.
+00C008 SECO SRL
+00C009 KT TECHNOLOGY (S) PTE LTD
+00C00A MICRO CRAFT
+00C00B NORCONTROL A.S.
+00C00C RELIA TECHNOLGIES
+00C00D ADVANCED LOGIC RESEARCH, INC.
+00C00E PSITECH, INC.
+00C00F QUANTUM SOFTWARE SYSTEMS LTD.
+00C010 HIRAKAWA HEWTECH CORP.
+00C011 INTERACTIVE COMPUTING DEVICES
+00C012 NETSPAN CORPORATION
+00C013 NETRIX
+00C014 TELEMATICS CALABASAS INT'L,INC
+00C015 NEW MEDIA CORPORATION
+00C016 ELECTRONIC THEATRE CONTROLS
+00C017 FORTE NETWORKS
+00C018 LANART CORPORATION
+00C019 LEAP TECHNOLOGY, INC.
+00C01A COROMETRICS MEDICAL SYSTEMS
+00C01B SOCKET COMMUNICATIONS, INC.
+00C01C INTERLINK COMMUNICATIONS LTD.
+00C01D GRAND JUNCTION NETWORKS, INC.
+00C01E LA FRANCAISE DES JEUX
+00C01F S.E.R.C.E.L.
+00C020 ARCO ELECTRONIC, CONTROL LTD.
+00C021 NETEXPRESS
+00C022 LASERMASTER TECHNOLOGIES, INC.
+00C023 TUTANKHAMON ELECTRONICS
+00C024 EDEN SISTEMAS DE COMPUTACAO SA
+00C025 DATAPRODUCTS CORPORATION
+00C026 LANS TECHNOLOGY CO., LTD.
+00C027 CIPHER SYSTEMS, INC.
+00C028 JASCO CORPORATION
+00C029 KABEL RHEYDT AG
+00C02A OHKURA ELECTRIC CO., LTD.
+00C02B GERLOFF GESELLSCHAFT FUR
+00C02C CENTRUM COMMUNICATIONS, INC.
+00C02D FUJI PHOTO FILM CO., LTD.
+00C02E NETWIZ
+00C02F OKUMA CORPORATION
+00C030 INTEGRATED ENGINEERING B. V.
+00C031 DESIGN RESEARCH SYSTEMS, INC.
+00C032 I-CUBED LIMITED
+00C033 TELEBIT COMMUNICATIONS APS
+00C034 TRANSACTION NETWORK
+00C035 QUINTAR COMPANY
+00C036 RAYTECH ELECTRONIC CORP.
+00C037 DYNATEM
+00C038 RASTER IMAGE PROCESSING SYSTEM
+00C039 TDK SEMICONDUCTOR CORPORATION
+00C03A MEN-MIKRO ELEKTRONIK GMBH
+00C03B MULTIACCESS COMPUTING CORP.
+00C03C TOWER TECH S.R.L.
+00C03D WIESEMANN & THEIS GMBH
+00C03E FA. GEBR. HELLER GMBH
+00C03F STORES AUTOMATED SYSTEMS, INC.
+00C040 ECCI
+00C041 DIGITAL TRANSMISSION SYSTEMS
+00C042 DATALUX CORP.
+00C043 STRATACOM
+00C044 EMCOM CORPORATION
+00C045 ISOLATION SYSTEMS, LTD.
+00C046 KEMITRON LTD.
+00C047 UNIMICRO SYSTEMS, INC.
+00C048 BAY TECHNICAL ASSOCIATES
+00C049 U.S. ROBOTICS, INC.
+00C04A GROUP 2000 AG
+00C04B CREATIVE MICROSYSTEMS
+00C04C DEPARTMENT OF FOREIGN AFFAIRS
+00C04D MITEC, INC.
+00C04E COMTROL CORPORATION
+00C04F DELL COMPUTER CORPORATION
+00C050 TOYO DENKI SEIZO K.K.
+00C051 ADVANCED INTEGRATION RESEARCH
+00C052 BURR-BROWN
+00C053 DAVOX CORPORATION
+00C054 NETWORK PERIPHERALS, LTD.
+00C055 MODULAR COMPUTING TECHNOLOGIES
+00C056 SOMELEC
+00C057 MYCO ELECTRONICS
+00C058 DATAEXPERT CORP.
+00C059 NIPPON DENSO CO., LTD.
+00C05A SEMAPHORE COMMUNICATIONS CORP.
+00C05B NETWORKS NORTHWEST, INC.
+00C05C ELONEX PLC
+00C05D L&N TECHNOLOGIES
+00C05E VARI-LITE, INC.
+00C05F FINE-PAL COMPANY LIMITED
+00C060 ID SCANDINAVIA AS
+00C061 SOLECTEK CORPORATION
+00C062 IMPULSE TECHNOLOGY
+00C063 MORNING STAR TECHNOLOGIES, INC
+00C064 GENERAL DATACOMM IND. INC.
+00C065 SCOPE COMMUNICATIONS, INC.
+00C066 DOCUPOINT, INC.
+00C067 UNITED BARCODE INDUSTRIES
+00C068 PHILIP DRAKE ELECTRONICS LTD.
+00C069 ADAPTIVE BROADBAND CORPORATION
+00C06A ZAHNER-ELEKTRIK GMBH & CO. KG
+00C06B OSI PLUS CORPORATION
+00C06C SVEC COMPUTER CORP.
+00C06D BOCA RESEARCH, INC.
+00C06E HAFT TECHNOLOGY, INC.
+00C06F KOMATSU LTD.
+00C070 SECTRA SECURE-TRANSMISSION AB
+00C071 AREANEX COMMUNICATIONS, INC.
+00C072 KNX LTD.
+00C073 XEDIA CORPORATION
+00C074 TOYODA AUTOMATIC LOOM
+00C075 XANTE CORPORATION
+00C076 I-DATA INTERNATIONAL A-S
+00C077 DAEWOO TELECOM LTD.
+00C078 COMPUTER SYSTEMS ENGINEERING
+00C079 FONSYS CO.,LTD.
+00C07A PRIVA B.V.
+00C07B ASCEND COMMUNICATIONS, INC.
+00C07C HIGHTECH INFORMATION
+00C07D RISC DEVELOPMENTS LTD.
+00C07E KUBOTA CORPORATION ELECTRONIC
+00C07F NUPON COMPUTING CORP.
+00C080 NETSTAR, INC.
+00C081 METRODATA LTD.
+00C082 MOORE PRODUCTS CO.
+00C083 TRACE MOUNTAIN PRODUCTS, INC.
+00C084 DATA LINK CORP. LTD.
+00C085 ELECTRONICS FOR IMAGING, INC.
+00C086 THE LYNK CORPORATION
+00C087 UUNET TECHNOLOGIES, INC.
+00C088 EKF ELEKTRONIK GMBH
+00C089 TELINDUS DISTRIBUTION
+00C08A LAUTERBACH DATENTECHNIK GMBH
+00C08B RISQ MODULAR SYSTEMS, INC.
+00C08C PERFORMANCE TECHNOLOGIES, INC.
+00C08D TRONIX PRODUCT DEVELOPMENT
+00C08E NETWORK INFORMATION TECHNOLOGY
+00C08F MATSUSHITA ELECTRIC WORKS, LTD
+00C090 PRAIM S.R.L.
+00C091 JABIL CIRCUIT, INC.
+00C092 MENNEN MEDICAL INC.
+00C093 ALTA RESEARCH CORP.
+00C094 VMX INC.
+00C095 ZNYX
+00C096 TAMURA CORPORATION
+00C097 ARCHIPEL SA
+00C098 CHUNTEX ELECTRONIC CO., LTD.
+00C099 YOSHIKI INDUSTRIAL CO.,LTD.
+00C09A PHOTONICS CORPORATION
+00C09B RELIANCE COMM/TEC, R-TEC
+00C09C TOA ELECTRONIC LTD.
+00C09D DISTRIBUTED SYSTEMS INT'L, INC
+00C09E CACHE COMPUTERS, INC.
+00C09F QUANTA COMPUTER, INC.
+00C0A0 ADVANCE MICRO RESEARCH, INC.
+00C0A1 TOKYO DENSHI SEKEI CO.
+00C0A2 INTERMEDIUM A/S
+00C0A3 DUAL ENTERPRISES CORPORATION
+00C0A4 UNIGRAF OY
+00C0A5 DICKENS DATA SYSTEMS
+00C0A6 EXICOM AUSTRALIA PTY. LTD
+00C0A7 SEEL LTD.
+00C0A8 GVC CORPORATION
+00C0A9 BARRON MCCANN LTD.
+00C0AA SILICON VALLEY COMPUTER
+00C0AB Telco Systems, Inc.
+00C0AC GAMBIT COMPUTER COMMUNICATIONS
+00C0AD MARBEN COMMUNICATION SYSTEMS
+00C0AE TOWERCOM CO. INC. DBA PC HOUSE
+00C0AF TEKLOGIX INC.
+00C0B0 GCC TECHNOLOGIES,INC.
+00C0B1 GENIUS NET CO.
+00C0B2 NORAND CORPORATION
+00C0B3 COMSTAT DATACOMM CORPORATION
+00C0B4 MYSON TECHNOLOGY, INC.
+00C0B5 CORPORATE NETWORK SYSTEMS,INC.
+00C0B6 MERIDIAN DATA, INC.
+00C0B7 AMERICAN POWER CONVERSION CORP
+00C0B8 FRASER'S HILL LTD.
+00C0B9 FUNK SOFTWARE, INC.
+00C0BA NETVANTAGE
+00C0BB FORVAL CREATIVE, INC.
+00C0BC TELECOM AUSTRALIA/CSSC
+00C0BD INEX TECHNOLOGIES, INC.
+00C0BE ALCATEL - SEL
+00C0BF TECHNOLOGY CONCEPTS, LTD.
+00C0C0 SHORE MICROSYSTEMS, INC.
+00C0C1 QUAD/GRAPHICS, INC.
+00C0C2 INFINITE NETWORKS LTD.
+00C0C3 ACUSON COMPUTED SONOGRAPHY
+00C0C4 COMPUTER OPERATIONAL
+00C0C5 SID INFORMATICA
+00C0C6 PERSONAL MEDIA CORP.
+00C0C7 SPARKTRUM MICROSYSTEMS, INC.
+00C0C8 MICRO BYTE PTY. LTD.
+00C0C9 ELSAG BAILEY PROCESS
+00C0CA ALFA, INC.
+00C0CB CONTROL TECHNOLOGY CORPORATION
+00C0CC TELESCIENCES CO SYSTEMS, INC.
+00C0CD COMELTA, S.A.
+00C0CE CEI SYSTEMS & ENGINEERING PTE
+00C0CF IMATRAN VOIMA OY
+00C0D0 RATOC SYSTEM INC.
+00C0D1 COMTREE TECHNOLOGY CORPORATION
+00C0D2 SYNTELLECT, INC.
+00C0D3 OLYMPUS IMAGE SYSTEMS, INC.
+00C0D4 AXON NETWORKS, INC.
+00C0D5 QUANCOM ELECTRONIC GMBH
+00C0D6 J1 SYSTEMS, INC.
+00C0D7 TAIWAN TRADING CENTER DBA
+00C0D8 UNIVERSAL DATA SYSTEMS
+00C0D9 QUINTE NETWORK CONFIDENTIALITY
+00C0DA NICE SYSTEMS LTD.
+00C0DB IPC CORPORATION (PTE) LTD.
+00C0DC EOS TECHNOLOGIES, INC.
+00C0DD QLogic Corporation
+00C0DE ZCOMM, INC.
+00C0DF KYE SYSTEMS CORP.
+00C0E0 DSC COMMUNICATION CORP.
+00C0E1 SONIC SOLUTIONS
+00C0E2 CALCOMP, INC.
+00C0E3 OSITECH COMMUNICATIONS, INC.
+00C0E4 SIEMENS BUILDING
+00C0E5 GESPAC, S.A.
+00C0E6 Verilink Corporation
+00C0E7 FIBERDATA AB
+00C0E8 PLEXCOM, INC.
+00C0E9 OAK SOLUTIONS, LTD.
+00C0EA ARRAY TECHNOLOGY LTD.
+00C0EB SEH COMPUTERTECHNIK GMBH
+00C0EC DAUPHIN TECHNOLOGY
+00C0ED US ARMY ELECTRONIC
+00C0EE KYOCERA CORPORATION
+00C0EF ABIT CORPORATION
+00C0F0 KINGSTON TECHNOLOGY CORP.
+00C0F1 SHINKO ELECTRIC CO., LTD.
+00C0F2 TRANSITION NETWORKS
+00C0F3 NETWORK COMMUNICATIONS CORP.
+00C0F4 INTERLINK SYSTEM CO., LTD.
+00C0F5 METACOMP, INC.
+00C0F6 CELAN TECHNOLOGY INC.
+00C0F7 ENGAGE COMMUNICATION, INC.
+00C0F8 ABOUT COMPUTING INC.
+00C0F9 HARRIS AND JEFFRIES, INC.
+00C0FA CANARY COMMUNICATIONS, INC.
+00C0FB ADVANCED TECHNOLOGY LABS
+00C0FC ELASTIC REALITY, INC.
+00C0FD PROSUM
+00C0FE APTEC COMPUTER SYSTEMS, INC.
+00C0FF DOT HILL SYSTEMS CORPORATION
+00CBBD Cambridge Broadband Ltd.
+00CF1C COMMUNICATION MACHINERY CORP.
+00D000 FERRAN SCIENTIFIC, INC.
+00D001 VST TECHNOLOGIES, INC.
+00D002 DITECH CORPORATION
+00D003 COMDA ENTERPRISES CORP.
+00D004 PENTACOM LTD.
+00D005 ZHS ZEITMANAGEMENTSYSTEME
+00D006 CISCO SYSTEMS, INC.
+00D007 MIC ASSOCIATES, INC.
+00D008 MACTELL CORPORATION
+00D009 HSING TECH. ENTERPRISE CO. LTD
+00D00A LANACCESS TELECOM S.A.
+00D00B RHK TECHNOLOGY, INC.
+00D00C SNIJDER MICRO SYSTEMS
+00D00D MICROMERITICS INSTRUMENT
+00D00E PLURIS, INC.
+00D00F SPEECH DESIGN GMBH
+00D010 CONVERGENT NETWORKS, INC.
+00D011 PRISM VIDEO, INC.
+00D012 GATEWORKS CORP.
+00D013 PRIMEX AEROSPACE COMPANY
+00D014 ROOT, INC.
+00D015 UNIVEX MICROTECHNOLOGY CORP.
+00D016 SCM MICROSYSTEMS, INC.
+00D017 SYNTECH INFORMATION CO., LTD.
+00D018 QWES. COM, INC.
+00D019 DAINIPPON SCREEN CORPORATE
+00D01A URMET SUD S.P.A.
+00D01B MIMAKI ENGINEERING CO., LTD.
+00D01C SBS TECHNOLOGIES,
+00D01D FURUNO ELECTRIC CO., LTD.
+00D01E PINGTEL CORP.
+00D01F CTAM PTY. LTD.
+00D020 AIM SYSTEM, INC.
+00D021 REGENT ELECTRONICS CORP.
+00D022 INCREDIBLE TECHNOLOGIES, INC.
+00D023 INFORTREND TECHNOLOGY, INC.
+00D024 Cognex Corporation
+00D025 XROSSTECH, INC.
+00D026 HIRSCHMANN AUSTRIA GMBH
+00D027 APPLIED AUTOMATION, INC.
+00D028 OMNEON VIDEO NETWORKS
+00D029 WAKEFERN FOOD CORPORATION
+00D02A FLEXION SYSTEMS
+00D02B JETCELL, INC.
+00D02C CAMPBELL SCIENTIFIC, INC.
+00D02D ADEMCO
+00D02E COMMUNICATION AUTOMATION CORP.
+00D02F VLSI TECHNOLOGY INC.
+00D030 SAFETRAN SYSTEMS CORP.
+00D031 INDUSTRIAL LOGIC CORPORATION
+00D032 YANO ELECTRIC CO., LTD.
+00D033 DALIAN DAXIAN NETWORK
+00D034 ORMEC SYSTEMS CORP.
+00D035 BEHAVIOR TECH. COMPUTER CORP.
+00D036 TECHNOLOGY ATLANTA CORP.
+00D037 PHILIPS-DVS-LO BDR
+00D038 FIVEMERE, LTD.
+00D039 UTILICOM, INC.
+00D03A ZONEWORX, INC.
+00D03B VISION PRODUCTS PTY. LTD.
+00D03C Vieo, Inc.
+00D03E ROCKETCHIPS, INC.
+00D03F AMERICAN COMMUNICATION
+00D040 SYSMATE CO., LTD.
+00D041 AMIGO TECHNOLOGY CO., LTD.
+00D042 MAHLO GMBH & CO. UG
+00D043 ZONAL RETAIL DATA SYSTEMS
+00D044 ALIDIAN NETWORKS, INC.
+00D045 KVASER AB
+00D046 DOLBY LABORATORIES, INC.
+00D047 XN TECHNOLOGIES
+00D048 ECTON, INC.
+00D049 IMPRESSTEK CO., LTD.
+00D04A PRESENCE TECHNOLOGY GMBH
+00D04B LA CIE GROUP S.A.
+00D04C EUROTEL TELECOM LTD.
+00D04D DIV OF RESEARCH & STATISTICS
+00D04E LOGIBAG
+00D04F BITRONICS, INC.
+00D050 ISKRATEL
+00D051 O2 MICRO, INC.
+00D052 ASCEND COMMUNICATIONS, INC.
+00D053 CONNECTED SYSTEMS
+00D054 SAS INSTITUTE INC.
+00D055 KATHREIN-WERKE KG
+00D056 SOMAT CORPORATION
+00D057 ULTRAK, INC.
+00D058 CISCO SYSTEMS, INC.
+00D059 AMBIT MICROSYSTEMS CORP.
+00D05A SYMBIONICS, LTD.
+00D05B ACROLOOP MOTION CONTROL
+00D05C TECHNOTREND SYSTEMTECHNIK GMBH
+00D05D INTELLIWORXX, INC.
+00D05E STRATABEAM TECHNOLOGY, INC.
+00D05F VALCOM, INC.
+00D060 PANASONIC EUROPEAN
+00D061 TREMON ENTERPRISES CO., LTD.
+00D062 DIGIGRAM
+00D063 CISCO SYSTEMS, INC.
+00D064 MULTITEL
+00D065 TOKO ELECTRIC
+00D066 WINTRISS ENGINEERING CORP.
+00D067 CAMPIO COMMUNICATIONS
+00D068 IWILL CORPORATION
+00D069 TECHNOLOGIC SYSTEMS
+00D06A LINKUP SYSTEMS CORPORATION
+00D06B SR TELECOM INC.
+00D06C SHAREWAVE, INC.
+00D06D ACRISON, INC.
+00D06E TRENDVIEW RECORDERS LTD.
+00D06F KMC CONTROLS
+00D070 LONG WELL ELECTRONICS CORP.
+00D071 ECHELON CORP.
+00D072 BROADLOGIC
+00D073 ACN ADVANCED COMMUNICATIONS
+00D074 TAQUA SYSTEMS, INC.
+00D075 ALARIS MEDICAL SYSTEMS, INC.
+00D076 MERRILL LYNCH & CO., INC.
+00D077 LUCENT TECHNOLOGIES
+00D078 ELTEX OF SWEDEN AB
+00D079 CISCO SYSTEMS, INC.
+00D07A AMAQUEST COMPUTER CORP.
+00D07B COMCAM INTERNATIONAL LTD.
+00D07C KOYO ELECTRONICS INC. CO.,LTD.
+00D07D COSINE COMMUNICATIONS
+00D07E KEYCORP LTD.
+00D07F STRATEGY & TECHNOLOGY, LIMITED
+00D080 EXABYTE CORPORATION
+00D081 REAL TIME DEVICES USA, INC.
+00D082 IOWAVE INC.
+00D083 INVERTEX, INC.
+00D084 NEXCOMM SYSTEMS, INC.
+00D085 OTIS ELEVATOR COMPANY
+00D086 FOVEON, INC.
+00D087 MICROFIRST INC.
+00D088 MAINSAIL NETWORKS, INC.
+00D089 DYNACOLOR, INC.
+00D08A PHOTRON USA
+00D08B ADVA Limited
+00D08C GENOA TECHNOLOGY, INC.
+00D08D PHOENIX GROUP, INC.
+00D08E NVISION INC.
+00D08F ARDENT TECHNOLOGIES, INC.
+00D090 CISCO SYSTEMS, INC.
+00D091 SMARTSAN SYSTEMS, INC.
+00D092 GLENAYRE WESTERN MULTIPLEX
+00D093 TQ - COMPONENTS GMBH
+00D094 TIMELINE VISTA, INC.
+00D095 XYLAN CORPORATION
+00D096 3COM EUROPE LTD.
+00D097 CISCO SYSTEMS, INC.
+00D098 IPS AUTOMATION
+00D099 ELCARD OY
+00D09A FILANET CORPORATION
+00D09B SPECTEL LTD.
+00D09C KAPADIA COMMUNICATIONS
+00D09D VERIS INDUSTRIES
+00D09E 2WIRE, INC.
+00D09F NOVTEK TEST SYSTEMS
+00D0A0 MIPS DENMARK
+00D0A1 OSKAR VIERLING GMBH + CO. KG
+00D0A2 INTEGRATED DEVICE
+00D0A3 VOCAL DATA, INC.
+00D0A4 ALANTRO COMMUNICATIONS
+00D0A5 AMERICAN ARIUM
+00D0A6 LANBIRD TECHNOLOGY CO., LTD.
+00D0A7 TOKYO SOKKI KENKYUJO CO., LTD.
+00D0A8 NETWORK ENGINES, INC.
+00D0A9 SHINANO KENSHI CO., LTD.
+00D0AA CHASE COMMUNICATIONS
+00D0AB DELTAKABEL TELECOM CV
+00D0AC GRAYSON WIRELESS
+00D0AD TL INDUSTRIES
+00D0AE ORESIS COMMUNICATIONS, INC.
+00D0AF CUTLER-HAMMER, INC.
+00D0B0 BITSWITCH LTD.
+00D0B1 OMEGA ELECTRONICS SA
+00D0B2 XIOTECH CORPORATION
+00D0B3 DRS FLIGHT SAFETY AND
+00D0B4 KATSUJIMA CO., LTD.
+00D0B5 DOTCOM
+00D0B6 CRESCENT NETWORKS, INC.
+00D0B7 INTEL CORPOTATION
+00D0B8 IOMEGA CORP.
+00D0B9 MICROTEK INTERNATIONAL, INC.
+00D0BA CISCO SYSTEMS, INC.
+00D0BB CISCO SYSTEMS, INC.
+00D0BC CISCO SYSTEMS, INC.
+00D0BD SICAN GMBH
+00D0BE EMUTEC INC.
+00D0BF PIVOTAL TECHNOLOGIES
+00D0C0 CISCO SYSTEMS, INC.
+00D0C1 HARMONIC DATA SYSTEMS, LTD.
+00D0C2 BALTHAZAR TECHNOLOGY AB
+00D0C3 VIVID TECHNOLOGY PTE, LTD.
+00D0C4 TERATECH CORPORATION
+00D0C5 COMPUTATIONAL SYSTEMS, INC.
+00D0C6 THOMAS & BETTS CORP.
+00D0C7 PATHWAY, INC.
+00D0C8 I/O CONSULTING A/S
+00D0C9 ADVANTECH CO., LTD.
+00D0CA INTRINSYC SOFTWARE INC.
+00D0CB DASAN CO., LTD.
+00D0CC TECHNOLOGIES LYRE INC.
+00D0CD ATAN TECHNOLOGY INC.
+00D0CE ASYST ELECTRONIC
+00D0CF MORETON BAY
+00D0D0 ZHONGXING TELECOM LTD.
+00D0D1 SIROCCO SYSTEMS, INC.
+00D0D2 EPILOG CORPORATION
+00D0D3 CISCO SYSTEMS, INC.
+00D0D4 V-BITS, INC.
+00D0D5 GRUNDIG AG
+00D0D6 AETHRA TELECOMUNICAZIONI
+00D0D7 B2C2, INC.
+00D0D8 3Com Corporation
+00D0D9 DEDICATED MICROCOMPUTERS
+00D0DA TAICOM DATA SYSTEMS CO., LTD.
+00D0DB MCQUAY INTERNATIONAL
+00D0DC MODULAR MINING SYSTEMS, INC.
+00D0DD SUNRISE TELECOM, INC.
+00D0DE PHILIPS MULTIMEDIA NETWORK
+00D0DF KUZUMI ELECTRONICS, INC.
+00D0E0 DOOIN ELECTRONICS CO.
+00D0E1 AVIONITEK ISRAEL INC.
+00D0E2 MRT MICRO, INC.
+00D0E3 ELE-CHEM ENGINEERING CO., LTD.
+00D0E4 CISCO SYSTEMS, INC.
+00D0E5 SOLIDUM SYSTEMS CORP.
+00D0E6 IBOND INC.
+00D0E7 VCON TELECOMMUNICATION LTD.
+00D0E8 MAC SYSTEM CO., LTD.
+00D0E9 ADVANTAGE CENTURY
+00D0EA NEXTONE COMMUNICATIONS, INC.
+00D0EB LIGHTERA NETWORKS, INC.
+00D0EC NAKAYO TELECOMMUNICATIONS, INC
+00D0ED XIOX
+00D0EE DICTAPHONE CORPORATION
+00D0EF IGT
+00D0F0 CONVISION TECHNOLOGY GMBH
+00D0F1 SEGA ENTERPRISES, LTD.
+00D0F2 MONTEREY NETWORKS
+00D0F3 SOLARI DI UDINE SPA
+00D0F4 CARINTHIAN TECH INSTITUTE
+00D0F5 ORANGE MICRO, INC.
+00D0F6 NORTHCHURCH COMMUNICATIONS INC
+00D0F7 NEXT NETS CORPORATION
+00D0F8 FUJIAN STAR TERMINAL
+00D0F9 ACUTE COMMUNICATIONS CORP.
+00D0FA RACAL GUARDATA
+00D0FB TEK MICROSYSTEMS, INCORPORATED
+00D0FC GRANITE MICROSYSTEMS
+00D0FD OPTIMA TELE.COM, INC.
+00D0FE ASTRAL POINT
+00D0FF CISCO SYSTEMS, INC.
+00DD00 UNGERMANN-BASS INC.
+00DD01 UNGERMANN-BASS INC.
+00DD02 UNGERMANN-BASS INC.
+00DD03 UNGERMANN-BASS INC.
+00DD04 UNGERMANN-BASS INC.
+00DD05 UNGERMANN-BASS INC.
+00DD06 UNGERMANN-BASS INC.
+00DD07 UNGERMANN-BASS INC.
+00DD08 UNGERMANN-BASS INC.
+00DD09 UNGERMANN-BASS INC.
+00DD0A UNGERMANN-BASS INC.
+00DD0B UNGERMANN-BASS INC.
+00DD0C UNGERMANN-BASS INC.
+00DD0D UNGERMANN-BASS INC.
+00DD0E UNGERMANN-BASS INC.
+00DD0F UNGERMANN-BASS INC.
+00E000 FUJITSU, LTD
+00E001 STRAND LIGHTING LIMITED
+00E002 CROSSROADS SYSTEMS, INC.
+00E003 NOKIA WIRELESS BUSINESS COMMUN
+00E004 PMC-SIERRA, INC.
+00E005 TECHNICAL CORP.
+00E006 SILICON INTEGRATED SYS. CORP.
+00E007 NETWORK ALCHEMY LTD.
+00E008 AMAZING CONTROLS! INC.
+00E009 MARATHON TECHNOLOGIES CORP.
+00E00A DIBA, INC.
+00E00B ROOFTOP COMMUNICATIONS CORP.
+00E00C MOTOROLA
+00E00D RADIANT SYSTEMS
+00E00E AVALON IMAGING SYSTEMS, INC.
+00E00F SHANGHAI BAUD DATA
+00E010 HESS SB-AUTOMATENBAU GMBH
+00E011 UNIDEN SAN DIEGO
+00E012 PLUTO TECHNOLOGIES
+00E013 EASTERN ELECTRONIC CO., LTD.
+00E014 CISCO SYSTEMS, INC.
+00E015 HEIWA CORPORATION
+00E016 RAPID CITY COMMUNICATIONS
+00E017 EXXACT GMBH
+00E018 ASUSTEK COMPUTER INC.
+00E019 ING. GIORDANO ELETTRONICA
+00E01A COMTEC SYSTEMS. CO., LTD.
+00E01B SPHERE COMMUNICATIONS, INC.
+00E01C MOBILITY ELECTRONICSY
+00E01D WEBTV NETWORKS, INC.
+00E01E CISCO SYSTEMS, INC.
+00E01F AVIDIA SYSTEMS, INC.
+00E020 TECNOMEN OY
+00E021 FREEGATE CORP.
+00E022 MEDIALIGHT INC.
+00E023 TELRAD
+00E024 GADZOOX NETWORKS
+00E025 DIT CO., LTD.
+00E026 EASTMAN KODAK CO.
+00E027 DUX, INC.
+00E028 APTIX CORPORATION
+00E029 STANDARD MICROSYSTEMS CORP.
+00E02A TANDBERG TELEVISION AS
+00E02B EXTREME NETWORKS
+00E02C AST COMPUTER
+00E02D INNOMEDIALOGIC, INC.
+00E02E SPC ELECTRONICS CORPORATION
+00E02F MCNS HOLDINGS, L.P.
+00E030 MELITA INTERNATIONAL CORP.
+00E031 HAGIWARA ELECTRIC CO., LTD.
+00E032 MISYS FINANCIAL SYSTEMS, LTD.
+00E033 E.E.P.D. GMBH
+00E034 CISCO SYSTEMS, INC.
+00E035 LOUGHBOROUGH SOUND IMAGES, PLC
+00E036 PIONEER CORPORATION
+00E037 CENTURY CORPORATION
+00E038 PROXIMA CORPORATION
+00E039 PARADYNE CORP.
+00E03A CABLETRON SYSTEMS, INC.
+00E03B PROMINET CORPORATION
+00E03C ADVANSYS
+00E03D FOCON ELECTRONIC SYSTEMS A/S
+00E03E ALFATECH, INC.
+00E03F JATON CORPORATION
+00E040 DESKSTATION TECHNOLOGY, INC.
+00E041 CSPI
+00E042 PACOM DATA LTD.
+00E043 VITALCOM
+00E044 LSICS CORPORATION
+00E045 TOUCHWAVE, INC.
+00E046 BENTLY NEVADA CORP.
+00E047 INFOCUS SYSTEMS
+00E048 SDL COMMUNICATIONS, INC.
+00E049 MICROWI ELECTRONIC GMBH
+00E04A ENHANCED MESSAGING SYSTEMS,INC
+00E04B JUMP INDUSTRIELLE
+00E04C REALTEK SEMICONDUCTOR CORP.
+00E04D INTERNET INITIATIVE JAPAN, INC
+00E04E SANYO DENKI CO., LTD.
+00E04F CISCO SYSTEMS, INC.
+00E050 EXECUTONE INFORMATION
+00E051 TALX CORPORATION
+00E052 FOUNDRY NETWORKS, INC.
+00E053 CELLPORT LABS, INC.
+00E054 KODAI HITEC CO., LTD.
+00E055 INGENIERIA ELECTRONICA
+00E056 HOLONTECH CORPORATION
+00E057 HAN MICROTELECOM. CO., LTD.
+00E058 PHASE ONE DENMARK A/S
+00E059 CONTROLLED ENVIRONMENTS, LTD.
+00E05A GALEA NETWORK SECURITY
+00E05B WEST END SYSTEMS CORP.
+00E05C MATSUSHITA KOTOBUKI
+00E05D UNITEC CO., LTD.
+00E05E JAPAN AVIATION ELECTRONICS
+00E05F E-NET, INC.
+00E060 SHERWOOD
+00E061 EDGEPOINT NETWORKS, INC.
+00E062 HOST ENGINEERING
+00E063 CABLETRON - YAGO SYSTEMS, INC.
+00E064 SAMSUNG ELECTRONICS
+00E065 OPTICAL ACCESS INTERNATIONAL
+00E066 PROMAX SYSTEMS, INC.
+00E067 EAC AUTOMATION-CONSULTING GMBH
+00E068 MERRIMAC SYSTEMS INC.
+00E069 JAYCOR NETWORKS, INC.
+00E06A KAPSCH AG
+00E06B W&G SPECIAL PRODUCTS
+00E06C BALTIMORE TECHNOLOGIES, LTD.
+00E06D COMPUWARE CORPORATION
+00E06E FAR SYSTEMS SPA
+00E06F TERAYON CORP.
+00E070 DH TECHNOLOGY
+00E071 EPIS MICROCOMPUTER
+00E072 LYNK
+00E073 NATIONAL AMUSEMENT
+00E074 TIERNAN COMMUNICATIONS, INC.
+00E075 ATLAS COMPUTER EQUIPMENT, INC.
+00E076 DEVELOPMENT CONCEPTS, INC.
+00E077 WEBGEAR, INC.
+00E078 BERKELEY NETWORKS
+00E079 A.T.N.R.
+00E07A MIKRODIDAKT AB
+00E07B BAY NETWORKS
+00E07C METTLER-TOLEDO, INC.
+00E07D NETRONIX, INC.
+00E07E WALT DISNEY IMAGINEERING
+00E07F LOGISTISTEM SRL
+00E080 CONTROL RESOURCES CORPORATION
+00E081 TYAN COMPUTER CORP.
+00E082 ANERMA
+00E083 JATO TECHNOLOGIES, INC.
+00E084 COMPULITE R&D
+00E085 GLOBAL MAINTECH, INC.
+00E086 CYBEX COMPUTER PRODUCTS
+00E087 LECROY
+00E088 LTX CORPORATION
+00E089 ION Networks, Inc.
+00E08A GEC AVERY, LTD.
+00E08B QLOGIC CORP.
+00E08C NEOPARADIGM LABS, INC.
+00E08D PRESSURE SYSTEMS, INC.
+00E08E UTSTARCOM
+00E08F CISCO SYSTEMS, INC.
+00E090 BECKMAN LAB. AUTOMATION DIV.
+00E091 LG ELECTRONICS, INC.
+00E092 ADMTEK INCORPORATED
+00E093 ACKFIN NETWORKS
+00E094 OSAI SRL
+00E095 ADVANCED-VISION TECHNOLGIES
+00E096 SHIMADZU CORPORATION
+00E097 CARRIER ACCESS CORPORATION
+00E098 ABOCOM SYSTEMS, INC.
+00E099 SAMSON AG
+00E09A POSITRON INDUSTRIES, INC.
+00E09B ENGAGE NETWORKS, INC.
+00E09C MII
+00E09D SARNOFF CORPORATION
+00E09E QUANTUM CORPORATION
+00E09F PIXEL VISION
+00E0A0 WILTRON CO.
+00E0A1 HIMA PAUL HILDEBRANDT
+00E0A2 MICROSLATE INC.
+00E0A3 CISCO SYSTEMS, INC.
+00E0A4 ESAOTE S.P.A.
+00E0A5 COMCORE SEMICONDUCTOR, INC.
+00E0A6 TELOGY NETWORKS, INC.
+00E0A7 IPC INFORMATION SYSTEMS, INC.
+00E0A8 SAT GMBH&CO
+00E0A9 FUNAI ELECTRIC CO., LTD.
+00E0AA ELECTROSONIC LTD.
+00E0AB DIMAT S.A.
+00E0AC MIDSCO, INC.
+00E0AD EES TECHNOLOGY, LTD.
+00E0AE XAQTI CORPORATION
+00E0AF GENERAL DYNAMICS INFORMATION
+00E0B0 CISCO SYSTEMS, INC.
+00E0B1 PACKET ENGINES, INC.
+00E0B2 TELMAX COMMUNICATIONS CORP.
+00E0B3 ETHERWAN SYSTEMS, INC.
+00E0B4 TECHNO SCOPE CO., LTD.
+00E0B5 ARDENT COMMUNICATIONS CORP.
+00E0B6 Entrada Networks
+00E0B7 PI GROUP, LTD.
+00E0B8 GATEWAY 2000
+00E0B9 BYAS SYSTEMS
+00E0BA BERGHOF AUTOMATIONSTECHNIK
+00E0BB NBX CORPORATION
+00E0BC SYMON COMMUNICATIONS, INC.
+00E0BD INTERFACE SYSTEMS, INC.
+00E0BE GENROCO INTERNATIONAL, INC.
+00E0BF TORRENT NETWORKING
+00E0C0 SEIWA ERECTRIC MFG. CO., LTD.
+00E0C1 MEMOREX TELEX JAPAN, LTD.
+00E0C2 NECSY SPA
+00E0C3 SAKAI SYSTEM DEVELOPMENT CORP.
+00E0C4 HORNER ELECTRIC, INC.
+00E0C5 BCOM ELECTRONICS INC.
+00E0C6 LINK2IT, L.L.C.
+00E0C7 EUROTECH SRL
+00E0C8 VIRTUAL ACCESS, LTD.
+00E0C9 AUTOMATEDLOGIC CORPORATION
+00E0CA BEST DATA PRODUCTS
+00E0CB RESON, INC.
+00E0CC HERO SYSTEMS, LTD.
+00E0CD SENSIS CORPORATION
+00E0CE ARN
+00E0CF INTEGRATED DEVICE
+00E0D0 NETSPEED, INC.
+00E0D1 TELSIS LIMITED
+00E0D2 VERSANET COMMUNICATIONS, INC.
+00E0D3 DATENTECHNIK GMBH
+00E0D4 EXCELLENT COMPUTER
+00E0D5 ARCXEL TECHNOLOGIES, INC.
+00E0D6 COMPUTER & COMMUNICATION
+00E0D7 SUNSHINE ELECTRONICS, INC.
+00E0D8 LANBIT COMPUTER, INC.
+00E0D9 TAZMO CO., LTD.
+00E0DA ASSURED ACCESS
+00E0DB VIAVIDEO COMMUNICATIONS
+00E0DC NEXWARE CORP.
+00E0DD ZENITH ELECTRONICS CORPORATION
+00E0DE DATAX NV
+00E0DF KE KOMMUNIKATIONS-ELECTRONIK
+00E0E0 SI ELECTRONICS, LTD.
+00E0E1 G2 NETWORKS, ILNC.
+00E0E2 INNOVA CORP.
+00E0E3 SK-ELEKTRONIK GMBH
+00E0E4 FANUC ROBOTICS NORTH AMERICA,
+00E0E5 CINCO NETWORKS, INC.
+00E0E6 INCAA DATACOM B.V.
+00E0E7 RAYTHEON E-SYSTEMS, INC.
+00E0E8 GRETACODER DATA SYSTEMS AG
+00E0E9 DATA LABS, INC.
+00E0EA INNOVAT COMMUNICATIONS, INC.
+00E0EB DIGICOM SYSTEMS, INCORPORATED
+00E0EC CELESTICA INC.
+00E0ED SILICOM, LTD.
+00E0EE MAREL HF
+00E0EF DIONEX
+00E0F0 ABLER TECHNOLOGY, INC.
+00E0F1 THAT CORPORATION
+00E0F2 ARLOTTO COMNET, INC.
+00E0F3 WEBSPRINT COMMUNICATIONS, INC.
+00E0F4 INSIDE TECHNOLOGY A/S
+00E0F5 TELES AG
+00E0F6 DECISION EUROPE
+00E0F7 CISCO SYSTEMS, INC.
+00E0F8 DIANA CONTROL AB
+00E0F9 CISCO SYSTEMS, INC.
+00E0FA TRL TECHNOLOGY, LTD.
+00E0FB LEIGHTRONIX, INC.
+00E0FC HUAWEI TECHNOLOGIES CO., LTD.
+00E0FD A-TREND TECHNOLOGY CO., LTD.
+00E0FE CISCO SYSTEMS, INC.
+00E0FF SECURITY DYNAMICS TECHNOLOGIES
+00E6D3 NIXDORF COMPUTER CORP.
+020701 RACAL-DATACOM
+021C7C PERQ SYSTEMS CORPORATION
+026086 LOGIC REPLACEMENT TECH. LTD.
+02608C 3COM CORPORATION
+027001 RACAL-DATACOM
+0270B0 M/A-COM INC. COMPANIES
+0270B3 DATA RECALL LTD
+029D8E CARDIAC RECORDERS INC.
+02AA3C OLIVETTI TELECOMM SPA (OLTECO)
+02BB01 OCTOTHORPE CORP.
+02C08C 3COM CORPORATION
+02CF1C COMMUNICATION MACHINERY CORP.
+02E6D3 NIXDORF COMPUTER CORPORATION
+040AE0 XMIT AG COMPUTER NETWORKS
+04E0C4 TRIUMPH-ADLER AG
+080001 COMPUTERVISION CORPORATION
+080002 BRIDGE COMMUNICATIONS INC.
+080003 ADVANCED COMPUTER COMM.
+080004 CROMEMCO INCORPORATED
+080005 SYMBOLICS INC.
+080006 SIEMENS AG
+080007 APPLE COMPUTER INC.
+080008 BOLT BERANEK AND NEWMAN INC.
+080009 HEWLETT PACKARD
+08000A NESTAR SYSTEMS INCORPORATED
+08000B UNISYS CORPORATION
+08000C MIKLYN DEVELOPMENT CO.
+08000D INTERNATIONAL COMPUTERS LTD.
+08000E NCR CORPORATION
+08000F MITEL CORPORATION
+080011 TEKTRONIX INC.
+080012 BELL ATLANTIC INTEGRATED SYST.
+080013 EXXON
+080014 EXCELAN
+080015 STC BUSINESS SYSTEMS
+080016 BARRISTER INFO SYS CORP
+080017 NATIONAL SEMICONDUCTOR
+080018 PIRELLI FOCOM NETWORKS
+080019 GENERAL ELECTRIC CORPORATION
+08001A TIARA/ 10NET
+08001B DATA GENERAL
+08001C KDD-KOKUSAI DEBNSIN DENWA CO.
+08001D ABLE COMMUNICATIONS INC.
+08001E APOLLO COMPUTER INC.
+08001F SHARP CORPORATION
+080020 SUN MICROSYSTEMS INC.
+080021 3M COMPANY
+080022 NBI INC.
+080023 MATSUHITA GRAPHIC COMM SYS INC
+080024 10NET COMMUNICATIONS/DCA
+080025 CONTROL DATA
+080026 NORSK DATA A.S.
+080027 CADMUS COMPUTER SYSTEMS
+080028 TEXAS INSTRUMENTS
+080029 MEGATEK CORPORATION
+08002A MOSAIC TECHNOLOGIES INC.
+08002B DIGITAL EQUIPMENT CORPORATION
+08002C BRITTON LEE INC.
+08002D LAN-TEC INC.
+08002E METAPHOR COMPUTER SYSTEMS
+08002F PRIME COMPUTER INC.
+080030 NETWORK RESEARCH CORPORATION
+080030 CERN
+080030 ROYAL MELBOURNE INST OF TECH
+080031 LITTLE MACHINES INC.
+080032 TIGAN INCORPORATED
+080033 BAUSCH & LOMB
+080034 FILENET CORPORATION
+080035 MICROFIVE CORPORATION
+080036 INTERGRAPH CORPORATION
+080037 FUJI-XEROX CO. LTD.
+080038 CII HONEYWELL BULL
+080039 SPIDER SYSTEMS LIMITED
+08003A ORCATECH INC.
+08003B TORUS SYSTEMS LIMITED
+08003C SCHLUMBERGER WELL SERVICES
+08003D CADNETIX CORPORATIONS
+08003E CODEX CORPORATION
+08003F FRED KOSCHARA ENTERPRISES
+080040 FERRANTI COMPUTER SYS. LIMITED
+080041 RACAL-MILGO INFORMATION SYS..
+080042 JAPAN MACNICS CORP.
+080043 PIXEL COMPUTER INC.
+080044 DAVID SYSTEMS INC.
+080045 CONCURRENT COMPUTER CORP.
+080046 SONY CORPORATION LTD.
+080047 SEQUENT COMPUTER SYSTEMS INC.
+080048 EUROTHERM GAUGING SYSTEMS
+080049 UNIVATION
+08004A BANYAN SYSTEMS INC.
+08004B PLANNING RESEARCH CORP.
+08004C HYDRA COMPUTER SYSTEMS INC.
+08004D CORVUS SYSTEMS INC.
+08004E 3COM EUROPE LTD.
+08004F CYGNET SYSTEMS
+080050 DAISY SYSTEMS CORP.
+080051 EXPERDATA
+080052 INSYSTEC
+080053 MIDDLE EAST TECH. UNIVERSITY
+080055 STANFORD TELECOMM. INC.
+080056 STANFORD LINEAR ACCEL. CENTER
+080057 EVANS & SUTHERLAND
+080058 SYSTEMS CONCEPTS
+080059 A/S MYCRON
+08005A IBM CORPORATION
+08005B VTA TECHNOLOGIES INC.
+08005C FOUR PHASE SYSTEMS
+08005D GOULD INC.
+08005E COUNTERPOINT COMPUTER INC.
+08005F SABER TECHNOLOGY CORP.
+080060 INDUSTRIAL NETWORKING INC.
+080061 JAROGATE LTD.
+080062 GENERAL DYNAMICS
+080063 PLESSEY
+080064 AUTOPHON AG
+080065 GENRAD INC.
+080066 AGFA CORPORATION
+080067 COMDESIGN
+080068 RIDGE COMPUTERS
+080069 SILICON GRAPHICS INC.
+08006A ATT BELL LABORATORIES
+08006B ACCEL TECHNOLOGIES INC.
+08006C SUNTEK TECHNOLOGY INT'L
+08006D WHITECHAPEL COMPUTER WORKS
+08006E MASSCOMP
+08006F PHILIPS APELDOORN B.V.
+080070 MITSUBISHI ELECTRIC CORP.
+080071 MATRA (DSIE)
+080072 XEROX CORP UNIV GRANT PROGRAM
+080073 TECMAR INC.
+080074 CASIO COMPUTER CO. LTD.
+080075 DANSK DATA ELECTRONIK
+080076 PC LAN TECHNOLOGIES
+080077 TSL COMMUNICATIONS LTD.
+080078 ACCELL CORPORATION
+080079 THE DROID WORKS
+08007A INDATA
+08007B SANYO ELECTRIC CO. LTD.
+08007C VITALINK COMMUNICATIONS CORP.
+08007E AMALGAMATED WIRELESS(AUS) LTD
+08007F CARNEGIE-MELLON UNIVERSITY
+080080 AES DATA INC.
+080081 ,ASTECH INC.
+080082 VERITAS SOFTWARE
+080083 SEIKO INSTRUM. AND ELECTRONICS
+080084 TOMEN ELECTRONICS CORP.
+080085 ELXSI
+080086 IMAGEN CORPORATION
+080087 XYPLEX
+080088 MCDATA CORPORATION
+080089 KINETICS
+08008A PERFORMANCE TECHNOLOGY
+08008B PYRAMID TECHNOLOGY CORP.
+08008C NETWORK RESEARCH CORPORATION
+08008D XYVISION INC.
+08008E TANDEM COMPUTERS
+08008F CHIPCOM CORPORATION
+080090 SONOMA SYSTEMS
+08BBCC AK-NORD EDV VERTRIEBSGES. MBH
+10005A IBM CORPORATION
+1000E8 NATIONAL SEMICONDUCTOR
+800010 ATT BELL LABORATORIES
+A06A00 Verilink Corporation
+AA0000 DIGITAL EQUIPMENT CORPORATION
+AA0001 DIGITAL EQUIPMENT CORPORATION
+AA0002 DIGITAL EQUIPMENT CORPORATION
+AA0003 DIGITAL EQUIPMENT CORPORATION
+AA0004 DIGITAL EQUIPMENT CORPORATION
diff -urN linux-2.4.22-pre2/drivers/ieee1394/oui2c.sh linux-2.4.22-pre3/drivers/ieee1394/oui2c.sh
--- linux-2.4.22-pre2/drivers/ieee1394/oui2c.sh	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/drivers/ieee1394/oui2c.sh	2003-07-05 18:10:00.000000000 -0700
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+cat <<EOF
+/* Generated file for OUI database */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_IEEE1394_OUI_DB
+struct oui_list_struct {
+	int oui;
+	char *name;
+} oui_list[] = {
+EOF
+
+while read oui name; do
+	echo "	{ 0x$oui, \"$name\" },"
+done
+
+cat <<EOF
+};
+
+#endif /* CONFIG_IEEE1394_OUI_DB */
+EOF
diff -urN linux-2.4.22-pre2/drivers/ieee1394/raw1394.c linux-2.4.22-pre3/drivers/ieee1394/raw1394.c
--- linux-2.4.22-pre2/drivers/ieee1394/raw1394.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/raw1394.c	2003-07-05 18:10:01.000000000 -0700
@@ -44,11 +44,11 @@
 #include "ieee1394.h"
 #include "ieee1394_types.h"
 #include "ieee1394_core.h"
+#include "nodemgr.h"
 #include "hosts.h"
 #include "highlevel.h"
 #include "iso.h"
 #include "ieee1394_transactions.h"
-#include "ieee1394_hotplug.h"
 #include "raw1394.h"
 #include "raw1394-private.h"
 
@@ -602,7 +602,7 @@
                 if (fi->listen_channels & (1ULL << channel)) {
                         req->req.error = RAW1394_ERROR_ALREADY;
                 } else {
-                        if(hpsb_listen_channel(&raw1394_highlevel, fi->host, channel)) {
+                        if (hpsb_listen_channel(&raw1394_highlevel, fi->host, channel)) {
 				req->req.error = RAW1394_ERROR_ALREADY;
 			} else {
 				fi->listen_channels |= 1ULL << channel;
@@ -2009,7 +2009,7 @@
 
 	list_for_each(lh, &fi->req_complete) {
 		req = list_entry(lh, struct pending_request, list);
-		if(req->req.type == RAW1394_REQ_RAWISO_ACTIVITY) {
+		if (req->req.type == RAW1394_REQ_RAWISO_ACTIVITY) {
 			return 1;
 		}
 	}
@@ -2025,17 +2025,17 @@
 	spin_lock_irqsave(&fi->reqlists_lock, flags);
 
 	/* only one ISO activity event may be in the queue */
-	if(!__rawiso_event_in_queue(fi)) {
+	if (!__rawiso_event_in_queue(fi)) {
 		struct pending_request *req = __alloc_pending_request(SLAB_ATOMIC);
 
-		if(req) {
+		if (req) {
 			req->file_info = fi;
 			req->req.type = RAW1394_REQ_RAWISO_ACTIVITY;
 			req->req.generation = get_hpsb_generation(fi->host);
 			__queue_complete_req(req);
 		} else {
 			/* on allocation failure, signal an overflow */
-			if(fi->iso_handle) {
+			if (fi->iso_handle) {
 				atomic_inc(&fi->iso_handle->overflows);
 			}
 		}
@@ -2055,7 +2055,7 @@
 	if (hi != NULL) {
 		list_for_each(lh, &hi->file_info_list) {
 			struct file_info *fi = list_entry(lh, struct file_info, list);
-			if(fi->iso_handle == iso)
+			if (fi->iso_handle == iso)
 				queue_rawiso_event(fi);
 		}
 	}
@@ -2080,7 +2080,7 @@
 {
 	struct raw1394_iso_status stat;
 
-	if(copy_from_user(&stat, uaddr, sizeof(stat)))
+	if (copy_from_user(&stat, uaddr, sizeof(stat)))
 		return -EFAULT;
 
 	fi->iso_handle = hpsb_iso_xmit_init(fi->host,
@@ -2090,13 +2090,13 @@
 					    stat.config.speed,
 					    stat.config.irq_interval,
 					    rawiso_activity_cb);
-	if(!fi->iso_handle)
+	if (!fi->iso_handle)
 		return -ENOMEM;
 
 	fi->iso_state = RAW1394_ISO_XMIT;
 
 	raw1394_iso_fill_status(fi->iso_handle, &stat);
-	if(copy_to_user(uaddr, &stat, sizeof(stat)))
+	if (copy_to_user(uaddr, &stat, sizeof(stat)))
 		return -EFAULT;
 
 	/* queue an event to get things started */
@@ -2109,7 +2109,7 @@
 {
 	struct raw1394_iso_status stat;
 
-	if(copy_from_user(&stat, uaddr, sizeof(stat)))
+	if (copy_from_user(&stat, uaddr, sizeof(stat)))
 		return -EFAULT;
 
 	fi->iso_handle = hpsb_iso_recv_init(fi->host,
@@ -2118,13 +2118,13 @@
 					    stat.config.channel,
 					    stat.config.irq_interval,
 					    rawiso_activity_cb);
-	if(!fi->iso_handle)
+	if (!fi->iso_handle)
 		return -ENOMEM;
 
 	fi->iso_state = RAW1394_ISO_RECV;
 
 	raw1394_iso_fill_status(fi->iso_handle, &stat);
-	if(copy_to_user(uaddr, &stat, sizeof(stat)))
+	if (copy_to_user(uaddr, &stat, sizeof(stat)))
 		return -EFAULT;
 	return 0;
 }
@@ -2135,7 +2135,7 @@
 	struct hpsb_iso *iso = fi->iso_handle;
 
 	raw1394_iso_fill_status(fi->iso_handle, &stat);
-	if(copy_to_user(uaddr, &stat, sizeof(stat)))
+	if (copy_to_user(uaddr, &stat, sizeof(stat)))
 		return -EFAULT;
 
 	/* reset overflow counter */
@@ -2151,20 +2151,20 @@
 	unsigned int packet = fi->iso_handle->first_packet;
 	int i;
 
-	if(copy_from_user(&upackets, uaddr, sizeof(upackets)))
+	if (copy_from_user(&upackets, uaddr, sizeof(upackets)))
 		return -EFAULT;
 
-	if(upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle))
+	if (upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle))
 		return -EINVAL;
 
 	/* ensure user-supplied buffer is accessible and big enough */
-	if(verify_area(VERIFY_WRITE, upackets.infos,
+	if (verify_area(VERIFY_WRITE, upackets.infos,
 		       upackets.n_packets * sizeof(struct raw1394_iso_packet_info)))
 		return -EFAULT;
 
 	/* copy the packet_infos out */
-	for(i = 0; i < upackets.n_packets; i++) {
-		if(__copy_to_user(&upackets.infos[i],
+	for (i = 0; i < upackets.n_packets; i++) {
+		if (__copy_to_user(&upackets.infos[i],
 				  &fi->iso_handle->infos[packet],
 				  sizeof(struct raw1394_iso_packet_info)))
 			return -EFAULT;
@@ -2181,28 +2181,28 @@
 	struct raw1394_iso_packets upackets;
 	int i, rv;
 
-	if(copy_from_user(&upackets, uaddr, sizeof(upackets)))
+	if (copy_from_user(&upackets, uaddr, sizeof(upackets)))
 		return -EFAULT;
 
-	if(upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle))
+	if (upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle))
 		return -EINVAL;
 
 	/* ensure user-supplied buffer is accessible and big enough */
-	if(verify_area(VERIFY_READ, upackets.infos,
+	if (verify_area(VERIFY_READ, upackets.infos,
 		       upackets.n_packets * sizeof(struct raw1394_iso_packet_info)))
 		return -EFAULT;
 
 	/* copy the infos structs in and queue the packets */
-	for(i = 0; i < upackets.n_packets; i++) {
+	for (i = 0; i < upackets.n_packets; i++) {
 		struct raw1394_iso_packet_info info;
 
-		if(__copy_from_user(&info, &upackets.infos[i],
+		if (__copy_from_user(&info, &upackets.infos[i],
 				    sizeof(struct raw1394_iso_packet_info)))
 			return -EFAULT;
 
 		rv = hpsb_iso_xmit_queue_packet(fi->iso_handle, info.offset,
 						info.len, info.tag, info.sy);
-		if(rv)
+		if (rv)
 			return rv;
 	}
 
@@ -2211,7 +2211,7 @@
 
 static void raw1394_iso_shutdown(struct file_info *fi)
 {
-	if(fi->iso_handle)
+	if (fi->iso_handle)
 		hpsb_iso_shutdown(fi->iso_handle);
 
 	fi->iso_handle = NULL;
@@ -2223,7 +2223,7 @@
 {
 	struct file_info *fi = file->private_data;
 
-	if(fi->iso_state == RAW1394_ISO_INACTIVE)
+	if (fi->iso_state == RAW1394_ISO_INACTIVE)
 		return -EINVAL;
 
 	return dma_region_mmap(&fi->iso_handle->data_buf, file, vma);
@@ -2250,7 +2250,7 @@
 		case RAW1394_IOC_ISO_RECV_START: {
 			/* copy args from user-space */
 			int args[3];
-			if(copy_from_user(&args[0], (void*) arg, sizeof(args)))
+			if (copy_from_user(&args[0], (void*) arg, sizeof(args)))
 				return -EFAULT;
 			return hpsb_iso_recv_start(fi->iso_handle, args[0], args[1], args[2]);
 		}
@@ -2264,7 +2264,7 @@
 		case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK: {
 			/* copy the u64 from user-space */
 			u64 mask;
-			if(copy_from_user(&mask, (void*) arg, sizeof(mask)))
+			if (copy_from_user(&mask, (void*) arg, sizeof(mask)))
 				return -EFAULT;
 			return hpsb_iso_recv_set_channel_mask(fi->iso_handle, mask);
 		}
@@ -2287,7 +2287,7 @@
 		case RAW1394_IOC_ISO_XMIT_START: {
 			/* copy two ints from user-space */
 			int args[2];
-			if(copy_from_user(&args[0], (void*) arg, sizeof(args)))
+			if (copy_from_user(&args[0], (void*) arg, sizeof(args)))
 				return -EFAULT;
 			return hpsb_iso_xmit_start(fi->iso_handle, args[0], args[1]);
 		}
@@ -2375,7 +2375,7 @@
         struct arm_addr  *arm_addr = NULL;
         int another_host;
 
-	if(fi->iso_state != RAW1394_ISO_INACTIVE)
+	if (fi->iso_state != RAW1394_ISO_INACTIVE)
 		raw1394_iso_shutdown(fi);
 
         for (i = 0; i < 64; i++) {
diff -urN linux-2.4.22-pre2/drivers/ieee1394/sbp2.c linux-2.4.22-pre3/drivers/ieee1394/sbp2.c
--- linux-2.4.22-pre2/drivers/ieee1394/sbp2.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/sbp2.c	2003-07-05 18:10:02.000000000 -0700
@@ -4,6 +4,8 @@
  * Copyright (C) 2000 James Goodwin, Filanet Corporation (www.filanet.com)
  * jamesg@filanet.com (JSG)
  *
+ * Copyright (C) 2003 Ben Collins <bcollins@debian.org>
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -27,283 +29,17 @@
  * driver. It also registers as a SCSI lower-level driver in order to accept
  * SCSI commands for transport using SBP-2.
  *
- *
- * Driver Loading:
- *
- * Currently, the SBP-2 driver is supported only as a module. Because the 
- * Linux SCSI stack is not Plug-N-Play aware, module load order is 
- * important. Assuming the SCSI core drivers are either built into the 
- * kernel or already loaded as modules, you should load the IEEE-1394 modules 
- * in the following order:
- *
- * 	ieee1394 (e.g. insmod ieee1394)
- *	ohci1394 (e.g. insmod ohci1394)
- *	sbp2 (e.g. insmod sbp2)
- *
- * The SBP-2 driver will attempt to discover any attached SBP-2 devices when first
- * loaded, or after any IEEE-1394 bus reset (e.g. a hot-plug). It will then print 
- * out a debug message indicating if it was able to discover a SBP-2 device.
- *
- * Currently, the SBP-2 driver will catch any attached SBP-2 devices during the
- * initial scsi bus scan (when the driver is first loaded). To add or remove
- * SBP-2 devices "after" this initial scan (i.e. if you plug-in or un-plug a 
- * device after the SBP-2 driver is loaded), you must either use the scsi procfs
- * add-single-device, remove-single-device, or a shell script such as 
- * rescan-scsi-bus.sh.
- *
  * The easiest way to add/detect new SBP-2 devices is to run the shell script
- * rescan-scsi-bus.sh (or re-load the SBP-2 driver). This script may be 
- * found at:
+ * rescan-scsi-bus.sh. This script may be found at:
  * http://www.garloff.de/kurt/linux/rescan-scsi-bus.sh
  *
- * As an alternative, you may manually add/remove SBP-2 devices via the procfs with
- * add-single-device <h> <b> <t> <l> or remove-single-device <h> <b> <t> <l>, where:
- *	<h> = host (starting at zero for first SCSI adapter)
- *	<b> = bus (normally zero)
- *	<t> = target (starting at zero for first SBP-2 device)
- *	<l> = lun (normally zero)
- *
- * e.g. To manually add/detect a new SBP-2 device
- *	echo "scsi add-single-device 0 0 0 0" > /proc/scsi/scsi
- *
- * e.g. To manually remove a SBP-2 device after it's been unplugged
- *	echo "scsi remove-single-device 0 0 0 0" > /proc/scsi/scsi
- *
- * e.g. To check to see which SBP-2/SCSI devices are currently registered
- * 	cat /proc/scsi/scsi
- *
- * After scanning for new SCSI devices (above), you may access any attached 
- * SBP-2 storage devices as if they were SCSI devices (e.g. mount /dev/sda1, 
- * fdisk, mkfs, etc.).
- *
- *
- * Module Load Options:
- *
- * sbp2_max_speed 		- Force max speed allowed 
- *				  (2 = 400mb, 1 = 200mb, 0 = 100mb. default = 2)
- * sbp2_serialize_io		- Serialize all I/O coming down from the scsi drivers 
- *				  (0 = deserialized, 1 = serialized, default = 0)
- * sbp2_max_sectors, 		- Change max sectors per I/O supported (default = 255)
- * sbp2_exclusive_login		- Set to zero if you'd like to allow multiple hosts the ability
- *				  to log in at the same time. Sbp2 device must support this,
- *				  and you must know what you're doing (default = 1)
- *
- * (e.g. insmod sbp2 sbp2_serialize_io = 1)
- *
- *
- * Current Support:
- *
- * The SBP-2 driver is still in an early state, but supports a variety of devices.
- * I have read/written many gigabytes of data from/to SBP-2 drives, and have seen 
- * performance of more than 25 MBytes/s on individual drives (limit of the media 
- * transfer rate).
- *
- *
- * Following are a sampling of devices that have been tested successfully:
- *
- *	- Western Digital IEEE-1394 hard drives
- *	- Maxtor IEEE-1394 hard drives
- *	- VST (SmartDisk) IEEE-1394 hard drives and Zip drives (several flavors)
- *	- LaCie IEEE-1394 hard drives (several flavors)
- *	- QPS IEEE-1394 CD-RW/DVD drives and hard drives
- *	- BusLink IEEE-1394 hard drives
- *	- Iomega IEEE-1394 Zip/Jazz/Peerless drives
- *	- ClubMac IEEE-1394 hard drives
- *	- FirePower IEEE-1394 hard drives
- *	- EzQuest IEEE-1394 hard drives and CD-RW drives
- *	- Castlewood/ADS IEEE-1394 ORB drives
- *	- Evergreen IEEE-1394 hard drives and CD-RW drives
- *	- Addonics IEEE-1394 CD-RW drives
- *	- Bellstor IEEE-1394 hard drives and CD-RW drives
- *	- APDrives IEEE-1394 hard drives
- *	- Fujitsu IEEE-1394 MO drives
- *	- Sony IEEE-1394 CD-RW drives
- *	- Epson IEEE-1394 scanners
- *	- ADS IEEE-1394 memory stick and compact flash readers 
- *	- SBP-2 bridge-based devices (LSI, Oxford Semiconductor, Indigita bridges)
- *	- Various other standard IEEE-1394 hard drives and enclosures
- *
- *
- * Performance Issues:
- *
- *	- Make sure you are "not" running fat/fat32 on your attached SBP-2 drives. You'll
- *	  get much better performance formatting the drive ext2 (but you will lose the
- *	  ability to easily move the drive between Windows/Linux).
- *
+ * You may access any attached SBP-2 storage devices as if they were SCSI
+ * devices (e.g. mount /dev/sda1,  fdisk, mkfs, etc.).
  *
  * Current Issues:
  *
  *	- Error Handling: SCSI aborts and bus reset requests are handled somewhat
  *	  but the code needs additional debugging.
- *
- *	- Module: The SBP-2 driver is currently only supported as a module. It would not take
- *	  much work to allow it to be compiled into the kernel, but you'd have to 
- *	  add some init code to the kernel to support this... and modules are much
- *	  more flexible anyway.   ;-)
- *
- *	- Hot-plugging: Interaction with the SCSI stack and support for hot-plugging could
- *	  stand some improvement.
- *
- *
- * History:
- *
- *	07/25/00 - Initial revision (JSG)
- *	08/11/00 - Following changes/bug fixes were made (JSG):
- *		   * Bug fix to SCSI procfs code (still needs to be synched with 2.4 kernel).
- *		   * Bug fix where request sense commands were actually sent on the bus.
- *		   * Changed bus reset/abort code to deal with devices that spin up quite
- *		     slowly (which result in SCSI time-outs).
- *		   * "More" properly pull information from device's config rom, for enumeration
- *		     of SBP-2 devices, and determining SBP-2 register offsets.
- *		   * Change Simplified Direct Access Device type to Direct Access Device type in
- *		     returned inquiry data, in order to make the SCSI stack happy.
- *		   * Modified driver to register with the SCSI stack "before" enumerating any attached
- *		     SBP-2 devices. This means that you'll have to use procfs scsi-add-device or 
- *		     some sort of script to discover new SBP-2 devices.
- *		   * Minor re-write of some code and other minor changes.
- *	08/28/00 - Following changes/bug fixes were made (JSG):
- *		   * Bug fixes to scatter/gather support (case of one s/g element)
- *		   * Updated direction table for scsi commands (mostly DVD commands)
- *		   * Retries when trying to detect SBP-2 devices (for slow devices)
- *		   * Slightly better error handling (previously none) when commands time-out.
- *		   * Misc. other bug fixes and code reorganization.
- *	09/13/00 - Following changes/bug fixes were made (JSG)
- *		   * Moved detection/enumeration code to a kernel thread which is woken up when IEEE-1394
- *		     bus resets occur.
- *		   * Added code to handle bus resets and hot-plugging while devices are mounted, but full
- *		     hot-plug support is not quite there yet.
- *		   * Now use speed map to determine speed and max payload sizes for ORBs
- *		   * Clean-up of code and reorganization 
- *	09/19/00 - Added better hot-plug support and other minor changes (JSG)
- *	10/15/00 - Fixes for latest 2.4.0 test kernel, minor fix for hot-plug race. (JSG)
- *	12/03/00 - Created pool of request packet structures for use in sending out sbp2 command
- *		   and agent reset requests. This removes the kmallocs/kfrees in the critical I/O paths,
- *		   and also deals with some subtle race conditions related to allocating and freeing
- *		   packets. (JSG)
- *      12/09/00 - Improved the sbp2 device detection by actually reading the root and unit 
- *		   directory (khk@khk.net)
- *	12/23/00 - Following changes/enhancements were made (JSG)
- *		   * Only do SCSI to RBC command conversion for Direct Access and Simplified
- *		     Direct Access Devices (this is pulled from the config rom root directory).
- *		     This is needed because doing the conversion for all device types broke the
- *		     Epson scanner. Still looking for a better way of determining when to convert
- *		     commands (for RBC devices). Thanks to khk for helping on this!
- *		   * Added ability to "emulate" physical dma support, for host adapters such as TILynx.
- *		   * Determine max payload and speed by also looking at the host adapter's max_rec field.
- *	01/19/01 - Added checks to sbp2 login and made the login time-out longer. Also fixed a compile 
- *		   problem for 2.4.0. (JSG)
- *	01/24/01 - Fixed problem when individual s/g elements are 64KB or larger. Needed to break
- *		   up these larger elements, since the sbp2 page table element size is only 16 bits. (JSG)
- *	01/29/01 - Minor byteswap fix for login response (used for reconnect and log out).
- *	03/07/01 - Following changes/enhancements were made (JSG)
- *		   * Changes to allow us to catch the initial scsi bus scan (for detecting sbp2
- *		     devices when first loading sbp2.o). To disable this, un-define 
- *		     SBP2_SUPPORT_INITIAL_BUS_SCAN.
- *		   * Temporary fix to deal with many sbp2 devices that do not support individual
- *		     transfers of greater than 128KB in size. 
- *		   * Mode sense conversion from 6 byte to 10 byte versions for CDRW/DVD devices. (Mark Burton)
- *		   * Define allowing support for goofy sbp2 devices that do not support mode
- *		     sense command at all, allowing them to be mounted rw (such as 1394 memory
- *		     stick and compact flash readers). Define SBP2_MODE_SENSE_WRITE_PROTECT_HACK
- *		     if you need this fix.
- *	03/29/01 - Major performance enhancements and misc. other changes. Thanks to Daniel Berlin for many of
- *		   changes and suggestions for change:
- *		   * Now use sbp2 doorbell and link commands on the fly (instead of serializing requests)
- *		   * Removed all bit fields in an attempt to run on PPC machines (still needs a little more work)
- *		   * Added large request break-up/linking support for sbp2 chipsets that do not support transfers 
- *		     greater than 128KB in size.
- *		   * Bumped up max commands per lun to two, and max total outstanding commands to eight.
- *	04/03/01 - Minor clean-up. Write orb pointer directly if no outstanding commands (saves one 1394 bus
- *		   transaction). Added module load options (bus scan, mode sense hack, max speed, serialize_io,
- *		   no_large_transfers). Better bus reset handling while I/O pending. Set serialize_io to 1 by 
- *		   default (debugging of deserialized I/O in progress).
- *	04/04/01 - Added workaround for PPC Pismo firewire chipset. See #define below. (Daniel Berlin)
- *	04/20/01 - Minor clean-up. Allocate more orb structures when running with sbp2 target chipsets with
- *		   128KB max transfer limit.
- *	06/16/01 - Converted DMA interfaces to pci_dma - Ben Collins
- *							 <bcollins@debian.org
- *	07/22/01 - Use NodeMngr to get info about the local host and
- *		   attached devices. Ben Collins
- *
- *      09/15/01 - Remove detection code, instead subscribe to the nodemgr
- *                 driver management interface.  This also removes the
- *                 initial bus scan stuff since the nodemgr calls
- *                 sbp2_probe for each sbp2 device already on the bus,
- *                 when we register our driver.  This change 
- *                 automtically adds hotplug support to the driver.
- *                                 Kristian Hogsberg <hogsberg@users.sf.net>
- *
- *      11/17/01 - Various bugfixes/cleanups:
- *                 * Remember to logout of device in sbp2_disconnect.
- *                 * If we fail to reconnect to a device after bus reset
- *                   remember to release unit directory, so the ieee1394
- *                   knows we no longer manage it.
- *                 * Unregister scsi hosts in sbp2_remove_host when a
- *                   hpsb_host goes away.
- *                 * Remove stupid hack in sbp2_remove_host.
- *                 * Switched to "manual" module initialization
- *                   (i.e. not scsi_module.c) and moved sbp2_cleanup
- *                   moved sbp2scsi_release to sbp2_module_ext.  The
- *                   release function is called once pr. registered
- *                   scsi host, but sbp2_cleanup should only be called
- *                   upon module unload.  Moved much initialization
- *                   from sbp2scsi_detect to sbp2_module_init.
- *                                 Kristian Hogsberg <hogsberg@users.sf.net>
- *	01/06/02 - Misc bug fixes/enhancements:	(JSG)
- *		   * Enable use_new_eh_code for scsi stuff.
- *		   * Do not write all ones for NULL ORB high/low fields, but
- *		     rather leave reserved areas zeroed (per SBP2 spec).
- *		   * Use newer scsi transfer direction passed down instead of our
- *		     direction table.
- *		   * Bumped login time-out to 20 seconds, as some devices are slow.
- *		   * Fixed a couple scsi unregister bugs on module unload
- *	01/13/02 - Fixed compatibility with certain SBP2 devices, such as Iomega
- *		   1394 devices (Peerless, Jazz). Also a bit of clean-up of the 
- *		   driver, thanks to H.J.Lu (hjl@lucon.org). Removed mode_sense_hack
- *		   module load option, as it's been fixed in the 2.4 scsi stack.
- *	02/10/02 - Added support for max_sectors, minor fix for inquiry command, make
- *		   up sbp2 device type from inquiry response data if not part of 
- *		   device's 1394 unit directory. (JSG)
- *	02/18/02 - Code clean-up and enhancements: (JSG)
- *		   * Finish cleaning out hacked code for dealing with broken sbp2 devices
- *		     which do not support requests of 128KB or greater. Now use 
- *		     max_sectors scsi host entry to limit transfer sizes.
- *		   * Change status fifo address from a single address to a set of addresses,
- *		     with each sbp2 device having its own status fifo address. This makes
- *		     it easier to match the status write to the sbp2 device instance.
- *		   * Minor change to use lun when logging into sbp2 devices. First step in
- *		     supporting multi-lun devices such as CD/DVD changer devices.
- *		   * Added a new module load option for setting max sectors. For use by folk
- *		     who'd like to bump up the max scsi transfer size supported.
- *		   * Enabled deserialized operation by default, allowing for better performance,
- *		     particularily when running with multiple sbp2 devices. For debugging,
- *		     you may enable serialization through use of the sbp2_serialize_io module
- *		     load option (e.g. insmod sbp2 sbp2_serialize_io=1).
- *	02/20/02 - Added a couple additional module load options. 
- *		   Needed to bump down max commands per lun because of the !%@&*^# QPS CDRW 
- *		   drive I have, which doesn't seem to get along with other sbp2 devices 
- *		   (or handle linked commands well).
- *	04/21/02 - Added some additional debug capabilities:
- *		   * Able to handle phys dma requests directly, if host controller has phys
- *		     dma disabled (e.g. insmod ohci1394 phys_dma=0). Undefine CONFIG_IEEE1394_SBP2_PHYS_DMA
- *		     if you'd like to disable sbp2 driver from registering for phys address range. 
- *		   * New packet dump debug define (CONFIG_IEEE1394_SBP2_PACKET_DUMP) which allows
- *		     dumping of all sbp2 related packets sent and received. Especially effective
- *		     when phys dma is disabled on ohci controller (e.g. insmod ohci1394 phys_dma=0).
- *		   * Added new sbp2 module load option (sbp2_exclusive_login) for allowing
- *		     non-exclusive login to sbp2 device, for special multi-host applications.
- *	04/23/02 - Fix for Sony CD-ROM drives. Only send fetch agent reset to sbp2 device if it
- *		   returns the dead bit in status. Thanks to Chandan (chandan@toad.net) for this one.
- *	04/27/02 - Fix sbp2 login problem on SMP systems, enable real spinlocks by default. (JSG)
- *	06/09/02 - Don't force 36-bute SCSI inquiry, but leave in a define for badly behaved devices. (JSG)   
- *	02/04/03 - Fixed a SMP deadlock (don't hold sbp2_command_lock while calling sbp2scsi_complete_command).
- *		   Also save/restore irq flags in sbp2scsi_complete_command  - Sancho Dauskardt <sda@bdit.de>
- *
- */
-
-
-/*
- * Includes
  */
 
 #include <linux/config.h>
@@ -343,15 +79,15 @@
 #include "ieee1394.h"
 #include "ieee1394_types.h"
 #include "ieee1394_core.h"
+#include "nodemgr.h"
 #include "hosts.h"
 #include "nodemgr.h"
 #include "highlevel.h"
 #include "ieee1394_transactions.h"
-#include "ieee1394_hotplug.h"
 #include "sbp2.h"
 
 static char version[] __devinitdata =
-	"$Rev: 906 $ James Goodwin <jamesg@filanet.com>";
+	"$Rev: 953 $ Ben Collins <bcollins@debian.org>";
 
 /*
  * Module load parameter definitions
@@ -367,7 +103,7 @@
  */
 MODULE_PARM(sbp2_max_speed,"i");
 MODULE_PARM_DESC(sbp2_max_speed, "Force max speed (3 = 800mb, 2 = 400mb default, 1 = 200mb, 0 = 100mb)");
-static int sbp2_max_speed = SPEED_MAX;
+static int sbp2_max_speed = IEEE1394_SPEED_MAX;
 
 /*
  * Set sbp2_serialize_io to 1 if you'd like only one scsi command sent
@@ -489,6 +225,13 @@
 #define SBP2_ERR(fmt, args...)		HPSB_ERR("sbp2: "fmt, ## args)
 
 
+/* If you get the linux-2.4 scsi_{add,remove}_single_device patch, you can
+ * enable this define to make use of it. This provides better hotplug
+ * support. The mentioned patch is not part of the kernel proper though,
+ * because it is considered somewhat of a hack. */
+//#define SBP2_USE_SCSI_ADDREM_HACK
+
+
 /*
  * Globals
  */
@@ -502,9 +245,10 @@
 	
 static Scsi_Host_Template scsi_driver_template;
 
+const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC };
+
 static struct hpsb_highlevel sbp2_highlevel = {
 	.name =		SBP2_DEVICE_NAME,
-	.add_host =	sbp2_add_host,
 	.remove_host =	sbp2_remove_host,
 };
 
@@ -815,22 +559,22 @@
 /* Free our DMA's */
 static void sbp2util_free_command_dma(struct sbp2_command_info *command)
 {
-	struct sbp2scsi_host_info *hi;
+	struct hpsb_host *host;
 
-	hi = hpsb_get_hostinfo_bykey(&sbp2_highlevel,
+	host = hpsb_get_host_bykey(&sbp2_highlevel,
 		(unsigned long)command->Current_SCpnt->device->host->hostt);
-	if (!hi) {
-		printk(KERN_ERR "%s: hi == NULL\n", __FUNCTION__);
+	if (!host) {
+		printk(KERN_ERR "%s: host == NULL\n", __FUNCTION__);
 		return;
 	}
 
 	if (command->cmd_dma) {
 		if (command->dma_type == CMD_DMA_SINGLE) {
-			pci_unmap_single(hi->host->pdev, command->cmd_dma,
+			pci_unmap_single(host->pdev, command->cmd_dma,
 					 command->dma_size, command->dma_dir);
 			SBP2_DMA_FREE("single bulk");
 		} else if (command->dma_type == CMD_DMA_PAGE) {
-			pci_unmap_page(hi->host->pdev, command->cmd_dma,
+			pci_unmap_page(host->pdev, command->cmd_dma,
 				       command->dma_size, command->dma_dir);
 			SBP2_DMA_FREE("single page");
 		} /* XXX: Check for CMD_DMA_NONE bug */
@@ -839,7 +583,7 @@
 	}
 
 	if (command->sge_buffer) {
-		pci_unmap_sg(hi->host->pdev, command->sge_buffer,
+		pci_unmap_sg(host->pdev, command->sge_buffer,
 			     command->dma_size, command->dma_dir);
 		SBP2_DMA_FREE("scatter list");
 		command->sge_buffer = NULL;
@@ -873,7 +617,7 @@
 static int sbp2scsi_detect(Scsi_Host_Template *tpnt)
 {
 	struct Scsi_Host *scsi_host;
-	struct sbp2scsi_host_info *hi = hpsb_get_hostinfo_bykey(&sbp2_highlevel, (unsigned long)tpnt);
+	struct hpsb_host *host = hpsb_get_host_bykey(&sbp2_highlevel, (unsigned long)tpnt);
 
 	SBP2_DEBUG("sbp2scsi_detect");
 
@@ -881,7 +625,7 @@
 	if (!(scsi_host = scsi_register(tpnt, 0)))
 		return 0;
 
-	scsi_set_pci_device(scsi_host, hi->host->pdev);
+	scsi_set_pci_device(scsi_host, host->pdev);
 
 	tpnt->present = 1;
 
@@ -893,80 +637,104 @@
 	struct sbp2scsi_host_info *hi;
 
 	SBP2_DEBUG("sbp2_probe");
-	hi = hpsb_get_hostinfo(&sbp2_highlevel, ud->ne->host);
+	hi = sbp2_add_host(ud->ne->host);
 
-	return sbp2_start_device(hi, ud);
+	if (!hi)
+		return -1;
+
+	return sbp2_start_ud(hi, ud);
 }
 
 static void sbp2_disconnect(struct unit_directory *ud)
 {
-	struct scsi_id_instance_data *scsi_id = ud->driver_data;
+	struct scsi_id_group *scsi_group = ud->driver_data;
+	struct list_head *lh, *next;
+	struct scsi_id_instance_data *scsi_id;
 
 	SBP2_DEBUG("sbp2_disconnect");
 
-	if (scsi_id) {
-		sbp2_logout_device(scsi_id);
- 		sbp2_remove_device(scsi_id);
+	list_for_each_safe (lh, next, &scsi_group->scsi_id_list) {
+		scsi_id = list_entry(lh, struct scsi_id_instance_data, list);
+		if (scsi_id) {
+			sbp2_logout_device(scsi_id);
+ 			sbp2_remove_device(scsi_id);
+		}
 	}
+
+	kfree(scsi_group);
 }
 
 static void sbp2_update(struct unit_directory *ud)
 {
 	struct sbp2scsi_host_info *hi;
-	struct scsi_id_instance_data *scsi_id = ud->driver_data;
+	struct scsi_id_group *scsi_group = ud->driver_data;
+	struct list_head *lh, *next;
+	struct scsi_id_instance_data *scsi_id;
 	unsigned long flags;
 
 	SBP2_DEBUG("sbp2_update");
 	hi = hpsb_get_hostinfo(&sbp2_highlevel, ud->ne->host);
 
-	if (sbp2_reconnect_device(scsi_id)) {
-		
-		/* 
-		 * Ok, reconnect has failed. Perhaps we didn't
-		 * reconnect fast enough. Try doing a regular login.
-		 */
-		if (sbp2_login_device(scsi_id)) {
-			/* Login failed too, just remove the device. */
-			SBP2_ERR("sbp2_reconnect_device failed!");
-			sbp2_remove_device(scsi_id);
-			hpsb_release_unit_directory(ud);
-			return;
+	list_for_each_safe (lh, next, &scsi_group->scsi_id_list) {
+		scsi_id = list_entry(lh, struct scsi_id_instance_data, list);
+
+		if (sbp2_reconnect_device(scsi_id)) {
+			/* 
+			 * Ok, reconnect has failed. Perhaps we didn't
+			 * reconnect fast enough. Try doing a regular login.
+			 */
+			if (sbp2_login_device(scsi_id)) {
+				/* Login failed too, just remove the device. */
+				SBP2_ERR("sbp2_reconnect_device failed!");
+				sbp2_remove_device(scsi_id);
+				continue;
+			}
 		}
-	}
 
-	/* Set max retries to something large on the device. */
-	sbp2_set_busy_timeout(scsi_id);
+		/* Set max retries to something large on the device. */
+		sbp2_set_busy_timeout(scsi_id);
 
-	/* Do a SBP-2 fetch agent reset. */
-	sbp2_agent_reset(scsi_id, 0);
+		/* Do a SBP-2 fetch agent reset. */
+		sbp2_agent_reset(scsi_id, 0);
 	
-	/* Get the max speed and packet size that we can use. */
-	sbp2_max_speed_and_size(scsi_id);
+		/* Get the max speed and packet size that we can use. */
+		sbp2_max_speed_and_size(scsi_id);
 
-	/* Complete any pending commands with busy (so they get
-	 * retried) and remove them from our queue
-	 */
-	spin_lock_irqsave(&hi->sbp2_command_lock, flags);
-	sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY);
-	spin_unlock_irqrestore(&hi->sbp2_command_lock, flags);
+		/* Complete any pending commands with busy (so they get
+		 * retried) and remove them from our queue
+		 */
+		spin_lock_irqsave(&hi->sbp2_command_lock, flags);
+		sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY);
+		spin_unlock_irqrestore(&hi->sbp2_command_lock, flags);
+	}
+
+	if (list_empty(&scsi_group->scsi_id_list)) {
+		hpsb_release_unit_directory(ud);
+		kfree(scsi_group);
+	}
 }
 
 /*
  * We go ahead and allocate some memory for our host info structure, and
  * init some structures.
  */
-static void sbp2_add_host(struct hpsb_host *host)
+static struct sbp2scsi_host_info *sbp2_add_host(struct hpsb_host *host)
 {
 	struct sbp2scsi_host_info *hi;
 
 	SBP2_DEBUG("sbp2_add_host");
 
+	/* Check for existing hostinfo */
+	hi = hpsb_get_hostinfo(&sbp2_highlevel, host);
+	if (hi)
+		return hi;
+
 	/* Allocate some memory for our host info structure */
 	hi = hpsb_create_hostinfo(&sbp2_highlevel, host, sizeof(*hi));
 
 	if (hi == NULL) {
 		SBP2_ERR("out of memory in sbp2_add_host");
-		return;
+		return NULL;
 	}
 
 	/* Initialize some host stuff */
@@ -981,7 +749,7 @@
 	if (SCSI_REGISTER_HOST(&hi->sht)) {
                 SBP2_ERR("Failed to register scsi template for ieee1394 host");
 		hpsb_destroy_hostinfo(&sbp2_highlevel, host);
-                return;
+                return NULL;
         }
 
 	for (hi->scsi_host = scsi_hostlist; hi->scsi_host; hi->scsi_host = hi->scsi_host->next)
@@ -992,12 +760,12 @@
 		SBP2_ERR("Failed to register scsi host for ieee1394 host");
 		SCSI_UNREGISTER_HOST(&hi->sht);
 		hpsb_destroy_hostinfo(&sbp2_highlevel, host);
-		return;
+		return NULL;
 	}
 
 	hi->scsi_host->max_id = SBP2SCSI_MAX_SCSI_IDS;
 
-	return;
+	return hi;
 }
 
 
@@ -1014,34 +782,61 @@
 
 	if (hi)
 		SCSI_UNREGISTER_HOST(&hi->sht);
-	else
-		SBP2_ERR("attempt to remove unknown host %p", host);
 }
 
+static int sbp2_start_ud(struct sbp2scsi_host_info *hi, struct unit_directory *ud)
+{
+	struct scsi_id_instance_data *scsi_id;
+	struct scsi_id_group *scsi_group;
+	struct list_head *lh, *next;
+
+	SBP2_DEBUG("sbp2_start_ud");
+
+	scsi_group = kmalloc(sizeof(*scsi_group), GFP_KERNEL);
+	if (!scsi_group) {
+		SBP2_ERR ("Could not allocate memory for scsi_group");
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&scsi_group->scsi_id_list);
+	ud->driver_data = scsi_group;
+	sbp2_parse_unit_directory(scsi_group, ud);
+
+	list_for_each_safe (lh, next, &scsi_group->scsi_id_list) {
+		scsi_id = list_entry(lh, struct scsi_id_instance_data, list);
+
+		scsi_id->ne = ud->ne;
+		scsi_id->hi = hi;
+		scsi_id->speed_code = IEEE1394_SPEED_100;
+		scsi_id->max_payload_size = sbp2_speedto_max_payload[IEEE1394_SPEED_100];
+		atomic_set(&scsi_id->sbp2_login_complete, 0);
+		INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse);
+		INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
+		scsi_id->sbp2_command_orb_lock = SPIN_LOCK_UNLOCKED;
+
+		sbp2_start_device(scsi_id);
+	}
+
+	/* Check to see if any of our devices survived the ordeal */
+	if (list_empty(&scsi_group->scsi_id_list)) {
+		kfree(scsi_group);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+
 /*
  * This function is where we first pull the node unique ids, and then
  * allocate memory and register a SBP-2 device.
  */
-static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_directory *ud)
+static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
 {
-	struct scsi_id_instance_data *scsi_id = NULL;
-	struct node_entry *ne;
+	struct sbp2scsi_host_info *hi = scsi_id->hi;
 	int i;
 
 	SBP2_DEBUG("sbp2_start_device");
-	ne = ud->ne;
-
-	/*
-	 * This really is a "new" device plugged in. Let's allocate memory
-	 * for our scsi id instance data.
-	 */
-	scsi_id = (struct scsi_id_instance_data *)kmalloc(sizeof(struct scsi_id_instance_data),
-							  GFP_KERNEL);
-	if (!scsi_id)
-		goto alloc_fail_first;
-	memset(scsi_id, 0, sizeof(struct scsi_id_instance_data));
-
-	scsi_id->hi = hi;
 
 	/* Login FIFO DMA */
 	scsi_id->login_response =
@@ -1130,7 +925,9 @@
 		}
 
 		kfree(scsi_id);
-alloc_fail_first:
+
+		list_del(&scsi_id->list);
+
 		SBP2_ERR ("Could not allocate memory for scsi_id");
 
 		return -ENOMEM;
@@ -1138,31 +935,6 @@
 	SBP2_DMA_ALLOC("consistent DMA region for login ORB");
 
 	/*
-	 * Initialize some of the fields in this structure
-	 */
-	scsi_id->ne = ne;
-	scsi_id->ud = ud;
-	scsi_id->speed_code = SPEED_100;
-	scsi_id->max_payload_size = hpsb_speedto_maxrec[SPEED_100];
-	ud->driver_data = scsi_id;
-
-	atomic_set(&scsi_id->sbp2_login_complete, 0);
-
-	/* 
-	 * Initialize structures needed for the command orb pool.
-	 */
-	INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse);
-	INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
-	scsi_id->sbp2_command_orb_lock = SPIN_LOCK_UNLOCKED;
-
-	/*
-	 * Make sure that we've gotten ahold of the sbp2 management agent
-	 * address. Also figure out the command set being used (SCSI or
-	 * RBC).
-	 */
-	sbp2_parse_unit_directory(scsi_id);
-
-	/*
 	 * Find an empty spot to stick our scsi id instance data. 
 	 */
 	for (i = 0; i < hi->scsi_host->max_id; i++) {
@@ -1216,6 +988,12 @@
 	 */
 	sbp2_max_speed_and_size(scsi_id);
 
+#ifdef SBP2_USE_SCSI_ADDREM_HACK
+	/* Try to hook ourselves into the SCSI subsystem */
+	if (scsi_add_single_device(hi->scsi_host, 0, scsi_id->id, 0))
+		SBP2_INFO("Unable to connect SBP-2 device into the SCSI subsystem");
+#endif
+
 	return 0;
 }
 
@@ -1286,6 +1064,8 @@
 
 	SBP2_DEBUG("SBP-2 device removed, SCSI ID = %d", scsi_id->id);
 
+	list_del(&scsi_id->list);
+
 	kfree(scsi_id);
 }
 
@@ -1362,6 +1142,8 @@
 	scsi_id->query_logins_orb->lun_misc |= ORB_SET_NOTIFY(1);
 	if (scsi_id->sbp2_device_type_and_lun != SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) {
 		scsi_id->query_logins_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun);
+		SBP2_DEBUG("sbp2_query_logins: set lun to %d",
+			   ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun));
 	}
 	SBP2_DEBUG("sbp2_query_logins: lun_misc initialized");
 
@@ -1474,6 +1256,8 @@
 	/* Set the lun if we were able to pull it from the device's unit directory */
 	if (scsi_id->sbp2_device_type_and_lun != SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) {
 		scsi_id->login_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun);
+		SBP2_DEBUG("sbp2_query_logins: set lun to %d",
+			   ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun));
 	}
 	SBP2_DEBUG("sbp2_login_device: lun_misc initialized");
 
@@ -1514,7 +1298,8 @@
 
 	atomic_set(&scsi_id->sbp2_login_complete, 0);
 
-	SBP2_DEBUG("sbp2_login_device: prepared to write");
+	SBP2_DEBUG("sbp2_login_device: prepared to write to %08x",
+		   (unsigned int)scsi_id->sbp2_management_agent_addr);
 	hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8);
 	SBP2_DEBUG("sbp2_login_device: written");
 
@@ -1625,8 +1410,14 @@
 
 	SBP2_INFO("Logged out of SBP-2 device");
 
-	return(0);
+#ifdef SBP2_USE_SCSI_ADDREM_HACK
+	/* Now that we are logged out of the SBP-2 device, lets
+	 * try to un-hook ourselves from the SCSI subsystem */
+	if (scsi_remove_single_device(hi->scsi_host, 0, scsi_id->id, 0))
+		SBP2_INFO("Unable to disconnect SBP-2 device from the SCSI subsystem");
+#endif
 
+	return 0;
 }
 
 /*
@@ -1745,50 +1536,50 @@
  * directory. Used to determine things like sbp2 management agent offset,
  * and command set used (SCSI or RBC). 
  */
-static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id)
+static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group,
+				      struct unit_directory *ud)
 {
-	struct unit_directory *ud;
+	struct scsi_id_instance_data *scsi_id;
+	struct list_head *lh;
+	u64 management_agent_addr;
+	u32 command_set_spec_id, command_set, unit_characteristics,
+		firmware_revision, workarounds;
 	int i;
 
 	SBP2_DEBUG("sbp2_parse_unit_directory");
 
-	/* Initialize some fields, in case an entry does not exist */
-	scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED;
-	scsi_id->sbp2_management_agent_addr = 0x0;
-	scsi_id->sbp2_command_set_spec_id = 0x0;
-	scsi_id->sbp2_command_set = 0x0;
-	scsi_id->sbp2_unit_characteristics = 0x0;
-	scsi_id->sbp2_firmware_revision = 0x0;
-
-	ud = scsi_id->ud;
+	management_agent_addr = 0x0;
+	command_set_spec_id = 0x0;
+	command_set = 0x0;
+	unit_characteristics = 0x0;
+	firmware_revision = 0x0;
 
 	/* Handle different fields in the unit directory, based on keys */
 	for (i = 0; i < ud->length; i++) {
 		switch (CONFIG_ROM_KEY(ud->quadlets[i])) {
 		case SBP2_CSR_OFFSET_KEY:
 			/* Save off the management agent address */
-			scsi_id->sbp2_management_agent_addr =
+			management_agent_addr =
 				CSR_REGISTER_BASE + 
 				(CONFIG_ROM_VALUE(ud->quadlets[i]) << 2);
 
 			SBP2_DEBUG("sbp2_management_agent_addr = %x",
-				   (unsigned int) scsi_id->sbp2_management_agent_addr);
+				   (unsigned int) management_agent_addr);
 			break;
 
 		case SBP2_COMMAND_SET_SPEC_ID_KEY:
 			/* Command spec organization */
-			scsi_id->sbp2_command_set_spec_id
+			command_set_spec_id
 				= CONFIG_ROM_VALUE(ud->quadlets[i]);
 			SBP2_DEBUG("sbp2_command_set_spec_id = %x",
-				   (unsigned int) scsi_id->sbp2_command_set_spec_id);
+				   (unsigned int) command_set_spec_id);
 			break;
 
 		case SBP2_COMMAND_SET_KEY:
 			/* Command set used by sbp2 device */
-			scsi_id->sbp2_command_set
-				= CONFIG_ROM_VALUE(ud->quadlets[i]);
+			command_set = CONFIG_ROM_VALUE(ud->quadlets[i]);
 			SBP2_DEBUG("sbp2_command_set = %x",
-				   (unsigned int) scsi_id->sbp2_command_set);
+				   (unsigned int) command_set);
 			break;
 
 		case SBP2_UNIT_CHARACTERISTICS_KEY:
@@ -1796,10 +1587,10 @@
 			 * Unit characterisitcs (orb related stuff
 			 * that I'm not yet paying attention to)
 			 */
-			scsi_id->sbp2_unit_characteristics
+			unit_characteristics
 				= CONFIG_ROM_VALUE(ud->quadlets[i]);
 			SBP2_DEBUG("sbp2_unit_characteristics = %x",
-				   (unsigned int) scsi_id->sbp2_unit_characteristics);
+				   (unsigned int) unit_characteristics);
 			break;
 
 		case SBP2_DEVICE_TYPE_AND_LUN_KEY:
@@ -1807,21 +1598,29 @@
 			 * Device type and lun (used for
 			 * detemining type of sbp2 device)
 			 */
+			scsi_id = kmalloc(sizeof(*scsi_id), GFP_KERNEL);
+			if (!scsi_id) {
+				SBP2_ERR("Out of memory adding scsi_id, not all LUN's will be added");
+				break;
+			}
+			memset(scsi_id, 0, sizeof(*scsi_id));
+
 			scsi_id->sbp2_device_type_and_lun
 				= CONFIG_ROM_VALUE(ud->quadlets[i]);
 			SBP2_DEBUG("sbp2_device_type_and_lun = %x",
 				   (unsigned int) scsi_id->sbp2_device_type_and_lun);
+			list_add_tail(&scsi_id->list, &scsi_group->scsi_id_list);
 			break;
 
 		case SBP2_FIRMWARE_REVISION_KEY:
 			/* Firmware revision */
-			scsi_id->sbp2_firmware_revision
+			firmware_revision
 				= CONFIG_ROM_VALUE(ud->quadlets[i]);
 			if (sbp2_force_inquiry_hack)
 				SBP2_INFO("sbp2_firmware_revision = %x",
-				   (unsigned int) scsi_id->sbp2_firmware_revision);
+				   (unsigned int) firmware_revision);
 			else	SBP2_DEBUG("sbp2_firmware_revision = %x",
-				   (unsigned int) scsi_id->sbp2_firmware_revision);
+				   (unsigned int) firmware_revision);
 			break;
 
 		default:
@@ -1831,7 +1630,7 @@
 
 	/* This is the start of our broken device checking. We try to hack
 	 * around oddities and known defects.  */
-	scsi_id->workarounds = 0x0;
+	workarounds = 0x0;
 
 	/* If the vendor id is 0xa0b8 (Symbios vendor id), then we have a
 	 * bridge with 128KB max transfer size limitation. For sanity, we
@@ -1842,28 +1641,54 @@
 	 * host gets initialized. That way we can down-force the
 	 * sbp2_max_sectors to account for it. That is not currently
 	 * possible.  */
-	if ((scsi_id->sbp2_firmware_revision & 0xffff00) ==
+	if ((firmware_revision & 0xffff00) ==
 			SBP2_128KB_BROKEN_FIRMWARE &&
 			(sbp2_max_sectors * 512) > (128 * 1024)) {
 		SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB max transfer size.",
-				NODE_BUS_ARGS(scsi_id->ne->nodeid));
+				NODE_BUS_ARGS(ud->ne->nodeid));
 		SBP2_WARN("WARNING: Current sbp2_max_sectors setting is larger than 128KB (%d sectors)!",
 				sbp2_max_sectors);
-		scsi_id->workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER;
+		workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER;
 	}
 
 	/* Check for a blacklisted set of devices that require us to force
 	 * a 36 byte host inquiry. This can be overriden as a module param
 	 * (to force all hosts).  */
 	for (i = 0; i < NUM_BROKEN_INQUIRY_DEVS; i++) {
-		if ((scsi_id->sbp2_firmware_revision & 0xffff00) ==
+		if ((firmware_revision & 0xffff00) ==
 				sbp2_broken_inquiry_list[i]) {
 			SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround",
-					NODE_BUS_ARGS(scsi_id->ne->nodeid));
-			scsi_id->workarounds |= SBP2_BREAKAGE_INQUIRY_HACK;
+					NODE_BUS_ARGS(ud->ne->nodeid));
+			workarounds |= SBP2_BREAKAGE_INQUIRY_HACK;
 			break; /* No need to continue. */
 		}
 	}
+
+	/* If our list is empty, add a base scsi_id (happens in a normal
+	 * case where there is no logical_unit_number entry */
+	if (list_empty(&scsi_group->scsi_id_list)) {
+		scsi_id = kmalloc(sizeof(*scsi_id), GFP_KERNEL);
+		if (!scsi_id) {
+			SBP2_ERR("Out of memory adding scsi_id");
+			return;
+		}
+		memset(scsi_id, 0, sizeof(*scsi_id));
+
+		scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED;
+		list_add_tail(&scsi_id->list, &scsi_group->scsi_id_list);
+	}
+
+	/* Update the generic fields in all the LUN's */
+	list_for_each (lh, &scsi_group->scsi_id_list) {
+		scsi_id = list_entry(lh, struct scsi_id_instance_data, list);
+
+		scsi_id->sbp2_management_agent_addr = management_agent_addr;
+		scsi_id->sbp2_command_set_spec_id = command_set_spec_id;
+		scsi_id->sbp2_command_set = command_set;
+		scsi_id->sbp2_unit_characteristics = unit_characteristics;
+		scsi_id->sbp2_firmware_revision = firmware_revision;
+		scsi_id->workarounds = workarounds;
+	}
 }
 
 /*
@@ -1894,7 +1719,7 @@
 
 	/* Payload size is the lesser of what our speed supports and what
 	 * our host supports.  */
-	scsi_id->max_payload_size = min(hpsb_speedto_maxrec[scsi_id->speed_code],
+	scsi_id->max_payload_size = min(sbp2_speedto_max_payload[scsi_id->speed_code],
 					(u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1));
 
 	SBP2_ERR("Node[" NODE_BUS_FMT "]: Max speed [%s] - Max payload [%u]",
@@ -3053,27 +2878,27 @@
 			      int length, int hostno, int inout)
 {
 	Scsi_Device *scd;
-	struct Scsi_Host *host;
-	struct sbp2scsi_host_info *hi;
+	struct Scsi_Host *scsi_host;
+	struct hpsb_host *host;
 	char *pos = buffer;
 
 	/* if someone is sending us data, just throw it away */
 	if (inout)
 		return length;
 
-	for (host = scsi_hostlist; host; host = host->next)
-		if (host->host_no == hostno)
+	for (scsi_host = scsi_hostlist; scsi_host; scsi_host = scsi_host->next)
+		if (scsi_host->host_no == hostno)
 			break;
 
-	if (!host)  /* if we couldn't find it, we return an error */
+	if (!scsi_host)  /* if we couldn't find it, we return an error */
 		return -ESRCH;
 
-	hi = hpsb_get_hostinfo_bykey(&sbp2_highlevel, (unsigned long)host->hostt);
-	if (!hi) /* shouldn't happen, but... */
+	host = hpsb_get_host_bykey(&sbp2_highlevel, (unsigned long)scsi_host->hostt);
+	if (!host) /* shouldn't happen, but... */
 		return -ESRCH;
 
 	SPRINTF("Host scsi%d             : SBP-2 IEEE-1394 (%s)\n", hostno,
-		hi->host->driver->name);
+		host->driver->name);
 	SPRINTF("Driver version         : %s\n", version);
 
 	SPRINTF("\nModule options         :\n");
@@ -3082,9 +2907,9 @@
 	SPRINTF("  serialize_io         : %s\n", sbp2_serialize_io ? "yes" : "no");
 	SPRINTF("  exclusive_login      : %s\n", sbp2_exclusive_login ? "yes" : "no");
 
-	SPRINTF("\nAttached devices       : %s\n", host->host_queue ? "" : "none");
+	SPRINTF("\nAttached devices       : %s\n", scsi_host->host_queue ? "" : "none");
 
-	for (scd = host->host_queue; scd; scd = scd->next) {
+	for (scd = scsi_host->host_queue; scd; scd = scd->next) {
 		int i;
 
 		SPRINTF("  [Channel: %02d, Id: %02d, Lun: %02d]  ", scd->channel,
@@ -3117,7 +2942,7 @@
 }
 
 
-MODULE_AUTHOR("James Goodwin <jamesg@filanet.com>");
+MODULE_AUTHOR("Ben Collins <bcollins@debian.org>");
 MODULE_DESCRIPTION("IEEE-1394 SBP-2 protocol driver");
 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
 MODULE_LICENSE("GPL");
diff -urN linux-2.4.22-pre2/drivers/ieee1394/sbp2.h linux-2.4.22-pre3/drivers/ieee1394/sbp2.h
--- linux-2.4.22-pre2/drivers/ieee1394/sbp2.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/sbp2.h	2003-07-05 18:10:02.000000000 -0700
@@ -388,7 +388,6 @@
 	/*
 	 * Values pulled from the device's unit directory
 	 */
-	struct unit_directory *ud;
 	u32 sbp2_command_set_spec_id;
 	u32 sbp2_command_set;
 	u32 sbp2_unit_characteristics;
@@ -407,6 +406,8 @@
 	struct list_head sbp2_command_orb_inuse;
 	struct list_head sbp2_command_orb_completed;
 
+	struct list_head list;
+
 	/* Node entry, as retrieved from NodeMgr entries */
 	struct node_entry *ne;
 
@@ -417,6 +418,13 @@
 	u32 workarounds;
 };
 
+
+/* Describes a per-ud scsi_id group */
+struct scsi_id_group {
+	struct list_head scsi_id_list;
+};
+
+
 /*
  * Sbp2 host data structure (one per sbp2 host)
  */
@@ -461,14 +469,15 @@
 /*
  * IEEE-1394 core driver related prototypes
  */
-static void sbp2_add_host(struct hpsb_host *host);
+static struct sbp2scsi_host_info *sbp2_add_host(struct hpsb_host *host);
 static void sbp2_remove_host(struct hpsb_host *host);
 static int sbp2_probe(struct unit_directory *ud);
 static void sbp2_disconnect(struct unit_directory *ud);
 static void sbp2_update(struct unit_directory *ud);
 
-static int sbp2_start_device(struct sbp2scsi_host_info *hi, 
-			     struct unit_directory *ud);
+static int sbp2_start_ud(struct sbp2scsi_host_info *hi,
+			 struct unit_directory *ud);
+static int sbp2_start_device(struct scsi_id_instance_data *scsi_id);
 static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id);
 
 #ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
@@ -502,7 +511,8 @@
 static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data);
 static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd);
 static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, Scsi_Cmnd *SCpnt);
-static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id);
+static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group,
+				      struct unit_directory *ud);
 static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id);
 static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id);
 
diff -urN linux-2.4.22-pre2/drivers/ieee1394/video1394.c linux-2.4.22-pre3/drivers/ieee1394/video1394.c
--- linux-2.4.22-pre2/drivers/ieee1394/video1394.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/ieee1394/video1394.c	2003-07-05 18:10:03.000000000 -0700
@@ -46,7 +46,7 @@
 
 #include "ieee1394.h"
 #include "ieee1394_types.h"
-#include "ieee1394_hotplug.h"
+#include "nodemgr.h"
 #include "hosts.h"
 #include "ieee1394_core.h"
 #include "highlevel.h"
@@ -594,7 +594,7 @@
 		it_prg[i].begin.status = 0;
 		
 		it_prg[i].data[0] = cpu_to_le32(
-			(SPEED_100 << 16) 
+			(IEEE1394_SPEED_100 << 16) 
 			| (/* tag */ 1 << 14)
 			| (d->channel << 8) 
 			| (TCODE_ISO_DATA << 4));
@@ -713,7 +713,7 @@
 		struct dma_iso_ctx *d;
 		int i;
 
-		if(copy_from_user(&v, (void *)arg, sizeof(v)))
+		if (copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
 		/* if channel < 0, find lowest available one */
@@ -810,7 +810,7 @@
 			      v.channel);
 		}
 
-		if(copy_to_user((void *)arg, &v, sizeof(v)))
+		if (copy_to_user((void *)arg, &v, sizeof(v)))
 			return -EFAULT;
 
 		return 0;
@@ -824,7 +824,7 @@
 		u64 mask;
 		struct dma_iso_ctx *d;
 
-		if(copy_from_user(&channel, (void *)arg, sizeof(int)))
+		if (copy_from_user(&channel, (void *)arg, sizeof(int)))
 			return -EFAULT;
 
 		if (channel<0 || channel>(ISO_CHANNELS-1)) {
@@ -860,7 +860,7 @@
 		struct video1394_wait v;
 		struct dma_iso_ctx *d;
 
-		if(copy_from_user(&v, (void *)arg, sizeof(v)))
+		if (copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
 		d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
@@ -924,7 +924,7 @@
 		struct dma_iso_ctx *d;
 		int i;
 
-		if(copy_from_user(&v, (void *)arg, sizeof(v)))
+		if (copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
 		d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
@@ -953,12 +953,12 @@
 			}
 
 #if 1
-			while(d->buffer_status[v.buffer]!=
+			while (d->buffer_status[v.buffer]!=
 			      VIDEO1394_BUFFER_READY) {
 				spin_unlock_irqrestore(&d->lock, flags);
 				interruptible_sleep_on(&d->waitq);
 				spin_lock_irqsave(&d->lock, flags);
-				if(signal_pending(current)) {
+				if (signal_pending(current)) {
 					spin_unlock_irqrestore(&d->lock,flags);
 					return -EINTR;
 				}
@@ -995,7 +995,7 @@
 		spin_unlock_irqrestore(&d->lock, flags);
 
 		v.buffer=i;
-		if(copy_to_user((void *)arg, &v, sizeof(v)))
+		if (copy_to_user((void *)arg, &v, sizeof(v)))
 			return -EFAULT;
 
 		return 0;
@@ -1007,7 +1007,9 @@
 		struct video1394_queue_variable qv;
 		struct dma_iso_ctx *d;
 
-		if(copy_from_user(&v, (void *)arg, sizeof(v)))
+		qv.packet_sizes = NULL;
+
+		if (copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
 		d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
@@ -1019,12 +1021,22 @@
 		}
 		
 		if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) {
+			unsigned int *psizes;
+			int buf_size = d->nb_cmd * sizeof(unsigned int);
+
 			if (copy_from_user(&qv, (void *)arg, sizeof(qv))) 
 				return -EFAULT;
-			if (!access_ok(VERIFY_READ, qv.packet_sizes, 
-				       d->nb_cmd * sizeof(unsigned int))) {
+
+			psizes = kmalloc(buf_size, GFP_KERNEL);
+			if (!psizes)
+				return -ENOMEM;
+
+			if (copy_from_user(psizes, qv.packet_sizes, buf_size)) {
+				kfree(psizes);
 				return -EFAULT;
 			}
+
+			qv.packet_sizes = psizes;
 		}
 
 		spin_lock_irqsave(&d->lock,flags);
@@ -1033,6 +1045,8 @@
 			PRINT(KERN_ERR, ohci->id, 
 			      "Buffer %d is already used",v.buffer);
 			spin_unlock_irqrestore(&d->lock,flags);
+			if (qv.packet_sizes)
+				kfree(qv.packet_sizes);
 			return -EFAULT;
 		}
 		
@@ -1086,6 +1100,10 @@
 				reg_write(ohci, d->ctrlSet, 0x1000);
 			}
 		}
+
+		if (qv.packet_sizes)
+			kfree(qv.packet_sizes);
+
 		return 0;
 		
 	}
@@ -1095,7 +1113,7 @@
 		struct video1394_wait v;
 		struct dma_iso_ctx *d;
 
-		if(copy_from_user(&v, (void *)arg, sizeof(v)))
+		if (copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
 		d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
@@ -1112,10 +1130,10 @@
 			return 0;
 		case VIDEO1394_BUFFER_QUEUED:
 #if 1
-			while(d->buffer_status[v.buffer]!=
+			while (d->buffer_status[v.buffer]!=
 			      VIDEO1394_BUFFER_READY) {
 				interruptible_sleep_on(&d->waitq);
-				if(signal_pending(current)) return -EINTR;
+				if (signal_pending(current)) return -EINTR;
 			}
 #else
 			if (wait_event_interruptible(d->waitq, 
diff -urN linux-2.4.22-pre2/drivers/macintosh/adb.c linux-2.4.22-pre3/drivers/macintosh/adb.c
--- linux-2.4.22-pre2/drivers/macintosh/adb.c	2002-11-28 15:53:13.000000000 -0800
+++ linux-2.4.22-pre3/drivers/macintosh/adb.c	2003-07-05 18:10:05.000000000 -0700
@@ -252,6 +252,10 @@
 {
 	adb_probe_task_pid = kernel_thread(adb_probe_task, NULL,
 		SIGCHLD | CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+	if (adb_probe_task_pid < 0) {
+		adb_probe_task_pid = 0;
+		printk(KERN_ERR "adb: failed to create probe task !\n");
+	}
 }
 
 int
@@ -592,7 +596,6 @@
 	return (*original_address != 0);
 }
 
-
 /*
  * /dev/adb device driver.
  */
@@ -636,6 +639,27 @@
 	spin_unlock_irqrestore(&state->lock, flags);
 }
 
+static int
+do_adb_query(struct adb_request *req)
+{
+	int	ret = -EINVAL;
+
+	switch(req->data[1])
+	{
+	case ADB_QUERY_GETDEVINFO:
+		if (req->nbytes < 3)
+			break;
+		req->reply[0] = adb_handler[req->data[2]].original_address;
+		req->reply[1] = adb_handler[req->data[2]].handler_id;
+		req->complete = 1;
+		req->reply_len = 2;
+		adb_write_done(req);
+		ret = 0;
+		break;
+	}
+	return ret;
+}
+
 static int adb_open(struct inode *inode, struct file *file)
 {
 	struct adbdev_state *state;
@@ -655,6 +679,7 @@
 	return 0;
 }
 
+/* FIXME: Should wait completion, dequeue & delete pending requests */
 static int adb_release(struct inode *inode, struct file *file)
 {
 	struct adbdev_state *state = file->private_data;
@@ -772,9 +797,17 @@
 	/* If a probe is in progress or we are sleeping, wait for it to complete */
 	down(&adb_probe_mutex);
 
+	/* Queries are special requests sent to the ADB driver itself */
+	if (req->data[0] == ADB_QUERY) {
+		if (count > 1)
+			ret = do_adb_query(req);
+		else
+			ret = -EINVAL;
+		up(&adb_probe_mutex);
+	}
 	/* Special case for ADB_BUSRESET request, all others are sent to
 	   the controller */
-	if ((req->data[0] == ADB_PACKET)&&(count > 1)
+	else if ((req->data[0] == ADB_PACKET)&&(count > 1)
 		&&(req->data[1] == ADB_BUSRESET)) {
 		ret = do_adb_reset_bus();
 		up(&adb_probe_mutex);
diff -urN linux-2.4.22-pre2/drivers/macintosh/adbhid.c linux-2.4.22-pre3/drivers/macintosh/adbhid.c
--- linux-2.4.22-pre2/drivers/macintosh/adbhid.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/macintosh/adbhid.c	2003-07-05 18:10:06.000000000 -0700
@@ -42,6 +42,10 @@
 #include <linux/adb.h>
 #include <linux/cuda.h>
 #include <linux/pmu.h>
+
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
 #endif
@@ -65,7 +69,7 @@
 	  0, 83,  0, 55,  0, 78,  0, 69,  0,  0,  0, 98, 96,  0, 74,  0,
 	  0,117, 82, 79, 80, 81, 75, 76, 77, 71,  0, 72, 73,183,181,124,
 	 63, 64, 65, 61, 66, 67,191, 87,190, 99,  0, 70,  0, 68,101, 88,
-	  0,119,110,102,104,111, 62,107, 60,109, 59, 54,100, 97,116,116
+	  0,119,110,102,104,111, 62,107, 60,109, 59, 54,100, 97,126,116
 };
 
 struct adbhid {
@@ -154,6 +158,15 @@
 		return;
 	case 0x3f: /* ignore Powerbook Fn key */
 		return;
+	case 0x7e: /* Power key on PBook 3400 needs remapping */
+		switch(pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+			NULL, PMAC_MB_INFO_MODEL, 0)) {
+		case PMAC_TYPE_COMET:
+		case PMAC_TYPE_HOOPER:
+		case PMAC_TYPE_KANGA:
+			keycode = 0x7f;
+		}
+		break;
 	}
 
 	if (adbhid[id]->keycode[keycode])
@@ -306,13 +319,12 @@
 		case 0xa:	/* brightness decrease */
 #ifdef CONFIG_PMAC_BACKLIGHT
 			if (!disable_kernel_backlight) {
-				if (!down || backlight < 0)
-					break;
-				if (backlight > BACKLIGHT_OFF)
-					set_backlight_level(backlight-1);
-				else
-					set_backlight_level(BACKLIGHT_OFF);
-				break;
+				if (down && backlight >= 0) {
+					if (backlight > BACKLIGHT_OFF)
+						set_backlight_level(backlight-1);
+					else
+						set_backlight_level(BACKLIGHT_OFF);
+				}
 			}
 #endif /* CONFIG_PMAC_BACKLIGHT */
 			input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
@@ -320,13 +332,12 @@
 		case 0x9:	/* brightness increase */
 #ifdef CONFIG_PMAC_BACKLIGHT
 			if (!disable_kernel_backlight) {
-				if (!down || backlight < 0)
-					break;
-				if (backlight < BACKLIGHT_MAX)
-					set_backlight_level(backlight+1);
-				else 
-					set_backlight_level(BACKLIGHT_MAX);
-				break;
+				if (down && backlight >= 0) {
+					if (backlight < BACKLIGHT_MAX)
+						set_backlight_level(backlight+1);
+					else 
+						set_backlight_level(BACKLIGHT_MAX);
+				}
 			}
 #endif /* CONFIG_PMAC_BACKLIGHT */
 			input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down);
diff -urN linux-2.4.22-pre2/drivers/macintosh/apm_emu.c linux-2.4.22-pre3/drivers/macintosh/apm_emu.c
--- linux-2.4.22-pre2/drivers/macintosh/apm_emu.c	2002-11-28 15:53:13.000000000 -0800
+++ linux-2.4.22-pre3/drivers/macintosh/apm_emu.c	2003-07-05 18:10:06.000000000 -0700
@@ -436,40 +436,40 @@
 	int		percentage     = -1;
 	int             time_units     = -1;
 	int		real_count     = 0;
-	int		charge         = -1;
-	int		current        = 0;
 	int		i;
 	char *		p = buf;
 	char		charging       = 0;
+	long		charge	       = -1;
+	long		current        = 0;
+	unsigned long	btype          = 0;
 
 	ac_line_status = ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0);
 	for (i=0; i<pmu_battery_count; i++) {
-		if (percentage < 0)
-			percentage = 0;
-		if (charge < 0)
-			charge = 0;
 		if (pmu_batteries[i].flags & PMU_BATT_PRESENT) {
+			if (percentage < 0)
+				percentage = 0;
+			if (charge < 0)
+				charge = 0;
 			percentage += (pmu_batteries[i].charge * 100) /
 				pmu_batteries[i].max_charge;
-			/* hrm... should we provide the remaining charge
-			 * time when AC is plugged ? If yes, just remove
-			 * that test --BenH
-			 */
-			if (!ac_line_status) {
-				charge += pmu_batteries[i].charge;
-				current += pmu_batteries[i].current;
-			}
+			charge += pmu_batteries[i].charge;
+			current += pmu_batteries[i].current;
+			if (btype == 0)
+				btype = (pmu_batteries[i].flags & PMU_BATT_TYPE_MASK);
 			real_count++;
 			if ((pmu_batteries[i].flags & PMU_BATT_CHARGING))
 				charging++;
 		}
 	}
 	if (real_count) {
-		time_units = (charge * 59) / (current * -1);
-		if(!charging)
-			battery_flag &= ~0x08;
+		if (current < 0) {
+			if (btype == PMU_BATT_TYPE_SMART)
+				time_units = (charge * 59) / (current * -1);
+			else
+				time_units = (charge * 16440) / (current * -60);
+		}
 		percentage /= real_count;
-		if (battery_flag & 0x08) {
+		if (charging > 0) {
 			battery_status = 0x03;
 			battery_flag = 0x08;
 		} else if (percentage <= APM_CRITICAL) {
@@ -516,6 +516,7 @@
 static int __init apm_emu_init(void)
 {
 	struct proc_dir_entry *apm_proc;
+	int retval;
 
 	if (sys_ctrler != SYS_CTRLER_PMU) {
 		printk(KERN_INFO "apm_emu: Requires a machine with a PMU.\n");
@@ -523,10 +524,18 @@
 	}
 		
 	apm_proc = create_proc_info_entry("apm", 0, NULL, apm_emu_get_info);
-	if (apm_proc)
-		SET_MODULE_OWNER(apm_proc);
+	if (!apm_proc) {
+		printk(KERN_ERR "apm_emu: create_proc_info_entry failed.\n");
+		return -ENOENT;
+	}
+	SET_MODULE_OWNER(apm_proc);
 
-	misc_register(&apm_device);
+	retval = misc_register(&apm_device);
+	if (retval < 0) {
+		printk(KERN_ERR "apm_emu: misc_register failed\n");
+		remove_proc_entry("apm", NULL);
+		return retval;
+	}
 
 	pmu_register_sleep_notifier(&apm_sleep_notifier);
 
diff -urN linux-2.4.22-pre2/drivers/macintosh/via-pmu.c linux-2.4.22-pre3/drivers/macintosh/via-pmu.c
--- linux-2.4.22-pre2/drivers/macintosh/via-pmu.c	2002-11-28 15:53:13.000000000 -0800
+++ linux-2.4.22-pre3/drivers/macintosh/via-pmu.c	2003-07-05 18:10:06.000000000 -0700
@@ -345,11 +345,6 @@
 	} else
 		pmu_kind = PMU_UNKNOWN;
 
-#ifdef CONFIG_PMAC_PBOOK
-	if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
-		can_sleep = 1;
-#endif /* CONFIG_PMAC_PBOOK */
-
 	via = (volatile unsigned char *) ioremap(vias->addrs->address, 0x2000);
 
 	out_8(&via[IER], IER_CLR | 0x7f);	/* disable all intrs */
@@ -410,6 +405,8 @@
 	bright_req_3.complete = 1;
 #ifdef CONFIG_PMAC_PBOOK
 	batt_req.complete = 1;
+	if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
+		can_sleep = 1;
 #endif
 
 	if (request_irq(vias->intrs[0].line, via_pmu_interrupt, 0, "VIA-PMU",
@@ -436,12 +433,20 @@
 
 #ifdef CONFIG_PMAC_PBOOK
   	if (machine_is_compatible("AAPL,3400/2400") ||
-  		machine_is_compatible("AAPL,3500"))
+  		machine_is_compatible("AAPL,3500")) {
+		int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+			NULL, PMAC_MB_INFO_MODEL, 0);
 		pmu_battery_count = 1;
-	else if (machine_is_compatible("AAPL,PowerBook1998") ||
-		machine_is_compatible("PowerBook1,1"))
+		if (mb == PMAC_TYPE_COMET)
+			pmu_batteries[0].flags |= PMU_BATT_TYPE_COMET;
+		else
+			pmu_batteries[0].flags |= PMU_BATT_TYPE_HOOPER;
+	} else if (machine_is_compatible("AAPL,PowerBook1998") ||
+		machine_is_compatible("PowerBook1,1")) {
 		pmu_battery_count = 2;
-	else {
+		pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART;
+		pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART;
+	} else {
 		struct device_node* prim = find_devices("power-mgt");
 		u32 *prim_info = NULL;
 		if (prim)
@@ -449,6 +454,9 @@
 		if (prim_info) {
 			/* Other stuffs here yet unknown */
 			pmu_battery_count = (prim_info[6] >> 16) & 0xff;
+			pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART;
+			if (pmu_battery_count > 1)
+				pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART;
 		}
 	}
 #endif /* CONFIG_PMAC_PBOOK */
@@ -558,148 +566,12 @@
 
 #ifdef CONFIG_PMAC_PBOOK
 
-/* 
- * WARNING ! This code probably needs some debugging... -- BenH.
+/* This new version of the code for 2400/3400/3500 powerbooks
+ * is inspired from the implementation in gkrellm-pmu
  */
-#ifdef NEW_OHARE_CODE
-static void __pmac
-done_battery_state_ohare(struct adb_request* req)
-{
-	unsigned int bat_flags = 0;
-	int current = 0;
-	unsigned int capa, max, voltage, time;
-	int lrange[] = { 0, 275, 850, 1680, 2325, 
-				2765, 3160, 3500, 3830, 4115, 
-				4360, 4585, 4795, 4990, 5170, 
-				5340, 5510, 5710, 5930, 6150, 
-				6370, 6500
-				};
-	
-	if (req->reply[0] & 0x01)
-		pmu_power_flags |= PMU_PWR_AC_PRESENT;
-	else
-		pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
-
-	if (req->reply[0] & 0x04) {
-		int vb, i, j, k, charge, pcharge;
-		bat_flags |= PMU_BATT_PRESENT;
-		vb = (req->reply[1] << 8) | req->reply[2];
-		voltage = ((vb * 2650) + 726650)/100;
-		vb *= 100;
-		current = req->reply[5];
-		if ((req->reply[0] & 0x01) == 0 && (current > 200))
-			vb += (current - 200) * 15;
-		else if (req->reply[0] & 0x02)
-			vb = (vb - 2000);
-	  	i = (33000 - vb) / 10;
-	  	j = i - (i % 100);
-		k = j/100;
-		if (k <= 0)
-	       		charge = 0;
-		else if (k >= 21)
-	       		charge = 650000;
-	  	else
-			charge = (lrange[k + 1] - lrange[k]) * (i - j) + (lrange[k] * 100);
-		charge = (1000 - charge / 650) / 10;
-		if (req->reply[0] & 0x40) {
-			pcharge = (req->reply[6] << 8) + req->reply[7];
-			if (pcharge > 6500)
-				pcharge = 6500;
-			pcharge *= 100;
-			pcharge = (1000 - pcharge / 650) / 10;
-			if (pcharge < charge)
-				charge = pcharge;
-		}
-		capa = charge;
-		max = 100;
-		time = (charge * 16440) / current;
-		current = -current;
-		
-	} else
-		capa = max = current = voltage = time = 0;
-
-	if (req->reply[0] & 0x02)
-		bat_flags |= PMU_BATT_CHARGING;
-
-	pmu_batteries[pmu_cur_battery].flags = bat_flags;
-	pmu_batteries[pmu_cur_battery].charge = capa;
-	pmu_batteries[pmu_cur_battery].max_charge = max;
-	pmu_batteries[pmu_cur_battery].current = current;
-	pmu_batteries[pmu_cur_battery].voltage = voltage;
-	pmu_batteries[pmu_cur_battery].time_remaining = time;
-}
-#else /* NEW_OHARE_CODE */
 static void __pmac
 done_battery_state_ohare(struct adb_request* req)
 {
-	unsigned int bat_flags = 0;
-	int current = 0;
-	unsigned int capa, max, voltage, time;
-	int lrange[] = { 0, 275, 850, 1680, 2325, 
-				2765, 3160, 3500, 3830, 4115, 
-				4360, 4585, 4795, 4990, 5170, 
-				5340, 5510, 5710, 5930, 6150, 
-				6370, 6500
-				};
-	
-	if (req->reply[0] & 0x01)
-		pmu_power_flags |= PMU_PWR_AC_PRESENT;
-	else
-		pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
-
-	if (req->reply[0] & 0x04) {
-		int vb, i, j, charge, pcharge;
-		bat_flags |= PMU_BATT_PRESENT;
-		vb = (req->reply[1] << 8) | req->reply[2];
-		voltage = ((vb * 2650) + 726650)/100;
-		current = *((signed char *)&req->reply[5]);
-		if ((req->reply[0] & 0x01) == 0 && (current > 200))
-			vb += (current - 200) * 15;
-		else if (req->reply[0] & 0x02)
-			vb = (vb - 10) * 100;
-	  	i = (33000 - vb) / 10;
-	  	j = i - (i % 100);
-	  	if (j <= 0)
-	       		charge = 0;
-	  	else if (j >= 21)
-	       		charge = 650000;
-	  	else
-			charge = (lrange[j + 1] - lrange[j]) * (i - j) + (lrange[j] * 100);
-		charge = (1000 - charge / 650) / 10;
-		if (req->reply[0] & 0x40) {
-			pcharge = (req->reply[6] << 8) + req->reply[7];
-			if (pcharge > 6500)
-				pcharge = 6500;
-			pcharge *= 100;
-			pcharge = (1000 - pcharge / 650) / 10;
-			if (pcharge < charge)
-				charge = pcharge;
-		}
-		capa = charge;
-		max = 100;
-		time = (charge * 274) / current;
-		current = -current;
-		
-	} else
-		capa = max = current = voltage = time = 0;
-
-	if ((req->reply[0] & 0x02) && (current > 0))
-		bat_flags |= PMU_BATT_CHARGING;
-	if (req->reply[0] & 0x04) /* CHECK THIS ONE */
-		bat_flags |= PMU_BATT_PRESENT;
-
-	pmu_batteries[pmu_cur_battery].flags = bat_flags;
-	pmu_batteries[pmu_cur_battery].charge = capa;
-	pmu_batteries[pmu_cur_battery].max_charge = max;
-	pmu_batteries[pmu_cur_battery].current = current;
-	pmu_batteries[pmu_cur_battery].voltage = voltage;
-	pmu_batteries[pmu_cur_battery].time_remaining = time;
-}
-#endif /* NEW_OHARE_CODE */
-
- static void __pmac
-done_battery_state_comet(struct adb_request* req)
-{
 	/* format:
 	 *  [0]    :  flags
 	 *    0x01 :  AC indicator
@@ -718,57 +590,62 @@
 	 *  [6][7] :  pcharge
 	 *              --tkoba
 	 */
+	unsigned int bat_flags = PMU_BATT_TYPE_HOOPER;
+	long pcharge, charge, vb, vmax, lmax;
+	long vmax_charging, vmax_charged;
+	long current, voltage, time, max;
+	int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+			NULL, PMAC_MB_INFO_MODEL, 0);
 
-	unsigned int bat_flags = 0;
-	int current = 0;
-	unsigned int max = 100;
-	unsigned int charge, voltage, time;
-	int lrange[] = { 0, 600, 750, 900, 1000, 1080, 
-				1180, 1250, 1300, 1340, 1360, 
-				1390, 1420, 1440, 1470, 1490, 
-				1520, 1550, 1580, 1610, 1650, 
-				1700
-				};
-	
 	if (req->reply[0] & 0x01)
 		pmu_power_flags |= PMU_PWR_AC_PRESENT;
 	else
 		pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
+	
+	if (mb == PMAC_TYPE_COMET) {
+		vmax_charged = 189;
+		vmax_charging = 213;
+		lmax = 6500;
+	} else {
+		vmax_charged = 330;
+		vmax_charging = 330;
+		lmax = 6500;
+	}
+	vmax = vmax_charged;
 
-	if (req->reply[0] & 0x04) {	/* battery exist */
-		int vb, i;
+	/* If battery installed */
+	if (req->reply[0] & 0x04) {
 		bat_flags |= PMU_BATT_PRESENT;
+		if (req->reply[0] & 0x02)
+			bat_flags |= PMU_BATT_CHARGING;
 		vb = (req->reply[1] << 8) | req->reply[2];
-		voltage = ((vb * 2650) + 726650)/100;
-		vb *= 10;
+		voltage = (vb * 265 + 72665) / 10;
 		current = req->reply[5];
-		if ((req->reply[0] & 0x01) == 0 && (current > 200))
-			vb += ((current - 200) * 3);	/* vb = 500<->1800 */
-		else if (req->reply[0] & 0x02)
-			vb = ((vb - 800) * 1700/13)/100;	/*  in charging vb = 1300<->2130 */
-
-		if (req->reply[0] & 0x20) {	/* full charged */
-			charge = max;
-		} else {
-			if (lrange[21] < vb)
-				charge = max;
-			else {
-				if (vb < lrange[1])
-					charge = 0;
-				else {
-					for (i=21; vb < lrange[i]; --i);
-					charge = (i * 100)/21;
-				}
-			}
-			if (charge > max) charge = max;
+		if ((req->reply[0] & 0x01) == 0) {
+			if (current > 200)
+				vb += ((current - 200) * 15)/100;
+		} else if (req->reply[0] & 0x02) {
+			vb = (vb * 97) / 100;
+			vmax = vmax_charging;
 		}
-		time = (charge * 72);
+		charge = (100 * vb) / vmax;
+		if (req->reply[0] & 0x40) {
+			pcharge = (req->reply[6] << 8) + req->reply[7];
+			if (pcharge > lmax)
+				pcharge = lmax;
+			pcharge *= 100;
+			pcharge = 100 - pcharge / lmax;
+			if (pcharge < charge)
+				charge = pcharge;
+		}
+		if (current > 0)
+			time = (charge * 16440) / current;
+		else
+			time = 0;
+		max = 100;
 		current = -current;
 	} else
-		max = current = voltage = time = 0;
-
-	if (req->reply[0] & 0x02)
-		bat_flags |= PMU_BATT_CHARGING;
+		charge = max = current = voltage = time = 0;
 
 	pmu_batteries[pmu_cur_battery].flags = bat_flags;
 	pmu_batteries[pmu_cur_battery].charge = charge;
@@ -800,7 +677,7 @@
 	 *  [8][9] : voltage
 	 */
 	 
-	unsigned int bat_flags = 0;
+	unsigned int bat_flags = PMU_BATT_TYPE_SMART;
 	int current;
 	unsigned int capa, max, voltage;
 	
@@ -858,17 +735,10 @@
 {
 	if (!batt_req.complete)
 		return;
-	if (pmu_kind == PMU_OHARE_BASED) {
-		int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
-			NULL, PMAC_MB_INFO_MODEL, 0);
-
-		if (mb == PMAC_TYPE_COMET)
-			pmu_request(&batt_req, done_battery_state_comet,
-				1, PMU_BATTERY_STATE);
-		else
-			pmu_request(&batt_req, done_battery_state_ohare,
-				1, PMU_BATTERY_STATE);
-	} else
+	if (pmu_kind == PMU_OHARE_BASED)
+		pmu_request(&batt_req, done_battery_state_ohare,
+			1, PMU_BATTERY_STATE);
+	else
 		pmu_request(&batt_req, done_battery_state_smart,
 			2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1);
 }
@@ -1220,9 +1090,14 @@
 static inline void
 pmu_done(struct adb_request *req)
 {
+	void (*done)(struct adb_request *) = req->done;
+	mb();
 	req->complete = 1;
-	if (req->done)
-		(*req->done)(req);
+    	/* Here, we assume that if the request has a done member, the
+    	 * struct request will survive to setting req->complete to 1
+    	 */
+	if (done)
+		(*done)(req);
 }
 
 static void __openfirmware
@@ -1557,7 +1432,8 @@
 			wait_for_ack();
 			send_byte(PMU_INT_ACK);
 			adb_int_pending = 0;
-no_free_slot:			
+no_free_slot:
+			;	
 		} else if (current_req)
 			pmu_start();
 	}
@@ -1714,6 +1590,259 @@
 	return via != 0;
 }
 
+struct pmu_i2c_hdr {
+	u8	bus;
+	u8	mode;
+	u8	bus2;
+	u8	address;
+	u8	sub_addr;
+	u8	comb_addr;
+	u8	count;
+};
+
+int
+pmu_i2c_combined_read(int bus, int addr, int subaddr,  u8* data, int len)
+{
+	struct adb_request	req;
+	struct pmu_i2c_hdr	*hdr = (struct pmu_i2c_hdr *)&req.data[1];
+	int retry;
+	int rc;
+
+	for (retry=0; retry<16; retry++) {
+		memset(&req, 0, sizeof(req));
+
+		hdr->bus = bus;
+		hdr->address = addr & 0xfe;
+		hdr->mode = PMU_I2C_MODE_COMBINED;
+		hdr->bus2 = 0;
+		hdr->sub_addr = subaddr;
+		hdr->comb_addr = addr | 1;
+		hdr->count = len;
+		
+		req.nbytes = sizeof(struct pmu_i2c_hdr) + 1;
+		req.reply_expected = 0;
+		req.reply_len = 0;
+		req.data[0] = PMU_I2C_CMD;
+		req.reply[0] = 0xff;
+		rc = pmu_queue_request(&req);
+		if (rc)
+			return rc;
+		while(!req.complete)
+			pmu_poll();
+		if (req.reply[0] == PMU_I2C_STATUS_OK)
+			break;
+		mdelay(15);
+	}
+	if (req.reply[0] != PMU_I2C_STATUS_OK)
+		return -1;
+
+	for (retry=0; retry<16; retry++) {
+		memset(&req, 0, sizeof(req));
+
+		mdelay(15);
+
+		hdr->bus = PMU_I2C_BUS_STATUS;
+		req.reply[0] = 0xff;
+		
+		req.nbytes = 2;
+		req.reply_expected = 0;
+		req.reply_len = 0;
+		req.data[0] = PMU_I2C_CMD;
+		rc = pmu_queue_request(&req);
+		if (rc)
+			return rc;
+		while(!req.complete)
+			pmu_poll();
+		if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) {
+			memcpy(data, &req.reply[1], req.reply_len - 1);
+			return req.reply_len - 1;
+		}
+	}
+	return -1;
+}
+
+int
+pmu_i2c_stdsub_write(int bus, int addr, int subaddr,  u8* data, int len)
+{
+	struct adb_request	req;
+	struct pmu_i2c_hdr	*hdr = (struct pmu_i2c_hdr *)&req.data[1];
+	int retry;
+	int rc;
+
+	for (retry=0; retry<16; retry++) {
+		memset(&req, 0, sizeof(req));
+
+		hdr->bus = bus;
+		hdr->address = addr & 0xfe;
+		hdr->mode = PMU_I2C_MODE_STDSUB;
+		hdr->bus2 = 0;
+		hdr->sub_addr = subaddr;
+		hdr->comb_addr = addr & 0xfe;
+		hdr->count = len;
+
+		req.data[0] = PMU_I2C_CMD;
+		memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len);
+		req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1;
+		req.reply_expected = 0;
+		req.reply_len = 0;
+		req.reply[0] = 0xff;
+		rc = pmu_queue_request(&req);
+		if (rc)
+			return rc;
+		while(!req.complete)
+			pmu_poll();
+		if (req.reply[0] == PMU_I2C_STATUS_OK)
+			break;
+		mdelay(15);
+	}
+	if (req.reply[0] != PMU_I2C_STATUS_OK)
+		return -1;
+
+	for (retry=0; retry<16; retry++) {
+		memset(&req, 0, sizeof(req));
+
+		mdelay(15);
+
+		hdr->bus = PMU_I2C_BUS_STATUS;
+		req.reply[0] = 0xff;
+		
+		req.nbytes = 2;
+		req.reply_expected = 0;
+		req.reply_len = 0;
+		req.data[0] = PMU_I2C_CMD;
+		rc = pmu_queue_request(&req);
+		if (rc)
+			return rc;
+		while(!req.complete)
+			pmu_poll();
+		if (req.reply[0] == PMU_I2C_STATUS_OK)
+			return len;
+	}
+	return -1;
+}
+
+int
+pmu_i2c_simple_read(int bus, int addr,  u8* data, int len)
+{
+	struct adb_request	req;
+	struct pmu_i2c_hdr	*hdr = (struct pmu_i2c_hdr *)&req.data[1];
+	int retry;
+	int rc;
+
+	for (retry=0; retry<16; retry++) {
+		memset(&req, 0, sizeof(req));
+
+		hdr->bus = bus;
+		hdr->address = addr | 1;
+		hdr->mode = PMU_I2C_MODE_SIMPLE;
+		hdr->bus2 = 0;
+		hdr->sub_addr = 0;
+		hdr->comb_addr = 0;
+		hdr->count = len;
+
+		req.data[0] = PMU_I2C_CMD;
+		req.nbytes = sizeof(struct pmu_i2c_hdr) + 1;
+		req.reply_expected = 0;
+		req.reply_len = 0;
+		req.reply[0] = 0xff;
+		rc = pmu_queue_request(&req);
+		if (rc)
+			return rc;
+		while(!req.complete)
+			pmu_poll();
+		if (req.reply[0] == PMU_I2C_STATUS_OK)
+			break;
+		mdelay(15);
+	}
+	if (req.reply[0] != PMU_I2C_STATUS_OK)
+		return -1;
+
+	for (retry=0; retry<16; retry++) {
+		memset(&req, 0, sizeof(req));
+
+		mdelay(15);
+
+		hdr->bus = PMU_I2C_BUS_STATUS;
+		req.reply[0] = 0xff;
+		
+		req.nbytes = 2;
+		req.reply_expected = 0;
+		req.reply_len = 0;
+		req.data[0] = PMU_I2C_CMD;
+		rc = pmu_queue_request(&req);
+		if (rc)
+			return rc;
+		while(!req.complete)
+			pmu_poll();
+		if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) {
+			memcpy(data, &req.reply[1], req.reply_len - 1);
+			return req.reply_len - 1;
+		}
+	}
+	return -1;
+}
+
+int
+pmu_i2c_simple_write(int bus, int addr,  u8* data, int len)
+{
+	struct adb_request	req;
+	struct pmu_i2c_hdr	*hdr = (struct pmu_i2c_hdr *)&req.data[1];
+	int retry;
+	int rc;
+
+	for (retry=0; retry<16; retry++) {
+		memset(&req, 0, sizeof(req));
+
+		hdr->bus = bus;
+		hdr->address = addr & 0xfe;
+		hdr->mode = PMU_I2C_MODE_SIMPLE;
+		hdr->bus2 = 0;
+		hdr->sub_addr = 0;
+		hdr->comb_addr = 0;
+		hdr->count = len;
+
+		req.data[0] = PMU_I2C_CMD;
+		memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len);
+		req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1;
+		req.reply_expected = 0;
+		req.reply_len = 0;
+		req.reply[0] = 0xff;
+		rc = pmu_queue_request(&req);
+		if (rc)
+			return rc;
+		while(!req.complete)
+			pmu_poll();
+		if (req.reply[0] == PMU_I2C_STATUS_OK)
+			break;
+		mdelay(15);
+	}
+	if (req.reply[0] != PMU_I2C_STATUS_OK)
+		return -1;
+
+	for (retry=0; retry<16; retry++) {
+		memset(&req, 0, sizeof(req));
+
+		mdelay(15);
+
+		hdr->bus = PMU_I2C_BUS_STATUS;
+		req.reply[0] = 0xff;
+		
+		req.nbytes = 2;
+		req.reply_expected = 0;
+		req.reply_len = 0;
+		req.data[0] = PMU_I2C_CMD;
+		rc = pmu_queue_request(&req);
+		if (rc)
+			return rc;
+		while(!req.complete)
+			pmu_poll();
+		if (req.reply[0] == PMU_I2C_STATUS_OK)
+			return len;
+	}
+	return -1;
+}
+
+
 #if defined(DEBUG_SLEEP) || defined(DEBUG_FREQ)
 /* N.B. This doesn't work on the 3400 */
 void
@@ -2794,6 +2923,10 @@
 EXPORT_SYMBOL(pmu_poll);
 EXPORT_SYMBOL(pmu_suspend);
 EXPORT_SYMBOL(pmu_resume);
+EXPORT_SYMBOL(pmu_i2c_combined_read);
+EXPORT_SYMBOL(pmu_i2c_stdsub_write);
+EXPORT_SYMBOL(pmu_i2c_simple_read);
+EXPORT_SYMBOL(pmu_i2c_simple_write);
 #ifdef CONFIG_PMAC_PBOOK
 EXPORT_SYMBOL(pmu_register_sleep_notifier);
 EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
diff -urN linux-2.4.22-pre2/drivers/media/video/meye.c linux-2.4.22-pre3/drivers/media/video/meye.c
--- linux-2.4.22-pre2/drivers/media/video/meye.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/media/video/meye.c	2003-07-05 18:10:07.000000000 -0700
@@ -161,6 +161,34 @@
 	}
 }
 
+/****************************************************************************/
+/* dma_alloc_coherent / dma_free_coherent ported from 2.5                  */
+/****************************************************************************/
+
+void *dma_alloc_coherent(struct pci_dev *dev, size_t size,
+                           dma_addr_t *dma_handle, int gfp)
+{
+        void *ret;
+        /* ignore region specifiers */
+        gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+        if (dev == NULL || ((u32)dev->dma_mask < 0xffffffff))
+                gfp |= GFP_DMA;
+        ret = (void *)__get_free_pages(gfp, get_order(size));
+
+        if (ret != NULL) { 
+                memset(ret, 0, size);
+                *dma_handle = virt_to_phys(ret);
+        }       
+        return ret;
+}
+
+void dma_free_coherent(struct pci_dev *dev, size_t size,
+                         void *vaddr, dma_addr_t dma_handle)
+{
+        free_pages((unsigned long)vaddr, get_order(size));
+}
+
 /* return a page table pointing to N pages of locked memory */
 static int ptable_alloc(void) {
 	u32 *pt;
@@ -168,9 +196,10 @@
 
 	memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
 
-	meye.mchip_ptable[MCHIP_NB_PAGES] = pci_alloc_consistent(meye.mchip_dev, 
-								 PAGE_SIZE, 
-								 &meye.mchip_dmahandle);
+	meye.mchip_ptable[MCHIP_NB_PAGES] = dma_alloc_coherent(meye.mchip_dev, 
+							       PAGE_SIZE, 
+							       &meye.mchip_dmahandle,
+							       GFP_KERNEL);
 	if (!meye.mchip_ptable[MCHIP_NB_PAGES]) {
 		meye.mchip_dmahandle = 0;
 		return -1;
@@ -178,16 +207,17 @@
 
 	pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
 	for (i = 0; i < MCHIP_NB_PAGES; i++) {
-		meye.mchip_ptable[i] = pci_alloc_consistent(meye.mchip_dev, 
-							    PAGE_SIZE,
-							    pt);
+		meye.mchip_ptable[i] = dma_alloc_coherent(meye.mchip_dev, 
+							  PAGE_SIZE,
+							  pt,
+							  GFP_KERNEL);
 		if (!meye.mchip_ptable[i]) {
 			int j;
 			pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
 			for (j = 0; j < i; ++j) {
-				pci_free_consistent(meye.mchip_dev,
-						    PAGE_SIZE,
-						    meye.mchip_ptable[j], *pt);
+				dma_free_coherent(meye.mchip_dev,
+						  PAGE_SIZE,
+						  meye.mchip_ptable[j], *pt);
 				pt++;
 			}
 			meye.mchip_dmahandle = 0;
@@ -205,17 +235,17 @@
 	pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
 	for (i = 0; i < MCHIP_NB_PAGES; i++) {
 		if (meye.mchip_ptable[i])
-			pci_free_consistent(meye.mchip_dev, 
-					    PAGE_SIZE, 
-					    meye.mchip_ptable[i], *pt);
+			dma_free_coherent(meye.mchip_dev, 
+					  PAGE_SIZE, 
+					  meye.mchip_ptable[i], *pt);
 		pt++;
 	}
 
 	if (meye.mchip_ptable[MCHIP_NB_PAGES])
-		pci_free_consistent(meye.mchip_dev, 
-				    PAGE_SIZE, 
-				    meye.mchip_ptable[MCHIP_NB_PAGES], 
-				    meye.mchip_dmahandle);
+		dma_free_coherent(meye.mchip_dev, 
+				  PAGE_SIZE, 
+				  meye.mchip_ptable[MCHIP_NB_PAGES],
+				  meye.mchip_dmahandle);
 
 	memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
 	meye.mchip_dmahandle = 0;
@@ -614,25 +644,25 @@
 /* stop any existing HIC action and wait for any dma to complete then
    reset the dma engine */
 static void mchip_hic_stop(void) {
-	int i = 0;
+	int i, j;
 
 	meye.mchip_mode = MCHIP_HIC_MODE_NOOP;
-	if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY)) 
+	if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY))
 		return;
-	mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
-	mchip_delay(MCHIP_HIC_CMD, 0);
-	while (!mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) {
-		/*  resetting HIC */
+	for (i = 0; i < 20; ++i) {
 		mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
 		mchip_delay(MCHIP_HIC_CMD, 0);
+		for (j = 0; j < 100; ++j) {
+			if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
+				return;
+			wait_ms(1);
+		}
+		printk(KERN_ERR "meye: need to reset HIC!\n");
+	
 		mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET);
 		wait_ms(250);
-		if (i++ > 20) {
-			printk(KERN_ERR "meye: resetting HIC hanged!\n");
-			break;
-		}
 	}
-	wait_ms(100);
+	printk(KERN_ERR "meye: resetting HIC hanged!\n");
 }
 
 /****************************************************************************/
@@ -1392,6 +1422,8 @@
 
 	mchip_hic_stop();
 
+	mchip_dma_free();
+
 	/* disable interrupts */
 	mchip_set(MCHIP_MM_INTA, 0x0);
 
@@ -1404,8 +1436,6 @@
 
 	pci_disable_device(meye.mchip_dev);
 
-	mchip_dma_free();
-
 	if (meye.grab_fbuffer)
 		rvfree(meye.grab_fbuffer, gbuffers*gbufsize);
 
diff -urN linux-2.4.22-pre2/drivers/media/video/meye.h linux-2.4.22-pre3/drivers/media/video/meye.h
--- linux-2.4.22-pre2/drivers/media/video/meye.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/media/video/meye.h	2003-07-05 18:10:07.000000000 -0700
@@ -31,7 +31,7 @@
 #define _MEYE_PRIV_H_
 
 #define MEYE_DRIVER_MAJORVERSION	1
-#define MEYE_DRIVER_MINORVERSION	6
+#define MEYE_DRIVER_MINORVERSION	7
 
 #include <linux/config.h>
 #include <linux/types.h>
diff -urN linux-2.4.22-pre2/drivers/mtd/maps/octagon-5066.c linux-2.4.22-pre3/drivers/mtd/maps/octagon-5066.c
--- linux-2.4.22-pre2/drivers/mtd/maps/octagon-5066.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/mtd/maps/octagon-5066.c	2003-07-05 18:10:12.000000000 -0700
@@ -244,7 +244,6 @@
 	}
 	if (OctProbe() != 0) {
 		printk(KERN_NOTICE "5066: Octagon Probe Failed, is this an Octagon 5066 SBC?\n");
-		iounmap((void *)iomapadr);
 		ret = -EAGAIN;
 		goto out_unmap;
 	}
diff -urN linux-2.4.22-pre2/drivers/net/3c59x.c linux-2.4.22-pre3/drivers/net/3c59x.c
--- linux-2.4.22-pre2/drivers/net/3c59x.c	2003-07-05 18:09:18.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/3c59x.c	2003-07-05 18:10:12.000000000 -0700
@@ -166,6 +166,11 @@
     - Rename wait_for_completion() to issue_and_wait() to avoid completion.h
       clash.
 
+    LK1.1.18ac 01Jul02 akpm
+     - Fix for undocumented transceiver power-up bit on some 3c566B's
+       (Donald Becker, Rahul Karnik)
+ 
+
     - See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3 for more details.
     - Also see Documentation/networking/vortex.txt
 */
@@ -181,8 +186,8 @@
 
 
 #define DRV_NAME	"3c59x"
-#define DRV_VERSION	"LK1.1.16"
-#define DRV_RELDATE	"19 July 2001"
+#define DRV_VERSION	"LK1.1.18-ac"
+#define DRV_RELDATE	"1 July 2002"
 
 
 
@@ -400,7 +405,7 @@
 	EEPROM_8BIT=0x10,	/* AKPM: Uses 0x230 as the base bitmaps for EEPROM reads */
 	HAS_PWR_CTRL=0x20, HAS_MII=0x40, HAS_NWAY=0x80, HAS_CB_FNS=0x100,
 	INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400, MAX_COLLISION_RESET=0x800,
-	EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000 };
+	EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000, WNO_XCVR_PWR=0x4000 };
 
 enum vortex_chips {
 	CH_3C590 = 0,
@@ -424,6 +429,7 @@
 	CH_3C905B_2,
 	CH_3C905B_FX,
 	CH_3C905C,
+	CH_3C905C2,
 	CH_3C980,
 	CH_3C9805,
 
@@ -497,6 +503,8 @@
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 	{"3c905C Tornado",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
+	{"3c905C Tornado 2",
+	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
 	{"3c980 Cyclone",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 	{"3c980C Python-T",
@@ -511,7 +519,7 @@
 									HAS_HWCKSM, 128, },
 	{"3c556B Laptop Hurricane",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR|
-									HAS_HWCKSM, 128, },
+	                                WNO_XCVR_PWR|HAS_HWCKSM, 128, },
 	{"3c575 [Megahertz] 10/100 LAN 	CardBus",
 	PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
 
@@ -568,6 +576,7 @@
 	{ 0x10B7, 0x9058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_2 },
 	{ 0x10B7, 0x905A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_FX },
 	{ 0x10B7, 0x9200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C },
+	{ 0x10B7, 0x9201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C2 },
 	{ 0x10B7, 0x9800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C980 },
 	{ 0x10B7, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9805 },
 
@@ -1199,6 +1208,10 @@
 		if (vp->drv_flags & INVERT_MII_PWR)
 			n |= 0x4000;
 		outw(n, ioaddr + Wn2_ResetOptions);
+		if (vp->drv_flags & WNO_XCVR_PWR) {
+			EL3WINDOW(0);
+			outw(0x0800, ioaddr);
+		}
 	}
 
 	/* Extract our information from the EEPROM data. */
diff -urN linux-2.4.22-pre2/drivers/net/8139too.c linux-2.4.22-pre3/drivers/net/8139too.c
--- linux-2.4.22-pre2/drivers/net/8139too.c	2003-07-05 18:09:18.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/8139too.c	2003-07-05 18:10:12.000000000 -0700
@@ -2074,7 +2074,7 @@
 		RTL_W16 (IntrStatus, ackstat);
 
 		DPRINTK ("%s: interrupt  status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n",
-			 dev->name, ackstat, status, RTL_R16 (IntrStatus));
+			 dev->name, status, ackstat, RTL_R16 (IntrStatus));
 
 		if (netif_running (dev) && (status & RxAckBits))
 			rtl8139_rx_interrupt (dev, tp, ioaddr);
diff -urN linux-2.4.22-pre2/drivers/net/acenic.c linux-2.4.22-pre3/drivers/net/acenic.c
--- linux-2.4.22-pre2/drivers/net/acenic.c	2003-07-05 18:09:18.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/acenic.c	2003-07-05 18:10:13.000000000 -0700
@@ -3019,9 +3019,6 @@
 		return 0;
 
 	case ETHTOOL_SSET:
-		if(!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
 		link = readl(&regs->GigLnkState);
 		if (link & LNK_1000MB)
 			speed = SPEED_1000;
diff -urN linux-2.4.22-pre2/drivers/net/atari_pamsnet.c linux-2.4.22-pre3/drivers/net/atari_pamsnet.c
--- linux-2.4.22-pre2/drivers/net/atari_pamsnet.c	2001-10-16 21:56:29.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/atari_pamsnet.c	2003-07-05 18:10:13.000000000 -0700
@@ -170,7 +170,7 @@
 
 static void pamsnet_intr(int irq, void *data, struct pt_regs *fp);
 
-static struct timer_list pamsnet_timer = { function: amsnet_tick };
+static struct timer_list pamsnet_timer = { function: pamsnet_tick };
 
 #define STRAM_ADDR(a)	(((a) & 0xff000000) == 0)
 
diff -urN linux-2.4.22-pre2/drivers/net/bmac.c linux-2.4.22-pre3/drivers/net/bmac.c
--- linux-2.4.22-pre2/drivers/net/bmac.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/bmac.c	2003-07-05 18:10:13.000000000 -0700
@@ -18,6 +18,8 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
+#include <linux/ethtool.h>
+#include <asm/uaccess.h>
 #include <asm/prom.h>
 #include <asm/dbdma.h>
 #include <asm/io.h>
@@ -67,7 +69,6 @@
 	volatile struct dbdma_cmd *tx_cmds;	/* xmit dma command list */
 	volatile struct dbdma_cmd *rx_cmds;	/* recv dma command list */
 	struct device_node *node;
-	int is_bmac_plus;
 	struct sk_buff *rx_bufs[N_RX_RING];
 	int rx_fill;
 	int rx_empty;
@@ -80,6 +81,8 @@
 	int timeout_active;
 	int sleeping;
 	int opened;
+	int is_bmac_plus;
+	u32 device_id;
 	unsigned short hash_use_count[64];
 	unsigned short hash_table_mask[4];
 	struct net_device *next_bmac;
@@ -153,6 +156,7 @@
 static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev);
 static struct net_device_stats *bmac_stats(struct net_device *dev);
 static void bmac_set_multicast(struct net_device *dev);
+static int bmac_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 static void bmac_reset_and_enable(struct net_device *dev);
 static void bmac_start_chip(struct net_device *dev);
 static void bmac_init_chip(struct net_device *dev);
@@ -1053,7 +1057,7 @@
 {
 	struct dev_mc_list *dmi = dev->mc_list;
 	char *addrs;
-	int i, j, bit, byte;
+	int i;
 	unsigned short rx_cfg;
 	u32 crc;
 
@@ -1189,7 +1193,7 @@
 read_srom(struct net_device *dev, unsigned int addr, unsigned int addr_len)
 {
 	unsigned short data, val;
-	int i;
+	unsigned int i;
 
 	/* send out the address we want to read from */
 	for (i = 0; i < addr_len; i++)	{
@@ -1303,6 +1307,7 @@
 	struct bmac_data *bp;
 	unsigned char *addr;
 	struct net_device *dev;
+	u32 *deviceid;
 
 	if (bmac->n_addrs != 3 || bmac->n_intrs != 3) {
 		printk(KERN_ERR "can't use BMAC %s: need 3 addrs and 3 intrs\n",
@@ -1356,6 +1361,10 @@
 		goto err_out;
 	dev->irq = bmac->intrs[0].line;
 
+	deviceid = (u32 *)get_property(bmac, "device-id", NULL);
+	if (deviceid)
+		bp->device_id = *deviceid;
+
 	bmac_enable_and_reset_chip(dev);
 	bmwrite(dev, INTDISABLE, DisableAll);
 
@@ -1378,6 +1387,7 @@
 	dev->get_stats = bmac_stats;
 	dev->set_multicast_list = bmac_set_multicast;
 	dev->set_mac_address = bmac_set_address;
+	dev->do_ioctl = bmac_do_ioctl;
 
 	bmac_get_station_address(dev, addr);
 	if (bmac_verify_checksum(dev) != 0)
@@ -1451,6 +1461,56 @@
 	kfree(dev);
 }
 
+static int bmac_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	struct bmac_data *bp = (struct bmac_data *) dev->priv;
+	u32 ethcmd;
+
+	if (get_user(ethcmd, (u32 *)useraddr))
+		return -EFAULT;
+
+	switch (ethcmd) {
+	case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+		strcpy (info.driver, "bmac");
+		info.version[0] = '\0';
+		snprintf(info.fw_version, 31, "chip id %x", bp->device_id);
+		if (copy_to_user (useraddr, &info, sizeof (info)))
+			return -EFAULT;
+		return 0;
+	}
+
+	case ETHTOOL_GSET:
+	case ETHTOOL_SSET:
+	case ETHTOOL_NWAY_RST:
+	case ETHTOOL_GLINK:
+	case ETHTOOL_GMSGLVL:
+	case ETHTOOL_SMSGLVL:
+	default:
+		;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static int bmac_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	switch(cmd) {
+	case SIOCETHTOOL:
+		return bmac_ethtool_ioctl(dev, (void *) ifr->ifr_data);
+
+	case SIOCGMIIPHY:
+	case SIOCDEVPRIVATE:
+	case SIOCGMIIREG:
+	case SIOCDEVPRIVATE+1:
+	case SIOCSMIIREG:
+	case SIOCDEVPRIVATE+2:
+	default:
+		;
+	}
+	return -EOPNOTSUPP;
+}
+
 static int bmac_open(struct net_device *dev)
 {
 	struct bmac_data *bp = (struct bmac_data *) dev->priv;
diff -urN linux-2.4.22-pre2/drivers/net/bonding/bond_3ad.c linux-2.4.22-pre3/drivers/net/bonding/bond_3ad.c
--- linux-2.4.22-pre2/drivers/net/bonding/bond_3ad.c	2003-07-05 18:09:18.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/bonding/bond_3ad.c	2003-07-05 18:10:13.000000000 -0700
@@ -37,6 +37,16 @@
  * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
  *	- Renamed bond_3ad_link_status_changed() to
  *	  bond_3ad_handle_link_change() for compatibility with TLB.
+ *
+ * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
+ *	- Fix long fail over time when releasing last slave of an active
+ *	  aggregator - send LACPDU on unbind of slave to tell partner this
+ *	  port is no longer aggregatable.
+ *
+ * 2003/06/25 - Tsippy Mendelson <tsippy.mendelson at intel dot com>
+ *	- Send LACPDU as highest priority packet to further fix the above
+ *	  problem on very high Tx traffic load where packets may get dropped
+ *	  by the slave.
  */
 
 #include <linux/skbuff.h>
@@ -45,6 +55,7 @@
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
 #include <linux/if_bonding.h>
+#include <linux/pkt_sched.h>
 #include "bonding.h"
 #include "bond_3ad.h"
 
@@ -905,6 +916,7 @@
 	skb->mac.raw = skb->data;
 	skb->nh.raw = skb->data + ETH_HLEN;
 	skb->protocol = PKT_TYPE_LACPDU;
+	skb->priority = TC_PRIO_CONTROL;
 
 	lacpdu_header = (struct lacpdu_header *)skb_put(skb, length);
 
diff -urN linux-2.4.22-pre2/drivers/net/bonding/bond_3ad.h linux-2.4.22-pre3/drivers/net/bonding/bond_3ad.h
--- linux-2.4.22-pre2/drivers/net/bonding/bond_3ad.h	2003-07-05 18:09:18.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/bonding/bond_3ad.h	2003-07-05 18:10:13.000000000 -0700
@@ -165,7 +165,7 @@
 	//  = 0x02  (marker response information)
 	u8 marker_length;	 //  = 0x16
 	u16 requester_port;	 //   The number assigned to the port by the requester
-	struct mac_addr requester_system;      //   The requester’s system id
+	struct mac_addr requester_system;      //   The requester's system id
 	u32 requester_transaction_id;	//   The transaction id allocated by the requester,
 	u16 pad;		 //  = 0
 	u8 tlv_type_terminator;	     //  = 0x00
diff -urN linux-2.4.22-pre2/drivers/net/bonding/bond_alb.c linux-2.4.22-pre3/drivers/net/bonding/bond_alb.c
--- linux-2.4.22-pre2/drivers/net/bonding/bond_alb.c	2003-07-05 18:09:18.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/bonding/bond_alb.c	2003-07-05 18:10:13.000000000 -0700
@@ -17,6 +17,13 @@
  *
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
+ *
+ *
+ * Changes:
+ *
+ * 2003/06/25 - Shmulik Hen <shmulik.hen at intel dot com>
+ *	- Fixed signed/unsigned calculation errors that caused load sharing
+ *	  to collapse to one slave under very heavy UDP Tx stress.
  */
 
 #include <linux/skbuff.h>
@@ -246,7 +253,7 @@
 {
 	struct slave *slave;
 	struct slave *least_loaded;
-	u32 curr_gap, max_gap;
+	s64 curr_gap, max_gap;
 
 	/* Find the first enabled slave */
 	slave = bond_get_first_slave(bond);
@@ -262,15 +269,15 @@
 	}
 
 	least_loaded = slave;
-	max_gap = (slave->speed * 1000000) -
-		  (SLAVE_TLB_INFO(slave).load * 8);
+	max_gap = (s64)(slave->speed * 1000000) -
+			(s64)(SLAVE_TLB_INFO(slave).load * 8);
 
 	/* Find the slave with the largest gap */
 	slave = bond_get_next_slave(bond, slave);
 	while (slave) {
 		if (SLAVE_IS_OK(slave)) {
-			curr_gap = (slave->speed * 1000000) -
-				   (SLAVE_TLB_INFO(slave).load * 8);
+			curr_gap = (s64)(slave->speed * 1000000) -
+					(s64)(SLAVE_TLB_INFO(slave).load * 8);
 			if (max_gap < curr_gap) {
 				least_loaded = slave;
 				max_gap = curr_gap;
diff -urN linux-2.4.22-pre2/drivers/net/bonding/bond_main.c linux-2.4.22-pre3/drivers/net/bonding/bond_main.c
--- linux-2.4.22-pre2/drivers/net/bonding/bond_main.c	2003-07-05 18:09:18.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/bonding/bond_main.c	2003-07-05 18:10:13.000000000 -0700
@@ -385,6 +385,9 @@
  *	- In conjunction with fix for ifenslave -c, in
  *	  bond_change_active(), changing to the already active slave
  *	  is no longer an error (it successfully does nothing).
+ *
+ * 2003/06/30 - Amir Noam <amir.noam at intel dot com>
+ * 	- Fixed bond_change_active() for ALB/TLB modes.
  */
 
 #include <linux/config.h>
@@ -429,8 +432,8 @@
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION		"2.2.11"
-#define DRV_RELDATE		"May 29, 2003"
+#define DRV_VERSION		"2.2.14"
+#define DRV_RELDATE		"June 30, 2003"
 #define DRV_NAME		"bonding"
 #define DRV_DESCRIPTION		"Ethernet Channel Bonding Driver"
 
@@ -1761,8 +1764,11 @@
 	    (oldactive != NULL)&&
 	    (newactive->link == BOND_LINK_UP)&&
 	    IS_UP(newactive->dev)) {
-		bond_set_slave_inactive_flags(oldactive);
-		bond_set_slave_active_flags(newactive);
+		if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+			bond_set_slave_inactive_flags(oldactive);
+			bond_set_slave_active_flags(newactive);
+		}
+
 		bond_mc_update(bond, newactive, oldactive);
 		bond_assign_current_slave(bond, newactive);
 		printk("%s : activate %s(old : %s)\n",
diff -urN linux-2.4.22-pre2/drivers/net/e100/e100_main.c linux-2.4.22-pre3/drivers/net/e100/e100_main.c
--- linux-2.4.22-pre2/drivers/net/e100/e100_main.c	2003-07-05 18:09:18.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/e100/e100_main.c	2003-07-05 18:10:14.000000000 -0700
@@ -3422,10 +3422,6 @@
 	int ethtool_new_speed_duplex;
 	struct ethtool_cmd ecmd;
 
-	if (!capable(CAP_NET_ADMIN)) {
-		return -EPERM;
-	}
-
 	bdp = dev->priv;
 	if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd))) {
 		return -EFAULT;
@@ -3543,8 +3539,6 @@
 	void *addr = ifr->ifr_data;
 	u16 mdi_reg;
 
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
 	bdp = dev->priv;
 
 	if(copy_from_user(&regs, addr, sizeof(regs)))
@@ -3572,9 +3566,6 @@
 {
 	struct e100_private *bdp;
 
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
 	bdp = dev->priv;
 
 	if ((bdp->speed_duplex_caps & SUPPORTED_Autoneg) &&
@@ -3630,9 +3621,6 @@
 	void *ptr;
 	u8 *eeprom_data_bytes = (u8 *)eeprom_data;
 
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
 	bdp = dev->priv;
 
 	if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd)))
@@ -3910,9 +3898,6 @@
 	struct ethtool_wolinfo wolinfo;
 	int res = 0;
 
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
 	bdp = dev->priv;
 
 	if (copy_from_user(&wolinfo, ifr->ifr_data, sizeof (wolinfo))) {
diff -urN linux-2.4.22-pre2/drivers/net/e1000/e1000_ethtool.c linux-2.4.22-pre3/drivers/net/e1000/e1000_ethtool.c
--- linux-2.4.22-pre2/drivers/net/e1000/e1000_ethtool.c	2003-07-05 18:09:18.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/e1000/e1000_ethtool.c	2003-07-05 18:10:15.000000000 -0700
@@ -1289,8 +1289,6 @@
 	}
 	case ETHTOOL_SSET: {
 		struct ethtool_cmd ecmd;
-		if(!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		if(copy_from_user(&ecmd, addr, sizeof(ecmd)))
 			return -EFAULT;
 		return e1000_ethtool_sset(adapter, &ecmd);
@@ -1363,8 +1361,6 @@
 		return 0;
 	}
 	case ETHTOOL_NWAY_RST: {
-		if(!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		if(netif_running(netdev)) {
 			e1000_down(adapter);
 			e1000_up(adapter);
@@ -1393,8 +1389,6 @@
 	}
 	case ETHTOOL_SWOL: {
 		struct ethtool_wolinfo wol;
-		if(!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		if(copy_from_user(&wol, addr, sizeof(wol)) != 0)
 			return -EFAULT;
 		return e1000_ethtool_swol(adapter, &wol);
@@ -1436,9 +1430,6 @@
 	case ETHTOOL_SEEPROM: {
 		struct ethtool_eeprom eeprom;
 
-		if(!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
 		if(copy_from_user(&eeprom, addr, sizeof(eeprom)))
 			return -EFAULT;
 
@@ -1470,9 +1461,6 @@
 		} test = { {ETHTOOL_TEST} };
 		int err;
 
-		if(!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
 		if(copy_from_user(&test.eth_test, addr, sizeof(test.eth_test)))
 			return -EFAULT;
 
diff -urN linux-2.4.22-pre2/drivers/net/gmac.c linux-2.4.22-pre3/drivers/net/gmac.c
--- linux-2.4.22-pre2/drivers/net/gmac.c	2002-11-28 15:53:13.000000000 -0800
+++ linux-2.4.22-pre3/drivers/net/gmac.c	2003-07-05 18:10:17.000000000 -0700
@@ -1622,6 +1622,7 @@
 	gm->of_node = gmac;
 	if (!request_OF_resource(gmac, 0, " (gmac)")) {
 		printk(KERN_ERR "GMAC: can't request IO resource !\n");
+		gm->of_node = NULL;
 		goto out_unreg;
 	}
 	dev->base_addr = gmac->addrs[0].address;
diff -urN linux-2.4.22-pre2/drivers/net/ioc3-eth.c linux-2.4.22-pre3/drivers/net/ioc3-eth.c
--- linux-2.4.22-pre2/drivers/net/ioc3-eth.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/ioc3-eth.c	2003-07-05 18:10:17.000000000 -0700
@@ -1841,9 +1841,6 @@
 				return -EFAULT;
 			return 0;
 		} else if (ecmd.cmd == ETHTOOL_SSET) {
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
-
 			/* Verify the settings we care about. */
 			if (ecmd.autoneg != AUTONEG_ENABLE &&
 			    ecmd.autoneg != AUTONEG_DISABLE)
diff -urN linux-2.4.22-pre2/drivers/net/irda/ma600.c linux-2.4.22-pre3/drivers/net/irda/ma600.c
--- linux-2.4.22-pre2/drivers/net/irda/ma600.c	2002-11-28 15:53:13.000000000 -0800
+++ linux-2.4.22-pre3/drivers/net/irda/ma600.c	2003-07-05 18:10:17.000000000 -0700
@@ -51,9 +51,9 @@
 	#undef ASSERT(expr, func)
 	#define ASSERT(expr, func) \
 	if(!(expr)) { \
-	        printk( "Assertion failed! %s,%s,%s,line=%d\n",\
-        	#expr,__FILE__,__FUNCTION__,__LINE__); \
-	        ##func}
+		printk( "Assertion failed! %s,%s,%s,line=%d\n",\
+		#expr,__FILE__,__FUNCTION__,__LINE__); \
+		func}
 #endif
 
 /* convert hex value to ascii hex */
diff -urN linux-2.4.22-pre2/drivers/net/mac8390.c linux-2.4.22-pre3/drivers/net/mac8390.c
--- linux-2.4.22-pre2/drivers/net/mac8390.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/mac8390.c	2003-07-05 18:10:17.000000000 -0700
@@ -380,7 +380,7 @@
 #if LINUX_VERSION_CODE > 0x20118
 MODULE_AUTHOR("David Huggins-Daines <dhd@debian.org> and others");
 MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver");
-MODUEL_LICENSE("GPL");
+MODULE_LICENSE("GPL");
 #endif
 
 int init_module(void)
diff -urN linux-2.4.22-pre2/drivers/net/mace.c linux-2.4.22-pre3/drivers/net/mace.c
--- linux-2.4.22-pre2/drivers/net/mace.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/mace.c	2003-07-05 18:10:18.000000000 -0700
@@ -1,8 +1,12 @@
 /*
  * Network device driver for the MACE ethernet controller on
  * Apple Powermacs.  Assumes it's under a DBDMA controller.
+ * 
+ * MACE is beleived to be an AMD 79C940
  *
  * Copyright (C) 1996 Paul Mackerras.
+ * 
+ * TODO: Use a spinlock for smp safety (backport 2.5 version ?)
  */
 
 #include <linux/config.h>
@@ -16,6 +20,8 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
+#include <linux/ethtool.h>
+#include <asm/uaccess.h>
 #include <asm/prom.h>
 #include <asm/dbdma.h>
 #include <asm/io.h>
@@ -82,7 +88,10 @@
 static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
 static struct net_device_stats *mace_stats(struct net_device *dev);
 static void mace_set_multicast(struct net_device *dev);
+static int mace_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+static int mace_ethtool_ioctl(struct net_device *dev, void *useraddr);
 static void mace_reset(struct net_device *dev);
+static void mace_restart(struct net_device *dev);
 static int mace_set_address(struct net_device *dev, void *addr);
 static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void mace_txdma_intr(int irq, void *dev_id, struct pt_regs *regs);
@@ -226,6 +235,7 @@
 	dev->get_stats = mace_stats;
 	dev->set_multicast_list = mace_set_multicast;
 	dev->set_mac_address = mace_set_address;
+	dev->do_ioctl = mace_do_ioctl;
 
 	ether_setup(dev);
 
@@ -362,6 +372,90 @@
     return 0;
 }
 
+static int mace_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+        switch(cmd) {
+        case SIOCETHTOOL:
+                return mace_ethtool_ioctl(dev, (void *) ifr->ifr_data);
+
+        case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
+        case SIOCDEVPRIVATE:            /* for binary compat, remove in 2.5 */
+        case SIOCGMIIREG:               /* Read MII PHY register. */
+        case SIOCDEVPRIVATE+1:          /* for binary compat, remove in 2.5 */
+        case SIOCSMIIREG:               /* Write MII PHY register. */
+        case SIOCDEVPRIVATE+2:          /* for binary compat, remove in 2.5 */
+        default:
+                return -EOPNOTSUPP;
+        }
+}
+
+static int mace_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	struct mace_data *mp = (struct mace_data *) dev->priv;
+	u32 ethcmd;
+
+	if (get_user(ethcmd, (u32 *)useraddr))
+		return -EFAULT;
+
+	switch (ethcmd) {
+	case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = { .cmd = ETHTOOL_GDRVINFO };
+		struct mace_data *mp = dev->priv;
+		strcpy (info.driver, "mace");
+		info.version[0] = '\0';
+		snprintf(info.fw_version, 31, "chip revision %d.%d", mp->chipid >> 8, mp->chipid & 0xff);
+		if (copy_to_user (useraddr, &info, sizeof (info)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_GSET: {
+		struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
+
+		cmd.supported = SUPPORTED_10baseT_Half |
+				SUPPORTED_AUI |
+				SUPPORTED_MII;
+		cmd.advertising = SUPPORTED_10baseT_Half;
+		cmd.port = mp->port_aaui ? PORT_AUI : PORT_MII;
+		cmd.speed = SPEED_10;
+		if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SSET: {
+		struct ethtool_cmd cmd;
+
+		if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
+			return -EFAULT;
+
+		if (cmd.autoneg != AUTONEG_DISABLE)
+			return -EINVAL;
+		if (cmd.speed != SPEED_10)
+			return -EINVAL;
+		if ((cmd.port == PORT_AUI) != mp->port_aaui) {
+			int aaui = (cmd.port == PORT_AUI);
+			unsigned long flags;
+
+			printk("%s: switching port to: %s\n",
+				dev->name, aaui ? "AAUI" : "MII");
+			mp->port_aaui = aaui;
+    			save_flags(flags);
+			cli();
+			mace_restart(dev);
+			restore_flags(flags);
+		}
+		return 0;
+	}
+	case ETHTOOL_NWAY_RST:
+	case ETHTOOL_GLINK:
+	case ETHTOOL_GMSGLVL:
+	case ETHTOOL_SMSGLVL:
+	default:
+		break;
+	}
+
+	return -EOPNOTSUPP;
+}
+
 static int mace_open(struct net_device *dev)
 {
     struct mace_data *mp = (struct mace_data *) dev->priv;
@@ -473,10 +567,7 @@
 static inline void mace_set_timeout(struct net_device *dev)
 {
     struct mace_data *mp = (struct mace_data *) dev->priv;
-    unsigned long flags;
 
-    save_flags(flags);
-    cli();
     if (mp->timeout_active)
 	del_timer(&mp->tx_timeout);
     mp->tx_timeout.expires = jiffies + TX_TIMEOUT;
@@ -484,7 +575,6 @@
     mp->tx_timeout.data = (unsigned long) dev;
     add_timer(&mp->tx_timeout);
     mp->timeout_active = 1;
-    restore_flags(flags);
 }
 
 static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
@@ -763,31 +853,17 @@
     }
 }
 
-static void mace_tx_timeout(unsigned long data)
+static void mace_restart(struct net_device *dev)
 {
-    struct net_device *dev = (struct net_device *) data;
     struct mace_data *mp = (struct mace_data *) dev->priv;
     volatile struct mace *mb = mp->mace;
     volatile struct dbdma_regs *td = mp->tx_dma;
     volatile struct dbdma_regs *rd = mp->rx_dma;
     volatile struct dbdma_cmd *cp;
-    unsigned long flags;
     int i;
 
-    save_flags(flags);
-    cli();
-    mp->timeout_active = 0;
-    if (mp->tx_active == 0 && !mp->tx_bad_runt)
-	goto out;
-
-    /* update various counters */
-    mace_handle_misc_intrs(mp, in_8(&mb->ir));
-
-    cp = mp->tx_cmds + NCMDS_TX * mp->tx_empty;
-
     /* turn off both tx and rx and reset the chip */
     out_8(&mb->maccc, 0);
-    printk(KERN_ERR "mace: transmit timeout - resetting\n");
     dbdma_reset(td);
     mace_reset(dev);
 
@@ -825,7 +901,29 @@
     /* turn it back on */
     out_8(&mb->imr, RCVINT);
     out_8(&mb->maccc, mp->maccc);
+}
+
+static void mace_tx_timeout(unsigned long data)
+{
+    struct net_device *dev = (struct net_device *) data;
+    struct mace_data *mp = (struct mace_data *) dev->priv;
+    volatile struct mace *mb = mp->mace;
+    unsigned long flags;
+
+    save_flags(flags);
+    cli();
+    mp->timeout_active = 0;
+    if (mp->tx_active == 0 && !mp->tx_bad_runt)
+	goto out;
+
+    /* update various counters */
+    mace_handle_misc_intrs(mp, in_8(&mb->ir));
+
+    printk(KERN_ERR "mace: transmit timeout - resetting\n");
 
+    /* Kick chip */
+    mace_restart(dev);
+    
 out:
     restore_flags(flags);
 }
diff -urN linux-2.4.22-pre2/drivers/net/macsonic.c linux-2.4.22-pre3/drivers/net/macsonic.c
--- linux-2.4.22-pre2/drivers/net/macsonic.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/net/macsonic.c	2003-07-05 18:10:18.000000000 -0700
@@ -142,7 +142,7 @@
 
 int __init macsonic_init(struct net_device* dev)
 {
-	struct sonic_local* lp;
+	struct sonic_local* lp = NULL;
 	int i;
 
 	/* Allocate the entire chunk of memory for the descriptors.
diff -urN linux-2.4.22-pre2/drivers/net/pcmcia/aironet4500_cs.c linux-2.4.22-pre3/drivers/net/pcmcia/aironet4500_cs.c
--- linux-2.4.22-pre2/drivers/net/pcmcia/aironet4500_cs.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/net/pcmcia/aironet4500_cs.c	2003-07-05 18:10:19.000000000 -0700
@@ -282,7 +282,7 @@
 	};
 	memset(dev,0,sizeof(struct net_device));
 	dev->priv = kmalloc(sizeof(struct awc_private), GFP_KERNEL);
-	if (!dev->priv ) {printk(KERN_CRIT "out of mem on dev priv alloc \n"); return NULL;};
+	if (!dev->priv ) {printk(KERN_CRIT "out of mem on dev priv alloc \n"); kfree(dev); return NULL;};
 	memset(dev->priv,0,sizeof(struct awc_private));
 	
 //	link->dev->minor = dev->minor;
diff -urN linux-2.4.22-pre2/drivers/net/plip.c linux-2.4.22-pre3/drivers/net/plip.c
--- linux-2.4.22-pre2/drivers/net/plip.c	2003-07-05 18:09:18.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/plip.c	2003-07-05 18:10:19.000000000 -0700
@@ -1180,7 +1180,7 @@
 	struct plip_local *rcv = &nl->rcv_data;
 
 	netif_stop_queue (dev);
-	DISABLE(dev->irq);
+	disable_parport_interrupts(dev);
 	synchronize_irq();
 
 	if (dev->irq == -1)
diff -urN linux-2.4.22-pre2/drivers/net/sonic.c linux-2.4.22-pre3/drivers/net/sonic.c
--- linux-2.4.22-pre2/drivers/net/sonic.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/sonic.c	2003-07-05 18:10:20.000000000 -0700
@@ -113,15 +113,6 @@
 	if (sonic_debug > 2)
 		printk("sonic_send_packet: skb=%p, dev=%p\n", skb, dev);
 
-	/* 
-	 * Block a timer-based transmit from overlapping.  This could better be
-	 * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
-	 */
-	if (test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
-		printk("%s: Transmitter access conflict.\n", dev->name);
-		return 1;
-	}
-
 	/*
 	 * Map the packet data into the logical DMA address space
 	 */
diff -urN linux-2.4.22-pre2/drivers/net/sungem.c linux-2.4.22-pre3/drivers/net/sungem.c
--- linux-2.4.22-pre2/drivers/net/sungem.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/sungem.c	2003-07-05 18:10:21.000000000 -0700
@@ -2616,9 +2616,6 @@
 		return 0;
 
 	case ETHTOOL_SSET:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
 		/* Verify the settings we care about. */
 		if (ecmd.autoneg != AUTONEG_ENABLE &&
 		    ecmd.autoneg != AUTONEG_DISABLE)
diff -urN linux-2.4.22-pre2/drivers/net/sunhme.c linux-2.4.22-pre3/drivers/net/sunhme.c
--- linux-2.4.22-pre2/drivers/net/sunhme.c	2003-07-05 18:09:19.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/sunhme.c	2003-07-05 18:10:21.000000000 -0700
@@ -2480,9 +2480,6 @@
 			return -EFAULT;
 		return 0;
 	} else if (ecmd.cmd == ETHTOOL_SSET) {
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
 		/* Verify the settings we care about. */
 		if (ecmd.autoneg != AUTONEG_ENABLE &&
 		    ecmd.autoneg != AUTONEG_DISABLE)
diff -urN linux-2.4.22-pre2/drivers/net/tulip/tulip_core.c linux-2.4.22-pre3/drivers/net/tulip/tulip_core.c
--- linux-2.4.22-pre2/drivers/net/tulip/tulip_core.c	2003-07-05 18:09:19.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/tulip/tulip_core.c	2003-07-05 18:10:23.000000000 -0700
@@ -63,7 +63,7 @@
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
 #if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
 	|| defined(__sparc_) || defined(__ia64__) \
-	|| defined(__sh__) || defined(__mips__)
+	|| defined(__sh__) || defined(__mips__) || defined(__SH5__)
 static int rx_copybreak = 1518;
 #else
 static int rx_copybreak = 100;
diff -urN linux-2.4.22-pre2/drivers/net/typhoon.c linux-2.4.22-pre3/drivers/net/typhoon.c
--- linux-2.4.22-pre2/drivers/net/typhoon.c	2003-07-05 18:09:19.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/typhoon.c	2003-07-05 18:10:24.000000000 -0700
@@ -40,7 +40,7 @@
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
  * Setting to > 1518 effectively disables this feature.
  */
-static int rx_copybreak = 0;
+static int rx_copybreak = 200;
 
 /* end user-configurable values */
 
@@ -85,8 +85,8 @@
 #define PKT_BUF_SZ		1536
 
 #define DRV_MODULE_NAME		"typhoon"
-#define DRV_MODULE_VERSION 	"1.0"
-#define DRV_MODULE_RELDATE	"03/02/14"
+#define DRV_MODULE_VERSION 	"1.4.1"
+#define DRV_MODULE_RELDATE	"03/06/26"
 #define PFX			DRV_MODULE_NAME ": "
 #define ERR_PFX			KERN_ERR PFX
 
@@ -150,7 +150,7 @@
 #define TYPHOON_CRYPTO_DES		1
 #define TYPHOON_CRYPTO_3DES		2
 #define	TYPHOON_CRYPTO_VARIABLE		4
-#define TYPHOON_FIBER			5
+#define TYPHOON_FIBER			8
 
 enum typhoon_cards {
 	TYPHOON_TX = 0, TYPHOON_TX95, TYPHOON_TX97, TYPHOON_SVR,
@@ -1798,7 +1798,7 @@
 	u32 intr_status;
 
 	intr_status = readl(ioaddr + TYPHOON_REG_INTR_STATUS);
-	if(!intr_status)
+	if(!(intr_status & TYPHOON_INTR_HOST_INT))
 		return;
 
 	writel(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS);
diff -urN linux-2.4.22-pre2/drivers/net/via-rhine.c linux-2.4.22-pre3/drivers/net/via-rhine.c
--- linux-2.4.22-pre2/drivers/net/via-rhine.c	2003-07-05 18:09:19.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/via-rhine.c	2003-07-05 18:10:24.000000000 -0700
@@ -2,6 +2,8 @@
 /*
 	Written 1998-2001 by Donald Becker.
 
+	Current Maintainer: Roger Luethi <rl@hellgate.ch>
+
 	This software may be used and distributed according to the terms of
 	the GNU General Public License (GPL), incorporated herein by reference.
 	Drivers based on or derived from this code fall under the GPL and must
@@ -9,8 +11,9 @@
 	a complete program and may only be used when the entire operating
 	system is licensed under the GPL.
 
-	This driver is designed for the VIA VT86C100A Rhine-I. 
-	It also works with the 6102 Rhine-II, and 6105/6105M Rhine-III.   
+	This driver is designed for the VIA VT86C100A Rhine-I.
+	It also works with the Rhine-II (6102) and Rhine-III (6105/6105L/6105LOM
+	and management NIC 6105M).
 
 	The author may be reached as becker@scyld.com, or C/O
 	Scyld Computing Corporation
@@ -115,11 +118,15 @@
 	- Force flushing for PCI posted writes
 	- More reset code changes
 
+	LK1.1.18 (Roger Luethi)
+	- No filtering multicast in promisc mode (Edward Peng)
+	- Fix for Rhine-I Tx timeouts
+
 */
 
 #define DRV_NAME	"via-rhine"
-#define DRV_VERSION	"1.1.17"
-#define DRV_RELDATE	"March-1-2003"
+#define DRV_VERSION	"1.1.18"
+#define DRV_RELDATE	"July-4-2003"
 
 
 /* A few user-configurable values.
@@ -139,7 +146,7 @@
    Both 'options[]' and 'full_duplex[]' should exist for driver
    interoperability.
    The media type is usually passed in 'options[]'.
-   The default is autonegotation for speed and duplex.
+   The default is autonegotiation for speed and duplex.
      This should rarely be overridden.
    Use option values 0x10/0x20 for 10Mbps, 0x100,0x200 for 100Mbps.
    Use option values 0x10 and 0x100 for forcing half duplex fixed speed.
@@ -386,17 +393,17 @@
 	{ "VIA VT6102 Rhine-II", RHINE_IOTYPE, 256,
 	  CanHaveMII | HasWOL },
 	{ "VIA VT6105 Rhine-III", RHINE_IOTYPE, 256,
-	  CanHaveMII | HasWOL },	  
+	  CanHaveMII | HasWOL },
 	{ "VIA VT6105M Rhine-III", RHINE_IOTYPE, 256,
-	  CanHaveMII | HasWOL },	  	  	 
+	  CanHaveMII | HasWOL },
 };
 
 static struct pci_device_id via_rhine_pci_tbl[] __devinitdata =
 {
 	{0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A},
 	{0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6102},
-	{0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105},
-	{0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M},	
+	{0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105}, /* 6105{,L,LOM} */
+	{0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M},
 	{0,}			/* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, via_rhine_pci_tbl);
@@ -441,7 +448,7 @@
 	IntrRxWakeUp=0x8000,
 	IntrNormalSummary=0x0003, IntrAbnormalSummary=0xC260,
 	IntrTxDescRace=0x080000,	/* mapped from IntrStatus2 */
-	IntrTxErrSummary=0x082210,
+	IntrTxErrSummary=0x082218,
 };
 
 /* The Rx and Tx buffer descriptors. */
@@ -1264,7 +1271,7 @@
 
 	if (skb->len < ETH_ZLEN) {
 		skb = skb_padto(skb, ETH_ZLEN);
-		if(skb == NULL)
+		if (skb == NULL)
 			return 0;
 	}
 
@@ -1650,11 +1657,18 @@
 			printk(KERN_INFO "%s: Tx descriptor write-back race.\n",
 				   dev->name);
 	}
-	if (intr_status & ( IntrTxAborted | IntrTxUnderrun | IntrTxDescRace ))
+	if ((intr_status & IntrTxError) && ~( IntrTxAborted | IntrTxUnderrun |
+										   IntrTxDescRace )) {
+		if (debug > 2)
+			printk(KERN_INFO "%s: Unspecified error.\n",
+				   dev->name);
+	}
+	if (intr_status & ( IntrTxAborted | IntrTxUnderrun | IntrTxDescRace |
+						IntrTxError ))
 		via_rhine_restart_tx(dev);
 
 	if (intr_status & ~( IntrLinkChange | IntrStatsMax | IntrTxUnderrun |
- 						 IntrTxError | IntrTxAborted | IntrNormalSummary |
+						 IntrTxError | IntrTxAborted | IntrNormalSummary |
 						 IntrTxDescRace )) {
 		if (debug > 1)
 			printk(KERN_ERR "%s: Something Wicked happened! %8.8x.\n",
diff -urN linux-2.4.22-pre2/drivers/net/wireless/airport.c linux-2.4.22-pre3/drivers/net/wireless/airport.c
--- linux-2.4.22-pre2/drivers/net/wireless/airport.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/wireless/airport.c	2003-07-05 18:10:24.000000000 -0700
@@ -1,4 +1,4 @@
-/* airport.c 0.13b
+/* airport.c 0.13d
  *
  * A driver for "Hermes" chipset based Apple Airport wireless
  * card.
@@ -95,7 +95,7 @@
 
 		netif_device_detach(dev);
 
-		priv->hw_unavailable = 1;
+		priv->hw_unavailable++;
 
 		orinoco_unlock(priv, &flags);
 
@@ -121,14 +121,15 @@
 
 		netif_device_attach(dev);
 
-		if (priv->open) {
+		priv->hw_unavailable--;
+
+		if (priv->open && (! priv->hw_unavailable)) {
 			err = __orinoco_up(dev);
 			if (err)
 				printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
 				       dev->name, err);
 		}
 
-		priv->hw_unavailable = 0;
 
 		spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -140,8 +141,21 @@
 
 static int airport_hard_reset(struct orinoco_private *priv)
 {
+	/* It would be nice to power cycle the Airport for a real hard
+	 * reset, but for some reason although it appears to
+	 * re-initialize properly, it falls in a screaming heap
+	 * shortly afterwards. */
+#if 0
+	struct net_device *dev = priv->ndev;
 	struct airport *card = priv->card;
 
+	/* Vitally important.  If we don't do this it seems we get an
+	 * interrupt somewhere during the power cycle, since
+	 * hw_unavailable is already set it doesn't get ACKed, we get
+	 * into an interrupt loop and the the PMU decides to turn us
+	 * off. */
+	disable_irq(dev->irq);
+
 	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0);
 	current->state = TASK_UNINTERRUPTIBLE;
 	schedule_timeout(HZ);
@@ -149,6 +163,10 @@
 	current->state = TASK_UNINTERRUPTIBLE;
 	schedule_timeout(HZ);
 
+	enable_irq(dev->irq);
+	schedule_timeout(HZ);
+#endif
+
 	return 0;
 }
 
@@ -209,7 +227,7 @@
 	/* Reset it before we get the interrupt */
 	hermes_init(hw);
 
-	if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", (void *)priv)) {
+	if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", dev)) {
 		printk(KERN_ERR "airport: Couldn't get IRQ %d\n", dev->irq);
 		goto failed;
 	}
@@ -251,7 +269,7 @@
 	card->ndev_registered = 0;
 
 	if (card->irq_requested)
-		free_irq(dev->irq, priv);
+		free_irq(dev->irq, dev);
 	card->irq_requested = 0;
 
 	if (card->vaddr)
@@ -269,11 +287,10 @@
 	kfree(dev);
 }				/* airport_detach */
 
-static char version[] __initdata = "airport.c 0.13b (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
+static char version[] __initdata = "airport.c 0.13d (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
 MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
 MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
 MODULE_LICENSE("Dual MPL/GPL");
-EXPORT_NO_SYMBOLS;
 
 static int __init
 init_airport(void)
@@ -282,15 +299,11 @@
 
 	printk(KERN_DEBUG "%s\n", version);
 
-	MOD_INC_USE_COUNT;
-
 	/* Lookup card in device tree */
 	airport_node = find_devices("radio");
 	if (airport_node && !strcmp(airport_node->parent->name, "mac-io"))
 		airport_dev = airport_attach(airport_node);
 
-	MOD_DEC_USE_COUNT;
-
 	return airport_dev ? 0 : -ENODEV;
 }
 
diff -urN linux-2.4.22-pre2/drivers/net/wireless/hermes.c linux-2.4.22-pre3/drivers/net/wireless/hermes.c
--- linux-2.4.22-pre2/drivers/net/wireless/hermes.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/wireless/hermes.c	2003-07-05 18:10:24.000000000 -0700
@@ -544,4 +544,9 @@
 	return 0;
 }
 
+static void __exit exit_hermes(void)
+{
+}
+
 module_init(init_hermes);
+module_exit(exit_hermes);
diff -urN linux-2.4.22-pre2/drivers/net/wireless/hermes.h linux-2.4.22-pre3/drivers/net/wireless/hermes.h
--- linux-2.4.22-pre2/drivers/net/wireless/hermes.h	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/wireless/hermes.h	2003-07-05 18:10:24.000000000 -0700
@@ -250,7 +250,6 @@
 	u16 scanreason;             /* ??? */
 	struct hermes_scan_apinfo aps[35];        /* Scan result */
 } __attribute__ ((packed));
-
 #define HERMES_LINKSTATUS_NOT_CONNECTED   (0x0000)  
 #define HERMES_LINKSTATUS_CONNECTED       (0x0001)
 #define HERMES_LINKSTATUS_DISCONNECTED    (0x0002)
@@ -368,7 +367,7 @@
 	if (hw->io_space) {
 		insw(hw->iobase + off, buf, count);
 	} else {
-		int i;
+		unsigned i;
 		u16 *p;
 
 		/* This needs to *not* byteswap (like insw()) but
@@ -388,7 +387,7 @@
 	if (hw->io_space) {
 		outsw(hw->iobase + off, buf, count);
 	} else {
-		int i;
+		unsigned i;
 		const u16 *p;
 
 		/* This needs to *not* byteswap (like outsw()) but
@@ -401,6 +400,21 @@
 	}
 }
 
+static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count)
+{
+	unsigned i;
+
+	off = off << hw->reg_spacing;;
+
+	if (hw->io_space) {
+		for (i = 0; i < count; i++)
+			outw(0, hw->iobase + off);
+	} else {
+		for (i = 0; i < count; i++)
+			writew(0, hw->iobase + off);
+	}
+}
+
 #define HERMES_READ_RECORD(hw, bap, rid, buf) \
 	(hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf)))
 #define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
diff -urN linux-2.4.22-pre2/drivers/net/wireless/orinoco.c linux-2.4.22-pre3/drivers/net/wireless/orinoco.c
--- linux-2.4.22-pre2/drivers/net/wireless/orinoco.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/wireless/orinoco.c	2003-07-05 18:10:24.000000000 -0700
@@ -1,4 +1,4 @@
-/* orinoco.c 0.13b	- (formerly known as dldwd_cs.c and orinoco_cs.c)
+/* orinoco.c 0.13d	- (formerly known as dldwd_cs.c and orinoco_cs.c)
  *
  * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
  * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
@@ -345,11 +345,45 @@
  * 	  we are connected (avoids cofusing the firmware), and only
  * 	  give LINKSTATUS printk()s if the status has changed.
  *
+ * v0.13b -> v0.13c - 11 Mar 2003 - David Gibson
+ *	o Cleanup: use dev instead of priv in various places.
+ *	o Bug fix: Don't ReleaseConfiguration on RESET_PHYSICAL event
+ *	  if we're in the middle of a (driver initiated) hard reset.
+ *	o Bug fix: ETH_ZLEN is supposed to include the header
+ *	  (Dionysus Blazakis & Manish Karir)
+ *	o Convert to using workqueues instead of taskqueues (and
+ *	  backwards compatibility macros for pre 2.5.41 kernels).
+ *	o Drop redundant (I think...) MOD_{INC,DEC}_USE_COUNT in
+ *	  airport.c
+ *	o New orinoco_tmd.c init module from Joerg Dorchain for
+ *	  TMD7160 based PCI to PCMCIA bridges (similar to
+ *	  orinoco_plx.c).
+ *
+ * v0.13c -> v0.13d - 22 Apr 2003 - David Gibson
+ *	o Make hw_unavailable a counter, rather than just a flag, this
+ *	  is necessary to avoid some races (such as a card being
+ *	  removed in the middle of orinoco_reset().
+ *	o Restore Release/RequestConfiguration in the PCMCIA event handler
+ *	  when dealing with a driver initiated hard reset.  This is
+ *	  necessary to prevent hangs due to a spurious interrupt while
+ *	  the reset is in progress.
+ *	o Clear the 802.11 header when transmitting, even though we
+ *	  don't use it.  This fixes a long standing bug on some
+ *	  firmwares, which seem to get confused if that isn't done.
+ *	o Be less eager to de-encapsulate SNAP frames, only do so if
+ *	  the OUI is 00:00:00 or 00:00:f8, leave others alone.  The old
+ *	  behaviour broke CDP (Cisco Discovery Protocol).
+ *	o Use dev instead of priv for free_irq() as well as
+ *	  request_irq() (oops).
+ *	o Attempt to reset rather than giving up if we get too many
+ *	  IRQs.
+ *	o Changed semantics of __orinoco_down() so it can be called
+ *	  safely with hw_unavailable set.  It also now clears the
+ *	  linkstatus (since we're going to have to reassociate).
+ *
  * TODO
-
  *	o New wireless extensions API (patch from Moustafa
  *	  Youssef, updated by Jim Carter).
- *	o Fix PCMCIA hard resets with pcmcia-cs.
  *	o Handle de-encapsulation within network layer, provide 802.11
  *	  headers (patch from Thomas 'Dent' Mirlacher)
  *	o Fix possible races in SPY handling.
@@ -373,7 +407,7 @@
  * flag after taking the lock, and if it is set, give up on whatever
  * they are doing and drop the lock again.  The orinoco_lock()
  * function handles this (it unlocks and returns -EBUSY if
- * hw_unavailable is true). */
+ * hw_unavailable is non-zero). */
 
 #include <linux/config.h>
 
@@ -522,7 +556,7 @@
 
 /* Hardware control routines */
 
-static int __orinoco_program_rids(struct orinoco_private *priv);
+static int __orinoco_program_rids(struct net_device *dev);
 
 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
 static int __orinoco_hw_setup_wep(struct orinoco_private *priv);
@@ -535,14 +569,14 @@
 static void __orinoco_set_multicast_list(struct net_device *dev);
 
 /* Interrupt handling routines */
-static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw);
-static void __orinoco_ev_wterr(struct orinoco_private *priv, hermes_t *hw);
-static void __orinoco_ev_infdrop(struct orinoco_private *priv, hermes_t *hw);
-static void __orinoco_ev_info(struct orinoco_private *priv, hermes_t *hw);
-static void __orinoco_ev_rx(struct orinoco_private *priv, hermes_t *hw);
-static void __orinoco_ev_txexc(struct orinoco_private *priv, hermes_t *hw);
-static void __orinoco_ev_tx(struct orinoco_private *priv, hermes_t *hw);
-static void __orinoco_ev_alloc(struct orinoco_private *priv, hermes_t *hw);
+static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw);
+static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw);
+static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw);
+static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw);
+static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw);
+static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw);
+static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw);
+static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw);
 
 /* ioctl() routines */
 static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq);
@@ -577,7 +611,7 @@
 	struct hermes *hw = &priv->hw;
 	int err;
 
-	err = __orinoco_program_rids(priv);
+	err = __orinoco_program_rids(dev);
 	if (err) {
 		printk(KERN_ERR "%s: Error %d configuring card\n",
 		       dev->name, err);
@@ -606,14 +640,25 @@
 
 	netif_stop_queue(dev);
 
-	err = hermes_disable_port(hw, 0);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d disabling MAC port\n",
-		       dev->name, err);
-		return err;
+	if (! priv->hw_unavailable) {
+		if (! priv->broken_disableport) {
+			err = hermes_disable_port(hw, 0);
+			if (err) {
+				/* Some firmwares (e.g. Intersil 1.3.x) seem
+				 * to have problems disabling the port, oh
+				 * well, too bad. */
+				printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
+				       dev->name, err);
+				priv->broken_disableport = 1;
+			}
+		}
+		hermes_set_irqmask(hw, 0);
+		hermes_write_regn(hw, EVACK, 0xffff);
 	}
-	hermes_set_irqmask(hw, 0);
-	hermes_write_regn(hw, EVACK, 0xffff);
+	
+	/* firmware will have to reassociate */
+	priv->last_linkstatus = 0xffff;
+	priv->connected = 0;
 
 	return 0;
 }
@@ -656,38 +701,38 @@
 	if (err)
 		return err;
 
-        priv->open = 1;
-
 	err = __orinoco_up(dev);
 
+	if (! err)
+		priv->open = 1;
+
 	orinoco_unlock(priv, &flags);
 
 	return err;
 }
 
-static int orinoco_stop(struct net_device *dev)
+int orinoco_stop(struct net_device *dev)
 {
 	struct orinoco_private *priv = dev->priv;
 	int err = 0;
 
 	/* We mustn't use orinoco_lock() here, because we need to be
-	   able to close the interface, even if hw_unavailable is set
+	   able to close the interface even if hw_unavailable is set
 	   (e.g. as we're released after a PC Card removal) */
 	spin_lock_irq(&priv->lock);
 
 	priv->open = 0;
 
-	if (! priv->hw_unavailable)
-		err = __orinoco_down(dev);
+	err = __orinoco_down(dev);
 
 	spin_unlock_irq(&priv->lock);
 
 	return err;
 }
 
-static int __orinoco_program_rids(struct orinoco_private *priv)
+static int __orinoco_program_rids(struct net_device *dev)
 {
-	struct net_device *dev = priv->ndev;
+	struct orinoco_private *priv = dev->priv;
 	hermes_t *hw = &priv->hw;
 	int err;
 	struct hermes_idstring idbuf;
@@ -873,51 +918,84 @@
 }
 
 /* xyzzy */
-static int orinoco_reconfigure(struct orinoco_private *priv)
+static int orinoco_reconfigure(struct net_device *dev)
 {
+	struct orinoco_private *priv = dev->priv;
 	struct hermes *hw = &priv->hw;
 	unsigned long flags;
 	int err = 0;
 
-	orinoco_lock(priv, &flags);
+	if (priv->broken_disableport) {
+		schedule_work(&priv->reset_work);
+		return 0;
+	}
 
+	err = orinoco_lock(priv, &flags);
+	if (err)
+		return err;
+
+		
 	err = hermes_disable_port(hw, 0);
 	if (err) {
-		printk(KERN_ERR "%s: Unable to disable port in orinco_reconfigure()\n",
-		       priv->ndev->name);
+		printk(KERN_WARNING "%s: Unable to disable port while reconfiguring card\n",
+		       dev->name);
+		priv->broken_disableport = 1;
 		goto out;
 	}
 
-	err = __orinoco_program_rids(priv);
-	if (err)
+	err = __orinoco_program_rids(dev);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to reconfigure card\n",
+		       dev->name);
 		goto out;
+	}
 
 	err = hermes_enable_port(hw, 0);
 	if (err) {
-		printk(KERN_ERR "%s: Unable to enable port in orinco_reconfigure()\n",
-		       priv->ndev->name);
+		printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
+		       dev->name);
 		goto out;
 	}
 
  out:
+	if (err) {
+		printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
+		schedule_work(&priv->reset_work);
+		err = 0;
+	}
+
 	orinoco_unlock(priv, &flags);
 	return err;
 
 }
 
 /* This must be called from user context, without locks held - use
- * schedule_task() */
+ * schedule_work() */
 static void orinoco_reset(struct net_device *dev)
 {
 	struct orinoco_private *priv = dev->priv;
+	struct hermes *hw = &priv->hw;
 	int err;
 	unsigned long flags;
 
 	err = orinoco_lock(priv, &flags);
 	if (err)
+		/* When the hardware becomes available again, whatever
+		 * detects that is responsible for re-initializing
+		 * it. So no need for anything further*/
 		return;
 
-	priv->hw_unavailable = 1;
+	netif_stop_queue(dev);
+
+	/* Shut off interrupts.  Depending on what state the hardware
+	 * is in, this might not work, but we'll try anyway */
+	hermes_set_irqmask(hw, 0);
+	hermes_write_regn(hw, EVACK, 0xffff);
+
+	priv->hw_unavailable++;
+	priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
+	priv->connected = 0;
+
 	orinoco_unlock(priv, &flags);
 
 	if (priv->hard_reset)
@@ -936,18 +1014,22 @@
 		return;
 	}
 
-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irq(&priv->lock); /* This has to be called from user context */
 
-	priv->hw_unavailable = 0;
+	priv->hw_unavailable--;
 
-	err = __orinoco_up(dev);
-	if (err) {
-		printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
-		       dev->name, err);
-	} else
-		dev->trans_start = jiffies;
+	/* priv->open or priv->hw_unavailable might have changed while
+	 * we dropped the lock */
+	if (priv->open && (! priv->hw_unavailable)) {
+		err = __orinoco_up(dev);
+		if (err) {
+			printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
+			       dev->name, err);
+		} else
+			dev->trans_start = jiffies;
+	}
 
-	orinoco_unlock(priv, &flags);
+	spin_unlock_irq(&priv->lock);
 
 	return;
 }
@@ -979,10 +1061,18 @@
 	}
 }
 
+/* Does the frame have a SNAP header indicating it should be
+ * de-encapsulated to Ethernet-II? */
 static inline int
-is_snap(struct header_struct *hdr)
+is_ethersnap(struct header_struct *hdr)
 {
-	return (hdr->dsap == 0xAA) && (hdr->ssap == 0xAA) && (hdr->ctrl == 0x3);
+	/* We de-encapsulate all packets which, a) have SNAP headers
+	 * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
+	 * and where b) the OUI of the SNAP header is 00:00:00 or
+	 * 00:00:f8 - we need both because different APs appear to use
+	 * different OUIs for some reason */
+	return (memcmp(&hdr->dsap, &encaps_hdr, 5) == 0)
+		&& ( (hdr->oui[2] == 0x00) || (hdr->oui[2] == 0xf8) );
 }
 
 static void
@@ -1140,7 +1230,8 @@
 	return 0;
 }
 
-static int orinoco_hw_get_bssid(struct orinoco_private *priv, char buf[ETH_ALEN])
+static int orinoco_hw_get_bssid(struct orinoco_private *priv,
+				char buf[ETH_ALEN])
 {
 	hermes_t *hw = &priv->hw;
 	int err = 0;
@@ -1159,7 +1250,7 @@
 }
 
 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
-			      char buf[IW_ESSID_MAX_SIZE+1])
+				char buf[IW_ESSID_MAX_SIZE+1])
 {
 	hermes_t *hw = &priv->hw;
 	int err = 0;
@@ -1236,9 +1327,8 @@
 	}
 
 	if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
-		struct net_device *dev = priv->ndev;
-
-		printk(KERN_WARNING "%s: Channel out of range (%d)!\n", dev->name, channel);
+		printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
+		       priv->ndev->name, channel);
 		err = -EBUSY;
 		goto out;
 
@@ -1253,8 +1343,8 @@
 	return err ? err : freq;
 }
 
-static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, int *numrates,
-				    s32 *rates, int max)
+static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
+				      int *numrates, s32 *rates, int max)
 {
 	hermes_t *hw = &priv->hw;
 	struct hermes_idstring list;
@@ -1354,9 +1444,9 @@
  */
 void orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct orinoco_private *priv = (struct orinoco_private *) dev_id;
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct orinoco_private *priv = dev->priv;
 	hermes_t *hw = &priv->hw;
-	struct net_device *dev = priv->ndev;
 	int count = MAX_IRQLOOPS_PER_IRQ;
 	u16 evstat, events;
 	/* These are used to detect a runaway interrupt situation */
@@ -1380,11 +1470,11 @@
 
 	while (events && count--) {
 		if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
-			printk(KERN_CRIT "%s: IRQ handler is looping too \
-much! Shutting down.\n",
-			       dev->name);
-			/* Perform an emergency shutdown */
+			printk(KERN_WARNING "%s: IRQ handler is looping too "
+			       "much! Resetting.\n", dev->name);
+			/* Disable interrupts for now */
 			hermes_set_irqmask(hw, 0);
+			schedule_work(&priv->reset_work);
 			break;
 		}
 
@@ -1395,21 +1485,21 @@
 		}
 
 		if (events & HERMES_EV_TICK)
-			__orinoco_ev_tick(priv, hw);
+			__orinoco_ev_tick(dev, hw);
 		if (events & HERMES_EV_WTERR)
-			__orinoco_ev_wterr(priv, hw);
+			__orinoco_ev_wterr(dev, hw);
 		if (events & HERMES_EV_INFDROP)
-			__orinoco_ev_infdrop(priv, hw);
+			__orinoco_ev_infdrop(dev, hw);
 		if (events & HERMES_EV_INFO)
-			__orinoco_ev_info(priv, hw);
+			__orinoco_ev_info(dev, hw);
 		if (events & HERMES_EV_RX)
-			__orinoco_ev_rx(priv, hw);
+			__orinoco_ev_rx(dev, hw);
 		if (events & HERMES_EV_TXEXC)
-			__orinoco_ev_txexc(priv, hw);
+			__orinoco_ev_txexc(dev, hw);
 		if (events & HERMES_EV_TX)
-			__orinoco_ev_tx(priv, hw);
+			__orinoco_ev_tx(dev, hw);
 		if (events & HERMES_EV_ALLOC)
-			__orinoco_ev_alloc(priv, hw);
+			__orinoco_ev_alloc(dev, hw);
 		
 		hermes_write_regn(hw, EVACK, events);
 
@@ -1420,22 +1510,22 @@
 	orinoco_unlock(priv, &flags);
 }
 
-static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw)
+static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
 {
-	printk(KERN_DEBUG "%s: TICK\n", priv->ndev->name);
+	printk(KERN_DEBUG "%s: TICK\n", dev->name);
 }
 
-static void __orinoco_ev_wterr(struct orinoco_private *priv, hermes_t *hw)
+static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
 {
 	/* This seems to happen a fair bit under load, but ignoring it
 	   seems to work fine...*/
 	printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
-	       priv->ndev->name);
+	       dev->name);
 }
 
-static void __orinoco_ev_infdrop(struct orinoco_private *priv, hermes_t *hw)
+static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
 {
-	printk(KERN_WARNING "%s: Information frame lost.\n", priv->ndev->name);
+	printk(KERN_WARNING "%s: Information frame lost.\n", dev->name);
 }
 
 static void print_linkstatus(struct net_device *dev, u16 status)
@@ -1472,9 +1562,9 @@
 	       dev->name, s, status);
 }
 
-static void __orinoco_ev_info(struct orinoco_private *priv, hermes_t *hw)
+static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 {
-	struct net_device *dev = priv->ndev;
+	struct orinoco_private *priv = dev->priv;
 	u16 infofid;
 	struct {
 		u16 len;
@@ -1573,9 +1663,9 @@
 	}
 }
 
-static void __orinoco_ev_rx(struct orinoco_private *priv, hermes_t *hw)
+static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
 {
-	struct net_device *dev = priv->ndev;
+	struct orinoco_private *priv = dev->priv;
 	struct net_device_stats *stats = &priv->stats;
 	struct iw_statistics *wstats = &priv->wstats;
 	struct sk_buff *skb = NULL;
@@ -1664,7 +1754,7 @@
 	 * So, check ourselves */
 	if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
 	   ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
-	   is_snap(&hdr)) {
+	   is_ethersnap(&hdr)) {
 		/* These indicate a SNAP within 802.2 LLC within
 		   802.11 frame which we'll need to de-encapsulate to
 		   the original EthernetII frame. */
@@ -1726,9 +1816,9 @@
 	return;
 }
 
-static void __orinoco_ev_txexc(struct orinoco_private *priv, hermes_t *hw)
+static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
 {
-	struct net_device *dev = priv->ndev;
+	struct orinoco_private *priv = dev->priv;
 	struct net_device_stats *stats = &priv->stats;
 	u16 fid = hermes_read_regn(hw, TXCOMPLFID);
 	struct hermes_tx_descriptor desc;
@@ -1752,8 +1842,9 @@
 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
 }
 
-static void __orinoco_ev_tx(struct orinoco_private *priv, hermes_t *hw)
+static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
 {
+	struct orinoco_private *priv = dev->priv;
 	struct net_device_stats *stats = &priv->stats;
 
 	stats->tx_packets++;
@@ -1761,9 +1852,10 @@
 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
 }
 
-static void __orinoco_ev_alloc(struct orinoco_private *priv, hermes_t *hw)
+static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
 {
-	struct net_device *dev = priv->ndev;
+	struct orinoco_private *priv = dev->priv;
+
 	u16 fid = hermes_read_regn(hw, ALLOCFID);
 
 	if (fid != priv->txfid) {
@@ -1945,7 +2037,7 @@
 
 	TRACE_ENTER(dev->name);
 
-	/* No need to lock, the resetting flag is already set in
+	/* No need to lock, the hw_unavailable flag is already set in
 	 * alloc_orinocodev() */
 	priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
 
@@ -2081,8 +2173,6 @@
 	priv->wep_on = 0;
 	priv->tx_key = 0;
 
-	priv->hw_unavailable = 0;
-
 	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
 	if (err == -EIO) {
 		/* Try workaround for old Symbol firmware bug */
@@ -2102,6 +2192,12 @@
 		goto out;
 	}
 
+	/* Make the hardware available, as long as it hasn't been
+	 * removed elsewhere (e.g. by PCMCIA hot unplug) */
+	spin_lock_irq(&priv->lock);
+	priv->hw_unavailable--;
+	spin_unlock_irq(&priv->lock);
+
 	printk(KERN_DEBUG "%s: ready\n", dev->name);
 
  out:
@@ -2267,7 +2363,7 @@
 
 	/* Length of the packet body */
 	/* FIXME: what if the skb is smaller than this? */
-	len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN);
+	len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN);
 
 	eh = (struct ethhdr *)skb->data;
 
@@ -2281,6 +2377,12 @@
 		goto fail;
 	}
 
+	/* Clear the 802.11 header and data length fields - some
+	 * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
+	 * if this isn't done. */
+	hermes_clear_words(hw, HERMES_DATA0,
+			   HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
+
 	/* Encapsulate Ethernet-II frames */
 	if (ntohs(eh->h_proto) > 1500) { /* Ethernet-II frame */
 		struct header_struct hdr;
@@ -2362,7 +2464,7 @@
 
 	stats->tx_errors++;
 
-	schedule_task(&priv->timeout_task);
+	schedule_work(&priv->reset_work);
 }
 
 static int
@@ -2532,7 +2634,7 @@
 	}
 
 	err = orinoco_hw_get_bitratelist(priv, &numrates,
-				       range.bitrate, IW_MAX_BITRATES);
+					 range.bitrate, IW_MAX_BITRATES);
 	if (err)
 		return err;
 	range.num_bitrates = numrates;
@@ -3128,7 +3230,7 @@
 				rrq->value = 5500000;
 			else
 				rrq->value = val * 1000000;
-                        break;
+			break;
 		case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
 		case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
 			for (i = 0; i < BITRATE_TABLE_SIZE; i++)
@@ -3754,7 +3856,7 @@
 		
 		printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
 
-		schedule_task(&priv->timeout_task);
+		schedule_work(&priv->reset_work);
 		break;
 
 	case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */
@@ -3839,7 +3941,7 @@
 	}
 	
 	if (! err && changed && netif_running(dev)) {
-		err = orinoco_reconfigure(priv);
+		err = orinoco_reconfigure(dev);
 	}		
 
 	TRACE_EXIT(dev->name);
@@ -3924,7 +4026,7 @@
 	DEBUG_REC(PRIID,WORDS),
 	DEBUG_REC(PRISUPRANGE,WORDS),
 	DEBUG_REC(CFIACTRANGES,WORDS),
-	DEBUG_REC(NICSERNUM,WORDS),
+	DEBUG_REC(NICSERNUM,XSTRING),
 	DEBUG_REC(NICID,WORDS),
 	DEBUG_REC(MFISUPRANGE,WORDS),
 	DEBUG_REC(CFISUPRANGE,WORDS),
@@ -4062,7 +4164,7 @@
 	priv->hw_unavailable = 1; /* orinoco_init() must clear this
 				   * before anything else touches the
 				   * hardware */
-	INIT_TQUEUE(&priv->timeout_task, (void (*)(void *))orinoco_reset, dev);
+	INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
 
 	priv->last_linkstatus = 0xffff;
 	priv->connected = 0;
@@ -4079,13 +4181,14 @@
 
 EXPORT_SYMBOL(__orinoco_up);
 EXPORT_SYMBOL(__orinoco_down);
+EXPORT_SYMBOL(orinoco_stop);
 EXPORT_SYMBOL(orinoco_reinit_firmware);
 
 EXPORT_SYMBOL(orinoco_interrupt);
 
 /* Can't be declared "const" or the whole __initdata section will
  * become const */
-static char version[] __initdata = "orinoco.c 0.13b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata = "orinoco.c 0.13d (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 
 static int __init init_orinoco(void)
 {
diff -urN linux-2.4.22-pre2/drivers/net/wireless/orinoco.h linux-2.4.22-pre3/drivers/net/wireless/orinoco.h
--- linux-2.4.22-pre2/drivers/net/wireless/orinoco.h	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/wireless/orinoco.h	2003-07-05 18:10:24.000000000 -0700
@@ -11,9 +11,20 @@
 #include <linux/spinlock.h>
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
-#include <linux/tqueue.h>
+#include <linux/version.h>
 #include "hermes.h"
 
+/* Workqueue / task queue backwards compatibility stuff */
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
+#include <linux/workqueue.h>
+#else
+#include <linux/tqueue.h>
+#define work_struct tq_struct
+#define INIT_WORK INIT_TQUEUE
+#define schedule_work schedule_task
+#endif
+
 /* To enable debug messages */
 //#define ORINOCO_DEBUG		3
 
@@ -42,7 +53,7 @@
 	/* Synchronisation stuff */
 	spinlock_t lock;
 	int hw_unavailable;
-	struct tq_struct timeout_task;
+	struct work_struct reset_work;
 
 	/* driver state */
 	int open;
@@ -72,6 +83,7 @@
 	int has_sensitivity;
 	int nicbuf_size;
 	u16 channel_mask;
+	int broken_disableport;
 
 	/* Configuration paramaters */
 	u32 iw_mode;
@@ -111,8 +123,8 @@
 					   int (*hard_reset)(struct orinoco_private *));
 extern int __orinoco_up(struct net_device *dev);
 extern int __orinoco_down(struct net_device *dev);
-int orinoco_reinit_firmware(struct net_device *dev);
-
+extern int orinoco_stop(struct net_device *dev);
+extern int orinoco_reinit_firmware(struct net_device *dev);
 extern void orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
 
 /********************************************************************/
diff -urN linux-2.4.22-pre2/drivers/net/wireless/orinoco_cs.c linux-2.4.22-pre3/drivers/net/wireless/orinoco_cs.c
--- linux-2.4.22-pre2/drivers/net/wireless/orinoco_cs.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/wireless/orinoco_cs.c	2003-07-05 18:10:24.000000000 -0700
@@ -1,4 +1,4 @@
-/* orinoco_cs.c 0.13b	- (formerly known as dldwd_cs.c)
+/* orinoco_cs.c 0.13d	- (formerly known as dldwd_cs.c)
  *
  * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
  * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -22,7 +22,6 @@
 #include <linux/ptrace.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <linux/timer.h>
 #include <linux/ioport.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -38,7 +37,6 @@
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
-#include <pcmcia/bus_ops.h>
 
 #include "orinoco.h"
 
@@ -269,19 +267,12 @@
 		return;
 	}
 
-	/*
-	   If the device is currently configured and active, we won't
-	   actually delete it yet.  Instead, it is marked so that when
-	   the release() function is called, that will trigger a proper
-	   detach().
-	 */
 	if (link->state & DEV_CONFIG) {
-#ifdef PCMCIA_DEBUG
-		printk(KERN_DEBUG "orinoco_cs: detach postponed, '%s' "
-		       "still locked\n", link->dev->dev_name);
-#endif
-		link->state |= DEV_STALE_LINK;
-		return;
+		orinoco_cs_release((u_long)link);
+		if (link->state & DEV_CONFIG) {
+			link->state |= DEV_STALE_LINK;
+			return;
+		}
 	}
 
 	/* Break the link with Card Services */
@@ -472,7 +463,7 @@
 				link->irq.IRQInfo2 |= 1 << irq_list[i];
 		
   		link->irq.Handler = orinoco_interrupt; 
-  		link->irq.Instance = priv; 
+  		link->irq.Instance = dev; 
 		
 		CS_CHECK(RequestIRQ, link->handle, &link->irq);
 	}
@@ -549,18 +540,13 @@
 	dev_link_t *link = (dev_link_t *) arg;
 	struct net_device *dev = link->priv;
 	struct orinoco_private *priv = dev->priv;
+	unsigned long flags;
 
-	/*
-	   If the device is currently in use, we won't release until it
-	   is actually closed, because until then, we can't be sure that
-	   no one will try to access the device or its data structures.
-	 */
-	if (priv->open) {
-		DEBUG(0, "orinoco_cs: release postponed, '%s' still open\n",
-		      link->dev->dev_name);
-		link->state |= DEV_STALE_CONFIG;
-		return;
-	}
+	/* We're committed to taking the device away now, so mark the
+	 * hardware as unavailable */
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->hw_unavailable++;
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	/* Don't bother checking to see if these succeed or not */
 	CardServices(ReleaseConfiguration, link->handle);
@@ -593,14 +579,9 @@
 			orinoco_lock(priv, &flags);
 
 			netif_device_detach(dev);
-			priv->hw_unavailable = 1;
+			priv->hw_unavailable++;
 
 			orinoco_unlock(priv, &flags);
-
-/*  			if (link->open) */
-/*  				orinoco_cs_stop(dev); */
-
-			mod_timer(&link->release, jiffies + HZ / 20);
 		}
 		break;
 
@@ -619,13 +600,8 @@
                            a better way, short of rewriting the PCMCIA
                            layer to not suck :-( */
 			if (! test_bit(0, &card->hard_reset_in_progress)) {
-				err = orinoco_lock(priv, &flags);
-				if (err) {
-					printk(KERN_ERR "%s: hw_unavailable on SUSPEND/RESET_PHYSICAL\n",
-					       dev->name);
-					break;
-				}
-				
+				spin_lock_irqsave(&priv->lock, flags);
+
 				err = __orinoco_down(dev);
 				if (err)
 					printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
@@ -634,9 +610,9 @@
 					       err);
 				
 				netif_device_detach(dev);
-				priv->hw_unavailable = 1;
-				
-				orinoco_unlock(priv, &flags);
+				priv->hw_unavailable++;
+
+				spin_unlock_irqrestore(&priv->lock, flags);
 			}
 
 			CardServices(ReleaseConfiguration, link->handle);
@@ -653,10 +629,6 @@
 			CardServices(RequestConfiguration, link->handle,
 				     &link->conf);
 
-			/* If we're only getting these events because
-                           of the ResetCard in the hard reset, we
-                           don't need to do anything - orinoco_reset()
-                           will handle reinitialization. */
 			if (! test_bit(0, &card->hard_reset_in_progress)) {
 				err = orinoco_reinit_firmware(dev);
 				if (err) {
@@ -668,9 +640,9 @@
 				spin_lock_irqsave(&priv->lock, flags);
 				
 				netif_device_attach(dev);
-				priv->hw_unavailable = 0;
+				priv->hw_unavailable--;
 				
-				if (priv->open) {
+				if (priv->open && ! priv->hw_unavailable) {
 					err = __orinoco_up(dev);
 					if (err)
 						printk(KERN_ERR "%s: Error %d restarting card\n",
@@ -678,7 +650,7 @@
 					
 				}
 
-				orinoco_unlock(priv, &flags);
+				spin_unlock_irqrestore(&priv->lock, flags);
 			}
 		}
 		break;
@@ -693,7 +665,7 @@
 
 /* Can't be declared "const" or the whole __initdata section will
  * become const */
-static char version[] __initdata = "orinoco_cs.c 0.13b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata = "orinoco_cs.c 0.13d (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 
 static int __init
 init_orinoco_cs(void)
@@ -722,7 +694,6 @@
 	if (dev_list)
 		DEBUG(0, "orinoco_cs: Removing leftover devices.\n");
 	while (dev_list != NULL) {
-		del_timer(&dev_list->release);
 		if (dev_list->state & DEV_CONFIG)
 			orinoco_cs_release((u_long) dev_list);
 		orinoco_cs_detach(dev_list);
diff -urN linux-2.4.22-pre2/drivers/net/wireless/orinoco_pci.c linux-2.4.22-pre3/drivers/net/wireless/orinoco_pci.c
--- linux-2.4.22-pre2/drivers/net/wireless/orinoco_pci.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/wireless/orinoco_pci.c	2003-07-05 18:10:24.000000000 -0700
@@ -1,4 +1,4 @@
-/* orinoco_pci.c 0.13b
+/* orinoco_pci.c 0.13d
  * 
  * Driver for Prism II devices that have a direct PCI interface
  * (i.e., not in a Pcmcia or PLX bridge)
@@ -143,8 +143,6 @@
 	unsigned long	timeout;
 	u16	reg;
 
-	TRACE_ENTER(priv->ndev->name);
-
 	/* Assert the reset until the card notice */
 	hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK);
 	printk(KERN_NOTICE "Reset done");
@@ -181,8 +179,6 @@
 	}
 	printk(KERN_NOTICE "pci_cor : reg = 0x%X - %lX - %lX\n", reg, timeout, jiffies);
 
-	TRACE_EXIT(priv->ndev->name);
-
 	return 0;
 }
 
@@ -232,7 +228,7 @@
 	hermes_struct_init(&(priv->hw), dev->base_addr, HERMES_MEM, HERMES_32BIT_REGSPACING);
 	pci_set_drvdata(pdev, dev);
 
-	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, priv);
+	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, dev);
 	if (err) {
 		printk(KERN_ERR "orinoco_pci: Error allocating IRQ %d.\n", pdev->irq);
 		err = -EBUSY;
@@ -264,7 +260,7 @@
 			unregister_netdev(dev);
 
 		if (dev->irq)
-			free_irq(dev->irq, priv);
+			free_irq(dev->irq, dev);
 
 		kfree(dev);
 	}
@@ -286,7 +282,7 @@
 	unregister_netdev(dev);
 
         if (dev->irq)
-		free_irq(dev->irq, priv);
+		free_irq(dev->irq, dev);
 
 	if (priv->hw.iobase)
 		iounmap((unsigned char *) priv->hw.iobase);
@@ -321,7 +317,7 @@
 	
 	netif_device_detach(dev);
 
-	priv->hw_unavailable = 1;
+	priv->hw_unavailable++;
 	
 	orinoco_unlock(priv, &flags);
 
@@ -348,15 +344,15 @@
 
 	netif_device_attach(dev);
 
-	if (priv->open) {
+	priv->hw_unavailable--;
+
+	if (priv->open && (! priv->hw_unavailable)) {
 		err = __orinoco_up(dev);
 		if (err)
 			printk(KERN_ERR "%s: Error %d restarting card on orinoco_pci_resume()\n",
 			       dev->name, err);
 	}
 	
-	priv->hw_unavailable = 0;
-	
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	return 0;
@@ -378,7 +374,7 @@
 	.resume		= orinoco_pci_resume,
 };
 
-static char version[] __initdata = "orinoco_pci.c 0.13b (David Gibson <hermes@gibson.dropbear.id.au> & Jean Tourrilhes <jt@hpl.hp.com>)";
+static char version[] __initdata = "orinoco_pci.c 0.13d (David Gibson <hermes@gibson.dropbear.id.au> & Jean Tourrilhes <jt@hpl.hp.com>)";
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 MODULE_DESCRIPTION("Driver for wireless LAN cards using direct PCI interface");
 MODULE_LICENSE("Dual MPL/GPL");
diff -urN linux-2.4.22-pre2/drivers/net/wireless/orinoco_plx.c linux-2.4.22-pre3/drivers/net/wireless/orinoco_plx.c
--- linux-2.4.22-pre2/drivers/net/wireless/orinoco_plx.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.22-pre3/drivers/net/wireless/orinoco_plx.c	2003-07-05 18:10:24.000000000 -0700
@@ -1,4 +1,4 @@
-/* orinoco_plx.c 0.13b
+/* orinoco_plx.c 0.13d
  * 
  * Driver for Prism II devices which would usually be driven by orinoco_cs,
  * but are connected to the PCI bus by a PLX9052. 
@@ -243,7 +243,7 @@
 			HERMES_IO, HERMES_16BIT_REGSPACING);
 	pci_set_drvdata(pdev, dev);
 
-	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, priv);
+	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, dev);
 	if (err) {
 		printk(KERN_ERR "orinoco_plx: Error allocating IRQ %d.\n", pdev->irq);
 		err = -EBUSY;
@@ -266,7 +266,7 @@
 			unregister_netdev(dev);
 		
 		if (dev->irq)
-			free_irq(dev->irq, priv);
+			free_irq(dev->irq, dev);
 		
 		kfree(priv);
 	}
@@ -285,7 +285,6 @@
 static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = dev->priv;
 
 	if (! dev)
 		BUG();
@@ -293,7 +292,7 @@
 	unregister_netdev(dev);
 		
 	if (dev->irq)
-		free_irq(dev->irq, priv);
+		free_irq(dev->irq, dev);
 		
 	pci_set_drvdata(pdev, NULL);
 
@@ -334,7 +333,7 @@
 	.resume		= 0,
 };
 
-static char version[] __initdata = "orinoco_plx.c 0.13b (Daniel Barlow <dan@telent.net>, David Gibson <hermes@gibson.dropbear.id.au>)";
+static char version[] __initdata = "orinoco_plx.c 0.13d (Daniel Barlow <dan@telent.net>, David Gibson <hermes@gibson.dropbear.id.au>)";
 MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
 MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
 #ifdef MODULE_LICENSE
diff -urN linux-2.4.22-pre2/drivers/net/wireless/orinoco_tmd.c linux-2.4.22-pre3/drivers/net/wireless/orinoco_tmd.c
--- linux-2.4.22-pre2/drivers/net/wireless/orinoco_tmd.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/drivers/net/wireless/orinoco_tmd.c	2003-07-05 18:10:24.000000000 -0700
@@ -0,0 +1,240 @@
+/* orinoco_tmd.c 0.01
+ * 
+ * Driver for Prism II devices which would usually be driven by orinoco_cs,
+ * but are connected to the PCI bus by a TMD7160. 
+ *
+ * Copyright (C) 2003 Joerg Dorchain <joerg@dorchain.net>
+ * based heavily upon orinoco_plx.c Copyright (C) 2001 Daniel Barlow <dan@telent.net>
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+
+ * Caution: this is experimental and probably buggy.  For success and
+ * failure reports for different cards and adaptors, see
+ * orinoco_tmd_pci_id_table near the end of the file.  If you have a
+ * card we don't have the PCI id for, and looks like it should work,
+ * drop me mail with the id and "it works"/"it doesn't work".
+ *
+ * Note: if everything gets detected fine but it doesn't actually send
+ * or receive packets, your first port of call should probably be to   
+ * try newer firmware in the card.  Especially if you're doing Ad-Hoc
+ * modes
+ *
+ * The actual driving is done by orinoco.c, this is just resource
+ * allocation stuff.
+ *
+ * This driver is modeled after the orinoco_plx driver. The main
+ * difference is that the TMD chip has only IO port ranges and no
+ * memory space, i.e.  no access to the CIS. Compared to the PLX chip,
+ * the io range functionalities are exchanged.
+ *
+ * Pheecom sells cards with the TMD chip as "ASIC version"
+ */
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/wireless.h>
+#include <linux/fcntl.h>
+
+#include <pcmcia/cisreg.h>
+
+#include "hermes.h"
+#include "orinoco.h"
+
+static char dev_info[] = "orinoco_tmd";
+
+#define COR_VALUE     (COR_LEVEL_REQ | COR_FUNC_ENA | COR_FUNC_ENA) /* Enable PC card with level triggered irqs and irq requests */
+
+
+static int orinoco_tmd_init_one(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	int err = 0;
+	u32 reg, addr;
+	struct orinoco_private *priv = NULL;
+	unsigned long pccard_ioaddr = 0;
+	unsigned long pccard_iolen = 0;
+	struct net_device *dev = NULL;
+	int netdev_registered = 0;
+
+	err = pci_enable_device(pdev);
+	if (err)
+		return -EIO;
+
+	printk(KERN_DEBUG "TMD setup\n");
+	pccard_ioaddr = pci_resource_start(pdev, 2);
+	pccard_iolen = pci_resource_len(pdev, 2);
+	if (! request_region(pccard_ioaddr, pccard_iolen, dev_info)) {
+		printk(KERN_ERR "orinoco_tmd: I/O resource at 0x%lx len 0x%lx busy\n",
+			pccard_ioaddr, pccard_iolen);
+		pccard_ioaddr = 0;
+		err = -EBUSY;
+		goto fail;
+	}
+	addr = pci_resource_start(pdev, 1);
+	outb(COR_VALUE, addr);
+	mdelay(1);
+	reg = inb(addr);
+	if (reg != COR_VALUE) {
+		printk(KERN_ERR "orinoco_tmd: Error setting TMD COR values %x should be %x\n", reg, COR_VALUE);
+		err = -EIO;
+		goto fail;
+	}
+
+	dev = alloc_orinocodev(0, NULL);
+	if (! dev) {
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	priv = dev->priv;
+	dev->base_addr = pccard_ioaddr;
+	SET_MODULE_OWNER(dev);
+
+	printk(KERN_DEBUG
+	       "Detected Orinoco/Prism2 TMD device at %s irq:%d, io addr:0x%lx\n",
+	       pdev->slot_name, pdev->irq, pccard_ioaddr);
+
+	hermes_struct_init(&(priv->hw), dev->base_addr,
+			HERMES_IO, HERMES_16BIT_REGSPACING);
+	pci_set_drvdata(pdev, dev);
+
+	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name,
+			  dev);
+	if (err) {
+		printk(KERN_ERR "orinoco_tmd: Error allocating IRQ %d.\n",
+		       pdev->irq);
+		err = -EBUSY;
+		goto fail;
+	}
+	dev->irq = pdev->irq;
+
+	err = register_netdev(dev);
+	if (err)
+		goto fail;
+	netdev_registered = 1;
+
+	return 0;		/* succeeded */
+
+ fail:	
+	printk(KERN_DEBUG "orinoco_tmd: init_one(), FAIL!\n");
+
+	if (priv) {
+		if (dev->irq)
+			free_irq(dev->irq, dev);
+		
+		kfree(priv);
+	}
+
+	if (pccard_ioaddr)
+		release_region(pccard_ioaddr, pccard_iolen);
+
+	pci_disable_device(pdev);
+
+	return err;
+}
+
+static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+
+	if (! dev)
+		BUG();
+
+	unregister_netdev(dev);
+		
+	if (dev->irq)
+		free_irq(dev->irq, dev);
+		
+	pci_set_drvdata(pdev, NULL);
+
+	kfree(dev);
+
+	release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
+
+	pci_disable_device(pdev);
+}
+
+
+static struct pci_device_id orinoco_tmd_pci_id_table[] __devinitdata = {
+	{0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,},      /* NDC and OEMs, e.g. pheecom */
+	{0,},
+};
+
+MODULE_DEVICE_TABLE(pci, orinoco_tmd_pci_id_table);
+
+static struct pci_driver orinoco_tmd_driver = {
+	.name		= "orinoco_tmd",
+	.id_table	= orinoco_tmd_pci_id_table,
+	.probe		= orinoco_tmd_init_one,
+	.remove		= __devexit_p(orinoco_tmd_remove_one),
+	.suspend	= 0,
+	.resume		= 0,
+};
+
+static char version[] __initdata = "orinoco_tmd.c 0.01 (Joerg Dorchain <joerg@dorchain.net>)";
+MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
+MODULE_DESCRIPTION("Driver for wireless LAN cards using the TMD7160 PCI bridge");
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("Dual MPL/GPL");
+#endif
+
+static int __init orinoco_tmd_init(void)
+{
+	printk(KERN_DEBUG "%s\n", version);
+	return pci_module_init(&orinoco_tmd_driver);
+}
+
+extern void __exit orinoco_tmd_exit(void)
+{
+	pci_unregister_driver(&orinoco_tmd_driver);
+	current->state = TASK_UNINTERRUPTIBLE;
+	schedule_timeout(HZ);
+}
+
+module_init(orinoco_tmd_init);
+module_exit(orinoco_tmd_exit);
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -urN linux-2.4.22-pre2/drivers/pci/pci.ids linux-2.4.22-pre3/drivers/pci/pci.ids
--- linux-2.4.22-pre2/drivers/pci/pci.ids	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.22-pre3/drivers/pci/pci.ids	2003-07-05 18:10:25.000000000 -0700
@@ -7,7 +7,8 @@
 #	so if you have anything to contribute, please visit the home page or
 #	send a diff -u against the most recent pci.ids to pci-ids@ucw.cz.
 #
-#	$Id: pci.ids,v 1.46 2002/08/14 17:38:51 mares Exp $
+#	Daily snapshot on Thu 2003-05-29 10:00:04
+#	Modded on Fri 2003-05-30 03:13:05
 #
 
 # Vendors, devices and subsystems. Please keep sorted.
@@ -21,6 +22,8 @@
 001a  Ascend Communications, Inc.
 0033  Paradyne corp.
 003d  Lockheed Martin-Marietta Corp
+# Real TJN ID is e159, but they got it wrong several times --mj
+0059  Tiger Jet Network Inc. (Wrong ID)
 0070  Hauppauge computer works Inc.
 0100  Ncipher Corp Ltd
 0675  Dynalink
@@ -98,7 +101,8 @@
 	f130  NetFlex-3/P ThunderLAN 1.0
 	f150  NetFlex-3/P ThunderLAN 2.3
 0e55  HaSoTec GmbH
-1000  LSI Logic / Symbios Logic (formerly NCR)
+# Formerly NCR
+1000  LSI Logic / Symbios Logic
 	0001  53c810
 		1000 1000  8100S
 	0002  53c820
@@ -123,7 +127,7 @@
 	0020  53c1010 Ultra3 SCSI Adapter
 		1de1 1020  DC-390U3W
 	0021  53c1010 66MHz  Ultra3 SCSI Adapter
-	0030  53c1030
+	0030  53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI
 		1028 1010  LSI U320 SCSI Controller
 	0040  53c1035
 	008f  53c875J
@@ -158,9 +162,20 @@
 	0017  PROTO-3 PCI Prototyping board
 	9100  INI-9100/9100W SCSI Host
 1002  ATI Technologies Inc
+	4136  Radeon IGP 320 M
+# New support forthcoming in XFree86 4.3.0
+	4144  Radeon R300 AD [Radeon 9500 Pro]
+# New support forthcoming in XFree86 4.3.0
+	4145  Radeon R300 AE [Radeon 9500 Pro]
+# New support forthcoming in XFree86 4.3.0
+	4146  Radeon R300 AF [Radeon 9500 Pro]
+# Update:  Oops, AF was a typo above for 4147, should be AG
+	4147  Radeon R300 AG [FireGL Z1/X1]
 	4158  68800AX [Mach32]
-	4242  Radeon 8500 DV
+	4242  Radeon R200 BB [Radeon All in Wonder 8500DV]
 		1002 02aa  Radeon 8500 AIW DV Edition
+	4336  Radeon Mobility U1
+	4337  Radeon IGP 340M
 	4354  215CT [Mach64 CT]
 	4358  210888CX [Mach64 CX]
 	4554  210888ET [Mach64 ET]
@@ -210,6 +225,8 @@
 	4752  Rage XL
 		1002 0008  Rage XL
 		1002 4752  Rage XL
+		1002 8008  Rage XL
+		1028 00d1  PowerEdge 2550
 	4753  Rage XC
 		1002 4753  Rage XC
 	4754  3D Rage I/II 215GT [Mach64 GT]
@@ -227,6 +244,20 @@
 	475a  3D Rage IIC AGP
 		1002 0087  Rage 3D IIC
 		1002 475a  Rage IIC AGP
+	4964  Radeon R250 Id [Radeon 9000]
+	4965  Radeon R250 Ie [Radeon 9000]
+	4966  Radeon R250 If [Radeon 9000]
+		10f1 0002  R250 If [Tachyon G9000 PRO]
+		148c 2039  R250 If [Radeon 9000 Pro "Evil Commando"]
+		1509 9a00  R250 If [Radeon 9000 "AT009"]
+# New subdevice - 3D Prophet 9000 PCI by Hercules.  AGP version probably would have same ID, so not specified.
+		1681 0040  R250 If [3D prophet 9000]
+		174b 7176  R250 If [Sapphire Radeon 9000 Pro]
+		174b 7192  R250 If [Radeon 9000 "Atlantis"]
+		17af 2005  R250 If [Excalibur Radeon 9000 Pro]
+		17af 2006  R250 If [Excalibur Radeon 9000]
+	4967  Radeon R250 Ig [Radeon 9000]
+	496e  Radeon R250 [Radeon 9000] (Secondary)
 	4c42  3D Rage LT Pro AGP-133
 		0e11 b0e8  Rage 3D LT Pro
 		0e11 b10e  3D Rage LT Pro (Compaq Armada 1750)
@@ -245,7 +276,9 @@
 		1002 0044  Rage LT Pro
 		1002 4c49  Rage LT Pro
 	4c4d  Rage Mobility P/M AGP 2x
+		0e11 b111  Armada M700
 		1002 0084  Xpert 98 AGP 2X (Mobility)
+		1014 0154  ThinkPad A20m
 	4c4e  Rage Mobility L AGP 2x
 	4c50  3D Rage LT Pro
 		1002 4c50  Rage LT Pro
@@ -253,16 +286,39 @@
 	4c52  Rage Mobility P/M
 	4c53  Rage Mobility L
 	4c54  264LT [Mach64 LT]
-	4c57  Radeon Mobility M7 LW
+	4c57  Radeon Mobility M7 LW [Radeon Mobility 7500]
+		1014 0517  ThinkPad T30
 		1028 00e6  Radeon Mobility M7 LW (Dell Inspiron 8100)
-	4c58  Radeon Mobility M7 LX [Radeon Mobility FireGL 7800]
+		144d c006  Radeon Mobility M7 LW in vpr Matrix 170B4
+# Update:  More correct labelling for this FireGL chipset
+	4c58  Radeon RV200 LX [Mobility FireGL 7800 M7]
 	4c59  Radeon Mobility M6 LY
 		1014 0235  ThinkPad A30p (2653-64G)
 		1014 0239  ThinkPad X22/X23/X24
 		104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
 	4c5a  Radeon Mobility M6 LZ
+# Update:  Add M9 to product name
+	4c64  Radeon R250 Ld [Radeon Mobility 9000 M9]
+# Update:  Add M9 to product name
+	4c65  Radeon R250 Le [Radeon Mobility 9000 M9]
+# Update:  Add M9 to product name
+	4c66  Radeon R250 Lf [Radeon Mobility 9000 M9]
+# Update:  Add M9 to product name
+	4c67  Radeon R250 Lg [Radeon Mobility 9000 M9]
 	4d46  Rage Mobility M4 AGP
 	4d4c  Rage Mobility M4 AGP
+	4e44  Radeon R300 ND [Radeon 9700 Pro]
+	4e45  Radeon R300 NE [Radeon 9500 Pro]
+		1002 0002  Radeon R300 NE [Radeon 9500 Pro]
+	4e46  Radeon R300 NF [Radeon 9700]
+# Update:  This is FireGL X1, not Radeon 9700
+	4e47  Radeon R300 NG [FireGL X1]
+	4e48  Radeon R350 [Radeon 9800]
+	4e64  Radeon R300 [Radeon 9700 Pro] (Secondary)
+	4e65  Radeon R300 [Radeon 9500 Pro] (Secondary)
+	4e66  Radeon R300 [Radeon 9700] (Secondary)
+	4e67  Radeon R300 [FireGL X1] (Secondary)
+	4e68  Radeon R350 [Radeon 9800] (Secondary)
 	5041  Rage 128 PA/PRO
 	5042  Rage 128 PB/PRO AGP 2x
 	5043  Rage 128 PC/PRO AGP 4x
@@ -289,7 +345,7 @@
 	504d  Rage 128 PM/PRO
 	504e  Rage 128 PN/PRO AGP 2x
 	504f  Rage 128 PO/PRO AGP 4x
-	5050  Rage 128 PP/PRO TMDS
+	5050  Rage 128 PP/PRO TMDS [Xpert 128]
 		1002 0008  Xpert 128
 	5051  Rage 128 PQ/PRO AGP 2x TMDS
 	5052  Rage 128 PR/PRO AGP 4x TMDS
@@ -299,7 +355,8 @@
 	5056  Rage 128 PV/PRO TMDS
 	5057  Rage 128 PW/PRO AGP 2x TMDS
 	5058  Rage 128 PX/PRO AGP 4x TMDS
-	5144  Radeon QD
+# Update: This same chip is used in all 32Mb and 64Mb SDR/DDR orig Radeons, and is now known as 7200
+	5144  Radeon R100 QD [Radeon 7200]
 		1002 0008  Radeon 7000/Radeon VE
 		1002 0009  Radeon 7000/Radeon
 		1002 000a  Radeon 7000/Radeon
@@ -313,34 +370,59 @@
 		1002 028a  Radeon 7000/Radeon
 		1002 02aa  Radeon AIW
 		1002 053a  Radeon 7000/Radeon
-	5145  Radeon QE
-	5146  Radeon QF
-	5147  Radeon QG
+	5145  Radeon R100 QE
+	5146  Radeon R100 QF
+	5147  Radeon R100 QG
 	5148  Radeon R200 QH [Radeon 8500]
-		1002 0152  FireGL 8800
-		1002 0172  FireGL 8700
+		1002 010a  FireGL 8800 64Mb
+		1002 0152  FireGL 8800 128Mb
+		1002 0162  FireGL 8700 32Mb
+		1002 0172  FireGL 8700 64Mb
 	5149  Radeon R200 QI
 	514a  Radeon R200 QJ
 	514b  Radeon R200 QK
 	514c  Radeon R200 QL [Radeon 8500 LE]
 		1002 003a  Radeon R200 QL [Radeon 8500 LE]
 		1002 013a  Radeon 8500
-	5157  Radeon 7500 QW
+		148c 2026  R200 QL [Radeon 8500 Evil Master II Multi Display Edition]
+		174b 7149  Radeon R200 QL [Sapphire Radeon 8500 LE]
+# New: Radeon 9100 is basically a Radeon 8500LE branded as 9100 by Sapphire
+	514d  Radeon R200 QM [Radeon 9100]
+# New: Radeon 8500LE chip
+	514e  Radeon R200 QN [Radeon 8500LE]
+# New: Radeon 8500LE chip
+	514f  Radeon R200 QO [Radeon 8500LE]
+	5157  Radeon RV200 QW [Radeon 7500]
 		1002 013a  Radeon 7500
+		1458 4000  RV200 QW [RADEON 7500 PRO MAYA AR]
+		148c 2024  RV200 QW [Radeon 7500LE Dual Display]
+		148c 2025  RV200 QW [Radeon 7500 Evil Master Multi Display Edition]
+		148c 2036  RV200 QW [Radeon 7500 PCI Dual Display]
+		174b 7147  RV200 QW [Sapphire Radeon 7500LE]
 		174b 7161  Radeon RV200 QW [Radeon 7500 LE]
-	5158  Radeon 7500 QX
-	5159  Radeon VE QY
+		17af 0202  RV200 QW [Excalibur Radeon 7500LE]
+	5158  Radeon RV200 QX [Radeon 7500]
+# Update: More correct name
+	5159  Radeon RV100 QY [Radeon 7000/VE]
 		1002 000a  Radeon 7000/Radeon VE
+		1002 000b  Radeon 7000
 		1002 0038  Radeon 7000/Radeon VE
 		1002 003a  Radeon 7000/Radeon VE
 		1002 00ba  Radeon 7000/Radeon VE
 		1002 013a  Radeon 7000/Radeon VE
-		174b 7112  Radeon 7000 64M TVO
-	515a  Radeon VE QZ
+		1458 4002  RV100 QY [RADEON 7000 PRO MAYA AV Series]
+		148c 2003  RV100 QY [Radeon 7000 Multi-Display Edition]
+		148c 2023  RV100 QY [Radeon 7000 Evil Master Multi-Display]
+		174b 7112  RV100 QY [Sapphire Radeon VE 7000]
+		1787 0202  RV100 QY [Excalibur Radeon 7000]
+# Update: More correct name
+	515a  Radeon RV100 QZ [Radeon 7000/VE]
 	5168  Radeon R200 Qh
 	5169  Radeon R200 Qi
 	516a  Radeon R200 Qj
 	516b  Radeon R200 Qk
+# new: This one is not in ATI documentation, but is in XFree86 source code
+	516c  Radeon R200 Ql
 	5245  Rage 128 RE/SG
 		1002 0008  Xpert 128
 		1002 0028  Rage 128 AIW
@@ -360,6 +442,7 @@
 		1002 0088  Xpert 99
 	5345  Rage 128 SE/4x
 	5346  Rage 128 SF/4x AGP 2x
+		1002 0048  RAGE 128 16MB VGA TVOUT AMC PAL
 	5347  Rage 128 SG/4x AGP 4x
 	5348  Rage 128 SH
 	534b  Rage 128 SK/4x
@@ -390,6 +473,9 @@
 		1002 5654  Mach64VT Reference
 	5655  264VT3 [Mach64 VT3]
 	5656  264VT4 [Mach64 VT4]
+	700f  PCI Bridge [IGP 320M]
+	7010  PCI Bridge [IGP 340M]
+	cab2  RS200/RS200M AGP Bridge [IGP 340M]
 1003  ULSI Systems
 	0201  US201
 1004  VLSI Technology Inc
@@ -419,7 +505,10 @@
 		1004 0306  QSound ThunderBird PCI Audio Support Registers
 		122d 1208  DSP368 Audio Support Registers
 		1483 5022  XWave Thunder 3D Audio Support Registers
+	0307  Thunderbird
+	0308  Thunderbird
 	0702  VAS96011 [Golden Gate II]
+	0703  Tollgate
 1005  Avance Logic Inc. [ALI]
 	2064  ALG2032/2064
 	2128  ALG2364A
@@ -492,13 +581,14 @@
 	0014  DECchip 21041 [Tulip Pass 3]
 		1186 0100  DE-530+
 	0016  DGLPB [OPPO]
+	0017  PV-PCI Graphics Controller (ZLXp-L)
 	0019  DECchip 21142/43
 		1011 500a  DE500A Fast Ethernet
 		1011 500b  DE500B Fast Ethernet
 		1014 0001  10/100 EtherJet Cardbus
 		1025 0315  ALN315 Fast Ethernet
-		1033 800c  PC-9821-CS01
-		1033 800d  PC-9821NR-B06
+		1033 800c  PC-9821-CS01 100BASE-TX Interface Card
+		1033 800d  PC-9821NR-B06 100BASE-TX Interface Card
 		108d 0016  Rapidfire 2327 10/100 Ethernet
 		108d 0017  GoCard 2250 Ethernet 10/100 Cardbus
 		10b8 2005  SMC8032DT Extreme Ethernet 10/100
@@ -522,6 +612,7 @@
 		1374 0002  Cardbus Ethernet Card 10/100
 		1374 0007  Cardbus Ethernet Card 10/100
 		1374 0008  Cardbus Ethernet Card 10/100
+		1385 2100  FA510
 		1395 0001  10/100 Ethernet CardBus PC Card
 		13d1 ab01  EtherFast 10/100 Cardbus (PCMPC200)
 		8086 0001  EtherExpress PRO/100 Mobile CardBus 32
@@ -581,8 +672,8 @@
 		1014 1010  CS4610 SoundFusion Audio Accelerator
 	6003  CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
 		1013 4280  Crystal SoundFusion PCI Audio Accelerator
-		1681 0050  Hercules Game Theater XP
-		1681 a011  Hercules Fortissimo III 7.1
+		1681 0050  Game Theater XP
+		1681 a011  Fortissimo III 7.1
 	6004  CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
 	6005  Crystal CS4281 PCI Audio
 		1013 4281  Crystal CS4281 PCI Audio
@@ -608,7 +699,9 @@
 	0020  MCA
 	0022  IBM27-82351
 	002d  Python
-	002e  ServeRAID-3x
+	002e  ServeRAID Controller
+		1014 002e  ServeRAID-3x
+		1014 022e  ServeRAID-4H
 	0036  Miami
 	003a  CPU to PCI Bridge
 	003e  16/4 Token ring UTP/STP controller
@@ -644,18 +737,25 @@
 	00b7  256-bit Graphics Rasterizer [Fire GL1]
 		1902 00b8  Fire GL1
 	00be  ATM 622MBPS Controller (1410be00)
+	00dc  Advanced Systems Management Adapter (ASMA)
 	00fc  CPC710 Dual Bridge and Memory Controller (PCI-64)
 	0105  CPC710 Dual Bridge and Memory Controller (PCI-32)
+	010f  Remote Supervisor Adapter (RSA)
 	0142  Yotta Video Compositor Input
 		1014 0143  Yotta Input Controller (ytin)
 	0144  Yotta Video Compositor Output
 		1014 0145  Yotta Output Controller (ytout)
 	0156  405GP PLB to PCI Bridge
 	01a7  PCI-X to PCI-X Bridge
-	01bd  Netfinity ServeRAID controller
-	01be  ServeRAID-4M
-	01bf  ServeRAID-4L
-	022e  ServeRAID-4H
+	01bd  ServeRAID Controller
+		1014 01be  ServeRAID-4M
+		1014 01bf  ServeRAID-4L
+		1014 0208  ServeRAID-4Mx
+		1014 020e  ServeRAID-4Lx
+		1014 022e  ServeRAID-4H
+		1014 0258  ServeRAID-5i
+		1014 0259  ServeRAID-5i
+	0302  XA-32 chipset [Summit]
 	ffff  MPIC-2 interrupt controller
 1015  LSI Logic Corp of Canada
 1016  ICL Personal Systems
@@ -700,7 +800,11 @@
 1020  Hitachi Computer Products
 1021  OKI Electric Industry Co. Ltd.
 1022  Advanced Micro Devices [AMD]
-	2000  79c970 [PCnet LANCE]
+	1100  K8 NorthBridge
+	1101  K8 NorthBridge
+	1102  K8 NorthBridge
+	1103  K8 NorthBridge
+	2000  79c970 [PCnet32 LANCE]
 		1014 2000  NetFinity 10/100 Fast Ethernet
 		103c 104c  Ethernet with LAN remote power Adapter
 		103c 1064  Ethernet with LAN remote power Adapter
@@ -743,19 +847,23 @@
 	7443  AMD-768 [Opus] ACPI
 		1043 8044  A7M-D Mainboard
 	7445  AMD-768 [Opus] Audio
+	7446  AMD-768 [Opus] MC97 Modem (Smart Link HAMR5600 compatible)
 	7448  AMD-768 [Opus] PCI
 	7449  AMD-768 [Opus] USB
+	7450  AMD-8131 PCI-X Bridge
+	7451  AMD-8131 PCI-X APIC
 	7454  AMD-8151 System Controller
 	7455  AMD-8151 AGP Bridge
 	7460  AMD-8111 PCI
 	7461  AMD-8111 USB
 	7462  AMD-8111 Ethernet
+	7464  AMD-8111 USB
 	7468  AMD-8111 LPC
 	7469  AMD-8111 IDE
 	746a  AMD-8111 SMBus 2.0
 	746b  AMD-8111 ACPI
 	746d  AMD-8111 AC97 Audio
-	756b  AMD-8111 ACPI
+	746e  AMD-8111 MC97 Modem
 1023  Trident Microsystems
 	0194  82C194
 	2000  4DWave DX
@@ -768,6 +876,8 @@
 	8520  CyberBlade i1
 		0e11 b16e  CyberBlade i1 AGP
 		1023 8520  CyberBlade i1 AGP
+	8620  CyberBlade/i1
+		1014 0502  ThinkPad T30
 	8820  CyberBlade XPAi1
 	9320  TGUI 9320
 	9350  GUI Accelerator
@@ -876,13 +986,15 @@
 		1028 00d0  PowerEdge Expandable RAID Controller 3/Si
 	0005  PowerEdge Expandable RAID Controller 3/Di
 	0006  PowerEdge Expandable RAID Controller 3/Di
-	0007  Remote Assistant Card 3
-	0008  PowerEdge Expandable RAID Controller 3/Di
+	0007  Remote Access Controller:DRAC III
+	0008  Remote Access Controller
+	0009  BMC/SMIC device not present
 	000a  PowerEdge Expandable RAID Controller 3
-		1027 0121  PowerEdge Expandable RAID Controller 3/Di
 		1028 0106  PowerEdge Expandable RAID Controller 3/Di
 		1028 011b  PowerEdge Expandable RAID Controller 3/Di
-	000c  Embedded Systems Management Device 4
+		1028 0121  PowerEdge Expandable RAID Controller 3/Di
+	000c  Remote Access Controller:ERA or ERA/O
+	000d  BMC/SMIC device
 	000e  PowerEdge Expandable RAID Controller
 	000f  PowerEdge Expandable RAID Controller 4/Di
 1029  Siemens Nixdorf IS
@@ -892,9 +1004,11 @@
 102b  Matrox Graphics, Inc.
 # DJ: I've a suspicion that 0010 is a duplicate of 0d10.
 	0010  MGA-I [Impression?]
+	0100  MGA 1064SG [Mystique]
 	0518  MGA-II [Athena]
 	0519  MGA 2064W [Millennium]
 	051a  MGA 1064SG [Mystique]
+		102b 0100  MGA-1064SG Mystique
 		102b 1100  MGA-1084SG Mystique
 		102b 1200  MGA-1084SG Mystique
 		1100 102b  MGA-1084SG Mystique
@@ -989,10 +1103,10 @@
 		102b 5f52  4Sight II
 		102b 9010  Millennium G400 Dual Head
 		1458 0400  GA-G400
-		1705 0001  Digital First Millennium G450 32MB SGRAM
-		1705 0002  Digital First Millennium G450 16MB SGRAM
-		1705 0003  Digital First Millennium G450 32MB
-		1705 0004  Digital First Millennium G450 16MB
+		1705 0001  Millennium G450 32MB SGRAM
+		1705 0002  Millennium G450 16MB SGRAM
+		1705 0003  Millennium G450 32MB
+		1705 0004  Millennium G450 16MB
 		b16f 0e11  MGA-G400 AGP
 	0527  MGA Parhelia AGP
 		102b 0840  Parhelia 128Mb
@@ -1050,17 +1164,22 @@
 	0003  ATM Controller
 	0004  R4000 PCI Bridge
 	0005  PCI to 486-like bus Bridge
-	0006  GUI Accelerator
+	0006  PC-9800 Graphic Accelerator
 	0007  PCI to UX-Bus Bridge
-	0008  GUI Accelerator
-	0009  GUI Accelerator for W98
+	0008  PC-9800 Graphic Accelerator
+	0009  PCI to PC9800 Core-Graph Bridge
+	0016  PCI to VL Bridge
 	001a  [Nile II]
 	0021  Vrc4373 [Nile I]
 	0029  PowerVR PCX1
 	002a  PowerVR 3D
+	002c  Star Alpha 2
+	002d  PCI to C-bus Bridge
 	0035  USB
 		1179 0001  USB
 		12ee 7000  Root Hub
+		1799 0001  Root Hub
+	003b  PCI to C-bus Bridge
 	003e  NAPCCARD Cardbus Controller
 	0046  PowerVR PCX2 [midas]
 	005a  Vrc5074 [Nile 4]
@@ -1082,6 +1201,7 @@
 		12ee 8011  Root hub
 	00e0  USB 2.0
 		12ee 7001  Root hub
+		1799 0002  Root Hub
 1034  Framatome Connectors USA Inc.
 1035  Comp. & Comm. Research Lab
 1036  Future Domain Corp.
@@ -1089,7 +1209,8 @@
 1037  Hitachi Micro Systems
 1038  AMP, Inc
 1039  Silicon Integrated Systems [SiS]
-	0001  5591/5592 AGP
+# This is what all my tests report. I don't know if this is equivalent to "5591/5592 AGP".
+	0001  SiS 530 Virtual PCI-to-PCI bridge (AGP)
 	0002  SG86C202
 	0006  85C501/2/3
 	0008  85C503/5513
@@ -1099,8 +1220,12 @@
 		1039 0000  SiS5597 SVGA (Shared RAM)
 	0204  82C204
 	0205  SG86C205
-	0300  300/200
+	0300  SiS300/305 PCI/AGP VGA Display Adapter
 		107d 2720  Leadtek WinFast VR300
+	0310  SiS315H PCI/AGP VGA Display Adapter
+	0315  SiS315 PCI/AGP VGA Display Adapter
+	0325  SiS315PRO PCI/AGP VGA Display Adapter
+	0330  SiS330 [Xabre] PCI/AGP VGA Display Adapter
 	0406  85C501/2
 	0496  85C496
 	0530  530 Host
@@ -1111,24 +1236,30 @@
 	0630  630 Host
 	0633  633 Host
 	0635  635 Host
-	0645  645 Host
-	0646  645DX Host
+	0645  SiS645 Host & Memory & AGP Controller
+	0646  SiS645DX Host & Memory & AGP Controller
+	0648  SiS 645xx
 	0650  650 Host
+	0651  SiS651 Host
 	0730  730 Host
 	0733  733 Host
 	0735  735 Host
 	0740  740 Host
 	0745  745 Host
 	0746  746 Host
+	0755  SiS 755 Host Bridge
 	0900  SiS900 10/100 Ethernet
 		1039 0900  SiS900 10/100 Ethernet Adapter
 	0961  SiS961 [MuTIOL Media IO]
+	0962  SiS962 [MuTIOL Media IO]
 	3602  83C602
 	5107  5107
 	5300  SiS540 PCI Display Adapter
+	5315  SiS550 AGP/VGA VGA Display Adapter
 	5401  486 PCI Chipset
 	5511  5511/5512
 	5513  5513 [IDE]
+		1019 0970  P6STP-FL motherboard
 		1039 5513  SiS5513 EIDE Controller (A,B step)
 	5517  5517
 	5571  5571
@@ -1142,8 +1273,10 @@
 	6205  VGA Controller
 	6236  6236 3D-AGP
 	6300  SiS630 GUI Accelerator+3D
-	6306  6306 3D-AGP
+		1019 0970  P6STP-FL motherboard
+	6306  SiS530 3D PCI/AGP
 		1039 6306  SiS530,620 GUI Accelerator+3D
+	6325  SiS65x/M650/740 PCI/AGP VGA Display Adapter
 	6326  86C326 5598/6326
 		1039 6326  SiS6326 GUI Accelerator
 		1092 0a50  SpeedStar A50
@@ -1151,11 +1284,14 @@
 		1092 4910  SpeedStar A70
 		1092 4920  SpeedStar A70
 		1569 6326  SiS6326 GUI Accelerator
-	7001  7001
+	7001  USB 1.0 Controller
+		1039 7000  Onboard USB Controller
+	7002  USB 2.0 Controller
+		1509 7002  Onboard USB Controller
 	7007  FireWire Controller
-	7012  SiS7012 PCI Audio Accelerator
-	7013  56k Winmodem (Smart Link HAMR5600 compatible)
-	7016  SiS7016 10/100 Ethernet Adapter
+	7012  Sound Controller
+	7013  Intel 537 [56k Winmodem]
+	7016  10/100 Ethernet Adapter
 		1039 7016  SiS7016 10/100 Ethernet Adapter
 	7018  SiS PCI Audio Accelerator
 		1014 01b6  SiS PCI Audio Accelerator
@@ -1232,13 +1368,14 @@
 1040  Accelgraphics Inc.
 1041  Computrend
 1042  Micron
-	1000  FDC 37C665
-	1001  37C922
+	1000  PC Tech RZ1000
+	1001  PC Tech RZ1001
 	3000  Samurai_0
 	3010  Samurai_1
 	3020  Samurai_IDE
 1043  Asustek Computer, Inc.
 	0675  ISDNLink P-IN100-ST-D
+	4021  v7100 Combo Deluxe [GeForce2 MX + TV tuner]
 	4057  V8200 GeForce 3
 1044  Distributed Processing Technology
 	1012  Domino RAID Engine
@@ -1314,6 +1451,9 @@
 104a  SGS Thomson Microelectronics
 	0008  STG 2000X
 	0009  STG 1764X
+	0010  STG4000 [3D Prophet Kyro Series]
+# From <http://gatekeeper.dec.com/pub/BSD/FreeBSD/FreeBSD-stable/src/share/misc/pci_vendors>
+	0210  STPC Atlas ISA Bridge
 	0981  DEC-Tulip compatible 10/100 Ethernet
 	1746  STG 1764X
 	2774  DEC-Tulip compatible 10/100 Ethernet
@@ -1326,6 +1466,7 @@
 	0500  100 MBit LAN Controller
 	0508  TMS380C2X Compressor Interface
 	1000  Eagle i/f AS
+	104c  PCI1510 PC card Cardbus Controller
 	3d04  TVP4010 [Permedia]
 	3d07  TVP4020 [Permedia 2]
 		1011 4d10  Comet
@@ -1369,9 +1510,12 @@
 	8026  TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link)
 	8027  PCI4451 IEEE-1394 Controller
 		1028 00e6  PCI4451 IEEE-1394 Controller (Dell Inspiron 8100)
+	8029  PCI4510 IEEE-1394 Controller
+	8400  ACX 100 22Mbps Wireless Interface
 	a001  TDC1570
 	a100  TDC1561
 	a102  TNETA1575 HyperSAR Plus w/PCI Host i/f & UTOPIA i/f
+	a106  TMS320C6205
 	ac10  PCI1050
 	ac11  PCI1053
 	ac12  PCI1130
@@ -1383,6 +1527,7 @@
 	ac19  PCI1221
 	ac1a  PCI1210
 	ac1b  PCI1450
+		0e11 b113  Armada M700
 	ac1c  PCI1225
 	ac1d  PCI1251A
 	ac1e  PCI1211
@@ -1397,6 +1542,7 @@
 	ac41  PCI4410 PC card Cardbus Controller
 	ac42  PCI4451 PC card Cardbus Controller
 		1028 00e6  PCI4451 PC card CardBus Controller (Dell Inspiron 8100)
+	ac44  PCI4510 PC card Cardbus Controller
 	ac50  PCI1410 PC card Cardbus Controller
 	ac51  PCI1420
 		1014 023b  ThinkPad T23 (2647-4MG)
@@ -1405,6 +1551,8 @@
 	ac52  PCI1451 PC card Cardbus Controller
 	ac53  PCI1421 PC card Cardbus Controller
 	ac55  PCI1250 PC card Cardbus Controller
+		1014 0512  ThinkPad T30
+	ac56  PCI1510 PC card Cardbus Controller
 	ac60  PCI2040 PCI to DSP Bridge Controller
 	fe00  FireWire Host Controller
 	fe03  12C01A FireWire Host Controller
@@ -1430,6 +1578,7 @@
 		1050 0840  W89C840 Ethernet Adapter
 	0940  W89C940
 	5a5a  W89C940F
+	6692  W6692
 	9970  W9970CF
 1051  Anigma, Inc.
 1052  ?Young Micro Systems
@@ -1446,6 +1595,8 @@
 	0001  MPC105 [Eagle]
 	0002  MPC106 [Grackle]
 	0003  MPC8240 [Kahlua]
+	0004  MPC107
+	0006  MPC8245 [Unity]
 	0100  MC145575 [HFC-PCI]
 	0431  KTI829c 100VG
 	1801  Audio I/O Controller (MIDI)
@@ -1483,6 +1634,8 @@
 	0d38  20263
 		105a 4d39  Fasttrak66
 	1275  20275
+	3376  PDC20376
+		1043 809e  A7V8X motherboard
 	4d30  20267
 		105a 4d33  Ultra100
 		105a 4d39  Fasttrak100
@@ -1495,12 +1648,14 @@
 	4d68  20268
 		105a 4d68  Ultra100TX2
 	4d69  20269
+		105a 4d68  Ultra133TX2
 	5275  PDC20276 IDE
 		105a 0275  SuperTrak SX6000 IDE
 	5300  DC5300
 	6268  20268R
 	6269  PDC20271
-		105a 6269  Fasttrack tx2
+		105a 6269  FastTrak TX2/TX2000
+	6621  PDC20621 [SX4000] 4 Channel IDE RAID Controller
 	7275  PDC20277
 105b  Foxconn International, Inc.
 105c  Wipro Infotech Limited
@@ -1538,6 +1693,7 @@
 		13cc 0009  Barco Metheus 5 Megapixel, Dual Head
 		13cc 000a  Barco Metheus 5 Megapixel, Dual Head
 	5348  Revolution 4
+		105d 0037  Revolution IV-FP AGP (For SGI 1600SW)
 105e  Vtech Computers Ltd
 105f  Infotronic America Inc
 1060  United Microelectronics [UMC]
@@ -1615,6 +1771,11 @@
 	002e  UniNorth 1.5 PCI
 	002f  UniNorth 1.5 Internal PCI
 	0030  UniNorth/Pangea FireWire
+	0031  UniNorth 2 FireWire
+	0032  UniNorth 2 GMAC (Sun GEM)
+	0033  UniNorth 2 ATA/100
+	0034  UniNorth 2 AGP
+	1645  Tigon3 Gigabit Ethernet NIC (BCM5701)
 106c  Hyundai Electronics America
 	8801  Dual Pentium ISA/PCI Motherboard
 	8802  PowerPC ISA/PCI Motherboard
@@ -1671,6 +1832,7 @@
 	2100  QLA2100 64-bit Fibre Channel Adapter
 		1077 0001  QLA2100 64-bit Fibre Channel Adapter
 	2200  QLA2200
+		1077 0002  QLA2200
 	2300  QLA2300 64-bit FC-AL Adapter
 	2312  QLA2312 Fibre Channel Adapter
 1078  Cyrix Corporation
@@ -1726,7 +1888,8 @@
 1087  Cache Computer
 1088  Microcomputer Systems (M) Son
 1089  Data General Corporation
-108a  SBS Technologies (formerly Bit3 Computer Corp.)
+# Formerly Bit3 Computer Corp.
+108a  SBS Technologies
 	0001  VME Bridge Model 617
 	0010  VME Bridge Model 618
 	0040  dataBLIZZARD
@@ -1818,8 +1981,10 @@
 	b081  IMAQ-PXI-1422
 	b091  IMAQ-PXI-1411
 	c801  PCI-GPIB
+	c831  PCI-GPIB bridge
 1094  First International Computers [FIC]
 1095  CMD Technology Inc
+	0240  Adaptec AAR-1210SA SATA HostRAID Controller
 	0640  PCI0640
 	0643  PCI0643
 	0646  PCI0646
@@ -1834,6 +1999,7 @@
 		1095 0670  USB0670
 	0673  USB0673
 	0680  PCI0680
+	3112  Silicon Image SiI 3112 SATARaid Controller
 1096  Alacron
 1097  Appian Technology
 1098  Quantum Designs (H.K.) Ltd
@@ -1853,8 +2019,10 @@
 	036c  Bt879(??) Video Capture
 		13e9 0070  Win/TV (Video Section)
 	036e  Bt878 Video Capture
-		0070 13eb  WinTV/GO
+		0070 13eb  WinTV Series
 		0070 ff01  Viewcast Osprey 200
+		107d 6606  WinFast TV 2000
+		11bd 0012  PCTV pro (TV + FM stereo receiver)
 		11bd 001c  PCTV Sat (DBC receiver)
 		127a 0001  Bt878 Mediastream Controller NTSC
 		127a 0002  Bt878 Mediastream Controller PAL BG
@@ -1869,6 +2037,7 @@
 		1851 1850  FlyVideo'98 - Video
 		1851 1851  FlyVideo II
 		1852 1852  FlyVideo'98 - Video (with FM Tuner)
+		bd11 1200  PCTV pro (TV + FM stereo receiver)
 	036f  Bt879 Video Capture
 		127a 0044  Bt879 Video Capture NTSC
 		127a 0122  Bt879 Video Capture PAL I
@@ -1904,10 +2073,11 @@
 		1851 1851  FlyVideo'98 EZ - video
 		1852 1852  FlyVideo'98 (with FM Tuner)
 	0878  Bt878 Audio Capture
-		0070 13eb  WinTV/GO
+		0070 13eb  WinTV Series
 		0070 ff01  Viewcast Osprey 200
 		1002 0001  TV-Wonder
 		1002 0003  TV-Wonder/VE
+		11bd 0012  PCTV pro (TV + FM stereo receiver, audio section)
 		11bd 001c  PCTV Sat (DBC receiver)
 		127a 0001  Bt878 Video Capture (Audio Section)
 		127a 0002  Bt878 Video Capture (Audio Section)
@@ -1920,6 +2090,7 @@
 		14f1 0002  Bt878 Video Capture (Audio Section)
 		14f1 0003  Bt878 Video Capture (Audio Section)
 		14f1 0048  Bt878 Video Capture (Audio Section)
+		bd11 1200  PCTV pro (TV + FM stereo receiver, audio section)
 	0879  Bt879 Audio Capture
 		127a 0044  Bt879 Video Capture (Audio Section)
 		127a 0122  Bt879 Video Capture (Audio Section)
@@ -1961,7 +2132,9 @@
 10a2  Quantum Corporation
 10a3  Everex Systems Inc
 10a4  Globe Manufacturing Sales
-10a5  Racal Interlan
+10a5  Smart Link Ltd.
+	3052  SmartPCI562 56K Modem
+	5449  SmartPCI561 modem
 10a6  Informtech Industrial Ltd.
 10a7  Benchmarq Microelectronics
 10a8  Sierra Semiconductor
@@ -1976,6 +2149,7 @@
 	0007  RPCEX
 	0008  DiVO VIP
 	0009  Alteon Gigabit Ethernet
+		10a9 8002  Acenic Gigabit Ethernet
 	0010  AMP Video I/O
 	0011  GRIP
 	0012  SGH PSHAC GSN
@@ -1987,6 +2161,7 @@
 	1006  Dual JPEG 4
 	1007  Dual JPEG 5
 	1008  Cesium
+	100a  IOC4 I/O controller
 	2001  Fibre Channel
 	2002  ASDE
 	8001  O2 1394
@@ -2027,7 +2202,9 @@
 		15ed 1003  MCCS 16-port Serial Hot Swap
 	9036  9036
 	9050  PCI <-> IOBus Bridge
+		10b5 2036  SatPak GPS
 		10b5 2273  SH-ARC SoHard ARCnet card
+		10b5 9050  MP9050
 		1522 0001  RockForce 4 Port V.90 Data/Fax/Voice Modem
 		1522 0002  RockForce 2 Port V.90 Data/Fax/Voice Modem
 		1522 0003  RockForce 6 Port V.90 Data/Fax/Voice Modem
@@ -2038,6 +2215,7 @@
 		15ed 1001  Macrolink MCCS 16-port Serial
 		15ed 1002  Macrolink MCCS 8-port Serial Hot Swap
 		15ed 1003  Macrolink MCCS 16-port Serial Hot Swap
+		5654 5634  OpenLine4 Telephony Card
 		d531 c002  PCIntelliCAN 2xSJA1000 CAN bus
 		d84d 4006  EX-4006 1P
 		d84d 4008  EX-4008 1P EPP/ECP
@@ -2058,6 +2236,7 @@
 		d84d 4078  EX-4078 2S(16C552) RS-232+1P
 	9054  PCI <-> IOBus Bridge
 		10b5 2455  Wessex Techology PHIL-PCI
+		12d9 0002  PCI Prosody Card rev 1.5
 	9060  9060
 	906d  9060SD
 		125c 0640  Aries 16000P
@@ -2065,8 +2244,7 @@
 	9080  9080
 		10b5 9080  9080 [real subsystem ID not set]
 		129d 0002  Aculab PCI Prosidy card
-	a001  GTEK Jetport II 2 port serial adaptor
-	c001  GTEK Cyclone 16/32 port serial adaptor
+		12d9 0002  PCI Prosody Card
 10b6  Madge Networks
 	0001  Smart 16/4 PCI Ringnode
 	0002  Smart 16/4 PCI Ringnode Mk2
@@ -2094,6 +2272,7 @@
 	1001  Collage 155 ATM Server Adapter
 10b7  3Com Corporation
 	0001  3c985 1000BaseSX (SX/TX)
+	0910  3C910-A01
 	1006  MINI PCI type 3B Data Fax Modem
 	1007  Mini PCI 56k Winmodem
 		10b7 615c  Mini PCI 56K Modem
@@ -2172,19 +2351,28 @@
 		1028 0095  Integrated 3C905C-TX Fast Etherlink for PC Management NIC
 		10b7 1000  3C905C-TX Fast Etherlink for PC Management NIC
 		10b7 7000  10/100 Mini PCI Ethernet Adapter
+	9201  3C920B-EMB Integrated Fast Ethernet Controller
+	9300  3CSOHO100B-TX  [910-A01]
 	9800  3c980-TX [Fast Etherlink XL Server Adapter]
 		10b7 9800  3c980-TX Fast Etherlink XL Server Adapter
 	9805  3c980-TX 10/100baseTX NIC [Python-T]
 		10b7 1201  3c982-TXM 10/100baseTX Dual Port A [Hydra]
 		10b7 1202  3c982-TXM 10/100baseTX Dual Port B [Hydra]
 		10b7 9805  3c980 10/100baseTX NIC [Python-T]
-	9900  3C990-TX Typhoon
-	9902  3CR990-TX-95 56-bit Typhoon Client
-	9903  3CR990-TX-97 168-bit Typhoon Client
+		10f1 2462  Thunder K7 S2462
+	9900  3C990-TX [Typhoon]
+	9902  3CR990-TX-95 [Typhoon 56-bit]
+	9903  3CR990-TX-97 [Typhoon 168-bit]
 	9904  3C990B-TX-M/3C990BSVR [Typhoon2]
+		10b7 1000  3CR990B-TX-M [Typhoon2]
+		10b7 2000  3CR990BSVR [Typhoon2 Server]
 	9905  3CR990-FX-95/97/95 [Typhon Fiber]
-	9908  3CR990SVR95 56-bit Typhoon Server
-	9909  3CR990SVR97 Typhoon Server
+		10b7 1101  3CR990-FX-95 [Typhoon Fiber 56-bit]
+		10b7 1102  3CR990-FX-97 [Typhoon Fiber 168-bit]
+		10b7 2101  3CR990-FX-95 Server [Typhoon Fiber 56-bit]
+		10b7 2102  3CR990-FX-97 Server [Typhoon Fiber 168-bit]
+	9908  3CR990SVR95 [Typhoon Server 56-bit]
+	9909  3CR990SVR97 [Typhoon Server 168-bit]
 	990b  3C990SVR [Typhoon Server]
 10b8  Standard Microsystems Corp [SMC]
 	0005  83C170QF
@@ -2207,7 +2395,7 @@
 	1001  FDC 37C922
 	a011  83C170QF
 	b106  SMC34C90
-10b9  ALi Corporation. [ALi]
+10b9  ALi Corporation
 	0111  C-Media CMI8738/C3DX Audio Device (OEM)
 		10b9 0111  C-Media CMI8738/C3DX Audio Device (OEM)
 	1435  M1435
@@ -2229,7 +2417,7 @@
 	1541  M1541
 		10b9 1541  ALI M1541 Aladdin V/V+ AGP System Controller
 	1543  M1543
-	1563  M1563 South Bridge supporting HT Technology
+	1563  M1563 HyperTransport South Bridge
 	1621  M1621
 	1631  ALI M1631 PCI North Bridge Aladdin Pro III
 	1632  M1632M Northbridge+Trident
@@ -2238,9 +2426,9 @@
 	1646  M1646 Northbridge+Trident
 	1647  M1647 Northbridge [MAGiK 1 / MobileMAGiK 1]
 	1651  M1651/M1651T Northbridge [Aladdin-Pro 5/5M,Aladdin-Pro 5T/5TM]
-	1671  M1671 Super P4 Northbridge [AGP4X,PCI, and SDR/DDR]
-	1681  M1681 P4 Northbridge [AGP8X,HT, and SDR/DDR]
-	1687  M1687 K8 Northbridge [AGP8X and HT]
+	1671  M1671 Super P4 Northbridge [AGP4X,PCI and SDR/DDR]
+	1681  M1681 P4 Northbridge [AGP8X,HyperTransport and SDR/DDR]
+	1687  M1687 K8 Northbridge [AGP8X and HyperTransport]
 	3141  M3141
 	3143  M3143
 	3145  M3145
@@ -2261,14 +2449,20 @@
 	5239  USB 2.0 Controller
 	5243  M1541 PCI to AGP Controller
 	5247  PCI to AGP Controller
-	5249  HTT to PCI Bridge
+	5249  M5249 HTT to PCI Bridge
 	5251  M5251 P1394 OHCI 1.0 Controller
 	5253  M5253 P1394 OHCI 1.1 Controller
 	5261  M5261 Ethernet Controller
+	5450  Lucent Technologies Soft Modem AMR
 	5451  M5451 PCI AC-Link Controller Audio Device
+		1014 0506  ThinkPad R30
 	5453  M5453 PCI AC-Link Controller Modem Device
 	5455  M5455 PCI AC-Link Controller Audio Device
-	5457  M5457 AC-Link Modem Interface Controller
+	5457  Intel 537 [M5457 AC-Link Modem]
+# Same but more usefull for driver's lookup
+	5459  SmartLink SmartPCI561 56K Modem
+# SmartLink PCI SoftModem
+	545a  SmartLink SmartPCI563 56K Modem
 	5471  M5471 Memory Stick Controller
 	5473  M5473 SD-MMC Controller
 	7101  M7101 PMU
@@ -2291,7 +2485,7 @@
 10c6  Rambus Inc.
 10c7  Media Vision
 10c8  Neomagic Corporation
-	0001  NM2070 [MagicGraph NM2070]
+	0001  NM2070 [MagicGraph 128]
 	0002  NM2090 [MagicGraph 128V]
 	0003  NM2093 [MagicGraph 128ZV]
 	0004  NM2160 [MagicGraph 128XD]
@@ -2313,13 +2507,14 @@
 		10f7 830b  MagicGraph 128XD
 		10f7 830d  MagicGraph 128XD
 		10f7 8312  MagicGraph 128XD
-	0005  [MagicMedia 256AV]
+	0005  NM2200 [MagicGraph 256AV]
+		1014 00dd  ThinkPad 570
 	0006  NM2360 [MagicMedia 256ZX]
 	0016  NM2380 [MagicMedia 256XL+]
 		10c8 0016  MagicMedia 256XL+
-	0025  [MagicMedia 256AV+]
-	0083  [MagicGraph 128ZV Plus]
-	8005  [MagicMedia 256AV Audio]
+	0025  NM2230 [MagicGraph 256AV+]
+	0083  NM2093 [MagicGraph 128ZV+]
+	8005  NM2200 [MagicMedia 256AV Audio]
 		0e11 b0d1  MagicMedia 256AV Audio Device on Discovery
 		0e11 b126  MagicMedia 256AV Audio Device on Durango
 		1014 00dd  MagicMedia 256AV Audio Device on BlackTip Thinkpad
@@ -2332,7 +2527,7 @@
 		110a 8005  MagicMedia 256AV Audio Device
 		14c0 0004  MagicMedia 256AV Audio Device
 	8006  NM2360 [MagicMedia 256ZX Audio]
-	8016  NM2360 [MagicMedia 256ZX Audio]
+	8016  NM2380 [MagicMedia 256XL+ Audio]
 10c9  Dataexpert Corporation
 10ca  Fujitsu Microelectr., Inc.
 10cb  Omron Corporation
@@ -2377,7 +2572,7 @@
 	0008  NV1 [EDGE 3D]
 	0009  NV1 [EDGE 3D]
 	0010  NV2 [Mutara V08]
-	0020  NV4 [Riva TnT]
+	0020  NV4 [RIVA TNT]
 		1043 0200  V3400 TNT
 		1048 0c18  Erazor II SGRAM
 		1048 0c1b  Erazor II
@@ -2394,15 +2589,17 @@
 		1092 4914  Viper V550
 		1092 8225  Viper V550
 		10b4 273d  Velocity 4400
+		10b4 273e  Velocity 4400
 		10b4 2740  Velocity 4400
 		10de 0020  Riva TNT
 		1102 1015  Graphics Blaster CT6710
 		1102 1016  Graphics Blaster RIVA TNT
-	0028  NV5 [Riva TnT2]
+	0028  NV5 [RIVA TNT2/TNT2 Pro]
 		1043 0200  AGP-V3800 SGRAM
 		1043 0201  AGP-V3800 SDRAM
 		1043 0205  PCI-V3800
 		1043 4000  AGP-V3800PRO
+		1048 0c21  Synergy II
 		1092 4804  Viper V770
 		1092 4a00  Viper V770
 		1092 4a02  Viper V770 Ultra
@@ -2414,7 +2611,7 @@
 		1102 1020  3D Blaster RIVA TNT2
 		1102 1026  3D Blaster RIVA TNT2 Digital
 		14af 5810  Maxi Gamer Xentor
-	0029  NV5 [Riva TnT2 Ultra]
+	0029  NV5 [RIVA TNT2 Ultra]
 		1043 0200  AGP-V3800 Deluxe
 		1043 0201  AGP-V3800 Ultra SDRAM
 		1043 0205  PCI-V3800 Ultra
@@ -2424,16 +2621,18 @@
 		14af 5820  Maxi Gamer Xentor 32
 	002a  NV5 [Riva TnT2]
 	002b  NV5 [Riva TnT2]
-	002c  NV6 [Vanta]
+	002c  NV6 [Vanta/Vanta LT]
 		1043 0200  AGP-V3800 Combat SDRAM
 		1043 0201  AGP-V3800 Combat
 		1092 6820  Viper V730
 		1102 1031  CT6938 VANTA 8MB
 		1102 1034  CT6894 VANTA 16MB
 		14af 5008  Maxi Gamer Phoenix 2
-	002d  RIVA TNT2 Model 64
+	002d  NV5M64 [RIVA TNT2 Model 64/Model 64 Pro]
 		1043 0200  AGP-V3800M
 		1043 0201  AGP-V3800M
+		1048 0c3a  Erazor III LT
+		10de 001e  M64 AGP4x
 		1102 1023  CT6892 RIVA TNT2 Value
 		1102 1024  CT6932 RIVA TNT2 Value 32Mb
 		1102 102c  CT6931 RIVA TNT2 Value [Jumper]
@@ -2441,7 +2640,19 @@
 		1554 1041  PixelView RIVA TNT2 M64 32MB
 	002e  NV6 [Vanta]
 	002f  NV6 [Vanta]
-	00a0  NV5 [Riva TNT2]
+	0060  nForce2 ISA Bridge
+		1043 80ad  A7N8X Mainboard
+	0064  nForce2 SMBus (MCP)
+	0065  nForce2 IDE
+	0066  nForce2 Ethernet Controller
+	0067  nForce2 USB Controller
+		1043 0c11  A7N8X Mainboard
+	0068  nForce2 USB Controller
+		1043 0c11  A7N8X Mainboard
+	006a  nForce2 AC97 Audio Controler (MCP)
+	006b  nForce MultiMedia audio [Via VT82C686B]
+	006e  nForce2 FireWire (IEEE 1394) Controller
+	00a0  NV5 [Aladdin TNT2]
 		14af 5810  Maxi Gamer Xentor
 	0100  NV10 [GeForce 256 SDR]
 		1043 0200  AGP-V6600 SGRAM
@@ -2450,40 +2661,53 @@
 		1043 4009  AGP-V6600 SDRAM
 		1102 102d  CT6941 GeForce 256
 		14af 5022  3D Prophet SE
-	0101  NV10 [GeForce 256 DDR]
+	0101  NV10DDR [GeForce 256 DDR]
 		1043 0202  AGP-V6800 DDR
 		1043 400a  AGP-V6800 DDR SGRAM
 		1043 400b  AGP-V6800 DDR SDRAM
 		1102 102e  CT6971 GeForce 256 DDR
 		14af 5021  3D Prophet DDR-DVI
-	0103  NV10 [Quadro]
-	0110  NV11 [GeForce2 MX]
+	0103  NV10GL [Quadro]
+	0110  NV11 [GeForce2 MX/MX 400]
 		1043 4015  AGP-V7100 Pro
 		1043 4031  V7100 Pro with TV output
+		1462 8817  MSI GeForce2 MX400 Pro32S [MS-8817]
+		14af 7102  3D Prophet II MX
 		14af 7103  3D Prophet II MX Dual-Display
-	0111  NV11 [GeForce2 MX DDR]
+	0111  NV11DDR [GeForce2 MX 100 DDR/200 DDR]
 	0112  NV11 [GeForce2 Go]
-	0113  NV11 [GeForce2 MXR]
-	0150  NV15 [GeForce2 GTS]
+	0113  NV11GL [Quadro2 MXR/EX]
+	0150  NV15 [GeForce2 GTS/Pro]
 		1043 4016  V7700 AGP Video Card
 		107d 2840  WinFast GeForce2 GTS with TV output
 		1462 8831  Creative GeForce2 Pro
-	0151  NV15 [GeForce2 Ti]
-	0152  NV15 [GeForce2 Ultra, Bladerunner]
+	0151  NV15DDR [GeForce2 Ti]
+		1043 405f  V7700Ti
+	0152  NV15BR [GeForce2 Ultra, Bladerunner]
 		1048 0c56  GLADIAC Ultra
-	0153  NV15 [Quadro2 Pro]
-	0170  NV17 [GeForce4 MX460]
-	0171  NV17 [GeForce4 MX440]
-	0172  NV17 [GeForce4 MX420]
-	0173  NV1x
+	0153  NV15GL [Quadro2 Pro]
+	0170  NV17 [GeForce4 MX 460]
+	0171  NV17 [GeForce4 MX 440]
+		10b0 0002  Gainward Pro/600 TV
+		1462 8661  G4MX440-VTP
+		1462 8730  MX440SES-T (MS-8873)
+		147b 8f00  Abit Siluro GeForce4MX440
+	0172  NV17 [GeForce4 MX 420]
+	0173  NV17 [GeForce4 MX 440-SE]
 	0174  NV17 [GeForce4 440 Go]
 	0175  NV17 [GeForce4 420 Go]
 	0176  NV17 [GeForce4 420 Go 32M]
-	0178  Quadro4 500XGL
+	0178  NV17GL [Quadro4 550 XGL]
 	0179  NV17 [GeForce4 440 Go 64M]
-	017a  Quadro4 200/400NVS
-	017b  Quadro4 550XGL
-	017c  Quadro4 550 GoGL
+	017a  NV17GL [Quadro4 200/400 NVS]
+	017b  NV17GL [Quadro4 550 XGL]
+	017c  NV17GL [Quadro4 550 GoGL]
+	0181  NV18 [GeForce4 MX 440 AGP 8x]
+	0182  NV18 [GeForce4 MX 440SE AGP 8x]
+	0183  NV18 [GeForce4 MX 420 AGP 8x]
+	0188  NV18GL [Quadro4 580 XGL]
+	018a  NV18GL [Quadro4 NVS]
+	018b  NV18GL [Quadro4 380 XGL]
 	01a0  NV15 [GeForce2 - nForce GPU]
 	01a4  nForce CPU bridge
 	01ab  nForce 420 Memory Controller (DDR)
@@ -2495,31 +2719,54 @@
 	01b7  nForce AGP to PCI Bridge
 	01b8  nForce PCI-to-PCI bridge
 	01bc  nForce IDE
+	01c1  Intel 537 [nForce MC97 Modem]
+	01c2  nForce USB Controller
+	01c3  nForce Ethernet Controller
+	01e8  nForce2 AGP
+	01f0  NV18 [GeForce4 MX - nForce GPU]
 	0200  NV20 [GeForce3]
 		1043 402f  AGP-V8200 DDR
-	0201  NV20 [GeForce3 Ti200]
-	0202  NV20 [GeForce3 Ti500]
+	0201  NV20 [GeForce3 Ti 200]
+	0202  NV20 [GeForce3 Ti 500]
 		1043 405b  V8200 T5
-	0203  NV20 [Quadro DCC]
-	0250  NV25 [GeForce4 Ti4600]
-	0251  NV25 [GeForce4 Ti4400]
-	0253  NV25 [GeForce4 Ti4200]
-	0258  Quadro4 900XGL
-	0259  Quadro4 750XGL
-	025b  Quadro4 700XGL
+		1545 002f  Xtasy 6964
+	0203  NV20DCC [Quadro DCC]
+	0250  NV25 [GeForce4 Ti 4600]
+	0251  NV25 [GeForce4 Ti 4400]
+	0252  NV25 [GeForce4 Ti]
+	0253  NV25 [GeForce4 Ti 4200]
+		107d 2896  WinFast A250 LE TD (Dual VGA/TV-out/DVI)
+		147b 8f09  Siluro (Dual VGA/TV-out/DVI)
+	0258  NV25GL [Quadro4 900 XGL]
+	0259  NV25GL [Quadro4 750 XGL]
+	025b  NV25GL [Quadro4 700 XGL]
+	0280  NV28 [GeForce4 Ti 4800]
+	0281  NV28 [GeForce4 Ti 4200 AGP 8x]
+	0282  NV28 [GeForce4 Ti 4800 SE]
+	0286  NV28 [GeForce4 Ti 4200 Go AGP 8x]
+	0288  NV28GL [Quadro4 980 XGL]
+	0289  NV28GL [Quadro4 780 XGL]
+	0300  NV30 [GeForce FX]
+	0301  NV30 [GeForce FX 5800 Ultra]
+	0302  NV30 [GeForce FX 5800]
+	0308  NV30GL [Quadro FX 2000]
+	0309  NV30GL [Quadro FX 1000]
 10df  Emulex Corporation
-	10df  Light Pulse Fibre Channel Adapter
 	1ae5  LP6000 Fibre Channel Host Adapter
+	f085  LP850 Fibre Channel Adapter
+	f095  LP952 Fibre Channel Adapter
+	f098  LP982 Fibre Channel Adapter
 	f700  LP7000 Fibre Channel Host Adapter
 	f800  LP8000 Fibre Channel Host Adapter
 	f900  LP9000 Fibre Channel Host Adapter
+	f980  LP9802 Fibre Channel Adapter
 10e0  Integrated Micro Solutions Inc.
 	5026  IMS5026/27/28
 	5027  IMS5027
 	5028  IMS5028
 	8849  IMS8849
 	8853  IMS8853
-	9128  IMS9129 [Twin turbo 128]
+	9128  IMS9128 [Twin turbo 128]
 10e1  Tekram Technology Co.,Ltd.
 	0391  TRM-S1040
 		10e1 0391  DC-315U SCSI-3 Host Adapter
@@ -2529,6 +2776,7 @@
 10e3  Tundra Semiconductor Corp.
 	0000  CA91C042 [Universe]
 	0860  CA91C860 [QSpan]
+	0862  CA91C862A [QSpan-II]
 10e4  Tandem Computers
 10e5  Micro Industries Corporation
 10e6  Gainbery Computer Products Inc.
@@ -2558,6 +2806,7 @@
 	2010  CyberPro 2000A
 	5000  CyberPro 5000
 	5050  CyberPro 5050
+	5202  CyberPro 5202
 10eb  Artists Graphics
 	0101  3GA
 	8111  Twist3 Frame Grabber
@@ -2580,6 +2829,7 @@
 		1186 1300  DFE-538TX
 		1186 1320  SN5200
 		1186 8139  DRN-32TX
+		11f6 8139  FN22-3(A) LinxPRO Ethernet Adapter
 		1259 2500  AT-2500TX
 		1259 2503  AT-2500TX/ACPI
 		1429 d010  ND010
@@ -2595,9 +2845,11 @@
 		8e2e 7100  KF-230TX/2
 		a0a0 0007  ALN-325C
 	8169  RTL-8169
+		1371 434e  ProG-2000L
+	8197  SmartLAN56 56K Modem
 10ed  Ascii Corporation
 	7310  V7310
-10ee  Xilinx, Inc.
+10ee  Xilinx Corporation
 	3fc0  RME Digi96
 	3fc1  RME Digi96/8
 	3fc2  RME Digi96/8 Pro
@@ -2620,6 +2872,7 @@
 10fa  Truevision
 	000c  TARGA 1000
 10fb  Thesys Gesellschaft für Mikroelektronik mbH
+	186f  TH 6255
 10fc  I-O Data Device, Inc.
 # What's in the cardbus end of a Sony ACR-A01 card, comes with newer Vaio CD-RW drives
 	0003  Cardbus IDE Controller
@@ -2651,14 +2904,21 @@
 		1102 8040  CT4760 SBLive!
 		1102 8051  CT4850 SBLive! Value
 		1102 8061  SBLive! Player 5.1
+		1102 8064  SB Live! 5.1 Model SB0100
+		1102 8065  SBLive! 5.1 Digital Model SB0220
 	0004  SB Audigy
 		1102 0051  SB0090 Audigy Player
+		1102 0053  SB0090 Audigy Player/OEM
+	0006  [SB Live! Value] EMU10k1X
 	4001  SB Audigy FireWire Port
+		1102 0010  SB Audigy FireWire Port
 	7002  SB Live! MIDI/Game Port
 		1102 0020  Gameport Joystick
 	7003  SB Audigy MIDI/Game port
-		1102 0040  SB Audigy MIDI/Gameport
-	8938  ES1371
+		1102 0040  SB Audigy MIDI/Game Port
+	7004  [SB Live! Value] Input device controller
+	8064  SB0100 [SBLive! 5.1 OEM]
+	8938  Ectiva EV1938
 1103  Triones Technologies, Inc.
 	0003  HPT343
 # Revisions: 01=HPT366, 03=HPT370, 04=HPT370A, 05=HPT372
@@ -2669,23 +2929,32 @@
 	0006  HPT302
 	0007  HPT371
 	0008  HPT374
+	0009  HPT372N
 1104  RasterOps Corp.
 1105  Sigma Designs, Inc.
 	1105  REALmagic Xcard MPEG 1/2/3/4 DVD Decoder
 	8300  REALmagic Hollywood Plus DVD Decoder
 	8400  EM840x REALmagic DVD/MPEG-2 Audio/Video Decoder
 1106  VIA Technologies, Inc.
+	0102  Embedded VIA Ethernet Controller
 	0130  VT6305 1394.A Controller
 	0305  VT8363/8365 [KT133/KM133]
 		1043 8033  A7V Mainboard
+		1043 803e  A7V-E Mainboard
 		1043 8042  A7V133/A7V133-C Mainboard
 		147b a401  KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard
 	0391  VT8371 [KX133]
 	0501  VT8501 [Apollo MVP4]
 	0505  VT82C505
-	0561  VT82C561
-	0571  VT82C586B PIPC Bus Master IDE
-		1458 5002 GA-7VAX Mainboard
+# Shares chip with :0576. The VT82C576M has :1571 instead of :0561.
+	0561  VT82C576MV
+	0571  VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE
+		1019 0985  P6VXA Motherboard
+		1043 8052  VT8233A Bus Master ATA100/66/33 IDE
+		1043 808c  A7V8X motherboard
+		1106 0571  VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE
+		1179 0001  Magnia Z310
+		1458 5002  GA-7VAX Mainboard
 	0576  VT82C576 3V [Apollo Master]
 	0585  VT82C585VP [Apollo VP1/VPX]
 	0586  VT82C586/A/B PCI-to-ISA [Apollo VP]
@@ -2698,24 +2967,35 @@
 	0598  VT82C598 [Apollo MVP3]
 	0601  VT8601 [Apollo ProMedia]
 	0605  VT8605 [ProSavage PM133]
+		1043 802c  CUV4X mainboard
 	0680  VT82C680 [Apollo P6]
 	0686  VT82C686 [Apollo Super South]
+		1019 0985  P6VXA Motherboard
+		1043 802c  CUV4X mainboard
 		1043 8033  A7V Mainboard
+		1043 803e  A7V-E Mainboard
+		1043 8040  A7M266 Mainboard
 		1043 8042  A7V133/A7V133-C Mainboard
 		1106 0000  VT82C686/A PCI to ISA Bridge
 		1106 0686  VT82C686/A PCI to ISA Bridge
+		1179 0001  Magnia Z310
+		147b a702  KG7-Lite Mainboard
 	0691  VT82C693A/694x [Apollo PRO133x]
+		1019 0985  P6VXA Motherboard
+		1179 0001  Magnia Z310
 		1458 0691  VT82C691 Apollo Pro System Controller
 	0693  VT82C693 [Apollo Pro Plus]
 	0698  VT82C693A [Apollo Pro133 AGP]
 	0926  VT82C926 [Amazon]
 	1000  VT82C570MV
 	1106  VT82C570MV
-	1571  VT82C416MV
+	1571  VT82C576M/VT82C586
 	1595  VT82C595/97 [Apollo VP2/97]
 	3038  USB
 		0925 1234  USB Controller
-		1234 0925  MVP3 USB Controller
+		1019 0985  P6VXA Motherboard
+		1043 808c  A7V8X motherboard
+		1179 0001  Magnia Z310
 	3040  VT82C586B ACPI
 	3043  VT86C100A [Rhine]
 		10bd 0000  VT86C100A Fast Ethernet Adapter
@@ -2725,41 +3005,60 @@
 	3050  VT82C596 Power Management
 	3051  VT82C596 Power Management
 	3057  VT82C686 [Apollo Super ACPI]
+		1019 0985  P6VXA Motherboard
 		1043 8033  A7V Mainboard
+		1043 803e  A7V-E Mainboard
+		1043 8040  A7M266 Mainboard
 		1043 8042  A7V133/A7V133-C Mainboard
+		1179 0001  Magnia Z310
 	3058  VT82C686 AC97 Audio Controller
 		0e11 b194  Soundmax integrated digital audio
+		1019 0985  P6VXA Motherboard
 		1106 4511  Onboard Audio on EP7KXA
 		1458 7600  Onboard Audio
 		1462 3091  MS-6309 Onboard Audio
 		15dd 7609  Onboard Audio
-	3059  VT8233 AC97 Audio Controller
-		1458 a002  GA-7VAX Onboard Audio (Realtek ALC650) 
+	3059  VT8233/A/8235 AC97 Audio Controller
+		1043 8095  A7V8X Motherboard (Realtek ALC650 codec)
+		1458 a002  GA-7VAX Onboard Audio (Realtek ALC650)
 	3065  VT6102 [Rhine-II]
+		1106 0102  VT6102 [Rhine II] Embeded Ethernet Controller on VT8235
 		1186 1400  DFE-530TX rev A
 		1186 1401  DFE-530TX rev B
-	3068  AC97 Modem Controller
+		13b9 1421  LD-10/100AL PCI Fast Ethernet Adapter (rev.B)
+	3068  Intel 537 [AC97 Modem]
 	3074  VT8233 PCI to ISA Bridge
+		1043 8052  VT8233A
 	3091  VT8633 [Apollo Pro266]
-	3099  VT8367 [KT266]
-		1043 8064  A7V266-E
-		1043 807f  A7V333
+	3099  VT8366/A/7 [Apollo KT266/A/333]
+		1043 8064  A7V266-E Mainboard
+		1043 807f  A7V333 Mainboard
 	3101  VT8653 Host Bridge
 	3102  VT8662 Host Bridge
 	3103  VT8615 Host Bridge
 	3104  USB 2.0
+		1043 808c  A7V8X motherboard
 		1458 5004  GA-7VAX Mainboard
+	3106  VT6105 [Rhine-III]
 	3109  VT8233C PCI to ISA Bridge
 	3112  VT8361 [KLE133] Host Bridge
+	3116  VT8375 [KM266/KL266] Host Bridge
+# found on EPIA M6000/9000 mainboard
+	3122  VT8623 [Apollo CLE266] integrated CastleRock graphics
+# found on EPIA M6000/9000 mainboard
+	3123  VT8623 [Apollo CLE266]
 	3128  VT8753 [P4X266 AGP]
 	3133  VT3133 Host Bridge
 	3147  VT8233A ISA Bridge
 	3148  P4M266 Host Bridge
 	3156  P/KN266 Host Bridge
-	3177  VT8233A ISA Bridge
-		1458 5001 GA-7VAX Mainboard
+	3168  VT8374 P4X400 Host Controller/AGP Bridge
+	3177  VT8235 ISA Bridge
+		1043 808c  A7V8X motherboard
+		1458 5001  GA-7VAX Mainboard
 	3189  VT8377 [KT400 AGP] Host Bridge
-		1458 5000 GA-7VAX Mainboard
+		1043 807f  A7V8X motherboard
+		1458 5000  GA-7VAX Mainboard
 	5030  VT82C596 ACPI [Apollo PRO]
 	6100  VT85C100A [Rhine II]
 	8231  VT8231 [PCI-to-ISA Bridge]
@@ -2770,12 +3069,13 @@
 	8596  VT82C596 [Apollo PRO AGP]
 	8597  VT82C597 [Apollo VP3 AGP]
 	8598  VT82C598/694x [Apollo MVP3/Pro133x AGP]
+		1019 0985  P6VXA Motherboard
 	8601  VT8601 [Apollo ProMedia AGP]
 	8605  VT8605 [PM133 AGP]
 	8691  VT82C691 [Apollo Pro]
 	8693  VT82C693 [Apollo Pro Plus] PCI Bridge
 	b091  VT8633 [Apollo Pro266 AGP]
-	b099  VT8367 [KT333 AGP]
+	b099  VT8366/A/7 [Apollo KT266/A/333 AGP]
 	b101  VT8653 AGP Bridge
 	b102  VT8362 AGP Bridge
 	b103  VT8615 AGP Bridge
@@ -2797,6 +3097,12 @@
 110a  Siemens Nixdorf AG
 	0002  Pirahna 2-port
 	0005  Tulip controller, power management, switch extender
+	0006  FSC PINC (I/O-APIC)
+	0015  FSC Multiprocessor Interrupt Controller
+	001d  FSC Copernicus Management Controller
+	007b  FSC Remote Service Controller, mailbox device
+	007c  FSC Remote Service Controller, shared memory device
+	007d  FSC Remote Service Controller, SMIC device
 	2102  DSCC4 WAN adapter
 	4942  FPGA I-Bus Tracer for MBD
 	6120  SZB6120
@@ -2811,8 +3117,8 @@
 	6037  Firepower Powerized SMP I/O ASIC
 	6073  Firepower Powerized SMP I/O ASIC
 1111  Santa Cruz Operation
-# DJ: Some people say that 0x1112 is Rockwell International
-1112  RNS - Div. of Meret Communications Inc
+# Also claimed to be RNS or Rockwell International, current PCISIG records list Osicom
+1112  Osicom Technologies Inc
 	2200  FDDI Adapter
 	2300  Fast Ethernet Adapter
 	2340  4 Port Fast Ethernet Adapter
@@ -2822,6 +3128,7 @@
 		103c 1207  EN-1207D Fast Ethernet Adapter
 		1113 1211  EN-1207D Fast Ethernet Adapter
 	1216  EN-1216 Ethernet Adapter
+		111a 1020  SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?]
 	1217  EN-1217 Ethernet Adapter
 	5105  10Mbps Network card
 	9211  EN-1207D Fast Ethernet Adapter
@@ -2962,9 +3269,14 @@
 	0001  MVC IM-PCI Video frame grabber/processor
 1130  Computervision
 1131  Philips Semiconductors
+	1561  USB 1.1 Host Controller
+	1562  USB 2.0 Host Controller
+	3400  SmartPCI56(UCB1500) 56K Modem
 	7130  SAA7130 Video Broadcast Decoder
+	7133  SAA7133 Audio+video broadcast decoder
 # PCI audio and video broadcast decoder (http://www.semiconductors.philips.com/pip/saa7134hl)
 	7134  SAA7134
+	7135  SAA7135 Audio+video broadcast decoder
 	7145  SAA7145
 	7146  SAA7146
 		114b 2003  DVRaptor Video Edit/Capture Card
@@ -2993,6 +3305,7 @@
 		1133 e004  DIVA 2.0 U
 	e005  DIVA LOW
 		1133 e005  DIVA 2.01 S/T
+	e00b  DIVA 2.02
 	e010  DIVA Server BRI-2M
 		1133 e010  DIVA Server BRI-2M
 	e012  DIVA Server BRI-8M
@@ -3041,15 +3354,15 @@
 1144  Cincinnati Milacron
 	0001  Noservo controller
 1145  Workbit Corporation
-	f007  NinjaSCSI-32 KME
 	8007  NinjaSCSI-32 Workbit
+	f007  NinjaSCSI-32 KME
 	f010  NinjaSCSI-32 Workbit
 	f012  NinjaSCSI-32 Logitec
 	f013  NinjaSCSI-32 Logitec
 	f015  NinjaSCSI-32 Melco
 1146  Force Computers
 1147  Interface Corp
-1148  SysKonnect
+1148  Syskonnect (Schneider & Koch)
 	4000  FDDI Adapter
 		0e11 b03b  Netelligent 100 FDDI DAS Fibre SC
 		0e11 b03c  Netelligent 100 FDDI SAS Fibre SC
@@ -3067,29 +3380,37 @@
 		1148 5843  FDDI SK-5843 (SK-NET FDDI-LP64)
 		1148 5844  FDDI SK-5844 (SK-NET FDDI-LP64 DAS)
 	4200  Token Ring adapter
-	4300  SK-98xx Gigabit Ethernet Server Adapter
-		1148 9821  SK-9821 Gigabit Ethernet 1000Base-T Server Adapter
-		1148 9822  SK-9822 Gigabit Ethernet 1000Base-T Dual Port Server Adapter
-		1148 9841  SK-9841 Gigabit Ethernet 1000Base-LX Server Adapter
-		1148 9842  SK-9842 Gigabit Ethernet 1000Base-LX Dual Port Server Adapter
-		1148 9843  SK-9843 Gigabit Ethernet 1000Base-SX Server Adapter
-		1148 9844  SK-9844 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter
-		1148 9861  SK-9861 Gigabit Ethernet 1000Base-SX Server Adapter
-		1148 9862  SK-9862 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter
-		1148 9871  SK-9871 Gigabit Ethernet 1000Base-ZX Server Adapter
-		1148 9872  SK-9872 Gigabit Ethernet 1000Base-ZX Dual Port Server Adapter
+	4300  Gigabit Ethernet
+		1148 9821  SK-9821 (1000Base-T single link)
+		1148 9822  SK-9822 (1000Base-T dual link)
+		1148 9841  SK-9841 (1000Base-LX single link)
+		1148 9842  SK-9842 (1000Base-LX dual link)
+		1148 9843  SK-9843 (1000Base-SX single link)
+		1148 9844  SK-9844 (1000Base-SX dual link)
+		1148 9861  SK-9861 (1000Base-SX VF45 single link)
+		1148 9862  SK-9862 (1000Base-SX VF45 dual link)
+# Information got from SysKonnekt
+		1148 9871  SK-9871 (1000Base-ZX single link)
+# Information got from SysKonnekt
+		1148 9872  SK-9872 (1000Base-ZX dual link)
+		1259 2970  AT-2970SX [Allied Telesyn]
+		1259 2972  AT-2970T [Allied Telesyn]
+		1259 2975  AT-2970SX [Allied Telesyn]
+		1259 2977  AT-2970T [Allied Telesyn]
 	4320  SK-98xx Gigabit Ethernet Server Adapter
-		1148 9521  SK-9521 10/100/1000Base-T Adapter
 		1148 5021  SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
 		1148 5041  SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
 		1148 5043  SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
 		1148 5051  SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
 		1148 5061  SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
 		1148 5071  SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
+		1148 9521  SK-9521 10/100/1000Base-T Adapter
 	4400  Gigabit Ethernet
 1149  Win System Corporation
 114a  VMIC
 	5579  VMIPCI-5579 (Reflective Memory Card)
+	5587  VMIPCI-5587 (Reflective Memory Card)
+	6504  VMIC PCI 7755 FPGA
 	7587  VMIVME-7587
 114b  Canopus Co., Ltd
 114c  Annabooks
@@ -3200,11 +3521,13 @@
 	0001  Motion TPEG Recorder/Player with audio
 1166  ServerWorks
 	0005  CNB20-LE Host Bridge
+	0006  CNB20HE Host Bridge
 	0007  CNB20-LE Host Bridge
 	0008  CNB20HE Host Bridge
 	0009  CNB20LE Host Bridge
 	0010  CIOB30
 	0011  CMIC-HE
+	0012  CMIC-LE
 	0013  CNB20-HE Host Bridge
 	0014  CNB20-HE Host Bridge
 	0015  CMIC-GC Host Bridge
@@ -3270,7 +3593,9 @@
 	0465  RL5c465
 	0466  RL5c466
 	0475  RL5c475
+		144d c006  vpr Matrix 170B4 CardBus bridge
 	0476  RL5c476 II
+		1014 0185  ThinkPad A/T/X Series
 		104d 80df  Vaio PCG-FX403
 		104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
 	0477  RL5c477
@@ -3279,7 +3604,9 @@
 	0522  R5C522 IEEE 1394 Controller
 		1014 01cf  ThinkPad A30p (2653-64G)
 	0551  R5C551 IEEE 1394 Controller
+		144d c006  vpr Matrix 170B4
 	0552  R5C552 IEEE 1394 Controller
+		1014 0511  ThinkPad A/T/X Series
 1181  Telmatics International
 1183  Fujikura Ltd
 1184  Forks Inc
@@ -3371,7 +3698,9 @@
 	4240  AMCC S933Q Intelligent Serial Card
 11aa  Actel
 11ab  Galileo Technology Ltd.
-	0146  GT-64010
+	0146  GT-64010/64010A System Controller
+	4611  GT-64115 System Controller
+	4620  GT-64120/64120A/64121A System Controller
 	4801  GT-48001
 	f003  GT-64010 Primary Image Piranha Image Generator
 11ac  Canon Information Systems Research Aust.
@@ -3467,6 +3796,7 @@
 	0443  LT WinModem
 	0444  LT WinModem
 	0445  LT WinModem
+		8086 2203  PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card)
 	0446  LT WinModem
 	0447  LT WinModem
 	0448  WinModem 56k
@@ -3496,6 +3826,7 @@
 	044e  LT WinModem
 	044f  V90 WildWire Modem
 	0450  LT WinModem
+		144f 4005  Magnia SG20
 	0451  LT WinModem
 	0452  LT WinModem
 	0453  LT WinModem
@@ -3506,15 +3837,18 @@
 	0458  LT WinModem
 	0459  LT WinModem
 	045a  LT WinModem
+	045c  LT WinModem
 	0461  V90 WildWire Modem
 	0462  V90 WildWire Modem
 	0480  Venus Modem (V90, 56KFlex)
 	5801  USB
 	5802  USS-312 USB Controller
+# 4 port PCI USB Controller made by Agere (formely Lucent)
+	5803  USS-344S USB Controller
 	5811  FW323
 		dead 0800  FireWire Host Bus Adapter
 11c2  Sand Microelectronics
-11c3  NEC Corp
+11c3  NEC Corporation
 11c4  Document Technologies, Inc
 11c5  Shiva Corporation
 11c6  Dainippon Screen Mfg. Co. Ltd
@@ -3568,6 +3902,7 @@
 11e1  GEC Plessey Semi Inc.
 11e2  Samsung Information Systems America
 11e3  Quicklogic Corporation
+	5030  PC Watchdog
 11e4  Second Wave Inc
 11e5  IIX Consulting
 11e6  Mitsui-Zosen System Research
@@ -3629,6 +3964,11 @@
 1200  CSS Corporation
 1201  Vista Controls Corp
 1202  Network General Corp.
+	4300  Gigabit Ethernet Adapter
+		1202 9841  SK-9841 LX
+		1202 9842  SK-9841 LX dual link
+		1202 9843  SK-9843 SX
+		1202 9844  SK-9843 SX dual link
 1203  Bayer Corporation, Agfa Division
 1204  Lattice Semiconductor Corporation
 1205  Array Corporation
@@ -3675,6 +4015,7 @@
 	6933  OZ6933 Cardbus Controller
 		1025 1016  Travelmate 612 TX
 	6972  OZ6912 Cardbus Controller
+		1179 0001  Magnia Z310
 1218  Hybricon Corp.
 1219  First Virtual Corporation
 121a  3Dfx Interactive, Inc.
@@ -3696,7 +4037,6 @@
 		139c 0016  Raven
 		139c 0017  Raven
 		14af 0002  Maxi Gamer Phoenix
-		3030 3030  Skywell Magic TwinPower
 	0004  Voodoo Banshee [Velocity 100]
 	0005  Voodoo 3
 		121a 0004  Voodoo3 AGP
@@ -3808,7 +4148,7 @@
 1249  Samsung Electronics Co., Ltd.
 124a  AEG Electrocom GmbH
 124b  SBS/Greenspring Modular I/O
-	0040  cPCI-200 Four Slot IndustryPack carrier
+	0040  PCI-40A or cPCI-200 Quad IndustryPack carrier
 		124b 9080  PCI9080 Bridge
 124c  Solitron Technologies, Inc.
 124d  Stallion Technologies, Inc.
@@ -3853,6 +4193,7 @@
 		125d 8888  Solo-1 Audio Adapter
 		525f c888  ES1969 SOLO-1 AudioDrive (+ES1938)
 	1978  ES1978 Maestro 2E
+		0e11 b112  Armada M700
 		1033 803c  ES1978 Maestro-2E Audiodrive
 		1033 8058  ES1978 Maestro-2E Audiodrive
 		1092 4000  Monster Sound MX400
@@ -3884,6 +4225,10 @@
 1260  Harris Semiconductor
 	3873  Prism 2.5 Wavelan chipset
 		1186 3501  DWL-520 Wireless PCI Adapter
+		1668 0414  HWP01170-01 802.11b PCI Wireless Adapter
+		1737 3874  WMP11 Wireless 802.11b PCI Adapter
+		8086 2513  Wireless 802.11b MiniPCI Adapter
+	3890  D-Links DWL-g650 A1
 	8130  HMP8130 NTSC/PAL Video Decoder
 	8131  HMP8131 NTSC/PAL Video Decoder
 1261  Matsushita-Kotobuki Electronics Industries, Ltd.
@@ -3919,6 +4264,7 @@
 1273  Hughes Network Systems
 	0002  DirecPC
 1274  Ensoniq
+	1171  ES1373 [AudioPCI] (also Creative Labs CT5803)
 	1371  ES1371 [AudioPCI-97]
 		0e11 0024  AudioPCI on Motherboard Compaq Deskpro
 		0e11 b1a7  ES1371, ES1373 AudioPCI
@@ -3989,6 +4335,7 @@
 1277  Comstream
 1278  Transtech Parallel Systems Ltd.
 	0701  TPE3/TM3 PowerPC Node
+	0710  TPE5 PowerPC PCI board
 1279  Transmeta Corporation
 	0295  Northbridge
 	0395  LongRun Northbridge
@@ -4184,6 +4531,7 @@
 		12ae 0001  Gigabit Ethernet-SX (Universal)
 		1410 0104  Gigabit Ethernet-SX PCI Adapter
 	0002  AceNIC Gigabit Ethernet (Copper)
+		10a9 8002  Acenic Gigabit Ethernet
 		12ae 0002  Gigabit Ethernet-T (3C986-T)
 12af  TDK USA Corp
 12b0  Jorge Scientific Corp
@@ -4214,7 +4562,7 @@
 		12b9 00ab  USR 56k Internal Voice Modem (Model 5609)
 		12b9 00ac  USR 56k Internal Voice Modem (Model 3298)
 		12b9 00ad  USR 56k Internal FAX Modem (Model 5610)
-12ba  PMC Sierra
+12ba  BittWare, Inc.
 12bb  Nippon Unisoft Corporation
 12bc  Array Microsystems
 12bd  Computerm Corp.
@@ -4278,11 +4626,14 @@
 	00a0  ITNT2
 12d3  Vingmed Sound A/S
 12d4  Ulticom (Formerly DGM&S)
+	0200  T1 Card
 12d5  Equator Technologies
 12d6  Analogic Corp
 12d7  Biotronic SRL
 12d8  Pericom Semiconductor
 12d9  Aculab PLC
+	0002  PCI Prosody
+	0004  cPCI Prosody
 12da  True Time Inc.
 12db  Annapolis Micro Systems, Inc
 12dc  Symicron Computer Communication Ltd.
@@ -4400,6 +4751,7 @@
 	0036  PCI-DAS64/M2/16
 	0037  PCI-DAS64/M3/16
 	004c  PCI-DAS1000
+	004d  PCI-QUAD04
 1308  Jato Technologies Inc.
 	0001  NetCelerator Adapter
 		1308 0001  NetCelerator Adapter
@@ -4486,6 +4838,8 @@
 1330  MMC Networks
 1331  Radisys Corp.
 1332  Micro Memory
+	5415  MM-5415CN PCI Memory Module with Battery Backup
+	5425  MM-5425CN PCI 64/66 Memory Module with Battery Backup
 1334  Redcreek Communications, Inc
 1335  Videomail, Inc
 1337  Third Planet Publishing
@@ -4523,7 +4877,11 @@
 134f  Algo System Co Ltd
 1350  Systec Co. Ltd
 1351  Sonix Inc
-1353  Dassault A.T.
+1353  Thales Idatys
+	0002  Proserver
+	0003  PCI-FUT
+	0004  PCI-S0
+	0005  PCI-FUT-S0
 1354  Dwave System Inc
 1355  Kratos Analytical Ltd
 1356  The Logical Co
@@ -4531,7 +4889,19 @@
 135a  Brain Boxes
 135b  Giganet Inc
 135c  Quatech Inc
+	0010  QSC-100
+	0020  DSC-100
+	0030  DSC-200/300
+	0040  QSC-200/300
+	0050  ESC-100D
+	0060  ESC-100M
 	00f0  MPAC-100 Syncronous Serial Card (Zilog 85230)
+	0170  QSCLP-100
+	0180  DSCLP-100
+	0190  SSCLP-100
+	01a0  QSCLP-200/300
+	01b0  DSCLP-200/300
+	01c0  SSCLP-200/300
 135d  ABB Network Partner AB
 135e  Sealevel Systems Inc
 	7101  Single Port RS-232/422/485/530
@@ -4579,6 +4949,7 @@
 1384  Reality Simulation Systems Inc
 1385  Netgear
 	4100  802.11b Wireless Adapter (MA301)
+	4105  MA311 802.11b wireless adapter
 	620a  GA620
 	622a  GA622
 	630a  GA630
@@ -4631,6 +5002,10 @@
 	0006  6500 Public Key Processor
 	0007  7811 Security Processor
 	0012  7951 Security Processor
+	0014  78XX Security Processor
+	0016  8065 Security Processor
+	0017  8165 Security Processor
+	0018  8154 Security Processor
 13a4  Rascom Inc
 13a5  Audio Digital Imaging Inc
 13a6  Videonics Inc
@@ -4681,7 +5056,10 @@
 13ce  Cocom A/S
 13cf  Studio Audio & Video Ltd
 13d0  Techsan Electronics Co Ltd
+# http://www.b2c2inc.com/products/pc-specs.html
+	2103  B2C2 Sky2PC PCI [SkyStar2]
 13d1  Abocom Systems Inc
+	ab02  ADMtek Centaur-C rev 17 [D-Link DFE-680TX] CardBus Fast Ethernet Adapter
 	ab06  RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter
 13d2  Shark Multimedia Inc
 13d3  IMC Networks
@@ -4708,7 +5086,7 @@
 13e6  Argosy research Inc
 13e7  NAC Incorporated
 13e8  Chip Express Corporation
-13e9  Chip Express Corporation
+13e9  Intraserver Technology Inc
 13ea  Dallas Semiconductor
 13eb  Hauppauge Computer Works Inc
 13ec  Zydacron Inc
@@ -4729,9 +5107,11 @@
 	0101  CM8338B
 		13f6 0101  CMI8338-031 PCI Audio Device
 	0111  CM8738
+		1019 0970  P6STP-FL motherboard
 		1043 8077  CMI8738 6-channel audio controller
 		1043 80e2  CMI8738 6ch-MX
 		13f6 0111  CMI8738/C3DX PCI Audio Device
+		1681 a000  Gamesurround MUSE XL
 	0211  CM8738
 13f7  Wildfire Communications
 13f8  Ad Lib Multimedia Inc
@@ -4778,6 +5158,7 @@
 1411  Ikos Systems Inc
 1412  IC Ensemble Inc
 	1712  ICE1712 [Envy24]
+	1724  ICE1724 [Envy24HT]
 1413  Addonics
 1414  Microsoft Corporation
 1415  Oxford Semiconductor Ltd
@@ -4875,7 +5256,7 @@
 	0001  NextMove PCI
 1460  DYNARC INC
 1461  Avermedia Technologies Inc
-1462  Micro-star International Co Ltd
+1462  Micro-Star International Co., Ltd.
 1463  Fast Corporation
 1464  Interactive Circuits & Systems Ltd
 1465  GN NETTEST Telecom DIV.
@@ -4886,6 +5267,7 @@
 146a  IFR
 146b  Parascan Technologies Ltd
 146c  Ruby Tech Corp.
+	1430  FE-1430TX Fast Ethernet PCI Adapter
 146d  Tachyon, INC.
 146e  Williams Electronics Games, Inc.
 146f  Multi Dimensional Consulting Inc
@@ -4936,6 +5318,7 @@
 149b  SEIKO Instruments Inc
 149c  OVISLINK Corp.
 149d  NEWTEK Inc
+	0001  Video Toaster for PC
 149e  Mapletree Networks Inc.
 149f  LECTRON Co Ltd
 14a0  SOFTING GmBH
@@ -4954,6 +5337,7 @@
 14ad  Time Space Radio AB
 14ae  CTI, Inc
 14af  Guillemot Corporation
+	7102  3D Prophet II MX
 14b0  BST Communication Technology Ltd
 14b1  Nextcom K.K.
 14b2  ENNOVATE Networks Inc
@@ -4961,6 +5345,14 @@
 	0000  DSL NIC
 14b4  PHILIPS Business Electronics B.V.
 14b5  Creamware GmBH
+	0200  Scope
+	0300  Pulsar
+	0400  Pulsar2
+	0600  Pulsar2
+	0800  DSP-Board
+	0900  DSP-Board
+	0a00  DSP-Board
+	0b00  DSP-Board
 14b6  Quantum Data Corp.
 14b7  PROXIM Inc
 	0001  Symphony 4110
@@ -4971,6 +5363,7 @@
 	0350  PC4800
 	4500  PC4500
 	4800  PC4800
+	a504  Cisco Aironet Wireless 802.11b
 14ba  INTERNIX Inc.
 14bb  SEMTECH Corporation
 14bc  Globespan Semiconductor Inc.
@@ -5043,40 +5436,44 @@
 14e3  AMTELCO
 14e4  Broadcom Corporation
 	1644  NetXtreme BCM5700 Gigabit Ethernet
-		1014 0277  Broadcom Vigil B5700 1000BaseTX
+		1014 0277  Broadcom Vigil B5700 1000Base-T
 		1028 00d1  Broadcom BCM5700
 		1028 0106  Broadcom BCM5700
-		1028 0109  Broadcom BCM5700 1000BaseTX
+		1028 0109  Broadcom BCM5700 1000Base-T
 		1028 010a  Broadcom BCM5700 1000BaseTX
-		10b7 1000  3C996-T 1000BaseTX
-		10b7 1001  3C996B-T 1000BaseTX
-		10b7 1002  3C996C-T 1000BaseTX
-		10b7 1003  3C997-T 1000BaseTX Dual Port
-		10b7 1004  3C996-SX 1000BaseSX
-		10b7 1005  3C997-SX 1000BaseSX Dual Port
+		10b7 1000  3C996-T 1000Base-T
+		10b7 1001  3C996B-T 1000Base-T
+		10b7 1002  3C996C-T 1000Base-T
+		10b7 1003  3C997-T 1000Base-T Dual Port
+		10b7 1004  3C996-SX 1000Base-SX
+		10b7 1005  3C997-SX 1000Base-SX Dual Port
 		10b7 1008  3C942 Gigabit LOM (31X31)
-		14e4 0002  NetXtreme 1000BaseSX
-		14e4 0003  NetXtreme 1000BaseSX
-		14e4 0004  NetXtreme 1000BaseTX
+		14e4 0002  NetXtreme 1000Base-SX
+		14e4 0003  NetXtreme 1000Base-SX
+		14e4 0004  NetXtreme 1000Base-T
 		14e4 1028  NetXtreme 1000BaseTX
-		14e4 1644  BCM5700 1000BaseTX
+		14e4 1644  BCM5700 1000Base-T
 	1645  NetXtreme BCM5701 Gigabit Ethernet
 		0e11 007c  NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
 		0e11 007d  NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
 		0e11 0085  NC7780 Gigabit Server Adapter (embedded, WOL)
 		0e11 0099  NC7780 Gigabit Server Adapter (embedded, WOL)
 		0e11 009a  NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
-		1028 0121  Broadcom BCM5701 1000BaseTX
-		10b7 1004  3C996-SX 1000BaseSX
-		10b7 1006  3C996B-T 1000BaseTX
-		10b7 1007  3C1000-T 1000BaseTX
-		10b7 1008  3C940-BR01 1000BaseTX
-		14e4 0001  BCM5701 1000BaseTX
-		14e4 0005  BCM5701 1000BaseTX
-		14e4 0006  BCM5701 1000BaseTX
-		14e4 0007  BCM5701 1000BaseSX
-		14e4 0008  BCM5701 1000BaseTX
-		14e4 8008  BCM5701 1000BaseTX
+		0e11 00c1  NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
+		1028 0121  Broadcom BCM5701 1000Base-T
+		10a9 8010  SGI IO9 Gigabit Ethernet (Copper)
+		10a9 8011  SGI Gigabit Ethernet (Copper)
+		10a9 8012  SGI Gigabit Ethernet (Fiber)
+		10b7 1004  3C996-SX 1000Base-SX
+		10b7 1006  3C996B-T 1000Base-T
+		10b7 1007  3C1000-T 1000Base-T
+		10b7 1008  3C940-BR01 1000Base-T
+		14e4 0001  BCM5701 1000Base-T
+		14e4 0005  BCM5701 1000Base-T
+		14e4 0006  BCM5701 1000Base-T
+		14e4 0007  BCM5701 1000Base-SX
+		14e4 0008  BCM5701 1000Base-T
+		14e4 8008  BCM5701 1000Base-T
 	1646  NetXtreme BCM5702 Gigabit Ethernet
 		0e11 00bb  NC7760 1000BaseTX
 		1028 0126  Broadcom BCM5702 1000BaseTX
@@ -5084,19 +5481,57 @@
 	1647  NetXtreme BCM5703 Gigabit Ethernet
 		0e11 0099  NC7780 1000BaseTX
 		0e11 009a  NC7770 1000BaseTX
+		10a9 8010  SGI IO9 Gigabit Ethernet (Copper)
 		14e4 0009  BCM5703 1000BaseTX
 		14e4 000a  BCM5703 1000BaseSX
 		14e4 000b  BCM5703 1000BaseTX
 		14e4 8009  BCM5703 1000BaseTX
 		14e4 800a  BCM5703 1000BaseTX
 	1648  NetXtreme BCM5704 Gigabit Ethernet
+		0e11 00cf  NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+		0e11 00d0  NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+		0e11 00d1  NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+		10b7 2000  3C998-T Dual Port 10/100/1000 PCI-X
+		10b7 3000  3C999-T Quad Port 10/100/1000 PCI-X
+		1166 1648  NetXtreme CIOB-E 1000Base-T
 	164d  NetXtreme BCM5702FE Gigabit Ethernet
-	16a6  NetXtreme BCM5702X Gigabit Ethernet
-	16a7  NetXtreme BCM5703X Gigabit Ethernet
+	1653  NetXtreme BCM5705 Gigabit Ethernet
+	165d  NetXtreme BCM5705M Gigabit Ethernet
+	1696  NetXtreme BCM5782 Gigabit Ethernet
+		14e4 000d  NetXtreme BCM5782 1000Base-T
+	169c  NetXtreme BCM5788 Gigabit Ethernet
+	16a6  NetXtreme BCM5702 Gigabit Ethernet
+		0e11 00bb  NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+		1028 0126  BCM5702 1000Base-T
+		14e4 000c  BCM5702 1000Base-T
+		14e4 8009  BCM5702 1000Base-T
+	16a7  NetXtreme BCM5703 Gigabit Ethernet
+		0e11 00ca  NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+		0e11 00cb  NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+		14e4 0009  NetXtreme BCM5703 1000Base-T
+		14e4 000a  NetXtreme BCM5703 1000Base-SX
+		14e4 000b  NetXtreme BCM5703 1000Base-T
+		14e4 800a  NetXtreme BCM5703 1000Base-T
 	16a8  NetXtreme BCM5704S Gigabit Ethernet
-	16c6  NetXtreme BCM5702A3 Gigabit Ethernet
-	16c7  NetXtreme BCM5703A3 Gigabit Ethernet
-	4212  BCM v.90 56k modem
+		10b7 2001  3C998-SX Dual Port 1000-SX PCI-X
+	16c6  NetXtreme BCM5702 Gigabit Ethernet
+		10b7 1100  3C1000B-T 10/100/1000 PCI
+		14e4 000c  BCM5702 1000Base-T
+		14e4 8009  BCM5702 1000Base-T
+	16c7  NetXtreme BCM5703 Gigabit Ethernet
+		14e4 0009  NetXtreme BCM5703 1000Base-T
+		14e4 000a  NetXtreme BCM5703 1000Base-SX
+	4210  BCM4210 iLine10 HomePNA 2.0
+	4211  BCM4211 iLine10 HomePNA 2.0 + V.90 56k modem
+	4212  BCM4212 v.90 56k modem
+	4301  BCM4301 802.11b
+	4320  BCM94306 802.11g
+	4401  BCM4401 100Base-T
+		1043 80a8  A7V8X motherboard
+	4402  BCM4402 Integrated 10/100BaseT
+	4410  BCM4413 iLine32 HomePNA 2.0
+	4411  BCM4413 V.90 56k modem
+	4412  BCM4413 10/100BaseT
 	5820  BCM5820 Crypto Accelerator
 	5821  BCM5821 Crypto Accelerator
 14e5  Pixelfusion Ltd
@@ -5181,6 +5616,9 @@
 		122d 4302  Dell MP3930V-W(C) MiniPCI
 	1610  ADSL AccessRunner PCI Arbitration Device
 	1611  AccessRunner PCI ADSL Interface Device
+	1620  ADSL AccessRunner V2 PCI Arbitration Device
+	1621  AccessRunner V2 PCI ADSL Interface Device
+	1622  AccessRunner V2 PCI ADSL Yukon WAN Adapter
 	1803  HCF 56k Modem
 		0e11 0023  623-LAN Grizzly
 		0e11 0043  623-LAN Yogi
@@ -5318,8 +5756,14 @@
 		1522 0400  RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem
 		1522 0500  RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem
 		1522 0600  RockForce+ 2 Port V.90 Data/Fax/Voice Modem
+		1522 0700  RockForce+ 4 Port V.90 Data/Fax/Voice Modem
+		1522 0800  RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem
 1523  MUSIC Semiconductors
 1524  ENE Technology Inc
+	1211  CB1211 Cardbus Controller
+	1225  CB1225 Cardbus Controller
+	1410  CB1410 Cardbus Controller
+	1420  CB1420 Cardbus Controller
 1525  IMPACT Technologies
 1526  ISS, Inc
 1527  SOLECTRON
@@ -5350,6 +5794,8 @@
 1541  MACHONE Communications
 1542  VIVID Technology Inc
 1543  SILICON Laboratories
+	3052  Intel 537 [Winmodem]
+	4c22  Si3036 MC'97 DAA
 1544  DCM DATA Systems
 1545  VISIONTEK
 1546  IOI Technology Corp
@@ -5580,6 +6026,7 @@
 1607  Lava Semiconductor Manufacturing Inc
 1608  Automated Wagering International
 1609  Scimetric Instruments Inc
+1612  Telesynergy Research Inc.
 1619  FarSite Communications Ltd
 	0400  FarSync T2P (2 port X.21/V.35/V.24)
 	0440  FarSync T4P (4 port X.21/V.35/V.24)
@@ -5588,22 +6035,40 @@
 	2002  Fast Universal Data Output
 1638  Standard Microsystems Corp [SMC]
 	1100  SMC2602W EZConnect / Addtron AWA-100
+163c  Smart Link Ltd.
+	3052  SmartLink SmartPCI562 56K Modem
+	5449  SmartPCI561 Modem
 1657  Brocade Communications Systems, Inc.
+165a  Epix Inc
+	c100  PIXCI(R) CL1 Camera Link Video Capture Board [custom QL5232]
+	d200  PIXCI(R) D2X Digital Video Capture Board [custom QL5232]
+	d300  PIXCI(R) D3X Digital Video Capture Board [custom QL5232]
 165d  Hsing Tech. Enterprise Co., Ltd.
 1661  Worldspace Corp.
-1668  Action Tec Electronics Inc
+1668  Actiontec Electronics Inc
+1681  Hercules
+16ab  Global Sun Technology Inc
+	1102  PCMCIA-to-PCI Wireless Network Bridge
+16be  Creatix Polymedia GmbH
+16ca  CENATEK Inc
+	0001  Rocket Drive DL
 16ec  U.S. Robotics
 	3685  Wireless Access PCI Adapter Model 022415
 16f6  VideoTele.com, Inc.
+1705  Digital First, Inc.
 170b  NetOctave Inc
 170c  YottaYotta Inc.
+172a  Accelerated Encryption
+1737  Linksys
 173b  Altima (nee Broadcom)
 	03e8  AC1000 Gigabit Ethernet
 	03ea  AC9100 Gigabit Ethernet
+		173b 0001  AC1002
 1743  Peppercon AG
 	8139  ROL/F-100 Fast Ethernet Adapter with ROL
 174b  PC Partner Limited
 175e  Sanera Systems, Inc.
+1787  Hightech Information System Ltd.
 # also used by Struck Innovative Systeme for joint developments
 1796  Research Centre Juelich
 	0001  SIS1100 [Gigabit link]
@@ -5612,7 +6077,22 @@
 	0004  CAMAC Controller
 	0005  PROFIBUS
 	0006  AMCC HOTlink
+1799  Belkin
+17af  Hightech Information System Ltd.
+17cc  NetChip Technology, Inc
+	2280  USB 2.0
 1813  Ambient Technologies Inc
+	4000  HaM controllerless modem
+		16be 0001  V9x HAM Data Fax Modem
+	4100  HaM plus Data Fax Modem
+		16be 0002  V9x HAM 1394
+1851  Microtune, Inc.
+1852  Anritsu Corp.
+1888  Varisys Ltd
+	0301  VMFX1 FPGA PMC module
+	0601  VSM2 dual PMC carrier
+	0710  VS14x series PowerPC PCI board
+	0720  VS24x series PowerPC PCI board
 1a08  Sierra semiconductor
 	0000  SC15064
 1b13  Jaton Corp
@@ -5625,7 +6105,12 @@
 	2020  DC-390
 	690c  690c
 	dc29  DC290
+1fc0  Tumsan Oy
+	0300  E2200 Dual E1/Rawpipe Card
+2000  Smart Link Ltd.
 2001  Temporal Research Ltd
+2003  Smart Link Ltd.
+2004  Smart Link Ltd.
 21c3  21st Century Computer Corp.
 2348  Racore
 	2010  8142 100VG/AnyLAN
@@ -5637,7 +6122,11 @@
 3000  Hansol Electronics Inc.
 3142  Post Impression Systems.
 3388  Hint Corp
+	0013  HiNT HC4 PCI to ISDN bridge, Multimedia audio controller
+	0014  HiNT HC4 PCI to ISDN bridge, Network controller
 	0021  HB1-SE33 PCI-PCI Bridge
+	101a  E.Band [AudioTrak Inca88]
+	101b  E.Band [AudioTrak Inca88]
 	8011  VXPro II Chipset
 		3388 8011  VXPro II Chipset CPU to PCI Bridge
 	8012  VXPro II Chipset
@@ -5668,6 +6157,8 @@
 		3d3d 0127  Permedia3 Create!
 	000a  GLINT R3
 		3d3d 0121  Oxygen VX1
+	000c  GLINT R3 [Oxygen VX1]
+		3d3d 0144  Oxygen VX1-4X AGP [Permedia 4]
 	0100  Permedia II 2D+3D
 	1004  Permedia
 	3d04  Permedia
@@ -5695,6 +6186,7 @@
 	0100  AladdinCARD
 	0200  CPC
 4444  Internext Compression Inc
+	0803  iTVC15 MPEG-2 Encoder
 4468  Bridgeport machines
 4594  Cogetec Informatique Inc
 45fb  Baldor Electric Company
@@ -5740,6 +6232,7 @@
 5143  Qualcomm Inc
 5145  Ensoniq (Old)
 	3031  Concert AudioPCI
+5168  Animation Technologies Inc.
 5301  Alliance Semiconductor Corp.
 	0001  ProMotion aT3D
 5333  S3 Inc.
@@ -5848,7 +6341,9 @@
 	8c10  86C270-294 Savage/MX-MV
 	8c11  82C270-294 Savage/MX
 	8c12  86C270-294 Savage/IX-MV
+		1014 017f  ThinkPad T20
 	8c13  86C270-294 Savage/IX
+		1179 0001  Magnia Z310
 	8c22  SuperSavage MX/128
 	8c24  SuperSavage MX/64
 	8c26  SuperSavage MX/64C
@@ -5859,10 +6354,10 @@
 	8c2e  SuperSavage IX/C SDR
 		1014 01fc  ThinkPad T23 (2647-4MG)
 	8c2f  SuperSavage IX/C DDR
-# Integrated in VIA ProSavage PN133 North Bridge
-	8d01  VT8603 [ProSavage PN133] AGP4X VGA Controller (Twister)
+	8d01  86C380 [ProSavageDDR K4M266]
 	8d02  VT8636A [ProSavage KN133] AGP4X VGA Controller (TwisterK)
-	8d04  VT8751 [ProSavageDDR P4M266] VGA Controller
+	8d03  VT8751 [ProSavageDDR P4M266]
+	8d04  VT8375 [ProSavage8 KM266/KL266]
 	9102  86C410 Savage 2000
 		1092 5932  Viper II Z200
 		1092 5934  Viper II Z200
@@ -5874,6 +6369,7 @@
 		1092 5a57  Viper II Z200
 	ca00  SonicVibes
 544c  Teralogic Inc
+	0350  TL880-based HDTV/ATSC tuner
 5455  Technische University Berlin
 	4458  S5933
 5519  Cnet Technologies, Inc.
@@ -5881,6 +6377,7 @@
 	0001  I-30xx Scanner Interface
 5555  Genroco, Inc
 	0003  TURBOstor HFP-832 [HiPPI NIC]
+5654  VoiceTronix Pty Ltd
 5700  Netpower
 6356  UltraStor
 6374  c't Magazin für Computertechnik
@@ -5916,7 +6413,7 @@
 		0e11 b123  NC1634 Gigabit Ethernet Adapter (1000-SX)
 		1014 0119  Netfinity Gigabit Ethernet SX Adapter
 		8086 1000  PRO/1000 Gigabit Server Adapter
-	1001  82543GC Gigabit Ethernet Controller
+	1001  82543GC Gigabit Ethernet Controller (Fiber)
 		0e11 004a  NC6136 Gigabit Server Adapter
 		1014 01ea  Netfinity Gigabit Ethernet SX Adapter
 		8086 1003  PRO/1000 F Server Adapter
@@ -5924,44 +6421,46 @@
 		8086 200e  Pro 100 LAN+Modem 56 Cardbus II
 		8086 2013  Pro 100 SR Mobile Combo Adapter
 		8086 2017  Pro 100 S Combo Mobile Adapter
-	1004  82543GC Gigabit Ethernet Controller
+	1004  82543GC Gigabit Ethernet Controller (Copper)
 		0e11 0049  NC7132 Gigabit Upgrade Module
 		0e11 b1a4  NC7131 Gigabit Server Adapter
 		1014 10f2  Gigabit Ethernet Server Adapter
 		8086 1004  PRO/1000 T Server Adapter
 		8086 2004  PRO/1000 T Server Adapter
-	1008  82544EI Gigabit Ethernet Controller
+	1008  82544EI Gigabit Ethernet Controller (Copper)
 		8086 1107  PRO/1000 XT Server Adapter
 		8086 2107  PRO/1000 XT Server Adapter
 		8086 2110  PRO/1000 XT Server Adapter
-	1009  82544EI Gigabit Ethernet Controller
+	1009  82544EI Gigabit Ethernet Controller (Fiber)
 		8086 1109  PRO/1000 XF Server Adapter
 		8086 2109  PRO/1000 XF Server Adapter
-	100c  82544GC Gigabit Ethernet Controller
+	100c  82544GC Gigabit Ethernet Controller (Copper)
 		8086 1112  PRO/1000 T Desktop Adapter
 		8086 2112  PRO/1000 T Desktop Adapter
-	100d  82544GC Gigabit Ethernet Controller
+	100d  82544GC Gigabit Ethernet Controller (LOM)
 	100e  82540EM Gigabit Ethernet Controller
 		8086 001e  PRO/1000 MT Desktop Adapter
 		8086 002e  PRO/1000 MT Desktop Adapter
-	100f  82545EM Gigabit Ethernet Controller
+	100f  82545EM Gigabit Ethernet Controller (Copper)
 		8086 1001  PRO/1000 MT Server Adapter
-	1010  82546EB Gigabit Ethernet Controller
+	1010  82546EB Gigabit Ethernet Controller (Copper)
 		8086 1011  PRO/1000 MT Dual Port Server Adapter
-	1011  82545EM Gigabit Ethernet Controller
+	1011  82545EM Gigabit Ethernet Controller (Fiber)
 		8086 1002  PRO/1000 MF Server Adapter
-	1012  82546EB Gigabit Ethernet Controller
+	1012  82546EB Gigabit Ethernet Controller (Fiber)
 		8086 1012  PRO/1000 MF Dual Port Server Adapter
+	1015  82540EM Gigabit Ethernet Controller (LOM)
 	1029  82559 Ethernet Controller
 	1030  82559 InBusiness 10/100
 	1031  82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller
-		1014 0209  ThinkPad A30p (2653-64G)
+		1014 0209  ThinkPad A/T/X Series
 		104d 80e7  Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
 		107b 5350  EtherExpress PRO/100 VE
 		1179 0001  EtherExpress PRO/100 VE
 		144d c000  EtherExpress PRO/100 VE
 		144d c001  EtherExpress PRO/100 VE
 		144d c003  EtherExpress PRO/100 VE
+		144d c006  vpr Matrix 170B4
 	1032  82801CAM (ICH3) PRO/100 VE Ethernet Controller
 	1033  82801CAM (ICH3) PRO/100 VM (LOM) Ethernet Controller
 	1034  82801CAM (ICH3) PRO/100 VM Ethernet Controller
@@ -5975,16 +6474,25 @@
 	103c  82801BD PRO/100 VM (CNR) Ethernet Controller
 	103d  82801BD PRO/100 VE (MOB) Ethernet Controller
 	103e  82801BD PRO/100 VM (MOB) Ethernet Controller
+	1040  536EP Data Fax Modem
+		16be 1040  V.9X DSP Data Fax Modem
+	1043  PRO/Wireless LAN 2100 3B Mini PCI Adapter
 	1059  82551QM Ethernet Controller
 	1130  82815 815 Chipset Host Bridge and Memory Controller Hub
+		1025 1016  Travelmate 612 TX
 		1043 8027  TUSL2-C Mainboard
 		104d 80df  Vaio PCG-FX403
+		8086 4532  D815EEA2 mainboard
+		8086 4557  D815EGEW Mainboard
 	1131  82815 815 Chipset AGP Bridge
 	1132  82815 CGC [Chipset Graphics Controller]
 		1025 1016  Travelmate 612 TX
 		104d 80df  Vaio PCG-FX403
+		8086 4532  D815EEA2 Mainboard
+		8086 4557  D815EGEW Mainboard
 	1161  82806AA PCI64 Hub Advanced Programmable Interrupt Controller
 		8086 1161  82806AA PCI64 Hub APIC
+	1162  Xscale 80200 Big Endian Companion Chip
 	1200  Intel IXP1200 Network Processor
 		172a 0000  AEP SSL Accelerator
 	1209  82559ER
@@ -6026,13 +6534,16 @@
 		1014 01f2  10/100 Ethernet Server Adapter
 		1014 0207  Ethernet Pro/100 S
 		1014 0232  10/100 Dual Port Server Adapter
+		1014 023a  ThinkPad R30
 		1014 105c  Netfinity 10/100
+		1014 2205  ThinkPad A22p
 		1014 305c  10/100 EtherJet Management Adapter
 		1014 405c  10/100 EtherJet Adapter with Alert on LAN
 		1014 505c  10/100 EtherJet Secure Management Adapter
 		1014 605c  10/100 EtherJet Secure Management Adapter
 		1014 705c  10/100 Netfinity 10/100 Ethernet Security Adapter
 		1014 805c  10/100 Netfinity 10/100 Ethernet Security Adapter
+		1028 009b  PowerEdge 2550
 		1033 8000  PC-9821X-B06
 		1033 8016  PK-UG-X006
 		1033 801f  PK-UG-X006
@@ -6163,6 +6674,7 @@
 		8086 8000  82806AA PCI64 Hub Controller (HRes)
 	1460  82870P2 P64H2 Hub PCI Bridge
 	1461  82870P2 P64H2 I/OxAPIC
+		15d9 3480  P4DP6
 	1462  82870P2 P64H2 Hot Plug Controller
 	1960  80960RP [i960RP Microprocessor]
 		101e 0431  MegaRAID 431 RAID Controller
@@ -6214,20 +6726,34 @@
 	2428  82801AB PCI Bridge
 	2440  82801BA ISA Bridge (LPC)
 	2442  82801BA/BAM USB (Hub #1)
+		1014 01c6  Netvista A40/A40p
+		1025 1016  Travelmate 612 TX
 		104d 80df  Vaio PCG-FX403
 		147b 0507  TH7II-RAID
+		8086 4532  D815EEA2 mainboard
+		8086 4557  D815EGEW Mainboard
 	2443  82801BA/BAM SMBus
+		1014 01c6  Netvista A40/A40p
+		1025 1016  Travelmate 612 TX
 		1043 8027  TUSL2-C Mainboard
 		104d 80df  Vaio PCG-FX403
 		147b 0507  TH7II-RAID
+		8086 4532  D815EEA2 mainboard
+		8086 4557  D815EGEW Mainboard
 	2444  82801BA/BAM USB (Hub #2)
+		1025 1016  Travelmate 612 TX
 		104d 80df  Vaio PCG-FX403
 		147b 0507  TH7II-RAID
+		8086 4532  D815EEA2 mainboard
 	2445  82801BA/BAM AC'97 Audio
+		1014 01c6  Netvista A40/A40p
+		1025 1016  Travelmate 612 TX
 		104d 80df  Vaio PCG-FX403
 		1462 3370  STAC9721 AC
 		147b 0507  TH7II-RAID
-	2446  82801BA/BAM AC'97 Modem
+		8086 4557  D815EGEW Mainboard
+	2446  Intel 537 [82801BA/BAM AC'97 Modem]
+		1025 1016  Travelmate 612 TX
 		104d 80df  Vaio PCG-FX403
 	2448  82801BAM/CAM PCI Bridge
 	2449  82801BA/BAM/CA/CAM Ethernet Controller
@@ -6244,8 +6770,12 @@
 		1014 023d  EtherExpress PRO/100 VE
 		1014 0244  EtherExpress PRO/100 VE
 		1014 0245  EtherExpress PRO/100 VE
+		1014 0265  PRO/100 VE Desktop Connection
+		1014 0267  PRO/100 VE Desktop Connection
+		1014 026a  PRO/100 VE Desktop Connection
 		109f 315d  EtherExpress PRO/100 VE
 		109f 3181  EtherExpress PRO/100 VE
+		1179 ff01  PRO/100 VE Network Connection
 		1186 7801  EtherExpress PRO/100 VE
 		144d 2602  HomePNA 1M CNR
 		8086 3010  EtherExpress PRO/100 VE
@@ -6261,10 +6791,13 @@
 		1025 1016  Travelmate 612TX
 		104d 80df  Vaio PCG-FX403
 	244b  82801BA IDE U100
+		1014 01c6  Netvista A40/A40p
 		1043 8027  TUSL2-C Mainboard
 		147b 0507  TH7II-RAID
+		8086 4532  D815EEA2 mainboard
+		8086 4557  D815EGEW Mainboard
 	244c  82801BAM ISA Bridge (LPC)
-	244e  82801BA/CA/DB PCI Bridge
+	244e  82801BA/CA/DB/EB PCI Bridge
 	2450  82801E ISA Bridge (LPC)
 	2452  82801E USB
 	2453  82801E SMBus
@@ -6272,41 +6805,80 @@
 	245b  82801E IDE U100
 	245d  82801E Ethernet Controller 1
 	245e  82801E PCI Bridge
-	2480  82801CA ISA Bridge (LPC)
+	2480  82801CA LPC Interface Controller
 	2482  82801CA/CAM USB (Hub #1)
-		1014 0220  ThinkPad T23 (2647-4MG) or A30p (2653-64G)
+		1014 0220  ThinkPad A/T/X Series
 		104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-	2483  82801CA/CAM SMBus
-		1014 0220  ThinkPad T23 (2647-4MG) or A30p (2653-64G)
+		15d9 3480  P4DP6
+		8086 1958  vpr Matrix 170B4
+	2483  82801CA/CAM SMBus Controller
+		1014 0220  ThinkPad A/T/X Series
 		104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+		15d9 3480  P4DP6
+		8086 1958  vpr Matrix 170B4
 	2484  82801CA/CAM USB (Hub #2)
-		1014 0220  ThinkPad T23 (2647-4MG) or A30p (2653-64G)
+		1014 0220  ThinkPad A/T/X Series
 		104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-	2485  82801CA/CAM AC'97 Audio
-		1014 0222  ThinkPad T23 (2647-4MG)
+		15d9 3480  P4DP6
+		8086 1958  vpr Matrix 170B4
+	2485  82801CA/CAM AC'97 Audio Controller
+		1014 0222  ThinkPad T23 (2647-4MG) or A30p (2653-64G)
+		1014 0508  ThinkPad T30
+		1014 051c  ThinkPad A/T/X Series
 		104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-	2486  82801CA/CAM AC'97 Modem
-		1014 0223  ThinkPad A30p (2653-64G)
+		144d c006  vpr Matrix 170B4
+	2486  82801CA/CAM AC'97 Modem Controller
+		1014 0223  ThinkPad A/T/X Series
 		1014 0503  ThinkPad R31 2656BBG
+		1014 051a  ThinkPad A/T/X Series
 		104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+		1179 0001  Toshiba Satellite 1110 Z15 internal Modem
 		134d 4c21  Dell Inspiron 2100 internal modem
+		144d 2115  vpr Matrix 170B4 internal modem
+		14f1 5421  MD56ORD V.92 MDC Modem
 	2487  82801CA/CAM USB (Hub #3)
-		1014 0220  ThinkPad T23 (2647-4MG) or A30p (2653-64G)
+		1014 0220  ThinkPad A/T/X Series
 		104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+		15d9 3480  P4DP6
+		8086 1958  vpr Matrix 170B4
 	248a  82801CAM IDE U100
-		1014 0220  ThinkPad T23 (2647-4MG) or A30p (2653-64G)
+		1014 0220  ThinkPad A/T/X Series
 		104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
-	248b  82801CA IDE U100
+		8086 1958  vpr Matrix 170B4
+	248b  82801CA Ultra ATA Storage Controller
+		15d9 3480  P4DP6
 	248c  82801CAM ISA Bridge (LPC)
-	24c0  82801DB ISA Bridge (LPC)
+	24c0  82801DB LPC Interface Controller
+		1462 5800  845PE Max (MS-6580)
 	24c2  82801DB USB (Hub #1)
-	24c3  82801DB SMBus
+		1462 5800  845PE Max (MS-6580)
+	24c3  82801DB/DBM SMBus Controller
+		1462 5800  845PE Max (MS-6580)
 	24c4  82801DB USB (Hub #2)
-	24c5  82801DB AC'97 Audio
-	24c6  82801DB AC'97 Modem
+		1462 5800  845PE Max (MS-6580)
+	24c5  82801DB AC'97 Audio Controller
+		1462 5800  845PE Max (MS-6580)
+	24c6  82801DB AC'97 Modem Controller
 	24c7  82801DB USB (Hub #3)
-	24cb  82801DB ICH4 IDE
-	24cd  82801DB USB EHCI Controller
+		1462 5800  845PE Max (MS-6580)
+	24ca  82801DBM Ultra ATA Storage Controller
+	24cb  82801DB Ultra ATA Storage Controller
+		1462 5800  845PE Max (MS-6580)
+	24cc  82801DBM LPC Interface Controller
+	24cd  82801DB USB2
+		1462 3981  845PE Max (MS-6580) Onboard USB EHCI Controller
+	24d0  82801EB LPC Interface Controller
+	24d1  82801EB Ultra ATA Storage Controller
+	24d2  82801EB USB
+	24d3  82801EB SMBus Controller
+	24d4  82801EB USB
+	24d5  82801EB AC'97 Audio Controller
+	24d6  82801EB AC'97 Modem Controller
+	24d7  82801EB USB
+	24db  82801EB Ultra ATA Storage Controller
+	24dc  82801EB LPC Interface Controller
+	24dd  82801EB USB2
+	24de  82801EB USB
 	2500  82820 820 (Camino) Chipset Host Bridge (MCH)
 		1028 0095  Precision Workstation 220 Chipset
 		1043 801c  P3C-2000 system chipset
@@ -6322,24 +6894,48 @@
 	2532  82850 850 (Tehama) Chipset AGP Bridge
 	2533  82860 860 (Wombat) Chipset AGP Bridge
 	2534  82860 860 (Wombat) Chipset PCI Bridge
-	2540  e7500 [Plumas] DRAM Controller
-	2541  e7500 [Plumas] DRAM Controller Error Reporting
-	2543  e7500 [Plumas] HI_B Virtual PCI Bridge (F0)
-	2544  e7500 [Plumas] HI_B Virtual PCI Bridge (F1)
-	2545  e7500 [Plumas] HI_C Virtual PCI Bridge (F0)
-	2546  e7500 [Plumas] HI_C Virtual PCI Bridge (F1)
-	2547  e7500 [Plumas] HI_D Virtual PCI Bridge (F0)
-	2548  e7500 [Plumas] HI_D Virtual PCI Bridge (F1)
+	2540  E7500 Memory Controller Hub
+		15d9 3480  P4DP6
+	2541  E7000 Series Host RASUM Controller
+		15d9 3480  P4DP6
+	2543  E7000 Series Hub Interface B PCI-to-PCI Bridge
+	2544  E7000 Series Hub Interface B RASUM Controller
+	2545  E7000 Series Hub Interface C PCI-to-PCI Bridge
+	2546  E7000 Series Hub Interface C RASUM Controller
+	2547  E7000 Series Hub Interface D PCI-to-PCI Bridge
+	2548  E7000 Series Hub Interface D RASUM Controller
+	254c  E7501 Memory Controller Hub
+	2550  E7505 Memory Controller Hub
+	2551  E7000 Series RAS Controller
+	2552  E7000 Series Processor to AGP Controller
+	2553  E7000 Series Hub Interface B PCI-to-PCI Bridge
+	2554  E7000 Series Hub Interface B PCI-to-PCI Bridge RAS Controller
+	255d  E7205 Memory Controller Hub
 	2560  82845G/GL [Brookdale-G] Chipset Host Bridge
+		1462 5800  845PE Max (MS-6580)
 	2561  82845G/GL [Brookdale-G] Chipset AGP Bridge
 	2562  82845G/GL [Brookdale-G] Chipset Integrated Graphics Device
+	2570  82865G/PE/P Processor to I/O Controller
+	2571  82865G/PE/P Processor to AGP Controller
+	2572  82865G Integrated Graphics Device
+	2573  82865G/PE/P Processor to PCI to CSA Bridge
+	2576  82864G/PE/P Processor to I/O Memory Interface
+	2578  82875P Memory Controller Hub
+	2579  82875P Processor to AGP Controller
+	257b  82875P Processor to PCI to CSA Bridge
+	257e  82875P Processor to I/O Memory Interface
 	3092  Integrated RAID
+	3340  82855PM Processor to I/O Controller
+	3341  82855PM Processor to AGP Controller
 	3575  82830 830 Chipset Host Bridge
-		1014 021d  ThinkPad T23 (2647-4MG) or A30p (2653-64G)
+		1014 021d  ThinkPad A/T/X Series
 		104d 80e7  VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
 	3576  82830 830 Chipset AGP Bridge
 	3577  82830 CGC [Chipset Graphics Controller]
+		1014 0513  ThinkPad A/T/X Series
 	3578  82830 830 Chipset Host Bridge
+	3580  82852/855GM Host Bridge
+	3582  82852/855GM Integrated Graphics Device
 	5200  EtherExpress PRO/100 Intelligent Server
 	5201  EtherExpress PRO/100 Intelligent Server
 		8086 0001  EtherExpress PRO/100 Server Ethernet Adapter
@@ -6355,6 +6951,7 @@
 	7113  82371AB/EB/MB PIIX4 ACPI
 	7120  82810 GMCH [Graphics Memory Controller Hub]
 	7121  82810 CGC [Chipset Graphics Controller]
+		8086 4341  Cayman (CA810) Mainboard
 	7122  82810 DC-100 GMCH [Graphics Memory Controller Hub]
 	7123  82810 DC-100 CGC [Chipset Graphics Controller]
 	7124  82810E DC-133 GMCH [Graphics Memory Controller Hub]
@@ -6366,6 +6963,7 @@
 	7181  440LX/EX - 82443LX/EX AGP bridge
 	7190  440BX/ZX/DX - 82443BX/ZX/DX Host bridge
 		0e11 0500  Armada 1750 Laptop System Chipset
+		0e11 b110  Armada M700
 		1179 0001  Toshiba Tecra 8100 Laptop System Chipset
 	7191  440BX/ZX/DX - 82443BX/ZX/DX AGP bridge
 	7192  440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled)
@@ -6484,6 +7082,8 @@
 	7478  AHA-2944/2944W / AIC-7874
 	7578  AHA-3944/3944W / AIC-7875
 	7678  AHA-4944W/UW / AIC-7876
+	7710  ANA-7711F Network Accelerator Card (NAC) - Optical
+	7711  ANA-7711C Network Accelerator Card (NAC) - Copper
 	7778  AIC-787x
 	7810  AIC-7810
 	7815  AIC-7815 RAID+Memory Controller IC
@@ -6560,15 +7160,49 @@
 		9005 62a1  19160 Ultra160 SCSI Controller
 	0083  AIC-7892D U160/m
 	008f  AIC-7892P U160/m
+		1179 0001  Magnia Z310
+		15d9 9005  Onboard SCSI Host Adapter
 	00c0  AHA-3960D / AIC-7899A U160/m
 		0e11 f620  Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter
 		9005 f620  AHA-3960D U160/m
 	00c1  AIC-7899B U160/m
 	00c3  AIC-7899D U160/m
 	00c5  RAID subsystem HBA
+		1028 00c5  PowerEdge 2550
 	00cf  AIC-7899P U160/m
+		1028 00d1  PowerEdge 2550
+		10f1 2462  Thunder K7 S2462
+		15d9 9005  Onboard SCSI Host Adapter
+	0250  ServeRAID Controller
+		1014 0279  ServeRAID-xx
+		1014 028c  ServeRAID-xx
 	0285  AAC-RAID
 		1028 0287  PowerEdge Expandable RAID Controller 320/DC
+	8000  ASC-29320A U320
+	800f  AIC-7901 U320
+	8010  ASC-39320 U320
+	8011  ASC-32320D U320
+		0e11 00ac  U320
+		9005 0041  ASC-39320D U320
+	8012  ASC-29320 U320
+	8013  ASC-29320B U320
+	8014  ASC-29320LP U320
+	801e  AIC-7901A U320
+	801f  AIC-7902 U320
+	8080  ASC-29320A U320 w/HostRAID
+	808f  AIC-7901 U320 w/HostRAID
+	8090  ASC-39320 U320 w/HostRAID
+	8091  ASC-39320D U320 w/HostRAID
+	8092  ASC-29320 U320 w/HostRAID
+	8093  ASC-29320B U320 w/HostRAID
+	8094  ASC-29320LP U320 w/HostRAID
+	8095  ASC-39320(B) U320 w/HostRAID
+	8096  ASC-39320A U320 w/HostRAID
+	8097  ASC-29320ALP U320 w/HostRAID
+	809c  ASC-39320D(B) U320 w/HostRAID
+	809d  AIC-7902(B) U320 w/HostRAID
+	809e  AIC-7901A U320 w/HostRAID
+	809f  AIC-7902 U320 w/HostRAID
 907f  Atronics
 	2015  IDE-2015PL
 919a  Gigapixel Corp
@@ -6589,6 +7223,8 @@
 aa42  Scitex Digital Video
 ac1e  Digital Receiver Technology Inc
 b1b3  Shiva Europe Limited
+# Pinnacle should be 11bd, but they got it wrong several times --mj
+bd11  Pinnacle Systems, Inc. (Wrong ID)
 c001  TSI Telsys
 c0a9  Micron/Crucial Technology
 c0de  Motorola
@@ -6596,6 +7232,9 @@
 ca50  Varian Australia Pty Ltd
 cafe  Chrysalis-ITS
 cccc  Catapult Communications
+cddd  Tyzx, Inc.
+	0101  DeepSea 1 High Speed Stereo Vision Frame Grabber
+	0200  DeepSea 2 High Speed Stereo Vision Frame Grabber
 d4d4  Dy4 Systems Inc
 	0601  PCI Mezzanine Card
 d531  I+ME ACTIA GmbH
@@ -6604,12 +7243,17 @@
 e000  Winbond
 	e000  W89C940
 e159  Tiger Jet Network Inc.
-	0001  Model 300 128k
+	0001  Intel 537
 		0059 0001  128k ISDN-S/T Adapter
 		0059 0003  128k ISDN-U Adapter
 	0002  Tiger100APC ISDN chipset
 e4bf  EKF Elektronik GmbH
 ea01  Eagle Technology
+# The main chip of all these devices is by Xilinx -> It could also be a Xilinx ID.
+ea60  RME
+	9896  Digi32
+	9897  Digi32 Pro
+	9898  Digi32/8
 eabb  Aashima Technology B.V.
 eace  Endace Measurement Systems, Ltd
 	3100  DAG 3.10 OC-3/OC-12
@@ -6625,15 +7269,29 @@
 	422e  DAG 4.2E Dual Gigabit Ethernet
 ec80  Belkin Corporation
 	ec00  F5D6000
-ecc0  Echo Corporation
+ecc0  Echo Digital Audio Corporation
+	0050  Gina24_301
+	0051  Gina24_361
+	0060  Layla24
+	0070  Mona_301_80
+	0071  Mona_301_66
+	0072  Mona_361
+	0080  Mia
 edd8  ARK Logic Inc
 	a091  1000PV [Stingray]
 	a099  2000PV [Stingray]
 	a0a1  2000MT
 	a0a9  2000MI
+f1d0  AJA Video
+# All boards I have seen have this ID not efac, though all docs say efac...
+	cafe  KONA SD SMPTE 259M I/O
+	efac  KONA SD SMPTE 259M I/O
+	facd  KONA HD SMPTE 292M I/O
 fa57  Fast Search & Transfer ASA
 febd  Ultraview Corp.
-feda  Epigram Inc
+feda  Broadcom Inc (nee Epigram)
+	a0fa  BCM4210 iLine10 HomePNA 2.0
+	a10e  BCM4230 iLine10 HomePNA 2.0
 fffe  VMWare Inc
 	0710  Virtual SVGA
 ffff  Illegal Vendor ID
diff -urN linux-2.4.22-pre2/drivers/pcmcia/i82092.c linux-2.4.22-pre3/drivers/pcmcia/i82092.c
--- linux-2.4.22-pre2/drivers/pcmcia/i82092.c	2003-07-05 18:09:19.000000000 -0700
+++ linux-2.4.22-pre3/drivers/pcmcia/i82092.c	2003-07-05 18:10:25.000000000 -0700
@@ -26,6 +26,7 @@
 
 #include "i82092aa.h"
 #include "i82365.h"
+#include "cirrus.h"
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Red Hat, Inc. - Arjan Van De Ven <arjanv@redhat.com>");
@@ -43,8 +44,15 @@
 	      subdevice:PCI_ANY_ID,
 	      class: 0, class_mask:0,
 
-	 },
-	 {} 
+	},
+	{
+	      vendor:PCI_VENDOR_ID_CIRRUS,
+	      device:PCI_DEVICE_ID_CIRRUS_6729,
+	      subvendor:PCI_ANY_ID,
+	      subdevice:PCI_ANY_ID,
+	      class: 0, class_mask:0,
+	},
+	{} 
 };
 
 static struct pci_driver i82092aa_pci_drv = {
@@ -90,14 +98,18 @@
 	void	*info;		/* to be passed to the handler */
 	
 	struct pci_dev *dev;	/* The PCI device for the socket */
+	
+	int type;		/* Type of socket */
+#define IS_I82092	0x0001
+#define IS_PD6729	0x0002
 };
 
 #define MAX_SOCKETS 4
 static struct socket_info sockets[MAX_SOCKETS];
 static int socket_count;  /* shortcut */
 
-int membase = -1;
-int isa_setup;
+static int membase = -1;
+static int isa_setup;
 
 MODULE_PARM(membase, "i");
 MODULE_PARM(isa_setup, "i");
@@ -107,6 +119,7 @@
 	unsigned char configbyte;
 	struct pci_dev *parent;
 	int i;
+	int type;
 	
 	enter("i82092aa_pci_probe");
 	
@@ -116,7 +129,18 @@
 	/* Since we have no memory BARs some firmware we may not
 	   have had PCI_COMMAND_MEM enabled, yet the device needs
 	   it. */
-	pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
+
+	// pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
+	if (dev->vendor == PCI_VENDOR_ID_CIRRUS) {
+		type = IS_PD6729;
+		configbyte = 0;	/* always 2 sockets */
+		printk(KERN_INFO "Cirrus PD6729 PCI to PCMCIA Bridge \n");
+	} else {
+		type = IS_I82092;
+		pci_read_config_byte(dev, 0x40, &configbyte);  /* PCI Configuration Control */
+		printk(KERN_INFO "Intel I82092AA PCI to PCMCIA Bridge \n");
+	}
+
 	if (!(configbyte | PCI_COMMAND_MEMORY)) {
 		dprintk(KERN_DEBUG "Enabling PCI_COMMAND_MEMORY\n");
 		configbyte |= PCI_COMMAND_MEMORY;
@@ -203,6 +227,7 @@
 		sockets[i].cap.map_size = 0x1000;
 		sockets[i].cap.irq_mask = 0;
 		sockets[i].cap.pci_irq  = dev->irq;
+		sockets[i].type = type;
 
 		/* Trick the resource code into doing the right thing... */
 		sockets[i].cap.cb_dev = dev;
@@ -215,10 +240,11 @@
 		}
 	}
 		
-	/* Now, specifiy that all interrupts are to be done as PCI interrupts */
-	configbyte = 0xFF; /* bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt */
-	pci_write_config_byte(dev, 0x50, configbyte); /* PCI Interrupt Routing Register */
-
+	if (type == IS_I82092) {
+		/* Now, specifiy that all interrupts are to be done as PCI interrupts */
+		configbyte = 0xFF; /* bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt */
+		pci_write_config_byte(dev, 0x50, configbyte); /* PCI Interrupt Routing Register */
+	}
 
 	/* Register the interrupt handler */
 	dprintk(KERN_DEBUG "Requesting interrupt %i \n",dev->irq);
@@ -240,6 +266,7 @@
 	enter("i82092aa_pci_remove");
 	
 	free_irq(dev->irq, i82092aa_interrupt);
+	flush_scheduled_tasks();
 
 	leave("i82092aa_pci_remove");
 }
@@ -654,6 +681,7 @@
 static int i82092aa_set_socket(unsigned int sock, socket_state_t *state) 
 {
 	unsigned char reg;
+	unsigned long flags;
 	
 	enter("i82092aa_set_socket");
 	
@@ -740,9 +768,26 @@
 	
 	/* now write the value and clear the (probably bogus) pending stuff by doing a dummy read*/
 	
+	spin_lock_irqsave(&port_lock,flags);
+
 	indirect_write(sock,I365_CSCINT,reg);
 	(void)indirect_read(sock,I365_CSC);
 
+	if (sockets[sock].type == IS_PD6729) {
+		/* Configure PD6729 bridge for PCI interrupts */
+		reg |= 0x30;	/* management IRQ: PCI INTA = "irq 3" */
+		indirect_write(sock,I365_CSCINT,reg);
+		(void)indirect_read(sock,I365_CSC);
+
+		reg = indirect_read(sock,I365_INTCTL);
+		reg |= 0x03; /* card IRQ: PCI INTA = "irq 3" */
+		indirect_write(sock,I365_INTCTL,reg);
+
+		indirect_write(sock, PD67_EXT_INDEX, PD67_EXT_CTL_1);
+		indirect_write(sock, PD67_EXT_DATA, PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ);
+	}
+	spin_unlock_irqrestore(&port_lock,flags);
+
 	leave("i82092aa_set_socket");
 	return 0;
 }
@@ -768,9 +813,10 @@
 	io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0; /* check this out later */
 	io->flags = 0;
 	
-	if (addr & I365_IOCTL_16BIT(map))
-		io->flags |= MAP_AUTOSZ;
-		
+	io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0;
+	io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0;
+	io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0;
+
 	leave("i82092aa_get_io_map");
 	return 0;
 }
@@ -788,7 +834,7 @@
 		leave("i82092aa_set_io_map with invalid map");
 		return -EINVAL;
 	}
-	if ((io->start > 0xffff) || (io->stop > 0xffff) || (io->stop < io->start)){
+	if (io->start > 0xffff || io->stop > 0xffff || io->stop < io->start){
 		leave("i82092aa_set_io_map with invalid io");
 		return -EINVAL;
 	}
@@ -805,9 +851,10 @@
 	            	
 	ioctl = indirect_read(sock,I365_IOCTL) & ~I365_IOCTL_MASK(map);
 	
-	if (io->flags & (MAP_16BIT|MAP_AUTOSZ))
-		ioctl |= I365_IOCTL_16BIT(map);
-		
+    	if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
+    	if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
+    	if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
+
 	indirect_write(sock,I365_IOCTL,ioctl);
 	
 	/* Turn the window back on if needed */
@@ -866,11 +913,19 @@
 		mem->flags |= MAP_WRPROT;
 	if (i & I365_MEM_REG)
 		mem->flags |= MAP_ATTRIB;
-	mem->card_start = ( (unsigned long)(i & 0x3fff)<12) + mem->sys_start;
-	mem->card_start &=  0x3ffffff;
 	
+	if (sockets[sock].type == IS_PD6729) {
+		/* Take care of high byte */
+		indirect_write(sock,PD67_EXT_INDEX, PD67_MEM_PAGE(map));
+		addr = indirect_read16(sock, PD67_EXT_DATA) << 24;
+		mem->sys_stop += addr; mem->sys_start += addr;
+		mem->card_start = (unsigned long)(i) + mem->sys_start;
+	} else {
+		mem->card_start = ((unsigned long)(i & 0x3fff)<12) + mem->sys_start;
+		mem->card_start &=  0x3ffffff;
+	}
+
 	dprintk("Card %i is from %lx to %lx \n",sock,mem->sys_start,mem->sys_stop);
-	
 	leave("i82092aa_get_mem_map");
 	return 0;
 	
@@ -897,7 +952,9 @@
 	if (!(mem->flags & MAP_ACTIVE))
 		return 0;
 
-	if ( (mem->card_start > 0x3ffffff) || (mem->sys_start > mem->sys_stop) ||
+	if (sockets[sock].type == IS_PD6729)  {
+		;	/* PD6729 accepts high byte */	
+	} else if ( (mem->card_start > 0x3ffffff) || (mem->sys_start > mem->sys_stop) ||
 	     ((mem->sys_start >> 24) != membase) || ((mem->sys_stop >> 24) != membase) ||
 	     (mem->speed > 1000) ) {
 		leave("i82092aa_set_mem_map: invalid address / speed");
@@ -906,7 +963,6 @@
 	}
 	
 	                 
-	                 
 /* 	printk("set_mem_map: Setting map %i range to %x - %x on socket %i, speed is %i, active = %i \n",map, mem->sys_start,mem->sys_stop,sock,mem->speed,mem->flags & MAP_ACTIVE);  */
 
 	/* write the start address */
@@ -937,6 +993,12 @@
 	
 	indirect_write16(sock,base+I365_W_STOP,i);
 	
+	if (sockets[sock].type == IS_PD6729)  {
+		/* Take care of high byte */
+		indirect_write(sock, PD67_EXT_INDEX, PD67_MEM_PAGE(map));
+		indirect_write16(sock, PD67_EXT_DATA, mem->sys_start >> 24);
+	}
+
 	/* card start */
 	
 	i = (((mem->card_start - mem->sys_start) >> 12) - (membase << 12)) & 0x3fff;
@@ -949,7 +1011,9 @@
 /*		printk("requesting normal memory for socket %i\n",sock);*/
 	}
 	indirect_write16(sock,base+I365_W_OFF,i);
-	indirect_write(sock, I365_CPAGE, membase);
+	if (sockets[sock].type == IS_I82092) {
+		indirect_write(sock, I365_CPAGE, membase);
+	}
 
 	/* Enable the window if necessary */
 	indirect_setbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
diff -urN linux-2.4.22-pre2/drivers/pcmcia/rsrc_mgr.c linux-2.4.22-pre3/drivers/pcmcia/rsrc_mgr.c
--- linux-2.4.22-pre2/drivers/pcmcia/rsrc_mgr.c	2001-12-21 09:41:55.000000000 -0800
+++ linux-2.4.22-pre3/drivers/pcmcia/rsrc_mgr.c	2003-07-05 18:10:25.000000000 -0700
@@ -419,14 +419,17 @@
 void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long),
 		  int force_low, socket_info_t *s)
 {
-    resource_map_t *m;
+    resource_map_t *m, *n;
     static int done = 0;
     
     if (!probe_mem || done++)
 	return;
-    for (m = mem_db.next; m != &mem_db; m = m->next)
+
+    for (m = mem_db.next; m != &mem_db; m = n) {
+	n = m->next;
 	if (do_mem_probe(m->base, m->num, is_valid, do_cksum, s))
 	    return;
+    }
 }
 
 #endif /* CONFIG_ISA */
diff -urN linux-2.4.22-pre2/drivers/pcmcia/ti113x.h linux-2.4.22-pre3/drivers/pcmcia/ti113x.h
--- linux-2.4.22-pre2/drivers/pcmcia/ti113x.h	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/pcmcia/ti113x.h	2003-07-05 18:10:25.000000000 -0700
@@ -167,6 +167,27 @@
 		new |= I365_INTR_ENA;
 	if (new != reg)
 		exca_writeb(socket, I365_INTCTL, new);
+
+	/*
+	 * If ISA interrupts don't work, then fall back to routing card
+	 * interrupts to the PCI interrupt of the socket.
+	 */
+	if (!socket->cap.irq_mask) {
+		int irqmux, devctl;
+
+		printk (KERN_INFO "ti113x: Routing card interrupts to PCI\n");
+
+		devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
+		devctl &= ~TI113X_DCR_IMODE_MASK;
+
+		irqmux = config_readl(socket, TI122X_IRQMUX);
+		irqmux = (irqmux & ~0x0f) | 0x02; /* route INTA */
+		irqmux = (irqmux & ~0xf0) | 0x20; /* route INTB */
+
+		config_writel(socket, TI122X_IRQMUX, irqmux);
+		config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
+	}
+
 	return 0;
 }
 
diff -urN linux-2.4.22-pre2/drivers/s390/block/dasd.c linux-2.4.22-pre3/drivers/s390/block/dasd.c
--- linux-2.4.22-pre2/drivers/s390/block/dasd.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/block/dasd.c	2003-07-05 18:10:26.000000000 -0700
@@ -6,6 +6,8 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
+ * $Revision: 1.289 $
+ *
  * History of changes (starts July 2000)
  * 11/09/00 complete redesign after code review
  * 02/01/01 added dynamic registration of ioctls
@@ -33,6 +35,7 @@
  * 06/26/01 hopefully fixed PL030172SBA,PL030234SBA
  * 07/09/01 fixed PL030324MSH (wrong statistics output)
  * 07/16/01 merged in new fixes for handling low-mem situations
+ * 01/22/01 fixed PL030579KBE (wrong statistics)
  */
 
 #include <linux/config.h>
@@ -70,7 +73,6 @@
 #include <asm/s390_ext.h>
 #include <asm/s390dyn.h>
 #include <asm/idals.h>
-#include <asm/dasd.h>
 
 #include "dasd_int.h"
 
@@ -84,8 +86,9 @@
 #include "dasd_diag.h"
 #endif				/*  CONFIG_DASD_DIAG */
 
-/* SECTION: exported variables of dasd.c */
-
+/********************************************************************************
+ * SECTION: exported variables of dasd.c 
+ ********************************************************************************/
 debug_info_t *dasd_debug_area;
 
 MODULE_AUTHOR ("Holger Smolinski <Holger.Smolinski@de.ibm.com>");
@@ -94,6 +97,9 @@
 MODULE_SUPPORTED_DEVICE ("dasd");
 MODULE_PARM (dasd, "1-" __MODULE_STRING (256) "s");
 MODULE_PARM (dasd_disciplines, "1-" __MODULE_STRING (8) "s");
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12))
+MODULE_LICENSE ("GPL");
+#endif
 EXPORT_SYMBOL (dasd_chanq_enq_head);
 EXPORT_SYMBOL (dasd_debug_area);
 EXPORT_SYMBOL (dasd_chanq_enq);
@@ -103,6 +109,7 @@
 EXPORT_SYMBOL (dasd_start_IO);
 EXPORT_SYMBOL (dasd_term_IO);
 EXPORT_SYMBOL (dasd_schedule_bh);
+EXPORT_SYMBOL (dasd_schedule_bh_timed);
 EXPORT_SYMBOL (dasd_int_handler);
 EXPORT_SYMBOL (dasd_oper_handler);
 EXPORT_SYMBOL (dasd_alloc_request);
@@ -115,17 +122,24 @@
 EXPORT_SYMBOL (dasd_set_normalized_cda);
 EXPORT_SYMBOL (dasd_device_from_kdev);
 
-/* SECTION: Constant definitions to be used within this file */
+
+/********************************************************************************
+ * SECTION: Constant definitions to be used within this file 
+ ********************************************************************************/
 
 #define PRINTK_HEADER DASD_NAME":"
-#undef  DASD_PROFILE            /* fill profile information - used for */
+#define DASD_PROFILE            /* fill profile information - used for */
                                 /* statistics and perfomance           */
 
-#define DASD_MIN_SIZE_FOR_QUEUE 32
-#undef CONFIG_DYNAMIC_QUEUE_MIN_SIZE
-#define DASD_CHANQ_MAX_SIZE 6
-
-/* SECTION: prototypes for static functions of dasd.c */
+#ifndef CONFIG_PROC_FS          /* DASD_PROFILE doesn't make sense     */
+#undef DASD_PROFILE             /* without procfs                      */
+#endif /* not CONFIG_PROC_FS */
+
+#define DASD_CHANQ_MAX_SIZE 4
+
+/********************************************************************************
+ * SECTION: prototypes for static functions of dasd.c 
+ ********************************************************************************/
 
 static request_fn_proc do_dasd_request;
 static int dasd_set_device_level (unsigned int, dasd_discipline_t *, int);
@@ -147,7 +161,11 @@
 static struct block_device_operations dasd_device_operations;
 static inline dasd_device_t ** dasd_device_from_devno (int);
 static void dasd_process_queues (dasd_device_t * device);
-/* SECTION: static variables of dasd.c */
+static int  dasd_sleep_on_immediate (ccw_req_t *cqr);
+
+/********************************************************************************
+ * SECTION: static variables of dasd.c 
+ ********************************************************************************/
 
 static devfs_handle_t dasd_devfs_handle;
 static wait_queue_head_t dasd_init_waitq;
@@ -155,7 +173,9 @@
 
 #ifdef CONFIG_DASD_DYNAMIC
 
-/* SECTION: managing dynamic configuration of dasd_driver */
+/********************************************************************************
+ * SECTION: managing dynamic configuration of dasd_driver 
+ ********************************************************************************/
 
 static struct list_head dasd_devreg_head = LIST_HEAD_INIT (dasd_devreg_head);
 
@@ -188,15 +208,17 @@
 
 #endif				/* CONFIG_DASD_DYNAMIC */
 
-/* SECTION: managing setup of dasd_driver */
+/********************************************************************************
+ * SECTION: managing setup of dasd_driver 
+ ********************************************************************************/
 
 /* default setting is probeonly, autodetect */
-static int dasd_probeonly = 1;	/* is true, when probeonly mode is active */
-static int dasd_autodetect = 1;	/* is true, when autodetection is active */
+static int dasd_probeonly =  0;	/* is true, when probeonly mode is active */
+static int dasd_autodetect = 0;	/* is true, when autodetection is active */
 
 static dasd_range_t dasd_range_head =
     { list:LIST_HEAD_INIT (dasd_range_head.list) };
-static spinlock_t range_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t range_lock     = SPIN_LOCK_UNLOCKED;
 
 /*
  * function: dasd_create_range
@@ -210,20 +232,24 @@
         int i;
 
 	if ( from > to ) {
-                printk (KERN_WARNING PRINTK_HEADER 
-                        "Adding device range %04x-%04x: range invalid, ignoring.\n",
-                        from,
-                        to);
+
+                MESSAGE (KERN_WARNING, 
+                         "Adding device range %04x-%04x: "
+                         "range invalid, ignoring.",
+                         from,
+                         to);
 
 		return NULL;
 	}
 	for (i=from;i<=to;i++) {
                 if (dasd_device_from_devno(i)) {
-                        printk (KERN_WARNING PRINTK_HEADER 
-                                "device range %04x-%04x: device %04x is already in a range.\n",
-                                from,
-                                to,
-                                i);
+
+                        MESSAGE (KERN_WARNING,
+                                 "device range %04x-%04x: device "
+                                 "%04x is already in a range.",
+                                 from,
+                                 to,
+                                 i);
                 }
         }
 	range = (dasd_range_t *) kmalloc (sizeof (dasd_range_t), GFP_KERNEL);
@@ -392,7 +418,9 @@
 	return -ENODEV;
 }
 
-/* SECTION: parsing the dasd= parameter of the parmline/insmod cmdline */
+/********************************************************************************
+ * SECTION: parsing the dasd= parameter of the parmline/insmod cmdline 
+ ********************************************************************************/
 
 /*
  * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
@@ -426,11 +454,14 @@
 			*end = '\0';
 			end++;
 		}
-		dasd[count] = kmalloc (len * sizeof (char), GFP_ATOMIC);
+		dasd[count] = kmalloc (len * sizeof (char), 
+                                       GFP_ATOMIC);
 		if (dasd[count] == NULL) {
-			printk (KERN_WARNING PRINTK_HEADER
-				"can't store dasd= parameter no %d\n",
-				count + 1);
+
+			MESSAGE (KERN_WARNING,
+                                 "can't store dasd= parameter no"
+                                 " %d",
+                                 count + 1);
 			break;
 		}
 		memset (dasd[count], 0, len * sizeof (char));
@@ -500,10 +531,13 @@
         int val,i,start;
 
         buffer=(char*)kmalloc((strlen(str)+1)*sizeof(char),GFP_ATOMIC);
+
         if (buffer==NULL) {
-            printk (KERN_WARNING PRINTK_HEADER
-                    "can't parse dasd= parameter %s due to low memory\n",
-                    str);
+
+                MESSAGE (KERN_WARNING,
+                         "can't parse dasd= parameter %s due "
+                         "to low memory",
+                         str);
         }
 
         /* remove leading '0x' */
@@ -528,7 +562,7 @@
         val = simple_strtoul (buffer, &buffer, 16);
 
         /* check for features - e.g. (ro) ; the '\0', ')' and '-' stops check */
-        *features = DASD_DEFAULT_FEATURES;
+        *features = DASD_FEATURE_DEFAULT;
 
         if (temp[i]=='(') {
 
@@ -545,14 +579,18 @@
                                         (*features) |= DASD_FEATURE_READONLY;
                                         break;
                                 }
-                                printk (KERN_WARNING PRINTK_HEADER 
-                                        "unsupported feature: %s, ignoring setting",
-                                        buffer);
+
+                                MESSAGE (KERN_WARNING,
+                                         "unsupported feature: %s, "
+                                         "ignoring setting",
+                                         buffer);
                         }
                 }
         }
 
         *stra = temp+i;
+        if ((val > 65535) || (val < 0))
+                return -EINVAL;
         return val;
 }
 
@@ -569,22 +607,23 @@
         int features;
         int rc = 0;
 
-	if (*str) {
-		/* turn off probeonly mode, if any dasd parameter is present */
-		dasd_probeonly = 0;
-		dasd_autodetect = 0;
-	}
 	while (*str) {
 		temp = *str;
 		from = 0;
 		to = 0;
 		if (strcmp ("autodetect", *str) == 0) {
 			dasd_autodetect = 1;
-			printk (KERN_INFO "turning to autodetection mode\n");
+
+			MESSAGE (KERN_INFO, "%s",
+                                 "turning to autodetection mode");
+
 			break;
 		} else if (strcmp ("probeonly", *str) == 0) {
 			dasd_probeonly = 1;
-			printk (KERN_INFO "turning to probeonly mode\n");
+
+			MESSAGE (KERN_INFO, "%s",
+                                 "turning to probeonly mode");
+
 			break;
 		} else {
 			/* turn off autodetect mode, if any range is present */
@@ -609,20 +648,16 @@
         return rc;
 }
 
-/* SECTION: Dealing with devices registered to multiple major numbers */
+/********************************************************************************
+ * SECTION: Dealing with devices registered to multiple major numbers 
+ ********************************************************************************/
 
 static spinlock_t dasd_major_lock = SPIN_LOCK_UNLOCKED;
 
-static major_info_t dasd_major_info[] = {
-	{
-	      list:LIST_HEAD_INIT (dasd_major_info[1].list)
-	 },
-	{
-	      list:LIST_HEAD_INIT (dasd_major_info[0].list),
-	      gendisk:{
-	  INIT_GENDISK (94, DASD_NAME, DASD_PARTN_BITS, DASD_PER_MAJOR)
-	  },
-      flags:DASD_MAJOR_INFO_IS_STATIC}
+static struct list_head dasd_major_info = LIST_HEAD_INIT(dasd_major_info);
+static major_info_t dasd_major_static = {
+        gendisk:{INIT_GENDISK(94, DASD_NAME, DASD_PARTN_BITS, DASD_PER_MAJOR)},
+        flags: DASD_MAJOR_INFO_IS_STATIC
 };
 
 static major_info_t *
@@ -658,8 +693,11 @@
 	if (major_info == NULL) {
 		major_info = get_new_major_info ();
 		if (!major_info) {
-			printk (KERN_WARNING PRINTK_HEADER
-				"Cannot get memory to allocate another major number\n");
+
+			MESSAGE (KERN_WARNING, "%s",
+				"Cannot get memory to allocate another "
+                                 "major number");
+
 			return -ENOMEM;
 		}
 	}
@@ -686,10 +724,12 @@
         /* register blockdevice */
 	rc = devfs_register_blkdev (major, DASD_NAME, &dasd_device_operations);
 	if (rc < 0) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"Cannot register to major no %d, rc = %d\n",
-                        major, 
-                        rc);
+                
+		MESSAGE (KERN_WARNING,
+                         "Cannot register to major no %d, rc = %d",
+                         major, 
+                         rc);
+
 		goto out_reg_blkdev; 
 	} else {
 		major_info->flags |= DASD_MAJOR_INFO_REGISTERED;
@@ -698,7 +738,7 @@
 	/* Insert the new major info into dasd_major_info if needed (dynamic major) */
 	if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {
 		spin_lock_irqsave (&dasd_major_lock, flags);
-		list_add_tail (&major_info->list, &dasd_major_info[0].list);
+		list_add_tail (&major_info->list, &dasd_major_info);
 		spin_unlock_irqrestore (&dasd_major_lock, flags);
 	}
 
@@ -791,10 +831,11 @@
         /* unregister blockdevice */
 	rc = devfs_unregister_blkdev (major, DASD_NAME);
 	if (rc < 0) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"Unable to unregister from major no %d, rc = %d\n", 
-                        major,
-			rc);
+
+		MESSAGE (KERN_WARNING,
+                         "Unable to unregister from major no %d, rc = %d", 
+                         major,
+                         rc);
 	} else {
 		major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED;
 	}
@@ -844,10 +885,12 @@
 
 	rc = devfs_unregister_blkdev (major, DASD_NAME);
 	if (rc < 0) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"Cannot unregister from major no %d, rc = %d\n",
-                        major,
-			rc);
+
+		MESSAGE (KERN_WARNING,
+                         "Cannot unregister from major no %d, rc = %d",
+                         major,
+                         rc);
+
 		return rc;
 	} else {
 		major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED;
@@ -874,20 +917,23 @@
 dasd_device_t *
 dasd_device_from_kdev (kdev_t kdev)
 {
-	major_info_t *major_info = NULL;
+	major_info_t *major_info;
+        dasd_device_t *device;
 	struct list_head *l;
 	unsigned long flags;
 
+        device = NULL;
 	spin_lock_irqsave (&dasd_major_lock, flags);
-	list_for_each (l, &dasd_major_info[0].list) {
+	list_for_each (l, &dasd_major_info) {
 		major_info = list_entry (l, major_info_t, list);
-		if (major_info->gendisk.major == MAJOR (kdev))
+		if (major_info->gendisk.major == MAJOR (kdev)) {
+                        device = major_info->dasd_device[MINOR (kdev) >>
+                                                         DASD_PARTN_BITS];
 			break;
+                }
 	}
 	spin_unlock_irqrestore (&dasd_major_lock, flags);
-	if (major_info != &dasd_major_info[0])
-		return major_info->dasd_device[MINOR (kdev) >> DASD_PARTN_BITS];
-	return NULL;
+        return device;
 }
 
 /*
@@ -900,21 +946,29 @@
 dasd_device_from_devno (int devno)
 {
 	major_info_t *major_info;
+        dasd_device_t **device;
 	struct list_head *l;
-	int devindex = dasd_devindex_from_devno (devno);
+	int devindex;
 	unsigned long flags;
 
 	spin_lock_irqsave (&dasd_major_lock, flags);
-	list_for_each (l, &dasd_major_info[0].list) {
+        devindex = dasd_devindex_from_devno (devno);
+        if (devindex < 0) {
+                spin_unlock_irqrestore (&dasd_major_lock, flags);
+                return NULL;
+        }
+
+        device = NULL;
+	list_for_each (l, &dasd_major_info) {
 		major_info = list_entry (l, major_info_t, list);
 		if (devindex < DASD_PER_MAJOR) {
-			spin_unlock_irqrestore (&dasd_major_lock, flags);
-			return &major_info->dasd_device[devindex];
+                        device = &major_info->dasd_device[devindex];
+                        break;
 		}
 		devindex -= DASD_PER_MAJOR;
 	}
 	spin_unlock_irqrestore (&dasd_major_lock, flags);
-	return NULL;
+	return device;
 }
 
 /*
@@ -945,9 +999,33 @@
 	return -ENODEV;
 }
 
+/*
+ * function: dasd_check_bp_block
+ * checks the blocksize and returns 0 if valid.
+ */
+
+static int
+dasd_check_bp_block (dasd_device_t *device)
+{
+        int rc;
 
+        switch (device->sizes.bp_block) {
+        case 512:
+        case 1024:
+        case 2048:
+        case 4096:
+                rc = 0;
+                break;
+        default:
+                rc = -EMEDIUMTYPE;
+        }
+        
+        return rc;
+}
 
-/* SECTION: managing dasd disciplines */
+/********************************************************************************
+ * SECTION: managing dasd disciplines 
+ ********************************************************************************/
 
 /* anchor and spinlock for list of disciplines */
 static struct list_head dasd_disc_head = LIST_HEAD_INIT(dasd_disc_head);
@@ -955,14 +1033,18 @@
 
 /*
  * function dasd_discipline_enq
- * chains the discpline given as argument to the head of disiplines
- * head chaining policy is required to allow module disciplines to
- * be preferred against those, who are statically linked
+ * chains the discpline given as argument to the tail of disiplines.
+ * Exception: DIAG is always queued to the head, to ensure that CMS RESERVED
+ * minidisks are invariably accessed using DIAG.
  */
 static inline void
-dasd_discipline_enq (dasd_discipline_t * d)
+dasd_discipline_enq (dasd_discipline_t *discipline)
 {
-    list_add(&d->list, &dasd_disc_head);
+        if (strncmp (discipline->name, "DIAG", 4) == 0) {
+                list_add (&discipline->list, &dasd_disc_head);
+        } else {
+                list_add_tail (&discipline->list, &dasd_disc_head);
+        }
 }
 
 /*
@@ -970,59 +1052,88 @@
  * removes the discipline given as argument from the list of disciplines
  */
 static inline void
-dasd_discipline_deq (dasd_discipline_t * d)
+dasd_discipline_deq (dasd_discipline_t * discipline)
 {
-        list_del(&d->list);
+        if (&discipline->list) {
+                list_del (&discipline->list);
+        }
 }
 
 void
-dasd_discipline_add (dasd_discipline_t * d)
+dasd_discipline_add (dasd_discipline_t * discipline)
 {
         unsigned long flags;
         MOD_INC_USE_COUNT;
 	spin_lock_irqsave (&discipline_lock,flags);
-        dasd_discipline_enq (d);
+        dasd_discipline_enq (discipline);
 	spin_unlock_irqrestore (&discipline_lock,flags);
-        dasd_enable_ranges (&dasd_range_head, d, DASD_STATE_ONLINE);
+
+        dasd_enable_ranges (&dasd_range_head, 
+                            discipline, 
+                            DASD_STATE_ONLINE);
 }
 
-void dasd_discipline_del (dasd_discipline_t * d)
+void dasd_discipline_del (dasd_discipline_t * discipline)
 {
         unsigned long flags;
+
+        dasd_disable_ranges(&dasd_range_head,
+                            discipline, 
+                            DASD_STATE_DEL, 
+                            1);
+
 	spin_lock_irqsave (&discipline_lock,flags);
-        dasd_disable_ranges(&dasd_range_head, d, DASD_STATE_DEL, 1);
-        dasd_discipline_deq (d);
+        dasd_discipline_deq (discipline);
 	spin_unlock_irqrestore (&discipline_lock,flags);
         MOD_DEC_USE_COUNT;
 }
 
+/*
+ * function dasd_find_disc
+ * checks the list of disciplines for the first one able to access the device
+ */
 static inline dasd_discipline_t *
-dasd_find_disc (dasd_device_t * device, dasd_discipline_t *d)
+dasd_find_disc (dasd_device_t * device, dasd_discipline_t *discipline)
 {
         dasd_discipline_t *t;
-        struct list_head *l = d ? &d->list : dasd_disc_head.next;
+        struct list_head *l = discipline ? 
+                              &discipline->list : dasd_disc_head.next;
+
         do {
                 t = list_entry(l,dasd_discipline_t,list);
+
                 if ( ( t->id_check == NULL ||
                        t->id_check (&device->devinfo) == 0 ) &&
                      ( t->check_characteristics == NULL ||
                        t->check_characteristics (device) == 0 ) )
                         break;
                 l = l->next;
-                if ( d || 
+                if ( discipline || 
                      l == &dasd_disc_head ) {
                         t = NULL;
                         break;
                 }
          } while ( 1 );
+
 	return t;
 }
 
-/* SECTION: profiling stuff */
+/********************************************************************************
+ * SECTION: profiling stuff 
+ ********************************************************************************/
+
+#ifdef CONFIG_PROC_FS
 
 static dasd_profile_info_t dasd_global_profile;
+#endif  /* CONFIG_PROC_FS */
 
 #ifdef DASD_PROFILE
+
+#define DASD_PROFILE_ON  1
+#define DASD_PROFILE_OFF 0
+
+static unsigned int dasd_profile_level = DASD_PROFILE_OFF;
+
 /*
  * macro: dasd_profile_add_counter
  * increments counter in global and local profiling structures
@@ -1032,7 +1143,7 @@
 { \
         int ind; \
         long help; \
-	for (ind = 0, help = value >> 3; \
+	for (ind = 0, help = value >> 2; \
              ind < 31 && help; \
              help = help >> 1, ind++) {} \
 	dasd_global_profile.counter[ind]++; \
@@ -1086,56 +1197,134 @@
 	dasd_profile_add_counter (irqtime / sectors, dasd_io_time2ps, device);
 	dasd_profile_add_counter (endtime, dasd_io_time3, device);
 }
-#endif
+#endif /* DASD_PROFILE */
 
-/* SECTION: All the gendisk stuff */
+/********************************************************************************
+ * SECTION: All the gendisk stuff 
+ ********************************************************************************/
 
 
-/* SECTION: Managing wrappers for ccwcache */
+/********************************************************************************
+ * SECTION: Managing wrappers for ccwcache 
+ ********************************************************************************/
 
 /*
  * function dasd_alloc_request
  * tries to return space for a channel program of length cplength with
  * additional data of size datasize.
- * If the ccwcache cannot fulfill the request it tries the emergeny requests
- * before giving up finally
+ * If the ccwcache cannot fulfill the request it tries the lowmem requests
+ * before giving up finally.
  * FIXME: initialization of ccw_req_t should be done by function of ccwcache
  */
 ccw_req_t *
-dasd_alloc_request (char *magic, int cplength, int datasize, dasd_device_t* device)
+dasd_alloc_request (char *magic, int cplength, int datasize, 
+                    dasd_device_t *device)
 {
-	ccw_req_t *rv = NULL;
+	ccw_req_t *cqr;
+        unsigned long size_needed;
+	unsigned long data_offset, ccw_offset;
+        dasd_lowmem_t *lowmem;
+ 
+        if ((cqr = ccw_alloc_request (magic, cplength, datasize)) != NULL) {
+                return cqr;
+        }
+
+	/* Sanity checks */
+	if (magic == NULL || datasize > PAGE_SIZE ||
+            cplength == 0 || (cplength * sizeof(ccw1_t)) > PAGE_SIZE)
+		BUG();
 
-	if ((rv = ccw_alloc_request (magic, cplength, datasize)) != NULL) {
-		return rv;
+        /* use lowmem page only for ERP or */
+        /* if there are less than 2 requests on queue */
+        if (device->queue.head != NULL &&
+            device->queue.head->next != NULL &&
+            device->queue.head->status != CQR_STATUS_ERROR) {
+                return NULL;
+        }
+
+	/* We try to keep things together in memory */
+	size_needed = (sizeof (ccw_req_t) + 7) & (~7L);
+	data_offset = ccw_offset = 0;
+	if (size_needed + datasize <= PAGE_SIZE) {
+		/* Keep data with the request */
+		data_offset = size_needed;
+		size_needed += (datasize + 7) & (~7L);
+	}
+	if (size_needed + cplength*sizeof(ccw1_t) <= PAGE_SIZE) {
+		/* Keep CCWs with request */
+		ccw_offset = size_needed;
+		size_needed += (cplength*sizeof(ccw1_t)) & (~7L);
 	}
-	if ((((sizeof (ccw_req_t) + 7) & -8) +
-	     cplength * sizeof (ccw1_t) + datasize) > PAGE_SIZE) {
-		BUG ();
+        
+        /* take page from lowmem_pool for request */
+        list_for_each_entry (lowmem, &device->lowmem_pool, list) {
+                list_del (&lowmem->list);
+                cqr = (ccw_req_t *) lowmem;
+                memset (cqr, 0, PAGE_SIZE);
+                cqr->flags |= CQR_FLAGS_LM_CQR;
+                break;
+        }
+	if (cqr == NULL)
+		return NULL;
+
+	/* take page from lowmem_pool for the extra data */
+	if (data_offset == 0) {
+
+                list_for_each_entry (lowmem, &device->lowmem_pool, list) {
+                        list_del (&lowmem->list);
+                        cqr->data = (void *) lowmem;
+                        memset (cqr->data, 0, PAGE_SIZE);
+                        break;
+                }
+		if (cqr->data == NULL) {
+			printk(KERN_DEBUG PRINTK_HEADER 
+			       "Couldn't allocate data area\n");
+                        
+                        lowmem = (dasd_lowmem_t *) cqr;
+                        list_add (&lowmem->list, &device->lowmem_pool);
+			return NULL;
 		}
-        if (device->lowmem_cqr==NULL) {
-                DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
-                                         "(%04x) Low memory! Using emergency request %p.",
-                                         device->devinfo.devno,
-                                         device->lowmem_ccws);
-
-                device->lowmem_cqr=device->lowmem_ccws;
-                rv = device->lowmem_ccws;
-		memset (rv, 0, PAGE_SIZE);
-		strncpy ((char *) (&rv->magic), magic, 4);
-		ASCEBC ((char *) (&rv->magic), 4);
-		rv->cplength = cplength;
-		rv->datasize = datasize;
-		rv->data = (void *) ((long) rv + PAGE_SIZE - datasize);
-		rv->cpaddr = (ccw1_t *) ((long) rv + sizeof (ccw_req_t));
-        } else {
-                DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
-                                         "(%04x) Refusing emergency mem for request "
-                                         "NULL, already in use at %p.",
-                                         device->devinfo.devno,
-                                         device->lowmem_ccws);
-	}
-	return rv;
+	} else {
+		/* Extra data already allocated with the request */
+		cqr->data = (void *) ((addr_t) cqr + data_offset);
+        }
+
+	/* take page from lowmem_pool for the channel program */
+	if (ccw_offset == 0) {
+
+                list_for_each_entry (lowmem, &device->lowmem_pool, list) {
+                        list_del (&lowmem->list);
+                        cqr->cpaddr = (ccw1_t *) lowmem;
+                        memset (cqr->cpaddr, 0, PAGE_SIZE);
+                        break;
+                }
+
+		if (cqr->cpaddr == NULL) {
+			printk (KERN_DEBUG PRINTK_HEADER
+				"Couldn't allocate channel program area\n");
+			if (data_offset == 0) {
+                                lowmem = (dasd_lowmem_t *) cqr->data;
+                                list_add (&lowmem->list, &device->lowmem_pool);
+                        }
+                        lowmem = (dasd_lowmem_t *) cqr;
+                        list_add (&lowmem->list, &device->lowmem_pool);
+			return NULL;
+		}
+	} else {
+		/* Channel program already allocated with the request */
+		cqr->cpaddr = (ccw1_t *) ((addr_t) cqr + ccw_offset);
+        }
+
+        /* use the remaining memory of the cqr page for IDALs */
+        cqr->lowmem_idal_ptr = (void *) ((addr_t) cqr + size_needed);
+
+	strncpy ((char *)(&cqr->magic), magic, 4);
+
+	ASCEBC((char *)(&cqr->magic), 4);
+	cqr->cplength = cplength;
+	cqr->datasize = datasize;
+
+	return cqr;
 }
 
 /*
@@ -1143,87 +1332,147 @@
  * returns a ccw_req_t to the appropriate cache or emergeny request line
  */
 void
-dasd_free_request (ccw_req_t * request, dasd_device_t* device)
+dasd_free_request (ccw_req_t *cqr, dasd_device_t* device)
 {
+        unsigned long size_needed;
+        dasd_lowmem_t *lowmem;
+
 #ifdef CONFIG_ARCH_S390X
         ccw1_t* ccw;
-        /* clear any idals used for chain */
-        ccw=request->cpaddr-1;
+        /* clear any idals used for chain (might be in lowmen cqr page, */
+        /* in seperate lowmen page or kmalloced */
+        ccw=cqr->cpaddr-1;
         do {
                 ccw++;
-                if ((ccw->cda < (unsigned long) device->lowmem_idals           ) || 
-                    (ccw->cda >= (unsigned long) device->lowmem_idals+PAGE_SIZE)   )
-                        clear_normalized_cda (ccw);
-                else {
-                        if (device->lowmem_idal_ptr != device->lowmem_idals)
-                                DASD_MESSAGE (KERN_WARNING, device,
-                                              "Freeing emergency idals from request at %p.",
-                                              request);
-                        device->lowmem_idal_ptr = device->lowmem_idals;
-                        device->lowmem_cqr=NULL;
+                if ((cqr->flags & CQR_FLAGS_LM_CQR) &&
+                    (ccw->cda >= (unsigned long) cqr) &&
+                    (ccw->cda < (unsigned long) cqr + PAGE_SIZE)) {
+                    /* IDAL is on the car lowmem page */
+                        continue;
+                }
+
+                if ((cqr->flags & CQR_FLAGS_LM_IDAL) &&
+                    (ccw->cda >= (unsigned long) cqr->lowmem_idal) &&
+                    (ccw->cda < (unsigned long) cqr->lowmem_idal + PAGE_SIZE)) {
+                        /* IDAL is on seperate lowmem page */
+                        continue;
                 }
+
+                /* IDAL was build by set_normalized_cda */
+                clear_normalized_cda (ccw);
+
         } while ((ccw->flags & CCW_FLAG_CC) || 
                  (ccw->flags & CCW_FLAG_DC)   );
 #endif
-        if (request != device->lowmem_ccws) { 
-                /* compare to lowmem_ccws to protect usage of lowmem_cqr for IDAL only ! */
-		ccw_free_request (request);
-        } else {
-                DASD_MESSAGE (KERN_WARNING, device,
-                              "Freeing emergency request at %p",
-                              request);
-                device->lowmem_cqr=NULL;
-	}
+        /* give idal lowmem page back to lowmem_pool */
+        if (cqr->flags & CQR_FLAGS_LM_IDAL) {
+                lowmem = (dasd_lowmem_t *) cqr->lowmem_idal;
+                list_add (&lowmem->list, &device->lowmem_pool);
+                cqr->flags &= ~CQR_FLAGS_LM_IDAL;
+        }
+                
+        /* give cqr lowmem pages back to lowmem_pool */
+        if (cqr->flags & CQR_FLAGS_LM_CQR) { 
+                
+                /* make the same decisions as in dasd_alloc_request */
+                size_needed = (sizeof (ccw_req_t) + 7) & (~7L);
+                if (size_needed + cqr->datasize <= PAGE_SIZE) {
+                        /* We kept the data with the request */
+                        size_needed += (cqr->datasize + 7) & (~7L);
+                } else {
+                        lowmem = (dasd_lowmem_t *) cqr->data;
+                        list_add (&lowmem->list, &device->lowmem_pool);
+                }
+                
+                if (size_needed + cqr->cplength * sizeof(ccw1_t) > PAGE_SIZE) {
+                        /* We didn't keep the CCWs with request */
+                        lowmem = (dasd_lowmem_t *) cqr->cpaddr;
+                        list_add (&lowmem->list, &device->lowmem_pool);
+                }
+                lowmem = (dasd_lowmem_t *) cqr;
+                list_add (&lowmem->list, &device->lowmem_pool);
+	} else {
+                ccw_free_request (cqr);
+        }
 }
 
+/*
+ * function dasd_set_normalized_cda
+ * calls set_normalized_cda to build IDALs.
+ * If this did not work because of low memory, we try to use memory from the 
+ * lowmem pool.
+ */
 int
-dasd_set_normalized_cda (ccw1_t * cp, unsigned long address, 
-                         ccw_req_t* request, dasd_device_t* device )
+dasd_set_normalized_cda (ccw1_t *cp, unsigned long address, 
+                         ccw_req_t *cqr, dasd_device_t *device)
 {
 #ifdef CONFIG_ARCH_S390X
+        int rc;
 	int nridaws;
+        dasd_lowmem_t *lowmem;
         int count = cp->count;
         
-        if (set_normalized_cda (cp, address)!=-ENOMEM) {
-                return 0;
-        }
-
-        if ((device->lowmem_cqr!=NULL) && (device->lowmem_cqr!=request)) {
-                DASD_MESSAGE (KERN_WARNING, device, 
-                              "Refusing emergency idals for request %p, memory"
-                              " is already in use for request %p",
-                              request,
-                              device->lowmem_cqr);
-                return -ENOMEM;
-        }
-        device->lowmem_cqr=request;
-        if (device->lowmem_idal_ptr == device->lowmem_idals) {
-            DASD_MESSAGE (KERN_WARNING,device, 
-                          "Low memory! Using emergency IDALs for request %p.\n",
-                          request);
+        /* use lowmem idal page if already assinged */
+        if (!(cqr->flags & CQR_FLAGS_LM_IDAL)) {
+                rc = set_normalized_cda (cp, (void *)address);
+                if (rc !=-ENOMEM) {
+                        return rc;
+                }
         }
+        
+        /* get number of idal words needed */
         nridaws = ((address & (IDA_BLOCK_SIZE-1)) + count + 
 		   (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
-	if ( device->lowmem_idal_ptr>=device->lowmem_idals + PAGE_SIZE ) {
-		/* Ouch! No Idals left for emergency request */
-		BUG();
-	}
+
+        /* check if we need an additional IDALs page */
+	if (!(cqr->flags & CQR_FLAGS_LM_IDAL)) {
+                /* we got no lowmem cqr page OR */
+                /* there is no space left for IDALs */
+                if ((!(cqr->flags & CQR_FLAGS_LM_CQR)) ||
+                    ((cqr->lowmem_idal_ptr + nridaws * sizeof(unsigned long)) > 
+                     ((void *) cqr + PAGE_SIZE))) {
+                        
+                        /* use lowmem page only for ERP or */
+                        /* if there are less than 2 requests on queue */
+                        if (device->queue.head != NULL &&
+                            device->queue.head->next != NULL &&
+                            device->queue.head->status != CQR_STATUS_ERROR) {
+                                return -ENOMEM;
+                        }
+                       
+                        list_for_each_entry (lowmem, &device->lowmem_pool, 
+                                             list) {
+                                list_del (&lowmem->list);
+                                cqr->lowmem_idal = (void *)lowmem;
+                                cqr->lowmem_idal_ptr  = (void *) lowmem;
+                                memset (cqr->lowmem_idal, 0, PAGE_SIZE);
+                                cqr->flags |= CQR_FLAGS_LM_IDAL;
+                                break;
+                        }
+                }
+                
+        }
+        
+        /* now we (should) have an valid lowmem_idal_ptr and enough space for */
+        /* the IDALs - fill the idals table */
 	cp->flags |= CCW_FLAG_IDA;
-	cp->cda = (__u32)(unsigned long)device->lowmem_idal_ptr;
+	cp->cda = (__u32)(unsigned long)cqr->lowmem_idal_ptr;
         do {
-		*((long*)device->lowmem_idal_ptr) = address;
-		address = (address & -(IDA_BLOCK_SIZE)) + (IDA_BLOCK_SIZE);
+		*((long*)cqr->lowmem_idal_ptr) = address;
+		address  = (address & -(IDA_BLOCK_SIZE)) + (IDA_BLOCK_SIZE);
+                cqr->lowmem_idal_ptr += sizeof(unsigned long);
 		nridaws --;
-                device->lowmem_idal_ptr += sizeof(unsigned long);
         } while ( nridaws > 0 );
 #else 
-        cp -> cda = address;
+        cp->cda = address;
 #endif
 	return 0;
 }
 
 
-/* SECTION: (de)queueing of requests to channel program queues */
+/********************************************************************************
+ * SECTION: (de)queueing of requests to channel program queues 
+ ********************************************************************************/
 
 /*
  * function dasd_chanq_enq
@@ -1245,22 +1494,26 @@
 
        
 #ifdef DASD_PROFILE
-        /* save profile information for non erp cqr */
-        if (cqr->refers == NULL) {
-                unsigned int  counter = 0;
-                ccw_req_t     *ptr;
-                dasd_device_t *device = cqr->device;
-
-                /* count the length of the chanq for statistics */
-                for (ptr = q->head; 
-                     ptr->next != NULL && counter <=31; 
-                     ptr = ptr->next) {
-                        counter++;
-                }                
-                
-                dasd_global_profile.dasd_io_nr_req[counter]++;
-                device->profile.dasd_io_nr_req[counter]++;
-        }
+        if (dasd_profile_level == DASD_PROFILE_ON) {
+
+                /* save profile information for non erp cqr */
+                if (cqr->refers == NULL) {
+                        unsigned int  counter = 0;
+                        ccw_req_t     *ptr;
+                        dasd_device_t *device = cqr->device;
+                        
+                        /* count the length of the chanq for statistics */
+                        for (ptr = q->head; 
+                             ptr->next != NULL && counter <=31; 
+                             ptr = ptr->next) {
+                                counter++;
+                        }                
+                        
+                        dasd_global_profile.dasd_io_nr_req[counter]++;
+                        device->profile.dasd_io_nr_req[counter]++;
+                }
+
+        } /* end if DASD_PROFILE_ON */
 #endif 
 }
 
@@ -1276,7 +1529,10 @@
 	q->head = cqr;
 	if (q->tail == NULL)
 		q->tail = cqr;
-	check_then_set (&cqr->status, CQR_STATUS_FILLED, CQR_STATUS_QUEUED);
+
+	check_then_set (&cqr->status, 
+                        CQR_STATUS_FILLED, 
+                        CQR_STATUS_QUEUED);
 }
 
 /*
@@ -1302,7 +1558,7 @@
 		while (prev && prev->next != cqr)
 			prev = prev->next;
 		if (prev == NULL)
-			return;
+			return; /* request not in chanq */
 		prev->next = cqr->next;
 		if (prev->next == NULL)
 			q->tail = prev;
@@ -1310,7 +1566,87 @@
 	cqr->next = NULL;
 }
 
-/* SECTION: Managing the device queues etc. */
+/********************************************************************************
+ * SECTION: Managing the device queues etc. 
+ ********************************************************************************/
+
+/*
+ * DASD_RESREL_TIMEOUT
+ *
+ * A timer is used to suspend the current reserve/release request 
+ * if it doesn't return within a certain time.
+ */
+void
+dasd_resrel_timeout (unsigned long cqr_ptr)
+{
+        dasd_device_t *device = ((ccw_req_t *) cqr_ptr)->device;
+        ccw_req_t     *cqr;
+	unsigned long flags;
+
+	s390irq_spin_lock_irqsave (device->devinfo.irq, 
+                                   flags);
+        cqr = device->queue.head;
+
+        switch (cqr->status) {
+        case CQR_STATUS_FILLED:
+        case CQR_STATUS_QUEUED:
+                /* request was not started - just set to failed */
+                cqr->status = CQR_STATUS_FAILED;
+                break;
+
+        case CQR_STATUS_IN_IO:
+        case CQR_STATUS_ERROR:        
+                if (device->discipline->term_IO (cqr) != 0);
+                        cqr->status = CQR_STATUS_FAILED;
+                break;
+
+        default:
+                ; /* DONE and FAILED are ok */
+        }
+
+        dasd_schedule_bh (device);
+
+        s390irq_spin_unlock_irqrestore (device->devinfo.irq, 
+                                        flags);
+
+} /* end dasd_resrel_timeout */
+
+/*
+ * Call unconditional reserve to break the reserve of an other system.
+ * Timeout the request if it doesn't succseed within a certain time.
+ */
+static int 
+dasd_steal_lock (dasd_device_t *device)
+{
+        ccw_req_t *cqr;
+        int rc = 0;
+
+        if (!device->discipline->steal_lock) 
+                rc = -EINVAL;
+        
+        cqr = device->discipline->steal_lock (device);
+        
+        if (cqr) {
+                struct timer_list res_timer;
+                
+                init_timer(&res_timer);
+                res_timer.function = dasd_resrel_timeout; 
+                res_timer.data     = (unsigned long) cqr;
+                res_timer.expires  = jiffies + 4 * HZ; 
+                add_timer(&res_timer);
+                
+                rc = dasd_sleep_on_immediate (cqr);
+                
+                del_timer_sync(&res_timer); 
+                dasd_free_request (cqr, 
+                                   device);
+        } else {
+                rc = -ENOMEM;
+        }
+
+        return rc;
+
+} /* end dasd_steal_lock */
 
 /*
  * DASD_TERM_IO
@@ -1331,55 +1667,57 @@
 		BUG ();
 	}
 	irq = device->devinfo.irq;
-	if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) {
-		DASD_MESSAGE (KERN_WARNING, device,
-			      " ccw_req_t 0x%08x magic doesn't match"
-			      " discipline 0x%08x\n",
-			      cqr->magic,
-			      *(unsigned int *) device->discipline->name);
+	if (strncmp ((char *) &cqr->magic, 
+                     device->discipline->ebcname, 4)) {
+
+		DEV_MESSAGE (KERN_WARNING, device,
+                             " ccw_req_t 0x%08x magic doesn't match"
+                             " discipline 0x%08x",
+                             cqr->magic,
+                             *(unsigned int *) device->discipline->name);
+
 		return -EINVAL;
 	}
         
         while ((retries < 5                    ) &&
                (cqr->status == CQR_STATUS_IN_IO)   ) {
 
-                if ( retries < 2 )
-                        rc = halt_IO(irq, (long)cqr, 
-                                     cqr->options | DOIO_WAIT_FOR_INTERRUPT);
-                else
-                        rc = clear_IO(irq, (long)cqr, 
-                                      cqr->options | DOIO_WAIT_FOR_INTERRUPT);
-
+                rc = clear_IO (irq, 
+                               (long)cqr, 
+                               cqr->options);
+                
                 switch (rc) {
                 case 0:         /* termination successful */
                         check_then_set (&cqr->status,
                                         CQR_STATUS_IN_IO, 
                                         CQR_STATUS_FAILED);
                         
-                        asm volatile ("STCK %0":"=m" (cqr->stopclk));
+                        cqr->stopclk = get_clock ();
+
                         break;
                 case -ENODEV:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "device gone, retry\n");
+                        DBF_DEV_EVENT (DBF_ERR, device, "%s",
+                                       "device gone, retry");
                         break;
                 case -EIO:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "I/O error, retry\n");
+                        DBF_DEV_EVENT (DBF_ERR, device, "%s",
+                                       "I/O error, retry");
                         break;
                 case -EBUSY:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "device busy, retry later\n");
+                        DBF_DEV_EVENT (DBF_ERR, device, "%s",
+                                       "device busy, retry later");
                         break;
                 default:
-                        DASD_MESSAGE (KERN_ERR, device,
-                                      "line %d unknown RC=%d, please report"
-                                      " to linux390@de.ibm.com\n", 
-                                      __LINE__, 
-                                      rc);
+                        DEV_MESSAGE (KERN_ERR, device,
+                                     "line %d unknown RC=%d, please "
+                                     "report to linux390@de.ibm.com", 
+                                     __LINE__, 
+                                     rc);
                         BUG ();
                         break;
                 }
 
+                dasd_schedule_bh (device);
                 retries ++;
         }
 	return rc;
@@ -1401,27 +1739,30 @@
 		BUG ();
 	}
 	irq = device->devinfo.irq;
-	if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) {
-		DASD_MESSAGE (KERN_WARNING, device,
-			      " ccw_req_t 0x%08x magic doesn't match"
-			      " discipline 0x%08x\n",
-			      cqr->magic,
-			      *(unsigned int *) device->discipline->name);
+	if (strncmp ((char *) &cqr->magic, 
+                     device->discipline->ebcname, 4)) {
+
+		DEV_MESSAGE (KERN_ERR, device,
+                             " ccw_req_t 0x%08x magic doesn't match"
+                             " discipline 0x%08x",
+                             cqr->magic,
+                             *(unsigned int *) device->discipline->name);
+
 		return -EINVAL;
 	}
 
-	asm volatile ("STCK %0":"=m" (now));
-        cqr->startclk = now;
+	now = get_clock ();
 
-	rc = do_IO (irq, cqr->cpaddr, (long) cqr, cqr->lpm, cqr->options);
+        cqr->startclk = now;
+        if (device->accessible)
+                rc = do_IO (irq, cqr->cpaddr, (long) cqr, cqr->lpm, cqr->options);
+        else
+                rc = -EBUSY;
 
 	switch (rc) {
 	case 0:
                 if (cqr->options & DOIO_WAIT_FOR_INTERRUPT) {
                         /* request already finished (synchronous IO) */
-                        DASD_MESSAGE (KERN_ERR, device, "%s",
-                                      " do_IO finished request... "
-                                      "DOIO_WAIT_FOR_INTERRUPT was set");
                         check_then_set (&cqr->status,
                                         CQR_STATUS_QUEUED, 
                                         CQR_STATUS_DONE);
@@ -1436,12 +1777,22 @@
                 }
 		break;
 	case -EBUSY:
-		DASD_MESSAGE (KERN_WARNING, device, "%s",
-			      "device busy, retry later\n");
+		DBF_DEV_EVENT (DBF_ERR, device, "%s",
+                               "device busy, retry later");
+
+                if (!timer_pending(&device->timer)) {
+                        init_timer (&device->timer);
+                        device->timer.function = dasd_schedule_bh_timed; 
+                        device->timer.data     = (unsigned long) device;
+                        device->timer.expires  = jiffies + (HZ >> 4);
+                        add_timer (&device->timer);
+                } else {
+                        mod_timer(&device->timer, jiffies + (HZ >> 4));
+                }
 		break;
 	case -ETIMEDOUT: 
-		DASD_MESSAGE (KERN_WARNING, device, "%s",
-			      "request timeout - terminated\n");
+		DBF_DEV_EVENT (DBF_ERR, device, "%s",
+                               "request timeout - terminated");
 	case -ENODEV:
 	case -EIO:
 		check_then_set (&cqr->status,
@@ -1452,9 +1803,11 @@
                 dasd_schedule_bh (device);
 		break;
 	default:
-		DASD_MESSAGE (KERN_ERR, device,
-			      "line %d unknown RC=%d, please report"
-			      " to linux390@de.ibm.com\n", __LINE__, rc);
+		DEV_MESSAGE (KERN_ERR, device,
+                             "line %d unknown RC=%d, please report"
+                             " to linux390@de.ibm.com",
+                             __LINE__, 
+                             rc);
 		BUG ();
 		break;
 	}
@@ -1465,43 +1818,83 @@
 /*
  * function dasd_sleep_on_req
  * attempts to start the IO and waits for completion
- * FIXME: replace handmade sleeping by wait_event
  */
 int
-dasd_sleep_on_req (ccw_req_t * req)
+dasd_sleep_on_req (ccw_req_t * cqr)
 {
 	unsigned long flags;
-	int cs;
-	int rc = 0;
-	dasd_device_t *device = (dasd_device_t *) req->device;
+	dasd_device_t *device = (dasd_device_t *) cqr->device;
 
-        if ( signal_pending(current) ) {
+        if (signal_pending(current)) {
                 return -ERESTARTSYS;
         }
-	s390irq_spin_lock_irqsave (device->devinfo.irq, flags);
-	dasd_chanq_enq (&device->queue, req);
+	s390irq_spin_lock_irqsave (device->devinfo.irq, 
+                                   flags);
+        
+	dasd_chanq_enq (&device->queue, 
+                        cqr);
+
 	/* let the bh start the request to keep them in order */
 	dasd_schedule_bh (device);
-	do {
-		s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags);
-		wait_event ( device->wait_q,
-			     (((cs = req->status) == CQR_STATUS_DONE) ||
-			     (cs == CQR_STATUS_FAILED) ||
-                             signal_pending(current)));
-		s390irq_spin_lock_irqsave (device->devinfo.irq, flags);
-                if ( signal_pending(current) ) {
-                        rc = -ERESTARTSYS;
-		     	if (req->status == CQR_STATUS_IN_IO ) 
-                        	device->discipline->term_IO(req);
-                        break;
-                } else if ( req->status == CQR_STATUS_FAILED) {
-                        rc = -EIO;
-                        break;
-                }
-	} while (cs != CQR_STATUS_DONE && cs != CQR_STATUS_FAILED);
-	s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags);
-	return rc;
-}				/* end dasd_sleep_on_req */
+
+        s390irq_spin_unlock_irqrestore (device->devinfo.irq, 
+                                        flags);
+
+        wait_event (device->wait_q,
+                    cqr->flags & CQR_FLAGS_FINALIZED); 
+
+        if (cqr->status == CQR_STATUS_FAILED) {
+                return -EIO;
+        }
+
+	return 0;
+
+} /* end dasd_sleep_on_req */
+
+/*
+ * function dasd_sleep_on_immediate
+ * same as dasd_sleep_on_req, but attempts to start the IO immediately 
+ * (killing the actual running IO). 
+ */
+static int
+dasd_sleep_on_immediate (ccw_req_t *cqr)
+{
+	unsigned long flags;
+	dasd_device_t *device = (dasd_device_t *) cqr->device;
+
+        if (signal_pending(current))
+                return -ERESTARTSYS;
+
+	s390irq_spin_lock_irqsave (device->devinfo.irq, 
+                                   flags);
+        
+        /* terminate currently running IO */
+        if (device->queue.head->status == CQR_STATUS_IN_IO) {
+
+                device->discipline->term_IO (device->queue.head);
+
+                device->queue.head->status = CQR_STATUS_QUEUED;
+        }
+
+	dasd_chanq_enq_head (&device->queue, 
+                             cqr);
+
+	/* let the bh start the request to keep them in order */
+	dasd_schedule_bh (device);
+
+        s390irq_spin_unlock_irqrestore (device->devinfo.irq, 
+                                        flags);
+        
+        wait_event (device->wait_q,
+                    cqr->flags & CQR_FLAGS_FINALIZED); 
+        
+        if (cqr->status == CQR_STATUS_FAILED) {
+                return -EIO;
+        }
+
+	return 0;
+
+} /* end dasd_sleep_on_immediate */
 
 /*
  * function dasd_end_request
@@ -1547,12 +1940,17 @@
 	unsigned long long now;
 	int rc = 0;
 
-	asm volatile ("STCK %0":"=m" (now));
-	if (cqr->expires && cqr->expires + cqr->startclk < now) {
-		DASD_MESSAGE (KERN_ERR, ((dasd_device_t *) cqr->device),
-			      "IO timeout 0x%08lx%08lx usecs in req %p\n",
-			      (long) (cqr->expires >> 44),
-			      (long) (cqr->expires >> 12), cqr);
+	now = get_clock ();
+
+	if (cqr->expires && 
+            cqr->expires + cqr->startclk < now) {
+
+		DBF_DEV_EVENT (DBF_WARNING, ((dasd_device_t *) cqr->device),
+                               "IO timeout 0x%08lx%08lx usecs in req %p",
+                               (long) (cqr->expires >> 44),
+                               (long) (cqr->expires >> 12), 
+                               cqr);
+
 		cqr->expires <<= 1;
                 rc = -EIO;
 	}
@@ -1569,22 +1967,36 @@
 {
 	dasd_device_t *device = cqr->device;
 
-	asm volatile ("STCK %0":"=m" (cqr->endclk));
+	cqr->endclk = get_clock ();
+
 	if (cqr->req) {
+
 #ifdef DASD_PROFILE
-		dasd_profile_add (cqr);
+                if (dasd_profile_level == DASD_PROFILE_ON) {
+                        dasd_profile_add (cqr);
+                }
 #endif
+
 		dasd_end_request (cqr->req, (cqr->status == CQR_STATUS_DONE));
 		/* free request if nobody is waiting on it */
 		dasd_free_request (cqr, cqr->device);
 	} else {
-                if ( cqr == device->init_cqr && /* bring late devices online */
-                     device->level <= DASD_STATE_ONLINE ) { 
-                        device->timer.function = dasd_enable_single_device; 
-                        device->timer.data     = (unsigned long) device;
-                        device->timer.expires  = jiffies;
-                        add_timer(&device->timer);
+                if (cqr == device->init_cqr && /* bring late devices online */
+                    device->level <= DASD_STATE_ONLINE ) { 
+                        if (!timer_pending(&device->late_timer)) {
+                                init_timer(&device->late_timer);
+                                device->late_timer.function = dasd_enable_single_device; 
+                                device->late_timer.data     = (unsigned long) device;
+                                device->late_timer.expires  = jiffies;
+                                add_timer(&device->late_timer);
+                        } else {
+                                mod_timer(&device->late_timer, jiffies);
+                        }
+                } else {
+                        /* notify sleep_on_xxx about finished cqr */
+                        cqr->flags |= CQR_FLAGS_FINALIZED;
                 }
+
 		/* notify sleeping task about finished postprocessing */
 		wake_up (&device->wait_q);
                 
@@ -1606,12 +2018,10 @@
 	dasd_chanq_t *qp = &device->queue;
 	int irq = device->devinfo.irq;
 	ccw_req_t *final_requests = NULL;
-	static int chanq_min_size = DASD_MIN_SIZE_FOR_QUEUE;
 	int chanq_max_size = DASD_CHANQ_MAX_SIZE;
 	ccw_req_t *cqr = NULL, *temp;
 	dasd_erp_postaction_fn_t erp_postaction;
 
-
 	s390irq_spin_lock_irqsave (irq, flags);
 
 	/* First we dechain the requests, processed with completed status */
@@ -1628,16 +2038,10 @@
 
                         qp->head->retries--; 
 
-			if (qp->head->dstat->flag & DEVSTAT_HALT_FUNCTION) {
-
-                                check_then_set (&qp->head->status,
-                                                CQR_STATUS_ERROR,
-                                                CQR_STATUS_FAILED);
-
-                                asm volatile ("STCK %0":"=m" (qp->head->stopclk));
-
-                        } else if ((device->discipline->erp_action == NULL                          ) ||
-                                   ((erp_action = device->discipline->erp_action (qp->head)) == NULL)   ) {
+			if ((qp->head->dstat == NULL                                         ) ||
+			    ((qp->head->dstat->flag & DEVSTAT_FLAG_SENSE_AVAIL) == 0         ) ||
+			    (device->discipline->erp_action == NULL                          ) ||
+			    ((erp_action = device->discipline->erp_action (qp->head)) == NULL)   ) {
                                 
 				erp_cqr = dasd_default_erp_action (qp->head);
 
@@ -1651,12 +2055,12 @@
 
 			if (qp->head->status == CQR_STATUS_DONE) {
 
-                                DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                                              "ERP successful");
+                                DBF_DEV_EVENT (DBF_NOTICE, device, "%s",
+                                               "ERP successful");
 			} else {
 
-                                DASD_MESSAGE (KERN_ERR, device, "%s",
-                                              "ERP unsuccessful");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "ERP unsuccessful");
 			}
 
 			if ((device->discipline->erp_postaction == NULL                              )||
@@ -1685,66 +2089,61 @@
 	} /* end while over completed requests */
 
 	if (cqr)
-		cqr->next = NULL;
+		cqr->next = NULL;         /* terminate final_requests queue */
+
 	/* Now clean the requests with final status */
 	while (final_requests) { 
 		temp = final_requests;
 		final_requests = temp->next;
 		dasd_finalize_request (temp);
 	}
+
 	/* Now we try to fetch requests from the request queue */
-	for (temp = cqr; temp != NULL; temp = temp->next)
+	for (temp = qp->head; temp != NULL; temp = temp->next) {
 		if (temp->status == CQR_STATUS_QUEUED)
 			chanq_max_size--;
+        }
+
 	while ((atomic_read(&device->plugged) == 0) &&
+               (queue) &&
                (!queue->plugged) &&
 	       (!list_empty (&queue->queue_head)) &&
-	       (req = dasd_next_request (queue)) != NULL) {
+	       (req = dasd_next_request (queue)) &&
+               (qp->head == NULL || chanq_max_size > 0)) {
 		/* queue empty or certain critera fulfilled -> transfer */
-		if (qp->head == NULL ||
-		    chanq_max_size > 0 || (req->nr_sectors >= chanq_min_size)) {
-			ccw_req_t *cqr = NULL;
-                        if (is_read_only(device->kdev) && req->cmd == WRITE) {
-
-                                DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
-                                                         "(%04x) Rejecting write request %p\n",
-                                                         device->devinfo.devno,
-                                                         req);
+                cqr = NULL;
+                if (is_read_only(device->kdev) && req->cmd == WRITE) {
 
-                                dasd_end_request (req, 0);
-                                dasd_dequeue_request (queue,req);
-                        } else {
-                            /* relocate request according to partition table */
-                            req->sector +=
-                                device->major_info->gendisk.
-                                part[MINOR (req->rq_dev)].start_sect;
-                            cqr = device->discipline->build_cp_from_req (device, req);
-                            if (cqr == NULL) {
-
-                                    DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
-                                                             "(%04x) CCW creation failed "
-                                                             "on request %p\n",
-                                                             device->devinfo.devno,
-                                                             req);
-                                    /* revert relocation of request */
-                                    req->sector -=
-                                        device->major_info->gendisk.
-                                        part[MINOR (req->rq_dev)].start_sect;
-                                    break;	/* terminate request queue loop */
-                                    
-                            }
-#ifdef CONFIG_DYNAMIC_QUEUE_MIN_SIZE
-                            chanq_min_size =
-                                (chanq_min_size + req->nr_sectors) >> 1;
-#endif				/* CONFIG_DYNAMIC_QUEUE_MIN_SIZE */
-                            dasd_dequeue_request (queue, req);
-                            dasd_chanq_enq (qp, cqr);
+                        DBF_EVENT (DBF_ERR,
+                                   "(%04x) Rejecting write request %p",
+                                   device->devinfo.devno,
+                                   req);
+                        dasd_dequeue_request (queue,req);
+                        dasd_end_request (req, 0);
+                        continue;
+                } 
+                cqr = device->discipline->build_cp_from_req (device, req);
+                        
+                if (cqr == NULL || IS_ERR(cqr)) {
+                        if (cqr == ERR_PTR(-ENOMEM)) {
+                                break;
                         }
-		} else {	/* queue not empty OR criteria not met */
-			break;	/* terminate request queue loop */
-		}
-	}
-	/* we process the requests with non-final status */
+
+                        MESSAGE (KERN_EMERG,
+                                 "(%04x) CCW creation failed "
+                                 "on request %p",
+                                 device->devinfo.devno, req);
+                        dasd_dequeue_request (queue,req);
+                        dasd_end_request (req, 0);
+                        continue;
+                }
+                dasd_dequeue_request (queue, req);
+                dasd_chanq_enq (qp, cqr);
+                chanq_max_size--;
+
+	}
+
+	/* we process the requests with non-final status */
 	if (qp->head) {
 		switch (qp->head->status) {
 		case CQR_STATUS_QUEUED:
@@ -1764,6 +2163,10 @@
 			/* just wait */
 			break;
 		default:
+                        MESSAGE (KERN_EMERG,
+                                 "invalid cqr (%p) detected with status %02x ",
+                                 qp->head,
+                                 qp->head->status);
 			BUG ();
 		}
 	}
@@ -1786,6 +2189,18 @@
 }
 
 /*
+ * function dasd_schedule_bh_timed
+ * retriggers the dasd_schedule_bh function (called by timer queue)
+ */
+void 
+dasd_schedule_bh_timed (unsigned long device_ptr)
+{
+        dasd_device_t *device = (dasd_device_t *) device_ptr;
+
+        dasd_schedule_bh (device);
+}
+
+/*
  * function dasd_schedule_bh
  * schedules the request_fn to run with next run_bh cycle
  */
@@ -1842,30 +2257,43 @@
 
 	if (device_addr == NULL) {
 
-		printk (KERN_DEBUG PRINTK_HEADER
-			"unable to find device for state change pending "
-			"interrupt: devno%04x\n", 
-                        stat->devno);
+		MESSAGE (KERN_DEBUG,
+                         "unable to find device for state change pending "
+                         "interrupt: devno%04x", 
+                         stat->devno);
                 return;
 	} 
 
         /* re-activate first request in queue */
         cqr = (*device_addr)->queue.head;
+
+	if (cqr == NULL) {
+		MESSAGE (KERN_DEBUG,
+			 "got state change pending interrupt on"
+			 "idle device: %04x",
+			 stat->devno);
+		return;
+	}
         
         if (cqr->status == CQR_STATUS_PENDING) {
                 
-                DASD_MESSAGE (KERN_DEBUG, (*device_addr), "%s",
-                              "device request queue restarted by "
-                              "state change pending interrupt\n");
+                DEV_MESSAGE (KERN_DEBUG, (*device_addr), "%s",
+                             "device request queue restarted by "
+                             "state change pending interrupt");
                 
-                del_timer (&(*device_addr)->timer);
+                del_timer_sync (&(*device_addr)->blocking_timer);
                 
                 check_then_set (&cqr->status,
                                 CQR_STATUS_PENDING, CQR_STATUS_QUEUED);
                 
-                dasd_schedule_bh (*device_addr);
-                
         }
+	if (cqr->status == CQR_STATUS_IN_IO) {
+		cqr->status = CQR_STATUS_QUEUED;
+		DEV_MESSAGE (KERN_WARNING, (*device_addr), "%s",
+				"redriving state change pending condition while in IO");
+	}
+
+        dasd_schedule_bh (*device_addr);
 
 } /* end dasd_handle_state_change_pending */
 
@@ -1879,50 +2307,50 @@
 	int ip;
 	ccw_req_t *cqr;
 	dasd_device_t *device;
-        unsigned long long now;
-	dasd_era_t era = dasd_era_none; /* default is everything is okay */
+	dasd_era_t era;
 	devstat_t *stat = (devstat_t *)ds;
 
         if (stat == NULL) {
                 BUG();
 	}
-        DASD_DRIVER_DEBUG_EVENT (6, dasd_int_handler,
-                                 "Interrupt: IRQ %02x, stat %02x, devno %04x",
-                                 irq,
-                                 stat->dstat,
-                                 stat->devno);
-        asm volatile ("STCK %0":"=m" (now));
+
+        DBF_EVENT (DBF_DEBUG,
+                   "Int: IRQ %02x, CS/DS %04x, flag %08x, devno %04x, ip %08x",
+                   irq,
+                   ((stat->cstat<<8)|stat->dstat),
+                   stat->flag,
+                   stat->devno,
+                   stat->intparm);
 
         /* first of all check for state change pending interrupt */
         if ((stat->dstat & DEV_STAT_ATTENTION ) && 
             (stat->dstat & DEV_STAT_DEV_END   ) &&
             (stat->dstat & DEV_STAT_UNIT_EXCEP)   ) {
-                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
-                                         "State change Interrupt: %04x",
-                                         stat->devno);
+
+                DBF_EVENT (DBF_NOTICE,
+                           "State change Interrupt: %04x",
+                           stat->devno);
+
                 dasd_handle_state_change_pending (stat);
                 return;
         }
 
 	ip = stat->intparm;
 	if (!ip) {		/* no intparm: unsolicited interrupt */
-                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
-                                         "Unsolicited Interrupt: %04x",
-                                         stat->devno);
-		printk (KERN_DEBUG PRINTK_HEADER
-                        "unsolicited interrupt: irq 0x%x devno %04x\n",
-                        irq,
-                        stat->devno);
+
+		MESSAGE (KERN_DEBUG,
+                         "unsolicited interrupt: irq 0x%x devno %04x",
+                         irq,
+                         stat->devno);
 		return;
 	}
-	if (ip & 0x80000001) {
-                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
-                                         "spurious Interrupt: %04x",
-                                         stat->devno);
-		printk (KERN_DEBUG PRINTK_HEADER
-                        "spurious interrupt: irq 0x%x devno %04x, parm %08x\n",
-                        irq,
-                        stat->devno,ip);
+
+	if (ip & 0x80000001) {  /* check for invalid 'cqr' address */
+
+		MESSAGE (KERN_DEBUG,
+                         "spurious interrupt: irq 0x%x devno %04x, parm %08x",
+                         irq,
+                         stat->devno,ip);
 		return;
 	}
 
@@ -1930,19 +2358,16 @@
 
         /* check status - the request might have been killed because of dyn dettach */
 	if (cqr->status != CQR_STATUS_IN_IO) {
-                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
-                                         "invalid status %02x on device %04x",
-                                         cqr->status,
-                                         stat->devno);
-
-		printk (KERN_DEBUG PRINTK_HEADER
-                        "invalid status: irq 0x%x devno %04x, status %02x\n",
-                        irq,
-                        stat->devno,
-                        cqr->status);
+
+		MESSAGE (KERN_DEBUG,
+                         "invalid status: irq 0x%x devno %04x, status %02x",
+                         irq,
+                         stat->devno,
+                         cqr->status);
 		return;
 	}
 
+        /* some consistency checks */
 	device = (dasd_device_t *) cqr->device;
 	if (device == NULL || 
             device != ds-offsetof(dasd_device_t,dev_status)) {
@@ -1955,73 +2380,98 @@
                 BUG();
 	}
 
-        /* first of all lets try to find out the appropriate era_action */
-        DASD_DEVICE_DEBUG_EVENT (4, device," Int: CS/DS 0x%04x",
-                                 ((stat->cstat<<8)|stat->dstat));
-
 	/* first of all lets try to find out the appropriate era_action */
-	if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL ||
-	    stat->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) {
-		/* anything abnormal ? */
-		if (device->discipline->examine_error == NULL ||
-		    stat->flag & DEVSTAT_HALT_FUNCTION) {
-			era = dasd_era_fatal;
-		} else {
-			era = device->discipline->examine_error (cqr, stat);
-		}
-                DASD_DRIVER_DEBUG_EVENT (1, dasd_int_handler," era_code %d",
-                                         era);
-	}
-        if ( era == dasd_era_none ) {
-                check_then_set(&cqr->status, 
-                               CQR_STATUS_IN_IO, 
-                               CQR_STATUS_DONE);
-
-                cqr->stopclk=now;
-		/* start the next queued request if possible -> fast_io */
-                if (cqr->next &&
-                    cqr->next->status == CQR_STATUS_QUEUED) {
-                        if (device->discipline->start_IO (cqr->next) != 0) {
-                                printk (KERN_WARNING PRINTK_HEADER
-                                        "Interrupt fastpath failed!\n");
-                        } 
-                }
-        } else { /* error */
+        if (stat->flag & DEVSTAT_HALT_FUNCTION) {
+                era = dasd_era_fatal;
+                
+	} else if (stat->flag  & DEVSTAT_FINAL_STATUS &&
+                   stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
+                   stat->cstat == 0) {
+		/* received 'ok' for running IO */
+		era = dasd_era_none;
+                
+        } else if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL) {
+                /* got sense data */
 		if (cqr->dstat == NULL)
 			cqr->dstat = kmalloc (sizeof (devstat_t), GFP_ATOMIC);
 		if (cqr->dstat) {
 			memcpy (cqr->dstat, stat, sizeof (devstat_t));
 		} else {
-			PRINT_ERR ("no memory for dstat...ignoring\n");
+			MESSAGE (KERN_DEBUG, "%s",
+                                 "no memory for dstat...ignoring");
 		}
-
 #ifdef ERP_DEBUG
-		/* dump sense data */
-		if (device->discipline            && 
+		if (device->discipline            &&
                     device->discipline->dump_sense  ) {
-
+                        
                         device->discipline->dump_sense (device, 
                                                         cqr);
 		}
 #endif
+                if (device->discipline->examine_error == NULL) {
+                        era = dasd_era_recover;
+                } else {
+                        era = device->discipline->examine_error (cqr, stat);
+                }
 
-		switch (era) {
-		case dasd_era_fatal:
-			check_then_set (&cqr->status, 
-                                        CQR_STATUS_IN_IO,
-					CQR_STATUS_FAILED);
+        } else  if (stat->flag & DEVSTAT_NOT_OPER) {
+                /* path became offline or similar                          */
+                /* => retry to see if there are any other pathes available */
+                DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Device or a path became not operational while in IO");
+		era = dasd_era_recover;
+
+        } else if (stat->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END) ||
+                   stat->cstat & ~(SCHN_STAT_PCI | SCHN_STAT_INCORR_LEN) ) {
+                /* received device state apart from (channel end & device end)  */
+                /* OR any kind of channel check (e.g. IFCC, DATA_CHECK or ..... */
+                /* we got no sense data, therefore we just retry                */
+                DEV_MESSAGE (KERN_DEBUG, device,
+                             "Status without sense (IFCC,...) CS/DS %04x flag %08x",
+			     ((stat->cstat<<8)|stat->dstat),
+			     stat->flag);
+		era = dasd_era_recover;
 
-                        cqr->stopclk = now;
-			break;
-		case dasd_era_recover:
-			check_then_set (&cqr->status, 
-                                        CQR_STATUS_IN_IO,
-					CQR_STATUS_ERROR);
-			break;
-		default:
-			BUG ();
+        } else {
+                /* any other kind of interrupt  - just retry */
+                DEV_MESSAGE (KERN_DEBUG, device,
+                             "Got unclassified interrupt CS/DS %04x flag %08x",
+                             ((stat->cstat<<8)|stat->dstat),
+                             stat->flag);
+                era = dasd_era_recover;
+        }
+        
+        switch (era) {
+        case dasd_era_none:
+		check_then_set(&cqr->status, 
+			       CQR_STATUS_IN_IO, 
+			       CQR_STATUS_DONE);
+		cqr->stopclk = get_clock ();
+		/* start the next queued request if possible -> fast_io */
+		if (cqr->next &&
+		    cqr->next->status == CQR_STATUS_QUEUED) {
+			if (device->discipline->start_IO (cqr->next) != 0) {
+				MESSAGE (KERN_WARNING, "%s",
+					 "Interrupt fastpath failed!");
+			} 
 		}
-	}
+		break;
+        case dasd_era_fatal:
+		check_then_set (&cqr->status, 
+				CQR_STATUS_IN_IO,
+				CQR_STATUS_FAILED);
+		cqr->stopclk = get_clock ();
+		break;
+        case dasd_era_recover:
+		check_then_set (&cqr->status, 
+				CQR_STATUS_IN_IO,
+				CQR_STATUS_ERROR);
+		break;
+        default:
+		BUG ();
+        }
+	
+	/* handle special device initialization request */
         if ( cqr == device->init_cqr &&
              ( cqr->status == CQR_STATUS_DONE ||
                cqr->status == CQR_STATUS_FAILED )){
@@ -2033,59 +2483,47 @@
 
 } /* end dasd_int_handler */
 
-/* SECTION: Some stuff related to error recovery */
+/********************************************************************************
+ * SECTION: Some stuff related to error recovery 
+ ********************************************************************************/
 
 /*
  * DEFAULT_ERP_ACTION
  *
  * DESCRIPTION
- *   sets up the default-ERP ccw_req_t, namely one, which performs a TIC
- *   to the original channel program with a retry counter of 16
+ *   just retries the current cqr
  *
  * PARAMETER
  *   cqr                failed CQR
  *
  * RETURN VALUES
- *   erp                CQR performing the ERP
+ *   cqr                modified CQR
  */
 ccw_req_t *
 dasd_default_erp_action (ccw_req_t * cqr)
 {
 
         dasd_device_t *device = cqr->device;
-	ccw_req_t     *erp    = dasd_alloc_request ((char *) &cqr->magic, 1, 0, cqr->device);
-
-	printk (KERN_DEBUG PRINTK_HEADER "Default ERP called... \n");
-
-	if (!erp) {
-
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "Unable to allocate ERP request");
-                
+        // just retry - there is nothing to save ... I got no sense data....
+        if (cqr->retries > 0) {
+                DEV_MESSAGE (KERN_DEBUG, device, 
+                             "default ERP called (%i retries left)",
+                             cqr->retries);
+ 
                 check_then_set (&cqr->status,
                                 CQR_STATUS_ERROR,
-                                CQR_STATUS_FAILED);
-
-                asm volatile ("STCK %0":"=m" (cqr->stopclk));
-
-                return cqr;
-	}
-
-	erp->cpaddr->cmd_code = CCW_CMD_TIC;
-	erp->cpaddr->cda = (__u32) (addr_t) cqr->cpaddr;
-	erp->function = dasd_default_erp_action;
-	erp->refers = cqr;
-	erp->device = cqr->device;
-	erp->magic = cqr->magic;
-	erp->retries = 16;
-
-	erp->status = CQR_STATUS_FILLED;
-
-        dasd_chanq_enq_head (&device->queue,
-                             erp);
-
-	return erp;
-
+                                CQR_STATUS_QUEUED);
+        } else {
+                DEV_MESSAGE (KERN_WARNING, device, "%s",
+			     "default ERP called (NO retry left)");
+		
+		check_then_set (&cqr->status,
+				CQR_STATUS_ERROR,
+				CQR_STATUS_FAILED);
+		
+		cqr->stopclk = get_clock ();
+        }
+        return cqr;
 } /* end dasd_default_erp_action */
 
 /*
@@ -2141,26 +2579,21 @@
 	/* save ptr to original cqr */
 	cqr = erp;
 
-	/* set corresponding status to original cqr */
+	/* set corresponding status for original cqr */
 	if (success) {
-
-		check_then_set (&cqr->status, 
-                                CQR_STATUS_ERROR,
-				CQR_STATUS_DONE);
+                cqr->status = CQR_STATUS_DONE;
 	} else {
-
-		check_then_set (&cqr->status,
-				CQR_STATUS_ERROR, 
-                                CQR_STATUS_FAILED);
-
-                asm volatile ("STCK %0":"=m" (cqr->stopclk));
+                cqr->status  = CQR_STATUS_FAILED;
+                cqr->stopclk = get_clock ();
 	}
 
 	return cqr;
 
 } /* end default_erp_postaction */
 
-/* SECTION: The helpers of the struct file_operations */
+/********************************************************************************
+ * SECTION: The helpers of the struct file_operations 
+ ********************************************************************************/
 
 /*
  * function dasd_format
@@ -2175,39 +2608,41 @@
 {
 	int rc = 0;
 	int openct = atomic_read (&device->open_count);
+        ccw_req_t *req;
 
 	if (openct > 1) {
-		DASD_MESSAGE (KERN_WARNING, device, "%s",
-			      "dasd_format: device is open! expect errors.");
+
+		DEV_MESSAGE (KERN_WARNING, device, "%s",
+                             "dasd_format: device is open! "
+                             "expect errors.");
 	}
-	DASD_MESSAGE (KERN_INFO, device,
-		      "formatting units %d to %d (%d B blocks) flags %d",
-		      fdata->start_unit, 
-                      fdata->stop_unit,
-		      fdata->blksize, 
-                      fdata->intensity);
+
+	DBF_DEV_EVENT (DBF_NOTICE, device,
+                       "formatting units %d to %d (%d B blocks) flags %d",
+                       fdata->start_unit, 
+                       fdata->stop_unit,
+                       fdata->blksize, 
+                       fdata->intensity);
+
 	while ((!rc) && (fdata->start_unit <= fdata->stop_unit)) {
-                ccw_req_t *req;
-                dasd_format_fn_t ffn = device->discipline->format_device;
-		ffn = device->discipline->format_device;
-		if (ffn == NULL)
+
+		if (device->discipline->format_device == NULL)
 			break;
-		req = ffn (device, fdata);
+
+		req = device->discipline->format_device (device, fdata);
 		if (req == NULL) {
 			rc = -ENOMEM;
 			break;
 		}
 		if ((rc = dasd_sleep_on_req (req)) != 0) {
-			DASD_MESSAGE (KERN_WARNING, device,
-				      " Formatting of unit %d failed with rc = %d\n",
-				      fdata->start_unit, rc);
+
+			DEV_MESSAGE (KERN_WARNING, device,
+                                     " Formatting of unit %d failed "
+                                     "with rc = %d",
+                                     fdata->start_unit, rc);
 			break;
 		} 
 		dasd_free_request (req, device);	/* request is no longer used */
-	        if ( signal_pending(current) ) {
-			rc = -ERESTARTSYS;
-			break;		
-                }
 		fdata->start_unit++;
 	}
 	return rc;
@@ -2258,6 +2693,9 @@
 	return 0;
 }
 
+/*
+ * handle the re-read partition table IOCTL (BLKRRPART)
+ */ 
 static int
 dasd_revalidate (dasd_device_t * device)
 {
@@ -2267,8 +2705,9 @@
 	int openct = atomic_read (&device->open_count);
 	int start = MINOR (kdev);
 	if (openct != 1) {
-		DASD_MESSAGE (KERN_WARNING, device, "%s",
-			      "BLKRRPART: device is open! expect errors.");
+
+		DEV_MESSAGE (KERN_WARNING, device, "%s",
+                             "BLKRRPART: device is open! expect errors.");
 	}
 	for (i = (1 << DASD_PARTN_BITS) - 1; i >= 0; i--) {
                 int major = device->major_info->gendisk.major;
@@ -2279,6 +2718,15 @@
         return rc;
 
 }
+
+/*
+ * function do_dasd_ioctl
+ * Implementation of the DASD API.
+ * Changes to the API should be binary compatible to privous versions
+ * of the user-space applications by means of any already existing tool 
+ * (e.g. dasdfmt) must work with the new kernel API.
+ */
+
 static int
 do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data)
 {
@@ -2287,10 +2735,12 @@
 	major_info_t *major_info;
 
 	if (!device) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"No device registered as device (%d:%d)\n",
-			MAJOR (inp->i_rdev), 
-                        MINOR (inp->i_rdev));
+
+		MESSAGE (KERN_WARNING,
+                         "No device registered as device (%d:%d)",
+                         MAJOR (inp->i_rdev), 
+                         MINOR (inp->i_rdev));
+
 		return -EINVAL;
 	}
 	if ((_IOC_DIR (no) != _IOC_NONE) && (data == 0)) {
@@ -2298,225 +2748,356 @@
 		return -EINVAL;
 	}
 	major_info = device->major_info;
-#if 0
-	printk (KERN_DEBUG PRINTK_HEADER
-		"ioctl 0x%08x %s'0x%x'%d(%d) on /dev/%s (%d:%d,"
-		" devno 0x%04x on irq %d) with data %8lx\n",
-		no,
-		_IOC_DIR (no) == _IOC_NONE ? "0" :
-		_IOC_DIR (no) == _IOC_READ ? "r" :
-		_IOC_DIR (no) == _IOC_WRITE ? "w" :
-		_IOC_DIR (no) == (_IOC_READ | _IOC_WRITE) ? "rw" : "u",
-		_IOC_TYPE (no),
-                _IOC_NR (no),
-                _IOC_SIZE (no),
-		device->name, 
-                MAJOR (inp->i_rdev), 
-                MINOR (inp->i_rdev),
-		device->devinfo.devno, 
-                device->devinfo.irq, 
-                data);
-#endif
+
+	DBF_DEV_EVENT (DBF_DEBUG, device,
+                 "ioctl 0x%08x %s'0x%x'%d(%d) with data %8lx",
+                 no,
+                 (_IOC_DIR (no) == _IOC_NONE ? "0" :
+                  _IOC_DIR (no) == _IOC_READ ? "r" :
+                  _IOC_DIR (no) == _IOC_WRITE ? "w" :
+                  _IOC_DIR (no) == (_IOC_READ | _IOC_WRITE) ? "rw" : "u"),
+                 _IOC_TYPE (no),
+                 _IOC_NR (no),
+                 _IOC_SIZE (no),
+                 data);
+
 	switch (no) {
-        case DASDAPIVER: {
-			int ver = DASD_API_VERSION;
-			rc = put_user(ver, (int *) data);
-			break;
+        case DASDAPIVER: {      /* retrun dasd API version */
+                int ver = DASD_API_VERSION;
+                rc = put_user(ver, (int *) data);
+                break;
+        }
+	case BLKGETSIZE: {	/* Return device size in # of sectors */
+                long blocks = major_info->gendisk.sizes 
+                        [MINOR (inp->i_rdev)] << 1;
+                rc = put_user(blocks, (long *) data);
+                break;
+        }
+	case BLKGETSIZE64:{ 
+                u64 blocks = major_info->gendisk.sizes 
+                        [MINOR (inp->i_rdev)];
+                rc = put_user(blocks << 10, (u64 *) data);
+                break;
+        }
+	case BLKRRPART: {       /* reread partition table */
+                if (!capable (CAP_SYS_ADMIN)) {
+                        rc = -EACCES;
+                        break;
+                }
+                rc = dasd_revalidate (device);
+                break;
         }
-	case BLKGETSIZE:{	/* Return device size */
-			long blocks = major_info->gendisk.sizes 
-                                      [MINOR (inp->i_rdev)] << 1;
-			rc = put_user(blocks, (long *) data);
-			break;
-		}
-	case BLKGETSIZE64:{
-			u64 blocks = major_info->gendisk.sizes 
-                                      [MINOR (inp->i_rdev)];
-			rc = put_user(blocks << 10, (u64 *) data);
-			break;
-		}
-	case BLKRRPART:{
-			if (!capable (CAP_SYS_ADMIN)) {
-				rc = -EACCES;
-				break;
-			}
-			rc = dasd_revalidate (device);
-			break;
-		}
-	case HDIO_GETGEO:{
-			struct hd_geometry geo = { 0, };
-			rc = dasd_fillgeo (inp->i_rdev, &geo);
-			if (rc)
-				break;
+	case HDIO_GETGEO: {     /* return disk geometry */
+                struct hd_geometry geo = { 0, };
+                rc = dasd_fillgeo (inp->i_rdev, &geo);
+                if (rc)
+                        break;
 
-			rc = copy_to_user ((struct hd_geometry *) data, &geo,
-					   sizeof (struct hd_geometry));
-			if (rc)
-				rc = -EFAULT;
-			break;
-		}
-	case BIODASDDISABLE:{
-			if (!capable (CAP_SYS_ADMIN)) {
-				rc = -EACCES;
-				break;
-			}
-                        if ( device->level > DASD_STATE_ACCEPT) {
-                                dasd_deactivate_queue(device);
-                                if ( device->request_queue)
-                                        dasd_flush_request_queues(device,0);
-                                dasd_flush_chanq(device,0);
-                                dasd_disable_blkdev(device);
-                                dasd_set_device_level (device->devinfo.devno, 
-                                                       device->discipline, 
-                                                       DASD_STATE_ACCEPT);
-                        }
+                rc = copy_to_user ((struct hd_geometry *) data, &geo,
+                                   sizeof (struct hd_geometry));
+                if (rc)
+                        rc = -EFAULT;
+                break;
+        }
+	case BIODASDDISABLE: {  /* disable device */
+                if (!capable (CAP_SYS_ADMIN)) {
+                        rc = -EACCES;
                         break;
+                }
+
+                if ( device->level > DASD_STATE_ACCEPT) {
+                        dasd_deactivate_queue(device);
+                        if ( device->request_queue)
+                                dasd_flush_request_queues(device,0);
+                        dasd_flush_chanq(device,0);
+                        dasd_disable_blkdev(device);
+                        dasd_set_device_level (device->devinfo.devno, 
+                                               device->discipline, 
+                                               DASD_STATE_ACCEPT);
+                }
+
+                break;
         }
-	case BIODASDENABLE:{
-                        dasd_range_t range = { 
-                                from: device->devinfo.devno,
-                                to: device->devinfo.devno 
-                        };
-			if (!capable (CAP_SYS_ADMIN)) {
-				rc = -EACCES;
-				break;
-			}
-                        dasd_enable_ranges (&range, device->discipline, 0);
+	case BIODASDENABLE: {   /* enable device */
+                dasd_range_t range = { 
+                        from: device->devinfo.devno,
+                        to: device->devinfo.devno 
+                };
+                if (!capable (CAP_SYS_ADMIN)) {
+                        rc = -EACCES;
                         break;
+                }
+                dasd_enable_ranges (&range, device->discipline, 0);
+                break;
         }
-	case BIODASDFMT:{
-			/* fdata == NULL is no longer a valid arg to dasd_format ! */
-			int partn = MINOR (inp->i_rdev) &
-			    ((1 << major_info->gendisk.minor_shift) - 1);
-			format_data_t fdata;
+	case BIODASDFMT: {      /* format device */
+                /* fdata == NULL is no longer a valid arg to dasd_format ! */
+                int partn = MINOR (inp->i_rdev) &
+                        ((1 << major_info->gendisk.minor_shift) - 1);
+                format_data_t fdata;
+                
+                if (!capable (CAP_SYS_ADMIN)) {
+                        rc = -EACCES;
+                        break;
+                }
+                if (dasd_features_from_devno(device->devinfo.devno)&DASD_FEATURE_READONLY) {
+                        rc = -EROFS;
+                        break;
+                }
+                if (!data) {
+                        rc = -EINVAL;
+                        break;
+                }
+                rc = copy_from_user (&fdata, (void *) data,
+                                     sizeof (format_data_t));
+                if (rc) {
+                        rc = -EFAULT;
+                        break;
+                }
+                if (partn != 0) {
 
-			if (!capable (CAP_SYS_ADMIN)) {
-				rc = -EACCES;
-				break;
-			}
-                        if (dasd_features_from_devno(device->devinfo.devno)&DASD_FEATURE_READONLY) {
-                                rc = -EROFS;
-                                break;
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "Cannot low-level format a partition");
+
+                        return -EINVAL;
+                }
+                rc = dasd_format (device, &fdata);
+                break;
+        }
+	case BIODASDSATTR: {      /* Set Attributes (cache operations) */
+
+                attrib_data_t attrib;
+                
+                if (!capable (CAP_SYS_ADMIN)) {
+                        rc = -EACCES;
+                        break;
+                }
+
+                if (!data) {
+                        rc = -EINVAL;
+                        break;
+                }
+                        
+                if (!device->discipline->set_attrib) {
+                        rc = -EINVAL;
+                        break;
+                }
+                        
+                rc = copy_from_user (&attrib, (void *) data,
+                                     sizeof (attrib_data_t));
+                if (rc) {
+                        rc = -EFAULT;
+                        break;
+                }
+
+                rc = device->discipline->set_attrib (device,
+                                                     &attrib);
+                break;
+        }
+	case BIODASDPRRST: {    /* reset device profile information */
+                if (!capable (CAP_SYS_ADMIN)) {
+                        rc = -EACCES;
+                        break;
+                }
+                memset (&device->profile, 0,
+                        sizeof (dasd_profile_info_t));
+                break;
+        }
+	case BIODASDPRRD: {     /* return device profile information */
+                rc = copy_to_user((long *)data,
+                                  (long *)&device->profile,
+                                  sizeof(dasd_profile_info_t));
+                if (rc)
+                        rc = -EFAULT;
+                break;
+        }
+	case BIODASDRSRV: {     /* reserve device */
+                ccw_req_t *cqr;
+                if (!capable (CAP_SYS_ADMIN)) {
+                        rc = -EACCES;
+                        break;
+                }
+
+                if (!device->discipline->reserve) {
+                        rc = -EINVAL;
+                        break;
+                }
+                
+                cqr = device->discipline->reserve (device);
+
+                if (cqr) {
+                        struct timer_list res_timer;
+                        
+                        init_timer (&res_timer);
+                        res_timer.function = dasd_resrel_timeout; 
+                        res_timer.data     = (unsigned long) cqr;
+                        res_timer.expires  = jiffies + 2 * HZ; 
+                        add_timer (&res_timer);
+                        
+                        rc = dasd_sleep_on_immediate (cqr);
+
+                        del_timer_sync (&res_timer); 
+                        dasd_free_request (cqr, 
+                                           device);
+                } else {
+                        rc = -ENOMEM;
+                }
+                break;
+        }
+	case BIODASDRLSE: {     /* release device */
+                ccw_req_t *cqr;
+                if (!capable (CAP_SYS_ADMIN)) {
+                        rc = -EACCES;
+                        break;
+                }
+
+                if (!device->discipline->release) {
+                        rc = -EINVAL;
+                        break;
+                }
+
+                cqr = device->discipline->release (device);
+                
+                if (cqr) {
+                        struct timer_list rel_timer;
+                        
+                        init_timer (&rel_timer);
+                        rel_timer.function = dasd_resrel_timeout; 
+                        rel_timer.data     = (unsigned long) cqr;
+                        rel_timer.expires  = jiffies + 2 * HZ; 
+                        add_timer (&rel_timer);
+                        
+                        rc = dasd_sleep_on_immediate (cqr);
+
+                        del_timer_sync (&rel_timer); /* in case of interrupt */
+                        dasd_free_request (cqr, 
+                                           device);
+                } else {
+                        rc = -ENOMEM;
+                }
+                break;
+        }
+	case BIODASDSLCK: {     /* steal lock - unconditional reserve device */
+                if (!capable (CAP_SYS_ADMIN)) {
+                        rc = -EACCES;
+                        break;
+                }
+                        
+                rc = dasd_steal_lock (device);
+                break;
+        }
+	case BIODASDINFO:       /* return dasd information */
+	case BIODASDINFO2: {    /* return dasd information2 (incl. format and features) */
+                dasd_information2_t dasd_info;
+                
+                unsigned long flags;
+
+                if (!device->discipline->fill_info) {
+                        rc = -EINVAL;
+                        break;
+                }
+
+                rc = device->discipline->fill_info (device, 
+                                                    &dasd_info);
+
+                dasd_info.label_block = device->sizes.pt_block;
+                dasd_info.devno = device->devinfo.devno;
+                dasd_info.schid = device->devinfo.irq;
+                dasd_info.cu_type = device->devinfo.sid_data.cu_type;
+                dasd_info.cu_model = device->devinfo.sid_data.cu_model;
+                dasd_info.dev_type = device->devinfo.sid_data.dev_type;
+                dasd_info.dev_model = device->devinfo.sid_data.dev_model;
+                dasd_info.open_count =
+                        atomic_read (&device->open_count);
+                dasd_info.status = device->level;
+                
+                /* check if device is really formatted - LDL / CDL was returned by 'fill_info' */
+                if ((device->level < DASD_STATE_READY) ||
+                    (dasd_check_bp_block (device)    )   ) {
+                        dasd_info.format = DASD_FORMAT_NONE;
+                }
+                
+                dasd_info.features = 
+                        dasd_features_from_devno (device->devinfo.devno);
+                
+                if (device->discipline) {
+                        memcpy (dasd_info.type,
+                                device->discipline->name, 4);
+                } else {
+                        memcpy (dasd_info.type, "none", 4);
+                }
+                dasd_info.req_queue_len = 0;
+                dasd_info.chanq_len = 0;
+
+                if ((device->request_queue            ) &&
+                    (device->request_queue->request_fn)   ) {
+                        struct list_head *l;
+                        ccw_req_t *cqr = device->queue.head;
+                        spin_lock_irqsave (&io_request_lock, flags);
+                        list_for_each (l,
+                                       &device->request_queue->
+                                       queue_head) {
+                                dasd_info.req_queue_len++;
                         }
-			if (!data) {
-				rc = -EINVAL;
-				break;
-			}
-			rc = copy_from_user (&fdata, (void *) data,
-					     sizeof (format_data_t));
-			if (rc) {
-				rc = -EFAULT;
-				break;
-			}
-			if (partn != 0) {
-				DASD_MESSAGE (KERN_WARNING, device, "%s",
-					      "Cannot low-level format a partition");
-				return -EINVAL;
-			}
-			rc = dasd_format (device, &fdata);
-			break;
-		}
-	case BIODASDPRRST:{     /* reset device profile information */
-			if (!capable (CAP_SYS_ADMIN)) {
-				rc = -EACCES;
-				break;
-			}
-			memset (&device->profile, 0,
-				sizeof (dasd_profile_info_t));
-			break;
-		}
-	case BIODASDPRRD:{      /* retrun device profile information */
-			rc = copy_to_user((long *)data,
-					  (long *)&device->profile,
-					  sizeof(dasd_profile_info_t));
-			if (rc)
-				rc = -EFAULT;
-			break;
-		}
-	case BIODASDRSRV:{      /* reserve */
-			ccw_req_t *req;
-			if (!capable (CAP_SYS_ADMIN)) {
-				rc = -EACCES;
-				break;
-			}
-			req = device->discipline->reserve (device);
-			rc = dasd_sleep_on_req (req);
-			dasd_free_request (req, device);
-			break;
-		}
-	case BIODASDRLSE:{      /* release */
-			ccw_req_t *req;
-			if (!capable (CAP_SYS_ADMIN)) {
-				rc = -EACCES;
-				break;
-			}
-			req = device->discipline->release (device);
-			rc = dasd_sleep_on_req (req);
-			dasd_free_request (req, device);
-			break;
-		}
-	case BIODASDSLCK:{      /* steal lock - unconditional reserve */
-			ccw_req_t *req;
-			if (!capable (CAP_SYS_ADMIN)) {
-				rc = -EACCES;
-				break;
-			}
-			req = device->discipline->steal_lock (device);
-			rc = dasd_sleep_on_req (req);
-			dasd_free_request (req, device);
-			break;
-		}
-	case BIODASDINFO:{
-			dasd_information_t dasd_info;
-			unsigned long flags;
-			rc = device->discipline->fill_info (device, &dasd_info);
-                        dasd_info.label_block = device->sizes.pt_block;
-			dasd_info.devno = device->devinfo.devno;
-			dasd_info.schid = device->devinfo.irq;
-			dasd_info.cu_type = device->devinfo.sid_data.cu_type;
-			dasd_info.cu_model = device->devinfo.sid_data.cu_model;
-			dasd_info.dev_type = device->devinfo.sid_data.dev_type;
-			dasd_info.dev_model = device->devinfo.sid_data.dev_model;
-			dasd_info.open_count =
-			    atomic_read (&device->open_count);
-			dasd_info.status = device->level;
-			if (device->discipline) {
-				memcpy (dasd_info.type,
-					device->discipline->name, 4);
-			} else {
-				memcpy (dasd_info.type, "none", 4);
-			}
-			dasd_info.req_queue_len = 0;
-			dasd_info.chanq_len = 0;
-			if (device->request_queue->request_fn) {
-				struct list_head *l;
-				ccw_req_t *cqr = device->queue.head;
-				spin_lock_irqsave (&io_request_lock, flags);
-				list_for_each (l,
-					       &device->request_queue->
-					       queue_head) {
-					dasd_info.req_queue_len++;
-				}
-				spin_unlock_irqrestore (&io_request_lock,
-							flags);
-				s390irq_spin_lock_irqsave (device->devinfo.irq,
-							   flags);
-				while (cqr) {
-					cqr = cqr->next;
-					dasd_info.chanq_len++;
-				}
-				s390irq_spin_unlock_irqrestore (device->devinfo.
-								irq, flags);
-			}
-			rc =
-			    copy_to_user ((long *) data, (long *) &dasd_info,
-					  sizeof (dasd_information_t));
-			if (rc)
-				rc = -EFAULT;
-			break;
-		}
+                        spin_unlock_irqrestore (&io_request_lock,
+                                                flags);
+                        s390irq_spin_lock_irqsave (device->devinfo.irq,
+                                                   flags);
+                        while (cqr) {
+                                cqr = cqr->next;
+                                dasd_info.chanq_len++;
+                        }
+                        s390irq_spin_unlock_irqrestore (device->devinfo.
+                                                        irq, flags);
+                }
+
+                rc = copy_to_user ((long *) data, (long *) &dasd_info,
+                                   ((no == (unsigned int) BIODASDINFO2) ? 
+                                    sizeof (dasd_information2_t) : 
+                                    sizeof (dasd_information_t)));
+
+                if (rc)
+                        rc = -EFAULT;
+                break;
+        }
+        case BIODASDPSRD: { /* Performance Statistics Read */
+                
+                ccw_req_t              *cqr;
+                dasd_rssd_perf_stats_t *stats;
+
+                if ((!device->discipline->read_stats) ||
+                    (!device->discipline->ret_stats )   ) {
+                        rc = -EINVAL;
+                        break;
+                }
+
+                cqr = device->discipline->read_stats (device); 
+                
+                if (cqr) {
+                        
+                        if ((rc = dasd_sleep_on_req (cqr)) == 0) {
+                                
+                                if ((stats = device->discipline->ret_stats (cqr)) != NULL) {
+                                        
+                                        rc = copy_to_user ((long *) data,
+                                                           (long *) stats,
+                                                           sizeof (dasd_rssd_perf_stats_t));
+                                } else {
+                                        
+                                        rc = -EFAULT;
+                             }
+                        }
+                        
+                        dasd_free_request (cqr, 
+                                           device);
+                        
+                } else {
+                        rc = -ENOMEM;
+                }
+                break;
+        }
 #if 0 /* needed for XFS */
-	case BLKBSZSET:{
+	case BLKBSZSET: {
 		int bsz;
 		rc = copy_from_user ((long *)&bsz,(long *)data,sizeof(int));
 		if ( rc ) {
@@ -2528,10 +3109,46 @@
 				rc = -EINVAL; 
 		}
 		break;
-		}
+        }
 #endif /* 0 */
+	case BLKROSET: {
+                int intval;
+                dasd_range_t *temp;
+                int devindex = 0;
+                unsigned long flags;
+                struct list_head *l;
+                int major=MAJOR(device->kdev);
+                int minor;
+
+                if (!capable(CAP_SYS_ADMIN))
+                        return -EACCES;
+                if (inp->i_rdev != device->kdev)
+                        // ro setting is not allowed for partitions
+                        return -EINVAL; 
+                if (get_user(intval, (int *)(data)))
+                        return -EFAULT;
+                spin_lock_irqsave (&range_lock, flags);
+                list_for_each (l, &dasd_range_head.list) {
+                        temp = list_entry (l, dasd_range_t, list);
+                        if (device->devinfo.devno >= temp->from && device->devinfo.devno <= temp->to) {
+                                spin_unlock_irqrestore (&range_lock, flags);
+                                if (intval)
+                                        temp->features |= DASD_FEATURE_READONLY;
+                                else
+                                        temp->features &= ~DASD_FEATURE_READONLY;
+                                goto continue_blkroset;
+                        }
+                        devindex += temp->to - temp->from + 1;
+                }
+                spin_unlock_irqrestore (&range_lock, flags);
+                return(-ENODEV);
+continue_blkroset:
+                for (minor = MINOR(device->kdev); minor < MINOR(device->kdev) + (1 << DASD_PARTN_BITS); minor++)
+                        set_device_ro(MKDEV(major,minor), intval);
+                return 0;
+        }
+	case BLKBSZGET:
 	case BLKSSZGET:
-	case BLKROSET:
 	case BLKROGET:
 	case BLKRASET:
 	case BLKRAGET:
@@ -2541,37 +3158,41 @@
 	case BLKELVSET:
 		return blk_ioctl (inp->i_rdev, no, data);
 		break;
-	default:{
+	default: {
 
-			dasd_ioctl_list_t *old = dasd_find_ioctl (no);
-			if (old) {
-				if ( old->owner )
-					__MOD_INC_USE_COUNT(old->owner);
-				rc = old->handler (inp, no, data);
-				if ( old->owner )
-					__MOD_DEC_USE_COUNT(old->owner);
-			} else {
-				DASD_MESSAGE (KERN_INFO, device,
-					      "ioctl 0x%08x=%s'0x%x'%d(%d) data %8lx\n",
-					      no,
-					      _IOC_DIR (no) == _IOC_NONE ? "0" :
-					      _IOC_DIR (no) == _IOC_READ ? "r" :
-					      _IOC_DIR (no) == _IOC_WRITE ? "w" : 
-                                              _IOC_DIR (no) == 
-                                              (_IOC_READ | _IOC_WRITE) ? "rw" : "u",
-                                              _IOC_TYPE (no),
-					      _IOC_NR (no), 
-                                              _IOC_SIZE (no),
-					      data);
-				rc = -ENOTTY;
-			}
-			break;
+                dasd_ioctl_list_t *old = dasd_find_ioctl (no);
+                if (old) {
+                        if ( old->owner )
+                                __MOD_INC_USE_COUNT(old->owner);
+                        rc = old->handler (inp, no, data);
+                        if ( old->owner )
+                                __MOD_DEC_USE_COUNT(old->owner);
+                } else {
+
+                        DBF_DEV_EVENT (DBF_INFO, device,
+                                       "unknown ioctl 0x%08x=%s'0x%x'%d(%d) data %8lx",
+                                       no,
+                                       (_IOC_DIR (no) == _IOC_NONE ? "0" :
+                                        _IOC_DIR (no) == _IOC_READ ? "r" :
+                                        _IOC_DIR (no) == _IOC_WRITE ? "w" : 
+                                        _IOC_DIR (no) == 
+                                        (_IOC_READ | _IOC_WRITE) ? "rw" : "u"),
+                                       _IOC_TYPE (no),
+                                       _IOC_NR (no), 
+                                       _IOC_SIZE (no),
+                                       data);
+
+                        rc = -ENOTTY;
+                }
+                break;
 		}
 	}
 	return rc;
 }
 
-/* SECTION: The members of the struct file_operations */
+/********************************************************************************
+ * SECTION: The members of the struct file_operations 
+ ********************************************************************************/
 
 static int
 dasd_ioctl (struct inode *inp, struct file *filp,
@@ -2597,26 +3218,32 @@
                 goto fail;
 	}
 	if (dasd_probeonly) {
-		printk ("\n" KERN_INFO PRINTK_HEADER
-			"No access to device (%d:%d) due to probeonly mode\n",
-			MAJOR (inp->i_rdev), 
-                        MINOR (inp->i_rdev));
+
+		MESSAGE (KERN_INFO,
+                         "No access to device (%d:%d) due to probeonly mode",
+                         MAJOR (inp->i_rdev), 
+                         MINOR (inp->i_rdev));
+
 		rc = -EPERM;
                 goto fail;
 	}
         spin_lock_irqsave(&discipline_lock,flags);
 	device = dasd_device_from_kdev (inp->i_rdev);
 	if (!device) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"No device registered as (%d:%d)\n",
-			MAJOR (inp->i_rdev), 
-                        MINOR (inp->i_rdev));
+
+		MESSAGE (KERN_WARNING,
+                         "No device registered as (%d:%d)",
+                         MAJOR (inp->i_rdev), 
+                         MINOR (inp->i_rdev));
+
 		rc = -ENODEV;
                 goto unlock;
 	}
 	if (device->level <= DASD_STATE_ACCEPT ) {
-		DASD_MESSAGE (KERN_WARNING, device, " %s", 
-                              " Cannot open unrecognized device\n");
+
+		DBF_DEV_EVENT (DBF_ERR, device, " %s", 
+                               " Cannot open unrecognized device");
+
 		rc = -ENODEV;
                 goto unlock;
 	}
@@ -2648,17 +3275,21 @@
 	}
 	device = dasd_device_from_kdev (inp->i_rdev);
 	if (!device) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"No device registered as %d:%d\n",
-			MAJOR (inp->i_rdev), 
-                        MINOR (inp->i_rdev));
+
+		MESSAGE (KERN_WARNING,
+                         "No device registered as %d:%d",
+                         MAJOR (inp->i_rdev), 
+                         MINOR (inp->i_rdev));
+
 		rc = -EINVAL;
                 goto out;
 	}
 
 	if (device->level < DASD_STATE_ACCEPT ) {
-		DASD_MESSAGE (KERN_WARNING, device, " %s",
-                              " Cannot release unrecognized device\n");
+
+		DBF_DEV_EVENT (DBF_ERR, device, " %s",
+                               " Cannot release unrecognized device");
+
 		rc = -ENODEV;
                 goto out;
 	}
@@ -2669,8 +3300,9 @@
                         __MOD_DEC_USE_COUNT(device->discipline->owner);
 	} else if ( count == -1 ) { /* paranoia only */
                 atomic_set (&device->open_count,0);
-                printk (KERN_WARNING PRINTK_HEADER
-                        "release called with open count==0\n");
+
+                MESSAGE (KERN_WARNING, "%s",
+                         "release called with open count==0");
         }
  out:
 	return rc;
@@ -2685,7 +3317,9 @@
 	ioctl:dasd_ioctl,
 };
 
-/* SECTION: Management of device list */
+/********************************************************************************
+ * SECTION: Management of device list 
+ ********************************************************************************/
 int
 dasd_fillgeo(int kdev,struct hd_geometry *geo)
 {
@@ -2708,24 +3342,27 @@
 int
 dasd_device_name (char *str, int index, int partition, struct gendisk *hd)
 {
-	int len = 0;
+        major_info_t *major_info;
+        struct list_head *l;
 	char first, second, third;
+	int len;
 
-	if (hd) {
-		major_info_t *major_info = NULL;
-		struct list_head *l;
-
-		list_for_each (l, &dasd_major_info[0].list) {
-			major_info = list_entry (l, major_info_t, list);
-			if (&major_info->gendisk == hd) {
-				break;
-			}
-			index += DASD_PER_MAJOR;
-		}
-		if (major_info == &dasd_major_info[0]) {
-			return -EINVAL;
-		}
-	}
+        if (hd == NULL)
+                return -EINVAL;
+
+        major_info = NULL;
+        list_for_each (l, &dasd_major_info) {
+                major_info = list_entry (l, major_info_t, list);
+                if (&major_info->gendisk == hd)
+                        break;
+                index += DASD_PER_MAJOR;
+        }
+        if (major_info == NULL || &major_info->gendisk != hd) { 
+                /* list empty or hd not found in list */
+                return -EINVAL;
+        }
+
+        len = 0;
 	third = index % 26;
 	second = ((index - 26) / 26) % 26;
 	first = (((index - 702) / 26) / 26) % 26;
@@ -2777,7 +3414,8 @@
                              cqr->status != CQR_STATUS_FAILED ) {
 
                                 cqr->status = CQR_STATUS_FAILED;
-                                asm volatile ("STCK %0":"=m" (cqr->stopclk));
+
+                                cqr->stopclk = get_clock ();
 
                         }
                         dasd_schedule_bh(device);
@@ -2802,6 +3440,56 @@
         } 
 }
 
+static inline void dasd_do_hotplug_event (dasd_device_t* device, int eventid) {
+#ifdef CONFIG_HOTPLUG
+        int i;
+        char *argv[3], *envp[8];
+        char devno[20],major[20],minor[20],devname[26],action[20];
+
+        /* setup command line arguments */
+        i=0;
+        argv[i++] = hotplug_path;
+        argv[i++] = "dasd";
+        argv[i++] = 0;
+
+        /* minimal environment */
+        i=0;
+        envp[i++] = "HOME=/";
+        envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+        
+        /* device information and event*/
+        sprintf (devno, "DEVNO=%04x", device->devinfo.devno);
+        sprintf (major, "MAJOR=%d", MAJOR(device->kdev));
+        sprintf (minor, "MINOR=%d", MINOR(device->kdev));
+        sprintf (devname, "DASDNAME=%s",device->name);
+        switch (eventid) {
+        case DASD_HOTPLUG_EVENT_ADD:
+                sprintf (action,"ACTION=add");
+                break;
+        case DASD_HOTPLUG_EVENT_REMOVE:
+                sprintf (action,"ACTION=remove");
+                break;
+        case DASD_HOTPLUG_EVENT_PARTCHK:
+                sprintf (action,"ACTION=partchk");
+                break;
+        case DASD_HOTPLUG_EVENT_PARTREMOVE:
+                sprintf (action,"ACTION=partremove");
+                break;
+        default:
+                BUG();
+        }
+        envp[i++] = devno;
+        envp[i++] = major;
+        envp[i++] = minor;
+        envp[i++] = devname;
+        envp[i++] = action;
+        envp[i++] = 0;
+        
+        call_usermodehelper (argv [0], argv, envp);
+#endif
+}
+
+
 static int
 dasd_disable_volume ( dasd_device_t * device, int force ) 
 {
@@ -2810,8 +3498,9 @@
         int count = atomic_read (&device->open_count);
         
 	if ( count ) {
-		DASD_MESSAGE (KERN_EMERG, device, "%s",
-			      "device has vanished although it was open!");
+
+		DEV_MESSAGE (KERN_EMERG, device, "%s",
+                             "device has vanished although it was open!");
         }
         if ( force ) {
                 dasd_deactivate_queue(device);
@@ -2824,9 +3513,11 @@
         /* unregister partitions ('ungrok_partitions') */
         devfs_register_partitions(&device->major_info->gendisk,
                                   MINOR(device->kdev),1);
+        dasd_do_hotplug_event (device, DASD_HOTPLUG_EVENT_PARTREMOVE);
         
-        DASD_MESSAGE (KERN_WARNING, device, 
-                      "disabling device, target state: %d",target);
+        DBF_DEV_EVENT (DBF_ERR, device, 
+                       "disabling device, target state: %d",
+                       target);
 
         dasd_set_device_level (device->devinfo.devno, 
                                device->discipline, 
@@ -2836,7 +3527,7 @@
 
 static void
 dasd_disable_ranges (dasd_range_t *range, 
-                     dasd_discipline_t *d,
+                     dasd_discipline_t *discipline,
                      int all, int force ) 
 {
         dasd_range_t *rrange;
@@ -2858,14 +3549,15 @@
                         }
                         device = *dptr;
                         if (device == NULL ||
-                            (d != NULL &&
-                             device -> discipline != d))
+                            (discipline != NULL &&
+                             device -> discipline != discipline))
                                 continue;
                         
                         dasd_disable_volume(device, force);
                 }
                 rrange = list_entry (rrange->list.next, dasd_range_t, list);
         } while ( all && rrange && rrange != range );
+        
 }
 
 static void 
@@ -2877,10 +3569,13 @@
 }
 
 static void
-dasd_enable_ranges (dasd_range_t *range, dasd_discipline_t *d, int all ) 
+dasd_enable_ranges (dasd_range_t *range, 
+                    dasd_discipline_t *discipline, 
+                    int all) 
 {
         int retries = 0;
 	int j;
+        int do_again;
         kdev_t tempdev;
 	dasd_range_t *rrange;
 
@@ -2888,6 +3583,7 @@
 		return;
         
         do {
+                do_again = 0;
                 if (range == &dasd_range_head) {
                         rrange = list_entry (range->list.next, 
                                              dasd_range_t, list);
@@ -2898,26 +3594,40 @@
                         for (j = rrange->from; j <= rrange->to; j++) {
                                 if ( dasd_devindex_from_devno(j) < 0 )
                                         continue;
-                                dasd_set_device_level (j, d, DASD_STATE_ONLINE);
+                                if (-EAGAIN == dasd_set_device_level 
+                                    (j, discipline, DASD_STATE_ONLINE))
+                                        do_again = 1;
                         }
                         rrange = list_entry (rrange->list.next, dasd_range_t, list);
                 } while ( all && rrange && rrange != range );
 
-                if (atomic_read (&dasd_init_pending) == 0) /* we are done, exit loop */
+                if ((atomic_read (&dasd_init_pending) == 0) &&
+                    (!do_again)) /* we are done, exit loop */
                         break;
 
                 if ( retries == 0 ) {
-                        printk (KERN_INFO PRINTK_HEADER
-                                "waiting for responses...\n");
+
+                        MESSAGE (KERN_INFO, "%s",
+                                 "waiting for responses...");
+
                 } else if ( retries < 5 ) {
-                        printk (KERN_INFO PRINTK_HEADER
-                                "waiting a little bit longer...\n");
+
+                        DBF_EVENT (DBF_NOTICE, "%s",
+                                   "waiting a little bit longer...");
+
                 } else {
-                        printk (KERN_INFO PRINTK_HEADER
-                                "giving up, enable late devices manually!\n");
+
+                        MESSAGE (KERN_INFO, "%s",
+                                 "giving up, enable late devices manually!");
                         break;
                 }
-                interruptible_sleep_on_timeout (&dasd_init_waitq, (1 * HZ));
+
+                /* prevent scheduling if called by bh (timer) */
+                if (!in_interrupt()) {
+                        interruptible_sleep_on_timeout (&dasd_init_waitq, 
+                                                        (1 * HZ)         );
+                }
+
                 retries ++;
         } while (1);
         /* now setup block devices */
@@ -2939,9 +3649,9 @@
                         device = *dptr;
                         if (device == NULL )
                                 continue;
-                        if ( ((d == NULL && device->discipline != NULL) ||
-                              (device->discipline == d )) &&
-                             device->level >= DASD_STATE_READY &&
+                        if ( ((discipline == NULL && device->discipline != NULL) ||
+                              (device->discipline == discipline )) &&
+                             device->level == DASD_STATE_ONLINE &&
                              device->request_queue == NULL ) {
                                 if (dasd_features_from_devno(j)&DASD_FEATURE_READONLY) {
                                         for (tempdev=device->kdev;
@@ -2949,9 +3659,8 @@
                                              tempdev++)
                                                 set_device_ro (tempdev, 1);
 
-                                        printk (KERN_WARNING PRINTK_HEADER 
-                                                "setting read-only mode for device /dev/%s\n",
-                                                device->name);
+                                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                                     "setting read-only mode ");
                                 }
                                 dasd_setup_blkdev(device);
                                 dasd_setup_partitions(device);
@@ -2971,13 +3680,17 @@
 static void
 dasd_not_oper_handler (int irq, int status)
 {
-	dasd_device_t *device = NULL;
-	major_info_t *major_info = NULL;
+	dasd_device_t *device;
+	major_info_t *major_info;
+        ccw_req_t* cqr;
 	struct list_head *l;
-	int i, devno = -ENODEV;
+        unsigned long flags;
+	int i, devno;
 
 	/* find out devno of leaving device: CIO has already deleted this information ! */
-	list_for_each (l, &dasd_major_info[0].list) {
+        devno = -ENODEV;
+	device = NULL;
+	list_for_each (l, &dasd_major_info) {
 		major_info = list_entry (l, major_info_t, list);
 		for (i = 0; i < DASD_PER_MAJOR; i++) {
 			device = major_info->dasd_device[i];
@@ -2990,17 +3703,44 @@
 			break;
 	}
 
-	DASD_DRIVER_DEBUG_EVENT (5, dasd_not_oper_handler, 
-                                 "called for devno %04x", 
-                                 devno);
-
 	if (devno < 0) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"not_oper_handler called on irq 0x%04x no devno!\n", 
-                        irq);
+
+		MESSAGE (KERN_WARNING,
+                         "not_oper_handler called on irq 0x%04x no devno!", 
+                         irq);
 		return;
 	}
-        dasd_disable_volume(device, 1);
+	switch (status) {
+	case DEVSTAT_DEVICE_GONE:
+	case DEVSTAT_REVALIDATE: //FIXME
+		DEV_MESSAGE (KERN_DEBUG, device, "%s", 
+			"device is gone, disabling it permanently\n");
+        	dasd_disable_volume(device, 1);
+		break;
+	case DEVSTAT_NOT_ACC:
+	case DEVSTAT_NOT_ACC_ERR:
+		DEV_MESSAGE (KERN_DEBUG, device, "%s",
+			"device is not accessible, disabling it temporary\n");                
+                s390irq_spin_lock_irqsave (device->devinfo.irq, 
+                                           flags);
+                device->accessible = 0;
+		if (status == DEVSTAT_NOT_ACC_ERR) {
+			cqr = device->queue.head;
+			while (cqr) {
+				if (cqr->status == CQR_STATUS_QUEUED)
+					break;
+				if (cqr->status == CQR_STATUS_IN_IO)
+					cqr->status = CQR_STATUS_QUEUED;
+				cqr = cqr->next;
+			}
+		}
+                s390irq_spin_unlock_irqrestore(device->devinfo.irq, 
+                                               flags);
+
+		break;
+	default:
+		panic ("dasd not operational handler was called with illegal status\n");
+	}
 }
 
 /*
@@ -3014,56 +3754,62 @@
 {
 	int devno;
 	int rc = 0;
-	major_info_t *major_info = NULL;
+	major_info_t *major_info;
         dasd_range_t *rptr,range;
-        dasd_device_t *device = NULL;
+        dasd_device_t *device;
 	struct list_head *l;
+	unsigned long flags;
         int i;
 
+
 	devno = get_devno_by_irq (irq);
 	if (devno == -ENODEV) {
 		rc = -ENODEV;
                 goto out;
 	}
 
-	DASD_DRIVER_DEBUG_EVENT (5, dasd_oper_handler, 
-                                 "called for devno %04x", 
-                                 devno);
-
 	/* find out devno of device */
-	list_for_each (l, &dasd_major_info[0].list) {
+	device = NULL;
+	list_for_each (l, &dasd_major_info) {
 		major_info = list_entry (l, major_info_t, list);
 		for (i = 0; i < DASD_PER_MAJOR; i++) {
 			device = major_info->dasd_device[i];
-			if (device && device->devinfo.irq == irq) {
-				devno = device->devinfo.devno;
+			if (device && device->devinfo.irq == irq)
 				break;
-			}
+			else
+                                device = NULL;
 		}
-		if (devno != -ENODEV)
+		if (device)
 			break;
 	}
-	if (devno < 0) {
-                BUG();
-	}
+
         if ( device &&
-             device->level == DASD_STATE_READY ) {
-            dasd_set_device_level (device->devinfo.devno, 
-                                   device->discipline, DASD_STATE_ONLINE);
+             (device->level == DASD_STATE_ONLINE) &&
+	     (!device->accessible) ) {
+                s390irq_spin_lock_irqsave (device->devinfo.irq, 
+                                           flags);
+		DEV_MESSAGE (KERN_DEBUG, device, "%s",
+			"device is accessible again, reenabling it\n");
+                device->accessible = 1;
+                s390irq_spin_unlock_irqrestore(device->devinfo.irq, 
+                                               flags);
 
+		    
+                dasd_schedule_bh(device);
         } else {
-            if (dasd_autodetect) {
-		rptr = dasd_add_range (devno, devno, DASD_DEFAULT_FEATURES);
-                if ( rptr == NULL ) {
-                    rc = -ENOMEM;
-                    goto out;
-                }
-            } else {
-                range.from = devno;
-                range.to = devno;
-                rptr = &range;
-            }
-            dasd_enable_ranges (rptr, NULL, 0);
+
+                if (dasd_autodetect) {
+                        rptr = dasd_add_range (devno, devno, DASD_FEATURE_DEFAULT);
+                        if ( rptr == NULL ) {
+                                rc = -ENOMEM;
+                                goto out;
+                        }
+                } else {
+                        range.from = devno;
+                        range.to = devno;
+                        rptr = &range;
+                }
+                dasd_enable_ranges (rptr, NULL, 0);
         }
  out:
 	return rc;
@@ -3075,13 +3821,16 @@
 {
         dasd_device_t **device_addr;
 
-	DASD_DRIVER_DEBUG_EVENT (1, dasd_find_device_addr, 
-                                 "devno %04x", 
-                                 devno);
+	DBF_EVENT (DBF_INFO, 
+                   "devno %04x", 
+                   devno);
+
 	if ( dasd_devindex_from_devno (devno) < 0 ) {
-                DASD_DRIVER_DEBUG_EXCEPTION (1, dasd_find_device_addr, 
-                                             "no dasd: devno %04x",
-                                             devno);
+
+                DBF_EXC (DBF_ALERT, 
+                         "no dasd: devno %04x",
+                         devno);
+
 		return NULL;
 	}
         /* allocate major numbers on demand  for new devices */
@@ -3090,9 +3839,8 @@
 
 		if ((rc = dasd_register_major (NULL)) <= 0) {
 
-                        DASD_DRIVER_DEBUG_EXCEPTION (1, dasd_find_device_addr, 
-                                                     "%s",
-                                                     "out of major numbers!");
+                        DBF_EXC (DBF_ALERT, "%s",
+                                 "out of major numbers!");
                         break;
 		}
 	}
@@ -3100,86 +3848,110 @@
 }
 
 static inline int
-dasd_state_del_to_new (dasd_device_t **addr ) 
+dasd_state_del_to_new (dasd_device_t **addr, int devno) 
 {
+        int i;
         dasd_device_t* device;
-        int rc = 0;
-	if (*addr == NULL) { /* allocate device descriptor on demand for new device */
-                device = kmalloc (sizeof (dasd_device_t), GFP_ATOMIC);
-		if (device == NULL ) {
-			rc = -ENOMEM;
-                        goto out;
-		}
-		memset (device, 0, sizeof (dasd_device_t));
+        dasd_lowmem_t *lowmem;
+        int rc;
+
+
+        /* allocate device descriptor on demand for new device */
+	if (*addr != NULL) { 
+                BUG ();
+        }
+
+        device = kmalloc (sizeof (dasd_device_t), GFP_ATOMIC);
+        if (device == NULL) {
+                return -ENOMEM;
+        }
+        
+        memset (device, 0, sizeof (dasd_device_t));
+        dasd_plug_device (device);
+        device->accessible = 1;
+        INIT_LIST_HEAD (&device->lowmem_pool);
+        
+        /* allocate pages for lowmem pool */
+        for (i = 0; i < DASD_LOWMEM_PAGES; i++) {
+                
+                lowmem = (void *) get_free_page (GFP_ATOMIC|GFP_DMA);
+                if (lowmem == NULL) {
+                        break;
+                }
+
+                list_add (&lowmem->list, &device->lowmem_pool);
+        } 
+
+        if (i < DASD_LOWMEM_PAGES) {
+                /* didn't get the needed lowmem pages */
+                list_for_each_entry (lowmem, &device->lowmem_pool, list) {
+                        MESSAGE (KERN_DEBUG,
+                                 "<devno: %04x> not enough memory - "
+                                 "Free page again :%p",
+                                 devno, lowmem);
+                        free_page ((unsigned long) lowmem);
+                }
+                kfree (device);
+                rc = -ENOMEM;
+        } else {
                 *addr = device;
-                device->lowmem_ccws = (void*)get_free_page (GFP_ATOMIC|GFP_DMA);
-                if (device->lowmem_ccws == NULL) {
-                        rc = -ENOMEM;
-                        goto noccw;
-	}
-#ifdef CONFIG_ARCH_S390X
-                device->lowmem_idals =
-                    device->lowmem_idal_ptr = (void*) get_free_page (GFP_ATOMIC|GFP_DMA);
-                if (device->lowmem_idals == NULL) {
-                        rc = -ENOMEM;
-                        goto noidal;
-                }                
-#endif
-}
-        goto out;
-#ifdef CONFIG_ARCH_S390X
- noidal:
-        free_page ((long) device->lowmem_ccws);
-#endif
- noccw:
-        kfree(device);
- out:
+                rc = 0;
+        }
         return rc;
 }
 
 static inline int
-dasd_state_new_to_del (dasd_device_t **addr )
+dasd_state_new_to_del (dasd_device_t **addr, int devno)
 {
+        dasd_lowmem_t *lowmem;
+
         dasd_device_t *device = *addr;
+
+        /* free private area */
         if (device && device->private) {
                 kfree(device->private);
-                device->private = NULL;
         }
-#ifdef CONFIG_ARCH_S390X
-        free_page ((long)(device->lowmem_idals));
-#endif
-        free_page((long)(device->lowmem_ccws));
+
+        /* free lowmem_pool */
+        list_for_each_entry (lowmem, &device->lowmem_pool, list) {
+                free_page ((unsigned long) lowmem);
+        }
+
+        /* free device */
         kfree(device);
         *addr = NULL; 
         return 0;
 }
 
 static inline int
-dasd_state_new_to_known (dasd_device_t **dptr, int devno, dasd_discipline_t *disc) 
+dasd_state_new_to_known (dasd_device_t **dptr, 
+                         int devno, 
+                         dasd_discipline_t *discipline) 
 {
         int rc = 0;
 	umode_t devfs_perm  = S_IFBLK | S_IRUSR | S_IWUSR;
         struct list_head *l;
-        major_info_t *major_info = NULL;
+        major_info_t *major_info, *tmp;
         int i;
         dasd_device_t *device = *dptr;
         devfs_handle_t dir;
         char buffer[5];
         
-
-	list_for_each (l, &dasd_major_info[0].list) {
-                major_info = list_entry (l, major_info_t, list);
+        major_info = NULL;
+	list_for_each (l, &dasd_major_info) {
+                tmp = list_entry (l, major_info_t, list);
 		for (i = 0; i < DASD_PER_MAJOR; i++) {
-			if (major_info->dasd_device[i] == device) {
-				device->kdev = MKDEV (major_info->gendisk.major,
+			if (tmp->dasd_device[i] == device) {
+				device->kdev = MKDEV (tmp->gendisk.major,
                                                       i << DASD_PARTN_BITS);
+                                major_info = tmp;
 				break;
 			}
 		}
-		if (i < DASD_PER_MAJOR) /* we found one */
+		if (major_info != NULL) /* we found one */
 			break;
 	}
-        if ( major_info == NULL || major_info == &dasd_major_info[0] ) 
+        if ( major_info == NULL )
                 BUG();
 
         device->major_info = major_info;
@@ -3192,18 +3964,24 @@
         
         rc = get_dev_info_by_devno (devno, &device->devinfo);
         if ( rc ) {
+                /* returns -EUSERS if boxed !!*/
+                if (rc == -EUSERS) {
+                        device->level = DASD_STATE_BOXED;
+                }
                 goto out;
         }
 
-	DASD_DRIVER_DEBUG_EVENT (5, dasd_state_new_to_known, 
-                                 "got devinfo CU-type %04x and dev-type %04x", 
-                                 device->devinfo.sid_data.cu_type,
-                                 device->devinfo.sid_data.dev_type);
-
+	DBF_EVENT (DBF_NOTICE,
+                   "got devinfo CU-type %04x and dev-type %04x", 
+                   device->devinfo.sid_data.cu_type,
+                   device->devinfo.sid_data.dev_type);
+        
 
         if ( devno != device->devinfo.devno )
                 BUG();
-        device->discipline = dasd_find_disc (device, disc);
+
+        device->discipline = dasd_find_disc (device, 
+                                             discipline);
         if ( device->discipline == NULL ) {
                 rc = -ENODEV;
                 goto out;
@@ -3221,6 +3999,7 @@
                                               MINOR(device->kdev),
                                               devfs_perm,
                                               &dasd_device_operations,NULL);
+        dasd_do_hotplug_event (device, DASD_HOTPLUG_EVENT_ADD);
         device->level = DASD_STATE_KNOWN;
  out:
         return rc;
@@ -3233,7 +4012,7 @@
         /* don't reset to zeros because of persistent data durich detach/attach! */
         devfs_unregister(device->devfs_entry);
         devfs_unregister(device->major_info->gendisk.de_arr[MINOR(device->kdev) >> DASD_PARTN_BITS]);
-
+        dasd_do_hotplug_event (device, DASD_HOTPLUG_EVENT_REMOVE);
         return rc;
 }
 
@@ -3241,12 +4020,21 @@
 dasd_state_known_to_accept (dasd_device_t *device) 
 {
         int rc = 0;
-        device->debug_area = debug_register (device->name, 0, 2, 
-                                             3 * sizeof (long));
-        debug_register_view (device->debug_area, &debug_sprintf_view);
-        debug_register_view (device->debug_area, &debug_hex_ascii_view);
-        DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area created",
-                                 device);
+
+        /* register 'device' debug area, used for all DBF_DEV_XXX calls*/
+        device->debug_area = debug_register (device->name, 
+                                             0,     /* size of debug area */
+                                             2,     /* number of areas */
+                                             8 * sizeof (long));
+
+        debug_register_view (device->debug_area, 
+                             &debug_sprintf_view);
+
+        debug_set_level (device->debug_area, 
+                         DBF_ERR);
+
+        DBF_DEV_EVENT (DBF_EMERG, device, "%s",
+                       "debug area created");
         
         if (device->discipline->int_handler) {
                 rc = s390_request_irq_special (device->devinfo.irq,
@@ -3255,7 +4043,10 @@
                                                0, DASD_NAME,
                                                &device->dev_status);
                 if ( rc ) {
-                        printk("No request IRQ\n");
+
+                        MESSAGE (KERN_DEBUG, "%s",
+                                 "No request IRQ");
+
                         goto out;
                 }
         }
@@ -3272,10 +4063,15 @@
         if (device->discipline->int_handler) {
                 free_irq (device->devinfo.irq, &device->dev_status);
         }
-        DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area deleted",
-                                 device);
-        if ( device->debug_area != NULL )
+
+        DBF_DEV_EVENT (DBF_EMERG, device,
+                       "%p debug area deleted",
+                       device);
+
+        if (device->debug_area != NULL) {
                 debug_unregister (device->debug_area);
+                device->debug_area = NULL;  
+        }
         device->discipline = NULL;
         device->level = DASD_STATE_KNOWN;
  out:
@@ -3297,18 +4093,17 @@
                         s390irq_spin_lock_irqsave (device->devinfo.irq, 
                                                    flags);
                         rc = device->discipline->start_IO (device->init_cqr);
+                        if ( ! rc )
+                        	device->level = DASD_STATE_INIT;
                         s390irq_spin_unlock_irqrestore(device->devinfo.irq, 
                                                        flags);
-                        if ( rc )
-                                goto out;
-                        device->level = DASD_STATE_INIT;
                 } else {
                         rc = -ENOMEM;
                 }
         } else {
                 rc = dasd_state_init_to_ready ( device ); 
         }
- out:
+
         return rc;
 }
 
@@ -3318,15 +4113,8 @@
         int rc = 0;    
         if (device->discipline->do_analysis != NULL)
                 if ( device->discipline->do_analysis (device) == 0 ) 
-                        switch (device->sizes.bp_block) {
-                        case 512:
-                        case 1024:
-                        case 2048:
-                        case 4096:
-                                break;
-                        default:
-                                rc = -EMEDIUMTYPE;
-                        }
+                        rc = dasd_check_bp_block (device);
+        
         if ( device->init_cqr ) {
                 /* This pointer is no longer needed, BUT dont't free the       */ 
                 /* memory, because this is done in bh for finished request!!!! */
@@ -3362,8 +4150,10 @@
 dasd_state_ready_to_online (dasd_device_t *device ) 
 {
         int rc = 0;
-        dasd_unplug_device (device);
-        device->level = DASD_STATE_ONLINE;
+        if (!(rc = dasd_check_bp_block (device))) {
+                dasd_unplug_device (device);
+                device->level = DASD_STATE_ONLINE;
+        }
         return rc;
 }
 
@@ -3383,6 +4173,7 @@
         int i;
         int major = MAJOR(device->kdev);
         int minor = MINOR(device->kdev);
+        request_queue_t *request_queue;
 
         for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
                 if (i == 0)
@@ -3399,11 +4190,16 @@
 		device->major_info->gendisk.part[minor+i].start_sect = 0;
 		device->major_info->gendisk.part[minor+i].nr_sects = 0;
         }
-        device->request_queue = kmalloc(sizeof(request_queue_t),GFP_KERNEL);
-        device->request_queue->queuedata = device;
-        blk_init_queue (device->request_queue, do_dasd_request);
-        blk_queue_headactive (device->request_queue, 0);
-        elevator_init (&(device->request_queue->elevator),ELEVATOR_NOOP);
+
+        request_queue = kmalloc(sizeof(request_queue_t),GFP_KERNEL);
+        if (request_queue) {
+                request_queue->queuedata = device;
+                blk_init_queue (request_queue, do_dasd_request);
+                blk_queue_headactive (request_queue, 1);
+                elevator_init (&(request_queue->elevator),ELEVATOR_NOOP);
+        }
+        device->request_queue = request_queue;
+        
         return rc;
 }
 
@@ -3424,6 +4220,19 @@
         int i;
         int major = MAJOR(device->kdev);
         int minor = MINOR(device->kdev);
+	request_queue_t *q   = device->request_queue;
+	struct request  *req;
+	long             flags;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	while (q                           &&
+               !list_empty(&q->queue_head) &&
+               (req = dasd_next_request(q)) != NULL) {
+
+		dasd_end_request(req, 0);
+		dasd_dequeue_request(q, req);
+	}
+	spin_unlock_irqrestore(&io_request_lock, flags);
 
         for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
                 destroy_buffers(MKDEV(major,minor+i));
@@ -3453,6 +4262,7 @@
 		       1 << DASD_PARTN_BITS,
 		       &dasd_device_operations,
 		       (device->sizes.blocks << device->sizes.s2b_shift));
+        dasd_do_hotplug_event (device, DASD_HOTPLUG_EVENT_PARTCHK);
 }
 
 static inline void
@@ -3467,14 +4277,7 @@
         }
         devfs_register_partitions(&device->major_info->gendisk,
                                   MINOR(device->kdev),1);
-}
-
-static inline void
-dasd_resetup_partitions ( dasd_device_t * device ) 
-{
-    BUG();
-    dasd_destroy_partitions ( device ) ;
-    dasd_setup_partitions ( device ) ;
+        dasd_do_hotplug_event (device, DASD_HOTPLUG_EVENT_PARTREMOVE);
 }
 
 /*
@@ -3505,11 +4308,11 @@
                 from_state = device->level;
         }
 
-        DASD_DRIVER_DEBUG_EVENT (3, dasd_set_device_level,
-                                 "devno %04x; from %i to %i",
-                                 devno,
-                                 from_state,
-                                 to_state);
+        DBF_EVENT (DBF_INFO,
+                   "devno %04x; from %i to %i",
+                   devno,
+                   from_state,
+                   to_state);
 
         if ( from_state == to_state )
                 goto out;
@@ -3520,20 +4323,30 @@
         /* First check for bringup */
         if ( from_state <= DASD_STATE_DEL &&
              to_state >= DASD_STATE_NEW ) { 
-                rc = dasd_state_del_to_new(device_addr);
+                rc = dasd_state_del_to_new(device_addr, devno);
                 if ( rc ) {
                         goto bringup_fail;
                 }
                 device = *device_addr;
         }
-        if ( from_state <= DASD_STATE_NEW &&
+
+        /* reprobe boxed devices */
+        if (device->level == DASD_STATE_BOXED) {
+                rc = s390_trigger_resense (device->devinfo.irq);
+                if ( rc ) {
+                        goto bringup_fail;
+                }
+        }
+
+        if ( device->level <= DASD_STATE_BOXED &&
              to_state >= DASD_STATE_KNOWN ) { 
                 rc = dasd_state_new_to_known( device_addr, devno, discipline );
                 if ( rc ) {
                         goto bringup_fail;
                 }
         }
-        if ( from_state <= DASD_STATE_KNOWN &&
+
+        if ( device->level <= DASD_STATE_KNOWN &&
              to_state >= DASD_STATE_ACCEPT ) { 
                 rc = dasd_state_known_to_accept(device);
                 if ( rc ) {
@@ -3543,19 +4356,21 @@
         if ( dasd_probeonly ) {
             goto out;
         }
-        if ( from_state <= DASD_STATE_ACCEPT &&
+
+        if ( device->level <= DASD_STATE_ACCEPT &&
              to_state >= DASD_STATE_INIT ) { 
                 rc = dasd_state_accept_to_init(device);
                 if ( rc ) {
                         goto bringup_fail;
                 }
         }
-        if ( from_state <= DASD_STATE_INIT &&
+        if ( device->level <= DASD_STATE_INIT &&
              to_state >= DASD_STATE_READY ) { 
                 rc = -EAGAIN;
                 goto out;
         }
-        if ( from_state <= DASD_STATE_READY &&
+
+        if ( device->level <= DASD_STATE_READY &&
              to_state >= DASD_STATE_ONLINE ) { 
                 rc = dasd_state_ready_to_online(device);
                 if ( rc ) {
@@ -3564,50 +4379,57 @@
         }
         goto out;
  bringup_fail:   /* revert changes */
-#if 0
-        printk (KERN_DEBUG PRINTK_HEADER
-                "failed to set device from state %d to %d at "
-                "level %d rc %d. Reverting...\n",
-                from_state,
-                to_state,
-                device->level,
-                rc);
-#endif
-        to_state = from_state;
-        from_state = device->level;
+
+        DBF_DEV_EVENT (DBF_ERR, device,
+                       "failed to set device from state %d to %d at "
+                       "level %d rc %d. Reverting...",
+                       from_state,
+                       to_state,
+                       device->level,
+                       rc);
+
+        if (device->level <= DASD_STATE_NEW) {
+                /* Revert - device can not be accessed */
+                to_state = from_state;
+                from_state = device->level;
+        }
         
         /* now do a shutdown */
  shutdown: 
-        if ( from_state >= DASD_STATE_ONLINE &&
+        if ( device->level >= DASD_STATE_ONLINE &&
              to_state <= DASD_STATE_READY ) 
                 if (dasd_state_online_to_ready(device))
                         BUG();
 
-        if ( from_state >= DASD_STATE_READY &&
+        if ( device->level >= DASD_STATE_READY &&
              to_state <= DASD_STATE_ACCEPT ) 
                 if ( dasd_state_ready_to_accept(device))
                         BUG();
 
-        if ( from_state >= DASD_STATE_ACCEPT &&
+        if ( device->level >= DASD_STATE_ACCEPT &&
              to_state <= DASD_STATE_KNOWN ) 
                 if ( dasd_state_accept_to_known(device))
                         BUG();
 
-        if ( from_state >= DASD_STATE_KNOWN &&
+        if ( device->level >= DASD_STATE_KNOWN &&
              to_state <= DASD_STATE_NEW ) 
                 if ( dasd_state_known_to_new(device))
                         BUG();
 
-        if ( from_state >= DASD_STATE_NEW &&
+        if ( device->level >= DASD_STATE_NEW &&
              to_state <= DASD_STATE_DEL) 
-                if (dasd_state_new_to_del(device_addr))
+                if (dasd_state_new_to_del(device_addr, devno))
                         BUG();
         goto out;
  out:
         return rc;
 }
 
-/* SECTION: Procfs stuff */
+/********************************************************************************
+ * SECTION: Procfs stuff 
+ ********************************************************************************/
+#ifdef CONFIG_PROC_FS
+
 typedef struct {
 	char *data;
 	int len;
@@ -3640,29 +4462,53 @@
         int index = 0;
 
         MOD_INC_USE_COUNT;
-        spin_lock_irqsave(&discipline_lock,flags);
+
+        spin_lock_irqsave(&discipline_lock,
+                          flags);
+
 	info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
+
 	if (info == NULL) {
-                printk (KERN_WARNING "No memory available for data\n");
+
+                MESSAGE (KERN_WARNING, "%s",
+                         "No memory available for data (tempinfo)");
+
+                spin_unlock_irqrestore(&discipline_lock,
+                                       flags);
+
                 MOD_DEC_USE_COUNT;
+
                 return -ENOMEM;
+
 	} else {
 		file->private_data = (void *) info;
 	}
-	list_for_each (l, &dasd_major_info[0].list) {
+	list_for_each (l, &dasd_major_info) {
                 size += 128 * 1 << (MINORBITS - DASD_PARTN_BITS);
 	}
 	info->data = (char *) vmalloc (size);	
-	DASD_DRIVER_DEBUG_EVENT (1, dasd_devices_open, "area: %p, size 0x%x",
-				 info->data, 
-                                 size);
+
 	if (size && info->data == NULL) {
-		printk (KERN_WARNING "No memory available for data\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+                         "No memory available for data (info->data)");
+
 		vfree (info);
+
+                spin_unlock_irqrestore(&discipline_lock,
+                                       flags);
+
                 MOD_DEC_USE_COUNT;
+
 		return -ENOMEM;
 	}
-	list_for_each (l, &dasd_major_info[0].list) {
+
+	DBF_EVENT (DBF_NOTICE,
+                   "procfs-area: %p, size 0x%x allocated",
+                   info->data, 
+                   size);
+
+	list_for_each (l, &dasd_major_info) {
 		temp = list_entry (l, major_info_t, list);
 		for (i = 0; i < 1 << (MINORBITS - DASD_PARTN_BITS); i++) {
 			dasd_device_t *device;
@@ -3673,8 +4519,8 @@
                                 continue;
 
                         features = dasd_features_from_devno(devno);
-                        if (features < DASD_DEFAULT_FEATURES)
-                                features = DASD_DEFAULT_FEATURES;
+                        if (features < DASD_FEATURE_DEFAULT)
+                                features = DASD_FEATURE_DEFAULT;
 
                         device = temp->dasd_device[i];
 			if (device) {
@@ -3702,45 +4548,45 @@
 					    sprintf (info->data + len,
 						     "detected");
 					break;
+				case DASD_STATE_BOXED:
+					len +=
+					    sprintf (info->data + len,
+						     "boxed");
+					break;
 				case DASD_STATE_ACCEPT:
-                                        len += sprintf (info->data + len,"accepted");
+                                        len += sprintf (info->data + len,
+                                                        "accepted");
 					break;
 				case DASD_STATE_INIT:
-					len +=
-					    sprintf (info->data + len,
-						     "busy   ");
+					len += sprintf (info->data + len,
+                                                        "busy   ");
 					break;
 				case DASD_STATE_READY:
+					len += sprintf (info->data + len,
+							"ready  ");
+					break;
 				case DASD_STATE_ONLINE:
-                                    if ( atomic_read(&device->plugged) )
-                                        len +=
-                                            sprintf (info->data + len,
-                                                     "fenced ");
-                                    else
-                                        len +=
-                                            sprintf (info->data + len,
-                                                     "active ");
-                                    if ( device->sizes.bp_block == 512 ||
-                                         device->sizes.bp_block == 1024 ||
-                                         device->sizes.bp_block == 2048 ||
-                                         device->sizes.bp_block == 4096 )
-					len +=
-					    sprintf (info->data + len,
-						     "at blocksize: %d, %ld blocks, %ld MB",
-						     device->sizes.bp_block,
-						     device->sizes.blocks,
-						     ((device->
-						       sizes.bp_block >> 9) *
-						      device->sizes.
-						      blocks) >> 11);
-                                    else
-                                        len +=
-                                            sprintf (info->data + len,
-                                                     "n/f    ");
+                                        len += sprintf (info->data + len,
+                                                        "active ");
+
+                                        if (dasd_check_bp_block (device))
+                                                len +=
+                                                    sprintf (info->data + len,
+                                                             "n/f    ");
+                                        else
+                                                len +=
+                                                    sprintf (info->data + len,
+                                                             "at blocksize: %d, %ld blocks, %ld MB",
+                                                             device->sizes.bp_block,
+                                                             device->sizes.blocks,
+                                                             ((device->
+                                                               sizes.bp_block >> 9) *
+                                                              device->sizes.
+                                                              blocks) >> 11);
 					break;
 				default:
 					len +=
-					    sprintf (info->data + len,
+                                            sprintf (info->data + len,
 						     "no stat");
 					break;
 				}
@@ -3769,7 +4615,9 @@
                 index += 1 << (MINORBITS - DASD_PARTN_BITS);
 	}
 	info->len = len;
-        spin_unlock_irqrestore(&discipline_lock,flags);
+
+        spin_unlock_irqrestore(&discipline_lock,
+                               flags);
 	return rc;
 }
 
@@ -3793,22 +4641,250 @@
 	}
 }
 
+/* 
+ * scan for device range in given string (e.g. 0x0150-0x0155).
+ * devnos are always hex and leading 0x are ignored.
+ */
+static char *
+dasd_parse_range (char *buffer, dasd_range_t *range)
+{
+        char *str;
+
+        /* remove optional 'device ' and 'range=' and search for nexet digit */
+        for (str = buffer + 4; isspace(*str); str++);
+
+	if (strncmp (str, "device ", 7) == 0) 
+		for (str = str + 7; isspace(*str); str++);
+        
+	if (strncmp (str, "range=", 6) == 0) 
+                for (str = str + 6; isspace(*str); str++);
+        
+        range->to = range->from = dasd_strtoul (str, 
+                                                &str, 
+                                                &(range->features));
+        
+        if (*str == '-') {
+		str++;
+		range->to = dasd_strtoul (str, 
+                                          &str, 
+                                          &(range->features));
+	}
+        
+        /* remove blanks after device range */
+	for (; isspace(*str); str++);
+
+        if (range->from < 0 || range->to < 0) {
+                MESSAGE (KERN_WARNING,
+                         "/proc/dasd/devices: range parse error in '%s'", 
+                         buffer);
+                return ERR_PTR (-EINVAL);
+        }
+
+        return str;
+
+} /* end dasd_parse_range */
+
+/* 
+ * Enable / Disable the given devices  
+ */
+static void
+dasd_proc_set (char *buffer)
+{
+	dasd_range_t range;
+        char *str;
+
+        str = dasd_parse_range (buffer, 
+                                &range);
+        
+        /* Negative numbers in str/from/to indicate errors */
+        if (IS_ERR (str) || (range.from < 0) || (range.to < 0)
+            || (range.from > 65535) || (range.to > 65535)) 
+                return;
+
+        if (strncmp (str, "on", 2) == 0) {
+                dasd_enable_ranges (&range, NULL, 0);
+
+        } else if (strncmp (str, "off", 3) == 0) {
+                dasd_disable_ranges (&range, NULL, 0, 1);
+                
+        } else {
+                MESSAGE (KERN_WARNING,
+                         "/proc/dasd/devices: "
+                         "only 'on' and 'off' are alowed in 'set' "
+                         "command ('%s'/'%s')",
+                         buffer,
+                         str);
+        }
+
+        return;
+
+} /* end dasd_proc_set */
+
+/* 
+ * Add the given devices
+ */
+static void
+dasd_proc_add (char *buffer)
+{
+	dasd_range_t range;
+        char *str;
+        
+        str = dasd_parse_range (buffer, 
+                                &range);
+        
+        /* Negative numbers in str/from/to indicate errors */
+        if (IS_ERR (str) || (range.from < 0) || (range.to < 0)
+            || (range.from > 65535) || (range.to > 65535))
+                return;
+
+        dasd_add_range (range.from, range.to, range.features);
+        dasd_enable_ranges (&range, NULL, 0);
+
+        return;
+
+} /* end dasd_proc_add */
+
+/* 
+ * Break the lock of a given 'boxed' dasd.
+ * If the dasd in not in status 'boxed' just return.  
+ */
+static int
+dasd_break_boxed (dasd_range_t  *range,
+                  dasd_device_t *device)
+{
+        int rc = 0;
+        dasd_discipline_t *discipline;
+        struct list_head  *lh = dasd_disc_head.next;
+                
+        /* check devixe status */
+        if (device->level != DASD_STATE_BOXED) {
+                MESSAGE (KERN_WARNING,
+                         "/proc/dasd/devices: the given device (%04X) "
+                         "is not 'boxed')",
+                         device->devinfo.devno);
+                rc = -EINVAL;
+                goto out; 
+        }
+
+        /* force eckd discipline */
+        do {
+                discipline = list_entry(lh,
+                                        dasd_discipline_t,
+                                        list);
+                
+                if (strncmp (discipline->name, range->discipline, 4) == 0)
+                        break;  /* discipline found */
+                
+                lh = lh->next;    /* check next discipline in list */
+                if (lh == &dasd_disc_head) {
+                        discipline = NULL;
+                        break;
+                }
+        } while ( 1 );
+        device->discipline = discipline;
+
+        if (device->discipline == NULL) {
+                MESSAGE (KERN_WARNING, "%s",
+                         "/proc/dasd/devices: discipline not found "
+                         "in discipline list");
+                rc = -EINVAL;
+                goto out;
+        }
+
+        /* register the int handler to enable IO */
+        rc = s390_request_irq_special (device->devinfo.irq,
+                                       device->discipline->int_handler,
+                                       dasd_not_oper_handler,
+                                       0, 
+                                       DASD_NAME,
+                                       &device->dev_status);
+        if ( rc ) 
+                goto out;
+
+        rc = dasd_steal_lock (device);
+
+        /* unregister the int handler to enable re-sensing */
+        free_irq (device->devinfo.irq, 
+                  &device->dev_status);
+        
+        device->discipline = NULL;
+        device->level      = DASD_STATE_NEW;
+
+ out:
+        return rc;
+
+} /* end dasd_break_boxed */
+
+/* 
+ * Handle the procfs call 'brk <devno> <discipline>.
+ */
+static void
+dasd_proc_brk (char *buffer)
+{
+	char *str;
+	dasd_range_t range;
+        dasd_device_t *device;
+        int rc = 0;
+
+        str = dasd_parse_range (buffer,
+                                 &range);
+
+        if (IS_ERR (str))
+                return;
+
+        if (range.from != range.to) {
+                MESSAGE (KERN_WARNING, "%s",
+                         "/proc/dasd/devices: 'brk <devno> <discipline> "
+                         "is only allowed for a single device (no ranges)");
+                return;
+        }
+
+        /* check for discipline = 'eckd' */
+        if (strncmp(str, "eckd", 4) != 0) {
+                MESSAGE (KERN_WARNING,
+                         "/proc/dasd/devices: 'brk <devno> <discipline> "
+                         "is only allowed for 'eckd' (%s)",
+                         str);
+                return;
+        }
+        
+        memcpy (range.discipline, "ECKD", 4);
+
+	device = *(dasd_device_from_devno (range.from));
+        if (device == NULL) {
+                MESSAGE (KERN_WARNING,
+                         "/proc/dasd/devices: no device found for devno (%04X)",
+                         range.from);
+                return;
+        }
+        
+        rc = dasd_break_boxed (&range, 
+                               device);
+        if (rc == 0) {
+                /* trigger CIO to resense the device */
+                s390_trigger_resense (device->devinfo.irq);
+                
+                // get the device online now
+                dasd_enable_ranges (&range, 
+                                    NULL, 
+                                    0);
+        }
+        
+} /* end dasd_proc_brk */
+
 static ssize_t
 dasd_devices_write (struct file *file, const char *user_buf,
 		    size_t user_len, loff_t * offset)
 {
 	char *buffer;
-	int off = 0;
-	char *temp;
-	dasd_range_t range;
-        int features;
 
 	if (user_len > PAGE_SIZE)
 		return -EINVAL;
-		
+
 	buffer = vmalloc (user_len+1);
 	if (buffer == NULL)
 		return -ENOMEM;
+
 	if (copy_from_user (buffer, user_buf, user_len)) {
 		vfree (buffer);
 		return -EFAULT;
@@ -3821,60 +4897,29 @@
                 buffer[user_len] = '\0';
         }
 
-	printk (KERN_INFO PRINTK_HEADER "/proc/dasd/devices: '%s'\n", buffer);
-	if (strncmp (buffer, "set ", 4) && strncmp (buffer, "add ", 4)) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"/proc/dasd/devices: only 'set' and 'add' are supported verbs\n");
-		return -EINVAL;
-	}
-	off += 4;
-	while (buffer[off] && !isalnum (buffer[off]))
-		off++;
-	if (!strncmp (buffer + off, "device", strlen ("device"))) {
-		off += strlen ("device");
-		while (buffer[off] && !isalnum (buffer[off]))
-			off++;
-	}
-	if (!strncmp (buffer + off, "range=", strlen ("range="))) {
-		off += strlen ("range=");
-		while (buffer[off] && !isalnum (buffer[off]))
-			off++;
-	}
-	
-	temp = buffer + off;
-	range.from = dasd_strtoul (temp, &temp, &features);
-	range.to = range.from;
-
-	if (*temp == '-') {
-		temp++;
-		range.to = dasd_strtoul (temp, &temp, &features);
-	}
+	MESSAGE (KERN_INFO,
+                 "/proc/dasd/devices: '%s'", 
+                 buffer);
+
+	if (strncmp (buffer, "set ", 4) == 0) {
+                /* handle 'set <devno> on/off' */
+                dasd_proc_set (buffer);
+
+        } else if (strncmp (buffer, "add ", 4) == 0) {
+                /* handle 'add <devno>' */
+                dasd_proc_add (buffer);
+
+        } else if (strncmp (buffer, "brk ", 4) == 0) {
+                /* handle 'brk <devno> <discipline>' */
+                dasd_proc_brk (buffer);
 
-        if (range.from == -EINVAL ||
-            range.to   == -EINVAL   ) {
-                
-                printk (KERN_WARNING PRINTK_HEADER
-                        "/proc/dasd/devices: range parse error in '%s'\n", 
-                        buffer);
         } else {
-                off = (long) temp - (long) buffer;
-                if (!strncmp (buffer, "add", strlen ("add"))) {
-                        dasd_add_range (range.from, range.to, features);
-                        dasd_enable_ranges (&range, NULL, 0);
-                } else { 
-                        while (buffer[off] && !isalnum (buffer[off]))
-                                off++;
-                        if (!strncmp (buffer + off, "on", strlen ("on"))) {
-                                dasd_enable_ranges (&range, NULL, 0);
-                        } else if (!strncmp (buffer + off, "off", strlen ("off"))) {
-                                dasd_disable_ranges (&range, NULL, 0, 1);
-                        } else {
-                                printk (KERN_WARNING PRINTK_HEADER
-                                        "/proc/dasd/devices: parse error in '%s'\n",
-                                        buffer);
-                        }
-                }
-        }
+		MESSAGE (KERN_WARNING, "%s",
+                         "/proc/dasd/devices: only 'set' ,'add' and "
+                         "'brk' are supported verbs");
+		vfree (buffer);
+		return -EINVAL;
+	}
 
 	vfree (buffer);
 	return user_len;
@@ -3895,9 +4940,9 @@
 }
 
 static struct file_operations dasd_devices_file_ops = {
-	read:dasd_generic_read,	/* read */
+	read:dasd_generic_read,	        /* read */
 	write:dasd_devices_write,	/* write */
-	open:dasd_devices_open,	/* open */
+	open:dasd_devices_open,	        /* open */
 	release:dasd_devices_close,	/* close */
 };
 
@@ -3914,22 +4959,41 @@
 
         MOD_INC_USE_COUNT;
 	info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
+
 	if (info == NULL) {
-		printk (KERN_WARNING "No memory available for data\n");
+ 
+		MESSAGE (KERN_WARNING, "%s",
+                         "No memory available for data (tempinfo)");
+
                 MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	} else {
 		file->private_data = (void *) info;
 	}
-	info->data = (char *) vmalloc (PAGE_SIZE);	/* FIXME! determine space needed in a better way */
+        /* FIXME! determine space needed in a better way */
+	info->data = (char *) vmalloc (PAGE_SIZE);	
+
 	if (info->data == NULL) {
-		printk (KERN_WARNING "No memory available for data\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+                         "No memory available for data (info->data)");
+
 		vfree (info);
 		file->private_data = NULL;
                 MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
         
+        /* check for active profiling */
+        if (dasd_profile_level == DASD_PROFILE_OFF) {
+
+                info->len = sprintf (info->data, 
+                                     "Statistics are off - they might be "
+                                     "switched on using 'echo set on > "
+                                     "/proc/dasd/statistics'\n");
+                return rc;
+        } 
+
         /* prevent couter 'ouverflow' on output */
 	for (shift = 0, help = dasd_global_profile.dasd_io_reqs;
 	     help > 9999999; help = help >> 1, shift++) ;
@@ -3958,7 +5022,15 @@
 	}
 	len += sprintf (info->data + len, "\n");
 
-	len += sprintf (info->data + len, "Histogram of I/O times (microseconds)\n");
+	for (; i < 32; i++) {
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_secs[i] >> shift);
+	}
+	len += sprintf (info->data + len, "\n");
+
+	len += sprintf (info->data + len, 
+                        "Histogram of I/O times (microseconds)\n");
+
 	for (i = 0; i < 16; i++) {
 		len += sprintf (info->data + len, "%7d ",
                                 dasd_global_profile.dasd_io_times[i] >> shift);
@@ -4008,7 +5080,9 @@
 	len += sprintf (info->data + len, "\n");
 
 	len += sprintf (info->data + len,
-                        "Histogram of I/O time between ssch and irq per sector\n");
+                        "Histogram of I/O time between ssch and irq per "
+                        "sector\n");
+
 	for (i = 0; i < 16; i++) {
 		len += sprintf (info->data + len, "%7d ",
                                 dasd_global_profile.dasd_io_time2ps[i] >> shift);
@@ -4064,23 +5138,89 @@
 
 	if (buffer == NULL)
 		return -ENOMEM;
+
 	if (copy_from_user (buffer, user_buf, user_len)) {
 		vfree (buffer);
 		return -EFAULT;
 	}
+
 	buffer[user_len] = 0;
-	printk (KERN_INFO PRINTK_HEADER "/proc/dasd/statictics: '%s'\n",
-		buffer);
-	if (strncmp (buffer, "reset", 4)) {
-		memset (&dasd_global_profile, 0, sizeof (dasd_profile_info_t));
+        
+	MESSAGE (KERN_INFO,
+                 "/proc/dasd/statictics: '%s'",
+                 buffer);
+
+#ifdef DASD_PROFILE
+         /* check for valid verbs */
+	if (strncmp (buffer, "reset", 5) && 
+            strncmp (buffer, "set ",  4)   ) {
+
+		MESSAGE (KERN_WARNING, "%s",
+                         "/proc/dasd/statistics: only 'set' and "
+                         "'reset' are supported verbs");
+
+        	return -EINVAL;
 	}
+
+	if (!strncmp (buffer, "reset", 5)) {
+                
+                /* reset the statistics */
+		memset (&dasd_global_profile, 
+                        0, 
+                        sizeof (dasd_profile_info_t));
+                
+                MESSAGE (KERN_INFO, "%s",
+                         "Statictics reset");
+
+	} else {
+
+                /* 'set xxx' was given */
+                int offset = 4;
+
+                while (buffer[offset] && !isalnum (buffer[offset]))
+                        offset++;
+
+                if (!strncmp (buffer + offset, "on", 2)) {
+                        
+                        /* switch on statistics profiling */
+                        dasd_profile_level = DASD_PROFILE_ON;
+                        
+                        MESSAGE (KERN_INFO, "%s",
+                                 "Statictics switched on");
+                        
+                } else if (!strncmp (buffer + offset, "off", 3)) {
+                        
+                        /* switch off and reset statistics profiling */
+                        memset (&dasd_global_profile, 
+                                0, 
+                                sizeof (dasd_profile_info_t));
+                        
+                        dasd_profile_level = DASD_PROFILE_OFF;
+                        
+                        MESSAGE (KERN_INFO, "%s",
+                                 "Statictics switched off");
+
+                } else {
+
+                        MESSAGE (KERN_WARNING, "%s",
+                                 "/proc/dasd/statistics: only 'set on' and "
+                                 "'set off' are supported verbs");
+                } 
+        } 
+#else
+        MESSAGE (KERN_WARNING, "%s",
+                 "/proc/dasd/statistics: is not activated in this "
+                 "kernel");
+        
+
+#endif /* DASD_PROFILE */
 	return user_len;
 }
 
 static struct file_operations dasd_statistics_file_ops = {
-	read:dasd_generic_read,	/* read */
-	open:dasd_statistics_open,	/* open */
+	read:dasd_generic_read,	        /* read */
 	write:dasd_statistics_write,	/* write */
+	open:dasd_statistics_open,	/* open */
 	release:dasd_devices_close,	/* close */
 };
 
@@ -4113,6 +5253,11 @@
 	remove_proc_entry ("dasd", &proc_root);
 }
 
+#endif /* CONFIG_PROC_FS */
+
+/********************************************************************************
+ * SECTION: Initializing the driver 
+ ********************************************************************************/
 int
 dasd_request_module ( void *name ) {
 	int rc = -ERESTARTSYS;
@@ -4124,16 +5269,17 @@
 	} 
 	while ( (rc=request_module(name)) != 0 ) {
         	DECLARE_WAIT_QUEUE_HEAD(wait);
-		printk ( KERN_INFO "request_module returned %d for %s\n",
+
+		MESSAGE (KERN_INFO,
+                         "request_module returned %d for %s",
                          rc,
                          (char*)name);
+
         	sleep_on_timeout(&wait,5* HZ); /* wait in steps of 5 seconds */
     	}
     	return rc;
 }
 
-
-/* SECTION: Initializing the driver */
 int __init
 dasd_init (void)
 {
@@ -4142,40 +5288,56 @@
 	major_info_t *major_info = NULL;
 	struct list_head *l;
 
-	printk (KERN_INFO PRINTK_HEADER "initializing...\n");
-	dasd_debug_area = debug_register (DASD_NAME, 0, 2, 5 * sizeof (long));
-	debug_register_view (dasd_debug_area, &debug_sprintf_view);
-	debug_register_view (dasd_debug_area, &debug_hex_ascii_view);
+	MESSAGE (KERN_INFO, "%s",
+                 "initializing...");
 
 	init_waitqueue_head (&dasd_init_waitq);
 
+        /* register 'common' DASD debug area, used faor all DBF_XXX calls*/
+	dasd_debug_area = debug_register (DASD_NAME, 
+                                          0,     /* size of debug area */
+                                          2,     /* number of areas */
+                                          8 * sizeof (long));
+
+	debug_register_view (dasd_debug_area, 
+                             &debug_sprintf_view);
+
 	if (dasd_debug_area == NULL) {
 		goto failed;
 	}
-	DASD_DRIVER_DEBUG_EVENT (0, dasd_init, "%s", 
-                                 "ENTRY");
-	dasd_devfs_handle = devfs_mk_dir (NULL, DASD_NAME, NULL);
+
+        debug_set_level (dasd_debug_area, 
+                         DBF_ERR);
+
+        DBF_EVENT (DBF_EMERG, "%s", 
+                   "debug area created");
+
+	dasd_devfs_handle = devfs_mk_dir (NULL, 
+                                          DASD_NAME, 
+                                          NULL);
+
 	if (dasd_devfs_handle < 0) {
-		DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s", 
-                                         "no devfs");
+
+		DBF_EVENT (DBF_ALERT, "%s", 
+                           "no devfs");
 		goto failed;
 	}
-	list_for_each (l, &dasd_major_info[0].list) {
+
+        list_add_tail(&dasd_major_static.list, &dasd_major_info);
+	list_for_each (l, &dasd_major_info) {
 		major_info = list_entry (l, major_info_t, list);
 		if ((rc = dasd_register_major (major_info)) > 0) {
-			DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
-						 "major %d: success",
-						 major_info->gendisk.major);
-			printk (KERN_INFO PRINTK_HEADER
-				"Registered successfully to major no %u\n",
-				major_info->gendisk.major);
+
+			MESSAGE (KERN_INFO,
+                                 "Registered successfully to major no %u",
+                                 major_info->gendisk.major);
 		} else {
-			DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
-						 "major %d: failed",
-						 major_info->gendisk.major);
-			printk (KERN_WARNING PRINTK_HEADER
-				"Couldn't register successfully to major no %d\n",
-				major_info->gendisk.major);
+
+			MESSAGE (KERN_WARNING,
+                                 "Couldn't register successfully to "
+                                 "major no %d",
+                                 major_info->gendisk.major);
+
 			/* revert registration of major infos */
 			goto failed;
 		}
@@ -4185,18 +5347,24 @@
 #endif				/* ! MODULE */
 	rc = dasd_parse (dasd);
 	if (rc) {
-		DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s",
-                                         "invalid range found");
+
+		DBF_EVENT (DBF_ALERT, "%s",
+                           "invalid range found");
 		goto failed;
 	}
 
+#ifdef CONFIG_PROC_FS
 	rc = dasd_proc_init ();
 	if (rc) {
-		DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s", "no proc-FS");
+                
+		DBF_EVENT (DBF_ALERT, "%s", 
+                           "no proc-FS");
 		goto failed;
 	}
+#endif /* CONFIG_PROC_FS */
+
 	genhd_dasd_name = dasd_device_name;
-	genhd_dasd_ioctl = dasd_ioctl;
+        genhd_dasd_ioctl = dasd_ioctl;
 
 	if (dasd_autodetect) {	/* update device range to all devices */
 		for (irq = get_irq_first (); irq != -ENODEV;
@@ -4204,10 +5372,14 @@
 			int devno = get_devno_by_irq (irq);
 			int index = dasd_devindex_from_devno (devno);
 			if (index == -ENODEV) {	/* not included in ranges */
-				DASD_DRIVER_DEBUG_EVENT (2, dasd_init,
-							 "add %04x to range",
-							 devno);
-				dasd_add_range (devno, devno, DASD_DEFAULT_FEATURES);
+
+				DBF_EVENT (DBF_CRIT,
+                                           "add %04x to range",
+                                           devno);
+
+				dasd_add_range (devno, 
+                                                devno, 
+                                                DASD_FEATURE_DEFAULT);
 			}
 		}
 	}
@@ -4216,15 +5388,15 @@
 #ifdef CONFIG_DASD_DIAG
 		rc = dasd_diag_init ();
 		if (rc == 0) {
-			DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
-						 "DIAG discipline %s",
-						 "success");
-			printk (KERN_INFO PRINTK_HEADER
-				"Registered DIAG discipline successfully\n");
+
+			MESSAGE (KERN_INFO, "%s",
+                                 "Registered DIAG discipline successfully");
+
 		} else {
-			DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
-						 "DIAG discipline %s",
-						 "failed");
+
+			DBF_EVENT (DBF_ALERT, "%s",
+                                   "Register DIAG discipline failed");
+
 			goto failed;
 		}
 #endif /* CONFIG_DASD_DIAG */
@@ -4235,13 +5407,14 @@
 #ifdef CONFIG_DASD_ECKD
 	rc = dasd_eckd_init ();
 	if (rc == 0) {
-		DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
-					 "ECKD discipline %s", "success");
-		printk (KERN_INFO PRINTK_HEADER
-			"Registered ECKD discipline successfully\n");
+
+		MESSAGE (KERN_INFO, "%s",
+                         "Registered ECKD discipline successfully");
 	} else {
-		DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
-					 "ECKD discipline %s", "failed");
+
+		DBF_EVENT (DBF_ALERT, "%s",
+                           "Register ECKD discipline failed");
+
 		goto failed;
 	}
 #endif /* CONFIG_DASD_ECKD */
@@ -4251,14 +5424,14 @@
 #ifdef CONFIG_DASD_FBA
 	rc = dasd_fba_init ();
 	if (rc == 0) {
-		DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
-					 "FBA discipline %s", "success");
-
-		printk (KERN_INFO PRINTK_HEADER
-			"Registered FBA discipline successfully\n");
+                
+		MESSAGE (KERN_INFO, "%s",
+			"Registered FBA discipline successfully");
 	} else {
-		DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
-					 "FBA discipline %s", "failed");
+                
+		DBF_EVENT (DBF_ALERT, "%s",
+                           "Register FBA discipline failed");
+
 		goto failed;
 	}
 #endif /* CONFIG_DASD_FBA */
@@ -4276,12 +5449,16 @@
 	rc = 0;
 	goto out;
       failed:
-	printk (KERN_INFO PRINTK_HEADER
-		"initialization not performed due to errors\n");
+
+	MESSAGE (KERN_INFO, "%s",
+                 "initialization not performed due to errors");
+
 	cleanup_dasd ();
       out:
-	DASD_DRIVER_DEBUG_EVENT (0, dasd_init, "%s", "LEAVE");
-	printk (KERN_INFO PRINTK_HEADER "initialization finished\n");
+        
+	MESSAGE (KERN_INFO, "%s",
+                 "initialization finished");
+
 	return rc;
 }
 
@@ -4293,57 +5470,60 @@
 	struct list_head *l,*n;
 	dasd_range_t *range;
 
-	printk (KERN_INFO PRINTK_HEADER "shutting down\n");
-        DASD_DRIVER_DEBUG_EVENT(0,"cleanup_dasd","%s","ENTRY");
-	dasd_disable_ranges (&dasd_range_head, NULL, 1, 1);
-        if (MACHINE_IS_VM) {
+	MESSAGE (KERN_INFO, "%s",
+                "shutting down");
+
+	dasd_disable_ranges (&dasd_range_head, 
+                             NULL, 1, 1);
+
 #ifdef CONFIG_DASD_DIAG
+        if (MACHINE_IS_VM) {
                 dasd_diag_cleanup ();
-                DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd",
-                                         "DIAG discipline %s", "success");
-                printk (KERN_INFO PRINTK_HEADER
-			"De-Registered DIAG discipline successfully\n");
-#endif /* CONFIG_DASD_ECKD_BUILTIN */
+
+                MESSAGE (KERN_INFO, "%s",
+                         "De-Registered DIAG discipline successfully");
 	}
+#endif /* CONFIG_DASD_DIAG */
+
 #ifdef CONFIG_DASD_FBA
 	dasd_fba_cleanup ();
-	DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd",
-				 "FBA discipline %s", "success");
-	printk (KERN_INFO PRINTK_HEADER
-		"De-Registered FBA discipline successfully\n");
-#endif /* CONFIG_DASD_ECKD_BUILTIN */
+
+	MESSAGE (KERN_INFO, "%s",
+		"De-Registered FBA discipline successfully");
+#endif /* CONFIG_DASD_FBA */
+
 #ifdef CONFIG_DASD_ECKD
 	dasd_eckd_cleanup ();
-	DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd",
-				 "ECKD discipline %s", "success");
-	printk (KERN_INFO PRINTK_HEADER
-		"De-Registered ECKD discipline successfully\n");
-#endif /* CONFIG_DASD_ECKD_BUILTIN */
 
-	genhd_dasd_name = NULL;
-	genhd_dasd_ioctl = NULL;
+	MESSAGE (KERN_INFO, "%s",
+                 "De-Registered ECKD discipline successfully");
+#endif /* CONFIG_DASD_ECKD */
+
+        genhd_dasd_name = NULL;
+        genhd_dasd_ioctl = NULL;
+
+#ifdef CONFIG_PROC_FS
 	dasd_proc_cleanup ();
+#endif /* CONFIG_PROC_FS */
         
-	list_for_each_safe (l, n, &dasd_major_info[0].list) {
+	list_for_each_safe (l, n, &dasd_major_info) {
 		major_info = list_entry (l, major_info_t, list);
 		for (i = 0; i < DASD_PER_MAJOR; i++) {
 			kfree (major_info->dasd_device[i]);
 		}
 		if ((major_info->flags & DASD_MAJOR_INFO_REGISTERED) &&
 		    (rc = dasd_unregister_major (major_info)) == 0) {
-			DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd",
-						 "major %d: success",
-						 major_info->gendisk.major);
-			printk (KERN_INFO PRINTK_HEADER
-				"Unregistered successfully from major no %u\n",
+
+			MESSAGE (KERN_INFO, 
+				"Unregistered successfully from major no %u",
 				major_info->gendisk.major);
 		} else {
-			DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd",
-						 "major %d: failed",
-						 major_info->gendisk.major);
-			printk (KERN_WARNING PRINTK_HEADER
-				"Couldn't unregister successfully from major no %d rc = %d\n",
-				major_info->gendisk.major, rc);
+
+			MESSAGE (KERN_WARNING,
+                                 "Couldn't unregister successfully from major "
+                                 "no %d rc = %d",
+                                 major_info->gendisk.major, 
+                                 rc);
   		}
   	}
 	list_for_each_safe (l, n, &dasd_range_head.list) {
@@ -4360,10 +5540,14 @@
 #endif /* MODULE */
         if (dasd_devfs_handle) 
                 devfs_unregister(dasd_devfs_handle);
-        if (dasd_debug_area != NULL )
+
+        if (dasd_debug_area != NULL ) {
                 debug_unregister(dasd_debug_area);
-	printk (KERN_INFO PRINTK_HEADER "shutdown completed\n");
-        DASD_DRIVER_DEBUG_EVENT(0,"cleanup_dasd","%s","LEAVE");
+                dasd_debug_area = NULL;
+        }
+
+	MESSAGE (KERN_INFO, "%s",
+                 "shutdown completed");
 }
 
 #ifdef MODULE
diff -urN linux-2.4.22-pre2/drivers/s390/block/dasd_3990_erp.c linux-2.4.22-pre3/drivers/s390/block/dasd_3990_erp.c
--- linux-2.4.22-pre2/drivers/s390/block/dasd_3990_erp.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/block/dasd_3990_erp.c	2003-07-05 18:10:26.000000000 -0700
@@ -5,6 +5,8 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
  *
+ * $Revision: 1.50 $
+ *
  * History of changes:
  * 05/14/01 fixed PL030160GTO (BUG() in erp_action_5)
  */
@@ -41,7 +43,9 @@
         char    *nl, 
                 *end_cqr,
                 *begin, 
-                *end;
+                *end,
+                buffer[80];
+        
         
         /* dump sense data */
         if (device->discipline            && 
@@ -54,83 +58,130 @@
         /* log the channel program */
         while (loop_cqr != NULL) {
                 
-                DASD_MESSAGE (KERN_ERR, device, 
-                              "(%s) ERP chain report for req: %p",
-                              caller == 0 ? "EXAMINE" : "ACTION",
-                              loop_cqr);
+                DEV_MESSAGE (KERN_ERR, device, 
+                             "(%s) ERP chain report for req: %p",
+                             caller == 0 ? "EXAMINE" : "ACTION",
+                             loop_cqr);
                 
                 nl      = (char *) loop_cqr;
                 end_cqr = nl + sizeof (ccw_req_t); 
                 
                 while (nl < end_cqr) {
+
+                        sprintf (buffer,
+                                 "%p: %02x%02x%02x%02x"
+                                 " %02x%02x%02x%02x"
+                                 " %02x%02x%02x%02x"
+                                 " %02x%02x%02x%02x",
+                                 nl,
+                                 nl[0], nl[1], nl[2], nl[3],
+                                 nl[4], nl[5], nl[6], nl[7],
+                                 nl[8], nl[9], nl[10], nl[11],
+                                 nl[12], nl[13], nl[14], nl[15]);
+        
+                        DEV_MESSAGE (KERN_ERR, device, "%s", 
+                                     buffer);
                         
-                        DASD_MESSAGE (KERN_ERR, device, 
-                                      "%p: %02x%02x%02x%02x %02x%02x%02x%02x "
-                                      "%02x%02x%02x%02x %02x%02x%02x%02x",
-                                      nl,
-                                      nl[0], nl[1], nl[2], nl[3],
-                                      nl[4], nl[5], nl[6], nl[7],
-                                      nl[8], nl[9], nl[10], nl[11],
-                                      nl[12], nl[13], nl[14], nl[15]);
                         nl +=16;
                 }        
-                
+               	
+		DEV_MESSAGE (KERN_ERR, device,
+				"DATA area is at: %p",
+				loop_cqr->data);
+
+		nl      = (char *) loop_cqr->data;
+		end_cqr = nl + loop_cqr->datasize;
+
+                while (nl < end_cqr) {
+					 
+                        sprintf (buffer,
+                                 "%p: %02x%02x%02x%02x"
+                                 " %02x%02x%02x%02x"
+                                 " %02x%02x%02x%02x"
+                                 " %02x%02x%02x%02x",
+                                  nl,
+                                  nl[0], nl[1], nl[2], nl[3],
+                                  nl[4], nl[5], nl[6], nl[7],
+                                  nl[8], nl[9], nl[10], nl[11],
+                                 nl[12], nl[13], nl[14], nl[15]);
+
+                        DEV_MESSAGE (KERN_ERR, device, "%s",
+                                     buffer);
+
+                        nl +=16;
+              }
+	       	
                 nl  = (char *) loop_cqr->cpaddr;
                 
                 if (loop_cqr->cplength > 40) { /* log only parts of the CP */
 
-                        DASD_MESSAGE (KERN_ERR, device, "%s",
+                        DEV_MESSAGE (KERN_ERR, device, "%s",
                                       "Start of channel program:");
                         
                         for (i = 0; i < 20; i += 2) { 
                                 
-                                DASD_MESSAGE (KERN_ERR, device, 
-                                              "%p: %02x%02x%02x%02x %02x%02x%02x%02x "
-                                              "%02x%02x%02x%02x %02x%02x%02x%02x",
-                                              nl,
-                                              nl[0], nl[1], nl[2], nl[3],
-                                              nl[4], nl[5], nl[6], nl[7],
-                                              nl[8], nl[9], nl[10], nl[11],
-                                              nl[12], nl[13], nl[14], nl[15]);
+                                sprintf (buffer,
+                                         "%p: %02x%02x%02x%02x"
+                                         " %02x%02x%02x%02x"
+                                         " %02x%02x%02x%02x"
+                                         " %02x%02x%02x%02x",
+                                         nl,
+                                         nl[0], nl[1], nl[2], nl[3],
+                                         nl[4], nl[5], nl[6], nl[7],
+                                         nl[8], nl[9], nl[10], nl[11],
+                                         nl[12], nl[13], nl[14], nl[15]);
                                 
+                                DEV_MESSAGE (KERN_ERR, device, "%s",
+                                             buffer);
+
                                 nl += 16;
                         }
                         
-                        DASD_MESSAGE (KERN_ERR, device, "%s",
-                                      "End of channel program:");
+                        DEV_MESSAGE (KERN_ERR, device, "%s",
+                                     "End of channel program:");
                         
                         nl  = (char *) loop_cqr->cpaddr;
                         nl  += ((loop_cqr->cplength - 10) * 8);
                         
                         for (i = 0; i < 20; i += 2) { 
                                 
-                                DASD_MESSAGE (KERN_ERR, device, 
-                                              "%p: %02x%02x%02x%02x %02x%02x%02x%02x "
-                                              "%02x%02x%02x%02x %02x%02x%02x%02x",
-                                              nl,
-                                              nl[0], nl[1], nl[2], nl[3],
-                                              nl[4], nl[5], nl[6], nl[7],
-                                              nl[8], nl[9], nl[10], nl[11],
-                                              nl[12], nl[13], nl[14], nl[15]);
+                                sprintf (buffer,
+                                         "%p: %02x%02x%02x%02x"
+                                         " %02x%02x%02x%02x"
+                                         " %02x%02x%02x%02x"
+                                         " %02x%02x%02x%02x",
+                                         nl,
+                                         nl[0], nl[1], nl[2], nl[3],
+                                         nl[4], nl[5], nl[6], nl[7],
+                                         nl[8], nl[9], nl[10], nl[11],
+                                         nl[12], nl[13], nl[14], nl[15]);
+                                
+                                DEV_MESSAGE (KERN_ERR, device, "%s",
+                                             buffer);
                                 
                                 nl += 16;
                         }
                         
                 } else { /* log the whole CP */
                         
-                        DASD_MESSAGE (KERN_ERR, device, "%s",
+                        DEV_MESSAGE (KERN_ERR, device, "%s",
                                       "Channel program (complete):");
                         
                         for (i = 0; i < (loop_cqr->cplength + 4); i += 2) { 
                                 
-                                DASD_MESSAGE (KERN_ERR, device, 
-                                              "%p: %02x%02x%02x%02x %02x%02x%02x%02x "
-                                              "%02x%02x%02x%02x %02x%02x%02x%02x",
-                                              nl,
-                                              nl[0], nl[1], nl[2], nl[3],
-                                              nl[4], nl[5], nl[6], nl[7],
-                                              nl[8], nl[9], nl[10], nl[11],
-                                              nl[12], nl[13], nl[14], nl[15]);
+                                sprintf (buffer,
+                                         "%p: %02x%02x%02x%02x"
+                                         " %02x%02x%02x%02x"
+                                         " %02x%02x%02x%02x"
+                                         " %02x%02x%02x%02x",
+                                         nl,
+                                         nl[0], nl[1], nl[2], nl[3],
+                                         nl[4], nl[5], nl[6], nl[7],
+                                         nl[8], nl[9], nl[10], nl[11],
+                                         nl[12], nl[13], nl[14], nl[15]);
+                                
+                                DEV_MESSAGE (KERN_ERR, device, "%s",
+                                             buffer);
                                 
                                 nl += 16;
                         }
@@ -150,29 +201,34 @@
                         
                                 nl -= 10*8;     /* start some bytes before */
                                 
-                                DASD_MESSAGE (KERN_ERR, device, 
-                                                "Failed CCW (%p) (area):",
-                                                (void *)(long)cpa);
+                                DEV_MESSAGE (KERN_ERR, device, 
+                                             "Failed CCW (%p) (area):",
+                                             (void *)(long)cpa);
                                 
                                 for (i = 0; i < 20; i += 2) { 
                                         
-                                        DASD_MESSAGE (KERN_ERR, device, 
-                                                      "%p: %02x%02x%02x%02x %02x%02x%02x%02x "
-                                                      "%02x%02x%02x%02x %02x%02x%02x%02x",
-                                                      nl,
-                                                      nl[0], nl[1], nl[2], nl[3],
-                                                      nl[4], nl[5], nl[6], nl[7],
-                                                      nl[8], nl[9], nl[10], nl[11],
-                                                      nl[12], nl[13], nl[14], nl[15]);
+                                        sprintf (buffer,
+                                                 "%p: %02x%02x%02x%02x"
+                                                 " %02x%02x%02x%02x"
+                                                 " %02x%02x%02x%02x"
+                                                 " %02x%02x%02x%02x",
+                                                 nl,
+                                                 nl[0], nl[1], nl[2], nl[3],
+                                                 nl[4], nl[5], nl[6], nl[7],
+                                                 nl[8], nl[9], nl[10], nl[11],
+                                                 nl[12], nl[13], nl[14], nl[15]);
+
+                                        DEV_MESSAGE (KERN_ERR, device, "%s",
+                                                     buffer);
                                         
                                         nl += 16;
                                 }
                                 
                         } else {
                                 
-                                DASD_MESSAGE (KERN_ERR, device, 
-                                              "Failed CCW (%p) already logged",
-                                              (void *)(long)cpa);
+                                DEV_MESSAGE (KERN_ERR, device, 
+                                             "Failed CCW (%p) already logged",
+                                             (void *)(long)cpa);
                         }
                 }
                 
@@ -216,9 +272,9 @@
 	if ((  sense[0] & SNS0_CMD_REJECT       ) &&
 	    (!(sense[2] & SNS2_ENV_DATA_PRESENT))   ) {
 
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "EXAMINE 24: Command Reject detected - "
-                              "fatal error");
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "EXAMINE 24: Command Reject detected - "
+                             "fatal error");
 
                 return dasd_era_fatal;
 	}
@@ -227,9 +283,9 @@
 	if ((  sense[1] & SNS1_INV_TRACK_FORMAT ) &&
             (!(sense[2] & SNS2_ENV_DATA_PRESENT))   ) {
 
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "EXAMINE 24: Invalid Track Format detected "
-                              "- fatal error");
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "EXAMINE 24: Invalid Track Format detected "
+                             "- fatal error");
 
                 return dasd_era_fatal;
 	}
@@ -237,10 +293,10 @@
 	/* check for 'No Record Found' */
 	if (sense[1] & SNS1_NO_REC_FOUND) {
                 
-                DASD_MESSAGE (KERN_ERR, device,
-                              "EXAMINE 24: No Record Found detected %s",
-                              cqr == device->init_cqr ? " " :
-                              "- fatal error");
+                DEV_MESSAGE (KERN_ERR, device,
+                             "EXAMINE 24: No Record Found detected %s",
+                             cqr == device->init_cqr ? " " :
+                             "- fatal error");
 
                 return dasd_era_fatal;
 	}
@@ -274,8 +330,9 @@
 		return dasd_era_none;
 
 	case 0x01:
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "EXAMINE 32: fatal error");
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "EXAMINE 32: fatal error");
+
 		return dasd_era_fatal;
 
 	default:
@@ -405,20 +462,24 @@
 
 	dasd_device_t *device = erp->device;
 
-        DASD_MESSAGE (KERN_INFO, device,
-                      "blocking request queue for %is",
-                      (int) expires);
+        DEV_MESSAGE (KERN_INFO, device,
+                     "blocking request queue for %is",
+                     (int) expires);
 
         check_then_set (&erp->status,
                         CQR_STATUS_ERROR,
                         CQR_STATUS_PENDING);
 
         /* restart queue after some time */
-        device->timer.function = dasd_3990_erp_restart_queue; 
-        device->timer.data     = (unsigned long) erp;
-        device->timer.expires  = jiffies + (expires * HZ);
-
-        add_timer(&device->timer); 
+        if (!timer_pending(&device->blocking_timer)) {
+                init_timer(&device->blocking_timer);
+                device->blocking_timer.function = dasd_3990_erp_restart_queue; 
+                device->blocking_timer.data     = (unsigned long) erp;
+                device->blocking_timer.expires  = jiffies + (expires * HZ);
+                add_timer(&device->blocking_timer); 
+        } else {
+                mod_timer(&device->blocking_timer, jiffies + (expires * HZ));
+        }
 
 } /* end dasd_3990_erp_block_queue */ 
 
@@ -453,8 +514,8 @@
         /* 'restart' the device queue */
         if (cqr->status == CQR_STATUS_PENDING) {
                 
-                DASD_MESSAGE (KERN_INFO, device, "%s",
-                              "request queue restarted by MIH");
+                DEV_MESSAGE (KERN_INFO, device, "%s",
+                             "request queue restarted by MIH");
 
                 check_then_set (&cqr->status,
                                 CQR_STATUS_PENDING,
@@ -498,9 +559,9 @@
         } else {
 
                 /* issue a message and wait for 'device ready' interrupt */
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "is offline or not installed - "
-                              "INTERVENTION REQUIRED!!");
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "is offline or not installed - "
+                             "INTERVENTION REQUIRED!!");
                 
                 dasd_3990_erp_block_queue (erp,
                                            60);
@@ -538,11 +599,11 @@
 
 	if ((erp->lpm & ioinfo[irq]->opm) != 0x00) {
 
-		DASD_MESSAGE (KERN_DEBUG, device,
-                              "try alternate lpm=%x (lpum=%x / opm=%x)",
-                              erp->lpm,
-                              erp->dstat->lpum,
-                              ioinfo[irq]->opm);
+		DEV_MESSAGE (KERN_DEBUG, device,
+                             "try alternate lpm=%x (lpum=%x / opm=%x)",
+                             erp->lpm,
+                             erp->dstat->lpum,
+                             ioinfo[irq]->opm);
 
 		/* reset status to queued to handle the request again... */
 		check_then_set (&erp->status,
@@ -553,11 +614,11 @@
                 
 	} else {
          
-                DASD_MESSAGE (KERN_ERR, device,
-                              "No alternate channel path left (lpum=%x / "
-                              "opm=%x) -> permanent error",
-                              erp->dstat->lpum,
-                              ioinfo[irq]->opm);
+                DEV_MESSAGE (KERN_ERR, device,
+                             "No alternate channel path left (lpum=%x / "
+                             "opm=%x) -> permanent error",
+                             erp->dstat->lpum,
+                             ioinfo[irq]->opm);
                 
                 /* post request with permanent error */
                 check_then_set (&erp->status,
@@ -598,8 +659,8 @@
         
 	if (!dctl_cqr) {
 
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "Unable to allocate DCTL-CQR");
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "Unable to allocate DCTL-CQR");
                 
                 check_then_set (&erp->status,
                                 CQR_STATUS_ERROR,
@@ -620,8 +681,9 @@
         if (dasd_set_normalized_cda(ccw, 
                                     __pa (DCTL_data), dctl_cqr, erp->device)) {
                 dasd_free_request (dctl_cqr, erp->device);
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "Unable to allocate DCTL-CQR");
+
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "Unable to allocate DCTL-CQR");
 
                 check_then_set (&erp->status,
                                 CQR_STATUS_ERROR,
@@ -635,7 +697,8 @@
         dctl_cqr->lpm      = LPM_ANYPATH;
         dctl_cqr->expires  = 5 * TOD_MIN;
         dctl_cqr->retries  = 2;
-	asm volatile ("STCK %0":"=m" (dctl_cqr->buildclk));
+
+	dctl_cqr->buildclk = get_clock ();
 
         dctl_cqr->status = CQR_STATUS_FILLED;
 
@@ -706,17 +769,16 @@
 
         } else {
 
-                if (sense[25] & 0x1D) {	/* state change pending */
+                if (sense[25] == 0x1D) {	/* state change pending */
                         
-                        DASD_MESSAGE (KERN_INFO, device, "%s",
-                                      "waiting for state change pending "
-                                      "int");
+                        DEV_MESSAGE (KERN_INFO, device, "%s",
+                                     "waiting for state change pending "
+                                     "int");
                         
                         dasd_3990_erp_block_queue (erp,
                                                    30);
-                        
                 } else {
-
+			DEV_MESSAGE (KERN_INFO, device, "redriving request immediately, %d retries left", erp->retries);
                         /* no state change pending - retry */
                         check_then_set (&erp->status,
                                         CQR_STATUS_ERROR,
@@ -793,98 +855,98 @@
 			case 0x00:	/* No Message */
 				break;
 			case 0x01:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Invalid Command");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Invalid Command");
 				break;
 			case 0x02:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Invalid Command "
-                                              "Sequence");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Invalid Command "
+                                             "Sequence");
 				break;
 			case 0x03:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - CCW Count less than "
-                                              "required");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - CCW Count less than "
+                                             "required");
 				break;
 			case 0x04:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Invalid Parameter");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Invalid Parameter");
 				break;
 			case 0x05:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Diagnostic of Sepecial"
-                                              " Command Violates File Mask");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Diagnostic of Sepecial"
+                                             " Command Violates File Mask");
 				break;
 			case 0x07:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Channel Returned with "
-                                              "Incorrect retry CCW");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Channel Returned with "
+                                             "Incorrect retry CCW");
 				break;
 			case 0x08:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Reset Notification");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Reset Notification");
 				break;
 			case 0x09:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Storage Path Restart");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Storage Path Restart");
 				break;
 			case 0x0A:
-                                DASD_MESSAGE (KERN_WARNING, device,
-                                              "FORMAT 0 - Channel requested "
-                                              "... %02x",
-                                              sense[8]);
+                                DEV_MESSAGE (KERN_WARNING, device,
+                                             "FORMAT 0 - Channel requested "
+                                             "... %02x",
+                                             sense[8]);
 				break;
 			case 0x0B:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Invalid Defective/"
-                                              "Alternate Track Pointer");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Invalid Defective/"
+                                             "Alternate Track Pointer");
 				break;
 			case 0x0C:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - DPS Installation "
-                                              "Check");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - DPS Installation "
+                                             "Check");
 				break;
 			case 0x0E:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Command Invalid on "
-                                              "Secondary Address");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Command Invalid on "
+                                             "Secondary Address");
 				break;
 			case 0x0F:
-                                DASD_MESSAGE (KERN_WARNING, device,
-                                              "FORMAT 0 - Status Not As "
-                                              "Required: reason %02x",
-                                              sense[8]);
+                                DEV_MESSAGE (KERN_WARNING, device,
+                                             "FORMAT 0 - Status Not As "
+                                             "Required: reason %02x",
+                                             sense[8]);
 				break;
 			default:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Reseved");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Reseved");
 			}
 		} else {
 			switch (msg_no) {
 			case 0x00:	/* No Message */
 				break;
 			case 0x01:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Device Error Source");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Device Error Source");
 				break;
 			case 0x02:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Reserved");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Reserved");
 				break;
 			case 0x03:
-                                DASD_MESSAGE (KERN_WARNING, device,
-                                              "FORMAT 0 - Device Fenced - "
-                                              "device = %02x",
-                                              sense[4]);
+                                DEV_MESSAGE (KERN_WARNING, device,
+                                             "FORMAT 0 - Device Fenced - "
+                                             "device = %02x",
+                                             sense[4]);
 				break;
 			case 0x04:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Data Pinned for "
-                                              "Device");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Data Pinned for "
+                                             "Device");
 				break;
 			default:
-                                DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                              "FORMAT 0 - Reserved");
+                                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                             "FORMAT 0 - Reserved");
 			}
                 }
                 break;
@@ -894,348 +956,348 @@
 		case 0x00:	/* No Message */
 			break;
 		case 0x01:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Device Status 1 not as "
-                                      "expected");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Device Status 1 not as "
+                                     "expected");
 			break;
 		case 0x03:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Index missing");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Index missing");
 			break;
 		case 0x04:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Interruption cannot be reset");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Interruption cannot be reset");
 			break;
 		case 0x05:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Device did not respond to "
-                                      "selection");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Device did not respond to "
+                                     "selection");
 			break;
 		case 0x06:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Device check-2 error or Set "
-                                      "Sector is not complete");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Device check-2 error or Set "
+                                     "Sector is not complete");
 			break;
 		case 0x07:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Head address does not "
-                                      "compare");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Head address does not "
+                                     "compare");
 			break;
 		case 0x08:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Device status 1 not valid");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Device status 1 not valid");
 			break;
 		case 0x09:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Device not ready");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Device not ready");
 			break;
 		case 0x0A:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Track physical address did "
-                                      "not compare");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Track physical address did "
+                                     "not compare");
 			break;
 		case 0x0B:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Missing device address bit");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Missing device address bit");
 			break;
 		case 0x0C:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Drive motor switch is off");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Drive motor switch is off");
 			break;
 		case 0x0D:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Seek incomplete");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Seek incomplete");
 			break;
 		case 0x0E:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Cylinder address did not "
-                                      "compare");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Cylinder address did not "
+                                     "compare");
 			break;
 		case 0x0F:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Offset active cannot be "
-                                      "reset");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Offset active cannot be "
+                                     "reset");
 			break;
 		default:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 1 - Reserved");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 1 - Reserved");
 		}
                 break;		
                         
 	case 0x20:	/* Format 2 - 3990 Equipment Checks */
 		switch (msg_no) {
 		case 0x08:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 2 - 3990 check-2 error");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 2 - 3990 check-2 error");
 			break;
 		case 0x0E:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 2 - Support facility errors");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 2 - Support facility errors");
 			break;
 		case 0x0F:
-                        DASD_MESSAGE (KERN_WARNING, device,
-                                      "FORMAT 2 - Microcode detected error %02x",
-                                      sense[8]);
+                        DEV_MESSAGE (KERN_WARNING, device,
+                                     "FORMAT 2 - Microcode detected error %02x",
+                                     sense[8]);
 			break;
 		default:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 2 - Reserved");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 2 - Reserved");
 		}
                 break;		
 
 	case 0x30:	/* Format 3 - 3990 Control Checks */
 		switch (msg_no) {
 		case 0x0F:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 3 - Allegiance terminated");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 3 - Allegiance terminated");
 			break;
 		default:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 3 - Reserved");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 3 - Reserved");
 		}
                 break;		
 
 	case 0x40:	/* Format 4 - Data Checks */
 		switch (msg_no) {
 		case 0x00:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - Home address area error");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - Home address area error");
 			break;
 		case 0x01:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - Count area error");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - Count area error");
 			break;
 		case 0x02:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - Key area error");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - Key area error");
 			break;
 		case 0x03:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - Data area error");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - Data area error");
 			break;
 		case 0x04:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - No sync byte in home address "
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - No sync byte in home address "
                                       "area");
 			break;
 		case 0x05:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - No sync byte in count address "
-                                      "area");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - No sync byte in count address "
+                                     "area");
 			break;
 		case 0x06:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - No sync byte in key area");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - No sync byte in key area");
 			break;
 		case 0x07:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - No sync byte in data area");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - No sync byte in data area");
 			break;
 		case 0x08:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - Home address area error; "
-                                      "offset active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - Home address area error; "
+                                     "offset active");
 			break;
 		case 0x09:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - Count area error; offset "
-                                      "active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - Count area error; offset "
+                                     "active");
 			break;
 		case 0x0A:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - Key area error; offset "
-                                      "active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - Key area error; offset "
+                                     "active");
 			break;
 		case 0x0B:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - Data area error; "
-                                      "offset active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - Data area error; "
+                                     "offset active");
 			break;
 		case 0x0C:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - No sync byte in home "
-                                      "address area; offset active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - No sync byte in home "
+                                     "address area; offset active");
 			break;
 		case 0x0D:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - No syn byte in count "
-                                      "address area; offset active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - No syn byte in count "
+                                     "address area; offset active");
 			break;
 		case 0x0E:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - No sync byte in key area; "
-                                      "offset active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - No sync byte in key area; "
+                                     "offset active");
 			break;
 		case 0x0F:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - No syn byte in data area; "
-                                      "offset active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - No syn byte in data area; "
+                                     "offset active");
 			break;
 		default:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 4 - Reserved");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 4 - Reserved");
 		}
                 break;		
 
 	case 0x50:	/* Format 5 - Data Check with displacement information */
 		switch (msg_no) {
 		case 0x00:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 5 - Data Check in the "
-                                      "home address area");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 5 - Data Check in the "
+                                     "home address area");
 			break;
 		case 0x01:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 5 - Data Check in the count area");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 5 - Data Check in the count area");
 			break;
 		case 0x02:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 5 - Data Check in the key area");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 5 - Data Check in the key area");
 			break;
 		case 0x03:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 5 - Data Check in the data area");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 5 - Data Check in the data area");
 			break;
 		case 0x08:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 5 - Data Check in the "
-                                      "home address area; offset active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 5 - Data Check in the "
+                                     "home address area; offset active");
 			break;
 		case 0x09:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 5 - Data Check in the count area; "
-                                      "offset active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 5 - Data Check in the count area; "
+                                     "offset active");
 			break;
 		case 0x0A:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 5 - Data Check in the key area; "
-                                      "offset active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 5 - Data Check in the key area; "
+                                     "offset active");
 			break;
 		case 0x0B:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 5 - Data Check in the data area; "
-                                      "offset active");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 5 - Data Check in the data area; "
+                                     "offset active");
 			break;
 		default:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 5 - Reserved");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 5 - Reserved");
 		}
                 break;		
 
 	case 0x60:	/* Format 6 - Usage Statistics/Overrun Errors */
 		switch (msg_no) {
 		case 0x00:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 6 - Overrun on channel A");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 6 - Overrun on channel A");
 			break;
 		case 0x01:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 6 - Overrun on channel B");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 6 - Overrun on channel B");
 			break;
 		case 0x02:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 6 - Overrun on channel C");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 6 - Overrun on channel C");
 			break;
 		case 0x03:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 6 - Overrun on channel D");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 6 - Overrun on channel D");
 			break;
 		case 0x04:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 6 - Overrun on channel E");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 6 - Overrun on channel E");
 			break;
 		case 0x05:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 6 - Overrun on channel F");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 6 - Overrun on channel F");
 			break;
 		case 0x06:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 6 - Overrun on channel G");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 6 - Overrun on channel G");
 			break;
 		case 0x07:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 6 - Overrun on channel H");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 6 - Overrun on channel H");
 			break;
 		default:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 6 - Reserved");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 6 - Reserved");
 		}
                 break;		
 
 	case 0x70:	/* Format 7 - Device Connection Control Checks */
 		switch (msg_no) {
 		case 0x00:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - RCC initiated by a connection "
-                                      "check alert");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - RCC initiated by a connection "
+                                     "check alert");
 			break;
 		case 0x01:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - RCC 1 sequence not "
-                                      "successful");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - RCC 1 sequence not "
+                                     "successful");
 			break;
 		case 0x02:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - RCC 1 and RCC 2 sequences not "
-                                      "successful");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - RCC 1 and RCC 2 sequences not "
+                                     "successful");
 			break;
 		case 0x03:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - Invalid tag-in during "
-                                      "selection sequence");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - Invalid tag-in during "
+                                     "selection sequence");
 			break;
 		case 0x04:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - extra RCC required");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - extra RCC required");
 			break;
 		case 0x05:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - Invalid DCC selection "
-                                      "response or timeout");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - Invalid DCC selection "
+                                     "response or timeout");
 			break;
 		case 0x06:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - Missing end operation; device "
-                                      "transfer complete");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - Missing end operation; device "
+                                     "transfer complete");
 			break;
 		case 0x07:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - Missing end operation; device "
-                                      "transfer incomplete");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - Missing end operation; device "
+                                     "transfer incomplete");
 			break;
 		case 0x08:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - Invalid tag-in for an "
-                                      "immediate command sequence");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - Invalid tag-in for an "
+                                     "immediate command sequence");
 			break;
 		case 0x09:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - Invalid tag-in for an "
-                                      "extended command sequence");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - Invalid tag-in for an "
+                                     "extended command sequence");
 			break;
 		case 0x0A:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - 3990 microcode time out when "
-                                      "stopping selection");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - 3990 microcode time out when "
+                                     "stopping selection");
 			break;
 		case 0x0B:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - No response to selection "
-                                      "after a poll interruption");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - No response to selection "
+                                     "after a poll interruption");
 			break;
 		case 0x0C:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - Permanent path error (DASD "
-                                      "controller not available)");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - Permanent path error (DASD "
+                                     "controller not available)");
 			break;
 		case 0x0D:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - DASD controller not available"
-                                      " on disconnected command chain");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - DASD controller not available"
+                                     " on disconnected command chain");
 			break;
 		default:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 7 - Reserved");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 7 - Reserved");
 		}
                 break;		
 
@@ -1243,52 +1305,52 @@
 		switch (msg_no) {
 		case 0x00:	/* No Message */
 		case 0x01:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 8 - Error correction code "
-                                      "hardware fault");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 8 - Error correction code "
+                                     "hardware fault");
 			break;
 		case 0x03:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 8 - Unexpected end operation "
-                                      "response code");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 8 - Unexpected end operation "
+                                     "response code");
 			break;
 		case 0x04:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 8 - End operation with transfer "
-                                      "count not zero");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 8 - End operation with transfer "
+                                     "count not zero");
 			break;
 		case 0x05:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 8 - End operation with transfer "
-                                      "count zero");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 8 - End operation with transfer "
+                                     "count zero");
 			break;
 		case 0x06:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 8 - DPS checks after a system "
-                                      "reset or selective reset");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 8 - DPS checks after a system "
+                                     "reset or selective reset");
 			break;
 		case 0x07:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 8 - DPS cannot be filled");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 8 - DPS cannot be filled");
 			break;
 		case 0x08:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 8 - Short busy time-out during "
-                                      "device selection");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 8 - Short busy time-out during "
+                                     "device selection");
 			break;
 		case 0x09:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 8 - DASD controller failed to "
-                                      "set or reset the long busy latch");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 8 - DASD controller failed to "
+                                     "set or reset the long busy latch");
 			break;
 		case 0x0A:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 8 - No interruption from device "
-                                      "during a command chain");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 8 - No interruption from device "
+                                     "during a command chain");
 			break;
 		default:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 8 - Reserved");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 8 - Reserved");
 		}
                 break;		
 
@@ -1297,94 +1359,97 @@
 		case 0x00:
 			break;	/* No Message */
 		case 0x06:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 9 - Device check-2 error");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 9 - Device check-2 error");
 			break;
 		case 0x07:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 9 - Head address did not compare");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 9 - Head address did not compare");
 			break;
 		case 0x0A:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 9 - Track physical address did "
-                                      "not compare while oriented");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 9 - Track physical address did "
+                                     "not compare while oriented");
 			break;
 		case 0x0E:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 9 - Cylinder address did not "
-                                      "compare");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 9 - Cylinder address did not "
+                                     "compare");
 			break;
 		default:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT 9 - Reserved");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT 9 - Reserved");
 		}
                 break;		
 
 	case 0xF0:		/* Format F - Cache Storage Checks */
 		switch (msg_no) {
 		case 0x00:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - Operation Terminated");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - Operation Terminated");
 			break;
 		case 0x01:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - Subsystem Processing Error");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - Subsystem Processing Error");
 			break;
 		case 0x02:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - Cache or nonvolatile storage "
-                                      "equipment failure");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - Cache or nonvolatile storage "
+                                     "equipment failure");
 			break;
 		case 0x04:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - Caching terminated");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - Caching terminated");
 			break;
 		case 0x06:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - Cache fast write access not "
-                                      "authorized");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - Cache fast write access not "
+                                     "authorized");
 			break;
 		case 0x07:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - Track format incorrect");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - Track format incorrect");
 			break;
 		case 0x09:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - Caching reinitiated");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - Caching reinitiated");
 			break;
 		case 0x0A:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - Nonvolatile storage "
-                                      "terminated");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - Nonvolatile storage "
+                                     "terminated");
 			break;
 		case 0x0B:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - Volume is suspended duplex");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - Volume is suspended duplex");
 			break;
 		case 0x0C:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - Subsystem status connot be "
-                                      "determined");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - Subsystem status connot be "
+                                     "determined");
 			break;
 		case 0x0D:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - Caching status reset to "
-                                      "default");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - Caching status reset to "
+                                     "default");
 			break;
 		case 0x0E:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT F - DASD Fast Write inhibited");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT F - DASD Fast Write inhibited");
 			break;
 		default:
-                        DASD_MESSAGE (KERN_WARNING, device, "%s",
-                                      "FORMAT D - Reserved");
+                        DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "FORMAT D - Reserved");
 		}
                 break;		
 
 	default:	/* unknown message format - should not happen */
-
+                DEV_MESSAGE (KERN_WARNING, device,
+                             "unknown message format %02x",
+                             msg_format);
+                
 	} /* end switch message format */
-
+        
 } /* end dasd_3990_handle_env_data */
 
 /*
@@ -1412,8 +1477,8 @@
 	/* env data present (ACTION 10 - retry should work) */
 	if (sense[2] & SNS2_ENV_DATA_PRESENT) {
 
-                DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Command Reject - environmental data present");
+                DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Command Reject - environmental data present");
 
 		dasd_3990_handle_env_data (erp,
                                            sense);
@@ -1422,8 +1487,8 @@
 
 	} else {
 		/* fatal error -  set status to FAILED */
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "Command Reject - Fatal error");
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "Command Reject - Fatal error");
 
                 erp = dasd_3990_erp_cleanup (erp,
                                              CQR_STATUS_FAILED);
@@ -1460,9 +1525,9 @@
         } else {
 
                 /* issue a message and wait for 'device ready' interrupt */
-                DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "bus out parity error or BOPC requested by "
-                              "channel");
+                DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "bus out parity error or BOPC requested by "
+                             "channel");
                 
                 dasd_3990_erp_block_queue (erp,
                                            60);
@@ -1495,22 +1560,22 @@
 
 	if (sense[1] & SNS1_WRITE_INHIBITED) {
 
-		DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Write inhibited path encountered");
+		DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Write inhibited path encountered");
 
 		/* vary path offline */
-		DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "Path should be varied off-line. "
-                              "This is not implemented yet \n - please report "
-                              "to linux390@de.ibm.com");
+		DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "Path should be varied off-line. "
+                             "This is not implemented yet \n - please report "
+                             "to linux390@de.ibm.com");
 
 		erp = dasd_3990_erp_action_1 (erp);
 
 	} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
                 
-                DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Equipment Check - "
-                              "environmental data present");
+                DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Equipment Check - "
+                             "environmental data present");
                 
                 dasd_3990_handle_env_data (erp,
                                            sense);
@@ -1519,17 +1584,18 @@
                                               sense);
                 
         } else if (sense[1] & SNS1_PERM_ERR) {
-                DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Equipment Check - retry exhausted or "
-                              "undesirable");
+
+                DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Equipment Check - retry exhausted or "
+                             "undesirable");
                 
                 erp = dasd_3990_erp_action_1 (erp);
                 
         } else {
                 /* all other equipment checks - Action 5 */
                 /* rest is done when retries == 0 */
-                DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Equipment check or processing error");
+                DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Equipment check or processing error");
                 
                 erp = dasd_3990_erp_action_5 (erp);
         }
@@ -1561,9 +1627,9 @@
 	if (sense[2] & SNS2_CORRECTABLE) {	/* correctable data check */
 
 		/* issue message that the data has been corrected */
-		DASD_MESSAGE (KERN_EMERG, device, "%s",
-                              "Data recovered during retry with PCI "
-                              "fetch mode active");
+		DEV_MESSAGE (KERN_EMERG, device, "%s",
+                             "Data recovered during retry with PCI "
+                             "fetch mode active");
 
                 /* not possible to handle this situation in Linux */    
                 panic("No way to inform appliction about the possibly "
@@ -1571,26 +1637,26 @@
 
 	} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
 
-		DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Uncorrectable data check recovered secondary "
-                              "addr of duplex pair");
+		DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Uncorrectable data check recovered secondary "
+                             "addr of duplex pair");
 
 		erp = dasd_3990_erp_action_4 (erp,
 					      sense);
 
 	} else if (sense[1] & SNS1_PERM_ERR) {
 
-		DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Uncorrectable data check with internal "
-                              "retry exhausted");
+		DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Uncorrectable data check with internal "
+                             "retry exhausted");
 
 		erp = dasd_3990_erp_action_1 (erp);
 
 	} else {
 		/* all other data checks */
-		DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Uncorrectable data check with retry count "
-                              "exhausted...");
+		DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Uncorrectable data check with retry count "
+                             "exhausted...");
 
 		erp = dasd_3990_erp_action_5 (erp);
 	}
@@ -1619,9 +1685,9 @@
 
 	erp->function = dasd_3990_erp_overrun;
 
-        DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                      "Overrun - service overrun or overrun"
-                      " error requested by channel");
+        DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                     "Overrun - service overrun or overrun"
+                     " error requested by channel");
 
         erp = dasd_3990_erp_action_5 (erp);
 
@@ -1651,9 +1717,9 @@
 
 	if (sense[2] & SNS2_ENV_DATA_PRESENT) {
 
-		DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Track format error when destaging or "
-                              "staging data");
+		DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Track format error when destaging or "
+                             "staging data");
 
 		dasd_3990_handle_env_data (erp,
                                            sense);
@@ -1662,9 +1728,9 @@
 					      sense);
 
 	} else {
-		DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "Invalid Track Format - Fatal error should have "
-                              "been handled within the interrupt handler");
+		DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "Invalid Track Format - Fatal error should have "
+                             "been handled within the interrupt handler");
 
                 erp= dasd_3990_erp_cleanup (erp,
                                             CQR_STATUS_FAILED);
@@ -1692,8 +1758,8 @@
 
 	dasd_device_t *device = default_erp->device;
 
-        DASD_MESSAGE (KERN_ERR, device, "%s",
-                      "End-of-Cylinder - must never happen");
+        DEV_MESSAGE (KERN_ERR, device, "%s",
+                     "End-of-Cylinder - must never happen");
 
         /* implement action 7 - BUG */
         return dasd_3990_erp_cleanup (default_erp,
@@ -1721,8 +1787,8 @@
 
 	erp->function = dasd_3990_erp_env_data;
 
-        DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                      "Environmental data present");
+        DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                     "Environmental data present");
 
         dasd_3990_handle_env_data (erp,
                                    sense);
@@ -1761,9 +1827,9 @@
 
 	dasd_device_t *device = default_erp->device;
 
-        DASD_MESSAGE (KERN_ERR, device, "%s",
-                      "No Record Found - Fatal error should "
-                      "have been handled within the interrupt handler");
+        DEV_MESSAGE (KERN_ERR, device, "%s",
+                     "No Record Found - Fatal error should "
+                     "have been handled within the interrupt handler");
 
         return dasd_3990_erp_cleanup (default_erp,
                                       CQR_STATUS_FAILED);
@@ -1789,8 +1855,8 @@
 
 	dasd_device_t *device = erp->device;
 
-        DASD_MESSAGE (KERN_ERR, device, "%s",
-                      "File Protected");
+        DEV_MESSAGE (KERN_ERR, device, "%s",
+                     "File Protected");
 
         return dasd_3990_erp_cleanup (erp,
                                       CQR_STATUS_FAILED);
@@ -1921,8 +1987,8 @@
         erp->retries  = 256;
         erp->function = dasd_3990_erp_action_10_32;
 
-	DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                      "Perform logging requested");
+	DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                     "Perform logging requested");
 
 	return erp;
 
@@ -1960,8 +2026,8 @@
 	char           *LO_data;   /* LO_eckd_data_t */
         ccw1_t         *ccw;
 
-	DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                      "Write not finished because of unexpected condition");
+	DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                     "Write not finished because of unexpected condition");
         
         default_erp->function = dasd_3990_erp_action_1B_32;
 
@@ -1975,8 +2041,8 @@
         /* for imprecise ending just do default erp */
         if (sense[1] & 0x01) {
 
-                DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Imprecise ending is set - just retry");
+                DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Imprecise ending is set - just retry");
 
                 return default_erp;
         } 
@@ -1987,9 +2053,9 @@
         
         if (cpa == 0) {
                 
-                DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Unable to determine address of the CCW "
-                              "to be restarted");
+                DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Unable to determine address of the CCW "
+                             "to be restarted");
                 
                 return dasd_3990_erp_cleanup (default_erp,
                                               CQR_STATUS_FAILED);
@@ -2004,8 +2070,8 @@
 
 	if (!erp) {
 
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "Unable to allocate ERP");
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "Unable to allocate ERP");
                 
                 return dasd_3990_erp_cleanup (default_erp,
                                               CQR_STATUS_FAILED);
@@ -2023,8 +2089,8 @@
         if ((sense[3]  == 0x01) &&
             (LO_data[1] & 0x01)   ){
 
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "BUG - this should not happen");
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "BUG - this should not happen");
 
                 return dasd_3990_erp_cleanup (default_erp,
                                               CQR_STATUS_FAILED);
@@ -2060,8 +2126,8 @@
 	if (dasd_set_normalized_cda (ccw,
                                      __pa (DE_data), erp, device)) {
                 dasd_free_request (erp, device);
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "Unable to allocate ERP");
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "Unable to allocate ERP");
 
                 return dasd_3990_erp_cleanup (default_erp,
                                               CQR_STATUS_FAILED);
@@ -2076,8 +2142,8 @@
 	if (dasd_set_normalized_cda (ccw, 
                                      __pa (LO_data), erp, device)){
                 dasd_free_request (erp, device);
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "Unable to allocate ERP");
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "Unable to allocate ERP");
                 
                 return dasd_3990_erp_cleanup (default_erp,
                                               CQR_STATUS_FAILED);
@@ -2132,9 +2198,9 @@
 	char           *LO_data;   /* LO_eckd_data_t */
         ccw1_t         *ccw;
 
-	DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                      "Write not finished because of unexpected condition"
-                      " - follow on");
+	DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                     "Write not finished because of unexpected condition"
+                     " - follow on");
         
         /* determine the original cqr */
         cqr = previous_erp;
@@ -2146,8 +2212,8 @@
         /* for imprecise ending just do default erp */
         if (sense[1] & 0x01) {
 
-                DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Imprecise ending is set - just retry");
+                DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Imprecise ending is set - just retry");
 
                 check_then_set (&previous_erp->status,
                                 CQR_STATUS_ERROR,
@@ -2162,9 +2228,9 @@
         
         if (cpa == 0) {
                 
-                DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                              "Unable to determine address of the CCW "
-                              "to be restarted");
+                DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                             "Unable to determine address of the CCW "
+                             "to be restarted");
                 
                 check_then_set (&previous_erp->status,
                                 CQR_STATUS_ERROR,
@@ -2181,8 +2247,8 @@
         if ((sense[3]  == 0x01) &&
             (LO_data[1] & 0x01)   ){
 
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "BUG - this should not happen");
+                DEV_MESSAGE (KERN_ERR, device, "%s",
+                             "BUG - this should not happen");
 
                 check_then_set (&previous_erp->status,
                                 CQR_STATUS_ERROR,
@@ -2337,7 +2403,7 @@
                 switch (sense[28]) {
                 case 0x17:
                         /* issue a Diagnostic Control command with an 
-                         * Inhibit Write subcommand and controler modifier */
+                                * Inhibit Write subcommand and controler modifier */
                         erp = dasd_3990_erp_DCTL (erp,
                                                   0x20);
                         break;
@@ -2351,7 +2417,7 @@
                         break;
                         
                 default:
-                        /* should not happen - continue */
+                        ; /* should not happen - continue */
 
                 }
         }
@@ -2389,11 +2455,11 @@
                 /* set to suspended duplex state then restart */
                 dasd_device_t *device  = erp->device;
 
-                DASD_MESSAGE (KERN_ERR, device, "%s",      
-                              "Set device to suspended duplex state should be "
-                              "done!\n"
-                              "This is not implemented yet (for compound ERP)"
-                              " - please report to linux390@de.ibm.com");
+                DEV_MESSAGE (KERN_ERR, device, "%s",      
+                             "Set device to suspended duplex state should be "
+                             "done!\n"
+                             "This is not implemented yet (for compound ERP)"
+                             " - please report to linux390@de.ibm.com");
                 
         }
 
@@ -2490,10 +2556,10 @@
 		switch (sense[25]) {
 
 		case 0x00:	/* success */
-                        DASD_MESSAGE (KERN_DEBUG, device,
-                                      "ERP called for successful request %p"
-                                      " - NO ERP necessary",
-                                      erp);
+                        DEV_MESSAGE (KERN_DEBUG, device,
+                                     "ERP called for successful request %p"
+                                     " - NO ERP necessary",
+                                     erp);
                         
                         erp = dasd_3990_erp_cleanup (erp,
                                                      CQR_STATUS_DONE);
@@ -2501,9 +2567,9 @@
                         break;
                         
 		case 0x01:	/* fatal error */
-                        DASD_MESSAGE (KERN_ERR, device, "%s",
-                                      "Fatal error should have been "
-                                      "handled within the interrupt handler");
+                        DEV_MESSAGE (KERN_ERR, device, "%s",
+                                     "Fatal error should have been "
+                                     "handled within the interrupt handler");
 
                         erp = dasd_3990_erp_cleanup (erp,
                                                      CQR_STATUS_FAILED);
@@ -2515,12 +2581,12 @@
                         break;
 
 		case 0x0F:	/* length mismatch during update write command */
-                        DASD_MESSAGE (KERN_ERR, device, "%s",
-                                      "update write command error - should not "
-                                      "happen;\n"
-                                      "Please send this message together with "
-                                      "the above sense data to linux390@de."
-                                      "ibm.com");
+                        DEV_MESSAGE (KERN_ERR, device, "%s",
+                                     "update write command error - should not "
+                                     "happen;\n"
+                                     "Please send this message together with "
+                                     "the above sense data to linux390@de."
+                                     "ibm.com");
 
                         erp = dasd_3990_erp_cleanup (erp,
                                                      CQR_STATUS_FAILED);
@@ -2532,12 +2598,12 @@
                         break;
 
 		case 0x15:	/* next track outside defined extend */
-                        DASD_MESSAGE (KERN_ERR, device, "%s",
-                                      "next track outside defined extend - "
-                                      "should not happen;\n"
-                                      "Please send this message together with "
-                                      "the above sense data to linux390@de."
-                                      "ibm.com");
+                        DEV_MESSAGE (KERN_ERR, device, "%s",
+                                     "next track outside defined extend - "
+                                     "should not happen;\n"
+                                     "Please send this message together with "
+                                     "the above sense data to linux390@de."
+                                     "ibm.com");
 
                         erp= dasd_3990_erp_cleanup (erp,
                                                     CQR_STATUS_FAILED);
@@ -2550,9 +2616,9 @@
                         break;
 
 		case 0x1C:	/* invalid data */
-                        DASD_MESSAGE (KERN_EMERG, device, "%s",
-                                      "Data recovered during retry with PCI "
-                                      "fetch mode active");
+                        DEV_MESSAGE (KERN_EMERG, device, "%s",
+                                     "Data recovered during retry with PCI "
+                                     "fetch mode active");
                         
                         /* not possible to handle this situation in Linux */    
                         panic("Invalid data - No way to inform appliction about "
@@ -2560,16 +2626,16 @@
 			break;
 
 		case 0x1D:	/* state-change pending */
-                        DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                                      "A State change pending condition exists "
-                                      "for the subsystem or device");
+                        DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                                     "A State change pending condition exists "
+                                     "for the subsystem or device");
 
                         erp = dasd_3990_erp_action_4 (erp,
                                                       sense);
 			break;
 
-		default:	/* all others errors - default erp  */
-                        
+		default:	
+                        ;       /* all others errors - default erp  */
 		}
 	}
 
@@ -2642,25 +2708,47 @@
 {
 
 	dasd_device_t *device = cqr->device;
+	ccw1_t *ccw;
 
 	/* allocate additional request block */
-	ccw_req_t *erp = dasd_alloc_request ((char *) &cqr->magic, 1, 0, cqr->device);
+	ccw_req_t *erp = dasd_alloc_request ((char *) &cqr->magic, 2, 0, cqr->device);
 
 	if (!erp) {
-
-                DASD_MESSAGE (KERN_ERR, device, "%s",
-                              "Unable to allocate ERP request");
+                if (cqr->retries <= 0) {
+                        DEV_MESSAGE (KERN_ERR, device, "%s",
+                                     "Unable to allocate ERP request (NO retries left)");
                 
-                check_then_set (&cqr->status,
-                                CQR_STATUS_ERROR,
-                                CQR_STATUS_FAILED);
+                        check_then_set (&cqr->status,
+                                        CQR_STATUS_ERROR,
+                                        CQR_STATUS_FAILED);
 
+                        cqr->stopclk = get_clock ();
+
+                } else {
+                        DEV_MESSAGE (KERN_ERR, device,
+                                     "Unable to allocate ERP request (%i retries left)",
+                                     cqr->retries);
+                
+                        if (!timer_pending(&device->timer)) {
+                                init_timer (&device->timer);
+                                device->timer.function = dasd_schedule_bh_timed;
+                                device->timer.data     = (unsigned long) device;
+                                device->timer.expires  = jiffies + (HZ << 3);
+                                add_timer (&device->timer);
+                        } else {
+                                mod_timer(&device->timer, jiffies + (HZ << 3));
+                        }
+                }
                 return cqr;
 	}
 
 	/* initialize request with default TIC to current ERP/CQR */
-	erp->cpaddr->cmd_code = CCW_CMD_TIC;
-	erp->cpaddr->cda      = (long)(cqr->cpaddr);
+	ccw = erp->cpaddr;
+	ccw->cmd_code = CCW_CMD_NOOP;
+	ccw->flags = CCW_FLAG_CC;
+	ccw++;
+	ccw->cmd_code = CCW_CMD_TIC;
+	ccw->cda      = (long)(cqr->cpaddr);
 	erp->function = dasd_3990_erp_add_erp;
 	erp->refers   = cqr;
 	erp->device   = cqr->device;
@@ -2738,7 +2826,7 @@
 	}
 
 	/* check sense data; byte 0-2,25,27 */
-	if (!((strncmp (cqr1->dstat->ii.sense.data,
+	if (!((memcmp (cqr1->dstat->ii.sense.data,
 			cqr2->dstat->ii.sense.data,
 			3) == 0) &&
 	      (cqr1->dstat->ii.sense.data[27] ==
@@ -2859,10 +2947,10 @@
                                 break;
                         }
                         default:
-                                DASD_MESSAGE (KERN_DEBUG, device,
-                                              "invalid subcommand modifier 0x%x "
-                                              "for Diagnostic Control Command",
-                                              sense[25]);
+                                DEV_MESSAGE (KERN_DEBUG, device,
+                                             "invalid subcommand modifier 0x%x "
+                                             "for Diagnostic Control Command",
+                                             sense[25]);
                         }
                 } 
 
@@ -2877,10 +2965,10 @@
 
 	} else {
                 /* no retry left and no additional special handling necessary */
-                DASD_MESSAGE (KERN_ERR, device,
-                              "no retries left for erp %p - "
-                              "set status to FAILED",
-                              erp);
+                DEV_MESSAGE (KERN_ERR, device,
+                             "no retries left for erp %p - "
+                             "set status to FAILED",
+                             erp);
 
 		check_then_set (&erp->status,
                                 CQR_STATUS_ERROR,
@@ -2940,7 +3028,7 @@
 
         if (erp->retries > 0) {
                 
-                char *sense = erp->dstat->ii.sense.data;
+                char *sense = erp->refers->dstat->ii.sense.data;
                 
                 /* check for special retries */
                 if (erp->function == dasd_3990_erp_action_4) {
@@ -2959,10 +3047,10 @@
                         
                 } else {
                         /* simple retry   */
-                        DASD_MESSAGE (KERN_DEBUG, device,
-                                      "%i retries left for erp %p",
-                                      erp->retries,
-                                      erp);
+                        DEV_MESSAGE (KERN_DEBUG, device,
+                                     "%i retries left for erp %p",
+                                     erp->retries,
+                                     erp);
                         
                         /* handle the request again... */
                         check_then_set (&erp->status,
@@ -3006,26 +3094,20 @@
         __u32         cpa     = cqr->dstat->cpa;    
 
 #ifdef ERP_DEBUG 
-        DASD_MESSAGE (KERN_DEBUG, device,
-                      "entering 3990 ERP for "
-                      "0x%04X on sch %d = /dev/%s ",
-                      device->devinfo.devno,
-                      device->devinfo.irq,
-                      device->name);
-
 	/* print current erp_chain */
-        DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                      "ERP chain at BEGINNING of ERP-ACTION");
+        DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                     "ERP chain at BEGINNING of ERP-ACTION");
         {
                 ccw_req_t *temp_erp = NULL;
+
                 for (temp_erp = cqr; 
                      temp_erp != NULL; 
                      temp_erp = temp_erp->refers){
 
-                        DASD_MESSAGE (KERN_DEBUG, device,
-                                      "      erp %p refers to %p",
-                                      temp_erp,
-                                      temp_erp->refers);
+                        DEV_MESSAGE (KERN_DEBUG, device,
+                                     "      erp %p refers to %p",
+                                     temp_erp,
+                                     temp_erp->refers);
                 }
         } 
 #endif /* ERP_DEBUG */
@@ -3034,10 +3116,10 @@
 	if ((cqr->dstat->cstat == 0x00                                 ) &&
 	    (cqr->dstat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))   ) {
 
-                DASD_MESSAGE (KERN_DEBUG, device,
-                              "ERP called for successful request %p"
-                              " - NO ERP necessary",
-                              cqr);
+                DEV_MESSAGE (KERN_DEBUG, device,
+                             "ERP called for successful request %p"
+                             " - NO ERP necessary",
+                             cqr);
                 
                 check_then_set (&cqr->status,
                                 CQR_STATUS_ERROR,
@@ -3047,10 +3129,10 @@
 	}
 	/* check if sense data are available */
 	if (!cqr->dstat->ii.sense.data) {
-		DASD_MESSAGE (KERN_DEBUG, device,
-			"ERP called witout sense data avail ..."
-			"request %p - NO ERP possible",
-			cqr);
+		DEV_MESSAGE (KERN_DEBUG, device,
+                             "ERP called witout sense data avail ..."
+                             "request %p - NO ERP possible",
+                             cqr);
 
                 check_then_set (&cqr->status,
                                 CQR_STATUS_ERROR,
@@ -3074,18 +3156,18 @@
 
 #ifdef ERP_DEBUG
 	/* print current erp_chain */
-        DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                      "ERP chain at END of ERP-ACTION");
+        DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                     "ERP chain at END of ERP-ACTION");
         {
                 ccw_req_t *temp_erp = NULL;
                 for (temp_erp = erp; 
                      temp_erp != NULL; 
                      temp_erp = temp_erp->refers) {
 
-                        DASD_MESSAGE (KERN_DEBUG, device,
-                                      "      erp %p refers to %p",
-                                      temp_erp,
-                                      temp_erp->refers);
+                        DEV_MESSAGE (KERN_DEBUG, device,
+                                     "      erp %p refers to %p",
+                                     temp_erp,
+                                     temp_erp->refers);
                 }
         }
 #endif /* ERP_DEBUG */
@@ -3098,35 +3180,32 @@
         }
 
         /* enqueue added ERP request */
-        if ((erp != cqr                      ) &&
+        if ((erp != device->queue.head ) &&
             (erp->status == CQR_STATUS_FILLED)   ){
 
                 dasd_chanq_enq_head (&device->queue,
                                      erp);
         } else {
-                if ((erp->status == CQR_STATUS_FILLED )||
-                    (erp != cqr                       )  ){
-                        /* something strange happened - log the error and throw a BUG() */
-                        DASD_MESSAGE (KERN_ERR, device, "%s",
-                                      "Problems with ERP chain!!! BUG");
-
+                if ((erp->status == CQR_STATUS_FILLED ) || (erp != device->queue.head)) {
+                        /* something strange happened - log the error and panic */
                         /* print current erp_chain */
-                        DASD_MESSAGE (KERN_DEBUG, device, "%s",
-                                      "ERP chain at END of ERP-ACTION");
+                        DEV_MESSAGE (KERN_DEBUG, device, "%s",
+                                     "ERP chain at END of ERP-ACTION");
                         {
                                 ccw_req_t *temp_erp = NULL;
                                 for (temp_erp = erp; 
                                      temp_erp != NULL; 
                                      temp_erp = temp_erp->refers) {
 
-                                        DASD_MESSAGE (KERN_DEBUG, device,
-                                                      "      erp %p (function %p) refers to %p",
-                                                      temp_erp,
-                                                      temp_erp->function,
-                                                      temp_erp->refers);
+                                        DEV_MESSAGE (KERN_DEBUG, device,
+                                                     "      erp %p (function %p)"
+                                                     " refers to %p",
+                                                     temp_erp,
+                                                     temp_erp->function,
+                                                     temp_erp->refers);
                                 }
                         }
-                        BUG();
+                        panic ("Problems with ERP chain!!! Please report to linux390@de.ibm.com");
                 }
 
         }
@@ -3136,112 +3215,6 @@
 } /* end dasd_3990_erp_action */
 
 /*
- * DASD_3990_ERP_POSTACTION
- *
- * DESCRIPTION
- *   Frees all ERPs of the current ERP Chain and set the status
- *   of the original CQR either to CQR_STATUS_DONE if ERP was successful
- *   or to CQR_STATUS_FAILED if ERP was NOT successful.
- *
- * PARAMETER
- *   erp                current erp_head
- *
- * RETURN VALUES
- *   cqr                pointer to the original CQR
- */
-ccw_req_t *
-dasd_3990_erp_postaction (ccw_req_t *erp)
-{
-
-	ccw_req_t     *cqr      = NULL, 
-                      *free_erp = NULL;
-	dasd_device_t *device   = erp->device;
-	int           success;
-
-	if (erp->refers   == NULL || 
-            erp->function == NULL   ) {
-
-		BUG ();
-	}
-
-	if (erp->status == CQR_STATUS_DONE)
-		success = 1;
-	else
-		success = 0;
-
-#ifdef ERP_DEBUG
-
-	/* print current erp_chain */
-	printk (KERN_DEBUG PRINTK_HEADER
-		"3990 ERP postaction called for erp chain:\n");
-	{
-		ccw_req_t *temp_erp = NULL;
-
-		for (temp_erp = erp; 
-                     temp_erp != NULL;
-		     temp_erp = temp_erp->refers) {
-
-			printk (KERN_DEBUG PRINTK_HEADER
-				"       erp %p refers to %p with erp function %p\n",
-				temp_erp, temp_erp->refers, temp_erp->function);
-		}
-	}
-
-#endif /* ERP_DEBUG */
-
-	/* free all ERPs - but NOT the original cqr */
-	while (erp->refers != NULL) {
-
-		free_erp = erp;
-		erp      = erp->refers;
-
-		/* remove the request from the device queue */
-		dasd_chanq_deq (&device->queue,
-                                free_erp);
-
-		/* free the finished erp request */
-		dasd_free_request (free_erp, free_erp->device);
-	}
-
-	/* save ptr to original cqr */
-	cqr = erp;
-
-	/* set corresponding status to original cqr */
-	if (success) {
-
-		check_then_set (&cqr->status, 
-                                CQR_STATUS_ERROR,
-				CQR_STATUS_DONE);
-	} else {
-
-		check_then_set (&cqr->status,
-				CQR_STATUS_ERROR, 
-                                CQR_STATUS_FAILED);
-	}
-
-#ifdef ERP_DEBUG
-	/* print current erp_chain */
-	printk (KERN_DEBUG PRINTK_HEADER
-		"3990 ERP postaction finished with remaining chain:\n");
-	{
-		ccw_req_t *temp_erp = NULL;
-
-		for (temp_erp = cqr; 
-                     temp_erp != NULL;
-		     temp_erp = temp_erp->refers) {
-
-			printk (KERN_DEBUG PRINTK_HEADER
-				" erp %p refers to %p \n", temp_erp,
-				temp_erp->refers);
-		}
-	}
-#endif /* ERP_DEBUG */
-
-	return cqr;
-
-} /* end dasd_3990_erp_postaction */
-
-/*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
  * adjust the settings for this buffer only.  This must remain at the end
diff -urN linux-2.4.22-pre2/drivers/s390/block/dasd_diag.c linux-2.4.22-pre3/drivers/s390/block/dasd_diag.c
--- linux-2.4.22-pre2/drivers/s390/block/dasd_diag.c	2001-09-30 12:26:07.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/block/dasd_diag.c	2003-07-05 18:10:26.000000000 -0700
@@ -5,13 +5,16 @@
  * ...............: by Hartmunt Penner <hpenner@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
-
+ *
+ * $Revision: 1.47 $
+ *
  * History of changes
  * 07/13/00 Added fixup sections for diagnoses ans saved some registers
  * 07/14/00 fixed constraints in newly generated inline asm
  * 10/05/00 adapted to 'new' DASD driver
  *          fixed return codes of dia250()
  *          fixed partition handling and HDIO_GETGEO
+ * 10/01/02 fixed Bugzilla 1341
  */
 
 #include <linux/config.h>
@@ -20,7 +23,7 @@
 #include <asm/debug.h>
 
 #include <linux/slab.h>
-#include <linux/hdreg.h>	/* HDIO_GETGEO                      */
+#include <linux/hdreg.h>
 #include <linux/blk.h>
 #include <asm/ccwcache.h>
 #include <asm/dasd.h>
@@ -29,6 +32,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/s390dyn.h>
+#include <asm/s390_ext.h>
 
 #include "dasd_int.h"
 #include "dasd_diag.h"
@@ -38,62 +42,50 @@
 #endif				/* PRINTK_HEADER */
 #define PRINTK_HEADER DASD_NAME"(diag):"
 
+#ifdef MODULE
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12))
+MODULE_LICENSE("GPL");
+#endif
+#endif
+
 dasd_discipline_t dasd_diag_discipline;
 
 typedef struct
     dasd_diag_private_t {
-	dasd_diag_characteristics_t rdc_data;
+	diag210_t rdc_data;
 	diag_rw_io_t iob;
 	diag_init_io_t iib;
 	unsigned long *label;
 } dasd_diag_private_t;
 
 static __inline__ int
-dia210 (void *devchar)
-{
-	int rc;
-
-	__asm__ __volatile__ ("    diag  %1,0,0x210\n"
-			      "0:  ipm   %0\n"
-			      "    srl   %0,28\n"
-			      "1:\n"
-			      ".section .fixup,\"ax\"\n"
-			      "2:  lhi   %0,3\n"
-			      "    bras  1,3f\n"
-			      "    .long 1b\n"
-			      "3:  l     1,0(1)\n"
-			      "    br    1\n"
-			      ".previous\n"
-			      ".section __ex_table,\"a\"\n"
-			      "    .align 4\n"
-			      "    .long 0b,2b\n" ".previous\n":"=d" (rc)
-			      :"d" ((void *) __pa (devchar))
-			      :"1");
-	return rc;
-}
-
-static __inline__ int
 dia250 (void *iob, int cmd)
 {
-	__asm__ __volatile__ ("    lr    0,%1\n"
-			      "    diag  0,%0,0x250\n"
+        unsigned long addr;
+        int rc;
+
+        addr = __pa(iob);
+	__asm__ __volatile__ ("    lhi   %0,11\n"
+                              "    lr    0,%2\n"
+			      "    diag  0,%1,0x250\n"
 			      "0:  ipm   %0\n"
 			      "    srl   %0,28\n"
 			      "    or    %0,1\n"
 			      "1:\n"
-			      ".section .fixup,\"ax\"\n"
-			      "2:  lhi   %0,3\n"
-			      "    bras  1,3f\n"
-			      "    .long 1b\n"
-			      "3:  l     1,0(1)\n"
-			      "    br    1\n"
-			      ".previous\n"
+#ifndef CONFIG_ARCH_S390X
 			      ".section __ex_table,\"a\"\n"
 			      "    .align 4\n"
-			      "    .long 0b,2b\n" ".previous\n":"+d" (cmd)
-			      :"d" ((void *) __pa (iob))
-			      :"0", "1", "cc");
-	return cmd;
+			      "    .long 0b,1b\n"
+                              ".previous\n"
+#else
+			      ".section __ex_table,\"a\"\n"
+			      "    .align 8\n"
+			      "    .quad  0b,1b\n"
+                              ".previous\n"
+#endif
+                              : "+&d" (rc)
+                              : "d" (cmd), "d" (addr) : "0", "1", "cc");
+	return rc;
 }
 
 static __inline__ int
@@ -144,13 +136,18 @@
 	iob->key = 0;
 	iob->flags = 2;
 	iob->block_count = cqr->cplength >> 1;
-	iob->interrupt_params = (u32) cqr;
+	iob->interrupt_params = (u32)(addr_t) cqr;
 	iob->bio_list = __pa (cqr->cpaddr);
 
-	asm volatile ("STCK %0":"=m" (cqr->startclk));
+	cqr->startclk = get_clock ();
+
 	rc = dia250 (iob, RW_BIO);
 	if (rc > 8) {
-		PRINT_WARN ("dia250 returned CC %d\n", rc);
+                
+		MESSAGE (KERN_WARNING,
+                         "dia250 returned CC %d", 
+                         rc);
+
 		check_then_set (&cqr->status,
 				CQR_STATUS_QUEUED, CQR_STATUS_ERROR);
 	} else if (rc == 0) {
@@ -176,41 +173,56 @@
 	int done_fast_io = 0;
 	int devno;
         unsigned long flags;
+	int subcode;
 
+	/*
+	 * Get the external interruption subcode. VM stores
+         * this in the 'cpu address' field associated with
+         * the external interrupt. For diag 250 the subcode
+         * needs to be 3.
+	 */
+	subcode = S390_lowcore.cpu_addr;
+	if ((subcode & 0xff00) != 0x0300)
+		return;
 
 	irq_enter(cpu, -1);
 
 	if (!ip) {		/* no intparm: unsolicited interrupt */
-		printk (KERN_WARNING PRINTK_HEADER
-			"caught unsolicited interrupt\n");
+
+		MESSAGE (KERN_DEBUG, "%s",
+                         "caught unsolicited interrupt");
+
 		irq_exit(cpu, -1);
 		return;
 	}
 	if (ip & 0x80000001) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"caught spurious interrupt with parm %08x\n", ip);
+
+		MESSAGE (KERN_DEBUG,
+                         "caught spurious interrupt with parm %08x",
+                         ip);
+
 		irq_exit(cpu, -1);
 		return;
 	}
-	cqr = (ccw_req_t *) ip;
+	cqr = (ccw_req_t *)(addr_t) ip;
 	device = (dasd_device_t *) cqr->device;
 
 	devno = device->devinfo.devno;
+
 	if (device == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			" INT on devno 0x%04X  = /dev/%s (%d:%d)"
-			" belongs to NULL device\n",
-			devno, device->name, MAJOR (device->kdev),
-			MINOR (device->kdev));
+
+		DEV_MESSAGE (KERN_WARNING, device, "%s",
+                             " belongs to NULL device");
 	}
+
 	if (strncmp (device->discipline->ebcname, (char *) &cqr->magic, 4)) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"0x%04X : /dev/%s (%d:%d)"
-			" magic number of ccw_req_t 0x%08X doesn't match"
-			" discipline 0x%08X\n",
-			devno, device->name,
-			MAJOR (device->kdev), MINOR (device->kdev),
-			cqr->magic, *(int *) (&device->discipline->name));
+
+		DEV_MESSAGE (KERN_WARNING, device,
+                             " magic number of ccw_req_t 0x%08X doesn't match"
+                             " discipline 0x%08X",
+                             cqr->magic, 
+                             *(int *) (&device->discipline->name));
+
 		irq_exit(cpu, -1);
 		return;
 	}
@@ -219,7 +231,7 @@
         s390irq_spin_lock_irqsave (device->devinfo.irq, 
                                    flags);
 
-	asm volatile ("STCK %0":"=m" (cqr->stopclk));
+	cqr->stopclk = get_clock ();
 
 	switch (status) {
 	case 0x00:
@@ -254,52 +266,60 @@
 {
 	int rc = 0;
 	int bsize;
-	int label_block;
 	dasd_diag_private_t *private;
-	dasd_diag_characteristics_t *rdc_data;
+	diag210_t *rdc_data;
 	ccw_req_t *cqr;
 	long *label;
 	int sb;
 
 	if (device == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"Null device pointer passed to characteristics checker\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+                         "Null device pointer passed to characteristics "
+                         "checker");
+
 		return -ENODEV;
 	}
 	device->private = kmalloc (sizeof (dasd_diag_private_t), GFP_KERNEL);
+
 	if (device->private == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"memory allocation failed for private data\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+                         "memory allocation failed for private data");
+
 		rc = -ENOMEM;
                 goto fail;
 	}
 	private = (dasd_diag_private_t *) device->private;
 	rdc_data = (void *) &(private->rdc_data);
 
-	rdc_data->dev_nr = device->devinfo.devno;
-	rdc_data->rdc_len = sizeof (dasd_diag_characteristics_t);
+	rdc_data->vrdcdvno = device->devinfo.devno;
+	rdc_data->vrdclen = sizeof (diag210_t);
 
-        rc = dia210 (rdc_data);
+        rc = diag210 (rdc_data);
 	if ( rc != 0) {
 		goto fail;
 	}
-	if (rdc_data->vdev_class != DEV_CLASS_FBA &&
-	    rdc_data->vdev_class != DEV_CLASS_ECKD &&
-	    rdc_data->vdev_class != DEV_CLASS_CKD) {
+	if (rdc_data->vrdcvcla != DEV_CLASS_FBA &&
+	    rdc_data->vrdcvcla != DEV_CLASS_ECKD &&
+	    rdc_data->vrdcvcla != DEV_CLASS_CKD) {
                 rc = -ENOTSUPP;
 		goto fail;
 	}
-#if 0
-	printk (KERN_INFO PRINTK_HEADER
-		"%04X: %04X on real %04X/%02X\n",
-		rdc_data->dev_nr,
-		rdc_data->vdev_type, rdc_data->rdev_type, rdc_data->rdev_model);
-#endif
+
+	DBF_EVENT (DBF_INFO,
+                   "%04X: %04X on real %04X/%02X",
+                   rdc_data->vrdcdvno,
+                   rdc_data->vrdcvtyp, 
+                   rdc_data->vrdccrty, 
+                   rdc_data->vrdccrmd);
+
+
 	/* Figure out position of label block */
-	if (private->rdc_data.vdev_class == DEV_CLASS_FBA) {
+	if (private->rdc_data.vrdcvcla == DEV_CLASS_FBA) {
 		device->sizes.pt_block = 1;
-	} else if (private->rdc_data.vdev_class == DEV_CLASS_ECKD ||
-		   private->rdc_data.vdev_class == DEV_CLASS_CKD) {
+	} else if (private->rdc_data.vrdcvcla == DEV_CLASS_ECKD ||
+		   private->rdc_data.vrdcvcla == DEV_CLASS_CKD) {
 		device->sizes.pt_block = 2;
 	} else {
                 BUG();
@@ -319,9 +339,12 @@
 		cqr = dasd_alloc_request (dasd_diag_discipline.name,
                                          sizeof (diag_bio_t) / sizeof (ccw1_t),
                                          0, device);
+
 		if (cqr == NULL) {
-			printk (KERN_WARNING PRINTK_HEADER
-				"No memory to allocate initialization request\n");
+
+			MESSAGE (KERN_WARNING, "%s",
+                                 "No memory to allocate initialization request");
+                        
 			free_page ((long) private->label);
                         rc = -ENOMEM;
                         goto fail;
@@ -334,11 +357,12 @@
 		cqr->device = device;
 		cqr->status = CQR_STATUS_FILLED;
 		memset (iob, 0, sizeof (diag_rw_io_t));
-		iob->dev_nr = rdc_data->dev_nr;
+		iob->dev_nr = rdc_data->vrdcdvno;
 		iob->block_count = 1;
-		iob->interrupt_params = (u32) cqr;
+		iob->interrupt_params = (u32)(addr_t) cqr;
 		iob->bio_list = __pa (bio);
 		rc = dia250 (iob, RW_BIO);
+		dasd_free_request(cqr, device);
 		if (rc == 0) {
 			if (label[3] != bsize ||
                             label[0] != 0xc3d4e2f1 ||	/* != CMS1 */
@@ -357,13 +381,16 @@
 	device->sizes.blocks = label[7];
 	device->sizes.bp_block = bsize;
 	device->sizes.s2b_shift = 0;	/* bits to shift 512 to get a block */
+
 	for (sb = 512; sb < bsize; sb = sb << 1)
+
 		device->sizes.s2b_shift++;
-	printk (KERN_INFO PRINTK_HEADER
-		"/dev/%s (%04X): capacity (%dkB blks): %ldkB\n",
-		device->name, device->devinfo.devno,
-		(device->sizes.bp_block >> 10),
-		(device->sizes.blocks << device->sizes.s2b_shift) >> 1);
+
+	DEV_MESSAGE (KERN_INFO, device,
+                     "capacity (%dkB blks): %ldkB",
+                     (device->sizes.bp_block >> 10),
+                     (device->sizes.blocks << device->sizes.s2b_shift) >> 1);
+
 	free_page ((long) private->label);
         rc = 0;
 	goto out;
@@ -380,12 +407,9 @@
 dasd_diag_fill_geometry (struct dasd_device_t *device, struct hd_geometry *geo)
 {
 	int rc = 0;
-	dasd_diag_private_t *private = (dasd_diag_private_t *) device->private;
 	unsigned long sectors = device->sizes.blocks << device->sizes.s2b_shift;
 	unsigned long tracks = sectors >> 6;
-	unsigned long trk_rem = sectors & ((1 << 6) - 1);	/* 64k per track */
 	unsigned long cyls = tracks >> 4;
-	unsigned long cyls_rem = tracks & ((1 << 4) - 1);	/* 16 head per cyl */
 
 	switch (device->sizes.bp_block) {
 	case 512:
@@ -420,14 +444,19 @@
 	diag_bio_t *bio;
 	int bhct;
 	long size;
+        unsigned long reloc_sector = req->sector + 
+                device->major_info->gendisk.part[MINOR (req->rq_dev)].start_sect;
 
 	if (!noblk) {
-		PRINT_ERR ("No blocks to read/write...returning\n");
-		return NULL;
+
+		MESSAGE (KERN_ERR, "%s",
+                         "No blocks to read/write...returning");
+
+		return ERR_PTR(-EINVAL);
 	}
 	if (req->cmd == READ) {
 		rw_cmd = MDSK_READ_REQ;
-	} else if (req->cmd == WRITE) {
+	} else {
 		rw_cmd = MDSK_WRITE_REQ;
 	}
 	bhct = 0;
@@ -439,11 +468,11 @@
 	/* Build the request */
 	rw_cp = dasd_alloc_request (dasd_diag_discipline.name, bhct << 1, 0, device);
 	if (!rw_cp) {
-		return NULL;
+		return  ERR_PTR(-ENOMEM);
 	}
 	bio = (diag_bio_t *) (rw_cp->cpaddr);
 
-	block = req->sector >> device->sizes.s2b_shift;
+	block = reloc_sector >> device->sizes.s2b_shift;
 	for (bh = req->bh; bh; bh = bh->b_reqnext) {
                 memset (bio, 0, sizeof (diag_bio_t));
                 for (size = 0; size < bh->b_size; size += byt_per_blk) {
@@ -454,7 +483,9 @@
                         block++;
                 }
 	}
-	asm volatile ("STCK %0":"=m" (rw_cp->buildclk));
+
+	rw_cp->buildclk = get_clock ();
+
 	rw_cp->device = device;
 	rw_cp->expires = 50 * TOD_SEC;	/* 50 seconds */
 	rw_cp->req = req;
@@ -463,14 +494,15 @@
 }
 
 static int
-dasd_diag_fill_info (dasd_device_t * device, dasd_information_t * info)
+dasd_diag_fill_info (dasd_device_t * device, dasd_information2_t * info)
 {
 	int rc = 0;
 	info->FBA_layout = 1;
-	info->characteristics_size = sizeof (dasd_diag_characteristics_t);
+	info->format = DASD_FORMAT_LDL;
+	info->characteristics_size = sizeof (diag210_t);
 	memcpy (info->characteristics,
 		&((dasd_diag_private_t *) device->private)->rdc_data,
-		sizeof (dasd_diag_characteristics_t));
+		sizeof (diag210_t));
 	info->confdata_size = 0;
 	return rc;
 }
@@ -501,26 +533,32 @@
 	examine_error:dasd_diag_examine_error,
 	build_cp_from_req:dasd_diag_build_cp_from_req,
 	dump_sense:dasd_diag_dump_sense,
-	int_handler:dasd_ext_handler,
+	int_handler:(void *) dasd_ext_handler,
 	fill_info:dasd_diag_fill_info,
+	list:LIST_HEAD_INIT(dasd_diag_discipline.list),
 };
 
 int
 dasd_diag_init (void)
 {
 	int rc = 0;
+
 	if (MACHINE_IS_VM) {
-		printk (KERN_INFO PRINTK_HEADER
-			"%s discipline initializing\n",
-			dasd_diag_discipline.name);
+
+		MESSAGE (KERN_INFO,
+                         "%s discipline initializing",
+                         dasd_diag_discipline.name);
+
 		ASCEBC (dasd_diag_discipline.ebcname, 4);
 		ctl_set_bit (0, 9);
 		register_external_interrupt (0x2603, dasd_ext_handler);
 		dasd_discipline_add (&dasd_diag_discipline);
 	} else {
-		printk (KERN_INFO PRINTK_HEADER
-			"Machine is not VM: %s discipline not initializing\n",
-			dasd_diag_discipline.name);
+
+		MESSAGE (KERN_INFO,
+			"Machine is not VM: %s discipline not initializing",
+                         dasd_diag_discipline.name);
+
 		rc = -EINVAL;
 	}
 	return rc;
@@ -530,16 +568,19 @@
 dasd_diag_cleanup (void)
 {
 	if (MACHINE_IS_VM) {
-		printk (KERN_INFO PRINTK_HEADER
-			"%s discipline cleaning up\n",
-			dasd_diag_discipline.name);
+
+		MESSAGE (KERN_INFO,
+                         "%s discipline cleaning up",
+                         dasd_diag_discipline.name);
+
 		dasd_discipline_del (&dasd_diag_discipline);
 		unregister_external_interrupt (0x2603, dasd_ext_handler);
 		ctl_clear_bit (0, 9);
 	} else {
-		printk (KERN_INFO PRINTK_HEADER
-			"Machine is not VM: %s discipline not initializing\n",
-			dasd_diag_discipline.name);
+
+		MESSAGE (KERN_INFO,
+                         "Machine is not VM: %s discipline not initializing",
+                         dasd_diag_discipline.name);
 	}
 }
 
diff -urN linux-2.4.22-pre2/drivers/s390/block/dasd_diag.h linux-2.4.22-pre3/drivers/s390/block/dasd_diag.h
--- linux-2.4.22-pre2/drivers/s390/block/dasd_diag.h	2001-08-05 13:12:41.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/block/dasd_diag.h	2003-07-05 18:10:26.000000000 -0700
@@ -5,6 +5,11 @@
  * ...............: by Hartmunt Penner <hpenner@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ *
+ * $Revision: 1.7 $
+ *
+ * History of changes
+ *
  */
 
 #define MDSK_WRITE_REQ 0x01
@@ -18,21 +23,6 @@
 #define DEV_CLASS_ECKD  0x04
 #define DEV_CLASS_CKD   0x04
 
-typedef struct dasd_diag_characteristics_t {
-	u16 dev_nr;
-	u16 rdc_len;
-	u8 vdev_class;
-	u8 vdev_type;
-	u8 vdev_status;
-	u8 vdev_flags;
-	u8 rdev_class;
-	u8 rdev_type;
-	u8 rdev_model;
-	u8 rdev_features;
-} __attribute__ ((packed, aligned (4)))
-
-    dasd_diag_characteristics_t;
-
 typedef struct diag_bio_t {
 	u8 type;
 	u8 status;
diff -urN linux-2.4.22-pre2/drivers/s390/block/dasd_eckd.c linux-2.4.22-pre3/drivers/s390/block/dasd_eckd.c
--- linux-2.4.22-pre2/drivers/s390/block/dasd_eckd.c	2002-02-25 11:38:03.000000000 -0800
+++ linux-2.4.22-pre3/drivers/s390/block/dasd_eckd.c	2003-07-05 18:10:26.000000000 -0700
@@ -1,10 +1,13 @@
 /* 
  * File...........: linux/drivers/s390/block/dasd_eckd.c
  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
-                    Carsten Otte <Cotte@de.ibm.com>
+ *                  Horst Hummel <Horst.Hummel@de.ibm.com> 
+ *                  Carsten Otte <Cotte@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
-
+ *
+ * $Revision $
+ *
  * History of changes (starts July 2000)
  * 07/11/00 Enabled rotational position sensing
  * 07/14/00 Reorganized the format process for better ERP
@@ -42,7 +45,6 @@
 #undef PRINTK_HEADER
 #endif				/* PRINTK_HEADER */
 #define PRINTK_HEADER DASD_NAME"(eckd):"
-#undef CDL_PRINTK
 
 #define ECKD_C0(i) (i->home_bytes)
 #define ECKD_F(i) (i->formula)
@@ -55,21 +57,27 @@
 #define ECKD_F7(i) (i->factor7)
 #define ECKD_F8(i) (i->factor8)
 
+#ifdef MODULE
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12))
+MODULE_LICENSE("GPL");
+#endif
+#endif
+
 dasd_discipline_t dasd_eckd_discipline;
 
-typedef struct
-dasd_eckd_private_t {
+typedef struct dasd_eckd_private_t {
 	dasd_eckd_characteristics_t rdc_data;
-	dasd_eckd_confdata_t conf_data;
-	eckd_count_t count_area[5];
-	int uses_cdl;
+	dasd_eckd_confdata_t        conf_data;
+	eckd_count_t                count_area[5];
+	int                         uses_cdl;
+        attrib_data_t               attrib;     /* e.g. cache operations */
 } dasd_eckd_private_t;
 
 #ifdef CONFIG_DASD_DYNAMIC
 static
 devreg_t dasd_eckd_known_devices[] = {
         {
-                ci: { hc: {ctype:0x3880, dtype: 3390}},
+                ci: { hc: {ctype:0x3880, dtype: 0x3390}},
                 flag:(DEVREG_MATCH_CU_TYPE | DEVREG_MATCH_DEV_TYPE | 
                       DEVREG_TYPE_DEVCHARS),
                 oper_func:dasd_oper_handler
@@ -143,7 +151,10 @@
 			break;
 		}
 	default:
-		INTERNAL_ERROR ("unknown formula%d\n", rdc->formula);
+
+		MESSAGE (KERN_ERR,
+                         "unknown formula%d", 
+                         rdc->formula);
 	}
 	return bpr;
 }
@@ -190,10 +201,35 @@
 	return rpt;
 }
 
+static inline void
+check_XRC (ccw1_t         *de_ccw,
+           DE_eckd_data_t *data,
+           dasd_device_t  *device)
+{
+        
+	dasd_eckd_private_t *private = (dasd_eckd_private_t *) device->private;
+
+        /* switch on System Time Stamp - needed for XRC Support */
+        if (private->rdc_data.facilities.XRC_supported) {
+                
+                data->ga_extended |= 0x08;   /* switch on 'Time Stamp Valid'   */
+                data->ga_extended |= 0x02;   /* switch on 'Extended Parameter' */
+                
+                data->ep_sys_time = get_clock ();
+                
+                de_ccw->count = sizeof (DE_eckd_data_t);
+                de_ccw->flags |= CCW_FLAG_SLI;  
+        }
+
+        return;
+
+} /* end check_XRC */
+
 static inline int
 define_extent (ccw1_t * de_ccw,
 	       DE_eckd_data_t * data,
-	       int trk, int totrk, int cmd, dasd_device_t * device, ccw_req_t* cqr)
+	       int trk, int totrk, 
+               int cmd, dasd_device_t * device, ccw_req_t* cqr)
 {
         int rc=0;
 	ch_t geo, beg, end;
@@ -207,8 +243,10 @@
 	end.head = totrk % geo.head;
 
 	memset (de_ccw, 0, sizeof (ccw1_t));
+
 	de_ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;
 	de_ccw->count = 16;
+
 	if ((rc=dasd_set_normalized_cda (de_ccw, __pa (data), cqr, device))) 
                 return rc;
 
@@ -224,40 +262,86 @@
 	case DASD_ECKD_CCW_READ_KD_MT:
 	case DASD_ECKD_CCW_READ_COUNT:
 		data->mask.perm = 0x1;
-		data->attributes.operation = 0x3;	/* enable seq. caching */
+		data->attributes.operation = private->attrib.operation;
 		break;
 	case DASD_ECKD_CCW_WRITE:
 	case DASD_ECKD_CCW_WRITE_MT:
 	case DASD_ECKD_CCW_WRITE_KD:
 	case DASD_ECKD_CCW_WRITE_KD_MT:
 		data->mask.perm = 0x02;
-		data->attributes.operation = 0x3;	/* enable seq. caching */
+		data->attributes.operation = private->attrib.operation;
+
+                check_XRC (de_ccw,
+                           data,
+                           device);
 		break;
 	case DASD_ECKD_CCW_WRITE_CKD:
 	case DASD_ECKD_CCW_WRITE_CKD_MT:
-		data->attributes.operation = 0x1;	/* format through cache */
+		data->attributes.operation = DASD_BYPASS_CACHE;
+
+                check_XRC (de_ccw,
+                           data,
+                           device);
 		break;
 	case DASD_ECKD_CCW_ERASE:
 	case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
 	case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
 		data->mask.perm = 0x3;
 		data->mask.auth = 0x1;
-		data->attributes.operation = 0x1;	/* format through cache */
+		data->attributes.operation = DASD_BYPASS_CACHE;
+
+                check_XRC (de_ccw,
+                           data,
+                           device);
 		break;
 	default:
-		INTERNAL_ERROR ("unknown opcode 0x%x\n", cmd);
+
+		MESSAGE (KERN_ERR,
+                         "unknown opcode 0x%x", 
+                         cmd);
+
 		break;
 	}
-	data->attributes.mode = 0x3;
+
+	data->attributes.mode = 0x3; /* ECKD */
+
 	if (private->rdc_data.cu_type == 0x2105
-	    && !(private->uses_cdl && trk < 2)
-	    ) {
-		data->reserved |= 0x40;
+	    && !(private->uses_cdl && trk < 2) ) {
+                
+		data->ga_extended |= 0x40;
 	}
-	data->beg_ext.cyl = beg.cyl;
+        
+        /* check for sequential prestage - enhance cylinder range */
+        if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
+            data->attributes.operation == DASD_SEQ_ACCESS     ) {
+                
+                if (end.cyl + private->attrib.nr_cyl < geo.cyl) {
+
+                        end.cyl +=  private->attrib.nr_cyl; 
+
+                        DBF_DEV_EVENT (DBF_NOTICE, device,
+                                       "Enhanced DE Cylinder from  %x to %x",
+                                       (totrk / geo.head),
+                                       end.cyl);
+
+
+                } else {
+                        end.cyl = (geo.cyl -1);
+
+                        DBF_DEV_EVENT (DBF_NOTICE, device,
+                                       "Enhanced DE Cylinder from  %x to "
+                                       "End of device %x",
+                                       (totrk / geo.head),
+                                       end.cyl);
+
+                }
+        }
+
+	data->beg_ext.cyl  = beg.cyl;
 	data->beg_ext.head = beg.head;
-	data->end_ext.cyl = end.cyl;
+	data->end_ext.cyl  = end.cyl;
 	data->end_ext.head = end.head;
+
         return rc;
 }
 
@@ -266,7 +350,11 @@
 	       LO_eckd_data_t * data,
 	       int trk,
 	       int rec_on_trk,
-	       int no_rec, int cmd, dasd_device_t * device, int reclen, ccw_req_t* cqr)
+	       int no_rec, 
+               int cmd, 
+               dasd_device_t * device, 
+               int reclen, 
+               ccw_req_t* cqr)
 {
         int rc=0;
 	dasd_eckd_private_t *private = (dasd_eckd_private_t *) device->private;
@@ -276,10 +364,14 @@
 	ch_t seek = { trk / (geo.head), trk % (geo.head) };
 	int sector = 0;
 
-#ifdef CDL_PRINTK
-	printk ("Locate: trk %d, rec %d, no_rec %d, cmd %d, reclen %d\n", trk,
-		rec_on_trk, no_rec, cmd, reclen);
-#endif
+        DBF_EVENT (DBF_INFO, 
+                   "Locate: trk %d, rec %d, no_rec %d, cmd %d, reclen %d",
+                   trk,
+                   rec_on_trk, 
+                   no_rec, 
+                   cmd, 
+                   reclen);
+
 	memset (lo_ccw, 0, sizeof (ccw1_t));
 	lo_ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;
 	lo_ccw->count = 16;
@@ -365,7 +457,10 @@
 		data->operation.operation = 0x0b;
 		break;
 	default:
-		INTERNAL_ERROR ("unknown opcode 0x%x\n", cmd);
+
+                MESSAGE (KERN_ERR,
+                         "unknown opcode 0x%x",
+                         cmd);
 	}
 	memcpy (&(data->seek_addr), &seek, sizeof (ch_t));
 	memcpy (&(data->search_arg), &seek, sizeof (ch_t));
@@ -391,79 +486,113 @@
 static int
 dasd_eckd_check_characteristics (struct dasd_device_t *device)
 {
-	int rc = 0;
+	int   rc = 0;
 	void *conf_data;
-	void *rdc_data;
-	int conf_len;
+        void *rdc_data;
+	int   conf_len;
 	dasd_eckd_private_t *private;
 
 	if (device == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"Null device pointer passed to characteristics checker\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+                         "Null device pointer passed to characteristics "
+                         "checker");
+
                 return -ENODEV;
 	}
-	device->private = kmalloc (sizeof (dasd_eckd_private_t), GFP_KERNEL);
+	device->private = kmalloc (sizeof (dasd_eckd_private_t), 
+                                   GFP_KERNEL);
+
 	if (device->private == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"memory allocation failed for private data\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+			"memory allocation failed for private data");
+
 		rc = -ENOMEM;
                 goto fail;
 	}
-	private = (dasd_eckd_private_t *) device->private;
+
+	private  = (dasd_eckd_private_t *) device->private;
 	rdc_data = (void *) &(private->rdc_data);
-	rc = read_dev_chars (device->devinfo.irq, &rdc_data, 64);
+
+        /* Read Device Characteristics */
+	rc = read_dev_chars (device->devinfo.irq, 
+                             &rdc_data, 
+                             64);
 	if (rc) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"Read device characteristics returned error %d\n", rc);
+
+		MESSAGE (KERN_WARNING,
+			"Read device characteristics returned error %d",
+                         rc);
+
                 goto fail;
         }
-	printk (KERN_INFO PRINTK_HEADER
-		"%04X on sch %d: %04X/%02X(CU:%04X/%02X) "
-                "Cyl:%d Head:%d Sec:%d\n",
-		device->devinfo.devno, device->devinfo.irq,
-		private->rdc_data.dev_type, private->rdc_data.dev_model,
-		private->rdc_data.cu_type, private->rdc_data.cu_model.model,
-		private->rdc_data.no_cyl, private->rdc_data.trk_per_cyl,
-		private->rdc_data.sec_per_trk);
-	rc = read_conf_data (device->devinfo.irq, &conf_data, &conf_len,
+
+        DEV_MESSAGE (KERN_INFO, device,
+                     "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
+                     private->rdc_data.dev_type, 
+                     private->rdc_data.dev_model,
+                     private->rdc_data.cu_type, 
+                     private->rdc_data.cu_model.model,
+                     private->rdc_data.no_cyl, 
+                     private->rdc_data.trk_per_cyl,
+                     private->rdc_data.sec_per_trk);
+
+        /* set default cache operations */
+        private->attrib.operation = DASD_SEQ_ACCESS;
+        private->attrib.nr_cyl    = 0x02;
+        
+        /* Read Configuration Data */
+        rc = read_conf_data (device->devinfo.irq, 
+                             &conf_data, 
+                             &conf_len,
                              LPM_ANYPATH);
 
         if (rc == -EOPNOTSUPP) {
                 rc = 0; /* this one is ok */
         }
 	if (rc) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"Read configuration data returned error %d\n", rc);
+
+		MESSAGE (KERN_WARNING,
+                         "Read configuration data returned error %d",
+                         rc);
+
                 goto fail;
 	}
         if (conf_data == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"No configuration data retrieved\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+                         "No configuration data retrieved");
+
                 goto out; /* no errror */
 	} 
         if (conf_len != sizeof (dasd_eckd_confdata_t)) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"sizes of configuration data mismatch"
-                        "%d (read) vs %ld (expected)\n",
-			conf_len, sizeof (dasd_eckd_confdata_t));
+
+		MESSAGE (KERN_WARNING,
+                         "sizes of configuration data mismatch"
+                         "%d (read) vs %ld (expected)",
+                         conf_len, 
+                         sizeof (dasd_eckd_confdata_t));
+
                 goto out; /* no errror */
 	} 
         memcpy (&private->conf_data, conf_data, 
                 sizeof (dasd_eckd_confdata_t));
-        printk (KERN_INFO PRINTK_HEADER
-                "%04X on sch %d: %04X/%02X(CU:%04X/%02X): "
-                "Configuration data read\n",
-                device->devinfo.devno, device->devinfo.irq,
+
+        DEV_MESSAGE (KERN_INFO, device,
+                "%04X/%02X(CU:%04X/%02X): Configuration data read",
                 private->rdc_data.dev_type, 
                 private->rdc_data.dev_model,
                 private->rdc_data.cu_type, 
                 private->rdc_data.cu_model.model);
         goto out;
+
  fail:
-        if ( rc ) {
+        if (device->private) {
                 kfree (device->private);
                 device->private = NULL;
         }
+        
  out:
 	return rc;
 }
@@ -498,8 +627,9 @@
 				 2 * sizeof (LO_eckd_data_t),
                                  device);
 	if (cqr == NULL) {
-                printk (KERN_WARNING PRINTK_HEADER
-                        "No memory to allocate initialization request\n");
+
+                MESSAGE (KERN_WARNING, "%s",
+                        "No memory to allocate initialization request");
                 goto out;
 	}
 	DE_data = cqr->data;
@@ -557,13 +687,17 @@
         }
 	cqr->device = device;
 	cqr->retries = 0;
+        cqr->buildclk = get_clock ();
 	cqr->status = CQR_STATUS_FILLED;
         dasd_chanq_enq (&device->queue, cqr);
         goto out;
+
  clear_cqr:
         dasd_free_request (cqr,device);
-        printk (KERN_WARNING PRINTK_HEADER
-                "No memory to allocate initialization request\n");
+
+        MESSAGE (KERN_WARNING, "%s",
+                "No memory to allocate initialization request");
+
         cqr=NULL;
  out:
 	return cqr;
@@ -578,14 +712,17 @@
 	char *cdl_msg;
         int status;
 	int i;
+
 	private->uses_cdl = 1;
         status = device->init_cqr->status;
 	dasd_chanq_deq (&device->queue, device->init_cqr);
 	dasd_free_request (device->init_cqr, device);
 	/* Free the cqr and cleanup device->sizes */
         if ( status != CQR_STATUS_DONE ) {
-                DASD_MESSAGE (KERN_WARNING,device,"%s",
-                              "volume analysis returned unformatted disk");
+
+                DEV_MESSAGE (KERN_WARNING, device, "%s",
+                             "volume analysis returned unformatted disk");
+
                 return -EMEDIUMTYPE;
         }
 	/* Check Track 0 for Compatible Disk Layout */
@@ -614,8 +751,9 @@
 		}
 	} else {
 		if (private->count_area[3].record == 1) {
-			DASD_MESSAGE (KERN_WARNING, device, "%s",
-				      "Trk 0: no records after VTOC!");
+
+			DEV_MESSAGE (KERN_WARNING, device, "%s",
+                                     "Trk 0: no records after VTOC!");
 		}
 	}
 	if (count_area != NULL &&	/* we found notthing violating our disk layout */
@@ -631,8 +769,10 @@
 		}
 	}
 	if (device->sizes.bp_block == 0) {
-		DASD_MESSAGE (KERN_WARNING, device, "%s",
-			      "Volume has incompatible disk layout");
+
+		DEV_MESSAGE (KERN_WARNING, device, "%s",
+                             "Volume has incompatible disk layout");
+
 		return -EMEDIUMTYPE;
 	}
 	device->sizes.s2b_shift = 0;	/* bits to shift 512 to get a block */
@@ -647,18 +787,21 @@
 						device->sizes.bp_block));
 	cdl_msg =
 	    private->
-	    uses_cdl ? "compatible disk layout" : "classic disk layout";
+	    uses_cdl ? "compatible disk layout" : "linux disk layout";
+
+	DEV_MESSAGE (KERN_INFO, device, 
+                     "(%dkB blks): %dkB at %dkB/trk %s",
+                     (device->sizes.bp_block >> 10),
+                     ((private->rdc_data.no_cyl *
+                       private->rdc_data.trk_per_cyl *
+                       recs_per_track (&private->rdc_data, 0,
+                                       device->sizes.bp_block) *
+                       (device->sizes.bp_block >> 9)) >> 1),
+                     ((recs_per_track (&private->rdc_data, 0,
+                                       device->sizes.bp_block) *
+                       device->sizes.bp_block) >> 10),
+                     cdl_msg);
 
-	DASD_MESSAGE (KERN_INFO, device, "(%dkB blks): %dkB at %dkB/trk %s",
-		      (device->sizes.bp_block >> 10),
-		      (private->rdc_data.no_cyl *
-		       private->rdc_data.trk_per_cyl *
-		       recs_per_track (&private->rdc_data, 0,
-				       device->sizes.bp_block) *
-		       (device->sizes.bp_block >> 9)) >> 1,
-		      (recs_per_track (&private->rdc_data, 0,
-				       device->sizes.bp_block) *
-		       device->sizes.bp_block) >> 10, cdl_msg);
 	return 0;
 }
 
@@ -703,13 +846,21 @@
 	int wrccws = rpt;
 	int datasize = sizeof (DE_eckd_data_t) + sizeof (LO_eckd_data_t);
         
-	if (fdata->start_unit >= (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)){
-                DASD_MESSAGE (KERN_INFO, device, "Track no %d too big!", fdata->start_unit);
+	if (fdata->start_unit >= 
+            (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)){
+
+                DEV_MESSAGE (KERN_INFO, device, 
+                             "Track no %d too big!", 
+                             fdata->start_unit);
+
                 return NULL;
         }
         if ( fdata->start_unit > fdata->stop_unit) {
-                DASD_MESSAGE (KERN_INFO, device, "Track %d reached! ending.",
-                              fdata->start_unit);
+
+                DEV_MESSAGE (KERN_INFO, device, 
+                             "Track %d reached! ending.",
+                             fdata->start_unit);
+
 		return NULL;
 	}
 	switch (fdata->blksize) {
@@ -719,8 +870,11 @@
 	case 4096:
 		break;
 	default:
-		printk (KERN_WARNING PRINTK_HEADER
-			"Invalid blocksize %d...terminating!\n", fdata->blksize);
+
+		MESSAGE (KERN_WARNING,
+                         "Invalid blocksize %d...terminating!", 
+                         fdata->blksize);
+
 		return NULL;
 	}
 	switch (fdata->intensity) {
@@ -734,8 +888,11 @@
 	case 0x0c:
 		break;
 	default:
-		printk (KERN_WARNING PRINTK_HEADER
-			"Invalid flags 0x%x...terminating!\n", fdata->intensity);
+
+		MESSAGE (KERN_WARNING,
+                         "Invalid flags 0x%x...terminating!", 
+                         fdata->intensity);
+
 		return NULL;
 	}
 
@@ -745,9 +902,12 @@
 	    (fdata->start_unit % private->rdc_data.no_cyl == 0 &&
 	     (fdata->start_unit / private->rdc_data.no_cyl) %
 	     (private->rdc_data.no_cyl / 20))) {
-		DASD_MESSAGE (KERN_INFO, device,
-			      "Format Cylinder: %d Flags: %d",
-			      fdata->start_unit / private->rdc_data.trk_per_cyl, fdata->intensity);
+
+		DBF_DEV_EVENT (DBF_NOTICE, device,
+                               "Format Cylinder: %d Flags: %d",
+                               fdata->start_unit / private->rdc_data.trk_per_cyl,
+                               fdata->intensity);
+
 	}
 	if ((fdata->intensity & ~0x8) & 0x04) {
 		wrccws = 1;
@@ -789,14 +949,14 @@
 		switch (fdata->intensity & ~0x08) {
 		case 0x03:
 			if (define_extent (last_ccw, DE_data, fdata->start_unit, fdata->start_unit,
-				       DASD_ECKD_CCW_WRITE_HOME_ADDRESS,
+                                           DASD_ECKD_CCW_WRITE_HOME_ADDRESS,
                                            device, fcp)) {
                                 goto clear_fcp;
                         }
 			last_ccw->flags |= CCW_FLAG_CC;
 			last_ccw++;
 			if (locate_record (last_ccw, LO_data, fdata->start_unit, 0, wrccws,
-				       DASD_ECKD_CCW_WRITE_HOME_ADDRESS, device,
+                                           DASD_ECKD_CCW_WRITE_HOME_ADDRESS, device,
                                            device->sizes.bp_block, fcp)) {
                                 goto clear_fcp;
                         }
@@ -811,7 +971,7 @@
 			last_ccw->flags |= CCW_FLAG_CC;
 			last_ccw++;
 			if (locate_record (last_ccw, LO_data, fdata->start_unit, 0, wrccws,
-				       DASD_ECKD_CCW_WRITE_RECORD_ZERO, device,
+                                           DASD_ECKD_CCW_WRITE_RECORD_ZERO, device,
                                            device->sizes.bp_block, fcp)) {
                                 goto clear_fcp;
                         }
@@ -837,11 +997,19 @@
 			last_ccw++;
 			break;
 		default:
-			PRINT_WARN ("Unknown format flags...%d\n", fdata->intensity);
+
+			MESSAGE (KERN_WARNING,
+                                 "Unknown format flags...%d", 
+                                 fdata->intensity);
+
 			return NULL;
 		}
 		if (fdata->intensity & 0x02) {
-			PRINT_WARN ("Unsupported format flag...%d\n", fdata->intensity);
+
+			MESSAGE (KERN_WARNING,
+                                 "Unsupported format flag...%d", 
+                                 fdata->intensity);
+
 			return NULL;
 		}
 		if (fdata->intensity & 0x01) {	/* write record zero */
@@ -913,6 +1081,7 @@
 		}
 		(last_ccw - 1)->flags &= ~(CCW_FLAG_CC | CCW_FLAG_DC);
 		fcp->device = device;
+                fcp->buildclk = get_clock ();
 		fcp->status = CQR_STATUS_FILLED;
 	}
         goto out;
@@ -939,8 +1108,10 @@
 	case 0x9343:
 		return dasd_9343_erp_examine (cqr, stat);
 	default:
-		printk (KERN_WARNING PRINTK_HEADER
-			"default (unknown CU type) - RECOVERABLE return \n");
+
+		MESSAGE (KERN_WARNING, "%s",
+                         "default (unknown CU type) - RECOVERABLE return");
+
 		return dasd_era_recover;
 	}
 }
@@ -1015,26 +1186,36 @@
 	int byt_per_blk = device->sizes.bp_block;
 	int shift = device->sizes.s2b_shift;
 	int blk_per_trk = recs_per_track (&(private->rdc_data), 0, byt_per_blk);
-	int btrk = (req->sector >> shift) / blk_per_trk;
-	int etrk = ((req->sector + req->nr_sectors - 1) >> shift) / blk_per_trk;
-	int recid = req->sector >> shift;
+        unsigned long reloc_sector = req->sector + 
+                device->major_info->gendisk.part[MINOR(req->rq_dev)].start_sect;
+        int btrk = (reloc_sector >> shift) / blk_per_trk; 
+	int etrk = ((reloc_sector + req->nr_sectors - 1) >> shift) / blk_per_trk;
+	int recid = reloc_sector >> shift;
 	int locate4k_set = 0;
 	int nlocs = 0;
+	int errcode;
 
 	if (req->cmd == READ) {
 		rw_cmd = DASD_ECKD_CCW_READ_MT;
 	} else if (req->cmd == WRITE) {
 		rw_cmd = DASD_ECKD_CCW_WRITE_MT;
 	} else {
-		PRINT_ERR ("Unknown command %d\n", req->cmd);
-		return NULL;
+
+		MESSAGE (KERN_ERR,
+                         "Unknown command %d", 
+                         req->cmd);
+
+		return ERR_PTR(-EINVAL);
 	}
 	/* Build the request */
 	/* count bhs to prevent errors, when bh smaller than block */
 	bhct = 0;
 	for (bh = req->bh; bh; bh = bh->b_reqnext) {
-		if (bh->b_size < byt_per_blk)
-                        BUG();
+		if (bh->b_size < byt_per_blk) {
+			MESSAGE(KERN_ERR, "ignoring bogus sized request: %d<%d",
+					  bh->b_size, byt_per_blk);
+                        return ERR_PTR(-EINVAL);
+		}
                 bhct+= bh->b_size >> (device->sizes.s2b_shift+9);
 	}
 	if (btrk < 2 && private->uses_cdl) {
@@ -1050,12 +1231,13 @@
                                     sizeof (LO_eckd_data_t),
                                     device);
 	if (!rw_cp) {
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 	}
 	DE_data = rw_cp->data;
 	LO_data = rw_cp->data + sizeof (DE_eckd_data_t);
 	ccw = rw_cp->cpaddr;
-	if (define_extent (ccw, DE_data, btrk, etrk, rw_cmd, device, rw_cp)) {
+	if ((errcode = define_extent (ccw, DE_data, btrk, etrk, 
+                                      rw_cmd, device, rw_cp))) {
                 goto clear_rw_cp;
         }
 	ccw->flags |= CCW_FLAG_CC;
@@ -1068,25 +1250,25 @@
                                     && private->uses_cdl) {
                                         /* Do a locate record for our special blocks */
                                         int cmd = dasd_eckd_cdl_cmd (device,recid, req->cmd);
-                                        if (locate_record (ccw, 
+                                        if ((errcode = locate_record (ccw, 
                                                        LO_data++,
                                                        recid / blk_per_trk, 
                                                        recid % blk_per_trk + 1, 
                                                        1, cmd, device,
-                                                           dasd_eckd_cdl_reclen(device, recid), rw_cp)) {
+                                                       dasd_eckd_cdl_reclen(device, recid), rw_cp))) {
                                                 goto clear_rw_cp;
                                         }
                                 } else {
                                         // Do a locate record for standard blocks */
-                                        if (locate_record (ccw, 
+                                        if ((errcode = locate_record (ccw, 
                                                        LO_data++,
                                                        recid /blk_per_trk,
                                                        recid %blk_per_trk + 1,
-                                                       (((req->sector +
+                                                       (((reloc_sector +
                                                           req->nr_sectors) >>
                                                          shift) - recid), 
                                                        rw_cmd, device,
-                                                           device->sizes.bp_block, rw_cp)) {
+                                                       device->sizes.bp_block, rw_cp))) {
                                                 goto clear_rw_cp;
                                         }
                                         locate4k_set = 1;
@@ -1105,25 +1287,32 @@
                                             0xE5, byt_per_blk - ccw->count);
                                 }
                         }
-                        if (dasd_set_normalized_cda (ccw, __pa (bh->b_data+size), rw_cp, device)) {
+                        if ((errcode = dasd_set_normalized_cda (ccw, __pa (bh->b_data+size), 
+                                                                rw_cp, device))) {
                                 goto clear_rw_cp;
                         }
                         recid++;
                 }
                 bh = bh->b_reqnext;
 	}
-	ccw->flags &= ~(CCW_FLAG_DC | CCW_FLAG_CC);
-	rw_cp->device = device;
+	ccw->flags    &= ~(CCW_FLAG_DC | CCW_FLAG_CC);
+	rw_cp->device  = device;
 	rw_cp->expires = 5 * TOD_MIN;	/* 5 minutes */
-	rw_cp->req = req;
-	rw_cp->lpm = LPM_ANYPATH;
-	rw_cp->retries = 2;
-	asm volatile ("STCK %0":"=m" (rw_cp->buildclk));
-	check_then_set (&rw_cp->status, CQR_STATUS_EMPTY, CQR_STATUS_FILLED);
+	rw_cp->req     = req;
+	rw_cp->lpm     = LPM_ANYPATH;
+	rw_cp->retries = 256;
+
+	rw_cp->buildclk = get_clock ();
+
+	check_then_set (&rw_cp->status, 
+                        CQR_STATUS_EMPTY, 
+                        CQR_STATUS_FILLED);
+
         goto out;
  clear_rw_cp:
-        dasd_free_request (rw_cp, device);
-        rw_cp=NULL;
+        dasd_free_request (rw_cp, 
+                           device);
+        rw_cp=ERR_PTR(errcode);
  out:
 	return rw_cp;
 }
@@ -1176,18 +1365,31 @@
 ccw_req_t *
 dasd_eckd_reserve (struct dasd_device_t * device)
 {
-	ccw_req_t *cqr =
-	    dasd_alloc_request (dasd_eckd_discipline.name, 1 + 1, 0, device);
+	ccw_req_t *cqr;
+
+        cqr = dasd_alloc_request (dasd_eckd_discipline.name, 
+                                  1 + 1, 32, device);
 	if (cqr == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"No memory to allocate initialization request\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+                         "No memory to allocate initialization request");
+
 		return NULL;
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
+        cqr->cpaddr->flags |= CCW_FLAG_SLI;
+        cqr->cpaddr->count = 32;
+
+	if (dasd_set_normalized_cda (cqr->cpaddr, __pa (cqr->data), 
+                                     cqr, device)) {
+                dasd_free_request (cqr, device);
+                return NULL;
+        }
+        
 	cqr->device  = device;
 	cqr->retries = 0;
 	cqr->expires = 10 * TOD_SEC;
-        cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */
+	cqr->buildclk = get_clock ();
 	cqr->status  = CQR_STATUS_FILLED;
 	return cqr; 
 }
@@ -1202,18 +1404,31 @@
 ccw_req_t *
 dasd_eckd_release (struct dasd_device_t * device)
 {
-	ccw_req_t *cqr =
-	    dasd_alloc_request (dasd_eckd_discipline.name, 1 + 1, 0, device);
+	ccw_req_t *cqr;
+
+        cqr = dasd_alloc_request (dasd_eckd_discipline.name, 
+                                  1 + 1, 32, device);
 	if (cqr == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"No memory to allocate initialization request\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+                         "No memory to allocate initialization request");
+
 		return NULL;
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
+        cqr->cpaddr->flags |= CCW_FLAG_SLI;
+        cqr->cpaddr->count = 32;
+
+	if (dasd_set_normalized_cda (cqr->cpaddr, __pa (cqr->data), 
+                                     cqr, device)) {
+                dasd_free_request (cqr, device);
+                return NULL;
+        }
+
 	cqr->device  = device;
 	cqr->retries = 0;
 	cqr->expires = 10 * TOD_SEC;
-        cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */
+	cqr->buildclk = get_clock ();
 	cqr->status  = CQR_STATUS_FILLED;
 	return cqr;
 
@@ -1229,18 +1444,31 @@
 ccw_req_t *
 dasd_eckd_steal_lock (struct dasd_device_t * device)
 {
-	ccw_req_t *cqr =
-	    dasd_alloc_request (dasd_eckd_discipline.name, 1 + 1, 0, device);
+	ccw_req_t *cqr;
+
+        cqr = dasd_alloc_request (dasd_eckd_discipline.name, 
+                                  1 + 1, 32, device);
 	if (cqr == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"No memory to allocate initialization request\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+			"No memory to allocate initialization request");
+
 		return NULL;
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
+        cqr->cpaddr->flags |= CCW_FLAG_SLI;
+        cqr->cpaddr->count = 32;
+
+	if (dasd_set_normalized_cda (cqr->cpaddr, __pa (cqr->data), 
+                                     cqr, device)) {
+                dasd_free_request (cqr, device);
+                return NULL;
+        }
+        
 	cqr->device  = device;
 	cqr->retries = 0;
 	cqr->expires = 10 * TOD_SEC;
-        cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */
+	cqr->buildclk = get_clock ();
 	cqr->status  = CQR_STATUS_FILLED;
 	return cqr;
 }
@@ -1274,14 +1502,17 @@
 }
 
 static int
-dasd_eckd_fill_info (dasd_device_t * device, dasd_information_t * info)
+dasd_eckd_fill_info (dasd_device_t * device, dasd_information2_t * info)
 {
 	int rc = 0;
 	info->label_block = 2;
-	if (((dasd_eckd_private_t *) device->private)->uses_cdl)
+	if (((dasd_eckd_private_t *) device->private)->uses_cdl) {
 		info->FBA_layout = 0;
-	else
-		info->FBA_layout = 1;
+                info->format = DASD_FORMAT_CDL;
+        } else {
+                info->FBA_layout = 1;
+                info->format = DASD_FORMAT_LDL;
+        }
 	info->characteristics_size = sizeof (dasd_eckd_characteristics_t);
 	memcpy (info->characteristics,
 		&((dasd_eckd_private_t *) device->private)->rdc_data,
@@ -1293,6 +1524,138 @@
 	return rc;
 }
 
+/*
+ * DASD_ECKD_READ_STATS
+ * 
+ * DESCRIPTION
+ *   build the channel program to read the performance statistics
+ *   of the attached subsystem
+ */
+ccw_req_t *
+dasd_eckd_read_stats (struct dasd_device_t * device)
+{
+
+        int                    rc;
+	ccw1_t                 *ccw;
+	ccw_req_t              *cqr;
+	dasd_psf_prssd_data_t  *prssdp;
+	dasd_rssd_perf_stats_t *statsp;
+
+        cqr = dasd_alloc_request (dasd_eckd_discipline.name, 
+                                  1 /* PSF */ + 1 /* RSSD */,
+                                  (sizeof (dasd_psf_prssd_data_t) +  
+                                   sizeof (dasd_rssd_perf_stats_t) ), 
+                                  device);
+
+	if (cqr == NULL) {
+                
+                MESSAGE (KERN_WARNING, "%s",
+                         "No memory to allocate initialization request");
+                
+		return NULL;
+	}
+
+	cqr->device  = device;
+	cqr->retries = 0;
+	cqr->expires = 10 * TOD_SEC;
+
+        /* Prepare for Read Subsystem Data */
+	prssdp = (dasd_psf_prssd_data_t *) cqr->data;
+
+	memset (prssdp, 0, sizeof (dasd_psf_prssd_data_t));
+
+	prssdp->order     = PSF_ORDER_PRSSD;
+	prssdp->suborder  = 0x01; /* Perfomance Statistics */
+	prssdp->varies[1] = 0x01; /* Perf Statistics for the Subsystem */
+
+	ccw = cqr->cpaddr;
+
+	ccw->cmd_code = DASD_ECKD_CCW_PSF;
+	ccw->count    = sizeof (dasd_psf_prssd_data_t);
+	ccw->flags   |= CCW_FLAG_CC;
+
+	if ((rc = dasd_set_normalized_cda (ccw,__pa (prssdp), cqr, device))) {
+
+                dasd_free_request (cqr, 
+                                   device);
+                return NULL;
+        }
+
+	ccw++;
+
+        /* Read Subsystem Data - Performance Statistics */
+	statsp = (dasd_rssd_perf_stats_t *) (prssdp + 1);
+	memset (statsp, 0, sizeof (dasd_rssd_perf_stats_t));
+
+	ccw->cmd_code = DASD_ECKD_CCW_RSSD;
+	ccw->count    = sizeof (dasd_rssd_perf_stats_t);
+
+	if ((rc = dasd_set_normalized_cda (ccw,__pa (statsp), cqr, device))) {
+
+                dasd_free_request (cqr, 
+                                   device);
+                return NULL;
+        }
+        cqr->buildclk = get_clock ();
+	cqr->status   = CQR_STATUS_FILLED;
+
+	return cqr; 
+} /* end  dasd_eckd_rstat */
+
+/*
+ * DASD_ECKD_RET_STATS
+ * 
+ * DESCRIPTION
+ *   returns pointer to Performance Statistics Data.
+ */
+dasd_rssd_perf_stats_t *
+dasd_eckd_ret_stats (ccw_req_t *cqr)
+{
+        
+        dasd_psf_prssd_data_t  *prssdp;
+	dasd_rssd_perf_stats_t *statsp;
+        
+	if (cqr == NULL) {
+
+		return NULL;
+	}
+
+        /* Prepare for Read Subsystem Data */
+	prssdp = (dasd_psf_prssd_data_t *)  cqr->data;
+	statsp = (dasd_rssd_perf_stats_t *) (prssdp + 1);
+
+	return statsp;
+
+} /* end  dasd_eckd_rstat */
+
+
+/*
+ * DASD_ECKD_SET_ATTRUB
+ * 
+ * DESCRIPTION
+ *   stores the attributes for cache operation to be used in Define Extend (DE).
+ */
+int
+dasd_eckd_set_attrib (dasd_device_t *device,
+                      attrib_data_t *attrib)
+{
+        int rc = 0;
+	dasd_eckd_private_t *private;
+
+        private = (dasd_eckd_private_t *) device->private;
+        private->attrib = *attrib;
+
+        DBF_DEV_EVENT (DBF_ERR, device,
+                     "cache operation mode set to "
+                     "%x (%i cylinder prestage)",
+                     private->attrib.operation,
+                     private->attrib.nr_cyl);
+        
+
+        return rc;
+        
+} /* end dasd_eckd_set_attrib */
+
 static char*
 dasd_eckd_dump_sense (struct dasd_device_t *device, 
                       ccw_req_t            *req)
@@ -1304,8 +1667,10 @@
 	int len, sl, sct;
 
 	if (page == NULL) {
-                printk (KERN_ERR PRINTK_HEADER
-                        "No memory to dump sense data\n");
+
+                MESSAGE (KERN_ERR, "%s",
+                        "No memory to dump sense data");
+
 		return NULL;
 	}
 
@@ -1318,17 +1683,27 @@
 	len += sprintf (page + len, KERN_ERR PRINTK_HEADER
 			"Failing CCW: %p\n", (void *) (long) stat->cpa);
 	{
+
 		ccw1_t *act = req->cpaddr;
 		int i = req->cplength;
+
 		do {
-#ifdef ERP_DEBUG
-			printk (KERN_ERR "CCW %p: %08X %08X\n",
-				act, ((int *) act)[0], ((int *) act)[1]);
-			printk (KERN_ERR "DAT: %08X %08X %08X %08X\n",
-				((int *) act->cda)[0], ((int *) act->cda)[1],
-				((int *) act->cda)[2], ((int *) act->cda)[3]);
-#endif				/* ERP_DEBUG */
+
+			DBF_EVENT (DBF_INFO, 
+                                   "CCW %p: %08X %08X",
+                                   act, 
+                                   ((int *) act)[0], 
+                                   ((int *) act)[1]);
+
+			DBF_EVENT (DBF_INFO, 
+                                   "DAT: %08X %08X %08X %08X",
+                                   ((int *) (addr_t) act->cda)[0], 
+                                   ((int *) (addr_t) act->cda)[1],
+                                   ((int *) (addr_t) act->cda)[2], 
+                                   ((int *) (addr_t) act->cda)[3]);
+
 			act++;
+
 		} while (--i);
 	}
 	if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL) {
@@ -1353,13 +1728,15 @@
 		} else {
 			/* 32 Byte Sense Data */
 			len += sprintf (page + len, KERN_ERR PRINTK_HEADER
-					"32 Byte: Format: %x Exception class %x\n",
+					"32 Byte: Format: %x "
+                                        "Exception class %x\n",
 					sense[6] & 0x0f, sense[22] >> 4);
 		}
 	}
 
-        printk ("Sense data:\n%s", 
-                page);
+        MESSAGE (KERN_ERR,
+                 "Sense data:\n%s", 
+                 page);
 
         free_page ((unsigned long) page);
         
@@ -1371,7 +1748,7 @@
         owner: THIS_MODULE,
 	name:"ECKD",
 	ebcname:"ECKD",
-	max_blocks:255,
+	max_blocks:240,
 	id_check:dasd_eckd_id_check,
 	check_characteristics:dasd_eckd_check_characteristics,
 	init_analysis:dasd_eckd_init_analysis,
@@ -1391,14 +1768,21 @@
         steal_lock:dasd_eckd_steal_lock,
 	merge_cp:dasd_eckd_merge_cp,
 	fill_info:dasd_eckd_fill_info,
+        read_stats:dasd_eckd_read_stats,
+        ret_stats:dasd_eckd_ret_stats,
+        set_attrib:dasd_eckd_set_attrib,
+	list:LIST_HEAD_INIT(dasd_eckd_discipline.list),
 };
 
 int
 dasd_eckd_init (void)
 {
 	int rc = 0;
-	printk (KERN_INFO PRINTK_HEADER
-		"%s discipline initializing\n", dasd_eckd_discipline.name);
+
+	MESSAGE (KERN_INFO,
+		"%s discipline initializing", 
+                 dasd_eckd_discipline.name);
+
 	ASCEBC (dasd_eckd_discipline.ebcname, 4);
 	dasd_discipline_add (&dasd_eckd_discipline);
 #ifdef CONFIG_DASD_DYNAMIC
@@ -1407,10 +1791,12 @@
 		for (i = 0;
 		     i < sizeof (dasd_eckd_known_devices) / sizeof (devreg_t);
 		     i++) {
-			printk (KERN_INFO PRINTK_HEADER
-				"We are interested in: CU %04X/%02x\n",
-				dasd_eckd_known_devices[i].ci.hc.ctype,
-				dasd_eckd_known_devices[i].ci.hc.cmode);
+
+			MESSAGE (KERN_INFO,
+                                 "We are interested in: CU %04X/%02x",
+                                 dasd_eckd_known_devices[i].ci.hc.ctype,
+                                 dasd_eckd_known_devices[i].ci.hc.cmode);
+
 			s390_device_register (&dasd_eckd_known_devices[i]);
 		}
 	}
@@ -1421,18 +1807,23 @@
 void
 dasd_eckd_cleanup (void)
 {
-	printk (KERN_INFO PRINTK_HEADER
-		"%s discipline cleaning up\n", dasd_eckd_discipline.name);
+
+	MESSAGE (KERN_INFO,
+		"%s discipline cleaning up", 
+                 dasd_eckd_discipline.name);
+
 #ifdef CONFIG_DASD_DYNAMIC
 	{
 		int i;
 		for (i = 0;
 		     i < sizeof (dasd_eckd_known_devices) / sizeof (devreg_t);
 		     i++) {
-			printk (KERN_INFO PRINTK_HEADER
-				"We were interested in: CU %04X/%02x\n",
-				dasd_eckd_known_devices[i].ci.hc.ctype,
-				dasd_eckd_known_devices[i].ci.hc.cmode);
+
+			MESSAGE (KERN_INFO,
+                                 "We were interested in: CU %04X/%02x",
+                                 dasd_eckd_known_devices[i].ci.hc.ctype,
+                                 dasd_eckd_known_devices[i].ci.hc.cmode);
+
 			s390_device_unregister (&dasd_eckd_known_devices[i]);
 		}
 	}
diff -urN linux-2.4.22-pre2/drivers/s390/block/dasd_eckd.h linux-2.4.22-pre3/drivers/s390/block/dasd_eckd.h
--- linux-2.4.22-pre2/drivers/s390/block/dasd_eckd.h	2001-09-30 12:26:07.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/block/dasd_eckd.h	2003-07-05 18:10:26.000000000 -0700
@@ -1,78 +1,96 @@
+/* 
+ * File...........: linux/drivers/s390/block/dasd_eckd.h
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ *                  Horst Hummel <Horst.Hummel@de.ibm.com> 
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ *
+ * $Revision: 1.14 $
+ *
+ * History of changes 
+ * 
+ */
+
 #ifndef DASD_ECKD_H
 #define DASD_ECKD_H
 
 #include "dasd_3990_erp.h"
 #include "dasd_9343_erp.h"
 
-#define DASD_ECKD_CCW_WRITE 0x05
-#define DASD_ECKD_CCW_READ 0x06
+/*******************************************************************************
+ * SECTION: CCW Definitions
+ ******************************************************************************/
+#define DASD_ECKD_CCW_WRITE              0x05
+#define DASD_ECKD_CCW_READ               0x06
 #define DASD_ECKD_CCW_WRITE_HOME_ADDRESS 0x09
-#define DASD_ECKD_CCW_READ_HOME_ADDRESS 0x0a
-#define DASD_ECKD_CCW_WRITE_KD 0x0d
-#define DASD_ECKD_CCW_READ_KD 0x0e
-#define DASD_ECKD_CCW_ERASE 0x11
-#define DASD_ECKD_CCW_READ_COUNT 0x12
-#define DASD_ECKD_CCW_WRITE_RECORD_ZERO 0x15
-#define DASD_ECKD_CCW_READ_RECORD_ZERO 0x16
-#define DASD_ECKD_CCW_WRITE_CKD 0x1d
-#define DASD_ECKD_CCW_READ_CKD 0x1e
-#define DASD_ECKD_CCW_LOCATE_RECORD 0x47
-#define DASD_ECKD_CCW_DEFINE_EXTENT 0x63
-#define DASD_ECKD_CCW_WRITE_MT 0x85
-#define DASD_ECKD_CCW_READ_MT 0x86
-#define DASD_ECKD_CCW_WRITE_KD_MT 0x8d
-#define DASD_ECKD_CCW_READ_KD_MT 0x8e
-#define DASD_ECKD_CCW_RELEASE 0x94
-#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
-#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
-#define DASD_ECKD_CCW_RESERVE 0xB4
-#define DASD_ECKD_CCW_SLCK 0x14	/* steal lock - unconditional reserve */
+#define DASD_ECKD_CCW_READ_HOME_ADDRESS  0x0a
+#define DASD_ECKD_CCW_WRITE_KD           0x0d
+#define DASD_ECKD_CCW_READ_KD            0x0e
+#define DASD_ECKD_CCW_ERASE              0x11
+#define DASD_ECKD_CCW_READ_COUNT         0x12
+#define DASD_ECKD_CCW_SLCK               0x14
+#define DASD_ECKD_CCW_WRITE_RECORD_ZERO  0x15
+#define DASD_ECKD_CCW_READ_RECORD_ZERO   0x16
+#define DASD_ECKD_CCW_WRITE_CKD          0x1d
+#define DASD_ECKD_CCW_READ_CKD           0x1e
+#define DASD_ECKD_CCW_PSF                0x27
+#define DASD_ECKD_CCW_RSSD               0x3e
+#define DASD_ECKD_CCW_LOCATE_RECORD      0x47
+#define DASD_ECKD_CCW_DEFINE_EXTENT      0x63
+#define DASD_ECKD_CCW_WRITE_MT           0x85
+#define DASD_ECKD_CCW_READ_MT            0x86
+#define DASD_ECKD_CCW_WRITE_KD_MT        0x8d
+#define DASD_ECKD_CCW_READ_KD_MT         0x8e
+#define DASD_ECKD_CCW_RELEASE            0x94
+#define DASD_ECKD_CCW_READ_CKD_MT        0x9e
+#define DASD_ECKD_CCW_WRITE_CKD_MT       0x9d
+#define DASD_ECKD_CCW_RESERVE            0xB4
+
+/*
+ *Perform Subsystem Function / Sub-Orders
+ */
+#define PSF_ORDER_PRSSD                  0x18
+
+
+/*******************************************************************************
+ * SECTION: Type Definitions
+ ******************************************************************************/
 
-typedef
-    struct eckd_count_t {
+typedef struct eckd_count_t {
 	__u16 cyl;
 	__u16 head;
 	__u8 record;
 	__u8 kl;
 	__u16 dl;
-} __attribute__ ((packed))
+} __attribute__ ((packed)) eckd_count_t;
 
-    eckd_count_t;
 
-typedef
-    struct ch_t {
+typedef struct ch_t {
 	__u16 cyl;
 	__u16 head;
-} __attribute__ ((packed))
+} __attribute__ ((packed)) ch_t;
 
-    ch_t;
 
-typedef
-    struct chs_t {
+typedef struct chs_t {
 	__u16 cyl;
 	__u16 head;
 	__u32 sector;
-} __attribute__ ((packed))
+} __attribute__ ((packed)) chs_t;
 
-    chs_t;
 
-typedef
-    struct chr_t {
+typedef struct chr_t {
 	__u16 cyl;
 	__u16 head;
 	__u8 record;
-} __attribute__ ((packed))
+} __attribute__ ((packed)) chr_t;
 
-    chr_t;
 
-typedef
-    struct geom_t {
+typedef struct geom_t {
 	__u16 cyl;
 	__u16 head;
 	__u32 sector;
-} __attribute__ ((packed))
+} __attribute__ ((packed)) geom_t;
 
-    geom_t;
 
 typedef struct eckd_home_t {
 	__u8 skip_control[14];
@@ -83,12 +101,10 @@
 	__u8 reserved;
 	__u8 key_length;
 	__u8 reserved2[2];
-} __attribute__ ((packed))
+} __attribute__ ((packed)) eckd_home_t;
 
-    eckd_home_t;
 
-typedef
-    struct DE_eckd_data_t {
+typedef struct DE_eckd_data_t {
 	struct {
 		unsigned char perm:2;	/* Permissions on this extent */
 		unsigned char reserved:1;
@@ -103,18 +119,20 @@
 		unsigned char cfw:1;	/* Cache fast write */
 		unsigned char dfw:1;	/* DASD fast write */
 	} __attribute__ ((packed)) attributes;
-	__u16 short blk_size;	/* Blocksize */
+	__u16 blk_size;		/* Blocksize */
 	__u16 fast_write_id;
-	__u8 unused;
-	__u8 reserved;
+	__u8 ga_additional;     /* Global Attributes Additional */
+	__u8 ga_extended;	/* Global Attributes Extended   */
 	ch_t beg_ext;
 	ch_t end_ext;
-} __attribute__ ((packed))
+	unsigned long long ep_sys_time; /* Extended Parameter - System Time Stamp */
+	__u8 ep_format;        /* Extended Parameter format byte       */
+	__u8 ep_prio;          /* Extended Parameter priority I/O byte */
+	__u8 ep_reserved[6];   /* Extended Parameter Reserved          */
+} __attribute__ ((packed)) DE_eckd_data_t;
 
-    DE_eckd_data_t;
 
-typedef
-    struct LO_eckd_data_t {
+typedef struct LO_eckd_data_t {
 	struct {
 		unsigned char orientation:2;
 		unsigned char operation:6;
@@ -130,12 +148,10 @@
 	chr_t search_arg;
 	__u8 sector;
 	__u16 length;
-} __attribute__ ((packed))
+} __attribute__ ((packed)) LO_eckd_data_t;
 
-    LO_eckd_data_t;
 
-typedef
-    struct dasd_eckd_characteristics_t {
+typedef struct dasd_eckd_characteristics_t {
 	__u16 cu_type;
 	struct {
 		unsigned char support:2;
@@ -154,7 +170,8 @@
 		unsigned char reserved2:4;
 		unsigned char reserved3:8;
 		unsigned char defect_wr:1;
-		unsigned char reserved4:2;
+		unsigned char XRC_supported:1; 
+		unsigned char reserved4:1;
 		unsigned char striping:1;
 		unsigned char reserved5:4;
 		unsigned char cfw:1;
@@ -205,9 +222,7 @@
 	__u8 factor8;
 	__u8 reserved2[3];
 	__u8 reserved3[10];
-} __attribute__ ((packed))
-
-    dasd_eckd_characteristics_t;
+} __attribute__ ((packed)) dasd_eckd_characteristics_t;
 
 typedef struct dasd_eckd_confdata_t {
 	struct {
@@ -324,9 +339,20 @@
 		__u8 log_dev_address;
 		unsigned char reserved2[12];
 	} __attribute__ ((packed)) neq;
-} __attribute__ ((packed))
+} __attribute__ ((packed)) dasd_eckd_confdata_t;
+
+/*
+ * Perform Subsystem Function - Prepare for Read Subsystem Data  
+ */
+typedef struct dasd_psf_prssd_data_t {
+	unsigned char order;
+	unsigned char flags;
+	unsigned char reserved[4];
+	unsigned char suborder;
+	unsigned char varies[9];
+} __attribute__((packed)) dasd_psf_prssd_data_t;
+
 
-    dasd_eckd_confdata_t;
 
 int dasd_eckd_init (void);
 void dasd_eckd_cleanup (void);
diff -urN linux-2.4.22-pre2/drivers/s390/block/dasd_fba.c linux-2.4.22-pre3/drivers/s390/block/dasd_fba.c
--- linux-2.4.22-pre2/drivers/s390/block/dasd_fba.c	2001-09-30 12:26:07.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/block/dasd_fba.c	2003-07-05 18:10:26.000000000 -0700
@@ -1,9 +1,12 @@
-
 /* 
  * File...........: linux/drivers/s390/block/dasd_fba.c
  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ *
+ * $Revision: 1.49 $
+ *
+ * History of changes
  *          fixed partition handling and HDIO_GETGEO
  */
 
@@ -38,6 +41,12 @@
 #define DASD_FBA_CCW_LOCATE 0x43
 #define DASD_FBA_CCW_DEFINE_EXTENT 0x63
 
+#ifdef MODULE
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12))
+MODULE_LICENSE("GPL");
+#endif
+#endif
+
 dasd_discipline_t dasd_fba_discipline;
 
 typedef struct
@@ -123,35 +132,46 @@
 	dasd_fba_private_t *private;
 
 	if (device == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"Null device pointer passed to characteristics checker\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+                         "Null device pointer passed to characteristics "
+                         "checker");
+
                 return -ENODEV;
 	}
 	device->private = kmalloc (sizeof (dasd_fba_private_t), GFP_KERNEL);
+
 	if (device->private == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"memory allocation failed for private data\n");
+
+		MESSAGE (KERN_WARNING, "%s",
+			"memory allocation failed for private data");
+
                 rc = -ENOMEM;
                 goto fail;
 	}
 	private = (dasd_fba_private_t *) device->private;
 	rdc_data = (void *) &(private->rdc_data);
 	rc = read_dev_chars (device->devinfo.irq, &rdc_data, 32);
+
 	if (rc) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"Read device characteristics returned error %d\n", rc);
+
+		MESSAGE (KERN_WARNING,
+			"Read device characteristics returned error %d", 
+                         rc);
+
                 goto fail;
 	}
-	printk (KERN_INFO PRINTK_HEADER
-		"%04X on sch %d: %04X/%02X(CU:%04X/%02X) %dMB at(%d B/blk)\n",
-		device->devinfo.devno, device->devinfo.irq,
-		device->devinfo.sid_data.dev_type,
-		device->devinfo.sid_data.dev_model,
-		device->devinfo.sid_data.cu_type,
-		device->devinfo.sid_data.cu_model,
-		(private->rdc_data.blk_bdsa *
-		 (private->rdc_data.blk_size >> 9)) >> 11,
-		private->rdc_data.blk_size);
+
+	DEV_MESSAGE (KERN_INFO, device,
+                     "%04X/%02X(CU:%04X/%02X) %dMB at(%d B/blk)",
+                     device->devinfo.sid_data.dev_type,
+                     device->devinfo.sid_data.dev_model,
+                     device->devinfo.sid_data.cu_type,
+                     device->devinfo.sid_data.cu_model,
+                     ((private->rdc_data.blk_bdsa *
+                       (private->rdc_data.blk_size >> 9)) >> 11),
+                     private->rdc_data.blk_size);
+
         goto out;
  fail:
         if ( rc ) {
@@ -180,9 +200,11 @@
 		device->sizes.bp_block = bs;
 		break;
 	default:
-		printk (KERN_INFO PRINTK_HEADER
-			"/dev/%s (%04X): unknown blocksize %d\n",
-			device->name, device->devinfo.devno, bs);
+
+		DEV_MESSAGE (KERN_INFO, device,
+                             "unknown blocksize %d",
+                             bs);
+
 		return -EMEDIUMTYPE;
 	}
 	device->sizes.s2b_shift = 0;	/* bits to shift 512 to get a block */
@@ -247,8 +269,11 @@
 {
 	if (cqr->function == dasd_default_erp_action)
 		return dasd_default_erp_postaction;
-	printk (KERN_WARNING PRINTK_HEADER
-		"unknown ERP action %p\n", cqr->function);
+
+	MESSAGE (KERN_WARNING,
+                 "unknown ERP action %p", 
+                 cqr->function);
+
 	return NULL;
 }
 
@@ -265,14 +290,20 @@
 	struct buffer_head *bh;
 	dasd_fba_private_t *private = (dasd_fba_private_t *) device->private;
 	int byt_per_blk = device->sizes.bp_block;
+        unsigned long reloc_sector = req->sector + 
+                device->major_info->gendisk.part[MINOR (req->rq_dev)].start_sect;
         
 	if (req->cmd == READ) {
 		rw_cmd = DASD_FBA_CCW_READ;
 	} else if (req->cmd == WRITE) {
 		rw_cmd = DASD_FBA_CCW_WRITE;
 	} else {
-		PRINT_ERR ("Unknown command %d\n", req->cmd);
-		return NULL;
+
+		MESSAGE (KERN_ERR,
+                         "Unknown command %d\n", 
+                         req->cmd);
+
+		return ERR_PTR(-EINVAL);
 	}
 	/* Build the request */
 	/* count hs to prevent errors, when bh smaller than block */
@@ -300,14 +331,14 @@
                                             device);
         }
 	if (!rw_cp) {
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 	}
 	DE_data = rw_cp->data;
 	LO_data = rw_cp->data + sizeof (DE_fba_data_t);
 	ccw = rw_cp->cpaddr;
 
 	if (define_extent (ccw, DE_data, req->cmd, byt_per_blk,
-                           req->sector, req->nr_sectors, rw_cp, device)) {
+                           reloc_sector, req->nr_sectors, rw_cp, device)) {
                 goto clear_rw_cp;
         }
 	ccw->flags |= CCW_FLAG_CC;
@@ -363,11 +394,12 @@
 }
 
 static int
-dasd_fba_fill_info (dasd_device_t * device, dasd_information_t * info)
+dasd_fba_fill_info (dasd_device_t * device, dasd_information2_t * info)
 {
 	int rc = 0;
 	info->label_block = 1;
 	info->FBA_layout = 1;
+	info->format = DASD_FORMAT_LDL;
 	info->characteristics_size = sizeof (dasd_fba_characteristics_t);
 	memcpy (info->characteristics,
 		&((dasd_fba_private_t *) device->private)->rdc_data,
@@ -410,14 +442,18 @@
 	dump_sense:dasd_fba_dump_sense,
 	int_handler:dasd_int_handler,
 	fill_info:dasd_fba_fill_info,
+	list:LIST_HEAD_INIT(dasd_fba_discipline.list),
 };
 
 int
 dasd_fba_init (void)
 {
 	int rc = 0;
-	printk (KERN_INFO PRINTK_HEADER
-		"%s discipline initializing\n", dasd_fba_discipline.name);
+
+	MESSAGE (KERN_INFO,
+                 "%s discipline initializing", 
+                 dasd_fba_discipline.name);
+
 	ASCEBC (dasd_fba_discipline.ebcname, 4);
 	dasd_discipline_add (&dasd_fba_discipline);
 #ifdef CONFIG_DASD_DYNAMIC
@@ -426,12 +462,15 @@
 		for (i = 0;
 		     i < sizeof (dasd_fba_known_devices) / sizeof (devreg_t);
 		     i++) {
-			printk (KERN_INFO PRINTK_HEADER
-				"We are interested in: Dev %04X/%02X @ CU %04X/%02x\n",
-				dasd_fba_known_devices[i].ci.hc.dtype,
-				dasd_fba_known_devices[i].ci.hc.dmode,
-				dasd_fba_known_devices[i].ci.hc.ctype,
-				dasd_fba_known_devices[i].ci.hc.cmode);
+
+			MESSAGE (KERN_INFO,
+                                 "We are interested in: "
+                                 "Dev %04X/%02X @ CU %04X/%02x",
+                                 dasd_fba_known_devices[i].ci.hc.dtype,
+                                 dasd_fba_known_devices[i].ci.hc.dmode,
+                                 dasd_fba_known_devices[i].ci.hc.ctype,
+                                 dasd_fba_known_devices[i].ci.hc.cmode);
+
 			s390_device_register (&dasd_fba_known_devices[i]);
 		}
 	}
@@ -441,8 +480,11 @@
 
 void
 dasd_fba_cleanup( void ) {
-        printk ( KERN_INFO PRINTK_HEADER
-                 "%s discipline cleaning up\n", dasd_fba_discipline.name);
+
+        MESSAGE (KERN_INFO,
+                 "%s discipline cleaning up", 
+                 dasd_fba_discipline.name);
+
 #ifdef CONFIG_DASD_DYNAMIC
         {
 	int i;
diff -urN linux-2.4.22-pre2/drivers/s390/block/dasd_fba.h linux-2.4.22-pre3/drivers/s390/block/dasd_fba.h
--- linux-2.4.22-pre2/drivers/s390/block/dasd_fba.h	2001-08-05 13:12:41.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/block/dasd_fba.h	2003-07-05 18:10:26.000000000 -0700
@@ -1,3 +1,15 @@
+/* 
+ * File...........: linux/drivers/s390/block/dasd_fba.h
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ *                  Horst Hummel <Horst.Hummel@de.ibm.com> 
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ *
+ * $Revision: 1.6 $
+ *
+ * History of changes
+ *
+ */
 
 #ifndef DASD_FBA_H
 #define DASD_FBA_H
diff -urN linux-2.4.22-pre2/drivers/s390/block/dasd_int.h linux-2.4.22-pre3/drivers/s390/block/dasd_int.h
--- linux-2.4.22-pre2/drivers/s390/block/dasd_int.h	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/block/dasd_int.h	2003-07-05 18:10:26.000000000 -0700
@@ -1,9 +1,12 @@
 /* 
- * File...........: linux/drivers/s390/block/dasd.c
+ * File...........: linux/drivers/s390/block/dasd_int.h
  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ *                  Horst Hummel <Horst.Hummel@de.ibm.com> 
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
+ * $Revision: 1.26 $
+ *
  * History of changes (starts July 2000)
  * 02/01/01 added dynamic registration of ioctls
  */
@@ -11,8 +14,6 @@
 #ifndef DASD_INT_H
 #define DASD_INT_H
 
-#define DASD_API_VERSION 0
-
 #include <asm/dasd.h>
 
 #define CONFIG_DASD_DYNAMIC
@@ -28,14 +29,19 @@
 #define DASD_FORMAT_INTENS_WRITE_RECZERO 0x01
 #define DASD_FORMAT_INTENS_WRITE_HOMEADR 0x02
 
-#define DASD_STATE_DEL   -1
-#define DASD_STATE_NEW    0
-#define DASD_STATE_KNOWN  1
-#define DASD_STATE_ACCEPT 2
-#define DASD_STATE_INIT   3
-#define DASD_STATE_READY  4
-#define DASD_STATE_ONLINE 5
-
+#define DASD_STATE_DEL   -1     /* "unknown" */
+#define DASD_STATE_NEW    0     /* memory for dasd_device_t and lowmem ccw/idals allocated */  
+#define DASD_STATE_BOXED  1     /* boxed dasd could not be analysed "plugged" */
+#define DASD_STATE_KNOWN  2     /* major_info/devinfo/discipline/devfs-'device'/gendisk - "detected" */
+#define DASD_STATE_ACCEPT 3     /* irq requested - "accepted" */
+#define DASD_STATE_INIT   4     /* init_cqr started - "busy" */
+#define DASD_STATE_READY  5     /* init finished  - "fenced(plugged)" */
+#define DASD_STATE_ONLINE 6     /* unplugged "active" */
+
+#define DASD_HOTPLUG_EVENT_ADD        0
+#define DASD_HOTPLUG_EVENT_REMOVE     1
+#define DASD_HOTPLUG_EVENT_PARTCHK    2
+#define DASD_HOTPLUG_EVENT_PARTREMOVE 3
 
 #define DASD_FORMAT_INTENS_WRITE_RECZERO 0x01
 #define DASD_FORMAT_INTENS_WRITE_HOMEADR 0x02
@@ -61,7 +67,9 @@
 #include <asm/todclk.h>
 #include <asm/debug.h>
 
-/* Kernel Version Compatibility section */
+/********************************************************************************
+ * SECTION: Kernel Version Compatibility section 
+ ********************************************************************************/
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98))
 typedef struct request *request_queue_t;
 #define block_device_operations file_operations
@@ -102,6 +110,7 @@
         *q = req->next;
         req->next = NULL;
 }
+
 #else
 #define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \
 do { \
@@ -124,9 +133,12 @@
 {
         blkdev_dequeue_request (req);
 }
-#endif
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98)) */
+
+/********************************************************************************
+ * SECTION: Type definitions
+ ********************************************************************************/
 
-/* dasd_range_t are used for dynamic device att-/detachment */
 typedef struct dasd_devreg_t {
         devreg_t devreg; /* the devreg itself */
         /* build a linked list of devregs, needed for cleanup */
@@ -153,27 +165,6 @@
 #define DASD_SENSE_BIT_2 0x20
 #define DASD_SENSE_BIT_3 0x10
 
-#define check_then_set(where,from,to) \
-do { \
-        if ((*(where)) != (from) ) { \
-                printk (KERN_ERR PRINTK_HEADER "was %d\n", *(where)); \
-                BUG(); \
-        } \
-        (*(where)) = (to); \
-} while (0)
-
-#define DASD_MESSAGE(d_loglevel,d_device,d_string,d_args...)\
-do { \
-        int d_devno = d_device->devinfo.devno; \
-        int d_irq = d_device->devinfo.irq; \
-        char *d_name = d_device->name; \
-        int d_major = MAJOR(d_device->kdev); \
-        int d_minor = MINOR(d_device->kdev); \
-        printk(d_loglevel PRINTK_HEADER \
-               "/dev/%s(%d:%d),%04x@0x%x:" \
-               d_string "\n",d_name,d_major,d_minor,d_devno,d_irq,d_args ); \
-} while(0)
-
 /* 
  * struct dasd_sizes_t
  * represents all data needed to access dasd with properly set up sectors
@@ -196,68 +187,164 @@
 	ccw_req_t *tail;
 } dasd_chanq_t;
 
-#define DASD_DEVICE_FORMAT_STRING "Device: %p"
-#define DASD_DEVICE_DEBUG_EVENT(d_level, d_device, d_str, d_data...)\
-do {\
-        if ( d_device->debug_area != NULL )\
-        debug_sprintf_event(d_device->debug_area,d_level,\
-                    DASD_DEVICE_FORMAT_STRING d_str "\n",\
-                    d_device, d_data);\
+/* 
+ * struct dasd_lowmem_t 
+ * represents a queue of pages for lowmem request
+ */
+typedef struct {
+        struct list_head list;
+} dasd_lowmem_t;
+
+#define DASD_LOWMEM_PAGES 2     /* # of lowmem pages per device (min 2) */
+
+/********************************************************************************
+ * SECTION: MACROS
+ ********************************************************************************/
+
+/*
+ * CHECK_THEN_SET
+ *
+ * Change 'where' value from 'from' to 'to'.
+ ' BUG if the 'from' value doesn't match.
+ */
+#define check_then_set(where,from,to) \
+do { \
+        if ((*(where)) != (from) ) { \
+                printk (KERN_ERR PRINTK_HEADER "was %d\n", *(where)); \
+                BUG(); \
+        } \
+        (*(where)) = (to); \
 } while(0)
-#define DASD_DEVICE_DEBUG_EXCEPTION(d_level, d_device, d_str, d_data...)\
-do {\
-        if ( d_device->debug_area != NULL )\
-        debug_sprintf_exception(d_device->debug_area,d_level,\
-                        DASD_DEVICE_FORMAT_STRING d_str "\n",\
-                        d_device, d_data);\
+
+
+/********************************************************************************
+ * SECION: MACROs for klogd and s390 debug feature (dbf)
+ ********************************************************************************/
+
+#define DBF_DEV_EVENT(d_level, d_device, d_str, d_data...) \
+do { \
+        if (d_device->debug_area != NULL) \
+                debug_sprintf_event(d_device->debug_area, \
+                                    d_level, \
+                                    d_str "\n", \
+                                    d_data); \
+} while(0)
+
+#define DBF_DEV_EXC(d_level, d_device, d_str, d_data...) \
+do { \
+        if (d_device->debug_area != NULL) \
+                debug_sprintf_exception(d_device->debug_area, \
+                                        d_level, \
+                                        d_str "\n", \
+                                        d_data); \
+} while(0)
+
+#define DBF_EVENT(d_level, d_str, d_data...)\
+do { \
+        if (dasd_debug_area != NULL) \
+                debug_sprintf_event(dasd_debug_area, \
+                                    d_level,\
+                                    d_str "\n", \
+                                    d_data); \
+} while(0)
+
+#define DBF_EXC(d_level, d_str, d_data...)\
+do { \
+        if (dasd_debug_area != NULL) \
+                debug_sprintf_exception(dasd_debug_area, \
+                                        d_level,\
+                                        d_str "\n", \
+                                        d_data); \
 } while(0)
 
-#define DASD_DRIVER_FORMAT_STRING "Driver: <[%p]>"
-#define DASD_DRIVER_DEBUG_EVENT(d_level, d_fn, d_str, d_data...)\
-do {\
-        if ( dasd_debug_area != NULL )\
-        debug_sprintf_event(dasd_debug_area, d_level,\
-                    DASD_DRIVER_FORMAT_STRING #d_fn ":" d_str "\n",\
-                    d_fn, d_data);\
+/* definition of dbf debug levels */
+#define	DBF_EMERG	0	/* system is unusable		*/
+#define	DBF_ALERT	1	/* action must be taken immediately	*/
+#define	DBF_CRIT	2	/* critical conditions		*/
+#define	DBF_ERR  	3	/* error conditions			*/
+#define	DBF_WARNING	4	/* warning conditions		*/
+#define	DBF_NOTICE	5	/* normal but significant condition	*/
+#define	DBF_INFO	6	/* informational			*/
+#define	DBF_DEBUG	6	/* debug-level messages		*/
+
+/* messages to be written via klogd and dbf */
+#define DEV_MESSAGE(d_loglevel,d_device,d_string,d_args...)\
+do { \
+        int d_devno = d_device->devinfo.devno; \
+        int d_irq = d_device->devinfo.irq; \
+        char *d_name = d_device->name; \
+        int d_major = MAJOR(d_device->kdev); \
+        int d_minor = MINOR(d_device->kdev); \
+\
+        printk(d_loglevel PRINTK_HEADER \
+               " /dev/%-7s(%3d:%3d),%04x@%02x: " \
+               d_string "\n", \
+               d_name, \
+               d_major, \
+               d_minor, \
+               d_devno, \
+               d_irq, \
+               d_args); \
+\
+        DBF_DEV_EVENT(DBF_ALERT, \
+                      d_device, \
+                      d_string, \
+                      d_args); \
 } while(0)
-#define DASD_DRIVER_DEBUG_EXCEPTION(d_level, d_fn, d_str, d_data...)\
-do {\
-        if ( dasd_debug_area != NULL )\
-        debug_sprintf_exception(dasd_debug_area, d_level,\
-                        DASD_DRIVER_FORMAT_STRING #d_fn ":" d_str "\n",\
-                        d_fn, d_data);\
+
+#define MESSAGE(d_loglevel,d_string,d_args...)\
+do { \
+        printk(d_loglevel PRINTK_HEADER \
+               " " d_string "\n", \
+               d_args); \
+\
+        DBF_EVENT(DBF_ALERT, \
+                  d_string, \
+                  d_args); \
 } while(0)
 
 struct dasd_device_t;
 struct request;
 
-/* 
- * signatures for the functions of dasd_discipline_t 
+/********************************************************************************
+ * SECTION: signatures for the functions of dasd_discipline_t 
  * make typecasts much easier
- */
-typedef ccw_req_t *(*dasd_erp_action_fn_t) (ccw_req_t * cqr);
+ ********************************************************************************/
+
+typedef int    (*dasd_ck_id_fn_t)              (s390_dev_info_t *);
+typedef int    (*dasd_ck_characteristics_fn_t) (struct dasd_device_t *);
+typedef int    (*dasd_fill_geometry_fn_t)      (struct dasd_device_t *, 
+                                                struct hd_geometry *);
+typedef int    (*dasd_do_analysis_fn_t)        (struct dasd_device_t *);
+typedef int    (*dasd_io_starter_fn_t)         (ccw_req_t *);
+typedef int    (*dasd_io_stopper_fn_t)         (ccw_req_t *);
+typedef int    (*dasd_info_fn_t)               (struct dasd_device_t *, 
+                                                dasd_information2_t *);
+typedef int    (*dasd_use_count_fn_t)          (int);
+typedef int    (*dasd_set_attrib_fn_t)         (struct dasd_device_t *, 
+                                                struct attrib_data_t *);
+typedef void   (*dasd_int_handler_fn_t)        (int irq, void *, 
+                                                struct pt_regs *);
+typedef char * (*dasd_dump_sense_fn_t)         (struct dasd_device_t *,
+                                                ccw_req_t *);
+typedef ccw_req_t *(*dasd_format_fn_t)         (struct dasd_device_t *, 
+                                                struct format_data_t *);
+typedef ccw_req_t *(*dasd_init_analysis_fn_t ) (struct dasd_device_t *);
+typedef ccw_req_t *(*dasd_cp_builder_fn_t)     (struct dasd_device_t *,
+                                                struct request *);
+typedef ccw_req_t *(*dasd_reserve_fn_t)        (struct dasd_device_t *);
+typedef ccw_req_t *(*dasd_release_fn_t)        (struct dasd_device_t *);
+typedef ccw_req_t *(*dasd_steal_lock_fn_t)     (struct dasd_device_t *);
+typedef ccw_req_t *(*dasd_merge_cp_fn_t)       (struct dasd_device_t *);
+typedef ccw_req_t *(*dasd_erp_action_fn_t)     (ccw_req_t * cqr);
 typedef ccw_req_t *(*dasd_erp_postaction_fn_t) (ccw_req_t * cqr);
+typedef ccw_req_t *(*dasd_read_stats_fn_t)     (struct dasd_device_t *);
 
-typedef int (*dasd_ck_id_fn_t) (s390_dev_info_t *);
-typedef int (*dasd_ck_characteristics_fn_t) (struct dasd_device_t *);
-typedef int (*dasd_fill_geometry_fn_t) (struct dasd_device_t *, struct hd_geometry *);
-typedef ccw_req_t *(*dasd_format_fn_t) (struct dasd_device_t *, struct format_data_t *);
-typedef ccw_req_t *(*dasd_init_analysis_fn_t) (struct dasd_device_t *);
-typedef int (*dasd_do_analysis_fn_t) (struct dasd_device_t *);
-typedef int (*dasd_io_starter_fn_t) (ccw_req_t *);
-typedef int (*dasd_io_stopper_fn_t) (ccw_req_t *);
-typedef void (*dasd_int_handler_fn_t)(int irq, void *, struct pt_regs *);
-typedef dasd_era_t (*dasd_error_examine_fn_t) (ccw_req_t *, devstat_t * stat);
-typedef dasd_erp_action_fn_t (*dasd_error_analyse_fn_t) (ccw_req_t *);
-typedef dasd_erp_postaction_fn_t (*dasd_erp_analyse_fn_t) (ccw_req_t *);
-typedef ccw_req_t *(*dasd_cp_builder_fn_t)(struct dasd_device_t *,struct request *);
-typedef char *(*dasd_dump_sense_fn_t)(struct dasd_device_t *,ccw_req_t *);
-typedef ccw_req_t *(*dasd_reserve_fn_t)(struct dasd_device_t *);
-typedef ccw_req_t *(*dasd_release_fn_t)(struct dasd_device_t *);
-typedef ccw_req_t *(*dasd_steal_lock_fn_t)(struct dasd_device_t *);
-typedef ccw_req_t *(*dasd_merge_cp_fn_t)(struct dasd_device_t *);
-typedef int (*dasd_info_fn_t) (struct dasd_device_t *, dasd_information_t *);
-typedef int (*dasd_use_count_fn_t) (int);
+typedef dasd_rssd_perf_stats_t * (*dasd_ret_stats_fn_t)     (ccw_req_t *);
+typedef dasd_era_t               (*dasd_error_examine_fn_t) (ccw_req_t *, 
+                                                             devstat_t * stat);
+typedef dasd_erp_action_fn_t     (*dasd_error_analyse_fn_t) (ccw_req_t *);
+typedef dasd_erp_postaction_fn_t (*dasd_erp_analyse_fn_t)   (ccw_req_t *);
 
 /*
  * the dasd_discipline_t is
@@ -270,31 +357,31 @@
 	char ebcname[8]; /* a name used for tagging and printks */
         char name[8];		/* a name used for tagging and printks */
 	int max_blocks;	/* maximum number of blocks to be chained */
-	dasd_ck_id_fn_t id_check;	/* to check sense data */
-	dasd_ck_characteristics_fn_t check_characteristics;	/* to check the characteristics */
-	dasd_init_analysis_fn_t init_analysis;	/* to start the analysis of the volume */
-	dasd_do_analysis_fn_t do_analysis;	/* to complete the analysis of the volume */
-	dasd_fill_geometry_fn_t fill_geometry;	/* to set up hd_geometry */
-	dasd_io_starter_fn_t start_IO;
-	dasd_io_stopper_fn_t term_IO;
-        dasd_format_fn_t format_device;		/* to format the device */
-	dasd_error_examine_fn_t examine_error;
-	dasd_error_analyse_fn_t erp_action;
-	dasd_erp_analyse_fn_t erp_postaction;
-        dasd_cp_builder_fn_t build_cp_from_req;
-        dasd_dump_sense_fn_t dump_sense;
-        dasd_int_handler_fn_t int_handler;
-        dasd_reserve_fn_t reserve;
-        dasd_release_fn_t release;
-        dasd_steal_lock_fn_t steal_lock;
-        dasd_merge_cp_fn_t merge_cp;
-        dasd_info_fn_t fill_info;
+	dasd_ck_id_fn_t              id_check;	            /* check sense data */
+	dasd_ck_characteristics_fn_t check_characteristics; /* check the characteristics */
+	dasd_init_analysis_fn_t      init_analysis;	    /* start the analysis of the volume */
+	dasd_do_analysis_fn_t        do_analysis;	    /* complete the analysis of the volume */
+	dasd_fill_geometry_fn_t      fill_geometry;	    /* set up hd_geometry */
+	dasd_io_starter_fn_t         start_IO;                 
+	dasd_io_stopper_fn_t         term_IO;                  
+        dasd_format_fn_t             format_device;	    /* format the device */
+	dasd_error_examine_fn_t      examine_error;
+	dasd_error_analyse_fn_t      erp_action;
+	dasd_erp_analyse_fn_t        erp_postaction;
+        dasd_cp_builder_fn_t         build_cp_from_req;
+        dasd_dump_sense_fn_t         dump_sense;
+        dasd_int_handler_fn_t        int_handler;
+        dasd_reserve_fn_t            reserve;
+        dasd_release_fn_t            release;
+        dasd_steal_lock_fn_t         steal_lock;
+        dasd_merge_cp_fn_t           merge_cp;
+        dasd_info_fn_t               fill_info;
+        dasd_read_stats_fn_t         read_stats;
+        dasd_ret_stats_fn_t          ret_stats;             /* return performance statistics */
+        dasd_set_attrib_fn_t         set_attrib;            /* set attributes (cache operations */ 
 	struct list_head list;	/* used for list of disciplines */
 } dasd_discipline_t;
 
-#define DASD_DEFAULT_FEATURES 0
-#define DASD_FEATURE_READONLY 1
-
 /* dasd_range_t are used for ordering the DASD devices */
 typedef struct dasd_range_t {
 	unsigned int from;	/* first DASD in range */
@@ -326,7 +413,9 @@
 	struct dasd_chanq_t queue;
         wait_queue_head_t wait_q;
         request_queue_t *request_queue;
-        struct timer_list timer;      
+        struct timer_list timer;             /* used for start_IO */
+        struct timer_list late_timer;        /* to get late devices online */  
+        struct timer_list blocking_timer;    /* used for ERP */
 	devstat_t dev_status; /* needed ONLY!! for request_irq */
         dasd_sizes_t sizes;
         char name[16]; /* The name of the device in /dev */
@@ -340,35 +429,37 @@
         dasd_profile_info_t profile;
         ccw_req_t *init_cqr;
         atomic_t plugged;
-        void* lowmem_cqr;
-        void* lowmem_ccws;
-        void* lowmem_idals;
-        void* lowmem_idal_ptr;
+        int accessible; /* set to !=0 if doing IO is permitted */
+        struct list_head lowmem_pool;
 }  dasd_device_t;
 
-int dasd_init (void);
-void dasd_discipline_add(dasd_discipline_t *);
-void dasd_discipline_del(dasd_discipline_t *);
-int dasd_start_IO (ccw_req_t *);
-int dasd_term_IO (ccw_req_t *);
-void dasd_int_handler (int , void *, struct pt_regs *);
-ccw_req_t *dasd_default_erp_action (ccw_req_t *);
-ccw_req_t *dasd_default_erp_postaction (ccw_req_t *);
-inline void dasd_chanq_deq (dasd_chanq_t *, ccw_req_t *);
-inline void dasd_chanq_enq (dasd_chanq_t *, ccw_req_t *);
-inline void dasd_chanq_enq_head (dasd_chanq_t *, ccw_req_t *);
-ccw_req_t *dasd_alloc_request (char *, int, int, dasd_device_t *);
-void dasd_free_request (ccw_req_t *, dasd_device_t *);
-int dasd_oper_handler (int irq, devreg_t * devreg);
-void dasd_schedule_bh (dasd_device_t *);
-int dasd_sleep_on_req(ccw_req_t*);
-int  dasd_set_normalized_cda ( ccw1_t * cp, unsigned long address, ccw_req_t* request, dasd_device_t* device );
-dasd_device_t * dasd_device_from_kdev (kdev_t kdev);
+
+int  dasd_init               (void);
+void dasd_discipline_add     (dasd_discipline_t *);
+void dasd_discipline_del     (dasd_discipline_t *);
+int  dasd_start_IO           (ccw_req_t *);
+int  dasd_term_IO            (ccw_req_t *);
+void dasd_int_handler        (int , void *, struct pt_regs *);
+void dasd_free_request       (ccw_req_t *, dasd_device_t *);
+int  dasd_oper_handler       (int irq, devreg_t * devreg);
+void dasd_schedule_bh        (dasd_device_t *);
+void dasd_schedule_bh_timed  (unsigned long);
+int  dasd_sleep_on_req       (ccw_req_t*);
+int  dasd_set_normalized_cda (ccw1_t * cp, unsigned long address, 
+                              ccw_req_t* request, 
+                              dasd_device_t* device );
+ccw_req_t *     dasd_default_erp_action     (ccw_req_t *);
+ccw_req_t *     dasd_default_erp_postaction (ccw_req_t *);
+inline void     dasd_chanq_deq              (dasd_chanq_t *, ccw_req_t *);
+inline void     dasd_chanq_enq              (dasd_chanq_t *, ccw_req_t *);
+inline void     dasd_chanq_enq_head         (dasd_chanq_t *, ccw_req_t *);
+ccw_req_t *     dasd_alloc_request          (char *, int, int, dasd_device_t *);
+dasd_device_t * dasd_device_from_kdev       (kdev_t kdev);
 
 extern debug_info_t *dasd_debug_area;
 extern int (*genhd_dasd_name) (char *, int, int, struct gendisk *);
 extern int (*genhd_dasd_ioctl) (struct inode *inp, struct file *filp,
-                            unsigned int no, unsigned long data);
+                                unsigned int no, unsigned long data);
 
 #endif /* __KERNEL__ */
 
diff -urN linux-2.4.22-pre2/drivers/s390/char/con3215.c linux-2.4.22-pre3/drivers/s390/char/con3215.c
--- linux-2.4.22-pre2/drivers/s390/char/con3215.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/char/con3215.c	2003-07-05 18:10:26.000000000 -0700
@@ -462,30 +462,35 @@
                 if ((raw = req->info) == NULL)
                         return;              /* That shouldn't happen ... */
 		if (req->type == RAW3215_READ && raw->tty != NULL) {
-			char *cchar;
+			unsigned int cchar;
 
 			tty = raw->tty;
-                        count = 160 - req->residual;
-                        if (MACHINE_IS_P390) {
-                                slen = strnlen(raw->inbuf, RAW3215_INBUF_SIZE);
-                                if (count > slen)
-                                        count = slen;
-                        } else
+			count = 160 - req->residual;
+			if (MACHINE_IS_P390) {
+				slen = strnlen(raw->inbuf, RAW3215_INBUF_SIZE);
+				if (count > slen)
+					count = slen;
+			} else
 			if (count >= TTY_FLIPBUF_SIZE - tty->flip.count)
 				count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
 			EBCASC(raw->inbuf, count);
-			if ((cchar = ctrlchar_handle(raw->inbuf, count, tty))) {
-				if (cchar == (char *)-1)
-					goto in_out;
+			cchar = ctrlchar_handle(raw->inbuf, count, tty);
+			switch (cchar & CTRLCHAR_MASK) {
+			case CTRLCHAR_SYSRQ:
+				break;
+
+			case CTRLCHAR_CTRL:
 				tty->flip.count++;
 				*tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-				*tty->flip.char_buf_ptr++ = *cchar;
+				*tty->flip.char_buf_ptr++ = cchar;
 				tty_flip_buffer_push(raw->tty);
-			} else {
+				break;
+
+			case CTRLCHAR_NONE:
 				memcpy(tty->flip.char_buf_ptr,
 				       raw->inbuf, count);
 				if (count < 2 ||
-				    (strncmp(raw->inbuf+count-2, "^n", 2) ||
+				    (strncmp(raw->inbuf+count-2, "^n", 2) && 
 				    strncmp(raw->inbuf+count-2, "\252n", 2)) ) {
 					/* don't add the auto \n */
 					tty->flip.char_buf_ptr[count] = '\n';
@@ -498,12 +503,12 @@
 				tty->flip.flag_buf_ptr += count;
 				tty->flip.count += count;
 				tty_flip_buffer_push(raw->tty);
+				break;
 			}
 		} else if (req->type == RAW3215_WRITE) {
 			raw->count -= req->len;
                         raw->written -= req->len;
 		} 
-in_out:
 		raw->flags &= ~RAW3215_WORKING;
 		raw3215_free_req(req);
 		/* check for empty wait */
@@ -823,7 +828,8 @@
  *  The console structure for the 3215 console
  */
 static struct console con3215 = {
-	name:		"tty3215",
+	name:		"ttyS",
+	index:		0,
 	write:		con3215_write,
 	device:		con3215_device,
 	unblank:	con3215_unblank,
@@ -1120,6 +1126,9 @@
  */
 void __init tty3215_init(void)
 {
+	/* Don't bother registering the tty if we already skipped the console */
+	if (!CONSOLE_IS_3215)
+		return;
 	/*
 	 * Initialize the tty_driver structure
 	 * Entries in tty3215_driver that are NOT initialized:
diff -urN linux-2.4.22-pre2/drivers/s390/char/ctrlchar.c linux-2.4.22-pre3/drivers/s390/char/ctrlchar.c
--- linux-2.4.22-pre2/drivers/s390/char/ctrlchar.c	2001-09-30 12:26:07.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/char/ctrlchar.c	2003-07-05 18:10:26.000000000 -0700
@@ -8,32 +8,30 @@
  */
 
 #include <linux/config.h>
-#include <linux/types.h>
-#include <linux/tty.h>
-#include <linux/interrupt.h>
-
+#include <linux/stddef.h>
 #include <linux/sysrq.h>
+#include <linux/ctype.h>
+#include <linux/interrupt.h>
 
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/delay.h>
-#include <asm/cpcmd.h>
-#include <asm/irq.h>
+#include "ctrlchar.h"
 
 #ifdef CONFIG_MAGIC_SYSRQ
 static int ctrlchar_sysrq_key;
 static struct tq_struct ctrlchar_tq;
 
 static void
-ctrlchar_handle_sysrq(struct tty_struct *tty) {
-	handle_sysrq(ctrlchar_sysrq_key, NULL, NULL, tty);
+ctrlchar_handle_sysrq(void *tty)
+{
+	handle_sysrq(ctrlchar_sysrq_key, NULL, NULL, (struct tty_struct*) tty);
 }
 #endif
 
-void ctrlchar_init(void) {
+void
+ctrlchar_init(void)
+{
 #ifdef CONFIG_MAGIC_SYSRQ
 	static int init_done = 0;
-
+ 
 	if (init_done++)
 		return;
 	INIT_LIST_HEAD(&ctrlchar_tq.list);
@@ -48,49 +46,43 @@
  * @param buf Console input buffer.
  * @param len Length of valid data in buffer.
  * @param tty The tty struct for this console.
- * @return NULL, if nothing matched, (char *)-1, if buffer contents
- *         should be ignored, otherwise pointer to char to be inserted.
+ * @return CTRLCHAR_NONE, if nothing matched,
+ *         CTRLCHAR_SYSRQ, if sysrq was encountered
+ *         otherwise char to be inserted logically or'ed
+ *         with CTRLCHAR_CTRL
  */
-char *ctrlchar_handle(const char *buf, int len, struct tty_struct *tty) {
-
-	static char ret;
-
+unsigned int
+ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty)
+{
 	if ((len < 2) || (len > 3))
-		return NULL;
+		return CTRLCHAR_NONE;
+
 	/* hat is 0xb1 in codepage 037 (US etc.) and thus */
 	/* converted to 0x5e in ascii ('^') */
 	if ((buf[0] != '^') && (buf[0] != '\252'))
-		return NULL;
-	switch (buf[1]) {
+		return CTRLCHAR_NONE;
+
 #ifdef CONFIG_MAGIC_SYSRQ
-		case '-':
-			if (len == 3) {
-				ctrlchar_sysrq_key = buf[2];
-				ctrlchar_tq.data = tty;
-				queue_task(&ctrlchar_tq, &tq_immediate);
-				mark_bh(IMMEDIATE_BH);
-				return (char *)-1;
-			}
-			break;
+	/* racy */
+	if (len == 3 && buf[1] == '-') {
+		ctrlchar_sysrq_key = buf[2];
+		ctrlchar_tq.data = tty;
+		queue_task(&ctrlchar_tq, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
+		return CTRLCHAR_SYSRQ;
+	}
 #endif
-		case 'c':
-			if (len == 2) {
-				ret = INTR_CHAR(tty);
-				return &ret;
-			}
-			break;
-		case 'd':
-			if (len == 2) {
-				ret = EOF_CHAR(tty);
-				return &ret;
-			}
-			break;
-		case 'z':
-			if (len == 2) {
-				ret = SUSP_CHAR(tty);
-				return &ret;
-			}
-			break;
+
+	if (len != 2)
+		return CTRLCHAR_NONE;
+
+	switch (tolower(buf[1])) {
+	case 'c':
+		return INTR_CHAR(tty) | CTRLCHAR_CTRL;
+	case 'd':
+		return EOF_CHAR(tty)  | CTRLCHAR_CTRL;
+	case 'z':
+		return SUSP_CHAR(tty) | CTRLCHAR_CTRL;
 	}
-	return NULL;
+	return CTRLCHAR_NONE;
 }
diff -urN linux-2.4.22-pre2/drivers/s390/char/ctrlchar.h linux-2.4.22-pre3/drivers/s390/char/ctrlchar.h
--- linux-2.4.22-pre2/drivers/s390/char/ctrlchar.h	2001-07-25 14:12:02.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/char/ctrlchar.h	2003-07-05 18:10:26.000000000 -0700
@@ -7,9 +7,15 @@
  *
  */
 
-#include <linux/config.h>
-#include <linux/types.h>
 #include <linux/tty.h>
 
+extern unsigned int
+ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty);
 extern void ctrlchar_init(void);
-extern char *ctrlchar_handle(const char *buf, int len, struct tty_struct *tty);
+
+
+#define CTRLCHAR_NONE  (1 << 8)
+#define CTRLCHAR_CTRL  (2 << 8)
+#define CTRLCHAR_SYSRQ (3 << 8)
+
+#define CTRLCHAR_MASK (~0xffu)
diff -urN linux-2.4.22-pre2/drivers/s390/misc/chandev.c linux-2.4.22-pre3/drivers/s390/misc/chandev.c
--- linux-2.4.22-pre2/drivers/s390/misc/chandev.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/misc/chandev.c	2003-07-05 18:10:26.000000000 -0700
@@ -2470,6 +2470,7 @@
 					goto BadArgs;
 					
 				}
+				break;
 			case del_auto_msck_stridx*stridx_mult:
 			case (del_auto_msck_stridx*stridx_mult)|iscomma:
 				switch(ints[0])
@@ -2482,6 +2483,7 @@
 				default:
 					goto BadArgs;
 				}
+				break;
 			case del_noauto_stridx*stridx_mult:
 				chandev_free_all_list((list **)&chandev_noauto_head);
 				break;
diff -urN linux-2.4.22-pre2/drivers/s390/net/ctcmain.c linux-2.4.22-pre3/drivers/s390/net/ctcmain.c
--- linux-2.4.22-pre2/drivers/s390/net/ctcmain.c	2002-02-25 11:38:03.000000000 -0800
+++ linux-2.4.22-pre3/drivers/s390/net/ctcmain.c	2003-07-05 18:10:27.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * $Id: ctcmain.c,v 1.55 2001/12/03 14:28:45 felfert Exp $
+ * $Id: ctcmain.c,v 1.60 2003/06/18 11:16:32 cotte Exp $
  *
  * CTC / ESCON network driver
  *
@@ -35,7 +35,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.55 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.60 $
  *
  */
 
@@ -301,20 +301,44 @@
 	ctc_profile         prof;
 
 	unsigned char       *trans_skb_data;
+
+        __u16               logflags;
+
 } channel;
 
 #define CHANNEL_FLAGS_READ            0
 #define CHANNEL_FLAGS_WRITE           1
 #define CHANNEL_FLAGS_INUSE           2
 #define CHANNEL_FLAGS_BUFSIZE_CHANGED 4
+#define CHANNEL_FLAGS_FAILED          8
 #define CHANNEL_FLAGS_RWMASK 1
 #define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK)
 
+#define LOG_FLAG_ILLEGALPKT  1
+#define LOG_FLAG_ILLEGALSIZE 2
+#define LOG_FLAG_OVERRUN     4
+#define LOG_FLAG_NOMEM       8
+
 /**
  * Linked list of all detected channels.
  */
 static channel *channels = NULL;
 
+#define CTC_LOGLEVEL_INFO     1
+#define CTC_LOGLEVEL_NOTICE   2
+#define CTC_LOGLEVEL_WARN     4
+#define CTC_LOGLEVEL_EMERG    8  
+#define CTC_LOGLEVEL_ERR     16
+#define CTC_LOGLEVEL_DEBUG   32
+#define CTC_LOGLEVEL_CRIT    64
+
+#define CTC_LOGLEVEL_DEFAULT \
+(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT)
+
+#define CTC_LOGLEVEL_MAX     ((CTC_LOGLEVEL_CRIT<<1)-1)
+
+static int loglevel = CTC_LOGLEVEL_DEFAULT;
+
 #ifdef CTC_CHANDEV
 static int activated;
 #endif
@@ -336,7 +360,13 @@
 	struct proc_dir_entry   *proc_dentry;
 	struct proc_dir_entry   *proc_stat_entry;
 	struct proc_dir_entry   *proc_ctrl_entry;
+	struct proc_dir_entry   *proc_loglevel_entry;
 	int                     proc_registered;
+
+	/**
+	 * Timer for restarting after I/O Errors
+	 */
+	fsm_timer               restart_timer;
 } ctc_priv;
 
 /**
@@ -387,7 +417,7 @@
  */
 static void print_banner(void) {
 	static int printed = 0;
-	char vbuf[] = "$Revision: 1.55 $";
+	char vbuf[] = "$Revision: 1.60 $";
 	char *version = vbuf;
 
 	if (printed)
@@ -398,16 +428,17 @@
 			*p = '\0';
 	} else
 		version = " ??? ";
-	printk(KERN_INFO
-	       "CTC driver Version%swith"
+	if (loglevel & CTC_LOGLEVEL_INFO)
+		printk(KERN_INFO
+		       "CTC driver Version%swith"
 #ifndef CTC_CHANDEV
-	       "out"
+		       "out"
 #endif
-	       " CHANDEV support"
+		       " CHANDEV support"
 #ifdef DEBUG
-	       " (DEBUG-VERSION, " __DATE__ __TIME__ ")"
+		       " (DEBUG-VERSION, " __DATE__ __TIME__ ")"
 #endif
-	       " initialized\n", version);
+		       " initialized\n", version);
 	printed = 1;
 }
 
@@ -464,9 +495,10 @@
 
 				default:
 					type = channel_type_unknown;
-					printk(KERN_INFO
-					       "channel: Unknown model found "
-					       "3088-%02x\n", id->cu_model);
+					if (loglevel & CTC_LOGLEVEL_INFO)
+						printk(KERN_INFO
+						       "channel: Unknown model found "
+						       "3088-%02x\n", id->cu_model);
 			}
 			break;
 
@@ -517,6 +549,7 @@
 	DEV_EVENT_TXUP,
 	DEV_EVENT_RXDOWN,
 	DEV_EVENT_TXDOWN,
+	DEV_EVENT_RESTART,
 	/**
 	 * MUST be always the last element!!
 	 */
@@ -530,6 +563,7 @@
 	"TX up",
 	"RX down",
 	"TX down",
+	"Restart",
 };
 
 /**
@@ -699,6 +733,8 @@
 	ll_header *header;
 	int i;
 
+	if (!(loglevel & CTC_LOGLEVEL_DEBUG))
+		return;
 	p += offset;
 	bl = *((__u16*)p);
 	p += 2;
@@ -745,16 +781,25 @@
 		skb_pull(pskb, LL_HEADER_LENGTH);
 		if ((ch->protocol == CTC_PROTO_S390) &&
 		    (header->type != ETH_P_IP)) {
-			/**
-			 * Check packet type only if we stick strictly
-			 * to S/390's protocol of OS390. This only
-			 * supports IP. Otherwise allow any packet
-			 * type.
-			 */
-			printk(KERN_WARNING
-			       "%s Illegal packet type 0x%04x "
-			       "received, dropping\n",
-			       dev->name, header->type);
+#ifndef DEBUG
+		        if (!(ch->logflags & LOG_FLAG_ILLEGALPKT)) {
+#endif
+				/**
+				 * Check packet type only if we stick strictly
+				 * to S/390's protocol of OS390. This only
+				 * supports IP. Otherwise allow any packet
+				 * type.
+				 */
+				if (loglevel & CTC_LOGLEVEL_WARN)
+					printk(KERN_WARNING
+					       "%s Illegal packet type 0x%04x "
+					       "received, dropping\n",
+				       dev->name, header->type);
+				ch->logflags |= LOG_FLAG_ILLEGALPKT;
+#ifndef DEBUG
+			}
+#endif
+
 #ifdef DEBUG
 			ctc_dump_skb(pskb, -6);
 #endif
@@ -763,15 +808,20 @@
 			return;
 		}
 		pskb->protocol = ntohs(header->type);
-		header->length -= LL_HEADER_LENGTH;
-		if ((header->length == 0) ||
-		    (header->length > skb_tailroom(pskb)) ||
-		    (header->length > len)) {
-			printk(KERN_WARNING
-			       "%s Illegal packet size %d "
-			       "received (MTU=%d blocklen=%d), "
-			       "dropping\n", dev->name, header->length,
-			       dev->mtu, len);
+		if (header->length <= LL_HEADER_LENGTH) {
+#ifndef DEBUG
+		        if (!(ch->logflags & LOG_FLAG_ILLEGALSIZE)) {
+#endif
+				if (loglevel & CTC_LOGLEVEL_WARN)
+					printk(KERN_WARNING
+					       "%s Illegal packet size %d "
+					       "received (MTU=%d blocklen=%d), "
+					       "dropping\n", dev->name, header->length,
+					       dev->mtu, len);
+				ch->logflags |= LOG_FLAG_ILLEGALSIZE;
+#ifndef DEBUG
+			}
+#endif
 #ifdef DEBUG
 			ctc_dump_skb(pskb, -6);
 #endif
@@ -779,11 +829,22 @@
 			privptr->stats.rx_length_errors++;
 			return;
 		}
-		if (header->length > skb_tailroom(pskb)) {
-			printk(KERN_WARNING
-			       "%s Illegal packet size %d "
-			       "(beyond the end of received data), "
-			       "dropping\n", dev->name, header->length);
+		header->length -= LL_HEADER_LENGTH;
+		len -= LL_HEADER_LENGTH;
+		if ((header->length > skb_tailroom(pskb)) ||
+		    (header->length > len)) {
+#ifndef DEBUG
+		        if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
+#endif
+				if (loglevel & CTC_LOGLEVEL_WARN)
+					printk(KERN_WARNING
+					       "%s Illegal packet size %d "
+					       "(beyond the end of received data), "
+					       "dropping\n", dev->name, header->length);
+				ch->logflags |= LOG_FLAG_OVERRUN;
+#ifndef DEBUG
+			}
+#endif
 #ifdef DEBUG
 			ctc_dump_skb(pskb, -6);
 #endif
@@ -793,12 +854,20 @@
 		}
 		skb_put(pskb, header->length);
 		pskb->mac.raw = pskb->data;
-		len -= (LL_HEADER_LENGTH + header->length);
+		len -= header->length;
 		skb = dev_alloc_skb(pskb->len);
 		if (!skb) {
-			printk(KERN_WARNING
-			       "%s Out of memory in ctc_unpack_skb\n",
-			       dev->name);
+#ifndef DEBUG
+		        if (!(ch->logflags & LOG_FLAG_NOMEM)) {
+#endif
+				if (loglevel & CTC_LOGLEVEL_WARN)
+					printk(KERN_WARNING
+					       "%s Out of memory in ctc_unpack_skb\n",
+					       dev->name);
+				ch->logflags |= LOG_FLAG_NOMEM;
+#ifndef DEBUG
+			}
+#endif
 			privptr->stats.rx_dropped++;
 			return;
 		}
@@ -811,11 +880,29 @@
 			ctc_tty_netif_rx(skb);
 		else
 			netif_rx(skb);
+		/**
+		 * Successful rx; reset logflags
+		 */
+		ch->logflags = 0;
 		privptr->stats.rx_packets++;
 		privptr->stats.rx_bytes += skb->len;
 		if (len > 0) {
 			skb_pull(pskb, header->length);
-			skb_put(pskb, LL_HEADER_LENGTH);
+			if (skb_tailroom(pskb) < LL_HEADER_LENGTH) {
+#ifndef DEBUG
+				if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
+#endif
+					if (loglevel & CTC_LOGLEVEL_WARN)
+						printk(KERN_WARNING
+						       "%s Buffer overrun in ctc_unpack_skb\n",
+						       dev->name);
+					ch->logflags |= LOG_FLAG_OVERRUN;
+#ifndef DEBUG
+				}
+#endif
+				return;
+			}
+	                skb_put(pskb, LL_HEADER_LENGTH);
 		}
 	}
 }
@@ -846,24 +933,28 @@
 			fsm_event(ch->fsm, CH_EVENT_IO_SUCCESS, ch);
 			break;
 		case -EBUSY:
-			printk(KERN_INFO "ch-%04x: Busy !\n", ch->devno);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING "ch-%04x: Busy !\n", ch->devno);
 			fsm_event(ch->fsm, CH_EVENT_IO_EBUSY, ch);
 			break;
 		case -ENODEV:
-			printk(KERN_EMERG
-			       "ch-%04x: Invalid device called for IO\n",
-			       ch->devno);
+			if (loglevel & CTC_LOGLEVEL_EMERG)
+				printk(KERN_EMERG
+				       "ch-%04x: Invalid device called for IO\n",
+				       ch->devno);
 			fsm_event(ch->fsm, CH_EVENT_IO_ENODEV, ch);
 			break;
 		case -EIO:
-			printk(KERN_EMERG
-			       "ch-%04x: Status pending... \n", ch->devno);
+			if (loglevel & CTC_LOGLEVEL_EMERG)
+				printk(KERN_EMERG
+				       "ch-%04x: Status pending... \n", ch->devno);
 			fsm_event(ch->fsm, CH_EVENT_IO_EIO, ch);
 			break;
 		default:
-			printk(KERN_EMERG
-			       "ch-%04x: Unknown error in do_IO %04x\n",
-			       ch->devno, return_code);
+			if (loglevel & CTC_LOGLEVEL_EMERG)
+				printk(KERN_EMERG
+				       "ch-%04x: Unknown error in do_IO %04x\n",
+				       ch->devno, return_code);
 			fsm_event(ch->fsm, CH_EVENT_IO_UNKNOWN, ch);
 	}
 }
@@ -878,49 +969,58 @@
 	if (sense & SNS0_INTERVENTION_REQ) {
 		if (sense & 0x01)  {
 			if (ch->protocol != CTC_PROTO_LINUX_TTY)
-				printk(KERN_DEBUG
-				       "ch-%04x: Interface disc. or Sel. reset "
-				       "(remote)\n", ch->devno);
+				if (loglevel & CTC_LOGLEVEL_DEBUG)
+					printk(KERN_DEBUG
+					       "ch-%04x: Interface disc. or Sel. reset "
+					       "(remote)\n", ch->devno);
 			fsm_event(ch->fsm, CH_EVENT_UC_RCRESET, ch);
 		} else {
-			printk(KERN_DEBUG "ch-%04x: System reset (remote)\n",
-			       ch->devno);
+			if (loglevel & CTC_LOGLEVEL_DEBUG)
+				printk(KERN_DEBUG "ch-%04x: System reset (remote)\n",
+				       ch->devno);
 			fsm_event(ch->fsm, CH_EVENT_UC_RSRESET, ch);
 		}
 	} else if (sense & SNS0_EQUIPMENT_CHECK) {
 		if (sense & SNS0_BUS_OUT_CHECK) {
-			printk(KERN_WARNING
-			       "ch-%04x: Hardware malfunction (remote)\n",
-			       ch->devno);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ch-%04x: Hardware malfunction (remote)\n",
+				       ch->devno);
 			fsm_event(ch->fsm, CH_EVENT_UC_HWFAIL, ch);
 		} else {
-			printk(KERN_WARNING
-			       "ch-%04x: Read-data parity error (remote)\n",
-			       ch->devno);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ch-%04x: Read-data parity error (remote)\n",
+				       ch->devno);
 			fsm_event(ch->fsm, CH_EVENT_UC_RXPARITY, ch);
 		}
 	} else if (sense & SNS0_BUS_OUT_CHECK) {
 		if (sense & 0x04) {
-			printk(KERN_WARNING
-			       "ch-%04x: Data-streaming timeout)\n",
-			       ch->devno);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ch-%04x: Data-streaming timeout)\n",
+				       ch->devno);
 			fsm_event(ch->fsm, CH_EVENT_UC_TXTIMEOUT, ch);
 		} else {
-			printk(KERN_WARNING
-			       "ch-%04x: Data-transfer parity error\n",
-			       ch->devno);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ch-%04x: Data-transfer parity error\n",
+				       ch->devno);
 			fsm_event(ch->fsm, CH_EVENT_UC_TXPARITY, ch);
 		}
 	} else if (sense & SNS0_CMD_REJECT) {
-			printk(KERN_WARNING "ch-%04x: Command reject\n",
-			       ch->devno);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING "ch-%04x: Command reject\n",
+				       ch->devno);
 	} else if (sense == 0) {
-		printk(KERN_DEBUG "ch-%04x: Unit check ZERO\n", ch->devno);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "ch-%04x: Unit check ZERO\n", ch->devno);
 		fsm_event(ch->fsm, CH_EVENT_UC_ZERO, ch);
 	} else {
-		printk(KERN_WARNING
-		       "ch-%04x: Unit Check with sense code: %02x\n",
-		       ch->devno, sense);
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING
+			       "ch-%04x: Unit Check with sense code: %02x\n",
+			       ch->devno, sense);
 		fsm_event(ch->fsm, CH_EVENT_UC_UNKNOWN, ch);
 	}
 }
@@ -944,7 +1044,7 @@
 		ch->trans_skb = __dev_alloc_skb(ch->max_bufsize,
 						GFP_ATOMIC|GFP_DMA);
 		if (ch->trans_skb == NULL) {
-			if (warn)
+			if (warn && (loglevel & CTC_LOGLEVEL_WARN))
 				printk(KERN_WARNING
 				       "ch-%04x: Couldn't alloc %s trans_skb\n",
 				       ch->devno,
@@ -957,7 +1057,7 @@
 				       virt_to_phys(ch->trans_skb->data))) {
 			dev_kfree_skb(ch->trans_skb);
 			ch->trans_skb = NULL;
-			if (warn)
+			if (warn && (loglevel & CTC_LOGLEVEL_WARN))
 				printk(KERN_WARNING
 				       "ch-%04x: set_normalized_cda for %s "
 				       "trans_skb failed, dropping packets\n",
@@ -1009,7 +1109,7 @@
 	if (duration > ch->prof.tx_time)
 		ch->prof.tx_time = duration;
 
-	if (ch->devstat->rescnt != 0)
+	if ((ch->devstat->rescnt != 0) && (loglevel & CTC_LOGLEVEL_DEBUG))
 		printk(KERN_DEBUG "%s: TX not complete, remaining %d bytes\n",
 		       dev->name, ch->devstat->rescnt);
 	
@@ -1110,15 +1210,17 @@
 
 	fsm_deltimer(&ch->timer);
 	if (len < 8) {
-		printk(KERN_WARNING "%s: got packet with length %d < 8\n",
-		       dev->name, len);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "%s: got packet with length %d < 8\n",
+			       dev->name, len);
 		privptr->stats.rx_dropped++;
 		privptr->stats.rx_length_errors++;
 		goto again;
 	}
 	if (len > ch->max_bufsize) {
-		printk(KERN_WARNING "%s: got packet with length %d > %d\n",
-		       dev->name, len, ch->max_bufsize);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "%s: got packet with length %d > %d\n",
+			       dev->name, len, ch->max_bufsize);
 		privptr->stats.rx_dropped++;
 		privptr->stats.rx_length_errors++;
 		goto again;
@@ -1137,8 +1239,9 @@
 			break;
 	}
 	if ((len < block_len) || (len > check_len)) {
-		printk(KERN_WARNING "%s: got block length %d != rx length %d\n",
-		       dev->name, block_len, len);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "%s: got block length %d != rx length %d\n",
+			       dev->name, block_len, len);
 #ifdef DEBUG
 		ctc_dump_skb(skb, 0);
 #endif
@@ -1177,9 +1280,11 @@
 	channel *ch = (channel *)arg;
 	int     rc;
 
-	if (fsm_getstate(fi) == CH_STATE_TXIDLE)
-		printk(KERN_DEBUG "ch-%04x: remote side issued READ?, "
-		       "init ...\n", ch->devno);
+	if (fsm_getstate(fi) == CH_STATE_TXIDLE) {
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "ch-%04x: remote side issued READ?, "
+			       "init ...\n", ch->devno);
+	}
 	fsm_deltimer(&ch->timer);
 	if (ctc_checkalloc_buffer(ch, 1))
 		return;
@@ -1253,7 +1358,8 @@
 	fsm_deltimer(&ch->timer);
 	buflen = *((__u16 *)ch->trans_skb->data);
 #ifdef DEBUG
-	printk(KERN_DEBUG "%s: Initial RX count %d\n", dev->name, buflen);
+	if (loglevel & CTC_LOGLEVEL_DEBUG)
+		printk(KERN_DEBUG "%s: Initial RX count %d\n", dev->name, buflen);
 #endif
 	if (buflen >= CTC_INITIAL_BLOCKLEN) {
 		if (ctc_checkalloc_buffer(ch, 1))
@@ -1268,8 +1374,9 @@
 			fsm_event(((ctc_priv *)dev->priv)->fsm,
 				  DEV_EVENT_RXUP, dev);
 	} else {
-		printk(KERN_DEBUG "%s: Initial RX count %d not %d\n",
-		       dev->name, buflen, CTC_INITIAL_BLOCKLEN);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "%s: Initial RX count %d not %d\n",
+			       dev->name, buflen, CTC_INITIAL_BLOCKLEN);
 		ch_action_firstio(fi, event, arg);
 	}
 }
@@ -1318,19 +1425,22 @@
 	net_device *dev;
 
 	if (ch == NULL) {
-		printk(KERN_WARNING "ch_action_start ch=NULL\n");
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING "ch_action_start ch=NULL\n");
 		return;
 	}
 	if (ch->netdev == NULL) {
-		printk(KERN_WARNING "ch_action_start dev=NULL, irq=%d\n",
-		       ch->irq);
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING "ch_action_start dev=NULL, irq=%d\n",
+			       ch->irq);
 		return;
 	}
 	dev = ch->netdev;
 
 #ifdef DEBUG
-	printk(KERN_DEBUG "%s: %s channel start\n", dev->name,
-	       (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
+	if (loglevel & CTC_LOGLEVEL_DEBUG)
+		printk(KERN_DEBUG "%s: %s channel start\n", dev->name,
+		       (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
 #endif
 
 	if (ch->trans_skb != NULL) {
@@ -1347,12 +1457,14 @@
 		ch->ccw[1].flags    = CCW_FLAG_SLI | CCW_FLAG_CC;
 		ch->ccw[1].count    = 0;
 	}
-	if (ctc_checkalloc_buffer(ch, 0))
-		printk(KERN_NOTICE
-		       "%s: Could not allocate %s trans_skb, delaying "
-		       "allocation until first transfer\n",
-		       dev->name, 
-		       (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
+	if (ctc_checkalloc_buffer(ch, 0)) {
+		if (loglevel & CTC_LOGLEVEL_NOTICE)
+			printk(KERN_NOTICE
+			       "%s: Could not allocate %s trans_skb, delaying "
+			       "allocation until first transfer\n",
+			       dev->name, 
+			       (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
+	}
 
 #if LINUX_VERSION_CODE >= 0x020400
 	INIT_LIST_HEAD(&ch->tq.list);
@@ -1385,7 +1497,8 @@
 		ccw_check_return_code(ch, rc);
 	}
 #ifdef DEBUG
-	printk(KERN_DEBUG "ctc: %s(): leaving\n", __FUNCTION__);
+	if (loglevel & CTC_LOGLEVEL_DEBUG)
+		printk(KERN_DEBUG "ctc: %s(): leaving\n", __FUNCTION__);
 #endif
 }
 
@@ -1525,10 +1638,11 @@
 		return;
 	}
 
-	printk(KERN_DEBUG "%s: Error %s during %s channel setup state=%s\n",
-	       dev->name, ch_event_names[event],
-	       (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX",
-	       fsm_getstate_str(fi));
+	if (loglevel & CTC_LOGLEVEL_DEBUG)
+		printk(KERN_DEBUG "%s: Error %s during %s channel setup state=%s\n",
+		       dev->name, ch_event_names[event],
+		       (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX",
+		       fsm_getstate_str(fi));
 	if (CHANNEL_DIRECTION(ch->flags) == READ) {
 		fsm_newstate(fi, CH_STATE_RXERR);
 		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
@@ -1555,8 +1669,9 @@
 	net_device *dev = ch->netdev;
 
 	fsm_deltimer(&ch->timer);
-	printk(KERN_DEBUG "%s: %s channel restart\n", dev->name,
-	       (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
+	if (loglevel & CTC_LOGLEVEL_DEBUG)
+		printk(KERN_DEBUG "%s: %s channel restart\n", dev->name,
+		       (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
 	fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
 	oldstate = fsm_getstate(fi);
 	fsm_newstate(fi, CH_STATE_STARTWAIT);
@@ -1587,8 +1702,9 @@
 
 	if (event == CH_EVENT_TIMER) {
 		fsm_deltimer(&ch->timer);
-		printk(KERN_DEBUG "%s: Timeout during RX init handshake\n",
-		       dev->name);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "%s: Timeout during RX init handshake\n",
+			       dev->name);
 		if (ch->retry++ < 3)
 			ch_action_restart(fi, event, arg);
 		else {
@@ -1597,8 +1713,9 @@
 				  DEV_EVENT_RXDOWN, dev);
 		}
 	} else
-		printk(KERN_WARNING "%s: Error during RX init handshake\n",
-		       dev->name);
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING "%s: Error during RX init handshake\n",
+			       dev->name);
 }
 
 /**
@@ -1615,8 +1732,10 @@
 	net_device *dev = ch->netdev;
 
 	fsm_newstate(fi, CH_STATE_RXERR);
-	printk(KERN_WARNING "%s: RX initialization failed\n", dev->name);
-	printk(KERN_WARNING "%s: RX <-> RX connection detected\n", dev->name);
+	if (loglevel & CTC_LOGLEVEL_WARN) {
+		printk(KERN_WARNING "%s: RX initialization failed\n", dev->name);
+		printk(KERN_WARNING "%s: RX <-> RX connection detected\n", dev->name);
+	}
 	fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
 }
 
@@ -1634,8 +1753,9 @@
 	net_device *dev = ch->netdev;
 
 	fsm_deltimer(&ch->timer);
-	printk(KERN_DEBUG "%s: Got remote disconnect, re-initializing ...\n",
-	       dev->name);
+	if (loglevel & CTC_LOGLEVEL_DEBUG)
+		printk(KERN_DEBUG "%s: Got remote disconnect, re-initializing ...\n",
+		       dev->name);
 
 	/**
 	 * Notify device statemachine
@@ -1665,8 +1785,9 @@
 
 	if (event == CH_EVENT_TIMER) {
 		fsm_deltimer(&ch->timer);
-		printk(KERN_DEBUG "%s: Timeout during TX init handshake\n",
-		       dev->name);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "%s: Timeout during TX init handshake\n",
+			       dev->name);
 		if (ch->retry++ < 3)
 			ch_action_restart(fi, event, arg);
 		else {
@@ -1675,8 +1796,9 @@
 				  DEV_EVENT_TXDOWN, dev);
 		}
 	} else
-		printk(KERN_WARNING "%s: Error during TX init handshake\n",
-		       dev->name);
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING "%s: Error during TX init handshake\n",
+			       dev->name);
 }
 
 /**
@@ -1694,14 +1816,16 @@
 
 	fsm_deltimer(&ch->timer);
 	if (ch->retry++ > 3) {
-		printk(KERN_DEBUG "%s: TX retry failed, restarting channel\n",
-		       dev->name);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "%s: TX retry failed, restarting channel\n",
+			       dev->name);
 		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_TXDOWN, dev);
 		ch_action_restart(fi, event, arg);
 	} else {
 		struct sk_buff *skb;
 
-		printk(KERN_DEBUG "%s: TX retry %d\n", dev->name, ch->retry);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "%s: TX retry %d\n", dev->name, ch->retry);
 		if ((skb = skb_peek(&ch->io_queue))) {
 			int rc = 0;
 
@@ -1709,8 +1833,9 @@
 			ch->ccw[4].count = skb->len;
 			if (set_normalized_cda(&ch->ccw[4],
 					       virt_to_phys(skb->data))) {
-				printk(KERN_DEBUG "%s: IDAL alloc failed, "
-				       "restarting channel\n", dev->name);
+				if (loglevel & CTC_LOGLEVEL_DEBUG)
+					printk(KERN_DEBUG "%s: IDAL alloc failed, "
+					       "restarting channel\n", dev->name);
 				fsm_event(((ctc_priv *)dev->priv)->fsm,
 					  DEV_EVENT_TXDOWN, dev);
 				ch_action_restart(fi, event, arg);
@@ -1747,15 +1872,27 @@
 
 	fsm_deltimer(&ch->timer);
 	if (CHANNEL_DIRECTION(ch->flags) == READ) {
-		printk(KERN_DEBUG "%s: RX I/O error\n", dev->name);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "%s: RX I/O error\n", dev->name);
 		fsm_newstate(fi, CH_STATE_RXERR);
 		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
 	} else {
-		printk(KERN_DEBUG "%s: TX I/O error\n", dev->name);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "%s: TX I/O error\n", dev->name);
 		fsm_newstate(fi, CH_STATE_TXERR);
 		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_TXDOWN, dev);
 	}
 }
+
+static void ch_action_reinit(fsm_instance *fi, int event, void *arg)
+{
+	channel *ch = (channel *)arg;
+	net_device *dev = ch->netdev;
+	ctc_priv   *privptr = dev->priv;
+
+	ch_action_iofatal(fi, event, arg);
+	fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev);
+}
 
 /**
  * The statemachine for a channel.
@@ -1777,7 +1914,7 @@
 	{ CH_STATE_STARTWAIT,  CH_EVENT_FINSTAT,    ch_action_setmode    },
 	{ CH_STATE_STARTWAIT,  CH_EVENT_TIMER,      ch_action_setuperr   },
 	{ CH_STATE_STARTWAIT,  CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_STARTWAIT,  CH_EVENT_IO_EIO,     ch_action_iofatal    },
+	{ CH_STATE_STARTWAIT,  CH_EVENT_IO_EIO,     ch_action_reinit     },
 	{ CH_STATE_STARTWAIT,  CH_EVENT_MC_FAIL,    ch_action_fail       },
 
 	{ CH_STATE_STARTRETRY, CH_EVENT_STOP,       ch_action_haltio     },
@@ -1792,7 +1929,7 @@
 	{ CH_STATE_SETUPWAIT,  CH_EVENT_UC_RSRESET, ch_action_setuperr   },
 	{ CH_STATE_SETUPWAIT,  CH_EVENT_TIMER,      ch_action_setmode    },
 	{ CH_STATE_SETUPWAIT,  CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_SETUPWAIT,  CH_EVENT_IO_EIO,     ch_action_iofatal    },
+	{ CH_STATE_SETUPWAIT,  CH_EVENT_IO_EIO,     ch_action_reinit     },
 	{ CH_STATE_SETUPWAIT,  CH_EVENT_MC_FAIL,    ch_action_fail       },
 
 	{ CH_STATE_RXINIT,     CH_EVENT_STOP,       ch_action_haltio     },
@@ -1803,7 +1940,7 @@
 	{ CH_STATE_RXINIT,     CH_EVENT_TIMER,      ch_action_rxiniterr  },
 	{ CH_STATE_RXINIT,     CH_EVENT_ATTNBUSY,   ch_action_rxinitfail },
 	{ CH_STATE_RXINIT,     CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_RXINIT,     CH_EVENT_IO_EIO,     ch_action_iofatal    },
+	{ CH_STATE_RXINIT,     CH_EVENT_IO_EIO,     ch_action_reinit     },
 	{ CH_STATE_RXINIT,     CH_EVENT_UC_ZERO,    ch_action_firstio    },
 	{ CH_STATE_RXINIT,     CH_EVENT_MC_FAIL,    ch_action_fail       },
 
@@ -1813,7 +1950,7 @@
 	{ CH_STATE_RXIDLE,     CH_EVENT_UC_RCRESET, ch_action_rxdisc     },
 //	{ CH_STATE_RXIDLE,     CH_EVENT_UC_RSRESET, ch_action_rxretry    },
 	{ CH_STATE_RXIDLE,     CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_RXIDLE,     CH_EVENT_IO_EIO,     ch_action_iofatal    },
+	{ CH_STATE_RXIDLE,     CH_EVENT_IO_EIO,     ch_action_reinit     },
 	{ CH_STATE_RXIDLE,     CH_EVENT_MC_FAIL,    ch_action_fail       },
 	{ CH_STATE_RXIDLE,     CH_EVENT_UC_ZERO,    ch_action_rx         },
 
@@ -1824,7 +1961,7 @@
 	{ CH_STATE_TXINIT,     CH_EVENT_UC_RSRESET, ch_action_txiniterr  },
 	{ CH_STATE_TXINIT,     CH_EVENT_TIMER,      ch_action_txiniterr  },
 	{ CH_STATE_TXINIT,     CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_TXINIT,     CH_EVENT_IO_EIO,     ch_action_iofatal    },
+	{ CH_STATE_TXINIT,     CH_EVENT_IO_EIO,     ch_action_reinit     },
 	{ CH_STATE_TXINIT,     CH_EVENT_MC_FAIL,    ch_action_fail       },
 
 	{ CH_STATE_TXIDLE,     CH_EVENT_STOP,       ch_action_haltio     },
@@ -1833,7 +1970,7 @@
 	{ CH_STATE_TXIDLE,     CH_EVENT_UC_RCRESET, fsm_action_nop       },
 	{ CH_STATE_TXIDLE,     CH_EVENT_UC_RSRESET, fsm_action_nop       },
 	{ CH_STATE_TXIDLE,     CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_TXIDLE,     CH_EVENT_IO_EIO,     ch_action_iofatal    },
+	{ CH_STATE_TXIDLE,     CH_EVENT_IO_EIO,     ch_action_reinit     },
 	{ CH_STATE_TXIDLE,     CH_EVENT_MC_FAIL,    ch_action_fail       },
 
 	{ CH_STATE_TERM,       CH_EVENT_STOP,       fsm_action_nop       },
@@ -1857,7 +1994,7 @@
 	{ CH_STATE_TX,         CH_EVENT_UC_RSRESET, ch_action_txretry    },
 	{ CH_STATE_TX,         CH_EVENT_TIMER,      ch_action_txretry    },
 	{ CH_STATE_TX,         CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_TX,         CH_EVENT_IO_EIO,     ch_action_iofatal    },
+	{ CH_STATE_TX,         CH_EVENT_IO_EIO,     ch_action_reinit     },
 	{ CH_STATE_TX,         CH_EVENT_MC_FAIL,    ch_action_fail       },
 
 	{ CH_STATE_RXERR,      CH_EVENT_STOP,       ch_action_haltio     },
@@ -1889,14 +2026,16 @@
 	char name[10];
 
 	if ((ch = (channel *)kmalloc(sizeof(channel), GFP_KERNEL)) == NULL) {
-		printk(KERN_WARNING "ctc: Out of memory in add_channel\n");
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING "ctc: Out of memory in add_channel\n");
 		return -1;
 	}
 	memset(ch, 0, sizeof(channel));
 	if ((ch->ccw = (ccw1_t *)kmalloc(sizeof(ccw1_t) * 8,
 					 GFP_KERNEL|GFP_DMA)) == NULL) {
 		kfree(ch);
-		printk(KERN_WARNING "ctc: Out of memory in add_channel\n");
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING "ctc: Out of memory in add_channel\n");
 		return -1;
 	}
 
@@ -1932,20 +2071,23 @@
 	ch->irq = irq;
 	ch->devno = devno;
 	ch->type = type;
+	loglevel = CTC_LOGLEVEL_DEFAULT;
 	sprintf(name, "ch-%04x", devno);
 	ch->fsm = init_fsm(name, ch_state_names,
 			ch_event_names, NR_CH_STATES, NR_CH_EVENTS,
 			ch_fsm, CH_FSM_LEN, GFP_KERNEL);
 	if (ch->fsm == NULL) {
-		printk(KERN_WARNING
-		       "ctc: Could not create FSM in add_channel\n");
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING
+			       "ctc: Could not create FSM in add_channel\n");
 		kfree(ch);
 		return -1;
 	}
 	fsm_newstate(ch->fsm, CH_STATE_IDLE);
 	if ((ch->devstat = (devstat_t*)kmalloc(sizeof(devstat_t), GFP_KERNEL))
 	    == NULL) {
-		printk(KERN_WARNING "ctc: Out of memory in add_channel\n");
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING "ctc: Out of memory in add_channel\n");
 		kfree_fsm(ch->fsm);
 		kfree(ch);
 		return -1;
@@ -1954,9 +2096,10 @@
 	while (*c && ((*c)->devno < devno))
 		c = &(*c)->next;
 	if ((*c)->devno == devno) {
-		printk(KERN_DEBUG
-		       "ctc: add_channel: device %04x already in list, "
-		       "using old entry\n", (*c)->devno);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG
+			       "ctc: add_channel: device %04x already in list, "
+			       "using old entry\n", (*c)->devno);
 		kfree(ch->devstat);
 		kfree_fsm(ch->fsm);
 		kfree(ch);
@@ -2006,14 +2149,16 @@
 		}
 	}
 	if (print_result) {
-		if (nr_escon + nr_ctca)
-			printk(KERN_INFO
-			       "ctc: %d CTC/A channel%s and %d ESCON "
-			       "channel%s found.\n",
-			       nr_ctca, (nr_ctca == 1) ? "s" : "",
-			       nr_escon, (nr_escon == 1) ? "s" : "");
-		else
-			printk(KERN_INFO "ctc: No channel devices found.\n");
+		if (loglevel & CTC_LOGLEVEL_INFO) {
+			if (nr_escon + nr_ctca)
+				printk(KERN_INFO
+				       "ctc: %d CTC/A channel%s and %d ESCON "
+				       "channel%s found.\n",
+				       nr_ctca, (nr_ctca == 1) ? "s" : "",
+				       nr_escon, (nr_escon == 1) ? "s" : "");
+			else
+				printk(KERN_INFO "ctc: No channel devices found.\n");
+		}
 	}
 	print_result = 0;
 }
@@ -2079,28 +2224,32 @@
 	channel *ch = channels;
 
 #ifdef DEBUG
-	printk(KERN_DEBUG
-	       "ctc: %s(): searching for ch with devno %d and type %d\n",
-	       __FUNCTION__, devno, type);
+	if (loglevel & CTC_LOGLEVEL_DEBUG)
+		printk(KERN_DEBUG
+		       "ctc: %s(): searching for ch with devno %d and type %d\n",
+		       __FUNCTION__, devno, type);
 #endif
 
 	while (ch && ((ch->devno != devno) || (ch->type != type))) {
 #ifdef DEBUG
-		printk(KERN_DEBUG
-		       "ctc: %s(): ch=0x%p (devno=%d, type=%d\n",
-		       __FUNCTION__, ch, ch->devno, ch->type);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG
+			       "ctc: %s(): ch=0x%p (devno=%d, type=%d\n",
+			       __FUNCTION__, ch, ch->devno, ch->type);
 #endif
 		ch = ch->next;
 	}
 #ifdef DEBUG
-	printk(KERN_DEBUG
-	       "ctc: %s(): ch=0x%pq (devno=%d, type=%d\n",
-	       __FUNCTION__, ch, ch->devno, ch->type);
+	if (loglevel & CTC_LOGLEVEL_DEBUG)
+		printk(KERN_DEBUG
+		       "ctc: %s(): ch=0x%pq (devno=%d, type=%d\n",
+		       __FUNCTION__, ch, ch->devno, ch->type);
 #endif
 	if (!ch) {
-		printk(KERN_WARNING "ctc: %s(): channel with devno %d "
-		       "and type %d not found in channel list\n",
-	       __FUNCTION__, devno, type);
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING "ctc: %s(): channel with devno %d "
+			       "and type %d not found in channel list\n",
+			       __FUNCTION__, devno, type);
 	}
 	else {
 		if (ch->flags & CHANNEL_FLAGS_INUSE)
@@ -2197,39 +2346,43 @@
 	 */
 	if (ch == NULL) {
 		if ((ch = find_channel_by_irq(irq)) == NULL) {
-			printk(KERN_WARNING
-			       "ctc: Got unsolicited irq: %04x c-%02x d-%02x"
-			       "f-%02x\n", devstat->devno, devstat->cstat,
-			       devstat->dstat, devstat->flag);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ctc: Got unsolicited irq: %04x c-%02x d-%02x"
+				       "f-%02x\n", devstat->devno, devstat->cstat,
+				       devstat->dstat, devstat->flag);
 			goto done;
 		}
 	}
 
 	dev = (net_device *)(ch->netdev);
 	if (dev == NULL) {
-		printk(KERN_CRIT
-		       "ctc: ctc_irq_handler dev = NULL irq=%d, ch=0x%p\n",
-		       irq, ch);
+		if (loglevel & CTC_LOGLEVEL_CRIT)
+			printk(KERN_CRIT
+			       "ctc: ctc_irq_handler dev = NULL irq=%d, ch=0x%p\n",
+			       irq, ch);
 		goto done;
 	}
-	if (intparm == NULL)
+	if ((intparm == NULL) && (loglevel & CTC_LOGLEVEL_DEBUG))
 		printk(KERN_DEBUG "%s: Channel %04x found by IRQ %d\n",
 		       dev->name, ch->devno, irq);
 
 #ifdef DEBUG
-	printk(KERN_DEBUG
-	       "%s: interrupt for device: %04x received c-%02x d-%02x "
-	       "f-%02x\n", dev->name, devstat->devno, devstat->cstat,
-	       devstat->dstat, devstat->flag);
+	if (loglevel & CTC_LOGLEVEL_DEBUG)
+		printk(KERN_DEBUG
+		       "%s: interrupt for device: %04x received c-%02x d-%02x "
+		       "f-%02x\n", dev->name, devstat->devno, devstat->cstat,
+		       devstat->dstat, devstat->flag);
 #endif
 
 	/* Check for good subchannel return code, otherwise error message */
 	if (devstat->cstat) {
 		fsm_event(ch->fsm, CH_EVENT_SC_UNKNOWN, ch);
-		printk(KERN_WARNING
-		       "%s: subchannel check for device: %04x - %02x %02x "
-		       "%02x\n", dev->name, ch->devno, devstat->cstat,
-		       devstat->dstat, devstat->flag);
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING
+			       "%s: subchannel check for device: %04x - %02x %02x "
+			       "%02x\n", dev->name, ch->devno, devstat->cstat,
+			       devstat->dstat, devstat->flag);
 		goto done;
 	}
 
@@ -2274,6 +2427,7 @@
 	ctc_priv   *privptr = dev->priv;
 	int        direction;
 
+	fsm_deltimer(&privptr->restart_timer);
 	fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
 	for (direction = READ; direction <= WRITE; direction++) {
 		channel *ch = privptr->channel[direction];
@@ -2301,6 +2455,19 @@
 	}
 }
 
+static void dev_action_restart(fsm_instance *fi, int event, void *arg)
+{
+    net_device *dev = (net_device *)arg;
+    ctc_priv   *privptr = dev->priv;
+
+    if (loglevel & CTC_LOGLEVEL_DEBUG)
+	    printk(KERN_DEBUG "%s: Restarting\n", dev->name);
+    dev_action_stop(fi, event, arg);
+    fsm_event(privptr->fsm, DEV_EVENT_STOP, dev);
+    fsm_addtimer(&privptr->restart_timer, CTC_TIMEOUT_5SEC,
+		 DEV_EVENT_START, dev);
+}
+
 /**
  * Called from channel statemachine
  * when a channel is up and running.
@@ -2324,9 +2491,10 @@
 		case DEV_STATE_STARTWAIT_RX:
 			if (event == DEV_EVENT_RXUP) {
 				fsm_newstate(fi, DEV_STATE_RUNNING);
-				printk(KERN_INFO
-				       "%s: connected with remote side\n",
-				       dev->name);
+				if (loglevel & CTC_LOGLEVEL_INFO)
+					printk(KERN_INFO
+					       "%s: connected with remote side\n",
+					       dev->name);
 				if (privptr->protocol == CTC_PROTO_LINUX_TTY)
 					ctc_tty_setcarrier(dev, 1);
 				ctc_clear_busy(dev);
@@ -2335,9 +2503,10 @@
 		case DEV_STATE_STARTWAIT_TX:
 			if (event == DEV_EVENT_TXUP) {
 				fsm_newstate(fi, DEV_STATE_RUNNING);
-				printk(KERN_INFO
-				       "%s: connected with remote side\n",
-				       dev->name);
+				if (loglevel & CTC_LOGLEVEL_INFO)
+					printk(KERN_INFO
+					       "%s: connected with remote side\n",
+					       dev->name);
 				if (privptr->protocol == CTC_PROTO_LINUX_TTY)
 					ctc_tty_setcarrier(dev, 1);
 				ctc_clear_busy(dev);
@@ -2402,43 +2571,50 @@
 }
 
 static const fsm_node dev_fsm[] = {
-	{ DEV_STATE_STOPPED,        DEV_EVENT_START,   dev_action_start  },
+	{ DEV_STATE_STOPPED,        DEV_EVENT_START,   dev_action_start   },
 
-	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_START,   dev_action_start  },
-	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_RXDOWN,  dev_action_chdown },
-	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_TXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_START,   dev_action_start  },
-	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_RXUP,    dev_action_chup   },
-	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_TXUP,    dev_action_chup   },
-	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_RXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_START,   dev_action_start  },
-	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_RXUP,    dev_action_chup   },
-	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_TXUP,    dev_action_chup   },
-	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_TXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_STOP,    dev_action_stop   },
-	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXDOWN,  dev_action_chdown },
-	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_STOP,    dev_action_stop   },
-	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_RXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_TXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_RXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_STOP,    dev_action_stop   },
-	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_RXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_TXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_TXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_RUNNING,        DEV_EVENT_STOP,    dev_action_stop   },
-	{ DEV_STATE_RUNNING,        DEV_EVENT_RXDOWN,  dev_action_chdown },
-	{ DEV_STATE_RUNNING,        DEV_EVENT_TXDOWN,  dev_action_chdown },
-	{ DEV_STATE_RUNNING,        DEV_EVENT_TXUP,    fsm_action_nop    },
-	{ DEV_STATE_RUNNING,        DEV_EVENT_RXUP,    fsm_action_nop    },
+	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_START,   dev_action_start   },
+	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_RXDOWN,  dev_action_chdown  },
+	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_TXDOWN,  dev_action_chdown  },
+	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_RESTART, dev_action_restart },
+
+	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_START,   dev_action_start   },
+	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_RXUP,    dev_action_chup    },
+	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_TXUP,    dev_action_chup    },
+	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_RXDOWN,  dev_action_chdown  },
+	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_RESTART, dev_action_restart },
+
+	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_START,   dev_action_start   },
+	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_RXUP,    dev_action_chup    },
+	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_TXUP,    dev_action_chup    },
+	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_TXDOWN,  dev_action_chdown  },
+	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_RESTART, dev_action_restart },
+
+	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_STOP,    dev_action_stop    },
+	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXUP,    dev_action_chup    },
+	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXUP,    dev_action_chup    },
+	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXDOWN,  dev_action_chdown  },
+	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXDOWN,  dev_action_chdown  },
+	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart },
+
+	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_STOP,    dev_action_stop    },
+	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_RXUP,    dev_action_chup    },
+	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_TXUP,    dev_action_chup    },
+	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_RXDOWN,  dev_action_chdown  },
+	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_RESTART, dev_action_restart },
+
+	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_STOP,    dev_action_stop    },
+	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_RXUP,    dev_action_chup    },
+	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_TXUP,    dev_action_chup    },
+	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_TXDOWN,  dev_action_chdown  },
+	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_RESTART, dev_action_restart },
+
+	{ DEV_STATE_RUNNING,        DEV_EVENT_STOP,    dev_action_stop    },
+	{ DEV_STATE_RUNNING,        DEV_EVENT_RXDOWN,  dev_action_chdown  },
+	{ DEV_STATE_RUNNING,        DEV_EVENT_TXDOWN,  dev_action_chdown  },
+	{ DEV_STATE_RUNNING,        DEV_EVENT_TXUP,    fsm_action_nop     },
+	{ DEV_STATE_RUNNING,        DEV_EVENT_RXUP,    fsm_action_nop     },
+	{ DEV_STATE_RUNNING,        DEV_EVENT_RESTART, dev_action_restart },
 };
 
 static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);
@@ -2633,14 +2809,16 @@
 	 * Some sanity checks ...
 	 */
 	if (skb == NULL) {
-		printk(KERN_WARNING "%s: NULL sk_buff passed\n", dev->name);
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING "%s: NULL sk_buff passed\n", dev->name);
 		privptr->stats.tx_dropped++;
 		return 0;
 	}
 	if (skb_headroom(skb) < (LL_HEADER_LENGTH + 2)) {
-		printk(KERN_WARNING
-		       "%s: Got sk_buff with head room < %ld bytes\n",
-		       dev->name, LL_HEADER_LENGTH + 2);
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING
+			       "%s: Got sk_buff with head room < %ld bytes\n",
+			       dev->name, LL_HEADER_LENGTH + 2);
 		dev_kfree_skb(skb);
 		privptr->stats.tx_dropped++;
 		return 0;
@@ -2725,7 +2903,8 @@
 			privptr = (ctc_priv *)dev->priv;
 
 			if ((privptr->proc_ctrl_entry->low_ino == ino) ||
-			    (privptr->proc_stat_entry->low_ino == ino))
+			    (privptr->proc_stat_entry->low_ino == ino) ||
+			    (privptr->proc_loglevel_entry->low_ino == ino))
 				return dev;
 		}
 		ch = ch->next;
@@ -2844,6 +3023,91 @@
 	return ret;
 }
 
+#define LOGLEVEL_BUFSIZE 10
+
+static int ctc_loglevel_open(struct inode *inode, struct file *file)
+{
+	file->private_data = kmalloc(LOGLEVEL_BUFSIZE, GFP_KERNEL);
+	if (file->private_data == NULL)
+		return -ENOMEM;
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int ctc_loglevel_close(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static ssize_t ctc_loglevel_write(struct file *file, const char *buf, size_t count,
+			   loff_t *off)
+{
+	unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
+	net_device   *dev;
+	ctc_priv     *privptr;
+	char         *e;
+	int          bs1;
+	char         tmp[40];
+
+	if (!(dev = find_netdev_by_ino(ino)))
+		return -ENODEV;
+	if (off != &file->f_pos)
+		return -ESPIPE;
+
+	privptr = (ctc_priv *)dev->priv;
+
+	if (count >= 3)
+		return -EINVAL;
+
+	if (copy_from_user(tmp, buf, count))
+		return -EFAULT;
+	tmp[count+1] = '\0';
+	bs1 = simple_strtoul(tmp, &e, 0);
+
+	if ((bs1 > CTC_LOGLEVEL_MAX) ||
+	    (e && (!isspace(*e))))
+		return -EINVAL;
+
+	loglevel = bs1;
+	return count;
+}
+
+static ssize_t ctc_loglevel_read(struct file *file, char *buf, size_t count,
+			  loff_t *off)
+{
+	unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
+	char *sbuf = (char *)file->private_data;
+	net_device *dev;
+	ctc_priv *privptr;
+	ssize_t ret = 0;
+	char *p = sbuf;
+	int l;
+
+	if (!(dev = find_netdev_by_ino(ino)))
+		return -ENODEV;
+	if (off != &file->f_pos)
+		return -ESPIPE;
+
+	privptr = (ctc_priv *)dev->priv;
+
+	if (file->f_pos == 0)
+		sprintf(sbuf, "0x%02x\n", loglevel);
+
+	l = strlen(sbuf);
+	p = sbuf;
+	if (file->f_pos < l) {
+		p += file->f_pos;
+		l = strlen(p);
+		ret = (count > l) ? l : count;
+		if (copy_to_user(buf, p, ret))
+			return -EFAULT;
+	}
+	file->f_pos += ret;
+	return ret;
+}
+
 #define STATS_BUFSIZE 2048
 
 static int ctc_stat_open(struct inode *inode, struct file *file)
@@ -2946,6 +3210,13 @@
 	release: ctc_ctrl_close,
 };
 
+static struct file_operations ctc_loglevel_fops = {
+	read:    ctc_loglevel_read,
+	write:   ctc_loglevel_write,
+	open:    ctc_loglevel_open,
+	release: ctc_loglevel_close,
+};
+
 static struct inode_operations ctc_stat_iops = {
 #if LINUX_VERSION_CODE < 0x020363
 	default_file_ops: &ctc_stat_fops
@@ -2956,6 +3227,11 @@
 	default_file_ops: &ctc_ctrl_fops
 #endif
 };
+static struct inode_operations ctc_loglevel_iops = {
+#if LINUX_VERSION_CODE < 0x020363
+	default_file_ops: &ctc_loglevel_fops
+#endif
+};
 
 static struct proc_dir_entry stat_entry = {
 	0,                           /* low_ino */
@@ -2981,6 +3257,18 @@
 	&ctc_ctrl_iops               /* ops     */
 };
 
+static struct proc_dir_entry loglevel_entry = {
+	0,                           /* low_ino */
+	8,                           /* namelen */
+	"loglevel",                  /* name    */
+	S_IFREG | S_IRUSR | S_IWUSR, /* mode    */
+	1,                           /* nlink   */
+	0,                           /* uid     */
+	0,                           /* gid     */
+	0,                           /* size    */
+	&ctc_loglevel_iops           /* ops     */
+};
+
 #if LINUX_VERSION_CODE < 0x020363
 static struct proc_dir_entry ctc_dir = {
 	0,                           /* low_ino  */
@@ -3023,8 +3311,10 @@
 	 * If not registered, register main proc dir-entry now
 	 */
 #if LINUX_VERSION_CODE > 0x020362
+#ifdef CONFIG_PROC_FS
 	if (!ctc_dir)
 		ctc_dir = proc_mkdir("ctc", proc_net);
+#endif
 #else
 	if (ctc_dir.low_ino == 0)
 		proc_net_register(&ctc_dir);
@@ -3037,12 +3327,14 @@
  */
 static void ctc_proc_destroy_main(void) {
 #if LINUX_VERSION_CODE > 0x020362
+#ifdef CONFIG_PROC_FS
 	remove_proc_entry("ctc", proc_net);
+#endif
 #else
 	proc_net_unregister(ctc_dir.low_ino);
 #endif
 }
-#endif MODULE
+#endif /* MODULE */
 
 /**
  * Create a device specific subdirectory in /proc/net/ctc/ with the
@@ -3069,12 +3361,19 @@
 				  privptr->proc_dentry);
 	privptr->proc_ctrl_entry->proc_fops = &ctc_ctrl_fops;
 	privptr->proc_ctrl_entry->proc_iops = &ctc_ctrl_iops;
+	privptr->proc_loglevel_entry =
+		create_proc_entry("loglevel",
+				  S_IFREG | S_IRUSR | S_IWUSR,
+				  privptr->proc_dentry);
+	privptr->proc_loglevel_entry->proc_fops = &ctc_loglevel_fops;
+	privptr->proc_loglevel_entry->proc_iops = &ctc_loglevel_iops;
 #else
 	privptr->proc_dentry->name = dev->name;
 	privptr->proc_dentry->namelen = strlen(dev->name);
 	proc_register(&ctc_dir, privptr->proc_dentry);
 	proc_register(privptr->proc_dentry, privptr->proc_stat_entry);
 	proc_register(privptr->proc_dentry, privptr->proc_ctrl_entry);
+	proc_register(privptr->proc_dentry, privptr->proc_loglevel_entry);
 #endif
 	privptr->proc_registered = 1;
 }
@@ -3089,11 +3388,14 @@
 	if (!privptr->proc_registered)
 		return;
 #if LINUX_VERSION_CODE > 0x020362
+	remove_proc_entry("loglevel", privptr->proc_dentry);
 	remove_proc_entry("statistics", privptr->proc_dentry);
 	remove_proc_entry("buffersize", privptr->proc_dentry);
 	remove_proc_entry(privptr->proc_dentry->name, ctc_dir);
 #else
 	proc_unregister(privptr->proc_dentry,
+			privptr->proc_loglevel_entry->low_ino);
+	proc_unregister(privptr->proc_dentry,
 			privptr->proc_stat_entry->low_ino);
 	proc_unregister(privptr->proc_dentry,
 			privptr->proc_ctrl_entry->low_ino);
@@ -3144,8 +3446,9 @@
 	int noauto = 0;
 
 #ifdef DEBUG
-	printk(KERN_DEBUG
-	       "ctc: parse_opts(): *setup='%s', maxip=%d\n", *setup, maxip);
+	if (loglevel & CTC_LOGLEVEL_DEBUG)
+		printk(KERN_DEBUG
+		       "ctc: parse_opts(): *setup='%s', maxip=%d\n", *setup, maxip);
 #endif
 	if (*setup) {
 		*dev_name = *setup;
@@ -3154,8 +3457,9 @@
 		    strncmp(cur, "noauto", 6)) {
 			if ((*setup = strchr(cur, ':')))
 				*(*setup)++ = '\0';
-			printk(KERN_WARNING
-			       "ctc: Invalid device name or option '%s'\n",
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ctc: Invalid device name or option '%s'\n",
 			       cur);
 			return 1;
 		}
@@ -3185,10 +3489,11 @@
 					ints[i++] =
 						simple_strtoul(cur, NULL, 0);
 #ifdef DEBUG
-					printk(KERN_DEBUG
-					       "ctc: %s: ints[%d]=%d\n",
-					       __FUNCTION__,
-					       i-1, ints[i-1]);
+					if (loglevel & CTC_LOGLEVEL_DEBUG)
+						printk(KERN_DEBUG
+						       "ctc: %s: ints[%d]=%d\n",
+						       __FUNCTION__,
+						       i-1, ints[i-1]);
 #endif
 					if ((cur = strchr(cur, ':')) != NULL)
 						cur++;
@@ -3303,36 +3608,41 @@
 		read_dev = -1;
 		proto = CTC_PROTO_S390;
 #ifdef DEBUG
-		printk(KERN_DEBUG
-		       "ctc: ctc_setup(): setup='%s' dev_name='%s',"
-		       " ints[0]=%d)\n",
-		       setup, dev_name, ints[0]);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG
+			       "ctc: ctc_setup(): setup='%s' dev_name='%s',"
+			       " ints[0]=%d)\n",
+			       setup, dev_name, ints[0]);
 #endif DEBUG
 		if (dev_name == NULL) {
 			/**
 			 * happens if device name is not specified in
 			 * parameter line (cf. init/main.c:get_options()
 			 */
-			printk(KERN_WARNING
-			       "ctc: %s(): Device name not specified\n",
-			       __FUNCTION__);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ctc: %s(): Device name not specified\n",
+				       __FUNCTION__);
 			ctc_setup_return;
 		}
 
 #ifdef DEBUG
-		printk(KERN_DEBUG "name=´%s´ argc=%d\n", dev_name, ints[0]);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "name=´%s´ argc=%d\n", dev_name, ints[0]);
 #endif
 
 		if (strcmp(dev_name, "noauto") == 0) {
-			printk(KERN_INFO "ctc: autoprobing disabled\n");
+			if (loglevel & CTC_LOGLEVEL_INFO)
+				printk(KERN_INFO "ctc: autoprobing disabled\n");
 			ctc_no_auto = 1;
 			continue;
 		}
 
 		if (find_param(dev_name) != NULL) {
-			printk(KERN_WARNING
-			       "ctc: Definition for device %s already set. "
-			       "Ignoring second definition\n", dev_name);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ctc: Definition for device %s already set. "
+				       "Ignoring second definition\n", dev_name);
 			continue;
 		}
 
@@ -3340,9 +3650,10 @@
 			case 3: /* protocol type passed */
 				proto = ints[3];
 				if (proto > CTC_PROTO_MAX) {
-					printk(KERN_WARNING
-					       "%s: wrong protocol type "
-					       "passed\n", dev_name);
+					if (loglevel & CTC_LOGLEVEL_WARN)
+						printk(KERN_WARNING
+						       "%s: wrong protocol type "
+						       "passed\n", dev_name);
 					ctc_setup_return;
 				}
 			case 2: /* write channel passed */
@@ -3353,22 +3664,25 @@
 					write_dev = read_dev + 1;
 				break;
 			default:
-				printk(KERN_WARNING
-				       "ctc: wrong number of parameter "
-				       "passed (is: %d, expected: [1..3]\n",
-				       ints[0]);
+				if (loglevel & CTC_LOGLEVEL_WARN)
+					printk(KERN_WARNING
+					       "ctc: wrong number of parameter "
+					       "passed (is: %d, expected: [1..3]\n",
+					       ints[0]);
 				ctc_setup_return;
 		}
 		par = alloc_param();
 		if (!par) {
 #ifdef MODULE
-			printk(KERN_WARNING
-			       "ctc: Couldn't allocate setup param block\n");
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ctc: Couldn't allocate setup param block\n");
 #else
-			printk(KERN_WARNING
-			       "ctc: Number of device definitions in "
-			       " kernel commandline exceeds builtin limit "
-			       " of %d devices.\n", MAX_STATIC_DEVICES);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ctc: Number of device definitions in "
+				       " kernel commandline exceeds builtin limit "
+				       " of %d devices.\n", MAX_STATIC_DEVICES);
 #endif
 			ctc_setup_return;
 		}
@@ -3379,8 +3693,9 @@
 		par->next = params;
 		params = par;
 #ifdef DEBUG
-		printk(KERN_DEBUG "%s: protocol=%x read=%04x write=%04x\n",
-		       dev_name, proto, read_dev, write_dev);
+		if (loglevel & CTC_LOGLEVEL_DEBUG)
+			printk(KERN_DEBUG "%s: protocol=%x read=%04x write=%04x\n",
+			       dev_name, proto, read_dev, write_dev);
 #endif
 	}
 	ctc_setup_return;
@@ -3488,9 +3803,13 @@
         privptr->proc_ctrl_entry = (struct proc_dir_entry *)
 		(((char *)privptr) + sizeof(ctc_priv) +
 		 sizeof(ctc_template) + sizeof(stat_entry));
+        privptr->proc_loglevel_entry = (struct proc_dir_entry *)
+		(((char *)privptr) + sizeof(ctc_priv) +
+		 sizeof(ctc_template) + sizeof(stat_entry) + sizeof(ctrl_entry));
 	memcpy(privptr->proc_dentry, &ctc_template, sizeof(ctc_template));
 	memcpy(privptr->proc_stat_entry, &stat_entry, sizeof(stat_entry));
 	memcpy(privptr->proc_ctrl_entry, &ctrl_entry, sizeof(ctrl_entry));
+	memcpy(privptr->proc_loglevel_entry, &loglevel_entry, sizeof(loglevel_entry));
 	privptr->fsm = init_fsm("ctcdev", dev_state_names,
 			dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,
 			dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
@@ -3501,6 +3820,7 @@
 		return NULL;
 	}
 	fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
+	fsm_settimer(privptr->fsm, &privptr->restart_timer);
 	dev->mtu	         = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
 	dev->hard_start_xmit     = ctc_tx;
 	dev->open	         = ctc_open;
@@ -3540,10 +3860,11 @@
 				if (get_dev_info_by_irq(ch->irq, &devinfo))
 					ch->devno = devinfo.devno;
 				else
-					printk(KERN_WARNING
-					       "ctc_chandev_msck_notify: "
-					       "get_dev_info_by_irq failed for "
-					       "irq %d\n", ch->irq);
+					if (loglevel & CTC_LOGLEVEL_WARN)
+						printk(KERN_WARNING
+						       "ctc_chandev_msck_notify: "
+						       "get_dev_info_by_irq failed for "
+						       "irq %d\n", ch->irq);
 			}
 		}
 	switch (newstatus) {
@@ -3552,18 +3873,27 @@
 		case chandev_status_gone:
 			for (direction = READ; direction <= WRITE; direction++) {
 				channel *ch = privptr->channel[direction];
+				ch->flags |= CHANNEL_FLAGS_FAILED;
 				fsm_event(ch->fsm, CH_EVENT_MC_FAIL, ch);
 			}
-			printk(KERN_WARNING
-			       "ctc: %s channel deactivated\n", device->name);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ctc: %s channel deactivated\n", device->name);
 			break;
 		case chandev_status_all_chans_good:
 			for (direction = READ; direction <= WRITE; direction++) {
 				channel *ch = privptr->channel[direction];
+				if (!(ch->flags & CHANNEL_FLAGS_FAILED))
+					fsm_event(ch->fsm, CH_EVENT_MC_FAIL, ch);
+			}
+			for (direction = READ; direction <= WRITE; direction++) {
+				channel *ch = privptr->channel[direction];
+				ch->flags &= ~CHANNEL_FLAGS_FAILED;
 				fsm_event(ch->fsm, CH_EVENT_MC_GOOD, ch);
 			}
-			printk(KERN_WARNING
-			       "ctc: %s channel activated\n", device->name);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "ctc: %s channel activated\n", device->name);
 			break;
 		default:
 			break;
@@ -3605,8 +3935,9 @@
 			type = channel_type_escon;
 			break;
 		default:
-			printk(KERN_WARNING "ctc_chandev_probe called with "
-			       "unsupported channel type %d\n", info->chan_type);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING "ctc_chandev_probe called with "
+				       "unsupported channel type %d\n", info->chan_type);
 			return -ENODEV;
 	}
 	devno[READ]  = info->read.devno;
@@ -3622,7 +3953,8 @@
 
 	
 	if (!dev) {
-		printk(KERN_WARNING "ctc_init_netdevice failed\n");
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING "ctc_init_netdevice failed\n");
 		return -ENODEV;
 	}
 	
@@ -3653,10 +3985,11 @@
 				 dev->name,
 				 privptr->channel[direction]->devstat);
 		if (rc) {
-			printk(KERN_WARNING
-			       "%s: requested irq %d is busy rc=%02x\n",
-			       dev->name, privptr->channel[direction]->irq,
-			       rc);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "%s: requested irq %d is busy rc=%02x\n",
+				       dev->name, privptr->channel[direction]->irq,
+				       rc);
 			if (direction == WRITE) {
 				FREE_IRQ(privptr->channel[READ]->irq,
 					 privptr->channel[READ]->devstat);
@@ -3681,12 +4014,13 @@
 
 	print_banner();
 
-	printk(KERN_INFO
-	       "%s: read: ch %04x (irq %04x), "
-	       "write: ch %04x (irq %04x) proto: %d\n",
-	       dev->name, privptr->channel[READ]->devno,
-	       privptr->channel[READ]->irq, privptr->channel[WRITE]->devno,
-	       privptr->channel[WRITE]->irq, proto);
+	if (loglevel & CTC_LOGLEVEL_INFO)
+		printk(KERN_INFO
+		       "%s: read: ch %04x (irq %04x), "
+		       "write: ch %04x (irq %04x) proto: %d\n",
+		       dev->name, privptr->channel[READ]->devno,
+		       privptr->channel[READ]->irq, privptr->channel[WRITE]->devno,
+		       privptr->channel[WRITE]->irq, proto);
 
 	chandev_initdevice(info, dev, 0, dev->name,
 			   (proto == CTC_PROTO_LINUX_TTY)
@@ -3779,10 +4113,11 @@
 				 dev->name,
 				 privptr->channel[direction]->devstat);
 		if (rc) {
-			printk(KERN_WARNING
-			       "%s: requested irq %d is busy rc=%02x\n",
-			       dev->name, privptr->channel[direction]->irq,
-			       rc);
+			if (loglevel & CTC_LOGLEVEL_WARN)
+				printk(KERN_WARNING
+				       "%s: requested irq %d is busy rc=%02x\n",
+				       dev->name, privptr->channel[direction]->irq,
+				       rc);
 			if (direction == WRITE) {
 				FREE_IRQ(privptr->channel[READ]->irq,
 					 privptr->channel[READ]->devstat);
@@ -3801,12 +4136,13 @@
 
 	print_banner();
 
-	printk(KERN_INFO
-	       "%s: read: ch %04x (irq %04x), "
-	       "write: ch %04x (irq %04x) proto: %d\n",
-	       dev->name, privptr->channel[READ]->devno,
-	       privptr->channel[READ]->irq, privptr->channel[WRITE]->devno,
-	       privptr->channel[WRITE]->irq, proto);
+	if (loglevel & CTC_LOGLEVEL_INFO)
+		printk(KERN_INFO
+		       "%s: read: ch %04x (irq %04x), "
+		       "write: ch %04x (irq %04x) proto: %d\n",
+		       dev->name, privptr->channel[READ]->devno,
+		       privptr->channel[READ]->irq, privptr->channel[WRITE]->devno,
+		       privptr->channel[WRITE]->irq, proto);
 
 	return 0;
 }
@@ -3853,11 +4189,12 @@
 #ifdef CTC_CHANDEV
 	chandev_unregister(ctc_chandev_probe, 1);
 #endif
-	printk(KERN_INFO "CTC driver unloaded\n");
+	if (loglevel & CTC_LOGLEVEL_INFO)
+		printk(KERN_INFO "CTC driver unloaded\n");
 }
 
 #define ctc_init init_module
-#endif MODULE
+#endif /* MODULE */
 
 /**
  * Initialize module.
@@ -3878,8 +4215,9 @@
 	print_banner();
 
 #if defined(DEBUG) && !defined(CTC_CHANDEV)
-	printk(KERN_DEBUG
-	       "ctc: init_module(): got string '%s'\n", ctc);
+	if (loglevel & CTC_LOGLEVEL_DEBUG)
+		printk(KERN_DEBUG
+		       "ctc: init_module(): got string '%s'\n", ctc);
 #endif
 
 #ifndef CTC_CHANDEV
@@ -3939,24 +4277,28 @@
 					(cnt[itype])++);
 			}
 #ifdef DEBUG
-			printk(KERN_DEBUG "ctc: %s(): probing for device %s\n",
-						 __FUNCTION__, dev->name);
+			if (loglevel & CTC_LOGLEVEL_DEBUG)
+				printk(KERN_DEBUG "ctc: %s(): probing for device %s\n",
+				       __FUNCTION__, dev->name);
 #endif			
 			probed = 1;
 			if (ctc_probe(dev) == 0) {
 				ctc_priv *privptr = (ctc_priv *)dev->priv;
 #ifdef DEBUG
-				printk(KERN_DEBUG
-				       "ctc: %s(): probing succeeded\n",
-				       __FUNCTION__);
-				printk(KERN_DEBUG
-				       "ctc: %s(): registering device %s\n",
-				       __FUNCTION__, dev->name);
+				if (loglevel & CTC_LOGLEVEL_DEBUG) {
+					printk(KERN_DEBUG
+					       "ctc: %s(): probing succeeded\n",
+					       __FUNCTION__);
+					printk(KERN_DEBUG
+					       "ctc: %s(): registering device %s\n",
+					       __FUNCTION__, dev->name);
+				}
 #endif
 				if (ctc_netdev_register(dev) != 0) {
-					printk(KERN_WARNING
-					       "ctc: Couldn't register %s\n",
-					       dev->name);
+					if (loglevel & CTC_LOGLEVEL_WARN)
+						printk(KERN_WARNING
+						       "ctc: Couldn't register %s\n",
+						       dev->name);
 					FREE_IRQ(
 						privptr->channel[READ]->irq,
 						privptr->channel[READ]->devstat);
@@ -3969,17 +4311,19 @@
 					dev = NULL;
 				} else {
 #ifdef DEBUG
-					printk(KERN_DEBUG
-					       "ctc: %s(): register succeed\n",
-					       __FUNCTION__);
+					if (loglevel & CTC_LOGLEVEL_DEBUG)
+						printk(KERN_DEBUG
+						       "ctc: %s(): register succeed\n",
+						       __FUNCTION__);
 #endif			
 					activated++;
 				}
 			} else {
 #ifdef DEBUG
-				printk(KERN_DEBUG
-				       "ctc: %s(): probing failed\n",
-				       __FUNCTION__);
+				if (loglevel & CTC_LOGLEVEL_DEBUG)
+					printk(KERN_DEBUG
+					       "ctc: %s(): probing failed\n",
+					       __FUNCTION__);
 #endif			
 				dev = NULL;
 			}
@@ -3988,7 +4332,8 @@
 #endif /* CHANDEV */
 #if !defined(CTC_CHANDEV) && defined(MODULE)
 	if (!activated) {
-		printk(KERN_WARNING "ctc: No devices registered\n");
+		if (loglevel & CTC_LOGLEVEL_WARN)
+			printk(KERN_WARNING "ctc: No devices registered\n");
 		ret = -ENODEV;
 	}
 #endif
diff -urN linux-2.4.22-pre2/drivers/s390/net/ctctty.c linux-2.4.22-pre3/drivers/s390/net/ctctty.c
--- linux-2.4.22-pre2/drivers/s390/net/ctctty.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/net/ctctty.c	2003-07-05 18:10:27.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * $Id: ctctty.c,v 1.8 2001/05/16 16:28:31 felfert Exp $
+ * $Id: ctctty.c,v 1.11 2003/05/14 15:27:54 felfert Exp $
  *
  * CTC / ESCON network driver, tty interface.
  *
@@ -88,6 +88,7 @@
   struct semaphore      write_sem;
   struct tq_struct      tq;
   struct timer_list     stoptimer;
+  struct timer_list	flowtimer;
 } ctc_tty_info;
 
 /* Description of one CTC-tty */
@@ -114,7 +115,7 @@
 static char *ctc_ttyname = CTC_TTY_NAME;
 #endif
 
-char *ctc_tty_revision = "$Revision: 1.8 $";
+char *ctc_tty_revision = "$Revision: 1.11 $";
 
 static __u32 ctc_tty_magic = CTC_ASYNC_MAGIC;
 static int ctc_tty_shuttingdown = 0;
@@ -163,35 +164,44 @@
 static int
 ctc_tty_readmodem(ctc_tty_info *info)
 {
-	int ret = 1;
+	int c;
 	struct tty_struct *tty;
+	struct sk_buff *skb;
 
-	if ((tty = info->tty)) {
-		if (info->mcr & UART_MCR_RTS) {
-			int c = TTY_FLIPBUF_SIZE - tty->flip.count;
-			struct sk_buff *skb;
-			
-			if ((c > 0) && (skb = skb_dequeue(&info->rx_queue))) {
-				int len = skb->len;
-				if (len > c)
-					len = c;
-				memcpy(tty->flip.char_buf_ptr, skb->data, len);
-				skb_pull(skb, len);
-				memset(tty->flip.flag_buf_ptr, 0, len);
-				tty->flip.count += len;
-				tty->flip.char_buf_ptr += len;
-				tty->flip.flag_buf_ptr += len;
-				tty_flip_buffer_push(tty);
-				if (skb->len > 0)
-					skb_queue_head(&info->rx_queue, skb);
-				else {
-					kfree_skb(skb);
-					ret = skb_queue_len(&info->rx_queue);
-				}
-			}
+	if (!(tty = info->tty)) 
+		return 0;
+
+	/* If the upper layer is flow blocked or just
+   	 * has no room for data we schedule a timer to 
+	 * try again later - wilder
+	 */
+	c = TTY_FLIPBUF_SIZE - tty->flip.count;
+	if ( !(info->mcr & UART_MCR_RTS) || (c <= 0) ) {
+		/* can't do any work now, wake up later */
+		mod_timer(&info->flowtimer, jiffies+(HZ/100) );
+		return 0;
+	}
+
+	if ((skb = skb_dequeue(&info->rx_queue))) {
+		int len = skb->len;
+		if (len > c)
+			len = c;
+		memcpy(tty->flip.char_buf_ptr, skb->data, len);
+		skb_pull(skb, len);
+		memset(tty->flip.flag_buf_ptr, 0, len);
+		tty->flip.count += len;
+		tty->flip.char_buf_ptr += len;
+		tty->flip.flag_buf_ptr += len;
+		tty_flip_buffer_push(tty);
+
+		if (skb->len > 0){
+			skb_queue_head(&info->rx_queue, skb);
+		}else {
+			kfree_skb(skb);
 		}
 	}
-	return ret;
+
+	return  skb_queue_len(&info->rx_queue);
 }
 
 void
@@ -234,6 +244,11 @@
 		dev_kfree_skb(skb);
 		return;
 	}
+	if ( !(info->tty) ) {
+		dev_kfree_skb(skb);
+		return;
+        }
+
 	if (skb->len < 6) {
 		dev_kfree_skb(skb);
 		return;
@@ -244,7 +259,7 @@
 	}
 	skb_pull(skb, sizeof(__u32));
 
-	i = *((int *)skb->data);
+	i = *((__u32 *)skb->data);
 	skb_pull(skb, sizeof(info->mcr));
 	if (i & UART_MCR_RTS) {
 		info->msr |= UART_MSR_CTS;
@@ -270,7 +285,12 @@
 	/* Direct deliver failed or queue wasn't empty.
 	 * Queue up for later dequeueing via timer-irq.
 	 */
-	skb_queue_tail(&info->rx_queue, skb);
+	if (skb_queue_len(&info->rx_queue) < 50)
+		skb_queue_tail(&info->rx_queue, skb);
+	else {
+		kfree_skb(skb);
+		printk(KERN_DEBUG "ctctty: RX overrun\n");
+	}
 	/* Schedule dequeuing */
 	queue_task(&info->tq, &tq_immediate);
 	mark_bh(IMMEDIATE_BH);
@@ -330,6 +350,13 @@
 			skb_queue_head(&info->tx_queue, skb);
 		else
 			kfree_skb(skb);
+
+	/* The connection is not up yet, try again in one second. - wilder */
+		if ( rc == -EBUSY ){ 
+			mod_timer(&info->flowtimer, jiffies+(HZ) );
+			return 0;
+		}
+
 	} else {
 		struct tty_struct *tty = info->tty;
 
@@ -484,6 +511,18 @@
 	info->flags &= ~CTC_ASYNC_NETDEV_OPEN;
 }
 
+/* Run from the timer queue when we are flow blocked
+ * to kick start the bottom half - wilder */
+static void
+ctc_tty_startupbh(unsigned long data)
+{
+	ctc_tty_info *info = (ctc_tty_info *)data;
+	if (( !ctc_tty_shuttingdown) && info) {
+		queue_task(&info->tq, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
+	}
+}
+
 /*
  * This routine will shutdown a serial port; interrupts are disabled, and
  * DTR is dropped if the hangup on close termio flag is on.
@@ -577,6 +616,12 @@
 
 	if (ctc_tty_paranoia_check(info, tty->device, "ctc_tty_write_room"))
 		return 0;
+
+/* wilder */
+	if (skb_queue_len(&info->tx_queue) > 10 ) {
+		return 0;
+	}
+
 	return CTC_TTY_XMIT_SIZE;
 }
 
@@ -1262,6 +1307,9 @@
 		init_timer(&info->stoptimer);
 		info->stoptimer.function = ctc_tty_stopdev;
 		info->stoptimer.data = (unsigned long)info;
+		init_timer(&info->flowtimer);
+                info->flowtimer.function = ctc_tty_startupbh;
+                info->flowtimer.data = (unsigned long)info;
 		info->mcr = UART_MCR_RTS;
 	}
 	return 0;
diff -urN linux-2.4.22-pre2/drivers/s390/net/fsm.h linux-2.4.22-pre3/drivers/s390/net/fsm.h
--- linux-2.4.22-pre2/drivers/s390/net/fsm.h	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/net/fsm.h	2003-07-05 18:10:27.000000000 -0700
@@ -1,4 +1,4 @@
-/* $Id: fsm.h,v 1.4 2001/09/24 10:38:02 mschwide Exp $
+/* $Id: fsm.h,v 1.5 2002/08/05 09:07:56 heicarst Exp $
  */
 #ifndef _FSM_H_
 #define _FSM_H_
diff -urN linux-2.4.22-pre2/drivers/s390/net/iucv.c linux-2.4.22-pre3/drivers/s390/net/iucv.c
--- linux-2.4.22-pre2/drivers/s390/net/iucv.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/net/iucv.c	2003-07-05 18:10:28.000000000 -0700
@@ -1,5 +1,5 @@
 /* 
- * $Id: iucv.c,v 1.32 2002/02/12 21:52:20 felfert Exp $
+ * $Id: iucv.c,v 1.41 2003/06/24 16:05:32 felfert Exp $
  *
  * IUCV network driver
  *
@@ -29,7 +29,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.32 $
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.41 $
  *
  */
 
@@ -89,6 +89,8 @@
 
 static spinlock_t iucv_lock = SPIN_LOCK_UNLOCKED;
 
+static int messagesDisabled = 0;
+
 /***************INTERRUPT HANDLING ***************/
 
 typedef struct {
@@ -302,7 +304,7 @@
 	if (debuglevel < 3)
 		return;
 
-	printk(KERN_DEBUG __FUNCTION__ ": %s\n", title);
+	printk(KERN_DEBUG "%s: %s\n", __FUNCTION__, title);
 	printk("  ");
 	for (i = 0; i < len; i++) {
 		if (!(i % 16) && i != 0)
@@ -318,7 +320,7 @@
 #define iucv_debug(lvl, fmt, args...) \
 do { \
 	if (debuglevel >= lvl) \
-		printk(KERN_DEBUG __FUNCTION__ ": " fmt "\n" , ## args); \
+		printk(KERN_DEBUG __FUNCTION__ ": " fmt "\n", ## args); \
 } while (0)
 
 #else
@@ -338,7 +340,7 @@
 static void
 iucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.32 $";
+	char vbuf[] = "$Revision: 1.41 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
@@ -384,6 +386,14 @@
 		return -ENOMEM;
 	}
 	memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE);
+#if 0
+        /* Show parameter pool on startup */
+	{
+	    int i;
+	    for (i = 0; i < PARAM_POOL_SIZE; i++)
+		printk("iparm[%d] at %p\n", i, &iucv_param_pool[i]);
+	}
+#endif
 
 	/* Initialize task queue */
 	INIT_LIST_HEAD(&iucv_tq.list);
@@ -429,7 +439,7 @@
 grab_param(void)
 {
 	iucv_param *ret;
-	static int i = 0;
+	int i = 0;
 
 	while (atomic_compare_and_swap(0, 1, &iucv_param_pool[i].in_use)) {
 		i++;
@@ -1047,6 +1057,7 @@
 	      iucv_handle_t handle, void *pgm_data)
 {
 	iparml_control *parm;
+	iparml_control local_parm;
 	struct list_head *lh;
 	ulong b2f0_result = 0;
 	ulong flags;
@@ -1103,24 +1114,50 @@
 		EBC_TOUPPER(parm->iptarget, sizeof(parm->iptarget));
 	}
 
+	/* In order to establish an IUCV connection, the procedure is:
+	 *
+	 * b2f0(CONNECT)
+	 * take the ippathid from the b2f0 call
+	 * register the handler to the ippathid
+	 * 
+	 * Unfortunately, the ConnectionEstablished message gets sent after the
+	 * b2f0(CONNECT) call but before the register is handled.
+	 *
+	 * In order for this race condition to be eliminated, the IUCV Control
+	 * Interrupts must be disabled for the above procedure.
+	 *
+	 * David Kennedy <dkennedy@linuxcare.com>
+	 */
+
+	/* Enable everything but IUCV Control messages */
+	iucv_setmask(~(AllInterrupts));
+	messagesDisabled = 1;
+
 	parm->ipflags1 = (__u8)flags1;
 	b2f0_result = b2f0(CONNECT, parm);
+	memcpy(&local_parm, parm, sizeof(local_parm));
+	release_param(parm);
+	parm = &local_parm;
 
 	if (b2f0_result) {
-		release_param(parm);
+		iucv_setmask(~0);
+		messagesDisabled = 0;
 		return b2f0_result;
 	}
 
 	add_pathid_result = iucv_add_pathid(parm->ippathid, h);
 	*pathid = parm->ippathid;
 
+	/* Enable everything again */
+	iucv_setmask(IUCVControlInterruptsFlag);
+
 	if (msglim)
 		*msglim = parm->ipmsglim;
 	if (flags1_out)
 		*flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0;
 
 	if (add_pathid_result) {
-		iucv_sever(parm->ippathid, no_memory);
+		iucv_sever(*pathid, no_memory);
 		printk(KERN_WARNING "%s: add_pathid failed with rc ="
 			" %d\n", __FUNCTION__, add_pathid_result);
 		return(add_pathid_result);
@@ -1736,6 +1773,7 @@
 {
 	iparml_db *parm;
 	ulong b2f0_result;
+	iucv_param save_param;
 
 	iucv_debug(2, "entering");
 
@@ -1752,7 +1790,13 @@
 	parm->ipmsgtag = msgtag;
 	parm->ipflags1 = (IPNORPY | flags1);	/* one way priority message */
 
+	memcpy((void *)&save_param, (void *)parm, sizeof(iucv_param));
 	b2f0_result = b2f0(SEND, parm);
+	if (b2f0_result != 0) {
+	    printk("b2f0 call returned %lx\n", b2f0_result);
+	    iucv_dumpit("PL before:", &save_param, sizeof(iucv_param));
+	    iucv_dumpit("PL after:", parm, sizeof(iucv_param));
+	}
 
 	if ((b2f0_result == 0) && (msgid))
 		*msgid = parm->ipmsgid;
@@ -2103,6 +2147,24 @@
 	return b2f0_result;
 }
 
+void
+iucv_setmask_cpu0 (void *result)
+{
+	iparml_set_mask *parm;
+
+	if (smp_processor_id() != 0)
+		return;
+
+	iucv_debug(1, "entering");
+	parm = (iparml_set_mask *)grab_param();
+	parm->ipmask = *((__u8*)result);
+	*((ulong *)result) = b2f0(SETMASK, parm);
+	release_param(parm);
+
+	iucv_debug(1, "b2f0_result = %ld", *((ulong *)result));
+	iucv_debug(1, "exiting");
+}
+
 /*
  * Name: iucv_setmask
  * Purpose: This function enables or disables the following IUCV
@@ -2113,28 +2175,25 @@
  *           0x40 - Priority_MessagePendingInterruptsFlag
  *           0x20 - Nonpriority_MessageCompletionInterruptsFlag
  *           0x10 - Priority_MessageCompletionInterruptsFlag
+ *           0x08 - IUCVControlInterruptsFlag
  * Output: NA
  * Return: b2f0_result - return code from CP
 */
 int
 iucv_setmask (int SetMaskFlag)
 {
-	iparml_set_mask *parm;
-	ulong b2f0_result = 0;
-
-	iucv_debug(1, "entering");
-
-	parm = (iparml_set_mask *)grab_param();
-
-	parm->ipmask = (__u8)SetMaskFlag;
-
-	b2f0_result = b2f0(SETMASK, parm);
-	release_param(parm);
+	union {
+		ulong result;
+		__u8  param;
+	} u;
 
-	iucv_debug(1, "b2f0_result = %ld", b2f0_result);
-	iucv_debug(1, "exiting");
+	u.param = SetMaskFlag;
+	if (smp_processor_id() == 0)
+		iucv_setmask_cpu0(&u);
+	else
+		smp_call_function(iucv_setmask_cpu0, &u, 0, 1);
 
-	return b2f0_result;
+	return u.result;
 }
 
 /**
@@ -2250,6 +2309,10 @@
 	/* end of if statement */
 	switch (int_buf->iptype) {
 		case 0x01:		/* connection pending */
+			if (messagesDisabled) {
+			    iucv_setmask(~0);
+			    messagesDisabled = 0;
+			}
 			spin_lock_irqsave(&iucv_lock, flags);
 			list_for_each(lh, &iucv_handler_table) {
 				h = list_entry(lh, handler, list);
@@ -2298,11 +2361,17 @@
 			break;
 			
 		case 0x02:		/*connection complete */
+			if (messagesDisabled) {
+			    iucv_setmask(~0);
+			    messagesDisabled = 0;
+			}
 			if (h) {
 				if (interrupt->ConnectionComplete)
+				{
 					interrupt->ConnectionComplete(
 						(iucv_ConnectionComplete *)int_buf,
 						h->pgm_data);
+				}
 				else
 					iucv_debug(1,
 						   "ConnectionComplete not called");
@@ -2311,6 +2380,10 @@
 			break;
 			
 		case 0x03:		/* connection severed */
+			if (messagesDisabled) {
+			    iucv_setmask(~0);
+			    messagesDisabled = 0;
+			}
 			if (h) {
 				if (interrupt->ConnectionSevered)
 					interrupt->ConnectionSevered(
@@ -2324,6 +2397,10 @@
 			break;
 			
 		case 0x04:		/* connection quiesced */
+			if (messagesDisabled) {
+			    iucv_setmask(~0);
+			    messagesDisabled = 0;
+			}
 			if (h) {
 				if (interrupt->ConnectionQuiesced)
 					interrupt->ConnectionQuiesced(
@@ -2336,6 +2413,10 @@
 			break;
 			
 		case 0x05:		/* connection resumed */
+			if (messagesDisabled) {
+			    iucv_setmask(~0);
+			    messagesDisabled = 0;
+			}
 			if (h) {
 				if (interrupt->ConnectionResumed)
 					interrupt->ConnectionResumed(
diff -urN linux-2.4.22-pre2/drivers/s390/net/iucv.h linux-2.4.22-pre3/drivers/s390/net/iucv.h
--- linux-2.4.22-pre2/drivers/s390/net/iucv.h	2003-07-05 18:09:19.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/net/iucv.h	2003-07-05 18:10:28.000000000 -0700
@@ -62,6 +62,9 @@
 #define Priority_MessagePendingInterruptsFlag            0x40
 #define Nonpriority_MessageCompletionInterruptsFlag      0x20
 #define Priority_MessageCompletionInterruptsFlag         0x10
+#define IUCVControlInterruptsFlag                        0x08
+#define AllInterrupts					 0xf8
+
 /*
  * Mapping of external interrupt buffers should be used with the corresponding
  * interrupt types.                  
@@ -735,6 +738,7 @@
  *           0x40 - Priority_MessagePendingInterruptsFlag            
  *           0x20 - Nonpriority_MessageCompletionInterruptsFlag      
  *           0x10 - Priority_MessageCompletionInterruptsFlag         
+ *           0x08 - IUCVControlInterruptsFlag         
  * Output: NA                                                        
  * Return: Return code from CP IUCV call.                         
 */
diff -urN linux-2.4.22-pre2/drivers/s390/net/netiucv.c linux-2.4.22-pre3/drivers/s390/net/netiucv.c
--- linux-2.4.22-pre2/drivers/s390/net/netiucv.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/s390/net/netiucv.c	2003-07-05 18:10:28.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * $Id: netiucv.c,v 1.17 2002/02/12 21:52:20 felfert Exp $
+ * $Id: netiucv.c,v 1.23 2003/06/24 16:05:32 felfert Exp $
  *
  * IUCV network driver
  *
@@ -28,7 +28,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV network driver $Revision: 1.17 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.23 $
  *
  */
 
@@ -96,6 +96,8 @@
 	unsigned long txlen;
 	unsigned long tx_time;
 	struct timeval send_stamp;
+	unsigned long tx_pending;
+	unsigned long tx_max_pending;
 } connection_profile;
 
 /**
@@ -108,6 +110,7 @@
 	struct sk_buff           *rx_buff;
 	struct sk_buff           *tx_buff;
 	struct sk_buff_head      collect_queue;
+	struct sk_buff_head      commit_queue;
 	spinlock_t               collect_lock;
 	int                      collect_len;
 	int                      max_buffsize;
@@ -443,6 +446,10 @@
 	iucv_connection *conn = (iucv_connection *)pgm_data;
 	iucv_event ev;
 
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+
 	ev.conn = conn;
 	ev.data = (void *)eib;
 	fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, &ev);
@@ -619,10 +626,11 @@
 	iucv_MessageComplete *eib = (iucv_MessageComplete *)ev->data;
 	netiucv_priv *privptr = NULL;
 			         /* Shut up, gcc! skb is always below 2G. */
-	struct sk_buff *skb = (struct sk_buff *)(unsigned long)eib->ipmsgtag;
+	__u32 single_flag = eib->ipmsgtag;
 	__u32 txbytes = 0;
 	__u32 txpackets = 0;
 	__u32 stat_maxcq = 0;
+	struct sk_buff *skb;
 	unsigned long saveflags;
 	ll_header header;
 
@@ -632,13 +640,17 @@
 	fsm_deltimer(&conn->timer);
 	if (conn && conn->netdev && conn->netdev->priv)
 		privptr = (netiucv_priv *)conn->netdev->priv;
-	if (skb) {
+	conn->prof.tx_pending--;
+	if (single_flag) {
+		if ((skb = skb_dequeue(&conn->commit_queue))) {
+			atomic_dec(&skb->users);
+			dev_kfree_skb_any(skb);
+		}
 		if (privptr) {
 			privptr->stats.tx_packets++;
 			privptr->stats.tx_bytes +=
 				(skb->len - NETIUCV_HDRLEN - NETIUCV_HDRLEN);
 		}
-		dev_kfree_skb_any(skb);
 	}
 	conn->tx_buff->data = conn->tx_buff->tail = conn->tx_buff->head;
 	conn->tx_buff->len = 0;
@@ -672,11 +684,17 @@
 			       conn->tx_buff->data, conn->tx_buff->len);
 		conn->prof.doios_multi++;
 		conn->prof.txlen += conn->tx_buff->len;
+		conn->prof.tx_pending++;
+		if (conn->prof.tx_pending > conn->prof.tx_max_pending)
+			conn->prof.tx_max_pending = conn->prof.tx_pending;
 		if (rc != 0) {
 			fsm_deltimer(&conn->timer);
+			conn->prof.tx_pending--;
 			fsm_newstate(fi, CONN_STATE_IDLE);
 			if (privptr)
 				privptr->stats.tx_errors += txpackets;
+			printk(KERN_DEBUG "iucv_send returned %08x\n",
+			       rc);
 		} else {
 			if (privptr) {
 				privptr->stats.tx_packets += txpackets;
@@ -764,6 +782,13 @@
 	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
 #endif
 	switch (state) {
+		case CONN_STATE_SETUPWAIT:
+			printk(KERN_INFO "%s: Remote dropped connection\n",
+			       netdev->name);
+			conn->handle = 0;
+			fsm_newstate(fi, CONN_STATE_STOPPED);
+			fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
+			break;
 		case CONN_STATE_IDLE:
 		case CONN_STATE_TX:
 			printk(KERN_INFO "%s: Remote dropped connection\n",
@@ -807,10 +832,15 @@
 	printk(KERN_DEBUG "%s('%s'): connecting ...\n",
 	       conn->netdev->name, conn->userid);
 #endif
+
+	/* We must set the state before calling iucv_connect because the callback
+	 * handler could be called at any point after the connection request is
+	 * sent. */
+
+	fsm_newstate(fi, CONN_STATE_SETUPWAIT);
 	rc = iucv_connect(&(conn->pathid), NETIUCV_QUEUELEN_DEFAULT, iucvMagic,
 			  conn->userid, iucv_host, 0, NULL, NULL, conn->handle,
 			  conn);
-	fsm_newstate(fi, CONN_STATE_SETUPWAIT);
 	switch (rc) {
 		case 0:
 			return;
@@ -885,6 +915,7 @@
 	if (conn->handle)
 		iucv_unregister_program(conn->handle);
 	conn->handle = 0;
+	netiucv_purge_skb_queue(&conn->commit_queue);
 	fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
 }
 
@@ -928,6 +959,7 @@
 	{ CONN_STATE_TX,        CONN_EVENT_RX,       conn_action_rx         },
 
 	{ CONN_STATE_TX,        CONN_EVENT_TXDONE,   conn_action_txdone     },
+	{ CONN_STATE_IDLE,      CONN_EVENT_TXDONE,   conn_action_txdone     },
 };
 
 static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node);
@@ -1130,14 +1162,21 @@
 			     CONN_EVENT_TIMER, conn);
 		conn->prof.send_stamp = xtime;
 		
-		rc = iucv_send(conn->pathid, NULL, 0, 0,
-			       /* Shut up, gcc! nskb is always below 2G. */
-			       (__u32)(((unsigned long)nskb)&0xffffffff), 0,
-			       nskb->data, nskb->len);
+		rc = iucv_send(conn->pathid, NULL, 0, 0, 1 /* single_flag */,
+			       0, nskb->data, nskb->len);
 		conn->prof.doios_single++;
 		conn->prof.txlen += skb->len;
+		conn->prof.tx_pending++;
+		if (conn->prof.tx_pending > conn->prof.tx_max_pending)
+			conn->prof.tx_max_pending = conn->prof.tx_pending;
 		if (rc != 0) {
+			netiucv_priv *privptr;
 			fsm_deltimer(&conn->timer);
+			fsm_newstate(conn->fsm, CONN_STATE_IDLE);
+			conn->prof.tx_pending--;
+			privptr = (netiucv_priv *)conn->netdev->priv;
+			if (privptr)
+				privptr->stats.tx_errors++;
 			if (copied)
 				dev_kfree_skb(nskb);
 			else {
@@ -1148,9 +1187,13 @@
 				skb_pull(skb, NETIUCV_HDRLEN);
 				skb_trim(skb, skb->len - NETIUCV_HDRLEN);
 			}
+			printk(KERN_DEBUG "iucv_send returned %08x\n",
+			       rc);
 		} else {
 			if (copied)
 				dev_kfree_skb(skb);
+			atomic_inc(&nskb->users);
+			skb_queue_tail(&conn->commit_queue, nskb);
 		}
 	}
 
@@ -1549,12 +1592,7 @@
 	if (!(dev = find_netdev_by_ino(ino)))
 		return -ENODEV;
 	privptr = (netiucv_priv *)dev->priv;
-	privptr->conn->prof.maxmulti = 0;
-	privptr->conn->prof.maxcqueue = 0;
-	privptr->conn->prof.doios_single = 0;
-	privptr->conn->prof.doios_multi = 0;
-	privptr->conn->prof.txlen = 0;
-	privptr->conn->prof.tx_time = 0;
+	memset(&(privptr->conn->prof), 0, sizeof(privptr->conn->prof));
 	return count;
 }
 
@@ -1593,6 +1631,10 @@
 			     privptr->conn->prof.txlen);
 		p += sprintf(p, "Max. TX IO-time: %ld\n",
 			     privptr->conn->prof.tx_time);
+		p += sprintf(p, "Pending transmits: %ld\n",
+			     privptr->conn->prof.tx_pending);
+		p += sprintf(p, "Max. pending transmits: %ld\n",
+			     privptr->conn->prof.tx_max_pending);
 	}
 	l = strlen(sbuf);
 	p = sbuf;
@@ -1725,8 +1767,10 @@
 	 * If not registered, register main proc dir-entry now
 	 */
 #if LINUX_VERSION_CODE > 0x020362
+#ifdef CONFIG_PROC_FS
 	if (!netiucv_dir)
 		netiucv_dir = proc_mkdir("iucv", proc_net);
+#endif
 #else
 	if (netiucv_dir.low_ino == 0)
 		proc_net_register(&netiucv_dir);
@@ -1741,7 +1785,9 @@
 netiucv_proc_destroy_main(void)
 {
 #if LINUX_VERSION_CODE > 0x020362
+#ifdef CONFIG_PROC_FS
 	remove_proc_entry("iucv", proc_net);
+#endif
 #else
 	proc_net_unregister(netiucv_dir.low_ino);
 #endif
@@ -1833,6 +1879,7 @@
 	if (conn) {
 		memset(conn, 0, sizeof(iucv_connection));
 		skb_queue_head_init(&conn->collect_queue);
+		skb_queue_head_init(&conn->commit_queue);
 		conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT;
 		conn->netdev = dev;
 
@@ -2005,7 +2052,7 @@
 static void
 netiucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.17 $";
+	char vbuf[] = "$Revision: 1.23 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
@@ -2066,7 +2113,7 @@
 
 	netiucv_proc_create_main();
 	while (p) {
-		if (isalnum(*p)) {
+		if (isalnum(*p) || (*p == '$')) {
 			username[i++] = *p++;
 			username[i] = '\0';
 			if (i > 8) {
diff -urN linux-2.4.22-pre2/drivers/s390/s390io.c linux-2.4.22-pre3/drivers/s390/s390io.c
--- linux-2.4.22-pre2/drivers/s390/s390io.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/s390/s390io.c	2003-07-05 18:10:30.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/s390io.c
  *   S/390 common I/O routines
- *   $Revision: 1.171.2.21 $
+ *   $Revision: 1.247 $
  *
  *  S390 version
  *    Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH,
@@ -59,6 +59,7 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/ctype.h>
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
 #endif
@@ -116,6 +117,11 @@
                                     ##args); \
         } while (0)
 
+#define CIO_HEX_EVENT(imp, args...) do { \
+	if (cio_debug_initialized) \
+                debug_event(cio_debug_trace_id, imp, ##args); \
+        } while (0)
+
 #undef  CONFIG_DEBUG_IO
 #define CONFIG_DEBUG_CRW
 #define CONFIG_DEBUG_CHSC
@@ -175,14 +181,13 @@
 int s390_start_IO (int irq, ccw1_t * cpa, unsigned long user_intparm,
 		   __u8 lpm, unsigned long flag);
 
-static int s390_send_nop(int irq, __u8 lpm);
-
 #ifdef CONFIG_PROC_FS
 static int chan_proc_init (void);
 #endif
 
 static inline void do_adapter_IO (__u32 intparm);
 
+static void s390_schedule_path_verification(unsigned long irq);
 int s390_DevicePathVerification (int irq, __u8 domask);
 int s390_register_adapter_interrupt (adapter_int_handler_t handler);
 int s390_unregister_adapter_interrupt (adapter_int_handler_t handler);
@@ -251,20 +256,17 @@
 
 	if ((to && (from > to))
 	    || (to<0) || (to > 0xffff)
-	    || (from<0) || (from > 0xffff)) {
-		printk (KERN_WARNING
-			"Invalid blacklist range %x to %x, skipping\n", from,
-			to);
+	    || (from<0) || (from > 0xffff))
 		return;
-	}
+
 	if (!locked)
 		spin_lock_irqsave (&blacklist_lock, flags);
 
 	if (!to)
 		to = from;
 	for (i = from; i <= to; i++) {
-		set_bit (i, &bl_dev);
-		nr_ignored++;
+		if (!test_and_set_bit (i, &bl_dev))
+			nr_ignored++;
 	}
 
 	if (to >= highest_ignored)
@@ -285,20 +287,16 @@
 	long flags;
 	int i;
 
-	if ((to<0) || (to > 0xffff)
-	    || (from<0) || (from > 0xffff)) {
-		printk (KERN_WARNING
-			"Invalid blacklist range %x to %x, "
-			"not freeing\n",
-			from, to);
+	if ((to && (from > to))
+	    || (to<0) || (to > 0xffff)
+	    || (from<0) || (from > 0xffff))
 		return;
-	}
 
 	spin_lock_irqsave (&blacklist_lock, flags);
 
 	for (i = from; i <= to; i++) {
-		clear_bit (i, &bl_dev);
-		nr_ignored--;
+		if (test_and_clear_bit (i, &bl_dev))
+			nr_ignored--;
 	}
 
 	if (to == highest_ignored)
@@ -364,16 +362,12 @@
 static inline int
 blacklist_strtoul (char *str, char **stra)
 {
-	char *temp = str;
-	int val;
-	if (*temp == '0') {
-		temp++;		/* strip leading zero */
-		if (*temp == 'x')
-			temp++;	/* strip leading x */
-	}
-	val = simple_strtoul (temp, &temp, 16);	/* interpret anything as hex */
-	*stra = temp;
-	return val;
+	if (*str == '0') {
+		str++;		/* strip leading zero */
+		if (*str == 'x')
+			str++;	/* strip leading x */
+	}
+	return simple_strtoul (str, stra, 16);	/* interpret anything as hex */
 }
 
 /*
@@ -507,85 +501,62 @@
 void
 blacklist_parse_proc_parameters (char *buf)
 {
-	char *tmp;
 	int i;
-	char *end;
-	int len = -1;
-	char *param;
 	int from = 0;
 	int to = 0;
 	long flags;
 	int err = 0;
 
-	tmp = buf;
-	if (strstr (tmp, "free ")) {
+	if (strstr (buf, "free ")) {
 		for (i = 0; i < 5; i++) {
-			tmp++;
+			buf++;
 		}
-		if (strstr (tmp, "all")) {
+		if (strstr (buf, "all")) {
 			blacklist_free_all_ranges ();
 			s390_redo_validation ();
 		} else {
-			while (tmp != NULL) {
-				end = strchr (tmp, ',');
-				if (end == NULL) {
-					len = strlen (tmp) + 1;
-				} else {
-					len = (long) end - (long) tmp + 1;
-					*end = '\0';
-					end++;
-				}
-				param =
-				    (char *) kmalloc (len * sizeof (char) + 1,
-						      GFP_KERNEL);
-				strncpy (param, (const char *) tmp, len);
-				tmp = end;
-				from = blacklist_strtoul (param, &param);
-				if (*param == '-') {
-					param++;
-					to = blacklist_strtoul (param, &param);
-				} else {
-					to = from;
+			while (*buf != 0 && *buf != '\n') {
+				if (!isxdigit(*buf)) {
+					printk(KERN_WARNING "%s: error parsing "
+					       "\"%s\"\n", __FUNCTION__, buf);
+					return;
 				}
+				
+				from = blacklist_strtoul (buf, &buf);
+				to = (*buf == '-') ?
+					blacklist_strtoul (buf+1, &buf) : from;
+				
 				blacklist_range_remove (from, to);
-				kfree (param);
+			
+				if (*buf == ',')
+					buf++;
 			}
-			s390_redo_validation ();
+			s390_redo_validation();
 		}
-	} else if (strstr (tmp, "add ")) {
+	} else if (strstr (buf, "add ")) {
 		for (i = 0; i < 4; i++) {
-			tmp++;
+			buf++;
 		}
-		while (tmp != NULL) {
-			end = strchr (tmp, ',');
-			if (end == NULL) {
-				len = strlen (tmp) + 1;
-			} else {
-				len = (long) end - (long) tmp + 1;
-				*end = '\0';
-				end++;
-			}
-			param =
-			    (char *) kmalloc (len * sizeof (char) + 1,
-					      GFP_KERNEL);
-			strncpy (param, (const char *) tmp, len);
-			tmp = end;
-			from = blacklist_strtoul (param, &param);
-			if (*param == '-') {
-				param++;
-				to = blacklist_strtoul (param, &param);
-			} else {
-				to = from;
+		while (*buf != 0 && *buf != '\n') {
+			if (!isxdigit(*buf)) {
+				printk(KERN_WARNING "%s: error parsing "
+				       "\"%s\"\n", __FUNCTION__, buf);
+				return;
 			}
+			
+			from = blacklist_strtoul (buf, &buf);
+			to = (*buf == '-') ?
+				blacklist_strtoul (buf+1, &buf) : from;
+			
 			spin_lock_irqsave (&blacklist_lock, flags);
-
+			
 			/*
 			 * Don't allow for already known devices to be
 			 * blacklisted
 			 * The criterion is a bit dumb, devices which once were
 			 * there but are already gone are also caught...
 			 */
-
+			
 			err = 0;
 			for (i = 0; i <= highest_subchannel; i++) {
 				if (ioinfo[i] != INVALID_STORAGE_AREA) {
@@ -603,12 +574,13 @@
 						}
 				}
 			}
-
+			
 			if (!err)
 				blacklist_range_add (from, to, 1);
-
+			
 			spin_unlock_irqrestore (&blacklist_lock, flags);
-			kfree (param);
+			if (*buf == ',')
+				buf++;
 		}
 
 	} else {
@@ -623,7 +595,6 @@
 /* End of blacklist handling */
 
 void s390_displayhex (char *str, void *ptr, s32 cnt);
-void s390_displayhex2 (char *str, void *ptr, s32 cnt, int level);
 
 void
 s390_displayhex (char *str, void *ptr, s32 cnt)
@@ -644,26 +615,6 @@
 	}
 }
 
-void
-s390_displayhex2 (char *str, void *ptr, s32 cnt, int level)
-{
-	s32 cnt1, cnt2, maxcnt2;
-	u32 *currptr = (__u32 *) ptr;
-	char buffer[cnt * 12];
-
-	debug_text_event (cio_debug_msg_id, level, str);
-
-	for (cnt1 = 0; cnt1 < cnt; cnt1 += 16) {
-		sprintf (buffer, "%08lX ", (unsigned long) currptr);
-		maxcnt2 = cnt - cnt1;
-		if (maxcnt2 > 16)
-			maxcnt2 = 16;
-		for (cnt2 = 0; cnt2 < maxcnt2; cnt2 += 4)
-			sprintf (buffer, "%08X ", *currptr++);
-	}
-	debug_text_event (cio_debug_msg_id, level, buffer);
-}
-
 static int __init
 cio_setup (char *parm)
 {
@@ -815,93 +766,6 @@
 	return;
 }
 
-
-/*
- * Function: s390_send_nop
- * 
- * sends a nop CCW to the specified subchannel down the given path(s)
- */
-static int
-s390_send_nop(int irq, __u8 lpm)
-{
-	char dbf_txt[15];
-	ccw1_t *nop_ccw;
-	devstat_t devstat;
-	devstat_t *pdevstat = &devstat;
-	unsigned long flags;
-
-	int irq_ret = 0;
-	int inlreq = 0;
-
-	SANITY_CHECK(irq);
-
-	if (!ioinfo[irq]->ui.flags.oper)
-		/* no sense in trying */
-		return -ENODEV;
-
-	sprintf(dbf_txt, "snop%x", irq);
-	CIO_TRACE_EVENT(5, dbf_txt);
-
-	if (!ioinfo[irq]->ui.flags.ready) {
-		/*
-		 * If there's no handler, use our dummy handler.
-		 */
-		irq_ret = request_irq (irq,
-				       init_IRQ_handler,
-				       SA_PROBE,
-				       "SNOP",
-				       pdevstat);
-		if (!irq_ret)
-			inlreq = 1;
-	} else {
-		pdevstat = ioinfo[irq]->irq_desc.dev_id;
-	}
-	
-	if (irq_ret)
-		return irq_ret;
-
-	s390irq_spin_lock_irqsave (irq, flags);
-
-	if (init_IRQ_complete)
-		nop_ccw = kmalloc (sizeof (ccw1_t), GFP_DMA);
-	else
-		nop_ccw = alloc_bootmem_low (sizeof (ccw1_t));
-
-	nop_ccw->cmd_code = CCW_CMD_NOOP;
-	nop_ccw->cda = 0;
-	nop_ccw->count = 0;
-	nop_ccw->flags = CCW_FLAG_SLI;
-
-	memset (pdevstat, '\0', sizeof (devstat_t));
-	
-	irq_ret = s390_start_IO (irq, nop_ccw, 0xE2D5D6D7, lpm,
-				 DOIO_WAIT_FOR_INTERRUPT
-				 | DOIO_TIMEOUT
-				 | DOIO_DONT_CALL_INTHDLR
-				 | DOIO_VALID_LPM);
-	
-	if (irq_ret == -ETIMEDOUT) {
-
-		/* better cancel... */
-		cancel_IO(irq);
-	}
-
-	if (init_IRQ_complete) 
-		kfree (nop_ccw);
-	else
-		free_bootmem ((unsigned long) nop_ccw, sizeof (ccw1_t));
-
-	s390irq_spin_unlock_irqrestore (irq, flags);
-
-	if (inlreq)
-		free_irq (irq, pdevstat);
-
-	return irq_ret;
-
-}
-
-
-
 /*
  * Note : internal use of irqflags SA_PROBE for NOT path grouping 
  *
@@ -930,7 +794,7 @@
 	if (ioinfo[irq]->st)
 		return -ENODEV;
 
-	sprintf (dbf_txt, "reqs%x", irq);
+	sprintf (dbf_txt, "reqsp%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/*
@@ -1054,6 +918,7 @@
 				s390irq_spin_unlock_irqrestore (irq, flags);
 				udelay (200000);	/* 200 ms */
 				s390irq_spin_lock_irqsave (irq, flags);
+
 				ret = disable_subchannel (irq);
 
 				if (ret == -EBUSY) {
@@ -1130,7 +995,7 @@
 	if (!ioinfo[irq]->ui.flags.ready)
 		return -ENODEV;
 
-	sprintf (dbf_txt, "dirq%x", irq);
+	sprintf (dbf_txt, "disirq%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	s390irq_spin_lock_irqsave (irq, flags);
@@ -1157,7 +1022,7 @@
 	if (!ioinfo[irq]->ui.flags.ready)
 		return -ENODEV;
 
-	sprintf (dbf_txt, "eirq%x", irq);
+	sprintf (dbf_txt, "enirq%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	s390irq_spin_lock_irqsave (irq, flags);
@@ -1183,7 +1048,7 @@
 
 	SANITY_CHECK (irq);
 
-	sprintf (dbf_txt, "esch%x", irq);
+	sprintf (dbf_txt, "ensch%x", irq);
 	CIO_TRACE_EVENT (2, dbf_txt);
 
 	/*
@@ -1268,7 +1133,7 @@
 
 	SANITY_CHECK (irq);
 
-	sprintf (dbf_txt, "dsch%x", irq);
+	sprintf (dbf_txt, "dissch%x", irq);
 	CIO_TRACE_EVENT (2, dbf_txt);
 
 	if (ioinfo[irq]->ui.flags.busy) {
@@ -1367,6 +1232,7 @@
 {
 	unsigned long flags;	/* PSW flags */
 	long cr6 __attribute__ ((aligned (8)));
+	cpuid_t cpuid;
 
 	asm volatile ("STCK %0":"=m" (irq_IPL_TOD));
 
@@ -1406,8 +1272,18 @@
 	
 	global_pgid = (pgid_t *)alloc_bootmem(sizeof(pgid_t));
 
-	global_pgid->cpu_addr = *(__u16 *) __LC_CPUADDR;
-	global_pgid->cpu_id = ((cpuid_t *) __LC_CPUID)->ident;
+	cpuid = *(cpuid_t*) __LC_CPUID;
+	
+	if (MACHINE_NEW_STIDP)
+		global_pgid->cpu_addr = 0x8000;
+	else {
+#ifdef CONFIG_SMP
+		global_pgid->cpu_addr = hard_smp_processor_id();
+#else
+		global_pgid->cpu_addr = 0;
+#endif
+	}
+	global_pgid->cpu_id = cpuid.ident;
 	global_pgid->cpu_model = ((cpuid_t *) __LC_CPUID)->machine;
 	global_pgid->tod_high = *(__u32 *) & irq_IPL_TOD;
 
@@ -1445,7 +1321,6 @@
 {				/* flags */
 	int ccode;
 	int ret = 0;
-	char buffer[80];
 	char dbf_txt[15];
 
 	SANITY_CHECK (irq);
@@ -1512,7 +1387,14 @@
 	/*
 	 * Issue "Start subchannel" and process condition code
 	 */
-	ccode = ssch (irq, &(ioinfo[irq]->orb));
+	if (flag & DOIO_USE_DIAG98) {
+		ioinfo[irq]->orb.key = get_storage_key() >> 4;
+		ioinfo[irq]->orb.cpa =
+			(__u32) pfix_get_addr((void *)ioinfo[irq]->orb.cpa);
+		ccode = diag98 (irq, &(ioinfo[irq]->orb));
+	} else {
+		ccode = ssch (irq, &(ioinfo[irq]->orb));
+	}
 
 	sprintf (dbf_txt, "ccode:%d", ccode);
 	CIO_TRACE_EVENT (4, dbf_txt);
@@ -1674,6 +1556,16 @@
 		break;
 
 	case 1:		/* status pending */
+		
+		/* 
+		 * Don't do an inline processing of pending interrupt conditions
+		 * while doing async. I/O. The interrupt will pop up when we are
+		 * enabled again and the I/O can be retried.
+		 */
+		if (!ioinfo[irq]->ui.flags.syncio) {
+			ret = -EBUSY;
+			break;
+		}
 
 		ioinfo[irq]->devstat.flag = DEVSTAT_START_FUNCTION
 		    | DEVSTAT_STATUS_PENDING;
@@ -1715,14 +1607,6 @@
 		 *  than the one used (i.e. path available mask is non-zero).
 		 */
 		if (ioinfo[irq]->devstat.ii.irb.scsw.cc == 3) {
-			if (flag & DOIO_VALID_LPM) {
-				ioinfo[irq]->opm &=
-				    ~(ioinfo[irq]->devstat.ii.irb.esw.esw1.
-				      lpum);
-			} else {
-				ioinfo[irq]->opm = 0;
-
-			}
 
 			if (ioinfo[irq]->opm == 0) {
 				ret = -ENODEV;
@@ -1736,6 +1620,7 @@
 
 #ifdef CONFIG_DEBUG_IO
 			{
+				char buffer[80];
 
 				stsch (irq, &(ioinfo[irq]->schib));
 
@@ -1777,39 +1662,23 @@
 #endif
 			if (cio_debug_initialized) {
 				stsch (irq, &(ioinfo[irq]->schib));
-
-				sprintf (buffer,
-					 "s390_start_IO(%04X) - irb for "
-					 "device %04X, after status pending\n",
-					 irq, ioinfo[irq]->devstat.devno);
-
-				s390_displayhex2 (buffer,
-						  &(ioinfo[irq]->devstat.ii.
-						    irb), sizeof (irb_t), 2);
-
-				sprintf (buffer,
-					 "s390_start_IO(%04X) - schib for "
-					 "device %04X, after status pending\n",
-					 irq, ioinfo[irq]->devstat.devno);
-
-				s390_displayhex2 (buffer,
-						  &(ioinfo[irq]->schib),
-						  sizeof (schib_t), 2);
+				
+				sprintf(dbf_txt, "sp%x", irq);
+				CIO_TRACE_EVENT(2, dbf_txt);
+				CIO_TRACE_EVENT(2, "irb:");
+				CIO_HEX_EVENT(2, &(ioinfo[irq]->devstat.ii.irb),
+					      sizeof (irb_t));
+				CIO_TRACE_EVENT(2, "schib:");
+				CIO_HEX_EVENT(2, &(ioinfo[irq]->schib),
+					      sizeof (schib_t));
 
 				if (ioinfo[irq]->devstat.
 				    flag & DEVSTAT_FLAG_SENSE_AVAIL) {
-					sprintf (buffer,
-						 "s390_start_IO(%04X) "
-						 "- sense data for device %04X,"
-						 " after status pending\n",
-						 irq,
-						 ioinfo[irq]->devstat.devno);
-
-					s390_displayhex2 (buffer,
-							  ioinfo[irq]->irq_desc.
-							  dev_id->ii.sense.data,
-							  ioinfo[irq]->irq_desc.
-							  dev_id->rescnt, 2);
+					CIO_TRACE_EVENT(2, "sense:");
+					CIO_HEX_EVENT(2, ioinfo[irq]->irq_desc.
+						      dev_id->ii.sense.data,
+						      ioinfo[irq]->irq_desc.
+						      dev_id->rescnt);
 
 				}
 			}
@@ -1860,14 +1729,10 @@
 #endif
 		if (cio_debug_initialized) {
 			stsch (irq, &(ioinfo[irq]->schib));
-
-			sprintf (buffer, "s390_start_IO(%04X) - schib for "
-				 "device %04X, after 'not oper' status\n",
-				 irq, ioinfo[irq]->devstat.devno);
-
-			s390_displayhex2 (buffer,
-					  &(ioinfo[irq]->schib),
-					  sizeof (schib_t), 2);
+			sprintf(dbf_txt, "no%x", irq);
+			CIO_TRACE_EVENT(2, dbf_txt);
+			CIO_HEX_EVENT(2, &(ioinfo[irq]->schib),
+				      sizeof (schib_t));
 		}
 
 		break;
@@ -1908,6 +1773,9 @@
 	sprintf (dbf_txt, "doIO%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
+	if (ioinfo[irq]->ui.flags.noio)
+		return -EBUSY;
+
 	/*
 	 * Note: We ignore the device operational status - if not operational,
 	 *        the SSCH will lead to an -ENODEV condition ...
@@ -1963,7 +1831,7 @@
 
 	SANITY_CHECK (irq);
 
-	sprintf (dbf_txt, "rsIO%x", irq);
+	sprintf (dbf_txt, "resIO%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/*
@@ -1982,7 +1850,6 @@
 			break;
 
 		case 1:
-			s390_process_IRQ (irq);
 			ret = -EBUSY;
 			break;
 
@@ -2025,6 +1892,9 @@
 
 	SANITY_CHECK (irq);
 
+	if (ioinfo[irq]->ui.flags.noio)
+		return -EBUSY;
+
 	/*
 	 * we only allow for halt_IO if the device has an I/O handler associated
 	 */
@@ -2038,8 +1908,7 @@
 	if (ioinfo[irq]->ui.flags.w4sense) {
 		return 0;
 	}
-	CIO_TRACE_EVENT (2, "haltIO");
-	sprintf (dbf_txt, "%x", irq);
+	sprintf (dbf_txt, "haltIO%x", irq);
 	CIO_TRACE_EVENT (2, dbf_txt);
 
 	/*
@@ -2158,6 +2027,16 @@
 
 	case 1:		/* status pending */
 
+		/* 
+		 * Don't do an inline processing of pending interrupt conditions
+		 * while doing async. I/O. The interrupt will pop up when we are
+		 * enabled again and the I/O can be retried.
+		 */
+		if (!ioinfo[irq]->ui.flags.syncio) {
+			ret = -EBUSY;
+			break;
+		}
+		
 		ioinfo[irq]->devstat.flag |= DEVSTAT_STATUS_PENDING;
 
 		/*
@@ -2248,6 +2127,8 @@
 	if (ioinfo[irq] == INVALID_STORAGE_AREA)
 		return (-ENODEV);
 
+	if (ioinfo[irq]->ui.flags.noio)
+		return -EBUSY;
 	/*
 	 * we only allow for clear_IO if the device has an I/O handler associated
 	 */
@@ -2260,8 +2141,7 @@
 	if (ioinfo[irq]->ui.flags.w4sense)
 		return 0;
 
-	CIO_TRACE_EVENT (2, "clearIO");
-	sprintf (dbf_txt, "%x", irq);
+	sprintf (dbf_txt, "clearIO%x", irq);
 	CIO_TRACE_EVENT (2, dbf_txt);
 
 	/*
@@ -2418,8 +2298,7 @@
 
 	SANITY_CHECK (irq);
 
-	CIO_TRACE_EVENT (2, "cancelIO");
-	sprintf (dbf_txt, "%x", irq);
+	sprintf (dbf_txt, "cancelIO%x", irq);
 	CIO_TRACE_EVENT (2, dbf_txt);
 
 	ccode = xsch (irq);
@@ -2435,8 +2314,6 @@
 
 	case 1:		/* status pending */
 
-		/* process the pending irq... */
-		s390_process_IRQ (irq);
 		ret = -EBUSY;
 		break;
 
@@ -2595,7 +2472,7 @@
 
 	dp = &ioinfo[irq]->devstat;
 	udp = ioinfo[irq]->irq_desc.dev_id;
-
+	
 	/*
 	 * It might be possible that a device was not-oper. at the time
 	 *  of free_irq() processing. This means the handler is no longer
@@ -2719,7 +2596,7 @@
 		}
 
 		dp->cpa = dp->ii.irb.scsw.cpa;
-
+		
 	}
 	irb_cc = dp->ii.irb.scsw.cc;
 
@@ -2806,18 +2683,9 @@
 				 irq, dp->devno);
 
 			s390_displayhex (buffer, &(dp->ii.irb), sizeof (irb_t));
-			if (cio_debug_initialized) {
-
-				sprintf (buffer,
-					 "s390_process_IRQ(%04X) - irb for "
-					 "device %04X after channel check "
-					 "or interface control check\n",
-					 irq, dp->devno);
-
-				s390_displayhex2 (buffer,
-						  &(dp->ii.irb),
-						  sizeof (irb_t), 0);
-			}
+			sprintf(dbf_txt, "chk%x", irq);
+			CIO_TRACE_EVENT(0, dbf_txt);
+			CIO_HEX_EVENT(0, &(dp->ii.irb), sizeof (irb_t));
 		}
 
 		ioinfo[irq]->stctl |= stctl;
@@ -2840,6 +2708,7 @@
 		 */
 		if (!(stctl & SCSW_STCTL_ALERT_STATUS)
 		    && (ioinfo[irq]->ui.flags.busy == 0)) {
+
 #ifdef CONFIG_DEBUG_IO
 			if (irq != cons_dev)
 				printk (KERN_INFO
@@ -2863,16 +2732,9 @@
 				      "subchannel status : %02X\n",
 				      dp->devno,
 				      irq, dp->dstat, dp->cstat);
-			if (cio_debug_initialized) {
-				sprintf (buffer,
-					 "s390_process_IRQ(%04X) - irb for "
-					 "device %04X, ending_status %d\n", irq,
-					 dp->devno, ending_status);
-				
-				s390_displayhex2 (buffer,
-						  &(dp->ii.irb),
-						  sizeof (irb_t), 2);
-			}
+			sprintf(dbf_txt, "uint%x", irq);
+			CIO_TRACE_EVENT(2, dbf_txt);
+			CIO_HEX_EVENT(2, &(dp->ii.irb), sizeof (irb_t));
 		}
 
 		/*
@@ -2899,13 +2761,25 @@
 			unsigned long s_flag = 0;
 
 			if (ending_status) {
+				/* there is a chance that the command
+				 * that gave us the unit check actually
+				 * was a basic sense, so we must not
+				 * overwrite *udp in that case
+				 */
+				if (ioinfo[irq]->ui.flags.w4sense &&
+					(dp->ii.irb.scsw.dstat & DEV_STAT_UNIT_CHECK)) {
+					CIO_MSG_EVENT(4,"double unit check irq %04x, dstat %02x," 
+							"flags %8x\n", irq, dp->ii.irb.scsw.dstat,
+							 ioinfo[irq]->ui.info, ending_status);
+				} else {
 				/*
 				 * We copy the current status information into the device driver
 				 *  status area. Then we can use the local devstat area for device
 				 *  sensing. When finally calling the IRQ handler we must not overlay
 				 *  the original device status but copy the sense data only.
 				 */
-				memcpy (udp, dp, sizeof (devstat_t));
+					memcpy (udp, dp, sizeof (devstat_t));
+				}
 
 				s_ccw->cmd_code = CCW_CMD_BASIC_SENSE;
 				s_ccw->cda =
@@ -2919,10 +2793,13 @@
 				 *  process we have to sense synchronously
 				 */
 				if (ioinfo[irq]->ui.flags.unready
-				    || ioinfo[irq]->ui.flags.syncio) {
-					s_flag = DOIO_WAIT_FOR_INTERRUPT;
+				    || ioinfo[irq]->ui.flags.syncio)
+					s_flag = DOIO_WAIT_FOR_INTERRUPT
+						|  DOIO_TIMEOUT
+						|  DOIO_VALID_LPM;
 
-				}
+				else
+					s_flag = DOIO_VALID_LPM;
 
 				/*
 				 * Reset status info
@@ -2950,8 +2827,34 @@
 				ioinfo[irq]->ui.flags.w4sense = 1;
 
 				ret_io = s390_start_IO (irq, s_ccw, 0xE2C5D5E2,	/* = SENSe */
-							0,	/* n/a */
+							0xff,
 							s_flag);
+				switch (ret_io) {
+				case 0: /* OK */
+					break;
+				case -ENODEV:
+					/*
+					 * The device is no longer operational.
+					 * We won't get any sense data.
+					 */
+					ioinfo[irq]->ui.flags.w4sense = 0;
+					ioinfo[irq]->ui.flags.oper = 0;
+					allow4handler = 1; /* to notify the driver */
+					break;
+				case -EBUSY:
+					/*
+					 * The channel subsystem is either busy, or we have
+					 * a status pending. Retry later.
+					 */
+					ioinfo[irq]->ui.flags.w4sense = 0;
+					ioinfo[irq]->ui.flags.delsense = 1;
+					break;
+				default:
+					printk(KERN_ERR"irq %04X: Unexpected rc %d "
+					       "for BASIC SENSE!\n", irq, ret_io);
+					ioinfo[irq]->ui.flags.w4sense = 0;
+					allow4handler = 1;
+				}
 			} else {
 				/*
 				 * we received an Unit Check but we have no final
@@ -3024,10 +2927,12 @@
 				udp->flag |= DEVSTAT_FLAG_SENSE_AVAIL;
 				udp->scnt = sense_count;
 
-				if (sense_count >= 0) {
+				if (sense_count > 0) {
 					memcpy (udp->ii.sense.data,
 						ioinfo[irq]->sense_data,
 						sense_count);
+				} else if (sense_count == 0) {
+					udp->flag &= ~DEVSTAT_FLAG_SENSE_AVAIL;
 				} else {
 					panic
 					    ("s390_process_IRQ(%04x) encountered "
@@ -3090,7 +2995,8 @@
 				dp->flag |= DEVSTAT_FINAL_STATUS;
 				udp->flag |= DEVSTAT_FINAL_STATUS;
 
-				ioinfo[irq]->irq_desc.handler (irq, udp, NULL);
+				if (!ioinfo[irq]->ui.flags.killio)
+					ioinfo[irq]->irq_desc.handler (irq, udp, NULL);
 
 				/*
 				 * reset intparm after final status or we will badly present unsolicited
@@ -3156,7 +3062,7 @@
 					udp->flag |= DEVSTAT_SUSPENDED;
 
 				}
-
+				
 				ioinfo[irq]->irq_desc.handler (irq, udp, NULL);
 
 			}
@@ -3174,16 +3080,15 @@
 		dp->cstat = 0;
 		dp->dstat = 0;
 
-		if (ioinfo[irq]->ulpm != ioinfo[irq]->opm) {
-			/*
-			 * either it was the only path or it was restricted ...
-			 */
-			ioinfo[irq]->opm &=
-			    ~(ioinfo[irq]->devstat.ii.irb.esw.esw1.lpum);
-		} else {
-			ioinfo[irq]->opm = 0;
-
-		}
+ 		if ((dp->ii.irb.scsw.fctl != 0) &&
+ 		    ((dp->ii.irb.scsw.stctl & SCSW_STCTL_STATUS_PEND) != 0) &&
+ 		    (((dp->ii.irb.scsw.stctl & SCSW_STCTL_INTER_STATUS) == 0) ||
+ 		     ((dp->ii.irb.scsw.actl & SCSW_ACTL_SUSPENDED) != 0)))
+ 			if (dp->ii.irb.scsw.pno) {
+ 				stsch(irq, &ioinfo[irq]->schib);
+ 				ioinfo[irq]->opm &=
+ 					~ioinfo[irq]->schib.pmcw.pnom;
+ 			}
 
 		if (ioinfo[irq]->opm == 0) {
 			ioinfo[irq]->ui.flags.oper = 0;
@@ -3234,9 +3139,10 @@
 		ioinfo[irq]->devstat.intparm = 0;
 
 		if (!ioinfo[irq]->ui.flags.s_pend
-		    && !ioinfo[irq]->ui.flags.repnone) {
-			ioinfo[irq]->irq_desc.handler (irq, udp, NULL);
+		    && !ioinfo[irq]->ui.flags.repnone
+		    && !ioinfo[irq]->ui.flags.killio) {
 
+			ioinfo[irq]->irq_desc.handler (irq, udp, NULL);
 		}
 
 		ending_status = 1;
@@ -3245,6 +3151,18 @@
 
 	}
 
+	if (ending_status && 
+	    ioinfo[irq]->ui.flags.noio &&
+	    !ioinfo[irq]->ui.flags.syncio &&
+	    !ioinfo[irq]->ui.flags.w4sense) {
+		if(ioinfo[irq]->ui.flags.ready) {
+			s390_schedule_path_verification(irq);
+		} else {
+			ioinfo[irq]->ui.flags.killio = 0;
+			ioinfo[irq]->ui.flags.noio = 0;
+		}
+	}
+
 	return (ending_status);
 }
 
@@ -3277,7 +3195,7 @@
 	if (cons_dev != -1)
 		return -EBUSY;
 
-	sprintf (dbf_txt, "scd%x", irq);
+	sprintf (dbf_txt, "scons%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/*
@@ -3322,7 +3240,7 @@
 	if (cons_dev != -1)
 		return -EBUSY;
 
-	sprintf (dbf_txt, "rscd%x", irq);
+	sprintf (dbf_txt, "rcons%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/*
@@ -3366,7 +3284,7 @@
 	if (irq != cons_dev)
 		return -EINVAL;
 
-	sprintf (dbf_txt, "wcd%x", irq);
+	sprintf (dbf_txt, "wcons%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/*
@@ -3417,7 +3335,7 @@
 	int rc = 0;
 	char dbf_txt[15];
 
-	sprintf (dbf_txt, "eisc%x", irq);
+	sprintf (dbf_txt, "enisc%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/* This one spins until it can get the sync_isc lock for irq# irq */
@@ -3438,7 +3356,6 @@
 		 * we only run the STSCH/MSCH path for the first enablement
 		 */
 		else if (sync_isc_cnt == 1) {
-			ioinfo[irq]->ui.flags.syncio = 1;
 
 			ccode = stsch (irq, &(ioinfo[irq]->schib));
 
@@ -3463,6 +3380,7 @@
 						 * if neccessary */
 						if (cons_dev != -1)
 							cr6 &= 0xFEFFFFFF;
+						ioinfo[irq]->ui.flags.syncio = 1;
 						__ctl_load (cr6, 6, 6);
 						rc = 0;
 						retry = 0;
@@ -3505,6 +3423,15 @@
 		if (rc) {	/* can only happen if stsch/msch fails */
 			sync_isc_cnt = 0;
 			atomic_set (&sync_isc, -1);
+		} else if (sync_isc_cnt == 1) {
+			int ccode;
+			
+			ccode = stsch(irq, &ioinfo[irq]->schib);
+			if (!ccode && ioinfo[irq]->schib.pmcw.isc != 5) {
+				ioinfo[irq]->ui.flags.syncio = 0;
+				sync_isc_cnt = 0;
+				atomic_set (&sync_isc, -1);
+			}
 		}
 	} else {
 #ifdef CONFIG_SYNC_ISC_PARANOIA
@@ -3531,7 +3458,7 @@
 
 	char dbf_txt[15];
 
-	sprintf (dbf_txt, "disc%x", irq);
+	sprintf (dbf_txt, "disisc%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	if ((irq <= highest_subchannel) && 
@@ -3621,7 +3548,7 @@
 
 			sync_isc_cnt = 0;
 			atomic_set (&sync_isc, -1);
-
+		
 		} else {
 			sync_isc_cnt--;
 
@@ -3641,6 +3568,26 @@
 	return (rc);
 }
 
+int diag210 (diag210_t *addr)
+{
+        int ccode;
+
+        __asm__ __volatile__(
+#ifdef CONFIG_ARCH_S390X
+                "   sam31\n"
+                "   diag  %1,0,0x210\n"
+                "   sam64\n"
+#else
+                "   diag  %1,0,0x210\n"
+#endif
+                "   ipm   %0\n"
+                "   srl   %0,28"
+                : "=d" (ccode) 
+		: "a" (addr)
+                : "cc" );
+        return ccode;
+}
+
 /*
  * Input :
  *   devno - device number
@@ -3658,11 +3605,13 @@
 	CIO_TRACE_EVENT (4, "VMvdinf");
 
 	if (init_IRQ_complete) {
-		p_diag_data = kmalloc (sizeof (diag210_t), GFP_DMA);
+		p_diag_data = kmalloc (sizeof (diag210_t), GFP_DMA | GFP_ATOMIC);
 	} else {
 		p_diag_data = alloc_bootmem_low (sizeof (diag210_t));
 
 	}
+	if (!p_diag_data)
+		return;
 
 	p_diag_data->vrdcdvno = devno;
 	p_diag_data->vrdclen = sizeof (diag210_t);
@@ -3980,7 +3929,7 @@
 int
 read_dev_chars (int irq, void **buffer, int length)
 {
-	unsigned int flags;
+	unsigned long flags;
 	ccw1_t *rdc_ccw;
 	devstat_t devstat;
 	char *rdc_buf;
@@ -4009,7 +3958,7 @@
  		return -EUSERS;
  	}
 
-	sprintf (dbf_txt, "rdc%x", irq);
+	sprintf (dbf_txt, "rddevch%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/*
@@ -4052,8 +4001,7 @@
 				rdc_ccw->count = length;
 				rdc_ccw->flags = CCW_FLAG_SLI;
 				ret =
-				    set_normalized_cda (rdc_ccw, (unsigned long)
-							rdc_buf);
+				    set_normalized_cda (rdc_ccw, rdc_buf);
 				if (!ret) {
 
 					memset (ioinfo[irq]->irq_desc.dev_id,
@@ -4139,7 +4087,7 @@
  		return -EUSERS;
  	}
 
-	sprintf (dbf_txt, "rcd%x", irq);
+	sprintf (dbf_txt, "rdconf%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/*
@@ -4194,7 +4142,7 @@
 			if (init_IRQ_complete) {
 				rcd_buf =
 				    kmalloc (ioinfo[irq]->senseid.ciw[ciw_cnt].
-					     count, GFP_DMA);
+					     count, GFP_DMA | GFP_ATOMIC);
 			} else {
 				rcd_buf =
 				    alloc_bootmem_low (ioinfo[irq]->senseid.
@@ -4553,7 +4501,7 @@
 	int ret;
 	char dbf_txt[15];
 
-	sprintf (dbf_txt, "dri%x", irq);
+	sprintf (dbf_txt, "devrec%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/*
@@ -4576,6 +4524,7 @@
 
 			if (!ret) {
  				pgid_t pgid;
+				int i, mask;
  				/*
  				 * First thing we should do is a sensePGID in
  				 * order to find out how we can proceed with
@@ -4586,13 +4535,24 @@
  				 */
   
  				memcpy(&pgid, global_pgid, sizeof(pgid_t));
- 				ret = s390_SensePGID(irq, 0xff, &pgid);
 
-				if (ret == -EOPNOTSUPP) 
-					/* 
-					 * Doesn't prevent us from proceeding
-					 */
-					ret = 0;
+				ret = -EAGAIN;
+				for (i=0; i<8 && ret==-EAGAIN; i++) {
+
+					mask = (0x80 >> i) & ioinfo[irq]->opm;
+
+					if (!mask)
+						continue;
+
+					ret = s390_SensePGID(irq, mask, &pgid);
+
+					if (ret == -EOPNOTSUPP) 
+						/* 
+						 * Doesn't prevent us from proceeding
+						 */
+						ret = 0;
+
+				}
  				
  				if (!ret && !ioinfo[irq]->ui.flags.unfriendly) {
 
@@ -4645,18 +4605,9 @@
 						s390_displayhex (buffer, prcd,
 								 lrcd);
 #endif
-						if (cio_debug_initialized) {
-							sprintf (buffer,
-								 "RCD for device(%04X)/"
-								 "subchannel(%04X) returns :\n",
-								 ioinfo[irq]->
-								 schib.pmcw.dev,
-								 irq);
-
-							s390_displayhex2
-							    (buffer, prcd, lrcd,
-							     2);
-						}
+						CIO_TRACE_EVENT(2, "rcddata:");
+						CIO_HEX_EVENT(2, prcd, lrcd);
+
 						if (init_IRQ_complete) {
 							kfree (prcd);
 						} else {
@@ -4756,14 +4707,9 @@
 int
 s390_trigger_resense(int irq)
 {
-	char dbf_txt[8];
 
 	SANITY_CHECK(irq);
 
-	CIO_TRACE_EVENT (2, "tsns");
-	sprintf(dbf_txt, "%x", irq);
-	CIO_TRACE_EVENT (2, dbf_txt);
-
 	if (ioinfo[irq]->ui.flags.ready) {
 		printk (KERN_WARNING "s390_trigger_resense(%04X): "
 			"Device is in use!\n", irq);
@@ -4826,7 +4772,7 @@
 
 	char dbf_txt[15];
 
-	sprintf (dbf_txt, "vals%x", irq);
+	sprintf (dbf_txt, "valsch%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/*
@@ -4901,9 +4847,12 @@
 			    alloc_bootmem_low (sizeof (ioinfo_t));
 		} else {
 			ioinfo[irq] = (ioinfo_t *)
-			    kmalloc (sizeof (ioinfo_t), GFP_DMA);
+			    kmalloc (sizeof (ioinfo_t), GFP_DMA | GFP_ATOMIC);
 
 		}
+		if (!ioinfo[irq])
+			return -ENOMEM;
+			
 
 		memset (ioinfo[irq], '\0', sizeof (ioinfo_t));
 		memcpy (&ioinfo[irq]->schib, p_init_schib, sizeof (schib_t));
@@ -4964,6 +4913,10 @@
 					/* disable using this path */
 					ioinfo[irq]->opm &= ~mask;
 				}
+			} else {
+				/* This chpid is not available to us */
+				clear_bit(ioinfo[irq]->schib.pmcw.chpid[chp],
+					  &chpids);
 			}
 		}
 	}
@@ -5209,8 +5162,7 @@
  		return -EUSERS;
  	}
 
-	CIO_TRACE_EVENT (4, "senseID");
-	sprintf (dbf_txt, "%x", irq);
+	sprintf (dbf_txt, "snsID%x", irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	inlreq = 0;		/* to make the compiler quiet... */
@@ -5245,11 +5197,17 @@
 	s390irq_spin_lock (irq);
 
 	if (init_IRQ_complete) {
-		sense_ccw = kmalloc (2 * sizeof (ccw1_t), GFP_DMA);
+		sense_ccw = kmalloc (2 * sizeof (ccw1_t), GFP_DMA | GFP_ATOMIC);
 	} else {
 		sense_ccw = alloc_bootmem_low (2 * sizeof (ccw1_t));
 
 	}
+	if (!sense_ccw) {
+		s390irq_spin_unlock (irq);
+		if (inlreq)
+			free_irq (irq, &devstat);
+		return -ENOMEM;
+	}
 
 	/* more than one path installed ? */
 	if (ioinfo[irq]->schib.pmcw.pim != 0x80) {
@@ -5642,56 +5600,237 @@
 	return (cc);
 }
 
-/*
- * Device Path Verification
- *
- * Path verification is accomplished by checking which paths (CHPIDs) are
- *  available. Further, a path group ID is set, if possible in multipath
- *  mode, otherwise in single path mode.
- *
- * Note : This function must not be called during normal device recognition,
- *         but during device driver initiated request_irq() processing only.
- */
-int
-s390_DevicePathVerification (int irq, __u8 usermask)
+static int
+s390_do_path_verification(int irq, __u8 usermask)
 {
-	int ccode;
-	__u8 pathmask;
 	__u8 domask;
-#ifdef CONFIG_CHSC
-	int chp;
-	int mask;
-	int old_opm = 0;
-#endif /* CONFIG_CHSC */
-
-	int ret = 0;
 	int i;
 	pgid_t pgid;
 	__u8 dev_path;
 	int first = 1;
-
+	int ret = 0;
 	char dbf_txt[15];
 
-	sprintf (dbf_txt, "dpvf%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
+	sprintf(dbf_txt, "dopv%x", irq);
+	CIO_TRACE_EVENT(2, dbf_txt);
 
-	if (ioinfo[irq]->st) 
-		return -ENODEV;
+	dev_path = usermask ? usermask : ioinfo[irq]->opm;
 
-#ifdef CONFIG_CHSC
-	old_opm = ioinfo[irq]->opm;
+	if (ioinfo[irq]->ui.flags.pgid == 0) {
+		memcpy (&ioinfo[irq]->pgid, global_pgid, sizeof (pgid_t));
+		ioinfo[irq]->ui.flags.pgid = 1;
+	}
+
+	for (i = 0; i < 8 && !ret; i++) {
+
+		domask = dev_path & (0x80>>i);
+
+		if (!domask)
+			continue;
+
+		if (!test_bit(ioinfo[irq]->schib.pmcw.chpid[i],
+			      &chpids_logical))
+			/* Chpid is logically offline, don't do io */
+			continue;
+
+		ret = s390_SetPGID (irq, domask);
+
+		/*
+		 * For the *first* path we are prepared for recovery
+		 *
+		 *  - If we fail setting the PGID we assume its
+		 *     using  a different PGID already (VM) we
+		 *     try to sense.
+		 */
+		if (ret == -EOPNOTSUPP && first) {
+			*(int *) &pgid = 0;
+			
+			ret = s390_SensePGID (irq, domask, &pgid);
+			first = 0;
+
+			if (ret == 0) {
+				/*
+				 * Check whether we retrieved
+				 *  a reasonable PGID ...
+				 */
+				if (pgid.inf.ps.state1 == SNID_STATE1_GROUPED)
+					memcpy (&ioinfo[irq]->pgid,
+						&pgid, sizeof (pgid_t));
+				else /* ungrouped or garbage ... */
+					ret = -EOPNOTSUPP;
+				
+			} else {
+				ioinfo[irq]->ui.flags.pgid_supp = 0;
+
+#ifdef CONFIG_DEBUG_IO
+				printk (KERN_WARNING
+					"PathVerification(%04X) - Device %04X "
+					"doesn't support path grouping\n",
+					irq, ioinfo[irq]->schib.pmcw.dev);
+#endif
+				CIO_MSG_EVENT(2, "PathVerification(%04X) "
+					      "- Device %04X doesn't "
+					      " support path grouping\n",
+					      irq,
+					      ioinfo[irq]->schib.pmcw.dev);
+					
+			}
+		} else if (ret == -EIO) {
+#ifdef CONFIG_DEBUG_IO
+			printk (KERN_ERR "PathVerification(%04X) - I/O error "
+				"on device %04X\n", irq,
+				ioinfo[irq]->schib.pmcw.dev);
+#endif
+
+			CIO_MSG_EVENT(2, "PathVerification(%04X) - I/O error "
+				      "on device %04X\n", irq,
+				      ioinfo[irq]->schib.pmcw.dev);
+				
+			ioinfo[irq]->ui.flags.pgid_supp = 0;
+
+		} else if (ret == -ETIMEDOUT) {
+#ifdef CONFIG_DEBUG_IO
+			printk (KERN_ERR "PathVerification(%04X) - I/O timed "
+				"out on device %04X\n", irq,
+				ioinfo[irq]->schib.pmcw.dev);
+#endif
+			CIO_MSG_EVENT(2, "PathVerification(%04X) - I/O timed "
+				      "out on device %04X\n", irq,
+				      ioinfo[irq]->schib.pmcw.dev);
+				
+			ioinfo[irq]->ui.flags.pgid_supp = 0;
+
+		} else if (ret == -EAGAIN) {
+			
+			ret = 0;
+		} else if (ret == -EUSERS) {
+			
+#ifdef CONFIG_DEBUG_IO
+			printk (KERN_ERR "PathVerification(%04X) "
+				"- Device is locked by someone else!\n",
+				irq);
+#endif
+			CIO_MSG_EVENT(2, "PathVerification(%04X) "
+				      "- Device is locked by someone else!\n",
+				      irq);
+		} else if (ret == -ENODEV) {
+#ifdef CONFIG_DEBUG_IO
+			printk (KERN_ERR "PathVerification(%04X) "
+				"- Device %04X is no longer there?!?\n",
+				irq, ioinfo[irq]->schib.pmcw.dev);
+#endif
+			CIO_MSG_EVENT(2, "PathVerification(%04X) "
+				      "- Device %04X is no longer there?!?\n",
+				      irq, ioinfo[irq]->schib.pmcw.dev);
+
+		} else if (ret == -EBUSY) {
+			/* 
+			 * The device is busy. Schedule the path verification 
+			 * bottom half and we'll hopefully get in next time.
+			 */
+			if (!ioinfo[irq]->ui.flags.noio) {
+				s390_schedule_path_verification(irq);
+			}
+			return -EINPROGRESS;
+		} else if (ret) {
+#ifdef CONFIG_DEBUG_IO
+			printk (KERN_ERR "PathVerification(%04X) "
+				"- Unexpected error %d on device %04X\n",
+				irq, ret, ioinfo[irq]->schib.pmcw.dev);
+#endif
+			CIO_MSG_EVENT(2, "PathVerification(%04X) - "
+				      "Unexpected error %d on device %04X\n",
+				      irq, ret, ioinfo[irq]->schib.pmcw.dev);
+				
+			ioinfo[irq]->ui.flags.pgid_supp = 0;
+		}
+	}
+	if (stsch(irq, &ioinfo[irq]->schib) != 0)
+		/* FIXME: tell driver device is dead. */
+		return -ENODEV;
+
+	/*
+	 * stsch() doesn't always yield the correct pim, pam, and pom
+	 * values, if no device selection has been performed yet.
+	 * However, after complete path verification they are up to date.
+	 */
+	ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim &
+		ioinfo[irq]->schib.pmcw.pam &
+		ioinfo[irq]->schib.pmcw.pom;
+
+#ifdef CONFIG_CHSC	
+	if (ioinfo[irq]->opm) {
+		for (i=0;i<=7;i++) {
+			int mask = 0x80 >> i;
+			if ((ioinfo[irq]->opm & mask) &&
+			    (!test_bit(ioinfo[irq]->schib.pmcw.chpid[i],
+				       &chpids_logical)))
+				/* disable using this path */
+				ioinfo[irq]->opm &= ~mask;
+		}
+	}
+#endif /* CONFIG_CHSC */	
+
+	ioinfo[irq]->ui.flags.noio = 0;
+
+	/* Eventually wake up the device driver. */
+	if (ioinfo[irq]->opm != 0) {
+		devreg_t *pdevreg;
+		pdevreg = s390_search_devreg(ioinfo[irq]);
+
+		if (pdevreg && pdevreg->oper_func)
+			pdevreg->oper_func(irq, pdevreg);
+	}
+	return ret;
+
+}
+
+/*
+ * Device Path Verification
+ *
+ * Path verification is accomplished by checking which paths (CHPIDs) are
+ *  available. Further, a path group ID is set, if possible in multipath
+ *  mode, otherwise in single path mode.
+ *
+ * Note : This function must not be called during normal device recognition,
+ *         but during device driver initiated request_irq() processing only.
+ */
+int
+s390_DevicePathVerification (int irq, __u8 usermask)
+{
+	int ccode;
+#ifdef CONFIG_CHSC
+	int chp;
+	int mask;
+	int old_opm = 0;
+#endif /* CONFIG_CHSC */
+
+	int ret = 0;
+
+	char dbf_txt[15];
+	devreg_t *pdevreg;
+
+	sprintf (dbf_txt, "dpver%x", irq);
+	CIO_TRACE_EVENT (4, dbf_txt);
+
+	if (ioinfo[irq]->st) 
+		return -ENODEV;
+
+#ifdef CONFIG_CHSC
+	old_opm = ioinfo[irq]->opm;
 #endif /* CONFIG_CHSC */
 	ccode = stsch (irq, &(ioinfo[irq]->schib));
 
-	if (ccode) {
+	if (ccode)
 		return -ENODEV;
-	}
+
 	if (ioinfo[irq]->schib.pmcw.pim == 0x80) {
 		/*
 		 * no error, just not required for single path only devices
 		 */
 		ioinfo[irq]->ui.flags.pgid_supp = 0;
 		ret = 0;
+		ioinfo[irq]->ui.flags.noio = 0;
 
 #ifdef CONFIG_CHSC
 		/*
@@ -5699,58 +5838,35 @@
 		 */
 		if (!test_bit(ioinfo[irq]->schib.pmcw.chpid[0], 
 			      &chpids_logical)) {
-			not_oper_handler_func_t nopfunc=ioinfo[irq]->nopfunc;
-			int was_oper = ioinfo[irq]->ui.flags.oper;
 
 			ioinfo[irq]->opm = 0;
 			ioinfo[irq]->ui.flags.oper = 0;
 			printk(KERN_WARNING 
 			       "No logical path for sch %d...\n",
 			       irq);
-			if (old_opm && 
-			    was_oper && 
-			    ioinfo[irq]->ui.flags.ready) {
-#ifdef CONFIG_PROC_FS
-				if (cio_proc_devinfo)
-					cio_procfs_device_remove
-						(ioinfo[irq]->devno);
-#endif /* CONFIG_PROC_FS */
-				free_irq( irq, ioinfo[irq]->irq_desc.dev_id);
-				if (nopfunc)
-					nopfunc( irq, DEVSTAT_DEVICE_GONE);
-			}
-			ret = -ENODEV;
-		} else if (!old_opm) {
 
-			/*
-			 * check for opm...
-			 */
+			if (ioinfo[irq]->nopfunc)
+				ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC);
+
+			return -ENODEV;
+		}
+		if (!old_opm) {
+
 			ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim
 				& ioinfo[irq]->schib.pmcw.pam
 				& ioinfo[irq]->schib.pmcw.pom;
-				
+		
 			if (ioinfo[irq]->opm) {
-				devreg_t *pdevreg;
 
 				ioinfo[irq]->ui.flags.oper = 1;
-				pdevreg = s390_search_devreg( ioinfo[irq] );
-
-				if (pdevreg) 
-					if (pdevreg->oper_func)
-						pdevreg->oper_func
-							( irq, pdevreg);
-#ifdef CONFIG_PROC_FS
-				if (cio_proc_devinfo) 
-					if (highest_subchannel 
-					    < MAX_CIO_PROCFS_ENTRIES) {
-						cio_procfs_device_create
-							(ioinfo[irq]->devno);
-					}
-#endif /* CONFIG_PROC_FS */
+				pdevreg = s390_search_devreg(ioinfo[irq]);
+			
+				if (pdevreg && pdevreg->oper_func)
+					pdevreg->oper_func(irq, pdevreg);
+				ret = 0;
+			} else {
+				ret = -ENODEV;
 			}
-			ret = 0;
-		} else {
-			ret = 0;
 		}
 #endif /* CONFIG_CHSC */
 		return ret;
@@ -5763,199 +5879,72 @@
 	if (ioinfo[irq]->opm) {
 		for (chp=0;chp<=7;chp++) {
 			mask = 0x80 >> chp;
-			if (ioinfo[irq]->opm & mask) {
-				if (!test_bit
-				    (ioinfo[irq]->schib.pmcw.chpid[chp], 
-				     &chpids_logical)) {
-					/* disable using this path */
-					ioinfo[irq]->opm &= ~mask;
-				}
-			}
+			if ((ioinfo[irq]->opm & mask)
+			    &&(!test_bit(ioinfo[irq]->schib.pmcw.chpid[chp],
+					 &chpids_logical)))
+				/* disable using this path */
+				ioinfo[irq]->opm &= ~mask;
 		}
 	}
 	
-	if ((ioinfo[irq]->opm == 0) && (old_opm)) {
-		not_oper_handler_func_t nopfunc=ioinfo[irq]->nopfunc;
-		int was_oper = ioinfo[irq]->ui.flags.ready;
-
-		ioinfo[irq]->ui.flags.oper = 0;
-		printk(KERN_WARNING "No logical path for sch %d...\n",irq);
-		if (was_oper && ioinfo[irq]->ui.flags.oper) {
-#ifdef CONFIG_PROC_FS
-			if (cio_proc_devinfo)
-				cio_procfs_device_remove(ioinfo[irq]->devno);
-#endif /* CONFIG_PROC_FS */
-				free_irq( irq, ioinfo[irq]->irq_desc.dev_id);
-				if (nopfunc)
-					nopfunc( irq, DEVSTAT_DEVICE_GONE);
-		}
-		return -ENODEV;
-	}
-
-	if (!old_opm) {
-		/* Hey, we have a new logical path... */
-		devreg_t *pdevreg;
-		
-		ioinfo[irq]->ui.flags.oper = 1;
-		pdevreg = s390_search_devreg( ioinfo[irq] );
-		
-		if (pdevreg) 
-			if (pdevreg->oper_func)
-				pdevreg->oper_func( irq, pdevreg);
-#ifdef CONFIG_PROC_FS		
-		if (cio_proc_devinfo) 
-			if (highest_subchannel < MAX_CIO_PROCFS_ENTRIES) {
-				cio_procfs_device_create(ioinfo[irq]->devno);
-			}
-#endif /* CONFIG_PROC_FS */
-	}
 #endif /* CONFIG_CHSC */
 
-	if ( ioinfo[irq]->ui.flags.pgid_supp == 0 )
-		return( 0);	/* just exit ... */
+	if (ioinfo[irq]->ui.flags.pgid_supp == 0) {		
 
-	if (usermask) {
-		dev_path = usermask;
-	} else {
-		dev_path = ioinfo[irq]->opm;
+		if (ioinfo[irq]->opm == 0)
+			return -ENODEV;
+			
+		ioinfo[irq]->ui.flags.oper = 1;
+		ioinfo[irq]->ui.flags.noio = 0;
 
-	}
+		pdevreg = s390_search_devreg(ioinfo[irq]);
+		
+		if (pdevreg && pdevreg->oper_func)
+			pdevreg->oper_func(irq, pdevreg);
 
-	if (ioinfo[irq]->ui.flags.pgid == 0) {
-		memcpy (&ioinfo[irq]->pgid, global_pgid, sizeof (pgid_t));
-		ioinfo[irq]->ui.flags.pgid = 1;
+		return 0;
 	}
 
-	for (i = 0; i < 8 && !ret; i++) {
-		pathmask = 0x80 >> i;
-
-		domask = dev_path & pathmask;
-
-		if (domask) {
-			ret = s390_SetPGID (irq, domask);
-
-			/*
-			 * For the *first* path we are prepared
-			 *  for recovery
-			 *
-			 *  - If we fail setting the PGID we assume its
-			 *     using  a different PGID already (VM) we
-			 *     try to sense.
-			 */
-			if (ret == -EOPNOTSUPP && first) {
-				*(int *) &pgid = 0;
-
-				ret = s390_SensePGID (irq, domask, &pgid);
-				first = 0;
-
-				if (ret == 0) {
-					/*
-					 * Check whether we retrieved
-					 *  a reasonable PGID ...
-					 */
-					if (pgid.inf.ps.state1 ==
-					    SNID_STATE1_GROUPED) {
-						memcpy (&ioinfo[irq]->pgid,
-							&pgid, sizeof (pgid_t));
-					} else {	/* ungrouped or garbage ... */
-						ret = -EOPNOTSUPP;
-
-					}
-				} else {
-					ioinfo[irq]->ui.flags.pgid_supp = 0;
-
-#ifdef CONFIG_DEBUG_IO
-					printk (KERN_WARNING
-						"PathVerification(%04X) "
-						"- Device %04X doesn't "
-						" support path grouping\n",
-						irq,
-						ioinfo[irq]->schib.pmcw.dev);
-#endif
-					CIO_MSG_EVENT(2,
-						      "PathVerification(%04X) "
-						      "- Device %04X doesn't "
-						      " support path grouping\n",
-						      irq,
-						      ioinfo[irq]->schib.
-						      pmcw.dev);
-					
-				}
-			} else if (ret == -EIO) {
-#ifdef CONFIG_DEBUG_IO
-				printk (KERN_ERR
-					"PathVerification(%04X) - I/O error "
-					"on device %04X\n", irq,
-					ioinfo[irq]->schib.pmcw.dev);
-#endif
+	return s390_do_path_verification (irq, usermask);
 
-				CIO_MSG_EVENT(2,
-					      "PathVerification(%04X) - I/O error "
-					      "on device %04X\n", irq,
-					      ioinfo[irq]->schib.pmcw.dev);
-				
-				ioinfo[irq]->ui.flags.pgid_supp = 0;
+}
 
-			} else if (ret == -ETIMEDOUT) {
-#ifdef CONFIG_DEBUG_IO
-				printk (KERN_ERR
-					"PathVerification(%04X) - I/O timed "
-					"out on device %04X\n", 
-					irq,
-					ioinfo[irq]->schib.pmcw.dev);
-#endif
-				CIO_MSG_EVENT(2,
-					      "PathVerification(%04X) - I/O timed "
-					      "out on device %04X\n", irq,
-					      ioinfo[irq]->schib.pmcw.dev);
-				
-				ioinfo[irq]->ui.flags.pgid_supp = 0;
+void
+s390_kick_path_verification (unsigned long irq)
+{
+	long cr6 __attribute__ ((aligned (8)));
 
-			} else if (ret == -EAGAIN) {
+	atomic_set (&ioinfo[irq]->pver_pending, 0);
+	/* Do not enter path verification if sync_isc is enabled. */
+	__ctl_store (cr6, 6, 6);
+	if (cr6 & 0x04000000) {
+		s390_schedule_path_verification (irq);
+		return;
+	}
+	ioinfo[irq]->ui.flags.killio = 0;
+	s390_DevicePathVerification(irq, 0xff);
 
-				ret = 0;
+}
 
-			} else if (ret == -EUSERS) {
-				
-#ifdef CONFIG_DEBUG_IO
-				printk (KERN_ERR 
-					"PathVerification(%04X) "
-					"- Device is locked by someone else!\n",
-					irq);
-#endif
-				CIO_MSG_EVENT(2,
-					      "PathVerification(%04X) "
-					      "- Device is locked by someone else!\n",
-					      irq);
-			} else if (ret == -ENODEV) {
-#ifdef CONFIG_DEBUG_IO
-				printk (KERN_ERR 
-					"PathVerification(%04X) "
-					"- Device %04X is no longer there?!?\n",
-					irq, ioinfo[irq]->schib.pmcw.dev);
-#endif
-				CIO_MSG_EVENT(2,
-					      "PathVerification(%04X) "
-					      "- Device %04X is no longer there?!?\n",
-					      irq, ioinfo[irq]->schib.pmcw.dev);
-			} else if (ret) {
-#ifdef CONFIG_DEBUG_IO
-				printk (KERN_ERR
-					"PathVerification(%04X) "
-					"- Unexpected error %d on device %04X\n",
-					irq, ret, ioinfo[irq]->schib.pmcw.dev);
-#endif
-				CIO_MSG_EVENT(2,
-					      "PathVerification(%04X) - "
-					      "Unexpected error %d on device %04X\n",
-					      irq, ret, ioinfo[irq]->schib.pmcw.dev);
-				
-				ioinfo[irq]->ui.flags.pgid_supp = 0;
-			}
-		}
+static void
+s390_schedule_path_verification(unsigned long irq)
+{
+	/* Protect against rescheduling, when already running */
+	if (atomic_compare_and_swap (0, 1, &ioinfo[irq]->pver_pending)) {
+		return;
 	}
-	return ret;
 
+	/* 
+	 * Call path verification.
+	 * Note this is always called from inside the i/o layer, so we don't 
+	 * need to care about the usermask.
+	 */
+	INIT_LIST_HEAD (&ioinfo[irq]->pver_bh.list);
+	ioinfo[irq]->pver_bh.sync = 0;
+	ioinfo[irq]->pver_bh.routine = (void*) (void*) s390_kick_path_verification;
+	ioinfo[irq]->pver_bh.data = (void*) irq;
+	queue_task (&ioinfo[irq]->pver_bh, &tq_immediate);
+	mark_bh (IMMEDIATE_BH);
 }
 
 /*
@@ -6018,10 +6007,15 @@
 	s390irq_spin_lock_irqsave (irq, flags);
 
 	if (init_IRQ_complete) {
-		spid_ccw = kmalloc (2 * sizeof (ccw1_t), GFP_DMA);
+		spid_ccw = kmalloc (2 * sizeof (ccw1_t), GFP_DMA | GFP_ATOMIC);
 	} else {
 		spid_ccw = alloc_bootmem_low (2 * sizeof (ccw1_t));
-
+	}
+	if (!spid_ccw) {
+		s390irq_spin_unlock_irqrestore(irq, flags);
+		if (inlreq)
+			free_irq(irq, pdevstat);
+		return -ENOMEM;
 	}
 
 	spid_ccw[0].cmd_code = CCW_CMD_SUSPEND_RECONN;
@@ -6056,17 +6050,19 @@
 				printk (KERN_DEBUG "SPID - Device %04X "
 					"on Subchannel %04X "
 					"reports pending status, "
+					"lpm = %x, "
 					"retry : %d\n",
 					ioinfo[irq]->schib.pmcw.dev,
-					irq, retry);
+					irq, lpm, retry);
 #endif
 				CIO_MSG_EVENT(2,
 					      "SPID - Device %04X "
 					      "on Subchannel %04X "
 					      "reports pending status, "
+					      "lpm = %x, "
 					      "retry : %d\n",
 					      ioinfo[irq]->schib.pmcw.
-					      dev, irq, retry);
+					      dev, irq, lpm, retry);
 				retry--;
 				irq_ret = -EIO;
 			}
@@ -6117,11 +6113,12 @@
 						"SPID - device %04X,"
 						" unit check,"
 						" retry %d, cnt %02d,"
-						" sns :"
+						" lpm %x, sns :"
 						" %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
 						ioinfo[irq]->schib.pmcw.
 						dev, retry,
 						pdevstat->scnt,
+						lpm, 
 						pdevstat->ii.sense.
 						data[0],
 						pdevstat->ii.sense.
@@ -6143,11 +6140,12 @@
 						     "SPID - device %04X,"
 						     " unit check,"
 						     " retry %d, cnt %02d,"
-						     " sns :"
+						     " lpm %x, sns :"
 						     " %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
 						     ioinfo[irq]->schib.
 						     pmcw.dev, retry,
 						     pdevstat->scnt,
+						     lpm, 
 						     pdevstat->ii.sense.
 						     data[0],
 						     pdevstat->ii.sense.
@@ -6174,7 +6172,7 @@
 				/* don't issue warnings during startup unless requested */
 				if (init_IRQ_complete || cio_notoper_msg) {
 
-					printk (KERN_WARNING
+					printk (KERN_INFO
 						"SPID - Device %04X "
 						"on Subchannel %04X, "
 						"lpm %02X, "
@@ -6214,12 +6212,52 @@
 					      irq);
 			retry--;
 
+		} else if (irq_ret == -EBUSY) {
+#ifdef CONFIG_DEBUG_IO
+			printk(KERN_WARNING
+			       "SPID - device %x, irq %x is busy!\n",
+			       ioinfo[irq]->schib.pmcw.dev, irq);
+#endif /* CONFIG_DEBUG_IO */
+			CIO_MSG_EVENT(2,
+				      "SPID - device %x, irq %x is busy!\n",
+				      ioinfo[irq]->schib.pmcw.dev, irq);
+			retry = 0;
+
 		} else if (irq_ret != -ENODEV) {
 			retry--;
 			irq_ret = -EIO;
-		} else {
+		} else if (!pdevstat->flag & DEVSTAT_NOT_OPER) {
 			retry = 0;
 			irq_ret = -ENODEV;
+		} else {
+			/* don't issue warnings during startup unless requested */
+			if (init_IRQ_complete || cio_notoper_msg) {
+				
+				printk (KERN_INFO
+					"SPID - Device %04X "
+					"on Subchannel %04X, "
+					"lpm %02X, "
+					"became 'not operational'\n",
+					ioinfo[irq]->schib.pmcw.
+					dev, irq,
+					lpm);
+				CIO_MSG_EVENT(2,
+					      "SPID - Device %04X "
+					      "on Subchannel %04X, "
+					      "lpm %02X, "
+					      "became 'not operational'\n",
+					      ioinfo[irq]->schib.
+					      pmcw.dev, irq,
+					      lpm);
+			}
+
+			retry = 0;
+			ioinfo[irq]->opm &= ~lpm;
+
+			if (ioinfo[irq]->opm != 0)
+				irq_ret = -EAGAIN;
+			else
+				irq_ret = -ENODEV;
 
 		}
 
@@ -6302,13 +6340,32 @@
 	ioinfo[irq]->ui.flags.unfriendly = 0; /* assume it's friendly... */
 
 	if (init_IRQ_complete) {
-		snid_ccw = kmalloc (sizeof (ccw1_t), GFP_DMA);
-		tmp_pgid = kmalloc (sizeof (pgid_t), GFP_DMA);
+		snid_ccw = kmalloc (sizeof (ccw1_t), GFP_DMA | GFP_ATOMIC);
+		tmp_pgid = kmalloc (sizeof (pgid_t), GFP_DMA | GFP_ATOMIC);
 	} else {
 		snid_ccw = alloc_bootmem_low (sizeof (ccw1_t));
 		tmp_pgid = alloc_bootmem_low (sizeof (pgid_t));
 	}
 
+	if (!snid_ccw || !tmp_pgid) {
+		if (snid_ccw) {
+			if (init_IRQ_complete)
+				kfree(snid_ccw);
+			else
+				free_bootmem((unsigned long) snid_ccw, sizeof(ccw1_t));
+		}
+		if (tmp_pgid) {
+			if (init_IRQ_complete)
+				kfree(tmp_pgid);
+			else
+				free_bootmem((unsigned long) tmp_pgid, sizeof(pgid_t));
+		}
+		s390irq_spin_unlock_irqrestore(irq, flags);
+		if (inlreq) 
+			free_irq (irq, pdevstat);
+		return -ENOMEM;
+	}
+
 	snid_ccw->cmd_code = CCW_CMD_SENSE_PGID;
 	snid_ccw->cda = (__u32) virt_to_phys (tmp_pgid);
 	snid_ccw->count = sizeof (pgid_t);
@@ -6335,8 +6392,8 @@
 				 *  Sense Path Group ID command
 				 *  further retries wouldn't help ...
 				 */
-				if (pdevstat->ii.sense.data[0] & 
-				    (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)) {
+				if (pdevstat->ii.sense.data[0] 
+				    & (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)) {
 					retry = 0;
 					irq_ret = -EOPNOTSUPP;
 				} else {
@@ -6403,7 +6460,7 @@
 			} else if (pdevstat->flag & DEVSTAT_NOT_OPER) {
 				/* don't issue warnings during startup unless requested */
 				if (init_IRQ_complete || cio_notoper_msg) {
-					printk (KERN_WARNING
+					printk (KERN_INFO
 						"SNID - Device %04X "
 						"on Subchannel %04X, "
 						"lpm %02X, "
@@ -6422,7 +6479,8 @@
 				}
 
 				retry = 0;
-				irq_ret = -EIO;
+				ioinfo[irq]->opm &= ~lpm;
+				irq_ret = -EAGAIN;
 
 			} else {
 				retry = 0;	/* success ... */
@@ -6432,7 +6490,7 @@
  				 * -- we'll fail other commands if that is
  				 * the case
  				 */
- 				if (pgid->inf.ps.state2 ==
+ 				if (tmp_pgid->inf.ps.state2 ==
  				    SNID_STATE2_RESVD_ELSE) {
  					printk (KERN_WARNING 
  						"SNID - Device %04X "
@@ -6507,10 +6565,38 @@
 				      ioinfo[irq]->schib.pmcw.dev, irq_ret);
 			retry--;
 			irq_ret = -EIO;
-		} else {	/* -ENODEV ... */
-
+		} else if (!pdevstat->flag & DEVSTAT_NOT_OPER) {
 			retry = 0;
 			irq_ret = -ENODEV;
+		} else {
+			/* don't issue warnings during startup unless requested */
+			if (init_IRQ_complete || cio_notoper_msg) {
+				
+				printk (KERN_INFO
+					"SNID - Device %04X "
+					"on Subchannel %04X, "
+					"lpm %02X, "
+					"became 'not operational'\n",
+					ioinfo[irq]->schib.pmcw.
+					dev, irq,
+					lpm);
+				CIO_MSG_EVENT(2,
+					      "SNID - Device %04X "
+					      "on Subchannel %04X, "
+					      "lpm %02X, "
+					      "became 'not operational'\n",
+					      ioinfo[irq]->schib.
+					      pmcw.dev, irq,
+					      lpm);
+			}
+
+			retry = 0;
+			ioinfo[irq]->opm &= ~lpm;
+
+			if (ioinfo[irq]->opm != 0)
+				irq_ret = -EAGAIN;
+			else
+				irq_ret = -ENODEV;
 
 		}
 
@@ -6650,12 +6736,9 @@
 
 				pdevreg = s390_search_devreg (ioinfo[irq]);
 
-				if (pdevreg != NULL) {
-					if (pdevreg->oper_func != NULL)
-						pdevreg->
-						    oper_func (irq, pdevreg);
+				if (pdevreg && pdevreg->oper_func)
+					pdevreg->oper_func(irq, pdevreg);
 
-				}
 #ifdef CONFIG_PROC_FS
 				/* add new procfs entry */
 				if (cio_proc_devinfo)
@@ -6995,19 +7078,120 @@
 
 __initcall(chsc_get_sch_descriptions);
 
+static int
+__check_for_io_and_kill(int irq, __u8 mask, int fatal)
+{
+	schib_t *schib = &ioinfo[irq]->schib;
+	int ret = 0;
+
+	if (schib->scsw.actl & SCSW_ACTL_DEVACT) {
+		if ((ioinfo[irq]->opm != mask) ||
+		     (fatal == 0)) {
+			ret = CIO_PATHGONE_WAIT4INT;
+		}
+		if ((schib->scsw.actl & SCSW_ACTL_SCHACT) &&
+		    (schib->pmcw.lpum == mask) &&
+		    (fatal != 0)) {
+			int cc;
+			/* Kill the IO. It won't complete. */
+			ioinfo[irq]->ui.flags.noio = 0;
+			ioinfo[irq]->ui.flags.killio = 1;
+			cc = clear_IO(irq, 0xD2C9D3D3, 0);
+			if (cc != 0) {
+				/* Eek, can't kill io. */
+				CIO_CRW_EVENT(0, 
+					      "Can't kill io on "
+					      "sch %x, clear_IO "
+					      "returned %d!\n",
+					      irq, cc);
+				ioinfo[irq]->ui.flags.killio = 0;
+				s390irq_spin_unlock(irq);
+				if ((cc == -ENODEV) && 
+				    (ioinfo[irq]->nopfunc)) {
+					ioinfo[irq]->ui.flags.oper = 0;
+					ioinfo[irq]->nopfunc(irq,
+							     DEVSTAT_DEVICE_GONE);
+				}
+				ret = CIO_PATHGONE_DEVGONE;
+			} else {
+				ret |= CIO_PATHGONE_WAIT4INT;
+			}
+			ioinfo[irq]->ui.flags.noio = 1;
+			ret |= CIO_PATHGONE_IOERR;
+		}
+
+	} else if (schib->scsw.actl & (SCSW_ACTL_CLEAR_PEND |
+				SCSW_ACTL_HALT_PEND |
+				SCSW_ACTL_START_PEND |
+				SCSW_ACTL_RESUME_PEND)) {
+		if ((schib->pmcw.lpum != mask) ||
+		    (fatal == 0)) {
+			ret = CIO_PATHGONE_WAIT4INT;
+		} else {
+			int cc;
+			/* Cancel the i/o. */
+			cc = cancel_IO(irq);
+			switch (cc) {
+			case 0: 
+				/* i/o cancelled; we can do path verif. */
+				ret = CIO_PATHGONE_IOERR;
+				break;
+			case -EBUSY:
+				/* Status pending, we'll get an interrupt */
+				ret = CIO_PATHGONE_WAIT4INT;
+				break;
+			case -EINVAL:
+				/*
+				 * There is either not only the start function
+				 * specified or we are subchannel active.
+				 * Do a clear sch.
+				 */
+				ioinfo[irq]->ui.flags.noio = 0;
+				ioinfo[irq]->ui.flags.killio = 1;
+				cc = clear_IO(irq, 0xD2C9D3D3, 0);
+				if (cc != 0) {
+				/* Eek, can't kill io. */
+					CIO_CRW_EVENT(0, 
+						      "Can't kill io on "
+						      "sch %x, clear_IO "
+						      "returned %d!\n",
+						      irq, cc);
+					ioinfo[irq]->ui.flags.killio = 0;
+					s390irq_spin_unlock(irq);
+					if ((cc == -ENODEV) && 
+					    (ioinfo[irq]->nopfunc)) {
+						ioinfo[irq]->nopfunc(irq,
+								     DEVSTAT_DEVICE_GONE);
+						ioinfo[irq]->ui.flags.oper = 0;
+					}
+					ret = CIO_PATHGONE_DEVGONE;
+				} else {
+					ret = CIO_PATHGONE_WAIT4INT
+						| CIO_PATHGONE_IOERR;
+					ioinfo[irq]->ui.flags.noio = 1;
+				}
+				break;
+			default: /* -ENODEV */
+				s390irq_spin_unlock(irq);
+				if (ioinfo[irq]->nopfunc) {
+						ioinfo[irq]->ui.flags.oper = 0;
+						ioinfo[irq]->nopfunc(irq,
+								     DEVSTAT_DEVICE_GONE);
+				}
+				ret = CIO_PATHGONE_DEVGONE;
+			}
+		}
+	}
+	return ret;
+}
+
 void 
 s390_do_chpid_processing( __u8 chpid)
 {
 
 	int irq;
 	int j;
-	int mask;
 	char dbf_txt[15];
-	int ccode;
-	int was_oper;
-	int chp = 0;
-	int mask2;
-	int ret = 0;
 
 	sprintf(dbf_txt, "chpr%x", chpid);
 	CIO_TRACE_EVENT( 2, dbf_txt);
@@ -7017,141 +7201,82 @@
 	 * but the chpid the report came in through. How to handle???
 	 */
 	clear_bit(chpid, &chpids);
-	if (!test_and_clear_bit(chpid, &chpids_known))
+	if (!test_and_clear_bit(chpid, &chpids_known)) {
+#ifdef CONFIG_DEBUG_CHSC
+		pr_debug(KERN_DEBUG"Got link incident for unknown chpid %x\n",
+		       chpid);
+#endif /* CONFIG_DEBUG_CHSC */
 		return;  /* we didn't know the chpid anyway */
+	}
 
 	for (irq=0;irq<=highest_subchannel;irq++) {
+		schib_t *schib;
+		
 		if (ioinfo[irq] == INVALID_STORAGE_AREA) 
 			continue;  /* we don't know the device anyway */
 		if (ioinfo[irq]->st)
 			continue; /* non-io subchannel */
+		schib = &ioinfo[irq]->schib;
 		for (j=0; j<8;j++) {
-			if (ioinfo[irq]->schib.pmcw.chpid[j] == chpid) {
-				
-				/*
-				 * Send nops down each path to find out
-				 * which path is gone (ssch will yield cc=3 
-				 * and the path will be switched off in the opm)
-				 */
-				
-				/* 
-				 * Note: irq spinlock is grabbed several times
-				 * in here
-				 */
-				for (chp=0;chp<=7;chp++) {
-					mask2 = 0x80 >> chp;
-					if (mask2 & ioinfo[irq]->opm)
-						ret = s390_send_nop (irq, mask2);
-				}
-				
-				s390irq_spin_lock(irq);
-
-				/*
-				 * FIXME: is this neccessary?
-				 */
-				ccode = stsch(irq, &ioinfo[irq]->schib);
-				if (ccode) {
-#ifdef CONFIG_DEBUG_CRW
-					printk( KERN_WARNING 
-						"do_crw_pending: device on "
-						"sch %x is not operational\n",
-						irq);
-#endif /* CONFIG_DEBUG_CRW */
-					CIO_CRW_EVENT( 2,
-						       "device on sch %x is "
-						       "not operational\n",
-						       irq);
-					ioinfo[irq]->ui.flags.oper = 0;
+			int mask = 0x80 >> j;
+			int out = 0;
+			int err = 0;
+			
+			if (schib->pmcw.chpid[j] != chpid)
+				continue;
+			
+			if (stsch(irq, schib) != 0) {
+				ioinfo[irq]->ui.flags.oper = 0;
+				if (ioinfo[irq]->nopfunc)
+					ioinfo[irq]->nopfunc(irq, DEVSTAT_DEVICE_GONE);
+				break;
+			}
+			
+			s390irq_spin_lock(irq);
+			
+			ioinfo[irq]->ui.flags.noio = 1;
+			
+			/* Do we still expect an interrupt for outstanding io? */
+			if (ioinfo[irq]->ui.flags.busy) {
+				int rck = __check_for_io_and_kill(irq, mask, 1);
+				if (rck & CIO_PATHGONE_WAIT4INT)
+					out=1;
+				if (rck & CIO_PATHGONE_IOERR)
+					err=1;
+				if (rck & CIO_PATHGONE_DEVGONE)
 					break;
-				}
-
-				ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim &
-					ioinfo[irq]->schib.pmcw.pam &
-					ioinfo[irq]->schib.pmcw.pom;
-
-				if (ioinfo[irq]->opm) {
-					for (chp=0;chp<=7;chp++) {
-						mask2 = 0x80 >> chp;
-						if (ioinfo[irq]->opm & mask2) {
-							if (!test_bit
-							    (ioinfo[irq]->
-							     schib.pmcw.chpid[chp], 
-							     &chpids_logical)) {
-								/* disable using this path */
-								ioinfo[irq]->opm 
-									&= ~mask2;
-							}
-						}
-					}
-				}
+			}
+			
+			s390irq_spin_unlock(irq);
+			
+			/* Tell the device driver not to disturb us. */
+			if (ioinfo[irq]->ui.flags.ready &&
+			    schib->pmcw.pim != 0x80 &&
+			    ioinfo[irq]->nopfunc) {
+				if (err)
+					ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC_ERR);
+				else
+					ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC);
+			}
 
-				if (!ioinfo[irq]->opm) {
-					/*
-					 * sh*t, our last path has gone...
-					 * Set the device status to not operational
-					 * and eventually notify the device driver
-					 */
-#ifdef CONFIG_DEBUG_CRW
-					printk( KERN_WARNING 
-						"do_crw_pending: Last path gone for "
-						"device %x, sch %x\n",
-						ioinfo[irq]->devno, irq);
-#endif /* CONFIG_DEBUG_CRW */
-					CIO_CRW_EVENT( 2,
-						       "Last path gone for "
-						       "device %x, sch %x\n",
-						       ioinfo[irq]->devno,
-						       irq);
-					
-					was_oper = ioinfo[irq]->ui.flags.oper;
-					
-					ioinfo[irq]->ui.flags.oper = 0;
-					
-					if (was_oper && ioinfo[irq]->ui.flags.ready) {
-						
-						not_oper_handler_func_t nopfunc = 
-							ioinfo[irq]->nopfunc;
-#ifdef CONFIG_PROC_FS						
-						if (cio_proc_devinfo)
-							cio_procfs_device_remove
-								(ioinfo[irq]->devno);
-#endif /* CONFIG_PROC_FS */
-						free_irq(irq, 
-							 ioinfo[irq]->irq_desc.dev_id);
-						if (nopfunc)
-							nopfunc(irq, 
-								DEVSTAT_DEVICE_GONE);
-					}
-					
-				} else if (ioinfo[irq]->ui.flags.ready) {
-					/* 
-					 * Re-do path verification for the chpid in question
-					 * FIXME: is this neccessary?
-					 */
-					mask = 0x80 >> j;
+			ioinfo[irq]->opm &= ~mask;
+			
+			if (out)
+				break;
 
-					if (!s390_DevicePathVerification(irq,mask)) {
-#ifdef CONFIG_DEBUG_CRW
-						printk( KERN_DEBUG 
-							"DevicePathVerification "
-							"successful for"
-							" Subchannel %x, "
-							"chpid %x\n",
-							irq, chpid);
-#endif /* CONFIG_DEBUG_CRW */
-						CIO_CRW_EVENT( 2,
-							       "DevicePathVerification "
-							       "successful for"
-							       " Subchannel %x, "
-							       "chpid %x\n",
-							       irq, chpid);
-					}
-				}
-					
-				j=8;
-				s390irq_spin_unlock(irq);
+			/* 
+			 * Always schedule the path verification, even if opm=0.
+			 * Reason: We can't rely on stsch() to return latest&greatest
+			 * values, if a device selections hasn't been performed, and
+			 * we might miss a path we didn't get a mchk for.
+			 */
+			if (ioinfo[irq]->ui.flags.ready)
+				s390_schedule_path_verification(irq);
+			else {
+				ioinfo[irq]->ui.flags.noio = 0;
+				ioinfo[irq]->ui.flags.killio = 0;
 			}
-			
+			break;
 		}
 	}	
 }
@@ -7163,13 +7288,11 @@
 
 	char dbf_txt[15];
 	int irq = 0;
-	int ccode;
 	__u32 fla_mask = 0xffff;
 	int chp;
-	int mask, mask2;
-	int ret;
+	int mask;
 
-	sprintf(dbf_txt, "accp%x", chpid);
+	sprintf(dbf_txt, "accpr%x", chpid);
 	CIO_TRACE_EVENT( 2, dbf_txt);
 	if (info != CHSC_SEI_ACC_CHPID) {
 		sprintf(dbf_txt, "fla%x", fla);
@@ -7204,8 +7327,13 @@
 		return;
 	} 
 
-	if (!test_bit(chpid, &chpids_logical))
+	if (!test_bit(chpid, &chpids_logical)) {
+#ifdef CONFIG_DEBUG_CHSC
+		printk(KERN_DEBUG"chpid %x is logically offline, "
+		       "skipping res acc processing\n", chpid);
+#endif /* CONFIG_DEBUG_CHSC */
 		return; /* no need to do the rest */
+	}
 
 	switch (info) {
 	case CHSC_SEI_ACC_CHPID: /*
@@ -7216,62 +7344,13 @@
 		printk( KERN_DEBUG "Looking at chpid %x...\n", chpid);
 #endif /* CONFIG_DEBUG_CHSC */
 		
-		for (irq=0; irq<=__MAX_SUBCHANNELS; irq++) {
+		for (irq=0; irq<__MAX_SUBCHANNELS; irq++) {
 			
 			if((ioinfo[irq] != INVALID_STORAGE_AREA) 
-			   && (!ioinfo[irq]->st)) {
+			   && (ioinfo[irq]->st != 0))
+				continue;
 				
-				/*
-				 * Send nops down each path to find out
-				 * which path is there 
-				 */
-				
-				for (chp=0;chp<=7;chp++) {
-					mask = 0x80 >> chp;
-
-					/*
-					 * check if chpid is in information
-					 * updated by ssd
-					 */
-					if ((ioinfo[irq]->ssd_info.valid) &&
-					    (ioinfo[irq]->ssd_info.chpid[chp]
-					     == chpid))
-						ret = s390_send_nop (irq, mask);
-				}
-
-				ccode = stsch(irq, &ioinfo[irq]->schib);
-				if (!ccode) {
-
-					ioinfo[irq]->opm = 
-						ioinfo[irq]->schib.pmcw.pim &
-						ioinfo[irq]->schib.pmcw.pam &
-						ioinfo[irq]->schib.pmcw.pom;
-
-					if (ioinfo[irq]->opm) {
-						for (chp=0;chp<=7;chp++) {
-							mask = 0x80 >> chp;
-							if (ioinfo[irq]->opm 
-							    & mask) {
-								if (!test_bit
-								    (ioinfo[irq]->
-								     schib.pmcw.chpid[chp], 
-								     &chpids_logical)) {
-									/* disable using this path */
-									ioinfo[irq]->opm 
-										&= ~mask;
-								}
-							}
-						}
-					}
-
-					if ((ioinfo[irq]->ui.flags.ready) 
-					    && (chpid & ioinfo[irq]->opm))
-						s390_DevicePathVerification(irq, chpid);
-
-				} else {
-					ioinfo[irq]->ui.flags.oper = 0;
-				}
-			} else if (ioinfo[irq] == INVALID_STORAGE_AREA) {
+			if (ioinfo[irq] == INVALID_STORAGE_AREA) {
 				/*
 				 * We don't know the device yet, but since a path
 				 * may be available now to the device we'll have
@@ -7291,9 +7370,41 @@
 					highest_subchannel = irq;
 				if (valret == 0)
 					s390_device_recognition_irq(irq);
+				continue;
 			}
-		}
 
+			for (chp=0;chp<=7;chp++) {
+				mask = 0x80 >> chp;
+				
+				/*
+				 * check if chpid is in information
+				 * updated by ssd
+				 */
+				if ((!ioinfo[irq]->ssd_info.valid) ||
+				    (ioinfo[irq]->ssd_info.chpid[chp] != chpid))
+					continue;
+
+				/* Tell the device driver not to disturb us. */
+				if (ioinfo[irq]->ui.flags.ready &&
+				    ioinfo[irq]->schib.pmcw.pim != 0x80 &&
+				    ioinfo[irq]->nopfunc)
+					ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC);
+
+				ioinfo[irq]->ui.flags.noio = 1;
+
+				/* Do we still expect an interrupt for outstanding io? */
+				if (ioinfo[irq]->ui.flags.busy)
+					/* Wait for interrupt. */
+					break;
+
+				if (ioinfo[irq]->ui.flags.ready) {
+					s390_schedule_path_verification(irq);
+				} else
+					ioinfo[irq]->ui.flags.noio = 0;
+
+				break;
+			}
+		}
 		break;
 		
 	case CHSC_SEI_ACC_LINKADDR: /*
@@ -7313,8 +7424,8 @@
 			chpid, fla);
 #endif /* CONFIG_DEBUG_CHSC */
 		
-		for (irq=0; irq<=__MAX_SUBCHANNELS; irq++) {
-			
+		for (irq=0; irq<__MAX_SUBCHANNELS; irq++) {
+			int j;
 			/*
 			 * Walk through all subchannels and
 			 * look if our chpid and our (masked) link 
@@ -7322,52 +7433,7 @@
 			 * Do a stsch for the found subchannels and
 			 * perform path grouping  
 			 */
-			if ((ioinfo[irq] != INVALID_STORAGE_AREA) 
-			    && (!ioinfo[irq]->st)) {
-				int j;
-				
-				/* Update our ssd_info */
-				if (chsc_get_sch_desc_irq(irq)) 
-					break;
-				
-				for (j=0;j<8;j++) {
-					if ((ioinfo[irq]->ssd_info.chpid[j] == chpid) &&
-					    ((ioinfo[irq]->ssd_info.fla[j]&fla_mask) == fla)) {
-
-						mask2 = 0x80 >> j;
-						ret = s390_send_nop (irq, mask2);
-						
-						ccode = stsch(irq,&ioinfo[irq]->schib);
-						if (!ccode) {
-							ioinfo[irq]->opm = 
-								ioinfo[irq]->schib.pmcw.pim &
-								ioinfo[irq]->schib.pmcw.pam &
-								ioinfo[irq]->schib.pmcw.pom;
-
-							if (ioinfo[irq]->opm) {
-								for (chp=0;chp<=7;chp++) {
-									mask = 0x80 >> chp;
-									if (ioinfo[irq]->opm 
-									    & mask) {
-										if (!test_bit
-										    (ioinfo[irq]->
-										     schib.pmcw.chpid[chp], 
-										     &chpids_logical)) {
-											/* disable using this path */
-											ioinfo[irq]->opm 
-												&= ~mask;
-										}
-									}
-								}
-							}
-
-							if (ioinfo[irq]->ui.flags.ready)
-								s390_DevicePathVerification(irq, chpid);
-						}
-						break;
-					}
-				}
-			} else if (ioinfo[irq] == INVALID_STORAGE_AREA) {
+			if (ioinfo[irq] == INVALID_STORAGE_AREA) {
 				/* The full program again (see above), grr... */
 				int valret = 0;
 				
@@ -7380,10 +7446,43 @@
 					highest_subchannel = irq;
 				if (valret == 0)
 					s390_device_recognition_irq(irq);
+				continue;
+			}
+			if (ioinfo[irq]->st != 0)
+				continue;
+				
+			/* Update our ssd_info */
+			if (chsc_get_sch_desc_irq(irq)) 
+				break;
+			
+			for (j=0;j<8;j++) {
+				if ((ioinfo[irq]->ssd_info.chpid[j] != chpid) ||
+				    ((ioinfo[irq]->ssd_info.fla[j]&fla_mask) != fla))
+					continue;
+					
+				/* Tell the device driver not to disturb us. */
+				if (ioinfo[irq]->ui.flags.ready &&
+				    ioinfo[irq]->schib.pmcw.pim != 0x80 &&
+				    ioinfo[irq]->nopfunc)
+					ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC);
+
+				ioinfo[irq]->ui.flags.noio = 1;
+
+				/* Do we still expect an interrupt for outstanding io? */
+				if (ioinfo[irq]->ui.flags.busy)
+					/* Wait for interrupt. */
+					break;
+
+				if (ioinfo[irq]->ui.flags.ready) {
+					s390_schedule_path_verification(irq);
+				} else
+					ioinfo[irq]->ui.flags.noio = 0;
 				
+				break;
 			}
+			break;
+			
 		}
-		
 		break;
 
 	default: BUG();
@@ -7394,7 +7493,7 @@
 s390_process_css( void ) 
 {
 
-	int ccode;
+	int ccode, do_sei;
 
 	CIO_TRACE_EVENT( 2, "prcss");
 
@@ -7414,18 +7513,26 @@
 		return;
 	}
 
-	/* 
-	 * build the chsc request block for store event information 
-	 * and do the call 
-	 */
-	memset(chsc_area_sei,0,sizeof(chsc_area_t));
-	chsc_area_sei->request_block.command_code1=0x0010;
-	chsc_area_sei->request_block.command_code2=0x000E;
+	do_sei = 1;
 
-	ccode = chsc(chsc_area_sei);
+	while (do_sei) {
+		
+		do_sei = 0;
 
+		/* 
+		 * build the chsc request block for store event information 
+		 * and do the call 
+		 */
+		memset(chsc_area_sei,0,sizeof(chsc_area_t));
+		chsc_area_sei->request_block.command_code1=0x0010;
+		chsc_area_sei->request_block.command_code2=0x000E;
+		
+		ccode = chsc(chsc_area_sei);
+		
+		
+		if (ccode)
+			break;
 
-	if (!ccode) {
 		/* for debug purposes, check for problems */
 		if (chsc_area_sei->response_block.response_code == 0x0003) {
 #ifdef CONFIG_DEBUG_CHSC
@@ -7435,8 +7542,9 @@
 			CIO_CRW_EVENT( 2, 
 				       "s390_process_css: "
 				       "error in chsc request block!\n");
-
-		} else if (chsc_area_sei->response_block.response_code == 0x0005) {
+			break;
+		}
+		if (chsc_area_sei->response_block.response_code == 0x0005) {
 #ifdef CONFIG_DEBUG_CHSC
 			printk( KERN_WARNING 
 				"s390_process_css: no event information stored\n");
@@ -7444,8 +7552,9 @@
 			CIO_CRW_EVENT( 2, 
 				       "s390_process_css: "
 				       "no event information stored\n");
-
-		} else if (chsc_area_sei->response_block.response_code == 0x0002) {
+			break;
+		}
+		if (chsc_area_sei->response_block.response_code == 0x0002) {
 #ifdef CONFIG_DEBUG_CHSC
 			printk( KERN_WARNING
 				"s390_process_css: invalid command!\n");
@@ -7453,157 +7562,350 @@
 			CIO_CRW_EVENT( 2,
 				       "s390_process_css: "
 				       "invalid command!\n");
+			break;
+		}
+		if (chsc_area_sei->response_block.response_code != 0x0001) {
+#ifdef CONFIG_DEBUG_CHSC
+			printk( KERN_WARNING
+				"s390_process_css: unknown response code %d\n",
+				chsc_area_sei->response_block.response_code);
+#endif /* CONFIG_DEBUG_CHSC */
+			CIO_CRW_EVENT( 2,
+				       "s390_process_css: unknown response "
+				       "code %d\n",
+				       chsc_area_sei->response_block.response_code);
+			break;
+		}
+		/* everything ok */
+#ifdef CONFIG_DEBUG_CHSC
+		printk( KERN_DEBUG 
+			"s390_process_css: "
+			"event information successfully stored\n");
+#endif /* CONFIG_DEBUG_CHSC */
+		CIO_CRW_EVENT( 4, 
+			       "s390_process_css: "
+			       "event information successfully stored\n");
+					
+		/* Check if there is more event information pending. */
+		if (chsc_area_sei->response_block.response_block_data.
+		    sei_res.flags & 0x80) {
+#ifdef CONFIG_DEBUG_CHSC
+			printk(KERN_INFO"s390_process_css: further event "
+			       "information pending...\n");
+#endif /* CONFIG_DEBUG_CHSC */
+			CIO_CRW_EVENT( 2, "further event information pending\n");
 
-		} else if (chsc_area_sei->response_block.response_code == 0x0001) {
-			/* everything ok */
+			do_sei = 1;
+		}
+
+		/* Check if we might have lost some information. */
+		if (chsc_area_sei->response_block.response_block_data.
+		    sei_res.flags & 0x40) {
 #ifdef CONFIG_DEBUG_CHSC
-			printk( KERN_DEBUG 
+			printk(KERN_ERR"s390_process_css: Event information has "
+			       "been lost due to overflow!\n");
+#endif /* CONFIG_DEBUG_CHSC */
+			CIO_CRW_EVENT( 2, "Event information has "
+				       "been lost due to overflow!\n");
+		}
+		
+		if (chsc_area_sei->response_block.
+		    response_block_data.sei_res.rs != 4) {
+#ifdef CONFIG_DEBUG_CHSC
+			printk( KERN_ERR
 				"s390_process_css: "
-				"event information successfully stored\n");
+				"reporting source (%04X) isn't a chpid!\n",
+				chsc_area_sei->response_block.
+				response_block_data.sei_res.rsid);
 #endif /* CONFIG_DEBUG_CHSC */
-			CIO_CRW_EVENT( 4, 
+			CIO_CRW_EVENT( 2,
 				       "s390_process_css: "
-				       "event information successfully stored\n");
+				       "reporting source (%04X) isn't a chpid!\n",
+				       chsc_area_sei->response_block.
+				       response_block_data.sei_res.rsid);
+			continue;
+		}
 
-			if (chsc_area_sei->response_block.
-			    response_block_data.sei_res.rs != 4) {
+		/* which kind of information was stored? */
+		switch (chsc_area_sei->response_block.
+			response_block_data.sei_res.cc) {
+		case 1: /* link incident*/
 #ifdef CONFIG_DEBUG_CHSC
-				printk( KERN_ERR
-					"s390_process_css: "
-					"reporting source (%04X) isn't a chpid!"
-					"Aborting processing of machine check...\n",
-					chsc_area_sei->response_block.
-					response_block_data.sei_res.rsid);
+			printk( KERN_DEBUG 
+				"s390_process_css: "
+				"channel subsystem reports link incident,"
+				" source is chpid %x\n", 
+				chsc_area_sei->response_block.
+				response_block_data.sei_res.rsid);
 #endif /* CONFIG_DEBUG_CHSC */
-				CIO_CRW_EVENT( 2,
-					       "s390_process_css: "
-					       "reporting source (%04X) isn't a chpid!"
-					       "Aborting processing of machine check...\n",
-					       chsc_area_sei->response_block.
-					       response_block_data.sei_res.rsid);
-				return;
-			}
+			CIO_CRW_EVENT( 4,
+				       "s390_process_css: "
+				       "channel subsystem reports "
+				       "link incident, "
+				       "source is chpid %x\n", 
+				       chsc_area_sei->response_block.
+				       response_block_data.sei_res.rsid);
+			
+			s390_do_chpid_processing(chsc_area_sei->response_block.
+						 response_block_data.sei_res.rsid);
 			
-			/* which kind of information was stored? */
-			switch (chsc_area_sei->response_block.
-				response_block_data.sei_res.cc) {
-			case 1: /* link incident*/
+			break;
+			
+		case 2: /* i/o resource accessibiliy */
 #ifdef CONFIG_DEBUG_CHSC
-				printk( KERN_DEBUG 
-					"s390_process_css: "
-					"channel subsystem reports link incident,"
-					" source is chpid %x\n", 
-					chsc_area_sei->response_block.
-					response_block_data.sei_res.rsid);
+			printk( KERN_DEBUG 
+				"s390_process_css: channel subsystem "
+				"reports some I/O devices "
+				"may have become accessible\n");
 #endif /* CONFIG_DEBUG_CHSC */
-				CIO_CRW_EVENT( 4,
-					       "s390_process_css: "
-					       "channel subsystem reports "
-					       "link incident, "
-					       "source is chpid %x\n", 
-					       chsc_area_sei->response_block.
-					       response_block_data.sei_res.rsid);
-
-				s390_do_chpid_processing(chsc_area_sei->response_block.
-							 response_block_data.sei_res.rsid);
-							    
-				break;
-
-			case 2: /* i/o resource accessibiliy */
+			CIO_CRW_EVENT( 4,
+				       "s390_process_css: "
+				       "channel subsystem reports "
+				       "some I/O devices "
+				       "may have become accessible\n");
 #ifdef CONFIG_DEBUG_CHSC
-				printk( KERN_DEBUG 
-					"s390_process_css: channel subsystem "
-					"reports some I/O devices "
-					"may have become accessable\n");
+			printk( KERN_DEBUG 
+				"Data received after sei: \n");
+			printk( KERN_DEBUG 
+				"Validity flags: %x\n", 
+				chsc_area_sei->response_block.
+				response_block_data.sei_res.vf);
 #endif /* CONFIG_DEBUG_CHSC */
-				CIO_CRW_EVENT( 4,
-					       "s390_process_css: "
-					       "channel subsystem reports "
-					       "some I/O devices "
-					       "may have become accessable\n");
+			if ((chsc_area_sei->response_block.
+			     response_block_data.sei_res.vf&0x80)
+			    == 0) {
 #ifdef CONFIG_DEBUG_CHSC
-				printk( KERN_DEBUG 
-					"Data received after sei: \n");
-				printk( KERN_DEBUG 
-					"Validity flags: %x\n", 
-				       chsc_area_sei->response_block.
-					response_block_data.sei_res.vf);
+				printk( KERN_DEBUG "chpid: %x\n",
+					chsc_area_sei->response_block.
+					response_block_data.sei_res.rsid);
 #endif /* CONFIG_DEBUG_CHSC */
-				if ((chsc_area_sei->response_block.
-				    response_block_data.sei_res.vf&0x80)
-				    == 0) {
+				s390_do_res_acc_processing
+					(chsc_area_sei->response_block.
+					 response_block_data.sei_res.rsid,
+					 0,
+					 CHSC_SEI_ACC_CHPID);
+			} else if ((chsc_area_sei->response_block.
+				    response_block_data.sei_res.vf&0xc0)
+				   == 0x80) {
 #ifdef CONFIG_DEBUG_CHSC
-					printk( KERN_DEBUG "chpid: %x\n",
-						chsc_area_sei->response_block.
-						response_block_data.sei_res.rsid);
+				printk( KERN_DEBUG 
+					"chpid: %x  link addr: %x\n",
+					chsc_area_sei->response_block.
+					response_block_data.sei_res.rsid,
+					chsc_area_sei->response_block.
+					response_block_data.sei_res.fla);
 #endif /* CONFIG_DEBUG_CHSC */
-					s390_do_res_acc_processing
-						(chsc_area_sei->response_block.
-						 response_block_data.sei_res.rsid,
-						 0,
-						 CHSC_SEI_ACC_CHPID);
-				} else if ((chsc_area_sei->response_block.
-					   response_block_data.sei_res.vf&0xc0)
-					   == 0x80) {
+				s390_do_res_acc_processing
+					(chsc_area_sei->response_block.
+					 response_block_data.sei_res.rsid, 
+					 chsc_area_sei->response_block.
+					 response_block_data.sei_res.fla,
+					 CHSC_SEI_ACC_LINKADDR);
+			} else if ((chsc_area_sei->response_block.
+				    response_block_data.sei_res.vf & 0xc0)
+				   == 0xc0) {
 #ifdef CONFIG_DEBUG_CHSC
-					printk( KERN_DEBUG 
-						"chpid: %x  link addr: %x\n",
-						chsc_area_sei->response_block.
-						response_block_data.sei_res.rsid,
-						chsc_area_sei->response_block.
-						response_block_data.sei_res.fla);
+				printk( KERN_DEBUG 
+					"chpid: %x  "
+					"full link addr: %x\n",
+					chsc_area_sei->response_block.
+					response_block_data.sei_res.rsid,
+					chsc_area_sei->response_block.
+					response_block_data.sei_res.fla);
 #endif /* CONFIG_DEBUG_CHSC */
-					s390_do_res_acc_processing
-						(chsc_area_sei->response_block.
-						 response_block_data.sei_res.rsid, 
-						 chsc_area_sei->response_block.
-						 response_block_data.sei_res.fla,
-						 CHSC_SEI_ACC_LINKADDR);
-				} else if ((chsc_area_sei->response_block.
-					    response_block_data.sei_res.vf & 0xc0)
-					   == 0xc0) {
+				s390_do_res_acc_processing
+					(chsc_area_sei->response_block.
+					 response_block_data.sei_res.rsid, 
+					 chsc_area_sei->response_block.
+					 response_block_data.sei_res.fla,
+					 CHSC_SEI_ACC_FULLLINKADDR);
+			}
 #ifdef CONFIG_DEBUG_CHSC
-					printk( KERN_DEBUG 
-						"chpid: %x  "
-						"full link addr: %x\n",
-						chsc_area_sei->response_block.
-						response_block_data.sei_res.rsid,
-						chsc_area_sei->response_block.
-						response_block_data.sei_res.fla);
+			printk( KERN_DEBUG "\n");
 #endif /* CONFIG_DEBUG_CHSC */
-					s390_do_res_acc_processing
-						(chsc_area_sei->response_block.
-						 response_block_data.sei_res.rsid, 
-						 chsc_area_sei->response_block.
-						 response_block_data.sei_res.fla,
-						 CHSC_SEI_ACC_FULLLINKADDR);
-				}
+			
+			break;
+			
+		default: /* other stuff */
 #ifdef CONFIG_DEBUG_CHSC
-				printk( KERN_DEBUG "\n");
+			printk( KERN_DEBUG 
+				"s390_process_css: event %d\n",
+				chsc_area_sei->response_block.
+				response_block_data.sei_res.cc);
 #endif /* CONFIG_DEBUG_CHSC */
+			CIO_CRW_EVENT( 4, 
+				       "s390_process_css: event %d\n",
+				       chsc_area_sei->response_block.
+				       response_block_data.sei_res.cc);
+			
+			break;
+			
+		}
+	}
+		
+	spin_unlock(&chsc_lock_sei);
+}
+#endif
 
+static void
+__process_chp_gone(int irq, int chpid)
+{
+	schib_t *schib = &ioinfo[irq]->schib;
+	int i;
+	
+	for (i=0;i<8;i++) {
+		int mask = 0x80>>i;
+		int out = 0;
+		int err = 0;
+		
+		if (schib->pmcw.chpid[i] != chpid)
+			continue;
+		
+		if (stsch(irq, schib) != 0) {
+			ioinfo[irq]->ui.flags.oper = 0;
+			if (ioinfo[irq]->nopfunc)
+				ioinfo[irq]->nopfunc(irq, DEVSTAT_DEVICE_GONE);
+			break;
+		}
+		
+		s390irq_spin_lock(irq);
+		
+		ioinfo[irq]->ui.flags.noio = 1;
+		
+		/* Do we still expect an interrupt for outstanding io? */
+		if (ioinfo[irq]->ui.flags.busy) {
+			int rck = __check_for_io_and_kill(irq, mask, 1);
+			if (rck & CIO_PATHGONE_WAIT4INT)
+				out=1;
+			if (rck & CIO_PATHGONE_IOERR)
+				err=1;
+			if (rck & CIO_PATHGONE_DEVGONE)
 				break;
+		}
+		
+		s390irq_spin_unlock(irq);
 
-			default: /* other stuff */
-#ifdef CONFIG_DEBUG_CHSC
-				printk( KERN_DEBUG 
-					"s390_process_css: event %d\n",
-					chsc_area_sei->response_block.
-					response_block_data.sei_res.cc);
-#endif /* CONFIG_DEBUG_CHSC */
-				CIO_CRW_EVENT( 4, 
-					       "s390_process_css: event %d\n",
-					       chsc_area_sei->response_block.
-					       response_block_data.sei_res.cc);
+		/* Tell the device driver not to disturb us. */
+		if (ioinfo[irq]->ui.flags.ready &&
+		    schib->pmcw.pim != 0x80 &&
+		    ioinfo[irq]->nopfunc) {
+			if (err)
+				ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC_ERR);
+			else
+				ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC);
+		}
+		
+		if (out)
+			break;
+		
+		if (ioinfo[irq]->ui.flags.ready) {
+			s390_schedule_path_verification(irq);
+		} else {
+			ioinfo[irq]->ui.flags.noio = 0;
+			ioinfo[irq]->ui.flags.killio = 0;
+		}
+		break;
+	}
 
-				break;
+}
 
-			}
+static void
+__process_chp_come(int irq, int chpid)
+{
+	schib_t *schib = &ioinfo[irq]->schib;
+	int i;
+
+	for (i=0;i<8;i++) {
+
+		if (schib->pmcw.chpid[i] != chpid)
+			continue;
+		
+		/* Tell the device driver not to disturb us. */
+		if (ioinfo[irq]->ui.flags.ready &&
+		    schib->pmcw.pim != 0x80 &&
+		    ioinfo[irq]->nopfunc)
+			ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC);
+		
+		ioinfo[irq]->ui.flags.noio = 1;
+		
+		/* Do we still expect an interrupt for outstanding io? */
+		if (ioinfo[irq]->ui.flags.busy)
+			/* Wait for interrupt. */
+			break;
+		
+		if (ioinfo[irq]->ui.flags.ready)
+			s390_schedule_path_verification(irq);
+		else
+			ioinfo[irq]->ui.flags.noio = 0;
+		
+		break;
+	}
+}
+
+static void
+s390_process_chp_source(int chpid, int onoff)
+{
+	int irq;
+	int ret;
+	char dbf_txt[15];
+
+	sprintf(dbf_txt, "prchp%x", chpid);
+	CIO_TRACE_EVENT(2, dbf_txt);
+
+#ifdef CONFIG_CHSC
+	if (onoff == 0) {
+		clear_bit(chpid, &chpids);
+	} else {
+		set_bit(chpid, &chpids);
+		set_bit(chpid, &chpids_known);
+	}
+#endif /* CONFIG_CHSC */
+
+	if (onoff == 0) {
+		for (irq=0;irq<=highest_subchannel;irq++) {
+
+			if ((ioinfo[irq] == INVALID_STORAGE_AREA)
+			    || (ioinfo[irq]->st != 0))
+				continue;
+
+			__process_chp_gone(irq, chpid);
 		}
+		return;
 	}
-	spin_unlock(&chsc_lock_sei);
+
+	for (irq=0;irq<__MAX_SUBCHANNELS;irq++) {
+		
+		if (ioinfo[irq] == INVALID_STORAGE_AREA) {
+			ret = s390_validate_subchannel(irq,0);
+			if (ret == 0) {
+				if (irq > highest_subchannel)
+					highest_subchannel = irq;
+#ifdef CONFIG_DEBUG_CRW
+				printk(KERN_DEBUG"process_chp_source: Found "
+				       "device on irq %x\n", irq);
+#endif /* CONFIG_DEBUG_CRW */
+				CIO_CRW_EVENT(4, "Found device on irq %x\n",
+					      irq);
+				s390_device_recognition_irq(irq);
+			}
+		} else if (ioinfo[irq]->st == 0) {
+			ret = stsch(irq, &ioinfo[irq]->schib);
+			if (ret != 0)
+				ret = -ENXIO;
+		} else
+			continue;
+
+		if (ret == -ENXIO)
+			/* We're through. */
+			return;
+
+		if (ret != 0)
+			continue;
+		
+		__process_chp_come(irq, chpid);
+	}
+
 }
-#endif
 
 /*
  * s390_do_crw_pending
@@ -7657,7 +7959,24 @@
 			printk (KERN_NOTICE "do_crw_pending : source is "
 				"channel path %02X\n", chpid);
 #endif
-			CIO_CRW_EVENT(2, "source is channel path %02X\n");
+			CIO_CRW_EVENT(2, "source is channel path %02X\n",
+				      chpid);
+			switch (pcrwe->crw.erc) {
+			case CRW_ERC_IPARM: /* Path has come. */
+				s390_process_chp_source(chpid, 1);
+				break;
+			case CRW_ERC_PERRI: /* Path has gone. */
+				s390_process_chp_source(chpid, 0);
+				break;
+			default:
+#ifdef CONFIG_DEBUG_CRW
+				printk(KERN_WARNING"do_crw_pending: don't "
+				       "know how to handle erc=%x\n",
+				       pcrwe->crw.erc);
+#endif /* CONFIG_DEBUG_CRW */
+				CIO_CRW_EVENT(0, "don't know how to handle "
+					      "erc=%x\n", pcrwe->crw.erc);
+			}
 			break;
 
 		case CRW_RSC_CONFIG:
@@ -7850,6 +8169,84 @@
 	}
 }
 
+static void
+__vary_chpid_offline(int irq, int chpid)
+{
+	schib_t *schib = &ioinfo[irq]->schib;
+	int i;
+	
+	for (i=0;i<8;i++) {
+		int mask = 0x80>>i;
+		int out = 0;
+		unsigned long flags;
+		
+		if (ioinfo[irq]->ssd_info.chpid[i] != chpid)
+			continue;
+		
+		s390irq_spin_lock_irqsave(irq, flags);
+		
+		ioinfo[irq]->ui.flags.noio = 1;
+		
+		/* Hmm, the path is not really gone... */
+		if (ioinfo[irq]->ui.flags.busy) {
+			if (__check_for_io_and_kill(irq, mask, 0) != 0)
+				out=1;
+		}
+		
+		s390irq_spin_unlock_irqrestore(irq, flags);
+
+		/* Tell the device driver not to disturb us. */
+		if (ioinfo[irq]->ui.flags.ready &&
+		    schib->pmcw.pim != 0x80 &&
+		    ioinfo[irq]->nopfunc)
+			ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC);
+		
+		if (out)
+			break;
+		
+		if (ioinfo[irq]->ui.flags.ready)
+			s390_schedule_path_verification(irq);
+		else
+			ioinfo[irq]->ui.flags.noio = 0;
+
+		break;
+	}
+
+}
+
+static void
+__vary_chpid_online(int irq, int chpid)
+{
+	schib_t *schib = &ioinfo[irq]->schib;
+	int i;
+
+	for (i=0;i<8;i++) {
+
+		if (schib->pmcw.chpid[i] != chpid)
+			continue;
+		
+		/* Tell the device driver not to disturb us. */
+		if (ioinfo[irq]->ui.flags.ready &&
+		    schib->pmcw.pim != 0x80 &&
+		    ioinfo[irq]->nopfunc)
+			ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC);
+		
+		ioinfo[irq]->ui.flags.noio = 1;
+		
+		/* Do we still expect an interrupt for outstanding io? */
+		if (ioinfo[irq]->ui.flags.busy)
+			/* Wait for interrupt. */
+			break;
+		
+		if (ioinfo[irq]->ui.flags.ready)
+			s390_schedule_path_verification(irq);
+		else
+			ioinfo[irq]->ui.flags.noio = 0;
+		
+		break;
+	}
+}
+
 
 /*
  * Function: s390_vary_chpid
@@ -7899,34 +8296,20 @@
 	
 	for (irq=0;irq<=highest_subchannel;irq++) {
 
-		/* 
-		 * We don't need to adjust the opm, as this will be done in
-		 * DevicePathVerification...
-		 */
-
 		if (ioinfo[irq] == INVALID_STORAGE_AREA)
 			continue;
 
 		if (ioinfo[irq]->st)
 			continue;
+		
+		if (!ioinfo[irq]->ssd_info.valid)
+			continue;
+
+		if (on)
+			__vary_chpid_online(irq, chpid);
+		else
+			__vary_chpid_offline(irq, chpid);
 
-		if (ioinfo[irq]->ssd_info.valid) {
-			if ((ioinfo[irq]->ssd_info.chpid[0] == chpid) ||
-			    (ioinfo[irq]->ssd_info.chpid[1] == chpid) ||
-			    (ioinfo[irq]->ssd_info.chpid[2] == chpid) ||
-			    (ioinfo[irq]->ssd_info.chpid[3] == chpid) ||
-			    (ioinfo[irq]->ssd_info.chpid[4] == chpid) ||
-			    (ioinfo[irq]->ssd_info.chpid[5] == chpid) ||
-			    (ioinfo[irq]->ssd_info.chpid[6] == chpid) ||
-			    (ioinfo[irq]->ssd_info.chpid[7] == chpid)) {
-#ifdef CONFIG_DEBUG_CHSC
-				printk(KERN_DEBUG "Calling "
-				       "DevicePathVerification for irq %d\n", 
-				       irq);
-#endif /* CONFIG_DEBUG_CHSC */
-				s390_DevicePathVerification(irq, 0);
-			}
-		}
 	}
 
 	return 0;
@@ -8613,7 +8996,7 @@
 		user_len = 65536;
 	
 	buffer = vmalloc (user_len + 1);
-	
+
 	if (buffer == NULL)
 		return -ENOMEM;
 	if (copy_from_user (buffer, user_buf, user_len)) {
@@ -8624,9 +9007,6 @@
 #ifdef CONFIG_DEBUG_IO
 	printk (KERN_DEBUG "/proc/cio_ignore: '%s'\n", buffer);
 #endif /* CONFIG_DEBUG_IO */
-	if (cio_debug_initialized)
-		debug_sprintf_event (cio_debug_msg_id, 2,
-				     "/proc/cio_ignore: '%s'\n", buffer);
 
 	blacklist_parse_proc_parameters (buffer);
 
@@ -8795,19 +9175,28 @@
 			chsc_get_sch_descriptions();
 			if (!cio_chsc_desc_avail) {
 				len += sprintf(info->data+len, "no info available\n");
-			} else {
-				for (i=0;i<NR_CHPIDS;i++) {
-					if ((test_bit(i, &chpids)) && 
-					    test_bit(i, &chpids_logical))
+				goto cont;
+			}
+
+			for (i=0;i<NR_CHPIDS;i++) {
+				if (test_bit(i, &chpids_known)) {
+					if (!test_bit(i, &chpids))
+						len += sprintf(info->data+len,
+							       "%02X n/a\n",
+							       i);
+					else if (test_bit(i, &chpids_logical))
 						len += sprintf(info->data+len, 
 							       "%02X online\n", 
 							       i);
-					else if (test_bit(i, &chpids_known))
+					else 
 						len += sprintf(info->data+len, 
-							       "%02X logically offline\n", 
+							       "%02X logically "
+							       "offline\n", 
 							       i);
 				}
+
 			}
+		cont:
 			info->len = len;
 		}
 	}
@@ -8940,6 +9329,7 @@
 EXPORT_SYMBOL (do_IO);
 EXPORT_SYMBOL (resume_IO);
 EXPORT_SYMBOL (ioinfo);
+EXPORT_SYMBOL (diag210);
 EXPORT_SYMBOL (get_dev_info_by_irq);
 EXPORT_SYMBOL (get_dev_info_by_devno);
 EXPORT_SYMBOL (get_irq_by_devno);
diff -urN linux-2.4.22-pre2/drivers/s390/s390mach.c linux-2.4.22-pre3/drivers/s390/s390mach.c
--- linux-2.4.22-pre2/drivers/s390/s390mach.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/s390/s390mach.c	2003-07-05 18:10:30.000000000 -0700
@@ -121,7 +121,7 @@
 #if 1
   	ctl_set_bit( 14, 28 );		// enable channel report MCH
 #endif
-#ifdef CONFIG_MACHCK_WARNING
+#ifdef CONFIG_MACHCHK_WARNING
 	ctl_set_bit( 14, 24);   /* enable warning MCH */
 #endif
 
@@ -152,7 +152,6 @@
 	return;
 }
 
-
 /*
  * s390_do_machine_check
  *
@@ -327,6 +326,16 @@
 			} /* endif */
 #endif
 
+#ifdef CONFIG_MACHCHK_WARNING
+			if ( pmache->mcic.mcc.mcd.w )
+			{
+				ctrl_alt_del();		// shutdown NOW!
+#ifdef S390_MACHCHK_DEBUG
+			printk( KERN_DEBUG "mach_handler : kill -SIGPWR init\n");
+#endif
+			} /* endif */
+#endif
+
 			s390_enqueue_free_mchchk( pmache );
 		}
 		else
@@ -655,4 +664,3 @@
 	return ( 1 );
 }
 #endif
-
diff -urN linux-2.4.22-pre2/drivers/scsi/README.st linux-2.4.22-pre3/drivers/scsi/README.st
--- linux-2.4.22-pre2/drivers/scsi/README.st	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/README.st	2003-07-05 18:10:30.000000000 -0700
@@ -1,8 +1,8 @@
 This file contains brief information about the SCSI tape driver.
 The driver is currently maintained by Kai Mäkisara (email
-Kai.Makisara@metla.fi)
+Kai.Makisara@kolumbus.fi)
 
-Last modified: Tue Apr 16 22:32:10 2002 by makisara
+Last modified: Sun Apr  6 22:44:55 2003 by makisara
 
 
 BASICS
@@ -112,7 +112,7 @@
 
 Asynchronous writing. Writing the buffer contents to the tape is
 started and the write call returns immediately. The status is checked
-at the next tape operation.
+at the next tape operation. Applies only to variable block mode.
 
 Buffered writes and asynchronous writes may in some rare cases cause
 problems in multivolume operations if there is not enough space on the
@@ -147,11 +147,6 @@
 supports scatter/gather (the allocation is not limited to "DMA memory"
 and the buffer can be composed of several fragments).
 
-The threshold for triggering asynchronous write in fixed block mode
-is defined by ST_WRITE_THRESHOLD. This may be optimized for each
-use pattern. The default triggers asynchronous write after three
-default sized writes (10 kB) from tar.
-
 Scatter/gather buffers (buffers that consist of chunks non-contiguous
 in the physical memory) are used if contiguous buffers can't be
 allocated. To support all SCSI adapters (including those not
@@ -184,7 +179,6 @@
 are configurable when the driver is loaded as a module. The keywords are:
 
 buffer_kbs=xxx             the buffer size in kilobytes is set to xxx
-write_threshold_kbs=xxx    the write threshold in kilobytes set to xxx
 max_buffers=xxx            the maximum number of tape buffer set to xxx
 max_sg_segs=xxx		   the maximum number of scatter/gather
 			   segments
@@ -213,7 +207,7 @@
 
 where
   aa is the buffer size in 1024 byte units
-  bb is the write threshold in 1024 byte units
+  bb is the write threshold in 1024 byte units (not used any more)
   cc is the maximum number of tape buffers to allocate (the number of
         buffers is bounded also by the number of drives detected)
   dd is the maximum number of scatter/gather segments
@@ -321,9 +315,6 @@
 	MT_ST_SETBOOLEANS
 	MT_ST_CLEARBOOLEANS
 	   Sets or clears the option bits.
-        MT_ST_WRITE_THRESHOLD
-           Sets the write threshold for this device to kilobytes
-           specified by the lowest bits.
 	MT_ST_DEF_BLKSIZE
 	   Defines the default block size set automatically. Value
 	   0xffffff means that the default is not used any more.
diff -urN linux-2.4.22-pre2/drivers/scsi/aacraid/README linux-2.4.22-pre3/drivers/scsi/aacraid/README
--- linux-2.4.22-pre2/drivers/scsi/aacraid/README	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/aacraid/README	2003-07-05 18:10:30.000000000 -0700
@@ -18,6 +18,12 @@
 	ADAPTEC 2120S
 	ADAPTEC 2200S
 	ADAPTEC 5400S
+	Legend S220
+	Legend S230
+	Adaptec 3230S
+	Adaptec 3240S
+	ASR-2020S PCI-X
+	AAR-2410SA SATA
 
 People
 -------------------------
@@ -28,15 +34,22 @@
 					 added new ioctls, changed scsi interface to use new error handler,
 					 increased the number of fibs and outstanding commands to a container)
 
+					(fixed 64bit and 64G memory model, changed confusing naming convention
+					 where fibs that go to the hardware are consistently called hw_fibs and
+					 not just fibs like the name of the driver tracking structure)
+Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas.
+
 Original Driver
 -------------------------
 Adaptec Unix OEM Product Group
 
 Mailing List
 -------------------------
-None currently. Also note this is very different to Brian's original driver
+linux-aacraid-devel@dell.com (Interested parties troll here)
+http://mbserver.adaptec.com/ (Currently more Community Support than Devel Support)
+Also note this is very different to Brian's original driver
 so don't expect him to support it.
-Adaptec does support this driver.  Contact either tech support or deanna bonds.
+Adaptec does support this driver.  Contact either tech support or Mark Salyzyn.
 
 Original by Brian Boerner February 2001
 Rewritten by Alan Cox, November 2001
diff -urN linux-2.4.22-pre2/drivers/scsi/aacraid/TODO linux-2.4.22-pre3/drivers/scsi/aacraid/TODO
--- linux-2.4.22-pre2/drivers/scsi/aacraid/TODO	2001-12-21 09:41:55.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/aacraid/TODO	2003-07-05 18:10:30.000000000 -0700
@@ -2,3 +2,4 @@
 o	More testing
 o	Feature request: display the firmware/bios/etc revisions in the
 	/proc info
+o	2.5.0 and beyond.
diff -urN linux-2.4.22-pre2/drivers/scsi/aacraid/aachba.c linux-2.4.22-pre3/drivers/scsi/aacraid/aachba.c
--- linux-2.4.22-pre2/drivers/scsi/aacraid/aachba.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/scsi/aacraid/aachba.c	2003-07-05 18:10:30.000000000 -0700
@@ -23,6 +23,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -224,6 +225,15 @@
 static char *aac_get_status_string(u32 status);
 #endif
 
+/*
+ *	Non dasd selection is handled entirely in aachba now
+ */	
+ 
+MODULE_PARM(nondasd, "i");
+MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
+
+static int nondasd = -1;
+
 /**
  *	aac_get_containers	-	list containers
  *	@common: adapter to probe
@@ -261,13 +271,14 @@
 				    1, 1,
 				    NULL, NULL);
 		if (status < 0 ) {
-			printk(KERN_WARNING "ProbeContainers: SendFIB failed.\n");
+			printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n");
 			break;
 		}
 		dresp = (struct aac_mount *)fib_data(fibptr);
 
 		if ((le32_to_cpu(dresp->status) == ST_OK) &&
-		    (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
+		    (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
+		    (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
 			fsa_dev_ptr->valid[index] = 1;
 			fsa_dev_ptr->type[index] = le32_to_cpu(dresp->mnt[0].vol);
 			fsa_dev_ptr->size[index] = le32_to_cpu(dresp->mnt[0].capacity);
@@ -332,7 +343,8 @@
 	dresp = (struct aac_mount *) fib_data(fibptr);
 
 	if ((le32_to_cpu(dresp->status) == ST_OK) &&
-	    (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
+	    (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
+	    (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
 		fsa_dev_ptr->valid[cid] = 1;
 		fsa_dev_ptr->type[cid] = le32_to_cpu(dresp->mnt[0].vol);
 		fsa_dev_ptr->size[cid] = le32_to_cpu(dresp->mnt[0].capacity);
@@ -520,22 +532,54 @@
 			dev->name, dev->id,
 			dev->adapter_info.serial[0],
 			dev->adapter_info.serial[1]);
-	dev->pae_support = 0;
+
 	dev->nondasd_support = 0;
-	if( BITS_PER_LONG >= 64 && 
-	  (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
-		printk(KERN_INFO "%s%d: 64 Bit PAE enabled\n", dev->name, dev->id);
+	dev->raid_scsi_mode = 0;
+	if(dev->adapter_info.options & AAC_OPT_NONDASD){
+		dev->nondasd_support = 1;
+	}
+
+	/*
+	 * If the firmware supports ROMB RAID/SCSI mode and we are currently
+	 * in RAID/SCSI mode, set the flag. For now if in this mode we will
+	 * force nondasd support on. If we decide to allow the non-dasd flag
+	 * additional changes changes will have to be made to support
+	 * RAID/SCSI.  the function aac_scsi_cmd in this module will have to be
+	 * changed to support the new dev->raid_scsi_mode flag instead of
+	 * leaching off of the dev->nondasd_support flag. Also in linit.c the
+	 * function aac_detect will have to be modified where it sets up the
+	 * max number of channels based on the aac->nondasd_support flag only.
+	 */
+	if ((dev->adapter_info.options & AAC_OPT_SCSI_MANAGED)
+		&& (dev->adapter_info.options & AAC_OPT_RAID_SCSI_MODE))
+	{
+		dev->nondasd_support = 1;
+		dev->raid_scsi_mode = 1;
+	}
+	if (dev->raid_scsi_mode != 0)
+		printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n",dev->name, dev->id);
+		
+	if (nondasd != -1)
+		dev->nondasd_support = (nondasd!=0);
+
+	if(dev->nondasd_support != 0)
+		printk(KERN_INFO "%s%d: Non-DASD support enabled\n",dev->name, dev->id);
+
+	dev->pae_support = 0;
+	if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
 		dev->pae_support = 1;
 	}
 	/* TODO - dmb temporary until fw can set this bit  */
 	dev->pae_support = (BITS_PER_LONG >= 64);
-	if(dev->pae_support != 0) {
+	if(dev->pae_support != 0) 
+	{
 		printk(KERN_INFO "%s%d: 64 Bit PAE enabled\n", dev->name, dev->id);
+		pci_set_dma_mask(dev->pdev, (dma_addr_t)0xFFFFFFFFFFFFFFFFULL);
 	}
 
-	if(dev->adapter_info.options & AAC_OPT_NONDASD){
-		dev->nondasd_support = 1;
-	}
+	fib_complete(fibptr);
+	fib_free(fibptr);
+
 	return rcode;
 }
 
@@ -554,7 +598,7 @@
 	cid =TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);
 
 	lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
-	dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %d, t = %ld.\n", smp_processor_id(), lba, jiffies));
+	dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));
 
 	if (fibptr == NULL)
 		BUG();
@@ -599,7 +643,7 @@
 	cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);
 
 	lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
-	dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %d, t = %ld.\n", smp_processor_id(), lba, jiffies));
+	dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));
 	if (fibptr == NULL)
 		BUG();
 
@@ -765,7 +809,7 @@
 		lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
 		count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
 	}
-	dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %lu, t = %ld.\n", smp_processor_id(), lba, jiffies));
+	dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));
 	/*
 	 *	Allocate and initialize a Fib then setup a BlockWrite command
 	 */
@@ -1261,17 +1305,29 @@
 	/*
 	 * Next check the srb status
 	 */
-	switch(le32_to_cpu(srbreply->srb_status)){
+	switch( (le32_to_cpu(srbreply->srb_status))&0x3f){
 	case SRB_STATUS_ERROR_RECOVERY:
 	case SRB_STATUS_PENDING:
 	case SRB_STATUS_SUCCESS:
 		if(scsicmd->cmnd[0] == INQUIRY ){
 			u8 b;
+			u8 b1;
 			/* We can't expose disk devices because we can't tell whether they
-			 * are the raw container drives or stand alone drives
+			 * are the raw container drives or stand alone drives.  If they have
+			 * the removable bit set then we should expose them though.
 			 */
-			b = *(u8*)scsicmd->buffer;
-			if( (b & 0x0f) == TYPE_DISK ){
+			b = (*(u8*)scsicmd->buffer)&0x1f;
+			b1 = ((u8*)scsicmd->buffer)[1];
+			if( b==TYPE_TAPE || b==TYPE_WORM || b==TYPE_ROM || b==TYPE_MOD|| b==TYPE_MEDIUM_CHANGER 
+					|| (b==TYPE_DISK && (b1&0x80)) ){
+				scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+			/*
+			 * We will allow disk devices if in RAID/SCSI mode and
+			 * the channel is 2
+			 */
+			} else if((dev->raid_scsi_mode)&&(scsicmd->channel == 2)){
+				scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+			} else {
 				scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
 			}
 		} else {
@@ -1293,6 +1349,28 @@
 			}
 			scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
 			break;
+		case INQUIRY: {
+			u8 b;
+			u8 b1;
+			/* We can't expose disk devices because we can't tell whether they
+			* are the raw container drives or stand alone drives
+			*/
+			b = (*(u8*)scsicmd->buffer)&0x0f;
+			b1 = ((u8*)scsicmd->buffer)[1];
+			if( b==TYPE_TAPE || b==TYPE_WORM || b==TYPE_ROM || b==TYPE_MOD|| b==TYPE_MEDIUM_CHANGER
+					|| (b==TYPE_DISK && (b1&0x80)) ){
+				scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+			/*
+			 * We will allow disk devices if in RAID/SCSI mode and
+			 * the channel is 2
+			 */
+			} else if((dev->raid_scsi_mode)&&(scsicmd->channel == 2)){
+				scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+			} else {
+				scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
+			}
+			break;
+		}
 		default:
 			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
 			break;
@@ -1348,13 +1426,14 @@
 	case SRB_STATUS_DOMAIN_VALIDATION_FAIL:
 	default:
 #ifdef AAC_DETAILED_STATUS_INFO
-		printk("aacraid: SRB ERROR (%s)\n",aac_get_status_string(le32_to_cpu(srbreply->srb_status)));
+		printk("aacraid: SRB ERROR(%u) %s scsi cmd 0x%x - scsi status 0x%x\n",le32_to_cpu(srbreply->srb_status&0x3f),aac_get_status_string(le32_to_cpu(srbreply->srb_status)), scsicmd->cmnd[0], le32_to_cpu(srbreply->scsi_status) );
 #endif
 		scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
 		break;
 	}
 	if (le32_to_cpu(srbreply->scsi_status) == 0x02 ){  // Check Condition
 		int len;
+		scsicmd->result |= CHECK_CONDITION;
 		len = (srbreply->sense_data_size > sizeof(scsicmd->sense_buffer))?
 				sizeof(scsicmd->sense_buffer):srbreply->sense_data_size;
 		printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n", le32_to_cpu(srbreply->status), len);
@@ -1387,6 +1466,7 @@
 	struct aac_srb *srbcmd;
 	u16 fibsize;
 	u32 flag;
+	u32 timeout;
 
 	if( scsicmd->target > 15 || scsicmd->lun > 7) {
 		scsicmd->result = DID_NO_CONNECT << 16;
@@ -1428,7 +1508,11 @@
 	srbcmd->target   = cpu_to_le32(scsicmd->target);
 	srbcmd->lun      = cpu_to_le32(scsicmd->lun);
 	srbcmd->flags    = cpu_to_le32(flag);
-	srbcmd->timeout  = cpu_to_le32(0);  // timeout not used
+	timeout = (scsicmd->timeout-jiffies)/HZ;
+	if(timeout == 0){
+		timeout = 1;
+	}
+	srbcmd->timeout  = cpu_to_le32(timeout);  // timeout in seconds
 	srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter
 	srbcmd->cdb_size = cpu_to_le32(scsicmd->cmd_len);
 	
@@ -1533,6 +1617,7 @@
 		psg->count = cpu_to_le32(1);
 		psg->sg[0].addr = cpu_to_le32(addr);
 		psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  
+		/* Cast to pointer from integer of different size */
 		scsicmd->SCp.ptr = (void *)addr;
 		byte_count = scsicmd->request_bufflen;
 	}
@@ -1594,6 +1679,7 @@
 		psg->sg[0].addr[1] = (u32)(le_addr>>32);
 		psg->sg[0].addr[0] = (u32)(le_addr & 0xffffffff);
 		psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  
+		/* Cast to pointer from integer of different size */
 		scsicmd->SCp.ptr = (void *)addr;
 		byte_count = scsicmd->request_bufflen;
 	}
diff -urN linux-2.4.22-pre2/drivers/scsi/aacraid/aacraid.h linux-2.4.22-pre3/drivers/scsi/aacraid/aacraid.h
--- linux-2.4.22-pre2/drivers/scsi/aacraid/aacraid.h	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/aacraid/aacraid.h	2003-07-05 18:10:30.000000000 -0700
@@ -1,5 +1,7 @@
-#define dprintk(x)
-/*#define dprintk(x) printk x */
+//#define dprintk(x) printk x
+#if (!defined(dprintk))
+# define dprintk(x)
+#endif
 
 /*------------------------------------------------------------------------------
  *              D E F I N E S
@@ -8,12 +10,13 @@
 #define MAXIMUM_NUM_CONTAINERS	31
 #define MAXIMUM_NUM_ADAPTERS	8
 
-#define AAC_NUM_FIB	578
-#define AAC_NUM_IO_FIB	512
+#define AAC_NUM_FIB		578
+//#define AAC_NUM_IO_FIB	512
+#define AAC_NUM_IO_FIB		100
 
-#define AAC_MAX_TARGET (MAXIMUM_NUM_CONTAINERS+1)
+#define AAC_MAX_TARGET		(MAXIMUM_NUM_CONTAINERS+1)
 //#define AAC_MAX_TARGET 	(16)
-#define AAC_MAX_LUN	(8)
+#define AAC_MAX_LUN		(8)
 
 /*
  * These macros convert from physical channels to virtual channels
@@ -269,11 +272,11 @@
 		    u32 _ReceiverTimeStart; 	// Timestamp for receipt of fib
 		    u32 _ReceiverTimeDone;	// Timestamp for completion of fib
 		} _s;
-		struct list_head _FibLinks;	// Used to link Adapter Initiated Fibs on the host
+//		struct aac_list_head _FibLinks;	// Used to link Adapter Initiated Fibs on the host
 	} _u;
 };
 
-#define FibLinks			_u._FibLinks
+//#define FibLinks			_u._FibLinks
 
 #define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(struct aac_fibhdr))
 
@@ -438,6 +441,8 @@
 	char *	vname;
 	char *	model;
 	u16	channels;
+	int	quirks;
+#define AAC_QUIRK_31BIT			1
 };
 
 /*
@@ -629,7 +634,7 @@
 	struct semaphore 	wait_sem;	// this is used to wait for the next fib to arrive.
 	int			wait;		// Set to true when thread is in WaitForSingleObject
 	unsigned long		count;		// total number of FIBs on FibList
-	struct list_head	fibs;
+	struct list_head	fib_list;	// this holds fibs which should be 32 bit addresses
 };
 
 struct fsa_scsi_hba {
@@ -639,7 +644,7 @@
 	u8		ro[MAXIMUM_NUM_CONTAINERS];
 	u8		locked[MAXIMUM_NUM_CONTAINERS];
 	u8		deleted[MAXIMUM_NUM_CONTAINERS];
-	u32		devno[MAXIMUM_NUM_CONTAINERS];
+	s32		devno[MAXIMUM_NUM_CONTAINERS];
 };
 
 struct fib {
@@ -650,7 +655,6 @@
 	 *	The Adapter that this I/O is destined for.
 	 */
 	struct aac_dev 		*dev;
-	u64			logicaladdr;	/* 64 bit */
 	/*
 	 *	This is the event the sendfib routine will wait on if the
 	 *	caller did not pass one and this is synch io.
@@ -667,9 +671,14 @@
 	 *	Outstanding I/O queue.
 	 */
 	struct list_head	queue;
-
+	/*
+	 *	And for the internal issue/reply queues (we may be able
+	 *	to merge these two)
+	 */
+	struct list_head	fiblink;
 	void 			*data;
-	struct hw_fib		*fib;		/* Actual shared object */
+	struct hw_fib		*hw_fib;		/* Actual shared object */
+	dma_addr_t		hw_fib_pa;		/* physical address of hw_fib*/
 };
 
 /*
@@ -696,6 +705,7 @@
 	u32	biosrev;
 	u32	biosbuild;
 	u32	cluster;
+	u32	clusterchannelmask; 
 	u32	serial[2];
 	u32	battery;
 	u32	options;
@@ -720,19 +730,22 @@
 /*
  * Supported Options
  */
-#define AAC_OPT_SNAPSHOT	cpu_to_le32(1)
-#define AAC_OPT_CLUSTERS	cpu_to_le32(1<<1)
-#define AAC_OPT_WRITE_CACHE	cpu_to_le32(1<<2)
-#define AAC_OPT_64BIT_DATA	cpu_to_le32(1<<3)
-#define AAC_OPT_HOST_TIME_FIB	cpu_to_le32(1<<4)
-#define AAC_OPT_RAID50		cpu_to_le32(1<<5)
-#define AAC_OPT_4GB_WINDOW	cpu_to_le32(1<<6)
-#define AAC_OPT_SCSI_UPGRADEABLE cpu_to_le32(1<<7)
-#define AAC_OPT_SOFT_ERR_REPORT	cpu_to_le32(1<<8)
-#define AAC_OPT_SUPPORTED_RECONDITION cpu_to_le32(1<<9)
-#define AAC_OPT_SGMAP_HOST64	cpu_to_le32(1<<10)
-#define AAC_OPT_ALARM		cpu_to_le32(1<<11)
-#define AAC_OPT_NONDASD		cpu_to_le32(1<<12)
+#define AAC_OPT_SNAPSHOT		cpu_to_le32(1)
+#define AAC_OPT_CLUSTERS		cpu_to_le32(1<<1)
+#define AAC_OPT_WRITE_CACHE		cpu_to_le32(1<<2)
+#define AAC_OPT_64BIT_DATA		cpu_to_le32(1<<3)
+#define AAC_OPT_HOST_TIME_FIB		cpu_to_le32(1<<4)
+#define AAC_OPT_RAID50			cpu_to_le32(1<<5)
+#define AAC_OPT_4GB_WINDOW		cpu_to_le32(1<<6)
+#define AAC_OPT_SCSI_UPGRADEABLE	cpu_to_le32(1<<7)
+#define AAC_OPT_SOFT_ERR_REPORT		cpu_to_le32(1<<8)
+#define AAC_OPT_SUPPORTED_RECONDITION	cpu_to_le32(1<<9)
+#define AAC_OPT_SGMAP_HOST64		cpu_to_le32(1<<10)
+#define AAC_OPT_ALARM			cpu_to_le32(1<<11)
+#define AAC_OPT_NONDASD			cpu_to_le32(1<<12)
+#define AAC_OPT_SCSI_MANAGED    	cpu_to_le32(1<<13)
+#define AAC_OPT_RAID_SCSI_MODE		cpu_to_le32(1<<14)
+#define AAC_OPT_SUPPLEMENT_ADAPTER_INFO	cpu_to_le32(1<<15)
 
 struct aac_dev
 {
@@ -746,13 +759,12 @@
 	 */	
 	dma_addr_t		hw_fib_pa;
 	struct hw_fib		*hw_fib_va;
-#if BITS_PER_LONG >= 64
 	ulong			fib_base_va;
-#endif
 	/*
 	 *	Fib Headers
 	 */
-	struct fib		fibs[AAC_NUM_FIB];
+	struct fib              *fibs;
+
 	struct fib		*free_fib;
 	struct fib		*timeout_fib;
 	spinlock_t		fib_lock;
@@ -781,7 +793,7 @@
 
 	struct Scsi_Host	*scsi_host_ptr;
 	struct fsa_scsi_hba	fsa_dev;
-	int			thread_pid;
+	pid_t			thread_pid;
 	int			cardtype;
 	
 	/*
@@ -804,8 +816,15 @@
 	 */
 	u8			nondasd_support; 
 	u8			pae_support;
+	u8			raid_scsi_mode;
 };
 
+#define AllocateAndMapFibSpace(dev, MapFibContext) \
+	dev->a_ops.AllocateAndMapFibSpace(dev, MapFibContext)
+
+#define UnmapAndFreeFibSpace(dev, MapFibContext) \
+	dev->a_ops.UnmapAndFreeFibSpace(dev, MapFibContext)
+
 #define aac_adapter_interrupt(dev) \
 	dev->a_ops.adapter_interrupt(dev)
 
@@ -1142,7 +1161,9 @@
 	u32			altoid;		// != oid <==> snapshot or broken mirror exists
 };
 
-#define FSCS_READONLY	0x0002	/*	possible result of broken mirror */
+#define FSCS_NOTCLEAN	0x0001  	/* fsck is neccessary before mounting */
+#define FSCS_READONLY	0x0002		/* possible result of broken mirror */
+#define FSCS_HIDDEN	0x0004		/* should be ignored - set during a clear */
 
 struct aac_query_mount {
 	u32		command;
@@ -1326,9 +1347,12 @@
  */
  
 #define 	AifCmdEventNotify	1	/* Notify of event */
+#define		AifEnContainerChange	4	/* Container configuration change */
 #define		AifCmdJobProgress	2	/* Progress report */
 #define		AifCmdAPIReport		3	/* Report from other user of API */
 #define		AifCmdDriverNotify	4	/* Notify host driver of event */
+#define		AifDenMorphComplete	200	/* A morph operation completed */
+#define		AifDenVolumeExtendComplete 201  /* A volume expand operation completed */
 #define		AifReqJobList		100	/* Gets back complete job list */
 #define		AifReqJobsForCtr	101	/* Gets back jobs for specific container */
 #define		AifReqJobsForScsi	102	/* Gets back jobs for specific SCSI device */ 
@@ -1353,16 +1377,6 @@
 	u8 data[1];		/* Undefined length (from kernel viewpoint) */
 };
 
-static inline u32 fib2addr(struct hw_fib *hw)
-{
-	return (u32)hw;
-}
-
-static inline struct hw_fib *addr2fib(u32 addr)
-{
-	return (struct hw_fib *)addr;
-}
-
 const char *aac_driverinfo(struct Scsi_Host *);
 struct fib *fib_alloc(struct aac_dev *dev);
 int fib_setup(struct aac_dev *dev);
@@ -1376,7 +1390,7 @@
 int aac_consumer_avail(struct aac_dev * dev, struct aac_queue * q);
 void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum);
 int fib_complete(struct fib * context);
-#define fib_data(fibctx) ((void *)(fibctx)->fib->data)
+#define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data)
 int aac_detach(struct aac_dev *dev);
 struct aac_dev *aac_init_adapter(struct aac_dev *dev);
 int aac_get_containers(struct aac_dev *dev);
diff -urN linux-2.4.22-pre2/drivers/scsi/aacraid/commctrl.c linux-2.4.22-pre3/drivers/scsi/aacraid/commctrl.c
--- linux-2.4.22-pre2/drivers/scsi/aacraid/commctrl.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/aacraid/commctrl.c	2003-07-05 18:10:30.000000000 -0700
@@ -63,7 +63,7 @@
 	if(fibptr == NULL)
 		return -ENOMEM;
 		
-	kfib = fibptr->fib;
+	kfib = fibptr->hw_fib;
 	/*
 	 *	First copy in the header so that we can check the size field.
 	 */
@@ -150,7 +150,7 @@
 		 *	the list to 0.
 		 */
 		fibctx->count = 0;
-		INIT_LIST_HEAD(&fibctx->fibs);
+		INIT_LIST_HEAD(&fibctx->fib_list);
 		fibctx->jiffies = jiffies/HZ;
 		/*
 		 *	Now add this context onto the adapter's 
@@ -181,7 +181,7 @@
 {
 	struct fib_ioctl f;
 	struct aac_fib_context *fibctx, *aifcp;
-	struct hw_fib * fib;
+	struct fib * fib;
 	int status;
 	struct list_head * entry;
 	int found;
@@ -211,12 +211,16 @@
 		}
 		entry = entry->next;
 	}
-	if (found == 0)
+	if (found == 0) {
+		dprintk ((KERN_INFO "Fib not found\n"));
 		return -EINVAL;
+	}
 
 	if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
-		 (fibctx->size != sizeof(struct aac_fib_context)))
+		 (fibctx->size != sizeof(struct aac_fib_context))) {
+		dprintk ((KERN_INFO "Fib Context corrupt?\n"));
 		return -EINVAL;
+	}
 	status = 0;
 	spin_lock_irqsave(&dev->fib_lock, flags);
 	/*
@@ -224,27 +228,28 @@
 	 *	-EAGAIN
 	 */
 return_fib:
-	if (!list_empty(&fibctx->fibs)) {
+	if (!list_empty(&fibctx->fib_list)) {
 		struct list_head * entry;
 		/*
 		 *	Pull the next fib from the fibs
 		 */
-		entry = fibctx->fibs.next;
+		entry = fibctx->fib_list.next;
 		list_del(entry);
 		
-		fib = list_entry(entry, struct hw_fib, header.FibLinks);
+		fib = list_entry(entry, struct fib, fiblink);
 		fibctx->count--;
 		spin_unlock_irqrestore(&dev->fib_lock, flags);
-		if (copy_to_user(f.fib, fib, sizeof(struct hw_fib))) {
+		if (copy_to_user(f.fib, fib->hw_fib, sizeof(struct hw_fib))) {
+			kfree(fib->hw_fib);
 			kfree(fib);
 			return -EFAULT;
 		}	
 		/*
 		 *	Free the space occupied by this copy of the fib.
 		 */
+		kfree(fib->hw_fib);
 		kfree(fib);
 		status = 0;
-		fibctx->jiffies = jiffies/HZ;
 	} else {
 		spin_unlock_irqrestore(&dev->fib_lock, flags);
 		if (f.wait) {
@@ -259,28 +264,30 @@
 			status = -EAGAIN;
 		}	
 	}
+	fibctx->jiffies = jiffies/HZ;
 	return status;
 }
 
 int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
 {
-	struct hw_fib *fib;
+	struct fib *fib;
 
 	/*
 	 *	First free any FIBs that have not been consumed.
 	 */
-	while (!list_empty(&fibctx->fibs)) {
+	while (!list_empty(&fibctx->fib_list)) {
 		struct list_head * entry;
 		/*
 		 *	Pull the next fib from the fibs
 		 */
-		entry = fibctx->fibs.next;
+		entry = fibctx->fib_list.next;
 		list_del(entry);
-		fib = list_entry(entry, struct hw_fib, header.FibLinks);
+		fib = list_entry(entry, struct fib, fiblink);
 		fibctx->count--;
 		/*
 		 *	Free the space occupied by this copy of the fib.
 		 */
+		kfree(fib->hw_fib);
 		kfree(fib);
 	}
 	/*
diff -urN linux-2.4.22-pre2/drivers/scsi/aacraid/comminit.c linux-2.4.22-pre3/drivers/scsi/aacraid/comminit.c
--- linux-2.4.22-pre2/drivers/scsi/aacraid/comminit.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/aacraid/comminit.c	2003-07-05 18:10:30.000000000 -0700
@@ -39,6 +39,7 @@
 #include <linux/slab.h>
 #include <linux/blk.h>
 #include <linux/completion.h>
+#include <linux/mm.h>
 #include <asm/semaphore.h>
 #include "scsi.h"
 #include "hosts.h"
@@ -58,7 +59,6 @@
 	struct aac_init *init;
 	dma_addr_t phys;
 
-	/* FIXME: Adaptec add 128 bytes to this value - WHY ?? */
 	size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz;
 
 	base = pci_alloc_consistent(dev->pdev, size, &phys);
@@ -74,14 +74,6 @@
 	dev->init = (struct aac_init *)(base + fibsize);
 	dev->init_pa = phys + fibsize;
 
-	/*
-	 *	Cache the upper bits of the virtual mapping for 64bit boxes
-	 *	FIXME: this crap should be rewritten
-	 */
-#if BITS_PER_LONG >= 64 
-	dev->fib_base_va = ((ulong)base & 0xffffffff00000000);
-#endif
-
 	init = dev->init;
 
 	init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
@@ -92,16 +84,20 @@
 	 *	Adapter Fibs are the first thing allocated so that they
 	 *	start page aligned
 	 */
-	init->AdapterFibsVirtualAddress = cpu_to_le32((u32)base);
-	init->AdapterFibsPhysicalAddress = cpu_to_le32(phys);
+	dev->fib_base_va = (ulong)base;
+
+	/* We submit the physical address for AIF tags to limit to 32 bits */
+	init->AdapterFibsVirtualAddress = cpu_to_le32((u32)phys);
+	init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
 	init->AdapterFibsSize = cpu_to_le32(fibsize);
 	init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
+	init->HostPhysMemPages = cpu_to_le32(num_physpages);		// number of 4k pages of host physical memory
 
 	/*
 	 * Increment the base address by the amount already used
 	 */
 	base = base + fibsize + sizeof(struct aac_init);
-	phys = phys + fibsize + sizeof(struct aac_init);
+	phys = (dma_addr_t)((ulong)phys + fibsize + sizeof(struct aac_init));
 	/*
 	 *	Align the beginning of Headers to commalign
 	 */
@@ -111,8 +107,8 @@
 	/*
 	 *	Fill in addresses of the Comm Area Headers and Queues
 	 */
-	*commaddr = (unsigned long *)base;
-	init->CommHeaderAddress = cpu_to_le32(phys);
+	*commaddr = base;
+	init->CommHeaderAddress = cpu_to_le32((u32)phys);
 	/*
 	 *	Increment the base address by the size of the CommArea
 	 */
@@ -140,8 +136,8 @@
 	q->lock = &q->lockdata;
 	q->headers.producer = mem;
 	q->headers.consumer = mem+1;
-	*q->headers.producer = cpu_to_le32(qsize);
-	*q->headers.consumer = cpu_to_le32(qsize);
+	*(q->headers.producer) = cpu_to_le32(qsize);
+	*(q->headers.consumer) = cpu_to_le32(qsize);
 	q->entries = qsize;
 }
 
@@ -246,9 +242,9 @@
 	if (!aac_alloc_comm(dev, (void * *)&headers, size, QUEUE_ALIGNMENT))
 		return -ENOMEM;
 
-	queues = (struct aac_entry *)((unsigned char *)headers + hdrsize);
+	queues = (struct aac_entry *)(((ulong)headers) + hdrsize);
 
-	/* Adapter to Host normal proirity Command queue */ 
+	/* Adapter to Host normal priority Command queue */ 
 	comm->queue[HostNormCmdQueue].base = queues;
 	aac_queue_init(dev, &comm->queue[HostNormCmdQueue], headers, HOST_NORM_CMD_ENTRIES);
 	queues += HOST_NORM_CMD_ENTRIES;
@@ -320,14 +316,18 @@
 	}
 	memset(dev->queues, 0, sizeof(struct aac_queue_block));
 
-	if (aac_comm_init(dev)<0)
+	if (aac_comm_init(dev)<0){
+		kfree(dev->queues);
 		return NULL;
+	}
 	/*
 	 *	Initialize the list of fibs
 	 */
-	if(fib_setup(dev)<0)
+	if(fib_setup(dev)<0){
+		kfree(dev->queues);
 		return NULL;
-		
+	}
+
 	INIT_LIST_HEAD(&dev->fib_list);
 	init_completion(&dev->aif_completion);
 	/*
diff -urN linux-2.4.22-pre2/drivers/scsi/aacraid/commsup.c linux-2.4.22-pre3/drivers/scsi/aacraid/commsup.c
--- linux-2.4.22-pre2/drivers/scsi/aacraid/commsup.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/aacraid/commsup.c	2003-07-05 18:10:30.000000000 -0700
@@ -42,6 +42,7 @@
 #include <linux/completion.h>
 #include <asm/semaphore.h>
 #include <linux/blk.h>
+#include <asm/uaccess.h>
 #include "scsi.h"
 #include "hosts.h"
 
@@ -86,32 +87,32 @@
 int fib_setup(struct aac_dev * dev)
 {
 	struct fib *fibptr;
-	struct hw_fib *fib;
-	dma_addr_t fibpa;
+	struct hw_fib *hw_fib_va;
+	dma_addr_t hw_fib_pa;
 	int i;
 	
 	if(fib_map_alloc(dev)<0)
 		return -ENOMEM;
 		
-	fib = dev->hw_fib_va;
-	fibpa = dev->hw_fib_pa;
-	memset(fib, 0, sizeof(struct hw_fib) * AAC_NUM_FIB);
+	hw_fib_va = dev->hw_fib_va;
+	hw_fib_pa = dev->hw_fib_pa;
+	memset(hw_fib_va, 0, sizeof(struct hw_fib) * AAC_NUM_FIB);
 	/*
 	 *	Initialise the fibs
 	 */
 	for (i = 0, fibptr = &dev->fibs[i]; i < AAC_NUM_FIB; i++, fibptr++) 
 	{
 		fibptr->dev = dev;
-		fibptr->fib = fib;
-		fibptr->data = (void *) fibptr->fib->data;
+		fibptr->hw_fib = hw_fib_va;
+		fibptr->data = (void *) fibptr->hw_fib->data;
 		fibptr->next = fibptr+1;	/* Forward chain the fibs */
 		init_MUTEX_LOCKED(&fibptr->event_wait);
 		spin_lock_init(&fibptr->event_lock);
-		fib->header.XferState = cpu_to_le32(0xffffffff);
-		fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib));
-		fibptr->logicaladdr = (unsigned long) fibpa;
-		fib = (struct hw_fib *)((unsigned char *)fib + sizeof(struct hw_fib));
-		fibpa = fibpa + sizeof(struct hw_fib);
+		hw_fib_va->header.XferState = cpu_to_le32(0xffffffff);
+		hw_fib_va->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib));
+		fibptr->hw_fib_pa = hw_fib_pa;
+		hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + sizeof(struct hw_fib));
+		hw_fib_pa = hw_fib_pa + sizeof(struct hw_fib); 
 	}
 	/*
 	 *	Add the fib chain to the free list
@@ -152,7 +153,7 @@
 	 *	Null out fields that depend on being zero at the start of
 	 *	each I/O
 	 */
-	fibptr->fib->header.XferState = cpu_to_le32(0);
+	fibptr->hw_fib->header.XferState = cpu_to_le32(0);
 	fibptr->callback = NULL;
 	fibptr->callback_data = NULL;
 
@@ -178,9 +179,9 @@
 		fibptr->next = fibptr->dev->timeout_fib;
 		fibptr->dev->timeout_fib = fibptr;
 	} else {
-		if (fibptr->fib->header.XferState != 0) {
+		if (fibptr->hw_fib->header.XferState != 0) {
 			printk(KERN_WARNING "fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", 
-				 (void *)fibptr, fibptr->fib->header.XferState);
+				 (void*)fibptr, fibptr->hw_fib->header.XferState);
 		}
 		fibptr->next = fibptr->dev->free_fib;
 		fibptr->dev->free_fib = fibptr;
@@ -197,14 +198,14 @@
  
 void fib_init(struct fib *fibptr)
 {
-	struct hw_fib *fib = fibptr->fib;
+	struct hw_fib *hw_fib = fibptr->hw_fib;
 
-	fib->header.StructType = FIB_MAGIC;
-	fib->header.Size = cpu_to_le16(sizeof(struct hw_fib));
-        fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
-	fib->header.SenderFibAddress = cpu_to_le32(0);
-	fib->header.ReceiverFibAddress = cpu_to_le32(0);
-	fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib));
+	hw_fib->header.StructType = FIB_MAGIC;
+	hw_fib->header.Size = cpu_to_le16(sizeof(struct hw_fib));
+	hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
+	hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
+	hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
+	hw_fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib));
 }
 
 /**
@@ -217,10 +218,10 @@
  
 void fib_dealloc(struct fib * fibptr)
 {
-	struct hw_fib *fib = fibptr->fib;
-	if(fib->header.StructType != FIB_MAGIC) 
+	struct hw_fib *hw_fib = fibptr->hw_fib;
+	if(hw_fib->header.StructType != FIB_MAGIC) 
 		BUG();
-	fib->header.XferState = cpu_to_le32(0);        
+	hw_fib->header.XferState = cpu_to_le32(0);        
 }
 
 /*
@@ -257,7 +258,7 @@
 	q = &dev->queues->queue[qid];
 	
 	*index = le32_to_cpu(*(q->headers.producer));
-		if (*index - 2 == le32_to_cpu(*(q->headers.consumer)))
+	if ((*index - 2) == le32_to_cpu(*(q->headers.consumer)))
 			*nonotify = 1; 
 
 	if (qid == AdapHighCmdQueue) {
@@ -304,7 +305,7 @@
  *	success.
  */
 
-static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * fib, int wait, struct fib * fibptr, unsigned long *nonotify)
+static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify)
 {
 	struct aac_entry * entry = NULL;
 	int map = 0;
@@ -322,7 +323,7 @@
 	        /*
 	         *	Setup queue entry with a command, status and fib mapped
 	         */
-	        entry->size = cpu_to_le32(le16_to_cpu(fib->header.Size));
+	        entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size));
 	        map = 1;
 	}
 	else if (qid == AdapHighRespQueue || qid == AdapNormRespQueue)
@@ -334,9 +335,10 @@
         	/*
         	 *	Setup queue entry with command, status and fib mapped
         	 */
-        	entry->size = cpu_to_le32(le16_to_cpu(fib->header.Size));
-        	entry->addr = cpu_to_le32(fib->header.SenderFibAddress);     		/* Restore adapters pointer to the FIB */
-		fib->header.ReceiverFibAddress = fib->header.SenderFibAddress;		/* Let the adapter now where to find its data */
+        	entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size));
+        	entry->addr = hw_fib->header.SenderFibAddress;
+     			/* Restore adapters pointer to the FIB */
+		hw_fib->header.ReceiverFibAddress = hw_fib->header.SenderFibAddress;	/* Let the adapter now where to find its data */
         	map = 0;
 	} 
 	/*
@@ -344,7 +346,7 @@
 	 *	in the queue entry.
 	 */
 	if (map)
-		entry->addr = cpu_to_le32((unsigned long)(fibptr->logicaladdr));
+		entry->addr = fibptr->hw_fib_pa;
 	return 0;
 }
 
@@ -415,11 +417,11 @@
 	u32 qid;
 	struct aac_dev * dev = fibptr->dev;
 	unsigned long nointr = 0;
-	struct hw_fib * fib = fibptr->fib;
+	struct hw_fib * hw_fib = fibptr->hw_fib;
 	struct aac_queue * q;
 	unsigned long flags = 0;
 
-	if (!(le32_to_cpu(fib->header.XferState) & HostOwned))
+	if (!(le32_to_cpu(hw_fib->header.XferState) & HostOwned))
 		return -EBUSY;
 	/*
 	 *	There are 5 cases with the wait and reponse requested flags. 
@@ -435,19 +437,22 @@
 	if (wait && !reply) {
 		return -EINVAL;
 	} else if (!wait && reply) {
-		fib->header.XferState |= cpu_to_le32(Async | ResponseExpected);
+		hw_fib->header.XferState |= cpu_to_le32(Async | ResponseExpected);
 		FIB_COUNTER_INCREMENT(aac_config.AsyncSent);
 	} else if (!wait && !reply) {
-		fib->header.XferState |= cpu_to_le32(NoResponseExpected);
+		hw_fib->header.XferState |= cpu_to_le32(NoResponseExpected);
 		FIB_COUNTER_INCREMENT(aac_config.NoResponseSent);
 	} else if (wait && reply) {
-		fib->header.XferState |= cpu_to_le32(ResponseExpected);
+		hw_fib->header.XferState |= cpu_to_le32(ResponseExpected);
 		FIB_COUNTER_INCREMENT(aac_config.NormalSent);
 	} 
 	/*
 	 *	Map the fib into 32bits by using the fib number
 	 */
-	fib->header.SenderData = fibptr-&dev->fibs[0];	/* for callback */
+
+//	hw_fib->header.SenderFibAddress = ((u32)(fibptr-dev->fibs)) << 1;
+	hw_fib->header.SenderFibAddress = cpu_to_le32((u32)(ulong)fibptr->hw_fib_pa);
+	hw_fib->header.SenderData = (u32)(fibptr - dev->fibs);
 	/*
 	 *	Set FIB state to indicate where it came from and if we want a
 	 *	response from the adapter. Also load the command from the
@@ -455,15 +460,14 @@
 	 *
 	 *	Map the hw fib pointer as a 32bit value
 	 */
-	fib->header.SenderFibAddress = fib2addr(fib);
-	fib->header.Command = cpu_to_le16(command);
-	fib->header.XferState |= cpu_to_le32(SentFromHost);
-	fibptr->fib->header.Flags = 0;				/* Zero the flags field - its internal only...	 */
+	hw_fib->header.Command = cpu_to_le16(command);
+	hw_fib->header.XferState |= cpu_to_le32(SentFromHost);
+	fibptr->hw_fib->header.Flags = 0;	/* 0 the flags field - internal only*/
 	/*
 	 *	Set the size of the Fib we want to send to the adapter
 	 */
-	fib->header.Size = cpu_to_le16(sizeof(struct aac_fibhdr) + size);
-	if (le16_to_cpu(fib->header.Size) > le16_to_cpu(fib->header.SenderSize)) {
+	hw_fib->header.Size = cpu_to_le16(sizeof(struct aac_fibhdr) + size);
+	if (le16_to_cpu(hw_fib->header.Size) > le16_to_cpu(hw_fib->header.SenderSize)) {
 		return -EMSGSIZE;
 	}                
 	/*
@@ -471,22 +475,25 @@
 	 *	the adapter a command is ready.
 	 */
 	if (priority == FsaHigh) {
-		fib->header.XferState |= cpu_to_le32(HighPriority);
+		hw_fib->header.XferState |= cpu_to_le32(HighPriority);
 		qid = AdapHighCmdQueue;
 	} else {
-		fib->header.XferState |= cpu_to_le32(NormalPriority);
+		hw_fib->header.XferState |= cpu_to_le32(NormalPriority);
 		qid = AdapNormCmdQueue;
 	}
 	q = &dev->queues->queue[qid];
 
 	if(wait)
 		spin_lock_irqsave(&fibptr->event_lock, flags);
-	if(aac_queue_get( dev, &index, qid, fib, 1, fibptr, &nointr)<0)
+	if(aac_queue_get( dev, &index, qid, hw_fib, 1, fibptr, &nointr)<0)
 		return -EWOULDBLOCK;
 	dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
 	dprintk((KERN_DEBUG "Fib contents:.\n"));
-	dprintk((KERN_DEBUG "  Command =               %d.\n", fib->header.Command));
-	dprintk((KERN_DEBUG "  XferState  =            %x.\n", fib->header.XferState));
+	dprintk((KERN_DEBUG "  Command =               %d.\n", hw_fib->header.Command));
+	dprintk((KERN_DEBUG "  XferState  =            %x.\n", hw_fib->header.XferState));
+	dprintk((KERN_DEBUG "  hw_fib va being sent=%p\n",fibptr->hw_fib));
+	dprintk((KERN_DEBUG "  hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));
+	dprintk((KERN_DEBUG "  fib being sent=%p\n",fibptr));
 	/*
 	 *	Fill in the Callback and CallbackContext if we are not
 	 *	going to wait.
@@ -500,6 +507,7 @@
 	q->numpending++;
 
 	fibptr->done = 0;
+	fibptr->flags = 0;
 
 	if(aac_insert_entry(dev, index, qid, (nointr & aac_config.irq_mod)) < 0)
 		return -EWOULDBLOCK;
@@ -543,8 +551,7 @@
 {
 	u32 index;
 	int status;
-
-	if (*q->headers.producer == *q->headers.consumer) {
+	if (le32_to_cpu(*q->headers.producer) == le32_to_cpu(*q->headers.consumer)) {
 		status = 0;
 	} else {
 		/*
@@ -564,7 +571,7 @@
 
 int aac_consumer_avail(struct aac_dev *dev, struct aac_queue * q)
 {
-	return (*q->headers.producer != *q->headers.consumer);
+	return (le32_to_cpu(*q->headers.producer) != le32_to_cpu(*q->headers.consumer));
 }
 
 
@@ -583,7 +590,7 @@
 	int wasfull = 0;
 	u32 notify;
 
-	if (*q->headers.producer+1 == *q->headers.consumer)
+	if ((le32_to_cpu(*q->headers.producer)+1) == le32_to_cpu(*q->headers.consumer))
 		wasfull = 1;
         
 	if (le32_to_cpu(*q->headers.consumer) >= q->entries)
@@ -625,16 +632,15 @@
 
 int fib_adapter_complete(struct fib * fibptr, unsigned short size)
 {
-	struct hw_fib * fib = fibptr->fib;
+	struct hw_fib * hw_fib = fibptr->hw_fib;
 	struct aac_dev * dev = fibptr->dev;
 	unsigned long nointr = 0;
-
-	if (le32_to_cpu(fib->header.XferState) == 0)
+	if (le32_to_cpu(hw_fib->header.XferState) == 0)
         	return 0;
 	/*
 	 *	If we plan to do anything check the structure type first.
 	 */ 
-	if ( fib->header.StructType != FIB_MAGIC ) {
+	if ( hw_fib->header.StructType != FIB_MAGIC ) {
         	return -EINVAL;
 	}
 	/*
@@ -644,34 +650,34 @@
 	 *	and want to send a response back to the adapter. This will 
 	 *	send the completed cdb to the adapter.
 	 */
-	if (fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
-	        fib->header.XferState |= cpu_to_le32(HostProcessed);
-	        if (fib->header.XferState & cpu_to_le32(HighPriority)) {
+	if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
+	        hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
+	        if (hw_fib->header.XferState & cpu_to_le32(HighPriority)) {
         		u32 index;
        			if (size) 
 			{
 				size += sizeof(struct aac_fibhdr);
-				if (size > le16_to_cpu(fib->header.SenderSize))
+				if (size > le16_to_cpu(hw_fib->header.SenderSize))
 					return -EMSGSIZE;
-				fib->header.Size = cpu_to_le16(size);
+				hw_fib->header.Size = cpu_to_le16(size);
 			}
-			if(aac_queue_get(dev, &index, AdapHighRespQueue, fib, 1, NULL, &nointr) < 0) {
+			if(aac_queue_get(dev, &index, AdapHighRespQueue, hw_fib, 1, NULL, &nointr) < 0) {
 				return -EWOULDBLOCK;
 			}
 			if (aac_insert_entry(dev, index, AdapHighRespQueue,  (nointr & (int)aac_config.irq_mod)) != 0) {
 			}
 		}
-		else if (fib->header.XferState & NormalPriority) 
+		else if (hw_fib->header.XferState & NormalPriority) 
 		{
 			u32 index;
 
 			if (size) {
 				size += sizeof(struct aac_fibhdr);
-				if (size > le16_to_cpu(fib->header.SenderSize)) 
+				if (size > le16_to_cpu(hw_fib->header.SenderSize)) 
 					return -EMSGSIZE;
-				fib->header.Size = cpu_to_le16(size);
+				hw_fib->header.Size = cpu_to_le16(size);
 			}
-			if (aac_queue_get(dev, &index, AdapNormRespQueue, fib, 1, NULL, &nointr) < 0) 
+			if (aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr) < 0) 
 				return -EWOULDBLOCK;
 			if (aac_insert_entry(dev, index, AdapNormRespQueue, 
 				(nointr & (int)aac_config.irq_mod)) != 0) 
@@ -696,19 +702,19 @@
  
 int fib_complete(struct fib * fibptr)
 {
-	struct hw_fib * fib = fibptr->fib;
+	struct hw_fib * hw_fib = fibptr->hw_fib;
 
 	/*
 	 *	Check for a fib which has already been completed
 	 */
 
-	if (fib->header.XferState == cpu_to_le32(0))
+	if (hw_fib->header.XferState == cpu_to_le32(0))
         	return 0;
 	/*
 	 *	If we plan to do anything check the structure type first.
 	 */ 
 
-	if (fib->header.StructType != FIB_MAGIC)
+	if (hw_fib->header.StructType != FIB_MAGIC)
 	        return -EINVAL;
 	/*
 	 *	This block completes a cdb which orginated on the host and we 
@@ -716,19 +722,19 @@
 	 *	command is complete that we had sent to the adapter and this
 	 *	cdb could be reused.
 	 */
-	if((fib->header.XferState & cpu_to_le32(SentFromHost)) &&
-		(fib->header.XferState & cpu_to_le32(AdapterProcessed)))
+	if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) &&
+		(hw_fib->header.XferState & cpu_to_le32(AdapterProcessed)))
 	{
 		fib_dealloc(fibptr);
 	}
-	else if(fib->header.XferState & cpu_to_le32(SentFromHost))
+	else if(hw_fib->header.XferState & cpu_to_le32(SentFromHost))
 	{
 		/*
 		 *	This handles the case when the host has aborted the I/O
 		 *	to the adapter because the adapter is not responding
 		 */
 		fib_dealloc(fibptr);
-	} else if(fib->header.XferState & cpu_to_le32(HostOwned)) {
+	} else if(hw_fib->header.XferState & cpu_to_le32(HostOwned)) {
 		fib_dealloc(fibptr);
 	} else {
 		BUG();
@@ -776,16 +782,115 @@
  *	dispatches it to the appropriate routine for handling.
  */
 
+#define CONTAINER_TO_BUS(cont)		(0)
+#define CONTAINER_TO_TARGET(cont)	((cont))
+#define CONTAINER_TO_LUN(cont)		(0)
+
 static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
 {
-	struct hw_fib * fib = fibptr->fib;
-	/*
-	 * Set the status of this FIB to be Invalid parameter.
-	 *
-	 *	*(u32 *)fib->data = ST_INVAL;
-	 */
-	*(u32 *)fib->data = cpu_to_le32(ST_OK);
-	fib_adapter_complete(fibptr, sizeof(u32));
+	struct hw_fib * hw_fib = fibptr->hw_fib;
+	struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data;
+	int busy;
+	u32 container;
+	mm_segment_t fs;
+
+	/* Sniff for container changes */
+	dprintk ((KERN_INFO "AifCmdDriverNotify=%x\n", le32_to_cpu(*(u32 *)aifcmd->data)));
+	switch (le32_to_cpu(*(u32 *)aifcmd->data)) {
+	case AifDenMorphComplete:
+	case AifDenVolumeExtendComplete:
+	case AifEnContainerChange: /* Not really a driver notify Event */
+
+		busy = 0;
+		container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+		dprintk ((KERN_INFO "container=%d(%d,%d,%d,%d) ",
+		  container,
+		  (dev && dev->scsi_host_ptr)
+		    ? dev->scsi_host_ptr->host_no
+		    : -1,
+		  CONTAINER_TO_BUS(container),
+		  CONTAINER_TO_TARGET(container),
+		  CONTAINER_TO_LUN(container)));
+
+		/*
+		 *	Find the Scsi_Device associated with the SCSI address,
+		 * and mark it as changed, invalidating the cache. This deals
+		 * with changes to existing device IDs.
+		 */
+
+		if ((dev != (struct aac_dev *)NULL)
+		 && (dev->scsi_host_ptr != (struct Scsi_Host *)NULL)) {
+			Scsi_Device * device;
+
+			for (device = dev->scsi_host_ptr->host_queue;
+			  device != (Scsi_Device *)NULL;
+			  device = device->next) {
+				dprintk((KERN_INFO
+				  "aifd: device (%d,%d,%d,%d)?\n",
+				  dev->scsi_host_ptr->host_no,
+				  device->channel,
+				  device->id,
+				  device->lun));
+				if ((device->channel == CONTAINER_TO_BUS(container))
+				 && (device->id == CONTAINER_TO_TARGET(container))
+				 && (device->lun == CONTAINER_TO_LUN(container))) {
+					busy |= (device->access_count != 0);
+					if (busy == 0) {
+						device->removable = TRUE;
+					}
+				}
+			}
+		}
+		dprintk (("busy=%d\n", busy));
+
+		/*
+		 * if (busy == 0) {
+		 *	scan_scsis(dev->scsi_host_ptr, 1,
+		 *	  CONTAINER_TO_BUS(container),
+		 *	  CONTAINER_TO_TARGET(container),
+		 *	  CONTAINER_TO_LUN(container));
+		 * }
+		 * is not exported as accessible, so we need to go around it
+		 * another way. So, we look for the "proc/scsi/scsi" entry in
+		 * the proc filesystem (using proc_scsi as a shortcut) and send
+		 * it a message. This deals with new devices that have
+		 * appeared. If the device has gone offline, scan_scsis will
+		 * also discover this, but we do not want the device to
+		 * go away. We need to check the access_count for the
+		 * device since we are not wanting the devices to go away.
+		 */
+		if (busy == 0 && proc_scsi != NULL) {
+			struct proc_dir_entry * entry;
+
+			dprintk((KERN_INFO "proc_scsi=%p ", proc_scsi));
+			for (entry = proc_scsi->subdir; entry != (struct proc_dir_entry *)NULL; entry = entry->next) {
+				dprintk(("\"%.*s\"[%d]=%x ", entry->namelen,
+				  entry->name, entry->namelen, entry->low_ino));
+				if ((entry->low_ino != 0) && (entry->namelen == 4) && (memcmp ("scsi", entry->name, 4) == 0)) {
+					dprintk(("%p->write_proc=%p ", entry, entry->write_proc));
+					if (entry->write_proc != (int (*)(struct file *, const char *, unsigned long, void *))NULL) {
+						char buffer[80];
+						int length;
+
+						sprintf (buffer,
+						  "scsi add-single-device %d %d %d %d\n",
+						  dev->scsi_host_ptr->host_no,
+						  CONTAINER_TO_BUS(container),
+						  CONTAINER_TO_TARGET(container),
+						  CONTAINER_TO_LUN(container));
+						length = strlen (buffer);
+						dprintk((KERN_INFO "echo %.*s > /proc/scsi/scsi\n", length-1, buffer));
+						fs = get_fs();
+						set_fs(get_ds());
+						length = entry->write_proc(NULL, buffer, length, NULL);
+						set_fs(fs);
+						dprintk((KERN_INFO "returns %d\n", length));
+					}
+					break;
+				}
+			}
+		}
+	}
 }
 
 /**
@@ -800,8 +905,8 @@
  
 int aac_command_thread(struct aac_dev * dev)
 {
-	struct hw_fib *fib, *newfib;
-	struct fib fibptr; /* for error logging */
+	struct hw_fib *hw_fib, *hw_newfib;
+	struct fib *fib, *newfib;
 	struct aac_queue_block *queues = dev->queues;
 	struct aac_fib_context *fibctx;
 	unsigned long flags;
@@ -822,9 +927,9 @@
 	 *	Let the DPC know it has a place to send the AIF's to.
 	 */
 	dev->aif_thread = 1;
-	memset(&fibptr, 0, sizeof(struct fib));
 	add_wait_queue(&queues->queue[HostNormCmdQueue].cmdready, &wait);
 	set_current_state(TASK_INTERRUPTIBLE);
+	dprintk ((KERN_INFO "aac_command_thread start\n"));
 	while(1) 
 	{
 		spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);
@@ -833,37 +938,47 @@
 			struct aac_aifcmd * aifcmd;
 
 			set_current_state(TASK_RUNNING);
-		
+
 			entry = queues->queue[HostNormCmdQueue].cmdq.next;
 			list_del(entry);
-			
+	
 			spin_unlock_irqrestore(queues->queue[HostNormCmdQueue].lock, flags);
-			fib = list_entry(entry, struct hw_fib, header.FibLinks);
+			fib = list_entry(entry, struct fib, fiblink);
 			/*
 			 *	We will process the FIB here or pass it to a 
 			 *	worker thread that is TBD. We Really can't 
 			 *	do anything at this point since we don't have
 			 *	anything defined for this thread to do.
 			 */
-			memset(&fibptr, 0, sizeof(struct fib));
-			fibptr.type = FSAFS_NTC_FIB_CONTEXT;
-			fibptr.size = sizeof( struct fib );
-			fibptr.fib = fib;
-			fibptr.data = fib->data;
-			fibptr.dev = dev;
+			hw_fib = fib->hw_fib;
+			
+			memset(fib, 0, sizeof(struct fib));
+			fib->type = FSAFS_NTC_FIB_CONTEXT;
+			fib->size = sizeof( struct fib );
+			fib->hw_fib = hw_fib;
+			fib->data = hw_fib->data;
+			fib->dev = dev;
 			/*
 			 *	We only handle AifRequest fibs from the adapter.
 			 */
-			aifcmd = (struct aac_aifcmd *) fib->data;
-			if (aifcmd->command == le16_to_cpu(AifCmdDriverNotify)) {
-				aac_handle_aif(dev, &fibptr);
+			aifcmd = (struct aac_aifcmd *) hw_fib->data;
+			if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
+				/* Handle Driver Notify Events */
+				aac_handle_aif(dev, fib);
+				*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
+				fib_adapter_complete(fib, sizeof(u32));
 			} else {
+				struct list_head *entry;
 				/* The u32 here is important and intended. We are using
 				   32bit wrapping time to fit the adapter field */
 				   
 				u32 time_now, time_last;
 				unsigned long flagv;
 				
+				/* Sniff events */
+				if (aifcmd->command == cpu_to_le32(AifCmdEventNotify))
+					aac_handle_aif(dev, fib);
+
 				time_now = jiffies/HZ;
 
 				spin_lock_irqsave(&dev->fib_lock, flagv);
@@ -885,6 +1000,11 @@
 					 */
 					if (fibctx->count > 20)
 					{
+						/*
+						 * It's *not* jiffies folks,
+						 * but jiffies / HZ, so do not
+						 * panic ...
+						 */
 						time_last = fibctx->jiffies;
 						/*
 						 * Has it been > 2 minutes 
@@ -901,17 +1021,21 @@
 					 * Warning: no sleep allowed while
 					 * holding spinlock
 					 */
-					newfib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC);
-					if (newfib) {
+					hw_newfib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC);
+					newfib = kmalloc(sizeof(struct fib), GFP_ATOMIC);
+					if (newfib && hw_newfib) {
 						/*
 						 * Make the copy of the FIB
+						 * FIXME: check if we need to fix other fields up
 						 */
-						memcpy(newfib, fib, sizeof(struct hw_fib));
+						memcpy(hw_newfib, hw_fib, sizeof(struct hw_fib));
+						memcpy(newfib, fib, sizeof(struct fib));
+						newfib->hw_fib = hw_newfib;
 						/*
 						 * Put the FIB onto the
 						 * fibctx's fibs
 						 */
-						list_add_tail(&newfib->header.FibLinks, &fibctx->fibs);
+						list_add_tail(&newfib->fiblink, &fibctx->fib_list);
 						fibctx->count++;
 						/* 
 						 * Set the event to wake up the
@@ -920,17 +1044,22 @@
 						up(&fibctx->wait_sem);
 					} else {
 						printk(KERN_WARNING "aifd: didn't allocate NewFib.\n");
+						if(newfib)
+							kfree(newfib);
+						if(hw_newfib)
+							kfree(hw_newfib);
 					}
 					entry = entry->next;
 				}
 				/*
 				 *	Set the status of this FIB
 				 */
-				*(u32 *)fib->data = cpu_to_le32(ST_OK);
-				fib_adapter_complete(&fibptr, sizeof(u32));
+				*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
+				fib_adapter_complete(fib, sizeof(u32));
 				spin_unlock_irqrestore(&dev->fib_lock, flagv);
 			}
 			spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);
+			kfree(fib);
 		}
 		/*
 		 *	There are no more AIF's
diff -urN linux-2.4.22-pre2/drivers/scsi/aacraid/dpcsup.c linux-2.4.22-pre3/drivers/scsi/aacraid/dpcsup.c
--- linux-2.4.22-pre2/drivers/scsi/aacraid/dpcsup.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/aacraid/dpcsup.c	2003-07-05 18:10:30.000000000 -0700
@@ -74,12 +74,14 @@
 	 */
 	while(aac_consumer_get(dev, q, &entry))
 	{
-		int fast;
+		u32 fast ;
+		fast = (entry->addr & cpu_to_le32(0x01));
+//		fib = &dev->fibs[(entry->addr >> 1)];
+//		hwfib = fib->hw_fib;
+		hwfib = bus_to_virt(le32_to_cpu(entry->addr & cpu_to_le32(~0x01)));
+		fib = &dev->fibs[hwfib->header.SenderData];
 
-		fast = (int) (entry->addr & 0x01);
-		hwfib = addr2fib(entry->addr & ~0x01);
 		aac_consumer_free(dev, q, HostNormRespQueue);
-		fib = &dev->fibs[hwfib->header.SenderData];
 		/*
 		 *	Remove this fib from the Outstanding I/O queue.
 		 *	But only if it has not already been timed out.
@@ -169,30 +171,51 @@
 	 *	up the waiters until there are no more QEs. We then return
 	 *	back to the system.
 	 */
+	dprintk((KERN_INFO
+	  "dev=%p, dev->comm_phys=%x, dev->comm_addr=%p, dev->comm_size=%u\n",
+	  dev, (u32)dev->comm_phys, dev->comm_addr, (unsigned)dev->comm_size));
+
 	while(aac_consumer_get(dev, q, &entry))
 	{
-		struct hw_fib * fib;
-		fib = addr2fib(entry->addr);
+		struct fib fibctx;
+		struct fib *fib = &fibctx;
+		u32 hw_fib_pa = le32_to_cpu(entry->addr & cpu_to_le32(~0x01));
+		struct hw_fib * hw_fib_va = ((dev->comm_phys <= hw_fib_pa)
+		 && (hw_fib_pa < (dev->comm_phys + dev->comm_size)))
+		  ? dev->comm_addr + (hw_fib_pa - dev->comm_phys)
+		  : /* inconceivable */ bus_to_virt(hw_fib_pa);
+		dprintk((KERN_INFO "hw_fib_pa=%x hw_fib_va=%p\n", hw_fib_pa, hw_fib_va));
 
-		if (dev->aif_thread) {
-		        list_add_tail(&fib->header.FibLinks, &q->cmdq);
+		/*
+		 *	Allocate a FIB at all costs. For non queued stuff
+		 *	we can just use the stack so we are happy. We need
+		 *	a fib object in order to manage the linked lists
+		 */
+		if (dev->aif_thread)
+			if((fib = kmalloc(sizeof(struct fib), GFP_ATOMIC))==NULL)
+				fib = &fibctx;
+			
+		memset(fib, 0, sizeof(struct fib));
+		INIT_LIST_HEAD(&fib->fiblink);
+		fib->type = FSAFS_NTC_FIB_CONTEXT;
+		fib->size = sizeof(struct fib);
+		fib->hw_fib = hw_fib_va;
+		fib->data = hw_fib_va->data;
+		fib->dev = dev;
+		
+		if (dev->aif_thread && fib != &fibctx)
+		{		
+			list_add_tail(&fib->fiblink, &q->cmdq);
 	 	        aac_consumer_free(dev, q, HostNormCmdQueue);
 		        wake_up_interruptible(&q->cmdready);
 		} else {
-			struct fib fibctx;
 	 	        aac_consumer_free(dev, q, HostNormCmdQueue);
 			spin_unlock_irqrestore(q->lock, flags);
-			memset(&fibctx, 0, sizeof(struct fib));
-			fibctx.type = FSAFS_NTC_FIB_CONTEXT;
-			fibctx.size = sizeof(struct fib);
-			fibctx.fib = fib;
-			fibctx.data = fib->data;
-			fibctx.dev = dev;
 			/*
 			 *	Set the status of this FIB
 			 */
-			*(u32 *)fib->data = cpu_to_le32(ST_OK);
-			fib_adapter_complete(&fibctx, sizeof(u32));
+			*(u32 *)hw_fib_va->data = cpu_to_le32(ST_OK);
+			fib_adapter_complete(fib, sizeof(u32));
 			spin_lock_irqsave(q->lock, flags);
 		}		
 	}
diff -urN linux-2.4.22-pre2/drivers/scsi/aacraid/linit.c linux-2.4.22-pre3/drivers/scsi/aacraid/linit.c
--- linux-2.4.22-pre2/drivers/scsi/aacraid/linit.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/scsi/aacraid/linit.c	2003-07-05 18:10:31.000000000 -0700
@@ -35,8 +35,8 @@
  *	
  */
 
-#define AAC_DRIVER_VERSION		"0.9.9ac6-TEST"
-#define AAC_DRIVER_BUILD_DATE		__DATE__
+#define AAC_DRIVER_VERSION		"1.1.2"
+#define AAC_DRIVER_BUILD_DATE		__DATE__ " " __TIME__
 
 #include <linux/module.h>
 #include <linux/config.h>
@@ -59,12 +59,12 @@
 #define AAC_DRIVERNAME	"aacraid"
 
 MODULE_AUTHOR("Red Hat Inc and Adaptec");
-MODULE_DESCRIPTION("Supports Dell PERC2, 2/Si, 3/Si, 3/Di, PERC 320/DC, Adaptec 2120S, 2200S, 5400S, and HP NetRAID-4M devices. http://domsch.com/linux/ or http://linux.adaptec.com");
+MODULE_DESCRIPTION("Supports Dell PERC2, 2/Si, 3/Si, 3/Di, Adaptec Advanced Raid Products, and HP NetRAID-4M devices. http://domsch.com/linux/ or http://linux.adaptec.com");
 MODULE_LICENSE("GPL");
-MODULE_PARM(nondasd, "i");
-MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
+MODULE_PARM(paemode, "i");
+MODULE_PARM_DESC(paemode, "Control whether dma addressing is using PAE. 0=off, 1=on");
 
-static int nondasd=-1;
+static int paemode = -1;
 
 struct aac_dev *aac_devices[MAXIMUM_NUM_ADAPTERS];
 
@@ -81,25 +81,41 @@
  */
  
 static struct aac_driver_ident aac_drivers[] = {
-	{ 0x1028, 0x0001, 0x1028, 0x0001, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, /* PERC 2/Si */
-	{ 0x1028, 0x0002, 0x1028, 0x0002, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, /* PERC 3/Di */
-	{ 0x1028, 0x0003, 0x1028, 0x0003, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, /* PERC 3/Si */
-	{ 0x1028, 0x0004, 0x1028, 0x00d0, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, /* PERC 3/Si */
-	{ 0x1028, 0x0002, 0x1028, 0x00d1, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, /* PERC 3/Di */
-	{ 0x1028, 0x0002, 0x1028, 0x00d9, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, /* PERC 3/Di */
-	{ 0x1028, 0x000a, 0x1028, 0x0106, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, /* PERC 3/Di */
-	{ 0x1028, 0x000a, 0x1028, 0x011b, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, /* PERC 3/Di */
-	{ 0x1028, 0x000a, 0x1028, 0x0121, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, /* PERC 3/Di */
-	{ 0x9005, 0x0283, 0x9005, 0x0283, aac_rx_init, "aacraid",  "ADAPTEC ", "catapult        ", 2 }, /* catapult*/
-	{ 0x9005, 0x0284, 0x9005, 0x0284, aac_rx_init, "aacraid",  "ADAPTEC ", "tomcat          ", 2 }, /* tomcat*/
-	{ 0x9005, 0x0285, 0x9005, 0x0286, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2120S   ", 1 }, /* Adaptec 2120S (Crusader)*/
-	{ 0x9005, 0x0285, 0x9005, 0x0285, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2 }, /* Adaptec 2200S (Vulcan)*/
-	{ 0x9005, 0x0285, 0x9005, 0x0287, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2 }, /* Adaptec 2200S (Vulcan-2m)*/
-	{ 0x9005, 0x0285, 0x1028, 0x0287, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, /* Dell PERC 320/DC */
-	{ 0x1011, 0x0046, 0x9005, 0x0365, aac_sa_init, "aacraid",  "ADAPTEC ", "Adaptec 5400S   ", 4 }, /* Adaptec 5400S (Mustang)*/
-	{ 0x1011, 0x0046, 0x9005, 0x0364, aac_sa_init, "aacraid",  "ADAPTEC ", "AAC-364         ", 4 }, /* Adaptec 5400S (Mustang)*/
-	{ 0x1011, 0x0046, 0x9005, 0x1364, aac_sa_init, "percraid", "DELL    ", "PERCRAID        ", 4 }, /* Dell PERC2 "Quad Channel" */
-	{ 0x1011, 0x0046, 0x103c, 0x10c2, aac_sa_init, "hpnraid",  "HP      ", "NetRAID-4M      ", 4 }  /* HP NetRAID-4M */
+	{ 0x1028, 0x0001, 0x1028, 0x0001, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, 		/* PERC 2/Si (Iguana/PERC2Si) */
+	{ 0x1028, 0x0002, 0x1028, 0x0002, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, 		/* PERC 3/Di (Opal/PERC3Di) */
+	{ 0x1028, 0x0003, 0x1028, 0x0003, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, 		/* PERC 3/Si (SlimFast/PERC3Si */
+	{ 0x1028, 0x0004, 0x1028, 0x00d0, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, 		/* PERC 3/Di (Iguana FlipChip/PERC3DiF */
+	{ 0x1028, 0x0002, 0x1028, 0x00d1, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, 		/* PERC 3/Di (Viper/PERC3DiV) */
+	{ 0x1028, 0x0002, 0x1028, 0x00d9, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, 		/* PERC 3/Di (Lexus/PERC3DiL) */
+	{ 0x1028, 0x000a, 0x1028, 0x0106, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, 		/* PERC 3/Di (Jaguar/PERC3DiJ) */
+	{ 0x1028, 0x000a, 0x1028, 0x011b, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, 		/* PERC 3/Di (Dagger/PERC3DiD) */
+	{ 0x1028, 0x000a, 0x1028, 0x0121, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, 		/* PERC 3/Di (Boxster/PERC3DiB) */
+	{ 0x9005, 0x0283, 0x9005, 0x0283, aac_rx_init, "aacraid",  "ADAPTEC ", "catapult        ", 2 }, 		/* catapult */
+	{ 0x9005, 0x0284, 0x9005, 0x0284, aac_rx_init, "aacraid",  "ADAPTEC ", "tomcat          ", 2 }, 		/* tomcat */
+	{ 0x9005, 0x0285, 0x9005, 0x0286, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2120S   ", 1, AAC_QUIRK_31BIT },/* Adaptec 2120S (Crusader) */
+	{ 0x9005, 0x0285, 0x9005, 0x0285, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2, AAC_QUIRK_31BIT },/* Adaptec 2200S (Vulcan) */
+	{ 0x9005, 0x0285, 0x9005, 0x0287, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2, AAC_QUIRK_31BIT },/* Adaptec 2200S (Vulcan-2m) */
+	{ 0x9005, 0x0285, 0x17aa, 0x0286, aac_rx_init, "aacraid",  "Legend  ", "Legend S220     ", 1 }, 		/* Legend S220 (Legend Crusader) */
+	{ 0x9005, 0x0285, 0x17aa, 0x0287, aac_rx_init, "aacraid",  "Legend  ", "Legend S230     ", 2 }, 		/* Legend S230 (Legend Vulcan) */
+
+	{ 0x9005, 0x0285, 0x9005, 0x0288, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 3230S   ", 2 }, 		/* Adaptec 3230S (Harrier) */
+	{ 0x9005, 0x0285, 0x9005, 0x0289, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 3240S   ", 2 }, 		/* Adaptec 3240S (Tornado) */
+	{ 0x9005, 0x0285, 0x9005, 0x028a, aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, 		/* ASR-2020S PCI-X ZCR (Skyhawk) */
+	{ 0x9005, 0x0285, 0x9005, 0x028b, aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, 		/* ASR-2020S SO-DIMM PCI-X ZCR (Terminator) */
+	{ 0x9005, 0x0285, 0x9005, 0x0290, aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-2410SA SATA ", 2 }, 		/* AAR-2410SA PCI SATA 4ch (Jaguar II) */
+	{ 0x9005, 0x0285, 0x1028, 0x0291, aac_rx_init, "aacraid",  "DELL    ", "CERC SATA RAID 2 ", 2 },		/* CERC SATA RAID 2 PCI SATA 8ch (DellCorsair) */
+	{ 0x9005, 0x0285, 0x9005, 0x0292, aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-2810SA SATA ", 2 }, 		/* AAR-2810SA PCI SATA 8ch (Corsair-8) */
+	{ 0x9005, 0x0285, 0x9005, 0x0293, aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-21610SA SATA ", 2 },		/* AAR-21610SA PCI SATA 16ch (Corsair-16) */
+	{ 0x9005, 0x0285, 0x9005, 0x0294, aac_rx_init, "aacraid",  "ADAPTEC ", "SO-DIMM SATA ZCR ", 2 },		/* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
+	/* ServeRAID */
+/*	{ 0x9005, 0x0250, 0x1014, 0x0279, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec         ", 2 }, */ /*  (Marco) */
+/*	{ 0x9005, 0x0250, 0x1014, 0x028c, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec         ", 2 }, */ /* (Sebring)*/
+
+	{ 0x9005, 0x0285, 0x1028, 0x0287, aac_rx_init, "percraid", "DELL    ", "PERC 320/DC     ", 2 },			/* Perc 320/DC*/
+	{ 0x1011, 0x0046, 0x9005, 0x0365, aac_sa_init, "aacraid",  "ADAPTEC ", "Adaptec 5400S   ", 4 }, 		/* Adaptec 5400S (Mustang)*/
+	{ 0x1011, 0x0046, 0x9005, 0x0364, aac_sa_init, "aacraid",  "ADAPTEC ", "AAC-364         ", 4 },			/* Adaptec 5400S (Mustang)*/
+	{ 0x1011, 0x0046, 0x9005, 0x1364, aac_sa_init, "percraid", "DELL    ", "PERCRAID        ", 4 },			/* Dell PERC2 "Quad Channel" */
+	{ 0x1011, 0x0046, 0x103c, 0x10c2, aac_sa_init, "hpnraid",  "HP      ", "NetRAID         ", 4 }			/* HP NetRAID-4M */
 };
 
 #define NUM_AACTYPES	(sizeof(aac_drivers) / sizeof(struct aac_driver_ident))
@@ -159,10 +175,11 @@
 	struct fsa_scsi_hba *fsa_dev_ptr;
 	char *name = NULL;
 	
-	printk(KERN_INFO "Red Hat/Adaptec aacraid driver, %s\n", AAC_DRIVER_BUILD_DATE);
+	printk(KERN_INFO "Red Hat/Adaptec aacraid driver (%s %s)\n", AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE);
 
 	/* setting up the proc directory structure */
 	template->proc_name = "aacraid";
+	spin_unlock_irq(&io_request_lock);
 
 	for( index = 0; index != num_aacdrivers; index++ )
 	{
@@ -179,7 +196,11 @@
 			if (pci_enable_device(dev))
 				continue;
 			pci_set_master(dev);
-			pci_set_dma_mask(dev, 0xFFFFFFFFULL);
+			
+			if(aac_drivers[index].quirks & AAC_QUIRK_31BIT)
+				pci_set_dma_mask(dev, 0x7FFFFFFFULL);
+			else
+				pci_set_dma_mask(dev, 0xFFFFFFFFULL);
 
 			if((dev->subsystem_vendor != aac_drivers[index].subsystem_vendor) || 
 			   (dev->subsystem_device != aac_drivers[index].subsystem_device))
@@ -188,8 +209,6 @@
 			dprintk((KERN_DEBUG "%s device detected.\n", name));
 			dprintk((KERN_DEBUG "%x/%x/%x/%x.\n", vendor_id, device_id, 
 				aac_drivers[index].subsystem_vendor, aac_drivers[index].subsystem_device));
-			/* Increment the host adapter count */
-			aac_count++;
 			/*
 			 * scsi_register() allocates memory for a Scsi_Hosts structure and
 			 * links it into the linked list of host adapters. This linked list
@@ -203,13 +222,14 @@
 			 * specific information.
 			 */
 			host_ptr = scsi_register( template, sizeof(struct aac_dev) );
+			if(host_ptr == NULL)
+				continue;
+			/* Increment the host adapter count */
+			aac_count++;
 			/* 
 			 * These three parameters can be used to allow for wide SCSI 
 			 * and for host adapters that support multiple buses.
 			 */
-			host_ptr->max_id = 17;
-			host_ptr->max_lun = 8;
-			host_ptr->max_channel = 1;
 			host_ptr->irq = dev->irq;		/* Adapter IRQ number */
 			/* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
 			host_ptr->base = dev->resource[0].start;
@@ -236,9 +256,13 @@
 			/* attach a pointer back to Scsi_Host */
 			aac->scsi_host_ptr = host_ptr;	
 			aac->pdev = dev;
-			aac->cardtype =  index;
 			aac->name = aac->scsi_host_ptr->hostt->name;
 			aac->id = aac->scsi_host_ptr->unique_id;
+			aac->cardtype =  index;
+
+			aac->fibs = (struct fib*) kmalloc(sizeof(struct fib)*AAC_NUM_FIB, GFP_KERNEL);
+			spin_lock_init(&aac->fib_lock);
+
 			/* Initialize the ordinal number of the device to -1 */
 			fsa_dev_ptr = &(aac->fsa_dev);
 			for( container = 0; container < MAXIMUM_NUM_CONTAINERS; container++ )
@@ -255,15 +279,6 @@
 			} 
 			dprintk((KERN_DEBUG "%s:%d device initialization successful.\n", name, host_ptr->unique_id));
 			aac_get_adapter_info(aac);
-			if(nondasd != -1) 
-			{
-				/* someone told us how to set this on the cmdline */
-				aac->nondasd_support = (nondasd!=0);
-			}
-			if(aac->nondasd_support != 0){
-				printk(KERN_INFO "%s%d: Non-DASD support enabled\n", aac->name, aac->id);
-			}
-			dprintk((KERN_DEBUG "%s:%d options flag %04x.\n",name, host_ptr->unique_id,aac->adapter_info.options));
 			if(aac->nondasd_support == 1)
 			{
 				/*
@@ -280,21 +295,11 @@
 			aac_devices[aac_count-1] = aac;
 
 			/*
-			 * dmb - we may need to move these 3 parms somewhere else once
+			 * dmb - we may need to move the setting of these parms somewhere else once
 			 * we get a fib that can report the actual numbers
 			 */
 			host_ptr->max_id = AAC_MAX_TARGET;
 			host_ptr->max_lun = AAC_MAX_LUN;
-			
-			/*
-			 *  If we are PAE capable then our future DMA mappings
-			 *  (for read/write commands) are 64bit clean and don't 
-			 *  need bouncing. This assumes we do no other 32bit only
-			 *  allocations (eg fib table expands) after this point.
-			 */
-			 
-			if(aac->pae_support)
-				pci_set_dma_mask(dev, 0xFFFFFFFFFFFFFFFFUL);
 		}
 	}
 
@@ -302,6 +307,7 @@
 		if((aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops))<0)
 			printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n");
 	}
+	spin_lock_irq(&io_request_lock);
 
 	template->present = aac_count; /* # of cards of this type found */
 	return aac_count;
@@ -738,7 +744,10 @@
 	if(write || offset > 0)
 		return 0;
 	*start_ptr = proc_buffer;
-	return sprintf(proc_buffer, "%s  %d\n", "Raid Controller, scsi hba number", host_no);
+	return sprintf(proc_buffer,
+	  "Adaptec Raid Controller %s %s, scsi hba number %d\n",
+	  AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE,
+	  host_no);
 }
 
 EXPORT_NO_SYMBOLS;
diff -urN linux-2.4.22-pre2/drivers/scsi/aacraid/rx.c linux-2.4.22-pre3/drivers/scsi/aacraid/rx.c
--- linux-2.4.22-pre2/drivers/scsi/aacraid/rx.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/aacraid/rx.c	2003-07-05 18:10:31.000000000 -0700
@@ -400,6 +400,11 @@
 	 *	Start any kernel threads needed
 	 */
 	dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0);
+	if(dev->thread_pid < 0)
+	{
+		printk(KERN_ERR "aacraid: Unable to create rx thread.\n");
+		return -1;
+	}	
 	/*
 	 *	Tell the adapter that all is configured, and it can start
 	 *	accepting requests
diff -urN linux-2.4.22-pre2/drivers/scsi/aacraid/sa.c linux-2.4.22-pre3/drivers/scsi/aacraid/sa.c
--- linux-2.4.22-pre2/drivers/scsi/aacraid/sa.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/aacraid/sa.c	2003-07-05 18:10:31.000000000 -0700
@@ -349,7 +349,7 @@
 	 *	Wait for the adapter to be up and running. Wait up to 3 minutes.
 	 */
 	while (!(sa_readl(dev, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
-		if (time_after(start+180*HZ, jiffies)) {
+		if (time_after(jiffies, start+180*HZ)) {
 			status = sa_readl(dev, Mailbox7) >> 16;
 			printk(KERN_WARNING "%s%d: adapter kernel failed to start, init status = %d.\n", name, instance, le32_to_cpu(status));
 			return -1;
@@ -384,6 +384,11 @@
 	 *	Start any kernel threads needed
 	 */
 	dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0);
+	if (dev->thread_pid < 0) {
+	     printk(KERN_ERR "aacraid: Unable to create command thread.\n");
+	     return -1;
+	}
+
 	/*
 	 *	Tell the adapter that all is configure, and it can start 
 	 *	accepting requests
diff -urN linux-2.4.22-pre2/drivers/scsi/aic7xxx/aicasm/Makefile linux-2.4.22-pre3/drivers/scsi/aic7xxx/aicasm/Makefile
--- linux-2.4.22-pre2/drivers/scsi/aic7xxx/aicasm/Makefile	2003-07-05 18:09:19.000000000 -0700
+++ linux-2.4.22-pre3/drivers/scsi/aic7xxx/aicasm/Makefile	2003-07-05 18:10:39.000000000 -0700
@@ -34,7 +34,9 @@
 	$(AICASM_CC) $(AICASM_CFLAGS) $(SRCS) -o $(PROG) $(LIBS)
 
 aicdb.h:
-	@if [ -e "/usr/include/db3/db_185.h" ]; then		\
+	@if [ -e "/usr/include/db4/db_185.h" ]; then		\
+		echo "#include <db4/db_185.h>" > aicdb.h;	\
+	 elif [ -e "/usr/include/db3/db_185.h" ]; then		\
 		echo "#include <db3/db_185.h>" > aicdb.h;	\
 	 elif [ -e "/usr/include/db2/db_185.h" ]; then		\
 		echo "#include <db2/db_185.h>" > aicdb.h;	\
diff -urN linux-2.4.22-pre2/drivers/scsi/gdth.c linux-2.4.22-pre3/drivers/scsi/gdth.c
--- linux-2.4.22-pre2/drivers/scsi/gdth.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/scsi/gdth.c	2003-07-05 18:10:41.000000000 -0700
@@ -4029,6 +4029,8 @@
             break;
         if (gdth_search_isa(isa_bios)) {        /* controller found */
             shp = scsi_register(shtp,sizeof(gdth_ext_str));
+            if(shp == NULL)
+            	continue;
             ha = HADATA(shp);
             if (!gdth_init_isa(isa_bios,ha)) {
                 scsi_unregister(shp);
diff -urN linux-2.4.22-pre2/drivers/scsi/ide-scsi.c linux-2.4.22-pre3/drivers/scsi/ide-scsi.c
--- linux-2.4.22-pre2/drivers/scsi/ide-scsi.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/scsi/ide-scsi.c	2003-07-05 18:10:41.000000000 -0700
@@ -1105,15 +1105,34 @@
 
 int idescsi_reset (Scsi_Cmnd *cmd, unsigned int resetflags)
 {
+	return SCSI_RESET_SNOOZE;
+
+#ifdef WORK_IN_PROGRESS
 	ide_drive_t *drive	= idescsi_drives[cmd->target];
 
-	/* We cannot reset the interface holding the lock. We can
-	   drop the lock here however */
+	/* At this point the state machine is running, that
+	   requires we are especially careful. Ideally we want
+	   to abort commands on timeout only if they hit the
+	   cable but thats harder */
+
+	DRIVER(drive)->abort(drive, "scsi reset");
+	if(HWGROUP(drive)->handler)
+		BUG();
+	
+	/* Ok the state machine is halted but make sure it
+	   doesn't restart too early */ 
 	   
-	spin_unlock(&io_request_lock);
-	(void) ide_do_reset(drive);
-	spin_lock(&io_request_lock);
+	HWGROUP(drive)->busy = 1;
+	spin_unlock_irq(&io_request_lock);
+	
+	/* Apply the mallet of re-education firmly to the drive */
+	ide_do_reset(drive);
+
+	/* At this point the reset state machine is running and
+	   its termination will kick off the next command */	
+	spin_lock_irq(&io_request_lock);
 	return SCSI_RESET_SUCCESS;
+#endif	
 }
 
 int idescsi_bios (Disk *disk, kdev_t dev, int *parm)
diff -urN linux-2.4.22-pre2/drivers/scsi/megaraid.c linux-2.4.22-pre3/drivers/scsi/megaraid.c
--- linux-2.4.22-pre2/drivers/scsi/megaraid.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/scsi/megaraid.c	2003-07-05 18:10:41.000000000 -0700
@@ -4924,8 +4924,10 @@
 
 		if( !scsicmd->result && outlen ) {
 			if (copy_to_user(uaddr, kvaddr, length))
+			{
 				ret = -EFAULT;
 				goto out;
+			}
 		}
 
 		/*
diff -urN linux-2.4.22-pre2/drivers/scsi/scsi.c linux-2.4.22-pre3/drivers/scsi/scsi.c
--- linux-2.4.22-pre2/drivers/scsi/scsi.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/scsi.c	2003-07-05 18:10:41.000000000 -0700
@@ -197,6 +197,7 @@
 
 	blk_init_queue(q, scsi_request_fn);
 	blk_queue_headactive(q, 0);
+	blk_queue_throttle_sectors(q, 1);
 	q->queuedata = (void *) SDpnt;
 }
 
diff -urN linux-2.4.22-pre2/drivers/scsi/scsi_ioctl.c linux-2.4.22-pre3/drivers/scsi/scsi_ioctl.c
--- linux-2.4.22-pre2/drivers/scsi/scsi_ioctl.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/scsi/scsi_ioctl.c	2003-07-05 18:10:41.000000000 -0700
@@ -279,6 +279,7 @@
 		cmd[1] = (cmd[1] & 0x1f) | (dev->lun << 5);
 
 	switch (opcode) {
+	case SEND_DIAGNOSTIC:
 	case FORMAT_UNIT:
 		timeout = FORMAT_UNIT_TIMEOUT;
 		retries = 1;
diff -urN linux-2.4.22-pre2/drivers/scsi/scsi_lib.c linux-2.4.22-pre3/drivers/scsi/scsi_lib.c
--- linux-2.4.22-pre2/drivers/scsi/scsi_lib.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/scsi/scsi_lib.c	2003-07-05 18:10:41.000000000 -0700
@@ -378,6 +378,7 @@
 		if ((bh = req->bh) != NULL) {
 			nsect = bh->b_size >> 9;
 			blk_finished_io(nsect);
+			blk_finished_sectors(req, nsect);
 			req->bh = bh->b_reqnext;
 			bh->b_reqnext = NULL;
 			sectors -= nsect;
diff -urN linux-2.4.22-pre2/drivers/scsi/scsi_scan.c linux-2.4.22-pre3/drivers/scsi/scsi_scan.c
--- linux-2.4.22-pre2/drivers/scsi/scsi_scan.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/scsi/scsi_scan.c	2003-07-05 18:10:42.000000000 -0700
@@ -112,9 +112,9 @@
 	{"HP", "C1750A", "3226", BLIST_NOLUN},			/* scanjet iic */
 	{"HP", "C1790A", "", BLIST_NOLUN},			/* scanjet iip */
 	{"HP", "C2500A", "", BLIST_NOLUN},			/* scanjet iicx */
-	{"HP", "A6188A", "*", BLIST_SPARSELUN},			/* HP Va7100 Array */
-	{"HP", "A6189A", "*", BLIST_SPARSELUN},			/* HP Va7400 Array */
-	{"HP", "A6189B", "*", BLIST_SPARSELUN},			/* HP Va7410 Array */
+	{"HP", "A6188A", "*", BLIST_SPARSELUN | BLIST_LARGELUN},/* HP Va7100 Array */
+	{"HP", "A6189A", "*", BLIST_SPARSELUN | BLIST_LARGELUN},/* HP Va7400 Array */
+	{"HP", "A6189B", "*", BLIST_SPARSELUN | BLIST_LARGELUN},/* HP Va7410 Array */
 	{"YAMAHA", "CDR100", "1.00", BLIST_NOLUN},		/* Locks up if polled for lun != 0 */
 	{"YAMAHA", "CDR102", "1.00", BLIST_NOLUN},		/* Locks up if polled for lun != 0  
 								 * extra reset */
@@ -187,7 +187,7 @@
 	{"HITACHI", "DF500", "*", BLIST_SPARSELUN},
 	{"HITACHI", "DF600", "*", BLIST_SPARSELUN},
 	{"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"HITACHI", "OPEN-", "*", BLIST_SPARSELUN},		/* HITACHI XP Arrays */
+	{"HITACHI", "OPEN-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},  /* HITACHI XP Arrays */
 	{"WINSYS","FLASHDISK G6", "*", BLIST_SPARSELUN},
 	{"DotHill","SANnet RAID X300", "*", BLIST_SPARSELUN},	
 	{"SUN", "T300", "*", BLIST_SPARSELUN},
@@ -199,6 +199,10 @@
 	{"SGI", "TP9400", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"SGI", "TP9500", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"MYLEX", "DACARMRB", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"PLATYPUS", "CX5", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"Raidtec", "FCR", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"HP", "C7200", "*", BLIST_SPARSELUN},			/* Medium Changer */
+	{"SMSC", "USB 2 HS", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, 
 	{"XYRATEX", "RS", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 
 	/*
diff -urN linux-2.4.22-pre2/drivers/scsi/seagate.c linux-2.4.22-pre3/drivers/scsi/seagate.c
--- linux-2.4.22-pre2/drivers/scsi/seagate.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/seagate.c	2003-07-05 18:10:42.000000000 -0700
@@ -324,6 +324,8 @@
 	{"FUTURE DOMAIN TMC-950", 5, 21, FD},
 	/* Added for 2.2.16 by Matthias_Heidbrink@b.maus.de */
 	{"IBM F1 V1.2009/22/93", 5, 25, FD},
+	/* Added for Dell Latitude XP 4100CX */
+	{"Future Domain Corp. V1.0008/18/9364/32", 5, 38, FD},
 };
 
 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
diff -urN linux-2.4.22-pre2/drivers/scsi/st.c linux-2.4.22-pre3/drivers/scsi/st.c
--- linux-2.4.22-pre2/drivers/scsi/st.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/st.c	2003-07-05 18:10:43.000000000 -0700
@@ -9,10 +9,10 @@
    Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky,
    Michael Schaefer, J"org Weule, and Eric Youngdale.
 
-   Copyright 1992 - 2002 Kai Makisara
-   email Kai.Makisara@metla.fi
+   Copyright 1992 - 2003 Kai Makisara
+   email Kai.Makisara@kolumbus.fi
 
-   Last modified: Mon Aug  5 22:54:13 2002 by makisara
+   Last modified: Sun Apr  6 22:44:42 2003 by makisara
    Some small formal changes - aeb, 950809
 
    Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
@@ -21,7 +21,7 @@
    error handling will be discarded.
  */
 
-static char *verstr = "20020805";
+static char *verstr = "20030406";
 
 #include <linux/module.h>
 
@@ -72,7 +72,6 @@
 #include "constants.h"
 
 static int buffer_kbs;
-static int write_threshold_kbs;
 static int max_buffers = (-1);
 static int max_sg_segs;
 static int blocking_open = ST_BLOCKING_OPEN;
@@ -84,8 +83,6 @@
 
 MODULE_PARM(buffer_kbs, "i");
 MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size (KB; 32)");
-MODULE_PARM(write_threshold_kbs, "i");
-MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 30)");
 MODULE_PARM(max_buffers, "i");
 MODULE_PARM_DESC(max_buffers, "Maximum number of buffer allocated at initialisation (4)");
 MODULE_PARM(max_sg_segs, "i");
@@ -103,8 +100,8 @@
 	{
 		"buffer_kbs", &buffer_kbs
 	},
-	{
-		"write_threshold_kbs", &write_threshold_kbs
+	{	/* Retained for compatibility */
+		"write_threshold_kbs", NULL
 	},
 	{
 		"max_buffers", &max_buffers
@@ -122,7 +119,6 @@
 /* The default definitions have been moved to st_options.h */
 
 #define ST_BUFFER_SIZE (ST_BUFFER_BLOCKS * ST_KILOBYTE)
-#define ST_WRITE_THRESHOLD (ST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
 
 /* The buffer size should fit into the 24 bits for length in the
    6-byte SCSI read and write commands. */
@@ -153,7 +149,6 @@
 static int st_nbr_buffers;
 static ST_buffer **st_buffers = NULL;
 static int st_buffer_size = ST_BUFFER_SIZE;
-static int st_write_threshold = ST_WRITE_THRESHOLD;
 static int st_max_buffers = ST_MAX_BUFFERS;
 static int st_max_sg_segs = ST_MAX_SG;
 
@@ -167,6 +162,7 @@
 static int set_sg_lengths(ST_buffer *, unsigned int);
 static int append_to_buffer(const char *, ST_buffer *, int);
 static int from_buffer(ST_buffer *, char *, int);
+static void move_buffer_data(ST_buffer *, int);
 
 static int st_init(void);
 static int st_attach(Scsi_Device *);
@@ -1196,6 +1192,7 @@
 	ssize_t total;
 	ssize_t i, do_count, blks, transfer;
 	ssize_t retval = 0;
+	int residual, retry_eot = 0, scode;
 	int write_threshold;
 	int doing_write = 0;
 	unsigned char cmd[MAX_COMMAND_SIZE];
@@ -1367,7 +1364,7 @@
 		write_threshold = 1;
 	} else
 		write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
-	if (!STm->do_async_writes)
+	if (!STm->do_async_writes || STp->block_size > 0)
 		write_threshold--;
 
 	total = count;
@@ -1381,7 +1378,7 @@
 	b_point = buf;
 	while ((STp->block_size == 0 && !STm->do_async_writes && count > 0) ||
 	       (STp->block_size != 0 &&
-		(STp->buffer)->buffer_bytes + count > write_threshold)) {
+		(STp->buffer)->buffer_bytes + count > write_threshold && !retry_eot)) {
 		doing_write = 1;
 		if (STp->block_size == 0)
 			do_count = count;
@@ -1398,6 +1395,7 @@
 			goto out;
 		}
 
+	retry_write:
 		if (STp->block_size == 0)
 			blks = transfer = do_count;
 		else {
@@ -1420,46 +1418,66 @@
                         DEBC(printk(ST_DEB_MSG "st%d: Error on write:\n", dev));
 			if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
 			    (SRpnt->sr_sense_buffer[2] & 0x40)) {
+				scode = SRpnt->sr_sense_buffer[2] & 0x0f;
 				if ((SRpnt->sr_sense_buffer[0] & 0x80) != 0)
-					transfer = (SRpnt->sr_sense_buffer[3] << 24) |
+					residual = (SRpnt->sr_sense_buffer[3] << 24) |
 					    (SRpnt->sr_sense_buffer[4] << 16) |
 					    (SRpnt->sr_sense_buffer[5] << 8) |
                                                 SRpnt->sr_sense_buffer[6];
 				else if (STp->block_size == 0 &&
-					 (SRpnt->sr_sense_buffer[2] & 0x0f) ==
-                                         VOLUME_OVERFLOW)
-					transfer = do_count;
+					 scode == VOLUME_OVERFLOW)
+					residual = do_count;
 				else
-					transfer = 0;
+					residual = 0;
 				if (STp->block_size != 0)
-					transfer *= STp->block_size;
-				if (transfer <= do_count) {
-					filp->f_pos += do_count - transfer;
-					count -= do_count - transfer;
+					residual *= STp->block_size;
+				if (residual <= do_count) {
+					/* Within the data in this write() */
+					filp->f_pos += do_count - residual;
+					count -= do_count - residual;
 					if (STps->drv_block >= 0) {
 						if (STp->block_size == 0 &&
-                                                    transfer < do_count)
+						    residual < do_count)
 							STps->drv_block++;
 						else if (STp->block_size != 0)
 							STps->drv_block +=
-                                                                (do_count - transfer) /
+								(transfer - residual) /
                                                                 STp->block_size;
 					}
 					STps->eof = ST_EOM_OK;
 					retval = (-ENOSPC); /* EOM within current request */
                                         DEBC(printk(ST_DEB_MSG
                                                        "st%d: EOM with %d bytes unwritten.\n",
-						       dev, transfer));
+						       dev, count));
 				} else {
-					STps->eof = ST_EOM_ERROR;
-					STps->drv_block = (-1); /* Too cautious? */
-					retval = (-EIO);	/* EOM for old data */
-					DEBC(printk(ST_DEB_MSG
-                                                       "st%d: EOM with lost data.\n",
-                                                       dev));
+					/* EOT in within data buffered earlier */
+					if (!retry_eot && (SRpnt->sr_sense_buffer[0] & 1) == 0 &&
+					    (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
+						move_buffer_data(STp->buffer, transfer - residual);
+						retry_eot = TRUE;
+						if (STps->drv_block >= 0) {
+							STps->drv_block += (transfer - residual) /
+								STp->block_size;
+						}
+						STps->eof = ST_EOM_OK;
+						DEBC(printk(ST_DEB_MSG
+							    "st%d: Retry write of %d bytes at EOM.\n",
+							    dev, do_count));
+						goto retry_write;
+					}
+					else {
+						/* Either error within data buffered by driver or failed retry */
+						STps->eof = ST_EOM_ERROR;
+						STps->drv_block = (-1); /* Too cautious? */
+						retval = (-EIO);	/* EOM for old data */
+						DEBC(printk(ST_DEB_MSG
+							    "st%d: EOM with lost data.\n",
+							    dev));
+					}
 				}
 			} else {
 				STps->drv_block = (-1);		/* Too cautious? */
+				retry_eot = FALSE;
 				retval = (-EIO);
 			}
 
@@ -1483,7 +1501,7 @@
 		(STp->buffer)->buffer_bytes = 0;
 		STp->dirty = 0;
 	}
-	if (count != 0) {
+	if (count != 0 && !retry_eot) {
 		STp->dirty = 1;
 		i = append_to_buffer(b_point, STp->buffer, count);
 		if (i) {
@@ -1499,26 +1517,14 @@
 		goto out;
 	}
 
-	if (STm->do_async_writes &&
-	    (((STp->buffer)->buffer_bytes >= STp->write_threshold &&
-	      (STp->buffer)->buffer_bytes >= STp->block_size) ||
-	     STp->block_size == 0)) {
+	if (STm->do_async_writes && STp->block_size == 0) {
 		/* Schedule an asynchronous write */
-		if (STp->block_size == 0)
-			(STp->buffer)->writing = (STp->buffer)->buffer_bytes;
-		else
-			(STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
-				      STp->block_size) * STp->block_size;
-		STp->dirty = !((STp->buffer)->writing ==
-			       (STp->buffer)->buffer_bytes);
-
-		if (STp->block_size == 0)
-			blks = (STp->buffer)->writing;
-		else
-			blks = (STp->buffer)->writing / STp->block_size;
-		cmd[2] = blks >> 16;
-		cmd[3] = blks >> 8;
-		cmd[4] = blks;
+		(STp->buffer)->writing = (STp->buffer)->buffer_bytes;
+		STp->dirty = FALSE;
+		residual = (STp->buffer)->writing;
+		cmd[2] = residual >> 16;
+		cmd[3] = residual >> 8;
+		cmd[4] = residual;
 		DEB( STp->write_pending = 1; )
 
 		SRpnt = st_do_scsi(SRpnt, STp, cmd, (STp->buffer)->writing,
@@ -1532,9 +1538,9 @@
 
 	}
 	STps->at_sm &= (total == 0);
-	if (total > 0)
+	if (total > 0 && !retry_eot)
 		STps->eof = ST_NOEOF;
-	retval = total;
+	retval = total - count;
 
  out:
 	if (SRpnt != NULL)
@@ -1625,9 +1631,14 @@
 
 				if (SRpnt->sr_sense_buffer[2] & 0x20) {	/* ILI */
 					if (STp->block_size == 0) {
-						if (transfer < 0) {
+						if (transfer <= 0) {
+							if (transfer < 0)
+								printk(KERN_NOTICE
+								       "st%d: Failed to read %d byte block with %d byte read.\n",
+								       dev, bytes - transfer, bytes);
 							if (STps->drv_block >= 0)
 								STps->drv_block += 1;
+							(STp->buffer)->buffer_bytes = 0;
 							return (-ENOMEM);
 						}
 						(STp->buffer)->buffer_bytes = bytes - transfer;
@@ -1694,6 +1705,9 @@
 				} else	/* Some other extended sense code */
 					retval = (-EIO);
 			}
+
+			if ((STp->buffer)->buffer_bytes < 0) /* Caused by bogus sense data */
+				(STp->buffer)->buffer_bytes = 0;
 		}
 		/* End of extended sense test */ 
 		else {		/* Non-extended sense */
@@ -2004,16 +2018,7 @@
 			debugging = value; )
 		st_log_options(STp, STm, dev);
 	} else if (code == MT_ST_WRITE_THRESHOLD) {
-		value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
-		if (value < 1 || value > st_buffer_size) {
-			printk(KERN_WARNING
-                               "st%d: Write threshold %d too small or too large.\n",
-			       dev, value);
-			return (-EIO);
-		}
-		STp->write_threshold = value;
-		printk(KERN_INFO "st%d: Write threshold set to %d bytes.\n",
-		       dev, value);
+		/* Retained for compatibility */
 	} else if (code == MT_ST_DEF_BLKSIZE) {
 		value = (options & ~MT_ST_OPTIONS);
 		if (value == ~MT_ST_OPTIONS) {
@@ -2155,7 +2160,7 @@
 
 /* Send the mode page in the tape buffer to the drive. Assumes that the mode data
    in the buffer is correctly formatted. */
-static int write_mode_page(Scsi_Tape *STp, int page)
+static int write_mode_page(Scsi_Tape *STp, int page, int slow)
 {
 	int pgo;
 	unsigned char cmd[MAX_COMMAND_SIZE];
@@ -2174,7 +2179,7 @@
 	(STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
 
 	SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE,
-			   STp->timeout, 0, TRUE);
+			   (slow ? STp->long_timeout : STp->timeout), 0, TRUE);
 	if (SRpnt == NULL)
 		return (STp->buffer)->syscall_result;
 
@@ -2241,7 +2246,7 @@
 			b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
 	}
 
-	retval = write_mode_page(STp, COMPRESSION_PAGE);
+	retval = write_mode_page(STp, COMPRESSION_PAGE, FALSE);
 	if (retval) {
                 DEBC(printk(ST_DEB_MSG "st%d: Compression change failed.\n", dev));
 		return (-EIO);
@@ -3055,7 +3060,7 @@
 	bp[pgo + PP_OFF_RESERVED] = 0;
 	bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
 
-	result = write_mode_page(STp, PART_PAGE);
+	result = write_mode_page(STp, PART_PAGE, TRUE);
 	if (result) {
 		printk(KERN_INFO "st%d: Partitioning of tape failed.\n", dev);
 		result = (-EIO);
@@ -3644,6 +3649,50 @@
 }
 
 
+/* Move data towards start of buffer */
+static void move_buffer_data(ST_buffer * st_bp, int offset)
+{
+	int src_seg, dst_seg, src_offset = 0, dst_offset;
+	int count, total;
+
+	if (offset == 0)
+		return;
+
+	total=st_bp->buffer_bytes - offset;
+	for (src_seg=0; src_seg < st_bp->sg_segs; src_seg++) {
+		src_offset = offset;
+		if (src_offset < st_bp->sg_lengths[src_seg])
+			break;
+		offset -= st_bp->sg_lengths[src_seg];
+	}
+	if (src_seg == st_bp->sg_segs) {	/* Should never happen */
+		printk(KERN_WARNING "st: zap_buffer offset overflow.\n");
+		return;
+	}
+
+	st_bp->buffer_bytes = st_bp->read_pointer = total;
+	for (dst_seg=dst_offset=0; total > 0; ) {
+		count = min(st_bp->sg_lengths[dst_seg] - dst_offset,
+			    st_bp->sg_lengths[src_seg] - src_offset);
+		memmove(st_bp->sg[dst_seg].address + dst_offset,
+			st_bp->sg[src_seg].address + src_offset, count);
+		printk("st: move (%d,%d) -> (%d,%d) count %d\n",
+		       src_seg, src_offset, dst_seg, dst_offset, count);
+		src_offset += count;
+		if (src_offset >= st_bp->sg_lengths[src_seg]) {
+			src_seg++;
+			src_offset = 0;
+		}
+		dst_offset += count;
+		if (dst_offset >= st_bp->sg_lengths[dst_seg]) {
+			dst_seg++;
+			dst_offset = 0;
+		}
+		total -= count;
+	}
+}
+
+
 /* Set the scatter/gather list length fields to sum up to the transfer length.
    Return the number of segments being used. */
 static int set_sg_lengths(ST_buffer *st_bp, unsigned int length)
@@ -3668,15 +3717,6 @@
 {
 	if (buffer_kbs > 0)
 		st_buffer_size = buffer_kbs * ST_KILOBYTE;
-	if (write_threshold_kbs > 0)
-		st_write_threshold = write_threshold_kbs * ST_KILOBYTE;
-	else if (buffer_kbs > 0)
-		st_write_threshold = st_buffer_size - 2048;
-	if (st_write_threshold > st_buffer_size) {
-		st_write_threshold = st_buffer_size;
-		printk(KERN_WARNING "st: write_threshold limited to %d bytes.\n",
-		       st_write_threshold);
-	}
 	if (max_buffers >= 0)
 		st_max_buffers = max_buffers;
 	if (max_sg_segs >= ST_FIRST_SG)
@@ -3695,13 +3735,15 @@
 
 	if (ints[0] > 0) {
 		for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
-			*parms[i].val = ints[i + 1];
+			if (parms[i].val)
+				*parms[i].val = ints[i + 1];
 	} else {
 		while (stp != NULL) {
 			for (i = 0; i < ARRAY_SIZE(parms); i++) {
 				len = strlen(parms[i].name);
 				if (!strncmp(stp, parms[i].name, len) &&
-				    (*(stp + len) == ':' || *(stp + len) == '=')) {
+				    (*(stp + len) == ':' || *(stp + len) == '=') &&
+				    parms[i].val) {
 					*parms[i].val =
                                                 simple_strtoul(stp + len + 1, NULL, 0);
 					break;
@@ -3863,7 +3905,6 @@
 	tpnt->fast_mteom = ST_FAST_MTEOM;
 	tpnt->scsi2_logical = ST_SCSI2LOGICAL;
 	tpnt->immediate = ST_NOWAIT;
-	tpnt->write_threshold = st_write_threshold;
 	tpnt->default_drvbuffer = 0xff;		/* No forced buffering */
 	tpnt->partition = 0;
 	tpnt->new_partition = 0;
@@ -3941,8 +3982,8 @@
 		return 0;
 
 	printk(KERN_INFO
-	       "st: Version %s, bufsize %d, wrt %d, max init. bufs %d, s/g segs %d\n",
-	       verstr, st_buffer_size, st_write_threshold, st_max_buffers, st_max_sg_segs);
+	       "st: Version %s, bufsize %d, max init. bufs %d, s/g segs %d\n",
+	       verstr, st_buffer_size, st_max_buffers, st_max_sg_segs);
 
 	write_lock_irqsave(&st_dev_arr_lock, flags);
 	if (!st_registered) {
diff -urN linux-2.4.22-pre2/drivers/scsi/st.h linux-2.4.22-pre3/drivers/scsi/st.h
--- linux-2.4.22-pre2/drivers/scsi/st.h	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/st.h	2003-07-05 18:10:43.000000000 -0700
@@ -86,7 +86,6 @@
 	unsigned char use_pf;			/* Set Page Format bit in all mode selects? */
 	unsigned char c_algo;	     /* compression algorithm */
 	int tape_type;
-	int write_threshold;
 	int timeout;		/* timeout for normal commands */
 	int long_timeout;	/* timeout for commands known to take long time */
 
diff -urN linux-2.4.22-pre2/drivers/scsi/st_options.h linux-2.4.22-pre3/drivers/scsi/st_options.h
--- linux-2.4.22-pre2/drivers/scsi/st_options.h	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/scsi/st_options.h	2003-07-05 18:10:43.000000000 -0700
@@ -1,9 +1,9 @@
 /*
    The compile-time configurable defaults for the Linux SCSI tape driver.
 
-   Copyright 1995-2002 Kai Makisara.
+   Copyright 1995-2003 Kai Makisara.
 
-   Last modified: Wed May  1 11:06:47 2002 by makisara
+   Last modified: Sun Apr  6 22:45:15 2003 by makisara
 */
 
 #ifndef _ST_OPTIONS_H
@@ -33,11 +33,6 @@
 /* The tape driver buffer size in kilobytes. Must be non-zero. */
 #define ST_BUFFER_BLOCKS 32
 
-/* The number of kilobytes of data in the buffer that triggers an
-   asynchronous write in fixed block mode. See also ST_ASYNC_WRITES
-   below. */
-#define ST_WRITE_THRESHOLD_BLOCKS 30
-
 /* The maximum number of tape buffers the driver tries to allocate at 
    driver initialisation. The number is also constrained by the number
    of drives detected. If more buffers are needed, they are allocated
diff -urN linux-2.4.22-pre2/drivers/sound/ac97_codec.c linux-2.4.22-pre3/drivers/sound/ac97_codec.c
--- linux-2.4.22-pre2/drivers/sound/ac97_codec.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/ac97_codec.c	2003-07-05 18:10:43.000000000 -0700
@@ -1,4 +1,3 @@
-
 /*
  * ac97_codec.c: Generic AC97 mixer/modem module
  *
@@ -31,6 +30,10 @@
  **************************************************************************
  *
  * History
+ * May 02, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ *	Removed non existant WM9700
+ *	Added support for WM9705, WM9708, WM9709, WM9710, WM9711
+ *	WM9712 and WM9717
  * Mar 28, 2002 Randolph Bentson <bentson@holmsjoen.com>
  *	corrections to support WM9707 in ViewPad 1000
  * v0.4 Mar 15 2000 Ollie Lho
@@ -45,6 +48,7 @@
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/bitops.h>
@@ -63,9 +67,10 @@
 
 static int ac97_init_mixer(struct ac97_codec *codec);
 
-static int wolfson_init00(struct ac97_codec * codec);
 static int wolfson_init03(struct ac97_codec * codec);
 static int wolfson_init04(struct ac97_codec * codec);
+static int wolfson_init05(struct ac97_codec * codec);
+static int wolfson_init11(struct ac97_codec * codec);
 static int tritech_init(struct ac97_codec * codec);
 static int tritech_maestro_init(struct ac97_codec * codec);
 static int sigmatel_9708_init(struct ac97_codec *codec);
@@ -73,9 +78,10 @@
 static int sigmatel_9744_init(struct ac97_codec *codec);
 static int ad1886_init(struct ac97_codec *codec);
 static int eapd_control(struct ac97_codec *codec, int);
-static int crystal_digital_control(struct ac97_codec *codec, int mode);
+static int crystal_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
 static int cmedia_init(struct ac97_codec * codec);
-static int cmedia_digital_control(struct ac97_codec *codec, int mode);
+static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
+static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
 
 
 /*
@@ -96,9 +102,11 @@
  
 static struct ac97_ops null_ops = { NULL, NULL, NULL };
 static struct ac97_ops default_ops = { NULL, eapd_control, NULL };
-static struct ac97_ops wolfson_ops00 = { wolfson_init00, NULL, NULL };
+static struct ac97_ops default_digital_ops = { NULL, eapd_control, generic_digital_control};
 static struct ac97_ops wolfson_ops03 = { wolfson_init03, NULL, NULL };
 static struct ac97_ops wolfson_ops04 = { wolfson_init04, NULL, NULL };
+static struct ac97_ops wolfson_ops05 = { wolfson_init05, NULL, NULL };
+static struct ac97_ops wolfson_ops11 = { wolfson_init11, NULL, NULL };
 static struct ac97_ops tritech_ops = { tritech_init, NULL, NULL };
 static struct ac97_ops tritech_m_ops = { tritech_maestro_init, NULL, NULL };
 static struct ac97_ops sigmatel_9708_ops = { sigmatel_9708_init, NULL, NULL };
@@ -126,8 +134,9 @@
 	{0x414B4D00, "Asahi Kasei AK4540",	&null_ops},
 	{0x414B4D01, "Asahi Kasei AK4542",	&null_ops},
 	{0x414B4D02, "Asahi Kasei AK4543",	&null_ops},
+	{0x414C4326, "ALC100P",			&null_ops},
 	{0x414C4710, "ALC200/200P",		&null_ops},
-	{0x414C4720, "ALC650",			&null_ops},
+	{0x414C4720, "ALC650",			&default_digital_ops},
 	{0x434D4941, "CMedia",			&cmedia_ops,		AC97_NO_PCM_VOLUME },
 	{0x434D4942, "CMedia",			&cmedia_ops,		AC97_NO_PCM_VOLUME },
 	{0x434D4961, "CMedia",			&cmedia_digital_ops,	AC97_NO_PCM_VOLUME },
@@ -154,9 +163,11 @@
 	{0x54524106, "TriTech TR28026",		&null_ops},
 	{0x54524108, "TriTech TR28028",		&tritech_ops},
 	{0x54524123, "TriTech TR A5",		&null_ops},
-	{0x574D4C00, "Wolfson WM9700A",		&wolfson_ops00},
-	{0x574D4C03, "Wolfson WM9703/WM9707",	&wolfson_ops03},
+	{0x574D4C03, "Wolfson WM9703/07/08/17",	&wolfson_ops03},
 	{0x574D4C04, "Wolfson WM9704M/WM9704Q",	&wolfson_ops04},
+	{0x574D4C05, "Wolfson WM9705/WM9710",   &wolfson_ops05},
+	{0x574D4C09, "Wolfson WM9709",		&null_ops},
+	{0x574D4C12, "Wolfson WM9711/9712",	&wolfson_ops11},
 	{0x83847600, "SigmaTel STAC????",	&null_ops},
 	{0x83847604, "SigmaTel STAC9701/3/4/5", &null_ops},
 	{0x83847605, "SigmaTel STAC9704",	&null_ops},
@@ -282,6 +293,10 @@
 	[SOUND_MIXER_PHONEIN] 	= AC97_REC_PHONE
 };
 
+static LIST_HEAD(codecs);
+static LIST_HEAD(codec_drivers);
+static DECLARE_MUTEX(codec_sem);
+
 /* reads the given OSS mixer from the ac97 the caller must have insured that the ac97 knows
    about that given mixer, and should be holding a spinlock for the card */
 static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel) 
@@ -709,6 +724,56 @@
 
 
 /**
+ *	ac97_alloc_codec - Allocate an AC97 codec
+ *
+ *	Returns a new AC97 codec structure. AC97 codecs may become
+ *	refcounted soon so this interface is needed. Returns with
+ *	one reference taken.
+ */
+ 
+struct ac97_codec *ac97_alloc_codec(void)
+{
+	struct ac97_codec *codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL);
+	if(!codec)
+		return NULL;
+
+	memset(codec, 0, sizeof(*codec));
+	spin_lock_init(&codec->lock);
+	INIT_LIST_HEAD(&codec->list);
+	list_add(&codec->list, &codecs);
+	return codec;
+}
+
+EXPORT_SYMBOL(ac97_alloc_codec);
+
+/**
+ *	ac97_release_codec -	Release an AC97 codec
+ *	@codec: codec to release
+ *
+ *	Release an allocated AC97 codec. This will be refcounted in
+ *	time but for the moment is trivial. Calls the unregister
+ *	handler if the codec is now defunct.
+ */
+ 
+void ac97_release_codec(struct ac97_codec *codec)
+{
+	/* Remove from the list first, we don't want to be
+	   "rediscovered" */
+	down(&codec_sem);
+	list_del(&codec->list);
+	up(&codec_sem);
+	/*
+	 *	The driver needs to deal with internal
+	 *	locking to avoid accidents here. 
+	 */
+	if(codec->driver)
+		codec->driver->remove(codec, codec->driver);
+	kfree(codec);
+}
+
+EXPORT_SYMBOL(ac97_release_codec);
+
+/**
  *	ac97_probe_codec - Initialize and setup AC97-compatible codec
  *	@codec: (in/out) Kernel info for a single AC97 codec
  *
@@ -737,7 +802,10 @@
 	u16 audio;
 	int i;
 	char cidbuf[CODEC_ID_BUFSZ];
-
+	u16 f;
+	struct list_head *l;
+	struct ac97_driver *d;
+	
 	/* probing AC97 codec, AC97 2.0 says that bit 15 of register 0x00 (reset) should 
 	 * be read zero.
 	 *
@@ -762,7 +830,7 @@
 	/* probe for Modem Codec */
 	codec->modem = ac97_check_modem(codec);
 	codec->name = NULL;
-	codec->codec_ops = &null_ops;
+	codec->codec_ops = &default_ops;
 
 	id1 = codec->codec_read(codec, AC97_VENDOR_ID1);
 	id2 = codec->codec_read(codec, AC97_VENDOR_ID2);
@@ -775,6 +843,12 @@
 			break;
 		}
 	}
+
+	codec->model = (id1 << 16) | id2;
+	
+	f = codec->codec_read(codec, AC97_EXTENDED_STATUS);
+	if(f & 4)
+		codec->codec_ops = &default_digital_ops;
 	
 	/* A device which thinks its a modem but isnt */
 	if(codec->flags & AC97_DELUDED_MODEM)
@@ -786,7 +860,29 @@
 		codec->modem ? "Modem" : (audio ? "Audio" : ""),
 	       codec_id(id1, id2, cidbuf), codec->name);
 
-	return ac97_init_mixer(codec);
+	if(!ac97_init_mixer(codec))
+		return 0;
+		
+	/* 
+	 *	Attach last so the caller can override the mixer
+	 *	callbacks.
+	 */
+	 
+	down(&codec_sem);
+
+	list_for_each(l, &codec_drivers) {
+		d = list_entry(l, struct ac97_driver, list);
+		if ((codec->model ^ d->codec_id) & d->codec_mask)
+			continue;
+		if(d->probe(codec, d) == 0)
+		{
+			codec->driver = d;
+			break;
+		}
+	}
+
+	up(&codec_sem);
+	return 1;
 }
 
 static int ac97_init_mixer(struct ac97_codec *codec)
@@ -805,8 +901,6 @@
 	if (!(cap & 0x10))
 		codec->supported_mixers &= ~SOUND_MASK_ALTPCM;
 
-	if(codec->flags & AC97_NO_PCM_VOLUME)
-		codec->supported_mixers &= ~SOUND_MASK_PCM;
 
 	/* detect bit resolution */
 	codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0x2020);
@@ -836,8 +930,15 @@
 		ac97_set_mixer(codec, md->mixer, md->value);
 	}
 
+	/*
+	 *	Volume is MUTE only on this device. We have to initialise
+	 *	it but its useless beyond that.
+	 */
 	if(codec->flags & AC97_NO_PCM_VOLUME)
+	{
+		codec->supported_mixers &= ~SOUND_MASK_PCM;
 		printk(KERN_WARNING "AC97 codec does not have proper volume support.\n");
+	}
 	return 1;
 }
 
@@ -933,53 +1034,52 @@
 	return 0;
 }
 	
-static int wolfson_init00(struct ac97_codec * codec)
-{
-	/* This initialization is suspect, but not known to be wrong.
-	   It was copied from the initialization for the WM9704Q, but
-	   that same sequence is known to fail for the WM9707.  Thus
-	   this warning may help someone with hardware to test
-	   this code. */
-	codec->codec_write(codec, 0x72, 0x0808);
-	codec->codec_write(codec, 0x74, 0x0808);
-
-	// patch for DVD noise
-	codec->codec_write(codec, 0x5a, 0x0200);
-
-	// init vol as PCM vol
-	codec->codec_write(codec, 0x70,
-		codec->codec_read(codec, AC97_PCMOUT_VOL));
-
-	codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);
-	return 0;
-}
-
+#define AC97_WM97XX_FMIXER_VOL 0x72
+#define AC97_WM97XX_RMIXER_VOL 0x74
+#define AC97_WM97XX_TEST 0x5a
+#define AC97_WM9704_RPCM_VOL 0x70
+#define AC97_WM9711_OUT3VOL 0x16
 
 static int wolfson_init03(struct ac97_codec * codec)
 {
 	/* this is known to work for the ViewSonic ViewPad 1000 */
-	codec->codec_write(codec, 0x72, 0x0808);
-	codec->codec_write(codec, 0x20, 0x8000);
+	codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808);
+	codec->codec_write(codec, AC97_GENERAL_PURPOSE, 0x8000);
 	return 0;
 }
 
-
 static int wolfson_init04(struct ac97_codec * codec)
 {
-	codec->codec_write(codec, 0x72, 0x0808);
-	codec->codec_write(codec, 0x74, 0x0808);
+	codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808);
+	codec->codec_write(codec, AC97_WM97XX_RMIXER_VOL, 0x0808);
 
 	// patch for DVD noise
-	codec->codec_write(codec, 0x5a, 0x0200);
+	codec->codec_write(codec, AC97_WM97XX_TEST, 0x0200);
 
 	// init vol as PCM vol
-	codec->codec_write(codec, 0x70,
+	codec->codec_write(codec, AC97_WM9704_RPCM_VOL,
 		codec->codec_read(codec, AC97_PCMOUT_VOL));
 
+	/* set rear surround volume */
 	codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);
 	return 0;
 }
 
+/* WM9705, WM9710 */
+static int wolfson_init05(struct ac97_codec * codec)
+{
+	/* set front mixer volume */
+	codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808);
+	return 0;
+}
+
+/* WM9711, WM9712 */
+static int wolfson_init11(struct ac97_codec * codec)
+{
+	/* set out3 volume */
+	codec->codec_write(codec, AC97_WM9711_OUT3VOL, 0x0808);
+	return 0;
+}
 
 static int tritech_init(struct ac97_codec * codec)
 {
@@ -1040,21 +1140,78 @@
 	return 0;
 }
 
+static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode)
+{
+	u16 reg;
+	
+	reg = codec->codec_read(codec, AC97_SPDIF_CONTROL);
+	
+	switch(rate)
+	{
+		/* Off by default */
+		default:
+		case 0:
+			reg = codec->codec_read(codec, AC97_EXTENDED_STATUS);
+			codec->codec_write(codec, AC97_EXTENDED_STATUS, (reg & ~AC97_EA_SPDIF));
+			if(rate == 0)
+				return 0;
+			return -EINVAL;
+		case 1:
+			reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_48K;
+			break;
+		case 2:
+			reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_44K;
+			break;
+		case 3:
+			reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_32K;
+			break;
+	}
+	
+	reg &= ~AC97_SC_CC_MASK;
+	reg |= (mode & AUDIO_CCMASK) << 6;
+	
+	if(mode & AUDIO_DIGITAL)
+		reg |= 2;
+	if(mode & AUDIO_PRO)
+		reg |= 1;
+	if(mode & AUDIO_DRS)
+		reg |= 0x4000;
+
+	codec->codec_write(codec, AC97_SPDIF_CONTROL, reg);
+
+	reg = codec->codec_read(codec, AC97_EXTENDED_STATUS);
+	reg &= (AC97_EA_SLOT_MASK);
+	reg |= AC97_EA_VRA | AC97_EA_SPDIF | slots;
+	codec->codec_write(codec, AC97_EXTENDED_STATUS, reg);
+	
+	reg = codec->codec_read(codec, AC97_EXTENDED_STATUS);
+	if(!(reg & 0x0400))
+	{
+		codec->codec_write(codec, AC97_EXTENDED_STATUS, reg & ~ AC97_EA_SPDIF);
+		return -EINVAL;
+	}
+	return 0;
+}
+
 /*
- *	Crystal digital audio control (CS4299
+ *	Crystal digital audio control (CS4299)
  */
  
-static int crystal_digital_control(struct ac97_codec *codec, int mode)
+static int crystal_digital_control(struct ac97_codec *codec, int slots, int rate, int mode)
 {
 	u16 cv;
 
-	switch(mode)
+	if(mode & AUDIO_DIGITAL)
+		return -EINVAL;
+		
+	switch(rate)
 	{
 		case 0: cv = 0x0; break;	/* SPEN off */
-		case 1: cv = 0x8004; break;	/* 48KHz digital */
-		case 2: cv = 0x8104; break;	/* 44.1KHz digital */
+		case 48000: cv = 0x8004; break;	/* 48KHz digital */
+		case 44100: cv = 0x8104; break;	/* 44.1KHz digital */
+		case 32768: 			/* 32Khz */
 		default:
-			return -1;		/* Not supported yet(eg AC3) */
+			return -EINVAL;
 	}
 	codec->codec_write(codec, 0x68, cv);
 	return 0;
@@ -1065,16 +1222,19 @@
  *	Needs more work.
  */
  
-static int cmedia_digital_control(struct ac97_codec *codec, int mode)
+static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode)
 {
 	u16 cv;
 
-	switch(mode)
+	if(mode & AUDIO_DIGITAL)
+		return -EINVAL;
+		
+	switch(rate)
 	{
-		case 0: cv = 0x0001; break;	/* SPEN off */
-		case 1: cv = 0x0009; break;	/* 48KHz digital */
+		case 0:		cv = 0x0001; break;	/* SPEN off */
+		case 48000:	cv = 0x0009; break;	/* 48KHz digital */
 		default:
-			return -1;		/* Not supported yet(eg AC3) */
+			return -EINVAL;
 	}
 	codec->codec_write(codec, 0x2A, 0x05c4);
 	codec->codec_write(codec, 0x6C, cv);
@@ -1226,4 +1386,67 @@
 
 EXPORT_SYMBOL(ac97_restore_state);
 
+/**
+ *	ac97_register_driver	-	register a codec helper
+ *	@driver: Driver handler
+ *
+ *	Register a handler for codecs matching the codec id. The handler
+ *	attach function is called for all present codecs and will be 
+ *	called when new codecs are discovered.
+ */
+ 
+int ac97_register_driver(struct ac97_driver *driver)
+{
+	struct list_head *l;
+	struct ac97_codec *c;
+	
+	down(&codec_sem);
+	INIT_LIST_HEAD(&driver->list);
+	list_add(&driver->list, &codec_drivers);
+	
+	list_for_each(l, &codecs)
+	{
+		c = list_entry(l, struct ac97_codec, list);
+		if(c->driver != NULL || ((c->model ^ driver->codec_id) & driver->codec_mask))
+			continue;
+		if(driver->probe(c, driver))
+			continue;
+		c->driver = driver;
+	}
+	up(&codec_sem);
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(ac97_register_driver);
+
+/**
+ *	ac97_unregister_driver	-	unregister a codec helper
+ *	@driver: Driver handler
+ *
+ *	Register a handler for codecs matching the codec id. The handler
+ *	attach function is called for all present codecs and will be 
+ *	called when new codecs are discovered.
+ */
+ 
+void ac97_unregister_driver(struct ac97_driver *driver)
+{
+	struct list_head *l;
+	struct ac97_codec *c;
+	
+	down(&codec_sem);
+	list_del_init(&driver->list);
+	
+	list_for_each(l, &codecs)
+	{
+		c = list_entry(l, struct ac97_codec, list);
+		if(c->driver == driver)
+			driver->remove(c, driver);
+		c->driver = NULL;
+	}
+	
+	up(&codec_sem);
+}
+
+EXPORT_SYMBOL_GPL(ac97_unregister_driver);
+	
 MODULE_LICENSE("GPL");
diff -urN linux-2.4.22-pre2/drivers/sound/ad1889.c linux-2.4.22-pre3/drivers/sound/ad1889.c
--- linux-2.4.22-pre2/drivers/sound/ad1889.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/ad1889.c	2003-07-05 18:10:43.000000000 -0700
@@ -257,7 +257,7 @@
 		return;
 
 	if (dev->ac97_codec)
-		kfree(dev->ac97_codec);
+		ac97_release_codec(dev->ac97_codec);
 
 	for (j = 0; j < AD_MAX_STATES; j++) {
 		dmabuf = &dev->state[j].dmabuf;
@@ -831,9 +831,8 @@
 	struct ac97_codec *ac97;
 	u16 eid;
 
-	if ((ac97 = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL) 
+	if ((ac97 = ac97_alloc_codec()) == NULL) 
 		return -ENOMEM;
-	memset(ac97, 0, sizeof(struct ac97_codec));
 
 	ac97->private_data = dev;
 	ac97->id = id;
@@ -863,7 +862,7 @@
 	return 0;
 
 out_free:
-	kfree(ac97);
+	ac97_release_codec(ac97);
 	return -ENODEV;
 }
 
diff -urN linux-2.4.22-pre2/drivers/sound/ali5455.c linux-2.4.22-pre3/drivers/sound/ali5455.c
--- linux-2.4.22-pre2/drivers/sound/ali5455.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/sound/ali5455.c	2003-07-05 18:10:44.000000000 -0700
@@ -306,6 +306,7 @@
 	/* The ali has a certain amount of cross channel interaction
 	   so we use a single per card lock */
 	spinlock_t lock;
+	spinlock_t ac97_lock;
 
 	/* PCI device stuff */
 	struct pci_dev *pci_dev;
@@ -2950,6 +2951,7 @@
 	char val;
 	unsigned short int data, count, addr1, addr2;
 
+	spin_lock(&card->ac97_lock);
 	while (count1-- && (inl(card->iobase + ALI_CAS) & 0x80000000))
 		udelay(1);
 
@@ -2961,7 +2963,10 @@
 			break;
 	}
 	if (count == 0x7f)
+	{
+		spin_unlock(&card->ac97_lock);
 		return -1;
+	}
 	outw(reg, (card->iobase + ALI_CPR) + 2);
 	for (count = 0; count < 0x7f; count++) {
 		val = inb(card->iobase + ALI_CSPSR);
@@ -2971,6 +2976,7 @@
 			break;
 		}
 	}
+	spin_unlock(&card->ac97_lock);
 	if (count == 0x7f)
 		return -1;
 	if (addr2 != addr1)
@@ -2988,6 +2994,7 @@
 	char val;
 	unsigned short int count;
 
+	spin_lock(&card->ac97_lock);
 	while (count1-- && (inl(card->iobase + ALI_CAS) & 0x80000000))
 		udelay(1);
 
@@ -2997,7 +3004,8 @@
 			break;
 	}
 	if (count == 0x7f) {
-		printk(KERN_WARNING "ali_ac96_set: AC97 codec register access timed out. \n");
+		printk(KERN_WARNING "ali_ac97_set: AC97 codec register access timed out. \n");
+		spin_unlock(&card->ac97_lock);
 		return;
 	}
 	outw(data, (card->iobase + ALI_CPR));
@@ -3007,10 +3015,9 @@
 		if (val & 0x01)
 			break;
 	}
-	if (count == 0x7f) {
-		printk(KERN_WARNING "ali_ac96_set: AC97 codec register access timed out. \n");
-		return;
-	}
+	spin_unlock(&card->ac97_lock);
+	if (count == 0x7f)
+		printk(KERN_WARNING "ali_ac97_set: AC97 codec register access timed out. \n");
 	return;
 }
 
@@ -3257,9 +3264,8 @@
 			break;
 		}
 
-		if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
+		if ((codec = ac97_alloc_codec()) == NULL)
 			return -ENOMEM;
-		memset(codec, 0, sizeof(struct ac97_codec));
 		/* initialize some basic codec information, other fields will be filled
 		   in ac97_probe_codec */
 		codec->private_data = card;
@@ -3277,7 +3283,7 @@
 		card->ac97_status = 0;
 		/* Don't attempt to get eid until powerup is complete */
 		eid = ali_ac97_get(codec, AC97_EXTENDED_ID);
-		if (eid == 0xFFFFFF) {
+		if (eid == 0xFFFF) {
 			printk(KERN_ERR "ali_audio: no codec attached ?\n");
 			kfree(codec);
 			break;
@@ -3427,6 +3433,7 @@
 	card->pm_suspended = 0;
 #endif
 	spin_lock_init(&card->lock);
+	spin_lock_init(&card->ac97_lock);
 	devs = card;
 	pci_set_master(pci_dev);
 	printk(KERN_INFO "ali: %s found at IO 0x%04lx, IRQ %d\n",
@@ -3516,7 +3523,7 @@
 		if (card->ac97_codec[i] != NULL) {
 			unregister_sound_mixer(card->ac97_codec[i]->
 					       dev_mixer);
-			kfree(card->ac97_codec[i]);
+			ac97_release_codec(card->ac97_codec[i]);
 			card->ac97_codec[i] = NULL;
 		}
 	unregister_sound_dsp(card->dev_audio);
diff -urN linux-2.4.22-pre2/drivers/sound/au1000.c linux-2.4.22-pre3/drivers/sound/au1000.c
--- linux-2.4.22-pre2/drivers/sound/au1000.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/sound/au1000.c	2003-07-05 18:10:44.000000000 -0700
@@ -117,7 +117,7 @@
 	struct proc_dir_entry *ac97_ps;
 #endif				/* AU1000_DEBUG */
 
-	struct ac97_codec codec;
+	struct ac97_codec *codec;
 	unsigned        codec_base_caps;// AC'97 reg 00h, "Reset Register"
 	unsigned        codec_ext_caps;	// AC'97 reg 28h, "Extended Audio ID"
 	int             no_vra;	// do not use VRA
@@ -357,17 +357,17 @@
 
 	adc->src_factor = 1;
 
-	ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
+	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
 
 	rate = rate > 48000 ? 48000 : rate;
 
 	// enable VRA
-	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+	wrcodec(s->codec, AC97_EXTENDED_STATUS,
 		ac97_extstat | AC97_EXTSTAT_VRA);
 	// now write the sample rate
-	wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
+	wrcodec(s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
 	// read it back for actual supported rate
-	adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
+	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
 
 #ifdef AU1000_VERBOSE_DEBUG
 	dbg(__FUNCTION__ ": set to %d Hz", adc_rate);
@@ -375,11 +375,11 @@
 
 	// some codec's don't allow unequal DAC and ADC rates, in which case
 	// writing one rate reg actually changes both.
-	dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
+	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
 	if (dac->num_channels > 2)
-		wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
+		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
 	if (dac->num_channels > 4)
-		wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
+		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
 
 	adc->sample_rate = adc_rate;
 	dac->sample_rate = dac_rate;
@@ -402,23 +402,23 @@
 
 	dac->src_factor = 1;
 
-	ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
+	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
 
 	rate = rate > 48000 ? 48000 : rate;
 
 	// enable VRA
-	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+	wrcodec(s->codec, AC97_EXTENDED_STATUS,
 		ac97_extstat | AC97_EXTSTAT_VRA);
 	// now write the sample rate
-	wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
+	wrcodec(s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
 	// I don't support different sample rates for multichannel,
 	// so make these channels the same.
 	if (dac->num_channels > 2)
-		wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
+		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
 	if (dac->num_channels > 4)
-		wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
+		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
 	// read it back for actual supported rate
-	dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
+	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
 
 #ifdef AU1000_VERBOSE_DEBUG
 	dbg(__FUNCTION__ ": set to %d Hz", dac_rate);
@@ -426,7 +426,7 @@
 
 	// some codec's don't allow unequal DAC and ADC rates, in which case
 	// writing one rate reg actually changes both.
-	adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
+	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
 
 	dac->sample_rate = dac_rate;
 	adc->sample_rate = adc_rate;
@@ -905,7 +905,7 @@
 			       unsigned int cmd, unsigned long arg)
 {
 	struct au1000_state *s = (struct au1000_state *)file->private_data;
-	struct ac97_codec *codec = &s->codec;
+	struct ac97_codec *codec = s->codec;
 
 	return mixdev_ioctl(codec, cmd, arg);
 }
@@ -1504,9 +1504,9 @@
 			s->dma_dac.num_channels = val ? 2 : 1;
 			if (s->codec_ext_caps & AC97_EXT_DACS) {
 				// disable surround and center/lfe in AC'97
-				u16 ext_stat = rdcodec(&s->codec,
+				u16 ext_stat = rdcodec(s->codec,
 						       AC97_EXTENDED_STATUS);
-				wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+				wrcodec(s->codec, AC97_EXTENDED_STATUS,
 					ext_stat | (AC97_EXTSTAT_PRI |
 						    AC97_EXTSTAT_PRJ |
 						    AC97_EXTSTAT_PRK));
@@ -1556,9 +1556,9 @@
 					// disable surround and center/lfe
 					// channels in AC'97
 					u16             ext_stat =
-						rdcodec(&s->codec,
+						rdcodec(s->codec,
 							AC97_EXTENDED_STATUS);
-					wrcodec(&s->codec,
+					wrcodec(s->codec,
 						AC97_EXTENDED_STATUS,
 						ext_stat | (AC97_EXTSTAT_PRI |
 							    AC97_EXTSTAT_PRJ |
@@ -1567,14 +1567,14 @@
 					// enable surround, center/lfe
 					// channels in AC'97
 					u16             ext_stat =
-						rdcodec(&s->codec,
+						rdcodec(s->codec,
 							AC97_EXTENDED_STATUS);
 					ext_stat &= ~AC97_EXTSTAT_PRJ;
 					if (val == 6)
 						ext_stat &=
 							~(AC97_EXTSTAT_PRI |
 							  AC97_EXTSTAT_PRK);
-					wrcodec(&s->codec,
+					wrcodec(s->codec,
 						AC97_EXTENDED_STATUS,
 						ext_stat);
 				}
@@ -1836,7 +1836,7 @@
 		return -EINVAL;
 	}
 
-	return mixdev_ioctl(&s->codec, cmd, arg);
+	return mixdev_ioctl(s->codec, cmd, arg);
 }
 
 
@@ -1987,7 +1987,7 @@
 	len += sprintf(buf + len, "----------------------\n");
 	for (cnt = 0; cnt <= 0x7e; cnt += 2)
 		len += sprintf(buf + len, "reg %02x = %04x\n",
-			       cnt, rdcodec(&s->codec, cnt));
+			       cnt, rdcodec(s->codec, cnt));
 
 	if (fpos >= len) {
 		*start = buf;
@@ -2023,16 +2023,23 @@
 	init_waitqueue_head(&s->open_wait);
 	init_MUTEX(&s->open_sem);
 	spin_lock_init(&s->lock);
-	s->codec.private_data = s;
-	s->codec.id = 0;
-	s->codec.codec_read = rdcodec;
-	s->codec.codec_write = wrcodec;
-	s->codec.codec_wait = waitcodec;
+	
+	s->codec = ac97_alloc_codec();
+	if(s->codec == NULL)
+	{
+		error("Out of memory");
+		return -1;
+	}
+	s->codec->private_data = s;
+	s->codec->id = 0;
+	s->codec->codec_read = rdcodec;
+	s->codec->codec_write = wrcodec;
+	s->codec->codec_wait = waitcodec;
 
 	if (!request_region(virt_to_phys((void *) AC97C_CONFIG),
 			    0x14, AU1000_MODULE_NAME)) {
 		err("AC'97 ports in use");
-		return -1;
+		goto err_codec;
 	}
 	// Allocate the DMA Channels
 	if ((s->dma_dac.dmanr = request_au1000_dma(DMA_ID_AC97C_TX,
@@ -2072,7 +2079,7 @@
 
 	if ((s->dev_audio = register_sound_dsp(&au1000_audio_fops, -1)) < 0)
 		goto err_dev1;
-	if ((s->codec.dev_mixer =
+	if ((s->codec->dev_mixer =
 	     register_sound_mixer(&au1000_mixer_fops, -1)) < 0)
 		goto err_dev2;
 
@@ -2105,11 +2112,11 @@
 	au_writel(0, AC97C_CONFIG);
 
 	/* codec init */
-	if (!ac97_probe_codec(&s->codec))
+	if (!ac97_probe_codec(s->codec))
 		goto err_dev3;
 
-	s->codec_base_caps = rdcodec(&s->codec, AC97_RESET);
-	s->codec_ext_caps = rdcodec(&s->codec, AC97_EXTENDED_ID);
+	s->codec_base_caps = rdcodec(s->codec, AC97_RESET);
+	s->codec_ext_caps = rdcodec(s->codec, AC97_EXTENDED_ID);
 	info("AC'97 Base/Extended ID = %04x/%04x",
 	     s->codec_base_caps, s->codec_ext_caps);
 
@@ -2121,12 +2128,12 @@
 	 * ALTPCM). ac97_codec.c does not handle detection
 	 * of this channel correctly.
 	 */
-	s->codec.supported_mixers |= SOUND_MASK_ALTPCM;
+	s->codec->supported_mixers |= SOUND_MASK_ALTPCM;
 	/*
 	 * Now set AUX_OUT's default volume.
 	 */
 	val = 0x4343;
-	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_ALTPCM,
+	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_ALTPCM,
 		     (unsigned long) &val);
 	
 	if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
@@ -2134,8 +2141,8 @@
 		s->no_vra = 1;
 	} else if (!vra) {
 		// Boot option says disable VRA
-		u16 ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
-		wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+		u16 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
+		wrcodec(s->codec, AC97_EXTENDED_STATUS,
 			ac97_extstat & ~AC97_EXTSTAT_VRA);
 		s->no_vra = 1;
 	}
@@ -2144,20 +2151,20 @@
 
 	/* set mic to be the recording source */
 	val = SOUND_MASK_MIC;
-	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
+	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
 		     (unsigned long) &val);
 
 #ifdef AU1000_DEBUG
 	sprintf(proc_str, "driver/%s/%d/ac97", AU1000_MODULE_NAME,
-		s->codec.id);
+		s->codec->id);
 	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
-					     ac97_read_proc, &s->codec);
+					     ac97_read_proc, s->codec);
 #endif
 
 	return 0;
 
  err_dev3:
-	unregister_sound_mixer(s->codec.dev_mixer);
+	unregister_sound_mixer(s->codec->dev_mixer);
  err_dev2:
 	unregister_sound_dsp(s->dev_audio);
  err_dev1:
@@ -2166,6 +2173,8 @@
 	free_au1000_dma(s->dma_dac.dmanr);
  err_dma1:
 	release_region(virt_to_phys((void *) AC97C_CONFIG), 0x14);
+ err_codec:
+ 	ac97_release_codec(s->codec);
 	return -1;
 }
 
@@ -2184,7 +2193,8 @@
 	free_au1000_dma(s->dma_dac.dmanr);
 	release_region(virt_to_phys((void *) AC97C_CONFIG), 0x14);
 	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->codec.dev_mixer);
+	unregister_sound_mixer(s->codec->dev_mixer);
+	ac97_release_codec(s->codec);
 }
 
 static int __init init_au1000(void)
diff -urN linux-2.4.22-pre2/drivers/sound/awe_wave.c linux-2.4.22-pre3/drivers/sound/awe_wave.c
--- linux-2.4.22-pre2/drivers/sound/awe_wave.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/awe_wave.c	2003-07-05 18:10:44.000000000 -0700
@@ -2059,18 +2059,15 @@
 		awe_reset(dev);
 		awe_reset_samples();
 		return 0;
-		break;
 
 	case SNDCTL_SEQ_PERCMODE:
 		/* what's this? */
 		return 0;
-		break;
 
 	case SNDCTL_SYNTH_MEMAVL:
 		return memsize - awe_free_mem_ptr() * 2;
 
 	default:
-		printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd);
 		return -EINVAL;
 	}
 }
diff -urN linux-2.4.22-pre2/drivers/sound/cmpci.c linux-2.4.22-pre3/drivers/sound/cmpci.c
--- linux-2.4.22-pre2/drivers/sound/cmpci.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/cmpci.c	2003-07-05 18:10:44.000000000 -0700
@@ -580,15 +580,17 @@
 	spin_unlock_irqrestore(&s->lock, flags);
 }
 
-static void trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
+static int trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
 {
 	int   i = size / 2;
 	unsigned long data;
 	unsigned long *dst = (unsigned long *) dest;
 	unsigned short *src = (unsigned short *)source;
+	int err;
 
 	do {
-		__get_user(data, src);
+		if ((err = __get_user(data, src)))
+			return err;
 		src++;
 		data <<= 12;			// ok for 16-bit data
 		if (s->spdif_counter == 2 || s->spdif_counter == 3)
@@ -606,6 +608,8 @@
 		if (s->spdif_counter == 384)
 			s->spdif_counter = 0;
 	} while (--i);
+
+	return 0;
 }
 
 static void set_adc_rate_unlocked(struct cm_state *s, unsigned rate)
@@ -1655,13 +1659,16 @@
 			continue;
 		}
 		if (s->status & DO_AC3_SW) {
+			int err;
+
 			// clip exceeded data, caught by 033 and 037
 			if (swptr + 2 * cnt > s->dma_dac.dmasize)
 				cnt = (s->dma_dac.dmasize - swptr) / 2;
-			trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt);
+			if ((err = trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt)))
+				return err;
 			swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize;
 		} else if (s->status & DO_DUAL_DAC) {
-			int	i;
+			int	i, err;
 			unsigned long *src, *dst0, *dst1;
 
 			src = (unsigned long *) buffer;
@@ -1669,8 +1676,10 @@
 			dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr);
 			// copy left/right sample at one time
 			for (i = 0; i <= cnt / 4; i++) {
-				*dst0++ = *src++;
-				*dst1++ = *src++;
+				if ((err = __get_user(*dst0++, src++)))
+					return err;
+				if ((err = __get_user(*dst1++, src++)))
+					return err;
 			}
 			swptr = (swptr + cnt) % s->dma_dac.dmasize;
 		} else {
diff -urN linux-2.4.22-pre2/drivers/sound/cs46xx.c linux-2.4.22-pre3/drivers/sound/cs46xx.c
--- linux-2.4.22-pre2/drivers/sound/cs46xx.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/cs46xx.c	2003-07-05 18:10:45.000000000 -0700
@@ -312,6 +312,9 @@
 	/* The cs461x has a certain amount of cross channel interaction
 	   so we use a single per card lock */
 	spinlock_t lock;
+	
+	/* Keep AC97 sane */
+	spinlock_t ac97_lock;
 
 	/* mixer use count */
 	atomic_t mixer_use_cnt;
@@ -947,8 +950,8 @@
 
 struct InitStruct
 {
-    u32 long off;
-    u32 long val;
+    u32 off;
+    u32 val;
 } InitArray[] = { {0x00000040, 0x3fc0000f},
                   {0x0000004c, 0x04800000},
 
@@ -3823,11 +3826,12 @@
 /* Write AC97 codec registers */
 
 
-static u16 cs_ac97_get(struct ac97_codec *dev, u8 reg)
+static u16 _cs_ac97_get(struct ac97_codec *dev, u8 reg)
 {
 	struct cs_card *card = dev->private_data;
 	int count,loopcnt;
 	unsigned int tmp;
+	u16 ret;
 	
 	/*
 	 *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
@@ -3838,7 +3842,6 @@
 	 *  6. Read ACSTS = Status Register = 464h, check VSTS bit
 	 */
 
-
 	cs461x_peekBA0(card, BA0_ACSDA);
 
 	/*
@@ -3929,7 +3932,19 @@
 		"cs46xx: cs_ac97_get() reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", 
 			reg, cs461x_peekBA0(card, BA0_ACSDA),
 			cs461x_peekBA0(card, BA0_ACCAD)));
-	return(cs461x_peekBA0(card, BA0_ACSDA));
+	ret = cs461x_peekBA0(card, BA0_ACSDA);
+	return ret;
+}
+
+static u16 cs_ac97_get(struct ac97_codec *dev, u8 reg)
+{
+	u16 ret;
+	struct cs_card *card = dev->private_data;
+	
+	spin_lock(&card->ac97_lock);
+	ret = _cs_ac97_get(dev, reg);
+	spin_unlock(&card->ac97_lock);
+	return ret;
 }
 
 static void cs_ac97_set(struct ac97_codec *dev, u8 reg, u16 val)
@@ -3938,11 +3953,14 @@
 	int count;
 	int val2 = 0;
 	
+	spin_lock(&card->ac97_lock);
+	
 	if(reg == AC97_CD_VOL)
 	{
-		val2 = cs_ac97_get(dev, AC97_CD_VOL);
+		val2 = _cs_ac97_get(dev, AC97_CD_VOL);
 	}
 	
+	
 	/*
 	 *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
 	 *  2. Write ACCDA = Command Data Register = 470h    for data to write to AC97
@@ -3990,6 +4008,8 @@
 			"cs46xx: AC'97 write problem, reg = 0x%x, val = 0x%x\n", reg, val));
 	}
 
+	spin_unlock(&card->ac97_lock);
+
 	/*
 	 *	Adjust power if the mixer is selected/deselected according
 	 *	to the CD.
@@ -4235,7 +4255,7 @@
 		"cs46xx: cs_ac97_init()+\n") );
 
 	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-		if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
+		if ((codec = ac97_alloc_codec()) == NULL)
 			return -ENOMEM;
 		memset(codec, 0, sizeof(struct ac97_codec));
 
@@ -4260,10 +4280,10 @@
 
 		eid = cs_ac97_get(codec, AC97_EXTENDED_ID);
 		
-		if(eid==0xFFFFFF)
+		if(eid==0xFFFF)
 		{
 			printk(KERN_WARNING "cs46xx: codec %d not present\n",num_ac97);
-			kfree(codec);
+			ac97_release_codec(codec);
 			break;
 		}
 		
@@ -4271,7 +4291,7 @@
 			
 		if ((codec->dev_mixer = register_sound_mixer(&cs_mixer_fops, -1)) < 0) {
 			printk(KERN_ERR "cs46xx: couldn't register mixer!\n");
-			kfree(codec);
+			ac97_release_codec(codec);
 			break;
 		}
 		card->ac97_codec[num_ac97] = codec;
@@ -5311,6 +5331,7 @@
 	card->irq = pci_dev->irq;
 	card->magic = CS_CARD_MAGIC;
 	spin_lock_init(&card->lock);
+	spin_lock_init(&card->ac97_lock);
 
 	pci_set_master(pci_dev);
 
@@ -5438,7 +5459,7 @@
 			for (j = 0; j < NR_AC97; j++)
 				if (card->ac97_codec[j] != NULL) {
 					unregister_sound_mixer(card->ac97_codec[j]->dev_mixer);
-					kfree (card->ac97_codec[j]);
+					ac97_release_codec(card->ac97_codec[j]);
 				}
 			mdelay(10 * cs_laptop_wait);
 			continue;
@@ -5595,7 +5616,7 @@
 	for (i = 0; i < NR_AC97; i++)
 		if (card->ac97_codec[i] != NULL) {
 			unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
-			kfree (card->ac97_codec[i]);
+			ac97_release_codec(card->ac97_codec[i]);
 		}
 	unregister_sound_dsp(card->dev_audio);
         if(card->dev_midi)
diff -urN linux-2.4.22-pre2/drivers/sound/emu10k1/efxmgr.c linux-2.4.22-pre3/drivers/sound/emu10k1/efxmgr.c
--- linux-2.4.22-pre2/drivers/sound/emu10k1/efxmgr.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/emu10k1/efxmgr.c	2003-07-05 18:10:45.000000000 -0700
@@ -101,10 +101,10 @@
 {
 	extern char volume_params[SOUND_MIXER_NRDEVICES];
 
-	card->ac97.mixer_state[oss_mixer] = (right << 8) | left;
+	card->ac97->mixer_state[oss_mixer] = (right << 8) | left;
 
 	if (!card->is_aps)
-		card->ac97.write_mixer(&card->ac97, oss_mixer, left, right);
+		card->ac97->write_mixer(card->ac97, oss_mixer, left, right);
 	
 	emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][0], left,
 			       volume_params[oss_mixer]);
@@ -125,7 +125,7 @@
 		right = (val >> 8) & 0xff;
 		val = 0;
 	} else {
-		val = card->ac97.mixer_state[oss_channel];
+		val = card->ac97->mixer_state[oss_channel];
 		left = 0;
 		right = 0;
 	}
@@ -138,8 +138,8 @@
 	int oss_channel = VOLCTRL_CHANNEL;
 	int left, right;
 
-	left = card->ac97.mixer_state[oss_channel] & 0xff;
-	right = (card->ac97.mixer_state[oss_channel] >> 8) & 0xff;
+	left = card->ac97->mixer_state[oss_channel] & 0xff;
+	right = (card->ac97->mixer_state[oss_channel] >> 8) & 0xff;
 
 	if ((left += VOLCTRL_STEP_SIZE) > 100)
 		left = 100;
@@ -155,8 +155,8 @@
 	int oss_channel = VOLCTRL_CHANNEL;
 	int left, right;
 
-	left = card->ac97.mixer_state[oss_channel] & 0xff;
-	right = (card->ac97.mixer_state[oss_channel] >> 8) & 0xff;
+	left = card->ac97->mixer_state[oss_channel] & 0xff;
+	right = (card->ac97->mixer_state[oss_channel] >> 8) & 0xff;
 
 	if ((left -= VOLCTRL_STEP_SIZE) < 0)
 		left = 0;
diff -urN linux-2.4.22-pre2/drivers/sound/emu10k1/hwaccess.h linux-2.4.22-pre3/drivers/sound/emu10k1/hwaccess.h
--- linux-2.4.22-pre2/drivers/sound/emu10k1/hwaccess.h	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/sound/emu10k1/hwaccess.h	2003-07-05 18:10:45.000000000 -0700
@@ -162,7 +162,7 @@
 	struct emu10k1_mididevice *seq_mididev;
 #endif
 
-	struct ac97_codec ac97;
+	struct ac97_codec *ac97;
 	int ac97_supported_mixers;
 	int ac97_stereo_mixers;
 
diff -urN linux-2.4.22-pre2/drivers/sound/emu10k1/main.c linux-2.4.22-pre3/drivers/sound/emu10k1/main.c
--- linux-2.4.22-pre2/drivers/sound/emu10k1/main.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/sound/emu10k1/main.c	2003-07-05 18:10:45.000000000 -0700
@@ -224,21 +224,31 @@
 {
 	char s[32];
 
-	struct ac97_codec *codec = &card->ac97;
-	card->ac97.dev_mixer = register_sound_mixer(&emu10k1_mixer_fops, -1);
-	if (card->ac97.dev_mixer < 0) {
-		printk(KERN_ERR "emu10k1: cannot register mixer device\n");
+	struct ac97_codec *codec  = ac97_alloc_codec();
+	
+	if(codec == NULL)
+	{
+		printk(KERN_ERR "emu10k1: cannot allocate mixer\n");
 		return -EIO;
+	}
+	card->ac97 = codec;
+	
+#warning "Initialisation order race. Must register after usable"
+
+	card->ac97->dev_mixer = register_sound_mixer(&emu10k1_mixer_fops, -1);
+	if (card->ac97->dev_mixer < 0) {
+		printk(KERN_ERR "emu10k1: cannot register mixer device\n");
+		goto err_codec;
         }
 
-	card->ac97.private_data = card;
+	card->ac97->private_data = card;
 
 	if (!card->is_aps) {
-		card->ac97.id = 0;
-		card->ac97.codec_read = emu10k1_ac97_read;
-        	card->ac97.codec_write = emu10k1_ac97_write;
+		card->ac97->id = 0;
+		card->ac97->codec_read = emu10k1_ac97_read;
+        	card->ac97->codec_write = emu10k1_ac97_write;
 
-		if (ac97_probe_codec (&card->ac97) == 0) {
+		if (ac97_probe_codec (card->ac97) == 0) {
 			printk(KERN_ERR "emu10k1: unable to probe AC97 codec\n");
 			goto err_out;
 		}
@@ -250,7 +260,7 @@
 		}
 
 		// Force 5bit:		    
-		//card->ac97.bit_resolution=5;
+		//card->ac97->bit_resolution=5;
 
 		if (!proc_mkdir ("driver/emu10k1", 0)) {
 			printk(KERN_ERR "emu10k1: unable to create proc directory driver/emu10k1\n");
@@ -264,14 +274,14 @@
 		}
 	
 		sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name);
-		if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, &card->ac97)) {
+		if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, card->ac97)) {
 			printk(KERN_ERR "emu10k1: unable to create proc entry %s\n", s);
 			goto err_ac97_proc;
 		}
 
 		/* these will store the original values and never be modified */
-		card->ac97_supported_mixers = card->ac97.supported_mixers;
-		card->ac97_stereo_mixers = card->ac97.stereo_mixers;
+		card->ac97_supported_mixers = card->ac97->supported_mixers;
+		card->ac97_stereo_mixers = card->ac97->stereo_mixers;
 	}
 
 	return 0;
@@ -283,7 +293,9 @@
  err_emu10k1_proc:
 	remove_proc_entry("driver/emu10k1", NULL);
  err_out:
-	unregister_sound_mixer (card->ac97.dev_mixer);
+	unregister_sound_mixer (card->ac97->dev_mixer);
+ err_codec:
+ 	ac97_release_codec(card->ac97);
 	return -EIO;
 }
 
@@ -301,7 +313,8 @@
 		remove_proc_entry("driver/emu10k1", NULL);
 	}
 
-	unregister_sound_mixer (card->ac97.dev_mixer);
+	unregister_sound_mixer (card->ac97->dev_mixer);
+	ac97_release_codec(card->ac97);
 }
 
 static int __devinit emu10k1_midi_init(struct emu10k1_card *card)
@@ -695,21 +708,21 @@
 	mgr->ctrl_gpr[SOUND_MIXER_VOLUME][0] = 8;
 	mgr->ctrl_gpr[SOUND_MIXER_VOLUME][1] = 9;
 
-	left = card->ac97.mixer_state[SOUND_MIXER_VOLUME] & 0xff;
-	right = (card->ac97.mixer_state[SOUND_MIXER_VOLUME] >> 8) & 0xff;
+	left = card->ac97->mixer_state[SOUND_MIXER_VOLUME] & 0xff;
+	right = (card->ac97->mixer_state[SOUND_MIXER_VOLUME] >> 8) & 0xff;
 
-	emu10k1_set_volume_gpr(card, 8, left, 1 << card->ac97.bit_resolution);
-	emu10k1_set_volume_gpr(card, 9, right, 1 << card->ac97.bit_resolution);
+	emu10k1_set_volume_gpr(card, 8, left, 1 << card->ac97->bit_resolution);
+	emu10k1_set_volume_gpr(card, 9, right, 1 << card->ac97->bit_resolution);
 
 	//Rear volume
 	mgr->ctrl_gpr[ SOUND_MIXER_OGAIN ][0] = 0x19;
 	mgr->ctrl_gpr[ SOUND_MIXER_OGAIN ][1] = 0x1a;
 
 	left = right = 67;
-	card->ac97.mixer_state[SOUND_MIXER_OGAIN] = (right << 8) | left;
+	card->ac97->mixer_state[SOUND_MIXER_OGAIN] = (right << 8) | left;
 
-	card->ac97.supported_mixers |= SOUND_MASK_OGAIN;
-	card->ac97.stereo_mixers |= SOUND_MASK_OGAIN;
+	card->ac97->supported_mixers |= SOUND_MASK_OGAIN;
+	card->ac97->stereo_mixers |= SOUND_MASK_OGAIN;
 
 	emu10k1_set_volume_gpr(card, 0x19, left, VOL_5BIT);
 	emu10k1_set_volume_gpr(card, 0x1a, right, VOL_5BIT);
@@ -718,8 +731,8 @@
 	mgr->ctrl_gpr[SOUND_MIXER_PCM][0] = 6;
 	mgr->ctrl_gpr[SOUND_MIXER_PCM][1] = 7;
 
-	left = card->ac97.mixer_state[SOUND_MIXER_PCM] & 0xff;
-	right = (card->ac97.mixer_state[SOUND_MIXER_PCM] >> 8) & 0xff;
+	left = card->ac97->mixer_state[SOUND_MIXER_PCM] & 0xff;
+	right = (card->ac97->mixer_state[SOUND_MIXER_PCM] >> 8) & 0xff;
 
 	emu10k1_set_volume_gpr(card, 6, left, VOL_5BIT);
 	emu10k1_set_volume_gpr(card, 7, right, VOL_5BIT);
@@ -729,22 +742,22 @@
 	mgr->ctrl_gpr[SOUND_MIXER_DIGITAL1][1] = 0xf;
 
 	left = right = 67;
-	card->ac97.mixer_state[SOUND_MIXER_DIGITAL1] = (right << 8) | left; 
+	card->ac97->mixer_state[SOUND_MIXER_DIGITAL1] = (right << 8) | left; 
 
-	card->ac97.supported_mixers |= SOUND_MASK_DIGITAL1;
-	card->ac97.stereo_mixers |= SOUND_MASK_DIGITAL1;
+	card->ac97->supported_mixers |= SOUND_MASK_DIGITAL1;
+	card->ac97->stereo_mixers |= SOUND_MASK_DIGITAL1;
 
 	emu10k1_set_volume_gpr(card, 0xd, left, VOL_5BIT);
 	emu10k1_set_volume_gpr(card, 0xf, right, VOL_5BIT);
 
 	//hard wire the ac97's pcm, we'll do that in dsp code instead.
-	emu10k1_ac97_write(&card->ac97, 0x18, 0x0);
+	emu10k1_ac97_write(card->ac97, 0x18, 0x0);
 	card->ac97_supported_mixers &= ~SOUND_MASK_PCM;
 	card->ac97_stereo_mixers &= ~SOUND_MASK_PCM;
 
 	//set Igain to 0dB by default, maybe consider hardwiring it here.
-	emu10k1_ac97_write(&card->ac97, AC97_RECORD_GAIN, 0x0000);
-	card->ac97.mixer_state[SOUND_MIXER_IGAIN] = 0x101; 
+	emu10k1_ac97_write(card->ac97, AC97_RECORD_GAIN, 0x0000);
+	card->ac97->mixer_state[SOUND_MIXER_IGAIN] = 0x101; 
 
 	return 0;
 }
diff -urN linux-2.4.22-pre2/drivers/sound/emu10k1/mixer.c linux-2.4.22-pre3/drivers/sound/emu10k1/mixer.c
--- linux-2.4.22-pre2/drivers/sound/emu10k1/mixer.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/emu10k1/mixer.c	2003-07-05 18:10:45.000000000 -0700
@@ -459,29 +459,29 @@
 				break;
 
 			if (addr >= 0) {
-				unsigned int state = card->ac97.mixer_state[id];
+				unsigned int state = card->ac97->mixer_state[id];
 
 				if (ch == 1) {
 					state >>= 8;
-					card->ac97.stereo_mixers |= (1 << id);
+					card->ac97->stereo_mixers |= (1 << id);
 				}
 
-				card->ac97.supported_mixers |= (1 << id);
+				card->ac97->supported_mixers |= (1 << id);
 
 				if (id == SOUND_MIXER_TREBLE) {
-					set_treble(card, card->ac97.mixer_state[id] & 0xff, (card->ac97.mixer_state[id] >> 8) & 0xff);
+					set_treble(card, card->ac97->mixer_state[id] & 0xff, (card->ac97->mixer_state[id] >> 8) & 0xff);
 				} else if (id == SOUND_MIXER_BASS) {
-					set_bass(card, card->ac97.mixer_state[id] & 0xff, (card->ac97.mixer_state[id] >> 8) & 0xff);
+					set_bass(card, card->ac97->mixer_state[id] & 0xff, (card->ac97->mixer_state[id] >> 8) & 0xff);
 				} else
 					emu10k1_set_volume_gpr(card, addr, state & 0xff,
 							       volume_params[id]);
 			} else {
-				card->ac97.stereo_mixers &= ~(1 << id);
-				card->ac97.stereo_mixers |= card->ac97_stereo_mixers;
+				card->ac97->stereo_mixers &= ~(1 << id);
+				card->ac97->stereo_mixers |= card->ac97_stereo_mixers;
 
 				if (ch == 0) {
-					card->ac97.supported_mixers &= ~(1 << id);
-					card->ac97.supported_mixers |= card->ac97_supported_mixers;
+					card->ac97->supported_mixers &= ~(1 << id);
+					card->ac97->supported_mixers |= card->ac97_supported_mixers;
 				}
 			}
 			break;
@@ -502,9 +502,9 @@
 
 		case CMD_AC97_BOOST:
 			if(ctl->val[0])
-				emu10k1_ac97_write(&card->ac97, 0x18, 0x0);	
+				emu10k1_ac97_write(card->ac97, 0x18, 0x0);	
 			else
-				emu10k1_ac97_write(&card->ac97, 0x18, 0x0808);
+				emu10k1_ac97_write(card->ac97, 0x18, 0x0808);
 			break;
 		default:
 			ret = -EINVAL;
@@ -579,7 +579,7 @@
 	int val;
 	int scale;
 
-	card->ac97.modcnt++;
+	card->ac97->modcnt++;
 
 	if (get_user(val, (int *)arg))
 		return -EFAULT;
@@ -591,7 +591,7 @@
 	if (right > 100) right = 100;
 	if (left > 100) left = 100;
 
-	card->ac97.mixer_state[oss_mixer] = (right << 8) | left;
+	card->ac97->mixer_state[oss_mixer] = (right << 8) | left;
 	if (oss_mixer == SOUND_MIXER_TREBLE) {
 		set_treble(card, left, right);
 		return 0;
@@ -601,7 +601,7 @@
 	}
 
 	if (oss_mixer == SOUND_MIXER_VOLUME)
-		scale = 1 << card->ac97.bit_resolution;
+		scale = 1 << card->ac97->bit_resolution;
 	else
 		scale = volume_params[oss_mixer];
 
@@ -609,7 +609,7 @@
 	emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][1], right, scale);
 
 	if (card->ac97_supported_mixers & (1 << oss_mixer))
-		card->ac97.write_mixer(&card->ac97, oss_mixer, left, right);
+		card->ac97->write_mixer(card->ac97, oss_mixer, left, right);
 
 	return 0;
 }
@@ -625,9 +625,9 @@
 		if (cmd == SOUND_MIXER_INFO) {
 			mixer_info info;
 
-			strncpy(info.id, card->ac97.name, sizeof(info.id));
+			strncpy(info.id, card->ac97->name, sizeof(info.id));
 			strncpy(info.name, "Creative SBLive - Emu10k1", sizeof(info.name));
-			info.modify_counter = card->ac97.modcnt;
+			info.modify_counter = card->ac97->modcnt;
 
 			if (copy_to_user((void *)arg, &info, sizeof(info)))
 				return -EFAULT;
@@ -638,7 +638,7 @@
 		if ((_SIOC_DIR(cmd) == (_SIOC_WRITE|_SIOC_READ)) && oss_mixer <= SOUND_MIXER_NRDEVICES)
 			ret = emu10k1_dsp_mixer(card, oss_mixer, arg);
 		else
-			ret = card->ac97.mixer_ioctl(&card->ac97, cmd, arg);
+			ret = card->ac97->mixer_ioctl(card->ac97, cmd, arg);
 	}
 	
 	if (ret < 0)
@@ -658,7 +658,7 @@
 	list_for_each(entry, &emu10k1_devs) {
 		card = list_entry(entry, struct emu10k1_card, list);
 
-		if (card->ac97.dev_mixer == minor)
+		if (card->ac97->dev_mixer == minor)
 			goto match;
 	}
 
diff -urN linux-2.4.22-pre2/drivers/sound/es1371.c linux-2.4.22-pre3/drivers/sound/es1371.c
--- linux-2.4.22-pre2/drivers/sound/es1371.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/es1371.c	2003-07-05 18:10:46.000000000 -0700
@@ -412,7 +412,7 @@
 	struct proc_dir_entry *ps;
 #endif /* ES1371_DEBUG */
 
-	struct ac97_codec codec;
+	struct ac97_codec *codec;
 
 	/* wave stuff */
 	unsigned ctrl;
@@ -688,10 +688,10 @@
 	unsigned long flags;
 	unsigned t, x;
         
+	spin_lock_irqsave(&s->lock, flags);
 	for (t = 0; t < POLL_COUNT; t++)
 		if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
 			break;
-	spin_lock_irqsave(&s->lock, flags);
 
         /* save the current state for later */
         x = wait_src_ready(s);
@@ -730,11 +730,12 @@
 	unsigned long flags;
 	unsigned t, x;
 
+	spin_lock_irqsave(&s->lock, flags);
+	
         /* wait for WIP to go away */
 	for (t = 0; t < 0x1000; t++)
 		if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
 			break;
-	spin_lock_irqsave(&s->lock, flags);
 
 	/* save the current state for later */
 	x = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC));
@@ -762,7 +763,6 @@
 	/* restore SRC reg */
 	wait_src_ready(s);
 	outl(x, s->io+ES1371_REG_SRCONV);
-	spin_unlock_irqrestore(&s->lock, flags);
 
         /* wait for WIP again */
 	for (t = 0; t < 0x1000; t++)
@@ -774,6 +774,7 @@
 		if ((x = inl(s->io+ES1371_REG_CODEC)) & CODEC_RDY)
 			break;
         
+	spin_unlock_irqrestore(&s->lock, flags);
 	return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT);
 }
 
@@ -1222,7 +1223,7 @@
 		if (list == &devs)
 			return -ENODEV;
 		s = list_entry(list, struct es1371_state, devs);
-		if (s->codec.dev_mixer == minor)
+		if (s->codec->dev_mixer == minor)
 			break;
 	}
        	VALIDATE_STATE(s);
@@ -1241,7 +1242,7 @@
 static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	struct ac97_codec *codec = &s->codec;
+	struct ac97_codec *codec = s->codec;
 
 	return mixdev_ioctl(codec, cmd, arg);
 }
@@ -1909,7 +1910,7 @@
                 return -EINVAL;
 		
 	}
-	return mixdev_ioctl(&s->codec, cmd, arg);
+	return mixdev_ioctl(s->codec, cmd, arg);
 }
 
 static int es1371_open(struct inode *inode, struct file *file)
@@ -2338,7 +2339,7 @@
                 return -EINVAL;
 		
 	}
-	return mixdev_ioctl(&s->codec, cmd, arg);
+	return mixdev_ioctl(s->codec, cmd, arg);
 }
 
 static int es1371_open_dac(struct inode *inode, struct file *file)
@@ -2716,7 +2717,7 @@
         /* print out CODEC state */
         len += sprintf (buf + len, "AC97 CODEC state\n");
 	for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
-                len+= sprintf (buf + len, "reg:0x%02x  val:0x%04x\n", cnt, rdcodec(&s->codec, cnt));
+                len+= sprintf (buf + len, "reg:0x%02x  val:0x%04x\n", cnt, rdcodec(s->codec, cnt));
 
         if (fpos >=len){
                 *start = buf;
@@ -2819,6 +2820,11 @@
 		return -ENOMEM;
 	}
 	memset(s, 0, sizeof(struct es1371_state));
+	
+	s->codec = ac97_alloc_codec();
+	if(s->codec == NULL)
+		goto err_codec;
+		
 	init_waitqueue_head(&s->dma_adc.wait);
 	init_waitqueue_head(&s->dma_dac1.wait);
 	init_waitqueue_head(&s->dma_dac2.wait);
@@ -2834,10 +2840,10 @@
 	s->vendor = pcidev->vendor;
 	s->device = pcidev->device;
 	pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
-	s->codec.private_data = s;
-	s->codec.id = 0;
-	s->codec.codec_read = rdcodec;
-	s->codec.codec_write = wrcodec;
+	s->codec->private_data = s;
+	s->codec->id = 0;
+	s->codec->codec_read = rdcodec;
+	s->codec->codec_write = wrcodec;
 	printk(KERN_INFO PFX "found chip, vendor id 0x%04x device id 0x%04x revision 0x%02x\n",
 	       s->vendor, s->device, s->rev);
 	if (!request_region(s->io, ES1371_EXTENT, "es1371")) {
@@ -2854,7 +2860,7 @@
 	/* register devices */
 	if ((res=(s->dev_audio = register_sound_dsp(&es1371_audio_fops,-1)))<0)
 		goto err_dev1;
-	if ((res=(s->codec.dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1)) < 0))
+	if ((res=(s->codec->dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1)) < 0))
 		goto err_dev2;
 	if ((res=(s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1))) < 0)
 		goto err_dev3;
@@ -2945,7 +2951,7 @@
 	/* init the sample rate converter */
 	src_init(s);
 	/* codec init */
-	if (!ac97_probe_codec(&s->codec)) {
+	if (!ac97_probe_codec(s->codec)) {
 		res = -ENODEV;
 		goto err_gp;
 	}
@@ -2954,16 +2960,16 @@
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 	val = SOUND_MASK_LINE;
-	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
+	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
 	for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
 		val = initvol[i].vol;
-		mixdev_ioctl(&s->codec, initvol[i].mixch, (unsigned long)&val);
+		mixdev_ioctl(s->codec, initvol[i].mixch, (unsigned long)&val);
 	}
 	/* mute master and PCM when in S/PDIF mode */
 	if (s->spdif_volume != -1) {
 		val = 0x0000;
-		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME, (unsigned long)&val);
-		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM, (unsigned long)&val);
+		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_VOLUME, (unsigned long)&val);
+		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_PCM, (unsigned long)&val);
 	}
 	set_fs(fs);
 	/* turn on S/PDIF output driver if requested */
@@ -2991,7 +2997,7 @@
  err_dev4:
 	unregister_sound_dsp(s->dev_dac);
  err_dev3:
-	unregister_sound_mixer(s->codec.dev_mixer);
+	unregister_sound_mixer(s->codec->dev_mixer);
  err_dev2:
 	unregister_sound_dsp(s->dev_audio);
  err_dev1:
@@ -3000,6 +3006,8 @@
  err_irq:
 	release_region(s->io, ES1371_EXTENT);
  err_region:
+ err_codec:
+	ac97_release_codec(s->codec);
 	kfree(s);
 	return res;
 }
@@ -3025,9 +3033,10 @@
 	}
 	release_region(s->io, ES1371_EXTENT);
 	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->codec.dev_mixer);
+	unregister_sound_mixer(s->codec->dev_mixer);
 	unregister_sound_dsp(s->dev_dac);
 	unregister_sound_midi(s->dev_midi);
+	ac97_release_codec(s->codec);
 	kfree(s);
 	pci_set_drvdata(dev, NULL);
 }
diff -urN linux-2.4.22-pre2/drivers/sound/forte.c linux-2.4.22-pre3/drivers/sound/forte.c
--- linux-2.4.22-pre2/drivers/sound/forte.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/forte.c	2003-07-05 18:10:46.000000000 -0700
@@ -1945,10 +1945,8 @@
 	      chip->iobase + FORTE_IRQ_STATUS);
 
 	/* Set up the AC97 codec */
-	if ((codec = kmalloc (sizeof (struct ac97_codec), GFP_KERNEL)) == NULL)
+	if ((codec = ac97_alloc_codec()) == NULL)
 		return -ENOMEM;
-	memset (codec, 0, sizeof (struct ac97_codec));
-
 	codec->private_data = chip;
 	codec->codec_read = forte_ac97_read;
 	codec->codec_write = forte_ac97_write;
@@ -1956,7 +1954,7 @@
 
 	if (ac97_probe_codec (codec) == 0) {
 		printk (KERN_ERR PFX "codec probe failed\n");
-		kfree (codec);
+		ac97_release_codec(codec);
 		return -1;
 	}
 
@@ -1964,7 +1962,7 @@
 	if ((codec->dev_mixer = 
 	     register_sound_mixer (&forte_mixer_fops, -1)) < 0) {
 		printk (KERN_ERR PFX "couldn't register mixer!\n");
-		kfree (codec);
+		ac97_release_codec(codec);
 		return -1;
 	}
 
@@ -2092,7 +2090,7 @@
 
 	unregister_sound_dsp (chip->dsp);
 	unregister_sound_mixer (chip->ac97->dev_mixer);
-
+	ac97_release_codec(chip->ac97);
 	kfree (chip);
 
 	printk (KERN_INFO PFX "driver released\n");
diff -urN linux-2.4.22-pre2/drivers/sound/i810_audio.c linux-2.4.22-pre3/drivers/sound/i810_audio.c
--- linux-2.4.22-pre2/drivers/sound/i810_audio.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/i810_audio.c	2003-07-05 18:10:46.000000000 -0700
@@ -118,6 +118,9 @@
 #ifndef PCI_DEVICE_ID_INTEL_ICH4
 #define PCI_DEVICE_ID_INTEL_ICH4	0x24c5
 #endif
+#ifndef PCI_DEVICE_ID_INTEL_ICH5
+#define PCI_DEVICE_ID_INTEL_ICH5	0x24d5
+#endif
 #ifndef PCI_DEVICE_ID_INTEL_440MX
 #define PCI_DEVICE_ID_INTEL_440MX	0x7195
 #endif
@@ -273,6 +276,7 @@
 	INTELICH2,
 	INTELICH3,
 	INTELICH4,
+	INTELICH5,
 	SI7012,
 	NVIDIA_NFORCE,
 	AMD768,
@@ -286,6 +290,7 @@
 	"Intel ICH2",
 	"Intel ICH3",
 	"Intel ICH4",
+	"Intel ICH5",
 	"SiS 7012",
 	"NVIDIA nForce Audio",
 	"AMD 768",
@@ -304,7 +309,8 @@
 	{  1, 0x0000 }, /* INTEL440MX */
 	{  1, 0x0000 }, /* INTELICH2 */
 	{  2, 0x0000 }, /* INTELICH3 */
-        {  3, 0x0003 }, /* INTELICH4 */
+ 	{  3, 0x0003 }, /* INTELICH4 */
+	{  3, 0x0003 }, /* INTELICH5 */
 	/*@FIXME to be verified*/	{  2, 0x0000 }, /* SI7012 */
 	/*@FIXME to be verified*/	{  2, 0x0000 }, /* NVIDIA_NFORCE */
 	/*@FIXME to be verified*/	{  2, 0x0000 }, /* AMD768 */
@@ -324,6 +330,8 @@
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH3},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH4,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH4},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH5,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH5},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7012,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, SI7012},
 	{PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO,
@@ -420,6 +428,9 @@
 	/* The i810 has a certain amount of cross channel interaction
 	   so we use a single per card lock */
 	spinlock_t lock;
+	
+	/* Control AC97 access serialization */
+	spinlock_t ac97_lock;
 
 	/* PCI device stuff */
 	struct pci_dev * pci_dev;
@@ -548,80 +559,42 @@
  *     The DSP sample rate must already be set to a supported
  *     S/PDIF rate (32kHz, 44.1kHz, or 48kHz) or we abort.
  */
-static void i810_set_spdif_output(struct i810_state *state, int slots, int rate)
+static int i810_set_spdif_output(struct i810_state *state, int slots, int rate)
 {
 	int	vol;
 	int	aud_reg;
+	int	r = 0;
 	struct ac97_codec *codec = state->card->ac97_codec[0];
 
-	if(!(state->card->ac97_features & 4)) {
-#ifdef DEBUG
-		printk(KERN_WARNING "i810_audio: S/PDIF transmitter not available.\n");
-#endif
+	if(!codec->codec_ops->digital) {
 		state->card->ac97_status &= ~SPDIF_ON;
 	} else {
 		if ( slots == -1 ) { /* Turn off S/PDIF */
-			aud_reg = i810_ac97_get(codec, AC97_EXTENDED_STATUS);
-			i810_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
-
+			codec->codec_ops->digital(codec, 0, 0, 0);
 			/* If the volume wasn't muted before we turned on S/PDIF, unmute it */
 			if ( !(state->card->ac97_status & VOL_MUTED) ) {
 				aud_reg = i810_ac97_get(codec, AC97_MASTER_VOL_STEREO);
 				i810_ac97_set(codec, AC97_MASTER_VOL_STEREO, (aud_reg & ~VOL_MUTED));
 			}
 			state->card->ac97_status &= ~(VOL_MUTED | SPDIF_ON);
-			return;
+			return 0;
 		}
 
 		vol = i810_ac97_get(codec, AC97_MASTER_VOL_STEREO);
 		state->card->ac97_status = vol & VOL_MUTED;
-
-		/* Set S/PDIF transmitter sample rate */
-		aud_reg = i810_ac97_get(codec, AC97_SPDIF_CONTROL);
-		switch ( rate ) {
-			case 32000:
-				aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_32K; 
-				break;
-			 case 44100:
-			 	aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_44K; 
-				break;
-			case 48000:
-			 	aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_48K; 
-				break;
-			default:
-#ifdef DEBUG
-				printk(KERN_WARNING "i810_audio: %d sample rate not supported by S/PDIF.\n", rate);
-#endif
-				/* turn off S/PDIF */
-				aud_reg = i810_ac97_get(codec, AC97_EXTENDED_STATUS);
-				i810_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
-				state->card->ac97_status &= ~SPDIF_ON;
-				return;
-		}
-
-		i810_ac97_set(codec, AC97_SPDIF_CONTROL, aud_reg);
 		
-		aud_reg = i810_ac97_get(codec, AC97_EXTENDED_STATUS);
-		aud_reg = (aud_reg & AC97_EA_SLOT_MASK) | slots | AC97_EA_VRA | AC97_EA_SPDIF;
-		i810_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg);
-		state->card->ac97_status |= SPDIF_ON;
+		r = codec->codec_ops->digital(codec, slots, rate, 0);
 
-		/* Check to make sure the configuration is valid */
-		aud_reg = i810_ac97_get(codec, AC97_EXTENDED_STATUS);
-		if ( ! (aud_reg & 0x0400) ) {
-#ifdef DEBUG
-			printk(KERN_WARNING "i810_audio: S/PDIF transmitter configuration not valid (0x%04x).\n", aud_reg);
-#endif
-
-			/* turn off S/PDIF */
-			i810_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
+		if(r)
+			state->card->ac97_status |= SPDIF_ON;
+		else
 			state->card->ac97_status &= ~SPDIF_ON;
-			return;
-		}
+
 		/* Mute the analog output */
 		/* Should this only mute the PCM volume??? */
 		i810_ac97_set(codec, AC97_MASTER_VOL_STEREO, (vol | VOL_MUTED));
 	}
+	return r;
 }
 
 /* i810_set_dac_channels
@@ -2640,23 +2613,32 @@
 static u16 i810_ac97_get(struct ac97_codec *dev, u8 reg)
 {
 	struct i810_card *card = dev->private_data;
+	u16 ret;
+	
+	spin_lock(&card->ac97_lock);
 	if (card->use_mmio) {
-		return i810_ac97_get_mmio(dev, reg);
+		ret = i810_ac97_get_mmio(dev, reg);
 	}
 	else {
-		return i810_ac97_get_io(dev, reg);
+		ret = i810_ac97_get_io(dev, reg);
 	}
+	spin_unlock(&card->ac97_lock);
+	
+	return ret;
 }
 
 static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data)
 {
 	struct i810_card *card = dev->private_data;
+	
+	spin_lock(&card->ac97_lock);
 	if (card->use_mmio) {
 		i810_ac97_set_mmio(dev, reg, data);
 	}
 	else {
 		i810_ac97_set_io(dev, reg, data);
 	}
+	spin_unlock(&card->ac97_lock);
 }
 
 
@@ -2802,7 +2784,7 @@
 	 */	
 	/* see i810_ac97_init for the next 7 lines (jsaw) */
 	inw(card->ac97base);
-	if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4)
+	if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4 || card->pci_id == PCI_DEVICE_ID_INTEL_ICH5)
 	    && (card->use_mmio)) {
 		primary_codec_id = (int) readl(card->iobase_mmio + SDM) & 0x3;
 		printk(KERN_INFO "i810_audio: Primary codec has ID %d\n",
@@ -2872,7 +2854,7 @@
 		   possible IO channels. Bit 0:1 of SDM then holds the 
 		   last codec ID spoken to. 
 		*/
-		if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4)
+		if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4 || card->pci_id == PCI_DEVICE_ID_INTEL_ICH5)
 		    && (card->use_mmio)) {
 			ac97_id = (int) readl(card->iobase_mmio + SDM) & 0x3;
 			printk(KERN_INFO "i810_audio: Connection %d with codec id %d\n",
@@ -2891,7 +2873,7 @@
 				printk(KERN_ERR "i810_audio: Primary codec not ready.\n");
 		}
 		
-		if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
+		if ((codec = ac97_alloc_codec()) == NULL)
 			return -ENOMEM;
 		memset(codec, 0, sizeof(struct ac97_codec));
 
@@ -2912,7 +2894,7 @@
 	
 		if(!i810_ac97_probe_and_powerup(card,codec)) {
 			printk(KERN_ERR "i810_audio: timed out waiting for codec %d analog ready.\n", ac97_id);
-			kfree(codec);
+			ac97_release_codec(codec);
 			break;	/* it didn't work */
 		}
 		/* Store state information about S/PDIF transmitter */
@@ -2921,10 +2903,10 @@
 		/* Don't attempt to get eid until powerup is complete */
 		eid = i810_ac97_get(codec, AC97_EXTENDED_ID);
 
-		if(eid==0xFFFFFF)
+		if(eid==0xFFFF)
 		{
 			printk(KERN_WARNING "i810_audio: no codec attached ?\n");
-			kfree(codec);
+			ac97_release_codec(codec);
 			break;
 		}
 		
@@ -2933,7 +2915,7 @@
 		if(codec->modem)
 		{
 			printk(KERN_WARNING "i810_audio: codec %d is a softmodem - skipping.\n", ac97_id);
-			kfree(codec);
+			ac97_release_codec(codec);
 			continue;
 		}
 		
@@ -3016,7 +2998,7 @@
 
 		if ((codec->dev_mixer = register_sound_mixer(&i810_mixer_fops, -1)) < 0) {
 			printk(KERN_ERR "i810_audio: couldn't register mixer!\n");
-			kfree(codec);
+			ac97_release_codec(codec);
 			break;
 		}
 
@@ -3148,6 +3130,7 @@
 	card->pm_suspended=0;
 #endif
 	spin_lock_init(&card->lock);
+	spin_lock_init(&card->ac97_lock);
 	devs = card;
 
 	pci_set_master(pci_dev);
@@ -3243,7 +3226,7 @@
 		for (i = 0; i < NR_AC97; i++)
 		if (card->ac97_codec[i] != NULL) {
 			unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
-			kfree (card->ac97_codec[i]);
+			ac97_release_codec(card->ac97_codec[i]);
 		}
 		goto out_iospace;
 	}
@@ -3288,7 +3271,7 @@
 	for (i = 0; i < NR_AC97; i++)
 		if (card->ac97_codec[i] != NULL) {
 			unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
-			kfree (card->ac97_codec[i]);
+			ac97_release_codec(card->ac97_codec[i]);
 			card->ac97_codec[i] = NULL;
 		}
 	unregister_sound_dsp(card->dev_audio);
diff -urN linux-2.4.22-pre2/drivers/sound/ite8172.c linux-2.4.22-pre3/drivers/sound/ite8172.c
--- linux-2.4.22-pre2/drivers/sound/ite8172.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/ite8172.c	2003-07-05 18:10:47.000000000 -0700
@@ -285,7 +285,7 @@
 	struct proc_dir_entry *ac97_ps;
 #endif /* IT8172_DEBUG */
 
-	struct ac97_codec codec;
+	struct ac97_codec *codec;
 
 	unsigned short pcc, capcc;
 	unsigned dacrate, adcrate;
@@ -873,7 +873,7 @@
 		if (list == &devs)
 			return -ENODEV;
 		s = list_entry(list, struct it8172_state, devs);
-		if (s->codec.dev_mixer == minor)
+		if (s->codec->dev_mixer == minor)
 			break;
 	}
 	file->private_data = s;
@@ -997,7 +997,7 @@
 			       unsigned int cmd, unsigned long arg)
 {
 	struct it8172_state *s = (struct it8172_state *)file->private_data;
-	struct ac97_codec *codec = &s->codec;
+	struct ac97_codec *codec = s->codec;
 
 	return mixdev_ioctl(codec, cmd, arg);
 }
@@ -1763,7 +1763,7 @@
 		return -EINVAL;
 	}
 
-	return mixdev_ioctl(&s->codec, cmd, arg);
+	return mixdev_ioctl(s->codec, cmd, arg);
 }
 
 
@@ -1931,7 +1931,7 @@
 	len += sprintf (buf + len, "----------------------\n");
 	for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
 		len+= sprintf (buf + len, "reg %02x = %04x\n",
-			       cnt, rdcodec(&s->codec, cnt));
+			       cnt, rdcodec(s->codec, cnt));
 
 	if (fpos >=len){
 		*start = buf;
@@ -1996,11 +1996,16 @@
 	s->vendor = pcidev->vendor;
 	s->device = pcidev->device;
 	pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
-	s->codec.private_data = s;
-	s->codec.id = 0;
-	s->codec.codec_read = rdcodec;
-	s->codec.codec_write = wrcodec;
-	s->codec.codec_wait = waitcodec;
+	
+	s->codec = ac97_alloc_codec();
+	if(s->codec == NULL)
+		goto err_codec;
+		
+	s->codec->private_data = s;
+	s->codec->id = 0;
+	s->codec->codec_read = rdcodec;
+	s->codec->codec_write = wrcodec;
+	s->codec->codec_wait = waitcodec;
 
 	if (!request_region(s->io, pci_resource_len(pcidev,0),
 			    IT8172_MODULE_NAME)) {
@@ -2019,7 +2024,7 @@
 	/* register devices */
 	if ((s->dev_audio = register_sound_dsp(&it8172_audio_fops, -1)) < 0)
 		goto err_dev1;
-	if ((s->codec.dev_mixer =
+	if ((s->codec->dev_mixer =
 	     register_sound_mixer(&it8172_mixer_fops, -1)) < 0)
 		goto err_dev2;
 
@@ -2090,11 +2095,11 @@
 	outw(0, s->io+IT_AC_CODECC);
     
 	/* codec init */
-	if (!ac97_probe_codec(&s->codec))
+	if (!ac97_probe_codec(s->codec))
 		goto err_dev3;
 
 	/* add I2S as allowable recording source */
-	s->codec.record_sources |= SOUND_MASK_I2S;
+	s->codec->record_sources |= SOUND_MASK_I2S;
 	
 	/* Enable Volume button interrupts */
 	imc = inb(s->io+IT_AC_IMC);
@@ -2114,23 +2119,23 @@
 
 	/* set mic to be the recording source */
 	val = SOUND_MASK_MIC;
-	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
+	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
 		     (unsigned long)&val);
 
 	/* mute AC'97 master and PCM when in S/PDIF mode */
 	if (s->spdif_volume != -1) {
 		val = 0x0000;
-		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME,
+		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_VOLUME,
 				     (unsigned long)&val);
-		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM,
+		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_PCM,
 				     (unsigned long)&val);
 	}
     
 #ifdef IT8172_DEBUG
 	sprintf(proc_str, "driver/%s/%d/ac97", IT8172_MODULE_NAME,
-		s->codec.id);
+		s->codec->id);
 	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
-					     ac97_read_proc, &s->codec);
+					     ac97_read_proc, s->codec);
 #endif
     
 	/* store it in the driver field */
@@ -2144,7 +2149,7 @@
 	return 0;
 
  err_dev3:
-	unregister_sound_mixer(s->codec.dev_mixer);
+	unregister_sound_mixer(s->codec->dev_mixer);
  err_dev2:
 	unregister_sound_dsp(s->dev_audio);
  err_dev1:
@@ -2153,6 +2158,8 @@
  err_irq:
 	release_region(s->io, pci_resource_len(pcidev,0));
  err_region:
+ 	ac97_release_codec(s->codec);
+ err_codec:
 	kfree(s);
 	return -1;
 }
@@ -2172,7 +2179,8 @@
 	free_irq(s->irq, s);
 	release_region(s->io, pci_resource_len(dev,0));
 	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->codec.dev_mixer);
+	unregister_sound_mixer(s->codec->dev_mixer);
+	ac97_codec_release(s->codec);
 	kfree(s);
 	pci_set_drvdata(dev, NULL);
 }
diff -urN linux-2.4.22-pre2/drivers/sound/maestro3.c linux-2.4.22-pre3/drivers/sound/maestro3.c
--- linux-2.4.22-pre2/drivers/sound/maestro3.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.22-pre3/drivers/sound/maestro3.c	2003-07-05 18:10:47.000000000 -0700
@@ -2297,9 +2297,8 @@
 {
     struct ac97_codec *codec;
 
-    if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
+    if ((codec = ac97_alloc_codec()) == NULL)
         return -ENOMEM;
-    memset(codec, 0, sizeof(struct ac97_codec));
 
     codec->private_data = card;
     codec->codec_read = m3_ac97_read;
@@ -2309,13 +2308,13 @@
 
     if (ac97_probe_codec(codec) == 0) {
         printk(KERN_ERR PFX "codec probe failed\n");
-        kfree(codec);
+        ac97_release_codec(codec);
         return -1;
     }
 
     if ((codec->dev_mixer = register_sound_mixer(&m3_mixer_fops, -1)) < 0) {
         printk(KERN_ERR PFX "couldn't register mixer!\n");
-        kfree(codec);
+        ac97_release_codec(codec);
         return -1;
     }
 
diff -urN linux-2.4.22-pre2/drivers/sound/nec_vrc5477.c linux-2.4.22-pre3/drivers/sound/nec_vrc5477.c
--- linux-2.4.22-pre2/drivers/sound/nec_vrc5477.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/nec_vrc5477.c	2003-07-05 18:10:47.000000000 -0700
@@ -195,7 +195,7 @@
 	struct proc_dir_entry *ac97_ps;
 #endif /* VRC5477_AC97_DEBUG */
 
-	struct ac97_codec codec;
+	struct ac97_codec *codec;
 
 	unsigned dacChannels, adcChannels;
 	unsigned short dacRate, adcRate;
@@ -386,7 +386,7 @@
 
 static void set_adc_rate(struct vrc5477_ac97_state *s, unsigned rate)
 {
-	wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, rate);
+	wrcodec(s->codec, AC97_PCM_LR_ADC_RATE, rate);
 	s->adcRate = rate;
 }
 
@@ -394,8 +394,8 @@
 static void set_dac_rate(struct vrc5477_ac97_state *s, unsigned rate)
 {
 	if(s->extended_status & AC97_EXTSTAT_VRA) {
-	wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, rate);
-		s->dacRate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
+	wrcodec(s->codec, AC97_PCM_FRONT_DAC_RATE, rate);
+		s->dacRate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
 	}
 }
 
@@ -865,7 +865,7 @@
 		if (list == &devs)
 			return -ENODEV;
 		s = list_entry(list, struct vrc5477_ac97_state, devs);
-		if (s->codec.dev_mixer == minor)
+		if (s->codec->dev_mixer == minor)
 			break;
 	}
 	file->private_data = s;
@@ -889,7 +889,7 @@
 {
     struct vrc5477_ac97_state *s = 
 	    (struct vrc5477_ac97_state *)file->private_data;
-    struct ac97_codec *codec = &s->codec;
+    struct ac97_codec *codec = s->codec;
 
     return mixdev_ioctl(codec, cmd, arg);
 }
@@ -1563,7 +1563,7 @@
 		return -EINVAL;
 	}
 
-	return mixdev_ioctl(&s->codec, cmd, arg);
+	return mixdev_ioctl(s->codec, cmd, arg);
 }
 
 
@@ -1789,7 +1789,7 @@
 	len += sprintf (buf + len, "----------------------\n");
 	for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
 		len+= sprintf (buf + len, "reg %02x = %04x\n",
-			       cnt, rdcodec(&s->codec, cnt));
+			       cnt, rdcodec(s->codec, cnt));
 
 	if (fpos >=len){
 		*start = buf;
@@ -1842,12 +1842,14 @@
 	s->dev = pcidev;
 	s->io = pci_resource_start(pcidev, 0);
 	s->irq = pcidev->irq;
+	
+	s->codec = ac97_alloc_codec();
 
-	s->codec.private_data = s;
-	s->codec.id = 0;
-	s->codec.codec_read = rdcodec;
-	s->codec.codec_write = wrcodec;
-	s->codec.codec_wait = waitcodec;
+	s->codec->private_data = s;
+	s->codec->id = 0;
+	s->codec->codec_read = rdcodec;
+	s->codec->codec_write = wrcodec;
+	s->codec->codec_wait = waitcodec;
 
 	/* setting some other default values such as
 	 * adcChannels, adcRate is done in open() so that
@@ -1855,7 +1857,7 @@
 	 */
 
 	/* test if get response from ac97, if not return */
-        if (ac97_codec_not_present(&(s->codec))) {
+        if (ac97_codec_not_present(s->codec)) {
 		printk(KERN_ERR PFX "no ac97 codec\n");
 		goto err_region;
 
@@ -1878,7 +1880,7 @@
 	/* register devices */
 	if ((s->dev_audio = register_sound_dsp(&vrc5477_ac97_audio_fops, -1)) < 0)
 		goto err_dev1;
-	if ((s->codec.dev_mixer =
+	if ((s->codec->dev_mixer =
 	     register_sound_mixer(&vrc5477_ac97_mixer_fops, -1)) < 0)
 		goto err_dev2;
 
@@ -1899,22 +1901,22 @@
 	while (inl(s->io + VRC5477_ACLINK_CTRL) & VRC5477_ACLINK_CTRL_RST_ON);
 
 	/* codec init */
-	if (!ac97_probe_codec(&s->codec))
+	if (!ac97_probe_codec(s->codec))
 		goto err_dev3;
 
 #ifdef VRC5477_AC97_DEBUG
 	sprintf(proc_str, "driver/%s/%d/ac97", 
-		VRC5477_AC97_MODULE_NAME, s->codec.id);
+		VRC5477_AC97_MODULE_NAME, s->codec->id);
 	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
-					     ac97_read_proc, &s->codec);
+					     ac97_read_proc, s->codec);
 	/* TODO : why this proc file does not show up? */
 #endif
 
 	/* Try to enable variable rate audio mode. */
-	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-		rdcodec(&s->codec, AC97_EXTENDED_STATUS) | AC97_EXTSTAT_VRA);
+	wrcodec(s->codec, AC97_EXTENDED_STATUS,
+		rdcodec(s->codec, AC97_EXTENDED_STATUS) | AC97_EXTSTAT_VRA);
 	/* Did we enable it? */
-	if(rdcodec(&s->codec, AC97_EXTENDED_STATUS) & AC97_EXTSTAT_VRA)
+	if(rdcodec(s->codec, AC97_EXTENDED_STATUS) & AC97_EXTSTAT_VRA)
 		s->extended_status |= AC97_EXTSTAT_VRA;
 	else {
 		s->dacRate = 48000;
@@ -1923,17 +1925,17 @@
 	}
 
         /* let us get the default volumne louder */
-        wrcodec(&s->codec, 0x2, 0x1010);	/* master volume, middle */
-        wrcodec(&s->codec, 0xc, 0x10);		/* phone volume, middle */
-        // wrcodec(&s->codec, 0xe, 0x10);		/* misc volume, middle */
-	wrcodec(&s->codec, 0x10, 0x8000);	/* line-in 2 line-out disable */
-        wrcodec(&s->codec, 0x18, 0x0707);	/* PCM out (line out) middle */
+        wrcodec(s->codec, 0x2, 0x1010);	/* master volume, middle */
+        wrcodec(s->codec, 0xc, 0x10);		/* phone volume, middle */
+        // wrcodec(s->codec, 0xe, 0x10);		/* misc volume, middle */
+	wrcodec(s->codec, 0x10, 0x8000);	/* line-in 2 line-out disable */
+        wrcodec(s->codec, 0x18, 0x0707);	/* PCM out (line out) middle */
 
 
 	/* by default we select line in the input */
-	wrcodec(&s->codec, 0x1a, 0x0404);
-	wrcodec(&s->codec, 0x1c, 0x0f0f);
-	wrcodec(&s->codec, 0x1e, 0x07);
+	wrcodec(s->codec, 0x1a, 0x0404);
+	wrcodec(s->codec, 0x1c, 0x0f0f);
+	wrcodec(s->codec, 0x1e, 0x07);
 
 	/* enable the master interrupt but disable all others */
 	outl(VRC5477_INT_MASK_NMASK, s->io + VRC5477_INT_MASK);
@@ -1949,7 +1951,7 @@
 	return 0;
 
  err_dev3:
-	unregister_sound_mixer(s->codec.dev_mixer);
+	unregister_sound_mixer(s->codec->dev_mixer);
  err_dev2:
 	unregister_sound_dsp(s->dev_audio);
  err_dev1:
@@ -1958,6 +1960,7 @@
  err_irq:
 	release_region(s->io, pci_resource_len(pcidev,0));
  err_region:
+ 	ac97_release_codec(codec);
 	kfree(s);
 	return -1;
 }
@@ -1979,7 +1982,8 @@
 	free_irq(s->irq, s);
 	release_region(s->io, pci_resource_len(dev,0));
 	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->codec.dev_mixer);
+	unregister_sound_mixer(s->codec->dev_mixer);
+	ac97_release_codec(s->codec);
 	kfree(s);
 	pci_set_drvdata(dev, NULL);
 }
diff -urN linux-2.4.22-pre2/drivers/sound/nm256_audio.c linux-2.4.22-pre3/drivers/sound/nm256_audio.c
--- linux-2.4.22-pre2/drivers/sound/nm256_audio.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/nm256_audio.c	2003-07-05 18:10:47.000000000 -0700
@@ -1090,7 +1090,7 @@
 		printk (KERN_ERR "NM256: This doesn't look to me like the AC97-compatible version.\n");
 		printk (KERN_ERR "       You can force the driver to load by passing in the module\n");
 		printk (KERN_ERR "       parameter:\n");
-		printk (KERN_ERR "              force_ac97 = 1\n");
+		printk (KERN_ERR "              force_load = 1\n");
 		printk (KERN_ERR "\n");
 		printk (KERN_ERR "       More likely, you should be using the appropriate SB-16 or\n");
 		printk (KERN_ERR "       CS4232 driver instead.  (If your BIOS has settings for\n");
diff -urN linux-2.4.22-pre2/drivers/sound/trident.c linux-2.4.22-pre3/drivers/sound/trident.c
--- linux-2.4.22-pre2/drivers/sound/trident.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/trident.c	2003-07-05 18:10:47.000000000 -0700
@@ -2931,7 +2931,6 @@
 		block = 1;
 		goto unlock;
 	}
-	printk(KERN_ERR "accesscodecsemaphore: fail\n");
 	return 0;
 }
 
@@ -2956,8 +2955,6 @@
 			break;
 		udelay(50);
 	}
-
-	printk(KERN_NOTICE "waitforstimertick :BIT_CLK is dead\n");
 	return 0;
 }
 
@@ -2969,6 +2966,7 @@
         unsigned long aud_reg;
 	u32 data;
         u16 wcontrol;
+        unsigned long flags;
 
 	if(!card)
 		BUG();
@@ -2981,6 +2979,8 @@
 	if (secondary)
 		mask |= ALI_AC97_SECONDARY;
     
+    	spin_lock_irqsave(&card->lock, flags);
+    	
 	if (!acquirecodecaccess(card))
 		printk(KERN_ERR "access codec fail\n");
 	
@@ -2992,7 +2992,7 @@
 	data = (mask | (reg & AC97_REG_ADDR));
 	
 	if(!waitforstimertick(card)) {
-		printk(KERN_ERR "BIT_CLOCK is dead\n");
+		printk(KERN_ERR "ali_ac97_read: BIT_CLOCK is dead\n");
 		goto releasecodec;
 	}
 	
@@ -3019,7 +3019,8 @@
 
  releasecodec: 
 	releasecodecaccess(card);
-	printk(KERN_ERR "ali: AC97 CODEC read timed out.\n");
+	spin_unlock_irqrestore(&card->lock, flags);
+	printk(KERN_ERR "ali_ac97_read: AC97 CODEC read timed out.\n");
 	return 0;
 }
 
@@ -3031,6 +3032,7 @@
 	unsigned int ncount;
 	u32 data;
         u16 wcontrol;
+        unsigned long flags;
 	
 	data = ((u32) val) << 16;
 	
@@ -3044,8 +3046,9 @@
 	if (card->revision == ALI_5451_V02)
 		mask |= ALI_AC97_WRITE_MIXER_REGISTER;
 		
+	spin_lock_irqsave(&card->lock, flags);
         if (!acquirecodecaccess(card))      
-		printk(KERN_ERR "access codec fail\n");
+		printk(KERN_ERR "ali_ac97_write: access codec fail\n");
 			
 	wcontrol = inw(TRID_REG(card, ALI_AC97_WRITE));
 	wcontrol &= 0xff00;
@@ -3073,6 +3076,7 @@
 	
  releasecodec:
 	releasecodecaccess(card);
+	spin_unlock_irqrestore(&card->lock, flags);
 	return;
 }
 
@@ -3101,6 +3105,9 @@
 	if(!card->mixer_regs_ready)
 		return ali_ac97_get(card, codec->id, reg);
 
+	/*
+	 *	FIXME: need to stop this caching some registers
+	 */
 	if(codec->id)
 		id = 1;
 	else
@@ -4015,9 +4022,8 @@
 	}
 
 	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-		if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
+		if ((codec = ac97_alloc_codec()) == NULL)
 			return -ENOMEM;
-		memset(codec, 0, sizeof(struct ac97_codec));
 
 		/* initialize some basic codec information, other fields will be filled
 		   in ac97_probe_codec */
@@ -4038,7 +4044,7 @@
 
 		if ((codec->dev_mixer = register_sound_mixer(&trident_mixer_fops, -1)) < 0) {
 			printk(KERN_ERR "trident: couldn't register mixer!\n");
-			kfree(codec);
+			ac97_release_codec(codec);
 			break;
 		}
 
@@ -4206,7 +4212,7 @@
 		for (i = 0; i < NR_AC97; i++) {
 			if (card->ac97_codec[i] != NULL) {
 				unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
-				kfree (card->ac97_codec[i]);
+				ac97_release_codec(card->ac97_codec[i]);
 			}
 		}
 		goto out_unregister_sound_dsp;
@@ -4304,7 +4310,7 @@
 	for (i = 0; i < NR_AC97; i++)
 		if (card->ac97_codec[i] != NULL) {
 			unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
-			kfree (card->ac97_codec[i]);
+			ac97_release_codec(card->ac97_codec[i]);
 		}
 	unregister_sound_dsp(card->dev_audio);
 	
diff -urN linux-2.4.22-pre2/drivers/sound/via82cxxx_audio.c linux-2.4.22-pre3/drivers/sound/via82cxxx_audio.c
--- linux-2.4.22-pre2/drivers/sound/via82cxxx_audio.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/via82cxxx_audio.c	2003-07-05 18:10:48.000000000 -0700
@@ -3,7 +3,7 @@
  * Copyright 1999,2000 Jeff Garzik
  *
  * Updated to support the VIA 8233/8235 audio subsystem
- * Alan Cox <alan@redhat.com> (C) Copyright 2002 Red Hat Inc
+ * Alan Cox <alan@redhat.com> (C) Copyright 2002, 2003 Red Hat Inc
  *
  * Distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2.
  * See the "COPYING" file distributed with this software for more info.
@@ -15,7 +15,7 @@
  */
 
 
-#define VIA_VERSION	"1.9.1-ac2"
+#define VIA_VERSION	"1.9.1-ac3"
 
 
 #include <linux/config.h>
@@ -85,10 +85,13 @@
 #define VIA_DEFAULT_FRAG_TIME		20
 #define VIA_DEFAULT_BUFFER_TIME		500
 
+/* the hardware has a 256 fragment limit */
+#define VIA_MIN_FRAG_NUMBER		2
+#define VIA_MAX_FRAG_NUMBER		128
+
 #define VIA_MAX_FRAG_SIZE		PAGE_SIZE
-#define VIA_MIN_FRAG_SIZE		64
+#define VIA_MIN_FRAG_SIZE		(VIA_MAX_BUFFER_DMA_PAGES * PAGE_SIZE / VIA_MAX_FRAG_NUMBER)
 
-#define VIA_MIN_FRAG_NUMBER		2
 
 /* 82C686 function 5 (audio codec) PCI configuration registers */
 #define VIA_ACLINK_STATUS	0x40
@@ -296,7 +299,8 @@
 	struct pci_dev *pdev;
 	long baseaddr;
 
-	struct ac97_codec ac97;
+	struct ac97_codec *ac97;
+	spinlock_t ac97_lock;
 	spinlock_t lock;
 	int card_num;		/* unique card number, from 0 */
 
@@ -746,9 +750,8 @@
  *      Performs some of the preparations necessary to begin
  *      using a PCM channel.
  *
- *      Currently the preparations consist in
- *      setting the
- *      PCM channel to a known state.
+ *      Currently the preparations consist of
+ *      setting the PCM channel to a known state.
  */
 
 
@@ -1128,7 +1131,7 @@
 
 	via_chan_clear (card, chan);
 
-	val = via_set_rate (&card->ac97, chan, val);
+	val = via_set_rate (card->ac97, chan, val);
 
 	DPRINTK ("EXIT, returning %d\n", val);
 	return val;
@@ -1301,6 +1304,8 @@
 
 	if (chan->frag_number < VIA_MIN_FRAG_NUMBER)
                 chan->frag_number = VIA_MIN_FRAG_NUMBER;
+        if (chan->frag_number > VIA_MAX_FRAG_NUMBER)
+        	chan->frag_number = VIA_MAX_FRAG_NUMBER;
 
 	if ((chan->frag_number * chan->frag_size) / PAGE_SIZE > VIA_MAX_BUFFER_DMA_PAGES)
 		chan->frag_number = (VIA_MAX_BUFFER_DMA_PAGES * PAGE_SIZE) / chan->frag_size;
@@ -1383,6 +1388,7 @@
 {
 	assert (chan->is_active == sg_active(chan->iobase));
 
+	DPRINTK ("MAYBE START %s\n", chan->name);
 	if (!chan->is_active && chan->is_enabled) {
 		chan->is_active = 1;
 		sg_begin (chan);
@@ -1456,6 +1462,8 @@
 	assert (codec->private_data != NULL);
 
 	card = codec->private_data;
+	
+	spin_lock(&card->ac97_lock);
 
 	/* Every time we write to register 80 we cause a transaction.
 	   The only safe way to clear the valid bit is to write it at
@@ -1486,6 +1494,7 @@
 	if (((data & 0x007F0000) >> 16) == reg) {
 		DPRINTK ("EXIT, success, data=0x%lx, retval=0x%lx\n",
 			 data, data & 0x0000FFFF);
+		spin_unlock(&card->ac97_lock);
 		return data & 0x0000FFFF;
 	}
 
@@ -1493,6 +1502,7 @@
 		reg, ((data & 0x007F0000) >> 16));
 
 err_out:
+	spin_unlock(&card->ac97_lock);
 	DPRINTK ("EXIT, returning 0\n");
 	return 0;
 }
@@ -1524,6 +1534,8 @@
 
 	card = codec->private_data;
 
+	spin_lock(&card->ac97_lock);
+	
 	data = (reg << 16) + value;
 	outl (data, card->baseaddr + VIA_BASE0_AC97_CTRL);
 	udelay (10);
@@ -1538,6 +1550,7 @@
 	printk (KERN_WARNING PFX "timeout after AC97 codec write (0x%X, 0x%X)\n", reg, value);
 
 out:
+	spin_unlock(&card->ac97_lock);
 	DPRINTK ("EXIT\n");
 }
 
@@ -1557,7 +1570,7 @@
 			assert (pci_get_drvdata (pdev) != NULL);
 
 			card = pci_get_drvdata (pdev);
-			if (card->ac97.dev_mixer == minor)
+			if (card->ac97->dev_mixer == minor)
 				goto match;
 		}
 	}
@@ -1566,7 +1579,7 @@
 	return -ENODEV;
 
 match:
-	file->private_data = &card->ac97;
+	file->private_data = card->ac97;
 
 	DPRINTK ("EXIT, returning 0\n");
 	return 0;
@@ -1724,9 +1737,9 @@
 	/* WARNING: this line is magic.  Remove this
 	 * and things break. */
 	/* enable variable rate */
- 	tmp16 = via_ac97_read_reg (&card->ac97, AC97_EXTENDED_STATUS);
+ 	tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS);
  	if ((tmp16 & 1) == 0)
- 		via_ac97_write_reg (&card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1);
+ 		via_ac97_write_reg (card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1);
 
 	DPRINTK ("EXIT, returning 0\n");
 	return 0;
@@ -1749,16 +1762,20 @@
 
 	assert (card != NULL);
 
-	memset (&card->ac97, 0, sizeof (card->ac97));
-	card->ac97.private_data = card;
-	card->ac97.codec_read = via_ac97_read_reg;
-	card->ac97.codec_write = via_ac97_write_reg;
-	card->ac97.codec_wait = via_ac97_codec_wait;
+	card->ac97 = ac97_alloc_codec();
+	if(card->ac97 == NULL)
+		return -ENOMEM;
+		
+	card->ac97->private_data = card;
+	card->ac97->codec_read = via_ac97_read_reg;
+	card->ac97->codec_write = via_ac97_write_reg;
+	card->ac97->codec_wait = via_ac97_codec_wait;
 
-	card->ac97.dev_mixer = register_sound_mixer (&via_mixer_fops, -1);
-	if (card->ac97.dev_mixer < 0) {
+	card->ac97->dev_mixer = register_sound_mixer (&via_mixer_fops, -1);
+	if (card->ac97->dev_mixer < 0) {
 		printk (KERN_ERR PFX "unable to register AC97 mixer, aborting\n");
 		DPRINTK ("EXIT, returning -EIO\n");
+		ac97_release_codec(card->ac97);
 		return -EIO;
 	}
 
@@ -1770,24 +1787,24 @@
 	
 	mdelay(10);
 	
-	if (ac97_probe_codec (&card->ac97) == 0) {
+	if (ac97_probe_codec (card->ac97) == 0) {
 		printk (KERN_ERR PFX "unable to probe AC97 codec, aborting\n");
 		rc = -EIO;
 		goto err_out;
 	}
 
 	/* enable variable rate */
-	tmp16 = via_ac97_read_reg (&card->ac97, AC97_EXTENDED_STATUS);
-	via_ac97_write_reg (&card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1);
+	tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS);
+	via_ac97_write_reg (card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1);
 
  	/*
  	 * If we cannot enable VRA, we have a locked-rate codec.
  	 * We try again to enable VRA before assuming so, however.
  	 */
- 	tmp16 = via_ac97_read_reg (&card->ac97, AC97_EXTENDED_STATUS);
+ 	tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS);
  	if ((tmp16 & 1) == 0) {
- 		via_ac97_write_reg (&card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1);
- 		tmp16 = via_ac97_read_reg (&card->ac97, AC97_EXTENDED_STATUS);
+ 		via_ac97_write_reg (card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1);
+ 		tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS);
  		if ((tmp16 & 1) == 0) {
  			card->locked_rate = 1;
  			printk (KERN_WARNING PFX "Codec rate locked at 48Khz\n");
@@ -1798,8 +1815,9 @@
 	return 0;
 
 err_out:
-	unregister_sound_mixer (card->ac97.dev_mixer);
+	unregister_sound_mixer (card->ac97->dev_mixer);
 	DPRINTK ("EXIT, returning %d\n", rc);
+	ac97_release_codec(card->ac97);
 	return rc;
 }
 
@@ -1809,9 +1827,10 @@
 	DPRINTK ("ENTER\n");
 
 	assert (card != NULL);
-	assert (card->ac97.dev_mixer >= 0);
+	assert (card->ac97->dev_mixer >= 0);
 
-	unregister_sound_mixer (card->ac97.dev_mixer);
+	unregister_sound_mixer (card->ac97->dev_mixer);
+	ac97_release_codec(card->ac97);
 
 	DPRINTK ("EXIT\n");
 }
@@ -1836,11 +1855,11 @@
  *	Locking: inside card->lock
  */
 
-static void via_intr_channel (struct via_channel *chan)
+static void via_intr_channel (struct via_info *card, struct via_channel *chan)
 {
 	u8 status;
 	int n;
-
+	
 	/* check pertinent bits of status register for action bits */
 	status = inb (chan->iobase) & (VIA_SGD_FLAG | VIA_SGD_EOL | VIA_SGD_STOPPED);
 	if (!status)
@@ -1859,6 +1878,7 @@
 	assert (n >= 0);
 	assert (n < chan->frag_number);
 
+	
 	/* reset SGD data structure in memory to reflect a full buffer,
 	 * and advance the h/w ptr, wrapping around to zero if needed
 	 */
@@ -1873,9 +1893,28 @@
 	/* accounting crap for SNDCTL_DSP_GETxPTR */
 	chan->n_irqs++;
 	chan->bytes += chan->frag_size;
+	/* FIXME - signed overflow is undefined */
 	if (chan->bytes < 0) /* handle overflow of 31-bit value */
 		chan->bytes = chan->frag_size;
-
+	/* all following checks only occur when not in mmap(2) mode */
+	if (!chan->is_mapped)
+	{
+		/* If we are recording, then n_frags represents the number
+		 * of fragments waiting to be handled by userspace.
+		 * If we are playback, then n_frags represents the number
+		 * of fragments remaining to be filled by userspace.
+		 * We increment here.  If we reach max number of fragments,
+		 * this indicates an underrun/overrun.  For this case under OSS,
+		 * we stop the record/playback process.
+		 */
+		if (atomic_read (&chan->n_frags) < chan->frag_number)
+			atomic_inc (&chan->n_frags);
+		assert (atomic_read (&chan->n_frags) <= chan->frag_number);
+		if (atomic_read (&chan->n_frags) == chan->frag_number) {
+			chan->is_active = 0;
+			via_chan_stop (chan->iobase);
+		}
+	}
 	/* wake up anyone listening to see when interrupts occur */
 	wake_up_all (&chan->wait);
 
@@ -1883,29 +1922,8 @@
 		 chan->name, status, (long) inl (chan->iobase + 0x04),
 		 atomic_read (&chan->hw_ptr));
 
-	/* all following checks only occur when not in mmap(2) mode */
-	if (chan->is_mapped)
-		return;
-
-	/* If we are recording, then n_frags represents the number
-	 * of fragments waiting to be handled by userspace.
-	 * If we are playback, then n_frags represents the number
-	 * of fragments remaining to be filled by userspace.
-	 * We increment here.  If we reach max number of fragments,
-	 * this indicates an underrun/overrun.  For this case under OSS,
-	 * we stop the record/playback process.
-	 */
-	if (atomic_read (&chan->n_frags) < chan->frag_number)
-		atomic_inc (&chan->n_frags);
-	assert (atomic_read (&chan->n_frags) <= chan->frag_number);
-
-	if (atomic_read (&chan->n_frags) == chan->frag_number) {
-		chan->is_active = 0;
-		via_chan_stop (chan->iobase);
-	}
-
-	DPRINTK ("%s intr, channel n_frags == %d\n", chan->name,
-		 atomic_read (&chan->n_frags));
+	DPRINTK ("%s intr, channel n_frags == %d, missed %d\n", chan->name,
+		 atomic_read (&chan->n_frags), missed);
 }
 
 
@@ -1936,11 +1954,11 @@
 	spin_lock (&card->lock);
 
 	if (status32 & VIA_INTR_OUT)
-		via_intr_channel (&card->ch_out);
+		via_intr_channel (card, &card->ch_out);
 	if (status32 & VIA_INTR_IN)
-		via_intr_channel (&card->ch_in);
+		via_intr_channel (card, &card->ch_in);
 	if (status32 & VIA_INTR_FM)
-		via_intr_channel (&card->ch_fm);
+		via_intr_channel (card, &card->ch_fm);
 
 	spin_unlock (&card->lock);
 }
@@ -1963,9 +1981,9 @@
 	 */
 	spin_lock (&card->lock);
 
-	via_intr_channel (&card->ch_out);
-	via_intr_channel (&card->ch_in);
-	via_intr_channel (&card->ch_fm);
+	via_intr_channel (card, &card->ch_out);
+	via_intr_channel (card, &card->ch_in);
+	via_intr_channel (card, &card->ch_fm);
 
 	spin_unlock (&card->lock);
 }
@@ -2548,7 +2566,10 @@
 		goto handle_one_block;
 
 out:
-	return userbuf - orig_userbuf;
+	if (userbuf - orig_userbuf)
+		return userbuf - orig_userbuf;
+	else
+		return ret;
 }
 
 
@@ -2657,6 +2678,7 @@
 
 	add_wait_queue(&chan->wait, &wait);
 	for (;;) {
+		DPRINTK ("FRAGS %d FRAGNUM %d\n", atomic_read(&chan->n_frags), chan->frag_number);
 		__set_current_state(TASK_INTERRUPTIBLE);
 		if (atomic_read (&chan->n_frags) >= chan->frag_number)
 			break;
@@ -3204,7 +3226,7 @@
 	/* inform device of an upcoming pause in input (or output). */
 	case SNDCTL_DSP_POST:
 		DPRINTK ("DSP_POST\n");
-		if (wr) {
+		if (0 && wr) {
 			if (card->ch_out.slop_len > 0)
 				via_chan_flush_frag (&card->ch_out);
 			via_chan_maybe_start (&card->ch_out);
@@ -3289,7 +3311,7 @@
 
 		// TO DO - use FIFO: via_capture_fifo(card, 1);
 		via_chan_pcm_fmt (chan, 0);
-		via_set_rate (&card->ac97, chan, 44100);
+		via_set_rate (card->ac97, chan, 44100);
 	}
 
 	/* handle output to analog source */
@@ -3304,15 +3326,15 @@
 			chan->pcm_fmt = VIA_PCM_FMT_16BIT | VIA_PCM_FMT_STEREO;
 			chan->channels = 2;
 			via_chan_pcm_fmt (chan, 0);
-                        via_set_rate (&card->ac97, chan, 44100);
+                        via_set_rate (card->ac97, chan, 44100);
 		} else {
 			 if ((minor & 0xf) == SND_DEV_DSP16) {
 				chan->pcm_fmt = VIA_PCM_FMT_16BIT;
 				via_chan_pcm_fmt (chan, 0);
-				via_set_rate (&card->ac97, chan, 44100);
+				via_set_rate (card->ac97, chan, 44100);
 			} else {
 				via_chan_pcm_fmt (chan, 1);
-				via_set_rate (&card->ac97, chan, 8000);
+				via_set_rate (card->ac97, chan, 8000);
 			}
 		}
 	}
@@ -3406,6 +3428,7 @@
 	card->baseaddr = pci_resource_start (pdev, 0);
 	card->card_num = via_num_cards++;
 	spin_lock_init (&card->lock);
+	spin_lock_init (&card->ac97_lock);
 	init_MUTEX (&card->syscall_sem);
 	init_MUTEX (&card->open_sem);
 
@@ -3769,7 +3792,7 @@
 	}
 
 	sprintf (s, "driver/via/%d/ac97", card->card_num);
-	if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, &card->ac97)) {
+	if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, card->ac97)) {
 		rc = -EIO;
 		goto err_out_info;
 	}
diff -urN linux-2.4.22-pre2/drivers/sound/ymfpci.c linux-2.4.22-pre3/drivers/sound/ymfpci.c
--- linux-2.4.22-pre2/drivers/sound/ymfpci.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/ymfpci.c	2003-07-05 18:10:49.000000000 -0700
@@ -176,15 +176,16 @@
 	ymfpci_t *codec = dev->private_data;
 	u32 cmd;
 
+	spin_lock(&codec->ac97_lock);
 	/* XXX Do make use of dev->id */
 	ymfpci_codec_ready(codec, 0, 0);
 	cmd = ((YDSXG_AC97WRITECMD | reg) << 16) | val;
 	ymfpci_writel(codec, YDSXGR_AC97CMDDATA, cmd);
+	spin_unlock(&codec->ac97_lock);
 }
 
-static u16 ymfpci_codec_read(struct ac97_codec *dev, u8 reg)
+static u16 _ymfpci_codec_read(ymfpci_t *unit, u8 reg)
 {
-	ymfpci_t *unit = dev->private_data;
 	int i;
 
 	if (ymfpci_codec_ready(unit, 0, 0))
@@ -199,6 +200,18 @@
 	return ymfpci_readw(unit, YDSXGR_PRISTATUSDATA);
 }
 
+static u16 ymfpci_codec_read(struct ac97_codec *dev, u8 reg)
+{
+	ymfpci_t *unit = dev->private_data;
+	u16 ret;
+	
+	spin_lock(&unit->ac97_lock);
+	ret = _ymfpci_codec_read(unit, reg);
+	spin_unlock(&unit->ac97_lock);
+	
+	return ret;
+}
+
 /*
  *  Misc routines
  */
@@ -2442,9 +2455,8 @@
 	struct ac97_codec *codec;
 	u16 eid;
 
-	if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
+	if ((codec = ac97_alloc_codec()) == NULL)
 		return -ENOMEM;
-	memset(codec, 0, sizeof(struct ac97_codec));
 
 	/* initialize some basic codec information, other fields will be filled
 	   in ac97_probe_codec */
@@ -2460,7 +2472,7 @@
 	}
 
 	eid = ymfpci_codec_read(codec, AC97_EXTENDED_ID);
-	if (eid==0xFFFFFF) {
+	if (eid==0xFFFF) {
 		printk(KERN_WARNING "ymfpci: no codec attached ?\n");
 		goto out_kfree;
 	}
@@ -2476,7 +2488,7 @@
 
 	return 0;
  out_kfree:
-	kfree(codec);
+	ac97_release_codec(codec);
 	return -ENODEV;
 }
 
@@ -2515,6 +2527,7 @@
 
 	spin_lock_init(&codec->reg_lock);
 	spin_lock_init(&codec->voice_lock);
+	spin_lock_init(&codec->ac97_lock);
 	init_MUTEX(&codec->open_sem);
 	INIT_LIST_HEAD(&codec->states);
 	codec->pci = pcidev;
@@ -2613,7 +2626,7 @@
  out_release_region:
 	release_mem_region(pci_resource_start(pcidev, 0), 0x8000);
  out_free:
-	kfree(codec);
+	ac97_release_codec(codec->ac97_codec[0]);
 	return -ENODEV;
 }
 
@@ -2626,7 +2639,7 @@
 	list_del(&codec->ymf_devs);
 
 	unregister_sound_mixer(codec->ac97_codec[0]->dev_mixer);
-	kfree(codec->ac97_codec[0]);
+	ac97_release_codec(codec->ac97_codec[0]);
 	unregister_sound_dsp(codec->dev_audio);
 	free_irq(pcidev->irq, codec);
 	ymfpci_memfree(codec);
@@ -2641,7 +2654,6 @@
 		unload_uart401(&codec->mpu_data);
 	}
 #endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-	kfree(codec);
 }
 
 MODULE_AUTHOR("Jaroslav Kysela");
diff -urN linux-2.4.22-pre2/drivers/sound/ymfpci.h linux-2.4.22-pre3/drivers/sound/ymfpci.h
--- linux-2.4.22-pre2/drivers/sound/ymfpci.h	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.22-pre3/drivers/sound/ymfpci.h	2003-07-05 18:10:49.000000000 -0700
@@ -275,6 +275,7 @@
 
 	spinlock_t reg_lock;
 	spinlock_t voice_lock;
+	spinlock_t ac97_lock;
 
 	/* soundcore stuff */
 	int dev_audio;
diff -urN linux-2.4.22-pre2/drivers/usb/Makefile linux-2.4.22-pre3/drivers/usb/Makefile
--- linux-2.4.22-pre2/drivers/usb/Makefile	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/Makefile	2003-07-05 18:10:49.000000000 -0700
@@ -19,7 +19,6 @@
 hid-objs		:= hid-core.o
 pwc-objs		:= pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o
 auerswald-objs		:= auerbuf.o auerchain.o auerchar.o auermain.o
-speedtch-objs		:= speedcrc.o speedtouch.o
 
 # Optional parts of multipart objects.
 
@@ -150,6 +149,3 @@
 
 auerswald.o: $(auerswald-objs)
 	$(LD) -r -o $@ $(auerswald-objs)
-
-speedtch.o: $(speedtch-objs)
-	$(LD) -r -o $@ $(speedtch-objs)
diff -urN linux-2.4.22-pre2/drivers/usb/Makefile.lib linux-2.4.22-pre3/drivers/usb/Makefile.lib
--- linux-2.4.22-pre2/drivers/usb/Makefile.lib	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/Makefile.lib	2003-07-05 18:10:49.000000000 -0700
@@ -1,3 +1,4 @@
 obj-$(CONFIG_USB_USBNET)		+= crc32.o
 obj-$(CONFIG_USB_CATC)			+= crc32.o
+obj-$(CONFIG_USB_SPEEDTOUCH)		+= crc32.o
 
diff -urN linux-2.4.22-pre2/drivers/usb/aiptek.c linux-2.4.22-pre3/drivers/usb/aiptek.c
--- linux-2.4.22-pre2/drivers/usb/aiptek.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/aiptek.c	2003-07-05 18:10:50.000000000 -0700
@@ -969,16 +969,9 @@
 	char *out = page;
 	struct aiptek *aiptek = data;
 
-	int inchX = aiptek->features->x_max / 375 * 100;
-	int inchY = aiptek->features->y_max / 375 * 100;
-	int mmX = (int) ((double) aiptek->features->x_max / 14.8);
-	int mmY = (int) ((double) aiptek->features->y_max / 14.8);
-
 	out +=
-	    sprintf(out, "Aiptek Tablet (%dx%d, %d.%02dx%d.%02d\", %dx%dmm)\n",
-		    aiptek->features->x_max, aiptek->features->y_max,
-		    inchX / 100, inchX % 100, inchY / 100, inchY % 100, mmX,
-		    mmY);
+	    sprintf(out, "Aiptek Tablet (%dx%d)\n",
+		    aiptek->features->x_max, aiptek->features->y_max);
 
 	out +=
 	    sprintf(out,
diff -urN linux-2.4.22-pre2/drivers/usb/host/uhci-debug.h linux-2.4.22-pre3/drivers/usb/host/uhci-debug.h
--- linux-2.4.22-pre2/drivers/usb/host/uhci-debug.h	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/host/uhci-debug.h	2003-07-05 18:10:51.000000000 -0700
@@ -464,7 +464,7 @@
 }
 
 #ifdef CONFIG_PROC_FS
-#define MAX_OUTPUT	(PAGE_SIZE * 8)
+#define MAX_OUTPUT	(64 * 1024)
 
 static struct proc_dir_entry *uhci_proc_root = NULL;
 
diff -urN linux-2.4.22-pre2/drivers/usb/host/usb-ohci.c linux-2.4.22-pre3/drivers/usb/host/usb-ohci.c
--- linux-2.4.22-pre2/drivers/usb/host/usb-ohci.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/host/usb-ohci.c	2003-07-05 18:10:51.000000000 -0700
@@ -490,13 +490,20 @@
 				usb_pipeout (urb->pipe)
 					? PCI_DMA_TODEVICE
 					: PCI_DMA_FROMDEVICE);
-			urb->complete (urb);
 
-			/* implicitly requeued */
-  			urb->actual_length = 0;
-			urb->status = -EINPROGRESS;
-			td_submit_urb (urb);
-  			break;
+			if (urb->interval) {
+				urb->complete (urb);
+ 
+				/* implicitly requeued */
+				urb->actual_length = 0;
+				urb->status = -EINPROGRESS;
+				td_submit_urb (urb);
+			} else {
+				urb_rm_priv(urb);
+				urb->complete (urb);
+			}
+   			break;
+
   			
 		case PIPE_ISOCHRONOUS:
 			for (urbt = urb->next; urbt && (urbt != urb); urbt = urbt->next);
diff -urN linux-2.4.22-pre2/drivers/usb/host/usb-uhci.c linux-2.4.22-pre3/drivers/usb/host/usb-uhci.c
--- linux-2.4.22-pre2/drivers/usb/host/usb-uhci.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/host/usb-uhci.c	2003-07-05 18:10:52.000000000 -0700
@@ -2430,9 +2430,9 @@
 
 _static int process_interrupt (uhci_t *s, struct urb *urb)
 {
-	int i, ret = -EINPROGRESS;
+	int ret = -EINPROGRESS;
 	urb_priv_t *urb_priv = urb->hcpriv;
-	struct list_head *p = urb_priv->desc_list.next;
+	struct list_head *p;
 	uhci_desc_t *desc = list_entry (urb_priv->desc_list.prev, uhci_desc_t, desc_list);
 
 	int actual_length;
@@ -2440,8 +2440,9 @@
 
 	//dbg("urb contains interrupt request");
 
-	for (i = 0; p != &urb_priv->desc_list; p = p->next, i++)	// Maybe we allow more than one TD later ;-)
-	{
+	// Maybe we allow more than one TD later ;-)
+	while ((p = urb_priv->desc_list.next) != &urb_priv->desc_list) {
+
 		desc = list_entry (p, uhci_desc_t, desc_list);
 
 		if (is_td_active(desc)) {
diff -urN linux-2.4.22-pre2/drivers/usb/powermate.c linux-2.4.22-pre3/drivers/usb/powermate.c
--- linux-2.4.22-pre2/drivers/usb/powermate.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/powermate.c	2003-07-05 18:10:52.000000000 -0700
@@ -1,9 +1,9 @@
 /*
  * A driver for the Griffin Technology, Inc. "PowerMate" USB controller dial.
  *
- * v1.0, (c)2002 William R Sowerbutts <will@sowerbutts.com>
+ * v1.1, (c)2002 William R Sowerbutts <will@sowerbutts.com>
  *
- * This device is a stainless steel knob which connects over USB. It can measure
+ * This device is an anodized aluminium knob which connects over USB. It can measure
  * clockwise and anticlockwise rotation. The dial also acts as a pushbutton with
  * a spring for automatic release. The base contains a pair of LEDs which illuminate
  * the translucent base. It rotates without limit and reports its relative rotation
@@ -49,9 +49,13 @@
 #define UPDATE_PULSE_AWAKE       (1<<2)
 #define UPDATE_PULSE_MODE        (1<<3)
 
-#define POWERMATE_PAYLOAD_SIZE 3
+/* at least two versions of the hardware exist, with differing payload 
+   sizes. the first three bytes always contain the "interesting" data in
+   the relevant format. */
+#define POWERMATE_PAYLOAD_SIZE_MAX 6
+#define POWERMATE_PAYLOAD_SIZE_MIN 3
 struct powermate_device {
-	signed char data[POWERMATE_PAYLOAD_SIZE];
+	signed char data[POWERMATE_PAYLOAD_SIZE_MAX];
 	struct urb irq, config;
 	struct usb_ctrlrequest configdr;
 	struct usb_device *udev;
@@ -266,10 +270,14 @@
 	pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
 
-	if(maxp != POWERMATE_PAYLOAD_SIZE)
-		printk("powermate: Expected payload of %d bytes, found %d bytes!\n", POWERMATE_PAYLOAD_SIZE, maxp);
+	if(maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX){
+		printk("powermate: Expected payload of %d--%d bytes, found %d bytes!\n", 
+		       POWERMATE_PAYLOAD_SIZE_MIN, POWERMATE_PAYLOAD_SIZE_MAX, maxp);
+		maxp = POWERMATE_PAYLOAD_SIZE_MAX;
+	}
+
 
-	FILL_INT_URB(&pm->irq, udev, pipe, pm->data, POWERMATE_PAYLOAD_SIZE, powermate_irq, pm, endpoint->bInterval);
+	FILL_INT_URB(&pm->irq, udev, pipe, pm->data, maxp, powermate_irq, pm, endpoint->bInterval);
 
 	/* register our interrupt URB with the USB system */
 	if(usb_submit_urb(&pm->irq)) {
diff -urN linux-2.4.22-pre2/drivers/usb/serial/ftdi_sio.c linux-2.4.22-pre3/drivers/usb/serial/ftdi_sio.c
--- linux-2.4.22-pre2/drivers/usb/serial/ftdi_sio.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/serial/ftdi_sio.c	2003-07-05 18:10:53.000000000 -0700
@@ -17,6 +17,48 @@
  * See http://ftdi-usb-sio.sourceforge.net for upto date testing info
  *	and extra documentation
  *
+ * (23/Jun/2003) Ian Abbott
+ *      Reduced flip buffer pushes and corrected a data length test in
+ *      ftdi_read_bulk_callback.
+ *      Defererence pointers after any paranoid checks, not before.
+ *
+ * (21/Jun/2003) Erik Nygren
+ *      Added support for Home Electronics Tira-1 IR tranceiver using FT232BM chip.
+ *      See <http://www.home-electro.com/tira1.htm>.  Only operates properly 
+ *      at 100000 and RTS-CTS, so set custom divisor mode on startup.
+ *      Also force the Tira-1 and USB-UIRT to only use their custom baud rates.
+ *
+ * (18/Jun/2003) Ian Abbott
+ *      Added Device ID of the USB relais from Rudolf Gugler (backported from
+ *      Philipp Gühring's patch for 2.5.x kernel).
+ *      Moved read transfer buffer reallocation into startup function.
+ *      Free existing write urb and transfer buffer in startup function.
+ *      Only use urbs in write urb pool that were successfully allocated.
+ *      Moved some constant macros out of functions.
+ *      Minor whitespace and comment changes.
+ *
+ * (12/Jun/2003) David Norwood
+ *      Added support for USB-UIRT IR tranceiver using 8U232AM chip.
+ *      See <http://home.earthlink.net/~jrhees/USBUIRT/index.htm>.  Only
+ *      operates properly at 312500, so set custom divisor mode on startup.
+ *
+ * (12/Jun/2003) Ian Abbott
+ *      Added Sealevel SeaLINK+ 210x, 220x, 240x, 280x vid/pids from Tuan Hoang
+ *      - I've eliminated some that don't seem to exist!
+ *      Added Home Electronics Tira-1 IR transceiver pid from Chris Horn
+ *      Some whitespace/coding-style cleanups
+ *
+ * (11/Jun/2003) Ian Abbott
+ *      Fixed unsafe spinlock usage in ftdi_write
+ *
+ * (24/Feb/2003) Richard Shooter
+ *      Increase read buffer size to improve read speeds at higher baud rates
+ *      (specifically tested with up to 1Mb/sec at 1.5M baud)
+ *
+ * (23/Feb/2003) John Wilkins
+ *      Added Xon/xoff flow control (activating support in the ftdi device)
+ *      Added vid/pid for Videonetworks/Homechoice (UK ISP)
+ *
  * (23/Feb/2003) Bill Ryder
  *      Added matrix orb device vid/pids from Wayne Wylupski
  *
@@ -175,7 +217,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.3.2"
+#define DRIVER_VERSION "v1.3.4"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>"
 #define DRIVER_DESC "USB FTDI Serial Converters Driver"
 
@@ -203,9 +245,11 @@
 
 static struct usb_device_id id_table_8U232AM [] = {
 	{ USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_1_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_2_PID, 0, 0x3ff) },
@@ -213,15 +257,63 @@
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_4_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_5_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_6_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2101_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2102_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2103_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2104_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_1_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_2_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_1_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_2_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_1_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_2_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_1_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_2_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_3_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_4_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_1_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_2_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_3_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_4_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_1_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_2_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_3_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_4_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_1_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_2_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_3_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_4_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_5_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_6_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_7_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_8_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_1_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_2_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_3_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_4_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_5_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_6_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_7_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_8_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_1_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_2_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_3_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_4_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_5_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_6_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_7_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0, 0x3ff) },
 	{ }						/* Terminating entry */
 };
 
 
 static struct usb_device_id id_table_FT232BM [] = {
 	{ USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_1_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_2_PID, 0x400, 0xffff) },
@@ -229,7 +321,64 @@
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_4_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_5_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_6_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2101_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2102_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2103_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2104_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_1_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_2_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_1_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_2_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_1_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_2_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_1_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_2_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_3_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_4_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_1_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_2_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_3_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_4_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_1_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_2_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_3_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_4_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_1_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_2_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_3_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_4_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_5_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_6_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_7_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_8_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_1_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_2_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_3_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_4_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_5_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_6_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_7_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_8_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_1_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_2_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_3_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_4_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_5_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_6_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_7_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0x400, 0xffff) },
+	{ }						/* Terminating entry */
+};
+
 
+static struct usb_device_id id_table_USB_UIRT [] = {
+	{ USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) },
+	{ }						/* Terminating entry */
+};
+
+
+static struct usb_device_id id_table_HE_TIRA1 [] = {
+	{ USB_DEVICE_VER(FTDI_VID, FTDI_HE_TIRA1_PID, 0x400, 0xffff) },
 	{ }						/* Terminating entry */
 };
 
@@ -237,16 +386,67 @@
 static __devinitdata struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
 	{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) },
 	{ USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID) },
 	{ USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_1_PID) },
 	{ USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_2_PID) },
 	{ USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_3_PID) },
 	{ USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_4_PID) },
 	{ USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_5_PID) },
-	{ USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_6_PID) },	{ }						/* Terminating entry */
+	{ USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_6_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2104_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_1_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_2_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2202_1_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2202_2_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2203_1_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2203_2_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_1_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_2_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_3_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_4_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_1_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_2_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_3_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_4_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_1_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_2_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_3_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_4_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_1_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_2_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_3_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_4_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_5_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_6_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_7_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_8_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_1_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_2_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_3_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_4_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_5_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_6_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_7_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_8_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_1_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_2_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_3_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_4_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_5_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_6_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_7_PID) },
+	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) },
+	{ USB_DEVICE_VER(FTDI_VID, FTDI_HE_TIRA1_PID, 0x400, 0xffff) },
+	{ USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) },
+	{ }						/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
@@ -257,6 +457,9 @@
 /* Don't be tempted to increase this buffer to > 64 ! I tried it and it doesn't work */
 #define URB_TRANSFER_BUFFER_SIZE	64 /* the device's max packet size */
 
+/* Constants for read urb */
+#define BUFSZ 512
+#define PKTSZ 64
 
 struct ftdi_private {
 	ftdi_chip_type_t chip_type;
@@ -276,6 +479,8 @@
 	struct urb	*write_urb_pool[NUM_URBS];
 	spinlock_t	write_urb_pool_lock;
 
+	int force_baud;		/* if non-zero, force the baud rate to this value */
+	int force_rtscts;	/* if non-zero, force RTS-CTS to always be enabled */
 };
 
 /* Used for TIOCMIWAIT */
@@ -290,6 +495,8 @@
 static int  ftdi_SIO_startup		(struct usb_serial *serial);
 static int  ftdi_8U232AM_startup	(struct usb_serial *serial);
 static int  ftdi_FT232BM_startup	(struct usb_serial *serial);
+static int  ftdi_USB_UIRT_startup	(struct usb_serial *serial);
+static int  ftdi_HE_TIRA1_startup	(struct usb_serial *serial);
 static void ftdi_shutdown		(struct usb_serial *serial);
 static int  ftdi_open			(struct usb_serial_port *port, struct file *filp);
 static void ftdi_close			(struct usb_serial_port *port, struct file *filp);
@@ -381,6 +588,56 @@
 	.shutdown =		ftdi_shutdown,
 };
 
+static struct usb_serial_device_type ftdi_USB_UIRT_device = {
+	.owner =		THIS_MODULE,
+	.name =			"USB-UIRT Infrared Receiver/Transmitter",
+	.id_table =		id_table_USB_UIRT,
+	.num_interrupt_in =	0,
+	.num_bulk_in =		1,
+	.num_bulk_out =		1,
+	.num_ports =		1,
+	.open =			ftdi_open,
+	.close =		ftdi_close,
+	.throttle =		ftdi_throttle,
+	.unthrottle =		ftdi_unthrottle,
+	.write =		ftdi_write,
+	.write_room =		ftdi_write_room,
+	.chars_in_buffer =	ftdi_chars_in_buffer,
+	.read_bulk_callback =	ftdi_read_bulk_callback,
+	.write_bulk_callback =	ftdi_write_bulk_callback,
+	.ioctl =		ftdi_ioctl,
+	.set_termios =		ftdi_set_termios,
+	.break_ctl =		ftdi_break_ctl,
+	.startup =		ftdi_USB_UIRT_startup,
+	.shutdown =		ftdi_shutdown,
+};
+
+/* The TIRA1 is based on a  FT232BM which requires a fixed baud rate of 100000
+ * and which requires RTS-CTS to be enabled. */
+static struct usb_serial_device_type ftdi_HE_TIRA1_device = {
+	.owner =		THIS_MODULE,
+	.name =			"Home-Electronics TIRA-1 IR Transceiver",
+	.id_table =		id_table_HE_TIRA1,
+	.num_interrupt_in =	0,
+	.num_bulk_in =		1,
+	.num_bulk_out =		1,
+	.num_ports =		1,
+	.open =			ftdi_open,
+	.close =		ftdi_close,
+	.throttle =		ftdi_throttle,
+	.unthrottle =		ftdi_unthrottle,
+	.write =		ftdi_write,
+	.write_room =		ftdi_write_room,
+	.chars_in_buffer =	ftdi_chars_in_buffer,
+	.read_bulk_callback =	ftdi_read_bulk_callback,
+	.write_bulk_callback =	ftdi_write_bulk_callback,
+	.ioctl =		ftdi_ioctl,
+	.set_termios =		ftdi_set_termios,
+	.break_ctl =		ftdi_break_ctl,
+	.startup =		ftdi_HE_TIRA1_startup,
+	.shutdown =		ftdi_shutdown,
+};
+
 
 
 #define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
@@ -684,13 +941,14 @@
 /* Called from ftdi_SIO_startup, etc. */
 static int ftdi_common_startup (struct usb_serial *serial)
 {
+	struct usb_serial_port *port = &serial->port[0];
 	struct ftdi_private *priv;
 	int i ;
 	struct urb *urb; 
 	
 	dbg("%s",__FUNCTION__);
 
-	priv = serial->port->private = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL);
+	priv = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL);
 	if (!priv){
 		err("%s- kmalloc(%Zd) failed.", __FUNCTION__, sizeof(struct ftdi_private));
 		return -ENOMEM;
@@ -702,17 +960,40 @@
 	   than queue a task to deliver them */
 	priv->flags = ASYNC_LOW_LATENCY;
 
-	/* create our write urb pool and transfer buffers - shared across all ftdi devices */ 
+	/* Increase the size of read buffers */
+	if (port->bulk_in_buffer) {
+		kfree (port->bulk_in_buffer);
+	}
+	port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL);
+	if (!port->bulk_in_buffer) {
+		kfree (priv);
+		return -ENOMEM;
+	}
+	if (port->read_urb) {
+		port->read_urb->transfer_buffer = port->bulk_in_buffer;
+		port->read_urb->transfer_buffer_length = BUFSZ;
+	}
+
+	/* Free port's existing write urb and transfer buffer. */
+	if (port->write_urb) {
+		usb_free_urb (port->write_urb);
+		port->write_urb = NULL;
+	}
+	if (port->bulk_out_buffer) {
+		kfree (port->bulk_out_buffer);
+		port->bulk_out_buffer = NULL;
+	}
+
+	/* create our write urb pool and transfer buffers */ 
 	spin_lock_init (&priv->write_urb_pool_lock);
 	for (i = 0; i < NUM_URBS; ++i) {
 		urb = usb_alloc_urb(0);
 		priv->write_urb_pool[i] = urb;
 		if (urb == NULL) {
 			err("Unable to create new urb in urb pool");
-			continue;
+			break;
 		}
 
-		urb->transfer_buffer = NULL;
 		urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
 		if (!urb->transfer_buffer) {
 			err("%s - out of memory for urb buffers.", 
@@ -721,6 +1002,13 @@
 		}
 	}
 
+	/* Need at least one write urb in the pool */
+	if (i == 0) {
+		kfree (priv);
+		return -ENOMEM;
+	}
+
+	port->private = priv;
 	
 	return (0);
 }
@@ -788,6 +1076,50 @@
 	return (0);
 } /* ftdi_FT232BM_startup */
 
+/* Startup for the USB-UIRT device, which requires hardwired baudrate (38400 gets mapped to 312500) */
+/* Called from usbserial:serial_probe */
+static int ftdi_USB_UIRT_startup (struct usb_serial *serial)
+{ /* ftdi_USB_UIRT_startup */
+	struct ftdi_private *priv;
+	int err;
+
+	dbg("%s",__FUNCTION__);
+	err = ftdi_8U232AM_startup(serial);
+	if (err){
+		return (err);
+	}
+
+	priv = serial->port->private;
+	priv->flags |= ASYNC_SPD_CUST;
+	priv->custom_divisor = 77;
+	priv->force_baud = B38400;
+	
+	return (0);
+} /* ftdi_USB_UIRT_startup */
+
+/* Startup for the HE-TIRA1 device, which requires hardwired
+ * baudrate (38400 gets mapped to 100000) */
+static int ftdi_HE_TIRA1_startup (struct usb_serial *serial)
+{ /* ftdi_HE_TIRA1_startup */
+	struct ftdi_private *priv;
+	int err;
+
+	dbg("%s",__FUNCTION__);
+	err = ftdi_FT232BM_startup(serial);
+	if (err){
+		return (err);
+	}
+
+	priv = serial->port->private;
+	priv->flags |= ASYNC_SPD_CUST;
+	priv->custom_divisor = 240;
+	priv->force_baud = B38400;
+	priv->force_rtscts = 1;
+	
+	return (0);
+} /* ftdi_HE_TIRA1_startup */
+
+
 /* ftdi_shutdown is called from usbserial:usb_serial_disconnect 
  *   it is called when the usb device is disconnected
  *
@@ -816,19 +1148,17 @@
 	if (port->open_count == 0){
 		spin_lock_irqsave (&priv->write_urb_pool_lock, flags);
 
-		for (i = 0; i < NUM_URBS; ++i) {
-			if (priv->write_urb_pool[i]) {
-				/* FIXME - uncomment the following usb_unlink_urb call when
-				 * the host controllers get fixed to set urb->dev = NULL after
-				 * the urb is finished.  Otherwise this call oopses. */
-				/* usb_unlink_urb(priv->write_urb_pool[i]); */
-				if (priv->write_urb_pool[i]->transfer_buffer) {
-					kfree(priv->write_urb_pool[i]->transfer_buffer);
-					priv->write_urb_pool[i]->transfer_buffer = NULL;
-				}
-				usb_free_urb (priv->write_urb_pool[i]);
-				priv->write_urb_pool[i] = NULL;
+		for (i = 0; i < NUM_URBS && priv->write_urb_pool[i]; ++i) {
+			/* FIXME - uncomment the following usb_unlink_urb call when
+			 * the host controllers get fixed to set urb->dev = NULL after
+			 * the urb is finished.  Otherwise this call oopses. */
+			/* usb_unlink_urb(priv->write_urb_pool[i]); */
+			if (priv->write_urb_pool[i]->transfer_buffer) {
+				kfree(priv->write_urb_pool[i]->transfer_buffer);
+				priv->write_urb_pool[i]->transfer_buffer = NULL;
 			}
+			usb_free_urb (priv->write_urb_pool[i]);
+			priv->write_urb_pool[i] = NULL;
 		}
 
 		spin_unlock_irqrestore (&priv->write_urb_pool_lock, flags);
@@ -880,10 +1210,6 @@
 		err("%s Error from RTS HIGH urb", __FUNCTION__);
 	}
 
-	/* Make sure write_urb is initialised since a write_pool is used now */
-	port->write_urb = NULL; /* prevents usbserial.c from trying something silly */
-
-
 	/* Start reading from the device */
 	FILL_BULK_URB(port->read_urb, serial->dev, 
 		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
@@ -998,20 +1324,18 @@
 
 		spin_lock_irqsave (&(priv->write_urb_pool_lock), flags) ; 
 
-		for (i = 0 ; i < NUM_URBS; i++) {
+		for (i = 0 ; i < NUM_URBS && priv->write_urb_pool[i]; i++) {
 			if (priv->write_urb_pool[i] -> status != -EINPROGRESS) {
-			  urb = priv->write_urb_pool[i];
-			  /* Must make sure another device doesn't grab this */
-			  /* BUT unfortunately the uhci stack errors if it sees this */
-			  /* so have to increase the size of the spin_lock */
-			  /* urb->status = -EINPROGRESS; */
+				urb = priv->write_urb_pool[i];
+				/* Must make sure another write doesn't grab this */
+				urb->status = -EINPROGRESS;
 				break;
 			}
 		}
 
+		spin_unlock_irqrestore (&priv->write_urb_pool_lock, flags);
 
 		if (urb == NULL) {
-		        spin_unlock_irqrestore (&priv->write_urb_pool_lock, flags);
 			dbg("%s - no more free urbs", __FUNCTION__);
 			goto exit;
 		}
@@ -1020,7 +1344,6 @@
 		if (urb->transfer_buffer == NULL) {
 			urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
 			if (urb->transfer_buffer == NULL) {
-				spin_unlock_irqrestore (&priv->write_urb_pool_lock, flags);
 				err("%s ran out of kernel memory for urb ...", __FUNCTION__);
 				goto exit;
 			}
@@ -1036,7 +1359,6 @@
 		if (from_user) {
 			if (copy_from_user(urb->transfer_buffer + data_offset,
 					   current_position, user_byte_count )){
-				spin_unlock_irqrestore (&priv->write_urb_pool_lock, flags);
 				return -EFAULT;
 			}
 		} else {
@@ -1060,6 +1382,11 @@
 			      ftdi_write_bulk_callback, port);
 		urb->transfer_flags |= USB_QUEUE_BULK;
 		
+		/* uhci stack errors if it status set to -EINPROGRESS on */
+		/* urb submission, so clear status before submission.    */
+		spin_lock_irqsave (&(priv->write_urb_pool_lock), flags) ; 
+		urb->status = 0;
+
 		result = usb_submit_urb(urb);
 		if (result) {
 			spin_unlock_irqrestore (&priv->write_urb_pool_lock, flags);
@@ -1089,7 +1416,7 @@
 static void ftdi_write_bulk_callback (struct urb *urb)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+	struct usb_serial *serial;
 
 	dbg("%s", __FUNCTION__);
 
@@ -1101,6 +1428,7 @@
 		return;
 	}
 
+	serial = get_usb_serial (port, __FUNCTION__);
 	if (!serial) {
 		dbg("%s - bad serial pointer, exiting", __FUNCTION__);
 		return;
@@ -1128,7 +1456,7 @@
 
 	spin_lock_irqsave (&priv->write_urb_pool_lock, flags);
 
-	for (i = 0; i < NUM_URBS; i++) {
+	for (i = 0; i < NUM_URBS && priv->write_urb_pool[i]; i++) {
 		if (priv->write_urb_pool[i]->status != -EINPROGRESS) {
 			room += URB_TRANSFER_BUFFER_SIZE - priv->write_offset;
 		}
@@ -1154,7 +1482,7 @@
 	spin_lock_irqsave (&priv->write_urb_pool_lock, flags);
 
 	/* tally up the number of bytes waiting */
-	for (i = 0; i < NUM_URBS; ++i) {
+	for (i = 0; i < NUM_URBS && priv->write_urb_pool[i]; i++) {
 		if (priv->write_urb_pool[i]->status == -EINPROGRESS) {
 			chars += URB_TRANSFER_BUFFER_SIZE - data_offset;
 		}
@@ -1173,15 +1501,22 @@
 static void ftdi_read_bulk_callback (struct urb *urb)
 { /* ftdi_read_bulk_callback */
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-	struct usb_serial *serial = get_usb_serial(port,__FUNCTION__);
-       	struct tty_struct *tty = port->tty ;
-	struct ftdi_private *priv = (struct ftdi_private *) port->private;
+	struct usb_serial *serial;
+	struct tty_struct *tty;
+	struct ftdi_private *priv;
 	char error_flag;
        	unsigned char *data = urb->transfer_buffer;
 
-	const int data_offset = 2;
 	int i;
 	int result;
+	int need_flip;
+	int packet_offset;
+
+	if (urb->number_of_packets > 0) {
+		err("%s transfer_buffer_length %d actual_length %d number of packets %d",__FUNCTION__,
+		    urb->transfer_buffer_length, urb->actual_length, urb->number_of_packets );
+		err("%s transfer_flags %x USB_QUEUE_BULK %x ", __FUNCTION__,urb->transfer_flags, USB_QUEUE_BULK );
+	}
 
 	dbg("%s", __FUNCTION__);
 
@@ -1191,16 +1526,19 @@
 	if (port->open_count <= 0)
 		return;
 
+	serial = get_usb_serial(port,__FUNCTION__);
 	if (!serial){
 		dbg("%s - bad serial pointer - exiting",__FUNCTION__);
 		return;
 	}
 	
+	tty = port->tty;
 	if (!tty) {
 		dbg("%s - bad tty pointer - exiting",__FUNCTION__);
 		return;
 	}
 
+	priv = (struct ftdi_private *) port->private;
 
 	if (urb->status) {
 		/* This will happen at close every time so it is a dbg not an err */
@@ -1221,75 +1559,82 @@
 	/* See acm.c - you do a tty_hangup  - eg tty_hangup(tty) */
 	/* if CD is dropped and the line is not CLOCAL then we should hangup */
 
-	/* Compare new line status to the old one, signal if different */
-	if (priv != NULL) {
-		char new_status = data[0] & FTDI_STATUS_B0_MASK;
-		if (new_status != priv->prev_status) {
-			priv->diff_status |= new_status ^ priv->prev_status;
-			wake_up_interruptible(&priv->delta_msr_wait);
-			priv->prev_status = new_status;
+	need_flip = 0;
+	for (packet_offset=0; packet_offset < urb->actual_length; packet_offset += PKTSZ) {
+		/* Compare new line status to the old one, signal if different */
+		if (priv != NULL) {
+			char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK;
+			if (new_status != priv->prev_status) {
+				priv->diff_status |= new_status ^ priv->prev_status;
+				wake_up_interruptible(&priv->delta_msr_wait);
+				priv->prev_status = new_status;
+			}
 		}
-	}
 
-	/* Handle errors and break */
-	error_flag = TTY_NORMAL;
-        /* Although the device uses a bitmask and hence can have multiple */
-        /* errors on a packet - the order here sets the priority the */
-        /* error is returned to the tty layer  */
-	
-	if ( data[1] & FTDI_RS_OE ) { 
-		error_flag = TTY_OVERRUN;
-                dbg("OVERRRUN error");
-	}
-	if ( data[1] & FTDI_RS_BI ) { 
-		error_flag = TTY_BREAK;
-                dbg("BREAK received");
-	}
-	if ( data[1] & FTDI_RS_PE ) { 
-		error_flag = TTY_PARITY;
-                dbg("PARITY error");
-	}
-	if ( data[1] & FTDI_RS_FE ) { 
-		error_flag = TTY_FRAME;
-                dbg("FRAMING error");
-	}
-	if (urb->actual_length > data_offset) {
-
-		for (i = data_offset ; i < urb->actual_length ; ++i) {
-			/* have to make sure we don't overflow the buffer
-			  with tty_insert_flip_char's */
-			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-				tty_flip_buffer_push(tty);
+		/* Handle errors and break */
+		error_flag = TTY_NORMAL;
+		/* Although the device uses a bitmask and hence can have multiple */
+		/* errors on a packet - the order here sets the priority the */
+		/* error is returned to the tty layer  */
+
+		if ( data[packet_offset+1] & FTDI_RS_OE ) {
+			error_flag = TTY_OVERRUN;
+			dbg("OVERRRUN error");
+		}
+		if ( data[packet_offset+1] & FTDI_RS_BI ) {
+			error_flag = TTY_BREAK;
+			dbg("BREAK received");
+		}
+		if ( data[packet_offset+1] & FTDI_RS_PE ) {
+			error_flag = TTY_PARITY;
+			dbg("PARITY error");
+		}
+		if ( data[packet_offset+1] & FTDI_RS_FE ) {
+			error_flag = TTY_FRAME;
+			dbg("FRAMING error");
+		}
+		if (urb->actual_length > packet_offset + 2) {
+			for (i = 2; (i < PKTSZ) && ((i+packet_offset) < urb->actual_length); ++i) {
+				/* have to make sure we don't overflow the buffer
+				  with tty_insert_flip_char's */
+				if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+					tty_flip_buffer_push(tty);
+				}
+				/* Note that the error flag is duplicated for 
+				   every character received since we don't know
+				   which character it applied to */
+				tty_insert_flip_char(tty, data[packet_offset+i], error_flag);
 			}
-			/* Note that the error flag is duplicated for 
-			   every character received since we don't know
-			   which character it applied to */
-			tty_insert_flip_char(tty, data[i], error_flag);
+			need_flip = 1;
 		}
-	  	tty_flip_buffer_push(tty);
-	} 
 
 #ifdef NOT_CORRECT_BUT_KEEPING_IT_FOR_NOW
-	/* if a parity error is detected you get status packets forever
-	   until a character is sent without a parity error.
-	   This doesn't work well since the application receives a never
-	   ending stream of bad data - even though new data hasn't been sent.
-	   Therefore I (bill) have taken this out.
-	   However - this might make sense for framing errors and so on 
-	   so I am leaving the code in for now.
-	*/
-      else {
-		if (error_flag != TTY_NORMAL){
-			dbg("error_flag is not normal");
+		/* if a parity error is detected you get status packets forever
+		   until a character is sent without a parity error.
+		   This doesn't work well since the application receives a never
+		   ending stream of bad data - even though new data hasn't been sent.
+		   Therefore I (bill) have taken this out.
+		   However - this might make sense for framing errors and so on 
+		   so I am leaving the code in for now.
+		*/
+		else {
+			if (error_flag != TTY_NORMAL){
+				dbg("error_flag is not normal");
 				/* In this case it is just status - if that is an error send a bad character */
 				if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
 					tty_flip_buffer_push(tty);
 				}
 				tty_insert_flip_char(tty, 0xff, error_flag);
-				tty_flip_buffer_push(tty);
+				need_flip = 1;
+			}
 		}
-	}
 #endif
+	} /* "for(packet_offset=0..." */
+
+	/* Low latency */
+	if (need_flip) {
+		tty_flip_buffer_push(tty);
+	}
 
 	/* if the port is closed stop trying to read */
 	if (port->open_count > 0){
@@ -1347,14 +1692,32 @@
 static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_termios)
 { /* ftdi_termios */
 	struct usb_serial *serial = port->serial;
-	unsigned int cflag = port->tty->termios->c_cflag;
+	unsigned int cflag;
 	struct ftdi_private *priv = (struct ftdi_private *)port->private;	
 	__u16 urb_value; /* will hold the new flags */
 	char buf[1]; /* Perhaps I should dynamically alloc this? */
 	
+	// Added for xon/xoff support
+	unsigned int iflag = port->tty->termios->c_iflag;
+	unsigned char vstop;
+	unsigned char vstart;
 	
 	dbg("%s", __FUNCTION__);
 
+	/* Force baud rate if this device requires it, unless it is set to B0. */
+	if (priv->force_baud && ((port->tty->termios->c_cflag & CBAUD) != B0)) {
+		dbg("%s: forcing baud rate for this device", __FUNCTION__);
+		port->tty->termios->c_cflag &= ~CBAUD;
+		port->tty->termios->c_cflag |= priv->force_baud;
+	}
+
+	/* Force RTS-CTS if this device requires it. */
+	if (priv->force_rtscts) {
+		dbg("%s: forcing rtscts for this device", __FUNCTION__);
+		port->tty->termios->c_cflag |= CRTSCTS;
+	}
+
+	cflag = port->tty->termios->c_cflag;
 
 	/* FIXME -For this cut I don't care if the line is really changing or 
 	   not  - so just do the change regardless  - should be able to 
@@ -1434,16 +1797,43 @@
 		}		
 		
 	} else { 
-		/* CHECKME Assuming XON/XOFF handled by tty stack - not by device */
-		dbg("%s Turning off hardware flow control", __FUNCTION__);
-		if (usb_control_msg(serial->dev, 
-				    usb_sndctrlpipe(serial->dev, 0),
-				    FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
-				    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
-				    0, 0, 
-				    buf, 0, WDR_TIMEOUT) < 0) {
-			err("urb failed to clear flow control");
-		}				
+		/*
+		 * Xon/Xoff code
+		 *
+		 * Check the IXOFF status in the iflag component of the termios structure
+		 * if IXOFF is not set, the pre-xon/xoff code is executed.
+		*/
+		if (iflag & IXOFF) {
+			dbg("%s  request to enable xonxoff iflag=%04x",__FUNCTION__,iflag);
+			// Try to enable the XON/XOFF on the ftdi_sio
+			// Set the vstart and vstop -- could have been done up above where
+			// a lot of other dereferencing is done but that would be very
+			// inefficient as vstart and vstop are not always needed
+			vstart=port->tty->termios->c_cc[VSTART];
+			vstop=port->tty->termios->c_cc[VSTOP];
+			urb_value=(vstop << 8) | (vstart);
+
+			if (usb_control_msg(serial->dev,
+					    usb_sndctrlpipe(serial->dev, 0),
+					    FTDI_SIO_SET_FLOW_CTRL_REQUEST,
+					    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
+					    urb_value , FTDI_SIO_XON_XOFF_HS,
+					    buf, 0, WDR_TIMEOUT) < 0) {
+				err("urb failed to set to xon/xoff flow control");
+			}
+		} else {
+			/* else clause to only run if cfag ! CRTSCTS and iflag ! XOFF */
+			/* CHECKME Assuming XON/XOFF handled by tty stack - not by device */
+			dbg("%s Turning off hardware flow control", __FUNCTION__);
+			if (usb_control_msg(serial->dev, 
+					    usb_sndctrlpipe(serial->dev, 0),
+					    FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
+					    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
+					    0, 0, 
+					    buf, 0, WDR_TIMEOUT) < 0) {
+				err("urb failed to clear flow control");
+			}				
+		}
 		
 	}
 	return;
@@ -1665,6 +2055,8 @@
 	usb_serial_register (&ftdi_SIO_device);
 	usb_serial_register (&ftdi_8U232AM_device);
 	usb_serial_register (&ftdi_FT232BM_device);
+	usb_serial_register (&ftdi_USB_UIRT_device);
+	usb_serial_register (&ftdi_HE_TIRA1_device);
 
 
 	info(DRIVER_VERSION ":" DRIVER_DESC);
@@ -1677,6 +2069,8 @@
 
 	dbg("%s", __FUNCTION__);
 
+	usb_serial_deregister (&ftdi_HE_TIRA1_device);
+	usb_serial_deregister (&ftdi_USB_UIRT_device);
 	usb_serial_deregister (&ftdi_FT232BM_device);
 	usb_serial_deregister (&ftdi_8U232AM_device);
 	usb_serial_deregister (&ftdi_SIO_device);
diff -urN linux-2.4.22-pre2/drivers/usb/serial/ftdi_sio.h linux-2.4.22-pre3/drivers/usb/serial/ftdi_sio.h
--- linux-2.4.22-pre2/drivers/usb/serial/ftdi_sio.h	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/serial/ftdi_sio.h	2003-07-05 18:10:53.000000000 -0700
@@ -17,11 +17,15 @@
  * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the 
  * FTDI_SIO implementation.
  *
+ * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais
+ * from Rudolf Gugler
+ *
  */
 
 #define FTDI_VID	0x0403	/* Vendor Id */
 #define FTDI_SIO_PID	0x8372	/* Product Id SIO application of 8U100AX  */
 #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */
+#define FTDI_RELAIS_PID	0xFA10  /* Relais device from Rudolf Gugler */
 #define FTDI_NF_RIC_VID	0x0DCD	/* Vendor Id */
 #define FTDI_NF_RIC_PID	0x0001	/* Product Id */
 
@@ -31,6 +35,10 @@
 #define FTDI_XF_634_PID  0xFC09	/* Four line device */
 #define FTDI_XF_632_PID  0xFC08	/* Two line device */
 
+/* Video Networks Limited / Homechoice in the UK use an ftdi-based device for their 1Mb */
+/* broadband internet service.  The following PID is exhibited by the usb device supplied */
+/* (the VID is the standard ftdi vid (FTDI_VID) */
+#define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */
 
 /*
  * The following are the values for the Matrix Orbital LCD displays,
@@ -45,6 +53,67 @@
 #define FTDI_MTXORB_5_PID      0xFA05  /* Matrix Orbital Product Id */
 #define FTDI_MTXORB_6_PID      0xFA06  /* Matrix Orbital Product Id */
 
+/*
+ * The following are the values for the Sealevel SeaLINK+ adapters.
+ * (Original list sent by Tuan Hoang.  Ian Abbott renamed the macros and
+ * removed some PIDs that don't seem to match any existing products.)
+ */
+#define SEALEVEL_VID		0x0c52	/* Sealevel Vendor ID */
+#define SEALEVEL_2101_PID	0x2101	/* SeaLINK+232 (2101/2105) */
+#define SEALEVEL_2102_PID	0x2102	/* SeaLINK+485 (2102) */
+#define SEALEVEL_2103_PID	0x2103	/* SeaLINK+232I (2103) */
+#define SEALEVEL_2104_PID	0x2104	/* SeaLINK+485I (2104) */
+#define SEALEVEL_2201_1_PID	0x2211	/* SeaPORT+2/232 (2201) Port 1 */
+#define SEALEVEL_2201_2_PID	0x2221	/* SeaPORT+2/232 (2201) Port 2 */
+#define SEALEVEL_2202_1_PID	0x2212	/* SeaPORT+2/485 (2202) Port 1 */
+#define SEALEVEL_2202_2_PID	0x2222	/* SeaPORT+2/485 (2202) Port 2 */
+#define SEALEVEL_2203_1_PID	0x2213	/* SeaPORT+2 (2203) Port 1 */
+#define SEALEVEL_2203_2_PID	0x2223	/* SeaPORT+2 (2203) Port 2 */
+#define SEALEVEL_2401_1_PID	0x2411	/* SeaPORT+4/232 (2401) Port 1 */
+#define SEALEVEL_2401_2_PID	0x2421	/* SeaPORT+4/232 (2401) Port 2 */
+#define SEALEVEL_2401_3_PID	0x2431	/* SeaPORT+4/232 (2401) Port 3 */
+#define SEALEVEL_2401_4_PID	0x2441	/* SeaPORT+4/232 (2401) Port 4 */
+#define SEALEVEL_2402_1_PID	0x2412	/* SeaPORT+4/485 (2402) Port 1 */
+#define SEALEVEL_2402_2_PID	0x2422	/* SeaPORT+4/485 (2402) Port 2 */
+#define SEALEVEL_2402_3_PID	0x2432	/* SeaPORT+4/485 (2402) Port 3 */
+#define SEALEVEL_2402_4_PID	0x2442	/* SeaPORT+4/485 (2402) Port 4 */
+#define SEALEVEL_2403_1_PID	0x2413	/* SeaPORT+4 (2403) Port 1 */
+#define SEALEVEL_2403_2_PID	0x2423	/* SeaPORT+4 (2403) Port 2 */
+#define SEALEVEL_2403_3_PID	0x2433	/* SeaPORT+4 (2403) Port 3 */
+#define SEALEVEL_2403_4_PID	0x2443	/* SeaPORT+4 (2403) Port 4 */
+#define SEALEVEL_2801_1_PID	0X2811	/* SeaLINK+8/232 (2801) Port 1 */
+#define SEALEVEL_2801_2_PID	0X2821	/* SeaLINK+8/232 (2801) Port 2 */
+#define SEALEVEL_2801_3_PID	0X2831	/* SeaLINK+8/232 (2801) Port 3 */
+#define SEALEVEL_2801_4_PID	0X2841	/* SeaLINK+8/232 (2801) Port 4 */
+#define SEALEVEL_2801_5_PID	0X2851	/* SeaLINK+8/232 (2801) Port 5 */
+#define SEALEVEL_2801_6_PID	0X2861	/* SeaLINK+8/232 (2801) Port 6 */
+#define SEALEVEL_2801_7_PID	0X2871	/* SeaLINK+8/232 (2801) Port 7 */
+#define SEALEVEL_2801_8_PID	0X2881	/* SeaLINK+8/232 (2801) Port 8 */
+#define SEALEVEL_2802_1_PID	0X2812	/* SeaLINK+8/485 (2802) Port 1 */
+#define SEALEVEL_2802_2_PID	0X2822	/* SeaLINK+8/485 (2802) Port 2 */
+#define SEALEVEL_2802_3_PID	0X2832	/* SeaLINK+8/485 (2802) Port 3 */
+#define SEALEVEL_2802_4_PID	0X2842	/* SeaLINK+8/485 (2802) Port 4 */
+#define SEALEVEL_2802_5_PID	0X2852	/* SeaLINK+8/485 (2802) Port 5 */
+#define SEALEVEL_2802_6_PID	0X2862	/* SeaLINK+8/485 (2802) Port 6 */
+#define SEALEVEL_2802_7_PID	0X2872	/* SeaLINK+8/485 (2802) Port 7 */
+#define SEALEVEL_2802_8_PID	0X2882	/* SeaLINK+8/485 (2802) Port 8 */
+#define SEALEVEL_2803_1_PID	0X2813	/* SeaLINK+8 (2803) Port 1 */
+#define SEALEVEL_2803_2_PID	0X2823 	/* SeaLINK+8 (2803) Port 2 */
+#define SEALEVEL_2803_3_PID	0X2833 	/* SeaLINK+8 (2803) Port 3 */
+#define SEALEVEL_2803_4_PID	0X2843 	/* SeaLINK+8 (2803) Port 4 */
+#define SEALEVEL_2803_5_PID	0X2853 	/* SeaLINK+8 (2803) Port 5 */
+#define SEALEVEL_2803_6_PID	0X2863 	/* SeaLINK+8 (2803) Port 6 */
+#define SEALEVEL_2803_7_PID	0X2873 	/* SeaLINK+8 (2803) Port 7 */
+#define SEALEVEL_2803_8_PID	0X2883 	/* SeaLINK+8 (2803) Port 8 */
+ 
+/*
+ * Home Electronics (www.home-electro.com) USB gadgets
+ */
+#define FTDI_HE_TIRA1_PID	0xFA78	/* Tira-1 IR tranceiver */
+
+/* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */
+/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */
+#define FTDI_USB_UIRT_PID	0xF850	/* Product Id */
 
 /* Commands */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
diff -urN linux-2.4.22-pre2/drivers/usb/serial/io_edgeport.c linux-2.4.22-pre3/drivers/usb/serial/io_edgeport.c
--- linux-2.4.22-pre2/drivers/usb/serial/io_edgeport.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/serial/io_edgeport.c	2003-07-05 18:10:54.000000000 -0700
@@ -411,6 +411,7 @@
 // MCR.7 = 0.
 //
 static struct divisor_table_entry divisor_table[] = {
+	{   50,		4608},  
 	{   75,		3072},  
 	{   110,	2095},		/* 2094.545455 => 230450   => .0217 % over */
 	{   134,	1713},		/* 1713.011152 => 230398.5 => .00065% under */
@@ -2597,7 +2598,7 @@
 	// We have tried all of the standard baud rates
 	// lets try to calculate the divisor for this baud rate
 	// Make sure the baud rate is reasonable
-	if (baudrate > 75 &&  baudrate < 230400) {
+	if (baudrate < 230400) {
 		// get divisor
 		custom = (__u16)(230400L  / baudrate);
 
diff -urN linux-2.4.22-pre2/drivers/usb/serial/pl2303.c linux-2.4.22-pre3/drivers/usb/serial/pl2303.c
--- linux-2.4.22-pre2/drivers/usb/serial/pl2303.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/serial/pl2303.c	2003-07-05 18:10:54.000000000 -0700
@@ -525,10 +525,13 @@
 {
 	struct pl2303_private *priv = port->private;
 	unsigned int mcr = priv->line_control;
+	unsigned int status = priv->line_status;
 	unsigned int result;
 
 	result = ((mcr & CONTROL_DTR)		? TIOCM_DTR : 0)
-		  | ((mcr & CONTROL_RTS)	? TIOCM_RTS : 0);
+		  | ((mcr & CONTROL_RTS)	? TIOCM_RTS : 0)
+		  | ((status & UART_CTS)	? TIOCM_CTS : 0)
+		  | ((status & UART_DSR)	? TIOCM_DSR : 0);
 
 	dbg("%s - result = %x", __FUNCTION__, result);
 
diff -urN linux-2.4.22-pre2/drivers/usb/serial/visor.c linux-2.4.22-pre3/drivers/usb/serial/visor.c
--- linux-2.4.22-pre2/drivers/usb/serial/visor.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/serial/visor.c	2003-07-05 18:10:55.000000000 -0700
@@ -12,6 +12,10 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (06/03/2003) Judd Montgomery <judd at jpilot.org>
+ *	Added support for module parameter options for untested/unknown
+ *	devices.
+ *
  * (03/09/2003) gkh
  *	Added support for the Sony Clie NZ90V device.  Thanks to Martin Brachtl
  *	<brachtl@redgrep.cz> for the information.
@@ -182,6 +186,11 @@
 static int  clie_3_5_startup	(struct usb_serial *serial);
 static void treo_attach		(struct usb_serial *serial);
 
+/* Parameters that may be passed into the module. */
+static int vendor = -1;
+static int product = -1;
+static int param_register;
+
 
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
@@ -233,6 +242,12 @@
 	{ }					/* Terminating entry */
 };
 
+/* For passed in parameters */
+static struct usb_device_id id_param_table [] = {
+	{ },
+	{ }					/* Terminating entry */
+};
+
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 
@@ -285,6 +300,34 @@
 	.read_bulk_callback =	visor_read_bulk_callback,
 };
 
+/* This structure is for Handspring Visor, and Palm 4.0 devices that are not
+ * compiled into the kernel, but can be passed in when the module is loaded.
+ * This will allow the visor driver to work with new Vendor and Device IDs
+ * without recompiling the driver.
+ */
+static struct usb_serial_device_type param_device = {
+	.owner =		THIS_MODULE,
+	.name =			"user specified device with Palm 4.x protocols",
+	.id_table =		id_param_table,
+	.num_interrupt_in =	NUM_DONT_CARE,
+	.num_bulk_in =		2,
+	.num_bulk_out =		2,
+	.num_ports =		2,
+	.open =			visor_open,
+	.close =		visor_close,
+	.throttle =		visor_throttle,
+	.unthrottle =		visor_unthrottle,
+	.startup =		visor_startup,
+	.shutdown =		visor_shutdown,
+	.ioctl =		visor_ioctl,
+	.set_termios =		visor_set_termios,
+	.write =		visor_write,
+	.write_room =		visor_write_room,
+	.chars_in_buffer =	visor_chars_in_buffer,
+	.write_bulk_callback =	visor_write_bulk_callback,
+	.read_bulk_callback =	visor_read_bulk_callback,
+	.read_int_callback =	visor_read_int_callback,
+};
 
 #define NUM_URBS			24
 #define URB_TRANSFER_BUFFER_SIZE	768
@@ -925,6 +968,19 @@
 	struct urb *urb;
 	int i;
 
+	/* Only if parameters were passed to us */
+	if ((vendor > 0) && (product > 0)) {
+       		struct usb_device_id usb_dev_temp[]=
+	       		{{USB_DEVICE(vendor, product)}};
+		id_param_table[0] = usb_dev_temp[0];
+		info("Untested USB device specified at time of module insertion");
+		info("Warning: This is not guaranteed to work");
+		info("Using a newer kernel is preferred to this method");
+		info("Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x",
+			param_device.id_table[0].idVendor, param_device.id_table[0].idProduct);
+		param_register = 1;
+		usb_serial_register (&param_device);
+	}
 	usb_serial_register (&handspring_device);
 	usb_serial_register (&clie_3_5_device);
 	
@@ -957,6 +1013,10 @@
 	int i;
 	unsigned long flags;
 
+	if (param_register) {
+		param_register = 0;
+		usb_serial_deregister (&param_device);
+	}
 	usb_serial_deregister (&handspring_device);
 	usb_serial_deregister (&clie_3_5_device);
 
@@ -987,3 +1047,7 @@
 
 MODULE_PARM(debug, "i");
 MODULE_PARM_DESC(debug, "Debug enabled or not");
+MODULE_PARM(vendor, "i");
+MODULE_PARM_DESC(vendor, "User specified vendor ID");
+MODULE_PARM(product, "i");
+MODULE_PARM_DESC(product, "User specified product ID");
diff -urN linux-2.4.22-pre2/drivers/usb/speedcrc.c linux-2.4.22-pre3/drivers/usb/speedcrc.c
--- linux-2.4.22-pre2/drivers/usb/speedcrc.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/speedcrc.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,124 +0,0 @@
-/******************************************************************************
- *  speedcrc.c  --  CRC library for use with speedtouch.
- *
- *  Copyright (C) 2000, Johan Verrept
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the Free
- *  Software Foundation; either 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 <stddef.h>
-
-/*
- * CRC Routines from  net/wan/sbni.c)
- * table generated by Rocksoft^tm Model CRC Algorithm Table Generation Program V1.0
- */
-#define CRC32_REMAINDER CBF43926
-#define CRC32_INITIAL 0xffffffff
-unsigned long crc32tab[256] = {
-	0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
-	0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
-	0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L,
-	0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL,
-	0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L,
-	0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L,
-	0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L,
-	0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL,
-	0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L,
-	0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L,
-	0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L,
-	0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL,
-	0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L,
-	0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L,
-	0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L,
-	0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL,
-	0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL,
-	0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L,
-	0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L,
-	0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL,
-	0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL,
-	0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L,
-	0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L,
-	0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL,
-	0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL,
-	0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L,
-	0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L,
-	0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL,
-	0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL,
-	0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L,
-	0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L,
-	0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL,
-	0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L,
-	0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL,
-	0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL,
-	0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L,
-	0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L,
-	0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL,
-	0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL,
-	0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L,
-	0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L,
-	0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL,
-	0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL,
-	0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L,
-	0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L,
-	0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL,
-	0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL,
-	0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L,
-	0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L,
-	0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL,
-	0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L,
-	0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L,
-	0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L,
-	0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL,
-	0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L,
-	0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L,
-	0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L,
-	0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL,
-	0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L,
-	0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L,
-	0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L,
-	0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL,
-	0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
-	0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
-};
-
-#ifdef CRCASM
-
-unsigned long spdcrc32 (char *mem, int len, unsigned initial)
-{
-	unsigned crc, dummy_len;
-      __asm__ ("xorl %%eax,%%eax\n\t" "1:\n\t" "movl %%edx,%%eax\n\t" "shrl $16,%%eax\n\t" "lodsb\n\t" "xorb %%ah,%%al\n\t" "andl $255,%%eax\n\t" "shll $8,%%edx\n\t" "xorl (%%edi,%%eax,4),%%edx\n\t" "loop 1b":"=d" (crc),
-		 "=c"
-		 (dummy_len)
-      :	 "S" (mem), "D" (&crc32tab[0]), "1" (len), "0" (initial)
-      :	 "eax");
-	return crc;
-}
-
-#else
-
-#define CRC32(c,crc) (crc32tab[((size_t)(crc>>24) ^ (c)) & 0xff] ^ (((crc) << 8)))
-
-unsigned long spdcrc32 (char *mem, int len, unsigned initial)
-{
-	unsigned crc;
-	crc = initial;
-
-	for (; len; mem++, len--) {
-		crc = CRC32 (*mem, crc);
-	}
-	return (crc);
-}
-#endif
diff -urN linux-2.4.22-pre2/drivers/usb/speedcrc.h linux-2.4.22-pre3/drivers/usb/speedcrc.h
--- linux-2.4.22-pre2/drivers/usb/speedcrc.h	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/speedcrc.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,28 +0,0 @@
-#ifndef _SPEEDCRC_H_
-#define _SPEEDCRC_H_
-
-/******************************************************************************
- *  speedcrc.h  --  CRC library for use with speedtouch.
- *
- *  Copyright (C) 2000, Johan Verrept
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the Free
- *  Software Foundation; either 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.
- *
- ******************************************************************************/
-
-unsigned long spdcrc32 (char *mem, int len, unsigned initial);
-#define crc32_be(crc, mem, len) spdcrc32(mem, len, crc)
-
-#endif				/* _SPEEDCRC_H_ */
diff -urN linux-2.4.22-pre2/drivers/usb/speedtch.c linux-2.4.22-pre3/drivers/usb/speedtch.c
--- linux-2.4.22-pre2/drivers/usb/speedtch.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/drivers/usb/speedtch.c	2003-07-05 18:10:56.000000000 -0700
@@ -0,0 +1,1344 @@
+/******************************************************************************
+ *  speedtouch.c  -  Alcatel SpeedTouch USB xDSL modem driver
+ *
+ *  Copyright (C) 2001, Alcatel
+ *  Copyright (C) 2003, Duncan Sands
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; either 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.
+ *
+ ******************************************************************************/
+
+/*
+ *  Written by Johan Verrept, maintained by Duncan Sands (duncan.sands@wanadoo.fr)
+ *
+ *  1.6:	- No longer opens a connection if the firmware is not loaded
+ *  		- Added support for the speedtouch 330
+ *  		- Removed the limit on the number of devices
+ *  		- Module now autoloads on device plugin
+ *  		- Merged relevant parts of sarlib
+ *  		- Replaced the kernel thread with a tasklet
+ *  		- New packet transmission code
+ *  		- Changed proc file contents
+ *  		- Fixed all known SMP races
+ *  		- Many fixes and cleanups
+ *  		- Various fixes by Oliver Neukum (oliver@neukum.name)
+ *
+ *  1.5A:	- Backport of version for inclusion in 2.5 series kernel
+ *		- Modifications by Richard Purdie (rpurdie@rpsys.net)
+ *		- made compatible with kernel 2.5.6 onwards by changing
+ *		udsl_usb_send_data_context->urb to a pointer and adding code
+ *		to alloc and free it
+ *		- remove_wait_queue() added to udsl_atm_processqueue_thread()
+ *
+ *  1.5:	- fixed memory leak when atmsar_decode_aal5 returned NULL.
+ *		(reported by stephen.robinson@zen.co.uk)
+ *
+ *  1.4:	- changed the spin_lock() under interrupt to spin_lock_irqsave()
+ *		- unlink all active send urbs of a vcc that is being closed.
+ *
+ *  1.3.1:	- added the version number
+ *
+ *  1.3:	- Added multiple send urb support
+ *		- fixed memory leak and vcc->tx_inuse starvation bug
+ *		  when not enough memory left in vcc.
+ *
+ *  1.2:	- Fixed race condition in udsl_usb_send_data()
+ *  1.1:	- Turned off packet debugging
+ *
+ */
+
+#include <asm/semaphore.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/atm.h>
+#include <linux/atmdev.h>
+#include <linux/crc32.h>
+#include <linux/init.h>
+
+/*
+#define DEBUG
+#define VERBOSE_DEBUG
+*/
+
+#include <linux/usb.h>
+
+
+#ifdef VERBOSE_DEBUG
+static int udsl_print_packet (const unsigned char *data, int len);
+#define PACKETDEBUG(arg...)	udsl_print_packet (arg)
+#define vdbg(arg...)		dbg (arg)
+#else
+#define PACKETDEBUG(arg...)
+#define vdbg(arg...)
+#endif
+
+#define DRIVER_AUTHOR	"Johan Verrept, Duncan Sands <duncan.sands@wanadoo.fr>"
+#define DRIVER_DESC	"Alcatel SpeedTouch USB driver"
+#define DRIVER_VERSION	"1.6"
+
+static const char udsl_driver_name [] = "speedtch";
+
+#define SPEEDTOUCH_VENDORID		0x06b9
+#define SPEEDTOUCH_PRODUCTID		0x4061
+
+#define UDSL_MAX_RCV_URBS		4
+#define UDSL_MAX_SND_URBS		4
+#define UDSL_MAX_RCV_BUFS		8
+#define UDSL_MAX_SND_BUFS		8
+#define UDSL_MAX_RCV_BUF_SIZE		1024 /* ATM cells */
+#define UDSL_MAX_SND_BUF_SIZE		1024 /* ATM cells */
+#define UDSL_DEFAULT_RCV_URBS		1
+#define UDSL_DEFAULT_SND_URBS		1
+#define UDSL_DEFAULT_RCV_BUFS		2
+#define UDSL_DEFAULT_SND_BUFS		2
+#define UDSL_DEFAULT_RCV_BUF_SIZE	64 /* ATM cells */
+#define UDSL_DEFAULT_SND_BUF_SIZE	64 /* ATM cells */
+
+static unsigned int num_rcv_urbs = UDSL_DEFAULT_RCV_URBS;
+static unsigned int num_snd_urbs = UDSL_DEFAULT_SND_URBS;
+static unsigned int num_rcv_bufs = UDSL_DEFAULT_RCV_BUFS;
+static unsigned int num_snd_bufs = UDSL_DEFAULT_SND_BUFS;
+static unsigned int rcv_buf_size = UDSL_DEFAULT_RCV_BUF_SIZE;
+static unsigned int snd_buf_size = UDSL_DEFAULT_SND_BUF_SIZE;
+
+MODULE_PARM (num_rcv_urbs, "i");
+MODULE_PARM_DESC (num_rcv_urbs, "Number of urbs used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_URBS) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_URBS) ")");
+
+MODULE_PARM (num_snd_urbs, "i");
+MODULE_PARM_DESC (num_snd_urbs, "Number of urbs used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_URBS) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_URBS) ")");
+
+MODULE_PARM (num_rcv_bufs, "i");
+MODULE_PARM_DESC (num_rcv_bufs, "Number of buffers used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_BUFS) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_BUFS) ")");
+
+MODULE_PARM (num_snd_bufs, "i");
+MODULE_PARM_DESC (num_snd_bufs, "Number of buffers used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_BUFS) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_BUFS) ")");
+
+MODULE_PARM (rcv_buf_size, "i");
+MODULE_PARM_DESC (rcv_buf_size, "Size of the buffers used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_BUF_SIZE) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_BUF_SIZE) ")");
+
+MODULE_PARM (snd_buf_size, "i");
+MODULE_PARM_DESC (snd_buf_size, "Size of the buffers used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_BUF_SIZE) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_BUF_SIZE) ")");
+
+#define UDSL_IOCTL_LINE_UP		1
+#define UDSL_IOCTL_LINE_DOWN		2
+
+#define UDSL_ENDPOINT_DATA_OUT		0x07
+#define UDSL_ENDPOINT_DATA_IN		0x87
+
+#define ATM_CELL_HEADER			(ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
+#define UDSL_NUM_CELLS(x)		(((x) + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD)
+
+#define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
+
+static struct usb_device_id udsl_usb_ids [] = {
+	{ USB_DEVICE (SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID) },
+	{ }
+};
+
+MODULE_DEVICE_TABLE (usb, udsl_usb_ids);
+
+/* receive */
+
+struct udsl_receive_buffer {
+	struct list_head list;
+	unsigned char *base;
+	unsigned int filled_cells;
+};
+
+struct udsl_receiver {
+	struct list_head list;
+	struct udsl_receive_buffer *buffer;
+	struct urb *urb;
+	struct udsl_instance_data *instance;
+};
+
+struct udsl_vcc_data {
+	/* vpi/vci lookup */
+	struct list_head list;
+	short vpi;
+	int vci;
+	struct atm_vcc *vcc;
+
+	/* raw cell reassembly */
+	struct sk_buff *skb;
+	unsigned int max_pdu;
+};
+
+/* send */
+
+struct udsl_send_buffer {
+	struct list_head list;
+	unsigned char *base;
+	unsigned char *free_start;
+	unsigned int free_cells;
+};
+
+struct udsl_sender {
+	struct list_head list;
+	struct udsl_send_buffer *buffer;
+	struct urb *urb;
+	struct udsl_instance_data *instance;
+};
+
+struct udsl_control {
+	struct atm_skb_data atm_data;
+	unsigned int num_cells;
+	unsigned int num_entire;
+	unsigned int pdu_padding;
+	unsigned char cell_header [ATM_CELL_HEADER];
+	unsigned char aal5_trailer [ATM_AAL5_TRAILER];
+};
+
+#define UDSL_SKB(x)		((struct udsl_control *)(x)->cb)
+
+/* main driver data */
+
+struct udsl_instance_data {
+	struct semaphore serialize;
+
+	/* USB device part */
+	struct usb_device *usb_dev;
+	char description [64];
+	int firmware_loaded;
+
+	/* ATM device part */
+	struct atm_dev *atm_dev;
+	struct list_head vcc_list;
+
+	/* receive */
+	struct udsl_receiver receivers [UDSL_MAX_RCV_URBS];
+	struct udsl_receive_buffer receive_buffers [UDSL_MAX_RCV_BUFS];
+
+	spinlock_t receive_lock;
+	struct list_head spare_receivers;
+	struct list_head filled_receive_buffers;
+
+	struct tasklet_struct receive_tasklet;
+	struct list_head spare_receive_buffers;
+
+	/* send */
+	struct udsl_sender senders [UDSL_MAX_SND_URBS];
+	struct udsl_send_buffer send_buffers [UDSL_MAX_SND_BUFS];
+
+	struct sk_buff_head sndqueue;
+
+	spinlock_t send_lock;
+	struct list_head spare_senders;
+	struct list_head spare_send_buffers;
+
+	struct tasklet_struct send_tasklet;
+	struct sk_buff *current_skb;			/* being emptied */
+	struct udsl_send_buffer *current_buffer;	/* being filled */
+	struct list_head filled_send_buffers;
+};
+
+/* ATM */
+
+static void udsl_atm_dev_close (struct atm_dev *dev);
+static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci);
+static void udsl_atm_close (struct atm_vcc *vcc);
+static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg);
+static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb);
+static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page);
+
+static struct atmdev_ops udsl_atm_devops = {
+	dev_close:	udsl_atm_dev_close,
+	open:		udsl_atm_open,
+	close:		udsl_atm_close,
+	ioctl:		udsl_atm_ioctl,
+	send:		udsl_atm_send,
+	proc_read:	udsl_atm_proc_read,
+	owner:		THIS_MODULE,
+};
+
+/* USB */
+
+static void *udsl_usb_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id);
+static void udsl_usb_disconnect (struct usb_device *dev, void *ptr);
+static int udsl_usb_ioctl (struct usb_device *hub, unsigned int code, void *user_data);
+
+static struct usb_driver udsl_usb_driver = {
+	owner:		THIS_MODULE,
+	name:		udsl_driver_name,
+	probe:		udsl_usb_probe,
+	disconnect:	udsl_usb_disconnect,
+	ioctl:		udsl_usb_ioctl,
+	id_table:	udsl_usb_ids,
+};
+
+
+/*************
+**  decode  **
+*************/
+
+static inline struct udsl_vcc_data *udsl_find_vcc (struct udsl_instance_data *instance, short vpi, int vci)
+{
+	struct udsl_vcc_data *vcc;
+
+	list_for_each_entry (vcc, &instance->vcc_list, list)
+		if ((vcc->vci == vci) && (vcc->vpi == vpi))
+			return vcc;
+	return NULL;
+}
+
+static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned char *source, unsigned int howmany)
+{
+	struct udsl_vcc_data *cached_vcc = NULL;
+	struct atm_vcc *vcc;
+	struct sk_buff *skb;
+	struct udsl_vcc_data *vcc_data;
+	int cached_vci = 0;
+	unsigned int i;
+	unsigned int length;
+	unsigned int pdu_length;
+	int pti;
+	int vci;
+	short cached_vpi = 0;
+	short vpi;
+
+	for (i = 0; i < howmany; i++, source += ATM_CELL_SIZE) {
+		vpi = ((source [0] & 0x0f) << 4) | (source [1] >> 4);
+		vci = ((source [1] & 0x0f) << 12) | (source [2] << 4) | (source [3] >> 4);
+		pti = (source [3] & 0x2) != 0;
+
+		vdbg ("udsl_extract_cells: vpi %hd, vci %d, pti %d", vpi, vci, pti);
+
+		if (cached_vcc && (vci == cached_vci) && (vpi == cached_vpi))
+			vcc_data = cached_vcc;
+		else if ((vcc_data = udsl_find_vcc (instance, vpi, vci))) {
+			cached_vcc = vcc_data;
+			cached_vpi = vpi;
+			cached_vci = vci;
+		} else {
+			dbg ("udsl_extract_cells: unknown vpi/vci (%hd/%d)!", vpi, vci);
+			continue;
+		}
+
+		vcc = vcc_data->vcc;
+
+		if (!vcc_data->skb && !(vcc_data->skb = dev_alloc_skb (vcc_data->max_pdu))) {
+			dbg ("udsl_extract_cells: no memory for skb (vcc: 0x%p)!", vcc);
+			if (pti)
+				atomic_inc (&vcc->stats->rx_err);
+			continue;
+		}
+
+		skb = vcc_data->skb;
+
+		if (skb->len + ATM_CELL_PAYLOAD > vcc_data->max_pdu) {
+			dbg ("udsl_extract_cells: buffer overrun (max_pdu: %u, skb->len %u, vcc: 0x%p)", vcc_data->max_pdu, skb->len, vcc);
+			/* discard cells already received */
+			skb_trim (skb, 0);
+			BUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
+		}
+
+		memcpy (skb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
+		__skb_put (skb, ATM_CELL_PAYLOAD);
+
+		if (pti) {
+			length = (source [ATM_CELL_SIZE - 6] << 8) + source [ATM_CELL_SIZE - 5];
+
+			/* guard against overflow */
+			if (length > ATM_MAX_AAL5_PDU) {
+				dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)", length, vcc);
+				goto drop;
+			}
+
+			pdu_length = UDSL_NUM_CELLS (length) * ATM_CELL_PAYLOAD;
+
+			if (skb->len < pdu_length) {
+				dbg ("udsl_extract_cells: bogus pdu_length %u (skb->len: %u, vcc: 0x%p)", pdu_length, skb->len, vcc);
+				goto drop;
+			}
+
+			if (crc32_be (~0, skb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
+				dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)", vcc);
+				goto drop;
+			}
+
+			if (!atm_charge (vcc, skb->truesize)) {
+				dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)", skb->truesize);
+				goto drop_no_stats; /* atm_charge increments rx_drop */
+			}
+
+			/* now that we are sure to send the skb, it is ok to change skb->data */
+			if (skb->len > pdu_length)
+				skb_pull (skb, skb->len - pdu_length); /* discard initial junk */
+
+			skb_trim (skb, length); /* drop zero padding and trailer */
+
+			atomic_inc (&vcc->stats->rx);
+
+			PACKETDEBUG (skb->data, skb->len);
+
+			vdbg ("udsl_extract_cells: sending skb 0x%p, skb->len %u, skb->truesize %u", skb, skb->len, skb->truesize);
+
+			vcc->push (vcc, skb);
+
+			vcc_data->skb = NULL;
+
+			continue;
+
+drop:
+			atomic_inc (&vcc->stats->rx_err);
+drop_no_stats:
+			skb_trim (skb, 0);
+		}
+	}
+}
+
+
+/*************
+**  encode  **
+*************/
+
+static const unsigned char zeros [ATM_CELL_PAYLOAD];
+
+static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb)
+{
+	struct udsl_control *ctrl = UDSL_SKB (skb);
+	unsigned int zero_padding;
+	u32 crc;
+
+	ctrl->atm_data.vcc = vcc;
+	ctrl->cell_header [0] = vcc->vpi >> 4;
+	ctrl->cell_header [1] = (vcc->vpi << 4) | (vcc->vci >> 12);
+	ctrl->cell_header [2] = vcc->vci >> 4;
+	ctrl->cell_header [3] = vcc->vci << 4;
+	ctrl->cell_header [4] = 0xec;
+
+	ctrl->num_cells = UDSL_NUM_CELLS (skb->len);
+	ctrl->num_entire = skb->len / ATM_CELL_PAYLOAD;
+
+	zero_padding = ctrl->num_cells * ATM_CELL_PAYLOAD - skb->len - ATM_AAL5_TRAILER;
+
+	if (ctrl->num_entire + 1 < ctrl->num_cells)
+		ctrl->pdu_padding = zero_padding - (ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
+	else
+		ctrl->pdu_padding = zero_padding;
+
+	ctrl->aal5_trailer [0] = 0; /* UU = 0 */
+	ctrl->aal5_trailer [1] = 0; /* CPI = 0 */
+	ctrl->aal5_trailer [2] = skb->len >> 8;
+	ctrl->aal5_trailer [3] = skb->len;
+
+	crc = crc32_be (~0, skb->data, skb->len);
+	crc = crc32_be (crc, zeros, zero_padding);
+	crc = crc32_be (crc, ctrl->aal5_trailer, 4);
+	crc = ~crc;
+
+	ctrl->aal5_trailer [4] = crc >> 24;
+	ctrl->aal5_trailer [5] = crc >> 16;
+	ctrl->aal5_trailer [6] = crc >> 8;
+	ctrl->aal5_trailer [7] = crc;
+}
+
+static unsigned int udsl_write_cells (unsigned int howmany, struct sk_buff *skb, unsigned char **target_p)
+{
+	struct udsl_control *ctrl = UDSL_SKB (skb);
+	unsigned char *target = *target_p;
+	unsigned int nc, ne, i;
+
+	vdbg ("udsl_write_cells: howmany=%u, skb->len=%d, num_cells=%u, num_entire=%u, pdu_padding=%u", howmany, skb->len, ctrl->num_cells, ctrl->num_entire, ctrl->pdu_padding);
+
+	nc = ctrl->num_cells;
+	ne = min (howmany, ctrl->num_entire);
+
+	for (i = 0; i < ne; i++) {
+		memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
+		target += ATM_CELL_HEADER;
+		memcpy (target, skb->data, ATM_CELL_PAYLOAD);
+		target += ATM_CELL_PAYLOAD;
+		__skb_pull (skb, ATM_CELL_PAYLOAD);
+	}
+
+	ctrl->num_entire -= ne;
+
+	if (!(ctrl->num_cells -= ne) || !(howmany -= ne))
+		goto out;
+
+	memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
+	target += ATM_CELL_HEADER;
+	memcpy (target, skb->data, skb->len);
+	target += skb->len;
+	__skb_pull (skb, skb->len);
+	memset (target, 0, ctrl->pdu_padding);
+	target += ctrl->pdu_padding;
+
+	if (--ctrl->num_cells) {
+		if (!--howmany) {
+			ctrl->pdu_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
+			goto out;
+		}
+
+		memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
+		target += ATM_CELL_HEADER;
+		memset (target, 0, ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
+		target += ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
+
+		BUG_ON (--ctrl->num_cells);
+	}
+
+	memcpy (target, ctrl->aal5_trailer, ATM_AAL5_TRAILER);
+	target += ATM_AAL5_TRAILER;
+	/* set pti bit in last cell */
+	*(target + 3 - ATM_CELL_SIZE) |= 0x2;
+
+out:
+	*target_p = target;
+	return nc - ctrl->num_cells;
+}
+
+
+/**************
+**  receive  **
+**************/
+
+static void udsl_complete_receive (struct urb *urb)
+{
+	struct udsl_receive_buffer *buf;
+	struct udsl_instance_data *instance;
+	struct udsl_receiver *rcv;
+	unsigned long flags;
+
+	if (!urb || !(rcv = urb->context)) {
+		dbg ("udsl_complete_receive: bad urb!");
+		return;
+	}
+
+	instance = rcv->instance;
+	buf = rcv->buffer;
+
+	buf->filled_cells = urb->actual_length / ATM_CELL_SIZE;
+
+	vdbg ("udsl_complete_receive: urb 0x%p, status %d, actual_length %d, filled_cells %u, rcv 0x%p, buf 0x%p", urb, urb->status, urb->actual_length, buf->filled_cells, rcv, buf);
+
+	BUG_ON (buf->filled_cells > rcv_buf_size);
+
+	/* may not be in_interrupt() */
+	spin_lock_irqsave (&instance->receive_lock, flags);
+	list_add (&rcv->list, &instance->spare_receivers);
+	list_add_tail (&buf->list, &instance->filled_receive_buffers);
+	if (likely (!urb->status))
+		tasklet_schedule (&instance->receive_tasklet);
+	spin_unlock_irqrestore (&instance->receive_lock, flags);
+}
+
+static void udsl_process_receive (unsigned long data)
+{
+	struct udsl_receive_buffer *buf;
+	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
+	struct udsl_receiver *rcv;
+	int err;
+
+made_progress:
+	while (!list_empty (&instance->spare_receive_buffers)) {
+		spin_lock_irq (&instance->receive_lock);
+		if (list_empty (&instance->spare_receivers)) {
+			spin_unlock_irq (&instance->receive_lock);
+			break;
+		}
+		rcv = list_entry (instance->spare_receivers.next, struct udsl_receiver, list);
+		list_del (&rcv->list);
+		spin_unlock_irq (&instance->receive_lock);
+
+		buf = list_entry (instance->spare_receive_buffers.next, struct udsl_receive_buffer, list);
+		list_del (&buf->list);
+
+		rcv->buffer = buf;
+
+		FILL_BULK_URB (rcv->urb,
+			       instance->usb_dev,
+			       usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
+			       buf->base,
+			       rcv_buf_size * ATM_CELL_SIZE,
+			       udsl_complete_receive,
+			       rcv);
+		rcv->urb->transfer_flags |= USB_QUEUE_BULK;
+
+		vdbg ("udsl_process_receive: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf);
+
+		if ((err = usb_submit_urb(rcv->urb)) < 0) {
+			dbg ("udsl_process_receive: urb submission failed (%d)!", err);
+			list_add (&buf->list, &instance->spare_receive_buffers);
+			spin_lock_irq (&instance->receive_lock);
+			list_add (&rcv->list, &instance->spare_receivers);
+			spin_unlock_irq (&instance->receive_lock);
+			break;
+		}
+	}
+
+	spin_lock_irq (&instance->receive_lock);
+	if (list_empty (&instance->filled_receive_buffers)) {
+		spin_unlock_irq (&instance->receive_lock);
+		return; /* done - no more buffers */
+	}
+	buf = list_entry (instance->filled_receive_buffers.next, struct udsl_receive_buffer, list);
+	list_del (&buf->list);
+	spin_unlock_irq (&instance->receive_lock);
+	vdbg ("udsl_process_receive: processing buf 0x%p", buf);
+	udsl_extract_cells (instance, buf->base, buf->filled_cells);
+	list_add (&buf->list, &instance->spare_receive_buffers);
+	goto made_progress;
+}
+
+
+/***********
+**  send  **
+***********/
+
+static void udsl_complete_send (struct urb *urb)
+{
+	struct udsl_instance_data *instance;
+	struct udsl_sender *snd;
+	unsigned long flags;
+
+	if (!urb || !(snd = urb->context) || !(instance = snd->instance)) {
+		dbg ("udsl_complete_send: bad urb!");
+		return;
+	}
+
+	vdbg ("udsl_complete_send: urb 0x%p, status %d, snd 0x%p, buf 0x%p", urb, urb->status, snd, snd->buffer);
+
+	/* may not be in_interrupt() */
+	spin_lock_irqsave (&instance->send_lock, flags);
+	list_add (&snd->list, &instance->spare_senders);
+	list_add (&snd->buffer->list, &instance->spare_send_buffers);
+	tasklet_schedule (&instance->send_tasklet);
+	spin_unlock_irqrestore (&instance->send_lock, flags);
+}
+
+static void udsl_process_send (unsigned long data)
+{
+	struct udsl_send_buffer *buf;
+	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
+	struct sk_buff *skb;
+	struct udsl_sender *snd;
+	int err;
+	unsigned int num_written;
+
+made_progress:
+	spin_lock_irq (&instance->send_lock);
+	while (!list_empty (&instance->spare_senders)) {
+		if (!list_empty (&instance->filled_send_buffers)) {
+			buf = list_entry (instance->filled_send_buffers.next, struct udsl_send_buffer, list);
+			list_del (&buf->list);
+		} else if ((buf = instance->current_buffer)) {
+			instance->current_buffer = NULL;
+		} else /* all buffers empty */
+			break;
+
+		snd = list_entry (instance->spare_senders.next, struct udsl_sender, list);
+		list_del (&snd->list);
+		spin_unlock_irq (&instance->send_lock);
+
+		snd->buffer = buf;
+	        FILL_BULK_URB (snd->urb,
+			       instance->usb_dev,
+			       usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
+			       buf->base,
+			       (snd_buf_size - buf->free_cells) * ATM_CELL_SIZE,
+			       udsl_complete_send,
+			       snd);
+		snd->urb->transfer_flags |= USB_QUEUE_BULK;
+
+		vdbg ("udsl_process_send: submitting urb 0x%p (%d cells), snd 0x%p, buf 0x%p", snd->urb, snd_buf_size - buf->free_cells, snd, buf);
+
+		if ((err = usb_submit_urb(snd->urb)) < 0) {
+			dbg ("udsl_process_send: urb submission failed (%d)!", err);
+			spin_lock_irq (&instance->send_lock);
+			list_add (&snd->list, &instance->spare_senders);
+			spin_unlock_irq (&instance->send_lock);
+			list_add (&buf->list, &instance->filled_send_buffers);
+			return; /* bail out */
+		}
+
+		spin_lock_irq (&instance->send_lock);
+	} /* while */
+	spin_unlock_irq (&instance->send_lock);
+
+	if (!instance->current_skb && !(instance->current_skb = skb_dequeue (&instance->sndqueue)))
+		return; /* done - no more skbs */
+
+	skb = instance->current_skb;
+
+	if (!(buf = instance->current_buffer)) {
+		spin_lock_irq (&instance->send_lock);
+		if (list_empty (&instance->spare_send_buffers)) {
+			instance->current_buffer = NULL;
+			spin_unlock_irq (&instance->send_lock);
+			return; /* done - no more buffers */
+		}
+		buf = list_entry (instance->spare_send_buffers.next, struct udsl_send_buffer, list);
+		list_del (&buf->list);
+		spin_unlock_irq (&instance->send_lock);
+
+		buf->free_start = buf->base;
+		buf->free_cells = snd_buf_size;
+
+		instance->current_buffer = buf;
+	}
+
+	num_written = udsl_write_cells (buf->free_cells, skb, &buf->free_start);
+
+	vdbg ("udsl_process_send: wrote %u cells from skb 0x%p to buffer 0x%p", num_written, skb, buf);
+
+	if (!(buf->free_cells -= num_written)) {
+		list_add_tail (&buf->list, &instance->filled_send_buffers);
+		instance->current_buffer = NULL;
+	}
+
+	vdbg ("udsl_process_send: buffer contains %d cells, %d left", snd_buf_size - buf->free_cells, buf->free_cells);
+
+	if (!UDSL_SKB (skb)->num_cells) {
+		struct atm_vcc *vcc = UDSL_SKB (skb)->atm_data.vcc;
+
+		if (vcc->pop)
+			vcc->pop (vcc, skb);
+		else
+			dev_kfree_skb (skb);
+		instance->current_skb = NULL;
+
+		atomic_inc (&vcc->stats->tx);
+	}
+
+	goto made_progress;
+}
+
+static void udsl_cancel_send (struct udsl_instance_data *instance, struct atm_vcc *vcc)
+{
+	struct sk_buff *skb, *n;
+
+	dbg ("udsl_cancel_send entered");
+	spin_lock_irq (&instance->sndqueue.lock);
+	for (skb = instance->sndqueue.next, n = skb->next; skb != (struct sk_buff *)&instance->sndqueue; skb = n, n = skb->next)
+		if (UDSL_SKB (skb)->atm_data.vcc == vcc) {
+			dbg ("udsl_cancel_send: popping skb 0x%p", skb);
+			__skb_unlink (skb, &instance->sndqueue);
+			if (vcc->pop)
+				vcc->pop (vcc, skb);
+			else
+				dev_kfree_skb (skb);
+		}
+	spin_unlock_irq (&instance->sndqueue.lock);
+
+	tasklet_disable (&instance->send_tasklet);
+	if ((skb = instance->current_skb) && (UDSL_SKB (skb)->atm_data.vcc == vcc)) {
+		dbg ("udsl_cancel_send: popping current skb (0x%p)", skb);
+		instance->current_skb = NULL;
+		if (vcc->pop)
+			vcc->pop (vcc, skb);
+		else
+			dev_kfree_skb (skb);
+	}
+	tasklet_enable (&instance->send_tasklet);
+	dbg ("udsl_cancel_send done");
+}
+
+static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
+{
+	struct udsl_instance_data *instance = vcc->dev->dev_data;
+
+	vdbg ("udsl_atm_send called (skb 0x%p, len %u)", skb, skb->len);
+
+	if (!instance || !instance->usb_dev) {
+		dbg ("udsl_atm_send: NULL data!");
+		return -ENODEV;
+	}
+
+	if (vcc->qos.aal != ATM_AAL5) {
+		dbg ("udsl_atm_send: unsupported ATM type %d!", vcc->qos.aal);
+		return -EINVAL;
+	}
+
+	if (skb->len > ATM_MAX_AAL5_PDU) {
+		dbg ("udsl_atm_send: packet too long (%d vs %d)!", skb->len, ATM_MAX_AAL5_PDU);
+		return -EINVAL;
+	}
+
+	PACKETDEBUG (skb->data, skb->len);
+
+	udsl_groom_skb (vcc, skb);
+	skb_queue_tail (&instance->sndqueue, skb);
+	tasklet_schedule (&instance->send_tasklet);
+
+	return 0;
+}
+
+
+/**********
+**  ATM  **
+**********/
+
+static void udsl_atm_dev_close (struct atm_dev *dev)
+{
+	struct udsl_instance_data *instance = dev->dev_data;
+
+	if (!instance) {
+		dbg ("udsl_atm_dev_close: NULL instance!");
+		return;
+	}
+
+	dbg ("udsl_atm_dev_close: queue has %u elements", instance->sndqueue.qlen);
+
+	tasklet_kill (&instance->receive_tasklet);
+	tasklet_kill (&instance->send_tasklet);
+	kfree (instance);
+	dev->dev_data = NULL;
+}
+
+static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page)
+{
+	struct udsl_instance_data *instance = atm_dev->dev_data;
+	int left = *pos;
+
+	if (!instance) {
+		dbg ("udsl_atm_proc_read: NULL instance!");
+		return -ENODEV;
+	}
+
+	if (!left--)
+		return sprintf (page, "%s\n", instance->description);
+
+	if (!left--)
+		return sprintf (page, "MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+				atm_dev->esi [0], atm_dev->esi [1], atm_dev->esi [2],
+				atm_dev->esi [3], atm_dev->esi [4], atm_dev->esi [5]);
+
+	if (!left--)
+		return sprintf (page, "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n",
+				atomic_read (&atm_dev->stats.aal5.tx),
+				atomic_read (&atm_dev->stats.aal5.tx_err),
+				atomic_read (&atm_dev->stats.aal5.rx),
+				atomic_read (&atm_dev->stats.aal5.rx_err),
+				atomic_read (&atm_dev->stats.aal5.rx_drop));
+
+	if (!left--) {
+		switch (atm_dev->signal) {
+		case ATM_PHY_SIG_FOUND:
+			sprintf (page, "Line up");
+			break;
+		case ATM_PHY_SIG_LOST:
+			sprintf (page, "Line down");
+			break;
+		default:
+			sprintf (page, "Line state unknown");
+			break;
+		}
+
+		if (instance->usb_dev) {
+			if (!instance->firmware_loaded)
+				strcat (page, ", no firmware\n");
+			else
+				strcat (page, ", firmware loaded\n");
+		} else
+			strcat (page, ", disconnected\n");
+
+		return strlen (page);
+	}
+
+	return 0;
+}
+
+static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
+{
+	struct udsl_instance_data *instance = vcc->dev->dev_data;
+	struct udsl_vcc_data *new;
+
+	dbg ("udsl_atm_open: vpi %hd, vci %d", vpi, vci);
+
+	if (!instance || !instance->usb_dev) {
+		dbg ("udsl_atm_open: NULL data!");
+		return -ENODEV;
+	}
+
+	if ((vpi == ATM_VPI_ANY) || (vci == ATM_VCI_ANY))
+		return -EINVAL;
+
+	/* only support AAL5 */
+	if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU))
+		return -EINVAL;
+
+	if (!instance->firmware_loaded) {
+		dbg ("udsl_atm_open: firmware not loaded!");
+		return -EAGAIN;
+	}
+
+	down (&instance->serialize); /* vs self, udsl_atm_close */
+
+	if (udsl_find_vcc (instance, vpi, vci)) {
+		up (&instance->serialize);
+		return -EADDRINUSE;
+	}
+
+	if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) {
+		up (&instance->serialize);
+		return -ENOMEM;
+	}
+
+	memset (new, 0, sizeof (struct udsl_vcc_data));
+	new->vcc = vcc;
+	new->vpi = vpi;
+	new->vci = vci;
+	new->max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
+
+	vcc->dev_data = new;
+	vcc->vpi = vpi;
+	vcc->vci = vci;
+
+	tasklet_disable (&instance->receive_tasklet);
+	list_add (&new->list, &instance->vcc_list);
+	tasklet_enable (&instance->receive_tasklet);
+
+	set_bit (ATM_VF_ADDR, &vcc->flags);
+	set_bit (ATM_VF_PARTIAL, &vcc->flags);
+	set_bit (ATM_VF_READY, &vcc->flags);
+
+	up (&instance->serialize);
+
+	tasklet_schedule (&instance->receive_tasklet);
+
+	dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, new->max_pdu);
+
+	return 0;
+}
+
+static void udsl_atm_close (struct atm_vcc *vcc)
+{
+	struct udsl_instance_data *instance = vcc->dev->dev_data;
+	struct udsl_vcc_data *vcc_data = vcc->dev_data;
+
+	dbg ("udsl_atm_close called");
+
+	if (!instance || !vcc_data) {
+		dbg ("udsl_atm_close: NULL data!");
+		return;
+	}
+
+	dbg ("udsl_atm_close: deallocating vcc 0x%p with vpi %d vci %d", vcc_data, vcc_data->vpi, vcc_data->vci);
+
+	udsl_cancel_send (instance, vcc);
+
+	down (&instance->serialize); /* vs self, udsl_atm_open */
+
+	tasklet_disable (&instance->receive_tasklet);
+	list_del (&vcc_data->list);
+	tasklet_enable (&instance->receive_tasklet);
+
+	if (vcc_data->skb)
+		dev_kfree_skb (vcc_data->skb);
+	vcc_data->skb = NULL;
+
+	kfree (vcc_data);
+	vcc->dev_data = NULL;
+
+	vcc->vpi = ATM_VPI_UNSPEC;
+	vcc->vci = ATM_VCI_UNSPEC;
+	clear_bit (ATM_VF_READY, &vcc->flags);
+	clear_bit (ATM_VF_PARTIAL, &vcc->flags);
+	clear_bit (ATM_VF_ADDR, &vcc->flags);
+
+	up (&instance->serialize);
+
+	dbg ("udsl_atm_close successful");
+}
+
+static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
+{
+	switch (cmd) {
+	case ATM_QUERYLOOP:
+		return put_user (ATM_LM_NONE, (int *) arg) ? -EFAULT : 0;
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+
+/**********
+**  USB  **
+**********/
+
+static int udsl_set_alternate (struct udsl_instance_data *instance)
+{
+	down (&instance->serialize); /* vs self */
+	if (!instance->firmware_loaded) {
+		int ret;
+
+		if ((ret = usb_set_interface (instance->usb_dev, 1, 1)) < 0) {
+			dbg ("udsl_set_alternate: usb_set_interface returned %d!", ret);
+			up (&instance->serialize);
+			return ret;
+		}
+		instance->firmware_loaded = 1;
+	}
+	up (&instance->serialize);
+
+	tasklet_schedule (&instance->receive_tasklet);
+
+	return 0;
+}
+
+static int udsl_usb_ioctl (struct usb_device *dev, unsigned int code, void *user_data)
+{
+	struct usb_interface *intf = usb_ifnum_to_if (dev, 1);
+	struct udsl_instance_data *instance = intf->private_data;
+
+	dbg ("udsl_usb_ioctl entered");
+
+	if (!instance) {
+		dbg ("udsl_usb_ioctl: NULL instance!");
+		return -ENODEV;
+	}
+
+	switch (code) {
+	case UDSL_IOCTL_LINE_UP:
+		instance->atm_dev->signal = ATM_PHY_SIG_FOUND;
+		return udsl_set_alternate (instance);
+	case UDSL_IOCTL_LINE_DOWN:
+		instance->atm_dev->signal = ATM_PHY_SIG_LOST;
+		return 0;
+	default:
+		return -ENOTTY;
+	}
+}
+
+static void *udsl_usb_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
+{
+	struct udsl_instance_data *instance;
+	unsigned char mac_str [13];
+	int i, length;
+	char *buf;
+
+	dbg ("udsl_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d",
+	     dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
+
+	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
+	    (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) ||
+	    (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))
+		return NULL;
+
+	dbg ("udsl_usb_probe: device accepted");
+
+	/* instance init */
+	if (!(instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL))) {
+		dbg ("udsl_usb_probe: no memory for instance data!");
+		return NULL;
+	}
+
+	memset (instance, 0, sizeof (struct udsl_instance_data));
+
+	init_MUTEX (&instance->serialize);
+
+	instance->usb_dev = dev;
+
+	INIT_LIST_HEAD (&instance->vcc_list);
+
+	spin_lock_init (&instance->receive_lock);
+	INIT_LIST_HEAD (&instance->spare_receivers);
+	INIT_LIST_HEAD (&instance->filled_receive_buffers);
+
+	tasklet_init (&instance->receive_tasklet, udsl_process_receive, (unsigned long) instance);
+	INIT_LIST_HEAD (&instance->spare_receive_buffers);
+
+	skb_queue_head_init (&instance->sndqueue);
+
+	spin_lock_init (&instance->send_lock);
+	INIT_LIST_HEAD (&instance->spare_senders);
+	INIT_LIST_HEAD (&instance->spare_send_buffers);
+
+	tasklet_init (&instance->send_tasklet, udsl_process_send, (unsigned long) instance);
+	INIT_LIST_HEAD (&instance->filled_send_buffers);
+
+	/* receive init */
+	for (i = 0; i < num_rcv_urbs; i++) {
+		struct udsl_receiver *rcv = &(instance->receivers [i]);
+
+		if (!(rcv->urb = usb_alloc_urb (0))) {
+			dbg ("udsl_usb_probe: no memory for receive urb %d!", i);
+			goto fail;
+		}
+
+		rcv->instance = instance;
+
+		list_add (&rcv->list, &instance->spare_receivers);
+	}
+
+	for (i = 0; i < num_rcv_bufs; i++) {
+		struct udsl_receive_buffer *buf = &(instance->receive_buffers [i]);
+
+		if (!(buf->base = kmalloc (rcv_buf_size * ATM_CELL_SIZE, GFP_KERNEL))) {
+			dbg ("udsl_usb_probe: no memory for receive buffer %d!", i);
+			goto fail;
+		}
+
+		list_add (&buf->list, &instance->spare_receive_buffers);
+	}
+
+	/* send init */
+	for (i = 0; i < num_snd_urbs; i++) {
+		struct udsl_sender *snd = &(instance->senders [i]);
+
+		if (!(snd->urb = usb_alloc_urb (0))) {
+			dbg ("udsl_usb_probe: no memory for send urb %d!", i);
+			goto fail;
+		}
+
+		snd->instance = instance;
+
+		list_add (&snd->list, &instance->spare_senders);
+	}
+
+	for (i = 0; i < num_snd_bufs; i++) {
+		struct udsl_send_buffer *buf = &(instance->send_buffers [i]);
+
+		if (!(buf->base = kmalloc (snd_buf_size * ATM_CELL_SIZE, GFP_KERNEL))) {
+			dbg ("udsl_usb_probe: no memory for send buffer %d!", i);
+			goto fail;
+		}
+
+		list_add (&buf->list, &instance->spare_send_buffers);
+	}
+
+	/* ATM init */
+	if (!(instance->atm_dev = atm_dev_register (udsl_driver_name, &udsl_atm_devops, -1, 0))) {
+		dbg ("udsl_usb_probe: failed to register ATM device!");
+		goto fail;
+	}
+
+	instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
+	instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
+	instance->atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
+
+	/* temp init ATM device, set to 128kbit */
+	instance->atm_dev->link_rate = 128 * 1000 / 424;
+
+	/* set MAC address, it is stored in the serial number */
+	memset (instance->atm_dev->esi, 0, sizeof (instance->atm_dev->esi));
+	if (usb_string (dev, dev->descriptor.iSerialNumber, mac_str, sizeof (mac_str)) == 12)
+		for (i = 0; i < 6; i++)
+			instance->atm_dev->esi [i] = (hex2int (mac_str [i * 2]) * 16) + (hex2int (mac_str [i * 2 + 1]));
+
+	/* device description */
+	buf = instance->description;
+	length = sizeof (instance->description);
+
+	if ((i = usb_string (dev, dev->descriptor.iProduct, buf, length)) < 0)
+		goto finish;
+
+	buf += i;
+	length -= i;
+
+	i = snprintf (buf, length, " (");
+	buf += i;
+	length -= i;
+
+	if (length <= 0 || (i = usb_make_path (dev, buf, length)) < 0)
+		goto finish;
+
+	buf += i;
+	length -= i;
+
+	snprintf (buf, length, ")");
+
+finish:
+	/* ready for ATM callbacks */
+	wmb ();
+	instance->atm_dev->dev_data = instance;
+
+	return instance;
+
+fail:
+	for (i = 0; i < num_snd_bufs; i++)
+		kfree (instance->send_buffers [i].base);
+
+	for (i = 0; i < num_snd_urbs; i++)
+		usb_free_urb (instance->senders [i].urb);
+
+	for (i = 0; i < num_rcv_bufs; i++)
+		kfree (instance->receive_buffers [i].base);
+
+	for (i = 0; i < num_rcv_urbs; i++)
+		usb_free_urb (instance->receivers [i].urb);
+
+	kfree (instance);
+
+	return NULL;
+}
+
+static void udsl_usb_disconnect (struct usb_device *dev, void *ptr)
+{
+	struct udsl_instance_data *instance = ptr;
+	struct list_head *pos;
+	unsigned int count;
+	int result, i;
+
+	dbg ("udsl_usb_disconnect entered");
+
+	if (!instance) {
+		dbg ("udsl_usb_disconnect: NULL instance!");
+		return;
+	}
+
+	/* receive finalize */
+	tasklet_disable (&instance->receive_tasklet);
+
+	for (i = 0; i < num_rcv_urbs; i++)
+		if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0)
+			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result);
+
+	/* wait for completion handlers to finish */
+	do {
+		count = 0;
+		spin_lock_irq (&instance->receive_lock);
+		list_for_each (pos, &instance->spare_receivers)
+			if (++count > num_rcv_urbs)
+				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
+		spin_unlock_irq (&instance->receive_lock);
+
+		dbg ("udsl_usb_disconnect: found %u spare receivers", count);
+
+		if (count == num_rcv_urbs)
+			break;
+
+		set_current_state (TASK_RUNNING);
+		schedule ();
+	} while (1);
+
+	/* no need to take the spinlock */
+	INIT_LIST_HEAD (&instance->filled_receive_buffers);
+	INIT_LIST_HEAD (&instance->spare_receive_buffers);
+
+	tasklet_enable (&instance->receive_tasklet);
+
+	for (i = 0; i < num_rcv_urbs; i++)
+		usb_free_urb (instance->receivers [i].urb);
+
+	for (i = 0; i < num_rcv_bufs; i++)
+		kfree (instance->receive_buffers [i].base);
+
+	/* send finalize */
+	tasklet_disable (&instance->send_tasklet);
+
+	for (i = 0; i < num_snd_urbs; i++)
+		if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0)
+			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result);
+
+	/* wait for completion handlers to finish */
+	do {
+		count = 0;
+		spin_lock_irq (&instance->send_lock);
+		list_for_each (pos, &instance->spare_senders)
+			if (++count > num_snd_urbs)
+				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
+		spin_unlock_irq (&instance->send_lock);
+
+		dbg ("udsl_usb_disconnect: found %u spare senders", count);
+
+		if (count == num_snd_urbs)
+			break;
+
+		set_current_state (TASK_RUNNING);
+		schedule ();
+	} while (1);
+
+	/* no need to take the spinlock */
+	INIT_LIST_HEAD (&instance->spare_senders);
+	INIT_LIST_HEAD (&instance->spare_send_buffers);
+	instance->current_buffer = NULL;
+
+	tasklet_enable (&instance->send_tasklet);
+
+	for (i = 0; i < num_snd_urbs; i++)
+		usb_free_urb (instance->senders [i].urb);
+
+	for (i = 0; i < num_snd_bufs; i++)
+		kfree (instance->send_buffers [i].base);
+
+	wmb ();
+	instance->usb_dev = NULL;
+
+	/* ATM finalize */
+	shutdown_atm_dev (instance->atm_dev); /* frees instance, kills tasklets */
+}
+
+
+/***********
+**  init  **
+***********/
+
+static int __init udsl_usb_init (void)
+{
+	struct sk_buff *skb; /* dummy for sizeof */
+
+	dbg ("udsl_usb_init: driver version " DRIVER_VERSION);
+
+	if (sizeof (struct udsl_control) > sizeof (skb->cb)) {
+		printk (KERN_ERR __FILE__ ": unusable with this kernel!\n");
+		return -EIO;
+	}
+
+	if ((num_rcv_urbs > UDSL_MAX_RCV_URBS) || (num_snd_urbs > UDSL_MAX_SND_URBS) ||
+	    (num_rcv_bufs > UDSL_MAX_RCV_BUFS) || (num_snd_bufs > UDSL_MAX_SND_BUFS) ||
+	    (rcv_buf_size > UDSL_MAX_RCV_BUF_SIZE) || (snd_buf_size > UDSL_MAX_SND_BUF_SIZE))
+		return -EINVAL;
+
+	return usb_register (&udsl_usb_driver);
+}
+
+static void __exit udsl_usb_cleanup (void)
+{
+	dbg ("udsl_usb_cleanup entered");
+
+	usb_deregister (&udsl_usb_driver);
+}
+
+module_init (udsl_usb_init);
+module_exit (udsl_usb_cleanup);
+
+MODULE_AUTHOR (DRIVER_AUTHOR);
+MODULE_DESCRIPTION (DRIVER_DESC);
+MODULE_LICENSE ("GPL");
+
+
+/************
+**  debug  **
+************/
+
+#ifdef VERBOSE_DEBUG
+static int udsl_print_packet (const unsigned char *data, int len)
+{
+	unsigned char buffer [256];
+	int i = 0, j = 0;
+
+	for (i = 0; i < len;) {
+		buffer [0] = '\0';
+		sprintf (buffer, "%.3d :", i);
+		for (j = 0; (j < 16) && (i < len); j++, i++) {
+			sprintf (buffer, "%s %2.2x", buffer, data [i]);
+		}
+		dbg ("%s", buffer);
+	}
+	return i;
+}
+#endif
diff -urN linux-2.4.22-pre2/drivers/usb/speedtouch.c linux-2.4.22-pre3/drivers/usb/speedtouch.c
--- linux-2.4.22-pre2/drivers/usb/speedtouch.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/speedtouch.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1344 +0,0 @@
-/******************************************************************************
- *  speedtouch.c  -  Alcatel SpeedTouch USB xDSL modem driver
- *
- *  Copyright (C) 2001, Alcatel
- *  Copyright (C) 2003, Duncan Sands
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the Free
- *  Software Foundation; either 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.
- *
- ******************************************************************************/
-
-/*
- *  Written by Johan Verrept, maintained by Duncan Sands (duncan.sands@wanadoo.fr)
- *
- *  1.6:	- No longer opens a connection if the firmware is not loaded
- *  		- Added support for the speedtouch 330
- *  		- Removed the limit on the number of devices
- *  		- Module now autoloads on device plugin
- *  		- Merged relevant parts of sarlib
- *  		- Replaced the kernel thread with a tasklet
- *  		- New packet transmission code
- *  		- Changed proc file contents
- *  		- Fixed all known SMP races
- *  		- Many fixes and cleanups
- *  		- Various fixes by Oliver Neukum (oliver@neukum.name)
- *
- *  1.5A:	- Backport of version for inclusion in 2.5 series kernel
- *		- Modifications by Richard Purdie (rpurdie@rpsys.net)
- *		- made compatible with kernel 2.5.6 onwards by changing
- *		udsl_usb_send_data_context->urb to a pointer and adding code
- *		to alloc and free it
- *		- remove_wait_queue() added to udsl_atm_processqueue_thread()
- *
- *  1.5:	- fixed memory leak when atmsar_decode_aal5 returned NULL.
- *		(reported by stephen.robinson@zen.co.uk)
- *
- *  1.4:	- changed the spin_lock() under interrupt to spin_lock_irqsave()
- *		- unlink all active send urbs of a vcc that is being closed.
- *
- *  1.3.1:	- added the version number
- *
- *  1.3:	- Added multiple send urb support
- *		- fixed memory leak and vcc->tx_inuse starvation bug
- *		  when not enough memory left in vcc.
- *
- *  1.2:	- Fixed race condition in udsl_usb_send_data()
- *  1.1:	- Turned off packet debugging
- *
- */
-
-#include <asm/semaphore.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <asm/uaccess.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/init.h>
-#include "speedcrc.h"
-
-/*
-#define DEBUG
-#define VERBOSE_DEBUG
-*/
-
-#include <linux/usb.h>
-
-
-#ifdef VERBOSE_DEBUG
-static int udsl_print_packet (const unsigned char *data, int len);
-#define PACKETDEBUG(arg...)	udsl_print_packet (arg)
-#define vdbg(arg...)		dbg (arg)
-#else
-#define PACKETDEBUG(arg...)
-#define vdbg(arg...)
-#endif
-
-#define DRIVER_AUTHOR	"Johan Verrept, Duncan Sands <duncan.sands@wanadoo.fr>"
-#define DRIVER_DESC	"Alcatel SpeedTouch USB driver"
-#define DRIVER_VERSION	"1.6"
-
-static const char udsl_driver_name [] = "speedtch";
-
-#define SPEEDTOUCH_VENDORID		0x06b9
-#define SPEEDTOUCH_PRODUCTID		0x4061
-
-#define UDSL_MAX_RCV_URBS		4
-#define UDSL_MAX_SND_URBS		4
-#define UDSL_MAX_RCV_BUFS		8
-#define UDSL_MAX_SND_BUFS		8
-#define UDSL_MAX_RCV_BUF_SIZE		1024 /* ATM cells */
-#define UDSL_MAX_SND_BUF_SIZE		1024 /* ATM cells */
-#define UDSL_DEFAULT_RCV_URBS		1
-#define UDSL_DEFAULT_SND_URBS		1
-#define UDSL_DEFAULT_RCV_BUFS		2
-#define UDSL_DEFAULT_SND_BUFS		2
-#define UDSL_DEFAULT_RCV_BUF_SIZE	64 /* ATM cells */
-#define UDSL_DEFAULT_SND_BUF_SIZE	64 /* ATM cells */
-
-static unsigned int num_rcv_urbs = UDSL_DEFAULT_RCV_URBS;
-static unsigned int num_snd_urbs = UDSL_DEFAULT_SND_URBS;
-static unsigned int num_rcv_bufs = UDSL_DEFAULT_RCV_BUFS;
-static unsigned int num_snd_bufs = UDSL_DEFAULT_SND_BUFS;
-static unsigned int rcv_buf_size = UDSL_DEFAULT_RCV_BUF_SIZE;
-static unsigned int snd_buf_size = UDSL_DEFAULT_SND_BUF_SIZE;
-
-MODULE_PARM (num_rcv_urbs, "i");
-MODULE_PARM_DESC (num_rcv_urbs, "Number of urbs used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_URBS) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_URBS) ")");
-
-MODULE_PARM (num_snd_urbs, "i");
-MODULE_PARM_DESC (num_snd_urbs, "Number of urbs used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_URBS) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_URBS) ")");
-
-MODULE_PARM (num_rcv_bufs, "i");
-MODULE_PARM_DESC (num_rcv_bufs, "Number of buffers used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_BUFS) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_BUFS) ")");
-
-MODULE_PARM (num_snd_bufs, "i");
-MODULE_PARM_DESC (num_snd_bufs, "Number of buffers used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_BUFS) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_BUFS) ")");
-
-MODULE_PARM (rcv_buf_size, "i");
-MODULE_PARM_DESC (rcv_buf_size, "Size of the buffers used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_BUF_SIZE) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_BUF_SIZE) ")");
-
-MODULE_PARM (snd_buf_size, "i");
-MODULE_PARM_DESC (snd_buf_size, "Size of the buffers used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_BUF_SIZE) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_BUF_SIZE) ")");
-
-#define UDSL_IOCTL_LINE_UP		1
-#define UDSL_IOCTL_LINE_DOWN		2
-
-#define UDSL_ENDPOINT_DATA_OUT		0x07
-#define UDSL_ENDPOINT_DATA_IN		0x87
-
-#define ATM_CELL_HEADER			(ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
-#define UDSL_NUM_CELLS(x)		(((x) + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD)
-
-#define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
-
-static struct usb_device_id udsl_usb_ids [] = {
-	{ USB_DEVICE (SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID) },
-	{ }
-};
-
-MODULE_DEVICE_TABLE (usb, udsl_usb_ids);
-
-/* receive */
-
-struct udsl_receive_buffer {
-	struct list_head list;
-	unsigned char *base;
-	unsigned int filled_cells;
-};
-
-struct udsl_receiver {
-	struct list_head list;
-	struct udsl_receive_buffer *buffer;
-	struct urb *urb;
-	struct udsl_instance_data *instance;
-};
-
-struct udsl_vcc_data {
-	/* vpi/vci lookup */
-	struct list_head list;
-	short vpi;
-	int vci;
-	struct atm_vcc *vcc;
-
-	/* raw cell reassembly */
-	struct sk_buff *skb;
-	unsigned int max_pdu;
-};
-
-/* send */
-
-struct udsl_send_buffer {
-	struct list_head list;
-	unsigned char *base;
-	unsigned char *free_start;
-	unsigned int free_cells;
-};
-
-struct udsl_sender {
-	struct list_head list;
-	struct udsl_send_buffer *buffer;
-	struct urb *urb;
-	struct udsl_instance_data *instance;
-};
-
-struct udsl_control {
-	struct atm_skb_data atm_data;
-	unsigned int num_cells;
-	unsigned int num_entire;
-	unsigned int pdu_padding;
-	unsigned char cell_header [ATM_CELL_HEADER];
-	unsigned char aal5_trailer [ATM_AAL5_TRAILER];
-};
-
-#define UDSL_SKB(x)		((struct udsl_control *)(x)->cb)
-
-/* main driver data */
-
-struct udsl_instance_data {
-	struct semaphore serialize;
-
-	/* USB device part */
-	struct usb_device *usb_dev;
-	char description [64];
-	int firmware_loaded;
-
-	/* ATM device part */
-	struct atm_dev *atm_dev;
-	struct list_head vcc_list;
-
-	/* receive */
-	struct udsl_receiver receivers [UDSL_MAX_RCV_URBS];
-	struct udsl_receive_buffer receive_buffers [UDSL_MAX_RCV_BUFS];
-
-	spinlock_t receive_lock;
-	struct list_head spare_receivers;
-	struct list_head filled_receive_buffers;
-
-	struct tasklet_struct receive_tasklet;
-	struct list_head spare_receive_buffers;
-
-	/* send */
-	struct udsl_sender senders [UDSL_MAX_SND_URBS];
-	struct udsl_send_buffer send_buffers [UDSL_MAX_SND_BUFS];
-
-	struct sk_buff_head sndqueue;
-
-	spinlock_t send_lock;
-	struct list_head spare_senders;
-	struct list_head spare_send_buffers;
-
-	struct tasklet_struct send_tasklet;
-	struct sk_buff *current_skb;			/* being emptied */
-	struct udsl_send_buffer *current_buffer;	/* being filled */
-	struct list_head filled_send_buffers;
-};
-
-/* ATM */
-
-static void udsl_atm_dev_close (struct atm_dev *dev);
-static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci);
-static void udsl_atm_close (struct atm_vcc *vcc);
-static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg);
-static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb);
-static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page);
-
-static struct atmdev_ops udsl_atm_devops = {
-	dev_close:	udsl_atm_dev_close,
-	open:		udsl_atm_open,
-	close:		udsl_atm_close,
-	ioctl:		udsl_atm_ioctl,
-	send:		udsl_atm_send,
-	proc_read:	udsl_atm_proc_read,
-	owner:		THIS_MODULE,
-};
-
-/* USB */
-
-static void *udsl_usb_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id);
-static void udsl_usb_disconnect (struct usb_device *dev, void *ptr);
-static int udsl_usb_ioctl (struct usb_device *hub, unsigned int code, void *user_data);
-
-static struct usb_driver udsl_usb_driver = {
-	owner:		THIS_MODULE,
-	name:		udsl_driver_name,
-	probe:		udsl_usb_probe,
-	disconnect:	udsl_usb_disconnect,
-	ioctl:		udsl_usb_ioctl,
-	id_table:	udsl_usb_ids,
-};
-
-
-/*************
-**  decode  **
-*************/
-
-static inline struct udsl_vcc_data *udsl_find_vcc (struct udsl_instance_data *instance, short vpi, int vci)
-{
-	struct udsl_vcc_data *vcc;
-
-	list_for_each_entry (vcc, &instance->vcc_list, list)
-		if ((vcc->vci == vci) && (vcc->vpi == vpi))
-			return vcc;
-	return NULL;
-}
-
-static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned char *source, unsigned int howmany)
-{
-	struct udsl_vcc_data *cached_vcc = NULL;
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	struct udsl_vcc_data *vcc_data;
-	int cached_vci = 0;
-	unsigned int i;
-	unsigned int length;
-	unsigned int pdu_length;
-	int pti;
-	int vci;
-	short cached_vpi = 0;
-	short vpi;
-
-	for (i = 0; i < howmany; i++, source += ATM_CELL_SIZE) {
-		vpi = ((source [0] & 0x0f) << 4) | (source [1] >> 4);
-		vci = ((source [1] & 0x0f) << 12) | (source [2] << 4) | (source [3] >> 4);
-		pti = (source [3] & 0x2) != 0;
-
-		vdbg ("udsl_extract_cells: vpi %hd, vci %d, pti %d", vpi, vci, pti);
-
-		if (cached_vcc && (vci == cached_vci) && (vpi == cached_vpi))
-			vcc_data = cached_vcc;
-		else if ((vcc_data = udsl_find_vcc (instance, vpi, vci))) {
-			cached_vcc = vcc_data;
-			cached_vpi = vpi;
-			cached_vci = vci;
-		} else {
-			dbg ("udsl_extract_cells: unknown vpi/vci (%hd/%d)!", vpi, vci);
-			continue;
-		}
-
-		vcc = vcc_data->vcc;
-
-		if (!vcc_data->skb && !(vcc_data->skb = dev_alloc_skb (vcc_data->max_pdu))) {
-			dbg ("udsl_extract_cells: no memory for skb (vcc: 0x%p)!", vcc);
-			if (pti)
-				atomic_inc (&vcc->stats->rx_err);
-			continue;
-		}
-
-		skb = vcc_data->skb;
-
-		if (skb->len + ATM_CELL_PAYLOAD > vcc_data->max_pdu) {
-			dbg ("udsl_extract_cells: buffer overrun (max_pdu: %u, skb->len %u, vcc: 0x%p)", vcc_data->max_pdu, skb->len, vcc);
-			/* discard cells already received */
-			skb_trim (skb, 0);
-			BUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
-		}
-
-		memcpy (skb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
-		__skb_put (skb, ATM_CELL_PAYLOAD);
-
-		if (pti) {
-			length = (source [ATM_CELL_SIZE - 6] << 8) + source [ATM_CELL_SIZE - 5];
-
-			/* guard against overflow */
-			if (length > ATM_MAX_AAL5_PDU) {
-				dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)", length, vcc);
-				goto drop;
-			}
-
-			pdu_length = UDSL_NUM_CELLS (length) * ATM_CELL_PAYLOAD;
-
-			if (skb->len < pdu_length) {
-				dbg ("udsl_extract_cells: bogus pdu_length %u (skb->len: %u, vcc: 0x%p)", pdu_length, skb->len, vcc);
-				goto drop;
-			}
-
-			if (crc32_be (~0, skb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
-				dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)", vcc);
-				goto drop;
-			}
-
-			if (!atm_charge (vcc, skb->truesize)) {
-				dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)", skb->truesize);
-				goto drop_no_stats; /* atm_charge increments rx_drop */
-			}
-
-			/* now that we are sure to send the skb, it is ok to change skb->data */
-			if (skb->len > pdu_length)
-				skb_pull (skb, skb->len - pdu_length); /* discard initial junk */
-
-			skb_trim (skb, length); /* drop zero padding and trailer */
-
-			atomic_inc (&vcc->stats->rx);
-
-			PACKETDEBUG (skb->data, skb->len);
-
-			vdbg ("udsl_extract_cells: sending skb 0x%p, skb->len %u, skb->truesize %u", skb, skb->len, skb->truesize);
-
-			vcc->push (vcc, skb);
-
-			vcc_data->skb = NULL;
-
-			continue;
-
-drop:
-			atomic_inc (&vcc->stats->rx_err);
-drop_no_stats:
-			skb_trim (skb, 0);
-		}
-	}
-}
-
-
-/*************
-**  encode  **
-*************/
-
-static const unsigned char zeros [ATM_CELL_PAYLOAD];
-
-static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct udsl_control *ctrl = UDSL_SKB (skb);
-	unsigned int zero_padding;
-	u32 crc;
-
-	ctrl->atm_data.vcc = vcc;
-	ctrl->cell_header [0] = vcc->vpi >> 4;
-	ctrl->cell_header [1] = (vcc->vpi << 4) | (vcc->vci >> 12);
-	ctrl->cell_header [2] = vcc->vci >> 4;
-	ctrl->cell_header [3] = vcc->vci << 4;
-	ctrl->cell_header [4] = 0xec;
-
-	ctrl->num_cells = UDSL_NUM_CELLS (skb->len);
-	ctrl->num_entire = skb->len / ATM_CELL_PAYLOAD;
-
-	zero_padding = ctrl->num_cells * ATM_CELL_PAYLOAD - skb->len - ATM_AAL5_TRAILER;
-
-	if (ctrl->num_entire + 1 < ctrl->num_cells)
-		ctrl->pdu_padding = zero_padding - (ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
-	else
-		ctrl->pdu_padding = zero_padding;
-
-	ctrl->aal5_trailer [0] = 0; /* UU = 0 */
-	ctrl->aal5_trailer [1] = 0; /* CPI = 0 */
-	ctrl->aal5_trailer [2] = skb->len >> 8;
-	ctrl->aal5_trailer [3] = skb->len;
-
-	crc = crc32_be (~0, skb->data, skb->len);
-	crc = crc32_be (crc, zeros, zero_padding);
-	crc = crc32_be (crc, ctrl->aal5_trailer, 4);
-	crc = ~crc;
-
-	ctrl->aal5_trailer [4] = crc >> 24;
-	ctrl->aal5_trailer [5] = crc >> 16;
-	ctrl->aal5_trailer [6] = crc >> 8;
-	ctrl->aal5_trailer [7] = crc;
-}
-
-static unsigned int udsl_write_cells (unsigned int howmany, struct sk_buff *skb, unsigned char **target_p)
-{
-	struct udsl_control *ctrl = UDSL_SKB (skb);
-	unsigned char *target = *target_p;
-	unsigned int nc, ne, i;
-
-	vdbg ("udsl_write_cells: howmany=%u, skb->len=%d, num_cells=%u, num_entire=%u, pdu_padding=%u", howmany, skb->len, ctrl->num_cells, ctrl->num_entire, ctrl->pdu_padding);
-
-	nc = ctrl->num_cells;
-	ne = min (howmany, ctrl->num_entire);
-
-	for (i = 0; i < ne; i++) {
-		memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
-		target += ATM_CELL_HEADER;
-		memcpy (target, skb->data, ATM_CELL_PAYLOAD);
-		target += ATM_CELL_PAYLOAD;
-		__skb_pull (skb, ATM_CELL_PAYLOAD);
-	}
-
-	ctrl->num_entire -= ne;
-
-	if (!(ctrl->num_cells -= ne) || !(howmany -= ne))
-		goto out;
-
-	memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
-	target += ATM_CELL_HEADER;
-	memcpy (target, skb->data, skb->len);
-	target += skb->len;
-	__skb_pull (skb, skb->len);
-	memset (target, 0, ctrl->pdu_padding);
-	target += ctrl->pdu_padding;
-
-	if (--ctrl->num_cells) {
-		if (!--howmany) {
-			ctrl->pdu_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
-			goto out;
-		}
-
-		memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
-		target += ATM_CELL_HEADER;
-		memset (target, 0, ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
-		target += ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
-
-		BUG_ON (--ctrl->num_cells);
-	}
-
-	memcpy (target, ctrl->aal5_trailer, ATM_AAL5_TRAILER);
-	target += ATM_AAL5_TRAILER;
-	/* set pti bit in last cell */
-	*(target + 3 - ATM_CELL_SIZE) |= 0x2;
-
-out:
-	*target_p = target;
-	return nc - ctrl->num_cells;
-}
-
-
-/**************
-**  receive  **
-**************/
-
-static void udsl_complete_receive (struct urb *urb)
-{
-	struct udsl_receive_buffer *buf;
-	struct udsl_instance_data *instance;
-	struct udsl_receiver *rcv;
-	unsigned long flags;
-
-	if (!urb || !(rcv = urb->context)) {
-		dbg ("udsl_complete_receive: bad urb!");
-		return;
-	}
-
-	instance = rcv->instance;
-	buf = rcv->buffer;
-
-	buf->filled_cells = urb->actual_length / ATM_CELL_SIZE;
-
-	vdbg ("udsl_complete_receive: urb 0x%p, status %d, actual_length %d, filled_cells %u, rcv 0x%p, buf 0x%p", urb, urb->status, urb->actual_length, buf->filled_cells, rcv, buf);
-
-	BUG_ON (buf->filled_cells > rcv_buf_size);
-
-	/* may not be in_interrupt() */
-	spin_lock_irqsave (&instance->receive_lock, flags);
-	list_add (&rcv->list, &instance->spare_receivers);
-	list_add_tail (&buf->list, &instance->filled_receive_buffers);
-	if (likely (!urb->status))
-		tasklet_schedule (&instance->receive_tasklet);
-	spin_unlock_irqrestore (&instance->receive_lock, flags);
-}
-
-static void udsl_process_receive (unsigned long data)
-{
-	struct udsl_receive_buffer *buf;
-	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
-	struct udsl_receiver *rcv;
-	int err;
-
-made_progress:
-	while (!list_empty (&instance->spare_receive_buffers)) {
-		spin_lock_irq (&instance->receive_lock);
-		if (list_empty (&instance->spare_receivers)) {
-			spin_unlock_irq (&instance->receive_lock);
-			break;
-		}
-		rcv = list_entry (instance->spare_receivers.next, struct udsl_receiver, list);
-		list_del (&rcv->list);
-		spin_unlock_irq (&instance->receive_lock);
-
-		buf = list_entry (instance->spare_receive_buffers.next, struct udsl_receive_buffer, list);
-		list_del (&buf->list);
-
-		rcv->buffer = buf;
-
-		FILL_BULK_URB (rcv->urb,
-			       instance->usb_dev,
-			       usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
-			       buf->base,
-			       rcv_buf_size * ATM_CELL_SIZE,
-			       udsl_complete_receive,
-			       rcv);
-		rcv->urb->transfer_flags |= USB_QUEUE_BULK;
-
-		vdbg ("udsl_process_receive: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf);
-
-		if ((err = usb_submit_urb(rcv->urb)) < 0) {
-			dbg ("udsl_process_receive: urb submission failed (%d)!", err);
-			list_add (&buf->list, &instance->spare_receive_buffers);
-			spin_lock_irq (&instance->receive_lock);
-			list_add (&rcv->list, &instance->spare_receivers);
-			spin_unlock_irq (&instance->receive_lock);
-			break;
-		}
-	}
-
-	spin_lock_irq (&instance->receive_lock);
-	if (list_empty (&instance->filled_receive_buffers)) {
-		spin_unlock_irq (&instance->receive_lock);
-		return; /* done - no more buffers */
-	}
-	buf = list_entry (instance->filled_receive_buffers.next, struct udsl_receive_buffer, list);
-	list_del (&buf->list);
-	spin_unlock_irq (&instance->receive_lock);
-	vdbg ("udsl_process_receive: processing buf 0x%p", buf);
-	udsl_extract_cells (instance, buf->base, buf->filled_cells);
-	list_add (&buf->list, &instance->spare_receive_buffers);
-	goto made_progress;
-}
-
-
-/***********
-**  send  **
-***********/
-
-static void udsl_complete_send (struct urb *urb)
-{
-	struct udsl_instance_data *instance;
-	struct udsl_sender *snd;
-	unsigned long flags;
-
-	if (!urb || !(snd = urb->context) || !(instance = snd->instance)) {
-		dbg ("udsl_complete_send: bad urb!");
-		return;
-	}
-
-	vdbg ("udsl_complete_send: urb 0x%p, status %d, snd 0x%p, buf 0x%p", urb, urb->status, snd, snd->buffer);
-
-	/* may not be in_interrupt() */
-	spin_lock_irqsave (&instance->send_lock, flags);
-	list_add (&snd->list, &instance->spare_senders);
-	list_add (&snd->buffer->list, &instance->spare_send_buffers);
-	tasklet_schedule (&instance->send_tasklet);
-	spin_unlock_irqrestore (&instance->send_lock, flags);
-}
-
-static void udsl_process_send (unsigned long data)
-{
-	struct udsl_send_buffer *buf;
-	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
-	struct sk_buff *skb;
-	struct udsl_sender *snd;
-	int err;
-	unsigned int num_written;
-
-made_progress:
-	spin_lock_irq (&instance->send_lock);
-	while (!list_empty (&instance->spare_senders)) {
-		if (!list_empty (&instance->filled_send_buffers)) {
-			buf = list_entry (instance->filled_send_buffers.next, struct udsl_send_buffer, list);
-			list_del (&buf->list);
-		} else if ((buf = instance->current_buffer)) {
-			instance->current_buffer = NULL;
-		} else /* all buffers empty */
-			break;
-
-		snd = list_entry (instance->spare_senders.next, struct udsl_sender, list);
-		list_del (&snd->list);
-		spin_unlock_irq (&instance->send_lock);
-
-		snd->buffer = buf;
-	        FILL_BULK_URB (snd->urb,
-			       instance->usb_dev,
-			       usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
-			       buf->base,
-			       (snd_buf_size - buf->free_cells) * ATM_CELL_SIZE,
-			       udsl_complete_send,
-			       snd);
-		snd->urb->transfer_flags |= USB_QUEUE_BULK;
-
-		vdbg ("udsl_process_send: submitting urb 0x%p (%d cells), snd 0x%p, buf 0x%p", snd->urb, snd_buf_size - buf->free_cells, snd, buf);
-
-		if ((err = usb_submit_urb(snd->urb)) < 0) {
-			dbg ("udsl_process_send: urb submission failed (%d)!", err);
-			spin_lock_irq (&instance->send_lock);
-			list_add (&snd->list, &instance->spare_senders);
-			spin_unlock_irq (&instance->send_lock);
-			list_add (&buf->list, &instance->filled_send_buffers);
-			return; /* bail out */
-		}
-
-		spin_lock_irq (&instance->send_lock);
-	} /* while */
-	spin_unlock_irq (&instance->send_lock);
-
-	if (!instance->current_skb && !(instance->current_skb = skb_dequeue (&instance->sndqueue)))
-		return; /* done - no more skbs */
-
-	skb = instance->current_skb;
-
-	if (!(buf = instance->current_buffer)) {
-		spin_lock_irq (&instance->send_lock);
-		if (list_empty (&instance->spare_send_buffers)) {
-			instance->current_buffer = NULL;
-			spin_unlock_irq (&instance->send_lock);
-			return; /* done - no more buffers */
-		}
-		buf = list_entry (instance->spare_send_buffers.next, struct udsl_send_buffer, list);
-		list_del (&buf->list);
-		spin_unlock_irq (&instance->send_lock);
-
-		buf->free_start = buf->base;
-		buf->free_cells = snd_buf_size;
-
-		instance->current_buffer = buf;
-	}
-
-	num_written = udsl_write_cells (buf->free_cells, skb, &buf->free_start);
-
-	vdbg ("udsl_process_send: wrote %u cells from skb 0x%p to buffer 0x%p", num_written, skb, buf);
-
-	if (!(buf->free_cells -= num_written)) {
-		list_add_tail (&buf->list, &instance->filled_send_buffers);
-		instance->current_buffer = NULL;
-	}
-
-	vdbg ("udsl_process_send: buffer contains %d cells, %d left", snd_buf_size - buf->free_cells, buf->free_cells);
-
-	if (!UDSL_SKB (skb)->num_cells) {
-		struct atm_vcc *vcc = UDSL_SKB (skb)->atm_data.vcc;
-
-		if (vcc->pop)
-			vcc->pop (vcc, skb);
-		else
-			dev_kfree_skb (skb);
-		instance->current_skb = NULL;
-
-		atomic_inc (&vcc->stats->tx);
-	}
-
-	goto made_progress;
-}
-
-static void udsl_cancel_send (struct udsl_instance_data *instance, struct atm_vcc *vcc)
-{
-	struct sk_buff *skb, *n;
-
-	dbg ("udsl_cancel_send entered");
-	spin_lock_irq (&instance->sndqueue.lock);
-	for (skb = instance->sndqueue.next, n = skb->next; skb != (struct sk_buff *)&instance->sndqueue; skb = n, n = skb->next)
-		if (UDSL_SKB (skb)->atm_data.vcc == vcc) {
-			dbg ("udsl_cancel_send: popping skb 0x%p", skb);
-			__skb_unlink (skb, &instance->sndqueue);
-			if (vcc->pop)
-				vcc->pop (vcc, skb);
-			else
-				dev_kfree_skb (skb);
-		}
-	spin_unlock_irq (&instance->sndqueue.lock);
-
-	tasklet_disable (&instance->send_tasklet);
-	if ((skb = instance->current_skb) && (UDSL_SKB (skb)->atm_data.vcc == vcc)) {
-		dbg ("udsl_cancel_send: popping current skb (0x%p)", skb);
-		instance->current_skb = NULL;
-		if (vcc->pop)
-			vcc->pop (vcc, skb);
-		else
-			dev_kfree_skb (skb);
-	}
-	tasklet_enable (&instance->send_tasklet);
-	dbg ("udsl_cancel_send done");
-}
-
-static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct udsl_instance_data *instance = vcc->dev->dev_data;
-
-	vdbg ("udsl_atm_send called (skb 0x%p, len %u)", skb, skb->len);
-
-	if (!instance || !instance->usb_dev) {
-		dbg ("udsl_atm_send: NULL data!");
-		return -ENODEV;
-	}
-
-	if (vcc->qos.aal != ATM_AAL5) {
-		dbg ("udsl_atm_send: unsupported ATM type %d!", vcc->qos.aal);
-		return -EINVAL;
-	}
-
-	if (skb->len > ATM_MAX_AAL5_PDU) {
-		dbg ("udsl_atm_send: packet too long (%d vs %d)!", skb->len, ATM_MAX_AAL5_PDU);
-		return -EINVAL;
-	}
-
-	PACKETDEBUG (skb->data, skb->len);
-
-	udsl_groom_skb (vcc, skb);
-	skb_queue_tail (&instance->sndqueue, skb);
-	tasklet_schedule (&instance->send_tasklet);
-
-	return 0;
-}
-
-
-/**********
-**  ATM  **
-**********/
-
-static void udsl_atm_dev_close (struct atm_dev *dev)
-{
-	struct udsl_instance_data *instance = dev->dev_data;
-
-	if (!instance) {
-		dbg ("udsl_atm_dev_close: NULL instance!");
-		return;
-	}
-
-	dbg ("udsl_atm_dev_close: queue has %u elements", instance->sndqueue.qlen);
-
-	tasklet_kill (&instance->receive_tasklet);
-	tasklet_kill (&instance->send_tasklet);
-	kfree (instance);
-	dev->dev_data = NULL;
-}
-
-static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page)
-{
-	struct udsl_instance_data *instance = atm_dev->dev_data;
-	int left = *pos;
-
-	if (!instance) {
-		dbg ("udsl_atm_proc_read: NULL instance!");
-		return -ENODEV;
-	}
-
-	if (!left--)
-		return sprintf (page, "%s\n", instance->description);
-
-	if (!left--)
-		return sprintf (page, "MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
-				atm_dev->esi [0], atm_dev->esi [1], atm_dev->esi [2],
-				atm_dev->esi [3], atm_dev->esi [4], atm_dev->esi [5]);
-
-	if (!left--)
-		return sprintf (page, "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n",
-				atomic_read (&atm_dev->stats.aal5.tx),
-				atomic_read (&atm_dev->stats.aal5.tx_err),
-				atomic_read (&atm_dev->stats.aal5.rx),
-				atomic_read (&atm_dev->stats.aal5.rx_err),
-				atomic_read (&atm_dev->stats.aal5.rx_drop));
-
-	if (!left--) {
-		switch (atm_dev->signal) {
-		case ATM_PHY_SIG_FOUND:
-			sprintf (page, "Line up");
-			break;
-		case ATM_PHY_SIG_LOST:
-			sprintf (page, "Line down");
-			break;
-		default:
-			sprintf (page, "Line state unknown");
-			break;
-		}
-
-		if (instance->usb_dev) {
-			if (!instance->firmware_loaded)
-				strcat (page, ", no firmware\n");
-			else
-				strcat (page, ", firmware loaded\n");
-		} else
-			strcat (page, ", disconnected\n");
-
-		return strlen (page);
-	}
-
-	return 0;
-}
-
-static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
-{
-	struct udsl_instance_data *instance = vcc->dev->dev_data;
-	struct udsl_vcc_data *new;
-
-	dbg ("udsl_atm_open: vpi %hd, vci %d", vpi, vci);
-
-	if (!instance || !instance->usb_dev) {
-		dbg ("udsl_atm_open: NULL data!");
-		return -ENODEV;
-	}
-
-	if ((vpi == ATM_VPI_ANY) || (vci == ATM_VCI_ANY))
-		return -EINVAL;
-
-	/* only support AAL5 */
-	if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU))
-		return -EINVAL;
-
-	if (!instance->firmware_loaded) {
-		dbg ("udsl_atm_open: firmware not loaded!");
-		return -EAGAIN;
-	}
-
-	down (&instance->serialize); /* vs self, udsl_atm_close */
-
-	if (udsl_find_vcc (instance, vpi, vci)) {
-		up (&instance->serialize);
-		return -EADDRINUSE;
-	}
-
-	if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) {
-		up (&instance->serialize);
-		return -ENOMEM;
-	}
-
-	memset (new, 0, sizeof (struct udsl_vcc_data));
-	new->vcc = vcc;
-	new->vpi = vpi;
-	new->vci = vci;
-	new->max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
-
-	vcc->dev_data = new;
-	vcc->vpi = vpi;
-	vcc->vci = vci;
-
-	tasklet_disable (&instance->receive_tasklet);
-	list_add (&new->list, &instance->vcc_list);
-	tasklet_enable (&instance->receive_tasklet);
-
-	set_bit (ATM_VF_ADDR, &vcc->flags);
-	set_bit (ATM_VF_PARTIAL, &vcc->flags);
-	set_bit (ATM_VF_READY, &vcc->flags);
-
-	up (&instance->serialize);
-
-	tasklet_schedule (&instance->receive_tasklet);
-
-	dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, new->max_pdu);
-
-	return 0;
-}
-
-static void udsl_atm_close (struct atm_vcc *vcc)
-{
-	struct udsl_instance_data *instance = vcc->dev->dev_data;
-	struct udsl_vcc_data *vcc_data = vcc->dev_data;
-
-	dbg ("udsl_atm_close called");
-
-	if (!instance || !vcc_data) {
-		dbg ("udsl_atm_close: NULL data!");
-		return;
-	}
-
-	dbg ("udsl_atm_close: deallocating vcc 0x%p with vpi %d vci %d", vcc_data, vcc_data->vpi, vcc_data->vci);
-
-	udsl_cancel_send (instance, vcc);
-
-	down (&instance->serialize); /* vs self, udsl_atm_open */
-
-	tasklet_disable (&instance->receive_tasklet);
-	list_del (&vcc_data->list);
-	tasklet_enable (&instance->receive_tasklet);
-
-	if (vcc_data->skb)
-		dev_kfree_skb (vcc_data->skb);
-	vcc_data->skb = NULL;
-
-	kfree (vcc_data);
-	vcc->dev_data = NULL;
-
-	vcc->vpi = ATM_VPI_UNSPEC;
-	vcc->vci = ATM_VCI_UNSPEC;
-	clear_bit (ATM_VF_READY, &vcc->flags);
-	clear_bit (ATM_VF_PARTIAL, &vcc->flags);
-	clear_bit (ATM_VF_ADDR, &vcc->flags);
-
-	up (&instance->serialize);
-
-	dbg ("udsl_atm_close successful");
-}
-
-static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
-{
-	switch (cmd) {
-	case ATM_QUERYLOOP:
-		return put_user (ATM_LM_NONE, (int *) arg) ? -EFAULT : 0;
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
-
-/**********
-**  USB  **
-**********/
-
-static int udsl_set_alternate (struct udsl_instance_data *instance)
-{
-	down (&instance->serialize); /* vs self */
-	if (!instance->firmware_loaded) {
-		int ret;
-
-		if ((ret = usb_set_interface (instance->usb_dev, 1, 1)) < 0) {
-			dbg ("udsl_set_alternate: usb_set_interface returned %d!", ret);
-			up (&instance->serialize);
-			return ret;
-		}
-		instance->firmware_loaded = 1;
-	}
-	up (&instance->serialize);
-
-	tasklet_schedule (&instance->receive_tasklet);
-
-	return 0;
-}
-
-static int udsl_usb_ioctl (struct usb_device *dev, unsigned int code, void *user_data)
-{
-	struct usb_interface *intf = usb_ifnum_to_if (dev, 1);
-	struct udsl_instance_data *instance = intf->private_data;
-
-	dbg ("udsl_usb_ioctl entered");
-
-	if (!instance) {
-		dbg ("udsl_usb_ioctl: NULL instance!");
-		return -ENODEV;
-	}
-
-	switch (code) {
-	case UDSL_IOCTL_LINE_UP:
-		instance->atm_dev->signal = ATM_PHY_SIG_FOUND;
-		return udsl_set_alternate (instance);
-	case UDSL_IOCTL_LINE_DOWN:
-		instance->atm_dev->signal = ATM_PHY_SIG_LOST;
-		return 0;
-	default:
-		return -ENOTTY;
-	}
-}
-
-static void *udsl_usb_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
-{
-	struct udsl_instance_data *instance;
-	unsigned char mac_str [13];
-	int i, length;
-	char *buf;
-
-	dbg ("udsl_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d",
-	     dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
-
-	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
-	    (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) ||
-	    (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))
-		return NULL;
-
-	dbg ("udsl_usb_probe: device accepted");
-
-	/* instance init */
-	if (!(instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL))) {
-		dbg ("udsl_usb_probe: no memory for instance data!");
-		return NULL;
-	}
-
-	memset (instance, 0, sizeof (struct udsl_instance_data));
-
-	init_MUTEX (&instance->serialize);
-
-	instance->usb_dev = dev;
-
-	INIT_LIST_HEAD (&instance->vcc_list);
-
-	spin_lock_init (&instance->receive_lock);
-	INIT_LIST_HEAD (&instance->spare_receivers);
-	INIT_LIST_HEAD (&instance->filled_receive_buffers);
-
-	tasklet_init (&instance->receive_tasklet, udsl_process_receive, (unsigned long) instance);
-	INIT_LIST_HEAD (&instance->spare_receive_buffers);
-
-	skb_queue_head_init (&instance->sndqueue);
-
-	spin_lock_init (&instance->send_lock);
-	INIT_LIST_HEAD (&instance->spare_senders);
-	INIT_LIST_HEAD (&instance->spare_send_buffers);
-
-	tasklet_init (&instance->send_tasklet, udsl_process_send, (unsigned long) instance);
-	INIT_LIST_HEAD (&instance->filled_send_buffers);
-
-	/* receive init */
-	for (i = 0; i < num_rcv_urbs; i++) {
-		struct udsl_receiver *rcv = &(instance->receivers [i]);
-
-		if (!(rcv->urb = usb_alloc_urb (0))) {
-			dbg ("udsl_usb_probe: no memory for receive urb %d!", i);
-			goto fail;
-		}
-
-		rcv->instance = instance;
-
-		list_add (&rcv->list, &instance->spare_receivers);
-	}
-
-	for (i = 0; i < num_rcv_bufs; i++) {
-		struct udsl_receive_buffer *buf = &(instance->receive_buffers [i]);
-
-		if (!(buf->base = kmalloc (rcv_buf_size * ATM_CELL_SIZE, GFP_KERNEL))) {
-			dbg ("udsl_usb_probe: no memory for receive buffer %d!", i);
-			goto fail;
-		}
-
-		list_add (&buf->list, &instance->spare_receive_buffers);
-	}
-
-	/* send init */
-	for (i = 0; i < num_snd_urbs; i++) {
-		struct udsl_sender *snd = &(instance->senders [i]);
-
-		if (!(snd->urb = usb_alloc_urb (0))) {
-			dbg ("udsl_usb_probe: no memory for send urb %d!", i);
-			goto fail;
-		}
-
-		snd->instance = instance;
-
-		list_add (&snd->list, &instance->spare_senders);
-	}
-
-	for (i = 0; i < num_snd_bufs; i++) {
-		struct udsl_send_buffer *buf = &(instance->send_buffers [i]);
-
-		if (!(buf->base = kmalloc (snd_buf_size * ATM_CELL_SIZE, GFP_KERNEL))) {
-			dbg ("udsl_usb_probe: no memory for send buffer %d!", i);
-			goto fail;
-		}
-
-		list_add (&buf->list, &instance->spare_send_buffers);
-	}
-
-	/* ATM init */
-	if (!(instance->atm_dev = atm_dev_register (udsl_driver_name, &udsl_atm_devops, -1, 0))) {
-		dbg ("udsl_usb_probe: failed to register ATM device!");
-		goto fail;
-	}
-
-	instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
-	instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
-	instance->atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
-
-	/* temp init ATM device, set to 128kbit */
-	instance->atm_dev->link_rate = 128 * 1000 / 424;
-
-	/* set MAC address, it is stored in the serial number */
-	memset (instance->atm_dev->esi, 0, sizeof (instance->atm_dev->esi));
-	if (usb_string (dev, dev->descriptor.iSerialNumber, mac_str, sizeof (mac_str)) == 12)
-		for (i = 0; i < 6; i++)
-			instance->atm_dev->esi [i] = (hex2int (mac_str [i * 2]) * 16) + (hex2int (mac_str [i * 2 + 1]));
-
-	/* device description */
-	buf = instance->description;
-	length = sizeof (instance->description);
-
-	if ((i = usb_string (dev, dev->descriptor.iProduct, buf, length)) < 0)
-		goto finish;
-
-	buf += i;
-	length -= i;
-
-	i = snprintf (buf, length, " (");
-	buf += i;
-	length -= i;
-
-	if (length <= 0 || (i = usb_make_path (dev, buf, length)) < 0)
-		goto finish;
-
-	buf += i;
-	length -= i;
-
-	snprintf (buf, length, ")");
-
-finish:
-	/* ready for ATM callbacks */
-	wmb ();
-	instance->atm_dev->dev_data = instance;
-
-	return instance;
-
-fail:
-	for (i = 0; i < num_snd_bufs; i++)
-		kfree (instance->send_buffers [i].base);
-
-	for (i = 0; i < num_snd_urbs; i++)
-		usb_free_urb (instance->senders [i].urb);
-
-	for (i = 0; i < num_rcv_bufs; i++)
-		kfree (instance->receive_buffers [i].base);
-
-	for (i = 0; i < num_rcv_urbs; i++)
-		usb_free_urb (instance->receivers [i].urb);
-
-	kfree (instance);
-
-	return NULL;
-}
-
-static void udsl_usb_disconnect (struct usb_device *dev, void *ptr)
-{
-	struct udsl_instance_data *instance = ptr;
-	struct list_head *pos;
-	unsigned int count;
-	int result, i;
-
-	dbg ("udsl_usb_disconnect entered");
-
-	if (!instance) {
-		dbg ("udsl_usb_disconnect: NULL instance!");
-		return;
-	}
-
-	/* receive finalize */
-	tasklet_disable (&instance->receive_tasklet);
-
-	for (i = 0; i < num_rcv_urbs; i++)
-		if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0)
-			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result);
-
-	/* wait for completion handlers to finish */
-	do {
-		count = 0;
-		spin_lock_irq (&instance->receive_lock);
-		list_for_each (pos, &instance->spare_receivers)
-			if (++count > num_rcv_urbs)
-				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
-		spin_unlock_irq (&instance->receive_lock);
-
-		dbg ("udsl_usb_disconnect: found %u spare receivers", count);
-
-		if (count == num_rcv_urbs)
-			break;
-
-		set_current_state (TASK_RUNNING);
-		schedule ();
-	} while (1);
-
-	/* no need to take the spinlock */
-	INIT_LIST_HEAD (&instance->filled_receive_buffers);
-	INIT_LIST_HEAD (&instance->spare_receive_buffers);
-
-	tasklet_enable (&instance->receive_tasklet);
-
-	for (i = 0; i < num_rcv_urbs; i++)
-		usb_free_urb (instance->receivers [i].urb);
-
-	for (i = 0; i < num_rcv_bufs; i++)
-		kfree (instance->receive_buffers [i].base);
-
-	/* send finalize */
-	tasklet_disable (&instance->send_tasklet);
-
-	for (i = 0; i < num_snd_urbs; i++)
-		if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0)
-			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result);
-
-	/* wait for completion handlers to finish */
-	do {
-		count = 0;
-		spin_lock_irq (&instance->send_lock);
-		list_for_each (pos, &instance->spare_senders)
-			if (++count > num_snd_urbs)
-				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
-		spin_unlock_irq (&instance->send_lock);
-
-		dbg ("udsl_usb_disconnect: found %u spare senders", count);
-
-		if (count == num_snd_urbs)
-			break;
-
-		set_current_state (TASK_RUNNING);
-		schedule ();
-	} while (1);
-
-	/* no need to take the spinlock */
-	INIT_LIST_HEAD (&instance->spare_senders);
-	INIT_LIST_HEAD (&instance->spare_send_buffers);
-	instance->current_buffer = NULL;
-
-	tasklet_enable (&instance->send_tasklet);
-
-	for (i = 0; i < num_snd_urbs; i++)
-		usb_free_urb (instance->senders [i].urb);
-
-	for (i = 0; i < num_snd_bufs; i++)
-		kfree (instance->send_buffers [i].base);
-
-	wmb ();
-	instance->usb_dev = NULL;
-
-	/* ATM finalize */
-	shutdown_atm_dev (instance->atm_dev); /* frees instance, kills tasklets */
-}
-
-
-/***********
-**  init  **
-***********/
-
-static int __init udsl_usb_init (void)
-{
-	struct sk_buff *skb; /* dummy for sizeof */
-
-	dbg ("udsl_usb_init: driver version " DRIVER_VERSION);
-
-	if (sizeof (struct udsl_control) > sizeof (skb->cb)) {
-		printk (KERN_ERR __FILE__ ": unusable with this kernel!\n");
-		return -EIO;
-	}
-
-	if ((num_rcv_urbs > UDSL_MAX_RCV_URBS) || (num_snd_urbs > UDSL_MAX_SND_URBS) ||
-	    (num_rcv_bufs > UDSL_MAX_RCV_BUFS) || (num_snd_bufs > UDSL_MAX_SND_BUFS) ||
-	    (rcv_buf_size > UDSL_MAX_RCV_BUF_SIZE) || (snd_buf_size > UDSL_MAX_SND_BUF_SIZE))
-		return -EINVAL;
-
-	return usb_register (&udsl_usb_driver);
-}
-
-static void __exit udsl_usb_cleanup (void)
-{
-	dbg ("udsl_usb_cleanup entered");
-
-	usb_deregister (&udsl_usb_driver);
-}
-
-module_init (udsl_usb_init);
-module_exit (udsl_usb_cleanup);
-
-MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_LICENSE ("GPL");
-
-
-/************
-**  debug  **
-************/
-
-#ifdef VERBOSE_DEBUG
-static int udsl_print_packet (const unsigned char *data, int len)
-{
-	unsigned char buffer [256];
-	int i = 0, j = 0;
-
-	for (i = 0; i < len;) {
-		buffer [0] = '\0';
-		sprintf (buffer, "%.3d :", i);
-		for (j = 0; (j < 16) && (i < len); j++, i++) {
-			sprintf (buffer, "%s %2.2x", buffer, data [i]);
-		}
-		dbg ("%s", buffer);
-	}
-	return i;
-}
-#endif
diff -urN linux-2.4.22-pre2/drivers/usb/storage/initializers.c linux-2.4.22-pre3/drivers/usb/storage/initializers.c
--- linux-2.4.22-pre2/drivers/usb/storage/initializers.c	2000-09-08 16:39:12.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/storage/initializers.c	2003-07-05 18:10:56.000000000 -0700
@@ -39,6 +39,7 @@
 
 #include "initializers.h"
 #include "debug.h"
+#include "transport.h"
 
 /* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
  * mode */
@@ -57,4 +58,51 @@
 	return 0;
 }
 
+/* This function is required to activate all four slots on the UCR-61S2B
+ * flash reader */
 
+int usb_stor_ucr61s2b_init(struct us_data *us)
+{
+	int pipe;
+	struct bulk_cb_wrap *bcb;
+	struct bulk_cs_wrap *bcs;
+	int res, partial;
+
+	bcb = kmalloc(sizeof *bcb, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
+	if (!bcb) {
+		return(-1);
+	}
+	bcs = kmalloc(sizeof *bcs, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
+	if (!bcs) {
+		kfree(bcb);
+		return(-1);
+	}
+
+	US_DEBUGP("Sending UCR-61S2B initialization packet...\n");
+
+	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+	bcb->Tag = ++(us->tag);
+	bcb->DataTransferLength = cpu_to_le32(0);
+	bcb->Flags = bcb->Lun = 0;
+	bcb->Length = sizeof(UCR61S2B_INIT);
+	memset(bcb->CDB, 0, sizeof(bcb->CDB));
+	memcpy(bcb->CDB, UCR61S2B_INIT, sizeof(UCR61S2B_INIT));
+
+	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
+	res = usb_stor_bulk_msg(us, bcb, pipe, US_BULK_CB_WRAP_LEN, &partial);
+	US_DEBUGP("-- result is %d\n", res);
+	kfree(bcb);
+
+	if(res) {
+		kfree(bcs);
+		return(res);
+	}
+
+	pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
+	res = usb_stor_bulk_msg(us, bcs, pipe, US_BULK_CS_WRAP_LEN, &partial);
+	US_DEBUGP("-- result of status read is %d\n", res);
+
+	kfree(bcs);
+
+	return(res ? -1 : 0);
+}
diff -urN linux-2.4.22-pre2/drivers/usb/storage/initializers.h linux-2.4.22-pre3/drivers/usb/storage/initializers.h
--- linux-2.4.22-pre2/drivers/usb/storage/initializers.h	2001-11-22 11:49:34.000000000 -0800
+++ linux-2.4.22-pre3/drivers/usb/storage/initializers.h	2003-07-05 18:10:56.000000000 -0700
@@ -39,6 +39,12 @@
 
 #include "usb.h"
 
+#define UCR61S2B_INIT "\xec\x0a\x06\x00$PCCHIPS"
+
 /* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
  * mode */
 int usb_stor_euscsi_init(struct us_data *us);
+
+/* This function is required to activate all four slots on the UCR-61S2B
+ * flash reader */
+int usb_stor_ucr61s2b_init(struct us_data *us);
diff -urN linux-2.4.22-pre2/drivers/usb/storage/unusual_devs.h linux-2.4.22-pre3/drivers/usb/storage/unusual_devs.h
--- linux-2.4.22-pre2/drivers/usb/storage/unusual_devs.h	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/storage/unusual_devs.h	2003-07-05 18:10:56.000000000 -0700
@@ -618,16 +618,6 @@
 		US_SC_SCSI, US_PR_BULK, NULL,
 		US_FL_FIX_INQUIRY ),
 		
-/* Pentax Optio S digital camera
- * adapted from http://www2.goldfisch.at/knowledge/233
- * (Peter Pilsl <pilsl@goldfisch.at>)
- * by Christoph Weidemann <cweidema@indiana.edu> */
-UNUSUAL_DEV(  0x0a17, 0x0006, 0x0000, 0xffff,
-		"Pentax",
-		"Optio S",
-		US_SC_8070, US_PR_CB, NULL,
-		US_FL_MODE_XLATE|US_FL_FIX_INQUIRY),
-
 #ifdef CONFIG_USB_STORAGE_ISD200
 UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
                 "ATI",
@@ -649,6 +639,16 @@
 		US_SC_SCSI, US_PR_BULK, NULL,
 		US_FL_START_STOP ),
 
+/* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu>
+ * Tested on hardware version 1.10.
+ * Entry is needed only for the initializer function override.
+ */
+UNUSUAL_DEV(  0x1019, 0x0c55, 0x0000, 0x9999,
+		"Desknote",
+		"UCR-61S2B",
+		US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
+		0 ),
+
 /* Reported by Dan Pilone <pilone@slac.com>
  * The device needs the flags only.
  * Also reported by Brian Hall <brihall@pcisys.net>, again for flags.
diff -urN linux-2.4.22-pre2/drivers/usb/usbnet.c linux-2.4.22-pre3/drivers/usb/usbnet.c
--- linux-2.4.22-pre2/drivers/usb/usbnet.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/usbnet.c	2003-07-05 18:10:57.000000000 -0700
@@ -1377,8 +1377,18 @@
 	.in = 1, .out = 2,
 	.epsize = 64,
 };
+static const struct driver_info	zaurus_slc700_info = {
+	.description =	"Sharp Zaurus SL-C700",
+	.flags =	FLAG_FRAMING_Z,
+	.check_connect = always_connected,
+	.tx_fixup = 	zaurus_tx_fixup,
+
+	.in = 1, .out = 2,
+	.epsize = 64,
+};
 
 // SL-5600 and C-700 are PXA based; should resemble A300
+// but C-700 had a different idProduct so i had an entry :)
 
 #endif
 
@@ -2353,6 +2363,15 @@
 	.bInterfaceSubClass	= 0x0a,
 	.bInterfaceProtocol	= 0x00,
 	.driver_info =  (unsigned long) &zaurus_slb500_info,
+}, {
+	.match_flags	=   USB_DEVICE_ID_MATCH_INT_INFO
+			  | USB_DEVICE_ID_MATCH_DEVICE, 
+	.idVendor		= 0x04DD,
+	.idProduct		= 0x8007,
+	.bInterfaceClass	= 0x02,
+	.bInterfaceSubClass	= 0x0a,
+	.bInterfaceProtocol	= 0x00,
+	.driver_info =  (unsigned long) &zaurus_slc700_info,
 },
 #endif
 
diff -urN linux-2.4.22-pre2/drivers/usb/vicam.c linux-2.4.22-pre3/drivers/usb/vicam.c
--- linux-2.4.22-pre2/drivers/usb/vicam.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/drivers/usb/vicam.c	2003-07-05 18:10:57.000000000 -0700
@@ -367,7 +367,8 @@
 	struct semaphore busy_lock;	// guard against SMP multithreading
 
 	bool is_initialized;
-	u8 open_count;
+	bool is_removed;
+	bool is_opened;
 	u8 bulkEndpoint;
 	bool needsDummyRead;
 
@@ -384,6 +385,7 @@
 			       const struct usb_device_id *id);
 static void vicam_disconnect(struct usb_device *dev, void *ptr);
 static void read_frame(struct vicam_camera *cam, int framenum);
+static void vicam_purge(struct vicam_camera *cam);
 
 static int
 send_control_msg(struct usb_device *udev, u8 request, u16 value, u16 index,
@@ -704,6 +706,7 @@
 {
 	struct vicam_camera *cam =
 	    (struct vicam_camera *) dev->priv;
+	int intr;
 	DBG("open\n");
 
 	if (!cam) {
@@ -711,9 +714,11 @@
 		       "vicam video_device improperly initialized");
 	}
 
-	down_interruptible(&cam->busy_lock);
+	intr = down_interruptible(&cam->busy_lock);
+	if (intr)
+		return -EINTR;
 
-	if (cam->open_count > 0) {
+	if (cam->is_opened) {
 		printk(KERN_INFO
 		       "vicam_open called on already opened camera");
 		up(&cam->busy_lock);
@@ -748,7 +753,7 @@
 	set_camera_power(cam, 1);
 
 	cam->needsDummyRead = 1;
-	cam->open_count++;
+	cam->is_opened = 1;
 
 	up(&cam->busy_lock);
 
@@ -759,9 +764,15 @@
 vicam_close(struct video_device *dev)
 {
 	DBG("close\n");
-	set_camera_power((struct vicam_camera *) dev->priv, 0);
+	struct vicam_camera *cam = (struct vicam_camera *) dev->priv;
+
 
-	((struct vicam_camera *) dev->priv)->open_count--;
+	if (cam->is_removed) {
+		vicam_purge(cam);
+	} else {
+		set_camera_power(cam, 0);
+		cam->is_opened = 0;
+	}
 }
 
 inline int pin(int x)
@@ -772,7 +783,7 @@
 inline void writepixel(char *rgb, int Y, int Cr, int Cb)
 {
 	Y = 1160 * (Y - 16);
-	
+
 	rgb[2] = pin( ( ( Y + ( 1594 * Cr ) ) + 500 ) / 1300 );
 	rgb[1] = pin( ( ( Y - (  392 * Cb ) - ( 813 * Cr ) ) + 500 ) / 1000 );
 	rgb[0] = pin( ( ( Y + ( 2017 * Cb ) ) + 500 ) / 900 );
@@ -939,6 +950,7 @@
 		 unsigned long count, int noblock)
 {
 	struct vicam_camera *cam = dev->priv;
+	int intr;
 	DBG("read %d bytes.\n", (int) count);
 
 	if (!buf)
@@ -975,7 +987,9 @@
 		}
 	}
 
-	down_interruptible(&cam->busy_lock);
+	intr = down_interruptible(&cam->busy_lock);
+	if (intr)
+		return -EINTR;
 
 	if (cam->needsDummyRead) {
 		read_frame(cam, 0);
@@ -1306,10 +1320,10 @@
 	return cam;
 }
 
+
 static void
-vicam_disconnect(struct usb_device *dev, void *ptr)
+vicam_purge(struct vicam_camera *cam)
 {
-	struct vicam_camera *cam = ptr;
 	video_unregister_device(&cam->vdev);
 
 #ifdef CONFIG_PROC_FS
@@ -1327,6 +1341,18 @@
 	printk(KERN_DEBUG "ViCam-based WebCam disconnected\n");
 }
 
+static void
+vicam_disconnect(struct usb_device *dev, void *ptr)
+{
+	struct vicam_camera *cam = ptr;
+
+	if (cam->is_opened) {
+		cam->is_removed = 1;
+	} else {
+		vicam_purge(cam);
+	}
+}
+
 /*
  */
 static int __init
diff -urN linux-2.4.22-pre2/drivers/video/fbcon.c linux-2.4.22-pre3/drivers/video/fbcon.c
--- linux-2.4.22-pre2/drivers/video/fbcon.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/drivers/video/fbcon.c	2003-07-05 18:10:57.000000000 -0700
@@ -266,23 +266,22 @@
 int PROC_CONSOLE(const struct fb_info *info)
 {
         int fgc;
-        
-        if (info->display_fg != NULL)
-                fgc = info->display_fg->vc_num;
-        else
-                return -1;
-                
-        if (!current->tty)
-                return fgc;
-
-        if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
-                /* XXX Should report error here? */
-                return fgc;
 
-        if (MINOR(current->tty->device) < 1)
-                return fgc;
+	if (info->display_fg == NULL)
+		return -1;
 
-        return MINOR(current->tty->device) - 1;
+        if (!current->tty ||
+	    current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE ||
+	    MINOR(current->tty->device) < 1)
+		fgc = info->display_fg->vc_num;
+	else
+		fgc = MINOR(current->tty->device)-1;
+
+	/* Does this virtual console belong to the specified fbdev? */
+	if (fb_display[fgc].fb_info != info)
+		return -1;
+
+	return fgc;
 }
 
 
@@ -919,8 +918,9 @@
 	return;
 
     cursor_on = 0;
-    if (cursor_drawn)
-        p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
+    if (cursor_drawn && p->cursor_x < conp->vc_cols &&
+	p->cursor_y < conp->vc_rows)
+	p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
 
     p->cursor_x = conp->vc_x;
     p->cursor_y = y;
diff -urN linux-2.4.22-pre2/drivers/video/sis/300vtbl.h linux-2.4.22-pre3/drivers/video/sis/300vtbl.h
--- linux-2.4.22-pre2/drivers/video/sis/300vtbl.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/300vtbl.h	2003-07-05 18:10:58.000000000 -0700
@@ -1,7 +1,35 @@
-
-
-/* Register settings for SiS 300 series */
-
+/* $XFree86$ */
+/*
+ * Register settings for SiS 300 series
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
 
 typedef struct _SiS300_StStruct
 {
@@ -39,473 +67,109 @@
 	{0xff,     0,   0,   0,   0,   0,   0,   0}
 };
 
-typedef struct _SiS300_StandTableStruct
-{
-	UCHAR CRT_COLS;
-	UCHAR ROWS;
-	UCHAR CHAR_HEIGHT;
-	USHORT CRT_LEN;
-	UCHAR SR[4];
-	UCHAR MISC;
-	UCHAR CRTC[0x19];
-	UCHAR ATTR[0x14];
-	UCHAR GRC[9];
-} SiS300_StandTableStruct;
-
-static const SiS300_StandTableStruct  SiS300_StandTable[] =
-{
- {0x28,0x18,0x08,0x0800,			/* 0x00 */
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x28,0x18,0x08,0x0800,			/* 0x01 */
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x08,0x1000,			/* 0x02 */
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x08,0x1000,			/* 0x03 */
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x28,0x18,0x08,0x4000,			/* 0x04 */
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff} },
- {0x28,0x18,0x08,0x4000,			/* 0x05 */
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff} },
- {0x50,0x18,0x08,0x4000,			/* 0x06 */
-  {0x01,0x01,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
-   0xff},
-  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x01,0x00,0x01,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
-   0xff} },
- {0x50,0x18,0x0e,0x1000,			/* 0x07 */
-  {0x00,0x03,0x00,0x03},
-  0xa6,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff} },
-/* MDA_DAC*/
- {0x00,0x00,0x00,0x0000,			/* 0x08 */
-  {0x00,0x00,0x00,0x15},
-  0x15,
-  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
-   0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15},
-  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f} },
-/* CGA_DAC*/
- {0x00,0x10,0x04,0x0114,			/* 0x09 */
-  {0x11,0x09,0x15,0x00},
-  0x10,
-  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
-   0x04},
-  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
-   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
-   0x3e,0x2b,0x3b,0x2f},
-  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f} },
-/* EGA_DAC*/
- {0x00,0x10,0x04,0x0114,			/* 0x0a */
-  {0x11,0x05,0x15,0x20},
-  0x30,
-  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
-   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
-   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
-   0x06},
-  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
-   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
-   0x1e,0x0b,0x1b,0x0f},
-  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f} },
-/* VGA_DAC*/
- {0x00,0x10,0x04,0x0114,			/* 0x0b */
-  {0x11,0x09,0x15,0x2a},
-  0x3a,
-  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
-   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
-   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
-   0x1f},
-  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
-   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
-   0x1c,0x0e,0x11,0x15},
-  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
-   0x04} },
- {0x08,0x0c,0x10,0x0a08,			/* 0x0c */
-  {0x0c,0x0e,0x10,0x0b},
-  0x0c,
-  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
-   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
-   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
-   0x06},
-  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
-   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
-   0x00,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00} },
- {0x28,0x18,0x08,0x2000,			/* 0x0d */
-  {0x09,0x0f,0x00,0x06},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff} },
- {0x50,0x18,0x08,0x4000,			/* 0x0e */
-  {0x01,0x0f,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff} },
- {0x00,0x00,0x00,0x0000,			/* 0x0f */	/* TW: Standtable for VGA modes */
-  {0x01,0x0f,0x00,0x0e},
-  0x23,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x01,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff} },
- {0x4a,0x36,0x00,0x00c0,			/* 0x10 */
-  {0x00,0x00,0x00,0x00},
-  0x00,
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x3a,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x1a,0x00,0x57,0x39,0x00,0xc0,
-   0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00} },
- {0x50,0x18,0x0e,0x8000,			/* 0x11 */
-  {0x01,0x0f,0x00,0x06},
-  0xa2,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
-   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
-   0x0b,0x00,0x05,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
-   0xff} },
- {0x50,0x18,0x0e,0x8000,			/* 0x12 */
-  {0x01,0x0f,0x00,0x06},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff} },
- {0x28,0x18,0x0e,0x0800,			/* 0x13 */
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x28,0x18,0x0e,0x0800,			/* 0x14 */
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x0e,0x1000,			/* 0x15 */
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x0e,0x1000,			/* 0x16 */
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x28,0x18,0x10,0x0800,			/* 0x17 */
-  {0x08,0x03,0x00,0x02},
-  0x67,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x10,0x1000,			/* 0x18 */
-  {0x00,0x03,0x00,0x02},
-  0x67,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x10,0x1000,			/* 0x19 */
-  {0x00,0x03,0x00,0x02},
-  0x66,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff} },
- {0x50,0x1d,0x10,0xa000,			/* 0x1a */
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xc3,
-   0xff},
-  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
-   0xff} },
- {0x50,0x1d,0x10,0xa000,			/* 0x1b */
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff} },
- {0x28,0x18,0x08,0x2000,			/* 0x1c */
-  {0x01,0x0f,0x00,0x0e},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
-   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x41,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff} }
-};
-
 typedef struct _SiS300_ExtStruct
 {
-	UCHAR Ext_ModeID;
+	UCHAR  Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
-	USHORT Ext_Point;
 	USHORT Ext_VESAID;
-	UCHAR Ext_VESAMEMSize;
-	UCHAR Ext_RESINFO;
-	UCHAR VB_ExtTVFlickerIndex;
-	UCHAR VB_ExtTVEdgeIndex;
-	UCHAR VB_ExtTVYFilterIndex;
-	UCHAR REFindex;
+	UCHAR  Ext_RESINFO;
+	UCHAR  VB_ExtTVFlickerIndex;
+	UCHAR  VB_ExtTVEdgeIndex;
+	UCHAR  VB_ExtTVYFilterIndex;
+	UCHAR  REFindex;
 } SiS300_ExtStruct;
 
 static const SiS300_ExtStruct  SiS300_EModeIDTable[] =
 {
-	{0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600x? */
-	{0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08},
-	{0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10},  /* 640x400x8 */
-	{0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00},
-	{0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x8 */
-	{0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x8 */
-	{0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x16 */
-	{0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x16 */
-	{0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x32 */
-	{0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x32 */
-	{0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},  /* 1024x768x? */
-	{0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},  /* 1024x768x8 */
-	{0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 1280x1024x8 */
-	{0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},
-	{0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},
-	{0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23},  /* 320x200x15 */
-	{0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23},  /* 320x200x16 */
-	{0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08},
-	{0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08},
-	{0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600x15 */
-	{0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600x16 */
-	{0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
-	{0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},
-	{0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
-	{0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},
-	{0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24},  /* 320x240x8  */
-	{0x51,0xb21b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25},  /* 400x300x8  */
-	{0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26},  /* 512x384x8  */
-	{0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24},  /* 320x240x16 */
-	{0x57,0xb21d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25},  /* 400x300x16 */
-	{0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26},  /* 512x384x16 */
-	{0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23},  /* 320x200x8  */
-	{0x5c,0x921f,0x24,0x352b,0x0000,0x08,0x04,0x00,0x00,0x00,0x26},  /* TW: inserted 512x384x32 */
-	{0x5d,0x021d,0x35,0x3532,0x0139,0x08,0x05,0x00,0x00,0x00,0x10},  /* 640x400x16 */
- 	{0x5e,0x021f,0x35,0x3532,0x0000,0x08,0x05,0x00,0x00,0x00,0x10},  /* TW: inserted 640x400x32 */
-	{0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08},
-	{0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600x32 */
-	{0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},
-	{0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},
-	{0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},
-	{0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27},
-	{0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27},
-	{0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27},
-	{0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x11,0x00,0x00,0x00,0x28},  /* TW: 2048x1536x8 - not in BIOS! */
-	{0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x11,0x00,0x00,0x00,0x28},  /* TW: 2048x1536x16 - not in BIOS! */
-	{0x6e,0x0a3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 1280x960x8 */
-	{0x6f,0x0a7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 1280x960x16 */
-	/* TW: 16:9 modes - not in ANY BIOS */
-	{0x70,0x2a1b,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x8 */
-	{0x71,0x0a1b,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},    /* 1024x576x8 */
-	{0x74,0x0a1d,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},    /* 1024x576x16 */
-	{0x75,0x0e3d,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x16 */
-	{0x76,0x2a1f,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x32 */
-	{0x77,0x0a3f,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},	   /* 1024x576x32 */
-	{0x78,0x0eff,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x32 */
-	{0x79,0x0e3b,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x8 */
-	{0x7a,0x2a1d,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x16 */
-	/* TW: End of new 16:9 modes */
-	{0x7b,0x0aff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},    /* 1280x960x32 */
-	{0x20,0x0a1b,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},    /* 1024x600 */
-	{0x21,0x0a3d,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
-	{0x22,0x0a7f,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
-	{0x23,0x0a1b,0xc5,0x0000,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},    /* 1152x768 */
-	{0x24,0x0a3d,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
-	{0x25,0x0a7f,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
-	{0x29,0x0e1b,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},    /* TW: NEW 1152x864 - not in BIOS */
-	{0x2a,0x0e3d,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
-	{0x2b,0x0e7f,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
-	{0x39,0x2a1b,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},    /* TW: NEW 848x480 - not in BIOS */
-	{0x3b,0x2a3d,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
-	{0x3e,0x2a7f,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
-	{0x3f,0x2a1b,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},    /* TW: NEW 856x480 - not in BIOS */
-	{0x42,0x2a3d,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
-	{0x45,0x2a7f,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
-	{0x48,0x223b,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},    /* TW: NEW 1360x768 - not in BIOS */
-	{0x4b,0x227d,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
-	{0x4e,0x22ff,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
-	{0x4f,0x921f,0x00,0x0000,0x0000,0x08,0x00,0x00,0x00,0x00,0x23},    /* TW: New 320x200x32 */
-	{0x53,0x921f,0x01,0x0000,0x0000,0x08,0x01,0x00,0x00,0x00,0x24},    /* TW: New 320x240x32 */
-	{0x54,0xb21f,0x13,0x0000,0x0000,0x08,0x03,0x00,0x00,0x00,0x25},    /* TW: New 400x300x32 */
-	{0xff,0x0000,0x00,0x0000,0xffff,0x00,0x00,0x00,0x00,0x00,0x00}
+	{0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x? */
+	{0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
+	{0x2f,0x021b,0x0305,0x0100,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x8 */
+	{0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600,  0x00,0x00,0x00,0x00},
+	{0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x8 */
+	{0x32,0x2a1b,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x8 */
+	{0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x16 */
+	{0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x16 */
+	{0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x32 */
+	{0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x32 */
+	{0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},  /* 1024x768x? */
+	{0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},  /* 1024x768x8 */
+	{0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},  /* 1280x1024x8 */
+	{0x3c,0x063b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
+	{0x3d,0x067d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
+	{0x40,0x921c,0x0000,0x010d,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x15 */
+	{0x41,0x921d,0x0000,0x010e,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x16 */
+	{0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
+	{0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
+	{0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x15 */
+	{0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x16 */
+	{0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
+	{0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
+	{0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
+	{0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
+	{0x50,0x921b,0x0001,0x0132,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x8  */
+	{0x51,0xb21b,0x0103,0x0133,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x8  */
+	{0x52,0x921b,0x0204,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x8  */
+	{0x56,0x921d,0x0001,0x0135,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x16 */
+	{0x57,0xb21d,0x0103,0x0136,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x16 */
+	{0x58,0x921d,0x0204,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x16 */
+	{0x59,0x921b,0x0000,0x0138,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x8  */
+	{0x5c,0x921f,0x0204,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x32 */
+	{0x5d,0x021d,0x0305,0x0139,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x16 */
+ 	{0x5e,0x021f,0x0305,0x0000,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x32 */
+	{0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
+	{0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x32 */
+	{0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
+	{0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
+	{0x66,0x06ff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
+	{0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
+	{0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
+	{0x6b,0x07ff,0x080b,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
+	{0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28},  /* 2048x1536x8 - not in BIOS! */
+	{0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28},  /* 2048x1536x16 - not in BIOS! */
+	{0x70,0x2a1b,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x8 */
+	{0x71,0x0a1b,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x8 */
+	{0x74,0x0a1d,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x16 */
+	{0x75,0x0e3d,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x16 */
+	{0x76,0x2a1f,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x32 */
+	{0x77,0x0a3f,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x32 */
+	{0x78,0x0eff,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x32 */
+	{0x79,0x0e3b,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x8 */
+	{0x7a,0x2a1d,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x16 */
+	{0x7c,0x0a3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x8 */
+	{0x7d,0x0a7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x16 */
+	{0x7e,0x0aff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x32 */
+	{0x20,0x0a1b,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},  /* 1024x600 */
+	{0x21,0x0a3d,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},
+	{0x22,0x0a7f,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},
+	{0x23,0x0a1b,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},  /* 1152x768 */
+	{0x24,0x0a3d,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},
+	{0x25,0x0a7f,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},
+	{0x29,0x0e1b,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},  /* 1152x864 */
+	{0x2a,0x0e3d,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},
+	{0x2b,0x0e7f,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},
+	{0x39,0x2a1b,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},  /* 848x480 */
+	{0x3b,0x2a3d,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},
+	{0x3e,0x2a7f,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},
+	{0x3f,0x2a1b,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},  /* 856x480 */
+	{0x42,0x2a3d,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},
+	{0x45,0x2a7f,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},
+	{0x48,0x223b,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},  /* 1360x768 */
+	{0x4b,0x227d,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},
+	{0x4e,0x22ff,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},
+	{0x4f,0x921f,0x0000,0x0000,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x32 */
+	{0x53,0x921f,0x0001,0x0000,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x32 */
+	{0x54,0xb21f,0x0103,0x0000,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x32 */
+	{0x55,0x2e3b,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},  /* 1280x768   */
+	{0x5a,0x2e7d,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},
+	{0x5b,0x2eff,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},
+	{0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x8 */
+	{0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x16 */
+	{0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x32 */
+	{0x67,0x2e3b,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x8 (BARCO) */
+	{0x6f,0x2e7d,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x16 (BARCO) */
+	{0x72,0x2eff,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x32 (BARCO) */
+	{0xff,0x0000,0x0000,0xffff,0x00,            0x00,0x00,0x00,0x00}
 };
 
 typedef struct _SiS300_Ext2Struct
@@ -517,76 +181,77 @@
 	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
-	USHORT ROM_OFFSET;
 } SiS300_Ext2Struct;
 
 static const SiS300_Ext2Struct  SiS300_RefIndex[] =
 { /* TW: Don't ever insert anything here, table is indexed */
-	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3563}, /* 00 */
-	{0x0467,0x0e,0x44,0x05,0x6a, 800, 600,0x3568}, /* 01 */
-	{0x0067,0x0f,0x07,0x48,0x6a, 800, 600,0x356d}, /* 02 - CRT1CRTC was 0x4f */
-	{0x0067,0x10,0x06,0x8b,0x6a, 800, 600,0x3572}, /* 03 */
-	{0x0147,0x11,0x08,0x00,0x6a, 800, 600,0x3577}, /* 04 */
-	{0x0147,0x12,0x0c,0x00,0x6a, 800, 600,0x357c}, /* 05 */
-	{0x0047,0x11,0x4e,0x00,0x6a, 800, 600,0x3581}, /* 06 - CRT1CRTC was 0x51 */
-	{0x0047,0x11,0x13,0x00,0x6a, 800, 600,0x3586}, /* 07 */
-	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3539}, /* 08 */
-	{0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x353e}, /* 09 */
-	{0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3543}, /* 0a */
-	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3548}, /* 0b */
-	{0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x354d}, /* 0c */
-	{0xc047,0x0a,0x08,0x00,0x2e, 640, 480,0x3552}, /* 0d */
-	{0xc047,0x0b,0x0a,0x00,0x2e, 640, 480,0x3557}, /* 0e */
-	{0xc047,0x0c,0x10,0x00,0x2e, 640, 480,0x355c}, /* 0f */
-	{0x487f,0x04,0x00,0x00,0x2f, 640, 400,0x3532}, /* 10 */
-	{0xc00f,0x31,0x01,0x06,0x31, 720, 480,0x3630}, /* 11 */
-	{0x000f,0x32,0x03,0x06,0x32, 720, 576,0x3637}, /* 12 */
-	{0x0187,0x15,0x05,0x00,0x37,1024, 768,0x358d}, /* 13 */
-        {0xc877,0x16,0x09,0x06,0x37,1024, 768,0x3592}, /* 14 */
-	{0xc067,0x17,0x0b,0x49,0x37,1024, 768,0x3597}, /* 15 - CRT1CRTC was 0x97 */
-	{0x0267,0x18,0x0d,0x00,0x37,1024, 768,0x359c}, /* 16 */
-	{0x0047,0x19,0x11,0x8c,0x37,1024, 768,0x35a1}, /* 17 - CRT1CRTC was 0x59 */
-	{0x0047,0x1a,0x52,0x00,0x37,1024, 768,0x35a6}, /* 18 */
-	{0x0007,0x1b,0x16,0x00,0x37,1024, 768,0x35ab}, /* 19 - CRT1CRTC was 0x5b */
-	{0x0387,0x1c,0x4d,0x00,0x3a,1280,1024,0x35be}, /* 1a - CRT1CRTC was 0x5c */
-	{0x0077,0x1d,0x14,0x07,0x3a,1280,1024,0x35c3}, /* 1b */
-	{0x0047,0x1e,0x17,0x00,0x3a,1280,1024,0x35c8}, /* 1c */
-	{0x0007,0x1f,0x98,0x00,0x3a,1280,1024,0x35cd}, /* 1d */
-	{0x0007,0x20,0x59,0x00,0x3c,1600,1200,0x35d4}, /* 1e - CRT1CRTC was 0x60 */
-	{0x0007,0x21,0x5a,0x00,0x3c,1600,1200,0x35d9}, /* 1f */
-	{0x0007,0x22,0x1b,0x00,0x3c,1600,1200,0x35de}, /* 20 */
-	{0x0007,0x23,0x1d,0x00,0x3c,1600,1200,0x35e3}, /* 21 - CRT1CRTC was 0x63 */
-	{0x0007,0x24,0x1e,0x00,0x3c,1600,1200,0x35e8}, /* 22 */
-	{0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3516}, /* 23 */
-	{0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x351d}, /* 24 */
-	{0x0077,0x02,0x04,0x05,0x51, 400, 300,0x3524}, /* 25 */
-	{0xc877,0x03,0x09,0x06,0x52, 512, 384,0x352b}, /* 26 */  /* was c077 */
-	{0x8207,0x25,0x1f,0x00,0x68,1920,1440,0x35ef}, /* 27 */
-	{0x0007,0x26,0x20,0x00,0x6c,2048,1536,0x35f6}, /* 28 */
-	{0x0067,0x27,0x14,0x08,0x6e,1280, 960,0x35b7}, /* 29 - TW: 1280x960-60 */
-	{0x0027,0x45,0x3c,0x08,0x6e,1280, 960,0x35b7}, /* 2a - TW: 1280x960-85 */
-	{0xc077,0x33,0x09,0x06,0x20,1024, 600,0x0000}, /* 2b */
-	{0xc077,0x34,0x0b,0x06,0x23,1152, 768,0x0000}, /* 2c */	/* VCLK 0x09 */
-	{0x0057,0x35,0x27,0x08,0x70, 800, 480,0x3b52}, /* 2d - TW: 16:9 modes */
-	{0x0047,0x36,0x37,0x08,0x70, 800, 480,0x3b57}, /* 2e */
-	{0x0047,0x37,0x08,0x08,0x70, 800, 480,0x3b5c}, /* 2f */
-	{0x0057,0x38,0x09,0x09,0x71,1024, 576,0x3b63}, /* 30 */
-	{0x0047,0x39,0x38,0x09,0x71,1024, 576,0x3b68}, /* 31 */
-	{0x0047,0x3a,0x11,0x09,0x71,1024, 576,0x3b6d}, /* 32 */
-	{0x0057,0x3b,0x39,0x0a,0x75,1280, 720,0x3b74}, /* 33 */
-	{0x0047,0x3c,0x3a,0x0a,0x75,1280, 720,0x3b79}, /* 34 */
-	{0x0007,0x3d,0x3b,0x0a,0x75,1280, 720,0x3b7e}, /* 35 - TW: END of 16:9 modes */
-	{0x0047,0x3e,0x34,0x06,0x29,1152, 864,0x0000}, /* 36 TW: 1152x864-75Hz - Non-BIOS, new */
-	{0x0047,0x44,0x3a,0x06,0x29,1152, 864,0x0000}, /* 37 TW: 1152x864-85Hz - Non-BIOS, new */
-	{0x00c7,0x3f,0x28,0x00,0x39, 848, 480,0x0000}, /* 38 TW: 848x480-38Hzi - Non-BIOS, new */
-	{0xc047,0x40,0x3d,0x00,0x39, 848, 480,0x0000}, /* 39 TW: 848x480-60Hz  - Non-BIOS, new */
-	{0x00c7,0x41,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3a TW: 856x480-38Hzi - Non-BIOS, new */
-	{0xc047,0x42,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3b TW: 856x480-60Hz  - Non-BIOS, new */
-	{0x0047,0x43,0x3e,0x00,0x48,1360, 768,0x0000}, /* 3c TW: 1360x768-60Hz - Non-BIOS, new */
-	{0xffff,0,0,0,0,0,0,0}
+	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 00 */
+	{0x0467,0x0e,0x44,0x05,0x6a, 800, 600}, /* 01 */
+	{0x0067,0x0f,0x07,0x48,0x6a, 800, 600}, /* 02 - CRT1CRTC was 0x4f */
+	{0x0067,0x10,0x06,0x8b,0x6a, 800, 600}, /* 03 */
+	{0x0147,0x11,0x08,0x00,0x6a, 800, 600}, /* 04 */
+	{0x0147,0x12,0x0c,0x00,0x6a, 800, 600}, /* 05 */
+	{0x0047,0x11,0x4e,0x00,0x6a, 800, 600}, /* 06 - CRT1CRTC was 0x51 */
+	{0x0047,0x11,0x13,0x00,0x6a, 800, 600}, /* 07 */
+	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 08 */
+	{0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 09 */
+	{0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0a */
+	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0b */
+	{0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0c */
+	{0xc047,0x0a,0x08,0x00,0x2e, 640, 480}, /* 0d */
+	{0xc047,0x0b,0x0a,0x00,0x2e, 640, 480}, /* 0e */
+	{0xc047,0x0c,0x10,0x00,0x2e, 640, 480}, /* 0f */
+	{0x487f,0x04,0x00,0x00,0x2f, 640, 400}, /* 10 */
+	{0xc00f,0x31,0x01,0x06,0x31, 720, 480}, /* 11 */
+	{0x000f,0x32,0x03,0x06,0x32, 720, 576}, /* 12 */
+	{0x0187,0x15,0x05,0x00,0x37,1024, 768}, /* 13 */
+        {0xc877,0x16,0x09,0x06,0x37,1024, 768}, /* 14 */
+	{0xc067,0x17,0x0b,0x49,0x37,1024, 768}, /* 15 - CRT1CRTC was 0x97 */
+	{0x0267,0x18,0x0d,0x00,0x37,1024, 768}, /* 16 */
+	{0x0047,0x19,0x11,0x8c,0x37,1024, 768}, /* 17 - CRT1CRTC was 0x59 */
+	{0x0047,0x1a,0x52,0x00,0x37,1024, 768}, /* 18 */
+	{0x0007,0x1b,0x16,0x00,0x37,1024, 768}, /* 19 - CRT1CRTC was 0x5b */
+	{0x0387,0x1c,0x4d,0x00,0x3a,1280,1024}, /* 1a - CRT1CRTC was 0x5c */
+	{0x0077,0x1d,0x14,0x07,0x3a,1280,1024}, /* 1b */
+	{0x0047,0x1e,0x17,0x00,0x3a,1280,1024}, /* 1c */
+	{0x0007,0x1f,0x98,0x00,0x3a,1280,1024}, /* 1d */
+	{0x0007,0x20,0x59,0x00,0x3c,1600,1200}, /* 1e - CRT1CRTC was 0x60 */
+	{0x0007,0x21,0x5a,0x00,0x3c,1600,1200}, /* 1f */
+	{0x0007,0x22,0x1b,0x00,0x3c,1600,1200}, /* 20 */
+	{0x0007,0x23,0x1d,0x00,0x3c,1600,1200}, /* 21 - CRT1CRTC was 0x63 */
+	{0x0007,0x24,0x1e,0x00,0x3c,1600,1200}, /* 22 */
+	{0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 23 */
+	{0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 24 */
+	{0x0077,0x02,0x04,0x05,0x51, 400, 300}, /* 25 */
+	{0xc877,0x03,0x09,0x06,0x52, 512, 384}, /* 26 */  /* was c077 */
+	{0x8207,0x25,0x1f,0x00,0x68,1920,1440}, /* 27 */
+	{0x0007,0x26,0x20,0x00,0x6c,2048,1536}, /* 28 */
+	{0x0067,0x27,0x14,0x08,0x6e,1280, 960}, /* 29 - TW: 1280x960-60 */
+	{0x0027,0x45,0x3c,0x08,0x6e,1280, 960}, /* 2a - TW: 1280x960-85 */
+	{0xc077,0x33,0x09,0x06,0x20,1024, 600}, /* 2b */
+	{0xc077,0x34,0x0b,0x06,0x23,1152, 768}, /* 2c */	/* VCLK 0x09 */
+	{0x0057,0x35,0x27,0x08,0x70, 800, 480}, /* 2d */
+	{0x0047,0x36,0x37,0x08,0x70, 800, 480}, /* 2e */
+	{0x0047,0x37,0x08,0x08,0x70, 800, 480}, /* 2f */
+	{0x0057,0x38,0x09,0x09,0x71,1024, 576}, /* 30 */
+	{0x0047,0x39,0x38,0x09,0x71,1024, 576}, /* 31 */
+	{0x0047,0x3a,0x11,0x09,0x71,1024, 576}, /* 32 */
+	{0x0057,0x3b,0x39,0x0a,0x75,1280, 720}, /* 33 */
+	{0x0047,0x3c,0x3a,0x0a,0x75,1280, 720}, /* 34 */
+	{0x0007,0x3d,0x3b,0x0a,0x75,1280, 720}, /* 35 */
+	{0x0047,0x3e,0x34,0x06,0x29,1152, 864}, /* 36 1152x864-75Hz */
+	{0x0047,0x44,0x3a,0x06,0x29,1152, 864}, /* 37 1152x864-85Hz */
+	{0x00c7,0x3f,0x28,0x00,0x39, 848, 480}, /* 38 848x480-38Hzi */
+	{0xc047,0x40,0x3d,0x00,0x39, 848, 480}, /* 39 848x480-60Hz  */
+	{0x00c7,0x41,0x28,0x00,0x3f, 856, 480}, /* 3a 856x480-38Hzi */
+	{0xc047,0x42,0x28,0x00,0x3f, 856, 480}, /* 3b 856x480-60Hz  */
+	{0x0047,0x43,0x3e,0x00,0x48,1360, 768}, /* 3c 1360x768-60Hz */
+	{0x0077,0x46,0x3f,0x08,0x55,1280, 768}, /* 3d 1280x768-60Hz */
+	{0x000f,0x47,0x03,0x06,0x5f, 768, 576}, /* 3e 768x576 */
+	{0x0027,0x48,0x13,0x08,0x67,1360,1024}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
+	{0xffff,   0,   0,   0,   0,   0,   0}
 };
 
-/*add for 300 oem util*/
 typedef struct _SiS_VBModeIDTableStruct
 {
 	UCHAR  ModeID;
@@ -652,9 +317,8 @@
 	{0x6e,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
 	{0x6f,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
 	{0x7b,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
-	{0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}  /* TW: added! */
+	{0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
 };
-/*end*/
 
 typedef struct _SiS300_CRT1TableStruct
 {
@@ -673,21 +337,17 @@
   0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x04,
   0x00}},
 #endif
-#if 1
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,    /* 0x01 */
   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,     /* HRE [4],[15] is invalid - but correcting it does not work */
   0x00}},
-#endif
 #if 0
  {{0x2d,0x27,0x27,0x91,0x2c,0x92,0x0b,0x3e,    /* 0x01 - corrected 320x240-60 - does not work */
   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x04,
   0x00}},
 #endif
-#if 1
  {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,    /* 0x02 */
   0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
   0x01}},
-#endif
 #if 0
  {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,    /* 0x02 - corrected 400x300-60 */
   0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
@@ -707,7 +367,7 @@
  {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,    /* 0x05 - corrected 640x480-60 */
   0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
   0x00}},
- #if 0  
+#if 0  
  {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,    /* 0x06 */
   0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
   0x00}},
@@ -865,15 +525,10 @@
  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,  /* 0x33 - 1024x600 */
   0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
   0x01}},
-#if 0
- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,  /* 0x34 - 1152x768 */
-  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
-  0x01}},
-#endif
- {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5,  /* 0x34 - 1152x768 - TW: corrected */
+ {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5,  /* 0x34 - 1152x768 - corrected */
   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
   0x01}},
- {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,  /* 0x35 - NEW 16:9 modes, not in BIOS ------ */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,  /* 0x35 */
    0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
    0x01}}, /* 0x35 */
  {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
@@ -888,7 +543,7 @@
  {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
    0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
    0x01}}, /* 0x39 */
- {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,   	/* TW: 95 was 15 - illegal HBE! */
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,  /* 95 was 15 - illegal HBE! */
    0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
    0x01}}, /* 0x3a */
  {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
@@ -899,36 +554,40 @@
    0x01}}, /* 0x3c */
  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
    0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
-   0x01}}, /* 0x3d */			     /* TW: End of 16:9 modes --------------- */
- {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef,  /* TW: New, 1152x864-75 (not in any BIOS)   */
+   0x01}}, /* 0x3d */
+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef,  /* 1152x864-75 */
    0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
    0x01}},  /* 0x3e */
- {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15,  /* TW: New, 848x480-38i, not in BIOS */
+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15,  /* 848x480-38i */
    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
    0x00}}, /* 0x3f */
-#if 0
- {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E,  /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */
-   0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
-   0x00}}, /* 0x40 */
-#endif
- {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E,  /* TW: New, 848x480-60, not in BIOS */
+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E,  /* 848x480-60  */
    0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
    0x00}}, /* 0x40 */
- {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15,  /* TW: New, 856x480-38i, not in BIOS */
+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15,  /* 856x480-38i */
    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
    0x00}}, /* 0x41 */
- {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E,  /* TW: New, 856x480-60, not in BIOS */
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E,  /* 856x480-60  */
    0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
    0x00}}, /* 0x42 */
- {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd,  /* TW: New, 1360x768-60, not in BIOS */
+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd,  /* 1360x768-60 */
    0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
    0x01}}, /* 0x43 */
- {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff,  /* TW: New, 1152x864-84 (not in any BIOS)   */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff,  /* 1152x864-84 */
    0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
-   0x01}}, /* 0x44 */   
- {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff,  /* TW: New, 1280x960-85 (not in any BIOS)   */
+   0x01}}, /* 0x44 */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff,  /* 1280x960-85 */
    0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
-   0x01}}  /* 0x45 */
+   0x01}}, /* 0x45 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,  /* 1280x768-60 */
+   0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
+   0x01}},  /* 0x46 */
+ {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0,  /* 768x576 */
+   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
+   0x01}},  /* 0x47 */
+ {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52,  /* 1360x1024 (Barco iQ Pro R300) */
+   0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
+   0x00}}   /* 0x48 */
 };
 
 typedef struct _SiS300_MCLKDataStruct
@@ -937,8 +596,8 @@
 	USHORT CLOCK;
 } SiS300_MCLKDataStruct;
 
-static const SiS300_MCLKDataStruct  SiS300_MCLKData_630[] =	/* 630 */
-{ /* TW: at 0x54 in BIOS */
+static const SiS300_MCLKDataStruct  SiS300_MCLKData_630[] =
+{
 	{ 0x5a,0x64,0x80, 66},
 	{ 0xb3,0x45,0x80, 83},
 	{ 0x37,0x61,0x80,100},
@@ -949,8 +608,8 @@
 	{ 0x37,0x61,0x80,100}
 };
 
-static const SiS300_MCLKDataStruct  SiS300_MCLKData_300[] =  /* 300 */
-{ /* TW: at 0x54 in BIOS */
+static const SiS300_MCLKDataStruct  SiS300_MCLKData_300[] =
+{
 	{ 0x68,0x43,0x80,125},
 	{ 0x68,0x43,0x80,125},
 	{ 0x68,0x43,0x80,125},
@@ -961,6 +620,7 @@
 	{ 0x37,0x61,0x80,100}
 };
 
+#ifdef LINUXBIOS
 typedef struct _SiS300_ECLKDataStruct
 {
 	UCHAR SR2E,SR2F,SR30;
@@ -978,6 +638,7 @@
 	{ 0x54,0x43,0x80,100},
 	{ 0x54,0x43,0x80,100}
 };
+#endif
 
 typedef struct _SiS300_VCLKDataStruct
 {
@@ -988,71 +649,77 @@
 static const SiS300_VCLKDataStruct  SiS300_VCLKData[] =
 {
 	{ 0x1b,0xe1, 25}, /* 0x00 */
-	{ 0x4e,0xe4, 28},
+	{ 0x4e,0xe4, 28}, /* 0x01 */
 	{ 0x57,0xe4, 32}, /* 0x02 */
-	{ 0xc3,0xc8, 36},
+	{ 0xc3,0xc8, 36}, /* 0x03 */
 	{ 0x42,0xc3, 40}, /* 0x04 */
-	{ 0x5d,0xc4, 45},
+	{ 0x5d,0xc4, 45}, /* 0x05 */
 	{ 0x52,0x65, 50}, /* 0x06 */
-	{ 0x53,0x65, 50},
+	{ 0x53,0x65, 50}, /* 0x07 */
 	{ 0x6d,0x66, 56}, /* 0x08 */
-	{ 0x5a,0x64, 65},
+	{ 0x5a,0x64, 65}, /* 0x09 */
 	{ 0x46,0x44, 68}, /* 0x0a */
-	{ 0x3e,0x43, 75},
-	{ 0x6d,0x46, 76}, /* 0x0c: 800x600 | LVDS_2(CH), MITAC(CH);  - 730, A901(301B): 0xb1,0x46, 76 */
-	{ 0x41,0x43, 79},
+	{ 0x3e,0x43, 75}, /* 0x0b */
+	{ 0x6d,0x46, 76}, /* 0x0c */  /* 800x600 | LVDS_2(CH), MITAC(CH);  - 730, A901(301B): 0xb1,0x46, 76 */
+	{ 0x41,0x43, 79}, /* 0x0d */
 	{ 0x31,0x42, 79}, /* 0x0e */
-	{ 0x46,0x25, 85},
+	{ 0x46,0x25, 85}, /* 0x0f */
 	{ 0x78,0x29, 87}, /* 0x10 */
-	{ 0x62,0x44, 95},
+	{ 0x62,0x44, 95}, /* 0x11 */
 	{ 0x2b,0x22,105}, /* 0x12 */
-	{ 0x49,0x24,106},
+	{ 0x49,0x24,106}, /* 0x13 */
 	{ 0xc3,0x28,108}, /* 0x14 */
-	{ 0x3c,0x23,109},
+	{ 0x3c,0x23,109}, /* 0x15 */
 	{ 0xf7,0x2c,132}, /* 0x16 */
-	{ 0xd4,0x28,136},
+	{ 0xd4,0x28,136}, /* 0x17 */
 	{ 0x41,0x05,158}, /* 0x18 */
-	{ 0x43,0x05,162},
+	{ 0x43,0x05,162}, /* 0x19 */
 	{ 0xe1,0x0f,175}, /* 0x1a */
 	{ 0xfc,0x12,189}, /* 0x1b */
 	{ 0xde,0x26,194}, /* 0x1c */
-	{ 0x54,0x05,203},
+	{ 0x54,0x05,203}, /* 0x1d */
 	{ 0x3f,0x03,230}, /* 0x1e */
-	{ 0x30,0x02,234},
+	{ 0x30,0x02,234}, /* 0x1f */
 	{ 0x24,0x01,266}, /* 0x20 */
-	{ 0x52,0x2a, 54}, /* 301 TV */
-	{ 0x52,0x6a, 27}, /* 301 TV */
-	{ 0x62,0x24, 70}, /* 301 TV */
-	{ 0x62,0x64, 70}, /* 301 TV */
-	{ 0xa8,0x4c, 30}, /* 301 TV */
-	{ 0x20,0x26, 33}, /* 301 TV */
-	{ 0x31,0xc2, 39},
-	{ 0xbf,0xc8, 35}, /* 0x28 - 856x480 */
-	{ 0x60,0x36, 30}, /* 0x29  CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
-	{ 0x40,0x4a, 28},
-	{ 0x9f,0x46, 44},
-	{ 0x97,0x2c, 26},
-	{ 0x44,0xe4, 25},
-	{ 0x7e,0x32, 47},
-	{ 0x8a,0x24, 31}, /* 0x2f  CH/PAL TEXT | LVDS_2(CH), Mitac(CH) -  730, A901(301B): 0x57, 0xe4, 31 */
-	{ 0x97,0x2c, 26},
-	{ 0xce,0x3c, 39},
-	{ 0x52,0x4a, 36}, /* 0x32  CH/PAL 800x600 5/6 */
-	{ 0x34,0x61, 95},
-	{ 0x78,0x27,108},
-	{ 0xce,0x25,189}, /* 0x35 */
-	{ 0x45,0x6b, 21}, /* 0x36 */  /* TW: Added from Mitac */
-	{ 0x52,0xe2, 49}, /* 0x37 - added for 16:9 modes (not in any BIOS) */
-	{ 0x2b,0x61, 78}, /* 0x38 - added for 16:9 modes (not in any BIOS) */
-	{ 0x70,0x44,108}, /* 0x39 - added for 16:9 modes (not in any BIOS) */
-	{ 0x54,0x42,135}, /* 0x3a - added for 16:9 modes (not in any BIOS) */
-	{ 0x41,0x22,157}, /* 0x3b - added for 16:9 modes (not in any BIOS) */
-	{ 0x52,0x07,149}, /* 0x3c - added for 1280x960-85 (not in any BIOS)*/
-	{ 0x62,0xc6, 34}, /* 0x3d - added for 848x480-60 (not in any BIOS) */
-	{ 0x30,0x23, 88}, /* 0x3e - added for 1360x768-60 (not in any BIOS)*/
-	{ 0x3f,0x64, 46}, /* 0x3f - added for 640x480-100 (not in any BIOS)*/
-	{ 0x72,0x2a, 76}, /* 0x40 - test for SiS730 */
-	{ 0x15,0x21, 79}, /* 0x41 - test for SiS730 */
+	{ 0x52,0x2a, 54}, /* 0x21 */  /* 301 TV */
+	{ 0x52,0x6a, 27}, /* 0x22 */  /* 301 TV */
+	{ 0x62,0x24, 70}, /* 0x23 */  /* 301 TV */
+	{ 0x62,0x64, 70}, /* 0x24 */  /* 301 TV */
+	{ 0xa8,0x4c, 30}, /* 0x25 */  /* 301 TV */
+	{ 0x20,0x26, 33}, /* 0x26 */  /* 301 TV */
+	{ 0x31,0xc2, 39}, /* 0x27 */
+	{ 0xbf,0xc8, 35}, /* 0x28 */  /* 856x480 */
+	{ 0x60,0x36, 30}, /* 0x29 */  /* CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
+	{ 0x40,0x4a, 28}, /* 0x2a */
+	{ 0x9f,0x46, 44}, /* 0x2b */
+	{ 0x97,0x2c, 26}, /* 0x2c */
+	{ 0x44,0xe4, 25}, /* 0x2d */
+	{ 0x7e,0x32, 47}, /* 0x2e */
+	{ 0x8a,0x24, 31}, /* 0x2f */  /* CH/PAL TEXT | LVDS_2(CH), Mitac(CH) -  730, A901(301B): 0x57, 0xe4, 31 */
+	{ 0x97,0x2c, 26}, /* 0x30 */
+	{ 0xce,0x3c, 39}, /* 0x31 */
+	{ 0x52,0x4a, 36}, /* 0x32 */  /* CH/PAL 800x600 5/6 */
+	{ 0x34,0x61, 95}, /* 0x33 */
+	{ 0x78,0x27,108}, /* 0x34 */  /* Replacement for index 0x14 for 630 (?) */
+	{ 0xce,0x25,189}, /* 0x35 */  /* Replacement for index 0x1b for 730 (and 540?) */
+	{ 0x45,0x6b, 21}, /* 0x36 */
+	{ 0x52,0xe2, 49}, /* 0x37 */  /* 16:9 modes  */
+	{ 0x2b,0x61, 78}, /* 0x38 */  /* 16:9 modes  */
+	{ 0x70,0x44,108}, /* 0x39 */  /* 16:9 modes  */
+	{ 0x54,0x42,135}, /* 0x3a */  /* 16:9 modes  */
+	{ 0x41,0x22,157}, /* 0x3b */  /* 16:9 modes  */
+	{ 0x52,0x07,149}, /* 0x3c */  /* 1280x960-85 */
+	{ 0x62,0xc6, 34}, /* 0x3d */  /* 848x480-60  */
+	{ 0x30,0x23, 88}, /* 0x3e */  /* 1360x768-60 */
+#if 0
+	{ 0x3f,0x64, 46}, /* 0x3f */  /* 640x480-100 */
+#endif
+        { 0x70,0x29, 81}, /* 0x3f */  /* 1280x768-60 */
+	{ 0x72,0x2a, 76}, /* 0x40 */  /* test for SiS730 */
+	{ 0x15,0x21, 79}, /* 0x41 */  /* test for SiS730 */
+	{ 0xa1,0x42,108}, /* 0x42 */  /* 1280x960 LCD */
+	{ 0x37,0x61,100}, /* 0x43 */  /* 1280x960 LCD */
+	{ 0xe3,0x9a,106}, /* 0x44 */  /* 1360x1024 - special for Barco iQ R300 */
 	{ 0xff,0x00,  0}   
 };
 
@@ -1113,66 +780,10 @@
 static const UCHAR  SiS300_ScreenOffset[] =
 {
 	0x14,0x19,0x20,0x28,0x32,0x40,0x50,
-        0x64,0x78,0x80,0x2d,0x35,0x48,0x35,  /* 0x35 for 848 and 856 */
-	0x55,0xff			     /* 0x55 for 1360 */	
-};
-
-typedef struct _SiS300_StResInfoStruct
-{
-	USHORT HTotal;
-	USHORT VTotal;
-} SiS300_StResInfoStruct;
-
-static const SiS300_StResInfoStruct  SiS300_StResInfo[] =
-{
-	{ 640,400},
-	{ 640,350},
-	{ 720,400},
-	{ 720,350},
-	{ 640,480}
-};
-
-typedef struct _SiS300_ModeResInfoStruct
-{
-	USHORT HTotal;
-	USHORT VTotal;
-	UCHAR  XChar;
-	UCHAR  YChar;
-} SiS300_ModeResInfoStruct;
-
-static const SiS300_ModeResInfoStruct  SiS300_ModeResInfo[] =
-{
-	{  320, 200, 8, 8},  /* 0x00 */
-	{  320, 240, 8, 8},  /* 0x01 */
-	{  320, 400, 8, 8},  /* 0x02 */
-	{  400, 300, 8, 8},  /* 0x03 */
-	{  512, 384, 8, 8},  /* 0x04 */
-	{  640, 400, 8,16},  /* 0x05 */
-	{  640, 480, 8,16},  /* 0x06 */
-	{  800, 600, 8,16},  /* 0x07 */
-	{ 1024, 768, 8,16},  /* 0x08 */
-	{ 1280,1024, 8,16},  /* 0x09 */
-	{ 1600,1200, 8,16},  /* 0x0a */
-	{ 1920,1440, 8,16},  /* 0x0b */
-	{  720, 480, 8,16},  /* 0x0c */
-	{  720, 576, 8,16},  /* 0x0d */
-	{ 1280, 960, 8,16},  /* 0x0e */
-	{ 1024, 600, 8,16},  /* 0x0f */
-	{ 1152, 768, 8,16},  /* 0x10 */
-	{ 2048,1536, 8,16},  /* 0x11 - TW: Not in BIOS! */
-	{  800, 480, 8,16},  /* 0x12 - TW: New, not in any BIOS */
-	{ 1024, 576, 8,16},  /* 0x13 - TW: New, not in any BIOS */
-	{ 1280, 720, 8,16},  /* 0x14 - TW: New, not in any BIOS */
-	{ 1152, 864, 8,16},  /* 0x15 - TW: New, not in any BIOS */
-	{  848, 480, 8,16},  /* 0x16 - TW: New, not in any BIOS */
-	{  856, 480, 8,16},  /* 0x17 - TW: New, not in any BIOS */
-	{ 1360, 768, 8,16}   /* 0x18 - TW: New, not in any BIOS */
+        0x64,0x78,0x80,0x2d,0x35,0x48,0x35,
+	0x55,0x30,0xff
 };
 
-static const UCHAR SiS300_OutputSelect = 0x40;
-
-static const UCHAR SiS300_SoftSetting  = 0x30;
-
 #ifndef LINUX_XF86
 static UCHAR SiS300_SR07 = 0x10;
 #endif
@@ -1207,7 +818,7 @@
 static const USHORT SiS300_RGBSenseData = 0xd1;
 static const USHORT SiS300_VideoSenseData = 0xb3;
 static const USHORT SiS300_YCSenseData = 0xb9;
-static const USHORT SiS300_RGBSenseData2 = 0x0190;     /*301b*/
+static const USHORT SiS300_RGBSenseData2 = 0x0190;
 static const USHORT SiS300_VideoSenseData2 = 0x0174;
 static const USHORT SiS300_YCSenseData2 = 0x016b;
 
@@ -1216,15 +827,6 @@
 static UCHAR SiS300_CR49[2];
 #endif
 
-static const UCHAR SiS300_NTSCPhase[]  = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
-static const UCHAR SiS300_PALPhase[]   = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00};  */
-static const UCHAR SiS300_PALMPhase[]  = {0x21,0xE4,0x2E,0x9B};  /* palmn */
-static const UCHAR SiS300_PALNPhase[]  = {0x21,0xF4,0x3E,0xBA};
-static const UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};  /* 301b */
-static const UCHAR SiS300_PALPhase2[]  = {0x2a,0x09,0x86,0xe9};  /* 301b */
-static const UCHAR SiS300_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
-static const UCHAR SiS300_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
-
 typedef struct _SiS300_PanelDelayTblStruct
 {
 	UCHAR timer[2];
@@ -1232,7 +834,7 @@
 
 static const SiS300_PanelDelayTblStruct  SiS300_PanelDelayTbl[] =
 {
-	{{0x05,0xaa}}, /* TW: From 2.04.5a */
+	{{0x05,0xaa}},
 	{{0x05,0x14}},
 	{{0x05,0x36}},
 	{{0x05,0x14}},
@@ -1379,322 +981,6 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS300_LCDDataStruct  SiS300_NoScaleData[] =
-{
-	{ 1, 1, 800, 449, 800, 449 },
-	{ 1, 1, 800, 449, 800, 449 },
-	{ 1, 1, 900, 449, 900, 449 },
-	{ 1, 1, 900, 449, 900, 449 },
-	{ 1, 1, 800, 525, 800, 525 },
-	{ 1, 1,1056, 628,1056, 628 },
-	{ 1, 1,1344, 806,1344, 806 },
-	{ 1, 1,1688,1066,1688,1066 },
-	{ 1, 1,1800,1000,1800,1000 }   /* 1280x960 */
-};
-
-static const SiS300_LCDDataStruct  SiS300_LCD1280x960Data[] =
-{
-	{    9,   2, 800, 500,1800,1000},
-	{    9,   2, 800, 500,1800,1000},
-	{    4,   1, 900, 500,1800,1000},
-	{    4,   1, 900, 500,1800,1000},
-	{    9,   2, 800, 500,1800,1000},
-	{   30,  11,1056, 625,1800,1000},
-	{    5,   3,1350, 800,1800,1000},
-	{    1,   1,1576,1050,1576,1050},
-	{    1,   1,1800,1000,1800,1000}
-};
-
-static const SiS300_LCDDataStruct  SiS300_ExtLCD1400x1050Data[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS300_LCDDataStruct  SiS300_ExtLCD1600x1200Data[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS300_LCDDataStruct  SiS300_StLCD1400x1050Data[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS300_LCDDataStruct  SiS300_StLCD1600x1200Data[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS300_LCDDataStruct  SiS300_NoScaleData1400x1050[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS300_LCDDataStruct  SiS300_NoScaleData1600x1200[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-
-typedef struct _SiS300_TVDataStruct
-{
-	USHORT RVBHCMAX;
-	USHORT RVBHCFACT;
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT TVHDE;
-	USHORT TVVDE;
-	USHORT RVBHRS;
-	UCHAR FlickerMode;
-	USHORT HALFRVBHRS;
-	UCHAR RY1COE;
-	UCHAR RY2COE;
-	UCHAR RY3COE;
-	UCHAR RY4COE;
-} SiS300_TVDataStruct;
-
-static const SiS300_TVDataStruct  SiS300_StPALData[] =
-{
-	{    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
-	{    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
-	{    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
-	{    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
-	{    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
-	{    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
-};
-
-static const SiS300_TVDataStruct  SiS300_ExtPALData[] =
-{
-	{   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
-	{  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
-	{   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
-	{    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
-	{    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},
-	{   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},
-	{    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},
-	{    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}
-
-};
-
-static const SiS300_TVDataStruct  SiS300_StNTSCData[] =
-{
-	{    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
-	{    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
-	{    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
-	{    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
-	{    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
-};
-
-static const SiS300_TVDataStruct  SiS300_ExtNTSCData[] =
-{
-	{  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
-	{   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
-	{  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
-	{  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
-	{  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
-	{  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
-	{  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},
-	{   65,  64,1056, 791,1270, 480, 638,   0,   0,0xf1,0x04,0x1f,0x18}
-};
-
-#if 0
-static const SiS300_TVDataStruct  SiS300_St1HiTVData[]=
-{
-  
-};
-#endif
-
-static const SiS300_TVDataStruct  SiS300_St2HiTVData[]=
-{
- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
- {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
-};
-
-static const SiS300_TVDataStruct  SiS300_ExtHiTVData[]=
-{
- {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
- {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
- {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},
- {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
- {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}
-};
-
-static const UCHAR SiS300_NTSCTiming[] =
-{
-	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
-	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
-	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
-	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,  /* (in 2.06.50) */
-/*	0x0c,0x50,0x00,0x99,0x00,0xec,0x4a,0x17,     (in 2.04.5a) */
-	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,  /* (in 2.06.50) */
-/*	0x88,0x00,0x4b,0x00,0x00,0xe2,0x00,0x02,     (in 2.04.5a) */
-	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
-	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
-};
-
-static const UCHAR SiS300_PALTiming[] =
-{
-	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
-	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
-        0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,  /* (in 2.06.50) */
-/*	0x70,0x50,0x00,0x97,0x00,0xd7,0x5d,0x17,     (in 2.04.5a) */
-	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,  /* (in 2.06.50) */
-/*	0x88,0x00,0x45,0x00,0x00,0xe8,0x00,0x02,     (in 2.04.5a) */
-	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
-	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
-};
-
-static const UCHAR SiS300_HiTVExtTiming[] =	 /* TW: New */
-{
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
-};
-
-static const UCHAR SiS300_HiTVSt1Timing[] =   	/* TW: New */
-{
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
-	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
-	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
-	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
-};
-
-static const UCHAR SiS300_HiTVSt2Timing[] =	/* TW: New */
-{
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
-};
-
-static const UCHAR SiS300_HiTVTextTiming[] =   	/* TW: New */
-{
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
-	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
-	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
-        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
-	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
-};
-
-static const UCHAR SiS300_HiTVGroup3Data[] =   	/* TW: New */
-{
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
-	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
-	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
-
-static const UCHAR SiS300_HiTVGroup3Simu[] =   	/* TW: New */
-{
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
-	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
-
-static const UCHAR SiS300_HiTVGroup3Text[] =   	/* TW: New */
-{
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
-	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
-
 typedef struct _SiS300_LVDSDataStruct
 {
 	USHORT VGAHT;
@@ -1703,366 +989,14 @@
 	USHORT LCDVT;
 } SiS300_LVDSDataStruct;
 
-static const SiS300_LVDSDataStruct  SiS300_LVDS320x480Data_1[] =
-{
-	{848, 433,400, 525},
-	{848, 389,400, 525},
-	{848, 433,400, 525},
-	{848, 389,400, 525},
-	{848, 518,400, 525},
-	{1056,628,400, 525},
-	{400, 525,400, 525},
-	{800, 449,1000, 644},
-	{800, 525,1000, 635}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_1[] =
-{
-	{848, 433,1060, 629},
-	{848, 389,1060, 629},
-	{848, 433,1060, 629},
-	{848, 389,1060, 629},
-	{848, 518,1060, 629},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{800, 449,1000, 644},
-	{800, 525,1000, 635}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_2[] =
-{
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{800, 449,1000, 644},
-	{800, 525,1000, 635}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_1[] =
-{
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_2[] =
-{
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_1[]=  
-{	
-	{1048, 442,1688,1066},
-	{1048, 392,1688,1066},
-	{1048, 442,1688,1066},
-	{1048, 392,1688,1066},
-	{1048, 522,1688,1066},
-	{1208, 642,1688,1066},
-	{1432, 810,1688,1066},
-	{1688,1066,1688,1066}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_2[]=  
-{	
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1400x1050Data_1[] =   
-{
-        {928, 416, 1688, 1066},
-	{928, 366, 1688, 1066},
-	{928, 416, 1688, 1066},
-	{928, 366, 1688, 1066},
-	{928, 496, 1688, 1066},
-	{1088, 616, 1688, 1066},
-	{1312, 784, 1688, 1066},
-	{1568, 1040, 1688, 1066},
-	{1688, 1066, 1688, 1066}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1400x1050Data_2[] =  
-{
-        {1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1600x1200Data_1[]=  
-{
-        {1088, 450, 2048,1250},
-	{1088, 400, 2048,1250},
-	{1088, 450, 2048,1250},
-	{1088, 400, 2048,1250},
-	{1088, 530, 2048,1250},
-	{1248, 650, 2048,1250},
-	{1472, 818, 2048,1250},
-	{1728,1066, 2048,1250},
-	{1848,1066, 2048,1250},
-	{2048,1250, 2048,1250}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1600x1200Data_2[]= 
-{
-        {2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x768Data_1[]= 
-{	
-	{ 768, 438, 1408, 806},
-	{ 768, 388, 1408, 806},
-	{ 768, 438, 1408, 806},
-	{ 768, 388, 1408, 806},
-	{ 768, 518, 1408, 806},
-	{ 928, 638, 1408, 806},
-	{1152, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x768Data_2[]=  
-{	
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_1[] =
-{
-	{840, 604,1344, 800},
-	{840, 560,1344, 800},
-	{840, 604,1344, 800},
-	{840, 560,1344, 800},
-	{840, 689,1344, 800},
-	{1050, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{800, 449,1280, 789},
-	{800, 525,1280, 785}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_2[] =
-{
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_1[] =
-{
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_2[] =
-{
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-/* TW: pass 1:1 data */
-static const SiS300_LVDSDataStruct  SiS300_LVDSXXXxXXXData_1[]=  
-{
-        { 800, 449,  800, 449},
-	{ 800, 449,  800, 449},
-	{ 900, 449,  900, 449},
-	{ 900, 449,  900, 449},
-	{ 800, 525,  800, 525},  /*  640x480   */
-	{1056, 628, 1056, 628},  /*  800x600   */
-	{1344, 806, 1344, 806},  /* 1024x768   */
-	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
- 	{1688, 806, 1688, 806},  /* 1280x768 ! */
-	/* No other panels ! */
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS640x480Data_1[] =
-{
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 525, 800, 525},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x960Data_1[] =   /* TW: New */
-{
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x960Data_2[] =   /* TW: New */
-{
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LCDA1400x1050Data_1[] =   /* TW: New */
-{	/* TW: Might be temporary (invalid) data */
-        {928, 416, 1688, 1066},
-	{928, 366, 1688, 1066},
-	{1008, 416, 1688, 1066},
-	{1008, 366, 1688, 1066},
-	{1200, 530, 1688, 1066},
-	{1088, 616, 1688, 1066},
-	{1312, 784, 1688, 1066},
-	{1568, 1040, 1688, 1066},
-	{1688, 1066, 1688, 1066}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LCDA1400x1050Data_2[] =   /* TW: New */
-{	/* TW: Temporary data. Not valid */
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LCDA1600x1200Data_1[] =   /* TW: New */
-{	/* TW: Temporary data. Not valid */
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LCDA1600x1200Data_2[] =   /* TW: New */
-{	/* TW: Temporary data. Not valid */
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0}
-};
-
-
-/* TW: New: */
-static const SiS300_LVDSDataStruct  SiS300_CHTVUNTSCData[] =
-{
-	{840, 600, 840, 600},
-	{840, 600, 840, 600},
-	{840, 600, 840, 600},
-	{840, 600, 840, 600},
-	{784, 600, 784, 600},
-	{1064, 750,1064, 750}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_CHTVONTSCData[] =
-{
-	{840, 525, 840, 525},
-	{840, 525, 840, 525},
-	{840, 525, 840, 525},
-	{840, 525, 840, 525},
-	{784, 525, 784, 525},
-	{1040, 700,1040, 700}
-};
-
 static const SiS300_LVDSDataStruct  SiS300_CHTVUPALData[] =
 {
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
-	{840, 750, 840, 750},
-	{936, 836, 936, 836}
+	{ 840, 750, 840, 750},
+	{ 936, 836, 936, 836}
 };
 
 static const SiS300_LVDSDataStruct  SiS300_CHTVOPALData[] =
@@ -2071,8 +1005,8 @@
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
-	{840, 625, 840, 625},
-	{960, 750, 960, 750}
+	{ 840, 625, 840, 625},
+	{ 960, 750, 960, 750}
 };
 
 static const SiS300_LVDSDataStruct  SiS300_CHTVSOPALData[] =
@@ -2081,12 +1015,10 @@
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
-	{840, 500, 840, 500},
-	{944, 625, 944, 625}
+	{ 840, 500, 840, 500},
+	{ 944, 625, 944, 625}
 };
 
-/* TW: new end */
-
 typedef struct _SiS300_LVDSDesStruct
 {
 	USHORT LCDHDES;
@@ -2095,57 +1027,90 @@
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType00_1[] =
 {
+	{ 1059, 626 },   /* 2.08 */
+	{ 1059, 624 },
+	{ 1059, 626 },
+	{ 1059, 624 },
+	{ 1059, 624 },
+	{    0, 627 },
+	{    0, 627 },
+	{    0,   0 },
+	{    0,   0 }
+#if 0
 	{0, 626},
 	{0, 624},
 	{0, 626},
 	{0, 624},
 	{0, 624},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{0, 627},
+	{0, 627},
+	{0,   0},
+	{0,   0}
+#endif
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType01_1[] =
 {
+	{   0,   0 },  /* 2.08 */
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 }
+#if 0
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
+#endif
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType02_1[] =
 {
+	{ 1059, 626 },  /* 2.08 */
+	{ 1059, 624 },
+	{ 1059, 626 },
+	{ 1059, 624 },
+	{ 1059, 624 },
+	{    0, 627 },
+	{    0, 627 },
+	{    0,   0 },
+	{    0,   0 }
+#if 0
 	{0, 626},
 	{0, 624},
 	{0, 626},
 	{0, 624},
 	{0, 624},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{0, 627},
+	{0, 627},
+	{0,   0},
+	{0,   0}
+#endif
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType03_1[] =
 {
-	{ 8, 436},
-	{ 8, 440},
-	{ 8, 436},
-	{ 8, 440},
-	{ 8, 512},
+	{   8, 436},
+	{   8, 440},
+	{   8, 436},
+	{   8, 440},
+	{   8, 512},
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType04_1[] =
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_1[] =	/* 1280x1024 */
 {
 	{1343, 798},
 	{1343, 794},
@@ -2153,9 +1118,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType05_1[] =
@@ -2166,9 +1131,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType06_1[] =
@@ -2179,9 +1144,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType07_1[] =
@@ -2192,9 +1157,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType08_1[] =
@@ -2204,10 +1169,10 @@
 	{1059, 626},
 	{1059, 624},
 	{1059, 624},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{   0, 627},
+	{   0, 627},
+	{   0,   0},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType09_1[] =
@@ -2218,9 +1183,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0a_1[] =
@@ -2230,23 +1195,23 @@
 	{1059, 626},
 	{1059, 624},
 	{1059, 624},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{   0, 627},
+	{   0, 627},
+	{   0,   0},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0b_1[] =
 {
-	{1343, 0},
-	{1343, 0},
-	{1343, 0},
-	{1343, 0},
-	{1343, 0},   /* 640x480 - BIOS 1343, 0 */
-	{1343, 0},
-	{ 0, 799},
-	{ 0, 0},
-	{ 0, 0}
+	{1343,   0},
+	{1343,   0},
+	{1343,   0},
+	{1343,   0},
+	{1343,   0},
+	{1343,   0},
+	{   0, 799},
+	{   0,   0},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0c_1[] =
@@ -2257,9 +1222,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0d_1[] =
@@ -2270,9 +1235,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0e_1[] =
@@ -2281,11 +1246,11 @@
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343,   0},  /* 640x480 */
-	{1343,   0},  /* 800x600 */
-	{ 0, 805},    /* 1024x768 */
-	{ 0, 794},    /* 1280x1024 */
-	{ 0,   0}     /* 1280x960 - not applicable */
+	{1343,   0},    /* 640x480 */
+	{1343,   0},    /* 800x600 */
+	{   0, 805},    /* 1024x768 */
+	{   0, 794},    /* 1280x1024 */
+	{   0,   0}     /* 1280x960 - not applicable */
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0f_1[] =
@@ -2296,9 +1261,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType00_2[] =
@@ -2308,10 +1273,10 @@
 	{976, 527},
 	{976, 502},
 	{976, 567},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{  0, 627},
+	{  0, 627},
+	{  0,   0},
+	{  0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType01_2[] =
@@ -2322,9 +1287,9 @@
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType02_2[] =
@@ -2334,10 +1299,10 @@
 	{976, 527},
 	{976, 502},
 	{976, 567},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{  0, 627},
+	{  0, 627},
+	{  0,   0},
+	{  0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType03_2[] =
@@ -2509,156 +1474,57 @@
  	{   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelTypeNS_1[]= 
+/* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_1a[] =	/* 1280x1024 (1366x1024) */
 {
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0, 806},
-	{ 0, 0 }
-};
-
-static const SiS300_LVDSDesStruct  SiS300_PanelTypeNS_2[] = 
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1076_1[] =   /* TW: New */
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1076_2[] =   /* TW: New */
-{
-	{ 1152, 622 },
-	{ 1152, 597 },
-	{ 1152, 622 },
-	{ 1152, 597 },
-	{ 1152, 622 },
-	{ 1232, 722 },
-	{    0, 0   },
-	{    0, 794 },
-	{    0, 0   }
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1210_1[] =   /* TW: New */
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1210_2[] =   /* TW: New */
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1296_1[] =   /* TW: New */
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1296_2[] =   /* TW: New */
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-
-/* TW: New */
-static const SiS300_LVDSDesStruct  SiS300_CHTVUNTSCDesData[] =
-{
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0}
-};
-
-static const SiS300_LVDSDesStruct  SiS300_CHTVONTSCDesData[] =
-{
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0}
-};
-
-static const SiS300_LVDSDesStruct  SiS300_CHTVUPALDesData[] =
-{
- 	{256,   0},
- 	{256,   0},
- 	{256,   0},
- 	{256,   0},
- 	{  0,   0},
- 	{  0,   0}
+	{1330, 798},  /* 320x200 */
+	{1330, 794},
+	{1330, 798},
+	{1330, 794},
+	{1330,   0},  /* 640x480 / 320x240  */
+	{1343,   0},  /* 800x600 / 400x300  */
+	{   0, 805},  /* 1024x768 / 512x384 */
+	{1688,1066},  /* 1280x1024          */
+	{   0,   0}   /* 1360x1024          */
 };
 
-static const SiS300_LVDSDesStruct  SiS300_CHTVOPALDesData[] =
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_2a[] =
 {
- 	{256,   0},
- 	{256,   0},
- 	{256,   0},
- 	{256,   0},
- 	{  0,   0},
- 	{  0,   0}
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805},
+	{1688,1066},
+	{   0,   0}
+};
+
+/* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_1b[] =	/* 1024x768 */
+{
+	{1330, 798},  /* 320x200 */
+	{1330, 794},
+	{1330, 798},
+	{1330, 794},
+	{1330,   0},  /* 640x480 / 320x240  */
+	{1343,   0},  /* 800x600 / 400x300  */
+	{   0, 805}   /* 1024x768 / 512x384 */
+};
+
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_2b[] =
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805}
 };
-/* TW: New end */
 
-/* TW: New for SiS300+301LV */
+
 typedef struct _SiS300_Part2PortTblStruct
 {
  	UCHAR CR[12];
@@ -3053,207 +1919,6 @@
 	  0x01}}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1[] =
-{
-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
-	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
-	  0x00}},
-        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1_H[] =
-{
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-          0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-	  0x00}},
-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2[] =
-{
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2_H[] =
-{
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1[] =
-{
-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
-	  0x00}},
-        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1_H[] =
-{
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-	  0x00}},
-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2[] =
-{
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2_H[] =
-{
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-/* TW: New */
 static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[] =
 {
 	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
@@ -3363,9 +2028,7 @@
 	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
 	  0x01 }}
 };
-/* TW: New end */
 
-/* TW: New */
 typedef struct _SiS300_CHTVRegDataStruct
 {
 	UCHAR Reg[16];
@@ -3422,9 +2085,7 @@
 	{{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */
 	{{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}}  /* TW: Mode 19: 800x600 PAL 1/1 */
 };
-/* TW: New end */
 
-/* TW: New */
 static const UCHAR SiS300_CHTVVCLKUNTSC[]  = {0x29,0x29,0x29,0x29,0x2a,0x2e};
 
 static const UCHAR SiS300_CHTVVCLKONTSC[]  = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
@@ -3436,6 +2097,5 @@
 static const UCHAR SiS300_CHTVVCLKOPAL[]   = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
 
 static const UCHAR SiS300_CHTVVCLKSOPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x36,0x29};
-/* TW: New end */
 
 
diff -urN linux-2.4.22-pre2/drivers/video/sis/310vtbl.h linux-2.4.22-pre3/drivers/video/sis/310vtbl.h
--- linux-2.4.22-pre2/drivers/video/sis/310vtbl.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/310vtbl.h	2003-07-05 18:10:59.000000000 -0700
@@ -1,7 +1,35 @@
-
-
-/* Register settings for SiS 310/325/330 series */
-
+/* $XFree86$ */
+/*
+ * Register settings for SiS 315/330 series
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
 
 typedef struct _SiS310_StStruct
 {
@@ -39,466 +67,12 @@
 	{0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-typedef struct _SiS310_StandTableStruct
-{
-	UCHAR CRT_COLS;
-	UCHAR ROWS;
-	UCHAR CHAR_HEIGHT;
-	USHORT CRT_LEN;
-	UCHAR SR[4];
-	UCHAR MISC;
-	UCHAR CRTC[0x19];
-	UCHAR ATTR[0x14];
-	UCHAR GRC[9];
-} SiS310_StandTableStruct;
-
-static const SiS310_StandTableStruct SiS310_StandTable[]=
-{
-/* 0x00: MD_0_200 */
- {
-  0x28,0x18,0x08,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x01: MD_1_200 */
- {
-  0x28,0x18,0x08,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x02: MD_2_200 */
- {
-  0x50,0x18,0x08,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x03: MD_3_200 - mode 0x03 - 0 */
- {
-  0x50,0x18,0x08,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x04: MD_4 */
- {
-  0x28,0x18,0x08,0x4000,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff}
- },
-/* 0x05: MD_5 */
- {
-  0x28,0x18,0x08,0x4000,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff}
- },
-/* 0x06: MD_6 */
- {
-  0x50,0x18,0x08,0x4000,
-  {0x01,0x01,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
-   0xff},
-  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x01,0x00,0x01,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
-   0xff}
- },
-/* 0x07: MD_7 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x00,0x03,0x00,0x03},
-  0xa6,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff}
- },
-/* 0x08: MDA_DAC */
- {
-  0x00,0x00,0x00,0x0000,
-  {0x00,0x00,0x00,0x15},
-  0x15,
-  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
-   0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15},
-  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f}
- },
-/* 0x09: CGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x09,0x15,0x00},
-  0x10,
-  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
-   0x04},
-  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
-   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
-   0x3e,0x2b,0x3b,0x2f},
-  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f}
- },
-/* 0x0a: EGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x05,0x15,0x20},
-  0x30,
-  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
-   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
-   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
-   0x06},
-  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
-   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
-   0x1e,0x0b,0x1b,0x0f},
-  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f}
- },
-/* 0x0b: VGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x09,0x15,0x2a},
-  0x3a,
-  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
-   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
-   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
-   0x1f},
-  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
-   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
-   0x1c,0x0e,0x11,0x15},
-  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
-   0x04}
- },
-/* 0x0c */ 
- {
-  0x08,0x0c,0x10,0x0a08,
-  {0x0c,0x0e,0x10,0x0b},
-  0x0c,
-  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
-   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
-   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
-   0x06},
-  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
-   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
-   0x00,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}
- },
-/* 0x0d: MD_D */
- {
-  0x28,0x18,0x08,0x2000,
-  {0x09,0x0f,0x00,0x06},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* 0x0e: MD_E */
- {
-  0x50,0x18,0x08,0x4000,
-  {0x01,0x0f,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* 0x0f: ExtVGATable - modes > 0x13 */
- {
-  0x00,0x00,0x00,0x0000,
-  {0x01,0x0f,0x00,0x0e},
-  0x23,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x01,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff}
- },
-/* 0x10: ROM_SAVEPTR */
- {
-  0x9f,0x3b,0x00,0x00c0,
-  {0x00,0x00,0x00,0x00},
-  0x00,
-  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
-   0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}
- },
-/* 0x11: MD_F */
- {
-  0x50,0x18,0x0e,0x8000,
-  {0x01,0x0f,0x00,0x06},
-  0xa2,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
-   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
-   0x0b,0x00,0x05,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
-   0xff}
- },
-/* 0x12: MD_10 */
- {
-  0x50,0x18,0x0e,0x8000,
-  {0x01,0x0f,0x00,0x06},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* 0x13: MD_0_350 */
- {
-  0x28,0x18,0x0e,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x14: MD_1_350 */
- {
-  0x28,0x18,0x0e,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x15: MD_2_350 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x16: MD_3_350 - mode 0x03 - 1 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x17: MD_0_1_400 */
- {
-  0x28,0x18,0x10,0x0800,
-  {0x08,0x03,0x00,0x02},
-  0x67,
-  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
- {
-  0x50,0x18,0x10,0x1000,
-  {0x00,0x03,0x00,0x02},
-  0x67,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x19: MD_7_400 */
- {
-  0x50,0x18,0x10,0x1000,
-  {0x00,0x03,0x00,0x02},
-  0x66,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff}
- },
-/* 0x1a: MD_11 */
- {
-  0x50,0x1d,0x10,0xa000,
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,
-   0xff},
-  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
-   0xff}
- },
-/* 0x1b: ExtEGATable - Modes <= 0x02 */
- {
-  0x50,0x1d,0x10,0xa000,
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* 0x1c: MD_13 */
- {
-  0x28,0x18,0x08,0x2000,
-  {0x01,0x0f,0x00,0x0e},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x41,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff}
- }
-};
-
 typedef struct _SiS310_ExtStruct
 {
 	UCHAR Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
-	USHORT Ext_Point;    /* TW: Address of table entry in (older) BIOS image */
 	USHORT Ext_VESAID;
-	UCHAR Ext_VESAMEMSize;
 	UCHAR Ext_RESINFO;
 	UCHAR VB_ExtTVFlickerIndex;
 	UCHAR VB_ExtTVEdgeIndex;
@@ -506,96 +80,93 @@
 	UCHAR REFindex;
 } SiS310_ExtStruct;
 
-/* TW: Checked with 650/LVDS and 650/301LVx 1.10.6s */
 static const SiS310_ExtStruct  SiS310_EModeIDTable[]=
 {
-	{0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x? */
-	{0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x8 */
-/*	{0x2e,0x021b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},    */    /* 640x480x8 - 650/LVDS BIOS (no CRt2Mode) */
-	{0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},          /* 640x400x8 */
-/*	{0x2f,0x021b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},    */    /* 640x400x8 - 650/LVDS BIOS (no CRt2Mode) */
-	{0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x8 */
-/*	{0x30,0x221b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},    */    /* 800x600x8 - 650/LVDS BIOS (no CRt2Mode) */
-/*      {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},    */    /* 720x480x8 */
-        {0x31,0x0a1b,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x8 BIOS (301/LVDS) */
-	{0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x8 */
-	{0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x16 */
-	{0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x16 */
-	{0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x32 */
-	{0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x32 */
-	{0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x? */
-	{0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x8 */
-	{0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x8 */
-	{0x3c,0x0e3b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x8 */
-	{0x3d,0x0e7d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x16 - 650/301LVx - no CRT2Mode? */
-	{0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25},	   /* 320x200x15 */
-	{0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25},	   /* 320x200x16 */
-	{0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08},
-	{0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x16 */
-	{0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00},
-	{0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x16 */
-	{0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
-	{0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x16 */
-	{0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
-	{0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x16 */
-	{0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},	   /* 320x240x8  */
-	{0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},	   /* 400x300x8  */
-  	{0x52,0xba1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},          /* 512x384x8  */
-	{0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},	   /* 320x240x16 */
-	{0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27}, 	   /* 400x300x16 */
- 	{0x58,0xba1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28},          /* 512x384x16 */
-	{0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},	   /* 320x200x8  */
-	{0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f},          /* 320x480x8 fstn add new mode*/
-	{0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f},          /* 320x480x16 fstn add new mode*/
-	{0x5c,0xba1f,0x0204,0x3a49,0x0000,0x08,0x04,0x00,0x00,0x00,0x28},          /* TW: inserted 512x384x32 */
-	{0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10},
-	{0x5e,0x0a1f,0x0305,0x3a50,0x0000,0x08,0x05,0x00,0x00,0x07,0x10},          /* TW: Inserted 640x400x32 */
-	{0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x32 */
-	{0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x32 */
-	{0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x32 */
-	{0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x32 */
-	{0x66,0x0eff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x32 */
-	{0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x8 */
-	{0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x16 */
-	{0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x32 */
-	{0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x8 */
-	{0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x16 */
-	{0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x32 */
-	{0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x8 */
-	{0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},          /* 1024x576x8 */
-	{0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},          /* 1024x576x16 */
-	{0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x16 */
-	{0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x32 */
-	{0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},	   /* 1024x576x32 */
-	{0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x32 */
-	{0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x8 */
-	{0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x16 */
-	{0x7c,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x8 - TW */
-	{0x7d,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x16 - TW */
-	{0x7e,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x32 - TW */
-        /* TW: 650/LVDS BIOS new modes */
-	{0x23,0x0e3b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x8 */
-	{0x24,0x0e7d,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x16 */
-	{0x25,0x0eff,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x32 */
-	{0x26,0x0e3b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x8 */
-	{0x27,0x0e7d,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x16 */
-	{0x28,0x0eff,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x32*/
-	{0x29,0x0e1b,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},    /* TW: NEW 1152x864 - not in BIOS */
-	{0x2a,0x0e3d,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
-	{0x2b,0x0e7f,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
-	{0x39,0x2a1b,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},    /* TW: NEW 848x480 - not in BIOS */
-	{0x3b,0x2a3d,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
-	{0x3e,0x2a7f,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
-	{0x3f,0x2a1b,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},    /* TW: NEW 856x480 - not in BIOS */
-	{0x42,0x2a3d,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
-	{0x45,0x2a7f,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
-	{0x48,0x2a1b,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},    /* TW: NEW 1360x768 - not in BIOS */
-	{0x4b,0x2a3d,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
-	{0x4e,0x2a7f,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
-	{0x4f,0x9a1f,0x0000,0x0000,0x0000,0x08,0x00,0x00,0x00,0x04,0x25},	   /* TW: New 320x200x32 */
-	{0x53,0x9a1f,0x0001,0x0000,0x0000,0x08,0x01,0x00,0x00,0x04,0x26},	   /* TW: New 320x240x32 */
-	{0x54,0xba1f,0x0103,0x0000,0x0000,0x08,0x03,0x00,0x00,0x07,0x27}, 	   /* TW: New 400x300x32 */
-	{0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
+	{0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x? */
+	{0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x8 */
+        {0x2f,0x0a1b,0x0305,0x0100,SIS_RI_640x400,  0x00,0x00,0x05,0x10}, /* 640x400x8 */
+	{0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x8 */
+        {0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x8 */
+	{0x32,0x0a1b,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x8 */
+	{0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x16 */
+	{0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x16 */
+	{0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x32 */
+	{0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x32 */
+	{0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x? */
+	{0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x8 */
+	{0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
+	{0x3c,0x0e3b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */
+	{0x3d,0x0e7d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 */
+	{0x40,0x9a1c,0x0000,0x010d,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x15 */
+	{0x41,0x9a1d,0x0000,0x010e,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x16 */
+	{0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480,  0x00,0x00,0x05,0x08},
+	{0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x16 */
+	{0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600,  0x00,0x00,0x07,0x00},
+	{0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x16 */
+	{0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
+	{0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x16 */
+	{0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
+	{0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */
+	{0x50,0x9a1b,0x0001,0x0132,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x8  */
+	{0x51,0xba1b,0x0103,0x0133,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x8  */
+  	{0x52,0xba1b,0x0204,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x8  */
+	{0x56,0x9a1d,0x0001,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x16 */
+	{0x57,0xba1d,0x0103,0x0136,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x16 */
+ 	{0x58,0xba1d,0x0204,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x16 */
+	{0x59,0x9a1b,0x0000,0x0138,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x8  */
+	{0x5a,0x021b,0x0014,0x0138,SIS_RI_320x240,  0x00,0x00,0x04,0x3f}, /* 320x240x8  fstn */
+	{0x5b,0x0a1d,0x0014,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x3f}, /* 320x240x16 fstn */
+	{0x5c,0xba1f,0x0204,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x32 */
+	{0x5d,0x0a1d,0x0305,0x0139,SIS_RI_640x400,  0x00,0x00,0x07,0x10},
+	{0x5e,0x0a1f,0x0305,0x0000,SIS_RI_640x400,  0x00,0x00,0x07,0x10}, /* 640x400x32 */
+	{0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x32 */
+	{0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x32 */
+	{0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x32 */
+	{0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */
+	{0x66,0x0eff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */
+	{0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */
+	{0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */
+	{0x6b,0x07ff,0x080b,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */
+	{0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */
+	{0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */
+	{0x6e,0x07ff,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */
+	{0x70,0x2a1b,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x8 */
+	{0x71,0x0a1b,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x8 */
+	{0x74,0x0a1d,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x16 */
+	{0x75,0x0a3d,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x16 */
+	{0x76,0x2a1f,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x32 */
+	{0x77,0x0a1f,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x32 */
+	{0x78,0x0a3f,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x32 */
+	{0x79,0x0a3b,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x8 */
+	{0x7a,0x2a1d,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x16 */
+	{0x7c,0x0e3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x8 */
+	{0x7d,0x0e7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x16 */
+	{0x7e,0x0eff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x32 */
+	{0x23,0x0e3b,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x8 */
+	{0x24,0x0e7d,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x16 */
+	{0x25,0x0eff,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x32 */
+	{0x26,0x0e3b,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */
+	{0x27,0x0e7d,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */
+	{0x28,0x0eff,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/
+	{0x29,0x0e1b,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43}, /* 1152x864 */
+	{0x2a,0x0e3d,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43},
+	{0x2b,0x0e7f,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43},
+	{0x39,0x2a1b,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45}, /* 848x480 */
+	{0x3b,0x2a3d,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45},
+	{0x3e,0x2a7f,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45},
+	{0x3f,0x2a1b,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47}, /* 856x480 */
+	{0x42,0x2a3d,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47},
+	{0x45,0x2a7f,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47},
+	{0x48,0x2a1b,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49}, /* 1360x768 */
+	{0x4b,0x2a3d,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49},
+	{0x4e,0x2a7f,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49},
+	{0x4f,0x9a1f,0x0000,0x0000,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x32 */
+	{0x53,0x9a1f,0x0001,0x0000,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x32 */
+	{0x54,0xba1f,0x0103,0x0000,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x32 */
+	{0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x4a}, /* 768x576x8 */
+	{0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x4a}, /* 768x576x16 */
+	{0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x4a}, /* 768x576x32 */
+	{0xff,0x0000,0x0000,0x0000,0x00,            0x00,0x00,0x00,0x00}
 };
 
 typedef struct _SiS310_Ext2Struct
@@ -607,89 +178,87 @@
 	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
-	USHORT ROM_OFFSET;
 } SiS310_Ext2Struct;
 
 static const SiS310_Ext2Struct SiS310_RefIndex[]=
 {
-/*	{0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81},    0x0 - TW: Patch for Chrontel 7019  */
-	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */
-	{0x0467,0x0e,0x04,0x05,0x6a, 800, 600,0x3a86}, /* 0x1 */
-	{0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */
-	{0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */
-	{0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */
-	{0x0147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 - 4147 TW: Test sync change */
-	{0x0047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 - 4047 */
-	{0x0047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 - 4047 */
-/*	{0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57},    0x8 - TW: Patch for Chrontel 7019  */
-	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */
-	{0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */
-	{0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */
-	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */
-	{0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc - 4047 */
-	{0xc047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd - 4047 */
-	{0xc047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe - 4047 */
-	{0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */
-	{0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */
-	{0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */
-	{0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */
-	{0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */
-	{0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 */
-	{0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */
-	{0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */
-	{0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */
-	{0x0047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 - 4047 */
-	{0x0007,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 - 4047 */
-	{0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */
-	{0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */
-	{0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */
-	{0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */
-	{0x0027,0x20,0x21,0x09,0x3c,1600,1200,0x3af2}, /* 0x1e */
-	{0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */
-	{0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */
-	{0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */
-	{0x0007,0x24,0x26,0x00,0x3c,1600,1200,0x3b06}, /* 0x22 */
-	{0x0007,0x25,0x2c,0x00,0x3c,1600,1200,0x3b0b}, /* 0x23 */
-	{0x0007,0x26,0x34,0x00,0x3c,1600,1200,0x3b10}, /* 0x24 */
-	{0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3a34}, /* 0x25 */
-	{0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x3a3b}, /* 0x26 */
-	{0x007f,0x02,0x04,0x05,0x51, 400, 300,0x3a42}, /* 0x27 */
-	{0xc077,0x03,0x0b,0x06,0x52, 512, 384,0x3a49}, /* 0x28 */
-	{0x8007,0x27,0x27,0x00,0x68,1920,1440,0x3b17}, /* 0x29 */
-	{0x4007,0x28,0x29,0x00,0x68,1920,1440,0x3b1c}, /* 0x2a */
-	{0x4007,0x29,0x2e,0x00,0x68,1920,1440,0x3b21}, /* 0x2b */
-	{0x4007,0x2a,0x30,0x00,0x68,1920,1440,0x3b26}, /* 0x2c */
-	{0x4007,0x2b,0x35,0x00,0x68,1920,1440,0x3b2b}, /* 0x2d */
-	{0x4005,0x2c,0x39,0x00,0x68,1920,1440,0x3b30}, /* 0x2e */
-	{0x4007,0x2d,0x2b,0x00,0x6c,2048,1536,0x3b37}, /* 0x2f */
-	{0x4007,0x2e,0x31,0x00,0x6c,2048,1536,0x3b3c}, /* 0x30 */
-	{0x4007,0x2f,0x33,0x00,0x6c,2048,1536,0x3b41}, /* 0x31 */
-	{0x4007,0x30,0x37,0x00,0x6c,2048,1536,0x3b46}, /* 0x32 */
-	{0x4005,0x31,0x38,0x00,0x6c,2048,1536,0x3b4b}, /* 0x33 */
-	{0x0057,0x32,0x40,0x08,0x70, 800, 480,0x3b52}, /* 0x34 */
-	{0x0047,0x33,0x07,0x08,0x70, 800, 480,0x3b57}, /* 0x35 */
-	{0x0047,0x34,0x0a,0x08,0x70, 800, 480,0x3b5c}, /* 0x36 */
-	{0x0057,0x35,0x0b,0x09,0x71,1024, 576,0x3b63}, /* 0x37 */
-	{0x0047,0x36,0x11,0x09,0x71,1024, 576,0x3b68}, /* 0x38 */
-	{0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */
-	{0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */
-	{0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */
-	{0x0007,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
-	{0x0067,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3d */
-	{0x0027,0x4c,0x59,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3e */
-	{0xc07f,0x01,0x00,0x06,0x5a, 320, 480,0x3b83}, /* 0x3f */    /* FSTN mode */
-        {0x0077,0x42,0x5b,0x08,0x23,1280, 768,0x0000}, /* 0x40 */    /* TW: 0x5b was 0x12 */
-	{0x0067,0x43,0x4d,0x08,0x26,1400,1050,0x0000}, /* 0x41 */  
-	{0x0007,0x4b,0x5a,0x08,0x26,1400,1050,0x0000}, /* 0x42 */    /* TW: new, not in any BIOS */
-	{0x0047,0x44,0x19,0x00,0x29,1152, 864,0x0000}, /* 0x43 TW: Non-BIOS, new */
-	{0x0047,0x4a,0x1e,0x00,0x29,1152, 864,0x0000}, /* 0x44 TW: Non-BIOS, new */
-	{0x00c7,0x45,0x57,0x00,0x39, 848, 480,0x0000}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
-	{0xc047,0x46,0x55,0x00,0x39, 848, 480,0x0000}, /* 0x46 TW: 848x480-60Hz  - Non-BIOS, new */
-	{0x00c7,0x47,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
-	{0xc047,0x48,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x48 TW: 856x480-60Hz  - Non-BIOS, new */
-	{0x0047,0x49,0x58,0x00,0x48,1360, 768,0x0000}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
-	{0xffff,0x00,0x00,0x00,0x00,   0,   0,0x0000}
-}; 
+	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 0x0 */
+	{0x0467,0x0e,0x04,0x05,0x6a, 800, 600}, /* 0x1 */
+	{0x0067,0x0f,0x08,0x48,0x6a, 800, 600}, /* 0x2 */
+	{0x0067,0x10,0x07,0x8b,0x6a, 800, 600}, /* 0x3 */
+	{0x0147,0x11,0x0a,0x00,0x6a, 800, 600}, /* 0x4 */
+	{0x0147,0x12,0x0d,0x00,0x6a, 800, 600}, /* 0x5 - TW: Test sync change */
+	{0x0047,0x13,0x13,0x00,0x6a, 800, 600}, /* 0x6 */
+	{0x0047,0x14,0x1c,0x00,0x6a, 800, 600}, /* 0x7 */
+	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 0x8 */
+	{0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 0x9 */
+	{0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0xa */
+	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0xb */
+	{0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0xc */
+	{0xc047,0x0a,0x09,0x00,0x2e, 640, 480}, /* 0xd */
+	{0xc047,0x0b,0x0e,0x00,0x2e, 640, 480}, /* 0xe */
+	{0xc047,0x0c,0x15,0x00,0x2e, 640, 480}, /* 0xf */
+	{0x407f,0x04,0x00,0x00,0x2f, 640, 400}, /* 0x10 */
+	{0xc00f,0x3c,0x01,0x06,0x31, 720, 480}, /* 0x11 */
+	{0x000f,0x3d,0x03,0x06,0x32, 720, 576}, /* 0x12 */
+	{0x0187,0x15,0x06,0x00,0x37,1024, 768}, /* 0x13 */
+	{0xc877,0x16,0x0b,0x06,0x37,1024, 768}, /* 0x14 */
+	{0xc067,0x17,0x0f,0x49,0x37,1024, 768}, /* 0x15 */
+	{0x0267,0x18,0x11,0x00,0x37,1024, 768}, /* 0x16 */
+	{0x0047,0x19,0x16,0x8c,0x37,1024, 768}, /* 0x17 */
+	{0x0047,0x1a,0x1b,0x00,0x37,1024, 768}, /* 0x18 */
+	{0x0007,0x1b,0x1f,0x00,0x37,1024, 768}, /* 0x19 */
+	{0x0387,0x1c,0x11,0x00,0x3a,1280,1024}, /* 0x1a */
+	{0x0077,0x1d,0x19,0x07,0x3a,1280,1024}, /* 0x1b */
+	{0x0047,0x1e,0x1e,0x00,0x3a,1280,1024}, /* 0x1c */
+	{0x0007,0x1f,0x20,0x00,0x3a,1280,1024}, /* 0x1d */
+	{0x0867,0x20,0x21,0x09,0x3c,1600,1200}, /* 0x1e */
+	{0x0007,0x21,0x22,0x00,0x3c,1600,1200}, /* 0x1f */
+	{0x0007,0x22,0x23,0x00,0x3c,1600,1200}, /* 0x20 */
+	{0x0007,0x23,0x25,0x00,0x3c,1600,1200}, /* 0x21 */
+	{0x0007,0x24,0x26,0x00,0x3c,1600,1200}, /* 0x22 */
+	{0x0007,0x25,0x2c,0x00,0x3c,1600,1200}, /* 0x23 */
+	{0x0007,0x26,0x34,0x00,0x3c,1600,1200}, /* 0x24 */
+	{0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 0x25 */
+	{0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 0x26 */
+	{0x007f,0x02,0x04,0x05,0x51, 400, 300}, /* 0x27 */
+	{0xc077,0x03,0x0b,0x06,0x52, 512, 384}, /* 0x28 */
+	{0x8007,0x27,0x27,0x00,0x68,1920,1440}, /* 0x29 */
+	{0x4007,0x28,0x29,0x00,0x68,1920,1440}, /* 0x2a */
+	{0x4007,0x29,0x2e,0x00,0x68,1920,1440}, /* 0x2b */
+	{0x4007,0x2a,0x30,0x00,0x68,1920,1440}, /* 0x2c */
+	{0x4007,0x2b,0x35,0x00,0x68,1920,1440}, /* 0x2d */
+	{0x4005,0x2c,0x39,0x00,0x68,1920,1440}, /* 0x2e */
+	{0x4007,0x2d,0x2b,0x00,0x6c,2048,1536}, /* 0x2f */
+	{0x4007,0x2e,0x31,0x00,0x6c,2048,1536}, /* 0x30 */
+	{0x4007,0x2f,0x33,0x00,0x6c,2048,1536}, /* 0x31 */
+	{0x4007,0x30,0x37,0x00,0x6c,2048,1536}, /* 0x32 */
+	{0x4005,0x31,0x38,0x00,0x6c,2048,1536}, /* 0x33 */
+	{0x0057,0x32,0x40,0x08,0x70, 800, 480}, /* 0x34 */
+	{0x0047,0x33,0x07,0x08,0x70, 800, 480}, /* 0x35 */
+	{0x0047,0x34,0x0a,0x08,0x70, 800, 480}, /* 0x36 */
+	{0x0057,0x35,0x0b,0x09,0x71,1024, 576}, /* 0x37 */
+	{0x0047,0x36,0x11,0x09,0x71,1024, 576}, /* 0x38 */
+	{0x0047,0x37,0x16,0x09,0x71,1024, 576}, /* 0x39 */
+	{0x0057,0x38,0x19,0x0a,0x75,1280, 720}, /* 0x3a */
+	{0x0047,0x39,0x1e,0x0a,0x75,1280, 720}, /* 0x3b */
+	{0x0007,0x3a,0x20,0x0a,0x75,1280, 720}, /* 0x3c */
+	{0x0067,0x3b,0x19,0x08,0x7c,1280, 960}, /* 0x3d */
+	{0x0027,0x4c,0x59,0x08,0x7c,1280, 960}, /* 0x3e */
+	{0xc07f,0x4e,0x00,0x06,0x5a, 320, 240}, /* 0x3f */    /* FSTN 320x240 */
+        {0x0077,0x42,0x5b,0x08,0x23,1280, 768}, /* 0x40 */    /* TW: 0x5b was 0x12 */
+	{0x0067,0x43,0x4d,0x08,0x26,1400,1050}, /* 0x41 */
+	{0x0007,0x4b,0x5a,0x08,0x26,1400,1050}, /* 0x42 TW: not in any BIOS */
+	{0x0047,0x44,0x19,0x00,0x29,1152, 864}, /* 0x43 TW: Non-BIOS, new */
+	{0x0047,0x4a,0x1e,0x00,0x29,1152, 864}, /* 0x44 TW: Non-BIOS, new */
+	{0x00c7,0x45,0x57,0x00,0x39, 848, 480}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
+	{0xc047,0x46,0x55,0x00,0x39, 848, 480}, /* 0x46 TW: 848x480-60Hz  - Non-BIOS, new */
+	{0x00c7,0x47,0x57,0x00,0x3f, 856, 480}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
+	{0xc047,0x48,0x57,0x00,0x3f, 856, 480}, /* 0x48 TW: 856x480-60Hz  - Non-BIOS, new */
+	{0x0047,0x49,0x58,0x00,0x48,1360, 768}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
+	{0x000f,0x4d,0x03,0x06,0x5f, 768, 576}, /* 0x4a TW: 768x576 */
+	{0xffff,0x00,0x00,0x00,0x00,   0,   0}
+};
 
 typedef struct _SiS310_CRT1TableStruct
 {
@@ -713,7 +282,7 @@
  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
    0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
    0x00}}, /* 0x4 */
-#if 0   
+#if 0
  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
    0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
    0x00}}, /* 0x5 */
@@ -943,19 +512,25 @@
    0x00}},  /* 0x4b */ 
  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85, not in any BIOS */
    0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
-   0x01}}   /* 0x4c */
+   0x01}},  /* 0x4c */
+ {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
+   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
+   0x01}},  /* 0x4d */
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */
+   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}   /* 0x4e */
 };
 
-
 typedef struct _SiS310_MCLKDataStruct
 {
 	UCHAR SR28,SR29,SR2A;
 	USHORT CLOCK;
 } SiS310_MCLKDataStruct;
 
+#ifdef LINUXBIOS
 static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
 {
-	{ 0x3b,0x22,0x01,143},   /* TW: Was { 0x5c,0x23,0x01,166}, */
+	{ 0x3b,0x22,0x01,143},
 	{ 0x5c,0x23,0x01,166},
 	{ 0x5c,0x23,0x01,166},
 	{ 0x5c,0x23,0x01,166},
@@ -965,7 +540,7 @@
 	{ 0x5c,0x23,0x01,166}
 };
 
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =	/* @ 0x54 */
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =
 {
 	{ 0x5a,0x64,0x82, 66},
 	{ 0xb3,0x45,0x82, 83},
@@ -976,8 +551,22 @@
 	{ 0x37,0x22,0x82,133},
 	{ 0x37,0x22,0x82,133}
 };
+#endif
+
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =
+{
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x79,0x06,0x01,250},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x79,0x06,0x01,250}
+};
 
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =   /* @ 0x54 */
+#ifdef LINUXBIOS
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_660[] =  /* TODO */
 {
 	{ 0x5c,0x23,0x01,166},
 	{ 0x5c,0x23,0x01,166},
@@ -988,8 +577,9 @@
 	{ 0x7c,0x08,0x01,200},
 	{ 0x79,0x06,0x01,250}
 };
+#endif
 
-static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =	/* @ 0x155 */
+static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =
 {
         { 0x29,0x21,0x82,150},
 	{ 0x5c,0x23,0x82,166},
@@ -1001,6 +591,7 @@
 	{ 0x37,0x22,0x82,133}
 };
 
+#ifdef LINUXBIOS
 typedef struct _SiS310_ECLKDataStruct
 {
  	UCHAR SR2E,SR2F,SR30;
@@ -1014,6 +605,7 @@
 	{ 0x5c,0x23,0x01,166},
 	{ 0x5c,0x23,0x01,166}
 };
+#endif
 
 typedef struct _SiS310_VCLKDataStruct
 {
@@ -1023,22 +615,22 @@
 
 static const SiS310_VCLKDataStruct SiS310_VCLKData[]=
 {
-	{ 0x1b,0xe1, 25}, /* 0x0 */   /* 650/LVDS BIOS: @ 0x5647 */
-	{ 0x4e,0xe4, 28}, /* 0x1 */
-	{ 0x57,0xe4, 31}, /* 0x2 */
-	{ 0xc3,0xc8, 36}, /* 0x3 */
-	{ 0x42,0xe2, 40}, /* 0x4 */
-	{ 0xfe,0xcd, 43}, /* 0x5 */
-	{ 0x5d,0xc4, 44}, /* 0x6 */
-	{ 0x52,0xe2, 49}, /* 0x7 */
-	{ 0x53,0xe2, 50}, /* 0x8 */
-	{ 0x74,0x67, 52}, /* 0x9 */
-	{ 0x6d,0x66, 56}, /* 0xa */
-	{ 0x5a,0x64, 65}, /* 0xb */   /* TW: was 6c c3 - WRONG */
-	{ 0x46,0x44, 67}, /* 0xc */
-	{ 0xb1,0x46, 68}, /* 0xd */
-	{ 0xd3,0x4a, 72}, /* 0xe */
-	{ 0x29,0x61, 75}, /* 0xf */
+	{ 0x1b,0xe1, 25}, /* 0x00 */
+	{ 0x4e,0xe4, 28}, /* 0x01 */
+	{ 0x57,0xe4, 31}, /* 0x02 */
+	{ 0xc3,0xc8, 36}, /* 0x03 */
+	{ 0x42,0xe2, 40}, /* 0x04 */
+	{ 0xfe,0xcd, 43}, /* 0x05 */
+	{ 0x5d,0xc4, 44}, /* 0x06 */
+	{ 0x52,0xe2, 49}, /* 0x07 */
+	{ 0x53,0xe2, 50}, /* 0x08 */
+	{ 0x74,0x67, 52}, /* 0x09 */
+	{ 0x6d,0x66, 56}, /* 0x0a */
+	{ 0x5a,0x64, 65}, /* 0x0b */  /* TW: was 6c c3 - WRONG */
+	{ 0x46,0x44, 67}, /* 0x0c */
+	{ 0xb1,0x46, 68}, /* 0x0d */
+	{ 0xd3,0x4a, 72}, /* 0x0e */
+	{ 0x29,0x61, 75}, /* 0x0f */
 	{ 0x6e,0x46, 76}, /* 0x10 */
 	{ 0x2b,0x61, 78}, /* 0x11 */
 	{ 0x31,0x42, 79}, /* 0x12 */
@@ -1048,7 +640,7 @@
 	{ 0x62,0x44, 94}, /* 0x16 */
 	{ 0x2b,0x41,104}, /* 0x17 */
 	{ 0x3a,0x23,105}, /* 0x18 */
-	{ 0x70,0x44,108}, /* 0x19 */
+	{ 0x70,0x44,108}, /* 0x19 */  /* 1400x1050 LCD */
 	{ 0x3c,0x23,109}, /* 0x1a */
 	{ 0x5e,0x43,113}, /* 0x1b */
 	{ 0xbc,0x44,116}, /* 0x1c */
@@ -1081,12 +673,12 @@
 	{ 0xea,0x08,340}, /* 0x37 */
 	{ 0xe8,0x07,376}, /* 0x38 */
 	{ 0xde,0x06,389}, /* 0x39 */
-	{ 0x52,0x2a, 54}, /* 0x3a */
-	{ 0x52,0x6a, 27}, /* 0x3b */
-	{ 0x62,0x24, 70}, /* 0x3c */
-	{ 0x62,0x64, 70}, /* 0x3d */
-	{ 0xa8,0x4c, 30}, /* 0x3e */
-	{ 0x20,0x26, 33}, /* 0x3f */
+	{ 0x52,0x2a, 54}, /* 0x3a */  /* 301 TV */
+	{ 0x52,0x6a, 27}, /* 0x3b */  /* 301 TV */
+	{ 0x62,0x24, 70}, /* 0x3c */  /* 301 TV */
+	{ 0x62,0x64, 70}, /* 0x3d */  /* 301 TV */
+	{ 0xa8,0x4c, 30}, /* 0x3e */  /* 301 TV */
+	{ 0x20,0x26, 33}, /* 0x3f */  /* 301 TV */
 	{ 0x31,0xc2, 39}, /* 0x40 */
 	{ 0x60,0x36, 30}, /* 0x41 */  /* Chrontel */
 	{ 0x40,0x4a, 28}, /* 0x42 */  /* Chrontel */
@@ -1099,7 +691,7 @@
 	{ 0xce,0x3c, 39}, /* 0x49 */
 	{ 0x52,0x4a, 36}, /* 0x4a */  /* Chrontel */
 	{ 0x34,0x61, 95}, /* 0x4b */
-	{ 0x78,0x27,108}, /* 0x4c - was 102 */  /* TW: Last entry in 650/301 BIOS */
+	{ 0x78,0x27,108}, /* 0x4c - was 102 */
 	{ 0x66,0x43,123}, /* 0x4d */  /* Modes 0x26-0x28 (1400x1050) */
 	{ 0x41,0x4e, 21}, /* 0x4e */
 	{ 0xa1,0x4a, 29}, /* 0x4f */  /* Chrontel */
@@ -1114,7 +706,7 @@
 	{ 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) */
 	{ 0x52,0x07,149}, /* 0x59 - added for 1280x960-85 (Not in any BIOS) */
 	{ 0x56,0x07,156}, /* 0x5a - added for 1400x1050-75 */
-	{ 0x7a,0x2a, 81}  /* 0x5b */  /* For 1280x768 LCD mode */
+   	{ 0x70,0x29, 81}  /* 0x5b */  /* 1280x768 LCD */
 };
 
 typedef struct _SiS310_VBVCLKDataStruct
@@ -1125,22 +717,22 @@
 
 static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
 {
-	{ 0x1b,0xe1, 25}, /* 0x0 */   
-	{ 0x4e,0xe4, 28}, /* 0x1 */
-	{ 0x57,0xe4, 31}, /* 0x2 */
-	{ 0xc3,0xc8, 36}, /* 0x3 */
-	{ 0x42,0x47, 40}, /* 0x4 */
-	{ 0xfe,0xcd, 43}, /* 0x5 */
-	{ 0x5d,0xc4, 44}, /* 0x6 */
-	{ 0x52,0x47, 49}, /* 0x7 */
-	{ 0x53,0x47, 50}, /* 0x8 */
-	{ 0x74,0x67, 52}, /* 0x9 */
-	{ 0x6d,0x66, 56}, /* 0xa */
-	{ 0x35,0x62, 65}, /* 0xb */  /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62  */
-	{ 0x46,0x44, 67}, /* 0xc */
-	{ 0xb1,0x46, 68}, /* 0xd */
-	{ 0xd3,0x4a, 72}, /* 0xe */
-	{ 0x29,0x61, 75}, /* 0xf */
+	{ 0x1b,0xe1, 25}, /* 0x00 */
+	{ 0x4e,0xe4, 28}, /* 0x01 */
+	{ 0x57,0xe4, 31}, /* 0x02 */
+	{ 0xc3,0xc8, 36}, /* 0x03 */
+	{ 0x42,0x47, 40}, /* 0x04 */
+	{ 0xfe,0xcd, 43}, /* 0x05 */
+	{ 0x5d,0xc4, 44}, /* 0x06 */
+	{ 0x52,0x47, 49}, /* 0x07 */
+	{ 0x53,0x47, 50}, /* 0x08 */
+	{ 0x74,0x67, 52}, /* 0x09 */
+	{ 0x6d,0x66, 56}, /* 0x0a */
+	{ 0x35,0x62, 65}, /* 0x0b */  /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62  */
+	{ 0x46,0x44, 67}, /* 0x0c */
+	{ 0xb1,0x46, 68}, /* 0x0d */
+	{ 0xd3,0x4a, 72}, /* 0x0e */
+	{ 0x29,0x61, 75}, /* 0x0f */
 	{ 0x6d,0x46, 75}, /* 0x10 */
 	{ 0x41,0x43, 78}, /* 0x11 */
 	{ 0x31,0x42, 79}, /* 0x12 */
@@ -1150,7 +742,7 @@
 	{ 0x62,0x44, 94}, /* 0x16 */
 	{ 0x2b,0x22,104}, /* 0x17 */
 	{ 0x49,0x24,105}, /* 0x18 */
-	{ 0xf8,0x2f,108}, /* 0x19 */
+	{ 0xf8,0x2f,108}, /* 0x19 */  /* 1400x1050 LCD */
 	{ 0x3c,0x23,109}, /* 0x1a */
 	{ 0x5e,0x43,113}, /* 0x1b */
 	{ 0xbc,0x44,116}, /* 0x1c */
@@ -1183,19 +775,19 @@
 	{ 0xea,0x08,340}, /* 0x37 */
 	{ 0xe8,0x07,376}, /* 0x38 */
 	{ 0xde,0x06,389}, /* 0x39 */
-	{ 0x52,0x2a, 54}, /* 0x3a */
-	{ 0x52,0x6a, 27}, /* 0x3b */
-	{ 0x62,0x24, 70}, /* 0x3c */
-	{ 0x62,0x64, 70}, /* 0x3d */
-	{ 0xa8,0x4c, 30}, /* 0x3e */
-	{ 0x20,0x26, 33}, /* 0x3f */
+	{ 0x52,0x2a, 54}, /* 0x3a */  /* 301 TV */
+	{ 0x52,0x6a, 27}, /* 0x3b */  /* 301 TV */
+	{ 0x62,0x24, 70}, /* 0x3c */  /* 301 TV */
+	{ 0x62,0x64, 70}, /* 0x3d */  /* 301 TV */
+	{ 0xa8,0x4c, 30}, /* 0x3e */  /* 301 TV */
+	{ 0x20,0x26, 33}, /* 0x3f */  /* 301 TV */
 	{ 0x31,0xc2, 39}, /* 0x40 */
-	{ 0x2e,0x48, 25}, /* 0x41 */
-	{ 0x24,0x46, 25}, /* 0x42 */
-	{ 0x26,0x64, 28}, /* 0x43 */
-	{ 0x37,0x64, 40}, /* 0x44 */
-	{ 0xa1,0x42,108}, /* 0x45 */
-	{ 0x37,0x61,100}, /* 0x46 */
+	{ 0x2e,0x48, 25}, /* 0x41 */  /* Replacement for LCD on 315 for index 0 */
+	{ 0x24,0x46, 25}, /* 0x42 */  /* Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */
+	{ 0x26,0x64, 28}, /* 0x43 */  /* Replacement for LCD on 315 for index 1 */
+	{ 0x37,0x64, 40}, /* 0x44 */  /* Replacement for LCD on 315 for index 4 */
+	{ 0xa1,0x42,108}, /* 0x45 */  /* 1280x960 LCD */
+	{ 0x37,0x61,100}, /* 0x46 */  /* 1280x960 LCD */
 	{ 0x78,0x27,108}, /* 0x47 */
 	{ 0x97,0x2c, 26}, /* 0x48 */  /* UNUSED - Entries from here new, not in any BIOS */
 	{ 0xce,0x3c, 39}, /* 0x49 */  /* UNUSED */
@@ -1216,72 +808,16 @@
 	{ 0x30,0x23, 88}, /* 0x58 */  /* 1360x768-62 (is 60Hz!) TEMP, UNUSED */
 	{ 0x52,0x07,149}, /* 0x59 */  /* 1280x960-85  - UNUSED */
 	{ 0x56,0x07,156}, /* 0x5a */  /* 1400x1050-75 - UNUSED */
-	{ 0x7a,0x2a, 81}  /* 0x5b */  /* For 1280x768 LCD mode */
+   	{ 0x70,0x29, 81}  /* 0x5b */  /* 1280x768 LCD */
 };
 
 static const UCHAR SiS310_ScreenOffset[] = 
 {
         0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,
-	0x78,0x80,0x2d,0x35,0x57,0x48,0x55,
+	0x78,0x80,0x2d,0x35,0x57,0x48,0x55,0x30,
 	0xff
-};      /* TW: Added 1400x1050, 1152x864, 848/856x480, 1360x768 */
-
-typedef struct _SiS310_StResInfoStruct
-{
-	USHORT HTotal;
-	USHORT VTotal;
-} SiS310_StResInfoStruct;
-
-static const SiS310_StResInfoStruct SiS310_StResInfo[]=
-{
-	{ 640,400},
-	{ 640,350},
-	{ 720,400},
-	{ 720,350},
-	{ 640,480}
-};
-
-typedef struct _SiS310_ModeResInfoStruct
-{
-	USHORT HTotal;
-	USHORT VTotal;
-	UCHAR  XChar;
-	UCHAR  YChar;
-} SiS310_ModeResInfoStruct;
-
-static const SiS310_ModeResInfoStruct SiS310_ModeResInfo[] =
-{
-	{  320, 200, 8, 8},   /* 0x00 */
-	{  320, 240, 8, 8},   /* 0x01 */
-	{  320, 400, 8, 8},   /* 0x02 */
-	{  400, 300, 8, 8},   /* 0x03 */
-	{  512, 384, 8, 8},   /* 0x04 */
-	{  640, 400, 8,16},   /* 0x05 */
-	{  640, 480, 8,16},   /* 0x06 */
-	{  800, 600, 8,16},   /* 0x07 */
-	{ 1024, 768, 8,16},   /* 0x08 */
-	{ 1280,1024, 8,16},   /* 0x09 */
-	{ 1600,1200, 8,16},   /* 0x0a */
-	{ 1920,1440, 8,16},   /* 0x0b */
-	{ 2048,1536, 8,16},   /* 0x0c */
-	{  720, 480, 8,16},   /* 0x0d */
-	{  720, 576, 8,16},   /* 0x0e */
-	{ 1280, 960, 8,16},   /* 0x0f */
-	{  800, 480, 8,16},   /* 0x10 */
-	{ 1024, 576, 8,16},   /* 0x11 */
-	{ 1280, 720, 8,16},   /* 0x12 */
-	{  856, 480, 8,16},   /* 0x13 - TW: New, not in any BIOS */
-	{ 1280, 768, 8,16},   /* 0x14 20; TW: New */
-	{ 1400,1050, 8,16},   /* 0x15 21; TW: New */
-	{ 1152, 864, 8,16},   /* 0x16 - TW: New, not in any BIOS */
-	{  848, 480, 8,16},   /* 0x17 - TW: New, not in any BIOS */
-	{ 1360, 768, 8,16}    /* 0x18 - TW: New, not in any BIOS */
 };
 
-static const UCHAR SiS310_OutputSelect = 0x40;
-
-static const UCHAR SiS310_SoftSetting  = 0x30;   /* TW: RAM setting */
-
 static const UCHAR SiS310_SR15[8][4]={
 	{0x00,0x04,0x60,0x60},
 	{0x0f,0x0f,0x0f,0x0f},
@@ -1327,16 +863,6 @@
 static const USHORT SiS310_YCSenseData2    = 0x016b;
 #endif
 
-static const UCHAR SiS310_NTSCPhase[]    = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
-static const UCHAR SiS310_PALPhase[]     = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00}; */
-static const UCHAR SiS310_PALMPhase[]    = {0x21,0xE4,0x2E,0x9B};  /* TW: palm*/
-static const UCHAR SiS310_PALNPhase[]    = {0x21,0xF4,0x3E,0xBA};  /* TW: paln*/
-static const UCHAR SiS310_NTSCPhase2[]   = {0x21,0xF0,0x7B,0xD6};
-static const UCHAR SiS310_PALPhase2[]    = {0x2a,0x09,0x86,0xe9};
-static const UCHAR SiS310_PALMPhase2[]   = {0x21,0xE6,0xEF,0xA4};  /* TW: palm 301b*/
-static const UCHAR SiS310_PALNPhase2[]   = {0x21,0xF6,0x94,0x46};  /* TW: paln 301b*/
-static const UCHAR SiS310_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
-
 typedef struct _SiS310_LCDDataStruct
 {
 	USHORT RVBHCMAX;
@@ -1358,25 +884,6 @@
 	{    1,   1,1344, 806,1344, 806}
 };
 
-#if 0   /* Seems out-dated, all BIOSes since 03/27/2002 have the other version */
-static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] = 
-{
-	{   12,   5, 896, 512,1344, 806},
-	{   12,   5, 896, 510,1344, 806},
-	{   32,  15,1008, 505,1344, 806},
-	{   32,  15,1008, 514,1344, 806},
-	{   12,   5, 896, 500,1344, 806},
-	{   42,  25,1024, 625,1344, 806},
-	{    1,   1,1344, 806,1344, 806},
-	{   12,   5, 896, 500,1344, 806},
-	{   42,  25,1024, 625,1344, 806},
-	{    1,   1,1344, 806,1344, 806},
-	{   12,   5, 896, 500,1344, 806},
-	{   42,  25,1024, 625,1344, 806},
-	{    1,   1,1344, 806,1344, 806}
-};
-#endif
-
 static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =   
 {
 	{   42,  25,1536, 419,1344, 806},
@@ -1468,335 +975,14 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS310_LCDDataStruct  SiS310_LCD1280x960Data[] =
-{
-	{    9,   2, 800, 500,1800,1000},
-	{    9,   2, 800, 500,1800,1000},
-	{    4,   1, 900, 500,1800,1000},
-	{    4,   1, 900, 500,1800,1000},
-	{    9,   2, 800, 500,1800,1000},
-	{   30,  11,1056, 625,1800,1000},
-	{    5,   3,1350, 800,1800,1000},
-	{    1,   1,1576,1050,1576,1050},
-	{    1,   1,1800,1000,1800,1000}
-};
-
-static const SiS310_LCDDataStruct  SiS310_StLCD1400x1050Data[] =
-{  /* TW: New from 1.11.6s */
-	{ 211,  100, 2100,  408, 1688, 1066 },
-	{ 211,   64, 1536,  358, 1688, 1066 },
-	{ 211,  100, 2100,  408, 1688, 1066 },
-	{ 211,   64, 1536,  358, 1688, 1066 },
-	{ 211,   48,  840,  488, 1688, 1066 },
-	{ 211,   72, 1008,  609, 1688, 1066 },
-	{ 211,  128, 1400,  776, 1688, 1066 },
-	{ 211,  205, 1680, 1041, 1688, 1066 },
-	{   1,    1, 1688, 1066, 1688, 1066 }
-};
-
-static const SiS310_LCDDataStruct  SiS310_ExtLCD1400x1050Data[] =
-{  /* TW: New from 1.11.6s */
-	{ 211,  100, 2100,  408, 1688, 1066 },
-	{ 211,   64, 1536,  358, 1688, 1066 },
-	{ 211,  100, 2100,  408, 1688, 1066 },
-	{ 211,   64, 1536,  358, 1688, 1066 },
-	{ 211,   48,  840,  488, 1688, 1066 },
-	{ 211,   72, 1008,  609, 1688, 1066 },
-	{ 211,  128, 1400,  776, 1688, 1066 },
-	{ 211,  205, 1680, 1041, 1688, 1066 },
-	{   1,    1, 1688, 1066, 1688, 1066 }
-};
-
-static const SiS310_LCDDataStruct  SiS310_NoScaleData1400x1050[] =
-{  /* TW: To be checked (BIOS uses 1280x1024 data, one line too short) */
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 }
-};
-
-static const SiS310_LCDDataStruct  SiS310_StLCD1600x1200Data[] =
-{  /* TODO */
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS310_LCDDataStruct  SiS310_ExtLCD1600x1200Data[] = 
-{  /* TODO */
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS310_LCDDataStruct  SiS310_NoScaleData1600x1200[] = 
-{  /* TODO - values guessed */
-        {1,  1, 2048, 1250, 2048, 1250},
-	{1,  1, 2048, 1250, 2048, 1250},
-	{1,  1, 2048, 1250, 2048, 1250},
-	{1,  1, 2048, 1250, 2048, 1250},
-	{1,  1, 2048, 1250, 2048, 1250},
-	{1,  1, 2048, 1250, 2048, 1250},
-	{1,  1, 2048, 1250, 2048, 1250},
-	{1,  1, 2048, 1250, 2048, 1250},
-	{1,  1, 2048, 1250, 2048, 1250},
-	{1,  1, 2048, 1250, 2048, 1250}
-};
-
-static const SiS310_LCDDataStruct  SiS310_StLCD1280x768Data[] =
-{
-	{ 211,  100, 2100,  408, 1408,  806 }, /* These values are *wrong* */
-	{ 211,   64, 1536,  358, 1408,  806 },
-	{ 211,  100, 2100,  408, 1408,  806 },
-	{ 211,   64, 1536,  358, 1408,  806 },
-	{ 211,   48,  840,  488, 1408,  806 },
-	{ 211,   72, 1008,  609, 1408,  806 },
-	{ 211,  128, 1400,  776, 1408,  806 },
-	{ 211,  205, 1680, 1041, 1408,  806 },
-	{ 1,      1, 1408,  806, 1408,  806 }  /* That's the only one that *might* be correct */
-};
-
-static const SiS310_LCDDataStruct  SiS310_ExtLCD1280x768Data[] =
-{
-	{ 211,  100, 2100,  408, 1408,  806 }, /* These values are *wrong* */
-	{ 211,   64, 1536,  358, 1408,  806 },
-	{ 211,  100, 2100,  408, 1408,  806 },
-	{ 211,   64, 1536,  358, 1408,  806 },
-	{ 211,   48,  840,  488, 1408,  806 },
-	{ 211,   72, 1008,  609, 1408,  806 },
-	{ 211,  128, 1400,  776, 1408,  806 },
-	{ 211,  205, 1680, 1041, 1408,  806 },
-	{ 1,      1, 1408,  806, 1408,  806 }  /* That's the only one that *might* be correct */
-};
-
-static const SiS310_LCDDataStruct  SiS310_NoScaleData1280x768[] =
-{  /* All values guessed */
-        { 1, 1, 1408,  806, 1408,  806},
-	{ 1, 1, 1408,  806, 1408,  806},
-	{ 1, 1, 1408,  806, 1408,  806},
-	{ 1, 1, 1408,  806, 1408,  806},
-	{ 1, 1, 1408,  806, 1408,  806},
-	{ 1, 1, 1408,  806, 1408,  806},
-	{ 1, 1, 1408,  806, 1408,  806},
-	{ 1, 1, 1408,  806, 1408,  806},
-	{ 1, 1, 1408,  806, 1408,  806}
-};
-
-static const SiS310_LCDDataStruct  SiS310_NoScaleData[] =
-{
-	{ 1, 1, 800, 449, 800, 449 },
-	{ 1, 1, 800, 449, 800, 449 },
-	{ 1, 1, 900, 449, 900, 449 },
-	{ 1, 1, 900, 449, 900, 449 },
-	{ 1, 1, 800, 525, 800, 525 },
-	{ 1, 1,1056, 628,1056, 628 },
-	{ 1, 1,1344, 806,1344, 806 },
-	{ 1, 1,1688,1066,1688,1066 },
-	{ 1, 1,1688, 791,1688, 791 },  /* 1280x768: 791 was 860 in both cases */
-        { 1, 1,2048,1250,2048,1250 },  /* 1600x1200 (guessed) */
-	{ 1, 1,1800,1000,1800,1000 }   /* 1280x960 */
-};
-
-typedef struct _SiS310_TVDataStruct
-{
-	USHORT RVBHCMAX;
-	USHORT RVBHCFACT;
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT TVHDE;
-	USHORT TVVDE;
-	USHORT RVBHRS;
-	UCHAR FlickerMode;
-	USHORT HALFRVBHRS;
-	UCHAR RY1COE;
-	UCHAR RY2COE;
-	UCHAR RY3COE;
-	UCHAR RY4COE;
-} SiS310_TVDataStruct;
-
-static const SiS310_TVDataStruct  SiS310_StPALData[]=
-{
- {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
- {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
- {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
-};
-
-static const SiS310_TVDataStruct  SiS310_ExtPALData[] =   
-{
- {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
- {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
- {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
- {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
- {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},  /* 640x480 */
- {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},  /* 800x600 */
- {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},  /* 720x480/576 */
- {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}   /* 1024x768 */
-};
-
-static const SiS310_TVDataStruct  SiS310_StNTSCData[]=
-{
- {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
- {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
-};
-
-static const SiS310_TVDataStruct  SiS310_ExtNTSCData[]=
-{
- {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
- {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
- {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
- {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
- {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},  /* 640x480 */
- {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},  /* 800x600  */
- {    2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},  /* 720x480/576 */
- {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08}   /* 1024x768 */
-};
-
-#if 0
-static const SiS310_TVDataStruct  SiS310_St1HiTVData[]=
-{
-  
-};
-#endif
-
-static const SiS310_TVDataStruct  SiS310_St2HiTVData[]=
-{
- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
- {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
-};
-
-static const SiS310_TVDataStruct  SiS310_ExtHiTVData[]=
-{
- {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
- {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
- {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},
- {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
- {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}
-};
-
-static const UCHAR SiS310_NTSCTiming[] = { 
-	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
-	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
-	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
-	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
-	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
-	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
-	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
-};
-
-static const UCHAR SiS310_PALTiming[] = {  
-	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
-	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
-	0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
-	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
-	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
-	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
-};
-
-static const UCHAR SiS310_HiTVExtTiming[] = {  
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
-};
-
-static const UCHAR SiS310_HiTVSt1Timing[] = {  
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
-	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
-	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
-	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
-};
-
-static const UCHAR SiS310_HiTVSt2Timing[] = {  
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
-};
-
-static const UCHAR SiS310_HiTVTextTiming[] = {  
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
-	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
-	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
-        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
-	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
-};
-
-static const UCHAR SiS310_HiTVGroup3Data[] = {  
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
-	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
-	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
-
-static const UCHAR SiS310_HiTVGroup3Simu[] = {  
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
-	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
-
-static const UCHAR SiS310_HiTVGroup3Text[] = {  
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
-	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
-
 typedef struct _SiS310_PanelDelayTblStruct
 {
  	UCHAR timer[2];
 } SiS310_PanelDelayTblStruct;
 
-static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=  
+static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
 {
-        {{0x10,0x40}},		/* TW: from 650/301LVx 1.10.6s BIOS */
+        {{0x10,0x40}},
 	{{0x10,0x40}},
 	{{0x10,0x40}},
 	{{0x10,0x40}},
@@ -1812,24 +998,6 @@
 	{{0x10,0x40}},
 	{{0x10,0x40}},
 	{{0x10,0x40}}
-#if 0
-	{{0x28,0xc8}},		/* TW: from 650/301LV BIOS */
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}}
-#endif
 };
 
 static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
@@ -1860,363 +1028,7 @@
 	USHORT LCDVT;
 } SiS310_LVDSDataStruct;
 
-static const SiS310_LVDSDataStruct  SiS310_LVDS320x480Data_1[]=
-{
-	{ 848, 433, 400, 525},
-	{ 848, 389, 400, 525},
-	{ 848, 433, 400, 525},
-	{ 848, 389, 400, 525},
-	{ 848, 518, 400, 525},
-	{1056, 628, 400, 525},
-	{ 400, 525, 400, 525},
-	{ 800, 449,1000, 644},
-	{ 800, 525,1000, 635}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_1[]= 
-{
-	{ 848, 433,1060, 629},
-	{ 848, 389,1060, 629},
-	{ 848, 433,1060, 629},
-	{ 848, 389,1060, 629},
-	{ 848, 518,1060, 629},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{ 800, 449,1000, 644},
-	{ 800, 525,1000, 635}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_2[]=  
-{
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{ 800, 449,1000, 644},
-	{ 800, 525,1000, 635}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_1[]=  
-{
-	{ 840, 438,1344, 806},
-	{ 840, 409,1344, 806},
-	{ 840, 438,1344, 806},
-	{ 840, 409,1344, 806},
-	{ 840, 518,1344, 806},   /* 640x480 */
-	{1050, 638,1344, 806},   /* 800x600 */
-	{1344, 806,1344, 806},   /* 1024x768 */
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_2[]= 
-{
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_1[]=  
-{	
-	{1048, 442,1688,1066},
-	{1048, 392,1688,1066},
-	{1048, 442,1688,1066},
-	{1048, 392,1688,1066},
-	{1048, 522,1688,1066},
-	{1208, 642,1688,1066},
-	{1432, 810,1688,1066},
-	{1688,1066,1688,1066}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_2[]=  
-{	
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_1[]=  
-{
-        { 928, 416, 1688,1066},
-	{ 928, 366, 1688,1066},
-	{ 928, 416, 1688,1066},
-	{ 928, 366, 1688,1066},
-	{ 928, 496, 1688,1066},
-	{1088, 616, 1688,1066},
-	{1312, 784, 1688,1066},
-	{1568,1040, 1688,1066},
-	{1688,1066, 1688,1066}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_2[]= 
-{
-        {1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1600x1200Data_1[]=  
-{
-        {1088, 450, 2048,1250},
-	{1088, 400, 2048,1250},
-	{1088, 450, 2048,1250},
-	{1088, 400, 2048,1250},
-	{1088, 530, 2048,1250},
-	{1248, 650, 2048,1250},
-	{1472, 818, 2048,1250},
-	{1728,1066, 2048,1250},
-	{1848,1066, 2048,1250},
-	{2048,1250, 2048,1250}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1600x1200Data_2[]= 
-{
-        {2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x768Data_1[]= 
-{	
-	{ 768, 438, 1408, 806},
-	{ 768, 388, 1408, 806},
-	{ 768, 438, 1408, 806},
-	{ 768, 388, 1408, 806},
-	{ 768, 518, 1408, 806},
-	{ 928, 638, 1408, 806},
-	{1152, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x768Data_2[]=  
-{	
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_1[]=
-{
-	{ 840, 604, 1344, 800},
-	{ 840, 560, 1344, 800},
-	{ 840, 604, 1344, 800},
-	{ 840, 560, 1344, 800},
-	{ 840, 689, 1344, 800},
-	{1050, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{ 800, 449, 1280, 801},
-	{ 800, 525, 1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_2[]=
-{
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{ 800, 449, 1280, 801},
-	{ 800, 525, 1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_1[]=
-{
-	{ 840, 438, 1344, 806},
-	{ 840, 409, 1344, 806},
-	{ 840, 438, 1344, 806},
-	{ 840, 409, 1344, 806},
-	{ 840, 518, 1344, 806},
-	{1050, 638, 1344, 806},
-	{1344, 806, 1344, 806},
-	{ 800, 449, 1280, 801},
-	{ 800, 525, 1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_2[]=
-{
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{ 800, 449, 1280, 801},
-	{ 800, 525, 1280, 813}
-};
-
-/* TW: Pass 1:1 data */
-static const SiS310_LVDSDataStruct  SiS310_LVDSXXXxXXXData_1[]=  
-{
-        { 800, 449,  800, 449},
-	{ 800, 449,  800, 449},
-	{ 900, 449,  900, 449},
-	{ 900, 449,  900, 449},
-	{ 800, 525,  800, 525},  /*  640x480   */
-	{1056, 628, 1056, 628},  /*  800x600   */
-	{1344, 806, 1344, 806},  /* 1024x768   */
-	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
- 	{1688, 806, 1688, 806},  /* 1280x768   */
-	/* No other panels ! */
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS640x480Data_1[]=  
-{
-	{ 800, 449, 800, 449},
-	{ 800, 449, 800, 449},
-	{ 800, 449, 800, 449},
-	{ 800, 449, 800, 449},
-	{ 800, 525, 800, 525},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_1[]=   
-{
-	{ 840, 438,1344, 806},
-	{ 840, 409,1344, 806},
-	{ 840, 438,1344, 806},
-	{ 840, 409,1344, 806},
-	{ 840, 518,1344, 806},
-	{1050, 638,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_2[]=  
-{
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-/* LCDA */
-
-static const SiS310_LVDSDataStruct  SiS310_LCDA1400x1050Data_1[]=   
-{	/* TW: Might be temporary (invalid) data */
-        { 928, 416, 1688,1066},
-	{ 928, 366, 1688,1066},
-	{1008, 416, 1688,1066},
-	{1008, 366, 1688,1066},
-	{1200, 530, 1688,1066},
-	{1088, 616, 1688,1066},
-	{1312, 784, 1688,1066},
-	{1568,1040, 1688,1066},
-	{1688,1066, 1688,1066}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LCDA1400x1050Data_2[]=   
-{	/* TW: Temporary data. Not valid */
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LCDA1600x1200Data_1[]=  
-{	/* TW: Temporary data. Not valid */
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LCDA1600x1200Data_2[]=  
-{	/* TW: Temporary data. Not valid */
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0}
-};
-
-/* Chrontel TV */
-
-static const SiS310_LVDSDataStruct  SiS310_CHTVUNTSCData[]=   
-{
-	{ 840, 600, 840, 600},
-	{ 840, 600, 840, 600},
-	{ 840, 600, 840, 600},
-	{ 840, 600, 840, 600},
-	{ 784, 600, 784, 600},
-	{1064, 750,1064, 750},
-        {1160, 945,1160, 945}           /* TW: For Ch7019 1024 */
-};
-
-static const SiS310_LVDSDataStruct  SiS310_CHTVONTSCData[]=   
-{
-	{ 840, 525, 840, 525},
-	{ 840, 525, 840, 525},
-	{ 840, 525, 840, 525},
-	{ 840, 525, 840, 525},
-	{ 784, 525, 784, 525},
-	{1040, 700,1040, 700},
-        {1160, 840,1160, 840}          	/* TW: For Ch7019 1024 */
-};
-
-static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=   
+static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=
 {
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
@@ -2224,7 +1036,7 @@
 	{1008, 625,1008, 625},
 	{ 840, 625, 840, 625},
 	{ 960, 750, 960, 750},
-	{1400,1000,1400,1000}   	/*  TW: For Ch7019 1024 */
+	{1400,1000,1400,1000}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]= 
@@ -2235,7 +1047,7 @@
 	{1008, 625,1008, 625},
 	{ 840, 625, 840, 625},
 	{ 944, 625, 944, 625},
-        {1400, 875,1400, 875}       	/*  TW: For Ch7019 1024 */
+        {1400, 875,1400, 875}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVUPALMData[]=  
@@ -2246,7 +1058,7 @@
 	{ 840, 600, 840, 600},
 	{ 784, 600, 784, 600},
 	{1064, 750,1064, 750},
-        {1160, 945,1160, 945}           /* TW: For Ch7019 1024 */
+        {1160, 945,1160, 945}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVOPALMData[]=  
@@ -2257,7 +1069,7 @@
 	{ 840, 525, 840, 525},
 	{ 784, 525, 784, 525},
 	{1040, 700,1040, 700},
-        {1160, 840,1160, 840}          	/* TW: For Ch7019 1024 */
+        {1160, 840,1160, 840}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVUPALNData[]=  
@@ -2268,7 +1080,7 @@
 	{1008, 625,1008, 625},
 	{ 840, 625, 840, 625},
 	{ 960, 750, 960, 750},
-	{1400,1000,1400,1000}   	/*  TW: For Ch7019 1024 */
+	{1400,1000,1400,1000}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVOPALNData[]= 
@@ -2279,7 +1091,7 @@
 	{1008, 625,1008, 625},
 	{ 840, 625, 840, 625},
 	{ 944, 625, 944, 625},
-        {1400, 875,1400, 875}       	/*  TW: For Ch7019 1024 */
+        {1400, 875,1400, 875}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* TW: (super overscan - no effect on 7019) */
@@ -2299,7 +1111,7 @@
 	USHORT LCDVDES;
 } SiS310_LVDSDesStruct;
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  
+static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  /* 800x600 */
 {
 	{ 0, 0},
 	{ 0, 0},
@@ -2312,7 +1124,7 @@
 	{ 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=   
+static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=  /* 1024x768 */
 {
 	{ 0, 0},
 	{ 0, 0},
@@ -2325,7 +1137,7 @@
 	{ 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  
+static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  /* 1280x1024 */
 {
 	{ 0, 0},
 	{ 0, 0},
@@ -2450,33 +1262,31 @@
 	{ 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]= 
-{
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
-};
-
-static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  
+static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=  /* 640x480_2 */
 {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 8, 524},
+	{ 0, 524}
+};
+
+static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  /* 640x480_3 */
+{
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 8, 524},
+	{ 0, 524}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]= 
+static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=
 {
 	{1343, 798},
 	{1343, 794},
@@ -2672,7 +1482,7 @@
 	{   0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  
+static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  /* 640x480_2 */
 {
 	{1152, 622},
 	{1152, 597},
@@ -2685,7 +1495,7 @@
 	{ 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]= 
+static const SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=  /* 640x480_3 */
 {
 	{1152, 622},
 	{1152, 597},
@@ -2737,184 +1547,6 @@
 	{ 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelTypeNS_1[]= 
-{
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0, 806},
-	{ 0, 0 }
-};
-
-static const SiS310_LVDSDesStruct  SiS310_PanelTypeNS_2[] = 
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=  
-{  /* 1024x768 - Checked (1.10.6s) */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=  
-{  /* 1024x768 - Checked (1.10.6s) */
-	{ 1184, 622 },
-	{ 1184, 597 },
-	{ 1184, 622 },
-	{ 1184, 597 },
-	{ 1152, 622 },
-	{ 1232, 722 },
-	{    0, 0   },
-	{    0, 794 },
-	{    0, 0   }
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=  
-{  /* 1280x1024 - Checked (1.10.6s) */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=  
-{  /* 1280x1024 - Checked (1.10.6s) */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=  
-{  /* 1400x1050 - Checked (1.10.6s) */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=  
-{  /* 1400x1050 - Checked (1.10.6s) - looks heavily invalid */
-	{ 808 , 740},
-	{ 0   , 715},
-	{ 632 , 740},
-	{ 632 , 715},
-	{ 1307, 780},
-	{ 1387,1157},
-	{ 1499, 924},
-	{ 1627,1052},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1600_1[]= 
-{  /* 1600x1200 - Checked (1.10.6s) */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1600_2[]= 
-{  /* 1600x1200 - Checked (1.10.6s) - looks heavily invalid, not copied */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct  SiS310_CHTVUNTSCDesData[]=
-{
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
-};
-
-static const SiS310_LVDSDesStruct  SiS310_CHTVONTSCDesData[]=
-{
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
-};
-
-static const SiS310_LVDSDesStruct  SiS310_CHTVUPALDesData[]=
-{
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
-};
-
-static const SiS310_LVDSDesStruct  SiS310_CHTVOPALDesData[]=
-{
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
-};
-
 typedef struct _SiS310_Part2PortTblStruct
 {
  	UCHAR CR[12];
@@ -2934,16 +1566,15 @@
 };
 
 static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
-{	/* TW: Temporary data, invalid */
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
+{	/* TW: BIOS data invalid, last row taken from _3 */
+ {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+ {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+ {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+ {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}},
+ {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+ {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}},
+ {{0x36,0x13,0x02,0x25,0xFF,0x03,0x45,0x09,0x07,0xF9,0x00,0x24}},
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
 };
 
 static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] =
@@ -2980,7 +1611,8 @@
  {{0x2c,0x12,0x38,0x55,0x2f,0xc1,0x35,0xb1,0x47,0xe9,0x71,0x33}},
  {{0x2d,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
  {{0x29,0x12,0xb5,0xd2,0xac,0xe9,0x35,0xd9,0x47,0x11,0x99,0x33}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},  /* old  */
+/* 0x36,0x13,0x02,0x25,0xff,0x03,0x45,0x09,0x07,0xf9,0x00,0x24        new? */
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
 };
@@ -3027,6 +1659,7 @@
 
 static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
 {	/* TW: Data from 650/301LVx 1.10.6s */
+#if 0
  {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
@@ -3036,56 +1669,55 @@
  {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
  {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}}
-#if 0	/* TW: Data from 650/301LV */
- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-#endif
+#endif	/* Data from my 301LV */
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},   /* @@@@@ TEST */
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}
 };
 
 /*   1     2    4    5    6   1c   1d   1f   20   21   23   25   */
 static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
-{	/* TW: Temporary data, invalid */
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+{
+ {{0x31,0x1B,0xC4,0xDA,0xB0,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x34,0x1B,0x9F,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
+ {{0x3E,0x1B,0xCF,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
 };
 
 static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] =
 {	
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
 };
 
 static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] =
 {	/* TW: Temporary data, invalid */
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
 };
 
 typedef struct _SiS310_LCDACRT1DataStruct
@@ -3122,7 +1754,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
-{  /* TW: Checked (1.10.6s) */
+{
  {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
    0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
    0x00}},
@@ -3147,7 +1779,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1[]=
-{  /* Checked (1.10.6s) */
+{
  {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
    0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
    0x00}},
@@ -3175,7 +1807,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1[]=
-{    /* Checked (1.10.6s) */
+{
  {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
    0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
    0x00}},
@@ -3268,7 +1900,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
-{  /* TW: Checked (1.10.6s) */
+{
  {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
    0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
    0x00}},
@@ -3293,7 +1925,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1_H[]=
-{   /* Checked (1.10.6s) */
+{
  {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
    0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
    0x00}},
@@ -3318,7 +1950,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1_H[]=
-{   /* Checked (1.10.6s) */
+{
   {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
     0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
     0x00}},
@@ -3411,7 +2043,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2[]=
-{   /* Checked (1.10.6s) */
+{
  {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
    0x00}},
@@ -3436,7 +2068,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2[]=
-{   /* Checked (1.10.6s) */
+{
  {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
    0x00}},
@@ -3461,7 +2093,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2[]=
-{    /* Checked (1.10.6s) */
+{
  {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
    0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
    0x00}},
@@ -3554,7 +2186,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2_H[]=
-{   /* Checked (1.10.6s) */
+{
  {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
    0x00 }},
@@ -3579,7 +2211,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
-{   /* Checked (1.10.6s) */
+{
  {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
    0x00 }},
@@ -3604,7 +2236,7 @@
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2_H[]=
-{  /* Checked (1.10.6s) */
+{
  {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
    0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
    0x00}},
@@ -3673,32 +2305,7 @@
  	UCHAR CR[15];
 } SiS310_LVDSCRT1DataStruct;
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1320x480_1[] =
-{
- {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-   0x00 }},
- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
- {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-   0x00 }},
- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
- {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-   0x00 }},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01 }},
- {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-   0x00 }}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =   
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =
 {
  {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -3992,63 +2599,7 @@
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1[] =  
-{
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
-   0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-   0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
-   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
-   0x01}},
- {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1_H[] = 
-{
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-   0x00}},
- {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
-   0x01}},
- {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =  
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =
 {
   {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
     0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
@@ -4288,332 +2839,8 @@
 #endif   
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_1[] =  
-{	
- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
-   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
-   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
-   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
-   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
-   0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
-   0x00}},
- {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
-   0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
-   0x01}},
- {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_1_H[] = 
-{
- {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
-   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
-   0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
-   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
-   0x00}},
- {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
-   0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
-   0x01}},
- {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
-   0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
-   0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
-   0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_2[] = 
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =
 {
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
-   0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
-   0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
-   0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
-   0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
-   0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
-   0x01}},
- {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
-   0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
-   0x01}},
- {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_2_H[] =
-{
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
-   0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
-   0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
-   0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
-   0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
-   0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
-   0x01}},
- {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
-   0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
-   0x01}},
- {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1[] =
-{
-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
-	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
-	  0x00}},
-        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1_H[] =
-{
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-          0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-	  0x00}},
-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2[] =
-{
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2_H[] =
-{
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1[] =
-{
-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
-	  0x00}},
-        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1_H[] =
-{
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-	  0x00}},
-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2[] =
-{
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2_H[] =
-{
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =  
-{    
  {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
    0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
    0x00}},
@@ -4769,7 +2996,7 @@
 	{{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
 	  0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
 	  0x01 }},
-	{{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,  /* TW: 1024x768 */
+	{{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,
 	  0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
 	  0x01}}
 };
@@ -4794,7 +3021,7 @@
 	{{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
 	  0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
 	  0x01 }},
-	{{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,   /* TW: 1024x768 */
+	{{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,
 	  0x15,0x88,0xff,0x47,0x70,0x00,0x02,
 	  0x01 }}
 };
@@ -4819,7 +3046,7 @@
 	{{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
 	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
 	  0x01 }},
-	{{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,   /* TW: 1024x768 */
+	{{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,
 	  0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
 	  0x01}}
 };
@@ -4844,7 +3071,7 @@
 	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
 	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
 	  0x01 }},
-	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
+	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
 	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
 	  0x01 }}
 };
@@ -4869,12 +3096,11 @@
 	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
 	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
 	  0x01 }},
-	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
+	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
 	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
 	  0x01 }}
 };
 
-/* TW: Data for Chrontel 7019  */
 typedef struct _SiS310_CHTVRegDataStruct
 {
  	UCHAR Reg[16];
diff -urN linux-2.4.22-pre2/drivers/video/sis/init.c linux-2.4.22-pre3/drivers/video/sis/init.c
--- linux-2.4.22-pre2/drivers/video/sis/init.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/init.c	2003-07-05 18:11:00.000000000 -0700
@@ -1,24 +1,16 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.3 2002/24/04 01:16:16 dawes Exp $ */
 /*
- * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740/330
+ * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740/330/660
  * (Universal module for Linux kernel framebuffer and XFree86 4.x)
  *
  * Assembler-To-C translation
- * Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
- * Minor parts Copyright SiS, Inc.
+ * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
+ * Formerly based on non-functional code-fragements by SiS, Inc.
  *
- * Based on BIOS
- *     1.10.07, 1.10a for 650/CH7019
- *     1.11.21a for 740/CH7019
- *     1.11.05 for 650/LVDS (w/o Chrontel)
- *     1.07.1b, 1.11.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV)
- *     2.04.50 (I) and 2.04.5c (II) for 630/301(B)
- *     2.06.50 for 630/301B (dual VGA)
- *     2.02.3b, 2.03.02, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
- *     2.04.5c, 2.04.6c for 730+LVDS+CH7005
- *     1.09b for 315/301(B)
- *     1.16.51 for 300+301LV (ECS A907)
- *     1.01.03 for 330 (Xabre 400)
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -61,12 +53,12 @@
 #ifdef LINUX_XF86
 BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
                        ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
-DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn);
-#ifdef SISDUALHEAD /* TW: For dual head */
+DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi);
+#ifdef SISDUALHEAD
 BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
                        ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
 BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                       ScrnInfoPtr pScrn, DisplayModePtr mode);
+                       ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
 #endif /* dual head */
 #endif /* linux_xf86 */
 
@@ -90,49 +82,199 @@
 static ULONG GetDRAMSize(SiS_Private *SiS_Pr,
                          PSIS_HW_DEVICE_INFO HwDeviceExtension);
 
-static void DelaySeconds(int seconds);
-void SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code);
-
 static void
-DelaySeconds(int seconds)
-{
-  int i;
-#ifdef WIN2000
-  int j;
-#endif
-
-  for (i=0;i<seconds;i++) {
-#ifdef TC
-    delay(1000);
-#endif
-
-#ifdef WIN2000
-    for (j=0;j<20000;j++)
-      VideoPortStallExecution(50);
-#endif
-
-#ifdef WINCE_HEADER
-#endif
-
-#ifdef LINUX_KERNEL
-#endif
-  }
-}
-
-void
-SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code)
+InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  OutPortByte(0x80, code);
-  DelaySeconds(0x3);
+   SiS_Pr->SiS_StResInfo     = SiS_StResInfo;
+   SiS_Pr->SiS_ModeResInfo   = SiS_ModeResInfo;
+   SiS_Pr->SiS_StandTable    = SiS_StandTable;
+   if(HwDeviceExtension->jChipType < SIS_315H) {
+      SiS_StandTable[0x04].CRTC[4] = 0x2b;
+      SiS_StandTable[0x05].CRTC[4] = 0x2b;
+      SiS_StandTable[0x06].CRTC[4] = 0x54;
+      SiS_StandTable[0x06].CRTC[5] = 0x80;
+      SiS_StandTable[0x0d].CRTC[4] = 0x2b;
+      SiS_StandTable[0x0e].CRTC[4] = 0x54;
+      SiS_StandTable[0x0e].CRTC[5] = 0x80;
+      SiS_StandTable[0x11].CRTC[4] = 0x54;
+      SiS_StandTable[0x11].CRTC[5] = 0x80;
+      SiS_StandTable[0x11].CRTC[16] = 0x83;
+      SiS_StandTable[0x11].CRTC[17] = 0x85;
+      SiS_StandTable[0x12].CRTC[4] = 0x54;
+      SiS_StandTable[0x12].CRTC[5] = 0x80;
+      SiS_StandTable[0x12].CRTC[16] = 0x83;
+      SiS_StandTable[0x12].CRTC[17] = 0x85;
+      SiS_StandTable[0x13].CRTC[5] = 0xa0;
+      SiS_StandTable[0x17].CRTC[5] = 0xa0;
+      SiS_StandTable[0x1a].CRTC[4] = 0x54;
+      SiS_StandTable[0x1a].CRTC[5] = 0x80;
+      SiS_StandTable[0x1a].CRTC[16] = 0xea;
+      SiS_StandTable[0x1a].CRTC[17] = 0x8c;
+      SiS_StandTable[0x1b].CRTC[4] = 0x54;
+      SiS_StandTable[0x1b].CRTC[5] = 0x80;
+      SiS_StandTable[0x1b].CRTC[16] = 0xea;
+      SiS_StandTable[0x1b].CRTC[17] = 0x8c;
+      SiS_StandTable[0x1c].CRTC[4] = 0x54;
+      SiS_StandTable[0x1c].CRTC[5] = 0x80;
+   } else {
+      SiS_StandTable[0x04].CRTC[4] = 0x2c;
+      SiS_StandTable[0x05].CRTC[4] = 0x2c;
+      SiS_StandTable[0x06].CRTC[4] = 0x55;
+      SiS_StandTable[0x06].CRTC[5] = 0x81;
+      SiS_StandTable[0x0d].CRTC[4] = 0x2c;
+      SiS_StandTable[0x0e].CRTC[4] = 0x55;
+      SiS_StandTable[0x0e].CRTC[5] = 0x81;
+      SiS_StandTable[0x11].CRTC[4] = 0x55;
+      SiS_StandTable[0x11].CRTC[5] = 0x81;
+      SiS_StandTable[0x11].CRTC[16] = 0x82;
+      SiS_StandTable[0x11].CRTC[17] = 0x84;
+      SiS_StandTable[0x12].CRTC[4] = 0x55;
+      SiS_StandTable[0x12].CRTC[5] = 0x81;
+      SiS_StandTable[0x12].CRTC[16] = 0x82;
+      SiS_StandTable[0x12].CRTC[17] = 0x84;
+      SiS_StandTable[0x13].CRTC[5] = 0xb1;
+      SiS_StandTable[0x17].CRTC[5] = 0xb1;
+      SiS_StandTable[0x1a].CRTC[4] = 0x55;
+      SiS_StandTable[0x1a].CRTC[5] = 0x81;
+      SiS_StandTable[0x1a].CRTC[16] = 0xe9;
+      SiS_StandTable[0x1a].CRTC[17] = 0x8b;
+      SiS_StandTable[0x1b].CRTC[4] = 0x55;
+      SiS_StandTable[0x1b].CRTC[5] = 0x81;
+      SiS_StandTable[0x1b].CRTC[16] = 0xe9;
+      SiS_StandTable[0x1b].CRTC[17] = 0x8b;
+      SiS_StandTable[0x1c].CRTC[4] = 0x55;
+      SiS_StandTable[0x1c].CRTC[5] = 0x81;
+   }
+
+   SiS_Pr->SiS_NTSCPhase    = SiS_NTSCPhase;
+   SiS_Pr->SiS_PALPhase     = SiS_PALPhase;
+   SiS_Pr->SiS_NTSCPhase2   = SiS_NTSCPhase2;
+   SiS_Pr->SiS_PALPhase2    = SiS_PALPhase2;
+   SiS_Pr->SiS_PALMPhase    = SiS_PALMPhase;
+   SiS_Pr->SiS_PALNPhase    = SiS_PALNPhase;
+   SiS_Pr->SiS_PALMPhase2   = SiS_PALMPhase2;
+   SiS_Pr->SiS_PALNPhase2   = SiS_PALNPhase2;
+   SiS_Pr->SiS_SpecialPhase = SiS_SpecialPhase;
+
+   SiS_Pr->SiS_NTSCTiming     = SiS_NTSCTiming;
+   SiS_Pr->SiS_PALTiming      = SiS_PALTiming;
+   SiS_Pr->SiS_HiTVSt1Timing  = SiS_HiTVSt1Timing;
+   SiS_Pr->SiS_HiTVSt2Timing  = SiS_HiTVSt2Timing;
+   SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming;
+   SiS_Pr->SiS_HiTVExtTiming  = SiS_HiTVExtTiming;
+   SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data;
+   SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu;
+   SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text;
+
+   SiS_Pr->SiS_StPALData   = SiS_StPALData;
+   SiS_Pr->SiS_ExtPALData  = SiS_ExtPALData;
+   SiS_Pr->SiS_StNTSCData  = SiS_StNTSCData;
+   SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData;
+/* SiS_Pr->SiS_St1HiTVData = SiS_St1HiTVData;  */
+   SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData;
+   SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData;
+
+   SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
+   SiS_Pr->pSiS_SoftSetting  = &SiS_SoftSetting;
+
+   SiS_Pr->SiS_LCD1280x960Data      = SiS_LCD1280x960Data;
+   SiS_Pr->SiS_ExtLCD1400x1050Data  = SiS_ExtLCD1400x1050Data;
+   SiS_Pr->SiS_ExtLCD1600x1200Data  = SiS_ExtLCD1600x1200Data;
+   SiS_Pr->SiS_StLCD1400x1050Data   = SiS_StLCD1400x1050Data;
+   SiS_Pr->SiS_StLCD1600x1200Data   = SiS_StLCD1600x1200Data;
+   SiS_Pr->SiS_NoScaleData1400x1050 = SiS_NoScaleData1400x1050;
+   SiS_Pr->SiS_NoScaleData1600x1200 = SiS_NoScaleData1600x1200;
+   SiS_Pr->SiS_ExtLCD1280x768Data   = SiS_ExtLCD1280x768Data;
+   SiS_Pr->SiS_StLCD1280x768Data    = SiS_StLCD1280x768Data;
+   SiS_Pr->SiS_NoScaleData1280x768  = SiS_NoScaleData1280x768;
+   SiS_Pr->SiS_NoScaleData          = SiS_NoScaleData;
+
+   SiS_Pr->SiS_LVDS320x480Data_1   = SiS_LVDS320x480Data_1;
+   SiS_Pr->SiS_LVDS800x600Data_1   = SiS_LVDS800x600Data_1;
+   SiS_Pr->SiS_LVDS800x600Data_2   = SiS_LVDS800x600Data_2;
+   SiS_Pr->SiS_LVDS1024x768Data_1  = SiS_LVDS1024x768Data_1;
+   SiS_Pr->SiS_LVDS1024x768Data_2  = SiS_LVDS1024x768Data_2;
+   SiS_Pr->SiS_LVDS1280x1024Data_1 = SiS_LVDS1280x1024Data_1;
+   SiS_Pr->SiS_LVDS1280x1024Data_2 = SiS_LVDS1280x1024Data_2;
+   SiS_Pr->SiS_LVDS1400x1050Data_1 = SiS_LVDS1400x1050Data_1;
+   SiS_Pr->SiS_LVDS1400x1050Data_2 = SiS_LVDS1400x1050Data_2;
+   SiS_Pr->SiS_LVDS1600x1200Data_1 = SiS_LVDS1600x1200Data_1;
+   SiS_Pr->SiS_LVDS1600x1200Data_2 = SiS_LVDS1600x1200Data_2;
+   SiS_Pr->SiS_LVDS1280x768Data_1  = SiS_LVDS1280x768Data_1;
+   SiS_Pr->SiS_LVDS1280x768Data_2  = SiS_LVDS1280x768Data_2;
+   SiS_Pr->SiS_LVDS1024x600Data_1  = SiS_LVDS1024x600Data_1;
+   SiS_Pr->SiS_LVDS1024x600Data_2  = SiS_LVDS1024x600Data_2;
+   SiS_Pr->SiS_LVDS1152x768Data_1  = SiS_LVDS1152x768Data_1;
+   SiS_Pr->SiS_LVDS1152x768Data_2  = SiS_LVDS1152x768Data_2;
+   SiS_Pr->SiS_LVDSXXXxXXXData_1   = SiS_LVDSXXXxXXXData_1;
+   SiS_Pr->SiS_LVDS1280x960Data_1  = SiS_LVDS1280x960Data_1;
+   SiS_Pr->SiS_LVDS1280x960Data_2  = SiS_LVDS1280x960Data_2;
+   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
+   SiS_Pr->SiS_LVDS1280x960Data_1  = SiS_LVDS1280x1024Data_1;
+   SiS_Pr->SiS_LVDS1280x960Data_2  = SiS_LVDS1280x1024Data_2;
+   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
+   SiS_Pr->SiS_LVDS640x480Data_2   = SiS_LVDS640x480Data_2;
+
+   SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
+   SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
+   SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
+   SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
+
+   SiS_Pr->SiS_LCDA1400x1050Data_1 = SiS_LCDA1400x1050Data_1;
+   SiS_Pr->SiS_LCDA1400x1050Data_2 = SiS_LCDA1400x1050Data_2;
+   SiS_Pr->SiS_LCDA1600x1200Data_1 = SiS_LCDA1600x1200Data_1;
+   SiS_Pr->SiS_LCDA1600x1200Data_2 = SiS_LCDA1600x1200Data_2;
+   SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
+   SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
+
+   SiS_Pr->LVDS1024x768Des_1  = SiS_PanelType1076_1;
+   SiS_Pr->LVDS1280x1024Des_1 = SiS_PanelType1210_1;
+   SiS_Pr->LVDS1400x1050Des_1 = SiS_PanelType1296_1;
+   SiS_Pr->LVDS1600x1200Des_1 = SiS_PanelType1600_1;
+   SiS_Pr->LVDS1024x768Des_2  = SiS_PanelType1076_2;
+   SiS_Pr->LVDS1280x1024Des_2 = SiS_PanelType1210_2;
+   SiS_Pr->LVDS1400x1050Des_2 = SiS_PanelType1296_2;
+   SiS_Pr->LVDS1600x1200Des_2 = SiS_PanelType1600_2;
+
+   SiS_Pr->SiS_PanelTypeNS_1 = SiS_PanelTypeNS_1;
+   SiS_Pr->SiS_PanelTypeNS_2 = SiS_PanelTypeNS_2;
+
+   SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
+   SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
+   SiS_Pr->SiS_CHTVUPALDesData  = SiS_CHTVUPALDesData;
+   SiS_Pr->SiS_CHTVOPALDesData  = SiS_CHTVOPALDesData;
+
+   SiS_Pr->SiS_LVDSCRT11280x768_1    = SiS_LVDSCRT11280x768_1;
+   SiS_Pr->SiS_LVDSCRT11024x600_1    = SiS_LVDSCRT11024x600_1;
+   SiS_Pr->SiS_LVDSCRT11152x768_1    = SiS_LVDSCRT11152x768_1;
+   SiS_Pr->SiS_LVDSCRT11280x768_1_H  = SiS_LVDSCRT11280x768_1_H;
+   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = SiS_LVDSCRT11024x600_1_H;
+   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = SiS_LVDSCRT11152x768_1_H;
+   SiS_Pr->SiS_LVDSCRT11280x768_2    = SiS_LVDSCRT11280x768_2;
+   SiS_Pr->SiS_LVDSCRT11024x600_2    = SiS_LVDSCRT11024x600_2;
+   SiS_Pr->SiS_LVDSCRT11152x768_2    = SiS_LVDSCRT11152x768_2;
+   SiS_Pr->SiS_LVDSCRT11280x768_2_H  = SiS_LVDSCRT11280x768_2_H;
+   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = SiS_LVDSCRT11024x600_2_H;
+   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = SiS_LVDSCRT11152x768_2_H;
+   SiS_Pr->SiS_LVDSCRT1320x480_1     = SiS_LVDSCRT1320x480_1;
+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = SiS_LVDSCRT1XXXxXXX_1;
+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = SiS_LVDSCRT1XXXxXXX_1_H;
+   SiS_Pr->SiS_LVDSCRT1640x480_1     = SiS_LVDSCRT1640x480_1;
+   SiS_Pr->SiS_LVDSCRT1640x480_1_H   = SiS_LVDSCRT1640x480_1_H;
+   SiS_Pr->SiS_LVDSCRT1640x480_2     = SiS_LVDSCRT1640x480_2;
+   SiS_Pr->SiS_LVDSCRT1640x480_2_H   = SiS_LVDSCRT1640x480_2_H;
+   SiS_Pr->SiS_LVDSCRT1640x480_3     = SiS_LVDSCRT1640x480_3;
+   SiS_Pr->SiS_LVDSCRT1640x480_3_H   = SiS_LVDSCRT1640x480_3_H;
 }
 
 #ifdef SIS300
 static void
 InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
+   InitCommonPointer(SiS_Pr, HwDeviceExtension);
+
    SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS300_SModeIDTable;
    SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable;
-   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS300_StandTable;
    SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS300_EModeIDTable;
    SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS300_RefIndex;
    SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS300_CRT1Table;
@@ -141,15 +283,12 @@
    } else {
       SiS_Pr->SiS_MCLKData_0    = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630, 730 */
    }
+#ifdef LINUXBIOS
    SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS300_ECLKData;
+#endif
    SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS300_VCLKData;
    SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
    SiS_Pr->SiS_ScreenOffset  = SiS300_ScreenOffset;
-   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS300_StResInfo;
-   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS300_ModeResInfo;
-
-   SiS_Pr->pSiS_OutputSelect = &SiS300_OutputSelect;
-   SiS_Pr->pSiS_SoftSetting  = &SiS300_SoftSetting;
 
    SiS_Pr->SiS_SR15  = SiS300_SR15;
 
@@ -178,15 +317,6 @@
    SiS_Pr->pSiS_YCSenseData2    = &SiS300_YCSenseData2;
 #endif
 
-   SiS_Pr->SiS_NTSCPhase  = SiS300_NTSCPhase;
-   SiS_Pr->SiS_PALPhase   = SiS300_PALPhase;
-   SiS_Pr->SiS_NTSCPhase2 = SiS300_NTSCPhase2;
-   SiS_Pr->SiS_PALPhase2  = SiS300_PALPhase2;
-   SiS_Pr->SiS_PALMPhase  = SiS300_PALMPhase;
-   SiS_Pr->SiS_PALNPhase  = SiS300_PALNPhase;
-   SiS_Pr->SiS_PALMPhase2 = SiS300_PALMPhase2;
-   SiS_Pr->SiS_PALNPhase2 = SiS300_PALNPhase2;
-
    SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data;
    SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data;
    SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data;
@@ -195,69 +325,18 @@
    SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data;
    SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768;
    SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024;
-   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS300_LCD1280x960Data;
-   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1400x1050Data;
-   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1600x1200Data;
-   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS300_StLCD1400x1050Data;
-   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS300_StLCD1600x1200Data;
-   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS300_NoScaleData1400x1050;
-   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS300_NoScaleData1600x1200;
-   SiS_Pr->SiS_NoScaleData          = (SiS_LCDDataStruct *)SiS300_NoScaleData;
-
-   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS300_StPALData;
-   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS300_ExtPALData;
-   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS300_StNTSCData;
-   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS300_ExtNTSCData;
-/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS300_St1HiTVData;  */
-   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS300_St2HiTVData;
-   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS300_ExtHiTVData;
-
-   SiS_Pr->SiS_NTSCTiming     = SiS300_NTSCTiming;
-   SiS_Pr->SiS_PALTiming      = SiS300_PALTiming;
-   SiS_Pr->SiS_HiTVSt1Timing  = SiS300_HiTVSt1Timing;
-   SiS_Pr->SiS_HiTVSt2Timing  = SiS300_HiTVSt2Timing;
-   SiS_Pr->SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
-   SiS_Pr->SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
-   SiS_Pr->SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
-   SiS_Pr->SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
 
    SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
    SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS;
 
-   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_1;
-   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_2;
-   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_1;
-   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_2;
-   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
-   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
-   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
-   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
-   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_1;
-   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_2;
-   SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_1;
-   SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_2;
-   SiS_Pr->SiS_LVDS1280x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_1;
-   SiS_Pr->SiS_LVDS1280x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_2;
-   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_1;
-   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_2;
-   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_1;
-   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_2;
-   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS300_LVDSXXXxXXXData_1;
-   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS320x480Data_1;
-   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS640x480Data_1;
-   SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_1;
-   SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_2;
-   SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_1;
-   SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_2;
-   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData;
-   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData;
    SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;
    SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;
-   SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData; /* not supported on 300 series */
-   SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData; /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; 			   /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; 			   /* not supported on 300 series */
    SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;  /* not supported on 300 series */
    SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;  /* not supported on 300 series */
    SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVSOPALData;
+
    SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1;
    SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1;
    SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1;
@@ -290,32 +369,28 @@
    SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2;
    SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2;
    SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2;
-   SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_1;
-   SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_2;
-   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUNTSCDesData;
-   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVONTSCDesData;
-   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVUPALDesData;
-   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVOPALDesData;
+
+   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+      SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1a;
+      SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2a;
+   }
+   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+      SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1b;
+      SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2b;
+   }
+
    SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1;
    SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1;
    SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1;
-   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1;
-   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1;
    SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H;
    SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H;
    SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H;
-   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1_H;
-   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1_H;
    SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2;
    SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2;
    SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2;
-   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2;
-   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2;
    SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H;
    SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H;
    SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H;
-   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2_H;
-   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2_H;
    SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC;
    SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC;
    SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL;
@@ -340,7 +415,6 @@
    SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL;   /* not supported on 300 series */
    SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
 
-   /* TW: New from 300/301LV BIOS */
    SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_1;
    SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_1;
    SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_1;
@@ -354,7 +428,7 @@
    SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_3;
    SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_3;
 
-   /* TW: LCDResInfo will on 300 series be translated to 310/325 series definitions */
+   /* TW: LCDResInfo will on 300 series be translated to 315 series definitions */
    SiS_Pr->SiS_Panel320x480   = Panel_320x480;
    SiS_Pr->SiS_Panel640x480   = Panel_640x480;
    SiS_Pr->SiS_Panel800x600   = Panel_800x600;
@@ -363,13 +437,17 @@
    SiS_Pr->SiS_Panel1280x960  = Panel_1280x960;
    SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
    SiS_Pr->SiS_Panel1152x768  = Panel_1152x768;
-   SiS_Pr->SiS_Panel1600x1200 = 16;  		/* TW: Something illegal */
-   SiS_Pr->SiS_Panel1400x1050 = 16;  		/* TW: Something illegal */
-   SiS_Pr->SiS_Panel1152x864  = 16;   		/* TW: Something illegal */
-   SiS_Pr->SiS_Panel1280x768  = 16;   		/* TW: Something illegal */
+   SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
+   SiS_Pr->SiS_Panel1600x1200 = 255;  		/* TW: Something illegal */
+   SiS_Pr->SiS_Panel1400x1050 = 255;  		/* TW: Something illegal */
+   SiS_Pr->SiS_Panel640x480_2 = 255;  		/* TW: Something illegal */
+   SiS_Pr->SiS_Panel640x480_3 = 255;  		/* TW: Something illegal */
+   SiS_Pr->SiS_Panel1152x864  = 255;   		/* TW: Something illegal */
    SiS_Pr->SiS_PanelMax       = Panel_320x480;     /* TW: highest value */
    SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;     /* TW: Lowest value LVDS */
    SiS_Pr->SiS_PanelMin301    = Panel_1024x768;    /* TW: lowest value 301 */
+   SiS_Pr->SiS_PanelCustom    = Panel_Custom;
+   SiS_Pr->SiS_PanelBarco1366 = Panel_Barco1366;
 }
 #endif
 
@@ -377,29 +455,33 @@
 static void
 InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
+   InitCommonPointer(SiS_Pr, HwDeviceExtension);
+
    SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS310_SModeIDTable;
-   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS310_StandTable;
    SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS310_EModeIDTable;
    SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS310_RefIndex;
    SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS310_CRT1Table;
    /* TW: MCLK is different */
-   if(HwDeviceExtension->jChipType == SIS_330) {
+#ifdef LINUXBIOS
+   if(HwDeviceExtension->jChipType == SIS_660) {
+      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_660;  /* 660 */
+   } else if(HwDeviceExtension->jChipType == SIS_330) {
+#endif
       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330;  /* 330 */
+#ifdef LINUXBIOS
    } else if(HwDeviceExtension->jChipType > SIS_315PRO) {
       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650;  /* 550, 650, 740 */
    } else {
       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315;  /* 315 */
    }
+#endif
    SiS_Pr->SiS_MCLKData_1    = (SiS_MCLKDataStruct *)SiS310_MCLKData_1;
+#ifdef LINUXBIOS
    SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS310_ECLKData;
+#endif
    SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS310_VCLKData;
    SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData;
    SiS_Pr->SiS_ScreenOffset  = SiS310_ScreenOffset;
-   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS310_StResInfo;
-   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS310_ModeResInfo;
-
-   SiS_Pr->pSiS_OutputSelect = &SiS310_OutputSelect;
-   SiS_Pr->pSiS_SoftSetting  = &SiS310_SoftSetting;
 
    SiS_Pr->SiS_SR15  = SiS310_SR15;
 
@@ -428,16 +510,6 @@
    SiS_Pr->pSiS_YCSenseData2    = &SiS310_YCSenseData2;
 #endif
 
-   SiS_Pr->SiS_NTSCPhase    = SiS310_NTSCPhase;
-   SiS_Pr->SiS_PALPhase     = SiS310_PALPhase;
-   SiS_Pr->SiS_NTSCPhase2   = SiS310_NTSCPhase2;
-   SiS_Pr->SiS_PALPhase2    = SiS310_PALPhase2;
-   SiS_Pr->SiS_PALMPhase    = SiS310_PALMPhase;
-   SiS_Pr->SiS_PALNPhase    = SiS310_PALNPhase;
-   SiS_Pr->SiS_PALMPhase2   = SiS310_PALMPhase2;
-   SiS_Pr->SiS_PALNPhase2   = SiS310_PALNPhase2;
-   SiS_Pr->SiS_SpecialPhase = SiS310_SpecialPhase;
-
    SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data;
    SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data;
    SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data;
@@ -446,66 +518,10 @@
    SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data;
    SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768;
    SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024;
-   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS310_LCD1280x960Data;
-   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1400x1050Data;
-   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1600x1200Data;
-   SiS_Pr->SiS_ExtLCD1280x768Data   = (SiS_LCDDataStruct *)SiS310_ExtLCD1280x768Data;
-   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS310_StLCD1400x1050Data;
-   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS310_StLCD1600x1200Data;
-   SiS_Pr->SiS_StLCD1280x768Data    = (SiS_LCDDataStruct *)SiS310_StLCD1280x768Data;
-   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS310_NoScaleData1400x1050;
-   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS310_NoScaleData1600x1200;
-   SiS_Pr->SiS_NoScaleData1280x768  = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x768;
-   SiS_Pr->SiS_NoScaleData          = (SiS_LCDDataStruct *)SiS310_NoScaleData;
-
-   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS310_StPALData;
-   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS310_ExtPALData;
-   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS310_StNTSCData;
-   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS310_ExtNTSCData;
-/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS310_St1HiTVData;  */
-   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS310_St2HiTVData;
-   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS310_ExtHiTVData;
-
-   SiS_Pr->SiS_NTSCTiming     = SiS310_NTSCTiming;
-   SiS_Pr->SiS_PALTiming      = SiS310_PALTiming;
-   SiS_Pr->SiS_HiTVSt1Timing  = SiS310_HiTVSt1Timing;
-   SiS_Pr->SiS_HiTVSt2Timing  = SiS310_HiTVSt2Timing;
-   SiS_Pr->SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
-   SiS_Pr->SiS_HiTVExtTiming  = SiS310_HiTVExtTiming;
-   SiS_Pr->SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
-   SiS_Pr->SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
-   SiS_Pr->SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
 
-   SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
+   SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
    SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS;
 
-   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_1;
-   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_2;
-   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_1;
-   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_2;
-   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_1;
-   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_2;
-   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_1;
-   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_2;
-   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_1;
-   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_2;
-   SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_1;
-   SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_2;
-   SiS_Pr->SiS_LVDS1280x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_1;
-   SiS_Pr->SiS_LVDS1280x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_2;
-   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_1;
-   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_2;
-   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_1;
-   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_2;
-   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS310_LVDSXXXxXXXData_1;
-   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS320x480Data_1;
-   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS640x480Data_1;
-   SiS_Pr->SiS_LCDA1400x1050Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_1;
-   SiS_Pr->SiS_LCDA1400x1050Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_2;
-   SiS_Pr->SiS_LCDA1600x1200Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_1;
-   SiS_Pr->SiS_LCDA1600x1200Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_2;
-   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVUNTSCData;
-   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVONTSCData;
    SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData;
    SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData;
    SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALMData;
@@ -513,6 +529,7 @@
    SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALNData;
    SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALNData;
    SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVSOPALData;
+
    SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1;
    SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1;
    SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1;
@@ -545,19 +562,7 @@
    SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_2;
    SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2;
    SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2;
-   SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_1;
-   SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_2;
-
-   SiS_Pr->LVDS1024x768Des_1  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_1;
-   SiS_Pr->LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_1;
-   SiS_Pr->LVDS1400x1050Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_1 ;
-   SiS_Pr->LVDS1600x1200Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_1 ;
-   SiS_Pr->LVDS1024x768Des_2  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_2;
-   SiS_Pr->LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_2;
-   SiS_Pr->LVDS1400x1050Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_2;
-   SiS_Pr->LVDS1600x1200Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_2 ;
 
-   /* TW: New from 650/301LV BIOS */
    SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1;
    SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1;
    SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1;
@@ -571,51 +576,32 @@
    SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3;
    SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3;
 
-   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUNTSCDesData;
-   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVONTSCDesData;
-   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVUPALDesData;
-   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVOPALDesData;
-
    SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1;
    SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1;
    SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1;
    SiS_Pr->SiS_LVDSCRT11400x1050_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1;
-   SiS_Pr->SiS_LVDSCRT11280x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1;
-   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1;
-   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1;
    SiS_Pr->SiS_LVDSCRT11600x1200_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1;
    SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H;
    SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H;
    SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H;
    SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H;
-   SiS_Pr->SiS_LVDSCRT11280x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1_H;
-   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1_H;
-   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1_H;
    SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H;
    SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2;
    SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2;
    SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2;
    SiS_Pr->SiS_LVDSCRT11400x1050_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2;
-   SiS_Pr->SiS_LVDSCRT11280x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2;
-   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2;
-   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2;
    SiS_Pr->SiS_LVDSCRT11600x1200_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2;
    SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H;
    SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H;
    SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H;
    SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H;
-   SiS_Pr->SiS_LVDSCRT11280x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2_H;
-   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2_H;
-   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2_H;
    SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H;
-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1;
-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1_H;
-   SiS_Pr->SiS_LVDSCRT1320x480_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1320x480_1;
-   SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
-   SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
-   SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
-   SiS_Pr->SiS_CHTVCRT1OPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
-   SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
+   SiS_Pr->SiS_CHTVCRT1UNTSC         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
+   SiS_Pr->SiS_CHTVCRT1ONTSC         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
+   SiS_Pr->SiS_CHTVCRT1UPAL          = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
+   SiS_Pr->SiS_CHTVCRT1OPAL          = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
+   SiS_Pr->SiS_CHTVCRT1SOPAL         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
+
    SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC;
    SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC;
    SiS_Pr->SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL;
@@ -625,6 +611,7 @@
    SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALN;
    SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALN;
    SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_SOPAL;
+
    SiS_Pr->SiS_LCDACRT1800x600_1     = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1;
    SiS_Pr->SiS_LCDACRT11024x768_1    = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1;
    SiS_Pr->SiS_LCDACRT11280x1024_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1;
@@ -645,6 +632,7 @@
    SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H;
    SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H;
    SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H;
+
    SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
    SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
    SiS_Pr->SiS_CHTVVCLKUPAL  = SiS310_CHTVVCLKUPAL;
@@ -667,9 +655,13 @@
    SiS_Pr->SiS_Panel1152x864  = Panel_1152x864;
    SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
    SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
+   SiS_Pr->SiS_Panel640x480_2 = Panel_640x480_2;
+   SiS_Pr->SiS_Panel640x480_3 = Panel_640x480_3;
    SiS_Pr->SiS_PanelMax       = Panel_320x480;    /* TW: highest value */
    SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* TW: lowest value LVDS/LCDA */
    SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* TW: lowest value 301 */
+   SiS_Pr->SiS_PanelCustom    = Panel_Custom;
+   SiS_Pr->SiS_PanelBarco1366 = 255;
 }
 #endif
 
@@ -732,7 +724,8 @@
       (HwDeviceExtension->jChipType == SIS_550) ||
       (HwDeviceExtension->jChipType == SIS_650) ||
       (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330))
+      (HwDeviceExtension->jChipType == SIS_330) ||
+      (HwDeviceExtension->jChipType == SIS_660))
      InitTo310Pointer(SiS_Pr, HwDeviceExtension);
 #endif
 
@@ -901,7 +894,8 @@
       (HwDeviceExtension->jChipType == SIS_550) ||
       (HwDeviceExtension->jChipType == SIS_650) ||
       (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330)) {
+      (HwDeviceExtension->jChipType == SIS_330) ||
+      (HwDeviceExtension->jChipType == SIS_660)) {
    	for(i=0x12; i<=0x1B; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
    	for(i=0x79; i<=0x7C; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
    }
@@ -958,14 +952,15 @@
    if((HwDeviceExtension->jChipType == SIS_315H)   ||
       (HwDeviceExtension->jChipType == SIS_315)    ||
       (HwDeviceExtension->jChipType == SIS_315PRO) ||
-      (HwDeviceExtension->jChipType == SIS_330) ) {
+      (HwDeviceExtension->jChipType == SIS_330)) {
       	if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
           	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A) & 0x03;
         }
    }
    if((HwDeviceExtension->jChipType == SIS_550) ||
       (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_650)) {
+      (HwDeviceExtension->jChipType == SIS_650) ||
+      (HwDeviceExtension->jChipType == SIS_660)) {
         if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
           	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
         }
@@ -982,7 +977,7 @@
    if((HwDeviceExtension->jChipType != SIS_540) &&
       (HwDeviceExtension->jChipType != SIS_630) &&
       (HwDeviceExtension->jChipType != SIS_730)){
-     	for(i=0x15;i<0x1C;i++) {
+     	for(i=0x15; i<0x1C; i++) {
        	    SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SiS_Pr->SiS_SR15[i-0x15][SiS_Pr->SiS_RAMType]);
      	}
    }
@@ -1028,7 +1023,8 @@
       (HwDeviceExtension->jChipType == SIS_550) ||
       (HwDeviceExtension->jChipType == SIS_650) ||
       (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330))
+      (HwDeviceExtension->jChipType == SIS_330) ||
+      (HwDeviceExtension->jChipType == SIS_660))
      	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2E,0x08);    /* use VB */
 #endif
 
@@ -1185,7 +1181,8 @@
 #ifdef SIS315H
   if((HwDeviceExtension->jChipType == SIS_650) ||
      (HwDeviceExtension->jChipType == SIS_740) ||
-     (HwDeviceExtension->jChipType == SIS_330)) {
+     (HwDeviceExtension->jChipType == SIS_330) ||
+     (HwDeviceExtension->jChipType == SIS_660)) {
 #if 0 /* TW: This is not required */
         /* TW: Read POWER_ON_TRAP and copy to CR37 */
     	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
@@ -1304,7 +1301,7 @@
 #endif
 /* ===============  SiS 300 dram sizing end    =============== */
 
-/* ============  SiS 310/325 dram sizing begin  ============== */
+/* ============  SiS 315 dram sizing begin  ============== */
 #ifdef SIS315H
 
 /* TW: Moved Get310DRAMType further down */
@@ -1898,8 +1895,7 @@
    if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
      data = *SiS_Pr->pSiS_SoftSetting & 0x03;
    } else {
-     if((HwDeviceExtension->jChipType > SIS_315PRO) &&
-        (HwDeviceExtension->jChipType < SIS_330)) {
+     if(IS_SIS550650740660) {
         data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
      } else {	/* TW: 315, 330 */
         data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
@@ -1939,13 +1935,17 @@
    SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
    SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
    SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
-   SiS_Pr->SiS_P3da = BaseAddr + 0x2A;
-   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;   /* Digital video interface registers (LCD) */
-   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;   /* 301 TV Encoder registers */
-   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;   /* 301 Macrovision registers */
-   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;   /* 301 VGA2 (and LCD) registers */
-   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14+2; /* 301 palette address port registers */
-   SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;                /* DDC Port ( = P3C4, SR11/0A) */
+   SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
+   SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
+   SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
+   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;     /* Digital video interface registers (LCD) */
+   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;     /* 301 TV Encoder registers */
+   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;     /* 301 Macrovision registers */
+   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;     /* 301 VGA2 (and LCD) registers */
+   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; /* 301 palette address port registers */
+   SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;                  /* DDC Port ( = P3C4, SR11/0A) */
+   SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
+   SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
 }
 
 void
@@ -1970,7 +1970,8 @@
       (HwDeviceExtension->jChipType == SIS_550) ||
       (HwDeviceExtension->jChipType == SIS_650) ||
       (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330)) {
+      (HwDeviceExtension->jChipType == SIS_330) ||
+      (HwDeviceExtension->jChipType == SIS_660)) {
       /* TW: This seems to be done the same way on these chipsets */
       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
@@ -1992,10 +1993,14 @@
 
    SiS_Pr->SiS_ChrontelInit = 0;
 
-   if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
-   	SiS_Pr->SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
-   	SiS_Pr->SiS_IF_DEF_FSTN = 1;   /* for fstn */
+#if 0
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
+   	 SiS_Pr->SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
+   	 SiS_Pr->SiS_IF_DEF_FSTN = 1;   /* for fstn */
+      }
    }
+#endif
 
 #ifdef SIS300
    if((HwDeviceExtension->jChipType == SIS_540) ||
@@ -2020,11 +2025,14 @@
    if((HwDeviceExtension->jChipType == SIS_550) ||
       (HwDeviceExtension->jChipType == SIS_650) ||
       (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330))
+      (HwDeviceExtension->jChipType == SIS_330) ||
+      (HwDeviceExtension->jChipType == SIS_660))
     {
-        /* TW: CR37 is different on 310/325 series */
+        /* TW: CR37 is different on 315 series */
+#if 0
         if(SiS_Pr->SiS_IF_DEF_FSTN)                       /* fstn: set CR37=0x04 */
              SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x04);      /* (fake LVDS bridge) */
+#endif
 
 	temp=SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
       	temp = (temp & 0x0E) >> 1;
@@ -2049,7 +2057,8 @@
       (HwDeviceExtension->jChipType == SIS_550) ||
       (HwDeviceExtension->jChipType == SIS_650) ||
       (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330))
+      (HwDeviceExtension->jChipType == SIS_330) ||
+      (HwDeviceExtension->jChipType == SIS_660))
      InitTo310Pointer(SiS_Pr, HwDeviceExtension);
 #endif
 
@@ -2078,14 +2087,21 @@
 	      SiS_Pr->SiS_UseROM = TRUE;
 	 else SiS_Pr->SiS_UseROM = FALSE;
      } else if(HwDeviceExtension->jChipType < SIS_315H) {
+#if 0
         /* TW: Rest of 300 series: We don't use the ROM image if
 	 *     the BIOS version < 2.0.0 as such old BIOSes don't
 	 *     have the needed data at the expected locations.
 	 */
         if(ROMAddr[0x06] < '2')  SiS_Pr->SiS_UseROM = FALSE;
 	else                     SiS_Pr->SiS_UseROM = TRUE;
+#else
+	/* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
+	 * the others do as well
+	 */
+	SiS_Pr->SiS_UseROM = TRUE;
+#endif
      } else {
-        /* TW: 310/325/330 series stick to the standard */
+        /* TW: 315/330 series stick to the standard */
 	SiS_Pr->SiS_UseROM = TRUE;
      }
    } else SiS_Pr->SiS_UseROM = FALSE;
@@ -2109,24 +2125,27 @@
    SiS_Pr->UseCustomMode = FALSE;
 
    if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
-   
-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", 
-	 	SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
-		
+
+         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
+	 	SiS_Pr->CHDisplay,
+		(mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
+		   (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
+		      SiS_Pr->CVDisplay)));
+
 	 return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
-   
+
    }
-   
-   ModeNo = SiS_CalcModeIndex(pScrn, mode);
+
+   ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes);
    if(!ModeNo) return FALSE;
 
-   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting mode 0x%x\n", ModeNo);
+   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
 
    return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));   
 }
 
 #ifdef SISDUALHEAD
-/* TW: Set CRT1 mode (used for dual head) */
+/* TW: Set CRT1 mode (used for dual head and MergedFB) */
 BOOLEAN
 SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
                DisplayModePtr mode, BOOLEAN IsCustom)
@@ -2139,31 +2158,37 @@
    SISEntPtr pSiSEnt = pSiS->entityPrivate;
    unsigned char backupreg=0;
    BOOLEAN backupcustom;
-
    UShort  ModeNo=0;
    
    SiS_Pr->UseCustomMode = FALSE;
-   
+
    if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
-   
+
+         USHORT temptemp = SiS_Pr->CVDisplay;
+
+         if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
+         else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
+
          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-	 	"Setting custom mode %dx%d in CRT1\n", 
-	 	SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
+	 	"Setting custom mode %dx%d on CRT1\n",
+	 	SiS_Pr->CHDisplay, temptemp);
 	 ModeNo = 0xfe;
-	 
+
    } else {
 
-         ModeNo = SiS_CalcModeIndex(pScrn, mode);
+         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes);
          if(!ModeNo) return FALSE;
 
          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-	 	"Setting mode 0x%x on CRT1\n", ModeNo);
+	 	"Setting standard mode 0x%x on CRT1\n", ModeNo);
    }
 
    SiSInitPtr(SiS_Pr, HwDeviceExtension);
 
    SiSRegInit(SiS_Pr, BaseAddr);
 
+   SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
+
    SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
 
    SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
@@ -2172,7 +2197,7 @@
 
    SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
 
-   /* TW: We don't clear the buffer under X */
+   /* We don't clear the buffer under X */
    SiS_Pr->SiS_flag_clearbuffer = 0;
 
    /* 1.Openkey */
@@ -2180,8 +2205,8 @@
 
    SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
 
+   /* 2.Get ModeID Table  */
    if(!SiS_Pr->UseCustomMode) {
-      /* 2.Get ModeID Table  */
       temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
       if(temp == 0)  return(0);
    } else {
@@ -2206,57 +2231,65 @@
    SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
 
    if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
             if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
+            SiS_Pr->SiS_SetFlag |= SetDOSMode;
          }
       }
 
-      /* TW: New from 650/LV 1.10.6x */
       if(IS_SIS650) {
-          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-	  }
+         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+	    if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+	 }
       }
    }
 
-   /* TW: Set mode on CRT1 */
+   /* Set mode on CRT1 */
    SiS_SetCRT1Group(SiS_Pr, ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
 
+   /* SetPitch: Adapt to virtual size & position */
+   SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
+
    if(pSiS->DualHeadMode) {
       pSiSEnt->CRT1ModeNo = ModeNo;
       pSiSEnt->CRT1DMode = mode;
    }
 
-   /* TW: SetPitch: Adapt to virtual size & position */
-   SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
+   if(SiS_Pr->UseCustomMode) {
+      SiS_Pr->CRT1UsesCustomMode = TRUE;
+      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
+      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
+   } else {
+      SiS_Pr->CRT1UsesCustomMode = FALSE;
+   }
 
    /* We have to reset CRT2 if changing mode on CRT1 */
    if(pSiS->DualHeadMode) {
       if(pSiSEnt->CRT2ModeNo != -1) {
          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-				"(Re-)Setting mode 0x%x on CRT2\n",
-				pSiSEnt->CRT2ModeNo);
+				"(Re-)Setting mode for CRT2\n");
 	 backupcustom = SiS_Pr->UseCustomMode;
-	 if(SiS_Pr->UseCustomMode) {
-	    SiS_Pr->CRT1UsesCustomMode = TRUE;
-	 } else {
-	    SiS_Pr->CRT1UsesCustomMode = FALSE;
-	 }
 	 SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
-				pSiSEnt->CRT2DMode);
+			    pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
 	 SiS_Pr->UseCustomMode = backupcustom;
-	 SiS_Pr->CRT1UsesCustomMode = FALSE;
       }
    }
-   
+
+   /* Warning: From here, the custom mode entries in SiS_Pr are
+    * possibly overwritten
+    */
+
    SiS_HandleCRT1(SiS_Pr);
 
+   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
+
    SiS_DisplayOn(SiS_Pr);
    SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
 
-   /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630/301B 2.06.50 */
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
       if(HwDeviceExtension->jChipType >= SIS_315H) {
 	 SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
@@ -2275,7 +2308,7 @@
 /* TW: Set CRT2 mode (used for dual head) */
 BOOLEAN
 SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
-               DisplayModePtr mode)
+               DisplayModePtr mode, BOOLEAN IsCustom)
 {
    ULONG   temp;
    USHORT  ModeIdIndex;
@@ -2285,33 +2318,39 @@
    SISPtr  pSiS     = SISPTR(pScrn);
    SISEntPtr pSiSEnt = pSiS->entityPrivate;
    unsigned char tempr1, tempr2, backupreg=0;
-   
+
    SiS_Pr->UseCustomMode = FALSE;
-   
-   ModeNo = SiS_CalcModeIndex(pScrn, mode);
-   if(!ModeNo) return FALSE;
 
-   SiSInitPtr(SiS_Pr, HwDeviceExtension);
+   /* Remember: Custom modes for CRT2 are ONLY supported
+    * 		-) on 315/330 series,
+    *           -) on the 301 and 30xB, and
+    *           -) if CRT2 is LCD or VGA
+    */
 
-   SiSRegInit(SiS_Pr, BaseAddr);
+   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
 
-   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+	 ModeNo = 0xfe;
 
-   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+   } else {
 
-   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+         BOOLEAN havecustommodes = pSiS->HaveCustomModes;
 
-   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+#ifdef SISMERGED
+	 if(pSiS->MergedFB) havecustommodes = pSiS->HaveCustomModes2;
+#endif
 
-   /* TW: We don't clear the buffer under X */
-   SiS_Pr->SiS_flag_clearbuffer=0;
+         ModeNo = SiS_CalcModeIndex(pScrn, mode, havecustommodes);
+         if(!ModeNo) return FALSE;
+
+   }
 
-   /* TW: Save ModeNo so we can set it from within SetMode for CRT1 */
+   /* Save mode info so we can set it from within SetMode for CRT1 */
    if(pSiS->DualHeadMode) {
       pSiSEnt->CRT2ModeNo = ModeNo;
       pSiSEnt->CRT2DMode = mode;
+      pSiSEnt->CRT2IsCustom = IsCustom;
 
-      /* TW: We can't set CRT2 mode before CRT1 mode is set */
+      /* We can't set CRT2 mode before CRT1 mode is set */
       if(pSiSEnt->CRT1ModeNo == -1) {
     	 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
 		"Setting CRT2 mode delayed until after setting CRT1 mode\n");
@@ -2319,8 +2358,40 @@
       }
    }
 
-   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-   		"Setting mode 0x%x on CRT2\n", ModeNo);
+   SiSInitPtr(SiS_Pr, HwDeviceExtension);
+
+   SiSRegInit(SiS_Pr, BaseAddr);
+
+   SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
+
+   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+
+   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+
+   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+
+   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+
+   /* We don't clear the buffer under X */
+   SiS_Pr->SiS_flag_clearbuffer=0;
+
+   if(SiS_Pr->UseCustomMode) {
+
+      USHORT temptemp = SiS_Pr->CVDisplay;
+
+      if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
+      else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
+
+      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+	  "Setting custom mode %dx%d on CRT2\n",
+	  SiS_Pr->CHDisplay, temptemp);
+
+   } else {
+
+      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+   	  "Setting standard mode 0x%x on CRT2\n", ModeNo);
+
+   }
 
    /* 1.Openkey */
    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
@@ -2328,10 +2399,14 @@
    SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
 
    /* 2.Get ModeID */
-   temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
-   if(temp == 0)  return(0);
+   if(!SiS_Pr->UseCustomMode) {
+      temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
+      if(temp == 0)  return(0);
+   } else {
+      ModeIdIndex = 0;
+   }
 
-   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
+   /* Determine VBType (301,301B,301LV,302B,302LV) */
    SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
 
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
@@ -2354,15 +2429,22 @@
       }
    }
 
-   /* TW: Get VB information (connectors, connected devices) */
-   SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
+   /* Get VB information (connectors, connected devices) */
+   if(!SiS_Pr->UseCustomMode) {
+      SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
+   } else {
+      /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
+      SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
+   }
    SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
    SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
 
    if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
             if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
+            SiS_Pr->SiS_SetFlag |= SetDOSMode;
          }
       }
    }
@@ -2375,17 +2457,19 @@
      case VB_CHIP_302:
      case VB_CHIP_302B:
      case VB_CHIP_302LV:
-        SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        SiS_SetCRT2Group(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
         break;
      case VB_CHIP_UNKNOWN:
-        if (SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
-	    SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
-	    SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
-             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        if(SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
+	   SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
+	   SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
+           SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
   	}
         break;
    }
 
+   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
+
    SiS_DisplayOn(SiS_Pr);
    SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
 
@@ -2397,7 +2481,6 @@
       }
    }
 
-   /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630 2.06.50 */
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
       if(HwDeviceExtension->jChipType >= SIS_315H) {
 	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
@@ -2423,7 +2506,7 @@
       }
    }
 
-   /* TW: SetPitch: Adapt to virtual size & position */
+   /* SetPitch: Adapt to virtual size & position */
    SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
 
    return TRUE;
@@ -2459,6 +2542,8 @@
 
    SiSRegInit(SiS_Pr, BaseAddr);
 
+   SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
+
 #ifdef LINUX_XF86
    if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
    else
@@ -2469,7 +2554,7 @@
 #ifdef TWDEBUG
    xf86DrvMsg(0, X_INFO, "VGAInfo 0x%02x\n", SiS_Pr->SiS_VGAINFO);
 #endif
-#endif	 	 
+#endif
 
    SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
 
@@ -2483,7 +2568,7 @@
    }      
 
 #ifdef LINUX_XF86
-   /* TW: We never clear the buffer in X */
+   /* We never clear the buffer in X */
    ModeNo |= 0x8000;
 #endif
 
@@ -2512,10 +2597,10 @@
       
    }
     
-   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
+   /* Determine VBType (301,301B,301LV,302B,302LV) */
    SiS_GetVBType(SiS_Pr,BaseAddr,HwDeviceExtension);
 
-   /* TW: Init/restore some VB registers */
+   /* Init/restore some VB registers */
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
        if(HwDeviceExtension->jChipType >= SIS_315H) {
          SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
@@ -2536,8 +2621,12 @@
        }
    }
    
-   /* TW: Get VB information (connectors, connected devices) */
-   SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
+   /* Get VB information (connectors, connected devices) */
+   if(SiS_Pr->UseCustomMode) {
+      SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
+   } else {
+      SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
+   }
    SiS_SetHiVision(SiS_Pr,BaseAddr,HwDeviceExtension);
    SiS_GetLCDResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
 
@@ -2546,22 +2635,32 @@
    if(!temp) return(0);
 
    if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
             if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
+            SiS_Pr->SiS_SetFlag |= SetDOSMode;
          }
       }
 
-      /* TW: New from 650/LV 1.10.6x; not in any BIOS for other chipsets */
       if(IS_SIS650) {
-          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-	  }
+         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+	    if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+	 }
       }
    }
 
-   /* TW: Set mode on CRT1 */
+   if(SiS_Pr->UseCustomMode) {
+      SiS_Pr->CRT1UsesCustomMode = TRUE;
+      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
+      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
+   } else {
+      SiS_Pr->CRT1UsesCustomMode = FALSE;
+   }
+
+   /* Set mode on CRT1 */
    if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
    	SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
    } else {
@@ -2570,7 +2669,7 @@
      }
    }
 
-   /* TW: Set mode on CRT2 */
+   /* Set mode on CRT2 */
    if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {
      switch (HwDeviceExtension->ujVBChipID) {
      case VB_CHIP_301:
@@ -2579,18 +2678,20 @@
      case VB_CHIP_302:
      case VB_CHIP_302B:
      case VB_CHIP_302LV:
-        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
         break;
      case VB_CHIP_UNKNOWN:
 	if(SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
 	   SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
 	   SiS_Pr->SiS_IF_DEF_TRUMPION != 0)
-             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+           SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
         break;
      }
    }
    
    SiS_HandleCRT1(SiS_Pr);
+
+   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
    
    SiS_DisplayOn(SiS_Pr);
    SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
@@ -2603,7 +2704,6 @@
       }
    }
 
-   /* TW: New from 650/LV 1.10.6x and 1.10.7w */
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
       if(HwDeviceExtension->jChipType >= SIS_315H) {
 	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
@@ -2638,7 +2738,7 @@
 
 #ifdef LINUX_XF86
    if(pScrn) {
-      /* TW: SetPitch: Adapt to virtual size & position */
+      /* SetPitch: Adapt to virtual size & position */
       if((ModeNo > 0x13) && (dosetpitch)) {
          SiS_SetPitch(SiS_Pr, pScrn, BaseAddr);
       }
@@ -2648,7 +2748,7 @@
    }
 #endif
 
-#ifndef LINUX_XF86  /* TW: We never lock registers in XF86 */
+#ifndef LINUX_XF86  /* We never lock registers in XF86 */
    if(KeepLockReg == 0xA1) SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
    else SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x00);
 #endif
@@ -2657,10 +2757,15 @@
 }
 
 void
-SiS_SetEnableDstn(SiS_Private *SiS_Pr)	/* TW: Called from sis_main.c */
+SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable)
+{
+   SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
+}
+
+void
+SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable)
 {
-   /* For 550 dstn */
-   SiS_Pr->SiS_IF_DEF_DSTN = 1;
+   SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
 }
 
 void
@@ -2674,13 +2779,73 @@
   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
 
 #if 0
-  if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01))
-     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
+  if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
+     if((SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
+        (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
+        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
+     }
   }
 #endif
 }
 
 void
+SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   unsigned char cr5f, temp1, temp2;
+
+   /* You should use the macros, not these flags directly */
+
+   SiS_Pr->SiS_SysFlags = 0;
+   if(HwDeviceExtension->jChipType == SIS_650) {
+      cr5f = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
+      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
+      temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
+      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
+      temp2 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
+      if((!temp1) || (temp2)) {
+         switch(cr5f) {
+	    case 0x80:
+	    case 0x90:
+	    case 0xc0:
+	       SiS_Pr->SiS_SysFlags |= SF_IsM650;  break;
+	    case 0xa0:
+	    case 0xb0:
+	    case 0xe0:
+	       SiS_Pr->SiS_SysFlags |= SF_Is651;   break;
+	 }
+      } else {
+         switch(cr5f) {
+	    case 0x90:
+	       temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
+	       switch(temp1) {
+	          case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
+		  case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
+		  default:   SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
+	       }
+	       break;
+	    case 0xb0:
+	       SiS_Pr->SiS_SysFlags |= SF_Is652;  break;
+	    default:
+	       SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
+	 }
+      }
+   }
+}
+
+void
+SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   if((IS_SIS651) || (IS_SISM650)) {
+      SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x3f, 0x00);   /* Fiddle with capture regs */
+      SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
+      SiS_SetReg1(SiS_Pr->SiS_VidPlay, 0x00, 0x86);   /* (BIOS does NOT unlock) */
+      SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe); /* Fiddle with video regs */
+      SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
+   }
+   /* !!! This does not support modes < 0x13 !!! */
+}
+
+void
 SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
                  USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr)
 {
@@ -2694,6 +2859,9 @@
     }
   }
 
+  /* 550, 651 */
+  SiS_WhatTheHellIsThis(SiS_Pr,HwDeviceExtension,BaseAddr);
+
   SiS_SetSeqRegs(SiS_Pr,ROMAddr,StandTableIndex);
   SiS_SetMiscRegs(SiS_Pr,ROMAddr,StandTableIndex);
   SiS_SetCRTCRegs(SiS_Pr,ROMAddr,HwDeviceExtension,StandTableIndex);
@@ -2770,15 +2938,20 @@
 SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
 {
    SISPtr pSiS = SISPTR(pScrn);
+   BOOLEAN isslavemode = FALSE;
 
-   /* TW: We need to set pitch for CRT1 if bridge is in SlaveMode, too */
-   if( (pSiS->VBFlags & DISPTYPE_DISP1) ||
-       ( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
-         ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
-           ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) {
+   if( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
+       ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
+         ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
+      isslavemode = TRUE;
+   }
+
+   /* We need to set pitch for CRT1 if bridge is in slave mode, too */
+   if( (pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode) ) {
    	SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
    }
-   if (pSiS->VBFlags & DISPTYPE_DISP2) {
+   /* We must not set the pitch for CRT2 if bridge is in slave mode */
+   if( (pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode) ) {
    	SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
    }
 }
@@ -2801,7 +2974,7 @@
     SISPtr pSiS = SISPTR(pScrn);
     ULong  HDisplay,temp;
 
-    HDisplay = pSiS->scrnPitch / 8;
+    HDisplay = pSiS->scrnPitch2 / 8;
 
     /* Unlock CRT2 */
     if (pSiS->VGAEngine == SIS_315_VGA)
@@ -2891,7 +3064,6 @@
    return TRUE;
 }
 
-/* For SiS 300 oem util: Search VBModeID */
 BOOLEAN
 SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo)
 {
@@ -2957,6 +3129,81 @@
    return index;
 }
 
+static void
+SiS_WhatIsThis1a(SiS_Private *SiS_Pr, USHORT somevalue)
+{
+   USHORT temp, tempbl, tempbh;
+
+   tempbl = tempbh = somevalue;
+   temp = SiS_GetReg2(SiS_Pr->SiS_P3cb);
+   temp &= 0xf0;
+   tempbl >>= 4;
+   temp |= tempbl;
+   SiS_SetReg3(SiS_Pr->SiS_P3cb, temp);
+   temp = SiS_GetReg2(SiS_Pr->SiS_P3cd);
+   temp &= 0xf0;
+   tempbh &= 0x0f;
+   temp |= tempbh;
+   SiS_SetReg3(SiS_Pr->SiS_P3cd, temp);
+}
+
+static void
+SiS_WhatIsThis1b(SiS_Private *SiS_Pr, USHORT somevalue)
+{
+   USHORT temp, tempbl, tempbh;
+
+   tempbl = tempbh = somevalue;
+   temp = SiS_GetReg2(SiS_Pr->SiS_P3cb);
+   temp &= 0x0f;
+   tempbl &= 0xf0;
+   temp |= tempbl;
+   SiS_SetReg3(SiS_Pr->SiS_P3cb, temp);
+   temp = SiS_GetReg2(SiS_Pr->SiS_P3cd);
+   temp &= 0x0f;
+   tempbh <<= 4;
+   temp |= tempbh;
+   SiS_SetReg3(SiS_Pr->SiS_P3cd, temp);
+}
+
+static void
+SiS_WhatIsThis2b(SiS_Private *SiS_Pr, USHORT somevalue)
+{
+   SiS_WhatIsThis1a(SiS_Pr, somevalue);
+   SiS_WhatIsThis1b(SiS_Pr, somevalue);
+}
+
+static void
+SiS_WhatIsThis1(SiS_Private *SiS_Pr)
+{
+   SiS_WhatIsThis2b(SiS_Pr, 0);
+}
+
+static void
+SiS_WhatIsThis2a(SiS_Private *SiS_Pr, USHORT somevalue)
+{
+   USHORT temp = somevalue >> 8;
+
+   temp &= 0x07;
+   temp |= (temp << 4);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1d,temp);
+   SiS_WhatIsThis2b(SiS_Pr, somevalue);
+}
+
+static void
+SiS_WhatIsThis2(SiS_Private *SiS_Pr)
+{
+   SiS_WhatIsThis2a(SiS_Pr, 0);
+}
+
+void
+SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+   if(IS_SIS65x) {
+      SiS_WhatIsThis1(SiS_Pr);
+      SiS_WhatIsThis2(SiS_Pr);
+   }
+}
+
 void
 SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
 {
@@ -3038,7 +3285,7 @@
       (HwDeviceExtension->jChipRevision >= 0x30) ) {       	   /* for 630S0 */
     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
+         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
       }
     }
   }
@@ -3076,7 +3323,7 @@
       }
       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
          if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    if(IS_SIS650740 || IS_SIS550) {  
+	    if(IS_SIS550650740660) {
 	       /* 315, 330 don't do this */
 	       if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { 
 	          if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
@@ -3159,7 +3406,7 @@
   USHORT tempah,i,modeflag,j;
 #ifdef SIS315H
   USHORT temp;
-  USHORT ResInfo,DisplayType;
+  USHORT ResIndex,DisplayType;
   const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
 #endif
 
@@ -3182,7 +3429,7 @@
      /* LCDA */
 
      temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                       RefreshRateTableIndex,&ResInfo,&DisplayType);
+                       RefreshRateTableIndex,&ResIndex,&DisplayType);
 
      switch(DisplayType) {
       case Panel_800x600       : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1;      break;
@@ -3208,30 +3455,30 @@
       default:                   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
      }
 
-     tempah = (LCDACRT1Ptr+ResInfo)->CR[0];
+     tempah = (LCDACRT1Ptr+ResIndex)->CR[0];
      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
      for(i=0x01,j=1;i<=0x07;i++,j++){
-       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
      }
      for(i=0x10,j=8;i<=0x12;i++,j++){
-       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
      }
      for(i=0x15,j=11;i<=0x16;i++,j++){
-       tempah =(LCDACRT1Ptr+ResInfo)->CR[j];
+       tempah =(LCDACRT1Ptr+ResIndex)->CR[j];
        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
      }
      for(i=0x0A,j=13;i<=0x0C;i++,j++){
-       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
        SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
      }
 
-     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
+     tempah = (LCDACRT1Ptr+ResIndex)->CR[16];
      tempah &= 0x0E0;
      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
 
-     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
+     tempah = (LCDACRT1Ptr+ResIndex)->CR[16];
      tempah &= 0x01;
      tempah <<= 5;
      if(modeflag & DoubleScanMode)  tempah |= 0x080;
@@ -3312,7 +3559,7 @@
 
 BOOLEAN
 SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
+		   USHORT RefreshRateTableIndex,USHORT *ResIndex,
 		   USHORT *DisplayType)
  {
   USHORT tempbx=0,modeflag=0;
@@ -3331,7 +3578,7 @@
   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 32;
   if(modeflag & HalfDCLK)                 tempbx += 16;
 
-  *ResInfo = CRT2CRTC & 0x3F;
+  *ResIndex = CRT2CRTC & 0x3F;
   *DisplayType = tempbx;
 
   return 1;
@@ -3501,11 +3748,11 @@
 
   data2 = 0;
   if(ModeNo > 0x13) {
-    if(SiS_Pr->SiS_ModeType > 0x02) {
-       data2 |= 0x02;
-       data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
-       data2 |= data3;
-    }
+     if(SiS_Pr->SiS_ModeType > 0x02) {
+        data2 |= 0x02;
+        data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
+        data2 |= data3;
+     }
   }
 #ifdef TWDEBUG
   xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n", 
@@ -3528,7 +3775,8 @@
   if(HwDeviceExtension->jChipType != SIS_300) {
      data = 0x0000;
      if(infoflag & InterlaceMode) {
-        if(xres == 1024) data = 0x0035;
+        if(xres <= 800)  data = 0x0020;
+        else if(xres <= 1024) data = 0x0035;
         else data = 0x0048;
      }
      data2 = data & 0x00FF;
@@ -3539,17 +3787,6 @@
 
   if(modeflag & HalfDCLK) {
      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
-     /* @@@@ TEST |||| */
-#if 0
-     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0x7F);
-     if(xres < 512) {
-	if(modeflag & DoubleScanMode) {
-           SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x80);
-           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xF7);
-        }
-     }
-#endif     
-     /* TEST END */
   }
 
   if(HwDeviceExtension->jChipType == SIS_300) {
@@ -3571,6 +3808,7 @@
      } else {
         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
      }
+     /* 651 BIOS does something for mode 0x12 here */
   }
 
   if(HwDeviceExtension->jChipType != SIS_300) {
@@ -3701,7 +3939,7 @@
     if(VCLK >= 150) data2 |= 0x08;       	/* VCLK > 150 */
     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
 
-  } else { 						/* 310/325 series */
+  } else { 						/* 315 series */
 
     data = 0;
     if(VCLK >= 166) data |= 0x0c;         	/* TW: Was 200; is 166 in 650, 315 and 330 BIOSes */
@@ -3710,12 +3948,6 @@
     if(VCLK >= 166) {				/* TW: Was 200, is 166 in 650, 315 and 330 BIOSes */
        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
     }
-#if 0 /* Not done in 315 and 650/301LV/LVDS BIOSes: */
-    data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);	  	/* DAC pedestal */
-    data &= 0xE7;
-    if(VCLK<200) data |= 0x10;
-    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,data);	  	/* DAC pedestal */
-#endif
   }
 
   data2 = 0x03;
@@ -3940,7 +4172,8 @@
 
   } else if((HwDeviceExtension->jChipType == SIS_550) ||
             (HwDeviceExtension->jChipType == SIS_740) ||
-            (HwDeviceExtension->jChipType == SIS_650)) {
+            (HwDeviceExtension->jChipType == SIS_650) ||
+	    (HwDeviceExtension->jChipType == SIS_660)) {
 
   	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
       	counter++;
@@ -4750,7 +4983,7 @@
           SiS_Pr->SiS_SetFlag = 0x00;
           SiS_Pr->SiS_ModeType = ModeVGA;
           SiS_Pr->SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
-          SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+          SiS_SetCRT2Group(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
           for(i=0;i<20;i++) {
             SiS_LongWait(SiS_Pr);
           }
@@ -4788,7 +5021,7 @@
 #ifdef SIS315H
 	   if(HwDeviceExtension->jChipType >= SIS_315H) {
 	        OutputSelect = ROMAddr[0xf3];
-		if(HwDeviceExtension->jChipType == SIS_330) {
+		if(HwDeviceExtension->jChipType >= SIS_330) {
 		     OutputSelect = ROMAddr[0x11b];
 		}
 	   }
@@ -4836,7 +5069,7 @@
       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,P2reg0);
       if(!(P2reg0 & 0x20)) {
         SiS_Pr->SiS_VBInfo = DisableCRT2Display;
-        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+        SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
       }
     }
   }
@@ -4906,111 +5139,6 @@
 }
 #endif /* LINUXBIOS */
 
-/*  ================ for TC only =================  */
-
-#ifdef TC
-
-int
-INT1AReturnCode(union REGS regs)
-{
-  if (regs.x.cflag)
-  {
-    /*printf("Error to find pci device!\n"); */
-    return 1;
-  }
-
-  switch(regs.h.ah)
-  {
-    case 0: return 0;
-            break;
-    case 0x81: printf("Function not support\n");
-               break;
-    case 0x83: printf("bad vendor id\n");
-               break;
-    case 0x86: printf("device not found\n");
-               break;
-    case 0x87: printf("bad register number\n");
-               break;
-    case 0x88: printf("set failed\n");
-               break;
-    case 0x89: printf("buffer too small");
-               break;
-  }
-  return 1;
-}
-
-unsigned
-FindPCIIOBase(unsigned index,unsigned deviceid)
-{
-  union REGS regs;
-
-  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
-  regs.h.al = 0x02;  /*FIND_PCI_DEVICE */
-  regs.x.cx = deviceid;
-  regs.x.dx = 0x1039;
-  regs.x.si = index;  /* find n-th device */
-
-  int86(0x1A, &regs, &regs);
-
-  if (INT1AReturnCode(regs)!=0)
-    return 0;
-
-  /* regs.h.bh *//* bus number */
-  /* regs.h.bl *//* device number */
-  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
-  regs.h.al = 0x09;  /*READ_CONFIG_WORD */
-  regs.x.cx = deviceid;
-  regs.x.dx = 0x1039;
-  regs.x.di = 0x18;  /* register number */
-  int86(0x1A, &regs, &regs);
-
-  if (INT1AReturnCode(regs)!=0)
-    return 0;
-  return regs.x.cx;
-}
-
-
-void
-main(int argc, char *argv[])
-{
-  SIS_HW_DEVICE_INFO  HwDeviceExtension;
-  USHORT temp;
-  USHORT ModeNo;
-
-  /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
-  /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/
-
-#ifdef SIS300  
-  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30;
-  HwDeviceExtension.jChipType = SIS_630;
-#endif
-
-#ifdef SIS315H  
-//  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x5315)&0xFF80) + 0x30;
-//  HwDeviceExtension.jChipType = SIS_550;
-  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x325)&0xFF80) + 0x30;
-  HwDeviceExtension.jChipType = SIS_315H;
-#endif
-
-  HwDeviceExtension.ujVBChipID = VB_CHIP_301;
-  strcpy(HwDeviceExtension.szVBIOSVer,"0.84");
-  HwDeviceExtension.bSkipDramSizing = FALSE;
-  HwDeviceExtension.ulVideoMemorySize = 0;
-  if(argc==2) {
-    ModeNo=atoi(argv[1]);
-  }
-  else {
-    ModeNo=0x2e;
-    /*ModeNo=0x37; */ /* 1024x768x 4bpp */
-    /*ModeNo=0x38; *//* 1024x768x 8bpp */
-    /*ModeNo=0x4A; *//* 1024x768x 16bpp */
-    /*ModeNo=0x47;*/ /* 800x600x 16bpp */
-  }
- /* SiSInit(SiS_Pr, &HwDeviceExtension);*/
-  SiSSetMode(SiS_Pr, &HwDeviceExtension, ModeNo);
-}
-#endif /* TC END */
-
 /* ================ XFREE86 ================= */
 
 /* Helper functions */
@@ -5022,47 +5150,78 @@
    SISPtr pSiS = SISPTR(pScrn);
    int    out_n, out_dn, out_div, out_sbit, out_scale;
    int    depth = pSiS->CurrentLayout.bitsPerPixel;
+   unsigned int vclk[5];
 
-#ifdef SISMERGED
-   if(!pSiS->MergedFB)
-#endif   
-#ifdef SISDUALHEAD
-      if( ((!pSiS->DualHeadMode) && (VBFlags & DISPTYPE_DISP2)) ||
-          ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) ) return 0;
-#else
-      if(VBFlags & DISPTYPE_DISP2) return 0;
-#endif   
+#define Midx         0
+#define Nidx         1
+#define VLDidx       2
+#define Pidx         3
+#define PSNidx       4
+
+   pSiS->SiS_Pr->CModeFlag = 0;
    
    pSiS->SiS_Pr->CDClock = mode->Clock;
-   
+
    pSiS->SiS_Pr->CHDisplay = mode->HDisplay;
    pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart;
    pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
    pSiS->SiS_Pr->CHTotal = mode->HTotal;
-   pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
-   pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
-   
+
    pSiS->SiS_Pr->CVDisplay = mode->VDisplay;
    pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart;
    pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
    pSiS->SiS_Pr->CVTotal = mode->VTotal;
+
+   pSiS->SiS_Pr->CFlags = mode->Flags;
+
+   if(pSiS->SiS_Pr->CFlags & V_INTERLACE) {
+         pSiS->SiS_Pr->CVDisplay >>= 1;
+	 pSiS->SiS_Pr->CVSyncStart >>= 1;
+	 pSiS->SiS_Pr->CVSyncEnd >>= 1;
+	 pSiS->SiS_Pr->CVTotal >>= 1;
+   }
+   if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) {
+         /* pSiS->SiS_Pr->CDClock <<= 1; */
+	 pSiS->SiS_Pr->CVDisplay <<= 1;
+	 pSiS->SiS_Pr->CVSyncStart <<= 1;
+	 pSiS->SiS_Pr->CVSyncEnd <<= 1;
+	 pSiS->SiS_Pr->CVTotal <<= 1;
+   }
+
+   pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
+   pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
    pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
    pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
-   
-   pSiS->SiS_Pr->CFlags = mode->Flags;
 
-   SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale);
-   
+   if(SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
+      pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
+      pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
+      pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
+      pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
+      pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
+#ifdef TWDEBUG
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
+        	pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
+#endif
+   } else {
+      SiSCalcClock(pScrn, pSiS->SiS_Pr->CDClock, 2, vclk);
+      pSiS->SiS_Pr->CSR2B = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
+      pSiS->SiS_Pr->CSR2B |= (vclk[Midx] - 1) & 0x7f;
+      pSiS->SiS_Pr->CSR2C = (vclk[Nidx] - 1) & 0x1f;
+      if(vclk[Pidx] <= 4) {
+         /* postscale 1,2,3,4 */
+         pSiS->SiS_Pr->CSR2C |= ((vclk[Pidx] - 1) & 3) << 5;
+      } else {
+         /* postscale 6,8 */
+         pSiS->SiS_Pr->CSR2C |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
+	 pSiS->SiS_Pr->CSR2C |= 0x80;
+      }
 #ifdef TWDEBUG
-   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
-      	pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
-#endif	
-
-   pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
-   pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
-   pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
-   pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
-   pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
+        	pSiS->SiS_Pr->CDClock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
+#endif
+   }
+
    pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
 
    pSiS->SiS_Pr->CCRT1CRTC[0]  =  ((pSiS->SiS_Pr->CHTotal >> 3) - 5) & 0xff;
@@ -5070,9 +5229,9 @@
    pSiS->SiS_Pr->CCRT1CRTC[2]  =  (pSiS->SiS_Pr->CHBlankStart >> 3) - 1;
    pSiS->SiS_Pr->CCRT1CRTC[3]  =  (((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
    pSiS->SiS_Pr->CCRT1CRTC[4]  =  (pSiS->SiS_Pr->CHSyncStart >> 3) + 3;
-   pSiS->SiS_Pr->CCRT1CRTC[5]  =  ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | 
+   pSiS->SiS_Pr->CCRT1CRTC[5]  =  ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |
        				  (((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
-   
+
    pSiS->SiS_Pr->CCRT1CRTC[6]  =  (pSiS->SiS_Pr->CVTotal - 2) & 0xFF;
    pSiS->SiS_Pr->CCRT1CRTC[7]  =  (((pSiS->SiS_Pr->CVTotal - 2) & 0x100) >> 8)
  	 			| (((pSiS->SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
@@ -5082,50 +5241,50 @@
 	 			| (((pSiS->SiS_Pr->CVTotal - 2) & 0x200)   >> 4)
 	 			| (((pSiS->SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
 	 			| ((pSiS->SiS_Pr->CVSyncStart & 0x200) >> 2);
-    
+
    pSiS->SiS_Pr->CCRT1CRTC[16] = ((((pSiS->SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); 	/* cr9 */
-    
-#if 0    
+
+#if 0
    if (mode->VScan >= 32)
 	regp->CRTC[9] |= 0x1F;
    else if (mode->VScan > 1)
 	regp->CRTC[9] |= mode->VScan - 1;
-#endif	
+#endif
 
-   pSiS->SiS_Pr->CCRT1CRTC[8] =  (pSiS->SiS_Pr->CVSyncStart - 1) & 0xFF;	/* cr10 */
-   pSiS->SiS_Pr->CCRT1CRTC[9] =  ((pSiS->SiS_Pr->CVSyncEnd - 1) & 0x0F) | 0x80;	/* cr11 */
-   pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF;		/* cr12 */
-   pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF;	/* cr15 */
-   pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF;		/* cr16 */
-   
-   pSiS->SiS_Pr->CCRT1CRTC[13] = 
+   pSiS->SiS_Pr->CCRT1CRTC[8] =  (pSiS->SiS_Pr->CVSyncStart     ) & 0xFF;		/* cr10 */
+   pSiS->SiS_Pr->CCRT1CRTC[9] =  ((pSiS->SiS_Pr->CVSyncEnd      ) & 0x0F) | 0x80;	/* cr11 */
+   pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay    - 1) & 0xFF;		/* cr12 */
+   pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF;		/* cr15 */
+   pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd   - 1) & 0xFF;		/* cr16 */
+
+   pSiS->SiS_Pr->CCRT1CRTC[13] =
                         GETBITSTR((pSiS->SiS_Pr->CVTotal     -2), 10:10, 0:0) |
                         GETBITSTR((pSiS->SiS_Pr->CVDisplay   -1), 10:10, 1:1) |
                         GETBITSTR((pSiS->SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
                         GETBITSTR((pSiS->SiS_Pr->CVSyncStart   ), 10:10, 3:3) |
                         GETBITSTR((pSiS->SiS_Pr->CVBlankEnd  -1),   8:8, 4:4) |
-                        GETBITSTR((pSiS->SiS_Pr->CVSyncEnd   -1),   4:4, 5:5) ;  
+                        GETBITSTR((pSiS->SiS_Pr->CVSyncEnd     ),   4:4, 5:5) ;
 
-   pSiS->SiS_Pr->CCRT1CRTC[14] = 
+   pSiS->SiS_Pr->CCRT1CRTC[14] =
                         GETBITSTR((pSiS->SiS_Pr->CHTotal      >> 3) - 5, 9:8, 1:0) |
                         GETBITSTR((pSiS->SiS_Pr->CHDisplay    >> 3) - 1, 9:8, 3:2) |
                         GETBITSTR((pSiS->SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
                         GETBITSTR((pSiS->SiS_Pr->CHSyncStart  >> 3) + 3, 9:8, 7:6) ;
 
-        
+
    pSiS->SiS_Pr->CCRT1CRTC[15] =
                         GETBITSTR((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
-                        GETBITSTR((pSiS->SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ; 
-			
+                        GETBITSTR((pSiS->SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ;
+
    switch(depth) {
-   case 8: 			
-      	pSiS->SiS_Pr->CModeFlag = 0x223b;
+   case 8:
+      	pSiS->SiS_Pr->CModeFlag |= 0x223b;
 	break;
-   case 16: 			
-      	pSiS->SiS_Pr->CModeFlag = 0x227d;
+   case 16:
+      	pSiS->SiS_Pr->CModeFlag |= 0x227d;
 	break;
-   case 32: 			
-      	pSiS->SiS_Pr->CModeFlag = 0x22ff;
+   case 32:
+      	pSiS->SiS_Pr->CModeFlag |= 0x22ff;
 	break;		
    default: 
    	return 0;	
@@ -5139,9 +5298,9 @@
 	pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
    if(pSiS->SiS_Pr->CFlags & V_CLKDIV2)
         pSiS->SiS_Pr->CModeFlag |= HalfDCLK;
-   
+
    pSiS->SiS_Pr->CInfoFlag = 0x0007;
-   if(pSiS->SiS_Pr->CFlags & V_NHSYNC) 
+   if(pSiS->SiS_Pr->CFlags & V_NHSYNC)
    	pSiS->SiS_Pr->CInfoFlag |= 0x4000;
    if(pSiS->SiS_Pr->CFlags & V_NVSYNC) 
    	pSiS->SiS_Pr->CInfoFlag |= 0x8000;
@@ -5177,13 +5336,13 @@
    	pSiS->SiS_Pr->CSR2B,
 	pSiS->SiS_Pr->CSR2C,
 	pSiS->SiS_Pr->CSRClock);
-#endif   	
+#endif
    return 1;
 }
 
 /* TW: Build a list of supported modes */
 DisplayModePtr
-SiSBuildBuiltInModeList(ScrnInfoPtr pScrn)
+SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi)
 {
    SISPtr         pSiS = SISPTR(pScrn);
    unsigned short VRE, VBE, VRS, VBS, VDE, VT;
@@ -5191,14 +5350,16 @@
    unsigned char  sr_data, cr_data, cr_data2, cr_data3;
    unsigned char  sr2b, sr2c;
    float          num, denum, postscalar, divider;
-   int            A, B, C, D, E, F, temp, i, j, index, vclkindex;
+   int            A, B, C, D, E, F, temp, i, j, k, l, index, vclkindex;
    DisplayModePtr new = NULL, current = NULL, first = NULL;
+   BOOLEAN        done = FALSE;
 #if 0
    DisplayModePtr backup = NULL;
-#endif   
+#endif
 
    pSiS->backupmodelist = NULL;
-   
+   pSiS->AddedPlasmaModes = FALSE;
+
    /* Initialize our pointers */
    if(pSiS->VGAEngine == SIS_300_VGA) {
 #ifdef SIS300
@@ -5222,13 +5383,20 @@
       if(pSiS->VGAEngine == SIS_300_VGA) index &= 0x3F;
 #endif      
 
-      if((!pSiS->DSTN) &&
-	 (pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
-	 (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 480))  {
+      /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */
+      if((!pSiS->FSTN) &&
+	 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID == 0x5a))  {
            i++;
       	   continue;
       }
-      
+      if((pSiS->FSTN) &&
+         (pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
+	 (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240) &&
+	 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID != 0x5a)) {
+	   i++;
+	   continue;
+      }
+
       if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
       memset(new, 0, sizeof(DisplayModeRec));
       if(!(new->name = xalloc(10))) {
@@ -5242,13 +5410,13 @@
       }
 
       current = new;
-      
+
       sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes,
                                       pSiS->SiS_Pr->SiS_RefIndex[i].YRes);
 
       current->status = MODE_OK;
 
-      current->type = M_T_DEFAULT; 
+      current->type = M_T_DEFAULT;
 
       vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK;
       if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F;
@@ -5261,7 +5429,7 @@
               ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0);
       num = (sr2b & 0x7f) + 1.0;
       denum = (sr2c & 0x1f) + 1.0;
-      
+
 #ifdef TWDEBUG
       xf86DrvMsg(0, X_INFO, "------------\n");
       xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n",
@@ -5475,7 +5643,7 @@
 	 current->VSyncStart <<= 1;
 	 current->VSyncEnd <<= 1;
 	 current->VTotal <<= 1;
-	 current->VTotal |= 1; 
+	 current->VTotal |= 1;
       }
       if(current->Flags & V_DBLSCAN) {
          current->Clock >>= 1;
@@ -5517,6 +5685,187 @@
       i++;
    }
 
+   /* Add non-standard LCD modes for panel's detailed timings */
+
+   if(!includelcdmodes) return first;
+
+   xf86DrvMsg(0, X_INFO, "Checking database for vendor %x, product %x\n",
+      pSiS->SiS_Pr->CP_Vendor, pSiS->SiS_Pr->CP_Product);
+
+   i = 0;
+   while((!done) && (SiS_PlasmaTable[i].vendor) && (pSiS->SiS_Pr->CP_Vendor)) {
+
+     if(SiS_PlasmaTable[i].vendor == pSiS->SiS_Pr->CP_Vendor) {
+
+        for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
+
+	    if(SiS_PlasmaTable[i].product[j] == pSiS->SiS_Pr->CP_Product) {
+
+	       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+	       	  "Identified %s panel, adding specific modes\n",
+		  SiS_PlasmaTable[i].plasmaname);
+
+	       for(k=0; k<SiS_PlasmaTable[i].modenum; k++) {
+
+	          if(isfordvi) {
+		     if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x80)) continue;
+		  } else {
+		     if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue;
+		  }
+
+	          if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
+
+                  memset(new, 0, sizeof(DisplayModeRec));
+                  if(!(new->name = xalloc(10))) {
+      		     xfree(new);
+		     return first;
+                  }
+                  if(!first) first = new;
+                  if(current) {
+                     current->next = new;
+	             new->prev = current;
+                  }
+
+                  current = new;
+
+		  pSiS->AddedPlasmaModes = TRUE;
+
+		  l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
+
+	          sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
+                                                  SiS_PlasmaMode[l].VDisplay);
+
+                  current->status = MODE_OK;
+
+                  current->type = M_T_BUILTIN;
+
+		  current->Clock = SiS_PlasmaMode[l].clock;
+            	  current->SynthClock = current->Clock;
+
+                  current->HDisplay   = SiS_PlasmaMode[l].HDisplay;
+                  current->HSyncStart = current->HDisplay + SiS_PlasmaMode[l].HFrontPorch;
+                  current->HSyncEnd   = current->HSyncStart + SiS_PlasmaMode[l].HSyncWidth;
+                  current->HTotal     = SiS_PlasmaMode[l].HTotal;
+
+		  current->VDisplay   = SiS_PlasmaMode[l].VDisplay;
+                  current->VSyncStart = current->VDisplay + SiS_PlasmaMode[l].VFrontPorch;
+                  current->VSyncEnd   = current->VSyncStart + SiS_PlasmaMode[l].VSyncWidth;
+                  current->VTotal     = SiS_PlasmaMode[l].VTotal;
+
+                  current->CrtcHDisplay = current->HDisplay;
+                  current->CrtcHBlankStart = current->HSyncStart;
+                  current->CrtcHSyncStart = current->HSyncStart;
+                  current->CrtcHSyncEnd = current->HSyncEnd;
+                  current->CrtcHBlankEnd = current->HSyncEnd;
+                  current->CrtcHTotal = current->HTotal;
+
+                  current->CrtcVDisplay = current->VDisplay;
+                  current->CrtcVBlankStart = current->VSyncStart;
+                  current->CrtcVSyncStart = current->VSyncStart;
+                  current->CrtcVSyncEnd = current->VSyncEnd;
+                  current->CrtcVBlankEnd = current->VSyncEnd;
+                  current->CrtcVTotal = current->VTotal;
+
+                  if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_HSYNCP)
+                     current->Flags |= V_PHSYNC;
+                  else
+                     current->Flags |= V_NHSYNC;
+
+                  if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_VSYNCP)
+                     current->Flags |= V_PVSYNC;
+                  else
+                     current->Flags |= V_NVSYNC;
+
+		  if(current->HDisplay > pSiS->LCDwidth)
+		     pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX = current->HDisplay;
+	          if(current->VDisplay > pSiS->LCDheight)
+		     pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay;
+
+               }
+	       done = TRUE;
+	       break;
+	    }
+	}
+     }
+
+     i++;
+
+   }
+
+   if(pSiS->SiS_Pr->CP_HaveCustomData) {
+
+      for(i=0; i<7; i++) {
+
+         if(pSiS->SiS_Pr->CP_DataValid[i]) {
+
+            if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
+
+            memset(new, 0, sizeof(DisplayModeRec));
+            if(!(new->name = xalloc(10))) {
+      		xfree(new);
+		return first;
+            }
+            if(!first) first = new;
+            if(current) {
+               current->next = new;
+	       new->prev = current;
+            }
+
+            current = new;
+
+            sprintf(current->name, "%dx%d", pSiS->SiS_Pr->CP_HDisplay[i],
+                                            pSiS->SiS_Pr->CP_VDisplay[i]);
+
+            current->status = MODE_OK;
+
+            current->type = M_T_BUILTIN;
+
+            current->Clock = pSiS->SiS_Pr->CP_Clock[i];
+            current->SynthClock = current->Clock;
+
+            current->HDisplay   = pSiS->SiS_Pr->CP_HDisplay[i];
+            current->HSyncStart = pSiS->SiS_Pr->CP_HSyncStart[i];
+            current->HSyncEnd   = pSiS->SiS_Pr->CP_HSyncEnd[i];
+            current->HTotal     = pSiS->SiS_Pr->CP_HTotal[i];
+
+            current->VDisplay   = pSiS->SiS_Pr->CP_VDisplay[i];
+            current->VSyncStart = pSiS->SiS_Pr->CP_VSyncStart[i];
+            current->VSyncEnd   = pSiS->SiS_Pr->CP_VSyncEnd[i];
+            current->VTotal     = pSiS->SiS_Pr->CP_VTotal[i];
+
+            current->CrtcHDisplay = current->HDisplay;
+            current->CrtcHBlankStart = pSiS->SiS_Pr->CP_HBlankStart[i];
+            current->CrtcHSyncStart = current->HSyncStart;
+            current->CrtcHSyncEnd = current->HSyncEnd;
+            current->CrtcHBlankEnd = pSiS->SiS_Pr->CP_HBlankEnd[i];
+            current->CrtcHTotal = current->HTotal;
+
+            current->CrtcVDisplay = current->VDisplay;
+            current->CrtcVBlankStart = pSiS->SiS_Pr->CP_VBlankStart[i];
+            current->CrtcVSyncStart = current->VSyncStart;
+            current->CrtcVSyncEnd = current->VSyncEnd;
+            current->CrtcVBlankEnd = pSiS->SiS_Pr->CP_VBlankEnd[i];
+            current->CrtcVTotal = current->VTotal;
+
+	    if(pSiS->SiS_Pr->CP_SyncValid[i]) {
+               if(pSiS->SiS_Pr->CP_HSync_P[i])
+                  current->Flags |= V_PHSYNC;
+               else
+                  current->Flags |= V_NHSYNC;
+
+               if(pSiS->SiS_Pr->CP_VSync_P[i])
+                  current->Flags |= V_PVSYNC;
+               else
+                  current->Flags |= V_NVSYNC;
+	    } else {
+	       /* No sync data? Use positive sync... */
+	       current->Flags |= V_PHSYNC;
+	       current->Flags |= V_PVSYNC;
+	    }
+         }
+      }
+   }
+
    return first;
 
 }
@@ -5533,7 +5882,7 @@
     UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
     ULONG  temp = 0;
     int    Clock;
-    
+
     if(HwDeviceExtension->jChipType < SIS_315H) {
 #ifdef SIS300
        InitTo300Pointer(SiS_Pr, HwDeviceExtension);
@@ -5565,6 +5914,56 @@
     return(Clock);
 }
 
+BOOLEAN
+sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex)
+{
+    USHORT ModeNo = modeno;
+    USHORT ModeIdIndex = 0, CRT1Index = 0;
+    USHORT RefreshRateTableIndex = 0;
+    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
+    ULONG  temp = 0;
+    unsigned char  sr_data, cr_data, cr_data2;
+
+    if(HwDeviceExtension->jChipType < SIS_315H) {
+#ifdef SIS300
+       InitTo300Pointer(SiS_Pr, HwDeviceExtension);
+#else
+       return FALSE;
+#endif
+    } else {
+#ifdef SIS315H
+       InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+#else
+       return FALSE;
+#endif
+    }
+
+    temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
+    if(!temp) return FALSE;
+
+    RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+    RefreshRateTableIndex += (rateindex - 1);
+    CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+
+    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
+    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
+    *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
+
+    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
+    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
+    cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+    *vtotal = ((cr_data & 0xFF) |
+               ((unsigned short)(cr_data2 & 0x01) <<  8) |
+	       ((unsigned short)(cr_data2 & 0x20) <<  4) |
+	       ((unsigned short)(sr_data  & 0x01) << 10)) + 2;
+
+    if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & InterlaceMode)
+       *vtotal *= 2;
+
+    return TRUE;
+}
+
 int
 sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
 			 unsigned char modeno, unsigned char rateindex,
@@ -5676,9 +6075,9 @@
     sr_data = SiS_Pr->SiS_CRT1Table[index].CR[13];
 
     cr_data = SiS_Pr->SiS_CRT1Table[index].CR[6];
-    
+
     cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[7];
-    
+
     /* Vertical total */
     VT = (cr_data & 0xFF) |
          ((unsigned short) (cr_data2 & 0x01) << 8) |
diff -urN linux-2.4.22-pre2/drivers/video/sis/init.h linux-2.4.22-pre3/drivers/video/sis/init.h
--- linux-2.4.22-pre2/drivers/video/sis/init.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/init.h	2003-07-05 18:11:00.000000000 -0700
@@ -1,19 +1,44 @@
+/* $XFree86$ */
+/*
+ * Data and prototypes for init.c
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
 #ifndef _INIT_
 #define _INIT_
 
 #include "osdef.h"
+
 #include "initdef.h"
 #include "vgatypes.h"
 #include "vstruct.h"
 
-#ifdef TC
-#include <stdio.h>
-#include <string.h>
-#include <conio.h>
-#include <dos.h>
-#include <stdlib.h>
-#endif
-
 #ifdef LINUX_XF86
 #include "xf86.h"
 #include "xf86Pci.h"
@@ -24,6 +49,9 @@
 #endif
 
 #ifdef LINUX_KERNEL
+#ifdef SIS_CP
+#undef SIS_CP
+#endif
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/types.h>
@@ -36,19 +64,6 @@
 #endif
 #endif
 
-#ifdef WIN2000
-#include <stdio.h>
-#include <string.h>
-#include <miniport.h>
-#include "dderror.h"
-#include "devioctl.h"
-#include "miniport.h"
-#include "ntddvdeo.h"
-#include "video.h"
-#include "sisv.h"
-#include "tools.h"
-#endif
-
 const USHORT SiS_DRAMType[17][5]={
 	{0x0C,0x0A,0x02,0x40,0x39},
 	{0x0D,0x0A,0x01,0x40,0x48},
@@ -144,6 +159,2175 @@
 	0x0B,0x0C,0x0D,0x0F,0x10
 };
 
+static const SiS_StResInfoStruct SiS_StResInfo[]=
+{
+	{ 640,400},
+	{ 640,350},
+	{ 720,400},
+	{ 720,350},
+	{ 640,480}
+};
+
+static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
+{
+	{  320, 200, 8, 8},   /* 0x00 */
+	{  320, 240, 8, 8},   /* 0x01 */
+	{  320, 400, 8, 8},   /* 0x02 */
+	{  400, 300, 8, 8},   /* 0x03 */
+	{  512, 384, 8, 8},   /* 0x04 */
+	{  640, 400, 8,16},   /* 0x05 */
+	{  640, 480, 8,16},   /* 0x06 */
+	{  800, 600, 8,16},   /* 0x07 */
+	{ 1024, 768, 8,16},   /* 0x08 */
+	{ 1280,1024, 8,16},   /* 0x09 */
+	{ 1600,1200, 8,16},   /* 0x0a */
+	{ 1920,1440, 8,16},   /* 0x0b */
+	{ 2048,1536, 8,16},   /* 0x0c */
+	{  720, 480, 8,16},   /* 0x0d */
+	{  720, 576, 8,16},   /* 0x0e */
+	{ 1280, 960, 8,16},   /* 0x0f */
+	{  800, 480, 8,16},   /* 0x10 */
+	{ 1024, 576, 8,16},   /* 0x11 */
+	{ 1280, 720, 8,16},   /* 0x12 */
+	{  856, 480, 8,16},   /* 0x13 */
+	{ 1280, 768, 8,16},   /* 0x14 */
+	{ 1400,1050, 8,16},   /* 0x15 */
+	{ 1152, 864, 8,16},   /* 0x16 */
+	{  848, 480, 8,16},   /* 0x17 */
+	{ 1360, 768, 8,16},   /* 0x18 */
+	{ 1024, 600, 8,16},   /* 0x19 */
+	{ 1152, 768, 8,16},   /* 0x1a */
+	{  768, 576, 8,16},   /* 0x1b */
+	{ 1360,1024, 8,16}    /* 0x1c */
+};
+
+static SiS_StandTableStruct SiS_StandTable[]=
+{
+/* 0x00: MD_0_200 */
+ {
+  0x28,0x18,0x08,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x01: MD_1_200 */
+ {
+  0x28,0x18,0x08,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x02: MD_2_200 */
+ {
+  0x50,0x18,0x08,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x03: MD_3_200 - mode 0x03 - 0 */
+ {
+  0x50,0x18,0x08,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x04: MD_4 */
+ {
+  0x28,0x18,0x08,0x4000,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,   /* 0x2c is 2b for 300 */
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+   0xff},
+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x03,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+   0xff}
+ },
+/* 0x05: MD_5 */
+ {
+  0x28,0x18,0x08,0x4000,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,   /* 0x2c is 2b for 300 */
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+   0xff},
+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x03,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+   0xff}
+ },
+/* 0x06: MD_6 */
+ {
+  0x50,0x18,0x08,0x4000,
+  {0x01,0x01,0x00,0x06},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,   /* 55,81 is 54,80 for 300 */
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
+   0xff},
+  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+   0x01,0x00,0x01,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
+   0xff}
+ },
+/* 0x07: MD_7 */
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x00,0x03,0x00,0x03},
+  0xa6,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+   0x0e,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+   0xff}
+ },
+/* 0x08: MDA_DAC */
+ {
+  0x00,0x00,0x00,0x0000,
+  {0x00,0x00,0x00,0x15},
+  0x15,
+  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
+   0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15},
+  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x3f}
+ },
+/* 0x09: CGA_DAC */
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x09,0x15,0x00},
+  0x10,
+  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
+   0x04},
+  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
+   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
+   0x3e,0x2b,0x3b,0x2f},
+  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+   0x3f}
+ },
+/* 0x0a: EGA_DAC */
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x05,0x15,0x20},
+  0x30,
+  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
+   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
+   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
+   0x06},
+  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
+   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
+   0x1e,0x0b,0x1b,0x0f},
+  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+   0x3f}
+ },
+/* 0x0b: VGA_DAC */
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x09,0x15,0x2a},
+  0x3a,
+  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
+   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
+   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
+   0x1f},
+  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
+   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
+   0x1c,0x0e,0x11,0x15},
+  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
+   0x04}
+ },
+/* 0x0c */
+ {
+  0x08,0x0c,0x10,0x0a08,
+  {0x0c,0x0e,0x10,0x0b},
+  0x0c,
+  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
+   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
+   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
+   0x06},
+  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
+   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
+   0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}
+ },
+/* 0x0d: MD_D */
+ {
+  0x28,0x18,0x08,0x2000,
+  {0x09,0x0f,0x00,0x06},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,     /* 2c is 2b for 300 */
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
+/* 0x0e: MD_E */
+ {
+  0x50,0x18,0x08,0x4000,
+  {0x01,0x0f,0x00,0x06},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,     /* 55,81 is 54,80 for 300 */
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
+/* 0x0f: ExtVGATable - modes > 0x13 */
+ {
+  0x00,0x00,0x00,0x0000,
+  {0x01,0x0f,0x00,0x0e},
+  0x23,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+   0x01,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+   0xff}
+ },
+/* 0x10: ROM_SAVEPTR - totally different for 300 */
+ {
+  0x9f,0x3b,0x00,0x00c0,
+  {0x00,0x00,0x00,0x00},
+  0x00,
+  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
+   0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}
+ },
+/* 0x11: MD_F */
+ {
+  0x50,0x18,0x0e,0x8000,
+  {0x01,0x0f,0x00,0x06},
+  0xa2,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,    /* 82,84 is 83,85 on 300 */
+   0xff},
+  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
+   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
+   0x0b,0x00,0x05,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
+   0xff}
+ },
+/* 0x12: MD_10 */
+ {
+  0x50,0x18,0x0e,0x8000,
+  {0x01,0x0f,0x00,0x06},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,    /* 82,84 is 83,85 on 300 */
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
+/* 0x13: MD_0_350 */
+ {
+  0x28,0x18,0x0e,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0xa3,
+  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,    /* b1 is a0 on 300 */
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x14: MD_1_350 */
+ {
+  0x28,0x18,0x0e,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0xa3,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x15: MD_2_350 */
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x16: MD_3_350 - mode 0x03 - 1 */
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x17: MD_0_1_400 */
+ {
+  0x28,0x18,0x10,0x0800,
+  {0x08,0x03,0x00,0x02},
+  0x67,
+  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,    /* b1 is a0 on 300 */
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x0c,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
+ {
+  0x50,0x18,0x10,0x1000,
+  {0x00,0x03,0x00,0x02},
+  0x67,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x0c,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x19: MD_7_400 */
+ {
+  0x50,0x18,0x10,0x1000,
+  {0x00,0x03,0x00,0x02},
+  0x66,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+   0x0e,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+   0xff}
+ },
+/* 0x1a: MD_11 */
+ {
+  0x50,0x1d,0x10,0xa000,
+  {0x01,0x0f,0x00,0x06},
+  0xe3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,    /* 55,81 is 54,80 on 300 */
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,    /* e9,8b is ea,8c on 300 */
+   0xff},
+  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
+   0xff}
+ },
+/* 0x1b: ExtEGATable - Modes <= 0x02 */
+ {
+  0x50,0x1d,0x10,0xa000,
+  {0x01,0x0f,0x00,0x06},
+  0xe3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,    /* 55,81 is 54,80 on 300 */
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,    /* e9,8b is ea,8c on 300 */
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
+/* 0x1c: MD_13 */
+ {
+  0x28,0x18,0x08,0x2000,
+  {0x01,0x0f,0x00,0x0e},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
+   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+   0x41,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+   0xff}
+ }
+};
+
+static const UCHAR SiS_NTSCTiming[] = {
+	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
+	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
+	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
+	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
+	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
+	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
+	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
+};
+
+static const UCHAR SiS_PALTiming[] = {
+	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
+	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
+	0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
+	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
+	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
+	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
+};
+
+static const UCHAR SiS_HiTVExtTiming[] = {
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+};
+
+static const UCHAR SiS_HiTVSt1Timing[] = {
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
+	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
+	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
+	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
+};
+
+static const UCHAR SiS_HiTVSt2Timing[] = {
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+};
+
+static const UCHAR SiS_HiTVTextTiming[] = {
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
+	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
+	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
+        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
+	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
+};
+
+static const UCHAR SiS_HiTVGroup3Data[] = {
+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
+	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
+	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS_HiTVGroup3Simu[] = {
+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
+	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
+	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS_HiTVGroup3Text[] = {
+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
+	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
+	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS_NTSCPhase[]    = {0x21,0xed,0xba,0x08};  /* Was {0x21,0xed,0x8a,0x08}; */
+static const UCHAR SiS_PALPhase[]     = {0x2a,0x05,0xe3,0x00};  /* Was {0x2a,0x05,0xd3,0x00};  */
+static const UCHAR SiS_PALMPhase[]    = {0x21,0xE4,0x2E,0x9B};
+static const UCHAR SiS_PALNPhase[]    = {0x21,0xF4,0x3E,0xBA};
+static const UCHAR SiS_NTSCPhase2[]   = {0x21,0xF0,0x7B,0xD6};
+static const UCHAR SiS_PALPhase2[]    = {0x2a,0x09,0x86,0xe9};
+static const UCHAR SiS_PALMPhase2[]   = {0x21,0xE6,0xEF,0xA4};
+static const UCHAR SiS_PALNPhase2[]   = {0x21,0xF6,0x94,0x46};
+static const UCHAR SiS_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
+
+static const SiS_TVDataStruct  SiS_StPALData[]=
+{
+ {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+ {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
+};
+
+static const SiS_TVDataStruct  SiS_ExtPALData[] =
+{
+ {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},  /* 640x400, 320x200 */
+ {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+ {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
+ {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
+ {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},  /* 640x480, 320x240 */
+ {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},  /* 800x600, 400x300 */
+ {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},  /* 720x576 */
+ {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}   /* 1024x768 */
+};
+
+static const SiS_TVDataStruct  SiS_StNTSCData[]=
+{
+ {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+ {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
+};
+
+static const SiS_TVDataStruct  SiS_ExtNTSCData[]=
+{
+ {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},    /* 640x400, 320x200 */
+ {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
+ {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},    /* 640x480, 320x240 */
+ {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},    /* 800x600, 400x300  */
+ {  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},    /* 720x480 - BETTER (from 300 series) */
+/*{   2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},*/  /* 720x480  (old, from 650) */
+ {    1,   1,1100, 811,1412, 440,   0, 128,   0,0xee,0x0c,0x22,0x08}     /* 1024x768 CORRECTED */
+/*{  65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} */  /* 1024x768 */
+#if 0  /* 300 series was: */
+ {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+ {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
+ {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
+ {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
+ {  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},
+ {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xf1,0x04,0x1f,0x18}
+#endif
+};
+
+
+static const SiS_TVDataStruct  SiS_St2HiTVData[]=
+{
+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
+ {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
+};
+
+static const SiS_TVDataStruct  SiS_ExtHiTVData[]=
+{
+ {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},  /* 640x480   */
+ {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},  /* 800x600   */
+ {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},  /* 1024x768  */
+ {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},  /* 1280x1024 */
+ {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},  /* 800x480   */
+ {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},  /* 1024x576  */
+ {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}   /* 1280x720  */
+};
+
+static const UCHAR SiS_OutputSelect = 0x40;
+
+static const UCHAR SiS_SoftSetting  = 0x30;   /* RAM setting */
+
+static const SiS_LCDDataStruct  SiS_LCD1280x960Data[] =
+{
+	{    9,   2, 800, 500,1800,1000},
+	{    9,   2, 800, 500,1800,1000},
+	{    4,   1, 900, 500,1800,1000},
+	{    4,   1, 900, 500,1800,1000},
+	{    9,   2, 800, 500,1800,1000},
+	{   30,  11,1056, 625,1800,1000},
+	{    5,   3,1350, 800,1800,1000},
+	{    1,   1,1576,1050,1576,1050},
+	{    1,   1,1800,1000,1800,1000}
+};
+
+static const SiS_LCDDataStruct  SiS_StLCD1280x768Data[] =
+{
+	{ 211,  100, 2100,  408, 1688,  802 }, /* These values are *wrong* */
+	{ 211,   64, 1536,  358, 1688,  802 }, /* (which is why they aren't used yet) */
+	{ 211,  100, 2100,  408, 1688,  802 },
+	{ 211,   64, 1536,  358, 1688,  802 },
+	{ 211,   48,  840,  488, 1688,  802 },
+	{ 211,   72, 1008,  609, 1688,  802 },
+	{ 211,  128, 1400,  776, 1688,  802 },
+	{ 211,  205, 1680, 1041, 1688,  802 },
+	{ 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that *might* be correct */
+};
+
+static const SiS_LCDDataStruct  SiS_ExtLCD1280x768Data[] =
+{
+	{ 211,  100, 2100,  408, 1688,  802 }, /* These values are *wrong* */
+	{ 211,   64, 1536,  358, 1688,  802 }, /* (which is why they aren't used yet) */
+	{ 211,  100, 2100,  408, 1688,  802 },
+	{ 211,   64, 1536,  358, 1688,  802 },
+	{ 211,   48,  840,  488, 1688,  802 },
+	{ 211,   72, 1008,  609, 1688,  802 },
+	{ 211,  128, 1400,  776, 1688,  802 },
+	{ 211,  205, 1680, 1041, 1688,  802 },
+	{ 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that *might* be correct */
+};
+
+static const SiS_LCDDataStruct  SiS_NoScaleData1280x768[] =
+{  /* All values guessed */
+        { 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802}
+};
+
+static const SiS_LCDDataStruct  SiS_StLCD1400x1050Data[] =
+{
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,   48,  840,  488, 1688, 1066 },
+	{ 211,   72, 1008,  609, 1688, 1066 },
+	{ 211,  128, 1400,  776, 1688, 1066 },
+	{ 211,  205, 1680, 1041, 1688, 1066 },
+	{   1,    1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS_LCDDataStruct  SiS_ExtLCD1400x1050Data[] =
+{
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,   48,  840,  488, 1688, 1066 },
+	{ 211,   72, 1008,  609, 1688, 1066 },
+	{ 211,  128, 1400,  776, 1688, 1066 },
+	{ 211,  205, 1680, 1041, 1688, 1066 },
+	{   1,    1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS_LCDDataStruct  SiS_NoScaleData1400x1050[] =
+{
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS_LCDDataStruct  SiS_StLCD1600x1200Data[] =
+{  /* TODO */
+	{    0,   0,   0,   0,   0,   0}
+};
+
+static const SiS_LCDDataStruct  SiS_ExtLCD1600x1200Data[] =
+{  /* TODO */
+	{    0,   0,   0,   0,   0,   0}
+};
+
+static const SiS_LCDDataStruct  SiS_NoScaleData1600x1200[] =
+{  /* TODO - values guessed */
+        {1,  1, 2048, 1250, 2048, 1250},
+	{1,  1, 2048, 1250, 2048, 1250},
+	{1,  1, 2048, 1250, 2048, 1250},
+	{1,  1, 2048, 1250, 2048, 1250},
+	{1,  1, 2048, 1250, 2048, 1250},
+	{1,  1, 2048, 1250, 2048, 1250},
+	{1,  1, 2048, 1250, 2048, 1250},
+	{1,  1, 2048, 1250, 2048, 1250},
+	{1,  1, 2048, 1250, 2048, 1250},
+	{1,  1, 2048, 1250, 2048, 1250}
+};
+
+static const SiS_LCDDataStruct  SiS_NoScaleData[] =
+{
+	{ 1, 1, 800, 449, 800, 449 },
+	{ 1, 1, 800, 449, 800, 449 },
+	{ 1, 1, 900, 449, 900, 449 },
+	{ 1, 1, 900, 449, 900, 449 },
+	{ 1, 1, 800, 525, 800, 525 },
+	{ 1, 1,1056, 628,1056, 628 },
+	{ 1, 1,1344, 806,1344, 806 },
+	{ 1, 1,1688,1066,1688,1066 },
+        { 1, 1,1688, 802,1688, 802 },  /* 1280x768: 802 was 806 in both cases */
+        { 1, 1,2048,1250,2048,1250 },  /* 1600x1200 (guessed) */
+	{ 1, 1,1800,1000,1800,1000 }   /* 1280x960 */
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS320x480Data_1[]=
+{
+	{ 848, 433, 400, 525},
+	{ 848, 389, 400, 525},
+	{ 848, 433, 400, 525},
+	{ 848, 389, 400, 525},
+	{ 848, 518, 400, 525},
+	{1056, 628, 400, 525},
+	{ 400, 525, 400, 525},
+	{ 800, 449,1000, 644},
+	{ 800, 525,1000, 635}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_1[]=
+{
+	{ 848, 433,1060, 629},
+	{ 848, 389,1060, 629},
+	{ 848, 433,1060, 629},
+	{ 848, 389,1060, 629},
+	{ 848, 518,1060, 629},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{ 800, 449,1000, 644},
+	{ 800, 525,1000, 635}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_2[]=
+{
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{ 800, 449,1000, 644},
+	{ 800, 525,1000, 635}
+};
+
+
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_1[]=
+{
+	{1048, 442,1688,1066},
+	{1048, 392,1688,1066},
+	{1048, 442,1688,1066},
+	{1048, 392,1688,1066},
+	{1048, 522,1688,1066},
+	{1208, 642,1688,1066},
+	{1432, 810,1688,1066},
+	{1688,1066,1688,1066}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_2[]=
+{
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_1[]=
+{
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 518,1344, 806},   /* 640x480 */
+	{1050, 638,1344, 806},   /* 800x600 */
+	{1344, 806,1344, 806},   /* 1024x768 */
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+/* Custom data for Barco iQ R300 */
+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1366Data_1[]=
+{
+	{ 832, 438,1331, 806},
+	{ 832, 388,1331, 806},
+	{ 832, 438,1331, 806},
+	{ 832, 388,1331, 806},
+	{ 832, 518,1331, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066}   /* 1360x1024 */
+};
+
+/* Custom data for Barco iQ R300 */
+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1366Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066}   /* 1360x1024 */
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1024Data_1[]=
+{
+	{ 832, 438,1331, 806},
+	{ 832, 409,1331, 806},
+	{ 832, 438,1331, 806},
+	{ 832, 409,1331, 806},
+	{ 832, 518,1331, 806},   /* 640x480 */
+	{1050, 638,1344, 806},   /* 800x600 */
+	{1344, 806,1344, 806},   /* 1024x768 */
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1024Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_1[]=
+{
+        { 928, 416, 1688,1066},
+	{ 928, 366, 1688,1066},
+	{ 928, 416, 1688,1066},
+	{ 928, 366, 1688,1066},
+	{ 928, 496, 1688,1066},
+	{1088, 616, 1688,1066},
+	{1312, 784, 1688,1066},
+	{1568,1040, 1688,1066},
+	{1688,1066, 1688,1066}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_2[]=
+{
+        {1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_1[]=
+{
+        {1088, 450, 2048,1250},
+	{1088, 400, 2048,1250},
+	{1088, 450, 2048,1250},
+	{1088, 400, 2048,1250},
+	{1088, 530, 2048,1250},
+	{1248, 650, 2048,1250},
+	{1472, 818, 2048,1250},
+	{1728,1066, 2048,1250},
+	{1848,1066, 2048,1250},
+	{2048,1250, 2048,1250}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_2[]=
+{
+        {2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_1[]=
+{
+	{ 768, 438, 1408, 806},
+	{ 768, 388, 1408, 806},
+	{ 768, 438, 1408, 806},
+	{ 768, 388, 1408, 806},
+	{ 768, 518, 1408, 806},
+	{ 928, 638, 1408, 806},
+	{1152, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_2[]=
+{
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_1[] =
+{
+	{840, 604,1344, 800},
+	{840, 560,1344, 800},
+	{840, 604,1344, 800},
+	{840, 560,1344, 800},
+	{840, 689,1344, 800},
+	{1050, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{800, 449,1280, 789},
+	{800, 525,1280, 785}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_2[] =
+{
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_1[] =
+{
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 518,1344, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_2[] =
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+/* TW: Pass 1:1 data */
+static const SiS_LVDSDataStruct  SiS_LVDSXXXxXXXData_1[]=
+{
+        { 800, 449,  800, 449},
+	{ 800, 449,  800, 449},
+	{ 900, 449,  900, 449},
+	{ 900, 449,  900, 449},
+	{ 800, 525,  800, 525},  /*  640x480   */
+	{1056, 628, 1056, 628},  /*  800x600   */
+	{1344, 806, 1344, 806},  /* 1024x768   */
+	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
+ 	{1688, 806, 1688, 806},  /* 1280x768   */
+	/* No other panels ! */
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS640x480Data_1[]=
+{
+	{ 800, 445, 800, 525},   /* 800, 449, 800, 449 */
+	{ 800, 395, 800, 525},
+	{ 800, 445, 800, 525},
+	{ 800, 395, 800, 525},
+	{ 800, 525, 800, 525},
+	{ 800, 525, 800, 525},   /* pseudo */
+	{ 800, 525, 800, 525}    /* pseudo */
+};
+
+/* FSTN 320x240 */
+static const SiS_LVDSDataStruct  SiS_LVDS640x480Data_2[]=
+{
+	{ 800, 445, 800, 525},
+	{ 800, 395, 800, 525},
+	{ 800, 445, 800, 525},
+	{ 800, 395, 800, 525},
+	{ 800, 525, 800, 525},
+        { 800, 525, 800, 525},   /* pseudo */
+	{ 800, 525, 800, 525}    /* pseudo */
+};
+
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_1[]=
+{
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 518,1344, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+/* LCDA */
+
+static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_1[]=
+{	/* TW: Might be temporary (invalid) data */
+        { 928, 416, 1688,1066},
+	{ 928, 366, 1688,1066},
+	{1008, 416, 1688,1066},
+	{1008, 366, 1688,1066},
+	{1200, 530, 1688,1066},
+	{1088, 616, 1688,1066},
+	{1312, 784, 1688,1066},
+	{1568,1040, 1688,1066},
+	{1688,1066, 1688,1066}
+};
+
+static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_2[]=
+{	/* TW: Temporary data. Not valid */
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_1[]=
+{	/* TW: Temporary data. Not valid */
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_2[]=
+{	/* TW: Temporary data. Not valid */
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0}
+};
+
+static const SiS_LVDSDataStruct  SiS_CHTVUNTSCData[]=
+{
+	{ 840, 600, 840, 600},
+	{ 840, 600, 840, 600},
+	{ 840, 600, 840, 600},
+	{ 840, 600, 840, 600},
+	{ 784, 600, 784, 600},
+	{1064, 750,1064, 750},
+        {1160, 945,1160, 945}
+};
+
+static const SiS_LVDSDataStruct  SiS_CHTVONTSCData[]=
+{
+	{ 840, 525, 840, 525},
+	{ 840, 525, 840, 525},
+	{ 840, 525, 840, 525},
+	{ 840, 525, 840, 525},
+	{ 784, 525, 784, 525},
+	{1040, 700,1040, 700},
+        {1160, 840,1160, 840}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1076_1[]=
+{  /* 1024x768 */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1076_2[]=
+{  /* 1024x768 */
+	{ 1184, 622 },
+	{ 1184, 597 },
+	{ 1184, 622 },
+	{ 1184, 597 },
+	{ 1152, 622 },
+	{ 1232, 722 },
+	{    0, 0   },
+	{    0, 794 },
+	{    0, 0   }
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1210_1[]=
+{  /* 1280x1024 */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1210_2[]=
+{  /* 1280x1024 */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1296_1[]=
+{  /* 1400x1050 */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1296_2[]=
+{  /* 1400x1050 - looks heavily invalid */
+	{ 808 , 740},
+	{ 0   , 715},
+	{ 632 , 740},
+	{ 632 , 715},
+	{ 1307, 780},
+	{ 1387,1157},
+	{ 1499, 924},
+	{ 1627,1052},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1600_1[]=
+{  /* 1600x1200 */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1600_2[]=
+{  /* 1600x1200 - BIOS looks heavily invalid, not copied */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct  SiS_PanelTypeNS_1[]=
+{
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0, 806},
+	{ 0, 0 }
+};
+
+static const SiS_LVDSDesStruct  SiS_PanelTypeNS_2[] =
+{
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct  SiS_CHTVUNTSCDesData[]=
+{
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
+
+static const SiS_LVDSDesStruct  SiS_CHTVONTSCDesData[]=
+{
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
+
+static const SiS_LVDSDesStruct  SiS_CHTVUPALDesData[]=
+{
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
+
+static const SiS_LVDSDesStruct  SiS_CHTVOPALDesData[]=
+{
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1320x480_1[] =
+{
+ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00 }},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01 }},
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00 }}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_1[] =
+{
+        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
+	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
+	  0x00}},
+        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
+	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
+	  0x01}},
+        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_1_H[] =
+{
+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+          0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+	  0x00}},
+        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+	  0x01}},
+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_2[] =
+{
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+	  0x01}},
+        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_2_H[] =
+{
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+	  0x01}},
+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_1[] =
+{
+        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+	  0x00}},
+        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+	  0x01}},
+        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_1_H[] =
+{
+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+	  0x00}},
+        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+	  0x01}},
+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_2[] =
+{
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+	  0x01}},
+        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_2_H[] =
+{
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+	  0x01}},
+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_1[] =
+{
+ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
+   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
+   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
+   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
+   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
+   0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
+   0x00}},
+ {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
+   0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
+   0x01}},
+ {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_1_H[] =
+{
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
+   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
+   0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
+   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
+   0x00}},
+ {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
+   0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
+   0x01}},
+ {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
+   0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
+   0x01}},
+ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
+   0x01}},
+ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_2[] =
+{
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
+   0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
+   0x01}},
+ {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
+   0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
+   0x01}},
+ {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_2_H[] =
+{
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
+   0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
+   0x01}},
+ {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
+   0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
+   0x01}},
+ {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1XXXxXXX_1[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01}},
+ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
+   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+   0x01}},
+ {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1XXXxXXX_1_H[] =
+{
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}},
+ {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
+   0x01}},
+ {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_1[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_1_H[] =
+{
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
+   0x00}},
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
+   0x00}},
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
+   0x00}},
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
+   0x00}},
+ {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2_H[] =
+{
+ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3_H[] =
+{
+ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}
+};
+
+#define SIS_PL_HSYNCP 0x01
+#define SIS_PL_HSYNCN 0x02
+#define SIS_PL_VSYNCP 0x04
+#define SIS_PL_VSYNCN 0x08
+#define SIS_PL_DVI    0x80
+
+typedef struct _SiS_PlasmaModes
+{
+  const char *name;
+  ULONG  clock;
+  USHORT HDisplay, HTotal, HFrontPorch, HSyncWidth;
+  USHORT VDisplay, VTotal, VFrontPorch, VSyncWidth;
+  UCHAR  SyncFlags;
+} SiS_PlasmaModes;
+
+
+typedef struct _SiS_PlasmaTables
+{
+   USHORT vendor;
+   UCHAR  productnum;
+   USHORT product[5];
+   const char *plasmaname;
+   UCHAR  modenum;
+   UCHAR  plasmamodes[20];  /* | 0x80 = DVI-capable, | 0x40 = analog */
+} SiS_PlasmaTables;
+
+static const SiS_PlasmaModes SiS_PlasmaMode[] = {
+   {  "640x400",		/* 00: IBM 400@70 */
+      25175,
+       640,  800, 17,  64,
+       400,  449, 13,   2,
+      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
+   {  "640x480",		/* 01: VESA 480@72 */
+      31500,
+       640,  832, 24,  40,
+       480,  520,  9,   3,
+      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
+   {  "800x600",		/* 02: VESA 600@72 */
+      50000,
+       800, 1040, 56, 120,
+       600,  666, 37,   6,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "864x480",		/* 03: Cereb wide 1 */
+      42526,
+       864, 1134, 22,  86,
+       480,  500,  1,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCN },
+   {  "848x480",		/* 04: VESA wide (NEC1) */
+      33750,
+       848, 1088, 16, 112,
+       480,  517,  6,   8,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1024x576",		/* 05: VESA wide (NEC2) */
+      47250,
+      1024, 1320, 16, 144,
+       576,  596,  2,   4,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x720",		/* 06: VESA wide (NEC3) */
+      76500,
+      1280, 1696, 48, 176,
+       720,  750,  4,   8,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1360x765",		/* 07: VESA wide (NEC4) */
+      85500,
+      1360, 1792, 64, 176,
+       765,  795,  4,   8,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1024x600",		/* 08: CEREB wide 2 */
+      51200,
+      1024, 1352, 51, 164,
+       600,  628,  1,   4,
+      SIS_PL_HSYNCN | SIS_PL_VSYNCP },
+   {  "1024x768",		/* 09: VESA 768@75 */
+      78750,
+      1024, 1312,  16, 96,
+       768,  800,   1,  3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1152x864",		/* 10: VESA 1152x864@75 */
+      108000,
+      1152, 1600, 64, 128,
+       864,  900,  1,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x1024",		/* 11: VESA 1024@60 */
+      108000,
+      1280, 1688, 48, 112,
+      1024, 1066,  1,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x768",		/* 12: W_XGA */
+      81000,
+      1280, 1688, 48, 112,
+       768,  802,  3,   6,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCN },
+   {  "1280x768",		/* 13: I/O Data W_XGA@56Hz */
+      76064,
+      1280, 1688, 48, 112,
+       768,  802,  2,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1376x768",		/* 14: I/O Wide XGA */
+      87340,
+      1376, 1808, 32, 128,
+       768,  806,  3,   6,
+      SIS_PL_HSYNCN | SIS_PL_VSYNCP },
+   {  "1280x960",		/* 15: VESA 960@60 */
+      108000,
+      1280, 1800, 96, 112,
+       960, 1000,  1,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1400x1050",		/* 16: VESA 1050@60Hz */
+      108000,
+      1400, 1688, 48, 112,
+      1050, 1066,  1,   3,
+      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
+   {  "1360x768",		/* 17: VESA wide (NEC4/2) */
+      85500,
+      1360, 1792, 64, 112,
+       765,  795,  3,   6,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "800x600",		/* 18: VESA 600@56 */
+      36000,
+       800, 1024, 24,   2,
+       600,  625,  1,   2,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP }
+};
+
+static const SiS_PlasmaTables SiS_PlasmaTable[] = {
+#if 0  /* Product IDs missing */
+   { 0x38a3, 4,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG",
+     14,   /* All DVI, except 0, 7, 13; 3, 15, 16 unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,12|0xc0,
+      13|0x40,14|0xc0,15|0xc0,16|0xc0, 0     , 0     , 0     , 0     , 0     , 0 }
+   },
+   { 0x38a3, 3,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     "NEC PlasmaSync 42PD1/50PD1/50PD2",
+     5,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     "NEC PlasmaSync 42PD3",
+     10,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 2,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     "NEC PlasmaSync 42VM3/61XM1",
+     11,  /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0,
+      17|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 2,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     "NEC PlasmaSync 42MP1/42MP2",
+     6,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     "NEC PlasmaSync 50MP1",
+     10,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+#endif
+   { 0x38a3, 4,
+     { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 },
+     "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1",
+     11,   /* All DVI except 0, 7, 13, 17 */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
+      17|0x40, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+#if 0  /* Product IDs missing */
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     "NEC PlasmaSync 3300W",
+     3,
+     { 0|0x40, 1|0xc0,18|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     "NEC PlasmaSync 4200W",
+     4,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 0     , 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     "NEC PlasmaSync 4210W",
+     6,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     "NEC PlasmaSync 5000W",
+     7,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,11|0xc0, 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+#endif
+   { 0x412f, 2,
+     { 0x000c, 0x000b, 0x0000, 0x0000, 0x0000 },
+     "Pioneer 503CMX/PDA-5002",
+     6,   /* DVI unknown */
+     { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x34a9, 1,
+     { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 },
+     "Panasonic TH-42",
+     5,   /* No DVI output */
+     { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x0000 }
+};
+
 void     SiS_SetReg1(USHORT, USHORT, USHORT);
 void     SiS_SetReg2(SiS_Private *, USHORT, USHORT, USHORT);
 void     SiS_SetReg3(USHORT, USHORT);
@@ -158,6 +2342,7 @@
 void     SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
 BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo);
 void     SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
 
 #ifdef SIS300
 void     SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
@@ -192,12 +2377,15 @@
 
 void     SiS_HandleCRT1(SiS_Private *SiS_Pr);
 void     SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo);
-void     SiS_SetEnableDstn(SiS_Private *SiS_Pr);
+void     SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
+void     SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
 void     SiS_Delay15us(SiS_Private *SiS_Pr);
 BOOLEAN  SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
 BOOLEAN  SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
                              USHORT ModeNo,USHORT ModeIdIndex);
 UCHAR    SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+void     SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
 void     SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
 void     SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
 void     SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
@@ -267,26 +2455,26 @@
 void    	SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
 extern int      SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
 	     	 		    int *out_sbit, int *out_scale);
+extern void 	SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk);
+
 extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value);
 extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
-extern USHORT 	     SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
+extern USHORT 	     SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN hcm);
 #endif
 
 extern USHORT    SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                        USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
 extern USHORT    SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
 extern void      SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-extern BOOLEAN   SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                                     PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void      SiS_PresetScratchregister(SiS_Private *SiS_Pr, USHORT SiS_P3d4,
-                                           PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN   SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                                  PSIS_HW_DEVICE_INFO HwDeviceExtension);
 extern void      SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
 extern void      SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
 extern BOOLEAN   SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr);
 extern BOOLEAN   SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO );
 extern void      SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
                                USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, int chkcrt2mode);
-extern BOOLEAN   SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+extern void      SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
                                    USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension);
 extern void      SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
 extern USHORT    SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
@@ -321,10 +2509,12 @@
 			      unsigned char modeno, unsigned char rateindex);
 int    sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
 			 unsigned char modeno, unsigned char rateindex,
-			 ULONG *left_margin, ULONG *right_margin, 
+			 ULONG *left_margin, ULONG *right_margin,
 			 ULONG *upper_margin, ULONG *lower_margin,
 			 ULONG *hsync_len, ULONG *vsync_len,
 			 ULONG *sync, ULONG *vmode);
+BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
 #endif
 
 #endif
diff -urN linux-2.4.22-pre2/drivers/video/sis/init301.c linux-2.4.22-pre3/drivers/video/sis/init301.c
--- linux-2.4.22-pre2/drivers/video/sis/init301.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/init301.c	2003-07-05 18:11:04.000000000 -0700
@@ -1,27 +1,16 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.3 2002/22/04 01:16:16 dawes Exp $ */
 /*
- * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740/330
- * (Universal module for Linux kernel framebuffer, XFree86 4.x)
+ * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740/330/660
+ * (Universal module for Linux kernel framebuffer and XFree86 4.x)
  *
  * Assembler-To-C translation
  * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
- * Minor parts Copyright SiS, Inc.
+ * Formerly based on non-functional code-fragements by SiS, Inc.
  *
- * Based on BIOS
- *     1.10.07, 1.10a for 650/CH7019
- *     1.11.21a for 740/CH7019
- *     1.11.05 for 650/LVDS (w/o Chrontel)
- *     1.07.1b, 1.10.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV), 650/302LV
- *     2.04.50 (I) and 2.04.5c (II) for 630/301(B)
- *     2.02.3b, 2.03.02, 2.04.2c, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
- *     2.04.5c, 2.04.6c for 730+LVDS+CH7005
- *     1.09b for 315/301(B)
- *     1.16.51 for 300+301LV (ECS A907)
- *     1.01.03 for 330 (Xabre 400)
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
  *
- * Known bugs:
- *   1024x768 panel, expanding (CR37=1): Mode 640x480 does not work on SOME panels
- *       therefore, we always do the scaling ourselves for now.
+ * Otherwise, the following terms apply:
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -73,8 +62,8 @@
 #define SiS_I2CDELAYSHORT  150
 
 BOOLEAN
-SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                 PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
    USHORT ModeIdIndex;
    USHORT RefreshRateTableIndex;
@@ -85,9 +74,9 @@
       SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
    } else {
       ModeIdIndex = 0;
-   }      
+   }
 
-   /* TW: Used for shifting CR33 */
+   /* Used for shifting CR33 */
    SiS_Pr->SiS_SelectCRT2Rate = 4;
 
    SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
@@ -110,8 +99,6 @@
       return(TRUE);
    }
 
-   if(SiS_Pr->UseCustomMode) return(FALSE);
-   
    SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                    HwDeviceExtension);
 
@@ -153,9 +140,9 @@
       	   SiS_SetGroup5(SiS_Pr,HwDeviceExtension, BaseAddr,ROMAddr,
 	                 ModeNo,ModeIdIndex);
 
-	   /* TW: For 301BDH (Panel link initialization): */
+	   /* For 301BDH (Panel link initialization): */
 	   if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {	 
+	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
 		 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo = 0x10)))) {
 		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
 		       SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
@@ -176,10 +163,10 @@
 	                      RefreshRateTableIndex,HwDeviceExtension);
 	   }
 	}
-        if(SiS_Pr->SiS_IF_DEF_FSTN == 0) {
-     	   SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-	 	           RefreshRateTableIndex,HwDeviceExtension);
-	}
+
+        SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+	                RefreshRateTableIndex,HwDeviceExtension);
+
 	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
      	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
 	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
@@ -199,74 +186,64 @@
    }
 
 #ifdef SIS300
-   if ( (HwDeviceExtension->jChipType == SIS_540) ||
-        (HwDeviceExtension->jChipType == SIS_630) ||
-        (HwDeviceExtension->jChipType == SIS_730) ||
-        (HwDeviceExtension->jChipType == SIS_300) )
-    {
-	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-	   if(SiS_Pr->SiS_UseOEM) {
-	      if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
-	         if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-	            SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
-	         }
-	      } else {
-       	         SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
-	      }
-	   }
-	}
-    }
-#endif
-
-#ifdef SIS315H
-   if ( (HwDeviceExtension->jChipType == SIS_315H)  ||
-        (HwDeviceExtension->jChipType == SIS_315)   ||
-	(HwDeviceExtension->jChipType == SIS_315PRO)||
-        (HwDeviceExtension->jChipType == SIS_550)   ||
-        (HwDeviceExtension->jChipType == SIS_740)   ||
-        (HwDeviceExtension->jChipType == SIS_650)   ||
-	(HwDeviceExtension->jChipType == SIS_330) )
-   {
-        if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-	   SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
-#if 0      /* Instead of FinalizeLCD(), older BIOSes (A92x) used OEMLCD() */
-	   SiS_OEMLCD(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-#endif
-           if(SiS_Pr->SiS_UseOEM) {
-              SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-           }
-           SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
-        }
-   }
-#endif
-
    if(HwDeviceExtension->jChipType < SIS_315H) {
+      if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+	 if(SiS_Pr->SiS_UseOEM) {
+	    if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
+	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+	          SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	       			    RefreshRateTableIndex);
+	       }
+	    } else {
+       	       SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	       			 RefreshRateTableIndex);
+	    }
+	 }
+	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+            if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+	       SetOEMLCDData2(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,
+	                      ModeIdIndex,RefreshRateTableIndex);
+	    }
+            if(HwDeviceExtension->jChipType == SIS_730) {
+               SiS_DisplayOn(SiS_Pr);
+	    }
+         }
+      }
       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
           if(HwDeviceExtension->jChipType != SIS_730) {
              SiS_DisplayOn(SiS_Pr);
 	  }
       }
    }
+#endif
 
-   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(HwDeviceExtension->jChipType == SIS_730) {
-            SiS_DisplayOn(SiS_Pr);
-	 }
+#ifdef SIS315H
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+	 SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
+         if(SiS_Pr->SiS_UseOEM) {
+            SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+         }
+         SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
       }
+   }
+#endif
+
+   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
       SiS_EnableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
    }
 
    SiS_DisplayOn(SiS_Pr);
 
    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-	     /* TW: Disable LCD panel when using TV */
-	     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
-	} else {
-	     /* TW: Disable TV when using LCD */
-	     SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
-	}
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	 /* Disable LCD panel when using TV */
+	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
+      } else {
+	 /* Disable TV when using LCD */
+	 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
+      }
    }
 
    if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
@@ -283,7 +260,7 @@
     USHORT temp,temp1,temp2;
 
     if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
-         return(1);
+       return(1);
     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11);
     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
     temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
@@ -304,7 +281,7 @@
     }
 }
 
-/* TW: Set Part1 registers */
+/* Set Part1 registers */
 void
 SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
               USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
@@ -313,25 +290,29 @@
   USHORT  temp=0, tempax=0, tempbx=0, tempcx=0;
   USHORT  pushbx=0, CRT1Index=0;
 #ifdef SIS315H
-  USHORT  pushcx=0, tempbl=0;
+  USHORT  tempbl=0;
 #endif
   USHORT  modeflag, resinfo=0;
 
-  if(ModeNo<=0x13) {
-	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
+     if(SiS_Pr->UseCustomMode) {
+	modeflag = SiS_Pr->CModeFlag;
+     } else {
     	CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
 	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     }
   }
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-
-	   SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
-                           RefreshRateTableIndex,HwDeviceExtension);
 #ifdef SIS315H
-	   SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-     	                      HwDeviceExtension,RefreshRateTableIndex);
+     SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
+                     RefreshRateTableIndex,HwDeviceExtension);
+
+     SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+                        HwDeviceExtension,RefreshRateTableIndex);
 #endif
   } else {
 
@@ -367,13 +348,13 @@
 #ifdef SIS300   /* ------------- 300 series --------------*/
 
     		temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   			/* BTVGA2HT 0x08,0x09 */
-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* TW: CRT2 Horizontal Total */
+    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* CRT2 Horizontal Total */
 
     		temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
-    		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* TW: CRT2 Horizontal Total Overflow [7:4] */
+    		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* CRT2 Horizontal Total Overflow [7:4] */
 
     		temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* TW: CRT2 Horizontal Display Enable End */
+    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* CRT2 Horizontal Display Enable End */
 
     		pushbx = SiS_Pr->SiS_VGAHDE + 12;                               /* bx  BTVGA@HRS 0x0B,0x0C */
     		tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
@@ -382,108 +363,129 @@
     		tempcx += tempbx;
 
     		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-      			if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
-			        /* CRT1Index &= 0x3F; - Not any longer */
-        			tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
-        			tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
-        			tempbx = (tempbx - 1) << 3;
-        			tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
-        			tempcx &= 0x1F;
-        			temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
-        			temp = (temp & 0x04) << (6-2);
-        			tempcx = (tempcx | temp);
-				tempcx--;
-				tempcx <<= 3;
-      			}
-
-    			if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
-        			if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
-      					tempbx = 1040;
-      					tempcx = 1042;
-      				}
-    			}
+
+		   if(SiS_Pr->UseCustomMode) {
+		      tempbx = SiS_Pr->CHSyncStart + 12;
+		      tempcx = SiS_Pr->CHSyncEnd + 12;
+		   }
+
+      		   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+		      unsigned char cr4, cr14, cr5, cr15;
+		      if(SiS_Pr->UseCustomMode) {
+		         cr4  = SiS_Pr->CCRT1CRTC[4];
+			 cr14 = SiS_Pr->CCRT1CRTC[14];
+			 cr5  = SiS_Pr->CCRT1CRTC[5];
+			 cr15 = SiS_Pr->CCRT1CRTC[15];
+		      } else {
+		         cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+			 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
+			 cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+			 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+		      }
+        	      tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 1) << 3;
+        	      tempcx = (((cr5 & 0x1F) | ((cr15 & 0x04) << (6-2))) - 1) << 3;
+      		   }
+
+    		   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
+        	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
+      			 tempbx = 1040;
+      			 tempcx = 1042;
+      		      }
+    		   }
 	        }
 
     		temp = tempbx & 0x00FF;
-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* TW: CRT2 Horizontal Retrace Start */
+    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* CRT2 Horizontal Retrace Start */
 #endif /* SIS300 */
 
  	} else {
 
-#ifdef SIS315H  /* ----------------- 310/325/330 series ------------- */
+#ifdef SIS315H  /* ------------------- 315/330 series --------------- */
 
 	        tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HT 0x08,0x09 */
-		pushcx = tempcx;
 		if(modeflag & HalfDCLK) {
-#ifndef NEWCH701x		
-		    if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_IF_DEF_CH70xx == 0)) {
-#endif		    
+		    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
 		          tempax = SiS_Pr->SiS_VGAHDE >> 1;
 			  tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
 			  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
 			      tempcx = SiS_Pr->SiS_HT - tempax;
 			  }
-#ifndef NEWCH701x					  
 		    } else {
 			  tempcx >>= 1;
 		    }
-#endif		    
 		}
 		tempcx--;
 
 		temp = tempcx & 0xff;
-		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* TW: CRT2 Horizontal Total */
+		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* CRT2 Horizontal Total */
 
 		temp = ((tempcx & 0xff00) >> 8) << 4;
-		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* TW: CRT2 Horizontal Total Overflow [7:4] */
+		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* CRT2 Horizontal Total Overflow [7:4] */
 
-		tempcx = pushcx;					       /* BTVGA2HDEE 0x0A,0x0C */
+		tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HDEE 0x0A,0x0C */
 		tempbx = SiS_Pr->SiS_VGAHDE;
 		tempcx -= tempbx;
 		tempcx >>= 2;
 		if(modeflag & HalfDCLK) {
-		    tempbx >>= 1;
-		    tempcx >>= 1;
+		   tempbx >>= 1;
+		   tempcx >>= 1;
 		}
 		tempbx += 16;
 
 		temp = tempbx & 0xff;
-		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* TW: CRT2 Horizontal Display Enable End */
+		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* CRT2 Horizontal Display Enable End */
 
 		pushbx = tempbx;
 		tempcx >>= 1;
 		tempbx += tempcx;
 		tempcx += tempbx;
 
-		if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
+		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+		   if(SiS_Pr->UseCustomMode) {
+		      tempbx = SiS_Pr->CHSyncStart + 16;
+		      tempcx = SiS_Pr->CHSyncEnd + 16;
+		      tempax = SiS_Pr->SiS_VGAHT;
+		      if(modeflag & HalfDCLK) tempax >>= 1;
+		      tempax--;
+		      if(tempcx > tempax)  tempcx = tempax;
+		   }
+
              	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
-                	tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
-                	tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
-                	tempbx = (tempbx - 3) << 3;         		/*(VGAHRS-3)*8 */
-                	tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
-               		tempcx &= 0x1F;
-                	temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
-                	temp = (temp & 0x04) << (5-2);      		/* VGAHRE D[5] */
-                	tempcx = (tempcx | temp);	  	  	/* (VGAHRE-3)*8 */
-			tempcx -= 3;
-			tempcx <<= 3;
-			tempcx &= 0x00FF;
-			tempcx |= (tempbx & 0xFF00);
-                	tempbx += 16;
-                	tempcx += 16;
-			tempax = SiS_Pr->SiS_VGAHT;
-			if(modeflag & HalfDCLK)  tempax >>= 1;
-			tempax--;
-			if(tempcx > tempax)  tempcx = tempax;
+		      unsigned char cr4, cr14, cr5, cr15;
+		      if(SiS_Pr->UseCustomMode) {
+		         cr4  = SiS_Pr->CCRT1CRTC[4];
+			 cr14 = SiS_Pr->CCRT1CRTC[14];
+			 cr5  = SiS_Pr->CCRT1CRTC[5];
+			 cr15 = SiS_Pr->CCRT1CRTC[15];
+		      } else {
+		         cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+			 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
+			 cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+			 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+		      }
+                      tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		/* (VGAHRS-3)*8 */
+                      tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; 	/* (VGAHRE-3)*8 */
+		      tempcx &= 0x00FF;
+		      tempcx |= (tempbx & 0xFF00);
+                      tempbx += 16;
+                      tempcx += 16;
+		      tempax = SiS_Pr->SiS_VGAHT;
+		      if(modeflag & HalfDCLK) tempax >>= 1;
+		      tempax--;
+		      if(tempcx > tempax)  tempcx = tempax;
              	   }
-         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
-             	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
-      		 	 tempbx = 1040;
-      		 	 tempcx = 1042;
-      	     	      }
+         	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+		      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+		         if(resinfo == SIS_RI_1024x768) {
+      		 	    tempbx = 1040;
+      		 	    tempcx = 1042;
+      	     	         }
+		      }
          	   }
-		   /* TW: Makes no sense, but is in 650/302LV 1.10.6s */
-         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+#if 0
+		   /* Makes no sense, but is in 650/30xLV 1.10.6s */
+         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
 		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
              	         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
       		 	    tempbx = 1040;
@@ -491,25 +493,26 @@
       	     	         }
 		      }
          	   }
+#endif
                 }
 
 		temp = tempbx & 0xff;
-	 	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* TW: CRT2 Horizontal Retrace Start */
+	 	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* CRT2 Horizontal Retrace Start */
 #endif  /* SIS315H */
 
-     	}  /* 310/325/330 series */
+     	}  /* 315/330 series */
 
-  	/* TW: The following is done for all bridge/chip types/series */
+  	/* The following is done for all bridge/chip types/series */
 
   	tempax = tempbx & 0xFF00;
   	tempbx = pushbx;
   	tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
   	tempax |= (tempbx & 0xFF00);
   	temp = (tempax & 0xFF00) >> 8;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* TW: Overflow */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* Overflow */
 
   	temp = tempcx & 0x00FF;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* TW: CRT2 Horizontal Retrace End */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* CRT2 Horizontal Retrace End */
 
   	/* 2. Vertical setup */
 
@@ -517,30 +520,30 @@
   	temp = tempcx & 0x00FF;
 
         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-	     if(HwDeviceExtension->jChipType < SIS_315H) {
-	          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-		       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
-		           temp--;
-		       }
-                  }
-	     } else {
- 		      temp--;
-             }
+	   if(HwDeviceExtension->jChipType < SIS_315H) {
+	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
+	            temp--;
+	         }
+              }
+	   } else {
+ 	      temp--;
+           }
         } else if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    /* TW: 650/30xLV 1.10.6s */
-	    temp--;
+	   /* 650/30xLV 1.10.6s */
+	   temp--;
 	}
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* TW: CRT2 Vertical Total */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* CRT2 Vertical Total */
 
   	tempbx = SiS_Pr->SiS_VGAVDE - 1;
   	temp = tempbx & 0x00FF;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* TW: CRT2 Vertical Display Enable End */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* CRT2 Vertical Display Enable End */
 
   	temp = ((tempbx & 0xFF00) << 3) >> 8;
   	temp |= ((tempcx & 0xFF00) >> 8);
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* TW: Overflow (and HWCursor Test Mode) */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* Overflow (and HWCursor Test Mode) */
 
-	/* TW: 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */
+	/* 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */
 	if(HwDeviceExtension->jChipType >= SIS_315H) {
            tempbx++;
    	   tempax = tempbx;
@@ -553,29 +556,44 @@
 	   tempcx += tempbx;
 	   tempcx++;
 	} else {
-	   /* TW: 300 series, LVDS/301B: */
+	   /* 300 series, LVDS/301B: */
   	   tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
   	   tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
 	}
 
   	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-    	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
-      		tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
-      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
-      		if(temp & 0x04) tempbx |= 0x0100;
-      		if(temp & 0x80) tempbx |= 0x0200;
-      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
-      		if(temp & 0x08) tempbx |= 0x0400;
-      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
-      		tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
+
+	   if(SiS_Pr->UseCustomMode) {
+	      tempbx = SiS_Pr->CVSyncStart;
+	      tempcx = (tempcx & 0xFF00) | (SiS_Pr->CVSyncEnd & 0x00FF);
+	   }
+
+    	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+	      unsigned char cr8, cr7, cr13, cr9;
+	      if(SiS_Pr->UseCustomMode) {
+	         cr8  = SiS_Pr->CCRT1CRTC[8];
+		 cr7  = SiS_Pr->CCRT1CRTC[7];
+		 cr13 = SiS_Pr->CCRT1CRTC[13];
+		 cr9  = SiS_Pr->CCRT1CRTC[9];
+	      } else {
+	         cr8  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
+		 cr7  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+		 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
+		 cr9  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
+	      }
+      	      tempbx = cr8;
+      	      if(cr7 & 0x04)  tempbx |= 0x0100;
+      	      if(cr7 & 0x80)  tempbx |= 0x0200;
+      	      if(cr13 & 0x08) tempbx |= 0x0400;
+      	      tempcx = (tempcx & 0xFF00) | (cr9 & 0x00FF);
     	   }
   	}
   	temp = tempbx & 0x00FF;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);           /* TW: CRT2 Vertical Retrace Start */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);           /* CRT2 Vertical Retrace Start */
 
   	temp = ((tempbx & 0xFF00) >> 8) << 4;
   	temp |= (tempcx & 0x000F);
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp);           /* TW: CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp);           /* CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
 
   	/* 3. Panel compensation delay */
 
@@ -590,18 +608,18 @@
 		   temp = 0x10;
 		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
 		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
-		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
 		}
 		if(SiS_Pr->SiS_VBType & VB_SIS301) {
 		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
 		}
 		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)     temp = 0x24;
+		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)       temp = 0x2c;
 		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 		temp = 0x08;
 		if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
       		   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	temp = 0x2c;
       		   else 					temp = 0x20;
     	        }
-		if((ROMAddr) && (SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+		if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
 		    if(ROMAddr[0x220] & 0x80) {
 		        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))
 				temp = ROMAddr[0x221];
@@ -636,19 +654,20 @@
 		}
 	   }
 
-    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* TW: Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
 
 #endif  /* SIS300 */
 
   	} else {
 
-#ifdef SIS315H   /* ----------- 310/325/330 series ---------------*/
+#ifdef SIS315H   /* --------------- 315/330 series ---------------*/
 
 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
                 temp = 0x10;
                 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
     	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
     	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
+		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)    temp = 0x2c;
 		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
 		   temp = 0x08;
 		   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
@@ -664,7 +683,7 @@
 		      }
     	           }
 		}
-		if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+		if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
 		   tempbl = 0x00;
 		   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
 		      if(HwDeviceExtension->jChipType < SIS_330) {
@@ -689,8 +708,16 @@
 		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
 		   }
 		}
+		
+		if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
+		   temp = 0x08;
+		   tempbl = 0;
+		   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+		      if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
+		   }
+		}
 	   }
-	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* TW: Panel Link Delay Compensation */
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
 
     	   tempax = 0;
     	   if (modeflag & DoubleScanMode) tempax |= 0x80;
@@ -705,14 +732,13 @@
 
      if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-        /* TW: For 301BDH, we set up the Panel Link */
-        if( (SiS_Pr->SiS_VBType & VB_NoLCD) &&
-	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
+        /* For 301BDH with LCD, we set up the Panel Link */
+        if( (SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
 
 	    SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
 	                       HwDeviceExtension,RefreshRateTableIndex);
 
-        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {                             
+        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
 
     	    SiS_SetGroup1_301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
 	                      HwDeviceExtension,RefreshRateTableIndex);
@@ -749,23 +775,27 @@
   USHORT  push1,push2;
   USHORT  tempax,tempbx,tempcx,temp;
   USHORT  resinfo,modeflag;
+  unsigned char p1_7, p1_8;
 
   if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+	resinfo = 0;
+     } else {
     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     }
   }
 
-  /* TW: The following is only done if bridge is in slave mode: */
+  /* The following is only done if bridge is in slave mode: */
 
   tempax = 0xFFFF;
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempax = SiS_GetVGAHT2(SiS_Pr);
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-  	modeflag |= Charx8Dot;
-  }
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
 
   if(modeflag & Charx8Dot) tempcx = 0x08;
   else                     tempcx = 0x09;
@@ -777,8 +807,7 @@
   tempax = (tempax / tempcx) - 5;
   tempbx = tempax & 0x00FF;
 
-  temp = 0xFF;                                                  /* set MAX HT */
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0xff);                 /* set MAX HT */
 
   tempax = SiS_Pr->SiS_VGAHDE;                                 	/* 0x04 Horizontal Display End */
   if(modeflag & HalfDCLK) tempax >>= 1;
@@ -789,13 +818,13 @@
 
   temp = (tempbx & 0xFF00) >> 8;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {        
-    	    temp += 2;
-        }
-  }	
+     if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+        temp += 2;
+     }
+  }
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
      if(SiS_Pr->SiS_HiVision == 3) {
-              if(resinfo == 7) temp -= 2;
+        if(resinfo == SIS_RI_800x600) temp -= 2;
      }
   }
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
@@ -804,140 +833,133 @@
 
   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
      (SiS_Pr->SiS_HiVision == 3)) {
-    temp = (tempbx & 0x00FF) - 1;
-    if(!(modeflag & HalfDCLK)) {
-      temp -= 6;
-      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-        temp -= 2;
-        if(ModeNo > 0x13) temp -= 10;
-      }
-    }
+     temp = (tempbx & 0x00FF) - 1;
+     if(!(modeflag & HalfDCLK)) {
+        temp -= 6;
+        if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+           temp -= 2;
+           if(ModeNo > 0x13) temp -= 10;
+        }
+     }
   } else {
-    tempcx = tempbx & 0x00FF;
-    tempbx = (tempbx & 0xFF00) >> 8;
-    tempcx = (tempcx + tempbx) >> 1;
-    temp = (tempcx & 0x00FF) + 2;
-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV){
-       temp--;
-       if(!(modeflag & HalfDCLK)){
-          if((modeflag & Charx8Dot)){
-             temp += 4;
-             if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
-             if(HwDeviceExtension->jChipType >= SIS_315H) {
-	        if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
-             }
-          }
-       }
-    } else {
-       if(!(modeflag & HalfDCLK)) {
-          temp -= 4;
-          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
-             if(SiS_Pr->SiS_VGAHDE >= 800) {
-                temp -= 7;
-	        if(HwDeviceExtension->jChipType < SIS_315H) {
-	           /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
-                   if(SiS_Pr->SiS_ModeType == ModeEGA) {
-                      if(SiS_Pr->SiS_VGAVDE == 1024) {
-                         temp += 15;
-                         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) 
-			    temp += 7;
-                      }
-                   }
-	        }
-                if(SiS_Pr->SiS_VGAHDE >= 1280) {
-                   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
-                      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
-                   }
-                }
-             }
-          }
-       }
-    }
+     tempcx = tempbx & 0x00FF;
+     tempbx = (tempbx & 0xFF00) >> 8;
+     tempcx = (tempcx + tempbx) >> 1;
+     temp = (tempcx & 0x00FF) + 2;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        temp--;
+        if(!(modeflag & HalfDCLK)) {
+           if((modeflag & Charx8Dot)) {
+              temp += 4;
+              if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
+              if(HwDeviceExtension->jChipType >= SIS_315H) {
+	         if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
+              }
+           }
+        }
+     } else {
+        if(!(modeflag & HalfDCLK)) {
+           temp -= 4;
+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+              if(SiS_Pr->SiS_VGAHDE >= 800) {
+                 temp -= 7;
+	         if(HwDeviceExtension->jChipType < SIS_315H) {
+	            /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
+                    if(SiS_Pr->SiS_ModeType == ModeEGA) {
+                       if(SiS_Pr->SiS_VGAVDE == 1024) {
+                          temp += 15;
+                          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
+		  	     temp += 7;
+                       }
+                    }
+	         }
+                 if(SiS_Pr->SiS_VGAHDE >= 1280) {
+                    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
+                 }
+              }
+           }
+        }
+     }
   }
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);               	/* 0x07 Horizontal Retrace Start */
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);                 /* 0x08 Horizontal Retrace End   */
+  p1_7 = temp;
+  p1_8 = 0x00;
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-            if(ModeNo <= 0x01) {
-	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2a);
-		if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x61);
-		} else {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x41);
-		}
-	    } else if(SiS_Pr->SiS_ModeType == ModeText) {
-	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x54);
-		} else {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x55);
-		}
-		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);
-	    } else if(ModeNo <= 0x13) {
-	        if(modeflag & HalfDCLK) {
-		    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
-			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
-		    } else {
-		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
-			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x02);
-		    }
-		} else {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x5b);
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
-		}
-	    } else if( ((HwDeviceExtension->jChipType >= SIS_315H) && (ModeNo == 0x50)) ||
-	               ((HwDeviceExtension->jChipType < SIS_315H) && (resinfo == 0 || resinfo == 1)) ) {
-	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
-		} else {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
-		}
-	    }
-
+        if(ModeNo <= 0x01) {
+	   p1_7 = 0x2a;
+	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_8 = 0x61;
+	   else 	      			p1_8 = 0x41;
+	} else if(SiS_Pr->SiS_ModeType == ModeText) {
+	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_7 = 0x54;
+	   else 	    			p1_7 = 0x55;
+	   p1_8 = 0x00;
+	} else if(ModeNo <= 0x13) {
+	   if(modeflag & HalfDCLK) {
+	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+		 p1_7 = 0x30;
+		 p1_8 = 0x03;
+	      } else {
+	 	 p1_7 = 0x2f;
+		 p1_8 = 0x02;
+	      }
+	   } else {
+	      p1_7 = 0x5b;
+	      p1_8 = 0x03;
+	   }
+	} else if( ((HwDeviceExtension->jChipType >= SIS_315H) &&
+	            ((ModeNo == 0x50) || (ModeNo = 0x56) || (ModeNo = 0x53))) ||
+	           ((HwDeviceExtension->jChipType < SIS_315H) &&
+		    (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
+	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+	      p1_7 = 0x30,
+	      p1_8 = 0x03;
+	   } else {
+	      p1_7 = 0x2f;
+	      p1_8 = 0x03;
+	   }
+        }
      }
   }
+
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
      if(SiS_Pr->SiS_HiVision & 0x03) {
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xb2);
+	p1_7 = 0xb2;
 	if(SiS_Pr->SiS_HiVision & 0x02) {
-	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xab);
+	   p1_7 = 0xab;
 	}
      }
   }
 
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,p1_7);			/* 0x07 Horizontal Retrace Start */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,p1_8);			/* 0x08 Horizontal Retrace End   */
+
+
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08 (FIFO Threshold?)   */
 
   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
 
-  tempbx = SiS_Pr->SiS_VGAVT;
-  push1 = tempbx;
-
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
 
   tempcx = 0x121;
   tempbx = SiS_Pr->SiS_VGAVDE;                               	/* 0x0E Vertical Display End */
-  if(tempbx == 357) tempbx = 350;
-  if(tempbx == 360) tempbx = 350;
-  if(tempbx == 375) tempbx = 350;
-  if(tempbx == 405) tempbx = 400;
-  if(tempbx == 420) tempbx = 400;
-  if(tempbx == 525) tempbx = 480;
+  if     (tempbx == 357) tempbx = 350;
+  else if(tempbx == 360) tempbx = 350;
+  else if(tempbx == 375) tempbx = 350;
+  else if(tempbx == 405) tempbx = 400;
+  else if(tempbx == 420) tempbx = 400;
+  else if(tempbx == 525) tempbx = 480;
   push2 = tempbx;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-    	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-      		if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-        		if(tempbx == 350) tempbx += 5;
-        		if(tempbx == 480) tempbx += 5;
-      		}
-    	}
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+      	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+           if     (tempbx == 350) tempbx += 5;
+           else if(tempbx == 480) tempbx += 5;
+      	}
+     }
   }
-  tempbx--;
-  temp = tempbx & 0x00FF;
-  tempbx--;
+  tempbx -= 2;
   temp = tempbx & 0x00FF;
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);        		/* 0x10 vertical Blank Start */
 
@@ -945,126 +967,91 @@
   tempbx--;
   temp = tempbx & 0x00FF;
 #if 0
-  /* TW: Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
+  /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
   if(xxx()) {
       if(temp == 0xdf) temp = 0xda;
   }
 #endif
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);
 
-  if(tempbx & 0x0100) {
-  	tempcx |= 0x0002;
-	if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x000a;
-  }
+  if(tempbx & 0x0100)  tempcx |= 0x0002;
 
   tempax = 0x000B;
   if(modeflag & DoubleScanMode) tempax |= 0x8000;
 
-  if(tempbx & 0x0200) {
-  	tempcx |= 0x0040;
-	if(SiS_Pr->SiS_VBType & VB_SIS301) tempax |= 0x2000;
-  }
-
-  if(SiS_Pr->SiS_VBType & VB_SIS301) {
-        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-	      if(SiS_Pr->SiS_VGAVDE == 480) {
-	             tempax = (tempax & 0x00ff) | 0x2000;
-		     if(modeflag & DoubleScanMode)  tempax |= 0x8000;
-	      }
-	}
-  }
+  if(tempbx & 0x0200)  tempcx |= 0x0040;
 
   temp = (tempax & 0xFF00) >> 8;
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);
 
-  if(tempbx & 0x0400) tempcx |= 0x0600;
+  if(tempbx & 0x0400)  tempcx |= 0x0600;
 
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
 
-  tempax = push1;
-  tempax -= tempbx;
-  tempax >>= 2;
-  push1 = tempax;
+  tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-        /* TW: 650/30xLV 1.10.6s */
-        if(ModeNo > 0x13) {
-	    if(resinfo != 0x09) {  /* 1280x1024 */
-	        tempax <<= 1;
-		tempbx += tempax;
-	    }
-	} else {
-	    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
-	        tempax <<= 1;
-		tempbx += tempax;
-	    }
-	}
-  } else if((resinfo != 0x09) || (SiS_Pr->SiS_VBType & VB_SIS301)) {
-    	tempax <<= 1;
-    	tempbx += tempax;
+  if((ModeNo > 0x13) || (HwDeviceExtension->jChipType < SIS_315H)) {
+     if(resinfo != SIS_RI_1280x1024) {
+	tempbx += (tempax << 1);
+     }
+  } else if(HwDeviceExtension->jChipType >= SIS_315H) {
+     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+	tempbx += (tempax << 1);
+     }
   }
 
-  if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-      (SiS_Pr->SiS_HiVision == 3) ) {
-    	tempbx -= 10;
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+     (SiS_Pr->SiS_HiVision == 3)) {
+     tempbx -= 10;
   } else {
-    	if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-      	   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-	       if(!(SiS_Pr->SiS_HiVision & 0x03)) {
-                    tempbx += 40;
-		    if(HwDeviceExtension->jChipType >= SIS_315H) {
-		       if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
-		    }
-      	       }
-	   }
-    	}
+     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+	   if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+              tempbx += 40;
+	      if(HwDeviceExtension->jChipType >= SIS_315H) {
+	         if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
+	      }
+      	   }
+	}
+     }
   }
-  tempax = push1;
   tempax >>= 2;
   tempax++;
   tempax += tempbx;
   push1 = tempax;
   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-    	if(tempbx <= 513)  {
-      		if(tempax >= 513) tempbx = 513;
-    	}
+     if(tempbx <= 513)  {
+     	if(tempax >= 513) tempbx = 513;
+     }
   }
   temp = tempbx & 0x00FF;
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
 
-  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
-  	tempbx--;
-  	temp = tempbx & 0x00FF;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
-
-	if(tempbx & 0x0100) tempcx |= 0x0008;
+  tempbx--;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
 
-  	if(tempbx & 0x0200) {
-    	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
-	}
+  if(tempbx & 0x0100) tempcx |= 0x0008;
 
-  	tempbx++;
+  if(tempbx & 0x0200) {
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
   }
+  tempbx++;
+
   if(tempbx & 0x0100) tempcx |= 0x0004;
   if(tempbx & 0x0200) tempcx |= 0x0080;
   if(tempbx & 0x0400) {
-        if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
-  	else                               tempcx |= 0x0C00;
+     if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
+     else                               tempcx |= 0x0C00;
   }
 
   tempbx = push1;
-  temp = tempbx & 0x00FF;
-  temp &= 0x0F;
+  temp = tempbx & 0x000F;
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
 
   if(tempbx & 0x0010) tempcx |= 0x2000;
 
   temp = tempcx & 0x00FF;
-  if(SiS_Pr->SiS_VBType & VB_SIS301) {
-	if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-	      if(SiS_Pr->SiS_VGAVDE == 480)  temp = 0xa3;
-	}
-  }
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);              	/* 0x0A CR07 */
 
   temp = (tempcx & 0xFF00) >> 8;
@@ -1074,8 +1061,8 @@
   temp = (tempax & 0xFF00) >> 8;
   temp = (temp >> 1) & 0x09;
   if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
-       /* Only use 8 dot clock */
-       temp |= 0x01;
+     /* Only use 8 dot clock */
+     temp |= 0x01;
   }
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* 0x16 SR01 */
 
@@ -1084,16 +1071,15 @@
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* 0x12 CR17 */
 
   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-       if(IS_SIS650) {
-           /* TW: 650/30xLV 1.10.6s */
-           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
-	       temp = 0x80;
-	   }
-       } else temp = 0x80;
-  } else  temp = 0x00;
+     if(IS_SIS650) {
+        /* 650/30xLV 1.10.6s */
+        if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+	   temp = 0x80;
+	}
+     } else temp = 0x80;
+  } else temp = 0x00;
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* 0x1A SR0E */
 
-  return;
 }
 
 void
@@ -1108,40 +1094,52 @@
 #endif
   ULONG  tempeax=0, tempebx, tempecx, tempvcfact=0;
 
+  /* This is not supported on LVDS */
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+  if(SiS_Pr->UseCustomMode) return;
+
   if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
 
-  /* TW: Set up Panel Link */
+  /* Set up Panel Link */
 
   /* 1. Horizontal setup */
 
   tempax = SiS_Pr->SiS_LCDHDES;
 
-  if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
-      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
-  	tempax -= 8;
+  if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+     if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
+         (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
+  	   tempax -= 8;
+     }
   }
 
   tempcx = SiS_Pr->SiS_HT;    				  /* Horiz. Total */
 
   tempbx = SiS_Pr->SiS_HDE;                               /* Horiz. Display End */
 
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
+     tempbx >>= 1;
+  }
+
   if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
- 	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempbx =  800;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempbx = 1024;  /* TW */
-    	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempbx = 1024;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempbx = 1152;  /* TW */
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempbx = 1280;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1280; 
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400; 
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600; 
+        if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
+	   tempbx = SiS_Pr->PanelXRes;
+	} else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	   tempbx = SiS_Pr->PanelXRes;
+	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+	      tempbx = 800;
+	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+	         tempbx = 1024;
+	      }
+	   }
         }
      }
   }
@@ -1154,13 +1152,17 @@
   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
 
   push2 = tempax;
-  
-  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
-     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
-     	   else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+
+  if((!SiS_Pr->SiS_IF_DEF_FSTN) &&
+     (!SiS_Pr->SiS_IF_DEF_DSTN) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
+     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+     	      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
+     	      else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
 	            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
 	  	   if(HwDeviceExtension->jChipType < SIS_315H) {
 		      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
@@ -1174,11 +1176,12 @@
 		   } else {
 		      tempcx = 0x0018;
 		   }
+	      }
+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0028;
+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
 	   }
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0028;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
         }
      }
   }
@@ -1188,14 +1191,17 @@
 
   tempax = tempcx >> 3;                          /* BPLHRS */
   temp = tempax & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);		 /* Part1_14h; TW: Panel Link Horizontal Retrace Start  */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);		 /* Part1_14h; Panel Link Horizontal Retrace Start  */
 
   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
      temp = (tempax & 0x00FF) + 2;
   } else {
      temp = (tempax & 0x00FF) + 10;
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if(!SiS_Pr->SiS_IF_DEF_DSTN) {
+        if((!SiS_Pr->SiS_IF_DEF_DSTN) &&
+	   (!SiS_Pr->SiS_IF_DEF_FSTN) &&
+	   (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
+	   (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
 	      temp += 6;
               if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
@@ -1219,47 +1225,57 @@
 
   temp &= 0x1F;
   temp |= ((tempcx & 0x0007) << 5);
-  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);    	 /* Part1_15h; TW: Panel Link Horizontal Retrace End/Skew */
+#if 0
+  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;       /* WRONG? BIOS loads cl, not ah */
+#endif  
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);    	 /* Part1_15h; Panel Link Horizontal Retrace End/Skew */
 
   tempbx = push2;
   tempcx = push1;                                /* lcdhdes  */
 
   temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; TW: Panel Link Vertical Retrace Start (2:0) */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; Panel Link Vertical Retrace Start (2:0) */
 
   tempcx >>= 3;                                  /* BPLHDES */
   temp = (tempcx & 0x00FF);
-  if(ModeNo == 0x5b) temp--;                     
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);    	 /* Part1_16h; TW: Panel Link Horizontal Display Enable Start  */
+#if 0 /* Not 550 FSTN */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     if(ModeNo == 0x5b) temp--; */
+  }
+#endif
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);    	 /* Part1_16h; Panel Link Horizontal Display Enable Start  */
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {  
+  if((HwDeviceExtension->jChipType < SIS_315H) ||
+     (SiS_Pr->SiS_IF_DEF_FSTN) ||
+     (SiS_Pr->SiS_IF_DEF_DSTN)) {
      if(tempbx & 0x07) tempbx += 8;              
   }
   tempbx >>= 3;                                  /* BPLHDEE  */
   temp = tempbx & 0x00FF;
-  if(ModeNo == 0x5b) temp--;			 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);   	 /* Part1_17h; TW: Panel Link Horizontal Display Enable End  */
+#if 0 /* Not 550 FSTN */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     if(ModeNo == 0x5b) temp--;
+  }
+#endif
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);   	 /* Part1_17h; Panel Link Horizontal Display Enable End  */
 
   /* 2. Vertical setup */
 
   if(HwDeviceExtension->jChipType < SIS_315H) {
      tempcx = SiS_Pr->SiS_VGAVT;
      tempbx = SiS_Pr->SiS_VGAVDE;
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)       tempbx =  600;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempbx =  600;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx =  768;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempbx =  768;
-	   else								tempbx = 1024;
-        }
+     if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) && (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	      tempbx = SiS_Pr->PanelYRes;
+           }
+	}
      }
      tempcx -= tempbx;
 
   } else {
 
-     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;          /* VGAVT-VGAVDE  */
+     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;           /* VGAVT-VGAVDE  */
 
   }
 
@@ -1268,18 +1284,20 @@
 
   tempax = SiS_Pr->SiS_VGAVDE;
 
-  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
-     if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0)   && 
-         (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
-         (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempax =  600;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempax =  600;  
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempax =  768;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempax =  768;  
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempax =  768;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempax = 1024; 
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempax = 1050; 
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempax = 1200; 
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+     if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+           tempax = 600;
+	   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+	      tempax = 768;
+	   }
+	}
+     } else if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0)   &&
+                (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
+                ((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ||
+	         (SiS_Pr->SiS_IF_DEF_FSTN) ||
+	         (SiS_Pr->SiS_IF_DEF_DSTN)) ) {
+	tempax = SiS_Pr->PanelYRes;
      }
   }
 
@@ -1290,11 +1308,24 @@
 
   tempcx >>= 1;
 
-  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
-     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-        if(!SiS_Pr->SiS_IF_DEF_DSTN) {
-     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0001;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0001;
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
+	tempcx = 0x0017;
+     } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+        if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
+	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0003;
+  	   else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+	           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)) tempcx = 0x0003;
+           else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0001;
+           else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0001;
+	   else 							  tempcx = 0x0057;
+        } else  {
+     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0001;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0001;
      	   else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
 	           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)) {
 		   if(HwDeviceExtension->jChipType < SIS_315H) {
@@ -1304,7 +1335,7 @@
 			    tempcx = 0x0003;
 #endif
 		      } else {
-		            tempcx = 0x0002;   /* TW: A901; sometimes 0x0003; */
+		            tempcx = 0x0002;   /* A901; sometimes 0x0003; */
 		      }
 		   } else tempcx = 0x0003;
            }
@@ -1319,26 +1350,32 @@
 
   tempbx += tempcx;			 	/* BPLVRS  */
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-      tempbx++;
+  if((HwDeviceExtension->jChipType < SIS_315H) ||
+     (SiS_Pr->SiS_IF_DEF_FSTN) ||
+     (SiS_Pr->SiS_IF_DEF_DSTN)) {
+     tempbx++;
   }
 
   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
 
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; TW: Panel Link Vertical Retrace Start  */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; Panel Link Vertical Retrace Start  */
 
   tempcx >>= 3;
 
-  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+  if((!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
         if( (HwDeviceExtension->jChipType < SIS_315H) &&
             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) )     tempcx = 0x0001;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2)  tempcx = 0x0002;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)  tempcx = 0x0002;
         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)    tempcx = 0x0003;
         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0005;
         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)   tempcx = 0x0005;
 	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 0x0011;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0005;	 
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0005;
         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0002;
         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 0x0011;
         else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
@@ -1360,26 +1397,36 @@
 
   tempcx = tempcx + tempbx + 1;                  /* BPLVRE  */
   temp = tempcx & 0x000F;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; TW: Panel Link Vertical Retrace End (3:0); Misc.  */
+  if(SiS_Pr->SiS_IF_DEF_FSTN ||
+     SiS_Pr->SiS_IF_DEF_DSTN ||
+     (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+     (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+     temp |= 0x30;
+  }
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; Panel Link Vertical Retrace End (3:0); Misc.  */
 
   temp = ((tempbx & 0x0700) >> 8) << 3;          /* BPLDESKEW =0 */
-  if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
+  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
+     if(SiS_Pr->SiS_HDE != 640) {
+        if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)   temp |= 0x40;
+     }
+  } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)           temp |= 0x40;
   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
-         if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
-            temp |= 0x80;
-         }
-      } else {
-	 if( (HwDeviceExtension->jChipType == SIS_630) ||
-	     (HwDeviceExtension->jChipType == SIS_730) ) {
-	    if(HwDeviceExtension->jChipRevision >= 0x30) {
-	       temp |= 0x80;
-	    }
-	 }
-      }
+     if(HwDeviceExtension->jChipType >= SIS_315H) {
+        if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+           temp |= 0x80;
+        }
+     } else {
+	if( (HwDeviceExtension->jChipType == SIS_630) ||
+	    (HwDeviceExtension->jChipType == SIS_730) ) {
+	   if(HwDeviceExtension->jChipRevision >= 0x30) {
+	      temp |= 0x80;
+	   }
+	}
+     }
   }
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; TW: Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
 
   if (HwDeviceExtension->jChipType < SIS_315H) {
 
@@ -1396,19 +1443,19 @@
 	}
 
   	temp = (USHORT)(tempebx & 0x00FF);
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; TW: Panel Link Vertical Scaling Factor */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; Panel Link Vertical Scaling Factor */
 
 #endif /* SIS300 */
 
   } else {
 
-#ifdef SIS315H  /* 310/325 series */
+#ifdef SIS315H  /* 315 series */
 
-#ifdef NEWCH701x
-        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
-#else
-	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
-#endif	
+        if(HwDeviceExtension->jChipType == SIS_740) {
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
+        } else {
+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
+	}
 
 	tempeax = SiS_Pr->SiS_VGAVDE << 18;
     	temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
@@ -1417,12 +1464,13 @@
     	tempebx = tempeax;                         /* BPLVCFACT  */
         tempvcfact = tempeax;
     	temp = (USHORT)(tempebx & 0x00FF);
-    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; TW: Panel Link Vertical Scaling Factor */
+    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; Panel Link Vertical Scaling Factor */
     	temp = (USHORT)((tempebx & 0x00FF00) >> 8);
-    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; TW: Panel Link Vertical Scaling Factor */
+    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; Panel Link Vertical Scaling Factor */
     	temp = (USHORT)((tempebx & 0x00030000) >> 16);
+	temp &= 0x03;
     	if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
-    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; TW: Panel Link Vertical Scaling Factor */
+    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; Panel Link Vertical Scaling Factor */
 
 #endif /* SIS315H */
 
@@ -1434,47 +1482,50 @@
   push1 = temp;					   
 
   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-   	if(!SiS_Pr->SiS_IF_DEF_DSTN){
+   	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
 		if(HwDeviceExtension->jChipType < SIS_315H) {
 			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-      				if(resinfo == 15) tempcx++;
+      				if(resinfo == SIS_RI_1024x600) tempcx++;
 				if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-					if(resinfo == 7) tempcx++;
+					if(resinfo == SIS_RI_800x600) tempcx++;
 		    		}
 			} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-      				if(resinfo == 7) tempcx++;
-				if(resinfo == 8) tempcx++; /* TW: Doesnt make sense anyway... */
-			} else  if(resinfo == 8) tempcx++;
+      				if(resinfo == SIS_RI_800x600)  tempcx++;
+				if(resinfo == SIS_RI_1024x768) tempcx++; /* Doesnt make sense anyway... */
+			} else  if(resinfo == SIS_RI_1024x768) tempcx++;
 		} else {
 			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-      				if(resinfo == 7) tempcx++;
+      				if(resinfo == SIS_RI_800x600)  tempcx++;
 			}
 		}
 	}
   }
 
   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-     tempcx = SiS_Pr->SiS_VGAVDE;
-     tempbx = SiS_Pr->SiS_VGAVDE - 1;
+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+        tempcx = SiS_Pr->SiS_VGAVDE;
+        tempbx = SiS_Pr->SiS_VGAVDE - 1;
+     }
   }
 
   temp = ((tempbx & 0x0700) >> 8) << 3;
   temp |= ((tempcx & 0x0700) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; TW: Vertical Display Overflow; Control Signal */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; Vertical Display Overflow; Control Signal */
 
   temp = tempbx & 0x00FF;
-  if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; TW: Panel Link Vertical Display Enable End  */
+  /* if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;  */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; Panel Link Vertical Display Enable End  */
 
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; TW: Panel Link Vertical Display Enable Start  */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; Panel Link Vertical Display Enable Start  */
 
   /* 3. Additional horizontal setup (scaling, etc) */
 
   tempecx = SiS_Pr->SiS_VGAHDE;
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if(modeflag & HalfDCLK)
-        tempecx >>= 1;
+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+        if(modeflag & HalfDCLK) tempecx >>= 1;
+     }
   }
   tempebx = SiS_Pr->SiS_HDE;
   if(tempecx == tempebx) tempeax = 0xFFFF;
@@ -1484,139 +1535,165 @@
      temp = (USHORT)(tempeax % tempebx);
      tempeax = tempeax / tempebx;
      if(HwDeviceExtension->jChipType >= SIS_315H) {
-         if(temp) tempeax++;
+        if(temp) tempeax++;
      }
   }
   tempecx = tempeax;
 
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      tempeax = SiS_Pr->SiS_VGAHDE;
-      if(modeflag & HalfDCLK) tempeax >>= 1;
-      tempeax <<= 16;
-      tempeax = (tempeax / tempecx) - 1;
+     tempeax = SiS_Pr->SiS_VGAHDE;
+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+        if(modeflag & HalfDCLK) tempeax >>= 1;
+     }
+     tempeax <<= 16;
+     tempeax = (tempeax / tempecx) - 1;
   } else {
-      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
+     tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
   }
   tempecx <<= 16;
   tempecx |= (tempeax & 0xFFFF);
   temp = (USHORT)(tempecx & 0x00FF);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; TW: Panel Link DDA Operational Number in each horiz. line */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; Panel Link DDA Operational Number in each horiz. line */
 
   tempbx = SiS_Pr->SiS_VDE;
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
-      tempbx = (USHORT)(tempeax & 0x0FFFF);
+     tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
+     tempbx = (USHORT)(tempeax & 0x0FFFF);
   } else {
-      tempax = SiS_Pr->SiS_VGAVDE << 6;
-      tempbx = push1;
-      tempbx &= 0x3f;
-      if(tempbx == 0) tempbx = 64;
-      tempax = tempax / tempbx;
-      tempbx = tempax;
+     tempeax = SiS_Pr->SiS_VGAVDE << 6;
+     tempbx = push1 & 0x3f;
+     if(tempbx == 0) tempbx = 64;
+     tempeax /= tempbx;
+     tempbx = (USHORT)(tempeax & 0x0FFFF);
   }
   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)                 tempbx = 1;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
+     else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  tempbx = 1;
+  }
 
   temp = ((tempbx & 0xFF00) >> 8) << 3;
   temp |= (USHORT)((tempecx & 0x0700) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);  	/* Part1_20h; TW: Overflow register */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);  	/* Part1_20h; Overflow register */
 
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);  	/* Part1_21h; TW: Panel Link Vertical Accumulator Register */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);  	/* Part1_21h; Panel Link Vertical Accumulator Register */
 
   tempecx >>= 16;                               /* BPLHCFACT  */
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-      if(modeflag & HalfDCLK) tempecx >>= 1;
+  if((HwDeviceExtension->jChipType < SIS_315H) || (SiS_Pr->SiS_IF_DEF_FSTN) || (SiS_Pr->SiS_IF_DEF_DSTN)) {
+     if(modeflag & HalfDCLK) tempecx >>= 1;
   }
   temp = (USHORT)((tempecx & 0xFF00) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);     	/* Part1_22h; TW: Panel Link Horizontal Scaling Factor High */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);     	/* Part1_22h; Panel Link Horizontal Scaling Factor High */
 
   temp = (USHORT)(tempecx & 0x00FF);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; TW: Panel Link Horizontal Scaling Factor Low */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; Panel Link Horizontal Scaling Factor Low */
 
   /* 630/301B and 630/LVDS do something for 640x480 panels here */
 
 #ifdef SIS315H
-  /* TW: DSTN/FSTN initialisation - hardcoded for 320x480 panel */
-  if(SiS_Pr->SiS_IF_DEF_DSTN) {
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x01);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
-     	tempbx = SiS_Pr->SiS_HDE + 64;                       	/*Blps = lcdhdee(lcdhdes+HDE) + 64*/
-     	temp = tempbx & 0x00FF;
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
-     	temp=((tempbx & 0xFF00) >> 8) << 3;
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
-     	tempbx += 32;		                     		/*Blpe=lBlps+32*/
-     	temp = tempbx & 0x00FF;
-     	if(SiS_Pr->SiS_IF_DEF_FSTN)  temp=0;
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00);        	/*Bflml=0*/
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
-     	tempbx = SiS_Pr->SiS_VDE / 2;
-     	temp = tempbx & 0x00FF;
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
-     	temp = ((tempbx & 0xFF00) >> 8) << 3;
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
-     	tempeax = SiS_Pr->SiS_HDE << 2;                       	/* BDxFIFOSTOP = (HDE*4)/128 */
-     	tempebx = 128;
-     	temp = (USHORT)(tempeax % tempebx);
-     	tempeax = tempeax / tempebx;
-     	if(temp != 0)  tempeax++;
-     	temp = (USHORT)(tempeax & 0x003F);
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00);         	/* BDxWadrst0 */
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
-     	tempax = SiS_Pr->SiS_HDE >> 4;                        	/* BDxWadroff = HDE*4/8/8 */
-     	pushcx = tempax;
-     	temp = tempax & 0x00FF;
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
-     	temp = ((tempax & 0xFF00) >> 8) << 3;
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
-     	tempax = SiS_Pr->SiS_VDE;                             /*BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
-     	tempeax = (tempax * pushcx);
-     	tempebx = 0x00100000 + tempeax;
-     	temp = (USHORT)tempebx & 0x000000FF;
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
-     	temp = (USHORT)((tempebx & 0x0000FF00)>>8);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
-     	temp = (USHORT)((tempebx & 0x00FF0000)>>16);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
-     	temp = (USHORT)(((tempebx & 0x01000000)>>24) << 7);
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x13,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);        /* Unlock */
-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
-     	if(SiS_Pr->SiS_IF_DEF_FSTN){
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2b,0x1b);
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2c,0xe3);
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2e,0x04);
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2f,0x42);
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,0x01);
-         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
-         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
-         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
-     	}
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,0x30);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x7d);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2e,0xe0);
+  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
+     tempax = SiS_Pr->SiS_HDE;                       		/* Blps = lcdhdee(lcdhdes+HDE) + 64 */
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     tempax += 64;
+     temp = tempax & 0x00FF;
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
+     temp = ((tempax & 0xFF00) >> 8) << 3;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
+     tempax += 32;		                     		/* Blpe=lBlps+32 */
+     temp = tempax & 0x00FF;
+     if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00);        	/* Bflml=0 */
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
+
+     tempax = SiS_Pr->SiS_VDE;
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     tempax >>= 1;
+     temp = tempax & 0x00FF;
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
+     temp = ((tempax & 0xFF00) >> 8) << 3;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
+
+     tempeax = SiS_Pr->SiS_HDE;
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempeax >>= 1;
+     tempeax <<= 2;                       			/* BDxFIFOSTOP = (HDE*4)/128 */
+     tempebx = 128;
+     temp = (USHORT)(tempeax % tempebx);
+     tempeax = tempeax / tempebx;
+     if(temp) tempeax++;
+     temp = (USHORT)(tempeax & 0x003F);
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00);         	/* BDxWadrst0 */
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
+
+     tempax = SiS_Pr->SiS_HDE;
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     tempax >>= 4;                        			/* BDxWadroff = HDE*4/8/8 */
+     pushcx = tempax;
+     temp = tempax & 0x00FF;
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
+     temp = ((tempax & 0xFF00) >> 8) << 3;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
+
+     tempax = SiS_Pr->SiS_VDE;                             	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     tempeax = (tempax * pushcx);
+     tempebx = 0x00100000 + tempeax;
+     temp = (USHORT)tempebx & 0x000000FF;
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
+     temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
+     temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
+     temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
+
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0x38);
+
+     if(SiS_Pr->SiS_IF_DEF_FSTN) {
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,0x0c);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,0x00);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,0x00);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,0x80);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,0xA0);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3a,0x00);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3c,0x00);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3d,0x10);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3e,0x00);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3f,0x00);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,0x10);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,0x25);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,0x80);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,0x14);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x44,0x03);
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x45,0x0a);
+     }
   }
 #endif  /* SIS315H */
 
-  return;
-
 }
 
 #ifdef SIS315H
@@ -1629,7 +1706,7 @@
 
 
 #ifdef SIS315H
-/* TW: For LVDS / 302B/30xLV - LCDA (this must only be called on 310/325 series!) */
+/* For LVDS / 302B/30xLV - LCDA (this must only be called on 315 series!) */
 void
 SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                    PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
@@ -1638,6 +1715,10 @@
   USHORT push1,push2,tempax,tempbx,tempcx,temp;
   ULONG tempeax=0,tempebx,tempecx,tempvcfact;
 
+  /* This is not supported with LCDA */
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+  if(SiS_Pr->UseCustomMode) return;
+
   if(IS_SIS330) {
      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* Xabre 1.01.03 */
   } else if(IS_SIS740) {
@@ -1645,7 +1726,7 @@
         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);      	/* 740/LVDS */
 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
      } else {
-        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* 740/301LV 1.10.1i */
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* 740/301LV, 301BDH */
      }
   } else {
      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* 650/LVDS */
@@ -1669,10 +1750,7 @@
   tempcx = SiS_Pr->SiS_HT;
 
   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx = 1024;
-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400;
-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600;
-	else 							      tempbx = 1280;
+        tempbx = SiS_Pr->PanelXRes;
   }
   tempcx -= tempbx;                        	            	/* HT-HDE  */
   push1 = tempax;
@@ -1684,7 +1762,7 @@
 
   tempcx >>= 2;
 
-  /* TW: 650/30xLV 1.10.6s, 740/LVDS */
+  /* 650/30xLV 1.10.6s, 740/LVDS */
   if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
       ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
@@ -1748,13 +1826,10 @@
   tempbx = SiS_Pr->SiS_LCDVDES;                                	/* VGAVDES  */
   push1 = tempbx;                                      		
   if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)        tempax = 768;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempax = 768;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempax = 1024;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempax = 1050;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempax = 1200;
-    else                                                           tempax = 960;
-  } else tempax = SiS_Pr->SiS_VGAVDE;  /* Trumpion */
+     tempax = SiS_Pr->PanelYRes;
+  } else {
+     tempax = SiS_Pr->SiS_VGAVDE;
+  }
 
   tempbx += tempax;
   tempax = SiS_Pr->SiS_VT;                                    	/* VT  */
@@ -1764,7 +1839,7 @@
  
   tempcx >>= 2;	
 
-  /* TW: 650/30xLV 1.10.6s, 740/LVDS */
+  /* 650/30xLV 1.10.6s, 740/LVDS */
   if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
       ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
@@ -1806,7 +1881,7 @@
   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);
   } else {
-     /* TW: 650/30xLV 1.10.6s, Xabre */
+     /* 650/30xLV 1.10.6s, Xabre */
      temp |= 0xC0;
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);             /* Part1_19h  */
   }
@@ -1823,7 +1898,7 @@
      }
   } else {
      if(IS_SIS650) {
-        /* TW: 650/30xLV 1.10.6s */
+        /* 650/30xLV 1.10.6s */
         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
            if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
         }
@@ -1839,7 +1914,7 @@
 
   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-      if(resinfo == 7) tempcx++;
+      if(resinfo == SIS_RI_800x600) tempcx++;
     }
   }
   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
@@ -1925,18 +2000,17 @@
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);
 
 #if 0
-  /* TW: Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */
+  /* Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */
   if(xxx()) {
       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0e,0xda);
   }
 #endif
 
-  /* TW: Only for LVDS and 301LV/302LV */
+  /* Only for LVDS and 301LV/302LV */
   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)){
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
   }
 
-  return;
 }
 #endif  /* SIS 315 */
 
@@ -1951,10 +2025,10 @@
 
   offset = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                          HwDeviceExtension);
-#if 0
-  if(SiS_Pr->LCDResInfo == 13) offset >>= 1;
-  if(SiS_Pr->LCDResInfo == 12) offset >>= 1;
-#endif			 
+
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) offset >>= 1;
+
   temp = (UCHAR)(offset & 0xFF);
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);
   temp = (UCHAR)((offset & 0xFF00) >> 8);
@@ -1976,13 +2050,7 @@
   } else {
      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
      modeinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
-  
-     if(HwDeviceExtension->jChipType < SIS_315H ) {
-    	index = (modeinfo >> 4) & 0xFF;
-     } else {
-    	index = (modeinfo >> 8) & 0xFF;
-     }
-
+     index = (modeinfo >> 8) & 0xFF;
      temp = SiS_Pr->SiS_ScreenOffset[index];
   }
   
@@ -1992,9 +2060,8 @@
 
   temp *= colordepth;
 
-  /* TW: For 1400x1050 and 856x480 */
-  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) || 
-        ModeNo == 0x3f || 
+  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) ||
+        ModeNo == 0x3f ||
 	ModeNo == 0x42 || 
 	ModeNo == 0x45 ) ||
       (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
@@ -2012,7 +2079,8 @@
   SHORT  index;
   USHORT modeflag;
 
-  if(SiS_Pr->UseCustomMode) {
+  /* Do NOT check UseCustomMode, will skrew up FIFO */
+  if(ModeNo == 0xfe) {
      modeflag = SiS_Pr->CModeFlag;
   } else {
      if(ModeNo <= 0x13)
@@ -2035,7 +2103,11 @@
   flag = 0;
   tempbl = 0xC0;
 
-  infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  if(SiS_Pr->UseCustomMode) {
+     infoflag = SiS_Pr->CInfoFlag;
+  } else {
+     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  }
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
 
@@ -2044,12 +2116,19 @@
     } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
        tempah = SiS_Pr->SiS_LCDInfo;
     } else tempah = infoflag >> 8;
-    
+
     tempah &= 0xC0;
-    
+
     tempah |= 0x20;
     if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
 
+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+       if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+          (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+	  tempah |= 0xc0;
+       }
+    }
+
     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
        if(HwDeviceExtension->jChipType >= SIS_315H) {
           tempah >>= 3;
@@ -2079,9 +2158,11 @@
             tempah |= 0x20;
             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
 
+#if 0
             if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-	       	/* TW: BIOS does something here @@@ */
+	       	/* BIOS does something here @@@ */
             }
+#endif
 
  	    tempah &= 0x3f;
   	    tempah |= tempbl;
@@ -2089,16 +2170,11 @@
 
          } else {							/* 630 - 301 */
 
-            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-               tempah = SiS_Pr->SiS_LCDInfo;
-	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCDShift) { /* ! */
-	          flag = 1;
-	       }
-            }
-            if(flag != 1) tempah = infoflag >> 8;
+            tempah = infoflag >> 8;
             tempah &= 0xC0;
-            tempah |= 0x30;
-            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x3F,tempah);
+            tempah |= 0x20;
+	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
 
          }
 
@@ -2106,9 +2182,9 @@
 
       } else {
 
-#ifdef SIS315H  /* ----- 310/325 series ---- */
+#ifdef SIS315H  /* ------- 315 series ------ */
 
-         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 310/325 - 30xLV */
+         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 315 - 30xLV */
 
             tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
             tempah &= 0xC0;
@@ -2116,24 +2192,33 @@
             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
 
-         } else {							/* 310/325 - 301, 301B */
+         } else {							/* 315 - 301, 301B */
 
             tempah = infoflag >> 8;
             tempah &= 0xC0;
-	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-	          tempah = SiS_Pr->SiS_LCDInfo;
-	          tempah &= 0xC0;
+	    if(!SiS_Pr->UseCustomMode) {
+	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+	          if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+	             tempah = SiS_Pr->SiS_LCDInfo;
+	             tempah &= 0xC0;
+	          }
 	       }
 	    }
 	    
             tempah |= 0x20;
             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+	    
 #if 0
             if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-		/* TW: BIOS does something here @@@ */
+		/* BIOS does something here @@@ */
             }
-#endif	    
+#endif
+
+	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {			/* TEST, imitate BIOS bug */
+	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	          tempah |= 0xc0;
+	       }
+	    }
             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
 
          } 
@@ -2143,7 +2228,7 @@
    }
 }
 
-/* TW: Set CRT2 FIFO on 300/630/730 */
+/* Set CRT2 FIFO on 300/630/730 */
 #ifdef SIS300
 void
 SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
@@ -2197,7 +2282,7 @@
 
   if(!SiS_Pr->CRT1UsesCustomMode) {
   
-     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
+     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 	/* get CRT1 ModeNo */
      SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&modeidindex);
      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
      SiS_Pr->SiS_SelectCRT2Rate = 0;
@@ -2205,20 +2290,32 @@
 						modeidindex,HwDeviceExtension);
 
      if(CRT1ModeNo >= 0x13) {
-       index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
-       index &= 0x3F;
-       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;			/* Get VCLK */
-       data2 = SiS_Pr->SiS_ModeType - 2;
+        index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
+        index &= 0x3F;
+        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;				/* Get VCLK */
+
+	colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,modeidindex); 	/* Get colordepth */
+        colorth >>= 1;
+        if(!colorth) colorth++;
      }
-     
+
   } else {
   
      CRT1ModeNo = 0xfe;
-     VCLK = SiS_Pr->CSRClock;						/* Get VCLK */
-     data2 = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
-  
-  }			
-     
+     VCLK = SiS_Pr->CSRClock_CRT1;						/* Get VCLK */
+     data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
+     switch(data2) {								/* Get color depth */
+        case 0 : colorth = 1; break;
+        case 1 : colorth = 1; break;
+        case 2 : colorth = 2; break;
+        case 3 : colorth = 2; break;
+        case 4 : colorth = 3; break;
+        case 5 : colorth = 4; break;
+        default: colorth = 2;
+     }
+
+  }
+
   if(CRT1ModeNo >= 0x13) {
     if(HwDeviceExtension->jChipType == SIS_300) {
        index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
@@ -2227,22 +2324,8 @@
     }
     index &= 0x07;
     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;				/* Get MCLK */
-    
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "FIFO2: CRT1Mode 0x%x VCLK %d MCLK %d modetype-2 = %d\n",
-    	CRT1ModeNo, VCLK, MCLK, data2);
-#endif  
-  
-    switch(data2) {							/* Get color depth */
-      case 0 : 	colorth = 1; break;
-      case 1 : 	colorth = 1; break;
-      case 2 : 	colorth = 2; break;
-      case 3 : 	colorth = 2; break;
-      case 4 : 	colorth = 3; break;
-      case 5 : 	colorth = 4; break;
-      default:  colorth = 2; break;
-    }
-    data2 = (colorth * VCLK) / MCLK;  
+
+    data2 = (colorth * VCLK) / MCLK;
 
     temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
     temp = ((temp & 0x00FF) >> 6) << 1;
@@ -2252,22 +2335,12 @@
 
     data2 = temp - data2;
     
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step1) = %d\n",
-    	data2);
-#endif    
-
     if((28 * 16) % data2) {
       	data2 = (28 * 16) / data2;
       	data2++;
     } else {
       	data2 = (28 * 16) / data2;
     }
-    
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step2) = %d\n",
-    	data2);
-#endif
 
     if(HwDeviceExtension->jChipType == SIS_300) {
 
@@ -2313,10 +2386,6 @@
        temp &= 0x0F;   
        tempal |= temp;
 
-#ifdef TWDEBUG
-       xf86DrvMsg(0, X_INFO, "FIFO2: Latencyfactorindex = 0x%x\n", tempal);
-#endif
-      
        tempbx = tempal;   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
        tempbx = 0;        /* -- do it like the BIOS anyway... */
        tempax = tempbx;
@@ -2341,7 +2410,7 @@
        SiS_SetReg4(0xcf8,0x800000A0);
        eax = SiS_GetReg3(0xcfc);
 #else
-       /* TW: We use pci functions X offers. We use tag 0, because
+       /* We use pci functions X offers. We use tag 0, because
         * we want to read/write to the host bridge (which is always
         * 00:00.0 on 630, 730 and 540), not the VGA device.
         */
@@ -2368,43 +2437,41 @@
        if(!(temp & 0x80)) data += 5;
     }
     
-#ifdef TWDEBUG    
-    xf86DrvMsg(0, X_INFO, "FIFO2: latencyfactor (CRT1) = %d\n", data);
-#endif
-
     data += data2;				/* CRT1 Request Period */
     
-#ifdef TWDEBUG    
-    xf86DrvMsg(0, X_INFO, "FIFO2: CRT1 request period = %d\n", data);
-#endif
-
-    CRT2ModeNo = ModeNo;
     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
-    SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);    
 
-    refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
-                                               modeidindex,HwDeviceExtension);
+    if(!SiS_Pr->UseCustomMode) {
+
+       CRT2ModeNo = ModeNo;
+       SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);
+
+       refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
+                                                  modeidindex,HwDeviceExtension);
+
+       index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
+                               refreshratetableindex,HwDeviceExtension);
+       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                         	/* Get VCLK  */
+
+       if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+	     if(ROMAddr[0x220] & 0x01) {
+                VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
+	     }
+          }
+       }
+
+    } else {
+
+       CRT2ModeNo = 0xfe;
+       VCLK = SiS_Pr->CSRClock;							/* Get VCLK */
 
-    index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
-                            refreshratetableindex,HwDeviceExtension);
-    VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                         	/* Get VCLK  */
-    
-    data2 = SiS_Pr->SiS_ModeType - 2;
-    switch(data2) {							/* Get color depth */
-      case 0 : 	colorth = 1; break;
-      case 1 : 	colorth = 1; break;
-      case 2 : 	colorth = 2; break;
-      case 3 : 	colorth = 2; break;
-      case 4 : 	colorth = 3; break;
-      case 5 : 	colorth = 4; break;
-      default:  colorth = 2; break;
     }
-    
-#ifdef TWDEBUG    
-    xf86DrvMsg(0, X_INFO, "FIFO2: CRT2Mode 0x%x VCLK %d MCLK %d modetype-2 = %d, colorth %d\n",
-    	CRT2ModeNo, VCLK, MCLK, data2, colorth);
-#endif
+
+    colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex);   	/* Get colordepth */
+    colorth >>= 1;
+    if(!colorth) colorth++;
 
     data = data * VCLK * colorth;
     if(data % (MCLK << 4)) {
@@ -2414,10 +2481,6 @@
       	data = data / (MCLK << 4);
     }
     
-#ifdef TWDEBUG    
-    xf86DrvMsg(0, X_INFO, "FIFO2: data (unclipped) = 0x%x\n", data);
-#endif    
-    
     if(data <= 6) data = 6;
     if(data > 0x14) data = 0x14;
 
@@ -2456,13 +2519,13 @@
 }
 #endif
 
-/* TW: Set FIFO on 310/325/330 series */
+/* Set FIFO on 315/330 series */
 #ifdef SIS315H
 void
 SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
                     PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-
+#if 0   /* This code is obsolete */
   UCHAR CombCode[]  = { 1, 1, 1, 4, 3, 1, 3, 4,
                         4, 1, 4, 4, 5, 1, 5, 4};
   UCHAR CRT2ThLow[] = { 39, 63, 55, 79, 78,102, 90,114,
@@ -2474,11 +2537,13 @@
   USHORT ModeIdIndex;
   USHORT RefreshRateTableIndex;
   USHORT SelectRate_backup;
-  
+
   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
-  
+#endif
+
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,0x3B);
 
+#if 0
   if(!SiS_Pr->CRT1UsesCustomMode) {
   
      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
@@ -2489,28 +2554,27 @@
 
      /* Get REFIndex for crt1 refreshrate */
      RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
-                                             ModeIdIndex,HwDeviceExtension);
+                                                ModeIdIndex,HwDeviceExtension);
+     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;			/* Get VCLK */
 
-     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex,
-                          RefreshRateTableIndex,HwDeviceExtension);
-     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                        /* Get VCLK */
-     
      tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */
      tempbx >>= 1;
-     if(!tempbx) tempbx++; 
-     
+     if(!tempbx) tempbx++;
+
   } else {
-  
-     tempax = SiS_Pr->CSRClock;						/* Get VCLK */
-     tempbx = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
+
+     CRT1ModeNo = 0xfe;
+     tempax = SiS_Pr->CSRClock_CRT1;					/* Get VCLK */
+     tempbx = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
      switch(tempbx) {							/* Get color depth */
-       case 0 : 	tempbx = 1; break;
-       case 1 : 	tempbx = 1; break;
-       case 2 : 	tempbx = 2; break;
-       case 3 : 	tempbx = 2; break;
-       case 4 : 	tempbx = 3; break;
-       case 5 : 	tempbx = 4; break;
-       default:  	tempbx = 2; break;
+       case 0 : tempbx = 1; break;
+       case 1 : tempbx = 1; break;
+       case 2 : tempbx = 2; break;
+       case 3 : tempbx = 2; break;
+       case 4 : tempbx = 3; break;
+       case 5 : tempbx = 4; break;
+       default: tempbx = 2;
      }
   
   }
@@ -2523,13 +2587,6 @@
 
   tempbx = tempax;
 
-#if 0 /* TW: BIOS code is skrewed */
-  if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x02) {
-   	tempax = 16;
-  } else {
-    	tempax = 8;
-  }
-#endif
   tempax = 16;
 
   tempax -= tempbx;
@@ -2556,24 +2613,33 @@
 
   tempcx +=  temp3;                                      /* CRT1 Request Period */
 
-  CRT2ModeNo = ModeNo;                                                 /* get CRT2 ModeNo */
-  SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex);           /* Get ModeID Table */
-
   SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
   SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
 
-  RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
-                                           ModeIdIndex,HwDeviceExtension);
+  if(!SiS_Pr->UseCustomMode) {
+
+     CRT2ModeNo = ModeNo;                                                 /* get CRT2 ModeNo */
+     SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex);
+
+     RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
+                                                ModeIdIndex,HwDeviceExtension);
+
+     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
+                             RefreshRateTableIndex,HwDeviceExtension);
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+        tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                       /* Get VCLK  */
+     } else {
+        tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK;
+     }
 
-  index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
-                          RefreshRateTableIndex,HwDeviceExtension);
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                       /* Get VCLK  */
   } else {
-     tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK;                     /* Get VCLK  */
+
+     CRT2ModeNo = 0xfe;							  /* Get VCLK  */
+     tempax = SiS_Pr->CSRClock;
+
   }
 
-  tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex);   /* Get colordepth */
+  tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex);   	  /* Get colordepth */
   tempbx >>= 1;
   if(!tempbx) tempbx++;
 
@@ -2590,12 +2656,16 @@
 
   if (tempax > 0x37)  tempax = 0x37;
 
-  /* TW: 650/LVDS (1.10.07, 1.10.00), 650/301LV, 740, 330 overrule calculated value; 315 does not */
+  /* 650/LVDS, 650/301LV, 740, 330 overrule calculated value; 315 does not */
   if(HwDeviceExtension->jChipType >= SIS_650) {
   	tempax = 0x04;
   }
-  
   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,tempax);
+#else
+
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,0x04);
+
+#endif
 }
 
 USHORT
@@ -2611,9 +2681,10 @@
     return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
   }
 }
+
 #endif
 
-/* TW: Checked against 650/LVDS 1.10.07 BIOS */
+/* Checked against 650/LVDS 1.10.07 BIOS */
 void
 SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                    USHORT RefreshRateTableIndex,
@@ -2623,6 +2694,13 @@
   USHORT PanelIndex,ResIndex;
   const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
 
+  if((SiS_Pr->UseCustomMode) ||
+     (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)) {
+     SiS_Pr->SiS_LCDHDES = 0;
+     SiS_Pr->SiS_LCDVDES = 0;
+     return;
+  }
+
   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
 
 #ifdef SIS315H  
@@ -2689,11 +2767,11 @@
      	case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;    break;
      	case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;    break;
 	default:
-		if(HwDeviceExtension->jChipType < SIS_315H)
-		   PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
-		else
-		   PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
-		break;
+		 if(HwDeviceExtension->jChipType < SIS_315H)
+		    PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
+		 else
+		    PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
+		 break;
      }
   }
   SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
@@ -2710,7 +2788,7 @@
      } else {
         if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
            if( (HwDeviceExtension->jChipType < SIS_315H) || 
-	       (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) {  
+	       (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) {
               if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768){
                  if(ModeNo <= 0x13) {
 	            modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
@@ -2737,7 +2815,7 @@
         }
      }
   }
-  return;
+
 }
 
 void
@@ -2757,11 +2835,11 @@
 
   tempbx = 0;
   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
         tempbx = 50;
         if((SiS_Pr->SiS_VBInfo & SetPALTV) && (!SiS_Pr->SiS_CHPALM)) tempbx += 2;
         if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-        /* TW: Nothing special needed for SOverscan    */
+        /* Nothing special needed for SOverscan    */
         /*     PALM uses NTSC data, PALN uses PAL data */
      }
   }
@@ -2773,7 +2851,7 @@
         if(modeflag & HalfDCLK) tempbx++;
      }
   }
-  /* TW: 630/LVDS and 650/LVDS (1.10.07) BIOS */
+  /* 630/LVDS and 650/LVDS (1.10.07) BIOS */
   if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
         tempal = 0x07;
@@ -2833,14 +2911,13 @@
      }
   }
   
-  /* TW: BIOS does not do this (neither 301 nor LVDS) */
+  /* BIOS does not do this (neither 301 nor LVDS) */
   /*     (But it's harmless; see SetCRT2Offset) */
   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
 
-  /* TW: Removed 301B302B301LV302LV check here to match 650/LVDS BIOS */
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
 
-	/* TW:   1. for LVDS/302B/302LV **LCDA** */
+	/*   1. for LVDS/302B/302LV **LCDA** */
 
       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
@@ -2855,23 +2932,23 @@
 
 #ifdef SIS300    /* ---- 300 series ---- */
 
-      /* For 301BDH: */
+      /* For 301BDH: (with LCD via LVDS) */
       if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-	  temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
-	  temp &= 0xef;
-	  temp |= 0x02;
-	  if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
-	     temp |= 0x10;
-	     temp &= 0xfd;
-	  }
-	  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+	 temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
+	 temp &= 0xef;
+	 temp |= 0x02;
+	 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+	    temp |= 0x10;
+	    temp &= 0xfd;
+	 }
+	 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
       }
 
       if(ModeNo > 0x13) {
-        tempcl -= ModeVGA;
-        if((tempcl > 0) || (tempcl == 0)) {      /* TW: tempcl is USHORT -> always true! */
-           tempah = ((0x10 >> tempcl) | 0x80);
-        }
+         tempcl -= ModeVGA;
+         if((tempcl > 0) || (tempcl == 0)) {      /* tempcl is USHORT -> always true! */
+            tempah = ((0x10 >> tempcl) | 0x80);
+         }
       } else tempah = 0x80;
 
       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
@@ -2880,7 +2957,7 @@
 
     } else {
 
-#ifdef SIS315H    /* ---- 310/325/330 series ---- */
+#ifdef SIS315H    /* ------- 315/330 series ------ */
 
       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
          if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) {
@@ -2889,12 +2966,12 @@
       }
 
       if(ModeNo > 0x13) {
-        tempcl -= ModeVGA;
-        if((tempcl > 0) || (tempcl == 0)) {  /* TW: tempcl is USHORT -> always true! */
-           tempah = (0x08 >> tempcl);
-           if (tempah == 0) tempah = 1;
-           tempah |= 0x40;
-        }
+         tempcl -= ModeVGA;
+         if((tempcl > 0) || (tempcl == 0)) {  /* tempcl is USHORT -> always true! */
+            tempah = (0x08 >> tempcl);
+            if (tempah == 0) tempah = 1;
+            tempah |= 0x40;
+         }
       } else tempah = 0x40;
 
       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0x50;
@@ -2921,7 +2998,7 @@
 
     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-	/* TW:   2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
+	/*   2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
 
     	tempah = 0x01;
     	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
@@ -2938,7 +3015,7 @@
 
     	if(HwDeviceExtension->jChipType < SIS_315H) {
 
-		/* --- 300 series --- */
+		/* ---- 300 series ---- */
 
       		tempah = (tempah << 5) & 0xFF;
       		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
@@ -2946,7 +3023,7 @@
 
     	} else {
 
-		/* --- 310 series --- */
+		/* ---- 315 series ---- */
 
       		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
 
@@ -2956,9 +3033,9 @@
       		tempah |= 0x10;
 	}
 
-	/* TW: 630/301 BIOS */
 	if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
-		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+		if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+		   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
 			tempah |= 0x80;
 		}
 	} else {
@@ -2996,28 +3073,31 @@
       	      }
 	   }
     	}
-	/* TW: For 302LV dual-channel */
+
+	/* For 302LV dual-channel */
 	if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
-		    tempah |= 0x40;
-	    }
+	   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
+	         tempah |= 0x40;
+	   }
 	}
 
 	if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
-		tempah |= 0x80;
+	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  ||
+	   ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) &&
+	    (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
+	   tempah |= 0x80;
 	}
 
     	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0C,tempah);
 
     } else {
 
-    	/* TW: 3. for LVDS */
+    	/* 3. for LVDS */
 
 	if(HwDeviceExtension->jChipType >= SIS_315H) {
 
-	   /* TW: Inserted this entire section (BIOS 650/LVDS); added ModeType check
+	   /* Inserted this entire section (BIOS 650/LVDS); added ModeType check
 	    *     (LVDS can only be slave in 8bpp modes)
 	    */
 	   tempah = 0x80;
@@ -3043,7 +3123,7 @@
 
 	} else {
 
-	   /* TW: (added ModeType check) */
+	   /* (added ModeType check) */
 	   tempah = 0;
 	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
                	  tempah |= 0x02;
@@ -3060,50 +3140,69 @@
 
   }
 
-  /* TW: Inserted the entire following section */
+  /* Inserted the entire following section */
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
       if(HwDeviceExtension->jChipType >= SIS_315H) {
 
 #ifdef SIS315H
+
+         unsigned char bridgerev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);;
+
+	 /* The following is nearly unpreditable and varies from machine
+	  * to machine. Especially the 301DH seems to be a real trouble
+	  * maker. Some BIOSes simply set the registers (like in the
+	  * NoLCD-if-statements here), some set them according to the
+	  * LCDA stuff. It is very likely that some machines are not
+	  * treated correctly in the following, very case-orientated
+	  * code. What do I do then...?
+	  */
+
+	 /* 740 variants match for 30xB, 301B-DH, 30xLV */
+
          if(!(IS_SIS740)) {
             tempah = 0x04;						   /* For all bridges */
             tempbl = 0xfb;
             if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
                tempah = 0x00;
-	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
+	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
 	          tempbl = 0xff;
+	       }
             }
             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);   
 	 }
-	 
-	 if(IS_SIS740) {						
+
+	 /* The following two are responsible for eventually wrong colors
+	  * in TV output. The DH (VB_NoLCD) conditions are unknown; the
+	  * b0 was found in some 651 machine (Pim); the b1 version in a
+	  * 650 box (Jake). What is the criteria?
+	  */
+
+	 if(IS_SIS740) {
 	    tempah = 0x30;
 	    tempbl = 0xcf;
 	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
 	       tempah = 0x00;
 	    }
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);    
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
+	 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
+	    /* Fixes "TV-blue-bug" on 315+301 */
+	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF);          /* For 301   */
+	 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xLV */
+	 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xB-DH rev b0 (or "DH on 651"?) */
 	 } else {
-	    /* TW: This in order to fix "TV-blue-bug" on 315+301 */
-            if(SiS_Pr->SiS_VBType & VB_SIS301) {
-	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF);             /* For 301   */
-	    } else {
-	       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xLV */
-	       } else {
-	          tempah = 0x30;					   /* For 301B  */
-	          tempbl = 0xcf;
-	          if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-	             tempah = 0x00;
-		     if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
-		        tempbl = 0xff;
-		     }
-	          }
-	          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);    
+	    tempah = 0x30;					     /* For 30xB (and 301BDH rev b1) */
+	    tempbl = 0xcf;
+	    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+	       tempah = 0x00;
+	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+		  tempbl = 0xff;
 	       }
 	    }
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
 	 }
 
 	 if(IS_SIS740) {
@@ -3111,25 +3210,25 @@
   	    tempbl = 0x3f;
 	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
 	       tempah = 0x00;
-	    } 
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);     
+	    }
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
+	 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);	/* For 30xLV */
+	 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);	/* For 30xB-DH rev b0 (or "DH on 651"? */
 	 } else {
-	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {			/* For 30xLV */
-	       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);
-	    } else {							/* For 301, 301B */ 
-	        tempah = 0xc0;
-	        tempbl = 0x3f;
-	        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-	           tempah = 0x00;
-		   if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
-		      tempbl = 0xff;
-		   }
-	        }
-	        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);     
+	    tempah = 0xc0;						/* For 301, 301B (and 301BDH rev b1) */
+	    tempbl = 0x3f;
+	    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+	       tempah = 0x00;
+	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+		  tempbl = 0xff;
+	       }
 	    }
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
 	 }
 
-	 if(IS_SIS740) {						
+	 if(IS_SIS740) {
 	    tempah = 0x80;
 	    tempbl = 0x7f;
 	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
@@ -3141,8 +3240,9 @@
             tempbl = 0x7f;
             if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
                tempbl = 0xff;
-	       if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)))
+	       if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) {
 	          tempah |= 0x80;
+	       }
             }
             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
 	 }
@@ -3174,16 +3274,32 @@
 	    tempbl = 0xfb;
             if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
                tempah = 0x00;
-	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
+	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
 	          tempbl = 0xff;
+	       }
             }
 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
 
-	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)
+	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x00);
+	    }
 
 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
 
+	 } else if(HwDeviceExtension->jChipType == SIS_550) {
+
+#if 0
+	    tempah = 0x00;
+	    tempbl = 0xfb;
+	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	       tempah = 0x00;
+	       tempbl = 0xfb;
+	    }
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
+#endif
+	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
 	 }
 
       }
@@ -3209,10 +3325,9 @@
 	                      HwDeviceExtension);
         } else {
 
-	   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
-	       (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
-	       
-	      /* TW: Need LVDS Data for LCD on 301BDH */
+	   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+
+	      /* Need LVDS Data for LCD on 301B-DH */
 	      SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
 	                          HwDeviceExtension);
 				  
@@ -3282,18 +3397,16 @@
 
    } else {
 
-      /* TW: 301BDH needs LVDS Data */
-      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
-          (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+      /* 301BDH needs LVDS Data */
+      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
 	      SiS_Pr->SiS_IF_DEF_LVDS = 1;
       }
 
       SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                      &CRT2Index,&ResIndex,HwDeviceExtension);
 
-      /* TW: 301BDH needs LVDS Data */
-      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
-          (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+      /* 301BDH needs LVDS Data */
+      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
               SiS_Pr->SiS_IF_DEF_LVDS = 0;
       }
 
@@ -3321,11 +3434,16 @@
 	case 20:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2;   break;
 	case 21:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1;  break;
 	case 22:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2;  break;
+	case 30:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_2;    break;
+	case 80:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
+	case 81:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
+	case 82:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
+	case 83:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2;  break;
 	case 90:  LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
       	case 91:  LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
       	case 92:  LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
       	case 93:  LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
-	case 99:  LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;  /* TW: Super Overscan */
+	case 99:  LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;  /* Super Overscan */
 	default:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
      }
    }
@@ -3337,67 +3455,36 @@
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-    if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)){
-         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
-           SiS_Pr->SiS_HDE = 1024;
-           SiS_Pr->SiS_VDE =  768;
-         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024){
-           SiS_Pr->SiS_HDE = 1280;
-           SiS_Pr->SiS_VDE = 1024;
-	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050){
-           SiS_Pr->SiS_HDE = 1400;
-           SiS_Pr->SiS_VDE = 1050;
-	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200){
-           SiS_Pr->SiS_HDE = 1600;
-           SiS_Pr->SiS_VDE = 1200;
-         } else {
-	   SiS_Pr->SiS_HDE = 1280;
-	   SiS_Pr->SiS_VDE =  960;
-	 }
-    }
+     if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+        SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+        SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+     }
 
   } else {
 
-    if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
-      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-          if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-              SiS_Pr->SiS_HDE =  800;
-              SiS_Pr->SiS_VDE =  600;
-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-	      SiS_Pr->SiS_HDE = 1024;
-              SiS_Pr->SiS_VDE =  600;  
-            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-              SiS_Pr->SiS_HDE = 1024;
-              SiS_Pr->SiS_VDE =  768;
- 	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
-	      SiS_Pr->SiS_HDE = 1152;
-	      SiS_Pr->SiS_VDE =  768;	
-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x864) {
-	      SiS_Pr->SiS_HDE = 1152;
-	      SiS_Pr->SiS_VDE =  864;  
-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-	      SiS_Pr->SiS_HDE = 1280;
-	      SiS_Pr->SiS_VDE =  768;        
-            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-              SiS_Pr->SiS_HDE = 1280;
-              SiS_Pr->SiS_VDE = 1024;
-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-	      SiS_Pr->SiS_HDE = 1400;
-              SiS_Pr->SiS_VDE = 1050;
-	    } else {
-	      SiS_Pr->SiS_HDE = 1600;
-	      SiS_Pr->SiS_VDE = 1200;
-	    }
-            if(SiS_Pr->SiS_IF_DEF_FSTN) {
-              SiS_Pr->SiS_HDE = 320;
-              SiS_Pr->SiS_VDE = 480;
-            }
-          }
+     if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+        if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+              if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+	         SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+                 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+
+		 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+		    if(ResIndex < 0x08) {
+		       SiS_Pr->SiS_HDE = 1280;
+                       SiS_Pr->SiS_VDE = 1024;
+		    }
+		 }
+#if 0
+                 if(SiS_Pr->SiS_IF_DEF_FSTN) {
+                    SiS_Pr->SiS_HDE = 320;
+                    SiS_Pr->SiS_VDE = 480;
+                 }
+#endif		 
+              }
+           }
         }
-      }
-    }
+     }
   }
 }
 
@@ -3413,11 +3500,16 @@
   const SiS_TVDataStruct  *TVPtr  = NULL;
 
   if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+	resinfo = 0;
+     } else {
     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     }
   }
   
   SiS_Pr->SiS_NewFlickerMode = 0;
@@ -3429,17 +3521,26 @@
 
   SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
 
-  /* TW: For VGA2 ("RAMDAC2") */
-
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
-     SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                        HwDeviceExtension);
-     return;
-  }
 
-  /* TW: For TV */
+     if(SiS_Pr->UseCustomMode) {
+
+        SiS_Pr->SiS_RVBHCMAX  = 1;
+        SiS_Pr->SiS_RVBHCFACT = 1;
+        SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
+        SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
+        SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
+        SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
+	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
+        SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     } else {
+
+        SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                           HwDeviceExtension);
+     }
+
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
 
     SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                    &CRT2Index,&ResIndex,HwDeviceExtension);
@@ -3452,7 +3553,7 @@
       case  4:  TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
       case  8:  TVPtr = SiS_Pr->SiS_StPALData;     break;
       case  9:  TVPtr = SiS_Pr->SiS_StNTSCData;    break;
-      default:  TVPtr = SiS_Pr->SiS_StPALData;     break;  /* TW: Just to avoid a crash */
+      default:  TVPtr = SiS_Pr->SiS_StPALData;     break;  /* Just to avoid a crash */
     }
 
     SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
@@ -3464,18 +3565,16 @@
     SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
     SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
     if(modeflag & HalfDCLK) {
-	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->HALFRVBHRS;
+	SiS_Pr->SiS_RVBHRS     = (TVPtr+ResIndex)->HALFRVBHRS;
     }
 
     if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {  
     
        if(SiS_Pr->SiS_HiVision != 3) {
-       
-      	  if(resinfo == 0x08) SiS_Pr->SiS_NewFlickerMode = 0x40;
-      	  if(resinfo == 0x09) SiS_Pr->SiS_NewFlickerMode = 0x40;
-	  if(resinfo == 0x12) SiS_Pr->SiS_NewFlickerMode = 0x40;
-	  
-       } 
+      	  if(resinfo == SIS_RI_1024x768)  SiS_Pr->SiS_NewFlickerMode = 0x40;
+      	  if(resinfo == SIS_RI_1280x1024) SiS_Pr->SiS_NewFlickerMode = 0x40;
+	  if(resinfo == SIS_RI_1280x720)  SiS_Pr->SiS_NewFlickerMode = 0x40;
+       }
        
        switch(SiS_Pr->SiS_HiVision) {
        case 2:
@@ -3504,127 +3603,126 @@
 
     } else {
 
-      SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
-      SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
-      SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
-      SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
-
-      if(modeflag & HalfDCLK) {
-         SiS_Pr->SiS_RY1COE = 0x00;
-         SiS_Pr->SiS_RY2COE = 0xf4;
-         SiS_Pr->SiS_RY3COE = 0x10;
-         SiS_Pr->SiS_RY4COE = 0x38;
-      }
-
-      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-        SiS_Pr->SiS_HT = NTSCHT;
-	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {  
-	   if((ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
-	}  
-        SiS_Pr->SiS_VT = NTSCVT;
-      } else {
-        SiS_Pr->SiS_HT = PALHT;
-        SiS_Pr->SiS_VT = PALVT;
-      }
+       SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
+       SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
+       SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
+       SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
+
+       if(modeflag & HalfDCLK) {
+          SiS_Pr->SiS_RY1COE = 0x00;
+          SiS_Pr->SiS_RY2COE = 0xf4;
+          SiS_Pr->SiS_RY3COE = 0x10;
+          SiS_Pr->SiS_RY4COE = 0x38;
+       }
+
+       if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+          SiS_Pr->SiS_HT = NTSCHT;
+	  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	     if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
+	  }
+          SiS_Pr->SiS_VT = NTSCVT;
+       } else {
+          SiS_Pr->SiS_HT = PALHT;
+          SiS_Pr->SiS_VT = PALVT;
+       }
 
     }
 
-    return;
-  }
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+
+     if(SiS_Pr->UseCustomMode) {
 
-  /* TW: For LCD */
+        SiS_Pr->SiS_RVBHCMAX  = 1;
+        SiS_Pr->SiS_RVBHCFACT = 1;
+        SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
+        SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
+        SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
+        SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
+	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
+        SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+     } else {
 
-    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                   &CRT2Index,&ResIndex,HwDeviceExtension);
+        SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                      &CRT2Index,&ResIndex,HwDeviceExtension);
+
+        switch(CRT2Index) {
+         case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
+         case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
+         case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
+         case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
+         case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
+         case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
+         case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
+         case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
+         case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
+         case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
+         case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding (let panel scale) */
+         case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;        break; /* Non-VESA Timing (let panel scale) */
+         case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
+         case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
+         case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;        break; /* Non-VESA Timing */
+         case 26: LCDPtr = SiS_Pr->SiS_ExtLCD1280x768Data;        break; /* VESA Timing */
+         case 27: LCDPtr = SiS_Pr->SiS_NoScaleData1280x768;       break; /* Non-expanding */
+         case 28: LCDPtr = SiS_Pr->SiS_StLCD1280x768Data;         break; /* Non-VESA Timing */
+         case 29: LCDPtr = SiS_Pr->SiS_NoScaleData;	          break; /* Generic no-scale data */
+         default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;	  break; /* Just to avoid a crash */
+        }
+
+        SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
+        SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
+        SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
+        SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
+        SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
+        SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
 
-    switch(CRT2Index) {
-      case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
-      case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
-      case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
-      case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
-      case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
-      case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
-      case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
-      case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
-      case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
-      case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
-      case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding (let panel scale) */
-      case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;	       break; /* Non-VESA Timing (let panel scale) */
-      case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
-      case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
-      case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;	       break; /* Non-VESA Timing */
-      case 26: LCDPtr = SiS_Pr->SiS_ExtLCD1280x768Data;        break; /* VESA Timing */
-      case 27: LCDPtr = SiS_Pr->SiS_NoScaleData1280x768;       break; /* Non-expanding */
-      case 28: LCDPtr = SiS_Pr->SiS_StLCD1280x768Data;	       break; /* Non-VESA Timing */
-      case 29: LCDPtr = SiS_Pr->SiS_NoScaleData;	       break; /* Generic no-scale data */
-      default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;	       break; /* Just to avoid a crash */
-    }
-
-    SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
-    SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
-    SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
-    SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
-    SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
-    SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
-    
 #ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO,
-    	"GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
-#endif    
+        xf86DrvMsg(0, X_INFO,
+    	    "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+#endif
 
-    tempax = 1024;
-    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-      if(HwDeviceExtension->jChipType < SIS_315H) {
-         if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
-         else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
-         else                               tempbx = 768;
-      } else {      
-         tempbx = 768; 
-      }
-    } else {
-      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
-      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
-      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
-      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
-      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
-      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
-      else                               tempbx = 768;
-    }
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-      tempax = 1280;
-      if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
-      else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
-      else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
-      else                               tempbx = 1024;
-    }
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-      tempax = 1280;
-      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
-      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
-      else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
-      else                                tempbx = 960;
-    }
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-      tempax = 1400;
-      tempbx = 1050;
-    }
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-      tempax = 1600;
-      tempbx = 1200;
-    }
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {  /* guessed */
-      tempax = 1280;
-      tempbx = 768;
-    }
-    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-       tempax = SiS_Pr->SiS_VGAHDE;
-       tempbx = SiS_Pr->SiS_VGAVDE;
-    }
-    SiS_Pr->SiS_HDE = tempax;
-    SiS_Pr->SiS_VDE = tempbx;
-    return;
+	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+           tempax = 1024;
+           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+              if(HwDeviceExtension->jChipType < SIS_315H) {
+                 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+                 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+                 else                               tempbx = 768;
+              } else {
+                 tempbx = 768;
+              }
+           } else {
+              if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
+              else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
+              else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
+              else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
+              else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+              else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+              else                               tempbx = 768;
+           }
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+           tempax = 1280;
+           if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
+           else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
+           else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
+           else                               tempbx = 1024;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+           tempax = 1280;
+           if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
+           else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
+           else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
+           else                                tempbx = 960;
+        } else {
+	   tempax = SiS_Pr->PanelXRes;
+           tempbx = SiS_Pr->PanelYRes;
+	}
+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+           tempax = SiS_Pr->SiS_VGAHDE;
+           tempbx = SiS_Pr->SiS_VGAVDE;
+        }
+        SiS_Pr->SiS_HDE = tempax;
+        SiS_Pr->SiS_VDE = tempbx;
+     }
   }
 }
 
@@ -3634,9 +3732,9 @@
   USHORT resindex;
 
   if(ModeNo <= 0x13)
-    	resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+     resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   else
-    	resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
 
   return(resindex);
 }
@@ -3647,41 +3745,46 @@
 {
   USHORT xres,yres,modeflag=0,resindex;
 
+  if(SiS_Pr->UseCustomMode) {
+     SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = SiS_Pr->CHDisplay;
+     SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
+     return;
+  }
+
   resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
 
   if(ModeNo <= 0x13) {
-    	xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
-    	yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
+     xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
+     yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
   } else {
-	xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
-    	yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+     yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
-      if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-          if(yres == 350) yres = 400;
-      }
-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
- 	  if(ModeNo == 0x12) yres = 400;
-      }
-  }
+  if((!SiS_Pr->SiS_IF_DEF_DSTN) && (!SiS_Pr->SiS_IF_DEF_FSTN)) {
+
+     if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
+        if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+           if(yres == 350) yres = 400;
+        }
+        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
+ 	   if(ModeNo == 0x12) yres = 400;
+        }
+     }
+
+     if(ModeNo > 0x13) {
+  	if(modeflag & HalfDCLK)       xres *= 2;
+  	if(modeflag & DoubleScanMode) yres *= 2;
+     }
 
-  if(ModeNo > 0x13) {
-      if(SiS_Pr->SiS_IF_DEF_FSTN == 1){
-            xres *= 2;
-            yres *= 2;
-      } else {
-  	    if(modeflag & HalfDCLK)       xres *= 2;
-  	    if(modeflag & DoubleScanMode) yres *= 2;
-      }
   }
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
            if(xres == 720) xres = 640;
 	} else {
-	   if(SiS_Pr->SiS_VBType & VB_NoLCD) {           /* TW: 301BDH */
+	   if(SiS_Pr->SiS_VBType & VB_NoLCD) {           /* 301BDH */
 	        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
                    if(xres == 720) xres = 640;
 		}
@@ -3702,17 +3805,18 @@
 	         if(xres == 720) xres = 640;
 	      }
 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-    	         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-		    if(ModeNo <= 0x13) {
-		       /* TW: This is wrong for 640x400 *graphics* mode */
+		 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+		    if((ModeNo <= 0x13) || (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+		       /* Panel on 301B via DVI shows 5 extra (garbage-)lines if this is done,
+		        * panel on 30xLV blinks if it's not done...
+			*/
       		       if(yres == 400) yres = 405;
 		    }
       		    if(yres == 350) yres = 360;
       		    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
         	       if(yres == 360) yres = 375;
       		    }
-   	         }
-    	         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
+   	         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
       		    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
         	       if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
           	          if(yres == 350) yres = 357;
@@ -3727,12 +3831,15 @@
   } else {
     	if(xres == 720) xres = 640;
 	if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-	      yres = 400;
-	      if(HwDeviceExtension->jChipType >= SIS_315H) {
-	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
-	      } else {
-	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
-	      }
+	   yres = 400;
+	   if(HwDeviceExtension->jChipType >= SIS_315H) {
+	      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
+	   } else {
+	      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
+	   }
+	   if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
+	      yres = 480;
+	   }
 	}
   }
   SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
@@ -3782,12 +3889,10 @@
 			} else {
 			   tempbx = 29;
 			   if(ModeNo >= 0x13) {
-			      if(HwDeviceExtension->jChipType >= SIS_315H) {
-			         /* 1280x768 and 1280x960 have same CRT2CRTC,
-				  * so we change it here if 1280x960 is chosen
-				  */
-			         if(resinfo == 0x0f) tempal = 10;
-			      }
+			      /* 1280x768 and 1280x960 have same CRT2CRTC,
+			       * so we change it here if 1280x960 is chosen
+			       */
+			      if(resinfo == SIS_RI_1280x960) tempal = 10;
 			   }
 			}
 		} else {
@@ -3795,7 +3900,7 @@
       		   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
         		tempbx += 5;
                         /* GetRevisionID();  */
-			/* TW: BIOS only adds 5 once */
+			/* BIOS only adds 5 once */
         		tempbx += 5;
        		   }
 	        }
@@ -3819,24 +3924,16 @@
 
         tempal &= 0x3F;
 
-      	if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
-           (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))) {
-      		if(tempal == 0x06) tempal = 0x07;
-        }
-
-	if((HwDeviceExtension->jChipType == SIS_300) &&
-	   (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
-	    if(ModeNo > 0x13) {
-	        if((resinfo == 0x0c) || (resinfo == 0x0d))  /* 720 (index diff. on 310/325!) */
-		    tempal = 6;
-	    }
-	}
-
-	if(HwDeviceExtension->jChipType != SIS_300) {
-           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-              if((ModeNo == 0x31) || (ModeNo == 0x32)) tempal = 6;
+      	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
+	   if(ModeNo > 0x13) {
+      	      if(tempal == 6) tempal = 7;
+              if((resinfo == SIS_RI_720x480) ||
+	         (resinfo == SIS_RI_720x576) ||
+	         (resinfo == SIS_RI_768x576)) {
+		 tempal = 6;
+	      }
 	   }
-	}
+        }
 
      	*CRT2Index = tempbx;
      	*ResIndex = tempal;
@@ -3846,25 +3943,22 @@
     	Flag = 1;
     	tempbx = 0;
     	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-	
-      		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-        		Flag = 0;
-        		tempbx = 10;
-			if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-        		if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-				tempbx += 2;
-				if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
-				if(SiS_Pr->SiS_CHPALM) {
-					tempbx = 90;
-					if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-				} else if(SiS_Pr->SiS_CHPALN) {
-					tempbx = 92;
-					if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-				}
-				
-			}
-      		}
-		
+      	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+              Flag = 0;
+              tempbx = 10;
+	      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+              if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+		 tempbx += 2;
+		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+		 if(SiS_Pr->SiS_CHPALM) {
+		    tempbx = 90;
+		    if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+		 } else if(SiS_Pr->SiS_CHPALN) {
+		    tempbx = 92;
+		    if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+	 	 }
+              }
+           }
     	}
 
     	if(Flag) {
@@ -3872,11 +3966,19 @@
 		if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
 		   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
    	      	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 3;
+		   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+		      tempbx = 82;
+		      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+		   }
 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
 		   tempbx = 18;
 		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++; 
-	        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { 
+	        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
 		   tempbx = 6;
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
+		   tempbx = 30;
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
+		   tempbx = 30;
 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
 		   tempbx = 15;
   		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
@@ -3889,20 +3991,25 @@
 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
 		   tempbx = 21;
 		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
+		   tempbx = 80;
+   	      	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
 		}
-		
+
 		if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
 		   tempbx = 7;
         	}
 		
 	}
 
+#if 0
 	if(SiS_Pr->SiS_IF_DEF_FSTN){
        	 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
          		tempbx = 14;
          		tempal = 6;
         	}
     	}
+#endif	
 
 	if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
 	        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
@@ -3914,13 +4021,10 @@
 
 	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 	    if(ModeNo > 0x13) {
-	        if(HwDeviceExtension->jChipType < SIS_315H) {
-	           if((resinfo == 0x0c) || (resinfo == 0x0d))  /* 720 */
-		       tempal = 6;
-	        } else {
-		   if((resinfo == 0x0d) || (resinfo == 0x0e))  /* 720 */
-		       tempal = 6;
-		}
+	       if((resinfo == SIS_RI_720x480) ||
+	          (resinfo == SIS_RI_720x576) ||
+		  (resinfo == SIS_RI_768x576))
+		  tempal = 6;
 	    }
 	}
 
@@ -3988,8 +4092,9 @@
   USHORT RefreshRateTableIndex,i,backup_i;
   USHORT modeflag,index,temp,backupindex;
 
-  if(SiS_Pr->UseCustomMode) return 0;
-  
+  /* Do NOT check for UseCustomMode here, will skrew up FIFO */
+  if(ModeNo == 0xfe) return 0;
+
   if(ModeNo <= 0x13)
     	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   else
@@ -4003,7 +4108,7 @@
 
   if(ModeNo < 0x14) return(0xFFFF);
 
- /* TW: CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
+ /* CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
   *     On LVDS machines, CRT2 index is always 0 and will be
   *     set to 0 by the following code; this causes the function
   *     to take the first non-interlaced mode in SiS_Ext2Struct
@@ -4017,40 +4122,38 @@
   if(index > 0) index--;
 
   if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))  index = 0;
-      } else {
+     } else {
         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-	    if(SiS_Pr->SiS_VBType & VB_NoLCD)
-	       	    index = 0;
-	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)
-	    	    index = backupindex = 0;
+	   if(SiS_Pr->SiS_VBType & VB_NoLCD)
+	      index = 0;
+	   else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)
+	      index = backupindex = 0;
 	}
-      }
-  }
+     }
 
-  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
-    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-      		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        		index = 0;
-      		}
-    	}
-    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-      		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-			if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
-           		   temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
-        		   if(index > temp) index = temp;
-			}
-      		} else {
-        		index = 0;
-      		}
-    	}
+     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+           index = 0;
+        }
+     }
+     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+	   if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
+              temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
+              if(index > temp) index = temp;
+	   }
+      	} else {
+           index = 0;
+      	}
+     }
   }
 
   RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
   ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
 
-  /* TW: 650/LVDS 1.10.07, 650/30xLV 1.10.6s */
+  /* 650/LVDS 1.10.07, 650/30xLV 1.10.6s */
   if(HwDeviceExtension->jChipType >= SIS_315H) {
      if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
         if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
@@ -4085,7 +4188,7 @@
     	backup_i = i;
     	if (!(SiS_AdjustCRT2Rate(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
 	                             RefreshRateTableIndex,&i,HwDeviceExtension))) {
-		/* TW: This is for avoiding random data to be used; i is
+		/* This is for avoiding random data to be used; i is
 		 *     in an undefined state if no matching CRT2 mode is
 		 *     found.
 		 */
@@ -4104,42 +4207,45 @@
   USHORT tempax,tempbx,resinfo;
   USHORT modeflag,infoflag;
 
-  if (ModeNo <= 0x13)
+  if(ModeNo <= 0x13) {
     	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  else
+	resinfo = 0;
+  } else {
     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+        resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
 
-  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
 
   tempax = 0;
+
   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
     	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
       		tempax |= SupportRAMDAC2;
 		if(HwDeviceExtension->jChipType >= SIS_315H) {
-		    tempax |= SupportTV;
-		    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-		        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-			    if(resinfo == 0x0a) tempax |= SupportTV1024;
-			}
-		    }
+		   tempax |= SupportTV;
+		   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+		      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+			 if(resinfo == SIS_RI_1600x1200) tempax |= SupportTV1024;
+		      }
+		   }
 		}
-    	}
-    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+    	} else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
       		tempax |= SupportLCD;
 		if(HwDeviceExtension->jChipType >= SIS_315H) {
                    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
 		      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
-		         if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+		         if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
 			    (*i) = 0;
                             return(1);
 		         } else {
       		            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
         		       if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
-           			  if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+           			  if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
 				     return(0);
 				  } else {
-             			     if((resinfo >= 9) && (resinfo != 0x14)) {
+             			     if((resinfo >= SIS_RI_1280x1024) && (resinfo != SIS_RI_1280x768)) {
                				return(0);
              			     }
            			  }
@@ -4150,150 +4256,150 @@
       		   }
 		} else {
 		  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-		     if((resinfo != 0x0f) && ((resinfo == 4) || (resinfo >= 8))) return(0);
+		     if( (resinfo != SIS_RI_1024x600) &&
+		         ((resinfo == SIS_RI_512x384) || (resinfo >= SIS_RI_1024x768))) return(0);
 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
-		     if((resinfo != 0x10) && (resinfo > 8)) return(0);
+		     if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768)) return(0);
 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-		     if((resinfo != 0x0e) && (resinfo > 8)) return(0);
+		     if((resinfo != SIS_RI_1280x960) && (resinfo > SIS_RI_1024x768)) return(0);
 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-		     if(resinfo > 9) return(0);
+		     if(resinfo > SIS_RI_1280x1024) return(0);
 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-		     if(resinfo > 8) return(0);
+		     if(resinfo > SIS_RI_1024x768) return(0);
 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-		     if((resinfo == 4) || (resinfo > 7)) return(0);
+		     if((resinfo == SIS_RI_512x384) || (resinfo > SIS_RI_800x600)) return(0);
 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-		     if((resinfo == 4) || (resinfo == 3) || (resinfo > 6)) return(0);
+		     if((resinfo == SIS_RI_512x384) ||
+		        (resinfo == SIS_RI_400x300) ||
+			(resinfo > SIS_RI_640x480)) return(0);
 		  }
 		}
-    	}
-    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { 
+    	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
 	        if(SiS_Pr->SiS_HiVision == 3) {
 		      	tempax |= SupportHiVisionTV2;
       			if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
-        			if(resinfo == 4) return(0);
-        			if(resinfo == 3) return(0);
-				if(resinfo == 7) {
+        			if(resinfo == SIS_RI_512x384) return(0);
+        			if(resinfo == SIS_RI_400x300) return(0);
+				if(resinfo == SIS_RI_800x600) {
 	          			if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
         			}
-        			if(resinfo > 7) return(0);
+        			if(resinfo > SIS_RI_800x600) return(0);
 			}
 		} else {  
       			tempax |= SupportHiVisionTV;
       			if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
-        			if(resinfo == 4) return(0);
-        			if((resinfo == 3) || (resinfo == 7)) {
+        			if(resinfo == SIS_RI_512x384) return(0);
+        			if((resinfo == SIS_RI_400x300) || (resinfo == SIS_RI_800x600)) {
 	          			if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
         			}
-        			if(resinfo > 7) return(0);
+        			if(resinfo > SIS_RI_800x600) return(0);
 			}
 		}
-    	} else {
-      	   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
+    	} else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
         	tempax |= SupportTV;
 		tempax |= SupportTV1024;
 		if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-		        if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
-			     if(resinfo != 8) {
-			         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-				     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4)) ) {
-				     tempax &= ~(SupportTV1024);
-				     if(HwDeviceExtension->jChipType >= SIS_315H) {
-                                         if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-				             if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-			                         ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
-			                         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
-		                             }
-				         }
-		                     } else {
-				         if( (resinfo != 3) ||
-					     (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-					     (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-					     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-						 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-						     if(resinfo == 3) return(0);
-						     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-						 }
-		                             }
-                                         } else return(0);
-				     }
-				 }
-			     }
-			} else {
-			    tempax &= ~(SupportTV1024);
-			    if(HwDeviceExtension->jChipType >= SIS_315H) {
-			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-			            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-			                ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+		   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+		      if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
+		         if(resinfo != SIS_RI_1024x768) {
+			    if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384)) ) {
+			       tempax &= ~(SupportTV1024);
+			       if(HwDeviceExtension->jChipType >= SIS_315H) {
+                                  if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+			             if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+			                 ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
 			                if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
-		                    }
-		                }
-			    } else {
-			        if( (resinfo != 3) ||
-				    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-				    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-				     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-					 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-					     if(resinfo == 3) return(0);
-					     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-					 }
 		                     }
-                                } else return(0);
-                            }
-			}
-		    } else {  /* slavemode */
-			if(resinfo != 8) {
-			    if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4) ) ) {
-				 tempax &= ~(SupportTV1024);
-				 if(HwDeviceExtension->jChipType >= SIS_315H) {
-				     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-				         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-			                     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
-			                     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode))  return(0);
-		                         }
+				  }
+		               } else {
+				  if( (resinfo != SIS_RI_400x300) ||
+				      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+				      (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+				     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+					if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+					   if(resinfo == SIS_RI_400x300) return(0);
+					   if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+					}
 		                     }
-			        } else {
-				    if( (resinfo != 3) ||
-				        (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-				        (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-				         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-					     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-					         if(resinfo == 3) return(0);
-					         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-					     }
-		                         }
-                                    } else return(0);
-				}
+                                  } else return(0);
+			       }
 			    }
-			}
-		    }
-		} else {   /* 301 */
-		    tempax &= ~(SupportTV1024);
-		    if(HwDeviceExtension->jChipType >= SIS_315H) {
-		        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-		            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
-			        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
-		            }
-		        }
-		    } else {
-		        if( (resinfo != 3) ||
-			    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-			    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-			    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-				    if(resinfo == 3) return(0);
-				    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-				}
+			 }
+		      } else {
+			 tempax &= ~(SupportTV1024);
+			 if(HwDeviceExtension->jChipType >= SIS_315H) {
+			    if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+			       if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+			           ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
+			          if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+		               }
 		            }
-                        } else return(0);
-		    }
-		}
-           }
-    	}
-	
-  } else {	/* TW: for LVDS  */
+			 } else {
+			    if( (resinfo != SIS_RI_400x300) ||
+			        (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+				(SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+			       if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+				  if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+				     if(resinfo == SIS_RI_400x300) return(0);
+				     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+				  }
+		               }
+                            } else return(0);
+                         }
+		      }
+		   } else {  /* slavemode */
+		      if(resinfo != SIS_RI_1024x768) {
+			 if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+			     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384) ) ) {
+			    tempax &= ~(SupportTV1024);
+			    if(HwDeviceExtension->jChipType >= SIS_315H) {
+			       if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+			          if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+			              ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
+			             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode))  return(0);
+		                  }
+		               }
+			    } else {
+			       if( (resinfo != SIS_RI_400x300) ||
+			           (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+			           (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+			          if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+				     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+				        if(resinfo == SIS_RI_400x300) return(0);
+				        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+				     }
+		                  }
+                               } else return(0);
+			    }
+		  	 }
+		      }
+		   }
+	        } else {   /* 301 */
+		   tempax &= ~(SupportTV1024);
+		   if(HwDeviceExtension->jChipType >= SIS_315H) {
+		      if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+		         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+		             ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
+		            if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+		         }
+		      }
+		   } else {
+		      if( (resinfo != SIS_RI_400x300) ||
+			  (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+			  (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+		         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+			    if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+			       if(resinfo == SIS_RI_400x300) return(0);
+			       if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+			    }
+		         }
+                      } else return(0);
+		   }
+	        }
+        }
+
+  } else {	/* for LVDS  */
 
     	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
       		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
@@ -4303,24 +4409,29 @@
     	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
       		tempax |= SupportLCD;
 		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-		     if((resinfo != 0x14) && (resinfo > 0x09)) return(0);
+		     if((resinfo != SIS_RI_1280x768) && (resinfo >= SIS_RI_1280x1024)) return(0);
 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-		     if((resinfo != 0x0f) && (resinfo > 0x08)) return(0);
+		     if((resinfo != SIS_RI_1024x600) && (resinfo >= SIS_RI_1024x768))  return(0);
 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
-		     if((resinfo != 0x10) && (resinfo > 0x08)) return(0);
+		     if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768))   return(0);
 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-		     if((resinfo != 0x15) && (resinfo > 0x09)) return(0);
+		     if((resinfo != SIS_RI_1400x1050) && (resinfo > SIS_RI_1280x1024)) return(0);
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+                     if(resinfo > SIS_RI_1600x1200) return(0);
 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-                     if(resinfo > 0x09) return(0);
+                     if(resinfo > SIS_RI_1280x1024) return(0);
                 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-		     if(resinfo > 0x08) return(0);
+		     if(resinfo > SIS_RI_1024x768)  return(0);
 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600){
-		     if(resinfo > 0x07) return(0);
-		     if(resinfo == 0x04) return(0);
+		     if(resinfo > SIS_RI_800x600)   return(0);
+		     if(resinfo == SIS_RI_512x384)  return(0);
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
+                     if((resinfo != SIS_RI_1360x1024) && (resinfo > SIS_RI_1280x1024)) return(0);
 		}
     	}
   }
-  /* TW: Look backwards in table for matching CRT2 mode */
+  
+  /* Look backwards in table for matching CRT2 mode */
   for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
      	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
      	if(infoflag & tempax) {
@@ -4328,7 +4439,7 @@
      	}
      	if ((*i) == 0) break;
   }
-  /* TW: Look through the whole mode-section of the table from the beginning
+  /* Look through the whole mode-section of the table from the beginning
    *     for a matching CRT2 mode if no mode was found yet.
    */
   for((*i) = 0; ; (*i)++) {
@@ -4348,7 +4459,7 @@
 {
   USHORT temp1,temp2;
 
-  /* TW: We store CRT1 ModeNo in CR34 */
+  /* We store CRT1 ModeNo in CR34 */
   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,ModeNo);
   temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
   temp2 = ~(SetInSlaveMode >> 8);
@@ -4364,16 +4475,16 @@
   USHORT modeflag, resinfo=0;
   UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
 
-  if(SiS_Pr->UseCustomMode) {
-        modeflag = SiS_Pr->CModeFlag;
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
-    if (ModeNo <= 0x13)
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    else {
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+     } else {
    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-    }
-  }    
+     }
+  }
 
   SiS_Pr->SiS_SetFlag = 0;
 
@@ -4383,22 +4494,24 @@
   if(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension) == 0) {  
     	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
 #if 0	
-	/* SiS_HiVision is only used on 310/325/330+30xLV */
+	/* SiS_HiVision is only used on 315/330+30xLV */
 	if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV)) {
-	   if(SiS_Pr->SiS_HiVision & 0x03) {	/* TW: New from 650/30xLV 1.10.6s */
+	   if(SiS_Pr->SiS_HiVision & 0x03) {	/* New from 650/30xLV 1.10.6s */
 	      temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
 	      temp |= SetCRT2ToHiVisionTV;   					/* 0x80 */
 	   }
-	   if(SiS_Pr->SiS_HiVision & 0x04) {	/* TW: New from 650/30xLV 1.10.6s */
+	   if(SiS_Pr->SiS_HiVision & 0x04) {	/* New from 650/30xLV 1.10.6s */
 	      temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
 	      temp |= SetCRT2ToSVIDEO;  					/* 0x08 */
 	   }
 	}
-#endif	
+#endif
+#if 0
     	if(SiS_Pr->SiS_IF_DEF_FSTN) {   /* fstn must set CR30=0x21 */
        		temp = (SetCRT2ToLCD | SetSimuScanMode);
        		SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,temp);
     	}
+#endif	
     	tempbx |= temp;
     	tempax = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) << 8;
         tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch | SetNotSimuMode | SetPALTV);
@@ -4538,7 +4651,7 @@
       		tempbx |= SetSimuScanMode;
     	}
 
-	/* TW: LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
+	/* LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
 	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
 	       ((tempbx & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) ) {
@@ -4546,12 +4659,12 @@
 	   }
 	}
 	
-    	if(!(tempbx & SetSimuScanMode)){
+    	if(!(tempbx & SetSimuScanMode)) {
       	    if(tempbx & SwitchToCRT2) {
         	if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
 		     if( (HwDeviceExtension->jChipType >= SIS_315H) &&
 			 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
-			 if(resinfo != 0x0a)
+			 if(resinfo != SIS_RI_1600x1200)
                               tempbx |= SetSimuScanMode;
 		     } else {
             		      tempbx |= SetSimuScanMode;
@@ -4574,7 +4687,7 @@
           	    if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
 	                if( (HwDeviceExtension->jChipType >= SIS_315H) &&
 			    (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
-			     if(resinfo != 0x0a) {  /* TW: 650/301 BIOS */
+			     if(resinfo != SIS_RI_1600x1200) {  /* 650/301 BIOS */
 			          tempbx |= SetInSlaveMode;
             		          if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
               		 	     if(tempbx & SetCRT2ToTV) {
@@ -4582,7 +4695,7 @@
 					     SiS_Pr->SiS_SetFlag |= TVSimuMode;
               			     }
                                   }
-			     }                      /* TW: 650/301 BIOS */
+			     }                      /* 650/301 BIOS */
 		        } else {
             		    tempbx |= SetInSlaveMode;
             		    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
@@ -4640,7 +4753,7 @@
      	if(HwDeviceExtension->jChipType >= SIS_315H) {
 	        if(ROMAddr && SiS_Pr->SiS_UseROM) {
 		    OutputSelect = ROMAddr[0xf3];
-		    if(HwDeviceExtension->jChipType == SIS_330) {
+		    if(HwDeviceExtension->jChipType >= SIS_330) {
 			OutputSelect = ROMAddr[0x11b];
 		    }
                 }
@@ -4671,7 +4784,7 @@
   SiS_Pr->SiS_VBInfo = tempbx;
 
   if(HwDeviceExtension->jChipType == SIS_630) {
-       SiS_WhatIsThis(SiS_Pr, SiS_Pr->SiS_VBInfo);
+       SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
   }
 
 #ifdef TWDEBUG
@@ -4685,61 +4798,35 @@
 #endif
 #endif
 
-#if 0  /* TW: Incomplete! (But does not seem to be required) */
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-     /* TW: From A901/630+301B BIOS */
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
-     }
-     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
-	     if( [si] == 3) ModeIdIndex = 0x3f2b;
-	 }
-     }
-     SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
-     if(ModeNo == 0x13) bp+4 = 0x03;
-  } else {
-     /* From 650/30xLV BIOS: */
-     SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
-     if(ModeNo == 0x13) bp+4 = 0x03;
-     else bp+4 = ModeNo;
-  }
-#endif
-
-  /* TW: 630/301B and 650/301 (not 301LV!) BIOSes do more here, but this seems for DOS mode */
-
 }
 
+/* Setup general purpose IO for Chrontel communication */
 void
-SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo)
+SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
 {
-   unsigned long eax, temp;
-   unsigned short temp1;
+   unsigned long  acpibase;
+   unsigned short temp;
 
    if(!(SiS_Pr->SiS_ChSW)) return;
 
 #ifndef LINUX_XF86
-   SiS_SetReg4(0xcf8,0x80000874);
-   eax = SiS_GetReg3(0xcfc);
+   SiS_SetReg4(0xcf8,0x80000874);		   /* get ACPI base */
+   acpibase = SiS_GetReg3(0xcfc);
 #else
-   eax = pciReadLong(0x00000800, 0x74);
+   acpibase = pciReadLong(0x00000800, 0x74);
 #endif
-   eax &= 0xFFFF;
-   temp = eax;
-   eax += 0x3c;
-   temp1 = SiS_GetReg4((USHORT)eax);
-   temp1 &= 0xFEFF;
-   SiS_SetReg5((USHORT)eax, temp1);
-   temp1 = SiS_GetReg4((USHORT)eax);
-   eax = temp;
-   eax += 0x3a;
-   temp1 = SiS_GetReg4((USHORT)eax);
-   temp1 &= 0xFEFF;
+   acpibase &= 0xFFFF;
+   temp = SiS_GetReg4((USHORT)(acpibase + 0x3c));  /* ACPI register 0x3c: GP Event 1 I/O mode select */
+   temp &= 0xFEFF;
+   SiS_SetReg5((USHORT)(acpibase + 0x3c), temp);
+   temp = SiS_GetReg4((USHORT)(acpibase + 0x3c));
+   temp = SiS_GetReg4((USHORT)(acpibase + 0x3a));  /* ACPI register 0x3a: GP Pin Level (low/high) */
+   temp &= 0xFEFF;
    if(!(myvbinfo & SetCRT2ToTV)) {
-      temp1 |= 0x0100;
+      temp |= 0x0100;
    }
-   SiS_SetReg5((USHORT)eax, temp1);
-   temp1 = SiS_GetReg4((USHORT)eax);
+   SiS_SetReg5((USHORT)(acpibase + 0x3a), temp);
+   temp = SiS_GetReg4((USHORT)(acpibase + 0x3a));
 }
 
 void
@@ -4750,14 +4837,14 @@
   USHORT temp1=0,modeflag=0,tempcx=0;
   USHORT StandTableIndex,CRT1Index;
 #ifdef SIS315H   
-  USHORT ResInfo,DisplayType,temp=0;
+  USHORT ResIndex,DisplayType,temp=0;
   const  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
 #endif
 
   SiS_Pr->SiS_RVBHCMAX  = 1;
   SiS_Pr->SiS_RVBHCFACT = 1;
 
-  if(ModeNo <= 0x13){
+  if(ModeNo <= 0x13) {
 
     	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
     	StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
@@ -4771,7 +4858,7 @@
 
 #ifdef SIS315H     
     	temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-			RefreshRateTableIndex,&ResInfo,&DisplayType);
+			RefreshRateTableIndex,&ResIndex,&DisplayType);
 
     	if(temp == 0)  return;
 
@@ -4814,16 +4901,16 @@
 		case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
 		default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
     	}
-	tempax = (LVDSCRT1Ptr+ResInfo)->CR[0];
-	tempax |= (LVDSCRT1Ptr+ResInfo)->CR[14] << 8;
+	tempax = (LVDSCRT1Ptr+ResIndex)->CR[0];
+	tempax |= (LVDSCRT1Ptr+ResIndex)->CR[14] << 8;
 	tempax &= 0x03FF;
-    	tempbx = (LVDSCRT1Ptr+ResInfo)->CR[6];
-    	tempcx = (LVDSCRT1Ptr+ResInfo)->CR[13] << 8;
+    	tempbx = (LVDSCRT1Ptr+ResIndex)->CR[6];
+    	tempcx = (LVDSCRT1Ptr+ResIndex)->CR[13] << 8;
     	tempcx &= 0x0100;
     	tempcx <<= 2;
     	tempbx |= tempcx;
-	temp1  = (LVDSCRT1Ptr+ResInfo)->CR[7];
-#endif	
+	temp1  = (LVDSCRT1Ptr+ResIndex)->CR[7];
+#endif
 
     } else {
 
@@ -4859,11 +4946,12 @@
   if(modeflag & Charx8Dot) tempax *= 8;
   else                     tempax *= 9;
 
-  /* TW: From 650/30xLV 1.10.6s */
+  /* From 650/30xLV 1.10.6s */
   if(modeflag & HalfDCLK)  tempax <<= 1;
 
-  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
   tempbx++;
+
+  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
 }
 
@@ -4871,18 +4959,18 @@
 SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
 {
   if(HwDeviceExtension->jChipType >= SIS_315H)
-    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
   else
-    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
 }
 
 void
 SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
 {
   if(HwDeviceExtension->jChipType >= SIS_315H)
-    	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
   else
-     	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
 }
 
 void
@@ -4891,7 +4979,6 @@
   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
 }
 
-/* Checked against all BIOSes */
 void
 SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
 {
@@ -4901,9 +4988,9 @@
   USHORT temp=0;
   UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
 
-  if (SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== TW: For 30xB/LV ===== */
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
 
         if(HwDeviceExtension->jChipType < SIS_315H) {
 
@@ -4959,9 +5046,9 @@
 
         } else {
 
-#ifdef SIS315H	   /* 310/325 series */
+#ifdef SIS315H	   /* 315 series */
 
-           if(IS_SIS650740) {		/* 650, 740 */
+           if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
 
 #if 0
 	      if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
@@ -4985,22 +5072,35 @@
 	         SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
 
                  pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
-		 
+
 		 if(IS_SIS740) {
 		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
 		 }
 
 	         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-		 
-		 if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	            tempah = 0xef;
-	            if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	               tempah = 0xf7;
-                    }
-	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+
+		 if(!(IS_SIS740)) {
+		    if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	               tempah = 0xef;
+	               if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	                  tempah = 0xf7;
+                       }
+	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+		    }
 	         }
 
-              }
+              } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+	         if(HwDeviceExtension->jChipType == SIS_650) {
+	            if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,0xef);
+	            }
+		    if((!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+		       (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
+	     	       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+	            }
+		    SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 3);
+		 }
+	      }
 
               if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
 	         tempah = 0x3f;
@@ -5065,8 +5165,8 @@
 
 	      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
 
-		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);    /* 1.10.8r */
-		 
+		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);    		/* 1.10.8r, 8m */
+
 	         tempah = 0x3f;
 	         if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
 	            tempah = 0x7f;
@@ -5076,9 +5176,9 @@
 	         }
 	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
 
-		 if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {   /* 1.10.8r */
+		 if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {   /* 1.10.8r, 8m */
 	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-		 }								/* 1.10.8r */
+		 }								/* 1.10.8r, 8m */
 
 	         if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
 	            SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
@@ -5094,80 +5194,32 @@
 
 	         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
 
-  	      }
-
-#if 0
-          } else if(IS_SIS740) {	/* 740 */
-	  
-	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {   /* 30xLV */
-	     
-	        if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
-		    (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
-	     	      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
-	        }
-		
-		SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
-
-                pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
-		
-		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
-
-	        SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-		
-		if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-		   SiS_DisplayOff(SiS_Pr);
-	           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-	           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
-		} else {
-		   SiS_DisplayOff(SiS_Pr);
-	           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-	           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-	           temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
-                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
-	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	           SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
-		}
-		
-		SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
-		SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xEF);  /* (from 650) */
-		
-		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-		
-		if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
-	        }
-		
-		if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	              if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
-	                 if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
-                         }
-                      }
-	           }
-		}
-	        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
-	     
-	     } else {	/* (301,) 301B */
-	  
-	        if(SiS_Is301B(SiS_Pr,BaseAddr)) {
-	           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
-	        }
-	     
-	        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
-	        SiS_DisplayOff(SiS_Pr);
-	        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+  	      } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+	         if(HwDeviceExtension->jChipType == SIS_650) {
+		    if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+		       (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)))) {
+		       if((!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+		          (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)))) {
+			  SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2);
+	     	          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
+			  SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4);
+	               }
+		    }
+		 }
+	      } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+	         if(HwDeviceExtension->jChipType == SIS_650) {
+		    if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	               tempah = 0xef;
+	               if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+		          if(modenum > 0x13) {
+	                     tempah = 0xf7;
+			  }
+                       }
+	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+		    }
+		 }
+	      }
 
-	        temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
-                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
-	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
-		
-	     }
-#endif	  
 	  } else {			/* 315, 330 - all bridge types */
 
 	     if(SiS_Is301B(SiS_Pr,BaseAddr)) {
@@ -5212,13 +5264,13 @@
 
 	}
 
-      } else {     /* ============ TW: For 301 ================ */
+      } else {     /* ============ For 301 ================ */
 
         if(HwDeviceExtension->jChipType < SIS_315H) {
-            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
-	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
-	    }
+            if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+	      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+	      SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+	   }
 	}
 
         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
@@ -5237,18 +5289,23 @@
 	    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
 	} else {
             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
+	    if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
+	        (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
+		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+		SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+	    }
 	}
 
       }
 
-  } else {     /* ============ TW: For LVDS =============*/
+  } else {     /* ============ For LVDS =============*/
 
     if(HwDeviceExtension->jChipType < SIS_315H) {
 
 #ifdef SIS300	/* 300 series */
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-	    SiS_SetCH700x(SiS_Pr,0x090E);
+	   SiS_SetCH700x(SiS_Pr,0x090E);
 	}
 
 	if(HwDeviceExtension->jChipType == SIS_730) {
@@ -5264,17 +5321,17 @@
 
 	      if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
   
-  	          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+  	         if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
 
-                     SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+                    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
 
-		     if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
-		         SiS_DisplayOff(SiS_Pr);
-	             }
+		    if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
+		        SiS_DisplayOff(SiS_Pr);
+	            }
 
-	             SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
-	             SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-                  }
+	            SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+	            SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+                 }
               }
 	   }
 	}
@@ -5298,29 +5355,40 @@
 
     } else {
 
-#ifdef SIS315H	/* 310/325 series */
+#ifdef SIS315H	/* 315 series */
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-		temp = SiS_GetCH701x(SiS_Pr,0x61);
-		if(temp < 1) {
-		   SiS_SetCH701x(SiS_Pr,0xac76);
-		   SiS_SetCH701x(SiS_Pr,0x0066);
-		}
-		
-		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+
+		if(HwDeviceExtension->jChipType == SIS_740) {
+		   temp = SiS_GetCH701x(SiS_Pr,0x61);
+		   if(temp < 1) {
+		      SiS_SetCH701x(SiS_Pr,0xac76);
+		      SiS_SetCH701x(SiS_Pr,0x0066);
+		   }
+
+		   if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
 			SiS_SetCH701x(SiS_Pr,0x3e49);
-		} else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
+		   } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
 			SiS_SetCH701x(SiS_Pr,0x3e49);
+		   }
 		}
-		
+
 		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
 			SiS_Chrontel701xBLOff(SiS_Pr);
-			SiS_Chrontel701xOff(SiS_Pr);
+			SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension);
 		} else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
 			SiS_Chrontel701xBLOff(SiS_Pr);
-			SiS_Chrontel701xOff(SiS_Pr);
+			SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension);
 		}
-		
+
+		if(HwDeviceExtension->jChipType != SIS_740) {
+		   if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+			SiS_SetCH701x(SiS_Pr,0x0149);
+		   } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
+			SiS_SetCH701x(SiS_Pr,0x0149);
+		   }
+		}
+
 	}
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
@@ -5344,6 +5412,10 @@
 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
 	}
 
+	if(HwDeviceExtension->jChipType == SIS_740) {
+	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+	}
+
 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
@@ -5356,15 +5428,27 @@
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
 	        if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) {
-			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+		   if(HwDeviceExtension->jChipType == SIS_550) {
+		      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
+		      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
+		   }
 		}
-	} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+	} else {
+	   if(HwDeviceExtension->jChipType == SIS_740) {
+	        if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+		}
+	   } else {
+	        if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+	        }
+	   }
 	}
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
 	    	if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff);
+			/* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
 		} else {
 			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
 		}
@@ -5372,7 +5456,10 @@
 
 	SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
 
-	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+	if(HwDeviceExtension->jChipType == SIS_550) {
+	        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
+		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
+	} else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
 		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
 	} else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
 		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
@@ -5380,7 +5467,7 @@
 		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
 	}
 
-#if 0  /* TW: BIOS code makes no sense */
+#if 0  /* BIOS code makes no sense */
        if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
            if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
 	        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
@@ -5406,7 +5493,6 @@
 
 }
 
-/* TW: Checked against all BIOSes */
 void
 SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
@@ -5419,7 +5505,7 @@
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: ====== For 301B et al  ====== */
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ====== For 301B et al  ====== */
 
       if(HwDeviceExtension->jChipType < SIS_315H) {
 
@@ -5516,9 +5602,9 @@
 
       } else {
 
-#ifdef SIS315H    /* 310/325 series */
+#ifdef SIS315H    /* 315 series */
 
-	 if(IS_SIS650740) {		/* 650 */
+	 if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
 
 #if 0
 	    if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
@@ -5560,7 +5646,32 @@
 		  delaylong = TRUE;
 	       }
 
-	    }
+	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+	       if(HwDeviceExtension->jChipType == SIS_650) {
+	          if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x10);
+	          }
+		  if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+		      (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+		     SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0);
+		  }
+	       }
+  	    } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+
+	         if(HwDeviceExtension->jChipType == SIS_650) {
+		    if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	               tempah = 0x10;
+		       if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {
+		          tempah = 0x18;
+		          if((SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) {
+			     tempah = 0x08;
+			  }
+		       }
+	               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+		    }
+		 }
+	      }
 
 	    if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
                temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
@@ -5614,11 +5725,24 @@
 	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);	/* All this from 1.10.7u */
 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);  
-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);  
-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);  
-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); 
-	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); 
+
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x12);
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0xd0);
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x6b);
+	       if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) == 0x02) {
+	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x0d);
+	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x70);
+	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x40);
+		  if(((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) != 0x03)) {
+		     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);
+	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);
+	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x33);  /* 00 */
+		  }
+	       }
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	       if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x03) {
+	          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
+	       }
 	       
 	       SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
 	    
@@ -5629,127 +5753,44 @@
 	       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
 	          if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
 	              ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) {
-		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
-		    if(delaylong) {
+		     SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+		     if(delaylong) {
 			SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
-		    }
-                    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
-	         }
-	      }
+		     }
+                     SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+		     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
+	          }
+	       }
 
-	      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
-	      SiS_DisplayOn(SiS_Pr);
-	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+	       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+	       SiS_DisplayOn(SiS_Pr);
+	       SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
 
-	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
 	          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-	      }
+	       }
 #if 0
-              SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);   /* 1.10.8r: 0x0d */
-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);   /* 1.10.8r: 0x70 */
-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);   /* 1.10.8r: 0x40 */
-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); 
-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); 
+               SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);   /* 1.10.8r: 0x0d */
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);   /* 1.10.8r: 0x70 */
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);   /* 1.10.8r: 0x40 */
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
 #endif	      
+	    } if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+	       if(HwDeviceExtension->jChipType == SIS_650) {
+	          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		     if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+		         (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+			SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+		     }
+		  }
+	       }
+  	    }
 
-	  }
-
-#if 0
-         } else if(IS_SIS740) {		/* 740 */
-	 
-	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {  /* 30xLV */
-	   
-	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
-	      SiS_DisplayOff(SiS_Pr);
-	      pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
-	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
-	      
-	      if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-	          (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-                   if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
-		      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-	              SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-		   }
-	      }
-	      
-	      if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
-	         if(SiS_BridgeInSlave(SiS_Pr)) {
-                    tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-                    if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
-                 }
-                 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
-
-	         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);  	
-		 SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	      }
-	      
-	      if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
-	      }
-	      
-	      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0x10);  /* (taken from 650 1.10.8r) */
-	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
-	      
-	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	         if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-	             (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
-		    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
-		       SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-		    }
-		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
-		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
-		    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-	         }
-              }
-	      
-	      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
-	      SiS_DisplayOn(SiS_Pr);
-	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
-	      
-	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-	      }
-	   
-	   } else {	/* (301), 301B */
-	 
-	      if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
-	         if(SiS_BridgeInSlave(SiS_Pr)) {
-                    tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-                    if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
-                 }
-                 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
-
-	         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
-
-	         temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
-                 if(!(temp & 0x80))
-                    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
-              }
-
-	      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
-
-	      if(SiS_Is301B(SiS_Pr,BaseAddr)) { 
-	         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
-	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-	      } else {
-	         SiS_VBLongWait(SiS_Pr);
-                 SiS_DisplayOn(SiS_Pr);
-	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
-                 SiS_VBLongWait(SiS_Pr);
-	      }
-	      
-	   }
-#endif
-	  
 	 } else {			/* 315, 330 */
 
 	   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
@@ -5801,11 +5842,11 @@
 
       }
 
-    } else {	/* ============  TW: For 301 ================ */
+    } else {	/* ============  For 301 ================ */
 
        if(HwDeviceExtension->jChipType < SIS_315H) {
             if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
+                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
 	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
 	    }
        }
@@ -5837,13 +5878,13 @@
        if(HwDeviceExtension->jChipType < SIS_315H) {
             if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
 	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
-                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x03);
+                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
 	    }
        }
 
     }
 
-  } else {   /* =================== TW: For LVDS ================== */
+  } else {   /* =================== For LVDS ================== */
 
     if(HwDeviceExtension->jChipType < SIS_315H) {
 
@@ -5894,7 +5935,7 @@
 
     } else {
 
-#ifdef SIS315H    /* 310/325 series */
+#ifdef SIS315H    /* 315 series */
 
 #if 0  /* BIOS code makes no sense */
        if(SiS_IsVAMode()) {
@@ -5921,36 +5962,41 @@
 	  SiS_Chrontel701xBLOff(SiS_Pr);
        }
 
-       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-       
-#ifdef NEWCH701x
-       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-           if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) {
+       if(HwDeviceExtension->jChipType != SIS_550) {
+          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+       }
+
+       if(HwDeviceExtension->jChipType == SIS_740) {
+          if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+             if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) {
 	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
-	   }
+	     }
+	  }
        }
-#endif       
 
        temp1 = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
-       if (!(temp1 & 0x80))
+       if(!(temp1 & 0x80))
            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
            if(temp) {
-	       SiS_Chrontel701xBLOn(SiS_Pr);
+	       SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
 	   }
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
 	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+		if(HwDeviceExtension->jChipType == SIS_550) {
+		   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
+		   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
+		}
+	   }
+       } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+           if(HwDeviceExtension->jChipType != SIS_740) {
+              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
 	   }
-       } 
-#ifndef NEWCH701x       
-         else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
        }
-#endif       
 
        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
@@ -5973,10 +6019,10 @@
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
        	 	if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
  	   		if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	            		SiS_Chrontel701xBLOn(SiS_Pr);
+	            		SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
 	            		SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
            		} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr))  {
-       				SiS_Chrontel701xBLOn(SiS_Pr);
+       				SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
        				SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
 	   		}
        		}
@@ -6002,7 +6048,7 @@
 {
   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
 
-  /* TW: Switch on LCD backlight on SiS30xLV */
+  /* Switch on LCD backlight on SiS30xLV */
   if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
       (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
     if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
@@ -6020,7 +6066,7 @@
 {
   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
 
-  /* TW: Switch off LCD backlight on SiS30xLV */
+  /* Switch off LCD backlight on SiS30xLV */
   if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
       (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
@@ -6042,12 +6088,14 @@
   UCHAR *ROMAddr;
 
   if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
-     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
-     temp >>= 4;
-     temp = 1 << temp;
-     temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
-     if(temp1 & temp) return(1);
-     else return(0);
+     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
+        temp >>= 4;
+        temp = 1 << temp;
+        temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
+        if(temp1 & temp) return(1);
+        else return(0);
+     } else return(0);
   } else {
      return(0);
   }
@@ -6060,12 +6108,14 @@
   UCHAR *ROMAddr;
 
   if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
-     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
-     temp >>= 4;
-     temp = 1 << temp;
-     temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
-     if(temp1 & temp) return(1);
-     else return(0);
+     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
+        temp >>= 4;
+        temp = 1 << temp;
+        temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
+        if(temp1 & temp) return(1);
+        else return(0);
+     } else return(0);
   } else {
      return(0);
   }
@@ -6162,7 +6212,7 @@
 
 #ifdef SIS315H
 
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 310/325 series, LVDS */
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 315 series, LVDS */
 
           if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
               PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
@@ -6190,7 +6240,7 @@
 	      SiS_ShortDelay(SiS_Pr,Delay);
 	  }
 
-      } else {							/* 310/325 series, 301(B) */
+      } else {							/* 315 series, 301(B) */
 
           PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
 	  DelayIndex = PanelID >> 4;
@@ -6290,14 +6340,7 @@
   if(HwDeviceExtension->jChipType >= SIS_315H) {
      flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
      if((flag & EnableDualEdge) && (flag & SetToLCDA))   return(1);
-#if 0 /* Not done in 650/30xLV 1.10.6s, but in 650/301LV */
-     else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       if(flag) return(1);
-       else     return(0);   			         
-     }
-#endif
-     else
-       return(0);
+     else return(0);
   } else
 #endif
      return(0);
@@ -6344,7 +6387,9 @@
   if(HwDeviceExtension->jChipType == SIS_650) {
      flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
      flag &= 0xF0;
-     if((flag == 0xb0) || (flag == 0x90)) return 0;
+     /* Check for revision != A0 only */
+     if((flag == 0xe0) || (flag == 0xc0) ||
+        (flag == 0xb0) || (flag == 0x90)) return 0;
      else return 1;
   } else
 #endif
@@ -6462,7 +6507,7 @@
       if((flag == 0x80) || (flag == 0x20)) return 0;
       else	                           return 1;
     } else {
-      /* 310/325 series (650/30xLV 1.10.6s) */
+      /* 315 series (650/30xLV 1.10.6s) */
       flag &= 0x50;
       if((flag == 0x40) || (flag == 0x10)) return 0;
       else                                 return 1;
@@ -6506,14 +6551,14 @@
   }
 }
 
-BOOLEAN
+void
 SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
                   USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT temp,modeflag,resinfo=0;
   const unsigned char SiS300SeriesLCDRes[] =
-         { 0, 1, 2, 3, 7, 4, 5, 8,
-	   0, 0, 0, 0, 0, 0, 0, 0 };
+         { 0,  1,  2,  3,  7,  4,  5,  8,
+	   0,  0, 10,  0,  0,  0,  0, 15 };
 
   SiS_Pr->SiS_LCDResInfo = 0;
   SiS_Pr->SiS_LCDTypeInfo = 0;
@@ -6530,17 +6575,19 @@
      }
   }
 
-  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))   return 0;
+  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))   return;
 
-  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return 0;
+  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return;
 
   temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
 
+#if 0
   /* FSTN: Fake CR36 (TypeInfo 2, ResInfo SiS_Panel320x480) */
   if(SiS_Pr->SiS_IF_DEF_FSTN) {
    	temp = 0x20 | SiS_Pr->SiS_Panel320x480;
    	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
   }
+#endif
 
   if(HwDeviceExtension->jChipType < SIS_315H) {
   	SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
@@ -6549,14 +6596,16 @@
   }
   temp &= 0x0f;
   if(HwDeviceExtension->jChipType < SIS_315H) {
-      /* TW: Translate 300 series LCDRes to 310/325 series for unified usage */
+      /* Translate 300 series LCDRes to 315 series for unified usage */
       temp = SiS300SeriesLCDRes[temp];
   }
   SiS_Pr->SiS_LCDResInfo = temp;
 
+#if 0
   if(SiS_Pr->SiS_IF_DEF_FSTN){
        	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel320x480;
   }
+#endif
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
     	if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
@@ -6566,83 +6615,109 @@
 		SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
   }
 
-  if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
+  if((!SiS_Pr->CP_HaveCustomData) || (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_PanelCustom)) {
+     if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
   	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
+  }
+
+  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+     SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
+  }
+
+  switch(SiS_Pr->SiS_LCDResInfo) {
+     case Panel_800x600:   SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600; break;
+     case Panel_1024x768:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
+     case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; break;
+     case Panel_640x480_3:
+     case Panel_640x480_2:
+     case Panel_640x480:   SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480; break;
+     case Panel_1024x600:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600; break;
+     case Panel_1152x864:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864; break;
+     case Panel_1280x960:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960; break;
+     case Panel_1152x768:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768; break;
+     case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; break;
+     case Panel_1280x768:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768; break;
+     case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; break;
+     case Panel_320x480:   SiS_Pr->PanelXRes =  320; SiS_Pr->PanelYRes =  480; break;
+     case Panel_Custom:    SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
+    			   SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
+			   break;
+     case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; break;
+     default:		   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
+  }
 
   temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+#if 0
   if(SiS_Pr->SiS_IF_DEF_FSTN){
-        /* TW: Fake LVDS bridge for FSTN */
+        /* Fake LVDS bridge for FSTN */
       	temp = 0x04;
       	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,temp);
   }
+#endif
   SiS_Pr->SiS_LCDInfo = temp;
   
   if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
 
-  /* TW: Inserted entire 315-block from 650/LVDS/30xLV BIOSes */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-#ifdef SIS315H
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-		 if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
-		     /* Bridge does not scale to 1280x1024 */
-		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		 }
-	     }
-	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-	         if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
-		     /* TW: Bridge does not scale to 1280x960 */
-		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		 }
-		 if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
-		     /* TW: Bridge does not scale to 640x400 */
-		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		 }
-	     }
-	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-	         if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
-		     /* TW: Most panels can't scale to 640x400 */
-		     SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-		 }
-	     }
-	     /* TEMP - no idea about the timing and zoom factors */
-	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-	         SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	     }
-	     /* TEMP - no idea about the timing and zoom factors */
-	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
+	   /* For non-standard LCD resolution, we let the panel scale */
+           SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+	   if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
+	      /* Bridge does not scale to 1280x960 */
+              SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   } else if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
+	      if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+	         /* Bridge does not scale to 640x400 */
 	         SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	     }
-	 }
+	      }
+	   }
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+           /* TEMP - no idea about the timing and zoom factors */
+           SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+	   if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
+	      /* Bridge does not scale to 1280x1024 */
+	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   }
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+	   /* TEMP - no idea about the timing and zoom factors */
+	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	}
      }
+  }
+
+
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+#ifdef SIS315H
      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
-         SiS_Pr->SiS_LCDInfo &= 0xFFEF;    
-	 SiS_Pr->SiS_LCDInfo |= LCDPass11;
+        SiS_Pr->SiS_LCDInfo &= 0xFFEF;
+	SiS_Pr->SiS_LCDInfo |= LCDPass11;
      }
 #endif
   } else {
 #ifdef SIS300
      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
         if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-           if(!(ROMAddr[0x235] & 0x02)) {
-	      SiS_Pr->SiS_LCDInfo &= 0xEF;
+	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+              if(!(ROMAddr[0x235] & 0x02)) {
+	         SiS_Pr->SiS_LCDInfo &= 0xEF;
+ 	      }
 	   }
         }
-     } else {
-        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	   if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
-               SiS_Pr->SiS_LCDInfo &= 0xEF;
-	   }
+     } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
+           SiS_Pr->SiS_LCDInfo &= 0xEF;
 	}
      }
 #endif
   }
-  
-  /* TW: With Trumpion, always Expanding */
-  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0){
-       SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+
+  /* Trumpion: Assume non-expanding */
+  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
+     SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
   }
 
   if(!((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
@@ -6651,7 +6726,7 @@
         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
 	   if(ModeNo > 0x13) {
 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-                 if((resinfo == 7) || (resinfo == 3)) {
+                 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
                     SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
 		 }
               }
@@ -6671,9 +6746,9 @@
 	                                      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
                  if(ModeNo > 0x13) {
                     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-                       if(resinfo == 4) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 512x384  */
+                       if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
                     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-                       if(resinfo == 3) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 400x300  */
+                       if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
                     }
                  }
 	      } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
@@ -6692,19 +6767,21 @@
   }
 
 #ifdef SIS315H
-  /* TW: 650/30xLV 1.10.6s */
+  /* 650/30xLV 1.10.6s */
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-    if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
-      /* Enable 302B/302LV dual link mode */
-      /* (302B is a theory - not in any BIOS */
-      temp = 0x00;
-      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) temp = 0x04;
-      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x04;
-      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) temp = 0x04;
-      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,temp);
-    } else if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,0x00);
-    }
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,~0x04);
+        if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
+           /* Enable 302B/302LV dual link mode.
+            * (302B is a theory - not in any BIOS)
+	    */
+           if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+	      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x39,0x04);
+	   }
+  	}
+     }
   }
 #endif
 
@@ -6720,20 +6797,6 @@
 	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
 #endif
 
-  return 1;
-}
-
-void
-SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  return;
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x21);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0x41);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x28);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x33,0x22);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,0x43);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,0x01);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x00);  */
 }
 
 void
@@ -6763,7 +6826,6 @@
   } else {
     SiS_LongWait(SiS_Pr);
   }
-  return;
 }
 
 void
@@ -6830,7 +6892,7 @@
 #endif
   } else {
 #ifdef SIS300
-#if 0  /* TW: Not done in A901 BIOS */
+#if 0  /* Not done in A901 BIOS */
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
      }
@@ -6925,7 +6987,51 @@
 
 /* ========================================================= */
 
-/* TW: Set 301 TV Encoder (and some LCD relevant) registers */
+static void
+SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
+{
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+           if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);   /* 48 */
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);   /* de */
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
+	      if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38)) & 0x40) {
+	         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x14);
+	      } else {
+	         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x15);
+	      }
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1b);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
+           }
+        } else {
+	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x21);
+	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x5a);
+	}
+     }
+  }
+}
+
+/* Set 301 TV Encoder (and some LCD relevant) registers */
 void
 SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr, USHORT ModeNo,
               USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
@@ -6938,67 +7044,46 @@
 #ifdef SIS315H   
   const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
   USHORT      resindex, CRT2Index;
-#endif  
+#endif
   USHORT      modeflag, resinfo, crt2crtc;
-  ULONG       longtemp, tempeax, tempebx, temp2, tempecx;
+  ULONG       longtemp, tempeax;
+#ifdef SIS300
   const UCHAR atable[] = {
                  0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
 	         0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
   };
+#endif  
 
 #ifdef SIS315H   
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-     /* TW: 650/30xLV 1.10.6s: (Is at end of SetGroup2!) */
+     /* 650/30xLV 1.10.6s: (Is at end of SetGroup2!) */
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);
-	   temp = 1;
-	   if(ModeNo <= 0x13) temp = 3;
+	   temp = 0x01;
+	   if(ModeNo <= 0x13) temp = 0x03;
 	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
 	}
      }
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-           if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
-               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
-           }
-         }
-       }
-     }
+     SiS_SetTVSpecial(SiS_Pr, ModeNo);
      return;
   }
-#endif  
+#endif
 
-  if(ModeNo<=0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-    	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+	resinfo = 0;
+	crt2crtc = 0;
+     } else {
+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
     	crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     }
   }
 
   tempcx = SiS_Pr->SiS_VBInfo;
@@ -7011,9 +7096,9 @@
   temp |= ((tempbx & 0x00FF) >> 3);
   temp ^= 0x0C;
 
-  /* TW: From 1.10.7w (no vb check there; don't care - this only disables SVIDEO and CVBS signal) */
+  /* From 1.10.7w (no vb check there; don't care - this only disables SVIDEO and CVBS signal) */
   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-  	temp |= 0x0c;
+     temp |= 0x0c;
   }
 
   PhasePoint  = SiS_Pr->SiS_PALPhase;
@@ -7021,44 +7106,44 @@
   
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {          
   
-    temp ^= 0x01;
-    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-      TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
-      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-        if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
-        else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
-      }
-    } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
-    
-    if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe;
-    
+     temp ^= 0x01;
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
+        if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+           if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
+           else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
+        }
+     } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
+
+     if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe;
+
   } else {
-  
-    if(SiS_Pr->SiS_VBInfo & SetPALTV){
 
-      TimingPoint = SiS_Pr->SiS_PALTiming;
-      PhasePoint  = SiS_Pr->SiS_PALPhase;
+     if(SiS_Pr->SiS_VBInfo & SetPALTV){
 
-      if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
-          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-	    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
-         PhasePoint = SiS_Pr->SiS_PALPhase2;
-      }
+        TimingPoint = SiS_Pr->SiS_PALTiming;
+        PhasePoint  = SiS_Pr->SiS_PALPhase;
 
-    } else {
+        if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+            ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+           PhasePoint = SiS_Pr->SiS_PALPhase2;
+        }
+
+     } else {
 
         temp |= 0x10;
-	TimingPoint = SiS_Pr->SiS_NTSCTiming;
-	PhasePoint  = SiS_Pr->SiS_NTSCPhase;
+        TimingPoint = SiS_Pr->SiS_NTSCTiming;
+        PhasePoint  = SiS_Pr->SiS_NTSCPhase;
 
         if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
 	    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
 	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
-        	PhasePoint = SiS_Pr->SiS_NTSCPhase2;
+           PhasePoint = SiS_Pr->SiS_NTSCPhase2;
         }
 
-    }
-    
+     }
+
   }
   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,temp);
 
@@ -7071,36 +7156,35 @@
      temp = 0x38;
   }
   if(temp) {
-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-          temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
-          if(temp1 & EnablePALM) {	/* 0x40 */
-              	PhasePoint = SiS_Pr->SiS_PALMPhase;
-		if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
-		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
-	           PhasePoint = SiS_Pr->SiS_PALMPhase2;
-		}
-	  }
-          if(temp1 & EnablePALN) {	/* 0x80 */
-               	PhasePoint = SiS_Pr->SiS_PALNPhase;
-		if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
-		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
-	           PhasePoint = SiS_Pr->SiS_PALNPhase2;
-		}
-	  }
-      }
-    }
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+           temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
+           if(temp1 & EnablePALM) {	/* 0x40 */
+              PhasePoint = SiS_Pr->SiS_PALMPhase;
+	      if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+		  ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+		    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+	         PhasePoint = SiS_Pr->SiS_PALMPhase2;
+	      }
+	   }
+           if(temp1 & EnablePALN) {	/* 0x80 */
+              PhasePoint = SiS_Pr->SiS_PALNPhase;
+	      if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+		  ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+		    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+	         PhasePoint = SiS_Pr->SiS_PALNPhase2;
+	      }
+	   }
+        }
+     }
   }
 
 #ifdef SIS315H
-  /* TW: 650/301LV BIOS */
   if(HwDeviceExtension->jChipType >= SIS_315H) {
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {  
         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
            if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-              if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+              if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
 	         PhasePoint = SiS_Pr->SiS_SpecialPhase;
 	      }
            }
@@ -7121,12 +7205,12 @@
   }
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-    if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(!(SiS_Pr->SiS_ModeType & 0x07))
+     if(HwDeviceExtension->jChipType >= SIS_315H) {
+        if(!(SiS_Pr->SiS_ModeType & 0x07))
+           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
+     } else {
         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
-    } else {
-      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
-    }
+     }
   }
 
   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
@@ -7137,11 +7221,11 @@
   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-      if(SiS_Pr->SiS_HiVision == 3) tempax = 950;
-      else tempax = 440;
+     if(SiS_Pr->SiS_HiVision == 3) tempax = 950;
+     else tempax = 440;
   } else {
-    if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
-    else tempax = 440;
+     if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
+     else tempax = 440;
   }
 
   if( ( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_HiVision == 3) ) && (SiS_Pr->SiS_VDE <= tempax) ) ||
@@ -7161,18 +7245,18 @@
      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
 
      if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
-        (SiS_Pr->SiS_HiVision != 3) &&
-        (SiS_Pr->SiS_VGAHDE >= 1024) ) {
+         (SiS_Pr->SiS_HiVision != 3) &&
+         (SiS_Pr->SiS_VGAHDE >= 1024) ) {
         if(SiS_Pr->SiS_VBInfo & SetPALTV) {
            SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x19);
            SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x52);
         } else {
            if(HwDeviceExtension->jChipType >= SIS_315H) {
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
 	   } else {
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
 	   }
         }
      }
@@ -7181,7 +7265,7 @@
 
   tempcx = SiS_Pr->SiS_HT;
 
-  /* TW: 650/30xLV 1.10.6s */
+  /* 650/30xLV 1.10.6s */
   if(HwDeviceExtension->jChipType >= SIS_315H) {
       if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
       	   tempcx >>= 1;
@@ -7208,7 +7292,7 @@
   tempcx += 7;
   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
      (SiS_Pr->SiS_HiVision == 3)) {
-       tempcx -= 4;
+     tempcx -= 4;
   }
   temp = (tempcx & 0x00FF) << 4;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp);
@@ -7228,8 +7312,8 @@
   tempbx += 8;
   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
      (SiS_Pr->SiS_HiVision == 3)) {
-    tempbx -= 4;
-    tempcx = tempbx;
+     tempbx -= 4;
+     tempcx = tempbx;
   }
   temp = (tempbx & 0x00FF) << 4;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp);
@@ -7258,8 +7342,8 @@
 
   tempcx -= 11;
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
-    tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
-    tempcx = tempax;
+     tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
+     tempcx = tempax;
   }
   temp = tempcx & 0x00FF;
   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2E,temp);
@@ -7269,38 +7353,38 @@
   if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
   if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
   if(HwDeviceExtension->jChipType < SIS_315H) {
-  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
   } else {
-	if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
-	   tempbx >>= 1;
-	   if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-	      if(ModeNo <= 0x13) {
-	         if(crt2crtc == 1) {
-	            tempbx++;
-                 }
-	      }
-	   } else {
-              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-	         if(crt2crtc == 4)   /* TW: BIOS calls GetRatePtrCRT2 here - does not make sense */
-                    if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
-	      }
+     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+	tempbx >>= 1;
+	if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+	   if(ModeNo <= 0x13) {
+	      if(crt2crtc == 1) {
+	         tempbx++;
+              }
 	   }
-        }
+	} else {
+           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+	      if(crt2crtc == 4)   /* BIOS calls GetRatePtrCRT2 here - does not make sense */
+                 if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
+	   }
+	}
+     }
   }
   tempbx -= 2;
   temp = tempbx & 0x00FF;
   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
      (SiS_Pr->SiS_HiVision == 3)) {
-    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-      if(ModeNo == 0x2f) temp++;
-    }
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) temp++;
+     }
   }
-  /* TW: From 1.10.7w - doesn't make sense */
+  /* From 1.10.7w - doesn't make sense */
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
 	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {   /* SetFlag?? */
-	       if(ModeNo == 0x03) temp++;
+	      if(ModeNo == 0x03) temp++;
 	   }
 	}
      }
@@ -7312,15 +7396,15 @@
   tempax |= (tempbx & 0xFF00);
   if(HwDeviceExtension->jChipType < SIS_315H) {
      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) {		/* TW: New from 630/301B (II) BIOS */
+        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) {		/* New from 630/301B (II) BIOS */
            tempax |= 0x1000;
            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
         }
      }
   } else {
      /* TODO Check this with other BIOSes */
-     if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) && 
-        (SiS_Pr->SiS_HiVision == 3)) {
+     if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV))
+         /* && (SiS_Pr->SiS_HiVision == 3) */ ) {
 	tempax |= 0x1000;
         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
      }
@@ -7328,12 +7412,12 @@
   temp = (tempax & 0xFF00) >> 8;
   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,temp);
 
-  /* TW: 650/30xLV 1.10.6s */
+  /* 650/30xLV 1.10.6s */
   if(HwDeviceExtension->jChipType > SIS_315H) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
         if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) {
-            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
+           SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
         }
      }
   }
@@ -7349,79 +7433,70 @@
      }
   }
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {     
-    tempbx = SiS_Pr->SiS_VDE;
-    if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
-         tempbx >>= 1;
-    }
-    tempbx -= 3;
-    tempbx &= 0x03ff;
-    temp = ((tempbx & 0xFF00) >> 8) << 5;
-    temp |= 0x18;
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
-    temp = tempbx & 0x00FF;
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp);	/* tv gatingno */
-    if(HwDeviceExtension->jChipType >= SIS_315H) {	/* TW: 650/30xLV 1.10.6s */
-       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-          tempax = 0;
-          if(SiS_Pr->SiS_HiVision & 0x03) {
-	     tempax = 0x3000;
-	     if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000;
-	  }
-	  temp = (tempax & 0xFF00) >> 8;
-          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
-       }
-    }
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     tempbx = SiS_Pr->SiS_VDE;
+     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+        tempbx >>= 1;
+     }
+     tempbx -= 3;
+     tempbx &= 0x03ff;
+     temp = ((tempbx & 0xFF00) >> 8) << 5;
+     temp |= 0x18;
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
+     temp = tempbx & 0x00FF;
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp);	/* tv gatingno */
+     if(HwDeviceExtension->jChipType >= SIS_315H) {
+        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+           tempax = 0;
+           if(SiS_Pr->SiS_HiVision & 0x03) {
+ 	      tempax = 0x3000;
+	      if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000;
+	   }
+	   temp = (tempax & 0xFF00) >> 8;
+           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
+        }
+     }
   }
 
   tempbx &= 0x00FF;
   if(!(modeflag & HalfDCLK)) {
-    tempcx = SiS_Pr->SiS_VGAHDE;
-    if(tempcx >= SiS_Pr->SiS_HDE) {
-      tempbx |= 0x2000;
-      tempax &= 0x00FF;
-    }
+     if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
+        tempbx |= 0x2000;
+        tempax &= 0x00FF;
+     }
   }
 
   tempcx = 0x0101;
-/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) {  */ /*301b- TW: BIOS BUG? */
+/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) {  */ /* BIOS BUG? */
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
-    if(!(SiS_Pr->SiS_HiVision & 0x03)) {
-      if(SiS_Pr->SiS_VGAHDE >= 1024) {
-        if((!(modeflag & HalfDCLK)) || (HwDeviceExtension->jChipType < SIS_315H)) {   /* TW: This check not in 630/301B */
-          tempcx = 0x1920;
-          if(SiS_Pr->SiS_VGAHDE >= 1280) {
-            tempcx = 0x1420;
-            tempbx &= 0xDFFF;
-          }
+     if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+        if(SiS_Pr->SiS_VGAHDE >= 1024) {
+           if((!(modeflag & HalfDCLK)) || (HwDeviceExtension->jChipType < SIS_315H)) {
+              tempcx = 0x1920;
+              if(SiS_Pr->SiS_VGAHDE >= 1280) {
+                 tempcx = 0x1420;
+                 tempbx &= 0xDFFF;
+              }
+           }
         }
-      }
-    }
+     }
   }
 
   if(!(tempbx & 0x2000)) {
-    if(modeflag & HalfDCLK) {
-         tempcx = (tempcx & 0xFF00) | (((tempcx & 0x00FF) << 1) & 0xff);
-    }
-    push1 = tempbx;
-    tempeax = SiS_Pr->SiS_VGAHDE;
-    tempebx = (tempcx & 0xFF00) >> 8;
-    longtemp = tempeax * tempebx;
-    tempecx = tempcx & 0x00FF;
-    longtemp /= tempecx;
-    longtemp <<= 0x0d;
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     if(modeflag & HalfDCLK) {
+        tempcx = (tempcx & 0xFF00) | ((tempcx << 1) & 0x00FF);
+     }
+     longtemp = (SiS_Pr->SiS_VGAHDE * ((tempcx & 0xFF00) >> 8)) / (tempcx & 0x00FF);
+     longtemp <<= 13;
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
      	longtemp <<= 3;
-    }
-    tempecx = SiS_Pr->SiS_HDE;
-    temp2 = longtemp % tempecx;
-    tempeax = longtemp / tempecx;
-    if(temp2 != 0) tempeax++;
-    tempax = (USHORT)tempeax;
-    tempbx = push1;
-    tempcx = (tempcx & 0xff00) | (((tempax & 0xFF00) >> 8) >> 5);
-    tempbx |= (tempax & 0x1F00);
-    tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
+     }
+     tempeax = longtemp / SiS_Pr->SiS_HDE;
+     if(longtemp % SiS_Pr->SiS_HDE) tempeax++;
+     tempax = (USHORT)tempeax;
+     tempcx = (tempcx & 0xFF00) | ((tempax & 0xFF00) >> (8 + 5));
+     tempbx |= (tempax & 0x1F00);
+     tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
   }
 
   temp = (tempax & 0xFF00) >> 8;
@@ -7430,33 +7505,32 @@
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,temp);
 
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       temp = tempcx & 0x00FF;
-       if(tempbx & 0x2000) temp = 0;
-       temp |= 0x18;
-       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
-       if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-             tempbx = 0x0382;  
-             tempcx = 0x007e;  
-       } else {
-             tempbx = 0x0369;  
-             tempcx = 0x0061;  
-       }
-       temp = (tempbx & 0x00FF) ;
-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
-       temp = (tempcx & 0x00FF) ;
-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
-       tempbx &= 0x03FF;
-       temp = (tempcx & 0xFF00) >> 8;
-       temp = (temp & 0x0003) << 2;
-       temp |= (tempbx >> 8);
-       if(HwDeviceExtension->jChipType < SIS_315H) {
-          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
-       } else {
-          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
-       }
+     temp = tempcx & 0x00FF;
+     if(tempbx & 0x2000) temp = 0;
+     temp |= 0x18;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
 
-       temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
+     if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+        tempbx = 0x0382;
+        tempcx = 0x007e;
+     } else {
+        tempbx = 0x0369;
+        tempcx = 0x0061;
+     }
+     temp = (tempbx & 0x00FF) ;
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
+     temp = (tempcx & 0x00FF) ;
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
+     temp = (tempcx & 0x0300) >> (8 - 2);
+     temp |= ((tempbx >> 8) & 0x03);
+     if(HwDeviceExtension->jChipType < SIS_315H) {
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
+     } else {
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
+     }
+
+     temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
   }
 
   temp = 0;
@@ -7467,23 +7541,33 @@
      temp = 0x38;
   }
   if(temp) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-               if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) {  /* 0x40 */
-                     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
-                     temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
-                     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
-               }
-          }
-      }
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+           if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) {  /* 0x40 */
+              SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
+              temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
+           }
+        }
+     }
+  }
+
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
+        }
+     }
   }
 
+#if 0  /* Old: Why HiVision? */
   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
       (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) {
-    if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
-    }
+     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
+     }
   }
+#endif
 
   if(HwDeviceExtension->jChipType < SIS_315H) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
@@ -7492,74 +7576,43 @@
 	return;
      }
   } else {
-     /* TW: !!! The following is a duplicate, done for LCDA as well (see above) */
+     /* !!! The following is a duplicate, done for LCDA as well (see above) */
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-           if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-             if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
-               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
-	     }
-           }
-         }
-       }
-       return;
+        SiS_SetTVSpecial(SiS_Pr, ModeNo);
+        return;
      }
   }
 
-  /* TW: From here: Part2 LCD setup */
+  /* From here: Part2 LCD setup */
 
   tempbx = SiS_Pr->SiS_HDE;
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      /* TW: 650/30xLV 1.10.6s */
-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
+     /* 650/30xLV 1.10.6s */
+     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
   }
   tempbx--;			         	/* RHACTE=HDE-1 */
   temp = tempbx & 0x00FF;
   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2C,temp);
-  temp = (tempbx & 0xFF00) >> 8;
-  temp <<= 4;
+  temp = (tempbx & 0xFF00) >> 4;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
 
   temp = 0x01;
   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-    if(SiS_Pr->SiS_ModeType == ModeEGA) {
-      if(SiS_Pr->SiS_VGAHDE >= 1024) {
-        temp = 0x02;
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
-           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-             temp = 0x01;
+     if(SiS_Pr->SiS_ModeType == ModeEGA) {
+        if(SiS_Pr->SiS_VGAHDE >= 1024) {
+           temp = 0x02;
+	   if(HwDeviceExtension->jChipType >= SIS_315H) {
+              if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+                 temp = 0x01;
+	      }
 	   }
-	}
-      }
-    }
+        }
+     }
   }
   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,temp);
 
-  tempbx = SiS_Pr->SiS_VDE;         		/* RTVACTEO=(VDE-1)&0xFF */
-  push1 = tempbx;
-
+  tempbx = SiS_Pr->SiS_VDE;         		/* RTVACTEO = VDE - 1 */
+  /* push1 = tempbx; */
   tempbx--;
   temp = tempbx & 0x00FF;
   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x03,temp);
@@ -7567,10 +7620,9 @@
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
 
   tempcx = SiS_Pr->SiS_VT;
-  push2 = tempcx;
-
+  /* push2 = tempcx; */
   tempcx--;
-  temp = tempcx & 0x00FF;  			 /* RVTVT=VT-1 */
+  temp = tempcx & 0x00FF;  			 /* RVTVT = VT - 1 */
   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x19,temp);
 
   temp = (tempcx & 0xFF00) >> 8;
@@ -7578,30 +7630,26 @@
   
   /* Enable dithering; newer versions only do this for 32bpp mode */
   if((HwDeviceExtension->jChipType == SIS_300) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
-    if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
+     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
   } else if(HwDeviceExtension->jChipType < SIS_315H) {
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp |= 0x10;
-    else {
-      if(SiS_Pr->SiS_LCDInfo & LCDSync)       /* TW: 630/301 BIOS checks this */
-         temp |= 0x10;
-    }
+     temp |= 0x10;
   } else {
-      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-         /* TW: 650/30xLV 1.10.6s */
-         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-            if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {  /* 32bpp mode? */
-      	       temp |= 0x10;
-	    }
-         }
-      } else {
-         temp |= 0x10;
-      }
+     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        /* 650/30xLV 1.10.6s */
+        if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {  /* 32bpp mode? */
+              temp |= 0x10;
+	   }
+        }
+     } else {
+        temp |= 0x10;
+     }
   }
 
   /* 630/301 does not do all this */
   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
      if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-        /* TW: 650/30xLV 1.10.6s */
+        /* 650/30xLV 1.10.6s */
         temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6);
 	temp |= 0x08;   					/* From 1.10.7w */
 	if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04; 	/* From 1.10.7w */
@@ -7622,18 +7670,15 @@
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
 
-  /* 1280x960, 1280x1024 and 1600x1200 data invalid/missing in tables, use old calculation */
-  if((HwDeviceExtension->jChipType >= SIS_315H)             &&
-     (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)                &&
-     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) &&
-     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x768)  &&
-     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) &&
-     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960)) {
+  /* much data invalid/missing in tables, use old calculation in such case */
+  if((HwDeviceExtension->jChipType >= SIS_315H)         &&
+     (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)            &&
+     ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  ||
+      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)) ) {
      
-#ifdef SIS315H 							/* ------------- 310/325/330 series ------------ */
+#ifdef SIS315H 							/* ------------- 315/330 series ------------ */
 
-      /* TW: Inserted this entire section from 650/301LV(x) BIOS */
-      
       /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) results
        * in a black bar in modes < 1024; if the panel is non-expanding, the bridge
        * scales all modes to 1024. All modes in both variants (exp/non-exp) work.
@@ -7681,8 +7726,7 @@
 	  }
 	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
 	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xb3);
-	}
-	if(SiS_Pr->SiS_VGAVDE == 420) {
+	} else if(SiS_Pr->SiS_VGAVDE == 420) {
 	  temp = 0x4d;
 	  if(SiS_Pr->SiS_ModeType <= ModeVGA) {
 	     temp++;
@@ -7692,7 +7736,6 @@
 	}
      }
 
-     /* TW: 650/30xLV 1.10.6s: */
      /* !!! This is a duplicate, done for LCDA as well - see above */
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
@@ -7711,60 +7754,46 @@
        * the bridge scales all modes to 1024.
        * !!! Malfunction at 640x480 and 640x400 when panel is auto-expanding - black screen !!!
        */
-  
+
+    /* cx = VT - 1 */
+
     tempcx++;
-    
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx =  768;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1024;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1200;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempbx =  768;
-    else if(SiS_Pr->SiS_VDE != 1024) 				  tempbx =  960;
-    else            						  tempbx = 1024;
-    
-#if 0  /* old */
-    tempbx = 768;
-    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
-      tempbx = 1024;
-      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
-         tempbx = 1200;
-         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
-            if(tempbx != SiS_Pr->SiS_VDE) {
-               tempbx = 960;
-            }
-         }
-      }
-    }
-#endif
-    
+
+    tempbx = SiS_Pr->PanelYRes;
+
     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-      tempbx = SiS_Pr->SiS_VDE - 1;
-      tempcx--;
+       tempbx = SiS_Pr->SiS_VDE - 1;
+       tempcx--;
     }
-    
+
     tempax = 1;
     if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-      if(tempbx != SiS_Pr->SiS_VDE) {
-        tempax = tempbx;
-/*	if(SiS_Pr->SiS_VGAVDE == 525) tempax += 60;   in 650/301B BIOS */
-        if(tempax < SiS_Pr->SiS_VDE) {
-          tempax = 0;
-          tempcx = 0;
-        } else {
-          tempax -= SiS_Pr->SiS_VDE;
-        }
-        tempax >>= 1;
-      }
-      tempcx -= tempax; /* lcdvdes */
-      tempbx -= tempax; /* lcdvdee */
-    } else {
-      tempax >>= 1;
-      tempcx -= tempax; /* lcdvdes */
-      tempbx -= tempax; /* lcdvdee */
+       if(tempbx != SiS_Pr->SiS_VDE) {
+          tempax = tempbx;
+          if(tempax < SiS_Pr->SiS_VDE) {
+             tempax = 0;
+             tempcx = 0;
+          } else {
+             tempax -= SiS_Pr->SiS_VDE;
+          }
+          tempax >>= 1;
+       }
+       tempcx -= tempax; /* lcdvdes */
+       tempbx -= tempax; /* lcdvdee */
     }
-    
+#if 0  /* meaningless: 1 / 2 = 0... */
+    else {
+       tempax >>= 1;
+       tempcx -= tempax; /* lcdvdes */
+       tempbx -= tempax; /* lcdvdee */
+    }
+#endif
+
+    /* Non-expanding: lcdvdees = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
+
 #ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdvds 0x%x lcdvde 0x%x\n", tempcx, tempbx);
-#endif    
+    xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
+#endif
 
     temp = tempcx & 0x00FF;   				/* RVEQ1EQ=lcdvdes */
     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,temp);
@@ -7775,140 +7804,178 @@
     temp |= ((tempcx & 0xFF00) >> 8);
     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
 
-    tempbx = push2;
-    tempax = push1;
-    tempcx = tempbx;
-    tempcx -= tempax;
-    tempcx >>= 4;
+    tempbx = SiS_Pr->SiS_VT;    /* push2; */
+    tempax = SiS_Pr->SiS_VDE;   /* push1; */
+    tempcx = (tempbx - tempax) >> 4;
     tempbx += tempax;
     tempbx >>= 1;
     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx -= 10;
-    
+
+    /* non-expanding: lcdvrs = tempbx = ((VT + VDE) / 2) - 10 */
+
+    if(SiS_Pr->UseCustomMode) {
+       tempbx = SiS_Pr->CVSyncStart;
+    }
+
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
 #endif
 
-    temp = tempbx & 0x00FF;   				/* RTVACTEE=lcdvrs */
+    temp = tempbx & 0x00FF;   				/* RTVACTEE = lcdvrs */
     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
 
     temp = ((tempbx & 0xFF00) >> 8) << 4;
     tempbx += (tempcx + 1);
     temp |= (tempbx & 0x000F);
+
+    if(SiS_Pr->UseCustomMode) {
+       temp &= 0xf0;
+       temp |= (SiS_Pr->CVSyncEnd & 0x0f);
+    }
+
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
+#endif
+
     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
 
-    /* TW: Code from 630/301B (I+II) BIOS */
+    /* Code from 630/301B (I+II) BIOS */
 
-    if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
-            (HwDeviceExtension->jChipType == SIS_730) ) &&
-          (HwDeviceExtension->jChipRevision > 2) )  &&
-        (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
-        (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
-        (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
-            if(ModeNo == 0x13) {
-              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
-              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
-              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
-            } else {
-              if((crt2crtc & 0x3F) == 4) {
+    if(!SiS_Pr->UseCustomMode) {
+       if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
+               (HwDeviceExtension->jChipType == SIS_730) ) &&
+             (HwDeviceExtension->jChipRevision > 2) )  &&
+           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
+           (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
+           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+          if(ModeNo == 0x13) {
+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
+          } else {
+             if((crt2crtc & 0x3F) == 4) {
                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x2B);
                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x13);
                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xE5);
                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0x08);
                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xE2);
-              }
-            }
+             }
+          }
+       }
     }
 
-    /* TW: Inserted missing code from 630/301B BIOS;
-     *     Strangely, this is done in all 650 BIOSes as
-     *     well (although LCDTypeInfo is not used there
-     *     in the same way as on 300 series)
-     */
-
-    if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
-         crt2crtc &= 0x1f;
-         tempcx = 0;
-         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
-           if (SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-              tempcx += 7;
-           }
-         }
-         tempcx += crt2crtc;
-         if (crt2crtc >= 4) {
-           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
-         }
+#ifdef SIS300
+    if(HwDeviceExtension->jChipType < SIS_315H) {
+       if(!SiS_Pr->UseCustomMode) {
+          if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
+             crt2crtc &= 0x1f;
+             tempcx = 0;
+             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+                   tempcx += 7;
+                }
+             }
+             tempcx += crt2crtc;
+             if(crt2crtc >= 4) {
+                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
+             }
 
-         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
-           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-             if(crt2crtc == 4) {
-                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
+             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+                   if(crt2crtc == 4) {
+                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
+                   }
+                }
              }
-           }
-         }
-         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
-         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
+          }
+       }
     }
+#endif
 
-    tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT-HDE)>>2     */
+    tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT - HDE) >> 2 */
     tempbx = SiS_Pr->SiS_HDE + 7;            		  /* lcdhdee         */
     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         tempbx += 2;
+       tempbx += 2;
     }
     push1 = tempbx;
+
 #ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdhde 0x%x\n", tempbx);
-#endif    
-    temp = tempbx & 0x00FF;    			          /* RHEQPLE=lcdhdee */
+    xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
+#endif
+
+    temp = tempbx & 0x00FF;    			          /* RHEQPLE = lcdhdee */
     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,temp);
     temp = (tempbx & 0xFF00) >> 8;
     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
 
     temp = 7;
     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         temp += 2;
+       temp += 2;
     }
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp);  	  /* RHBLKE=lcdhdes[7:0] */
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp);  	  /* RHBLKE = lcdhdes[7:0] */
     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F);	  /* lcdhdes [11:8] */
 
     tempbx += tempcx;
     push2 = tempbx;
+
+    if(SiS_Pr->UseCustomMode) {
+       tempbx = SiS_Pr->CHSyncStart + 7;
+       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+          tempbx += 2;
+       }
+    }
+
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
 #endif
-    temp = tempbx & 0x00FF;            		          /* RHBURSTS=lcdhrs */
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-          if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
+
+    temp = tempbx & 0x00FF;            		          /* RHBURSTS = lcdhrs */
+    if(!SiS_Pr->UseCustomMode) {
+       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+             if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
+          }
        }
     }
     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1C,temp);
-    temp = ((tempbx & 0xFF00) >> 8) << 4;
+    temp = (tempbx & 0x0F00) >> 4;
     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
 
     tempbx = push2;
     tempcx <<= 1;
     tempbx += tempcx;
+
+    if(SiS_Pr->UseCustomMode) {
+       tempbx = SiS_Pr->CHSyncEnd + 7;
+       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+          tempbx += 2;
+       }
+    }
+
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
-#endif    
-    temp = tempbx & 0x00FF;            		          /* RHSYEXP2S=lcdhre */
+#endif
+
+    temp = tempbx & 0x00FF;            		          /* RHSYEXP2S = lcdhre */
     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,temp);
 
     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-      if(SiS_Pr->SiS_VGAVDE == 525) {
-        if(SiS_Pr->SiS_ModeType <= ModeVGA)
-    	   temp=0xC6;
-        else
-       	   temp=0xC3;
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
-      } else if(SiS_Pr->SiS_VGAVDE == 420) {
-        if(SiS_Pr->SiS_ModeType <= ModeVGA)
-	   temp=0x4F;
-        else
-       	   temp=0x4D;   
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
-      }
+       if(SiS_Pr->SiS_VGAVDE == 525) {
+          if(SiS_Pr->SiS_ModeType <= ModeVGA)
+    	     temp=0xC6;
+          else
+       	     temp=0xC3;
+          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
+       } else if(SiS_Pr->SiS_VGAVDE == 420) {
+          if(SiS_Pr->SiS_ModeType <= ModeVGA)
+	     temp=0x4F;
+          else
+       	     temp=0x4D;
+          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+       }
     }
     SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex,
                         RefreshRateTableIndex, BaseAddr, ModeNo);
@@ -7927,7 +7994,7 @@
   return((USHORT) tempax);
 }
 
-/* TW: New from 300/301LV BIOS 1.16.51 for ECS A907. Seems highly preliminary. */
+/* New from 300/301LV BIOS 1.16.51 for ECS A907. Seems highly preliminary. */
 void
 SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
     			USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
@@ -7939,18 +8006,19 @@
 
   if(HwDeviceExtension->jChipType != SIS_300) return;
   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+  if(SiS_Pr->UseCustomMode) return;
 
-  if(ModeNo<=0x13) {
-    	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  if(ModeNo <= 0x13) {
+     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
-    	crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   }
 
   resindex = crt2crtc & 0x3F;
   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
 
-  /* TW: The BIOS code (1.16.51) is obviously a fragment! */
+  /* The BIOS code (1.16.51) is obviously a fragment! */
   if(ModeNo > 0x13) {
      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
      resindex = 4;
@@ -7971,7 +8039,6 @@
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
 }
 
-/* TW: Set 301 Macrovision(tm) registers */
 void
 SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
               USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
@@ -7983,24 +8050,35 @@
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
 
-  if(ModeNo<=0x13)
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  else
+  if(ModeNo<=0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+     } else {
     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     }
+  }
 
+#ifndef SIS_CP
   SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x00,0x00);
+#endif  
+
+#ifdef SIS_CP
+  SIS_CP_INIT301_CP
+#endif
 
   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
-    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+     SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+     SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
   } else {
-    if(HwDeviceExtension->jChipType >= SIS_315H) {
-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
-    } else {
-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
-    }
+     if(HwDeviceExtension->jChipType >= SIS_315H) {
+        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
+        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
+     } else {
+        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
+        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
+     }
   }
 
   temp = 0;
@@ -8008,41 +8086,44 @@
      (HwDeviceExtension->jChipType == SIS_730)) {
      temp = 0x35;
   } else if(HwDeviceExtension->jChipType >= SIS_315H) {
-     temp = 0x38;
-  }
-  if(temp) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-              if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){  /* 0x40 */
-                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
-                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
-                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
-              }
-          }
-      }
+     temp = 0x38;
+  }
+  if(temp) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+           if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){  /* 0x40 */
+              SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+              SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+              SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
+           }
+        }
+     }
   }
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-    tempdi = SiS_Pr->SiS_HiTVGroup3Data;
-    if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-      tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
-      if(!(modeflag & Charx8Dot)) {
-        tempdi = SiS_Pr->SiS_HiTVGroup3Text;
-      }
-    }
-    if(SiS_Pr->SiS_HiVision & 0x03) {
-       tempdi = SiS_HiTVGroup3_1;
-       if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
-    }
-    for(i=0; i<=0x3E; i++){
-       SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
-    }
+     tempdi = SiS_Pr->SiS_HiTVGroup3Data;
+     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+        tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
+        if(!(modeflag & Charx8Dot)) {
+           tempdi = SiS_Pr->SiS_HiTVGroup3Text;
+        }
+     }
+     if(SiS_Pr->SiS_HiVision & 0x03) {
+        tempdi = SiS_HiTVGroup3_1;
+        if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
+     }
+     for(i=0; i<=0x3E; i++){
+        SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
+     }
   }
 
-  return;
+#ifdef SIS_CP
+  SIS_CP_INIT301_CP2
+#endif
+
 }
 
-/* TW: Set 301 VGA2 registers */
+/* Set 301 VGA2 registers */
 void
 SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
               USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
@@ -8051,17 +8132,20 @@
   USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,resinfo;
   ULONG tempebx,tempeax,templong;
 
-
-  if(ModeNo<=0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+	resinfo = 0;
+     } else {
     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     }
   }
 
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      /* TW: From 650/302LV 1.10.6s (not for 300/301LV - no LCDA on this combination) */
      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
            SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
@@ -8078,10 +8162,10 @@
   if(HwDeviceExtension->jChipType >= SIS_315H) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	   /* TW: From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */
-  	   /* TW: This is a duplicate; done at the end, too */
+	   /* From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */
+  	   /* This is a duplicate; done at the end, too */
 	   if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
-		SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
 	   }
 	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
 	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
@@ -8119,39 +8203,33 @@
   tempbx = SiS_Pr->SiS_VGAHDE;
   if(modeflag & HalfDCLK)  tempbx >>= 1;
 
-  /* TW: New for 650/301LV and 630/301B */
   temp = 0xA0;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-       temp = 0;
-       if(tempbx > 800) {
-          temp = 0xA0;
-          if(tempbx != 1024) {
-             temp = 0xC0;
-             if(tempbx != 1280) temp = 0;
-	  }
-       }
-  } else
-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-      if(tempbx <= 800) {
-         temp = 0x80;
-	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-            temp = 0;
-            if(tempbx > 800) temp = 0x60;
-         }
-      }
+     temp = 0;
+     if(tempbx > 800) {
+        temp = 0xA0;
+        if(tempbx != 1024) {
+           temp = 0xC0;
+           if(tempbx != 1280) temp = 0;
+	}
+     }
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     if(tempbx <= 800) {
+        temp = 0x80;
+     }
   } else {
-      temp = 0x80;
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-            temp = 0;
-            if(tempbx > 800) temp = 0x60;
-      }
+     temp = 0x80;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        temp = 0;
+        if(tempbx > 800) temp = 0x60;
+     }
   }
   if(SiS_Pr->SiS_HiVision & 0x03) {
         temp = 0;
 	if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
   }
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-  	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
+     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
   }
 
   if(SiS_Pr->SiS_VBType & VB_SIS301) {
@@ -8173,10 +8251,10 @@
 
   tempeax = SiS_Pr->SiS_VGAVDE;
   tempcx |= 0x4000;
-  if(tempeax <= tempebx){
-    tempcx ^= 0x4000;
+  if(tempeax <= tempebx) {
+     tempcx ^= 0x4000;
   } else {
-    tempeax -= tempebx;
+     tempeax -= tempebx;
   }
 
   templong = (tempeax * 256 * 1024) % tempebx;
@@ -8202,64 +8280,64 @@
          tempax = SiS_Pr->SiS_VGAHDE;
          if(modeflag & HalfDCLK) tempax >>= 1;
          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || (SiS_Pr->SiS_HiVision & 0x03)) {
-	     if(HwDeviceExtension->jChipType >= SIS_315H) {
-	         if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
-		 else if(tempax > 800) tempax -= 800;
-	     } else {
-                 if(tempax > 800) tempax -= 800;
-             }
+	    if(HwDeviceExtension->jChipType >= SIS_315H) {
+	       if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
+	       else if(tempax > 800) tempax -= 800;
+	    } else {
+               if(tempax > 800) tempax -= 800;
+            }
          }
 
 /*       if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetPALTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {  */
  	 if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
-           if(tempax > 800) {
-	      tempbx = 8;
-              if(tempax == 1024)
-	        tempax *= 25;
-              else
-	        tempax *= 20;
-
-	      temp = tempax % 32;
-	      tempax /= 32;
-	      tempax--;
-	      if (temp!=0) tempax++;
-           }
+            if(tempax > 800) {
+	       tempbx = 8;
+               if(tempax == 1024)
+	          tempax *= 25;
+               else
+	          tempax *= 20;
+
+	       temp = tempax % 32;
+	       tempax /= 32;
+	       tempax--;
+	       if (temp!=0) tempax++;
+            }
          }
 	 tempax--;
          temp = (tempax & 0xFF00) >> 8;
          temp &= 0x03;
-	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {		/* From 1.10.7w */
-	 	if(ModeNo > 0x13) {			/* From 1.10.7w */
-			if(resinfo == 8) tempax = 0x1f;	/* From 1.10.7w */
-		}					/* From 1.10.7w */
-	 }						/* From 1.10.7w */
+	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* From 1.10.7w */
+	    if(ModeNo > 0x13) {					/* From 1.10.7w */
+	       if(resinfo == SIS_RI_1024x768) tempax = 0x1f;	/* From 1.10.7w */
+	    }							/* From 1.10.7w */
+	 }							/* From 1.10.7w */
 	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
 	 temp <<= 4;
 	 temp |= tempbx;
 	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1E,temp);
 
 	 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	    if(IS_SIS650740) {
-	        temp = 0x0026;  /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
+	    if(IS_SIS550650740660) {
+	       temp = 0x0026;  /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
 	    } else {
-	        temp = 0x0036;
+	       temp = 0x0036;
 	    }
 	 } else {
-	     temp = 0x0036;
+	    temp = 0x0036;
 	 }
          if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
 	                               (!(SiS_Pr->SiS_HiVision & 0x03))) {
-		temp |= 0x01;
-	        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-	          if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
-  	                  temp &= 0xFE;
-		}
+	    temp |= 0x01;
+	    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+	       if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
+  	          temp &= 0xFE;
+	    }
          }
          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
 
 	 tempbx = SiS_Pr->SiS_HT;
 	 if(HwDeviceExtension->jChipType >= SIS_315H) {
-	 	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
+	    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
 	 }
          tempbx >>= 1;
 	 tempbx -= 2;
@@ -8267,7 +8345,7 @@
          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
          temp = tempbx & 0x00FF;
          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x22,temp);
-	 
+
          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
                SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
@@ -8275,24 +8353,24 @@
 	 }
 
 	 if(HwDeviceExtension->jChipType >= SIS_315H) {
-	     /* TW: 650/LV BIOS does this for all bridge types - assumingly wrong */
-	     /* 315, 330, 650+301B BIOS don't do this at all */
-             /* TW: This is a duplicate; done for LCDA as well (see above) */
-	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
-		   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
-	        }
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
-	     }
+	    /* 650/LV BIOS does this for all bridge types - assumingly wrong */
+	    /* 315, 330, 650+301B BIOS don't do this at all */
+            /* This is a duplicate; done for LCDA as well (see above) */
+	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	       if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+		  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+	       }
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	    }
          } else if(HwDeviceExtension->jChipType == SIS_300) {
-	     /* TW: 300/301LV BIOS does this for all bridge types - assumingly wrong */
-	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
-	     }
+	    /* 300/301LV BIOS does this for all bridge types - assumingly wrong */
+	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	    }
 	 }
 
   }  /* 301B */
@@ -8307,21 +8385,26 @@
                  USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT vclkindex;
-  USHORT tempah;
+  USHORT temp, reg1, reg2;
 
-  vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                              HwDeviceExtension);
+  if(SiS_Pr->UseCustomMode) {
+     reg1 = SiS_Pr->CSR2B;
+     reg2 = SiS_Pr->CSR2C;
+  } else {
+     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                                 HwDeviceExtension);
+     reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
+     reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
+  }
 
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1);
+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2);
      if(HwDeviceExtension->jChipType >= SIS_315H) {
 	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
 	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-                 if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+                 if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
 		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0a,0x57);
 		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0b,0x46);
 		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
@@ -8332,15 +8415,13 @@
      }
   } else {	
      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,0x01);
-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2);
+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1);
   }
   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x12,0x00);
-  tempah = 0x08;
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) tempah |= 0x20;
-  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,tempah);
+  temp = 0x08;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
+  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
 }
 
 USHORT
@@ -8348,23 +8429,24 @@
                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT tempbx;
-  const USHORT LCDXlat0VCLK[4]    = {VCLK40, VCLK40, VCLK40, VCLK40};
-  const USHORT LVDSXlat1VCLK[4]   = {VCLK40, VCLK40, VCLK40, VCLK40};
+  const USHORT LCDXlat0VCLK[4]    = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
+  const USHORT LVDSXlat1VCLK[4]   = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
+  const USHORT LVDSXlat4VCLK[4]   = {VCLK28,       VCLK28,       VCLK28,       VCLK28};
 #ifdef SIS300
-  const USHORT LCDXlat1VCLK300[4] = {VCLK65,   VCLK65,   VCLK65,   VCLK65};
-  const USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
-  const USHORT LVDSXlat2VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
-  const USHORT LVDSXlat3VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
+  const USHORT LCDXlat1VCLK300[4] = {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
+  const USHORT LCDXlat2VCLK300[4] = {VCLK108_2_300,VCLK108_2_300,VCLK108_2_300,VCLK108_2_300};
+  const USHORT LVDSXlat2VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
+  const USHORT LVDSXlat3VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
 #endif
 #ifdef SIS315H
-  const USHORT LCDXlat1VCLK310[4] = {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
-  const USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
-  const USHORT LVDSXlat2VCLK310[4]= {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
-  const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
+  const USHORT LCDXlat1VCLK310[4] = {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
+  const USHORT LCDXlat2VCLK310[4] = {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
+  const USHORT LVDSXlat2VCLK310[4]= {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
+  const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
 #endif
   USHORT CRT2Index,VCLKIndex=0;
   USHORT modeflag,resinfo;
-  const UCHAR *CHTVVCLKPtr=NULL;
+  const UCHAR  *CHTVVCLKPtr = NULL;
   const USHORT *LCDXlatVCLK1 = NULL;
   const USHORT *LCDXlatVCLK2 = NULL;
   const USHORT *LVDSXlatVCLK2 = NULL;
@@ -8401,32 +8483,38 @@
      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
 
         CRT2Index >>= 6;
-        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)){      /*  LCD */
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      /*  LCD */
             if(HwDeviceExtension->jChipType < SIS_315H) {
-	       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)
+	       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
 	    		VCLKIndex = LCDXlat0VCLK[CRT2Index];
-	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
+	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
 	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
-	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
+	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
 	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
-	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
+	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
 	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
-	       else
+	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+	                VCLKIndex = VCLK81_300;	/* guessed */
+	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+		        VCLKIndex = VCLK108_3_300;
+		        if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_300;
+	       } else {
 	    		VCLKIndex = LCDXlatVCLK2[CRT2Index];
+	       }
 	    } else {
 	       if( (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) ||
 	           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
       	          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-		     VCLKIndex = 0x19;
+		     VCLKIndex = VCLK108_2_315;
 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-		     VCLKIndex = 0x12;  /* TEMP - guessed */
+		     VCLKIndex = VCLK81_315;  	/* guessed */
 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-		     VCLKIndex = 0x19;
+		     VCLKIndex = VCLK108_2_315;
 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-		     VCLKIndex = 0x21;
+		     VCLKIndex = VCLK162_315;
 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-		     VCLKIndex = 0x45;  /* TW: in VBVCLK table */
-		     if(resinfo == 0x09) VCLKIndex++;
+		     VCLKIndex = VCLK108_3_315;
+		     if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_315;
 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
 		     VCLKIndex = LCDXlatVCLK1[CRT2Index];
 	          } else {
@@ -8465,9 +8553,11 @@
        			if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO)  VCLKIndex = TVVCLKDIV2;
             		else         		              VCLKIndex = TVVCLK;
           	}
-		if(HwDeviceExtension->jChipType >= SIS_315H) {
-              		VCLKIndex += 25;
-  		}
+		if(HwDeviceExtension->jChipType < SIS_315H) {
+              		VCLKIndex += TVCLKBASE_300;
+  		} else {
+			VCLKIndex += TVCLKBASE_315;
+		}
         } else {         					/* RAMDAC2 */
         	VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
         	VCLKIndex = ((VCLKIndex >> 2) & 0x03);
@@ -8477,7 +8567,11 @@
           			VCLKIndex &= 0x3f;
 				if( (HwDeviceExtension->jChipType == SIS_630) &&
 				    (HwDeviceExtension->jChipRevision >= 0x30)) {
-				     if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
+				     /* This is certainly wrong: It replaces clock
+				      * 108 by 47...
+				      */
+				     /* if(VCLKIndex == 0x14) VCLKIndex = 0x2e; */
+				     if(VCLKIndex == 0x14) VCLKIndex = 0x34;
 				}
 			}
         	}
@@ -8541,6 +8635,10 @@
      		if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
 		   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
      			VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
+		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480   ||
+		        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+			SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)
+			VCLKIndex = LVDSXlat4VCLK[VCLKIndex];
      		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
      			VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
 		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
@@ -8549,6 +8647,11 @@
                         VCLKIndex = LVDSXlatVCLK2[VCLKIndex];			
      		else    VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
 
+		if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+		   /* Special Timing: Barco iQ Pro R300/400 */
+		   VCLKIndex = 0x44;
+		}
+
 	   } else {
 
 	        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
@@ -8592,11 +8695,11 @@
 #ifdef TWDEBUG
   xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
 #endif
-  return (VCLKIndex);
+  return(VCLKIndex);
 }
 
-/* TW: Set 301 Palette address port registers */
-/* TW: Checked against 650/301LV BIOS */
+/* Set 301 Palette address port registers */
+/* Checked against 650/301LV BIOS */
 void
 SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
               UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
@@ -8604,7 +8707,7 @@
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
 
-  if(SiS_Pr->SiS_ModeType == ModeVGA){
+  if(SiS_Pr->SiS_ModeType == ModeVGA) {
      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))){
         SiS_EnableCRT2(SiS_Pr);
         SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
@@ -8617,17 +8720,21 @@
                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT temp,tempah,i,modeflag,j;
-  USHORT ResInfo,DisplayType;
+  USHORT ResIndex,DisplayType;
   const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
 
   if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
+  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+     (SiS_Pr->SiS_CustomT == CUT_BARCO1024))
+     return;
+
   temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                            &ResInfo,&DisplayType);
+                            &ResIndex,&DisplayType);
 
   if(temp == 0) return;
 
@@ -8675,47 +8782,53 @@
     case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H;        break;
     case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2;          break;
     case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H;        break;
+    case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
+    case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
+    case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2;           break;
+    case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H;         break;
+    case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3;           break;
+    case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H;         break;
     case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
     default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
   }
 
   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
 
-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
+  tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
 
   for(i=0x02,j=1;i<=0x05;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x06,j=5;i<=0x07;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x10,j=7;i<=0x11;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x15,j=9;i<=0x16;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x0A,j=11;i<=0x0C;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
     SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
   }
 
-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
   tempah &= 0xE0;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);     
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
 
-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
   tempah &= 0x01;
   tempah <<= 5;
   if(modeflag & DoubleScanMode)  tempah |= 0x080;
   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
 
-  /* TW: 650/LVDS BIOS - doesn't make sense */
+  /* 650/LVDS BIOS - doesn't make sense */
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
      if(modeflag & HalfDCLK)
         SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
@@ -8724,7 +8837,7 @@
 
 BOOLEAN
 SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
+		   USHORT RefreshRateTableIndex,USHORT *ResIndex,
 		   USHORT *DisplayType)
  {
   USHORT tempbx,modeflag=0;
@@ -8793,19 +8906,33 @@
            tempbx = 40;
 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
 	   if(modeflag & HalfDCLK) tempbx++;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
+           tempbx = 54;
+	   if(modeflag & HalfDCLK) tempbx++;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
+           tempbx = 52;
+	   if(modeflag & HalfDCLK) tempbx++;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+           tempbx = 50;
+	   if(modeflag & HalfDCLK) tempbx++;
         }
+
      }
      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
         tempbx = 12;
 	if(modeflag & HalfDCLK) tempbx++;
      }
   }
-  if(SiS_Pr->SiS_IF_DEF_FSTN){
+
+#if 0
+  if(SiS_Pr->SiS_IF_DEF_FSTN) {
      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
         tempbx = 22;
      }
   }
-  *ResInfo = CRT2CRTC & 0x3F;
+#endif
+
+  *ResIndex = CRT2CRTC & 0x3F;
   *DisplayType = tempbx;
   return 1;
 }
@@ -8814,54 +8941,54 @@
 SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
            USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  USHORT tempah,tempal,pushax;
-  USHORT vclkindex=0;
-    
+  USHORT clkbase, vclkindex=0;
+  UCHAR  sr2b, sr2c;
+
   if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
 	SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
-        tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-    	tempal &= 0x3F;
-	if(tempal == 2) RefreshRateTableIndex--;
+        if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
+	   RefreshRateTableIndex--;
+	}
 	vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                               RefreshRateTableIndex,HwDeviceExtension);
+                                    RefreshRateTableIndex,HwDeviceExtension);
 	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
   } else {
         vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                               RefreshRateTableIndex,HwDeviceExtension);
+                                    RefreshRateTableIndex,HwDeviceExtension);
   }
-  
-  tempal = 0x02B;
+
+  sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+  sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+
+  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+     if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+	if(ROMAddr[0x220] & 0x01) {
+           sr2b = ROMAddr[0x227];
+	   sr2c = ROMAddr[0x228];
+	}
+     }
+  }
+
+  clkbase = 0x02B;
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-    	tempal += 3;
+    	clkbase += 3;
      }
   }
+
   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
-  pushax = tempal;
   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-  tempal++;
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
-  tempal = pushax;
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-  tempal++;
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
-  tempal = pushax;
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-  tempal++;
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-  return;
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
 }
 
-#if 0  /* TW: Not used */
+#if 0  /* Not used */
 void
 SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr)
 {
@@ -8880,7 +9007,7 @@
 }
 #endif
 
-/* TW: Start of Chrontel 70xx functions ---------------------- */
+/* Start of Chrontel 70xx functions ---------------------- */
 
 /* Set-up the Chrontel Registers */
 void
@@ -8926,44 +9053,44 @@
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
 
 #ifdef SIS300
-  
-     /* Chrontel 7005 - I assume that it does not come with a 310/325 series chip */
 
-     /* TW: We don't support modes >800x600 */
+     /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
+
+     /* We don't support modes >800x600 */
      if (resindex > 5) return;
 
      if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-    	SiS_SetCH700x(SiS_Pr,0x4304);   /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
-    	SiS_SetCH700x(SiS_Pr,0x6909);	/* TW: Black level for PAL (105)*/
+    	SiS_SetCH700x(SiS_Pr,0x4304);   /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
+    	SiS_SetCH700x(SiS_Pr,0x6909);	/* Black level for PAL (105)*/
      } else {
-    	SiS_SetCH700x(SiS_Pr,0x0304);   /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
-    	SiS_SetCH700x(SiS_Pr,0x7109);	/* TW: Black level for NTSC (113)*/
+    	SiS_SetCH700x(SiS_Pr,0x0304);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
+    	SiS_SetCH700x(SiS_Pr,0x7109);	/* Black level for NTSC (113)*/
      }
 
      temp = CHTVRegData[resindex].Reg[0];
-     tempbx=((temp&0x00FF)<<8)|0x00;	/* TW: Mode register */
+     tempbx=((temp&0x00FF)<<8)|0x00;	/* Mode register */
      SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[1];
-     tempbx=((temp&0x00FF)<<8)|0x07;	/* TW: Start active video register */
+     tempbx=((temp&0x00FF)<<8)|0x07;	/* Start active video register */
      SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[2];
-     tempbx=((temp&0x00FF)<<8)|0x08;	/* TW: Position overflow register */
+     tempbx=((temp&0x00FF)<<8)|0x08;	/* Position overflow register */
      SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[3];
-     tempbx=((temp&0x00FF)<<8)|0x0A;	/* TW: Horiz Position register */
+     tempbx=((temp&0x00FF)<<8)|0x0A;	/* Horiz Position register */
      SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[4];
-     tempbx=((temp&0x00FF)<<8)|0x0B;	/* TW: Vertical Position register */
+     tempbx=((temp&0x00FF)<<8)|0x0B;	/* Vertical Position register */
      SiS_SetCH700x(SiS_Pr,tempbx);
 
-     /* TW: Set minimum flicker filter for Luma channel (SR1-0=00),
+     /* Set minimum flicker filter for Luma channel (SR1-0=00),
                 minimum text enhancement (S3-2=10),
    	        maximum flicker filter for Chroma channel (S5-4=10)
 	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
       */
      SiS_SetCH700x(SiS_Pr,0x2801);
 
-     /* TW: Set video bandwidth
+     /* Set video bandwidth
             High bandwith Luma composite video filter(S0=1)
             low bandwith Luma S-video filter (S2-1=00)
 	    disable peak filter in S-video channel (S3=0)
@@ -8972,22 +9099,24 @@
      */
      SiS_SetCH700x(SiS_Pr,0xb103);       /* old: 3103 */
 
-     /* TW: Register 0x3D does not exist in non-macrovision register map
+     /* Register 0x3D does not exist in non-macrovision register map
             (Maybe this is a macrovision register?)
       */
-     /* SiS_SetCH70xx(SiS_Pr,0x003D); */
+#ifndef SIS_CP
+     SiS_SetCH70xx(SiS_Pr,0x003D);
+#endif     
 
-     /* TW: Register 0x10 only contains 1 writable bit (S0) for sensing,
+     /* Register 0x10 only contains 1 writable bit (S0) for sensing,
             all other bits a read-only. Macrovision?
       */
      SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
 
-     /* TW: Register 0x11 only contains 3 writable bits (S0-S2) for
+     /* Register 0x11 only contains 3 writable bits (S0-S2) for
             contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
       */
      SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
 
-     /* TW: Clear DSEN
+     /* Clear DSEN
       */
      SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
 
@@ -9030,7 +9159,7 @@
          }
        }
      } else {				/* ---- PAL ---- */
-           /* TW: We don't play around with FSCI in PAL mode */
+           /* We don't play around with FSCI in PAL mode */
          if (resindex == 0x04) {
            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	/* loop filter off */
            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
@@ -9048,7 +9177,7 @@
 
 #ifdef SIS315H
 
-     /* TW: We don't support modes >1024x768 */
+     /* We don't support modes >1024x768 */
      if (resindex > 6) return;
 
      temp = CHTVRegData[resindex].Reg[0];
@@ -9118,26 +9247,29 @@
 #endif	/* 315 */
 
   }
+
+#ifdef SIS_CP
+  SIS_CP_INIT301_CP3
+#endif
+
 }
 
-/* TW: Chrontel 701x functions ================================= */
+/* Chrontel 701x functions ================================= */
 
 void
-SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr)
+SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-#ifndef NEWCH701x
   USHORT temp;
-#endif  
 
-  /* TW: Enable Chrontel 7019 LCD panel backlight */
+  /* Enable Chrontel 7019 LCD panel backlight */
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-#ifdef NEWCH701x
+     if(HwDeviceExtension->jChipType == SIS_740) {
         SiS_SetCH701x(SiS_Pr,0x6566);
-#else  
+     } else {
         temp = SiS_GetCH701x(SiS_Pr,0x66);
         temp |= 0x20;
 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
-#endif	
+     }
   }
 }
 
@@ -9146,7 +9278,7 @@
 {
   USHORT temp;
 
-  /* TW: Disable Chrontel 7019 LCD panel backlight */
+  /* Disable Chrontel 7019 LCD panel backlight */
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
         temp = SiS_GetCH701x(SiS_Pr,0x66);
         temp &= 0xDF;
@@ -9154,47 +9286,54 @@
   }
 }
 
-#ifdef SIS315H  /* -------- 310/325 series only --------- */
+#ifdef SIS315H  /* ----------- 315 series only ---------- */
 
 void
 SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
 {
-#ifdef NEWCH701x  
-  UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
-                        0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
-  UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
-                        0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 }; 
-  UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
-   			0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; 			
-  UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,         
-                        0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; 
-  UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
-  			0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
-#else
-  UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
-                        0x72, 0x73, 0x74, 0x76, 0x78, 0x7d };
-  UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
-                        0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 }; 
-  UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
-   			0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 }; 			
-  UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,   
-                        0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 }; 
-  UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
-  			0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
-#endif			
+  UCHAR regtable[]      = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
+                            0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
+  UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+                            0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
+  UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+   			    0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
+  UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+                            0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
+  UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+  			    0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
+  UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+                            0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
+  UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+   		   	    0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
+  UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
+                            0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
+  UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+  			    0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
   UCHAR *tableptr = NULL;
   USHORT tempbh;
   int i;
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-     tableptr = table1024;
-  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-     tableptr = table1280;
-  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-     tableptr = table1400;
-  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-     tableptr = table1600;
-  } else return;
+  if(HwDeviceExtension->jChipType == SIS_740) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        tableptr = table1024_740;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+        tableptr = table1280_740;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+        tableptr = table1400_740;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+        tableptr = table1600_740;
+     } else return;
+  } else {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        tableptr = table1024_650;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+        tableptr = table1280_650;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+        tableptr = table1400_650;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+        tableptr = table1600_650;
+     } else return;
+  }
 
   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
@@ -9208,54 +9347,64 @@
         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
      }
   }
-#ifdef NEWCH701x     /* New from 740/LVDS: */    
-  for(i=0; i<0x0d; i++) {	
-#else
-  for(i=0; i<0x0c; i++) {
-#endif  
+
+  if(HwDeviceExtension->jChipType == SIS_740) {
+     tempbh = 0x0d;
+  } else {
+     tempbh = 0x0c;
+  }
+  for(i = 0; i < tempbh; i++) {
      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
   }
-  SiS_ChrontelPowerSequencing(SiS_Pr);
+  SiS_ChrontelPowerSequencing(SiS_Pr,HwDeviceExtension);
   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
   tempbh |= 0xc0;
   SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
-  
-#ifdef NEWCH701x     /* 740/LVDS: */
-  tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
-  tempbh &= 0xfb;
-  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port, 0x2d, 0x03);
-  tempbh = SiS_GetCH701x(SiS_Pr,0x64);
-  tempbh |= 0x40;
-  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
-  tempbh = SiS_GetCH701x(SiS_Pr,0x03);
-  tempbh &= 0x3f;
-  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
-#endif  /* End 740/LVDS */
+
+  if(HwDeviceExtension->jChipType == SIS_740) {
+     tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
+     tempbh &= 0xfb;
+     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
+     tempbh = SiS_GetCH701x(SiS_Pr,0x64);
+     tempbh |= 0x40;
+     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
+     tempbh = SiS_GetCH701x(SiS_Pr,0x03);
+     tempbh &= 0x3f;
+     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
+  }
 }
 
 void
-SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr)
-{
-  UCHAR regtable[]  = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
-#ifdef NEWCH701x  
-  UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
-  UCHAR table1400[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
-#else
-  UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
-  UCHAR table1400[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
-#endif  
+SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  UCHAR regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
+  UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
+  UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
+  UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+  UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
   UCHAR *tableptr = NULL;
   int i;
 
   /* Set up Power up/down timing */
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-     tableptr = table1024;
-  } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-	    (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
-     tableptr = table1400;
-  } else return;
+
+  if(HwDeviceExtension->jChipType == SIS_740) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        tableptr = table1024_740;
+     } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+	       (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+        tableptr = table1400_740;
+     } else return;
+  } else {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        tableptr = table1024_650;
+     } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+	       (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+        tableptr = table1400_650;
+     } else return;
+  }
   
   for(i=0; i<5; i++) {
      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
@@ -9268,66 +9417,72 @@
   USHORT temp;
 
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-#ifdef NEWCH701x
-     temp = SiS_GetCH701x(SiS_Pr,0x1c);
-     temp |= 0x04;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
-#endif 
+     if(HwDeviceExtension->jChipType == SIS_740) {
+        temp = SiS_GetCH701x(SiS_Pr,0x1c);
+        temp |= 0x04;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+     }
      if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
         temp = SiS_GetCH701x(SiS_Pr,0x01);
 	temp &= 0x3f;
-	temp |= 0x80;	/* TW: Enable YPrPb (HDTV) */
+	temp |= 0x80;	/* Enable YPrPb (HDTV) */
 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
      }
      if(SiS_IsChScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
         temp = SiS_GetCH701x(SiS_Pr,0x01);
 	temp &= 0x3f;
-	temp |= 0xc0;	/* TW: Enable SCART + CVBS */
+	temp |= 0xc0;	/* Enable SCART + CVBS */
 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
      }
-#ifdef NEWCH701x
-     SiS_ChrontelDoSomething5(SiS_Pr);
-     SiS_SetCH701x(SiS_Pr,0x2049);   			/* TW: Enable TV path */
-#else      
-     SiS_SetCH701x(SiS_Pr,0x2049);   			/* TW: Enable TV path */
-     temp = SiS_GetCH701x(SiS_Pr,0x49);
-     if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-        temp = SiS_GetCH701x(SiS_Pr,0x73);
-	temp |= 0x60;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
+     if(HwDeviceExtension->jChipType == SIS_740) {
+        SiS_ChrontelDoSomething5(SiS_Pr);
+        SiS_SetCH701x(SiS_Pr,0x2049);   			/* Enable TV path */
+     } else {
+        SiS_SetCH701x(SiS_Pr,0x2049);   			/* Enable TV path */
+        temp = SiS_GetCH701x(SiS_Pr,0x49);
+        if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+           temp = SiS_GetCH701x(SiS_Pr,0x73);
+	   temp |= 0x60;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
+        }
+        temp = SiS_GetCH701x(SiS_Pr,0x47);
+        temp &= 0x7f;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+        SiS_LongDelay(SiS_Pr,2);
+        temp = SiS_GetCH701x(SiS_Pr,0x47);
+        temp |= 0x80;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
      }
-     temp = SiS_GetCH701x(SiS_Pr,0x47);
-     temp &= 0x7f;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-     SiS_LongDelay(SiS_Pr,2);
-     temp = SiS_GetCH701x(SiS_Pr,0x47);
-     temp |= 0x80;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-#endif     
   }
 }
 
 void
-SiS_Chrontel701xOff(SiS_Private *SiS_Pr)
+SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT temp;
 
+  /* Complete power down of LVDS */
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+     if(HwDeviceExtension->jChipType == SIS_740) {
+        SiS_LongDelay(SiS_Pr,1);
+	SiS_GenericDelay(SiS_Pr,0x16ff);
+	SiS_SetCH701x(SiS_Pr,0xac76);
+	SiS_SetCH701x(SiS_Pr,0x0066);
+     } else {
         SiS_LongDelay(SiS_Pr,2);
-	/* TW: Complete power down of LVDS */
 	temp = SiS_GetCH701x(SiS_Pr,0x76);
 	temp &= 0xfc;
 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
 	SiS_SetCH701x(SiS_Pr,0x0066);
+     }
   }
 }
 
-#ifdef NEWCH701x
 void
 SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr)
 {
      unsigned char temp, temp1;
-     
+
      temp1 = SiS_GetCH701x(SiS_Pr,0x49);
      SiS_SetCH701x(SiS_Pr,0x3e49);
      temp = SiS_GetCH701x(SiS_Pr,0x47);
@@ -9339,130 +9494,134 @@
      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
      SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
 }
-#endif
 
 void
 SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
-#ifdef NEWCH701x
      USHORT temp;
-     
-     /* 740/LVDS: */
-     temp = SiS_GetCH701x(SiS_Pr,0x4a);
-     temp &= 0x01;
-     if(!(temp)) {
-     
-        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	   temp = SiS_GetCH701x(SiS_Pr,0x49);
-	   SiS_SetCH701x(SiS_Pr,0x3e49);
-	}
-	/* TW: Reset Chrontel 7019 datapath */
+
+     if(HwDeviceExtension->jChipType == SIS_740) {
+        temp = SiS_GetCH701x(SiS_Pr,0x4a);
+        temp &= 0x01;
+        if(!(temp)) {
+
+           if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	      temp = SiS_GetCH701x(SiS_Pr,0x49);
+	      SiS_SetCH701x(SiS_Pr,0x3e49);
+	   }
+	   /* Reset Chrontel 7019 datapath */
+           SiS_SetCH701x(SiS_Pr,0x1048);
+           SiS_LongDelay(SiS_Pr,1);
+           SiS_SetCH701x(SiS_Pr,0x1848);
+
+	   if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	      SiS_ChrontelDoSomething5(SiS_Pr);
+	      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
+	   }
+
+        } else {
+
+           temp = SiS_GetCH701x(SiS_Pr,0x5c);
+	   temp &= 0xef;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
+	   temp |= 0x10;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
+	   temp &= 0xef;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+	   temp = SiS_GetCH701x(SiS_Pr,0x61);
+	   if(!temp) {
+	      SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+	   }
+        }
+     } else { /* 650 */
+        /* Reset Chrontel 7019 datapath */
         SiS_SetCH701x(SiS_Pr,0x1048);
         SiS_LongDelay(SiS_Pr,1);
         SiS_SetCH701x(SiS_Pr,0x1848);
-	
-	if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	   SiS_ChrontelDoSomething5(SiS_Pr);
-	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
-	}    
-     } else {
-     
-        temp = SiS_GetCH701x(SiS_Pr,0x5c);
-	temp &= 0xef;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
-	temp = SiS_GetCH701x(SiS_Pr,0x5c);
-	temp |= 0x10;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
-	temp = SiS_GetCH701x(SiS_Pr,0x5c);
-	temp &= 0xef;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
-	temp = SiS_GetCH701x(SiS_Pr,0x61);
-	if(!temp) {
-	   SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
-	}
-     }
-#else /* pre 740/LVDS code */     
-     /* TW: Reset Chrontel 7019 datapath */
-     SiS_SetCH701x(SiS_Pr,0x1048);
-     SiS_LongDelay(SiS_Pr,1);
-     SiS_SetCH701x(SiS_Pr,0x1848);
-#endif     
+     }
 }
 
 void
 SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
-#ifdef NEWCH701x
-     if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-        SiS_ChrontelDoSomething5(SiS_Pr);
-     }
-#else
      USHORT temp;
 
-     SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
-     temp = SiS_GetCH701x(SiS_Pr,0x49);
-     temp &= 1;
-     if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
-	temp = SiS_GetCH701x(SiS_Pr,0x47);
-	temp &= 0x70;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
-	SiS_LongDelay(SiS_Pr,3);
-	temp = SiS_GetCH701x(SiS_Pr,0x47);
-	temp |= 0x80;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
+     if(HwDeviceExtension->jChipType == SIS_740) {
+
+        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+           SiS_ChrontelDoSomething5(SiS_Pr);
+        }
+
+     } else {
+
+        SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
+        temp = SiS_GetCH701x(SiS_Pr,0x49);
+        temp &= 1;
+        if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
+	   temp = SiS_GetCH701x(SiS_Pr,0x47);
+	   temp &= 0x70;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
+	   SiS_LongDelay(SiS_Pr,3);
+	   temp = SiS_GetCH701x(SiS_Pr,0x47);
+	   temp |= 0x80;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
+        }
+
      }
-#endif     
 }
 
 void
 SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension,
                          USHORT BaseAddr)
 {
-#ifdef NEWCH701x
-     USHORT temp;
-     
-     temp = SiS_GetCH701x(SiS_Pr,0x61);
-     if(temp < 1) {
-          temp++;
-	  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
-     }
-     SiS_SetCH701x(SiS_Pr,0x4566);
-     SiS_SetCH701x(SiS_Pr,0xaf76);
-     SiS_LongDelay(SiS_Pr,1);
-     SiS_GenericDelay(SiS_Pr,0x16ff);
-
-#else
      USHORT temp,temp1;
-     
-     temp1 = 0;
-     temp = SiS_GetCH701x(SiS_Pr,0x61);
-     if(temp < 2) {
-          temp++;
-	  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
-	  temp1 = 1;
-     }
-     SiS_SetCH701x(SiS_Pr,0xac76);
-     temp = SiS_GetCH701x(SiS_Pr,0x66);
-     temp |= 0x5f;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
-     if(ModeNo > 0x13) {
-         if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	    SiS_GenericDelay(SiS_Pr,0x3ff);
-	 } else {
-	    SiS_GenericDelay(SiS_Pr,0x2ff);
-	 }
-     } else {
-         if(!temp1)
-	    SiS_GenericDelay(SiS_Pr,0x2ff);
+
+     if(HwDeviceExtension->jChipType == SIS_740) {
+
+        temp = SiS_GetCH701x(SiS_Pr,0x61);
+        if(temp < 1) {
+           temp++;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+        }
+        SiS_SetCH701x(SiS_Pr,0x4566);
+        SiS_SetCH701x(SiS_Pr,0xaf76);
+        SiS_LongDelay(SiS_Pr,1);
+        SiS_GenericDelay(SiS_Pr,0x16ff);
+
+     } else {  /* 650 */
+
+        temp1 = 0;
+        temp = SiS_GetCH701x(SiS_Pr,0x61);
+        if(temp < 2) {
+           temp++;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+	   temp1 = 1;
+        }
+        SiS_SetCH701x(SiS_Pr,0xac76);
+        temp = SiS_GetCH701x(SiS_Pr,0x66);
+        temp |= 0x5f;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+        if(ModeNo > 0x13) {
+           if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	      SiS_GenericDelay(SiS_Pr,0x3ff);
+	   } else {
+	      SiS_GenericDelay(SiS_Pr,0x2ff);
+	   }
+        } else {
+           if(!temp1)
+	      SiS_GenericDelay(SiS_Pr,0x2ff);
+        }
+        temp = SiS_GetCH701x(SiS_Pr,0x76);
+        temp |= 0x03;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+        temp = SiS_GetCH701x(SiS_Pr,0x66);
+        temp &= 0x7f;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+        SiS_LongDelay(SiS_Pr,1);
+
      }
-     temp = SiS_GetCH701x(SiS_Pr,0x76);
-     temp |= 0x03;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
-     temp = SiS_GetCH701x(SiS_Pr,0x66);
-     temp &= 0x7f;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
-     SiS_LongDelay(SiS_Pr,1);
-#endif     
 }
 
 void
@@ -9479,9 +9638,9 @@
        temp &= 0x04;
        if(temp == 0x04) break;
        
-#ifdef NEWCH701x
-       SiS_SetCH701x(SiS_Pr,0xac76);    /* 740/LVDS */
-#endif       
+       if(HwDeviceExtension->jChipType == SIS_740) {
+          SiS_SetCH701x(SiS_Pr,0xac76);
+       }
 
        SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
 
@@ -9499,11 +9658,11 @@
        temp = SiS_GetCH701x(SiS_Pr,0x76);
        temp |= 0x04;
        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
-#ifdef NEWCH701x
-       SiS_SetCH701x(SiS_Pr,0xe078);
-#else       
-       SiS_SetCH701x(SiS_Pr,0x6078);
-#endif       
+       if(HwDeviceExtension->jChipType == SIS_740) {
+          SiS_SetCH701x(SiS_Pr,0xe078);
+       } else {
+          SiS_SetCH701x(SiS_Pr,0x6078);
+       }
        SiS_LongDelay(SiS_Pr,2);
     } while(0);
 
@@ -9521,51 +9680,52 @@
      temp &= 0xbf;	/* Set datapath 2 to LVDS */
      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
      
-#ifdef NEWCH701x   /* 740/LVDS: */
+     if(HwDeviceExtension->jChipType == SIS_740) {
+
+        temp = SiS_GetCH701x(SiS_Pr,0x1c);
+        temp &= 0xfb;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
+
+        temp = SiS_GetCH701x(SiS_Pr,0x64);
+        temp |= 0x40;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
+
+        temp = SiS_GetCH701x(SiS_Pr,0x03);
+        temp &= 0x3f;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+
+        temp = SiS_GetCH701x(SiS_Pr,0x66);
+        if(temp != 0x45) {
+           SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
+           SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
+	   temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+           SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
+        }
+
+     } else { /* 650 */
 
-     temp = SiS_GetCH701x(SiS_Pr,0x1c);
-     temp &= 0xfb;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
-     
-     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
-     
-     temp = SiS_GetCH701x(SiS_Pr,0x64);
-     temp |= 0x40;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
-     
-     temp = SiS_GetCH701x(SiS_Pr,0x03);
-     temp &= 0x3f;	
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
-     
-     temp = SiS_GetCH701x(SiS_Pr,0x66);
-     if(temp != 0x45) {
         SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
-        SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
-	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
-        SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
-     }     
 
-#else  /* pre-740/LVDS: */     
+        SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
 
-     SiS_ChrontelResetDB(SiS_Pr);
+        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+        SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
 
-     SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
+        SiS_SetCH701x(SiS_Pr,0xaf76);
 
-     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
-     SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
+     }
 
-     SiS_SetCH701x(SiS_Pr,0xaf76);
-     
-#endif  /* End of pre-740/LVDS */
 }
 
-#endif  /* 310/325 series --------------------------------- */
+#endif  /* 315 series ------------------------------------ */
 
-/* TW: End of Chrontel 701x functions ==================================== */
+/* End of Chrontel 701x functions ==================================== */
 
-/* TW: Generic Read/write routines for Chrontel ========================== */
+/* Generic Read/write routines for Chrontel ========================== */
 
-/* TW: The Chrontel is connected to the 630/730 via
+/* The Chrontel is connected to the 630/730 via
  * the 630/730's DDC/I2C port.
  *
  * On 630(S)T chipset, the index changed from 0x11 to 0x0a,
@@ -9575,13 +9735,13 @@
 void
 SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
       SiS_SetCH700x(SiS_Pr,tempbx);
    else
       SiS_SetCH701x(SiS_Pr,tempbx);
 }
 
-/* TW: Write to Chrontel 700x */
+/* Write to Chrontel 700x */
 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
 void
 SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
@@ -9589,100 +9749,100 @@
   USHORT tempah,temp,i;
 
   if(!(SiS_Pr->SiS_ChrontelInit)) {
-     SiS_Pr->SiS_DDC_Index = 0x11;		   /* TW: Bit 0 = SC;  Bit 1 = SD */
+     SiS_Pr->SiS_DDC_Index = 0x11;		   /* Bit 0 = SC;  Bit 1 = SD */
      SiS_Pr->SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
      SiS_Pr->SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
      SiS_Pr->SiS_DDC_DataShift = 0x00;
-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	   /* TW: DAB (Device Address Byte) */
+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	   /* DAB (Device Address Byte) */
   }
 
-  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
+  for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
     /* SiS_SetSwitchDDC2(SiS_Pr); */
-    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
+    if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
-    tempah = tempbx & 0x00FF;			/* TW: Write RAB */
-    tempah |= 0x80;                             /* TW: (set bit 7, see datasheet) */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
+    if(temp) continue;				/*    (ERROR: no ack) */
+    tempah = tempbx & 0x00FF;			/* Write RAB */
+    tempah |= 0x80;                             /* (set bit 7, see datasheet) */
     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
+    if(temp) continue;				/*    (ERROR: no ack) */
     tempah = (tempbx & 0xFF00) >> 8;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
-    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write data */
+    if(temp) continue;				/*    (ERROR: no ack) */
+    if(SiS_SetStop(SiS_Pr)) continue;		/* Set stop condition */
     SiS_Pr->SiS_ChrontelInit = 1;
     return;
   }
 
-  /* TW: For 630ST */
+  /* For 630ST */
   if(!(SiS_Pr->SiS_ChrontelInit)) {
-     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 7 = SC;  Bit 6 = SD */
+     SiS_Pr->SiS_DDC_Index = 0x0a;		/* Bit 7 = SC;  Bit 6 = SD */
      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
      SiS_Pr->SiS_DDC_DataShift = 0x00;
-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* DAB (Device Address Byte) */
 
-     for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
+     for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
        /* SiS_SetSwitchDDC2(SiS_Pr); */
-       if (SiS_SetStart(SiS_Pr)) continue;	/* TW: Set start condition */
+       if (SiS_SetStart(SiS_Pr)) continue;	/* Set start condition */
        tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
-       if(temp) continue;			/* TW:    (ERROR: no ack) */
-       tempah = tempbx & 0x00FF;		/* TW: Write RAB */
-       tempah |= 0x80;                          /* TW: (set bit 7, see datasheet) */
+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
+       if(temp) continue;			/*    (ERROR: no ack) */
+       tempah = tempbx & 0x00FF;		/* Write RAB */
+       tempah |= 0x80;                          /* (set bit 7, see datasheet) */
        temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-       if(temp) continue;			/* TW:    (ERROR: no ack) */
+       if(temp) continue;			/*    (ERROR: no ack) */
        tempah = (tempbx & 0xFF00) >> 8;
-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
-       if(temp) continue;			/* TW:    (ERROR: no ack) */
-       if(SiS_SetStop(SiS_Pr)) continue;	/* TW: Set stop condition */
+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write data */
+       if(temp) continue;			/*    (ERROR: no ack) */
+       if(SiS_SetStop(SiS_Pr)) continue;	/* Set stop condition */
        SiS_Pr->SiS_ChrontelInit = 1;
        return;
     }
   }
 }
 
-/* TW: Write to Chrontel 701x */
+/* Write to Chrontel 701x */
 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
 void
 SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   USHORT tempah,temp,i;
 
-  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
+  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
   SiS_Pr->SiS_DDC_DataShift = 0x00;
-  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* TW: DAB (Device Address Byte) */
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
 
-  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
-    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
+  for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
+    if (SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
+    if(temp) continue;				/*    (ERROR: no ack) */
     tempah = tempbx & 0x00FF;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write RAB */
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write RAB */
+    if(temp) continue;				/*    (ERROR: no ack) */
     tempah = (tempbx & 0xFF00) >> 8;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
-    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write data */
+    if(temp) continue;				/*    (ERROR: no ack) */
+    if(SiS_SetStop(SiS_Pr)) continue;		/* Set stop condition */
     return;
   }
 }
 
-/* TW: Read from Chrontel 70xx */
+/* Read from Chrontel 70xx */
 /* Parameter is [Register no (S7-S0)] */
 USHORT
 SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
       return(SiS_GetCH700x(SiS_Pr,tempbx));
    else
       return(SiS_GetCH701x(SiS_Pr,tempbx));
 }
 
-/* TW: Read from Chrontel 700x */
+/* Read from Chrontel 700x */
 /* Parameter is [Register no (S7-S0)] */
 USHORT
 SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
@@ -9690,57 +9850,57 @@
   USHORT tempah,temp,i;
 
   if(!(SiS_Pr->SiS_ChrontelInit)) {
-     SiS_Pr->SiS_DDC_Index = 0x11;		/* TW: Bit 0 = SC;  Bit 1 = SD */
+     SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
      SiS_Pr->SiS_DDC_DataShift = 0x00;
-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
   }
 
   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
 
-  for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
+  for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
     /* SiS_SetSwitchDDC2(SiS_Pr); */
-    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
+    if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
+    if(temp) continue;				/*        (ERROR: no ack) */
+    tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* Write RAB | 0x80 */
     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
+    if(temp) continue;				/*        (ERROR: no ack) */
+    if (SiS_SetStart(SiS_Pr)) continue;		/* Re-start */
     tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
-    if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* DAB (S0=1=read) */
+    if(temp) continue;				/*        (ERROR: no ack) */
+    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* Read byte */
+    if (SiS_SetStop(SiS_Pr)) continue;		/* Stop condition */
     SiS_Pr->SiS_ChrontelInit = 1;
     return(tempah);
   }
 
-  /* TW: For 630ST */
+  /* For 630ST */
   if(!SiS_Pr->SiS_ChrontelInit) {
-     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 0 = SC;  Bit 1 = SD */
+     SiS_Pr->SiS_DDC_Index = 0x0a;		/* Bit 0 = SC;  Bit 1 = SD */
      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
      SiS_Pr->SiS_DDC_DataShift = 0x00;
-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* DAB (Device Address Byte) */
 
-     for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
+     for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
        /* SiS_SetSwitchDDC2(SiS_Pr); */
-       if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
+       if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
        tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: Write DAB (S0=0=write) */
-       if(temp) continue;				/* TW:        (ERROR: no ack) */
-       tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* Write DAB (S0=0=write) */
+       if(temp) continue;				/*        (ERROR: no ack) */
+       tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* Write RAB | 0x80 */
        temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-       if(temp) continue;				/* TW:        (ERROR: no ack) */
-       if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
+       if(temp) continue;				/*        (ERROR: no ack) */
+       if (SiS_SetStart(SiS_Pr)) continue;		/* Re-start */
        tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; 	/* DAB | 0x01 = Read */
-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: DAB (S0=1=read) */
-       if(temp) continue;				/* TW:        (ERROR: no ack) */
-       tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
-       if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* DAB (S0=1=read) */
+       if(temp) continue;				/*        (ERROR: no ack) */
+       tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* Read byte */
+       if (SiS_SetStop(SiS_Pr)) continue;		/* Stop condition */
        SiS_Pr->SiS_ChrontelInit = 1;
        return(tempah);
      }
@@ -9748,52 +9908,51 @@
   return(0xFFFF);
 }
 
-/* TW: Read from Chrontel 701x */
+/* Read from Chrontel 701x */
 /* Parameter is [Register no (S7-S0)] */
 USHORT
 SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   USHORT tempah,temp,i;
 
-  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
+  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
   SiS_Pr->SiS_DDC_DataShift = 0x00;
-  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
 
-   for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
-    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
+   for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
+    if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    tempah = SiS_Pr->SiS_DDC_ReadAddr;		/* TW: Write RAB */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
+    if(temp) continue;				/*        (ERROR: no ack) */
+    tempah = SiS_Pr->SiS_DDC_ReadAddr;		/* Write RAB */
     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
+    if(temp) continue;				/*        (ERROR: no ack) */
+    if (SiS_SetStart(SiS_Pr)) continue;		/* Re-start */
     tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
-    SiS_SetStop(SiS_Pr);			/* TW: Stop condition */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* DAB (S0=1=read) */
+    if(temp) continue;				/*        (ERROR: no ack) */
+    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* Read byte */
+    SiS_SetStop(SiS_Pr);			/* Stop condition */
     return(tempah);
    }
   return 0xFFFF;
 }
 
-#ifdef LINUX_XF86
-/* TW: Our own DDC functions */
+/* Our own DDC functions */
 USHORT
-SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype,
-		BOOLEAN checkcr32)
+SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+                USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
 {
      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
      unsigned char flag, cr32;
      USHORT        temp = 0, myadaptnum = adaptnum;
 
      if(adaptnum != 0) {
-        if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0xFFFF;
-	if((pSiS->VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
+        if(!(VBFlags & (VB_301|VB_301B|VB_302B))) return 0xFFFF;
+	if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
      }	
      
      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
@@ -9807,8 +9966,9 @@
      flag = 0xff;
 
      cr32 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x32);
-  
-     if(pSiS->VBFlags & VB_SISBRIDGE) {
+
+#if 0
+     if(VBFlags & VB_SISBRIDGE) {
 	if(myadaptnum == 0) {
 	   if(!(cr32 & 0x20)) {
 	      myadaptnum = 2;
@@ -9821,18 +9981,19 @@
 	   }
         }
      }
+#endif
 
-     if(pSiS->VGAEngine == SIS_300_VGA) {		/* 300 series */
+     if(VGAEngine == SIS_300_VGA) {		/* 300 series */
 	
         if(myadaptnum != 0) {
 	   flag = 0;
-	   if(pSiS->VBFlags & VB_SISBRIDGE) {
+	   if(VBFlags & VB_SISBRIDGE) {
 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
               SiS_Pr->SiS_DDC_Index = 0x0f;
 	   }
         }
 
-	if(!(pSiS->VBFlags & VB_301)) {
+	if(!(VBFlags & VB_301)) {
 	   if((cr32 & 0x80) && (checkcr32)) {
               if(myadaptnum >= 1) {
 	         if(!(cr32 & 0x08)) {
@@ -9846,11 +10007,11 @@
 	temp = 4 - (myadaptnum * 2);
 	if(flag) temp = 0;
 
-     } else {						/* 310/325/330 series */
+     } else {						/* 315/330 series */
 
      	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
 	
-	if(pSiS->VBFlags & VB_SISBRIDGE) {
+	if(VBFlags & VB_SISBRIDGE) {
 	   if(myadaptnum == 2) {
 	      myadaptnum = 1;
            }
@@ -9858,7 +10019,7 @@
 
         if(myadaptnum == 1) {
      	   flag = 0;
-	   if(pSiS->VBFlags & VB_SISBRIDGE) {
+	   if(VBFlags & VB_SISBRIDGE) {
 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
               SiS_Pr->SiS_DDC_Index = 0x0f;
 	   }
@@ -9876,7 +10037,7 @@
         temp = myadaptnum;
         if(myadaptnum == 1) {
            temp = 0;
-	   if(pSiS->VBFlags & VB_LVDS) flag = 0xff;
+	   if(VBFlags & VB_LVDS) flag = 0xff;
         }
 
 	if(flag) temp = 0;
@@ -9888,7 +10049,7 @@
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
     		SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
-#endif	 
+#endif
     
     return 0;
 }
@@ -9898,15 +10059,9 @@
 {
    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
-#ifdef TWDEBUG
-        xf86DrvMsg(0, X_INFO, "WriteDAB 1 failed\n");
-#endif	 
   	return 0xFFFF;
    }
    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
-#ifdef TWDEBUG
-        xf86DrvMsg(0, X_INFO, "WriteDAB 2 failed\n");
-#endif	 
    	return 0xFFFF;
    }
    return(0);
@@ -9917,9 +10072,6 @@
 {
    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
-#ifdef TWDEBUG
-        xf86DrvMsg(0, X_INFO, "PrepareReadDDC 1 failed\n");
-#endif	 
    	return 0xFFFF;
    }
    return(0);
@@ -9957,9 +10109,6 @@
     SiS_SetSwitchDDC2(SiS_Pr);
     if(SiS_PrepareDDC(SiS_Pr)) {
          SiS_SetStop(SiS_Pr);
-#ifdef TWDEBUG
-	 xf86DrvMsg(0, X_INFO, "DoProbeDDC 1 failed at PrepareDDC\n");
-#endif	 
          return(0xFFFF);
     }
     mask = 0xf0;
@@ -10008,7 +10157,7 @@
 }
 
 USHORT
-SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer)
+SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
 {
    USHORT flag, length, i;
    unsigned char chksum,gotcha;
@@ -10040,28 +10189,7 @@
    return(flag);
 }
 
-USHORT
-SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer)
-{
-   USHORT i=0, flag=0;
-
-   length--;
-   
-   SiS_SetSwitchDDC2(SiS_Pr);
-   if(!(SiS_PrepareDDC(SiS_Pr))) {
-      for(i=0; i<length; i++) {
-         buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
-         SiS_SendACK(SiS_Pr, 0);
-      }
-      buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
-      SiS_SendACK(SiS_Pr, 1);
-   } else flag = 0xFFFF;
-   
-   SiS_SetStop(SiS_Pr);
-   return(0);
-}
-
-/* TW: Our private DDC function
+/* Our private DDC functions
 
    It complies somewhat with the corresponding VESA function
    in arguments and return values.
@@ -10072,7 +10200,7 @@
 
    Arguments:
        adaptnum: 0=CRT1, 1=LCD, 2=VGA2
-                 CRT2 DDC is only supported on SiS301, 301B (non-DH version), 302B.
+                 CRT2 DDC is only supported on SiS301, 301B, 302B.
        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
        buffer: ptr to 256 data bytes which will be filled with read data.
 
@@ -10082,43 +10210,48 @@
 
  */
 USHORT
-SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
-              USHORT DDCdatatype, unsigned char *buffer)
+SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+              USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
 {
    if(adaptnum > 2) return 0xFFFF;
    if(DDCdatatype > 4) return 0xFFFF;
-   if((!(pSiS->VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
+   if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
+   if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
    if(DDCdatatype == 0) {
        return(SiS_ProbeDDC(SiS_Pr));
    } else {
-       return(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer));
+       return(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer));
    }
 }
 
+#ifdef LINUX_XF86
 /* Sense the LCD parameters (CR36, CR37) via DDC */
 /* SiS30x(B) only */
 USHORT
 SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
 {
-   USHORT DDCdatatype, paneltype, flag, xres, yres;
+   USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
    USHORT index, myindex, lumsize, numcodes;
    unsigned char cr37=0, seekcode;
    BOOLEAN checkexpand = FALSE;
    int retry, i;
    unsigned char buffer[256];
-   
+
+   for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
+   SiS_Pr->CP_HaveCustomData = FALSE;
+   SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
+
    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
    if(pSiS->VBFlags & VB_30xBDH) return 0;
   
-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0;
+   if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
    
    SiS_Pr->SiS_DDC_SecAddr = 0x00;
    
    /* Probe supported DA's */
    flag = SiS_ProbeDDC(SiS_Pr);
 #ifdef TWDEBUG   
-   xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
+   xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
    	"CRT2 DDC capabilities 0x%x\n", flag);
 #endif	
    if(flag & 0x10) {
@@ -10135,7 +10268,7 @@
    /* Read the entire EDID */
    retry = 2;
    do {
-      if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
+      if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
 	 	"CRT2: DDC read failed (attempt %d), %s\n", 
 		(3-retry), (retry == 1) ? "giving up" : "retrying");
@@ -10168,7 +10301,7 @@
       }
       
       if((buffer[0x18] & 0x18) != 0x08) {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, 
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
 	 	"CRT2: Attached display is not of RGB but of %s type (0x%02x)\n", 
 		((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
 		  ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" : 
@@ -10176,104 +10309,226 @@
 		buffer[0x18]);
 	 return 0;
       }
-      
-      /* Now analyze the first Detailed Timing Block and hope
-       * that the preferred timing mode is stored there.
-       */	
-      xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
-      yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
+
+      /* Now analyze the first Detailed Timing Block and see
+       * if the preferred timing mode is stored there. If so,
+       * check if this is a standard panel for which we already
+       * know the timing.
+       */
+
+      paneltype = Panel_Custom;
       checkexpand = FALSE;
-      switch(xres) {
-         case 800:
-	     if(yres == 600) {
-	     	paneltype = Panel310_800x600;
-	     	checkexpand = TRUE;
-	     }
-	     break;
-         case 1024:
-	     if(yres == 768) {
-	     	paneltype = Panel310_1024x768;
-	     	checkexpand = FALSE;    /* expand causes error at 640x480, should otherwise be TRUE; */
-	     }
-	     break;
-	 case 1280:
-	     if(yres == 960) {
-	        if(pSiS->VGAEngine == SIS_300_VGA) {
-		   paneltype = Panel300_1280x960;
-		} else {
-		   paneltype = Panel310_1280x960; 
-		}
-	     } else if(yres == 1024) {
-	     	paneltype = Panel310_1280x1024;  
-		checkexpand = TRUE;
-	     } else if(pSiS->VGAEngine == SIS_315_VGA) {
+
+      if(buffer[0x18] & 0x02) {
+
+         xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
+         yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
+
+	 SiS_Pr->CP_PreferredX = xres;
+	 SiS_Pr->CP_PreferredY = yres;
+
+         switch(xres) {
+            case 800:
+	        if(yres == 600) {
+	     	   paneltype = Panel_800x600;
+	     	   checkexpand = TRUE;
+	        }
+	        break;
+            case 1024:
 	        if(yres == 768) {
-	       	   paneltype = Panel310_1280x768;
+	     	   paneltype = Panel_1024x768;
+	     	   checkexpand = TRUE;
+	        }
+	        break;
+	    case 1280:
+	        if(yres == 1024) {
+	     	   paneltype = Panel_1280x1024;
+		   checkexpand = TRUE;
+	        } else if(yres == 960) {
+	           if(pSiS->VGAEngine == SIS_300_VGA) {
+		      paneltype = Panel300_1280x960;
+		   } else {
+		      paneltype = Panel310_1280x960;
+		   }
+	        } else if(yres == 768) {
+	       	   paneltype = Panel_1280x768;
 		   checkexpand = FALSE;
 		   cr37 |= 0x10;
 	        }
-	     }
-	     break;
-	 case 1400:
-	     if(pSiS->VGAEngine == SIS_315_VGA) {
-	        if(yres == 1050) {
-	           paneltype = Panel310_1400x1050;
-		   checkexpand = TRUE; 
-	        } 
-	     }
-      	     break;
-	 case 1600:
-	     if(pSiS->VGAEngine == SIS_315_VGA) {
-	        if(yres == 1200) {
-	           paneltype = Panel310_1600x1200;
-		   checkexpand = TRUE;
-	        } 
-	     }
-      	     break;
+	        break;
+	    case 1400:
+	        if(pSiS->VGAEngine == SIS_315_VGA) {
+	           if(yres == 1050) {
+	              paneltype = Panel310_1400x1050;
+		      checkexpand = TRUE;
+	           }
+	        }
+      	        break;
+#if 0	    /* Treat this as custom, as we have no valid timing data yet */
+	    case 1600:
+	        if(pSiS->VGAEngine == SIS_315_VGA) {
+	           if(yres == 1200) {
+	              paneltype = Panel310_1600x1200;
+		      checkexpand = TRUE;
+	           }
+	        }
+      	        break;
+#endif
+         }
+
+	 if(paneltype != Panel_Custom) {
+	    if((buffer[0x47] & 0x18) == 0x18) {
+	       cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
+	    } else {
+	       /* What now? There is no digital separate output timing... */
+	       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+	       	   "CRT2: Unable to retrieve Sync polarity information\n");
+	    }
+	 }
+
       }
 
-      if(buffer[0x18] & 0x02) {
-         /* If the preferred timing mode is stored in the first
-	  * detailed timing block, we now can extract the sync
-	  * polarisation information as well. This only works
-	  * if the Flags indicate a digital separate output.
-	  */
-	  if((buffer[0x47] & 0x18) == 0x18) {
-	     cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
-	  } else {
-	     /* What now? There is no digital separate output timing... */
-	     xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
-	     	"CRT2: Unable to retrieve Sync polarity information\n");
-	  }
-	  
-      } else {
-         /* If the preferred timing mode is *not* stored in the first
-	  * detailed timing block, we need to guess the resolution
-	  * from the supported Established Timings and assume the
-	  * default sync polarity
-	  */
+      /* If we still don't know what panel this is, we take it
+       * as a custom panel and derive the timing data from the
+       * detailed timing blocks
+       */
+      if(paneltype == Panel_Custom) {
+
+         BOOLEAN havesync = FALSE;
+	 int i, temp, base = 0x36;
+	 unsigned long estpack;
+	 unsigned short estx[] = {
+	 	720, 720, 640, 640, 640, 640, 800, 800,
+		800, 800, 832,1024,1024,1024,1024,1280,
+		1152
+	 };
+	 unsigned short esty[] = {
+	 	400, 400, 480, 480, 480, 480, 600, 600,
+		600, 600, 624, 768, 768, 768, 768,1024,
+		870
+	 };
+
 	 paneltype = 0;
-	 if(buffer[0x24] & 0x01) { 	
-	 	paneltype = Panel310_1280x1024;
-		checkexpand = TRUE;
-		cr37 |= 0x20;
-	 } else if(buffer[0x24] & 0x0e) {
-	 	paneltype = Panel310_1024x768;
-		cr37 |= 0xe0;
-		checkexpand = FALSE;		/* Bug at 640x480 */
-	 } else if(buffer[0x23] & 0x01) {
-	 	paneltype = Panel310_800x600;
-		cr37 |= 0xe0;
-		checkexpand = TRUE;
-         }
+
+	 /* Find the maximum resolution */
+
+	 /* 1. From Established timings */
+	 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
+	 for(i=16; i>=0; i--) {
+	     if(estpack & (1 << i)) {
+	        if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
+		if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
+	     }
+	 }
+
+	 /* 2. From Standard Timings */
+	 for(i=0x26; i < 0x36; i+=2) {
+	    if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
+	       temp = (buffer[i] + 31) * 8;
+	       if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
+	       switch((buffer[i+1] & 0xc0) >> 6) {
+	       case 0x03: temp = temp * 9 / 16; break;
+	       case 0x02: temp = temp * 4 / 5;  break;
+	       case 0x01: temp = temp * 3 / 4;  break;
+	       }
+	       if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
+	    }
+	 }
+
+	 /* Now extract the Detailed Timings and convert them into modes */
+
+         for(i = 0; i < 4; i++, base += 18) {
+
+	    /* Is this a detailed timing block or a monitor descriptor? */
+	    if(buffer[base] || buffer[base+1] || buffer[base+2]) {
+
+      	       xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
+               yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
+
+	       SiS_Pr->CP_HDisplay[i] = xres;
+	       SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
+               SiS_Pr->CP_HSyncEnd[i]   = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
+	       SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
+	       SiS_Pr->CP_HBlankStart[i] = xres + 1;
+	       SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
+
+	       SiS_Pr->CP_VDisplay[i] = yres;
+               SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
+               SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
+	       SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
+	       SiS_Pr->CP_VBlankStart[i] = yres + 1;
+	       SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
+
+	       SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
+
+	       SiS_Pr->CP_DataValid[i] = TRUE;
+
+	       /* Sort out invalid timings, interlace and too high clocks */
+	       if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  ||
+	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   ||
+	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     ||
+	          (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
+	          (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    ||
+	          (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      ||
+	          (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  ||
+	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   ||
+	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     ||
+	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  ||
+	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    ||
+	          (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      ||
+	          (SiS_Pr->CP_Clock[i] > 108000)                       ||
+		  (buffer[base+17] & 0x80)) {
+
+	          SiS_Pr->CP_DataValid[i] = FALSE;
+
+	       } else {
+
+	          paneltype = Panel_Custom;
+
+		  SiS_Pr->CP_HaveCustomData = TRUE;
+
+		  if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
+	          if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
+		  if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
+
+		  SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
+		  SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
+
+	          /* We must assume the panel can scale, since we have
+	           * no scaling data
+		   */
+	          checkexpand = FALSE;
+	          cr37 |= 0x10;
+
+	          /* Extract the sync polarisation information. This only works
+	           * if the Flags indicate a digital separate output.
+	           */
+	          if((buffer[base+17] & 0x18) == 0x18) {
+		     SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
+		     SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
+		     SiS_Pr->CP_SyncValid[i] = TRUE;
+		     if(!havesync) {
+	                cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
+			havesync = TRUE;
+	   	     }
+	          } else {
+		     SiS_Pr->CP_SyncValid[i] = FALSE;
+		  }
+	       }
+            }
+	 }
+	 if(!havesync) {
+	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+	       	   "CRT2: Unable to retrieve Sync polarity information\n");
+   	 }
       }
-      
-      if(checkexpand) {
-         /* If any of the Established low-res modes is supported, the 
+
+      if(paneltype && checkexpand) {
+         /* If any of the Established low-res modes is supported, the
 	  * panel can scale automatically. For 800x600 panels, we only 
 	  * check the even lower ones.
 	  */
-	 if(paneltype == Panel310_800x600) {
+	 if(paneltype == Panel_800x600) {
 	    if(buffer[0x23] & 0xfc) cr37 |= 0x10;
 	 } else {
             if(buffer[0x23])	    cr37 |= 0x10;
@@ -10299,20 +10554,31 @@
 		buffer[0x41]);
 	 return 0;
       }
-   
-      xres = buffer[0x76] | (buffer[0x77] << 8);
-      yres = buffer[0x78] | (buffer[0x79] << 8);
+
+      paneltype = Panel_Custom;
+      SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
+      SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
       switch(xres) {
          case 800:
 	     if(yres == 600) {
-	     	paneltype = Panel310_800x600;
+	     	paneltype = Panel_800x600;
 	     	checkexpand = TRUE;
 	     }
 	     break;
          case 1024:
 	     if(yres == 768) {
-	     	paneltype = Panel310_1024x768;
-	     	checkexpand = FALSE;			/* Bug at 640x480; we do the scaling ourselves */
+	     	paneltype = Panel_1024x768;
+	     	checkexpand = TRUE;
+	     }
+	     break;
+	 case 1152:
+	     if(yres == 768) {
+	        if(pSiS->VGAEngine == SIS_300_VGA) {
+		   paneltype = Panel300_1152x768;
+		} else {
+		   paneltype = Panel310_1152x768;
+		}
+	     	checkexpand = TRUE;
 	     }
 	     break;
 	 case 1280:
@@ -10323,46 +10589,46 @@
 		   paneltype = Panel300_1280x960;
 		}
 	     } else if(yres == 1024) {
-	     	paneltype = Panel310_1280x1024;  
+	     	paneltype = Panel_1280x1024;
 		checkexpand = TRUE;
-	     } else if(pSiS->VGAEngine == SIS_315_VGA) {
-	        if(yres == 768) {
-	       	   paneltype = Panel310_1280x768;
-		   checkexpand = FALSE;
-		   cr37 |= 0x10;
-	        }
-	     } 
+	     } else if(yres == 768) {
+	        paneltype = Panel_1280x768;
+		checkexpand = FALSE;
+		cr37 |= 0x10;
+	     }
 	     break;
 	 case 1400:
 	     if(pSiS->VGAEngine == SIS_315_VGA) {
 	        if(yres == 1050) {
 	           paneltype = Panel310_1400x1050;
 		   checkexpand = TRUE;
-	        } 
+	        }
 	     }
       	     break;
+#if 0    /* Treat this one as custom since we have no timing data yet */
 	 case 1600:
 	     if(pSiS->VGAEngine == SIS_315_VGA) {
 	        if(yres == 1200) {
 	           paneltype = Panel310_1600x1200;
 		   checkexpand = TRUE;
-	        } 
+	        }
 	     }
       	     break;
+#endif
       }
-                 
+
       /* Determine if RGB18 or RGB24 */
       if(index) {
          if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
 	    cr37 |= 0x01;
 	 }
       }
-      
+
       if(checkexpand) {
          /* TODO - for now, we let the panel scale */
 	 cr37 |= 0x10;
       }
-     
+
       /* Now seek 4-Byte Timing codes and extract sync pol info */
       index = 0x80;
       if(buffer[0x7e] & 0x20) {			    /* skip Luminance Table (if provided) */
@@ -10384,28 +10650,117 @@
 	 if(buffer[myindex] == seekcode) {
 	    cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
 	 } else {
-	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
-	    	"CRT2: Unable to retrieve Sync polarity information\n");    
+	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+	        "CRT2: Unable to retrieve Sync polarity information\n");
 	 }
       } else {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
-	    	"CRT2: Unable to retrieve Sync polarity information\n");
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+	     "CRT2: Unable to retrieve Sync polarity information\n");
+      }
+
+      /* Now seek the detailed timing descriptions for custom panels */
+      if(paneltype == Panel_Custom) {
+         index += (numcodes * 4);
+	 numcodes = buffer[0x7f] & 0x07;
+	 for(i=0; i<numcodes; i++) {
+	    xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
+            yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
+
+	    SiS_Pr->CP_HDisplay[i] = xres;
+	    SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
+            SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
+	    SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
+	    SiS_Pr->CP_HBlankStart[i] = xres + 1;
+	    SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
+
+	    SiS_Pr->CP_VDisplay[i] = yres;
+            SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
+            SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
+	    SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
+	    SiS_Pr->CP_VBlankStart[i] = yres + 1;
+	    SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
+
+	    SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
+
+	    SiS_Pr->CP_DataValid[i] = TRUE;
+
+	    if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  ||
+	       (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   ||
+	       (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     ||
+	       (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
+	       (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    ||
+	       (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      ||
+	       (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  ||
+	       (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   ||
+	       (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     ||
+	       (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  ||
+	       (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    ||
+	       (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      ||
+	       (SiS_Pr->CP_Clock[i] > 108000)                       ||
+	       (buffer[index + 17] & 0x80)) {
+
+	       SiS_Pr->CP_DataValid[i] = FALSE;
+
+	    } else {
+
+	       SiS_Pr->CP_HaveCustomData = TRUE;
+
+	       if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
+
+	       SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
+	       SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
+	       SiS_Pr->CP_SyncValid[i] = TRUE;
+
+	       SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
+	       SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
+
+	       /* We must assume the panel can scale, since we have
+	        * no scaling data
+    	        */
+	       cr37 |= 0x10;
+
+	    }
+	 }
+
       }
 
       break;
-     
+
    }
-   
+
    /* 1280x960 panels are always RGB24, unable to scale and use
     * high active sync polarity
     */
    if(pSiS->VGAEngine == SIS_315_VGA) {
-      if(paneltype == Panel310_1280x960) cr37 &= 0x0e; 
+      if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
    } else {
-      if(paneltype == Panel300_1280x960) cr37 &= 0x0e; 
+      if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
    }
-   
+
+   for(i = 0; i < 7; i++) {
+      if(SiS_Pr->CP_DataValid[i]) {
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+            "Non-standard LCD timing data no. %d:\n", i);
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	    "   HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
+	    SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
+	    SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+            "   VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
+            SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
+   	    SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	    "   Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
+	 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
+	    "   To use this, add \"%dx%d\" to the list of Modes in the Display section\n",
+	    SiS_Pr->CP_HDisplay[i],
+	    SiS_Pr->CP_VDisplay[i]);
+      }
+   }
+
    if(paneltype) {
+       if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
+       if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
        cr37 &= 0xf1;
        cr37 |= 0x02;    /* SiS301 */
        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x36,0xf0,paneltype);
@@ -10430,7 +10785,7 @@
    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
 /* if(pSiS->VBFlags & VB_30xBDH) return 0;  */
    
-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 2, 0, FALSE) == 0xFFFF) return 0;
+   if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
    
    SiS_Pr->SiS_DDC_SecAddr = 0x00;
    
@@ -10454,7 +10809,7 @@
    /* Read the entire EDID */
    retry = 2;
    do {
-      if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
+      if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
 	 	"CRT2: DDC read failed (attempt %d), %s\n", 
 		(3-retry), (retry == 1) ? "giving up" : "retrying");
@@ -10473,6 +10828,8 @@
 	  	"CRT2: Attached display expects digital input\n");
       	  return 0;  	
       }
+      SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
+      SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
       foundcrt = TRUE;
       break;
    case 3:
@@ -10486,198 +10843,19 @@
 		buffer[0x41]);
 	  return 0;
       }
+      SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
+      SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
       foundcrt = TRUE;
-      break;	  
+      break;
    }
-   
+
    if(foundcrt) {
        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
    }
    return(0);
 }
 
-#if 0
-   /* ----- */
-USHORT
-SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
-{
-   USHORT DDCdatatype, paneltype, flag;
-   unsigned char cr36=0, cr37=0;
-   unsigned char tempal, tempah, tempbl, tempbh;
-   USHORT tempax, tempbx, tempcx, push1, push2, push3;
-   unsigned char addresstable[] = { 0x00, 0x22, 0x30, 0x40 };
-   int i;
-   unsigned char buffer[256];
-   
-   if(pSiS->VGAEngine != SIS_315_VGA) return 0xFFFF;
-   if(!(pSiS->VBFlags & (VB_301B|VB_302B))) return 0xFFFF;
-   
-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0xFFFF;   
-   
-   flag = SiS_ProbeDDC(SiS_Pr);
-   if(flag & 0x02) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;	/* EDID V1 */
-      DDCdatatype = 1;
-      SiS_Pr->SiS_DDC_SecAddr = 0x3a;
-   } else if(flag & 0x08) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;	/* EDID V2 (P&D-D Monitor) */
-      DDCdatatype = 3;
-      SiS_Pr->SiS_DDC_SecAddr = 0x76;
-   } else if(flag & 0x10) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;	/* EDID V2 (FP) */
-      DDCdatatype = 4;
-      SiS_Pr->SiS_DDC_SecAddr = 0x76;
-   } else return 0xFFFF;
-   
-   
-   SiS_ReadLCDDDC(SiS_Pr, 4, buffer);
-   tempbl = buffer[0];  /* 3a - 76 */
-   tempbh = buffer[1];  /* 3b - 77 */
-   
-   if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
-   
-      /* Read and analyze EDID V1 (res) */
-   
-      tempah = 0x02;				/* 1024x768 by default */
-      tempbl &= 0xf0;
-      if(tempbl != 0x40) {			
-         tempah = 0x03;				/* 1280x1024 by default */
-	 if(tempbl == 0x50) {
-	    if(!tempbh) {
-	       tempbh = buffer[3] & 0xf0;
-	       if(tempbh == 0x30) {
-	           SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
-      		   SiS_Pr->SiS_DDC_SecAddr = 0x23;
-		   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-		   tempbl = buffer[0];  /* 0x23 */
-		   tempbh = buffer[1];  /* 0x24 */
-		   if(tempbl) cr37 |= 0x10;
-		   tempah = 0x0a;		/* 1280x768 */
-	       }
-	       if(tempbh == 0x40) {
-	           SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
-      		   SiS_Pr->SiS_DDC_SecAddr = 0x23;
-		   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-		   tempbl = buffer[0];  /* 0x23 */
-		   tempbh = buffer[1];  /* 0x24 */
-		   if(tempbl) cr37 |= 0x10;
-		   tempah = 0x03;		/* 1280x1024 */
-	       }
-	       tempbh = 0x00;
-	    }
-	 }
-	 if(tempbh == 0x00) goto cr36ready;
-	 tempah = 0x07;				/* 1280x960 */
-	 if(tempbh == 0xc0) goto cr36ready;
-      }
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
-      SiS_Pr->SiS_DDC_SecAddr = 0x18;		/* feature support */
-      SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-      tempbl = buffer[0];
-      tempbh = buffer[1];
-      if(tempbl & 0x02) goto cr36ready;
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
-      SiS_Pr->SiS_DDC_SecAddr = 0x23;		/* Established Timings */
-      SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-      tempbl = buffer[0];
-      tempbh = buffer[1];
-      tempah = 0x03;
-      if(!(tempbh & 0x01)) tempah = 0x02;
-      if(!tempbl) cr37 |= 0x10;
-      
-  } else {
-  
-      /* Read and analyze EDID V2 (res) */
-      
-      tempah = 0x02;
-      tempbx = tempbl | (tempbh << 8);
-      if(tempbx != 1024) tempah = 0x03;
-      
-  }     
-
-cr36ready:
-  cr36 = tempah;      
-  
-  if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
-  
-     /* Read and analyze EDID V1 (pol) */
-  
-     SiS_Pr->SiS_DDC_SecAddr = 0x47;
-     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-     tempah = buffer[0];
-     tempah &= 0x06;
-     tempah ^= 0x06;
-     tempah <<= 5;
-     tempah |= 0x20;
-     cr37 &= 0x1f;
-     cr37 |= tempah;
-     if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
-     
-  } else {
-  
-     /* Read and analyze EDID V2 (depth, pol) */
-  
-     push1 = tempah;
-     SiS_Pr->SiS_DDC_SecAddr = 0x45;
-     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-     tempah = 0x01;
-     if((buffer[0] != 0x20) && (buffer[0] != 0x34)) {   /* RGB18 or 24? */
-        tempah = 0x00;
-     }
-     cr37 &= 0xfe;
-     cr37 |= tempah;
-     
-     SiS_Pr->SiS_DDC_SecAddr = 0x7e;
-     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-     tempax = (USHORT)(buffer[0] | (buffer[1] << 8));
-     push2 = tempax;
-     tempax &= 0x0003;
-     tempax *= 0x1b;
-     push3 = tempax;
-     tempax = (USHORT)buffer[0];
-     tempax &= 0x001c;
-     tempax >>= 2;
-     tempax *= 8;
-     tempbx = push3;
-     tempbx += tempax;
-     if(buffer[0] & 0x20) {		/* Luminance table provided? */
-        SiS_Pr->SiS_DDC_SecAddr = 0x80;
-	SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-	tempax = buffer[0] | (buffer[1] << 8);
-	tempax &= 0x1f;
-	if(buffer[0] & 0x70) tempax <<= 1;
-	tempax++;	
-	tempbx += tempax;        	/* yes -> skip it */
-     }
-     tempcx = push2;
-     tempax = push1 << 8;
-     tempbx = (tempbx & 0xff00) | (((tempbx & 0x00ff) + 0x80) & 0x00ff);
-     if(tempcx & 0xf800) {
-        tempal = addresstable[((tempax & 0xff00) >> 8)];
-	tempcx &= 0xf8ff;
-	tempcx >>= 11;
-	for(i=0; i<tempcx; i++) {
-	   SiS_Pr->SiS_DDC_SecAddr = (tempbx & 0x00ff);
-	   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-	   tempbx += 0x04;
-	   if(buffer[0] == tempal) break;
-	}
-	tempah = buffer[1];
-	tempah &= 0x0c;
-	tempah ^= 0x0c;
-	tempah <<= 4;
-	tempah |= 0x20;
-        cr37 &= 0x1f;
-        cr37 |= tempah;
-	if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
-     }
-  }
-  xf86DrvMsg(0, X_INFO, "DDC: cr36 = 0x%02x, cr37 = 0x%02x\n", cr36, cr37);
-  return 0;
-}
-#endif
-
-/* TW: Generic I2C functions (compliant to i2c library) */
+/* Generic I2C functions (compliant to i2c library) */
 
 #if 0
 USHORT
@@ -10722,7 +10900,7 @@
   SiS_SetCH70xx(SiS_Pr,tempbl);
 }
 
-/* TW: Generic I2C functions for Chrontel --------- */
+/* Generic I2C functions for Chrontel --------- */
 
 void
 SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
@@ -10736,37 +10914,37 @@
   SiS_WaitRetraceDDC(SiS_Pr);
 }
 
-/* TW: Set I2C start condition */
-/* TW: This is done by a SD high-to-low transition while SC is high */
+/* Set I2C start condition */
+/* This is done by a SD high-to-low transition while SC is high */
 USHORT
 SiS_SetStart(SiS_Private *SiS_Pr)
 {
-  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low)  */
+  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low)  */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);             /* TW: SD->high */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high */
+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);             /* SD->high */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* SC->high */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                  ~SiS_Pr->SiS_DDC_Data,0x00);                             /* TW: SD->low = start condition */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
+                  ~SiS_Pr->SiS_DDC_Data,0x00);                             /* SD->low = start condition */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* (SC->low) */
   return 0;
 }
 
-/* TW: Set I2C stop condition */
-/* TW: This is done by a SD low-to-high transition while SC is high */
+/* Set I2C stop condition */
+/* This is done by a SD low-to-high transition while SC is high */
 USHORT
 SiS_SetStop(SiS_Private *SiS_Pr)
 {
-  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
+  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low) */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                  ~SiS_Pr->SiS_DDC_Data,0x00);          		   /* TW: SD->low   */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high  */
+                  ~SiS_Pr->SiS_DDC_Data,0x00);          		   /* SD->low   */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* SC->high  */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);  	   /* TW: SD->high = stop condition */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->high) */
+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);  	   /* SD->high = stop condition */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* (SC->high) */
   return 0;
 }
 
-/* TW: Write 8 bits of data */
+/* Write 8 bits of data */
 USHORT
 SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
 {
@@ -10774,18 +10952,18 @@
 
   flag=0x80;
   for(i=0;i<8;i++) {
-    SiS_SetSCLKLow(SiS_Pr);				                      /* TW: SC->low */
+    SiS_SetSCLKLow(SiS_Pr);				                      /* SC->low */
     if(tempax & flag) {
       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                      ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);            /* TW: Write bit (1) to SD */
+                      ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);            /* Write bit (1) to SD */
     } else {
       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                      ~SiS_Pr->SiS_DDC_Data,0x00);                            /* TW: Write bit (0) to SD */
+                      ~SiS_Pr->SiS_DDC_Data,0x00);                            /* Write bit (0) to SD */
     }
-    SiS_SetSCLKHigh(SiS_Pr);				                      /* TW: SC->high */
+    SiS_SetSCLKHigh(SiS_Pr);				                      /* SC->high */
     flag >>= 1;
   }
-  temp = SiS_CheckACK(SiS_Pr);				                      /* TW: Check acknowledge */
+  temp = SiS_CheckACK(SiS_Pr);				                      /* Check acknowledge */
   return(temp);
 }
 
@@ -10846,27 +11024,27 @@
   }
 }
 
-/* TW: Check I2C acknowledge */
+/* Check I2C acknowledge */
 /* Returns 0 if ack ok, non-0 if ack not ok */
 USHORT
 SiS_CheckACK(SiS_Private *SiS_Pr)
 {
   USHORT tempah;
 
-  SiS_SetSCLKLow(SiS_Pr);				           /* TW: (SC->low) */
+  SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* TW: (SD->high) */
-  SiS_SetSCLKHigh(SiS_Pr);				           /* TW: SC->high = clock impulse for ack */
-  tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* TW: Read SD */
-  SiS_SetSCLKLow(SiS_Pr);				           /* TW: SC->low = end of clock impulse */
-  if(tempah & SiS_Pr->SiS_DDC_Data) return(1);			   /* TW: Ack OK if bit = 0 */
+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* (SD->high) */
+  SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
+  tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* Read SD */
+  SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
+  if(tempah & SiS_Pr->SiS_DDC_Data) return(1);			   /* Ack OK if bit = 0 */
   else return(0);
 }
 
-/* TW: End of I2C functions ----------------------- */
+/* End of I2C functions ----------------------- */
 
 
-/* =============== SiS 310/325/330 O.E.M. ================= */
+/* =============== SiS 315/330 O.E.M. ================= */
 
 #ifdef SIS315H
 
@@ -10876,11 +11054,11 @@
   USHORT romptr;
 
   if(HwDeviceExtension->jChipType < SIS_330) {
-     romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);  
+     romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);
      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
         romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8);
   } else {
-     romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);  
+     romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);
      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
         romptr = ROMAddr[0x1aa] | (ROMAddr[0x1ab] << 8);
   }
@@ -10893,11 +11071,11 @@
   USHORT romptr;
 
   if(HwDeviceExtension->jChipType < SIS_330) {
-     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);  
+     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
         romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
   } else {
-     romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);  
+     romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
         romptr = ROMAddr[0x1a2] | (ROMAddr[0x1a3] << 8);
   }
@@ -10922,10 +11100,22 @@
 }
 
 static USHORT
-GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr)
+GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
   USHORT index;
-  
+
+  if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+     if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+        if((index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
+	   index >>= 4;
+	   index *= 3;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
+           else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
+           return index;
+	}
+     }
+  }
+
   index = SiS_Pr->SiS_LCDResInfo & 0x0F;
   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      index -= 5;
   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) index -= 6;
@@ -10933,7 +11123,6 @@
   index *= 3;
   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
-
   return index;
 }
 
@@ -10984,7 +11173,7 @@
              UCHAR *ROMAddr, USHORT ModeNo)
 {
   USHORT delay,index,myindex,temp,romptr=0;
-  
+
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* VGA */
      
      if((ROMAddr) && SiS_Pr->SiS_UseROM) {
@@ -11009,8 +11198,10 @@
      }
   
   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {		/* LCD */
+
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
   
-     index = GetLCDPtrIndexBIOS(SiS_Pr);
+     index = GetLCDPtrIndexBIOS(SiS_Pr, HwDeviceExtension, BaseAddr);
      myindex = GetLCDPtrIndex(SiS_Pr);
      
      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { 	/* 650+30xLV */
@@ -11018,7 +11209,7 @@
           if((ROMAddr) && SiS_Pr->SiS_UseROM) {
 #if 0	     /* Always use the second pointer on 650; some BIOSes */
              /* still carry old 301 data at the first location    */  
-	     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8); 
+	     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
 	     if(SiS_Pr->SiS_VBType & VB_SIS302LV) 
 #endif		
 	        romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
@@ -11032,13 +11223,13 @@
 #endif		
 	  }
        } else {
-          delay = SiS310_LCDDelayCompensation_651301LV[myindex];     
+          delay = SiS310_LCDDelayCompensation_651301LV[myindex];
 	  if(SiS_Pr->SiS_VBType & VB_SIS302LV)
-	     delay = SiS310_LCDDelayCompensation_651302LV[myindex];  
+	     delay = SiS310_LCDDelayCompensation_651302LV[myindex];
        }
      } else {
         if((ROMAddr) && SiS_Pr->SiS_UseROM && 				/* 315, 330, 740, 650+301B */
-	   (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) { 
+	   (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) {
            romptr = GetLCDromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
 	   if(!romptr) return;
 	   delay = ROMAddr[(romptr + index)];
@@ -11046,7 +11237,7 @@
            delay = SiS310_LCDDelayCompensation_301[myindex];
            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 #if 0 	      /* This data is (like the one in the BIOS) wrong. */	   
-	      if(IS_SIS650740) {  /* V */
+	      if(IS_SIS550650740660) {
 	         delay = SiS310_LCDDelayCompensation_650301B[myindex];
 	      } else {
 #endif	      
@@ -11126,14 +11317,16 @@
   } else {
      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
         temp = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
-        if(temp == 8) {
+        if(temp == 8) {		/* 1400x1050 BIOS */
 	   delay &= 0x0f;
 	   delay |= 0xb0;
         } else if(temp == 6) {
            delay &= 0x0f;
 	   delay |= 0xc0;
+        } else if(temp > 7) {	/* 1280x1024 BIOS */
+	   delay = 0x35;
         }
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);  /* index 2D D[3:0] */
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);
      } else {
         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
      }
@@ -11156,7 +11349,7 @@
 
   if(ROMAddr && SiS_Pr->SiS_UseROM) {
      romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
-     if(HwDeviceExtension->jChipType == SIS_330) {
+     if(HwDeviceExtension->jChipType >= SIS_330) {
         romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8);
      }
   }
@@ -11188,7 +11381,7 @@
 
   if(ROMAddr && SiS_Pr->SiS_UseROM) {
      romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
-     if(HwDeviceExtension->jChipType == SIS_330) {
+     if(HwDeviceExtension->jChipType >= SIS_330) {
         romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8);
      }
   }
@@ -11236,7 +11429,7 @@
 
   if(ROMAddr && SiS_Pr->SiS_UseROM) {
   	OutputSelect = ROMAddr[0xf3];
-	if(HwDeviceExtension->jChipType == SIS_330) {
+	if(HwDeviceExtension->jChipType >= SIS_330) {
 	    OutputSelect = ROMAddr[0x11b];
 	}
   }
@@ -11300,17 +11493,17 @@
    */
   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
      romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
-     if(HwDeviceExtension->jChipType == SIS_330) {
+     if(HwDeviceExtension->jChipType >= SIS_330) {
         romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
      }
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
         romptr = ROMAddr[0x11c] | (ROMAddr[0x11d] << 8);
-	if(HwDeviceExtension->jChipType == SIS_330) {
+	if(HwDeviceExtension->jChipType >= SIS_330) {
 	   romptr = ROMAddr[0x19c] | (ROMAddr[0x19d] << 8);
 	}
 	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_SetFlag & TVSimuMode))) {
 	   romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
-	   if(HwDeviceExtension->jChipType == SIS_330) {
+	   if(HwDeviceExtension->jChipType >= SIS_330) {
               romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
            }
 	}
@@ -11334,19 +11527,19 @@
      }
   }
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* TW: 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
      if((!(SiS_Pr->SiS_VBInfo & SetPALTV)) && (ModeNo > 0x13)) {
-        if(resinfo == 6) {
+        if(resinfo == SIS_RI_640x480) {
 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
-	} else if (resinfo == 7) {
+	} else if (resinfo == SIS_RI_800x600) {
 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
-	} else if (resinfo == 8) {
+	} else if (resinfo == SIS_RI_1024x768) {
 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x1e);
 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0x8b);
 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xfb);
@@ -11361,7 +11554,9 @@
                   UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
    SetDelayComp(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
-   /* TW: The TV functions are not for LVDS */
+
+   if(SiS_Pr->UseCustomMode) return;
+
    if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
        SetAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
        SetPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
@@ -11373,7 +11568,7 @@
 }
 
 /* FinalizeLCD
- * This finalizes some Part1 registers for the very panel used.
+ * This finalizes some CRT2 registers for the very panel used.
  * If we have a backup if these registers, we use it; otherwise
  * we set the register according to most BIOSes. However, this
  * function looks quite different in every BIOS, so you better
@@ -11388,6 +11583,9 @@
 
   if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
 
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+  if(SiS_Pr->UseCustomMode) return;
+
   if(ModeNo <= 0x13) {
 	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
 	modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
@@ -11396,20 +11594,31 @@
 	modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
+  if((SiS_GetReg1(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
+  }
+
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
 	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
 	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {   /* For all panels? */
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
      }
      tempch = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
      tempch &= 0xf0;
      tempch >>= 4;
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+        if(tempch == 0x03) {
+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x25);
+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,0x00);
+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
+	}
 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
 	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1f,0x76);
-	}
-	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {	
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
 	   if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
 	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
 	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
@@ -11425,14 +11634,14 @@
 	       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x90);
 	       if(ModeNo <= 0x13) {
 	          SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x11);
-		  if((resinfo == 0) && (resinfo == 2)) return;
+		  if((resinfo == 0) || (resinfo == 2)) return;
 		  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x18);
-		  if((resinfo == 1) && (resinfo == 3)) return;
+		  if((resinfo == 1) || (resinfo == 3)) return;
 	       }
 	       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
-	       if((ModeNo > 0x13) && (resinfo == 8)) {
+	       if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
 	          SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
-#if 0	       
+#if 0
 	          tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
 		  tempbx--;
 		  temp = tempbx & 0xff;
@@ -11487,7 +11696,7 @@
 	tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
 	tempbx = (tempbh << 8) | tempbl;
 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-	   if((resinfo == 8) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
+	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
 	      	tempbx = 770;
 	      } else {
@@ -11515,67 +11724,56 @@
   }
 }
 
-#if 0
-/* TW: New and checked from 650/301LV BIOS */
-/* This might clash with newer "FinalizeLCD()" function */
+#endif
+
+
+/*  =================  SiS 300 O.E.M. ================== */
+
+#ifdef SIS300
+
 void
-SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                  UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
 {
-   USHORT tempbx,tempah,tempbl,tempbh,tempcl;
-
-   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+  USHORT crt2crtc=0, modeflag, myindex=0;
+  UCHAR  temp;
+  int i;
 
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-      SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
-      tempbh = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x1a);
-      tempbh &= 0x38;
-      tempbh >>= 3;
-      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
-      tempbx = (tempbh << 8) | tempbl;
-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempbx -= 0x12;
-      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,tempbx & 0x00ff);
-      tempah = (tempbx & 0xff00) >> 8;
-      tempah &= 0x07;
-      tempah <<= 3;
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0xc7,tempah);
-      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x19);
-      tempah &= 0x0f;
-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah -= 2;
-      tempah &= 0x0f;
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,tempah);
-      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x14);
-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah++;
-      tempah -= 8;
-      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,tempah);
-   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-      tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
-      tempbh &= 0x70;
-      tempbh >>= 4;
-      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
-      tempbx = (tempbh << 8) | tempbl;
-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  {
-           tempbx -= 0x1e;
-	   tempcl &= 0x0f;
-	   tempcl -= 4;
-	   tempcl &= 0x0f;
-      }
-      tempbl = tempbx & 0x00ff;
-      tempbh = (tempbx >> 8) & 0x00ff;
-      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,tempbl);
-      tempbh <<= 4;
-      tempbh |= tempcl;
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,tempbh);
-   }
-}
-#endif
+  if(ModeNo <= 0x13) {
+        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
+  }
 
-#endif
+  crt2crtc &= 0x3f;
 
+  if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
+  }
 
-/*  =================  SiS 300 O.E.M. ================== */
+  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+     if(modeflag & HalfDCLK) myindex = 1;
 
-#ifdef SIS300
+     if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+        for(i=0; i<7; i++) {
+           if(barco_p1[myindex][crt2crtc][i][0]) {
+	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
+	                      barco_p1[myindex][crt2crtc][i][0],
+	   	   	      barco_p1[myindex][crt2crtc][i][2],
+			      barco_p1[myindex][crt2crtc][i][1]);
+	   }
+        }
+     }
+     temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+     if(temp & 0x80) {
+        temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
+        temp++;
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);
+     }
+  }
+}
 
 #if 0   /* Not used */
 static USHORT
@@ -11620,7 +11818,7 @@
 
   if(HwDeviceExtension->jChipType == SIS_300) {
 
-    tempbx = SiS_Pr->SiS_LCDResInfo - 2;
+    tempbx = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
@@ -11674,24 +11872,29 @@
 {
   USHORT index,temp,romptr=0;
 
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+
   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x237] & 0x01)) return;
      if(!(ROMAddr[0x237] & 0x02)) return;
      romptr = ROMAddr[0x24b] | (ROMAddr[0x24c] << 8);
   }
 
-  /* TW: The Panel Compensation Delay should be set according to tables
-   *     here. Unfortunately, various BIOS versions don't case about
-   *     a uniform way using eg. ROM byte 0x220, but use different
-   *     hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
-   *     Thus we don't set this if the user select a custom pdc or if
-   *     we otherwise detected a valid pdc.
+  /* The Panel Compensation Delay should be set according to tables
+   * here. Unfortunately, various BIOS versions don't case about
+   * a uniform way using eg. ROM byte 0x220, but use different
+   * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
+   * Thus we don't set this if the user select a custom pdc or if
+   * we otherwise detected a valid pdc.
    */
   if(HwDeviceExtension->pdc) return;
 
   temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 0);
 
-  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
+  if(SiS_Pr->UseCustomMode)
+     index = 0;
+  else
+     index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
 
   if(HwDeviceExtension->jChipType != SIS_300) {
 	if(romptr) {
@@ -11738,9 +11941,9 @@
 
 static void
 SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-#if 0  /* TW: Unfinished; VData table missing */
+#if 0  /* Unfinished; Data table missing */
   USHORT index,temp;
 
   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
@@ -11937,25 +12140,29 @@
 
 void
 SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo)
+		  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		  USHORT RefTableIndex)
 {
-  USHORT ModeIdIndex;
+  USHORT OEMModeIdIndex=0;
 
-  ModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
-  if(!(ModeIdIndex)) return;
+  if(!SiS_Pr->UseCustomMode) {
+     OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
+     if(!(OEMModeIdIndex)) return;
+  }
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-       SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-            SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+            SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
        }
   }
+  if(SiS_Pr->UseCustomMode) return;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-       SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
        if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-       		SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-    		SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-       		SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       		SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
+    		SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
+       		SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
        }
   }
 }
diff -urN linux-2.4.22-pre2/drivers/video/sis/init301.h linux-2.4.22-pre3/drivers/video/sis/init301.h
--- linux-2.4.22-pre2/drivers/video/sis/init301.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/init301.h	2003-07-05 18:11:04.000000000 -0700
@@ -1,20 +1,44 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
+/* $XFree86$ */
+/*
+ * Data and prototypes for init301.c
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
 #ifndef  _INIT301_
 #define  _INIT301_
 
 #include "osdef.h"
+
 #include "initdef.h"
 #include "vgatypes.h"
 #include "vstruct.h"
 
-#ifdef TC
-#include <stdio.h>
-#include <string.h>
-#include <conio.h>
-#include <dos.h>
-#include <stdlib.h>
-#endif
-
 #ifdef LINUX_XF86
 #include "xf86.h"
 #include "xf86Pci.h"
@@ -24,6 +48,9 @@
 #endif
 
 #ifdef LINUX_KERNEL
+#ifdef SIS_CP
+#undef SIS_CP
+#endif
 #include <linux/config.h>
 #include <linux/version.h>
 #include <asm/io.h>
@@ -35,24 +62,60 @@
 #endif
 #endif
 
-#ifdef WIN2000
-#include <stdio.h>
-#include <string.h>
-#include <miniport.h>
-#include "dderror.h"
-#include "devioctl.h"
-#include "miniport.h"
-#include "ntddvdeo.h"
-#include "video.h"
-#include "sisv.h"
-#endif
+const UCHAR SiS_HiVisionTable[3][64] = {
+  {
+    0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
+    0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
+    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
+    0x0c, 0x50, 0x00, 0x97, 0x00, 0xd4, 0x4a, 0x17,
+    0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
+    0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
+    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x53,
+    0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
+  },
+  {
+    0x1d, 0x1d, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
+    0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
+    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
+    0x0c, 0x50, 0xb2, 0x2e, 0x16, 0xb5, 0xf4, 0x03,
+    0x7d, 0x11, 0x7d, 0xea, 0x30, 0x36, 0x18, 0x96,
+    0x21, 0x0a, 0x58, 0xee, 0x42, 0x92, 0x0f, 0x40,
+    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3,
+    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
+  },
+  {
+    0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c,
+    0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a,
+    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
+    0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13,
+    0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0,
+    0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40,
+    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a,
+    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
+  }
+};
 
-#if 0
-extern   const USHORT   SiS_MDA_DAC[];
-extern   const USHORT   SiS_CGA_DAC[];
-extern   const USHORT   SiS_EGA_DAC[];
-extern   const USHORT   SiS_VGA_DAC[];
-#endif
+const UCHAR SiS_HiTVGroup3_1[] = {
+    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
+    0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
+    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
+    0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
+    0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
+    0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
+    0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
+    0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
+};
+
+const UCHAR SiS_HiTVGroup3_2[] = {
+    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
+    0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
+    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
+    0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
+    0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
+    0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
+    0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
+    0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
+};
 
 extern   BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *RomAddr, USHORT *);
 
@@ -129,7 +192,6 @@
 BOOLEAN  SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
 BOOLEAN  SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
 BOOLEAN  SiS_BridgeInSlave(SiS_Private *SiS_Pr);
-void     SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
 void     SiS_SetTVSystem(SiS_Private *SiS_Pr);
 void     SiS_LongWait(SiS_Private *SiS_Pr);
 USHORT   SiS_GetQueueConfig(SiS_Private *SiS_Pr);
@@ -149,7 +211,7 @@
                             USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex);
 #endif			    
 void     SiS_SetTPData(SiS_Private *SiS_Pr);
-void     SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo);
+void     SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
 void     SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                          USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
 void     SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
@@ -178,30 +240,28 @@
 USHORT   SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
 USHORT   SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
 USHORT   SiS_CheckACK(SiS_Private *SiS_Pr);
-USHORT   SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer);
-#ifdef LINUX_XF86
-USHORT   SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
-USHORT   SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
-#endif
+
 #ifdef SIS315H
 void     SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
                            UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
 void     SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                    UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+                    UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
 #endif
 #ifdef SIS300
 void     SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                           UCHAR *ROMAddr,USHORT ModeNo);
+                           UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
+void     SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+			UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
 #endif
 BOOLEAN  SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
 
-BOOLEAN  SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex,
+void     SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex,
                            PSIS_HW_DEVICE_INFO HwDeviceExtension);
 /* void    SiS_CHACRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                         USHORT RefreshRateTableIndex); */
 
-BOOLEAN  SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                          PSIS_HW_DEVICE_INFO HwDeviceExtension);
 void     SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                        PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
 void     SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
@@ -237,19 +297,19 @@
 void     SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
 void     SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
 
-void     SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr);
+void     SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
 void     SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
 #ifdef SIS315H
 void     SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
                             USHORT BaseAddr);
-void     SiS_Chrontel701xOff(SiS_Private *SiS_Pr);
+void     SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
 void     SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
 void     SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
 void     SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
 void     SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
 void     SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
 BOOLEAN  SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void     SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr);
+void     SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr,  PSIS_HW_DEVICE_INFO HwDeviceExtension);
 void     SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
 #ifdef NEWCH701x
 void     SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr);
@@ -289,73 +349,21 @@
 extern   UCHAR    SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
 #endif
 
-#ifdef LINUX_XF86
 /* DDC functions */
-USHORT   SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
+USHORT   SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+                         USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
 USHORT   SiS_WriteDABDDC(SiS_Private *SiS_Pr);
 USHORT   SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
 USHORT   SiS_PrepareDDC(SiS_Private *SiS_Pr);
 void     SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
 USHORT   SiS_DoProbeDDC(SiS_Private *SiS_Pr);
 USHORT   SiS_ProbeDDC(SiS_Private *SiS_Pr);
-USHORT   SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer);
-USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
-                       USHORT DDCdatatype, unsigned char *buffer);
+USHORT   SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer);
+USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+		       USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
+#ifdef LINUX_XF86
+USHORT   SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+USHORT   SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
 #endif
 
-const UCHAR SiS_HiVisionTable[3][64] = {
-  { 
-    0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
-    0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
-    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
-    0x0c, 0x50, 0x00, 0x97, 0x00, 0xd4, 0x4a, 0x17,
-    0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
-    0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
-    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x53,
-    0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
-  },
-  { 
-    0x1d, 0x1d, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
-    0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
-    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
-    0x0c, 0x50, 0xb2, 0x2e, 0x16, 0xb5, 0xf4, 0x03,
-    0x7d, 0x11, 0x7d, 0xea, 0x30, 0x36, 0x18, 0x96,
-    0x21, 0x0a, 0x58, 0xee, 0x42, 0x92, 0x0f, 0x40,
-    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3,
-    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
-  },
-  { 
-    0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c, 
-    0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a, 
-    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, 
-    0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13, 
-    0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0, 
-    0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40, 
-    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a, 
-    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00 
-  }
-};
-
-const UCHAR SiS_HiTVGroup3_1[] = {
-    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
-    0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
-    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
-    0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
-    0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
-    0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
-    0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
-    0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
-};
-
-const UCHAR SiS_HiTVGroup3_2[] = {
-    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
-    0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
-    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
-    0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
-    0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
-    0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
-    0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
-    0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
-};
-
 #endif
diff -urN linux-2.4.22-pre2/drivers/video/sis/initdef.h linux-2.4.22-pre3/drivers/video/sis/initdef.h
--- linux-2.4.22-pre2/drivers/video/sis/initdef.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/initdef.h	2003-07-05 18:11:04.000000000 -0700
@@ -1,5 +1,29 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
-
+/*
+ * Global definitions for init.c and init301.c
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ */
 
 #ifndef _INITDEF_
 #define _INITDEF_
@@ -22,12 +46,18 @@
 #define VB_SIS301B302B          (VB_SIS301B|VB_SIS302B)
 #define VB_SIS301LV302LV        (VB_SIS301LV|VB_SIS302LV)
 
-#define IS_SIS650740            ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330))
-
 #define IS_SIS650		(HwDeviceExtension->jChipType == SIS_650)
 #define IS_SIS740		(HwDeviceExtension->jChipType == SIS_740)
 #define IS_SIS330		(HwDeviceExtension->jChipType == SIS_330)
 #define IS_SIS550		(HwDeviceExtension->jChipType == SIS_550)
+#define IS_SIS651	        (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652))
+#define IS_SISM650	        (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653))
+#define IS_SIS65x               (IS_SIS651 || IS_SISM650)
+#define IS_SIS660		(HwDeviceExtension->jChipType == SIS_660)
+#define IS_SIS650660            (IS_SIS650 || IS_SIS660)
+#define IS_SIS650740            ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330))
+#define IS_SIS650740660         (IS_SIS650 || IS_SIS660 || IS_SIS740)
+#define IS_SIS550650740660      (IS_SIS550 || IS_SIS650 || IS_SIS660 || IS_SIS740)
 
 #define CRT1Len                 17
 #define LVDSCRT1Len             15
@@ -63,7 +93,7 @@
 #define SupportTV               0x0008
 #define SupportHiVisionTV       0x0010
 #define SupportLCD              0x0020
-#define SupportRAMDAC2          0x0040  
+#define SupportRAMDAC2          0x0040
 #define NoSupportTV             0x0070
 #define NoSupportHiVisionTV     0x0060
 #define NoSupportLCD            0x0058
@@ -105,6 +135,24 @@
 #define HotKeySwitch            0x8000  /* TW: ? */
 #define SetCRT2ToLCDA           0x8000
 
+/* SetFlag */
+#define ProgrammingCRT2         0x01
+#define TVSimuMode              0x02
+#define RPLLDIV2XO              0x04
+#define LCDVESATiming           0x08
+#define EnableLVDSDDA           0x10
+#define SetDispDevSwitchFlag    0x20
+#define CheckWinDos             0x40
+#define SetDOSMode              0x80
+
+/* SysFlags */
+#define SF_Is651                0x0001
+#define SF_IsM650               0x0002
+#define SF_Is652		0x0004
+#define SF_IsM652		0x0008
+#define SF_IsM653		0x0010
+#define SF_Is660		0x8000
+
 #define PanelRGB18Bit           0x0100
 #define PanelRGB24Bit           0x0000
 
@@ -112,7 +160,7 @@
 #define TVOverScanShift         4
 #define ClearBufferFlag         0x20
 
-/* CR32 (Newer 630, and 310/325 series)
+/* CR32 (Newer 630, and 315 series)
 
    [0]   VB connected with CVBS
    [1]   VB connected with SVHS
@@ -134,7 +182,7 @@
 	    011   LVDS + Tumpion Zurac
 	    100   LVDS + Chrontel 7005
 	    110   Chrontel 7005
-	  310/325 series
+	  315 series
 	    001   SiS30x (never seen)
 	    010   LVDS
 	    011   LVDS + Chrontel 7019
@@ -163,14 +211,15 @@
 #define LCDSyncBit            0x00e0
 #define LCDSyncShift               6
 
-/* CR38 (310/325 series) */
+/* CR38 (315 series) */
 #define EnableDualEdge 		0x01   
 #define SetToLCDA		0x02   /* LCD channel A (302B/LV and 650+LVDS only) */
 #define EnableSiSHiVision       0x04   /* HiVision (HDTV) on SiS bridge */
 #define EnableLVDSScart         0x04   /* Scart on Ch7019 (unofficial definition - TW) */
 #define EnableLVDSHiVision      0x08   /* YPbPr color format (480i HDTV); only on 650/Ch7019 systems */
-#define SiSHiVision1            0x10   /* See SetHiVision() */
-#define SiSHiVision2            0x20
+#define EnableHiVision750       0x08   /* Enable 750P HiVision mode (30xLV only) */
+#define EnableHiVision525       0x10   /* Enable 525P HiVision mode (30xLV only) */
+#define SiSHiVision2            0x20   /* ? - |  --- mask 0x38 combinations have different meaning! */
 #define EnablePALM              0x40   /* 1 = Set PALM */
 #define EnablePALN              0x80   /* 1 = Set PALN */
 
@@ -184,7 +233,7 @@
 #define Enable302LV_DualLink    0x04   /* 30xNEW (302LV) only; set by mode switching function */
 
 
-/* CR79 (310/325 series only)
+/* CR79 (315 series only)
    [3-0] Notify driver
          0001 Mode Switch event (set by BIOS)
 	 0010 Epansion On/Off event
@@ -202,16 +251,6 @@
    [7]   TV UnderScan/OverScan (set by BIOS)
 */
 
-/* SetFlag */
-#define ProgrammingCRT2         0x01
-#define TVSimuMode              0x02
-#define RPLLDIV2XO              0x04
-#define LCDVESATiming           0x08
-#define EnableLVDSDDA           0x10
-#define SetDispDevSwitchFlag    0x20
-#define CheckWinDos             0x40
-#define SetDOSMode              0x80
-
 /* LCDResInfo */
 #define Panel300_800x600        0x01	/* CR36 */
 #define Panel300_1024x768       0x02
@@ -220,7 +259,10 @@
 #define Panel300_640x480        0x05
 #define Panel300_1024x600       0x06
 #define Panel300_1152x768       0x07
-#define Panel300_320x480        0x08 	/* fstn - TW: This is fake, can be any */
+#define Panel300_1280x768       0x0a
+#define Panel300_320x480        0x0e 	/* fstn - TW: This is fake, can be any */
+#define Panel300_Custom		0x0f
+#define Panel300_Barco1366      0x10
 
 #define Panel310_800x600        0x01
 #define Panel310_1024x768       0x02
@@ -231,9 +273,12 @@
 #define Panel310_1280x960       0x07
 #define Panel310_1152x768       0x08	/* LVDS only */
 #define Panel310_1400x1050      0x09
-#define Panel310_1280x768       0x0a    
+#define Panel310_1280x768       0x0a
 #define Panel310_1600x1200      0x0b
-#define Panel310_320x480        0x0c    /* fstn - TW: This is fake, can be any */
+#define Panel310_640x480_2      0x0c
+#define Panel310_640x480_3      0x0d
+#define Panel310_320x480        0x0e    /* fstn - TW: This is fake, can be any */
+#define Panel310_Custom		0x0f
 
 #define Panel_800x600           0x01	/* Unified values */
 #define Panel_1024x768          0x02
@@ -246,7 +291,42 @@
 #define Panel_1400x1050         0x09
 #define Panel_1280x768          0x0a    /* LVDS only */
 #define Panel_1600x1200         0x0b
-#define Panel_320x480           0x0c    /* fstn - TW: This is fake, can be any */
+#define Panel_640x480_2		0x0c
+#define Panel_640x480_3		0x0d
+#define Panel_320x480           0x0e    /* fstn - TW: This is fake, can be any */
+#define Panel_Custom		0x0f
+#define Panel_Barco1366         0x10
+
+/* Index in ModeResInfo table */
+#define SIS_RI_320x200 0
+#define SIS_RI_320x240 1
+#define SIS_RI_320x400 2
+#define SIS_RI_400x300 3
+#define SIS_RI_512x384 4
+#define SIS_RI_640x400 5
+#define SIS_RI_640x480 6
+#define SIS_RI_800x600 7
+#define SIS_RI_1024x768 8
+#define SIS_RI_1280x1024 9
+#define SIS_RI_1600x1200 10
+#define SIS_RI_1920x1440 11
+#define SIS_RI_2048x1536 12
+#define SIS_RI_720x480 13
+#define SIS_RI_720x576 14
+#define SIS_RI_1280x960 15
+#define SIS_RI_800x480 16
+#define SIS_RI_1024x576 17
+#define SIS_RI_1280x720 18
+#define SIS_RI_856x480 19
+#define SIS_RI_1280x768 20
+#define SIS_RI_1400x1050 21
+#define SIS_RI_1152x864 22
+#define SIS_RI_848x480 23
+#define SIS_RI_1360x768 24
+#define SIS_RI_1024x600 25
+#define SIS_RI_1152x768 26
+#define SIS_RI_768x576 27
+#define SIS_RI_1360x1024 28
 
 #define ExtChipType             0x0e
 #define ExtChip301              0x02
@@ -278,15 +358,32 @@
 #define VCLKStartFreq           25
 #define SoftDramType            0x80
 
-#define VCLK40                  0x04   /* Index in VCLKData array */
-#define VCLK65                  0x09   /* Index in VCLKData array */
-#define VCLK108_2               0x14   /* Index in VCLKData array */
-#define TVVCLKDIV2              0x21   /* Indices in (VB)VCLKData arrays */
-#define TVVCLK                  0x22
-#define HiTVVCLKDIV2            0x23
-#define HiTVVCLK                0x24
-#define HiTVSimuVCLK            0x25
-#define HiTVTextVCLK            0x26
+/* Indices in (VB)VCLKData tables */
+
+#define VCLK28                  0x00   /* Index in VCLKData table (300 and 315) */
+#define VCLK40                  0x04   /* Index in VCLKData table (300 and 315) */
+#define VCLK65_300              0x09   /* Index in VCLKData table (300) */
+#define VCLK108_2_300           0x14   /* Index in VCLKData table (300) */
+#define VCLK81_300		0x3f   /* Index in VCLKData table (300) */
+#define VCLK108_3_300           0x42   /* Index in VCLKData table (300) */
+#define VCLK100_300             0x43   /* Index in VCLKData table (300) */
+#define VCLK65_315              0x0b   /* Index in (VB)VCLKData table (315) */
+#define VCLK108_2_315           0x19   /* Index in (VB)VCLKData table (315) */
+#define VCLK81_315		0x5b   /* Index in (VB)VCLKData table (315) */
+#define VCLK162_315             0x21   /* Index in (VB)VCLKData table (315) */
+#define VCLK108_3_315           0x45   /* Index in VBVCLKData table (315) */
+#define VCLK100_315             0x46   /* Index in VBVCLKData table (315) */
+
+#define TVCLKBASE_300		0x21   /* Indices on TV clocks in VCLKData table (300) */
+#define TVCLKBASE_315	        0x3a   /* Indices on TV clocks in (VB)VCLKData table (315) */
+#define TVVCLKDIV2              0x00   /* Index relative to TVCLKBASE */
+#define TVVCLK                  0x01   /* Index relative to TVCLKBASE */
+#define HiTVVCLKDIV2            0x02   /* Index relative to TVCLKBASE */
+#define HiTVVCLK                0x03   /* Index relative to TVCLKBASE */
+#define HiTVSimuVCLK            0x04   /* Index relative to TVCLKBASE */
+#define HiTVTextVCLK            0x05   /* Index relative to TVCLKBASE */
+
+/* ------------------------------ */
 
 #define LoadDACFlag             0x1000
 #define AfterLockCRT2           0x4000
@@ -306,6 +403,8 @@
 #define HotPlugFunction         0x08
 #define StStructSize            0x06
 
+#define SIS_VIDEO_CAPTURE       0x00 - 0x30
+#define SIS_VIDEO_PLAYBACK      0x02 - 0x30
 #define SIS_CRT2_PORT_04        0x04 - 0x30
 #define SIS_CRT2_PORT_10        0x10 - 0x30
 #define SIS_CRT2_PORT_12        0x12 - 0x30
@@ -393,7 +492,7 @@
 
 /*
   =============================================================
-   			for 310/325 series
+   			  for 315 series
   =============================================================
 */
 #define SoftDRAMType        0x80
diff -urN linux-2.4.22-pre2/drivers/video/sis/oem300.h linux-2.4.22-pre3/drivers/video/sis/oem300.h
--- linux-2.4.22-pre2/drivers/video/sis/oem300.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/oem300.h	2003-07-05 18:11:04.000000000 -0700
@@ -1,5 +1,36 @@
-
-/* OEM Data for 300 series */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
+/*
+ * OEM Data for 300 series
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
 
 const UCHAR SiS300_OEMTVDelay301[8][4] =
 {
@@ -680,325 +711,147 @@
     }
 };
 
-const UCHAR SiS300_LCDHData[24][11][5] = {
+/* Custom data for Barco iQ Pro R300 */
+const UCHAR barco_p1[2][9][7][3] = {
     {
-        {0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x8a,0x14,0x00,0x80,0x00},
-	{0x8a,0x14,0x00,0x80,0x00}
-    },
-    {
-        {0x4e,0x18,0x90,0x38,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9a,0x56,0x00},
-        {0x67,0x11,0x9a,0x56,0x00},
-	{0x8a,0x14,0x00,0x80,0x00},
-	{0x8a,0x14,0x00,0x80,0x00}
-    },
-    {
-        {0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x8a,0x14,0x00,0x80,0x00},
-	{0x8a,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4e,0x18,0x90,0x38,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9a,0x56,0x00},
-	{0x67,0x11,0x9a,0x56,0x00},
-	{0x8a,0x14,0x00,0x80,0x00},
-	{0x8a,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x8a,0x14,0x00,0x80,0x00},
-	{0x8a,0x14,0x00,0x80,0x00}
-    },
-    {
-        {0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-    	{0x67,0x91,0x84,0x5E,0x00},
-    	{0x67,0x91,0x84,0x5E,0x00},
-    	{0x67,0x91,0x84,0x5E,0x00},
-    	{0x67,0x91,0x84,0x5E,0x00},
-    	{0x65,0xEF,0x83,0x5C,0x00},
-    	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
+	{  { 0x16, 0xcf, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x19, 0x00 }
+	},
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x1e, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x16, 0x00 }
+	},
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x19, 0x00 },
+	   {    0,    0,    0 }
+	},
+	{
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x1e, 0x00 },
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0xd1, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x11, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x26, 0x00 }
+	},
+	{
+	   { 0x16, 0xd1, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x30, 0x00 },
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0x00, 0x00 },
+	   { 0x17, 0xa0, 0x00 },
+	   { 0x1a, 0xa0, 0x00 },
+	   { 0x1b, 0x2a, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0x00, 0x00 },
+	   { 0x17, 0xaa, 0x00 },
+	   { 0x1a, 0xa0, 0x00 },
+	   { 0x1b, 0x2a, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   {    0,    0,    0 }
+	}
+    },
+    {
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x19, 0x00 }
+	},
+	{
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x19, 0x00 },
+	},
+	{
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x1e, 0x00 }
+	},
+	{
+	   { 0x16, 0xd1, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe6, 0x00 },
+	   { 0x1b, 0x11, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x26, 0x00 }
+	},
+	{
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe0, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x30, 0x00 },
+	   {    0,    0,    0 }
+	},
+	{
+	   {    0,    0,    0 }
+	},
+	{
+	   {    0,    0,    0 }
+	}
     }
 };
 
-#if 0
-const UCHAR SiS300_LCDVData[24][11][6] = {
-    {
-        {
-    },
-};
-#endif
+
+
+
+
+
diff -urN linux-2.4.22-pre2/drivers/video/sis/oem310.h linux-2.4.22-pre3/drivers/video/sis/oem310.h
--- linux-2.4.22-pre2/drivers/video/sis/oem310.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/oem310.h	2003-07-05 18:11:04.000000000 -0700
@@ -1,5 +1,35 @@
-
-/* OEM Data for 310/325/330 series */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
+/*
+ * OEM Data for 315/330 series
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
 
 const UCHAR SiS310_LCDDelayCompensation_301[] =	    	/* 301 */
 {
@@ -100,7 +130,7 @@
 
 const UCHAR SiS310_LCDDelayCompensation_651301LV[] =	  /* M650/651 301LV */
 {
-                 0x33,0x33,0x33,    /*   800x600 (guessed) */
+                 0x33,0x33,0x33,    /*   800x600 (guessed) - new: PanelType, not PanelRes ! */
 		 0x33,0x33,0x33,    /*  1024x768 */
 		 0x33,0x33,0x33,    /* 1280x1024 */
 		 0x33,0x33,0x33,    /*   640x480 (unknown) */
diff -urN linux-2.4.22-pre2/drivers/video/sis/osdef.h linux-2.4.22-pre3/drivers/video/sis/osdef.h
--- linux-2.4.22-pre2/drivers/video/sis/osdef.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/osdef.h	2003-07-05 18:11:04.000000000 -0700
@@ -1,76 +1,43 @@
-/* #define WINCE_HEADER */
-/* #define WIN2000 */
-/* #define TC */
+
+/* OS depending defines */
+
+/* The choices are: */
+
 #define LINUX_KERNEL	   /* Kernel framebuffer */
 /* #define LINUX_XF86 */   /* XFree86 */
 
 /**********************************************************************/
-#ifdef LINUX_KERNEL
-	#include <linux/config.h>
-	#include <linux/version.h>
-	#ifdef CONFIG_FB_SIS_300
- 		#define SIS300
-	#endif
-
-	#ifdef CONFIG_FB_SIS_315
-		#define SIS315H
-	#endif
-	#if 1
-		#define SISFBACCEL	/* Include 2D acceleration */
-	#endif
-#else
-/*	#define SIS300*/
-	#define SIS315H
-#endif
-#ifdef LINUX_XF86
-	#define SIS300
-	/* #define SIS315H */ /* TW: done above */
-#endif
+#ifdef LINUX_KERNEL  /* -------------------------- */
+#include <linux/config.h>
+#include <linux/version.h>
 
-/**********************************************************************/
-#ifdef TC
-#endif
-#ifdef WIN2000
-#endif
-#ifdef WINCE_HEADER
-#endif
-#ifdef LINUX_XF86
+#ifdef CONFIG_FB_SIS_300
+#define SIS300
 #endif
-#ifdef LINUX_KERNEL
-#endif
-/**********************************************************************/
-#ifdef TC
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
-#endif
-#ifdef WIN2000
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) MemFill((PVOID) MemoryAddress,(ULONG) MemorySize,(UCHAR) value);
+
+#ifdef CONFIG_FB_SIS_315
+#define SIS315H
 #endif
-#ifdef WINCE_HEADER
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
+
+#if 1
+#define SISFBACCEL	/* Include 2D acceleration */
 #endif
-#ifdef LINUX_XF86
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+
 #endif
-#ifdef LINUX_KERNEL
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+
+#ifdef LINUX_XF86 /* ----------------------------- */
+#define SIS300
+#define SIS315H
 #endif
-/**********************************************************************/
 
 /**********************************************************************/
-
-#ifdef TC
-#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
-#endif
-#ifdef WIN2000
-#define SiS_MemoryCopy(Destination,Soruce,Length)  /*VideoPortMoveMemory((PUCHAR)Destination , Soruce,length);*/
-#endif
-#ifdef WINCE_HEADER
-#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
-#endif
 #ifdef LINUX_XF86
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
 #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
 #endif
+
 #ifdef LINUX_KERNEL
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
 #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
 #endif
 
@@ -101,19 +68,6 @@
 #endif /* InPortLong */
 
 /**********************************************************************/
-/*  TC                                                                */
-/**********************************************************************/
-
-#ifdef TC
-#define OutPortByte(p,v) outp((unsigned short)(p),(unsigned char)(v))
-#define OutPortWord(p,v) outp((unsigned short)(p),(unsigned short)(v))
-#define OutPortLong(p,v) outp((unsigned short)(p),(unsigned long)(v))
-#define InPortByte(p)    inp((unsigned short)(p))
-#define InPortWord(p)    inp((unsigned short)(p))
-#define InPortLong(p)    ((inp((unsigned short)(p+2))<<16) | inp((unsigned short)(p)))
-#endif
-
-/**********************************************************************/
 /*  LINUX XF86                                                        */
 /**********************************************************************/
 
@@ -139,29 +93,4 @@
 #define InPortLong(p)    inl((u16)(p))
 #endif
 
-/**********************************************************************/
-/*  WIN 2000                                                          */
-/**********************************************************************/
-
-#ifdef WIN2000
-#define OutPortByte(p,v) VideoPortWritePortUchar ((PUCHAR) (p), (UCHAR) (v))
-#define OutPortWord(p,v) VideoPortWritePortUshort((PUSHORT) (p), (USHORT) (v))
-#define OutPortLong(p,v) VideoPortWritePortUlong ((PULONG) (p), (ULONG) (v))
-#define InPortByte(p)    VideoPortReadPortUchar  ((PUCHAR) (p))
-#define InPortWord(p)    VideoPortReadPortUshort ((PUSHORT) (p))
-#define InPortLong(p)    VideoPortReadPortUlong  ((PULONG) (p))
-#endif
 
-
-/**********************************************************************/
-/*  WIN CE                                                            */
-/**********************************************************************/
-
-#ifdef WINCE_HEADER
-#define OutPortByte(p,v) WRITE_PORT_UCHAR ((PUCHAR) (p), (UCHAR) (v))
-#define OutPortWord(p,v) WRITE_PORT_USHORT((PUSHORT) (p), (USHORT) (v))
-#define OutPortLong(p,v) WRITE_PORT_ULONG ((PULONG) (p), (ULONG) (v))
-#define InPortByte(p)    READ_PORT_UCHAR  ((PUCHAR) (p))
-#define InPortWord(p)    READ_PORT_USHORT ((PUSHORT) (p))
-#define InPortLong(p)    READ_PORT_ULONG  ((PULONG) (p))
-#endif
diff -urN linux-2.4.22-pre2/drivers/video/sis/sis_accel.c linux-2.4.22-pre3/drivers/video/sis/sis_accel.c
--- linux-2.4.22-pre2/drivers/video/sis/sis_accel.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/sis_accel.c	2003-07-05 18:11:05.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * SiS 300/630/730/540/315/550/650/740 frame buffer driver
+ * SiS 300/630/730/540/315/550/650/740/330/660 frame buffer driver
  * for Linux kernels 2.4.x and 2.5.x
  *
  * 2D acceleration part
@@ -211,7 +211,7 @@
 	SiS300DoCMD
 }
 
-/* 310/325 series ------------------------------------------------ */
+/* 315 series ---------------------------------------------------- */
 
 static void
 SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
@@ -230,7 +230,7 @@
 		/* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
 	}
 	SiS310SetupCMDFlag(ivideo.SiS310_AccelDepth)
-	/* TW: The 310/325 series is smart enough to know the direction */
+	/* TW: The 315 series is smart enough to know the direction */
 }
 
 static void
@@ -593,38 +593,38 @@
 
 #ifdef FBCON_HAS_CFB8
 struct display_switch fbcon_sis8 = {
-	setup:			fbcon_cfb8_setup,
-	bmove:			fbcon_sis_bmove,
-	clear:			fbcon_sis_clear8,
-	putc:			fbcon_cfb8_putc,
-	putcs:			fbcon_cfb8_putcs,
-	revc:			fbcon_cfb8_revc,
-	clear_margins:		fbcon_cfb8_clear_margins,
-	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+	.setup			= fbcon_cfb8_setup,
+	.bmove			= fbcon_sis_bmove,
+	.clear			= fbcon_sis_clear8,
+	.putc			= fbcon_cfb8_putc,
+	.putcs			= fbcon_cfb8_putcs,
+	.revc			= fbcon_cfb8_revc,
+	.clear_margins		= fbcon_cfb8_clear_margins,
+	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 #ifdef FBCON_HAS_CFB16
 struct display_switch fbcon_sis16 = {
-	setup:			fbcon_cfb16_setup,
-	bmove:			fbcon_sis_bmove,
-	clear:			fbcon_sis_clear16,
-	putc:			fbcon_cfb16_putc,
-	putcs:			fbcon_cfb16_putcs,
-	revc:			fbcon_sis_revc,
-	clear_margins:		fbcon_cfb16_clear_margins,
-	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+	.setup			= fbcon_cfb16_setup,
+	.bmove			= fbcon_sis_bmove,
+	.clear			= fbcon_sis_clear16,
+	.putc			= fbcon_cfb16_putc,
+	.putcs			= fbcon_cfb16_putcs,
+	.revc			= fbcon_sis_revc,
+	.clear_margins		= fbcon_cfb16_clear_margins,
+	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 #ifdef FBCON_HAS_CFB32
 struct display_switch fbcon_sis32 = {
-	setup:			fbcon_cfb32_setup,
-	bmove:			fbcon_sis_bmove,
-	clear:			fbcon_sis_clear32,
-	putc:			fbcon_cfb32_putc,
-	putcs:			fbcon_cfb32_putcs,
-	revc:			fbcon_sis_revc,
-	clear_margins:		fbcon_cfb32_clear_margins,
-	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+	.setup			= fbcon_cfb32_setup,
+	.bmove			= fbcon_sis_bmove,
+	.clear			= fbcon_sis_clear32,
+	.putc			= fbcon_cfb32_putc,
+	.putcs			= fbcon_cfb32_putcs,
+	.revc			= fbcon_sis_revc,
+	.clear_margins		= fbcon_cfb32_clear_margins,
+	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 
diff -urN linux-2.4.22-pre2/drivers/video/sis/sis_accel.h linux-2.4.22-pre3/drivers/video/sis/sis_accel.h
--- linux-2.4.22-pre2/drivers/video/sis/sis_accel.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/sis_accel.h	2003-07-05 18:11:05.000000000 -0700
@@ -47,7 +47,7 @@
 #define TRAPAZOID_FILL          0x00000005  /* Fill trapezoid */
 #define TRANSPARENT_BITBLT      0x00000006  /* Transparent Blit */
 
-/* Additional engine commands for 310/325 */
+/* Additional engine commands for 315 */
 #define ALPHA_BLEND		0x00000007  /* Alpha blend ? */
 #define A3D_FUNCTION		0x00000008  /* 3D command ? */
 #define	CLEAR_Z_BUFFER		0x00000009  /* ? */
@@ -90,11 +90,11 @@
 #define NO_RESET_COUNTER        0x00400000
 #define NO_LAST_PIXEL           0x00200000
 
-/* Subfunctions for Color/Enhanced Color Expansion (310/325 only) */
+/* Subfunctions for Color/Enhanced Color Expansion (315 only) */
 #define COLOR_TO_MONO		0x00100000
 #define AA_TEXT			0x00200000
 
-/* Some general registers for 310/325 series */
+/* Some general registers for 315 series */
 #define SRC_ADDR		0x8200
 #define SRC_PITCH		0x8204
 #define AGP_BASE		0x8206 /* color-depth dependent value */
@@ -326,7 +326,7 @@
 
 
 
-/* ----------- SiS 310/325 series --------------- */
+/* -------------- SiS 315 series --------------- */
 
 /* Q_STATUS:
    bit 31 = 1: All engines idle and all queues empty
@@ -342,7 +342,7 @@
    bits 7:0:   2D counter 1
 
    Where is the command queue length (current amount of commands the queue
-   can accept) on the 310/325 series? (The current implementation is taken
+   can accept) on the 315 series? (The current implementation is taken
    from 300 series and certainly wrong...)
 */
 
diff -urN linux-2.4.22-pre2/drivers/video/sis/sis_main.c linux-2.4.22-pre3/drivers/video/sis/sis_main.c
--- linux-2.4.22-pre2/drivers/video/sis/sis_main.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/sis_main.c	2003-07-05 18:11:05.000000000 -0700
@@ -1,21 +1,14 @@
 /*
- * SiS 300/630/730/540/315/550/650/740 frame buffer device
+ * SiS 300/630/730/540/315/550/650/740/330/660 frame buffer device
  * for Linux kernels 2.4.x and 2.5.x
  *
+ * (C) 1999 Silicon Integrated Systems, Inc.
+ * (C) 2001-2003 Thomas Winischhofer, Vienna, Austria.
+ *
  * Authors:   	SiS (www.sis.com.tw)
- *		Thomas Winischhofer <thomas@winischhofer.net>:
- *			- SiS Xabre (330) support
- *			- many fixes and enhancements for all chipset series,
- *			- extended bridge handling, TV output for Chrontel 7005
- *                      - 650/740/LVDS support (for LCD panels up to 1600x1200)
- *                      - 650/740/Chrontel 7019 support (LCD and TV)
- *                      - 30xB/30xLV LCD, TV and VGA2 support
- *			- memory queue handling enhancements,
- *                      - 2D acceleration and y-panning,
- *                      - rewritten for 2.5 API (>= 2.5.63)
- *			- etc.
- *			(see http://www.winischhofer.net/
- *			for more information and updates)
+ *		Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * See http://www.winischhofer.net/ for more information and updates
  *
  * Originally based on the VBE 2.0 compliant graphic boards framebuffer driver,
  * which is (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
@@ -43,7 +36,6 @@
 #include <linux/fs.h>
 #include <linux/agp_backend.h>
 #include <linux/types.h>
-
 #include <asm/uaccess.h>
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
@@ -81,6 +73,12 @@
 #endif
 #endif
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
+#error "This version of sisfb requires at least 2.5.69"
+#endif
+#endif
+
 /* -------------------- Macro definitions ---------------------------- */
 
 #undef SISFBDEBUG 	/* TW: no debugging */
@@ -186,9 +184,12 @@
 		case SIS_650:
 			nbridge_id = PCI_DEVICE_ID_SI_650;
 			break;
-		case SIS_740:			
+		case SIS_740:
 			nbridge_id = PCI_DEVICE_ID_SI_740;
 			break;
+		case SIS_660:
+			nbridge_id = PCI_DEVICE_ID_SI_660;
+			break;
 		default:
 			nbridge_id = 0;
 			break;
@@ -221,61 +222,285 @@
 
 /* ------------------ Internal helper routines ----------------- */
 
-static void sisfb_search_mode(const char *name)
+static BOOLEAN sisfb_verify_rate(struct sisfb_monitor *monitor, int mode_idx, int rate_idx, int rate)
 {
-	int i = 0, j = 0;
+	int htotal, vtotal;
+	unsigned int dclock, hsync;
 
-	if(name == NULL) {
-	   printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
-	   sisfb_mode_idx = DEFAULT_MODE;
-	   return;
+	if(!monitor->datavalid) return TRUE;
+
+	if(mode_idx < 0) return FALSE;
+
+	if(rate < (monitor->vmin - 1)) return FALSE;
+	if(rate > (monitor->vmax + 1)) return FALSE;
+
+	if(sisfb_gettotalfrommode(&SiS_Pr, &sishw_ext, sisbios_mode[mode_idx].mode_no,
+	                          &htotal, &vtotal, rate_idx)) {
+		dclock = (htotal * vtotal * rate) / 1000;
+		if(dclock > (monitor->dclockmax + 1000)) return FALSE;
+		hsync = dclock / htotal;
+		if(hsync < (monitor->hmin - 1)) return FALSE;
+		if(hsync > (monitor->hmax + 1)) return FALSE;
+        } else {
+	  	return FALSE;
 	}
-		
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)		
-        if (!strcmp(name, sisbios_mode[MODE_INDEX_NONE].name)) {
-	   printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
-	   sisfb_mode_idx = DEFAULT_MODE;
-	   return;
+	return TRUE;
+};
+
+static BOOLEAN sisfb_interpret_edid(struct sisfb_monitor *monitor, unsigned char *buffer)
+{
+	int i, j, xres, yres, refresh, index;
+	u32 emodes;
+
+	if(buffer[0] != 0x00 || buffer[1] != 0xff ||
+	   buffer[2] != 0xff || buffer[3] != 0xff ||
+	   buffer[4] != 0xff || buffer[5] != 0xff ||
+	   buffer[6] != 0xff || buffer[7] != 0x00) {
+	   printk(KERN_INFO "sisfb: Bad EDID header\n");
+	   return FALSE;
 	}
-#endif		
 
-	while(sisbios_mode[i].mode_no != 0) {
-		if (!strcmp(name, sisbios_mode[i].name)) {
-			sisfb_mode_idx = i;
-			j = 1;
-			break;
-		}
-		i++;
+	if(buffer[0x12] != 0x01) {
+	   printk(KERN_INFO "sisfb: EDID version %d not supported\n",
+	   	buffer[0x12]);
+	   return FALSE;
+	}
+
+	monitor->feature = buffer[0x18];
+
+	if(!buffer[0x14] & 0x80) {
+	   if(!(buffer[0x14] & 0x08)) {
+	      printk(KERN_INFO "sisfb: WARNING: Monitor does not support separate syncs\n");
+	   }
+	}
+
+	if(buffer[0x13] >= 0x01) {
+	   /* EDID V1 rev 1 and 2: Search for monitor descriptor
+	    * to extract ranges
+	    */
+	    j = 0x36;
+	    for(i=0; i<4; i++) {
+	       if(buffer[j]     == 0x00 && buffer[j + 1] == 0x00 &&
+	          buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
+		  buffer[j + 4] == 0x00) {
+		  monitor->hmin = buffer[j + 7];
+		  monitor->hmax = buffer[j + 8];
+		  monitor->vmin = buffer[j + 5];
+		  monitor->vmax = buffer[j + 6];
+		  monitor->dclockmax = buffer[j + 9] * 10 * 1000;
+		  monitor->datavalid = TRUE;
+		  break;
+	       }
+	       j += 18;
+	    }
 	}
-	if(!j) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", name);
+
+	if(!monitor->datavalid) {
+	   /* Otherwise: Get a range from the list of supported
+	    * Estabished Timings. This is not entirely accurate,
+	    * because fixed frequency monitors are not supported
+	    * that way.
+	    */
+	   monitor->hmin = 65535; monitor->hmax = 0;
+	   monitor->vmin = 65535; monitor->vmax = 0;
+	   monitor->dclockmax = 0;
+	   emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16);
+	   for(i = 0; i < 13; i++) {
+	      if(emodes & sisfb_ddcsmodes[i].mask) {
+	         if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
+		 if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1;
+		 if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v;
+		 if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[i].v;
+		 if(monitor->dclockmax < sisfb_ddcsmodes[i].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
+	      }
+	   }
+	   index = 0x26;
+	   for(i = 0; i < 8; i++) {
+	      xres = (buffer[index] + 31) * 8;
+	      switch(buffer[index + 1] & 0xc0) {
+	         case 0xc0: yres = (xres * 9) / 16; break;
+	         case 0x80: yres = (xres * 4) /  5; break;
+	         case 0x40: yres = (xres * 3) /  4; break;
+	         default:   yres = xres;	    break;
+	      }
+	      refresh = (buffer[index + 1] & 0x3f) + 60;
+	      if((xres >= 640) && (yres >= 480)) {
+                 for(j = 0; j < 8; j++) {
+	            if((xres == sisfb_ddcfmodes[j].x) &&
+	               (yres == sisfb_ddcfmodes[j].y) &&
+		       (refresh == sisfb_ddcfmodes[j].v)) {
+		      if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h;
+		      if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1;
+		      if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v;
+		      if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v;
+		      if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
+	            }
+	         }
+	      }
+	      index += 2;
+           }
+	   if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
+	      monitor->datavalid = TRUE;
+	   }
+	}
+
+ 	return(monitor->datavalid);
 }
 
-static void sisfb_search_vesamode(unsigned int vesamode)
+static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno)
+{
+	USHORT        temp, i, realcrtno = crtno;
+   	unsigned char buffer[256];
+
+	monitor->datavalid = FALSE;
+
+	if(crtno) {
+       	   if(ivideo.vbflags & CRT2_LCD)      realcrtno = 1;
+      	   else if(ivideo.vbflags & CRT2_VGA) realcrtno = 2;
+      	   else return;
+   	}
+
+	if((sisfb_crt1off) && (!crtno)) return;
+
+    	temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine, realcrtno, 0, &buffer[0]);
+   	if((!temp) || (temp == 0xffff)) {
+      	   printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
+	   return;
+   	} else {
+      	   printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
+      	   printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
+	   	crtno + 1,
+	   	(temp & 0x1a) ? "" : "[none of the supported]",
+	   	(temp & 0x02) ? "2 " : "",
+	   	(temp & 0x08) ? "D&P" : "",
+           	(temp & 0x10) ? "FPDI-2" : "");
+      	   if(temp & 0x02) {
+	      i = 3;  /* Number of retrys */
+	      do {
+	    	 temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine,
+				     realcrtno, 1, &buffer[0]);
+	      } while((temp) && i--);
+              if(!temp) {
+	    	 if(sisfb_interpret_edid(monitor, &buffer[0])) {
+		    printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",
+		    	monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
+			monitor->dclockmax / 1000);
+		 } else {
+	       	    printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
+	    	 }
+	      } else {
+            	 printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
+	      }
+	   } else {
+	      printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n");
+	   }
+	}
+}
+
+static void sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
 {
 	int i = 0, j = 0;
 
 	if(vesamode == 0) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		sisfb_mode_idx = MODE_INDEX_NONE;
 #else
-		printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+		if(!quiet)
+		   printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
 		sisfb_mode_idx = DEFAULT_MODE;
-#endif		
+#endif
 		return;
 	}
 
 	vesamode &= 0x1dff;  /* Clean VESA mode number from other flags */
 
+	while(sisbios_mode[i++].mode_no != 0) {
+		if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
+		    (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
+		    if(sisfb_fstn) {
+		       if(sisbios_mode[i-1].mode_no == 0x50 ||
+		          sisbios_mode[i-1].mode_no == 0x56 ||
+		          sisbios_mode[i-1].mode_no == 0x53) continue;
+	            } else {
+		       if(sisbios_mode[i-1].mode_no == 0x5a ||
+		          sisbios_mode[i-1].mode_no == 0x5b) continue;
+		    }
+		    sisfb_mode_idx = i - 1;
+		    j = 1;
+		    break;
+		}
+	}
+	if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
+}
+
+static void sisfb_search_mode(char *name, BOOLEAN quiet)
+{
+	int i = 0;
+	unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
+	char strbuf[16], strbuf1[20];
+	char *nameptr = name;
+
+	if(name == NULL) {
+	   if(!quiet)
+	      printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
+	   sisfb_mode_idx = DEFAULT_MODE;
+	   return;
+	}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+        if (!strcmp(name, sisbios_mode[MODE_INDEX_NONE].name)) {
+	   if(!quiet)
+	      printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+	   sisfb_mode_idx = DEFAULT_MODE;
+	   return;
+	}
+#endif
+	if(strlen(name) <= 19) {
+	   strcpy(strbuf1, name);
+	   for(i=0; i<strlen(strbuf1); i++) {
+	      if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
+	   }
+
+	   /* This does some fuzzy mode naming detection */
+	   if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
+	      if((rate <= 32) || (depth > 32)) {
+	         j = rate; rate = depth; depth = j;
+	      }
+	      sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+	      nameptr = strbuf;
+	      ivideo.refresh_rate = sisfb_parm_rate = rate;
+	   } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
+	      sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+	      nameptr = strbuf;
+	   } else {
+	      xres = 0;
+	      if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
+	         sprintf(strbuf, "%ux%ux8", xres, yres);
+	         nameptr = strbuf;
+	      } else {
+	         sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
+	         return;
+	      }
+	   }
+	}
+
+	i = 0; j = 0;
 	while(sisbios_mode[i].mode_no != 0) {
-		if( (sisbios_mode[i].vesa_mode_no_1 == vesamode) ||
-		    (sisbios_mode[i].vesa_mode_no_2 == vesamode) ) {
-			sisfb_mode_idx = i;
-			j = 1;
-			break;
+		if(!strcmp(nameptr, sisbios_mode[i++].name)) {
+		   if(sisfb_fstn) {
+		      if(sisbios_mode[i-1].mode_no == 0x50 ||
+		         sisbios_mode[i-1].mode_no == 0x56 ||
+		         sisbios_mode[i-1].mode_no == 0x53) continue;
+	           } else {
+		      if(sisbios_mode[i-1].mode_no == 0x5a ||
+		         sisbios_mode[i-1].mode_no == 0x5b) continue;
+		   }
+		   sisfb_mode_idx = i - 1;
+		   j = 1;
+		   break;
 		}
-		i++;
 	}
-	if(!j) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
+	if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
 }
 
 static int sisfb_validate_mode(int myindex, unsigned long vbflags)
@@ -320,11 +545,17 @@
 		xres = 1400; yres = 1050;  break;		
 	case LCD_1600x1200:
 		xres = 1600; yres = 1200;  break;
-	case LCD_320x480:				/* TW: FSTN */
+	case LCD_320x480:				/* FSTN (old) */
 		xres =  320; yres =  480;  break;
+	case LCD_640x480_2:				/* FSTN (new) */
+	case LCD_640x480_3:
+		xres =  640; yres =  480;  break;
 	default:
 	        xres =    0; yres =    0;  break;
 	}
+	if(SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
+	   	xres = 1360; yres = 1024;
+	}
 	if(sisbios_mode[myindex].xres > xres) {
 	        return(-1);
 	}
@@ -335,19 +566,28 @@
 	   switch (sisbios_mode[myindex].xres) {
 	   	case 320:
 			if((sisbios_mode[myindex].yres != 200) &&
-	           	   (sisbios_mode[myindex].yres != 240) &&
-			   (sisbios_mode[myindex].yres != 480))
-		          	return -1;
-			if(sisbios_mode[myindex].yres == 480) {
-			   	if(!enable_dstn) return -1;
+	           	   (sisbios_mode[myindex].yres != 240))
+		          	return(-1);
+			if((sisbios_mode[myindex].yres == 240) ||
+			   (sisbios_mode[myindex].yres == 480)) {
+			   	if(!sisfb_fstn) {
+				   if(sisbios_mode[myindex].mode_no == 0x5a ||
+				      sisbios_mode[myindex].mode_no == 0x5b)
+					return(-1);
+			        } else {
+				   if(sisbios_mode[myindex].mode_no == 0x50 ||
+				      sisbios_mode[myindex].mode_no == 0x56 ||
+				      sisbios_mode[myindex].mode_no == 0x53)
+					return(-1);
+				}
 			}
 			break;
 		case 400:
-	       		if(sisbios_mode[myindex].yres != 300) return -1;
+	       		if(sisbios_mode[myindex].yres != 300) return(-1);
 	       		break;
 	   	case 512:
-	       		if(sisbios_mode[myindex].yres != 384) return -1;
-			if(sishw_ext.ulCRT2LCDType == LCD_1024x600) return -1;
+	       		if(sisbios_mode[myindex].yres != 384) return(-1);
+			if(sishw_ext.ulCRT2LCDType == LCD_1024x600) return(-1);
 	       		break;
 	   	case 640:
 		       	if((sisbios_mode[myindex].yres != 400) &&
@@ -355,36 +595,40 @@
 		          	return -1;
 	       		break;
 	   	case 800:
-		       	if(sisbios_mode[myindex].yres != 600) return -1;
+		       	if(sisbios_mode[myindex].yres != 600) return(-1);
 	       		break;
 	   	case 1024:
 		       	if((sisbios_mode[myindex].yres != 600) &&
 	           	   (sisbios_mode[myindex].yres != 768))
-		          	return -1;
+		          	return(-1);
 			if((sisbios_mode[myindex].yres == 600) &&
 			   (sishw_ext.ulCRT2LCDType != LCD_1024x600))
-			   	return -1;
+			   	return(-1);
 			break;
 		case 1152:
-			if((sisbios_mode[myindex].yres) != 768) return -1;
-			if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return -1;
+			if((sisbios_mode[myindex].yres) != 768) return(-1);
+			if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return(-1);
 			break;
 	   	case 1280:
 		   	if((sisbios_mode[myindex].yres != 768) &&
 	           	   (sisbios_mode[myindex].yres != 1024))
-		          	return -1;
+		          	return(-1);
 			if((sisbios_mode[myindex].yres == 768) &&
 			   (sishw_ext.ulCRT2LCDType != LCD_1280x768))
-			   	return -1;				
+			   	return(-1);
+			break;
+		case 1360:
+			if(SiS_Pr.SiS_CustomT != CUT_BARCO1366) return(-1);
+			if(sisbios_mode[myindex].yres != 1024) return(-1);
 			break;
 	   	case 1400:
-		   	if(sisbios_mode[myindex].yres != 1050) return -1;
+		   	if(sisbios_mode[myindex].yres != 1050) return(-1);
 			break;
 	   	case 1600:
-		   	if(sisbios_mode[myindex].yres != 1200) return -1;
+		   	if(sisbios_mode[myindex].yres != 1200) return(-1);
 			break;
 	   	default:
-		        return -1;		
+		        return(-1);
 	   }
 	} else {
 	   switch (sisbios_mode[myindex].xres) {
@@ -394,81 +638,87 @@
 		          	return -1;
 			break;
 		case 400:
-	       		if(sisbios_mode[myindex].yres != 300) return -1;
+	       		if(sisbios_mode[myindex].yres != 300) return(-1);
 	       		break;
 	   	case 512:
-	       		if(sisbios_mode[myindex].yres != 384) return -1;
+	       		if(sisbios_mode[myindex].yres != 384) return(-1);
 	       		break;
 	   	case 640:
 		       	if((sisbios_mode[myindex].yres != 400) &&
 	           	   (sisbios_mode[myindex].yres != 480))
-		          	return -1;
+		          	return(-1);
 	       		break;
 	   	case 800:
-		       	if(sisbios_mode[myindex].yres != 600) return -1;
+		       	if(sisbios_mode[myindex].yres != 600) return(-1);
 	       		break;
 	   	case 1024:
-		       	if(sisbios_mode[myindex].yres != 768) return -1;
+		       	if(sisbios_mode[myindex].yres != 768) return(-1);
 			break;
 	   	case 1280:
 		   	if((sisbios_mode[myindex].yres != 960) &&
+			   (sisbios_mode[myindex].yres != 768) &&
 	           	   (sisbios_mode[myindex].yres != 1024))
-		          	return -1;
-			if(sisbios_mode[myindex].yres == 960) {
-			    if(sishw_ext.ulCRT2LCDType == LCD_1400x1050) 
-			   	return -1;
+		          	return(-1);
+			if((sisbios_mode[myindex].yres == 768) ||
+			   (sisbios_mode[myindex].yres == 960)) {
+			    	if(sishw_ext.ulCRT2LCDType == LCD_1400x1050)
+			   		return(-1);
+			}
+			if(sisbios_mode[myindex].yres == 768) {
+			    	if(sishw_ext.ulCRT2LCDType == LCD_1280x960)
+			   		return(-1);
 			}
 			break;
 	   	case 1400:
-		   	if(sisbios_mode[myindex].yres != 1050) return -1;
+		   	if(sisbios_mode[myindex].yres != 1050) return(-1);
 			break;
 	   	case 1600:
-		   	if(sisbios_mode[myindex].yres != 1200) return -1;
+		   	if(sisbios_mode[myindex].yres != 1200) return(-1);
 			break;
 	   	default:
-		        return -1;		
+		        return(-1);
 	   }
 	}
 	break;
      case CRT2_TV:
 	switch (sisbios_mode[myindex].xres) {
 	case 512:
-		if(vbflags & VB_CHRONTEL) return -1;
+		if(vbflags & VB_CHRONTEL) return(-1);
+		if((vbflags & VB_SISBRIDGE) && (vbflags & TV_NTSC))
+		   	return(-1);
 		/* fall through */
 	case 640:
 	case 800:
 		break;
 	case 720:
-		if (vbflags & VB_CHRONTEL) return -1;
-		if (vbflags & TV_NTSC) {
+		if(vbflags & VB_CHRONTEL) return -1;
+		if(vbflags & TV_NTSC) {
 			if (sisbios_mode[myindex].yres != 480) {
-				return -1;
+				return(-1);
 			}
-		} else if (vbflags & TV_PAL) {
+		} else if(vbflags & TV_PAL) {
 			if (sisbios_mode[myindex].yres != 576) {
-				return -1;
+				return(-1);
 			}
 		}
 		break;
 	case 1024:
-		if (vbflags & VB_301) return -1;
-		if (vbflags & VB_CHRONTEL) {
-		    if(ivideo.chip < SIS_315H) {
+		if(vbflags & VB_301) return(-1);
+		if(vbflags & VB_CHRONTEL) {
+		    	if(ivideo.chip < SIS_315H) {
 				return(-1);
-		    }
-		}
-		if (vbflags & TV_NTSC) {
-			if(sisbios_mode[myindex].bpp == 32) {
-			       return(-1);
-			}
+		    	}
 		}
 		break;
 	default:
-		return -1;
+		return(-1);
 	}
 	break;
      case CRT2_VGA:	
-        if(sisbios_mode[myindex].xres > 1280) return -1;
+        if(sisbios_mode[myindex].xres > 1600) return(-1);
+	if(!(vbflags & (VB_301B|VB_302B))) {
+	   if(sisbios_mode[myindex].xres > 1400) return(-1);
+	}
 	break;	
      }
      return(myindex);
@@ -485,12 +735,17 @@
 		if (!strcmp(name, sis_crt2type[i].name)) {
 			sisfb_crt2type = sis_crt2type[i].type_no;
 			sisfb_tvplug = sis_crt2type[i].tvplug_no;
+			sisfb_dstn = (sis_crt2type[i].flags & FL_550_DSTN) ? 1 : 0;
+			sisfb_fstn = (sis_crt2type[i].flags & FL_550_FSTN) ? 1 : 0;
 			break;
 		}
 		i++;
 	}
 	if(sisfb_crt2type < 0)
 		printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
+        if(ivideo.chip != SIS_550) {
+	   sisfb_dstn = sisfb_fstn = 0;
+	}
 }
 
 static void sisfb_search_queuemode(const char *name)
@@ -636,32 +891,152 @@
    return(sisfbcheckvretracecrt1());
 }
 
+static int sisfb_myblank(int blank)
+{
+   u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
+   BOOLEAN backlight = TRUE;
+
+   switch(blank) {
+   case 0:	/* on */
+      sr01  = 0x00;
+      sr11  = 0x00;
+      sr1f  = 0x00;
+      cr63  = 0x00;
+      p2_0  = 0x20;
+      p1_13 = 0x00;
+      backlight = TRUE;
+      break;
+   case 1:	/* blank */
+      sr01  = 0x20;
+      sr11  = 0x00;
+      sr1f  = 0x00;
+      cr63  = 0x00;
+      p2_0  = 0x20;
+      p1_13 = 0x00;
+      backlight = TRUE;
+      break;
+   case 2:	/* no vsync */
+      sr01  = 0x20;
+      sr11  = 0x08;
+      sr1f  = 0x80;
+      cr63  = 0x40;
+      p2_0  = 0x40;
+      p1_13 = 0x80;
+      backlight = FALSE;
+      break;
+   case 3:	/* no hsync */
+      sr01  = 0x20;
+      sr11  = 0x08;
+      sr1f  = 0x40;
+      cr63  = 0x40;
+      p2_0  = 0x80;
+      p1_13 = 0x40;
+      backlight = FALSE;
+      break;
+   case 4:	/* off */
+      sr01  = 0x20;
+      sr11  = 0x08;
+      sr1f  = 0xc0;
+      cr63  = 0x40;
+      p2_0  = 0xc0;
+      p1_13 = 0xc0;
+      backlight = FALSE;
+      break;
+   default:
+      return 1;
+   }
+
+   if(ivideo.currentvbflags & VB_DISPTYPE_CRT1) {
+
+      setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
+
+      if( (!sisfb_thismonitor.datavalid) ||
+          ((sisfb_thismonitor.datavalid) &&
+           (sisfb_thismonitor.feature & 0xe0))) {
+
+	 if(sisvga_engine == SIS_315_VGA) {
+	    setSISIDXREG(SISCR, 0x63, 0xbf, cr63);
+	 }
+
+	 setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
+      }
+
+   }
+
+   if(ivideo.currentvbflags & CRT2_LCD) {
+
+      if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
+	 if(backlight) {
+	    SiS_SiS30xBLOn(&SiS_Pr, &sishw_ext);
+	 } else {
+	    SiS_SiS30xBLOff(&SiS_Pr, &sishw_ext);
+	 }
+      } else if(sisvga_engine == SIS_315_VGA) {
+	 if(ivideo.vbflags & VB_CHRONTEL) {
+	    if(backlight) {
+	       SiS_Chrontel701xBLOn(&SiS_Pr,&sishw_ext);
+	    } else {
+	       SiS_Chrontel701xBLOff(&SiS_Pr);
+	    }
+	 }
+      }
+
+      if(((sisvga_engine == SIS_300_VGA) &&
+          (ivideo.vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
+         ((sisvga_engine == SIS_315_VGA) &&
+          ((ivideo.vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
+          setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
+      }
+
+      if(sisvga_engine == SIS_300_VGA) {
+         if((ivideo.vbflags & (VB_301B|VB_302B)) &&
+            (!(ivideo.vbflags & VB_30xBDH))) {
+	    setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
+	 }
+      } else if(sisvga_engine == SIS_315_VGA) {
+         if((ivideo.vbflags & (VB_301B|VB_302B)) &&
+            (!(ivideo.vbflags & VB_30xBDH))) {
+	    setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
+	 }
+      }
+
+   } else if(ivideo.currentvbflags & CRT2_VGA) {
+
+      if(ivideo.vbflags & (VB_301B|VB_302B)) {
+         setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
+      }
+
+   }
+
+   return(0);
+}
+
 /* ----------- FBDev related routines for all series ----------- */
 
 static void sisfb_set_vparms(void)
 {
-	switch(ivideo.video_bpp) {
-        case 8:
-        	ivideo.DstColor = 0x0000;
-		ivideo.SiS310_AccelDepth = 0x00000000;
-		ivideo.video_cmap_len = 256;
-        	break;
-        case 16:
-        	ivideo.DstColor = 0x8000;
-        	ivideo.SiS310_AccelDepth = 0x00010000;
-		ivideo.video_cmap_len = 16;
-        	break;
-        case 32:
-        	ivideo.DstColor = 0xC000;
-		ivideo.SiS310_AccelDepth = 0x00020000;
-		ivideo.video_cmap_len = 16;
-            	break;
-	default:
-		ivideo.video_cmap_len = 16;
-	        printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
-		ivideo.accel = 0;
-		break;
-    	}
+   switch(ivideo.video_bpp) {
+   case 8:
+       	ivideo.DstColor = 0x0000;
+	ivideo.SiS310_AccelDepth = 0x00000000;
+	ivideo.video_cmap_len = 256;
+       	break;
+   case 16:
+       	ivideo.DstColor = 0x8000;
+       	ivideo.SiS310_AccelDepth = 0x00010000;
+	ivideo.video_cmap_len = 16;
+       	break;
+   case 32:
+       	ivideo.DstColor = 0xC000;
+	ivideo.SiS310_AccelDepth = 0x00020000;
+	ivideo.video_cmap_len = 16;
+       	break;
+   default:
+ 	ivideo.video_cmap_len = 16;
+	printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
+	ivideo.accel = 0;
+	break;
+   }
 }
 
 static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
@@ -739,6 +1114,15 @@
 	}
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	if(sisfb_thismonitor.datavalid) {
+	   if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
+	                         sisfb_rate_idx, ivideo.refresh_rate)) {
+	      printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+	   }
+	}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 	if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
 #else
 	if(isactive) {
@@ -1146,7 +1530,7 @@
 	display->ywrapstep = fix.ywrapstep;
 	display->line_length = fix.line_length;
 	display->next_line = fix.line_length;
-	display->can_soft_blank = 0;
+	display->can_soft_blank = 1;
 	display->inverse = sisfb_inverse;
 	display->var = *var;
 
@@ -1219,9 +1603,10 @@
 	else
 		*var = fb_display[con].var;
 
- 	/* For FSTN, DSTN */
-	if (var->xres == 320 && var->yres == 480)
+	if(sisfb_fstn) {
+	   if (var->xres == 320 && var->yres == 480)
 		var->yres = 240;
+        }
 
 	return 0;
 }
@@ -1434,20 +1819,7 @@
 
 static void sisfb_blank(int blank, struct fb_info *info)
 {
-	u8 reg;
-
-	if(sisfb_bridgeisslave()) return;
-
-	inSISIDXREG(SISCR, 0x17, reg);
-
-	if(blank > 0)
-		reg &= 0x7f;
-	else
-		reg |= 0x80;
-
-        outSISIDXREG(SISCR, 0x17, reg);
-	outSISIDXREG(SISSR, 0x00, 0x01);    /* Synchronous Reset */
-	outSISIDXREG(SISSR, 0x00, 0x03);    /* End Reset */
+	sisfb_myblank(blank);
 }
 #endif
 
@@ -1606,7 +1978,7 @@
 	}
 
 	if( ((ivideo.vbflags & VB_LVDS) ||			/* Slave modes on LVDS and 301B-DH */
-	     ((ivideo.vbflags & VB_301BDH) && (ivideo.currentvbflags & CRT2_LCD))) &&
+	     ((ivideo.vbflags & VB_30xBDH) && (ivideo.currentvbflags & CRT2_LCD))) &&
 	    (var->bits_per_pixel == 8) ) {
 	    	refresh_rate = 60;
 		recalc_clock = TRUE;
@@ -1639,9 +2011,10 @@
 		recalc_clock = TRUE;
 	}
 
+	myrateindex = sisfb_search_refresh_rate(refresh_rate, search_idx);
+
 	/* Eventually recalculate timing and clock */
 	if(recalc_clock) {
-	   myrateindex = sisfb_search_refresh_rate(refresh_rate, search_idx);
 	   if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
 	   var->pixclock = (u32) (1E12 / sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
 						sisbios_mode[search_idx].mode_no, myrateindex));
@@ -1656,6 +2029,13 @@
 	   }
 	}
 
+	if(sisfb_thismonitor.datavalid) {
+	   if(!sisfb_verify_rate(&sisfb_thismonitor, search_idx,
+	                         myrateindex, refresh_rate)) {
+	      printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+	   }
+	}
+
 	/* Adapt RGB settings */
 	sisfb_bpp_to_var(var);	
 	
@@ -1782,21 +2162,7 @@
 
 static int sisfb_blank(int blank, struct fb_info *info)
 {
-	u8 reg;
-
-	if(sisfb_bridgeisslave()) return 1;
-
-	inSISIDXREG(SISCR, 0x17, reg);
-
-	if(blank > 0)
-		reg &= 0x7f;
-	else
-		reg |= 0x80;
-
-        outSISIDXREG(SISCR, 0x17, reg);
-	outSISIDXREG(SISSR, 0x00, 0x01);    /* Synchronous Reset */
-	outSISIDXREG(SISSR, 0x00, 0x03);    /* End Reset */
-        return(0);
+	return(sisfb_myblank(blank));
 }
 
 #endif
@@ -1814,36 +2180,43 @@
 		       struct fb_info *info)
 #endif
 {
-	struct sis_memreq req;
-   	struct ap_data ap;
-	unsigned long a;
-	
+	struct sis_memreq sismemreq;
+	struct ap_data sisapdata;
+	unsigned long sismembase = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	SIS_GLYINFO sisglyinfo;
+#endif
+
 	switch (cmd) {
 	   case FBIO_ALLOC:
-		if (!capable(CAP_SYS_RAWIO))
+		if(!capable(CAP_SYS_RAWIO))
 			return -EPERM;
-		if (copy_from_user(&req, (void *)arg, sizeof(req)))
-			return -EFAULT;
-		sis_malloc(&req);
-		if (copy_to_user((void *)arg, &req, sizeof(req)))
-			return -EFAULT;
+		if(copy_from_user(&sismemreq, (void *)arg, sizeof(sismemreq)))
+		   	return -EFAULT;
+        	sis_malloc(&sismemreq);
+		if(copy_to_user((void *)arg, &sismemreq, sizeof(sismemreq))) {
+			sis_free(sismemreq.offset);
+		    	return -EFAULT;
+		}
 		break;
 	   case FBIO_FREE:
-		if (!capable(CAP_SYS_RAWIO))
+		if(!capable(CAP_SYS_RAWIO))
 			return -EPERM;
-		if(get_user(a, (unsigned long *) arg))
+		if(get_user(sismembase, (unsigned long *) arg))
 			return -EFAULT;
-		sis_free(a);
+		sis_free(sismembase);
 		break;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 	   case FBIOGET_GLYPH:
-                sis_get_glyph(info,(SIS_GLYINFO *) arg);
+	        if(copy_from_user(&sisglyinfo, (void *)arg, sizeof(sisglyinfo)))
+			return -EFAULT;
+                sis_get_glyph(info, &sisglyinfo);
 		break;
 	   case FBIOPUT_MODEINFO:
 		{
 			struct mode_info x;
-			
-			if(copy_from_user(&x, (void *)arg, sizeof(struct mode_info)))
+
+			if(copy_from_user(&x, (void *)arg, sizeof(x)))
 				return -EFAULT;
 
 			ivideo.video_bpp        = x.bpp;
@@ -1861,24 +2234,24 @@
 #endif
 	   case FBIOGET_HWCINFO:
 		{
-			unsigned long *hwc_offset = (unsigned long *) arg;
+			unsigned long myhwcoffset = 0;
 
-			if (sisfb_caps & HW_CURSOR_CAP)
-				return put_user(sisfb_hwcursor_vbase -
-				    (unsigned long) ivideo.video_vbase, hwc_offset);
-			else
-				return put_user(0, hwc_offset);
+			if(sisfb_caps & HW_CURSOR_CAP)
+				myhwcoffset = sisfb_hwcursor_vbase -
+				    (unsigned long) ivideo.video_vbase;
+
+			return put_user(myhwcoffset, (unsigned long *)arg);
+
+			break;
 		}
 	   case FBIOGET_DISPINFO:
-	   	if(copy_from_user(&ap, (void *)arg, sizeof(struct ap_data)))
-	   		return -EFAULT;
-		sis_dispinfo(&ap);
-	   	if(copy_to_user((void *)arg, &ap, sizeof(struct ap_data)))
-	   		return -EFAULT;
+	   	sis_dispinfo(&sisapdata);
+		if(copy_to_user((void *)arg, &sisapdata, sizeof(sisapdata)))
+			return -EFAULT;
 		break;
-	   case SISFB_GET_INFO:  /* TW: New for communication with X driver */
+	   case SISFB_GET_INFO:  /* New for communication with X driver */
 	        {
-	        	sisfb_info x;
+			sisfb_info x;
 
 			x.sisfb_id = SISFB_ID;
 			x.sisfb_version = VER_MAJOR;
@@ -1897,18 +2270,17 @@
 			x.sisfb_lcda = sisfb_detectedlcda;
 			x.sisfb_vbflags = ivideo.vbflags;
 			x.sisfb_currentvbflags = ivideo.currentvbflags;
-			
-			if(copy_to_user((void *)arg, &x, sizeof(sisfb_info)))
+			if(copy_to_user((void *)arg, &x, sizeof(x)))
 				return -EFAULT;
 	                break;
 		}
 	   case SISFB_GET_VBRSTATUS:
 	        {
-			unsigned long *vbrstatus = (unsigned long *) arg;
 			if(sisfb_CheckVBRetrace())
-				return put_user(1, vbrstatus);
+				return put_user(1UL, (unsigned long *) arg);
 			else
-				return put_user(0, vbrstatus);
+				return put_user(0UL, (unsigned long *) arg);
+			break;
 		}
 	   default:
 		return -EINVAL;
@@ -1931,12 +2303,16 @@
 	fix->smem_start = ivideo.video_base;
 
         if((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
-	    if (ivideo.video_size > 0x1000000) {
-	        fix->smem_len = 0xc00000;
-	    } else if (ivideo.video_size > 0x800000)
-		fix->smem_len = 0x800000;
-	    else
-		fix->smem_len = 0x400000;
+	    if(sisvga_engine == SIS_300_VGA) {
+	       if(ivideo.video_size > 0x1000000) {
+	          	fix->smem_len = 0xc00000;
+	       } else if(ivideo.video_size > 0x800000)
+		  	fix->smem_len = 0x800000;
+	       else
+		  	fix->smem_len = 0x400000;
+            } else {
+	       	fix->smem_len = ivideo.video_size - 0x100000;
+	    }
         } else
 		fix->smem_len = sisfb_mem * 1024;
 
@@ -1956,16 +2332,16 @@
 	fix->mmio_len    = sisfb_mmio_size;
 	if(sisvga_engine == SIS_300_VGA) 
 	   fix->accel    = FB_ACCEL_SIS_GLAMOUR;
-	else if(ivideo.chip == SIS_330)
+	else if((ivideo.chip == SIS_330) || (ivideo.chip == SIS_660))
 	   fix->accel    = FB_ACCEL_SIS_XABRE;
-	else 
+	else
 	   fix->accel    = FB_ACCEL_SIS_GLAMOUR_2;
-	
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 	fix->reserved[0] = ivideo.video_size & 0xFFFF;
 	fix->reserved[1] = (ivideo.video_size >> 16) & 0xFFFF;
 	fix->reserved[2] = sisfb_caps;
-#endif	
+#endif
 
 	return 0;
 }
@@ -1974,15 +2350,15 @@
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 static struct fb_ops sisfb_ops = {
-	owner:		THIS_MODULE,
-	fb_get_fix:	sisfb_get_fix,
-	fb_get_var:	sisfb_get_var,
-	fb_set_var:	sisfb_set_var,
-	fb_get_cmap:	sisfb_get_cmap,
-	fb_set_cmap:	sisfb_set_cmap,
-        fb_pan_display:	sisfb_pan_display,
-	fb_ioctl:	sisfb_ioctl,
-	fb_mmap:	sisfb_mmap,
+	.owner		= THIS_MODULE,
+	.fb_get_fix	= sisfb_get_fix,
+	.fb_get_var	= sisfb_get_var,
+	.fb_set_var	= sisfb_set_var,
+	.fb_get_cmap	= sisfb_get_cmap,
+	.fb_set_cmap	= sisfb_set_cmap,
+        .fb_pan_display = sisfb_pan_display,
+	.fb_ioctl	= sisfb_ioctl,
+	.fb_mmap	= sisfb_mmap,
 };
 #endif
 
@@ -2094,7 +2470,10 @@
 	u8  pci_data;
 	u8  reg = 0;
 
-	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
+	if (ivideo.chip == SIS_550 ||
+	    ivideo.chip == SIS_650 ||
+	    ivideo.chip == SIS_740 ||
+	    ivideo.chip == SIS_660) {
 
 #ifdef LINUXBIOS
 
@@ -2103,7 +2482,8 @@
 			if ( (pdev->vendor == PCI_VENDOR_ID_SI)
 				&& ( (pdev->device == PCI_DEVICE_ID_SI_550) ||
 				     (pdev->device == PCI_DEVICE_ID_SI_650) ||
-				     (pdev->device == PCI_DEVICE_ID_SI_740))) {
+				     (pdev->device == PCI_DEVICE_ID_SI_740) ||
+				     (pdev->device == PCI_DEVICE_ID_SI_660))) {
 				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
 				                     &pci_data);
 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
@@ -2294,14 +2674,16 @@
 			 *     [4] AVIDEO  [5] SVIDEO
 			 */
 
+#if 0
 			if (sr17 & 0x01) orSISIDXREG(SISCR, 0x32, SIS_CRT1);
 			else		 andSISIDXREG(SISCR, 0x32, ~SIS_CRT1);
-		
+
 			if (sr17 & 0x02) orSISIDXREG(SISCR, 0x32, SIS_VB_LCD);
 			else		 andSISIDXREG(SISCR, 0x32, ~SIS_VB_LCD);
-		
+
 			/* no HiVision and no DVI connector here */
 			andSISIDXREG(SISCR, 0x32, ~0xc0);
+#endif
 		
 			/* PAL/NTSC is stored on SR16 on such machines */
 			if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
@@ -2355,7 +2737,7 @@
 				ivideo.vbflags |= TV_PAL;
 			else
 				ivideo.vbflags |= TV_NTSC;
-		} else if((ivideo.chip <= SIS_315PRO) || (ivideo.chip >= SIS_330)) {
+		} else if((ivideo.chip <= SIS_315PRO) || (ivideo.chip == SIS_330)) {
 
                 	inSISIDXREG(SISCR, 0x38, temp);
 			if(temp & 0x10)
@@ -2379,29 +2761,22 @@
 		else                sisfb_crt1off = 1;
     	}
 
-	if(enable_dstn) {
-		ivideo.vbflags &= ~(CRT2_TV | CRT2_VGA);
-		ivideo.vbflags |= CRT2_LCD;
-	}
 }
 
 static void sisfb_get_VB_type(void)
 {
 	u8 vb_chipid;
 	u8 reg;
+	char stdstr[]    = "sisfb: Detected";
+	char bridgestr[] = "video bridge";
+	char lvdsstr[]   = "LVDS transmitter";
+  	char chrstr[]    = "Chrontel TV encoder";
 	
 	ivideo.hasVB = HASVB_NONE;
 	sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
 	sishw_ext.Is301BDH = FALSE;
 	sishw_ext.usExternalChip = 0;
 
-	if(enable_dstn) {
-		ivideo.hasVB = HASVB_LVDS;
-		ivideo.vbflags |= VB_LVDS;
-		sishw_ext.usExternalChip = 0x01;
-		return;
-	}
-
 	inSISIDXREG(SISPART4, 0x00, vb_chipid);
 	switch (vb_chipid) {
 	   case 0x01:
@@ -2410,19 +2785,19 @@
 		if(reg < 0xb0) { 
 			ivideo.vbflags |= VB_301;
 			sishw_ext.ujVBChipID = VB_CHIP_301;
-			printk(KERN_INFO "sisfb: Detected SiS301 video bridge\n");
+			printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
 		} else if(reg < 0xd0) {
 		 	ivideo.vbflags |= VB_301B;
 			sishw_ext.ujVBChipID = VB_CHIP_301B;
-			printk(KERN_INFO "sisfb: Detected SiS301B video bridge\n");
+			printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
 		} else if(reg < 0xe0) {
 			ivideo.vbflags |= VB_301LV;
 			sishw_ext.ujVBChipID = VB_CHIP_301LV;
-			printk(KERN_INFO "sisfb: Detected SiS301LV video bridge\n");
+			printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
 		} else if(reg <= 0xe1) {
 			ivideo.vbflags |= VB_302LV;
 			sishw_ext.ujVBChipID = VB_CHIP_302LV;
-			printk(KERN_INFO "sisfb: Detected SiS302LV video bridge\n");
+			printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
 		}
 		break;
 	   case 0x02:
@@ -2431,15 +2806,15 @@
 		if(reg < 0xd0) {
 			ivideo.vbflags |= VB_302B;
 			sishw_ext.ujVBChipID = VB_CHIP_302B;
-			printk(KERN_INFO "sisfb: Detected SiS302B video bridge\n");
+			printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
 		} else if(reg < 0xe0) {
 		 	ivideo.vbflags |= VB_301LV;
 			sishw_ext.ujVBChipID = VB_CHIP_301LV;
-			printk(KERN_INFO "sisfb: Detected SiS301LV video bridge\n");
+			printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
 		} else if(reg <= 0xe1) {
 			ivideo.vbflags |= VB_302LV;
 			sishw_ext.ujVBChipID = VB_CHIP_302LV;
-			printk(KERN_INFO "sisfb: Detected SiS302LV video bridge\n");
+			printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
 		}
 		break;
 	}
@@ -2449,6 +2824,7 @@
 		if(!(reg & 0x02)) {
 			sishw_ext.Is301BDH = TRUE;
 			ivideo.vbflags |= VB_30xBDH;
+			printk(KERN_INFO "This %s does not support LCD output\n", bridgestr);
 		}
 	}
 	
@@ -2462,25 +2838,25 @@
 				ivideo.hasVB = HASVB_LVDS;
 				ivideo.vbflags |= VB_LVDS;
 				sishw_ext.usExternalChip = 0x01;
-				printk(KERN_INFO "sisfb: Detected LVDS transmitter\n");
+				printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
 				break;
 			   case SIS_EXTERNAL_CHIP_TRUMPION:
 				ivideo.hasVB = HASVB_TRUMPION;
 				ivideo.vbflags |= VB_TRUMPION;
 				sishw_ext.usExternalChip = 0x02;
-				printk(KERN_INFO "sisfb: Detected Trumpion LCD scaler\n");
+				printk(KERN_INFO "%s Trumpion LCD scaler\n", stdstr);
 				break;	   
 			   case SIS_EXTERNAL_CHIP_CHRONTEL:
 				ivideo.hasVB = HASVB_CHRONTEL;
 				ivideo.vbflags |= VB_CHRONTEL;
 				sishw_ext.usExternalChip = 0x04;
-				printk(KERN_INFO "sisfb: Detected Chrontel TV encoder\n");
+				printk(KERN_INFO "%s %s\n", stdstr, chrstr);
 				break;
 			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
 				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
 				ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
 				sishw_ext.usExternalChip = 0x05;
-				printk(KERN_INFO "sisfb: Detected LVDS transmitter and Chrontel TV encoder\n");
+				printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
 				break;
 			}
 		} else {
@@ -2489,14 +2865,14 @@
 				ivideo.hasVB = HASVB_LVDS;
 				ivideo.vbflags |= VB_LVDS;
 				sishw_ext.usExternalChip = 0x01;
-				printk(KERN_INFO "sisfb: Detected LVDS transmitter\n");
+				printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
 				break;
 		   	   case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
 				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
 				ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
 				sishw_ext.usExternalChip = 0x05;
-				printk(KERN_INFO "sisfb: Detected Chrontel LVDS transmitter and TV encoder\n");
-				break;	
+				printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
+				break;
 			}
 		}
 	
@@ -2526,24 +2902,29 @@
     inSISIDXREG(SISPART4,0x03,temp);
     temp ^= 0x0e;
     temp &= tempch;
-    return(temp);
+    return((temp == tempch));
 }
 
 void
 SiS_Sense30x(void)
 {
-  u8 backupP4_0d;
+  u8 backupP4_0d,backupP2_00;
   u8 testsvhs_tempbl, testsvhs_tempbh;
   u8 testsvhs_tempcl, testsvhs_tempch;
   u8 testcvbs_tempbl, testcvbs_tempbh;
   u8 testcvbs_tempcl, testcvbs_tempch;
   u8 testvga2_tempbl, testvga2_tempbh;
   u8 testvga2_tempcl, testvga2_tempch;
-  int myflag, result;
+  int myflag, result, haveresult, i, j;
+  char stdstr[] = "sisfb: Detected";
+  char tvstr[]  = "TV connected to";
 
   inSISIDXREG(SISPART4,0x0d,backupP4_0d);
   outSISIDXREG(SISPART4,0x0d,(backupP4_0d | 0x04));
 
+  inSISIDXREG(SISPART2,0x00,backupP2_00);
+  outSISIDXREG(SISPART2,0x00,(backupP2_00 | 0x1c));
+
   if(sisvga_engine == SIS_300_VGA) {
 
 	if(ivideo.vbflags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) {
@@ -2562,7 +2943,7 @@
 	   testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
 	}
 	testvga2_tempch = 0x0e;	testvga2_tempcl = 0x08;
-	testsvhs_tempch = 0x06;	testsvhs_tempcl = 0x04;
+	testsvhs_tempch = 0x04;	testsvhs_tempcl = 0x04;
 	testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
 	if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
 	   	testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
@@ -2606,38 +2987,61 @@
 	   testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08;
 	} else {
 	   testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
-	   testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
+	   testsvhs_tempch = 0x04; testsvhs_tempcl = 0x04;
 	   testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
 	}
     } 
 
     if(testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) {
-        result = SISDoSense(testvga2_tempbl, testvga2_tempbh,
-                            testvga2_tempcl, testvga2_tempch);
- 	if(result) {
-        	printk(KERN_INFO "sisfb: Detected secondary VGA connection\n");
-		orSISIDXREG(SISCR, 0x32, 0x10);
-	} else {
-		andSISIDXREG(SISCR, 0x32, ~0x10);
-	}
+       haveresult = 0;
+       for(j = 0; j < 10; j++) {
+          result = 0;
+          for(i = 0; i < 3; i++) {
+             if(SISDoSense(testvga2_tempbl, testvga2_tempbh,
+                           testvga2_tempcl, testvga2_tempch))
+	        result++;
+          }
+	  if((result == 0) || (result >= 2)) break;
+       }
+       if(result) {
+          printk(KERN_INFO "%s secondary VGA connection\n", stdstr);
+	  orSISIDXREG(SISCR, 0x32, 0x10);
+       } else {
+	  andSISIDXREG(SISCR, 0x32, ~0x10);
+       }
+    }
+
+    haveresult = 0;
+    for(j = 0; j < 10; j++) {
+       result = 0;
+       for(i = 0; i < 3; i++) {
+          if(SISDoSense(testsvhs_tempbl, testsvhs_tempbh,
+                        testsvhs_tempcl, testsvhs_tempch))
+	        result++;
+       }
+       if((result == 0) || (result >= 2)) break;
     }
-    
-    result = SISDoSense(testsvhs_tempbl, testsvhs_tempbh,
-                        testsvhs_tempcl, testsvhs_tempch);
     if(result) {
-        printk(KERN_INFO "sisfb: Detected TV connected to SVIDEO output\n");
-        /* TW: So we can be sure that there IS a SVHS output */
+        printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr);
 	ivideo.vbflags |= TV_SVIDEO;
 	orSISIDXREG(SISCR, 0x32, 0x02);
 	andSISIDXREG(SISCR, 0x32, ~0x05);
     }
 
     if(!result) {
-        result = SISDoSense(testcvbs_tempbl, testcvbs_tempbh,
-	                    testcvbs_tempcl, testcvbs_tempch);
+
+	haveresult = 0;
+       	for(j = 0; j < 10; j++) {
+           result = 0;
+           for(i = 0; i < 3; i++) {
+              if(SISDoSense(testcvbs_tempbl, testcvbs_tempbh,
+	                    testcvbs_tempcl, testcvbs_tempch))
+	        result++;
+           }
+           if((result == 0) || (result >= 2)) break;
+        }
 	if(result) {
-	    printk(KERN_INFO "sisfb: Detected TV connected to CVBS output\n");
-	    /* TW: So we can be sure that there IS a CVBS output */
+	    printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr);
 	    ivideo.vbflags |= TV_AVIDEO;
 	    orSISIDXREG(SISCR, 0x32, 0x01);
 	    andSISIDXREG(SISCR, 0x32, ~0x06);
@@ -2647,6 +3051,7 @@
     }
     SISDoSense(0, 0, 0, 0);
 
+    outSISIDXREG(SISPART2,0x00,backupP2_00);
     outSISIDXREG(SISPART4,0x0d,backupP4_0d);
 }
 
@@ -2655,38 +3060,65 @@
 SiS_SenseCh(void)
 {
 
-   u8 temp1;
-#ifdef CONFIG_FB_SIS_315
-   u8 temp2;
+   u8 temp1, temp2;
+#ifdef CONFIG_FB_SIS_300
+   unsigned char test[3];
+   int i;
 #endif
+   char stdstr[] = "sisfb: Chrontel: Detected TV connected to";
 
    if(ivideo.chip < SIS_315H) {
 
 #ifdef CONFIG_FB_SIS_300
-       SiS_Pr.SiS_IF_DEF_CH70xx = 1;		/* TW: Chrontel 7005 */
+       SiS_Pr.SiS_IF_DEF_CH70xx = 1;		/* Chrontel 700x */
+       SiS_SetChrontelGPIO(&SiS_Pr, 0x9c);	/* Set general purpose IO for Chrontel communication */
+       SiS_DDC2Delay(&SiS_Pr, 1000);
        temp1 = SiS_GetCH700x(&SiS_Pr, 0x25);
-       if ((temp1 >= 50) && (temp1 <= 100)) {
-	   /* TW: Read power status */
+       /* TW: See Chrontel TB31 for explanation */
+       temp2 = SiS_GetCH700x(&SiS_Pr, 0x0e);
+       if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
+	  SiS_SetCH700x(&SiS_Pr, 0x0b0e);
+	  SiS_DDC2Delay(&SiS_Pr, 300);
+       }
+       temp2 = SiS_GetCH700x(&SiS_Pr, 0x25);
+       if(temp2 != temp1) temp1 = temp2;
+
+       if((temp1 >= 0x22) && (temp1 <= 0x50)) {
+	   /* Read power status */
 	   temp1 = SiS_GetCH700x(&SiS_Pr, 0x0e);
 	   if((temp1 & 0x03) != 0x03) {
-     	        /* TW: Power all outputs */
-		SiS_SetCH70xxANDOR(&SiS_Pr, 0x030E,0xF8);
+     	        /* Power all outputs */
+		SiS_SetCH700x(&SiS_Pr, 0x0B0E);
+		SiS_DDC2Delay(&SiS_Pr, 300);
 	   }
-	   /* TW: Sense connected TV devices */
-	   SiS_SetCH700x(&SiS_Pr, 0x0110);
-	   SiS_SetCH700x(&SiS_Pr, 0x0010);
-	   temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
-	   if(!(temp1 & 0x08)) {
-		printk(KERN_INFO
-		   "sisfb: Chrontel: Detected TV connected to SVIDEO output\n");
-		/* TW: So we can be sure that there IS a SVHS output */
+	   /* Sense connected TV devices */
+	   for(i = 0; i < 3; i++) {
+	       SiS_SetCH700x(&SiS_Pr, 0x0110);
+	       SiS_DDC2Delay(&SiS_Pr, 0x96);
+	       SiS_SetCH700x(&SiS_Pr, 0x0010);
+	       SiS_DDC2Delay(&SiS_Pr, 0x96);
+	       temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
+	       if(!(temp1 & 0x08))       test[i] = 0x02;
+	       else if(!(temp1 & 0x02))  test[i] = 0x01;
+	       else                      test[i] = 0;
+	       SiS_DDC2Delay(&SiS_Pr, 0x96);
+	   }
+
+	   if(test[0] == test[1])      temp1 = test[0];
+	   else if(test[0] == test[2]) temp1 = test[0];
+	   else if(test[1] == test[2]) temp1 = test[1];
+	   else {
+	   	printk(KERN_INFO
+			"sisfb: TV detection unreliable - test results varied\n");
+		temp1 = test[2];
+	   }
+	   if(temp1 == 0x02) {
+		printk(KERN_INFO "%s SVIDEO output\n", stdstr);
 		ivideo.vbflags |= TV_SVIDEO;
 		orSISIDXREG(SISCR, 0x32, 0x02);
 		andSISIDXREG(SISCR, 0x32, ~0x05);
-	   } else if (!(temp1 & 0x02)) {
-		printk(KERN_INFO
-		   "sisfb: Chrontel: Detected TV connected to CVBS output\n");
-		/* TW: So we can be sure that there IS a CVBS output */
+	   } else if (temp1 == 0x01) {
+		printk(KERN_INFO "%s CVBS output\n", stdstr);
 		ivideo.vbflags |= TV_AVIDEO;
 		orSISIDXREG(SISCR, 0x32, 0x01);
 		andSISIDXREG(SISCR, 0x32, ~0x06);
@@ -2698,12 +3130,14 @@
 	  SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
 	  andSISIDXREG(SISCR, 0x32, ~0x07);
        }
+       /* Set general purpose IO for Chrontel communication */
+       SiS_SetChrontelGPIO(&SiS_Pr, 0x00);
 #endif
 
    } else {
 
 #ifdef CONFIG_FB_SIS_315
-	SiS_Pr.SiS_IF_DEF_CH70xx = 2;		/* TW: Chrontel 7019 */
+	SiS_Pr.SiS_IF_DEF_CH70xx = 2;		/* Chrontel 7019 */
         temp1 = SiS_GetCH701x(&SiS_Pr, 0x49);
 	SiS_SetCH701x(&SiS_Pr, 0x2049);
 	SiS_DDC2Delay(&SiS_Pr, 0x96);
@@ -2723,22 +3157,19 @@
 	if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04;
 	switch(temp1) {
 	case 0x01:
-	     printk(KERN_INFO
-		"sisfb: Chrontel: Detected TV connected to CVBS output\n");
+	     printk(KERN_INFO "%s CVBS output\n", stdstr);
 	     ivideo.vbflags |= TV_AVIDEO;
 	     orSISIDXREG(SISCR, 0x32, 0x01);
 	     andSISIDXREG(SISCR, 0x32, ~0x06);
              break;
 	case 0x02:
-	     printk(KERN_INFO
-		"sisfb: Chrontel: Detected TV connected to SVIDEO output\n");
+	     printk(KERN_INFO "%s SVIDEO output\n", stdstr);
 	     ivideo.vbflags |= TV_SVIDEO;
 	     orSISIDXREG(SISCR, 0x32, 0x02);
 	     andSISIDXREG(SISCR, 0x32, ~0x05);
              break;
 	case 0x04:
-	     printk(KERN_INFO
-		"sisfb: Chrontel: Detected TV connected to SCART output\n");
+	     printk(KERN_INFO "%s SCART output\n", stdstr);
 	     orSISIDXREG(SISCR, 0x32, 0x04);
 	     andSISIDXREG(SISCR, 0x32, ~0x03);		
              break;
@@ -2780,14 +3211,20 @@
  *     in XF86Config-4.
  *     The heap start can also be specified by parameter "mem" when starting the sisfb
  *     driver. sisfb mem=1024 lets heap starts at 1MB, etc.
+ *     On the 315 series, the default is a 1MB heap since DRI is not supported
+ *     there.
  */
      if ((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
-        if (ivideo.video_size > 0x1000000) {
+        if(sisvga_engine == SIS_300_VGA) {
+           if (ivideo.video_size > 0x1000000) {
 	        ivideo.heapstart = 0xc00000;
-	} else if (ivideo.video_size > 0x800000) {
+	   } else if (ivideo.video_size > 0x800000) {
 	        ivideo.heapstart = 0x800000;
-	} else {
+	   } else {
 		ivideo.heapstart = 0x400000;
+	   }
+	} else {
+	   ivideo.heapstart = ivideo.video_size - 0x100000;
 	}
      } else {
            ivideo.heapstart = sisfb_mem * 1024;
@@ -2803,7 +3240,7 @@
 #ifdef CONFIG_FB_SIS_315
      if (sisvga_engine == SIS_315_VGA) {
         /* TW: Now initialize the 310 series' command queue mode.
-	 * On 310/325, there are three queue modes available which
+	 * On 315, there are three queue modes available which
 	 * are chosen by setting bits 7:5 in SR26:
 	 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
 	 *    track of the queue, the FIFO, command parsing and so
@@ -3253,7 +3690,6 @@
 		req->offset = poh->offset;
 		req->size = poh->size;
 	}
-
 }
 
 void sis_free(unsigned long base)
@@ -3282,6 +3718,9 @@
 	
 	cr33 = sisfb_rate_idx & 0x0F;
 
+	SiS_SetEnableDstn(&SiS_Pr, FALSE);
+	SiS_SetEnableFstn(&SiS_Pr, FALSE);
+
 	switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
 	   case CRT2_TV:
 		ivideo.disp_state = DISPTYPE_TV;
@@ -3321,6 +3760,8 @@
 		ivideo.disp_state = DISPTYPE_LCD;
 		cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		cr31 |= SIS_DRIVER_MODE;
+		SiS_SetEnableDstn(&SiS_Pr, sisfb_dstn);
+	        SiS_SetEnableFstn(&SiS_Pr, sisfb_fstn);
 		break;		
 	   case CRT2_VGA:
 		ivideo.disp_state = DISPTYPE_CRT2;
@@ -3349,46 +3790,77 @@
 static void sisfb_post_setmode(void)
 {
 	u8 reg;
+	BOOLEAN crt1isoff = FALSE;
+#ifdef CONFIG_FB_SIS_315
+	u8 reg1;
+#endif
+#ifdef CONFIG_FB_SIS_300
 	BOOLEAN doit = TRUE;
-
+#endif
 	/* TW: We can't switch off CRT1 if bridge is in slave mode */
 	if(ivideo.vbflags & VB_VIDEOBRIDGE) {
-		inSISIDXREG(SISPART1, 0x00, reg);
+#ifdef CONFIG_FB_SIS_300
 		if(sisvga_engine == SIS_300_VGA) {
+			inSISIDXREG(SISPART1, 0x00, reg);
 			if((reg & 0xa0) == 0x20) {
 				doit = FALSE;
 			}
 		}
-		if(sisvga_engine == SIS_315_VGA) {
-			if((reg & 0x50) == 0x10) {
-				doit = FALSE;
-			}
-		}
+#endif
 	} else sisfb_crt1off = 0;
 
-	inSISIDXREG(SISCR, 0x17, reg);
-	if((sisfb_crt1off) && (doit)) {
-		reg &= ~0x80;
-		ivideo.currentvbflags |= VB_SINGLE_MODE;
-		ivideo.disp_state |= DISPMODE_SINGLE;
+	if(sisvga_engine == SIS_300_VGA) {
+
+#ifdef CONFIG_FB_SIS_300
+	   if((sisfb_crt1off) && (doit)) {
+	        crt1isoff = TRUE;
+		reg = 0x00;
+	   } else {
+	        crt1isoff = FALSE;
+		reg = 0x80;
+	   }
+	   setSISIDXREG(SISCR, 0x17, 0x7f, reg);
+#endif
+
 	} else {
-		reg |= 0x80;
-		ivideo.currentvbflags |= VB_DISPTYPE_CRT1;
-		ivideo.disp_state |= DISPTYPE_CRT1;
-		if(ivideo.currentvbflags & VB_DISPTYPE_CRT2) {
-		   	ivideo.currentvbflags |= VB_MIRROR_MODE;
-			ivideo.disp_state |= DISPMODE_MIRROR;
-		} else {
-			ivideo.currentvbflags |= VB_SINGLE_MODE;
-			ivideo.disp_state |= DISPMODE_SINGLE;
-		}
+
+#ifdef CONFIG_FB_SIS_315
+	   if(sisfb_crt1off) {
+	        crt1isoff = TRUE;
+		reg  = 0x40;
+		reg1 = 0xc0;
+	   } else {
+	        crt1isoff = FALSE;
+		reg  = 0x00;
+		reg1 = 0x00;
+
+	   }
+	   setSISIDXREG(SISCR, 0x63, ~0x40, reg);
+	   setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
+#endif
+
+	}
+
+	if(crt1isoff) {
+	   ivideo.currentvbflags &= ~VB_DISPTYPE_CRT1;
+	   ivideo.currentvbflags |= VB_SINGLE_MODE;
+	   ivideo.disp_state |= DISPMODE_SINGLE;
+	} else {
+	   ivideo.currentvbflags |= VB_DISPTYPE_CRT1;
+	   ivideo.disp_state |= DISPTYPE_CRT1;
+	   if(ivideo.currentvbflags & VB_DISPTYPE_CRT2) {
+	  	ivideo.currentvbflags |= VB_MIRROR_MODE;
+		ivideo.disp_state |= DISPMODE_MIRROR;
+	   } else {
+	 	ivideo.currentvbflags |= VB_SINGLE_MODE;
+		ivideo.disp_state |= DISPMODE_SINGLE;
+	   }
 	}
-	outSISIDXREG(SISCR, 0x17, reg);
 
         andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
 
 	if((ivideo.currentvbflags & CRT2_TV) && (ivideo.vbflags & VB_301)) {  /* Set filter for SiS301 */
-		
+
 		switch (ivideo.video_width) {
 		   case 320:
 			filter_tb = (ivideo.vbflags & TV_NTSC) ? 4 : 12;
@@ -3516,9 +3988,9 @@
 		if (!*this_opt)	continue;
 
 		if (!strncmp(this_opt, "mode:", 5)) {
-			sisfb_search_mode(this_opt + 5);
+			sisfb_search_mode(this_opt + 5, FALSE);
 		} else if (!strncmp(this_opt, "vesa:", 5)) {
-			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
+			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE);
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)			
 		} else if (!strcmp(this_opt, "inverse")) {
 			sisfb_inverse = 1;
@@ -3548,10 +4020,6 @@
 			sisfb_search_tvstd(this_opt + 7);
                 } else if (!strncmp(this_opt, "mem:",4)) {
 		        sisfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
-                } else if (!strncmp(this_opt, "dstn", 4)) {
-			enable_dstn = 1;
-			/* TW: DSTN overrules forcecrt2type */
-			sisfb_crt2type = CRT2_LCD;
 		} else if (!strncmp(this_opt, "queuemode:", 10)) {
 			sisfb_search_queuemode(this_opt + 10);
 		} else if (!strncmp(this_opt, "pdc:", 4)) {
@@ -3570,6 +4038,8 @@
 			sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
 		} else if (!strncmp(this_opt, "nocrt2rate", 10)) {
 			sisfb_nocrt2rate = 1;			
+		} else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
+			sisfb_search_mode(this_opt, TRUE);
 		} else {
 			printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
 		}
@@ -3596,14 +4066,14 @@
         char *sis_sig_300[4] = {
           "300", "540", "630", "730"
         };
-        char *sis_sig_310[7] = {
-          "315", "315", "315", "5315", "6325", "6325", "Xabre"
+        char *sis_sig_310[8] = {
+          "315", "315", "315", "5315", "6325", "6325", "Xabre", "6330"
         };
 	ushort sis_nums_300[4] = {
 	  SIS_300, SIS_540, SIS_630, SIS_730
 	};
-	unsigned short sis_nums_310[7] = {
-	  SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330
+	unsigned short sis_nums_310[8] = {
+	  SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330, SIS_660
 	};
 
         for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
@@ -3640,7 +4110,7 @@
                     }
                 }
 		if(stage != 4) {
-                   for(i = 0;(i < 7) && (stage != 4); i++) {
+                   for(i = 0;(i < 8) && (stage != 4); i++) {
                       if(strncmp(sis_sig_310[i], rom, strlen(sis_sig_310[i])) == 0) {
 		          if(sis_nums_310[i] == ivideo.chip) {
                              stage = 4;
@@ -3686,10 +4156,8 @@
 	if (sisfb_off)
 		return -ENXIO;
 
-	if (enable_dstn)
-		SiS_SetEnableDstn(&SiS_Pr);
-		
 	sisfb_registered = 0;
+	sisfb_thismonitor.datavalid = FALSE;
 
 	memset(&sis_fb_info, 0, sizeof(sis_fb_info));
 
@@ -3816,6 +4284,12 @@
 		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
 		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
+	   case PCI_DEVICE_ID_SI_660_VGA:
+		ivideo.chip = SIS_660;
+		sisvga_engine = SIS_315_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
+		break;
 #endif
            default:
 	        return -ENODEV;
@@ -3841,30 +4315,34 @@
 	SiS_Pr.SiS_Backup70xx = 0xff;
         SiS_Pr.SiS_CHOverScan = -1;
         SiS_Pr.SiS_ChSW = FALSE;
+	SiS_Pr.SiS_CustomT = CUT_NONE;
 	SiS_Pr.SiS_UseLCDA = FALSE;
 	SiS_Pr.UsePanelScaler = -1;
 	SiSRegInit(&SiS_Pr, (USHORT)sishw_ext.ulIOAddress);
 
 #ifdef CONFIG_FB_SIS_300
-	/* TW: Find PCI systems for Chrontel/ISA bridge manipulation */
+	/* TW: Find PCI systems for Chrontel/GPIO communication setup */
 	if(ivideo.chip == SIS_630) {
-	  int i=0;
-          do {
-	    if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
-	       mychswtable[i].subsysCard   == ivideo.subsysdevice) {
-		SiS_Pr.SiS_ChSW = TRUE;
-            }
-            i++;
-          } while(mychswtable[i].subsysVendor != 0);
+	   int i=0;
+           do {
+	      if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
+	         mychswtable[i].subsysCard   == ivideo.subsysdevice) {
+		 SiS_Pr.SiS_ChSW = TRUE;
+		 printk(KERN_DEBUG "sisfb: Identified [%s %s] requiring Chrontel/GPIO setup\n",
+		        mychswtable[i].vendorName, mychswtable[i].cardName);
+		 break;
+              }
+              i++;
+           } while(mychswtable[i].subsysVendor != 0);
 	}
 #endif
 
         outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		
-#ifdef MODULE	
+#ifdef MODULE
 	inSISIDXREG(SISCR,0x34,reg);
-	if(reg & 0x80) {
+	if((reg & 0x80) && (reg != 0xff)) {
 	   if((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {
 	      printk(KERN_INFO "sisfb: Cannot initialize display mode, X server is active\n");
 	      return -EBUSY;
@@ -3885,7 +4363,8 @@
 	}
 #endif
 #ifdef CONFIG_FB_SIS_315
-	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
+	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 ||
+	    ivideo.chip == SIS_740 || ivideo.chip == SIS_660) {
 	        outSISIDXREG(SISSR, 0x28, 0x5a);
 
                 outSISIDXREG(SISSR, 0x29, 0x64);
@@ -3906,6 +4385,7 @@
 		   case SIS_550:
 		   case SIS_650:
 		   case SIS_740:
+		   case SIS_660:
 			sishw_ext.bIntegratedMMEnabled = TRUE;
 			break;
 		   default:
@@ -3945,13 +4425,45 @@
 	sishw_ext.pQueryNorthBridgeSpace = &sisfb_query_north_bridge_space;
 	strcpy(sishw_ext.szVBIOSVer, "0.84");
 
-	/* TW: Mode numbers for 1280x960 are different for 300 and 310/325 series */
+        /* Find systems for special custom timing */
+	if(sishw_ext.UseROM) {
+	   int i=0,j;
+	   unsigned char *biosver = sishw_ext.pjVirtualRomBase + 0x06;
+           unsigned char *biosdate = sishw_ext.pjVirtualRomBase + 0x2c;
+	   BOOLEAN footprint;
+           do {
+	      if( (mycustomttable[i].chipID == ivideo.chip) &&
+	          (!strncmp(mycustomttable[i].biosversion, biosver, strlen(mycustomttable[i].biosversion))) &&
+	          (!strncmp(mycustomttable[i].biosdate, biosdate, strlen(mycustomttable[i].biosdate))) ) {
+		 footprint = TRUE;
+	         for(j=0; j<5; j++) {
+	           if(mycustomttable[i].biosFootprintAddr[j]) {
+	              if(sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
+		      		mycustomttable[i].biosFootprintData[j])
+		         footprint = FALSE;
+		   }
+	         }
+	         if(footprint) {
+	 	    SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
+		    printk(KERN_DEBUG "sisfb: Identified [%s %s] for non-standard timing\n",
+		        mycustomttable[i].vendorName,
+			mycustomttable[i].cardName);
+	            break;
+                 }
+	      }
+              i++;
+           } while(mycustomttable[i].chipID);
+	}
+
+#ifdef CONFIG_FB_SIS_300
+	/* TW: Mode numbers for 1280x768 are different for 300 and 315 series */
 	if(sisvga_engine == SIS_300_VGA) {
-		sisbios_mode[MODEINDEX_1280x960].mode_no = 0x6e;
-		sisbios_mode[MODEINDEX_1280x960+1].mode_no = 0x6f;
-		sisbios_mode[MODEINDEX_1280x960+2].mode_no = 0x7b;
-		sisbios_mode[MODEINDEX_1280x960+3].mode_no = 0x7b;
+		sisbios_mode[MODEINDEX_1280x768].mode_no = 0x55;
+		sisbios_mode[MODEINDEX_1280x768+1].mode_no = 0x5a;
+		sisbios_mode[MODEINDEX_1280x768+2].mode_no = 0x5b;
+		sisbios_mode[MODEINDEX_1280x768+3].mode_no = 0x5b;
 	}
+#endif
 
 	sishw_ext.pSR = vmalloc(sizeof(SIS_DSReg) * SR_BUFFER_SIZE);
 	if (sishw_ext.pSR == NULL) {
@@ -4131,25 +4643,29 @@
 		         ivideo.currentvbflags |= sisfb_crt2type;
 		      }
 		   } else {
-		      if(ivideo.vbflags & CRT2_TV)       ivideo.currentvbflags |= CRT2_TV;
-		      else if(ivideo.vbflags & CRT2_LCD) ivideo.currentvbflags |= CRT2_LCD;
-		      else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
+		      /* Chrontel 700x TV detection often unreliable, therefore use a
+		       * different default order on such machines
+		       */
+		      if((sisvga_engine == SIS_300_VGA) && (ivideo.vbflags & VB_CHRONTEL)) {
+		         if(ivideo.vbflags & CRT2_LCD)      ivideo.currentvbflags |= CRT2_LCD;
+		         else if(ivideo.vbflags & CRT2_TV)  ivideo.currentvbflags |= CRT2_TV;
+		         else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
+		      } else {
+		         if(ivideo.vbflags & CRT2_TV)       ivideo.currentvbflags |= CRT2_TV;
+		         else if(ivideo.vbflags & CRT2_LCD) ivideo.currentvbflags |= CRT2_LCD;
+		         else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
+		      }
 		   }
 		}
 
-		if (ivideo.vbflags & CRT2_LCD) {
-		    if (!enable_dstn) {
-		        inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
-			reg &= 0x0f;
-			if (sisvga_engine == SIS_300_VGA) {
-			    sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
-			} else {
-			    sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
-			}
-		    } else {
-		        /* TW: FSTN/DSTN */
-			sishw_ext.ulCRT2LCDType = LCD_320x480;
-		    }
+		if(ivideo.vbflags & CRT2_LCD) {
+		   inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
+		   reg &= 0x0f;
+		   if(sisvga_engine == SIS_300_VGA) {
+		      sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
+		   } else {
+		      sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
+		   }
 		}
 		
 		sisfb_detectedpdc = 0;
@@ -4189,7 +4705,7 @@
 		   if(ivideo.vbflags & (VB_302B | VB_301LV | VB_302LV)) {
 		      int tmp;
 		      inSISIDXREG(SISCR,0x34,tmp);
-		      if(tmp <= 0x13) {	
+		      if((tmp <= 0x13) || (tmp == 0xff)) {
 		         /* Currently on LCDA? (Some BIOSes leave CR38) */
 		         inSISIDXREG(SISCR,0x38,tmp);
 			 if((tmp & 0x03) == 0x03)  SiS_Pr.SiS_UseLCDA = TRUE;
@@ -4208,7 +4724,7 @@
 			       }
 			    }
 			 }
-		      } 
+		      }
 		      if(SiS_Pr.SiS_UseLCDA) {
 		         sisfb_detectedlcda = 0x03;
 		         printk(KERN_INFO
@@ -4219,6 +4735,15 @@
 #endif
 #endif
 
+		if (!sisfb_crt1off) {
+		   	sisfb_handle_ddc(&sisfb_thismonitor, 0);
+		} else {
+		   	if ((ivideo.vbflags & (VB_301|VB_301B|VB_302B)) &&
+		      	    (ivideo.vbflags & (CRT2_VGA | CRT2_LCD))) {
+		      		sisfb_handle_ddc(&sisfb_thismonitor, 1);
+		   	}
+		}
+
 		if (sisfb_mode_idx >= 0)
 			sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
 
@@ -4246,6 +4771,13 @@
 			ivideo.refresh_rate = 60;
 		}
 
+		if (sisfb_thismonitor.datavalid) {
+			if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
+			                      sisfb_rate_idx, ivideo.refresh_rate)) {
+				printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+			}
+		}
+
 		ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
 		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
 		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
@@ -4340,7 +4872,6 @@
 	    		}
 		} 
 
-		sis_fb_info.node = NODEV;
 		sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
 		sis_fb_info.var = default_var;
 		sis_fb_info.fix = sisfb_fix;
@@ -4395,9 +4926,11 @@
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 		printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
-	       		minor(sis_fb_info.node), myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
+	       		sis_fb_info.node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
 #endif
 
+		printk(KERN_INFO "sisfb: (C) 2001-2003 Thomas Winischhofer. All rights reserved.\n");
+
 	}	/* TW: if mode = "none" */
 	return 0;
 }
@@ -4410,7 +4943,6 @@
 static unsigned int rate = 0;
 static unsigned int crt1off = 1;
 static unsigned int mem = 0;
-static unsigned int dstn = 0;
 static char         *forcecrt2type = NULL;
 static int          forcecrt1 = -1;
 static char         *queuemode = NULL;
@@ -4425,7 +4957,7 @@
 static char         *tvstandard = NULL;
 static int	    nocrt2rate = 0;
 
-MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740/330 framebuffer driver");
+MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740/330/660 framebuffer driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>; SiS; Various others");
 
@@ -4433,15 +4965,20 @@
 MODULE_PARM(mode, "s");
 MODULE_PARM_DESC(mode,
        "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
-         "800x600x16 (default: none if sisfb is a module; this leaves the\n"
-	 "console untouched and the driver will only do the video memory\n"
-	 "management for eg. DRM/DRI; 800x600x8 if sisfb is in the kernel)");
+         "1024x768x16. Other formats supported include XxY-Depth and\n"
+	 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
+	 "number, it will be interpreted as a VESA mode number. (default: none if\n"
+	 "sisfb is a module; this leaves the console untouched and the driver will\n"
+	 "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
+	 "is in the kernel)");
 #endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	 
 MODULE_PARM(mode, "s");
 MODULE_PARM_DESC(mode,
-       "\nSelects the desired default display mode in the format [X]x[Y]x[Depth],\n"
-         "eg. 1024x768x16 (default: 800x600x8)");
+       "\nSelects the desired default display mode in the format XxYxDepth,\n"
+         "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
+	 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
+	 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)");
 #endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
@@ -4452,17 +4989,18 @@
 	 "and the driver will only do the video memory management for eg. DRM/DRI;\n"
 	 "0x0103 if sisfb is in the kernel)");
 #endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 MODULE_PARM(vesa, "i");
 MODULE_PARM_DESC(vesa,
        "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
          "0x117 (default: 0x0103)");
-#endif	 
+#endif
 
 MODULE_PARM(rate, "i");
 MODULE_PARM_DESC(rate,
 	"\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
-	  "(default: 60)");
+	  "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
+	  "will be ignored (default: 60)");
 
 MODULE_PARM(crt1off,   "i");
 MODULE_PARM_DESC(crt1off,
@@ -4473,14 +5011,9 @@
 	"\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
 	  "(Possible values 0-7, default: [no filter])");
 
-MODULE_PARM(dstn,   "i");
-MODULE_PARM_DESC(dstn,
-	"\nSelects DSTN/FSTN display mode for SiS550. This sets CRT2 type to LCD and\n"
-	  "overrides forcecrt2type setting. (1=ON, 0=OFF) (default: 0)");
-
 MODULE_PARM(queuemode,   "s");
 MODULE_PARM_DESC(queuemode,
-	"\nSelects the queue mode on 315/550/650/740/330. Possible choices are AGP, VRAM or\n"
+	"\nSelects the queue mode on 315/550/650/740/330/660. Possible choices are AGP, VRAM,\n"
   	  "MMIO. AGP is only available if the kernel has AGP support. The queue mode is\n"
 	  "important to programs using the 2D/3D accelerator of the SiS chip. The modes\n"
 	  "require a totally different way of programming the engines. If any mode than\n"
@@ -4555,28 +5088,28 @@
 MODULE_PARM(nocrt2rate, "i");
 MODULE_PARM_DESC(nocrt2rate,
 	"\nSetting this to 1 will force the driver to use the default refresh rate for\n"
-	  "CRT2 if CRT2 type is VGA. (default: 0, use same rate as crt1)");	
+	  "CRT2 if CRT2 type is VGA. (default: 0, use same rate as crt1)");
 	
 int init_module(void)
 {
 	int err;
-	
+
+	ivideo.refresh_rate = sisfb_parm_rate = rate;
+
 	if(mode)
-		sisfb_search_mode(mode);
+		sisfb_search_mode(mode, FALSE);
 	else if(vesa != -1)
-		sisfb_search_vesamode(vesa);
-	else  
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+		sisfb_search_vesamode(vesa, FALSE);
+	else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		/* For 2.4, set mode=none if no mode is given  */
 		sisfb_mode_idx = MODE_INDEX_NONE;
 #endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-		/* For 2.5, we don't need this "mode=none" stuff anymore */	
+		/* For 2.5, we don't need this "mode=none" stuff anymore */
 		sisfb_mode_idx = DEFAULT_MODE;
 #endif
 
-	ivideo.refresh_rate = sisfb_parm_rate = rate;
-
 	if(forcecrt2type)
 		sisfb_search_crt2type(forcecrt2type);
 
@@ -4610,11 +5143,6 @@
 
 	sisfb_useoem = useoem;
 
-	enable_dstn = dstn;
-
-	/* TW: DSTN overrules forcecrt2type */
-	if (enable_dstn)      sisfb_crt2type = CRT2_LCD;
-
 	if (queuemode)        sisfb_search_queuemode(queuemode);
 	
 	/* TW: If other queuemode than MMIO, disable 2D accel and ypan */
diff -urN linux-2.4.22-pre2/drivers/video/sis/sis_main.h linux-2.4.22-pre3/drivers/video/sis/sis_main.h
--- linux-2.4.22-pre2/drivers/video/sis/sis_main.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/sis_main.h	2003-07-05 18:11:05.000000000 -0700
@@ -12,7 +12,7 @@
 
 #define VER_MAJOR                 1
 #define VER_MINOR                 6
-#define VER_LEVEL                 3
+#define VER_LEVEL                 11
 
 #include "sis.h"
 
@@ -29,6 +29,12 @@
 #ifndef PCI_DEVICE_ID_SI_330
 #define PCI_DEVICE_ID_SI_330      0x0330
 #endif
+#ifndef PCI_DEVICE_ID_SI_660
+#define PCI_DEVICE_ID_SI_660      0x0660
+#endif
+#ifndef PCI_DEVICE_ID_SI_660_VGA
+#define PCI_DEVICE_ID_SI_660_VGA  0x6330
+#endif
 
 /* To be included in fb.h */
 #ifndef FB_ACCEL_SIS_GLAMOUR_2
@@ -51,7 +57,7 @@
 #define TURBO_QUEUE_AREA_SIZE     0x80000 /* 512K */
 #endif
 
-/* For 310/315 series */
+/* For 315 series */
 #ifdef CONFIG_FB_SIS_315
 #define COMMAND_QUEUE_AREA_SIZE   0x80000 /* 512K */
 #define COMMAND_QUEUE_THRESHOLD   0x1F
@@ -281,43 +287,43 @@
 static struct fb_info sis_fb_info;
 
 static struct fb_var_screeninfo default_var = {
-	xres:           0,
-	yres:           0,
-	xres_virtual:   0,
-	yres_virtual:   0,
-	xoffset:        0,
-	yoffset:        0,
-	bits_per_pixel: 0,
-	grayscale:      0,
-	red:            {0, 8, 0},
-	green:          {0, 8, 0},
-	blue:           {0, 8, 0},
-	transp:         {0, 0, 0},
-	nonstd:         0,
-	activate:       FB_ACTIVATE_NOW,
-	height:         -1,
-	width:          -1,
-	accel_flags:    0,
-	pixclock:       0,
-	left_margin:    0,
-	right_margin:   0,
-	upper_margin:   0,
-	lower_margin:   0,
-	hsync_len:      0,
-	vsync_len:      0,
-	sync:           0,
-	vmode:          FB_VMODE_NONINTERLACED,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
-	reserved:       {0, 0, 0, 0, 0, 0}
-#endif	
+	.xres            = 0,
+	.yres            = 0,
+	.xres_virtual    = 0,
+	.yres_virtual    = 0,
+	.xoffset         = 0,
+	.yoffset         = 0,
+	.bits_per_pixel  = 0,
+	.grayscale       = 0,
+	.red             = {0, 8, 0},
+	.green           = {0, 8, 0},
+	.blue            = {0, 8, 0},
+	.transp          = {0, 0, 0},
+	.nonstd          = 0,
+	.activate        = FB_ACTIVATE_NOW,
+	.height          = -1,
+	.width           = -1,
+	.accel_flags     = 0,
+	.pixclock        = 0,
+	.left_margin     = 0,
+	.right_margin    = 0,
+	.upper_margin    = 0,
+	.lower_margin    = 0,
+	.hsync_len       = 0,
+	.vsync_len       = 0,
+	.sync            = 0,
+	.vmode           = FB_VMODE_NONINTERLACED,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	.reserved        = {0, 0, 0, 0, 0, 0}
+#endif
 };
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static struct fb_fix_screeninfo sisfb_fix = {
-	id:		"SiS",
-	type:		FB_TYPE_PACKED_PIXELS,
-	xpanstep:	0,
-	ypanstep:	1,
+	.id		= "SiS",
+	.type		= FB_TYPE_PACKED_PIXELS,
+	.xpanstep	= 0,
+	.ypanstep	= 1,
 };
 static char myid[20];
 static u32 pseudo_palette[17];
@@ -356,9 +362,10 @@
 static int sisfb_registered = 0;
 static int sisfb_mem = 0;
 static int sisfb_pdc = 0;
-static int enable_dstn = 0;
 static int sisfb_ypan = -1;
 static int sisfb_nocrt2rate = 0;
+static int sisfb_dstn = 0;
+static int sisfb_fstn = 0;
 
 VGA_ENGINE sisvga_engine = UNKNOWN_VGA;
 int 	   sisfb_accel = -1;
@@ -370,7 +377,7 @@
 int sisfb_crt2type  = -1;	/* CRT2 type (for overriding autodetection) */
 int sisfb_tvplug    = -1;	/* Tv plug type (for overriding autodetection) */
 
-int sisfb_queuemode = -1; 	/* Use MMIO queue mode by default (310/325 series only) */
+int sisfb_queuemode = -1; 	/* Use MMIO queue mode by default (315 series only) */
 
 unsigned char sisfb_detectedpdc = 0;
 
@@ -404,7 +411,7 @@
 	VM_CMD_QUEUE,
 } SIS_CMDTYPE;
 
-/* Supported SiS Chips list */
+/* List of supported chips */
 static struct board {
 	u16 vendor, device;
 	const char *name;
@@ -418,6 +425,7 @@
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, "SIS 550 VGA"},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 650/M650/651/740 VGA"},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330,     "SIS 330"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, "SIS 660 VGA"},
 	{0, 0, NULL}
 };
 
@@ -425,7 +433,7 @@
 #define MD_SIS315 2
 
 /* Mode table */
-/* NOT const - will be patched for 1280x960 mode number chaos reasons */
+/* NOT const - will be patched for 1280x768 mode number chaos reasons */
 struct _sisbios_mode {
 	char name[15];
 	u8 mode_no;
@@ -449,8 +457,8 @@
 	{"320x240x16",   0x56, 0x0135, 0x0000,  320,  240, 16, 1,  40, 15, MD_SIS300|MD_SIS315},
 	{"320x240x24",   0x53, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
 	{"320x240x32",   0x53, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
-	{"320x480x8",    0x5a, 0x0000, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
-	{"320x480x16",   0x5b, 0x0000, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
+	{"320x240x8",    0x5a, 0x0132, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
+	{"320x240x16",   0x5b, 0x0135, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
 	{"400x300x8",    0x51, 0x0133, 0x0000,  400,  300,  8, 1,  50, 18, MD_SIS300|MD_SIS315},
 	{"400x300x16",   0x57, 0x0136, 0x0000,  400,  300, 16, 1,  50, 18, MD_SIS300|MD_SIS315},
 	{"400x300x24",   0x54, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
@@ -518,12 +526,12 @@
 	{"1280x720x16",  0x75, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
 	{"1280x720x24",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
 	{"1280x720x32",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
-	{"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48,           MD_SIS315},
-	{"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48,           MD_SIS315},
-	{"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_SIS315},
-	{"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_SIS315},
-#define MODEINDEX_1280x960 79
-	{"1280x960x8",   0x7c, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315},  /* TW: Modenumbers being patched */
+#define MODEINDEX_1280x768 75
+	{"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48, MD_SIS300|MD_SIS315},
+	{"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
+	{"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
+	{"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
+	{"1280x960x8",   0x7c, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315}, 
 	{"1280x960x16",  0x7d, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
 	{"1280x960x24",  0x7e, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
 	{"1280x960x32",  0x7e, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
@@ -531,10 +539,14 @@
 	{"1280x1024x16", 0x4d, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
 	{"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
 	{"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
-	{"1360x768x8",   0x48, 0x0107, 0x0107, 1360,  768,  8, 1, 170, 48, MD_SIS300|MD_SIS315},
-	{"1360x768x16",  0x4b, 0x011a, 0x011a, 1360,  768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
-	{"1360x768x24",  0x4e, 0x013d, 0x011b, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
-	{"1360x768x32",  0x4e, 0x013d, 0x011b, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
+	{"1360x768x8",   0x48, 0x0000, 0x0000, 1360,  768,  8, 1, 170, 48, MD_SIS300|MD_SIS315},
+	{"1360x768x16",  0x4b, 0x0000, 0x0000, 1360,  768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
+	{"1360x768x24",  0x4e, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
+	{"1360x768x32",  0x4e, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
+	{"1360x1024x8",  0x67, 0x0000, 0x0000, 1360, 1024,  8, 1, 170, 64, MD_SIS300          },
+	{"1360x1024x16", 0x6f, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300          },
+	{"1360x1024x24", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
+	{"1360x1024x32", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
 	{"1400x1050x8",  0x26, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},
 	{"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65,           MD_SIS315},
 	{"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
@@ -565,37 +577,45 @@
 
 /* TW: CR36 evaluation */
 const USHORT sis300paneltype[] =
-    { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
-      LCD_1280x960,  LCD_640x480,  LCD_1024x600,  LCD_1152x768,
-      LCD_320x480,   LCD_1024x768, LCD_1024x768,  LCD_1024x768,
-      LCD_1024x768,  LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
+    { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
+      LCD_1280x960,  LCD_640x480,   LCD_1024x600,  LCD_1152x768,
+      LCD_1024x768,   LCD_1024x768,  LCD_1024x768,  LCD_1024x768,
+      LCD_1024x768,  LCD_1024x768,  LCD_320x480,   LCD_1024x768 };
 
 const USHORT sis310paneltype[] =
-    { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
-      LCD_640x480,   LCD_1024x600, LCD_1152x864,  LCD_1280x960,
-      LCD_1152x768,  LCD_1400x1050,LCD_1280x768,  LCD_1600x1200,
-      LCD_320x480,   LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
+    { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
+      LCD_640x480,   LCD_1024x600,  LCD_1152x864,  LCD_1280x960,
+      LCD_1152x768,  LCD_1400x1050, LCD_1280x768,  LCD_1600x1200,
+      LCD_640x480_2, LCD_640x480_3, LCD_320x480,   LCD_1024x768 };
+
+#define FL_550_DSTN 0x01
+#define FL_550_FSTN 0x02
 
 static const struct _sis_crt2type {
 	char name[10];
 	int type_no;
 	int tvplug_no;
+	unsigned short flags;
 } sis_crt2type[] = {
-	{"NONE", 	0, 		-1},
-	{"LCD",  	CRT2_LCD, 	-1},
-	{"TV",   	CRT2_TV, 	-1},
-	{"VGA",  	CRT2_VGA, 	-1},
-	{"SVIDEO", 	CRT2_TV, 	TV_SVIDEO},
-	{"COMPOSITE", 	CRT2_TV, 	TV_AVIDEO},
-	{"SCART", 	CRT2_TV, 	TV_SCART},
-	{"none", 	0, 		-1},
-	{"lcd",  	CRT2_LCD, 	-1},
-	{"tv",   	CRT2_TV, 	-1},
-	{"vga",  	CRT2_VGA, 	-1},
-	{"svideo", 	CRT2_TV, 	TV_SVIDEO},
-	{"composite", 	CRT2_TV, 	TV_AVIDEO},
-	{"scart", 	CRT2_TV, 	TV_SCART},
-	{"\0",  	-1, 		-1}
+	{"NONE", 	0, 		-1,        0},
+	{"LCD",  	CRT2_LCD, 	-1,        0},
+	{"TV",   	CRT2_TV, 	-1,        0},
+	{"VGA",  	CRT2_VGA, 	-1,        0},
+	{"SVIDEO", 	CRT2_TV, 	TV_SVIDEO, 0},
+	{"COMPOSITE", 	CRT2_TV, 	TV_AVIDEO, 0},
+	{"SCART", 	CRT2_TV, 	TV_SCART,  0},
+	{"none", 	0, 		-1,        0},
+	{"lcd",  	CRT2_LCD, 	-1,        0},
+	{"tv",   	CRT2_TV, 	-1,        0},
+	{"vga",  	CRT2_VGA, 	-1,        0},
+	{"svideo", 	CRT2_TV, 	TV_SVIDEO, 0},
+	{"composite", 	CRT2_TV, 	TV_AVIDEO, 0},
+	{"scart", 	CRT2_TV, 	TV_SCART,  0},
+	{"DSTN",        CRT2_LCD,       -1,        FL_550_DSTN},
+	{"dstn",        CRT2_LCD,       -1,        FL_550_DSTN},
+	{"FSTN",        CRT2_LCD,       -1,        FL_550_FSTN},
+	{"fstn",        CRT2_LCD,       -1,        FL_550_FSTN},
+	{"\0",  	-1, 		-1,        0}
 };
 
 /* Queue mode selection for 310 series */
@@ -661,6 +681,7 @@
 	{1, 1280, 1024,  43,  TRUE}, {2, 1280, 1024,  60,  TRUE}, {3, 1280, 1024,  75,  TRUE},
 	{4, 1280, 1024,  85,  TRUE},
 	{1, 1360,  768,  60,  TRUE},
+	{1, 1360, 1024,  59,  TRUE},
 	{1, 1400, 1050,  60,  TRUE}, {2, 1400, 1050,  75,  TRUE},
 	{1, 1600, 1200,  60,  TRUE}, {2, 1600, 1200,  65,  TRUE}, {3, 1600, 1200,  70,  TRUE},
 	{4, 1600, 1200,  75,  TRUE}, {5, 1600, 1200,  85,  TRUE}, {6, 1600, 1200, 100,  TRUE},
@@ -672,6 +693,54 @@
 	{0,    0,    0,   0, FALSE}
 };
 
+static struct sisfb_monitor {
+	u16 hmin;
+	u16 hmax;
+	u16 vmin;
+	u16 vmax;
+	u32 dclockmax;
+	u8  feature;
+	BOOLEAN datavalid;
+} sisfb_thismonitor;
+
+static const struct _sisfbddcsmodes {
+	u32 mask;
+	u16 h;
+	u16 v;
+	u32 d;
+} sisfb_ddcsmodes[] = {
+	{ 0x10000, 67, 75, 108000},
+	{ 0x08000, 48, 72,  50000},
+	{ 0x04000, 46, 75,  49500},
+	{ 0x01000, 35, 43,  44900},
+	{ 0x00800, 48, 60,  65000},
+	{ 0x00400, 56, 70,  75000},
+	{ 0x00200, 60, 75,  78800},
+	{ 0x00100, 80, 75, 135000},
+	{ 0x00020, 31, 60,  25200},
+	{ 0x00008, 38, 72,  31500},
+	{ 0x00004, 37, 75,  31500},
+	{ 0x00002, 35, 56,  36000},
+	{ 0x00001, 38, 60,  40000}
+};
+
+static const struct _sisfbddcfmodes {
+	u16 x;
+	u16 y;
+	u16 v;
+	u16 h;
+	u32 d;
+} sisfb_ddcfmodes[] = {
+       { 1280, 1024, 85, 92, 157500},
+       { 1600, 1200, 60, 75, 162000},
+       { 1600, 1200, 65, 82, 175500},
+       { 1600, 1200, 70, 88, 189000},
+       { 1600, 1200, 75, 94, 202500},
+       { 1600, 1200, 85, 107,229500},
+       { 1920, 1440, 60, 90, 234000},
+       { 1920, 1440, 75, 113,297000}
+};
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static u8 sisfb_lastrates[128];
 #endif
@@ -683,9 +752,38 @@
     char *cardName;
 } mychswtable[] = {
         { 0x1631, 0x1002, "Mitachi", "0x1002" },
+	{ 0x1071, 0x7521, "Mitac"  , "7521P"  },
 	{ 0,      0,      ""       , ""       }
 };
 
+static const struct _customttable {
+    unsigned short chipID;
+    char *biosversion;
+    char *biosdate;
+    unsigned short biosFootprintAddr[5];
+    unsigned char biosFootprintData[5];
+    char *vendorName;
+    char *cardName;
+    unsigned long SpecialID;
+    char *optionName;
+} mycustomttable[] = {
+        { SIS_630, "2.00.07", "09/27/2002-13:38:25",
+	  { 0x220, 0x227, 0x228, 0x229, 0x22a },
+	  {  0x01,  0xe3,  0x9a,  0x6a,  0x00 },
+	  "Barco", "iQ R200L/300/400", CUT_BARCO1366, "BARCO1366"
+	},
+	{ SIS_630, "2.00.07", "09/27/2002-13:38:25",
+	  { 0x220, 0x227, 0x228, 0x229, 0x22a },
+	  {  0x00,  0x5a,  0x64,  0x41,  0x00 },
+	  "Barco", "iQ G200L/300/400/500", CUT_BARCO1024, "BARCO1024"
+	},
+	{ 0, "", "",
+	  { 0, 0, 0, 0 },
+	  { 0, 0, 0, 0 },
+	  "", "", CUT_NONE, ""
+	}
+};
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 /* Offscreen layout */
 typedef struct _SIS_GLYINFO {
@@ -953,7 +1051,7 @@
 			 unsigned int *left_margin, unsigned int *right_margin, 
 			 unsigned int *upper_margin, unsigned int *lower_margin,
 			 unsigned int *hsync_len, unsigned int *vsync_len,
-			 unsigned int *sync, unsigned int *vmode);			      		    			      
+			 unsigned int *sync, unsigned int *vmode);
 #endif
 			
 static int      sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
@@ -964,7 +1062,7 @@
 extern void     sisfb_syncaccel(void);
 
 /* Internal general routines */
-static void     sisfb_search_mode(const char *name);
+static void     sisfb_search_mode(char *name, BOOLEAN quiet);
 static int      sisfb_validate_mode(int modeindex, unsigned long vbflags);
 static u8       sisfb_search_refresh_rate(unsigned int rate, int index);
 static int      sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
@@ -983,6 +1081,10 @@
 static void     sisfb_detect_VB_connect(void);
 static void     sisfb_get_VB_type(void);
 
+static void     sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno);
+static BOOLEAN  sisfb_interpret_edid(struct sisfb_monitor *monitor, unsigned char *buffer);
+
+
 /* SiS-specific Export functions */
 void            sis_dispinfo(struct ap_data *rec);
 void            sis_malloc(struct sis_memreq *req);
@@ -1019,9 +1121,13 @@
 extern void 	SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
 extern BOOLEAN  SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
 extern BOOLEAN  SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
-extern void     SiS_SetEnableDstn(SiS_Private *SiS_Pr);
+extern void     SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
+extern void     SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
 extern void     SiS_LongWait(SiS_Private *SiS_Pr);
 
+extern BOOLEAN  sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
+
 /* Chrontel TV functions */
 extern USHORT 	SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
 extern void 	SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
@@ -1029,7 +1135,14 @@
 extern void 	SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
 extern void     SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
 extern void     SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
-
+extern void     SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
+extern USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+		              USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
+extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
+extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+			      
 /* Sensing routines */
 void            SiS_Sense30x(void);
 int             SISDoSense(int tempbl, int tempbh, int tempcl, int tempch);
diff -urN linux-2.4.22-pre2/drivers/video/sis/vgatypes.h linux-2.4.22-pre3/drivers/video/sis/vgatypes.h
--- linux-2.4.22-pre2/drivers/video/sis/vgatypes.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/vgatypes.h	2003-07-05 18:11:06.000000000 -0700
@@ -1,3 +1,35 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
+/*
+ * General type definitions for universal mode switching modules
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
 #ifndef _VGATYPES_
 #define _VGATYPES_
 
@@ -5,7 +37,7 @@
 #include "xf86Pci.h"
 #endif
 
-#ifdef LINUX_KERNEL  /* TW: We don't want the X driver to depend on kernel source */
+#ifdef LINUX_KERNEL  /* We don't want the X driver to depend on kernel source */
 #include <linux/ioctl.h>
 #endif
 
@@ -72,18 +104,15 @@
 typedef UCHAR BOOLEAN;
 #endif
 
-#ifndef WINCE_HEADER
 #ifndef bool
 typedef UCHAR bool;
 #endif
-#endif /*WINCE_HEADER*/
 
 #ifndef VBIOS_VER_MAX_LENGTH
 #define VBIOS_VER_MAX_LENGTH         4
 #endif
 
 #ifndef LINUX_KERNEL   /* For kernel, this is defined in sisfb.h */
-#ifndef WIN2000
 #ifndef SIS_CHIP_TYPE
 typedef enum _SIS_CHIP_TYPE {
     SIS_VGALegacy = 0,
@@ -101,19 +130,18 @@
     SIS_550,
     SIS_650,
     SIS_740,
-    SIS_330, 
+    SIS_330,
+    SIS_660,
     MAX_SIS_CHIP
 } SIS_CHIP_TYPE;
 #endif
 #endif
-#endif
 
-#ifndef WIN2000
 #ifndef SIS_VB_CHIP_TYPE
 typedef enum _SIS_VB_CHIP_TYPE {
     VB_CHIP_Legacy = 0,
     VB_CHIP_301,
-    VB_CHIP_301B,      
+    VB_CHIP_301B,
     VB_CHIP_301LV,
     VB_CHIP_302,
     VB_CHIP_302B,
@@ -122,9 +150,7 @@
     MAX_VB_CHIP
 } SIS_VB_CHIP_TYPE;
 #endif
-#endif
 
-#ifndef WIN2000
 #ifndef SIS_LCD_TYPE
 typedef enum _SIS_LCD_TYPE {
     LCD_INVALID = 0,
@@ -136,18 +162,19 @@
     LCD_1600x1200,
     LCD_1920x1440,
     LCD_2048x1536,
-    LCD_320x480,       /* TW: FSTN */
+    LCD_320x480,       /* FSTN, DSTN */
     LCD_1400x1050,
     LCD_1152x864,
     LCD_1152x768,
     LCD_1280x768,
     LCD_1024x600,
+    LCD_640x480_2,     /* FSTN, DSTN */
+    LCD_640x480_3,     /* FSTN, DSTN */
+    LCD_CUSTOM,
     LCD_UNKNOWN
 } SIS_LCD_TYPE;
 #endif
-#endif
 
-#ifndef WIN2000 /* mark by Paul, Move definition to sisv.h*/
 #ifndef PSIS_DSReg
 typedef struct _SIS_DSReg
 {
@@ -162,7 +189,6 @@
 
 typedef BOOLEAN (*PSIS_QUERYSPACE)   (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
 
-
 struct _SIS_HW_DEVICE_INFO
 {
     PVOID  pDevice;              /* The pointer to the physical device data structure
@@ -173,7 +199,7 @@
                                  /* Note:ROM image file is the file of VBIOS ROM */
 
     BOOLEAN UseROM;		 /* TW: Use the ROM image if provided */
- 
+
     UCHAR  *pjCustomizedROMImage;/* base virtual address of ROM image file. */
                                  /* wincE:ROM image file is the file for OEM */
                                  /*       customized table */
@@ -195,7 +221,7 @@
                                  /* defined in the data structure type */
                                  /* "SIS_VB_CHIP_TYPE" */
 
-    USHORT usExternalChip;       /* NO VB or other video bridge(not  */
+    USHORT usExternalChip;       /* NO VB or other video bridge (other than  */
                                  /* SiS video bridge) */
                                  /* if ujVBChipID = VB_CHIP_UNKNOWN, */
                                  /* then bit0=1 : LVDS,bit1=1 : trumpion, */
@@ -207,7 +233,7 @@
                                  /*             011:Trumpion LVDS Scaling Chip */
                                  /*             100:LVDS(LCD-out)+Chrontel 7005 */
                                  /*             101:Single Chrontel 7005 */
-				 /* TW: This has changed on 310/325 series! */
+				 /* TW: This has changed on 315 series! */
 
     ULONG  ulCRT2LCDType;        /* defined in the data structure type */
                                  /* "SIS_LCD_TYPE" */
@@ -244,7 +270,6 @@
 #endif
 };
 #endif
-#endif 
 
 
 /* TW: Addtional IOCTL for communication sisfb <> X driver        */
@@ -288,8 +313,6 @@
 };
 #endif
 
-#ifndef WIN2000
-#ifndef WINCE_HEADER
 #ifndef BUS_DATA_TYPE
 typedef enum _BUS_DATA_TYPE {
     ConfigurationSpaceUndefined = -1,
@@ -307,7 +330,6 @@
     MaximumBusDataType
 } BUS_DATA_TYPE, *PBUS_DATA_TYPE;
 #endif
-#endif /* WINCE_HEADER */
 
 #ifndef PCI_TYPE0_ADDRESSES
 #define PCI_TYPE0_ADDRESSES             6
@@ -317,7 +339,6 @@
 #define PCI_TYPE1_ADDRESSES             2
 #endif
 
-#ifndef WINCE_HEADER
 #ifndef PCI_COMMON_CONFIG
 typedef struct _PCI_COMMON_CONFIG {
     USHORT  VendorID;                   /* (ro)                 */
@@ -355,7 +376,6 @@
 
 } PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
 #endif
-#endif /* WINCE_HEADER */
 
 #ifndef FIELD_OFFSET
 #define FIELD_OFFSET(type, field)    ((LONG)&(((type *)0)->field))
@@ -364,6 +384,6 @@
 #ifndef PCI_COMMON_HDR_LENGTH
 #define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific))
 #endif
-#endif
 
 #endif
+
diff -urN linux-2.4.22-pre2/drivers/video/sis/vstruct.h linux-2.4.22-pre3/drivers/video/sis/vstruct.h
--- linux-2.4.22-pre2/drivers/video/sis/vstruct.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/sis/vstruct.h	2003-07-05 18:11:06.000000000 -0700
@@ -1,3 +1,37 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
+/*
+ * General structure definitions for universal mode switching modules
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *              ?
+ *
+ */
+ 
 #ifdef _INIT_
 #define EXTERN
 #else
@@ -58,7 +92,6 @@
 	UCHAR  CR[15];
 } SiS_LVDSCRT1DataStruct;
 
-/*add for LCDA*/
 typedef struct _SiS_LCDACRT1DataStruct
 {
 	UCHAR  CR[17];
@@ -111,9 +144,7 @@
 	UCHAR  Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
-	USHORT Ext_Point;
 	USHORT Ext_VESAID;
-	UCHAR  Ext_VESAMEMSize;
 	UCHAR  Ext_RESINFO;
 	UCHAR  VB_ExtTVFlickerIndex;
 	UCHAR  VB_ExtTVEdgeIndex;
@@ -130,7 +161,6 @@
 	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
-	USHORT ROM_OFFSET;
 } SiS_Ext2Struct;
 
 typedef struct _SiS_Part2PortTblStruct
@@ -183,6 +213,12 @@
 
 typedef UCHAR DRAM4Type[4];
 
+/* Defines for SiS_Customt */
+#define CUT_NONE       0
+#define CUT_FORCENONE  1
+#define CUT_BARCO1366  2
+#define CUT_BARCO1024  3
+
 typedef struct _SiS_Private
 {
 #ifdef LINUX_KERNEL
@@ -198,25 +234,34 @@
 	USHORT SiS_P3c7;
 	USHORT SiS_P3c8;
 	USHORT SiS_P3c9;
+	USHORT SiS_P3cb;
+	USHORT SiS_P3cd;
 	USHORT SiS_P3da;
 	USHORT SiS_Part1Port;
 	USHORT SiS_Part2Port;
 	USHORT SiS_Part3Port;
 	USHORT SiS_Part4Port;
 	USHORT SiS_Part5Port;
+	USHORT SiS_VidCapt;
+	USHORT SiS_VidPlay;
 	USHORT SiS_IF_DEF_LVDS;
 	USHORT SiS_IF_DEF_TRUMPION;
 	USHORT SiS_IF_DEF_DSTN;
 	USHORT SiS_IF_DEF_FSTN;
 	USHORT SiS_IF_DEF_CH70xx;
 	USHORT SiS_IF_DEF_HiVision;
+	USHORT SiS_SysFlags;
 	UCHAR  SiS_VGAINFO;
+#ifndef LINUX_KERNEL
+        USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
+#endif
 	BOOLEAN SiS_UseROM;
 	int    SiS_CHOverScan;
 	BOOLEAN SiS_CHSOverScan;
 	BOOLEAN SiS_ChSW;
 	BOOLEAN SiS_UseLCDA;
 	int    SiS_UseOEM;
+	ULONG  SiS_CustomT;
 	USHORT SiS_Backup70xx;
 	USHORT SiS_CRT1Mode;
 	USHORT SiS_flag_clearbuffer;
@@ -270,15 +315,18 @@
 	USHORT SiS_Panel1280x768;
 	USHORT SiS_Panel1024x600;
 	USHORT SiS_Panel640x480;
+	USHORT SiS_Panel640x480_2;
+	USHORT SiS_Panel640x480_3;
 	USHORT SiS_Panel1152x864;
+	USHORT SiS_PanelCustom;
+	USHORT SiS_PanelBarco1366;
 	USHORT SiS_PanelMax;
 	USHORT SiS_PanelMinLVDS;
 	USHORT SiS_PanelMin301;
 	USHORT SiS_ChrontelInit;
 	
-	/* Pointers: */
 	const SiS_StStruct          *SiS_SModeIDTable;
-	const SiS_StandTableStruct  *SiS_StandTable;
+	SiS_StandTableStruct        *SiS_StandTable;
 	const SiS_ExtStruct         *SiS_EModeIDTable;
 	const SiS_Ext2Struct        *SiS_RefIndex;
 	const SiS_VBModeStruct      *SiS_VBModeIDTable;
@@ -316,7 +364,7 @@
 	const USHORT *pSiS_RGBSenseData;
 	const USHORT *pSiS_VideoSenseData;
 	const USHORT *pSiS_YCSenseData;
-	const USHORT *pSiS_RGBSenseData2; /*301b*/
+	const USHORT *pSiS_RGBSenseData2;
 	const USHORT *pSiS_VideoSenseData2;
 	const USHORT *pSiS_YCSenseData2;
 #endif
@@ -352,7 +400,6 @@
 	const SiS_TVDataStruct   *SiS_ExtPALData;
 	const SiS_TVDataStruct   *SiS_StNTSCData;
 	const SiS_TVDataStruct   *SiS_ExtNTSCData;
-/*	const SiS_TVDataStruct   *SiS_St1HiTVData;  */
 	const SiS_TVDataStruct   *SiS_St2HiTVData;
 	const SiS_TVDataStruct   *SiS_ExtHiTVData;
 	const UCHAR *SiS_NTSCTiming;
@@ -385,12 +432,17 @@
 	const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_1;
 	const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_2;
 	const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_2;
 	const SiS_LVDSDataStruct  *SiS_LVDS320x480Data_1;
 	const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_1;
 	const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_2;
 	const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_1;
 	const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_2;
 	const SiS_LVDSDataStruct  *SiS_LVDSXXXxXXXData_1;
+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1024Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1024Data_2;
 	const SiS_LVDSDataStruct  *SiS_CHTVUNTSCData;
 	const SiS_LVDSDataStruct  *SiS_CHTVONTSCData;
 	const SiS_LVDSDataStruct  *SiS_CHTVUPALData;
@@ -482,6 +534,12 @@
 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_2_H;
 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1;
 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_1;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_2;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_2_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3_H;
 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UNTSC;
 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1ONTSC;
 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UPAL;
@@ -511,7 +569,6 @@
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_2_H;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_2_H;
 
-	/* TW: New for 650/301LV */
 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_1;
@@ -543,6 +600,9 @@
 	const UCHAR *SiS_CHTVVCLKUPALN;
 	const UCHAR *SiS_CHTVVCLKOPALN;
 	const UCHAR *SiS_CHTVVCLKSOPAL;
+
+	USHORT  PanelXRes;
+	USHORT  PanelYRes;
 	
 	BOOLEAN UseCustomMode;
 	BOOLEAN CRT1UsesCustomMode;
@@ -564,8 +624,11 @@
 	UCHAR   CSR2B;
 	UCHAR   CSR2C;
 	USHORT  CSRClock;
+	USHORT  CSRClock_CRT1;
 	USHORT  CModeFlag;
+	USHORT  CModeFlag_CRT1;
 	USHORT  CInfoFlag;
+
 	BOOLEAN SiS_CHPALM;
 	BOOLEAN SiS_CHPALN;
 	
@@ -582,7 +645,21 @@
 	UCHAR Backup_1c;
 	UCHAR Backup_1d;
 	
-	int    UsePanelScaler;
+	int     UsePanelScaler;
+
+	USHORT  CP_Vendor, CP_Product;
+	BOOLEAN CP_HaveCustomData;
+	int     CP_PreferredX, CP_PreferredY;
+	int	CP_MaxX, CP_MaxY, CP_MaxClock;
+	int     CP_HDisplay[7], CP_VDisplay[7];	/* For Custom LCD panel dimensions */
+    	int     CP_HTotal[7], CP_VTotal[7];
+    	int     CP_HSyncStart[7], CP_VSyncStart[7];
+    	int     CP_HSyncEnd[7], CP_VSyncEnd[7];
+	int     CP_HBlankStart[7], CP_VBlankStart[7];
+	int     CP_HBlankEnd[7], CP_VBlankEnd[7];
+    	int     CP_Clock[7];
+	BOOLEAN CP_DataValid[7];
+	BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
 } SiS_Private;
 
 #endif
diff -urN linux-2.4.22-pre2/drivers/video/vesafb.c linux-2.4.22-pre3/drivers/video/vesafb.c
--- linux-2.4.22-pre2/drivers/video/vesafb.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/drivers/video/vesafb.c	2003-07-05 18:11:06.000000000 -0700
@@ -94,6 +94,7 @@
 
 static int             inverse   = 0;
 static int             mtrr      = 0;
+static int	 vram __initdata = 0;	/* needed for vram boot option */
 static int             currcon   = 0;
 
 static int             pmi_setpal = 0;	/* pmi for palette changes ??? */
@@ -479,6 +480,10 @@
 			pmi_setpal=1;
 		else if (! strcmp(this_opt, "mtrr"))
 			mtrr=1;
+		/* checks for vram boot option */
+		else if (! strncmp(this_opt, "vram:", 5))
+			vram = simple_strtoul(this_opt+5, NULL, 0);
+
 		else if (!strncmp(this_opt, "font:", 5))
 			strcpy(fb_info.fontname, this_opt+5);
 	}
@@ -520,7 +525,20 @@
 	video_width         = screen_info.lfb_width;
 	video_height        = screen_info.lfb_height;
 	video_linelength    = screen_info.lfb_linelength;
-	video_size          = screen_info.lfb_width *	screen_info.lfb_height * video_bpp;
+
+	/* remap memory according to videomode, multiply by 2 to get space for doublebuffering */
+	video_size          = screen_info.lfb_width *	screen_info.lfb_height * video_bpp / 8 * 2;
+
+	/* check that we don't remap more memory than old cards have */
+	if (video_size > screen_info.lfb_size * 65536)
+		video_size = screen_info.lfb_size * 65536;
+	
+	/* FIXME: Should we clip against declared size for banked devices ? */
+	
+	/* sets video_size according to vram boot option */
+	if (vram && vram * 1024 * 1024 != video_size)
+		video_size = vram * 1024 * 1024;
+		
 	video_visual = (video_bpp == 8) ?
 		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
 
diff -urN linux-2.4.22-pre2/fs/Config.in linux-2.4.22-pre3/fs/Config.in
--- linux-2.4.22-pre2/fs/Config.in	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/Config.in	2003-07-05 18:11:06.000000000 -0700
@@ -22,6 +22,8 @@
 dep_tristate 'BeOS file systemv(BeFS) support (read only) (EXPERIMENTAL)' CONFIG_BEFS_FS $CONFIG_EXPERIMENTAL
 dep_mbool '  Debug Befs' CONFIG_BEFS_DEBUG $CONFIG_BEFS_FS
 
+dep_tristate 'Apple Extended HFS file system support (EXPERIMENTAL)' CONFIG_HFSPLUS_FS $CONFIG_EXPERIMENTAL
+
 dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
 
 tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS
diff -urN linux-2.4.22-pre2/fs/Makefile linux-2.4.22-pre3/fs/Makefile
--- linux-2.4.22-pre2/fs/Makefile	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/Makefile	2003-07-05 18:11:06.000000000 -0700
@@ -42,6 +42,7 @@
 subdir-$(CONFIG_ISO9660_FS)	+= isofs
 subdir-$(CONFIG_DEVFS_FS)	+= devfs
 subdir-$(CONFIG_HFS_FS)		+= hfs
+subdir-$(CONFIG_HFSPLUS_FS)	+= hfsplus
 subdir-$(CONFIG_VXFS_FS)	+= freevxfs
 subdir-$(CONFIG_NFS_FS)		+= nfs
 subdir-$(CONFIG_NFSD)		+= nfsd
diff -urN linux-2.4.22-pre2/fs/buffer.c linux-2.4.22-pre3/fs/buffer.c
--- linux-2.4.22-pre2/fs/buffer.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/fs/buffer.c	2003-07-05 18:11:06.000000000 -0700
@@ -153,10 +153,23 @@
 	get_bh(bh);
 	add_wait_queue(&bh->b_wait, &wait);
 	do {
-		run_task_queue(&tq_disk);
 		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
 		if (!buffer_locked(bh))
 			break;
+		/*
+		 * We must read tq_disk in TQ_ACTIVE after the
+		 * add_wait_queue effect is visible to other cpus.
+		 * We could unplug some line above it wouldn't matter
+		 * but we can't do that right after add_wait_queue
+		 * without an smp_mb() in between because spin_unlock
+		 * has inclusive semantics.
+		 * Doing it here is the most efficient place so we
+		 * don't do a suprious unplug if we get a racy
+		 * wakeup that make buffer_locked to return 0, and
+		 * doing it here avoids an explicit smp_mb() we
+		 * rely on the implicit one in set_task_state.
+		 */
+		run_task_queue(&tq_disk);
 		schedule();
 	} while (buffer_locked(bh));
 	tsk->state = TASK_RUNNING;
@@ -1516,6 +1529,9 @@
 
 	/* Done - end_buffer_io_async will unlock */
 	SetPageUptodate(page);
+
+	wakeup_page_waiters(page);
+
 	return 0;
 
 out:
@@ -1547,6 +1563,7 @@
 	} while (bh != head);
 	if (need_unlock)
 		UnlockPage(page);
+	wakeup_page_waiters(page);
 	return err;
 }
 
@@ -1774,6 +1791,8 @@
 		else
 			submit_bh(READ, bh);
 	}
+
+	wakeup_page_waiters(page);
 	
 	return 0;
 }
@@ -2400,6 +2419,7 @@
 		submit_bh(rw, bh);
 		bh = next;
 	} while (bh != head);
+	wakeup_page_waiters(page);
 	return 0;
 }
 
diff -urN linux-2.4.22-pre2/fs/exec.c linux-2.4.22-pre3/fs/exec.c
--- linux-2.4.22-pre2/fs/exec.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/fs/exec.c	2003-07-05 18:11:06.000000000 -0700
@@ -286,6 +286,8 @@
 	pgd_t * pgd;
 	pmd_t * pmd;
 	pte_t * pte;
+	struct vm_area_struct *vma; 
+	pgprot_t prot = PAGE_COPY; 
 
 	if (page_count(page) != 1)
 		printk(KERN_ERR "mem_map disagrees with %p at %08lx\n", page, address);
@@ -303,7 +305,11 @@
 	lru_cache_add(page);
 	flush_dcache_page(page);
 	flush_page_to_ram(page);
-	set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY))));
+	/* lookup is cheap because there is only a single entry in the list */
+	vma = find_vma(tsk->mm, address); 
+	if (vma) 
+		prot = vma->vm_page_prot;
+	set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, prot))));
 	tsk->mm->rss++;
 	spin_unlock(&tsk->mm->page_table_lock);
 
@@ -338,8 +344,8 @@
 		mpnt->vm_mm = current->mm;
 		mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
 		mpnt->vm_end = STACK_TOP;
-		mpnt->vm_page_prot = PAGE_COPY;
 		mpnt->vm_flags = VM_STACK_FLAGS;
+		mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7];
 		mpnt->vm_ops = NULL;
 		mpnt->vm_pgoff = 0;
 		mpnt->vm_file = NULL;
diff -urN linux-2.4.22-pre2/fs/fat/inode.c linux-2.4.22-pre3/fs/fat/inode.c
--- linux-2.4.22-pre2/fs/fat/inode.c	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/fs/fat/inode.c	2003-07-05 18:11:06.000000000 -0700
@@ -637,6 +637,7 @@
 	sbi->cluster_bits = ffs(logical_sector_size * sbi->cluster_size) - 1;
 	sbi->fats = b->fats;
 	sbi->fat_start = CF_LE_W(b->reserved);
+	sbi->prev_free = 0;
 	if (!b->fat_length && b->fat32_length) {
 		struct fat_boot_fsinfo *fsinfo;
 		struct buffer_head *fsinfo_bh;
@@ -675,6 +676,7 @@
 			       sbi->fsinfo_sector);
 		} else {
 			sbi->free_clusters = CF_LE_L(fsinfo->free_clusters);
+			sbi->prev_free = CF_LE_L(fsinfo->next_cluster);
 		}
 
 		if (fsinfo_block != 0)
@@ -754,7 +756,6 @@
 	sb->s_magic = MSDOS_SUPER_MAGIC;
 	/* set up enough so that it can read an inode */
 	init_MUTEX(&sbi->fat_lock);
-	sbi->prev_free = 0;
 
 	cp = opts.codepage ? opts.codepage : 437;
 	sprintf(buf, "cp%d", cp);
diff -urN linux-2.4.22-pre2/fs/fat/misc.c linux-2.4.22-pre3/fs/fat/misc.c
--- linux-2.4.22-pre2/fs/fat/misc.c	2001-10-12 13:48:42.000000000 -0700
+++ linux-2.4.22-pre3/fs/fat/misc.c	2003-07-05 18:11:06.000000000 -0700
@@ -108,6 +108,7 @@
 		return;
 	}
 	fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters);
+	fsinfo->next_cluster = CF_LE_L(MSDOS_SB(sb)->prev_free);
 	fat_mark_buffer_dirty(sb, bh);
 	fat_brelse(sb, bh);
 }
diff -urN linux-2.4.22-pre2/fs/hfsplus/Makefile linux-2.4.22-pre3/fs/hfsplus/Makefile
--- linux-2.4.22-pre2/fs/hfsplus/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/Makefile	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,17 @@
+#
+# Makefile for the linux hfsplus filesystem routines.
+#
+# 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...
+
+O_TARGET :=	hfsplus.o
+
+obj-y    :=	super.o options.o inode.o extents.o catalog.o dir.o btree.o \
+		bnode.o brec.o bfind.o btiter.o tables.o unicode.o wrapper.o
+
+obj-m	 :=	$(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.22-pre2/fs/hfsplus/README linux-2.4.22-pre3/fs/hfsplus/README
--- linux-2.4.22-pre2/fs/hfsplus/README	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/README	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,33 @@
+    Copyright (C) 2001 Brad Boyer
+    Copyright (C) 2003 Ardis Technologies bv
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either 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
+
+
+HFS+ is the standard volume format for Mac OS X.
+
+A basic overview and also a detailed description of the HFS+ volume format
+is provided by Apple's technical note 1150.
+
+The new driver provides full access to HFS+ plus volumes under Linux. It
+bases on the driver by Brad Boyer at 
+http://sourceforge.net/projects/linux-hfsplus.
+
+This driver now supports full read and write access and has a better
+perfomance. It also supports hard links and the resource fork is accessible
+via /rsrc.
+
+This is a beta release, it was intensively tested, but use at your own risk.
+
diff -urN linux-2.4.22-pre2/fs/hfsplus/bfind.c linux-2.4.22-pre3/fs/hfsplus/bfind.c
--- linux-2.4.22-pre2/fs/hfsplus/bfind.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/bfind.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,150 @@
+/*
+ *  linux/fs/hfsplus/bfind.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Search routines for btrees
+ */
+
+#include <linux/slab.h>
+#include "hfsplus_fs.h"
+
+/* Find the record in bnode that best matches key (not greater than...)*/
+void hfsplus_find_rec(hfsplus_bnode *bnode, struct hfsplus_find_data *fd)
+{
+	int cmpval;
+	u16 off, len, keylen;
+	int rec;
+	int b, e;
+
+	b = 0;
+	e = bnode->num_recs - 1;
+	do {
+		rec = (e + b) / 2;
+		len = hfsplus_brec_lenoff(bnode, rec, &off);
+		keylen = hfsplus_brec_keylen(bnode, rec);
+		hfsplus_bnode_readbytes(bnode, fd->key, off, keylen);
+		cmpval = bnode->tree->keycmp(fd->key, fd->search_key);
+		if (!cmpval) {
+			fd->exact = 1;
+			e = rec;
+			break;
+		}
+		if (cmpval < 0)
+			b = rec + 1;
+		else
+			e = rec - 1;
+	} while (b <= e);
+	//printk("%d: %d,%d,%d\n", bnode->this, b, e, rec);
+	if (rec != e && e >= 0) {
+		len = hfsplus_brec_lenoff(bnode, e, &off);
+		keylen = hfsplus_brec_keylen(bnode, e);
+		hfsplus_bnode_readbytes(bnode, fd->key, off, keylen);
+	}
+	fd->record = e;
+	fd->keyoffset = off;
+	fd->keylength = keylen;
+	fd->entryoffset = off + keylen;
+	fd->entrylength = len - keylen;
+}
+
+/* Traverse a B*Tree from the root to a leaf finding best fit to key */
+/* Return allocated copy of node found, set recnum to best record */
+int hfsplus_btree_find(struct hfsplus_find_data *fd)
+{
+	hfsplus_btree *tree;
+	hfsplus_bnode *bnode;
+	u32 data, nidx, parent;
+	int height, err;
+
+	tree = fd->tree;
+	if (fd->bnode)
+		hfsplus_put_bnode(fd->bnode);
+	fd->bnode = NULL;
+	fd->exact = 0;
+	nidx = tree->root;
+	if (!nidx)
+		return -ENOENT;
+	height = tree->depth;
+	err = 0;
+	parent = 0;
+	for (;;) {
+		bnode = hfsplus_find_bnode(tree, nidx);
+		if (!bnode) {
+			err = -EIO;
+			break;
+		}
+		if (bnode->height != height)
+			goto invalid;
+		if (bnode->kind != (--height ? HFSPLUS_NODE_NDX : HFSPLUS_NODE_LEAF))
+			goto invalid;
+		bnode->parent = parent;
+
+		hfsplus_find_rec(bnode, fd);
+		if (fd->record < 0) {
+			err = -ENOENT;
+			goto release;
+		}
+		if (!height) {
+			if (!fd->exact)
+				err = -ENOENT;
+			break;
+		}
+
+		parent = nidx;
+		hfsplus_bnode_readbytes(bnode, &data, fd->entryoffset, 4);
+		nidx = be32_to_cpu(data);
+		hfsplus_put_bnode(bnode);
+	}
+	fd->bnode = bnode;
+	return err;
+
+invalid:
+	printk("HFS+-fs: inconsistency in B*Tree\n");
+	err = -EIO;
+release:
+	hfsplus_put_bnode(bnode);
+	return err;
+}
+
+int hfsplus_btree_find_entry(struct hfsplus_find_data *fd,
+			     void *entry, int entry_len)
+{
+	int res;
+
+	res = hfsplus_btree_find(fd);
+	if (res)
+		return res;
+	if (fd->entrylength > entry_len)
+		return -EINVAL;
+	hfsplus_bnode_readbytes(fd->bnode, entry, fd->entryoffset, fd->entrylength);
+	return 0;
+}
+
+int hfsplus_find_init(hfsplus_btree *tree, struct hfsplus_find_data *fd)
+{
+	fd->tree = tree;
+	fd->bnode = NULL;
+	fd->search_key = kmalloc(tree->max_key_len + 2, GFP_KERNEL);
+	if (!fd->search_key)
+		return -ENOMEM;
+	fd->key = kmalloc(tree->max_key_len + 2, GFP_KERNEL);
+	if (!fd->key) {
+		kfree(fd->search_key);
+		return -ENOMEM;
+	}
+	dprint(DBG_BNODE_REFS, "find_init: %d (%p)\n", tree->cnid, __builtin_return_address(0));
+	down(&tree->tree_lock);
+	return 0;
+}
+
+void hfsplus_find_exit(struct hfsplus_find_data *fd)
+{
+	hfsplus_put_bnode(fd->bnode);
+	kfree(fd->search_key);
+	kfree(fd->key);
+	dprint(DBG_BNODE_REFS, "find_exit: %d (%p)\n", fd->tree->cnid, __builtin_return_address(0));
+	up(&fd->tree->tree_lock);
+	fd->tree = NULL;
+}
diff -urN linux-2.4.22-pre2/fs/hfsplus/bnode.c linux-2.4.22-pre3/fs/hfsplus/bnode.c
--- linux-2.4.22-pre2/fs/hfsplus/bnode.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/bnode.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,1030 @@
+/*
+ *  linux/fs/hfsplus/bnode.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Handle basic btree node operations
+ */
+
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/fs.h>
+#include <linux/swap.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <linux/buffer_head.h>
+#endif
+
+#include "hfsplus_fs.h"
+#include "hfsplus_raw.h"
+
+#define REF_PAGES	0
+
+int hfsplus_update_idx_rec(struct hfsplus_find_data *fd);
+
+/* Get the given block associated with the tree owning node */
+struct buffer_head *hfsplus_getblk(struct inode *inode, unsigned long n)
+{
+	struct super_block *sb;
+	struct buffer_head tmp_bh;
+
+	sb = inode->i_sb;
+	if (hfsplus_get_block(inode, n, &tmp_bh, 1)) {
+		printk("HFS+-fs: Failed to find block for B*Tree data\n");
+		return NULL;
+	}
+	return sb_bread(sb, tmp_bh.b_blocknr);
+}
+
+/* Copy a specified range of bytes from the raw data of a node */
+void hfsplus_bnode_readbytes(hfsplus_bnode *node, void *buf,
+			     unsigned long off, unsigned long len)
+{
+	unsigned long l;
+	struct page **pagep;
+
+	off += node->page_offset;
+	pagep = node->page + (off >> PAGE_CACHE_SHIFT);
+	off &= ~PAGE_CACHE_MASK;
+
+	l = min(len, PAGE_CACHE_SIZE - off);
+	memcpy(buf, hfsplus_kmap(*pagep) + off, l);
+	hfsplus_kunmap(*pagep++);
+
+	while ((len -= l)) {
+		buf += l;
+		l = min(len, PAGE_CACHE_SIZE);
+		memcpy(buf, hfsplus_kmap(*pagep), l);
+		hfsplus_kunmap(*pagep++);
+	}
+}
+
+u16 hfsplus_bnode_read_u16(hfsplus_bnode *node, unsigned long off)
+{
+	u16 data;
+	// optimize later...
+	hfsplus_bnode_readbytes(node, &data, off, 2);
+	return be16_to_cpu(data);
+}
+
+void hfsplus_bnode_read_key(hfsplus_bnode *node, void *key, unsigned long off)
+{
+	hfsplus_btree *tree;
+	unsigned long key_len;
+
+	tree = node->tree;
+	if (node->kind == HFSPLUS_NODE_LEAF ||
+	    tree->attributes & HFSPLUS_TREE_VAR_NDXKEY_SIZE)
+		key_len = hfsplus_bnode_read_u16(node, off) + 2;
+	else
+		key_len = tree->max_key_len + 2;
+	
+	hfsplus_bnode_readbytes(node, key, off, key_len);	
+}
+
+void hfsplus_bnode_writebytes(hfsplus_bnode *node, void *buf,
+			      unsigned long off, unsigned long len)
+{
+	unsigned long l;
+	struct page **pagep;
+
+	off += node->page_offset;
+	pagep = node->page + (off >> PAGE_CACHE_SHIFT);
+	off &= ~PAGE_CACHE_MASK;
+
+	l = min(len, PAGE_CACHE_SIZE - off);
+	memcpy(hfsplus_kmap(*pagep) + off, buf, l);
+	set_page_dirty(*pagep);
+	hfsplus_kunmap(*pagep++);
+
+	while ((len -= l)) {
+		buf += l;
+		l = min(len, PAGE_CACHE_SIZE);
+		memcpy(hfsplus_kmap(*pagep), buf, l);
+		set_page_dirty(*pagep);
+		hfsplus_kunmap(*pagep++);
+	}
+}
+
+void hfsplus_bnode_write_u16(hfsplus_bnode *node, unsigned long off, u16 data)
+{
+	data = cpu_to_be16(data);
+	// optimize later...
+	hfsplus_bnode_writebytes(node, &data, off, 2);
+}
+
+void hfsplus_bnode_copybytes(hfsplus_bnode *dst_node, unsigned long dst,
+			     hfsplus_bnode *src_node, unsigned long src, unsigned long len)
+{
+	struct hfsplus_btree *tree;
+	struct page **src_page, **dst_page;
+	unsigned long l;
+
+	dprint(DBG_BNODE_MOD, "copybytes: %lu,%lu,%lu\n", dst, src, len);
+	if (!len)
+		return;
+	tree = src_node->tree;
+	src += src_node->page_offset;
+	dst += dst_node->page_offset;
+	src_page = src_node->page + (src >> PAGE_CACHE_SHIFT);
+	src &= ~PAGE_CACHE_MASK;
+	dst_page = dst_node->page + (dst >> PAGE_CACHE_SHIFT);
+	dst &= ~PAGE_CACHE_MASK;
+
+	if (src == dst) {
+		l = min(len, PAGE_CACHE_SIZE - src);
+		memcpy(hfsplus_kmap(*dst_page) + src, hfsplus_kmap(*src_page) + src, l);
+		hfsplus_kunmap(*src_page++);
+		set_page_dirty(*dst_page);
+		hfsplus_kunmap(*dst_page++);
+
+		while ((len -= l)) {
+			l = min(len, PAGE_CACHE_SIZE);
+			memcpy(hfsplus_kmap(*dst_page), hfsplus_kmap(*src_page), l);
+			hfsplus_kunmap(*src_page++);
+			set_page_dirty(*dst_page);
+			hfsplus_kunmap(*dst_page++);
+		}
+	} else {
+		void *src_ptr, *dst_ptr;
+
+		do {
+			src_ptr = hfsplus_kmap(*src_page) + src;
+			dst_ptr = hfsplus_kmap(*dst_page) + dst;
+			if (PAGE_CACHE_SIZE - src < PAGE_CACHE_SIZE - dst) {
+				l = PAGE_CACHE_SIZE - src;
+				src = 0;
+				dst += l;
+			} else {
+				l = PAGE_CACHE_SIZE - dst;
+				src += l;
+				dst = 0;
+			}
+			l = min(len, l);
+			memcpy(dst_ptr, src_ptr, l);
+			hfsplus_kunmap(*src_page);
+			set_page_dirty(*dst_page);
+			hfsplus_kunmap(*dst_page);
+			if (!dst)
+				dst_page++;
+			else
+				src_page++;
+		} while ((len -= l));
+	}
+}
+
+void hfsplus_bnode_movebytes(hfsplus_bnode *node, unsigned long dst,
+			     unsigned long src, unsigned long len)
+{
+	struct page **src_page, **dst_page;
+	unsigned long l;
+
+	dprint(DBG_BNODE_MOD, "movebytes: %lu,%lu,%lu\n", dst, src, len);
+	if (!len)
+		return;
+	src += node->page_offset;
+	dst += node->page_offset;
+	if (dst > src) {
+		src += len - 1;
+		src_page = node->page + (src >> PAGE_CACHE_SHIFT);
+		src = (src & ~PAGE_CACHE_MASK) + 1;
+		dst += len - 1;
+		dst_page = node->page + (dst >> PAGE_CACHE_SHIFT);
+		dst = (dst & ~PAGE_CACHE_MASK) + 1;
+
+		if (src == dst) {
+			while (src < len) {
+				memmove(hfsplus_kmap(*dst_page), hfsplus_kmap(*src_page), src);
+				hfsplus_kunmap(*src_page--);
+				set_page_dirty(*dst_page);
+				hfsplus_kunmap(*dst_page--);
+				len -= src;
+				src = PAGE_CACHE_SIZE;
+			}
+			src -= len;
+			memmove(hfsplus_kmap(*dst_page) + src, hfsplus_kmap(*src_page) + src, len);
+			hfsplus_kunmap(*src_page);
+			set_page_dirty(*dst_page);
+			hfsplus_kunmap(*dst_page);
+		} else {
+			void *src_ptr, *dst_ptr;
+
+			do {
+				src_ptr = hfsplus_kmap(*src_page) + src;
+				dst_ptr = hfsplus_kmap(*dst_page) + dst;
+				if (src < dst) {
+					l = src;
+					src = PAGE_CACHE_SIZE;
+					dst -= l;
+				} else {
+					l = dst;
+					src -= l;
+					dst = PAGE_CACHE_SIZE;
+				}
+				l = min(len, l);
+				memmove(dst_ptr - l, src_ptr - l, l);
+				hfsplus_kunmap(*src_page);
+				set_page_dirty(*dst_page);
+				hfsplus_kunmap(*dst_page);
+				if (dst == PAGE_CACHE_SIZE)
+					dst_page--;
+				else
+					src_page--;
+			} while ((len -= l));
+		}
+	} else {
+		src_page = node->page + (src >> PAGE_CACHE_SHIFT);
+		src &= ~PAGE_CACHE_MASK;
+		dst_page = node->page + (dst >> PAGE_CACHE_SHIFT);
+		dst &= ~PAGE_CACHE_MASK;
+
+		if (src == dst) {
+			l = min(len, PAGE_CACHE_SIZE - src);
+			memmove(hfsplus_kmap(*dst_page) + src, hfsplus_kmap(*src_page) + src, l);
+			hfsplus_kunmap(*src_page++);
+			set_page_dirty(*dst_page);
+			hfsplus_kunmap(*dst_page++);
+
+			while ((len -= l)) {
+				l = min(len, PAGE_CACHE_SIZE);
+				memmove(hfsplus_kmap(*dst_page), hfsplus_kmap(*src_page), l);
+				hfsplus_kunmap(*src_page++);
+				set_page_dirty(*dst_page);
+				hfsplus_kunmap(*dst_page++);
+			}
+		} else {
+			void *src_ptr, *dst_ptr;
+
+			do {
+				src_ptr = hfsplus_kmap(*src_page) + src;
+				dst_ptr = hfsplus_kmap(*dst_page) + dst;
+				if (PAGE_CACHE_SIZE - src < PAGE_CACHE_SIZE - dst) {
+					l = PAGE_CACHE_SIZE - src;
+					src = 0;
+					dst += l;
+				} else {
+					l = PAGE_CACHE_SIZE - dst;
+					src += l;
+					dst = 0;
+				}
+				l = min(len, l);
+				memmove(dst_ptr, src_ptr, l);
+				hfsplus_kunmap(*src_page);
+				set_page_dirty(*dst_page);
+				hfsplus_kunmap(*dst_page);
+				if (!dst)
+					dst_page++;
+				else
+					src_page++;
+			} while ((len -= l));
+		}
+	}
+}
+
+void hfsplus_bnode_dump(hfsplus_bnode *node)
+{
+	hfsplus_btree_node_desc desc;
+	u32 cnid;
+	int i, off, key_off;
+
+	dprint(DBG_BNODE_MOD, "bnode: %d\n", node->this);
+	hfsplus_bnode_readbytes(node, &desc, 0, sizeof(desc));
+	dprint(DBG_BNODE_MOD, "%d, %d, %d, %d, %d\n",
+		be32_to_cpu(desc.next), be32_to_cpu(desc.prev),
+		desc.kind, desc.height, be16_to_cpu(desc.num_rec));
+
+	off = node->tree->node_size - 2;
+	for (i = be16_to_cpu(desc.num_rec); i >= 0; off -= 2, i--) {
+		key_off = hfsplus_bnode_read_u16(node, off);
+		dprint(DBG_BNODE_MOD, " %d", key_off);
+		if (i && node->kind == HFSPLUS_NODE_NDX) {
+			int tmp;
+
+			tmp = hfsplus_bnode_read_u16(node, key_off);
+			dprint(DBG_BNODE_MOD, " (%d", tmp);
+			hfsplus_bnode_readbytes(node, &cnid, key_off + 2 + tmp, 4);
+			dprint(DBG_BNODE_MOD, ",%d)", be32_to_cpu(cnid));
+		}
+	}
+	dprint(DBG_BNODE_MOD, "\n");
+}
+
+int hfsplus_btree_add_level(hfsplus_btree *tree)
+{
+	hfsplus_bnode *node, *new_node;
+	hfsplus_btree_node_desc node_desc;
+	int key_size, rec;
+	u32 cnid;
+
+	node = NULL;
+	if (tree->root)
+		node = hfsplus_find_bnode(tree, tree->root);
+	new_node = hfsplus_btree_alloc_node(tree);
+	if (IS_ERR(new_node))
+		return PTR_ERR(new_node);
+
+	tree->root = new_node->this;
+	if (!tree->depth) {
+		tree->leaf_head = tree->leaf_tail = new_node->this;
+		new_node->kind = HFSPLUS_NODE_LEAF;
+		new_node->num_recs = 0;
+	} else {
+		new_node->kind = HFSPLUS_NODE_NDX;
+		new_node->num_recs = 1;
+	}
+	new_node->parent = 0;
+	new_node->next = 0;
+	new_node->prev = 0;
+	new_node->height = ++tree->depth;
+
+	node_desc.next = cpu_to_be32(new_node->next);
+	node_desc.prev = cpu_to_be32(new_node->prev);
+	node_desc.kind = new_node->kind;
+	node_desc.height = new_node->height;
+	node_desc.num_rec = cpu_to_be16(new_node->num_recs);
+	node_desc.reserved = 0;
+	hfsplus_bnode_writebytes(new_node, &node_desc, 0, sizeof(node_desc));
+
+	rec = tree->node_size - 2;
+	hfsplus_bnode_write_u16(new_node, rec, 14);
+
+	if (node) {
+		/* insert old root idx into new root */
+		node->parent = tree->root;
+		key_size = hfsplus_bnode_read_u16(node, 14) + 2;
+		// key_size if index node
+		hfsplus_bnode_copybytes(new_node, 14, node, 14, key_size);
+		cnid = cpu_to_be32(node->this);
+		hfsplus_bnode_writebytes(new_node, &cnid, 14 + key_size, 4);
+
+		rec -= 2;
+		hfsplus_bnode_write_u16(new_node, rec, 14 + key_size + 4);
+
+		hfsplus_put_bnode(node);
+	}
+	hfsplus_put_bnode(new_node);
+	mark_inode_dirty(tree->inode);
+
+	return 0;
+}
+
+hfsplus_bnode *hfsplus_bnode_split(struct hfsplus_find_data *fd)
+{
+	hfsplus_btree *tree;
+	hfsplus_bnode *node, *new_node;
+	hfsplus_btree_node_desc node_desc;
+	int num_recs, new_rec_off, new_off, old_rec_off;
+	int data_start, data_end, size;
+
+	tree = fd->tree;
+	node = fd->bnode;
+	new_node = hfsplus_btree_alloc_node(tree);
+	if (IS_ERR(new_node))
+		return new_node;
+	hfsplus_get_bnode(node);
+	dprint(DBG_BNODE_MOD, "split_nodes: %d - %d - %d\n",
+		node->this, new_node->this, node->next);
+	new_node->next = node->next;
+	new_node->prev = node->this;
+	new_node->parent = node->parent;
+	new_node->kind = node->kind;
+	new_node->height = node->height;
+
+	size = tree->node_size / 2;
+	old_rec_off = tree->node_size - 4;
+	num_recs = 1;
+	for (;;) {
+		data_start = hfsplus_bnode_read_u16(node, old_rec_off);
+		if (data_start > size)
+			break;
+		old_rec_off -= 2;
+		num_recs++;
+		if (num_recs < node->num_recs)
+			continue;
+		/* panic? */
+		hfsplus_put_bnode(node);
+		hfsplus_put_bnode(new_node);
+		return NULL;
+	}
+
+	if (fd->record + 1 < num_recs) {
+		/* new record is in the lower half,
+		 * so leave some more space there
+		 */
+		old_rec_off += 2;
+		num_recs--;
+		data_start = hfsplus_bnode_read_u16(node, old_rec_off);
+	} else {
+		hfsplus_put_bnode(node);
+		hfsplus_get_bnode(new_node);
+		fd->bnode = new_node;
+		fd->record -= num_recs;
+		fd->keyoffset -= data_start;
+		fd->entryoffset -= data_start;
+	}
+	new_node->num_recs = node->num_recs - num_recs;
+	node->num_recs = num_recs;
+
+	new_rec_off = tree->node_size - 2;
+	new_off = 14;
+	size = data_start - new_off;
+	num_recs = new_node->num_recs;
+	data_end = data_start;
+	while (num_recs) {
+		hfsplus_bnode_write_u16(new_node, new_rec_off, new_off);
+		old_rec_off -= 2;
+		new_rec_off -= 2;
+		data_end = hfsplus_bnode_read_u16(node, old_rec_off);
+		new_off = data_end - size;
+		num_recs--;
+	}
+	hfsplus_bnode_write_u16(new_node, new_rec_off, new_off);
+	hfsplus_bnode_copybytes(new_node, 14, node, data_start, data_end - data_start);
+
+	/* update new bnode header */
+	node_desc.next = cpu_to_be32(new_node->next);
+	node_desc.prev = cpu_to_be32(new_node->prev);
+	node_desc.kind = new_node->kind;
+	node_desc.height = new_node->height;
+	node_desc.num_rec = cpu_to_be16(new_node->num_recs);
+	node_desc.reserved = 0;
+	hfsplus_bnode_writebytes(new_node, &node_desc, 0, sizeof(node_desc));
+
+	/* update previous bnode header */
+	node->next = new_node->this;
+	hfsplus_bnode_readbytes(node, &node_desc, 0, sizeof(node_desc));
+	node_desc.next = cpu_to_be32(node->next);
+	node_desc.num_rec = cpu_to_be16(node->num_recs);
+	hfsplus_bnode_writebytes(node, &node_desc, 0, sizeof(node_desc));
+
+	/* update next bnode header */
+	if (new_node->next) {
+		hfsplus_bnode *next_node = hfsplus_find_bnode(tree, new_node->next);
+		next_node->prev = new_node->this;
+		hfsplus_bnode_readbytes(next_node, &node_desc, 0, sizeof(node_desc));
+		node_desc.prev = cpu_to_be32(next_node->prev);
+		hfsplus_bnode_writebytes(next_node, &node_desc, 0, sizeof(node_desc));
+		hfsplus_put_bnode(next_node);
+	} else if (node->this == tree->leaf_tail) {
+		/* if there is no next node, this might be the new tail */
+		tree->leaf_tail = new_node->this;
+		mark_inode_dirty(tree->inode);
+	}
+
+	hfsplus_bnode_dump(node);
+	hfsplus_bnode_dump(new_node);
+	hfsplus_put_bnode(node);
+
+	return new_node;
+}
+
+int hfsplus_bnode_insert_rec(struct hfsplus_find_data *fd, void *entry, int entry_len)
+{
+	hfsplus_btree *tree;
+	hfsplus_bnode *node, *new_node;
+	int size, key_len, rec;
+	int data_off, end_off;
+	int idx_rec_off, data_rec_off, end_rec_off;
+	u32 cnid;
+
+	tree = fd->tree;
+	if (!fd->bnode) {
+		if (!tree->root)
+			hfsplus_btree_add_level(tree);
+		fd->bnode = hfsplus_find_bnode(tree, tree->leaf_head);
+		fd->record = -1;
+	}
+	new_node = NULL;
+again:
+	/* new record idx and complete record size */
+	rec = fd->record + 1;
+	key_len = be16_to_cpu(fd->search_key->key_len) + 2;
+	size = key_len + entry_len;
+
+	node = fd->bnode;
+	hfsplus_bnode_dump(node);
+	/* get last offset */
+	end_rec_off = tree->node_size - (node->num_recs + 1) * 2;
+	end_off = hfsplus_bnode_read_u16(node, end_rec_off);
+	end_rec_off -= 2;
+	dprint(DBG_BNODE_MOD, "insert_rec: %d, %d, %d, %d\n", rec, size, end_off, end_rec_off);
+	if (size > end_rec_off - end_off) {
+		if (new_node)
+			panic("not enough room!\n");
+		new_node = hfsplus_bnode_split(fd);
+		if (IS_ERR(new_node))
+			return PTR_ERR(new_node);
+		goto again;
+	}
+	if (node->kind == HFSPLUS_NODE_LEAF) {
+		tree->leaf_count++;
+		mark_inode_dirty(tree->inode);
+	}
+	node->num_recs++;
+	/* write new last offset */
+	hfsplus_bnode_write_u16(node, offsetof(hfsplus_btree_node_desc, num_rec), node->num_recs);
+	hfsplus_bnode_write_u16(node, end_rec_off, end_off + size);
+	data_off = end_off;
+	data_rec_off = end_rec_off + 2;
+	idx_rec_off = tree->node_size - (rec + 1) * 2;
+	if (idx_rec_off == data_rec_off)
+		goto skip;
+	/* move all following entries */
+	do {
+		data_off = hfsplus_bnode_read_u16(node, data_rec_off + 2);
+		hfsplus_bnode_write_u16(node, data_rec_off, data_off + size);
+		data_rec_off += 2;
+	} while (data_rec_off < idx_rec_off);
+
+	/* move data away */
+	hfsplus_bnode_movebytes(node, data_off + size, data_off,
+				end_off - data_off);
+
+skip:
+	hfsplus_bnode_writebytes(node, fd->search_key, data_off, key_len);
+	hfsplus_bnode_writebytes(node, entry, data_off + key_len, entry_len);
+	hfsplus_bnode_dump(node);
+
+	if (new_node) {
+		if (!rec && new_node != node)
+			hfsplus_update_idx_rec(fd);
+
+		hfsplus_put_bnode(fd->bnode);
+		if (!new_node->parent) {
+			hfsplus_btree_add_level(tree);
+			new_node->parent = tree->root;
+		}
+		fd->bnode = hfsplus_find_bnode(tree, new_node->parent);
+
+		/* create index data entry */
+		cnid = cpu_to_be32(new_node->this);
+		entry = &cnid;
+		entry_len = sizeof(cnid);
+
+		/* get index key */
+		hfsplus_bnode_read_key(new_node, fd->search_key, 14);
+		hfsplus_find_rec(fd->bnode, fd);
+
+		hfsplus_put_bnode(new_node);
+		new_node = NULL;
+		goto again;
+	}
+
+	if (!rec)
+		hfsplus_update_idx_rec(fd);
+
+	return 0;
+}
+
+int hfsplus_update_idx_rec(struct hfsplus_find_data *fd)
+{
+	hfsplus_btree *tree;
+	hfsplus_bnode *node, *new_node, *parent;
+	int newkeylen, diff;
+	int rec, rec_off, end_rec_off;
+	int start_off, end_off;
+
+	tree = fd->tree;
+	node = fd->bnode;
+	new_node = NULL;
+	if (!node->parent)
+		return 0;
+
+again:
+	parent = hfsplus_find_bnode(tree, node->parent);
+	hfsplus_find_rec(parent, fd);
+	hfsplus_bnode_dump(parent);
+	rec = fd->record;
+
+	/* size difference between old and new key */
+	newkeylen = hfsplus_bnode_read_u16(node, 14) + 2;
+	dprint(DBG_BNODE_MOD, "update_rec: %d, %d, %d\n", rec, fd->keylength, newkeylen);
+
+	rec_off = tree->node_size - (rec + 2) * 2;
+	end_rec_off = tree->node_size - (parent->num_recs + 1) * 2;
+	diff = newkeylen - fd->keylength;
+	if (!diff)
+		goto skip;
+	if (diff > 0) {
+		end_off = hfsplus_bnode_read_u16(parent, end_rec_off);
+		if (end_rec_off - end_off < diff) {
+
+			printk("splitting index node...\n");
+			fd->bnode = parent;
+			new_node = hfsplus_bnode_split(fd);
+			if (IS_ERR(new_node))
+				return PTR_ERR(new_node);
+			parent = fd->bnode;
+			rec = fd->record;
+			rec_off = tree->node_size - (rec + 2) * 2;
+			end_rec_off = tree->node_size - (parent->num_recs + 1) * 2;
+		}
+	}
+
+	end_off = start_off = hfsplus_bnode_read_u16(parent, rec_off);
+	hfsplus_bnode_write_u16(parent, rec_off, start_off + diff);
+	start_off -= 4;	/* move previous cnid too */
+
+	while (rec_off > end_rec_off) {
+		rec_off -= 2;
+		end_off = hfsplus_bnode_read_u16(parent, rec_off);
+		hfsplus_bnode_write_u16(parent, rec_off, end_off + diff);
+	}
+	hfsplus_bnode_movebytes(parent, start_off + diff, start_off,
+				end_off - start_off);
+skip:
+	hfsplus_bnode_copybytes(parent, fd->keyoffset, node, 14, newkeylen);
+	hfsplus_bnode_dump(parent);
+
+	hfsplus_put_bnode(node);
+	node = parent;
+
+	if (new_node) {
+		u32 cnid;
+
+		fd->bnode = hfsplus_find_bnode(tree, new_node->parent);
+		/* create index key and entry */
+		hfsplus_bnode_read_key(new_node, fd->search_key, 14);
+		cnid = cpu_to_be32(new_node->this);
+
+		hfsplus_find_rec(fd->bnode, fd);
+		hfsplus_bnode_insert_rec(fd, &cnid, sizeof(cnid));
+		hfsplus_put_bnode(fd->bnode);
+		hfsplus_put_bnode(new_node);
+
+		if (!rec) {
+			if (new_node == node)
+				goto out;
+			/* restore search_key */
+			hfsplus_bnode_read_key(node, fd->search_key, 14);
+		}
+	}
+
+	if (!rec && node->parent)
+		goto again;
+out:
+	fd->bnode = node;
+	return 0;
+}
+
+int hfsplus_bnode_remove_rec(struct hfsplus_find_data *fd)
+{
+	hfsplus_btree *tree;
+	hfsplus_bnode *node, *parent;
+	int end_off, rec_off, data_off, size;
+
+	tree = fd->tree;
+	node = fd->bnode;
+again:
+	rec_off = tree->node_size - (fd->record + 2) * 2;
+	end_off = tree->node_size - (node->num_recs + 1) * 2;
+
+	if (node->kind == HFSPLUS_NODE_LEAF) {
+		tree->leaf_count--;
+		mark_inode_dirty(tree->inode);
+	}
+	hfsplus_bnode_dump(node);
+	dprint(DBG_BNODE_MOD, "remove_rec: %d, %d\n", fd->record, fd->keylength + fd->entrylength);
+	if (!--node->num_recs) {
+		hfsplus_btree_remove_node(node);
+		if (!node->parent)
+			return 0;
+		parent = hfsplus_find_bnode(tree, node->parent);
+		if (!parent)
+			return -EIO;
+		hfsplus_put_bnode(node);
+		node = fd->bnode = parent;
+
+		hfsplus_find_rec(node, fd);
+		goto again;
+	}
+	hfsplus_bnode_write_u16(node, offsetof(hfsplus_btree_node_desc, num_rec), node->num_recs);
+
+	if (rec_off == end_off)
+		goto skip;
+	size = fd->keylength + fd->entrylength;
+
+	do {
+		data_off = hfsplus_bnode_read_u16(node, rec_off);
+		hfsplus_bnode_write_u16(node, rec_off + 2, data_off - size);
+		rec_off -= 2;
+	} while (rec_off >= end_off);
+
+	/* fill hole */
+	hfsplus_bnode_movebytes(node, fd->keyoffset, fd->keyoffset + size,
+				data_off - fd->keyoffset - size);
+skip:
+	hfsplus_bnode_dump(node);
+	if (!fd->record)
+		hfsplus_update_idx_rec(fd);
+	return 0;
+}
+
+/* Check for valid kind/height pairs , return 0 for bad pairings */
+static int hfsplus_check_kh(hfsplus_btree *tree, u8 kind, u8 height)
+{
+	if ((kind == HFSPLUS_NODE_HEAD) || (kind == HFSPLUS_NODE_MAP)) {
+		if (height != 0)
+			goto hk_error;
+	} else if (kind == HFSPLUS_NODE_LEAF) {
+		if (height != 1)
+			goto hk_error;
+	} else if (kind == HFSPLUS_NODE_NDX) {
+		if ((height <= 1) || (height > tree->depth))
+			goto hk_error;
+	} else {
+		printk("HFS+-fs: unknown node type in B*Tree\n");
+		return 0;
+	}
+	return 1;
+ hk_error:
+	printk("HFS+-fs: corrupt node height in B*Tree\n");
+	return 0;
+}
+
+static inline int hfsplus_bnode_hash(u32 num)
+{
+	num = (num >> 16) + num;
+	num += num >> 8;
+	return num & (NODE_HASH_SIZE - 1);
+}
+
+hfsplus_bnode *__hfsplus_find_bnode(hfsplus_btree *tree, u32 cnid)
+{
+	hfsplus_bnode *node;
+
+	if (cnid >= tree->node_count) {
+		printk("HFS+-fs: request for non-existent node %d in B*Tree\n", cnid);
+		return NULL;
+	}
+
+	for (node = tree->node_hash[hfsplus_bnode_hash(cnid)];
+	     node; node = node->next_hash) {
+		if (node->this == cnid) {
+			return node;
+		}
+	}
+	return NULL;
+}
+
+hfsplus_bnode *__hfsplus_create_bnode(hfsplus_btree *tree, u32 cnid)
+{
+	struct super_block *sb;
+	hfsplus_bnode *node, *node2;
+	struct address_space *mapping;
+	struct page *page;
+	int size, block, i, hash;
+	loff_t off;
+
+	if (cnid >= tree->node_count) {
+		printk("HFS+-fs: request for non-existent node %d in B*Tree\n", cnid);
+		return NULL;
+	}
+
+	sb = tree->inode->i_sb;
+	size = sizeof(hfsplus_bnode) + tree->pages_per_bnode *
+		sizeof(struct page *);
+	node = kmalloc(size, GFP_KERNEL);
+	if (!node)
+		return NULL;
+	memset(node, 0, size);
+	node->tree = tree;
+	node->this = cnid;
+	set_bit(HFSPLUS_BNODE_NEW, &node->flags);
+	atomic_set(&node->refcnt, 1);
+	dprint(DBG_BNODE_REFS, "new_node(%d:%d): 1\n",
+	       node->tree->cnid, node->this);
+	init_waitqueue_head(&node->lock_wq);
+	spin_lock(&tree->hash_lock);
+	node2 = __hfsplus_find_bnode(tree, cnid);
+	if (!node2) {
+		hash = hfsplus_bnode_hash(cnid);
+		node->next_hash = tree->node_hash[hash];
+		tree->node_hash[hash] = node;
+		tree->node_hash_cnt++;
+	} else {
+		spin_unlock(&tree->hash_lock);
+		kfree(node);
+		wait_event(node2->lock_wq, !test_bit(HFSPLUS_BNODE_NEW, &node2->flags));
+		return node2;
+	}
+	spin_unlock(&tree->hash_lock);
+
+	mapping = tree->inode->i_mapping;
+	off = (loff_t)cnid * tree->node_size;
+	block = off >> PAGE_CACHE_SHIFT;
+	node->page_offset = off & ~PAGE_CACHE_MASK;
+	for (i = 0; i < tree->pages_per_bnode; i++) {
+		page = grab_cache_page(mapping, block++);
+		if (!page)
+			goto fail;
+		if (!PageUptodate(page)) {
+			if (mapping->a_ops->readpage(NULL, page))
+				goto fail;
+			wait_on_page_locked(page);
+			if (!PageUptodate(page))
+				goto fail;
+		} else
+			unlock_page(page);
+#if !REF_PAGES
+		page_cache_release(page);
+#endif
+		node->page[i] = page;
+	}
+
+	return node;
+fail:
+	if (page)
+		page_cache_release(page);
+	set_bit(HFSPLUS_BNODE_ERROR, &node->flags);
+	return node;
+}
+
+void __hfsplus_bnode_remove(hfsplus_bnode *node)
+{
+	hfsplus_bnode **p;
+
+	dprint(DBG_BNODE_REFS, "remove_node(%d:%d): %d\n",
+		node->tree->cnid, node->this, atomic_read(&node->refcnt));
+	for (p = &node->tree->node_hash[hfsplus_bnode_hash(node->this)];
+	     *p && *p != node; p = &(*p)->next_hash)
+		;
+	if (!*p)
+		BUG();
+	*p = node->next_hash;
+	node->tree->node_hash_cnt--;
+}
+
+/* Load a particular node out of a tree */
+hfsplus_bnode *hfsplus_find_bnode(hfsplus_btree *tree, u32 num)
+{
+	hfsplus_bnode *node;
+	hfsplus_btree_node_desc *desc;
+	int i, rec_off, off, next_off;
+	int entry_size, key_size;
+
+	spin_lock(&tree->hash_lock);
+	node = __hfsplus_find_bnode(tree, num);
+	if (node) {
+		hfsplus_get_bnode(node);
+		spin_unlock(&tree->hash_lock);
+		wait_event(node->lock_wq, !test_bit(HFSPLUS_BNODE_NEW, &node->flags));
+		return node;
+	}
+	spin_unlock(&tree->hash_lock);
+	node = __hfsplus_create_bnode(tree, num);
+	if (!node)
+		return ERR_PTR(-ENOMEM);
+	if (!test_bit(HFSPLUS_BNODE_NEW, &node->flags))
+		return node;
+
+	desc = (hfsplus_btree_node_desc *)(hfsplus_kmap(node->page[0]) + node->page_offset);
+	node->prev = be32_to_cpu(desc->prev);
+	node->next = be32_to_cpu(desc->next);
+	node->num_recs = be16_to_cpu(desc->num_rec);
+	node->kind = desc->kind;
+	node->height = desc->height;
+
+	if (!hfsplus_check_kh(tree, desc->kind, desc->height)) {
+		hfsplus_kunmap(node->page[0]);
+		goto node_error;
+	}
+	hfsplus_kunmap(node->page[0]);
+
+	rec_off = tree->node_size - 2;
+	off = hfsplus_bnode_read_u16(node, rec_off);
+	if (off != sizeof(hfsplus_btree_node_desc))
+		goto node_error;
+	for (i = 1; i <= node->num_recs; off = next_off, i++) {
+		rec_off -= 2;
+		next_off = hfsplus_bnode_read_u16(node, rec_off);
+		if (next_off <= off ||
+		    next_off > tree->node_size ||
+		    next_off & 1)
+			goto node_error;
+		entry_size = next_off - off;
+		if (node->kind != HFSPLUS_NODE_NDX &&
+		    node->kind != HFSPLUS_NODE_LEAF)
+			continue;
+		key_size = hfsplus_bnode_read_u16(node, off) + 2;
+		if (key_size >= entry_size || key_size & 1)
+			goto node_error;
+	}
+	clear_bit(HFSPLUS_BNODE_NEW, &node->flags);
+	wake_up(&node->lock_wq);
+	return node;
+
+node_error:
+	set_bit(HFSPLUS_BNODE_ERROR, &node->flags);
+	clear_bit(HFSPLUS_BNODE_NEW, &node->flags);
+	wake_up(&node->lock_wq);
+	hfsplus_put_bnode(node);
+	return ERR_PTR(-EIO);
+}
+
+void hfsplus_bnode_free(hfsplus_bnode *node)
+{
+	//int i;
+
+	//for (i = 0; i < node->tree->pages_per_bnode; i++)
+	//	if (node->page[i])
+	//		page_cache_release(node->page[i]);
+	kfree(node);
+}
+
+hfsplus_bnode *hfsplus_create_bnode(hfsplus_btree *tree, u32 num)
+{
+	hfsplus_bnode *node;
+	struct page **pagep;
+	int i;
+
+	spin_lock(&tree->hash_lock);
+	node = __hfsplus_find_bnode(tree, num);
+	spin_unlock(&tree->hash_lock);
+	if (node)
+		BUG();
+	node = __hfsplus_create_bnode(tree, num);
+	if (!node)
+		return ERR_PTR(-ENOMEM);
+
+	pagep = node->page;
+	memset(hfsplus_kmap(*pagep) + node->page_offset, 0,
+	       min((int)PAGE_CACHE_SIZE, (int)tree->node_size));
+	set_page_dirty(*pagep);
+	hfsplus_kunmap(*pagep++);
+	for (i = 1; i < tree->pages_per_bnode; i++) {
+		memset(hfsplus_kmap(*pagep), 0, PAGE_CACHE_SIZE);
+		set_page_dirty(*pagep);
+		hfsplus_kunmap(*pagep++);
+	}
+	clear_bit(HFSPLUS_BNODE_NEW, &node->flags);
+	wake_up(&node->lock_wq);
+
+	return node;
+}
+
+void hfsplus_get_bnode(hfsplus_bnode *node)
+{
+	if (node) {
+		atomic_inc(&node->refcnt);
+#if REF_PAGES
+		{
+		int i;
+		for (i = 0; i < node->tree->pages_per_bnode; i++)
+			get_page(node->page[i]);
+		}
+#endif
+		dprint(DBG_BNODE_REFS, "get_node(%d:%d): %d\n",
+		       node->tree->cnid, node->this, atomic_read(&node->refcnt));
+	}
+}
+
+/* Dispose of resources used by a node */
+void hfsplus_put_bnode(hfsplus_bnode *node)
+{
+	if (node) {
+		struct hfsplus_btree *tree = node->tree;
+		int i;
+
+		dprint(DBG_BNODE_REFS, "put_node(%d:%d): %d\n",
+		       node->tree->cnid, node->this, atomic_read(&node->refcnt));
+		if (!atomic_read(&node->refcnt))
+			BUG();
+		if (!atomic_dec_and_lock(&node->refcnt, &tree->hash_lock)) {
+#if REF_PAGES
+			for (i = 0; i < tree->pages_per_bnode; i++)
+				put_page(node->page[i]);
+#endif
+			return;
+		}
+		for (i = 0; i < tree->pages_per_bnode; i++) {
+			mark_page_accessed(node->page[i]);
+#if REF_PAGES
+			put_page(node->page[i]);
+#endif
+		}
+
+		if (test_bit(HFSPLUS_BNODE_DELETED, &node->flags)) {
+			__hfsplus_bnode_remove(node);
+			spin_unlock(&tree->hash_lock);
+			hfsplus_btree_free_node(node);
+			hfsplus_bnode_free(node);
+			return;
+		}
+		spin_unlock(&tree->hash_lock);
+	}
+}
+
+void hfsplus_lock_bnode(hfsplus_bnode *node)
+{
+	wait_event(node->lock_wq, !test_and_set_bit(HFSPLUS_BNODE_LOCK, &node->flags));
+}
+
+void hfsplus_unlock_bnode(hfsplus_bnode *node)
+{
+	clear_bit(HFSPLUS_BNODE_LOCK, &node->flags);
+	if (waitqueue_active(&node->lock_wq))
+		wake_up(&node->lock_wq);
+}
diff -urN linux-2.4.22-pre2/fs/hfsplus/brec.c linux-2.4.22-pre3/fs/hfsplus/brec.c
--- linux-2.4.22-pre2/fs/hfsplus/brec.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/brec.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,102 @@
+/*
+ *  linux/fs/hfsplus/brec.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Handle individual btree records
+ */
+
+#include "hfsplus_fs.h"
+#include "hfsplus_raw.h"
+
+/* Get the offset of the given record in the given node */
+u16 hfsplus_brec_off(hfsplus_bnode *node, u16 rec)
+{
+	u16 dataoff;
+
+	dataoff = node->tree->node_size - (rec + 1) * 2;
+	return hfsplus_bnode_read_u16(node, dataoff);
+}
+
+/* Get the length of the given record in the given node */
+u16 hfsplus_brec_len(hfsplus_bnode *node, u16 rec)
+{
+	u16 retval[2];
+	u16 dataoff;
+
+	dataoff = node->tree->node_size - (rec + 2) * 2;
+	hfsplus_bnode_readbytes(node, retval, dataoff, 4);
+	return be16_to_cpu(retval[0]) - be16_to_cpu(retval[1]);
+}
+
+/* Get the length and offset of the given record in the given node */
+u16 hfsplus_brec_lenoff(hfsplus_bnode *node, u16 rec, u16 *off)
+{
+	u16 retval[2];
+	u16 dataoff;
+
+	dataoff = node->tree->node_size - (rec + 2) * 2;
+	hfsplus_bnode_readbytes(node, retval, dataoff, 4);
+	*off = be16_to_cpu(retval[1]);
+	return be16_to_cpu(retval[0]) - *off;
+}
+
+/* Copy a record from a node into a buffer, return the actual length */
+u16 hfsplus_brec_data(hfsplus_bnode *node, u16 rec, char *buf,
+			   u16 len)
+{
+	u16 recoff, reclen, cplen;
+
+	reclen = hfsplus_brec_lenoff(node, rec, &recoff);
+	if (!reclen)
+		return 0;
+	cplen = (reclen>len) ? len : reclen;
+	hfsplus_bnode_readbytes(node, buf, recoff, cplen);
+	return reclen;
+}
+
+/* Get the length of the key from a keyed record */
+u16 hfsplus_brec_keylen(hfsplus_bnode *node, u16 rec)
+{
+	u16 klsz, retval, recoff;
+	unsigned char buf[2];
+
+	if ((node->kind != HFSPLUS_NODE_NDX)&&(node->kind != HFSPLUS_NODE_LEAF))
+		return 0;
+
+	klsz = (node->tree->attributes & HFSPLUS_TREE_BIGKEYS) ? 2 : 1;
+	if ((node->kind == HFSPLUS_NODE_NDX) &&
+	   !(node->tree->attributes & HFSPLUS_TREE_VAR_NDXKEY_SIZE)) {
+		retval = node->tree->max_key_len;
+	} else {
+		recoff = hfsplus_brec_off(node, rec);
+		if (!recoff)
+			return 0;
+		hfsplus_bnode_readbytes(node, buf, recoff, klsz);
+		if (klsz == 1)
+			retval = buf[0];
+		else
+			retval = be16_to_cpu(*(u16 *)buf);
+	}
+	return (retval + klsz + 1) & 0xFFFE;
+}
+
+/* Get a copy of the key of the given record, returns real key length */
+u16 hfsplus_brec_key(hfsplus_bnode *node, u16 rec, void *buf,
+			  u16 len)
+{
+	u16 recoff, reclen, keylen, tocopy;
+
+	reclen = hfsplus_brec_lenoff(node, rec, &recoff);
+	keylen = hfsplus_brec_keylen(node, rec);
+	if (!reclen || !keylen)
+		return 0;
+	if (keylen > reclen) {
+		printk("HFS+-fs: corrupt key length in B*Tree (%d,%d,%d,%d,%d)\n", node->this, rec, reclen, keylen, recoff);
+		return 0;
+	}
+	tocopy = (len > keylen) ? keylen : len;
+	hfsplus_bnode_readbytes(node, buf, recoff, tocopy);
+	return keylen;
+}
diff -urN linux-2.4.22-pre2/fs/hfsplus/btiter.c linux-2.4.22-pre3/fs/hfsplus/btiter.c
--- linux-2.4.22-pre2/fs/hfsplus/btiter.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/btiter.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,72 @@
+/*
+ *  linux/fs/hfsplus/btiter.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Iterators for btrees
+ */
+
+#include "hfsplus_fs.h"
+
+int hfsplus_btiter_move(struct hfsplus_find_data *fd, int cnt)
+{
+	struct hfsplus_btree *tree;
+	hfsplus_bnode *bnode;
+	int idx, res = 0;
+	u16 off, len, keylen;
+
+	bnode = fd->bnode;
+	tree = bnode->tree;
+
+	if (cnt < -0xFFFF || cnt > 0xFFFF)
+		return -EINVAL;
+
+	if (cnt < 0) {
+		cnt = -cnt;
+		while (cnt > fd->record) {
+			cnt -= fd->record + 1;
+			fd->record = bnode->num_recs - 1;
+			idx = bnode->prev;
+			if (!idx) {
+				res = -ENOENT;
+				goto out;
+			}
+			hfsplus_put_bnode(bnode);
+			bnode = hfsplus_find_bnode(tree, idx);
+			if (!bnode) {
+				res = -EIO;
+				goto out;
+			}
+		}
+		fd->record -= cnt;
+	} else {
+		while (cnt >= bnode->num_recs - fd->record) {
+			cnt -= bnode->num_recs - fd->record;
+			fd->record = 0;
+			idx = bnode->next;
+			if (!idx) {
+				res = -ENOENT;
+				goto out;
+			}
+			hfsplus_put_bnode(bnode);
+			bnode = hfsplus_find_bnode(tree, idx);
+			if (!bnode) {
+				res = -EIO;
+				goto out;
+			}
+		}
+		fd->record += cnt;
+	}
+
+	len = hfsplus_brec_lenoff(bnode, fd->record, &off);
+	keylen = hfsplus_brec_keylen(bnode, fd->record);
+	fd->keyoffset = off;
+	fd->keylength = keylen;
+	fd->entryoffset = off + keylen;
+	fd->entrylength = len - keylen;
+	hfsplus_bnode_readbytes(bnode, fd->key, off, keylen);
+out:
+	fd->bnode = bnode;
+	return res;
+}
diff -urN linux-2.4.22-pre2/fs/hfsplus/btree.c linux-2.4.22-pre3/fs/hfsplus/btree.c
--- linux-2.4.22-pre2/fs/hfsplus/btree.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/btree.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,316 @@
+/*
+ *  linux/fs/hfsplus/btree.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Handle opening/closing btree
+ */
+
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <asm/div64.h>
+
+#include "hfsplus_fs.h"
+#include "hfsplus_raw.h"
+
+/* Release resources used by a btree */
+void hfsplus_close_btree(struct hfsplus_btree *tree)
+{
+	hfsplus_bnode *node;
+	int i;
+
+	if (!tree)
+		return;
+
+	for (i = 0; i < NODE_HASH_SIZE; i++) {
+		while ((node = tree->node_hash[i])) {
+			tree->node_hash[i] = node->next_hash;
+			if (atomic_read(&node->refcnt))
+				printk("HFS+: node %d:%d still has %d user(s)!\n",
+					node->tree->cnid, node->this, atomic_read(&node->refcnt));
+			hfsplus_bnode_free(node);
+			tree->node_hash_cnt--;
+		}
+	}
+	iput(tree->inode);
+	kfree(tree);
+}
+
+/* Fill in extra data in tree structure from header node */
+static void hfsplus_read_treeinfo(hfsplus_btree *tree, hfsplus_btree_head *hdr)
+{
+	unsigned int shift, size;
+
+	if (!tree || !hdr)
+		return;
+
+	tree->root = be32_to_cpu(hdr->root);
+	tree->leaf_count = be32_to_cpu(hdr->leaf_count);
+	tree->leaf_head = be32_to_cpu(hdr->leaf_head);
+	tree->leaf_tail = be32_to_cpu(hdr->leaf_tail);
+	tree->node_count = be32_to_cpu(hdr->node_count);
+	tree->free_nodes = be32_to_cpu(hdr->free_nodes);
+	tree->attributes = be32_to_cpu(hdr->attributes);
+	tree->node_size = be16_to_cpu(hdr->node_size);
+	tree->max_key_len = be16_to_cpu(hdr->max_key_len);
+	tree->depth = be16_to_cpu(hdr->depth);
+
+	size = tree->node_size;
+	if (size & (size - 1))
+		/* panic */;
+	for (shift = 0; size >>= 1; shift += 1)
+		;
+	tree->node_size_shift = shift;
+
+	tree->pages_per_bnode = (tree->node_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+}
+
+static void hfsplus_write_treeinfo(hfsplus_btree *tree, hfsplus_btree_head *hdr)
+{
+	hdr->root = cpu_to_be32(tree->root);
+	hdr->leaf_count = cpu_to_be32(tree->leaf_count);
+	hdr->leaf_head = cpu_to_be32(tree->leaf_head);
+	hdr->leaf_tail = cpu_to_be32(tree->leaf_tail);
+	hdr->node_count = cpu_to_be32(tree->node_count);
+	hdr->free_nodes = cpu_to_be32(tree->free_nodes);
+	hdr->attributes = cpu_to_be32(tree->attributes);
+	hdr->depth = cpu_to_be16(tree->depth);
+}
+
+/* Get a reference to a B*Tree and do some initial checks */
+hfsplus_btree *hfsplus_open_btree(struct super_block *sb, u32 id)
+{
+	hfsplus_btree *tree;
+	hfsplus_btree_head *head;
+	struct address_space *mapping;
+	struct page *page;
+
+	tree = kmalloc(sizeof(struct hfsplus_btree), GFP_KERNEL);
+	if (!tree)
+		return NULL;
+	memset(tree, 0, sizeof(struct hfsplus_btree));
+
+	init_MUTEX(&tree->tree_lock);
+	spin_lock_init(&tree->hash_lock);
+	/* Set the correct compare function */
+	tree->sb = sb;
+	tree->cnid = id;
+	if (id == HFSPLUS_EXT_CNID) {
+		tree->keycmp = hfsplus_cmp_ext_key;
+	} else if (id == HFSPLUS_CAT_CNID) {
+		tree->keycmp = hfsplus_cmp_cat_key;
+	} else {
+		printk("HFS+-fs: unknown B*Tree requested\n");
+		goto free_tree;
+	}
+	tree->inode = iget(sb, id);
+	if (!tree->inode)
+		goto free_tree;
+
+	mapping = tree->inode->i_mapping;
+	page = grab_cache_page(mapping, 0);
+	if (!page)
+		goto free_tree;
+	if (!PageUptodate(page)) {
+		if (mapping->a_ops->readpage(NULL, page))
+			goto fail_page;
+		wait_on_page_locked(page);
+		if (!PageUptodate(page))
+			goto fail_page;
+	} else
+		unlock_page(page);
+
+	/* Load the header */
+	head = (hfsplus_btree_head *)(kmap(page) + sizeof(hfsplus_btree_node_desc));
+	hfsplus_read_treeinfo(tree, head);
+	kunmap(page);
+	page_cache_release(page);
+	return tree;
+
+ fail_page:
+	page_cache_release(page);
+ free_tree:
+	iput(tree->inode);
+	kfree(tree);
+	return NULL;
+}
+
+void hfsplus_write_btree(struct hfsplus_btree *tree)
+{
+	hfsplus_btree_head *head;
+	hfsplus_bnode *node;
+	struct page *page;
+
+	node = hfsplus_find_bnode(tree, 0);
+	if (!node)
+		/* panic? */
+		return;
+	/* Load the header */
+	page = node->page[0];
+	head = (hfsplus_btree_head *)(kmap(page) + sizeof(hfsplus_btree_node_desc));
+	hfsplus_write_treeinfo(tree, head);
+	kunmap(page);
+	set_page_dirty(page);
+	hfsplus_put_bnode(node);
+}
+
+hfsplus_bnode *hfsplus_btree_alloc_node(hfsplus_btree *tree)
+{
+	hfsplus_bnode *node;
+	struct page **pagep;
+	u32 nidx;
+	u16 idx, off, len;
+	u8 *data, byte, m;
+	int i;
+
+	while (!tree->free_nodes) {
+		loff_t size;
+		int res;
+
+		res = hfsplus_extend_file(tree->inode);
+		if (res)
+			return ERR_PTR(res);
+		HFSPLUS_I(tree->inode).total_blocks = HFSPLUS_I(tree->inode).alloc_blocks;
+		size = HFSPLUS_I(tree->inode).total_blocks;
+		size <<= tree->sb->s_blocksize_bits;
+		tree->inode->i_size = size;
+		do_div(size, (u32)tree->node_size);
+		tree->free_nodes = (u32)size - tree->node_count;
+		tree->node_count = size;
+	}
+
+	nidx = 0;
+	node = hfsplus_find_bnode(tree, nidx);
+	len = hfsplus_brec_lenoff(node, 2, &off);
+
+	off += node->page_offset;
+	pagep = node->page + (off >> PAGE_CACHE_SHIFT);
+	data = hfsplus_kmap(*pagep);
+	off &= ~PAGE_CACHE_MASK;
+	idx = 0;
+
+	for (;;) {
+		while (len) {
+			byte = data[off];
+			if (byte != 0xff) {
+				for (m = 0x80, i = 0; i < 8; m >>= 1, i++) {
+					if (!(byte & m)) {
+						idx += i;
+						data[off] |= m;
+						set_page_dirty(*pagep);
+						hfsplus_kunmap(*pagep);
+						tree->free_nodes--;
+						mark_inode_dirty(tree->inode);
+						hfsplus_put_bnode(node);
+						return hfsplus_create_bnode(tree, idx);
+					}
+				}
+			}
+			if (++off >= PAGE_CACHE_SIZE) {
+				hfsplus_kunmap(*pagep++);
+				data = hfsplus_kmap(*pagep);
+				off = 0;
+			}
+			idx += 8;
+			len--;
+		}
+		nidx = node->next;
+		hfsplus_put_bnode(node);
+		if (!nidx) {
+			printk("need new bmap node...\n");
+			hfsplus_kunmap(*pagep);
+			return ERR_PTR(-ENOSPC);
+		}
+		node = hfsplus_find_bnode(tree, nidx);
+		len = hfsplus_brec_lenoff(node, 0, &off);
+
+		off += node->page_offset;
+		pagep = node->page + (off >> PAGE_CACHE_SHIFT);
+		data = hfsplus_kmap(*pagep);
+		off &= ~PAGE_CACHE_MASK;
+	}
+}
+
+void hfsplus_btree_remove_node(hfsplus_bnode *node)
+{
+	hfsplus_btree *tree;
+	hfsplus_bnode *tmp;
+	u32 cnid;
+
+	tree = node->tree;
+	if (node->prev) {
+		tmp = hfsplus_find_bnode(tree, node->prev);
+		tmp->next = node->next;
+		cnid = cpu_to_be32(tmp->next);
+		hfsplus_bnode_writebytes(tmp, &cnid, offsetof(hfsplus_btree_node_desc, next), 4);
+		hfsplus_put_bnode(tmp);
+	} else if (node->kind == HFSPLUS_NODE_LEAF)
+		tree->leaf_head = node->next;
+
+	if (node->next) {
+		tmp = hfsplus_find_bnode(tree, node->next);
+		tmp->prev = node->prev;
+		cnid = cpu_to_be32(tmp->prev);
+		hfsplus_bnode_writebytes(tmp, &cnid, offsetof(hfsplus_btree_node_desc, prev), 4);
+		hfsplus_put_bnode(tmp);
+	} else if (node->kind == HFSPLUS_NODE_LEAF)
+		tree->leaf_tail = node->prev;
+
+	// move down?
+	if (!node->prev && !node->next) {
+		printk("hfsplus_btree_del_level\n");
+	}
+	if (!node->parent) {
+		tree->root = 0;
+		tree->depth = 0;
+	}
+	set_bit(HFSPLUS_BNODE_DELETED, &node->flags);
+}
+
+void hfsplus_btree_free_node(hfsplus_bnode *node)
+{
+	hfsplus_btree *tree;
+	struct page *page;
+	u16 off, len;
+	u32 nidx;
+	u8 *data, byte, m;
+
+	dprint(DBG_BNODE_MOD, "btree_free_node: %u\n", node->this);
+	tree = node->tree;
+	nidx = node->this;
+	node = hfsplus_find_bnode(tree, 0);
+	len = hfsplus_brec_lenoff(node, 2, &off);
+	while (nidx >= len * 8) {
+		u32 i;
+
+		nidx -= len * 8;
+		i = node->next;
+		hfsplus_put_bnode(node);
+		if (!nidx)
+			/* panic */;
+		node = hfsplus_find_bnode(tree, nidx);
+		if (node->kind != HFSPLUS_NODE_MAP)
+			/* panic */;
+		len = hfsplus_brec_lenoff(node, 0, &off);
+	}
+	off += node->page_offset + nidx / 8;
+	page = node->page[off >> PAGE_CACHE_SHIFT];
+	data = hfsplus_kmap(page);
+	off &= ~PAGE_CACHE_MASK;
+	m = 1 << (~nidx & 7);
+	byte = data[off];
+	if (!(byte & m)) {
+		BUG();
+		/* panic */
+		hfsplus_kunmap(page);
+		hfsplus_put_bnode(node);
+		return;
+	}
+	data[off] = byte & ~m;
+	set_page_dirty(page);
+	hfsplus_kunmap(page);
+	hfsplus_put_bnode(node);
+	tree->free_nodes++;
+	mark_inode_dirty(tree->inode);
+}
diff -urN linux-2.4.22-pre2/fs/hfsplus/catalog.c linux-2.4.22-pre3/fs/hfsplus/catalog.c
--- linux-2.4.22-pre2/fs/hfsplus/catalog.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/catalog.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,327 @@
+/*
+ *  linux/fs/hfsplus/catalog.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Handling of catalog records
+ */
+
+#include <linux/sched.h>
+
+#include "hfsplus_fs.h"
+#include "hfsplus_raw.h"
+
+int hfsplus_cmp_cat_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2)
+{
+	u32 k1p, k2p;
+
+	k1p = k1->cat.parent;
+	k2p = k2->cat.parent;
+	if (k1p != k2p)
+		return be32_to_cpu(k1p) < be32_to_cpu(k2p) ? -1 : 1;
+
+	return hfsplus_unistrcmp(&k1->cat.name, &k2->cat.name);
+}
+
+void hfsplus_fill_cat_key(hfsplus_btree_key *key, u32 parent,
+			  struct qstr *str)
+{
+	int len;
+
+	key->cat.parent = cpu_to_be32(parent);
+	if (str) {
+		hfsplus_asc2uni(&key->cat.name, str->name, str->len);
+		len = be16_to_cpu(key->cat.name.length);
+	} else
+		len = key->cat.name.length = 0;
+	key->key_len = cpu_to_be16(6 + 2 * len);
+}
+
+static void hfsplus_fill_cat_key_uni(hfsplus_btree_key *key, u32 parent,
+				     hfsplus_unistr *name)
+{
+	int ustrlen;
+
+	ustrlen = be16_to_cpu(name->length);
+	key->cat.parent = cpu_to_be32(parent);
+	key->cat.name.length = cpu_to_be16(ustrlen);
+	ustrlen *= 2;
+	memcpy(key->cat.name.unicode, name->unicode, ustrlen);
+	key->key_len = cpu_to_be16(6 + ustrlen);
+}
+
+static void hfsplus_set_perms(struct inode *inode, hfsplus_perm *perms)
+{
+	perms->mode = cpu_to_be32(inode->i_mode);
+	perms->owner = cpu_to_be32(inode->i_uid);
+	perms->group = cpu_to_be32(inode->i_gid);
+}
+
+static int hfsplus_fill_cat_entry(hfsplus_cat_entry *entry, u32 cnid, struct inode *inode)
+{
+	if (S_ISDIR(inode->i_mode)) {
+		hfsplus_cat_folder *folder;
+
+		folder = &entry->folder;
+		memset(folder, 0, sizeof(*folder));
+		folder->type = cpu_to_be16(HFSPLUS_FOLDER);
+		folder->id = cpu_to_be32(inode->i_ino);
+		folder->create_date = folder->content_mod_date = 
+			folder->attribute_mod_date = folder->access_date = 
+			hfsp_now2mt();
+		hfsplus_set_perms(inode, &folder->permissions);
+		return sizeof(*folder);
+	} else {
+		hfsplus_cat_file *file;
+
+		file = &entry->file;
+		memset(file, 0, sizeof(*file));
+		file->type = cpu_to_be16(HFSPLUS_FILE);
+		file->id = cpu_to_be32(cnid);
+		file->create_date = file->content_mod_date =
+			file->attribute_mod_date = file->access_date =
+			hfsp_now2mt();
+		if (cnid == inode->i_ino)
+			hfsplus_set_perms(inode, &file->permissions);
+		else {
+			file->user_info.fdType = cpu_to_be32(HFSP_HARDLINK_TYPE);
+			file->user_info.fdCreator = cpu_to_be32(HFSP_HFSPLUS_CREATOR);
+			file->user_info.fdFlags = cpu_to_be16(0x100);
+			file->permissions.dev = cpu_to_be32(HFSPLUS_I(inode).dev);
+		}
+		return sizeof(*file);
+	}
+}
+
+static int hfsplus_fill_cat_thread(hfsplus_cat_entry *entry, int type,
+				   u32 parentid, struct qstr *str)
+{
+	entry->type = cpu_to_be16(type);
+	entry->thread.reserved = 0;
+	entry->thread.parentID = cpu_to_be32(parentid);
+	hfsplus_asc2uni(&entry->thread.nodeName, str->name, str->len);
+	return 10 + be16_to_cpu(entry->thread.nodeName.length) * 2;
+}
+
+/* Try to get a catalog entry for given catalog id */
+int hfsplus_find_cat(struct super_block *sb, unsigned long cnid,
+		     struct hfsplus_find_data *fd)
+{
+	hfsplus_cat_entry tmp;
+	int err;
+	u16 type;
+
+	hfsplus_fill_cat_key(fd->search_key, cnid, NULL);
+	err = hfsplus_btree_find_entry(fd, &tmp, sizeof(hfsplus_cat_entry));
+	if (err)
+		return err;
+
+	type = be16_to_cpu(tmp.type);
+	if (type != HFSPLUS_FOLDER_THREAD && type != HFSPLUS_FILE_THREAD) {
+		printk("HFS+-fs: Found bad thread record in catalog\n");
+		return -EIO;
+	}
+
+	hfsplus_fill_cat_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID),
+				 &tmp.thread.nodeName);
+	return hfsplus_btree_find(fd);
+}
+
+int hfsplus_create_cat(u32 cnid, struct inode *dir, struct qstr *str, struct inode *inode)
+{
+	struct hfsplus_find_data fd;
+	struct super_block *sb;
+	hfsplus_cat_entry entry;
+	int entry_size;
+	int err;
+
+	dprint(DBG_CAT_MOD, "create_cat: %s,%u(%d)\n", str->name, cnid, inode->i_nlink);
+	sb = dir->i_sb;
+	hfsplus_find_init(HFSPLUS_SB(sb).cat_tree, &fd);
+
+	hfsplus_fill_cat_key(fd.search_key, cnid, NULL);
+	entry_size = hfsplus_fill_cat_thread(&entry, S_ISDIR(inode->i_mode) ?
+			HFSPLUS_FOLDER_THREAD : HFSPLUS_FILE_THREAD,
+			dir->i_ino, str);
+	err = hfsplus_btree_find(&fd);
+	if (err != -ENOENT) {
+		if (!err)
+			err = -EEXIST;
+		goto out;
+	}
+	err = hfsplus_bnode_insert_rec(&fd, &entry, entry_size);
+	if (err)
+		goto out;
+
+	hfsplus_fill_cat_key(fd.search_key, dir->i_ino, str);
+	entry_size = hfsplus_fill_cat_entry(&entry, cnid, inode);
+	err = hfsplus_btree_find(&fd);
+	if (err != -ENOENT) {
+		/* panic? */
+		if (!err)
+			err = -EEXIST;
+		goto out;
+	}
+	err = hfsplus_bnode_insert_rec(&fd, &entry, entry_size);
+	if (!err) {
+		dir->i_size++;
+		mark_inode_dirty(dir);
+	}
+out:
+	hfsplus_find_exit(&fd);
+
+	return err;
+}
+
+int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
+{
+	struct super_block *sb;
+	struct hfsplus_find_data fd;
+	hfsplus_fork_raw fork;
+	struct list_head *pos;
+	int err, off;
+	u16 type;
+
+	dprint(DBG_CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid);
+	sb = dir->i_sb;
+	hfsplus_find_init(HFSPLUS_SB(sb).cat_tree, &fd);
+
+	if (!str) {
+		int len;
+
+		hfsplus_fill_cat_key(fd.search_key, cnid, NULL);
+		err = hfsplus_btree_find(&fd);
+		if (err)
+			goto out;
+
+		off = fd.entryoffset + offsetof(hfsplus_cat_thread, nodeName);
+		fd.search_key->cat.parent = cpu_to_be32(dir->i_ino);
+		hfsplus_bnode_readbytes(fd.bnode, &fd.search_key->cat.name.length, off, 2);
+		len = be16_to_cpu(fd.search_key->cat.name.length) * 2;
+		hfsplus_bnode_readbytes(fd.bnode, &fd.search_key->cat.name.unicode, off + 2, len);
+		fd.search_key->key_len = cpu_to_be16(6 + len);
+	} else
+		hfsplus_fill_cat_key(fd.search_key, dir->i_ino, str);
+
+	err = hfsplus_btree_find(&fd);
+	if (err)
+		goto out;
+
+	type = hfsplus_bnode_read_u16(fd.bnode, fd.entryoffset);
+	if (type == HFSPLUS_FILE) {
+#if 0
+		off = fd.entryoffset + offsetof(hfsplus_cat_file, data_fork);
+		hfsplus_bnode_readbytes(fd.bnode, &fork, off, sizeof(fork));
+		hfsplus_free_fork(sb, cnid, &fork, HFSPLUS_TYPE_DATA);
+#endif
+
+		off = fd.entryoffset + offsetof(hfsplus_cat_file, rsrc_fork);
+		hfsplus_bnode_readbytes(fd.bnode, &fork, off, sizeof(fork));
+		hfsplus_free_fork(sb, cnid, &fork, HFSPLUS_TYPE_RSRC);
+	}
+
+	list_for_each(pos, &HFSPLUS_I(dir).open_dir_list) {
+		struct hfsplus_readdir_data *rd =
+			list_entry(pos, struct hfsplus_readdir_data, list);
+		if (fd.tree->keycmp(fd.search_key, (void *)&rd->key) < 0)
+			rd->file->f_pos--;
+	}
+
+	err = hfsplus_bnode_remove_rec(&fd);
+	if (err)
+		goto out;
+
+	hfsplus_fill_cat_key(fd.search_key, cnid, NULL);
+	err = hfsplus_btree_find(&fd);
+	if (err)
+		goto out;
+
+	err = hfsplus_bnode_remove_rec(&fd);
+	if (err) 
+		goto out;
+
+	dir->i_size--;
+	mark_inode_dirty(dir);
+out:
+	hfsplus_find_exit(&fd);
+
+	return err;
+}
+
+int hfsplus_rename_cat(u32 cnid,
+		       struct inode *src_dir, struct qstr *src_name,
+		       struct inode *dst_dir, struct qstr *dst_name)
+{
+	struct super_block *sb;
+	struct hfsplus_find_data src_fd, dst_fd;
+	hfsplus_cat_entry entry;
+	int entry_size, type;
+	int err = 0;
+
+	dprint(DBG_CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", cnid, src_dir->i_ino, src_name->name,
+		dst_dir->i_ino, dst_name->name);
+	sb = src_dir->i_sb;
+	hfsplus_find_init(HFSPLUS_SB(sb).cat_tree, &src_fd);
+	dst_fd = src_fd;
+
+	/* find the old dir entry and read the data */
+	hfsplus_fill_cat_key(src_fd.search_key, src_dir->i_ino, src_name);
+	err = hfsplus_btree_find(&src_fd);
+	if (err)
+		goto out;
+		
+	hfsplus_bnode_readbytes(src_fd.bnode, &entry, src_fd.entryoffset,
+				src_fd.entrylength);
+
+	/* create new dir entry with the data from the old entry */
+	hfsplus_fill_cat_key(dst_fd.search_key, dst_dir->i_ino, dst_name);
+	err = hfsplus_btree_find(&dst_fd);
+	if (err != -ENOENT) {
+		if (!err)
+			err = -EEXIST;
+		goto out;
+	}
+
+	err = hfsplus_bnode_insert_rec(&dst_fd, &entry, src_fd.entrylength);
+	if (err)
+		goto out;
+	dst_dir->i_size++;
+	mark_inode_dirty(dst_dir);
+
+	/* finally remove the old entry */
+	hfsplus_fill_cat_key(src_fd.search_key, src_dir->i_ino, src_name);
+	err = hfsplus_btree_find(&src_fd);
+	if (err)
+		goto out;
+	err = hfsplus_bnode_remove_rec(&src_fd);
+	if (err)
+		goto out;
+	src_dir->i_size--;
+	mark_inode_dirty(src_dir);
+
+	/* remove old thread entry */
+	hfsplus_fill_cat_key(src_fd.search_key, cnid, NULL);
+	err = hfsplus_btree_find(&src_fd);
+	if (err)
+		goto out;
+	type = hfsplus_bnode_read_u16(src_fd.bnode, src_fd.entryoffset);
+	err = hfsplus_bnode_remove_rec(&src_fd);
+	if (err)
+		goto out;
+
+	/* create new thread entry */
+	hfsplus_fill_cat_key(dst_fd.search_key, cnid, NULL);
+	entry_size = hfsplus_fill_cat_thread(&entry, type, dst_dir->i_ino, dst_name);
+	err = hfsplus_btree_find(&dst_fd);
+	if (err != -ENOENT) {
+		if (!err)
+			err = -EEXIST;
+		goto out;
+	}
+	err = hfsplus_bnode_insert_rec(&dst_fd, &entry, entry_size);
+out:
+	hfsplus_put_bnode(dst_fd.bnode);
+	hfsplus_find_exit(&src_fd);
+	return err;
+}
diff -urN linux-2.4.22-pre2/fs/hfsplus/dir.c linux-2.4.22-pre3/fs/hfsplus/dir.c
--- linux-2.4.22-pre2/fs/hfsplus/dir.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/dir.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,493 @@
+/*
+ *  linux/fs/hfsplus/dir.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Handling of directories
+ */
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <linux/buffer_head.h>
+#endif
+
+#include "hfsplus_fs.h"
+#include "hfsplus_raw.h"
+
+/* Find the entry inside dir named dentry->d_name */
+static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry)
+{
+	struct inode *inode = NULL;
+	struct hfsplus_find_data fd;
+	struct super_block *sb;
+	hfsplus_cat_entry entry;
+	int err;
+	u32 cnid, linkid = 0;
+	u16 type;
+
+	sb = dir->i_sb;
+	dentry->d_fsdata = NULL;
+	hfsplus_find_init(HFSPLUS_SB(sb).cat_tree, &fd);
+	hfsplus_fill_cat_key(fd.search_key, dir->i_ino, &dentry->d_name);
+again:
+	err = hfsplus_btree_find_entry(&fd, &entry, sizeof(entry));
+	if (err) {
+		if (err == -ENOENT) {
+			hfsplus_find_exit(&fd);
+			/* No such entry */
+			inode = NULL;
+			goto out;
+		}
+		goto fail;
+	}
+	type = be16_to_cpu(entry.type);
+	if (type == HFSPLUS_FOLDER) {
+		if (fd.entrylength < sizeof(hfsplus_cat_folder)) {
+			err = -EIO;
+			goto fail;
+		}
+		cnid = be32_to_cpu(entry.folder.id);
+	} else if (type == HFSPLUS_FILE) {
+		if (fd.entrylength < sizeof(hfsplus_cat_file)) {
+			err = -EIO;
+			goto fail;
+		}
+		cnid = be32_to_cpu(entry.file.id);
+		if (entry.file.user_info.fdType == cpu_to_be32(HFSP_HARDLINK_TYPE) &&
+		    entry.file.user_info.fdCreator == cpu_to_be32(HFSP_HFSPLUS_CREATOR)) {
+			struct qstr str;
+			char name[32];
+
+			if (dentry->d_fsdata) {
+				err = -ENOENT;
+				inode = NULL;
+				goto out;
+			}
+			dentry->d_fsdata = (void *)(unsigned long)cnid;
+			linkid = be32_to_cpu(entry.file.permissions.dev);
+			str.len = sprintf(name, "iNode%d", linkid);
+			str.name = name;
+			hfsplus_fill_cat_key(fd.search_key, HFSPLUS_SB(sb).hidden_dir->i_ino, &str);
+			goto again;
+		} else if (!dentry->d_fsdata)
+			dentry->d_fsdata = (void *)(unsigned long)cnid;
+	} else {
+		printk("HFS+-fs: Illegal catalog entry type in lookup\n");
+		err = -EIO;
+		goto fail;
+	}
+	hfsplus_find_exit(&fd);
+	inode = iget(dir->i_sb, cnid);
+	if (!inode)
+		return ERR_PTR(-EACCES);
+	if (S_ISREG(inode->i_mode))
+		HFSPLUS_I(inode).dev = linkid;
+out:
+	d_add(dentry, inode);
+	return NULL;
+fail:
+	hfsplus_find_exit(&fd);
+	return ERR_PTR(err);
+}
+
+static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct super_block *sb = inode->i_sb;
+	int len, err;
+	char strbuf[HFSPLUS_MAX_STRLEN + 1];
+	hfsplus_cat_entry entry;
+	struct hfsplus_find_data fd;
+	struct hfsplus_readdir_data *rd;
+	u16 type;
+
+	if (filp->f_pos >= inode->i_size)
+		return 0;
+
+	hfsplus_find_init(HFSPLUS_SB(sb).cat_tree, &fd);
+	hfsplus_fill_cat_key(fd.search_key, inode->i_ino, NULL);
+	err = hfsplus_btree_find(&fd);
+	if (err)
+		goto out;
+
+	switch ((u32)filp->f_pos) {
+	case 0:
+		/* This is completely artificial... */
+		if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR))
+			goto out;
+		filp->f_pos++;
+		/* fall through */
+	case 1:
+		hfsplus_bnode_readbytes(fd.bnode, &entry, fd.entryoffset, fd.entrylength);
+		if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) {
+			printk("HFS+-fs: bad catalog folder thread\n");
+			err = -EIO;
+			goto out;
+		}
+		if (fd.entrylength < HFSPLUS_MIN_THREAD_SZ) {
+			printk("HFS+-fs: truncated catalog thread\n");
+			err = -EIO;
+			goto out;
+		}
+		if (filldir(dirent, "..", 2, 1,
+			    be32_to_cpu(entry.thread.parentID), DT_DIR))
+			goto out;
+		filp->f_pos++;
+		/* fall through */
+	default:
+		if (filp->f_pos >= inode->i_size)
+			goto out;
+		err = hfsplus_btiter_move(&fd, filp->f_pos - 1);
+		if (err)
+			goto out;
+	}
+
+	for (;;) {
+		if (be32_to_cpu(fd.key->cat.parent) != inode->i_ino) {
+			printk("HFS+-fs: walked past end of dir\n");
+			err = -EIO;
+			goto out;
+		}
+		hfsplus_bnode_readbytes(fd.bnode, &entry, fd.entryoffset, fd.entrylength);
+		type = be16_to_cpu(entry.type);
+		len = HFSPLUS_MAX_STRLEN;
+		err = hfsplus_uni2asc(&fd.key->cat.name, strbuf, &len);
+		if (err)
+			goto out;
+		if (type == HFSPLUS_FOLDER) {
+			if (fd.entrylength < sizeof(hfsplus_cat_folder)) {
+				printk("HFS+-fs: small dir entry\n");
+				err = -EIO;
+				goto out;
+			}
+			if (HFSPLUS_SB(sb).hidden_dir &&
+			    HFSPLUS_SB(sb).hidden_dir->i_ino == be32_to_cpu(entry.folder.id))
+				goto next;
+			if (filldir(dirent, strbuf, len, filp->f_pos,
+				    be32_to_cpu(entry.folder.id), DT_DIR))
+				break;
+		} else if (type == HFSPLUS_FILE) {
+			if (fd.entrylength < sizeof(hfsplus_cat_file)) {
+				printk("HFS+-fs: small file entry\n");
+				err = -EIO;
+				goto out;
+			}
+			if (filldir(dirent, strbuf, len, filp->f_pos,
+				    be32_to_cpu(entry.file.id), DT_REG))
+				break;
+		} else {
+			printk("HFS+-fs: bad catalog entry type\n");
+			err = -EIO;
+			goto out;
+		}
+	next:
+		filp->f_pos++;
+		if (filp->f_pos >= inode->i_size)
+			goto out;
+		err = hfsplus_btiter_move(&fd, 1);
+		if (err)
+			goto out;
+	}
+	rd = filp->private_data;
+	if (!filp->private_data) {
+		rd = kmalloc(sizeof(struct hfsplus_readdir_data), GFP_KERNEL);
+		if (!rd) {
+			err = -ENOMEM;
+			goto out;
+		}
+		filp->private_data = rd;
+		rd->file = filp;
+		list_add(&rd->list, &HFSPLUS_I(inode).open_dir_list);
+	}
+	memcpy(&rd->key, fd.key, sizeof(hfsplus_cat_key));
+out:
+	hfsplus_find_exit(&fd);
+	return err;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+static loff_t hfsplus_seek_dir(struct file *file, loff_t offset, int origin)
+{
+	loff_t res;
+
+	down(&file->f_dentry->d_inode->i_sem);
+	res = default_llseek(file, offset, origin);
+	up(&file->f_dentry->d_inode->i_sem);
+
+	return res;
+}
+#endif
+
+static int hfsplus_dir_release(struct inode *inode, struct file *file)
+{
+	struct hfsplus_readdir_data *rd = file->private_data;
+	if (rd) {
+		list_del(&rd->list);
+		kfree(rd);
+	}
+	return 0;
+}
+
+int hfsplus_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+	struct super_block *sb = dir->i_sb;
+	struct inode *inode;
+	int res;
+
+	inode = hfsplus_new_inode(sb, mode);
+	if (!inode)
+		return -ENOSPC;
+
+	res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode);
+	if (res) {
+		inode->i_nlink = 0;
+		iput(inode);
+		return res;
+	}
+	dentry->d_fsdata = (void *)inode->i_ino;
+	d_instantiate(dentry, inode);
+	mark_inode_dirty(inode);
+	return 0;
+}
+
+int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, struct dentry *dst_dentry)
+{
+	struct super_block *sb = dst_dir->i_sb;
+	struct inode *inode = src_dentry->d_inode;
+	struct inode *src_dir = src_dentry->d_parent->d_inode;
+	struct qstr str;
+	char name[32];
+	u32 cnid, id;
+	int res;
+
+	if (HFSPLUS_IS_RSRC(inode))
+		return -EPERM;
+
+	if (inode->i_ino == (u32)(unsigned long)src_dentry->d_fsdata) {
+		for (;;) {
+			get_random_bytes(&id, sizeof(cnid));
+			id &= 0x3fffffff;
+			str.name = name;
+			str.len = sprintf(name, "iNode%d", id);
+			res = hfsplus_rename_cat(inode->i_ino,
+						 src_dir, &src_dentry->d_name,
+						 HFSPLUS_SB(sb).hidden_dir, &str);
+			if (!res)
+				break;
+			if (res != -EEXIST)
+				return res;
+		}
+		HFSPLUS_I(inode).dev = id;
+		cnid = HFSPLUS_SB(sb).next_cnid++;
+		src_dentry->d_fsdata = (void *)(unsigned long)cnid;
+		res = hfsplus_create_cat(cnid, src_dir, &src_dentry->d_name, inode);
+		if (res)
+			/* panic? */
+			return res;
+		HFSPLUS_SB(sb).file_count++;
+	}
+	cnid = HFSPLUS_SB(sb).next_cnid++;
+	res = hfsplus_create_cat(cnid, dst_dir, &dst_dentry->d_name, inode);
+	if (res)
+		return res;
+
+	inode->i_nlink++;
+	dst_dentry->d_fsdata = (void *)(unsigned long)cnid;
+	d_instantiate(dst_dentry, inode);
+	atomic_inc(&inode->i_count);
+	inode->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(inode);
+	HFSPLUS_SB(sb).file_count++;
+	sb->s_dirt = 1;
+
+	return 0;
+}
+
+int hfsplus_unlink(struct inode *dir, struct dentry *dentry)
+{
+	struct super_block *sb = dir->i_sb;
+	struct inode *inode = dentry->d_inode;
+	struct qstr str;
+	char name[32];
+	u32 cnid;
+	int res;
+
+	if (HFSPLUS_IS_RSRC(inode))
+		return -EPERM;
+
+	cnid = (u32)(unsigned long)dentry->d_fsdata;
+	if (inode->i_ino == cnid &&
+	    atomic_read(&HFSPLUS_I(inode).opencnt)) {
+		str.name = name;
+		str.len = sprintf(name, "temp%lu", inode->i_ino);
+		res = hfsplus_rename_cat(inode->i_ino,
+					 dir, &dentry->d_name,
+					 HFSPLUS_SB(sb).hidden_dir, &str);
+		if (!res)
+			inode->i_flags |= S_DEAD;
+		return res;
+	}
+	res = hfsplus_delete_cat(cnid, dir, &dentry->d_name);
+	if (res)
+		return res;
+
+	inode->i_nlink--;
+	hfsplus_delete_inode(inode);
+	if (inode->i_ino != cnid && !inode->i_nlink) {
+		if (!atomic_read(&HFSPLUS_I(inode).opencnt)) {
+			res = hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
+			if (!res)
+				hfsplus_delete_inode(inode);
+		} else
+			inode->i_flags |= S_DEAD;
+	}
+	inode->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(inode);
+
+	return res;
+}
+
+int hfsplus_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	struct super_block *sb;
+	struct inode *inode;
+	int res;
+
+	sb = dir->i_sb;
+	inode = dentry->d_inode;
+	inode = hfsplus_new_inode(sb, S_IFDIR | mode);
+	if (!inode)
+		return -ENOSPC;
+
+	res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode);
+	if (res) {
+		inode->i_nlink = 0;
+		iput(inode);
+		return res;
+	}
+	d_instantiate(dentry, inode);
+	mark_inode_dirty(inode);
+	return 0;
+}
+
+int hfsplus_rmdir(struct inode *dir, struct dentry *dentry)
+{
+	struct inode *inode;
+	int res;
+
+	inode = dentry->d_inode;
+	if (inode->i_size != 2)
+		return -ENOTEMPTY;
+	res = hfsplus_delete_cat(inode->i_ino, dir, &dentry->d_name);
+	if (res)
+		return res;
+	inode->i_nlink = 0;
+	inode->i_ctime = CURRENT_TIME;
+	hfsplus_delete_inode(inode);
+	mark_inode_dirty(inode);
+	return 0;
+}
+
+int hfsplus_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+{
+	struct super_block *sb;
+	struct inode *inode;
+	int res;
+
+	sb = dir->i_sb;
+	inode = hfsplus_new_inode(sb, S_IFLNK | S_IRWXUGO);
+	if (!inode)
+		return -ENOSPC;
+
+	res = page_symlink(inode, symname, strlen(symname) + 1);
+	if (res) {
+		inode->i_nlink = 0;
+		iput (inode);
+		return res;
+	}
+
+	mark_inode_dirty(inode);
+	res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode);
+
+	if (!res) {
+		d_instantiate(dentry, inode);
+		mark_inode_dirty(inode);
+	}
+
+	return res;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+int hfsplus_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
+#else
+int hfsplus_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
+#endif
+{
+	struct super_block *sb;
+	struct inode *inode;
+	int res;
+
+	sb = dir->i_sb;
+	inode = hfsplus_new_inode(sb, mode);
+	if (!inode)
+		return -ENOSPC;
+
+	res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode);
+	if (res) {
+		inode->i_nlink = 0;
+		iput(inode);
+		return res;
+	}
+	init_special_inode(inode, mode, rdev);
+	d_instantiate(dentry, inode);
+	mark_inode_dirty(inode);
+
+	return 0;
+}
+
+int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry,
+		   struct inode *new_dir, struct dentry *new_dentry)
+{
+	int res;
+
+	/* Unlink destination if it already exists */
+	if (new_dentry->d_inode) {
+		res = hfsplus_unlink(new_dir, new_dentry);
+		if (res)
+			return res;
+	}
+
+	res = hfsplus_rename_cat(old_dentry->d_inode->i_ino,
+				 old_dir, &old_dentry->d_name,
+				 new_dir, &new_dentry->d_name);
+	return res;
+}
+
+struct inode_operations hfsplus_dir_inode_operations = {
+	.lookup		= hfsplus_lookup,
+	.create		= hfsplus_create,
+	.link		= hfsplus_link,
+	.unlink		= hfsplus_unlink,
+	.mkdir		= hfsplus_mkdir,
+	.rmdir		= hfsplus_rmdir,
+	.symlink	= hfsplus_symlink,
+	.mknod		= hfsplus_mknod,
+	.rename		= hfsplus_rename,
+};
+
+struct file_operations hfsplus_dir_operations = {
+	.read		= generic_read_dir,
+	.readdir	= hfsplus_readdir,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	.llseek		= hfsplus_seek_dir,
+#else
+	.llseek		= generic_file_llseek,
+#endif
+	.release	= hfsplus_dir_release,
+};
diff -urN linux-2.4.22-pre2/fs/hfsplus/extents.c linux-2.4.22-pre3/fs/hfsplus/extents.c
--- linux-2.4.22-pre2/fs/hfsplus/extents.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/extents.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,519 @@
+/*
+ *  linux/fs/hfsplus/extents.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Handling of Extents both in catalog and extents overflow trees
+ */
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <linux/buffer_head.h>
+#endif
+
+#include "hfsplus_fs.h"
+#include "hfsplus_raw.h"
+
+/* Compare two extents keys, returns 0 on same, pos/neg for difference */
+int hfsplus_cmp_ext_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2)
+{
+	u32 k1id, k2id;
+	u32 k1s, k2s;
+
+	k1id = k1->ext.cnid;
+	k2id = k2->ext.cnid;
+	if (k1id != k2id)
+		return be32_to_cpu(k1id) < be32_to_cpu(k2id) ? -1 : 1;
+
+	if (k1->ext.fork_type != k2->ext.fork_type)
+		return k1->ext.fork_type < k2->ext.fork_type ? -1 : 1;
+
+	k1s = k1->ext.start_block;
+	k2s = k2->ext.start_block;
+	if (k1s == k2s)
+		return 0;
+	return be32_to_cpu(k1s) < be32_to_cpu(k2s) ? -1 : 1;
+}
+
+void hfsplus_fill_ext_key(hfsplus_btree_key *key, u32 cnid,
+			  u32 block, u8 type)
+{
+	key->key_len = cpu_to_be16(HFSPLUS_EXT_KEYLEN - 2);
+	key->ext.cnid = cpu_to_be32(cnid);
+	key->ext.start_block = cpu_to_be32(block);
+	key->ext.fork_type = type;
+	key->ext.pad = 0;
+}
+
+static int hfsplus_find_extent(hfsplus_extent *extent, u32 off)
+{
+	int i;
+	u32 count;
+
+	for (i = 0; i < 8; extent++, i++) {
+		count = be32_to_cpu(extent->block_count);
+		if (off < count)
+			return be32_to_cpu(extent->start_block) + off;
+		off -= count;
+	}
+	/* panic? */
+	return 0;
+}
+
+static int hfsplus_find_extentry(struct hfsplus_find_data *fd,
+				 hfsplus_extent *extent)
+{
+	int res;
+
+	fd->key->ext.cnid = 0;
+	res = hfsplus_btree_find(fd);
+	if (res && res != -ENOENT)
+		return res;
+	if (fd->key->ext.cnid != fd->search_key->ext.cnid ||
+	    fd->key->ext.fork_type != fd->search_key->ext.fork_type)
+		return -ENOENT;
+	//if (fd->entrylength != ext_key_size)...
+	hfsplus_bnode_readbytes(fd->bnode, extent, fd->entryoffset, fd->entrylength);
+	return 0;
+}
+
+/* Get a block at iblock for inode, possibly allocating if create */
+int hfsplus_get_block(struct inode *inode, sector_t iblock,
+		      struct buffer_head *bh_result, int create)
+{
+	struct super_block *s;
+	hfsplus_extent_rec ext_entry;
+	struct hfsplus_find_data fd;
+	unsigned long ino;
+	int err = -EIO;
+	u32 ablock, dblock = 0;
+
+	ino = inode->i_ino;
+	s = inode->i_sb;
+
+	/* Convert inode block to disk allocation block */
+	ablock = iblock;
+
+	if (ablock >= HFSPLUS_I(inode).total_blocks) {
+		if (ablock > HFSPLUS_I(inode).total_blocks || !create) {
+			BUG();
+			return -EIO;
+		}
+		if (ablock >= HFSPLUS_I(inode).alloc_blocks) {
+			err = hfsplus_extend_file(inode);
+			if (err)
+				return err;
+		}
+		HFSPLUS_I(inode).mmu_private += s->s_blocksize;
+		HFSPLUS_I(inode).total_blocks++;
+		mark_inode_dirty(inode);
+	} else
+		create = 0;
+
+	if (ablock < HFSPLUS_I(inode).extent_blocks) {
+		dblock = hfsplus_find_extent(HFSPLUS_I(inode).extents, ablock);
+	} else {
+		hfsplus_find_init(HFSPLUS_SB(s).ext_tree, &fd);
+		hfsplus_fill_ext_key(fd.search_key, ino, ablock, HFSPLUS_IS_RSRC(inode) ?
+				     HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA);
+		err = hfsplus_find_extentry(&fd, ext_entry);
+		if (!err)
+			dblock = hfsplus_find_extent(ext_entry, ablock -
+						    be32_to_cpu(fd.key->ext.start_block));
+		hfsplus_find_exit(&fd);
+		if (err) {
+			BUG();
+			return err;
+		}
+	}
+
+	if (!dblock) {
+		BUG();
+		return -EIO;
+	}
+	dprint(DBG_EXTENT, "get_block(%lu): %lu - %u\n", inode->i_ino, iblock, dblock);
+
+	map_bh(bh_result, s, dblock + HFSPLUS_SB(s).blockoffset);
+	if (create)
+		set_buffer_new(bh_result);
+	return 0;
+}
+
+static void hfsplus_dump_extent(hfsplus_extent *extent)
+{
+	int i;
+
+	dprint(DBG_EXTENT, "   ");
+	for (i = 0; i < 8; i++)
+		dprint(DBG_EXTENT, " %u:%u", be32_to_cpu(extent[i].start_block),
+				 be32_to_cpu(extent[i].block_count));
+	dprint(DBG_EXTENT, "\n");
+}
+
+static int hfsplus_add_extent(hfsplus_extent *extent, u32 offset,
+			      u32 alloc_block, u32 block_count)
+{
+	u32 count, start;
+	int i;
+
+	hfsplus_dump_extent(extent);
+	for (i = 0; i < 8; extent++, i++) {
+		count = be32_to_cpu(extent->block_count);
+		if (offset == count) {
+			start = be32_to_cpu(extent->start_block);
+			if (alloc_block != start + count) {
+				if (++i >= 8)
+					return -ENOSPC;
+				extent++;
+				extent->start_block = cpu_to_be32(alloc_block);
+			} else
+				block_count += count;
+			extent->block_count = cpu_to_be32(block_count);
+			return 0;
+		} else if (offset < count)
+			break;
+		offset -= count;
+	}
+	/* panic? */
+	return -EIO;
+}
+
+void hfsplus_free_blocks(struct super_block *sb, u32 start, u32 count)
+{
+	struct inode *anode;
+	struct buffer_head *bh;
+	int size, blk, off;
+	unsigned long *data, word, m;
+
+	anode = HFSPLUS_SB(sb).alloc_file;
+	size = sb->s_blocksize / sizeof(unsigned long);
+	blk = (start >> sb->s_blocksize_bits) / 8;
+	off = (start & (sb->s_blocksize * 8 - 1)) / 8 / sizeof(unsigned long);
+	m = 1 << (~start & (8 * sizeof(unsigned long) - 1));
+
+	HFSPLUS_SB(sb).free_blocks += count;
+	sb->s_dirt = 1;
+
+	while (count) {
+		bh = hfsplus_getblk(anode, blk);
+		data = (unsigned long *)bh->b_data;
+		do {
+			word = ~be32_to_cpu(data[off]);
+			for (;;) {
+				if (word & m)
+					printk("freeing free block %u\n", start);
+				word |= m;
+				start++;
+				if (!--count) {
+					data[off] = cpu_to_be32(~word);
+					goto done;
+				}
+				if (!(m >>= 1))
+					break;
+			}
+			data[off] = cpu_to_be32(~word);
+			m = 1UL << (8 * sizeof(unsigned long) - 1);
+		} while (++off < size);
+	done:
+		mark_buffer_dirty_inode(bh, anode);
+		brelse(bh);
+		if (++blk >= anode->i_blocks)
+			break;
+		off = 0;
+	}
+	if (count)
+		printk("%u block left to free\n", count);
+}
+
+int hfsplus_free_extents(struct super_block *sb, hfsplus_extent *extent,
+			 u32 offset, u32 block_nr)
+{
+	u32 count, start;
+	int i;
+
+	hfsplus_dump_extent(extent);
+	for (i = 0; i < 8; extent++, i++) {
+		count = be32_to_cpu(extent->block_count);
+		if (offset == count)
+			goto found;
+		else if (offset < count)
+			break;
+		offset -= count;
+	}
+	/* panic? */
+	return -EIO;
+found:
+	for (;;) {
+		start = be32_to_cpu(extent->start_block);
+		if (count <= block_nr) {
+			hfsplus_free_blocks(sb, start, count);
+			extent->block_count = 0;
+			extent->start_block = 0;
+			block_nr -= count;
+		} else {
+			count -= block_nr;
+			hfsplus_free_blocks(sb, start + count, block_nr);
+			extent->block_count = cpu_to_be32(count);
+			block_nr = 0;
+		}
+		if (!block_nr || !i)
+			return 0;
+		i--;
+		extent--;
+		count = be32_to_cpu(extent->block_count);
+	}
+}
+
+int hfsplus_free_fork(struct super_block *sb, u32 cnid, hfsplus_fork_raw *fork, int type)
+{
+	struct hfsplus_find_data fd;
+	hfsplus_extent_rec ext_entry;
+	u32 total_blocks, blocks, start;
+	int res, i;
+
+	total_blocks = be32_to_cpu(fork->total_blocks);
+	if (!total_blocks)
+		return 0;
+
+	blocks = 0;
+	for (i = 0; i < 8; i++)
+		blocks += be32_to_cpu(fork->extents[i].block_count);
+
+	res = hfsplus_free_extents(sb, fork->extents, blocks, blocks);
+	if (res)
+		return res;
+	if (total_blocks == blocks)
+		return 0;
+
+	hfsplus_find_init(HFSPLUS_SB(sb).ext_tree, &fd);
+	do {
+		hfsplus_fill_ext_key(fd.search_key, cnid,
+				     total_blocks, type);
+		res = hfsplus_find_extentry(&fd, ext_entry);
+		if (res)
+			break;
+		start = be32_to_cpu(fd.key->ext.start_block);
+		hfsplus_free_extents(sb, ext_entry,
+				     total_blocks - start,
+				     total_blocks);
+		hfsplus_bnode_remove_rec(&fd);
+		total_blocks = start;
+	} while (total_blocks > blocks);
+	hfsplus_find_exit(&fd);
+
+	return res;
+}
+
+int hfsplus_extend_file(struct inode *inode)
+{
+	struct super_block *sb = inode->i_sb;
+	struct inode *anode = HFSPLUS_SB(sb).alloc_file;
+	struct hfsplus_find_data fd;
+	hfsplus_extent_rec ext_entry;
+	struct buffer_head *bh;
+	u32 blk, blk1, ablock, block_count;
+	unsigned long *data, word, m;
+	int res, size, off, i;
+
+	if (anode->i_size * 8 < HFSPLUS_SB(sb).total_blocks - HFSPLUS_SB(sb).free_blocks + 8) {
+		// extend alloc file
+		BUG();
+	}
+	blk = blk1 = (HFSPLUS_SB(sb).next_alloc >> sb->s_blocksize_bits) / 8;
+	off = (HFSPLUS_SB(sb).next_alloc & (sb->s_blocksize * 8 - 1)) / sizeof(unsigned long) / 8;
+
+	for (;;) {
+		// ignore first off for now...
+		off = 0;
+		bh = hfsplus_getblk(anode, blk);
+		if (blk == anode->i_blocks - 1)
+			size = (HFSPLUS_SB(sb).total_blocks &
+				(sb->s_blocksize * 8 - 1)) /
+				8 / sizeof(unsigned long);
+		else
+			size = sb->s_blocksize / sizeof(unsigned long);
+		data = (unsigned long *)bh->b_data;
+		do {
+			word = be32_to_cpu(data[off]);
+			if (!~word)
+				continue;
+			m = 1UL << (sizeof(unsigned long) * 8 - 1);
+			for (i = 0; m; i++, m >>= 1) {
+				if (word & m)
+					continue;
+				ablock = (blk << sb->s_blocksize_bits) * 8 +
+					off * sizeof(unsigned long) * 8 + i;
+				block_count = 1;
+				word |= m;
+#if 0
+				while ((m >>= 1) && !(word & m)) {
+					block_count++;
+					word |= m;
+				}
+#endif
+				data[off] = cpu_to_be32(word);
+				mark_buffer_dirty_inode(bh, anode);
+				brelse(bh);
+				goto found;
+			}
+		} while (++off < size);
+		brelse(bh);
+		if (++blk >= anode->i_blocks)
+			blk = 0;
+		if (blk == blk1)
+			return -ENOSPC;
+	}
+
+found:
+	dprint(DBG_EXTENT, "extend %lu: %u,%u\n", inode->i_ino, ablock, block_count);
+	if (HFSPLUS_I(inode).alloc_blocks <= HFSPLUS_I(inode).extent_blocks) {
+		if (!HFSPLUS_I(inode).extent_blocks) {
+			dprint(DBG_EXTENT, "first extents\n");
+			/* no extents yet */
+			HFSPLUS_I(inode).extents[0].start_block = cpu_to_be32(ablock);
+			HFSPLUS_I(inode).extents[0].block_count = cpu_to_be32(block_count);
+			res = 0;
+		} else
+			/* try to append to extents in inode */
+			res = hfsplus_add_extent(HFSPLUS_I(inode).extents,
+						 HFSPLUS_I(inode).alloc_blocks,
+						 ablock, block_count);
+		if (!res) {
+			hfsplus_dump_extent(HFSPLUS_I(inode).extents);
+			HFSPLUS_I(inode).extent_blocks += block_count;
+		} else if (res == -ENOSPC) {
+			/* create new extent, so find place to insert it */
+			hfsplus_find_init(HFSPLUS_SB(sb).ext_tree, &fd);
+			hfsplus_fill_ext_key(fd.search_key, inode->i_ino,
+					     HFSPLUS_I(inode).alloc_blocks,
+					     HFSPLUS_IS_RSRC(inode) ?
+					     HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA);
+			res = hfsplus_find_extentry(&fd, ext_entry);
+			if (res && res != -ENOENT) {
+				hfsplus_find_exit(&fd);
+				goto out;
+			}
+			goto insert_extent;
+		}
+	} else {
+		hfsplus_find_init(HFSPLUS_SB(sb).ext_tree, &fd);
+		hfsplus_fill_ext_key(fd.search_key, inode->i_ino,
+				     HFSPLUS_I(inode).alloc_blocks,
+				     HFSPLUS_IS_RSRC(inode) ?
+				     HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA);
+		res = hfsplus_find_extentry(&fd, ext_entry);
+		if (res) {
+			hfsplus_find_exit(&fd);
+			goto out;
+		}
+
+		res = hfsplus_add_extent(ext_entry, HFSPLUS_I(inode).alloc_blocks -
+					 be32_to_cpu(fd.key->ext.start_block),
+					 ablock, block_count);
+		if (!res) {
+			hfsplus_dump_extent(ext_entry);
+			hfsplus_bnode_writebytes(fd.bnode, &ext_entry,
+						 fd.entryoffset,
+						 sizeof(ext_entry));
+		} else if (res == -ENOSPC)
+			goto insert_extent;
+		hfsplus_find_exit(&fd);
+	}
+out:
+	if (!res) {
+		HFSPLUS_I(inode).alloc_blocks += block_count;
+		mark_inode_dirty(inode);
+		HFSPLUS_SB(sb).free_blocks -= block_count;
+		sb->s_dirt = 1;
+	}
+	return res;
+
+insert_extent:
+	dprint(DBG_EXTENT, "insert new extent\n");
+	memset(ext_entry, 0, sizeof(ext_entry));
+	ext_entry[0].start_block = cpu_to_be32(ablock);
+	ext_entry[0].block_count = cpu_to_be32(block_count);
+
+	hfsplus_bnode_insert_rec(&fd, ext_entry, sizeof(ext_entry));
+	hfsplus_find_exit(&fd);
+	res = 0;
+	goto out;
+}
+
+void hfsplus_truncate(struct inode *inode)
+{
+	struct super_block *sb = inode->i_sb;
+	struct hfsplus_find_data fd;
+	hfsplus_extent_rec ext_entry;
+	u32 blk_cnt, start;
+	int res;
+
+	dprint(DBG_INODE, "truncate: %lu, %Lu -> %Lu\n", inode->i_ino,
+	       (long long)HFSPLUS_I(inode).mmu_private, inode->i_size);
+	if (inode->i_size == HFSPLUS_I(inode).mmu_private)
+		return;
+	if (inode->i_size > HFSPLUS_I(inode).mmu_private) {
+		struct address_space *mapping = inode->i_mapping;
+		struct page *page;
+		u32 size = inode->i_size - 1;
+		int res;
+
+		page = grab_cache_page(mapping, size >> PAGE_CACHE_SHIFT);
+		if (!page)
+			return;
+		size &= PAGE_CACHE_SIZE - 1;
+		size++;
+		res = mapping->a_ops->prepare_write(NULL, page, size, size);
+		if (!res)
+			res = mapping->a_ops->commit_write(NULL, page, size, size);
+		if (res)
+			inode->i_size = HFSPLUS_I(inode).mmu_private;
+		unlock_page(page);
+		page_cache_release(page);
+		mark_inode_dirty(inode);
+		return;
+	}
+	blk_cnt = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
+
+	while (1) {
+		if (HFSPLUS_I(inode).alloc_blocks <= HFSPLUS_I(inode).extent_blocks) {
+			hfsplus_free_extents(sb, HFSPLUS_I(inode).extents,
+					     HFSPLUS_I(inode).alloc_blocks,
+					     HFSPLUS_I(inode).alloc_blocks - blk_cnt);
+			hfsplus_dump_extent(HFSPLUS_I(inode).extents);
+			HFSPLUS_I(inode).extent_blocks = blk_cnt;
+			break;
+		}
+		hfsplus_find_init(HFSPLUS_SB(sb).ext_tree, &fd);
+		hfsplus_fill_ext_key(fd.search_key, inode->i_ino,
+				     HFSPLUS_I(inode).alloc_blocks,
+				     HFSPLUS_IS_RSRC(inode) ?
+				     HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA);
+		res = hfsplus_find_extentry(&fd, ext_entry);
+		if (res) {
+			hfsplus_find_exit(&fd);
+			break;
+		}
+		start = be32_to_cpu(fd.key->ext.start_block);
+		hfsplus_free_extents(sb, ext_entry,
+				     HFSPLUS_I(inode).alloc_blocks - start,
+				     HFSPLUS_I(inode).alloc_blocks - blk_cnt);
+		hfsplus_dump_extent(ext_entry);
+		if (blk_cnt > start) {
+			hfsplus_bnode_writebytes(fd.bnode, &ext_entry,
+						 fd.entryoffset,
+						 sizeof(ext_entry));
+			hfsplus_find_exit(&fd);
+			break;
+		}
+		HFSPLUS_I(inode).alloc_blocks = start;
+		hfsplus_bnode_remove_rec(&fd);
+		hfsplus_find_exit(&fd);
+	}
+	HFSPLUS_I(inode).mmu_private = inode->i_size;
+	HFSPLUS_I(inode).alloc_blocks = HFSPLUS_I(inode).total_blocks = blk_cnt;
+}
diff -urN linux-2.4.22-pre2/fs/hfsplus/hfsplus_fs.h linux-2.4.22-pre3/fs/hfsplus/hfsplus_fs.h
--- linux-2.4.22-pre2/fs/hfsplus/hfsplus_fs.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/hfsplus_fs.h	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,293 @@
+/*
+ *  linux/include/linux/hfsplus_fs.h
+ *
+ * Copyright (C) 1999
+ * Brad Boyer (flar@pants.nu)
+ *
+ */
+
+#ifndef _LINUX_HFSPLUS_FS_H
+#define _LINUX_HFSPLUS_FS_H
+
+#include <linux/fs.h>
+#include <linux/version.h>
+#include "hfsplus_raw.h"
+#include "hfsplus_fs_sb.h"
+#include "hfsplus_fs_i.h"
+
+#define DBG_BNODE_REFS	0x00000001
+#define DBG_BNODE_MOD	0x00000002
+#define DBG_CAT_MOD	0x00000004
+#define DBG_INODE	0x00000008
+#define DBG_SUPER	0x00000010
+#define DBG_EXTENT	0x00000020
+
+//#define DBG_MASK	(DBG_EXTENT|DBG_INODE|DBG_BNODE_MOD)
+//#define DBG_MASK	(DBG_BNODE_MOD|DBG_CAT_MOD)
+//#define DBG_MASK	(DBG_BNODE_REFS|DBG_INODE|DBG_BNODE_MOD)
+#define DBG_MASK	(0)
+
+#define dprint(flg, fmt, args...) \
+	if (flg & DBG_MASK) printk(fmt , ## args)
+
+/* Runtime config options */
+#define HFSPLUS_CASE_ASIS      0
+#define HFSPLUS_CASE_LOWER     1
+
+#define HFSPLUS_FORK_RAW       0
+#define HFSPLUS_FORK_CAP       1
+#define HFSPLUS_FORK_DOUBLE    2
+#define HFSPLUS_FORK_NETATALK  3
+
+#define HFSPLUS_NAMES_TRIVIAL  0
+#define HFSPLUS_NAMES_CAP      1
+#define HFSPLUS_NAMES_NETATALK 2
+#define HFSPLUS_NAMES_7BIT     3
+
+#define HFSPLUS_DEF_CR_TYPE    0x3F3F3F3F  /* '????' */
+
+#define HFSPLUS_TYPE_DATA 0x00
+#define HFSPLUS_TYPE_RSRC 0xFF
+
+typedef int (*btree_keycmp)(hfsplus_btree_key *, hfsplus_btree_key *);
+
+#define NODE_HASH_SIZE	256
+
+/* An HFS+ BTree held in memory */
+typedef struct hfsplus_btree {
+	struct super_block *sb;
+	struct inode *inode;
+	btree_keycmp keycmp;
+
+	u32 cnid;
+	u32 root;
+	u32 leaf_count;
+	u32 leaf_head;
+	u32 leaf_tail;
+	u32 node_count;
+	u32 free_nodes;
+	u32 attributes;
+
+	unsigned int node_size;
+	unsigned int node_size_shift;
+	unsigned int max_key_len;
+	unsigned int depth;
+
+	//unsigned int map1_size, map_size;
+	struct semaphore tree_lock;
+
+	unsigned int pages_per_bnode;
+	spinlock_t hash_lock;
+	struct hfsplus_bnode *node_hash[NODE_HASH_SIZE];
+	int node_hash_cnt;
+} hfsplus_btree;
+
+struct page;
+
+/* An HFS+ BTree node in memory */
+typedef struct hfsplus_bnode {
+	struct hfsplus_btree *tree;
+
+	u32 prev;
+	u32 this;
+	u32 next;
+	u32 parent;
+
+	u16 num_recs;
+	u8 kind;
+	u8 height;
+
+	struct hfsplus_bnode *next_hash;
+	unsigned long flags;
+	wait_queue_head_t lock_wq;
+	atomic_t refcnt;
+	unsigned int page_offset;
+	struct page *page[0];
+} hfsplus_bnode;
+
+#define HFSPLUS_BNODE_LOCK	0
+#define HFSPLUS_BNODE_ERROR	1
+#define HFSPLUS_BNODE_NEW	2
+#define HFSPLUS_BNODE_DIRTY	3
+#define HFSPLUS_BNODE_DELETED	4
+
+struct hfsplus_find_data {
+	/* filled by caller */
+	hfsplus_btree_key *search_key;
+	hfsplus_btree_key *key;
+	/* filled by find */
+	hfsplus_btree *tree;
+	hfsplus_bnode *bnode;
+	/* filled by findrec */
+	int record, exact;
+	int keyoffset, keylength;
+	int entryoffset, entrylength;
+};
+
+struct hfsplus_readdir_data {
+	struct list_head list;
+	struct file *file;
+	hfsplus_cat_key key;
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+typedef long sector_t;
+#endif
+
+/*
+ * Functions in any *.c used in other files
+ */
+
+/* bfind.c */
+void hfsplus_find_rec(hfsplus_bnode *, struct hfsplus_find_data *);
+int hfsplus_btree_find(struct hfsplus_find_data *);
+int hfsplus_btree_find_entry(struct hfsplus_find_data *,
+			     void *, int);
+int hfsplus_find_init(hfsplus_btree *, struct hfsplus_find_data *);
+void hfsplus_find_exit(struct hfsplus_find_data *);
+
+/* bnode.c */
+struct buffer_head *hfsplus_getblk(struct inode *, unsigned long);
+hfsplus_bnode *__hfsplus_find_bnode(hfsplus_btree *, u32);
+void __hfsplus_bnode_remove(hfsplus_bnode *);
+hfsplus_bnode *hfsplus_create_bnode(hfsplus_btree *, u32);
+hfsplus_bnode *hfsplus_find_bnode(hfsplus_btree *, u32);
+void hfsplus_get_bnode(hfsplus_bnode *);
+void hfsplus_put_bnode(hfsplus_bnode *);
+void hfsplus_bnode_free(hfsplus_bnode *);
+void hfsplus_bnode_readbytes(hfsplus_bnode *, void *, unsigned long, unsigned long);
+u16 hfsplus_bnode_read_u16(hfsplus_bnode *, unsigned long);
+void hfsplus_bnode_writebytes(hfsplus_bnode *, void *, unsigned long, unsigned long);
+void hfsplus_bnode_write_u16(hfsplus_bnode *, unsigned long, u16);
+void hfsplus_bnode_copybytes(hfsplus_bnode *, unsigned long,
+			     hfsplus_bnode *, unsigned long, unsigned long);
+void hfsplus_bnode_movebytes(hfsplus_bnode *, unsigned long, unsigned long, unsigned long);
+int hfsplus_bnode_insert_rec(struct hfsplus_find_data *, void *, int);
+int hfsplus_bnode_remove_rec(struct hfsplus_find_data *);
+
+/* brec.c */
+u16 hfsplus_brec_off(hfsplus_bnode *, u16);
+u16 hfsplus_brec_len(hfsplus_bnode *, u16);
+u16 hfsplus_brec_lenoff(hfsplus_bnode *, u16, u16 *);
+u16 hfsplus_brec_data(hfsplus_bnode *, u16, char *, u16);
+u16 hfsplus_brec_keylen(hfsplus_bnode *, u16);
+u16 hfsplus_brec_key(hfsplus_bnode *, u16, void *, u16);
+
+/* btiter.c */
+int hfsplus_btiter_move(struct hfsplus_find_data *, int);
+
+/* btree.c */
+hfsplus_btree *hfsplus_open_btree(struct super_block *, u32);
+void hfsplus_close_btree(struct hfsplus_btree *);
+void hfsplus_write_btree(struct hfsplus_btree *);
+hfsplus_bnode *hfsplus_btree_alloc_node(hfsplus_btree *);
+void hfsplus_btree_remove_node(hfsplus_bnode *);
+void hfsplus_btree_free_node(hfsplus_bnode *);
+
+/* catalog.c */
+int hfsplus_cmp_cat_key(hfsplus_btree_key *, hfsplus_btree_key *);
+void hfsplus_fill_cat_key(hfsplus_btree_key *, u32, struct qstr *);
+int hfsplus_find_cat(struct super_block *, unsigned long, struct hfsplus_find_data *);
+int hfsplus_create_cat(u32, struct inode *, struct qstr *, struct inode *);
+int hfsplus_delete_cat(u32, struct inode *, struct qstr *);
+int hfsplus_rename_cat(u32, struct inode *, struct qstr *,
+		       struct inode *, struct qstr *);
+
+/* extents.c */
+int hfsplus_cmp_ext_key(hfsplus_btree_key *, hfsplus_btree_key *);
+void hfsplus_fill_ext_key(hfsplus_btree_key *, u32, u32, u8);
+int hfsplus_get_block(struct inode *, sector_t, struct buffer_head *, int);
+int hfsplus_free_fork(struct super_block *, u32, hfsplus_fork_raw *, int);
+int hfsplus_extend_file(struct inode *);
+void hfsplus_truncate(struct inode *);
+
+/* inode.c */
+void hfsplus_inode_read_fork(struct inode *, hfsplus_fork_raw *);
+void hfsplus_inode_write_fork(struct inode *, hfsplus_fork_raw *);
+int hfsplus_cat_read_inode(struct inode *, struct hfsplus_find_data *);
+void hfsplus_cat_write_inode(struct inode *);
+struct inode *hfsplus_new_inode(struct super_block *, int);
+void hfsplus_delete_inode(struct inode *);
+
+extern struct address_space_operations hfsplus_btree_aops;
+
+/* options.c */
+int parse_options(char *, struct hfsplus_sb_info *);
+void fill_defaults(struct hfsplus_sb_info *);
+void fill_current(struct hfsplus_sb_info *, struct hfsplus_sb_info *);
+
+/* tables.c */
+extern u16 case_fold_table[];
+
+/* unicode.c */
+int hfsplus_unistrcmp(const hfsplus_unistr *, const hfsplus_unistr *);
+int hfsplus_uni2asc(const hfsplus_unistr *, char *, int *);
+int hfsplus_asc2uni(hfsplus_unistr *, const char *, int);
+
+/* wrapper.c */
+int hfsplus_read_wrapper(struct super_block *);
+
+/* access macros */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define HFSPLUS_SB(super)        (*(struct hfsplus_sb_info *)&(super)->u)
+#define HFSPLUS_I(inode)         (*(struct hfsplus_inode_info *)&(inode)->u)
+#else
+/*
+static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb)
+{
+	return sb->s_fs_info;
+}
+static inline struct hfsplus_inode_info *HFSPLUS_I(struct inode *inode)
+{
+	return list_entry(inode, struct hfsplus_inode_info, vfs_inode);
+}
+*/
+#define HFSPLUS_SB(super)	(*(struct hfsplus_sb_info *)(super)->s_fs_info)
+#define HFSPLUS_I(inode)	(*list_entry(inode, struct hfsplus_inode_info, vfs_inode))
+#endif
+
+#if 1
+#define hfsplus_kmap(p)		({ struct page *__p = (p); kmap(__p); })
+#define hfsplus_kunmap(p)	({ struct page *__p = (p); kunmap(__p); __p; })
+#else
+#define hfsplus_kmap(p)		kmap(p)
+#define hfsplus_kunmap(p)	kunmap(p)
+#endif
+
+/* time macros */
+#define __hfsp_mt2ut(t)		(be32_to_cpu(t) - 2082844800U)
+#define __hfsp_ut2mt(t)		(cpu_to_be32(t + 2082844800U))
+
+/* compatibility */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define PageUptodate(page)	Page_Uptodate(page)
+#define wait_on_page_locked(page) wait_on_page(page)
+#define get_seconds()		CURRENT_TIME
+#define page_symlink(i,n,l)		block_symlink(i,n,l)
+#define map_bh(bh, sb, bl) ({					\
+	bh->b_dev = kdev_t_to_nr(sb->s_dev);			\
+	bh->b_blocknr = dblock + HFSPLUS_SB(sb).blockoffset;	\
+	bh->b_state |= (1UL << BH_Mapped);			\
+})
+#define set_buffer_new(bh)	(bh->b_state |= (1UL << BH_New))
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,21)
+#define new_inode(sb) ({					\
+	struct inode *inode = get_empty_inode();		\
+	if (inode) {						\
+		inode->i_sb = sb;				\
+		inode->i_dev = sb->s_dev;			\
+		inode->i_blkbits = sb->s_blocksize_bits;	\
+	}							\
+	inode;							\
+})
+#endif
+#define	hfsp_mt2ut(t)		__hfsp_mt2ut(t)
+#define hfsp_ut2mt(t)		__hfsp_ut2mt(t)
+#define hfsp_now2mt()		__hfsp_ut2mt(CURRENT_TIME)
+#else
+#define hfsp_mt2ut(t)		(struct timespec){ .tv_sec = __hfsp_mt2ut(t) }
+#define hfsp_ut2mt(t)		__hfsp_ut2mt((t).tv_sec)
+#define hfsp_now2mt()		__hfsp_ut2mt(get_seconds())
+#endif
+
+#endif
diff -urN linux-2.4.22-pre2/fs/hfsplus/hfsplus_fs_i.h linux-2.4.22-pre3/fs/hfsplus/hfsplus_fs_i.h
--- linux-2.4.22-pre2/fs/hfsplus/hfsplus_fs_i.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/hfsplus_fs_i.h	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,41 @@
+/*
+ *  linux/include/linux/hfsplus_fs_i.h
+ *
+ * Copyright (C) 1999
+ * Brad Boyer (flar@pants.nu)
+ *
+ */
+
+#ifndef _LINUX_HFSPLUS_FS_I_H
+#define _LINUX_HFSPLUS_FS_I_H
+
+#include <linux/types.h>
+#include <linux/version.h>
+#include "hfsplus_raw.h"
+
+struct hfsplus_inode_info {
+	/* Device number in hfsplus_permissions in catalog */
+	u32 dev;
+	/* Allocation extents from catlog record or volume header */
+	hfsplus_extent_rec extents;
+	u32 total_blocks, extent_blocks, alloc_blocks;
+	atomic_t opencnt;
+
+	struct inode *rsrc_inode;
+	unsigned long flags;
+
+	struct list_head open_dir_list;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	unsigned long mmu_private;
+#else
+	loff_t mmu_private;
+	struct inode vfs_inode;
+#endif
+};
+
+#define HFSPLUS_FLG_RSRC	0x0001
+
+#define HFSPLUS_IS_DATA(inode)   (!(HFSPLUS_I(inode).flags & HFSPLUS_FLG_RSRC))
+#define HFSPLUS_IS_RSRC(inode)   (HFSPLUS_I(inode).flags & HFSPLUS_FLG_RSRC)
+
+#endif
diff -urN linux-2.4.22-pre2/fs/hfsplus/hfsplus_fs_sb.h linux-2.4.22-pre3/fs/hfsplus/hfsplus_fs_sb.h
--- linux-2.4.22-pre2/fs/hfsplus/hfsplus_fs_sb.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/hfsplus_fs_sb.h	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,69 @@
+/*
+ *  linux/include/linux/hfsplus_fs_sb.h
+ *
+ * Copyright (C) 1999
+ * Brad Boyer (flar@pants.nu)
+ *
+ */
+
+#ifndef _LINUX_HFSPLUS_FS_SB_H
+#define _LINUX_HFSPLUS_FS_SB_H
+
+#include <linux/types.h>
+
+/*
+ * HFS+ superblock info (built from Volume Header on disk)
+ */
+
+struct hfsplus_vh;
+struct hfsplus_btree;
+
+struct hfsplus_sb_info {
+	struct buffer_head *s_vhbh;
+	struct hfsplus_vh *s_vhdr;
+	struct hfsplus_btree *ext_tree;
+	struct hfsplus_btree *cat_tree;
+	struct hfsplus_btree *attr_tree;
+	struct inode *alloc_file;
+	struct inode *hidden_dir;
+
+	/* Runtime variables */
+	u32 blockoffset;
+	u32 sect_count;
+	//int a2b_shift;
+
+	/* Stuff in host order from Vol Header */
+	u32 total_blocks;
+	u32 free_blocks;
+	u32 next_alloc;
+	u32 next_cnid;
+	u32 file_count;
+	u32 folder_count;
+
+	/* Config options */
+	u32 creator;
+	u32 type;
+
+	int charcase;
+	int fork;
+	int namemap;
+
+	umode_t umask;
+	uid_t uid;
+	gid_t gid;
+
+	unsigned long flags;
+
+	atomic_t inode_cnt;
+	u32 last_inode_cnt;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	struct list_head rsrc_inodes;
+#else
+	struct hlist_head rsrc_inodes;
+#endif
+};
+
+#define HFSPLUS_SB_WRITEBACKUP	0x0001
+
+#endif
diff -urN linux-2.4.22-pre2/fs/hfsplus/hfsplus_raw.h linux-2.4.22-pre3/fs/hfsplus/hfsplus_raw.h
--- linux-2.4.22-pre2/fs/hfsplus/hfsplus_raw.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/hfsplus_raw.h	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,318 @@
+/*
+ *  linux/include/linux/hfsplus_raw.h
+ *
+ * Copyright (C) 1999
+ * Brad Boyer (flar@pants.nu)
+ *
+ * Format of structures on disk
+ * Information taken from Apple Technote #1150 (HFS Plus Volume Format)
+ *
+ */
+
+#ifndef _LINUX_HFSPLUS_RAW_H
+#define _LINUX_HFSPLUS_RAW_H
+
+#include <linux/types.h>
+
+#define __packed __attribute__ ((packed))
+
+/* Some constants */
+#define HFSPLUS_SECTOR_SIZE        512
+#define HFSPLUS_VOLHEAD_SECTOR       2
+#define HFSPLUS_VOLHEAD_SIG     0x482b
+#define HFSPLUS_SUPER_MAGIC     0x482b
+#define HFSPLUS_CURRENT_VERSION      4
+
+#define HFSP_WRAP_MAGIC         0x4244
+#define HFSP_WRAP_ATTRIB_SLOCK  0x8000
+#define HFSP_WRAP_ATTRIB_SPARED 0x0200
+
+#define HFSP_WRAPOFF_SIG          0x00
+#define HFSP_WRAPOFF_ATTRIB       0x0A
+#define HFSP_WRAPOFF_ABLKSIZE     0x14
+#define HFSP_WRAPOFF_ABLKSTART    0x1C
+#define HFSP_WRAPOFF_EMBEDSIG     0x7C
+#define HFSP_WRAPOFF_EMBEDEXT     0x7E
+
+#define HFSP_HIDDENDIR_NAME	"\xe2\x90\x80\xe2\x90\x80\xe2\x90\x80\xe2\x90\x80HFS+ Private Data"
+
+#define HFSP_HARDLINK_TYPE	0x686c6e6b
+#define HFSP_HFSPLUS_CREATOR	0x6866732b
+
+/* Structures used on disk */
+
+typedef u32 hfsplus_cnid;
+typedef u16 hfsplus_unichr;
+
+/* A "string" as used in filenames, etc. */
+typedef struct {
+	u16 length;
+	hfsplus_unichr unicode[255];
+} __packed hfsplus_unistr;
+
+#define HFSPLUS_MAX_STRLEN 255
+
+/* POSIX permissions */
+typedef struct {
+	u32 owner;
+	u32 group;
+	u32 mode;
+	u32 dev;
+} __packed hfsplus_perm;
+
+/* A single contiguous area of a file */
+typedef struct {
+	u32 start_block;
+	u32 block_count;
+} __packed hfsplus_extent;
+typedef hfsplus_extent hfsplus_extent_rec[8];
+
+/* Information for a "Fork" in a file */
+typedef struct {
+	u64 total_size;
+	u32 clump_size;
+	u32 total_blocks;
+	hfsplus_extent_rec extents;
+} __packed hfsplus_fork_raw;
+
+/* HFS+ Volume Header */
+typedef struct hfsplus_vh {
+	u16 signature;
+	u16 version;
+	u32 attributes;
+	u32 last_mount_vers;
+	u32 reserved;
+
+	u32 create_date;
+	u32 modify_date;
+	u32 backup_date;
+	u32 checked_date;
+
+	u32 file_count;
+	u32 folder_count;
+
+	u32 blocksize;
+	u32 total_blocks;
+	u32 free_blocks;
+
+	u32 next_alloc;
+	u32 rsrc_clump_sz;
+	u32 data_clump_sz;
+	hfsplus_cnid next_cnid;
+
+	u32 write_count;
+	u64 encodings_bmp;
+
+	u8 finder_info[32];
+
+	hfsplus_fork_raw alloc_file;
+	hfsplus_fork_raw ext_file;
+	hfsplus_fork_raw cat_file;
+	hfsplus_fork_raw attr_file;
+	hfsplus_fork_raw start_file;
+} __packed hfsplus_vh;
+
+/* HFS+ volume attributes */
+#define HFSPLUS_VOL_UNMNT     (1 << 8)
+#define HFSPLUS_VOL_SPARE_BLK (1 << 9)
+#define HFSPLUS_VOL_NOCACHE   (1 << 10)
+#define HFSPLUS_VOL_INCNSTNT  (1 << 11)
+#define HFSPLUS_VOL_SOFTLOCK  (1 << 15)
+
+/* HFS+ BTree node descriptor */
+typedef struct {
+	u32 next;
+	u32 prev;
+	s8 kind;
+	u8 height;
+	u16 num_rec;
+	u16 reserved;
+} __packed hfsplus_btree_node_desc;
+
+/* HFS+ BTree node types */
+#define HFSPLUS_NODE_NDX  0x00
+#define HFSPLUS_NODE_HEAD 0x01
+#define HFSPLUS_NODE_MAP  0x02
+#define HFSPLUS_NODE_LEAF 0xFF
+
+/* HFS+ BTree header */
+typedef struct {
+	u16 depth;
+	u32 root;
+	u32 leaf_count;
+	u32 leaf_head;
+	u32 leaf_tail;
+	u16 node_size;
+	u16 max_key_len;
+	u32 node_count;
+	u32 free_nodes;
+	u16 reserved1;
+	u32 clump_size;
+	u8 btree_type;
+	u8 reserved2;
+	u32 attributes;
+	u32 reserved3[16];
+} __packed hfsplus_btree_head;
+
+/* BTree attributes */
+#define HFSPLUS_TREE_BIGKEYS         2
+#define HFSPLUS_TREE_VAR_NDXKEY_SIZE 4
+
+/* HFS+ BTree misc info */
+#define HFSPLUS_TREE_HEAD 0
+#define HFSPLUS_NODE_MXSZ 32768
+
+/* Some special File ID numbers (stolen from hfs.h) */
+#define HFSPLUS_POR_CNID		1	/* Parent Of the Root */
+#define HFSPLUS_ROOT_CNID		2	/* ROOT directory */
+#define HFSPLUS_EXT_CNID		3	/* EXTents B-tree */
+#define HFSPLUS_CAT_CNID		4	/* CATalog B-tree */
+#define HFSPLUS_BAD_CNID		5	/* BAD blocks file */
+#define HFSPLUS_ALLOC_CNID		6	/* ALLOCation file */
+#define HFSPLUS_START_CNID		7	/* STARTup file */
+#define HFSPLUS_ATTR_CNID		8	/* ATTRibutes file */
+#define HFSPLUS_EXCH_CNID		15	/* ExchangeFiles temp id */
+#define HFSPLUS_FIRSTUSER_CNID		16	/* first available user id */
+
+/* HFS+ catalog entry key */
+typedef struct {
+	u16 key_len;
+	hfsplus_cnid parent;
+	hfsplus_unistr name;
+} __packed hfsplus_cat_key;
+
+
+/* Structs from hfs.h */
+typedef struct {
+	u16 v;
+	u16 h;
+} __packed hfsp_point;
+
+typedef struct {
+	u16 top;
+	u16 left;
+	u16 bottom;
+	u16 right;
+} __packed hfsp_rect;
+
+
+/* HFS directory info (stolen from hfs.h */
+typedef struct {
+	hfsp_rect frRect;
+	u16 frFlags;
+	hfsp_point frLocation;
+	u16 frView;
+} __packed DInfo;
+
+typedef struct {
+	hfsp_point frScroll;
+	u32 frOpenChain;
+	u16 frUnused;
+	u16 frComment;
+	u32 frPutAway;
+} __packed DXInfo;
+
+/* HFS+ folder data (part of an hfsplus_cat_entry) */
+typedef struct {
+	s16 type;
+	u16 flags;
+	u32 valence;
+	hfsplus_cnid id;
+	u32 create_date;
+	u32 content_mod_date;
+	u32 attribute_mod_date;
+	u32 access_date;
+	u32 backup_date;
+	hfsplus_perm permissions;
+	DInfo user_info;
+	DXInfo finder_info;
+	u32 text_encoding;
+	u32 reserved;
+} __packed hfsplus_cat_folder;
+
+/* HFS file info (stolen from hfs.h) */
+typedef struct {
+	u32 fdType;
+	u32 fdCreator;
+	u16 fdFlags;
+	hfsp_point fdLocation;
+	u16 fdFldr;
+} __packed FInfo;
+
+typedef struct {
+	u16 fdIconID;
+	u8 fdUnused[8];
+	u16 fdComment;
+	u32 fdPutAway;
+} __packed FXInfo;
+
+/* HFS+ file data (part of a cat_entry) */
+typedef struct {
+	s16 type;
+	u16 flags;
+	u32 reserved1;
+	hfsplus_cnid id;
+	u32 create_date;
+	u32 content_mod_date;
+	u32 attribute_mod_date;
+	u32 access_date;
+	u32 backup_date;
+	hfsplus_perm permissions;
+	FInfo user_info;
+	FXInfo finder_info;
+	u32 text_encoding;
+	u32 reserved2;
+
+	hfsplus_fork_raw data_fork;
+	hfsplus_fork_raw rsrc_fork;
+} __packed hfsplus_cat_file;
+
+/* File attribute bits */
+#define kHFSFileLockedBit       0x0000
+#define kHFSFileLockedMask      0x0001
+#define kHFSThreadExistsBit     0x0001
+#define kHFSThreadExistsMask    0x0002
+
+/* HFS+ catalog thread (part of a cat_entry) */
+typedef struct {
+	s16 type;
+	s16 reserved;
+	hfsplus_cnid parentID;
+	hfsplus_unistr nodeName;
+} __packed hfsplus_cat_thread;
+
+#define HFSPLUS_MIN_THREAD_SZ 10
+
+/* A data record in the catalog tree */
+typedef union {
+	s16 type;
+	hfsplus_cat_folder folder;
+	hfsplus_cat_file file;
+	hfsplus_cat_thread thread;
+} __packed hfsplus_cat_entry;
+
+/* HFS+ catalog entry type */
+#define HFSPLUS_FOLDER         0x0001
+#define HFSPLUS_FILE           0x0002
+#define HFSPLUS_FOLDER_THREAD  0x0003
+#define HFSPLUS_FILE_THREAD    0x0004
+
+/* HFS+ extents tree key */
+typedef struct {
+	u16 key_len;
+	u8 fork_type;
+	u8 pad;
+	hfsplus_cnid cnid;
+	u32 start_block;
+} __packed hfsplus_ext_key;
+
+#define HFSPLUS_EXT_KEYLEN 12
+
+/* HFS+ generic BTree key */
+typedef union {
+	u16 key_len;
+	hfsplus_cat_key cat;
+	hfsplus_ext_key ext;
+} __packed hfsplus_btree_key;
+
+#endif
diff -urN linux-2.4.22-pre2/fs/hfsplus/inode.c linux-2.4.22-pre3/fs/hfsplus/inode.c
--- linux-2.4.22-pre2/fs/hfsplus/inode.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/inode.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,502 @@
+/*
+ *  linux/fs/hfsplus/inode.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Inode handling routines
+ */
+
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <linux/buffer_head.h>
+#endif
+
+#include "hfsplus_fs.h"
+#include "hfsplus_raw.h"
+
+static int hfsplus_readpage(struct file *file, struct page *page)
+{
+	//printk("readpage: %lu\n", page->index);
+	return block_read_full_page(page, hfsplus_get_block);
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+static int hfsplus_writepage(struct page *page, struct writeback_control *wbc)
+{
+	//printk("writepage: %lu\n", page->index);
+	return block_write_full_page(page, hfsplus_get_block, wbc);
+}
+#else
+static int hfsplus_writepage(struct page *page)
+{
+	//printk("writepage: %lu\n", page->index);
+	return block_write_full_page(page, hfsplus_get_block);
+}
+#endif
+
+static int hfsplus_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+{
+	return cont_prepare_write(page, from, to, hfsplus_get_block,
+		&HFSPLUS_I(page->mapping->host).mmu_private);
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+static int hfsplus_bmap(struct address_space *mapping, long block)
+#else
+static sector_t hfsplus_bmap(struct address_space *mapping, sector_t block)
+#endif
+{
+	return generic_block_bmap(mapping, block, hfsplus_get_block);
+}
+
+int hfsplus_releasepage(struct page *page, int mask)
+{
+	struct inode *inode = page->mapping->host;
+	struct super_block *sb = inode->i_sb;
+	struct hfsplus_btree *tree;
+	hfsplus_bnode *node;
+	u32 nidx;
+	int i, res = 1;
+
+	switch (inode->i_ino) {
+	case HFSPLUS_EXT_CNID:
+		tree = HFSPLUS_SB(sb).ext_tree;
+		break;
+	case HFSPLUS_CAT_CNID:
+		tree = HFSPLUS_SB(sb).cat_tree;
+		break;
+	case HFSPLUS_ATTR_CNID:
+		tree = HFSPLUS_SB(sb).attr_tree;
+		break;
+	default:
+		BUG();
+		return 0;
+	}
+	if (tree->node_size >= PAGE_CACHE_SIZE) {
+		nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT);
+		spin_lock(&tree->hash_lock);
+		node = __hfsplus_find_bnode(tree, nidx);
+		if (!node)
+			;
+		else if (atomic_read(&node->refcnt))
+			res = 0;
+		else for (i = 0; i < tree->pages_per_bnode; i++) {
+			if (PageActive(node->page[i])) {
+				res = 0;
+				break;
+			}
+		}
+		if (res && node) {
+			__hfsplus_bnode_remove(node);
+			hfsplus_bnode_free(node);
+		}
+		spin_unlock(&tree->hash_lock);
+	} else {
+		nidx = page->index >> (PAGE_CACHE_SHIFT - tree->node_size_shift);
+		i = 1 << (PAGE_CACHE_SHIFT - tree->node_size_shift);
+		spin_lock(&tree->hash_lock);
+		do {
+			node = __hfsplus_find_bnode(tree, nidx++);
+			if (!node)
+				continue;
+			if (atomic_read(&node->refcnt)) {
+				res = 0;
+				break;
+			}
+			__hfsplus_bnode_remove(node);
+			hfsplus_bnode_free(node);
+		} while (--i);
+		spin_unlock(&tree->hash_lock);
+	}
+	//printk("releasepage: %lu,%x = %d\n", page->index, mask, res);
+	return res;
+}
+
+struct address_space_operations hfsplus_btree_aops = {
+	.readpage	= hfsplus_readpage,
+	.writepage	= hfsplus_writepage,
+	.sync_page	= block_sync_page,
+	.prepare_write	= hfsplus_prepare_write,
+	.commit_write	= generic_commit_write,
+	.bmap		= hfsplus_bmap,
+	.releasepage	= hfsplus_releasepage,
+};
+
+struct address_space_operations hfsplus_aops = {
+	.readpage	= hfsplus_readpage,
+	.writepage	= hfsplus_writepage,
+	.sync_page	= block_sync_page,
+	.prepare_write	= hfsplus_prepare_write,
+	.commit_write	= generic_commit_write,
+	.bmap		= hfsplus_bmap,
+};
+
+static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry)
+{
+	struct hfsplus_find_data fd;
+	struct super_block *sb = dir->i_sb;
+	struct inode *inode = NULL;
+	int err;
+
+	if (HFSPLUS_IS_RSRC(dir) || strcmp(dentry->d_name.name, "rsrc"))
+		goto out;
+
+	inode = HFSPLUS_I(dir).rsrc_inode;
+	if (inode)
+		goto out;
+
+	inode = new_inode(sb);
+	if (!inode)
+		return ERR_PTR(-ENOMEM);
+
+	inode->i_ino = dir->i_ino;
+	HFSPLUS_I(inode).flags = HFSPLUS_FLG_RSRC;
+
+	hfsplus_find_init(HFSPLUS_SB(sb).cat_tree, &fd);
+	err = hfsplus_find_cat(sb, dir->i_ino, &fd);
+	if (!err)
+		err = hfsplus_cat_read_inode(inode, &fd);
+	hfsplus_find_exit(&fd);
+	if (err) {
+		iput(inode);
+		return ERR_PTR(err);
+	}
+	HFSPLUS_I(inode).rsrc_inode = dir;
+	HFSPLUS_I(dir).rsrc_inode = inode;
+	igrab(dir);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	list_add(&inode->i_hash, &HFSPLUS_SB(sb).rsrc_inodes);
+#else
+	hlist_add_head(&inode->i_hash, &HFSPLUS_SB(sb).rsrc_inodes);
+#endif
+	mark_inode_dirty(inode);
+	{
+	void hfsplus_inode_check(struct super_block *sb);
+	atomic_inc(&HFSPLUS_SB(sb).inode_cnt);
+	hfsplus_inode_check(sb);
+	}
+out:
+	d_add(dentry, inode);
+	return NULL;
+}
+
+static void hfsplus_get_perms(struct inode *inode, hfsplus_perm *perms)
+{
+	struct super_block *s = inode->i_sb;
+
+	inode->i_mode = be32_to_cpu(perms->mode);
+	if (!inode->i_mode)
+		inode->i_mode = S_IFREG | (S_IRWXUGO & ~(HFSPLUS_SB(s).umask));
+
+	inode->i_uid = be32_to_cpu(perms->owner);
+	if (!inode->i_uid)
+		inode->i_uid = HFSPLUS_SB(s).uid;
+
+	inode->i_gid = be32_to_cpu(perms->group);
+	if (!inode->i_gid)
+		inode->i_gid = HFSPLUS_SB(s).gid;
+}
+
+static void hfsplus_set_perms(struct inode *inode, hfsplus_perm *perms)
+{
+	perms->mode = cpu_to_be32(inode->i_mode);
+	perms->owner = cpu_to_be32(inode->i_uid);
+	perms->group = cpu_to_be32(inode->i_gid);
+	perms->dev = cpu_to_be32(HFSPLUS_I(inode).dev);
+}
+
+static int hfsplus_file_open(struct inode *inode, struct file *file)
+{
+	if (HFSPLUS_IS_RSRC(inode))
+		inode = HFSPLUS_I(inode).rsrc_inode;
+	if (atomic_read(&file->f_count) != 1)
+		return 0;
+	atomic_inc(&HFSPLUS_I(inode).opencnt);
+	return 0;
+}
+
+static int hfsplus_file_release(struct inode *inode, struct file *file)
+{
+	struct super_block *sb = inode->i_sb;
+
+	if (HFSPLUS_IS_RSRC(inode))
+		inode = HFSPLUS_I(inode).rsrc_inode;
+	if (atomic_read(&file->f_count) != 0)
+		return 0;
+	if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) {
+		down(&inode->i_sem);
+		if (inode->i_flags & S_DEAD) {
+			hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
+			hfsplus_delete_inode(inode);
+		}
+		up(&inode->i_sem);
+	}
+	return 0;
+}
+
+extern struct inode_operations hfsplus_dir_inode_operations;
+extern struct file_operations hfsplus_dir_operations;
+
+struct inode_operations hfsplus_file_inode_operations = {
+	.lookup		= hfsplus_file_lookup,
+	.truncate	= hfsplus_truncate,
+};
+
+struct file_operations hfsplus_file_operations = {
+	.llseek 	= generic_file_llseek,
+	.read		= generic_file_read,
+	//.write	= hfsplus_file_write,
+	.write		= generic_file_write,
+	.mmap		= generic_file_mmap,
+	.fsync		= file_fsync,
+	.open		= hfsplus_file_open,
+	.release	= hfsplus_file_release,
+};
+
+#if 0
+static nlink_t hfsplus_count_subdirs(struct inode *inode)
+{
+	struct hfsplus_find_data fd;
+	hfsplus_cat_entry entry;
+	nlink_t res = 0;
+	u32 cnid;
+
+	hfsplus_find_init(HFSPLUS_SB(inode->i_sb).cat_tree, &fd);
+	hfsplus_fill_cat_key(fd.search_key, inode->i_ino, NULL);
+	res = hfsplus_btree_find(&fd);
+	if (res)
+		goto out;
+	cnid = cpu_to_be32(inode->i_ino);
+	for (;;) {
+		if (fd.key->cat.parent != cnid)
+			break;
+		if (be16_to_cpu(entry.type) == HFSPLUS_FOLDER)
+			res++;
+
+		if (hfsplus_btiter_move(&fd, 1))
+			break;
+	}
+out:
+	hfsplus_find_exit(&fd);
+	return res;
+}
+#endif
+
+struct inode *hfsplus_new_inode(struct super_block *sb, int mode)
+{
+	struct inode *inode = new_inode(sb);
+	if (!inode)
+		return NULL;
+
+	{
+	void hfsplus_inode_check(struct super_block *sb);
+	atomic_inc(&HFSPLUS_SB(sb).inode_cnt);
+	hfsplus_inode_check(sb);
+	}
+	inode->i_ino = HFSPLUS_SB(sb).next_cnid++;
+	inode->i_mode = mode;
+	inode->i_uid = current->fsuid;
+	inode->i_gid = current->fsgid;
+	inode->i_nlink = 1;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	if (S_ISDIR(inode->i_mode)) {
+		inode->i_size = 2;
+		HFSPLUS_SB(sb).folder_count++;
+		inode->i_op = &hfsplus_dir_inode_operations;
+		inode->i_fop = &hfsplus_dir_operations;
+		INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list);
+	} else if (S_ISREG(inode->i_mode)) {
+		HFSPLUS_SB(sb).file_count++;
+		inode->i_op = &hfsplus_file_inode_operations;
+		inode->i_fop = &hfsplus_file_operations;
+		inode->i_mapping->a_ops = &hfsplus_aops;
+	} else if (S_ISLNK(inode->i_mode)) {
+		HFSPLUS_SB(sb).file_count++;
+		inode->i_op = &page_symlink_inode_operations;
+		inode->i_mapping->a_ops = &hfsplus_aops;
+	} else
+		HFSPLUS_SB(sb).file_count++;
+	insert_inode_hash(inode);
+	mark_inode_dirty(inode);
+	sb->s_dirt = 1;
+
+	return inode;
+}
+
+void hfsplus_delete_inode(struct inode *inode)
+{
+	struct super_block *sb = inode->i_sb;
+
+	if (S_ISDIR(inode->i_mode)) {
+		HFSPLUS_SB(sb).folder_count--;
+		sb->s_dirt = 1;
+		return;
+	}
+	HFSPLUS_SB(sb).file_count--;
+	if (S_ISREG(inode->i_mode)) {
+		if (!inode->i_nlink) {
+			inode->i_size = 0;
+			hfsplus_truncate(inode);
+		}
+	} else if (S_ISLNK(inode->i_mode)) {
+		inode->i_size = 0;
+		hfsplus_truncate(inode);
+	}
+	sb->s_dirt = 1;
+}
+
+void hfsplus_inode_read_fork(struct inode *inode, hfsplus_fork_raw *fork)
+{
+	u32 count;
+	int i;
+
+	memcpy(&HFSPLUS_I(inode).extents, &fork->extents,
+	       sizeof(hfsplus_extent_rec));
+	for (count = 0, i = 0; i < 8; i++)
+		count += be32_to_cpu(fork->extents[i].block_count);
+	HFSPLUS_I(inode).extent_blocks = count;
+	HFSPLUS_I(inode).total_blocks = HFSPLUS_I(inode).alloc_blocks =
+		be32_to_cpu(fork->total_blocks);
+	inode->i_size = HFSPLUS_I(inode).mmu_private = be64_to_cpu(fork->total_size);
+	inode->i_blocks = be32_to_cpu(fork->total_blocks);
+}
+
+void hfsplus_inode_write_fork(struct inode *inode, hfsplus_fork_raw *fork)
+{
+	memcpy(&fork->extents, &HFSPLUS_I(inode).extents,
+	       sizeof(hfsplus_extent_rec));
+	fork->total_size = cpu_to_be64(inode->i_size);
+	fork->total_blocks = cpu_to_be32(HFSPLUS_I(inode).alloc_blocks);
+}
+
+int hfsplus_cat_read_inode(struct inode *inode, struct hfsplus_find_data *fd)
+{
+	hfsplus_cat_entry entry;
+	int res = 0;
+	u16 type;
+
+	type = hfsplus_bnode_read_u16(fd->bnode, fd->entryoffset);
+
+	HFSPLUS_I(inode).dev = 0;
+	inode->i_blksize = PAGE_SIZE; /* Doesn't seem to be useful... */
+	if (type == HFSPLUS_FOLDER) {
+		hfsplus_cat_folder *folder = &entry.folder;
+
+		if (fd->entrylength < sizeof(hfsplus_cat_folder))
+			/* panic? */;
+		hfsplus_bnode_readbytes(fd->bnode, &entry, fd->entryoffset,
+					sizeof(hfsplus_cat_folder));
+		memset(&HFSPLUS_I(inode).extents, 0,
+		       sizeof(hfsplus_extent_rec));
+		hfsplus_get_perms(inode, &(folder->permissions));
+		inode->i_mode = S_IFDIR | (inode->i_mode & ~S_IFMT);
+		//inode->i_nlink = 2 + hfsplus_count_subdirs(inode);
+		inode->i_nlink = 1;
+		inode->i_size = 2 + be32_to_cpu(folder->valence);
+		inode->i_atime = hfsp_mt2ut(folder->access_date);
+		inode->i_mtime = hfsp_mt2ut(folder->content_mod_date);
+		inode->i_ctime = inode->i_mtime;
+		inode->i_blocks = 0;
+		inode->i_op = &hfsplus_dir_inode_operations;
+		inode->i_fop = &hfsplus_dir_operations;
+		INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list);
+	} else if (type == HFSPLUS_FILE) {
+		hfsplus_cat_file *file = &entry.file;
+
+		if (fd->entrylength < sizeof(hfsplus_cat_file))
+			/* panic? */;
+		hfsplus_bnode_readbytes(fd->bnode, &entry, fd->entryoffset,
+					sizeof(hfsplus_cat_file));
+
+		hfsplus_inode_read_fork(inode, HFSPLUS_IS_DATA(inode) ?
+					&file->data_fork : &file->rsrc_fork);
+		hfsplus_get_perms(inode, &file->permissions);
+		inode->i_nlink = 1;
+		if (S_ISREG(inode->i_mode)) {
+			if (file->permissions.dev)
+				inode->i_nlink = be32_to_cpu(file->permissions.dev);
+			inode->i_mode = S_IFREG | (inode->i_mode & ~S_IFMT);
+			inode->i_op = &hfsplus_file_inode_operations;
+			inode->i_fop = &hfsplus_file_operations;
+			inode->i_mapping->a_ops = &hfsplus_aops;
+		} else if (S_ISLNK(inode->i_mode)) {
+			inode->i_op = &page_symlink_inode_operations;
+			inode->i_mapping->a_ops = &hfsplus_aops;
+		} else {
+			init_special_inode(inode, inode->i_mode,
+					   be32_to_cpu(file->permissions.dev));
+		}
+		inode->i_atime = hfsp_mt2ut(file->access_date);
+		inode->i_mtime = hfsp_mt2ut(file->content_mod_date);
+		inode->i_ctime = inode->i_mtime;
+	} else {
+		printk("HFS+-fs: bad catalog entry used to create inode\n");
+		res = -EIO;
+	}
+	return res;
+}
+
+void hfsplus_cat_write_inode(struct inode *inode)
+{
+	struct hfsplus_find_data fd;
+	hfsplus_cat_entry entry;
+
+	if (HFSPLUS_IS_RSRC(inode)) {
+		mark_inode_dirty(HFSPLUS_I(inode).rsrc_inode);
+		return;
+	}
+
+	if (!inode->i_nlink)
+		return;
+
+	if (hfsplus_find_init(HFSPLUS_SB(inode->i_sb).cat_tree, &fd))
+		/* panic? */
+		return;
+
+	if (hfsplus_find_cat(inode->i_sb, inode->i_ino, &fd))
+		/* panic? */
+		goto out;
+
+	if (S_ISDIR(inode->i_mode)) {
+		hfsplus_cat_folder *folder = &entry.folder;
+
+		if (fd.entrylength < sizeof(hfsplus_cat_folder))
+			/* panic? */;
+		hfsplus_bnode_readbytes(fd.bnode, &entry, fd.entryoffset,
+					sizeof(hfsplus_cat_folder));
+		/* simple node checks? */
+		hfsplus_set_perms(inode, &folder->permissions);
+		folder->access_date = hfsp_ut2mt(inode->i_atime);
+		folder->content_mod_date = hfsp_ut2mt(inode->i_mtime);
+		folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime);
+		folder->valence = cpu_to_be32(inode->i_size - 2);
+		hfsplus_bnode_writebytes(fd.bnode, &entry, fd.entryoffset,
+					 sizeof(hfsplus_cat_folder));
+	} else {
+		hfsplus_cat_file *file = &entry.file;
+
+		if (fd.entrylength < sizeof(hfsplus_cat_file))
+			/* panic? */;
+		hfsplus_bnode_readbytes(fd.bnode, &entry, fd.entryoffset,
+					sizeof(hfsplus_cat_file));
+		hfsplus_inode_write_fork(inode, &file->data_fork);
+		if (HFSPLUS_I(inode).rsrc_inode)
+			hfsplus_inode_write_fork(HFSPLUS_I(inode).rsrc_inode, &file->rsrc_fork);
+		if (S_ISREG(inode->i_mode))
+			HFSPLUS_I(inode).dev = inode->i_nlink;
+		if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+			HFSPLUS_I(inode).dev = kdev_t_to_nr(inode->i_rdev);
+		hfsplus_set_perms(inode, &file->permissions);
+		file->access_date = hfsp_ut2mt(inode->i_atime);
+		file->content_mod_date = hfsp_ut2mt(inode->i_mtime);
+		file->attribute_mod_date = hfsp_ut2mt(inode->i_ctime);
+		hfsplus_bnode_writebytes(fd.bnode, &entry, fd.entryoffset,
+					 sizeof(hfsplus_cat_file));
+	}
+out:
+	hfsplus_find_exit(&fd);
+}
diff -urN linux-2.4.22-pre2/fs/hfsplus/options.c linux-2.4.22-pre3/fs/hfsplus/options.c
--- linux-2.4.22-pre2/fs/hfsplus/options.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/options.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,139 @@
+/*
+ *  linux/fs/hfsplus/options.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Option parsing
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include "hfsplus_fs.h"
+
+/* Initialize an options object to reasonable defaults */
+void fill_defaults(struct hfsplus_sb_info *opts)
+{
+	if (!opts)
+		return;
+
+	opts->creator = HFSPLUS_DEF_CR_TYPE;
+	opts->type = HFSPLUS_DEF_CR_TYPE;
+	opts->charcase = HFSPLUS_CASE_ASIS;
+	opts->fork = HFSPLUS_FORK_RAW;
+	opts->namemap = HFSPLUS_NAMES_TRIVIAL;
+	opts->umask = current->fs->umask;
+	opts->uid = current->uid;
+	opts->gid = current->gid;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+/* Copy settings from one hfsplus_sb_info object to another */
+void fill_current(struct hfsplus_sb_info *curopts,
+		  struct hfsplus_sb_info *opts)
+{
+	if (!curopts || !opts)
+		return;
+
+	opts->creator = curopts->creator;
+	opts->type = curopts->type;
+	opts->charcase = curopts->charcase;
+	opts->fork = curopts->fork;
+	opts->namemap = curopts->namemap;
+	opts->umask = curopts->umask;
+	opts->uid = curopts->uid;
+	opts->gid = curopts->gid;
+}
+#endif
+
+/* convert a "four byte character" to a 32 bit int with error checks */
+static int fill_fourchar(u32 *result, char *input)
+{
+	u32 out;
+	int i;
+
+	if (!result || !input || !*input || (strlen(input) != 4))
+		return 0;
+
+	for (out = 0, i = 0; i < 4; i++) {
+		out <<= 8;
+		out |= ((int)(input[i])) & 0xFF;
+	}
+	*result = out;
+	return 1;
+}
+
+/* convert a string to int with error checks */
+static int fill_int(int *result, char *input, int base)
+{
+	char *tmp = input;
+	int intval;
+
+	if (!result || !input || !*input)
+		return 0;
+
+	intval = simple_strtoul(tmp, &tmp, base);
+	if (*tmp)
+		return 0;
+
+	*result = intval;
+	return 1;
+}
+
+/* Parse options from mount. Returns 0 on failure */
+/* input is the options passed to mount() as a string */
+int parse_options(char *input, struct hfsplus_sb_info *results)
+{
+	char *curropt, *value;
+	int tmp;
+
+	if (!input)
+		return 1;
+
+	while ((curropt = strsep(&input,",")) != NULL) {
+		if (!*curropt)
+			continue;
+
+		if ((value = strchr(curropt, '=')) != NULL)
+			*value++ = '\0';
+
+		if (!strcmp(curropt, "creator")) {
+			if (!fill_fourchar(&(results->creator), value)) {
+				printk("HFS+-fs: creator requires a value\n");
+				return 0;
+			}
+		} else if (!strcmp(curropt, "type")) {
+			if (!fill_fourchar(&(results->type), value)) {
+				printk("HFS+-fs: type requires a value\n");
+				return 0;
+			}
+		} else if (!strcmp(curropt, "case")) {
+		} else if (!strcmp(curropt, "fork")) {
+		} else if (!strcmp(curropt, "names")) {
+		} else if (!strcmp(curropt, "umask")) {
+			if (!fill_int(&tmp, value, 8)) {
+				printk("HFS+-fs: umask requires a value\n");
+				return 0;
+			}
+			results->umask = (umode_t)tmp;
+		} else if (!strcmp(curropt, "uid")) {
+			if (!fill_int(&tmp, value, 0)) {
+				printk("HFS+-fs: uid requires an argument\n");
+				return 0;
+			}
+			results->uid = (uid_t)tmp;
+		} else if (!strcmp(curropt, "gid")) {
+			if (!fill_int(&tmp, value, 0)) {
+				printk("HFS+-fs: gid requires an argument\n");
+				return 0;
+			}
+			results->gid = (gid_t)tmp;
+		} else {
+			printk("HFS+-fs: unknown option %s\n", curropt);
+			return 0;
+		}
+	}
+
+	return 1;
+}
diff -urN linux-2.4.22-pre2/fs/hfsplus/super.c linux-2.4.22-pre3/fs/hfsplus/super.c
--- linux-2.4.22-pre2/fs/hfsplus/super.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/super.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,474 @@
+/*
+ *  linux/fs/hfsplus/super.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#include <linux/locks.h>
+#else
+#include <linux/buffer_head.h>
+#include <linux/vfs.h>
+
+static struct inode *hfsplus_alloc_inode(struct super_block *sb);
+static void hfsplus_destroy_inode(struct inode *inode);
+#endif
+
+#include "hfsplus_fs.h"
+
+void hfsplus_inode_check(struct super_block *sb)
+{
+#if 0
+	u32 cnt = atomic_read(&HFSPLUS_SB(sb).inode_cnt);
+	u32 last_cnt = HFSPLUS_SB(sb).last_inode_cnt;
+
+	if (cnt <= (last_cnt / 2) ||
+	    cnt >= (last_cnt * 2)) {
+		HFSPLUS_SB(sb).last_inode_cnt = cnt;
+		printk("inode_check: %u,%u,%u\n", cnt, last_cnt,
+			HFSPLUS_SB(sb).cat_tree ? HFSPLUS_SB(sb).cat_tree->node_hash_cnt : 0);
+	}
+#endif
+}
+
+static void hfsplus_read_inode(struct inode *inode)
+{
+	struct hfsplus_find_data fd;
+	struct hfsplus_vh *vhdr;
+	int err;
+
+	atomic_inc(&HFSPLUS_SB(inode->i_sb).inode_cnt);
+	hfsplus_inode_check(inode->i_sb);
+	if (inode->i_ino >= HFSPLUS_FIRSTUSER_CNID) {
+	read_inode:
+		HFSPLUS_I(inode).flags = 0;
+		hfsplus_find_init(HFSPLUS_SB(inode->i_sb).cat_tree, &fd);
+		err = hfsplus_find_cat(inode->i_sb, inode->i_ino, &fd);
+		if (!err)
+			err = hfsplus_cat_read_inode(inode, &fd);
+		hfsplus_find_exit(&fd);
+		if (err)
+			goto bad_inode;
+		return;
+	}
+	vhdr = HFSPLUS_SB(inode->i_sb).s_vhdr;
+	switch(inode->i_ino) {
+	case HFSPLUS_ROOT_CNID:
+		goto read_inode;
+	case HFSPLUS_EXT_CNID:
+		hfsplus_inode_read_fork(inode, &vhdr->ext_file);
+		inode->i_mapping->a_ops = &hfsplus_btree_aops;
+		break;
+	case HFSPLUS_CAT_CNID:
+		hfsplus_inode_read_fork(inode, &vhdr->cat_file);
+		inode->i_mapping->a_ops = &hfsplus_btree_aops;
+		break;
+	case HFSPLUS_ALLOC_CNID:
+		hfsplus_inode_read_fork(inode, &vhdr->alloc_file);
+		break;
+	case HFSPLUS_START_CNID:
+		hfsplus_inode_read_fork(inode, &vhdr->start_file);
+		break;
+	case HFSPLUS_ATTR_CNID:
+		hfsplus_inode_read_fork(inode, &vhdr->attr_file);
+		inode->i_mapping->a_ops = &hfsplus_btree_aops;
+		break;
+	default:
+		goto bad_inode;
+	}
+	
+	return;
+
+ bad_inode:
+	make_bad_inode(inode);
+}
+
+void hfsplus_write_inode(struct inode *inode, int unused)
+{
+	struct hfsplus_vh *vhdr;
+
+	dprint(DBG_INODE, "hfsplus_write_inode: %lu\n", inode->i_ino);
+	if (inode->i_ino >= HFSPLUS_FIRSTUSER_CNID) {
+		hfsplus_cat_write_inode(inode);
+		return;
+	}
+	vhdr = HFSPLUS_SB(inode->i_sb).s_vhdr;
+	switch (inode->i_ino) {
+	case HFSPLUS_ROOT_CNID:
+		hfsplus_cat_write_inode(inode);
+		break;
+	case HFSPLUS_EXT_CNID:
+		if (vhdr->ext_file.total_size != cpu_to_be64(inode->i_size)) {
+			HFSPLUS_SB(inode->i_sb).flags |= HFSPLUS_SB_WRITEBACKUP;
+			inode->i_sb->s_dirt = 1;
+		}
+		hfsplus_inode_write_fork(inode, &vhdr->ext_file);
+		hfsplus_write_btree(HFSPLUS_SB(inode->i_sb).ext_tree);
+		break;
+	case HFSPLUS_CAT_CNID:
+		if (vhdr->cat_file.total_size != cpu_to_be64(inode->i_size)) {
+			HFSPLUS_SB(inode->i_sb).flags |= HFSPLUS_SB_WRITEBACKUP;
+			inode->i_sb->s_dirt = 1;
+		}
+		hfsplus_inode_write_fork(inode, &vhdr->cat_file);
+		hfsplus_write_btree(HFSPLUS_SB(inode->i_sb).cat_tree);
+		break;
+	case HFSPLUS_ALLOC_CNID:
+		if (vhdr->alloc_file.total_size != cpu_to_be64(inode->i_size)) {
+			HFSPLUS_SB(inode->i_sb).flags |= HFSPLUS_SB_WRITEBACKUP;
+			inode->i_sb->s_dirt = 1;
+		}
+		hfsplus_inode_write_fork(inode, &vhdr->alloc_file);
+		break;
+	case HFSPLUS_START_CNID:
+		if (vhdr->start_file.total_size != cpu_to_be64(inode->i_size)) {
+			HFSPLUS_SB(inode->i_sb).flags |= HFSPLUS_SB_WRITEBACKUP;
+			inode->i_sb->s_dirt = 1;
+		}
+		hfsplus_inode_write_fork(inode, &vhdr->start_file);
+		break;
+	case HFSPLUS_ATTR_CNID:
+		if (vhdr->attr_file.total_size != cpu_to_be64(inode->i_size)) {
+			HFSPLUS_SB(inode->i_sb).flags |= HFSPLUS_SB_WRITEBACKUP;
+			inode->i_sb->s_dirt = 1;
+		}
+		hfsplus_inode_write_fork(inode, &vhdr->attr_file);
+		hfsplus_write_btree(HFSPLUS_SB(inode->i_sb).attr_tree);
+		break;
+	}
+}
+
+static void hfsplus_clear_inode(struct inode *inode)
+{
+	atomic_dec(&HFSPLUS_SB(inode->i_sb).inode_cnt);
+	if (HFSPLUS_IS_RSRC(inode)) {
+		HFSPLUS_I(HFSPLUS_I(inode).rsrc_inode).rsrc_inode = NULL;
+		iput(HFSPLUS_I(inode).rsrc_inode);
+	}
+	hfsplus_inode_check(inode->i_sb);
+}
+
+static void hfsplus_write_super(struct super_block *sb)
+{
+	struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
+
+	dprint(DBG_SUPER, "hfsplus_write_super\n");
+	sb->s_dirt = 0;
+	if (sb->s_flags & MS_RDONLY)
+		/* warn? */
+		return;
+
+	vhdr->free_blocks = cpu_to_be32(HFSPLUS_SB(sb).free_blocks);
+	vhdr->next_alloc = cpu_to_be32(HFSPLUS_SB(sb).next_alloc);
+	vhdr->next_cnid = cpu_to_be32(HFSPLUS_SB(sb).next_cnid);
+	vhdr->folder_count = cpu_to_be32(HFSPLUS_SB(sb).folder_count);
+	vhdr->file_count = cpu_to_be32(HFSPLUS_SB(sb).file_count);
+
+	mark_buffer_dirty(HFSPLUS_SB(sb).s_vhbh);
+	if (HFSPLUS_SB(sb).flags & HFSPLUS_SB_WRITEBACKUP) {
+		if (HFSPLUS_SB(sb).sect_count) {
+			struct buffer_head *bh;
+			u32 block, offset;
+
+			block = HFSPLUS_SB(sb).blockoffset;
+			block += (HFSPLUS_SB(sb).sect_count - 2) >> (sb->s_blocksize_bits - 9);
+			offset = ((HFSPLUS_SB(sb).sect_count - 2) << 9) & (sb->s_blocksize - 1);
+			//printk("backup: %u,%u,%u,%u\n", HFSPLUS_SB(sb).blockoffset,
+			//	HFSPLUS_SB(sb).sect_count, block, offset);
+			bh = sb_bread(sb, block);
+			vhdr = (struct hfsplus_vh *)(bh->b_data + offset);
+			if (be16_to_cpu(vhdr->signature) == HFSPLUS_VOLHEAD_SIG) {
+				memcpy(vhdr, HFSPLUS_SB(sb).s_vhdr, sizeof(*vhdr));
+				mark_buffer_dirty(bh);
+				brelse(bh);
+			} else
+				printk("backup not found!\n");
+		}
+		HFSPLUS_SB(sb).flags &= ~HFSPLUS_SB_WRITEBACKUP;
+	}
+}
+
+static void hfsplus_put_super(struct super_block *sb)
+{
+	dprint(DBG_SUPER, "hfsplus_put_super\n");
+	if (!(sb->s_flags & MS_RDONLY)) {
+		struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
+
+		vhdr->modify_date = hfsp_now2mt();
+		vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_UNMNT);
+		vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_INCNSTNT);
+		mark_buffer_dirty(HFSPLUS_SB(sb).s_vhbh);
+		ll_rw_block(WRITE, 1, &HFSPLUS_SB(sb).s_vhbh);
+		wait_on_buffer(HFSPLUS_SB(sb).s_vhbh);
+	}
+
+	hfsplus_close_btree(HFSPLUS_SB(sb).cat_tree);
+	hfsplus_close_btree(HFSPLUS_SB(sb).ext_tree);
+	iput(HFSPLUS_SB(sb).alloc_file);
+	iput(HFSPLUS_SB(sb).hidden_dir);
+	brelse(HFSPLUS_SB(sb).s_vhbh);
+}
+
+static int hfsplus_statfs(struct super_block *sb, struct statfs *buf)
+{
+	buf->f_type = HFSPLUS_SUPER_MAGIC;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_blocks = be32_to_cpu(HFSPLUS_SB(sb).s_vhdr->total_blocks);
+	buf->f_bfree = HFSPLUS_SB(sb).free_blocks;
+	buf->f_bavail = buf->f_bfree;
+	buf->f_files = 0xFFFFFFFF;
+	buf->f_ffree = 0xFFFFFFFF - HFSPLUS_SB(sb).next_cnid;
+	buf->f_namelen = HFSPLUS_MAX_STRLEN;
+
+	return 0;
+}
+
+static struct super_operations hfsplus_sops = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	.alloc_inode	= hfsplus_alloc_inode,
+	.destroy_inode	= hfsplus_destroy_inode,
+#endif
+	.read_inode	= hfsplus_read_inode,
+	.write_inode	= hfsplus_write_inode,
+	.clear_inode	= hfsplus_clear_inode,
+	.put_super	= hfsplus_put_super,
+	.write_super	= hfsplus_write_super,
+	.statfs		= hfsplus_statfs,
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+struct super_block *hfsplus_read_super(struct super_block *sb, void *data,
+				       int silent)
+#else
+static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
+#endif
+{
+	struct hfsplus_vh *vhdr;
+	struct hfsplus_sb_info *sbi;
+	hfsplus_cat_entry entry;
+	struct hfsplus_find_data fd;
+	struct qstr str;
+	int err = -EINVAL;
+
+	sbi = kmalloc(sizeof(struct hfsplus_sb_info), GFP_KERNEL);
+	if (!sbi) {
+		err = -ENOMEM;
+		goto out2;
+	}
+	memset(sbi, 0, sizeof(HFSPLUS_SB(sb)));
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	INIT_LIST_HEAD(&HFSPLUS_SB(sb).rsrc_inodes);
+#else
+	sb->s_fs_info = sbi;
+	INIT_HLIST_HEAD(&sbi->rsrc_inodes);
+#endif
+	fill_defaults(sbi);
+	if (!parse_options(data, sbi)) {
+		if (!silent)
+			printk("HFS+-fs: unable to parse mount options\n");
+		err = -EINVAL;
+		goto out2;
+	}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	fill_current(sbi, &HFSPLUS_SB(sb));
+	kfree(sbi);
+#endif
+
+	/* Grab the volume header */
+	if (hfsplus_read_wrapper(sb)) {
+		if (!silent)
+			printk("HFS+-fs: unable to find HFS+ superblock\n");
+		err = -EINVAL;
+		goto out2;
+	}
+	vhdr = HFSPLUS_SB(sb).s_vhdr;
+
+	/* Copy parts of the volume header into the superblock */
+	sb->s_magic = be16_to_cpu(vhdr->signature);
+	if (be16_to_cpu(vhdr->version) != HFSPLUS_CURRENT_VERSION) {
+		if (!silent)
+			printk("HFS+-fs: wrong filesystem version\n");
+		goto cleanup;
+	}
+	HFSPLUS_SB(sb).total_blocks = be32_to_cpu(vhdr->total_blocks);
+	HFSPLUS_SB(sb).free_blocks = be32_to_cpu(vhdr->free_blocks);
+	HFSPLUS_SB(sb).next_alloc = be32_to_cpu(vhdr->next_alloc);
+	HFSPLUS_SB(sb).next_cnid = be32_to_cpu(vhdr->next_cnid);
+	HFSPLUS_SB(sb).file_count = be32_to_cpu(vhdr->file_count);
+	HFSPLUS_SB(sb).folder_count = be32_to_cpu(vhdr->folder_count);
+
+	/* Set up operations so we can load metadata */
+	sb->s_op = &hfsplus_sops;
+
+	/* Load metadata objects (B*Trees) */
+	HFSPLUS_SB(sb).ext_tree = hfsplus_open_btree(sb, HFSPLUS_EXT_CNID);
+	if (!HFSPLUS_SB(sb).ext_tree) {
+		if (!silent)
+			printk("HFS+-fs: failed to load extents file\n");
+		goto cleanup;
+	}
+	HFSPLUS_SB(sb).cat_tree = hfsplus_open_btree(sb, HFSPLUS_CAT_CNID);
+	if (!HFSPLUS_SB(sb).cat_tree) {
+		if (!silent)
+			printk("HFS+-fs: failed to load catalog file\n");
+		goto cleanup;
+	}
+
+	HFSPLUS_SB(sb).alloc_file = iget(sb, HFSPLUS_ALLOC_CNID);
+	if (!HFSPLUS_SB(sb).alloc_file) {
+		if (!silent)
+			printk("HFS+-fs: failed to load allocation file\n");
+		goto cleanup;
+	}
+
+	/* Load the root directory */
+	sb->s_root = d_alloc_root(iget(sb, HFSPLUS_ROOT_CNID));
+	if (!sb->s_root) {
+		if (!silent)
+			printk("HFS+-fs: failed to load root directory\n");
+		goto cleanup;
+	}
+
+	str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1;
+	str.name = HFSP_HIDDENDIR_NAME;
+	hfsplus_find_init(HFSPLUS_SB(sb).cat_tree, &fd);
+	hfsplus_fill_cat_key(fd.search_key, HFSPLUS_ROOT_CNID, &str);
+	if (!hfsplus_btree_find_entry(&fd, &entry, sizeof(entry))) {
+		hfsplus_find_exit(&fd);
+		if (entry.type != cpu_to_be16(HFSPLUS_FOLDER))
+			goto cleanup;
+		HFSPLUS_SB(sb).hidden_dir = iget(sb, be32_to_cpu(entry.folder.id));
+		if (!HFSPLUS_SB(sb).hidden_dir)
+			goto cleanup;
+	} else
+		hfsplus_find_exit(&fd);
+
+	if (sb->s_flags & MS_RDONLY)
+		goto out;
+
+	//vhdr->last_mount_vers = cpu_to_be32('LNX0');
+	vhdr->modify_date = hfsp_now2mt();
+	vhdr->write_count = cpu_to_be32(be32_to_cpu(vhdr->write_count) + 1);
+	vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT);
+	vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT);
+	mark_buffer_dirty(HFSPLUS_SB(sb).s_vhbh);
+	ll_rw_block(WRITE, 1, &HFSPLUS_SB(sb).s_vhbh);
+	wait_on_buffer(HFSPLUS_SB(sb).s_vhbh);
+
+	if (!HFSPLUS_SB(sb).hidden_dir) {
+		printk("HFS+: create hidden dir...\n");
+		HFSPLUS_SB(sb).hidden_dir = hfsplus_new_inode(sb, S_IFDIR);
+		hfsplus_create_cat(HFSPLUS_SB(sb).hidden_dir->i_ino, sb->s_root->d_inode,
+				   &str, HFSPLUS_SB(sb).hidden_dir);
+		mark_inode_dirty(HFSPLUS_SB(sb).hidden_dir);
+	}
+out:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	return sb;
+#else
+	return 0;
+#endif
+
+cleanup:
+	hfsplus_put_super(sb);
+out2:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	return NULL;
+#else
+	return err;
+#endif
+}
+
+MODULE_AUTHOR("Brad Boyer");
+MODULE_DESCRIPTION("Extended Macintosh Filesystem");
+MODULE_LICENSE("GPL");
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+
+static DECLARE_FSTYPE_DEV(hfsplus_fs_type, "hfsplus", hfsplus_read_super);
+
+static int __init init_hfsplus_fs(void)
+{
+	return register_filesystem(&hfsplus_fs_type);
+}
+
+static void __exit exit_hfsplus_fs(void)
+{
+	unregister_filesystem(&hfsplus_fs_type);
+}
+
+EXPORT_NO_SYMBOLS;
+
+#else
+
+static kmem_cache_t * hfsplus_inode_cachep;
+
+static void init_once(void *p, kmem_cache_t *cachep, unsigned long flags)
+{
+	struct hfsplus_inode_info *i = (struct hfsplus_inode_info *)p;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) {
+		inode_init_once(&i->vfs_inode);
+	}
+}
+
+static struct inode *hfsplus_alloc_inode(struct super_block *sb)
+{
+	struct hfsplus_inode_info *i;
+	i = (struct hfsplus_inode_info *)kmem_cache_alloc(hfsplus_inode_cachep, SLAB_KERNEL);
+	return i ? &i->vfs_inode : NULL;
+}
+
+static void hfsplus_destroy_inode(struct inode *inode)
+{
+	kmem_cache_free(hfsplus_inode_cachep, &HFSPLUS_I(inode));
+}
+
+static struct super_block *hfsplus_get_sb(struct file_system_type *fs_type,
+					  int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, hfsplus_fill_super);
+}
+
+static struct file_system_type hfsplus_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "hfsplus",
+	.get_sb		= hfsplus_get_sb,
+	.kill_sb	= kill_block_super,
+	.fs_flags	= FS_REQUIRES_DEV,
+};
+
+static int __init init_hfsplus_fs(void)
+{
+	int err;
+
+	hfsplus_inode_cachep = kmem_cache_create("hfsplus_inode_cache",
+		sizeof(struct hfsplus_inode_info), 0, SLAB_HWCACHE_ALIGN,
+		init_once, NULL);
+	if (!hfsplus_inode_cachep)
+		return -ENOMEM;
+	err = register_filesystem(&hfsplus_fs_type);
+	if (err)
+		kmem_cache_destroy(hfsplus_inode_cachep);
+	return err;
+}
+
+static void __exit exit_hfsplus_fs(void)
+{
+	unregister_filesystem(&hfsplus_fs_type);
+	if (kmem_cache_destroy(hfsplus_inode_cachep))
+		printk(KERN_INFO "hfsplus_inode_cache: not all structures were freed\n");
+}
+#endif
+
+module_init(init_hfsplus_fs)
+module_exit(exit_hfsplus_fs)
diff -urN linux-2.4.22-pre2/fs/hfsplus/tables.c linux-2.4.22-pre3/fs/hfsplus/tables.c
--- linux-2.4.22-pre2/fs/hfsplus/tables.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/tables.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,408 @@
+/*
+ * linux/fs/hfsplus/tables.c
+ *
+ * Various data tables
+ */
+
+#include "hfsplus_fs.h"
+
+/*
+ *  Unicode case folding table taken from Apple Technote #1150
+ *  (HFS Plus Volume Format)
+ */
+
+u16 case_fold_table[] = {
+/*
+ *  The lower case table consists of a 256-entry high-byte table followed by
+ *  some number of 256-entry subtables. The high-byte table contains either an
+ *  offset to the subtable for characters with that high byte or zero, which
+ *  means that there are no case mappings or ignored characters in that block.
+ *  Ignored characters are mapped to zero.
+ */
+
+    // High-byte indices ( == 0 iff no case mapping and no ignorables )
+
+
+    /* 0 */ 0x0100, 0x0200, 0x0000, 0x0300, 0x0400, 0x0500, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* 1 */ 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* 2 */ 0x0700, 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* 3 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* 4 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* 5 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* 6 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* 7 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* 8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* 9 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* A */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* B */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* C */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* D */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* E */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* F */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0900, 0x0A00,
+
+    // Table 1 (for high byte 0x00)
+
+    /* 0 */ 0xFFFF, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+            0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    /* 1 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+            0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    /* 2 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+            0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    /* 3 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+            0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    /* 4 */ 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+            0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    /* 5 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+            0x0078, 0x0079, 0x007A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    /* 6 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+            0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    /* 7 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+            0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    /* 8 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+            0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+    /* 9 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+            0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+    /* A */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+            0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+    /* B */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+            0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+    /* C */ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00E6, 0x00C7,
+            0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+    /* D */ 0x00F0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+            0x00F8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00FE, 0x00DF,
+    /* E */ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+            0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+    /* F */ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+            0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
+
+    // Table 2 (for high byte 0x01)
+
+    /* 0 */ 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
+            0x0108, 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, 0x010F,
+    /* 1 */ 0x0111, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117,
+            0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F,
+    /* 2 */ 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0127, 0x0127,
+            0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F,
+    /* 3 */ 0x0130, 0x0131, 0x0133, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
+            0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x0140,
+    /* 4 */ 0x0140, 0x0142, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147,
+            0x0148, 0x0149, 0x014B, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F,
+    /* 5 */ 0x0150, 0x0151, 0x0153, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157,
+            0x0158, 0x0159, 0x015A, 0x015B, 0x015C, 0x015D, 0x015E, 0x015F,
+    /* 6 */ 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x0167, 0x0167,
+            0x0168, 0x0169, 0x016A, 0x016B, 0x016C, 0x016D, 0x016E, 0x016F,
+    /* 7 */ 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176, 0x0177,
+            0x0178, 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x017F,
+    /* 8 */ 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188,
+            0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
+    /* 9 */ 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268,
+            0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
+    /* A */ 0x01A0, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x01A6, 0x01A8,
+            0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01AF,
+    /* B */ 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292,
+            0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
+    /* C */ 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9,
+            0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC, 0x01CD, 0x01CE, 0x01CF,
+    /* D */ 0x01D0, 0x01D1, 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01D7,
+            0x01D8, 0x01D9, 0x01DA, 0x01DB, 0x01DC, 0x01DD, 0x01DE, 0x01DF,
+    /* E */ 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E5, 0x01E5, 0x01E6, 0x01E7,
+            0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x01EC, 0x01ED, 0x01EE, 0x01EF,
+    /* F */ 0x01F0, 0x01F3, 0x01F3, 0x01F3, 0x01F4, 0x01F5, 0x01F6, 0x01F7,
+            0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF,
+
+    // Table 3 (for high byte 0x03)
+
+    /* 0 */ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307,
+            0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x030E, 0x030F,
+    /* 1 */ 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,
+            0x0318, 0x0319, 0x031A, 0x031B, 0x031C, 0x031D, 0x031E, 0x031F,
+    /* 2 */ 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327,
+            0x0328, 0x0329, 0x032A, 0x032B, 0x032C, 0x032D, 0x032E, 0x032F,
+    /* 3 */ 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337,
+            0x0338, 0x0339, 0x033A, 0x033B, 0x033C, 0x033D, 0x033E, 0x033F,
+    /* 4 */ 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347,
+            0x0348, 0x0349, 0x034A, 0x034B, 0x034C, 0x034D, 0x034E, 0x034F,
+    /* 5 */ 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357,
+            0x0358, 0x0359, 0x035A, 0x035B, 0x035C, 0x035D, 0x035E, 0x035F,
+    /* 6 */ 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
+            0x0368, 0x0369, 0x036A, 0x036B, 0x036C, 0x036D, 0x036E, 0x036F,
+    /* 7 */ 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377,
+            0x0378, 0x0379, 0x037A, 0x037B, 0x037C, 0x037D, 0x037E, 0x037F,
+    /* 8 */ 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, 0x0387,
+            0x0388, 0x0389, 0x038A, 0x038B, 0x038C, 0x038D, 0x038E, 0x038F,
+    /* 9 */ 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+            0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+    /* A */ 0x03C0, 0x03C1, 0x03A2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+            0x03C8, 0x03C9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+    /* B */ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+            0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+    /* C */ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+            0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x03CF,
+    /* D */ 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
+            0x03D8, 0x03D9, 0x03DA, 0x03DB, 0x03DC, 0x03DD, 0x03DE, 0x03DF,
+    /* E */ 0x03E0, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7,
+            0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
+    /* F */ 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03F4, 0x03F5, 0x03F6, 0x03F7,
+            0x03F8, 0x03F9, 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF,
+
+    // Table 4 (for high byte 0x04)
+
+    /* 0 */ 0x0400, 0x0401, 0x0452, 0x0403, 0x0454, 0x0455, 0x0456, 0x0407,
+            0x0458, 0x0459, 0x045A, 0x045B, 0x040C, 0x040D, 0x040E, 0x045F,
+    /* 1 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+            0x0438, 0x0419, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+    /* 2 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+            0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+    /* 3 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+            0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+    /* 4 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+            0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+    /* 5 */ 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
+            0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F,
+    /* 6 */ 0x0461, 0x0461, 0x0463, 0x0463, 0x0465, 0x0465, 0x0467, 0x0467,
+            0x0469, 0x0469, 0x046B, 0x046B, 0x046D, 0x046D, 0x046F, 0x046F,
+    /* 7 */ 0x0471, 0x0471, 0x0473, 0x0473, 0x0475, 0x0475, 0x0476, 0x0477,
+            0x0479, 0x0479, 0x047B, 0x047B, 0x047D, 0x047D, 0x047F, 0x047F,
+    /* 8 */ 0x0481, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487,
+            0x0488, 0x0489, 0x048A, 0x048B, 0x048C, 0x048D, 0x048E, 0x048F,
+    /* 9 */ 0x0491, 0x0491, 0x0493, 0x0493, 0x0495, 0x0495, 0x0497, 0x0497,
+            0x0499, 0x0499, 0x049B, 0x049B, 0x049D, 0x049D, 0x049F, 0x049F,
+    /* A */ 0x04A1, 0x04A1, 0x04A3, 0x04A3, 0x04A5, 0x04A5, 0x04A7, 0x04A7,
+            0x04A9, 0x04A9, 0x04AB, 0x04AB, 0x04AD, 0x04AD, 0x04AF, 0x04AF,
+    /* B */ 0x04B1, 0x04B1, 0x04B3, 0x04B3, 0x04B5, 0x04B5, 0x04B7, 0x04B7,
+            0x04B9, 0x04B9, 0x04BB, 0x04BB, 0x04BD, 0x04BD, 0x04BF, 0x04BF,
+    /* C */ 0x04C0, 0x04C1, 0x04C2, 0x04C4, 0x04C4, 0x04C5, 0x04C6, 0x04C8,
+            0x04C8, 0x04C9, 0x04CA, 0x04CC, 0x04CC, 0x04CD, 0x04CE, 0x04CF,
+    /* D */ 0x04D0, 0x04D1, 0x04D2, 0x04D3, 0x04D4, 0x04D5, 0x04D6, 0x04D7,
+            0x04D8, 0x04D9, 0x04DA, 0x04DB, 0x04DC, 0x04DD, 0x04DE, 0x04DF,
+    /* E */ 0x04E0, 0x04E1, 0x04E2, 0x04E3, 0x04E4, 0x04E5, 0x04E6, 0x04E7,
+            0x04E8, 0x04E9, 0x04EA, 0x04EB, 0x04EC, 0x04ED, 0x04EE, 0x04EF,
+    /* F */ 0x04F0, 0x04F1, 0x04F2, 0x04F3, 0x04F4, 0x04F5, 0x04F6, 0x04F7,
+            0x04F8, 0x04F9, 0x04FA, 0x04FB, 0x04FC, 0x04FD, 0x04FE, 0x04FF,
+
+    // Table 5 (for high byte 0x05)
+
+    /* 0 */ 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507,
+            0x0508, 0x0509, 0x050A, 0x050B, 0x050C, 0x050D, 0x050E, 0x050F,
+    /* 1 */ 0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517,
+            0x0518, 0x0519, 0x051A, 0x051B, 0x051C, 0x051D, 0x051E, 0x051F,
+    /* 2 */ 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527,
+            0x0528, 0x0529, 0x052A, 0x052B, 0x052C, 0x052D, 0x052E, 0x052F,
+    /* 3 */ 0x0530, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
+            0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
+    /* 4 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
+            0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
+    /* 5 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0557,
+            0x0558, 0x0559, 0x055A, 0x055B, 0x055C, 0x055D, 0x055E, 0x055F,
+    /* 6 */ 0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
+            0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
+    /* 7 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
+            0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
+    /* 8 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587,
+            0x0588, 0x0589, 0x058A, 0x058B, 0x058C, 0x058D, 0x058E, 0x058F,
+    /* 9 */ 0x0590, 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597,
+            0x0598, 0x0599, 0x059A, 0x059B, 0x059C, 0x059D, 0x059E, 0x059F,
+    /* A */ 0x05A0, 0x05A1, 0x05A2, 0x05A3, 0x05A4, 0x05A5, 0x05A6, 0x05A7,
+            0x05A8, 0x05A9, 0x05AA, 0x05AB, 0x05AC, 0x05AD, 0x05AE, 0x05AF,
+    /* B */ 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
+            0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
+    /* C */ 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05C4, 0x05C5, 0x05C6, 0x05C7,
+            0x05C8, 0x05C9, 0x05CA, 0x05CB, 0x05CC, 0x05CD, 0x05CE, 0x05CF,
+    /* D */ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+            0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+    /* E */ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+            0x05E8, 0x05E9, 0x05EA, 0x05EB, 0x05EC, 0x05ED, 0x05EE, 0x05EF,
+    /* F */ 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x05F5, 0x05F6, 0x05F7,
+            0x05F8, 0x05F9, 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF,
+
+    // Table 6 (for high byte 0x10)
+
+    /* 0 */ 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
+            0x1008, 0x1009, 0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
+    /* 1 */ 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
+            0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
+    /* 2 */ 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
+            0x1028, 0x1029, 0x102A, 0x102B, 0x102C, 0x102D, 0x102E, 0x102F,
+    /* 3 */ 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037,
+            0x1038, 0x1039, 0x103A, 0x103B, 0x103C, 0x103D, 0x103E, 0x103F,
+    /* 4 */ 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047,
+            0x1048, 0x1049, 0x104A, 0x104B, 0x104C, 0x104D, 0x104E, 0x104F,
+    /* 5 */ 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057,
+            0x1058, 0x1059, 0x105A, 0x105B, 0x105C, 0x105D, 0x105E, 0x105F,
+    /* 6 */ 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067,
+            0x1068, 0x1069, 0x106A, 0x106B, 0x106C, 0x106D, 0x106E, 0x106F,
+    /* 7 */ 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077,
+            0x1078, 0x1079, 0x107A, 0x107B, 0x107C, 0x107D, 0x107E, 0x107F,
+    /* 8 */ 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087,
+            0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x108F,
+    /* 9 */ 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097,
+            0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x109F,
+    /* A */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7,
+            0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
+    /* B */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7,
+            0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
+    /* C */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10C6, 0x10C7,
+            0x10C8, 0x10C9, 0x10CA, 0x10CB, 0x10CC, 0x10CD, 0x10CE, 0x10CF,
+    /* D */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7,
+            0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
+    /* E */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7,
+            0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
+    /* F */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10F6, 0x10F7,
+            0x10F8, 0x10F9, 0x10FA, 0x10FB, 0x10FC, 0x10FD, 0x10FE, 0x10FF,
+
+    // Table 7 (for high byte 0x20)
+
+    /* 0 */ 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
+            0x2008, 0x2009, 0x200A, 0x200B, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* 1 */ 0x2010, 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017,
+            0x2018, 0x2019, 0x201A, 0x201B, 0x201C, 0x201D, 0x201E, 0x201F,
+    /* 2 */ 0x2020, 0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027,
+            0x2028, 0x2029, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x202F,
+    /* 3 */ 0x2030, 0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037,
+            0x2038, 0x2039, 0x203A, 0x203B, 0x203C, 0x203D, 0x203E, 0x203F,
+    /* 4 */ 0x2040, 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047,
+            0x2048, 0x2049, 0x204A, 0x204B, 0x204C, 0x204D, 0x204E, 0x204F,
+    /* 5 */ 0x2050, 0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057,
+            0x2058, 0x2059, 0x205A, 0x205B, 0x205C, 0x205D, 0x205E, 0x205F,
+    /* 6 */ 0x2060, 0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067,
+            0x2068, 0x2069, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    /* 7 */ 0x2070, 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077,
+            0x2078, 0x2079, 0x207A, 0x207B, 0x207C, 0x207D, 0x207E, 0x207F,
+    /* 8 */ 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087,
+            0x2088, 0x2089, 0x208A, 0x208B, 0x208C, 0x208D, 0x208E, 0x208F,
+    /* 9 */ 0x2090, 0x2091, 0x2092, 0x2093, 0x2094, 0x2095, 0x2096, 0x2097,
+            0x2098, 0x2099, 0x209A, 0x209B, 0x209C, 0x209D, 0x209E, 0x209F,
+    /* A */ 0x20A0, 0x20A1, 0x20A2, 0x20A3, 0x20A4, 0x20A5, 0x20A6, 0x20A7,
+            0x20A8, 0x20A9, 0x20AA, 0x20AB, 0x20AC, 0x20AD, 0x20AE, 0x20AF,
+    /* B */ 0x20B0, 0x20B1, 0x20B2, 0x20B3, 0x20B4, 0x20B5, 0x20B6, 0x20B7,
+            0x20B8, 0x20B9, 0x20BA, 0x20BB, 0x20BC, 0x20BD, 0x20BE, 0x20BF,
+    /* C */ 0x20C0, 0x20C1, 0x20C2, 0x20C3, 0x20C4, 0x20C5, 0x20C6, 0x20C7,
+            0x20C8, 0x20C9, 0x20CA, 0x20CB, 0x20CC, 0x20CD, 0x20CE, 0x20CF,
+    /* D */ 0x20D0, 0x20D1, 0x20D2, 0x20D3, 0x20D4, 0x20D5, 0x20D6, 0x20D7,
+            0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC, 0x20DD, 0x20DE, 0x20DF,
+    /* E */ 0x20E0, 0x20E1, 0x20E2, 0x20E3, 0x20E4, 0x20E5, 0x20E6, 0x20E7,
+            0x20E8, 0x20E9, 0x20EA, 0x20EB, 0x20EC, 0x20ED, 0x20EE, 0x20EF,
+    /* F */ 0x20F0, 0x20F1, 0x20F2, 0x20F3, 0x20F4, 0x20F5, 0x20F6, 0x20F7,
+            0x20F8, 0x20F9, 0x20FA, 0x20FB, 0x20FC, 0x20FD, 0x20FE, 0x20FF,
+
+    // Table 8 (for high byte 0x21)
+
+    /* 0 */ 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, 0x2106, 0x2107,
+            0x2108, 0x2109, 0x210A, 0x210B, 0x210C, 0x210D, 0x210E, 0x210F,
+    /* 1 */ 0x2110, 0x2111, 0x2112, 0x2113, 0x2114, 0x2115, 0x2116, 0x2117,
+            0x2118, 0x2119, 0x211A, 0x211B, 0x211C, 0x211D, 0x211E, 0x211F,
+    /* 2 */ 0x2120, 0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x2126, 0x2127,
+            0x2128, 0x2129, 0x212A, 0x212B, 0x212C, 0x212D, 0x212E, 0x212F,
+    /* 3 */ 0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137,
+            0x2138, 0x2139, 0x213A, 0x213B, 0x213C, 0x213D, 0x213E, 0x213F,
+    /* 4 */ 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, 0x2146, 0x2147,
+            0x2148, 0x2149, 0x214A, 0x214B, 0x214C, 0x214D, 0x214E, 0x214F,
+    /* 5 */ 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157,
+            0x2158, 0x2159, 0x215A, 0x215B, 0x215C, 0x215D, 0x215E, 0x215F,
+    /* 6 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
+            0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F,
+    /* 7 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
+            0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F,
+    /* 8 */ 0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185, 0x2186, 0x2187,
+            0x2188, 0x2189, 0x218A, 0x218B, 0x218C, 0x218D, 0x218E, 0x218F,
+    /* 9 */ 0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197,
+            0x2198, 0x2199, 0x219A, 0x219B, 0x219C, 0x219D, 0x219E, 0x219F,
+    /* A */ 0x21A0, 0x21A1, 0x21A2, 0x21A3, 0x21A4, 0x21A5, 0x21A6, 0x21A7,
+            0x21A8, 0x21A9, 0x21AA, 0x21AB, 0x21AC, 0x21AD, 0x21AE, 0x21AF,
+    /* B */ 0x21B0, 0x21B1, 0x21B2, 0x21B3, 0x21B4, 0x21B5, 0x21B6, 0x21B7,
+            0x21B8, 0x21B9, 0x21BA, 0x21BB, 0x21BC, 0x21BD, 0x21BE, 0x21BF,
+    /* C */ 0x21C0, 0x21C1, 0x21C2, 0x21C3, 0x21C4, 0x21C5, 0x21C6, 0x21C7,
+            0x21C8, 0x21C9, 0x21CA, 0x21CB, 0x21CC, 0x21CD, 0x21CE, 0x21CF,
+    /* D */ 0x21D0, 0x21D1, 0x21D2, 0x21D3, 0x21D4, 0x21D5, 0x21D6, 0x21D7,
+            0x21D8, 0x21D9, 0x21DA, 0x21DB, 0x21DC, 0x21DD, 0x21DE, 0x21DF,
+    /* E */ 0x21E0, 0x21E1, 0x21E2, 0x21E3, 0x21E4, 0x21E5, 0x21E6, 0x21E7,
+            0x21E8, 0x21E9, 0x21EA, 0x21EB, 0x21EC, 0x21ED, 0x21EE, 0x21EF,
+    /* F */ 0x21F0, 0x21F1, 0x21F2, 0x21F3, 0x21F4, 0x21F5, 0x21F6, 0x21F7,
+            0x21F8, 0x21F9, 0x21FA, 0x21FB, 0x21FC, 0x21FD, 0x21FE, 0x21FF,
+
+    // Table 9 (for high byte 0xFE)
+
+    /* 0 */ 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07,
+            0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 0xFE0F,
+    /* 1 */ 0xFE10, 0xFE11, 0xFE12, 0xFE13, 0xFE14, 0xFE15, 0xFE16, 0xFE17,
+            0xFE18, 0xFE19, 0xFE1A, 0xFE1B, 0xFE1C, 0xFE1D, 0xFE1E, 0xFE1F,
+    /* 2 */ 0xFE20, 0xFE21, 0xFE22, 0xFE23, 0xFE24, 0xFE25, 0xFE26, 0xFE27,
+            0xFE28, 0xFE29, 0xFE2A, 0xFE2B, 0xFE2C, 0xFE2D, 0xFE2E, 0xFE2F,
+    /* 3 */ 0xFE30, 0xFE31, 0xFE32, 0xFE33, 0xFE34, 0xFE35, 0xFE36, 0xFE37,
+            0xFE38, 0xFE39, 0xFE3A, 0xFE3B, 0xFE3C, 0xFE3D, 0xFE3E, 0xFE3F,
+    /* 4 */ 0xFE40, 0xFE41, 0xFE42, 0xFE43, 0xFE44, 0xFE45, 0xFE46, 0xFE47,
+            0xFE48, 0xFE49, 0xFE4A, 0xFE4B, 0xFE4C, 0xFE4D, 0xFE4E, 0xFE4F,
+    /* 5 */ 0xFE50, 0xFE51, 0xFE52, 0xFE53, 0xFE54, 0xFE55, 0xFE56, 0xFE57,
+            0xFE58, 0xFE59, 0xFE5A, 0xFE5B, 0xFE5C, 0xFE5D, 0xFE5E, 0xFE5F,
+    /* 6 */ 0xFE60, 0xFE61, 0xFE62, 0xFE63, 0xFE64, 0xFE65, 0xFE66, 0xFE67,
+            0xFE68, 0xFE69, 0xFE6A, 0xFE6B, 0xFE6C, 0xFE6D, 0xFE6E, 0xFE6F,
+    /* 7 */ 0xFE70, 0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE75, 0xFE76, 0xFE77,
+            0xFE78, 0xFE79, 0xFE7A, 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F,
+    /* 8 */ 0xFE80, 0xFE81, 0xFE82, 0xFE83, 0xFE84, 0xFE85, 0xFE86, 0xFE87,
+            0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, 0xFE8D, 0xFE8E, 0xFE8F,
+    /* 9 */ 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95, 0xFE96, 0xFE97,
+            0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E, 0xFE9F,
+    /* A */ 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7,
+            0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF,
+    /* B */ 0xFEB0, 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7,
+            0xFEB8, 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF,
+    /* C */ 0xFEC0, 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7,
+            0xFEC8, 0xFEC9, 0xFECA, 0xFECB, 0xFECC, 0xFECD, 0xFECE, 0xFECF,
+    /* D */ 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4, 0xFED5, 0xFED6, 0xFED7,
+            0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD, 0xFEDE, 0xFEDF,
+    /* E */ 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6, 0xFEE7,
+            0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF,
+    /* F */ 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7,
+            0xFEF8, 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0xFEFD, 0xFEFE, 0x0000,
+
+    // Table 10 (for high byte 0xFF)
+
+    /* 0 */ 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, 0xFF06, 0xFF07,
+            0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F,
+    /* 1 */ 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17,
+            0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F,
+    /* 2 */ 0xFF20, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47,
+            0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
+    /* 3 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57,
+            0xFF58, 0xFF59, 0xFF5A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F,
+    /* 4 */ 0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47,
+            0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
+    /* 5 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57,
+            0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFF5E, 0xFF5F,
+    /* 6 */ 0xFF60, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,
+            0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F,
+    /* 7 */ 0xFF70, 0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77,
+            0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F,
+    /* 8 */ 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87,
+            0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F,
+    /* 9 */ 0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97,
+            0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F,
+    /* A */ 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4, 0xFFA5, 0xFFA6, 0xFFA7,
+            0xFFA8, 0xFFA9, 0xFFAA, 0xFFAB, 0xFFAC, 0xFFAD, 0xFFAE, 0xFFAF,
+    /* B */ 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3, 0xFFB4, 0xFFB5, 0xFFB6, 0xFFB7,
+            0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD, 0xFFBE, 0xFFBF,
+    /* C */ 0xFFC0, 0xFFC1, 0xFFC2, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7,
+            0xFFC8, 0xFFC9, 0xFFCA, 0xFFCB, 0xFFCC, 0xFFCD, 0xFFCE, 0xFFCF,
+    /* D */ 0xFFD0, 0xFFD1, 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6, 0xFFD7,
+            0xFFD8, 0xFFD9, 0xFFDA, 0xFFDB, 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF,
+    /* E */ 0xFFE0, 0xFFE1, 0xFFE2, 0xFFE3, 0xFFE4, 0xFFE5, 0xFFE6, 0xFFE7,
+            0xFFE8, 0xFFE9, 0xFFEA, 0xFFEB, 0xFFEC, 0xFFED, 0xFFEE, 0xFFEF,
+    /* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7,
+            0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF,
+};
diff -urN linux-2.4.22-pre2/fs/hfsplus/unicode.c linux-2.4.22-pre3/fs/hfsplus/unicode.c
--- linux-2.4.22-pre2/fs/hfsplus/unicode.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/unicode.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,125 @@
+/*
+ *  linux/fs/hfsplus/unicode.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Handler routines for unicode strings
+ */
+
+#include <linux/types.h>
+#include <linux/nls.h>
+#include "hfsplus_fs.h"
+#include "hfsplus_raw.h"
+
+/* Fold the case of a unicode char, given the 16 bit value */
+/* Returns folded char, or 0 if ignorable */
+static inline u16 case_fold(u16 c)
+{
+        u16 tmp;
+
+        tmp = case_fold_table[(c>>8)];
+        if (tmp)
+                tmp = case_fold_table[tmp + (c & 0xFF)];
+        else
+                tmp = c;
+        return tmp;
+}
+
+/* Compare unicode strings, return values like normal strcmp */
+int hfsplus_unistrcmp(const hfsplus_unistr *s1, const hfsplus_unistr *s2)
+{
+	u16 len1, len2, c1, c2;
+	const hfsplus_unichr *p1, *p2;
+
+	len1 = be16_to_cpu(s1->length);
+	len2 = be16_to_cpu(s2->length);
+	p1 = s1->unicode;
+	p2 = s2->unicode;
+
+	while (1) {
+		c1 = c2 = 0;
+
+		while (len1 && !c1) {
+			c1 = case_fold(be16_to_cpu(*p1));
+			p1++;
+			len1--;
+		}
+		while (len2 && !c2) {
+			c2 = case_fold(be16_to_cpu(*p2));
+			p2++;
+			len2--;
+		}
+
+		if (c1 != c2)
+			return (c1 < c2) ? -1 : 1;
+		if (!c1 && !c2)
+			return 0;
+	}
+}
+
+int hfsplus_uni2asc(const hfsplus_unistr *ustr, char *astr, int *len)
+{
+	const hfsplus_unichr *ip;
+	u8 *op;
+	u16 ustrlen, cc;
+	int size, tmp;
+
+	op = astr;
+	ip = ustr->unicode;
+	ustrlen = be16_to_cpu(ustr->length);
+	tmp = *len;
+	while (ustrlen > 0 && tmp > 0) {
+		cc = be16_to_cpu(*ip);
+		if (!cc || cc > 0x7f) {
+			size = utf8_wctomb(op, cc ? cc : 0x2400, tmp);
+			if (size == -1) {
+				/* ignore */
+			} else {
+				op += size;
+				tmp -= size;
+			}
+		} else {
+			*op++ = (u8) cc;
+			tmp--;
+		}
+		ip++;
+		ustrlen--;
+	}
+	*len = (char *)op - astr;
+	if (ustrlen)
+		return -ENAMETOOLONG;
+	return 0;
+}
+
+int hfsplus_asc2uni(hfsplus_unistr *ustr, const char *astr, int len)
+{
+	int tmp;
+	wchar_t c;
+	u16 outlen = 0;
+
+	while (outlen <= HFSPLUS_MAX_STRLEN && len > 0) {
+		if (*astr & 0x80) {
+			tmp = utf8_mbtowc(&c, astr, len);
+			if (tmp < 0) {
+				astr++;
+				len--;
+				continue;
+			} else {
+				astr += tmp;
+				len -= tmp;
+			}
+			if (c == 0x2400)
+				c = 0;
+		} else {
+			c = *astr++;
+			len--;
+		}
+		ustr->unicode[outlen] = cpu_to_be16(c);
+		outlen++;
+	}
+	ustr->length = cpu_to_be16(outlen);
+	if (len > 0)
+		return -ENAMETOOLONG;
+	return 0;
+}
diff -urN linux-2.4.22-pre2/fs/hfsplus/wrapper.c linux-2.4.22-pre3/fs/hfsplus/wrapper.c
--- linux-2.4.22-pre2/fs/hfsplus/wrapper.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/fs/hfsplus/wrapper.c	2003-07-05 18:11:06.000000000 -0700
@@ -0,0 +1,147 @@
+/*
+ *  linux/fs/hfsplus/wrapper.c
+ *
+ * Copyright (C) 2001
+ * Brad Boyer (flar@allandria.com)
+ *
+ * Handling of HFS wrappers around HFS+ volumes
+ */
+
+#include <linux/fs.h>
+#include <linux/blkdev.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <linux/buffer_head.h>
+#endif
+
+#include "hfsplus_fs.h"
+#include "hfsplus_raw.h"
+
+struct hfsplus_wd {
+	u32 ablk_size;
+	u16 ablk_start;
+	u16 embed_start;
+	u16 embed_count;
+};
+
+static int hfsplus_read_mdb(unsigned char *bufptr, struct hfsplus_wd *wd)
+{
+	u32 extent;
+	u16 attrib;
+
+	if (be16_to_cpu(*(u16 *)(bufptr + HFSP_WRAPOFF_EMBEDSIG)) != HFSPLUS_VOLHEAD_SIG)
+		return 0;
+
+	attrib = be16_to_cpu(*(u16 *)(bufptr + HFSP_WRAPOFF_ATTRIB));
+	if (!(attrib & HFSP_WRAP_ATTRIB_SLOCK) ||
+	   !(attrib & HFSP_WRAP_ATTRIB_SPARED))
+		return 0;
+
+	wd->ablk_size = be32_to_cpu(*(u32 *)(bufptr + HFSP_WRAPOFF_ABLKSIZE));
+	if (wd->ablk_size < HFSPLUS_SECTOR_SIZE)
+		return 0;
+	if (wd->ablk_size % HFSPLUS_SECTOR_SIZE)
+		return 0;
+	wd->ablk_start = be16_to_cpu(*(u16 *)(bufptr + HFSP_WRAPOFF_ABLKSTART));
+
+	extent = be32_to_cpu(*(u32 *)(bufptr + HFSP_WRAPOFF_EMBEDEXT));
+	wd->embed_start = (extent >> 16) & 0xFFFF;
+	wd->embed_count = extent & 0xFFFF;
+
+	return 1;
+}
+
+/* Find the volume header and fill in some minimum bits in superblock */
+/* Takes in super block, returns true if good data read */
+int hfsplus_read_wrapper(struct super_block *sb)
+{
+	struct buffer_head *bh;
+	struct hfsplus_vh *vhdr;
+	char *bufptr;
+	unsigned long block, offset, vhsect;
+	struct hfsplus_wd wd;
+	u32 blocksize, blockoffset;
+	u16 sig;
+
+	blocksize = sb_min_blocksize(sb, HFSPLUS_SECTOR_SIZE);
+	if (!blocksize) {
+		printk("HFS+-fs: unable to configure block size\n");
+		return -EINVAL;
+	}
+
+	block = (HFSPLUS_VOLHEAD_SECTOR * HFSPLUS_SECTOR_SIZE) / blocksize;
+	offset = (HFSPLUS_VOLHEAD_SECTOR * HFSPLUS_SECTOR_SIZE) % blocksize;
+
+	bh = sb_bread(sb, block);
+	if (!bh) {
+		printk("HFS+-fs: unable to read VHDR or MDB\n");
+		return -EIO;
+	}
+
+	bufptr = bh->b_data + offset;
+	sig = be16_to_cpu(*(u16 *)(bufptr + HFSP_WRAPOFF_SIG));
+	if (sig == HFSP_WRAP_MAGIC) {
+		if (!hfsplus_read_mdb(bufptr, &wd))
+			goto error;
+		vhsect = (wd.ablk_start + wd.embed_start * (wd.ablk_size >> 9))
+			+ HFSPLUS_VOLHEAD_SECTOR;
+		block = (vhsect * HFSPLUS_SECTOR_SIZE) / blocksize;
+		offset = (vhsect * HFSPLUS_SECTOR_SIZE) % blocksize;
+		brelse(bh);
+		bh = sb_bread(sb, block);
+		if (!bh) {
+			printk("HFS+-fs: unable to read VHDR\n");
+			return -EIO;
+		}
+		HFSPLUS_SB(sb).sect_count = wd.embed_count * (wd.ablk_size >> 9);
+	} else {
+		wd.ablk_start = 0;
+		wd.ablk_size = blocksize;
+		wd.embed_start = 0;
+		HFSPLUS_SB(sb).sect_count = sb->s_bdev->bd_inode->i_size >> 9;
+	}
+	vhdr = (struct hfsplus_vh *)(bh->b_data + offset);
+	if (be16_to_cpu(vhdr->signature) != HFSPLUS_VOLHEAD_SIG)
+		goto error;
+	blocksize = be32_to_cpu(vhdr->blocksize);
+	brelse(bh);
+
+	/* block size must be at least as large as a sector
+	 * and a multiple of 2
+	 */
+	if (blocksize < HFSPLUS_SECTOR_SIZE ||
+	    ((blocksize - 1) & blocksize))
+		return -EINVAL;
+
+	/* block offset must be a multiple of the block size */
+	blockoffset = wd.ablk_start + wd.embed_start * (wd.ablk_size >> 9);
+	if (blockoffset % (blocksize / HFSPLUS_SECTOR_SIZE)) {
+		printk("HFS+-fs: embedded blocks not aligned with wrapper\n");
+		return -EINVAL;
+	}
+	blockoffset /= blocksize / HFSPLUS_SECTOR_SIZE;
+	HFSPLUS_SB(sb).blockoffset = blockoffset;
+
+	if (sb_set_blocksize(sb, blocksize) != blocksize)
+		return -EINVAL;
+
+	block = blockoffset + HFSPLUS_VOLHEAD_SECTOR /
+		(blocksize / HFSPLUS_SECTOR_SIZE);
+	offset = (HFSPLUS_VOLHEAD_SECTOR * HFSPLUS_SECTOR_SIZE) % blocksize;
+	bh = sb_bread(sb, block);
+	if (!bh) {
+		printk("HFS+-fs: unable to read VHDR or MDB\n");
+		return -EIO;
+	}
+	vhdr = (struct hfsplus_vh *)(bh->b_data + offset);
+	/* should still be the same... */
+	if (be16_to_cpu(vhdr->signature) != HFSPLUS_VOLHEAD_SIG)
+		goto error;
+	HFSPLUS_SB(sb).s_vhbh = bh;
+	HFSPLUS_SB(sb).s_vhdr = vhdr;
+
+	return 0;
+ error:
+	brelse(bh);
+	return -EINVAL;
+}
diff -urN linux-2.4.22-pre2/fs/lockd/clntproc.c linux-2.4.22-pre3/fs/lockd/clntproc.c
--- linux-2.4.22-pre2/fs/lockd/clntproc.c	2001-10-11 07:52:18.000000000 -0700
+++ linux-2.4.22-pre3/fs/lockd/clntproc.c	2003-07-05 18:11:06.000000000 -0700
@@ -460,7 +460,7 @@
 		}
 		if (status < 0)
 			return status;
-	} while (resp->status == NLM_LCK_BLOCKED);
+	} while (resp->status == NLM_LCK_BLOCKED && req->a_args.block);
 
 	if (resp->status == NLM_LCK_GRANTED) {
 		fl->fl_u.nfs_fl.state = host->h_state;
diff -urN linux-2.4.22-pre2/fs/lockd/host.c linux-2.4.22-pre3/fs/lockd/host.c
--- linux-2.4.22-pre2/fs/lockd/host.c	2001-10-01 13:45:47.000000000 -0700
+++ linux-2.4.22-pre3/fs/lockd/host.c	2003-07-05 18:11:06.000000000 -0700
@@ -187,15 +187,7 @@
 					host->h_nextrebind - jiffies);
 		}
 	} else {
-		uid_t saved_fsuid = current->fsuid;
-		kernel_cap_t saved_cap = current->cap_effective;
-
-		/* Create RPC socket as root user so we get a priv port */
-		current->fsuid = 0;
-		cap_raise (current->cap_effective, CAP_NET_BIND_SERVICE);
 		xprt = xprt_create_proto(host->h_proto, &host->h_addr, NULL);
-		current->fsuid = saved_fsuid;
-		current->cap_effective = saved_cap;
 		if (xprt == NULL)
 			goto forgetit;
 
@@ -209,6 +201,7 @@
 		}
 		clnt->cl_autobind = 1;	/* turn on pmap queries */
 		xprt->nocong = 1;	/* No congestion control for NLM */
+		xprt->resvport = 1;	/* NLM requires a reserved port */
 
 		host->h_rpcclnt = clnt;
 	}
diff -urN linux-2.4.22-pre2/fs/lockd/mon.c linux-2.4.22-pre3/fs/lockd/mon.c
--- linux-2.4.22-pre2/fs/lockd/mon.c	2001-10-01 13:45:47.000000000 -0700
+++ linux-2.4.22-pre3/fs/lockd/mon.c	2003-07-05 18:11:06.000000000 -0700
@@ -122,6 +122,7 @@
 	clnt->cl_softrtry = 1;
 	clnt->cl_chatty   = 1;
 	clnt->cl_oneshot  = 1;
+	xprt->resvport = 1;	/* NSM requires a reserved port */
 out:
 	return clnt;
 
diff -urN linux-2.4.22-pre2/fs/lockd/svc4proc.c linux-2.4.22-pre3/fs/lockd/svc4proc.c
--- linux-2.4.22-pre2/fs/lockd/svc4proc.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/lockd/svc4proc.c	2003-07-05 18:11:06.000000000 -0700
@@ -462,6 +462,24 @@
 }
 
 /*
+ * client sent a GRANTED_RES, let's remove the associated block
+ */
+static int
+nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res  *argp,
+                                                void            *resp)
+{
+        if (!nlmsvc_ops)
+                return rpc_success;
+
+        dprintk("lockd: GRANTED_RES   called\n");
+
+        nlmsvc_grant_reply(&argp->cookie, argp->status);
+        return rpc_success;
+}
+
+
+
+/*
  * This is the generic lockd callback for async RPC calls
  */
 static u32
@@ -524,7 +542,6 @@
 #define nlm4svc_proc_lock_res	nlm4svc_proc_null
 #define nlm4svc_proc_cancel_res	nlm4svc_proc_null
 #define nlm4svc_proc_unlock_res	nlm4svc_proc_null
-#define nlm4svc_proc_granted_res	nlm4svc_proc_null
 
 struct nlm_void			{ int dummy; };
 
@@ -559,7 +576,7 @@
   PROC(lock_res,	lockres,	norep,		res,	void, 1),
   PROC(cancel_res,	cancelres,	norep,		res,	void, 1),
   PROC(unlock_res,	unlockres,	norep,		res,	void, 1),
-  PROC(granted_res,	grantedres,	norep,		res,	void, 1),
+  PROC(granted_res,	res,		norep,		res,	void, 1),
   /* statd callback */
   PROC(sm_notify,	reboot,		void,		reboot,	void, 1),
   PROC(none,		void,		void,		void,	void, 0),
diff -urN linux-2.4.22-pre2/fs/lockd/svclock.c linux-2.4.22-pre3/fs/lockd/svclock.c
--- linux-2.4.22-pre2/fs/lockd/svclock.c	2001-10-11 07:52:18.000000000 -0700
+++ linux-2.4.22-pre3/fs/lockd/svclock.c	2003-07-05 18:11:06.000000000 -0700
@@ -64,7 +64,7 @@
 	if (when != NLM_NEVER) {
 		if ((when += jiffies) == NLM_NEVER)
 			when ++;
-		while ((b = *bp) && time_before_eq(b->b_when,when))
+		while ((b = *bp) && time_before_eq(b->b_when,when) && b->b_when != NLM_NEVER)
 			bp = &b->b_next;
 	} else
 		while ((b = *bp))
diff -urN linux-2.4.22-pre2/fs/lockd/svcproc.c linux-2.4.22-pre3/fs/lockd/svcproc.c
--- linux-2.4.22-pre2/fs/lockd/svcproc.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/lockd/svcproc.c	2003-07-05 18:11:06.000000000 -0700
@@ -490,6 +490,22 @@
 }
 
 /*
+ * client sent a GRANTED_RES, let's remove the associated block
+ */
+static int
+nlmsvc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res  *argp,
+                                                void            *resp)
+{
+	if (!nlmsvc_ops)
+		return rpc_success;
+
+	dprintk("lockd: GRANTED_RES   called\n");
+
+	nlmsvc_grant_reply(&argp->cookie, argp->status);
+	return rpc_success;
+}
+
+/*
  * This is the generic lockd callback for async RPC calls
  */
 static u32
@@ -552,7 +568,6 @@
 #define nlmsvc_proc_lock_res	nlmsvc_proc_null
 #define nlmsvc_proc_cancel_res	nlmsvc_proc_null
 #define nlmsvc_proc_unlock_res	nlmsvc_proc_null
-#define nlmsvc_proc_granted_res	nlmsvc_proc_null
 
 struct nlm_void			{ int dummy; };
 
@@ -589,7 +604,7 @@
   PROC(lock_res,	lockres,	norep,		res,	void, 1),
   PROC(cancel_res,	cancelres,	norep,		res,	void, 1),
   PROC(unlock_res,	unlockres,	norep,		res,	void, 1),
-  PROC(granted_res,	grantedres,	norep,		res,	void, 1),
+  PROC(granted_res,	res,		norep,		res,	void, 1),
   /* statd callback */
   PROC(sm_notify,	reboot,		void,		reboot,	void, 1),
   PROC(none,		void,		void,		void,	void, 1),
diff -urN linux-2.4.22-pre2/fs/nfs/nfs3proc.c linux-2.4.22-pre3/fs/nfs/nfs3proc.c
--- linux-2.4.22-pre2/fs/nfs/nfs3proc.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/nfs/nfs3proc.c	2003-07-05 18:11:06.000000000 -0700
@@ -300,11 +300,16 @@
 {
 	struct nfs3_diropargs	*arg;
 	struct nfs_fattr	*res;
+	struct unlinkxdr {
+		struct nfs3_diropargs arg;
+		struct nfs_fattr res;
+	} *ptr;
 
-	arg = (struct nfs3_diropargs *)kmalloc(sizeof(*arg)+sizeof(*res), GFP_KERNEL);
-	if (!arg)
+	ptr = (struct unlinkxdr *)kmalloc(sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
 		return -ENOMEM;
-	res = (struct nfs_fattr*)(arg + 1);
+	arg = &ptr->arg;
+	res = &ptr->res;
 	arg->fh = NFS_FH(dir->d_inode);
 	arg->name = name->name;
 	arg->len = name->len;
diff -urN linux-2.4.22-pre2/fs/nfs/write.c linux-2.4.22-pre3/fs/nfs/write.c
--- linux-2.4.22-pre2/fs/nfs/write.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/nfs/write.c	2003-07-05 18:11:06.000000000 -0700
@@ -812,8 +812,15 @@
 	 * If wsize is smaller than page size, update and write
 	 * page synchronously.
 	 */
-	if (NFS_SERVER(inode)->wsize < PAGE_CACHE_SIZE || IS_SYNC(inode))
-		return nfs_writepage_sync(file, inode, page, offset, count);
+	if (NFS_SERVER(inode)->wsize < PAGE_CACHE_SIZE || IS_SYNC(inode)) {
+		status = nfs_writepage_sync(file, inode, page, offset, count);
+		if (status > 0) {
+			if (offset == 0 && status == PAGE_CACHE_SIZE)
+				SetPageUptodate(page);
+			return 0;
+		}
+		return status;
+	}
 
 	/*
 	 * Try to find an NFS request corresponding to this page
diff -urN linux-2.4.22-pre2/fs/nls/Config.in linux-2.4.22-pre3/fs/nls/Config.in
--- linux-2.4.22-pre2/fs/nls/Config.in	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/nls/Config.in	2003-07-05 18:11:06.000000000 -0700
@@ -13,7 +13,7 @@
 if [ "$CONFIG_JOLIET" = "y" -o "$CONFIG_FAT_FS" != "n" \
 	-o "$CONFIG_NTFS_FS" != "n" -o "$CONFIG_NCPFS_NLS" = "y" \
 	-o "$CONFIG_SMB_NLS" = "y" -o "$CONFIG_JFS_FS" != "n" \
-	-o "$CONFIG_BEFS_FS" != "n" ]; then
+	-o "$CONFIG_BEFS_FS" != "n" -o "$CONFIG_HFSPLUS_FS" != "n" ]; then
   define_bool CONFIG_NLS y
 else
   define_bool CONFIG_NLS n
diff -urN linux-2.4.22-pre2/fs/partitions/efi.h linux-2.4.22-pre3/fs/partitions/efi.h
--- linux-2.4.22-pre2/fs/partitions/efi.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/partitions/efi.h	2003-07-05 18:11:06.000000000 -0700
@@ -40,7 +40,7 @@
 #define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
 
 #define GPT_BLOCK_SIZE 512
-#define GPT_HEADER_SIGNATURE 0x5452415020494645L
+#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
 #define GPT_HEADER_REVISION_V1 0x00010000
 #define GPT_PRIMARY_PARTITION_TABLE_LBA 1
 
diff -urN linux-2.4.22-pre2/fs/reiserfs/Makefile linux-2.4.22-pre3/fs/reiserfs/Makefile
--- linux-2.4.22-pre2/fs/reiserfs/Makefile	2002-02-25 11:38:09.000000000 -0800
+++ linux-2.4.22-pre3/fs/reiserfs/Makefile	2003-07-05 18:11:06.000000000 -0700
@@ -9,7 +9,7 @@
 
 O_TARGET := reiserfs.o
 obj-y   := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o super.o prints.o objectid.o \
-lbalance.o ibalance.o stree.o hashes.o buffer2.o tail_conversion.o journal.o resize.o version.o item_ops.o ioctl.o procfs.o
+lbalance.o ibalance.o stree.o hashes.o buffer2.o tail_conversion.o journal.o resize.o item_ops.o ioctl.o procfs.o
 
 obj-m   := $(O_TARGET)
 
diff -urN linux-2.4.22-pre2/fs/reiserfs/bitmap.c linux-2.4.22-pre3/fs/reiserfs/bitmap.c
--- linux-2.4.22-pre2/fs/reiserfs/bitmap.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/reiserfs/bitmap.c	2003-07-05 18:11:06.000000000 -0700
@@ -40,7 +40,7 @@
 
 #define SET_OPTION(optname) \
    do { \
-        reiserfs_warning("reiserfs: option \"%s\" is set\n", #optname); \
+        reiserfs_warning(s, "reiserfs: option \"%s\" is set\n", #optname); \
         set_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s)); \
     } while(0)
 #define TEST_OPTION(optname, s) \
@@ -66,7 +66,7 @@
     int i, j;
 
     if (block == 0 || block >= SB_BLOCK_COUNT (s)) {
-	reiserfs_warning ("vs-4010: is_reusable: block number is out of range %lu (%u)\n",
+	reiserfs_warning (s, "vs-4010: is_reusable: block number is out of range %lu (%u)\n",
 			  block, SB_BLOCK_COUNT (s));
 	return 0;
     }
@@ -74,7 +74,7 @@
     /* it can't be one of the bitmap blocks */
     for (i = 0; i < SB_BMAP_NR (s); i ++)
 	if (block == SB_AP_BITMAP (s)[i].bh->b_blocknr) {
-	    reiserfs_warning ("vs: 4020: is_reusable: "
+	    reiserfs_warning (s, "vs: 4020: is_reusable: "
 			      "bitmap block %lu(%u) can't be freed or reused\n",
 			      block, SB_BMAP_NR (s));
 	    return 0;
@@ -83,7 +83,7 @@
     get_bit_address (s, block, &i, &j);
 
     if (i >= SB_BMAP_NR (s)) {
-	reiserfs_warning ("vs-4030: is_reusable: there is no so many bitmap blocks: "
+	reiserfs_warning (s, "vs-4030: is_reusable: there is no so many bitmap blocks: "
 			  "block=%lu, bitmap_nr=%d\n", block, i);
 	return 0;
     }
@@ -92,7 +92,7 @@
          reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data)) ||
 	(bit_value == 1 && 
 	 reiserfs_test_le_bit(j, SB_AP_BITMAP (s)[i].bh->b_data) == 0)) {
-	reiserfs_warning ("vs-4040: is_reusable: corresponding bit of block %lu does not "
+	reiserfs_warning (s, "vs-4040: is_reusable: corresponding bit of block %lu does not "
 			  "match required value (i==%d, j==%d) test_bit==%d\n",
 		block, i, j, reiserfs_test_le_bit (j, SB_AP_BITMAP (s)[i].bh->b_data));
 		
@@ -100,7 +100,7 @@
     }
 
     if (bit_value == 0 && block == SB_ROOT_BLOCK (s)) {
-	reiserfs_warning ("vs-4050: is_reusable: this is root block (%u), "
+	reiserfs_warning (s, "vs-4050: is_reusable: this is root block (%u), "
 			  "it must be busy\n", SB_ROOT_BLOCK (s));
 	return 0;
     }
@@ -304,7 +304,7 @@
     get_bit_address (s, block, &nr, &offset);
   
     if (nr >= sb_bmap_nr (rs)) {
-	reiserfs_warning ("vs-4075: reiserfs_free_block: "
+	reiserfs_warning (s, "vs-4075: reiserfs_free_block: "
 			  "block %lu is out of range on %s\n",
 			  block, bdevname(s->s_dev));
 	return;
@@ -314,7 +314,7 @@
   
     /* clear bit for the given block in bit map */
     if (!reiserfs_test_and_clear_le_bit (offset, apbi[nr].bh->b_data)) {
-	reiserfs_warning ("vs-4080: reiserfs_free_block: "
+	reiserfs_warning (s, "vs-4080: reiserfs_free_block: "
 			  "free_block (%04x:%lu)[dev:blocknr]: bit already cleared\n", 
 			  s->s_dev, block);
     }
@@ -356,7 +356,7 @@
     unsigned long save = inode->u.reiserfs_i.i_prealloc_block ;
 #ifdef CONFIG_REISERFS_CHECK
     if (inode->u.reiserfs_i.i_prealloc_count < 0)
-	reiserfs_warning("zam-4001:%s: inode has negative prealloc blocks count.\n", __FUNCTION__ );
+	reiserfs_warning(th->t_super, "zam-4001:%s: inode has negative prealloc blocks count.\n", __FUNCTION__ );
 #endif  
     while (inode->u.reiserfs_i.i_prealloc_count > 0) {
 	reiserfs_free_prealloc_block(th,inode->u.reiserfs_i.i_prealloc_block);
@@ -385,7 +385,7 @@
     inode = list_entry(plist->next, struct inode, u.reiserfs_i.i_prealloc_list);
 #ifdef CONFIG_REISERFS_CHECK
     if (!inode->u.reiserfs_i.i_prealloc_count) {
-      reiserfs_warning("zam-4001:%s: inode is in prealloc list but has no preallocated blocks.\n", __FUNCTION__ );
+      reiserfs_warning(th->t_super, "zam-4001:%s: inode is in prealloc list but has no preallocated blocks.\n", __FUNCTION__ );
     }
 #endif
     __discard_prealloc(th, inode);
@@ -472,7 +472,7 @@
 	    continue;
 	}
 
-	reiserfs_warning("zam-4001: %s : unknown option - %s\n", __FUNCTION__ , this_char);
+	reiserfs_warning(s, "zam-4001: %s : unknown option - %s\n", __FUNCTION__ , this_char);
 	return 1;
     }
 
diff -urN linux-2.4.22-pre2/fs/reiserfs/buffer2.c linux-2.4.22-pre3/fs/reiserfs/buffer2.c
--- linux-2.4.22-pre2/fs/reiserfs/buffer2.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/reiserfs/buffer2.c	2003-07-05 18:11:06.000000000 -0700
@@ -28,7 +28,7 @@
   while (atomic_read (&(bh->b_count)) > 1) {
 
     if ( !(++repeat_counter % 30000000) ) {
-      reiserfs_warning ("vs-3050: wait_buffer_until_released: nobody releases buffer (%b). Still waiting (%d) %cJDIRTY %cJWAIT\n",
+      reiserfs_warning (NULL, "vs-3050: wait_buffer_until_released: nobody releases buffer (%b). Still waiting (%d) %cJDIRTY %cJWAIT\n",
 			bh, repeat_counter, buffer_journaled(bh) ? ' ' : '!',
 			buffer_journal_dirty(bh) ? ' ' : '!');
     }
@@ -36,7 +36,7 @@
     yield();
   }
   if (repeat_counter > 30000000) {
-    reiserfs_warning("vs-3051: done waiting, ignore vs-3050 messages for (%b)\n", bh) ;
+    reiserfs_warning(NULL, "vs-3051: done waiting, ignore vs-3050 messages for (%b)\n", bh) ;
   }
 }
 
@@ -60,3 +60,17 @@
     return result;
 }
 
+struct buffer_head  * journal_bread (struct super_block *s, int block)
+{
+	return bread (SB_JOURNAL_DEV(s), block, s->s_blocksize );
+}
+
+struct buffer_head  * journal_getblk (struct super_block *s, int block)
+{
+	return getblk (SB_JOURNAL_DEV(s), block, s->s_blocksize );
+}
+
+struct buffer_head  * journal_get_hash_table (struct super_block *s, int block)
+{
+  return get_hash_table (SB_JOURNAL_DEV(s), block, s->s_blocksize );
+}
diff -urN linux-2.4.22-pre2/fs/reiserfs/dir.c linux-2.4.22-pre3/fs/reiserfs/dir.c
--- linux-2.4.22-pre2/fs/reiserfs/dir.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/reiserfs/dir.c	2003-07-05 18:11:06.000000000 -0700
@@ -58,7 +58,7 @@
 		  TYPE_DIRENTRY, 3);
     next_pos = cpu_key_k_offset (&pos_key);
 
-    /*  reiserfs_warning ("reiserfs_readdir 1: f_pos = %Ld\n", filp->f_pos);*/
+    /*  reiserfs_warning (inode->i_sb, "reiserfs_readdir 1: f_pos = %Ld\n", filp->f_pos);*/
 
     while (1) {
     research:
diff -urN linux-2.4.22-pre2/fs/reiserfs/do_balan.c linux-2.4.22-pre3/fs/reiserfs/do_balan.c
--- linux-2.4.22-pre2/fs/reiserfs/do_balan.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/reiserfs/do_balan.c	2003-07-05 18:11:06.000000000 -0700
@@ -304,8 +304,6 @@
 		    int new_item_len;
 		    int version;
 
-		    RFALSE (!is_direct_le_ih (ih),
-			    "PAP-12075: only direct inserted item can be broken. %h", ih);
 		    ret_val = leaf_shift_left (tb, tb->lnum[0]-1, -1);
 
 		    /* Calculate item length to insert to S[0] */
@@ -328,7 +326,7 @@
 		    version = ih_version (ih);
 
 		    /* Calculate key component, item length and body to insert into S[0] */
-                    set_le_ih_k_offset( ih, le_ih_k_offset( ih ) + tb->lbytes );
+                    set_le_ih_k_offset( ih, le_ih_k_offset( ih ) + (tb->lbytes << (is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize_bits-UNFM_P_SHIFT:0)) );
 
 		    put_ih_item_len( ih, new_item_len );
 		    if ( tb->lbytes >  zeros_num ) {
@@ -437,23 +435,28 @@
 				ih_item_len( B_N_PITEM_HEAD(tb->L[0],n+item_pos-ret_val)),
 				l_n,body, zeros_num > l_n ? l_n : zeros_num
 				);
-
-			    RFALSE( l_n && 
-				    is_indirect_le_ih(B_N_PITEM_HEAD
-						      (tb->L[0],
-						       n + item_pos - ret_val)),
-				    "PAP-12110: pasting more than 1 unformatted node pointer into indirect item");
-
 			    /* 0-th item in S0 can be only of DIRECT type when l_n != 0*/
 			    {
-			      int version;
-
-			      version = ih_version (B_N_PITEM_HEAD (tbS0, 0));
-			      set_le_key_k_offset (version, B_N_PKEY (tbS0, 0), 
-						   le_key_k_offset (version, B_N_PKEY (tbS0, 0)) + l_n);
-			      version = ih_version (B_N_PITEM_HEAD(tb->CFL[0],tb->lkey[0]));
-			      set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]),
-						   le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0])) + l_n);
+				int version;
+				int temp_l = l_n;
+				
+				RFALSE (ih_item_len (B_N_PITEM_HEAD (tbS0, 0)),
+					"PAP-12106: item length must be 0");
+				RFALSE (comp_short_le_keys (B_N_PKEY (tbS0, 0),
+							    B_N_PKEY (tb->L[0],
+									    n + item_pos - ret_val)),
+					"PAP-12107: items must be of the same file");
+				if (is_indirect_le_ih(B_N_PITEM_HEAD (tb->L[0],
+								      n + item_pos - ret_val)))	{
+				    temp_l = l_n << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT);
+				}
+				/* update key of first item in S0 */
+				version = ih_version (B_N_PITEM_HEAD (tbS0, 0));
+				set_le_key_k_offset (version, B_N_PKEY (tbS0, 0), 
+						     le_key_k_offset (version, B_N_PKEY (tbS0, 0)) + temp_l);
+				/* update left delimiting key */
+				set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]),
+						     le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0])) + temp_l);
 			    }
 
 			    /* Calculate new body, position in item and insert_size[0] */
@@ -522,7 +525,7 @@
 			    );
 		    /* if appended item is indirect item, put unformatted node into un list */
 		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
+			set_ih_free_space (pasted, 0);
 		    tb->insert_size[0] = 0;
 		    zeros_num = 0;
 		}
@@ -550,15 +553,11 @@
 	    { /* new item or its part falls to R[0] */
 		if ( item_pos == n - tb->rnum[0] + 1 && tb->rbytes != -1 )
 		{ /* part of new item falls into R[0] */
-		    int old_key_comp, old_len, r_zeros_number;
+		    loff_t old_key_comp, old_len, r_zeros_number;
 		    const char * r_body;
 		    int version;
 		    loff_t offset;
 
-		    RFALSE( !is_direct_le_ih (ih),
-			    "PAP-12135: only direct item can be split. (%h)", 
-			    ih);
-
 		    leaf_shift_right(tb,tb->rnum[0]-1,-1);
 
 		    version = ih_version(ih);
@@ -567,7 +566,7 @@
 		    old_len = ih_item_len(ih);
 
 		    /* Calculate key component and item length to insert into R[0] */
-                    offset = le_ih_k_offset( ih ) + (old_len - tb->rbytes );
+                    offset = le_ih_k_offset( ih ) + ((old_len - tb->rbytes )<<(is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize_bits-UNFM_P_SHIFT:0));
                     set_le_ih_k_offset( ih, offset );
 		    put_ih_item_len( ih, tb->rbytes);
 		    /* Insert part of the item into R[0] */
@@ -575,13 +574,13 @@
 		    bi.bi_bh = tb->R[0];
 		    bi.bi_parent = tb->FR[0];
 		    bi.bi_position = get_right_neighbor_position (tb, 0);
-		    if ( offset - old_key_comp > zeros_num ) {
+		    if ( (old_len - tb->rbytes) > zeros_num ) {
 			r_zeros_number = 0;
-			r_body = body + offset - old_key_comp - zeros_num;
+			r_body = body + (old_len - tb->rbytes) - zeros_num;
 		    }
 		    else {
 			r_body = body;
-			r_zeros_number = zeros_num - (offset - old_key_comp);
+			r_zeros_number = zeros_num - (old_len - tb->rbytes);
 			zeros_num -= r_zeros_number;
 		    }
 
@@ -692,12 +691,17 @@
 			
 			{
 			  int version;
+			  unsigned long temp_rem = n_rem;
 			  
 			  version = ih_version (B_N_PITEM_HEAD (tb->R[0],0));
+			  if (is_indirect_le_key(version,B_N_PKEY(tb->R[0],0))){
+			      temp_rem = n_rem << (tb->tb_sb->s_blocksize_bits -
+			                 UNFM_P_SHIFT);
+			  }
 			  set_le_key_k_offset (version, B_N_PKEY(tb->R[0],0), 
-					       le_key_k_offset (version, B_N_PKEY(tb->R[0],0)) + n_rem);
+					       le_key_k_offset (version, B_N_PKEY(tb->R[0],0)) + temp_rem);
 			  set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0]), 
-					       le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) + n_rem);
+					       le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) + temp_rem);
 			}
 /*		  k_offset (B_N_PKEY(tb->R[0],0)) += n_rem;
 		  k_offset (B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) += n_rem;*/
@@ -721,13 +725,12 @@
 			leaf_paste_in_buffer(&bi, 0, n_shift, tb->insert_size[0] - n_rem, r_body, r_zeros_number);
 
 			if (is_indirect_le_ih (B_N_PITEM_HEAD(tb->R[0],0))) {
-
+#if 0
 			    RFALSE( n_rem,
 				    "PAP-12160: paste more than one unformatted node pointer");
-
-			    set_ih_free_space (B_N_PITEM_HEAD(tb->R[0],0), ((struct unfm_nodeinfo*)body)->unfm_freespace);
+#endif
+			    set_ih_free_space (B_N_PITEM_HEAD(tb->R[0],0), 0);
 			}
-
 			tb->insert_size[0] = n_rem;
 			if ( ! n_rem )
 			    pos_in_item ++;
@@ -766,7 +769,7 @@
 		    }
 
 		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
+			set_ih_free_space (pasted, 0);
 		    zeros_num = tb->insert_size[0] = 0;
 		}
 	    }
@@ -843,12 +846,6 @@
 		    const char * r_body;
 		    int version;
 
-		    RFALSE( !is_direct_le_ih(ih),
-			/* The items which can be inserted are:
-			   Stat_data item, direct item, indirect item and directory item which consist of only two entries "." and "..".
-			   These items must not be broken except for a direct one. */
-			    "PAP-12205: non-direct item can not be broken when inserting");
-
 		    /* Move snum[i]-1 items from S[0] to S_new[i] */
 		    leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i] - 1, -1, S_new[i]);
 		    /* Remember key component and item length */
@@ -858,7 +855,7 @@
 
 		    /* Calculate key component and item length to insert into S_new[i] */
                     set_le_ih_k_offset( ih,
-                                le_ih_k_offset(ih) + (old_len - sbytes[i] ) );
+                                le_ih_k_offset(ih) + ((old_len - sbytes[i] )<<(is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize_bits-UNFM_P_SHIFT:0) ));
 
 		    put_ih_item_len( ih, sbytes[i] );
 
@@ -868,13 +865,13 @@
 		    bi.bi_parent = 0;
 		    bi.bi_position = 0;
 
-		    if ( le_ih_k_offset (ih) - old_key_comp > zeros_num ) {
+		    if ( (old_len - sbytes[i]) > zeros_num ) {
 			r_zeros_number = 0;
-			r_body = body + (le_ih_k_offset(ih) - old_key_comp) - zeros_num;
+			r_body = body + (old_len - sbytes[i]) - zeros_num;
 		    }
 		    else {
 			r_body = body;
-			r_zeros_number = zeros_num - (le_ih_k_offset (ih) - old_key_comp);
+			r_zeros_number = zeros_num - (old_len - sbytes[i]);
 			zeros_num -= r_zeros_number;
 		    }
 
@@ -995,11 +992,14 @@
 
 			    tmp = B_N_PITEM_HEAD(S_new[i],0);
 			    if (is_indirect_le_ih (tmp)) {
-				if (n_rem)
-				    reiserfs_panic (tb->tb_sb, "PAP-12230: balance_leaf: invalid action with indirect item");
-				set_ih_free_space (tmp, ((struct unfm_nodeinfo*)body)->unfm_freespace);
+				set_ih_free_space (tmp, 0);
+				set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + 
+					            (n_rem << (tb->tb_sb->s_blocksize_bits -
+						     UNFM_P_SHIFT)));
+			    } else {
+				set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + 
+				                    n_rem );
 			    }
-                            set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + n_rem );
 			}
 
 			tb->insert_size[0] = n_rem;
@@ -1045,7 +1045,7 @@
 
 		    /* if we paste to indirect item update ih_free_space */
 		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
+			set_ih_free_space (pasted, 0);
 		    zeros_num = tb->insert_size[0] = 0;
 		}
 	    }
@@ -1141,11 +1141,12 @@
 		    leaf_paste_in_buffer (&bi, item_pos, pos_in_item, tb->insert_size[0], body, zeros_num);
 
 		    if (is_indirect_le_ih (pasted)) {
-
+#if 0
 			RFALSE( tb->insert_size[0] != UNFM_P_SIZE,
 				"PAP-12280: insert_size for indirect item must be %d, not %d",
 				UNFM_P_SIZE, tb->insert_size[0]);
-			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
+#endif
+			set_ih_free_space (pasted, 0);
 		    }
 		    tb->insert_size[0] = 0;
 		}
@@ -1227,14 +1228,14 @@
     int i;
 
     if (buffer_dirty (bh))
-      printk ("store_thrown deals with dirty buffer\n");
+      reiserfs_warning (tb->tb_sb, "store_thrown deals with dirty buffer\n");
     for (i = 0; i < sizeof (tb->thrown)/sizeof (tb->thrown[0]); i ++)
 	if (!tb->thrown[i]) {
 	    tb->thrown[i] = bh;
 	    get_bh(bh) ; /* free_thrown puts this */
 	    return;
 	}
-    reiserfs_warning ("store_thrown: too many thrown buffers\n");
+    reiserfs_warning (tb->tb_sb, "store_thrown: too many thrown buffers\n");
 }
 
 static void free_thrown(struct tree_balance *tb) {
@@ -1244,7 +1245,7 @@
 	if (tb->thrown[i]) {
 	    blocknr = tb->thrown[i]->b_blocknr ;
 	    if (buffer_dirty (tb->thrown[i]))
-	      printk ("free_thrown deals with dirty buffer %ld\n", blocknr);
+	      reiserfs_warning (tb->tb_sb, "free_thrown deals with dirty buffer %ld\n", blocknr);
 	    brelse(tb->thrown[i]) ; /* incremented in store_thrown */
 	    reiserfs_free_block (tb->transaction_handle, blocknr);
 	}
@@ -1356,7 +1357,7 @@
 static int locked_or_not_in_tree (struct buffer_head * bh, char * which)
 {
   if ( buffer_locked (bh) || !B_IS_IN_TREE (bh) ) {
-    reiserfs_warning ("vs-12339: locked_or_not_in_tree: %s (%b)\n", which, bh);
+    reiserfs_warning (NULL, "vs-12339: locked_or_not_in_tree: %s (%b)\n", which, bh);
     return 1;
   } 
   return 0;
@@ -1420,7 +1421,7 @@
 		    dc_size(B_N_CHILD (PATH_H_PBUFFER(tb->tb_path,1),
 			PATH_H_POSITION (tb->tb_path, 1))));
 	print_cur_tb ("12223");
-	reiserfs_warning(
+	reiserfs_warning( tb->tb_sb, 
 	    "B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0)) = %d; "
     	    "MAX_CHILD_SIZE (%d) - dc_size( %y, %d ) [%d] = %d\n",
 	    left,
@@ -1579,7 +1580,7 @@
     }
     /* if we have no real work to do  */
     if ( ! tb->insert_size[0] ) {
-	reiserfs_warning ("PAP-12350: do_balance: insert_size == 0, mode == %c",
+	reiserfs_warning (tb->tb_sb, "PAP-12350: do_balance: insert_size == 0, mode == %c\n ",
 			  flag);
 	unfix_nodes(tb);
 	return;
diff -urN linux-2.4.22-pre2/fs/reiserfs/fix_node.c linux-2.4.22-pre3/fs/reiserfs/fix_node.c
--- linux-2.4.22-pre2/fs/reiserfs/fix_node.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/fs/reiserfs/fix_node.c	2003-07-05 18:11:06.000000000 -0700
@@ -483,7 +483,7 @@
 	snum012[needed_nodes - 1 + 3] = units;
 
 	if (needed_nodes > 2)
-	    reiserfs_warning ("vs-8111: get_num_ver: split_item_position is out of boundary\n");
+	    reiserfs_warning (tb->tb_sb, "vs-8111: get_num_ver: split_item_position is out of boundary\n");
 	snum012[needed_nodes - 1] ++;
 	split_item_positions[needed_nodes - 1] = i;
 	needed_nodes ++;
@@ -510,7 +510,7 @@
 	snum012[4] = op_unit_num (&vn->vn_vi[split_item_num]) - snum012[4] - bytes_to_r - bytes_to_l - bytes_to_S1new;
 
 	if (vn->vn_vi[split_item_num].vi_index != TYPE_DIRENTRY)
-	    reiserfs_warning ("vs-8115: get_num_ver: not directory item\n");
+	    reiserfs_warning (tb->tb_sb, "vs-8115: get_num_ver: not directory item\n");
     }
 
     /* now we know S2bytes, calculate S1bytes */
@@ -810,7 +810,7 @@
     if (atomic_read (&(p_s_new_bh->b_count)) > 1) {
 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
 /*
-      reiserfs_warning ("waiting for buffer %b, iput inode pid = %d, this pid %d, mode %c, %h\n",
+      reiserfs_warning (p_s_sb, "waiting for buffer %b, iput inode pid = %d, this pid %d, mode %c, %h\n",
 			p_s_new_bh, put_inode_pid, current->pid, p_s_tb->tb_vn->vn_mode, p_s_tb->tb_vn->vn_ins_ih);
       print_tb (0, 0, 0, p_s_tb, "tb");
 */
@@ -1990,7 +1990,7 @@
     if (vp) {
 	s->u.reiserfs_sb.s_kmallocs += size;
 	if (s->u.reiserfs_sb.s_kmallocs > malloced + 200000) {
-	    reiserfs_warning ("vs-8301: reiserfs_kmalloc: allocated memory %d\n", s->u.reiserfs_sb.s_kmallocs);
+	    reiserfs_warning (s, "vs-8301: reiserfs_kmalloc: allocated memory %d\n", s->u.reiserfs_sb.s_kmallocs);
 	    malloced = s->u.reiserfs_sb.s_kmallocs;
 	}
     }
@@ -2000,11 +2000,13 @@
 
 void reiserfs_kfree (const void * vp, size_t size, struct super_block * s)
 {
+    if (!vp)
+        return;
     kfree (vp);
   
     s->u.reiserfs_sb.s_kmallocs -= size;
     if (s->u.reiserfs_sb.s_kmallocs < 0)
-	reiserfs_warning ("vs-8302: reiserfs_kfree: allocated memory %d\n", s->u.reiserfs_sb.s_kmallocs);
+	reiserfs_warning (s, "vs-8302: reiserfs_kfree: allocated memory %d\n", s->u.reiserfs_sb.s_kmallocs);
 
 }
 #endif
@@ -2064,7 +2066,7 @@
 	    buf = reiserfs_kmalloc(size, GFP_NOFS, tb->tb_sb);
 	    if ( !buf ) {
 #ifdef CONFIG_REISERFS_CHECK
-		reiserfs_warning ("vs-8345: get_mem_for_virtual_node: "
+		reiserfs_warning (tb->tb_sb, "vs-8345: get_mem_for_virtual_node: "
 				  "kmalloc failed. reiserfs kmalloced %d bytes\n",
 				  tb->tb_sb->u.reiserfs_sb.s_kmallocs);
 #endif
@@ -2229,7 +2231,7 @@
 #ifdef CONFIG_REISERFS_CHECK
 	    repeat_counter++;
 	    if ( (repeat_counter % 10000) == 0) {
-		reiserfs_warning ("wait_tb_buffers_until_released(): too many iterations waiting for buffer to unlock (%b)\n", locked);
+		reiserfs_warning (p_s_tb->tb_sb, "wait_tb_buffers_until_released(): too many iterations waiting for buffer to unlock (%b)\n", locked);
 
 		/* Don't loop forever.  Try to recover from possible error. */
 
diff -urN linux-2.4.22-pre2/fs/reiserfs/inode.c linux-2.4.22-pre3/fs/reiserfs/inode.c
--- linux-2.4.22-pre2/fs/reiserfs/inode.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/fs/reiserfs/inode.c	2003-07-05 18:11:06.000000000 -0700
@@ -748,7 +748,7 @@
 		retval = convert_tail_for_hole(inode, bh_result, tail_offset) ;
 		if (retval) {
 		    if ( retval != -ENOSPC )
-			printk("clm-6004: convert tail failed inode %lu, error %d\n", inode->i_ino, retval) ;
+			reiserfs_warning(inode->i_sb, "clm-6004: convert tail failed inode %lu, error %d\n", inode->i_ino, retval) ;
 		    if (allocated_block_nr) {
 			/* the bitmap, the super, and the stat data == 3 */
 			journal_begin(&th, inode->i_sb, 3) ;
@@ -798,7 +798,11 @@
 	       pointer to 'block'-th block use block, which is already
 	       allocated */
 	    struct cpu_key tmp_key;
-	    struct unfm_nodeinfo un = {0, 0};
+	    unp_t unf_single=0; // We use this in case we need to allocate only
+				// one block which is a fastpath
+	    unp_t *un;
+	    __u64 max_to_insert=MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE;
+	    __u64 blocks_needed;
 
 	    RFALSE( pos_in_item != ih_item_len(ih) / UNFM_P_SIZE,
 		    "vs-804: invalid position for append");
@@ -807,30 +811,58 @@
 			  le_key_k_offset (version, &(ih->ih_key)) + op_bytes_number (ih, inode->i_sb->s_blocksize),
 			  //pos_in_item * inode->i_sb->s_blocksize,
 			  TYPE_INDIRECT, 3);// key type is unimportant
-		  
-	    if (cpu_key_k_offset (&tmp_key) == cpu_key_k_offset (&key)) {
+
+	    blocks_needed = 1 + ((cpu_key_k_offset (&key) - cpu_key_k_offset (&tmp_key)) >> inode->i_sb->s_blocksize_bits);
+	    RFALSE( blocks_needed < 0, "green-805: invalid offset");
+
+	    if ( blocks_needed == 1 ) {
+		un = &unf_single;
+	    } else {
+		un=kmalloc( min(blocks_needed,max_to_insert)*UNFM_P_SIZE,
+			    GFP_ATOMIC); // We need to avoid scheduling.
+		if ( !un) {
+		    un = &unf_single;
+		    blocks_needed = 1;
+		    max_to_insert = 0;
+		} else
+		    memset(un, 0, UNFM_P_SIZE * min(blocks_needed,max_to_insert));
+	    }
+	    if ( blocks_needed <= max_to_insert) {
 		/* we are going to add target block to the file. Use allocated
 		   block for that */
-		un.unfm_nodenum = cpu_to_le32 (allocated_block_nr);
+		un[blocks_needed-1] = cpu_to_le32 (allocated_block_nr);
 		set_block_dev_mapped (bh_result, allocated_block_nr, inode);
 		bh_result->b_state |= (1UL << BH_New);
 		done = 1;
 	    } else {
 		/* paste hole to the indirect item */
+		/* If kmalloc failed, max_to_insert becomes zero and it means we
+		   only have space for one block */
+		blocks_needed=max_to_insert?max_to_insert:1;
 	    }
-	    retval = reiserfs_paste_into_item (&th, &path, &tmp_key, (char *)&un, UNFM_P_SIZE);
+	    retval = reiserfs_paste_into_item (&th, &path, &tmp_key, (char *)un, UNFM_P_SIZE * blocks_needed);
+
+	    if (blocks_needed != 1)
+		 kfree(un);
+
 	    if (retval) {
 		reiserfs_free_block (&th, allocated_block_nr);
 		goto failure;
 	    }
-	    if (un.unfm_nodenum)
+	    if (done) {
 		inode->i_blocks += inode->i_sb->s_blocksize / 512;
+	    } else {
+		/* We need to mark new file size in case this function will be
+		   interrupted/aborted later on. And we may do this only for
+		   holes. */
+		inode->i_size += blocks_needed << inode->i_blkbits;
+	    }
 	    //mark_tail_converted (inode);
 	}
-		
+
 	if (done == 1)
 	    break;
-	 
+
 	/* this loop could log more blocks than we had originally asked
 	** for.  So, we have to allow the transaction to end if it is
 	** too big or too full.  Update the inode so things are 
@@ -854,7 +886,7 @@
 	    goto failure;
 	}
 	if (retval == POSITION_FOUND) {
-	    reiserfs_warning ("vs-825: reiserfs_get_block: "
+	    reiserfs_warning (inode->i_sb, "vs-825: reiserfs_get_block: "
 			      "%K should not be found\n", &key);
 	    retval = -EEXIST;
 	    if (allocated_block_nr)
@@ -1085,8 +1117,8 @@
 	/* look for the object's stat data */
 	retval = search_item (inode->i_sb, &key, &path);
 	if (retval == IO_ERROR) {
-	    reiserfs_warning ("vs-13050: reiserfs_update_sd: "
-			      "i/o failure occurred trying to update %K stat data",
+	    reiserfs_warning (inode->i_sb, "vs-13050: reiserfs_update_sd: "
+			      "i/o failure occurred trying to update %K stat data\n",
 			      &key);
 	    return;
 	}
@@ -1097,7 +1129,7 @@
 		/*printk ("vs-13050: reiserfs_update_sd: i_nlink == 0, stat data not found\n");*/
 		return;
 	    }
-	    reiserfs_warning ("vs-13060: reiserfs_update_sd: "
+	    reiserfs_warning (inode->i_sb, "vs-13060: reiserfs_update_sd: "
 			      "stat data of object %k (nlink == %d) not found (pos %d)\n", 
 			      INODE_PKEY (inode), inode->i_nlink, pos);
 	    reiserfs_check_path(&path) ;
@@ -1165,7 +1197,7 @@
     /* look for the object's stat data */
     retval = search_item (inode->i_sb, &key, &path_to_sd);
     if (retval == IO_ERROR) {
-	reiserfs_warning ("vs-13070: reiserfs_read_inode2: "
+	reiserfs_warning (inode->i_sb, "vs-13070: reiserfs_read_inode2: "
                     "i/o failure occurred trying to find stat data of %K\n",
                     &key);
 	reiserfs_make_bad_inode(inode) ;
@@ -1197,7 +1229,7 @@
        during mount (fs/reiserfs/super.c:finish_unfinished()). */
     if( ( inode -> i_nlink == 0 ) && 
 	! inode -> i_sb -> u.reiserfs_sb.s_is_unlinked_ok ) {
-	    reiserfs_warning( "vs-13075: reiserfs_read_inode2: "
+	    reiserfs_warning( inode->i_sb, "vs-13075: reiserfs_read_inode2: "
 			      "dead inode read from disk %K. "
 			      "This is likely to be race with knfsd. Ignore\n", 
 			      &key );
@@ -1288,7 +1320,7 @@
      */
     if (fhtype > len) {
 	    if (fhtype != 6 || len != 5)
-		    printk(KERN_WARNING "nfsd/reiserfs, fhtype=%d, len=%d - odd\n",
+		    reiserfs_warning(sb, "nfsd/reiserfs, fhtype=%d, len=%d - odd\n",
 			   fhtype, len);
 	    fhtype = 5;
     }
@@ -1387,7 +1419,7 @@
     int jbegin_count = 1 ;
 
     if (inode->i_sb->s_flags & MS_RDONLY) {
-        reiserfs_warning("clm-6005: writing inode %lu on readonly FS\n", 
+        reiserfs_warning(inode->i_sb, "clm-6005: writing inode %lu on readonly FS\n", 
 	                  inode->i_ino) ;
         return ;
     }
@@ -1450,14 +1482,14 @@
     /* look for place in the tree for new item */
     retval = search_item (sb, &key, path);
     if (retval == IO_ERROR) {
-	reiserfs_warning ("vs-13080: reiserfs_new_directory: "
+	reiserfs_warning (sb, "vs-13080: reiserfs_new_directory: "
 			  "i/o failure occurred creating new directory\n");
 	return -EIO;
     }
     if (retval == ITEM_FOUND) {
 	pathrelse (path);
-	reiserfs_warning ("vs-13070: reiserfs_new_directory: "
-			  "object with this key exists (%k)", &(ih->ih_key));
+	reiserfs_warning (sb, "vs-13070: reiserfs_new_directory: "
+			  "object with this key exists (%k)\n", &(ih->ih_key));
 	return -EEXIST;
     }
 
@@ -1486,14 +1518,14 @@
     /* look for place in the tree for new item */
     retval = search_item (sb, &key, path);
     if (retval == IO_ERROR) {
-	reiserfs_warning ("vs-13080: reiserfs_new_symlinik: "
+	reiserfs_warning (sb, "vs-13080: reiserfs_new_symlinik: "
 			  "i/o failure occurred creating new symlink\n");
 	return -EIO;
     }
     if (retval == ITEM_FOUND) {
 	pathrelse (path);
-	reiserfs_warning ("vs-13080: reiserfs_new_symlink: "
-			  "object with this key exists (%k)", &(ih->ih_key));
+	reiserfs_warning (sb, "vs-13080: reiserfs_new_symlink: "
+			  "object with this key exists (%k)\n", &(ih->ih_key));
 	return -EEXIST;
     }
 
@@ -1751,8 +1783,8 @@
 	** I've screwed up the code to find the buffer, or the code to
 	** call prepare_write
 	*/
-	reiserfs_warning("clm-6000: error reading block %lu on dev %s\n",
-	                  bh->b_blocknr, kdevname(bh->b_dev)) ;
+	reiserfs_warning(p_s_inode->i_sb, "clm-6000: error reading block %lu\n",
+	                  bh->b_blocknr) ;
 	error = -EIO ;
 	goto unlock ;
     }
@@ -1792,7 +1824,7 @@
 	    // and get_block_create_0 could not find a block to read in,
 	    // which is ok.
 	    if (error != -ENOENT)
-	        reiserfs_warning("clm-6001: grab_tail_page failed %d\n", error);
+	        reiserfs_warning(p_s_inode->i_sb, "clm-6001: grab_tail_page failed %d\n", error);
 	    page = NULL ;
 	    bh = NULL ;
 	}
@@ -1889,7 +1921,7 @@
     /* we've found an unformatted node */
     if (indirect_item_found(retval, ih)) {
 	if (bytes_copied > 0) {
-	    reiserfs_warning("clm-6002: bytes_copied %d\n", bytes_copied) ;
+	    reiserfs_warning(inode->i_sb, "clm-6002: bytes_copied %d\n", bytes_copied) ;
 	}
         if (!get_block_num(item, pos_in_item)) {
 	    /* crap, we are writing to a hole */
@@ -1926,7 +1958,7 @@
 	    goto research ;
 	}
     } else {
-        reiserfs_warning("clm-6003: bad item inode %lu, device %s\n", inode->i_ino, kdevname(inode->i_sb->s_dev)) ;
+        reiserfs_warning(inode->i_sb, "clm-6003: bad item inode %lu\n", inode->i_ino) ;
         retval = -EIO ;
 	goto out ;
     }
@@ -2048,6 +2080,7 @@
     */
     if (nr) {
         submit_bh_for_writepage(arr, nr) ;
+	wakeup_page_waiters(page);
     } else {
         UnlockPage(page) ;
     }
diff -urN linux-2.4.22-pre2/fs/reiserfs/item_ops.c linux-2.4.22-pre3/fs/reiserfs/item_ops.c
--- linux-2.4.22-pre2/fs/reiserfs/item_ops.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/reiserfs/item_ops.c	2003-07-05 18:11:06.000000000 -0700
@@ -106,7 +106,7 @@
 
 static void sd_print_vi (struct virtual_item * vi)
 {
-    reiserfs_warning ("STATDATA, index %d, type 0x%x, %h\n", 
+    reiserfs_warning (NULL, "STATDATA, index %d, type 0x%x, %h\n", 
 		      vi->vi_index, vi->vi_type, vi->vi_ih);
 }
 
@@ -209,7 +209,7 @@
 
 static void direct_print_vi (struct virtual_item * vi)
 {
-    reiserfs_warning ("DIRECT, index %d, type 0x%x, %h\n", 
+    reiserfs_warning (NULL, "DIRECT, index %d, type 0x%x, %h\n", 
 		      vi->vi_index, vi->vi_type, vi->vi_ih);
 }
 
@@ -363,7 +363,7 @@
 
 static void indirect_print_vi (struct virtual_item * vi)
 {
-    reiserfs_warning ("INDIRECT, index %d, type 0x%x, %h\n", 
+    reiserfs_warning (NULL, "INDIRECT, index %d, type 0x%x, %h\n", 
 		      vi->vi_index, vi->vi_type, vi->vi_ih);
 }
 
@@ -390,7 +390,7 @@
 
 static int direntry_bytes_number (struct item_head * ih, int block_size)
 {
-    reiserfs_warning ("vs-16090: direntry_bytes_number: "
+    reiserfs_warning (NULL, "vs-16090: direntry_bytes_number: "
 		      "bytes number is asked for direntry");
     return 0;
 }
@@ -653,7 +653,7 @@
     int i;
     struct direntry_uarea * dir_u = vi->vi_uarea;
 
-    reiserfs_warning ("DIRENTRY, index %d, type 0x%x, %h, flags 0x%x\n", 
+    reiserfs_warning (NULL, "DIRENTRY, index %d, type 0x%x, %h, flags 0x%x\n", 
 		      vi->vi_index, vi->vi_type, vi->vi_ih, dir_u->flags);
     printk ("%d entries: ", dir_u->entry_count);
     for (i = 0; i < dir_u->entry_count; i ++)
@@ -682,32 +682,32 @@
 //
 static int errcatch_bytes_number (struct item_head * ih, int block_size)
 {
-    reiserfs_warning ("green-16001: Invalid item type observed, run fsck ASAP\n");
+    reiserfs_warning (NULL, "green-16001: Invalid item type observed, run fsck ASAP\n");
     return 0;
 }
 
 static void errcatch_decrement_key (struct cpu_key * key)
 {
-    reiserfs_warning ("green-16002: Invalid item type observed, run fsck ASAP\n");
+    reiserfs_warning (NULL, "green-16002: Invalid item type observed, run fsck ASAP\n");
 }
 
 
 static int errcatch_is_left_mergeable (struct key * key, unsigned long bsize)
 {
-    reiserfs_warning ("green-16003: Invalid item type observed, run fsck ASAP\n");
+    reiserfs_warning (NULL, "green-16003: Invalid item type observed, run fsck ASAP\n");
     return 0;
 }
 
 
 static void errcatch_print_item (struct item_head * ih, char * item)
 {
-    reiserfs_warning ("green-16004: Invalid item type observed, run fsck ASAP\n");
+    reiserfs_warning (NULL, "green-16004: Invalid item type observed, run fsck ASAP\n");
 }
 
 
 static void errcatch_check_item (struct item_head * ih, char * item)
 {
-    reiserfs_warning ("green-16005: Invalid item type observed, run fsck ASAP\n");
+    reiserfs_warning (NULL, "green-16005: Invalid item type observed, run fsck ASAP\n");
 }
 
 static int errcatch_create_vi (struct virtual_node * vn,
@@ -715,7 +715,7 @@
 			       int is_affected, 
 			       int insert_size)
 {
-    reiserfs_warning ("green-16006: Invalid item type observed, run fsck ASAP\n");
+    reiserfs_warning (NULL, "green-16006: Invalid item type observed, run fsck ASAP\n");
     return 0;	// We might return -1 here as well, but it won't help as create_virtual_node() from where
 		// this operation is called from is of return type void.
 }
@@ -723,32 +723,32 @@
 static int errcatch_check_left (struct virtual_item * vi, int free,
 				int start_skip, int end_skip)
 {
-    reiserfs_warning ("green-16007: Invalid item type observed, run fsck ASAP\n");
+    reiserfs_warning (NULL, "green-16007: Invalid item type observed, run fsck ASAP\n");
     return -1;
 }
 
 
 static int errcatch_check_right (struct virtual_item * vi, int free)
 {
-    reiserfs_warning ("green-16008: Invalid item type observed, run fsck ASAP\n");
+    reiserfs_warning (NULL, "green-16008: Invalid item type observed, run fsck ASAP\n");
     return -1;
 }
 
 static int errcatch_part_size (struct virtual_item * vi, int first, int count)
 {
-    reiserfs_warning ("green-16009: Invalid item type observed, run fsck ASAP\n");
+    reiserfs_warning (NULL, "green-16009: Invalid item type observed, run fsck ASAP\n");
     return 0;
 }
 
 static int errcatch_unit_num (struct virtual_item * vi)
 {
-    reiserfs_warning ("green-16010: Invalid item type observed, run fsck ASAP\n");
+    reiserfs_warning (NULL, "green-16010: Invalid item type observed, run fsck ASAP\n");
     return 0;
 }
 
 static void errcatch_print_vi (struct virtual_item * vi)
 {
-    reiserfs_warning ("green-16011: Invalid item type observed, run fsck ASAP\n");
+    reiserfs_warning (NULL, "green-16011: Invalid item type observed, run fsck ASAP\n");
 }
 
 struct item_operations errcatch_ops = {
diff -urN linux-2.4.22-pre2/fs/reiserfs/journal.c linux-2.4.22-pre3/fs/reiserfs/journal.c
--- linux-2.4.22-pre2/fs/reiserfs/journal.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/fs/reiserfs/journal.c	2003-07-05 18:11:07.000000000 -0700
@@ -96,7 +96,8 @@
 static int can_dirty(struct reiserfs_journal_cnode *cn) ;
 static int remove_from_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, struct buffer_head *bh, int remove_freed);
 static int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks);
-
+static int release_journal_dev( struct super_block *super,
+				struct reiserfs_journal *journal );
 static void init_journal_hash(struct super_block *p_s_sb) {
   memset(SB_JOURNAL(p_s_sb)->j_hash_table, 0, JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ;
 }
@@ -255,7 +256,7 @@
     jb->journal_list = NULL ;
     jb->bitmaps = vmalloc( mem ) ;
     if (!jb->bitmaps) {
-      reiserfs_warning("clm-2000, unable to allocate bitmaps for journal lists\n") ;
+      reiserfs_warning(p_s_sb, "clm-2000, unable to allocate bitmaps for journal lists\n") ;
       failed = 1;   
       break ;
     }
@@ -669,7 +670,7 @@
   atomic_set(&(jl->j_commit_flushing), 1) ; 
 
 
-  if (jl->j_len > JOURNAL_TRANS_MAX) {
+  if (jl->j_len > SB_JOURNAL_TRANS_MAX(s)) {
     reiserfs_panic(s, "journal-512: flush_commit_list: length is %lu, list number %d\n", jl->j_len, jl - SB_JOURNAL_LIST(s)) ;
     return 0 ;
   }
@@ -683,8 +684,8 @@
 retry:
   count = 0 ;
   for (i = 0 ; atomic_read(&(jl->j_commit_left)) > 1 && i < (jl->j_len + 1) ; i++) {  /* everything but commit_bh */
-    bn = reiserfs_get_journal_block(s) + (jl->j_start+i) % JOURNAL_BLOCK_COUNT;
-    tbh = sb_get_hash_table(s, bn) ;
+    bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start+i) %  SB_ONDISK_JOURNAL_SIZE(s);
+    tbh = journal_get_hash_table(s, bn) ;
 
 /* kill this sanity check */
 if (count > (orig_commit_left + 2)) {
@@ -698,7 +699,7 @@
 	}
       } 
       if (buffer_dirty(tbh)) {
-	printk("journal-569: flush_commit_list, block already dirty!\n") ;
+	reiserfs_warning(s, "journal-569: flush_commit_list, block already dirty!\n") ;
       } else {				
 	mark_buffer_dirty(tbh) ;
       }
@@ -712,8 +713,8 @@
   if (count > 0) {
     for (i = 0 ; atomic_read(&(jl->j_commit_left)) > 1 && 
                  i < (jl->j_len + 1) ; i++) {  /* everything but commit_bh */
-      bn = reiserfs_get_journal_block(s) + (jl->j_start + i) % JOURNAL_BLOCK_COUNT  ;
-      tbh = sb_get_hash_table(s, bn) ;
+      bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s) ;
+      tbh = journal_get_hash_table(s, bn) ;
 
       wait_on_buffer(tbh) ;
       if (!buffer_uptodate(tbh)) {
@@ -727,7 +728,7 @@
 
   if (atomic_read(&(jl->j_commit_left)) != 1) { /* just the commit_bh left, flush it without calling getblk for everyone */
     if (retry_count < 2) {
-      printk("journal-582: flush_commit_list, not all log blocks on disk yet, trying again\n") ;
+      reiserfs_warning(s, "journal-582: flush_commit_list, not all log blocks on disk yet, trying again\n") ;
       retry_count++ ;
       goto retry;
     }
@@ -792,7 +793,7 @@
   while(cn) {
     if (cn->blocknr != 0) {
       if (debug) {
-        printk("block %lu, bh is %d, state %ld\n", cn->blocknr, cn->bh ? 1: 0, 
+        reiserfs_warning(p_s_sb, "block %lu, bh is %d, state %ld\n", cn->blocknr, cn->bh ? 1: 0, 
 	        cn->state) ;
       }
       fake_bh.b_blocknr = cn->blocknr ;
@@ -833,7 +834,7 @@
     ll_rw_block(WRITE, 1, &(SB_JOURNAL(p_s_sb)->j_header_bh)) ;
     wait_on_buffer((SB_JOURNAL(p_s_sb)->j_header_bh)) ; 
     if (!buffer_uptodate(SB_JOURNAL(p_s_sb)->j_header_bh)) {
-      printk( "reiserfs: journal-837: IO error during journal replay\n" );
+      reiserfs_warning( p_s_sb, "reiserfs: journal-837: IO error during journal replay\n" );
       return -EIO ;
     }
   }
@@ -872,7 +873,7 @@
 
 static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate) {
     if (buffer_journaled(bh)) {
-        reiserfs_warning("clm-2084: pinned buffer %lu:%s sent to disk\n",
+        reiserfs_warning(NULL, "clm-2084: pinned buffer %lu:%s sent to disk\n",
 	                 bh->b_blocknr, kdevname(bh->b_dev)) ;
     }
     mark_buffer_uptodate(bh, uptodate) ;
@@ -912,7 +913,7 @@
   }
 
   if (atomic_read(&SB_JOURNAL(s)->j_wcount) != 0) {
-    reiserfs_warning("clm-2048: flush_journal_list called with wcount %d\n",
+    reiserfs_warning(s, "clm-2048: flush_journal_list called with wcount %d\n",
                       atomic_read(&SB_JOURNAL(s)->j_wcount)) ;
   }
   /* if someone is getting the commit list, we must wait for them */
@@ -928,7 +929,7 @@
   atomic_set(&(jl->j_flushing), 1) ;
 
   count = 0 ;
-  if (j_len_saved > JOURNAL_TRANS_MAX) {
+  if (j_len_saved > SB_JOURNAL_TRANS_MAX(s)) {
     reiserfs_panic(s, "journal-715: flush_journal_list, length is %lu, list number %d\n", j_len_saved, jl - SB_JOURNAL_LIST(s)) ;
     atomic_dec(&(jl->j_flushing)) ;
     return 0 ;
@@ -1010,14 +1011,14 @@
     ** is not marked JDirty_wait
     */
     if ((!was_jwait) && !buffer_locked(saved_bh)) {
-printk("journal-813: BAD! buffer %lu %cdirty %cjwait, not in a newer tranasction\n", saved_bh->b_blocknr,
+reiserfs_warning(s, "journal-813: BAD! buffer %lu %cdirty %cjwait, not in a newer tranasction\n", saved_bh->b_blocknr,
         was_dirty ? ' ' : '!', was_jwait ? ' ' : '!') ;
     }
     /* kupdate_one_transaction waits on the buffers it is writing, so we
     ** should never see locked buffers here
     */
     if (buffer_locked(saved_bh)) {
-      printk("clm-2083: locked buffer %lu in flush_journal_list\n", 
+      reiserfs_warning(s, "clm-2083: locked buffer %lu in flush_journal_list\n", 
               saved_bh->b_blocknr) ;
       wait_on_buffer(saved_bh) ;
       if (!buffer_uptodate(saved_bh)) {
@@ -1031,7 +1032,7 @@
       submit_logged_buffer(saved_bh) ;
       count++ ;
     } else {
-      printk("clm-2082: Unable to flush buffer %lu in flush_journal_list\n",
+      reiserfs_warning(s, "clm-2082: Unable to flush buffer %lu in flush_journal_list\n",
               saved_bh->b_blocknr) ;
     }
 free_cnode:
@@ -1041,7 +1042,7 @@
       /* we incremented this to keep others from taking the buffer head away */
       put_bh(saved_bh) ;
       if (atomic_read(&(saved_bh->b_count)) < 0) {
-        printk("journal-945: saved_bh->b_count < 0") ;
+        reiserfs_warning(s, "journal-945: saved_bh->b_count < 0\n") ;
       }
     }
   }
@@ -1085,7 +1086,7 @@
   ** being flushed
   */
   if (flushall) {
-    update_journal_header_block(s, (jl->j_start + jl->j_len + 2) % JOURNAL_BLOCK_COUNT, jl->j_trans_id) ;
+    update_journal_header_block(s, (jl->j_start + jl->j_len + 2) % SB_ONDISK_JOURNAL_SIZE(s), jl->j_trans_id) ;
   }
   remove_all_from_journal_list(s, jl, 0) ;
   jl->j_len = 0 ;
@@ -1189,7 +1190,7 @@
                     walk_cn = walk_cn->hnext ;
                 }
                 if (atomic_read(&saved_bh->b_count) < 1) {
-                    reiserfs_warning("clm-2081: bad count on %lu\n", 
+                    reiserfs_warning(s, "clm-2081: bad count on %lu\n", 
                                       saved_bh->b_blocknr) ;
                 }
                 brelse(saved_bh) ;
@@ -1312,6 +1313,10 @@
   if (SB_JOURNAL(p_s_sb)->j_header_bh) {
     brelse(SB_JOURNAL(p_s_sb)->j_header_bh) ;
   }
+  /* j_header_bh is on the journal dev, make sure not to release the journal
+   * dev until we brelse j_header_bh
+   */
+  release_journal_dev(p_s_sb, SB_JOURNAL(p_s_sb));
   vfree(SB_JOURNAL(p_s_sb)) ;
 }
 
@@ -1365,7 +1370,7 @@
 			               struct reiserfs_journal_commit *commit) {
   if (le32_to_cpu(commit->j_trans_id) != le32_to_cpu(desc->j_trans_id) || 
       le32_to_cpu(commit->j_len) != le32_to_cpu(desc->j_len) || 
-      le32_to_cpu(commit->j_len) > JOURNAL_TRANS_MAX || 
+      le32_to_cpu(commit->j_len) > SB_JOURNAL_TRANS_MAX(p_s_sb) || 
       le32_to_cpu(commit->j_len) <= 0 
   ) {
     return 1 ;
@@ -1401,14 +1406,15 @@
 		     *newest_mount_id) ;
       return -1 ;
     }
-    if ( le32_to_cpu(desc->j_len) > JOURNAL_TRANS_MAX ) {
-      reiserfs_warning("journal-2018: Bad transaction length %d encountered, ignoring transaction\n", le32_to_cpu(desc->j_len));
+    if ( le32_to_cpu(desc->j_len) > SB_JOURNAL_TRANS_MAX(p_s_sb) ) {
+      reiserfs_warning(p_s_sb, "journal-2018: Bad transaction length %d encountered, ignoring transaction\n", le32_to_cpu(desc->j_len));
       return -1 ;
     }
-    offset = d_bh->b_blocknr - reiserfs_get_journal_block(p_s_sb) ;
+    offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
 
     /* ok, we have a journal description block, lets see if the transaction was valid */
-    c_bh = sb_bread(p_s_sb, reiserfs_get_journal_block(p_s_sb) + ((offset + le32_to_cpu(desc->j_len) + 1) % JOURNAL_BLOCK_COUNT)) ;
+    c_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+		 ((offset + le32_to_cpu(desc->j_len) + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
     if (!c_bh)
       return 0 ;
     commit = (struct reiserfs_journal_commit *)c_bh->b_data ;
@@ -1416,7 +1422,7 @@
       reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, 
                      "journal_transaction_is_valid, commit offset %ld had bad "
 		     "time %d or length %d\n", 
-		     c_bh->b_blocknr - reiserfs_get_journal_block(p_s_sb),
+		     c_bh->b_blocknr -  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
 		     le32_to_cpu(commit->j_trans_id), 
 		     le32_to_cpu(commit->j_len));
       brelse(c_bh) ;
@@ -1431,7 +1437,7 @@
     brelse(c_bh) ;
     reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1006: found valid "
                    "transaction start offset %lu, len %d id %d\n", 
-		   d_bh->b_blocknr - reiserfs_get_journal_block(p_s_sb), 
+		   d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
 		   le32_to_cpu(desc->j_len), le32_to_cpu(desc->j_trans_id)) ;
     return 1 ;
   } else {
@@ -1463,19 +1469,19 @@
   unsigned long trans_offset ;
   int i;
 
-  d_bh = sb_bread(p_s_sb, cur_dblock) ;
+  d_bh = journal_bread(p_s_sb, cur_dblock) ;
   if (!d_bh)
     return 1 ;
   desc = (struct reiserfs_journal_desc *)d_bh->b_data ;
-  trans_offset = d_bh->b_blocknr - reiserfs_get_journal_block(p_s_sb) ;
+  trans_offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
   reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1037: "
                  "journal_read_transaction, offset %lu, len %d mount_id %d\n", 
-		 d_bh->b_blocknr - reiserfs_get_journal_block(p_s_sb), 
+		 d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
 		 le32_to_cpu(desc->j_len), le32_to_cpu(desc->j_mount_id)) ;
   if (le32_to_cpu(desc->j_trans_id) < oldest_trans_id) {
     reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1039: "
                    "journal_read_trans skipping because %lu is too old\n", 
-		   cur_dblock - reiserfs_get_journal_block(p_s_sb)) ;
+		   cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb)) ;
     brelse(d_bh) ;
     return 1 ;
   }
@@ -1487,7 +1493,9 @@
     brelse(d_bh) ;
     return 1 ;
   }
-  c_bh = sb_bread(p_s_sb, reiserfs_get_journal_block(p_s_sb) + ((trans_offset + le32_to_cpu(desc->j_len) + 1) % JOURNAL_BLOCK_COUNT)) ;
+  c_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+		((trans_offset + le32_to_cpu(desc->j_len) + 1) % 
+		 SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
   if (!c_bh) {
     brelse(d_bh) ;
     return 1 ;
@@ -1496,7 +1504,7 @@
   if (journal_compare_desc_commit(p_s_sb, desc, commit)) {
     reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal_read_transaction, "
                    "commit offset %ld had bad time %d or length %d\n", 
-		   c_bh->b_blocknr - reiserfs_get_journal_block(p_s_sb), 
+		   c_bh->b_blocknr -  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
 		   le32_to_cpu(commit->j_trans_id), le32_to_cpu(commit->j_len));
     brelse(c_bh) ;
     brelse(d_bh) ;
@@ -1511,24 +1519,24 @@
     brelse(d_bh) ;
     reiserfs_kfree(log_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
     reiserfs_kfree(real_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
-    reiserfs_warning("journal-1169: kmalloc failed, unable to mount FS\n") ;
+    reiserfs_warning(p_s_sb, "journal-1169: kmalloc failed, unable to mount FS\n") ;
     return -1 ;
   }
   /* get all the buffer heads */
   for(i = 0 ; i < le32_to_cpu(desc->j_len) ; i++) {
-    log_blocks[i] = sb_getblk(p_s_sb, reiserfs_get_journal_block(p_s_sb) + (trans_offset + 1 + i) % JOURNAL_BLOCK_COUNT);
+    log_blocks[i] = journal_getblk(p_s_sb,  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + (trans_offset + 1 + i) % SB_ONDISK_JOURNAL_SIZE(p_s_sb));
     if (i < JOURNAL_TRANS_HALF) {
       real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(desc->j_realblock[i])) ;
     } else {
       real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(commit->j_realblock[i - JOURNAL_TRANS_HALF])) ;
     }
     if ( real_blocks[i]->b_blocknr > SB_BLOCK_COUNT(p_s_sb) ) {
-      reiserfs_warning("journal-1207: REPLAY FAILURE fsck required! Block to replay is outside of filesystem\n");
+      reiserfs_warning(p_s_sb, "journal-1207: REPLAY FAILURE fsck required! Block to replay is outside of filesystem\n");
       goto abort_replay;
     }
-    if (real_blocks[i]->b_blocknr >= reiserfs_get_journal_block(p_s_sb) &&
-        real_blocks[i]->b_blocknr < (reiserfs_get_journal_block(p_s_sb)+JOURNAL_BLOCK_COUNT)) {
-      reiserfs_warning("journal-1204: REPLAY FAILURE fsck required! Trying to replay onto a log block\n") ;
+    /* make sure we don't try to replay onto log or reserved area */
+    if (is_block_in_log_or_reserved_area(p_s_sb, real_blocks[i]->b_blocknr)) {
+      reiserfs_warning(p_s_sb, "journal-1204: REPLAY FAILURE fsck required! Trying to replay onto a log block\n") ;
 abort_replay:
       brelse_array(log_blocks, i) ;
       brelse_array(real_blocks, i) ;
@@ -1544,7 +1552,7 @@
   for (i = 0 ; i < le32_to_cpu(desc->j_len) ; i++) {
     wait_on_buffer(log_blocks[i]) ;
     if (!buffer_uptodate(log_blocks[i])) {
-      reiserfs_warning("journal-1212: REPLAY FAILURE fsck required! buffer write failed\n") ;
+      reiserfs_warning(p_s_sb, "journal-1212: REPLAY FAILURE fsck required! buffer write failed\n") ;
       brelse_array(log_blocks + i, le32_to_cpu(desc->j_len) - i) ;
       brelse_array(real_blocks, le32_to_cpu(desc->j_len)) ;
       brelse(c_bh) ;
@@ -1565,7 +1573,7 @@
   for (i = 0 ; i < le32_to_cpu(desc->j_len) ; i++) {
     wait_on_buffer(real_blocks[i]) ; 
     if (!buffer_uptodate(real_blocks[i])) {
-      reiserfs_warning("journal-1226: REPLAY FAILURE, fsck required! buffer write failed\n") ;
+      reiserfs_warning(p_s_sb, "journal-1226: REPLAY FAILURE, fsck required! buffer write failed\n") ;
       brelse_array(real_blocks + i, le32_to_cpu(desc->j_len) - i) ;
       brelse(c_bh) ;
       brelse(d_bh) ;
@@ -1575,13 +1583,13 @@
     }
     brelse(real_blocks[i]) ;
   }
-  cur_dblock = reiserfs_get_journal_block(p_s_sb) + ((trans_offset + le32_to_cpu(desc->j_len) + 2) % JOURNAL_BLOCK_COUNT) ;
+  cur_dblock =  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + ((trans_offset + le32_to_cpu(desc->j_len) + 2) % SB_ONDISK_JOURNAL_SIZE(p_s_sb)) ;
   reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1095: setting journal "
                  "start to offset %ld\n", 
-		 cur_dblock - reiserfs_get_journal_block(p_s_sb)) ;
+		 cur_dblock -  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb)) ;
   
   /* init starting values for the first transaction, in case this is the last transaction to be replayed. */
-  SB_JOURNAL(p_s_sb)->j_start = cur_dblock - reiserfs_get_journal_block(p_s_sb) ;
+  SB_JOURNAL(p_s_sb)->j_start = cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
   SB_JOURNAL(p_s_sb)->j_last_flush_trans_id = trans_id ;
   SB_JOURNAL(p_s_sb)->j_trans_id = trans_id + 1;
   brelse(c_bh) ;
@@ -1635,6 +1643,13 @@
 	brelse (bh);
 	return NULL;
 }
+
+static struct buffer_head * journal_breada (struct super_block *p_s_sb, int block)
+{
+  return reiserfs_breada (SB_JOURNAL_DEV(p_s_sb), block, p_s_sb->s_blocksize,
+			  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb));
+}
+
 static int journal_read(struct super_block *p_s_sb) {
   struct reiserfs_journal_desc *desc ;
   unsigned long oldest_trans_id = 0;
@@ -1650,26 +1665,29 @@
   int continue_replay = 1 ;
   int ret ;
 
-  cur_dblock = reiserfs_get_journal_block(p_s_sb) ;
+  cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
   printk("reiserfs: checking transaction log (device %s) ...\n",
-          kdevname(p_s_sb->s_dev)) ;
+          bdevname(SB_JOURNAL_DEV(p_s_sb))) ;
+  printk("for (%s)\n",
+	  bdevname(p_s_sb->s_dev)) ;
+
   start = CURRENT_TIME ;
 
   /* step 1, read in the journal header block.  Check the transaction it says 
   ** is the first unflushed, and if that transaction is not valid, 
   ** replay is done
   */
-  SB_JOURNAL(p_s_sb)->j_header_bh = sb_bread(p_s_sb, 
-                                          reiserfs_get_journal_block(p_s_sb) + 
-					  JOURNAL_BLOCK_COUNT) ;
+  SB_JOURNAL(p_s_sb)->j_header_bh = journal_bread(p_s_sb, 
+                                          SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
+					  SB_ONDISK_JOURNAL_SIZE(p_s_sb)) ;
   if (!SB_JOURNAL(p_s_sb)->j_header_bh) {
     return 1 ;
   }
   jh = (struct reiserfs_journal_header *)(SB_JOURNAL(p_s_sb)->j_header_bh->b_data) ;
   if (le32_to_cpu(jh->j_first_unflushed_offset) >= 0 && 
-      le32_to_cpu(jh->j_first_unflushed_offset) < JOURNAL_BLOCK_COUNT &&
+      le32_to_cpu(jh->j_first_unflushed_offset) < SB_ONDISK_JOURNAL_SIZE(p_s_sb) &&
       le32_to_cpu(jh->j_last_flush_trans_id) > 0) {
-    oldest_start = reiserfs_get_journal_block(p_s_sb) + 
+    oldest_start = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
                        le32_to_cpu(jh->j_first_unflushed_offset) ;
     oldest_trans_id = le32_to_cpu(jh->j_last_flush_trans_id) + 1;
     newest_mount_id = le32_to_cpu(jh->j_mount_id);
@@ -1683,7 +1701,7 @@
     ** there is nothing more we can do, and it makes no sense to read 
     ** through the whole log.
     */
-    d_bh = sb_bread(p_s_sb, reiserfs_get_journal_block(p_s_sb) + le32_to_cpu(jh->j_first_unflushed_offset)) ;
+    d_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + le32_to_cpu(jh->j_first_unflushed_offset)) ;
     ret = journal_transaction_is_valid(p_s_sb, d_bh, NULL, NULL) ;
     if (!ret) {
       continue_replay = 0 ;
@@ -1693,7 +1711,7 @@
   }
 
   if (continue_replay && is_read_only(p_s_sb->s_dev)) {
-    printk("clm-2076: device is readonly, unable to replay log\n") ;
+    reiserfs_warning(p_s_sb, "clm-2076: device is readonly, unable to replay log\n") ;
     return -1 ;
   }
   if (continue_replay && (p_s_sb->s_flags & MS_RDONLY)) {
@@ -1703,9 +1721,8 @@
   /* ok, there are transactions that need to be replayed.  start with the first log block, find
   ** all the valid transactions, and pick out the oldest.
   */
-  while(continue_replay && cur_dblock < (reiserfs_get_journal_block(p_s_sb) + JOURNAL_BLOCK_COUNT)) {
-    d_bh = reiserfs_breada(p_s_sb->s_dev, cur_dblock, p_s_sb->s_blocksize,
-			   reiserfs_get_journal_block(p_s_sb) + JOURNAL_BLOCK_COUNT) ;
+  while(continue_replay && cur_dblock < (SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb))) {
+    d_bh = journal_breada(p_s_sb, cur_dblock) ;
     ret = journal_transaction_is_valid(p_s_sb, d_bh, &oldest_invalid_trans_id, &newest_mount_id) ;
     if (ret == 1) {
       desc = (struct reiserfs_journal_desc *)d_bh->b_data ;
@@ -1715,7 +1732,7 @@
 	newest_mount_id = le32_to_cpu(desc->j_mount_id) ;
 	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1179: Setting "
 	               "oldest_start to offset %lu, trans_id %lu\n", 
-		       oldest_start - reiserfs_get_journal_block(p_s_sb), 
+		       oldest_start - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
 		       oldest_trans_id) ;
       } else if (oldest_trans_id > le32_to_cpu(desc->j_trans_id)) { 
         /* one we just read was older */
@@ -1723,7 +1740,7 @@
 	oldest_start = d_bh->b_blocknr ;
 	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1180: Resetting "
 	               "oldest_start to offset %lu, trans_id %lu\n", 
-			oldest_start - reiserfs_get_journal_block(p_s_sb), 
+			oldest_start - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
 			oldest_trans_id) ;
       }
       if (newest_mount_id < le32_to_cpu(desc->j_mount_id)) {
@@ -1743,7 +1760,7 @@
   if (oldest_trans_id)  {
     reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1206: Starting replay "
                    "from offset %lu, trans_id %lu\n", 
-		   cur_dblock - reiserfs_get_journal_block(p_s_sb), 
+		   cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
 		   oldest_trans_id) ;
 
   }
@@ -1755,7 +1772,7 @@
     } else if (ret != 0) {
       break ;
     }
-    cur_dblock = reiserfs_get_journal_block(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start ;
+    cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start ;
     replay_count++ ;
    if (cur_dblock == oldest_start)
         break;
@@ -1850,7 +1867,7 @@
     wake_up(&reiserfs_commit_thread_wait) ;
   } else {
 #ifdef CONFIG_REISERFS_CHECK
-    reiserfs_warning("journal-1540: kmalloc failed, doing sync commit\n") ;
+    reiserfs_warning(p_s_sb, "journal-1540: kmalloc failed, doing sync commit\n") ;
 #endif
     flush_commit_list(p_s_sb, SB_JOURNAL_LIST(p_s_sb) + jindex, 1) ;
   }
@@ -1905,95 +1922,305 @@
   }
 }
 
-/*
-** must be called once on fs mount.  calls journal_read for you
-*/
-int journal_init(struct super_block *p_s_sb) {
-  int num_cnodes = JOURNAL_BLOCK_COUNT * 2 ;
+static int release_journal_dev( struct super_block *super,
+				struct reiserfs_journal *journal )
+{
+    int result;
+    
+    result = 0;
+	
+    if( journal -> j_dev_bd != NULL && journal->j_dev_bd != super->s_bdev) {
+	result = blkdev_put( journal -> j_dev_bd, BDEV_FS );
+	journal -> j_dev_bd = NULL;
+    }
+    if( journal -> j_dev_file != NULL ) {
+	result = filp_close( journal -> j_dev_file, NULL );
+	journal -> j_dev_file = NULL;
+    }
+    if( result != 0 ) {
+	reiserfs_warning(super, "release_journal_dev: Cannot release journal device: %i", result );
+    }
+    return result;
+}
 
-  if (sizeof(struct reiserfs_journal_commit) != 4096 ||
-      sizeof(struct reiserfs_journal_desc) != 4096
-     ) {
-    printk("journal-1249: commit or desc struct not 4096 %Zd %Zd\n", sizeof(struct reiserfs_journal_commit), 
-        sizeof(struct reiserfs_journal_desc)) ;
-    return 1 ;
-  }
-  /* sanity check to make sure they don't overflow the journal */
-  if (JOURNAL_BLOCK_COUNT > reiserfs_get_journal_orig_size(p_s_sb)) {
-    printk("journal-1393: current JOURNAL_BLOCK_COUNT (%d) is too big.  This FS was created with a journal size of %lu blocks\n",
-            JOURNAL_BLOCK_COUNT, reiserfs_get_journal_orig_size(p_s_sb)) ;
-    return 1 ;
-  }
-  SB_JOURNAL(p_s_sb) = vmalloc(sizeof (struct reiserfs_journal)) ;
+static int journal_init_dev( struct super_block *super, 
+			     struct reiserfs_journal *journal, 
+			     const char *jdev_name )
+{
+	int result;
+	kdev_t jdev;
+	int blkdev_mode = FMODE_READ | FMODE_WRITE;
+
+	result = 0;
+
+	journal -> j_dev_bd = NULL;
+	journal -> j_dev_file = NULL;
+	jdev = SB_JOURNAL_DEV( super ) = 
+      		SB_ONDISK_JOURNAL_DEVICE( super ) ?
+		to_kdev_t(SB_ONDISK_JOURNAL_DEVICE( super )) : super -> s_dev;	
+
+	/* there is no "jdev" option */
+
+	if (is_read_only(super->s_dev))
+	    blkdev_mode = FMODE_READ;
+
+	if( ( !jdev_name || !jdev_name[ 0 ] ) ) {
+
+		/* don't add an extra reference to the device when 
+		 * the log is on the same disk as the FS.  It makes the
+		 * raid code unhappy
+		 */
+		if (jdev == super->s_dev) {
+		    journal->j_dev_bd = super->s_bdev;
+		    return 0;
+		}
+		journal -> j_dev_bd = bdget( kdev_t_to_nr( jdev ) );
+		if( journal -> j_dev_bd ) {
+			result = blkdev_get( journal -> j_dev_bd, 
+					     blkdev_mode, 0, BDEV_FS );
+			if (result) {
+			    bdput(journal->j_dev_bd);
+			    journal->j_dev_bd = NULL;
+			}
+		} else {
+			result = -ENOMEM;
+		} 
+		if( result != 0 )
+			printk( "journal_init_dev: cannot init journal device\n '%s': %i", 
+				kdevname( jdev ), result );
 
-  if (!SB_JOURNAL(p_s_sb)) {
-    printk("journal-1256: unable to get memory for journal structure\n") ;
-    return 1 ;
-  }
-  memset(SB_JOURNAL(p_s_sb), 0, sizeof(struct reiserfs_journal)) ;
+		return result;
+	}
 
-  SB_JOURNAL(p_s_sb)->j_list_bitmap_index = 0 ;
-  SB_JOURNAL_LIST_INDEX(p_s_sb) = -10000 ; /* make sure flush_old_commits does not try to flush a list while replay is on */
+	/* "jdev" option has been found */
 
-  /* clear out the journal list array */
-  memset(SB_JOURNAL_LIST(p_s_sb), 0, sizeof(struct reiserfs_journal_list) * JOURNAL_LIST_COUNT) ; 
-  journal_list_init(p_s_sb) ;
+	journal -> j_dev_file = filp_open( jdev_name, 0, 0 );
+	if( !IS_ERR( journal -> j_dev_file ) ) {
+		struct inode *jdev_inode;
+
+		jdev_inode = journal -> j_dev_file -> f_dentry -> d_inode;
+		journal -> j_dev_bd = jdev_inode -> i_bdev;
+		if( !S_ISBLK( jdev_inode -> i_mode ) ) {
+			printk( "journal_init_dev: '%s' is not a block device", jdev_name );
+			result = -ENOTBLK;
+		} else if( journal -> j_dev_file -> f_vfsmnt -> mnt_flags & MNT_NODEV) {
+			printk( "journal_init_dev: Cannot use devices on '%s'", jdev_name );
+			result = -EACCES;
+		} else if( jdev_inode -> i_bdev == NULL ) {
+			printk( "journal_init_dev: bdev unintialized for '%s'", jdev_name );
+			result = -ENOMEM;
+		} else if( ( result = blkdev_get( jdev_inode -> i_bdev, 
+						  blkdev_mode,
+						  0, BDEV_FS ) ) != 0 ) {
+			journal -> j_dev_bd = NULL;
+			printk( "journal_init_dev: Cannot load device '%s': %i", jdev_name,
+			     result );
+		} else
+			/* ok */
+			SB_JOURNAL_DEV( super ) = 
+				to_kdev_t( jdev_inode -> i_bdev -> bd_dev );
+	} else {
+		result = PTR_ERR( journal -> j_dev_file );
+		journal -> j_dev_file = NULL;
+		printk( "journal_init_dev: Cannot open '%s': %i", jdev_name, result );
+	}
+	if( result != 0 ) {
+		release_journal_dev( super, journal );
+	}
+	printk( "journal_init_dev: journal device: %s", kdevname( SB_JOURNAL_DEV( super ) ) );
+	return result;
+}
+
+/*
+** must be called once on fs mount.  calls journal_read for you
+*/
+int journal_init(struct super_block *p_s_sb, const char * j_dev_name, 
+                  int old_format) {
+    int num_cnodes = SB_ONDISK_JOURNAL_SIZE(p_s_sb) * 2 ;
+    struct buffer_head *bhjh;
+    struct reiserfs_super_block * rs;
+    struct reiserfs_journal_header *jh;
+    struct reiserfs_journal *journal;
+
+    if (sizeof(struct reiserfs_journal_commit) != 4096 ||
+	sizeof(struct reiserfs_journal_desc) != 4096) {
+	reiserfs_warning(p_s_sb, "journal-1249: commit or desc struct not 4096 %Zd %Zd\n", 
+	       sizeof(struct reiserfs_journal_commit), 
+	sizeof(struct reiserfs_journal_desc)) ;
+	return 1 ;
+    }
 
-  memset(SB_JOURNAL(p_s_sb)->j_list_hash_table, 0, JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ;
-  memset(journal_writers, 0, sizeof(char *) * 512) ; /* debug code */
+    if ( SB_ONDISK_JOURNAL_SIZE(p_s_sb) < 512 ) {
+	reiserfs_warning(p_s_sb, "Journal size %d is less than 512+1 blocks, which unsupported\n", SB_ONDISK_JOURNAL_SIZE(p_s_sb));
+	return 1 ;
+    }
 
-  INIT_LIST_HEAD(&SB_JOURNAL(p_s_sb)->j_bitmap_nodes) ;
-  INIT_LIST_HEAD(&SB_JOURNAL(p_s_sb)->j_dirty_buffers) ;
-  reiserfs_allocate_list_bitmaps(p_s_sb, SB_JOURNAL(p_s_sb)->j_list_bitmap, 
-                                 SB_BMAP_NR(p_s_sb)) ;
-  allocate_bitmap_nodes(p_s_sb) ;
+    journal = SB_JOURNAL(p_s_sb) = vmalloc(sizeof (struct reiserfs_journal)) ;
+    if (!journal) {
+	reiserfs_warning(p_s_sb, "journal-1256: unable to get memory for journal structure\n") ;
+	return 1 ;
+    }
+    memset(journal, 0, sizeof(struct reiserfs_journal)) ;
+    INIT_LIST_HEAD(&SB_JOURNAL(p_s_sb)->j_bitmap_nodes) ;
+    INIT_LIST_HEAD (&SB_JOURNAL(p_s_sb)->j_prealloc_list);
+
+    reiserfs_allocate_list_bitmaps(p_s_sb, SB_JOURNAL(p_s_sb)->j_list_bitmap, 
+				   SB_BMAP_NR(p_s_sb)) ;
+    allocate_bitmap_nodes(p_s_sb) ;
+
+    /* reserved for journal area support */
+    SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ?
+					    REISERFS_OLD_DISK_OFFSET_IN_BYTES /
+					    p_s_sb->s_blocksize +
+					    SB_BMAP_NR(p_s_sb) + 1 :
+					    REISERFS_DISK_OFFSET_IN_BYTES / 
+					    p_s_sb->s_blocksize + 2); 
+    
+    if( journal_init_dev( p_s_sb, journal, j_dev_name ) != 0 ) {
+	reiserfs_warning(p_s_sb, "journal-1259: unable to initialize jornal device\n");
+	goto free_and_return;
+    }
+
+    rs = SB_DISK_SUPER_BLOCK(p_s_sb);
+     
+    /* read journal header */
+    bhjh = journal_bread (p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
+                          SB_ONDISK_JOURNAL_SIZE(p_s_sb));
+    if (!bhjh) {
+	reiserfs_warning(p_s_sb, "journal-459: unable to read  journal header\n") ;
+	goto free_and_return;
+    }
+    jh = (struct reiserfs_journal_header *)(bhjh->b_data);
+     
+    /* make sure that journal matches to the super block */
+    if (is_reiserfs_jr(rs) && 
+        jh->jh_journal.jp_journal_magic != sb_jp_journal_magic(rs)) {
+	char jname[ 32 ];
+	char fname[ 32 ];
+	 
+	strcpy( jname, kdevname( SB_JOURNAL_DEV(p_s_sb) ) );
+	strcpy( fname, kdevname( p_s_sb->s_dev ) );
+	printk("journal-460: journal header magic %x (device %s) does not "
+	       "match magic found in super block %x (device %s)\n",
+		jh->jh_journal.jp_journal_magic, jname,
+		sb_jp_journal_magic(rs), fname);
+	brelse (bhjh);
+	goto free_and_return;
+    }
+     
+    SB_JOURNAL_TRANS_MAX(p_s_sb) = le32_to_cpu (jh->jh_journal.jp_journal_trans_max);
+    SB_JOURNAL_MAX_BATCH(p_s_sb) = le32_to_cpu (jh->jh_journal.jp_journal_max_batch);
+    SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb) = le32_to_cpu (jh->jh_journal.jp_journal_max_commit_age);
+    SB_JOURNAL_MAX_TRANS_AGE(p_s_sb) = JOURNAL_MAX_TRANS_AGE;
+
+    if (SB_JOURNAL_TRANS_MAX(p_s_sb)) {
+	/* make sure these parameters are available, assign if they are not */
+	__u32 initial = SB_JOURNAL_TRANS_MAX(p_s_sb);
+	__u32 ratio = 1;
+    
+	if (p_s_sb->s_blocksize < 4096)
+	    ratio = 4096 / p_s_sb->s_blocksize;
+
+	if (SB_ONDISK_JOURNAL_SIZE(p_s_sb)/SB_JOURNAL_TRANS_MAX(p_s_sb) < 
+	    JOURNAL_MIN_RATIO) 
+	{
+	    SB_JOURNAL_TRANS_MAX(p_s_sb) = SB_ONDISK_JOURNAL_SIZE(p_s_sb) / 
+	                                   JOURNAL_MIN_RATIO;
+	}
+	if (SB_JOURNAL_TRANS_MAX(p_s_sb) > JOURNAL_TRANS_MAX_DEFAULT / ratio)
+	    SB_JOURNAL_TRANS_MAX(p_s_sb) = JOURNAL_TRANS_MAX_DEFAULT / ratio;
+	if (SB_JOURNAL_TRANS_MAX(p_s_sb) < JOURNAL_TRANS_MIN_DEFAULT / ratio)
+	    SB_JOURNAL_TRANS_MAX(p_s_sb) = JOURNAL_TRANS_MIN_DEFAULT / ratio;
+
+	if (SB_JOURNAL_TRANS_MAX(p_s_sb) != initial) {
+	    printk ("reiserfs warning: wrong transaction max size (%u). "
+	            "Changed to %u\n", initial, SB_JOURNAL_TRANS_MAX(p_s_sb));
+        }
+	SB_JOURNAL_MAX_BATCH(p_s_sb) = SB_JOURNAL_TRANS_MAX(p_s_sb) *
+	                               JOURNAL_MAX_BATCH_DEFAULT / 
+				       JOURNAL_TRANS_MAX_DEFAULT;
+    }
+  
+    if (!SB_JOURNAL_TRANS_MAX(p_s_sb)) {
+	/*we have the file system was created by old version of mkreiserfs 
+	  so this field contains zero value */
+	SB_JOURNAL_TRANS_MAX(p_s_sb)      = JOURNAL_TRANS_MAX_DEFAULT ;
+	SB_JOURNAL_MAX_BATCH(p_s_sb)      = JOURNAL_MAX_BATCH_DEFAULT ;  
+	SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb) = JOURNAL_MAX_COMMIT_AGE ;
+	
+	/* for blocksize >= 4096 - max transaction size is 1024. For 
+	   block size < 4096 trans max size is decreased proportionally */
+	if (p_s_sb->s_blocksize < 4096) {
+	    SB_JOURNAL_TRANS_MAX(p_s_sb) /= (4096 / p_s_sb->s_blocksize) ;
+	    SB_JOURNAL_MAX_BATCH(p_s_sb) = SB_JOURNAL_TRANS_MAX(p_s_sb)*9 / 10;
+	}
+    }
 
-  SB_JOURNAL(p_s_sb)->j_start = 0 ;
-  SB_JOURNAL(p_s_sb)->j_len = 0 ;
-  SB_JOURNAL(p_s_sb)->j_len_alloc = 0 ;
-  atomic_set(&(SB_JOURNAL(p_s_sb)->j_wcount), 0) ;
-  SB_JOURNAL(p_s_sb)->j_bcount = 0 ;	  
-  SB_JOURNAL(p_s_sb)->j_trans_start_time = 0 ;	  
-  SB_JOURNAL(p_s_sb)->j_last = NULL ;	  
-  SB_JOURNAL(p_s_sb)->j_first = NULL ;     
-  init_waitqueue_head(&(SB_JOURNAL(p_s_sb)->j_join_wait)) ;
-  init_waitqueue_head(&(SB_JOURNAL(p_s_sb)->j_wait)) ; 
-
-  SB_JOURNAL(p_s_sb)->j_trans_id = 10 ;  
-  SB_JOURNAL(p_s_sb)->j_mount_id = 10 ; 
-  SB_JOURNAL(p_s_sb)->j_state = 0 ;
-  atomic_set(&(SB_JOURNAL(p_s_sb)->j_jlock), 0) ;
-  atomic_set(&(SB_JOURNAL(p_s_sb)->j_wlock), 0) ;
-  SB_JOURNAL(p_s_sb)->j_cnode_free_list = allocate_cnodes(num_cnodes) ;
-  SB_JOURNAL(p_s_sb)->j_cnode_free_orig = SB_JOURNAL(p_s_sb)->j_cnode_free_list ;
-  SB_JOURNAL(p_s_sb)->j_cnode_free = SB_JOURNAL(p_s_sb)->j_cnode_free_list ? num_cnodes : 0 ;
-  SB_JOURNAL(p_s_sb)->j_cnode_used = 0 ;
-  SB_JOURNAL(p_s_sb)->j_must_wait = 0 ;
-  init_journal_hash(p_s_sb) ;
-  SB_JOURNAL_LIST(p_s_sb)[0].j_list_bitmap = get_list_bitmap(p_s_sb, SB_JOURNAL_LIST(p_s_sb)) ;
-  if (!(SB_JOURNAL_LIST(p_s_sb)[0].j_list_bitmap)) {
-    reiserfs_warning("journal-2005, get_list_bitmap failed for journal list 0\n") ;
-    return 1 ;
-  }
-  if (journal_read(p_s_sb) < 0) {
-    reiserfs_warning("Replay Failure, unable to mount\n") ;
-    free_journal_ram(p_s_sb) ;
-    return 1 ;
-  }
-  SB_JOURNAL_LIST_INDEX(p_s_sb) = 0 ; /* once the read is done, we can set this
-                                         where it belongs */
+    brelse (bhjh);
 
-  INIT_LIST_HEAD (&SB_JOURNAL(p_s_sb)->j_prealloc_list);
+    SB_JOURNAL(p_s_sb)->j_list_bitmap_index = 0 ;
+    SB_JOURNAL_LIST_INDEX(p_s_sb) = -10000 ; /* make sure flush_old_commits does not try to flush a list while replay is on */
 
-  if (reiserfs_dont_log (p_s_sb))
-    return 0;
+    /* clear out the journal list array */
+    memset(SB_JOURNAL_LIST(p_s_sb), 0, 
+           sizeof(struct reiserfs_journal_list) * JOURNAL_LIST_COUNT) ; 
+
+    journal_list_init(p_s_sb) ;
+
+    memset(SB_JOURNAL(p_s_sb)->j_list_hash_table, 0, 
+           JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ;
+    memset(journal_writers, 0, sizeof(char *) * 512) ; /* debug code */
+
+    INIT_LIST_HEAD(&(SB_JOURNAL(p_s_sb)->j_dirty_buffers)) ;
+
+    SB_JOURNAL(p_s_sb)->j_start = 0 ;
+    SB_JOURNAL(p_s_sb)->j_len = 0 ;
+    SB_JOURNAL(p_s_sb)->j_len_alloc = 0 ;
+    atomic_set(&(SB_JOURNAL(p_s_sb)->j_wcount), 0) ;
+    SB_JOURNAL(p_s_sb)->j_bcount = 0 ;	  
+    SB_JOURNAL(p_s_sb)->j_trans_start_time = 0 ;	  
+    SB_JOURNAL(p_s_sb)->j_last = NULL ;	  
+    SB_JOURNAL(p_s_sb)->j_first = NULL ;     
+    init_waitqueue_head(&(SB_JOURNAL(p_s_sb)->j_join_wait)) ;
+    init_waitqueue_head(&(SB_JOURNAL(p_s_sb)->j_wait)) ; 
+
+    SB_JOURNAL(p_s_sb)->j_trans_id = 10 ;  
+    SB_JOURNAL(p_s_sb)->j_mount_id = 10 ; 
+    SB_JOURNAL(p_s_sb)->j_state = 0 ;
+    atomic_set(&(SB_JOURNAL(p_s_sb)->j_jlock), 0) ;
+    atomic_set(&(SB_JOURNAL(p_s_sb)->j_wlock), 0) ;
+    SB_JOURNAL(p_s_sb)->j_cnode_free_list = allocate_cnodes(num_cnodes) ;
+    SB_JOURNAL(p_s_sb)->j_cnode_free_orig = SB_JOURNAL(p_s_sb)->j_cnode_free_list ;
+    SB_JOURNAL(p_s_sb)->j_cnode_free = SB_JOURNAL(p_s_sb)->j_cnode_free_list ? 
+                                       num_cnodes : 0 ;
+    SB_JOURNAL(p_s_sb)->j_cnode_used = 0 ;
+    SB_JOURNAL(p_s_sb)->j_must_wait = 0 ;
+    init_journal_hash(p_s_sb) ;
+    SB_JOURNAL_LIST(p_s_sb)[0].j_list_bitmap = get_list_bitmap(p_s_sb, SB_JOURNAL_LIST(p_s_sb)) ;
+    if (!(SB_JOURNAL_LIST(p_s_sb)[0].j_list_bitmap)) {
+	reiserfs_warning(p_s_sb, "journal-2005, get_list_bitmap failed for journal list 0\n") ;
+	goto free_and_return;
+    }
+    if (journal_read(p_s_sb) < 0) {
+	reiserfs_warning(p_s_sb, "Replay Failure, unable to mount\n") ;
+	goto free_and_return;
+    }
+    /* once the read is done, we can set this where it belongs */
+    SB_JOURNAL_LIST_INDEX(p_s_sb) = 0 ; 
+
+    if (reiserfs_dont_log (p_s_sb))
+	return 0;
+
+    reiserfs_mounted_fs_count++ ;
+    if (reiserfs_mounted_fs_count <= 1) {
+	kernel_thread((void *)(void *)reiserfs_journal_commit_thread, NULL,
+		      CLONE_FS | CLONE_FILES | CLONE_VM) ;
+    }
+    return 0 ;
 
-  reiserfs_mounted_fs_count++ ;
-  if (reiserfs_mounted_fs_count <= 1) {
-    kernel_thread((void *)(void *)reiserfs_journal_commit_thread, NULL,
-                  CLONE_FS | CLONE_FILES | CLONE_VM) ;
-  }
-  return 0 ;
+free_and_return:
+    free_journal_ram(p_s_sb);
+    return 1;
 }
 
 /*
@@ -2006,10 +2233,10 @@
   if (reiserfs_dont_log(th->t_super)) 
     return 0 ;
   if ( SB_JOURNAL(th->t_super)->j_must_wait > 0 ||
-       (SB_JOURNAL(th->t_super)->j_len_alloc + new_alloc) >= JOURNAL_MAX_BATCH || 
+       (SB_JOURNAL(th->t_super)->j_len_alloc + new_alloc) >= SB_JOURNAL_MAX_BATCH(th->t_super) || 
        atomic_read(&(SB_JOURNAL(th->t_super)->j_jlock)) ||
-      (now - SB_JOURNAL(th->t_super)->j_trans_start_time) > JOURNAL_MAX_TRANS_AGE ||
-       SB_JOURNAL(th->t_super)->j_cnode_free < (JOURNAL_TRANS_MAX * 3)) { 
+      (now - SB_JOURNAL(th->t_super)->j_trans_start_time) > SB_JOURNAL_MAX_TRANS_AGE(th->t_super) ||
+       SB_JOURNAL(th->t_super)->j_cnode_free < (SB_JOURNAL_TRANS_MAX(th->t_super) * 3)) { 
     return 1 ;
   }
   return 0 ;
@@ -2076,13 +2303,12 @@
   ** we don't sleep if there aren't other writers
   */
 
-
   if (  (!join && SB_JOURNAL(p_s_sb)->j_must_wait > 0) ||
-     ( !join && (SB_JOURNAL(p_s_sb)->j_len_alloc + nblocks + 2) >= JOURNAL_MAX_BATCH) || 
+     ( !join && (SB_JOURNAL(p_s_sb)->j_len_alloc + nblocks + 2) >= SB_JOURNAL_MAX_BATCH(p_s_sb)) || 
      (!join && atomic_read(&(SB_JOURNAL(p_s_sb)->j_wcount)) > 0 && SB_JOURNAL(p_s_sb)->j_trans_start_time > 0 && 
-      (now - SB_JOURNAL(p_s_sb)->j_trans_start_time) > JOURNAL_MAX_TRANS_AGE) ||
+      (now - SB_JOURNAL(p_s_sb)->j_trans_start_time) > SB_JOURNAL_MAX_TRANS_AGE(p_s_sb)) ||
      (!join && atomic_read(&(SB_JOURNAL(p_s_sb)->j_jlock)) ) ||
-     (!join && SB_JOURNAL(p_s_sb)->j_cnode_free < (JOURNAL_TRANS_MAX * 3))) {
+     (!join && SB_JOURNAL(p_s_sb)->j_cnode_free < (SB_JOURNAL_TRANS_MAX(p_s_sb) * 3))) {
 
     unlock_journal(p_s_sb) ; /* allow others to finish this transaction */
 
@@ -2177,7 +2403,7 @@
   ** could get to disk too early.  NOT GOOD.
   */
   if (!prepared || buffer_locked(bh)) {
-    printk("journal-1777: buffer %lu bad state %cPREPARED %cLOCKED %cDIRTY %cJDIRTY_WAIT\n", bh->b_blocknr, prepared ? ' ' : '!', 
+    reiserfs_warning(p_s_sb, "journal-1777: buffer %lu bad state %cPREPARED %cLOCKED %cDIRTY %cJDIRTY_WAIT\n", bh->b_blocknr, prepared ? ' ' : '!', 
                             buffer_locked(bh) ? ' ' : '!',
 			    buffer_dirty(bh) ? ' ' : '!',
 			    buffer_journal_dirty(bh) ? ' ' : '!') ;
@@ -2186,13 +2412,13 @@
   count_already_incd = clear_prepared_bits(bh) ;
 
   if (atomic_read(&(SB_JOURNAL(p_s_sb)->j_wcount)) <= 0) {
-    printk("journal-1409: journal_mark_dirty returning because j_wcount was %d\n", atomic_read(&(SB_JOURNAL(p_s_sb)->j_wcount))) ;
+    reiserfs_warning(p_s_sb, "journal-1409: journal_mark_dirty returning because j_wcount was %d\n", atomic_read(&(SB_JOURNAL(p_s_sb)->j_wcount))) ;
     return 1 ;
   }
   /* this error means I've screwed up, and we've overflowed the transaction.  
   ** Nothing can be done here, except make the FS readonly or panic.
   */ 
-  if (SB_JOURNAL(p_s_sb)->j_len >= JOURNAL_TRANS_MAX) { 
+  if (SB_JOURNAL(p_s_sb)->j_len >= SB_JOURNAL_TRANS_MAX(p_s_sb)) { 
     reiserfs_panic(th->t_super, "journal-1413: journal_mark_dirty: j_len (%lu) is too big\n", SB_JOURNAL(p_s_sb)->j_len) ;
   }
 
@@ -2310,7 +2536,7 @@
     mark_buffer_notjournal_dirty(bh) ; 
     put_bh(bh) ;
     if (atomic_read(&(bh->b_count)) < 0) {
-      printk("journal-1752: remove from trans, b_count < 0\n") ;
+      reiserfs_warning(p_s_sb, "journal-1752: remove from trans, b_count < 0\n") ;
     }
     if (!buffer_locked(bh)) reiserfs_clean_and_file_buffer(bh) ; 
     ret = 1 ;
@@ -2433,7 +2659,7 @@
   /* starting with oldest, loop until we get to the start */
   i = (SB_JOURNAL_LIST_INDEX(p_s_sb) + 1) % JOURNAL_LIST_COUNT ;
   while(i != start) {
-    if (SB_JOURNAL_LIST(p_s_sb)[i].j_len > 0 && ((now - SB_JOURNAL_LIST(p_s_sb)[i].j_timestamp) > JOURNAL_MAX_COMMIT_AGE ||
+    if (SB_JOURNAL_LIST(p_s_sb)[i].j_len > 0 && ((now - SB_JOURNAL_LIST(p_s_sb)[i].j_timestamp) > SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb) ||
        immediate)) {
       /* we have to check again to be sure the current transaction did not change */
       if (i != SB_JOURNAL_LIST_INDEX(p_s_sb))  {
@@ -2449,7 +2675,7 @@
   if (!immediate && atomic_read(&(SB_JOURNAL(p_s_sb)->j_wcount)) <= 0 &&  
      SB_JOURNAL(p_s_sb)->j_trans_start_time > 0 && 
      SB_JOURNAL(p_s_sb)->j_len > 0 && 
-     (now - SB_JOURNAL(p_s_sb)->j_trans_start_time) > JOURNAL_MAX_TRANS_AGE) {
+     (now - SB_JOURNAL(p_s_sb)->j_trans_start_time) > SB_JOURNAL_MAX_TRANS_AGE(p_s_sb)) {
     journal_join(&th, p_s_sb, 1) ;
     reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
     journal_mark_dirty(&th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
@@ -2541,21 +2767,21 @@
 
   /* deal with old transactions where we are the last writers */
   now = CURRENT_TIME ;
-  if ((now - SB_JOURNAL(p_s_sb)->j_trans_start_time) > JOURNAL_MAX_TRANS_AGE) {
+  if ((now - SB_JOURNAL(p_s_sb)->j_trans_start_time) > SB_JOURNAL_MAX_TRANS_AGE(p_s_sb)) {
     commit_now = 1 ;
     SB_JOURNAL(p_s_sb)->j_next_async_flush = 1 ;
   }
   /* don't batch when someone is waiting on j_join_wait */
   /* don't batch when syncing the commit or flushing the whole trans */
   if (!(SB_JOURNAL(p_s_sb)->j_must_wait > 0) && !(atomic_read(&(SB_JOURNAL(p_s_sb)->j_jlock))) && !flush && !commit_now && 
-      (SB_JOURNAL(p_s_sb)->j_len < JOURNAL_MAX_BATCH)  && 
-      SB_JOURNAL(p_s_sb)->j_len_alloc < JOURNAL_MAX_BATCH && SB_JOURNAL(p_s_sb)->j_cnode_free > (JOURNAL_TRANS_MAX * 3)) {
+      (SB_JOURNAL(p_s_sb)->j_len < SB_JOURNAL_MAX_BATCH(p_s_sb))  && 
+      SB_JOURNAL(p_s_sb)->j_len_alloc < SB_JOURNAL_MAX_BATCH(p_s_sb) && SB_JOURNAL(p_s_sb)->j_cnode_free > (SB_JOURNAL_TRANS_MAX(p_s_sb) * 3)) {
     SB_JOURNAL(p_s_sb)->j_bcount++ ;
     unlock_journal(p_s_sb) ;
     return 0 ;
   }
 
-  if (SB_JOURNAL(p_s_sb)->j_start > JOURNAL_BLOCK_COUNT) {
+  if (SB_JOURNAL(p_s_sb)->j_start > SB_ONDISK_JOURNAL_SIZE(p_s_sb)) {
     reiserfs_panic(p_s_sb, "journal-003: journal_end: j_start (%ld) is too high\n", SB_JOURNAL(p_s_sb)->j_start) ;
   }
   return 1 ;
@@ -2584,7 +2810,7 @@
   if (reiserfs_dont_log(th->t_super)) {
     bh = sb_get_hash_table(p_s_sb, blocknr) ;
     if (bh && buffer_dirty (bh)) {
-      printk ("journal_mark_freed(dont_log): dirty buffer on hash list: %lx %ld\n", bh->b_state, blocknr);
+      reiserfs_warning (p_s_sb, "journal_mark_freed(dont_log): dirty buffer on hash list: %lx %ld\n", bh->b_state, blocknr);
       BUG ();
     }
     brelse (bh);
@@ -2625,7 +2851,7 @@
 	    cleaned = 1 ;
 	    put_bh(cn->bh) ;
 	    if (atomic_read(&(cn->bh->b_count)) < 0) {
-	      printk("journal-2138: cn->bh->b_count < 0\n") ;
+	      reiserfs_warning(p_s_sb, "journal-2138: cn->bh->b_count < 0\n") ;
 	    }
 	  }
 	  if (cn->jlist) { /* since we are clearing the bh, we MUST dec nonzerolen */
@@ -2642,7 +2868,7 @@
     reiserfs_clean_and_file_buffer(bh) ;
     put_bh(bh) ; /* get_hash grabs the buffer */
     if (atomic_read(&(bh->b_count)) < 0) {
-      printk("journal-2165: bh->b_count < 0\n") ;
+      reiserfs_warning(p_s_sb, "journal-2165: bh->b_count < 0\n") ;
     }
   }
   return 0 ;
@@ -2817,7 +3043,7 @@
   
   rs = SB_DISK_SUPER_BLOCK(p_s_sb) ;
   /* setup description block */
-  d_bh = sb_getblk(p_s_sb, reiserfs_get_journal_block(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start) ; 
+  d_bh = journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start) ; 
   mark_buffer_uptodate(d_bh, 1) ;
   desc = (struct reiserfs_journal_desc *)(d_bh)->b_data ;
   memset(desc, 0, sizeof(struct reiserfs_journal_desc)) ;
@@ -2825,8 +3051,8 @@
   desc->j_trans_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_trans_id) ;
 
   /* setup commit block.  Don't write (keep it clean too) this one until after everyone else is written */
-  c_bh = sb_getblk(p_s_sb,  reiserfs_get_journal_block(p_s_sb) + 
-  				        ((SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL(p_s_sb)->j_len + 1) % JOURNAL_BLOCK_COUNT)) ;
+  c_bh =  journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
+		 ((SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL(p_s_sb)->j_len + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
   commit = (struct reiserfs_journal_commit *)c_bh->b_data ;
   memset(commit, 0, sizeof(struct reiserfs_journal_commit)) ;
   commit->j_trans_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_trans_id) ;
@@ -2869,8 +3095,10 @@
         last_cn->next = jl_cn ;
       }
       last_cn = jl_cn ;
-      if (cn->bh->b_blocknr >= reiserfs_get_journal_block(p_s_sb) &&
-          cn->bh->b_blocknr < (reiserfs_get_journal_block(p_s_sb) + JOURNAL_BLOCK_COUNT)) {
+      /* make sure the block we are trying to log is not a block 
+         of journal or reserved area */
+
+      if (is_block_in_log_or_reserved_area(p_s_sb, cn->bh->b_blocknr)) {
         reiserfs_panic(p_s_sb, "journal-2332: Trying to log block %lu, which is a log block\n", cn->bh->b_blocknr) ;
       }
       jl_cn->blocknr = cn->bh->b_blocknr ; 
@@ -2899,7 +3127,7 @@
     brelse(d_bh) ;
     brelse(c_bh) ;
     unlock_journal(p_s_sb) ;
-printk("journal-2020: do_journal_end: BAD desc->j_len is ZERO\n") ;
+reiserfs_warning(p_s_sb, "journal-2020: do_journal_end: BAD desc->j_len is ZERO\n") ;
     atomic_set(&(SB_JOURNAL(p_s_sb)->j_jlock), 0) ;
     wake_up(&(SB_JOURNAL(p_s_sb)->j_join_wait)) ;
     return 0 ;
@@ -2914,14 +3142,14 @@
     /* copy all the real blocks into log area.  dirty log blocks */
     if (test_bit(BH_JDirty, &cn->bh->b_state)) {
       struct buffer_head *tmp_bh ;
-      tmp_bh = sb_getblk(p_s_sb, reiserfs_get_journal_block(p_s_sb) + 
-		     ((cur_write_start + jindex) % JOURNAL_BLOCK_COUNT)) ;
+      tmp_bh =  journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
+		       ((cur_write_start + jindex) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
       mark_buffer_uptodate(tmp_bh, 1) ;
       memcpy(tmp_bh->b_data, cn->bh->b_data, cn->bh->b_size) ;  
       jindex++ ;
     } else {
       /* JDirty cleared sometime during transaction.  don't log this one */
-      printk("journal-2048: do_journal_end: BAD, buffer in journal hash, but not JDirty!\n") ;
+      reiserfs_warning(p_s_sb, "journal-2048: do_journal_end: BAD, buffer in journal hash, but not JDirty!\n") ;
     }
     cn = cn->next ;
     cur_blocks_left-- ;
@@ -2976,7 +3204,7 @@
 
   /* reset journal values for the next transaction */
   old_start = SB_JOURNAL(p_s_sb)->j_start ;
-  SB_JOURNAL(p_s_sb)->j_start = (SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL(p_s_sb)->j_len + 2) % JOURNAL_BLOCK_COUNT;
+  SB_JOURNAL(p_s_sb)->j_start = (SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL(p_s_sb)->j_len + 2) % SB_ONDISK_JOURNAL_SIZE(p_s_sb);
   atomic_set(&(SB_JOURNAL(p_s_sb)->j_wcount), 0) ;
   SB_JOURNAL(p_s_sb)->j_bcount = 0 ;
   SB_JOURNAL(p_s_sb)->j_last = NULL ;
@@ -2997,12 +3225,12 @@
   for (i = 0 ; i < JOURNAL_LIST_COUNT ; i++) {
     jindex = i ;
     if (SB_JOURNAL_LIST(p_s_sb)[jindex].j_len > 0 && SB_JOURNAL(p_s_sb)->j_start <= SB_JOURNAL_LIST(p_s_sb)[jindex].j_start) {
-      if ((SB_JOURNAL(p_s_sb)->j_start + JOURNAL_TRANS_MAX + 1) >= SB_JOURNAL_LIST(p_s_sb)[jindex].j_start) {
+      if ((SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL_TRANS_MAX(p_s_sb) + 1) >= SB_JOURNAL_LIST(p_s_sb)[jindex].j_start) {
 	flush_journal_list(p_s_sb, SB_JOURNAL_LIST(p_s_sb) + jindex, 1) ; 
       }
     } else if (SB_JOURNAL_LIST(p_s_sb)[jindex].j_len > 0 && 
-              (SB_JOURNAL(p_s_sb)->j_start + JOURNAL_TRANS_MAX + 1) > JOURNAL_BLOCK_COUNT) {
-      if (((SB_JOURNAL(p_s_sb)->j_start + JOURNAL_TRANS_MAX + 1) % JOURNAL_BLOCK_COUNT) >= 
+              (SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL_TRANS_MAX(p_s_sb) + 1) > SB_ONDISK_JOURNAL_SIZE(p_s_sb)) {
+      if (((SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL_TRANS_MAX(p_s_sb) + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb)) >= 
             SB_JOURNAL_LIST(p_s_sb)[jindex].j_start) {
 	flush_journal_list(p_s_sb, SB_JOURNAL_LIST(p_s_sb) + jindex, 1 ) ; 
       }
@@ -3010,7 +3238,7 @@
     /* this check should always be run, to send old lists to disk */
     if (SB_JOURNAL_LIST(p_s_sb)[jindex].j_len > 0 && 
               SB_JOURNAL_LIST(p_s_sb)[jindex].j_timestamp < 
-	      (CURRENT_TIME - (JOURNAL_MAX_TRANS_AGE * 4))) {
+	      (CURRENT_TIME - (SB_JOURNAL_MAX_TRANS_AGE(p_s_sb) * 4))) {
 	flush_journal_list(p_s_sb, SB_JOURNAL_LIST(p_s_sb) + jindex, 1 ) ; 
     }
   }
diff -urN linux-2.4.22-pre2/fs/reiserfs/lbalance.c linux-2.4.22-pre3/fs/reiserfs/lbalance.c
--- linux-2.4.22-pre2/fs/reiserfs/lbalance.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/reiserfs/lbalance.c	2003-07-05 18:11:07.000000000 -0700
@@ -1209,10 +1209,10 @@
       prev = (i != 0) ? deh_location( &(deh[i - 1]) ) : 0;
       
       if (prev && prev <= deh_location( &(deh[i])))
-	reiserfs_warning ("vs-10240: leaf_paste_entries: directory item (%h) corrupted (prev %a, cur(%d) %a)\n", 
+	reiserfs_warning (NULL, "vs-10240: leaf_paste_entries: directory item (%h) corrupted (prev %a, cur(%d) %a)\n", 
 			  ih, deh + i - 1, i, deh + i);
       if (next && next >= deh_location( &(deh[i])))
-	reiserfs_warning ("vs-10250: leaf_paste_entries: directory item (%h) corrupted (cur(%d) %a, next %a)\n",
+	reiserfs_warning (NULL, "vs-10250: leaf_paste_entries: directory item (%h) corrupted (cur(%d) %a, next %a)\n",
 			  ih, i, deh + i, deh + i + 1);
     }
   }
diff -urN linux-2.4.22-pre2/fs/reiserfs/namei.c linux-2.4.22-pre3/fs/reiserfs/namei.c
--- linux-2.4.22-pre2/fs/reiserfs/namei.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/fs/reiserfs/namei.c	2003-07-05 18:11:07.000000000 -0700
@@ -114,7 +114,7 @@
     switch (retval) {
     case ITEM_NOT_FOUND:
 	if (!PATH_LAST_POSITION (path)) {
-	    reiserfs_warning ("vs-7000: search_by_entry_key: search_by_key returned item position == 0");
+	    reiserfs_warning (sb, "vs-7000: search_by_entry_key: search_by_key returned item position == 0\n");
 	    pathrelse(path) ;
 	    return IO_ERROR ;
 	}
@@ -128,7 +128,7 @@
 
     default:
 	pathrelse (path);
-	reiserfs_warning ("vs-7002: search_by_entry_key: no path to here");
+	reiserfs_warning (sb, "vs-7002: search_by_entry_key: no path to here\n ");
 	return IO_ERROR;
     }
 
@@ -287,7 +287,7 @@
     while (1) {
 	retval = search_by_entry_key (dir->i_sb, &key_to_search, path_to_entry, de);
 	if (retval == IO_ERROR) {
-	    reiserfs_warning ("zam-7001: io error in %s\n", __FUNCTION__);
+	    reiserfs_warning (dir->i_sb, "zam-7001: io error in %s\n", __FUNCTION__);
 	    return IO_ERROR;
 	}
 
@@ -413,7 +413,7 @@
 	}
 
         if (retval != NAME_FOUND) {
-	    reiserfs_warning ("zam-7002:%s: \"reiserfs_find_entry\" has returned"
+	    reiserfs_warning (dir->i_sb, "zam-7002:%s: \"reiserfs_find_entry\" has returned"
                               " unexpected value (%d)\n", __FUNCTION__, retval);
        }
 
@@ -423,7 +423,7 @@
     gen_number = find_first_zero_bit ((unsigned long *)bit_string, MAX_GENERATION_NUMBER + 1);
     if (gen_number > MAX_GENERATION_NUMBER) {
       /* there is no free generation number */
-      reiserfs_warning ("reiserfs_add_entry: Congratulations! we have got hash function screwed up\n");
+      reiserfs_warning (dir->i_sb, "reiserfs_add_entry: Congratulations! we have got hash function screwed up\n");
       if (buffer != small_buf)
           reiserfs_kfree (buffer, buflen, dir->i_sb);
       pathrelse (&path);
@@ -453,7 +453,7 @@
  		  
     if (gen_number != 0) {	/* we need to re-search for the insertion point */
       if (search_by_entry_key (dir->i_sb, &entry_key, &path, &de) != NAME_NOT_FOUND) {
-            reiserfs_warning ("vs-7032: reiserfs_add_entry: "
+            reiserfs_warning (dir->i_sb, "vs-7032: reiserfs_add_entry: "
                             "entry with this key (%K) already exists\n", &entry_key);
 
 	    if (buffer != small_buf)
@@ -742,7 +742,7 @@
 	goto end_rmdir;
 
     if ( inode->i_nlink != 2 && inode->i_nlink != 1 )
-	printk ("reiserfs_rmdir: empty directory has nlink != 2 (%d)\n", inode->i_nlink);
+	reiserfs_warning ( inode->i_sb, "reiserfs_rmdir: empty directory has nlink != 2 (%d)\n", inode->i_nlink);
 
     inode->i_nlink = 0;
     inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
@@ -811,7 +811,7 @@
     }
   
     if (!inode->i_nlink) {
-	printk("reiserfs_unlink: deleting nonexistent file (%s:%lu), %d\n",
+	reiserfs_warning(inode->i_sb, "reiserfs_unlink: deleting nonexistent file (%s:%lu), %d\n",
 	       kdevname(inode->i_dev), inode->i_ino, inode->i_nlink);
 	inode->i_nlink = 1;
     }
@@ -1224,7 +1224,7 @@
     // anybody, but it will panic if will not be able to find the
     // entry. This needs one more clean up
     if (reiserfs_cut_from_item (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL, 0) < 0)
-	reiserfs_warning ("vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?\n");
+	reiserfs_warning ((&th)->t_super, "vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?\n");
 
     old_dir->i_size -= DEH_SIZE + old_de.de_entrylen;
     old_dir->i_blocks = ((old_dir->i_size + 511) >> 9);
diff -urN linux-2.4.22-pre2/fs/reiserfs/objectid.c linux-2.4.22-pre3/fs/reiserfs/objectid.c
--- linux-2.4.22-pre2/fs/reiserfs/objectid.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/reiserfs/objectid.c	2003-07-05 18:11:07.000000000 -0700
@@ -8,7 +8,7 @@
 #include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/reiserfs_fs.h>
-
+#include <linux/reiserfs_fs_sb.h>
 
 // find where objectid map starts
 #define objectid_map(s,rs) (old_format_only (s) ? \
@@ -63,7 +63,7 @@
                                 /* comment needed -Hans */
     unused_objectid = le32_to_cpu (map[1]);
     if (unused_objectid == U32_MAX) {
-	printk ("REISERFS: get_objectid: no more object ids\n");
+	reiserfs_warning (s, "REISERFS: get_objectid: no more object ids\n");
 	reiserfs_restore_prepared_buffer(s, SB_BUFFER_WITH_SB(s)) ;
 	return 0;
     }
@@ -146,7 +146,7 @@
 	    }
 
             /* JDM comparing two little-endian values for equality -- safe */
-	if (rs->s_oid_cursize == rs->s_oid_maxsize) {
+	if (sb_oid_cursize(rs) == sb_oid_maxsize(rs)) {
 		/* objectid map must be expanded, but there is no space */
 		PROC_INFO_INC( s, leaked_oid );
 		return;
@@ -163,16 +163,16 @@
 	i += 2;
     }
 
-    reiserfs_warning ("vs-15011: reiserfs_release_objectid: tried to free free object id (%lu)\n", 
+    reiserfs_warning (s, "vs-15011: reiserfs_release_objectid: tried to free free object id (%lu)\n", 
 		      ( long unsigned ) objectid_to_release);
 }
 
 
 int reiserfs_convert_objectid_map_v1(struct super_block *s) {
     struct reiserfs_super_block *disk_sb = SB_DISK_SUPER_BLOCK (s);
-    int cur_size = le16_to_cpu(disk_sb->s_oid_cursize) ;
+    int cur_size = sb_oid_cursize(disk_sb);
     int new_size = (s->s_blocksize - SB_SIZE) / sizeof(__u32) / 2 * 2 ;
-    int old_max = le16_to_cpu(disk_sb->s_oid_maxsize) ;
+    int old_max = sb_oid_maxsize(disk_sb);
     struct reiserfs_super_block_v1 *disk_sb_v1 ;
     __u32 *objectid_map, *new_objectid_map ;
     int i ;
@@ -186,7 +186,7 @@
 	** map 
 	*/
 	objectid_map[new_size - 1] = objectid_map[cur_size - 1] ;
-	disk_sb->s_oid_cursize = cpu_to_le16(new_size) ;
+	set_sb_oid_cursize(disk_sb,new_size) ;
     }
     /* move the smaller objectid map past the end of the new super */
     for (i = new_size - 1 ; i >= 0 ; i--) {
@@ -195,7 +195,7 @@
 
 
     /* set the max size so we don't overflow later */
-    disk_sb->s_oid_maxsize = cpu_to_le16(new_size) ;
+    set_sb_oid_maxsize(disk_sb,new_size) ;
 
     /* Zero out label and generate random UUID */
     memset(disk_sb->s_label, 0, sizeof(disk_sb->s_label)) ;
diff -urN linux-2.4.22-pre2/fs/reiserfs/prints.c linux-2.4.22-pre3/fs/reiserfs/prints.c
--- linux-2.4.22-pre2/fs/reiserfs/prints.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/reiserfs/prints.c	2003-07-05 18:11:07.000000000 -0700
@@ -180,10 +180,12 @@
    specification for complex structures like you used to do with
    printfs for integers, doubles and pointers. For instance, to print
    out key structure you have to write just: 
-   reiserfs_warning ("bad key %k", key); 
+   reiserfs_warning (NULL, "bad key %k", key); 
    instead of 
    printk ("bad key %lu %lu %lu %lu", key->k_dir_id, key->k_objectid, 
            key->k_offset, key->k_uniqueness); 
+   Also if you'd specify a pointer to fs super block as the first argument,
+   device name will be prepended to the output.
 */
 
 
@@ -259,18 +261,23 @@
     va_end( args );\
 }
 
-void reiserfs_warning (const char * fmt, ...)
+void reiserfs_warning (struct super_block * sb, const char * fmt, ...)
 {
   do_reiserfs_warning(fmt);
   /* console_print (error_buf); */
-  printk (KERN_WARNING "%s", error_buf);
+  if (sb)
+    printk (KERN_WARNING "%s:", bdevname(sb->s_dev));
+  else
+    printk (KERN_WARNING);
+
+  printk ("%s", error_buf);
 }
 
 void reiserfs_debug (struct super_block *s, int level, const char * fmt, ...)
 {
 #ifdef CONFIG_REISERFS_CHECK
   do_reiserfs_warning(fmt);
-  printk (KERN_DEBUG "%s", error_buf);
+  printk (KERN_DEBUG "%s: %s", bdevname(s->s_dev), error_buf);
 #else
   ; 
 #endif
@@ -330,7 +337,7 @@
 {
   show_reiserfs_locks() ;
   do_reiserfs_warning(fmt);
-  printk ( KERN_EMERG "%s", error_buf);
+  printk ( KERN_EMERG "%s (device %s)\n", error_buf, bdevname(sb->s_dev));
   BUG ();
 
   /* this is not actually called, but makes reiserfs_panic() "noreturn" */
@@ -409,13 +416,13 @@
 	to = last < B_NR_ITEMS (bh) ? last : B_NR_ITEMS (bh);
     }
 
-    reiserfs_warning ("INTERNAL NODE (%ld) contains %z\n",  bh->b_blocknr, bh);
+    reiserfs_warning (NULL, "INTERNAL NODE (%ld) contains %z\n",  bh->b_blocknr, bh);
     
     dc = B_N_CHILD (bh, from);
-    reiserfs_warning ("PTR %d: %y ", from, dc);
+    reiserfs_warning (NULL, "PTR %d: %y ", from, dc);
     
     for (i = from, key = B_N_PDELIM_KEY (bh, from), dc ++; i < to; i ++, key ++, dc ++) {
-	reiserfs_warning ("KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
+	reiserfs_warning (NULL, "KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
 	if (i && i % 4 == 0)
 	    printk ("\n");
     }
@@ -444,10 +451,10 @@
     nr = blkh_nr_item(blkh);
 
     printk ("\n===================================================================\n");
-    reiserfs_warning ("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
+    reiserfs_warning (NULL, "LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
 
     if (!(print_mode & PRINT_LEAF_ITEMS)) {
-	reiserfs_warning ("FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
+	reiserfs_warning (NULL, "FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
 			  &(ih->ih_key), &((ih + nr - 1)->ih_key));
 	return 0;
     }
@@ -467,7 +474,7 @@
     printk ("|##|   type    |           key           | ilen | free_space | version | loc  |\n");
     for (i = from; i < to; i++, ih ++) {
 	printk ("-------------------------------------------------------------------------------\n");
-	reiserfs_warning ("|%2d| %h |\n", i, ih);
+	reiserfs_warning (NULL, "|%2d| %h |\n", i, ih);
 	if (print_mode & PRINT_LEAF_ITEMS)
 	    op_print_item (ih, B_I_PITEM (bh, ih));
     }
@@ -496,12 +503,13 @@
     char *version;
     
 
-    if (strncmp (rs->s_magic,  REISERFS_SUPER_MAGIC_STRING,
-                 strlen ( REISERFS_SUPER_MAGIC_STRING)) == 0) {
+    if (is_reiserfs_3_5(rs)) {
         version = "3.5";
-    } else if( strncmp (rs->s_magic,  REISER2FS_SUPER_MAGIC_STRING,
-                        strlen ( REISER2FS_SUPER_MAGIC_STRING)) == 0) {
+    } else if (is_reiserfs_3_6(rs)) {
         version = "3.6";
+    } else if (is_reiserfs_jr(rs)) {
+      version = ((sb_version(rs) == REISERFS_VERSION_2) ?
+ 		 "3.6" : "3.5");  
     } else {
 	return 1;
     }
@@ -516,19 +524,18 @@
     // someone stores reiserfs super block in some data block ;)
 //    skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
     skipped = bh->b_blocknr;
-    data_blocks = sb_block_count(rs) - skipped - 1 -
-                  sb_bmap_nr(rs) - (sb_orig_journal_size(rs) + 1) -
-                  sb_free_blocks(rs);
-    printk ("Busy blocks (skipped %d, bitmaps - %d, journal blocks - %d\n"
-	    "1 super blocks, %d data blocks\n", 
-	    skipped, sb_bmap_nr(rs), 
-	    (sb_orig_journal_size(rs) + 1), data_blocks);
+    data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) -
+	    (!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) + 1 : sb_reserved_for_journal(rs)) -	    
+	    sb_free_blocks(rs);
+    printk ("Busy blocks (skipped %d, bitmaps - %d, journal (or reserved) blocks - %d\n"
+	    "1 super block, %d data blocks\n", 
+	    skipped, sb_bmap_nr(rs), (!is_reiserfs_jr(rs) ? (sb_jp_journal_size(rs) + 1) :
+				      sb_reserved_for_journal(rs)) , data_blocks);
     printk ("Root block %u\n", sb_root_block(rs));
-    printk ("Journal block (first) %d\n", sb_journal_block(rs));
-    printk ("Journal dev %d\n", sb_journal_dev(rs));
-    printk ("Journal orig size %d\n", sb_orig_journal_size(rs));
-    printk ("Filesystem state %s\n", 
-	    (sb_state(rs) == REISERFS_VALID_FS) ? "VALID" : "ERROR");
+    printk ("Journal block (first) %d\n", sb_jp_journal_1st_block(rs));
+    printk ("Journal dev %d\n", sb_jp_journal_dev(rs));
+    printk ("Journal orig size %d\n", sb_jp_journal_size(rs));
+    printk ("FS state %d\n", sb_fs_state(rs));
     printk ("Hash function \"%s\"\n",
             reiserfs_hashname(sb_hash_function_code(rs)));
 
diff -urN linux-2.4.22-pre2/fs/reiserfs/procfs.c linux-2.4.22-pre3/fs/reiserfs/procfs.c
--- linux-2.4.22-pre2/fs/reiserfs/procfs.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/reiserfs/procfs.c	2003-07-05 18:11:07.000000000 -0700
@@ -103,15 +103,6 @@
 				     int count, int *eof, void *data )
 {
 	int len = 0;
-    
-	len += sprintf( &buffer[ len ], "%s [%s]\n", 
-			reiserfs_get_version_string(),
-#if defined( CONFIG_REISERFS_FS_MODULE )
-			"as module"
-#else
-			"built into kernel"
-#endif
-			);
 	return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
 }
 
@@ -123,8 +114,10 @@
 
 #define D2C( x ) le16_to_cpu( x )
 #define D4C( x ) le32_to_cpu( x )
-#define DF( x ) D2C( rs -> x )
-#define DFL( x ) D4C( rs -> x )
+#define DF( x ) D2C( rs -> s_v1.x )
+#define DFL( x ) D4C( rs -> s_v1.x )
+#define DP( x ) D2C( rs -> x )
+#define DPL( x ) D4C( rs -> x )
 
 #define objectid_map( s, rs ) (old_format_only (s) ?				\
                          (__u32 *)((struct reiserfs_super_block_v1 *)rs + 1) :	\
@@ -132,6 +125,8 @@
 #define MAP( i ) D4C( objectid_map( sb, rs )[ i ] )
 
 #define DJF( x ) le32_to_cpu( rs -> x )
+#define DJV( x ) le32_to_cpu( s_v1 -> x )
+#define DJP( x ) le32_to_cpu( jp -> x ) 
 #define JF( x ) ( r -> s_journal -> x )
 
 int reiserfs_super_in_proc( char *buffer, char **start, off_t offset,
@@ -355,7 +350,6 @@
 	struct reiserfs_sb_info *sb_info;
 	struct reiserfs_super_block *rs;
 	int hash_code;
-	__u32 flags;
 	int len = 0;
     
 	sb = procinfo_prologue( ( kdev_t ) ( long ) data );
@@ -364,7 +358,6 @@
 	sb_info = &sb->u.reiserfs_sb;
 	rs = sb_info -> s_rs;
 	hash_code = DFL( s_hash_function_code );
-	flags = DFL( s_flags );
 
 	len += sprintf( &buffer[ len ], 
 			"block_count: \t%i\n"
@@ -373,12 +366,15 @@
 			"blocksize: \t%i\n"
 			"oid_maxsize: \t%i\n"
 			"oid_cursize: \t%i\n"
-			"state: \t%i\n"
-			"magic: \t%12.12s\n"
+			"umount_state: \t%i\n"
+			"magic: \t%10.10s\n"
+			"fs_state: \t%i\n"
 			"hash: \t%s\n"
 			"tree_height: \t%i\n"
 			"bmap_nr: \t%i\n"
 			"version: \t%i\n"
+			"reserved_for_journal: \t%i\n"
+			"inode_generation: \t%i\n"
 			"flags: \t%x[%s]\n",
 
 			DFL( s_block_count ),
@@ -387,8 +383,9 @@
 			DF( s_blocksize ),
 			DF( s_oid_maxsize ),
 			DF( s_oid_cursize ),
-			DF( s_state ),
-			rs -> s_magic,
+			DF( s_umount_state ),
+			rs -> s_v1.s_magic,
+			DF( s_fs_state ),
 			hash_code == TEA_HASH ? "tea" :
 			( hash_code == YURA_HASH ) ? "rupasov" :
 			( hash_code == R5_HASH ) ? "r5" :
@@ -396,9 +393,11 @@
 			DF( s_tree_height ),
 			DF( s_bmap_nr ),
 			DF( s_version ),
-			flags, 
-			( flags & reiserfs_attrs_cleared ) 
-			? "attrs_cleared" : "" );
+			DF( s_reserved_for_journal ),
+			DPL( s_inode_generation ),
+			DPL( s_flags ),
+			(DPL( s_flags ) & reiserfs_attrs_cleared 
+			? "attrs_cleared" : "" ));
 
 	procinfo_epilogue( sb );
 	return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
@@ -421,7 +420,7 @@
 		return -ENOENT;
 	sb_info = &sb->u.reiserfs_sb;
 	rs = sb_info -> s_rs;
-	mapsize = le16_to_cpu( rs -> s_oid_cursize );
+	mapsize = le16_to_cpu( rs -> s_v1.s_oid_cursize );
 	total_used = 0;
 
 	for( i = 0 ; i < mapsize ; ++i ) {
@@ -452,7 +451,7 @@
 	}
 	len += sprintf( &buffer[ len ], "total: \t%i [%i/%i] used: %lu [%s]\n", 
 			i, 
-			mapsize, le16_to_cpu( rs -> s_oid_maxsize ),
+			mapsize, le16_to_cpu( rs -> s_v1.s_oid_maxsize ),
 			total_used, exact ? "exact" : "estimation" );
 
 	procinfo_epilogue( sb );
@@ -465,6 +464,7 @@
 	struct super_block *sb;
 	struct reiserfs_sb_info *r;
 	struct reiserfs_super_block *rs;
+	struct journal_params *jp;	
 	int len = 0;
     
 	sb = procinfo_prologue( ( kdev_t ) ( long ) data );
@@ -472,18 +472,20 @@
 		return -ENOENT;
 	r = &sb->u.reiserfs_sb;
 	rs = r -> s_rs;
+	jp = &rs->s_v1.s_journal;
 
 	len += sprintf( &buffer[ len ], 
 			/* on-disk fields */
-			"s_journal_block: \t%i\n"
-			"s_journal_dev: \t%s[%x]\n"
-			"s_orig_journal_size: \t%i\n"
-			"s_journal_trans_max: \t%i\n"
-			"s_journal_block_count: \t%i\n"
-			"s_journal_max_batch: \t%i\n"
-			"s_journal_max_commit_age: \t%i\n"
-			"s_journal_max_trans_age: \t%i\n"
+ 			"jp_journal_1st_block: \t%i\n"
+ 			"jp_journal_dev: \t%s[%x]\n"
+ 			"jp_journal_size: \t%i\n"
+ 			"jp_journal_trans_max: \t%i\n"
+ 			"jp_journal_magic: \t%i\n"
+ 			"jp_journal_max_batch: \t%i\n"
+ 			"jp_journal_max_commit_age: \t%i\n"
+			"jp_journal_max_trans_age: \t%i\n"
 			/* incore fields */
+			"j_1st_reserved_block: \t%i\n" 
 			"j_state: \t%li\n"			
 			"j_trans_id: \t%lu\n"
 			"j_mount_id: \t%lu\n"
@@ -519,16 +521,17 @@
 			"prepare: \t%12lu\n"
 			"prepare_retry: \t%12lu\n",
 
-			DJF( s_journal_block ),
-			DJF( s_journal_dev ) == 0 ? "none" : bdevname( DJF( s_journal_dev ) ), 
-			DJF( s_journal_dev ),
-			DJF( s_orig_journal_size ),
-			DJF( s_journal_trans_max ),
-			DJF( s_journal_block_count ),
-			DJF( s_journal_max_batch ),
-			DJF( s_journal_max_commit_age ),
-			DJF( s_journal_max_trans_age ),
-			
+                        DJP( jp_journal_1st_block ),
+                        DJP( jp_journal_dev ) == 0 ? "none" : bdevname(to_kdev_t(DJP( jp_journal_dev ))),
+                        DJP( jp_journal_dev ),
+                        DJP( jp_journal_size ),
+                        DJP( jp_journal_trans_max ),
+                        DJP( jp_journal_magic ),
+                        DJP( jp_journal_max_batch ),
+                        DJP( jp_journal_max_commit_age ),
+                        DJP( jp_journal_max_trans_age ),
+
+ 			JF( j_1st_reserved_block ),
 			JF( j_state ),			
 			JF( j_trans_id ),
 			JF( j_mount_id ),
@@ -581,7 +584,7 @@
 		sb->u.reiserfs_sb.procdir -> owner = THIS_MODULE;
 		return 0;
 	}
-	reiserfs_warning( "reiserfs: cannot create /proc/%s/%s\n",
+	reiserfs_warning( sb, "reiserfs: cannot create /proc/%s/%s\n",
 			  proc_info_root_name, bdevname( sb -> s_dev ) );
 	return 1;
 }
@@ -636,7 +639,7 @@
 		if( proc_info_root ) {
 			proc_info_root -> owner = THIS_MODULE;
 		} else {
-			reiserfs_warning( "reiserfs: cannot create /proc/%s\n",
+			reiserfs_warning( NULL, "reiserfs: cannot create /proc/%s\n",
 					  proc_info_root_name );
 			return 1;
 		}
diff -urN linux-2.4.22-pre2/fs/reiserfs/resize.c linux-2.4.22-pre3/fs/reiserfs/resize.c
--- linux-2.4.22-pre2/fs/reiserfs/resize.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/fs/reiserfs/resize.c	2003-07-05 18:11:07.000000000 -0700
@@ -35,14 +35,14 @@
 	sb = SB_DISK_SUPER_BLOCK(s);
 
 	if (SB_BLOCK_COUNT(s) >= block_count_new) {
-		printk("can\'t shrink filesystem on-line\n");
+		reiserfs_warning(s, "can\'t shrink filesystem on-line\n");
 		return -EINVAL;
 	}
 
 	/* check the device size */
 	bh = sb_bread(s, block_count_new - 1);
 	if (!bh) {
-		printk("reiserfs_resize: can\'t read last block\n");
+		reiserfs_warning(s, "reiserfs_resize: can\'t read last block\n");
 		return -EINVAL;
 	}	
 	bforget(bh);
@@ -51,7 +51,7 @@
 	 * cannot be resized */
 	if (SB_BUFFER_WITH_SB(s)->b_blocknr *	SB_BUFFER_WITH_SB(s)->b_size 
 		!= REISERFS_DISK_OFFSET_IN_BYTES ) {
-		printk("reiserfs_resize: unable to resize a reiserfs without distributed bitmap (fs version < 3.5.12)\n");
+		reiserfs_warning(s, "reiserfs_resize: unable to resize a reiserfs without distributed bitmap (fs version < 3.5.12)\n");
 		return -ENOTSUPP;
 	}
        
@@ -75,7 +75,7 @@
 	if (bmap_nr_new > bmap_nr) {	    
 	    /* reallocate journal bitmaps */
 	    if (reiserfs_allocate_list_bitmaps(s, jbitmap, bmap_nr_new) < 0) {
-		printk("reiserfs_resize: unable to allocate memory for journal bitmaps\n");
+		reiserfs_warning(s, "reiserfs_resize: unable to allocate memory for journal bitmaps\n");
 		unlock_super(s) ;
 		return -ENOMEM ;
 	    }
@@ -106,14 +106,14 @@
 	     * block pointers */
 	    bitmap = vmalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
 	    if (!bitmap) {
-		printk("reiserfs_resize: unable to allocate memory.\n");
+		reiserfs_warning(s, "reiserfs_resize: unable to allocate memory.\n");
 		return -ENOMEM;
 	    }
 	    for (i = 0; i < bmap_nr; i++)
 		bitmap[i] = SB_AP_BITMAP(s)[i];
 	    for (i = bmap_nr; i < bmap_nr_new; i++) {
 		bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8);
-		memset(bitmap[i].bh->b_data, 0, sb->s_blocksize);
+		memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb));
 		reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data);
 
 		mark_buffer_dirty(bitmap[i].bh) ;
diff -urN linux-2.4.22-pre2/fs/reiserfs/stree.c linux-2.4.22-pre3/fs/reiserfs/stree.c
--- linux-2.4.22-pre2/fs/reiserfs/stree.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/fs/reiserfs/stree.c	2003-07-05 18:11:07.000000000 -0700
@@ -166,7 +166,7 @@
     if (cpu_key_k_offset (key1) > cpu_key_k_offset (key2))
 	return 1;
 
-    reiserfs_warning ("comp_cpu_keys: type are compared for %K and %K\n",
+    reiserfs_warning (NULL, "comp_cpu_keys: type are compared for %K and %K\n",
 		      key1, key2);
 
     if (cpu_key_k_type (key1) < cpu_key_k_type (key2))
@@ -506,14 +506,14 @@
     nr = blkh_nr_item(blkh);
     if (nr < 1 || nr > ((blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN))) {
 	/* item number is too big or too small */
-	reiserfs_warning ("is_leaf: nr_item seems wrong: %z\n", bh);
+	reiserfs_warning (NULL, "is_leaf: nr_item seems wrong: %z\n", bh);
 	return 0;
     }
     ih = (struct item_head *)(buf + BLKH_SIZE) + nr - 1;
     used_space = BLKH_SIZE + IH_SIZE * nr + (blocksize - ih_location (ih));
     if (used_space != blocksize - blkh_free_space(blkh)) {
 	/* free space does not match to calculated amount of use space */
-	reiserfs_warning ("is_leaf: free space seems wrong: %z\n", bh);
+	reiserfs_warning (NULL, "is_leaf: free space seems wrong: %z\n", bh);
 	return 0;
     }
 
@@ -525,19 +525,19 @@
     prev_location = blocksize;
     for (i = 0; i < nr; i ++, ih ++) {
 	if ( le_ih_k_type(ih) == TYPE_ANY) {
-	    reiserfs_warning ("is_leaf: wrong item type for item %h\n",ih);
+	    reiserfs_warning (NULL, "is_leaf: wrong item type for item %h\n",ih);
 	    return 0;
 	}
 	if (ih_location (ih) >= blocksize || ih_location (ih) < IH_SIZE * nr) {
-	    reiserfs_warning ("is_leaf: item location seems wrong: %h\n", ih);
+	    reiserfs_warning (NULL, "is_leaf: item location seems wrong: %h\n", ih);
 	    return 0;
 	}
 	if (ih_item_len (ih) < 1 || ih_item_len (ih) > MAX_ITEM_LEN (blocksize)) {
-	    reiserfs_warning ("is_leaf: item length seems wrong: %h\n", ih);
+	    reiserfs_warning (NULL, "is_leaf: item length seems wrong: %h\n", ih);
 	    return 0;
 	}
 	if (prev_location - ih_location (ih) != ih_item_len (ih)) {
-	    reiserfs_warning ("is_leaf: item location seems wrong (second one): %h\n", ih);
+	    reiserfs_warning (NULL, "is_leaf: item location seems wrong (second one): %h\n", ih);
 	    return 0;
 	}
 	prev_location = ih_location (ih);
@@ -566,13 +566,13 @@
     nr = blkh_nr_item(blkh);
     if (nr > (blocksize - BLKH_SIZE - DC_SIZE) / (KEY_SIZE + DC_SIZE)) {
 	/* for internal which is not root we might check min number of keys */
-	reiserfs_warning ("is_internal: number of key seems wrong: %z\n", bh);
+	reiserfs_warning (NULL, "is_internal: number of key seems wrong: %z\n", bh);
 	return 0;
     }
 
     used_space = BLKH_SIZE + KEY_SIZE * nr + DC_SIZE * (nr + 1);
     if (used_space != blocksize - blkh_free_space(blkh)) {
-	reiserfs_warning ("is_internal: free space seems wrong: %z\n", bh);
+	reiserfs_warning (NULL, "is_internal: free space seems wrong: %z\n", bh);
 	return 0;
     }
 
@@ -682,7 +682,7 @@
 
 #ifdef CONFIG_REISERFS_CHECK
 	if ( !(++n_repeat_counter % 50000) )
-	    reiserfs_warning ("PAP-5100: search_by_key: %s:"
+	    reiserfs_warning (p_s_sb, "PAP-5100: search_by_key: %s:"
 			      "there were %d iterations of while loop "
 			      "looking for key %K\n",
 			      current->comm, n_repeat_counter, p_s_key);
@@ -747,7 +747,7 @@
 	// make sure, that the node contents look like a node of
 	// certain level
 	if (!is_tree_node (p_s_bh, expected_level)) {
-	    reiserfs_warning ("vs-5150: search_by_key: "
+	    reiserfs_warning (p_s_sb, "vs-5150: search_by_key: "
 			      "invalid format found in block %ld. Fsck?\n", 
 			      p_s_bh->b_blocknr);
 	    pathrelse (p_s_search_path);
@@ -1268,7 +1268,7 @@
 	if (n_ret_value == IO_ERROR)
 	    break;
 	if (n_ret_value == FILE_NOT_FOUND) {
-	    reiserfs_warning ("vs-5340: reiserfs_delete_item: "
+	    reiserfs_warning (p_s_sb, "vs-5340: reiserfs_delete_item: "
 			      "no items of the file %K found\n", p_s_item_key);
 	    break;
 	}
@@ -1354,7 +1354,7 @@
     while (1) {
 	retval = search_item (th->t_super, &cpu_key, &path);
 	if (retval == IO_ERROR) {
-	    reiserfs_warning ("vs-5350: reiserfs_delete_solid_item: "
+	    reiserfs_warning (th->t_super, "vs-5350: reiserfs_delete_solid_item: "
 			      "i/o failure occurred trying to delete %K\n", &cpu_key);
 	    break;
 	}
@@ -1363,7 +1363,7 @@
 	    // No need for a warning, if there is just no free space to insert '..' item into the newly-created subdir
 	    if ( !( (unsigned long long) GET_HASH_VALUE (le_key_k_offset (le_key_version (key), key)) == 0 && \
 		 GET_GENERATION_NUMBER (le_key_k_offset (le_key_version (key), key)) == 1 ) )
-		reiserfs_warning ("vs-5355: reiserfs_delete_solid_item: %k not found", key);
+		reiserfs_warning (th->t_super, "vs-5355: reiserfs_delete_solid_item: %k not found\n", key);
 	    break;
 	}
 	if (!tb_init) {
@@ -1384,7 +1384,7 @@
 	}
 
 	// IO_ERROR, NO_DISK_SPACE, etc
-	reiserfs_warning ("vs-5360: reiserfs_delete_solid_item: "
+	reiserfs_warning (th->t_super, "vs-5360: reiserfs_delete_solid_item: "
 			  "could not delete %K due to fix_nodes failure\n", &cpu_key);
 	unfix_nodes (&tb);
 	break;
@@ -1479,7 +1479,7 @@
 	tail_len -= removed;
 	set_cpu_key_k_offset (&tail_key, cpu_key_k_offset (&tail_key) - removed);
     }
-    printk ("indirect_to_direct_roll_back: indirect_to_direct conversion has been rolled back due to lack of disk space\n");
+    reiserfs_warning (inode->i_sb, "indirect_to_direct_roll_back: indirect_to_direct conversion has been rolled back due to lack of disk space\n");
     //mark_file_without_tail (inode);
     mark_inode_dirty (inode);
 }
@@ -1569,7 +1569,7 @@
 	if (n_ret_value == POSITION_FOUND)
 	    continue;
 
-	reiserfs_warning ("PAP-5610: reiserfs_cut_from_item: item %K not found\n", p_s_item_key);
+	reiserfs_warning (p_s_sb, "PAP-5610: reiserfs_cut_from_item: item %K not found\n", p_s_item_key);
 	unfix_nodes (&s_cut_balance);
 	return (n_ret_value == IO_ERROR) ? -EIO : -ENOENT;
     } /* while */
@@ -1582,7 +1582,7 @@
 	    indirect_to_direct_roll_back (th, p_s_inode, p_s_path);
 	}
 	if (n_ret_value == NO_DISK_SPACE)
-	    reiserfs_warning ("NO_DISK_SPACE");
+	    reiserfs_warning (p_s_sb, "NO_DISK_SPACE\n");
 	unfix_nodes (&s_cut_balance);
 	return -EIO;
     }
@@ -1650,7 +1650,7 @@
 static void truncate_directory (struct reiserfs_transaction_handle *th, struct inode * inode)
 {
     if (inode->i_nlink)
-	reiserfs_warning ("vs-5655: truncate_directory: link count != 0\n");
+	reiserfs_warning (th->t_super, "vs-5655: truncate_directory: link count != 0\n");
 
     set_le_key_k_offset (KEY_FORMAT_3_5, INODE_PKEY (inode), DOT_OFFSET);
     set_le_key_k_type (KEY_FORMAT_3_5, INODE_PKEY (inode), TYPE_DIRENTRY);
@@ -1699,13 +1699,13 @@
 
     retval = search_for_position_by_key(p_s_inode->i_sb, &s_item_key, &s_search_path);
     if (retval == IO_ERROR) {
-	reiserfs_warning ("vs-5657: reiserfs_do_truncate: "
+	reiserfs_warning (p_s_inode->i_sb, "vs-5657: reiserfs_do_truncate: "
 			  "i/o failure occurred trying to truncate %K\n", &s_item_key);
 	return;
     }
     if (retval == POSITION_FOUND || retval == FILE_NOT_FOUND) {
 	pathrelse (&s_search_path);
-	reiserfs_warning ("PAP-5660: reiserfs_do_truncate: "
+	reiserfs_warning (p_s_inode->i_sb, "PAP-5660: reiserfs_do_truncate: "
 			  "wrong result %d of search for %K\n", retval, &s_item_key);
 	return;
     }
@@ -1737,7 +1737,7 @@
 	/* Cut or delete file item. */
 	n_deleted = reiserfs_cut_from_item(th, &s_search_path, &s_item_key, p_s_inode,  page, n_new_file_size);
 	if (n_deleted < 0) {
-	    reiserfs_warning ("vs-5665: reiserfs_truncate_file: cut_from_item failed");
+	    reiserfs_warning (th->t_super, "vs-5665: reiserfs_truncate_file: cut_from_item failed\n");
 	    reiserfs_check_path(&s_search_path) ;
 	    return;
 	}
@@ -1842,7 +1842,7 @@
 	    goto error_out ;
 	}
 	if (retval == POSITION_FOUND) {
-	    reiserfs_warning ("PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists\n", p_s_key);
+	    reiserfs_warning (th->t_super, "PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists\n", p_s_key);
 	    retval = -EEXIST ;
 	    goto error_out ;
 	}
@@ -1896,7 +1896,7 @@
 	    goto error_out ;
 	}
 	if (retval == ITEM_FOUND) {
-	    reiserfs_warning ("PAP-5760: reiserfs_insert_item: "
+	    reiserfs_warning (th->t_super, "PAP-5760: reiserfs_insert_item: "
 			      "key %K already exists in the tree\n", key);
 	    retval = -EEXIST ;
 	    goto error_out; 
diff -urN linux-2.4.22-pre2/fs/reiserfs/super.c linux-2.4.22-pre3/fs/reiserfs/super.c
--- linux-2.4.22-pre2/fs/reiserfs/super.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/fs/reiserfs/super.c	2003-07-05 18:11:07.000000000 -0700
@@ -16,8 +16,36 @@
 #define REISERFS_OLD_BLOCKSIZE 4096
 #define REISERFS_SUPER_MAGIC_STRING_OFFSET_NJ 20
 
-char reiserfs_super_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
-char reiser2fs_super_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
+const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
+const char reiserfs_3_6_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
+const char reiserfs_jr_magic_string[] = REISER2FS_JR_SUPER_MAGIC_STRING;
+
+int is_reiserfs_3_5 (struct reiserfs_super_block * rs)
+{
+  return !strncmp (rs->s_v1.s_magic, reiserfs_3_5_magic_string,
+		   strlen (reiserfs_3_5_magic_string));
+}
+
+
+int is_reiserfs_3_6 (struct reiserfs_super_block * rs)
+{
+  return !strncmp (rs->s_v1.s_magic, reiserfs_3_6_magic_string,
+ 		   strlen (reiserfs_3_6_magic_string));
+}
+
+
+int is_reiserfs_jr (struct reiserfs_super_block * rs)
+{
+  return !strncmp (rs->s_v1.s_magic, reiserfs_jr_magic_string,
+ 		   strlen (reiserfs_jr_magic_string));
+}
+
+
+static int is_any_reiserfs_magic_string (struct reiserfs_super_block * rs)
+{
+  return (is_reiserfs_3_5 (rs) || is_reiserfs_3_6 (rs) ||
+	  is_reiserfs_jr (rs));
+}
 
 static int reiserfs_remount (struct super_block * s, int * flags, char * data);
 static int reiserfs_statfs (struct super_block * s, struct statfs * buf);
@@ -107,7 +135,7 @@
     while (1) {
         retval = search_item (s, &max_cpu_key, &path);
         if (retval != ITEM_NOT_FOUND) {
-            reiserfs_warning ("vs-2140: finish_unfinished: search_by_key returned %d\n",
+            reiserfs_warning (s, "vs-2140: finish_unfinished: search_by_key returned %d\n",
                               retval);
             break;
         }
@@ -115,7 +143,7 @@
         bh = get_last_bh (&path);
         item_pos = get_item_pos (&path);
         if (item_pos != B_NR_ITEMS (bh)) {
-            reiserfs_warning ("vs-2060: finish_unfinished: wrong position found\n");
+            reiserfs_warning (s, "vs-2060: finish_unfinished: wrong position found\n");
             break;
         }
         item_pos --;
@@ -144,7 +172,7 @@
         if (!inode) {
             /* the unlink almost completed, it just did not manage to remove
 	       "save" link and release objectid */
-            reiserfs_warning ("vs-2180: finish_unfinished: iget failed for %K\n",
+            reiserfs_warning (s, "vs-2180: finish_unfinished: iget failed for %K\n",
                               &obj_key);
             remove_save_link_only (s, &save_link_key, 1);
             continue;
@@ -152,7 +180,7 @@
 
 	if (!truncate && inode->i_nlink) {
 	    /* file is not unlinked */
-            reiserfs_warning ("vs-2185: finish_unfinished: file %K is not unlinked\n",
+            reiserfs_warning (s, "vs-2185: finish_unfinished: file %K is not unlinked\n",
                               &obj_key);
             remove_save_link_only (s, &save_link_key, 0);
             continue;
@@ -163,7 +191,7 @@
 	       The only imaginable way is to execute unfinished truncate request
 	       then boot into old kernel, remove the file and create dir with
 	       the same key. */
-	    reiserfs_warning("green-2101: impossible truncate on a directory %k. Please report\n", INODE_PKEY (inode));
+	    reiserfs_warning(s, "green-2101: impossible truncate on a directory %k. Please report\n", INODE_PKEY (inode));
 	    remove_save_link_only (s, &save_link_key, 0);
 	    truncate = 0;
 	    iput (inode); 
@@ -174,14 +202,14 @@
             inode -> u.reiserfs_i.i_flags |= i_link_saved_truncate_mask;
             /* not completed truncate found. New size was committed together
 	       with "save" link */
-            reiserfs_warning ("Truncating %k to %Ld ..",
+            reiserfs_warning (s, "Truncating %k to %Ld ..",
                               INODE_PKEY (inode), inode->i_size);
             reiserfs_truncate_file (inode, 0/*don't update modification time*/);
             remove_save_link (inode, truncate);
         } else {
             inode -> u.reiserfs_i.i_flags |= i_link_saved_unlink_mask;
             /* not completed unlink (rmdir) found */
-            reiserfs_warning ("Removing %k..", INODE_PKEY (inode));
+            reiserfs_warning (s, "Removing %k..", INODE_PKEY (inode));
             /* removal gets completed in iput */
         }
  
@@ -193,7 +221,7 @@
      
     pathrelse (&path);
     if (done)
-        reiserfs_warning ("There were %d uncompleted unlinks/truncates. "
+        reiserfs_warning (s, "There were %d uncompleted unlinks/truncates. "
                           "Completed\n", done);
 }
  
@@ -235,7 +263,7 @@
     } else {
 	/* truncate */
 	if (S_ISDIR (inode->i_mode))
-	    reiserfs_warning("green-2102: Adding a truncate savelink for a directory %k! Please report\n", INODE_PKEY(inode));
+	    reiserfs_warning(inode->i_sb, "green-2102: Adding a truncate savelink for a directory %k! Please report\n", INODE_PKEY(inode));
 	set_cpu_key_k_offset (&key, 1);
 	set_cpu_key_k_type (&key, TYPE_INDIRECT);
 
@@ -249,7 +277,7 @@
     retval = search_item (inode->i_sb, &key, &path);
     if (retval != ITEM_NOT_FOUND) {
 	if ( retval != -ENOSPC )
-	    reiserfs_warning ("vs-2100: add_save_link:"
+	    reiserfs_warning (inode->i_sb, "vs-2100: add_save_link:"
 			  "search_by_key (%K) returned %d\n", &key, retval);
 	pathrelse (&path);
 	return;
@@ -262,7 +290,7 @@
     retval = reiserfs_insert_item (th, &path, &key, &ih, (char *)&link);
     if (retval) {
 	if (retval != -ENOSPC)
-	    reiserfs_warning ("vs-2120: add_save_link: insert_item returned %d\n",
+	    reiserfs_warning (inode->i_sb, "vs-2120: add_save_link: insert_item returned %d\n",
 			  retval);
     } else {
 	if( truncate )
@@ -321,7 +349,7 @@
   if (!(s->s_flags & MS_RDONLY)) {
     journal_begin(&th, s, 10) ;
     reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-    set_sb_state( SB_DISK_SUPER_BLOCK(s), s->u.reiserfs_sb.s_mount_state );
+    set_sb_umount_state( SB_DISK_SUPER_BLOCK(s), s->u.reiserfs_sb.s_mount_state );
     journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
   }
 
@@ -340,12 +368,12 @@
   print_statistics (s);
 
   if (s->u.reiserfs_sb.s_kmallocs != 0) {
-    reiserfs_warning ("vs-2004: reiserfs_put_super: allocated memory left %d\n",
+    reiserfs_warning (s, "vs-2004: reiserfs_put_super: allocated memory left %d\n",
 		      s->u.reiserfs_sb.s_kmallocs);
   }
 
   if (s->u.reiserfs_sb.reserved_blocks != 0) {
-    reiserfs_warning ("green-2005: reiserfs_put_super: reserved blocks left %d\n",
+    reiserfs_warning (s, "green-2005: reiserfs_put_super: reserved blocks left %d\n",
 		      s->u.reiserfs_sb.reserved_blocks);
   }
 
@@ -365,7 +393,7 @@
     struct reiserfs_transaction_handle th ;
 
     if (inode->i_sb->s_flags & MS_RDONLY) {
-        reiserfs_warning("clm-6006: writing inode %lu on readonly FS\n", 
+        reiserfs_warning(inode->i_sb, "clm-6006: writing inode %lu on readonly FS\n", 
 	                  inode->i_ino) ;
         return ;
     }
@@ -633,12 +661,12 @@
 	if( reiserfs_attrs( s ) ) {
 		rs = SB_DISK_SUPER_BLOCK (s);
 		if( old_format_only(s) ) {
-			reiserfs_warning( "reiserfs: cannot support attributes on 3.5.x disk format\n" );
+			reiserfs_warning(s, "reiserfs: cannot support attributes on 3.5.x disk format\n" );
 			s -> u.reiserfs_sb.s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
 			return;
 		}
 		if( !( le32_to_cpu( rs -> s_flags ) & reiserfs_attrs_cleared ) ) {
-				reiserfs_warning( "reiserfs: cannot support attributes until flag is set in super-block\n" );
+				reiserfs_warning(s, "reiserfs: cannot support attributes until flag is set in super-block\n" );
 				s -> u.reiserfs_sb.s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
 		}
 	}
@@ -653,7 +681,6 @@
   unsigned long safe_mask = 0;
 
   rs = SB_DISK_SUPER_BLOCK (s);
-
   if (!reiserfs_parse_options(s, data, &mount_options, &blocks))
   	return -EINVAL;
 
@@ -684,14 +711,14 @@
       /* it is read-only already */
       return 0;
     /* try to remount file system with read-only permissions */
-    if (sb_state(rs) == REISERFS_VALID_FS || s->u.reiserfs_sb.s_mount_state != REISERFS_VALID_FS) {
+    if (sb_umount_state(rs) == REISERFS_VALID_FS || s->u.reiserfs_sb.s_mount_state != REISERFS_VALID_FS) {
       return 0;
     }
 
     journal_begin(&th, s, 10) ;
     /* Mounting a rw partition read-only. */
     reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-    set_sb_state( rs, s->u.reiserfs_sb.s_mount_state );
+    set_sb_umount_state( rs, s->u.reiserfs_sb.s_mount_state );
     journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
     s->s_dirt = 0;
   } else {
@@ -699,15 +726,14 @@
     if (!(s->s_flags & MS_RDONLY))
 	return 0; /* We are read-write already */
 
-    s->u.reiserfs_sb.s_mount_state = sb_state(rs) ;
     s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */
     journal_begin(&th, s, 10) ;
     
     /* Mount a partition which is read-only, read-write */
     reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-    s->u.reiserfs_sb.s_mount_state = sb_state(rs);
+    s->u.reiserfs_sb.s_mount_state = sb_umount_state(rs);
     s->s_flags &= ~MS_RDONLY;
-    set_sb_state( rs, REISERFS_ERROR_FS );
+    set_sb_umount_state( rs, REISERFS_ERROR_FS );
     /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */
     journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
     s->s_dirt = 0;
@@ -791,7 +817,7 @@
     for (i = 0; i < SB_BMAP_NR(s); i++) {
       wait_on_buffer(SB_AP_BITMAP (s)[i].bh);
       if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
-	reiserfs_warning("sh-2029: reiserfs read_bitmaps: "
+	reiserfs_warning(s, "sh-2029: reiserfs read_bitmaps: "
 			 "bitmap block (#%lu) reading failed\n",
 			 SB_AP_BITMAP(s)[i].bh->b_blocknr);
 	for (i = 0; i < SB_BMAP_NR(s); i++)
@@ -842,7 +868,7 @@
   }
 
   if (free != SB_FREE_BLOCKS (s))
-    reiserfs_warning ("vs-4000: check_bitmap: %d free blocks, must be %d\n",
+    reiserfs_warning (s, "vs-4000: check_bitmap: %d free blocks, must be %d\n",
 		      free, SB_FREE_BLOCKS (s));
 }
 
@@ -854,17 +880,14 @@
 
     bh = bread (s->s_dev, offset / size, size);
     if (!bh) {
-      printk ("read_super_block: "
-              "bread failed (dev %s, block %d, size %d)\n",
+      printk ("sh-2006: reiserfs read_super_block: "
+              "bread failed (dev %s, block %u, size %u)\n",
               kdevname (s->s_dev), offset / size, size);
       return 1;
     }
  
     rs = (struct reiserfs_super_block *)bh->b_data;
-    if (!is_reiserfs_magic_string (rs)) {
-      printk ("read_super_block: "
-              "can't find a reiserfs filesystem on (dev %s, block %lu, size %d)\n",
-              kdevname(s->s_dev), bh->b_blocknr, size);
+    if (!is_any_reiserfs_magic_string (rs)) {
       brelse (bh);
       return 1;
     }
@@ -890,37 +913,23 @@
 
     bh = reiserfs_bread (s, offset / s->s_blocksize, s->s_blocksize);
     if (!bh) {
-	printk("read_super_block: "
-                "bread failed (dev %s, block %d, size %d)\n",
-                kdevname (s->s_dev), offset / size, size);
+      printk("sh-2007: reiserfs read_super_block: "
+	     "bread failed (dev %s, block %u, size %u)\n",
+	     kdevname (s->s_dev), offset / size, size);
 	return 1;
     }
     
     rs = (struct reiserfs_super_block *)bh->b_data;
-    if (!is_reiserfs_magic_string (rs) ||
-	sb_blocksize(rs) != s->s_blocksize) {
-	printk ("read_super_block: "
-		"can't find a reiserfs filesystem on (dev %s, block %lu, size %d)\n",
-		kdevname(s->s_dev), bh->b_blocknr, size);
-	brelse (bh);
-	printk ("read_super_block: can't find a reiserfs filesystem on dev %s.\n", kdevname(s->s_dev));
-	return 1;
-    }
-    /* must check to be sure we haven't pulled an old format super out
-    ** of the old format's log.  This is a kludge of a check, but it
-    ** will work.  If block we've just read in is inside the
-    ** journal for that super, it can't be valid.  
-    */
-    if (bh->b_blocknr >= sb_journal_block(rs) && 
-	bh->b_blocknr < (sb_journal_block(rs) + JOURNAL_BLOCK_COUNT)) {
-	brelse(bh) ;
-	printk("super-459: read_super_block: "
-	       "super found at block %lu is within its own log. "
-	       "It must not be of this format type.\n", bh->b_blocknr) ;
-	return 1 ;
+    if (!is_any_reiserfs_magic_string (rs) || sb_blocksize(rs) !=
+	s->s_blocksize) {
+      printk ("sh-2011: read_super_block: "
+	      "can't find a reiserfs filesystem on (dev %s, block %lu, size %lu)\n",
+	      kdevname(s->s_dev), bh->b_blocknr, s->s_blocksize);    
+      brelse (bh);
+      return 1;
     }
 
-    if ( rs->s_root_block == -1 ) {
+    if (sb_root_block(rs) == -1) {
 	brelse(bh) ;
 	printk("dev %s: Unfinished reiserfsck --rebuild-tree run detected. Please run\n"
 	       "reiserfsck --rebuild-tree and wait for a completion. If that fails\n"
@@ -930,7 +939,24 @@
 
     SB_BUFFER_WITH_SB (s) = bh;
     SB_DISK_SUPER_BLOCK (s) = rs;
-
+    if (is_reiserfs_jr (rs)) {
+      /* magic is of non-standard journal filesystem, look at s_version to
+	 find which format is in use */
+      if (sb_version(rs) == REISERFS_VERSION_2)
+	printk ("reiserfs: found format \"3.6\" with non-standard journal\n");
+      else if (sb_version(rs) == REISERFS_VERSION_1)
+	printk ("reiserfs: found format \"3.5\" with non-standard journal\n");
+      else {
+	printk ("sh-2012: read_super_block: found unknown format \"%u\" "
+		"of reiserfs with non-standard magic\n", sb_version(rs));
+ 	return 1;
+      }
+    }
+    else
+      /* s_version may contain incorrect information. Look at the magic
+	 string */
+      printk ("reiserfs: found format \"%s\" with standard journal\n",
+	      is_reiserfs_3_5 (rs) ? "3.5" : "3.6");
     s->s_op = &reiserfs_sops;
 
     /* new format is limited by the 32 bit wide i_blocks field, want to
@@ -948,7 +974,8 @@
   ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))) ;
   wait_on_buffer(SB_BUFFER_WITH_SB(s)) ;
   if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
-    printk("reread_meta_blocks, error reading the super\n") ;
+    reiserfs_warning(s, "sh-2016: reiserfs reread_meta_blocks, "
+	   "error reading the super\n") ;
     return 1 ;
   }
 
@@ -956,7 +983,7 @@
     ll_rw_block(READ, 1, &(SB_AP_BITMAP(s)[i].bh)) ;
     wait_on_buffer(SB_AP_BITMAP(s)[i].bh) ;
     if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
-      printk("reread_meta_blocks, error reading bitmap block number %d at %ld\n", i, SB_AP_BITMAP(s)[i].bh->b_blocknr) ;
+      reiserfs_warning(s, "reread_meta_blocks, error reading bitmap block number %d at %ld\n", i, SB_AP_BITMAP(s)[i].bh->b_blocknr) ;
       return 1 ;
     }
   }
@@ -1002,7 +1029,7 @@
 	    if (reiserfs_rupasov_hash(s)) {
 		hash = YURA_HASH ;
 	    }
-	    reiserfs_warning("reiserfs: FS seems to be empty, autodetect "
+	    reiserfs_warning(s, "reiserfs: FS seems to be empty, autodetect "
 	                     "is using the default hash\n");
 	    break;
 	}
@@ -1012,9 +1039,8 @@
 	if ( ( (teahash == r5hash) && (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash) ) ||
 	     ( (teahash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ||
 	     ( (r5hash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ) {
-	    reiserfs_warning("reiserfs: Unable to automatically detect hash"
-		"function for device %s\n"
-		"please mount with -o hash={tea,rupasov,r5}\n", kdevname (s->s_dev));
+	    reiserfs_warning(s, "reiserfs: Unable to automatically detect hash"
+		"function please mount with -o hash={tea,rupasov,r5}\n");
 	    hash = UNSET_HASH;
 	    break;
 	}
@@ -1025,8 +1051,7 @@
 	else if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == r5hash)
 	    hash = R5_HASH;
 	else {
-	    reiserfs_warning("reiserfs: Unrecognised hash function for "
-			     "device %s\n", kdevname (s->s_dev));
+	    reiserfs_warning(s, "reiserfs: Unrecognised hash function\n");
 	    hash = UNSET_HASH;
 	}
     } while (0);
@@ -1093,13 +1118,13 @@
 {
     switch (what_hash (s)) {
     case TEA_HASH:
-	reiserfs_warning ("Using tea hash to sort names\n");
+	reiserfs_warning (s, "Using tea hash to sort names\n");
 	return keyed_hash;
     case YURA_HASH:
-	reiserfs_warning ("Using rupasov hash to sort names\n");
+	reiserfs_warning (s, "Using rupasov hash to sort names\n");
 	return yura_hash;
     case R5_HASH:
-	reiserfs_warning ("Using r5 hash to sort names\n");
+	reiserfs_warning (s, "Using r5 hash to sort names\n");
 	return r5_hash;
     }
     return NULL;
@@ -1131,12 +1156,11 @@
     unsigned long blocks;
     int jinit_done = 0 ;
     struct reiserfs_iget4_args args ;
-    int old_magic;
+    char *jdev_name;
     struct reiserfs_super_block * rs;
 
 
     memset (&s->u.reiserfs_sb, 0, sizeof (struct reiserfs_sb_info));
-
     /* Set default values for options: non-aggressive tails */
     s->u.reiserfs_sb.s_mount_opt = ( 1 << REISERFS_SMALLTAIL );
     /* default block allocator option: skip_busy */
@@ -1147,11 +1171,14 @@
     s->u.reiserfs_sb.s_alloc_options.preallocsize = 9;
 
     if (reiserfs_parse_options (s, (char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks) == 0) {
-	return NULL;
+      return NULL;
+
+
+
     }
 
     if (blocks) {
-  	printk("reserfs: resize option for remount only\n");
+  	reiserfs_warning(s,"zam-2013: reserfs resize option for remount only\n");
 	return NULL;
     }	
 
@@ -1162,16 +1189,15 @@
 	size = BLOCK_SIZE;
 	set_blocksize (s->s_dev, BLOCK_SIZE);
     }
-
-    /* read block (64-th 1k block), which can contain reiserfs super block */
-    if (read_super_block (s, size, REISERFS_DISK_OFFSET_IN_BYTES)) {
-	// try old format (undistributed bitmap, super block in 8-th 1k block of a device)
-	if (read_super_block (s, size, REISERFS_OLD_DISK_OFFSET_IN_BYTES)) 
-	    goto error;
-	else
-	    old_format = 1;
+    /* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */
+    if (!read_super_block (s, size, REISERFS_OLD_DISK_OFFSET_IN_BYTES))
+      old_format = 1;
+    /* try new format (64-th 1k block), which can contain reiserfs super block */
+    else if (read_super_block (s, size, REISERFS_DISK_OFFSET_IN_BYTES)) {
+      printk("sh-2021: reiserfs_read_super: can not find reiserfs on %s\n", bdevname(s->s_dev));
+      goto error;
     }
-
+    
     rs = SB_DISK_SUPER_BLOCK (s);
 
     /* Let's do basic sanity check to verify that underlying device is not
@@ -1188,7 +1214,7 @@
     s->u.reiserfs_sb.s_mount_state = REISERFS_VALID_FS ;
 
     if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { 
-	printk ("reiserfs_read_super: unable to read bitmap\n");
+	reiserfs_warning (s, "sh-2014: reiserfs_read_super: unable to read bitmap\n");
 	goto error;
     }
 #ifdef CONFIG_REISERFS_CHECK
@@ -1196,9 +1222,11 @@
     printk("reiserfs:warning: - it is slow mode for debugging.\n");
 #endif
 
-    // set_device_ro(s->s_dev, 1) ;
-    if (journal_init(s)) {
-	printk("reiserfs_read_super: unable to initialize journal space\n") ;
+    /* fixme */
+    jdev_name = NULL;
+
+    if( journal_init(s, jdev_name, old_format) ) {
+	reiserfs_warning(s, "sh-2022: reiserfs_read_super: unable to initialize journal space\n") ;
 	goto error ;
     } else {
 	jinit_done = 1 ; /* once this is set, journal_release must be called
@@ -1206,7 +1234,7 @@
 			 */
     }
     if (reread_meta_blocks(s)) {
-	printk("reiserfs_read_super: unable to reread meta blocks after journal init\n") ;
+	reiserfs_warning(s, "sh-2015: reiserfs_read_super: unable to reread meta blocks after journal init\n") ;
 	goto error ;
     }
 
@@ -1214,13 +1242,13 @@
 	goto error;
 
     if (is_read_only(s->s_dev) && !(s->s_flags & MS_RDONLY)) {
-        printk("clm-7000: Detected readonly device, marking FS readonly\n") ;
+        reiserfs_warning(s, "clm-7000: Detected readonly device, marking FS readonly\n") ;
 	s->s_flags |= MS_RDONLY ;
     }
     args.objectid = REISERFS_ROOT_PARENT_OBJECTID ;
     root_inode = iget4 (s, REISERFS_ROOT_OBJECTID, 0, (void *)(&args));
     if (!root_inode) {
-	printk ("reiserfs_read_super: get root inode failed\n");
+	reiserfs_warning (s, "reiserfs_read_super: get root inode failed\n");
 	goto error;
     }
 
@@ -1237,38 +1265,40 @@
       s->s_root = NULL ;
       goto error ;
     }
-
-    rs = SB_DISK_SUPER_BLOCK (s);
-    old_magic = strncmp (rs->s_magic,  REISER2FS_SUPER_MAGIC_STRING,
-                           strlen ( REISER2FS_SUPER_MAGIC_STRING));
-    if (!old_magic)
-	set_bit(REISERFS_3_6, &(s->u.reiserfs_sb.s_properties));
+    
+    if (is_reiserfs_3_5 (rs) || (is_reiserfs_jr (rs) && SB_VERSION (s) == REISERFS_VERSION_1))
+      set_bit(REISERFS_3_5, &(s->u.reiserfs_sb.s_properties));
     else
-	set_bit(REISERFS_3_5, &(s->u.reiserfs_sb.s_properties));
-
+      set_bit(REISERFS_3_6, &(s->u.reiserfs_sb.s_properties)); 
+    
     if (!(s->s_flags & MS_RDONLY)) {
 
 	journal_begin(&th, s, 1) ;
 	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
 
-        set_sb_state( rs, REISERFS_ERROR_FS );
-
-        if ( old_magic ) {
-	    // filesystem created under 3.5.x found
-	    if (convert_reiserfs (s)) {
-		reiserfs_warning("reiserfs: converting 3.5.x filesystem to the new format\n") ;
-		// after this 3.5.x will not be able to mount this partition
-		memcpy (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, 
-			sizeof (REISER2FS_SUPER_MAGIC_STRING));
-
-		reiserfs_convert_objectid_map_v1(s) ;
-		set_bit(REISERFS_3_6, &(s->u.reiserfs_sb.s_properties));
-		clear_bit(REISERFS_3_5, &(s->u.reiserfs_sb.s_properties));
-	    } else {
-		reiserfs_warning("reiserfs: using 3.5.x disk format\n") ;
-	    }
+        set_sb_umount_state( rs, REISERFS_ERROR_FS );
+ 	set_sb_fs_state (rs, 0);	
+	
+	if (old_format_only(s)) {
+	  /* filesystem of format 3.5 either with standard or non-standard
+	     journal */       
+	  if (convert_reiserfs (s)) {
+	    /* and -o conv is given */ 
+	    reiserfs_warning (s, "reiserfs: converting 3.5 filesystem to the 3.6 format\n") ;
+	    
+	    if (is_reiserfs_3_5 (rs))
+	      /* put magic string of 3.6 format. 2.2 will not be able to
+		 mount this filesystem anymore */
+	      memcpy (rs->s_v1.s_magic, reiserfs_3_6_magic_string, 
+		      sizeof (reiserfs_3_6_magic_string));
+	    
+	    set_sb_version(rs,REISERFS_VERSION_2);
+	    reiserfs_convert_objectid_map_v1(s) ;
+	    set_bit(REISERFS_3_6, &(s->u.reiserfs_sb.s_properties));
+	    clear_bit(REISERFS_3_5, &(s->u.reiserfs_sb.s_properties));
+	  }
 	}
-
+		
 	journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
 	journal_end(&th, s, 1) ;
 	
@@ -1276,11 +1306,8 @@
 	finish_unfinished (s);
 
 	s->s_dirt = 0;
-    } else {
-	if ( old_magic ) {
-	    reiserfs_warning("reiserfs: using 3.5.x disk format\n") ;
-	}
     }
+
     // mark hash in super block: it could be unset. overwrite should be ok
     set_sb_hash_function_code( rs, function2code(s->u.reiserfs_sb.s_hash_function ) );
 
@@ -1296,7 +1323,6 @@
     reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc );
     init_waitqueue_head (&(s->u.reiserfs_sb.s_wait));
 
-    printk("%s\n", reiserfs_get_version_string()) ;
     return s;
 
  error:
diff -urN linux-2.4.22-pre2/fs/reiserfs/tail_conversion.c linux-2.4.22-pre3/fs/reiserfs/tail_conversion.c
--- linux-2.4.22-pre2/fs/reiserfs/tail_conversion.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.22-pre3/fs/reiserfs/tail_conversion.c	2003-07-05 18:11:07.000000000 -0700
@@ -30,7 +30,7 @@
                                 key of unfm pointer to be pasted */
     int	n_blk_size,
       n_retval;	  /* returned value for reiserfs_insert_item and clones */
-    struct unfm_nodeinfo unfm_ptr;  /* Handle on an unformatted node
+    unp_t unfm_ptr;  /* Handle on an unformatted node
 				       that will be inserted in the
 				       tree. */
 
@@ -50,7 +50,7 @@
 
     // FIXME: we could avoid this 
     if ( search_for_position_by_key (sb, &end_key, path) == POSITION_FOUND ) {
-	reiserfs_warning ("PAP-14030: direct2indirect: "
+	reiserfs_warning (sb, "PAP-14030: direct2indirect: "
 			"pasted or inserted byte exists in the tree %K. "
 			"Use fsck to repair.\n", &end_key);
 	pathrelse(path);
@@ -59,8 +59,7 @@
     
     p_le_ih = PATH_PITEM_HEAD (path);
 
-    unfm_ptr.unfm_nodenum = cpu_to_le32 (unbh->b_blocknr);
-    unfm_ptr.unfm_freespace = 0; // ???
+    unfm_ptr = cpu_to_le32 (unbh->b_blocknr);
     
     if ( is_statdata_le_ih (p_le_ih) )  {
 	/* Insert new indirect item. */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-anakin/memory.h linux-2.4.22-pre3/include/asm-arm/arch-anakin/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-anakin/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-anakin/memory.h	2003-07-05 18:11:08.000000000 -0700
@@ -31,6 +31,4 @@
 #define __virt_to_bus__is_a_macro
 #define __bus_to_virt__is_a_macro
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-anakin/time.h linux-2.4.22-pre3/include/asm-arm/arch-anakin/time.h
--- linux-2.4.22-pre2/include/asm-arm/arch-anakin/time.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-anakin/time.h	2003-07-05 18:11:08.000000000 -0700
@@ -24,7 +24,6 @@
 setup_timer(void)
 {
 	timer_irq.handler = anakin_timer_interrupt;
-	timer_irq.flags = SA_INTERRUPT;
 	setup_arm_irq(IRQ_TICK, &timer_irq);
 }
 
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-arc/memory.h linux-2.4.22-pre3/include/asm-arm/arch-arc/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-arc/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-arc/memory.h	2003-07-05 18:11:08.000000000 -0700
@@ -50,6 +50,4 @@
 #define __bus_to_virt__is_a_macro
 #define __bus_to_virt(x)	(x)
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-arc/system.h linux-2.4.22-pre3/include/asm-arm/arch-arc/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-arc/system.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-arc/system.h	2003-07-05 18:11:08.000000000 -0700
@@ -8,9 +8,8 @@
  * published by the Free Software Foundation.
  */
 
-static void arch_idle(void)
+static inline void arch_idle(void)
 {
-	while (!current->need_resched && !hlt_counter);
 }
 
 static inline void arch_reset(char mode)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,415 @@
+// ----------------------------------------------------------------------------
+//          ATMEL Microcontroller Software Support  -  ROUSSET  -
+// ----------------------------------------------------------------------------
+//  The software is delivered "AS IS" without warranty or condition of any
+//  kind, either express, implied or statutory. This includes without
+//  limitation any warranty or condition with respect to merchantability or
+//  fitness for any particular purpose, or against the infringements of
+//  intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// File Name           : AT91RM9200.h
+// Object              : AT91RM9200 definitions
+// Generated           : AT91 SW Application Group  04/16/2003 (12:30:06)
+//
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_H
+#define AT91RM9200_H
+
+#ifndef __ASSEMBLY__
+
+ /* Hardware register definition */
+typedef volatile unsigned int AT91_REG;
+
+#endif	/* __ASSEMBLY__ */
+
+// *****************************************************************************
+//               PERIPHERAL ID DEFINITIONS FOR AT91RM9200
+// *****************************************************************************
+#define AT91C_ID_FIQ    ( 0) // Advanced Interrupt Controller (FIQ)
+#define AT91C_ID_SYS    ( 1) // System Peripheral
+#define AT91C_ID_PIOA   ( 2) // Parallel IO Controller A
+#define AT91C_ID_PIOB   ( 3) // Parallel IO Controller B
+#define AT91C_ID_PIOC   ( 4) // Parallel IO Controller C
+#define AT91C_ID_PIOD   ( 5) // Parallel IO Controller D
+#define AT91C_ID_US0    ( 6) // USART 0
+#define AT91C_ID_US1    ( 7) // USART 1
+#define AT91C_ID_US2    ( 8) // USART 2
+#define AT91C_ID_US3    ( 9) // USART 3
+#define AT91C_ID_MCI    (10) // Multimedia Card Interface
+#define AT91C_ID_UDP    (11) // USB Device Port
+#define AT91C_ID_TWI    (12) // Two-Wire Interface
+#define AT91C_ID_SPI    (13) // Serial Peripheral Interface
+#define AT91C_ID_SSC0   (14) // Serial Synchronous Controller 0
+#define AT91C_ID_SSC1   (15) // Serial Synchronous Controller 1
+#define AT91C_ID_SSC2   (16) // Serial Synchronous Controller 2
+#define AT91C_ID_TC0    (17) // Timer Counter 0
+#define AT91C_ID_TC1    (18) // Timer Counter 1
+#define AT91C_ID_TC2    (19) // Timer Counter 2
+#define AT91C_ID_TC3    (20) // Timer Counter 3
+#define AT91C_ID_TC4    (21) // Timer Counter 4
+#define AT91C_ID_TC5    (22) // Timer Counter 5
+#define AT91C_ID_UHP    (23) // USB Host port
+#define AT91C_ID_EMAC   (24) // Ethernet MAC
+#define AT91C_ID_IRQ0   (25) // Advanced Interrupt Controller (IRQ0)
+#define AT91C_ID_IRQ1   (26) // Advanced Interrupt Controller (IRQ1)
+#define AT91C_ID_IRQ2   (27) // Advanced Interrupt Controller (IRQ2)
+#define AT91C_ID_IRQ3   (28) // Advanced Interrupt Controller (IRQ3)
+#define AT91C_ID_IRQ4   (29) // Advanced Interrupt Controller (IRQ4)
+#define AT91C_ID_IRQ5   (30) // Advanced Interrupt Controller (IRQ5)
+#define AT91C_ID_IRQ6   (31) // Advanced Interrupt Controller (IRQ6)
+
+
+// *****************************************************************************
+//               BASE ADDRESS DEFINITIONS FOR AT91RM9200
+// *****************************************************************************
+#define AT91C_BASE_SYS		(0xFFFFF000) // (SYS) Base Address
+#define AT91C_BASE_PDC_SPI	(0xFFFE0100) // (PDC_SPI) Base Address
+#define AT91C_BASE_SPI		(0xFFFE0000) // (SPI) Base Address
+#define AT91C_BASE_PDC_SSC2	(0xFFFD8100) // (PDC_SSC2) Base Address
+#define AT91C_BASE_SSC2		(0xFFFD8000) // (SSC2) Base Address
+#define AT91C_BASE_PDC_SSC1	(0xFFFD4100) // (PDC_SSC1) Base Address
+#define AT91C_BASE_SSC1		(0xFFFD4000) // (SSC1) Base Address
+#define AT91C_BASE_PDC_SSC0	(0xFFFD0100) // (PDC_SSC0) Base Address
+#define AT91C_BASE_SSC0		(0xFFFD0000) // (SSC0) Base Address
+#define AT91C_BASE_PDC_US3	(0xFFFCC100) // (PDC_US3) Base Address
+#define AT91C_BASE_US3		(0xFFFCC000) // (US3) Base Address
+#define AT91C_BASE_PDC_US2	(0xFFFC8100) // (PDC_US2) Base Address
+#define AT91C_BASE_US2		(0xFFFC8000) // (US2) Base Address
+#define AT91C_BASE_PDC_US1	(0xFFFC4100) // (PDC_US1) Base Address
+#define AT91C_BASE_US1		(0xFFFC4000) // (US1) Base Address
+#define AT91C_BASE_PDC_US0	(0xFFFC0100) // (PDC_US0) Base Address
+#define AT91C_BASE_US0		(0xFFFC0000) // (US0) Base Address
+#define AT91C_BASE_EMAC		(0xFFFBC000) // (EMAC) Base Address
+#define AT91C_BASE_PDC_MCI	(0xFFFB4100) // (PDC_MCI) Base Address
+#define AT91C_BASE_TWI		(0xFFFB8000) // (TWI) Base Address
+#define AT91C_BASE_MCI		(0xFFFB4000) // (MCI) Base Address
+#define AT91C_BASE_UDP		(0xFFFB0000) // (UDP) Base Address
+#define AT91C_BASE_TC5		(0xFFFA4080) // (TC5) Base Address
+#define AT91C_BASE_TC4		(0xFFFA4040) // (TC4) Base Address
+#define AT91C_BASE_TC3		(0xFFFA4000) // (TC3) Base Address
+#define AT91C_BASE_TCB1		(0xFFFA4000) // (TCB1) Base Address
+#define AT91C_BASE_TC2		(0xFFFA0080) // (TC2) Base Address
+#define AT91C_BASE_TC1		(0xFFFA0040) // (TC1) Base Address
+#define AT91C_BASE_TC0		(0xFFFA0000) // (TC0) Base Address
+#define AT91C_BASE_TCB0		(0xFFFA0000) // (TCB0) Base Address
+
+
+// *****************************************************************************
+//               PIO DEFINITIONS FOR AT91RM9200
+// *****************************************************************************
+#define AT91C_PIO_PA0		(1 <<  0)
+#define AT91C_PA0_MISO		(AT91C_PIO_PA0) //  SPI Master In Slave
+#define AT91C_PA0_PCK3		(AT91C_PIO_PA0) //  PMC Programmable Clock Output 3
+#define AT91C_PIO_PA1		(1 <<  1)
+#define AT91C_PA1_MOSI		(AT91C_PIO_PA1) //  SPI Master Out Slave
+#define AT91C_PA1_PCK0		(AT91C_PIO_PA1) //  PMC Programmable Clock Output 0
+#define AT91C_PIO_PA2		(1 <<  2)
+#define AT91C_PA2_SPCK		(AT91C_PIO_PA2) //  SPI Serial Clock
+#define AT91C_PA2_IRQ4		(AT91C_PIO_PA2) //  AIC Interrupt Input 4
+#define AT91C_PIO_PA3		(1 <<  3)
+#define AT91C_PA3_NPCS0		(AT91C_PIO_PA3) //  SPI Peripheral Chip Select 0
+#define AT91C_PA3_IRQ5		(AT91C_PIO_PA3) //  AIC Interrupt Input 5
+#define AT91C_PIO_PA4		(1 <<  4)
+#define AT91C_PA4_NPCS1		(AT91C_PIO_PA4) //  SPI Peripheral Chip Select 1
+#define AT91C_PA4_PCK1		(AT91C_PIO_PA4) //  PMC Programmable Clock Output 1
+#define AT91C_PIO_PA5		(1 <<  5)
+#define AT91C_PA5_NPCS2		(AT91C_PIO_PA5) //  SPI Peripheral Chip Select 2
+#define AT91C_PA5_TXD3		(AT91C_PIO_PA5) //  USART 3 Transmit Data
+#define AT91C_PIO_PA6		(1 <<  6)
+#define AT91C_PA6_NPCS3		(AT91C_PIO_PA6) //  SPI Peripheral Chip Select 3
+#define AT91C_PA6_RXD3		(AT91C_PIO_PA6) //  USART 3 Receive Data
+#define AT91C_PIO_PA7		(1 <<  7)
+#define AT91C_PA7_ETXCK_EREFCK	(AT91C_PIO_PA7) //  Ethernet MAC Transmit Clock/Reference Clock
+#define AT91C_PA7_PCK2		(AT91C_PIO_PA7) //  PMC Programmable Clock 2
+#define AT91C_PIO_PA8		(1 <<  8)
+#define AT91C_PA8_ETXEN		(AT91C_PIO_PA8) //  Ethernet MAC Transmit Enable
+#define AT91C_PA8_MCCDB		(AT91C_PIO_PA8) //  Multimedia Card B Command
+#define AT91C_PIO_PA9		(1 <<  9)
+#define AT91C_PA9_ETX0		(AT91C_PIO_PA9) //  Ethernet MAC Transmit Data 0
+#define AT91C_PA9_MCDB0		(AT91C_PIO_PA9) //  Multimedia Card B Data 0
+#define AT91C_PIO_PA10		(1 << 10)
+#define AT91C_PA10_ETX1		(AT91C_PIO_PA10) //  Ethernet MAC Transmit Data 1
+#define AT91C_PA10_MCDB1	(AT91C_PIO_PA10) //  Multimedia Card B Data 1
+#define AT91C_PIO_PA11		(1 << 11)
+#define AT91C_PA11_ECRS_ECRSDV	(AT91C_PIO_PA11) //  Ethernet MAC Carrier Sense/Carrier Sense and Data Valid
+#define AT91C_PA11_MCDB2	(AT91C_PIO_PA11) //  Multimedia Card B Data 2
+#define AT91C_PIO_PA12		(1 << 12)
+#define AT91C_PA12_ERX0		(AT91C_PIO_PA12) //  Ethernet MAC Receive Data 0
+#define AT91C_PA12_MCDB3	(AT91C_PIO_PA12) //  Multimedia Card B Data 3
+#define AT91C_PIO_PA13 		(1 << 13)
+#define AT91C_PA13_ERX1		(AT91C_PIO_PA13) //  Ethernet MAC Receive Data 1
+#define AT91C_PA13_TCLK0	(AT91C_PIO_PA13) //  Timer Counter 0 external clock input
+#define AT91C_PIO_PA14		(1 << 14)
+#define AT91C_PA14_ERXER	(AT91C_PIO_PA14) //  Ethernet MAC Receive Error
+#define AT91C_PA14_TCLK1	(AT91C_PIO_PA14) //  Timer Counter 1 external clock input
+#define AT91C_PIO_PA15		(1 << 15)
+#define AT91C_PA15_EMDC		(AT91C_PIO_PA15) //  Ethernet MAC Management Data Clock
+#define AT91C_PA15_TCLK2	(AT91C_PIO_PA15) //  Timer Counter 2 external clock input
+#define AT91C_PIO_PA16		(1 << 16)
+#define AT91C_PA16_EMDIO	(AT91C_PIO_PA16) //  Ethernet MAC Management Data Input/Output
+#define AT91C_PA16_IRQ6		(AT91C_PIO_PA16) //  AIC Interrupt input 6
+#define AT91C_PIO_PA17		(1 << 17)
+#define AT91C_PA17_TXD0		(AT91C_PIO_PA17) //  USART 0 Transmit Data
+#define AT91C_PA17_TIOA0	(AT91C_PIO_PA17) //  Timer Counter 0 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PA18		(1 << 18)
+#define AT91C_PA18_RXD0		(AT91C_PIO_PA18) //  USART 0 Receive Data
+#define AT91C_PA18_TIOB0	(AT91C_PIO_PA18) //  Timer Counter 0 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PA19		(1 << 19)
+#define AT91C_PA19_SCK0		(AT91C_PIO_PA19) //  USART 0 Serial Clock
+#define AT91C_PA19_TIOA1	(AT91C_PIO_PA19) //  Timer Counter 1 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PA20		(1 << 20)
+#define AT91C_PA20_CTS0		(AT91C_PIO_PA20) //  USART 0 Clear To Send
+#define AT91C_PA20_TIOB1	(AT91C_PIO_PA20) //  Timer Counter 1 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PA21		(1 << 21)
+#define AT91C_PA21_RTS0		(AT91C_PIO_PA21) //  USART 0 Ready To Send
+#define AT91C_PA21_TIOA2	(AT91C_PIO_PA21) //  Timer Counter 2 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PA22		(1 << 22)
+#define AT91C_PA22_RXD2		(AT91C_PIO_PA22) //  USART 2 Receive Data
+#define AT91C_PA22_TIOB2	(AT91C_PIO_PA22) //  Timer Counter 2 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PA23		(1 << 23)
+#define AT91C_PA23_TXD2		(AT91C_PIO_PA23) //  USART 2 Transmit Data
+#define AT91C_PA23_IRQ3		(AT91C_PIO_PA23) //  Interrupt input 3
+#define AT91C_PIO_PA24		(1 << 24)
+#define AT91C_PA24_SCK2		(AT91C_PIO_PA24) //  USART2 Serial Clock
+#define AT91C_PA24_PCK1		(AT91C_PIO_PA24) //  PMC Programmable Clock Output 1
+#define AT91C_PIO_PA25		(1 << 25)
+#define AT91C_PA25_TWD		(AT91C_PIO_PA25) //  TWI Two-wire Serial Data
+#define AT91C_PA25_IRQ2		(AT91C_PIO_PA25) //  Interrupt input 2
+#define AT91C_PIO_PA26		(1 << 26)
+#define AT91C_PA26_TWCK		(AT91C_PIO_PA26) //  TWI Two-wire Serial Clock
+#define AT91C_PA26_IRQ1		(AT91C_PIO_PA26) //  Interrupt input 1
+#define AT91C_PIO_PA27		(1 << 27)
+#define AT91C_PA27_MCCK		(AT91C_PIO_PA27) //  Multimedia Card Clock
+#define AT91C_PA27_TCLK3	(AT91C_PIO_PA27) //  Timer Counter 3 External Clock Input
+#define AT91C_PIO_PA28		(1 << 28)
+#define AT91C_PA28_MCCDA	(AT91C_PIO_PA28) //  Multimedia Card A Command
+#define AT91C_PA28_TCLK4	(AT91C_PIO_PA28) //  Timer Counter 4 external Clock Input
+#define AT91C_PIO_PA29		(1 << 29)
+#define AT91C_PA29_MCDA0	(AT91C_PIO_PA29) //  Multimedia Card A Data 0
+#define AT91C_PA29_TCLK5	(AT91C_PIO_PA29) //  Timer Counter 5 external clock input
+#define AT91C_PIO_PA30		(1 << 30)
+#define AT91C_PA30_DRXD		(AT91C_PIO_PA30) //  DBGU Debug Receive Data
+#define AT91C_PA30_CTS2		(AT91C_PIO_PA30) //  USART 2 Clear To Send
+#define AT91C_PIO_PA31		(1 << 31)
+#define AT91C_PA31_DTXD		(AT91C_PIO_PA31) //  DBGU Debug Transmit Data
+#define AT91C_PA31_RTS2		(AT91C_PIO_PA31) //  USART 2 Ready To Send
+
+#define AT91C_PIO_PB0		(1 <<  0)
+#define AT91C_PB0_TF0		(AT91C_PIO_PB0) //  SSC Transmit Frame Sync 0
+#define AT91C_PB0_RTS3		(AT91C_PIO_PB0) //  USART 3 Ready To Send
+#define AT91C_PIO_PB1		(1 <<  1)
+#define AT91C_PB1_TK0		(AT91C_PIO_PB1) //  SSC Transmit Clock 0
+#define AT91C_PB1_CTS3		(AT91C_PIO_PB1) //  USART 3 Clear To Send
+#define AT91C_PIO_PB2		(1 <<  2)
+#define AT91C_PB2_TD0		(AT91C_PIO_PB2) //  SSC Transmit data
+#define AT91C_PB2_SCK3		(AT91C_PIO_PB2) //  USART 3 Serial Clock
+#define AT91C_PIO_PB3		(1 <<  3)
+#define AT91C_PB3_RD0		(AT91C_PIO_PB3) //  SSC Receive Data
+#define AT91C_PB3_MCDA1		(AT91C_PIO_PB3) //  Multimedia Card A Data 1
+#define AT91C_PIO_PB4		(1 <<  4)
+#define AT91C_PB4_RK0		(AT91C_PIO_PB4) //  SSC Receive Clock
+#define AT91C_PB4_MCDA2		(AT91C_PIO_PB4) //  Multimedia Card A Data 2
+#define AT91C_PIO_PB5		(1 <<  5)
+#define AT91C_PB5_RF0		(AT91C_PIO_PB5) //  SSC Receive Frame Sync 0
+#define AT91C_PB5_MCDA3		(AT91C_PIO_PB5) //  Multimedia Card A Data 3
+#define AT91C_PIO_PB6		(1 <<  6)
+#define AT91C_PB6_TF1		(AT91C_PIO_PB6) //  SSC Transmit Frame Sync 1
+#define AT91C_PB6_TIOA3		(AT91C_PIO_PB6) //  Timer Counter 4 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PB7		(1 <<  7)
+#define AT91C_PB7_TK1		(AT91C_PIO_PB7) //  SSC Transmit Clock 1
+#define AT91C_PB7_TIOB3		(AT91C_PIO_PB7) //  Timer Counter 3 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PB8		(1 <<  8)
+#define AT91C_PB8_TD1		(AT91C_PIO_PB8) //  SSC Transmit Data 1
+#define AT91C_PB8_TIOA4		(AT91C_PIO_PB8) //  Timer Counter 4 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PB9		(1 <<  9)
+#define AT91C_PB9_RD1		(AT91C_PIO_PB9) //  SSC Receive Data 1
+#define AT91C_PB9_TIOB4		(AT91C_PIO_PB9) //  Timer Counter 4 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PB10		(1 << 10)
+#define AT91C_PB10_RK1		(AT91C_PIO_PB10) //  SSC Receive Clock 1
+#define AT91C_PB10_TIOA5	(AT91C_PIO_PB10) //  Timer Counter 5 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PB11		(1 << 11)
+#define AT91C_PB11_RF1		(AT91C_PIO_PB11) //  SSC Receive Frame Sync 1
+#define AT91C_PB11_TIOB5	(AT91C_PIO_PB11) //  Timer Counter 5 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PB12		(1 << 12)
+#define AT91C_PB12_TF2		(AT91C_PIO_PB12) //  SSC Transmit Frame Sync 2
+#define AT91C_PB12_ETX2		(AT91C_PIO_PB12) //  Ethernet MAC Transmit Data 2
+#define AT91C_PIO_PB13		(1 << 13)
+#define AT91C_PB13_TK2		(AT91C_PIO_PB13) //  SSC Transmit Clock 2
+#define AT91C_PB13_ETX3		(AT91C_PIO_PB13) //  Ethernet MAC Transmit Data 3
+#define AT91C_PIO_PB14		(1 << 14)
+#define AT91C_PB14_TD2		(AT91C_PIO_PB14) //  SSC Transmit Data 2
+#define AT91C_PB14_ETXER	(AT91C_PIO_PB14) //  Ethernet MAC Transmikt Coding Error
+#define AT91C_PIO_PB15		(1 << 15)
+#define AT91C_PB15_RD2		(AT91C_PIO_PB15) //  SSC Receive Data 2
+#define AT91C_PB15_ERX2		(AT91C_PIO_PB15) //  Ethernet MAC Receive Data 2
+#define AT91C_PIO_PB16		(1 << 16)
+#define AT91C_PB16_RK2		(AT91C_PIO_PB16) //  SSC Receive Clock 2
+#define AT91C_PB16_ERX3		(AT91C_PIO_PB16) //  Ethernet MAC Receive Data 3
+#define AT91C_PIO_PB17		(1 << 17)
+#define AT91C_PB17_RF2		(AT91C_PIO_PB17) //  SSC Receive Frame Sync 2
+#define AT91C_PB17_ERXDV	(AT91C_PIO_PB17) //  Ethernet MAC Receive Data Valid
+#define AT91C_PIO_PB18		(1 << 18)
+#define AT91C_PB18_RI1		(AT91C_PIO_PB18) //  USART 1 Ring Indicator
+#define AT91C_PB18_ECOL		(AT91C_PIO_PB18) //  Ethernet MAC Collision Detected
+#define AT91C_PIO_PB19		(1 << 19)
+#define AT91C_PB19_DTR1		(AT91C_PIO_PB19) //  USART 1 Data Terminal ready
+#define AT91C_PB19_ERXCK	(AT91C_PIO_PB19) //  Ethernet MAC Receive Clock
+#define AT91C_PIO_PB20		(1 << 20)
+#define AT91C_PB20_TXD1		(AT91C_PIO_PB20) //  USART 1 Transmit Data
+#define AT91C_PIO_PB21		(1 << 21)
+#define AT91C_PB21_RXD1		(AT91C_PIO_PB21) //  USART 1 Receive Data
+#define AT91C_PIO_PB22		(1 << 22)
+#define AT91C_PB22_SCK1		(AT91C_PIO_PB22) //  USART1 Serial Clock
+#define AT91C_PIO_PB23		(1 << 23)
+#define AT91C_PB23_DCD1		(AT91C_PIO_PB23) //  USART 1 Data Carrier Detect
+#define AT91C_PIO_PB24		(1 << 24)
+#define AT91C_PB24_CTS1		(AT91C_PIO_PB24) //  USART 1 Clear To Send
+#define AT91C_PIO_PB25		(1 << 25)
+#define AT91C_PB25_DSR1		(AT91C_PIO_PB25) //  USART 1 Data Set ready
+#define AT91C_PB25_EF100	(AT91C_PIO_PB25) //  Ethernet MAC Force 100 Mbits/sec
+#define AT91C_PIO_PB26		(1 << 26)
+#define AT91C_PB26_RTS1		(AT91C_PIO_PB26) //  USART 1 Ready To Send
+#define AT91C_PIO_PB27		(1 << 27)
+#define AT91C_PB27_PCK0		(AT91C_PIO_PB27) //  PMC Programmable Clock Output 0
+#define AT91C_PIO_PB28		(1 << 28)
+#define AT91C_PB28_FIQ		(AT91C_PIO_PB28) //  AIC Fast Interrupt Input
+#define AT91C_PIO_PB29		(1 << 29)
+#define AT91C_PB29_IRQ0		(AT91C_PIO_PB29) //  Interrupt input 0
+
+#define AT91C_PIO_PC0		(1 <<  0)
+#define AT91C_PC0_BFCK		(AT91C_PIO_PC0) //  Burst Flash Clock
+#define AT91C_PIO_PC1		(1 <<  1)
+#define AT91C_PC1_BFRDY_SMOE	(AT91C_PIO_PC1) //  Burst Flash Ready
+#define AT91C_PIO_PC2		(1 <<  2)
+#define AT91C_PC2_BFAVD		(AT91C_PIO_PC2) //  Burst Flash Address Valid
+#define AT91C_PIO_PC3		(1 <<  3)
+#define AT91C_PC3_BFBAA_SMWE	(AT91C_PIO_PC3) //  Burst Flash Address Advance / SmartMedia Write Enable
+#define AT91C_PIO_PC4		(1 <<  4)
+#define AT91C_PC4_BFOE		(AT91C_PIO_PC4) //  Burst Flash Output Enable
+#define AT91C_PIO_PC5		(1 <<  5)
+#define AT91C_PC5_BFWE		(AT91C_PIO_PC5) //  Burst Flash Write Enable
+#define AT91C_PIO_PC6		(1 <<  6)
+#define AT91C_PC6_NWAIT		(AT91C_PIO_PC6) //  NWAIT
+#define AT91C_PIO_PC7		(1 <<  7)
+#define AT91C_PC7_A23		(AT91C_PIO_PC7) //  Address Bus[23]
+#define AT91C_PIO_PC8		(1 <<  8)
+#define AT91C_PC8_A24		(AT91C_PIO_PC8) //  Address Bus[24]
+#define AT91C_PIO_PC9		(1 <<  9)
+#define AT91C_PC9_A25_CFRNW	(AT91C_PIO_PC9) //  Address Bus[25] /  Compact Flash Read Not Write
+#define AT91C_PIO_PC10		(1 << 10)
+#define AT91C_PC10_NCS4_CFCS	(AT91C_PIO_PC10) //  Compact Flash Chip Select
+#define AT91C_PIO_PC11		(1 << 11)
+#define AT91C_PC11_NCS5_CFCE1	(AT91C_PIO_PC11) //  Chip Select 5 / Compact Flash Chip Enable 1
+#define AT91C_PIO_PC12		(1 << 12)
+#define AT91C_PC12_NCS6_CFCE2	(AT91C_PIO_PC12) //  Chip Select 6 / Compact Flash Chip Enable 2
+#define AT91C_PIO_PC13		(1 << 13)
+#define AT91C_PC13_NCS7		(AT91C_PIO_PC13) //  Chip Select 7
+#define AT91C_PIO_PC14		(1 << 14)
+#define AT91C_PIO_PC15		(1 << 15)
+#define AT91C_PIO_PC16		(1 << 16)
+#define AT91C_PC16_D16		(AT91C_PIO_PC16) //  Data Bus [16]
+#define AT91C_PIO_PC17		(1 << 17)
+#define AT91C_PC17_D17		(AT91C_PIO_PC17) //  Data Bus [17]
+#define AT91C_PIO_PC18		(1 << 18)
+#define AT91C_PC18_D18		(AT91C_PIO_PC18) //  Data Bus [18]
+#define AT91C_PIO_PC19		(1 << 19)
+#define AT91C_PC19_D19		(AT91C_PIO_PC19) //  Data Bus [19]
+#define AT91C_PIO_PC20		(1 << 20)
+#define AT91C_PC20_D20		(AT91C_PIO_PC20) //  Data Bus [20]
+#define AT91C_PIO_PC21		(1 << 21)
+#define AT91C_PC21_D21		(AT91C_PIO_PC21) //  Data Bus [21]
+#define AT91C_PIO_PC22		(1 << 22)
+#define AT91C_PC22_D22		(AT91C_PIO_PC22) //  Data Bus [22]
+#define AT91C_PIO_PC23		(1 << 23)
+#define AT91C_PC23_D23		(AT91C_PIO_PC23) //  Data Bus [23]
+#define AT91C_PIO_PC24		(1 << 24)
+#define AT91C_PC24_D24		(AT91C_PIO_PC24) //  Data Bus [24]
+#define AT91C_PIO_PC25		(1 << 25)
+#define AT91C_PC25_D25		(AT91C_PIO_PC25) //  Data Bus [25]
+#define AT91C_PIO_PC26		(1 << 26)
+#define AT91C_PC26_D26		(AT91C_PIO_PC26) //  Data Bus [26]
+#define AT91C_PIO_PC27		(1 << 27)
+#define AT91C_PC27_D27		(AT91C_PIO_PC27) //  Data Bus [27]
+#define AT91C_PIO_PC28		(1 << 28)
+#define AT91C_PC28_D28		(AT91C_PIO_PC28) //  Data Bus [28]
+#define AT91C_PIO_PC29		(1 << 29)
+#define AT91C_PC29_D29		(AT91C_PIO_PC29) //  Data Bus [29]
+#define AT91C_PIO_PC30		(1 << 30)
+#define AT91C_PC30_D30		(AT91C_PIO_PC30) //  Data Bus [30]
+#define AT91C_PIO_PC31		(1 << 31)
+#define AT91C_PC31_D31		(AT91C_PIO_PC31) //  Data Bus [31]
+
+#define AT91C_PIO_PD0		(1 <<  0)
+#define AT91C_PD0_ETX0		(AT91C_PIO_PD0) //  Ethernet MAC Transmit Data 0
+#define AT91C_PIO_PD1		(1 <<  1)
+#define AT91C_PD1_ETX1		(AT91C_PIO_PD1) //  Ethernet MAC Transmit Data 1
+#define AT91C_PIO_PD2		(1 <<  2)
+#define AT91C_PD2_ETX2		(AT91C_PIO_PD2) //  Ethernet MAC Transmit Data 2
+#define AT91C_PIO_PD3		(1 <<  3)
+#define AT91C_PD3_ETX3		(AT91C_PIO_PD3) //  Ethernet MAC Transmit Data 3
+#define AT91C_PIO_PD4		(1 <<  4)
+#define AT91C_PD4_ETXEN		(AT91C_PIO_PD4) //  Ethernet MAC Transmit Enable
+#define AT91C_PIO_PD5		(1 <<  5)
+#define AT91C_PD5_ETXER		(AT91C_PIO_PD5) //  Ethernet MAC Transmit Coding Error
+#define AT91C_PIO_PD6		(1 <<  6)
+#define AT91C_PD6_DTXD		(AT91C_PIO_PD6) //  DBGU Debug Transmit Data
+#define AT91C_PIO_PD7		(1 <<  7)
+#define AT91C_PD7_PCK0		(AT91C_PIO_PD7) //  PMC Programmable Clock Output 0
+#define AT91C_PD7_TSYNC		(AT91C_PIO_PD7) //  ETM Synchronization signal
+#define AT91C_PIO_PD8		(1 <<  8)
+#define AT91C_PD8_PCK1		(AT91C_PIO_PD8) //  PMC Programmable Clock Output 1
+#define AT91C_PD8_TCLK		(AT91C_PIO_PD8) //  ETM Trace Clock signal
+#define AT91C_PIO_PD9		(1 <<  9)
+#define AT91C_PD9_PCK2		(AT91C_PIO_PD9) //  PMC Programmable Clock 2
+#define AT91C_PD9_TPS0		(AT91C_PIO_PD9) //  ETM ARM9 pipeline status 0
+#define AT91C_PIO_PD10		(1 << 10)
+#define AT91C_PD10_PCK3		(AT91C_PIO_PD10) //  PMC Programmable Clock Output 3
+#define AT91C_PD10_TPS1		(AT91C_PIO_PD10) //  ETM ARM9 pipeline status 1
+#define AT91C_PIO_PD11		(1 << 11)
+#define AT91C_PD11_TPS2		(AT91C_PIO_PD11) //  ETM ARM9 pipeline status 2
+#define AT91C_PIO_PD12		(1 << 12)
+#define AT91C_PD12_TPK0		(AT91C_PIO_PD12) //  ETM Trace Packet 0
+#define AT91C_PIO_PD13		(1 << 13)
+#define AT91C_PD13_TPK1		(AT91C_PIO_PD13) //  ETM Trace Packet 1
+#define AT91C_PIO_PD14		(1 << 14)
+#define AT91C_PD14_TPK2		(AT91C_PIO_PD14) //  ETM Trace Packet 2
+#define AT91C_PIO_PD15		(1 << 15)
+#define AT91C_PD15_TD0		(AT91C_PIO_PD15) //  SSC Transmit data
+#define AT91C_PD15_TPK3		(AT91C_PIO_PD15) //  ETM Trace Packet 3
+#define AT91C_PIO_PD16		(1 << 16)
+#define AT91C_PD16_TD1		(AT91C_PIO_PD16) //  SSC Transmit Data 1
+#define AT91C_PD16_TPK4		(AT91C_PIO_PD16) //  ETM Trace Packet 4
+#define AT91C_PIO_PD17		(1 << 17)
+#define AT91C_PD17_TD2		(AT91C_PIO_PD17) //  SSC Transmit Data 2
+#define AT91C_PD17_TPK5		(AT91C_PIO_PD17) //  ETM Trace Packet 5
+#define AT91C_PIO_PD18		(1 << 18)
+#define AT91C_PD18_NPCS1	(AT91C_PIO_PD18) //  SPI Peripheral Chip Select 1
+#define AT91C_PD18_TPK6		(AT91C_PIO_PD18) //  ETM Trace Packet 6
+#define AT91C_PIO_PD19		(1 << 19)
+#define AT91C_PD19_NPCS2	(AT91C_PIO_PD19) //  SPI Peripheral Chip Select 2
+#define AT91C_PD19_TPK7		(AT91C_PIO_PD19) //  ETM Trace Packet 7
+#define AT91C_PIO_PD20		(1 << 20)
+#define AT91C_PD20_NPCS3	(AT91C_PIO_PD20) //  SPI Peripheral Chip Select 3
+#define AT91C_PD20_TPK8		(AT91C_PIO_PD20) //  ETM Trace Packet 8
+#define AT91C_PIO_PD21		(1 << 21)
+#define AT91C_PD21_RTS0		(AT91C_PIO_PD21) //  Usart 0 Ready To Send
+#define AT91C_PD21_TPK9		(AT91C_PIO_PD21) //  ETM Trace Packet 9
+#define AT91C_PIO_PD22		(1 << 22)
+#define AT91C_PD22_RTS1		(AT91C_PIO_PD22) //  Usart 0 Ready To Send
+#define AT91C_PD22_TPK10	(AT91C_PIO_PD22) //  ETM Trace Packet 10
+#define AT91C_PIO_PD23		(1 << 23)
+#define AT91C_PD23_RTS2		(AT91C_PIO_PD23) //  USART 2 Ready To Send
+#define AT91C_PD23_TPK11	(AT91C_PIO_PD23) //  ETM Trace Packet 11
+#define AT91C_PIO_PD24		(1 << 24)
+#define AT91C_PD24_RTS3		(AT91C_PIO_PD24) //  USART 3 Ready To Send
+#define AT91C_PD24_TPK12	(AT91C_PIO_PD24) //  ETM Trace Packet 12
+#define AT91C_PIO_PD25		(1 << 25)
+#define AT91C_PD25_DTR1		(AT91C_PIO_PD25) //  USART 1 Data Terminal ready
+#define AT91C_PD25_TPK13	(AT91C_PIO_PD25) //  ETM Trace Packet 13
+#define AT91C_PIO_PD26		(1 << 26)
+#define AT91C_PD26_TPK14	(AT91C_PIO_PD26) //  ETM Trace Packet 14
+#define AT91C_PIO_PD27		(1 << 27)
+#define AT91C_PD27_TPK15	(AT91C_PIO_PD27) //  ETM Trace Packet 15
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_EMAC.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_EMAC.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_EMAC.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_EMAC.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,144 @@
+// ----------------------------------------------------------------------------
+//          ATMEL Microcontroller Software Support  -  ROUSSET  -
+// ----------------------------------------------------------------------------
+//  The software is delivered "AS IS" without warranty or condition of any
+//  kind, either express, implied or statutory. This includes without
+//  limitation any warranty or condition with respect to merchantability or
+//  fitness for any particular purpose, or against the infringements of
+//  intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// File Name           : AT91RM9200.h
+// Object              : AT91RM9200 / EMAC definitions
+// Generated           : AT91 SW Application Group  01/17/2003 (13:41:21)
+//
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_EMAC_H
+#define AT91RM9200_EMAC_H
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Ethernet MAC
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+
+typedef struct _AT91S_EMAC {
+	AT91_REG	 EMAC_CTL; 	// Network Control Register
+	AT91_REG	 EMAC_CFG; 	// Network Configuration Register
+	AT91_REG	 EMAC_SR; 	// Network Status Register
+	AT91_REG	 EMAC_TAR; 	// Transmit Address Register
+	AT91_REG	 EMAC_TCR; 	// Transmit Control Register
+	AT91_REG	 EMAC_TSR; 	// Transmit Status Register
+	AT91_REG	 EMAC_RBQP; 	// Receive Buffer Queue Pointer
+	AT91_REG	 Reserved0[1]; 	//
+	AT91_REG	 EMAC_RSR; 	// Receive Status Register
+	AT91_REG	 EMAC_ISR; 	// Interrupt Status Register
+	AT91_REG	 EMAC_IER; 	// Interrupt Enable Register
+	AT91_REG	 EMAC_IDR; 	// Interrupt Disable Register
+	AT91_REG	 EMAC_IMR; 	// Interrupt Mask Register
+	AT91_REG	 EMAC_MAN; 	// PHY Maintenance Register
+	AT91_REG	 Reserved1[2]; 	//
+	AT91_REG	 EMAC_FRA; 	// Frames Transmitted OK Register
+	AT91_REG	 EMAC_SCOL; 	// Single Collision Frame Register
+	AT91_REG	 EMAC_MCOL; 	// Multiple Collision Frame Register
+	AT91_REG	 EMAC_OK; 	// Frames Received OK Register
+	AT91_REG	 EMAC_SEQE; 	// Frame Check Sequence Error Register
+	AT91_REG	 EMAC_ALE; 	// Alignment Error Register
+	AT91_REG	 EMAC_DTE; 	// Deferred Transmission Frame Register
+	AT91_REG	 EMAC_LCOL; 	// Late Collision Register
+	AT91_REG	 EMAC_ECOL; 	// Excessive Collision Register
+	AT91_REG	 EMAC_CSE; 	// Carrier Sense Error Register
+	AT91_REG	 EMAC_TUE; 	// Transmit Underrun Error Register
+	AT91_REG	 EMAC_CDE; 	// Code Error Register
+	AT91_REG	 EMAC_ELR; 	// Excessive Length Error Register
+	AT91_REG	 EMAC_RJB; 	// Receive Jabber Register
+	AT91_REG	 EMAC_USF; 	// Undersize Frame Register
+	AT91_REG	 EMAC_SQEE; 	// SQE Test Error Register
+	AT91_REG	 EMAC_DRFC; 	// Discarded RX Frame Register
+	AT91_REG	 Reserved2[3]; 	//
+	AT91_REG	 EMAC_HSH; 	// Hash Address High[63:32]
+	AT91_REG	 EMAC_HSL; 	// Hash Address Low[31:0]
+	AT91_REG	 EMAC_SA1L; 	// Specific Address 1 Low, First 4 bytes
+	AT91_REG	 EMAC_SA1H; 	// Specific Address 1 High, Last 2 bytes
+	AT91_REG	 EMAC_SA2L; 	// Specific Address 2 Low, First 4 bytes
+	AT91_REG	 EMAC_SA2H; 	// Specific Address 2 High, Last 2 bytes
+	AT91_REG	 EMAC_SA3L; 	// Specific Address 3 Low, First 4 bytes
+	AT91_REG	 EMAC_SA3H; 	// Specific Address 3 High, Last 2 bytes
+	AT91_REG	 EMAC_SA4L; 	// Specific Address 4 Low, First 4 bytes
+	AT91_REG	 EMAC_SA4H; 	// Specific Address 4 High, Last 2 bytesr
+} AT91S_EMAC, *AT91PS_EMAC;
+
+#endif
+
+// -------- EMAC_CTL : (EMAC Offset: 0x0)  --------
+#define AT91C_EMAC_LB         ( 0x1 <<  0) // (EMAC) Loopback. Optional. When set, loopback signal is at high level.
+#define AT91C_EMAC_LBL        ( 0x1 <<  1) // (EMAC) Loopback local.
+#define AT91C_EMAC_RE         ( 0x1 <<  2) // (EMAC) Receive enable.
+#define AT91C_EMAC_TE         ( 0x1 <<  3) // (EMAC) Transmit enable.
+#define AT91C_EMAC_MPE        ( 0x1 <<  4) // (EMAC) Management port enable.
+#define AT91C_EMAC_CSR        ( 0x1 <<  5) // (EMAC) Clear statistics registers.
+#define AT91C_EMAC_ISR        ( 0x1 <<  6) // (EMAC) Increment statistics registers.
+#define AT91C_EMAC_WES        ( 0x1 <<  7) // (EMAC) Write enable for statistics registers.
+#define AT91C_EMAC_BP         ( 0x1 <<  8) // (EMAC) Back pressure.
+// -------- EMAC_CFG : (EMAC Offset: 0x4) Network Configuration Register --------
+#define AT91C_EMAC_SPD        ( 0x1 <<  0) // (EMAC) Speed.
+#define AT91C_EMAC_FD         ( 0x1 <<  1) // (EMAC) Full duplex.
+#define AT91C_EMAC_BR         ( 0x1 <<  2) // (EMAC) Bit rate.
+#define AT91C_EMAC_CAF        ( 0x1 <<  4) // (EMAC) Copy all frames.
+#define AT91C_EMAC_NBC        ( 0x1 <<  5) // (EMAC) No broadcast.
+#define AT91C_EMAC_MTI        ( 0x1 <<  6) // (EMAC) Multicast hash enable
+#define AT91C_EMAC_UNI        ( 0x1 <<  7) // (EMAC) Unicast hash enable.
+#define AT91C_EMAC_BIG        ( 0x1 <<  8) // (EMAC) Receive 1522 bytes.
+#define AT91C_EMAC_EAE        ( 0x1 <<  9) // (EMAC) External address match enable.
+#define AT91C_EMAC_CLK        ( 0x3 << 10) // (EMAC)
+#define 	AT91C_EMAC_CLK_HCLK_8               ( 0x0 << 10) // (EMAC) HCLK divided by 8
+#define 	AT91C_EMAC_CLK_HCLK_16              ( 0x1 << 10) // (EMAC) HCLK divided by 16
+#define 	AT91C_EMAC_CLK_HCLK_32              ( 0x2 << 10) // (EMAC) HCLK divided by 32
+#define 	AT91C_EMAC_CLK_HCLK_64              ( 0x3 << 10) // (EMAC) HCLK divided by 64
+#define AT91C_EMAC_RTY        ( 0x1 << 12) // (EMAC)
+#define AT91C_EMAC_RMII       ( 0x1 << 13) // (EMAC)
+// -------- EMAC_SR : (EMAC Offset: 0x8) Network Status Register --------
+#define AT91C_EMAC_MDIO       ( 0x1 <<  1) // (EMAC)
+#define AT91C_EMAC_IDLE       ( 0x1 <<  2) // (EMAC)
+// -------- EMAC_TCR : (EMAC Offset: 0x10) Transmit Control Register --------
+#define AT91C_EMAC_LEN        ( 0x7FF <<  0) // (EMAC)
+#define AT91C_EMAC_NCRC       ( 0x1 << 15) // (EMAC)
+// -------- EMAC_TSR : (EMAC Offset: 0x14) Transmit Control Register --------
+#define AT91C_EMAC_OVR        ( 0x1 <<  0) // (EMAC)
+#define AT91C_EMAC_COL        ( 0x1 <<  1) // (EMAC)
+#define AT91C_EMAC_RLE        ( 0x1 <<  2) // (EMAC)
+#define AT91C_EMAC_TXIDLE     ( 0x1 <<  3) // (EMAC)
+#define AT91C_EMAC_BNQ        ( 0x1 <<  4) // (EMAC)
+#define AT91C_EMAC_COMP       ( 0x1 <<  5) // (EMAC)
+#define AT91C_EMAC_UND        ( 0x1 <<  6) // (EMAC)
+// -------- EMAC_RSR : (EMAC Offset: 0x20) Receive Status Register --------
+#define AT91C_EMAC_BNA        ( 0x1 <<  0) // (EMAC)
+#define AT91C_EMAC_REC        ( 0x1 <<  1) // (EMAC)
+// -------- EMAC_ISR : (EMAC Offset: 0x24) Interrupt Status Register --------
+#define AT91C_EMAC_DONE       ( 0x1 <<  0) // (EMAC)
+#define AT91C_EMAC_RCOM       ( 0x1 <<  1) // (EMAC)
+#define AT91C_EMAC_RBNA       ( 0x1 <<  2) // (EMAC)
+#define AT91C_EMAC_TOVR       ( 0x1 <<  3) // (EMAC)
+#define AT91C_EMAC_TUND       ( 0x1 <<  4) // (EMAC)
+#define AT91C_EMAC_RTRY       ( 0x1 <<  5) // (EMAC)
+#define AT91C_EMAC_TBRE       ( 0x1 <<  6) // (EMAC)
+#define AT91C_EMAC_TCOM       ( 0x1 <<  7) // (EMAC)
+#define AT91C_EMAC_TIDLE      ( 0x1 <<  8) // (EMAC)
+#define AT91C_EMAC_LINK       ( 0x1 <<  9) // (EMAC)
+#define AT91C_EMAC_ROVR       ( 0x1 << 10) // (EMAC)
+#define AT91C_EMAC_HRESP      ( 0x1 << 11) // (EMAC)
+// -------- EMAC_IER : (EMAC Offset: 0x28) Interrupt Enable Register --------
+// -------- EMAC_IDR : (EMAC Offset: 0x2c) Interrupt Disable Register --------
+// -------- EMAC_IMR : (EMAC Offset: 0x30) Interrupt Mask Register --------
+// -------- EMAC_MAN : (EMAC Offset: 0x34) PHY Maintenance Register --------
+#define AT91C_EMAC_DATA       ( 0xFFFF <<  0) // (EMAC)
+#define AT91C_EMAC_CODE       ( 0x3 << 16) // (EMAC)
+#define         AT91C_EMAC_CODE_802_3 ( 0x2 << 16) // (EMAC) Write Operation
+#define AT91C_EMAC_REGA       ( 0x1F << 18) // (EMAC)
+#define AT91C_EMAC_PHYA       ( 0x1F << 23) // (EMAC)
+#define AT91C_EMAC_RW         ( 0x3 << 28) // (EMAC)
+#define         AT91C_EMAC_RW_R       ( 0x2 << 28) // (EMAC) Read Operation
+#define         AT91C_EMAC_RW_W       ( 0x1 << 28) // (EMAC) Write Operation
+#define AT91C_EMAC_HIGH       ( 0x1 << 30) // (EMAC)
+#define AT91C_EMAC_LOW        ( 0x1 << 31) // (EMAC)
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_SPI.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_SPI.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_SPI.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_SPI.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,104 @@
+// ----------------------------------------------------------------------------
+//          ATMEL Microcontroller Software Support  -  ROUSSET  -
+// ----------------------------------------------------------------------------
+//  The software is delivered "AS IS" without warranty or condition of any
+//  kind, either express, implied or statutory. This includes without
+//  limitation any warranty or condition with respect to merchantability or
+//  fitness for any particular purpose, or against the infringements of
+//  intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// File Name           : AT91RM9200.h
+// Object              : AT91RM9200 / SPI definitions
+// Generated           : AT91 SW Application Group  12/03/2002 (10:48:02)
+//
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_SPI_H
+#define AT91RM9200_SPI_H
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Serial Parallel Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+
+typedef struct _AT91S_SPI {
+	AT91_REG	 SPI_CR; 	// Control Register
+	AT91_REG	 SPI_MR; 	// Mode Register
+	AT91_REG	 SPI_RDR; 	// Receive Data Register
+	AT91_REG	 SPI_TDR; 	// Transmit Data Register
+	AT91_REG	 SPI_SR; 	// Status Register
+	AT91_REG	 SPI_IER; 	// Interrupt Enable Register
+	AT91_REG	 SPI_IDR; 	// Interrupt Disable Register
+	AT91_REG	 SPI_IMR; 	// Interrupt Mask Register
+	AT91_REG	 Reserved0[4]; 	//
+	AT91_REG	 SPI_CSR0; 	// Chip Select Register 0
+	AT91_REG	 SPI_CSR1; 	// Chip Select Register 1
+	AT91_REG	 SPI_CSR2; 	// Chip Select Register 2
+	AT91_REG	 SPI_CSR3; 	// Chip Select Register 3
+	AT91_REG	 Reserved1[48]; 	//
+	AT91_REG	 SPI_RPR; 	// Receive Pointer Register
+	AT91_REG	 SPI_RCR; 	// Receive Counter Register
+	AT91_REG	 SPI_TPR; 	// Transmit Pointer Register
+	AT91_REG	 SPI_TCR; 	// Transmit Counter Register
+	AT91_REG	 SPI_RNPR; 	// Receive Next Pointer Register
+	AT91_REG	 SPI_RNCR; 	// Receive Next Counter Register
+	AT91_REG	 SPI_TNPR; 	// Transmit Next Pointer Register
+	AT91_REG	 SPI_TNCR; 	// Transmit Next Counter Register
+	AT91_REG	 SPI_PTCR; 	// PDC Transfer Control Register
+	AT91_REG	 SPI_PTSR; 	// PDC Transfer Status Register
+} AT91S_SPI, *AT91PS_SPI;
+
+#endif
+
+// -------- SPI_CR : (SPI Offset: 0x0) SPI Control Register --------
+#define AT91C_SPI_SPIEN       ( 0x1 <<  0) // (SPI) SPI Enable
+#define AT91C_SPI_SPIDIS      ( 0x1 <<  1) // (SPI) SPI Disable
+#define AT91C_SPI_SWRST       ( 0x1 <<  7) // (SPI) SPI Software reset
+// -------- SPI_MR : (SPI Offset: 0x4) SPI Mode Register --------
+#define AT91C_SPI_MSTR        ( 0x1 <<  0) // (SPI) Master/Slave Mode
+#define AT91C_SPI_PS          ( 0x1 <<  1) // (SPI) Peripheral Select
+#define 	AT91C_SPI_PS_FIXED                ( 0x0 <<  1) // (SPI) Fixed Peripheral Select
+#define 	AT91C_SPI_PS_VARIABLE             ( 0x1 <<  1) // (SPI) Variable Peripheral Select
+#define AT91C_SPI_PCSDEC      ( 0x1 <<  2) // (SPI) Chip Select Decode
+#define AT91C_SPI_DIV32       ( 0x1 <<  3) // (SPI) Clock Selection
+#define AT91C_SPI_MODFDIS     ( 0x1 <<  4) // (SPI) Mode Fault Detection
+#define AT91C_SPI_LLB         ( 0x1 <<  7) // (SPI) Clock Selection
+#define AT91C_SPI_PCS         ( 0xF << 16) // (SPI) Peripheral Chip Select
+#define AT91C_SPI_DLYBCS      ( 0xFF << 24) // (SPI) Delay Between Chip Selects
+// -------- SPI_RDR : (SPI Offset: 0x8) Receive Data Register --------
+#define AT91C_SPI_RD          ( 0xFFFF <<  0) // (SPI) Receive Data
+#define AT91C_SPI_RPCS        ( 0xF << 16) // (SPI) Peripheral Chip Select Status
+// -------- SPI_TDR : (SPI Offset: 0xc) Transmit Data Register --------
+#define AT91C_SPI_TD          ( 0xFFFF <<  0) // (SPI) Transmit Data
+#define AT91C_SPI_TPCS        ( 0xF << 16) // (SPI) Peripheral Chip Select Status
+// -------- SPI_SR : (SPI Offset: 0x10) Status Register --------
+#define AT91C_SPI_RDRF        ( 0x1 <<  0) // (SPI) Receive Data Register Full
+#define AT91C_SPI_TDRE        ( 0x1 <<  1) // (SPI) Transmit Data Register Empty
+#define AT91C_SPI_MODF        ( 0x1 <<  2) // (SPI) Mode Fault Error
+#define AT91C_SPI_OVRES       ( 0x1 <<  3) // (SPI) Overrun Error Status
+#define AT91C_SPI_SPENDRX     ( 0x1 <<  4) // (SPI) End of Receiver Transfer
+#define AT91C_SPI_SPENDTX     ( 0x1 <<  5) // (SPI) End of Transmit Transfer
+#define AT91C_SPI_RXBUFF      ( 0x1 <<  6) // (SPI) RXBUFF Interrupt
+#define AT91C_SPI_TXBUFE      ( 0x1 <<  7) // (SPI) TXBUFE Interrupt
+#define AT91C_SPI_SPIENS      ( 0x1 << 16) // (SPI) Enable Status
+// -------- SPI_IER : (SPI Offset: 0x14) Interrupt Enable Register --------
+// -------- SPI_IDR : (SPI Offset: 0x18) Interrupt Disable Register --------
+// -------- SPI_IMR : (SPI Offset: 0x1c) Interrupt Mask Register --------
+// -------- SPI_CSR : (SPI Offset: 0x30) Chip Select Register --------
+#define AT91C_SPI_CPOL        ( 0x1 <<  0) // (SPI) Clock Polarity
+#define AT91C_SPI_NCPHA       ( 0x1 <<  1) // (SPI) Clock Phase
+#define AT91C_SPI_BITS        ( 0xF <<  4) // (SPI) Bits Per Transfer
+#define 	AT91C_SPI_BITS_8                    ( 0x0 <<  4) // (SPI) 8 Bits Per transfer
+#define 	AT91C_SPI_BITS_9                    ( 0x1 <<  4) // (SPI) 9 Bits Per transfer
+#define 	AT91C_SPI_BITS_10                   ( 0x2 <<  4) // (SPI) 10 Bits Per transfer
+#define 	AT91C_SPI_BITS_11                   ( 0x3 <<  4) // (SPI) 11 Bits Per transfer
+#define 	AT91C_SPI_BITS_12                   ( 0x4 <<  4) // (SPI) 12 Bits Per transfer
+#define 	AT91C_SPI_BITS_13                   ( 0x5 <<  4) // (SPI) 13 Bits Per transfer
+#define 	AT91C_SPI_BITS_14                   ( 0x6 <<  4) // (SPI) 14 Bits Per transfer
+#define 	AT91C_SPI_BITS_15                   ( 0x7 <<  4) // (SPI) 15 Bits Per transfer
+#define 	AT91C_SPI_BITS_16                   ( 0x8 <<  4) // (SPI) 16 Bits Per transfer
+#define AT91C_SPI_SCBR        ( 0xFF <<  8) // (SPI) Serial Clock Baud Rate
+#define AT91C_SPI_DLYBS       ( 0xFF << 16) // (SPI) Serial Clock Baud Rate
+#define AT91C_SPI_DLYBCT      ( 0xFF << 24) // (SPI) Delay Between Consecutive Transfers
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_SYS.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_SYS.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_SYS.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_SYS.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,719 @@
+// ----------------------------------------------------------------------------
+//          ATMEL Microcontroller Software Support  -  ROUSSET  -
+// ----------------------------------------------------------------------------
+//  The software is delivered "AS IS" without warranty or condition of any
+//  kind, either express, implied or statutory. This includes without
+//  limitation any warranty or condition with respect to merchantability or
+//  fitness for any particular purpose, or against the infringements of
+//  intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// File Name           : AT91RM9200.h
+// Object              : AT91RM9200 definitions
+// Generated           : AT91 SW Application Group  04/16/2003 (12:30:06)
+//
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_SYS_H
+#define AT91RM9200_SYS_H
+
+#ifndef __ASSEMBLY__
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR System Peripherals
+// *****************************************************************************
+typedef struct _AT91S_SYS {
+	AT91_REG	 AIC_SMR[32]; 	// Source Mode Register
+	AT91_REG	 AIC_SVR[32]; 	// Source Vector Register
+	AT91_REG	 AIC_IVR; 	// IRQ Vector Register
+	AT91_REG	 AIC_FVR; 	// FIQ Vector Register
+	AT91_REG	 AIC_ISR; 	// Interrupt Status Register
+	AT91_REG	 AIC_IPR; 	// Interrupt Pending Register
+	AT91_REG	 AIC_IMR; 	// Interrupt Mask Register
+	AT91_REG	 AIC_CISR; 	// Core Interrupt Status Register
+	AT91_REG	 Reserved0[2]; 	//
+	AT91_REG	 AIC_IECR; 	// Interrupt Enable Command Register
+	AT91_REG	 AIC_IDCR; 	// Interrupt Disable Command Register
+	AT91_REG	 AIC_ICCR; 	// Interrupt Clear Command Register
+	AT91_REG	 AIC_ISCR; 	// Interrupt Set Command Register
+	AT91_REG	 AIC_EOICR; 	// End of Interrupt Command Register
+	AT91_REG	 AIC_SPU; 	// Spurious Vector Register
+	AT91_REG	 AIC_DCR; 	// Debug Control Register (Protect)
+	AT91_REG	 Reserved1[1]; 	//
+	AT91_REG	 AIC_FFER; 	// Fast Forcing Enable Register
+	AT91_REG	 AIC_FFDR; 	// Fast Forcing Disable Register
+	AT91_REG	 AIC_FFSR; 	// Fast Forcing Status Register
+	AT91_REG	 Reserved2[45]; 	//
+	AT91_REG	 DBGU_CR; 	// Control Register
+	AT91_REG	 DBGU_MR; 	// Mode Register
+	AT91_REG	 DBGU_IER; 	// Interrupt Enable Register
+	AT91_REG	 DBGU_IDR; 	// Interrupt Disable Register
+	AT91_REG	 DBGU_IMR; 	// Interrupt Mask Register
+	AT91_REG	 DBGU_CSR; 	// Channel Status Register
+	AT91_REG	 DBGU_RHR; 	// Receiver Holding Register
+	AT91_REG	 DBGU_THR; 	// Transmitter Holding Register
+	AT91_REG	 DBGU_BRGR; 	// Baud Rate Generator Register
+	AT91_REG	 Reserved3[7]; 	//
+	AT91_REG	 DBGU_C1R; 	// Chip ID1 Register
+	AT91_REG	 DBGU_C2R; 	// Chip ID2 Register
+	AT91_REG	 DBGU_FNTR; 	// Force NTRST Register
+	AT91_REG	 Reserved4[45]; 	//
+	AT91_REG	 DBGU_RPR; 	// Receive Pointer Register
+	AT91_REG	 DBGU_RCR; 	// Receive Counter Register
+	AT91_REG	 DBGU_TPR; 	// Transmit Pointer Register
+	AT91_REG	 DBGU_TCR; 	// Transmit Counter Register
+	AT91_REG	 DBGU_RNPR; 	// Receive Next Pointer Register
+	AT91_REG	 DBGU_RNCR; 	// Receive Next Counter Register
+	AT91_REG	 DBGU_TNPR; 	// Transmit Next Pointer Register
+	AT91_REG	 DBGU_TNCR; 	// Transmit Next Counter Register
+	AT91_REG	 DBGU_PTCR; 	// PDC Transfer Control Register
+	AT91_REG	 DBGU_PTSR; 	// PDC Transfer Status Register
+	AT91_REG	 Reserved5[54]; 	//
+	AT91_REG	 PIOA_PER; 	// PIO Enable Register
+	AT91_REG	 PIOA_PDR; 	// PIO Disable Register
+	AT91_REG	 PIOA_PSR; 	// PIO Status Register
+	AT91_REG	 Reserved6[1]; 	//
+	AT91_REG	 PIOA_OER; 	// Output Enable Register
+	AT91_REG	 PIOA_ODR; 	// Output Disable Registerr
+	AT91_REG	 PIOA_OSR; 	// Output Status Register
+	AT91_REG	 Reserved7[1]; 	//
+	AT91_REG	 PIOA_IFER; 	// Input Filter Enable Register
+	AT91_REG	 PIOA_IFDR; 	// Input Filter Disable Register
+	AT91_REG	 PIOA_IFSR; 	// Input Filter Status Register
+	AT91_REG	 Reserved8[1]; 	//
+	AT91_REG	 PIOA_SODR; 	// Set Output Data Register
+	AT91_REG	 PIOA_CODR; 	// Clear Output Data Register
+	AT91_REG	 PIOA_ODSR; 	// Output Data Status Register
+	AT91_REG	 PIOA_PDSR; 	// Pin Data Status Register
+	AT91_REG	 PIOA_IER; 	// Interrupt Enable Register
+	AT91_REG	 PIOA_IDR; 	// Interrupt Disable Register
+	AT91_REG	 PIOA_IMR; 	// Interrupt Mask Register
+	AT91_REG	 PIOA_ISR; 	// Interrupt Status Register
+	AT91_REG	 PIOA_MDER; 	// Multi-driver Enable Register
+	AT91_REG	 PIOA_MDDR; 	// Multi-driver Disable Register
+	AT91_REG	 PIOA_MDSR; 	// Multi-driver Status Register
+	AT91_REG	 Reserved9[1]; 	//
+	AT91_REG	 PIOA_PPUDR; 	// Pull-up Disable Register
+	AT91_REG	 PIOA_PPUER; 	// Pull-up Enable Register
+	AT91_REG	 PIOA_PPUSR; 	// Pad Pull-up Status Register
+	AT91_REG	 Reserved10[1]; 	//
+	AT91_REG	 PIOA_ASR; 	// Select A Register
+	AT91_REG	 PIOA_BSR; 	// Select B Register
+	AT91_REG	 PIOA_ABSR; 	// AB Select Status Register
+	AT91_REG	 Reserved11[9]; 	//
+	AT91_REG	 PIOA_OWER; 	// Output Write Enable Register
+	AT91_REG	 PIOA_OWDR; 	// Output Write Disable Register
+	AT91_REG	 PIOA_OWSR; 	// Output Write Status Register
+	AT91_REG	 Reserved12[85]; 	//
+	AT91_REG	 PIOB_PER; 	// PIO Enable Register
+	AT91_REG	 PIOB_PDR; 	// PIO Disable Register
+	AT91_REG	 PIOB_PSR; 	// PIO Status Register
+	AT91_REG	 Reserved13[1]; 	//
+	AT91_REG	 PIOB_OER; 	// Output Enable Register
+	AT91_REG	 PIOB_ODR; 	// Output Disable Registerr
+	AT91_REG	 PIOB_OSR; 	// Output Status Register
+	AT91_REG	 Reserved14[1]; 	//
+	AT91_REG	 PIOB_IFER; 	// Input Filter Enable Register
+	AT91_REG	 PIOB_IFDR; 	// Input Filter Disable Register
+	AT91_REG	 PIOB_IFSR; 	// Input Filter Status Register
+	AT91_REG	 Reserved15[1]; 	//
+	AT91_REG	 PIOB_SODR; 	// Set Output Data Register
+	AT91_REG	 PIOB_CODR; 	// Clear Output Data Register
+	AT91_REG	 PIOB_ODSR; 	// Output Data Status Register
+	AT91_REG	 PIOB_PDSR; 	// Pin Data Status Register
+	AT91_REG	 PIOB_IER; 	// Interrupt Enable Register
+	AT91_REG	 PIOB_IDR; 	// Interrupt Disable Register
+	AT91_REG	 PIOB_IMR; 	// Interrupt Mask Register
+	AT91_REG	 PIOB_ISR; 	// Interrupt Status Register
+	AT91_REG	 PIOB_MDER; 	// Multi-driver Enable Register
+	AT91_REG	 PIOB_MDDR; 	// Multi-driver Disable Register
+	AT91_REG	 PIOB_MDSR; 	// Multi-driver Status Register
+	AT91_REG	 Reserved16[1]; 	//
+	AT91_REG	 PIOB_PPUDR; 	// Pull-up Disable Register
+	AT91_REG	 PIOB_PPUER; 	// Pull-up Enable Register
+	AT91_REG	 PIOB_PPUSR; 	// Pad Pull-up Status Register
+	AT91_REG	 Reserved17[1]; 	//
+	AT91_REG	 PIOB_ASR; 	// Select A Register
+	AT91_REG	 PIOB_BSR; 	// Select B Register
+	AT91_REG	 PIOB_ABSR; 	// AB Select Status Register
+	AT91_REG	 Reserved18[9]; 	//
+	AT91_REG	 PIOB_OWER; 	// Output Write Enable Register
+	AT91_REG	 PIOB_OWDR; 	// Output Write Disable Register
+	AT91_REG	 PIOB_OWSR; 	// Output Write Status Register
+	AT91_REG	 Reserved19[85]; 	//
+	AT91_REG	 PIOC_PER; 	// PIO Enable Register
+	AT91_REG	 PIOC_PDR; 	// PIO Disable Register
+	AT91_REG	 PIOC_PSR; 	// PIO Status Register
+	AT91_REG	 Reserved20[1]; 	//
+	AT91_REG	 PIOC_OER; 	// Output Enable Register
+	AT91_REG	 PIOC_ODR; 	// Output Disable Registerr
+	AT91_REG	 PIOC_OSR; 	// Output Status Register
+	AT91_REG	 Reserved21[1]; 	//
+	AT91_REG	 PIOC_IFER; 	// Input Filter Enable Register
+	AT91_REG	 PIOC_IFDR; 	// Input Filter Disable Register
+	AT91_REG	 PIOC_IFSR; 	// Input Filter Status Register
+	AT91_REG	 Reserved22[1]; 	//
+	AT91_REG	 PIOC_SODR; 	// Set Output Data Register
+	AT91_REG	 PIOC_CODR; 	// Clear Output Data Register
+	AT91_REG	 PIOC_ODSR; 	// Output Data Status Register
+	AT91_REG	 PIOC_PDSR; 	// Pin Data Status Register
+	AT91_REG	 PIOC_IER; 	// Interrupt Enable Register
+	AT91_REG	 PIOC_IDR; 	// Interrupt Disable Register
+	AT91_REG	 PIOC_IMR; 	// Interrupt Mask Register
+	AT91_REG	 PIOC_ISR; 	// Interrupt Status Register
+	AT91_REG	 PIOC_MDER; 	// Multi-driver Enable Register
+	AT91_REG	 PIOC_MDDR; 	// Multi-driver Disable Register
+	AT91_REG	 PIOC_MDSR; 	// Multi-driver Status Register
+	AT91_REG	 Reserved23[1]; 	//
+	AT91_REG	 PIOC_PPUDR; 	// Pull-up Disable Register
+	AT91_REG	 PIOC_PPUER; 	// Pull-up Enable Register
+	AT91_REG	 PIOC_PPUSR; 	// Pad Pull-up Status Register
+	AT91_REG	 Reserved24[1]; 	//
+	AT91_REG	 PIOC_ASR; 	// Select A Register
+	AT91_REG	 PIOC_BSR; 	// Select B Register
+	AT91_REG	 PIOC_ABSR; 	// AB Select Status Register
+	AT91_REG	 Reserved25[9]; 	//
+	AT91_REG	 PIOC_OWER; 	// Output Write Enable Register
+	AT91_REG	 PIOC_OWDR; 	// Output Write Disable Register
+	AT91_REG	 PIOC_OWSR; 	// Output Write Status Register
+	AT91_REG	 Reserved26[85]; 	//
+	AT91_REG	 PIOD_PER; 	// PIO Enable Register
+	AT91_REG	 PIOD_PDR; 	// PIO Disable Register
+	AT91_REG	 PIOD_PSR; 	// PIO Status Register
+	AT91_REG	 Reserved27[1]; 	//
+	AT91_REG	 PIOD_OER; 	// Output Enable Register
+	AT91_REG	 PIOD_ODR; 	// Output Disable Registerr
+	AT91_REG	 PIOD_OSR; 	// Output Status Register
+	AT91_REG	 Reserved28[1]; 	//
+	AT91_REG	 PIOD_IFER; 	// Input Filter Enable Register
+	AT91_REG	 PIOD_IFDR; 	// Input Filter Disable Register
+	AT91_REG	 PIOD_IFSR; 	// Input Filter Status Register
+	AT91_REG	 Reserved29[1]; 	//
+	AT91_REG	 PIOD_SODR; 	// Set Output Data Register
+	AT91_REG	 PIOD_CODR; 	// Clear Output Data Register
+	AT91_REG	 PIOD_ODSR; 	// Output Data Status Register
+	AT91_REG	 PIOD_PDSR; 	// Pin Data Status Register
+	AT91_REG	 PIOD_IER; 	// Interrupt Enable Register
+	AT91_REG	 PIOD_IDR; 	// Interrupt Disable Register
+	AT91_REG	 PIOD_IMR; 	// Interrupt Mask Register
+	AT91_REG	 PIOD_ISR; 	// Interrupt Status Register
+	AT91_REG	 PIOD_MDER; 	// Multi-driver Enable Register
+	AT91_REG	 PIOD_MDDR; 	// Multi-driver Disable Register
+	AT91_REG	 PIOD_MDSR; 	// Multi-driver Status Register
+	AT91_REG	 Reserved30[1]; 	//
+	AT91_REG	 PIOD_PPUDR; 	// Pull-up Disable Register
+	AT91_REG	 PIOD_PPUER; 	// Pull-up Enable Register
+	AT91_REG	 PIOD_PPUSR; 	// Pad Pull-up Status Register
+	AT91_REG	 Reserved31[1]; 	//
+	AT91_REG	 PIOD_ASR; 	// Select A Register
+	AT91_REG	 PIOD_BSR; 	// Select B Register
+	AT91_REG	 PIOD_ABSR; 	// AB Select Status Register
+	AT91_REG	 Reserved32[9]; 	//
+	AT91_REG	 PIOD_OWER; 	// Output Write Enable Register
+	AT91_REG	 PIOD_OWDR; 	// Output Write Disable Register
+	AT91_REG	 PIOD_OWSR; 	// Output Write Status Register
+	AT91_REG	 Reserved33[85]; 	//
+	AT91_REG	 PMC_SCER; 	// System Clock Enable Register
+	AT91_REG	 PMC_SCDR; 	// System Clock Disable Register
+	AT91_REG	 PMC_SCSR; 	// System Clock Status Register
+	AT91_REG	 Reserved34[1]; 	//
+	AT91_REG	 PMC_PCER; 	// Peripheral Clock Enable Register
+	AT91_REG	 PMC_PCDR; 	// Peripheral Clock Disable Register
+	AT91_REG	 PMC_PCSR; 	// Peripheral Clock Status Register
+	AT91_REG	 Reserved35[1]; 	//
+	AT91_REG	 CKGR_MOR; 	// Main Oscillator Register
+	AT91_REG	 CKGR_MCFR; 	// Main Clock  Frequency Register
+	AT91_REG	 CKGR_PLLAR; 	// PLL A Register
+	AT91_REG	 CKGR_PLLBR; 	// PLL B Register
+	AT91_REG	 PMC_MCKR; 	// Master Clock Register
+	AT91_REG	 Reserved36[3]; 	//
+	AT91_REG	 PMC_PCKR[8]; 	// Programmable Clock Register
+	AT91_REG	 PMC_IER; 	// Interrupt Enable Register
+	AT91_REG	 PMC_IDR; 	// Interrupt Disable Register
+	AT91_REG	 PMC_SR; 	// Status Register
+	AT91_REG	 PMC_IMR; 	// Interrupt Mask Register
+	AT91_REG	 Reserved37[36]; 	//
+	AT91_REG	 ST_CR; 	// Control Register
+	AT91_REG	 ST_PIMR; 	// Period Interval Mode Register
+	AT91_REG	 ST_WDMR; 	// Watchdog Mode Register
+	AT91_REG	 ST_RTMR; 	// Real-time Mode Register
+	AT91_REG	 ST_SR; 	// Status Register
+	AT91_REG	 ST_IER; 	// Interrupt Enable Register
+	AT91_REG	 ST_IDR; 	// Interrupt Disable Register
+	AT91_REG	 ST_IMR; 	// Interrupt Mask Register
+	AT91_REG	 ST_RTAR; 	// Real-time Alarm Register
+	AT91_REG	 ST_CRTR; 	// Current Real-time Register
+	AT91_REG	 Reserved38[54]; 	//
+	AT91_REG	 RTC_CR; 	// Control Register
+	AT91_REG	 RTC_MR; 	// Mode Register
+	AT91_REG	 RTC_TIMR; 	// Time Register
+	AT91_REG	 RTC_CALR; 	// Calendar Register
+	AT91_REG	 RTC_TIMALR; 	// Time Alarm Register
+	AT91_REG	 RTC_CALALR; 	// Calendar Alarm Register
+	AT91_REG	 RTC_SR; 	// Status Register
+	AT91_REG	 RTC_SCCR; 	// Status Clear Command Register
+	AT91_REG	 RTC_IER; 	// Interrupt Enable Register
+	AT91_REG	 RTC_IDR; 	// Interrupt Disable Register
+	AT91_REG	 RTC_IMR; 	// Interrupt Mask Register
+	AT91_REG	 RTC_VER; 	// Valid Entry Register
+	AT91_REG	 Reserved39[52]; 	//
+	AT91_REG	 MC_RCR; 	// MC Remap Control Register
+	AT91_REG	 MC_ASR; 	// MC Abort Status Register
+	AT91_REG	 MC_AASR; 	// MC Abort Address Status Register
+	AT91_REG	 Reserved40[1]; 	//
+	AT91_REG	 MC_PUIA[16]; 	// MC Protection Unit Area
+	AT91_REG	 MC_PUP; 	// MC Protection Unit Peripherals
+	AT91_REG	 MC_PUER; 	// MC Protection Unit Enable Register
+	AT91_REG	 Reserved41[2]; 	//
+	AT91_REG	 EBI_CSA; 	// Chip Select Assignment Register
+	AT91_REG	 EBI_CFGR; 	// Configuration Register
+	AT91_REG	 Reserved42[2]; 	//
+	AT91_REG	 EBI_SMC2_CSR[8]; 	// SMC2 Chip Select Register
+	AT91_REG	 EBI_SDRC_MR; 	// SDRAM Controller Mode Register
+	AT91_REG	 EBI_SDRC_TR; 	// SDRAM Controller Refresh Timer Register
+	AT91_REG	 EBI_SDRC_CR; 	// SDRAM Controller Configuration Register
+	AT91_REG	 EBI_SDRC_SRR; 	// SDRAM Controller Self Refresh Register
+	AT91_REG	 EBI_SDRC_LPR; 	// SDRAM Controller Low Power Register
+	AT91_REG	 EBI_SDRC_IER; 	// SDRAM Controller Interrupt Enable Register
+	AT91_REG	 EBI_SDRC_IDR; 	// SDRAM Controller Interrupt Disable Register
+	AT91_REG	 EBI_SDRC_IMR; 	// SDRAM Controller Interrupt Mask Register
+	AT91_REG	 EBI_SDRC_ISR; 	// SDRAM Controller Interrupt Mask Register
+	AT91_REG	 Reserved43[3]; 	//
+	AT91_REG	 EBI_BFC_MR; 	// BFC Mode Register
+} AT91S_SYS, *AT91PS_SYS;
+
+#else
+
+/* Offsets from AT91C_BASE_SYS */
+#define AIC_SMR		(0) // Source Mode Register
+#define AIC_SVR		(128) // Source Vector Register
+#define AIC_IVR		(256) // IRQ Vector Register
+#define AIC_FVR		(260) // FIQ Vector Register
+#define AIC_ISR		(264) // Interrupt Status Register
+#define AIC_IPR		(268) // Interrupt Pending Register
+#define AIC_IMR		(272) // Interrupt Mask Register
+#define AIC_CISR	(276) // Core Interrupt Status Register
+#define AIC_IECR	(288) // Interrupt Enable Command Register
+#define AIC_IDCR	(292) // Interrupt Disable Command Register
+#define AIC_ICCR	(296) // Interrupt Clear Command Register
+#define AIC_ISCR	(300) // Interrupt Set Command Register
+#define AIC_EOICR	(304) // End of Interrupt Command Register
+#define AIC_SPU		(308) // Spurious Vector Register
+#define AIC_DCR		(312) // Debug Control Register (Protect)
+#define AIC_FFER	(320) // Fast Forcing Enable Register
+#define AIC_FFDR	(324) // Fast Forcing Disable Register
+#define AIC_FFSR	(328) // Fast Forcing Status Register
+
+/* Offsets from AT91C_BASE_SYS */
+#define DBGU_CR		(0x200 + 0) // Control Register
+#define DBGU_MR		(0x200 + 4) // Mode Register
+#define DBGU_IER	(0x200 + 8) // Interrupt Enable Register
+#define DBGU_IDR	(0x200 + 12) // Interrupt Disable Register
+#define DBGU_IMR	(0x200 + 16) // Interrupt Mask Register
+#define DBGU_CSR	(0x200 + 20) // Channel Status Register
+#define DBGU_RHR	(0x200 + 24) // Receiver Holding Register
+#define DBGU_THR	(0x200 + 28) // Transmitter Holding Register
+#define DBGU_BRGR	(0x200 + 32) // Baud Rate Generator Register
+#define DBGU_C1R	(0x200 + 64) // Chip ID1 Register
+#define DBGU_C2R	(0x200 + 68) // Chip ID2 Register
+#define DBGU_FNTR	(0x200 + 72) // Force NTRST Register
+#define DBGU_RPR	(0x200 + 256) // Receive Pointer Register
+#define DBGU_RCR	(0x200 + 260) // Receive Counter Register
+#define DBGU_TPR	(0x200 + 264) // Transmit Pointer Register
+#define DBGU_TCR	(0x200 + 268) // Transmit Counter Register
+#define DBGU_RNPR	(0x200 + 272) // Receive Next Pointer Register
+#define DBGU_RNCR	(0x200 + 276) // Receive Next Counter Register
+#define DBGU_TNPR	(0x200 + 280) // Transmit Next Pointer Register
+#define DBGU_TNCR	(0x200 + 284) // Transmit Next Counter Register
+#define DBGU_PTCR	(0x200 + 288) // PDC Transfer Control Register
+#define DBGU_PTSR	(0x200 + 292) // PDC Transfer Status Register
+
+#endif // __ASSEMBLY
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Memory Controller Interface
+// *****************************************************************************
+// -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register --------
+#define AT91C_MC_RCB          (0x1 <<  0) // (MC) Remap Command Bit
+// -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register --------
+#define AT91C_MC_UNDADD       (0x1 <<  0) // (MC) Undefined Addess Abort Status
+#define AT91C_MC_MISADD       (0x1 <<  1) // (MC) Misaligned Addess Abort Status
+#define AT91C_MC_MPU          (0x1 <<  2) // (MC) Memory protection Unit Abort Status
+#define AT91C_MC_ABTSZ        (0x3 <<  8) // (MC) Abort Size Status
+#define 	AT91C_MC_ABTSZ_BYTE                 (0x0 <<  8) // (MC) Byte
+#define 	AT91C_MC_ABTSZ_HWORD                (0x1 <<  8) // (MC) Half-word
+#define 	AT91C_MC_ABTSZ_WORD                 (0x2 <<  8) // (MC) Word
+#define AT91C_MC_ABTTYP       (0x3 << 10) // (MC) Abort Type Status
+#define 	AT91C_MC_ABTTYP_DATAR                (0x0 << 10) // (MC) Data Read
+#define 	AT91C_MC_ABTTYP_DATAW                (0x1 << 10) // (MC) Data Write
+#define 	AT91C_MC_ABTTYP_FETCH                (0x2 << 10) // (MC) Code Fetch
+#define AT91C_MC_MST0         (0x1 << 16) // (MC) Master 0 Abort Source
+#define AT91C_MC_MST1         (0x1 << 17) // (MC) Master 1 Abort Source
+#define AT91C_MC_SVMST0       (0x1 << 24) // (MC) Saved Master 0 Abort Source
+#define AT91C_MC_SVMST1       (0x1 << 25) // (MC) Saved Master 1 Abort Source
+// -------- MC_PUIA : (MC Offset: 0x10) MC Protection Unit Area --------
+#define AT91C_MC_PROT         (0x3 <<  0) // (MC) Protection
+#define 	AT91C_MC_PROT_PNAUNA               (0x0) // (MC) Privilege: No Access, User: No Access
+#define 	AT91C_MC_PROT_PRWUNA               (0x1) // (MC) Privilege: Read/Write, User: No Access
+#define 	AT91C_MC_PROT_PRWURO               (0x2) // (MC) Privilege: Read/Write, User: Read Only
+#define 	AT91C_MC_PROT_PRWURW               (0x3) // (MC) Privilege: Read/Write, User: Read/Write
+#define AT91C_MC_SIZE         (0xF <<  4) // (MC) Internal Area Size
+#define 	AT91C_MC_SIZE_1KB                  (0x0 <<  4) // (MC) Area size 1KByte
+#define 	AT91C_MC_SIZE_2KB                  (0x1 <<  4) // (MC) Area size 2KByte
+#define 	AT91C_MC_SIZE_4KB                  (0x2 <<  4) // (MC) Area size 4KByte
+#define 	AT91C_MC_SIZE_8KB                  (0x3 <<  4) // (MC) Area size 8KByte
+#define 	AT91C_MC_SIZE_16KB                 (0x4 <<  4) // (MC) Area size 16KByte
+#define 	AT91C_MC_SIZE_32KB                 (0x5 <<  4) // (MC) Area size 32KByte
+#define 	AT91C_MC_SIZE_64KB                 (0x6 <<  4) // (MC) Area size 64KByte
+#define 	AT91C_MC_SIZE_128KB                (0x7 <<  4) // (MC) Area size 128KByte
+#define 	AT91C_MC_SIZE_256KB                (0x8 <<  4) // (MC) Area size 256KByte
+#define 	AT91C_MC_SIZE_512KB                (0x9 <<  4) // (MC) Area size 512KByte
+#define 	AT91C_MC_SIZE_1MB                  (0xA <<  4) // (MC) Area size 1MByte
+#define 	AT91C_MC_SIZE_2MB                  (0xB <<  4) // (MC) Area size 2MByte
+#define 	AT91C_MC_SIZE_4MB                  (0xC <<  4) // (MC) Area size 4MByte
+#define 	AT91C_MC_SIZE_8MB                  (0xD <<  4) // (MC) Area size 8MByte
+#define 	AT91C_MC_SIZE_16MB                 (0xE <<  4) // (MC) Area size 16MByte
+#define 	AT91C_MC_SIZE_64MB                 (0xF <<  4) // (MC) Area size 64MByte
+#define AT91C_MC_BA           (0x3FFFF << 10) // (MC) Internal Area Base Address
+// -------- MC_PUP : (MC Offset: 0x50) MC Protection Unit Peripheral --------
+// -------- MC_PUER : (MC Offset: 0x54) MC Protection Unit Area --------
+#define AT91C_MC_PUEB         (0x1 <<  0) // (MC) Protection Unit enable Bit
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Real-time Clock Alarm and Parallel Load Interface
+// *****************************************************************************
+// -------- RTC_CR : (RTC Offset: 0x0) RTC Control Register --------
+#define AT91C_RTC_UPDTIM      (0x1 <<  0) // (RTC) Update Request Time Register
+#define AT91C_RTC_UPDCAL      (0x1 <<  1) // (RTC) Update Request Calendar Register
+#define AT91C_RTC_TIMEVSEL    (0x3 <<  8) // (RTC) Time Event Selection
+#define 	AT91C_RTC_TIMEVSEL_MINUTE               (0x0 <<  8) // (RTC) Minute change.
+#define 	AT91C_RTC_TIMEVSEL_HOUR                 (0x1 <<  8) // (RTC) Hour change.
+#define 	AT91C_RTC_TIMEVSEL_DAY24                (0x2 <<  8) // (RTC) Every day at midnight.
+#define 	AT91C_RTC_TIMEVSEL_DAY12                (0x3 <<  8) // (RTC) Every day at noon.
+#define AT91C_RTC_CALEVSEL    (0x3 << 16) // (RTC) Calendar Event Selection
+#define 	AT91C_RTC_CALEVSEL_WEEK                 (0x0 << 16) // (RTC) Week change (every Monday at time 00:00:00).
+#define 	AT91C_RTC_CALEVSEL_MONTH                (0x1 << 16) // (RTC) Month change (every 01 of each month at time 00:00:00).
+#define 	AT91C_RTC_CALEVSEL_YEAR                 (0x2 << 16) // (RTC) Year change (every January 1 at time 00:00:00).
+// -------- RTC_MR : (RTC Offset: 0x4) RTC Mode Register --------
+#define AT91C_RTC_HRMOD       (0x1 <<  0) // (RTC) 12-24 hour Mode
+// -------- RTC_TIMR : (RTC Offset: 0x8) RTC Time Register --------
+#define AT91C_RTC_SEC         (0x7F <<  0) // (RTC) Current Second
+#define AT91C_RTC_MIN         (0x7F <<  8) // (RTC) Current Minute
+#define AT91C_RTC_HOUR        (0x3F << 16) // (RTC) Current Hour
+#define AT91C_RTC_AMPM        (0x1 << 22) // (RTC) Ante Meridiem, Post Meridiem Indicator
+// -------- RTC_CALR : (RTC Offset: 0xc) RTC Calendar Register --------
+#define AT91C_RTC_CENT        (0x3F <<  0) // (RTC) Current Century
+#define AT91C_RTC_YEAR        (0xFF <<  8) // (RTC) Current Year
+#define AT91C_RTC_MONTH       (0x1F << 16) // (RTC) Current Month
+#define AT91C_RTC_DAY         (0x7 << 21) // (RTC) Current Day
+#define AT91C_RTC_DATE        (0x3F << 24) // (RTC) Current Date
+// -------- RTC_TIMALR : (RTC Offset: 0x10) RTC Time Alarm Register --------
+#define AT91C_RTC_SECEN       (0x1 <<  7) // (RTC) Second Alarm Enable
+#define AT91C_RTC_MINEN       (0x1 << 15) // (RTC) Minute Alarm
+#define AT91C_RTC_HOUREN      (0x1 << 23) // (RTC) Current Hour
+// -------- RTC_CALALR : (RTC Offset: 0x14) RTC Calendar Alarm Register --------
+#define AT91C_RTC_MONTHEN     (0x1 << 23) // (RTC) Month Alarm Enable
+#define AT91C_RTC_DATEEN      (0x1 << 31) // (RTC) Date Alarm Enable
+// -------- RTC_SR : (RTC Offset: 0x18) RTC Status Register --------
+#define AT91C_RTC_ACKUPD      (0x1 <<  0) // (RTC) Acknowledge for Update
+#define AT91C_RTC_ALARM       (0x1 <<  1) // (RTC) Alarm Flag
+#define AT91C_RTC_SECEV       (0x1 <<  2) // (RTC) Second Event
+#define AT91C_RTC_TIMEV       (0x1 <<  3) // (RTC) Time Event
+#define AT91C_RTC_CALEV       (0x1 <<  4) // (RTC) Calendar event
+// -------- RTC_SCCR : (RTC Offset: 0x1c) RTC Status Clear Command Register --------
+// -------- RTC_IER : (RTC Offset: 0x20) RTC Interrupt Enable Register --------
+// -------- RTC_IDR : (RTC Offset: 0x24) RTC Interrupt Disable Register --------
+// -------- RTC_IMR : (RTC Offset: 0x28) RTC Interrupt Mask Register --------
+// -------- RTC_VER : (RTC Offset: 0x2c) RTC Valid Entry Register --------
+#define AT91C_RTC_NVTIM       (0x1 <<  0) // (RTC) Non valid Time
+#define AT91C_RTC_NVCAL       (0x1 <<  1) // (RTC) Non valid Calendar
+#define AT91C_RTC_NVTIMALR    (0x1 <<  2) // (RTC) Non valid time Alarm
+#define AT91C_RTC_NVCALALR    (0x1 <<  3) // (RTC) Nonvalid Calendar Alarm
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR System Timer Interface
+// *****************************************************************************
+// -------- ST_CR : (ST Offset: 0x0) System Timer Control Register --------
+#define AT91C_ST_WDRST        (0x1 <<  0) // (ST) Watchdog Timer Restart
+// -------- ST_PIMR : (ST Offset: 0x4) System Timer Period Interval Mode Register --------
+#define AT91C_ST_PIV          (0xFFFF <<  0) // (ST) Watchdog Timer Restart
+// -------- ST_WDMR : (ST Offset: 0x8) System Timer Watchdog Mode Register --------
+#define AT91C_ST_WDV          (0xFFFF <<  0) // (ST) Watchdog Timer Restart
+#define AT91C_ST_RSTEN        (0x1 << 16) // (ST) Reset Enable
+#define AT91C_ST_EXTEN        (0x1 << 17) // (ST) External Signal Assertion Enable
+// -------- ST_RTMR : (ST Offset: 0xc) System Timer Real-time Mode Register --------
+#define AT91C_ST_RTPRES       (0xFFFF <<  0) // (ST) Real-time Timer Prescaler Value
+// -------- ST_SR : (ST Offset: 0x10) System Timer Status Register --------
+#define AT91C_ST_PITS         (0x1 <<  0) // (ST) Period Interval Timer Interrupt
+#define AT91C_ST_WDOVF        (0x1 <<  1) // (ST) Watchdog Overflow
+#define AT91C_ST_RTTINC       (0x1 <<  2) // (ST) Real-time Timer Increment
+#define AT91C_ST_ALMS         (0x1 <<  3) // (ST) Alarm Status
+// -------- ST_IER : (ST Offset: 0x14) System Timer Interrupt Enable Register --------
+// -------- ST_IDR : (ST Offset: 0x18) System Timer Interrupt Disable Register --------
+// -------- ST_IMR : (ST Offset: 0x1c) System Timer Interrupt Mask Register --------
+// -------- ST_RTAR : (ST Offset: 0x20) System Timer Real-time Alarm Register --------
+#define AT91C_ST_ALMV         (0xFFFFF <<  0) // (ST) Alarm Value Value
+// -------- ST_CRTR : (ST Offset: 0x24) System Timer Current Real-time Register --------
+#define AT91C_ST_CRTV         (0xFFFFF <<  0) // (ST) Current Real-time Value
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Power Management Controler
+// *****************************************************************************
+// -------- PMC_SCER : (PMC Offset: 0x0) System Clock Enable Register --------
+#define AT91C_PMC_PCK         (0x1 <<  0) // (PMC) Processor Clock
+#define AT91C_PMC_UDP         (0x1 <<  1) // (PMC) USB Device Port Clock
+#define AT91C_PMC_MCKUDP      (0x1 <<  2) // (PMC) USB Device Port Master Clock Automatic Disable on Suspend
+#define AT91C_PMC_UHP         (0x1 <<  4) // (PMC) USB Host Port Clock
+#define AT91C_PMC_PCK0        (0x1 <<  8) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK1        (0x1 <<  9) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK2        (0x1 << 10) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK3        (0x1 << 11) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK4        (0x1 << 12) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK5        (0x1 << 13) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK6        (0x1 << 14) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK7        (0x1 << 15) // (PMC) Programmable Clock Output
+// -------- PMC_SCDR : (PMC Offset: 0x4) System Clock Disable Register --------
+// -------- PMC_SCSR : (PMC Offset: 0x8) System Clock Status Register --------
+// -------- PMC_MCKR : (PMC Offset: 0x30) Master Clock Register --------
+#define AT91C_PMC_CSS         (0x3 <<  0) // (PMC) Programmable Clock Selection
+#define 	AT91C_PMC_CSS_SLOW_CLK             (0x0) // (PMC) Slow Clock is selected
+#define 	AT91C_PMC_CSS_MAIN_CLK             (0x1) // (PMC) Main Clock is selected
+#define 	AT91C_PMC_CSS_PLLA_CLK             (0x2) // (PMC) Clock from PLL A is selected
+#define 	AT91C_PMC_CSS_PLLB_CLK             (0x3) // (PMC) Clock from PLL B is selected
+#define AT91C_PMC_PRES        (0x7 <<  2) // (PMC) Programmable Clock Prescaler
+#define 	AT91C_PMC_PRES_CLK                  (0x0 <<  2) // (PMC) Selected clock
+#define 	AT91C_PMC_PRES_CLK_2                (0x1 <<  2) // (PMC) Selected clock divided by 2
+#define 	AT91C_PMC_PRES_CLK_4                (0x2 <<  2) // (PMC) Selected clock divided by 4
+#define 	AT91C_PMC_PRES_CLK_8                (0x3 <<  2) // (PMC) Selected clock divided by 8
+#define 	AT91C_PMC_PRES_CLK_16               (0x4 <<  2) // (PMC) Selected clock divided by 16
+#define 	AT91C_PMC_PRES_CLK_32               (0x5 <<  2) // (PMC) Selected clock divided by 32
+#define 	AT91C_PMC_PRES_CLK_64               (0x6 <<  2) // (PMC) Selected clock divided by 64
+#define AT91C_PMC_MDIV        (0x3 <<  8) // (PMC) Master Clock Division
+#define 	AT91C_PMC_MDIV_1                    (0x0 <<  8) // (PMC) The master clock and the processor clock are the same
+#define 	AT91C_PMC_MDIV_2                    (0x1 <<  8) // (PMC) The processor clock is twice as fast as the master clock
+#define 	AT91C_PMC_MDIV_3                    (0x2 <<  8) // (PMC) The processor clock is three times faster than the master clock
+#define 	AT91C_PMC_MDIV_4                    (0x3 <<  8) // (PMC) The processor clock is four times faster than the master clock
+// -------- PMC_PCKR : (PMC Offset: 0x40) Programmable Clock Register --------
+// -------- PMC_IER : (PMC Offset: 0x60) PMC Interrupt Enable Register --------
+#define AT91C_PMC_MOSCS       (0x1 <<  0) // (PMC) MOSC Status/Enable/Disable/Mask
+#define AT91C_PMC_LOCKA       (0x1 <<  1) // (PMC) PLL A Status/Enable/Disable/Mask
+#define AT91C_PMC_LOCKB       (0x1 <<  2) // (PMC) PLL B Status/Enable/Disable/Mask
+#define AT91C_PMC_MCKRDY      (0x1 <<  3) // (PMC) MCK_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK0RDY     (0x1 <<  8) // (PMC) PCK0_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK1RDY     (0x1 <<  9) // (PMC) PCK1_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK2RDY     (0x1 << 10) // (PMC) PCK2_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK3RDY     (0x1 << 11) // (PMC) PCK3_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK4RDY     (0x1 << 12) // (PMC) PCK4_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK5RDY     (0x1 << 13) // (PMC) PCK5_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK6RDY     (0x1 << 14) // (PMC) PCK6_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK7RDY     (0x1 << 15) // (PMC) PCK7_RDY Status/Enable/Disable/Mask
+// -------- PMC_IDR : (PMC Offset: 0x64) PMC Interrupt Disable Register --------
+// -------- PMC_SR : (PMC Offset: 0x68) PMC Status Register --------
+// -------- PMC_IMR : (PMC Offset: 0x6c) PMC Interrupt Mask Register --------
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Clock Generator Controler
+// *****************************************************************************
+// -------- CKGR_MOR : (CKGR Offset: 0x0) Main Oscillator Register --------
+#define AT91C_CKGR_MOSCEN     (0x1 <<  0) // (CKGR) Main Oscillator Enable
+#define AT91C_CKGR_OSCTEST    (0x1 <<  1) // (CKGR) Oscillator Test
+#define AT91C_CKGR_OSCOUNT    (0xFF <<  8) // (CKGR) Main Oscillator Start-up Time
+// -------- CKGR_MCFR : (CKGR Offset: 0x4) Main Clock Frequency Register --------
+#define AT91C_CKGR_MAINF      (0xFFFF <<  0) // (CKGR) Main Clock Frequency
+#define AT91C_CKGR_MAINRDY    (0x1 << 16) // (CKGR) Main Clock Ready
+// -------- CKGR_PLLAR : (CKGR Offset: 0x8) PLL A Register --------
+#define AT91C_CKGR_DIVA       (0xFF <<  0) // (CKGR) Divider Selected
+#define 	AT91C_CKGR_DIVA_0                    (0x0) // (CKGR) Divider output is 0
+#define 	AT91C_CKGR_DIVA_BYPASS               (0x1) // (CKGR) Divider is bypassed
+#define AT91C_CKGR_PLLACOUNT  (0x3F <<  8) // (CKGR) PLL A Counter
+#define AT91C_CKGR_OUTA       (0x3 << 14) // (CKGR) PLL A Output Frequency Range
+#define 	AT91C_CKGR_OUTA_0                    (0x0 << 14) // (CKGR) Please refer to the PLLA datasheet
+#define 	AT91C_CKGR_OUTA_1                    (0x1 << 14) // (CKGR) Please refer to the PLLA datasheet
+#define 	AT91C_CKGR_OUTA_2                    (0x2 << 14) // (CKGR) Please refer to the PLLA datasheet
+#define 	AT91C_CKGR_OUTA_3                    (0x3 << 14) // (CKGR) Please refer to the PLLA datasheet
+#define AT91C_CKGR_MULA       (0x7FF << 16) // (CKGR) PLL A Multiplier
+#define AT91C_CKGR_SRCA       (0x1 << 29) // (CKGR) PLL A Source
+// -------- CKGR_PLLBR : (CKGR Offset: 0xc) PLL B Register --------
+#define AT91C_CKGR_DIVB       (0xFF <<  0) // (CKGR) Divider Selected
+#define 	AT91C_CKGR_DIVB_0                    (0x0) // (CKGR) Divider output is 0
+#define 	AT91C_CKGR_DIVB_BYPASS               (0x1) // (CKGR) Divider is bypassed
+#define AT91C_CKGR_PLLBCOUNT  (0x3F <<  8) // (CKGR) PLL B Counter
+#define AT91C_CKGR_OUTB       (0x3 << 14) // (CKGR) PLL B Output Frequency Range
+#define 	AT91C_CKGR_OUTB_0                    (0x0 << 14) // (CKGR) Please refer to the PLLB datasheet
+#define 	AT91C_CKGR_OUTB_1                    (0x1 << 14) // (CKGR) Please refer to the PLLB datasheet
+#define 	AT91C_CKGR_OUTB_2                    (0x2 << 14) // (CKGR) Please refer to the PLLB datasheet
+#define 	AT91C_CKGR_OUTB_3                    (0x3 << 14) // (CKGR) Please refer to the PLLB datasheet
+#define AT91C_CKGR_MULB       (0x7FF << 16) // (CKGR) PLL B Multiplier
+#define AT91C_CKGR_USB_96M    (0x1 << 28) // (CKGR) Divider for USB Ports
+#define AT91C_CKGR_USB_PLL    (0x1 << 29) // (CKGR) PLL Use
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Debug Unit
+// *****************************************************************************
+// -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register --------
+// -------- DBGU_MR : (DBGU Offset: 0x4) Debug Unit Mode Register --------
+// -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register --------
+#define AT91C_DBGU_TXRDY	(0x1 <<  1) // (DBGU) TXRDY Interrupt
+#define AT91C_DBGU_TXEMPTY	(0x1 <<  9) // (DBGU) TXEMPTY Interrupt
+// -------- DBGU_IDR : (DBGU Offset: 0xc) Debug Unit Interrupt Disable Register --------
+// -------- DBGU_IMR : (DBGU Offset: 0x10) Debug Unit Interrupt Mask Register --------
+// -------- DBGU_CSR : (DBGU Offset: 0x14) Debug Unit Channel Status Register --------
+// -------- DBGU_FNTR : (DBGU Offset: 0x48) Debug Unit FORCE_NTRST Register --------
+#define AT91C_DBGU_FORCE_NTRST  (0x1 <<  0) // (DBGU) Force NTRST in JTAG
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Peripheral Data Controller
+// *****************************************************************************
+// -------- PDC_PTCR : (PDC Offset: 0x20) PDC Transfer Control Register --------
+#define AT91C_PDC_RXTEN       (0x1 <<  0) // (PDC) Receiver Transfer Enable
+#define AT91C_PDC_RXTDIS      (0x1 <<  1) // (PDC) Receiver Transfer Disable
+#define AT91C_PDC_TXTEN       (0x1 <<  8) // (PDC) Transmitter Transfer Enable
+#define AT91C_PDC_TXTDIS      (0x1 <<  9) // (PDC) Transmitter Transfer Disable
+// -------- PDC_PTSR : (PDC Offset: 0x24) PDC Transfer Status Register --------
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Advanced Interrupt Controller
+// *****************************************************************************
+// -------- AIC_SMR : (AIC Offset: 0x0) Control Register --------
+#define AT91C_AIC_PRIOR       (0x7 <<  0) // (AIC) Priority Level
+#define 	AT91C_AIC_PRIOR_LOWEST               (0x0) // (AIC) Lowest priority level
+#define 	AT91C_AIC_PRIOR_HIGHEST              (0x7) // (AIC) Highest priority level
+#define AT91C_AIC_SRCTYPE     (0x3 <<  5) // (AIC) Interrupt Source Type
+#define 	AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE  (0x0 <<  5) // (AIC) Internal Sources Code Label Level Sensitive
+#define 	AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED   (0x1 <<  5) // (AIC) Internal Sources Code Label Edge triggered
+#define 	AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL       (0x2 <<  5) // (AIC) External Sources Code Label High-level Sensitive
+#define 	AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE    (0x3 <<  5) // (AIC) External Sources Code Label Positive Edge triggered
+// -------- AIC_CISR : (AIC Offset: 0x114) AIC Core Interrupt Status Register --------
+#define AT91C_AIC_NFIQ        (0x1 <<  0) // (AIC) NFIQ Status
+#define AT91C_AIC_NIRQ        (0x1 <<  1) // (AIC) NIRQ Status
+// -------- AIC_DCR : (AIC Offset: 0x138) AIC Debug Control Register (Protect) --------
+#define AT91C_AIC_DCR_PROT    (0x1 <<  0) // (AIC) Protection Mode
+#define AT91C_AIC_DCR_GMSK    (0x1 <<  1) // (AIC) General Mask
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR External Bus Interface
+// *****************************************************************************
+// -------- EBI_CSA : (EBI Offset: 0x0) Chip Select Assignment Register --------
+#define AT91C_EBI_CS0A        (0x1 <<  0) // (EBI) Chip Select 0 Assignment
+#define 	AT91C_EBI_CS0A_SMC                  (0x0) // (EBI) Chip Select 0 is assigned to the Static Memory Controller.
+#define 	AT91C_EBI_CS0A_BFC                  (0x1) // (EBI) Chip Select 0 is assigned to the Burst Flash Controller.
+#define AT91C_EBI_CS1A        (0x1 <<  1) // (EBI) Chip Select 1 Assignment
+#define 	AT91C_EBI_CS1A_SMC                  (0x0 <<  1) // (EBI) Chip Select 1 is assigned to the Static Memory Controller.
+#define 	AT91C_EBI_CS1A_SDRAMC               (0x1 <<  1) // (EBI) Chip Select 1 is assigned to the SDRAM Controller.
+#define AT91C_EBI_CS3A        (0x1 <<  3) // (EBI) Chip Select 3 Assignment
+#define 	AT91C_EBI_CS3A_SMC                  (0x0 <<  3) // (EBI) Chip Select 3 is only assigned to the Static Memory Controller and NCS3 behaves as defined by the SMC2.
+#define 	AT91C_EBI_CS3A_SMC_SmartMedia       (0x1 <<  3) // (EBI) Chip Select 3 is assigned to the Static Memory Controller and the SmartMedia Logic is activated.
+#define AT91C_EBI_CS4A        (0x1 <<  4) // (EBI) Chip Select 4 Assignment
+#define 	AT91C_EBI_CS4A_SMC                  (0x0 <<  4) // (EBI) Chip Select 4 is assigned to the Static Memory Controller and NCS4,NCS5 and NCS6 behave as defined by the SMC2.
+#define 	AT91C_EBI_CS4A_SMC_CompactFlash     (0x1 <<  4) // (EBI) Chip Select 4 is assigned to the Static Memory Controller and the CompactFlash Logic is activated.
+// -------- EBI_CFGR : (EBI Offset: 0x4) Configuration Register --------
+#define AT91C_EBI_DBPUC       (0x1 <<  0) // (EBI) Data Bus Pull-Up Configuration
+#define AT91C_EBI_EBSEN       (0x1 <<  1) // (EBI) Bus Sharing Enable
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Static Memory Controller 2 Interface
+// *****************************************************************************
+
+// -------- SMC2_CSR : (SMC2 Offset: 0x0) SMC2 Chip Select Register --------
+#define AT91C_SMC2_NWS        (0x7F <<  0) // (SMC2) Number of Wait States
+#define AT91C_SMC2_WSEN       (0x1 <<  7) // (SMC2) Wait State Enable
+#define AT91C_SMC2_TDF        (0xF <<  8) // (SMC2) Data Float Time
+#define AT91C_SMC2_BAT        (0x1 << 12) // (SMC2) Byte Access Type
+#define AT91C_SMC2_DBW        (0x1 << 13) // (SMC2) Data Bus Width
+#define 	AT91C_SMC2_DBW_16                   (0x1 << 13) // (SMC2) 16-bit.
+#define 	AT91C_SMC2_DBW_8                    (0x2 << 13) // (SMC2) 8-bit.
+#define AT91C_SMC2_DRP        (0x1 << 15) // (SMC2) Data Read Protocol
+#define AT91C_SMC2_ACSS       (0x3 << 16) // (SMC2) Address to Chip Select Setup
+#define 	AT91C_SMC2_ACSS_STANDARD             (0x0 << 16) // (SMC2) Standard, asserted at the beginning of the access and deasserted at the end.
+#define 	AT91C_SMC2_ACSS_1_CYCLE              (0x1 << 16) // (SMC2) One cycle less at the beginning and the end of the access.
+#define 	AT91C_SMC2_ACSS_2_CYCLES             (0x2 << 16) // (SMC2) Two cycles less at the beginning and the end of the access.
+#define 	AT91C_SMC2_ACSS_3_CYCLES             (0x3 << 16) // (SMC2) Three cycles less at the beginning and the end of the access.
+#define AT91C_SMC2_RWSETUP    (0x7 << 24) // (SMC2) Read and Write Signal Setup Time
+#define AT91C_SMC2_RWHOLD     (0x7 << 29) // (SMC2) Read and Write Signal Hold Time
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR SDRAM Controller Interface
+// *****************************************************************************
+// -------- SDRC_MR : (SDRC Offset: 0x0) SDRAM Controller Mode Register --------
+#define AT91C_SDRC_MODE       (0xF <<  0) // (SDRC) Mode
+#define 	AT91C_SDRC_MODE_NORMAL_CMD           (0x0) // (SDRC) Normal Mode
+#define 	AT91C_SDRC_MODE_NOP_CMD              (0x1) // (SDRC) NOP Command
+#define 	AT91C_SDRC_MODE_PRCGALL_CMD          (0x2) // (SDRC) All Banks Precharge Command
+#define 	AT91C_SDRC_MODE_LMR_CMD              (0x3) // (SDRC) Load Mode Register Command
+#define 	AT91C_SDRC_MODE_RFSH_CMD             (0x4) // (SDRC) Refresh Command
+#define AT91C_SDRC_DBW        (0x1 <<  4) // (SDRC) Data Bus Width
+#define 	AT91C_SDRC_DBW_32_BITS              (0x0 <<  4) // (SDRC) 32 Bits datas bus
+#define 	AT91C_SDRC_DBW_16_BITS              (0x1 <<  4) // (SDRC) 16 Bits datas bus
+// -------- SDRC_TR : (SDRC Offset: 0x4) SDRC Refresh Timer Register --------
+#define AT91C_SDRC_COUNT      (0xFFF <<  0) // (SDRC) Refresh Counter
+// -------- SDRC_CR : (SDRC Offset: 0x8) SDRAM Configuration Register --------
+#define AT91C_SDRC_NC         (0x3 <<  0) // (SDRC) Number of Column Bits
+#define 	AT91C_SDRC_NC_8                    (0x0) // (SDRC) 8 Bits
+#define 	AT91C_SDRC_NC_9                    (0x1) // (SDRC) 9 Bits
+#define 	AT91C_SDRC_NC_10                   (0x2) // (SDRC) 10 Bits
+#define 	AT91C_SDRC_NC_11                   (0x3) // (SDRC) 11 Bits
+#define AT91C_SDRC_NR         (0x3 <<  2) // (SDRC) Number of Row Bits
+#define 	AT91C_SDRC_NR_11                   (0x0 <<  2) // (SDRC) 11 Bits
+#define 	AT91C_SDRC_NR_12                   (0x1 <<  2) // (SDRC) 12 Bits
+#define 	AT91C_SDRC_NR_13                   (0x2 <<  2) // (SDRC) 13 Bits
+#define AT91C_SDRC_NB         (0x1 <<  4) // (SDRC) Number of Banks
+#define 	AT91C_SDRC_NB_2_BANKS              (0x0 <<  4) // (SDRC) 2 banks
+#define 	AT91C_SDRC_NB_4_BANKS              (0x1 <<  4) // (SDRC) 4 banks
+#define AT91C_SDRC_CAS        (0x3 <<  5) // (SDRC) CAS Latency
+#define 	AT91C_SDRC_CAS_2                    (0x2 <<  5) // (SDRC) 2 cycles
+#define AT91C_SDRC_TWR        (0xF <<  7) // (SDRC) Number of Write Recovery Time Cycles
+#define AT91C_SDRC_TRC        (0xF << 11) // (SDRC) Number of RAS Cycle Time Cycles
+#define AT91C_SDRC_TRP        (0xF << 15) // (SDRC) Number of RAS Precharge Time Cycles
+#define AT91C_SDRC_TRCD       (0xF << 19) // (SDRC) Number of RAS to CAS Delay Cycles
+#define AT91C_SDRC_TRAS       (0xF << 23) // (SDRC) Number of RAS Active Time Cycles
+#define AT91C_SDRC_TXSR       (0xF << 27) // (SDRC) Number of Command Recovery Time Cycles
+// -------- SDRC_SRR : (SDRC Offset: 0xc) SDRAM Controller Self-refresh Register --------
+#define AT91C_SDRC_SRCB       (0x1 <<  0) // (SDRC) Self-refresh Command Bit
+// -------- SDRC_LPR : (SDRC Offset: 0x10) SDRAM Controller Low-power Register --------
+#define AT91C_SDRC_LPCB       (0x1 <<  0) // (SDRC) Low-power Command Bit
+// -------- SDRC_IER : (SDRC Offset: 0x14) SDRAM Controller Interrupt Enable Register --------
+#define AT91C_SDRC_RES        (0x1 <<  0) // (SDRC) Refresh Error Status
+// -------- SDRC_IDR : (SDRC Offset: 0x18) SDRAM Controller Interrupt Disable Register --------
+// -------- SDRC_IMR : (SDRC Offset: 0x1c) SDRAM Controller Interrupt Mask Register --------
+// -------- SDRC_ISR : (SDRC Offset: 0x20) SDRAM Controller Interrupt Status Register --------
+
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Burst Flash Controller Interface
+// *****************************************************************************
+// -------- BFC_MR : (BFC Offset: 0x0) BFC Mode Register --------
+#define AT91C_BFC_BFCOM       (0x3 <<  0) // (BFC) Burst Flash Controller Operating Mode
+#define 	AT91C_BFC_BFCOM_DISABLED             (0x0) // (BFC) NPCS0 is driven by the SMC or remains high.
+#define 	AT91C_BFC_BFCOM_ASYNC                (0x1) // (BFC) Asynchronous
+#define 	AT91C_BFC_BFCOM_BURST_READ           (0x2) // (BFC) Burst Read
+#define AT91C_BFC_BFCC        (0x3 <<  2) // (BFC) Burst Flash Controller Operating Mode
+#define 	AT91C_BFC_BFCC_MCK                  (0x1 <<  2) // (BFC) Master Clock.
+#define 	AT91C_BFC_BFCC_MCK_DIV_2            (0x2 <<  2) // (BFC) Master Clock divided by 2.
+#define 	AT91C_BFC_BFCC_MCK_DIV_4            (0x3 <<  2) // (BFC) Master Clock divided by 4.
+#define AT91C_BFC_AVL         (0xF <<  4) // (BFC) Address Valid Latency
+#define AT91C_BFC_PAGES       (0x7 <<  8) // (BFC) Page Size
+#define 	AT91C_BFC_PAGES_NO_PAGE              (0x0 <<  8) // (BFC) No page handling.
+#define 	AT91C_BFC_PAGES_16                   (0x1 <<  8) // (BFC) 16 bytes page size.
+#define 	AT91C_BFC_PAGES_32                   (0x2 <<  8) // (BFC) 32 bytes page size.
+#define 	AT91C_BFC_PAGES_64                   (0x3 <<  8) // (BFC) 64 bytes page size.
+#define 	AT91C_BFC_PAGES_128                  (0x4 <<  8) // (BFC) 128 bytes page size.
+#define 	AT91C_BFC_PAGES_256                  (0x5 <<  8) // (BFC) 256 bytes page size.
+#define 	AT91C_BFC_PAGES_512                  (0x6 <<  8) // (BFC) 512 bytes page size.
+#define 	AT91C_BFC_PAGES_1024                 (0x7 <<  8) // (BFC) 1024 bytes page size.
+#define AT91C_BFC_OEL         (0x3 << 12) // (BFC) Output Enable Latency
+#define AT91C_BFC_BAAEN       (0x1 << 16) // (BFC) Burst Address Advance Enable
+#define AT91C_BFC_BFOEH       (0x1 << 17) // (BFC) Burst Flash Output Enable Handling
+#define AT91C_BFC_MUXEN       (0x1 << 18) // (BFC) Multiplexed Bus Enable
+#define AT91C_BFC_RDYEN       (0x1 << 19) // (BFC) Ready Enable Mode
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_TWI.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_TWI.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_TWI.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_TWI.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,89 @@
+// ----------------------------------------------------------------------------
+//          ATMEL Microcontroller Software Support  -  ROUSSET  -
+// ----------------------------------------------------------------------------
+//  The software is delivered "AS IS" without warranty or condition of any
+//  kind, either express, implied or statutory. This includes without
+//  limitation any warranty or condition with respect to merchantability or
+//  fitness for any particular purpose, or against the infringements of
+//  intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// File Name           : AT91RM9200.h
+// Object              : AT91RM9200 / TWI definitions
+// Generated           : AT91 SW Application Group  12/03/2002 (10:48:02)
+//
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_TWI_H
+#define AT91RM9200_TWI_H
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Two-wire Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+
+typedef struct _AT91S_TWI {
+	AT91_REG	 TWI_CR; 	// Control Register
+	AT91_REG	 TWI_MMR; 	// Master Mode Register
+	AT91_REG	 TWI_SMR; 	// Slave Mode Register
+	AT91_REG	 TWI_IADR; 	// Internal Address Register
+	AT91_REG	 TWI_CWGR; 	// Clock Waveform Generator Register
+	AT91_REG	 Reserved0[3]; 	//
+	AT91_REG	 TWI_SR; 	// Status Register
+	AT91_REG	 TWI_IER; 	// Interrupt Enable Register
+	AT91_REG	 TWI_IDR; 	// Interrupt Disable Register
+	AT91_REG	 TWI_IMR; 	// Interrupt Mask Register
+	AT91_REG	 TWI_RHR; 	// Receive Holding Register
+	AT91_REG	 TWI_THR; 	// Transmit Holding Register
+	AT91_REG	 Reserved1[50]; 	//
+	AT91_REG	 TWI_RPR; 	// Receive Pointer Register
+	AT91_REG	 TWI_RCR; 	// Receive Counter Register
+	AT91_REG	 TWI_TPR; 	// Transmit Pointer Register
+	AT91_REG	 TWI_TCR; 	// Transmit Counter Register
+	AT91_REG	 TWI_RNPR; 	// Receive Next Pointer Register
+	AT91_REG	 TWI_RNCR; 	// Receive Next Counter Register
+	AT91_REG	 TWI_TNPR; 	// Transmit Next Pointer Register
+	AT91_REG	 TWI_TNCR; 	// Transmit Next Counter Register
+	AT91_REG	 TWI_PTCR; 	// PDC Transfer Control Register
+	AT91_REG	 TWI_PTSR; 	// PDC Transfer Status Register
+} AT91S_TWI, *AT91PS_TWI;
+
+#endif
+
+// -------- TWI_CR : (TWI Offset: 0x0) TWI Control Register --------
+#define AT91C_TWI_START       ( 0x1 <<  0) // (TWI) Send a START Condition
+#define AT91C_TWI_STOP        ( 0x1 <<  1) // (TWI) Send a STOP Condition
+#define AT91C_TWI_MSEN        ( 0x1 <<  2) // (TWI) TWI Master Transfer Enabled
+#define AT91C_TWI_MSDIS       ( 0x1 <<  3) // (TWI) TWI Master Transfer Disabled
+#define AT91C_TWI_SVEN        ( 0x1 <<  4) // (TWI) TWI Slave Transfer Enabled
+#define AT91C_TWI_SVDIS       ( 0x1 <<  5) // (TWI) TWI Slave Transfer Disabled
+#define AT91C_TWI_SWRST       ( 0x1 <<  7) // (TWI) Software Reset
+// -------- TWI_MMR : (TWI Offset: 0x4) TWI Master Mode Register --------
+#define AT91C_TWI_IADRSZ      ( 0x3 <<  8) // (TWI) Internal Device Address Size
+#define 	AT91C_TWI_IADRSZ_NO                   ( 0x0 <<  8) // (TWI) No internal device address
+#define 	AT91C_TWI_IADRSZ_1_BYTE               ( 0x1 <<  8) // (TWI) One-byte internal device address
+#define 	AT91C_TWI_IADRSZ_2_BYTE               ( 0x2 <<  8) // (TWI) Two-byte internal device address
+#define 	AT91C_TWI_IADRSZ_3_BYTE               ( 0x3 <<  8) // (TWI) Three-byte internal device address
+#define AT91C_TWI_MREAD       ( 0x1 << 12) // (TWI) Master Read Direction
+#define AT91C_TWI_DADR        ( 0x7F <<  6) // (TWI) Device Address
+// -------- TWI_SMR : (TWI Offset: 0x8) TWI Slave Mode Register --------
+#define AT91C_TWI_SADR        ( 0x7F << 16) // (TWI) Slave Device Address
+// -------- TWI_CWGR : (TWI Offset: 0x10) TWI Clock Waveform Generator Register --------
+#define AT91C_TWI_CLDIV       ( 0xFF <<  0) // (TWI) Clock Low Divider
+#define AT91C_TWI_CHDIV       ( 0xFF <<  8) // (TWI) Clock High Divider
+#define AT91C_TWI_CKDIV       ( 0x7 << 16) // (TWI) Clock Divider
+// -------- TWI_SR : (TWI Offset: 0x20) TWI Status Register --------
+#define AT91C_TWI_TXCOMP      ( 0x1 <<  0) // (TWI) Transmission Completed
+#define AT91C_TWI_RXRDY       ( 0x1 <<  1) // (TWI) Receive holding register ReaDY
+#define AT91C_TWI_TXRDY       ( 0x1 <<  2) // (TWI) Transmit holding register ReaDY
+#define AT91C_TWI_SVREAD      ( 0x1 <<  3) // (TWI) Slave Read
+#define AT91C_TWI_SVACC       ( 0x1 <<  4) // (TWI) Slave Access
+#define AT91C_TWI_GCACC       ( 0x1 <<  5) // (TWI) General Call Access
+#define AT91C_TWI_OVRE        ( 0x1 <<  6) // (TWI) Overrun Error
+#define AT91C_TWI_UNRE        ( 0x1 <<  7) // (TWI) Underrun Error
+#define AT91C_TWI_NACK        ( 0x1 <<  8) // (TWI) Not Acknowledged
+#define AT91C_TWI_ARBLST      ( 0x1 <<  9) // (TWI) Arbitration Lost
+// -------- TWI_IER : (TWI Offset: 0x24) TWI Interrupt Enable Register --------
+// -------- TWI_IDR : (TWI Offset: 0x28) TWI Interrupt Disable Register --------
+// -------- TWI_IMR : (TWI Offset: 0x2c) TWI Interrupt Mask Register --------
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_UDP.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_UDP.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_UDP.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_UDP.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,104 @@
+// ----------------------------------------------------------------------------
+//          ATMEL Microcontroller Software Support  -  ROUSSET  -
+// ----------------------------------------------------------------------------
+//  The software is delivered "AS IS" without warranty or condition of any
+//  kind, either express, implied or statutory. This includes without
+//  limitation any warranty or condition with respect to merchantability or
+//  fitness for any particular purpose, or against the infringements of
+//  intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// File Name           : AT91RM9200.h
+// Object              : AT91RM9200 / UDP Device definitions
+// Generated           : AT91 SW Application Group  12/03/2002 (10:48:02)
+//
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_UDP_H
+#define AT91RM9200_UDP_H
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR USB Device Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+
+typedef struct _AT91S_UDP {
+	AT91_REG	 UDP_NUM; 	// Frame Number Register
+	AT91_REG	 UDP_GLBSTATE; 	// Global State Register
+	AT91_REG	 UDP_FADDR; 	// Function Address Register
+	AT91_REG	 Reserved0[1]; 	//
+	AT91_REG	 UDP_IER; 	// Interrupt Enable Register
+	AT91_REG	 UDP_IDR; 	// Interrupt Disable Register
+	AT91_REG	 UDP_IMR; 	// Interrupt Mask Register
+	AT91_REG	 UDP_ISR; 	// Interrupt Status Register
+	AT91_REG	 UDP_ICR; 	// Interrupt Clear Register
+	AT91_REG	 Reserved1[1]; 	//
+	AT91_REG	 UDP_RSTEP; 	// Reset Endpoint Register
+	AT91_REG	 Reserved2[1]; 	//
+	AT91_REG	 UDP_CSR[8]; 	// Endpoint Control and Status Register
+	AT91_REG	 UDP_FDR[8]; 	// Endpoint FIFO Data Register
+} AT91S_UDP, *AT91PS_UDP;
+
+#endif
+
+// -------- UDP_FRM_NUM : (UDP Offset: 0x0) USB Frame Number Register --------
+#define AT91C_UDP_FRM_NUM     ( 0x7FF <<  0) // (UDP) Frame Number as Defined in the Packet Field Formats
+#define AT91C_UDP_FRM_ERR     ( 0x1 << 16) // (UDP) Frame Error
+#define AT91C_UDP_FRM_OK      ( 0x1 << 17) // (UDP) Frame OK
+// -------- UDP_GLB_STATE : (UDP Offset: 0x4) USB Global State Register --------
+#define AT91C_UDP_FADDEN      ( 0x1 <<  0) // (UDP) Function Address Enable
+#define AT91C_UDP_CONFG       ( 0x1 <<  1) // (UDP) Configured
+#define AT91C_UDP_RMWUPE      ( 0x1 <<  2) // (UDP) Remote Wake Up Enable
+#define AT91C_UDP_RSMINPR     ( 0x1 <<  3) // (UDP) A Resume Has Been Sent to the Host
+// -------- UDP_FADDR : (UDP Offset: 0x8) USB Function Address Register --------
+#define AT91C_UDP_FADD        ( 0xFF <<  0) // (UDP) Function Address Value
+#define AT91C_UDP_FEN         ( 0x1 <<  8) // (UDP) Function Enable
+// -------- UDP_IER : (UDP Offset: 0x10) USB Interrupt Enable Register --------
+#define AT91C_UDP_EPINT0      ( 0x1 <<  0) // (UDP) Endpoint 0 Interrupt
+#define AT91C_UDP_EPINT1      ( 0x1 <<  1) // (UDP) Endpoint 0 Interrupt
+#define AT91C_UDP_EPINT2      ( 0x1 <<  2) // (UDP) Endpoint 2 Interrupt
+#define AT91C_UDP_EPINT3      ( 0x1 <<  3) // (UDP) Endpoint 3 Interrupt
+#define AT91C_UDP_EPINT4      ( 0x1 <<  4) // (UDP) Endpoint 4 Interrupt
+#define AT91C_UDP_EPINT5      ( 0x1 <<  5) // (UDP) Endpoint 5 Interrupt
+#define AT91C_UDP_EPINT6      ( 0x1 <<  6) // (UDP) Endpoint 6 Interrupt
+#define AT91C_UDP_EPINT7      ( 0x1 <<  7) // (UDP) Endpoint 7 Interrupt
+#define AT91C_UDP_RXSUSP      ( 0x1 <<  8) // (UDP) USB Suspend Interrupt
+#define AT91C_UDP_RXRSM       ( 0x1 <<  9) // (UDP) USB Resume Interrupt
+#define AT91C_UDP_EXTRSM      ( 0x1 << 10) // (UDP) USB External Resume Interrupt
+#define AT91C_UDP_SOFINT      ( 0x1 << 11) // (UDP) USB Start Of frame Interrupt
+#define AT91C_UDP_WAKEUP      ( 0x1 << 13) // (UDP) USB Resume Interrupt
+// -------- UDP_IDR : (UDP Offset: 0x14) USB Interrupt Disable Register --------
+// -------- UDP_IMR : (UDP Offset: 0x18) USB Interrupt Mask Register --------
+// -------- UDP_ISR : (UDP Offset: 0x1c) USB Interrupt Status Register --------
+#define AT91C_UDP_ENDBUSRES   ( 0x1 << 12) // (UDP) USB End Of Bus Reset Interrupt
+// -------- UDP_ICR : (UDP Offset: 0x20) USB Interrupt Clear Register --------
+// -------- UDP_RST_EP : (UDP Offset: 0x28) USB Reset Endpoint Register --------
+#define AT91C_UDP_EP0         ( 0x1 <<  0) // (UDP) Reset Endpoint 0
+#define AT91C_UDP_EP1         ( 0x1 <<  1) // (UDP) Reset Endpoint 1
+#define AT91C_UDP_EP2         ( 0x1 <<  2) // (UDP) Reset Endpoint 2
+#define AT91C_UDP_EP3         ( 0x1 <<  3) // (UDP) Reset Endpoint 3
+#define AT91C_UDP_EP4         ( 0x1 <<  4) // (UDP) Reset Endpoint 4
+#define AT91C_UDP_EP5         ( 0x1 <<  5) // (UDP) Reset Endpoint 5
+#define AT91C_UDP_EP6         ( 0x1 <<  6) // (UDP) Reset Endpoint 6
+#define AT91C_UDP_EP7         ( 0x1 <<  7) // (UDP) Reset Endpoint 7
+// -------- UDP_CSR : (UDP Offset: 0x30) USB Endpoint Control and Status Register --------
+#define AT91C_UDP_TXCOMP      ( 0x1 <<  0) // (UDP) Generates an IN packet with data previously written in the DPR
+#define AT91C_UDP_RX_DATA_BK0 ( 0x1 <<  1) // (UDP) Receive Data Bank 0
+#define AT91C_UDP_RXSETUP     ( 0x1 <<  2) // (UDP) Sends STALL to the Host (Control endpoints)
+#define AT91C_UDP_ISOERROR    ( 0x1 <<  3) // (UDP) Isochronous error (Isochronous endpoints)
+#define AT91C_UDP_TXPKTRDY    ( 0x1 <<  4) // (UDP) Transmit Packet Ready
+#define AT91C_UDP_FORCESTALL  ( 0x1 <<  5) // (UDP) Force Stall (used by Control, Bulk and Isochronous endpoints).
+#define AT91C_UDP_RX_DATA_BK1 ( 0x1 <<  6) // (UDP) Receive Data Bank 1 (only used by endpoints with ping-pong attributes).
+#define AT91C_UDP_DIR         ( 0x1 <<  7) // (UDP) Transfer Direction
+#define AT91C_UDP_EPTYPE      ( 0x7 <<  8) // (UDP) Endpoint type
+#define 	AT91C_UDP_EPTYPE_CTRL                 ( 0x0 <<  8) // (UDP) Control
+#define 	AT91C_UDP_EPTYPE_ISO_OUT              ( 0x1 <<  8) // (UDP) Isochronous OUT
+#define 	AT91C_UDP_EPTYPE_BULK_OUT             ( 0x2 <<  8) // (UDP) Bulk OUT
+#define 	AT91C_UDP_EPTYPE_INT_OUT              ( 0x3 <<  8) // (UDP) Interrupt OUT
+#define 	AT91C_UDP_EPTYPE_ISO_IN               ( 0x5 <<  8) // (UDP) Isochronous IN
+#define 	AT91C_UDP_EPTYPE_BULK_IN              ( 0x6 <<  8) // (UDP) Bulk IN
+#define 	AT91C_UDP_EPTYPE_INT_IN               ( 0x7 <<  8) // (UDP) Interrupt IN
+#define AT91C_UDP_DTGLE       ( 0x1 << 11) // (UDP) Data Toggle
+#define AT91C_UDP_EPEDS       ( 0x1 << 15) // (UDP) Endpoint Enable Disable
+#define AT91C_UDP_RXBYTECNT   ( 0x7FF << 16) // (UDP) Number Of Bytes Available in the FIFO
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_UHP.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_UHP.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_UHP.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_UHP.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,51 @@
+// ----------------------------------------------------------------------------
+//          ATMEL Microcontroller Software Support  -  ROUSSET  -
+// ----------------------------------------------------------------------------
+//  The software is delivered "AS IS" without warranty or condition of any
+//  kind, either express, implied or statutory. This includes without
+//  limitation any warranty or condition with respect to merchantability or
+//  fitness for any particular purpose, or against the infringements of
+//  intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// File Name           : AT91RM9200.h
+// Object              : AT91RM9200 / USB Host definitions
+// Generated           : AT91 SW Application Group  12/03/2002 (10:48:02)
+//
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_UHP_H
+#define AT91RM9200_UHP_H
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR USB Host Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+
+typedef struct _AT91S_UHP {
+	AT91_REG	 UHP_HcRevision; 	// Revision
+	AT91_REG	 UHP_HcControl; 	// Operating modes for the Host Controller
+	AT91_REG	 UHP_HcCommandStatus; 	// Command & status Register
+	AT91_REG	 UHP_HcInterruptStatus; 	// Interrupt Status Register
+	AT91_REG	 UHP_HcInterruptEnable; 	// Interrupt Enable Register
+	AT91_REG	 UHP_HcInterruptDisable; 	// Interrupt Disable Register
+	AT91_REG	 UHP_HcHCCA; 	// Pointer to the Host Controller Communication Area
+	AT91_REG	 UHP_HcPeriodCurrentED; 	// Current Isochronous or Interrupt Endpoint Descriptor
+	AT91_REG	 UHP_HcControlHeadED; 	// First Endpoint Descriptor of the Control list
+	AT91_REG	 UHP_HcControlCurrentED; 	// Endpoint Control and Status Register
+	AT91_REG	 UHP_HcBulkHeadED; 	// First endpoint register of the Bulk list
+	AT91_REG	 UHP_HcBulkCurrentED; 	// Current endpoint of the Bulk list
+	AT91_REG	 UHP_HcBulkDoneHead; 	// Last completed transfer descriptor
+	AT91_REG	 UHP_HcFmInterval; 	// Bit time between 2 consecutive SOFs
+	AT91_REG	 UHP_HcFmRemaining; 	// Bit time remaining in the current Frame
+	AT91_REG	 UHP_HcFmNumber; 	// Frame number
+	AT91_REG	 UHP_HcPeriodicStart; 	// Periodic Start
+	AT91_REG	 UHP_HcLSThreshold; 	// LS Threshold
+	AT91_REG	 UHP_HcRhDescriptorA; 	// Root Hub characteristics A
+	AT91_REG	 UHP_HcRhDescriptorB; 	// Root Hub characteristics B
+	AT91_REG	 UHP_HcRhStatus; 	// Root Hub Status register
+	AT91_REG	 UHP_HcRhPortStatus[2]; 	// Root Hub Port Status Register
+} AT91S_UHP, *AT91PS_UHP;
+
+#endif
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_USART.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_USART.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/AT91RM9200_USART.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/AT91RM9200_USART.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,149 @@
+// ----------------------------------------------------------------------------
+//          ATMEL Microcontroller Software Support  -  ROUSSET  -
+// ----------------------------------------------------------------------------
+//  The software is delivered "AS IS" without warranty or condition of any
+//  kind, either express, implied or statutory. This includes without
+//  limitation any warranty or condition with respect to merchantability or
+//  fitness for any particular purpose, or against the infringements of
+//  intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// File Name           : AT91RM9200.h
+// Object              : AT91RM9200 / USART definitions
+// Generated           : AT91 SW Application Group  01/17/2003 (13:41:22)
+//
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_USART_H
+#define AT91RM9200_USART_H
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Usart
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+
+typedef struct _AT91S_USART {
+	AT91_REG	 US_CR; 	// Control Register
+	AT91_REG	 US_MR; 	// Mode Register
+	AT91_REG	 US_IER; 	// Interrupt Enable Register
+	AT91_REG	 US_IDR; 	// Interrupt Disable Register
+	AT91_REG	 US_IMR; 	// Interrupt Mask Register
+	AT91_REG	 US_CSR; 	// Channel Status Register
+	AT91_REG	 US_RHR; 	// Receiver Holding Register
+	AT91_REG	 US_THR; 	// Transmitter Holding Register
+	AT91_REG	 US_BRGR; 	// Baud Rate Generator Register
+	AT91_REG	 US_RTOR; 	// Receiver Time-out Register
+	AT91_REG	 US_TTGR; 	// Transmitter Time-guard Register
+	AT91_REG	 Reserved0[5]; 	//
+	AT91_REG	 US_FIDI; 	// FI_DI_Ratio Register
+	AT91_REG	 US_NER; 	// Nb Errors Register
+	AT91_REG	 US_XXR; 	// XON_XOFF Register
+	AT91_REG	 US_IF; 	// IRDA_FILTER Register
+	AT91_REG	 Reserved1[44]; //
+	AT91_REG	 US_RPR; 	// Receive Pointer Register
+	AT91_REG	 US_RCR; 	// Receive Counter Register
+	AT91_REG	 US_TPR; 	// Transmit Pointer Register
+	AT91_REG	 US_TCR; 	// Transmit Counter Register
+	AT91_REG	 US_RNPR; 	// Receive Next Pointer Register
+	AT91_REG	 US_RNCR; 	// Receive Next Counter Register
+	AT91_REG	 US_TNPR; 	// Transmit Next Pointer Register
+	AT91_REG	 US_TNCR; 	// Transmit Next Counter Register
+	AT91_REG	 US_PTCR; 	// PDC Transfer Control Register
+	AT91_REG	 US_PTSR; 	// PDC Transfer Status Register
+} AT91S_USART, *AT91PS_USART;
+
+#endif
+
+// -------- US_CR : (USART Offset: 0x0) Debug Unit Control Register --------
+#define AT91C_US_RSTRX        ( 0x1 <<  2) // (USART) Reset Receiver
+#define AT91C_US_RSTTX        ( 0x1 <<  3) // (USART) Reset Transmitter
+#define AT91C_US_RXEN	      ( 0x1 <<  4) // (USART) Receiver Enable
+#define AT91C_US_RXDIS        ( 0x1 <<  5) // (USART) Receiver Disable
+#define AT91C_US_TXEN	      ( 0x1 <<  6) // (USART) Transmitter Enable
+#define AT91C_US_TXDIS        ( 0x1 <<  7) // (USART) Transmitter Disable
+#define AT91C_US_RSTSTA       ( 0x1 <<  8) // (USART) Reset Status Bits
+#define AT91C_US_STTBRK       ( 0x1 <<  9) // (USART) Start Break
+#define AT91C_US_STPBRK       ( 0x1 << 10) // (USART) Stop Break
+#define AT91C_US_STTTO        ( 0x1 << 11) // (USART) Start Time-out
+#define AT91C_US_SENDA        ( 0x1 << 12) // (USART) Send Address
+#define AT91C_US_RSTIT        ( 0x1 << 13) // (USART) Reset Iterations
+#define AT91C_US_RSTNACK      ( 0x1 << 14) // (USART) Reset Non Acknowledge
+#define AT91C_US_RETTO        ( 0x1 << 15) // (USART) Rearm Time-out
+#define AT91C_US_DTREN        ( 0x1 << 16) // (USART) Data Terminal ready Enable
+#define AT91C_US_DTRDIS       ( 0x1 << 17) // (USART) Data Terminal ready Disable
+#define AT91C_US_RTSEN        ( 0x1 << 18) // (USART) Request to Send enable
+#define AT91C_US_RTSDIS       ( 0x1 << 19) // (USART) Request to Send Disable
+// -------- US_MR : (USART Offset: 0x4) Debug Unit Mode Register --------
+#define AT91C_US_USMODE       ( 0xF <<  0) // (USART) Usart mode
+#define 	AT91C_US_USMODE_NORMAL               ( 0x0) // (USART) Normal
+#define 	AT91C_US_USMODE_RS485                ( 0x1) // (USART) RS485
+#define 	AT91C_US_USMODE_HWHSH                ( 0x2) // (USART) Hardware Handshaking
+#define 	AT91C_US_USMODE_MODEM                ( 0x3) // (USART) Modem
+#define 	AT91C_US_USMODE_ISO7816_0            ( 0x4) // (USART) ISO7816 protocol: T = 0
+#define 	AT91C_US_USMODE_ISO7816_1            ( 0x6) // (USART) ISO7816 protocol: T = 1
+#define 	AT91C_US_USMODE_IRDA                 ( 0x8) // (USART) IrDA
+#define 	AT91C_US_USMODE_SWHSH                ( 0xC) // (USART) Software Handshaking
+#define AT91C_US_CLKS         ( 0x3 <<  4) // (USART) Clock Selection (Baud Rate generator Input Clock
+#define 	AT91C_US_CLKS_CLOCK                ( 0x0 <<  4) // (USART) Clock
+#define 	AT91C_US_CLKS_FDIV1                ( 0x1 <<  4) // (USART) fdiv1
+#define 	AT91C_US_CLKS_SLOW                 ( 0x2 <<  4) // (USART) slow_clock (ARM)
+#define 	AT91C_US_CLKS_EXT                  ( 0x3 <<  4) // (USART) External (SCK)
+#define AT91C_US_CHRL         ( 0x3 <<  6) // (USART) Clock Selection (Baud Rate generator Input Clock
+#define 	AT91C_US_CHRL_5_BITS               ( 0x0 <<  6) // (USART) Character Length: 5 bits
+#define 	AT91C_US_CHRL_6_BITS               ( 0x1 <<  6) // (USART) Character Length: 6 bits
+#define 	AT91C_US_CHRL_7_BITS               ( 0x2 <<  6) // (USART) Character Length: 7 bits
+#define 	AT91C_US_CHRL_8_BITS               ( 0x3 <<  6) // (USART) Character Length: 8 bits
+#define AT91C_US_SYNC         ( 0x1 <<  8) // (USART) Synchronous Mode Select
+#define AT91C_US_PAR          ( 0x7 <<  9) // (USART) Parity type
+#define		AT91C_US_PAR_EVEN                 ( 0x0 <<  9) // (USART) Even Parity
+#define		AT91C_US_PAR_ODD                  ( 0x1 <<  9) // (USART) Odd Parity
+#define 	AT91C_US_PAR_SPACE                ( 0x2 <<  9) // (USART) Parity forced to 0 (Space)
+#define		AT91C_US_PAR_MARK                 ( 0x3 <<  9) // (USART) Parity forced to 1 (Mark)
+#define		AT91C_US_PAR_NONE                 ( 0x4 <<  9) // (USART) No Parity
+#define		AT91C_US_PAR_MULTI_DROP           ( 0x6 <<  9) // (USART) Multi-drop mode
+#define AT91C_US_NBSTOP       ( 0x3 << 12) // (USART) Number of Stop bits
+#define 	AT91C_US_NBSTOP_1_BIT                ( 0x0 << 12) // (USART) 1 stop bit
+#define 	AT91C_US_NBSTOP_15_BIT               ( 0x1 << 12) // (USART) Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits
+#define 	AT91C_US_NBSTOP_2_BIT                ( 0x2 << 12) // (USART) 2 stop bits
+#define AT91C_US_CHMODE       ( 0x3 << 14) // (USART) Channel Mode
+#define 	AT91C_US_CHMODE_NORMAL               ( 0x0 << 14) // (USART) Normal Mode: The USART channel operates as an RX/TX USART.
+#define 	AT91C_US_CHMODE_AUTO                 ( 0x1 << 14) // (USART) Automatic Echo: Receiver Data Input is connected to the TXD pin.
+#define 	AT91C_US_CHMODE_LOCAL                ( 0x2 << 14) // (USART) Local Loopback: Transmitter Output Signal is connected to Receiver Input Signal.
+#define 	AT91C_US_CHMODE_REMOTE               ( 0x3 << 14) // (USART) Remote Loopback: RXD pin is internally connected to TXD pin.
+#define AT91C_US_MSBF         ( 0x1 << 16) // (USART) Bit Order
+#define AT91C_US_MODE9        ( 0x1 << 17) // (USART) 9-bit Character length
+#define AT91C_US_CKLO         ( 0x1 << 18) // (USART) Clock Output Select
+#define AT91C_US_OVER         ( 0x1 << 19) // (USART) Over Sampling Mode
+#define AT91C_US_INACK        ( 0x1 << 20) // (USART) Inhibit Non Acknowledge
+#define AT91C_US_DSNACK       ( 0x1 << 21) // (USART) Disable Successive NACK
+#define AT91C_US_MAX_ITER     ( 0x1 << 24) // (USART) Number of Repetitions
+#define AT91C_US_FILTER       ( 0x1 << 28) // (USART) Receive Line Filter
+// -------- US_IER : (USART Offset: 0x8) Debug Unit Interrupt Enable Register --------
+#define AT91C_US_RXRDY        ( 0x1 <<  0) // (USART) RXRDY Interrupt
+#define AT91C_US_TXRDY        ( 0x1 <<  1) // (USART) TXRDY Interrupt
+#define AT91C_US_RXBRK        ( 0x1 <<  2) // (USART) Break Received/End of Break
+#define AT91C_US_ENDRX        ( 0x1 <<  3) // (USART) End of Receive Transfer Interrupt
+#define AT91C_US_ENDTX        ( 0x1 <<  4) // (USART) End of Transmit Interrupt
+#define AT91C_US_OVRE         ( 0x1 <<  5) // (USART) Overrun Interrupt
+#define AT91C_US_FRAME        ( 0x1 <<  6) // (USART) Framing Error Interrupt
+#define AT91C_US_PARE         ( 0x1 <<  7) // (USART) Parity Error Interrupt
+#define AT91C_US_TIMEOUT      ( 0x1 <<  8) // (USART) Receiver Time-out
+#define AT91C_US_TXEMPTY      ( 0x1 <<  9) // (USART) TXEMPTY Interrupt
+#define AT91C_US_ITERATION    ( 0x1 << 10) // (USART) Max number of Repetitions Reached
+#define AT91C_US_TXBUFE       ( 0x1 << 11) // (USART) TXBUFE Interrupt
+#define AT91C_US_RXBUFF       ( 0x1 << 12) // (USART) RXBUFF Interrupt
+#define AT91C_US_NACK         ( 0x1 << 13) // (USART) Non Acknowledge
+#define AT91C_US_RIIC         ( 0x1 << 16) // (USART) Ring INdicator Input Change Flag
+#define AT91C_US_DSRIC        ( 0x1 << 17) // (USART) Data Set Ready Input Change Flag
+#define AT91C_US_DCDIC        ( 0x1 << 18) // (USART) Data Carrier Flag
+#define AT91C_US_CTSIC        ( 0x1 << 19) // (USART) Clear To Send Input Change Flag
+#define AT91C_US_COMM_TX      ( 0x1 << 30) // (USART) COMM_TX Interrupt
+#define AT91C_US_COMM_RX      ( 0x1 << 31) // (USART) COMM_RX Interrupt
+// -------- US_IDR : (USART Offset: 0xc) Debug Unit Interrupt Disable Register --------
+// -------- US_IMR : (USART Offset: 0x10) Debug Unit Interrupt Mask Register --------
+// -------- US_CSR : (USART Offset: 0x14) Debug Unit Channel Status Register --------
+#define AT91C_US_RI           ( 0x1 << 20) // (USART) Image of RI Input
+#define AT91C_US_DSR          ( 0x1 << 21) // (USART) Image of DSR Input
+#define AT91C_US_DCD          ( 0x1 << 22) // (USART) Image of DCD Input
+#define AT91C_US_CTS          ( 0x1 << 23) // (USART) Image of CTS Input
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/at91rm9200dk.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/at91rm9200dk.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/at91rm9200dk.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/at91rm9200dk.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,80 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/at91rm9200dk.h
+ *
+ *  Copyright (c) 2003 SAN People
+ *  Copyright (c) 2003 ATMEL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_AT91RM9200DK_H
+#define __ASM_ARCH_HARDWARE_AT91RM9200DK_H
+
+
+/* AT91RM92000 clocks */
+#define AT91C_MAIN_CLOCK	179712000	/* from 18.432 MHz crystal (18432000 / 4 * 39) */
+#define AT91C_MASTER_CLOCK	59904000	/* peripheral clock (AT91C_MASTER_CLOCK / 3) */
+#define AT91C_SLOW_CLOCK	32768		/* slow clock */
+
+
+/* FLASH */
+#define AT91_FLASH_BASE		0x10000000	// NCS0: Flash physical base address
+
+/* SDRAM */
+#define AT91_SDRAM_BASE		0x20000000	// NCS1: SDRAM physical base address
+
+/* SmartMedia */
+#define AT91_SMARTMEDIA_BASE	0x40000000	// NCS3: Smartmedia physical base address
+
+/* Multi-Master Memory controller */
+#define AT91_UHP_BASE		0x00300000	// USB Host controller
+
+
+/* Peripheral interrupt configuration */
+#define AT91_SMR_FIQ	(AT91C_AIC_PRIOR_HIGHEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (FIQ)
+#define AT91_SMR_SYS	(AT91C_AIC_PRIOR_HIGHEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// System Peripheral
+#define AT91_SMR_PIOA	(AT91C_AIC_PRIOR_LOWEST	 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Parallel IO Controller A
+#define AT91_SMR_PIOB	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Parallel IO Controller B
+#define AT91_SMR_PIOC	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Parallel IO Controller C
+#define AT91_SMR_PIOD	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Parallel IO Controller D
+#define AT91_SMR_US0	(AT91C_AIC_PRIOR_6       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USART 0
+#define AT91_SMR_US1	(AT91C_AIC_PRIOR_6       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USART 1
+#define AT91_SMR_US2	(AT91C_AIC_PRIOR_6       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USART 2
+#define AT91_SMR_US3	(AT91C_AIC_PRIOR_6       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USART 3
+#define AT91_SMR_MCI	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Multimedia Card Interface
+#define AT91_SMR_UDP	(AT91C_AIC_PRIOR_4       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USB Device Port
+#define AT91_SMR_TWI	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Two-Wire Interface
+#define AT91_SMR_SPI	(AT91C_AIC_PRIOR_6       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Serial Peripheral Interface
+#define AT91_SMR_SSC0	(AT91C_AIC_PRIOR_5       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Serial Synchronous Controller 0
+#define AT91_SMR_SSC1	(AT91C_AIC_PRIOR_5       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Serial Synchronous Controller 1
+#define AT91_SMR_SSC2	(AT91C_AIC_PRIOR_5       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Serial Synchronous Controller 2
+#define AT91_SMR_TC0	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 0
+#define AT91_SMR_TC1	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 1
+#define AT91_SMR_TC2	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 2
+#define AT91_SMR_TC3	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 3
+#define AT91_SMR_TC4	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 4
+#define AT91_SMR_TC5	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 5
+#define AT91_SMR_UHP	(AT91C_AIC_PRIOR_3       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USB Host port
+#define AT91_SMR_EMAC	(AT91C_AIC_PRIOR_3       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Ethernet MAC
+#define AT91_SMR_IRQ0	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ0)
+#define AT91_SMR_IRQ1	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ1)
+#define AT91_SMR_IRQ2	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ2)
+#define AT91_SMR_IRQ3	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ3)
+#define AT91_SMR_IRQ4	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ4)
+#define AT91_SMR_IRQ5	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ5)
+#define AT91_SMR_IRQ6	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ6)
+
+
+/*
+ * Serial port configuration.
+ *    0 .. 3 = USART0 .. USART3
+ *    4      = DBGU
+ */
+#define AT91C_UART_MAP		{ 4, 1, -1, -1, -1 }	/* ttyS0, ..., ttyS4 */
+#define AT91C_CONSOLE		0			/* ttyS0 */
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/dma.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/dma.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/dma.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/dma.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,27 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/dma.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS		0xffffffff
+#define MAX_DMA_CHANNELS	0
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/hardware.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/hardware.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/hardware.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/hardware.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,86 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/hardware.h
+ *
+ *  Copyright (c) 2003 SAN People
+ *  Copyright (c) 2003 ATMEL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+#include <asm/arch/AT91RM9200.h>
+#include <asm/arch/AT91RM9200_SYS.h>
+
+#ifndef __ASSEMBLY__
+ /*
+  * The following variable is defined in arch/arm/mach-at91rm9200/core.c
+  * It is a pointer to the AT91RM9200 system peripherals.
+  */
+extern AT91PS_SYS AT91_SYS;
+#endif
+
+
+/*
+ * Remap the peripherals from address 0xFFFA0000 .. 0xFFFFFFFF
+ * to 0xFEFA0000 .. 0xFF000000.  (384Kb)
+ */
+#define AT91C_IO_PHYS_BASE	0xFFFA0000
+#define AT91C_IO_SIZE		(0xFFFFFFFF - AT91C_IO_PHYS_BASE + 1)
+#define AT91C_IO_VIRT_BASE	(0xFF000000 - AT91C_IO_SIZE)
+
+ /* Convert a physical IO address to virtual IO address */
+#define AT91_IO_P2V(x)	((x) - AT91C_IO_PHYS_BASE + AT91C_IO_VIRT_BASE)
+
+/*
+ * Virtual to Physical Address mapping for IO devices.
+ */
+#define AT91C_VA_BASE_SYS	AT91_IO_P2V(AT91C_BASE_SYS)
+#define AT91C_VA_BASE_SPI	AT91_IO_P2V(AT91C_BASE_SPI)
+#define AT91C_VA_BASE_SSC2	AT91_IO_P2V(AT91C_BASE_SSC2)
+#define AT91C_VA_BASE_SSC1	AT91_IO_P2V(AT91C_BASE_SSC1)
+#define AT91C_VA_BASE_SSC0	AT91_IO_P2V(AT91C_BASE_SSC0)
+#define AT91C_VA_BASE_US3	AT91_IO_P2V(AT91C_BASE_US3)
+#define AT91C_VA_BASE_US2	AT91_IO_P2V(AT91C_BASE_US2)
+#define AT91C_VA_BASE_US1	AT91_IO_P2V(AT91C_BASE_US1)
+#define AT91C_VA_BASE_US0	AT91_IO_P2V(AT91C_BASE_US0)
+#define AT91C_VA_BASE_EMAC	AT91_IO_P2V(AT91C_BASE_EMAC)
+#define AT91C_VA_BASE_TWI	AT91_IO_P2V(AT91C_BASE_TWI)
+#define AT91C_VA_BASE_MCI	AT91_IO_P2V(AT91C_BASE_MCI)
+#define AT91C_VA_BASE_UDP	AT91_IO_P2V(AT91C_BASE_UDP)
+#define AT91C_VA_BASE_TCB1	AT91_IO_P2V(AT91C_BASE_TCB1)
+#define AT91C_VA_BASE_TCB0	AT91_IO_P2V(AT91C_BASE_TCB0)
+
+
+#define AT91C_BASE_SRAM		0x00200000	/* Internal SRAM base address */
+
+#define AT91C_NR_UART		5		/* 4 USART3's and one DBGU port */
+
+ /* Definition of interrupt priority levels */
+#define AT91C_AIC_PRIOR_0 AT91C_AIC_PRIOR_LOWEST
+#define AT91C_AIC_PRIOR_1 ((unsigned int) 0x1)
+#define AT91C_AIC_PRIOR_2 ((unsigned int) 0x2)
+#define AT91C_AIC_PRIOR_3 ((unsigned int) 0x3)
+#define AT91C_AIC_PRIOR_4 ((unsigned int) 0x4)
+#define AT91C_AIC_PRIOR_5 ((unsigned int) 0x5)
+#define AT91C_AIC_PRIOR_6 ((unsigned int) 0x6)
+#define AT91C_AIC_PRIOR_7 AT91C_AIC_PRIOR_HIGEST
+
+
+/*
+ * Implementation specific hardware definitions.
+ */
+
+#ifdef CONFIG_ARCH_AT91RM9200DK
+#include <asm/arch/at91rm9200dk.h>
+#endif
+
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/io.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/io.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/io.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/io.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,45 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/io.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT		0xFFFFFFFF
+
+#define __io(a)			(a)
+#define __mem_pci(a)		((unsigned long)(a))
+
+/*
+ * Generic virtual read/write
+ */
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Validate the pci memory address for ioremap.
+ */
+#define iomem_valid_addr(iomem,size)	(1)
+
+/*
+ * Convert PCI memory space to a CPU physical address
+ */
+#define iomem_to_phys(iomem)	(iomem)
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/irq.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/irq.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/irq.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/irq.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,33 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/irq.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_IRQ_H
+#define __ASM_ARCH_IRQ_H
+
+/* The FIQ (irq = 0) is treated as a spurious IRQ */
+#define fixup_irq(i)	(i ? i : NR_IRQS)
+
+/*
+ * Acknowledge interrupt with AIC after interrupt has been handled.
+ *   (by kernel/irq.c)
+ */
+#define irq_finish(irq) do { AT91_SYS->AIC_EOICR = 0; } while (0)
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/irqs.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/irqs.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/irqs.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/irqs.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,31 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/irqs.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define NR_IRQS 32
+
+/*
+ *  IRQ interrupts definitions are the same as the ID definitions
+ *  in AT91RM9200.h
+ */
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/memory.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/memory.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/memory.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,61 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/memory.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <asm/arch/hardware.h>
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE	(0xc0000000)
+#define TASK_SIZE_26	(0x04000000)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET	TASK_SIZE
+#define PHYS_OFFSET	(AT91_SDRAM_BASE)
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - PHYS_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *              address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *              to an address that the kernel can use.
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x) __phys_to_virt(x)
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/param.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/param.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/param.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/param.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,28 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/param.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_PARAM_H
+#define __ASM_ARCH_PARAM_H
+
+/*
+ * We use default params
+ */
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/pio.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/pio.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/pio.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/pio.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,133 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/pio.h
+ *
+ *  Copyright (c) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_PIO_H
+#define __ASM_ARCH_PIO_H
+
+#include <asm/arch/hardware.h>
+
+static inline void AT91_CfgPIO_USART0(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA17_TXD0 | AT91C_PA18_RXD0
+		| AT91C_PA20_CTS0 | AT91C_PA21_RTS0;
+}
+
+static inline void AT91_CfgPIO_USART1(void) {
+	AT91_SYS->PIOB_PDR = AT91C_PB18_RI1 | AT91C_PB19_DTR1
+		| AT91C_PB20_TXD1 | AT91C_PB21_RXD1 | AT91C_PB23_DCD1
+		| AT91C_PB24_CTS1 | AT91C_PB25_DSR1 | AT91C_PB26_RTS1;
+}
+
+static inline void AT91_CfgPIO_USART2(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA22_RXD2 | AT91C_PA23_TXD2;
+}
+
+static inline void AT91_CfgPIO_USART3(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA5_TXD3 | AT91C_PA6_RXD3;
+	AT91_SYS->PIOA_BSR = AT91C_PA5_TXD3 | AT91C_PA6_RXD3;
+}
+
+static inline void AT91_CfgPIO_DBGU(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA31_DTXD | AT91C_PA30_DRXD;
+}
+
+/*
+ * Configure Ethernet for RMII mode.
+ */
+static inline void AT91_CfgPIO_EMAC_RMII(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1
+		| AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1
+		| AT91C_PA9_ETX0 | AT91C_PA8_ETXEN | AT91C_PA7_ETXCK_EREFCK;
+	AT91_SYS->PIOB_PDR = AT91C_PB25_EF100 | AT91C_PB19_ERXCK;
+	AT91_SYS->PIOB_BSR = AT91C_PB25_EF100 | AT91C_PB19_ERXCK;
+}
+
+/*
+ * Configure Ethernet for MII mode.
+ */
+static inline void AT91_CfgPIO_EMAC_MII(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1
+		| AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1
+		| AT91C_PA9_ETX0 | AT91C_PA8_ETXEN | AT91C_PA7_ETXCK_EREFCK;
+	AT91_SYS->PIOB_PDR = AT91C_PB25_EF100 | AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV
+		| AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3
+		| AT91C_PB12_ETX2;
+	AT91_SYS->PIOB_BSR = AT91C_PB25_EF100 | AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV
+		| AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3
+		| AT91C_PB12_ETX2;
+}
+
+/*
+ * Enable the Two-Wire interface.
+ */
+static inline void AT91_CfgPIO_TWI(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
+	AT91_SYS->PIOA_ASR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
+}
+
+/*
+ * Enable the Serial Peripheral Interface.
+ */
+static inline void AT91_CfgPIO_SPI(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA0_MISO | AT91C_PA1_MOSI | AT91C_PA2_SPCK;
+}
+
+static inline void AT91_CfgPIO_SPI_CS0(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA3_NPCS0;
+}
+
+static inline void AT91_CfgPIO_SPI_CS1(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA4_NPCS1;
+}
+
+static inline void AT91_CfgPIO_SPI_CS2(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA5_NPCS2;
+}
+
+static inline void AT91_CfgPIO_SPI_CS3(void) {
+	AT91_SYS->PIOA_PDR = AT91C_PA6_NPCS3;
+}
+
+/*
+ * Select the DataFlash card.
+ */
+static inline void AT91_CfgPIO_DataFlashCard(void) {
+	AT91_SYS->PIOB_PER = AT91C_PIO_PB7;
+	AT91_SYS->PIOB_OER = AT91C_PIO_PB7;
+	AT91_SYS->PIOB_CODR = AT91C_PIO_PB7;
+}
+
+/*
+ * Enable NAND Flash (SmartMedia) interface.
+ */
+static inline void AT91_CfgPIO_SmartMedia(void) {
+	/* enable PC0=SMCE, PC1=SMOE, PC3=SMWE, A21=CLE, A22=ALE */
+	AT91_SYS->PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
+	AT91_SYS->PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
+
+	/* Configure PC2 as input (signal READY of the SmartMedia) */
+	AT91_SYS->PIOC_PER = AT91C_PC2_BFAVD;	/* enable direct output enable */
+	AT91_SYS->PIOC_ODR = AT91C_PC2_BFAVD;	/* disable output */
+
+	/* Configure PB1 as input (signal Card Detect of the SmartMedia) */
+	AT91_SYS->PIOB_PER = AT91C_PIO_PB1;	/* enable direct output enable */
+	AT91_SYS->PIOB_ODR = AT91C_PIO_PB1;	/* disable output */
+}
+
+static inline int AT91_PIO_SmartMedia_RDY(void) {
+	return (AT91_SYS->PIOC_PDSR & AT91C_PIO_PC2) ? 1 : 0;
+}
+
+static inline int AT91_PIO_SmartMedia_CardDetect(void) {
+	return (AT91_SYS->PIOB_PDSR & AT91C_PIO_PB1) ? 1 : 0;
+}
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/system.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/system.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/system.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,51 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/system.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/arch/hardware.h>
+
+static inline void arch_idle(void)
+{
+	/*
+	 * Disable the processor clock.  The processor will be automatically
+	 * re-enabled by an interrupt or by a reset.
+	 */
+//	AT91_SYS->PMC_SCDR = AT91C_PMC_PCK;
+
+	/*
+	 * Set the processor (CP15) into 'Wait for Interrupt' mode.
+	 * Unlike disabling the processor clock via the PMC (above)
+	 *  this allows the processor to be woken via JTAG.
+	 */
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+	/*
+	 * Perform a hardware reset with the use of the Watchdog timer.
+	 */
+	AT91_SYS->ST_WDMR = AT91C_ST_RSTEN | AT91C_ST_EXTEN | 1 ;
+	AT91_SYS->ST_CR = AT91C_ST_WDRST;
+}
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/time.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/time.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/time.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/time.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,94 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/time.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *  Copyright (C) 2003 ATMEL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_TIME_H
+#define __ASM_ARCH_TIME_H
+
+#include <asm/system.h>
+
+extern unsigned long (*gettimeoffset)(void);
+
+/*
+ * Returns number of microseconds since last timer interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeofday()
+ *  'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
+ *  'tick' is usecs per jiffy (linux/timex.h).
+ */
+static unsigned long at91rm9200_gettimeoffset(void)
+{
+	unsigned long elapsed;
+
+	elapsed = (AT91_SYS->ST_CRTR - AT91_SYS->ST_RTAR) & AT91C_ST_ALMV;
+
+	return (unsigned long)(elapsed * tick) / LATCH;
+}
+
+/*
+ * IRQ handler for the timer.
+ */
+static void at91rm9200_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if (AT91_SYS->ST_SR & AT91C_ST_PITS) {	/* This is a shared interrupt */
+		do {
+			do_timer(regs);
+
+			AT91_SYS->ST_RTAR = (AT91_SYS->ST_RTAR + LATCH) & AT91C_ST_ALMV;
+
+		} while (((AT91_SYS->ST_CRTR - AT91_SYS->ST_RTAR) & AT91C_ST_ALMV) >= LATCH);
+
+		do_profile(regs);
+	}
+}
+
+/*
+ * Set up timer interrupt.
+ */
+static inline void setup_timer(void)
+{
+	/* Disable all timer interrupts */
+	AT91_SYS->ST_IDR = AT91C_ST_PITS | AT91C_ST_WDOVF | AT91C_ST_RTTINC | AT91C_ST_ALMS;
+	(void) AT91_SYS->ST_SR;		/* Clear any pending interrupts */
+
+	/*
+	 * Make IRQs happen for the system timer.
+	 */
+	timer_irq.handler = at91rm9200_timer_interrupt;
+	timer_irq.flags = SA_SHIRQ | SA_INTERRUPT;
+	setup_arm_irq(AT91C_ID_SYS, &timer_irq);
+	gettimeoffset = at91rm9200_gettimeoffset;
+
+	/* Set initial alarm to 0 */
+	AT91_SYS->ST_RTAR = 0;
+
+	/* Real time counter incremented every 30.51758 microseconds */
+	AT91_SYS->ST_RTMR = 1;
+
+	/* Set Period Interval timer */
+	AT91_SYS->ST_PIMR = LATCH;
+
+	/* Change the kernel's 'tick' value to 10009 usec. (the default is 10000) */
+	tick = (LATCH * 1000000) / CLOCK_TICK_RATE;
+
+	/* Enable Period Interval Timer interrupt */
+	AT91_SYS->ST_IER = AT91C_ST_PITS;
+}
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/timex.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/timex.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/timex.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/timex.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,26 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/timex.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#define CLOCK_TICK_RATE		(AT91C_SLOW_CLOCK)
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/uncompress.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/uncompress.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/uncompress.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/uncompress.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,47 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/uncompress.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <asm/arch/hardware.h>
+
+static void puts(const char *s)
+{
+	AT91PS_SYS pSYS = (AT91PS_SYS) AT91C_BASE_SYS;	/* physical address */
+
+	while (*s) {
+		while (!(pSYS->DBGU_CSR & AT91C_DBGU_TXRDY)) { barrier(); }
+		pSYS->DBGU_THR = *s;
+		if (*s == '\n')	{
+			while (!(pSYS->DBGU_CSR & AT91C_DBGU_TXRDY)) { barrier(); }
+			pSYS->DBGU_THR = '\r';
+		}
+		s++;
+	}
+	/* wait for transmission to complete */
+	while (!(pSYS->DBGU_CSR & AT91C_DBGU_TXEMPTY)) { barrier(); }
+}
+
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/vmalloc.h linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/vmalloc.h
--- linux-2.4.22-pre2/include/asm-arm/arch-at91rm9200/vmalloc.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-at91rm9200/vmalloc.h	2003-07-05 18:11:08.000000000 -0700
@@ -0,0 +1,38 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/vmalloc.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+
+#define VMALLOC_OFFSET		(8*1024*1024)
+#define VMALLOC_START		(((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x)	((unsigned long)(x))
+#define VMALLOC_END		(AT91C_IO_VIRT_BASE-1)
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-cl7500/memory.h linux-2.4.22-pre3/include/asm-arm/arch-cl7500/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-cl7500/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-cl7500/memory.h	2003-07-05 18:11:09.000000000 -0700
@@ -46,6 +46,4 @@
 #define __bus_to_virt__is_a_macro
 #define __bus_to_virt(x) __phys_to_virt(x)
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-cl7500/system.h linux-2.4.22-pre3/include/asm-arm/arch-cl7500/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-cl7500/system.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-cl7500/system.h	2003-07-05 18:11:09.000000000 -0700
@@ -8,10 +8,9 @@
 
 #include <asm/hardware/iomd.h>
 
-static void arch_idle(void)
+static inline void arch_idle(void)
 {
-	while (!current->need_resched && !hlt_counter)
-		iomd_writeb(0, IOMD_SUSMODE);
+	iomd_writeb(0, IOMD_SUSMODE);
 }
 
 #define arch_reset(mode)			\
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-clps711x/hardware.h linux-2.4.22-pre3/include/asm-arm/arch-clps711x/hardware.h
--- linux-2.4.22-pre2/include/asm-arm/arch-clps711x/hardware.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-clps711x/hardware.h	2003-07-05 18:11:09.000000000 -0700
@@ -119,6 +119,17 @@
 #define ETHER_SIZE       0x1000
 #define ETHER_BASE       0xfe000000
 
+#if defined (CONFIG_ARCH_GUIDEA07)
+/* persistance flash writing */
+#define GD_A07_PERSISTANCE_START       0x00300000
+#define GD_A07_PERSISTANCE_SIZE        0x00200000
+#define GD_A07_PERSISTANCE_BASE        0xe8300000
+/* Xilinx Spartan II FPGA */
+#define GD_A07_FPGA_START              0x10000000
+#define GD_A07_FPGA_SIZE               0x08000000
+#define GD_A07_FPGA_BASE               0xf0000000
+#endif
+
 #endif
 
 
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-clps711x/memory.h linux-2.4.22-pre3/include/asm-arm/arch-clps711x/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-clps711x/memory.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-clps711x/memory.h	2003-07-05 18:11:09.000000000 -0700
@@ -90,8 +90,6 @@
  * memory bank.  For those systems, simply undefine CONFIG_DISCONTIGMEM.
  */
 
-#ifdef CONFIG_ARCH_EDB7211
-
 #ifdef CONFIG_DISCONTIGMEM
 /*
  * Because of the wide memory address space between physical RAM banks on the 
@@ -120,9 +118,10 @@
 		(((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
 
 /*
- * Given a physical address, convert it to a node id.
+ * Given a page frame number, convert it to a node id.
  */
-#define PHYS_TO_NID(addr) KVADDR_TO_NID(__phys_to_virt(addr))
+#define PFN_TO_NID(pfn) \
+	(((pfn) - PHYS_PFN_OFFSET) >> (NODE_MAX_MEM_SHIFT - PAGE_SHIFT))
 
 /*
  * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
@@ -131,30 +130,15 @@
 #define ADDR_TO_MAPBASE(kaddr) \
 			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
 
+#define PFN_TO_MAPBASE(pfn)	NODE_MEM_MAP(PFN_TO_NID(pfn))
+
 /*
  * Given a kaddr, LOCAL_MAR_NR finds the owning node of the memory
  * and returns the index corresponding to the appropriate page in the
  * node's mem_map.
  */
-#define LOCAL_MAP_NR(kaddr) \
-	(((unsigned long)(kaddr)-LOCAL_BASE_ADDR((kaddr))) >> PAGE_SHIFT)
-
-/*
- * Given a kaddr, virt_to_page returns a pointer to the corresponding 
- * mem_map entry.
- */
-#define virt_to_page(kaddr) \
-	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
-
-/*
- * VALID_PAGE returns a non-zero value if given page pointer is valid.
- * This assumes all node's mem_maps are stored within the node they refer to.
- */
-#define VALID_PAGE(page) \
-({ unsigned int node = KVADDR_TO_NID(page); \
-   ( (node < NR_NODES) && \
-     ((unsigned)((page) - NODE_MEM_MAP(node)) < NODE_DATA(node)->node_size) ); \
-})
+#define LOCAL_MAP_NR(addr) \
+	(((unsigned long)(addr) & (NODE_MAX_MEM_SIZE - 1)) >> PAGE_SHIFT)
 
 /*
  * The PS7211 allows up to 256MB max per DRAM bank, but the EDB7211
@@ -167,40 +151,7 @@
 #define NODE_MAX_MEM_SHIFT	24
 #define NODE_MAX_MEM_SIZE	(1<<NODE_MAX_MEM_SHIFT)
 
-/*
- * Given a mem_map_t, LOCAL_MAP_BASE finds the owning node for the
- * physical page and returns the kaddr for the mem_map of that node.
- */
-#define LOCAL_MAP_BASE(page) \
-			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(page)))
-
-/*
- * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
- * and returns the kaddr corresponding to first physical page in the
- * node's mem_map.
- */
-#define LOCAL_BASE_ADDR(kaddr)	((unsigned long)(kaddr) & ~(NODE_MAX_MEM_SIZE-1))
-
-/* 
- * With discontigmem, the conceptual mem_map array starts from PAGE_OFFSET.
- * Given a kaddr, MAP_NR returns the appropriate global mem_map index so 
- * it matches the corresponding node's local mem_map.
- */
-#define MAP_NR(kaddr)	(LOCAL_MAP_NR((kaddr)) + \
-		(((unsigned long)ADDR_TO_MAPBASE((kaddr)) - PAGE_OFFSET) / \
-		sizeof(mem_map_t)))
-
-#else
-
-#define PHYS_TO_NID(addr)	(0)
-
 #endif /* CONFIG_DISCONTIGMEM */
 
-#endif	/* CONFIG_ARCH_EDB7211 */
-
-#ifndef PHYS_TO_NID
-#define PHYS_TO_NID(addr)	(0)
-#endif
-
 #endif
 
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-ebsa110/memory.h linux-2.4.22-pre3/include/asm-arm/arch-ebsa110/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-ebsa110/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-ebsa110/memory.h	2003-07-05 18:11:09.000000000 -0700
@@ -48,6 +48,4 @@
 #define __bus_to_virt__is_a_macro
 #define __bus_to_virt(x)	(x)
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-ebsa110/system.h linux-2.4.22-pre3/include/asm-arm/arch-ebsa110/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-ebsa110/system.h	2000-09-18 15:15:23.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-ebsa110/system.h	2003-07-05 18:11:09.000000000 -0700
@@ -17,29 +17,22 @@
  * will stop our MCLK signal (which provides the clock for the glue
  * logic, and therefore the timer interrupt).
  *
- * Instead, we spin, waiting for either hlt_counter or need_resched
- * to be set.  If we have been spinning for 2cs, then we drop the
- * core clock down to the memory clock.
+ * Instead, we spin, polling the IRQ_STAT register for the occurrence
+ * of any interrupt with core clock down to the memory clock.
  */
-static void arch_idle(void)
+static inline void arch_idle(void)
 {
-	unsigned long start_idle;
+	const char *irq_stat = (char *)0xff000000;
 
-	start_idle = jiffies;
+	/* disable clock switching */
+	asm volatile ("mcr%? p15, 0, %0, c15, c2, 2" : : "r" (0));
 
-	do {
-		if (current->need_resched || hlt_counter)
-			goto slow_out;
-	} while (time_before(jiffies, start_idle + HZ/50));
+	/* wait for an interrupt to occur */
+	while (!*irq_stat)
+		cpu_relax();
 
-	cpu_do_idle(IDLE_CLOCK_SLOW);
-
-	while (!current->need_resched && !hlt_counter) {
-		/* do nothing slowly */
-	}
-
-	cpu_do_idle(IDLE_CLOCK_FAST);
-slow_out:
+	/* enable clock switching */
+	asm volatile ("mcr%? p15, 0, %0, c15, c1, 2" : : "r" (0));
 }
 
 #define arch_reset(mode)	cpu_reset(0x80000000)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-ebsa110/uncompress.h linux-2.4.22-pre3/include/asm-arm/arch-ebsa110/uncompress.h
--- linux-2.4.22-pre2/include/asm-arm/arch-ebsa110/uncompress.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-ebsa110/uncompress.h	2003-07-05 18:11:09.000000000 -0700
@@ -15,28 +15,28 @@
 {
 	unsigned long tmp1, tmp2;
 
-	__asm__ __volatile__("
-	ldrb	%0, [%2], #1
-	teq	%0, #0
-	beq	3f
-1:	strb	%0, [%3]
-2:	ldrb	%1, [%3, #0x14]
-	and	%1, %1, #0x60
-	teq	%1, #0x60
-	bne	2b
-	teq	%0, #'\n'
-	moveq	%0, #'\r'
-	beq	1b
-	ldrb	%0, [%2], #1
-	teq	%0, #0
-	bne	1b
-3:	ldrb	%1, [%3, #0x14]
-	and	%1, %1, #0x60
-	teq	%1, #0x60
-	bne	3b
+	__asm__ __volatile__("			\n\
+	ldrb	%0, [%2], #1			\n\
+	teq	%0, #0				\n\
+	beq	3f				\n\
+1:	strb	%0, [%3]			\n\
+2:	ldrb	%1, [%3, #0x14]			\n\
+	and	%1, %1, #0x60			\n\
+	teq	%1, #0x60			\n\
+	bne	2b				\n\
+	teq	%0, #'\n'			\n\
+	moveq	%0, #'\r'			\n\
+	beq	1b				\n\
+	ldrb	%0, [%2], #1			\n\
+	teq	%0, #0				\n\
+	bne	1b				\n\
+3:	ldrb	%1, [%3, #0x14]			\n\
+	and	%1, %1, #0x60			\n\
+	teq	%1, #0x60			\n\
+	bne	3b				\n\
 	"
 	 : "=&r" (tmp1), "=&r" (tmp2)
-	 : "0" (0), "1" (0), "r" (s), "r" (0xf0000be0) : "cc");
+	 : "r" (s), "r" (0xf0000be0) : "cc");
 }
 
 /*
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-ebsa285/hardware.h linux-2.4.22-pre3/include/asm-arm/arch-ebsa285/hardware.h
--- linux-2.4.22-pre2/include/asm-arm/arch-ebsa285/hardware.h	2000-11-27 17:07:59.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-ebsa285/hardware.h	2003-07-05 18:11:09.000000000 -0700
@@ -133,7 +133,7 @@
 
 #define pcibios_assign_all_busses()	1
 
-#define PCIBIOS_MIN_IO		0x6000
+#define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM 	0x40000000
 
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-ebsa285/memory.h linux-2.4.22-pre3/include/asm-arm/arch-ebsa285/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-ebsa285/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-ebsa285/memory.h	2003-07-05 18:11:09.000000000 -0700
@@ -80,6 +80,4 @@
 #define __phys_to_virt__is_a_macro
 #define __phys_to_virt(ppage) ((unsigned long)(ppage) + PAGE_OFFSET)
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-ebsa285/system.h linux-2.4.22-pre3/include/asm-arm/arch-ebsa285/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-ebsa285/system.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-ebsa285/system.h	2003-07-05 18:11:09.000000000 -0700
@@ -13,26 +13,9 @@
 #include <asm/leds.h>
 #include <asm/mach-types.h>
 
-static void arch_idle(void)
+static inline void arch_idle(void)
 {
-	unsigned long start_idle;
-
-	start_idle = jiffies;
-
-	do {
-		if (current->need_resched || hlt_counter)
-			goto slow_out;
-		cpu_do_idle(IDLE_WAIT_FAST);
-	} while (time_before(jiffies, start_idle + HZ/50));
-
-	cpu_do_idle(IDLE_CLOCK_SLOW);
-
-	while (!current->need_resched && !hlt_counter) {
-		cpu_do_idle(IDLE_WAIT_SLOW);
-	}
-
-	cpu_do_idle(IDLE_CLOCK_FAST);
-slow_out:
+	cpu_do_idle();
 }
 
 static inline void arch_reset(char mode)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/dma.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/dma.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/dma.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/dma.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,28 @@
+/*
+ *  linux/include/asm-arm/arch-camelot/dma.h
+ *
+ *  Copyright (C) 1997,1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS		0xffffffff
+
+#define MAX_DMA_CHANNELS	0
+
+#endif /* _ASM_ARCH_DMA_H */
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/ether00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/ether00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/ether00.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/ether00.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,482 @@
+#ifndef __ETHER00_H
+#define __ETHER00_H
+
+
+
+/*
+ * Register definitions for the Ethernet MAC
+ */
+
+/*
+ * Copyright (c) Altera Corporation 2000.
+ * All rights reserved.
+ */
+
+/*
+*	Structures for the DMA controller
+*/
+typedef struct fda_desc
+	{
+	struct fda_desc *	FDNext;
+	long				FDSystem;
+	long				FDStat;
+	short				FDLength;
+	short				FDCtl;
+	}FDA_DESC;
+
+typedef struct buf_desc
+	{
+	char *	BuffData;
+	short	BuffLength;
+	char	BDStat;
+	char	BDCtl;
+	}BUF_DESC;
+
+/*
+*	Control masks for the DMA controller
+*/
+#define FDCTL_BDCOUNT_MSK						(0x1F)
+#define FDCTL_BDCOUNT_OFST						(0)
+#define FDCTL_FRMOPT_MSK						(0x7C00)
+#define FDCTL_FRMOPT_OFST						(10)
+#define	FDCTL_COWNSFD_MSK						(0x8000)
+#define	FDCTL_COWNSFD_OFST						(15)
+
+#define BDCTL_RXBDSEQN_MSK						(0x7F)
+#define BDCTL_RXBDSEQN_OFST						(0)
+#define	BDCTL_COWNSBD_MSK						(0x80)
+#define	BDCTL_COWNSBD_OFST						(7)
+
+#define FDNEXT_EOL_MSK							(0x1)
+#define FDNEXT_EOL_OFST							(0)
+#define FDNEXT_EOL_POINTER_MSK					(0xFFFFFFF0)
+#define FDNEXT_EOL_POINTER_OFST					(4)
+
+#define ETHER_ARC_SIZE         (21)
+
+/*
+*	Regsiter definitions and masks
+*/
+#define ETHER_DMA_CTL(base)							(ETHER00_TYPE (base + 0x100))
+#define ETHER_DMA_CTL_DMBURST_OFST				(2)
+#define ETHER_DMA_CTL_DMBURST_MSK				(0x1FC)
+#define ETHER_DMA_CTL_POWRMGMNT_OFST			(11)
+#define ETHER_DMA_CTL_POWRMGMNT_MSK				(0x1000)
+#define ETHER_DMA_CTL_TXBIGE_OFST				(14)
+#define ETHER_DMA_CTL_TXBIGE_MSK				(0x4000)
+#define ETHER_DMA_CTL_RXBIGE_OFST				(15)
+#define ETHER_DMA_CTL_RXBIGE_MSK				(0x8000)
+#define ETHER_DMA_CTL_TXWAKEUP_OFST				(16)
+#define ETHER_DMA_CTL_TXWAKEUP_MSK				(0x10000)
+#define ETHER_DMA_CTL_SWINTREQ_OFST				(17)
+#define ETHER_DMA_CTL_SWINTREQ_MSK				(0x20000)
+#define ETHER_DMA_CTL_INTMASK_OFST				(18)
+#define ETHER_DMA_CTL_INTMASK_MSK				(0x40000)
+#define ETHER_DMA_CTL_M66ENSTAT_OFST			(19)
+#define ETHER_DMA_CTL_M66ENSTAT_MSK				(0x80000)
+#define ETHER_DMA_CTL_RMTXINIT_OFST				(20)
+#define ETHER_DMA_CTL_RMTXINIT_MSK				(0x100000)
+#define ETHER_DMA_CTL_RMRXINIT_OFST				(21)
+#define ETHER_DMA_CTL_RMRXINIT_MSK				(0x200000)
+#define ETHER_DMA_CTL_RXALIGN_OFST				(22)
+#define ETHER_DMA_CTL_RXALIGN_MSK				(0xC00000)
+#define ETHER_DMA_CTL_RMSWRQ_OFST				(24)
+#define ETHER_DMA_CTL_RMSWRQ_MSK				(0x1000000)
+#define ETHER_DMA_CTL_RMEMBANK_OFST				(25)
+#define ETHER_DMA_CTL_RMEMBANK_MSK				(0x2000000)
+
+#define ETHER_TXFRMPTR(base)							(ETHER00_TYPE (base + 0x104))
+
+#define ETHER_TXTHRSH(base)							(ETHER00_TYPE (base + 0x308))
+
+#define ETHER_TXPOLLCTR(base)							(ETHER00_TYPE (base + 0x30c))
+
+#define	ETHER_BLFRMPTR(base)							(ETHER00_TYPE (base + 0x110))
+#define ETHER_BLFFRMPTR_EOL_OFST				(0)
+#define ETHER_BLFFRMPTR_EOL_MSK					(0x1)
+#define ETHER_BLFFRMPTR_ADDRESS_OFST			(4)
+#define ETHER_BLFFRMPTR_ADDRESS_MSK				(0xFFFFFFF0)
+
+#define ETHER_RXFRAGSIZE(base)						(ETHER00_TYPE (base + 0x114))
+#define	ETHER_RXFRAGSIZE_MINFRAG_OFST			(2)
+#define	ETHER_RXFRAGSIZE_MINFRAG_MSK			(0xFFC)
+#define	ETHER_RXFRAGSIZE_ENPACK_OFST			(15)
+#define	ETHER_RXFRAGSIZE_ENPACK_MSK				(0x8000)
+
+#define ETHER_INT_EN(base)							(ETHER00_TYPE (base + 0x118))
+#define ETHER_INT_EN_FDAEXEN_OFST				(0)
+#define ETHER_INT_EN_FDAEXEN_MSK				(0x1)
+#define ETHER_INT_EN_BLEXEN_OFST				(1)
+#define ETHER_INT_EN_BLEXN_MSK					(0x2)
+#define ETHER_INT_EN_STARGABTEN_OFST			(2)
+#define ETHER_INT_EN_STARGABTEN_MSK				(0x4)
+#define ETHER_INT_EN_RTARGABTEN_OFST			(3)
+#define ETHER_INT_EN_RTARGABTEN_MSK				(0x8)
+#define ETHER_INT_EN_RMASABTEN_OFST				(4)
+#define ETHER_INT_EN_RMASABTEN_MSK				(0x10)
+#define ETHER_INT_EN_SSYSERREN_OFST				(5)
+#define ETHER_INT_EN_SSYSERREN_MSK				(0x20)
+#define ETHER_INT_EN_DPARERREN_OFST				(6)
+#define ETHER_INT_EN_DPARERREN_MSK				(0x40)
+#define ETHER_INT_EN_EARNOTEN_OFST				(7)
+#define ETHER_INT_EN_EARNOTEN_MSK				(0x80)
+#define ETHER_INT_EN_DPARDEN_OFST				(8)
+#define ETHER_INT_EN_DPARDEN_MSK				(0x100)
+#define ETHER_INT_EN_DMPARERREN_OFST			(9)
+#define ETHER_INT_EN_DMPARERREN_MSK				(0x200)
+#define ETHER_INT_EN_TXCTLCMPEN_OFST			(10)
+#define ETHER_INT_EN_TXCTLCMPEN_MSK				(0x400)
+#define ETHER_INT_EN_NRABTEN_OFST				(11)
+#define ETHER_INT_EN_NRABTEN_MSK				(0x800)
+
+#define	ETHER_FDA_BAS(base)							(ETHER00_TYPE (base + 0x11C))
+#define ETHER_FDA_BAS_ADDRESS_OFST				(4)
+#define ETHER_FDA_BAS_ADDRESS_MSK				(0xFFFFFFF0)
+
+#define ETHER_FDA_LIM(base)							(ETHER00_TYPE (base + 0x120))
+#define ETHER_FDA_LIM_COUNT_OFST				(4)
+#define ETHER_FDA_LIM_COUNT_MSK					(0xFFF0)
+
+#define ETHER_INT_SRC(base)							(ETHER00_TYPE (base + 0x124))
+#define ETHER_INT_SRC_INTMACTX_OFST				(0)
+#define ETHER_INT_SRC_INTMACTX_MSK				(0x1)
+#define ETHER_INT_SRC_INTMACRX_OFST				(1)
+#define ETHER_INT_SRC_INTMACRX_MSK				(0x2)
+#define ETHER_INT_SRC_INTSBUS_OFST				(2)
+#define ETHER_INT_SRC_INTSBUS_MSK				(0x4)
+#define ETHER_INT_SRC_INTFDAEX_OFST				(3)
+#define ETHER_INT_SRC_INTFDAEX_MSK				(0x8)
+#define ETHER_INT_SRC_INTBLEX_OFST				(4)
+#define ETHER_INT_SRC_INTBLEX_MSK				(0x10)
+#define ETHER_INT_SRC_SWINT_OFST				(5)
+#define ETHER_INT_SRC_SWINT_MSK					(0x20)
+#define ETHER_INT_SRC_INTEARNOT_OFST			(6)
+#define ETHER_INT_SRC_INTEARNOT_MSK				(0x40)
+#define ETHER_INT_SRC_DMPARERR_OFST				(7)
+#define ETHER_INT_SRC_DMPARERR_MSK				(0x80)
+#define ETHER_INT_SRC_INTEXBD_OFST				(8)
+#define ETHER_INT_SRC_INTEXBD_MSK				(0x100)
+#define ETHER_INT_SRC_INTTXCTLCMP_OFST			(9)
+#define ETHER_INT_SRC_INTTXCTLCMP_MSK			(0x200)
+#define ETHER_INT_SRC_INTNRABT_OFST				(10)
+#define ETHER_INT_SRC_INTNRABT_MSK				(0x400)
+#define ETHER_INT_SRC_FDAEX_OFST				(11)
+#define ETHER_INT_SRC_FDAEX_MSK					(0x800)
+#define ETHER_INT_SRC_BLEX_OFST					(12)
+#define ETHER_INT_SRC_BLEX_MSK					(0x1000)
+#define ETHER_INT_SRC_DMPARERRSTAT_OFST			(13)
+#define ETHER_INT_SRC_DMPARERRSTAT_MSK			(0x2000)
+#define ETHER_INT_SRC_NRABT_OFST				(14)
+#define ETHER_INT_SRC_NRABT_MSK					(0x4000)
+#define ETHER_INT_SRC_INTLINK_OFST				(15)
+#define ETHER_INT_SRC_INTLINK_MSK				(0x8000)
+#define ETHER_INT_SRC_INTEXDEFER_OFST			(16)
+#define ETHER_INT_SRC_INTEXDEFER_MSK			(0x10000)
+#define ETHER_INT_SRC_INTRMON_OFST				(17)
+#define ETHER_INT_SRC_INTRMON_MSK				(0x20000)
+#define ETHER_INT_SRC_IRQ_MSK					(0x83FF)
+
+#define ETHER_PAUSECNT(base)							(ETHER00_TYPE (base + 0x40))
+#define ETHER_PAUSECNT_COUNT_OFST				(0)
+#define ETHER_PAUSECNT_COUNT_MSK				(0xFFFF)
+
+#define ETHER_REMPAUCNT(base)							(ETHER00_TYPE (base + 0x44))
+#define ETHER_REMPAUCNT_COUNT_OFST				(0)
+#define ETHER_REMPAUCNT_COUNT_MSK				(0xFFFF)
+
+#define ETHER_TXCONFRMSTAT(base)						(ETHER00_TYPE (base + 0x348))
+#define ETHER_TXCONFRMSTAT_TS_STAT_VALUE_OFST	(0)
+#define ETHER_TXCONFRMSTAT_TS_STAT_VALUE_MSK	(0x3FFFFF)
+
+#define ETHER_MAC_CTL(base)							(ETHER00_TYPE (base + 0))
+#define ETHER_MAC_CTL_HALTREQ_OFST				(0)
+#define ETHER_MAC_CTL_HALTREQ_MSK				(0x1)
+#define ETHER_MAC_CTL_HALTIMM_OFST				(1)
+#define ETHER_MAC_CTL_HALTIMM_MSK				(0x2)
+#define ETHER_MAC_CTL_RESET_OFST				(2)
+#define ETHER_MAC_CTL_RESET_MSK					(0x4)
+#define ETHER_MAC_CTL_FULLDUP_OFST				(3)
+#define ETHER_MAC_CTL_FULLDUP_MSK				(0x8)
+#define ETHER_MAC_CTL_MACLOOP_OFST				(4)
+#define ETHER_MAC_CTL_MACLOOP_MSK				(0x10)
+#define ETHER_MAC_CTL_CONN_OFST					(5)
+#define ETHER_MAC_CTL_CONN_MSK					(0x60)
+#define ETHER_MAC_CTL_LOOP10_OFST				(7)
+#define ETHER_MAC_CTL_LOOP10_MSK				(0x80)
+#define ETHER_MAC_CTL_LNKCHG_OFST				(8)
+#define ETHER_MAC_CTL_LNKCHG_MSK				(0x100)
+#define ETHER_MAC_CTL_MISSROLL_OFST				(10)
+#define ETHER_MAC_CTL_MISSROLL_MSK				(0x400)
+#define ETHER_MAC_CTL_ENMISSROLL_OFST			(13)
+#define ETHER_MAC_CTL_ENMISSROLL_MSK			(0x2000)
+#define ETHER_MAC_CTL_LINK10_OFST				(15)
+#define ETHER_MAC_CTL_LINK10_MSK				(0x8000)
+
+#define ETHER_ARC_CTL(base)							(ETHER00_TYPE (base + 0x4))
+#define	ETHER_ARC_CTL_STATIONACC_OFST			(0)
+#define	ETHER_ARC_CTL_STATIONACC_MSK			(0x1)
+#define	ETHER_ARC_CTL_GROUPACC_OFST				(1)
+#define	ETHER_ARC_CTL_GROUPACC_MSK				(0x2)
+#define	ETHER_ARC_CTL_BROADACC_OFST				(2)
+#define	ETHER_ARC_CTL_BROADACC_MSK				(0x4)
+#define	ETHER_ARC_CTL_NEGARC_OFST				(3)
+#define	ETHER_ARC_CTL_NEGARC_MSK				(0x8)
+#define	ETHER_ARC_CTL_COMPEN_OFST				(4)
+#define	ETHER_ARC_CTL_COMPEN_MSK				(0x10)
+
+#define ETHER_TX_CTL(base)							(ETHER00_TYPE (base + 0x8))
+#define ETHER_TX_CTL_TXEN_OFST					(0)
+#define ETHER_TX_CTL_TXEN_MSK					(0x1)
+#define ETHER_TX_CTL_TXHALT_OFST				(1)
+#define ETHER_TX_CTL_TXHALT_MSK					(0x2)
+#define ETHER_TX_CTL_NOPAD_OFST					(2)
+#define ETHER_TX_CTL_NOPAD_MSK					(0x4)
+#define ETHER_TX_CTL_NOCRC_OFST					(3)
+#define ETHER_TX_CTL_NOCRC_MSK					(0x8)
+#define ETHER_TX_CTL_FBACK_OFST					(4)
+#define ETHER_TX_CTL_FBACK_MSK					(0x10)
+#define ETHER_TX_CTL_NOEXDEF_OFST				(5)
+#define ETHER_TX_CTL_NOEXDEF_MSK				(0x20)
+#define ETHER_TX_CTL_SDPAUSE_OFST				(6)
+#define ETHER_TX_CTL_SDPAUSE_MSK				(0x40)
+#define ETHER_TX_CTL_MII10_OFST					(7)
+#define ETHER_TX_CTL_MII10_MSK					(0x80)
+#define ETHER_TX_CTL_ENUNDER_OFST				(8)
+#define ETHER_TX_CTL_ENUNDER_MSK				(0x100)
+#define ETHER_TX_CTL_ENEXDEFER_OFST				(9)
+#define ETHER_TX_CTL_ENEXDEFER_MSK				(0x200)
+#define ETHER_TX_CTL_ENLCARR_OFST				(10)
+#define ETHER_TX_CTL_ENLCARR_MSK				(0x400)
+#define ETHER_TX_CTL_ENEXCOLL_OFST				(11)
+#define ETHER_TX_CTL_ENEXCOLL_MSK				(0x800)
+#define ETHER_TX_CTL_ENLATECOLL_OFST				(12)
+#define ETHER_TX_CTL_ENLATECOLL_MSK				(0x1000)
+#define ETHER_TX_CTL_ENTXPAR_OFST				(13)
+#define ETHER_TX_CTL_ENTXPAR_MSK				(0x2000)
+#define ETHER_TX_CTL_ENCOMP_OFST				(14)
+#define ETHER_TX_CTL_ENCOMP_MSK					(0x4000)
+
+#define ETHER_TX_STAT(base)							(ETHER00_TYPE (base + 0xc))
+#define ETHER_TX_STAT_TXCOLL_OFST				(0)
+#define ETHER_TX_STAT_TXCOLL_MSK				(0xF)
+#define ETHER_TX_STAT_EXCOLL_OFST				(4)
+#define ETHER_TX_STAT_EXCOLL_MSK				(0x10)
+#define ETHER_TX_STAT_TXDEFER_OFST				(5)
+#define ETHER_TX_STAT_TXDEFER_MSK				(0x20)
+#define ETHER_TX_STAT_PAUSED_OFST				(6)
+#define ETHER_TX_STAT_PAUSED_MSK				(0x40)
+#define ETHER_TX_STAT_INTTX_OFST				(7)
+#define ETHER_TX_STAT_INTTX_MSK					(0x80)
+#define ETHER_TX_STAT_UNDER_OFST				(8)
+#define ETHER_TX_STAT_UNDER_MSK					(0x100)
+#define ETHER_TX_STAT_EXDEFER_OFST				(9)
+#define ETHER_TX_STAT_EXDEFER_MSK				(0x200)
+#define ETHER_TX_STAT_LCARR_OFST				(10)
+#define ETHER_TX_STAT_LCARR_MSK					(0x400)
+#define ETHER_TX_STAT_TX10STAT_OFST				(11)
+#define ETHER_TX_STAT_TX10STAT_MSK				(0x800)
+#define ETHER_TX_STAT_LATECOLL_OFST				(12)
+#define ETHER_TX_STAT_LATECOLL_MSK				(0x1000)
+#define ETHER_TX_STAT_TXPAR_OFST				(13)
+#define ETHER_TX_STAT_TXPAR_MSK					(0x2000)
+#define ETHER_TX_STAT_COMP_OFST					(14)
+#define ETHER_TX_STAT_COMP_MSK					(0x4000)
+#define ETHER_TX_STAT_TXHALTED_OFST				(15)
+#define ETHER_TX_STAT_TXHALTED_MSK				(0x8000)
+#define ETHER_TX_STAT_SQERR_OFST				(16)
+#define ETHER_TX_STAT_SQERR_MSK					(0x10000)
+#define ETHER_TX_STAT_TXMCAST_OFST				(17)
+#define ETHER_TX_STAT_TXMCAST_MSK				(0x20000)
+#define ETHER_TX_STAT_TXBCAST_OFST				(18)
+#define ETHER_TX_STAT_TXBCAST_MSK				(0x40000)
+#define ETHER_TX_STAT_VLAN_OFST					(19)
+#define ETHER_TX_STAT_VLAN_MSK					(0x80000)
+#define ETHER_TX_STAT_MACC_OFST					(20)
+#define ETHER_TX_STAT_MACC_MSK					(0x100000)
+#define ETHER_TX_STAT_TXPAUSE_OFST				(21)
+#define ETHER_TX_STAT_TXPAUSE_MSK				(0x200000)
+
+#define ETHER_RX_CTL(base)							(ETHER00_TYPE (base + 0x10))
+#define ETHER_RX_CTL_RXEN_OFST					(0)
+#define ETHER_RX_CTL_RXEN_MSK					(0x1)
+#define ETHER_RX_CTL_RXHALT_OFST				(1)
+#define ETHER_RX_CTL_RXHALT_MSK					(0x2)
+#define ETHER_RX_CTL_LONGEN_OFST				(2)
+#define ETHER_RX_CTL_LONGEN_MSK					(0x4)
+#define ETHER_RX_CTL_SHORTEN_OFST				(3)
+#define ETHER_RX_CTL_SHORTEN_MSK				(0x8)
+#define ETHER_RX_CTL_STRIPCRC_OFST				(4)
+#define ETHER_RX_CTL_STRIPCRC_MSK				(0x10)
+#define ETHER_RX_CTL_PASSCTL_OFST				(5)
+#define ETHER_RX_CTL_PASSCTL_MSK				(0x20)
+#define ETHER_RX_CTL_IGNORECRC_OFST				(6)
+#define ETHER_RX_CTL_IGNORECRC_MSK				(0x40)
+#define ETHER_RX_CTL_ENALIGN_OFST				(8)
+#define ETHER_RX_CTL_ENALIGN_MSK				(0x100)
+#define ETHER_RX_CTL_ENCRCERR_OFST				(9)
+#define ETHER_RX_CTL_ENCRCERR_MSK				(0x200)
+#define ETHER_RX_CTL_ENOVER_OFST				(10)
+#define ETHER_RX_CTL_ENOVER_MSK					(0x400)
+#define ETHER_RX_CTL_ENLONGERR_OFST				(11)
+#define ETHER_RX_CTL_ENLONGERR_MSK				(0x800)
+#define ETHER_RX_CTL_ENRXPAR_OFST				(13)
+#define ETHER_RX_CTL_ENRXPAR_MSK				(0x2000)
+#define ETHER_RX_CTL_ENGOOD_OFST				(14)
+#define ETHER_RX_CTL_ENGOOD_MSK					(0x4000)
+
+#define ETHER_RX_STAT(base)							(ETHER00_TYPE (base + 0x14))
+#define ETHER_RX_STAT_LENERR_OFST				(4)
+#define ETHER_RX_STAT_LENERR_MSK				(0x10)
+#define ETHER_RX_STAT_CTLRECD_OFST				(5)
+#define ETHER_RX_STAT_CTLRECD_MSK				(0x20)
+#define ETHER_RX_STAT_INTRX_OFST				(6)
+#define ETHER_RX_STAT_INTRX_MSK					(0x40)
+#define ETHER_RX_STAT_RX10STAT_OFST				(7)
+#define ETHER_RX_STAT_RX10STAT_MSK				(0x80)
+#define ETHER_RX_STAT_ALIGNERR_OFST				(8)
+#define ETHER_RX_STAT_ALIGNERR_MSK				(0x100)
+#define ETHER_RX_STAT_CRCERR_OFST				(9)
+#define ETHER_RX_STAT_CRCERR_MSK				(0x200)
+#define ETHER_RX_STAT_OVERFLOW_OFST				(10)
+#define ETHER_RX_STAT_OVERFLOW_MSK				(0x400)
+#define ETHER_RX_STAT_LONGERR_OFST				(11)
+#define ETHER_RX_STAT_LONGERR_MSK				(0x800)
+#define ETHER_RX_STAT_RXPAR_OFST				(13)
+#define ETHER_RX_STAT_RXPAR_MSK					(0x2000)
+#define ETHER_RX_STAT_GOOD_OFST					(14)
+#define ETHER_RX_STAT_GOOD_MSK					(0x4000)
+#define ETHER_RX_STAT_RXHALTED_OFST				(15)
+#define ETHER_RX_STAT_RXHALTED_MSK				(0x8000)
+#define ETHER_RX_STAT_RXMCAST_OFST				(17)
+#define ETHER_RX_STAT_RXMCAST_MSK				(0x10000)
+#define ETHER_RX_STAT_RXBCAST_OFST				(18)
+#define ETHER_RX_STAT_RXBCAST_MSK				(0x20000)
+#define ETHER_RX_STAT_RXVLAN_OFST				(19)
+#define ETHER_RX_STAT_RXVLAN_MSK				(0x40000)
+#define ETHER_RX_STAT_RXPAUSE_OFST				(20)
+#define ETHER_RX_STAT_RXPAUSE_MSK				(0x80000)
+#define ETHER_RX_STAT_ARCSTATUS_OFST				(21)
+#define ETHER_RX_STAT_ARCSTATUS_MSK				(0xF00000)
+#define ETHER_RX_STAT_ARCENT_OFST				(25)
+#define ETHER_RX_STAT_ARCENT_MSK				(0x1F000000)
+
+#define ETHER_MD_DATA(base)							(ETHER00_TYPE (base + 0x18))
+
+#define ETHER_MD_CA(base)								(ETHER00_TYPE (base + 0x1c))
+#define ETHER_MD_CA_ADDR_OFST					(0)
+#define ETHER_MD_CA_ADDR_MSK					(0x1F)
+#define ETHER_MD_CA_PHY_OFST					(5)
+#define ETHER_MD_CA_PHY_MSK					(0x3E0)
+#define ETHER_MD_CA_WR_OFST					(10)
+#define ETHER_MD_CA_WR_MSK					(0x400)
+#define ETHER_MD_CA_BUSY_OFST					(11)
+#define ETHER_MD_CA_BUSY_MSK					(0x800)
+#define ETHER_MD_CA_PRESUPP_OFST				(12)
+#define ETHER_MD_CA_PRESUPP_MSK					(0x1000)
+
+#define ETHER_ARC_ADR(base)	      (ETHER00_TYPE (base + 0x160))
+#define ETHER_ARC_ADR_ARC_LOC_OFST				(2)
+#define ETHER_ARC_ADR_ARC_LOC_MSK				(0xFFC)
+
+#define ETHER_ARC_DATA(base)  (ETHER00_TYPE (base + 0x364))
+
+#define ETHER_ARC_ENA(base)   (ETHER00_TYPE (base + 0x28))
+#define ETHER_ARC_ENA_MSK					(0x1FFFFF)
+
+#define ETHER_PROM_CTL(base)							(ETHER00_TYPE (base + 0x2c))
+#define ETHER_PROM_CTL_PROM_ADDR_OFST			(0)
+#define ETHER_PROM_CTL_PROM_ADDR_MSK			(0x3F)
+#define ETHER_PROM_CTL_OPCODE_OFST				(13)
+#define ETHER_PROM_CTL_OPCODE_MSK				(0x6000)
+#define ETHER_PROM_CTL_OPCODE_READ_MSK			(0x4000)
+#define ETHER_PROM_CTL_OPCODE_WRITE_MSK			(0x2000)
+#define ETHER_PROM_CTL_OPCODE_ERASE_MSK			(0x6000)
+#define ETHER_PROM_CTL_ENABLE_MSK				(0x0030)
+#define ETHER_PROM_CTL_DISABLE_MSK				(0x0000)
+#define ETHER_PROM_CTL_BUSY_OFST				(15)
+#define ETHER_PROM_CTL_BUSY_MSK					(0x8000)
+
+#define ETHER_PROM_DATA(base)							(ETHER00_TYPE (base + 0x30))
+
+#define ETHER_MISS_CNT(base)							(ETHER00_TYPE (base + 0x3c))
+#define ETHER_MISS_CNT_COUNT_OFST				(0)
+#define ETHER_MISS_CNT_COUNT_MSK				(0xFFFF)
+
+#define ETHER_CNTDATA(base)							(ETHER00_TYPE (base + 0x80))
+
+#define ETHER_CNTACC(base)							(ETHER00_TYPE (base + 0x84))
+#define ETHER_CNTACC_ADDR_OFST					(0)
+#define ETHER_CNTACC_ADDR_MSK					(0xFF)
+#define ETHER_CNTACC_WRRDN_OFST					(8)
+#define ETHER_CNTACC_WRRDN_MSK					(0x100)
+#define ETHER_CNTACC_CLEAR_OFST					(9)
+#define ETHER_CNTACC_CLEAR_MSK					(0x200)
+
+#define ETHER_TXRMINTEN(base)							(ETHER00_TYPE (base + 0x88))
+#define ETHER_TXRMINTEN_MSK						(0x3FFFFFFF)
+
+#define ETHER_RXRMINTEN(base)							(ETHER00_TYPE (base + 0x8C))
+#define ETHER_RXRMINTEN_MSK						(0xFFFFFF)
+
+/*
+*	RMON Registers
+*/
+#define		RMON_COLLISION0						0x0
+#define		RMON_COLLISION1						0x1
+#define		RMON_COLLISION2						0x2
+#define		RMON_COLLISION3						0x3
+#define		RMON_COLLISION4						0x4
+#define		RMON_COLLISION5						0x5
+#define		RMON_COLLISION6						0x6
+#define		RMON_COLLISION7						0x7
+#define		RMON_COLLISION8						0x8
+#define		RMON_COLLISION9						0x9
+#define		RMON_COLLISION10					0xa
+#define		RMON_COLLISION11					0xb
+#define		RMON_COLLISION12					0xc
+#define		RMON_COLLISION13					0xd
+#define		RMON_COLLISION14					0xe
+#define		RMON_COLLISION15					0xf
+#define		RMON_COLLISION16					0x10
+#define		RMON_FRAMES_WITH_DEFERRED_XMISSIONS	0x11
+#define		RMON_LATE_COLLISIONS				0x12
+#define		RMON_FRAMES_LOST_DUE_TO_MAC_XMIT	0x13
+#define		RMON_CARRIER_SENSE_ERRORS			0x14
+#define		RMON_FRAMES_WITH_EXCESSIVE_DEFERAL	0x15
+#define		RMON_UNICAST_FRAMES_TRANSMITTED_OK	0x16
+#define		RMON_MULTICAST_FRAMES_XMITTED_OK	0x17
+#define		RMON_BROADCAST_FRAMES_XMITTED_OK	0x18
+#define		RMON_SQE_TEST_ERRORS				0x19
+#define		RMON_PAUSE_MACCTRL_FRAMES_XMITTED	0x1A
+#define		RMON_MACCTRL_FRAMES_XMITTED			0x1B
+#define		RMON_VLAN_FRAMES_XMITTED			0x1C
+#define		RMON_OCTETS_XMITTED_OK				0x1D
+#define		RMON_OCTETS_XMITTED_OK_HI			0x1E
+
+#define		RMON_RX_PACKET_SIZES0				0x40
+#define		RMON_RX_PACKET_SIZES1				0x41
+#define		RMON_RX_PACKET_SIZES2				0x42
+#define		RMON_RX_PACKET_SIZES3				0x43
+#define		RMON_RX_PACKET_SIZES4				0x44
+#define		RMON_RX_PACKET_SIZES5				0x45
+#define		RMON_RX_PACKET_SIZES6				0x46
+#define		RMON_RX_PACKET_SIZES7				0x47
+#define		RMON_FRAME_CHECK_SEQUENCE_ERRORS	0x48
+#define		RMON_ALIGNMENT_ERRORS				0x49
+#define		RMON_FRAGMENTS						0x4A
+#define		RMON_JABBERS						0x4B
+#define		RMON_FRAMES_LOST_TO_INTMACRCVERR	0x4C
+#define		RMON_UNICAST_FRAMES_RCVD_OK			0x4D
+#define		RMON_MULTICAST_FRAMES_RCVD_OK		0x4E
+#define		RMON_BROADCAST_FRAMES_RCVD_OK		0x4F
+#define		RMON_IN_RANGE_LENGTH_ERRORS			0x50
+#define		RMON_OUT_OF_RANGE_LENGTH_ERRORS		0x51
+#define		RMON_VLAN_FRAMES_RCVD				0x52
+#define		RMON_PAUSE_MAC_CTRL_FRAMES_RCVD		0x53
+#define		RMON_MAC_CTRL_FRAMES_RCVD			0x54
+#define		RMON_OCTETS_RCVD_OK					0x55
+#define		RMON_OCTETS_RCVD_OK_HI				0x56
+#define		RMON_OCTETS_RCVD_OTHER				0x57
+#define		RMON_OCTETS_RCVD_OTHER_HI			0x58
+
+#endif /* __ETHER00_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/exc-epxa10dbr2.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/exc-epxa10dbr2.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/exc-epxa10dbr2.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/exc-epxa10dbr2.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,85 @@
+/* megafunction wizard: %ARM-Based Excalibur%
+   GENERATION: STANDARD
+   VERSION: WM1.0
+   MODULE: ARM-Based Excalibur
+   PROJECT: excalibur
+   ============================================================
+   File Name: v:\embedded\linux\bootldr\excalibur.h
+   Megafunction Name(s): ARM-Based Excalibur
+   ============================================================
+
+   ************************************************************
+   THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+   ************************************************************/
+
+#ifndef	EXCALIBUR_H_INCLUDED
+#define	EXCALIBUR_H_INCLUDED
+
+#define EXC_DEFINE_PROCESSOR_LITTLE_ENDIAN
+#define EXC_DEFINE_BOOT_FROM_FLASH
+
+#define	EXC_INPUT_CLK_FREQUENCY (50000000)
+#define	EXC_AHB1_CLK_FREQUENCY (150000000)
+#define	EXC_AHB2_CLK_FREQUENCY (75000000)
+#define	EXC_SDRAM_CLK_FREQUENCY (75000000)
+
+/* Registers Block */
+#define	EXC_REGISTERS_BASE (0x7fffc000)
+#define	EXC_MODE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x000)
+#define	EXC_IO_CTRL00_BASE (EXC_REGISTERS_BASE + 0x040)
+#define	EXC_MMAP00_BASE (EXC_REGISTERS_BASE + 0x080)
+#define	EXC_PLD_CONFIG00_BASE (EXC_REGISTERS_BASE + 0x140)
+#define	EXC_TIMER00_BASE (EXC_REGISTERS_BASE + 0x200)
+#define	EXC_INT_CTRL00_BASE (EXC_REGISTERS_BASE + 0xc00)
+#define	EXC_CLOCK_CTRL00_BASE (EXC_REGISTERS_BASE + 0x300)
+#define	EXC_WATCHDOG00_BASE (EXC_REGISTERS_BASE + 0xa00)
+#define	EXC_UART00_BASE (EXC_REGISTERS_BASE + 0x280)
+#define	EXC_EBI00_BASE (EXC_REGISTERS_BASE + 0x380)
+#define	EXC_SDRAM00_BASE (EXC_REGISTERS_BASE + 0x400)
+#define	EXC_AHB12_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x800)
+#define	EXC_PLD_STRIPE_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
+#define	EXC_STRIPE_PLD_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
+
+#define	EXC_REGISTERS_SIZE (0x00004000)
+
+/* EBI Block(s) */
+#define	EXC_EBI_BLOCK0_BASE (0x40000000)
+#define	EXC_EBI_BLOCK0_SIZE (0x00400000)
+#define	EXC_EBI_BLOCK0_WIDTH (8)
+#define	EXC_EBI_BLOCK0_NON_CACHEABLE
+#define	EXC_EBI_BLOCK1_BASE (0x40400000)
+#define	EXC_EBI_BLOCK1_SIZE (0x00400000)
+#define	EXC_EBI_BLOCK1_WIDTH (16)
+#define	EXC_EBI_BLOCK1_NON_CACHEABLE
+#define	EXC_EBI_BLOCK2_BASE (0x40800000)
+#define	EXC_EBI_BLOCK2_SIZE (0x00400000)
+#define	EXC_EBI_BLOCK2_WIDTH (16)
+#define	EXC_EBI_BLOCK2_NON_CACHEABLE
+#define	EXC_EBI_BLOCK3_BASE (0x40c00000)
+#define	EXC_EBI_BLOCK3_SIZE (0x00400000)
+#define	EXC_EBI_BLOCK3_WIDTH (16)
+#define	EXC_EBI_BLOCK3_NON_CACHEABLE
+
+/* SDRAM Block(s) */
+#define	EXC_SDRAM_BLOCK0_BASE (0x00000000)
+#define	EXC_SDRAM_BLOCK0_SIZE (0x04000000)
+#define	EXC_SDRAM_BLOCK0_WIDTH (32)
+#define	EXC_SDRAM_BLOCK1_BASE (0x04000000)
+#define	EXC_SDRAM_BLOCK1_SIZE (0x04000000)
+#define	EXC_SDRAM_BLOCK1_WIDTH (32)
+
+/* Single Port SRAM Block(s) */
+#define	EXC_SPSRAM_BLOCK0_BASE (0x20000000)
+#define	EXC_SPSRAM_BLOCK0_SIZE (0x00020000)
+#define	EXC_SPSRAM_BLOCK1_BASE (0x20020000)
+#define	EXC_SPSRAM_BLOCK1_SIZE (0x00020000)
+
+/* PLD Block(s) */
+#define	EXC_PLD_BLOCK0_BASE (0x80000000)
+#define	EXC_PLD_BLOCK0_SIZE (0x80000000)
+#define	EXC_PLD_BLOCK0_NON_CACHEABLE
+#define	EXC_PLD_BLOCK1_BASE (0x60000000)
+#define	EXC_PLD_BLOCK1_SIZE (0x10000000)
+#define	EXC_PLD_BLOCK1_NON_CACHEABLE
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/exc-epxa10dbr3.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/exc-epxa10dbr3.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/exc-epxa10dbr3.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/exc-epxa10dbr3.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,90 @@
+/* megafunction wizard: %ARM-Based Excalibur%
+   GENERATION: STANDARD
+   VERSION: WM1.0
+   MODULE: ARM-Based Excalibur
+   PROJECT: excalibur
+   ============================================================
+   File Name: F:\pr_armboot\armboot-1.1.0\board\epxa10db\quartus\excalibur.h
+   Megafunction Name(s): ARM-Based Excalibur
+   ============================================================
+
+   ************************************************************
+   THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+   ************************************************************/
+
+#ifndef	EXCALIBUR_H_INCLUDED
+#define	EXCALIBUR_H_INCLUDED
+
+#define EXC_DEFINE_PROCESSOR_LITTLE_ENDIAN
+#define EXC_DEFINE_BOOT_FROM_FLASH
+
+#define	EXC_INPUT_CLK_FREQUENCY (50000000)
+#define	EXC_AHB1_CLK_FREQUENCY (200000000)
+#define	EXC_AHB2_CLK_FREQUENCY (100000000)
+#define	EXC_SDRAM_CLK_FREQUENCY (125000000)
+
+/* Registers Block */
+#define	EXC_REGISTERS_BASE (0x7fffc000)
+#define	EXC_MODE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x000)
+#define	EXC_IO_CTRL00_BASE (EXC_REGISTERS_BASE + 0x040)
+#define	EXC_MMAP00_BASE (EXC_REGISTERS_BASE + 0x080)
+#define	EXC_PLD_CONFIG00_BASE (EXC_REGISTERS_BASE + 0x140)
+#define	EXC_TIMER00_BASE (EXC_REGISTERS_BASE + 0x200)
+#define	EXC_INT_CTRL00_BASE (EXC_REGISTERS_BASE + 0xc00)
+#define	EXC_CLOCK_CTRL00_BASE (EXC_REGISTERS_BASE + 0x300)
+#define	EXC_WATCHDOG00_BASE (EXC_REGISTERS_BASE + 0xa00)
+#define	EXC_UART00_BASE (EXC_REGISTERS_BASE + 0x280)
+#define	EXC_EBI00_BASE (EXC_REGISTERS_BASE + 0x380)
+#define	EXC_SDRAM00_BASE (EXC_REGISTERS_BASE + 0x400)
+#define	EXC_AHB12_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x800)
+#define	EXC_PLD_STRIPE_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
+#define	EXC_STRIPE_PLD_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
+
+#define	EXC_REGISTERS_SIZE (0x00004000)
+
+/* EBI Block(s) */
+#define	EXC_EBI_BLOCK0_BASE (0x40000000)
+#define	EXC_EBI_BLOCK0_SIZE (0x00800000)
+#define	EXC_EBI_BLOCK0_WIDTH (16)
+#define	EXC_EBI_BLOCK0_NON_CACHEABLE
+#define	EXC_EBI_BLOCK1_BASE (0x40800000)
+#define	EXC_EBI_BLOCK1_SIZE (0x00800000)
+#define	EXC_EBI_BLOCK1_WIDTH (16)
+#define	EXC_EBI_BLOCK1_NON_CACHEABLE
+#define	EXC_EBI_BLOCK2_BASE (0x41000000)
+#define	EXC_EBI_BLOCK2_SIZE (0x00800000)
+#define	EXC_EBI_BLOCK2_WIDTH (16)
+#define	EXC_EBI_BLOCK2_NON_CACHEABLE
+#define	EXC_EBI_BLOCK3_BASE (0x41800000)
+#define	EXC_EBI_BLOCK3_SIZE (0x00800000)
+#define	EXC_EBI_BLOCK3_WIDTH (16)
+#define	EXC_EBI_BLOCK3_NON_CACHEABLE
+
+/* SDRAM Block(s) */
+#define	EXC_SDRAM_BLOCK0_BASE (0x00000000)
+#define	EXC_SDRAM_BLOCK0_SIZE (0x08000000)
+#define	EXC_SDRAM_BLOCK0_WIDTH (32)
+
+/* Single Port SRAM Block(s) */
+#define	EXC_SPSRAM_BLOCK0_BASE (0x20000000)
+#define	EXC_SPSRAM_BLOCK0_SIZE (0x00020000)
+#define	EXC_SPSRAM_BLOCK1_BASE (0x20020000)
+#define	EXC_SPSRAM_BLOCK1_SIZE (0x00020000)
+
+/* Dual Port SRAM Block(s) */
+#define	EXC_DPSRAM_BLOCK0_BASE (0x20040000)
+#define	EXC_DPSRAM_BLOCK0_SIZE (0x00010000)
+#define	EXC_DPSRAM_BLOCK0_WIDTH (0)
+#define	EXC_DPSRAM_BLOCK1_BASE (0x20200000)
+#define	EXC_DPSRAM_BLOCK1_SIZE (0x00010000)
+#define	EXC_DPSRAM_BLOCK1_WIDTH (0)
+
+/* PLD Block(s) */
+#define	EXC_PLD_BLOCK0_BASE (0x80000000)
+#define	EXC_PLD_BLOCK0_SIZE (0x80000000)
+#define	EXC_PLD_BLOCK0_CACHEABLE
+#define	EXC_PLD_BLOCK1_BASE (0x60000000)
+#define	EXC_PLD_BLOCK1_SIZE (0x10000000)
+#define	EXC_PLD_BLOCK1_NON_CACHEABLE
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/exc-epxa1db.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/exc-epxa1db.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/exc-epxa1db.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/exc-epxa1db.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,83 @@
+/* megafunction wizard: %ARM-Based Excalibur%
+   GENERATION: STANDARD
+   VERSION: WM1.0
+   MODULE: ARM-Based Excalibur
+   PROJECT: excalibur
+   ============================================================
+   File Name: D:\tmp\quartus\excalibur.h
+   Megafunction Name(s): ARM-Based Excalibur
+   ============================================================
+
+   ************************************************************
+   THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+   ************************************************************/
+
+#ifndef	EXCALIBUR_H_INCLUDED
+#define	EXCALIBUR_H_INCLUDED
+
+#define EXC_DEFINE_PROCESSOR_LITTLE_ENDIAN
+#define EXC_DEFINE_BOOT_FROM_FLASH
+
+#define	EXC_INPUT_CLK_FREQUENCY (25000000)
+#define	EXC_AHB1_CLK_FREQUENCY (200000000)
+#define	EXC_AHB2_CLK_FREQUENCY (100000000)
+#define	EXC_SDRAM_CLK_FREQUENCY (35341652)
+
+/* Registers Block */
+#define	EXC_REGISTERS_BASE (0x7fffc000)
+#define	EXC_MODE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x000)
+#define	EXC_IO_CTRL00_BASE (EXC_REGISTERS_BASE + 0x040)
+#define	EXC_MMAP00_BASE (EXC_REGISTERS_BASE + 0x080)
+#define	EXC_PLD_CONFIG00_BASE (EXC_REGISTERS_BASE + 0x140)
+#define	EXC_TIMER00_BASE (EXC_REGISTERS_BASE + 0x200)
+#define	EXC_INT_CTRL00_BASE (EXC_REGISTERS_BASE + 0xc00)
+#define	EXC_CLOCK_CTRL00_BASE (EXC_REGISTERS_BASE + 0x300)
+#define	EXC_WATCHDOG00_BASE (EXC_REGISTERS_BASE + 0xa00)
+#define	EXC_UART00_BASE (EXC_REGISTERS_BASE + 0x280)
+#define	EXC_EBI00_BASE (EXC_REGISTERS_BASE + 0x380)
+#define	EXC_SDRAM00_BASE (EXC_REGISTERS_BASE + 0x400)
+#define	EXC_AHB12_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x800)
+#define	EXC_PLD_STRIPE_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
+#define	EXC_STRIPE_PLD_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
+
+#define	EXC_REGISTERS_SIZE (0x00004000)
+
+/* EBI Block(s) */
+#define	EXC_EBI_BLOCK0_BASE (0x40000000)
+#define	EXC_EBI_BLOCK0_SIZE (0x00400000)
+#define	EXC_EBI_BLOCK0_WIDTH (16)
+#define	EXC_EBI_BLOCK0_NON_CACHEABLE
+#define	EXC_EBI_BLOCK1_BASE (0x40400000)
+#define	EXC_EBI_BLOCK1_SIZE (0x00400000)
+#define	EXC_EBI_BLOCK1_WIDTH (16)
+#define	EXC_EBI_BLOCK1_NON_CACHEABLE
+#define	EXC_EBI_BLOCK3_BASE (0x40c00000)
+#define	EXC_EBI_BLOCK3_SIZE (0x00400000)
+#define	EXC_EBI_BLOCK3_WIDTH (16)
+#define	EXC_EBI_BLOCK3_NON_CACHEABLE
+
+/* SDRAM Block(s) */
+#define	EXC_SDRAM_BLOCK0_BASE (0x00000000)
+#define	EXC_SDRAM_BLOCK0_SIZE (0x02000000)
+#define	EXC_SDRAM_BLOCK0_WIDTH (16)
+
+/* Single Port SRAM Block(s) */
+#define	EXC_SPSRAM_BLOCK0_BASE (0x20000000)
+#define	EXC_SPSRAM_BLOCK0_SIZE (0x00004000)
+#define	EXC_SPSRAM_BLOCK1_BASE (0x20020000)
+#define	EXC_SPSRAM_BLOCK1_SIZE (0x00004000)
+
+/* Dual Port SRAM Block(s) */
+#define	EXC_DPSRAM_BLOCK0_BASE (0x20040000)
+#define	EXC_DPSRAM_BLOCK0_SIZE (0x00004000)
+#define	EXC_DPSRAM_BLOCK0_WIDTH (0)
+
+/* PLD Block(s) */
+#define	EXC_PLD_BLOCK0_BASE (0x80000000)
+#define	EXC_PLD_BLOCK0_SIZE (0x80000000)
+#define	EXC_PLD_BLOCK0_NON_CACHEABLE
+#define	EXC_PLD_BLOCK1_BASE (0x60000000)
+#define	EXC_PLD_BLOCK1_SIZE (0x10000000)
+#define	EXC_PLD_BLOCK1_NON_CACHEABLE
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/excalibur.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/excalibur.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/excalibur.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/excalibur.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,10 @@
+#include <linux/config.h>
+#ifdef CONFIG_EPXA10DB_R2
+#include "exc-epxa10dbr2.h"
+#elif defined CONFIG_EPXA10DB_R3
+#include "exc-epxa10dbr3.h"
+#elif defined CONFIG_EPXA1DB
+#include "exc-epxa1db.h"
+#else
+#error "must select an EPXA development board"
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/hardware.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/hardware.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/hardware.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/hardware.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,68 @@
+/*
+ *  linux/include/asm-arm/arch-epxa10/hardware.h
+ *
+ *  This file contains the hardware definitions of the Integrator.
+ *
+ *  Copyright (C) 1999 ARM Limited.
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/arch/platform.h>
+
+/*
+ * Where in virtual memory the IO devices (timers, system controllers
+ * and so on)
+ */
+#define IO_BASE			0xf0000000                 // VA of IO 
+#define IO_SIZE			0x10000000                 // How much?
+#define IO_START		EXC_REGISTERS_BASE              // PA of IO
+/* macro to get at IO space when running virtually */
+#define IO_ADDRESS(x) ((x) | 0xf0000000) 
+
+#define FLASH_VBASE             0xFE000000
+#ifdef  CONFIG_EPXA10DB
+#define FLASH_SIZE              0x01000000
+#else
+#define FLASH_SIZE              0x00800000
+#endif
+#define FLASH_START             EXC_EBI_BLOCK0_BASE
+#define FLASH_VADDR(x) ((x)|0xFE000000)
+/*
+ * Similar to above, but for PCI addresses (memory, IO, Config and the
+ * V3 chip itself).  WARNING: this has to mirror definitions in platform.h
+ */
+#if 0
+#define PCI_MEMORY_VADDR        0xe8000000
+#define PCI_CONFIG_VADDR        0xec000000
+#define PCI_V3_VADDR            0xed000000
+#define PCI_IO_VADDR            0xee000000
+
+#define PCIO_BASE		PCI_IO_VADDR
+#define PCIMEM_BASE		PCI_MEMORY_VADDR
+
+
+#define pcibios_assign_all_busses()	1
+
+#define PCIBIOS_MIN_IO		0x6000
+#define PCIBIOS_MIN_MEM 	0x00100000
+#endif
+
+
+#endif
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/int_ctrl00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/int_ctrl00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/int_ctrl00.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/int_ctrl00.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,288 @@
+/*
+ *  
+ *  This file contains the register definitions for the Excalibur
+ *  Timer TIMER00.
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __INT_CTRL00_H
+#define __INT_CTRL00_H
+
+#define INT_MS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x00 ))
+#define INT_MS_FC_MSK (0x10000)
+#define INT_MS_FC_OFST (16)
+#define INT_MS_M1_MSK (0x8000)
+#define INT_MS_M1_OFST (15)
+#define INT_MS_M0_MSK (0x4000)
+#define INT_MS_M0_OFST (14)
+#define INT_MS_AE_MSK (0x2000)
+#define INT_MS_AE_OFST (13)
+#define INT_MS_PE_MSK (0x1000)
+#define INT_MS_PE_OFST (12)
+#define INT_MS_EE_MSK (0x0800)
+#define INT_MS_EE_OFST (11)
+#define INT_MS_PS_MSK (0x0400)
+#define INT_MS_PS_OFST (10)
+#define INT_MS_T1_MSK (0x0200)
+#define INT_MS_T1_OFST (9)
+#define INT_MS_T0_MSK (0x0100)
+#define INT_MS_T0_OFST (8)
+#define INT_MS_UA_MSK (0x0080)
+#define INT_MS_UA_OFST (7)
+#define INT_MS_IP_MSK (0x0040)
+#define INT_MS_IP_OFST (6)
+#define INT_MS_P5_MSK (0x0020)
+#define INT_MS_P5_OFST (5)
+#define INT_MS_P4_MSK (0x0010)
+#define INT_MS_P4_OFST (4)
+#define INT_MS_P3_MSK (0x0008)
+#define INT_MS_P3_OFST (3)
+#define INT_MS_P2_MSK (0x0004)
+#define INT_MS_P2_OFST (2)
+#define INT_MS_P1_MSK (0x0002)
+#define INT_MS_P1_OFST (1)
+#define INT_MS_P0_MSK (0x0001)
+#define INT_MS_P0_OFST (0)
+
+#define INT_MC(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x04 ))
+#define INT_MC_FC_MSK (0x10000)
+#define INT_MC_FC_OFST (16)
+#define INT_MC_M1_MSK (0x8000)
+#define INT_MC_M1_OFST (15)
+#define INT_MC_M0_MSK (0x4000)
+#define INT_MC_M0_OFST (14)
+#define INT_MC_AE_MSK (0x2000)
+#define INT_MC_AE_OFST (13)
+#define INT_MC_PE_MSK (0x1000)
+#define INT_MC_PE_OFST (12)
+#define INT_MC_EE_MSK (0x0800)
+#define INT_MC_EE_OFST (11)
+#define INT_MC_PS_MSK (0x0400)
+#define INT_MC_PS_OFST (10)
+#define INT_MC_T1_MSK (0x0200)
+#define INT_MC_T1_OFST (9)
+#define INT_MC_T0_MSK (0x0100)
+#define INT_MC_T0_OFST (8)
+#define INT_MC_UA_MSK (0x0080)
+#define INT_MC_UA_OFST (7)
+#define INT_MC_IP_MSK (0x0040)
+#define INT_MC_IP_OFST (6)
+#define INT_MC_P5_MSK (0x0020)
+#define INT_MC_P5_OFST (5)
+#define INT_MC_P4_MSK (0x0010)
+#define INT_MC_P4_OFST (4)
+#define INT_MC_P3_MSK (0x0008)
+#define INT_MC_P3_OFST (3)
+#define INT_MC_P2_MSK (0x0004)
+#define INT_MC_P2_OFST (2)
+#define INT_MC_P1_MSK (0x0002)
+#define INT_MC_P1_OFST (1)
+#define INT_MC_P0_MSK (0x0001)
+#define INT_MC_P0_OFST (0)
+
+#define INT_SS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x08 ))
+#define INT_SS_FC_SSK (0x8000)
+#define INT_SS_FC_OFST (15)
+#define INT_SS_M1_SSK (0x8000)
+#define INT_SS_M1_OFST (15)
+#define INT_SS_M0_SSK (0x4000)
+#define INT_SS_M0_OFST (14)
+#define INT_SS_AE_SSK (0x2000)
+#define INT_SS_AE_OFST (13)
+#define INT_SS_PE_SSK (0x1000)
+#define INT_SS_PE_OFST (12)
+#define INT_SS_EE_SSK (0x0800)
+#define INT_SS_EE_OFST (11)
+#define INT_SS_PS_SSK (0x0400)
+#define INT_SS_PS_OFST (10)
+#define INT_SS_T1_SSK (0x0200)
+#define INT_SS_T1_OFST (9)
+#define INT_SS_T0_SSK (0x0100)
+#define INT_SS_T0_OFST (8)
+#define INT_SS_UA_SSK (0x0080)
+#define INT_SS_UA_OFST (7)
+#define INT_SS_IP_SSK (0x0040)
+#define INT_SS_IP_OFST (6)
+#define INT_SS_P5_SSK (0x0020)
+#define INT_SS_P5_OFST (5)
+#define INT_SS_P4_SSK (0x0010)
+#define INT_SS_P4_OFST (4)
+#define INT_SS_P3_SSK (0x0008)
+#define INT_SS_P3_OFST (3)
+#define INT_SS_P2_SSK (0x0004)
+#define INT_SS_P2_OFST (2)
+#define INT_SS_P1_SSK (0x0002)
+#define INT_SS_P1_OFST (1)
+#define INT_SS_P0_SSK (0x0001)
+#define INT_SS_P0_OFST (0)
+
+#define INT_RS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x0C ))
+#define INT_RS_FC_RSK (0x10000)
+#define INT_RS_FC_OFST (16)
+#define INT_RS_M1_RSK (0x8000)
+#define INT_RS_M1_OFST (15)
+#define INT_RS_M0_RSK (0x4000)
+#define INT_RS_M0_OFST (14)
+#define INT_RS_AE_RSK (0x2000)
+#define INT_RS_AE_OFST (13)
+#define INT_RS_PE_RSK (0x1000)
+#define INT_RS_PE_OFST (12)
+#define INT_RS_EE_RSK (0x0800)
+#define INT_RS_EE_OFST (11)
+#define INT_RS_PS_RSK (0x0400)
+#define INT_RS_PS_OFST (10)
+#define INT_RS_T1_RSK (0x0200)
+#define INT_RS_T1_OFST (9)
+#define INT_RS_T0_RSK (0x0100)
+#define INT_RS_T0_OFST (8)
+#define INT_RS_UA_RSK (0x0080)
+#define INT_RS_UA_OFST (7)
+#define INT_RS_IP_RSK (0x0040)
+#define INT_RS_IP_OFST (6)
+#define INT_RS_P5_RSK (0x0020)
+#define INT_RS_P5_OFST (5)
+#define INT_RS_P4_RSK (0x0010)
+#define INT_RS_P4_OFST (4)
+#define INT_RS_P3_RSK (0x0008)
+#define INT_RS_P3_OFST (3)
+#define INT_RS_P2_RSK (0x0004)
+#define INT_RS_P2_OFST (2)
+#define INT_RS_P1_RSK (0x0002)
+#define INT_RS_P1_OFST (1)
+#define INT_RS_P0_RSK (0x0001)
+#define INT_RS_P0_OFST (0)
+
+#define INT_ID(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x10 ))
+#define INT_ID_ID_MSK (0x3F)
+#define INT_ID_ID_OFST (0)
+
+#define INT_PLD_PRIORITY(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x14 ))
+#define INT_PLD_PRIORITY_PRI_MSK (0x3F)
+#define INT_PLD_PRIORITY_PRI_OFST (0)
+#define INT_PLD_PRIORITY_GA_MSK (0x40)
+#define INT_PLD_PRIORITY_GA_OFST (6)
+
+#define INT_MODE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x18 ))
+#define INT_MODE_MODE_MSK (0x3)
+#define INT_MODE_MODE_OFST (0)
+
+#define INT_PRIORITY_P0(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x80 ))
+#define INT_PRIORITY_P0_PRI_MSK (0x3F)
+#define INT_PRIORITY_P0_PRI_OFST (0)
+#define INT_PRIORITY_P0_FQ_MSK (0x40)
+#define INT_PRIORITY_P0_FQ_OFST (6)
+
+#define INT_PRIORITY_P1(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x84 ))
+#define INT_PRIORITY_P1_PRI_MSK (0x3F)
+#define INT_PRIORITY_P1_PRI_OFST (0)
+#define INT_PRIORITY_P1_FQ_MSK (0x40)
+#define INT_PRIORITY_P1_FQ_OFST (6)
+
+#define INT_PRIORITY_P2(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x88 ))
+#define INT_PRIORITY_P2_PRI_MSK (0x3F)
+#define INT_PRIORITY_P2_PRI_OFST (0)
+#define INT_PRIORITY_P2_FQ_MSK (0x40)
+#define INT_PRIORITY_P2_FQ_OFST (6)
+
+#define INT_PRIORITY_P3(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x8C ))
+#define INT_PRIORITY_P3_PRI_MSK (0x3F)
+#define INT_PRIORITY_P3_PRI_OFST (0)
+#define INT_PRIORITY_P3_FQ_MSK (0x40)
+#define INT_PRIORITY_P3_FQ_OFST (6)
+
+#define INT_PRIORITY_P4(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x90 ))
+#define INT_PRIORITY_P4_PRI_MSK (0x3F)
+#define INT_PRIORITY_P4_PRI_OFST (0)
+#define INT_PRIORITY_P4_FQ_MSK (0x40)
+#define INT_PRIORITY_P4_FQ_OFST (6)
+
+#define INT_PRIORITY_P5(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x94 ))
+#define INT_PRIORITY_P5_PRI_MSK (0x3F)
+#define INT_PRIORITY_P5_PRI_OFST (0)
+#define INT_PRIORITY_P5_FQ_MSK (0x40)
+#define INT_PRIORITY_P5_FQ_OFST (6)
+
+#define INT_PRIORITY_IP(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x94 ))
+#define INT_PRIORITY_IP_PRI_MSK (0x3F)
+#define INT_PRIORITY_IP_PRI_OFST (0)
+#define INT_PRIORITY_IP_FQ_MSK (0x40)
+#define INT_PRIORITY_IP_FQ_OFST (6)
+
+#define INT_PRIORITY_UA(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x9C ))
+#define INT_PRIORITY_UA_PRI_MSK (0x3F)
+#define INT_PRIORITY_UA_PRI_OFST (0)
+#define INT_PRIORITY_UA_FQ_MSK (0x40)
+#define INT_PRIORITY_UA_FQ_OFST (6)
+
+#define INT_PRIORITY_T0(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xA0 ))
+#define INT_PRIORITY_T0_PRI_MSK (0x3F)
+#define INT_PRIORITY_T0_PRI_OFST (0)
+#define INT_PRIORITY_T0_FQ_MSK (0x40)
+#define INT_PRIORITY_T0_FQ_OFST (6)
+
+#define INT_PRIORITY_T1(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xA4 ))
+#define INT_PRIORITY_T1_PRI_MSK (0x3F)
+#define INT_PRIORITY_T1_PRI_OFST (0)
+#define INT_PRIORITY_T1_FQ_MSK (0x40)
+#define INT_PRIORITY_T1_FQ_OFST (6)
+
+#define INT_PRIORITY_PS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xA8 ))
+#define INT_PRIORITY_PS_PRI_MSK (0x3F)
+#define INT_PRIORITY_PS_PRI_OFST (0)
+#define INT_PRIORITY_PS_FQ_MSK (0x40)
+#define INT_PRIORITY_PS_FQ_OFST (6)
+
+#define INT_PRIORITY_EE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xAC ))
+#define INT_PRIORITY_EE_PRI_MSK (0x3F)
+#define INT_PRIORITY_EE_PRI_OFST (0)
+#define INT_PRIORITY_EE_FQ_MSK (0x40)
+#define INT_PRIORITY_EE_FQ_OFST (6)
+
+#define INT_PRIORITY_PE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xB0 ))
+#define INT_PRIORITY_PE_PRI_MSK (0x3F)
+#define INT_PRIORITY_PE_PRI_OFST (0)
+#define INT_PRIORITY_PE_FQ_MSK (0x40)
+#define INT_PRIORITY_PE_FQ_OFST (6)
+
+#define INT_PRIORITY_AE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xB4 ))
+#define INT_PRIORITY_AE_PRI_MSK (0x3F)
+#define INT_PRIORITY_AE_PRI_OFST (0)
+#define INT_PRIORITY_AE_FQ_MSK (0x40)
+#define INT_PRIORITY_AE_FQ_OFST (6)
+
+#define INT_PRIORITY_M0(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xB8 ))
+#define INT_PRIORITY_M0_PRI_MSK (0x3F)
+#define INT_PRIORITY_M0_PRI_OFST (0)
+#define INT_PRIORITY_M0_FQ_MSK (0x40)
+#define INT_PRIORITY_M0_FQ_OFST (6)
+
+#define INT_PRIORITY_M1(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xBC ))
+#define INT_PRIORITY_M1_PRI_MSK (0x3F)
+#define INT_PRIORITY_M1_PRI_OFST (0)
+#define INT_PRIORITY_M1_FQ_MSK (0x40)
+#define INT_PRIORITY_M1_FQ_OFST (6)
+
+#define INT_PRIORITY_FC(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xC0 ))
+#define INT_PRIORITY_FC_PRI_MSK (0x3F)
+#define INT_PRIORITY_FC_PRI_OFST (0)
+#define INT_PRIORITY_FC_FQ_MSK (0x40)
+#define INT_PRIORITY_FC_FQ_OFST (6)
+
+#endif /* __INT_CTRL00_H */
+
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/io.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/io.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/io.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/io.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,46 @@
+/*
+ *  linux/include/asm-arm/arch-epxa10db/io.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffff
+
+
+/*
+ * Generic virtual read/write
+ */
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
+/*#define outsw   __arch_writesw
+#define outsl   __arch_writesl
+#define outsb   __arch_writesb
+#define insb    __arch_readsb
+#define insw    __arch_readsw
+#define insl    __arch_readsl*/
+
+#define __io(a)			(a)
+#define __mem_pci(a)            (a) 
+#define __arch_getw(a)			(*(volatile unsigned short  *)(a))
+#define __arch_putw(v,a)		(*(volatile unsigned short *)(a) = (v))
+#define iomem_valid_addr(off,size) (1)
+#define iomem_to_phys(off) (off)
+
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/irq.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/irq.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/irq.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/irq.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,20 @@
+/*
+ *  linux/include/asm-arm/arch-epxa10/irq.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#define fixup_irq(i)	(i)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/irqs.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/irqs.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/irqs.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/irqs.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,45 @@
+/*
+ *  linux/include/asm-arm/arch-camelot/irqs.h
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* Use the Excalibur chip definitions */
+#define INT_CTRL00_TYPE
+#include "asm/arch/int_ctrl00.h"
+
+
+#define IRQ_PLD0                     INT_MS_P0_OFST
+#define IRQ_PLD1                     INT_MS_P1_OFST
+#define IRQ_PLD2                     INT_MS_P2_OFST
+#define IRQ_PLD3                     INT_MS_P3_OFST
+#define IRQ_PLD4                     INT_MS_P4_OFST
+#define IRQ_PLD5                     INT_MS_P5_OFST
+#define IRQ_EXT                      INT_MS_IP_OFST
+#define IRQ_UART                     INT_MS_UA_OFST
+#define IRQ_TIMER0                   INT_MS_T0_OFST
+#define IRQ_TIMER1                   INT_MS_T1_OFST
+#define IRQ_PLL                      INT_MS_PLL_OFST
+#define IRQ_EBI                      INT_MS_EBI_OFST
+#define IRQ_STRIPE_BRIDGE            INT_MS_PLL_OFST
+#define IRQ_AHB_BRIDGE               INT_MS_PLL_OFST
+#define IRQ_COMMRX                   INT_MS_CR_OFST
+#define IRQ_COMMTX                   INT_MS_CT_OFST
+#define IRQ_FAST_COMM                INT_MS_FC_OFST
+
+#define NR_IRQS                         (INT_MS_FC_OFST + 1)
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/memory.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/memory.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/memory.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,61 @@
+/*
+ *  linux/include/asm-arm/arch-epxa10/memory.h
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE	(0xc0000000UL)
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET	(0xc0000000UL)
+#define PHYS_OFFSET	(0x00000000UL)
+
+/*
+ * On epxa10, the dram is contiguous
+ */
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *              address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *              to an address that the kernel can use.
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)	(x - PAGE_OFFSET + /*SDRAM_BASE*/0)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)	(x - /*SDRAM_BASE*/0 + PAGE_OFFSET)
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/mode_ctrl00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/mode_ctrl00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/mode_ctrl00.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/mode_ctrl00.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,80 @@
+#ifndef __MODE_CTRL00_H
+#define __MODE_CTRL00_H
+
+/*
+ * Register definitions for the reset and mode control
+ */
+
+/*
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+
+#define BOOT_CR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  ))
+#define BOOT_CR_BF_MSK (0x1)
+#define BOOT_CR_BF_OFST (0)
+#define BOOT_CR_HM_MSK (0x2)
+#define BOOT_CR_HM_OFST (1)
+#define BOOT_CR_RE_MSK (0x4)
+#define BOOT_CR_RE_OFST (2)
+
+#define RESET_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x4 ))
+#define RESET_SR_WR_MSK (0x1)
+#define RESET_SR_WR_OFST (0)
+#define RESET_SR_CR_MSK (0x2)
+#define RESET_SR_CR_OFST (1)
+#define RESET_SR_JT_MSK (0x4)
+#define RESET_SR_JT_OFST (2)
+#define RESET_SR_ER_MSK (0x8)
+#define RESET_SR_ER_OFST (3)
+
+#define ID_CODE(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x08 ))
+
+#define SRAM0_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x20 ))
+#define SRAM0_SR_SIZE_MSK (0xFFFFF000)
+#define SRAM0_SR_SIZE_OFST (12)
+
+#define SRAM1_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x24 ))
+#define SRAM1_SR_SIZE_MSK (0xFFFFF000)
+#define SRAM1_SR_SIZE_OFST (12)
+
+#define DPSRAM0_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x30 ))
+
+#define DPSRAM0_SR_MODE_MSK (0xF)
+#define DPSRAM0_SR_MODE_OFST (0)
+#define DPSRAM0_SR_GLBL_MSK (0x30)
+#define DPSRAM0_SR_SIZE_MSK (0xFFFFF000)
+#define DPSRAM0_SR_SIZE_OFST (12)
+
+#define DPSRAM0_LCR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x34 ))
+#define DPSRAM0_LCR_LCKADDR_MSK (0x1FFE0)
+#define DPSRAM0_LCR_LCKADDR_OFST (4)
+
+#define DPSRAM1_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x38 ))
+#define DPSRAM1_SR_MODE_MSK (0xF)
+#define DPSRAM1_SR_MODE_OFST (0)
+#define DPSRAM1_SR_GLBL_MSK (0x30)
+#define DPSRAM1_SR_GLBL_OFST (4)
+#define DPSRAM1_SR_SIZE_MSK (0xFFFFF000)
+#define DPSRAM1_SR_SIZE_OFST (12)
+
+#define DPSRAM1_LCR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x3C ))
+#define DPSRAM1_LCR_LCKADDR_MSK (0x1FFE0)
+#define DPSRAM1_LCR_LCKADDR_OFST (4)
+
+#endif /* __MODE_CTRL00_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/param.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/param.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/param.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/param.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,21 @@
+/*
+ *  linux/include/asm-arm/arch-epxa10db/param.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define HZ 100
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/platform.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/platform.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/platform.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/platform.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,7 @@
+#ifndef PLATFORM_H
+#define PLATFORM_H
+#include "excalibur.h"
+
+#define MAXIRQNUM 15 
+#endif
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/pld_conf00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/pld_conf00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/pld_conf00.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/pld_conf00.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,73 @@
+#ifndef __PLD_CONF00_H
+#define __PLD_CONF00_H
+
+/*
+ * Register definitions for the PLD Configuration Logic
+ */
+
+/*
+ *  
+ *  This file contains the register definitions for the Excalibur
+ *  Interrupnt controller INT_CTRL00.
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+ 
+#define CONFIG_CONTROL(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR))  
+#define CONFIG_CONTROL_LK_MSK (0x1)
+#define CONFIG_CONTROL_LK_OFST (0)
+#define CONFIG_CONTROL_CO_MSK (0x2)
+#define CONFIG_CONTROL_CO_OFST (1)
+#define CONFIG_CONTROL_B_MSK  (0x4)
+#define CONFIG_CONTROL_B_OFST (2)
+#define CONFIG_CONTROL_PC_MSK (0x8)
+#define CONFIG_CONTROL_PC_OFST (3)
+#define CONFIG_CONTROL_E_MSK (0x10)
+#define CONFIG_CONTROL_E_OFST (4)
+#define CONFIG_CONTROL_ES_MSK (0xE0)
+#define CONFIG_CONTROL_ES_OFST (5)
+#define CONFIG_CONTROL_ES_0_MSK (0x20)
+#define CONFIG_CONTROL_ES_1_MSK (0x40)
+#define CONFIG_CONTROL_ES_2_MSK (0x80)
+
+#define CONFIG_CONTROL_CLOCK(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR  + 0x4 ))
+#define CONFIG_CONTROL_CLOCK_RATIO_MSK (0xFFFF)
+#define CONFIG_CONTROL_CLOCK_RATIO_OFST (0)
+
+#define CONFIG_CONTROL_DATA(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR  + 0x8 ))
+#define CONFIG_CONTROL_DATA_MSK (0xFFFFFFFF)
+#define CONFIG_CONTROL_DATA_OFST (0)
+
+#define CONFIG_UNLOCK(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR  + 0xC )) 
+#define CONFIG_UNLOCK_MSK (0xFFFFFFFF)
+#define CONFIG_UNLOCK_OFST (0)
+
+#define CONFIG_UNLOCK_MAGIC (0x554E4C4B)
+
+#endif /* __PLD_CONF00_H */
+
+
+
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/serial.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/serial.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/serial.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/serial.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,50 @@
+/*
+ *  linux/include/asm-arm/arch-epxa10db/serial.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/arch/platform.h>
+#include <asm/irq.h>
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD (1 / 16)
+
+#define _SER_IRQ0	IRQ_UARTINT0
+#define _SER_IRQ1	IRQ_UARTINT1
+
+#define RS_TABLE_SIZE	2
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+     /* UART CLK        PORT  IRQ     FLAGS        */
+#define STD_SERIAL_PORT_DEFNS \
+	{ 0, BASE_BAUD, 0x3F8, _SER_IRQ0, STD_COM_FLAGS },	/* ttyS0 */	\
+	{ 0, BASE_BAUD, 0x2F8, _SER_IRQ1, STD_COM_FLAGS },	/* ttyS1 */
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/system.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/system.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/system.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,46 @@
+/*
+ *  linux/include/asm-arm/arch-epxa10db/system.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/arch/platform.h>
+#include <asm/arch/excalibur.h>
+#include <asm/arch/watchdog00.h>
+#define WATCHDOG00_TYPE (volatile unsigned int*)
+
+static void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle();
+}
+
+extern __inline__ void arch_reset(char mode)
+{
+
+	/* Force the watchdog to generate a reset */
+	*WDOG_CR(EXC_WATCHDOG00_BASE)=*WDOG_COUNT(EXC_WATCHDOG00_BASE)+0x100;
+}
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/tdkphy.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/tdkphy.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/tdkphy.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/tdkphy.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,209 @@
+/*
+ *  linux/drivers/tdkphy.h
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __TDKPHY_H
+#define __TDKPHY_H
+
+/*
+ * Register definitions for the TDK 78Q2120 PHY 
+ * which is on the Camelot board
+ */
+
+/*
+ * Copyright (c) Altera Corporation 2000.
+ * All rights reserved.
+ */
+#define PHY_CONTROL                                                                                     (0)
+#define PHY_CONTROL_COLT_MSK                                                            (0x80)
+#define PHY_CONTROL_COLT_OFST                                                           (7)
+#define PHY_CONTROL_DUPLEX_MSK                                                          (0x100)
+#define PHY_CONTROL_DUPLEX_OFST                                                         (8)
+#define PHY_CONTROL_RANEG_MSK                                                           (0x200)
+#define PHY_CONTROL_RANEG_OFST                                                          (9)
+#define PHY_CONTROL_ISO_MSK                                                                     (0x400)
+#define PHY_CONTROL_ISO_OFST                                                            (10)
+#define PHY_CONTROL_PWRDN_MSK                                                           (0x800)
+#define PHY_CONTROL_PWRDN_OFST                                                          (11)
+#define PHY_CONTROL_ANEGEN_MSK                                                          (0x1000)
+#define PHY_CONTROL_ANEGEN_OFST                                                         (12)
+#define PHY_CONTROL_SPEEDSL_MSK                                                         (0x2000)
+#define PHY_CONTROL_SPEEDSL_OFST                                                        (13)
+#define PHY_CONTROL_LOOPBK_MSK                                                          (0x4000)
+#define PHY_CONTROL_LOOPBK_OFST                                                         (14)
+#define PHY_CONTROL_RESET_MSK                                                           (0x8000)
+#define PHY_CONTROL_RESET_OFST                                                          (15)
+
+#define PHY_STATUS                                                                                      (1)
+#define PHY_STATUS_ETXD_MSK                                                                     (0x1)
+#define PHY_STATUS_EXTD_OFST                                                            (0)
+#define PHY_STATUS_JAB_MSK                                                                      (0x2)
+#define PHY_STATUS_JAB_OFST                                                                     (1)
+#define PHY_STATUS_LINK_MSK                                                                     (0x4)
+#define PHY_STATUS_LINK_OFST                                                            (2)
+#define PHY_STATUS_ANEGA_MSK                                                            (0x8)
+#define PHY_STATUS_ANEGA_OFST                                                           (3)
+#define PHY_STATUS_RFAULT_MSK                                                           (0x10)
+#define PHY_STATUS_RFAULT_OFST                                                          (4)
+#define PHY_STATUS_ANEGC_MSK                                                            (0x20)
+#define PHY_STATUS_ANEGC_OFST                                                           (5)
+#define PHY_STATUS_10T_H_MSK                                                            (0x800)
+#define PHY_STATUS_10T_H_OFST                                                           (11)
+#define PHY_STATUS_10T_F_MSK                                                            (0x1000)
+#define PHY_STATUS_10T_F_OFST                                                           (12)
+#define PHY_STATUS_100_X_H_MSK                                                          (0x2000)
+#define PHY_STATUS_100_X_H_OFST                                                         (13)
+#define PHY_STATUS_100_X_F_MSK                                                          (0x4000)
+#define PHY_STATUS_100_X_F_OFST                                                         (14)
+#define PHY_STATUS_100T4_MSK                                                            (0x8000)
+#define PHY_STATUS_100T4_OFST                                                           (15)
+
+#define PHY_ID1                                                                                         (2)
+#define PHY_ID1_OUI_MSK                                                                         (0xFFFF)
+#define PHY_ID1_OUI_OFST                                                                        (0)
+
+#define PHY_ID2                                                                                         (3)
+#define PHY_ID2_RN_MSK                                                                          (0xF)
+#define PHY_ID2_RN_OFST                                                                         (0)
+#define PHY_ID2_MN_MSK                                                                          (0x3F0)
+#define PHY_ID2_MN_OFST                                                                         (4)
+#define PHY_ID2_OUI_MSK                                                                         (0xFC00)
+#define PHY_ID2_OUI_OFST                                                                        (10)
+
+#define PHY_AUTO_NEG_ADVERTISEMENT                                                      (4)
+#define PHY_AUTO_NEG_ADVERTISEMENT_SELECTOR_MSK                         (0x1F)
+#define PHY_AUTO_NEG_ADVERTISEMENT_SELECTOR_OFST                        (0)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A0_MSK                                       (0x20)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A0_OFST                                      (5)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A1_MSK                                       (0x40)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A1_OFST                                      (6)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A2_MSK                                       (0x80)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A2_OFST                                      (7)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A3_MSK                                       (0x100)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A3_OFST                                      (8)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A4_MSK                                       (0x200)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A4_OFST                                      (9)
+#define PHY_AUTO_NEG_ADVERTISEMENT_TAF_MSK                                      (0x1FE0)
+#define PHY_AUTO_NEG_ADVERTISEMENT_TAF_OFST                                     (5)
+#define PHY_AUTO_NEG_ADVERTISEMENT_RF_MSK                                       (0x2000)
+#define PHY_AUTO_NEG_ADVERTISEMENT_RF_OFST                                      (13)
+#define PHY_AUTO_NEG_ADVERTISEMENT_RSVD_MSK                                     (0x4000)
+#define PHY_AUTO_NEG_ADVERTISEMENT_RVSD_OFST                            (14)
+#define PHY_AUTO_NEG_ADVERTISEMENT_NP_MSK                                       (0x8000)
+#define PHY_AUTO_NEG_ADVERTISEMENT_NP_OFST                                      (15)
+
+#define PHY_AUTO_NEG_LINK_PARTNER                                                       (5)
+#define PHY_AUTO_NEG_LINK_PARTNER_S4_MSK                                        (0x1F)
+#define PHY_AUTO_NEG_LINK_PARTNER_S4_OFST                                       (0)
+#define PHY_AUTO_NEG_LINK_PARTNER_A7_MSK                                        (0x1FE0)
+#define PHY_AUTO_NEG_LINK_PARTNER_A7_OFST                                       (5)
+#define PHY_AUTO_NEG_LINK_PARTNER_RF_MSK                                        (0x2000)
+#define PHY_AUTO_NEG_LINK_PARTNER_RF_OFST                                       (13)
+#define PHY_AUTO_NEG_LINK_PARTNER_ACK_MSK                                       (0x4000)
+#define PHY_AUTO_NEG_LINK_PARTNER_ACK_OFST                                      (14)
+#define PHY_AUTO_NEG_LINK_PARTNER_NP_MSK                                        (0x8000)
+#define PHY_AUTO_NEG_LINK_PARTNER_NP_OFST                                       (15)
+
+#define PHY_AUTO_NEG_EXPANSION                                                          (6)
+#define PHY_AUTO_NEG_EXPANSION_LPANEGA_MSK                                      (0x1)
+#define PHY_AUTO_NEG_EXPANSION_LPANEGA_OFST                                     (0)
+#define PHY_AUTO_NEG_EXPANSION_PRX_MSK                                          (0x2)
+#define PHY_AUTO_NEG_EXPANSION_PRX_OFST                                         (1)
+#define PHY_AUTO_NEG_EXPANSION_NPA_MSK                                          (0x4)
+#define PHY_AUTO_NEG_EXPANSION_NPA_OFST                                         (2)
+#define PHY_AUTO_NEG_EXPANSION_LPNPA_MSK                                        (0x8)
+#define PHY_AUTO_NEG_EXPANSION_LPNPA_OFST                                       (3)
+#define PHY_AUTO_NEG_EXPANSION_PDF_MSK                                          (0x10)
+#define PHY_AUTO_NEG_EXPANSION_PDF_OFST                                         (4)
+
+#define PHY_VENDOR_SPECIFIC                                                                     (16)
+#define PHY_VENDOR_SPECIFIC_RXCC_MSK                                            (0x1)
+#define PHY_VENDOR_SPECIFIC_RXCC_OFST                                           (0)
+#define PHY_VENDOR_SPECIFIC_PCSBP_MSK                                           (0x2)
+#define PHY_VENDOR_SPECIFIC_PCSBP_OFST                                          (1)
+#define PHY_VENDOR_SPECIFIC_RVSPOL_MSK                                          (0x10)
+#define PHY_VENDOR_SPECIFIC_RVSPOL_OFST                                         (4)
+#define PHY_VENDOR_SPECIFIC_APOL_MSK                                            (0x20)  
+#define PHY_VENDOR_SPECIFIC_APOL_OFST                                           (5)
+#define PHY_VENDOR_SPECIFIC_GPIO0_DIR_MSK                                       (0x40)
+#define PHY_VENDOR_SPECIFIC_GPIO0_DIR_OFST                                      (6)
+#define PHY_VENDOR_SPECIFIC_GPIO0_DAT_MSK                                       (0x80)
+#define PHY_VENDOR_SPECIFIC_GPIO0_DAT_OFST                                      (7)
+#define PHY_VENDOR_SPECIFIC_GPIO1_DIR_MSK                                       (0x100)
+#define PHY_VENDOR_SPECIFIC_GPIO1_DIR_OFST                                      (8)
+#define PHY_VENDOR_SPECIFIC_GPIO1_DAT_MSK                                       (0x200)
+#define PHY_VENDOR_SPECIFIC_GPIO1_DAT_OFST                                      (9)
+#define PHY_VENDOR_SPECIFIC_10BT_NATURAL_LOOPBACK_DAT_MSK       (0x400)
+#define PHY_VENDOR_SPECIFIC_10BT_NATURAL_LOOPBACK_DAT_OFST      (10)
+#define PHY_VENDOR_SPECIFIC_10BT_SQE_TEST_INHIBIT_MSK           (0x800)
+#define PHY_VENDOR_SPECIFIC_10BT_SQE_TEST_INHIBIT_OFST          (11)
+#define PHY_VENDOR_SPECIFIC_TXHIM_MSK                                           (0x1000)
+#define PHY_VENDOR_SPECIFIC_TXHIM_OFST                                          (12)
+#define PHY_VENDOR_SPECIFIC_INT_LEVEL_MSK                                       (0x4000)
+#define PHY_VENDOR_SPECIFIC_INT_LEVEL_OFST                                      (14)
+#define PHY_VENDOR_SPECIFIC_RPTR_MSK                                            (0x8000)
+#define PHY_VENDOR_SPECIFIC_RPTR_OFST                                           (15)
+
+#define PHY_IRQ_CONTROL                                                                         (17)
+#define PHY_IRQ_CONTROL_ANEG_COMP_INT_MSK                                       (0x1)
+#define PHY_IRQ_CONTROL_ANEG_COMP_INT_OFST                                      (0)
+#define PHY_IRQ_CONTROL_RFAULT_INT_MSK                                          (0x2)
+#define PHY_IRQ_CONTROL_RFAULT_INT_OFST                                         (1)
+#define PHY_IRQ_CONTROL_LS_CHG_INT_MSK                                          (0x4)
+#define PHY_IRQ_CONTROL_LS_CHG_INT_OFST                                         (2)
+#define PHY_IRQ_CONTROL_LP_ACK_INT_MSK                                          (0x8)
+#define PHY_IRQ_CONTROL_LP_ACK_INT_OFST                                         (3)
+#define PHY_IRQ_CONTROL_PDF_INT_MSK                                                     (0x10)
+#define PHY_IRQ_CONTROL_PDF_INT_OFST                                            (4)
+#define PHY_IRQ_CONTROL_PRX_INT_MSK                                                     (0x20)
+#define PHY_IRQ_CONTROL_PRX_INT_OFST                                            (5)
+#define PHY_IRQ_CONTROL_RXER_INT_MSK                                            (0x40)
+#define PHY_IRQ_CONTROL_RXER_INT_OFST                                           (6)
+#define PHY_IRQ_CONTROL_JABBER_INT_MSK                                          (0x80)
+#define PHY_IRQ_CONTROL_JABBER_INT_OFST                                         (7)
+#define PHY_IRQ_CONTROL_ANEG_COMP_IE_MSK                                        (0x100)
+#define PHY_IRQ_CONTROL_ANEG_COMP_IE_OFST                                       (8)
+#define PHY_IRQ_CONTROL_RFAULT_IE_MSK                                           (0x200)
+#define PHY_IRQ_CONTROL_RFAULT_IE_OFST                                          (9)
+#define PHY_IRQ_CONTROL_LS_CHG_IE_MSK                                           (0x400)
+#define PHY_IRQ_CONTROL_LS_CHG_IE_OFST                                          (10)
+#define PHY_IRQ_CONTROL_LP_ACK_IE_MSK                                           (0x800)
+#define PHY_IRQ_CONTROL_LP_ACK_IE_OFST                                          (11)
+#define PHY_IRQ_CONTROL_PDF_IE_MSK                                                      (0x1000)
+#define PHY_IRQ_CONTROL_PDF_IE_OFST                                                     (12)
+#define PHY_IRQ_CONTROL_PRX_IE_MSK                                                      (0x2000)
+#define PHY_IRQ_CONTROL_PRX_IE_OFST                                                     (13)
+#define PHY_IRQ_CONTROL_RXER_IE_MSK                                                     (0x4000)
+#define PHY_IRQ_CONTROL_RXER_IE_OFST                                            (14)
+#define PHY_IRQ_CONTROL_JABBER_IE_MSK                                           (0x8000)
+#define PHY_IRQ_CONTROL_JABBER_IE_OFST                                          (15)
+
+#define PHY_DIAGNOSTIC                                                                          (18)
+#define PHY_DIAGNOSTIC_RX_LOCK_MSK                                                      (0x100)
+#define PHY_DIAGNOSTIC_RX_LOCK_OFST                                                     (8)
+#define PHY_DIAGNOSTIC_RX_PASS_MSK                                                      (0x200)
+#define PHY_DIAGNOSTIC_RX_PASS_OFST                                                     (9)
+#define PHY_DIAGNOSTIC_RATE_MSK                                                         (0x400)
+#define PHY_DIAGNOSTIC_RATE_OFST                                                        (10)
+#define PHY_DIAGNOSTIC_DPLX_MSK                                                         (0x800)
+#define PHY_DIAGNOSTIC_DPLX_OFST                                                        (11)
+#define PHY_DIAGNOSTIC_ANEGF_MSK                                                        (0x1000)
+#define PHY_DIAGNOSTIC_ANEGF_OFST                                                       (12)
+
+#endif /* __TDKPHY_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/time.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/time.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/time.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/time.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,64 @@
+/*
+ *  linux/include/asm-arm/arch-epxa10db/time.h
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/config.h>
+#include <asm/system.h>
+#include <asm/leds.h>
+#include <asm/arch/hardware.h>
+#define TIMER00_TYPE (volatile unsigned int*)
+#include <asm/arch/timer00.h>
+
+
+/*
+ * IRQ handler for the timer
+ */
+static void excalibur_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+	// ...clear the interrupt
+	*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK;
+
+	do_leds();
+	do_timer(regs);
+	do_profile(regs);
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+extern __inline__ void setup_timer(void)
+{
+
+
+	timer_irq.handler = excalibur_timer_interrupt;
+
+
+	/* 
+	 * Make irqs happen for the system timer
+	 */
+	setup_arm_irq(IRQ_TIMER0, &timer_irq);
+
+
+	/* Stop the timer, reconfigure it and then restart it */
+
+	*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=0;
+	*TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200);
+	*TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1;
+	*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK;
+}
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/timer00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/timer00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/timer00.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/timer00.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,98 @@
+/*
+ *  
+ *  This file contains the register definitions for the Excalibur
+ *  Timer TIMER00.
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __TIMER00_H
+#define __TIMER00_H
+
+/*
+ * Register definitions for the timers
+ */
+
+
+#define TIMER0_CR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x00 ))
+#define TIMER0_CR_B_MSK (0x20)
+#define TIMER0_CR_B_OFST (0x5)
+#define TIMER0_CR_S_MSK  (0x10)
+#define TIMER0_CR_S_OFST (0x4)
+#define TIMER0_CR_CI_MSK (0x08)
+#define TIMER0_CR_CI_OFST (0x3)
+#define TIMER0_CR_IE_MSK (0x04)
+#define TIMER0_CR_IE_OFST (0x2)
+#define TIMER0_CR_MODE_MSK (0x3)
+#define TIMER0_CR_MODE_OFST (0)
+#define TIMER0_CR_MODE_FREE (0)
+#define TIMER0_CR_MODE_ONE  (1)
+#define TIMER0_CR_MODE_INTVL (2)
+
+#define TIMER0_SR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x00 ))
+#define TIMER0_SR_B_MSK (0x20)
+#define TIMER0_SR_B_OFST (0x5)
+#define TIMER0_SR_S_MSK  (0x10)
+#define TIMER0_SR_S_OFST (0x4)
+#define TIMER0_SR_CI_MSK (0x08)
+#define TIMER0_SR_CI_OFST (0x3)
+#define TIMER0_SR_IE_MSK (0x04)
+#define TIMER0_SR_IE_OFST (0x2)
+#define TIMER0_SR_MODE_MSK (0x3)
+#define TIMER0_SR_MODE_OFST (0)
+#define TIMER0_SR_MODE_FREE (0)
+#define TIMER0_SR_MODE_ONE  (1)
+#define TIMER0_SR_MODE_INTVL (2)
+
+#define TIMER0_PRESCALE(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x010 ))
+#define TIMER0_LIMIT(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x020 ))
+#define TIMER0_READ(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x030 ))
+
+#define TIMER1_CR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x40 ))
+#define TIMER1_CR_B_MSK (0x20)
+#define TIMER1_CR_B_OFST (0x5)
+#define TIMER1_CR_S_MSK  (0x10)
+#define TIMER1_CR_S_OFST (0x4)
+#define TIMER1_CR_CI_MSK (0x08)
+#define TIMER1_CR_CI_OFST (0x3)
+#define TIMER1_CR_IE_MSK (0x04)
+#define TIMER1_CR_IE_OFST (0x2)
+#define TIMER1_CR_MODE_MSK (0x3)
+#define TIMER1_CR_MODE_OFST (0)
+#define TIMER1_CR_MODE_FREE (0)
+#define TIMER1_CR_MODE_ONE  (1)
+#define TIMER1_CR_MODE_INTVL (2)
+
+#define TIMER1_SR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x40 ))
+#define TIMER1_SR_B_MSK (0x20)
+#define TIMER1_SR_B_OFST (0x5)
+#define TIMER1_SR_S_MSK  (0x10)
+#define TIMER1_SR_S_OFST (0x4)
+#define TIMER1_SR_CI_MSK (0x08)
+#define TIMER1_SR_CI_OFST (0x3)
+#define TIMER1_SR_IE_MSK (0x04)
+#define TIMER1_SR_IE_OFST (0x2)
+#define TIMER1_SR_MODE_MSK (0x3)
+#define TIMER1_SR_MODE_OFST (0)
+#define TIMER1_SR_MODE_FREE (0)
+#define TIMER1_SR_MODE_ONE  (1)
+#define TIMER1_SR_MODE_INTVL (2)
+
+#define TIMER1_PRESCALE(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x050 ))
+#define TIMER1_LIMIT(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x060 ))
+#define TIMER1_READ(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x070 ))
+
+#endif /* __TIMER00_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/timex.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/timex.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/timex.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/timex.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,26 @@
+/*
+ *  linux/include/asm-arm/arch-epxa10db/timex.h
+ *
+ *  Excalibur timex specifications
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * ??
+ */
+#define CLOCK_TICK_RATE		(50000000 / 16)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/uart00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/uart00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/uart00.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/uart00.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,181 @@
+/* *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __UART00_H
+#define __UART00_H
+
+/*
+ * Register definitions for the UART
+ */
+
+#define UART_TX_FIFO_SIZE      (15)
+
+#define UART_RSR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x00 ))
+#define UART_RSR_RX_LEVEL_MSK (0x1f)
+#define UART_RSR_RX_LEVEL_OFST (0)
+#define UART_RSR_RE_MSK (0x80)
+#define UART_RSR_RE_OFST (7)
+
+#define UART_RDS(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x04 ))
+#define UART_RDS_BI_MSK (0x8)
+#define UART_RDS_BI_OFST (4)
+#define UART_RDS_FE_MSK (0x4)
+#define UART_RDS_FE_OFST (2)
+#define UART_RDS_PE_MSK (0x2)
+#define UART_RDS_PE_OFST (1)
+#define UART_RDS_OE_MSK (0x1)
+#define UART_RDS_OE_OFST (0)
+
+#define UART_RD(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x08 ))
+#define UART_RD_RX_DATA_MSK (0xff)
+#define UART_RD_RX_DATA_OFST (0)
+
+#define UART_TSR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x0c ))
+#define UART_TSR_TX_LEVEL_MSK (0x1f)
+#define UART_TSR_TX_LEVEL_OFST (0)
+#define UART_TSR_TXI_MSK (0x80)
+#define UART_TSR_TXI_OFST (7)
+
+#define UART_TD(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x10 ))
+#define UART_TD_TX_DATA_MSK (0xff)
+#define UART_TD_TX_DATA_OFST (0)
+
+#define UART_FCR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x14 ))
+#define UART_FCR_RX_THR_MSK (0xd0)
+#define UART_FCR_RX_THR_OFST (5)
+#define UART_FCR_RX_THR_1 (0x00)
+#define UART_FCR_RX_THR_2 (0x20)
+#define UART_FCR_RX_THR_4 (0x40)
+#define UART_FCR_RX_THR_6 (0x60)
+#define UART_FCR_RX_THR_8 (0x80)
+#define UART_FCR_RX_THR_10 (0xa0)
+#define UART_FCR_RX_THR_12 (0xc0)
+#define UART_FCR_RX_THR_14 (0xd0)
+#define UART_FCR_TX_THR_MSK (0x1c)
+#define UART_FCR_TX_THR_OFST (2)
+#define UART_FCR_TX_THR_0 (0x00)
+#define UART_FCR_TX_THR_2 (0x04)
+#define UART_FCR_TX_THR_4 (0x08)
+#define UART_FCR_TX_THR_8 (0x0c)
+#define UART_FCR_TX_THR_10 (0x10)
+#define UART_FCR_TX_THR_12 (0x14)
+#define UART_FCR_TX_THR_14 (0x18)
+#define UART_FCR_TX_THR_15 (0x1c)
+#define UART_FCR_RC_MSK (0x02)
+#define UART_FCR_RC_OFST (1)
+#define UART_FCR_TC_MSK (0x01)
+#define UART_FCR_TC_OFST (0)
+
+#define UART_IES(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x18 ))
+#define UART_IES_ME_MSK (0x8)
+#define UART_IES_ME_OFST (3)
+#define UART_IES_TIE_MSK (0x4)
+#define UART_IES_TIE_OFST (2)
+#define UART_IES_TE_MSK (0x2)
+#define UART_IES_TE_OFST (1)
+#define UART_IES_RE_MSK (0x1)
+#define UART_IES_RE_OFST (0)
+
+#define UART_IEC(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x1c ))
+#define UART_IEC_ME_MSK (0x8)
+#define UART_IEC_ME_OFST (3)
+#define UART_IEC_TIE_MSK (0x4)
+#define UART_IEC_TIE_OFST (2)
+#define UART_IEC_TE_MSK (0x2)
+#define UART_IEC_TE_OFST (1)
+#define UART_IEC_RE_MSK (0x1)
+#define UART_IEC_RE_OFST (0)
+
+#define UART_ISR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x20 ))
+#define UART_ISR_MI_MSK (0x8)
+#define UART_ISR_MI_OFST (3)
+#define UART_ISR_TII_MSK (0x4)
+#define UART_ISR_TII_OFST (2)
+#define UART_ISR_TI_MSK (0x2)
+#define UART_ISR_TI_OFST (1)
+#define UART_ISR_RI_MSK (0x1)
+#define UART_ISR_RI_OFST (0)
+
+#define UART_IID(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x24 ))
+#define UART_IID_IID_MSK (0x7)
+#define UART_IID_IID_OFST (0)
+
+#define UART_MC(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x28 ))
+#define UART_MC_OE_MSK (0x40)
+#define UART_MC_OE_OFST (6)
+#define UART_MC_SP_MSK (0x20)
+#define UART_MC_SP_OFST (5)
+#define UART_MC_EP_MSK (0x10)
+#define UART_MC_EP_OFST (4)
+#define UART_MC_PE_MSK (0x08)
+#define UART_MC_PE_OFST (3)
+#define UART_MC_ST_MSK (0x04)
+#define UART_MC_ST_ONE (0x0)
+#define UART_MC_ST_TWO (0x04)
+#define UART_MC_ST_OFST (2)
+#define UART_MC_CLS_MSK (0x03)
+#define UART_MC_CLS_OFST (0)
+#define UART_MC_CLS_CHARLEN_5 (0)
+#define UART_MC_CLS_CHARLEN_6 (1)
+#define UART_MC_CLS_CHARLEN_7 (2)
+#define UART_MC_CLS_CHARLEN_8 (3)
+
+#define UART_MCR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x2c ))
+#define UART_MCR_AC_MSK (0x80)
+#define UART_MCR_AC_OFST (7)
+#define UART_MCR_AR_MSK (0x40)
+#define UART_MCR_AR_OFST (6)
+#define UART_MCR_BR_MSK (0x20)
+#define UART_MCR_BR_OFST (5)
+#define UART_MCR_LB_MSK (0x10)
+#define UART_MCR_LB_OFST (4)
+#define UART_MCR_DCD_MSK (0x08)
+#define UART_MCR_DCD_OFST (3)
+#define UART_MCR_RI_MSK (0x04)
+#define UART_MCR_RI_OFST (2)
+#define UART_MCR_DTR_MSK (0x02)
+#define UART_MCR_DTR_OFST (1)
+#define UART_MCR_RTS_MSK (0x01)
+#define UART_MCR_RTS_OFST (0)
+
+#define UART_MSR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x30 ))
+#define UART_MSR_DCD_MSK (0x80)
+#define UART_MSR_DCD_OFST (7)
+#define UART_MSR_RI_MSK (0x40)
+#define UART_MSR_RI_OFST (6)
+#define UART_MSR_DSR_MSK (0x20)
+#define UART_MSR_DSR_OFST (5)
+#define UART_MSR_CTS_MSK (0x10)
+#define UART_MSR_CTS_OFST (4)
+#define UART_MSR_DDCD_MSK (0x08)
+#define UART_MSR_DDCD_OFST (3)
+#define UART_MSR_TERI_MSK (0x04)
+#define UART_MSR_TERI_OFST (2)
+#define UART_MSR_DDSR_MSK (0x02)
+#define UART_MSR_DDSR_OFST (1)
+#define UART_MSR_DCTS_MSK (0x01)
+#define UART_MSR_DCTS_OFST (0)
+
+#define UART_DIV_LO(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x34 ))
+#define UART_DIV_LO_DIV_MSK (0xff)
+#define UART_DIV_LO_DIV_OFST (0)
+
+#define UART_DIV_HI(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x38 ))
+#define UART_DIV_HI_DIV_MSK (0xff)
+#define UART_DIV_HI_DIV_OFST (0)
+
+#endif /* __UART00_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/uncompress.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/uncompress.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/uncompress.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/uncompress.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,54 @@
+/*
+ *  linux/include/asm-arm/arch-epxa10db/uncompress.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include "asm/arch/platform.h"
+#include "asm/arch/hardware.h"
+#define UART00_TYPE (volatile unsigned int*)
+#include "asm/arch/uart00.h"
+
+/*
+ * This does not append a newline
+ */
+static void puts(const char *s)
+{
+	while (*s) {
+		while ((*UART_TSR(EXC_UART00_BASE) &
+		       UART_TSR_TX_LEVEL_MSK)==15);
+			barrier();
+
+		*UART_TD(EXC_UART00_BASE) = *s;
+
+		if (*s == '\n') {
+			while ((*UART_TSR(EXC_UART00_BASE) &
+			       UART_TSR_TX_LEVEL_MSK)==15);
+				barrier();
+
+			*UART_TD(EXC_UART00_BASE) = '\r';
+		}
+		s++;
+	}
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/vmalloc.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/vmalloc.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/vmalloc.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/vmalloc.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-arm/arch-epxa10db/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa/watchdog00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa/watchdog00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa/watchdog00.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa/watchdog00.h	2003-07-05 18:11:09.000000000 -0700
@@ -0,0 +1,27 @@
+#ifndef __WATCHDOG_00_H
+#define __WATCHDOG_00_H
+
+/*
+ * Register definitions for the watchdog
+ */
+
+/*
+ * Copyright (c) Altera Corporation 2000.
+ * All rights reserved.
+ */
+
+#define WDOG_CR(base_addr) (WATCHDOG00_TYPE (base_addr  ))
+#define WDOG_CR_LK_MSK (0x1)
+#define WDOG_CR_LK_OFST (0)
+#define WDOG_CR_LK_ENABLE (0x1)
+#define WDOG_CR_TRIGGER_MSK (0x3FFFFFF0)
+#define WDOG_CR_TRIGGER_OFST (4)
+
+#define WDOG_COUNT(base_addr) (WATCHDOG00_TYPE (base_addr  + 0x4 ))
+#define WDOG_COUNT_MSK (0x3FFFFFFF)
+
+#define WDOG_RELOAD(base_addr) (WATCHDOG00_TYPE (base_addr  + 0x8 ))
+#define WDOG_RELOAD_MAGIC_1 (0xA5A5A5A5)
+#define WDOG_RELOAD_MAGIC_2 (0x5A5A5A5A)
+
+#endif /* __WATCHDOG_00_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/dma.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/dma.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/dma.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/dma.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,28 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-camelot/dma.h
- *
- *  Copyright (C) 1997,1998 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_ADDRESS		0xffffffff
-
-#define MAX_DMA_CHANNELS	0
-
-#endif /* _ASM_ARCH_DMA_H */
-
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/ether00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/ether00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/ether00.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/ether00.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,482 +0,0 @@
-#ifndef __ETHER00_H
-#define __ETHER00_H
-
-
-
-/*
- * Register definitions for the Ethernet MAC
- */
-
-/*
- * Copyright (c) Altera Corporation 2000.
- * All rights reserved.
- */
-
-/*
-*	Structures for the DMA controller
-*/
-typedef struct fda_desc
-	{
-	struct fda_desc *	FDNext;
-	long				FDSystem;
-	long				FDStat;
-	short				FDLength;
-	short				FDCtl;
-	}FDA_DESC;
-
-typedef struct buf_desc
-	{
-	char *	BuffData;
-	short	BuffLength;
-	char	BDStat;
-	char	BDCtl;
-	}BUF_DESC;
-
-/*
-*	Control masks for the DMA controller
-*/
-#define FDCTL_BDCOUNT_MSK						(0x1F)
-#define FDCTL_BDCOUNT_OFST						(0)
-#define FDCTL_FRMOPT_MSK						(0x7C00)
-#define FDCTL_FRMOPT_OFST						(10)
-#define	FDCTL_COWNSFD_MSK						(0x8000)
-#define	FDCTL_COWNSFD_OFST						(15)
-
-#define BDCTL_RXBDSEQN_MSK						(0x7F)
-#define BDCTL_RXBDSEQN_OFST						(0)
-#define	BDCTL_COWNSBD_MSK						(0x80)
-#define	BDCTL_COWNSBD_OFST						(7)
-
-#define FDNEXT_EOL_MSK							(0x1)
-#define FDNEXT_EOL_OFST							(0)
-#define FDNEXT_EOL_POINTER_MSK					(0xFFFFFFF0)
-#define FDNEXT_EOL_POINTER_OFST					(4)
-
-#define ETHER_ARC_SIZE         (21)
-
-/*
-*	Regsiter definitions and masks
-*/
-#define ETHER_DMA_CTL(base)							(ETHER00_TYPE (base + 0x100))
-#define ETHER_DMA_CTL_DMBURST_OFST				(2)
-#define ETHER_DMA_CTL_DMBURST_MSK				(0x1FC)
-#define ETHER_DMA_CTL_POWRMGMNT_OFST			(11)
-#define ETHER_DMA_CTL_POWRMGMNT_MSK				(0x1000)
-#define ETHER_DMA_CTL_TXBIGE_OFST				(14)
-#define ETHER_DMA_CTL_TXBIGE_MSK				(0x4000)
-#define ETHER_DMA_CTL_RXBIGE_OFST				(15)
-#define ETHER_DMA_CTL_RXBIGE_MSK				(0x8000)
-#define ETHER_DMA_CTL_TXWAKEUP_OFST				(16)
-#define ETHER_DMA_CTL_TXWAKEUP_MSK				(0x10000)
-#define ETHER_DMA_CTL_SWINTREQ_OFST				(17)
-#define ETHER_DMA_CTL_SWINTREQ_MSK				(0x20000)
-#define ETHER_DMA_CTL_INTMASK_OFST				(18)
-#define ETHER_DMA_CTL_INTMASK_MSK				(0x40000)
-#define ETHER_DMA_CTL_M66ENSTAT_OFST			(19)
-#define ETHER_DMA_CTL_M66ENSTAT_MSK				(0x80000)
-#define ETHER_DMA_CTL_RMTXINIT_OFST				(20)
-#define ETHER_DMA_CTL_RMTXINIT_MSK				(0x100000)
-#define ETHER_DMA_CTL_RMRXINIT_OFST				(21)
-#define ETHER_DMA_CTL_RMRXINIT_MSK				(0x200000)
-#define ETHER_DMA_CTL_RXALIGN_OFST				(22)
-#define ETHER_DMA_CTL_RXALIGN_MSK				(0xC00000)
-#define ETHER_DMA_CTL_RMSWRQ_OFST				(24)
-#define ETHER_DMA_CTL_RMSWRQ_MSK				(0x1000000)
-#define ETHER_DMA_CTL_RMEMBANK_OFST				(25)
-#define ETHER_DMA_CTL_RMEMBANK_MSK				(0x2000000)
-
-#define ETHER_TXFRMPTR(base)							(ETHER00_TYPE (base + 0x104))
-
-#define ETHER_TXTHRSH(base)							(ETHER00_TYPE (base + 0x308))
-
-#define ETHER_TXPOLLCTR(base)							(ETHER00_TYPE (base + 0x30c))
-
-#define	ETHER_BLFRMPTR(base)							(ETHER00_TYPE (base + 0x110))
-#define ETHER_BLFFRMPTR_EOL_OFST				(0)
-#define ETHER_BLFFRMPTR_EOL_MSK					(0x1)
-#define ETHER_BLFFRMPTR_ADDRESS_OFST			(4)
-#define ETHER_BLFFRMPTR_ADDRESS_MSK				(0xFFFFFFF0)
-
-#define ETHER_RXFRAGSIZE(base)						(ETHER00_TYPE (base + 0x114))
-#define	ETHER_RXFRAGSIZE_MINFRAG_OFST			(2)
-#define	ETHER_RXFRAGSIZE_MINFRAG_MSK			(0xFFC)
-#define	ETHER_RXFRAGSIZE_ENPACK_OFST			(15)
-#define	ETHER_RXFRAGSIZE_ENPACK_MSK				(0x8000)
-
-#define ETHER_INT_EN(base)							(ETHER00_TYPE (base + 0x118))
-#define ETHER_INT_EN_FDAEXEN_OFST				(0)
-#define ETHER_INT_EN_FDAEXEN_MSK				(0x1)
-#define ETHER_INT_EN_BLEXEN_OFST				(1)
-#define ETHER_INT_EN_BLEXN_MSK					(0x2)
-#define ETHER_INT_EN_STARGABTEN_OFST			(2)
-#define ETHER_INT_EN_STARGABTEN_MSK				(0x4)
-#define ETHER_INT_EN_RTARGABTEN_OFST			(3)
-#define ETHER_INT_EN_RTARGABTEN_MSK				(0x8)
-#define ETHER_INT_EN_RMASABTEN_OFST				(4)
-#define ETHER_INT_EN_RMASABTEN_MSK				(0x10)
-#define ETHER_INT_EN_SSYSERREN_OFST				(5)
-#define ETHER_INT_EN_SSYSERREN_MSK				(0x20)
-#define ETHER_INT_EN_DPARERREN_OFST				(6)
-#define ETHER_INT_EN_DPARERREN_MSK				(0x40)
-#define ETHER_INT_EN_EARNOTEN_OFST				(7)
-#define ETHER_INT_EN_EARNOTEN_MSK				(0x80)
-#define ETHER_INT_EN_DPARDEN_OFST				(8)
-#define ETHER_INT_EN_DPARDEN_MSK				(0x100)
-#define ETHER_INT_EN_DMPARERREN_OFST			(9)
-#define ETHER_INT_EN_DMPARERREN_MSK				(0x200)
-#define ETHER_INT_EN_TXCTLCMPEN_OFST			(10)
-#define ETHER_INT_EN_TXCTLCMPEN_MSK				(0x400)
-#define ETHER_INT_EN_NRABTEN_OFST				(11)
-#define ETHER_INT_EN_NRABTEN_MSK				(0x800)
-
-#define	ETHER_FDA_BAS(base)							(ETHER00_TYPE (base + 0x11C))
-#define ETHER_FDA_BAS_ADDRESS_OFST				(4)
-#define ETHER_FDA_BAS_ADDRESS_MSK				(0xFFFFFFF0)
-
-#define ETHER_FDA_LIM(base)							(ETHER00_TYPE (base + 0x120))
-#define ETHER_FDA_LIM_COUNT_OFST				(4)
-#define ETHER_FDA_LIM_COUNT_MSK					(0xFFF0)
-
-#define ETHER_INT_SRC(base)							(ETHER00_TYPE (base + 0x124))
-#define ETHER_INT_SRC_INTMACTX_OFST				(0)
-#define ETHER_INT_SRC_INTMACTX_MSK				(0x1)
-#define ETHER_INT_SRC_INTMACRX_OFST				(1)
-#define ETHER_INT_SRC_INTMACRX_MSK				(0x2)
-#define ETHER_INT_SRC_INTSBUS_OFST				(2)
-#define ETHER_INT_SRC_INTSBUS_MSK				(0x4)
-#define ETHER_INT_SRC_INTFDAEX_OFST				(3)
-#define ETHER_INT_SRC_INTFDAEX_MSK				(0x8)
-#define ETHER_INT_SRC_INTBLEX_OFST				(4)
-#define ETHER_INT_SRC_INTBLEX_MSK				(0x10)
-#define ETHER_INT_SRC_SWINT_OFST				(5)
-#define ETHER_INT_SRC_SWINT_MSK					(0x20)
-#define ETHER_INT_SRC_INTEARNOT_OFST			(6)
-#define ETHER_INT_SRC_INTEARNOT_MSK				(0x40)
-#define ETHER_INT_SRC_DMPARERR_OFST				(7)
-#define ETHER_INT_SRC_DMPARERR_MSK				(0x80)
-#define ETHER_INT_SRC_INTEXBD_OFST				(8)
-#define ETHER_INT_SRC_INTEXBD_MSK				(0x100)
-#define ETHER_INT_SRC_INTTXCTLCMP_OFST			(9)
-#define ETHER_INT_SRC_INTTXCTLCMP_MSK			(0x200)
-#define ETHER_INT_SRC_INTNRABT_OFST				(10)
-#define ETHER_INT_SRC_INTNRABT_MSK				(0x400)
-#define ETHER_INT_SRC_FDAEX_OFST				(11)
-#define ETHER_INT_SRC_FDAEX_MSK					(0x800)
-#define ETHER_INT_SRC_BLEX_OFST					(12)
-#define ETHER_INT_SRC_BLEX_MSK					(0x1000)
-#define ETHER_INT_SRC_DMPARERRSTAT_OFST			(13)
-#define ETHER_INT_SRC_DMPARERRSTAT_MSK			(0x2000)
-#define ETHER_INT_SRC_NRABT_OFST				(14)
-#define ETHER_INT_SRC_NRABT_MSK					(0x4000)
-#define ETHER_INT_SRC_INTLINK_OFST				(15)
-#define ETHER_INT_SRC_INTLINK_MSK				(0x8000)
-#define ETHER_INT_SRC_INTEXDEFER_OFST			(16)
-#define ETHER_INT_SRC_INTEXDEFER_MSK			(0x10000)
-#define ETHER_INT_SRC_INTRMON_OFST				(17)
-#define ETHER_INT_SRC_INTRMON_MSK				(0x20000)
-#define ETHER_INT_SRC_IRQ_MSK					(0x83FF)
-
-#define ETHER_PAUSECNT(base)							(ETHER00_TYPE (base + 0x40))
-#define ETHER_PAUSECNT_COUNT_OFST				(0)
-#define ETHER_PAUSECNT_COUNT_MSK				(0xFFFF)
-
-#define ETHER_REMPAUCNT(base)							(ETHER00_TYPE (base + 0x44))
-#define ETHER_REMPAUCNT_COUNT_OFST				(0)
-#define ETHER_REMPAUCNT_COUNT_MSK				(0xFFFF)
-
-#define ETHER_TXCONFRMSTAT(base)						(ETHER00_TYPE (base + 0x348))
-#define ETHER_TXCONFRMSTAT_TS_STAT_VALUE_OFST	(0)
-#define ETHER_TXCONFRMSTAT_TS_STAT_VALUE_MSK	(0x3FFFFF)
-
-#define ETHER_MAC_CTL(base)							(ETHER00_TYPE (base + 0))
-#define ETHER_MAC_CTL_HALTREQ_OFST				(0)
-#define ETHER_MAC_CTL_HALTREQ_MSK				(0x1)
-#define ETHER_MAC_CTL_HALTIMM_OFST				(1)
-#define ETHER_MAC_CTL_HALTIMM_MSK				(0x2)
-#define ETHER_MAC_CTL_RESET_OFST				(2)
-#define ETHER_MAC_CTL_RESET_MSK					(0x4)
-#define ETHER_MAC_CTL_FULLDUP_OFST				(3)
-#define ETHER_MAC_CTL_FULLDUP_MSK				(0x8)
-#define ETHER_MAC_CTL_MACLOOP_OFST				(4)
-#define ETHER_MAC_CTL_MACLOOP_MSK				(0x10)
-#define ETHER_MAC_CTL_CONN_OFST					(5)
-#define ETHER_MAC_CTL_CONN_MSK					(0x60)
-#define ETHER_MAC_CTL_LOOP10_OFST				(7)
-#define ETHER_MAC_CTL_LOOP10_MSK				(0x80)
-#define ETHER_MAC_CTL_LNKCHG_OFST				(8)
-#define ETHER_MAC_CTL_LNKCHG_MSK				(0x100)
-#define ETHER_MAC_CTL_MISSROLL_OFST				(10)
-#define ETHER_MAC_CTL_MISSROLL_MSK				(0x400)
-#define ETHER_MAC_CTL_ENMISSROLL_OFST			(13)
-#define ETHER_MAC_CTL_ENMISSROLL_MSK			(0x2000)
-#define ETHER_MAC_CTL_LINK10_OFST				(15)
-#define ETHER_MAC_CTL_LINK10_MSK				(0x8000)
-
-#define ETHER_ARC_CTL(base)							(ETHER00_TYPE (base + 0x4))
-#define	ETHER_ARC_CTL_STATIONACC_OFST			(0)
-#define	ETHER_ARC_CTL_STATIONACC_MSK			(0x1)
-#define	ETHER_ARC_CTL_GROUPACC_OFST				(1)
-#define	ETHER_ARC_CTL_GROUPACC_MSK				(0x2)
-#define	ETHER_ARC_CTL_BROADACC_OFST				(2)
-#define	ETHER_ARC_CTL_BROADACC_MSK				(0x4)
-#define	ETHER_ARC_CTL_NEGARC_OFST				(3)
-#define	ETHER_ARC_CTL_NEGARC_MSK				(0x8)
-#define	ETHER_ARC_CTL_COMPEN_OFST				(4)
-#define	ETHER_ARC_CTL_COMPEN_MSK				(0x10)
-
-#define ETHER_TX_CTL(base)							(ETHER00_TYPE (base + 0x8))
-#define ETHER_TX_CTL_TXEN_OFST					(0)
-#define ETHER_TX_CTL_TXEN_MSK					(0x1)
-#define ETHER_TX_CTL_TXHALT_OFST				(1)
-#define ETHER_TX_CTL_TXHALT_MSK					(0x2)
-#define ETHER_TX_CTL_NOPAD_OFST					(2)
-#define ETHER_TX_CTL_NOPAD_MSK					(0x4)
-#define ETHER_TX_CTL_NOCRC_OFST					(3)
-#define ETHER_TX_CTL_NOCRC_MSK					(0x8)
-#define ETHER_TX_CTL_FBACK_OFST					(4)
-#define ETHER_TX_CTL_FBACK_MSK					(0x10)
-#define ETHER_TX_CTL_NOEXDEF_OFST				(5)
-#define ETHER_TX_CTL_NOEXDEF_MSK				(0x20)
-#define ETHER_TX_CTL_SDPAUSE_OFST				(6)
-#define ETHER_TX_CTL_SDPAUSE_MSK				(0x40)
-#define ETHER_TX_CTL_MII10_OFST					(7)
-#define ETHER_TX_CTL_MII10_MSK					(0x80)
-#define ETHER_TX_CTL_ENUNDER_OFST				(8)
-#define ETHER_TX_CTL_ENUNDER_MSK				(0x100)
-#define ETHER_TX_CTL_ENEXDEFER_OFST				(9)
-#define ETHER_TX_CTL_ENEXDEFER_MSK				(0x200)
-#define ETHER_TX_CTL_ENLCARR_OFST				(10)
-#define ETHER_TX_CTL_ENLCARR_MSK				(0x400)
-#define ETHER_TX_CTL_ENEXCOLL_OFST				(11)
-#define ETHER_TX_CTL_ENEXCOLL_MSK				(0x800)
-#define ETHER_TX_CTL_ENLATECOLL_OFST				(12)
-#define ETHER_TX_CTL_ENLATECOLL_MSK				(0x1000)
-#define ETHER_TX_CTL_ENTXPAR_OFST				(13)
-#define ETHER_TX_CTL_ENTXPAR_MSK				(0x2000)
-#define ETHER_TX_CTL_ENCOMP_OFST				(14)
-#define ETHER_TX_CTL_ENCOMP_MSK					(0x4000)
-
-#define ETHER_TX_STAT(base)							(ETHER00_TYPE (base + 0xc))
-#define ETHER_TX_STAT_TXCOLL_OFST				(0)
-#define ETHER_TX_STAT_TXCOLL_MSK				(0xF)
-#define ETHER_TX_STAT_EXCOLL_OFST				(4)
-#define ETHER_TX_STAT_EXCOLL_MSK				(0x10)
-#define ETHER_TX_STAT_TXDEFER_OFST				(5)
-#define ETHER_TX_STAT_TXDEFER_MSK				(0x20)
-#define ETHER_TX_STAT_PAUSED_OFST				(6)
-#define ETHER_TX_STAT_PAUSED_MSK				(0x40)
-#define ETHER_TX_STAT_INTTX_OFST				(7)
-#define ETHER_TX_STAT_INTTX_MSK					(0x80)
-#define ETHER_TX_STAT_UNDER_OFST				(8)
-#define ETHER_TX_STAT_UNDER_MSK					(0x100)
-#define ETHER_TX_STAT_EXDEFER_OFST				(9)
-#define ETHER_TX_STAT_EXDEFER_MSK				(0x200)
-#define ETHER_TX_STAT_LCARR_OFST				(10)
-#define ETHER_TX_STAT_LCARR_MSK					(0x400)
-#define ETHER_TX_STAT_TX10STAT_OFST				(11)
-#define ETHER_TX_STAT_TX10STAT_MSK				(0x800)
-#define ETHER_TX_STAT_LATECOLL_OFST				(12)
-#define ETHER_TX_STAT_LATECOLL_MSK				(0x1000)
-#define ETHER_TX_STAT_TXPAR_OFST				(13)
-#define ETHER_TX_STAT_TXPAR_MSK					(0x2000)
-#define ETHER_TX_STAT_COMP_OFST					(14)
-#define ETHER_TX_STAT_COMP_MSK					(0x4000)
-#define ETHER_TX_STAT_TXHALTED_OFST				(15)
-#define ETHER_TX_STAT_TXHALTED_MSK				(0x8000)
-#define ETHER_TX_STAT_SQERR_OFST				(16)
-#define ETHER_TX_STAT_SQERR_MSK					(0x10000)
-#define ETHER_TX_STAT_TXMCAST_OFST				(17)
-#define ETHER_TX_STAT_TXMCAST_MSK				(0x20000)
-#define ETHER_TX_STAT_TXBCAST_OFST				(18)
-#define ETHER_TX_STAT_TXBCAST_MSK				(0x40000)
-#define ETHER_TX_STAT_VLAN_OFST					(19)
-#define ETHER_TX_STAT_VLAN_MSK					(0x80000)
-#define ETHER_TX_STAT_MACC_OFST					(20)
-#define ETHER_TX_STAT_MACC_MSK					(0x100000)
-#define ETHER_TX_STAT_TXPAUSE_OFST				(21)
-#define ETHER_TX_STAT_TXPAUSE_MSK				(0x200000)
-
-#define ETHER_RX_CTL(base)							(ETHER00_TYPE (base + 0x10))
-#define ETHER_RX_CTL_RXEN_OFST					(0)
-#define ETHER_RX_CTL_RXEN_MSK					(0x1)
-#define ETHER_RX_CTL_RXHALT_OFST				(1)
-#define ETHER_RX_CTL_RXHALT_MSK					(0x2)
-#define ETHER_RX_CTL_LONGEN_OFST				(2)
-#define ETHER_RX_CTL_LONGEN_MSK					(0x4)
-#define ETHER_RX_CTL_SHORTEN_OFST				(3)
-#define ETHER_RX_CTL_SHORTEN_MSK				(0x8)
-#define ETHER_RX_CTL_STRIPCRC_OFST				(4)
-#define ETHER_RX_CTL_STRIPCRC_MSK				(0x10)
-#define ETHER_RX_CTL_PASSCTL_OFST				(5)
-#define ETHER_RX_CTL_PASSCTL_MSK				(0x20)
-#define ETHER_RX_CTL_IGNORECRC_OFST				(6)
-#define ETHER_RX_CTL_IGNORECRC_MSK				(0x40)
-#define ETHER_RX_CTL_ENALIGN_OFST				(8)
-#define ETHER_RX_CTL_ENALIGN_MSK				(0x100)
-#define ETHER_RX_CTL_ENCRCERR_OFST				(9)
-#define ETHER_RX_CTL_ENCRCERR_MSK				(0x200)
-#define ETHER_RX_CTL_ENOVER_OFST				(10)
-#define ETHER_RX_CTL_ENOVER_MSK					(0x400)
-#define ETHER_RX_CTL_ENLONGERR_OFST				(11)
-#define ETHER_RX_CTL_ENLONGERR_MSK				(0x800)
-#define ETHER_RX_CTL_ENRXPAR_OFST				(13)
-#define ETHER_RX_CTL_ENRXPAR_MSK				(0x2000)
-#define ETHER_RX_CTL_ENGOOD_OFST				(14)
-#define ETHER_RX_CTL_ENGOOD_MSK					(0x4000)
-
-#define ETHER_RX_STAT(base)							(ETHER00_TYPE (base + 0x14))
-#define ETHER_RX_STAT_LENERR_OFST				(4)
-#define ETHER_RX_STAT_LENERR_MSK				(0x10)
-#define ETHER_RX_STAT_CTLRECD_OFST				(5)
-#define ETHER_RX_STAT_CTLRECD_MSK				(0x20)
-#define ETHER_RX_STAT_INTRX_OFST				(6)
-#define ETHER_RX_STAT_INTRX_MSK					(0x40)
-#define ETHER_RX_STAT_RX10STAT_OFST				(7)
-#define ETHER_RX_STAT_RX10STAT_MSK				(0x80)
-#define ETHER_RX_STAT_ALIGNERR_OFST				(8)
-#define ETHER_RX_STAT_ALIGNERR_MSK				(0x100)
-#define ETHER_RX_STAT_CRCERR_OFST				(9)
-#define ETHER_RX_STAT_CRCERR_MSK				(0x200)
-#define ETHER_RX_STAT_OVERFLOW_OFST				(10)
-#define ETHER_RX_STAT_OVERFLOW_MSK				(0x400)
-#define ETHER_RX_STAT_LONGERR_OFST				(11)
-#define ETHER_RX_STAT_LONGERR_MSK				(0x800)
-#define ETHER_RX_STAT_RXPAR_OFST				(13)
-#define ETHER_RX_STAT_RXPAR_MSK					(0x2000)
-#define ETHER_RX_STAT_GOOD_OFST					(14)
-#define ETHER_RX_STAT_GOOD_MSK					(0x4000)
-#define ETHER_RX_STAT_RXHALTED_OFST				(15)
-#define ETHER_RX_STAT_RXHALTED_MSK				(0x8000)
-#define ETHER_RX_STAT_RXMCAST_OFST				(17)
-#define ETHER_RX_STAT_RXMCAST_MSK				(0x10000)
-#define ETHER_RX_STAT_RXBCAST_OFST				(18)
-#define ETHER_RX_STAT_RXBCAST_MSK				(0x20000)
-#define ETHER_RX_STAT_RXVLAN_OFST				(19)
-#define ETHER_RX_STAT_RXVLAN_MSK				(0x40000)
-#define ETHER_RX_STAT_RXPAUSE_OFST				(20)
-#define ETHER_RX_STAT_RXPAUSE_MSK				(0x80000)
-#define ETHER_RX_STAT_ARCSTATUS_OFST				(21)
-#define ETHER_RX_STAT_ARCSTATUS_MSK				(0xF00000)
-#define ETHER_RX_STAT_ARCENT_OFST				(25)
-#define ETHER_RX_STAT_ARCENT_MSK				(0x1F000000)
-
-#define ETHER_MD_DATA(base)							(ETHER00_TYPE (base + 0x18))
-
-#define ETHER_MD_CA(base)								(ETHER00_TYPE (base + 0x1c))
-#define ETHER_MD_CA_ADDR_OFST					(0)
-#define ETHER_MD_CA_ADDR_MSK					(0x1F)
-#define ETHER_MD_CA_PHY_OFST					(5)
-#define ETHER_MD_CA_PHY_MSK					(0x3E0)
-#define ETHER_MD_CA_WR_OFST					(10)
-#define ETHER_MD_CA_WR_MSK					(0x400)
-#define ETHER_MD_CA_BUSY_OFST					(11)
-#define ETHER_MD_CA_BUSY_MSK					(0x800)
-#define ETHER_MD_CA_PRESUPP_OFST				(12)
-#define ETHER_MD_CA_PRESUPP_MSK					(0x1000)
-
-#define ETHER_ARC_ADR(base)	      (ETHER00_TYPE (base + 0x160))
-#define ETHER_ARC_ADR_ARC_LOC_OFST				(2)
-#define ETHER_ARC_ADR_ARC_LOC_MSK				(0xFFC)
-
-#define ETHER_ARC_DATA(base)  (ETHER00_TYPE (base + 0x364))
-
-#define ETHER_ARC_ENA(base)   (ETHER00_TYPE (base + 0x28))
-#define ETHER_ARC_ENA_MSK					(0x1FFFFF)
-
-#define ETHER_PROM_CTL(base)							(ETHER00_TYPE (base + 0x2c))
-#define ETHER_PROM_CTL_PROM_ADDR_OFST			(0)
-#define ETHER_PROM_CTL_PROM_ADDR_MSK			(0x3F)
-#define ETHER_PROM_CTL_OPCODE_OFST				(13)
-#define ETHER_PROM_CTL_OPCODE_MSK				(0x6000)
-#define ETHER_PROM_CTL_OPCODE_READ_MSK			(0x4000)
-#define ETHER_PROM_CTL_OPCODE_WRITE_MSK			(0x2000)
-#define ETHER_PROM_CTL_OPCODE_ERASE_MSK			(0x6000)
-#define ETHER_PROM_CTL_ENABLE_MSK				(0x0030)
-#define ETHER_PROM_CTL_DISABLE_MSK				(0x0000)
-#define ETHER_PROM_CTL_BUSY_OFST				(15)
-#define ETHER_PROM_CTL_BUSY_MSK					(0x8000)
-
-#define ETHER_PROM_DATA(base)							(ETHER00_TYPE (base + 0x30))
-
-#define ETHER_MISS_CNT(base)							(ETHER00_TYPE (base + 0x3c))
-#define ETHER_MISS_CNT_COUNT_OFST				(0)
-#define ETHER_MISS_CNT_COUNT_MSK				(0xFFFF)
-
-#define ETHER_CNTDATA(base)							(ETHER00_TYPE (base + 0x80))
-
-#define ETHER_CNTACC(base)							(ETHER00_TYPE (base + 0x84))
-#define ETHER_CNTACC_ADDR_OFST					(0)
-#define ETHER_CNTACC_ADDR_MSK					(0xFF)
-#define ETHER_CNTACC_WRRDN_OFST					(8)
-#define ETHER_CNTACC_WRRDN_MSK					(0x100)
-#define ETHER_CNTACC_CLEAR_OFST					(9)
-#define ETHER_CNTACC_CLEAR_MSK					(0x200)
-
-#define ETHER_TXRMINTEN(base)							(ETHER00_TYPE (base + 0x88))
-#define ETHER_TXRMINTEN_MSK						(0x3FFFFFFF)
-
-#define ETHER_RXRMINTEN(base)							(ETHER00_TYPE (base + 0x8C))
-#define ETHER_RXRMINTEN_MSK						(0xFFFFFF)
-
-/*
-*	RMON Registers
-*/
-#define		RMON_COLLISION0						0x0
-#define		RMON_COLLISION1						0x1
-#define		RMON_COLLISION2						0x2
-#define		RMON_COLLISION3						0x3
-#define		RMON_COLLISION4						0x4
-#define		RMON_COLLISION5						0x5
-#define		RMON_COLLISION6						0x6
-#define		RMON_COLLISION7						0x7
-#define		RMON_COLLISION8						0x8
-#define		RMON_COLLISION9						0x9
-#define		RMON_COLLISION10					0xa
-#define		RMON_COLLISION11					0xb
-#define		RMON_COLLISION12					0xc
-#define		RMON_COLLISION13					0xd
-#define		RMON_COLLISION14					0xe
-#define		RMON_COLLISION15					0xf
-#define		RMON_COLLISION16					0x10
-#define		RMON_FRAMES_WITH_DEFERRED_XMISSIONS	0x11
-#define		RMON_LATE_COLLISIONS				0x12
-#define		RMON_FRAMES_LOST_DUE_TO_MAC_XMIT	0x13
-#define		RMON_CARRIER_SENSE_ERRORS			0x14
-#define		RMON_FRAMES_WITH_EXCESSIVE_DEFERAL	0x15
-#define		RMON_UNICAST_FRAMES_TRANSMITTED_OK	0x16
-#define		RMON_MULTICAST_FRAMES_XMITTED_OK	0x17
-#define		RMON_BROADCAST_FRAMES_XMITTED_OK	0x18
-#define		RMON_SQE_TEST_ERRORS				0x19
-#define		RMON_PAUSE_MACCTRL_FRAMES_XMITTED	0x1A
-#define		RMON_MACCTRL_FRAMES_XMITTED			0x1B
-#define		RMON_VLAN_FRAMES_XMITTED			0x1C
-#define		RMON_OCTETS_XMITTED_OK				0x1D
-#define		RMON_OCTETS_XMITTED_OK_HI			0x1E
-
-#define		RMON_RX_PACKET_SIZES0				0x40
-#define		RMON_RX_PACKET_SIZES1				0x41
-#define		RMON_RX_PACKET_SIZES2				0x42
-#define		RMON_RX_PACKET_SIZES3				0x43
-#define		RMON_RX_PACKET_SIZES4				0x44
-#define		RMON_RX_PACKET_SIZES5				0x45
-#define		RMON_RX_PACKET_SIZES6				0x46
-#define		RMON_RX_PACKET_SIZES7				0x47
-#define		RMON_FRAME_CHECK_SEQUENCE_ERRORS	0x48
-#define		RMON_ALIGNMENT_ERRORS				0x49
-#define		RMON_FRAGMENTS						0x4A
-#define		RMON_JABBERS						0x4B
-#define		RMON_FRAMES_LOST_TO_INTMACRCVERR	0x4C
-#define		RMON_UNICAST_FRAMES_RCVD_OK			0x4D
-#define		RMON_MULTICAST_FRAMES_RCVD_OK		0x4E
-#define		RMON_BROADCAST_FRAMES_RCVD_OK		0x4F
-#define		RMON_IN_RANGE_LENGTH_ERRORS			0x50
-#define		RMON_OUT_OF_RANGE_LENGTH_ERRORS		0x51
-#define		RMON_VLAN_FRAMES_RCVD				0x52
-#define		RMON_PAUSE_MAC_CTRL_FRAMES_RCVD		0x53
-#define		RMON_MAC_CTRL_FRAMES_RCVD			0x54
-#define		RMON_OCTETS_RCVD_OK					0x55
-#define		RMON_OCTETS_RCVD_OK_HI				0x56
-#define		RMON_OCTETS_RCVD_OTHER				0x57
-#define		RMON_OCTETS_RCVD_OTHER_HI			0x58
-
-#endif /* __ETHER00_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/excalibur.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/excalibur.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/excalibur.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/excalibur.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,91 +0,0 @@
-/* megafunction wizard: %ARM-Based Excalibur%
-   GENERATION: STANDARD
-   VERSION: WM1.0
-   MODULE: ARM-Based Excalibur
-   PROJECT: excalibur
-   ============================================================
-   File Name: v:\embedded\linux\bootldr\excalibur.h
-   Megafunction Name(s): ARM-Based Excalibur
-   ============================================================
-
-   ************************************************************
-   THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
-   ************************************************************/
-
-#ifndef	EXCALIBUR_H_INCLUDED
-#define	EXCALIBUR_H_INCLUDED
-
-#define EXC_DEFINE_PROCESSOR_LITTLE_ENDIAN
-#define EXC_DEFINE_BOOT_FROM_FLASH
-
-#define	EXC_INPUT_CLK_FREQUENCY (50000000)
-#define	EXC_AHB1_CLK_FREQUENCY (150000000)
-#define	EXC_AHB2_CLK_FREQUENCY (75000000)
-#define	EXC_SDRAM_CLK_FREQUENCY (75000000)
-
-/* Registers Block */
-#define	EXC_REGISTERS_BASE (0x7fffc000)
-#define	EXC_MODE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x000)
-#define	EXC_IO_CTRL00_BASE (EXC_REGISTERS_BASE + 0x040)
-#define	EXC_MMAP00_BASE (EXC_REGISTERS_BASE + 0x080)
-#define	EXC_PLD_CONFIG00_BASE (EXC_REGISTERS_BASE + 0x140)
-#define	EXC_TIMER00_BASE (EXC_REGISTERS_BASE + 0x200)
-#define	EXC_INT_CTRL00_BASE (EXC_REGISTERS_BASE + 0xc00)
-#define	EXC_CLOCK_CTRL00_BASE (EXC_REGISTERS_BASE + 0x300)
-#define	EXC_WATCHDOG00_BASE (EXC_REGISTERS_BASE + 0xa00)
-#define	EXC_UART00_BASE (EXC_REGISTERS_BASE + 0x280)
-#define	EXC_EBI00_BASE (EXC_REGISTERS_BASE + 0x380)
-#define	EXC_SDRAM00_BASE (EXC_REGISTERS_BASE + 0x400)
-#define	EXC_AHB12_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x800)
-#define	EXC_PLD_STRIPE_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
-#define	EXC_STRIPE_PLD_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
-
-#define	EXC_REGISTERS_SIZE (0x00004000)
-
-/* EBI Block(s) */
-#define	EXC_EBI_BLOCK0_BASE (0x40000000)
-#define	EXC_EBI_BLOCK0_SIZE (0x00400000)
-#define	EXC_EBI_BLOCK0_WIDTH (8)
-#define	EXC_EBI_BLOCK0_NON_CACHEABLE
-#define	EXC_EBI_BLOCK1_BASE (0x40400000)
-#define	EXC_EBI_BLOCK1_SIZE (0x00400000)
-#define	EXC_EBI_BLOCK1_WIDTH (16)
-#define	EXC_EBI_BLOCK1_NON_CACHEABLE
-#define	EXC_EBI_BLOCK2_BASE (0x40800000)
-#define	EXC_EBI_BLOCK2_SIZE (0x00400000)
-#define	EXC_EBI_BLOCK2_WIDTH (16)
-#define	EXC_EBI_BLOCK2_NON_CACHEABLE
-#define	EXC_EBI_BLOCK3_BASE (0x40c00000)
-#define	EXC_EBI_BLOCK3_SIZE (0x00400000)
-#define	EXC_EBI_BLOCK3_WIDTH (16)
-#define	EXC_EBI_BLOCK3_NON_CACHEABLE
-
-/* SDRAM Block(s) */
-#define	EXC_SDRAM_BLOCK0_BASE (0x00000000)
-#define	EXC_SDRAM_BLOCK0_SIZE (0x04000000)
-#define	EXC_SDRAM_BLOCK0_WIDTH (32)
-#define	EXC_SDRAM_BLOCK1_BASE (0x04000000)
-#define	EXC_SDRAM_BLOCK1_SIZE (0x04000000)
-#define	EXC_SDRAM_BLOCK1_WIDTH (32)
-
-/* Single Port SRAM Block(s) */
-#define	EXC_SPSRAM_BLOCK0_BASE (0x08000000)
-#define	EXC_SPSRAM_BLOCK0_SIZE (0x00020000)
-#define	EXC_SPSRAM_BLOCK1_BASE (0x08020000)
-#define	EXC_SPSRAM_BLOCK1_SIZE (0x00020000)
-
-/* PLD Block(s) */
-#define	EXC_PLD_BLOCK0_BASE (0x80000000)
-#define	EXC_PLD_BLOCK0_SIZE (0x00004000)
-#define	EXC_PLD_BLOCK0_NON_CACHEABLE
-#define	EXC_PLD_BLOCK1_BASE (0xf000000)
-#define	EXC_PLD_BLOCK1_SIZE (0x00004000)
-#define	EXC_PLD_BLOCK1_NON_CACHEABLE
-#define	EXC_PLD_BLOCK2_BASE (0x80008000)
-#define	EXC_PLD_BLOCK2_SIZE (0x00004000)
-#define	EXC_PLD_BLOCK2_NON_CACHEABLE
-#define	EXC_PLD_BLOCK3_BASE (0x8000c000)
-#define	EXC_PLD_BLOCK3_SIZE (0x00004000)
-#define	EXC_PLD_BLOCK3_NON_CACHEABLE
-
-#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/hardware.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/hardware.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/hardware.h	2001-11-09 14:11:14.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/hardware.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,64 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10/hardware.h
- *
- *  This file contains the hardware definitions of the Integrator.
- *
- *  Copyright (C) 1999 ARM Limited.
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include <asm/arch/platform.h>
-
-/*
- * Where in virtual memory the IO devices (timers, system controllers
- * and so on)
- */
-#define IO_BASE			0xf0000000                 // VA of IO 
-#define IO_SIZE			0x10000000                 // How much?
-#define IO_START		EXC_REGISTERS_BASE              // PA of IO
-/* macro to get at IO space when running virtually */
-#define IO_ADDRESS(x) ((x) | 0xf0000000) 
-
-#define FLASH_VBASE             0xFE000000
-#define FLASH_SIZE              0x01000000
-#define FLASH_START             EXC_EBI_BLOCK0_BASE
-#define FLASH_VADDR(x) ((x)|0xFE000000)
-/*
- * Similar to above, but for PCI addresses (memory, IO, Config and the
- * V3 chip itself).  WARNING: this has to mirror definitions in platform.h
- */
-#if 0
-#define PCI_MEMORY_VADDR        0xe8000000
-#define PCI_CONFIG_VADDR        0xec000000
-#define PCI_V3_VADDR            0xed000000
-#define PCI_IO_VADDR            0xee000000
-
-#define PCIO_BASE		PCI_IO_VADDR
-#define PCIMEM_BASE		PCI_MEMORY_VADDR
-
-
-#define pcibios_assign_all_busses()	1
-
-#define PCIBIOS_MIN_IO		0x6000
-#define PCIBIOS_MIN_MEM 	0x00100000
-#endif
-
-
-#endif
-
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/int_ctrl00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/int_ctrl00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/int_ctrl00.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/int_ctrl00.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,288 +0,0 @@
-/*
- *  
- *  This file contains the register definitions for the Excalibur
- *  Timer TIMER00.
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __INT_CTRL00_H
-#define __INT_CTRL00_H
-
-#define INT_MS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x00 ))
-#define INT_MS_FC_MSK (0x10000)
-#define INT_MS_FC_OFST (16)
-#define INT_MS_M1_MSK (0x8000)
-#define INT_MS_M1_OFST (15)
-#define INT_MS_M0_MSK (0x4000)
-#define INT_MS_M0_OFST (14)
-#define INT_MS_AE_MSK (0x2000)
-#define INT_MS_AE_OFST (13)
-#define INT_MS_PE_MSK (0x1000)
-#define INT_MS_PE_OFST (12)
-#define INT_MS_EE_MSK (0x0800)
-#define INT_MS_EE_OFST (11)
-#define INT_MS_PS_MSK (0x0400)
-#define INT_MS_PS_OFST (10)
-#define INT_MS_T1_MSK (0x0200)
-#define INT_MS_T1_OFST (9)
-#define INT_MS_T0_MSK (0x0100)
-#define INT_MS_T0_OFST (8)
-#define INT_MS_UA_MSK (0x0080)
-#define INT_MS_UA_OFST (7)
-#define INT_MS_IP_MSK (0x0040)
-#define INT_MS_IP_OFST (6)
-#define INT_MS_P5_MSK (0x0020)
-#define INT_MS_P5_OFST (5)
-#define INT_MS_P4_MSK (0x0010)
-#define INT_MS_P4_OFST (4)
-#define INT_MS_P3_MSK (0x0008)
-#define INT_MS_P3_OFST (3)
-#define INT_MS_P2_MSK (0x0004)
-#define INT_MS_P2_OFST (2)
-#define INT_MS_P1_MSK (0x0002)
-#define INT_MS_P1_OFST (1)
-#define INT_MS_P0_MSK (0x0001)
-#define INT_MS_P0_OFST (0)
-
-#define INT_MC(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x04 ))
-#define INT_MC_FC_MSK (0x10000)
-#define INT_MC_FC_OFST (16)
-#define INT_MC_M1_MSK (0x8000)
-#define INT_MC_M1_OFST (15)
-#define INT_MC_M0_MSK (0x4000)
-#define INT_MC_M0_OFST (14)
-#define INT_MC_AE_MSK (0x2000)
-#define INT_MC_AE_OFST (13)
-#define INT_MC_PE_MSK (0x1000)
-#define INT_MC_PE_OFST (12)
-#define INT_MC_EE_MSK (0x0800)
-#define INT_MC_EE_OFST (11)
-#define INT_MC_PS_MSK (0x0400)
-#define INT_MC_PS_OFST (10)
-#define INT_MC_T1_MSK (0x0200)
-#define INT_MC_T1_OFST (9)
-#define INT_MC_T0_MSK (0x0100)
-#define INT_MC_T0_OFST (8)
-#define INT_MC_UA_MSK (0x0080)
-#define INT_MC_UA_OFST (7)
-#define INT_MC_IP_MSK (0x0040)
-#define INT_MC_IP_OFST (6)
-#define INT_MC_P5_MSK (0x0020)
-#define INT_MC_P5_OFST (5)
-#define INT_MC_P4_MSK (0x0010)
-#define INT_MC_P4_OFST (4)
-#define INT_MC_P3_MSK (0x0008)
-#define INT_MC_P3_OFST (3)
-#define INT_MC_P2_MSK (0x0004)
-#define INT_MC_P2_OFST (2)
-#define INT_MC_P1_MSK (0x0002)
-#define INT_MC_P1_OFST (1)
-#define INT_MC_P0_MSK (0x0001)
-#define INT_MC_P0_OFST (0)
-
-#define INT_SS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x08 ))
-#define INT_SS_FC_SSK (0x8000)
-#define INT_SS_FC_OFST (15)
-#define INT_SS_M1_SSK (0x8000)
-#define INT_SS_M1_OFST (15)
-#define INT_SS_M0_SSK (0x4000)
-#define INT_SS_M0_OFST (14)
-#define INT_SS_AE_SSK (0x2000)
-#define INT_SS_AE_OFST (13)
-#define INT_SS_PE_SSK (0x1000)
-#define INT_SS_PE_OFST (12)
-#define INT_SS_EE_SSK (0x0800)
-#define INT_SS_EE_OFST (11)
-#define INT_SS_PS_SSK (0x0400)
-#define INT_SS_PS_OFST (10)
-#define INT_SS_T1_SSK (0x0200)
-#define INT_SS_T1_OFST (9)
-#define INT_SS_T0_SSK (0x0100)
-#define INT_SS_T0_OFST (8)
-#define INT_SS_UA_SSK (0x0080)
-#define INT_SS_UA_OFST (7)
-#define INT_SS_IP_SSK (0x0040)
-#define INT_SS_IP_OFST (6)
-#define INT_SS_P5_SSK (0x0020)
-#define INT_SS_P5_OFST (5)
-#define INT_SS_P4_SSK (0x0010)
-#define INT_SS_P4_OFST (4)
-#define INT_SS_P3_SSK (0x0008)
-#define INT_SS_P3_OFST (3)
-#define INT_SS_P2_SSK (0x0004)
-#define INT_SS_P2_OFST (2)
-#define INT_SS_P1_SSK (0x0002)
-#define INT_SS_P1_OFST (1)
-#define INT_SS_P0_SSK (0x0001)
-#define INT_SS_P0_OFST (0)
-
-#define INT_RS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x0C ))
-#define INT_RS_FC_RSK (0x10000)
-#define INT_RS_FC_OFST (16)
-#define INT_RS_M1_RSK (0x8000)
-#define INT_RS_M1_OFST (15)
-#define INT_RS_M0_RSK (0x4000)
-#define INT_RS_M0_OFST (14)
-#define INT_RS_AE_RSK (0x2000)
-#define INT_RS_AE_OFST (13)
-#define INT_RS_PE_RSK (0x1000)
-#define INT_RS_PE_OFST (12)
-#define INT_RS_EE_RSK (0x0800)
-#define INT_RS_EE_OFST (11)
-#define INT_RS_PS_RSK (0x0400)
-#define INT_RS_PS_OFST (10)
-#define INT_RS_T1_RSK (0x0200)
-#define INT_RS_T1_OFST (9)
-#define INT_RS_T0_RSK (0x0100)
-#define INT_RS_T0_OFST (8)
-#define INT_RS_UA_RSK (0x0080)
-#define INT_RS_UA_OFST (7)
-#define INT_RS_IP_RSK (0x0040)
-#define INT_RS_IP_OFST (6)
-#define INT_RS_P5_RSK (0x0020)
-#define INT_RS_P5_OFST (5)
-#define INT_RS_P4_RSK (0x0010)
-#define INT_RS_P4_OFST (4)
-#define INT_RS_P3_RSK (0x0008)
-#define INT_RS_P3_OFST (3)
-#define INT_RS_P2_RSK (0x0004)
-#define INT_RS_P2_OFST (2)
-#define INT_RS_P1_RSK (0x0002)
-#define INT_RS_P1_OFST (1)
-#define INT_RS_P0_RSK (0x0001)
-#define INT_RS_P0_OFST (0)
-
-#define INT_ID(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x10 ))
-#define INT_ID_ID_MSK (0x3F)
-#define INT_ID_ID_OFST (0)
-
-#define INT_PLD_PRIORITY(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x14 ))
-#define INT_PLD_PRIORITY_PRI_MSK (0x3F)
-#define INT_PLD_PRIORITY_PRI_OFST (0)
-#define INT_PLD_PRIORITY_GA_MSK (0x40)
-#define INT_PLD_PRIORITY_GA_OFST (6)
-
-#define INT_MODE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x18 ))
-#define INT_MODE_MODE_MSK (0x3)
-#define INT_MODE_MODE_OFST (0)
-
-#define INT_PRIORITY_P0(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x80 ))
-#define INT_PRIORITY_P0_PRI_MSK (0x3F)
-#define INT_PRIORITY_P0_PRI_OFST (0)
-#define INT_PRIORITY_P0_FQ_MSK (0x40)
-#define INT_PRIORITY_P0_FQ_OFST (6)
-
-#define INT_PRIORITY_P1(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x84 ))
-#define INT_PRIORITY_P1_PRI_MSK (0x3F)
-#define INT_PRIORITY_P1_PRI_OFST (0)
-#define INT_PRIORITY_P1_FQ_MSK (0x40)
-#define INT_PRIORITY_P1_FQ_OFST (6)
-
-#define INT_PRIORITY_P2(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x88 ))
-#define INT_PRIORITY_P2_PRI_MSK (0x3F)
-#define INT_PRIORITY_P2_PRI_OFST (0)
-#define INT_PRIORITY_P2_FQ_MSK (0x40)
-#define INT_PRIORITY_P2_FQ_OFST (6)
-
-#define INT_PRIORITY_P3(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x8C ))
-#define INT_PRIORITY_P3_PRI_MSK (0x3F)
-#define INT_PRIORITY_P3_PRI_OFST (0)
-#define INT_PRIORITY_P3_FQ_MSK (0x40)
-#define INT_PRIORITY_P3_FQ_OFST (6)
-
-#define INT_PRIORITY_P4(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x90 ))
-#define INT_PRIORITY_P4_PRI_MSK (0x3F)
-#define INT_PRIORITY_P4_PRI_OFST (0)
-#define INT_PRIORITY_P4_FQ_MSK (0x40)
-#define INT_PRIORITY_P4_FQ_OFST (6)
-
-#define INT_PRIORITY_P5(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x94 ))
-#define INT_PRIORITY_P5_PRI_MSK (0x3F)
-#define INT_PRIORITY_P5_PRI_OFST (0)
-#define INT_PRIORITY_P5_FQ_MSK (0x40)
-#define INT_PRIORITY_P5_FQ_OFST (6)
-
-#define INT_PRIORITY_IP(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x94 ))
-#define INT_PRIORITY_IP_PRI_MSK (0x3F)
-#define INT_PRIORITY_IP_PRI_OFST (0)
-#define INT_PRIORITY_IP_FQ_MSK (0x40)
-#define INT_PRIORITY_IP_FQ_OFST (6)
-
-#define INT_PRIORITY_UA(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x9C ))
-#define INT_PRIORITY_UA_PRI_MSK (0x3F)
-#define INT_PRIORITY_UA_PRI_OFST (0)
-#define INT_PRIORITY_UA_FQ_MSK (0x40)
-#define INT_PRIORITY_UA_FQ_OFST (6)
-
-#define INT_PRIORITY_T0(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xA0 ))
-#define INT_PRIORITY_T0_PRI_MSK (0x3F)
-#define INT_PRIORITY_T0_PRI_OFST (0)
-#define INT_PRIORITY_T0_FQ_MSK (0x40)
-#define INT_PRIORITY_T0_FQ_OFST (6)
-
-#define INT_PRIORITY_T1(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xA4 ))
-#define INT_PRIORITY_T1_PRI_MSK (0x3F)
-#define INT_PRIORITY_T1_PRI_OFST (0)
-#define INT_PRIORITY_T1_FQ_MSK (0x40)
-#define INT_PRIORITY_T1_FQ_OFST (6)
-
-#define INT_PRIORITY_PS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xA8 ))
-#define INT_PRIORITY_PS_PRI_MSK (0x3F)
-#define INT_PRIORITY_PS_PRI_OFST (0)
-#define INT_PRIORITY_PS_FQ_MSK (0x40)
-#define INT_PRIORITY_PS_FQ_OFST (6)
-
-#define INT_PRIORITY_EE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xAC ))
-#define INT_PRIORITY_EE_PRI_MSK (0x3F)
-#define INT_PRIORITY_EE_PRI_OFST (0)
-#define INT_PRIORITY_EE_FQ_MSK (0x40)
-#define INT_PRIORITY_EE_FQ_OFST (6)
-
-#define INT_PRIORITY_PE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xB0 ))
-#define INT_PRIORITY_PE_PRI_MSK (0x3F)
-#define INT_PRIORITY_PE_PRI_OFST (0)
-#define INT_PRIORITY_PE_FQ_MSK (0x40)
-#define INT_PRIORITY_PE_FQ_OFST (6)
-
-#define INT_PRIORITY_AE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xB4 ))
-#define INT_PRIORITY_AE_PRI_MSK (0x3F)
-#define INT_PRIORITY_AE_PRI_OFST (0)
-#define INT_PRIORITY_AE_FQ_MSK (0x40)
-#define INT_PRIORITY_AE_FQ_OFST (6)
-
-#define INT_PRIORITY_M0(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xB8 ))
-#define INT_PRIORITY_M0_PRI_MSK (0x3F)
-#define INT_PRIORITY_M0_PRI_OFST (0)
-#define INT_PRIORITY_M0_FQ_MSK (0x40)
-#define INT_PRIORITY_M0_FQ_OFST (6)
-
-#define INT_PRIORITY_M1(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xBC ))
-#define INT_PRIORITY_M1_PRI_MSK (0x3F)
-#define INT_PRIORITY_M1_PRI_OFST (0)
-#define INT_PRIORITY_M1_FQ_MSK (0x40)
-#define INT_PRIORITY_M1_FQ_OFST (6)
-
-#define INT_PRIORITY_FC(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xC0 ))
-#define INT_PRIORITY_FC_PRI_MSK (0x3F)
-#define INT_PRIORITY_FC_PRI_OFST (0)
-#define INT_PRIORITY_FC_FQ_MSK (0x40)
-#define INT_PRIORITY_FC_FQ_OFST (6)
-
-#endif /* __INT_CTRL00_H */
-
-
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/io.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/io.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/io.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/io.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,46 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10db/io.h
- *
- *  Copyright (C) 1999 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#define IO_SPACE_LIMIT 0xffff
-
-
-/*
- * Generic virtual read/write
- */
-#define __arch_getw(a)		(*(volatile unsigned short *)(a))
-#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
-/*#define outsw   __arch_writesw
-#define outsl   __arch_writesl
-#define outsb   __arch_writesb
-#define insb    __arch_readsb
-#define insw    __arch_readsw
-#define insl    __arch_readsl*/
-
-#define __io(a)			(a)
-#define __mem_pci(a)            (a) 
-#define __arch_getw(a)			(*(volatile unsigned short  *)(a))
-#define __arch_putw(v,a)		(*(volatile unsigned short *)(a) = (v))
-#define iomem_valid_addr(off,size) (1)
-#define iomem_to_phys(off) (off)
-
-
-#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/irq.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/irq.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/irq.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/irq.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,20 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10/irq.h
- *
- *  Copyright (C) 1999 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#define fixup_irq(i)	(i)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/irqs.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/irqs.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/irqs.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/irqs.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,45 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-camelot/irqs.h
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/* Use the Excalibur chip definitions */
-#define INT_CTRL00_TYPE
-#include "asm/arch/int_ctrl00.h"
-
-
-#define IRQ_PLD0                     INT_MS_P0_OFST
-#define IRQ_PLD1                     INT_MS_P1_OFST
-#define IRQ_PLD2                     INT_MS_P2_OFST
-#define IRQ_PLD3                     INT_MS_P3_OFST
-#define IRQ_PLD4                     INT_MS_P4_OFST
-#define IRQ_PLD5                     INT_MS_P5_OFST
-#define IRQ_EXT                      INT_MS_IP_OFST
-#define IRQ_UART                     INT_MS_UA_OFST
-#define IRQ_TIMER0                   INT_MS_T0_OFST
-#define IRQ_TIMER1                   INT_MS_T1_OFST
-#define IRQ_PLL                      INT_MS_PLL_OFST
-#define IRQ_EBI                      INT_MS_EBI_OFST
-#define IRQ_STRIPE_BRIDGE            INT_MS_PLL_OFST
-#define IRQ_AHB_BRIDGE               INT_MS_PLL_OFST
-#define IRQ_COMMRX                   INT_MS_CR_OFST
-#define IRQ_COMMTX                   INT_MS_CT_OFST
-#define IRQ_FAST_COMM                INT_MS_FC_OFST
-
-#define NR_IRQS                         (INT_MS_FC_OFST + 1)
-
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/memory.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/memory.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/memory.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,63 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10/memory.h
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-/*
- * Task size: 3GB
- */
-#define TASK_SIZE	(0xc0000000UL)
-#define TASK_SIZE_26	(0x04000000UL)
-
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
-
-/*
- * Page offset: 3GB
- */
-#define PAGE_OFFSET	(0xc0000000UL)
-#define PHYS_OFFSET	(0x00000000UL)
-
-#define PHYS_TO_NID(addr)    (0)
-
-/*
- * On epxa10, the dram is contiguous
- */
-#define __virt_to_phys__is_a_macro
-#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
-#define __phys_to_virt__is_a_macro
-#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
-
-/*
- * Virtual view <-> DMA view memory address translations
- * virt_to_bus: Used to translate the virtual address to an
- *              address suitable to be passed to set_dma_addr
- * bus_to_virt: Used to convert an address for DMA operations
- *              to an address that the kernel can use.
- */
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)	(x - PAGE_OFFSET + /*SDRAM_BASE*/0)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)	(x - /*SDRAM_BASE*/0 + PAGE_OFFSET)
-
-#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/mode_ctrl00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/mode_ctrl00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/mode_ctrl00.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/mode_ctrl00.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,80 +0,0 @@
-#ifndef __MODE_CTRL00_H
-#define __MODE_CTRL00_H
-
-/*
- * Register definitions for the reset and mode control
- */
-
-/*
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-
-#define BOOT_CR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  ))
-#define BOOT_CR_BF_MSK (0x1)
-#define BOOT_CR_BF_OFST (0)
-#define BOOT_CR_HM_MSK (0x2)
-#define BOOT_CR_HM_OFST (1)
-#define BOOT_CR_RE_MSK (0x4)
-#define BOOT_CR_RE_OFST (2)
-
-#define RESET_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x4 ))
-#define RESET_SR_WR_MSK (0x1)
-#define RESET_SR_WR_OFST (0)
-#define RESET_SR_CR_MSK (0x2)
-#define RESET_SR_CR_OFST (1)
-#define RESET_SR_JT_MSK (0x4)
-#define RESET_SR_JT_OFST (2)
-#define RESET_SR_ER_MSK (0x8)
-#define RESET_SR_ER_OFST (3)
-
-#define ID_CODE(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x08 ))
-
-#define SRAM0_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x20 ))
-#define SRAM0_SR_SIZE_MSK (0xFFFFF000)
-#define SRAM0_SR_SIZE_OFST (12)
-
-#define SRAM1_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x24 ))
-#define SRAM1_SR_SIZE_MSK (0xFFFFF000)
-#define SRAM1_SR_SIZE_OFST (12)
-
-#define DPSRAM0_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x30 ))
-
-#define DPSRAM0_SR_MODE_MSK (0xF)
-#define DPSRAM0_SR_MODE_OFST (0)
-#define DPSRAM0_SR_GLBL_MSK (0x30)
-#define DPSRAM0_SR_SIZE_MSK (0xFFFFF000)
-#define DPSRAM0_SR_SIZE_OFST (12)
-
-#define DPSRAM0_LCR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x34 ))
-#define DPSRAM0_LCR_LCKADDR_MSK (0x1FFE0)
-#define DPSRAM0_LCR_LCKADDR_OFST (4)
-
-#define DPSRAM1_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x38 ))
-#define DPSRAM1_SR_MODE_MSK (0xF)
-#define DPSRAM1_SR_MODE_OFST (0)
-#define DPSRAM1_SR_GLBL_MSK (0x30)
-#define DPSRAM1_SR_GLBL_OFST (4)
-#define DPSRAM1_SR_SIZE_MSK (0xFFFFF000)
-#define DPSRAM1_SR_SIZE_OFST (12)
-
-#define DPSRAM1_LCR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x3C ))
-#define DPSRAM1_LCR_LCKADDR_MSK (0x1FFE0)
-#define DPSRAM1_LCR_LCKADDR_OFST (4)
-
-#endif /* __MODE_CTRL00_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/param.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/param.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/param.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/param.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,21 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10db/param.h
- *
- *  Copyright (C) 1999 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#define HZ 100
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/platform.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/platform.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/platform.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/platform.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,7 +0,0 @@
-#ifndef PLATFORM_H
-#define PLATFORM_H
-#include "excalibur.h"
-
-#define MAXIRQNUM 15 
-#endif
-
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/pld_conf00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/pld_conf00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/pld_conf00.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/pld_conf00.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,73 +0,0 @@
-#ifndef __PLD_CONF00_H
-#define __PLD_CONF00_H
-
-/*
- * Register definitions for the PLD Configuration Logic
- */
-
-/*
- *  
- *  This file contains the register definitions for the Excalibur
- *  Interrupnt controller INT_CTRL00.
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
- 
-#define CONFIG_CONTROL(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR))  
-#define CONFIG_CONTROL_LK_MSK (0x1)
-#define CONFIG_CONTROL_LK_OFST (0)
-#define CONFIG_CONTROL_CO_MSK (0x2)
-#define CONFIG_CONTROL_CO_OFST (1)
-#define CONFIG_CONTROL_B_MSK  (0x4)
-#define CONFIG_CONTROL_B_OFST (2)
-#define CONFIG_CONTROL_PC_MSK (0x8)
-#define CONFIG_CONTROL_PC_OFST (3)
-#define CONFIG_CONTROL_E_MSK (0x10)
-#define CONFIG_CONTROL_E_OFST (4)
-#define CONFIG_CONTROL_ES_MSK (0xE0)
-#define CONFIG_CONTROL_ES_OFST (5)
-#define CONFIG_CONTROL_ES_0_MSK (0x20)
-#define CONFIG_CONTROL_ES_1_MSK (0x40)
-#define CONFIG_CONTROL_ES_2_MSK (0x80)
-
-#define CONFIG_CONTROL_CLOCK(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR  + 0x4 ))
-#define CONFIG_CONTROL_CLOCK_RATIO_MSK (0xFFFF)
-#define CONFIG_CONTROL_CLOCK_RATIO_OFST (0)
-
-#define CONFIG_CONTROL_DATA(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR  + 0x8 ))
-#define CONFIG_CONTROL_DATA_MSK (0xFFFFFFFF)
-#define CONFIG_CONTROL_DATA_OFST (0)
-
-#define CONFIG_UNLOCK(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR  + 0xC )) 
-#define CONFIG_UNLOCK_MSK (0xFFFFFFFF)
-#define CONFIG_UNLOCK_OFST (0)
-
-#define CONFIG_UNLOCK_MAGIC (0x554E4C4B)
-
-#endif /* __PLD_CONF00_H */
-
-
-
-
-
-
-
-
-
-
-
-
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/serial.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/serial.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/serial.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/serial.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,50 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10db/serial.h
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SERIAL_H
-#define __ASM_ARCH_SERIAL_H
-
-#include <asm/arch/platform.h>
-#include <asm/irq.h>
-
-/*
- * This assumes you have a 1.8432 MHz clock for your UART.
- *
- * It'd be nice if someone built a serial card with a 24.576 MHz
- * clock, since the 16550A is capable of handling a top speed of 1.5
- * megabits/second; but this requires the faster clock.
- */
-#define BASE_BAUD (1 / 16)
-
-#define _SER_IRQ0	IRQ_UARTINT0
-#define _SER_IRQ1	IRQ_UARTINT1
-
-#define RS_TABLE_SIZE	2
-
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-     /* UART CLK        PORT  IRQ     FLAGS        */
-#define STD_SERIAL_PORT_DEFNS \
-	{ 0, BASE_BAUD, 0x3F8, _SER_IRQ0, STD_COM_FLAGS },	/* ttyS0 */	\
-	{ 0, BASE_BAUD, 0x2F8, _SER_IRQ1, STD_COM_FLAGS },	/* ttyS1 */
-
-#define EXTRA_SERIAL_PORT_DEFNS
-
-#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/system.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/system.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/system.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,41 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10db/system.h
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <asm/arch/platform.h>
-
-static void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks
-	 */
-	cpu_do_idle(0);
-}
-
-extern __inline__ void arch_reset(char mode)
-{
-	/* Hmm... We can probably do something with the watchdog... */
-}
-
-#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/tdkphy.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/tdkphy.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/tdkphy.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/tdkphy.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,209 +0,0 @@
-/*
- *  linux/drivers/tdkphy.h
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __TDKPHY_H
-#define __TDKPHY_H
-
-/*
- * Register definitions for the TDK 78Q2120 PHY 
- * which is on the Camelot board
- */
-
-/*
- * Copyright (c) Altera Corporation 2000.
- * All rights reserved.
- */
-#define PHY_CONTROL                                                                                     (0)
-#define PHY_CONTROL_COLT_MSK                                                            (0x80)
-#define PHY_CONTROL_COLT_OFST                                                           (7)
-#define PHY_CONTROL_DUPLEX_MSK                                                          (0x100)
-#define PHY_CONTROL_DUPLEX_OFST                                                         (8)
-#define PHY_CONTROL_RANEG_MSK                                                           (0x200)
-#define PHY_CONTROL_RANEG_OFST                                                          (9)
-#define PHY_CONTROL_ISO_MSK                                                                     (0x400)
-#define PHY_CONTROL_ISO_OFST                                                            (10)
-#define PHY_CONTROL_PWRDN_MSK                                                           (0x800)
-#define PHY_CONTROL_PWRDN_OFST                                                          (11)
-#define PHY_CONTROL_ANEGEN_MSK                                                          (0x1000)
-#define PHY_CONTROL_ANEGEN_OFST                                                         (12)
-#define PHY_CONTROL_SPEEDSL_MSK                                                         (0x2000)
-#define PHY_CONTROL_SPEEDSL_OFST                                                        (13)
-#define PHY_CONTROL_LOOPBK_MSK                                                          (0x4000)
-#define PHY_CONTROL_LOOPBK_OFST                                                         (14)
-#define PHY_CONTROL_RESET_MSK                                                           (0x8000)
-#define PHY_CONTROL_RESET_OFST                                                          (15)
-
-#define PHY_STATUS                                                                                      (1)
-#define PHY_STATUS_ETXD_MSK                                                                     (0x1)
-#define PHY_STATUS_EXTD_OFST                                                            (0)
-#define PHY_STATUS_JAB_MSK                                                                      (0x2)
-#define PHY_STATUS_JAB_OFST                                                                     (1)
-#define PHY_STATUS_LINK_MSK                                                                     (0x4)
-#define PHY_STATUS_LINK_OFST                                                            (2)
-#define PHY_STATUS_ANEGA_MSK                                                            (0x8)
-#define PHY_STATUS_ANEGA_OFST                                                           (3)
-#define PHY_STATUS_RFAULT_MSK                                                           (0x10)
-#define PHY_STATUS_RFAULT_OFST                                                          (4)
-#define PHY_STATUS_ANEGC_MSK                                                            (0x20)
-#define PHY_STATUS_ANEGC_OFST                                                           (5)
-#define PHY_STATUS_10T_H_MSK                                                            (0x800)
-#define PHY_STATUS_10T_H_OFST                                                           (11)
-#define PHY_STATUS_10T_F_MSK                                                            (0x1000)
-#define PHY_STATUS_10T_F_OFST                                                           (12)
-#define PHY_STATUS_100_X_H_MSK                                                          (0x2000)
-#define PHY_STATUS_100_X_H_OFST                                                         (13)
-#define PHY_STATUS_100_X_F_MSK                                                          (0x4000)
-#define PHY_STATUS_100_X_F_OFST                                                         (14)
-#define PHY_STATUS_100T4_MSK                                                            (0x8000)
-#define PHY_STATUS_100T4_OFST                                                           (15)
-
-#define PHY_ID1                                                                                         (2)
-#define PHY_ID1_OUI_MSK                                                                         (0xFFFF)
-#define PHY_ID1_OUI_OFST                                                                        (0)
-
-#define PHY_ID2                                                                                         (3)
-#define PHY_ID2_RN_MSK                                                                          (0xF)
-#define PHY_ID2_RN_OFST                                                                         (0)
-#define PHY_ID2_MN_MSK                                                                          (0x3F0)
-#define PHY_ID2_MN_OFST                                                                         (4)
-#define PHY_ID2_OUI_MSK                                                                         (0xFC00)
-#define PHY_ID2_OUI_OFST                                                                        (10)
-
-#define PHY_AUTO_NEG_ADVERTISEMENT                                                      (4)
-#define PHY_AUTO_NEG_ADVERTISEMENT_SELECTOR_MSK                         (0x1F)
-#define PHY_AUTO_NEG_ADVERTISEMENT_SELECTOR_OFST                        (0)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A0_MSK                                       (0x20)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A0_OFST                                      (5)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A1_MSK                                       (0x40)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A1_OFST                                      (6)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A2_MSK                                       (0x80)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A2_OFST                                      (7)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A3_MSK                                       (0x100)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A3_OFST                                      (8)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A4_MSK                                       (0x200)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A4_OFST                                      (9)
-#define PHY_AUTO_NEG_ADVERTISEMENT_TAF_MSK                                      (0x1FE0)
-#define PHY_AUTO_NEG_ADVERTISEMENT_TAF_OFST                                     (5)
-#define PHY_AUTO_NEG_ADVERTISEMENT_RF_MSK                                       (0x2000)
-#define PHY_AUTO_NEG_ADVERTISEMENT_RF_OFST                                      (13)
-#define PHY_AUTO_NEG_ADVERTISEMENT_RSVD_MSK                                     (0x4000)
-#define PHY_AUTO_NEG_ADVERTISEMENT_RVSD_OFST                            (14)
-#define PHY_AUTO_NEG_ADVERTISEMENT_NP_MSK                                       (0x8000)
-#define PHY_AUTO_NEG_ADVERTISEMENT_NP_OFST                                      (15)
-
-#define PHY_AUTO_NEG_LINK_PARTNER                                                       (5)
-#define PHY_AUTO_NEG_LINK_PARTNER_S4_MSK                                        (0x1F)
-#define PHY_AUTO_NEG_LINK_PARTNER_S4_OFST                                       (0)
-#define PHY_AUTO_NEG_LINK_PARTNER_A7_MSK                                        (0x1FE0)
-#define PHY_AUTO_NEG_LINK_PARTNER_A7_OFST                                       (5)
-#define PHY_AUTO_NEG_LINK_PARTNER_RF_MSK                                        (0x2000)
-#define PHY_AUTO_NEG_LINK_PARTNER_RF_OFST                                       (13)
-#define PHY_AUTO_NEG_LINK_PARTNER_ACK_MSK                                       (0x4000)
-#define PHY_AUTO_NEG_LINK_PARTNER_ACK_OFST                                      (14)
-#define PHY_AUTO_NEG_LINK_PARTNER_NP_MSK                                        (0x8000)
-#define PHY_AUTO_NEG_LINK_PARTNER_NP_OFST                                       (15)
-
-#define PHY_AUTO_NEG_EXPANSION                                                          (6)
-#define PHY_AUTO_NEG_EXPANSION_LPANEGA_MSK                                      (0x1)
-#define PHY_AUTO_NEG_EXPANSION_LPANEGA_OFST                                     (0)
-#define PHY_AUTO_NEG_EXPANSION_PRX_MSK                                          (0x2)
-#define PHY_AUTO_NEG_EXPANSION_PRX_OFST                                         (1)
-#define PHY_AUTO_NEG_EXPANSION_NPA_MSK                                          (0x4)
-#define PHY_AUTO_NEG_EXPANSION_NPA_OFST                                         (2)
-#define PHY_AUTO_NEG_EXPANSION_LPNPA_MSK                                        (0x8)
-#define PHY_AUTO_NEG_EXPANSION_LPNPA_OFST                                       (3)
-#define PHY_AUTO_NEG_EXPANSION_PDF_MSK                                          (0x10)
-#define PHY_AUTO_NEG_EXPANSION_PDF_OFST                                         (4)
-
-#define PHY_VENDOR_SPECIFIC                                                                     (16)
-#define PHY_VENDOR_SPECIFIC_RXCC_MSK                                            (0x1)
-#define PHY_VENDOR_SPECIFIC_RXCC_OFST                                           (0)
-#define PHY_VENDOR_SPECIFIC_PCSBP_MSK                                           (0x2)
-#define PHY_VENDOR_SPECIFIC_PCSBP_OFST                                          (1)
-#define PHY_VENDOR_SPECIFIC_RVSPOL_MSK                                          (0x10)
-#define PHY_VENDOR_SPECIFIC_RVSPOL_OFST                                         (4)
-#define PHY_VENDOR_SPECIFIC_APOL_MSK                                            (0x20)  
-#define PHY_VENDOR_SPECIFIC_APOL_OFST                                           (5)
-#define PHY_VENDOR_SPECIFIC_GPIO0_DIR_MSK                                       (0x40)
-#define PHY_VENDOR_SPECIFIC_GPIO0_DIR_OFST                                      (6)
-#define PHY_VENDOR_SPECIFIC_GPIO0_DAT_MSK                                       (0x80)
-#define PHY_VENDOR_SPECIFIC_GPIO0_DAT_OFST                                      (7)
-#define PHY_VENDOR_SPECIFIC_GPIO1_DIR_MSK                                       (0x100)
-#define PHY_VENDOR_SPECIFIC_GPIO1_DIR_OFST                                      (8)
-#define PHY_VENDOR_SPECIFIC_GPIO1_DAT_MSK                                       (0x200)
-#define PHY_VENDOR_SPECIFIC_GPIO1_DAT_OFST                                      (9)
-#define PHY_VENDOR_SPECIFIC_10BT_NATURAL_LOOPBACK_DAT_MSK       (0x400)
-#define PHY_VENDOR_SPECIFIC_10BT_NATURAL_LOOPBACK_DAT_OFST      (10)
-#define PHY_VENDOR_SPECIFIC_10BT_SQE_TEST_INHIBIT_MSK           (0x800)
-#define PHY_VENDOR_SPECIFIC_10BT_SQE_TEST_INHIBIT_OFST          (11)
-#define PHY_VENDOR_SPECIFIC_TXHIM_MSK                                           (0x1000)
-#define PHY_VENDOR_SPECIFIC_TXHIM_OFST                                          (12)
-#define PHY_VENDOR_SPECIFIC_INT_LEVEL_MSK                                       (0x4000)
-#define PHY_VENDOR_SPECIFIC_INT_LEVEL_OFST                                      (14)
-#define PHY_VENDOR_SPECIFIC_RPTR_MSK                                            (0x8000)
-#define PHY_VENDOR_SPECIFIC_RPTR_OFST                                           (15)
-
-#define PHY_IRQ_CONTROL                                                                         (17)
-#define PHY_IRQ_CONTROL_ANEG_COMP_INT_MSK                                       (0x1)
-#define PHY_IRQ_CONTROL_ANEG_COMP_INT_OFST                                      (0)
-#define PHY_IRQ_CONTROL_RFAULT_INT_MSK                                          (0x2)
-#define PHY_IRQ_CONTROL_RFAULT_INT_OFST                                         (1)
-#define PHY_IRQ_CONTROL_LS_CHG_INT_MSK                                          (0x4)
-#define PHY_IRQ_CONTROL_LS_CHG_INT_OFST                                         (2)
-#define PHY_IRQ_CONTROL_LP_ACK_INT_MSK                                          (0x8)
-#define PHY_IRQ_CONTROL_LP_ACK_INT_OFST                                         (3)
-#define PHY_IRQ_CONTROL_PDF_INT_MSK                                                     (0x10)
-#define PHY_IRQ_CONTROL_PDF_INT_OFST                                            (4)
-#define PHY_IRQ_CONTROL_PRX_INT_MSK                                                     (0x20)
-#define PHY_IRQ_CONTROL_PRX_INT_OFST                                            (5)
-#define PHY_IRQ_CONTROL_RXER_INT_MSK                                            (0x40)
-#define PHY_IRQ_CONTROL_RXER_INT_OFST                                           (6)
-#define PHY_IRQ_CONTROL_JABBER_INT_MSK                                          (0x80)
-#define PHY_IRQ_CONTROL_JABBER_INT_OFST                                         (7)
-#define PHY_IRQ_CONTROL_ANEG_COMP_IE_MSK                                        (0x100)
-#define PHY_IRQ_CONTROL_ANEG_COMP_IE_OFST                                       (8)
-#define PHY_IRQ_CONTROL_RFAULT_IE_MSK                                           (0x200)
-#define PHY_IRQ_CONTROL_RFAULT_IE_OFST                                          (9)
-#define PHY_IRQ_CONTROL_LS_CHG_IE_MSK                                           (0x400)
-#define PHY_IRQ_CONTROL_LS_CHG_IE_OFST                                          (10)
-#define PHY_IRQ_CONTROL_LP_ACK_IE_MSK                                           (0x800)
-#define PHY_IRQ_CONTROL_LP_ACK_IE_OFST                                          (11)
-#define PHY_IRQ_CONTROL_PDF_IE_MSK                                                      (0x1000)
-#define PHY_IRQ_CONTROL_PDF_IE_OFST                                                     (12)
-#define PHY_IRQ_CONTROL_PRX_IE_MSK                                                      (0x2000)
-#define PHY_IRQ_CONTROL_PRX_IE_OFST                                                     (13)
-#define PHY_IRQ_CONTROL_RXER_IE_MSK                                                     (0x4000)
-#define PHY_IRQ_CONTROL_RXER_IE_OFST                                            (14)
-#define PHY_IRQ_CONTROL_JABBER_IE_MSK                                           (0x8000)
-#define PHY_IRQ_CONTROL_JABBER_IE_OFST                                          (15)
-
-#define PHY_DIAGNOSTIC                                                                          (18)
-#define PHY_DIAGNOSTIC_RX_LOCK_MSK                                                      (0x100)
-#define PHY_DIAGNOSTIC_RX_LOCK_OFST                                                     (8)
-#define PHY_DIAGNOSTIC_RX_PASS_MSK                                                      (0x200)
-#define PHY_DIAGNOSTIC_RX_PASS_OFST                                                     (9)
-#define PHY_DIAGNOSTIC_RATE_MSK                                                         (0x400)
-#define PHY_DIAGNOSTIC_RATE_OFST                                                        (10)
-#define PHY_DIAGNOSTIC_DPLX_MSK                                                         (0x800)
-#define PHY_DIAGNOSTIC_DPLX_OFST                                                        (11)
-#define PHY_DIAGNOSTIC_ANEGF_MSK                                                        (0x1000)
-#define PHY_DIAGNOSTIC_ANEGF_OFST                                                       (12)
-
-#endif /* __TDKPHY_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/time.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/time.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/time.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/time.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,61 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10db/time.h
- *
- *  Copyright (C) 2001 Altera Corporation
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/config.h>
-#include <asm/system.h>
-#include <asm/leds.h>
-#include <asm/arch/hardware.h>
-#define TIMER00_TYPE (volatile unsigned int*)
-#include <asm/arch/timer00.h>
-
-
-/*
- * IRQ handler for the timer
- */
-static void excalibur_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-
-	// ...clear the interrupt
-	*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK;
-
-	do_leds();
-	do_timer(regs);
-	do_profile(regs);
-}
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-extern __inline__ void setup_timer(void)
-{
-
-
-	timer_irq.handler = excalibur_timer_interrupt;
-
-
-	/* 
-	 * Make irqs happen for the system timer
-	 */
-	setup_arm_irq(IRQ_TIMER0, &timer_irq);
-
-	/* Start the timer */
-	*TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200);
-	*TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1;
-	*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK;
-}
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/timer00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/timer00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/timer00.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/timer00.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,98 +0,0 @@
-/*
- *  
- *  This file contains the register definitions for the Excalibur
- *  Timer TIMER00.
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __TIMER00_H
-#define __TIMER00_H
-
-/*
- * Register definitions for the timers
- */
-
-
-#define TIMER0_CR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x00 ))
-#define TIMER0_CR_B_MSK (0x20)
-#define TIMER0_CR_B_OFST (0x5)
-#define TIMER0_CR_S_MSK  (0x10)
-#define TIMER0_CR_S_OFST (0x4)
-#define TIMER0_CR_CI_MSK (0x08)
-#define TIMER0_CR_CI_OFST (0x3)
-#define TIMER0_CR_IE_MSK (0x04)
-#define TIMER0_CR_IE_OFST (0x2)
-#define TIMER0_CR_MODE_MSK (0x3)
-#define TIMER0_CR_MODE_OFST (0)
-#define TIMER0_CR_MODE_FREE (0)
-#define TIMER0_CR_MODE_ONE  (1)
-#define TIMER0_CR_MODE_INTVL (2)
-
-#define TIMER0_SR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x00 ))
-#define TIMER0_SR_B_MSK (0x20)
-#define TIMER0_SR_B_OFST (0x5)
-#define TIMER0_SR_S_MSK  (0x10)
-#define TIMER0_SR_S_OFST (0x4)
-#define TIMER0_SR_CI_MSK (0x08)
-#define TIMER0_SR_CI_OFST (0x3)
-#define TIMER0_SR_IE_MSK (0x04)
-#define TIMER0_SR_IE_OFST (0x2)
-#define TIMER0_SR_MODE_MSK (0x3)
-#define TIMER0_SR_MODE_OFST (0)
-#define TIMER0_SR_MODE_FREE (0)
-#define TIMER0_SR_MODE_ONE  (1)
-#define TIMER0_SR_MODE_INTVL (2)
-
-#define TIMER0_PRESCALE(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x010 ))
-#define TIMER0_LIMIT(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x020 ))
-#define TIMER0_READ(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x030 ))
-
-#define TIMER1_CR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x40 ))
-#define TIMER1_CR_B_MSK (0x20)
-#define TIMER1_CR_B_OFST (0x5)
-#define TIMER1_CR_S_MSK  (0x10)
-#define TIMER1_CR_S_OFST (0x4)
-#define TIMER1_CR_CI_MSK (0x08)
-#define TIMER1_CR_CI_OFST (0x3)
-#define TIMER1_CR_IE_MSK (0x04)
-#define TIMER1_CR_IE_OFST (0x2)
-#define TIMER1_CR_MODE_MSK (0x3)
-#define TIMER1_CR_MODE_OFST (0)
-#define TIMER1_CR_MODE_FREE (0)
-#define TIMER1_CR_MODE_ONE  (1)
-#define TIMER1_CR_MODE_INTVL (2)
-
-#define TIMER1_SR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x40 ))
-#define TIMER1_SR_B_MSK (0x20)
-#define TIMER1_SR_B_OFST (0x5)
-#define TIMER1_SR_S_MSK  (0x10)
-#define TIMER1_SR_S_OFST (0x4)
-#define TIMER1_SR_CI_MSK (0x08)
-#define TIMER1_SR_CI_OFST (0x3)
-#define TIMER1_SR_IE_MSK (0x04)
-#define TIMER1_SR_IE_OFST (0x2)
-#define TIMER1_SR_MODE_MSK (0x3)
-#define TIMER1_SR_MODE_OFST (0)
-#define TIMER1_SR_MODE_FREE (0)
-#define TIMER1_SR_MODE_ONE  (1)
-#define TIMER1_SR_MODE_INTVL (2)
-
-#define TIMER1_PRESCALE(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x050 ))
-#define TIMER1_LIMIT(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x060 ))
-#define TIMER1_READ(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x070 ))
-
-#endif /* __TIMER00_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/timex.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/timex.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/timex.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/timex.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,26 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10db/timex.h
- *
- *  Excalibur timex specifications
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/*
- * ??
- */
-#define CLOCK_TICK_RATE		(50000000 / 16)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/uart00.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/uart00.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/uart00.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/uart00.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,181 +0,0 @@
-/* *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __UART00_H
-#define __UART00_H
-
-/*
- * Register definitions for the UART
- */
-
-#define UART_TX_FIFO_SIZE      (15)
-
-#define UART_RSR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x00 ))
-#define UART_RSR_RX_LEVEL_MSK (0x1f)
-#define UART_RSR_RX_LEVEL_OFST (0)
-#define UART_RSR_RE_MSK (0x80)
-#define UART_RSR_RE_OFST (7)
-
-#define UART_RDS(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x04 ))
-#define UART_RDS_BI_MSK (0x8)
-#define UART_RDS_BI_OFST (4)
-#define UART_RDS_FE_MSK (0x4)
-#define UART_RDS_FE_OFST (2)
-#define UART_RDS_PE_MSK (0x2)
-#define UART_RDS_PE_OFST (1)
-#define UART_RDS_OE_MSK (0x1)
-#define UART_RDS_OE_OFST (0)
-
-#define UART_RD(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x08 ))
-#define UART_RD_RX_DATA_MSK (0xff)
-#define UART_RD_RX_DATA_OFST (0)
-
-#define UART_TSR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x0c ))
-#define UART_TSR_TX_LEVEL_MSK (0x1f)
-#define UART_TSR_TX_LEVEL_OFST (0)
-#define UART_TSR_TXI_MSK (0x80)
-#define UART_TSR_TXI_OFST (7)
-
-#define UART_TD(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x10 ))
-#define UART_TD_TX_DATA_MSK (0xff)
-#define UART_TD_TX_DATA_OFST (0)
-
-#define UART_FCR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x14 ))
-#define UART_FCR_RX_THR_MSK (0xd0)
-#define UART_FCR_RX_THR_OFST (5)
-#define UART_FCR_RX_THR_1 (0x00)
-#define UART_FCR_RX_THR_2 (0x20)
-#define UART_FCR_RX_THR_4 (0x40)
-#define UART_FCR_RX_THR_6 (0x60)
-#define UART_FCR_RX_THR_8 (0x80)
-#define UART_FCR_RX_THR_10 (0xa0)
-#define UART_FCR_RX_THR_12 (0xc0)
-#define UART_FCR_RX_THR_14 (0xd0)
-#define UART_FCR_TX_THR_MSK (0x1c)
-#define UART_FCR_TX_THR_OFST (2)
-#define UART_FCR_TX_THR_0 (0x00)
-#define UART_FCR_TX_THR_2 (0x04)
-#define UART_FCR_TX_THR_4 (0x08)
-#define UART_FCR_TX_THR_8 (0x0c)
-#define UART_FCR_TX_THR_10 (0x10)
-#define UART_FCR_TX_THR_12 (0x14)
-#define UART_FCR_TX_THR_14 (0x18)
-#define UART_FCR_TX_THR_15 (0x1c)
-#define UART_FCR_RC_MSK (0x02)
-#define UART_FCR_RC_OFST (1)
-#define UART_FCR_TC_MSK (0x01)
-#define UART_FCR_TC_OFST (0)
-
-#define UART_IES(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x18 ))
-#define UART_IES_ME_MSK (0x8)
-#define UART_IES_ME_OFST (3)
-#define UART_IES_TIE_MSK (0x4)
-#define UART_IES_TIE_OFST (2)
-#define UART_IES_TE_MSK (0x2)
-#define UART_IES_TE_OFST (1)
-#define UART_IES_RE_MSK (0x1)
-#define UART_IES_RE_OFST (0)
-
-#define UART_IEC(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x1c ))
-#define UART_IEC_ME_MSK (0x8)
-#define UART_IEC_ME_OFST (3)
-#define UART_IEC_TIE_MSK (0x4)
-#define UART_IEC_TIE_OFST (2)
-#define UART_IEC_TE_MSK (0x2)
-#define UART_IEC_TE_OFST (1)
-#define UART_IEC_RE_MSK (0x1)
-#define UART_IEC_RE_OFST (0)
-
-#define UART_ISR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x20 ))
-#define UART_ISR_MI_MSK (0x8)
-#define UART_ISR_MI_OFST (3)
-#define UART_ISR_TII_MSK (0x4)
-#define UART_ISR_TII_OFST (2)
-#define UART_ISR_TI_MSK (0x2)
-#define UART_ISR_TI_OFST (1)
-#define UART_ISR_RI_MSK (0x1)
-#define UART_ISR_RI_OFST (0)
-
-#define UART_IID(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x24 ))
-#define UART_IID_IID_MSK (0x7)
-#define UART_IID_IID_OFST (0)
-
-#define UART_MC(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x28 ))
-#define UART_MC_OE_MSK (0x40)
-#define UART_MC_OE_OFST (6)
-#define UART_MC_SP_MSK (0x20)
-#define UART_MC_SP_OFST (5)
-#define UART_MC_EP_MSK (0x10)
-#define UART_MC_EP_OFST (4)
-#define UART_MC_PE_MSK (0x08)
-#define UART_MC_PE_OFST (3)
-#define UART_MC_ST_MSK (0x04)
-#define UART_MC_ST_ONE (0x0)
-#define UART_MC_ST_TWO (0x04)
-#define UART_MC_ST_OFST (2)
-#define UART_MC_CLS_MSK (0x03)
-#define UART_MC_CLS_OFST (0)
-#define UART_MC_CLS_CHARLEN_5 (0)
-#define UART_MC_CLS_CHARLEN_6 (1)
-#define UART_MC_CLS_CHARLEN_7 (2)
-#define UART_MC_CLS_CHARLEN_8 (3)
-
-#define UART_MCR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x2c ))
-#define UART_MCR_AC_MSK (0x80)
-#define UART_MCR_AC_OFST (7)
-#define UART_MCR_AR_MSK (0x40)
-#define UART_MCR_AR_OFST (6)
-#define UART_MCR_BR_MSK (0x20)
-#define UART_MCR_BR_OFST (5)
-#define UART_MCR_LB_MSK (0x10)
-#define UART_MCR_LB_OFST (4)
-#define UART_MCR_DCD_MSK (0x08)
-#define UART_MCR_DCD_OFST (3)
-#define UART_MCR_RI_MSK (0x04)
-#define UART_MCR_RI_OFST (2)
-#define UART_MCR_DTR_MSK (0x02)
-#define UART_MCR_DTR_OFST (1)
-#define UART_MCR_RTS_MSK (0x01)
-#define UART_MCR_RTS_OFST (0)
-
-#define UART_MSR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x30 ))
-#define UART_MSR_DCD_MSK (0x80)
-#define UART_MSR_DCD_OFST (7)
-#define UART_MSR_RI_MSK (0x40)
-#define UART_MSR_RI_OFST (6)
-#define UART_MSR_DSR_MSK (0x20)
-#define UART_MSR_DSR_OFST (5)
-#define UART_MSR_CTS_MSK (0x10)
-#define UART_MSR_CTS_OFST (4)
-#define UART_MSR_DDCD_MSK (0x08)
-#define UART_MSR_DDCD_OFST (3)
-#define UART_MSR_TERI_MSK (0x04)
-#define UART_MSR_TERI_OFST (2)
-#define UART_MSR_DDSR_MSK (0x02)
-#define UART_MSR_DDSR_OFST (1)
-#define UART_MSR_DCTS_MSK (0x01)
-#define UART_MSR_DCTS_OFST (0)
-
-#define UART_DIV_LO(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x34 ))
-#define UART_DIV_LO_DIV_MSK (0xff)
-#define UART_DIV_LO_DIV_OFST (0)
-
-#define UART_DIV_HI(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x38 ))
-#define UART_DIV_HI_DIV_MSK (0xff)
-#define UART_DIV_HI_DIV_OFST (0)
-
-#endif /* __UART00_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/uncompress.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/uncompress.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/uncompress.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/uncompress.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,54 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10db/uncompress.h
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include "asm/arch/platform.h"
-#include "asm/arch/hardware.h"
-#define UART00_TYPE (volatile unsigned int*)
-#include "asm/arch/uart00.h"
-
-/*
- * This does not append a newline
- */
-static void puts(const char *s)
-{
-	while (*s) {
-		while ((*UART_TSR(EXC_UART00_BASE) &
-		       UART_TSR_TX_LEVEL_MSK)==15);
-			barrier();
-
-		*UART_TD(EXC_UART00_BASE) = *s;
-
-		if (*s == '\n') {
-			while ((*UART_TSR(EXC_UART00_BASE) &
-			       UART_TSR_TX_LEVEL_MSK)==15);
-				barrier();
-
-			*UART_TD(EXC_UART00_BASE) = '\r';
-		}
-		s++;
-	}
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
-
-#define arch_decomp_wdog()
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/vmalloc.h linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/vmalloc.h
--- linux-2.4.22-pre2/include/asm-arm/arch-epxa10db/vmalloc.h	2001-10-25 13:53:53.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-epxa10db/vmalloc.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,32 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10db/vmalloc.h
- *
- *  Copyright (C) 2000 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/*
- * Just any arbitrary offset to the start of the vmalloc VM area: the
- * current 8MB value just means that there will be a 8MB "hole" after the
- * physical memory until the kernel virtual memory starts.  That means that
- * any out-of-bounds memory accesses will hopefully be caught.
- * The vmalloc() routines leaves a hole of 4kB between each vmalloced
- * area for the same reason. ;)
- */
-#define VMALLOC_OFFSET	  (8*1024*1024)
-#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-integrator/memory.h linux-2.4.22-pre3/include/asm-arm/arch-integrator/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-integrator/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-integrator/memory.h	2003-07-05 18:11:10.000000000 -0700
@@ -58,6 +58,4 @@
 #define __bus_to_virt__is_a_macro
 #define __bus_to_virt(x)	(x - INTEGRATOR_HDR0_SDRAM_BASE + PAGE_OFFSET)
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-integrator/system.h linux-2.4.22-pre3/include/asm-arm/arch-integrator/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-integrator/system.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-integrator/system.h	2003-07-05 18:11:10.000000000 -0700
@@ -25,13 +25,13 @@
 #include <asm/io.h>
 #include <asm/arch/platform.h>
 
-static void arch_idle(void)
+static inline void arch_idle(void)
 {
 	/*
 	 * This should do all the clock switching
 	 * and wait for interrupt tricks
 	 */
-	cpu_do_idle(0);
+	cpu_do_idle();
 }
 
 static inline void arch_reset(char mode)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-l7200/keyboard.h linux-2.4.22-pre3/include/asm-arm/arch-l7200/keyboard.h
--- linux-2.4.22-pre2/include/asm-arm/arch-l7200/keyboard.h	2001-05-16 15:25:16.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-l7200/keyboard.h	2003-07-05 18:11:10.000000000 -0700
@@ -17,6 +17,8 @@
 
 #include <asm/irq.h>
 
+#error This needs fixing --rmk
+
 /*
  * Layout of L7200 keyboard registers
  */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-l7200/memory.h linux-2.4.22-pre3/include/asm-arm/arch-l7200/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-l7200/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-l7200/memory.h	2003-07-05 18:11:10.000000000 -0700
@@ -47,6 +47,4 @@
 #define __bus_to_virt__is_a_macro
 #define __bus_to_virt(x) __phys_to_virt(x)
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-l7200/system.h linux-2.4.22-pre3/include/asm-arm/arch-l7200/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-l7200/system.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-l7200/system.h	2003-07-05 18:11:10.000000000 -0700
@@ -12,9 +12,8 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-static void arch_idle(void)
+static inline void arch_idle(void)
 {
-	/* fixme: this needs to be cleaned up (converted from ASM code) --rmk */
 	*(unsigned long *)(IO_BASE + 0x50004) = 1;	/* idle mode */
 }
 
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-mx1ads/memory.h linux-2.4.22-pre3/include/asm-arm/arch-mx1ads/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-mx1ads/memory.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-mx1ads/memory.h	2003-07-05 18:11:10.000000000 -0700
@@ -70,6 +70,4 @@
 #define __bus_to_virt__is_a_macro
 #define __bus_to_virt(x)	(x -  PHYS_OFFSET + PAGE_OFFSET)
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-nexuspci/memory.h linux-2.4.22-pre3/include/asm-arm/arch-nexuspci/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-nexuspci/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-nexuspci/memory.h	2003-07-05 18:11:10.000000000 -0700
@@ -43,6 +43,4 @@
 #define __bus_to_virt__is_a_macro
 #define __bus_to_virt(x) ((unsigned long)(x) + PAGE_OFFSET - BUS_OFFSET)
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-nexuspci/system.h linux-2.4.22-pre3/include/asm-arm/arch-nexuspci/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-nexuspci/system.h	2000-09-18 15:15:23.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-nexuspci/system.h	2003-07-05 18:11:10.000000000 -0700
@@ -14,10 +14,9 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-static void arch_idle(void)
+static inline void arch_idle(void)
 {
-	while (!current->need_resched && !hlt_counter)
-		cpu_do_idle(IDLE_WAIT_SLOW);
+	cpu_do_idle();
 }
 
 #define arch_reset(mode)	do { } while (0)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/bits.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/bits.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/bits.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/bits.h	2003-07-05 18:11:10.000000000 -0700
@@ -0,0 +1,61 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either 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
+ */
+/* DO NOT EDIT!! - this file automatically generated
+ *                 from .s file by awk -f s2h.awk
+ */
+/*  Bit field defintions
+ *  Copyright (C) ARM Limited 1998. All rights reserved.
+ */
+
+#ifndef __bits_h
+#define __bits_h                        1
+
+#define BIT0                            0x00000001
+#define BIT1                            0x00000002
+#define BIT2                            0x00000004
+#define BIT3                            0x00000008
+#define BIT4                            0x00000010
+#define BIT5                            0x00000020
+#define BIT6                            0x00000040
+#define BIT7                            0x00000080
+#define BIT8                            0x00000100
+#define BIT9                            0x00000200
+#define BIT10                           0x00000400
+#define BIT11                           0x00000800
+#define BIT12                           0x00001000
+#define BIT13                           0x00002000
+#define BIT14                           0x00004000
+#define BIT15                           0x00008000
+#define BIT16                           0x00010000
+#define BIT17                           0x00020000
+#define BIT18                           0x00040000
+#define BIT19                           0x00080000
+#define BIT20                           0x00100000
+#define BIT21                           0x00200000
+#define BIT22                           0x00400000
+#define BIT23                           0x00800000
+#define BIT24                           0x01000000
+#define BIT25                           0x02000000
+#define BIT26                           0x04000000
+#define BIT27                           0x08000000
+#define BIT28                           0x10000000
+#define BIT29                           0x20000000
+#define BIT30                           0x40000000
+#define BIT31                           0x80000000
+
+#endif
+
+/*         END */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/dma.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/dma.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/dma.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/dma.h	2003-07-05 18:11:10.000000000 -0700
@@ -0,0 +1,29 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/dma.h
+ *
+ *  Copyright (C) 2002 ARM Limited.
+ *  Copyright (C) 1997,1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS		0xffffffff
+
+#define MAX_DMA_CHANNELS	0
+
+#endif /* _ASM_ARCH_DMA_H */
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/hardware.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/hardware.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/hardware.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/hardware.h	2003-07-05 18:11:10.000000000 -0700
@@ -0,0 +1,40 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/hardware.h
+ *
+ *  This file contains the hardware definitions of Omaha.
+ *
+ *  Copyright (C) 1999-2002 ARM Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <asm/arch/platform.h>
+
+/*
+ * Where in virtual memory the IO devices (timers, system controllers
+ * and so on)
+ */
+#define IO_BASE			0xE0000000                 // VA of IO 
+#define IO_SIZE			0x1B000000                 // How much?
+#define IO_START		0x00000000		   // PA of IO
+
+/* macro to get at IO space when running virtually */
+#define IO_ADDRESS(x) (x + IO_BASE) 
+
+#endif
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/ide.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/ide.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/ide.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/ide.h	2003-07-05 18:11:10.000000000 -0700
@@ -0,0 +1,63 @@
+/*
+ * linux/include/asm-arm/arch-omaha/ide.h
+ *
+ * Copyright (c) 2002 ARM Limited.
+ * Copyright (c) 2000 Steve Hill (sjhill@cotw.com)
+ *
+ * Changelog:
+ *  03-29-2000	SJH	Created file placeholder
+ */
+#include <linux/config.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+	ide_ioreg_t reg;
+	int i;
+	int regincr = 1;
+	
+	memset(hw, 0, sizeof(*hw));
+
+	reg = (ide_ioreg_t)data_port;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+	
+		hw->io_ports[i] = reg;
+
+		/* Special location in nCS2 for data register, as
+		 * we need to be able to do 16-bit r/w.
+		 */
+
+		if(i == IDE_DATA_OFFSET)
+			hw->io_ports[i] = reg + 0x04000000;
+
+		reg += regincr;
+	}
+	
+	hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port;
+	
+	if(irq)
+		*irq = 1;
+}
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void
+ide_init_default_hwifs(void)
+{
+        hw_regs_t hw;
+	
+        /* init the interface */
+	ide_init_hwif_ports(&hw, IO_ADDRESS(0x01C00000), IO_ADDRESS(0x01C00006), NULL);
+        hw.irq = 1;	// pld irq really
+        ide_register_hw(&hw, NULL);
+}
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/io.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/io.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/io.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/io.h	2003-07-05 18:11:10.000000000 -0700
@@ -0,0 +1,43 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/io.h
+ *
+ *  Copyright (C) 1999-2002 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)			((a))
+#define __mem_pci(a)		((unsigned long)(a))
+#define __mem_isa(a)		((unsigned long)(a))
+
+/*
+ * Generic virtual read/write
+ */
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
+
+// Validate io memory...
+#define iomem_valid_addr(iomem,size)	(1)
+
+/*
+ * Convert PCI memory space to a CPU physical address
+ */
+#define iomem_to_phys(iomem)	(iomem)
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/irq.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/irq.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/irq.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/irq.h	2003-07-05 18:11:10.000000000 -0700
@@ -0,0 +1,20 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/irq.h
+ *
+ *  Copyright (C) 1999-2002 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#define fixup_irq(i)	(i)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/irqs.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/irqs.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/irqs.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/irqs.h	2003-07-05 18:11:10.000000000 -0700
@@ -0,0 +1,26 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/irqs.h
+ *
+ *  Copyright (C) 1999-2002 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* Use the omaha definitions */
+#include <asm/arch/platform.h>
+
+
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/memory.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/memory.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/memory.h	2003-07-05 18:11:10.000000000 -0700
@@ -0,0 +1,63 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/mmu.h
+ *
+ *  Copyright (C) 1999-2002 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE	(0xC0000000UL)
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET	(0xC0000000UL)
+#define PHYS_OFFSET	(0x0C000000UL)
+
+/*
+ * On omaha, the dram is contiguous
+ */
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - PHYS_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *              address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *              to an address that the kernel can use.
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)	(x - PAGE_OFFSET + PLAT_SDRAM_PHYS0)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)	(x - PLAT_SDRAM_PHYS0 + PAGE_OFFSET)
+
+#define PHYS_TO_NID(addr)	(0)
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/param.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/param.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/param.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/param.h	2003-07-05 18:11:10.000000000 -0700
@@ -0,0 +1,21 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/param.h
+ *
+ *  Copyright (C) 1999-2002 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define HZ 100
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/platform.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/platform.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/platform.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/platform.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,829 @@
+
+/* DO NOT EDIT!! - this file automatically generated
+ *                 from .s file by awk -f s2h.awk
+ */
+/***********************************************************************
+ *    Copyright ARM Limited 1998 - 2001.  All rights reserved.
+ * ************************************************************************
+ * 
+ *   Omaha address map
+ * 
+ * 	NOTE: This is a multi-hosted header file for use with uHAL and
+ * 	      supported debuggers.
+ * 
+ * 	$Id: platform.h,v 1.12 2002/08/22 15:49:56 ahaigh Exp $
+ * 
+ *     Everything is defined in terms of PLAT_* and then the key values
+ *     are redefined as required for uHAL.
+ * 
+ *     NOTE: If things are defined in terms of a BASE and lots of OFFSETs,
+ * 	the code will be more portable and amenable to being used in
+ * 	different (physical vs virtual) memory maps - just change the
+ * 	base and the rest will work!
+ * 
+ * ***********************************************************************/
+
+#ifndef __address_h
+#define __address_h                     1
+
+#include "bits.h" 
+	
+#define PLATFORM_ID                     0x00000800	 /*  TBD */
+
+/*  Common modules for uHAL can be included or excluded by changing these
+ *  definitions. These can be over-ridden by the makefile/ARM project file
+ *  provided the .h file is rebuilt.
+ */
+
+#ifndef USE_C_LIBRARY
+#define USE_C_LIBRARY                   0
+#endif
+#ifndef uHAL_HEAP
+#define uHAL_HEAP                       1
+#endif
+#ifndef uHAL_PCI
+#define uHAL_PCI                        0
+#endif
+
+
+/* -----------------------------------------------------------------------
+ * 
+ *  uHAL always has RAM at 0 and, when a MMU is used, maps everything else
+ *  1-1 physical to virtual. 
+ */
+
+/* =======================================================================
+ *  Omaha
+ * =======================================================================
+ * -----------------------------------------------------------------------
+ *  Memory definitions
+ * -----------------------------------------------------------------------
+ */
+
+/*  New world memory....
+ */
+
+/*  We have eight banks of 32MB, covering the first 256Mb of address space
+ */
+
+/*  Bank		Function
+ *  0		Flash
+ *  1		TBD / ROM
+ *  2		TBD / ROM
+ *  3		FPGA / sub-chip-selects
+ *  4		TBD / ROM
+ *  5		TBD / ROM
+ *  6		SDRAM Bank 0
+ *  7		SDRAM Bank 1
+ */
+
+
+/*  SDRAM	: 64Mbytes. 
+ * 
+ *  Two banks of 32-bit SDRAM, each 32Mbytes in size.
+ *  Bank 0 is on nGCS6, bank 1 is on nGCS7
+ */
+
+/*  Physical address
+ */
+#define PLAT_SDRAM_PHYS0                0x0C000000	 /*  @ 192Mb */
+#define PLAT_SDRAM_PHYS1                0x0E000000	 /*  @ 224Mb */
+
+/*  Size of one SDRAM bank
+ */
+#define PLAT_SDRAM_BANKSIZE             SZ_32M
+
+/*  Virtual address
+ */
+#define PLAT_SDRAM_BASE                 0x00000000
+#define PLAT_SDRAM_SIZE                 SZ_64M
+
+/*  Put page tables in top 1MB of memory; don't let the user access this area.
+ */
+#define PLAT_PAGETABLE_BASE             0x0FFF0000
+#define PLAT_USER_SDRAM_SIZE            PLAT_SDRAM_SIZE - SZ_1M
+
+/*  Flash : 0.5MBytes
+ * 
+ *  One bank of 8-bit Flash on nGCS0 (SST39VF040-90-4C-NH)
+ */
+
+/*  Physical flash device base address
+ */
+#define PLAT_FLASH_PHYS                 0x00000000	 /*  nCS0 */
+
+/*  Logical address for flash
+ */
+#define PLAT_FLASH_BASE                 SZ_64M
+#define PLAT_FLASH_UNCACHED             SZ_128M
+#define PLAT_FLASH_DEVICE_SIZE          SZ_512K		
+#define PLAT_FLASH_SIZE                 SZ_512K
+
+/*  Notes
+ *  We do not map physical devices at their physical
+ *  addresses, because this would overlap the 64Mb of RAM
+ *  at the bottom of memory. Instead, they are mostly mapped
+ *  at 0x20000000 + Physical address instead
+ *  (CPU internal registers live at 0x10000000 + something)
+ */
+
+/*  FPGA space (all of nGCS 3)
+ */
+#define PLAT_FPGA_PHYS                  0x06000000
+#define PLAT_FPGA_BASE                  0x26000000
+#define PLAT_FPGA_SIZE                  SZ_32M	
+
+/*  PLD live in PLD space in nGCS1
+ */
+#define PLAT_PLD_PHYS                   0x02800000
+#define PLAT_PLD_BASE                   0x22800000
+#define PLAT_PLD_SIZE                   SZ_8M
+
+/*  USB2 space
+ */
+#define PLAT_USB2_PHYS                  0x04000000
+#define PLAT_USB2_BASE                  0x24000000
+#define PLAT_USB2_SIZE                  0x00200000
+			       
+/*  Ethernet space
+ */
+#define PLAT_ETHERNET_PHYS              0x02200000
+#define PLAT_ETHERNET_BASE              0x22200000
+#define PLAT_ETHERNET_SIZE              0x00200000
+
+/*  TAP Controller space
+ */
+#define PLAT_TAP_PHYS                   PLAT_FPGA_PHYS
+#define PLAT_TAP_BASE                   PLAT_FPGA_BASE
+#define PLAT_TAP_SIZE                   SZ_32M
+
+/*  CompactFlash address space (top half on nGCS1)
+ */
+
+/*  Notes about the CompactFlash implementation (rev b):
+ * 
+ *  Since we only need CF ATA cards to work, we
+ *  use TrueIDE mode for simplicity.
+ * 
+ *  However, we need 8-bit access to the Command
+ *  Registers, and 16-bit access to the Data-Register.
+ *  So we have to access the CF card in two chip select
+ *  regions: nCS0 and nCS2.
+ * 
+ *  In the case of TrueIDE mode, we get the following
+ *  (physical) address usage:
+ * 
+ *  0x01C00000 - 0x01C00007 	- Command Registers (8-bit r/w)
+ *  0x01E00006 - 0x01E00006	- Control Register (8-bit r/w)
+ *  0x05C00000 - 0x05C00001	- Data Register (16-bit r/w)
+ *  
+ */
+
+/*  CF 16-bit access in nCS2
+ */
+#define PLAT_PCMCIA_PHYS                0x05000000
+#define PLAT_PCMCIA_BASE                0x25000000
+#define PLAT_PCMCIA_SIZE                0x01000000
+
+/*  CF 8-bit access in nCS0
+ */
+#define PLAT_PCMCIA_8_PHYS              0x01000000
+#define PLAT_PCMCIA_8_BASE              0x21000000
+#define PLAT_PCMCIA_8_SIZE              0x01000000
+
+/*  Offsets into CF region (applies to both CS regions)
+ */
+#define PLAT_PCMCIA_ATTR                0x00800000
+#define PLAT_PCMCIA_MEM                 0x00A00000
+#define PLAT_PCMCIA_IO                  0x00C00000	 /*  CE1 in TrueIDE */
+#define PLAT_PCMCIA_IO_ALT              0x00E00000	 /*  CE2 in TrueIDE */
+
+/*  Expansion Bus memory region (nGCS4 and nGCS5)
+ */
+#define PLAT_BUS_PHYS                   0x08000000
+#define PLAT_BUS_BASE                   0x28000000
+#define PLAT_BUS_SIZE                   0x04000000
+
+/*  Location of high vectors used by operating system
+ *  If we may this, then we can seamlessly debug
+ *  from a uHAL program into an OS using high-vectors,
+ *  since we are always going to need exception handlers,
+ *  and they can only be in two places (0x0 and 0xFFFF0000)!
+ */
+#define PLAT_HIVECS_PHYS                0xFFFF0000
+#define PLAT_HIVECS_BASE                0xFFFF0000
+#define PLAT_HIVECS_SIZE                SZ_1M
+
+/*  Remaining chip-select regions
+ *  Leave these un-mapped for the moment
+ */
+
+
+/*  ----------------------------------------------------------------------
+ *  S3C2400X01 CPU peripherals
+ * -----------------------------------------------------------------------
+ */
+
+/*  AHB peripherals appear in the lower 16Mb, APB in the upper 16Mb
+ */
+
+/*  All peripherals are offsets from PLAT_PERIPHERAL_BASE
+ */
+
+#define PLAT_PERIPHERAL_BASE            0x14000000
+#define PLAT_PERIPHERAL_SIZE            SZ_32M
+
+/*  Memory Controller
+ */
+#define OMAHA_BWSCON                    0x00	 /*  Bus width and wait state control */
+#define OMAHA_BANKCON0                  0x04	 /*  Boot ROM control (Bank 0) */
+#define OMAHA_BANKCON1                  0x08	 /*  Bank 1 control */
+#define OMAHA_BANKCON2                  0x0C	 /*  Bank 2 control */
+#define OMAHA_BANKCON3                  0x10	 /*  Bank 3 control */
+#define OMAHA_BANKCON4                  0x14	 /*  Bank 4 control */
+#define OMAHA_BANKCON5                  0x18	 /*  Bank 5 control */
+#define OMAHA_BANKCON6                  0x1C	 /*  Bank 6 control */
+#define OMAHA_BANKCON7                  0x20	 /*  Bank 7 control */
+
+#define OMAHA_REFRESH                   0x24	 /*  SDRAM refresh control */
+#define OMAHA_BANKSIZE                  0x28	 /*  Flexible bank size */
+#define OMAHA_MRSRB6                    0x2C	 /*  Mode register set for SDRAM Bank 0 (nGCS6) */
+#define OMAHA_MRSRB7                    0x30	 /*  Mode register set for SDRAM Bank 1 (nGCS7) */
+
+/*  Interrupt controller
+ */
+#define OMAHA_SRCPND                    0x400000	 /*  Interrupt sources pending */
+#define OMAHA_INTMOD                    0x400004	 /*  Interrupt mode control */
+#define OMAHA_INTMSK                    0x400008	 /*  Interrupt mask control */
+#define OMAHA_PRIORITY                  0x40000C	 /*  Int. priority control */
+#define OMAHA_INTPND                    0x400010	 /*  Interrupts pending */
+#define OMAHA_INTOFFSET                 0x400014	 /*  IRQ source */
+
+/*  Clock / Power management
+ */
+#define OMAHA_LOCKTIME                  0x800000	 /*  PLL Lock time counter */
+#define OMAHA_MPLLCON                   0x800004	 /*  MPLL Control */
+#define OMAHA_UPLLCON                   0x800008	 /*  UPLL Control */
+#define OMAHA_CLKCON                    0x80000C	 /*  Clock control */
+#define OMAHA_CLKSLOW                   0x800010	 /*  Slow clock control */
+#define OMAHA_CLKDIVN                   0x800014	 /*  Clock divider control */
+
+/*  LCD Control
+ */
+
+/*  UARTs
+ */
+#define OMAHA_ULCON0                    0x1000000	 /*  UART 0 Line control */
+#define OMAHA_ULCON1                    0x1004000	 /*  UART 1 Line control */
+
+/*  PWM Timers
+ */
+#define OMAHA_TCFG0                     0x1100000	 /*  Timer 0 config */
+#define OMAHA_TCFG1                     0x1100004	 /*  Timer 1 config */
+#define OMAHA_TCON                      0x1100008	 /*  Timer control */
+#define OMAHA_TCNTB0                    0x110000C	 /*  Timer count buffer 0 */
+#define OMAHA_TCMPB0                    0x1100010	 /*  Timer Compare buffer 0 */
+#define OMAHA_TCNTO0                    0x1100014	 /*  Timer count observation 0 */
+#define OMAHA_TCNTB1                    0x1100018	 /*  Timer count buffer 1 */
+#define OMAHA_TCMPB1                    0x110001C	 /*  Timer compare buffer 1 */
+#define OMAHA_TCNTO1                    0x1100020	 /*  Timer count observation 1 */
+#define OMAHA_TCNTB2                    0x1100024	 /*  Timer count buffer 2 */
+#define OMAHA_TCMPB2                    0x1100028	 /*  Timer compare buffer 2 */
+#define OMAHA_TCNTO2                    0x110002C	 /*  Timer	count observation 2 */
+#define OMAHA_TCNTB3                    0x1100030	 /*  Timer count buffer 3 */
+#define OMAHA_TCMPB3                    0x1100034	 /*  Timer compare buffer 3 */
+#define OMAHA_TCNTO3                    0x1100038	 /*  Timer	count observation 3 */
+#define OMAHA_TCNTB4                    0x110003C	 /*  Timer count buffer 2 */
+#define OMAHA_TCNTO4                    0x1100040	 /*  Timer	count observation 2 */
+
+/*  DMA
+ */
+#define OMAHA_DMA_CON                   0x12001C0	 /*  DMA Interface control */
+#define OMAHA_DMA_UNIT                  0x12001C4	 /*  DMA Transfer unit counter */
+#define OMAHA_DMA_FIFO                  0x12001C8	 /*  DMA Transfer FIFO counter */
+#define OMAHA_DMA_TX                    0x12001CC	 /*  DMA Total transfer counter */
+
+/*  Watchdog
+ */
+#define OMAHA_WTCON                     0x1300000	 /*  Watchdog control register */
+#define OMAHA_WTDAT                     0x1300004	 /*  Watchdog data */
+#define OMAHA_WTCNT                     0x1300008	 /*  Watchdog count */
+#define OMAHA_WT_DEF                    0x0		 /*  Disable the watchdog */
+
+/*  IIC
+ */
+#define OMAHA_IICCON                    0x1400000	 /*  IIC Control */
+#define OMAHA_IICSTAT                   0x1400004	 /*  IIC Status */
+#define OMAHA_IICADD                    0x1400008	 /*  IIC address */
+#define OMAHA_IICDS                     0x140000C	 /*  IIC Data shift */
+
+/*  IIS
+ */
+#define OMAHA_IISCON                    0x1508000	 /*  IIS Control */
+#define OMAHA_IISMOD                    0x1508004	 /*  IIS Mode */
+#define OMAHA_IISPSR                    0x1508008	 /*  IIS Prescaler */
+#define OMAHA_IISFIFOCON                0x150800C	 /*  IIS FIFO control */
+#define OMAHA_IISFIF                    0x1508010	 /*  IIS Fifo entry */
+
+/*  I/O Ports (GPIO's)
+ */
+#define OMAHA_PACON                     0x1600000	 /*  Port A control */
+#define OMAHA_PADAT                     0x1600004	 /*  Port A data */
+#define OMAHA_PBCON                     0x1600008	 /*  Port B control */
+#define OMAHA_PBDAT                     0x160000C	 /*  Port B data */
+#define OMAHA_PBUP                      0x1600010	 /*  Port B pull-up control */
+#define OMAHA_PCCON                     0x1600014	 /*  Port C control */
+#define OMAHA_PCDAT                     0x1600018	 /*  Port C data */
+#define OMAHA_PCUP                      0x160001C	 /*  Port C pull-up */
+#define OMAHA_PDCON                     0x1600020	 /*  Port D control */
+#define OMAHA_PDDAT                     0x1600024	 /*  Port D data */
+#define OMAHA_PDUP                      0x1600028	 /*  Port D pull-up */
+#define OMAHA_PECON                     0x160002C	 /*  Port E control */
+#define OMAHA_PEDAT                     0x1600030	 /*  Port E data */
+#define OMAHA_PEUP                      0x1600034	 /*  Port E pull-up */
+#define OMAHA_PFCON                     0x1600038	 /*  Port F control */
+#define OMAHA_PFDAT                     0x160003C	 /*  Port F data */
+#define OMAHA_PFUP                      0x1600040	 /*  Port F pull-up */
+#define OMAHA_PGCON                     0x1600044	 /*  Port G control */
+#define OMAHA_PGDAT                     0x1600048	 /*  Port G data */
+#define OMAHA_PGUP                      0x160004C	 /*  Port G pull-up */
+#define OMAHA_OPENCR                    0x1600050	 /*  Open Drain enable */
+#define OMAHA_MISCCR                    0x1600054	 /*  Misc. control */
+#define OMAHA_EXTINT                    0x1600058	 /*  External interrupt control */
+
+/*  RTC
+ */
+#define OMAHA_RTCCON                    0x1700040	 /*  RTC Control */
+#define OMAHA_TICINT                    0x1700044	 /*  Tick time count */
+#define OMAHA_RTCALM                    0x1700050	 /*  RTC Alarm control */
+#define OMAHA_ALMSEC                    0x1700054	 /*  Alarm Second */
+#define OMAHA_ALMMIN                    0x1700058	 /*  Alarm Minute */
+#define OMAHA_ALMHOUR                   0x170005C	 /*  Alarm Hour */
+#define OMAHA_ALMDAY                    0x1700060	 /*  Alarm Day */
+#define OMAHA_ALMMON                    0x1700064	 /*  Alarm Month */
+#define OMAHA_ALMYEAR                   0x1700068	 /*  Alarm Year */
+#define OMAHA_RTCRST                    0x170006C	 /*  RTC Round Reset */
+#define OMAHA_BCDSEC                    0x1700070	 /*  BCD Second */
+#define OMAHA_BCDMIN                    0x1700074	 /*  BCD Minute */
+#define OMAHA_BCDHOUR                   0x1700078	 /*  BCD Hour */
+#define OMAHA_BCDDAY                    0x170007C	 /*  BCD Day */
+#define OMAHA_BCDDATE                   0x1700080	 /*  BCD Date */
+#define OMAHA_BCDMON                    0x1700084	 /*  BCD Month */
+#define OMAHA_BCDYEAR                   0x1700088	 /*  BCD Year */
+
+/*  ADC
+ */
+#define OMAHA_ADCCON                    0x1800000	 /*  ADC control */
+#define OMAHA_ADCDAT                    0x1800004	 /*  ADC data */
+
+/*  SPI
+ */
+#define OMAHA_SPCON                     0x1900000	 /*  SPI Control */
+#define OMAHA_SPSTA                     0x1900004	 /*  SPI status */
+#define OMAHA_SPPIN                     0x1900008	 /*  SPI pin control */
+#define OMAHA_SPPRE                     0x190000C	 /*  Baud rate prescaler */
+#define OMAHA_SPTDAT                    0x1900010	 /*  SPI Tx data */
+#define OMAHA_SPRDAT                    0x1900014	 /*  SPI Rx data */
+
+/*  MMC
+ */
+
+/*  Memory timings
+ */
+
+/*  nGCS0: 8-bit r/o, no-wait. boot flash
+ *  nGCS1: 32-bit, r/w, no-wait. PLD (inc. ethernet)
+ *  nGCS2: 16-bit, r/w, wait. CompactFlash+USB2
+ *  nGCS3: 32-bit, r/w, no-wait. FPGA
+ *  nGCS4: 32-bit, r/w, no-wait. Expansion Bus
+ *  nGCS5: 32-bit, r/w, no-wait. Expansion Bus
+ *  nGCS6: 32-bit, r/w, no-wait. SDRAM bank 0
+ *  nGCS7: 32-bit, r/w, no-wait. SDRAM bank 1
+ */
+
+#define OMAHA_BWSCON_DEF                0x222221A0	 /*  All 32-bit, r/w, no-wait */
+
+/*  Functions:
+ *  CS0	- Flash bank 0
+ *  CS1	- PLD
+ *  CS2	- FPGA
+ *  CS3	- FPGA
+ *  CS4	- PCMCIA0 (Unused)
+ *  CS5	- PCMCIA1 (Unused)
+ */
+	
+/*  CS0 Intel flash devices: 
+ */
+#define OMAHA_BANKCON0_DEF              0x00007FFC	 /*  Maximum clocks/function */
+#define OMAHA_BANKCON1_DEF              0x00007FFC	 /*  Maximum clocks/function */
+#define OMAHA_BANKCON2_DEF              0x00007FFC	 /*  Maximum clocks/function */
+#define OMAHA_BANKCON3_DEF              0x00002400	 /*  tacs=1, tacc = 6clks */
+#define OMAHA_BANKCON4_DEF              0x00007FFC	 /*  Maximum clocks/function */
+#define OMAHA_BANKCON5_DEF              0x00007FFC	 /*  Maximum clocks/function */
+	  
+/*  CS6 SDRAM0 
+ */
+#define OMAHA_BANKCON6_DEF              0x00018001	 /*  9-bit, 2clks */
+
+/*  CS7 SDRAM1
+ */
+#define OMAHA_BANKCON7_DEF              0x00018001	 /*  9-bit, 2clks */
+
+/*  refresh (Assumes HCLK = 66MHz)
+ *  refresh period = 64msecs (from datasheet) for 8K cycles (8usecs each)
+ *  @66MHz busclock, this is 533 cycles...
+ */
+#define OMAHA_REFRESH_DEF               0x00A405EC	 /*  Refresh enabled, max clk. */
+
+#define OMAHA_BANKSIZE_DEF              0x00000000	 /*  32Mb/32Mb */
+
+/*  mode register	(CL = 3)
+ */
+#define OMAHA_MRSRB6_DEF                0x00000030
+#define OMAHA_MRSRB7_DEF                0x00000030
+
+/* -----------------------------------------------------------------------
+ *  CPU Clocking
+ * -----------------------------------------------------------------------
+ */
+
+/*  There are three important clock domains
+ *  FCLK - CPU clock
+ *  HCLK - AHB clock
+ *  PCLK - APB clock
+ */
+
+/*  All clocks are derived from a 12MHz Xtal fed through
+ *  PLL's and dividers.
+ * 
+ *  Note:
+ *  HCLK = FCLK / 2
+ *  PCLK = HCLK / 2
+ * 
+ *  Eg. for FCLK = 133MHz, HCLK = 66MHz, PCLK = 33MHz
+ */
+
+#define OMAHA_LOCKTIME_DEF              0xFFFFFF	 /*  PLL synchronization time */
+
+/*  Nearest values (Samsung recommended from 12MHz xtal)
+ */
+#define OMAHA_CLK_33M                   0x25003		 /* ; 33.75 MHz */
+#define OMAHA_CLK_66M                   0x25002		 /*   67.50 MHz */
+#define OMAHA_CLK_100M                  0x2B011		 /*  102.00 MHz */
+#define OMAHA_CLK_133M                  0x51021		 /*  133.50 MHz */
+
+/*  Full speed ahead!
+ */
+#define OMAHA_CLK_DEFAULT               OMAHA_CLK_133M	
+
+/*  Don't trust the PLL, use SLOW mode (HCLK = 12MHz direct)
+ * OMAHA_SLOW		EQU	1
+ */
+
+/* -----------------------------------------------------------------------
+ *  From PrimeCell UART (PL010) Block Specification (ARM-DDI-0139B)
+ * -----------------------------------------------------------------------
+ *  UART Base register absolute address
+ */
+#define OMAHA_UART0_BASE                0x15000000	 /*  Uart 0 base */
+#define OMAHA_UART1_BASE                0x15004000	 /*  Uart 1 base */
+
+/*  Offsets into registers of each UART controller
+ */
+#define OMAHA_ULCON                     0x00		 /*  Line control */
+#define OMAHA_UCON                      0x04		 /*  Control */
+#define OMAHA_UFCON                     0x08		 /*  FIFO control */
+#define OMAHA_UMCON                     0x0C		 /*  Modem control */
+#define OMAHA_UTRSTAT                   0x10		 /*  Rx/Tx status */
+#define OMAHA_UERSTAT                   0x14		 /*  Rx Error Status */
+#define OMAHA_UFSTAT                    0x18		 /*  FIFO status */
+#define OMAHA_UMSTAT                    0x1C		 /*  Modem status */
+#define OMAHA_UTXH                      0x20		 /*  Transmission Hold (byte wide) */
+#define OMAHA_URXH                      0x24		 /*  Receive buffer (byte wide) */
+#define OMAHA_UBRDIV                    0x28		 /*  Baud rate divisor */
+
+/*  UART status flags in OMAHA_UTRSTAT
+ */
+#define OMAHA_URX_FULL                  0x1		 /*  Receive buffer has valid data */
+#define OMAHA_UTX_EMPTY                 0x2		 /*  Transmitter has finished */
+
+/* Baud rates supported on the uart. */
+
+#define ARM_BAUD_460800                 460800
+#define ARM_BAUD_230400                 230400
+#define ARM_BAUD_115200                 115200
+#define ARM_BAUD_57600                  57600
+#define ARM_BAUD_38400                  38400
+#define ARM_BAUD_19200                  19200
+#define ARM_BAUD_9600                   9600
+
+/*  LEDs
+ *  These are connected to GPIO Port C
+ */
+#define PLAT_DBG_LEDS                   (PLAT_PERIPHERAL_BASE + OMAHA_PCDAT)	
+
+/* -----------------------------------------------------------------------
+ *  Interrupts
+ * -----------------------------------------------------------------------
+ */
+
+/*  Interrupt numbers
+ */
+#define OMAHA_INT_EINT0                 0	 /*  FPGA */
+#define OMAHA_INT_EINT1                 1	 /*  PLD */
+#define OMAHA_INT_EINT2                 2	 /*  Expansion Bus */
+#define OMAHA_INT_EINT3                 3	 /*  Ethernet */
+#define OMAHA_INT_EINT4                 4	 /*  USB2 */
+#define OMAHA_INT_EINT5                 5	 /*  Fan */
+#define OMAHA_INT_EINT6                 6	 /*  unused */
+#define OMAHA_INT_EINT7                 7	 /*  unused */
+#define OMAHA_INT_TICK                  8
+#define OMAHA_INT_WDT                   9
+#define OMAHA_INT_TIMER0                10
+#define OMAHA_INT_TIMER1                11
+#define OMAHA_INT_TIMER2                12
+#define OMAHA_INT_TIMER3                13
+#define OMAHA_INT_TIMER4                14
+#define OMAHA_INT_UERR                  15
+/*  16 Unused
+ */
+#define OMAHA_INT_DMA0                  17
+#define OMAHA_INT_DMA1                  18
+#define OMAHA_INT_DMA2                  19
+#define OMAHA_INT_DMA3                  20
+#define OMAHA_INT_MMC                   21
+#define OMAHA_INT_SPI                   22
+#define OMAHA_INT_URXD0                 23
+#define OMAHA_INT_URXD1                 24
+#define OMAHA_INT_USBD                  25
+#define OMAHA_INT_USBH                  26
+#define OMAHA_INT_IIC                   27
+#define OMAHA_INT_UTXD0                 28
+#define OMAHA_INT_UTXD1                 29
+#define OMAHA_INT_RTC                   30
+#define OMAHA_INT_ADC                   31
+
+/* -----------------------------------------------------------------------
+ *  PLD Control registers (offset from PLAT_PLD_BASE)
+ * -----------------------------------------------------------------------
+ */
+
+/*  register offsets from PLAT_PLD_BASE
+ */
+#define PLD_FPGA_ID                     0x00	 /*  8-bit FPGA ID number (ro) */
+#define PLD_INT_CTRL                    0x04	 /*  Interrupt control */
+#define PLD_INT_STATUS                  0x08	 /*  Interrupt status */
+#define PLD_WAIT_STATUS                 0x0C	 /*  IO device wait status */
+#define PLD_ID                          0x10	 /*  PCB revision number */
+#define PLD_BUS                         0x14	 /*  Expansion bus control register */
+#define PLD_TEST                        0x18	 /*  8-bit test register (rw) */
+#define PLD_CF                          0x1C	 /*  CompactFlash control */
+#define PLD_DMA_CTRL                    0x20	 /*  DMA Control register */
+
+/*  PLD Register bitdefs
+ */
+
+/*  PLD_FPGA_ID		; contains FPGA Iden
+ */
+
+/*  INT_CTRL bit-defs
+ */
+#define PLD_INT_CTRL_USB                BIT0	 /*  USB */
+#define PLD_INT_CTRL_LAN                BIT1	 /*  Ethernet */
+
+/*  INT_STATUS bit-defs
+ */
+#define PLD_INT_STATUS_CF_IDE           BIT0	 /*  CF True-IDE mode (r/w) */
+#define PLD_INT_STATUS_nDATACS          BIT1	 /*  SMC91C111 nDATACS control (r/w) */
+#define PLD_INT_STATUS_CF_RDY           BIT2	 /*  CompactFlash ready (r/o) */
+#define PLD_INT_STATUS_nWP              BIT3	 /*  Flash write protect (r/w) */
+
+/*  WAIT_STATUS bit-defs
+ */
+#define PLD_WAIT_STATUS_USB             BIT0	 /*  USB wait signal active */
+#define PLD_WAIT_STATUS_LAN             BIT1	 /*  Ethernet wait signal active */
+#define PLD_WAIT_STATUS_CF              BIT2	 /*  CompactFlash wait status */
+
+/*  ID		; Contains PLD Id
+ */
+
+/*  BOARD_ADDR
+ */
+
+#define PLD_BUS_ADDR                    0x0F	 /*  4-bit expansion bus address */
+#define PLD_BUS_nACK                    BIT4	 /*  BUS nACK */
+#define PLD_BUS_nCLR                    BIT5	 /*  BUS nCLR */
+#define PLD_BUS_nSTR                    BIT6	 /*  BUS nSTR */
+#define PLD_BUS_DONE                    BIT7	 /*  BUS Done */
+
+/*  TEST		; 8-bit r/w any value.
+ */
+
+/*  CF status bitdefs
+ */
+#define PLD_CF_WP                       BIT0	 /*  r/w */
+#define PLD_CF_RDY                      BIT1	 /*  CF_RDY r/o */
+#define PLD_CF_VS1                      BIT2	 /*  Voltage Sense 1. r/o */
+#define PLD_CF_VS2                      BIT3	 /*  Voltage Sense 2. r/o */
+#define PLD_CF_RESET                    BIT4	 /*  Reset. r/w (TrueIDE active low/else high) */
+#define PLD_CF_CD                       BIT5	 /*  Card Detect (1 AND 2). r/o */
+#define PLD_CF_BVD                      BIT6	 /*  Batt. Voltage Detect (1 AND 2). r/o */
+#define PLD_CF_nINPACK                  BIT7	 /*  Input Acknowlegde. r/o */
+
+/*  DMA_CTRL
+ */
+#define PLD_DMA_BUS                     BIT4	 /*  Bus DMA request. r/w */
+#define PLD_DMA_USB                     BIT5	 /*  USB DMA request. r/w */
+#define PLD_DMA_FPGA                    BIT6	 /*  FPGA DMA request. r/w */
+
+/* =======================================================================
+ *  Start of uHAL definitions
+ * =======================================================================
+ */
+
+#define MAXIRQNUM                       31
+ 
+#define NR_IRQS                         (MAXIRQNUM + 1)
+
+/* -----------------------------------------------------------------------
+ *  LEDs - One available
+ * -----------------------------------------------------------------------
+ * 
+ */
+#define uHAL_LED_ON                     1
+#define uHAL_LED_OFF                    0
+#define uHAL_NUM_OF_LEDS                4
+
+/*  Colours may not match reality...
+ */
+#define GREEN_LED                       BIT8
+#define YELLOW_LED                      BIT9
+#define RED_LED                         BIT10
+#define RED_LED_1                       BIT11
+#define ALL_LEDS                        (RED_LED | RED_LED_1 | YELLOW_LED | GREEN_LED)						    
+
+#define LED_BANK                        PLAT_DBG_LEDS
+
+/*  LED definitions.		
+ *  The bit patterns & base addresses of the individual LEDs
+ */
+#define uHAL_LED_MASKS		{0, GREEN_LED, YELLOW_LED, RED_LED, RED_LED_1}
+#define uHAL_LED_OFFSETS	{0, (void *)LED_BANK, (void *)LED_BANK, (void *)LED_BANK}
+
+
+/* -----------------------------------------------------------------------
+ *  Memory definitions - run uHAL out of SDRAM.  Reserve top 64K for MMU.
+ */
+#define uHAL_MEMORY_SIZE                PLAT_USER_SDRAM_SIZE
+
+
+/*  Application Flash
+ */
+#define FLASH_BASE                      PLAT_FLASH_BASE
+#define WFLASH_BASE                     PLAT_FLASH_UNCACHED
+#define FLASH_SIZE                      PLAT_FLASH_SIZE
+#define FLASH_END                       (FLASH_BASE + FLASH_SIZE - 1)
+#define FLASH_BLOCK_SIZE                SZ_4K
+
+/*  Reserve the first sector of flash for the boot switcher.
+ *  Note: Changes to PLAT_BOOT_ROM_HI will have to be reflected in
+ *  FlashLibrary/Boards/P920/flashMap.h
+ */
+#define PLAT_BOOT_ROM_HI                FLASH_BASE
+#define PLAT_BOOT_ROM_SIZE              (FLASH_BLOCK_SIZE*0)
+
+/*  Boot Flash
+ */
+#define EPROM_BASE                      PLAT_BOOT_ROM_HI
+#define EPROM_SIZE                      PLAT_BOOT_ROM_SIZE
+#define EPROM_END                       (EPROM_BASE + EPROM_SIZE - 1)
+
+
+/*  Clean base - an area of memory (usually fast access) which can be read
+ *  to ensure the data caches are flushed. 
+ */
+#define CLEAN_BASE                      EPROM_BASE
+
+/* -----------------------------------------------------------------------
+ *  UART definitions
+ */
+
+/*  Which com port can the OS use?
+ * 
+ */
+/* Default port to talk to host (via debugger) */
+#define HOST_COMPORT                    OMAHA_UART0_BASE
+#define HOST_IRQBIT_NUMBER              OMAHA_INT_URXD0
+#define HOST_IRQBIT                     (1 << HOST_IRQBIT_NUMBER)
+
+/* Default port for use by Operating System or program */
+#define OS_COMPORT                      OMAHA_UART0_BASE
+#define OS_IRQBIT_NUMBER                OMAHA_INT_URXD0
+#define OS_IRQBIT                       (1 << OS_IRQBIT_NUMBER)
+
+#define DEBUG_COMPORT                   OS_COMPORT
+#define DEBUG_IRQBIT                    OS_IRQBIT
+
+/* Values to set given baud rates */
+#define DEFAULT_HOST_BAUD               ARM_BAUD_9600
+#define DEFAULT_OS_BAUD                 ARM_BAUD_38400
+
+/* 'C' macros to access comports */
+#define GET_STATUS(p)		(IO_READ((p) + OMAHA_UTRSTAT))
+#define GET_CHAR(p)		((IO_READ((p) + OMAHA_URXH)) & 0xFF)
+#define PUT_CHAR(p, c)		(IO_WRITE(((p) + OMAHA_UTXH), (c)))
+#define IO_READ(p)             (*(volatile unsigned int *)(p))
+#define IO_WRITE(p, c)         (*(unsigned int *)(p) = (c))
+#define IO_MASK_WRITE(p, m, c) IO_WRITE(p, (IO_READ(p) & ~(m)) | (c))
+#define IO_SET(p, c)	        IO_WRITE(p, (IO_READ(p) | (c)))
+#define IO_CLEAR(p, c)         IO_WRITE(p, (IO_READ(p) & ~(c)))
+#define RX_DATA(s)		(((s) & OMAHA_URX_FULL))
+#define TX_READY(s)		(((s) & OMAHA_UTX_EMPTY))
+#define TX_EMPTY(p)		((GET_STATUS(p) & OMAHA_UTX_EMPTY) != 0)
+
+
+/* -----------------------------------------------------------------------
+ *  Timer definitions
+ * 
+ *  There are 5 16-bit countdown timers on-chip.
+ *  These are all driven by PCLK, running at whatever Mhz.
+ *  For now we shall clock all the timers at 1MHz (arranged by uHAL)
+ */
+
+#define PLAT_TIMER1_BASE                (PLAT_PERIPHERAL_BASE + OMAHA_TCNTB0)
+#define PLAT_TIMER2_BASE                (PLAT_PERIPHERAL_BASE + OMAHA_TCNTB1)
+#define PLAT_TIMER3_BASE                (PLAT_PERIPHERAL_BASE + OMAHA_TCNTB2)
+#define PLAT_TIMER4_BASE                (PLAT_PERIPHERAL_BASE + OMAHA_TCNTB3)
+#define PLAT_TIMER5_BASE                (PLAT_PERIPHERAL_BASE + OMAHA_TCNTB4)
+
+
+#define MAX_TIMER                       5
+/*  Maximum time interval we can handle (in microseconds)
+ *  = max_ticks / ticks_per_us ( = 65535 / 0.2)
+ */
+
+/*  Maximum period in uSecs
+ */
+#define MAX_PERIOD                      131072
+			  	
+#define PLAT_uS_TO_TICK(t) (t*1)
+
+/*  These are useconds NOT ticks.  
+ */
+#define mSEC_1                          1000
+#define mSEC_5                          (mSEC_1 * 5)
+#define mSEC_10                         (mSEC_1 * 10)
+#define mSEC_25                         (mSEC_1 * 25)
+#define SEC_1                           (mSEC_1 * 1000)
+
+/*  SEMIHOSTED Debugger doesn't use a timer by default. If it requires a
+ *  timer (eg for profiling), set HOST_TIMER to MAX_TIMER
+ */
+#define HOST_TIMER                      0
+#define OS_TIMER                        1
+#define OS_TIMERINT                     OMAHA_INT_TIMER1
+
+
+/*  Timer definitions.		
+ *  The irq numbers & base addresses of the individual timers
+ */
+#define TIMER_VECTORS	{0, OMAHA_INT_TIMER0, OMAHA_INT_TIMER1, OMAHA_INT_TIMER2, OMAHA_INT_TIMER3, OMAHA_INT_TIMER4}
+#define TIMER_BASES	{0, (void *)PLAT_TIMER1_BASE, (void *)PLAT_TIMER2_BASE, (void *)PLAT_TIMER3_BASE, (void *)PLAT_TIMER4_BASE, (void *)PLAT_TIMER5_BASE}
+
+
+/* -----------------------------------------------------------------------
+ *  Number of Level2 table entries in uHAL_AddressTable
+ *  Each entry contains 256 32-bit descriptors
+ */
+#define L2_TABLE_ENTRIES                0
+
+
+/* macros to map from PCI memory/IO addresses to local bus addresses
+ */
+#define _MapAddress(a)		(a)
+#define _MapIOAddress(a)	(a)
+#define _MapMemAddress(a)	(a)
+
+
+#define ALLBITS                         0xffffffff
+
+
+#ifdef uHAL_HEAP
+#if USE_C_LIBRARY != 0
+#define uHAL_HEAP_BASE                  (PLAT_SDRAM_BASE + SZ_1M)
+#define uHAL_HEAP_SIZE                  (SZ_16M - SZ_1M - SZ_1M - 4)
+#define uHAL_STACK_BASE                 SZ_16M
+#define uHAL_STACK_SIZE                 SZ_1M
+#else
+#define uHAL_HEAP_BASE                  (PLAT_SDRAM_BASE + PLAT_SDRAM_SIZE - SZ_64K)
+#define uHAL_HEAP_SIZE                  SZ_16K
+#define uHAL_STACK_SIZE                 SZ_16K
+#define uHAL_STACK_BASE                 (uHAL_HEAP_BASE + SZ32K)
+#endif
+#endif
+
+
+#endif
+
+/* 	END */
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/serial.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/serial.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/serial.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/serial.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,43 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/serial.h
+ *
+ *  Copyright (C) 1999-2002 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/arch/platform.h>
+#include <asm/irq.h>
+
+/*
+ * Baud rate is a function of the cpu PCLK... assume 10 MHz for now.
+ */
+#define BASE_BAUD (10000000 / 16)
+
+#define _SER_IRQ0	OMAHA_INT_URXD0
+
+#define RS_TABLE_SIZE	1
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+     /* UART CLK        PORT  IRQ     FLAGS        */
+#define STD_SERIAL_PORT_DEFNS \
+	{ 0, BASE_BAUD, 0x3F8, _SER_IRQ0, STD_COM_FLAGS },	/* ttyS0 */	\
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/system.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/system.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/system.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,54 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/system.h
+ *
+ *  Copyright (C) 1999-2002 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+static void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle(0);
+}
+
+static inline void arch_reset(char mode)
+{
+	volatile unsigned int wtcon = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_WTCON);
+	volatile unsigned int wtdat = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_WTDAT);
+	volatile unsigned int wtcnt = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_WTCNT);
+		
+	// Let the watchdog bite. It will timeout and reset the CPU!
+	
+	// Minimum count until the end
+	__raw_writel(1,wtdat);
+	__raw_writel(1,wtcnt);
+
+	// Enable wathdog in reset mode
+	__raw_writel(0x21,wtcon);
+	
+	while(1);
+}
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/time.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/time.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/time.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/time.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,117 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/time.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <asm/system.h>
+#include <asm/leds.h>
+
+#define TIMER_INTERVAL	mSEC_10
+
+extern unsigned long (*gettimeoffset)(void);
+
+/*
+ * Returns number of ms since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long omaha_gettimeoffset(void)
+{
+	volatile unsigned int *p;
+	unsigned long ticks1, ticks2;
+
+	/*
+	 * Get the current number of ticks.  Note that there is a race
+	 * condition between us reading the timer and checking for
+	 * an interrupt.  We get around this by ensuring that the
+	 * counter has not reloaded between our two reads.
+	 */
+	p = (unsigned int *)(IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_TCNTB0));
+	
+	// Its only 16-bits
+	ticks2 = __raw_readl(p);
+	
+	do {
+		ticks1 = ticks2;
+		ticks2 =  __raw_readl(p);
+	} while (ticks2 > ticks1);
+
+	/*
+	 * Number of ticks since last interrupt.
+	 */
+	ticks1 = TIMER_INTERVAL - ticks2;
+
+	// Return number of usecs since last interrupt
+	return ticks1;
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static void omaha_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	volatile unsigned int *p;
+	int tmp;
+	
+	// Clear the interrupt pending register
+	p = (unsigned int *)(IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_SRCPND));
+	
+	tmp = __raw_readl(p);
+	tmp = tmp & ~OMAHA_INT_TIMER0;
+	__raw_writel(tmp, p);
+
+	do_leds();
+	do_timer(regs);
+	do_profile(regs);
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ *
+ * The bootloader ensures that the timer always counts at 1MHz.
+ */
+static inline void setup_timer(void)
+{
+	volatile unsigned int *p;
+	int tmp;
+
+	timer_irq.handler = omaha_timer_interrupt;
+
+	/*
+	 * Program reload count.
+	 */
+	p = (unsigned int *)(IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_TCNTB0));
+	
+	__raw_writel(TIMER_INTERVAL, p);
+	
+	// Set manual update bit, clear start bit
+	p = (unsigned int *)(IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_TCON));
+	tmp = __raw_readl(p);
+	tmp = tmp | 0x2;
+	tmp = tmp & ~0x1;
+	__raw_writel(tmp, p);
+	
+	// Clear manual update bit and set start bit
+	p = (unsigned int *)(IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_TCON));
+	tmp = __raw_readl(p);
+	tmp = tmp & ~0x2;
+	tmp = tmp | 0x1;
+	__raw_writel(tmp, p);	
+
+	/* 
+	 * Make irqs happen for the system timer
+	 */
+	setup_arm_irq(OMAHA_INT_TIMER0, &timer_irq);
+	gettimeoffset = omaha_gettimeoffset;
+}
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/timex.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/timex.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/timex.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/timex.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,37 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/timex.h
+ *
+ *  Omaha architecture timex specifications
+ *
+ *  Copyright (C) 1999-2002 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Always runs at (almost) 1Mhz.
+ *
+ * Time is derived as follows
+ *
+ * CLOCK_TICK_RATE = ((FCLK / 4) / (Prescaler + 1)) / 2
+ *
+ * Where FCLK = CPU Clock Rate = 133 MHz
+ * Prescaler = 16
+ *
+ * Therefore:
+ * CLOCK_TICK_RATE = (33.25 MHz / 17) / 2
+ *                 = 977941 Hz
+ */
+#define CLOCK_TICK_RATE		(977941)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/uncompress.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/uncompress.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/uncompress.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/uncompress.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,26 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/uncompress.h
+ *
+ *  Copyright (C) 1999-2002 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-omaha/vmalloc.h linux-2.4.22-pre3/include/asm-arm/arch-omaha/vmalloc.h
--- linux-2.4.22-pre2/include/asm-arm/arch-omaha/vmalloc.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-omaha/vmalloc.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-arm/arch-omaha/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/acornfb.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/acornfb.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/acornfb.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/acornfb.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,104 @@
+/*
+ *  linux/include/asm-arm/arch-rpc/acornfb.h
+ *
+ *  Copyright (C) 1999 Russell King
+ *  Copyright (C) 2002 Simtec Electronics / Ben Dooks / Vincent Sanders
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  AcornFB architecture specific code
+ */
+
+#define acornfb_valid_pixrate(rate) (1)
+
+/*
+ * Try to find the best PLL parameters for the pixel clock.
+ * This algorithm seems to give best predictable results,
+ * and produces the same values as detailed in the VIDC20
+ * data sheet.
+ */
+static inline u_int
+acornfb_vidc20_find_pll(u_int pixclk)
+{
+	u_int r, best_r = 2, best_v = 2;
+	int best_d = 0x7fffffff;
+
+	for (r = 2; r <= 32; r++) {
+		u_int rr, v, p;
+		int d;
+
+		rr = 31250 * r;
+
+		v = (rr + pixclk / 2) / pixclk;
+
+		if (v > 32 || v < 2)
+			continue;
+
+		p = (rr + v / 2) / v;
+
+		d = pixclk - p;
+
+		if (d < 0)
+			d = -d;
+
+		if (d < best_d) {
+			best_d = d;
+			best_v = v - 1;
+			best_r = r - 1;
+		}
+
+		if (d == 0)
+			break;
+	}
+
+	return best_v << 8 | best_r;
+}
+
+static inline void
+acornfb_vidc20_find_rates(struct vidc_timing *vidc,
+			  struct fb_var_screeninfo *var)
+{
+	u_int div, bandwidth;
+
+	/* Select pixel-clock divisor to keep PLL in range */
+	div = var->pixclock / 9090; /*9921*/
+
+	/* Limit divisor */
+	if (div == 0)
+		div = 1;
+	if (div > 8)
+		div = 8;
+
+	/* Encode divisor to VIDC20 setting */
+	switch (div) {
+	case 1:	vidc->control |= VIDC20_CTRL_PIX_CK;  break;
+	case 2:	vidc->control |= VIDC20_CTRL_PIX_CK2; break;
+	case 3:	vidc->control |= VIDC20_CTRL_PIX_CK3; break;
+	case 4:	vidc->control |= VIDC20_CTRL_PIX_CK4; break;
+	case 5:	vidc->control |= VIDC20_CTRL_PIX_CK5; break;
+	case 6:	vidc->control |= VIDC20_CTRL_PIX_CK6; break;
+	case 7:	vidc->control |= VIDC20_CTRL_PIX_CK7; break;
+	case 8: vidc->control |= VIDC20_CTRL_PIX_CK8; break;
+	}
+
+	/* Calculate bandwidth */
+	bandwidth = var->pixclock * 8 / var->bits_per_pixel;
+
+	/* Encode bandwidth as VIDC20 setting */
+	if (bandwidth > 33334)
+		vidc->control |= VIDC20_CTRL_FIFO_16;	/* < 30.0MB/s */
+	else if (bandwidth > 26666)
+		vidc->control |= VIDC20_CTRL_FIFO_20;	/* < 37.5MB/s */
+	else if (bandwidth > 22222)
+		vidc->control |= VIDC20_CTRL_FIFO_24;	/* < 45.0MB/s */
+	else
+		vidc->control |= VIDC20_CTRL_FIFO_28;	/* > 45.0MB/s */
+
+	/* Find the PLL values */
+	vidc->pll_ctl  = acornfb_vidc20_find_pll(var->pixclock / div);
+}
+
+#define acornfb_default_control()	(VIDC20_CTRL_PIX_VCLK)
+#define acornfb_default_econtrol()	(VIDC20_ECTL_DAC | VIDC20_ECTL_REG(3))
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/dma.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/dma.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/dma.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/dma.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,14 @@
+/*
+ *  linux/include/asm-arm/arch-rs/dma.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (c) 2002 Simtec Electronics / Ben Dooks
+ */
+
+/* identical to the arch-rpc implementation (bjd) */
+
+#include <asm/arch-rpc/dma.h>
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/hardware.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/hardware.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/hardware.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/hardware.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,69 @@
+/*
+ *  linux/include/asm-arm/arch-rpc/hardware.h
+ *
+ *  Copyright (C) 1996-1999 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  This file contains the hardware definitions of the RiscPC series machines.
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/arch/memory.h>
+
+/*
+ * What hardware must be present
+ */
+#define HAS_IOMD
+#define HAS_VIDC20
+
+/* Hardware addresses of major areas.
+ *  *_START is the physical address
+ *  *_SIZE  is the size of the region
+ *  *_BASE  is the virtual address
+ */
+#define RAM_SIZE		0x10000000
+#define RAM_START		0x10000000
+
+#define EASI_SIZE		0x08000000	/* EASI I/O */
+#define EASI_START		0x08000000
+#define EASI_BASE		0xe5000000
+
+#define IO_START		0x03000000	/* I/O */
+#define IO_SIZE			0x01000000
+#define IO_BASE			0xe0000000
+
+#define SCREEN_START		0x02000000	/* VRAM */
+#define SCREEN_END		0xdfc00000
+#define SCREEN_BASE		0xdf800000
+
+#define FLUSH_BASE		0xdf000000
+#define UNCACHEABLE_ADDR	0xdf010000
+
+/*
+ * IO Addresses
+ */
+#define VIDC_BASE		0xe0400000
+#define EXPMASK_BASE		0xe0360000
+#define IOMD_BASE		0xe0200000
+#define IOC_BASE		0xe0200000
+#define PCIO_BASE		0xe0010000
+#define FLOPPYDMA_BASE		0xe002a000
+
+#define FLUSH_BASE_PHYS		0x00000000	/* ROM */
+
+#define vidc_writel(val)	__raw_writel(val, VIDC_BASE)
+
+#define IO_EC_EASI_BASE		0x81400000
+#define IO_EC_IOC4_BASE		0x8009c000
+#define IO_EC_IOC_BASE		0x80090000
+#define IO_EC_MEMC8_BASE	0x8000ac00
+#define IO_EC_MEMC_BASE		0x80000000
+
+#define	EXPMASK_STATUS		(EXPMASK_BASE + 0x00)
+#define EXPMASK_ENABLE		(EXPMASK_BASE + 0x04)
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/ide.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/ide.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/ide.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/ide.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,46 @@
+/*
+ *  linux/include/asm-arm/arch-rs/ide.h
+ *
+ *  Copyright (C) 1997 Russell King
+ *  Copyright (C) 2002 Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Modifications:
+ *   29-07-1998	RMK	Major re-work of IDE architecture specific code
+ */
+
+#include <asm/irq.h>
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+	ide_ioreg_t reg = (ide_ioreg_t) data_port;
+	int i;
+
+	memset(hw, 0, sizeof(*hw));
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 1;
+	}
+	hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port;
+	if (irq)
+		*irq = 0;
+}
+
+/* we initialise our ide devices from the main ide core, due to problems
+ * with doing it in this function
+*/
+
+static __inline__ void
+ide_init_default_hwifs(void)
+{
+}
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/io.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/io.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/io.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/io.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,14 @@
+/*
+ *  linux/include/asm-arm/arch-rs/io.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (c) 2002 Simtec Electronics / Ben Dooks
+ */
+
+/* identical to the arch-rpc implementation (bjd) */
+
+#include <asm/arch-rpc/io.h>
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/irq.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/irq.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/irq.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/irq.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,209 @@
+/*
+ *  linux/include/asm-arm/arch-rpc/irq.h
+ *
+ *  Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   10-10-1996	RMK	Brought up to date with arch-sa110eval
+ *   22-08-1998	RMK	Restructured IRQ routines
+ */
+#include <asm/hardware/iomd.h>
+#include <asm/io.h>
+
+#define fixup_irq(x) (x)
+
+static void rpc_mask_irq_ack_a(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << irq;
+	val = iomd_readb(IOMD_IRQMASKA);
+	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
+	iomd_writeb(mask, IOMD_IRQCLRA);
+}
+
+static void rpc_mask_irq_a(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << irq;
+	val = iomd_readb(IOMD_IRQMASKA);
+	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
+}
+
+static void rpc_unmask_irq_a(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << irq;
+	val = iomd_readb(IOMD_IRQMASKA);
+	iomd_writeb(val | mask, IOMD_IRQMASKA);
+}
+
+static void rpc_mask_irq_b(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << (irq & 7);
+	val = iomd_readb(IOMD_IRQMASKB);
+	iomd_writeb(val & ~mask, IOMD_IRQMASKB);
+}
+
+static void rpc_unmask_irq_b(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << (irq & 7);
+	val = iomd_readb(IOMD_IRQMASKB);
+	iomd_writeb(val | mask, IOMD_IRQMASKB);
+}
+
+
+
+static void rpc_mask_irq_c(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << (irq & 7);
+	val = iomd_readb(IOMD_IRQMASKC);
+	iomd_writeb(val & ~mask, IOMD_IRQMASKC);
+}
+
+static void rpc_unmask_irq_c(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << (irq & 7);
+	val = iomd_readb(IOMD_IRQMASKC);
+	iomd_writeb(val | mask, IOMD_IRQMASKC);
+}
+
+static void rpc_mask_irq_d(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << (irq & 7);
+	val = iomd_readb(IOMD_IRQMASKD);
+	iomd_writeb(val & ~mask, IOMD_IRQMASKD);
+}
+
+static void rpc_unmask_irq_d(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << (irq & 7);
+	val = iomd_readb(IOMD_IRQMASKD);
+	iomd_writeb(val | mask, IOMD_IRQMASKD);
+}
+
+static void rpc_mask_irq_dma(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << (irq & 7);
+	val = iomd_readb(IOMD_DMAMASK);
+	iomd_writeb(val & ~mask, IOMD_DMAMASK);
+}
+
+static void rpc_unmask_irq_dma(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << (irq & 7);
+	val = iomd_readb(IOMD_DMAMASK);
+	iomd_writeb(val | mask, IOMD_DMAMASK);
+}
+
+static void rpc_mask_irq_fiq(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << (irq & 7);
+	val = iomd_readb(IOMD_FIQMASK);
+	iomd_writeb(val & ~mask, IOMD_FIQMASK);
+}
+
+static void rpc_unmask_irq_fiq(unsigned int irq)
+{
+	unsigned int val, mask;
+
+	mask = 1 << (irq & 7);
+	val = iomd_readb(IOMD_FIQMASK);
+	iomd_writeb(val | mask, IOMD_FIQMASK);
+}
+
+static __inline__ void irq_init_irq(void)
+{
+	int irq;
+
+	iomd_writeb(0, IOMD_IRQMASKA);
+	iomd_writeb(0, IOMD_IRQMASKB);
+	iomd_writeb(0, IOMD_IRQMASKC);
+	iomd_writeb(0, IOMD_IRQMASKD);
+
+	iomd_writeb(0xff, IOMD_IOLINES);
+
+	iomd_writeb(0, IOMD_FIQMASK);
+	iomd_writeb(0, IOMD_DMAMASK);
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		switch (irq) {
+		case 0 ... 6:
+			irq_desc[irq].probe_ok = 1;
+		case 7:
+			irq_desc[irq].valid    = 1;
+			irq_desc[irq].mask_ack = rpc_mask_irq_ack_a;
+			irq_desc[irq].mask     = rpc_mask_irq_a;
+			irq_desc[irq].unmask   = rpc_unmask_irq_a;
+			break;
+
+		case 9 ... 15:
+			irq_desc[irq].probe_ok = 1;
+		case 8:
+			irq_desc[irq].valid    = 1;
+			irq_desc[irq].mask_ack = rpc_mask_irq_b;
+			irq_desc[irq].mask     = rpc_mask_irq_b;
+			irq_desc[irq].unmask   = rpc_unmask_irq_b;
+			break;
+
+		case 16 ... 19:
+		case 21:
+			irq_desc[irq].noautoenable = 1;
+		case 20:
+			irq_desc[irq].valid    = 1;
+			irq_desc[irq].mask_ack = rpc_mask_irq_dma;
+			irq_desc[irq].mask     = rpc_mask_irq_dma;
+			irq_desc[irq].unmask   = rpc_unmask_irq_dma;
+			break;
+
+		case 24 ... 31:
+		        irq_desc[irq].valid     = 1;
+			irq_desc[irq].mask_ack  = rpc_mask_irq_c;
+			irq_desc[irq].mask 	= rpc_mask_irq_c;
+			irq_desc[irq].unmask	= rpc_unmask_irq_c;
+			break;
+
+		case 40 ... 47:
+		        irq_desc[irq].valid     = 1;
+			irq_desc[irq].mask_ack  = rpc_mask_irq_d;
+			irq_desc[irq].mask 	= rpc_mask_irq_d;
+			irq_desc[irq].unmask	= rpc_unmask_irq_d;
+			break;
+
+		case 64 ... 71:
+			irq_desc[irq].valid    = 1;
+			irq_desc[irq].mask_ack = rpc_mask_irq_fiq;
+			irq_desc[irq].mask     = rpc_mask_irq_fiq;
+			irq_desc[irq].unmask   = rpc_unmask_irq_fiq;
+			break;
+		}
+	}
+
+	irq_desc[IRQ_KEYBOARDTX].noautoenable = 1;
+
+	init_FIQ();
+}
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/irqs.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/irqs.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/irqs.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/irqs.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,22 @@
+/*
+ *  linux/include/asm-arm/arch-rs/irqs.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (c) 2002 Simtec Electronics / Ben Dooks
+ */
+
+/* identical to the arch-rpc implementation (bjd) */
+
+#include <asm/arch-rpc/irqs.h>
+
+#define RTC_IRQ    (27)
+#define IRQ_MOUSERX  (40)
+#define IRQ_MOUSETX  (41)
+
+#undef IRQ_MOUSERX
+#undef IRQ_MOUSETX
+#define IRQ_MOUSERX      (40)
+#define IRQ_MOUSETX      (41)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/keyboard.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/keyboard.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/keyboard.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/keyboard.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,20 @@
+/*
+ *  linux/include/asm-arm/arch-rpc/keyboard.h
+ *
+ *  Copyright (C) 1998-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Keyboard driver definitions for RiscPC architecture
+ */
+#include <asm/irq.h>
+
+#define NR_SCANCODES 128
+
+extern int ps2kbd_init_hw(void);
+
+#define kbd_disable_irq()	disable_irq(IRQ_KEYBOARDRX)
+#define kbd_enable_irq()	enable_irq(IRQ_KEYBOARDRX)
+#define kbd_init_hw()		ps2kbd_init_hw()
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/memory.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/memory.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/memory.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,133 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/mmu.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#include <linux/config.h>
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE	(0xc0000000UL)
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET	(0xc0000000UL)
+#define PHYS_OFFSET	(0x10000000UL)
+
+/*
+ * On integrator, the dram is contiguous
+ */
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - PHYS_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *              address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *              to an address that the kernel can use.
+ */
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)	((x) - PAGE_OFFSET)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)	((x) + PAGE_OFFSET)
+
+
+/*
+ * Like the SA1100, the EDB7211 has a large gap between physical RAM
+ * banks.  In 2.2, the Psion (CL-PS7110) port added custom support for
+ * discontiguous physical memory.  In 2.4, we can use the standard
+ * Linux NUMA support.
+ *
+ * This is not necessary for EP7211 implementations with only one used
+ * memory bank.  For those systems, simply undefine CONFIG_DISCONTIGMEM.
+ */
+
+#ifdef CONFIG_DISCONTIGMEM
+/*
+ * Because of the wide memory address space between physical RAM banks on the
+ * SA1100, it's much more convenient to use Linux's NUMA support to implement
+ * our memory map representation.  Assuming all memory nodes have equal access
+ * characteristics, we then have generic discontigous memory support.
+ *
+ * Of course, all this isn't mandatory for SA1100 implementations with only
+ * one used memory bank.  For those, simply undefine CONFIG_DISCONTIGMEM.
+ *
+ * The nodes are matched with the physical memory bank addresses which are
+ * incidentally the same as virtual addresses.
+ *
+ * 	node 0:  0xc0000000 - 0xc7ffffff
+ * 	node 1:  0xc8000000 - 0xcfffffff
+ * 	node 2:  0xd0000000 - 0xd7ffffff
+ * 	node 3:  0xd8000000 - 0xdfffffff
+ */
+
+#define NR_NODES	4
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define KVADDR_TO_NID(addr) \
+		(((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
+
+/*
+ * Given a page frame number, convert it to a node id.
+ */
+#define PFN_TO_NID(pfn) \
+	(((pfn) - PHYS_PFN_OFFSET) >> (NODE_MAX_MEM_SHIFT - PAGE_SHIFT))
+
+/*
+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
+ * and returns the mem_map of that node.
+ */
+#define ADDR_TO_MAPBASE(kaddr) \
+			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
+
+#define PFN_TO_MAPBASE(pfn)	NODE_MEM_MAP(PFN_TO_NID(pfn))
+
+/*
+ * Given a kaddr, LOCAL_MAR_NR finds the owning node of the memory
+ * and returns the index corresponding to the appropriate page in the
+ * node's mem_map.
+ */
+#define LOCAL_MAP_NR(addr) \
+	(((unsigned long)(addr) & (NODE_MAX_MEM_SIZE - 1)) >> PAGE_SHIFT)
+
+/*
+ * The 7500 has up-to 64Mb of memory per bank
+ */
+#define NODE_MAX_MEM_SHIFT	26
+#define NODE_MAX_MEM_SIZE	(1<<NODE_MAX_MEM_SHIFT)
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/param.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/param.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/param.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/param.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,3 @@
+/*
+ * linux/include/asm-arm/arch-rpc/param.h
+ */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/serial.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/serial.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/serial.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/serial.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,48 @@
+/*
+ *  linux/include/asm-arm/arch-rpc/serial.h
+ *
+ *  Copyright (C) 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   15-10-1996	RMK	Created
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD (1843200 / 16)
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+#define RS_TABLE_SIZE	16
+
+     /* UART CLK        PORT  IRQ     FLAGS        */
+#define STD_SERIAL_PORT_DEFNS \
+	{ 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS },	/* ttyS0 */	\
+	{ 0, BASE_BAUD, 0x2F8, 10, STD_COM_FLAGS },	/* ttyS1 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS2 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS3 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS }, 	/* ttyS4 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS5 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS6 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS7 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS8 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS9 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS10 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS11 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS12 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS }	/* ttyS13 */
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/system.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/system.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/system.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,27 @@
+/*
+ *  linux/include/asm-arm/arch-rpc/system.h
+ *
+ *  Copyright (C) 1996-1999 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/arch/hardware.h>
+#include <asm/hardware/iomd.h>
+#include <asm/io.h>
+
+static void arch_idle(void)
+{
+    iomd_writeb(0, IOMD_SUSMODE);
+}
+
+static inline void arch_reset(char mode)
+{
+	iomd_writeb(0, IOMD_ROMCR0);
+
+	/*
+	 * Jump into the ROM
+	 */
+	cpu_reset(0);
+}
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/time.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/time.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/time.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/time.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,198 @@
+/*
+ *  linux/include/asm-arm/arch-rs/time.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (c) 2002 Simtec Electronics / Ben Dooks
+ *
+ * Bits taken from linux/include/asm-arm/arch-rpc/time.h
+ *
+ * (c) 1996-2002 Russell King
+ *
+ * Bits taken from linux/include/asm-arm/arch-ebsa285/time.h
+ *
+ * Copyright (C) 1998 Russell King.
+ * Copyright (C) 1998 Phil Blundell
+*/
+
+#define RTC_PORT(x)    (0x70 + (x))
+#define RTC_ALWAYS_BCD (0)
+
+#include <linux/mc146818rtc.h>
+#include <asm/mach-types.h>
+
+extern void ioctime_init(void);
+
+/* timer interrut - update things like profiling information and our
+ * copy of the RTC's time
+*/
+
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	do_timer(regs);
+	do_set_rtc();
+	do_profile(regs);
+}
+
+/* get_isa_cmos_time()
+ *
+ * get the time from the CMOS RTC
+ *
+ * from linux/include/asm-arm/arch-ebsa285/time.h
+*/
+
+static unsigned long get_isa_cmos_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+	int i;
+
+	// check to see if the RTC makes sense.....
+	if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0)
+		return mktime(1970, 1, 1, 0, 0, 0);
+
+	/* The Linux interpretation of the CMOS clock register contents:
+	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+	 * RTC registers show the second which has precisely just started.
+	 * Let's hope other operating systems interpret the RTC the same way.
+	 */
+	/* read RTC exactly on falling edge of update flag */
+	for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
+		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+			break;
+
+	for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
+		if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+			break;
+
+	do { /* Isn't this overkill ? UIP above should guarantee consistency */
+		sec  = CMOS_READ(RTC_SECONDS);
+		min  = CMOS_READ(RTC_MINUTES);
+		hour = CMOS_READ(RTC_HOURS);
+		day  = CMOS_READ(RTC_DAY_OF_MONTH);
+		mon  = CMOS_READ(RTC_MONTH);
+		year = CMOS_READ(RTC_YEAR);
+	} while (sec != CMOS_READ(RTC_SECONDS));
+
+	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BCD_TO_BIN(sec);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(hour);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(mon);
+		BCD_TO_BIN(year);
+	}
+	if ((year += 1900) < 1970)
+		year += 100;
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+/* set_isa_cmos_time()
+ *
+ * set the CMOS RTC time
+ *
+ * from linux/include/asm-arm/arch-ebsa285/time.h
+*/
+
+static int
+set_isa_cmos_time(void)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+	unsigned char save_control, save_freq_select;
+	unsigned long nowtime = xtime.tv_sec;
+
+	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
+	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+
+	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
+	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+	cmos_minutes = CMOS_READ(RTC_MINUTES);
+	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+		BCD_TO_BIN(cmos_minutes);
+
+	/*
+	 * since we're only adjusting minutes and seconds,
+	 * don't interfere with hour overflow. This avoids
+	 * messing with unknown time zones but requires your
+	 * RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+		real_minutes += 30;		/* correct for half hour time zone */
+	real_minutes %= 60;
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+			BIN_TO_BCD(real_seconds);
+			BIN_TO_BCD(real_minutes);
+		}
+		CMOS_WRITE(real_seconds,RTC_SECONDS);
+		CMOS_WRITE(real_minutes,RTC_MINUTES);
+	} else
+		retval = -1;
+
+	/* The following flags have to be released exactly in this order,
+	 * otherwise the DS12887 (popular MC146818A clone with integrated
+	 * battery and quartz) will not reset the oscillator and will not
+	 * update precisely 500 ms later. You won't find this mentioned in
+	 * the Dallas Semiconductor data sheets, but who believes data
+	 * sheets anyway ...                           -- Markus Kuhn
+	 */
+	CMOS_WRITE(save_control, RTC_CONTROL);
+	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+
+	return retval;
+}
+
+
+/*
+ * Set up timer interrupt.
+ */
+static inline void setup_timer(void)
+{
+	int reg_b, reg_d;
+
+	ioctime_init();
+
+	/* ensure we have an RTC chip, and initialise it... */
+
+	reg_d = CMOS_READ(RTC_REG_D);
+
+	CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A);
+
+	/*
+	 * Set control reg B
+	 *   (24 hour mode, update enabled)
+	 */
+	reg_b = CMOS_READ(RTC_REG_B) & 0x7f;
+	reg_b |= 2;
+	CMOS_WRITE(reg_b, RTC_REG_B);
+
+	if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ &&
+	    CMOS_READ(RTC_REG_B) == reg_b) {
+
+		/*
+		 * We have a RTC.  Check the battery
+		 */
+		if ((reg_d & 0x80) == 0)
+			printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n");
+
+		printk("RTC: detected\n");
+
+		xtime.tv_sec = get_isa_cmos_time();
+		set_rtc = set_isa_cmos_time;
+	} else {
+		printk("RTC: Warning: No RTC detected\n");
+	}
+
+	/* ensure we have the IOC time interrupt setup */
+
+	timer_irq.handler = timer_interrupt;
+
+	setup_arm_irq(IRQ_TIMER, &timer_irq);
+}
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/timex.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/timex.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/timex.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/timex.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,17 @@
+/*
+ *  linux/include/asm-arm/arch-rpc/timex.h
+ *
+ *  Copyright (C) 1997, 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  RiscPC architecture timex specifications
+ */
+
+/*
+ * On the RiscPC, the clock ticks at 2MHz.
+ */
+#define CLOCK_TICK_RATE		2000000
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/uncompress.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/uncompress.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/uncompress.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/uncompress.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,156 @@
+/*
+ *  linux/include/asm-arm/arch-rpc/uncompress.h
+ *
+ *  Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define VIDMEM ((char *)SCREEN_START)
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+int video_num_columns, video_num_lines, video_size_row;
+int white, bytes_per_char_h;
+extern unsigned long con_charconvtable[256];
+
+struct param_struct {
+	unsigned long page_size;
+	unsigned long nr_pages;
+	unsigned long ramdisk_size;
+	unsigned long mountrootrdonly;
+	unsigned long rootdev;
+	unsigned long video_num_cols;
+	unsigned long video_num_rows;
+	unsigned long video_x;
+	unsigned long video_y;
+	unsigned long memc_control_reg;
+	unsigned char sounddefault;
+	unsigned char adfsdrives;
+	unsigned char bytes_per_char_h;
+	unsigned char bytes_per_char_v;
+	unsigned long unused[256/4-11];
+};
+
+static const unsigned long palette_4[16] = {
+	0x00000000,
+	0x000000cc,
+	0x0000cc00,             /* Green   */
+	0x0000cccc,             /* Yellow  */
+	0x00cc0000,             /* Blue    */
+	0x00cc00cc,             /* Magenta */
+	0x00cccc00,             /* Cyan    */
+	0x00cccccc,             /* White   */
+	0x00000000,
+	0x000000ff,
+	0x0000ff00,
+	0x0000ffff,
+	0x00ff0000,
+	0x00ff00ff,
+	0x00ffff00,
+	0x00ffffff
+};
+
+#define palette_setpixel(p)	*(unsigned long *)(IO_START+0x00400000) = 0x10000000|((p) & 255)
+#define palette_write(v)	*(unsigned long *)(IO_START+0x00400000) = 0x00000000|((v) & 0x00ffffff)
+
+extern struct param_struct params;
+
+#ifndef STANDALONE_DEBUG
+/*
+ * This does not append a newline
+ */
+static void puts(const char *s)
+{
+#if 0
+	extern void ll_write_char(char *, unsigned long);
+	int x,y;
+	unsigned char c;
+	char *ptr;
+
+	x = params.video_x;
+	y = params.video_y;
+
+	while ( ( c = *(unsigned char *)s++ ) != '\0' ) {
+		if ( c == '\n' ) {
+			x = 0;
+			if ( ++y >= video_num_lines ) {
+				y--;
+			}
+		} else {
+			ptr = VIDMEM + ((y*video_num_columns*params.bytes_per_char_v+x)*bytes_per_char_h);
+			ll_write_char(ptr, c|(white<<16));
+			if ( ++x >= video_num_columns ) {
+				x = 0;
+				if ( ++y >= video_num_lines ) {
+					y--;
+				}
+			}
+		}
+	}
+
+	params.video_x = x;
+	params.video_y = y;
+#else
+	/* do nothing */
+#endif
+}
+
+static void error(char *x);
+
+/*
+ * Setup for decompression
+ */
+static void arch_decomp_setup(void)
+{
+	int i;
+
+#if 0
+	video_num_lines = params.video_num_rows;
+	video_num_columns = params.video_num_cols;
+	bytes_per_char_h = params.bytes_per_char_h;
+	video_size_row = video_num_columns * bytes_per_char_h;
+	if (bytes_per_char_h == 4)
+		for (i = 0; i < 256; i++)
+			con_charconvtable[i] =
+				(i & 128 ? 1 << 0  : 0) |
+				(i & 64  ? 1 << 4  : 0) |
+				(i & 32  ? 1 << 8  : 0) |
+				(i & 16  ? 1 << 12 : 0) |
+				(i & 8   ? 1 << 16 : 0) |
+				(i & 4   ? 1 << 20 : 0) |
+				(i & 2   ? 1 << 24 : 0) |
+				(i & 1   ? 1 << 28 : 0);
+	else
+		for (i = 0; i < 16; i++)
+			con_charconvtable[i] =
+				(i & 8   ? 1 << 0  : 0) |
+				(i & 4   ? 1 << 8  : 0) |
+				(i & 2   ? 1 << 16 : 0) |
+				(i & 1   ? 1 << 24 : 0);
+
+
+	palette_setpixel(0);
+	if (bytes_per_char_h == 1) {
+		palette_write (0);
+		palette_write (0x00ffffff);
+		for (i = 2; i < 256; i++)
+			palette_write (0);
+		white = 1;
+	} else {
+		for (i = 0; i < 256; i++)
+			palette_write (i < 16 ? palette_4[i] : 0);
+		white = 7;
+	}
+
+	if (params.nr_pages * params.page_size < 4096*1024) error("<4M of mem\n");
+#endif
+}
+#endif
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_wdog()
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-riscstation/vmalloc.h linux-2.4.22-pre3/include/asm-arm/arch-riscstation/vmalloc.h
--- linux-2.4.22-pre2/include/asm-arm/arch-riscstation/vmalloc.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-riscstation/vmalloc.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,22 @@
+/*
+ *  linux/include/asm-arm/arch-rpc/vmalloc.h
+ *
+ *  Copyright (C) 1997 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x1c000000)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-rpc/hardware.h linux-2.4.22-pre3/include/asm-arm/arch-rpc/hardware.h
--- linux-2.4.22-pre2/include/asm-arm/arch-rpc/hardware.h	2001-04-12 12:20:31.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-rpc/hardware.h	2003-07-05 18:11:11.000000000 -0700
@@ -63,6 +63,17 @@
 #define IO_EC_MEMC8_BASE	0x8000ac00
 #define IO_EC_MEMC_BASE		0x80000000
 
+#define NETSLOT_BASE		0x0302b000
+#define NETSLOT_SIZE		0x00001000
+
+#define PODSLOT_IOC0_BASE	0x03240000
+#define PODSLOT_IOC4_BASE	0x03270000
+#define PODSLOT_IOC_SIZE	(1 << 14)
+#define PODSLOT_MEMC_BASE	0x03000000
+#define PODSLOT_MEMC_SIZE	(1 << 14)
+#define PODSLOT_EASI_BASE	0x08000000
+#define PODSLOT_EASI_SIZE	(1 << 24)
+
 #define	EXPMASK_STATUS		(EXPMASK_BASE + 0x00)
 #define EXPMASK_ENABLE		(EXPMASK_BASE + 0x04)
 
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-rpc/io.h linux-2.4.22-pre3/include/asm-arm/arch-rpc/io.h
--- linux-2.4.22-pre2/include/asm-arm/arch-rpc/io.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-rpc/io.h	2003-07-05 18:11:11.000000000 -0700
@@ -249,5 +249,17 @@
 
 #define iomem_valid_addr(o,s)	(1)
 #define iomem_to_phys(a)	(a)
+/*
+ * 1:1 mapping for ioremapped regions.
+ */
+#define __mem_pci(x)	(x)
+
+#define __arch_getw(a)		((*(unsigned int *)(a)) & 0xffff)
+#define __arch_putw(v,a)				\
+	do {						\
+		unsigned int __v = v & 0xffff;		\
+		__v |= __v << 16;			\
+		*(unsigned int *)(a) = __v;		\
+	} while (0)
 
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-rpc/memory.h linux-2.4.22-pre3/include/asm-arm/arch-rpc/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-rpc/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-rpc/memory.h	2003-07-05 18:11:11.000000000 -0700
@@ -50,6 +50,4 @@
 #define __bus_to_virt__is_a_macro
 #define __bus_to_virt(x) __phys_to_virt(x)
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-rpc/serial.h linux-2.4.22-pre3/include/asm-arm/arch-rpc/serial.h
--- linux-2.4.22-pre2/include/asm-arm/arch-rpc/serial.h	2000-09-18 15:15:23.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-rpc/serial.h	2003-07-05 18:11:11.000000000 -0700
@@ -29,7 +29,7 @@
      /* UART CLK        PORT  IRQ     FLAGS        */
 #define STD_SERIAL_PORT_DEFNS \
 	{ 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS },	/* ttyS0 */	\
-	{ 0, BASE_BAUD, 0x2F8, 10, STD_COM_FLAGS },	/* ttyS1 */	\
+	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS1 */	\
 	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },	/* ttyS3 */	\
 	{ 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS }, 	/* ttyS4 */	\
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-rpc/system.h linux-2.4.22-pre3/include/asm-arm/arch-rpc/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-rpc/system.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-rpc/system.h	2003-07-05 18:11:11.000000000 -0700
@@ -11,26 +11,9 @@
 #include <asm/hardware/iomd.h>
 #include <asm/io.h>
 
-static void arch_idle(void)
+static inline void arch_idle(void)
 {
-	unsigned long start_idle;
-
-	start_idle = jiffies;
-
-	do {
-		if (current->need_resched || hlt_counter)
-			goto slow_out;
-		cpu_do_idle(IDLE_WAIT_FAST);
-	} while (time_before(jiffies, start_idle + HZ/50));
-
-	cpu_do_idle(IDLE_CLOCK_SLOW);
-
-	while (!current->need_resched && !hlt_counter) {
-		cpu_do_idle(IDLE_WAIT_SLOW);
-	}
-
-	cpu_do_idle(IDLE_CLOCK_FAST);
-slow_out:
+	cpu_do_idle();
 }
 
 static inline void arch_reset(char mode)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-rpc/uncompress.h linux-2.4.22-pre3/include/asm-arm/arch-rpc/uncompress.h
--- linux-2.4.22-pre2/include/asm-arm/arch-rpc/uncompress.h	2000-11-27 17:07:59.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-rpc/uncompress.h	2003-07-05 18:11:11.000000000 -0700
@@ -56,7 +56,7 @@
 #define palette_setpixel(p)	*(unsigned long *)(IO_START+0x00400000) = 0x10000000|((p) & 255)
 #define palette_write(v)	*(unsigned long *)(IO_START+0x00400000) = 0x00000000|((v) & 0x00ffffff)
 
-extern struct param_struct params;
+static struct param_struct *params = (struct param_struct *)PARAMS_PHYS;
 
 #ifndef STANDALONE_DEBUG 
 /*
@@ -64,13 +64,13 @@
  */
 static void puts(const char *s)
 {
-	extern void ll_write_char(char *, unsigned long);
+	extern void ll_write_char(char *, char c, char white);
 	int x,y;
 	unsigned char c;
 	char *ptr;
 
-	x = params.video_x;
-	y = params.video_y;
+	x = params->video_x;
+	y = params->video_y;
 
 	while ( ( c = *(unsigned char *)s++ ) != '\0' ) {
 		if ( c == '\n' ) {
@@ -79,8 +79,8 @@
 				y--;
 			}
 		} else {
-			ptr = VIDMEM + ((y*video_num_columns*params.bytes_per_char_v+x)*bytes_per_char_h);
-			ll_write_char(ptr, c|(white<<16));
+			ptr = VIDMEM + ((y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h);
+			ll_write_char(ptr, c, white);
 			if ( ++x >= video_num_columns ) {
 				x = 0;
 				if ( ++y >= video_num_lines ) {
@@ -90,8 +90,8 @@
 		}
 	}
 
-	params.video_x = x;
-	params.video_y = y;
+	params->video_x = x;
+	params->video_y = y;
 }
 
 static void error(char *x);
@@ -103,9 +103,9 @@
 {
 	int i;
 	
-	video_num_lines = params.video_num_rows;
-	video_num_columns = params.video_num_cols;
-	bytes_per_char_h = params.bytes_per_char_h;
+	video_num_lines = params->video_num_rows;
+	video_num_columns = params->video_num_cols;
+	bytes_per_char_h = params->bytes_per_char_h;
 	video_size_row = video_num_columns * bytes_per_char_h;
 	if (bytes_per_char_h == 4)
 		for (i = 0; i < 256; i++)
@@ -140,7 +140,7 @@
 		white = 7;
 	}
 
-	if (params.nr_pages * params.page_size < 4096*1024) error("<4M of mem\n");
+	if (params->nr_pages * params->page_size < 4096*1024) error("<4M of mem\n");
 }
 #endif
 
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/SA-1100.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/SA-1100.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/SA-1100.h	2001-10-25 13:53:54.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/SA-1100.h	2003-07-05 18:11:11.000000000 -0700
@@ -22,6 +22,16 @@
 
 #include "bitfield.h"
 
+/*
+ * SA1100 CS line to physical address
+ */
+
+#define SA1100_CS0_PHYS	0x00000000
+#define SA1100_CS1_PHYS	0x08000000
+#define SA1100_CS2_PHYS	0x10000000
+#define SA1100_CS3_PHYS	0x18000000
+#define SA1100_CS4_PHYS	0x40000000
+#define SA1100_CS5_PHYS	0x48000000
 
 /*
  * Personal Computer Memory Card International Association (PCMCIA) sockets
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/adsagc.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/adsagc.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/adsagc.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/adsagc.h	2003-07-05 18:11:11.000000000 -0700
@@ -0,0 +1,83 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/adsagc.h
+ *
+ * Created Feb 7, 2003 by Robert Whaley <rwhaley@applieddata.net>
+ *
+ * This file comes from graphicsmaster.h of Woojung Huh <whuh@applieddata.net>
+ *
+ * This file contains the hardware specific definitions for the
+ * ADS Advanced Graphics Client
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+#define ADS_CPLD_BASE		(0x10000000)
+#define ADS_p2v( x )		((x) - ADS_CPLD_BASE + 0xf0000000)
+#define ADS_v2p( x )		((x) - 0xf0000000 + ADS_CPLD_BASE)
+
+
+#define _ADS_SW_SWITCHES	0x10060000	/* Software Switches */
+
+#define _ADS_CR1                0x10060004      /* audio and serial */
+#define _ADS_CR2                0x10060008      /* clocks */
+#define _ADS_CR3                0x1006000c      /* AVR, LCD, LEDs */
+
+#define ADS_CR1_AMP             0x01
+#define ADS_CR1_CODEC           0x02
+#define ADS_CR1_BTL             0x04
+#define ADS_CR1_AUDIO_RST       0x08
+#define ADS_CR1_COM3_ENA        0x10
+#define ADS_CR1_IRDA_ENA        0x20
+#define ADS_CR1_SPI_SEL         0x40
+#define ADS_CR1_ARM_RST         0x80
+
+#define ADS_CR2_CLK_SEL0        0x01
+#define ADS_CR2_CLK_SEL1        0x02
+#define ADS_CR2_PLL_OFF         0x04
+#define ADS_CR2_CLK_PWR         0x08
+
+#define ADS_CR3_PNLON           0x01
+#define ADS_CR3_VEECTL          0x02
+#define ADS_CR3_BLON            0x04
+#define ADS_CR3_WAKEUP          0x08
+
+
+/* Extra IRQ Controller */
+#define _ADS_INT_ST1		0x10080000	/* IRQ Status #1 */
+#define _ADS_INT_EN1		0x10080008	/* IRQ Enable #1 */
+#define _ADS_DCR			0x10080018	/* Discrete Control Reg */
+
+/* Discrete Controller (AVR:Atmel AT90LS8535) */
+#define _ADS_AVR_REG		0x10080018
+
+/* On-Board Ethernet */
+#define _ADS_ETHERNET		0x40000000	/* Ethernet */
+
+/* LEDs */
+#define ADS_LED0	0x10		/* on-board Green */
+#define ADS_LED1	0x20		/* on-board Yellow */
+#define ADS_LED2	0x40		/* on-board Red */
+
+/* DCR */
+#define DCR_AVR_RESET		0x01
+#define DCR_SA1111_RESET	0x02
+#define	DCR_BACKLITE_ON		0x04
+
+/* Virtual register addresses */
+
+#ifndef __ASSEMBLY__
+#define ADS_INT_ST1	(*((volatile u_char *) ADS_p2v(_ADS_INT_ST1)))
+#define ADS_INT_EN1	(*((volatile u_char *) ADS_p2v(_ADS_INT_EN1)))
+
+#define ADS_CR1  	(*((volatile u_char *) ADS_p2v(_ADS_CR1)))
+#define ADS_CR2  	(*((volatile u_char *) ADS_p2v(_ADS_CR2)))
+#define ADS_CR3  	(*((volatile u_char *) ADS_p2v(_ADS_CR3)))
+
+#define ADS_ETHERNET	((int) ADS_p2v(_ADS_ETHERNET))
+#define ADS_AVR_REG	(*((volatile u_char *) ADS_p2v(_ADS_AVR_REG)))
+#define ADS_DCR		(*((volatile u_char *) ADS_p2v(_ADS_DCR)))
+#endif
+
+#define ADS_SA1111_BASE		(0x18000000)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/adsbitsyplus.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/adsbitsyplus.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/adsbitsyplus.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/adsbitsyplus.h	2003-07-05 18:11:12.000000000 -0700
@@ -0,0 +1,70 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/adsbitsy.h
+ *
+ * Created Feb 7, 2003 by Robert Whaley <rwhaley@applieddata.net>
+ *
+ * This file comes from adsbitsy.h of Woojung Huh <whuh@applieddata.net>
+ *
+ * This file contains the hardware specific definitions for the
+ * ADS Bitsy Board
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+#define ADS_CPLD_BASE		(0x10000000)
+#define ADS_p2v( x )		((x) - ADS_CPLD_BASE + 0xf1000000)
+#define ADS_v2p( x )		((x) - 0xf1000000 + ADS_CPLD_BASE)
+
+
+#define _ADS_CPLD_IO1                0x10000000
+#define _ADS_CPLD_IO2                0x10000004
+#define _ADS_CPLD_IODR1              0x10000008
+#define _ADS_CPLD_IODR2              0x1000000C
+#define _ADS_CPLD_PCON               0x10000010
+#define _ADS_CPLD_SUPPC              0x10000014
+
+/* IO bits */
+#define ADS_IO1_MASK 0xFF
+#define ADS_IO2_MASK 0x03
+
+#define ADS_IO1_BIT0 0x01
+#define ADS_IO1_BIT1 0x02
+#define ADS_IO1_BIT2 0x04
+#define ADS_IO1_BIT3 0x08
+#define ADS_IO1_BIT4 0x10
+#define ADS_IO1_BIT5 0x20
+#define ADS_IO1_BIT6 0x40
+#define ADS_IO1_BIT7 0x80
+#define ADS_IO2_BIT8 0x01
+#define ADS_IO2_BIT9 0x02
+
+#define ADS_IO2_CPLD_REV_MASK 0xF0
+#define ADS_IO2_CPLD_REV_5_MAGIC 0x30
+
+#define ADS_PCON_PANEL_ON   0x01
+#define ADS_PCON_AUDIO_ON   0x02
+#define ADS_PCON_AUDIOPA_ON 0x04
+#define ADS_PCON_COM1_3_ON  0x08
+#define ADS_PCON_CONN_B_PE1 0x10
+#define ADS_PCON_CONN_B_PE2 0x20
+
+#define ADS_SUPPC_VEE_ON     0x01
+#define ADS_SUPPC_TS_SPI_SEL 0x02
+#define ADS_SUPPC_CB_SPI_SEL 0x04
+#define ADS_SUPPC_AVR_WKP    0x08
+
+/* Virtual register addresses */
+
+#ifndef __ASSEMBLY__
+#define ADS_CPLD_IO1                (*((volatile u_char *) ADS_p2v(_ADS_CPLD_IO1)))
+#define ADS_CPLD_IO2                (*((volatile u_char *) ADS_p2v(_ADS_CPLD_IO2)))
+#define ADS_CPLD_IODR1              (*((volatile u_char *) ADS_p2v(_ADS_CPLD_IODR1)))
+#define ADS_CPLD_IODR2              (*((volatile u_char *) ADS_p2v(_ADS_CPLD_IODR2)))
+#define ADS_CPLD_PCON               (*((volatile u_char *) ADS_p2v(_ADS_CPLD_PCON)))
+#define ADS_CPLD_SUPPC              (*((volatile u_char *) ADS_p2v(_ADS_CPLD_SUPPC)))
+
+#endif
+
+#define ADSBITSYPLUS_SA1111_BASE	(0x18000000)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/frodo.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/frodo.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/frodo.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/frodo.h	2003-07-05 18:11:12.000000000 -0700
@@ -17,6 +17,25 @@
  *
  * History:
  *
+ *   2002/07/17   Protect accesses to CPLD memory with a global lock
+ *                to prevent races.
+ *
+ *   2002/06/25   PCMCIA support
+ *
+ *   2002/06/06   Added Real-Time Clock IRQ
+ *                Added IRQs for UARTs
+ *
+ *   2002/05/20   Added I2C definitions
+ *                Updated USB port definitions
+ *                Removed scratchpad register
+ *                Added definitions for second UART
+ *
+ *   2002/04/19   Added USB definitions
+ *
+ *   2002/04/17   Added flow control definitions for UART1
+ *
+ *   2002/03/14   Added ethernet reset definitions
+ *
  *   2002/02/28   Ethernet (cs89x0) support
  *
  *   2002/02/27   IDE support
@@ -27,13 +46,29 @@
  *   2002/01/31   Initial version
  */
 
+/* CPLD memory */
+#define	FRODO_CPLD_BASE				0x40000000
+#define FRODO_CPLD_LENGTH			0x00100000
+
 /* CPLD registers */
-#define FRODO_CPLD_UART				*((u16 *) 0xf000c000)
-#define FRODO_CPLD_IDE				*((u16 *) 0xf0008000)
-#define FRODO_CPLD_GENERAL			*((u16 *) 0xf0004004)
-#define FRODO_CPLD_PCMCIA_STATUS	*((u16 *) 0xf0004000)
-#define FRODO_CPLD_PCMCIA_COMMAND	*((u16 *) 0xf0000000)
-#define FRODO_CPLD_SCRATCHPAD		*((u16 *) 0xf0000004)
+#define FRODO_CPLD_PCMCIA_COMMAND	0x00000
+#define FRODO_CPLD_PCMCIA_STATUS	0x04000
+#define FRODO_CPLD_IDE				0x08000
+#define FRODO_CPLD_UART1			0x0c000
+#define FRODO_CPLD_USB				0x10000
+#define FRODO_CPLD_ETHERNET			0x14000
+#define FRODO_CPLD_UART2			0x18000
+#define FRODO_CPLD_GENERAL			0x04004
+#define FRODO_CPLD_I2C				0x08004
+
+/* functions to access those registers */
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+extern u16 frodo_cpld_read (u32 reg);
+extern void frodo_cpld_write (u32 reg,u16 value);
+extern void frodo_cpld_set (u32 reg,u16 mask);
+extern void frodo_cpld_clear (u32 reg,u16 mask);
+#endif	/* #ifndef __ASSEMBLY__ */
 
 /* general command/status register */
 #define FRODO_LCD_BACKLIGHT			0x0400		/* R/W */
@@ -41,16 +76,87 @@
 #define FRODO_LED2					0x0200		/* R/W */
 #define FRODO_PUSHBUTTON			0x8000		/* R/O */
 
+/* ethernet register */
+#define FRODO_ETH_RESET				0x8000		/* R/W */
+
 /* IDE related definitions */
-#define FRODO_IDE_GPIO			GPIO_GPIO23
-#define FRODO_IDE_IRQ			IRQ_GPIO23
-#define FRODO_IDE_DATA			0xf0020000
-#define FRODO_IDE_CTRL			0xf0038004
+#define FRODO_IDE_GPIO				GPIO_GPIO23
+#define FRODO_IDE_IRQ				IRQ_GPIO23
+#define FRODO_IDE_CTRL				0xf0038004
+#define FRODO_IDE_DATA				0xf0020000
 
 /* Ethernet related definitions */
-#define FRODO_ETH_GPIO			GPIO_GPIO20
-#define FRODO_ETH_IRQ			IRQ_GPIO20
-#define FRODO_ETH_MEMORY		0xf0060000
-#define FRODO_ETH_IO			0xf0070000
+#define FRODO_ETH_GPIO				GPIO_GPIO20
+#define FRODO_ETH_IRQ				IRQ_GPIO20
+#define FRODO_ETH_MEMORY			0xf0060000
+#define FRODO_ETH_IO				0xf0070000
+
+/* USB device controller */
+#define FRODO_USB_DC_GPIO			GPIO_GPIO19
+#define FRODO_USB_DC_IRQ			IRQ_GPIO19
+#define FRODO_USB_DC_CTRL			0xf0040006
+#define FRODO_USB_DC_DATA			0xf0040004
+
+/* USB host controller */
+#define FRODO_USB_HC_GPIO			GPIO_GPIO18
+#define FRODO_USB_HC_IRQ			IRQ_GPIO18
+#define FRODO_USB_HC_CTRL			0xf0040002
+#define FRODO_USB_HC_DATA			0xf0040000
+
+/* This UART supports all the funky things */
+#define FRODO_UART1_RI				0x0100		/* R/O */
+#define FRODO_UART1_DCD				0x0200		/* R/O */
+#define FRODO_UART1_CTS				0x0400		/* R/O */
+#define FRODO_UART1_DSR				0x0800		/* R/O */
+#define FRODO_UART1_DTR				0x2000		/* R/W */
+#define FRODO_UART1_RTS				0x4000		/* R/W */
+#define FRODO_UART1_IRQEN			0x8000		/* R/W */
+#define FRODO_UART1_GPIO			GPIO_GPIO25
+#define FRODO_UART1_IRQ				IRQ_GPIO25
+
+/* Console port. Only supports a subset of the control lines */
+#define FRODO_UART2_IRQEN			0x0100		/* R/W */
+#define FRODO_UART2_CTS				0x1000		/* R/O */
+#define FRODO_UART2_RTS				0x8000		/* R/W */
+#define FRODO_UART2_GPIO			GPIO_GPIO24
+#define FRODO_UART2_IRQ				IRQ_GPIO24
+
+/* USB command register */
+#define FRODO_USB_HWAKEUP			0x2000		/* R/W */
+#define FRODO_USB_DWAKEUP			0x4000		/* R/W */
+#define FRODO_USB_NDPSEL			0x8000		/* R/W */
+
+/* I2C adapter information */
+#define FRODO_I2C_SCL_OUT			0x2000		/* R/W */
+#define FRODO_I2C_SCL_IN			0x1000		/* R/O */
+#define FRODO_I2C_SDA_OUT			0x8000		/* R/W */
+#define FRODO_I2C_SDA_IN			0x4000		/* R/O */
+
+/* Real-Time Clock */
+#define FRODO_RTC_GPIO				GPIO_GPIO14
+#define FRODO_RTC_IRQ				IRQ_GPIO14
+
+/* PCMCIA command register */
+#define FRODO_PCMCIA_RESET			0x0004		/* R/W */
+#define FRODO_PCMCIA_VCC1			0x0008		/* R/W */
+#define FRODO_PCMCIA_VCC0			0x0010		/* R/W */
+#define FRODO_PCMCIA_VPP1			0x0020		/* R/W */
+#define FRODO_PCMCIA_VPP0			0x0040		/* R/W */
+#define FRODO_PCMCIA_CLEAR			0x0080		/* R/W */
+
+/* PCMCIA status register */
+#define FRODO_PCMCIA_VS1			0x0001		/* R/O */
+#define FRODO_PCMCIA_VS2			0x0002		/* R/O */
+#define FRODO_PCMCIA_BVD1			0x0004		/* R/O */
+#define FRODO_PCMCIA_BVD2			0x0008		/* R/O */
+#define FRODO_PCMCIA_CD1			0x0010		/* R/O */
+#define FRODO_PCMCIA_CD2			0x0020		/* R/O */
+#define FRODO_PCMCIA_RDYBSY			0x0040		/* R/O */
+
+/* PCMCIA interrupts */
+#define FRODO_PCMCIA_STATUS_GPIO	GPIO_GPIO10
+#define FRODO_PCMCIA_STATUS_IRQ		IRQ_GPIO10
+#define FRODO_PCMCIA_RDYBSY_GPIO	GPIO_GPIO11
+#define FRODO_PCMCIA_RDYBSY_IRQ		IRQ_GPIO11
 
 #endif	/* _INCLUDE_FRODO_H_ */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/graphicsclient.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/graphicsclient.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/graphicsclient.h	2001-10-25 13:53:54.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/graphicsclient.h	2003-07-05 18:11:12.000000000 -0700
@@ -55,36 +55,6 @@
 
 #define _ADS_ETHERNET		0x100e0000	/* Ethernet */
 
-
-/* Extra UARTs */
-
-#define _ADS_UARTA		0x10100000	/* UART A */
-#define _ADS_UARTB		0x10120000	/* UART B */
-#define _ADS_UARTC		0x10140000	/* UART C */
-#define _ADS_UARTD		0x10160000	/* UART D */
-
-/* UART controll lines GPIOs */
-#define GPIO_GC_UART0_RTS       GPIO_GPIO15
-#define GPIO_GC_UART1_RTS	    GPIO_GPIO17
-#define GPIO_GC_UART2_RTS	    GPIO_GPIO19
-#define GPIO_GC_UART0_CTS       GPIO_GPIO14
-#define GPIO_GC_UART1_CTS       GPIO_GPIO16
-#define GPIO_GC_UART2_CTS       GPIO_GPIO17
-
-/* UART controll lines IRQs */
-#define IRQ_GC_UART0_CTS       IRQ_GPIO14
-#define IRQ_GC_UART1_CTS       IRQ_GPIO16
-#define IRQ_GC_UART2_CTS       IRQ_GPIO17
-
-#ifndef __ASSEMBLY__
-struct gc_uart_ctrl_data_t {
-  int cts_gpio;
-  int cts_prev_state;
-  struct uart_info *info;
-  struct uart_port *port;
-};
-#endif /* __ASSEMBLY__ */
-
 /* LEDs */
 
 #define ADS_LED0	GPIO_GPIO20		/* on-board D22 */
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/hackkit.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/hackkit.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/hackkit.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/hackkit.h	2003-07-05 18:11:12.000000000 -0700
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/hackkit.h
+ *
+ * Copyright (C) 2002 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/hardware.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/hardware.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/hardware.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/hardware.h	2003-07-05 18:11:12.000000000 -0700
@@ -183,14 +183,26 @@
 #include "simpad.h"
 #endif
 
+#ifdef CONFIG_SA1100_SIMPUTER
+#include "simputer.h"
+#endif
+
 #if defined(CONFIG_SA1100_GRAPHICSMASTER)
 #include "graphicsmaster.h"
 #endif
 
+#if defined(CONFIG_SA1100_ADSAGC)
+#include "adsagc.h"
+#endif
+
 #if defined(CONFIG_SA1100_ADSBITSY)
 #include "adsbitsy.h"
 #endif
 
+#if defined(CONFIG_SA1100_ADSBITSYPLUS)
+#include "adsbitsyplus.h"
+#endif
+
 #ifdef CONFIG_SA1101
 
 /*
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/irqs.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/irqs.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/irqs.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/irqs.h	2003-07-05 18:11:12.000000000 -0700
@@ -130,13 +130,12 @@
  * Figure out the MAX IRQ number.
  *
  * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
- * If graphicsclient or graphicsmaster, we don't have a SA1111.
+ * If graphicsclient we don't have a SA1111.
  * Otherwise, we have the standard IRQs only.
  */
 #ifdef CONFIG_SA1111
 #define NR_IRQS			(S1_BVD1_STSCHG + 1)
-#elif defined(CONFIG_SA1100_GRAPHICSCLIENT) || \
-      defined(CONFIG_SA1100_GRAPHICSMASTER)
+#elif defined(CONFIG_SA1100_GRAPHICSCLIENT)
 #define NR_IRQS			(IRQ_BOARD_END)
 #else
 #define NR_IRQS			(IRQ_BOARD_START)
@@ -151,3 +150,44 @@
 
 /* PT Digital Board Interrupts (CONFIG_SA1100_PT_SYSTEM3) */
 #define IRQ_SYSTEM3_SMC9196	(IRQ_BOARD_START + 0)
+
+/* ADS Graphics Client IRQs (CONFIG_SA1100_GRAPHICSCLIENT) */
+#define IRQ_GRAPHICSCLIENT_START   (IRQ_BOARD_START + 0)
+#define IRQ_GRAPHICSCLIENT_CAN     (IRQ_BOARD_START + 4)
+#define IRQ_GRAPHICSCLIENT_S0_CD   (IRQ_BOARD_START + 6)
+#define IRQ_GRAPHICSCLIENT_EXTIRQ  (IRQ_BOARD_START + 7)
+#define IRQ_GRAPHICSCLIENT_UCB1200 (IRQ_BOARD_START + 8)
+#define IRQ_GRAPHICSCLIENT_ETH     (IRQ_BOARD_START + 9)
+#define IRQ_GRAPHICSCLIENT_USB     (IRQ_BOARD_START + 10)
+#define IRQ_GRAPHICSCLIENT_S0_STS  (IRQ_BOARD_START + 11)
+#define IRQ_GRAPHICSCLIENT_SWITCH  (IRQ_BOARD_START + 13)
+#define IRQ_GRAPHICSCLIENT_AVR     (IRQ_BOARD_START + 14)
+#define IRQ_GRAPHICSCLIENT_BATFLT  (IRQ_BOARD_START + 15)
+#define IRQ_GRAPHICSCLIENT_END     (IRQ_BOARD_START + 16)
+
+/* ADS Graphics Master IRQs (CONFIG_SA1100_GRAPHICSMASTER) */
+
+#define IRQ_GRAPHICSMASTER_START   (IRQ_BOARD_START)
+#define IRQ_GRAPHICSMASTER_SA1111  (IRQ_BOARD_START + 0)
+#define IRQ_GRAPHICSMASTER_UART0   (IRQ_BOARD_START + 1)
+#define IRQ_GRAPHICSMASTER_UART1   (IRQ_BOARD_START + 2)
+#define IRQ_GRAPHICSMASTER_UART2   (IRQ_BOARD_START + 3)
+#define IRQ_GRAPHICSMASTER_CAN     (IRQ_BOARD_START + 4)
+#define IRQ_GRAPHICSMASTER_UART3   (IRQ_BOARD_START + 5)
+#define IRQ_GRAPHICSMASTER_FLASH   (IRQ_BOARD_START + 6)
+#define IRQ_GRAPHICSMASTER_EXTIRQ  (IRQ_BOARD_START + 7)
+#define IRQ_GRAPHICSMASTER_UCB1200 (IRQ_BOARD_START + 8)
+#define IRQ_GRAPHICSMASTER_ETH     (IRQ_BOARD_START + 9)
+#define IRQ_GRAPHICSMASTER_SWITCH  (IRQ_BOARD_START + 13)
+#define IRQ_GRAPHICSMASTER_AVR     (IRQ_BOARD_START + 14)
+#define IRQ_GRAPHICSMASTER_BATFLT  (IRQ_BOARD_START + 15)
+#define IRQ_GRAPHICSMASTER_END     (IRQ_BOARD_START + 16)
+
+/* ADS Advanced Graphics Client IRQs (CONFIG_SA1100 ADSAGC) */
+#define IRQ_ADSAGC_START           (IRQ_BOARD_START)
+#define IRQ_ADSAGC_AVR             (IRQ_BOARD_START + 0)
+#define IRQ_ADSAGC_CAN             (IRQ_BOARD_START + 1)
+#define IRQ_ADSAGC_ETH             (IRQ_BOARD_START + 2)
+#define IRQ_ADSAGC_EXTIRQ          (IRQ_BOARD_START + 3)
+#define IRQ_ADSAGC_END             (IRQ_BOARD_START + 4)
+
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/keyboard.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/keyboard.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/keyboard.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/keyboard.h	2003-07-05 18:11:12.000000000 -0700
@@ -21,11 +21,11 @@
 static inline void kbd_init_hw(void)
 {
 	if ((machine_is_assabet() && machine_has_neponset()) ||
-	    machine_is_graphicsmaster())
+	    machine_is_graphicsmaster() || machine_is_adsagc())
 		sa1111_kbd_init_hw();
 	if (machine_is_graphicsclient())
 		gc_kbd_init_hw();
-	if (machine_is_adsbitsy())
+	if (machine_is_adsbitsy() || machine_is_adsbitsyplus())
 		smartio_kbd_init_hw();
 #ifdef CONFIG_SA1100_CERF_CPLD
 	if (machine_is_cerf())
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/memory.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/memory.h	2003-07-05 18:11:12.000000000 -0700
@@ -58,9 +58,9 @@
 #ifdef CONFIG_DISCONTIGMEM
 /*
  * Because of the wide memory address space between physical RAM banks on the 
- * SA1100, it's much convenient to use Linux's NUMA support to implement our 
- * memory map representation.  Assuming all memory nodes have equal access 
- * characteristics, we then have generic discontigous memory support.
+ * SA1100, it's much more convenient to use Linux's NUMA support to implement
+ * our memory map representation.  Assuming all memory nodes have equal access 
+ * characteristics, we then have generic discontiguous memory support.
  *
  * Of course, all this isn't mandatory for SA1100 implementations with only
  * one used memory bank.  For those, simply undefine CONFIG_DISCONTIGMEM.
@@ -79,49 +79,36 @@
 /*
  * Given a kernel address, find the home node of the underlying memory.
  */
-#define KVADDR_TO_NID(addr) \
-		(((unsigned long)(addr) - 0xc0000000) >> 27)
+#define KVADDR_TO_NID(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> 27)
 
 /*
- * Given a physical address, convert it to a node id.
+ * Given a page frame number, convert it to a node id.
  */
-#define PHYS_TO_NID(addr) KVADDR_TO_NID(__phys_to_virt(addr))
+#define PFN_TO_NID(pfn)		(((pfn) - PHYS_PFN_OFFSET) >> (27 - PAGE_SHIFT))
 
 /*
  * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
  * and returns the mem_map of that node.
  */
-#define ADDR_TO_MAPBASE(kaddr) \
-			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
+#define ADDR_TO_MAPBASE(kaddr)	NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
 
 /*
- * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
- * and returns the index corresponding to the appropriate page in the
- * node's mem_map.
- */
-#define LOCAL_MAP_NR(kvaddr) \
-	(((unsigned long)(kvaddr) & 0x07ffffff) >> PAGE_SHIFT)
-
-/*
- * Given a kaddr, virt_to_page returns a pointer to the corresponding 
- * mem_map entry.
+ * Given a page frame number, find the owning node of the memory
+ * and returns the mem_map of that node.
  */
-#define virt_to_page(kaddr) \
-	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
+#define PFN_TO_MAPBASE(pfn)	NODE_MEM_MAP(PFN_TO_NID(pfn))
 
 /*
- * VALID_PAGE returns a non-zero value if given page pointer is valid.
- * This assumes all node's mem_maps are stored within the node they refer to.
+ * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
+ * and returns the index corresponding to the appropriate page in the
+ * node's mem_map.
  */
-#define VALID_PAGE(page) \
-({ unsigned int node = KVADDR_TO_NID(page); \
-   ( (node < NR_NODES) && \
-     ((unsigned)((page) - NODE_MEM_MAP(node)) < NODE_DATA(node)->node_size) ); \
-})
+#define LOCAL_MAP_NR(addr) \
+	(((unsigned long)(addr) & 0x07ffffff) >> PAGE_SHIFT)
 
 #else
 
-#define PHYS_TO_NID(addr)	(0)
+#define PFN_TO_NID(addr)	(0)
 
 #endif
 
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/simputer.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/simputer.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/simputer.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/simputer.h	2003-07-05 18:11:12.000000000 -0700
@@ -0,0 +1,18 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/simputer.h
+ *
+ * Created 2001/07/11 by Vivek K S <ksvivek@picopeta.com>
+ * Modified from Nicolas Pitre's assabet.h
+ *
+ *
+ * This file contains the hardware specific definitions for simputer
+ * Only include this file from SA1100-specific files.
+ *
+ */
+#ifndef __ASM_ARCH_SIMPUTER_H
+#define __ASM_ARCH_SIMPUTER_H
+
+#define GPIO_UCB1300_IRQ	GPIO_GPIO (5)	/* UCB GPIO and touchscreen */
+#define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO5
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/system.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/system.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/system.h	2003-07-05 18:11:12.000000000 -0700
@@ -8,13 +8,7 @@
 
 static inline void arch_idle(void)
 {
-	if (!hlt_counter) {
-		int flags;
-		local_irq_save(flags);
-		if (!current->need_resched)
-			cpu_do_idle(0);
-		local_irq_restore(flags);
-	}
+	cpu_do_idle();
 }
 
 #ifdef CONFIG_SA1100_VICTOR
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-sa1100/time.h linux-2.4.22-pre3/include/asm-arm/arch-sa1100/time.h
--- linux-2.4.22-pre2/include/asm-arm/arch-sa1100/time.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-sa1100/time.h	2003-07-05 18:11:12.000000000 -0700
@@ -65,24 +65,20 @@
 
 static void sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	long flags;
-	int next_match;
+	unsigned int next_match;
+	unsigned long flags;
 
-	/* Loop until we get ahead of the free running timer.
-	 * This ensures an exact clock tick count and time acuracy.
-	 * IRQs are disabled inside the loop to ensure coherence between
-	 * lost_ticks (updated in do_timer()) and the match reg value, so we
-	 * can use do_gettimeofday() from interrupt handlers.
-	 */
 	do {
 		do_leds();
-		do_set_rtc();
-		save_flags_cli( flags );
+		local_irq_save(flags);
 		do_timer(regs);
 		OSSR = OSSR_M0;  /* Clear match on timer 0 */
 		next_match = (OSMR0 += LATCH);
-		restore_flags( flags );
-	} while( (signed long)(next_match - OSCR) <= 0 );
+		local_irq_restore(flags);
+		do_set_rtc();
+	} while ((signed long)(next_match - OSCR) <= 0);
+
+	do_profile(regs);
 }
 
 static inline void setup_timer (void)
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-shark/memory.h linux-2.4.22-pre3/include/asm-arm/arch-shark/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-shark/memory.h	2001-10-25 13:53:55.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-shark/memory.h	2003-07-05 18:11:12.000000000 -0700
@@ -38,6 +38,4 @@
 #define __bus_to_virt__is_a_macro
 #define __bus_to_virt(x)	__phys_to_virt(x)
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-shark/system.h linux-2.4.22-pre3/include/asm-arm/arch-shark/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-shark/system.h	2001-10-25 13:53:55.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-shark/system.h	2003-07-05 18:11:12.000000000 -0700
@@ -11,7 +11,7 @@
 static void arch_reset(char mode)
 {
 	short temp;
-	cli();
+	local_irq_disable();
 	/* Reset the Machine via pc[3] of the sequoia chipset */
 	outw(0x09,0x24);
 	temp=inw(0x26);
@@ -21,7 +21,7 @@
 
 }
 
-static void arch_idle(void)
+static inline void arch_idle(void)
 {
 }
 
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-shark/time.h linux-2.4.22-pre3/include/asm-arm/arch-shark/time.h
--- linux-2.4.22-pre2/include/asm-arm/arch-shark/time.h	2001-10-25 13:53:55.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-shark/time.h	2003-07-05 18:11:12.000000000 -0700
@@ -80,6 +80,5 @@
 			      r_time.tm_hour, r_time.tm_min, r_time.tm_sec);
 
 	timer_irq.handler = timer_interrupt;
-	timer_irq.flags = SA_INTERRUPT; /* FIXME: really? */
 	setup_arm_irq(IRQ_TIMER, &timer_irq);
 }
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-tbox/memory.h linux-2.4.22-pre3/include/asm-arm/arch-tbox/memory.h
--- linux-2.4.22-pre2/include/asm-arm/arch-tbox/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-tbox/memory.h	2003-07-05 18:11:12.000000000 -0700
@@ -41,6 +41,4 @@
 #define __bus_to_virt__is_a_macro
 #define __bus_to_virt(x)	__phys_to_virt(x)
 
-#define PHYS_TO_NID(addr)	(0)
-
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/arch-tbox/system.h linux-2.4.22-pre3/include/asm-arm/arch-tbox/system.h
--- linux-2.4.22-pre2/include/asm-arm/arch-tbox/system.h	2000-09-18 15:15:23.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/arch-tbox/system.h	2003-07-05 18:11:12.000000000 -0700
@@ -6,26 +6,9 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-static void arch_idle(void)
+static inline void arch_idle(void)
 {
-	unsigned long start_idle;
-
-	start_idle = jiffies;
-
-	do {
-		if (current->need_resched || hlt_counter)
-			goto slow_out;
-		cpu_do_idle(IDLE_WAIT_FAST);
-	} while (time_before(jiffies, start_idle + HZ/50));
-
-	cpu_do_idle(IDLE_CLOCK_SLOW);
-
-	while (!current->need_resched && !hlt_counter) {
-		cpu_do_idle(IDLE_WAIT_SLOW);
-	}
-
-	cpu_do_idle(IDLE_CLOCK_FAST);
-slow_out:
+	cpu_do_idle();
 }
 
 #define arch_reset(mode)	do { } while (0)
diff -urN linux-2.4.22-pre2/include/asm-arm/atomic.h linux-2.4.22-pre3/include/asm-arm/atomic.h
--- linux-2.4.22-pre2/include/asm-arm/atomic.h	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/atomic.h	2003-07-05 18:11:12.000000000 -0700
@@ -32,75 +32,75 @@
 #define atomic_read(v)	((v)->counter)
 #define atomic_set(v,i)	(((v)->counter) = (i))
 
-static __inline__ void atomic_add(int i, volatile atomic_t *v)
+static inline void atomic_add(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
 
-	__save_flags_cli(flags);
+	local_irq_save(flags);
 	v->counter += i;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
-static __inline__ void atomic_sub(int i, volatile atomic_t *v)
+static inline void atomic_sub(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
 
-	__save_flags_cli(flags);
+	local_irq_save(flags);
 	v->counter -= i;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
-static __inline__ void atomic_inc(volatile atomic_t *v)
+static inline void atomic_inc(volatile atomic_t *v)
 {
 	unsigned long flags;
 
-	__save_flags_cli(flags);
+	local_irq_save(flags);
 	v->counter += 1;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
-static __inline__ void atomic_dec(volatile atomic_t *v)
+static inline void atomic_dec(volatile atomic_t *v)
 {
 	unsigned long flags;
 
-	__save_flags_cli(flags);
+	local_irq_save(flags);
 	v->counter -= 1;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
-static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+static inline int atomic_dec_and_test(volatile atomic_t *v)
 {
 	unsigned long flags;
-	int result;
+	int val;
 
-	__save_flags_cli(flags);
-	v->counter -= 1;
-	result = (v->counter == 0);
-	__restore_flags(flags);
+	local_irq_save(flags);
+	val = v->counter;
+	v->counter = val -= 1;
+	local_irq_restore(flags);
 
-	return result;
+	return val == 0;
 }
 
 static inline int atomic_add_negative(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
-	int result;
+	int val;
 
-	__save_flags_cli(flags);
-	v->counter += i;
-	result = (v->counter < 0);
-	__restore_flags(flags);
+	local_irq_save(flags);
+	val = v->counter;
+	v->counter = val += i;
+	local_irq_restore(flags);
 
-	return result;
+	return val < 0;
 }
 
-static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
 {
 	unsigned long flags;
 
-	__save_flags_cli(flags);
+	local_irq_save(flags);
 	*addr &= ~mask;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /* Atomic operations are already serializing on ARM */
diff -urN linux-2.4.22-pre2/include/asm-arm/bitops.h linux-2.4.22-pre3/include/asm-arm/bitops.h
--- linux-2.4.22-pre2/include/asm-arm/bitops.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/bitops.h	2003-07-05 18:11:12.000000000 -0700
@@ -88,7 +88,7 @@
  */
 static inline int test_bit(int nr, const void * addr)
 {
-    return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7));
+    return (((unsigned char *) addr)[nr >> 3] >> (nr & 7)) & 1;
 }	
 
 /*
diff -urN linux-2.4.22-pre2/include/asm-arm/cpu-multi32.h linux-2.4.22-pre3/include/asm-arm/cpu-multi32.h
--- linux-2.4.22-pre2/include/asm-arm/cpu-multi32.h	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/cpu-multi32.h	2003-07-05 18:11:12.000000000 -0700
@@ -43,7 +43,7 @@
 	/*
 	 * Idle the processor
 	 */
-	int (*_do_idle)(int mode);
+	int (*_do_idle)(void);
 	/*
 	 * Processor architecture specific
 	 */
@@ -133,7 +133,7 @@
 #define cpu_proc_init()				processor._proc_init()
 #define cpu_proc_fin()				processor._proc_fin()
 #define cpu_reset(addr)				processor.reset(addr)
-#define cpu_do_idle(mode)			processor._do_idle(mode)
+#define cpu_do_idle()				processor._do_idle()
 
 #define cpu_cache_clean_invalidate_all()	processor.cache.clean_invalidate_all()
 #define cpu_cache_clean_invalidate_range(s,e,f)	processor.cache.clean_invalidate_range(s,e,f)
diff -urN linux-2.4.22-pre2/include/asm-arm/cpu-single.h linux-2.4.22-pre3/include/asm-arm/cpu-single.h
--- linux-2.4.22-pre2/include/asm-arm/cpu-single.h	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/cpu-single.h	2003-07-05 18:11:12.000000000 -0700
@@ -62,7 +62,7 @@
 extern void cpu_check_bugs(void);
 extern void cpu_proc_init(void);
 extern void cpu_proc_fin(void);
-extern int cpu_do_idle(int mode);
+extern int cpu_do_idle(void);
 
 extern void cpu_cache_clean_invalidate_all(void);
 extern void cpu_cache_clean_invalidate_range(unsigned long address, unsigned long end, int flags);
diff -urN linux-2.4.22-pre2/include/asm-arm/delay.h linux-2.4.22-pre3/include/asm-arm/delay.h
--- linux-2.4.22-pre2/include/asm-arm/delay.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/delay.h	2003-07-05 18:11:12.000000000 -0700
@@ -1,32 +1,66 @@
+/*
+ *  linux/include/asm-arm/delay.h
+ *
+ *  Copyright (C) 1995-2003 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Delay routines, using a pre-computed "loops_per_second" value.
+ */
 #ifndef __ASM_ARM_DELAY_H
 #define __ASM_ARM_DELAY_H
 
 /*
- * Copyright (C) 1995 Russell King
+ * Division by multiplication and shifts.
+ *
+ *  We want the number of loops to complete, where loops is:
+ *      (us * (HZ * loops_per_jiffy)) / 10^6
+ *  or
+ *      (ns * (HZ * loops_per_jiffy)) / 10^9
+ *
+ *  Since we don't want to do long division, we multiply both numerator
+ *  and denominator by (2^28 / 10^6):
  *
- * Delay routines, using a pre-computed "loops_per_second" value.
+ *      (us * (2^28 / 10^6) * HZ * loops_per_jiffy) / 2^28
+ *
+ *  =>  (us * (2^28 * HZ / 10^6) * loops_per_jiffy) / 2^28
+ *
+ *  ~>  (((us * (2^28 * HZ / 10^6)) / 2^11) * (loops_per_jiffy / 2^12)) / 2^5
+ *         (for large loops_per_jiffy >> 2^12)
+ *
+ *  Note: maximum loops_per_jiffy = 67108863 (bogomips = 1342.18)
+ *        minimum loops_per_jiffy = 20000 (bogomips = 0.4)
+ *
+ * Note: we rely on HZ = 100.
  */
+#define UDELAY_FACTOR	26843
+#define NDELAY_FACTOR	27
 
-extern void __delay(int loops);
+#ifndef __ASSEMBLY__
 
-/*
- * division by multiplication: you don't have to worry about
- * loss of precision.
- *
- * Use only for very small delays ( < 1 msec).  Should probably use a
- * lookup table, really, as the multiplications take much too long with
- * short delays.  This is a "reasonable" implementation, though (and the
- * first constant multiplications gets optimized away if the delay is
- * a constant)
- */
-extern void udelay(unsigned long usecs);
+extern void __bad_udelay(void);	/* intentional errors */
+extern void __bad_ndelay(void);	/* intentional errors */
 
-static inline unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
-{
-	return a * b / c;
-}
+extern void __delay(unsigned long loops);
+extern void __udelay(unsigned long usecs);
+extern void __ndelay(unsigned long nsecs);
+extern void __const_delay(unsigned long units);
+
+#define udelay(n) 							\
+	(__builtin_constant_p(n) ?					\
+		((n) > 20000 ? __bad_udelay()				\
+			     : __const_delay((n) * UDELAY_FACTOR))	\
+				 : __udelay(n))
+
+#define ndelay(n) 							\
+	(__builtin_constant_p(n) ?					\
+		((n) > 20000 ? __bad_ndelay()				\
+			     : __const_delay((n) * NDELAY_FACTOR))	\
+				 : __ndelay(n))
 
-	
+#endif
 
 #endif /* defined(_ARM_DELAY_H) */
 
diff -urN linux-2.4.22-pre2/include/asm-arm/dma.h linux-2.4.22-pre3/include/asm-arm/dma.h
--- linux-2.4.22-pre2/include/asm-arm/dma.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/dma.h	2003-07-05 18:11:12.000000000 -0700
@@ -74,6 +74,10 @@
  */
 extern void disable_dma(dmach_t channel);
 
+/* Test whether the specified channel has an active DMA transfer
+ */
+extern int dma_channel_active(dmach_t channel);
+
 /* Set the DMA scatter gather list for this channel
  *
  * This should not be called if a DMA channel is enabled,
diff -urN linux-2.4.22-pre2/include/asm-arm/ecard.h linux-2.4.22-pre3/include/asm-arm/ecard.h
--- linux-2.4.22-pre2/include/asm-arm/ecard.h	2001-02-08 16:32:44.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/ecard.h	2003-07-05 18:11:12.000000000 -0700
@@ -53,6 +53,9 @@
 #define MANU_SERPORT		0x003f
 #define PROD_SERPORT_DSPORT		0x00b9
 
+#define MANU_ARXE 		0x0041
+#define PROD_ARXE_SCSI			0x00be
+
 #define MANU_I3			0x0046
 #define PROD_I3_ETHERLAN500		0x00d4
 #define PROD_I3_ETHERLAN600		0x00ec
@@ -95,9 +98,10 @@
 	ECARD_SYNC	 = 3
 } card_speed_t;
 
-typedef struct  {			/* Card ID structure		*/
-	unsigned short manufacturer;
-	unsigned short product;
+typedef struct ecard_id {		/* Card ID structure		*/
+	unsigned short	manufacturer;
+	unsigned short	product;
+	void		*data;
 } card_ids;
 
 struct in_ecid {			/* Packed card ID information	*/
@@ -126,12 +130,33 @@
 	int  (*fiqpending)(ecard_t *ec);
 } expansioncard_ops_t;
 
+#define ECARD_NUM_RESOURCES	(6)
+
+#define ECARD_RES_IOCSLOW	(0)
+#define ECARD_RES_IOCMEDIUM	(1)
+#define ECARD_RES_IOCFAST	(2)
+#define ECARD_RES_IOCSYNC	(3)
+#define ECARD_RES_MEMC		(4)
+#define ECARD_RES_EASI		(5)
+
+#define ecard_resource_start(ec,nr)	((ec)->resource[nr].start)
+#define ecard_resource_end(ec,nr)	((ec)->resource[nr].end)
+#define ecard_resource_len(ec,nr)	((ec)->resource[nr].end - \
+					 (ec)->resource[nr].start + 1)
+
+struct ecard_driver;
+
 /*
  * This contains all the info needed on an expansion card
  */
 struct expansion_card {
 	struct expansion_card  *next;
 
+	void			*driver_data;
+	struct ecard_driver	*driver;
+	struct resource		resource[ECARD_NUM_RESOURCES];
+	char			name[30];
+
 	/* Public data */
 	volatile unsigned char *irqaddr;	/* address of IRQ register	*/
 	volatile unsigned char *fiqaddr;	/* address of FIQ register	*/
@@ -141,7 +166,7 @@
 
 	void			*irq_data;	/* Data for use for IRQ by card	*/
 	void			*fiq_data;	/* Data for use for FIQ by card	*/
-	expansioncard_ops_t	*ops;		/* Enable/Disable Ops for card	*/
+	const expansioncard_ops_t *ops;		/* Enable/Disable Ops for card	*/
 
 	CONST unsigned int	slot_no;	/* Slot number			*/
 	CONST unsigned int	dma;		/* DMA number (for request_dma)	*/
@@ -248,4 +273,18 @@
 
 #endif
 
+struct ecard_driver {
+	int			(*probe)(struct expansion_card *, const struct ecard_id *);
+	void			(*remove)(struct expansion_card *);
+	void			(*shutdown)(struct expansion_card *);
+	const struct ecard_id	*id_table;
+	unsigned int		id;
+};
+
+#define ecard_set_drvdata(ec,data)	((ec)->driver_data = (data))
+#define ecard_get_drvdata(ec)		((ec)->driver_data)
+
+int ecard_register_driver(struct ecard_driver *);
+void ecard_remove_driver(struct ecard_driver *);
+
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/elf.h linux-2.4.22-pre3/include/asm-arm/elf.h
--- linux-2.4.22-pre2/include/asm-arm/elf.h	2001-04-12 12:20:31.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/elf.h	2003-07-05 18:11:12.000000000 -0700
@@ -6,11 +6,11 @@
  */
 
 #include <asm/ptrace.h>
+#include <asm/user.h>
 #include <asm/proc/elf.h>
 #include <asm/procinfo.h>
 
 typedef unsigned long elf_greg_t;
-typedef unsigned long elf_freg_t[3];
 
 #define EM_ARM	40
 #define EF_ARM_APCS26 0x08
@@ -18,7 +18,7 @@
 #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
-typedef struct { void *null; } elf_fpregset_t;
+typedef struct user_fp elf_fpregset_t;
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
@@ -53,7 +53,6 @@
 /* This yields a mask that user programs can use to figure out what
    instruction set this cpu supports. */
 
-extern unsigned int elf_hwcap;
 #define ELF_HWCAP	(elf_hwcap)
 
 /* This yields a string that ld.so will use to load implementation
diff -urN linux-2.4.22-pre2/include/asm-arm/hardware/ep7312.h linux-2.4.22-pre3/include/asm-arm/hardware/ep7312.h
--- linux-2.4.22-pre2/include/asm-arm/hardware/ep7312.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/hardware/ep7312.h	2003-07-05 18:11:12.000000000 -0700
@@ -0,0 +1,66 @@
+/*
+ *  linux/include/asm-arm/hardware/ep7312.h
+ *
+ *  This file contains the hardware definitions of the EP7312 internal
+ *  registers.
+ *
+ *  Copyright (C) 2003 Roland A.I. Rosier <roland.rosier@lycos.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+#ifndef __ASM_HARDWARE_EP7312_H
+#define __ASM_HARDWARE_EP7312_H
+
+#include <linux/config.h>
+
+/*
+ * Include CLPS7111 and EP7212 register definitions
+ */
+
+#include <asm/hardware/clps7111.h>
+#include <asm/hardware/ep7212.h>
+
+/*
+ * define EP7312_BASE to be the base address of the region
+ * you want to access.
+ */
+
+#define EP7312_PHYS_BASE        (0x80000000)
+
+#define SDCONF   0x2300	/* SDRAM Configuration register */
+#define SDRFPR   0x2340	/* SDRAM Refresh period register */
+#define UNIQID   0x2440	/* 32 bit unique ID for the EP73xx device */
+#define DAI64FS  0x2600	/* DAI 64Fs Control Register */
+#define PLLW     0x2610	/* Write Register for PLL Multiplier */
+#define PLLR     0xA5A8	/* Read Register for PLL Multiplier */
+#define RANDID0	 0x2700	/* Bits 31-0 of 128-bit random ID */
+#define RANDID1	 0x2704	/* Bits 63-32 of 128-bit random ID */
+#define RANDID2	 0x2708	/* Bits 95-64 of 128-bit random ID */
+#define RANDID3	 0x270C	/* Bits 127-96 of 128-bit random ID */
+
+#define SDCONF_ACTIVE           (1 << 10)
+#define SDCONF_CLKCTL           (1 << 9)
+#define SDCONF_WIDTH_4          (0 << 7)
+#define SDCONF_WIDTH_8          (1 << 7)
+#define SDCONF_WIDTH_16         (2 << 7)
+#define SDCONF_WIDTH_32         (3 << 7)
+#define SDCONF_SIZE_16          (0 << 5)
+#define SDCONF_SIZE_64          (1 << 5)
+#define SDCONF_SIZE_128         (2 << 5)
+#define SDCONF_SIZE_256         (3 << 5)
+#define SDCONF_CASLAT_2         (2)
+#define SDCONF_CASLAT_3         (3)
+
+#endif /* __ASM_HARDWARE_EP7312_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/hardware/iomd.h linux-2.4.22-pre3/include/asm-arm/hardware/iomd.h
--- linux-2.4.22-pre2/include/asm-arm/hardware/iomd.h	2001-04-12 12:20:31.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/hardware/iomd.h	2003-07-05 18:11:12.000000000 -0700
@@ -28,12 +28,18 @@
 
 #endif
 
+#if defined(CONFIG_ARCH_RISCSTATION) || defined(CONFIG_ARCH_CLPS7500)
+#ifndef CONFIG_CPU_7500
+#define CONFIG_CPU_7500
+#endif
+#endif
+
 #define IOMD_CONTROL	(0x000)
 #define IOMD_KARTTX	(0x004)
 #define IOMD_KARTRX	(0x004)
 #define IOMD_KCTRL	(0x008)
 
-#ifdef CONFIG_ARCH_CLPS7500
+#ifdef CONFIG_CPU_7500
 #define IOMD_IOLINES	(0x00C)
 #endif
 
@@ -42,7 +48,7 @@
 #define IOMD_IRQCLRA	(0x014)
 #define IOMD_IRQMASKA	(0x018)
 
-#ifdef CONFIG_ARCH_CLPS7500
+#ifdef CONFIG_CPU_7500
 #define IOMD_SUSMODE	(0x01C)
 #endif
 
@@ -54,7 +60,7 @@
 #define IOMD_FIQREQ	(0x034)
 #define IOMD_FIQMASK	(0x038)
 
-#ifdef CONFIG_ARCH_CLPS7500
+#ifdef CONFIG_CPU_7500
 #define IOMD_CLKCTL	(0x03C)
 #endif
 
@@ -72,7 +78,7 @@
 #define IOMD_T1GO	(0x058)
 #define IOMD_T1LATCH	(0x05c)
 
-#ifdef CONFIG_ARCH_CLPS7500
+#ifdef CONFIG_CPU_7500
 #define IOMD_IRQSTATC	(0x060)
 #define IOMD_IRQREQC	(0x064)
 #define IOMD_IRQMASKC	(0x068)
@@ -101,7 +107,7 @@
 #define IOMD_MOUSEY	(0x0A4)
 #endif
 
-#ifdef CONFIG_ARCH_CLPS7500
+#ifdef CONFIG_CPU_7500
 #define IOMD_MSEDAT	(0x0A8)
 #define IOMD_MSECTL	(0x0Ac)
 #endif
@@ -114,7 +120,7 @@
 #ifdef CONFIG_ARCH_RPC
 #define IOMD_DMAEXT	(0x0CC)
 #endif
-#ifdef CONFIG_ARCH_CLPS7500
+#ifdef CONFIG_CPU_7500
 #define IOMD_ASTCR	(0x0CC)
 #define IOMD_DRAMCR	(0x0D0)
 #define IOMD_SELFREF	(0x0D4)
diff -urN linux-2.4.22-pre2/include/asm-arm/hardware/sa1111.h linux-2.4.22-pre3/include/asm-arm/hardware/sa1111.h
--- linux-2.4.22-pre2/include/asm-arm/hardware/sa1111.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/hardware/sa1111.h	2003-07-05 18:11:12.000000000 -0700
@@ -675,4 +675,6 @@
 #define PCSSR_S0_SLEEP	(1<<0)
 #define PCSSR_S1_SLEEP	(1<<1)
 
+int sa1111_check_dma_bug(dma_addr_t addr);
+
 #endif  /* _ASM_ARCH_SA1111 */
diff -urN linux-2.4.22-pre2/include/asm-arm/hardware/serial_omaha.h linux-2.4.22-pre3/include/asm-arm/hardware/serial_omaha.h
--- linux-2.4.22-pre2/include/asm-arm/hardware/serial_omaha.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/hardware/serial_omaha.h	2003-07-05 18:11:12.000000000 -0700
@@ -0,0 +1,62 @@
+/*
+ *  linux/include/asm-arm/hardware/serial_omaha.h
+ *
+ *  Internal header file for Omaha serial ports
+ *
+ *  Copyright (C) 2002 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef ASM_ARM_HARDWARE_SERIAL_OMAHA_H
+#define ASM_ARM_HARDWARE_SERIAL_OMAHA_H
+
+#define OMAHA_UART0_BASE                0x15000000	 /*  Uart 0 base */
+#define OMAHA_UART1_BASE                0x15004000	 /*  Uart 1 base */
+
+/* 
+ *  UART Register Offsets.
+ */
+#define OMAHA_ULCON                     0x00		 /*  Line control */
+#define OMAHA_UCON                      0x04		 /*  Control */
+#define OMAHA_UFCON                     0x08		 /*  FIFO control */
+#define OMAHA_UMCON                     0x0C		 /*  Modem control */
+#define OMAHA_UTRSTAT                   0x10		 /*  Rx/Tx status */
+#define OMAHA_UERSTAT                   0x14		 /*  Rx Error Status */
+#define OMAHA_UFSTAT                    0x18		 /*  FIFO status */
+#define OMAHA_UMSTAT                    0x1C		 /*  Modem status */
+#define OMAHA_UTXH                      0x20		 /*  Transmission Hold (byte wide) */
+#define OMAHA_URXH                      0x24		 /*  Receive buffer (byte wide) */
+#define OMAHA_UBRDIV                    0x28		 /*  Baud rate divisor */
+
+/*  UART status flags in OMAHA_UTRSTAT
+ */
+#define OMAHA_URX_FULL                  0x1		 /*  Receive buffer has valid data */
+#define OMAHA_UTX_EMPTY                 0x2		 /*  Transmitter has finished */
+
+/* UART status flags in UFSTAT */
+#define OMAHA_TXFF			0x200		/* TX FIFO Full. */
+#define OMAHA_RXFF			0x100		/* RX FIFO Full. */
+#define OMAHA_TXFF_CNT			0xF0		/* Tx FIFO count */
+#define OMAHA_RXFF_CNT			0x0F		/* Rx FIFO count */
+
+/* UART status flags in UERSTAT
+*/
+#define OMAHA_UART_OVERRUN  		0x0
+#define OMAHA_UART_PARITY		0x1
+#define OMAHA_UART_FRAME		0x2
+#define OMAHA_UART_BREAK		0x4
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/hardware/ssp.h linux-2.4.22-pre3/include/asm-arm/hardware/ssp.h
--- linux-2.4.22-pre2/include/asm-arm/hardware/ssp.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/hardware/ssp.h	2003-07-05 18:11:12.000000000 -0700
@@ -0,0 +1,28 @@
+/*
+ *  ssp.h
+ *
+ *  Copyright (C) 2003 Russell King, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef SSP_H
+#define SSP_H
+
+struct ssp_state {
+	unsigned int	cr0;
+	unsigned int	cr1;
+};
+
+int ssp_write_word(u16 data);
+int ssp_read_word(void);
+void ssp_flush(void);
+void ssp_enable(void);
+void ssp_disable(void);
+void ssp_save_state(struct ssp_state *ssp);
+void ssp_restore_state(struct ssp_state *ssp);
+int ssp_init(void);
+void ssp_exit(void);
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-arm/io.h linux-2.4.22-pre3/include/asm-arm/io.h
--- linux-2.4.22-pre2/include/asm-arm/io.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/io.h	2003-07-05 18:11:13.000000000 -0700
@@ -23,6 +23,7 @@
 #ifdef __KERNEL__
 
 #include <linux/types.h>
+#include <asm/byteorder.h>
 #include <asm/memory.h>
 #include <asm/arch/hardware.h>
 
@@ -72,22 +73,37 @@
 #include <asm/arch/io.h>
 
 /*
- * IO definitions.  We define {out,in,outs,ins}[bwl] if __io is defined
- * by the machine.  Otherwise, these definitions are left for the machine
- * specific header files to pick up.
+ *  IO port access primitives
+ *  -------------------------
+ *
+ * The ARM doesn't have special IO access instructions; all IO is memory
+ * mapped.  Note that these are defined to perform little endian accesses
+ * only.  Their primary purpose is to access PCI and ISA peripherals.
+ *
+ * Note that for a big endian machine, this implies that the following
+ * big endian mode connectivity is in place, as described by numerious
+ * ARM documents:
+ *
+ *    PCI:  D0-D7   D8-D15 D16-D23 D24-D31
+ *    ARM: D24-D31 D16-D23  D8-D15  D0-D7
+ *
+ * The machine specific io.h include defines __io to translate an "IO"
+ * address to a memory address.
  *
  * Note that we prevent GCC re-ordering or caching values in expressions
  * by introducing sequence points into the in*() definitions.  Note that
  * __raw_* do not guarantee this behaviour.
+ *
+ * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
  */
 #ifdef __io
 #define outb(v,p)			__raw_writeb(v,__io(p))
-#define outw(v,p)			__raw_writew(v,__io(p))
-#define outl(v,p)			__raw_writel(v,__io(p))
+#define outw(v,p)			__raw_writew(cpu_to_le16(v),__io(p))
+#define outl(v,p)			__raw_writel(cpu_to_le32(v),__io(p))
 
-#define inb(p)		({ unsigned int __v = __raw_readb(__io(p)); __v; })
-#define inw(p)		({ unsigned int __v = __raw_readw(__io(p)); __v; })
-#define inl(p)		({ unsigned int __v = __raw_readl(__io(p)); __v; })
+#define inb(p)	({ unsigned int __v = __raw_readb(__io(p)); __v; })
+#define inw(p)	({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; })
+#define inl(p)	({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; })
 
 #define outsb(p,d,l)			__raw_writesb(__io(p),d,l)
 #define outsw(p,d,l)			__raw_writesw(__io(p),d,l)
@@ -172,20 +188,20 @@
  */
 #ifdef __mem_pci
 
-#define readb(addr) ({ unsigned int __v = __raw_readb(__mem_pci(addr)); __v; })
-#define readw(addr) ({ unsigned int __v = __raw_readw(__mem_pci(addr)); __v; })
-#define readl(addr) ({ unsigned int __v = __raw_readl(__mem_pci(addr)); __v; })
-
-#define writeb(val,addr)		__raw_writeb(val,__mem_pci(addr))
-#define writew(val,addr)		__raw_writew(val,__mem_pci(addr))
-#define writel(val,addr)		__raw_writel(val,__mem_pci(addr))
-
-#define memset_io(a,b,c)		_memset_io(__mem_pci(a),(b),(c))
-#define memcpy_fromio(a,b,c)		_memcpy_fromio((a),__mem_pci(b),(c))
-#define memcpy_toio(a,b,c)		_memcpy_toio(__mem_pci(a),(b),(c))
+#define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; })
+#define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; })
+#define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; })
+
+#define writeb(v,c)		__raw_writeb(v,__mem_pci(c))
+#define writew(v,c)		__raw_writew(cpu_to_le16(v),__mem_pci(c))
+#define writel(v,c)		__raw_writel(cpu_to_le32(v),__mem_pci(c))
+
+#define memset_io(c,v,l)		_memset_io(__mem_pci(c),(v),(l))
+#define memcpy_fromio(a,c,l)		_memcpy_fromio((a),__mem_pci(c),(l))
+#define memcpy_toio(c,a,l)		_memcpy_toio(__mem_pci(c),(a),(l))
 
-#define eth_io_copy_and_sum(a,b,c,d) \
-				eth_copy_and_sum((a),__mem_pci(b),(c),(d))
+#define eth_io_copy_and_sum(s,c,l,b) \
+				eth_copy_and_sum((s),__mem_pci(c),(l),(b))
 
 static inline int
 check_signature(unsigned long io_addr, const unsigned char *signature,
@@ -220,14 +236,6 @@
 #endif	/* __mem_pci */
 
 /*
- * remap a physical address `phys' of size `size' with page protection `prot'
- * into virtual address `from'
- */
-#define io_remap_page_range(from,phys,size,prot) \
-		remap_page_range(from,phys,size,prot)
-
-
-/*
  * If this architecture has ISA IO, then define the isa_read/isa_write
  * macros.
  */
diff -urN linux-2.4.22-pre2/include/asm-arm/mach/arch.h linux-2.4.22-pre3/include/asm-arm/mach/arch.h
--- linux-2.4.22-pre2/include/asm-arm/mach/arch.h	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/mach/arch.h	2003-07-05 18:11:13.000000000 -0700
@@ -54,39 +54,39 @@
 #define MACHINE_START(_type,_name)		\
 const struct machine_desc __mach_desc_##_type	\
  __attribute__((__section__(".arch.info"))) = {	\
-	nr:		MACH_TYPE_##_type,	\
-	name:		_name,
+	.nr		= MACH_TYPE_##_type,	\
+	.name		= _name,
 
 #define MAINTAINER(n)
 
 #define BOOT_MEM(_pram,_pio,_vio)		\
-	phys_ram:	_pram,	                \
-	phys_io:	_pio,  	                \
-	io_pg_offst:	((_vio)>>18)&0xfffc,
+	.phys_ram	= _pram,                \
+	.phys_io	= _pio,			\
+	.io_pg_offst	= ((_vio)>>18)&0xfffc,
 
 #define BOOT_PARAMS(_params)			\
-	param_offset:	_params,
+	.param_offset	= _params,
 
 #define VIDEO(_start,_end)			\
-	video_start:	_start,			\
-	video_end:	_end,
+	.video_start	= _start,		\
+	.video_end	= _end,
 
 #define DISABLE_PARPORT(_n)			\
-	reserve_lp##_n:	1,
+	.reserve_lp##_n	= 1,
 
 #define BROKEN_HLT /* unused */
 
 #define SOFT_REBOOT				\
-	soft_reboot:	1,
+	.soft_reboot	= 1,
 
 #define FIXUP(_func)				\
-	fixup:		_func,
+	.fixup		= _func,
 
 #define MAPIO(_func)				\
-	map_io:		_func,
+	.map_io		= _func,
 
 #define INITIRQ(_func)				\
-	init_irq:	_func,
+	.init_irq	= _func,
 
 #define MACHINE_END				\
 };
diff -urN linux-2.4.22-pre2/include/asm-arm/mach/dma.h linux-2.4.22-pre3/include/asm-arm/mach/dma.h
--- linux-2.4.22-pre2/include/asm-arm/mach/dma.h	2000-09-18 15:15:23.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/mach/dma.h	2003-07-05 18:11:13.000000000 -0700
@@ -40,7 +40,6 @@
 
 	unsigned int	dma_base;	/* Controller base address	*/
 	int		dma_irq;	/* Controller IRQ		*/
-	int		state;		/* Controller state		*/
 	struct scatterlist cur_sg;	/* Current controller buffer	*/
 
 	struct dma_ops	*d_ops;
diff -urN linux-2.4.22-pre2/include/asm-arm/mach/irq.h linux-2.4.22-pre3/include/asm-arm/mach/irq.h
--- linux-2.4.22-pre2/include/asm-arm/mach/irq.h	2001-02-08 16:32:44.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/mach/irq.h	2003-07-05 18:11:13.000000000 -0700
@@ -11,24 +11,31 @@
 #define __ASM_ARM_MACH_IRQ_H
 
 struct irqdesc {
-	unsigned int	 nomask   : 1;		/* IRQ does not mask in IRQ   */
-	unsigned int	 enabled  : 1;		/* IRQ is currently enabled   */
 	unsigned int	 triggered: 1;		/* IRQ has occurred	      */
+	unsigned int	 running  : 1;		/* IRQ is running             */
+	unsigned int	 pending  : 1;		/* IRQ is pending	      */
 	unsigned int	 probing  : 1;		/* IRQ in use for a probe     */
 	unsigned int	 probe_ok : 1;		/* IRQ can be used for probe  */
 	unsigned int	 valid    : 1;		/* IRQ claimable	      */
 	unsigned int	 noautoenable : 1;	/* don't automatically enable IRQ */
 	unsigned int	 unused   :25;
+	unsigned int	 disable_depth;
+
+	struct list_head pend;
+
 	void (*mask_ack)(unsigned int irq);	/* Mask and acknowledge IRQ   */
 	void (*mask)(unsigned int irq);		/* Mask IRQ		      */
 	void (*unmask)(unsigned int irq);	/* Unmask IRQ		      */
 	struct irqaction *action;
+
 	/*
 	 * IRQ lock detection
 	 */
 	unsigned int	 lck_cnt;
 	unsigned int	 lck_pc;
 	unsigned int	 lck_jif;
+	int		 lck_warned;
+	struct timer_list	lck_timer;
 };
 
 extern struct irqdesc irq_desc[];
diff -urN linux-2.4.22-pre2/include/asm-arm/mach/serial_at91rm9200.h linux-2.4.22-pre3/include/asm-arm/mach/serial_at91rm9200.h
--- linux-2.4.22-pre2/include/asm-arm/mach/serial_at91rm9200.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/mach/serial_at91rm9200.h	2003-07-05 18:11:13.000000000 -0700
@@ -0,0 +1,37 @@
+/*
+ *  linux/include/asm-arm/mach/serial_at91rm9200.h
+ *
+ *  Based on serial_sa1100.h  by Nicolas Pitre
+ *
+ *  Copyright (C) 2002 ATMEL Rousset
+ *
+ *  Low level machine dependent UART functions.
+ */
+#include <linux/config.h>
+
+struct uart_port;
+struct uart_info;
+
+/*
+ * This is a temporary structure for registering these
+ * functions; it is intended to be discarded after boot.
+ */
+struct at91rm9200_port_fns {
+	void	(*set_mctrl)(struct uart_port *, u_int);
+	u_int	(*get_mctrl)(struct uart_port *);
+	void	(*enable_ms)(struct uart_port *);
+	void	(*pm)(struct uart_port *, u_int, u_int);
+	int	(*set_wake)(struct uart_port *, u_int);
+	int	(*open)(struct uart_port *, struct uart_info *);
+	void	(*close)(struct uart_port *, struct uart_info *);
+};
+
+#if defined(CONFIG_SERIAL_AT91RM9200)
+void at91rm9200_register_uart_fns(struct at91rm9200_port_fns *fns);
+void at91rm9200_register_uart(int idx, int port);
+#else
+#define at91rm9200_register_uart_fns(fns) do { } while (0)
+#define at91rm9200_register_uart(idx,port) do { } while (0)
+#endif
+
+
diff -urN linux-2.4.22-pre2/include/asm-arm/mach/serial_sa1100.h linux-2.4.22-pre3/include/asm-arm/mach/serial_sa1100.h
--- linux-2.4.22-pre2/include/asm-arm/mach/serial_sa1100.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/mach/serial_sa1100.h	2003-07-05 18:11:13.000000000 -0700
@@ -22,8 +22,8 @@
 	void	(*enable_ms)(struct uart_port *);
 	void	(*pm)(struct uart_port *, u_int, u_int);
 	int	(*set_wake)(struct uart_port *, u_int);
-	int	(*open)(struct uart_port *, struct uart_info *);
-	void	(*close)(struct uart_port *, struct uart_info *);
+	int	(*open)(struct uart_port *);
+	void	(*close)(struct uart_port *);
 };
 
 #if defined(CONFIG_SERIAL_SA1100) && !defined(CONFIG_SERIAL_SA1100_OLD)
diff -urN linux-2.4.22-pre2/include/asm-arm/mc146818rtc.h linux-2.4.22-pre3/include/asm-arm/mc146818rtc.h
--- linux-2.4.22-pre2/include/asm-arm/mc146818rtc.h	2000-08-13 09:54:15.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/mc146818rtc.h	2003-07-05 18:11:13.000000000 -0700
@@ -16,13 +16,36 @@
  * The yet supported machines all access the RTC index register via
  * an ISA port access but the way to access the date register differs ...
  */
+
+
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#ifdef CONFIG_ARCH_RISCSTATION
+
+/* RiscStation hardware has a lock to ensure random read/writes can't
+ * do anything nasty to it
+*/
+
+#undef CMOS_READ
+#undef CMOS_WRITE
+
 #define CMOS_READ(addr) ({ \
 outb_p((addr),RTC_PORT(0)); \
+outb_p((addr),RTC_PORT(3)); \
 inb_p(RTC_PORT(1)); \
 })
 #define CMOS_WRITE(val, addr) ({ \
 outb_p((addr),RTC_PORT(0)); \
+outb_p((addr),RTC_PORT(3)); \
 outb_p((val),RTC_PORT(1)); \
 })
+#endif /* CONFIG_ARCH_RISCSTATION */
 
 #endif /* _ASM_MC146818RTC_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/memory.h linux-2.4.22-pre3/include/asm-arm/memory.h
--- linux-2.4.22-pre2/include/asm-arm/memory.h	2001-08-12 11:14:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/memory.h	2003-07-05 18:11:13.000000000 -0700
@@ -1,22 +1,34 @@
 /*
  *  linux/include/asm-arm/memory.h
  *
- *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2000-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
  *  Note: this file should not be included by non-asm/.h files
- *
- *  Modifications:
  */
 #ifndef __ASM_ARM_MEMORY_H
 #define __ASM_ARM_MEMORY_H
 
+#include <linux/config.h>
 #include <asm/arch/memory.h>
 
-static inline unsigned long virt_to_phys(volatile void *x)
+/*
+ * PFNs are used to describe any physical page; this means
+ * PFN 0 == physical address 0.
+ *
+ * This is the PFN of the first RAM page in the kernel
+ * direct-mapped view.  We assume this is the first page
+ * of RAM in the mem_map as well.
+ */
+#define PHYS_PFN_OFFSET	(PHYS_OFFSET >> PAGE_SHIFT)
+
+/*
+ * These are *only* valid on the kernel direct mapped RAM memory.
+ */
+static inline unsigned long virt_to_phys(void *x)
 {
 	return __virt_to_phys((unsigned long)(x));
 }
@@ -26,10 +38,101 @@
 	return (void *)(__phys_to_virt((unsigned long)(x)));
 }
 
+#define __pa(x)			__virt_to_phys((unsigned long)(x))
+#define __va(x)			((void *)__phys_to_virt((unsigned long)(x)))
+
 /*
  * Virtual <-> DMA view memory address translations
+ * Again, these are *only* valid on the kernel direct mapped RAM
+ * memory.  Use of these is *depreciated*.
  */
 #define virt_to_bus(x)		(__virt_to_bus((unsigned long)(x)))
 #define bus_to_virt(x)		((void *)(__bus_to_virt((unsigned long)(x))))
 
+/*
+ * Conversion between a struct page and a physical address.
+ *
+ * Note: when converting an unknown physical address to a
+ * struct page, the resulting pointer must be validated
+ * using VALID_PAGE().  It must return an invalid struct page
+ * for any physical address not corresponding to a system
+ * RAM address.
+ *
+ *  page_to_pfn(page)	convert a struct page * to a PFN number
+ *  pfn_to_page(pfn)	convert a _valid_ PFN number to struct page *
+ *  pfn_valid(pfn)	indicates whether a PFN number is valid
+ *
+ *  virt_to_page(k)	convert a _valid_ virtual address to struct page *
+ *  virt_addr_valid(k)	indicates whether a virtual address is valid
+ */
+#ifndef CONFIG_DISCONTIGMEM
+
+#define page_to_pfn(page)	(((page) - mem_map) + PHYS_PFN_OFFSET)
+#define pfn_to_page(pfn)	((mem_map + (pfn)) - PHYS_PFN_OFFSET)
+#define pfn_valid(pfn)		((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
+
+#define virt_to_page(kaddr)	(pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
+#define virt_addr_valid(kaddr)	((kaddr) >= PAGE_OFFSET && (kaddr) < (unsigned long)high_memory)
+
+#define PHYS_TO_NID(addr)	(0)
+
+#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+
+#else
+
+/*
+ * This is more complex.  We have a set of mem_map arrays spread
+ * around in memory.
+ */
+#define page_to_pfn(page)					\
+	(((page) - page_zone(page)->zone_mem_map)		\
+	  + (page_zone(page)->zone_start_paddr >> PAGE_SHIFT))
+
+#define pfn_to_page(pfn)					\
+	(PFN_TO_MAPBASE(pfn) + LOCAL_MAP_NR((pfn) << PAGE_SHIFT))
+
+#define pfn_valid(pfn)						\
+  ({								\
+	unsigned int node = PFN_TO_NID(pfn);			\
+	struct pglist_data *nd = NODE_DATA(node);		\
+	((node < NR_NODES) &&					\
+	 ((pfn - (nd->node_start_paddr >> PAGE_SHIFT)) < nd->node_size));\
+   })
+
+#define virt_to_page(kaddr)					\
+	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
+
+#define virt_addr_valid(kaddr)	(KVADDR_TO_NID(kaddr) < NR_NODES)
+
+/*
+ * Common discontigmem stuff.
+ *  PHYS_TO_NID is used by the ARM kernel/setup.c
+ */
+#define PHYS_TO_NID(addr)	PFN_TO_NID((addr) >> PAGE_SHIFT)
+
+/*
+ * 2.4 compatibility
+ *
+ * VALID_PAGE returns a non-zero value if given page pointer is valid.
+ * This assumes all node's mem_maps are stored within the node they
+ * refer to.  This is actually inherently buggy.
+ */
+#define VALID_PAGE(page) \
+({ unsigned int node = KVADDR_TO_NID(page); \
+   ((node < NR_NODES) && \
+     ((unsigned)((page) - NODE_MEM_MAP(node)) < NODE_DATA(node)->node_size)); \
+})
+
+#endif
+
+/*
+ * For BIO.  "will die".  Kill me when bio_to_phys() and bvec_to_phys() die.
+ */
+#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
+
+/*
+ * We should really eliminate virt_to_bus() here - it's depreciated.
+ */
+#define page_to_bus(page)	(virt_to_bus(page_address(page)))
+
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/mmu.h linux-2.4.22-pre3/include/asm-arm/mmu.h
--- linux-2.4.22-pre2/include/asm-arm/mmu.h	2000-12-29 14:07:23.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/mmu.h	2003-07-05 18:11:13.000000000 -0700
@@ -1,7 +1,9 @@
 #ifndef __ARM_MMU_H
 #define __ARM_MMU_H
 
-/* The ARM doesn't have a mmu context */
+/*
+ * The ARM doesn't have a mmu context
+ */
 typedef struct { } mm_context_t;
 
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/mmu_context.h linux-2.4.22-pre3/include/asm-arm/mmu_context.h
--- linux-2.4.22-pre2/include/asm-arm/mmu_context.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/mmu_context.h	2003-07-05 18:11:13.000000000 -0700
@@ -13,9 +13,8 @@
 #ifndef __ASM_ARM_MMU_CONTEXT_H
 #define __ASM_ARM_MMU_CONTEXT_H
 
-#include <asm/bitops.h>
 #include <asm/pgtable.h>
-#include <asm/arch/memory.h>
+#include <asm/memory.h>
 #include <asm/proc-fns.h>
 
 #define destroy_context(mm)		do { } while(0)
@@ -30,7 +29,8 @@
  *
  * tsk->mm will be NULL
  */
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+static inline void
+enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
 {
 }
 
diff -urN linux-2.4.22-pre2/include/asm-arm/page.h linux-2.4.22-pre3/include/asm-arm/page.h
--- linux-2.4.22-pre2/include/asm-arm/page.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/page.h	2003-07-05 18:11:13.000000000 -0700
@@ -95,17 +95,11 @@
 #endif /* !__ASSEMBLY__ */
 
 #include <linux/config.h>
-#include <asm/arch/memory.h>
+#include <asm/memory.h>
 
-#define __pa(x)			__virt_to_phys((unsigned long)(x))
-#define __va(x)			((void *)__phys_to_virt((unsigned long)(x)))
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#ifndef CONFIG_DISCONTIGMEM
-#define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT) - \
-				 (PHYS_OFFSET >> PAGE_SHIFT))
-#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
-#endif
-
-#endif
+#endif /* __KERNEL__ */
 
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/pci.h linux-2.4.22-pre3/include/asm-arm/pci.h
--- linux-2.4.22-pre2/include/asm-arm/pci.h	2002-02-25 11:38:10.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/pci.h	2003-07-05 18:11:13.000000000 -0700
@@ -3,7 +3,45 @@
 
 #ifdef __KERNEL__
 
+#include <linux/mm.h>
 #include <asm/arch/hardware.h>
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+
+/*
+ * For SA-1111 these functions are "magic" and utilize bounce
+ * buffers as need to workaround SA-1111 DMA bugs.  They are called in
+ * place of their pci_* counterparts when dev_is_sa1111() returns true.
+ */
+dma_addr_t sa1111_map_single(void *, size_t, int);
+void sa1111_unmap_single(dma_addr_t, size_t, int);
+int sa1111_map_sg(struct scatterlist *, int, int);
+void sa1111_unmap_sg(struct scatterlist *, int, int);
+void sa1111_dma_sync_single(dma_addr_t, size_t, int);
+void sa1111_dma_sync_sg(struct scatterlist *, int, int);
+
+#ifdef CONFIG_SA1111
+
+#define SA1111_FAKE_PCIDEV ((struct pci_dev *) 1111)
+
+static inline int dev_is_sa1111(const struct pci_dev *dev)
+{
+	return (dev == SA1111_FAKE_PCIDEV);
+}
+
+#else
+
+static inline int dev_is_sa1111(const struct pci_dev *dev) { return 0; }
+
+#endif
+
+/*
+ * The PCI address space does equal the physical memory address space.
+ * The networking and block device layers use this boolean for bounce
+ * buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS     (0)
+
 
 static inline void pcibios_set_master(struct pci_dev *dev)
 {
@@ -15,9 +53,6 @@
 	/* We don't do dynamic PCI IRQ allocation */
 }
 
-#include <asm/scatterlist.h>
-#include <asm/io.h>
-
 struct pci_dev;
 
 /* Allocate and map kernel buffer using consistent mode DMA for a device.
@@ -53,17 +88,9 @@
 static inline dma_addr_t
 pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
 {
-#ifdef CONFIG_SA1111
-	extern dma_addr_t sa1111_map_single(struct pci_dev *, void *, size_t, int);
+	if (dev_is_sa1111(hwdev))
+		return sa1111_map_single(ptr, size, direction);
 
-	/*
-	 * for SA1111 these functions are "magic" and relocate buffers.  We
-	 * only need to do these if hwdev is non-null; otherwise we expect
-	 * the buffer to already be suitable for DMA.
-	 */
-	if (hwdev != NULL)
-		return sa1111_map_single(hwdev, ptr, size, direction);
-#endif
 	consistent_sync(ptr, size, direction);
 	return virt_to_bus(ptr);
 }
@@ -78,12 +105,9 @@
 static inline void
 pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
 {
-#ifdef CONFIG_SA1111
-	extern void sa1111_unmap_single(struct pci_dev *, dma_addr_t, size_t, int);
+	if (dev_is_sa1111(hwdev))
+		sa1111_unmap_single(dma_addr, size, direction);
 
-	if (hwdev != NULL)
-		sa1111_unmap_single(hwdev, dma_addr, size, direction);
-#endif
 	/* nothing to do */
 }
 
@@ -132,9 +156,17 @@
 {
 	int i;
 
+	if (dev_is_sa1111(hwdev))
+		return sa1111_map_sg(sg, nents, direction);
+
 	for (i = 0; i < nents; i++, sg++) {
-		consistent_sync(sg->address, sg->length, direction);
-		sg->dma_address = virt_to_bus(sg->address);
+		char *vaddr = sg->address;
+
+		if (!vaddr)
+			vaddr = ((char *)page_address(sg->page)) + sg->offset;
+
+		consistent_sync(vaddr, sg->length, direction);
+		sg->dma_address = virt_to_bus(vaddr);
 	}
 
 	return nents;
@@ -147,6 +179,11 @@
 static inline void
 pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
 {
+	if (dev_is_sa1111(hwdev)) {
+		sa1111_unmap_sg(sg, nents, direction);
+		return;
+	}
+
 	/* nothing to do */
 }
 
@@ -162,6 +199,11 @@
 static inline void
 pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
 {
+	if (dev_is_sa1111(hwdev)) {
+	  	sa1111_dma_sync_single(dma_handle, size, direction);
+		return;
+	}
+
 	consistent_sync(bus_to_virt(dma_handle), size, direction);
 }
 
@@ -176,6 +218,11 @@
 {
 	int i;
 
+ 	if (dev_is_sa1111(hwdev)) {
+ 	  	sa1111_dma_sync_sg(sg, nelems, direction);
+ 		return;
+ 	}
+
 	for (i = 0; i < nelems; i++, sg++)
 		consistent_sync(sg->address, sg->length, direction);
 }
@@ -196,6 +243,19 @@
 /* Return the index of the PCI controller for device PDEV. */
 #define pci_controller_num(PDEV)	(0)
 
+
+#if defined(CONFIG_SA1111) && !defined(CONFIG_PCI)
+/* SA-1111 needs these prototypes even when !defined(CONFIG_PCI) */
+
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation, int flags);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+#endif
+
 #endif /* __KERNEL__ */
  
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/pgtable.h linux-2.4.22-pre3/include/asm-arm/pgtable.h
--- linux-2.4.22-pre2/include/asm-arm/pgtable.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/pgtable.h	2003-07-05 18:11:13.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/include/asm-arm/pgtable.h
  *
- *  Copyright (C) 2000-2001 Russell King
+ *  Copyright (C) 2000-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -11,7 +11,7 @@
 #define _ASMARM_PGTABLE_H
 
 #include <linux/config.h>
-#include <asm/arch/memory.h>
+#include <asm/memory.h>
 #include <asm/proc-fns.h>
 
 /*
@@ -75,21 +75,13 @@
 extern struct page *empty_zero_page;
 #define ZERO_PAGE(vaddr)	(empty_zero_page)
 
+#define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
+#define pfn_pte(pfn,prot)	(__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
+
 #define pte_none(pte)		(!pte_val(pte))
 #define pte_clear(ptep)		set_pte((ptep), __pte(0))
 
-#ifndef CONFIG_DISCONTIGMEM
-#define pte_page(x)		(mem_map + (pte_val((x)) >> PAGE_SHIFT) - \
-				 (PHYS_OFFSET >> PAGE_SHIFT))
-#else
-/*
- * I'm not happy with this - we needlessly convert a physical address
- * to a virtual one, and then immediately back to a physical address,
- * which, if __va and __pa are expensive causes twice the expense for
- * zero gain. --rmk
- */
-#define pte_page(x)		(virt_to_page(__va(pte_val((x)))))
-#endif
+#define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
 
 #define pmd_none(pmd)		(!pmd_val(pmd))
 #define pmd_present(pmd)	(pmd_val(pmd))
@@ -111,13 +103,7 @@
 	return pte;
 }
 
-#define mk_pte(page,pgprot)				\
-({							\
-	pte_t __pte;					\
-	pte_val(__pte) = __pa(page_address(page)) +	\
-			   pgprot_val(pgprot);		\
-	__pte;						\
-})
+#define mk_pte(page,prot)	pfn_pte(page_to_pfn(page),prot)
 
 /*
  * The "pgd_xxx()" functions here are trivial for a folded two-level
@@ -127,7 +113,7 @@
 #define pgd_none(pgd)		(0)
 #define pgd_bad(pgd)		(0)
 #define pgd_present(pgd)	(1)
-#define pgd_clear(pgdp)
+#define pgd_clear(pgdp)		do { } while (0)
 
 #define page_pte_prot(page,prot)	mk_pte(page, prot)
 #define page_pte(page)		mk_pte(page, __pgprot(0))
@@ -176,6 +162,13 @@
 
 extern void pgtable_cache_init(void);
 
+/*
+ * remap a physical address `phys' of size `size' with page protection `prot'
+ * into virtual address `from'
+ */
+#define io_remap_page_range(from,phys,size,prot) \
+		remap_page_range(from,phys,size,prot)
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASMARM_PGTABLE_H */
diff -urN linux-2.4.22-pre2/include/asm-arm/proc-armo/locks.h linux-2.4.22-pre3/include/asm-arm/proc-armo/locks.h
--- linux-2.4.22-pre2/include/asm-arm/proc-armo/locks.h	2000-09-18 15:15:24.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/proc-armo/locks.h	2003-07-05 18:11:13.000000000 -0700
@@ -31,7 +31,7 @@
 "	blmi	" SYMBOL_NAME_STR(fail)		\
 	:					\
 	: "r" (ptr)				\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	})
 
 #define __down_op_ret(ptr,fail)			\
@@ -54,7 +54,7 @@
 "	mov	%0, ip"				\
 	: "=&r" (result)			\
 	: "r" (ptr)				\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	result;					\
 	})
 
@@ -75,7 +75,7 @@
 "	blmi	" SYMBOL_NAME_STR(wake)		\
 	:					\
 	: "r" (ptr)				\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	})
 
 /*
@@ -107,7 +107,7 @@
 "	blne	" SYMBOL_NAME_STR(fail)		\
 	:					\
 	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	})
 
 /* Increments by RW_LOCK_BIAS, wakes if value >= 0 */
@@ -130,7 +130,7 @@
 "	blcs	" SYMBOL_NAME_STR(wake)		\
 	:					\
 	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	})
 
 #define __down_op_read(ptr,fail)		\
@@ -155,7 +155,7 @@
 "	bleq	" SYMBOL_NAME_STR(wake)		\
 	:					\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	})
 
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/proc-armo/processor.h linux-2.4.22-pre3/include/asm-arm/proc-armo/processor.h
--- linux-2.4.22-pre2/include/asm-arm/proc-armo/processor.h	2000-11-27 17:07:59.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/proc-armo/processor.h	2003-07-05 18:11:13.000000000 -0700
@@ -57,7 +57,7 @@
 	uaccess_t	*uaccess;		/* User access functions*/
 
 #define EXTRA_THREAD_STRUCT_INIT		\
-	uaccess:	&uaccess_kernel,
+	.uaccess	= &uaccess_kernel,
 
 #define start_thread(regs,pc,sp)					\
 ({									\
@@ -71,8 +71,8 @@
 	regs->ARM_r0 = stack[0];	/* r0 (argc) */			\
 })
 
-#define KSTK_EIP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
-#define KSTK_ESP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1020])
+#define KSTK_EIP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1020])
+#define KSTK_ESP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1018])
 
 /* Allocation and freeing of basic task resources. */
 /*
diff -urN linux-2.4.22-pre2/include/asm-arm/proc-armo/system.h linux-2.4.22-pre3/include/asm-arm/proc-armo/system.h
--- linux-2.4.22-pre2/include/asm-arm/proc-armo/system.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/proc-armo/system.h	2003-07-05 18:11:13.000000000 -0700
@@ -39,7 +39,7 @@
 /*
  * Save the current interrupt enable state & disable IRQs
  */
-#define __save_flags_cli(x)				\
+#define local_save_flags_cli(x)				\
 	do {						\
 	  unsigned long temp;				\
 	  __asm__ __volatile__(				\
@@ -55,7 +55,7 @@
 /*
  * Enable IRQs
  */
-#define __sti()					\
+#define local_irq_enable()			\
 	do {					\
 	  unsigned long temp;			\
 	  __asm__ __volatile__(			\
@@ -70,7 +70,7 @@
 /*
  * Disable IRQs
  */
-#define __cli()					\
+#define local_irq_disable()			\
 	do {					\
 	  unsigned long temp;			\
 	  __asm__ __volatile__(			\
@@ -103,7 +103,7 @@
 /*
  * save current IRQ & FIQ state
  */
-#define __save_flags(x)				\
+#define local_save_flags(x)			\
 	do {					\
 	  __asm__ __volatile__(			\
 "	mov	%0, pc		@ save_flags\n"	\
@@ -114,7 +114,7 @@
 /*
  * restore saved IRQ & FIQ state
  */
-#define __restore_flags(x)				\
+#define local_irq_restore(x)				\
 	do {						\
 	  unsigned long temp;				\
 	  __asm__ __volatile__(				\
diff -urN linux-2.4.22-pre2/include/asm-arm/proc-armo/uncompress.h linux-2.4.22-pre3/include/asm-arm/proc-armo/uncompress.h
--- linux-2.4.22-pre2/include/asm-arm/proc-armo/uncompress.h	2000-09-18 15:15:24.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/proc-armo/uncompress.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,11 +0,0 @@
-/*
- *  linux/include/asm-arm/proc-armo/uncompress.h
- *
- *  Copyright (C) 1997 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#define proc_decomp_setup()
diff -urN linux-2.4.22-pre2/include/asm-arm/proc-armv/cache.h linux-2.4.22-pre3/include/asm-arm/proc-armv/cache.h
--- linux-2.4.22-pre2/include/asm-arm/proc-armv/cache.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/proc-armv/cache.h	2003-07-05 18:11:13.000000000 -0700
@@ -128,6 +128,9 @@
 	}
 }
 
+#define flush_icache_user_range(vma,page,addr,len) \
+	flush_dcache_page(page)
+
 #define clean_dcache_entry(_s)		cpu_dcache_clean_entry((unsigned long)(_s))
 
 /*
diff -urN linux-2.4.22-pre2/include/asm-arm/proc-armv/elf.h linux-2.4.22-pre3/include/asm-arm/proc-armv/elf.h
--- linux-2.4.22-pre2/include/asm-arm/proc-armv/elf.h	2000-08-13 09:54:15.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/proc-armv/elf.h	2003-07-05 18:11:13.000000000 -0700
@@ -6,10 +6,14 @@
 
 #ifdef __KERNEL__
 
-/* 32-bit code is always OK.  Some cpus can do 26-bit, some can't.  */
-#define ELF_PROC_OK(x)				\
-	((! ((x)->e_flags & EF_ARM_APCS26))	\
-	|| (elf_hwcap & HWCAP_26BIT))
+/*
+ * 32-bit code is always OK.  Some cpus can do 26-bit, some can't.
+ */
+#define ELF_PROC_OK(x) 							 \
+	(( (elf_hwcap & HWCAP_THUMB) && ((x)->e_entry & 1) == 1)      || \
+	 (!(elf_hwcap & HWCAP_THUMB) && ((x)->e_entry & 3) == 0)      || \
+	 ( (elf_hwcap & HWCAP_26BIT) && (x)->e_flags & EF_ARM_APCS26) || \
+	 ((x)->e_flags & EF_ARM_APCS26) == 0)
 
 /* Old NetWinder binaries were compiled in such a way that the iBCS
    heuristic always trips on them.  Until these binaries become uncommon
diff -urN linux-2.4.22-pre2/include/asm-arm/proc-armv/locks.h linux-2.4.22-pre3/include/asm-arm/proc-armv/locks.h
--- linux-2.4.22-pre2/include/asm-arm/proc-armv/locks.h	2000-09-18 15:15:24.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/proc-armv/locks.h	2003-07-05 18:11:13.000000000 -0700
@@ -27,7 +27,7 @@
 "	blmi	" SYMBOL_NAME_STR(fail)		\
 	:					\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	})
 
 #define __down_op_ret(ptr,fail)			\
@@ -48,7 +48,7 @@
 "	mov	%0, ip"				\
 	: "=&r" (ret)				\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	ret;					\
 	})
 
@@ -67,7 +67,7 @@
 "	blle	" SYMBOL_NAME_STR(wake)		\
 	:					\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	})
 
 /*
@@ -94,7 +94,7 @@
 "	blne	" SYMBOL_NAME_STR(fail)		\
 	:					\
 	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	})
 
 #define __up_op_write(ptr,wake)			\
@@ -112,7 +112,7 @@
 "	blcs	" SYMBOL_NAME_STR(wake)		\
 	:					\
 	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	})
 
 #define __down_op_read(ptr,fail)		\
@@ -133,7 +133,7 @@
 "	bleq	" SYMBOL_NAME_STR(wake)		\
 	:					\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc");			\
+	: "ip", "lr", "cc", "memory");		\
 	})
 
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/proc-armv/processor.h linux-2.4.22-pre3/include/asm-arm/proc-armv/processor.h
--- linux-2.4.22-pre2/include/asm-arm/proc-armv/processor.h	2000-11-27 17:07:59.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/proc-armv/processor.h	2003-07-05 18:11:13.000000000 -0700
@@ -61,8 +61,8 @@
 	regs->ARM_r0 = stack[0];	/* r0 (argc) */			\
 })
 
-#define KSTK_EIP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1021])
-#define KSTK_ESP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1019])
+#define KSTK_EIP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1019])
+#define KSTK_ESP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1017])
 
 /* Allocation and freeing of basic task resources. */
 /*
diff -urN linux-2.4.22-pre2/include/asm-arm/proc-armv/system.h linux-2.4.22-pre3/include/asm-arm/proc-armv/system.h
--- linux-2.4.22-pre2/include/asm-arm/proc-armv/system.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/proc-armv/system.h	2003-07-05 18:11:13.000000000 -0700
@@ -36,24 +36,20 @@
 extern unsigned long cr_no_alignment;	/* defined in entry-armv.S */
 extern unsigned long cr_alignment;	/* defined in entry-armv.S */
 
-#ifdef __ARM_ARCH_4__
+#if __LINUX_ARM_ARCH__ >= 4
 #define vectors_base()	((cr_alignment & CR_V) ? 0xffff0000 : 0)
 #else
 #define vectors_base()	(0)
 #endif
 
 /*
- * A couple of speedups for the ARM
- */
-
-/*
  * Save the current interrupt enable state & disable IRQs
  */
-#define __save_flags_cli(x)					\
+#define local_irq_save(x)					\
 	({							\
 		unsigned long temp;				\
 	__asm__ __volatile__(					\
-	"mrs	%0, cpsr		@ save_flags_cli\n"	\
+	"mrs	%0, cpsr		@ local_irq_save\n"	\
 "	orr	%1, %0, #128\n"					\
 "	msr	cpsr_c, %1"					\
 	: "=r" (x), "=r" (temp)					\
@@ -61,14 +57,26 @@
 	: "memory");						\
 	})
 	
+#define local_irq_set(x)					\
+	({							\
+		unsigned long temp;				\
+	__asm__ __volatile__(					\
+	"mrs	%0, cpsr		@ local_irq_set\n"	\
+"	bic	%1, %0, #128\n"					\
+"	msr	cpsr_c, %1"					\
+	: "=r" (x), "=r" (temp)					\
+	:							\
+	: "memory");						\
+	})
+
 /*
  * Enable IRQs
  */
-#define __sti()							\
+#define local_irq_enable()					\
 	({							\
 		unsigned long temp;				\
 	__asm__ __volatile__(					\
-	"mrs	%0, cpsr		@ sti\n"		\
+	"mrs	%0, cpsr		@ local_irq_enable\n"	\
 "	bic	%0, %0, #128\n"					\
 "	msr	cpsr_c, %0"					\
 	: "=r" (temp)						\
@@ -79,11 +87,11 @@
 /*
  * Disable IRQs
  */
-#define __cli()							\
+#define local_irq_disable()					\
 	({							\
 		unsigned long temp;				\
 	__asm__ __volatile__(					\
-	"mrs	%0, cpsr		@ cli\n"		\
+	"mrs	%0, cpsr		@ local_irq_disable\n"	\
 "	orr	%0, %0, #128\n"					\
 "	msr	cpsr_c, %0"					\
 	: "=r" (temp)						\
@@ -122,27 +130,27 @@
 	})
 
 /*
- * save current IRQ & FIQ state
+ * Save the current interrupt enable state.
  */
-#define __save_flags(x)						\
+#define local_save_flags(x)					\
+	({							\
 	__asm__ __volatile__(					\
-	"mrs	%0, cpsr		@ save_flags\n"		\
+	"mrs	%0, cpsr		@ local_save_flags\n"	\
 	  : "=r" (x)						\
 	  :							\
-	  : "memory")
+	  : "memory");						\
+	})
 
 /*
  * restore saved IRQ & FIQ state
  */
-#define __restore_flags(x)					\
+#define local_irq_restore(x)					\
 	__asm__ __volatile__(					\
-	"msr	cpsr_c, %0		@ restore_flags\n"	\
+	"msr	cpsr_c, %0		@ local_irq_restore\n"	\
 	:							\
 	: "r" (x)						\
 	: "memory")
 
-#define __save_and_sti(x)	({__save_flags(x);__sti();})
-
 #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
 /*
  * On the StrongARM, "swp" is terminally broken since it bypasses the
@@ -170,31 +178,31 @@
 	switch (size) {
 #ifdef swp_is_buggy
 		case 1:
-			__save_flags_cli(flags);
+			local_irq_save(flags);
 			ret = *(volatile unsigned char *)ptr;
 			*(volatile unsigned char *)ptr = x;
-			__restore_flags(flags);
+			local_irq_restore(flags);
 			break;
 
 		case 4:
-			__save_flags_cli(flags);
+			local_irq_save(flags);
 			ret = *(volatile unsigned long *)ptr;
 			*(volatile unsigned long *)ptr = x;
-			__restore_flags(flags);
+			local_irq_restore(flags);
 			break;
 #else
 		case 1:	__asm__ __volatile__ ("swpb %0, %1, [%2]"
-					: "=r" (ret)
+					: "=&r" (ret)
 					: "r" (x), "r" (ptr)
 					: "memory");
 			break;
 		case 4:	__asm__ __volatile__ ("swp %0, %1, [%2]"
-					: "=r" (ret)
+					: "=&r" (ret)
 					: "r" (x), "r" (ptr)
 					: "memory");
 			break;
 #endif
-		default: __bad_xchg(ptr, size);
+		default: __bad_xchg(ptr, size), ret = 0;
 	}
 
 	return ret;
diff -urN linux-2.4.22-pre2/include/asm-arm/proc-armv/uncompress.h linux-2.4.22-pre3/include/asm-arm/proc-armv/uncompress.h
--- linux-2.4.22-pre2/include/asm-arm/proc-armv/uncompress.h	2000-09-18 15:15:24.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/proc-armv/uncompress.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,26 +0,0 @@
-/*
- *  linux/include/asm-arm/proc-armv/uncompress.h
- *
- *  Copyright (C) 1997 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-static inline void proc_decomp_setup (void)
-{
-	__asm__ __volatile__("
-	mrc	p15, 0, r0, c0, c0
-	eor	r0, r0, #0x44 << 24
-	eor	r0, r0, #0x01 << 16
-	eor	r0, r0, #0xA1 << 8
-	movs	r0, r0, lsr #5
-	mcreq	p15, 0, r0, c7, c5, 0		@ flush I cache
-	mrceq	p15, 0, r0, c1, c0
-	orreq	r0, r0, #1 << 12
-	mcreq	p15, 0, r0, c1, c0		@ enable I cache
-	mov	r0, #0
-	mcreq	p15, 0, r0, c15, c1, 2		@ enable clock switching
-	" : : : "r0", "cc", "memory");
-}
diff -urN linux-2.4.22-pre2/include/asm-arm/proc-fns.h linux-2.4.22-pre3/include/asm-arm/proc-fns.h
--- linux-2.4.22-pre2/include/asm-arm/proc-fns.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/proc-fns.h	2003-07-05 18:11:13.000000000 -0700
@@ -76,6 +76,14 @@
 #   define CPU_NAME arm926
 #  endif
 # endif
+# ifdef CONFIG_CPU_ARM1026
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME arm1026
+#  endif
+# endif
 # ifdef CONFIG_CPU_SA110
 #  ifdef CPU_NAME
 #   undef  MULTI_CPU
diff -urN linux-2.4.22-pre2/include/asm-arm/processor.h linux-2.4.22-pre3/include/asm-arm/processor.h
--- linux-2.4.22-pre2/include/asm-arm/processor.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/processor.h	2003-07-05 18:11:13.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/include/asm-arm/processor.h
  *
- *  Copyright (C) 1995 Russell King
+ *  Copyright (C) 1995-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -44,13 +44,21 @@
 #include <asm/ptrace.h>
 #include <asm/arch/memory.h>
 #include <asm/proc/processor.h>
+#include <asm/types.h>
+
+union debug_insn {
+	u32	arm;
+	u16	thumb;
+};
+
+struct debug_entry {
+	u32			address;
+	union debug_insn	insn;
+};
 
 struct debug_info {
-	int				nsaved;
-	struct {
-		unsigned long		address;
-		unsigned long		insn;
-	} bp[2];
+	int			nsaved;
+	struct debug_entry	bp[2];
 };
 
 struct thread_struct {
@@ -81,7 +89,7 @@
 	return t->save ? pc_pointer(t->save->pc) : 0;
 }
 
-static inline unsigned long get_css_fp(struct thread_struct *t)
+static inline unsigned long thread_saved_fp(struct thread_struct *t)
 {
 	return t->save ? t->save->fp : 0;
 }
@@ -112,7 +120,7 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
-#define cpu_relax()	do { } while (0)
+#define cpu_relax()	barrier()
 
 /*
  * Create a new kernel thread
diff -urN linux-2.4.22-pre2/include/asm-arm/procinfo.h linux-2.4.22-pre3/include/asm-arm/procinfo.h
--- linux-2.4.22-pre2/include/asm-arm/procinfo.h	2001-04-12 12:20:31.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/procinfo.h	2003-07-05 18:11:13.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/include/asm-arm/procinfo.h
  *
- *  Copyright (C) 1996-1999 Russell King
+ *  Copyright (C) 1996-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -14,6 +14,8 @@
 
 #include <asm/proc-fns.h>
 
+struct processor;
+
 struct proc_info_item {
 	const char	 *manufacturer;
 	const char	 *cpu_name;
@@ -29,30 +31,31 @@
  *  arch/arm/mm/proc-*.S and arch/arm/kernel/head-armv.S
  */
 struct proc_info_list {
-	unsigned int	 cpu_val;
-	unsigned int	 cpu_mask;
-	unsigned long	 __cpu_mmu_flags;	/* used by head-armv.S */
-	unsigned long	 __cpu_flush;		/* used by head-armv.S */
-	const char	 *arch_name;
-	const char	 *elf_name;
-	unsigned int	 elf_hwcap;
-	struct proc_info_item *info;
-#ifdef MULTI_CPU
-	struct processor *proc;
-#else
-	void		 *unused;
-#endif
+	unsigned int		cpu_val;
+	unsigned int		cpu_mask;
+	unsigned long		__cpu_mmu_flags;	/* used by head-armv.S */
+	unsigned long		__cpu_flush;		/* used by head-armv.S */
+	const char		*arch_name;
+	const char		*elf_name;
+	unsigned int		elf_hwcap;
+	struct proc_info_item	*info;
+	struct processor	*proc;
 };
 
+extern unsigned int elf_hwcap;
+
 #endif	/* __ASSEMBLY__ */
 
-#define HWCAP_SWP	 1
-#define HWCAP_HALF	 2
-#define HWCAP_THUMB	 4
-#define HWCAP_26BIT	 8	/* Play it safe */
-#define HWCAP_FAST_MULT	 16
-#define HWCAP_FPA        32
-#define HWCAP_VFP        64
-#define HWCAP_EDSP	 128
+#define PROC_INFO_SZ	36
+
+#define HWCAP_SWP	1
+#define HWCAP_HALF	2
+#define HWCAP_THUMB	4
+#define HWCAP_26BIT	8	/* Play it safe */
+#define HWCAP_FAST_MULT	16
+#define HWCAP_FPA	32
+#define HWCAP_VFP	64
+#define HWCAP_EDSP	128
+#define HWCAP_JAVA	256
 
 #endif
diff -urN linux-2.4.22-pre2/include/asm-arm/ptrace.h linux-2.4.22-pre3/include/asm-arm/ptrace.h
--- linux-2.4.22-pre2/include/asm-arm/ptrace.h	2000-09-03 11:19:11.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/ptrace.h	2003-07-05 18:11:14.000000000 -0700
@@ -1,6 +1,16 @@
 #ifndef __ASM_ARM_PTRACE_H
 #define __ASM_ARM_PTRACE_H
 
+#define PTRACE_GETREGS		12
+#define PTRACE_SETREGS		13
+#define PTRACE_GETFPREGS	14
+#define PTRACE_SETFPREGS	15
+
+#define PTRACE_SETOPTIONS	21
+
+/* options set using PTRACE_SETOPTIONS */
+#define PTRACE_O_TRACESYSGOOD	0x00000001
+
 #include <asm/proc/ptrace.h>
 
 #ifndef __ASSEMBLY__
@@ -11,11 +21,6 @@
 	(pc_pointer((regs)->ARM_pc))
 
 #ifdef __KERNEL__
-#define PTRACE_GETREGS		12
-#define PTRACE_SETREGS		13
-#define PTRACE_GETFPREGS	14
-#define PTRACE_SETFPREGS	15
-
 extern void show_regs(struct pt_regs *);
 
 #define predicate(x)	(x & 0xf0000000)
diff -urN linux-2.4.22-pre2/include/asm-arm/scatterlist.h linux-2.4.22-pre3/include/asm-arm/scatterlist.h
--- linux-2.4.22-pre2/include/asm-arm/scatterlist.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/scatterlist.h	2003-07-05 18:11:14.000000000 -0700
@@ -5,7 +5,8 @@
 
 struct scatterlist {
 	char		*address;	/* virtual address		 */
-	struct page	*page;		/* Location for highmem page, if any */
+	struct page	*page;		/* buffer page			 */
+	unsigned int	offset;		/* buffer address		 */
 	dma_addr_t	dma_address;	/* dma address			 */
 	unsigned int	length;		/* length			 */
 };
diff -urN linux-2.4.22-pre2/include/asm-arm/setup.h linux-2.4.22-pre3/include/asm-arm/setup.h
--- linux-2.4.22-pre2/include/asm-arm/setup.h	2001-10-25 13:53:55.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/setup.h	2003-07-05 18:11:14.000000000 -0700
@@ -130,9 +130,16 @@
 	u32 start;	/* starting block of floppy-based RAM disk image */
 };
 
-/* describes where the compressed ramdisk image lives */
+/* describes where the compressed ramdisk image lives (virtual address) */
+/*
+ * this one accidentally used virtual addresses - as such,
+ * its depreciated.
+ */
 #define ATAG_INITRD	0x54410005
 
+/* describes where the compressed ramdisk image lives (physical address) */
+#define ATAG_INITRD2	0x54420005
+
 struct tag_initrd {
 	u32 start;	/* physical start address */
 	u32 size;	/* size of compressed ramdisk image in bytes */
diff -urN linux-2.4.22-pre2/include/asm-arm/signal.h linux-2.4.22-pre3/include/asm-arm/signal.h
--- linux-2.4.22-pre2/include/asm-arm/signal.h	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/signal.h	2003-07-05 18:11:14.000000000 -0700
@@ -124,7 +124,6 @@
  */
 #define SA_PROBE		0x80000000
 #define SA_SAMPLE_RANDOM	0x10000000
-#define SA_IRQNOMASK		0x08000000
 #define SA_SHIRQ		0x04000000
 #endif
 
diff -urN linux-2.4.22-pre2/include/asm-arm/stat.h linux-2.4.22-pre3/include/asm-arm/stat.h
--- linux-2.4.22-pre2/include/asm-arm/stat.h	2000-08-01 14:08:00.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/stat.h	2003-07-05 18:11:14.000000000 -0700
@@ -40,6 +40,8 @@
 
 /* This matches struct stat64 in glibc2.1, hence the absolutely
  * insane amounts of padding around dev_t's.
+ * Note: The kernel zero's the padded region because glibc might read them
+ * in the hope that the kernel has stretched to using larger sizes.
  */
 struct stat64 {
 	unsigned short	st_dev;
diff -urN linux-2.4.22-pre2/include/asm-arm/system.h linux-2.4.22-pre3/include/asm-arm/system.h
--- linux-2.4.22-pre2/include/asm-arm/system.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/system.h	2003-07-05 18:11:14.000000000 -0700
@@ -22,6 +22,13 @@
 #define have_isa_bridge		(0)
 #endif
 
+struct pt_regs;
+
+void die(const char *msg, struct pt_regs *regs, int err)
+		__attribute__((noreturn));
+
+void die_if_kernel(const char *str, struct pt_regs *regs, int err);
+
 #include <asm/proc-fns.h>
 
 #define xchg(ptr,x) \
@@ -59,11 +66,11 @@
 	} while (0)
 
 /* For spinlocks etc */
-#define local_irq_save(x)	__save_flags_cli(x)
-#define local_irq_set(x)	__save_and_sti(x)
-#define local_irq_restore(x)	__restore_flags(x)
-#define local_irq_disable()	__cli()
-#define local_irq_enable()	__sti()
+#define __save_flags_cli(x)	local_irq_save(x)
+#define __save_flags(x)		local_save_flags(x)
+#define __restore_flags(x)	local_irq_restore(x)
+#define __cli()			local_irq_disable()
+#define __sti()			local_irq_enable()
 
 #ifdef CONFIG_SMP
 #error SMP not supported
@@ -78,15 +85,15 @@
 #define smp_rmb()		barrier()
 #define smp_wmb()		barrier()
 
-#define cli()			__cli()
-#define sti()			__sti()
+#define cli()			local_irq_disable()
+#define sti()			local_irq_enable()
 #define clf()			__clf()
 #define stf()			__stf()
-#define save_flags(x)		__save_flags(x)
-#define restore_flags(x)	__restore_flags(x)
-#define save_flags_cli(x)	__save_flags_cli(x)
-#define save_and_cli(x)		__save_flags_cli(x)
-#define save_and_sti(x)		__save_flags_sti(x)
+#define save_flags(x)		local_save_flags(x)
+#define restore_flags(x)	local_irq_restore(x)
+#define save_flags_cli(x)	local_irq_save(x)
+#define save_and_cli(x)		local_irq_save(x)
+#define save_and_sti(x)		local_irq_set(x)
 
 #endif /* CONFIG_SMP */
 
diff -urN linux-2.4.22-pre2/include/asm-arm/types.h linux-2.4.22-pre3/include/asm-arm/types.h
--- linux-2.4.22-pre2/include/asm-arm/types.h	2000-02-06 17:45:26.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-arm/types.h	2003-07-05 18:11:14.000000000 -0700
@@ -44,6 +44,7 @@
 /* Dma addresses are 32-bits wide.  */
 
 typedef u32 dma_addr_t;
+typedef u32 dma64_addr_t;
 
 #endif /* __KERNEL__ */
 
diff -urN linux-2.4.22-pre2/include/asm-arm/unistd.h linux-2.4.22-pre3/include/asm-arm/unistd.h
--- linux-2.4.22-pre2/include/asm-arm/unistd.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-arm/unistd.h	2003-07-05 18:11:14.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *  linux/include/asm-arm/unistd.h
  *
- *  Copyright (C) 2001 Russell King
+ *  Copyright (C) 2001-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -13,7 +13,13 @@
 #ifndef __ASM_ARM_UNISTD_H
 #define __ASM_ARM_UNISTD_H
 
+#include <linux/linkage.h>
+
+#if defined(__thumb__)
+#define __NR_SYSCALL_BASE	0
+#else
 #define __NR_SYSCALL_BASE	0x900000
+#endif
 
 /*
  * This file contains the system call numbers.
@@ -259,10 +265,26 @@
 #define __NR_fremovexattr		(__NR_SYSCALL_BASE+237)
 #endif
 #define __NR_tkill			(__NR_SYSCALL_BASE+238)
-/*
- * Please check 2.5 _before_ adding calls here,
- * and copy changes to rmk@arm.linux.org.uk.  Thanks.
- */
+#if 0 /* allocated in 2.5 */
+#define __NR_sendfile64                 (__NR_SYSCALL_BASE+239)
+#define __NR_futex                      (__NR_SYSCALL_BASE+240)
+#define __NR_sched_setaffinity          (__NR_SYSCALL_BASE+241)
+#define __NR_sched_getaffinity          (__NR_SYSCALL_BASE+242)
+#define __NR_io_setup                   (__NR_SYSCALL_BASE+243)
+#define __NR_io_destroy                 (__NR_SYSCALL_BASE+244)
+#define __NR_io_getevents               (__NR_SYSCALL_BASE+245)
+#define __NR_io_submit                  (__NR_SYSCALL_BASE+246)
+#define __NR_io_cancel                  (__NR_SYSCALL_BASE+247)
+#define __NR_exit_group                 (__NR_SYSCALL_BASE+248)
+#define __NR_lookup_dcookie             (__NR_SYSCALL_BASE+249)
+#define __NR_epoll_create               (__NR_SYSCALL_BASE+250)
+#define __NR_epoll_ctl                  (__NR_SYSCALL_BASE+251)
+#define __NR_epoll_wait                 (__NR_SYSCALL_BASE+252)
+#define __NR_remap_file_pages           (__NR_SYSCALL_BASE+253)
+                                        /* 254 for set_thread_area */
+                                        /* 255 for get_thread_area */
+                                        /* 256 for set_tid_address */
+#endif
 
 /*
  * The following SWIs are ARM private.
@@ -277,13 +299,21 @@
 #define __sys1(x) __sys2(x)
 
 #ifndef __syscall
+#if defined(__thumb__)
+#define __syscall(name)					\
+	"push	{r7}\n\t"				\
+	"mov	r7, #" __sys1(__NR_##name) "\n\t"	\
+	"swi	0\n\t"					\
+	"pop	{r7}"
+#else
 #define __syscall(name) "swi\t" __sys1(__NR_##name) "\n\t"
 #endif
+#endif
 
 #define __syscall_return(type, res)					\
 do {									\
 	if ((unsigned long)(res) >= (unsigned long)(-125)) {		\
-		errno = -(res);						\
+		errno = -(res); 					\
 		res = -1;						\
 	}								\
 	return (type) (res);						\
@@ -291,91 +321,103 @@
 
 #define _syscall0(type,name)						\
 type name(void) {							\
-  long __res;								\
+  register long __res __asm__("r0");					\
   __asm__ __volatile__ (						\
   __syscall(name)							\
-  "mov %0,r0"								\
-  :"=r" (__res) : : "r0","lr");						\
-  __syscall_return(type,__res);						\
+	:"=r" (__res)							\
+	:								\
+	: "lr");							\
+  __syscall_return(type,__res); 					\
 }
 
-#define _syscall1(type,name,type1,arg1)					\
-type name(type1 arg1) {							\
-  long __res;								\
+#define _syscall1(type,name,type1,arg1) 				\
+type name(type1 arg1) { 						\
+  register long __r0 __asm__("r0") = (long)arg1;			\
+  register long __res __asm__("r0");					\
   __asm__ __volatile__ (						\
-  "mov\tr0,%1\n\t"							\
   __syscall(name)							\
-  "mov %0,r0"								\
-        : "=r" (__res)							\
-        : "r" ((long)(arg1))						\
-	: "r0","lr");							\
-  __syscall_return(type,__res);						\
+	: "=r" (__res)							\
+	: "r" (__r0)							\
+	: "lr");							\
+  __syscall_return(type,__res); 					\
 }
 
 #define _syscall2(type,name,type1,arg1,type2,arg2)			\
 type name(type1 arg1,type2 arg2) {					\
-  long __res;								\
+  register long __r0 __asm__("r0") = (long)arg1;			\
+  register long __r1 __asm__("r1") = (long)arg2;			\
+  register long __res __asm__("r0");					\
   __asm__ __volatile__ (						\
-  "mov\tr0,%1\n\t"							\
-  "mov\tr1,%2\n\t"							\
   __syscall(name)							\
-  "mov\t%0,r0"								\
-        : "=r" (__res)							\
-        : "r" ((long)(arg1)),"r" ((long)(arg2))				\
-	: "r0","r1","lr");						\
-  __syscall_return(type,__res);						\
+	: "=r" (__res)							\
+	: "r" (__r0),"r" (__r1) 					\
+	: "lr");							\
+  __syscall_return(type,__res); 					\
 }
 
 
 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\
 type name(type1 arg1,type2 arg2,type3 arg3) {				\
-  long __res;								\
+  register long __r0 __asm__("r0") = (long)arg1;			\
+  register long __r1 __asm__("r1") = (long)arg2;			\
+  register long __r2 __asm__("r2") = (long)arg3;			\
+  register long __res __asm__("r0");					\
   __asm__ __volatile__ (						\
-  "mov\tr0,%1\n\t"							\
-  "mov\tr1,%2\n\t"							\
-  "mov\tr2,%3\n\t"							\
   __syscall(name)							\
-  "mov\t%0,r0"								\
-        : "=r" (__res)							\
-        : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3))	\
-        : "r0","r1","r2","lr");						\
-  __syscall_return(type,__res);						\
+	: "=r" (__res)							\
+	: "r" (__r0),"r" (__r1),"r" (__r2)				\
+	: "lr");							\
+  __syscall_return(type,__res); 					\
 }
 
 
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)		\
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {				\
-  long __res;										\
-  __asm__ __volatile__ (								\
-  "mov\tr0,%1\n\t"									\
-  "mov\tr1,%2\n\t"									\
-  "mov\tr2,%3\n\t"									\
-  "mov\tr3,%4\n\t"									\
-  __syscall(name)									\
-  "mov\t%0,r0"										\
-  	: "=r" (__res)									\
-  	: "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4))	\
-  	: "r0","r1","r2","r3","lr");							\
-  __syscall_return(type,__res);								\
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {		\
+  register long __r0 __asm__("r0") = (long)arg1;			\
+  register long __r1 __asm__("r1") = (long)arg2;			\
+  register long __r2 __asm__("r2") = (long)arg3;			\
+  register long __r3 __asm__("r3") = (long)arg4;			\
+  register long __res __asm__("r0");					\
+  __asm__ __volatile__ (						\
+  __syscall(name)							\
+	: "=r" (__res)							\
+	: "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3)			\
+	: "lr");							\
+  __syscall_return(type,__res); 					\
 }
   
 
 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5)	\
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) {			\
-  long __res;										\
-  __asm__ __volatile__ (								\
-  "mov\tr0,%1\n\t"									\
-  "mov\tr1,%2\n\t"									\
-  "mov\tr2,%3\n\t"									\
-  "mov\tr3,%4\n\t"									\
-  "mov\tr4,%5\n\t"									\
-  __syscall(name)									\
-  "mov\t%0,r0"										\
-  	: "=r" (__res)									\
-  	: "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)),	\
-	  "r" ((long)(arg5))								\
-	: "r0","r1","r2","r3","r4","lr");						\
-  __syscall_return(type,__res);								\
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
+  register long __r0 __asm__("r0") = (long)arg1;			\
+  register long __r1 __asm__("r1") = (long)arg2;			\
+  register long __r2 __asm__("r2") = (long)arg3;			\
+  register long __r3 __asm__("r3") = (long)arg4;			\
+  register long __r4 __asm__("r4") = (long)arg5;			\
+  register long __res __asm__("r0");					\
+  __asm__ __volatile__ (						\
+  __syscall(name)							\
+	: "=r" (__res)							\
+	: "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3),"r" (__r4)	\
+	: "lr");							\
+  __syscall_return(type,__res); 					\
+}
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6)	\
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) {	\
+  register long __r0 __asm__("r0") = (long)arg1;			\
+  register long __r1 __asm__("r1") = (long)arg2;			\
+  register long __r2 __asm__("r2") = (long)arg3;			\
+  register long __r3 __asm__("r3") = (long)arg4;			\
+  register long __r4 __asm__("r4") = (long)arg5;			\
+  register long __r5 __asm__("r5") = (long)arg6;			\
+  register long __res __asm__("r0");					\
+  __asm__ __volatile__ (						\
+  __syscall(name)							\
+	: "=r" (__res)							\
+	: "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3),"r" (__r4),"r" (__r5)		\
+	: "lr");							\
+  __syscall_return(type,__res); 					\
 }
 
 #ifdef __KERNEL_SYSCALLS__
diff -urN linux-2.4.22-pre2/include/asm-i386/apicdef.h linux-2.4.22-pre3/include/asm-i386/apicdef.h
--- linux-2.4.22-pre2/include/asm-i386/apicdef.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-i386/apicdef.h	2003-07-05 18:11:14.000000000 -0700
@@ -18,6 +18,7 @@
 #define			GET_APIC_VERSION(x)	((x)&0xFF)
 #define			GET_APIC_MAXLVT(x)	(((x)>>16)&0xFF)
 #define			APIC_INTEGRATED(x)	((x)&0xF0)
+#define			APIC_XAPIC_SUPPORT(x)	((x)>=0x14)
 #define		APIC_TASKPRI	0x80
 #define			APIC_TPRI_MASK		0xFF
 #define		APIC_ARBPRI	0x90
diff -urN linux-2.4.22-pre2/include/asm-i386/cpufeature.h linux-2.4.22-pre3/include/asm-i386/cpufeature.h
--- linux-2.4.22-pre2/include/asm-i386/cpufeature.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-i386/cpufeature.h	2003-07-05 18:11:14.000000000 -0700
@@ -64,8 +64,33 @@
 #define X86_FEATURE_CYRIX_ARR	(3*32+ 2) /* Cyrix ARRs (= MTRRs) */
 #define X86_FEATURE_CENTAUR_MCR	(3*32+ 3) /* Centaur MCRs (= MTRRs) */
 
+/* Intel defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+#define X86_FEATURE_EST		(4*32+ 7) /* Enhanced SpeedStep */
+
 #define cpu_has(c, bit)            test_bit(bit, (c)->x86_capability)
 
+
+#define cpu_has(c, bit)		test_bit(bit, (c)->x86_capability)
+#define boot_cpu_has(bit)	test_bit(bit, boot_cpu_data.x86_capability)
+
+#define cpu_has_fpu		boot_cpu_has(X86_FEATURE_FPU)
+#define cpu_has_vme		boot_cpu_has(X86_FEATURE_VME)
+#define cpu_has_de		boot_cpu_has(X86_FEATURE_DE)
+#define cpu_has_pse		boot_cpu_has(X86_FEATURE_PSE)
+#define cpu_has_tsc		boot_cpu_has(X86_FEATURE_TSC)
+#define cpu_has_pae		boot_cpu_has(X86_FEATURE_PAE)
+#define cpu_has_pge		boot_cpu_has(X86_FEATURE_PGE)
+#define cpu_has_apic		boot_cpu_has(X86_FEATURE_APIC)
+#define cpu_has_mtrr		boot_cpu_has(X86_FEATURE_MTRR)
+#define cpu_has_mmx		boot_cpu_has(X86_FEATURE_MMX)
+#define cpu_has_fxsr		boot_cpu_has(X86_FEATURE_FXSR)
+#define cpu_has_xmm		boot_cpu_has(X86_FEATURE_XMM)
+#define cpu_has_ht		boot_cpu_has(X86_FEATURE_HT)
+#define cpu_has_mp		boot_cpu_has(X86_FEATURE_MP)
+#define cpu_has_k6_mtrr		boot_cpu_has(X86_FEATURE_K6_MTRR)
+#define cpu_has_cyrix_arr	boot_cpu_has(X86_FEATURE_CYRIX_ARR)
+#define cpu_has_centaur_mcr	boot_cpu_has(X86_FEATURE_CENTAUR_MCR)
+
 #endif /* __ASM_I386_CPUFEATURE_H */
 
 /* 
diff -urN linux-2.4.22-pre2/include/asm-i386/io_apic.h linux-2.4.22-pre3/include/asm-i386/io_apic.h
--- linux-2.4.22-pre2/include/asm-i386/io_apic.h	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-i386/io_apic.h	2003-07-05 18:11:14.000000000 -0700
@@ -123,15 +123,6 @@
 }
 
 /*
- * Re-write a value: to be used for read-modify-write
- * cycles where the read already set up the index register.
- */
-static inline void io_apic_modify(unsigned int apic, unsigned int value)
-{
-	*(IO_APIC_BASE(apic)+4) = value;
-}
-
-/*
  * Synchronize the IO-APIC and the CPU by doing
  * a dummy read from the IO-APIC
  */
diff -urN linux-2.4.22-pre2/include/asm-i386/ipc.h linux-2.4.22-pre3/include/asm-i386/ipc.h
--- linux-2.4.22-pre2/include/asm-i386/ipc.h	1998-12-31 12:05:12.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-i386/ipc.h	2003-07-05 18:11:14.000000000 -0700
@@ -14,6 +14,7 @@
 #define SEMOP		 1
 #define SEMGET		 2
 #define SEMCTL		 3
+#define SEMTIMEDOP	 4
 #define MSGSND		11
 #define MSGRCV		12
 #define MSGGET		13
diff -urN linux-2.4.22-pre2/include/asm-i386/kmap_types.h linux-2.4.22-pre3/include/asm-i386/kmap_types.h
--- linux-2.4.22-pre2/include/asm-i386/kmap_types.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-i386/kmap_types.h	2003-07-05 18:11:14.000000000 -0700
@@ -8,6 +8,8 @@
 	KM_USER0,
 	KM_USER1,
 	KM_BH_IRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff -urN linux-2.4.22-pre2/include/asm-i386/msr.h linux-2.4.22-pre3/include/asm-i386/msr.h
--- linux-2.4.22-pre2/include/asm-i386/msr.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-i386/msr.h	2003-07-05 18:11:14.000000000 -0700
@@ -75,6 +75,9 @@
 #define MSR_P6_EVNTSEL0			0x186
 #define MSR_P6_EVNTSEL1			0x187
 
+#define MSR_IA32_PERF_STATUS		0x198
+#define MSR_IA32_PERF_CTL		0x199
+
 /* AMD Defined MSRs */
 #define MSR_K6_EFER			0xC0000080
 #define MSR_K6_STAR			0xC0000081
diff -urN linux-2.4.22-pre2/include/asm-i386/pgalloc.h linux-2.4.22-pre3/include/asm-i386/pgalloc.h
--- linux-2.4.22-pre2/include/asm-i386/pgalloc.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-i386/pgalloc.h	2003-07-05 18:11:14.000000000 -0700
@@ -224,7 +224,7 @@
 {
 	struct mm_struct *active_mm;
 	int state;
-};
+} ____cacheline_aligned;
 extern struct tlb_state cpu_tlbstate[NR_CPUS];
 
 #endif /* CONFIG_SMP */
diff -urN linux-2.4.22-pre2/include/asm-i386/processor.h linux-2.4.22-pre3/include/asm-i386/processor.h
--- linux-2.4.22-pre2/include/asm-i386/processor.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-i386/processor.h	2003-07-05 18:11:14.000000000 -0700
@@ -82,17 +82,6 @@
 #define current_cpu_data boot_cpu_data
 #endif
 
-#define cpu_has_pge	(test_bit(X86_FEATURE_PGE,  boot_cpu_data.x86_capability))
-#define cpu_has_pse	(test_bit(X86_FEATURE_PSE,  boot_cpu_data.x86_capability))
-#define cpu_has_pae	(test_bit(X86_FEATURE_PAE,  boot_cpu_data.x86_capability))
-#define cpu_has_tsc	(test_bit(X86_FEATURE_TSC,  boot_cpu_data.x86_capability))
-#define cpu_has_de	(test_bit(X86_FEATURE_DE,   boot_cpu_data.x86_capability))
-#define cpu_has_vme	(test_bit(X86_FEATURE_VME,  boot_cpu_data.x86_capability))
-#define cpu_has_fxsr	(test_bit(X86_FEATURE_FXSR, boot_cpu_data.x86_capability))
-#define cpu_has_xmm	(test_bit(X86_FEATURE_XMM,  boot_cpu_data.x86_capability))
-#define cpu_has_fpu	(test_bit(X86_FEATURE_FPU,  boot_cpu_data.x86_capability))
-#define cpu_has_apic	(test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability))
-
 extern char ignore_irq13;
 
 extern void identify_cpu(struct cpuinfo_x86 *);
diff -urN linux-2.4.22-pre2/include/asm-i386/system.h linux-2.4.22-pre3/include/asm-i386/system.h
--- linux-2.4.22-pre2/include/asm-i386/system.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-i386/system.h	2003-07-05 18:11:15.000000000 -0700
@@ -375,5 +375,6 @@
 
 #define BROKEN_ACPI_Sx		0x0001
 #define BROKEN_INIT_AFTER_S1	0x0002
+#define BROKEN_PNP_BIOS		0x0004
 
 #endif
diff -urN linux-2.4.22-pre2/include/asm-ia64/atomic.h linux-2.4.22-pre3/include/asm-ia64/atomic.h
--- linux-2.4.22-pre2/include/asm-ia64/atomic.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ia64/atomic.h	2003-07-05 18:11:15.000000000 -0700
@@ -14,7 +14,7 @@
  */
 #include <linux/types.h>
 
-#include <asm/system.h>
+#include <asm/intrinsics.h>
 
 /*
  * On IA-64, counter must always be volatile to ensure that that the
diff -urN linux-2.4.22-pre2/include/asm-ia64/bitops.h linux-2.4.22-pre3/include/asm-ia64/bitops.h
--- linux-2.4.22-pre2/include/asm-ia64/bitops.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/bitops.h	2003-07-05 18:11:15.000000000 -0700
@@ -6,7 +6,9 @@
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
-#include <asm/system.h>
+#include <linux/types.h>
+
+#include <asm/intrinsics.h>
 
 /**
  * set_bit - Atomically set a bit in memory
@@ -258,7 +260,7 @@
 }
 
 static __inline__ int
-test_bit (int nr, volatile void *addr)
+test_bit (int nr, const volatile void *addr)
 {
 	return 1 & (((const volatile __u32 *) addr)[nr >> 5] >> (nr & 31));
 }
diff -urN linux-2.4.22-pre2/include/asm-ia64/fpu.h linux-2.4.22-pre3/include/asm-ia64/fpu.h
--- linux-2.4.22-pre2/include/asm-ia64/fpu.h	2000-02-06 18:42:40.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ia64/fpu.h	2003-07-05 18:11:15.000000000 -0700
@@ -2,8 +2,8 @@
 #define _ASM_IA64_FPU_H
 
 /*
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998, 1999, 2002, 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <asm/types.h>
@@ -57,8 +57,9 @@
 struct ia64_fpreg {
 	union {
 		unsigned long bits[2];
+		long double __dummy;	/* force 16-byte alignment */
 	} u;
-} __attribute__ ((aligned (16)));
+};
 
 # endif /* __ASSEMBLY__ */
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/ia32.h linux-2.4.22-pre3/include/asm-ia64/ia32.h
--- linux-2.4.22-pre2/include/asm-ia64/ia32.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/ia32.h	2003-07-05 18:11:15.000000000 -0700
@@ -149,7 +149,8 @@
 	int	fcs;
 	int	foo;
 	int	fos;
-	int	st_space[20];	/* 8*10 bytes for each FP-reg = 80 bytes */
+	/* 8*10 bytes for each FP-reg = 80 bytes */
+	struct _fpreg_ia32 	st_space[8];
 };
 
 struct ia32_user_fxsr_struct {
diff -urN linux-2.4.22-pre2/include/asm-ia64/intrinsics.h linux-2.4.22-pre3/include/asm-ia64/intrinsics.h
--- linux-2.4.22-pre2/include/asm-ia64/intrinsics.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ia64/intrinsics.h	2003-07-05 18:11:15.000000000 -0700
@@ -0,0 +1,186 @@
+#ifndef _ASM_IA64_INTRINSICS_H
+#define _ASM_IA64_INTRINSICS_H
+
+/*
+ * Compiler-dependent intrinsics.
+ *
+ * Copyright (C) 2002-2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+#include <linux/config.h>
+
+/*
+ * Force an unresolved reference if someone tries to use
+ * ia64_fetch_and_add() with a bad value.
+ */
+extern unsigned long __bad_size_for_ia64_fetch_and_add (void);
+extern unsigned long __bad_increment_for_ia64_fetch_and_add (void);
+
+#define IA64_FETCHADD(tmp,v,n,sz)						\
+({										\
+	switch (sz) {								\
+	      case 4:								\
+		__asm__ __volatile__ ("fetchadd4.rel %0=[%1],%2"		\
+				      : "=r"(tmp) : "r"(v), "i"(n) : "memory");	\
+		break;								\
+										\
+	      case 8:								\
+		__asm__ __volatile__ ("fetchadd8.rel %0=[%1],%2"		\
+				      : "=r"(tmp) : "r"(v), "i"(n) : "memory");	\
+		break;								\
+										\
+	      default:								\
+		__bad_size_for_ia64_fetch_and_add();				\
+	}									\
+})
+
+#define ia64_fetch_and_add(i,v)								\
+({											\
+	__u64 _tmp;									\
+	volatile __typeof__(*(v)) *_v = (v);						\
+	/* Can't use a switch () here: gcc isn't always smart enough for that... */	\
+	if ((i) == -16)									\
+		IA64_FETCHADD(_tmp, _v, -16, sizeof(*(v)));				\
+	else if ((i) == -8)								\
+		IA64_FETCHADD(_tmp, _v, -8, sizeof(*(v)));				\
+	else if ((i) == -4)								\
+		IA64_FETCHADD(_tmp, _v, -4, sizeof(*(v)));				\
+	else if ((i) == -2)								\
+		IA64_FETCHADD(_tmp, _v, -2, sizeof(*(v)));				\
+	else if ((i) == -1)								\
+		IA64_FETCHADD(_tmp, _v, -1, sizeof(*(v)));				\
+	else if ((i) == 1)								\
+		IA64_FETCHADD(_tmp, _v, 1, sizeof(*(v)));				\
+	else if ((i) == 2)								\
+		IA64_FETCHADD(_tmp, _v, 2, sizeof(*(v)));				\
+	else if ((i) == 4)								\
+		IA64_FETCHADD(_tmp, _v, 4, sizeof(*(v)));				\
+	else if ((i) == 8)								\
+		IA64_FETCHADD(_tmp, _v, 8, sizeof(*(v)));				\
+	else if ((i) == 16)								\
+		IA64_FETCHADD(_tmp, _v, 16, sizeof(*(v)));				\
+	else										\
+		_tmp = __bad_increment_for_ia64_fetch_and_add();			\
+	(__typeof__(*(v))) (_tmp + (i));	/* return new value */			\
+})
+
+/*
+ * This function doesn't exist, so you'll get a linker error if
+ * something tries to do an invalid xchg().
+ */
+extern void __xchg_called_with_bad_pointer (void);
+
+static __inline__ unsigned long
+__xchg (unsigned long x, volatile void *ptr, int size)
+{
+	unsigned long result;
+
+	switch (size) {
+	      case 1:
+		__asm__ __volatile ("xchg1 %0=[%1],%2" : "=r" (result)
+				    : "r" (ptr), "r" (x) : "memory");
+		return result;
+
+	      case 2:
+		__asm__ __volatile ("xchg2 %0=[%1],%2" : "=r" (result)
+				    : "r" (ptr), "r" (x) : "memory");
+		return result;
+
+	      case 4:
+		__asm__ __volatile ("xchg4 %0=[%1],%2" : "=r" (result)
+				    : "r" (ptr), "r" (x) : "memory");
+		return result;
+
+	      case 8:
+		__asm__ __volatile ("xchg8 %0=[%1],%2" : "=r" (result)
+				    : "r" (ptr), "r" (x) : "memory");
+		return result;
+	}
+	__xchg_called_with_bad_pointer();
+	return x;
+}
+
+#define xchg(ptr,x)							     \
+  ((__typeof__(*(ptr))) __xchg ((unsigned long) (x), (ptr), sizeof(*(ptr))))
+
+/*
+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
+ * store NEW in MEM.  Return the initial value in MEM.  Success is
+ * indicated by comparing RETURN with OLD.
+ */
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid cmpxchg().
+ */
+extern long __cmpxchg_called_with_bad_pointer(void);
+
+#define ia64_cmpxchg(sem,ptr,old,new,size)						\
+({											\
+	__typeof__(ptr) _p_ = (ptr);							\
+	__typeof__(new) _n_ = (new);							\
+	__u64 _o_, _r_;									\
+											\
+	switch (size) {									\
+	      case 1: _o_ = (__u8 ) (long) (old); break;				\
+	      case 2: _o_ = (__u16) (long) (old); break;				\
+	      case 4: _o_ = (__u32) (long) (old); break;				\
+	      case 8: _o_ = (__u64) (long) (old); break;				\
+	      default: break;								\
+	}										\
+	 __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(_o_));				\
+	switch (size) {									\
+	      case 1:									\
+		__asm__ __volatile__ ("cmpxchg1."sem" %0=[%1],%2,ar.ccv"		\
+				      : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");	\
+		break;									\
+											\
+	      case 2:									\
+		__asm__ __volatile__ ("cmpxchg2."sem" %0=[%1],%2,ar.ccv"		\
+				      : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");	\
+		break;									\
+											\
+	      case 4:									\
+		__asm__ __volatile__ ("cmpxchg4."sem" %0=[%1],%2,ar.ccv"		\
+				      : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");	\
+		break;									\
+											\
+	      case 8:									\
+		__asm__ __volatile__ ("cmpxchg8."sem" %0=[%1],%2,ar.ccv"		\
+				      : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");	\
+		break;									\
+											\
+	      default:									\
+		_r_ = __cmpxchg_called_with_bad_pointer();				\
+		break;									\
+	}										\
+	(__typeof__(old)) _r_;								\
+})
+
+#define cmpxchg_acq(ptr,o,n)	ia64_cmpxchg("acq", (ptr), (o), (n), sizeof(*(ptr)))
+#define cmpxchg_rel(ptr,o,n)	ia64_cmpxchg("rel", (ptr), (o), (n), sizeof(*(ptr)))
+
+/* for compatibility with other platforms: */
+#define cmpxchg(ptr,o,n)	cmpxchg_acq(ptr,o,n)
+
+#ifdef CONFIG_IA64_DEBUG_CMPXCHG
+# define CMPXCHG_BUGCHECK_DECL	int _cmpxchg_bugcheck_count = 128;
+# define CMPXCHG_BUGCHECK(v)							\
+  do {										\
+	if (_cmpxchg_bugcheck_count-- <= 0) {					\
+		void *ip;							\
+		extern int printk(const char *fmt, ...);			\
+		asm ("mov %0=ip" : "=r"(ip));					\
+		printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v));	\
+		break;								\
+	}									\
+  } while (0)
+#else /* !CONFIG_IA64_DEBUG_CMPXCHG */
+# define CMPXCHG_BUGCHECK_DECL
+# define CMPXCHG_BUGCHECK(v)
+#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
+
+#endif /* _ASM_IA64_INTRINSICS_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/iosapic.h linux-2.4.22-pre3/include/asm-ia64/iosapic.h
--- linux-2.4.22-pre2/include/asm-ia64/iosapic.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ia64/iosapic.h	2003-07-05 18:11:15.000000000 -0700
@@ -51,24 +51,21 @@
 
 #ifndef __ASSEMBLY__
 
-extern void __devinit iosapic_init (unsigned long address,
-				    unsigned int gsi_base,
-				    int pcat_compat);
+extern void __init iosapic_system_init (int pcat_compat);
+extern void __init iosapic_init (unsigned long address,
+				    unsigned int gsi_base);
 extern int gsi_to_vector (unsigned int gsi);
 extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
-				  unsigned long edge_triggered,
-				  u32 gsi_base, char *iosapic_address);
-extern void iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
+				  unsigned long trigger);
+extern void __init iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
 				      unsigned long polarity,
-				      unsigned long edge_triggered);
-extern int iosapic_register_platform_intr (u32 int_type,
+				      unsigned long trigger);
+extern int __init iosapic_register_platform_intr (u32 int_type,
 					   unsigned int gsi,
 					   int pmi_vector,
 					   u16 eid, u16 id,
 					   unsigned long polarity,
-					   unsigned long edge_triggered,
-					   unsigned int gsi_base,
-					   char *iosapic_address);
+					   unsigned long trigger);
 extern unsigned int iosapic_version (char *addr);
 
 extern void iosapic_pci_fixup (int);
diff -urN linux-2.4.22-pre2/include/asm-ia64/machvec_init.h linux-2.4.22-pre3/include/asm-ia64/machvec_init.h
--- linux-2.4.22-pre2/include/asm-ia64/machvec_init.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ia64/machvec_init.h	2003-07-05 18:11:15.000000000 -0700
@@ -1,7 +1,3 @@
-#define __MACHVEC_HDR(n)		<asm/machvec_##n##.h>
-#define __MACHVEC_EXPAND(n)		__MACHVEC_HDR(n)
-#define MACHVEC_PLATFORM_HEADER		__MACHVEC_EXPAND(MACHVEC_PLATFORM_NAME)
-
 #include <asm/machvec.h>
 
 extern ia64_mv_send_ipi_t ia64_send_ipi;
diff -urN linux-2.4.22-pre2/include/asm-ia64/machvec_sn1.h linux-2.4.22-pre3/include/asm-ia64/machvec_sn1.h
--- linux-2.4.22-pre2/include/asm-ia64/machvec_sn1.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/machvec_sn1.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#ifndef _ASM_IA64_MACHVEC_SN1_h
-#define _ASM_IA64_MACHVEC_SN1_h
-
-extern ia64_mv_setup_t sn_setup;
-extern ia64_mv_cpu_init_t sn_cpu_init;
-extern ia64_mv_irq_init_t sn_irq_init;
-extern ia64_mv_map_nr_t sn1_map_nr;
-extern ia64_mv_send_ipi_t sn1_send_IPI;
-extern ia64_mv_global_tlb_purge_t sn1_global_tlb_purge;
-extern ia64_mv_irq_desc sn_irq_desc;
-extern ia64_mv_irq_to_vector sn_irq_to_vector;
-extern ia64_mv_local_vector_to_irq sn_local_vector_to_irq;
-extern ia64_mv_pci_fixup_t sn_pci_fixup;
-extern ia64_mv_inb_t sn_inb;
-extern ia64_mv_inw_t sn_inw;
-extern ia64_mv_inl_t sn_inl;
-extern ia64_mv_outb_t sn_outb;
-extern ia64_mv_outw_t sn_outw;
-extern ia64_mv_outl_t sn_outl;
-extern ia64_mv_pci_alloc_consistent	sn_pci_alloc_consistent;
-extern ia64_mv_pci_free_consistent	sn_pci_free_consistent;
-extern ia64_mv_pci_map_single		sn_pci_map_single;
-extern ia64_mv_pci_unmap_single		sn_pci_unmap_single;
-extern ia64_mv_pci_map_sg		sn_pci_map_sg;
-extern ia64_mv_pci_unmap_sg		sn_pci_unmap_sg;
-extern ia64_mv_pci_dma_sync_single	sn_pci_dma_sync_single;
-extern ia64_mv_pci_dma_sync_sg		sn_pci_dma_sync_sg;
-extern ia64_mv_pci_dma_supported	sn_pci_dma_supported;
-
-/*
- * This stuff has dual use!
- *
- * For a generic kernel, the macros are used to initialize the
- * platform's machvec structure.  When compiling a non-generic kernel,
- * the macros are used directly.
- */
-#define platform_name			"sn1"
-#define platform_setup			sn_setup
-#define platform_cpu_init		sn_cpu_init
-#define platform_irq_init		sn_irq_init
-#define platform_map_nr			sn_map_nr
-#define platform_send_ipi		sn1_send_IPI
-#define platform_global_tlb_purge       sn1_global_tlb_purge
-#define platform_pci_fixup		sn_pci_fixup
-#define platform_inb			sn_inb
-#define platform_inw			sn_inw
-#define platform_inl			sn_inl
-#define platform_outb			sn_outb
-#define platform_outw			sn_outw
-#define platform_outl			sn_outl
-#define platform_irq_desc		sn_irq_desc
-#define platform_irq_to_vector		sn_irq_to_vector
-#define platform_local_vector_to_irq	sn_local_vector_to_irq
-#define platform_pci_dma_init		machvec_noop
-#define platform_pci_alloc_consistent	sn_pci_alloc_consistent
-#define platform_pci_free_consistent	sn_pci_free_consistent
-#define platform_pci_map_single		sn_pci_map_single
-#define platform_pci_unmap_single	sn_pci_unmap_single
-#define platform_pci_map_sg		sn_pci_map_sg
-#define platform_pci_unmap_sg		sn_pci_unmap_sg
-#define platform_pci_dma_sync_single	sn_pci_dma_sync_single
-#define platform_pci_dma_sync_sg	sn_pci_dma_sync_sg
-#define platform_pci_dma_supported	sn_pci_dma_supported
-
-#endif /* _ASM_IA64_MACHVEC_SN1_h */
diff -urN linux-2.4.22-pre2/include/asm-ia64/machvec_sn2.h linux-2.4.22-pre3/include/asm-ia64/machvec_sn2.h
--- linux-2.4.22-pre2/include/asm-ia64/machvec_sn2.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/machvec_sn2.h	2003-07-05 18:11:15.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -33,22 +33,17 @@
 #ifndef _ASM_IA64_MACHVEC_SN2_H
 #define _ASM_IA64_MACHVEC_SN2_H
 
-extern ia64_mv_setup_t sn_setup;
-extern ia64_mv_cpu_init_t sn_cpu_init;
-extern ia64_mv_irq_init_t sn_irq_init;
-extern ia64_mv_map_nr_t sn2_map_nr;
-extern ia64_mv_send_ipi_t sn2_send_IPI;
-extern ia64_mv_global_tlb_purge_t sn2_global_tlb_purge;
-extern ia64_mv_irq_desc sn_irq_desc;
-extern ia64_mv_irq_to_vector sn_irq_to_vector;
-extern ia64_mv_local_vector_to_irq sn_local_vector_to_irq;
-extern ia64_mv_pci_fixup_t sn_pci_fixup;
-extern ia64_mv_inb_t sn_inb;
-extern ia64_mv_inw_t sn_inw;
-extern ia64_mv_inl_t sn_inl;
-extern ia64_mv_outb_t sn_outb;
-extern ia64_mv_outw_t sn_outw;
-extern ia64_mv_outl_t sn_outl;
+#include <asm/sn/sn2/io.h>
+
+extern ia64_mv_setup_t			sn_setup;
+extern ia64_mv_cpu_init_t		sn_cpu_init;
+extern ia64_mv_irq_init_t		sn_irq_init;
+extern ia64_mv_send_ipi_t		sn2_send_IPI;
+extern ia64_mv_global_tlb_purge_t	sn2_global_tlb_purge;
+extern ia64_mv_irq_desc			sn_irq_desc;
+extern ia64_mv_irq_to_vector		sn_irq_to_vector;
+extern ia64_mv_local_vector_to_irq	sn_local_vector_to_irq;
+extern ia64_mv_pci_fixup_t		sn_pci_fixup;
 extern ia64_mv_pci_alloc_consistent	sn_pci_alloc_consistent;
 extern ia64_mv_pci_free_consistent	sn_pci_free_consistent;
 extern ia64_mv_pci_map_single		sn_pci_map_single;
@@ -70,16 +65,19 @@
 #define platform_setup			sn_setup
 #define platform_cpu_init		sn_cpu_init
 #define platform_irq_init		sn_irq_init
-#define platform_map_nr			sn2_map_nr
 #define platform_send_ipi		sn2_send_IPI
 #define platform_global_tlb_purge       sn2_global_tlb_purge
 #define platform_pci_fixup		sn_pci_fixup
-#define platform_inb			sn_inb
-#define platform_inw			sn_inw
-#define platform_inl			sn_inl
-#define platform_outb			sn_outb
-#define platform_outw			sn_outw
-#define platform_outl			sn_outl
+#define platform_inb			__sn_inb
+#define platform_inw			__sn_inw
+#define platform_inl			__sn_inl
+#define platform_outb			__sn_outb
+#define platform_outw			__sn_outw
+#define platform_outl			__sn_outl
+#define platform_readb			__sn_readb
+#define platform_readw			__sn_readw
+#define platform_readl			__sn_readl
+#define platform_readq			__sn_readq
 #define platform_irq_desc		sn_irq_desc
 #define platform_irq_to_vector		sn_irq_to_vector
 #define platform_local_vector_to_irq	sn_local_vector_to_irq
diff -urN linux-2.4.22-pre2/include/asm-ia64/mca.h linux-2.4.22-pre3/include/asm-ia64/mca.h
--- linux-2.4.22-pre2/include/asm-ia64/mca.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/mca.h	2003-07-05 18:11:15.000000000 -0700
@@ -24,7 +24,7 @@
 	IA64_MCA_FAILURE	=	1
 };
 
-#define IA64_MCA_RENDEZ_TIMEOUT		(100 * HZ)	/* 1000 milliseconds */
+#define IA64_MCA_RENDEZ_TIMEOUT		(20 * 1000)	/* value in milliseconds - 20 seconds */
 
 #define IA64_CMC_INT_DISABLE		0
 #define IA64_CMC_INT_ENABLE		1
@@ -135,7 +135,7 @@
 extern void ia64_mca_cpe_int_handler(int,void *,struct pt_regs *);
 extern int  ia64_log_print(int,prfunc_t);
 extern void ia64_mca_cmc_vector_setup(void);
-extern void ia64_mca_check_errors( void );
+extern int  ia64_mca_check_errors(void);
 extern u64  ia64_log_get(int, prfunc_t);
 
 #define PLATFORM_CALL(fn, args)	printk("Platform call TBD\n")
diff -urN linux-2.4.22-pre2/include/asm-ia64/mmu_context.h linux-2.4.22-pre3/include/asm-ia64/mmu_context.h
--- linux-2.4.22-pre2/include/asm-ia64/mmu_context.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/mmu_context.h	2003-07-05 18:11:15.000000000 -0700
@@ -2,8 +2,8 @@
 #define _ASM_IA64_MMU_CONTEXT_H
 
 /*
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 /*
@@ -13,8 +13,6 @@
  * consider the region number when performing a TLB lookup, we need to assign a unique
  * region id to each region in a process.  We use the least significant three bits in a
  * region id for this purpose.
- *
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #define IA64_REGION_ID_KERNEL	0 /* the kernel's region id (tlb.c depends on this being 0) */
@@ -44,6 +42,23 @@
 {
 }
 
+/*
+ * When the context counter wraps around all TLBs need to be flushed because an old
+ * context number might have been reused. This is signalled by the ia64_need_tlb_flush
+ * per-CPU variable, which is checked in the routine below. Called by activate_mm().
+ * <efocht@ess.nec.de>
+ */
+static inline void
+delayed_tlb_flush (void)
+{
+	extern void local_flush_tlb_all (void);
+
+	if (unlikely(local_cpu_data->need_tlb_flush)) {
+		local_flush_tlb_all();
+		local_cpu_data->need_tlb_flush = 0;
+	}
+}
+
 static inline mm_context_t
 get_mmu_context (struct mm_struct *mm)
 {
@@ -127,6 +142,8 @@
 static inline void
 activate_mm (struct mm_struct *prev, struct mm_struct *next)
 {
+	delayed_tlb_flush();
+
 	/*
 	 * We may get interrupts here, but that's OK because interrupt handlers cannot
 	 * touch user-space.
diff -urN linux-2.4.22-pre2/include/asm-ia64/pal.h linux-2.4.22-pre3/include/asm-ia64/pal.h
--- linux-2.4.22-pre2/include/asm-ia64/pal.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/pal.h	2003-07-05 18:11:15.000000000 -0700
@@ -1,6 +1,8 @@
 #ifndef _ASM_IA64_PAL_H
 #define _ASM_IA64_PAL_H
 
+#ifdef __KERNEL__
+
 /*
  * Processor Abstraction Layer definitions.
  *
@@ -622,7 +624,8 @@
 	u64	pmsa_xip;		/* previous iip		   */
 	u64	pmsa_xpsr;		/* previous psr		   */
 	u64	pmsa_xfs;		/* previous ifs		   */
-	u64	pmsa_reserved[71];	/* pal_min_state_area should total to 1KB */
+	u64	pmsa_br1;		/* branch register 1	   */
+	u64	pmsa_reserved[70];	/* pal_min_state_area should total to 1KB */
 } pal_min_state_area_t;
 
 
@@ -1435,4 +1438,6 @@
 
 #endif /* __ASSEMBLY__ */
 
+#endif /* __KERNEL__ */
+
 #endif /* _ASM_IA64_PAL_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/pci.h linux-2.4.22-pre3/include/asm-ia64/pci.h
--- linux-2.4.22-pre2/include/asm-ia64/pci.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/pci.h	2003-07-05 18:11:15.000000000 -0700
@@ -45,6 +45,9 @@
 	/* We don't do dynamic PCI IRQ allocation */
 }
 
+#define HAVE_ARCH_PCI_MWI 1
+extern int pcibios_set_mwi (struct pci_dev *);
+
 /*
  * Dynamic DMA mapping API.  See Documentation/DMA-mapping.txt for details.
  */
diff -urN linux-2.4.22-pre2/include/asm-ia64/perfmon.h linux-2.4.22-pre3/include/asm-ia64/perfmon.h
--- linux-2.4.22-pre2/include/asm-ia64/perfmon.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/perfmon.h	2003-07-05 18:11:15.000000000 -0700
@@ -41,6 +41,7 @@
 #define PFM_FL_NOTIFY_BLOCK    	 0x04	/* block task on user level notifications */
 #define PFM_FL_SYSTEM_WIDE	 0x08	/* create a system wide context */
 #define PFM_FL_EXCL_IDLE         0x20   /* exclude idle task from system wide session */
+#define PFM_FL_UNSECURE		 0x40   /* allow unsecure monitoring for non self-monitoring task */
 
 /*
  * PMC flags
@@ -150,7 +151,7 @@
  * Define the version numbers for both perfmon as a whole and the sampling buffer format.
  */
 #define PFM_VERSION_MAJ		1U
-#define PFM_VERSION_MIN		3U
+#define PFM_VERSION_MIN		5U
 #define PFM_VERSION		(((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff))
 
 #define PFM_SMPL_VERSION_MAJ	1U
@@ -198,6 +199,12 @@
 #define PFM_CPUINFO_DCR_PP	0x2	/* if set a system wide session started on the CPU */
 #define PFM_CPUINFO_EXCL_IDLE	0x4	/* system wide session excludes the idle task */
 
+/*
+ * macros to set the specific perfmon bits in each CPU's private data area
+ */
+#define PFM_CPUINFO_CLEAR(v)	local_cpu_data->pfm_syst_info &= ~(v)
+#define PFM_CPUINFO_SET(v)	local_cpu_data->pfm_syst_info |= (v)
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_IA64_PERFMON_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/processor.h linux-2.4.22-pre3/include/asm-ia64/processor.h
--- linux-2.4.22-pre2/include/asm-ia64/processor.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/processor.h	2003-07-05 18:11:15.000000000 -0700
@@ -157,6 +157,7 @@
 	__u8 family;
 	__u8 archrev;
 	char vendor[16];
+	__u8 need_tlb_flush;
 	__u64 itc_freq;		/* frequency of ITC counter */
 	__u64 proc_freq;	/* frequency of processor */
 	__u64 cyc_per_usec;	/* itc_freq/1000000 */
@@ -300,12 +301,13 @@
 	INIT_THREAD_PM					\
 	{0, },				/* dbr */	\
 	{0, },				/* ibr */	\
-	{{{{0}}}, }			/* fph */	\
+	{{{{0}}}, },			/* fph */	\
+	-1				/* last_fph_cpu*/	\
 }
 
 #define start_thread(regs,new_ip,new_sp) do {							\
 	set_fs(USER_DS);									\
-	regs->cr_ipsr = ((regs->cr_ipsr | (IA64_PSR_BITS_TO_SET | IA64_PSR_CPL | IA64_PSR_SP))	\
+	regs->cr_ipsr = ((regs->cr_ipsr | (IA64_PSR_BITS_TO_SET | IA64_PSR_CPL))		\
 			 & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_RI | IA64_PSR_IS));		\
 	regs->cr_iip = new_ip;									\
 	regs->ar_rsc = 0xf;		/* eager mode, privilege level 3 */			\
@@ -394,7 +396,7 @@
 static inline unsigned long
 ia64_get_kr (unsigned long regnum)
 {
-	unsigned long r;
+	unsigned long r = 0;
 
 	switch (regnum) {
 	      case 0: asm volatile ("mov %0=ar.k0" : "=r"(r)); break;
@@ -423,18 +425,23 @@
 	      case 7: asm volatile ("mov ar.k7=%0" :: "r"(r)); break;
 	}
 }
+/* Return TRUE if task T owns the fph partition of the CPU we're running on. */
+#define ia64_is_local_fpu_owner(t)								\
+({												\
+	struct task_struct *__ia64_islfo_task = (t);						\
+	(__ia64_islfo_task->thread.last_fph_cpu == smp_processor_id()				\
+	 && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER));	\
+})
 
-static inline struct task_struct *
-ia64_get_fpu_owner (void)
-{
-	return (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER);
-}
+/* Mark task T as owning the fph partition of the CPU we're running on. */
+#define ia64_set_local_fpu_owner(t) do {						\
+	struct task_struct *__ia64_slfo_task = (t);					\
+	__ia64_slfo_task->thread.last_fph_cpu = smp_processor_id();			\
+	ia64_set_kr(IA64_KR_FPU_OWNER, (unsigned long) __ia64_slfo_task);		\
+} while (0)
 
-static inline void
-ia64_set_fpu_owner (struct task_struct *t)
-{
-	ia64_set_kr(IA64_KR_FPU_OWNER, (unsigned long) t);
-}
+/* Mark the fph partition of task T as being invalid on all CPUs.  */
+#define ia64_drop_fpu(t)	((t)->thread.last_fph_cpu = -1)
 
 extern void __ia64_init_fpu (void);
 extern void __ia64_save_fpu (struct ia64_fpreg *fph);
diff -urN linux-2.4.22-pre2/include/asm-ia64/ptrace.h linux-2.4.22-pre3/include/asm-ia64/ptrace.h
--- linux-2.4.22-pre2/include/asm-ia64/ptrace.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/ptrace.h	2003-07-05 18:11:15.000000000 -0700
@@ -218,8 +218,10 @@
 # define user_mode(regs)		(((struct ia64_psr *) &(regs)->cr_ipsr)->cpl != 0)
 
   struct task_struct;			/* forward decl */
+  struct unw_frame_info;		/* forward decl */
 
   extern void show_regs (struct pt_regs *);
+  extern void ia64_do_show_stack (struct unw_frame_info *, void *);
   extern unsigned long ia64_get_user_rbs_end (struct task_struct *, struct pt_regs *,
 					      unsigned long *);
   extern long ia64_peek (struct task_struct *, struct switch_stack *, unsigned long,
diff -urN linux-2.4.22-pre2/include/asm-ia64/rwsem.h linux-2.4.22-pre3/include/asm-ia64/rwsem.h
--- linux-2.4.22-pre2/include/asm-ia64/rwsem.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ia64/rwsem.h	2003-07-05 18:11:15.000000000 -0700
@@ -0,0 +1,188 @@
+/*
+ * asm-ia64/rwsem.h: R/W semaphores for ia64
+ *
+ * Copyright (C) 2003 Ken Chen <kenneth.w.chen@intel.com>
+ * Copyright (C) 2003 Asit Mallick <asit.k.mallick@intel.com>
+ *
+ * Based on asm-i386/rwsem.h and other architecture implementation.
+ *
+ * The MSW of the count is the negated number of active writers and
+ * waiting lockers, and the LSW is the total number of active locks.
+ *
+ * The lock count is initialized to 0 (no active and no waiting lockers).
+ *
+ * When a writer subtracts WRITE_BIAS, it'll get 0xffff0001 for the case
+ * of an uncontended lock. Readers increment by 1 and see a positive value
+ * when uncontended, negative if there are writers (and maybe) readers
+ * waiting (in which case it goes to sleep).
+ */
+
+#ifndef _ASM_IA64_RWSEM_H
+#define _ASM_IA64_RWSEM_H
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+/*
+ * the semaphore definition
+ */
+struct rw_semaphore {
+	signed int		count;
+	spinlock_t		wait_lock;
+	struct list_head	wait_list;
+#if RWSEM_DEBUG
+	int			debug;
+#endif
+};
+
+#define RWSEM_UNLOCKED_VALUE		0x00000000
+#define RWSEM_ACTIVE_BIAS		0x00000001
+#define RWSEM_ACTIVE_MASK		0x0000ffff
+#define RWSEM_WAITING_BIAS		(-0x00010000)
+#define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+
+/*
+ * initialization
+ */
+#if RWSEM_DEBUG
+#define __RWSEM_DEBUG_INIT      , 0
+#else
+#define __RWSEM_DEBUG_INIT	/* */
+#endif
+
+#define __RWSEM_INITIALIZER(name) \
+	{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
+	  LIST_HEAD_INIT((name).wait_list) \
+	  __RWSEM_DEBUG_INIT }
+
+#define DECLARE_RWSEM(name) \
+	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+
+extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
+
+static inline void
+init_rwsem (struct rw_semaphore *sem)
+{
+	sem->count = RWSEM_UNLOCKED_VALUE;
+	spin_lock_init(&sem->wait_lock);
+	INIT_LIST_HEAD(&sem->wait_list);
+#if RWSEM_DEBUG
+	sem->debug = 0;
+#endif
+}
+
+/*
+ * lock for reading
+ */
+static inline void
+__down_read (struct rw_semaphore *sem)
+{
+	int result;
+	__asm__ __volatile__ ("fetchadd4.acq %0=[%1],1" :
+			      "=r"(result) : "r"(&sem->count) : "memory");
+	if (result < 0)
+		rwsem_down_read_failed(sem);
+}
+
+/*
+ * lock for writing
+ */
+static inline void
+__down_write (struct rw_semaphore *sem)
+{
+	int old, new;
+
+	do {
+		old = sem->count;
+		new = old + RWSEM_ACTIVE_WRITE_BIAS;
+	} while (cmpxchg_acq(&sem->count, old, new) != old);
+
+	if (old != 0)
+		rwsem_down_write_failed(sem);
+}
+
+/*
+ * unlock after reading
+ */
+static inline void
+__up_read (struct rw_semaphore *sem)
+{
+	int result;
+	__asm__ __volatile__ ("fetchadd4.rel %0=[%1],-1" :
+			      "=r"(result) : "r"(&sem->count) : "memory");
+	if (result < 0 && (--result & RWSEM_ACTIVE_MASK) == 0)
+		rwsem_wake(sem);
+}
+
+/*
+ * unlock after writing
+ */
+static inline void
+__up_write (struct rw_semaphore *sem)
+{
+	int old, new;
+
+	do {
+		old = sem->count;
+		new = old - RWSEM_ACTIVE_WRITE_BIAS;
+	} while (cmpxchg_rel(&sem->count, old, new) != old);
+
+	if (new < 0 && (new & RWSEM_ACTIVE_MASK) == 0)
+		rwsem_wake(sem);
+}
+
+/*
+ * trylock for reading -- returns 1 if successful, 0 if contention
+ */
+static inline int
+__down_read_trylock (struct rw_semaphore *sem)
+{
+	int tmp;
+	while ((tmp = sem->count) >= 0) {
+		if (tmp == cmpxchg_acq(&sem->count, tmp, tmp+1)) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * trylock for writing -- returns 1 if successful, 0 if contention
+ */
+static inline int
+__down_write_trylock (struct rw_semaphore *sem)
+{
+	int tmp = cmpxchg_acq(&sem->count, RWSEM_UNLOCKED_VALUE,
+			      RWSEM_ACTIVE_WRITE_BIAS);
+	return tmp == RWSEM_UNLOCKED_VALUE;
+}
+
+/*
+ * downgrade write lock to read lock
+ */
+static inline void
+__downgrade_write (struct rw_semaphore *sem)
+{
+	int old, new;
+
+	do {
+		old = sem->count;
+		new = old - RWSEM_WAITING_BIAS;
+	} while (cmpxchg_rel(&sem->count, old, new) != old);
+
+	if (old < 0)
+		rwsem_downgrade_wake(sem);
+}
+
+/*
+ * Implement atomic add functionality.  These used to be "inline" functions, but GCC v3.1
+ * doesn't quite optimize this stuff right and ends up with bad calls to fetchandadd.
+ */
+#define rwsem_atomic_add(delta, sem)	atomic_add(delta, (atomic_t *)(&(sem)->count))
+#define rwsem_atomic_update(delta, sem)	atomic_add_return(delta, (atomic_t *)(&(sem)->count))
+
+#endif /* _ASM_IA64_RWSEM_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sal.h linux-2.4.22-pre3/include/asm-ia64/sal.h
--- linux-2.4.22-pre2/include/asm-ia64/sal.h	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sal.h	2003-07-05 18:11:15.000000000 -0700
@@ -10,8 +10,8 @@
  * Copyright (C) 2001 Intel
  * Copyright (C) 2002 Jenna Hall <jenna.s.hall@intel.com>
  * Copyright (C) 2001 Fred Lewis <frederick.v.lewis@intel.com>
- * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1998, 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 Srinivasa Prasad Thirumalachar <sprasad@sprasad.engr.sgi.com>
  *
  * 02/01/04 J. Hall Updated Error Record Structures to conform to July 2001
@@ -19,7 +19,7 @@
  * 01/01/03 fvlewis Updated Error Record Structures to conform with Nov. 2000
  *                  revision of the SAL spec.
  * 99/09/29 davidm	Updated for SAL 2.6.
- * 00/03/29 cfleck      Updated SAL Error Logging info for processor (SAL 2.6) 
+ * 00/03/29 cfleck      Updated SAL Error Logging info for processor (SAL 2.6)
  *                      (plus examples of platform error info structures from smariset @ Intel)
  */
 
@@ -36,14 +36,24 @@
 #define __SAL_CALL(result,a0,a1,a2,a3,a4,a5,a6,a7)	\
 	result = (*ia64_sal)(a0,a1,a2,a3,a4,a5,a6,a7)
 
-# define SAL_CALL(result,args...) do {			\
-	unsigned long flags;				\
-	struct ia64_fpreg fr[6];                        \
-	ia64_save_scratch_fpregs(fr);                   \
-	spin_lock_irqsave(&sal_lock, flags);		\
-	__SAL_CALL(result,args);			\
-	spin_unlock_irqrestore(&sal_lock, flags);	\
-	ia64_load_scratch_fpregs(fr);                   \
+# define SAL_CALL(result,args...) do {				\
+	unsigned long __ia64_sc_flags;				\
+	struct ia64_fpreg __ia64_sc_fr[6];			\
+	ia64_save_scratch_fpregs(__ia64_sc_fr);			\
+	spin_lock_irqsave(&sal_lock, __ia64_sc_flags);		\
+	__SAL_CALL(result, args);				\
+	spin_unlock_irqrestore(&sal_lock, __ia64_sc_flags);	\
+	ia64_load_scratch_fpregs(__ia64_sc_fr);			\
+} while (0)
+
+# define SAL_CALL_NOLOCK(result,args...) do {		\
+	unsigned long __ia64_scn_flags;			\
+	struct ia64_fpreg __ia64_scn_fr[6];		\
+	ia64_save_scratch_fpregs(__ia64_scn_fr);	\
+	local_irq_save(__ia64_scn_flags);		\
+	__SAL_CALL(result, args);			\
+	local_irq_restore(__ia64_scn_flags);		\
+	ia64_load_scratch_fpregs(__ia64_scn_fr);	\
 } while (0)
 
 #define SAL_SET_VECTORS			0x01000000
@@ -208,30 +218,30 @@
 
 /* SAL information type encodings */
 enum {
-	SAL_INFO_TYPE_MCA	=		0,	/* Machine check abort information */
-        SAL_INFO_TYPE_INIT	=		1,	/* Init information */
-        SAL_INFO_TYPE_CMC   =       2,  /* Corrected machine check information */
-        SAL_INFO_TYPE_CPE   =       3   /* Corrected platform error information */
+	SAL_INFO_TYPE_MCA  = 0,		/* Machine check abort information */
+        SAL_INFO_TYPE_INIT = 1,		/* Init information */
+        SAL_INFO_TYPE_CMC  = 2,		/* Corrected machine check information */
+        SAL_INFO_TYPE_CPE  = 3		/* Corrected platform error information */
 };
 
 /* Encodings for machine check parameter types */
 enum {
-        SAL_MC_PARAM_RENDEZ_INT		=	1,	/* Rendezevous interrupt */
-        SAL_MC_PARAM_RENDEZ_WAKEUP  =   2,  /* Wakeup */
-        SAL_MC_PARAM_CPE_INT        =   3   /* Corrected Platform Error Int */
+	SAL_MC_PARAM_RENDEZ_INT    = 1,	/* Rendezevous interrupt */
+	SAL_MC_PARAM_RENDEZ_WAKEUP = 2,	/* Wakeup */
+	SAL_MC_PARAM_CPE_INT	   = 3	/* Corrected Platform Error Int */
 };
 
 /* Encodings for rendezvous mechanisms */
 enum {
-        SAL_MC_PARAM_MECHANISM_INT	=	1,	/* Use interrupt */
-        SAL_MC_PARAM_MECHANISM_MEM	=	2	/* Use memory synchronization variable*/
+	SAL_MC_PARAM_MECHANISM_INT = 1,	/* Use interrupt */
+	SAL_MC_PARAM_MECHANISM_MEM = 2	/* Use memory synchronization variable*/
 };
 
 /* Encodings for vectors which can be registered by the OS with SAL */
 enum {
-	SAL_VECTOR_OS_MCA		= 0,
-	SAL_VECTOR_OS_INIT		= 1,
-	SAL_VECTOR_OS_BOOT_RENDEZ	= 2
+	SAL_VECTOR_OS_MCA	  = 0,
+	SAL_VECTOR_OS_INIT	  = 1,
+	SAL_VECTOR_OS_BOOT_RENDEZ = 2
 };
 
 /* Encodings for mca_opt parameter sent to SAL_MC_SET_PARAMS */
@@ -239,387 +249,370 @@
 #define	SAL_MC_PARAM_BINIT_ESCALATE	0x10
 
 /*
-** Definition of the SAL Error Log from the SAL spec
-*/
+ * Definition of the SAL Error Log from the SAL spec
+ */
 
 /* SAL Error Record Section GUID Definitions */
 #define SAL_PROC_DEV_ERR_SECT_GUID  \
-    EFI_GUID ( 0xe429faf1, 0x3cb7, 0x11d4,  0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 )
+    EFI_GUID(0xe429faf1, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
 #define SAL_PLAT_MEM_DEV_ERR_SECT_GUID  \
-    EFI_GUID(  0xe429faf2, 0x3cb7, 0x11d4,  0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 )
+    EFI_GUID(0xe429faf2, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
 #define SAL_PLAT_SEL_DEV_ERR_SECT_GUID  \
-    EFI_GUID(  0xe429faf3, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 )
+    EFI_GUID(0xe429faf3, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
 #define SAL_PLAT_PCI_BUS_ERR_SECT_GUID  \
-    EFI_GUID(  0xe429faf4, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 )
+    EFI_GUID(0xe429faf4, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
 #define SAL_PLAT_SMBIOS_DEV_ERR_SECT_GUID  \
-    EFI_GUID(  0xe429faf5, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 )
+    EFI_GUID(0xe429faf5, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
 #define SAL_PLAT_PCI_COMP_ERR_SECT_GUID  \
-    EFI_GUID(  0xe429faf6, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 )
+    EFI_GUID(0xe429faf6, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
 #define SAL_PLAT_SPECIFIC_ERR_SECT_GUID  \
-    EFI_GUID(  0xe429faf7, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 )
+    EFI_GUID(0xe429faf7, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
 #define SAL_PLAT_HOST_CTLR_ERR_SECT_GUID  \
-    EFI_GUID(  0xe429faf8, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 )
+    EFI_GUID(0xe429faf8, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
 #define SAL_PLAT_BUS_ERR_SECT_GUID  \
-    EFI_GUID(  0xe429faf9, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 )
+    EFI_GUID(0xe429faf9, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
 
-#define MAX_CACHE_ERRORS			6
-#define MAX_TLB_ERRORS				6
-#define MAX_BUS_ERRORS				1
+#define MAX_CACHE_ERRORS	6
+#define MAX_TLB_ERRORS		6
+#define MAX_BUS_ERRORS		1
 
 /* Definition of version  according to SAL spec for logging purposes */
-typedef struct sal_log_revision
-{
-    u8  minor;              /* BCD (0..99) */
-    u8  major;              /* BCD (0..99) */
+typedef struct sal_log_revision {
+	u8 minor;		/* BCD (0..99) */
+	u8 major;		/* BCD (0..99) */
 } sal_log_revision_t;
 
 /* Definition of timestamp according to SAL spec for logging purposes */
-typedef struct sal_log_timestamp
-{
+typedef struct sal_log_timestamp {
 	u8 slh_second;		/* Second (0..59) */
-    u8 slh_minute;      /* Minute (0..59) */
-    u8 slh_hour;        /* Hour (0..23) */
-    u8 slh_reserved;
-    u8 slh_day;         /* Day (1..31) */
-    u8 slh_month;       /* Month (1..12) */
-    u8 slh_year;        /* Year (00..99) */
-    u8 slh_century;     /* Century (19, 20, 21, ...) */
+	u8 slh_minute;		/* Minute (0..59) */
+	u8 slh_hour;		/* Hour (0..23) */
+	u8 slh_reserved;
+	u8 slh_day;		/* Day (1..31) */
+	u8 slh_month;		/* Month (1..12) */
+	u8 slh_year;		/* Year (00..99) */
+	u8 slh_century;		/* Century (19, 20, 21, ...) */
 } sal_log_timestamp_t;
 
 /* Definition of log record  header structures */
-typedef struct sal_log_record_header
-{
-    u64                 id;             /* Unique monotonically increasing ID */
-    sal_log_revision_t  revision;       /* Major and Minor revision of header */
-    u16                 severity;       /* Error Severity */
-    u32                 len;            /* Length of this error log in bytes */
-    sal_log_timestamp_t timestamp;      /* Timestamp */
-    efi_guid_t          platform_guid;  /* Unique OEM Platform ID */
+typedef struct sal_log_record_header {
+	u64 id;				/* Unique monotonically increasing ID */
+	sal_log_revision_t revision;	/* Major and Minor revision of header */
+	u16 severity;			/* Error Severity */
+	u32 len;			/* Length of this error log in bytes */
+	sal_log_timestamp_t timestamp;	/* Timestamp */
+	efi_guid_t platform_guid;	/* Unique OEM Platform ID */
 } sal_log_record_header_t;
 
 /* Definition of log section header structures */
-typedef struct sal_log_sec_header
-{
-    efi_guid_t          guid;       /* Unique Section ID */
-    sal_log_revision_t  revision;   /* Major and Minor revision of Section */
-    u16                 reserved;
-    u32                 len;        /* Section length */
+typedef struct sal_log_sec_header {
+    efi_guid_t guid;			/* Unique Section ID */
+    sal_log_revision_t revision;	/* Major and Minor revision of Section */
+    u16 reserved;
+    u32 len;				/* Section length */
 } sal_log_section_hdr_t;
 
-typedef struct sal_log_mod_error_info
-{
-    struct
-    {
-        u64 check_info              : 1,
-            requestor_identifier    : 1,
-            responder_identifier    : 1,
-            target_identifier       : 1,
-            precise_ip              : 1,
-            reserved                : 59;
-    } valid;
-    u64 check_info;
-    u64 requestor_identifier;
-    u64 responder_identifier;
-    u64 target_identifier;
-    u64 precise_ip;
+typedef struct sal_log_mod_error_info {
+	struct {
+		u64 check_info              : 1,
+		    requestor_identifier    : 1,
+		    responder_identifier    : 1,
+		    target_identifier       : 1,
+		    precise_ip              : 1,
+		    reserved                : 59;
+	} valid;
+	u64 check_info;
+	u64 requestor_identifier;
+	u64 responder_identifier;
+	u64 target_identifier;
+	u64 precise_ip;
 } sal_log_mod_error_info_t;
 
-typedef struct sal_processor_static_info
-{
-    struct
-    {
-        u64 minstate        : 1,
-            br              : 1,
-            cr              : 1,
-            ar              : 1,
-            rr              : 1,
-            fr              : 1,
-            reserved        : 58;
-    } valid;
-    pal_min_state_area_t    min_state_area;
-    u64                     br[8];
-    u64                     cr[128];
-    u64                     ar[128];
-    u64                     rr[8];
-    struct ia64_fpreg       fr[128];
+typedef struct sal_processor_static_info {
+	struct {
+		u64 minstate        : 1,
+		    br              : 1,
+		    cr              : 1,
+		    ar              : 1,
+		    rr              : 1,
+		    fr              : 1,
+		    reserved        : 58;
+	} valid;
+	pal_min_state_area_t min_state_area;
+	u64 br[8];
+	u64 cr[128];
+	u64 ar[128];
+	u64 rr[8];
+	struct ia64_fpreg fr[128];
 } sal_processor_static_info_t;
 
-typedef struct sal_log_processor_info
-{
-    sal_log_section_hdr_t       header;
-    struct
-    {
-        u64 proc_error_map      : 1,
-            proc_state_param    : 1,
-            proc_cr_lid         : 1,
-            psi_static_struct   : 1,
-            num_cache_check     : 4,
-            num_tlb_check       : 4,
-            num_bus_check       : 4,
-            num_reg_file_check  : 4,
-            num_ms_check        : 4,
-            cpuid_info          : 1,
-            reserved1           : 39;
-    } valid;
-    u64                         proc_error_map;
-    u64                         proc_state_parameter;
-    u64                         proc_cr_lid;
-    sal_log_mod_error_info_t    cache_check_info[16];
-    sal_log_mod_error_info_t    tlb_check_info[16];
-    sal_log_mod_error_info_t    bus_check_info[16];
-    sal_log_mod_error_info_t    reg_file_check_info[16];
-    sal_log_mod_error_info_t    ms_check_info[16];
-    struct
-    {
-        u64 regs[5];
-        u64 reserved;
-    } cpuid_info;
-    sal_processor_static_info_t processor_static_info;
+struct sal_cpuid_info {
+	u64 regs[5];
+	u64 reserved;
+};
+
+typedef struct sal_log_processor_info {
+	sal_log_section_hdr_t header;
+	struct {
+		u64 proc_error_map      : 1,
+		    proc_state_param    : 1,
+		    proc_cr_lid         : 1,
+		    psi_static_struct   : 1,
+		    num_cache_check     : 4,
+		    num_tlb_check       : 4,
+		    num_bus_check       : 4,
+		    num_reg_file_check  : 4,
+		    num_ms_check        : 4,
+		    cpuid_info          : 1,
+		    reserved1           : 39;
+	} valid;
+	u64 proc_error_map;
+	u64 proc_state_parameter;
+	u64 proc_cr_lid;
+	/*
+	 * The rest of this structure consists of variable-length arrays, which can't be
+	 * expressed in C.
+	 */
+	sal_log_mod_error_info_t info[0];
+	/*
+	 * This is what the rest looked like if C supported variable-length arrays:
+	 *
+	 * sal_log_mod_error_info_t cache_check_info[.valid.num_cache_check];
+	 * sal_log_mod_error_info_t tlb_check_info[.valid.num_tlb_check];
+	 * sal_log_mod_error_info_t bus_check_info[.valid.num_bus_check];
+	 * sal_log_mod_error_info_t reg_file_check_info[.valid.num_reg_file_check];
+	 * sal_log_mod_error_info_t ms_check_info[.valid.num_ms_check];
+	 * struct sal_cpuid_info cpuid_info;
+	 * sal_processor_static_info_t processor_static_info;
+	 */
 } sal_log_processor_info_t;
 
+/* Given a sal_log_processor_info_t pointer, return a pointer to the processor_static_info: */
+#define SAL_LPI_PSI_INFO(l)									\
+({	sal_log_processor_info_t *_l = (l);							\
+	((sal_processor_static_info_t *)							\
+	 ((char *) _l->info + ((_l->valid.num_cache_check + _l->valid.num_tlb_check		\
+				+ _l->valid.num_bus_check + _l->valid.num_reg_file_check	\
+				+ _l->valid.num_ms_check) * sizeof(sal_log_mod_error_info_t)	\
+			       + sizeof(struct sal_cpuid_info))));				\
+})
+
 /* platform error log structures */
 
-typedef struct sal_log_mem_dev_err_info
-{
-    sal_log_section_hdr_t   header;
-    struct
-    {
-        u64 error_status    : 1,
-            physical_addr   : 1,
-            addr_mask       : 1,
-            node            : 1,
-            card            : 1,
-            module          : 1,
-            bank            : 1,
-            device          : 1,
-            row             : 1,
-            column          : 1,
-            bit_position    : 1,
-            requestor_id    : 1,
-            responder_id    : 1,
-            target_id       : 1,
-            bus_spec_data   : 1,
-            oem_id          : 1,
-            oem_data        : 1,
-            reserved        : 47;
-    } valid;
-    u64             error_status;
-    u64             physical_addr;
-    u64             addr_mask;
-    u16             node;
-    u16             card;
-    u16             module;
-    u16             bank;
-    u16             device;
-    u16             row;
-    u16             column;
-    u16             bit_position;
-    u64             requestor_id;
-    u64             responder_id;
-    u64             target_id;
-    u64             bus_spec_data;
-    u8              oem_id[16];
-    u8              oem_data[1];        /* Variable length data */
+typedef struct sal_log_mem_dev_err_info {
+	sal_log_section_hdr_t header;
+	struct {
+		u64 error_status    : 1,
+		    physical_addr   : 1,
+		    addr_mask       : 1,
+		    node            : 1,
+		    card            : 1,
+		    module          : 1,
+		    bank            : 1,
+		    device          : 1,
+		    row             : 1,
+		    column          : 1,
+		    bit_position    : 1,
+		    requestor_id    : 1,
+		    responder_id    : 1,
+		    target_id       : 1,
+		    bus_spec_data   : 1,
+		    oem_id          : 1,
+		    oem_data        : 1,
+		    reserved        : 47;
+	} valid;
+	u64 error_status;
+	u64 physical_addr;
+	u64 addr_mask;
+	u16 node;
+	u16 card;
+	u16 module;
+	u16 bank;
+	u16 device;
+	u16 row;
+	u16 column;
+	u16 bit_position;
+	u64 requestor_id;
+	u64 responder_id;
+	u64 target_id;
+	u64 bus_spec_data;
+	u8 oem_id[16];
+	u8 oem_data[1];			/* Variable length data */
 } sal_log_mem_dev_err_info_t;
 
-typedef struct sal_log_sel_dev_err_info
-{
-    sal_log_section_hdr_t   header;
-    struct
-    {
-        u64 record_id       : 1,
-            record_type     : 1,
-            generator_id    : 1,
-            evm_rev         : 1,
-            sensor_type     : 1,
-            sensor_num      : 1,
-            event_dir       : 1,
-            event_data1     : 1,
-            event_data2     : 1,
-            event_data3     : 1,
-            reserved        : 54;
-    } valid;
-    u16             record_id;
-    u8              record_type;
-    u8              timestamp[4];
-    u16             generator_id;
-    u8              evm_rev;
-    u8              sensor_type;
-    u8              sensor_num;
-    u8              event_dir;
-    u8              event_data1;
-    u8              event_data2;
-    u8              event_data3;
+typedef struct sal_log_sel_dev_err_info {
+	sal_log_section_hdr_t header;
+	struct {
+		u64 record_id       : 1,
+		    record_type     : 1,
+		    generator_id    : 1,
+		    evm_rev         : 1,
+		    sensor_type     : 1,
+		    sensor_num      : 1,
+		    event_dir       : 1,
+		    event_data1     : 1,
+		    event_data2     : 1,
+		    event_data3     : 1,
+		    reserved        : 54;
+	} valid;
+	u16 record_id;
+	u8 record_type;
+	u8 timestamp[4];
+	u16 generator_id;
+	u8 evm_rev;
+	u8 sensor_type;
+	u8 sensor_num;
+	u8 event_dir;
+	u8 event_data1;
+	u8 event_data2;
+	u8 event_data3;
 } sal_log_sel_dev_err_info_t;
 
-typedef struct sal_log_pci_bus_err_info
-{
-    sal_log_section_hdr_t   header;
-    struct
-    {
-        u64 err_status      : 1,
-            err_type        : 1,
-            bus_id          : 1,
-            bus_address     : 1,
-            bus_data        : 1,
-            bus_cmd         : 1,
-            requestor_id    : 1,
-            responder_id    : 1,
-            target_id       : 1,
-            oem_data        : 1,
-            reserved        : 54;
-    } valid;
-    u64             err_status;
-    u16             err_type;
-    u16             bus_id;
-    u32             reserved;
-    u64             bus_address;
-    u64             bus_data;
-    u64             bus_cmd;
-    u64             requestor_id;
-    u64             responder_id;
-    u64             target_id;
-    u8              oem_data[1];        /* Variable length data */
+typedef struct sal_log_pci_bus_err_info {
+	sal_log_section_hdr_t header;
+	struct {
+		u64 err_status      : 1,
+		    err_type        : 1,
+		    bus_id          : 1,
+		    bus_address     : 1,
+		    bus_data        : 1,
+		    bus_cmd         : 1,
+		    requestor_id    : 1,
+		    responder_id    : 1,
+		    target_id       : 1,
+		    oem_data        : 1,
+		    reserved        : 54;
+	} valid;
+	u64 err_status;
+	u16 err_type;
+	u16 bus_id;
+	u32 reserved;
+	u64 bus_address;
+	u64 bus_data;
+	u64 bus_cmd;
+	u64 requestor_id;
+	u64 responder_id;
+	u64 target_id;
+	u8 oem_data[1];			/* Variable length data */
 } sal_log_pci_bus_err_info_t;
 
-typedef struct sal_log_smbios_dev_err_info
-{
-    sal_log_section_hdr_t   header;
-    struct
-    {
-        u64 event_type      : 1,
-            length          : 1,
-            time_stamp      : 1,
-            data            : 1,
-            reserved1       : 60;
-    } valid;
-    u8              event_type;
-    u8              length;
-    u8              time_stamp[6];
-    u8              data[1];  // data of variable length, length == slsmb_length
+typedef struct sal_log_smbios_dev_err_info {
+	sal_log_section_hdr_t header;
+	struct {
+		u64 event_type      : 1,
+		    length          : 1,
+		    time_stamp      : 1,
+		    data            : 1,
+		    reserved1       : 60;
+	} valid;
+	u8 event_type;
+	u8 length;
+	u8 time_stamp[6];
+	u8 data[1];			/* data of variable length, length == slsmb_length */
 } sal_log_smbios_dev_err_info_t;
 
-typedef struct sal_log_pci_comp_err_info
-{
-    sal_log_section_hdr_t   header;
-    struct
-    {
-        u64 err_status      : 1,
-            comp_info       : 1,
-            num_mem_regs    : 1,
-            num_io_regs     : 1,
-            reg_data_pairs  : 1,
-            oem_data        : 1,
-            reserved        : 58;
-    } valid;
-    u64             err_status;
-    struct
-    {
-        u16 vendor_id;
-        u16 device_id;
-	u8  class_code[3];
-        u8  func_num;
-        u8  dev_num;
-        u8  bus_num;
-        u8  seg_num;
-        u8  reserved[5];
-    }               comp_info;
-    u32             num_mem_regs;
-    u32             num_io_regs;
-    u64             reg_data_pairs[1];
-    /* array of address/data register pairs is num_mem_regs + num_io_regs
-       elements long.  Each array element consists of a u64 address followed
-       by a u64 data value.  The oem_data array immediately follows the
-       reg_data_pairs array */
-    u8              oem_data[1];        /* Variable length data */
+typedef struct sal_log_pci_comp_err_info {
+	sal_log_section_hdr_t header;
+	struct {
+		u64 err_status      : 1,
+		    comp_info       : 1,
+		    num_mem_regs    : 1,
+		    num_io_regs     : 1,
+		    reg_data_pairs  : 1,
+		    oem_data        : 1,
+		    reserved        : 58;
+	} valid;
+	u64 err_status;
+	struct {
+		u16 vendor_id;
+		u16 device_id;
+		u8 class_code[3];
+		u8 func_num;
+		u8 dev_num;
+		u8 bus_num;
+		u8 seg_num;
+		u8 reserved[5];
+	} comp_info;
+	u32 num_mem_regs;
+	u32 num_io_regs;
+	u64 reg_data_pairs[1];
+	/*
+	 * array of address/data register pairs is num_mem_regs + num_io_regs elements
+	 * long.  Each array element consists of a u64 address followed by a u64 data
+	 * value.  The oem_data array immediately follows the reg_data_pairs array
+	 */
+	u8 oem_data[1];			/* Variable length data */
 } sal_log_pci_comp_err_info_t;
 
-typedef struct sal_log_plat_specific_err_info
-{
-    sal_log_section_hdr_t   header;
-    struct
-    {
-        u64 err_status      : 1,
-            guid            : 1,
-            oem_data        : 1,
-            reserved        : 61;
-    } valid;
-    u64             err_status;
-    efi_guid_t      guid;
-    u8              oem_data[1];      /* platform specific variable length data */
+typedef struct sal_log_plat_specific_err_info {
+	sal_log_section_hdr_t header;
+	struct {
+		u64 err_status      : 1,
+		    guid            : 1,
+		    oem_data        : 1,
+		    reserved        : 61;
+	} valid;
+	u64 err_status;
+	efi_guid_t guid;
+	u8 oem_data[1];			/* platform specific variable length data */
 } sal_log_plat_specific_err_info_t;
 
-typedef struct sal_log_host_ctlr_err_info
-{
-    sal_log_section_hdr_t   header;
-    struct
-    {
-        u64 err_status      : 1,
-            requestor_id    : 1,
-            responder_id    : 1,
-            target_id       : 1,
-            bus_spec_data   : 1,
-            oem_data        : 1,
-            reserved        : 58;
-    } valid;
-    u64             err_status;
-    u64             requestor_id;
-    u64             responder_id;
-    u64             target_id;
-    u64             bus_spec_data;
-    u8              oem_data[1];        /* Variable length OEM data */
+typedef struct sal_log_host_ctlr_err_info {
+	sal_log_section_hdr_t header;
+	struct {
+		u64 err_status      : 1,
+		    requestor_id    : 1,
+		    responder_id    : 1,
+		    target_id       : 1,
+		    bus_spec_data   : 1,
+		    oem_data        : 1,
+		    reserved        : 58;
+	} valid;
+	u64 err_status;
+	u64 requestor_id;
+	u64 responder_id;
+	u64 target_id;
+	u64 bus_spec_data;
+	u8 oem_data[1];			/* Variable length OEM data */
 } sal_log_host_ctlr_err_info_t;
 
-typedef struct sal_log_plat_bus_err_info
-{
-    sal_log_section_hdr_t   header;
-    struct
-    {
-        u64 err_status      : 1,
-            requestor_id    : 1,
-            responder_id    : 1,
-            target_id       : 1,
-            bus_spec_data   : 1,
-            oem_data        : 1,
-            reserved        : 58;
-    } valid;
-    u64             err_status;
-    u64             requestor_id;
-    u64             responder_id;
-    u64             target_id;
-    u64             bus_spec_data;
-    u8              oem_data[1];        /* Variable length OEM data */
+typedef struct sal_log_plat_bus_err_info {
+	sal_log_section_hdr_t header;
+	struct {
+		u64 err_status      : 1,
+		    requestor_id    : 1,
+		    responder_id    : 1,
+		    target_id       : 1,
+		    bus_spec_data   : 1,
+		    oem_data        : 1,
+		    reserved        : 58;
+	} valid;
+	u64 err_status;
+	u64 requestor_id;
+	u64 responder_id;
+	u64 target_id;
+	u64 bus_spec_data;
+	u8 oem_data[1];			/* Variable length OEM data */
 } sal_log_plat_bus_err_info_t;
 
 /* Overall platform error section structure */
-typedef union sal_log_platform_err_info
-{
-    sal_log_mem_dev_err_info_t          mem_dev_err;
-    sal_log_sel_dev_err_info_t          sel_dev_err;
-    sal_log_pci_bus_err_info_t          pci_bus_err;
-    sal_log_smbios_dev_err_info_t       smbios_dev_err;
-    sal_log_pci_comp_err_info_t         pci_comp_err;
-    sal_log_plat_specific_err_info_t    plat_specific_err;
-    sal_log_host_ctlr_err_info_t        host_ctlr_err;
-    sal_log_plat_bus_err_info_t         plat_bus_err;
+typedef union sal_log_platform_err_info {
+	sal_log_mem_dev_err_info_t mem_dev_err;
+	sal_log_sel_dev_err_info_t sel_dev_err;
+	sal_log_pci_bus_err_info_t pci_bus_err;
+	sal_log_smbios_dev_err_info_t smbios_dev_err;
+	sal_log_pci_comp_err_info_t pci_comp_err;
+	sal_log_plat_specific_err_info_t plat_specific_err;
+	sal_log_host_ctlr_err_info_t host_ctlr_err;
+	sal_log_plat_bus_err_info_t plat_bus_err;
 } sal_log_platform_err_info_t;
 
 /* SAL log over-all, multi-section error record structure (processor+platform) */
-typedef struct err_rec
-{
-    sal_log_record_header_t     sal_elog_header;
-    sal_log_processor_info_t    proc_err;
-    sal_log_platform_err_info_t plat_err;
-    u8                          oem_data_pad[1024];
+typedef struct err_rec {
+	sal_log_record_header_t sal_elog_header;
+	sal_log_processor_info_t proc_err;
+	sal_log_platform_err_info_t plat_err;
+	u8 oem_data_pad[1024];
 } ia64_err_rec_t;
 
 /*
@@ -648,7 +641,6 @@
 }
 
 
-	
 /* Initialize all the processor and platform level instruction and data caches */
 static inline s64
 ia64_sal_cache_init (void)
@@ -658,8 +650,9 @@
 	return isrv.status;
 }
 
-/* Clear the processor and platform information logged by SAL with respect to the 
- * machine state at the time of MCA's, INITs, CMCs, or CPEs.
+/*
+ * Clear the processor and platform information logged by SAL with respect to the machine
+ * state at the time of MCA's, INITs, CMCs, or CPEs.
  */
 static inline s64
 ia64_sal_clear_state_info (u64 sal_info_type)
@@ -684,9 +677,11 @@
 		return 0;
 
 	return isrv.v0;
-}	
-/* Get the maximum size of the information logged by SAL with respect to the machine 
- * state at the time of MCAs, INITs, CMCs, or CPEs.
+}
+
+/*
+ * Get the maximum size of the information logged by SAL with respect to the machine state
+ * at the time of MCAs, INITs, CMCs, or CPEs.
  */
 static inline u64
 ia64_sal_get_state_info_size (u64 sal_info_type)
@@ -699,27 +694,33 @@
 	return isrv.v0;
 }
 
-/* Causes the processor to go into a spin loop within SAL where SAL awaits a wakeup
- * from the monarch processor.
+/*
+ * Causes the processor to go into a spin loop within SAL where SAL awaits a wakeup from
+ * the monarch processor.  Must not lock, because it will not return on any cpu until the
+ * monarch processor sends a wake up.
  */
 static inline s64
 ia64_sal_mc_rendez (void)
 {
 	struct ia64_sal_retval isrv;
-	SAL_CALL(isrv, SAL_MC_RENDEZ, 0, 0, 0, 0, 0, 0, 0);
+	SAL_CALL_NOLOCK(isrv, SAL_MC_RENDEZ, 0, 0, 0, 0, 0, 0, 0);
 	return isrv.status;
 }
 
-/* Allow the OS to specify the interrupt number to be used by SAL to interrupt OS during
- * the machine check rendezvous sequence as well as the mechanism to wake up the 
+/*
+ * Allow the OS to specify the interrupt number to be used by SAL to interrupt OS during
+ * the machine check rendezvous sequence as well as the mechanism to wake up the
  * non-monarch processor at the end of machine check processing.
+ * Returns the complete ia64_sal_retval because some calls return more than just a status
+ * value.
  */
-static inline s64
+static inline struct ia64_sal_retval
 ia64_sal_mc_set_params (u64 param_type, u64 i_or_m, u64 i_or_m_val, u64 timeout, u64 rz_always)
 {
 	struct ia64_sal_retval isrv;
-	SAL_CALL(isrv, SAL_MC_SET_PARAMS, param_type, i_or_m, i_or_m_val, timeout, rz_always, 0, 0);
-	return isrv.status;
+	SAL_CALL(isrv, SAL_MC_SET_PARAMS, param_type, i_or_m, i_or_m_val,
+		 timeout, rz_always, 0, 0);
+	return isrv;
 }
 
 /* Read from PCI configuration space */
@@ -744,8 +745,8 @@
 }
 
 /*
- * Register physical addresses of locations needed by SAL when SAL
- * procedures are invoked in virtual mode.
+ * Register physical addresses of locations needed by SAL when SAL procedures are invoked
+ * in virtual mode.
  */
 static inline s64
 ia64_sal_register_physical_addr (u64 phys_entry, u64 phys_addr)
@@ -756,9 +757,10 @@
 	return isrv.status;
 }
 
-/* Register software dependent code locations within SAL. These locations are handlers
- * or entry points where SAL will pass control for the specified event. These event
- * handlers are for the bott rendezvous, MCAs and INIT scenarios.
+/*
+ * Register software dependent code locations within SAL. These locations are handlers or
+ * entry points where SAL will pass control for the specified event. These event handlers
+ * are for the bott rendezvous, MCAs and INIT scenarios.
  */
 static inline s64
 ia64_sal_set_vectors (u64 vector_type,
@@ -768,10 +770,11 @@
 	struct ia64_sal_retval isrv;
 	SAL_CALL(isrv, SAL_SET_VECTORS, vector_type,
 			handler_addr1, gp1, handler_len1,
-			handler_addr2, gp2, handler_len2);			
+			handler_addr2, gp2, handler_len2);
 
 	return isrv.status;
-}		
+}
+
 /* Update the contents of PAL block in the non-volatile storage device */
 static inline s64
 ia64_sal_update_pal (u64 param_buf, u64 scratch_buf, u64 scratch_buf_size,
diff -urN linux-2.4.22-pre2/include/asm-ia64/smp.h linux-2.4.22-pre3/include/asm-ia64/smp.h
--- linux-2.4.22-pre2/include/asm-ia64/smp.h	2001-11-09 14:26:17.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ia64/smp.h	2003-07-05 18:11:16.000000000 -0700
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 2001 Hewlett-Packard Co
+ * Copyright (C) 2001-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #ifndef _ASM_IA64_SMP_H
@@ -48,6 +48,8 @@
 
 extern unsigned long ap_wakeup_vector;
 
+#define cpu_online(cpu)		(cpu_online_map & (1UL << (cpu)))
+
 /*
  * Function to map hard smp processor id to logical id.  Slow, so
  * don't use this in performance-critical code.
@@ -58,7 +60,7 @@
 	int i;
 
 	for (i = 0; i < smp_num_cpus; ++i)
-		if (cpu_physical_id(i) == (__u32) cpuid)
+		if (cpu_physical_id(i) == cpuid)
 			break;
 	return i;
 }
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/addrs.h linux-2.4.22-pre3/include/asm-ia64/sn/addrs.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/addrs.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/addrs.h	2003-07-05 18:11:16.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1999,2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_ADDRS_H
@@ -11,13 +11,7 @@
 
 #include <linux/config.h>
 
-#if defined (CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/addrs.h>
-#elif defined (CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/addrs.h>
-#else
-#error <<<BOMB! addrs.h defined only for SN1, or SN2 >>>
-#endif /* !SN1 && !SN2 */
 
 #ifndef __ASSEMBLY__
 #include <asm/sn/types.h>
@@ -27,11 +21,7 @@
 
 #define PS_UINT_CAST		(__psunsigned_t)
 #define UINT64_CAST		(uint64_t)
-#ifdef CONFIG_IA64_SGI_SN2
 #define HUBREG_CAST		(volatile mmr_t *)
-#else
-#define HUBREG_CAST		(volatile hubreg_t *)
-#endif
 
 #elif __ASSEMBLY__
 
@@ -49,11 +39,7 @@
  * node's address space.
  */
 
-#ifdef CONFIG_IA64_SGI_SN2	/* SN2 has an extra AS field between node offset and node id (nasid) */
 #define NODE_OFFSET(_n)		(UINT64_CAST (_n) << NASID_SHFT)
-#else
-#define NODE_OFFSET(_n)		(UINT64_CAST (_n) << NODE_SIZE_BITS)
-#endif
 
 #define NODE_CAC_BASE(_n)	(CAC_BASE  + NODE_OFFSET(_n))
 #define NODE_HSPEC_BASE(_n)	(HSPEC_BASE + NODE_OFFSET(_n))
@@ -80,7 +66,7 @@
  */
 
 #define SWIN_SIZE_BITS		24
-#define SWIN_SIZE		(UINT64_CAST 1 << 24)
+#define SWIN_SIZE		(1UL<<24)
 #define	SWIN_SIZEMASK		(SWIN_SIZE - 1)
 #define	SWIN_WIDGET_MASK	0xF
 
@@ -116,44 +102,13 @@
  *			references to the local hub's registers.
  */
 
-#if defined CONFIG_IA64_SGI_SN1
-#define LREG_BASE		(HSPEC_BASE + 0x10000000)
-#define LREG_SIZE		0x8000000  /* 128 MB */
-#define LREG_LIMIT		(LREG_BASE + LREG_SIZE)
-#define LBOOT_BASE		(LREG_LIMIT)
-#define LBOOT_SIZE		0x8000000   /* 128 MB */
-#define LBOOT_LIMIT		(LBOOT_BASE + LBOOT_SIZE)
-#define LBOOT_STRIDE		0x2000000    /* two PROMs, on 32M boundaries */
-#endif
-
 #define	HUB_REGISTER_WIDGET	1
-#ifdef CONFIG_IA64_SGI_SN2
 #define IALIAS_BASE		LOCAL_SWIN_BASE(HUB_REGISTER_WIDGET)
-#else
-#define IALIAS_BASE		NODE_SWIN_BASE(0, HUB_REGISTER_WIDGET)
-#endif
 #define IALIAS_SIZE		0x800000	/* 8 Megabytes */
 #define IS_IALIAS(_a)		(((_a) >= IALIAS_BASE) &&		\
 				 ((_a) < (IALIAS_BASE + IALIAS_SIZE)))
 
 /*
- * Macro for referring to Hub's RBOOT space
- */
-
-#if defined CONFIG_IA64_SGI_SN1
-
-#define NODE_LREG_BASE(_n)	(NODE_HSPEC_BASE(_n) + 0x30000000)
-#define NODE_LREG_LIMIT(_n)	(NODE_LREG_BASE(_n) + LREG_SIZE)
-#define RREG_BASE(_n)		(NODE_LREG_BASE(_n))
-#define RREG_LIMIT(_n)		(NODE_LREG_LIMIT(_n))
-#define RBOOT_SIZE		0x8000000	/* 128 Megabytes */
-#define NODE_RBOOT_BASE(_n)	(NODE_HSPEC_BASE(_n) + 0x38000000)
-#define NODE_RBOOT_LIMIT(_n)	(NODE_RBOOT_BASE(_n) + RBOOT_SIZE)
-
-#endif
-
-
-/*
  * The following macros produce the correct base virtual address for
  * the hub registers.  The LOCAL_HUB_* macros produce the appropriate
  * address for the local registers.  The REMOTE_HUB_* macro produce
@@ -163,11 +118,10 @@
  */
 
 
-#ifdef CONFIG_IA64_SGI_SN2
 /*
- * SN2 has II mmr's located inside small window space like SN0 & SN1,
- * but has all other non-II mmr's located at the top of big window
- * space, unlike SN0 & SN1.
+ * SN2 has II mmr's located inside small window space.
+ * As all other non-II mmr's located at the top of big window
+ * space.
  */
 #define LOCAL_HUB_BASE(_x)	(LOCAL_MMR_ADDR(_x) | (((~(_x)) & BWIN_TOP)>>8))
 #define REMOTE_HUB_BASE(_x)						\
@@ -179,18 +133,6 @@
 #define REMOTE_HUB(_n, _x)						\
 	(HUBREG_CAST (REMOTE_HUB_BASE(_x) | ((((long)(_n))<<NASID_SHFT))))
 
-#else	/* not CONFIG_IA64_SGI_SN2 */
-
-#define LOCAL_HUB(_x)		(HUBREG_CAST (IALIAS_BASE + (_x)))
-#define REMOTE_HUB(_n, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
-					      0x800000 + (_x)))
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define LOCAL_HSPEC(_x)		(HUBREG_CAST (LREG_BASE + (_x)))
-#define REMOTE_HSPEC(_n, _x)		(HUBREG_CAST (RREG_BASE(_n) + (_x)))
-#endif /* CONFIG_IA64_SGI_SN1 */
-
 
 /*
  * WARNING:
@@ -200,27 +142,12 @@
  *	Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
  *	They're always safe.
  */
-#ifdef CONFIG_IA64_SGI_SN2
 #define LOCAL_HUB_ADDR(_x)							\
 	(((_x) & BWIN_TOP) ? (HUBREG_CAST (LOCAL_MMR_ADDR(_x)))		\
 	: (HUBREG_CAST (IALIAS_BASE + (_x))))
 #define REMOTE_HUB_ADDR(_n, _x)						\
 	(((_x) & BWIN_TOP) ? (HUBREG_CAST (GLOBAL_MMR_ADDR(_n, _x)))	\
 	: (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x))))
-#else
-#define LOCAL_HUB_ADDR(_x)	(HUBREG_CAST (IALIAS_BASE + (_x)))
-#define REMOTE_HUB_ADDR(_n, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
-					      0x800000 + (_x)))
-#endif
-#if CONFIG_IA64_SGI_SN1
-#define REMOTE_HUB_PI_ADDR(_n, _sn, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
-					      0x800000 + PIREG(_x, _sn)))
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define LOCAL_HSPEC_ADDR(_x)		(HUBREG_CAST (LREG_BASE + (_x)))
-#define REMOTE_HSPEC_ADDR(_n, _x)	(HUBREG_CAST (RREG_BASE(_n) + (_x)))
-#endif /* CONFIG_IA64_SGI_SN1 */
 
 #ifndef __ASSEMBLY__
 
@@ -234,13 +161,6 @@
 #define REMOTE_HUB_PI_L(_n, _sn, _r)	HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)))
 #define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
 
-#ifdef CONFIG_IA64_SGI_SN1
-#define LOCAL_HSPEC_L(_r)	     HUB_L(LOCAL_HSPEC_ADDR(_r))
-#define LOCAL_HSPEC_S(_r, _d)	     HUB_S(LOCAL_HSPEC_ADDR(_r), (_d))
-#define REMOTE_HSPEC_L(_n, _r)	     HUB_L(REMOTE_HSPEC_ADDR((_n), (_r)))
-#define REMOTE_HSPEC_S(_n, _r, _d)   HUB_S(REMOTE_HSPEC_ADDR((_n), (_r)), (_d))
-#endif /* CONFIG_IA64_SGI_SN1 */
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -308,12 +228,7 @@
 #define	KLD_KERN_XP(nasid)	(KLD_BASE(nasid) + KLI_KERN_XP)
 #define	KLD_KERN_PARTID(nasid)	(KLD_BASE(nasid) + KLI_KERN_PARTID)
 
-#ifndef CONFIG_IA64_SGI_SN2
-#define KLCONFIG_OFFSET(nasid)	KLD_KLCONFIG(nasid)->offset
-#else
-#define KLCONFIG_OFFSET(nasid) \
-	ia64_sn_get_klconfig_addr(nasid)
-#endif /* CONFIG_IA64_SGI_SN2 */
+#define KLCONFIG_OFFSET(nasid)  ia64_sn_get_klconfig_addr(nasid)
 
 #define KLCONFIG_ADDR(nasid)						\
 	TO_NODE_CAC((nasid), KLCONFIG_OFFSET(nasid))
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/alenlist.h linux-2.4.22-pre3/include/asm-ia64/sn/alenlist.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/alenlist.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/alenlist.h	2003-07-05 18:11:16.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_ALENLIST_H
 #define _ASM_IA64_SN_ALENLIST_H
@@ -15,7 +15,7 @@
 
 /*
  * An Address/Length List is used when setting up for an I/O DMA operation.
- * A driver creates an Address/Length List that describes to the DMA 
+ * A driver creates an Address/Length List that describes to the the DMA 
  * interface where in memory the DMA should go.  The bus interface sets up 
  * mapping registers, if required, and returns a suitable list of "physical 
  * addresses" or "I/O address" to the driver.  The driver then uses these 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/arc/hinv.h linux-2.4.22-pre3/include/asm-ia64/sn/arc/hinv.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/arc/hinv.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/arc/hinv.h	2003-07-05 18:11:16.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 /* $Id$
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/arc/types.h linux-2.4.22-pre3/include/asm-ia64/sn/arc/types.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/arc/types.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/arc/types.h	2003-07-05 18:11:16.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright 1999 Ralf Baechle (ralf@gnu.org)
  */
 #ifndef _ASM_SN_ARC_TYPES_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/arch.h linux-2.4.22-pre3/include/asm-ia64/sn/arch.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/arch.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/arch.h	2003-07-05 18:11:16.000000000 -0700
@@ -6,7 +6,7 @@
  *
  * SGI specific setup.
  *
- * Copyright (C) 1995-1997,1999,2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 1995-1997,1999,2001-2003 Silicon Graphics, Inc.  All rights reserved.
  * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
  */
 #ifndef _ASM_IA64_SN_ARCH_H
@@ -17,19 +17,9 @@
 #include <linux/mmzone.h>
 #include <asm/sn/types.h>
 
-#if defined(CONFIG_IA64_SGI_SN1) 
-#include <asm/sn/sn1/arch.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/arch.h>
-#endif
 
-
-#if defined(CONFIG_IA64_SGI_SN1) 
-typedef u64	bdrkreg_t;
-#elif defined(CONFIG_IA64_SGI_SN2)
 typedef u64	shubreg_t;
-#endif
-
 typedef u64	hubreg_t;
 typedef u64	mmr_t;
 typedef u64	nic_t;
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/ate_utils.h linux-2.4.22-pre3/include/asm-ia64/sn/ate_utils.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/ate_utils.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/ate_utils.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,51 +0,0 @@
-#ifndef _ASM_IA64_SN_ATE_UTILS_H
-#define _ASM_IA64_SN_ATE_UTILS_H
-
-/* $Id: ate_utils.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- *	struct map	X[]	.m_size		.m_addr
- *			---	------------	-----------
- *			[0]	mapsize(X)	unused
- *				# X[] unused
- *			[1]	map lock *	mapwant sv_t *
- *				map access	wait for free map space
- *
- *	  mapstart(X)-> [2]	# units		unit number
- *			 :	    :		  :
- *			[ ]	    0
- */
-
-#include <linux/types.h>
-
-#define ulong_t uint64_t
-
-struct map
-{
-	unsigned long m_size;	/* number of units available */
-	unsigned long m_addr;	/* address of first available unit */
-};
-
-#define mapstart(X)		&X[2]		/* start of map array */
-
-#define mapsize(X)		X[0].m_size	/* number of empty slots */
-						/* remaining in map array */
-#define maplock(X)		(((spinlock_t *) X[1].m_size))
-
-#define mapout(X)		((sv_t *) X[1].m_addr)
-
-
-extern ulong_t atealloc(struct map *, size_t);
-extern struct map *atemapalloc(ulong_t);
-extern void atefree(struct map *, size_t, ulong_t);
-extern void atemapfree(struct map *);
-
-#endif /* _ASM_IA64_SN_ATE_UTILS_H  */
-
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/bte.h linux-2.4.22-pre3/include/asm-ia64/sn/bte.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/bte.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/bte.h	2003-07-05 18:11:16.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  *
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -36,11 +36,28 @@
 #ifndef _ASM_IA64_SN_BTE_H
 #define _ASM_IA64_SN_BTE_H
 
-#ident "$Revision: 1.1 $"
-
+#include <linux/timer.h>
 #include <linux/spinlock.h>
 #include <linux/cache.h>
 #include <asm/sn/io.h>
+#include <asm/delay.h>
+
+
+/* #define BTE_DEBUG */
+/* #define BTE_DEBUG_VERBOSE */
+
+#ifdef BTE_DEBUG
+#  define BTE_PRINTK(x) printk x	/* Terse */
+#  ifdef BTE_DEBUG_VERBOSE
+#    define BTE_PRINTKV(x) printk x	/* Verbose */
+#  else
+#    define BTE_PRINTKV(x)
+#  endif /* BTE_DEBUG_VERBOSE */
+#else
+#  define BTE_PRINTK(x)
+#  define BTE_PRINTKV(x)
+#endif	/* BTE_DEBUG */
+
 
 /* BTE status register only supports 16 bits for length field */
 #define BTE_LEN_BITS (16)
@@ -48,40 +65,60 @@
 #define BTE_MAX_XFER ((1 << BTE_LEN_BITS) * L1_CACHE_BYTES)
 
 
-/*
- * Constants used in determining the best and worst case transfer
- * times. To help explain the two, the following graph of transfer
- * status vs time may help.
- *
- *     active +------------------:-+  :
- *  status    |                  : |  :
- *       idle +__________________:_+=======
- *            0 Time           MaxT  MinT
- *
- *  Therefore, MaxT is the maximum thoeretical rate for transfering
- *  the request block (assuming ideal circumstances)
- *
- *  MinT is the minimum theoretical rate for transferring the
- *  requested block (assuming maximum link distance and contention)
- *
- *  The following defines are the inverse of the above.  They are
- *  used for calculating the MaxT time and MinT time given the 
- *  number of lines in the transfer.
- */
-#define BTE_MAXT_LINES_PER_SECOND 800
-#define BTE_MINT_LINES_PER_SECOND 600
-
-
 /* Define hardware */
 #define BTES_PER_NODE 2
 
+
 /* Define hardware modes */
 #define BTE_NOTIFY (IBCT_NOTIFY)
 #define BTE_NORMAL BTE_NOTIFY
 #define BTE_ZERO_FILL (BTE_NOTIFY | IBCT_ZFIL_MODE)
-
 /* Use a reserved bit to let the caller specify a wait for any BTE */
 #define BTE_WACQUIRE (0x4000)
+/* macro to force the IBCT0 value valid */
+#define BTE_VALID_MODE(x) ((x) & (IBCT_NOTIFY | IBCT_ZFIL_MODE))
+
+
+/*
+ * Handle locking of the bte interfaces.
+ *
+ * All transfers spinlock the interface before setting up the SHUB
+ * registers.  Sync transfers hold the lock until all processing is
+ * complete.  Async transfers release the lock as soon as the transfer
+ * is initiated.
+ *
+ * To determine if an interface is available, we must check both the
+ * busy bit and the spinlock for that interface.
+ */
+#define BTE_LOCK_IF_AVAIL(_x) (\
+	(*pda.cpu_bte_if[_x]->most_rcnt_na & (IBLS_BUSY | IBLS_ERROR)) && \
+	(!(spin_trylock(&(pda.cpu_bte_if[_x]->spinlock)))) \
+	)
+
+/*
+ * Some macros to simplify reading.
+ * Start with macros to locate the BTE control registers.
+ */
+#define BTEREG_LNSTAT_ADDR ((u64 *)(bte->bte_base_addr))
+#define BTEREG_SRC_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_SRC))
+#define BTEREG_DEST_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_DEST))
+#define BTEREG_CTRL_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_CTRL))
+#define BTEREG_NOTIF_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_NOTIFY))
+
+
+/* Possible results from bte_copy and bte_unaligned_copy */
+typedef enum {
+	BTE_SUCCESS,		/* 0 is success */
+	BTEFAIL_NOTAVAIL,	/* BTE not available */
+	BTEFAIL_POISON,		/* poison page */
+	BTEFAIL_PROT,		/* Protection violation */
+	BTEFAIL_ACCESS,		/* access error */
+	BTEFAIL_TOUT,		/* Time out */
+	BTEFAIL_XTERR,		/* Diretory error */
+	BTEFAIL_DIR,		/* Diretory error */
+	BTEFAIL_ERROR,		/* Generic error */
+} bte_result_t;
+
 
 /*
  * Structure defining a bte.  An instance of this
@@ -90,28 +127,41 @@
  * This structure contains everything necessary
  * to work with a BTE.
  */
-typedef struct bteinfo_s {
+struct bteinfo_s {
 	u64 volatile notify ____cacheline_aligned;
 	char *bte_base_addr ____cacheline_aligned;
 	spinlock_t spinlock;
-	u64 ideal_xfr_tmo;	/* Time out */
-	u64 ideal_xfr_tmo_cnt;
-	/* u64 most_recent_src;
-	 * u64 most_recent_dest;
-	 * u64 most_recent_len;
-	 * u64 most_recent_mode; */
+	cnodeid_t bte_cnode;	/* cnode                            */
+	int bte_error_count;	/* Number of errors encountered     */
+	int bte_num;		/* 0 --> BTE0, 1 --> BTE1           */
+	int cleanup_active;	/* Interface is locked for cleanup  */
+	volatile bte_result_t bh_error;	/* error while processing   */
 	u64 volatile *most_rcnt_na;
-	void *bte_test_buf;
-} bteinfo_t;
+	void *scratch_buf;	/* Node local scratch buffer        */
+};
 
-/* Possible results from bte_copy and bte_unaligned_copy */
-typedef enum {
-	BTE_SUCCESS,		/* 0 is success */
-	BTEFAIL_NOTAVAIL,	/* BTE not available */
-	BTEFAIL_ERROR,		/* Generic error */
-	BTEFAIL_DIR		/* Diretory error */
-} bte_result_t;
 
-void bte_reset_nasid(nasid_t);
+/*
+ * Function prototypes (functions defined in bte.c, used elsewhere)
+ */
+extern bte_result_t bte_copy(u64, u64, u64, u64, void *);
+extern bte_result_t bte_unaligned_copy(u64, u64, u64, u64);
+extern void bte_error_handler(unsigned long);
+
+
+/*
+ * The following is the prefered way of calling bte_unaligned_copy
+ * If the copy is fully cache line aligned, then bte_copy is
+ * used instead.  Since bte_copy is inlined, this saves a call
+ * stack.  NOTE: bte_copy is called synchronously and does block
+ * until the transfer is complete.  In order to get the asynch
+ * version of bte_copy, you must perform this check yourself.
+ */
+#define BTE_UNALIGNED_COPY(src, dest, len, mode)                        \
+	(((len & L1_CACHE_MASK) || (src & L1_CACHE_MASK) ||             \
+	  (dest & L1_CACHE_MASK)) ?                                     \
+	 bte_unaligned_copy(src, dest, len, mode) :              	\
+	 bte_copy(src, dest, len, mode, NULL))
+
 
-#endif				/* _ASM_IA64_SN_BTE_H */
+#endif	/* _ASM_IA64_SN_BTE_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/bte_copy.h linux-2.4.22-pre3/include/asm-ia64/sn/bte_copy.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/bte_copy.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/bte_copy.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,382 +0,0 @@
-/*
- *
- *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#ifndef _ASM_IA64_SN_BTE_COPY_H
-#define _ASM_IA64_SN_BTE_COPY_H
-
-#ident "$Revision: 1.1 $"
-
-#include <linux/timer.h>
-#include <asm/sn/bte.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/pda.h>
-#include <asm/delay.h>
-
-/*
- * BTE_LOCKING support - When CONFIG_IA64_SGI_BTE_LOCKING is
- * not defined, the bte_copy code supports one bte per cpu in
- * synchronous mode.  Even if bte_copy is called with a
- * notify address, the bte will spin and wait for the transfer
- * to complete.  By defining the following, spin_locks and
- * busy checks are placed around the initiation of a BTE
- * transfer and multiple bte's per cpu are supported.
- */
-#if 0
-#define CONFIG_IA64_SGI_BTE_LOCKING 1
-#endif
-
-/*
- * Handle locking of the bte interfaces.
- *
- * All transfers spinlock the interface before setting up the SHUB
- * registers.  Sync transfers hold the lock until all processing is
- * complete.  Async transfers release the lock as soon as the transfer
- * is initiated.
- *
- * To determine if an interface is available, we must check both the
- * busy bit and the spinlock for that interface.
- */
-#define BTE_LOCK_IF_AVAIL(_x) (\
-	(*pda.cpu_bte_if[_x]->most_rcnt_na & IBLS_BUSY) && \
-	(!(spin_trylock(&(pda.cpu_bte_if[_x]->spinlock)))) \
-	)
-
-/*
- * Some macros to simplify reading.
- *
- * Start with macros to locate the BTE control registers.
- */
-
-#define BTEREG_LNSTAT_ADDR ((u64 *)(bte->bte_base_addr))
-#define BTEREG_SRC_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_SRC))
-#define BTEREG_DEST_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_DEST))
-#define BTEREG_CTRL_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_CTRL))
-#define BTEREG_NOTIF_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_NOTIFY))
-
-/* Some macros to force the IBCT0 value valid. */
-
-#define BTE_VALID_MODES BTE_NOTIFY
-#define BTE_VLD_MODE(x) (x & BTE_VALID_MODES)
-
-// #define BTE_DEBUG
-// #define BTE_DEBUG_VERBOSE
-// #define BTE_TIME
-
-#ifdef BTE_DEBUG
-#  define BTE_PRINTK(x) printk x	/* Terse */
-#  ifdef BTE_DEBUG_VERBOSE
-#    define BTE_PRINTKV(x) printk x	/* Verbose */
-#  else
-#    define BTE_PRINTKV(x)
-#  endif /* BTE_DEBUG_VERBOSE */
-#else
-#  define BTE_PRINTK(x)
-#  define BTE_PRINTKV(x)
-#endif /* BTE_DEBUG */
-
-#define BTE_IDEAL_TMO(x) (jiffies + \
-	(HZ / BTE_MAXT_LINES_PER_SECOND * x))
-
-#ifdef BTE_TIME
-volatile extern u64 bte_setup_time;
-volatile extern u64 bte_transfer_time;
-volatile extern u64 bte_tear_down_time;
-volatile extern u64 bte_execute_time;
-
-#define BTE_TIME_DECLARE() \
-	u64 btcp_strt_tm = 0; \
-	u64 btcp_cplt_tm = 0; \
-	u64 xfr_strt_tm = 0; \
-	u64 xfr_cplt_tm = 0; \
-
-#define BTE_TIME_START() \
-	btcp_strt_tm = xfr_strt_tm = xfr_cplt_tm = ia64_get_itc();
-
-#define BTE_TIME_XFR_START() \
-	xfr_strt_tm = ia64_get_itc();
-
-#define BTE_TIME_XFR_STOP() \
-	xfr_cplt_tm = ia64_get_itc();
-
-#define BTE_TIME_STOP() \
-	btcp_cplt_tm = ia64_get_itc(); \
-	bte_setup_time = xfr_strt_tm - btcp_strt_tm; \
-	bte_transfer_time = xfr_cplt_tm - xfr_strt_tm; \
-	bte_tear_down_time = btcp_cplt_tm - xfr_cplt_tm; \
-	bte_execute_time = btcp_cplt_tm - btcp_strt_tm; \
-
-#else /* BTE_TIME */
-#define BTE_TIME_DECLARE()
-#define BTE_TIME_START()
-#define BTE_TIME_XFR_START()
-#define BTE_TIME_XFR_STOP()
-#define BTE_TIME_STOP()
-#endif /* BTE_TIME */
-
-/*
- * bte_copy(src, dest, len, mode, notification)
- *
- * use the block transfer engine to move kernel
- * memory from src to dest using the assigned mode.
- *
- * Paramaters:
- *   src - physical address of the transfer source.
- *   dest - physical address of the transfer destination.
- *   len - number of bytes to transfer from source to dest.
- *   mode - hardware defined.  See reference information
- *          for IBCT0/1 in the SHUB Programmers Reference
- *   notification - kernel virtual address of the notification cache
- *                  line.  If NULL, the default is used and
- *                  the bte_copy is synchronous.
- *
- * NOTE:  This function requires src, dest, and len to
- * be cache line aligned.
- */
-extern __inline__ bte_result_t
-bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
-{
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-	int bte_to_use;
-#endif /* CONFIG_IA64_SGI_BTE_LOCKING */
-	u64 transfer_size;
-	u64 lines_remaining;
-	bteinfo_t *bte;
-	BTE_TIME_DECLARE();
-
-	BTE_TIME_START();
-
-	BTE_PRINTK(("bte_copy (0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
-		    src, dest, len, mode, notification));
-
-	if (len == 0) {
-		BTE_TIME_STOP();
-		return (BTE_SUCCESS);
-	}
-
-	ASSERT(!((len & L1_CACHE_MASK) ||
-		 (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK)));
-
-	ASSERT(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT));
-
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-	{
-		bte_to_use = 0;
-
-		/* Attempt to lock one of the BTE interfaces */
-		while ((bte_to_use < BTES_PER_NODE) &&
-		       BTE_LOCK_IF_AVAIL(bte_to_use)) {
-
-			bte_to_use++;
-		}
-
-		if ((bte_to_use >= BTES_PER_NODE) &&
-		    !(mode & BTE_WACQUIRE)) {
-			BTE_TIME_STOP();
-			return (BTEFAIL_NOTAVAIL);
-		}
-
-		/* Wait until a bte is available. */
-	}
-	while (bte_to_use >= BTES_PER_NODE);
-
-	bte = pda.cpu_bte_if[bte_to_use];
-	BTE_PRINTKV(("Got a lock on bte %d\n", bte_to_use));
-#else
-	/* Assuming one BTE per CPU. */
-	bte = pda.cpu_bte_if[0];
-#endif /* CONFIG_IA64_SGI_BTE_LOCKING */
-
-	/*
-	 * The following are removed for optimization but is
-	 * available in the event that the SHUB exhibits
-	 * notification problems similar to the hub, bedrock et al.
-	 *
-	 * bte->mostRecentSrc = src;
-	 * bte->mostRecentDest = dest;
-	 * bte->mostRecentLen = len;
-	 * bte->mostRecentMode = mode;
-	 */
-	if (notification == NULL) {
-		/* User does not want to be notified. */
-		bte->most_rcnt_na = &bte->notify;
-	} else {
-		bte->most_rcnt_na = notification;
-	}
-
-	/* Calculate the number of cache lines to transfer. */
-	transfer_size = ((len >> L1_CACHE_SHIFT) & BTE_LEN_MASK);
-
-	BTE_PRINTKV(("Calculated transfer size of %d cache lines\n",
-		     transfer_size));
-
-	/* Initialize the notification to a known value. */
-	*bte->most_rcnt_na = -1L;
-
-
-	BTE_PRINTKV(("Before, status is 0x%lx and notify is 0x%lx\n",
-		     HUB_L(BTEREG_LNSTAT_ADDR),
-		     *bte->most_rcnt_na));
-
-	/* Set the status reg busy bit and transfer length */
-	BTE_PRINTKV(("IBLS - HUB_S(0x%lx, 0x%lx)\n",
-		     BTEREG_LNSTAT_ADDR, IBLS_BUSY | transfer_size));
-	HUB_S(BTEREG_LNSTAT_ADDR, (IBLS_BUSY | transfer_size));
-
-	/* Set the source and destination registers */
-	BTE_PRINTKV(("IBSA - HUB_S(0x%lx, 0x%lx)\n", BTEREG_SRC_ADDR,
-		     (TO_PHYS(src))));
-	HUB_S(BTEREG_SRC_ADDR, (TO_PHYS(src)));
-	BTE_PRINTKV(("IBDA - HUB_S(0x%lx, 0x%lx)\n", BTEREG_DEST_ADDR,
-		     (TO_PHYS(dest))));
-	HUB_S(BTEREG_DEST_ADDR, (TO_PHYS(dest)));
-
-	/* Set the notification register */
-	BTE_PRINTKV(("IBNA - HUB_S(0x%lx, 0x%lx)\n", BTEREG_NOTIF_ADDR,
-		     (TO_PHYS(__pa(bte->most_rcnt_na)))));
-	HUB_S(BTEREG_NOTIF_ADDR, (TO_PHYS(__pa(bte->most_rcnt_na))));
-
-	/* Initiate the transfer */
-	BTE_PRINTKV(("IBCT - HUB_S(0x%lx, 0x%lx)\n", BTEREG_CTRL_ADDR, mode));
-	BTE_TIME_XFR_START();
-	HUB_S(BTEREG_CTRL_ADDR, BTE_VLD_MODE(mode));
-
-	BTE_PRINTKV(("Initiated, status is 0x%lx and notify is 0x%lx\n",
-		     HUB_L(BTEREG_LNSTAT_ADDR),
-		     *bte->most_rcnt_na));
-
-	if (notification == NULL) {
-		/*
-		 * Calculate our timeout
-		 *
-		 * What are we doing here?  We are trying to determine
-		 * the fastest time the BTE could have transfered our
-		 * block of data.  By takine the clock frequency (ticks/sec)
-		 * divided by the BTE MaxT Transfer Rate (lines/sec)
-		 * times the transfer size (lines), we get a tick
-		 * offset from current time that the transfer should
-		 * complete.
-		 *
-		 * Why do this?  We are watching for a notification
-		 * failure from the BTE.  This behaviour has been
-		 * seen in the SN0 and SN1 hardware on rare circumstances
-		 * and is expected in SN2.  By checking at the
-		 * ideal transfer timeout, we minimize our time
-		 * delay from hardware completing our request and
-		 * our detecting the failure.
-		 */
-		bte->ideal_xfr_tmo = BTE_IDEAL_TMO(transfer_size);
-
-		while (bte->notify == -1UL) {
-			/*
-			 * Notification Workaround: When the max
-			 * theoretical time has elapsed, read the hub
-			 * status register into the notification area.
-			 * This fakes the shub performing the copy.
-			 */
-			BTE_PRINTKV(("  Timing.  IBLS = 0x%lx, "
-				     "notify= 0x%lx\n",
-				     HUB_L(BTEREG_LNSTAT_ADDR),
-				     bte->notify));
-			if (time_after(jiffies, bte->ideal_xfr_tmo)) {
-				lines_remaining = HUB_L(BTEREG_LNSTAT_ADDR) &
-					BTE_LEN_MASK;
-				bte->ideal_xfr_tmo_cnt++;
-				bte->ideal_xfr_tmo =
-					BTE_IDEAL_TMO(lines_remaining);
-
-				BTE_PRINTKV(("  Timeout.  cpu %d "
-					     "IBLS = 0x%lx, "
-					     "notify= 0x%lx, "
-					     "Lines remaining = %d. "
-					     "New timeout = %d.\n",
-					     smp_processor_id(),
-					     HUB_L(BTEREG_LNSTAT_ADDR),
-					     bte->notify,
-					     lines_remaining,
-					     bte->ideal_xfr_tmo));
-			}
-		}
-		BTE_PRINTKV((" Delay Done.  IBLS = 0x%lx, notify= 0x%lx\n",
-			     HUB_L(BTEREG_LNSTAT_ADDR),
-			  bte->notify));
-		BTE_TIME_XFR_STOP();
-		if (bte->notify & IBLS_ERROR) {
-			/* >>> Need to do real error checking. */
-			transfer_size = 0;
-
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-			spin_unlock(&(bte->spinlock));
-#endif /* CONFIG_IA64_SGI_BTE_LOCKING */
-			BTE_PRINTKV(("Erroring status is 0x%lx and "
-				     "notify is 0x%lx\n",
-				     HUB_L(BTEREG_LNSTAT_ADDR),
-				     bte->notify));
-
-			BTE_TIME_STOP();
-			bte->notify = 0L;
-			return (BTEFAIL_ERROR);
-		}
-
-	}
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-	spin_unlock(&(bte->spinlock));
-#endif /* CONFIG_IA64_SGI_BTE_LOCKING */
-	BTE_TIME_STOP();
-	BTE_PRINTKV(("Returning status is 0x%lx and notify is 0x%lx\n",
-		     HUB_L(BTEREG_LNSTAT_ADDR),
-		     *bte->most_rcnt_na));
-
-	return (BTE_SUCCESS);
-}
-
-/*
- * Define the bte_unaligned_copy as an extern.
- */
-extern bte_result_t bte_unaligned_copy(u64, u64, u64, u64);
-
-/*
- * The following is the prefered way of calling bte_unaligned_copy
- * If the copy is fully cache line aligned, then bte_copy is
- * used instead.  Since bte_copy is inlined, this saves a call
- * stack.  NOTE: bte_copy is called synchronously and does block
- * until the transfer is complete.  In order to get the asynch
- * version of bte_copy, you must perform this check yourself.
- */
-#define BTE_UNALIGNED_COPY(src, dest, len, mode)			\
-	(((len & L1_CACHE_MASK) || (src & L1_CACHE_MASK) ||		\
-	  (dest & L1_CACHE_MASK)) ?					\
-		bte_unaligned_copy(src, dest, len, mode) :		\
-		bte_copy(src, dest, len, mode, NULL))
-
-#endif /* _ASM_IA64_SN_BTE_COPY_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/cdl.h linux-2.4.22-pre3/include/asm-ia64/sn/cdl.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/cdl.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/cdl.h	2003-07-05 18:11:16.000000000 -0700
@@ -4,13 +4,20 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_CDL_H
 #define _ASM_IA64_SN_CDL_H
 
 #include <asm/sn/sgi.h>
 
+struct cdl {
+	int part_num;			/* Part part number */
+	int mfg_num;			/* Part MFG number */
+	int (*attach)(vertex_hdl_t);	/* Attach routine */
+};
+
+
 /*
  *	cdl: connection/driver list
  *
@@ -21,175 +28,14 @@
 typedef struct cdl     *cdl_p;
 
 /*
- *	cdl_itr_f is the type for the functions
- *	that are handled by cdl_iterate.
- */
-
-typedef void	
-cdl_iter_f		(devfs_handle_t vhdl);
-
-/*
- *	cdl_drv_f is the type for the functions
- *	that are called by cdl_add_driver and 
- *      cdl_del_driver.
- */
-
-typedef void	
-cdl_drv_f		(devfs_handle_t vhdl, int key1, int key2, int error);
-
-/*
- *	If CDL_PRI_HI is specified in the flags
- *	parameter for cdl_add_driver, then that driver's
- *	attach routine will be called for future connect
- *	points before any (non-CDL_PRI_HI) drivers.
- *
- *	The IOC3 driver uses this facility to make sure
- *	that the ioc3_attach() function is called before
- *	the attach routines of any subdevices.
- *
- *	Drivers for bridge-based crosstalk cards that
- *	are almost but not quite generic can use it to
- *	arrange that their attach() functions get called
- *	before the generic bridge drivers, so they can
- *	leave behind "hint" structures that will
- *	properly configure the generic driver.
- */
-#define	CDL_PRI_HI	0x0001
-
-/*
- *	cdl_new: construct a new connection/driver list
- *
- *	Called once for each "kind" of bus. Returns an
- *	opaque cookie representing the particular list
- *	that will be operated on by the other calls.
- */
-extern cdl_p		cdl_new(char *, char *, char *);
-
-/*
- *	cdl_del: destroy a connection/driver list.
- *
- *	Releases all dynamically allocated resources
- *	associated with the specified list. Forgets what
- *	drivers might be involved in this kind of bus,
- *	forgets what connection points have been noticed
- *	on this kind of bus.
- */
-extern void		cdl_del(cdl_p reg);
-
-/*
- *	cdl_add_driver: register a device driver
- *
- *	Calls the driver's attach routine with all
- *	connection points on the list that have the same
- *	key information as the driver; call-back the 
- *      specified function to notify the driver of the 
- *      attach status for each device.  Place the driver
- *      on the list so that any connection points
- *	discovered in the future that match the driver
- *	can be handed off to the driver's attach
- *	routine.
- *
- *	CDL_PRI_HI may be specified (see above).
- */
-
-extern int		cdl_add_driver(cdl_p reg,
-				       int key1,
-				       int key2,
-				       char *prefix,
-				       int flags,
-				       cdl_drv_f *func);
-
-/*
- *	cdl_del_driver: remove a device driver
- *
- *	Calls the driver's detach routine with all
- *	connection points on the list that match the
- *	driver;  call-back the specified function to
- *      notify the driver of the detach status for each
- *      device.  Then forget about the driver.  Future
- *	calls to cdl_add_connpt with connections that
- *	would match this driver no longer trigger calls
- *	to the driver's attach routine.
- *
- *	NOTE: Yes, I said CONNECTION POINTS, not
- *	verticies that the driver has been attached to
- *	with hwgraph_driver_add(); this gives the driver
- *	a chance to clean up anything it did to the
- *	connection point in its attach routine. Also,
- *	this is done whether or not the attach routine
- *	was successful.
- */
-extern void		cdl_del_driver(cdl_p reg, 
-				       char *prefix,
-				       cdl_drv_f *func);
-
-/*
  *	cdl_add_connpt: add a connection point
  *
  *	Calls the attach routines of all the drivers on
  *	the list that match this connection point, in
- *	the order that they were added to the list,
- *	except that CDL_PRI_HI drivers are called first.
- *
- *	Then the vertex is added to the list, so it can
- *	be presented to any matching drivers that may be
- *	subsequently added to the list.
+ *	the order that they were added to the list.
  */
-extern int		cdl_add_connpt(cdl_p reg,
-				       int key1,
+extern int		cdl_add_connpt(int key1,
 				       int key2,
-				       devfs_handle_t conn,
+				       vertex_hdl_t conn,
 				       int drv_flags);
-
-/*
- *	cdl_del_connpt: delete a connection point
- *
- *	Calls the detach routines of all matching
- *	drivers for this connection point, in the same
- *	order that the attach routines were called; then
- *	forgets about this vertex, so drivers added in
- *	the future will not be told about it.
- *
- *	NOTE: Same caveat here about the detach calls as
- *	in the cdl_del_driver() comment above.
- */
-extern int		cdl_del_connpt(cdl_p reg,
-				       int key1,
-				       int key2,
-				       devfs_handle_t conn,
-				       int drv_flags);
-
-/*
- *	cdl_iterate: find all verticies in the registry
- *	corresponding to the named driver and call them
- *	with the specified function (giving the vertex
- *	as the parameter).
- */
-
-extern void		cdl_iterate(cdl_p reg,
-				    char *prefix,
-				    cdl_iter_f *func);
-
-/*
- * An INFO_LBL_ASYNC_ATTACH label is attached to a vertex, pointing to
- * an instance of async_attach_s to indicate that asynchronous
- * attachment may be applied to that device ... if the corresponding
- * driver allows it.
- */
-
-struct async_attach_s {
-	struct semaphore async_sema;
-	int    async_count;
-};
-typedef struct async_attach_s *async_attach_t;
-
-async_attach_t	async_attach_new(void);
-void		async_attach_free(async_attach_t);
-async_attach_t  async_attach_get_info(devfs_handle_t);
-void            async_attach_add_info(devfs_handle_t, async_attach_t);
-void            async_attach_del_info(devfs_handle_t);
-void		async_attach_signal_start(async_attach_t);
-void		async_attach_signal_done(async_attach_t);
-void		async_attach_waitall(async_attach_t);
-
 #endif /* _ASM_IA64_SN_CDL_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/clksupport.h linux-2.4.22-pre3/include/asm-ia64/sn/clksupport.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/clksupport.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/clksupport.h	2003-07-05 18:11:16.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 /*
@@ -29,30 +29,18 @@
 #include <asm/sn/addrs.h>
 
 typedef long clkreg_t;
+
 extern unsigned long sn_rtc_cycles_per_second;
+extern unsigned long sn_rtc_usec_per_cyc;
+extern unsigned long sn_rtc_per_itc;
+extern unsigned long sn_rtc_delta;
 
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/sn1/hubpi_next.h>
-
-extern nasid_t master_nasid;
-
-#define RTC_MASK		(0x007fffffffffffff)
-/* clocks are not synchronized yet on SN1  - used node 0 (problem if no NASID 0) */
-#define RTC_COUNTER_ADDR	((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_COUNTER))
-#define RTC_COMPARE_A_ADDR      ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_COMPARE_A))
-#define RTC_COMPARE_B_ADDR      ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_COMPARE_B))
-#define RTC_INT_PENDING_A_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_INT_PEND_A))
-#define RTC_INT_PENDING_B_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_INT_PEND_B))
-#define RTC_INT_ENABLED_A_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_INT_EN_A))
-#define RTC_INT_ENABLED_B_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_INT_EN_B))
-#else	/* !CONFIG_IA64_SGI_SN1 */
 #include <asm/sn/addrs.h>
 #include <asm/sn/sn2/addrs.h>
 #include <asm/sn/sn2/shubio.h>
 #include <asm/sn/sn2/shub_mmr.h>
-#define RTC_MASK		(SH_RTC_MASK)
+#define RTC_MASK		SH_RTC_MASK
 #define RTC_COUNTER_ADDR	((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
 #define RTC_COMPARE_A_ADDR      ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
 #define RTC_COMPARE_B_ADDR      ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
@@ -60,9 +48,8 @@
 #define RTC_INT_PENDING_B_ADDR  ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
 #define RTC_INT_ENABLED_A_ADDR  ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
 #define RTC_INT_ENABLED_B_ADDR  ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
 
+#define SN_RTC_PER_ITC_SHIFT	34
 #define GET_RTC_COUNTER()	(*RTC_COUNTER_ADDR)
 #define rtc_time()		GET_RTC_COUNTER()
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/dmamap.h linux-2.4.22-pre3/include/asm-ia64/sn/dmamap.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/dmamap.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/dmamap.h	2003-07-05 18:11:16.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_DMAMAP_H
 #define _ASM_IA64_SN_DMAMAP_H
@@ -54,9 +54,6 @@
 extern int	dma_map(dmamap_t *, caddr_t, int);
 extern int	dma_map2(dmamap_t *, caddr_t, caddr_t, int);
 extern paddr_t	dma_mapaddr(dmamap_t *, caddr_t);
-#ifdef LATER
-extern int	dma_mapbp(dmamap_t *, buf_t *, int);
-#endif
 extern int	dma_map_alenlist(dmamap_t *, struct alenlist_s *, size_t);
 extern uint	ev_kvtoiopnum(caddr_t);
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/driver.h linux-2.4.22-pre3/include/asm-ia64/sn/driver.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/driver.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/driver.h	2003-07-05 18:11:16.000000000 -0700
@@ -4,12 +4,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_DRIVER_H
 #define _ASM_IA64_SN_DRIVER_H
 
-#include <linux/devfs_fs_kernel.h>
+#include <asm/sn/sgi.h>
 #include <asm/types.h>
 
 /*
@@ -75,7 +75,7 @@
 	/* TBD: allocated badwidth requirements */
 
 	/* interrupt description */
-	devfs_handle_t	intr_target;	/* Hardware locator string */
+	vertex_hdl_t	intr_target;	/* Hardware locator string */
 	int 		intr_policy;	/* TBD */
 	ilvl_t		intr_swlevel;	/* software level for blocking intr */
 	char		*intr_name;	/* name of interrupt, if any */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/eeprom.h linux-2.4.22-pre3/include/asm-ia64/sn/eeprom.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/eeprom.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/eeprom.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,384 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Public interface for reading Atmel EEPROMs via L1 system controllers
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_EEPROM_H
-#define _ASM_IA64_SN_EEPROM_H
-
-#include <linux/config.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/vector.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/nic.h>
-
-/*
- * The following structures are an implementation of the EEPROM info
- * areas described in the SN1 EEPROM spec and the IPMI FRU Information
- * Storage definition
- */
-
-/* Maximum lengths for EEPROM fields
- */
-#define EEPROM_PARTNUM_LEN	20
-#define EEPROM_SERNUM_LEN	10
-#define	EEPROM_MANUF_NAME_LEN	10
-#define EEPROM_PROD_NAME_LEN	14
-
-
-
-/* The EEPROM "common header", which contains offsets to the other
- * info areas in the EEPROM
- */
-typedef struct eeprom_common_hdr_t
-{
-    uchar_t	format;		/* common header format byte */
-    uchar_t	internal_use;	/* offsets to various info areas */
-    uchar_t	chassis;	/*  (in doubleword units)        */
-    uchar_t	board;
-    uchar_t	product;
-    uchar_t	multi_record;
-    uchar_t	pad;
-    uchar_t	checksum;
-} eeprom_common_hdr_t;
-
-
-/* The chassis (brick) info area 
- */
-typedef struct eeprom_chassis_ia_t
-{
-    uchar_t	format;		/* format byte */
-    uchar_t	length;		/* info area length in doublewords */
-    uchar_t	type;		/* chassis type (always 0x17 "rack mount") */
-    uchar_t	part_num_tl;	/* type/length of part number field */
-
-    char	part_num[EEPROM_PARTNUM_LEN];
-    				/* ASCII part number */
-
-    uchar_t	serial_num_tl;	/* type/length of serial number field */
-
-    char	serial_num[EEPROM_SERNUM_LEN];
-    				/* ASCII serial number */
-
-    uchar_t	checksum;
-
-} eeprom_chassis_ia_t;
-
-
-/* The board info area
- */
-typedef struct eeprom_board_ia_t
-{
-    uchar_t       format;         /* format byte */
-    uchar_t       length;         /* info area length in doublewords */
-    uchar_t	language;	/* language code, always 0x00 "English" */
-    int		mfg_date;	/* date & time of manufacture, in minutes
-				    since 0:00 1/1/96 */
-    uchar_t	manuf_tl;	/* type/length of manufacturer name field */
-
-    char	manuf[EEPROM_MANUF_NAME_LEN];
-				/* ASCII manufacturer name */
-
-    uchar_t	product_tl;	/* type/length of product name field */
-
-    char	product[EEPROM_PROD_NAME_LEN];
-				/* ASCII product name */
-
-    uchar_t	serial_num_tl;	/* type/length of board serial number */
-
-    char	serial_num[EEPROM_SERNUM_LEN];
-				/* ASCII serial number */
-
-    uchar_t	part_num_tl;	/* type/length of board part number */
-
-    char	part_num[EEPROM_PARTNUM_LEN];
-				/* ASCII part number */
-
-    /*
-     * "custom" fields -- see SN1 EEPROM Spec
-     */
-    uchar_t	board_rev_tl;	/* type/length of board rev (always 0xC2) */
-
-    char	board_rev[2];	/* ASCII board revision */
-
-    uchar_t	eeprom_size_tl; /* type/length of eeprom size field */
-    uchar_t	eeprom_size;	/* size code for eeprom */
-    uchar_t	temp_waiver_tl;	/* type/length of temp waiver field (0xC2) */
-    char	temp_waiver[2];	/* temp waiver */
-
-    
-    /*
-     * these fields only appear in main boards' EEPROMs
-     */
-    uchar_t	ekey_G_tl;	/* type/length of encryption key "G" */
-    uint32_t	ekey_G;		/* encryption key "G" */
-    uchar_t	ekey_P_tl;	/* type/length of encryption key "P" */
-    uint32_t	ekey_P;		/* encryption key "P" */
-    uchar_t	ekey_Y_tl;	/* type/length of encryption key "Y" */
-    uint32_t	ekey_Y;		/* encryption key "Y" */
-
-    
-    /*
-     * these fields are used for I bricks only
-     */
-    uchar_t	mac_addr_tl;	  /* type/length of MAC address */
-    char	mac_addr[12];	  /* MAC address */
-    uchar_t	ieee1394_cfg_tl;  /* type/length of IEEE 1394 info */
-    uchar_t	ieee1394_cfg[32]; /* IEEE 1394 config info */
-    
-
-    /*
-     * all boards have a checksum
-     */
-    uchar_t	checksum;
-
-} eeprom_board_ia_t;
-
-/* given a pointer to the three-byte little-endian EEPROM representation
- * of date-of-manufacture, this function translates to a big-endian
- * integer format
- */
-int eeprom_xlate_board_mfr_date( uchar_t *src );
-
-
-/* EEPROM Serial Presence Detect record (used for DIMMs in IP35)
- */
-typedef struct eeprom_spd_t
-{
-    /* 0*/ uchar_t spd_used; /* # of bytes written to serial memory by manufacturer */
-    /* 1*/ uchar_t spd_size; /* Total # of bytes of SPD memory device */
-    /* 2*/ uchar_t mem_type; /* Fundamental memory type (FPM, EDO, SDRAM..) */
-    /* 3*/ uchar_t num_rows; /* # of row addresses on this assembly */
-    /* 4*/ uchar_t num_cols; /* # Column Addresses on this assembly */
-    /* 5*/ uchar_t mod_rows; /* # Module Rows on this assembly */
-    /* 6*/ uchar_t data_width[2]; /* Data Width of this assembly (16b little-endian) */
-    /* 8*/ uchar_t volt_if; /* Voltage interface standard of this assembly */
-    /* 9*/ uchar_t cyc_time; /* SDRAM Cycle time, CL=X (highest CAS latency) */
-    /* A*/ uchar_t acc_time; /* SDRAM Access from Clock (highest CAS latency) */
-    /* B*/ uchar_t dimm_cfg; /* DIMM Configuration type (non-parity, ECC) */
-    /* C*/ uchar_t refresh_rt; /* Refresh Rate/Type */
-    /* D*/ uchar_t prim_width; /* Primary SDRAM Width */
-    /* E*/ uchar_t ec_width; /* Error Checking SDRAM width */
-    /* F*/ uchar_t min_delay; /* Min Clock Delay Back to Back Random Col Address */
-    /*10*/ uchar_t burst_len; /* Burst Lengths Supported */
-    /*11*/ uchar_t num_banks; /* # of Banks on Each SDRAM Device */
-    /*12*/ uchar_t cas_latencies; /* CAS# Latencies Supported */
-    /*13*/ uchar_t cs_latencies; /* CS# Latencies Supported */
-    /*14*/ uchar_t we_latencies; /* Write Latencies Supported */
-    /*15*/ uchar_t mod_attrib; /* SDRAM Module Attributes */
-    /*16*/ uchar_t dev_attrib; /* SDRAM Device Attributes: General */
-    /*17*/ uchar_t cyc_time2; /* Min SDRAM Cycle time at CL X-1 (2nd highest CAS latency) */
-    /*18*/ uchar_t acc_time2; /* SDRAM Access from Clock at CL X-1 (2nd highest CAS latency) */
-    /*19*/ uchar_t cyc_time3; /* Min SDRAM Cycle time at CL X-2 (3rd highest CAS latency) */
-    /*1A*/ uchar_t acc_time3; /* Max SDRAM Access from Clock at CL X-2 (3nd highest CAS latency) */
-    /*1B*/ uchar_t min_row_prechg; /* Min Row Precharge Time (Trp) */
-    /*1C*/ uchar_t min_ra_to_ra; /* Min Row Active to Row Active (Trrd) */
-    /*1D*/ uchar_t min_ras_to_cas; /* Min RAS to CAS Delay (Trcd) */
-    /*1E*/ uchar_t min_ras_pulse; /* Minimum RAS Pulse Width (Tras) */
-    /*1F*/ uchar_t row_density; /* Density of each row on module */
-    /*20*/ uchar_t ca_setup; /* Command and Address signal input setup time */
-    /*21*/ uchar_t ca_hold; /* Command and Address signal input hold time */
-    /*22*/ uchar_t d_setup; /* Data signal input setup time */
-    /*23*/ uchar_t d_hold; /* Data signal input hold time */
-
-    /*24*/ uchar_t pad0[26]; /* unused */
-    
-    /*3E*/ uchar_t data_rev; /* SPD Data Revision Code */
-    /*3F*/ uchar_t checksum; /* Checksum for bytes 0-62 */
-    /*40*/ uchar_t jedec_id[8]; /* Manufacturer's JEDEC ID code */
-    
-    /*48*/ uchar_t mfg_loc; /* Manufacturing Location */
-    /*49*/ uchar_t part_num[18]; /* Manufacturer's Part Number */
-
-    /*5B*/ uchar_t rev_code[2]; /* Revision Code */
-
-    /*5D*/ uchar_t mfg_date[2]; /* Manufacturing Date */
-
-    /*5F*/ uchar_t ser_num[4]; /* Assembly Serial Number */
-
-    /*63*/ uchar_t manuf_data[27]; /* Manufacturer Specific Data */
-
-    /*7E*/ uchar_t intel_freq; /* Intel specification frequency */
-    /*7F*/ uchar_t intel_100MHz; /* Intel spec details for 100MHz support */
-
-} eeprom_spd_t;
-
-
-#define EEPROM_SPD_RECORD_MAXLEN	256
-
-typedef union eeprom_spd_u
-{
-    eeprom_spd_t fields;
-    char         bytes[EEPROM_SPD_RECORD_MAXLEN];
-
-} eeprom_spd_u;
-
-
-/* EEPROM board record
- */
-typedef struct eeprom_brd_record_t 
-{
-    eeprom_chassis_ia_t		*chassis_ia;
-    eeprom_board_ia_t		*board_ia;
-    eeprom_spd_u		*spd;
-
-} eeprom_brd_record_t;
-
-
-/* End-of-fields marker
- */
-#define EEPROM_EOF	        0xc1
-
-
-/* masks for dissecting the type/length bytes
- */
-#define FIELD_FORMAT_MASK       0xc0
-#define FIELD_LENGTH_MASK       0x3f
-
-
-/* field format codes (used in type/length bytes)
- */
-#define FIELD_FORMAT_BINARY     0x00 /* binary format */
-#define FIELD_FORMAT_BCD        0x40 /* BCD */
-#define FIELD_FORMAT_PACKED     0x80 /* packed 6-bit ASCII */
-#define FIELD_FORMAT_ASCII      0xC0 /* 8-bit ASCII */
-
-
-
-
-/* codes specifying brick and board type
- */
-#define C_BRICK		0x100
-
-#define C_PIMM		(C_BRICK | 0x10)
-#define C_PIMM_0	(C_PIMM) /* | 0x0 */
-#define C_PIMM_1	(C_PIMM | 0x1)
-
-#define C_DIMM		(C_BRICK | 0x20)
-#define C_DIMM_0	(C_DIMM) /* | 0x0 */
-#define C_DIMM_1	(C_DIMM | 0x1)
-#define C_DIMM_2	(C_DIMM | 0x2)
-#define C_DIMM_3	(C_DIMM | 0x3)
-#define C_DIMM_4	(C_DIMM | 0x4)
-#define C_DIMM_5	(C_DIMM | 0x5)
-#define C_DIMM_6	(C_DIMM | 0x6)
-#define C_DIMM_7	(C_DIMM | 0x7)
-
-#define R_BRICK		0x200
-#define R_POWER		(R_BRICK | 0x10)
-
-#define VECTOR		0x300 /* used in vector ops when the destination
-			       * could be a cbrick or an rbrick */
-
-#define IO_BRICK	0x400
-#define IO_POWER	(IO_BRICK | 0x10)
-
-#define BRICK_MASK	0xf00
-#define SUBORD_MASK	0xf0  /* AND with component specification; if the
-			         the result is non-zero, then the component
-			         is a subordinate board of some kind */
-#define COMPT_MASK	0xf   /* if there's more than one instance of a
-				 particular type of subordinate board, this 
-				 masks out which one we're talking about */
-
-
-
-/* functions & macros for obtaining "NIC-like" strings from EEPROMs
- */
-
-#ifdef CONFIG_IA64_SGI_SN1
-
-int eeprom_str( char *nic_str, nasid_t nasid, int component );
-int vector_eeprom_str( char *nic_str, nasid_t nasid,
-		       int component, net_vec_t path );
-
-#define CBRICK_EEPROM_STR(s,n)	eeprom_str((s),(n),C_BRICK)
-#define IOBRICK_EEPROM_STR(s,n)	eeprom_str((s),(n),IO_BRICK)
-#define RBRICK_EEPROM_STR(s,n,p)  vector_eeprom_str((s),(n),R_BRICK,p)
-#define VECTOR_EEPROM_STR(s,n,p)  vector_eeprom_str((s),(n),VECTOR,p)
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-
-/* functions for obtaining formatted records from EEPROMs
- */
-
-int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			int component );
-int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			 int component );
-int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			net_vec_t path, int component );
-
-
-
-/* retrieve the ethernet MAC address for an I-brick
- */
-
-int ibrick_mac_addr_get( nasid_t nasid, char *eaddr );
-
-
-/* error codes
- */
-
-#define EEP_OK			0
-#define EEP_L1			1
-#define EEP_FAIL		2
-#define EEP_BAD_CHECKSUM	3
-#define EEP_NICIFY		4
-#define EEP_PARAM		6
-#define EEP_NOMEM		7
-
-
-
-/* given a hardware graph vertex and an indication of the brick type,
- * brick and board to be read, this functions reads the eeprom and
- * attaches a "NIC"-format string of manufacturing information to the 
- * vertex.  If the vertex already has the string, just returns the
- * string.  If component is not VECTOR or R_BRICK, the path parameter
- * is ignored.
- */
-
-#ifdef LATER
-char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v,
-			      net_vec_t path );
-#endif
-
-
-
-/* We may need to differentiate between an XBridge and other types of
- * bridges during discovery to tell whether the bridge in question
- * is part of an IO brick.  The following function reads the WIDGET_ID
- * register of the bridge under examination and returns a positive value
- * if the part and mfg numbers stored there indicate that this widget
- * is an XBridge (and so must be part of a brick).
- */
-#ifdef LATER
-int is_iobrick( int nasid, int widget_num );
-#endif
-
-/* the following macro derives the widget number from the register
- * address passed to it and uses is_iobrick to determine whether
- * the widget in question is part of an SN1 IO brick.
- */
-#define IS_IOBRICK(rg)	is_iobrick( NASID_GET((rg)), SWIN_WIDGETNUM((rg)) )
-
-
-
-/* macros for NIC compatability */
-/* always invoked on "this" cbrick */
-#define HUB_VERTEX_MFG_INFO(v) \
-    eeprom_vertex_info_set( C_BRICK, get_nasid(), (v), 0 )
-
-#define BRIDGE_VERTEX_MFG_INFO(v, r) \
-    ( IS_IOBRICK((r)) ? eeprom_vertex_info_set \
-		          ( IO_BRICK, NASID_GET((r)), (v), 0 ) \
-		      : nic_bridge_vertex_info((v), (r)) )
-
-#endif /* _ASM_IA64_SN_EEPROM_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/fetchop.h linux-2.4.22-pre3/include/asm-ia64/sn/fetchop.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/fetchop.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/fetchop.h	2003-07-05 18:11:16.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_FETCHOP_H
@@ -39,28 +39,10 @@
 #ifdef __KERNEL__
 
 /*
- * Initialize a FETCHOP line. The argument should point to the beginning
- * of the line.
- * 	SN1 - region mask is in word 0, data in word 1
- * 	SN2 - no region mask. Data in word 0
- */
-#ifdef CONFIG_IA64_SGI_SN1
-#define FETCHOP_INIT_LINE(p)	*(p) = 0xffffffffffffffffUL
-#elif CONFIG_IA64_SGI_SN2
-#define FETCHOP_INIT_LINE(p)
-#endif
-
-/*
- * Convert a region 7 (kaddr) address to the address of the fetchop variable
+ * Convert a region 6 (kaddr) address to the address of the fetchop variable
  */
 #define FETCHOP_KADDR_TO_MSPEC_ADDR(kaddr)	TO_MSPEC(kaddr)
 
-/*
- * Convert a page struct (page) address to the address of the first
- * fetchop variable in the page
- */
-#define FETCHOP_PAGE_TO_MSPEC_ADDR(page)	FETCHOP_KADDR_TO_MSPEC_ADDR(__pa(page_address(page)))
-
 
 /*
  * Each Atomic Memory Operation (AMO formerly known as fetchop)
@@ -80,21 +62,23 @@
  * inconsistency.
  */
 typedef struct {
-
-#ifdef CONFIG_IA64_SGI_SN1
-	u64 permissions;
-#endif
         u64 variable;
-
-#ifdef CONFIG_IA64_SGI_SN1
-        u64 unused[6];
-#else
         u64 unused[7];
-#endif
-
 } AMO_t;
 
 
+/*
+ * The following APIs are externalized to the kernel to allocate/free pages of
+ * fetchop variables.
+ *	fetchop_kalloc_page	- Allocate/initialize 1 fetchop page on the
+ *				  specified cnode. 
+ *	fetchop_kfree_page	- Free a previously allocated fetchop page
+ */
+
+unsigned long fetchop_kalloc_page(int nid);
+void fetchop_kfree_page(unsigned long maddr);
+
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_IA64_SN_FETCHOP_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/gda.h linux-2.4.22-pre3/include/asm-ia64/sn/gda.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/gda.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/gda.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,109 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Derived from IRIX <sys/SN/gda.h>.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- *
- * gda.h -- Contains the data structure for the global data area,
- * 	The GDA contains information communicated between the
- *	PROM, SYMMON, and the kernel. 
- */
-#ifndef _ASM_IA64_SN_GDA_H
-#define _ASM_IA64_SN_GDA_H
-
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn_cpuid.h>
-
-#define GDA_MAGIC	0x58464552
-
-/*
- * GDA Version History
- *
- * Version #	| Change
- * -------------+-------------------------------------------------------
- * 	1	| Initial IP27 version 
- * 	2	| Prom sets g_partid field to the partition number. 0 IS
- *		| a valid partition #. 
- */
-
-#define GDA_VERSION	2	/* Current GDA version # */
-
-#define G_MAGICOFF	0
-#define G_VERSIONOFF	4
-#define G_PROMOPOFF	6
-#define G_MASTEROFF	8
-#define G_VDSOFF	12
-#define G_HKDNORMOFF	16
-#define G_HKDUTLBOFF	24
-#define G_HKDXUTLBOFF	32
-#define G_PARTIDOFF	40
-#define G_TABLEOFF	128
-
-#ifndef __ASSEMBLY__
-
-typedef struct gda {
-	u32	g_magic;	/* GDA magic number */
-	u16	g_version;	/* Version of this structure */
-	u16	g_masterid;	/* The NASID:CPUNUM of the master cpu */
-	u32	g_promop;	/* Passes requests from the kernel to prom */
-	u32	g_vds;		/* Store the virtual dipswitches here */
-	void	**g_hooked_norm;/* ptr to pda loc for norm hndlr */
-	void	**g_hooked_utlb;/* ptr to pda loc for utlb hndlr */
-	void	**g_hooked_xtlb;/* ptr to pda loc for xtlb hndlr */
-	int	g_partid;	/* partition id */
-	int	g_symmax;	/* Max symbols in name table. */
-	void	*g_dbstab;	/* Address of idbg symbol table */
-	char	*g_nametab;	/* Address of idbg name table */
-	void	*g_ktext_repmask;
-				/* Pointer to a mask of nodes with copies
-				 * of the kernel. */
-	char	g_padding[56];	/* pad out to 128 bytes */
-	nasid_t	g_nasidtable[MAX_COMPACT_NODES+1]; /* NASID of each node,
-						  * indexed by cnodeid.
-						  */
-} gda_t;
-
-#define GDA ((gda_t*) GDA_ADDR(get_nasid()))
-
-#endif /* __ASSEMBLY__ */
-/*
- * Define:	PART_GDA_VERSION
- * Purpose:	Define the minimum version of the GDA required, lower 
- *		revisions assume GDA is NOT set up, and read partition
- *		information from the board info.
- */
-#define	PART_GDA_VERSION	2
-
-/*
- * The following requests can be sent to the PROM during startup.
- */
-
-#define PROMOP_MAGIC		0x0ead0000
-#define PROMOP_MAGIC_MASK	0x0fff0000
-
-#define PROMOP_BIST_SHIFT       11
-#define PROMOP_BIST_MASK        (0x3 << 11)
-
-#define PROMOP_REG		PI_ERR_STACK_ADDR_A
-
-#define PROMOP_INVALID		(PROMOP_MAGIC | 0x00)
-#define PROMOP_HALT             (PROMOP_MAGIC | 0x10)
-#define PROMOP_POWERDOWN        (PROMOP_MAGIC | 0x20)
-#define PROMOP_RESTART          (PROMOP_MAGIC | 0x30)
-#define PROMOP_REBOOT           (PROMOP_MAGIC | 0x40)
-#define PROMOP_IMODE            (PROMOP_MAGIC | 0x50)
-
-#define PROMOP_CMD_MASK		0x00f0
-#define PROMOP_OPTIONS_MASK	0xfff0
-
-#define PROMOP_SKIP_DIAGS	0x0100		/* don't bother running diags */
-#define PROMOP_SKIP_MEMINIT	0x0200		/* don't bother initing memory */
-#define PROMOP_SKIP_DEVINIT	0x0400		/* don't bother initing devices */
-#define PROMOP_BIST1		0x0800		/* keep track of which BIST ran */
-#define PROMOP_BIST2		0x1000		/* keep track of which BIST ran */
-
-#endif /* _ASM_IA64_SN_GDA_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/geo.h linux-2.4.22-pre3/include/asm-ia64/sn/geo.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/geo.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/geo.h	2003-07-05 18:11:16.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef __SYS_GEO_H__
@@ -17,15 +17,7 @@
  *   GEO_MAX_LEN:	The maximum length of a geoid, formatted for printing
  */
 
-#include <linux/config.h>
-
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn2/geo.h>
-#else
-
-#error <<BOMB! need geo.h for this platform >>
-
-#endif /* !SN2 && ... */
 
 /* Declarations applicable to all platforms */
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/hack.h linux-2.4.22-pre3/include/asm-ia64/sn/hack.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/hack.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/hack.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,66 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#ifndef _ASM_IA64_SN_HACK_H
-#define _ASM_IA64_SN_HACK_H
-
-#include <asm/sn/types.h>
-#include <asm/uaccess.h>		/* for copy_??_user */
-
-/******************************************
- * Definitions that do not exist in linux *
- ******************************************/
-
-typedef int cred_t;	/* This is for compilation reasons */
-struct cred { int x; };
-
-
-/*
- * Hardware Graph routines that are currently stubbed!
- */
-#include <linux/devfs_fs_kernel.h>
-
-#define DELAY(a)
-
-/************************************************
- * Routines redefined to use linux equivalents. *
- ************************************************/
-
-/* #define FIXME(s) printk("FIXME: [ %s ] in %s at %s:%d\n", s, __FUNCTION__, __FILE__, __LINE__) */
-
-#define FIXME(s)
-
-extern devfs_handle_t dummy_vrtx;
-#define cpuid_to_vertex(cpuid) dummy_vrtx /* (pdaindr[cpuid].pda->p_vertex) */
-
-#define PUTBUF_LOCK(a) { FIXME("PUTBUF_LOCK"); }
-#define PUTBUF_UNLOCK(a) { FIXME("PUTBUF_UNLOCK"); }
-
-typedef int (*splfunc_t)(void);
-
-/* move to stubs.c yet */
-#define dev_to_vhdl(dev) 0
-#define get_timestamp() 0
-#define us_delay(a)
-#define v_mapphys(a,b,c) 0    // printk("Fixme: v_mapphys - soft->base 0x%p\n", b);
-#define splhi()  0
-#define spl7	splhi()
-#define splx(s)
-
-extern void * snia_kmem_alloc_node(register size_t, register int, cnodeid_t);
-extern void * snia_kmem_zalloc(size_t, int);
-extern void * snia_kmem_zalloc_node(register size_t, register int, cnodeid_t );
-extern void * snia_kmem_zone_alloc(register zone_t *, int);
-extern zone_t * snia_kmem_zone_init(register int , char *);
-extern void snia_kmem_zone_free(register zone_t *, void *);
-extern int is_specified(char *);
-extern int cap_able(uint64_t);
-extern int compare_and_swap_ptr(void **, void *, void *);
-
-#endif /* _ASM_IA64_SN_HACK_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/hcl.h linux-2.4.22-pre3/include/asm-ia64/sn/hcl.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/hcl.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/hcl.h	2003-07-05 18:11:16.000000000 -0700
@@ -4,18 +4,15 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_HCL_H
 #define _ASM_IA64_SN_HCL_H
 
 #include <asm/sn/sgi.h>
-#include <asm/sn/invent.h>
-#include <linux/devfs_fs_kernel.h>
 
-extern devfs_handle_t hcl_handle; /* HCL driver */
-extern devfs_handle_t hwgraph_root;
-extern devfs_handle_t linux_busnum;
+extern vertex_hdl_t hwgraph_root;
+extern vertex_hdl_t linux_busnum;
 
 
 typedef long            labelcl_info_place_t;
@@ -58,58 +55,56 @@
 /*
  * External declarations of EXPORTED SYMBOLS in hcl.c
  */
-extern devfs_handle_t hwgraph_register(devfs_handle_t, const char *,
+extern vertex_hdl_t hwgraph_register(vertex_hdl_t, const char *,
 	unsigned int, unsigned int, unsigned int, unsigned int,
 	umode_t, uid_t, gid_t, struct file_operations *, void *);
 
-extern int hwgraph_mk_symlink(devfs_handle_t, const char *, unsigned int,
-	unsigned int, const char *, unsigned int, devfs_handle_t *, void *);
+extern int hwgraph_mk_symlink(vertex_hdl_t, const char *, unsigned int,
+	unsigned int, const char *, unsigned int, vertex_hdl_t *, void *);
 
-extern int hwgraph_vertex_destroy(devfs_handle_t);
+extern int hwgraph_vertex_destroy(vertex_hdl_t);
 
-extern int hwgraph_edge_add(devfs_handle_t, devfs_handle_t, char *);
-extern int hwgraph_edge_get(devfs_handle_t, char *, devfs_handle_t *);
+extern int hwgraph_edge_add(vertex_hdl_t, vertex_hdl_t, char *);
+extern int hwgraph_edge_get(vertex_hdl_t, char *, vertex_hdl_t *);
 
-extern arbitrary_info_t hwgraph_fastinfo_get(devfs_handle_t);
-extern void hwgraph_fastinfo_set(devfs_handle_t, arbitrary_info_t );
-extern devfs_handle_t hwgraph_mk_dir(devfs_handle_t, const char *, unsigned int, void *);
+extern arbitrary_info_t hwgraph_fastinfo_get(vertex_hdl_t);
+extern void hwgraph_fastinfo_set(vertex_hdl_t, arbitrary_info_t );
+extern vertex_hdl_t hwgraph_mk_dir(vertex_hdl_t, const char *, unsigned int, void *);
 
-extern int hwgraph_connectpt_set(devfs_handle_t, devfs_handle_t);
-extern devfs_handle_t hwgraph_connectpt_get(devfs_handle_t);
-extern int hwgraph_edge_get_next(devfs_handle_t, char *, devfs_handle_t *, uint *);
-extern graph_error_t hwgraph_edge_remove(devfs_handle_t, char *, devfs_handle_t *);
+extern int hwgraph_connectpt_set(vertex_hdl_t, vertex_hdl_t);
+extern vertex_hdl_t hwgraph_connectpt_get(vertex_hdl_t);
+extern int hwgraph_edge_get_next(vertex_hdl_t, char *, vertex_hdl_t *, uint *);
+extern graph_error_t hwgraph_edge_remove(vertex_hdl_t, char *, vertex_hdl_t *);
 
-extern graph_error_t hwgraph_traverse(devfs_handle_t, char *, devfs_handle_t *);
+extern graph_error_t hwgraph_traverse(vertex_hdl_t, char *, vertex_hdl_t *);
 
-extern int hwgraph_vertex_get_next(devfs_handle_t *, devfs_handle_t *);
-extern int hwgraph_inventory_get_next(devfs_handle_t, invplace_t *, 
+extern int hwgraph_vertex_get_next(vertex_hdl_t *, vertex_hdl_t *);
+extern int hwgraph_inventory_get_next(vertex_hdl_t, invplace_t *, 
 				      inventory_t **);
-extern int hwgraph_inventory_add(devfs_handle_t, int, int, major_t, minor_t, int);
-extern int hwgraph_inventory_remove(devfs_handle_t, int, int, major_t, minor_t, int);
-extern int hwgraph_controller_num_get(devfs_handle_t);
-extern void hwgraph_controller_num_set(devfs_handle_t, int);
-extern int hwgraph_path_ad(devfs_handle_t, char *, devfs_handle_t *);
-extern devfs_handle_t hwgraph_path_to_vertex(char *);
-extern devfs_handle_t hwgraph_path_to_dev(char *);
-extern devfs_handle_t hwgraph_block_device_get(devfs_handle_t);
-extern devfs_handle_t hwgraph_char_device_get(devfs_handle_t);
-extern graph_error_t hwgraph_char_device_add(devfs_handle_t, char *, char *, devfs_handle_t *);
-extern int hwgraph_path_add(devfs_handle_t, char *, devfs_handle_t *);
-extern int hwgraph_info_add_LBL(devfs_handle_t, char *, arbitrary_info_t);
-extern int hwgraph_info_get_LBL(devfs_handle_t, char *, arbitrary_info_t *);
-extern int hwgraph_info_replace_LBL(devfs_handle_t, char *, arbitrary_info_t,
+extern int hwgraph_inventory_add(vertex_hdl_t, int, int, major_t, minor_t, int);
+extern int hwgraph_inventory_remove(vertex_hdl_t, int, int, major_t, minor_t, int);
+extern int hwgraph_controller_num_get(vertex_hdl_t);
+extern void hwgraph_controller_num_set(vertex_hdl_t, int);
+extern int hwgraph_path_ad(vertex_hdl_t, char *, vertex_hdl_t *);
+extern vertex_hdl_t hwgraph_path_to_vertex(char *);
+extern vertex_hdl_t hwgraph_path_to_dev(char *);
+extern vertex_hdl_t hwgraph_block_device_get(vertex_hdl_t);
+extern vertex_hdl_t hwgraph_char_device_get(vertex_hdl_t);
+extern graph_error_t hwgraph_char_device_add(vertex_hdl_t, char *, char *, vertex_hdl_t *);
+extern int hwgraph_path_add(vertex_hdl_t, char *, vertex_hdl_t *);
+extern int hwgraph_info_add_LBL(vertex_hdl_t, char *, arbitrary_info_t);
+extern int hwgraph_info_get_LBL(vertex_hdl_t, char *, arbitrary_info_t *);
+extern int hwgraph_info_replace_LBL(vertex_hdl_t, char *, arbitrary_info_t,
 				    arbitrary_info_t *);
-extern int hwgraph_info_get_exported_LBL(devfs_handle_t, char *, int *, arbitrary_info_t *);
-extern int hwgraph_info_get_next_LBL(devfs_handle_t, char *, arbitrary_info_t *,
+extern int hwgraph_info_get_exported_LBL(vertex_hdl_t, char *, int *, arbitrary_info_t *);
+extern int hwgraph_info_get_next_LBL(vertex_hdl_t, char *, arbitrary_info_t *,
                                 labelcl_info_place_t *);
-
-extern int hwgraph_path_lookup(devfs_handle_t, char *, devfs_handle_t *, char **);
-extern int hwgraph_info_export_LBL(devfs_handle_t, char *, int);
-extern int hwgraph_info_unexport_LBL(devfs_handle_t, char *);
-extern int hwgraph_info_remove_LBL(devfs_handle_t, char *, arbitrary_info_t *);
-extern char * vertex_to_name(devfs_handle_t, char *, uint);
-extern graph_error_t hwgraph_vertex_unref(devfs_handle_t);
-
+extern int hwgraph_path_lookup(vertex_hdl_t, char *, vertex_hdl_t *, char **);
+extern int hwgraph_info_export_LBL(vertex_hdl_t, char *, int);
+extern int hwgraph_info_unexport_LBL(vertex_hdl_t, char *);
+extern int hwgraph_info_remove_LBL(vertex_hdl_t, char *, arbitrary_info_t *);
+extern char * vertex_to_name(vertex_hdl_t, char *, uint);
+extern graph_error_t hwgraph_vertex_unref(vertex_hdl_t);
 
 
 #endif /* _ASM_IA64_SN_HCL_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/hcl_util.h linux-2.4.22-pre3/include/asm-ia64/sn/hcl_util.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/hcl_util.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/hcl_util.h	2003-07-05 18:11:16.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_HCL_UTIL_H
@@ -12,11 +12,11 @@
 
 #include <linux/devfs_fs_kernel.h>
 
-extern char * dev_to_name(devfs_handle_t, char *, uint);
-extern int device_master_set(devfs_handle_t, devfs_handle_t);
-extern devfs_handle_t device_master_get(devfs_handle_t);
-extern cnodeid_t master_node_get(devfs_handle_t);
-extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t);
-extern void mark_nodevertex_as_node(devfs_handle_t, cnodeid_t);
+extern char * dev_to_name(vertex_hdl_t, char *, uint);
+extern int device_master_set(vertex_hdl_t, vertex_hdl_t);
+extern vertex_hdl_t device_master_get(vertex_hdl_t);
+extern cnodeid_t master_node_get(vertex_hdl_t);
+extern cnodeid_t nodevertex_to_cnodeid(vertex_hdl_t);
+extern void mark_nodevertex_as_node(vertex_hdl_t, cnodeid_t);
 
 #endif /* _ASM_IA64_SN_HCL_UTIL_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/hires_clock.h linux-2.4.22-pre3/include/asm-ia64/sn/hires_clock.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/hires_clock.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/hires_clock.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,52 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- *
- * SGI Hi Resolution Clock
- *
- * SGI SN platforms provide a high resolution clock that is
- * synchronized across all nodes. The clock can be memory mapped
- * and directly read from user space.
- *
- * Access to the clock is thru the following:
- *       (error checking not shown)
- *
- * (Note: should library routines be provided to encapsulate this??)
- *
- *	int		fd:
- *	volatile long	*clk;
- *
- *	fd = open (HIRES_FULLNAME, O_RDONLY);
- *	clk = mmap(0, getpagesize(), PROT_READ, MAP_SHARED, fd, 0);
- *	clk += ioctl(fd, HIRES_IOCQGETOFFSET, 0);
- *
- * At this point, clk is a pointer to the high resolution clock.
- *
- * The clock period can be obtained via:
- *
- *	long	picosec_per_tick;
- *	picosec_per_tick = ioctl(fd, HIRES_IOCQGETPICOSEC, 0);
- */
-
-#ifndef _ASM_IA64_SN_HIRES_CLOCK_H
-#define _ASM_IA64_SN_HIRES_CLOCK_H
-
-
-#define HIRES_BASENAME	"sgi_hires_clock"
-#define HIRES_FULLNAME  "/dev/sgi_hires_clock"
-#define HIRES_IOC_BASE	's'
-
-
-/* Get page offset of hires timer */
-#define HIRES_IOCQGETOFFSET	_IO( HIRES_IOC_BASE, 0 )
-
-/* get clock period in picoseconds per tick */
-#define HIRES_IOCQGETPICOSEC	_IO( HIRES_IOC_BASE, 1 )
-
-/* get number of significant bits in clock counter */
-#define HIRES_IOCQGETCLOCKBITS	_IO( HIRES_IOC_BASE, 2 )
-
-#endif /* _ASM_IA64_SN_HIRES_CLOCK_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/hwgfs.h linux-2.4.22-pre3/include/asm-ia64/sn/hwgfs.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/hwgfs.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ia64/sn/hwgfs.h	2003-07-05 18:11:16.000000000 -0700
@@ -0,0 +1,34 @@
+#ifndef _ASM_IA64_SN_HWGFS_H
+#define _ASM_IA64_SN_HWGFS_H
+
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+typedef struct dentry *hwgfs_handle_t;
+
+extern hwgfs_handle_t hwgfs_register(hwgfs_handle_t dir, const char *name,
+				     unsigned int flags,
+				     unsigned int major, unsigned int minor,
+				     umode_t mode, void *ops, void *info);
+extern int hwgfs_mk_symlink(hwgfs_handle_t dir, const char *name,
+			     unsigned int flags, const char *link,
+			     hwgfs_handle_t *handle, void *info);
+extern hwgfs_handle_t hwgfs_mk_dir(hwgfs_handle_t dir, const char *name,
+				    void *info);
+extern void hwgfs_unregister(hwgfs_handle_t de);
+
+extern hwgfs_handle_t hwgfs_find_handle(hwgfs_handle_t dir, const char *name,
+					unsigned int major,unsigned int minor,
+					char type, int traverse_symlinks);
+extern hwgfs_handle_t hwgfs_get_parent(hwgfs_handle_t de);
+extern int hwgfs_generate_path(hwgfs_handle_t de, char *path, int buflen);
+
+extern void *hwgfs_get_info(hwgfs_handle_t de);
+extern int hwgfs_set_info(hwgfs_handle_t de, void *info);
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/idle.h linux-2.4.22-pre3/include/asm-ia64/sn/idle.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/idle.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/idle.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,54 +0,0 @@
-#ifndef _ASM_IA64_SN_IDLE_H
-#define _ASM_IA64_SN_IDLE_H
-
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/config.h>
-#include <asm/sn/leds.h>
-#include <asm/sn/simulator.h>
-
-static __inline__ void
-snidle(void) {
-
-#ifdef CONFIG_IA64_SGI_AUTOTEST
-	{
-		extern int	autotest_enabled;
-		if (autotest_enabled) {
-			extern void llsc_main(int);
-			llsc_main(smp_processor_id());
-		}
-	}
-#endif
-	
-	if (pda.idle_flag == 0) {
-		/* 
-		 * Turn the activity LED off.
-		 */
-		set_led_bits(0, LED_CPU_ACTIVITY);
-	}
-
-#ifdef CONFIG_IA64_SGI_SN_SIM
-	if (IS_RUNNING_ON_SIMULATOR())
-		SIMULATOR_SLEEP();
-#endif
-
-	pda.idle_flag = 1;
-}
-
-static __inline__ void
-snidleoff(void) {
-	/* 
-	 * Turn the activity LED on.
-	 */
-	set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY);
-
-	pda.idle_flag = 0;
-}
-
-#endif /* _ASM_IA64_SN_IDLE_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/ifconfig_net.h linux-2.4.22-pre3/include/asm-ia64/sn/ifconfig_net.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/ifconfig_net.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/ifconfig_net.h	2003-07-05 18:11:16.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_IFCONFIG_NET_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/intr.h linux-2.4.22-pre3/include/asm-ia64/sn/intr.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/intr.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/intr.h	2003-07-05 18:11:16.000000000 -0700
@@ -4,21 +4,18 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_INTR_H
 #define _ASM_IA64_SN_INTR_H
 
 #include <linux/config.h>
-
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/intr.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/intr.h>
-#endif
 
 extern void sn_send_IPI_phys(long, int, int);
 
-#define CPU_VECTOR_TO_IRQ(cpuid,vector) ((cpuid) << 8 | (vector))
+#define CPU_VECTOR_TO_IRQ(cpuid,vector) (vector)
+#define SN_CPU_FROM_IRQ(irq)	(0)
+#define SN_IVEC_FROM_IRQ(irq)	(irq)
 
 #endif /* _ASM_IA64_SN_INTR_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/intr_public.h linux-2.4.22-pre3/include/asm-ia64/sn/intr_public.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/intr_public.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/intr_public.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,19 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_INTR_PUBLIC_H
-#define _ASM_IA64_SN_INTR_PUBLIC_H
-
-#include <linux/config.h>
-
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/intr_public.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
-#endif
-
-#endif /* _ASM_IA64_SN_INTR_PUBLIC_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/invent.h linux-2.4.22-pre3/include/asm-ia64/sn/invent.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/invent.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/invent.h	2003-07-05 18:11:16.000000000 -0700
@@ -4,14 +4,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_INVENT_H
 #define _ASM_IA64_SN_INVENT_H
 
 #include <linux/types.h>
-#include <linux/devfs_fs_kernel.h>
-
+#include <asm/sn/sgi.h>
 /*
  * sys/sn/invent.h --  Kernel Hardware Inventory
  *
@@ -31,7 +30,7 @@
 #define minor_t int
 #define app32_ptr_t unsigned long
 #define graph_vertex_place_t long
-#define GRAPH_VERTEX_NONE ((devfs_handle_t)-1)
+#define GRAPH_VERTEX_NONE ((vertex_hdl_t)-1)
 #define GRAPH_EDGE_PLACE_NONE ((graph_edge_place_t)0)
 #define GRAPH_INFO_PLACE_NONE ((graph_info_place_t)0)
 #define GRAPH_VERTEX_PLACE_NONE ((graph_vertex_place_t)0)
@@ -713,8 +712,8 @@
 } irix5_inventory_t;
 
 typedef struct invplace_s {
-	devfs_handle_t		invplace_vhdl;		/* current vertex */
-	devfs_handle_t		invplace_vplace;	/* place in vertex list */
+	vertex_hdl_t		invplace_vhdl;		/* current vertex */
+	vertex_hdl_t		invplace_vplace;	/* place in vertex list */
 	inventory_t		*invplace_inv;		/* place in inv list on vertex */
 } invplace_t; /* Magic cookie placeholder in inventory list */
 
@@ -730,7 +729,7 @@
 extern int	    scaninvent(int (*)(inventory_t *, void *), void *);
 extern int	    get_sizeof_inventory(int);
 
-extern void device_inventory_add(	devfs_handle_t device, 
+extern void device_inventory_add(	vertex_hdl_t device, 
 					int class, 
 					int type, 
 					major_t ctlr, 
@@ -738,11 +737,11 @@
 					int state);
 
 
-extern inventory_t *device_inventory_get_next(	devfs_handle_t device,
+extern inventory_t *device_inventory_get_next(	vertex_hdl_t device,
 						invplace_t *);
 
-extern void device_controller_num_set(	devfs_handle_t,
+extern void device_controller_num_set(	vertex_hdl_t,
 					int);
-extern int device_controller_num_get(	devfs_handle_t);
+extern int device_controller_num_get(	vertex_hdl_t);
 #endif /* __KERNEL__ */
 #endif /* _ASM_IA64_SN_INVENT_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/io.h linux-2.4.22-pre3/include/asm-ia64/sn/io.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/io.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/io.h	2003-07-05 18:11:16.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright (C) 2000 Ralf Baechle
  */
 #ifndef _ASM_IA64_SN_IO_H
@@ -56,26 +56,12 @@
 			(_x) : \
 			(_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/sn1/hubio.h>
-#include <asm/sn/sn1/hubio_next.h>
-#include <asm/sn/sn1/hubmd.h>
-#include <asm/sn/sn1/hubmd_next.h>
-#include <asm/sn/sn1/hubpi.h>
-#include <asm/sn/sn1/hubpi_next.h>
-#include <asm/sn/sn1/hublb.h>
-#include <asm/sn/sn1/hublb_next.h>
-#include <asm/sn/sn1/hubni.h>
-#include <asm/sn/sn1/hubni_next.h>
-#include <asm/sn/sn1/hubxb.h>
-#include <asm/sn/sn1/hubxb_next.h>
-#include <asm/sn/sn1/hubstat.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/sn1/synergy.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/shub.h>
 #include <asm/sn/sn2/shubio.h>
-#endif
+
+/*
+ * Used to ensure write ordering (like mb(), but for I/O space)
+ */
+extern void sn_mmiob(void);
 
 #endif /* _ASM_IA64_SN_IO_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/ioc3.h linux-2.4.22-pre3/include/asm-ia64/sn/ioc3.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/ioc3.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/ioc3.h	2003-07-05 18:11:16.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/ioc4.h linux-2.4.22-pre3/include/asm-ia64/sn/ioc4.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/ioc4.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/ioc4.h	2003-07-05 18:11:17.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/ioconfig_bus.h linux-2.4.22-pre3/include/asm-ia64/sn/ioconfig_bus.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/ioconfig_bus.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ia64/sn/ioconfig_bus.h	2003-07-05 18:11:17.000000000 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#define IOCONFIG_PCIBUS "/boot/efi/ioconfig_pcibus"
+#define POUND_CHAR                   '#'
+#define MAX_LINE_LEN	128
+#define MAXPATHLEN	128
+
+struct ioconfig_parm {
+	unsigned long ioconfig_activated;
+        unsigned long number;
+        void *buffer;
+};
+
+struct  ascii_moduleid{
+                unsigned char   io_moduleid[8]; /* pci path name */
+};
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/ioerror.h linux-2.4.22-pre3/include/asm-ia64/sn/ioerror.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/ioerror.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/ioerror.h	2003-07-05 18:11:17.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_IOERROR_H
 #define _ASM_IA64_SN_IOERROR_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/ioerror_handling.h linux-2.4.22-pre3/include/asm-ia64/sn/ioerror_handling.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/ioerror_handling.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/ioerror_handling.h	2003-07-05 18:11:17.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_IOERROR_HANDLING_H
 #define _ASM_IA64_SN_IOERROR_HANDLING_H
@@ -207,26 +207,17 @@
 
 /* Error state interfaces */
 #if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-extern error_return_code_t	error_state_set(devfs_handle_t,error_state_t);
-extern error_state_t		error_state_get(devfs_handle_t);
+extern error_return_code_t	error_state_set(vertex_hdl_t,error_state_t);
+extern error_state_t		error_state_get(vertex_hdl_t);
 #endif
 
-/* System critical graph interfaces */
-
-extern boolean_t		is_sys_critical_vertex(devfs_handle_t);
-extern devfs_handle_t		sys_critical_first_child_get(devfs_handle_t);
-extern devfs_handle_t		sys_critical_next_child_get(devfs_handle_t);
-extern devfs_handle_t		sys_critical_parent_get(devfs_handle_t);
-extern error_return_code_t	sys_critical_graph_vertex_add(devfs_handle_t,
-							     devfs_handle_t new);
-
 /* Error action interfaces */
 
-extern error_return_code_t	error_action_set(devfs_handle_t,
+extern error_return_code_t	error_action_set(vertex_hdl_t,
 						 error_action_f,
 						 error_context_t,
 						 error_priority_t);
-extern error_return_code_t	error_action_perform(devfs_handle_t);
+extern error_return_code_t	error_action_perform(vertex_hdl_t);
 
 
 #define INFO_LBL_ERROR_SKIP_ENV	"error_skip_env"
@@ -243,14 +234,14 @@
 hwgraph_info_remove_LBL(v, INFO_LBL_ERROR_SKIP_ENV, 0)
 
 /* Skip point interfaces */
-extern error_return_code_t	error_skip_point_jump(devfs_handle_t, boolean_t);
-extern error_return_code_t	error_skip_point_clear(devfs_handle_t);
+extern error_return_code_t	error_skip_point_jump(vertex_hdl_t, boolean_t);
+extern error_return_code_t	error_skip_point_clear(vertex_hdl_t);
 
 /* REFERENCED */
 #if defined(CONFIG_SGI_IO_ERROR_HANDLING)
 
 inline static int
-error_skip_point_mark(devfs_handle_t  v)  			 
+error_skip_point_mark(vertex_hdl_t  v)  			 
 {									
 	label_t		*error_env = NULL;	 			
 	int		code = 0;		
@@ -283,10 +274,10 @@
 
 typedef uint64_t		counter_t;
 
-extern counter_t		error_retry_count_get(devfs_handle_t);
-extern error_return_code_t	error_retry_count_set(devfs_handle_t,counter_t);
-extern counter_t		error_retry_count_increment(devfs_handle_t);
-extern counter_t		error_retry_count_decrement(devfs_handle_t);
+extern counter_t		error_retry_count_get(vertex_hdl_t);
+extern error_return_code_t	error_retry_count_set(vertex_hdl_t,counter_t);
+extern counter_t		error_retry_count_increment(vertex_hdl_t);
+extern counter_t		error_retry_count_decrement(vertex_hdl_t);
 
 /* Except for the PIO Read error typically the other errors are handled in
  * the context of an asynchronous error interrupt.
@@ -298,7 +289,7 @@
  * thru the calls the io error handling layer.
  */
 #if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-extern boolean_t		is_device_shutdown(devfs_handle_t);
+extern boolean_t		is_device_shutdown(vertex_hdl_t);
 #define IS_DEVICE_SHUTDOWN(_d) 	(is_device_shutdown(_d))
 #endif
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/iograph.h linux-2.4.22-pre3/include/asm-ia64/sn/iograph.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/iograph.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/iograph.h	2003-07-05 18:11:17.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_IOGRAPH_H
 #define _ASM_IA64_SN_IOGRAPH_H
@@ -77,7 +77,7 @@
 #define EDGE_LBL_IOC3			"ioc3"
 #define EDGE_LBL_LUN                    "lun"
 #define EDGE_LBL_LINUX                  "linux"
-#define EDGE_LBL_LINUX_BUS              EDGE_LBL_LINUX "/busnum"
+#define EDGE_LBL_LINUX_BUS              EDGE_LBL_LINUX "/bus/pci-x"
 #define EDGE_LBL_MACE                   "mace" 		/* O2 mace */
 #define EDGE_LBL_MACHDEP                "machdep"       /* Platform depedent devices */
 #define EDGE_LBL_MASTER			".master"
@@ -127,8 +127,12 @@
 #define EDGE_LBL_XBOX_RPS               "xbox_rps"      /* redundant power supply for xbox unit */ 
 #define EDGE_LBL_IOBRICK		"iobrick"
 #define EDGE_LBL_PBRICK			"Pbrick"
+#define EDGE_LBL_PEBRICK		"PEbrick"
+#define EDGE_LBL_PXBRICK		"PXbrick"
+#define EDGE_LBL_IXBRICK		"IXbrick"
 #define EDGE_LBL_IBRICK			"Ibrick"
 #define EDGE_LBL_XBRICK			"Xbrick"
+#define EDGE_LBL_CGBRICK		"CGbrick"
 #define EDGE_LBL_CPUBUS			"cpubus"	/* CPU Interfaces (SysAd) */
 
 /* vertex info labels in hwgraph */
@@ -211,7 +215,7 @@
 #include <asm/sn/xtalk/xbow.h>	/* For get MAX_PORT_NUM */
 
 int io_brick_map_widget(int, int);
-int io_path_map_widget(devfs_handle_t);
+int io_path_map_widget(vertex_hdl_t);
 
 /*
  * Map a brick's widget number to a meaningful int
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/klclock.h linux-2.4.22-pre3/include/asm-ia64/sn/klclock.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/klclock.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/klclock.h	2003-07-05 18:11:17.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1996, 2001-2003 Silicon Graphics, Inc. All rights reserved.
  * Copyright (C) 2001 by Ralf Baechle
  */
 #ifndef _ASM_IA64_SN_KLCLOCK_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/klconfig.h linux-2.4.22-pre3/include/asm-ia64/sn/klconfig.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/klconfig.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/klconfig.h	2003-07-05 18:11:17.000000000 -0700
@@ -6,7 +6,7 @@
  *
  * Derived from IRIX <sys/SN/klconfig.h>.
  *
- * Copyright (C) 1992-1997,1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997,1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright (C) 1999 by Ralf Baechle
  */
 #ifndef _ASM_IA64_SN_KLCONFIG_H
@@ -46,18 +46,8 @@
 #include <asm/sn/xtalk/xtalk.h>
 #include <asm/sn/kldir.h>
 #include <asm/sn/sn_fru.h>
-
-#ifdef CONFIG_IA64_SGI_SN1
-#include <asm/sn/sn1/hubmd_next.h>
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn2/shub_md.h>
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/geo.h>
-#endif
 
 #define KLCFGINFO_MAGIC	0xbeedbabe
 
@@ -273,7 +263,7 @@
  * Each BOARD consists of COMPONENTs and the BOARD structure has 
  * pointers (offsets) to its COMPONENT structure.
  * The COMPONENT structure has version info, size and speed info, revision,
- * error info and the NIC info. This structure can accomodate any
+ * error info and the NIC info. This structure can accommodate any
  * BOARD with arbitrary COMPONENT composition.
  *
  * The ERRORINFO part of each BOARD has error information
@@ -398,6 +388,12 @@
 #define KLTYPE_IBRICK		(KLCLASS_IOBRICK | 0x1)
 #define KLTYPE_PBRICK		(KLCLASS_IOBRICK | 0x2)
 #define KLTYPE_XBRICK		(KLCLASS_IOBRICK | 0x3)
+#define KLTYPE_NBRICK		(KLCLASS_IOBRICK | 0x4)
+#define KLTYPE_PEBRICK		(KLCLASS_IOBRICK | 0x5)
+#define KLTYPE_PXBRICK		(KLCLASS_IOBRICK | 0x6)
+#define KLTYPE_IXBRICK		(KLCLASS_IOBRICK | 0x7)
+#define KLTYPE_CGBRICK		(KLCLASS_IOBRICK | 0x8)
+
 
 #define KLTYPE_PBRICK_BRIDGE	KLTYPE_PBRICK
 
@@ -437,11 +433,7 @@
  	unsigned char 	brd_flags;        /* Enabled, Disabled etc */
 	unsigned char 	brd_slot;         /* slot number */
 	unsigned short	brd_debugsw;      /* Debug switches */
-#ifdef CONFIG_IA64_SGI_SN2
 	geoid_t		brd_geoid;	  /* geo id */
-#else
-	moduleid_t	brd_module;       /* module to which it belongs */
-#endif
 	partid_t 	brd_partition;    /* Partition number */
         unsigned short 	brd_diagval;      /* diagnostic value */
         unsigned short 	brd_diagparm;     /* diagnostic parameter */
@@ -452,13 +444,11 @@
 	klconf_off_t 	brd_compts[MAX_COMPTS_PER_BRD]; /* pointers to COMPONENTS */
 	klconf_off_t 	brd_errinfo;      /* Board's error information */
 	struct lboard_s *brd_parent;	  /* Logical parent for this brd */
-	devfs_handle_t	brd_graph_link;   /* vertex hdl to connect extern compts */
+	vertex_hdl_t	brd_graph_link;   /* vertex hdl to connect extern compts */
 	confidence_t	brd_confidence;	  /* confidence that the board is bad */
 	nasid_t		brd_owner;        /* who owns this board */
 	unsigned char 	brd_nic_flags;    /* To handle 8 more NICs */
-#ifdef CONFIG_IA64_SGI_SN2
 	char		pad[32];	  /* future expansion */
-#endif
 	char		brd_name[32];
 } lboard_t;
 
@@ -491,7 +481,8 @@
         ((_brd)->brd_next ?     \
          (NODE_OFFSET_TO_LBOARD(NASID_GET(_brd), (_brd)->brd_next)): NULL)
 #define KLCF_COMP(_brd, _ndx)   \
-                (NODE_OFFSET_TO_KLINFO(NASID_GET(_brd), (_brd)->brd_compts[(_ndx)]))
+                ((((_brd)->brd_compts[(_ndx)]) == 0) ? 0 : \
+			(NODE_OFFSET_TO_KLINFO(NASID_GET(_brd), (_brd)->brd_compts[(_ndx)])))
 
 #define KLCF_COMP_ERROR(_brd, _comp)    \
                 (NODE_OFFSET_TO_K0(NASID_GET(_brd), (_comp)->errinfo))
@@ -626,9 +617,7 @@
 	nasid_t		port_nasid;
 	unsigned char	port_flag;
 	klconf_off_t	port_offset;
-#ifdef CONFIG_IA64_SGI_SN2
 	short		port_num;
-#endif
 } klport_t;
 
 typedef struct klcpu_s {                          /* CPU */
@@ -638,9 +627,7 @@
     	unsigned short 	cpu_speed;	/* Speed in MHZ */
     	unsigned short 	cpu_scachesz;	/* secondary cache size in MB */
     	unsigned short 	cpu_scachespeed;/* secondary cache speed in MHz */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klcpu_t ;
 
 #define CPU_STRUCT_VERSION   2
@@ -648,28 +635,20 @@
 typedef struct klhub_s {			/* HUB */
 	klinfo_t 	hub_info;
 	uint 		hub_flags;		/* PCFG_HUB_xxx flags */
-#ifdef CONFIG_IA64_SGI_SN2
 #define MAX_NI_PORTS                    2
 	klport_t	hub_port[MAX_NI_PORTS + 1];/* hub is connected to this */
-#else
-	klport_t	hub_port;		/* hub is connected to this */
-#endif
 	nic_t		hub_box_nic;		/* nic of containing box */
 	klconf_off_t	hub_mfg_nic;		/* MFG NIC string */
 	u64		hub_speed;		/* Speed of hub in HZ */
-#ifdef CONFIG_IA64_SGI_SN2
 	moduleid_t	hub_io_module;		/* attached io module */
 	unsigned long	pad;
-#endif
 } klhub_t ;
 
 typedef struct klhub_uart_s {			/* HUB */
 	klinfo_t 	hubuart_info;
 	uint 		hubuart_flags;		/* PCFG_HUB_xxx flags */
 	nic_t		hubuart_box_nic;	/* nic of containing box */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klhub_uart_t ;
 
 #define MEMORY_STRUCT_VERSION   2
@@ -680,9 +659,7 @@
 	short		membnk_dimm_select; /* bank to physical addr mapping*/
 	short		membnk_bnksz[MD_MEM_BANKS]; /* Memory bank sizes */
 	short		membnk_attr;
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klmembnk_t ;
 
 #define KLCONFIG_MEMBNK_SIZE(_info, _bank)	\
@@ -701,9 +678,7 @@
               char snum_str[MAX_SERIAL_NUM_SIZE];
               unsigned long long       snum_int;
       } snum;
-#ifdef CONFIG_IA64_SGI_SN2
       unsigned long   pad;
-#endif
 } klmod_serial_num_t;
 
 /* Macros needed to access serial number structure in lboard_t.
@@ -721,9 +696,7 @@
     	klport_t	xbow_port_info[MAX_XBOW_LINKS] ; /* Module number */
         int		xbow_master_hub_link;
         /* type of brd connected+component struct ptr+flags */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klxbow_t ;
 
 #define MAX_PCI_SLOTS 8
@@ -742,9 +715,7 @@
     	pci_t    	pci_specific  ;    /* PCI Board config info */
 	klpci_device_t	bri_devices[MAX_PCI_DEVS] ;	/* PCI IDs */
 	klconf_off_t	bri_mfg_nic ;
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klbri_t ;
 
 #define MAX_IOC3_TTY	2
@@ -758,9 +729,7 @@
 	klinfo_t	ioc3_enet ;
 	klconf_off_t	ioc3_enet_off ;
 	klconf_off_t	ioc3_kbd_off ;
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klioc3_t ;
 
 #define MAX_VME_SLOTS 8
@@ -769,18 +738,14 @@
 	klinfo_t 	vmeb_info ;
 	vmeb_t		vmeb_specific ;
     	klconf_off_t   	vmeb_brdinfo[MAX_VME_SLOTS]   ;    /* VME Board config info */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klvmeb_t ;
 
 typedef struct klvmed_s {                          /* VME DEVICE - VME BOARD */
 	klinfo_t	vmed_info ;
 	vmed_t		vmed_specific ;
     	klconf_off_t   	vmed_brdinfo[MAX_VME_SLOTS]   ;    /* VME Board config info */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klvmed_t ;
 
 #define ROUTER_VECTOR_VERS	2
@@ -793,9 +758,7 @@
     	klport_t 	rou_port[MAX_ROUTER_PORTS + 1] ; /* array index 1 to 6 */
 	klconf_off_t	rou_mfg_nic ;     /* MFG NIC string */
 	u64	rou_vector;	  /* vector from master node */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long   pad;
-#endif
 } klrou_t ;
 
 /*
@@ -820,25 +783,19 @@
 	graphics_t	gfx_specific;
 	klconf_off_t    pad0;		/* for compatibility with older proms */
 	klconf_off_t    gfx_mfg_nic;
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klgfx_t;
 
 typedef struct klxthd_s {   
 	klinfo_t 	xthd_info ;
 	klconf_off_t	xthd_mfg_nic ;        /* MFG NIC string */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klxthd_t ;
 
 typedef struct kltpu_s {                     /* TPU board */
 	klinfo_t 	tpu_info ;
 	klconf_off_t	tpu_mfg_nic ;        /* MFG NIC string */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } kltpu_t ;
 
 typedef struct klgsn_s {                     /* GSN board */
@@ -860,9 +817,7 @@
     	scsi_t       	scsi_specific   ; 
 	unsigned char 	scsi_numdevs ;
 	klconf_off_t	scsi_devinfo[MAX_SCSI_DEVS] ; 
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klscsi_t ;
 
 typedef struct klscctl_s {                          /* SCSI Controller */
@@ -870,49 +825,37 @@
 	uint		type;
 	uint		scsi_buscnt;                        /* # busses this cntlr */
 	void		*scsi_bus[2];                       /* Pointer to 2 klscsi_t's */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klscctl_t ;
 
 typedef struct klscdev_s {                          /* SCSI device */
 	klinfo_t 	scdev_info ;
 	struct scsidisk_data *scdev_cfg ; /* driver fills up this */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klscdev_t ;
 
 typedef struct klttydev_s {                          /* TTY device */
 	klinfo_t 	ttydev_info ;
 	struct terminal_data *ttydev_cfg ; /* driver fills up this */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klttydev_t ;
 
 typedef struct klenetdev_s {                          /* ENET device */
 	klinfo_t 	enetdev_info ;
 	struct net_data *enetdev_cfg ; /* driver fills up this */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klenetdev_t ;
 
 typedef struct klkbddev_s {                          /* KBD device */
 	klinfo_t 	kbddev_info ;
 	struct keyboard_data *kbddev_cfg ; /* driver fills up this */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klkbddev_t ;
 
 typedef struct klmsdev_s {                          /* mouse device */
         klinfo_t        msdev_info ;
         void 		*msdev_cfg ; 
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klmsdev_t ;
 
 #define MAX_FDDI_DEVS 10 /* XXX Is this true */
@@ -921,17 +864,13 @@
 	klinfo_t 	fddi_info ;
     	fddi_t        	fddi_specific ;       
 	klconf_off_t	fddi_devinfo[MAX_FDDI_DEVS] ;
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klfddi_t ;
 
 typedef struct klmio_s {                          /* MIO */
 	klinfo_t 	mio_info ;
     	mio_t       	mio_specific   ; 
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klmio_t ;
 
 /*
@@ -942,9 +881,7 @@
 	klinfo_t	usb_info;	/* controller info */
 	void		*usb_bus;	/* handle to usb_bus_t */
 	uint64_t	usb_controller;	/* ptr to controller info */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klusb_t ; 
 
 typedef union klcomp_s {
@@ -1028,37 +965,18 @@
 extern klcpu_t *nasid_slice_to_cpuinfo(nasid_t, int);
 
 
-extern xwidgetnum_t nodevertex_widgetnum_get(devfs_handle_t node_vtx);
-extern devfs_handle_t nodevertex_xbow_peer_get(devfs_handle_t node_vtx);
 extern lboard_t *find_gfxpipe(int pipenum);
-extern void setup_gfxpipe_link(devfs_handle_t vhdl,int pipenum);
 extern lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_class);
-#ifdef CONFIG_IA64_SGI_SN2
-extern lboard_t *find_lboard_module_class(lboard_t *start, geoid_t geoid,
-						unsigned char brd_class);
-#else
-extern lboard_t *find_lboard_module_class(lboard_t *start, moduleid_t mod,
-                                               unsigned char brd_class);
-#endif
 extern lboard_t *find_nic_lboard(lboard_t *, nic_t);
 extern lboard_t *find_nic_type_lboard(nasid_t, unsigned char, nic_t);
-#ifdef CONFIG_IA64_SGI_SN2
 extern lboard_t *find_lboard_modslot(lboard_t *start, geoid_t geoid);
 extern lboard_t *find_lboard_module(lboard_t *start, geoid_t geoid);
-extern lboard_t *get_board_name(nasid_t nasid, geoid_t geoid, slotid_t slot, char *name);
-#else
-extern lboard_t *find_lboard_modslot(lboard_t *start, moduleid_t mod, slotid_t slot);
-extern lboard_t *find_lboard_module(lboard_t *start, moduleid_t mod);
-extern lboard_t *get_board_name(nasid_t nasid, moduleid_t mod, slotid_t slot, char *name);
-#endif
 extern int	config_find_nic_router(nasid_t, nic_t, lboard_t **, klrou_t**);
 extern int	config_find_nic_hub(nasid_t, nic_t, lboard_t **, klhub_t**);
 extern int	config_find_xbow(nasid_t, lboard_t **, klxbow_t**);
 extern int 	update_klcfg_cpuinfo(nasid_t, int);
 extern void 	board_to_path(lboard_t *brd, char *path);
-#ifdef CONFIG_IA64_SGI_SN2
 extern moduleid_t get_module_id(nasid_t nasid);
-#endif
 extern void 	nic_name_convert(char *old_name, char *new_name);
 extern int 	module_brds(nasid_t nasid, lboard_t **module_brds, int n);
 extern lboard_t *brd_from_key(uint64_t key);
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/kldir.h linux-2.4.22-pre3/include/asm-ia64/sn/kldir.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/kldir.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/kldir.h	2003-07-05 18:11:17.000000000 -0700
@@ -5,7 +5,7 @@
  *
  * Derived from IRIX <sys/SN/kldir.h>, revision 1.21.
  *
- * Copyright (C) 1992-1997,1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997,1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright (C) 1999 by Ralf Baechle
  */
 #ifndef _ASM_IA64_SN_KLDIR_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/ksys/elsc.h linux-2.4.22-pre3/include/asm-ia64/sn/ksys/elsc.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/ksys/elsc.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/ksys/elsc.h	2003-07-05 18:11:17.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_KSYS_ELSC_H
 #define _ASM_SN_KSYS_ELSC_H
@@ -12,82 +12,6 @@
 #include <linux/config.h>
 #include <asm/sn/ksys/l1.h>
 
-#ifdef CONFIG_IA64_SGI_SN1
-
-#define ELSC_ACP_MAX		86		/* 84+cr+lf */
-#define ELSC_LINE_MAX		(ELSC_ACP_MAX - 2)
-
-typedef sc_cq_t elsc_cq_t;
-
-/*
- * ELSC structure passed around as handle
- */
-
-typedef l1sc_t elsc_t;
-
-void	elsc_init(elsc_t *e, nasid_t nasid);
-
-int	elsc_process(elsc_t *e);
-int	elsc_msg_check(elsc_t *e, char *msg, int msg_max);
-int	elsc_msg_callback(elsc_t *e,
-			  void (*callback)(void *callback_data, char *msg),
-			  void *callback_data);
-char   *elsc_errmsg(int code);
-
-int	elsc_nvram_write(elsc_t *e, int addr, char *buf, int len);
-int	elsc_nvram_read(elsc_t *e, int addr, char *buf, int len);
-int	elsc_nvram_magic(elsc_t *e);
-int	elsc_command(elsc_t *e, int only_if_message);
-int	elsc_parse(elsc_t *e, char *p1, char *p2, char *p3);
-int	elsc_ust_write(elsc_t *e, uchar_t c);
-int 	elsc_ust_read(elsc_t *e, char *c);
-
-
-
-/*
- * System controller commands
- */
-
-int	elsc_version(elsc_t *e, char *result);
-int	elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2);
-int	elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2);
-int	elsc_module_set(elsc_t *e, int module);
-int	elsc_module_get(elsc_t *e);
-int	elsc_partition_set(elsc_t *e, int partition);
-int	elsc_partition_get(elsc_t *e);
-int	elsc_domain_set(elsc_t *e, int domain);
-int	elsc_domain_get(elsc_t *e);
-int	elsc_cluster_set(elsc_t *e, int cluster);
-int	elsc_cluster_get(elsc_t *e);
-int	elsc_cell_set(elsc_t *e, int cell);
-int	elsc_cell_get(elsc_t *e);
-int	elsc_bist_set(elsc_t *e, char bist_status);
-char	elsc_bist_get(elsc_t *e);
-int	elsc_lock(elsc_t *e, int retry_interval_usec, int timeout_usec, u_char lock_val);
-int	elsc_unlock(elsc_t *e);
-int	elsc_display_char(elsc_t *e, int led, int chr);
-int	elsc_display_digit(elsc_t *e, int led, int num, int l_case);
-int	elsc_display_mesg(elsc_t *e, char *chr);	/* 8-char input */
-int	elsc_password_set(elsc_t *e, char *password);	/* 4-char input */
-int	elsc_password_get(elsc_t *e, char *password);	/* 4-char output */
-int	elsc_rpwr_query(elsc_t *e, int is_master);
-int	elsc_power_query(elsc_t *e);
-int	elsc_power_down(elsc_t *e, int sec);
-int	elsc_power_cycle(elsc_t *e);
-int	elsc_system_reset(elsc_t *e);
-int	elsc_dip_switches(elsc_t *e);
-
-int	_elsc_hbt(elsc_t *e, int ival, int rdly);
-
-#define	elsc_hbt_enable(e, ival, rdly)	_elsc_hbt(e, ival, rdly)
-#define	elsc_hbt_disable(e)		_elsc_hbt(e, 0, 0)
-#define	elsc_hbt_send(e)		_elsc_hbt(e, 0, 1)
-
-elsc_t	       *get_elsc(void);
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-
 /*
  * Error codes
  *
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/ksys/l1.h linux-2.4.22-pre3/include/asm-ia64/sn/ksys/l1.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/ksys/l1.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/ksys/l1.h	2003-07-05 18:11:18.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #ifndef _ASM_SN_KSYS_L1_H
@@ -16,162 +16,6 @@
 #include <asm/atomic.h>
 #include <asm/sn/sv.h>
 
-
-#ifdef CONFIG_IA64_SGI_SN1
-
-#define BRL1_QSIZE	128	/* power of 2 is more efficient */
-#define BRL1_BUFSZ	264	/* needs to be large enough
-				 * to hold 2 flags, escaped
-				 * CRC, type/subchannel byte,
-				 * and escaped payload
-				 */
-
-#define BRL1_IQS          32
-#define BRL1_OQS          4
-
-
-typedef struct sc_cq_s {
-    u_char              buf[BRL1_QSIZE];
-    int                 ipos, opos, tent_next;
-} sc_cq_t;
-
-/* An l1sc_t struct can be associated with the local (C-brick) L1 or an L1
- * on an R-brick.  In the R-brick case, the l1sc_t records a vector path
- * to the R-brick's junk bus UART.  In the C-brick case, we just use the
- * following flag to denote the local uart.
- *
- * This value can't be confused with a network vector because the least-
- * significant nibble of a network vector cannot be greater than 8.
- */
-#define BRL1_LOCALHUB_UART	((net_vec_t)0xf)
-
-/* L1<->Bedrock reserved subchannels */
-
-/* console channels */
-#define SC_CONS_CPU0    0x00
-#define SC_CONS_CPU1    0x01
-#define SC_CONS_CPU2    0x02
-#define SC_CONS_CPU3    0x03
-
-#define L1_ELSCUART_SUBCH(p)	(p)
-#define L1_ELSCUART_CPU(ch)	(ch)
-
-#define SC_CONS_SYSTEM  CPUS_PER_NODE
-
-/* mapping subchannels to queues */
-#define MAP_IQ(s)       (s)
-#define MAP_OQ(s)       (s)
-     
-#define BRL1_NUM_SUBCHANS 32
-#define BRL1_CMD_SUBCH	  16
-#define BRL1_EVENT_SUBCH  (BRL1_NUM_SUBCHANS - 1)
-#define BRL1_SUBCH_RSVD   0
-#define BRL1_SUBCH_FREE   (-1)
-
-/* constants for L1 hwgraph vertex info */
-#define CBRICK_L1	(__psint_t)1
-#define IOBRICK_L1	(__psint_t)2
-#define RBRICK_L1	(__psint_t)3
-
-
-struct l1sc_s;     
-/* Saved off interrupt frame */
-typedef struct brl1_intr_frame {
-	int bf_irq;		/* irq received */
-	void *bf_dev_id;	/* device information */
-	struct pt_regs *bf_regs; /* register frame */
-} brl1_intr_frame_t;
-
-typedef void (*brl1_notif_t)(int, void *, struct pt_regs *, struct l1sc_s *, int);
-typedef int  (*brl1_uartf_t)(struct l1sc_s *);
-
-/* structure for controlling a subchannel */
-typedef struct brl1_sch_s {
-    int		use;		/* if this subchannel is free,
-				 * use == BRL1_SUBCH_FREE */
-    uint	target;		/* type, rack and slot of component to
-				 * which this subchannel is directed */
-    atomic_t	packet_arrived; /* true if packet arrived on
-				 * this subchannel */
-    sc_cq_t *	iqp;		/* input queue for this subchannel */
-    sv_t	arrive_sv;	/* used to wait for a packet */
-    spinlock_t	data_lock;	/* synchronize access to input queues and
-				 * other fields of the brl1_sch_s struct */
-    brl1_notif_t tx_notify;     /* notify higher layer that transmission may 
-				 * continue */
-    brl1_notif_t rx_notify;	/* notify higher layer that a packet has been
-				 * received */
-    brl1_intr_frame_t irq_frame; /* saved off irq information */
-} brl1_sch_t;
-
-/* br<->l1 protocol states */
-#define BRL1_IDLE	0
-#define BRL1_FLAG	1
-#define BRL1_HDR	2
-#define BRL1_BODY	3
-#define BRL1_ESC	4
-#define BRL1_RESET	7
-
-
-/*
- * l1sc_t structure-- tracks protocol state, open subchannels, etc.
- */
-typedef struct l1sc_s {
-    nasid_t	 nasid;		/* nasid with which this instance
-				 * of the structure is associated */
-    moduleid_t	 modid;         /* module id of this brick */
-    u_char	 verbose;	/* non-zero if elscuart routines should
-				 * prefix output */
-    net_vec_t    uart;		/* vector path to UART, or BRL1_LOCALUART */
-    int		 sent;		/* number of characters sent */
-    int		 send_len;	/* number of characters in send buf */
-    brl1_uartf_t putc_f;	/* pointer to UART putc function */
-    brl1_uartf_t getc_f;	/* pointer to UART getc function */
-
-    spinlock_t   send_lock;     /* arbitrates send synchronization */
-    spinlock_t   recv_lock;     /* arbitrates uart receive access */
-    spinlock_t	 subch_lock;	/* arbitrates subchannel allocation */
-    cpuid_t	 intr_cpu;	/* cpu that receives L1 interrupts */
-
-    u_char	 send_in_use;	/* non-zero if send buffer contains an
-				 * unsent or partially-sent  packet */
-    u_char	 fifo_space;	/* current depth of UART send FIFO */
-
-    u_char	 brl1_state;	/* current state of the receive side */
-    u_char	 brl1_last_hdr;	/* last header byte received */
-
-    char	 send[BRL1_BUFSZ]; /* send buffer */
-
-    int		 sol;		/* "start of line" (see elscuart routines) */
-    int		 cons_listen;	/* non-zero if the elscuart interface should
-				 * also check the system console subchannel */
-    brl1_sch_t	 subch[BRL1_NUM_SUBCHANS];
-    				/* subchannels provided by link */
-
-    sc_cq_t	 garbage_q;	/* a place to put unsolicited packets */
-    sc_cq_t	 oq[BRL1_OQS];	/* elscuart output queues */
-} l1sc_t;
-
-
-/* error codes */
-#define BRL1_VALID	  0
-#define BRL1_FULL_Q	(-1)
-#define BRL1_CRC	(-2)
-#define BRL1_PROTOCOL	(-3)
-#define BRL1_NO_MESSAGE	(-4)
-#define BRL1_LINK	(-5)
-#define BRL1_BUSY	(-6)
-
-#define SC_SUCCESS      BRL1_VALID
-#define SC_NMSG         BRL1_NO_MESSAGE
-#define SC_BUSY         BRL1_BUSY
-#define SC_NOPEN        (-7)
-#define SC_BADSUBCH     (-8)
-#define SC_TIMEDOUT	(-9)
-#define SC_NSUBCH	(-10)
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
 /* L1 Target Addresses */
 /*
  * L1 commands and responses use source/target addresses that are
@@ -181,39 +25,11 @@
  * id (L1 functionality is divided into several independent "tasks"
  * that can each receive command requests and transmit responses)
  */
-#ifdef CONFIG_IA64_SGI_SN1
-#define L1_ADDR_TYPE_SHFT	28
-#define L1_ADDR_TYPE_MASK	0xF0000000
-#else
-#define L1_ADDR_TYPE_SHFT	8
-#define L1_ADDR_TYPE_MASK	0xFF00
-#endif	/* CONFIG_IA64_SGI_SN1 */
 #define L1_ADDR_TYPE_L1		0x00	/* L1 system controller */
 #define L1_ADDR_TYPE_L2		0x01	/* L2 system controller */
 #define L1_ADDR_TYPE_L3		0x02	/* L3 system controller */
 #define L1_ADDR_TYPE_CBRICK	0x03	/* attached C brick	*/
 #define L1_ADDR_TYPE_IOBRICK	0x04	/* attached I/O brick	*/
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define L1_ADDR_RACK_SHFT	18
-#define L1_ADDR_RACK_MASK	0x0FFC0000
-#define	L1_ADDR_RACK_LOCAL	0x3ff	/* local brick's rack	*/
-#else
-#define L1_ADDR_RACK_SHFT	16
-#define L1_ADDR_RACK_MASK	0xFFFF00
-#define	L1_ADDR_RACK_LOCAL	0xffff	/* local brick's rack	*/
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define L1_ADDR_BAY_SHFT	12
-#define L1_ADDR_BAY_MASK	0x0003F000
-#define	L1_ADDR_BAY_LOCAL	0x3f	/* local brick's bay	*/
-#else
-#define L1_ADDR_BAY_SHFT	0
-#define L1_ADDR_BAY_MASK	0xFF
-#define	L1_ADDR_BAY_LOCAL	0xff	/* local brick's bay	*/
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
 #define L1_ADDR_TASK_SHFT	0
 #define L1_ADDR_TASK_MASK	0x0000001F
 #define L1_ADDR_TASK_INVALID	0x00	/* invalid task 	*/
@@ -296,7 +112,9 @@
 #define L1_BRICKTYPE_X          0x58            /* X */
 #define L1_BRICKTYPE_X2         0x59            /* Y */
 #define L1_BRICKTYPE_N          0x4e            /* N */
+#define L1_BRICKTYPE_PE		0x25		/* % */
 #define L1_BRICKTYPE_PX		0x23		/* # */
+#define L1_BRICKTYPE_IX		0x3d		/* = */
 
 /* EEPROM codes (for the "read EEPROM" request) */
 /* c brick */
@@ -339,50 +157,10 @@
 
 #define bzero(d, n)	memset((d), 0, (n))
 
-#ifdef CONFIG_IA64_SGI_SN1
-
-#define SC_EVENT_CLASS_MASK ((unsigned short)0xff00)
-
-/* public interfaces to L1 system controller */
-
-int	sc_open( l1sc_t *sc, uint target );
-int	sc_close( l1sc_t *sc, int ch );
-int	sc_construct_msg( l1sc_t *sc, int ch, 
-			  char *msg, int msg_len,
-			  uint addr_task, short req_code,
-			  int req_nargs, ... );
-int	sc_interpret_resp( char *resp, int resp_nargs, ... );
-int	sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait );
-int	sc_recv( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block );
-int	sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len );
-int	sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len );
-int	sc_poll( l1sc_t *sc, int ch );
-void	sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart );
-void	sc_intr_enable( l1sc_t *sc );
-
-int	elsc_rack_bay_get(l1sc_t *e, uint *rack, uint *bay);
-int	elsc_rack_bay_type_get(l1sc_t *e, uint *rack, 
-			       uint *bay, uint *brick_type);
-int	elsc_cons_subch(l1sc_t *e, uint ch);
-int	elsc_cons_node(l1sc_t *e);
-int	elsc_display_line(l1sc_t *e, char *line, int lnum);
-
-extern l1sc_t *get_elsc( void );
-#define get_l1sc	get_elsc
-#define get_master_l1sc get_l1sc
-
-int	iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack,
-				   uint *bay, uint *brick_type );
-int	iobrick_module_get( l1sc_t *sc );
-int	iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up );
-int	iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up );
-int	iobrick_sc_version( l1sc_t *sc, char *result );
-#else
 int	elsc_display_line(nasid_t nasid, char *line, int lnum);
 int	iobrick_rack_bay_type_get( nasid_t nasid, uint *rack,
 				   uint *bay, uint *brick_type );
 int	iobrick_module_get( nasid_t nasid );
-#endif	/* CONFIG_IA64_SGI_SN1 */
 
 
 #endif /* _ASM_SN_KSYS_L1_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/labelcl.h linux-2.4.22-pre3/include/asm-ia64/sn/labelcl.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/labelcl.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/labelcl.h	2003-07-05 18:11:18.000000000 -0700
@@ -4,13 +4,11 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_LABELCL_H
 #define _ASM_IA64_SN_LABELCL_H
 
-#include <asm/sn/hcl.h>
-
 #define LABELCL_MAGIC 0x4857434c	/* 'HWLC' */
 #define LABEL_LENGTH_MAX 256		/* Includes NULL char */
 #define INFO_DESC_PRIVATE (-1)      	/* default */
@@ -77,18 +75,18 @@
 
 extern labelcl_info_t *labelcl_info_create(void);
 extern int labelcl_info_destroy(labelcl_info_t *);
-extern int labelcl_info_add_LBL(struct devfs_entry *, char *, arb_info_desc_t, arbitrary_info_t);
-extern int labelcl_info_remove_LBL(struct devfs_entry *, char *, arb_info_desc_t *, arbitrary_info_t *);
-extern int labelcl_info_replace_LBL(struct devfs_entry *, char *, arb_info_desc_t,
+extern int labelcl_info_add_LBL(vertex_hdl_t, char *, arb_info_desc_t, arbitrary_info_t);
+extern int labelcl_info_remove_LBL(vertex_hdl_t, char *, arb_info_desc_t *, arbitrary_info_t *);
+extern int labelcl_info_replace_LBL(vertex_hdl_t, char *, arb_info_desc_t,
                         arbitrary_info_t, arb_info_desc_t *, arbitrary_info_t *);
-extern int labelcl_info_get_LBL(struct devfs_entry *, char *, arb_info_desc_t *,
+extern int labelcl_info_get_LBL(vertex_hdl_t, char *, arb_info_desc_t *,
                       arbitrary_info_t *);
-extern int labelcl_info_get_next_LBL(struct devfs_entry *, char *, arb_info_desc_t *,
+extern int labelcl_info_get_next_LBL(vertex_hdl_t, char *, arb_info_desc_t *,
                            arbitrary_info_t *, labelcl_info_place_t *);
-extern int labelcl_info_replace_IDX(struct devfs_entry *, int, arbitrary_info_t, 
+extern int labelcl_info_replace_IDX(vertex_hdl_t, int, arbitrary_info_t, 
 			arbitrary_info_t *);
-extern int labelcl_info_connectpt_set(struct devfs_entry *, struct devfs_entry *);
-extern int labelcl_info_get_IDX(struct devfs_entry *, int, arbitrary_info_t *);
-extern struct devfs_entry *device_info_connectpt_get(struct devfs_entry *);
+extern int labelcl_info_connectpt_set(vertex_hdl_t, vertex_hdl_t);
+extern int labelcl_info_get_IDX(vertex_hdl_t, int, arbitrary_info_t *);
+extern struct devfs_handle_t device_info_connectpt_get(vertex_hdl_t);
 
 #endif /* _ASM_IA64_SN_LABELCL_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/leds.h linux-2.4.22-pre3/include/asm-ia64/sn/leds.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/leds.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/leds.h	2003-07-05 18:11:18.000000000 -0700
@@ -5,7 +5,7 @@
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
@@ -13,25 +13,14 @@
 #include <asm/sn/addrs.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/pda.h>
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define LED0		0xc0000b00100000c0LL
-#define LED_CPU_SHIFT	3
-#else
 #include <asm/sn/sn2/shub.h>
+
 #define LED0		(LOCAL_MMR_ADDR(SH_REAL_JUNK_BUS_LED0))
 #define LED_CPU_SHIFT	16
-#endif
 
 #define LED_CPU_HEARTBEAT	0x01
 #define LED_CPU_ACTIVITY	0x02
-#ifdef LED_WAR
-#define LED_ALWAYS_SET		0x64	/* SN2 hw workaround: always set 0x60 */
-#define LED_MASK_AUTOTEST	0x9e
-#else /* LED_WAR */
 #define LED_ALWAYS_SET		0x00
-#define LED_MASK_AUTOTEST	0xfe
-#endif /* LED_WAR */
 
 /*
  * Basic macros for flashing the LEDS on an SGI, SN1.
@@ -41,11 +30,7 @@
 set_led_bits(u8 value, u8 mask)
 {
 	pda.led_state = (pda.led_state & ~mask) | (value & mask);
-#ifdef CONFIG_IA64_SGI_SN1
-	*pda.led_address = (long) pda.led_state;
-#else
 	*pda.led_address = (short) pda.led_state;
-#endif
 }
 
 #endif /* _ASM_IA64_SN_LEDS_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/mca.h linux-2.4.22-pre3/include/asm-ia64/sn/mca.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/mca.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/mca.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,128 +0,0 @@
-/*
- * File:	mca.h
- * Purpose:	Machine check handling specific to the SN platform defines
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <asm/sal.h>
-#include <asm/mca.h>
-
-#ifdef CONFIG_IA64_SGI_SN
-
-typedef u64 __uint64_t;
-
-typedef struct {
-	__uint64_t sh_event_occurred;
-	__uint64_t sh_first_error;
-	__uint64_t sh_event_overflow;
-	__uint64_t sh_pi_first_error;
-	__uint64_t sh_pi_error_summary;
-	__uint64_t sh_pi_error_overflow;
-	__uint64_t sh_pi_error_detail_1;
-	__uint64_t sh_pi_error_detail_2;
-	__uint64_t sh_pi_hw_time_stamp;
-	__uint64_t sh_pi_uncorrected_detail_1;
-	__uint64_t sh_pi_uncorrected_detail_2;
-	__uint64_t sh_pi_uncorrected_detail_3;
-	__uint64_t sh_pi_uncorrected_detail_4;
-	__uint64_t sh_pi_uncor_time_stamp;
-	__uint64_t sh_pi_corrected_detail_1;
-	__uint64_t sh_pi_corrected_detail_2;
-	__uint64_t sh_pi_corrected_detail_3;
-	__uint64_t sh_pi_corrected_detail_4;
-	__uint64_t sh_pi_cor_time_stamp;
-	__uint64_t sh_mem_error_summary;
-	__uint64_t sh_mem_error_overflow;
-	__uint64_t sh_misc_err_hdr_lower;
-	__uint64_t sh_misc_err_hdr_upper;
-	__uint64_t sh_dir_uc_err_hdr_lower;
-	__uint64_t sh_dir_uc_err_hdr_upper;
-	__uint64_t sh_dir_cor_err_hdr_lower;
-	__uint64_t sh_dir_cor_err_hdr_upper;
-	__uint64_t sh_mem_error_mask;
-	__uint64_t sh_md_uncor_time_stamp;
-	__uint64_t sh_md_cor_time_stamp;
-	__uint64_t sh_md_hw_time_stamp;
-	__uint64_t sh_xn_error_summary;
-	__uint64_t sh_xn_first_error;
-	__uint64_t sh_xn_error_overflow;
-	__uint64_t sh_xniilb_error_summary;
-	__uint64_t sh_xniilb_first_error;
-	__uint64_t sh_xniilb_error_overflow;
-	__uint64_t sh_xniilb_error_detail_1;
-	__uint64_t sh_xniilb_error_detail_2;
-	__uint64_t sh_xniilb_error_detail_3;
-	__uint64_t sh_xnpi_error_summary;
-	__uint64_t sh_xnpi_first_error;
-	__uint64_t sh_xnpi_error_overflow;
-	__uint64_t sh_xnpi_error_detail_1;
-	__uint64_t sh_xnmd_error_summary;
-	__uint64_t sh_xnmd_first_error;
-	__uint64_t sh_xnmd_error_overflow;
-	__uint64_t sh_xnmd_ecc_err_report;
-	__uint64_t sh_xnmd_error_detail_1;
-	__uint64_t sh_lb_error_summary;
-	__uint64_t sh_lb_first_error;
-	__uint64_t sh_lb_error_overflow;
-	__uint64_t sh_lb_error_detail_1;
-	__uint64_t sh_lb_error_detail_2;
-	__uint64_t sh_lb_error_detail_3;
-	__uint64_t sh_lb_error_detail_4;
-	__uint64_t sh_lb_error_detail_5;
-} sal_log_shub_state_t;
-
-typedef struct {
-sal_log_section_hdr_t header;
-	struct
-	{
-		__uint64_t    err_status      : 1,
-		guid            : 1,
-		oem_data        : 1,
-		reserved        : 61;
-	} valid;
-	__uint64_t             err_status;
-	efi_guid_t      guid;
-	__uint64_t shub_nic;
-	sal_log_shub_state_t    shub_state;
-} sal_log_plat_info_t;
-
-
-extern void sal_log_plat_print(int header_len, int sect_len, u8 *p_data, prfunc_t prfunc);
-
-#ifdef platform_plat_specific_err_print
-#undef platform_plat_specific_err_print
-#endif
-#define platform_plat_specific_err_print sal_log_plat_print
-
-#endif /* CONFIG_IA64_SGI_SN */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/mmtimer_private.h linux-2.4.22-pre3/include/asm-ia64/sn/mmtimer_private.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/mmtimer_private.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/mmtimer_private.h	2003-07-05 18:11:18.000000000 -0700
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  *
  * Helper file for the SN implementation of mmtimers
  *
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/module.h linux-2.4.22-pre3/include/asm-ia64/sn/module.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/module.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/module.h	2003-07-05 18:11:18.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_MODULE_H
 #define _ASM_IA64_SN_MODULE_H
@@ -14,7 +14,6 @@
 
 
 #include <linux/config.h>
-#include <asm/sn/systeminfo.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/ksys/elsc.h>
 
@@ -32,9 +31,6 @@
 #define MODULE_FORMAT_BRIEF	1
 #define MODULE_FORMAT_LONG	2
 
-
-#ifdef CONFIG_IA64_SGI_SN2
-
 /*
  *	Module id format
  *
@@ -141,6 +137,7 @@
 #define MODULE_NBRICK           7
 #define MODULE_PEBRICK          8
 #define MODULE_PXBRICK          9
+#define MODULE_IXBRICK          10
 
 /*
  * Moduleid_t comparison macros
@@ -150,118 +147,6 @@
                                  ((_m2)&(MODULE_RACK_MASK|MODULE_BPOS_MASK)))
 #define MODULE_MATCH(_m1, _m2)  (MODULE_CMP((_m1),(_m2)) == 0)
 
-
-#else
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-
-/*
- *	Module id format
- *
- *	  15-12 Brick type (enumerated)
- *	   11-6	Rack ID	(encoded class, group, number)
- *	    5-0 Brick position in rack (0-63)
- */
-/*
- * Macros for getting the brick type
- */
-#define MODULE_BTYPE_MASK	0xf000
-#define MODULE_BTYPE_SHFT	12
-#define MODULE_GET_BTYPE(_m)	(((_m) & MODULE_BTYPE_MASK) >> MODULE_BTYPE_SHFT)
-#define MODULE_BT_TO_CHAR(_b)	(brick_types[(_b)])
-#define MODULE_GET_BTCHAR(_m)	(MODULE_BT_TO_CHAR(MODULE_GET_BTYPE(_m)))
-
-/*
- * Macros for getting the rack ID.
- */
-#define MODULE_RACK_MASK	0x0fc0
-#define MODULE_RACK_SHFT	6
-#define MODULE_GET_RACK(_m)	(((_m) & MODULE_RACK_MASK) >> MODULE_RACK_SHFT)
-
-/*
- * Macros for getting the brick position
- */
-#define MODULE_BPOS_MASK	0x003f
-#define MODULE_BPOS_SHFT	0
-#define MODULE_GET_BPOS(_m)	(((_m) & MODULE_BPOS_MASK) >> MODULE_BPOS_SHFT)
-
-/*
- * Macros for constructing moduleid_t's
- */
-#define RBT_TO_MODULE(_r, _b, _t) ((_r) << MODULE_RACK_SHFT | \
-				   (_b) << MODULE_BPOS_SHFT | \
-				   (_t) << MODULE_BTYPE_SHFT)
-
-/*
- * Macros for encoding and decoding rack IDs
- * A rack number consists of three parts:
- *   class	1 bit, 0==CPU/mixed, 1==I/O
- *   group	2 bits for CPU/mixed, 3 bits for I/O
- *   number	3 bits for CPU/mixed, 2 bits for I/O (1 based)
- */
-#define RACK_GROUP_BITS(_r)	(RACK_GET_CLASS(_r) ? 3 : 2)
-#define RACK_NUM_BITS(_r)	(RACK_GET_CLASS(_r) ? 2 : 3)
-
-#define RACK_CLASS_MASK(_r)	0x20
-#define RACK_CLASS_SHFT(_r)	5
-#define RACK_GET_CLASS(_r)	\
-	(((_r) & RACK_CLASS_MASK(_r)) >> RACK_CLASS_SHFT(_r))
-#define RACK_ADD_CLASS(_r, _c)	\
-	((_r) |= (_c) << RACK_CLASS_SHFT(_r) & RACK_CLASS_MASK(_r))
-
-#define RACK_GROUP_SHFT(_r)	RACK_NUM_BITS(_r)
-#define RACK_GROUP_MASK(_r)	\
-	( (((unsigned)1<<RACK_GROUP_BITS(_r)) - 1) << RACK_GROUP_SHFT(_r) )
-#define RACK_GET_GROUP(_r)	\
-	(((_r) & RACK_GROUP_MASK(_r)) >> RACK_GROUP_SHFT(_r))
-#define RACK_ADD_GROUP(_r, _g)	\
-	((_r) |= (_g) << RACK_GROUP_SHFT(_r) & RACK_GROUP_MASK(_r))
-
-#define RACK_NUM_SHFT(_r)	0
-#define RACK_NUM_MASK(_r)	\
-	( (((unsigned)1<<RACK_NUM_BITS(_r)) - 1) << RACK_NUM_SHFT(_r) )
-#define RACK_GET_NUM(_r)	\
-	( (((_r) & RACK_NUM_MASK(_r)) >> RACK_NUM_SHFT(_r)) + 1 )
-#define RACK_ADD_NUM(_r, _n)	\
-	((_r) |= ((_n) - 1) << RACK_NUM_SHFT(_r) & RACK_NUM_MASK(_r))
-
-/*
- * Brick type definitions
- */
-#define MAX_BRICK_TYPES		16 /* 1 << (MODULE_RACK_SHFT - MODULE_BTYPE_SHFT */
-
-extern char brick_types[];
-
-#define MODULE_CBRICK		0
-#define MODULE_RBRICK		1
-#define MODULE_IBRICK		2
-#define MODULE_KBRICK		3
-#define MODULE_XBRICK		4
-#define MODULE_DBRICK		5
-#define MODULE_PBRICK		6
-#define MODULE_NBRICK           7
-#define MODULE_PEBRICK          8
-#define MODULE_PXBRICK          9
-
-/*
- * Moduleid_t comparison macros
- */
-/* Don't compare the brick type:  only the position is significant */
-#define MODULE_CMP(_m1, _m2)	(((_m1)&(MODULE_RACK_MASK|MODULE_BPOS_MASK)) -\
-				 ((_m2)&(MODULE_RACK_MASK|MODULE_BPOS_MASK)))
-#define MODULE_MATCH(_m1, _m2)	(MODULE_CMP((_m1),(_m2)) == 0)
-
-#else
-
-/*
- * Some code that uses this macro will not be conditionally compiled.
- */
-#define MODULE_GET_BTCHAR(_m)	('?')
-#define MODULE_CMP(_m1, _m2)	((_m1) - (_m2))
-#define MODULE_MATCH(_m1, _m2)	(MODULE_CMP((_m1),(_m2)) == 0)
-
-#endif /* SN1 */
-#endif /* SN2 */
-
 typedef struct module_s module_t;
 
 struct module_s {
@@ -271,20 +156,15 @@
 
     /* List of nodes in this module */
     cnodeid_t		nodes[MODULE_MAX_NODES];
-#ifdef CONFIG_IA64_SGI_SN2
     geoid_t		geoid[MODULE_MAX_NODES];
-#endif
+    struct {
+		char	moduleid[8];
+    } io[MODULE_MAX_NODES];
     int			nodecnt;	/* Number of nodes in array        */
-
     /* Fields for Module System Controller */
     int			mesgpend;	/* Message pending                 */
     int			shutdown;	/* Shutdown in progress            */
     struct semaphore	thdcnt;		/* Threads finished counter        */
-
-#ifdef CONFIG_IA64_SGI_SN1
-    elsc_t		elsc;
-    spinlock_t		elsclock;
-#endif
     time_t		intrhist[MODULE_HIST_CNT];
     int			histptr;
 
@@ -312,12 +192,6 @@
 
 extern module_t	       *module_lookup(moduleid_t id);
 
-#if defined(CONFIG_IA64_SGI_SN1)
-extern elsc_t	       *get_elsc(void);
-#endif
-
-extern int		get_kmod_info(cmoduleid_t cmod,
-				      module_info_t *mod_info);
 extern int		get_kmod_sys_snum(cmoduleid_t cmod,
 					  char *snum);
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/nag.h linux-2.4.22-pre3/include/asm-ia64/sn/nag.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/nag.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/nag.h	2003-07-05 18:11:18.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
 */
 
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/nic.h linux-2.4.22-pre3/include/asm-ia64/sn/nic.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/nic.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/nic.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,129 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_NIC_H
-#define _ASM_IA64_SN_NIC_H
-
-#include <asm/types.h>
-#include <asm/sn/types.h>
-#include <linux/devfs_fs_kernel.h>
-
-#define MCR_DATA(x)			((int) ((x) & 1))
-#define MCR_DONE(x)			((x) & 2)
-#define MCR_PACK(pulse, sample)		((pulse) << 10 | (sample) << 2)
-
-typedef __psunsigned_t	nic_data_t;
-
-typedef int		
-nic_access_f(nic_data_t data,
-	     int pulse, int sample, int delay);
-
-typedef nic_access_f   *nic_access_t;
-
-typedef struct nic_vmce_s      *nic_vmce_t;
-typedef void			nic_vmc_func(devfs_handle_t v);
-
-/*
- * PRIVATE data for Dallas NIC
- */
-
-typedef struct nic_state_t {
-    nic_access_t	access;
-    nic_data_t		data;
-    int			last_disc;
-    int			done;
-    int			bit_index;
-    int			disc_marker;
-    uchar_t		bits[64];
-} nic_state_t;
-
-/*
- * Public interface for Dallas NIC
- *
- *
- *   Access Routine
- *
- *   nic_setup requires an access routine that pulses the NIC line for a
- *   specified duration, samples the NIC line after a specified duration,
- *   then delays for a third specified duration (for precharge).
- *
- *   This general scheme allows us to access NICs through any medium
- *   (e.g. hub regs, bridge regs, vector writes, system ctlr commands).
- *
- *   The access routine should return the sample value 0 or 1, or if an
- *   error occurs, return a negative error code.  Negative error codes from
- *   the access routine will abort the NIC operation and be propagated
- *   through out of the top-level NIC call.
- */
-
-#define NIC_OK			0
-#define NIC_DONE		1
-#define NIC_FAIL		2
-#define NIC_BAD_CRC		3
-#define NIC_NOT_PRESENT		4
-#define NIC_REDIR_LOOP		5
-#define NIC_PARAM		6
-#define NIC_NOMEM		7
-
-uint64_t nic_get_phase_bits(void);
-
-extern int nic_setup(nic_state_t *ns,
-		     nic_access_t access,
-		     nic_data_t data);
-
-extern int nic_next(nic_state_t *ns,
-		    char *serial,
-		    char *family,
-		    char *crc);
-
-extern int nic_read_one_page(nic_state_t *ns,
-			     char *family,
-			     char *serial,
-			     char *crc,
-			     int start,
-			     uchar_t *redirect,
-			     uchar_t *byte);
-
-extern int nic_read_mfg(nic_state_t *ns,
-			char *family,
-			char *serial,
-			char *crc,
-			uchar_t *pageA,
-			uchar_t *pageB);
-
-extern int nic_info_get(nic_access_t access,
-			nic_data_t data,
-			char *info);
-
-extern int nic_item_info_get(char *buf, char *item, char **item_info);
-
-nic_access_f	nic_access_mcr32;
-
-extern char *nic_vertex_info_get(devfs_handle_t v);
-
-extern char *nic_vertex_info_set(nic_access_t access,
-				 nic_data_t data, 
-				 devfs_handle_t v);
-
-extern int nic_vertex_info_match(devfs_handle_t vertex,
-				 char *name);
-
-extern char *nic_bridge_vertex_info(devfs_handle_t vertex,
-				    nic_data_t	data);
-extern char *nic_hq4_vertex_info(devfs_handle_t vertex,
-				 nic_data_t data);
-extern char *nic_ioc3_vertex_info(devfs_handle_t vertex,
-				    nic_data_t	data,
-				    int32_t *gpcr_s);
-
-extern char *nic_hub_vertex_info(devfs_handle_t vertex);
-
-extern nic_vmce_t	nic_vmc_add(char *, nic_vmc_func *);
-extern void		nic_vmc_del(nic_vmce_t);
-
-#endif /* _ASM_IA64_SN_NIC_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/nodepda.h linux-2.4.22-pre3/include/asm-ia64/sn/nodepda.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/nodepda.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/nodepda.h	2003-07-05 18:11:18.000000000 -0700
@@ -3,27 +3,21 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_NODEPDA_H
 #define _ASM_IA64_SN_NODEPDA_H
 
 
 #include <linux/config.h>
+#include <asm/sn/sgi.h>
 #include <asm/irq.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/router.h>
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/synergy.h>
-#endif
 #include <asm/sn/pda.h>
 #include <asm/sn/module.h>
 #include <asm/sn/bte.h>
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/hubstat.h>
-#endif
-
 /*
  * NUMA Node-Specific Data structures are defined in this file.
  * In particular, this is the location of the node PDA.
@@ -31,23 +25,6 @@
  */
 
 /*
- * Subnode PDA structures. Each node needs a few data structures that 
- * correspond to the PIs on the HUB chip that supports the node.
- */
-#if defined(CONFIG_IA64_SGI_SN1)
-struct subnodepda_s {
-	intr_vecblk_t	intr_dispatch0;
-	intr_vecblk_t	intr_dispatch1;
-};
-
-typedef struct subnodepda_s subnode_pda_t;
-
-
-struct synergy_perf_s;
-#endif
-
-
-/*
  * Node-specific data structure.
  *
  * One of these structures is allocated on each node of a NUMA system.
@@ -66,24 +43,20 @@
 					/*  the second cpu on a node is */
 					/*  node_first_cpu+1.           */
 
-	devfs_handle_t 	xbow_vhdl;
+	vertex_hdl_t 	xbow_vhdl;
 	nasid_t		xbow_peer;	/* NASID of our peer hub on xbow */
 	struct semaphore xbow_sema;	/* Sema for xbow synchronization */
 	slotid_t	slotdesc;
-#ifdef CONFIG_IA64_SGI_SN2
 	geoid_t		geoid;
-#else
-	moduleid_t	module_id;	/* Module ID (redundant local copy) */
-#endif
 	module_t	*module;	/* Pointer to containing module */
 	xwidgetnum_t 	basew_id;
-	devfs_handle_t 	basew_xc;
+	vertex_hdl_t 	basew_xc;
 	int		hubticks;
 	int		num_routers;	/* XXX not setup! Total routers in the system */
 
 	
 	char		*hwg_node_name;	/* hwgraph node name */
-	devfs_handle_t	node_vertex;	/* Hwgraph vertex for this node */
+	vertex_hdl_t	node_vertex;	/* Hwgraph vertex for this node */
 
 	void 		*pdinfo;	/* Platform-dependent per-node info */
 
@@ -95,27 +68,9 @@
 	/*
 	 * The BTEs on this node are shared by the local cpus
 	 */
-	bteinfo_t	bte_if[BTES_PER_NODE];	/* Virtual Interface */
-	char		bte_cleanup[5 * L1_CACHE_BYTES] ____cacheline_aligned;
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	subnode_pda_t	snpda[NUM_SUBNODES];
-	/*
-	 * New extended memory reference counters
- 	 */
-	void			*migr_refcnt_counterbase;
-	void			*migr_refcnt_counterbuffer;
-	size_t			migr_refcnt_cbsize;
-	int			migr_refcnt_numsets;
-	hubstat_t		hubstats;
-	int			synergy_perf_enabled;
-        int       		synergy_perf_freq;
-	spinlock_t		synergy_perf_lock;
-        uint64_t       		synergy_inactive_intervals;
-        uint64_t       		synergy_active_intervals;
-        struct synergy_perf_s	*synergy_perf_data;
-        struct synergy_perf_s	*synergy_perf_first; /* reporting consistency .. */
-#endif /* CONFIG_IA64_SGI_SN1 */
+	struct bteinfo_s	bte_if[BTES_PER_NODE];	/* Virtual Interface */
+	struct timer_list	bte_recovery_timer;
+	spinlock_t		bte_recovery_lock;
 
 	/* 
 	 * Array of pointers to the nodepdas for each node.
@@ -126,17 +81,16 @@
 
 typedef struct nodepda_s nodepda_t;
 
-#ifdef CONFIG_IA64_SGI_SN2
 struct irqpda_s {
 	int num_irq_used;
-	char irq_flags[NR_IVECS];
+	char irq_flags[NR_IRQS];
+	struct pci_dev *device_dev[NR_IRQS];
+	char share_count[NR_IRQS];
+	struct pci_dev *current;
 };
 
 typedef struct irqpda_s irqpda_t;
 
-#endif /* CONFIG_IA64_SGI_SN2 */
-
-
 
 /*
  * Access Functions for node PDA.
@@ -155,21 +109,11 @@
 #define	nodepda		pda.p_nodepda		/* Ptr to this node's PDA */
 #define	NODEPDA(cnode)		(nodepda->pernode_pdaindr[cnode])
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#define subnodepda	pda.p_subnodepda	/* Ptr to this node's subnode PDA */
-#define	SUBNODEPDA(cnode,sn)	(&(NODEPDA(cnode)->snpda[sn]))
-#define	SNPDA(npda,sn)		(&(npda)->snpda[sn])
-#endif
-
 
 /*
  * Macros to access data structures inside nodepda 
  */
-#ifdef CONFIG_IA64_SGI_SN2
 #define NODE_MODULEID(cnode)    geo_module((NODEPDA(cnode)->geoid))
-#else
-#define NODE_MODULEID(cnode)	(NODEPDA(cnode)->module_id)
-#endif
 #define NODE_SLOTID(cnode)	(NODEPDA(cnode)->slotdesc)
 
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/pci/bridge.h linux-2.4.22-pre3/include/asm-ia64/sn/pci/bridge.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/pci/bridge.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/pci/bridge.h	2003-07-05 18:11:19.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_BRIDGE_H
 #define _ASM_SN_PCI_BRIDGE_H
@@ -14,7 +14,7 @@
  * bridge.h - header file for bridge chip and bridge portion of xbridge chip
  *
  * Also including offsets for unique PIC registers.
- * The PIC asic is a follow-on to Xbridge and most of it's registers are
+ * The PIC asic is a follow-on to Xbridge and most of its registers are
  * identical to those of Xbridge.  PIC is different than Xbridge in that
  * it will accept 64 bit register access and that, in some cases, data
  * is kept in bits 63:32.   PIC registers that are identical to Xbridge
@@ -36,7 +36,6 @@
 
 #include <linux/config.h>
 #include <asm/sn/xtalk/xwidget.h>
-#ifndef CONFIG_IA64_SGI_SN1
 #include <asm/sn/pci/pic.h>
 
 extern int io_get_sh_swapper(nasid_t);
@@ -45,7 +44,6 @@
 
 #define BRIDGE_REG_SET32(reg) \
                 *(volatile uint32_t *) (((uint64_t)reg)^4)
-#endif	/* CONFIG_IA64_SGI_SN1 */
 
 /* I/O page size */
 
@@ -111,7 +109,6 @@
  * Generated from Bridge spec dated 04oct95
  */
 
-#ifndef CONFIG_IA64_SGI_SN1
 
 /*
  * pic_widget_cfg_s is a local definition of widget_cfg_t but with
@@ -186,8 +183,8 @@
 
 /*
  * BRIDGE, XBRIDGE, PIC register definitions.  NOTE: Prior to PIC, registers
- * were a 32bit quantity and double word aligned (and only accessable as a
- * 32bit word.  PIC registers are 64bits and accessable as words or double
+ * were a 32bit quantity and double word aligned (and only accessible as a
+ * 32bit word.  PIC registers are 64bits and accessible as words or double
  * words.  PIC registers that have valid bits (ie. not just reserved) in the
  * upper 32bits are defined as a union of one 64bit picreg_t and two 32bit
  * bridgereg_t so we can access them both ways.
@@ -605,292 +602,6 @@
     } b_external_flash;
 } bridge_t;
 
-#else	/* CONFIG_IA64_SGI_SN1 */
-
-
-typedef volatile struct bridge_s {
-
-    /* Local Registers				       0x000000-0x00FFFF */
-
-    /* standard widget configuration		       0x000000-0x000057 */
-    widget_cfg_t	    b_widget;		    /* 0x000000 */
-
-    /* helper fieldnames for accessing bridge widget */
-
-#define b_wid_id			b_widget.w_id
-#define b_wid_stat			b_widget.w_status
-#define b_wid_err_upper			b_widget.w_err_upper_addr
-#define b_wid_err_lower			b_widget.w_err_lower_addr
-#define b_wid_control			b_widget.w_control
-#define b_wid_req_timeout		b_widget.w_req_timeout
-#define b_wid_int_upper			b_widget.w_intdest_upper_addr
-#define b_wid_int_lower			b_widget.w_intdest_lower_addr
-#define b_wid_err_cmdword		b_widget.w_err_cmd_word
-#define b_wid_llp			b_widget.w_llp_cfg
-#define b_wid_tflush			b_widget.w_tflush
-
-    /*
-     * we access these through synergy unswizzled space, so the address
-     * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.)
-     * That's why we put the register first and filler second.
-     */
-    /* bridge-specific widget configuration	       0x000058-0x00007F */
-    bridgereg_t             b_wid_aux_err;          /* 0x00005C */
-    bridgereg_t		    _pad_000058;
-
-    bridgereg_t             b_wid_resp_upper;       /* 0x000064 */
-    bridgereg_t             _pad_000060;
-
-    bridgereg_t             b_wid_resp_lower;       /* 0x00006C */
-    bridgereg_t             _pad_000068;
-
-    bridgereg_t             b_wid_tst_pin_ctrl;     /* 0x000074 */
-    bridgereg_t             _pad_000070;
-
-    bridgereg_t		    _pad_000078[2];
-
-    /* PMU & Map				       0x000080-0x00008F */
-    bridgereg_t             b_dir_map;              /* 0x000084 */
-    bridgereg_t             _pad_000080;
-    bridgereg_t		    _pad_000088[2];
-
-    /* SSRAM					       0x000090-0x00009F */
-    bridgereg_t             b_ram_perr_or_map_fault;/* 0x000094 */
-    bridgereg_t             _pad_000090;
-#define b_ram_perr  b_ram_perr_or_map_fault	/* Bridge */
-#define b_map_fault b_ram_perr_or_map_fault	/* Xbridge */
-    bridgereg_t		    _pad_000098[2];
-
-    /* Arbitration				       0x0000A0-0x0000AF */
-    bridgereg_t             b_arb;                  /* 0x0000A4 */
-    bridgereg_t             _pad_0000A0;
-    bridgereg_t		    _pad_0000A8[2];
-
-    /* Number In A Can				       0x0000B0-0x0000BF */
-    bridgereg_t             b_nic;                  /* 0x0000B4 */
-    bridgereg_t             _pad_0000B0;
-    bridgereg_t		    _pad_0000B8[2];
-
-    /* PCI/GIO					       0x0000C0-0x0000FF */
-    bridgereg_t             b_bus_timeout;          /* 0x0000C4 */
-    bridgereg_t             _pad_0000C0;
-#define b_pci_bus_timeout b_bus_timeout
-
-    bridgereg_t             b_pci_cfg;              /* 0x0000CC */
-    bridgereg_t             _pad_0000C8;
-
-    bridgereg_t             b_pci_err_upper;        /* 0x0000D4 */
-    bridgereg_t             _pad_0000D0;
-
-    bridgereg_t             b_pci_err_lower;        /* 0x0000DC */
-    bridgereg_t             _pad_0000D8;
-    bridgereg_t		    _pad_0000E0[8];
-#define b_gio_err_lower b_pci_err_lower
-#define b_gio_err_upper b_pci_err_upper
-
-    /* Interrupt				       0x000100-0x0001FF */
-    bridgereg_t             b_int_status;           /* 0x000104 */
-    bridgereg_t             _pad_000100;
-
-    bridgereg_t             b_int_enable;           /* 0x00010C */
-    bridgereg_t             _pad_000108;
-
-    bridgereg_t             b_int_rst_stat;         /* 0x000114 */
-    bridgereg_t             _pad_000110;
-
-    bridgereg_t             b_int_mode;             /* 0x00011C */
-    bridgereg_t             _pad_000118;
-
-    bridgereg_t             b_int_device;           /* 0x000124 */
-    bridgereg_t             _pad_000120;
-
-    bridgereg_t             b_int_host_err;         /* 0x00012C */
-    bridgereg_t             _pad_000128;
-
-    struct {
-        bridgereg_t             addr;               /* 0x0001{34,,,6C} */
-        bridgereg_t             __pad;              /* 0x0001{30,,,68} */
-    } b_int_addr[8];				    /* 0x000130 */
-
-    bridgereg_t             b_err_int_view;         /* 0x000174 */
-    bridgereg_t             _pad_000170;
-
-    bridgereg_t             b_mult_int;             /* 0x00017c */
-    bridgereg_t             _pad_000178;
-
-    struct {
-        bridgereg_t             intr;               /* 0x0001{84,,,BC} */
-        bridgereg_t             __pad;              /* 0x0001{80,,,B8} */
-    } b_force_always[8];			    /* 0x000180 */
-
-    struct {
-        bridgereg_t             intr;               /* 0x0001{C4,,,FC} */
-        bridgereg_t             __pad;              /* 0x0001{C0,,,F8} */
-    } b_force_pin[8];			    	    /* 0x0001C0 */
-
-    /* Device					       0x000200-0x0003FF */
-    struct {
-        bridgereg_t             reg;                /* 0x0002{04,,,3C} */
-        bridgereg_t             __pad;              /* 0x0002{00,,,38} */
-    } b_device[8];				    /* 0x000200 */
-
-    struct {
-        bridgereg_t             reg;                /* 0x0002{44,,,7C} */
-        bridgereg_t             __pad;              /* 0x0002{40,,,78} */
-    } b_wr_req_buf[8];				    /* 0x000240 */
-
-    struct {
-        bridgereg_t             reg;                /* 0x0002{84,,,8C} */
-        bridgereg_t             __pad;              /* 0x0002{80,,,88} */
-    } b_rrb_map[2];				    /* 0x000280 */
-#define	b_even_resp	b_rrb_map[0].reg	    /* 0x000284 */
-#define	b_odd_resp	b_rrb_map[1].reg	    /* 0x00028C */
-
-    bridgereg_t             b_resp_status;          /* 0x000294 */
-    bridgereg_t             _pad_000290;
-
-    bridgereg_t             b_resp_clear;           /* 0x00029C */
-    bridgereg_t             _pad_000298;
-
-    bridgereg_t		    _pad_0002A0[24];
-
-    /* Xbridge only */
-    struct {
-	bridgereg_t	        upper;              /* 0x0003{04,,,F4} */
-	bridgereg_t             __pad1;		    /* 0x0003{00,,,F0} */
-	bridgereg_t             lower;              /* 0x0003{0C,,,FC} */
-	bridgereg_t             __pad2;             /* 0x0003{08,,,F8} */
-    } b_buf_addr_match[16];
-
-    /* Performance Monitor Registers (even only) */
-    struct {
-        bridgereg_t             flush_w_touch;      /* 0x000404,,,5C4 */
-        bridgereg_t             __pad1;             /* 0x000400,,,5C0 */
-
-        bridgereg_t             flush_wo_touch;     /* 0x00040C,,,5CC */
-        bridgereg_t             __pad2;             /* 0x000408,,,5C8 */
-
-        bridgereg_t             inflight;           /* 0x000414,,,5D4 */
-        bridgereg_t             __pad3;             /* 0x000410,,,5D0 */
-
-        bridgereg_t             prefetch;           /* 0x00041C,,,5DC */
-        bridgereg_t             __pad4;             /* 0x000418,,,5D8 */
-
-        bridgereg_t             total_pci_retry;    /* 0x000424,,,5E4 */
-        bridgereg_t             __pad5;             /* 0x000420,,,5E0 */
-
-        bridgereg_t             max_pci_retry;      /* 0x00042C,,,5EC */
-        bridgereg_t             __pad6;             /* 0x000428,,,5E8 */
-
-        bridgereg_t             max_latency;        /* 0x000434,,,5F4 */
-        bridgereg_t             __pad7;             /* 0x000430,,,5F0 */
-
-        bridgereg_t             clear_all;          /* 0x00043C,,,5FC */
-        bridgereg_t             __pad8;             /* 0x000438,,,5F8 */
-    } b_buf_count[8];
-
-    char                    _pad_000600[0x010000 - 0x000600];
-
-    /*
-     * The Xbridge has 1024 internal ATE's and the Bridge has 128.
-     * Make enough room for the Xbridge ATE's and depend on runtime
-     * checks to limit access to bridge ATE's.
-     */
-
-    /* Internal Address Translation Entry RAM	       0x010000-0x011fff */
-    union {
-	bridge_ate_t		wr;		/* write-only */
-	struct {
-	    bridgereg_t             rd;         /* read-only */
-            bridgereg_t             _p_pad;
-	}			hi;
-    }			    b_int_ate_ram[XBRIDGE_INTERNAL_ATES];
-
-#define b_int_ate_ram_lo(idx) b_int_ate_ram[idx+512].hi.rd
-
-    /* the xbridge read path for internal ates starts at 0x12000.
-     * I don't believe we ever try to read the ates.
-     */
-    /* Internal Address Translation Entry RAM LOW       0x012000-0x013fff */
-    struct {
-	bridgereg_t             rd; 
-        bridgereg_t             _p_pad;
-    }			    xb_int_ate_ram_lo[XBRIDGE_INTERNAL_ATES];
-
-    char		    _pad_014000[0x20000 - 0x014000];
-
-    /* PCI Device Configuration Spaces		       0x020000-0x027FFF */
-    union {				/* make all access sizes available. */
-	uchar_t			c[0x1000 / 1];
-	uint16_t		s[0x1000 / 2];
-	uint32_t		l[0x1000 / 4];
-	uint64_t		d[0x1000 / 8];
-	union {
-	    uchar_t		c[0x100 / 1];
-	    uint16_t		s[0x100 / 2];
-	    uint32_t		l[0x100 / 4];
-	    uint64_t		d[0x100 / 8];
-	}			f[8];
-    } b_type0_cfg_dev[8];			    /* 0x020000 */
-
-    /* PCI Type 1 Configuration Space		       0x028000-0x028FFF */
-    union {				/* make all access sizes available. */
-	uchar_t			c[0x1000 / 1];
-	uint16_t		s[0x1000 / 2];
-	uint32_t		l[0x1000 / 4];
-	uint64_t		d[0x1000 / 8];
-        union {
-            uchar_t         c[0x100 / 1];
-            uint16_t        s[0x100 / 2];
-            uint32_t        l[0x100 / 4];
-            uint64_t        d[0x100 / 8];
-	} f[8];
-    } b_type1_cfg;				    /* 0x028000-0x029000 */
-
-    char		    _pad_029000[0x007000];  /* 0x029000-0x030000 */
-
-    /* PCI Interrupt Acknowledge Cycle		       0x030000 */
-    union {
-	uchar_t			c[8 / 1];
-	uint16_t		s[8 / 2];
-	uint32_t		l[8 / 4];
-	uint64_t		d[8 / 8];
-    } b_pci_iack;				    /* 0x030000 */
-
-    uchar_t		    _pad_030007[0x04fff8];  /* 0x030008-0x07FFFF */
-
-    /* External Address Translation Entry RAM	       0x080000-0x0FFFFF */
-    bridge_ate_t	    b_ext_ate_ram[0x10000];
-
-    /* Reserved					       0x100000-0x1FFFFF */
-    char		    _pad_100000[0x200000-0x100000];
-
-    /* PCI/GIO Device Spaces			       0x200000-0xBFFFFF */
-    union {				/* make all access sizes available. */
-	uchar_t			c[0x100000 / 1];
-	uint16_t		s[0x100000 / 2];
-	uint32_t		l[0x100000 / 4];
-	uint64_t		d[0x100000 / 8];
-    } b_devio_raw[10];			/* 0x200000 */
-
-    /* b_devio macro is a bit strange; it reflects the
-     * fact that the Bridge ASIC provides 2M for the
-     * first two DevIO windows and 1M for the other six.
-     */
-#define b_devio(n)	b_devio_raw[((n)<2)?(n*2):(n+2)]
-
-    /* External Flash Proms 1,0			       0xC00000-0xFFFFFF */
-    union {				/* make all access sizes available. */
-	uchar_t			c[0x400000 / 1];	/* read-only */
-	uint16_t		s[0x400000 / 2];	/* read-write */
-	uint32_t		l[0x400000 / 4];	/* read-only */
-	uint64_t		d[0x400000 / 8];	/* read-only */
-    } b_external_flash;			/* 0xC00000 */
-} bridge_t;
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-
 #define berr_field	berr_un.berr_st
 #endif				/* __ASSEMBLY__ */
 
@@ -1428,8 +1139,7 @@
 #define BRIDGE_ISR_ERRORS		\
 		(BRIDGE_ISR_LINK_ERROR|BRIDGE_ISR_PCIBUS_ERROR|		\
 		 BRIDGE_ISR_XTALK_ERROR|BRIDGE_ISR_SSRAM_PERR|		\
-		 BRIDGE_ISR_PMU_ESIZE_FAULT|PIC_ISR_PCIX_ARB_ERR|	\
-		 PIC_ISR_INT_RAM_PERR)
+		 BRIDGE_ISR_PMU_ESIZE_FAULT|PIC_ISR_INT_RAM_PERR)
 
 /*
  * List of Errors which are fatal and kill the sytem
@@ -1598,22 +1308,6 @@
 
 #define BRIDGE_TMO_PCI_RETRY_CNT_MAX	0x3ff
 
-#ifdef SN0
-/*
- * The NASID should be shifted by this amount and stored into the
- * interrupt(x) register.
- */
-#define BRIDGE_INT_ADDR_NASID_SHFT	8
-
-/*
- * The BRIDGE_INT_ADDR_DEST_IO bit should be set to send an interrupt to
- * memory.
- */
-#define BRIDGE_INT_ADDR_DEST_IO		(1 << 17)
-#define BRIDGE_INT_ADDR_DEST_MEM	0
-#define BRIDGE_INT_ADDR_MASK		(1 << 17)
-#endif
-
 /* Bridge device(x) register bits definition */
 #define BRIDGE_DEV_ERR_LOCK_EN		(1ull << 28)
 #define BRIDGE_DEV_PAGE_CHK_DIS		(1ull << 27)
@@ -1684,7 +1378,7 @@
 /* RRB clear register */
 #define	BRIDGE_RRB_CLEAR(r)	(0x00000001<<(r))
 
-/* Defines for the virtual channels so we dont hardcode 0-3 within code */
+/* Defines for the virtual channels so we don't hardcode 0-3 within code */
 #define VCHAN0	0	/* virtual channel 0 (ie. the "normal" channel) */
 #define VCHAN1	1	/* virtual channel 1 */
 #define VCHAN2	2	/* virtual channel 2 - PIC only */
@@ -1728,6 +1422,38 @@
 #define BRIDGE_PCI_IO_LIMIT		BRIDGE_PCIIO_XTALK_ALIAS_LIMIT
 
 /*
+ * Macros for Xtalk to Bridge bus (PCI) PIO
+ * refer to section 5.2.1 Figure 4 of the "PCI Interface Chip (PIC) Volume II
+ * Programmer's Reference" (Revision 0.8 as of this writing).
+ *
+ * These are PIC bridge specific.  A separate set of macros was defined
+ * because PIC deviates from Bridge/Xbridge by not supporting a big-window
+ * alias for PCI I/O space, and also redefines XTALK addresses
+ * 0x0000C0000000L and 0x000100000000L to be PCI MEM aliases for the second
+ * bus.
+ */
+
+/* XTALK addresses that map into PIC Bridge Bus addr space */
+#define PICBRIDGE0_PIO32_XTALK_ALIAS_BASE	0x000040000000L
+#define PICBRIDGE0_PIO32_XTALK_ALIAS_LIMIT	0x00007FFFFFFFL
+#define PICBRIDGE0_PIO64_XTALK_ALIAS_BASE	0x000080000000L
+#define PICBRIDGE0_PIO64_XTALK_ALIAS_LIMIT	0x0000BFFFFFFFL
+#define PICBRIDGE1_PIO32_XTALK_ALIAS_BASE	0x0000C0000000L
+#define PICBRIDGE1_PIO32_XTALK_ALIAS_LIMIT	0x0000FFFFFFFFL
+#define PICBRIDGE1_PIO64_XTALK_ALIAS_BASE	0x000100000000L
+#define PICBRIDGE1_PIO64_XTALK_ALIAS_LIMIT	0x00013FFFFFFFL
+
+/* XTALK addresses that map into PCI addresses */
+#define PICBRIDGE0_PCI_MEM32_BASE	PICBRIDGE0_PIO32_XTALK_ALIAS_BASE
+#define PICBRIDGE0_PCI_MEM32_LIMIT	PICBRIDGE0_PIO32_XTALK_ALIAS_LIMIT
+#define PICBRIDGE0_PCI_MEM64_BASE	PICBRIDGE0_PIO64_XTALK_ALIAS_BASE
+#define PICBRIDGE0_PCI_MEM64_LIMIT	PICBRIDGE0_PIO64_XTALK_ALIAS_LIMIT
+#define PICBRIDGE1_PCI_MEM32_BASE	PICBRIDGE1_PIO32_XTALK_ALIAS_BASE
+#define PICBRIDGE1_PCI_MEM32_LIMIT	PICBRIDGE1_PIO32_XTALK_ALIAS_LIMIT
+#define PICBRIDGE1_PCI_MEM64_BASE	PICBRIDGE1_PIO64_XTALK_ALIAS_BASE
+#define PICBRIDGE1_PCI_MEM64_LIMIT	PICBRIDGE1_PIO64_XTALK_ALIAS_LIMIT
+
+/*
  * Macros for Bridge bus (PCI/GIO) to Xtalk DMA
  */
 /* Bridge Bus DMA addresses */
@@ -1845,9 +1571,6 @@
 #define ATE_SWAP_ON(x)		((x) |= (1 << ATE_SWAPSHIFT))
 #define ATE_SWAP_OFF(x)		((x) &= ~(1 << ATE_SWAPSHIFT))
 
-#define is_xbridge(bridge) IS_XBRIDGE(bridge->b_wid_id)
-#define is_pic(bridge) IS_PIC_BRIDGE(bridge->b_wid_id)
-
 /* extern declarations */
 
 #ifndef __ASSEMBLY__
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/pci/pci_bus_cvlink.h linux-2.4.22-pre3/include/asm-ia64/sn/pci/pci_bus_cvlink.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/pci/pci_bus_cvlink.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/pci/pci_bus_cvlink.h	2003-07-05 18:11:19.000000000 -0700
@@ -4,13 +4,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_CVLINK_H
 #define _ASM_SN_PCI_CVLINK_H
 
 #include <asm/sn/types.h>
-#include <asm/sn/hack.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/driver.h>
 #include <asm/sn/iograph.h>
@@ -50,11 +49,11 @@
 	(((struct sn_widget_sysdata *)((pci_bus)->sysdata))->vhdl)
 
 struct sn_widget_sysdata {
-        devfs_handle_t  vhdl;
+        vertex_hdl_t  vhdl;
 };
 
 struct sn_device_sysdata {
-        devfs_handle_t  vhdl;
+        vertex_hdl_t  vhdl;
 	int		isa64;
 	int		isPIC;
 	volatile unsigned int *dma_buf_sync;
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/pci/pci_defs.h linux-2.4.22-pre3/include/asm-ia64/sn/pci/pci_defs.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/pci/pci_defs.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/pci/pci_defs.h	2003-07-05 18:11:19.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCI_DEFS_H
 #define _ASM_SN_PCI_PCI_DEFS_H
@@ -321,6 +321,112 @@
 
 #ifndef __ASSEMBLY__
 
+#ifdef LITTLE_ENDIAN
+
+/*
+ * PCI config space definition
+ */
+typedef volatile struct pci_cfg_s {
+	uint16_t	vendor_id;
+	uint16_t	dev_id;
+	uint16_t	cmd;
+	uint16_t	status;
+	uchar_t		rev;
+        uchar_t         prog_if;
+	uchar_t		sub_class;
+	uchar_t		class;
+	uchar_t		line_size;
+	uchar_t		lt;
+	uchar_t		hdr_type;
+	uchar_t		bist;
+	uint32_t	bar[6];
+	uint32_t	cardbus;
+	uint16_t	subsys_vendor_id;
+	uint16_t	subsys_dev_id;
+	uint32_t	exp_rom;
+	uint32_t	res[2];
+	uchar_t		int_line;
+	uchar_t		int_pin;
+	uchar_t		min_gnt;
+	uchar_t		max_lat;
+} pci_cfg_t;
+
+/*
+ * PCI Type 1 config space definition for PCI to PCI Bridges (PPBs)
+ */
+typedef volatile struct pci_cfg1_s {
+	uint16_t	vendor_id;
+	uint16_t	dev_id;
+	uint16_t	cmd;
+	uint16_t	status;
+	uchar_t		rev;
+	uchar_t		prog_if;
+	uchar_t		sub_class;
+	uchar_t		class;
+	uchar_t		line_size;
+	uchar_t		lt;
+	uchar_t		hdr_type;
+	uchar_t		bist;
+	uint32_t	bar[2];
+	uchar_t		pri_bus_num;
+	uchar_t		snd_bus_num;
+	uchar_t		sub_bus_num;
+	uchar_t		slt;
+	uchar_t		io_base;
+	uchar_t		io_limit;
+	uint16_t	snd_status;
+	uint16_t	mem_base;
+	uint16_t	mem_limit;
+	uint16_t	pmem_base;
+	uint16_t	pmem_limit;
+	uint32_t	pmem_base_upper;
+	uint32_t	pmem_limit_upper;
+	uint16_t	io_base_upper;
+	uint16_t	io_limit_upper;
+	uint32_t	res;
+	uint32_t	exp_rom;
+	uchar_t		int_line;
+	uchar_t		int_pin;
+	uint16_t	ppb_control;
+
+} pci_cfg1_t;
+
+/*
+ * PCI-X Capability
+ */
+typedef volatile struct cap_pcix_cmd_reg_s {
+	uint16_t	data_parity_enable:	1,
+			enable_relaxed_order:	1,
+			max_mem_read_cnt:	2,
+			max_split:		3,
+			reserved1:		9;
+} cap_pcix_cmd_reg_t;
+
+typedef volatile struct cap_pcix_stat_reg_s {
+	uint32_t	func_num:		3,
+			dev_num:		5,
+			bus_num:		8,
+			bit64_device:		1,
+			mhz133_capable:		1,
+			split_complt_discard:	1,
+			unexpect_split_complt:	1,
+			device_complex:		1,
+			max_mem_read_cnt:	2,
+			max_out_split:		3,
+			max_cum_read:		3,
+			split_complt_err:	1,
+			reserved1:		2;
+} cap_pcix_stat_reg_t;
+
+typedef volatile struct cap_pcix_type0_s {
+	uchar_t			pcix_cap_id;
+	uchar_t			pcix_cap_nxt;
+	cap_pcix_cmd_reg_t	pcix_type0_command;
+	cap_pcix_stat_reg_t	pcix_type0_status;
+} cap_pcix_type0_t;
+
+#else
+
 /*
  * PCI config space definition
  */
@@ -388,6 +494,8 @@
 	uchar_t		int_line;
 } pci_cfg1_t;
 
+
+
 /*
  * PCI-X Capability
  */
@@ -422,5 +530,6 @@
 	cap_pcix_stat_reg_t	pcix_type0_status;
 } cap_pcix_type0_t;
 
+#endif
 #endif	/* __ASSEMBLY__ */
 #endif /* _ASM_SN_PCI_PCI_DEFS_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/pci/pciba.h linux-2.4.22-pre3/include/asm-ia64/sn/pci/pciba.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/pci/pciba.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/pci/pciba.h	2003-07-05 18:11:19.000000000 -0700
@@ -3,7 +3,7 @@
  * Public License.  See the file "COPYING" in the main directory of
  * this archive for more details.
  *
- * Copyright (C) 1997, 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1997, 2001-2003 Silicon Graphics, Inc. All rights reserved.
  *
  */
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/pci/pcibr.h linux-2.4.22-pre3/include/asm-ia64/sn/pci/pcibr.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/pci/pcibr.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/pci/pcibr.h	2003-07-05 18:11:19.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIBR_H
 #define _ASM_SN_PCI_PCIBR_H
@@ -59,9 +59,7 @@
  *	code and part number registered by pcibr_init().
  */
 
-extern void		pcibr_init(void);
-
-extern int		pcibr_attach(devfs_handle_t);
+extern int		pcibr_attach(vertex_hdl_t);
 
 /* =====================================================================
  *    bus provider function table
@@ -94,7 +92,7 @@
  *	smarts on the part of the compilation system).
  */
 
-extern pcibr_piomap_t	pcibr_piomap_alloc(devfs_handle_t dev,
+extern pcibr_piomap_t	pcibr_piomap_alloc(vertex_hdl_t dev,
 					   device_desc_t dev_desc,
 					   pciio_space_t space,
 					   iopaddr_t pci_addr,
@@ -110,24 +108,24 @@
 
 extern void		pcibr_piomap_done(pcibr_piomap_t piomap);
 
-extern caddr_t		pcibr_piotrans_addr(devfs_handle_t dev,
+extern caddr_t		pcibr_piotrans_addr(vertex_hdl_t dev,
 					    device_desc_t dev_desc,
 					    pciio_space_t space,
 					    iopaddr_t pci_addr,
 					    size_t byte_count,
 					    unsigned flags);
 
-extern iopaddr_t	pcibr_piospace_alloc(devfs_handle_t dev,
+extern iopaddr_t	pcibr_piospace_alloc(vertex_hdl_t dev,
 					     device_desc_t dev_desc,
 					     pciio_space_t space,
 					     size_t byte_count,
 					     size_t alignment);
-extern void		pcibr_piospace_free(devfs_handle_t dev,
+extern void		pcibr_piospace_free(vertex_hdl_t dev,
 					    pciio_space_t space,
 					    iopaddr_t pciaddr,
 					    size_t byte_count);
 
-extern pcibr_dmamap_t	pcibr_dmamap_alloc(devfs_handle_t dev,
+extern pcibr_dmamap_t	pcibr_dmamap_alloc(vertex_hdl_t dev,
 					   device_desc_t dev_desc,
 					   size_t byte_count_max,
 					   unsigned flags);
@@ -150,109 +148,97 @@
  * (This node id can be different for each PCI bus.) 
  */
 
-extern cnodeid_t	pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl);
+extern cnodeid_t	pcibr_get_dmatrans_node(vertex_hdl_t pconn_vhdl);
 
-extern iopaddr_t	pcibr_dmatrans_addr(devfs_handle_t dev,
+extern iopaddr_t	pcibr_dmatrans_addr(vertex_hdl_t dev,
 					    device_desc_t dev_desc,
 					    paddr_t paddr,
 					    size_t byte_count,
 					    unsigned flags);
 
-extern alenlist_t	pcibr_dmatrans_list(devfs_handle_t dev,
+extern alenlist_t	pcibr_dmatrans_list(vertex_hdl_t dev,
 					    device_desc_t dev_desc,
 					    alenlist_t palenlist,
 					    unsigned flags);
 
 extern void		pcibr_dmamap_drain(pcibr_dmamap_t map);
 
-extern void		pcibr_dmaaddr_drain(devfs_handle_t vhdl,
+extern void		pcibr_dmaaddr_drain(vertex_hdl_t vhdl,
 					    paddr_t addr,
 					    size_t bytes);
 
-extern void		pcibr_dmalist_drain(devfs_handle_t vhdl,
+extern void		pcibr_dmalist_drain(vertex_hdl_t vhdl,
 					    alenlist_t list);
 
 typedef unsigned	pcibr_intr_ibit_f(pciio_info_t info,
 					  pciio_intr_line_t lines);
 
-extern void		pcibr_intr_ibit_set(devfs_handle_t, pcibr_intr_ibit_f *);
+extern void		pcibr_intr_ibit_set(vertex_hdl_t, pcibr_intr_ibit_f *);
 
-extern pcibr_intr_t	pcibr_intr_alloc(devfs_handle_t dev,
+extern pcibr_intr_t	pcibr_intr_alloc(vertex_hdl_t dev,
 					 device_desc_t dev_desc,
 					 pciio_intr_line_t lines,
-					 devfs_handle_t owner_dev);
+					 vertex_hdl_t owner_dev);
 
 extern void		pcibr_intr_free(pcibr_intr_t intr);
 
-#ifdef CONFIG_IA64_SGI_SN1
-extern int		pcibr_intr_connect(pcibr_intr_t intr);
-#else
 extern int		pcibr_intr_connect(pcibr_intr_t intr, intr_func_t, intr_arg_t);
-#endif
 
 extern void		pcibr_intr_disconnect(pcibr_intr_t intr);
 
-extern devfs_handle_t	pcibr_intr_cpu_get(pcibr_intr_t intr);
+extern vertex_hdl_t	pcibr_intr_cpu_get(pcibr_intr_t intr);
 
-extern void		pcibr_provider_startup(devfs_handle_t pcibr);
+extern void		pcibr_provider_startup(vertex_hdl_t pcibr);
 
-extern void		pcibr_provider_shutdown(devfs_handle_t pcibr);
+extern void		pcibr_provider_shutdown(vertex_hdl_t pcibr);
 
-extern int		pcibr_reset(devfs_handle_t dev);
+extern int		pcibr_reset(vertex_hdl_t dev);
 
-extern int              pcibr_write_gather_flush(devfs_handle_t dev);
+extern int              pcibr_write_gather_flush(vertex_hdl_t dev);
 
-extern pciio_endian_t	pcibr_endian_set(devfs_handle_t dev,
+extern pciio_endian_t	pcibr_endian_set(vertex_hdl_t dev,
 					 pciio_endian_t device_end,
 					 pciio_endian_t desired_end);
 
-extern pciio_priority_t pcibr_priority_set(devfs_handle_t dev,
+extern pciio_priority_t pcibr_priority_set(vertex_hdl_t dev,
 					   pciio_priority_t device_prio);
 
-extern uint64_t		pcibr_config_get(devfs_handle_t conn,
+extern uint64_t		pcibr_config_get(vertex_hdl_t conn,
 					 unsigned reg,
 					 unsigned size);
 
-extern void		pcibr_config_set(devfs_handle_t conn,
+extern void		pcibr_config_set(vertex_hdl_t conn,
 					 unsigned reg,
 					 unsigned size,
 					 uint64_t value);
 
-extern int		pcibr_error_devenable(devfs_handle_t pconn_vhdl,
+extern int		pcibr_error_devenable(vertex_hdl_t pconn_vhdl,
 					      int error_code);
 
-#ifdef PIC_LATER
-extern pciio_slot_t	pcibr_error_extract(devfs_handle_t pcibr_vhdl,
-					    pciio_space_t *spacep,
-					    iopaddr_t *addrp);
-#endif
-
-extern int		pcibr_wrb_flush(devfs_handle_t pconn_vhdl);
-extern int		pcibr_rrb_check(devfs_handle_t pconn_vhdl,
+extern int		pcibr_wrb_flush(vertex_hdl_t pconn_vhdl);
+extern int		pcibr_rrb_check(vertex_hdl_t pconn_vhdl,
 					int *count_vchan0,
 					int *count_vchan1,
 					int *count_reserved,
 					int *count_pool);
 
-#ifndef CONFIG_IA64_SGI_SN1
-extern int		pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd,
+extern int		pcibr_alloc_all_rrbs(vertex_hdl_t vhdl, int even_odd,
 					     int dev_1_rrbs, int virt1,
 					     int dev_2_rrbs, int virt2,
 					     int dev_3_rrbs, int virt3,
 					     int dev_4_rrbs, int virt4);
-#endif
 
 typedef void
-rrb_alloc_funct_f	(devfs_handle_t xconn_vhdl,
+rrb_alloc_funct_f	(vertex_hdl_t xconn_vhdl,
 			 int *vendor_list);
 
 typedef rrb_alloc_funct_f      *rrb_alloc_funct_t;
 
-void			pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl,
+void			pcibr_set_rrb_callback(vertex_hdl_t xconn_vhdl,
 					       rrb_alloc_funct_f *func);
 
-extern int		pcibr_device_unregister(devfs_handle_t);
-extern int		pcibr_dma_enabled(devfs_handle_t);
+extern int		pcibr_device_unregister(vertex_hdl_t);
+extern int		pcibr_dma_enabled(vertex_hdl_t);
 /*
  * Bridge-specific flags that can be set via pcibr_device_flags_set
  * and cleared via pcibr_device_flags_clear.  Other flags are
@@ -320,7 +306,7 @@
  * "flags" are defined above. NOTE: this includes turning
  * things *OFF* as well as turning them *ON* ...
  */
-extern int		pcibr_device_flags_set(devfs_handle_t dev,
+extern int		pcibr_device_flags_set(vertex_hdl_t dev,
 					     pcibr_device_flags_t flags);
 
 /*
@@ -331,7 +317,7 @@
  * <0 on failure, which occurs when we're unable to allocate any
  * buffers to a channel that desires at least one buffer.
  */
-extern int		pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
+extern int		pcibr_rrb_alloc(vertex_hdl_t pconn_vhdl,
 					int *count_vchan0,
 					int *count_vchan1);
 
@@ -345,19 +331,15 @@
 
 extern xwidget_intr_preset_f pcibr_xintr_preset;
 
-extern void		pcibr_hints_fix_rrbs(devfs_handle_t);
-extern void		pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-extern void		pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, ulong);
-extern void		pcibr_hints_handsoff(devfs_handle_t);
-
-#ifdef CONFIG_IA64_SGI_SN1
-typedef unsigned	pcibr_intr_bits_f(pciio_info_t, pciio_intr_line_t);
-#else
+extern void		pcibr_hints_fix_rrbs(vertex_hdl_t);
+extern void		pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
+extern void		pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, ulong);
+extern void		pcibr_hints_handsoff(vertex_hdl_t);
+
 typedef unsigned	pcibr_intr_bits_f(pciio_info_t, pciio_intr_line_t, int);
-#endif
-extern void		pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
+extern void		pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *);
 
-extern int		pcibr_asic_rev(devfs_handle_t);
+extern int		pcibr_asic_rev(vertex_hdl_t);
 
 #endif 	/* __ASSEMBLY__ */
 #endif	/* #if defined(__KERNEL__) */
@@ -433,7 +415,7 @@
     short		    resp_bs_bridge_mode;
     int                     resp_has_host;
     char                    resp_host_slot;
-    devfs_handle_t            resp_slot_conn;
+    vertex_hdl_t            resp_slot_conn;
     char                    resp_slot_conn_name[MAXDEVNAME];
     int                     resp_slot_status;
     int                     resp_l1_bus_num;
@@ -460,10 +442,8 @@
     bridgereg_t             resp_b_int_device;
     bridgereg_t             resp_b_int_enable;
     bridgereg_t             resp_b_int_host;
-#ifndef CONFIG_IA64_SGI_SN1
     picreg_t		    resp_p_int_enable;
     picreg_t		    resp_p_int_host;
-#endif
     struct pcibr_slot_func_info_resp_s {
         int                     resp_f_status;
         char                    resp_f_slot_name[MAXDEVNAME];
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/pci/pcibr_private.h linux-2.4.22-pre3/include/asm-ia64/sn/pci/pcibr_private.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/pci/pcibr_private.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/pci/pcibr_private.h	2003-07-05 18:11:19.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIBR_PRIVATE_H
 #define _ASM_SN_PCI_PCIBR_PRIVATE_H
@@ -16,6 +16,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/pci.h>
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/pci/pciio_private.h>
 #include <asm/sn/ksys/l1.h>
@@ -45,7 +46,7 @@
 cfg_p pcibr_func_config_addr(bridge_t *, pciio_bus_t bus, pciio_slot_t, pciio_function_t, int);
 unsigned pcibr_slot_config_get(bridge_t *, pciio_slot_t, int);
 unsigned pcibr_func_config_get(bridge_t *, pciio_slot_t, pciio_function_t, int);
-void pcibr_debug(uint32_t, devfs_handle_t, char *, ...);
+void pcibr_debug(uint32_t, vertex_hdl_t, char *, ...);
 void pcibr_slot_config_set(bridge_t *, pciio_slot_t, int, unsigned);
 void pcibr_func_config_set(bridge_t *, pciio_slot_t, pciio_function_t, int, 
 								unsigned);
@@ -171,6 +172,7 @@
     unsigned                bi_ibits;	/* which Bridge interrupt bit(s) */
     pcibr_soft_t            bi_soft;	/* shortcut to soft info */
     struct pcibr_intr_cbuf_s bi_ibuf;	/* circular buffer of wrap ptrs */
+    unsigned		bi_last_intr;	/* For Shub lb lost intr. bug */
 };
 
 
@@ -254,11 +256,7 @@
 struct pcibr_intr_wrap_s {
     pcibr_soft_t            iw_soft;	/* which bridge */
     volatile bridgereg_t   *iw_stat;	/* ptr to b_int_status */
-#ifdef CONFIG_IA64_SGI_SN1
-    bridgereg_t             iw_intr;	/* bit in b_int_status */
-#else
     bridgereg_t             iw_ibit;	/* bit in b_int_status */
-#endif
     pcibr_intr_list_t       iw_list;	/* ghostbusters! */
     int			    iw_hdlrcnt;	/* running handler count */
     int			    iw_shared;  /* if Bridge bit is shared */
@@ -293,6 +291,8 @@
 #define PCIBR_BRIDGETYPE_PIC		2
 #define IS_XBRIDGE_SOFT(ps) (ps->bs_bridge_type == PCIBR_BRIDGETYPE_XBRIDGE)
 #define IS_PIC_SOFT(ps)     (ps->bs_bridge_type == PCIBR_BRIDGETYPE_PIC)
+#define IS_PIC_BUSNUM_SOFT(ps, bus)	\
+		(IS_PIC_SOFT(ps) && ((ps)->bs_busnum == (bus)))
 #define IS_BRIDGE_SOFT(ps)  (ps->bs_bridge_type == PCIBR_BRIDGETYPE_BRIDGE)
 #define IS_XBRIDGE_OR_PIC_SOFT(ps) (IS_XBRIDGE_SOFT(ps) || IS_PIC_SOFT(ps))
 
@@ -348,13 +348,13 @@
  */
 
 struct pcibr_soft_s {
-    devfs_handle_t          bs_conn;		/* xtalk connection point */
-    devfs_handle_t          bs_vhdl;		/* vertex owned by pcibr */
+    vertex_hdl_t          bs_conn;		/* xtalk connection point */
+    vertex_hdl_t          bs_vhdl;		/* vertex owned by pcibr */
     uint64_t                bs_int_enable;	/* Mask of enabled intrs */
     bridge_t               *bs_base;		/* PIO pointer to Bridge chip */
     char                   *bs_name;		/* hw graph name */
     xwidgetnum_t            bs_xid;		/* Bridge's xtalk ID number */
-    devfs_handle_t          bs_master;		/* xtalk master vertex */
+    vertex_hdl_t          bs_master;		/* xtalk master vertex */
     xwidgetnum_t            bs_mxid;		/* master's xtalk ID number */
     pciio_slot_t            bs_first_slot;      /* first existing slot */
     pciio_slot_t            bs_last_slot;       /* last existing slot */
@@ -367,14 +367,12 @@
     iopaddr_t               bs_dir_xbase;	/* xtalk address for 32-bit PCI direct map */
     xwidgetnum_t	    bs_dir_xport;	/* xtalk port for 32-bit PCI direct map */
 
-    struct map             *bs_int_ate_map;	/* rmalloc map for internal ATEs */
-    struct map             *bs_ext_ate_map;	/* rmalloc map for external ATEs */
+    struct resource	    bs_int_ate_resource;/* root resource for internal ATEs */
+    struct resource	    bs_ext_ate_resource;/* root resource for external ATEs */
+    void	 	    *bs_allocated_ate_res;/* resource struct allocated */
     short		    bs_int_ate_size;	/* number of internal ates */
     short		    bs_bridge_type;	/* see defines above */
     short		    bs_bridge_mode;	/* see defines above */
-#ifdef CONFIG_IA64_SGI_SN1
-#define bs_xbridge	    bs_bridge_type
-#endif
     int                     bs_rev_num;		/* revision number of Bridge */
 
     /* bs_dma_flags are the forced dma flags used on all DMAs. Used for
@@ -382,9 +380,6 @@
      */
     unsigned                bs_dma_flags;	/* forced DMA flags */
 
-#ifdef CONFIG_IA64_SGI_SN1
-    l1sc_t                 *bs_l1sc;            /* io brick l1 system cntr */
-#endif
     moduleid_t		    bs_moduleid;	/* io brick moduleid */
     short		    bs_bricktype;	/* io brick type */
 
@@ -394,7 +389,7 @@
      */
     spinlock_t              bs_lock;
     
-    devfs_handle_t	    bs_noslot_conn;	/* NO-SLOT connection point */
+    vertex_hdl_t	    bs_noslot_conn;	/* NO-SLOT connection point */
     pcibr_info_t	    bs_noslot_info;
     struct pcibr_soft_slot_s {
 	/* information we keep about each CFG slot */
@@ -411,7 +406,7 @@
 	 */
 	int                     has_host;
 	pciio_slot_t            host_slot;
-	devfs_handle_t		slot_conn;
+	vertex_hdl_t		slot_conn;
 
         /* PCI Hot-Plug status word */
         int 			slot_status;
@@ -531,13 +526,8 @@
     int                     bs_rrb_avail[2];
     int                     bs_rrb_res[8];
     int                     bs_rrb_res_dflt[8];
-#ifdef CONFIG_IA64_SGI_SN1
-    int                     bs_rrb_valid[16];
-    int                     bs_rrb_valid_dflt[16];
-#else
     int			    bs_rrb_valid[8][4];
     int			    bs_rrb_valid_dflt[8][4];
-#endif
     struct {
 	/* Each Bridge interrupt bit has a single XIO
 	 * interrupt channel allocated.
@@ -599,20 +589,14 @@
      * in Megabytes), and they generally tend to take once and never
      * release. 
      */
-#ifdef CONFIG_IA64_SGI_SN1
-    struct br_pcisp_info {
-        iopaddr_t               pci_io_base;
-        iopaddr_t               pci_io_last;
-        iopaddr_t               pci_swin_base;
-        iopaddr_t               pci_swin_last;
-        iopaddr_t               pci_mem_base;
-        iopaddr_t               pci_mem_last;
-    } bs_spinfo;
-#endif	/* CONFIG_IA64_SGI_SN1 */
     struct pciio_win_map_s	bs_io_win_map;	/* I/O addr space */
     struct pciio_win_map_s	bs_swin_map;	/* Small window addr space */
     struct pciio_win_map_s	bs_mem_win_map;	/* Memory addr space */
 
+    struct resource		bs_io_win_root_resource; /* I/O addr space */
+    struct resource		bs_swin_root_resource; /* Small window addr space */
+    struct resource		bs_mem_win_root_resource; /* Memory addr space */
+
     int                   bs_bus_addr_status;    /* Bus space status */
 
 #define PCIBR_BUS_ADDR_MEM_FREED       1  /* Reserved PROM mem addr freed */
@@ -655,8 +639,6 @@
     pcibr_intr_bits_f	   *ph_intr_bits;	/* map PCI INT[ABCD] to Bridge Int(n) */
 };
 
-extern int              pcibr_prefetch_enable_rev, pcibr_wg_enable_rev;
-
 /*
  * Number of bridge non-fatal error interrupts we can see before
  * we decide to disable that interrupt.
@@ -689,7 +671,6 @@
 #define NEW(ptr)	NEWA(ptr,1)
 #define DEL(ptr)	DELA(ptr,1)
 
-#ifndef CONFIG_IA64_SGI_SN1
 /*
  * Additional PIO spaces per slot are
  * recorded in this structure.
@@ -701,7 +682,6 @@
     iopaddr_t               start;	/* Starting address of the PIO space */
     size_t                  count;	/* size of PIO space */
 };
-#endif	/* CONFIG_IA64_SGI_SN1 */
 
 /* Use io spin locks. This ensures that all the PIO writes from a particular
  * CPU to a particular IO device are synched before the start of the next
@@ -715,11 +695,9 @@
 #define pcibr_unlock(pcibr_soft, s)	
 #endif	/* PCI_LATER */
 
-#ifndef CONFIG_IA64_SGI_SN1
 #define PCIBR_VALID_SLOT(ps, s)     (s < PCIBR_NUM_SLOTS(ps))
 #define PCIBR_D64_BASE_UNSET    (0xFFFFFFFFFFFFFFFF)
 #define PCIBR_D32_BASE_UNSET    (0xFFFFFFFF)
-#endif
 #define INFO_LBL_PCIBR_ASIC_REV "_pcibr_asic_rev"
 
 #define PCIBR_SOFT_LIST 1
@@ -728,8 +706,35 @@
 struct pcibr_list_s {
 	pcibr_list_p            bl_next;
 	pcibr_soft_t            bl_soft;
-	devfs_handle_t          bl_vhdl;
+	vertex_hdl_t          bl_vhdl;
 };
 #endif /* PCIBR_SOFT_LIST */
 
+
+// Devices per widget: 2 buses, 2 slots per bus, 8 functions per slot.
+#define DEV_PER_WIDGET (2*2*8)
+
+struct sn_flush_device_list {
+	int bus;
+	int pin;
+	struct bar_list {
+		unsigned long start;
+		unsigned long end;
+	} bar_list[PCI_ROM_RESOURCE];
+	unsigned long force_int_addr;
+	volatile unsigned long flush_addr;
+	spinlock_t flush_lock;
+};
+
+struct sn_flush_nasid_entry  {
+        struct sn_flush_device_list **widget_p;
+        unsigned long        iio_itte1;
+        unsigned long        iio_itte2;
+        unsigned long        iio_itte3;
+        unsigned long        iio_itte4;
+        unsigned long        iio_itte5;
+        unsigned long        iio_itte6;
+        unsigned long        iio_itte7;
+};
+
 #endif				/* _ASM_SN_PCI_PCIBR_PRIVATE_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/pci/pciio.h linux-2.4.22-pre3/include/asm-ia64/sn/pci/pciio.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/pci/pciio.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/pci/pciio.h	2003-07-05 18:11:19.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIIO_H
 #define _ASM_SN_PCI_PCIIO_H
@@ -14,6 +14,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/ioport.h>
 #include <asm/sn/ioerror.h>
 #include <asm/sn/driver.h>
 #include <asm/sn/hcl.h>
@@ -277,7 +278,7 @@
 #define PCIIO_PIOMAP_WIN(n)	(0x8+(n))
 
 typedef pciio_piomap_t
-pciio_piomap_alloc_f    (devfs_handle_t dev,	/* set up mapping for this device */
+pciio_piomap_alloc_f    (vertex_hdl_t dev,	/* set up mapping for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 pciio_space_t space,	/* which address space */
 			 iopaddr_t pcipio_addr,		/* starting address */
@@ -297,7 +298,7 @@
 pciio_piomap_done_f     (pciio_piomap_t pciio_piomap);
 
 typedef caddr_t
-pciio_piotrans_addr_f   (devfs_handle_t dev,	/* translate for this device */
+pciio_piotrans_addr_f   (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 pciio_space_t space,	/* which address space */
 			 iopaddr_t pciio_addr,	/* starting address */
@@ -305,7 +306,7 @@
 			 unsigned flags);
 
 typedef caddr_t
-pciio_pio_addr_f        (devfs_handle_t dev,	/* translate for this device */
+pciio_pio_addr_f        (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 pciio_space_t space,	/* which address space */
 			 iopaddr_t pciio_addr,	/* starting address */
@@ -314,14 +315,14 @@
 			 unsigned flags);
 
 typedef iopaddr_t
-pciio_piospace_alloc_f  (devfs_handle_t dev,	/* PIO space for this device */
+pciio_piospace_alloc_f  (vertex_hdl_t dev,	/* PIO space for this device */
 			 device_desc_t dev_desc,	/* Device descriptor   */
 			 pciio_space_t space,	/* which address space  */
 			 size_t byte_count,	/* Number of bytes of space */
 			 size_t alignment);	/* Alignment of allocation  */
 
 typedef void
-pciio_piospace_free_f   (devfs_handle_t dev,	/* Device freeing space */
+pciio_piospace_free_f   (vertex_hdl_t dev,	/* Device freeing space */
 			 pciio_space_t space,	/* Which space is freed */
 			 iopaddr_t pci_addr,	/* Address being freed */
 			 size_t size);	/* Size freed           */
@@ -329,7 +330,7 @@
 /* DMA MANAGEMENT */
 
 typedef pciio_dmamap_t
-pciio_dmamap_alloc_f    (devfs_handle_t dev,	/* set up mappings for this device */
+pciio_dmamap_alloc_f    (vertex_hdl_t dev,	/* set up mappings for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 size_t byte_count_max,		/* max size of a mapping */
 			 unsigned flags);	/* defined in dma.h */
@@ -342,123 +343,107 @@
 			 paddr_t paddr,	/* map for this address */
 			 size_t byte_count);	/* map this many bytes */
 
-typedef alenlist_t
-pciio_dmamap_list_f     (pciio_dmamap_t dmamap,		/* use these mapping resources */
-			 alenlist_t alenlist,	/* map this address/length list */
-			 unsigned flags);
-
 typedef void
 pciio_dmamap_done_f     (pciio_dmamap_t dmamap);
 
 typedef iopaddr_t
-pciio_dmatrans_addr_f   (devfs_handle_t dev,	/* translate for this device */
+pciio_dmatrans_addr_f   (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 paddr_t paddr,	/* system physical address */
 			 size_t byte_count,	/* length */
 			 unsigned flags);	/* defined in dma.h */
 
-typedef alenlist_t
-pciio_dmatrans_list_f   (devfs_handle_t dev,	/* translate for this device */
-			 device_desc_t dev_desc,	/* device descriptor */
-			 alenlist_t palenlist,	/* system address/length list */
-			 unsigned flags);	/* defined in dma.h */
-
 typedef void
 pciio_dmamap_drain_f	(pciio_dmamap_t map);
 
 typedef void
-pciio_dmaaddr_drain_f	(devfs_handle_t vhdl,
+pciio_dmaaddr_drain_f	(vertex_hdl_t vhdl,
 			 paddr_t addr,
 			 size_t bytes);
 
 typedef void
-pciio_dmalist_drain_f	(devfs_handle_t vhdl,
+pciio_dmalist_drain_f	(vertex_hdl_t vhdl,
 			 alenlist_t list);
 
 /* INTERRUPT MANAGEMENT */
 
 typedef pciio_intr_t
-pciio_intr_alloc_f      (devfs_handle_t dev,	/* which PCI device */
+pciio_intr_alloc_f      (vertex_hdl_t dev,	/* which PCI device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 pciio_intr_line_t lines,	/* which line(s) will be used */
-			 devfs_handle_t owner_dev);	/* owner of this intr */
+			 vertex_hdl_t owner_dev);	/* owner of this intr */
 
 typedef void
 pciio_intr_free_f       (pciio_intr_t intr_hdl);
 
-#ifdef CONFIG_IA64_SGI_SN1
-typedef int
-pciio_intr_connect_f    (pciio_intr_t intr_hdl);	/* pciio intr resource handle */
-#else
 typedef int
 pciio_intr_connect_f    (pciio_intr_t intr_hdl, intr_func_t intr_func, intr_arg_t intr_arg);	/* pciio intr resource handle */
-#endif
 
 typedef void
 pciio_intr_disconnect_f (pciio_intr_t intr_hdl);
 
-typedef devfs_handle_t
+typedef vertex_hdl_t
 pciio_intr_cpu_get_f    (pciio_intr_t intr_hdl);	/* pciio intr resource handle */
 
 /* CONFIGURATION MANAGEMENT */
 
 typedef void
-pciio_provider_startup_f (devfs_handle_t pciio_provider);
+pciio_provider_startup_f (vertex_hdl_t pciio_provider);
 
 typedef void
-pciio_provider_shutdown_f (devfs_handle_t pciio_provider);
+pciio_provider_shutdown_f (vertex_hdl_t pciio_provider);
 
 typedef int	
-pciio_reset_f		(devfs_handle_t conn);	/* pci connection point */
+pciio_reset_f		(vertex_hdl_t conn);	/* pci connection point */
 
 typedef int
-pciio_write_gather_flush_f (devfs_handle_t dev);    /* Device flushing buffers */
+pciio_write_gather_flush_f (vertex_hdl_t dev);    /* Device flushing buffers */
 
 typedef pciio_endian_t			/* actual endianness */
-pciio_endian_set_f      (devfs_handle_t dev,	/* specify endianness for this device */
+pciio_endian_set_f      (vertex_hdl_t dev,	/* specify endianness for this device */
 			 pciio_endian_t device_end,	/* endianness of device */
 			 pciio_endian_t desired_end);	/* desired endianness */
 
 typedef pciio_priority_t
-pciio_priority_set_f    (devfs_handle_t pcicard,
+pciio_priority_set_f    (vertex_hdl_t pcicard,
 			 pciio_priority_t device_prio);
 
 typedef uint64_t
-pciio_config_get_f	(devfs_handle_t conn,	/* pci connection point */
+pciio_config_get_f	(vertex_hdl_t conn,	/* pci connection point */
 			 unsigned reg,		/* register byte offset */
 			 unsigned size);	/* width in bytes (1..4) */
 
 typedef void
-pciio_config_set_f	(devfs_handle_t conn,	/* pci connection point */
+pciio_config_set_f	(vertex_hdl_t conn,	/* pci connection point */
 			 unsigned reg,		/* register byte offset */
 			 unsigned size,		/* width in bytes (1..4) */
 			 uint64_t value);	/* value to store */
 
 typedef int
-pciio_error_devenable_f (devfs_handle_t pconn_vhdl, int error_code);
+pciio_error_devenable_f (vertex_hdl_t pconn_vhdl, int error_code);
 
 typedef pciio_slot_t
-pciio_error_extract_f	(devfs_handle_t vhdl,
+pciio_error_extract_f	(vertex_hdl_t vhdl,
 			 pciio_space_t *spacep,
 			 iopaddr_t *addrp);
 
 typedef void
-pciio_driver_reg_callback_f	(devfs_handle_t conn,
+pciio_driver_reg_callback_f	(vertex_hdl_t conn,
 				int key1,
 				int key2,
 				int error);
 
 typedef void
-pciio_driver_unreg_callback_f	(devfs_handle_t conn, /* pci connection point */
+pciio_driver_unreg_callback_f	(vertex_hdl_t conn, /* pci connection point */
 				 int key1,
 				 int key2,
 				 int error);
 
 typedef int
-pciio_device_unregister_f	(devfs_handle_t conn);
+pciio_device_unregister_f	(vertex_hdl_t conn);
 
 typedef int
-pciio_dma_enabled_f		(devfs_handle_t conn);
+pciio_dma_enabled_f		(vertex_hdl_t conn);
 
 /*
  * Adapters that provide a PCI interface adhere to this software interface.
@@ -477,10 +462,8 @@
     pciio_dmamap_alloc_f   *dmamap_alloc;
     pciio_dmamap_free_f    *dmamap_free;
     pciio_dmamap_addr_f    *dmamap_addr;
-    pciio_dmamap_list_f    *dmamap_list;
     pciio_dmamap_done_f    *dmamap_done;
     pciio_dmatrans_addr_f  *dmatrans_addr;
-    pciio_dmatrans_list_f  *dmatrans_list;
     pciio_dmamap_drain_f   *dmamap_drain;
     pciio_dmaaddr_drain_f  *dmaaddr_drain;
     pciio_dmalist_drain_f  *dmalist_drain;
@@ -525,10 +508,8 @@
 extern pciio_dmamap_alloc_f pciio_dmamap_alloc;
 extern pciio_dmamap_free_f pciio_dmamap_free;
 extern pciio_dmamap_addr_f pciio_dmamap_addr;
-extern pciio_dmamap_list_f pciio_dmamap_list;
 extern pciio_dmamap_done_f pciio_dmamap_done;
 extern pciio_dmatrans_addr_f pciio_dmatrans_addr;
-extern pciio_dmatrans_list_f pciio_dmatrans_list;
 extern pciio_dmamap_drain_f pciio_dmamap_drain;
 extern pciio_dmaaddr_drain_f pciio_dmaaddr_drain;
 extern pciio_dmalist_drain_f pciio_dmalist_drain;
@@ -580,34 +561,31 @@
 			unsigned flags);
 
 extern void
-pciio_error_register   (devfs_handle_t pconn,	/* which slot */
+pciio_error_register   (vertex_hdl_t pconn,	/* which slot */
 			error_handler_f *efunc,	/* function to call */
 			error_handler_arg_t einfo);	/* first parameter */
 
 extern void             pciio_driver_unregister(char *driver_prefix);
 
-typedef void		pciio_iter_f(devfs_handle_t pconn);	/* a connect point */
-
-extern void             pciio_iterate(char *driver_prefix,
-				      pciio_iter_f *func);
+typedef void		pciio_iter_f(vertex_hdl_t pconn);	/* a connect point */
 
 /* Interfaces used by PCI Bus Providers to talk to
  * the Generic PCI layer.
  */
-extern devfs_handle_t
-pciio_device_register  (devfs_handle_t connectpt,	/* vertex at center of bus */
-			devfs_handle_t master,	/* card's master ASIC (pci provider) */
+extern vertex_hdl_t
+pciio_device_register  (vertex_hdl_t connectpt,	/* vertex at center of bus */
+			vertex_hdl_t master,	/* card's master ASIC (pci provider) */
 			pciio_slot_t slot,	/* card's slot (0..?) */
 			pciio_function_t func,	/* card's func (0..?) */
 			pciio_vendor_id_t vendor,	/* card's vendor number */
 			pciio_device_id_t device);	/* card's device number */
 
 extern void
-pciio_device_unregister(devfs_handle_t connectpt);
+pciio_device_unregister(vertex_hdl_t connectpt);
 
 extern pciio_info_t
 pciio_device_info_new  (pciio_info_t pciio_info,	/* preallocated info struct */
-			devfs_handle_t master,	/* card's master ASIC (pci provider) */
+			vertex_hdl_t master,	/* card's master ASIC (pci provider) */
 			pciio_slot_t slot,	/* card's slot (0..?) */
 			pciio_function_t func,	/* card's func (0..?) */
 			pciio_vendor_id_t vendor,	/* card's vendor number */
@@ -616,24 +594,24 @@
 extern void
 pciio_device_info_free(pciio_info_t pciio_info);
 
-extern devfs_handle_t
+extern vertex_hdl_t
 pciio_device_info_register(
-			devfs_handle_t connectpt,	/* vertex at center of bus */
+			vertex_hdl_t connectpt,	/* vertex at center of bus */
 			pciio_info_t pciio_info);	/* details about conn point */
 
 extern void
 pciio_device_info_unregister(
-			devfs_handle_t connectpt,	/* vertex at center of bus */
+			vertex_hdl_t connectpt,	/* vertex at center of bus */
 			pciio_info_t pciio_info);	/* details about conn point */
 
 
 extern int              
 pciio_device_attach(
-			devfs_handle_t pcicard,   /* vertex created by pciio_device_register */
+			vertex_hdl_t pcicard,   /* vertex created by pciio_device_register */
 			int drv_flags);
 extern int
 pciio_device_detach(
-			devfs_handle_t pcicard,   /* vertex created by pciio_device_register */
+			vertex_hdl_t pcicard,   /* vertex created by pciio_device_register */
                         int drv_flags);
 
 
@@ -654,20 +632,12 @@
 			  size_t size);			/* size of free range */
 
 /* allocate window from mapping resource */
-#ifdef CONFIG_IA64_SGI_SN1
-extern iopaddr_t
-pciio_device_win_alloc(pciio_win_map_t win_map,		/* win map */
-		       pciio_win_alloc_t win_alloc,	/* opaque allocation cookie */
-		       size_t size,			/* size of allocation */
-		       size_t align);			/* alignment of allocation */
-#else
 extern iopaddr_t
-pciio_device_win_alloc(pciio_win_map_t win_map,		/* win map */
+pciio_device_win_alloc(struct resource * res,
 		       pciio_win_alloc_t win_alloc,	/* opaque allocation cookie */
 		       size_t start,			/* start unit, or 0 */
 		       size_t size,			/* size of allocation */
 		       size_t align);			/* alignment of allocation */
-#endif
 
 /* free previously allocated window */
 extern void
@@ -680,11 +650,11 @@
  */
 
 /* Generic PCI interrupt interfaces */
-extern devfs_handle_t     pciio_intr_dev_get(pciio_intr_t pciio_intr);
-extern devfs_handle_t     pciio_intr_cpu_get(pciio_intr_t pciio_intr);
+extern vertex_hdl_t     pciio_intr_dev_get(pciio_intr_t pciio_intr);
+extern vertex_hdl_t     pciio_intr_cpu_get(pciio_intr_t pciio_intr);
 
 /* Generic PCI pio interfaces */
-extern devfs_handle_t     pciio_pio_dev_get(pciio_piomap_t pciio_piomap);
+extern vertex_hdl_t     pciio_pio_dev_get(pciio_piomap_t pciio_piomap);
 extern pciio_slot_t     pciio_pio_slot_get(pciio_piomap_t pciio_piomap);
 extern pciio_space_t    pciio_pio_space_get(pciio_piomap_t pciio_piomap);
 extern iopaddr_t        pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap);
@@ -692,26 +662,26 @@
 extern caddr_t          pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap);
 
 /* Generic PCI dma interfaces */
-extern devfs_handle_t     pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap);
+extern vertex_hdl_t     pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap);
 
 /* Register/unregister PCI providers and get implementation handle */
-extern void             pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns);
-extern void             pciio_provider_unregister(devfs_handle_t provider);
-extern pciio_provider_t *pciio_provider_fns_get(devfs_handle_t provider);
+extern void             pciio_provider_register(vertex_hdl_t provider, pciio_provider_t *pciio_fns);
+extern void             pciio_provider_unregister(vertex_hdl_t provider);
+extern pciio_provider_t *pciio_provider_fns_get(vertex_hdl_t provider);
 
 /* Generic pci slot information access interface */
-extern pciio_info_t     pciio_info_chk(devfs_handle_t vhdl);
-extern pciio_info_t     pciio_info_get(devfs_handle_t vhdl);
-extern pciio_info_t     pciio_hostinfo_get(devfs_handle_t vhdl);
-extern void             pciio_info_set(devfs_handle_t vhdl, pciio_info_t widget_info);
-extern devfs_handle_t     pciio_info_dev_get(pciio_info_t pciio_info);
-extern devfs_handle_t     pciio_info_hostdev_get(pciio_info_t pciio_info);
+extern pciio_info_t     pciio_info_chk(vertex_hdl_t vhdl);
+extern pciio_info_t     pciio_info_get(vertex_hdl_t vhdl);
+extern pciio_info_t     pciio_hostinfo_get(vertex_hdl_t vhdl);
+extern void             pciio_info_set(vertex_hdl_t vhdl, pciio_info_t widget_info);
+extern vertex_hdl_t     pciio_info_dev_get(pciio_info_t pciio_info);
+extern vertex_hdl_t     pciio_info_hostdev_get(pciio_info_t pciio_info);
 extern pciio_bus_t	pciio_info_bus_get(pciio_info_t pciio_info);
 extern pciio_slot_t     pciio_info_slot_get(pciio_info_t pciio_info);
 extern pciio_function_t	pciio_info_function_get(pciio_info_t pciio_info);
 extern pciio_vendor_id_t pciio_info_vendor_id_get(pciio_info_t pciio_info);
 extern pciio_device_id_t pciio_info_device_id_get(pciio_info_t pciio_info);
-extern devfs_handle_t     pciio_info_master_get(pciio_info_t pciio_info);
+extern vertex_hdl_t     pciio_info_master_get(pciio_info_t pciio_info);
 extern arbitrary_info_t pciio_info_mfast_get(pciio_info_t pciio_info);
 extern pciio_provider_t *pciio_info_pops_get(pciio_info_t pciio_info);
 extern error_handler_f *pciio_info_efunc_get(pciio_info_t);
@@ -722,8 +692,8 @@
 extern iopaddr_t	pciio_info_rom_base_get(pciio_info_t);
 extern size_t		pciio_info_rom_size_get(pciio_info_t);
 extern int		pciio_info_type1_get(pciio_info_t);
-extern int              pciio_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
-extern int		pciio_dma_enabled(devfs_handle_t);
+extern int              pciio_error_handler(vertex_hdl_t, int, ioerror_mode_t, ioerror_t *);
+extern int		pciio_dma_enabled(vertex_hdl_t);
 
 #endif				/* C or C++ */
 #endif				/* _ASM_SN_PCI_PCIIO_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/pci/pciio_private.h linux-2.4.22-pre3/include/asm-ia64/sn/pci/pciio_private.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/pci/pciio_private.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/pci/pciio_private.h	2003-07-05 18:11:19.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIIO_PRIVATE_H
 #define _ASM_SN_PCI_PCIIO_PRIVATE_H
@@ -24,7 +24,7 @@
  */
 struct pciio_piomap_s {
     unsigned                pp_flags;	/* PCIIO_PIOMAP flags */
-    devfs_handle_t            pp_dev;	/* associated pci card */
+    vertex_hdl_t            pp_dev;	/* associated pci card */
     pciio_slot_t            pp_slot;	/* which slot the card is in */
     pciio_space_t           pp_space;	/* which address space */
     iopaddr_t               pp_pciaddr;		/* starting offset of mapping */
@@ -37,7 +37,7 @@
  */
 struct pciio_dmamap_s {
     unsigned                pd_flags;	/* PCIIO_DMAMAP flags */
-    devfs_handle_t            pd_dev;	/* associated pci card */
+    vertex_hdl_t            pd_dev;	/* associated pci card */
     pciio_slot_t            pd_slot;	/* which slot the card is in */
 };
 
@@ -47,7 +47,7 @@
 
 struct pciio_intr_s {
     unsigned                pi_flags;	/* PCIIO_INTR flags */
-    devfs_handle_t            pi_dev;	/* associated pci card */
+    vertex_hdl_t            pi_dev;	/* associated pci card */
     device_desc_t	    pi_dev_desc;	/* override device descriptor */
     pciio_intr_line_t       pi_lines;	/* which interrupt line(s) */
     intr_func_t             pi_func;	/* handler function (when connected) */
@@ -89,7 +89,7 @@
  * Opaque structure used to keep track of window allocation information.
  */
 struct pciio_win_alloc_s {
-	pciio_win_map_t	wa_map;		/* window map allocation is from */
+	struct resource *wa_resource;   /* window map allocation resource */
 	unsigned long	wa_base;	/* allocation starting page number */
 	size_t		wa_pages;	/* number of pages in allocation */
 };
@@ -100,13 +100,13 @@
 
 struct pciio_info_s {
     char                   *c_fingerprint;
-    devfs_handle_t            c_vertex;	/* back pointer to vertex */
+    vertex_hdl_t            c_vertex;	/* back pointer to vertex */
     pciio_bus_t             c_bus;	/* which bus the card is in */
     pciio_slot_t            c_slot;	/* which slot the card is in */
     pciio_function_t        c_func;	/* which func (on multi-func cards) */
     pciio_vendor_id_t       c_vendor;	/* PCI card "vendor" code */
     pciio_device_id_t       c_device;	/* PCI card "device" code */
-    devfs_handle_t            c_master;	/* PCI bus provider */
+    vertex_hdl_t            c_master;	/* PCI bus provider */
     arbitrary_info_t        c_mfast;	/* cached fastinfo from c_master */
     pciio_provider_t       *c_pops;	/* cached provider from c_master */
     error_handler_f        *c_efunc;	/* error handling function */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/pci/pic.h linux-2.4.22-pre3/include/asm-ia64/sn/pci/pic.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/pci/pic.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/pci/pic.h	2003-07-05 18:11:19.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PIC_H
 #define _ASM_SN_PCI_PIC_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/pda.h linux-2.4.22-pre3/include/asm-ia64/sn/pda.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/pda.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/pda.h	2003-07-05 18:11:19.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_PDA_H
 #define _ASM_IA64_SN_PDA_H
@@ -13,6 +13,7 @@
 #include <asm/system.h>
 #include <asm/processor.h>
 #include <asm/page.h>
+#include <linux/mmzone.h>
 #include <asm/sn/bte.h>
 
 
@@ -25,15 +26,6 @@
  * all SN per-cpu data structures. 
  */
 
-#ifdef BUS_INT_WAR
-#define POLL_ENTRIES	50
-typedef struct {
-	int	irq;
-	int	interval;
-	short	tick;
-} sn_poll_entry_t;
-#endif
-
 typedef struct pda_s {
 
 	/* Having a pointer in the begining of PDA tends to increase
@@ -47,31 +39,27 @@
 	/*
 	 * Support for SN LEDs
 	 */
-#ifdef CONFIG_IA64_SGI_SN1
-	volatile long	*led_address;
-#else
 	volatile short	*led_address;
-#endif
 	u8		led_state;
 	u8		hb_state;	/* supports blinking heartbeat leds */
+	u8		shub_1_1_found;
 	unsigned int	hb_count;
 
 	unsigned int	idle_flag;
 	
-#ifdef CONFIG_IA64_SGI_SN2
-	struct irqpda_s *p_irqpda;			/* Pointer to CPU irq data */
-#endif
 	volatile unsigned long *bedrock_rev_id;
 	volatile unsigned long *pio_write_status_addr;
 	volatile unsigned long *pio_shub_war_cam_addr;
 	volatile unsigned long *mem_write_status_addr;
 
-	bteinfo_t *cpu_bte_if[BTES_PER_NODE];	/* cpu interface order */
+	struct bteinfo_s *cpu_bte_if[BTES_PER_NODE];	/* cpu interface order */
 
-#ifdef BUS_INT_WAR
-	sn_poll_entry_t	pda_poll_entries[POLL_ENTRIES];
-	int		pda_poll_entry_count;
-#endif
+	unsigned long	sn_soft_irr[4];
+	unsigned long	sn_in_service_ivecs[4];
+	short		cnodeid_to_nasid_table[NR_NODES];	
+	int		sn_lb_int_war_ticks;
+	int		sn_last_irq;
+	int		sn_first_irq;
 } pda_t;
 
 
@@ -83,10 +71,10 @@
  * the IA64 cpu_data area. A full page is allocated for the cp_data area for each
  * cpu but only a small amout of the page is actually used. We put the SNIA PDA
  * in the same page as the cpu_data area. Note that there is a check in the setup
- * code to verify that we dont overflow the page.
+ * code to verify that we don't overflow the page.
  *
  * Seems like we should should cache-line align the pda so that any changes in the
- * size of the cpu_data area dont change cache layout. Should we align to 32, 64, 128
+ * size of the cpu_data area don't change cache layout. Should we align to 32, 64, 128
  * or 512 boundary. Each has merits. For now, pick 128 but should be revisited later.
  */
 #define CPU_DATA_END	CACHE_ALIGN((long)&(((struct cpuinfo_ia64*)0)->platform_specific))
@@ -96,5 +84,10 @@
 
 #define pdacpu(cpu)	(*((pda_t *) ((long)cpu_data(cpu) + CPU_DATA_END)))
 
+/*
+ * Use this macro to test if shub 1.1 wars should be enabled
+ */
+#define enable_shub_wars_1_1()	(pda.shub_1_1_found)
+
 
 #endif /* _ASM_IA64_SN_PDA_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/pio.h linux-2.4.22-pre3/include/asm-ia64/sn/pio.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/pio.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/pio.h	2003-07-05 18:11:19.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_PIO_H
 #define _ASM_IA64_SN_PIO_H
@@ -32,19 +32,11 @@
 typedef struct piomap {
 	uint		pio_bus;
 	uint		pio_adap;
-#ifdef LATER
-	iospace_t	pio_iospace;
-#endif
 	int		pio_flag;
 	int		pio_reg;
 	char		pio_name[7];	/* to identify the mapped device */
 	struct piomap	*pio_next;	/* dlist to link active piomap's */
 	struct piomap	*pio_prev;	/* for debug and error reporting */
-#ifdef LATER
-	void		(*pio_errfunc)(); /* Pointer to an error function */
-					  /* Used only for piomaps allocated
-					   * in user level vme driver     */
-#endif
 	iopaddr_t	pio_iopmask;	/* valid iop address bit mask */
 	iobush_t	pio_bushandle;	/* bus-level handle */
 } piomap_t;
@@ -60,54 +52,6 @@
 
 
 /*
- * pio_mapalloc() - allocates a handle that specifies a mapping from kernel
- *		    virtual to io space. The returned handle piomap is used
- *		    with the access functions to make sure that the mapping
- *		    to the iospace exists.
- * pio_mapfree()  - frees the mapping as specified in the piomap handle.
- * pio_mapaddr()  - returns the kv address that maps to piomap'ed io address.
- */
-#ifdef LATER
-extern piomap_t	*pio_mapalloc(uint,uint,iospace_t*,int,char*);
-extern void	 pio_mapfree(piomap_t*);
-extern caddr_t	 pio_mapaddr(piomap_t*,iopaddr_t);
-extern piomap_t *pio_ioaddr(int, iobush_t, iopaddr_t, piomap_t *);
-
-/*
- * PIO access functions.
- */
-extern int  pio_badaddr(piomap_t*,iopaddr_t,int);
-extern int  pio_badaddr_val(piomap_t*,iopaddr_t,int,void*);
-extern int  pio_wbadaddr(piomap_t*,iopaddr_t,int);
-extern int  pio_wbadaddr_val(piomap_t*,iopaddr_t,int,int);
-extern int  pio_bcopyin(piomap_t*,iopaddr_t,void *,int, int, int);
-extern int  pio_bcopyout(piomap_t*,iopaddr_t,void *,int, int, int);
-
-
-/*
- * PIO RMW functions using piomap.
- */
-extern void pio_orb_rmw(piomap_t*, iopaddr_t, unsigned char);
-extern void pio_orh_rmw(piomap_t*, iopaddr_t, unsigned short);
-extern void pio_orw_rmw(piomap_t*, iopaddr_t, unsigned long);
-extern void pio_andb_rmw(piomap_t*, iopaddr_t, unsigned char);
-extern void pio_andh_rmw(piomap_t*, iopaddr_t, unsigned short); 
-extern void pio_andw_rmw(piomap_t*, iopaddr_t, unsigned long); 
-
-
-/*
- * Old RMW function interface
- */
-extern void orb_rmw(volatile void*, unsigned int);
-extern void orh_rmw(volatile void*, unsigned int);
-extern void orw_rmw(volatile void*, unsigned int);
-extern void andb_rmw(volatile void*, unsigned int);
-extern void andh_rmw(volatile void*, unsigned int);
-extern void andw_rmw(volatile void*, unsigned int);
-#endif	/* LATER */
-
-
-/*
  * piomap_t type defines
  */
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/prio.h linux-2.4.22-pre3/include/asm-ia64/sn/prio.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/prio.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/prio.h	2003-07-05 18:11:19.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_PRIO_H
 #define _ASM_IA64_SN_PRIO_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/router.h linux-2.4.22-pre3/include/asm-ia64/sn/router.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/router.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/router.h	2003-07-05 18:11:19.000000000 -0700
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_ROUTER_H
@@ -494,19 +494,19 @@
 	slotid_t	ri_slotnum;	/* Which slot are we in?	    */
 	router_reg_t	ri_glbl_parms[GLBL_PARMS_REGS];
 					/* Global parms0&1 register contents*/
-	devfs_handle_t	ri_vertex;	/* hardware graph vertex            */
+	vertex_hdl_t	ri_vertex;	/* hardware graph vertex            */
 	router_reg_t	ri_prot_conf;	/* protection config. register	    */
 	int64_t	ri_per_minute;	/* Ticks per minute		    */
 
 	/*
 	 * Everything below here is for kernel use only and may change at	
-	 * at any time with or without a change in teh revision number
+	 * at any time with or without a change in the revision number
 	 *
 	 * Any pointers or things that come and go with DEBUG must go at
  	 * the bottom of the structure, below the user stuff.
 	 */
 	char		ri_hist_type;   /* histogram type		    */
-	devfs_handle_t	ri_guardian;	/* guardian node for the router	    */
+	vertex_hdl_t	ri_guardian;	/* guardian node for the router	    */
 	int64_t	ri_last_print;	/* When did we last print	    */
 	char		ri_print;	/* Should we print 		    */
 	char 		ri_just_blink;	/* Should we blink the LEDs         */
@@ -549,7 +549,7 @@
  * Router info hanging in the nodepda 
  */
 typedef struct nodepda_router_info_s {
-	devfs_handle_t 	router_vhdl;	/* vertex handle of the router 	    */
+	vertex_hdl_t 	router_vhdl;	/* vertex handle of the router 	    */
 	short		router_port;	/* port thru which we entered       */
 	short		router_portmask;
 	moduleid_t	router_module;	/* module in which router is there  */
@@ -593,9 +593,9 @@
 		 */
 		struct {
 			/* vertex handle for the router */
-			devfs_handle_t	vhdl;
+			vertex_hdl_t	vhdl;
 			/* guardian for this router */
-			devfs_handle_t	guard;	
+			vertex_hdl_t	guard;	
 			/* vector router from the guardian to the router */
 			net_vec_t	vec;
 		} k_elt;
@@ -648,8 +648,7 @@
 
 int router_reg_read(router_info_t *rip, int regno, router_reg_t *val);
 int router_reg_write(router_info_t *rip, int regno, router_reg_t val);
-int router_get_info(devfs_handle_t routerv, router_info_t *, int);
-int router_init(cnodeid_t cnode,int writeid, nodepda_router_info_t *npda_rip);
+int router_get_info(vertex_hdl_t routerv, router_info_t *, int);
 int router_set_leds(router_info_t *rip);
 void router_print_state(router_info_t *rip, int level,
 		   void (*pf)(int, char *, ...),int print_where);
@@ -658,7 +657,7 @@
 
 int 	probe_routers(void);
 void 	get_routername(unsigned char brd_type,char *rtrname);
-void 	router_guardians_set(devfs_handle_t hwgraph_root);
+void 	router_guardians_set(vertex_hdl_t hwgraph_root);
 int 	router_hist_reselect(router_info_t *, int64_t);
 #endif /* __ASSEMBLY__ */
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/rw_mmr.h linux-2.4.22-pre3/include/asm-ia64/sn/rw_mmr.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/rw_mmr.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/rw_mmr.h	2003-07-05 18:11:20.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_IA64_SN_RW_MMR_H
 #define _ASM_IA64_SN_RW_MMR_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sgi.h linux-2.4.22-pre3/include/asm-ia64/sn/sgi.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sgi.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sgi.h	2003-07-05 18:11:20.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -17,14 +17,18 @@
 #include <asm/uaccess.h>		/* for copy_??_user */
 #include <linux/mm.h>
 #include <linux/devfs_fs_kernel.h>
+#ifdef CONFIG_HWGFS_FS
+#include <linux/fs.h>
+#include <asm/sn/hwgfs.h>
+typedef hwgfs_handle_t vertex_hdl_t;
+#else
+typedef devfs_handle_t vertex_hdl_t;
+#endif
 
 typedef int64_t  __psint_t;	/* needed by klgraph.c */
 
 typedef enum { B_FALSE, B_TRUE } boolean_t;
 
-#define ctob(x)			((uint64_t)(x)*NBPC)
-#define btoc(x)			(((uint64_t)(x)+(NBPC-1))/NBPC)
-
 
 /*
 ** Possible return values from graph routines.
@@ -50,28 +54,13 @@
 typedef uint64_t vhandl_t;
 
 
-#ifndef NBPP
-#define NBPP 4096
-#endif
-
-#ifndef D_MP
-#define D_MP 1
-#endif
+#define NBPP PAGE_SIZE
+#define _PAGESZ PAGE_SIZE
 
 #ifndef MAXDEVNAME
 #define MAXDEVNAME 256
 #endif
 
-#ifndef NBPC
-#define NBPC 0
-#endif
-
-#ifndef _PAGESZ
-#define _PAGESZ 4096
-#endif
-
-typedef uint64_t mrlock_t;	/* needed by devsupport.c */
-
 #define HUB_PIO_CONVEYOR 0x1
 #define CNODEID_NONE ((cnodeid_t)-1)
 #define XTALK_PCI_PART_NUM "030-1275-"
@@ -81,10 +70,6 @@
 #define COPYIN(a, b, c)		copy_from_user(b,a,c)
 #define COPYOUT(a, b, c)	copy_to_user(b,a,c)
 
-#define kvtophys(x)		(alenaddr_t) (x)
-#define POFFMASK		(NBPP - 1)
-#define poff(X)			((__psunsigned_t)(X) & POFFMASK)
-
 #define BZERO(a,b)		memset(a, 0, b)
 
 #define kern_malloc(x)		kmalloc(x, GFP_KERNEL)
@@ -141,12 +126,6 @@
 
 #define PRINT_PANIC		panic
 
-#ifdef CONFIG_SMP
-#define cpu_enabled(cpu)        (test_bit(cpu, &cpu_online_map))
-#else
-#define cpu_enabled(cpu)	(1)
-#endif
-
 /* print_register() defs */
 
 /*
@@ -172,6 +151,31 @@
 
 extern void print_register(unsigned long long, struct reg_desc *);
 
-#include <asm/sn/hack.h>	/* for now */
+/******************************************
+ * Definitions that do not exist in linux *
+ ******************************************/
+
+#define DELAY(a)
+
+/************************************************
+ * Routines redefined to use linux equivalents. *
+ ************************************************/
+
+/* #define FIXME(s) printk("FIXME: [ %s ] in %s at %s:%d\n", s, __FUNCTION__, __FILE__, __LINE__) */
+
+#define FIXME(s)
+
+/* move to stubs.c yet */
+#define dev_to_vhdl(dev) 0
+#define get_timestamp() 0
+#define us_delay(a)
+#define v_mapphys(a,b,c) 0    // printk("Fixme: v_mapphys - soft->base 0x%p\n", b);
+#define splhi()  0
+#define splx(s)
+
+extern void * snia_kmem_alloc_node(register size_t, register int, cnodeid_t);
+extern void * snia_kmem_zalloc(size_t, int);
+extern void * snia_kmem_zalloc_node(register size_t, register int, cnodeid_t );
+extern int is_specified(char *);
 
 #endif /* _ASM_IA64_SN_SGI_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/simulator.h linux-2.4.22-pre3/include/asm-ia64/sn/simulator.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/simulator.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/simulator.h	2003-07-05 18:11:20.000000000 -0700
@@ -5,7 +5,7 @@
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/slotnum.h linux-2.4.22-pre3/include/asm-ia64/sn/slotnum.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/slotnum.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/slotnum.h	2003-07-05 18:11:20.000000000 -0700
@@ -4,23 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SLOTNUM_H
 #define _ASM_IA64_SN_SLOTNUM_H
 
-#include <linux/config.h>
 
 typedef	unsigned char slotid_t;
 
-#if defined (CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/slotnum.h>
-#elif defined (CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/slotnum.h>
-#else
-
-#error <<BOMB! slotnum defined only for SN0 and SN1 >>
-
-#endif /* !CONFIG_IA64_SGI_SN1 */
 
 #endif /* _ASM_IA64_SN_SLOTNUM_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/addrs.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/addrs.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/addrs.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/addrs.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,275 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_ADDRS_H
-#define _ASM_IA64_SN_SN1_ADDRS_H
-
-#include <linux/config.h>
-
-#ifdef CONFIG_IA64_SGI_SN1
-/*
- * SN1 (on a TRex) Address map
- *
- * This file contains a set of definitions and macros which are used
- * to reference into the major address spaces (CAC, HSPEC, IO, MSPEC,
- * and UNCAC) used by the SN1 architecture.  It also contains addresses
- * for "major" statically locatable PROM/Kernel data structures, such as
- * the partition table, the configuration data structure, etc.
- * We make an implicit assumption that the processor using this file
- * follows the R12K's provisions for specifying uncached attributes;
- * should this change, the base registers may very well become processor-
- * dependent.
- *
- * For more information on the address spaces, see the "Local Resources"
- * chapter of the Hub specification.
- *
- * NOTE: This header file is included both by C and by assembler source
- *	 files.  Please bracket any language-dependent definitions
- *	 appropriately.
- */
-
-
-/*
- * Some of the macros here need to be casted to appropriate types when used
- * from C.  They definitely must not be casted from assembly language so we
- * use some new ANSI preprocessor stuff to paste these on where needed.
- */
-
-#define CACHEABLE_MEM_SPACE     0xe000000000000000
-#define CAC_BASE		CACHEABLE_MEM_SPACE
-#define HSPEC_BASE              0xc0000b0000000000
-#define HSPEC_SWIZ_BASE         0xc000030000000000
-#define IO_BASE                 0xc0000a0000000000
-#define IO_SWIZ_BASE            0xc000020000000000
-#define MSPEC_BASE              0xc000090000000000
-#define UNCAC_BASE              0xc000000000000000
-#define TO_PHYS_MASK		0x000000ffffffffff
-
-#define TO_PHYS(x)		(	      ((x) & TO_PHYS_MASK))
-#define TO_CAC(x)		(CAC_BASE   | ((x) & TO_PHYS_MASK))
-#define TO_UNCAC(x)		(UNCAC_BASE | ((x) & TO_PHYS_MASK))
-#define TO_MSPEC(x)		(MSPEC_BASE | ((x) & TO_PHYS_MASK))
-#define TO_HSPEC(x)		(HSPEC_BASE | ((x) & TO_PHYS_MASK))
-
-
-/*
- * The following couple of definitions will eventually need to be variables,
- * since the amount of address space assigned to each node depends on
- * whether the system is running in N-mode (more nodes with less memory)
- * or M-mode (fewer nodes with more memory).  We expect that it will
- * be a while before we need to make this decision dynamically, though,
- * so for now we just use defines bracketed by an ifdef.
- */
-
-#if defined(N_MODE)
-
-#define NODE_SIZE_BITS		32
-#define BWIN_SIZE_BITS		28
-
-#define NASID_BITS		8
-#define NASID_BITMASK		(0xffLL)
-#define NASID_SHFT		32
-#define NASID_META_BITS		1
-#define NASID_LOCAL_BITS	7
-
-#define BDDIR_UPPER_MASK	(UINT64_CAST 0x1ffffff << 4)
-#define BDECC_UPPER_MASK	(UINT64_CAST 0x1fffffff )
-
-#else /* !defined(N_MODE), assume that M-mode is desired */
-
-#define NODE_SIZE_BITS		33
-#define BWIN_SIZE_BITS		29
-
-#define NASID_BITMASK		(0x7fLL)
-#define NASID_BITS		7
-#define NASID_SHFT		33
-#define NASID_META_BITS		0
-#define NASID_LOCAL_BITS	7
-
-#define BDDIR_UPPER_MASK	(UINT64_CAST 0x3ffffff << 4)
-#define BDECC_UPPER_MASK	(UINT64_CAST 0x3fffffff)
-
-#endif /* defined(N_MODE) */
-
-#define NODE_ADDRSPACE_SIZE	(UINT64_CAST 1 << NODE_SIZE_BITS)
-
-#define NASID_MASK		(UINT64_CAST NASID_BITMASK << NASID_SHFT)
-#define NASID_GET(_pa)		(int) ((UINT64_CAST (_pa) >>		\
-					NASID_SHFT) & NASID_BITMASK)
-
-#ifndef __ASSEMBLY__
-#define NODE_SWIN_BASE(nasid, widget)					\
-	((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN)		\
-	: RAW_NODE_SWIN_BASE(nasid, widget))
-#else
-#define NODE_SWIN_BASE(nasid, widget) \
-     (NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS))
-#endif /* __ASSEMBLY__ */
-
-/*
- * The following definitions pertain to the IO special address
- * space.  They define the location of the big and little windows
- * of any given node.
- */
-
-#define BWIN_INDEX_BITS		3
-#define BWIN_SIZE		(UINT64_CAST 1 << BWIN_SIZE_BITS)
-#define	BWIN_SIZEMASK		(BWIN_SIZE - 1)
-#define	BWIN_WIDGET_MASK	0x7
-#define NODE_BWIN_BASE0(nasid)	(NODE_IO_BASE(nasid) + BWIN_SIZE)
-#define NODE_BWIN_BASE(nasid, bigwin)	(NODE_BWIN_BASE0(nasid) + 	\
-			(UINT64_CAST (bigwin) << BWIN_SIZE_BITS))
-
-#define	BWIN_WIDGETADDR(addr)	((addr) & BWIN_SIZEMASK)
-#define	BWIN_WINDOWNUM(addr)	(((addr) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK)
-/*
- * Verify if addr belongs to large window address of node with "nasid"
- *
- *
- * NOTE: "addr" is expected to be XKPHYS address, and NOT physical
- * address
- *
- *
- */
-
-#define	NODE_BWIN_ADDR(nasid, addr)	\
-		(((addr) >= NODE_BWIN_BASE0(nasid)) && \
-		 ((addr) < (NODE_BWIN_BASE(nasid, HUB_NUM_BIG_WINDOW) + \
-				BWIN_SIZE)))
-
-/*
- * The following define the major position-independent aliases used
- * in SN1.
- *	CALIAS -- Varies in size, points to the first n bytes of memory
- *		  	on the reader's node.
- */
-
-#define CALIAS_BASE		CAC_BASE
-
-
-
-#define BRIDGE_REG_PTR(_base, _off)	((volatile bridgereg_t *) \
-	((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
-
-#define SN0_WIDGET_BASE(_nasid, _wid)	(NODE_SWIN_BASE((_nasid), (_wid)))
-
-
-
-/*
- * needed by symmon so it needs to be outside #if PROM
- * (see also POD_ELSCSIZE)
- */
-#define IP27PROM_ELSC_BASE_A	PHYS_TO_K0(0x020e0000)
-#define IP27PROM_ELSC_BASE_B	PHYS_TO_K0(0x020e0800)
-#define IP27PROM_ELSC_BASE_C	PHYS_TO_K0(0x020e1000)
-#define IP27PROM_ELSC_BASE_D	PHYS_TO_K0(0x020e1800)
-#define IP27PROM_ELSC_SHFT	11
-#define IP27PROM_ELSC_SIZE	(1 << IP27PROM_ELSC_SHFT)
-
-#define FREEMEM_BASE		PHYS_TO_K0(0x4000000)
-
-#define IO6PROM_STACK_SHFT	14	/* stack per cpu */
-#define IO6PROM_STACK_SIZE	(1 << IO6PROM_STACK_SHFT)
-
-
-#define KL_UART_BASE	LOCAL_HSPEC(HSPEC_UART_0)	/* base of UART regs */
-#define KL_UART_CMD	LOCAL_HSPEC(HSPEC_UART_0)	/* UART command reg */
-#define KL_UART_DATA	LOCAL_HSPEC(HSPEC_UART_1)	/* UART data reg */
-
-#if !__ASSEMBLY__
-/* Address 0x400 to 0x1000 ualias points to cache error eframe + misc
- * CACHE_ERR_SP_PTR could either contain an address to the stack, or
- * the stack could start at CACHE_ERR_SP_PTR
- */
-#define CACHE_ERR_EFRAME	0x400
-
-#define CACHE_ERR_ECCFRAME	(CACHE_ERR_EFRAME + EF_SIZE)
-#define CACHE_ERR_SP_PTR	(0x1000 - 32)	/* why -32? TBD */
-#define CACHE_ERR_IBASE_PTR	(0x1000 - 40)
-#define CACHE_ERR_SP		(CACHE_ERR_SP_PTR - 16)
-#define CACHE_ERR_AREA_SIZE	(ARCS_SPB_OFFSET - CACHE_ERR_EFRAME)
-
-#endif	/* !__ASSEMBLY__ */
-
-
-
-#define _ARCSPROM
-
-#ifdef _STANDALONE
-
-/*
- * The PROM needs to pass the device base address and the
- * device pci cfg space address to the device drivers during
- * install. The COMPONENT->Key field is used for this purpose.
- * Macros needed by SN1 device drivers to convert the
- * COMPONENT->Key field to the respective base address.
- * Key field looks as follows:
- *
- *  +----------------------------------------------------+
- *  |devnasid | widget  |pciid |hubwidid|hstnasid | adap |
- *  |   2     |   1     |  1   |   1    |    2    |   1  |
- *  +----------------------------------------------------+
- *  |         |         |      |        |         |      |
- *  64        48        40     32       24        8      0
- *
- * These are used by standalone drivers till the io infrastructure
- * is in place.
- */
-
-#ifndef __ASSEMBLY__
-
-#define uchar unsigned char
-
-#define KEY_DEVNASID_SHFT  48
-#define KEY_WIDID_SHFT	   40
-#define KEY_PCIID_SHFT	   32
-#define KEY_HUBWID_SHFT	   24
-#define KEY_HSTNASID_SHFT  8
-
-#define MK_SN0_KEY(nasid, widid, pciid) \
-			((((__psunsigned_t)nasid)<< KEY_DEVNASID_SHFT |\
-				((__psunsigned_t)widid) << KEY_WIDID_SHFT) |\
-				((__psunsigned_t)pciid) << KEY_PCIID_SHFT)
-
-#define ADD_HUBWID_KEY(key,hubwid)\
-			(key|=((__psunsigned_t)hubwid << KEY_HUBWID_SHFT))
-
-#define ADD_HSTNASID_KEY(key,hstnasid)\
-			(key|=((__psunsigned_t)hstnasid << KEY_HSTNASID_SHFT))
-
-#define GET_DEVNASID_FROM_KEY(key)	((short)(key >> KEY_DEVNASID_SHFT))
-#define GET_WIDID_FROM_KEY(key)		((uchar)(key >> KEY_WIDID_SHFT))
-#define GET_PCIID_FROM_KEY(key)		((uchar)(key >> KEY_PCIID_SHFT))
-#define GET_HUBWID_FROM_KEY(key)	((uchar)(key >> KEY_HUBWID_SHFT))
-#define GET_HSTNASID_FROM_KEY(key)	((short)(key >> KEY_HSTNASID_SHFT))
-
-#define PCI_64_TARGID_SHFT		60
-
-#define GET_PCIBASE_FROM_KEY(key)  (NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\
-					GET_WIDID_FROM_KEY(key))\
-					| BRIDGE_DEVIO(GET_PCIID_FROM_KEY(key)))
-
-#define GET_PCICFGBASE_FROM_KEY(key) \
-			(NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\
-			      GET_WIDID_FROM_KEY(key))\
-			| BRIDGE_TYPE0_CFG_DEV(GET_PCIID_FROM_KEY(key)))
-
-#define GET_WIDBASE_FROM_KEY(key) \
-                        (NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\
-                              GET_WIDID_FROM_KEY(key)))
-
-#define PUT_INSTALL_STATUS(c,s)		c->Revision = s
-#define GET_INSTALL_STATUS(c)		c->Revision
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _STANDALONE */
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-#endif /* _ASM_IA64_SN_SN1_ADDRS_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/arch.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/arch.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/arch.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/arch.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,89 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_ARCH_H
-#define _ASM_IA64_SN_SN1_ARCH_H
-
-#if defined(N_MODE)
-#error "ERROR constants defined only for M-mode"
-#endif
-
-#include <linux/threads.h>
-#include <asm/types.h>
-
-#define CPUS_PER_NODE           4       /* CPUs on a single hub */
-#define CPUS_PER_SUBNODE        2       /* CPUs on a single hub PI */
-
-/*
- * This is the maximum number of NASIDS that can be present in a system.
- * This include ALL nodes in ALL partitions connected via NUMALINK.
- * (Highest NASID plus one.)
- */
-#define MAX_NASIDS              128
-
-/*
- * This is the maximum number of nodes that can be part of a kernel.
- * Effectively, it's the maximum number of compact node ids (cnodeid_t).
- * This is not necessarily the same as MAX_NASIDS.
- */
-#define MAX_COMPACT_NODES       128
-
-/*
- * MAX_REGIONS refers to the maximum number of hardware partitioned regions.
- */
-#define	MAX_REGIONS		64
-#define MAX_NONPREMIUM_REGIONS  16
-#define MAX_PREMIUM_REGIONS     MAX_REGIONS
-
-/*
- * Slot constants for IP35
- */
-
-#define MAX_MEM_SLOTS    8                     /* max slots per node */
-
-#if defined(N_MODE)
-#error "N-mode not supported"
-#endif
-
-#define SLOT_SHIFT              (30)
-#define SLOT_MIN_MEM_SIZE       (64*1024*1024)
-
-
-/*
- * MAX_PARITIONS refers to the maximum number of logically defined 
- * partitions the system can support.
- */
-#define MAX_PARTITIONS		MAX_REGIONS
-
-
-#define NASID_MASK_BYTES	((MAX_NASIDS + 7) / 8)
-
-/*
- * New stuff in here from Irix sys/pfdat.h.
- */
-#define SLOT_PFNSHIFT           (SLOT_SHIFT - PAGE_SHIFT)
-#define PFN_NASIDSHFT           (NASID_SHFT - PAGE_SHIFT)
-#define slot_getbasepfn(node,slot)  (mkpfn(COMPACT_TO_NASID_NODEID(node), slot<<SLOT_PFNSHIFT))
-#define mkpfn(nasid, off)       (((pfn_t)(nasid) << PFN_NASIDSHFT) | (off))
-
-
-
-/*
- * two PIs per bedrock, two CPUs per PI
- */
-#define NUM_SUBNODES	2
-#define SUBNODE_SHFT	1
-#define SUBNODE_MASK	(0x1 << SUBNODE_SHFT)
-#define LOCALCPU_SHFT	0
-#define LOCALCPU_MASK	(0x1 << LOCALCPU_SHFT)
-#define SUBNODE(slice)	(((slice) & SUBNODE_MASK) >> SUBNODE_SHFT)
-#define LOCALCPU(slice)	(((slice) & LOCALCPU_MASK) >> LOCALCPU_SHFT)
-#define TO_SLICE(subn, local)	(((subn) << SUBNODE_SHFT) | \
-				 ((local) << LOCALCPU_SHFT))
-
-#endif /* _ASM_IA64_SN_SN1_ARCH_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/bedrock.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/bedrock.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/bedrock.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/bedrock.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,74 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_BEDROCK_H
-#define _ASM_IA64_SN_SN1_BEDROCK_H
-
-
-/* The secret password; used to release protection */
-#define HUB_PASSWORD		0x53474972756c6573ull
-
-#define CHIPID_HUB		0x3012
-#define CHIPID_ROUTER		0x3017
-
-#define BEDROCK_REV_1_0		1
-#define BEDROCK_REV_1_1		2
-
-#define MAX_HUB_PATH		80
-
-#include <asm/sn/arch.h>
-#include <asm/sn/sn1/addrs.h>
-#include <asm/sn/sn1/hubpi.h>
-#include <asm/sn/sn1/hubmd.h>
-#include <asm/sn/sn1/hubio.h>
-#include <asm/sn/sn1/hubni.h>
-#include <asm/sn/sn1/hublb.h>
-#include <asm/sn/sn1/hubxb.h>
-#include <asm/sn/sn1/hubpi_next.h>
-#include <asm/sn/sn1/hubmd_next.h>
-#include <asm/sn/sn1/hubio_next.h>
-#include <asm/sn/sn1/hubni_next.h>
-#include <asm/sn/sn1/hublb_next.h>
-#include <asm/sn/sn1/hubxb_next.h>
-
-/* Translation of uncached attributes */
-#define	UATTR_HSPEC	0
-#define	UATTR_IO	1
-#define	UATTR_MSPEC	2
-#define	UATTR_UNCAC	3
-
-#if __ASSEMBLY__
-
-/*
- * Get nasid into register, r (uses at)
- */
-#define GET_NASID_ASM(r)				\
-	dli	r, LOCAL_HUB_ADDR(LB_REV_ID);	\
-	ld	r, (r);					\
-	and	r, LRI_NODEID_MASK;			\
-	dsrl	r, LRI_NODEID_SHFT
-
-#endif /* __ASSEMBLY__ */
-
-#ifndef __ASSEMBLY__
-
-#include <asm/sn/xtalk/xwidget.h>
-
-/* hub-as-widget iograph info, labelled by INFO_LBL_XWIDGET */
-typedef struct v_hub_s *v_hub_t;
-typedef uint64_t      rtc_time_t;
-
-struct nodepda_s;
-int hub_check_pci_equiv(void *addra, void *addrb);
-void capture_hub_stats(cnodeid_t, struct nodepda_s *);
-void init_hub_stats(cnodeid_t, struct nodepda_s *);
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_IA64_SN_SN1_BEDROCK_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubdev.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubdev.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubdev.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubdev.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,21 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_HUBDEV_H
-#define _ASM_IA64_SN_SN1_HUBDEV_H
-
-extern void hubdev_init(void);
-extern void hubdev_register(int (*attach_method)(devfs_handle_t));
-extern int hubdev_unregister(int (*attach_method)(devfs_handle_t));
-extern int hubdev_docallouts(devfs_handle_t hub);
-
-extern caddr_t hubdev_prombase_get(devfs_handle_t hub);
-extern cnodeid_t hubdev_cnodeid_get(devfs_handle_t hub);
-
-#endif /* _ASM_IA64_SN_SN1_HUBDEV_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubio.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubio.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubio.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubio.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,5016 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-
-#ifndef _ASM_IA64_SN_SN1_HUBIO_H
-#define _ASM_IA64_SN_SN1_HUBIO_H
-
-
-#define    IIO_WID                   0x00400000    /*
-                                                    * Crosstalk Widget
-                                                    * Identification This
-                                                    * register is also
-                                                    * accessible from
-                                                    * Crosstalk at
-                                                    * address 0x0.
-                                                    */
-
-
-
-#define    IIO_WSTAT                 0x00400008    /*
-                                                    * Crosstalk Widget
-                                                    * Status
-                                                    */
-
-
-
-#define    IIO_WCR                   0x00400020    /*
-                                                    * Crosstalk Widget
-                                                    * Control Register
-                                                    */
-
-
-
-#define    IIO_ILAPR                 0x00400100    /*
-                                                    * IO Local Access
-                                                    * Protection Register
-                                                    */
-
-
-
-#define    IIO_ILAPO                 0x00400108    /*
-                                                    * IO Local Access
-                                                    * Protection Override
-                                                    */
-
-
-
-#define    IIO_IOWA                  0x00400110    /*
-                                                    * IO Outbound Widget
-                                                    * Access
-                                                    */
-
-
-
-#define    IIO_IIWA                  0x00400118    /*
-                                                    * IO Inbound Widget
-                                                    * Access
-                                                    */
-
-
-
-#define    IIO_IIDEM                 0x00400120    /*
-                                                    * IO Inbound Device
-                                                    * Error Mask
-                                                    */
-
-
-
-#define    IIO_ILCSR                 0x00400128    /*
-                                                    * IO LLP Control and
-                                                    * Status Register
-                                                    */
-
-
-
-#define    IIO_ILLR                  0x00400130    /* IO LLP Log Register    */
-
-
-
-#define    IIO_IIDSR                 0x00400138    /*
-                                                    * IO Interrupt
-                                                    * Destination
-                                                    */
-
-
-
-#define    IIO_IGFX0                 0x00400140    /*
-                                                    * IO Graphics
-                                                    * Node-Widget Map 0
-                                                    */
-
-
-
-#define    IIO_IGFX1                 0x00400148    /*
-                                                    * IO Graphics
-                                                    * Node-Widget Map 1
-                                                    */
-
-
-
-#define    IIO_ISCR0                 0x00400150    /*
-                                                    * IO Scratch Register
-                                                    * 0
-                                                    */
-
-
-
-#define    IIO_ISCR1                 0x00400158    /*
-                                                    * IO Scratch Register
-                                                    * 1
-                                                    */
-
-
-
-#define    IIO_ITTE1                 0x00400160    /*
-                                                    * IO Translation
-                                                    * Table Entry 1
-                                                    */
-
-
-
-#define    IIO_ITTE2                 0x00400168    /*
-                                                    * IO Translation
-                                                    * Table Entry 2
-                                                    */
-
-
-
-#define    IIO_ITTE3                 0x00400170    /*
-                                                    * IO Translation
-                                                    * Table Entry 3
-                                                    */
-
-
-
-#define    IIO_ITTE4                 0x00400178    /*
-                                                    * IO Translation
-                                                    * Table Entry 4
-                                                    */
-
-
-
-#define    IIO_ITTE5                 0x00400180    /*
-                                                    * IO Translation
-                                                    * Table Entry 5
-                                                    */
-
-
-
-#define    IIO_ITTE6                 0x00400188    /*
-                                                    * IO Translation
-                                                    * Table Entry 6
-                                                    */
-
-
-
-#define    IIO_ITTE7                 0x00400190    /*
-                                                    * IO Translation
-                                                    * Table Entry 7
-                                                    */
-
-
-
-#define    IIO_IPRB0                 0x00400198    /* IO PRB Entry 0         */
-
-
-
-#define    IIO_IPRB8                 0x004001A0    /* IO PRB Entry 8         */
-
-
-
-#define    IIO_IPRB9                 0x004001A8    /* IO PRB Entry 9         */
-
-
-
-#define    IIO_IPRBA                 0x004001B0    /* IO PRB Entry A         */
-
-
-
-#define    IIO_IPRBB                 0x004001B8    /* IO PRB Entry B         */
-
-
-
-#define    IIO_IPRBC                 0x004001C0    /* IO PRB Entry C         */
-
-
-
-#define    IIO_IPRBD                 0x004001C8    /* IO PRB Entry D         */
-
-
-
-#define    IIO_IPRBE                 0x004001D0    /* IO PRB Entry E         */
-
-
-
-#define    IIO_IPRBF                 0x004001D8    /* IO PRB Entry F         */
-
-
-
-#define    IIO_IXCC                  0x004001E0    /*
-                                                    * IO Crosstalk Credit
-                                                    * Count Timeout
-                                                    */
-
-
-
-#define    IIO_IMEM                  0x004001E8    /*
-                                                    * IO Miscellaneous
-                                                    * Error Mask
-                                                    */
-
-
-
-#define    IIO_IXTT                  0x004001F0    /*
-                                                    * IO Crosstalk
-                                                    * Timeout Threshold
-                                                    */
-
-
-
-#define    IIO_IECLR                 0x004001F8    /*
-                                                    * IO Error Clear
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_IBCR                  0x00400200    /*
-                                                    * IO BTE Control
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_IXSM                  0x00400208    /*
-                                                    * IO Crosstalk
-                                                    * Spurious Message
-                                                    */
-
-
-
-#define    IIO_IXSS                  0x00400210    /*
-                                                    * IO Crosstalk
-                                                    * Spurious Sideband
-                                                    */
-
-
-
-#define    IIO_ILCT                  0x00400218    /* IO LLP Channel Test    */
-
-
-
-#define    IIO_IIEPH1                0x00400220    /*
-                                                    * IO Incoming Error
-                                                    * Packet Header, Part
-                                                    * 1
-                                                    */
-
-
-
-#define    IIO_IIEPH2                0x00400228    /*
-                                                    * IO Incoming Error
-                                                    * Packet Header, Part
-                                                    * 2
-                                                    */
-
-
-
-#define    IIO_IPCA                  0x00400300    /*
-                                                    * IO PRB Counter
-                                                    * Adjust
-                                                    */
-
-
-
-#define    IIO_IPRTE0                0x00400308    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 0
-                                                    */
-
-
-
-#define    IIO_IPRTE1                0x00400310    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 1
-                                                    */
-
-
-
-#define    IIO_IPRTE2                0x00400318    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 2
-                                                    */
-
-
-
-#define    IIO_IPRTE3                0x00400320    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 3
-                                                    */
-
-
-
-#define    IIO_IPRTE4                0x00400328    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 4
-                                                    */
-
-
-
-#define    IIO_IPRTE5                0x00400330    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 5
-                                                    */
-
-
-
-#define    IIO_IPRTE6                0x00400338    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 6
-                                                    */
-
-
-
-#define    IIO_IPRTE7                0x00400340    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 7
-                                                    */
-
-
-
-#define    IIO_IPDR                  0x00400388    /*
-                                                    * IO PIO Deallocation
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_ICDR                  0x00400390    /*
-                                                    * IO CRB Entry
-                                                    * Deallocation
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_IFDR                  0x00400398    /*
-                                                    * IO IOQ FIFO Depth
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_IIAP                  0x004003A0    /*
-                                                    * IO IIQ Arbitration
-                                                    * Parameters
-                                                    */
-
-
-
-#define    IIO_ICMR                  0x004003A8    /*
-                                                    * IO CRB Management
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_ICCR                  0x004003B0    /*
-                                                    * IO CRB Control
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_ICTO                  0x004003B8    /* IO CRB Timeout         */
-
-
-
-#define    IIO_ICTP                  0x004003C0    /*
-                                                    * IO CRB Timeout
-                                                    * Prescalar
-                                                    */
-
-
-
-#define    IIO_ICRB0_A               0x00400400    /* IO CRB Entry 0_A       */
-
-
-
-#define    IIO_ICRB0_B               0x00400408    /* IO CRB Entry 0_B       */
-
-
-
-#define    IIO_ICRB0_C               0x00400410    /* IO CRB Entry 0_C       */
-
-
-
-#define    IIO_ICRB0_D               0x00400418    /* IO CRB Entry 0_D       */
-
-
-
-#define    IIO_ICRB1_A               0x00400420    /* IO CRB Entry 1_A       */
-
-
-
-#define    IIO_ICRB1_B               0x00400428    /* IO CRB Entry 1_B       */
-
-
-
-#define    IIO_ICRB1_C               0x00400430    /* IO CRB Entry 1_C       */
-
-
-
-#define    IIO_ICRB1_D               0x00400438    /* IO CRB Entry 1_D       */
-
-
-
-#define    IIO_ICRB2_A               0x00400440    /* IO CRB Entry 2_A       */
-
-
-
-#define    IIO_ICRB2_B               0x00400448    /* IO CRB Entry 2_B       */
-
-
-
-#define    IIO_ICRB2_C               0x00400450    /* IO CRB Entry 2_C       */
-
-
-
-#define    IIO_ICRB2_D               0x00400458    /* IO CRB Entry 2_D       */
-
-
-
-#define    IIO_ICRB3_A               0x00400460    /* IO CRB Entry 3_A       */
-
-
-
-#define    IIO_ICRB3_B               0x00400468    /* IO CRB Entry 3_B       */
-
-
-
-#define    IIO_ICRB3_C               0x00400470    /* IO CRB Entry 3_C       */
-
-
-
-#define    IIO_ICRB3_D               0x00400478    /* IO CRB Entry 3_D       */
-
-
-
-#define    IIO_ICRB4_A               0x00400480    /* IO CRB Entry 4_A       */
-
-
-
-#define    IIO_ICRB4_B               0x00400488    /* IO CRB Entry 4_B       */
-
-
-
-#define    IIO_ICRB4_C               0x00400490    /* IO CRB Entry 4_C       */
-
-
-
-#define    IIO_ICRB4_D               0x00400498    /* IO CRB Entry 4_D       */
-
-
-
-#define    IIO_ICRB5_A               0x004004A0    /* IO CRB Entry 5_A       */
-
-
-
-#define    IIO_ICRB5_B               0x004004A8    /* IO CRB Entry 5_B       */
-
-
-
-#define    IIO_ICRB5_C               0x004004B0    /* IO CRB Entry 5_C       */
-
-
-
-#define    IIO_ICRB5_D               0x004004B8    /* IO CRB Entry 5_D       */
-
-
-
-#define    IIO_ICRB6_A               0x004004C0    /* IO CRB Entry 6_A       */
-
-
-
-#define    IIO_ICRB6_B               0x004004C8    /* IO CRB Entry 6_B       */
-
-
-
-#define    IIO_ICRB6_C               0x004004D0    /* IO CRB Entry 6_C       */
-
-
-
-#define    IIO_ICRB6_D               0x004004D8    /* IO CRB Entry 6_D       */
-
-
-
-#define    IIO_ICRB7_A               0x004004E0    /* IO CRB Entry 7_A       */
-
-
-
-#define    IIO_ICRB7_B               0x004004E8    /* IO CRB Entry 7_B       */
-
-
-
-#define    IIO_ICRB7_C               0x004004F0    /* IO CRB Entry 7_C       */
-
-
-
-#define    IIO_ICRB7_D               0x004004F8    /* IO CRB Entry 7_D       */
-
-
-
-#define    IIO_ICRB8_A               0x00400500    /* IO CRB Entry 8_A       */
-
-
-
-#define    IIO_ICRB8_B               0x00400508    /* IO CRB Entry 8_B       */
-
-
-
-#define    IIO_ICRB8_C               0x00400510    /* IO CRB Entry 8_C       */
-
-
-
-#define    IIO_ICRB8_D               0x00400518    /* IO CRB Entry 8_D       */
-
-
-
-#define    IIO_ICRB9_A               0x00400520    /* IO CRB Entry 9_A       */
-
-
-
-#define    IIO_ICRB9_B               0x00400528    /* IO CRB Entry 9_B       */
-
-
-
-#define    IIO_ICRB9_C               0x00400530    /* IO CRB Entry 9_C       */
-
-
-
-#define    IIO_ICRB9_D               0x00400538    /* IO CRB Entry 9_D       */
-
-
-
-#define    IIO_ICRBA_A               0x00400540    /* IO CRB Entry A_A       */
-
-
-
-#define    IIO_ICRBA_B               0x00400548    /* IO CRB Entry A_B       */
-
-
-
-#define    IIO_ICRBA_C               0x00400550    /* IO CRB Entry A_C       */
-
-
-
-#define    IIO_ICRBA_D               0x00400558    /* IO CRB Entry A_D       */
-
-
-
-#define    IIO_ICRBB_A               0x00400560    /* IO CRB Entry B_A       */
-
-
-
-#define    IIO_ICRBB_B               0x00400568    /* IO CRB Entry B_B       */
-
-
-
-#define    IIO_ICRBB_C               0x00400570    /* IO CRB Entry B_C       */
-
-
-
-#define    IIO_ICRBB_D               0x00400578    /* IO CRB Entry B_D       */
-
-
-
-#define    IIO_ICRBC_A               0x00400580    /* IO CRB Entry C_A       */
-
-
-
-#define    IIO_ICRBC_B               0x00400588    /* IO CRB Entry C_B       */
-
-
-
-#define    IIO_ICRBC_C               0x00400590    /* IO CRB Entry C_C       */
-
-
-
-#define    IIO_ICRBC_D               0x00400598    /* IO CRB Entry C_D       */
-
-
-
-#define    IIO_ICRBD_A               0x004005A0    /* IO CRB Entry D_A       */
-
-
-
-#define    IIO_ICRBD_B               0x004005A8    /* IO CRB Entry D_B       */
-
-
-
-#define    IIO_ICRBD_C               0x004005B0    /* IO CRB Entry D_C       */
-
-
-
-#define    IIO_ICRBD_D               0x004005B8    /* IO CRB Entry D_D       */
-
-
-
-#define    IIO_ICRBE_A               0x004005C0    /* IO CRB Entry E_A       */
-
-
-
-#define    IIO_ICRBE_B               0x004005C8    /* IO CRB Entry E_B       */
-
-
-
-#define    IIO_ICRBE_C               0x004005D0    /* IO CRB Entry E_C       */
-
-
-
-#define    IIO_ICRBE_D               0x004005D8    /* IO CRB Entry E_D       */
-
-
-
-#define    IIO_ICSML                 0x00400600    /*
-                                                    * IO CRB Spurious
-                                                    * Message Low
-                                                    */
-
-
-
-#define    IIO_ICSMH                 0x00400608    /*
-                                                    * IO CRB Spurious
-                                                    * Message High
-                                                    */
-
-
-
-#define    IIO_IDBSS                 0x00400610    /*
-                                                    * IO Debug Submenu
-                                                    * Select
-                                                    */
-
-
-
-#define    IIO_IBLS0                 0x00410000    /*
-                                                    * IO BTE Length
-                                                    * Status 0
-                                                    */
-
-
-
-#define    IIO_IBSA0                 0x00410008    /*
-                                                    * IO BTE Source
-                                                    * Address 0
-                                                    */
-
-
-
-#define    IIO_IBDA0                 0x00410010    /*
-                                                    * IO BTE Destination
-                                                    * Address 0
-                                                    */
-
-
-
-#define    IIO_IBCT0                 0x00410018    /*
-                                                    * IO BTE Control
-                                                    * Terminate 0
-                                                    */
-
-
-
-#define    IIO_IBNA0                 0x00410020    /*
-                                                    * IO BTE Notification
-                                                    * Address 0
-                                                    */
-
-
-
-#define    IIO_IBIA0                 0x00410028    /*
-                                                    * IO BTE Interrupt
-                                                    * Address 0
-                                                    */
-
-
-
-#define    IIO_IBLS1                 0x00420000    /*
-                                                    * IO BTE Length
-                                                    * Status 1
-                                                    */
-
-
-
-#define    IIO_IBSA1                 0x00420008    /*
-                                                    * IO BTE Source
-                                                    * Address 1
-                                                    */
-
-
-
-#define    IIO_IBDA1                 0x00420010    /*
-                                                    * IO BTE Destination
-                                                    * Address 1
-                                                    */
-
-
-
-#define    IIO_IBCT1                 0x00420018    /*
-                                                    * IO BTE Control
-                                                    * Terminate 1
-                                                    */
-
-
-
-#define    IIO_IBNA1                 0x00420020    /*
-                                                    * IO BTE Notification
-                                                    * Address 1
-                                                    */
-
-
-
-#define    IIO_IBIA1                 0x00420028    /*
-                                                    * IO BTE Interrupt
-                                                    * Address 1
-                                                    */
-
-
-
-#define    IIO_IPCR                  0x00430000    /*
-                                                    * IO Performance
-                                                    * Control
-                                                    */
-
-
-
-#define    IIO_IPPR                  0x00430008    /*
-                                                    * IO Performance
-                                                    * Profiling
-                                                    */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- * Description:  This register echoes some information from the         *
- * LB_REV_ID register. It is available through Crosstalk as described   *
- * above. The REV_NUM and MFG_NUM fields receive their values from      *
- * the REVISION and MANUFACTURER fields in the LB_REV_ID register.      *
- * The PART_NUM field's value is the Crosstalk device ID number that    *
- * Steve Miller assigned to the Bedrock chip.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_wid_u {
-	bdrkreg_t	ii_wid_regval;
-	struct	{
-		bdrkreg_t	w_rsvd_1		  :	 1;
-		bdrkreg_t	w_mfg_num		  :	11;
-		bdrkreg_t	w_part_num		  :	16;
-		bdrkreg_t	w_rev_num		  :	 4;
-		bdrkreg_t	w_rsvd			  :	32;
-	} ii_wid_fld_s;
-} ii_wid_u_t;
-
-#else
-
-typedef union ii_wid_u {
-	bdrkreg_t	ii_wid_regval;
-	struct  {
-		bdrkreg_t	w_rsvd                    :	32;
-		bdrkreg_t	w_rev_num                 :	 4;
-		bdrkreg_t	w_part_num                :	16;
-		bdrkreg_t	w_mfg_num                 :	11;
-		bdrkreg_t	w_rsvd_1                  :	 1;
-	} ii_wid_fld_s;
-} ii_wid_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  The fields in this register are set upon detection of an error      *
- * and cleared by various mechanisms, as explained in the               *
- * description.                                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_wstat_u {
-	bdrkreg_t	ii_wstat_regval;
-	struct	{
-		bdrkreg_t	w_pending		  :	 4;
-		bdrkreg_t	w_xt_crd_to		  :	 1;
-		bdrkreg_t	w_xt_tail_to		  :	 1;
-		bdrkreg_t	w_rsvd_3		  :	 3;
-		bdrkreg_t       w_tx_mx_rty               :      1;
-		bdrkreg_t	w_rsvd_2		  :	 6;
-		bdrkreg_t	w_llp_tx_cnt		  :	 8;
-		bdrkreg_t	w_rsvd_1		  :	 8;
-		bdrkreg_t	w_crazy			  :	 1;
-		bdrkreg_t	w_rsvd			  :	31;
-	} ii_wstat_fld_s;
-} ii_wstat_u_t;
-
-#else
-
-typedef union ii_wstat_u {
-	bdrkreg_t	ii_wstat_regval;
-	struct  {
-		bdrkreg_t	w_rsvd                    :	31;
-		bdrkreg_t	w_crazy                   :	 1;
-		bdrkreg_t	w_rsvd_1                  :	 8;
-		bdrkreg_t	w_llp_tx_cnt              :	 8;
-		bdrkreg_t	w_rsvd_2                  :	 6;
-		bdrkreg_t	w_tx_mx_rty               :	 1;
-		bdrkreg_t	w_rsvd_3                  :	 3;
-		bdrkreg_t	w_xt_tail_to              :	 1;
-		bdrkreg_t	w_xt_crd_to               :	 1;
-		bdrkreg_t	w_pending                 :	 4;
-	} ii_wstat_fld_s;
-} ii_wstat_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This is a read-write enabled register. It controls     *
- * various aspects of the Crosstalk flow control.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_wcr_u {
-	bdrkreg_t	ii_wcr_regval;
-	struct	{
-		bdrkreg_t	w_wid			  :	 4;
-		bdrkreg_t	w_tag			  :	 1;
-		bdrkreg_t	w_rsvd_1		  :	 8;
-		bdrkreg_t	w_dst_crd		  :	 3;
-		bdrkreg_t	w_f_bad_pkt		  :	 1;
-		bdrkreg_t	w_dir_con		  :	 1;
-		bdrkreg_t	w_e_thresh		  :	 5;
-		bdrkreg_t	w_rsvd			  :	41;
-	} ii_wcr_fld_s;
-} ii_wcr_u_t;
-
-#else
-
-typedef union ii_wcr_u {
-	bdrkreg_t	ii_wcr_regval;
-	struct  {
-		bdrkreg_t	w_rsvd                    :	41;
-		bdrkreg_t	w_e_thresh                :	 5;
-		bdrkreg_t	w_dir_con                 :	 1;
-		bdrkreg_t	w_f_bad_pkt               :	 1;
-		bdrkreg_t	w_dst_crd                 :	 3;
-		bdrkreg_t	w_rsvd_1                  :	 8;
-		bdrkreg_t	w_tag                     :	 1;
-		bdrkreg_t	w_wid                     :	 4;
-	} ii_wcr_fld_s;
-} ii_wcr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register's value is a bit vector that guards      *
- * access to local registers within the II as well as to external       *
- * Crosstalk widgets. Each bit in the register corresponds to a         *
- * particular region in the system; a region consists of one, two or    *
- * four nodes (depending on the value of the REGION_SIZE field in the   *
- * LB_REV_ID register, which is documented in Section 8.3.1.1). The     *
- * protection provided by this register applies to PIO read             *
- * operations as well as PIO write operations. The II will perform a    *
- * PIO read or write request only if the bit for the requestor's        *
- * region is set; otherwise, the II will not perform the requested      *
- * operation and will return an error response. When a PIO read or      *
- * write request targets an external Crosstalk widget, then not only    *
- * must the bit for the requestor's region be set in the ILAPR, but     *
- * also the target widget's bit in the IOWA register must be set in     *
- * order for the II to perform the requested operation; otherwise,      *
- * the II will return an error response. Hence, the protection          *
- * provided by the IOWA register supplements the protection provided    *
- * by the ILAPR for requests that target external Crosstalk widgets.    *
- * This register itself can be accessed only by the nodes whose         *
- * region ID bits are enabled in this same register. It can also be     *
- * accessed through the IAlias space by the local processors.           *
- * The reset value of this register allows access by all nodes.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union ii_ilapr_u {
-	bdrkreg_t	ii_ilapr_regval;
-	struct  {
-		bdrkreg_t	i_region                  :	64;
-	} ii_ilapr_fld_s;
-} ii_ilapr_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  A write to this register of the 64-bit value           *
- * "SGIrules" in ASCII, will cause the bit in the ILAPR register        *
- * corresponding to the region of the requestor to be set (allow        *
- * access). A write of any other value will be ignored. Access          *
- * protection for this register is "SGIrules".                          *
- * This register can also be accessed through the IAlias space.         *
- * However, this access will not change the access permissions in the   *
- * ILAPR.                                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ilapo_u {
-	bdrkreg_t	ii_ilapo_regval;
-	struct	{
-		bdrkreg_t	i_io_ovrride		  :	 9;
-		bdrkreg_t	i_rsvd			  :	55;
-	} ii_ilapo_fld_s;
-} ii_ilapo_u_t;
-
-#else
-
-typedef union ii_ilapo_u {
-	bdrkreg_t	ii_ilapo_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	55;
-		bdrkreg_t	i_io_ovrride              :	 9;
-	} ii_ilapo_fld_s;
-} ii_ilapo_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register qualifies all the PIO and Graphics writes launched    *
- * from the Bedrock towards a widget.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iowa_u {
-	bdrkreg_t	ii_iowa_regval;
-	struct	{
-		bdrkreg_t	i_w0_oac		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-                bdrkreg_t       i_wx_oac                  :      8;
-		bdrkreg_t	i_rsvd			  :	48;
-	} ii_iowa_fld_s;
-} ii_iowa_u_t;
-
-#else
-
-typedef union ii_iowa_u {
-	bdrkreg_t	ii_iowa_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	48;
-		bdrkreg_t	i_wx_oac                  :	 8;
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_w0_oac                  :	 1;
-	} ii_iowa_fld_s;
-} ii_iowa_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register qualifies all the requests launched      *
- * from a widget towards the Bedrock. This register is intended to be   *
- * used by software in case of misbehaving widgets.                     *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iiwa_u {
-	bdrkreg_t	ii_iiwa_regval;
-	struct  {
-		bdrkreg_t	i_w0_iac                  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_wx_iac		  :	 8;
-		bdrkreg_t	i_rsvd			  :	48;
-	} ii_iiwa_fld_s;
-} ii_iiwa_u_t;
-
-#else
-
-typedef union ii_iiwa_u {
-	bdrkreg_t	ii_iiwa_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	48;
-		bdrkreg_t	i_wx_iac		  :	 8;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_w0_iac		  :	 1;
-	} ii_iiwa_fld_s;
-} ii_iiwa_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register qualifies all the operations launched    *
- * from a widget towards the Bedrock. It allows individual access       *
- * control for up to 8 devices per widget. A device refers to           *
- * individual DMA master hosted by a widget.                            *
- * The bits in each field of this register are cleared by the Bedrock   *
- * upon detection of an error which requires the device to be           *
- * disabled. These fields assume that 0=TNUM=7 (i.e., Bridge-centric    *
- * Crosstalk). Whether or not a device has access rights to this        *
- * Bedrock is determined by an AND of the device enable bit in the      *
- * appropriate field of this register and the corresponding bit in      *
- * the Wx_IAC field (for the widget which this device belongs to).      *
- * The bits in this field are set by writing a 1 to them. Incoming      *
- * replies from Crosstalk are not subject to this access control        *
- * mechanism.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iidem_u {
-	bdrkreg_t	ii_iidem_regval;
-	struct	{
-		bdrkreg_t	i_w8_dxs		  :	 8;
-		bdrkreg_t	i_w9_dxs		  :	 8;
-		bdrkreg_t	i_wa_dxs		  :	 8;
-		bdrkreg_t	i_wb_dxs		  :	 8;
-		bdrkreg_t	i_wc_dxs		  :	 8;
-		bdrkreg_t	i_wd_dxs		  :	 8;
-		bdrkreg_t	i_we_dxs		  :	 8;
-		bdrkreg_t	i_wf_dxs		  :	 8;
-	} ii_iidem_fld_s;
-} ii_iidem_u_t;
-
-#else
-
-typedef union ii_iidem_u {
-	bdrkreg_t	ii_iidem_regval;
-	struct  {
-		bdrkreg_t	i_wf_dxs                  :	 8;
-		bdrkreg_t	i_we_dxs                  :	 8;
-		bdrkreg_t	i_wd_dxs                  :	 8;
-		bdrkreg_t	i_wc_dxs                  :	 8;
-		bdrkreg_t	i_wb_dxs                  :	 8;
-		bdrkreg_t	i_wa_dxs                  :	 8;
-		bdrkreg_t	i_w9_dxs                  :	 8;
-		bdrkreg_t	i_w8_dxs                  :	 8;
-	} ii_iidem_fld_s;
-} ii_iidem_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the various programmable fields necessary    *
- * for controlling and observing the LLP signals.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ilcsr_u {
-	bdrkreg_t	ii_ilcsr_regval;
-	struct  {
-		bdrkreg_t	i_nullto                  :	 6;
-		bdrkreg_t	i_rsvd_4		  :	 2;
-		bdrkreg_t	i_wrmrst		  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 1;
-		bdrkreg_t	i_llp_en		  :	 1;
-		bdrkreg_t	i_bm8			  :	 1;
-		bdrkreg_t	i_llp_stat		  :	 2;
-		bdrkreg_t	i_remote_power		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 1;
-		bdrkreg_t	i_maxrtry		  :	10;
-		bdrkreg_t	i_d_avail_sel		  :	 2;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_maxbrst		  :	10;
-                bdrkreg_t       i_rsvd                    :     22;
-
-	} ii_ilcsr_fld_s;
-} ii_ilcsr_u_t;
-
-#else
-
-typedef union ii_ilcsr_u {
-	bdrkreg_t	ii_ilcsr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	22;
-		bdrkreg_t	i_maxbrst		  :	10;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_d_avail_sel		  :	 2;
-		bdrkreg_t	i_maxrtry		  :	10;
-		bdrkreg_t	i_rsvd_2		  :	 1;
-		bdrkreg_t	i_remote_power		  :	 1;
-		bdrkreg_t	i_llp_stat		  :	 2;
-		bdrkreg_t	i_bm8			  :	 1;
-		bdrkreg_t	i_llp_en		  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 1;
-		bdrkreg_t	i_wrmrst		  :	 1;
-		bdrkreg_t	i_rsvd_4		  :	 2;
-		bdrkreg_t	i_nullto		  :	 6;
-	} ii_ilcsr_fld_s;
-} ii_ilcsr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This is simply a status registers that monitors the LLP error       *
- * rate.                                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_illr_u {
-	bdrkreg_t	ii_illr_regval;
-	struct	{
-		bdrkreg_t	i_sn_cnt		  :	16;
-		bdrkreg_t	i_cb_cnt		  :	16;
-		bdrkreg_t	i_rsvd			  :	32;
-	} ii_illr_fld_s;
-} ii_illr_u_t;
-
-#else
-
-typedef union ii_illr_u {
-	bdrkreg_t	ii_illr_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	32;
-		bdrkreg_t	i_cb_cnt                  :	16;
-		bdrkreg_t	i_sn_cnt                  :	16;
-	} ii_illr_fld_s;
-} ii_illr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  All II-detected non-BTE error interrupts are           *
- * specified via this register.                                         *
- * NOTE: The PI interrupt register address is hardcoded in the II. If   *
- * PI_ID==0, then the II sends an interrupt request (Duplonet PWRI      *
- * packet) to address offset 0x0180_0090 within the local register      *
- * address space of PI0 on the node specified by the NODE field. If     *
- * PI_ID==1, then the II sends the interrupt request to address         *
- * offset 0x01A0_0090 within the local register address space of PI1    *
- * on the node specified by the NODE field.                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iidsr_u {
-	bdrkreg_t	ii_iidsr_regval;
-	struct  {
-		bdrkreg_t	i_level                   :	 7;
-		bdrkreg_t	i_rsvd_4		  :	 1;
-		bdrkreg_t       i_pi_id                   :      1;
-		bdrkreg_t	i_node			  :	 8;
-		bdrkreg_t       i_rsvd_3                  :      7;
-		bdrkreg_t	i_enable		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_int_sent		  :	 1;
-		bdrkreg_t       i_rsvd_1                  :      3;
-		bdrkreg_t	i_pi0_forward_int	  :	 1;
-		bdrkreg_t	i_pi1_forward_int	  :	 1;
-		bdrkreg_t	i_rsvd			  :	30;
-	} ii_iidsr_fld_s;
-} ii_iidsr_u_t;
-
-#else
-
-typedef union ii_iidsr_u {
-	bdrkreg_t	ii_iidsr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	30;
-		bdrkreg_t	i_pi1_forward_int	  :	 1;
-		bdrkreg_t	i_pi0_forward_int	  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_int_sent		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_enable		  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 7;
-		bdrkreg_t	i_node			  :	 8;
-		bdrkreg_t	i_pi_id			  :	 1;
-		bdrkreg_t	i_rsvd_4		  :	 1;
-		bdrkreg_t	i_level			  :	 7;
-	} ii_iidsr_fld_s;
-} ii_iidsr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this register. This register is used     *
- * for matching up the incoming responses from the graphics widget to   *
- * the processor that initiated the graphics operation. The             *
- * write-responses are converted to graphics credits and returned to    *
- * the processor so that the processor interface can manage the flow    *
- * control.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_igfx0_u {
-	bdrkreg_t	ii_igfx0_regval;
-	struct	{
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t       i_pi_id                   :      1;
-		bdrkreg_t	i_n_num			  :	 8;
-		bdrkreg_t       i_rsvd_1                  :      3;
-		bdrkreg_t       i_p_num                   :      1;
-		bdrkreg_t       i_rsvd                    :     47;
-	} ii_igfx0_fld_s;
-} ii_igfx0_u_t;
-
-#else
-
-typedef union ii_igfx0_u {
-	bdrkreg_t	ii_igfx0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	47;
-		bdrkreg_t	i_p_num                   :	 1;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_n_num                   :	 8;
-		bdrkreg_t	i_pi_id                   :	 1;
-		bdrkreg_t	i_w_num                   :	 4;
-	} ii_igfx0_fld_s;
-} ii_igfx0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this register. This register is used     *
- * for matching up the incoming responses from the graphics widget to   *
- * the processor that initiated the graphics operation. The             *
- * write-responses are converted to graphics credits and returned to    *
- * the processor so that the processor interface can manage the flow    *
- * control.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_igfx1_u {
-	bdrkreg_t	ii_igfx1_regval;
-	struct  {
-		bdrkreg_t	i_w_num                   :	 4;
-		bdrkreg_t	i_pi_id			  :	 1;
-		bdrkreg_t	i_n_num			  :	 8;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_p_num			  :	 1;
-		bdrkreg_t	i_rsvd			  :	47;
-	} ii_igfx1_fld_s;
-} ii_igfx1_u_t;
-
-#else
-
-typedef union ii_igfx1_u {
-	bdrkreg_t	ii_igfx1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	47;
-		bdrkreg_t	i_p_num			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_n_num			  :	 8;
-		bdrkreg_t	i_pi_id			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-	} ii_igfx1_fld_s;
-} ii_igfx1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this registers. These registers are      *
- * used as scratch registers for software use.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union ii_iscr0_u {
-	bdrkreg_t	ii_iscr0_regval;
-	struct  {
-		bdrkreg_t	i_scratch                 :	64;
-	} ii_iscr0_fld_s;
-} ii_iscr0_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this registers. These registers are      *
- * used as scratch registers for software use.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union ii_iscr1_u {
-	bdrkreg_t	ii_iscr1_regval;
-	struct  {
-		bdrkreg_t	i_scratch                 :	64;
-	} ii_iscr1_fld_s;
-} ii_iscr1_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte1_u {
-	bdrkreg_t	ii_itte1_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_rsvd			  :	51;
-	} ii_itte1_fld_s;
-} ii_itte1_u_t;
-
-#else
-
-typedef union ii_itte1_u {
-	bdrkreg_t	ii_itte1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte1_fld_s;
-} ii_itte1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte2_u {
-	bdrkreg_t	ii_itte2_regval;
-	struct	{
-		bdrkreg_t	i_offset		  :	 5;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte2_fld_s;
-} ii_itte2_u_t;
-
-#else
-typedef union ii_itte2_u {
-	bdrkreg_t	ii_itte2_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	51;
-		bdrkreg_t	i_iosp                    :	 1;
-		bdrkreg_t	i_w_num                   :	 4;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_offset                  :	 5;
-	} ii_itte2_fld_s;
-} ii_itte2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte3_u {
-	bdrkreg_t	ii_itte3_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t       i_rsvd_1                  :      3;
-		bdrkreg_t       i_w_num                   :      4;
-		bdrkreg_t       i_iosp                    :      1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte3_fld_s;
-} ii_itte3_u_t;
-
-#else
-
-typedef union ii_itte3_u {
-	bdrkreg_t	ii_itte3_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte3_fld_s;
-} ii_itte3_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte4_u {
-	bdrkreg_t	ii_itte4_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t       i_w_num                   :      4;
-		bdrkreg_t       i_iosp                    :      1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte4_fld_s;
-} ii_itte4_u_t;
-
-#else
-
-typedef union ii_itte4_u {
-	bdrkreg_t	ii_itte4_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte4_fld_s;
-} ii_itte4_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte5_u {
-	bdrkreg_t	ii_itte5_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t       i_rsvd_1                  :      3;
-		bdrkreg_t       i_w_num                   :      4;
-		bdrkreg_t       i_iosp                    :      1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte5_fld_s;
-} ii_itte5_u_t;
-
-#else
-
-typedef union ii_itte5_u {
-	bdrkreg_t	ii_itte5_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte5_fld_s;
-} ii_itte5_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte6_u {
-	bdrkreg_t	ii_itte6_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t       i_rsvd_1                  :      3;
-		bdrkreg_t       i_w_num                   :      4;
-		bdrkreg_t       i_iosp                    :      1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte6_fld_s;
-} ii_itte6_u_t;
-
-#else
-
-typedef union ii_itte6_u {
-	bdrkreg_t	ii_itte6_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte6_fld_s;
-} ii_itte6_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte7_u {
-	bdrkreg_t	ii_itte7_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t       i_w_num                   :      4;
-		bdrkreg_t       i_iosp                    :      1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte7_fld_s;
-} ii_itte7_u_t;
-
-#else
-
-typedef union ii_itte7_u {
-	bdrkreg_t	ii_itte7_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte7_fld_s;
-} ii_itte7_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprb0_u {
-	bdrkreg_t	ii_iprb0_regval;
-	struct  {
-		bdrkreg_t	i_c                       :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t       i_rsvd_2                  :      2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprb0_fld_s;
-} ii_iprb0_u_t;
-
-#else
-
-typedef union ii_iprb0_u {
-	bdrkreg_t	ii_iprb0_regval;
-	struct	{
-		bdrkreg_t	i_mult_err		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_c			  :	 8;
-	} ii_iprb0_fld_s;
-} ii_iprb0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprb8_u {
-	bdrkreg_t	ii_iprb8_regval;
-	struct  {
-		bdrkreg_t	i_c                       :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t       i_rsvd_2                  :      2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t       i_rsvd_1                  :      2;
-		bdrkreg_t       i_m                       :      2;
-		bdrkreg_t       i_f                       :      1;
-		bdrkreg_t       i_of_cnt                  :      5;
-		bdrkreg_t       i_error                   :      1;
-		bdrkreg_t       i_rd_to                   :      1;
-		bdrkreg_t       i_spur_wr                 :      1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t       i_rsvd                    :     11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprb8_fld_s;
-} ii_iprb8_u_t;
-
-#else
-
-
-typedef union ii_iprb8_u {
-	bdrkreg_t	ii_iprb8_regval;
-	struct	{
-		bdrkreg_t	i_mult_err		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_c			  :	 8;
-	} ii_iprb8_fld_s;
-} ii_iprb8_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprb9_u {
-	bdrkreg_t	ii_iprb9_regval;
-	struct	{
-		bdrkreg_t	i_c			  :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprb9_fld_s;
-} ii_iprb9_u_t;
-
-#else
-
-typedef union ii_iprb9_u {
-	bdrkreg_t	ii_iprb9_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprb9_fld_s;
-} ii_iprb9_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprba_u {
-	bdrkreg_t	ii_iprba_regval;
-	struct  {
-		bdrkreg_t	i_c                       :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t       i_rsvd_2                  :      2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprba_fld_s;
-} ii_iprba_u_t;
-
-#else
-
-typedef union ii_iprba_u {
-	bdrkreg_t	ii_iprba_regval;
-	struct	{
-		bdrkreg_t	i_mult_err		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_c			  :	 8;
-	} ii_iprba_fld_s;
-} ii_iprba_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprbb_u {
-	bdrkreg_t	ii_iprbb_regval;
-	struct	{
-		bdrkreg_t	i_c			  :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprbb_fld_s;
-} ii_iprbb_u_t;
-
-#else
-
-typedef union ii_iprbb_u {
-	bdrkreg_t	ii_iprbb_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprbb_fld_s;
-} ii_iprbb_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprbc_u {
-	bdrkreg_t	ii_iprbc_regval;
-	struct	{
-		bdrkreg_t	i_c			  :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprbc_fld_s;
-} ii_iprbc_u_t;
-
-#else
-
-typedef union ii_iprbc_u {
-	bdrkreg_t	ii_iprbc_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprbc_fld_s;
-} ii_iprbc_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprbd_u {
-	bdrkreg_t	ii_iprbd_regval;
-	struct	{
-		bdrkreg_t	i_c			  :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprbd_fld_s;
-} ii_iprbd_u_t;
-
-#else
-
-typedef union ii_iprbd_u {
-	bdrkreg_t	ii_iprbd_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprbd_fld_s;
-} ii_iprbd_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprbe_u {
-	bdrkreg_t	ii_iprbe_regval;
-	struct	{
-		bdrkreg_t	i_c			  :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprbe_fld_s;
-} ii_iprbe_u_t;
-
-#else
-
-typedef union ii_iprbe_u {
-	bdrkreg_t	ii_iprbe_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprbe_fld_s;
-} ii_iprbe_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprbf_u {
-        bdrkreg_t       ii_iprbf_regval;
-        struct  {
-                bdrkreg_t       i_c                       :      8;
-                bdrkreg_t       i_na                      :     14;
-                bdrkreg_t       i_rsvd_2                  :      2;
-                bdrkreg_t       i_nb                      :     14;
-                bdrkreg_t       i_rsvd_1                  :      2;
-                bdrkreg_t       i_m                       :      2;
-                bdrkreg_t       i_f                       :      1;
-                bdrkreg_t       i_of_cnt                  :      5;
-                bdrkreg_t       i_error                   :      1;
-                bdrkreg_t       i_rd_to                   :      1;
-                bdrkreg_t       i_spur_wr                 :      1;
-                bdrkreg_t       i_spur_rd                 :      1;
-                bdrkreg_t       i_rsvd                    :     11;
-                bdrkreg_t       i_mult_err                :      1;
-        } ii_iprbe_fld_s;
-} ii_iprbf_u_t;
-
-#else
-
-typedef union ii_iprbf_u {
-	bdrkreg_t	ii_iprbf_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprbf_fld_s;
-} ii_iprbf_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register specifies the timeout value to use for monitoring     *
- * Crosstalk credits which are used outbound to Crosstalk. An           *
- * internal counter called the Crosstalk Credit Timeout Counter         *
- * increments every 128 II clocks. The counter starts counting          *
- * anytime the credit count drops below a threshold, and resets to      *
- * zero (stops counting) anytime the credit count is at or above the    *
- * threshold. The threshold is 1 credit in direct connect mode and 2    *
- * in Crossbow connect mode. When the internal Crosstalk Credit         *
- * Timeout Counter reaches the value programmed in this register, a     *
- * Crosstalk Credit Timeout has occurred. The internal counter is not   *
- * readable from software, and stops counting at its maximum value,     *
- * so it cannot cause more than one interrupt.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ixcc_u {
-	bdrkreg_t	ii_ixcc_regval;
-	struct  {
-		bdrkreg_t	i_time_out                :	26;
-		bdrkreg_t	i_rsvd			  :	38;
-	} ii_ixcc_fld_s;
-} ii_ixcc_u_t;
-
-#else
-
-typedef union ii_ixcc_u {
-	bdrkreg_t	ii_ixcc_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	38;
-		bdrkreg_t	i_time_out		  :	26;
-	} ii_ixcc_fld_s;
-} ii_ixcc_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register qualifies all the PIO and DMA            *
- * operations launched from widget 0 towards the Bedrock. In            *
- * addition, it also qualifies accesses by the BTE streams.             *
- * The bits in each field of this register are cleared by the Bedrock   *
- * upon detection of an error which requires widget 0 or the BTE        *
- * streams to be terminated. Whether or not widget x has access         *
- * rights to this Bedrock is determined by an AND of the device         *
- * enable bit in the appropriate field of this register and bit 0 in    *
- * the Wx_IAC field. The bits in this field are set by writing a 1 to   *
- * them. Incoming replies from Crosstalk are not subject to this        *
- * access control mechanism.                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_imem_u {
-	bdrkreg_t	ii_imem_regval;
-	struct  {
-		bdrkreg_t	i_w0_esd                  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 3;
-		bdrkreg_t	i_b0_esd		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_b1_esd		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_clr_precise		  :	 1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_imem_fld_s;
-} ii_imem_u_t;
-
-#else
-
-typedef union ii_imem_u {
-	bdrkreg_t	ii_imem_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_clr_precise		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_b1_esd		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_b0_esd		  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 3;
-		bdrkreg_t	i_w0_esd		  :	 1;
-	} ii_imem_fld_s;
-} ii_imem_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register specifies the timeout value to use for   *
- * monitoring Crosstalk tail flits coming into the Bedrock in the       *
- * TAIL_TO field. An internal counter associated with this register     *
- * is incremented every 128 II internal clocks (7 bits). The counter    *
- * starts counting anytime a header micropacket is received and stops   *
- * counting (and resets to zero) any time a micropacket with a Tail     *
- * bit is received. Once the counter reaches the threshold value        *
- * programmed in this register, it generates an interrupt to the        *
- * processor that is programmed into the IIDSR. The counter saturates   *
- * (does not roll over) at its maximum value, so it cannot cause        *
- * another interrupt until after it is cleared.                         *
- * The register also contains the Read Response Timeout values. The     *
- * Prescalar is 23 bits, and counts II clocks. An internal counter      *
- * increments on every II clock and when it reaches the value in the    *
- * Prescalar field, all IPRTE registers with their valid bits set       *
- * have their Read Response timers bumped. Whenever any of them match   *
- * the value in the RRSP_TO field, a Read Response Timeout has          *
- * occurred, and error handling occurs as described in the Error        *
- * Handling section of this document.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ixtt_u {
-	bdrkreg_t	ii_ixtt_regval;
-	struct  {
-		bdrkreg_t	i_tail_to                 :	26;
-		bdrkreg_t	i_rsvd_1		  :	 6;
-		bdrkreg_t	i_rrsp_ps		  :	23;
-		bdrkreg_t	i_rrsp_to		  :	 5;
-		bdrkreg_t	i_rsvd			  :	 4;
-	} ii_ixtt_fld_s;
-} ii_ixtt_u_t;
-
-#else
-
-typedef union ii_ixtt_u {
-	bdrkreg_t	ii_ixtt_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	 4;
-		bdrkreg_t	i_rrsp_to		  :	 5;
-		bdrkreg_t	i_rrsp_ps		  :	23;
-		bdrkreg_t	i_rsvd_1		  :	 6;
-		bdrkreg_t	i_tail_to		  :	26;
-	} ii_ixtt_fld_s;
-} ii_ixtt_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Writing a 1 to the fields of this register clears the appropriate   *
- * error bits in other areas of Bedrock_II. Note that when the          *
- * E_PRB_x bits are used to clear error bits in PRB registers,          *
- * SPUR_RD and SPUR_WR may persist, because they require additional     *
- * action to clear them. See the IPRBx and IXSS Register                *
- * specifications.                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ieclr_u {
-	bdrkreg_t	ii_ieclr_regval;
-	struct  {
-		bdrkreg_t	i_e_prb_0                 :	 1;
-		bdrkreg_t	i_rsvd			  :	 7;
-		bdrkreg_t	i_e_prb_8		  :	 1;
-		bdrkreg_t	i_e_prb_9		  :	 1;
-		bdrkreg_t	i_e_prb_a		  :	 1;
-		bdrkreg_t	i_e_prb_b		  :	 1;
-		bdrkreg_t	i_e_prb_c		  :	 1;
-		bdrkreg_t	i_e_prb_d		  :	 1;
-		bdrkreg_t	i_e_prb_e		  :	 1;
-		bdrkreg_t	i_e_prb_f		  :	 1;
-		bdrkreg_t	i_e_crazy		  :	 1;
-		bdrkreg_t	i_e_bte_0		  :	 1;
-		bdrkreg_t	i_e_bte_1		  :	 1;
-		bdrkreg_t	i_reserved_1		  :	 9;
-		bdrkreg_t	i_ii_internal		  :	 1;
-		bdrkreg_t	i_spur_rd_hdr		  :	 1;
-		bdrkreg_t	i_pi0_forward_int	  :	 1;
-		bdrkreg_t	i_pi1_forward_int	  :	 1;
-		bdrkreg_t       i_reserved                :     32;
-	} ii_ieclr_fld_s;
-} ii_ieclr_u_t;
-
-#else
-
-typedef union ii_ieclr_u {
-	bdrkreg_t	ii_ieclr_regval;
-	struct	{
-		bdrkreg_t	i_reserved		  :	32;
-		bdrkreg_t	i_pi1_forward_int	  :	 1;
-		bdrkreg_t	i_pi0_forward_int	  :	 1;
-		bdrkreg_t	i_spur_rd_hdr		  :	 1;
-		bdrkreg_t	i_ii_internal		  :	 1;
-		bdrkreg_t	i_reserved_1		  :	 9;
-		bdrkreg_t	i_e_bte_1		  :	 1;
-		bdrkreg_t	i_e_bte_0		  :	 1;
-		bdrkreg_t	i_e_crazy		  :	 1;
-		bdrkreg_t	i_e_prb_f		  :	 1;
-		bdrkreg_t	i_e_prb_e		  :	 1;
-		bdrkreg_t	i_e_prb_d		  :	 1;
-		bdrkreg_t	i_e_prb_c		  :	 1;
-		bdrkreg_t	i_e_prb_b		  :	 1;
-		bdrkreg_t	i_e_prb_a		  :	 1;
-		bdrkreg_t	i_e_prb_9		  :	 1;
-		bdrkreg_t	i_e_prb_8		  :	 1;
-		bdrkreg_t	i_rsvd			  :	 7;
-		bdrkreg_t	i_e_prb_0		  :	 1;
-	} ii_ieclr_fld_s;
-} ii_ieclr_u_t;
-
-#endif
-
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls both BTEs. SOFT_RESET is intended for        *
- * recovery after an error. COUNT controls the total number of CRBs     *
- * that both BTEs (combined) can use, which affects total BTE           *
- * bandwidth.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibcr_u {
-	bdrkreg_t	ii_ibcr_regval;
-	struct  {
-		bdrkreg_t	i_count                   :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_soft_reset		  :	 1;
-		bdrkreg_t	i_rsvd			  :	55;
-	} ii_ibcr_fld_s;
-} ii_ibcr_u_t;
-
-#else
-
-typedef union ii_ibcr_u {
-	bdrkreg_t	ii_ibcr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	55;
-		bdrkreg_t	i_soft_reset		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_count			  :	 4;
-	} ii_ibcr_fld_s;
-} ii_ibcr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the header of a spurious read response       *
- * received from Crosstalk. A spurious read response is defined as a    *
- * read response received by II from a widget for which (1) the SIDN    *
- * has a value between 1 and 7, inclusive (II never sends requests to   *
- * these widgets (2) there is no valid IPRTE register which             *
- * corresponds to the TNUM, or (3) the widget indicated in SIDN is      *
- * not the same as the widget recorded in the IPRTE register            *
- * referenced by the TNUM. If this condition is true, and if the        *
- * IXSS[VALID] bit is clear, then the header of the spurious read       *
- * response is capture in IXSM and IXSS, and IXSS[VALID] is set. The    *
- * errant header is thereby captured, and no further spurious read      *
- * respones are captured until IXSS[VALID] is cleared by setting the    *
- * appropriate bit in IECLR.Everytime a spurious read response is       *
- * detected, the SPUR_RD bit of the PRB corresponding to the incoming   *
- * message's SIDN field is set. This always happens, regarless of       *
- * whether a header is captured. The programmer should check            *
- * IXSM[SIDN] to determine which widget sent the spurious response,     *
- * because there may be more than one SPUR_RD bit set in the PRB        *
- * registers. The widget indicated by IXSM[SIDN] was the first          *
- * spurious read response to be received since the last time            *
- * IXSS[VALID] was clear. The SPUR_RD bit of the corresponding PRB      *
- * will be set. Any SPUR_RD bits in any other PRB registers indicate    *
- * spurious messages from other widets which were detected after the    *
- * header was captured..                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ixsm_u {
-	bdrkreg_t	ii_ixsm_regval;
-	struct  {
-		bdrkreg_t	i_byte_en                 :	32;
-		bdrkreg_t	i_reserved		  :	 1;
-		bdrkreg_t	i_tag			  :	 3;
-		bdrkreg_t	i_alt_pactyp		  :	 4;
-		bdrkreg_t	i_bo			  :	 1;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_vbpm			  :	 1;
-		bdrkreg_t	i_gbr			  :	 1;
-		bdrkreg_t	i_ds			  :	 2;
-		bdrkreg_t	i_ct			  :	 1;
-		bdrkreg_t	i_tnum			  :	 5;
-		bdrkreg_t	i_pactyp		  :	 4;
-		bdrkreg_t	i_sidn			  :	 4;
-		bdrkreg_t	i_didn			  :	 4;
-	} ii_ixsm_fld_s;
-} ii_ixsm_u_t;
-
-#else
-
-typedef union ii_ixsm_u {
-	bdrkreg_t	ii_ixsm_regval;
-	struct	{
-		bdrkreg_t	i_didn			  :	 4;
-		bdrkreg_t	i_sidn			  :	 4;
-		bdrkreg_t	i_pactyp		  :	 4;
-		bdrkreg_t	i_tnum			  :	 5;
-		bdrkreg_t	i_ct			  :	 1;
-		bdrkreg_t	i_ds			  :	 2;
-		bdrkreg_t	i_gbr			  :	 1;
-		bdrkreg_t	i_vbpm			  :	 1;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_bo			  :	 1;
-		bdrkreg_t	i_alt_pactyp		  :	 4;
-		bdrkreg_t	i_tag			  :	 3;
-		bdrkreg_t	i_reserved		  :	 1;
-		bdrkreg_t	i_byte_en		  :	32;
-	} ii_ixsm_fld_s;
-} ii_ixsm_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the sideband bits of a spurious read         *
- * response received from Crosstalk.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ixss_u {
-	bdrkreg_t	ii_ixss_regval;
-	struct  {
-		bdrkreg_t	i_sideband                :	 8;
-		bdrkreg_t	i_rsvd			  :	55;
-		bdrkreg_t	i_valid			  :	 1;
-	} ii_ixss_fld_s;
-} ii_ixss_u_t;
-
-#else
-
-typedef union ii_ixss_u {
-	bdrkreg_t	ii_ixss_regval;
-	struct	{
-		bdrkreg_t	i_valid			  :	 1;
-		bdrkreg_t	i_rsvd			  :	55;
-		bdrkreg_t	i_sideband		  :	 8;
-	} ii_ixss_fld_s;
-} ii_ixss_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register enables software to access the II LLP's test port.    *
- * Refer to the LLP 2.5 documentation for an explanation of the test    *
- * port. Software can write to this register to program the values      *
- * for the control fields (TestErrCapture, TestClear, TestFlit,         *
- * TestMask and TestSeed). Similarly, software can read from this       *
- * register to obtain the values of the test port's status outputs      *
- * (TestCBerr, TestValid and TestData).                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ilct_u {
-	bdrkreg_t	ii_ilct_regval;
-	struct  {
-		bdrkreg_t	i_test_seed		  :	20;
-		bdrkreg_t	i_test_mask		  :	 8;
-		bdrkreg_t	i_test_data		  :	20;
-		bdrkreg_t	i_test_valid		  :	 1;
-		bdrkreg_t	i_test_cberr		  :	 1;
-		bdrkreg_t	i_test_flit		  :	 3;
-		bdrkreg_t	i_test_clear		  :	 1;
-		bdrkreg_t	i_test_err_capture	  :	 1;
-		bdrkreg_t	i_rsvd			  :	 9;
-	} ii_ilct_fld_s;
-} ii_ilct_u_t;
-
-#else
-
-typedef union ii_ilct_u {
-	bdrkreg_t	ii_ilct_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	 9;
-		bdrkreg_t	i_test_err_capture	  :	 1;
-		bdrkreg_t	i_test_clear		  :	 1;
-		bdrkreg_t	i_test_flit		  :	 3;
-		bdrkreg_t	i_test_cberr		  :	 1;
-		bdrkreg_t	i_test_valid		  :	 1;
-		bdrkreg_t	i_test_data		  :	20;
-		bdrkreg_t	i_test_mask		  :	 8;
-		bdrkreg_t	i_test_seed		  :	20;
-	} ii_ilct_fld_s;
-} ii_ilct_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  If the II detects an illegal incoming Duplonet packet (request or   *
- * reply) when VALID==0 in the IIEPH1 register, then it saves the       *
- * contents of the packet's header flit in the IIEPH1 and IIEPH2        *
- * registers, sets the VALID bit in IIEPH1, clears the OVERRUN bit,     *
- * and assigns a value to the ERR_TYPE field which indicates the        *
- * specific nature of the error. The II recognizes four different       *
- * types of errors: short request packets (ERR_TYPE==2), short reply    *
- * packets (ERR_TYPE==3), long request packets (ERR_TYPE==4) and long   *
- * reply packets (ERR_TYPE==5). The encodings for these types of        *
- * errors were chosen to be consistent with the same types of errors    *
- * indicated by the ERR_TYPE field in the LB_ERROR_HDR1 register (in    *
- * the LB unit). If the II detects an illegal incoming Duplonet         *
- * packet when VALID==1 in the IIEPH1 register, then it merely sets     *
- * the OVERRUN bit to indicate that a subsequent error has happened,    *
- * and does nothing further.                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iieph1_u {
-	bdrkreg_t	ii_iieph1_regval;
-	struct	{
-		bdrkreg_t	i_command		  :	 7;
-		bdrkreg_t	i_rsvd_5		  :	 1;
-		bdrkreg_t	i_suppl			  :	11;
-		bdrkreg_t	i_rsvd_4		  :	 1;
-		bdrkreg_t	i_source		  :	11;
-		bdrkreg_t	i_rsvd_3		  :	 1;
-		bdrkreg_t	i_err_type		  :	 4;
-		bdrkreg_t	i_rsvd_2		  :	 4;
-		bdrkreg_t	i_overrun		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_valid			  :	 1;
-		bdrkreg_t	i_rsvd			  :	19;
-	} ii_iieph1_fld_s;
-} ii_iieph1_u_t;
-
-#else
-
-typedef union ii_iieph1_u {
-	bdrkreg_t	ii_iieph1_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	19;
-		bdrkreg_t	i_valid                   :	 1;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_overrun                 :	 1;
-		bdrkreg_t	i_rsvd_2                  :	 4;
-		bdrkreg_t	i_err_type                :	 4;
-		bdrkreg_t	i_rsvd_3                  :	 1;
-		bdrkreg_t	i_source                  :	11;
-		bdrkreg_t	i_rsvd_4                  :	 1;
-		bdrkreg_t	i_suppl                   :	11;
-		bdrkreg_t	i_rsvd_5                  :	 1;
-		bdrkreg_t	i_command                 :	 7;
-	} ii_iieph1_fld_s;
-} ii_iieph1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register holds the Address field from the header flit of an    *
- * incoming erroneous Duplonet packet, along with the tail bit which    *
- * accompanied this header flit. This register is essentially an        *
- * extension of IIEPH1. Two registers were necessary because the 64     *
- * bits available in only a single register were insufficient to        *
- * capture the entire header flit of an erroneous packet.               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iieph2_u {
-	bdrkreg_t	ii_iieph2_regval;
-	struct  {
-		bdrkreg_t	i_address                 :	38;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_tail			  :	 1;
-		bdrkreg_t	i_rsvd			  :	23;
-	} ii_iieph2_fld_s;
-} ii_iieph2_u_t;
-
-#else
-
-typedef union ii_iieph2_u {
-	bdrkreg_t	ii_iieph2_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	23;
-		bdrkreg_t	i_tail			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_address		  :	38;
-	} ii_iieph2_fld_s;
-} ii_iieph2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register causes a particular field in the           *
- * corresponding widget's PRB entry to be adjusted up or down by 1.     *
- * This counter should be used when recovering from error and reset     *
- * conditions. Note that software would be capable of causing           *
- * inadvertent overflow or underflow of these counters.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ipca_u {
-	bdrkreg_t	ii_ipca_regval;
-	struct  {
-		bdrkreg_t	i_wid                     :	 4;
-		bdrkreg_t	i_adjust		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_field			  :	 2;
-		bdrkreg_t	i_rsvd			  :	54;
-	} ii_ipca_fld_s;
-} ii_ipca_u_t;
-
-#else
-
-typedef union ii_ipca_u {
-	bdrkreg_t	ii_ipca_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	54;
-		bdrkreg_t	i_field			  :	 2;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_adjust		  :	 1;
-		bdrkreg_t	i_wid			  :	 4;
-	} ii_ipca_fld_s;
-} ii_ipca_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte0_u {
-	bdrkreg_t	ii_iprte0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t       i_vld                     :      1;
-	} ii_iprte0_fld_s;
-} ii_iprte0_u_t;
-
-#else
-
-typedef union ii_iprte0_u {
-	bdrkreg_t	ii_iprte0_regval;
-	struct	{
-		bdrkreg_t	i_vld			  :	 1;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-	} ii_iprte0_fld_s;
-} ii_iprte0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte1_u {
-	bdrkreg_t	ii_iprte1_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t       i_vld                     :      1;
-	} ii_iprte1_fld_s;
-} ii_iprte1_u_t;
-
-#else
-
-typedef union ii_iprte1_u {
-	bdrkreg_t	ii_iprte1_regval;
-	struct	{
-		bdrkreg_t	i_vld			  :	 1;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-	} ii_iprte1_fld_s;
-} ii_iprte1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte2_u {
-	bdrkreg_t	ii_iprte2_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t       i_vld                     :      1;
-	} ii_iprte2_fld_s;
-} ii_iprte2_u_t;
-
-#else
-
-typedef union ii_iprte2_u {
-	bdrkreg_t	ii_iprte2_regval;
-	struct	{
-		bdrkreg_t	i_vld			  :	 1;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-	} ii_iprte2_fld_s;
-} ii_iprte2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte3_u {
-	bdrkreg_t	ii_iprte3_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_vld			  :	 1;
-	} ii_iprte3_fld_s;
-} ii_iprte3_u_t;
-
-#else
-
-typedef union ii_iprte3_u {
-	bdrkreg_t	ii_iprte3_regval;
-	struct	{
-		bdrkreg_t	i_vld			  :	 1;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-	} ii_iprte3_fld_s;
-} ii_iprte3_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte4_u {
-	bdrkreg_t	ii_iprte4_regval;
-	struct	{
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_vld			  :	 1;
-	} ii_iprte4_fld_s;
-} ii_iprte4_u_t;
-
-#else
-
-typedef union ii_iprte4_u {
-	bdrkreg_t	ii_iprte4_regval;
-	struct  {
-		bdrkreg_t	i_vld                     :	 1;
-		bdrkreg_t	i_to_cnt                  :	 5;
-		bdrkreg_t	i_widget                  :	 4;
-		bdrkreg_t	i_rsvd                    :	 2;
-		bdrkreg_t	i_source                  :	 8;
-		bdrkreg_t	i_init                    :	 3;
-		bdrkreg_t	i_addr                    :	38;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-	} ii_iprte4_fld_s;
-} ii_iprte4_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte5_u {
-	bdrkreg_t	ii_iprte5_regval;
-	struct	{
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_vld			  :	 1;
-	} ii_iprte5_fld_s;
-} ii_iprte5_u_t;
-
-#else
-
-typedef union ii_iprte5_u {
-	bdrkreg_t	ii_iprte5_regval;
-	struct  {
-		bdrkreg_t	i_vld                     :	 1;
-		bdrkreg_t	i_to_cnt                  :	 5;
-		bdrkreg_t	i_widget                  :	 4;
-		bdrkreg_t	i_rsvd                    :	 2;
-		bdrkreg_t	i_source                  :	 8;
-		bdrkreg_t	i_init                    :	 3;
-		bdrkreg_t	i_addr                    :	38;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-	} ii_iprte5_fld_s;
-} ii_iprte5_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte6_u {
-	bdrkreg_t	ii_iprte6_regval;
-	struct	{
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_vld			  :	 1;
-	} ii_iprte6_fld_s;
-} ii_iprte6_u_t;
-
-#else
-
-typedef union ii_iprte6_u {
-	bdrkreg_t	ii_iprte6_regval;
-	struct  {
-		bdrkreg_t	i_vld                     :	 1;
-		bdrkreg_t	i_to_cnt                  :	 5;
-		bdrkreg_t	i_widget                  :	 4;
-		bdrkreg_t	i_rsvd                    :	 2;
-		bdrkreg_t	i_source                  :	 8;
-		bdrkreg_t	i_init                    :	 3;
-		bdrkreg_t	i_addr                    :	38;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-	} ii_iprte6_fld_s;
-} ii_iprte6_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte7_u {
-        bdrkreg_t       ii_iprte7_regval;
-        struct  {
-                bdrkreg_t       i_rsvd_1                  :      3;
-                bdrkreg_t       i_addr                    :     38;
-                bdrkreg_t       i_init                    :      3;
-                bdrkreg_t       i_source                  :      8;
-                bdrkreg_t       i_rsvd                    :      2;
-                bdrkreg_t       i_widget                  :      4;
-                bdrkreg_t       i_to_cnt                  :      5;
-                bdrkreg_t       i_vld                     :      1;
-        } ii_iprte7_fld_s;
-} ii_iprte7_u_t;
-
-#else
-
-typedef union ii_iprte7_u {
-	bdrkreg_t	ii_iprte7_regval;
-	struct  {
-		bdrkreg_t	i_vld                     :	 1;
-		bdrkreg_t	i_to_cnt                  :	 5;
-		bdrkreg_t	i_widget                  :	 4;
-		bdrkreg_t	i_rsvd                    :	 2;
-		bdrkreg_t	i_source                  :	 8;
-		bdrkreg_t	i_init                    :	 3;
-		bdrkreg_t	i_addr                    :	38;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-	} ii_iprte7_fld_s;
-} ii_iprte7_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Bedrock_II contains a feature which did not exist in   *
- * the Hub which automatically cleans up after a Read Response          *
- * timeout, including deallocation of the IPRTE and recovery of IBuf    *
- * space. The inclusion of this register in Bedrock is for backward     *
- * compatibility                                                        *
- * A write to this register causes an entry from the table of           *
- * outstanding PIO Read Requests to be freed and returned to the        *
- * stack of free entries. This register is used in handling the         *
- * timeout errors that result in a PIO Reply never returning from       *
- * Crosstalk.                                                           *
- * Note that this register does not affect the contents of the IPRTE    *
- * registers. The Valid bits in those registers have to be              *
- * specifically turned off by software.                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ipdr_u {
-	bdrkreg_t	ii_ipdr_regval;
-	struct  {
-		bdrkreg_t	i_te                      :	 3;
-		bdrkreg_t	i_rsvd_1		  :	 1;
-		bdrkreg_t	i_pnd			  :	 1;
-		bdrkreg_t	i_init_rpcnt		  :	 1;
-		bdrkreg_t	i_rsvd			  :	58;
-	} ii_ipdr_fld_s;
-} ii_ipdr_u_t;
-
-#else
-
-typedef union ii_ipdr_u {
-	bdrkreg_t	ii_ipdr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	58;
-		bdrkreg_t	i_init_rpcnt		  :	 1;
-		bdrkreg_t	i_pnd			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 1;
-		bdrkreg_t	i_te			  :	 3;
-	} ii_ipdr_fld_s;
-} ii_ipdr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register causes a CRB entry to be returned to the   *
- * queue of free CRBs. The entry should have previously been cleared    *
- * (mark bit) via backdoor access to the pertinent CRB entry. This      *
- * register is used in the last step of handling the errors that are    *
- * captured and marked in CRB entries.  Briefly: 1) first error for     *
- * DMA write from a particular device, and first error for a            *
- * particular BTE stream, lead to a marked CRB entry, and processor     *
- * interrupt, 2) software reads the error information captured in the   *
- * CRB entry, and presumably takes some corrective action, 3)           *
- * software clears the mark bit, and finally 4) software writes to      *
- * the ICDR register to return the CRB entry to the list of free CRB    *
- * entries.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icdr_u {
-	bdrkreg_t	ii_icdr_regval;
-	struct  {
-		bdrkreg_t	i_crb_num                 :	 4;
-		bdrkreg_t	i_pnd			  :	 1;
-		bdrkreg_t       i_rsvd                    :     59;
-	} ii_icdr_fld_s;
-} ii_icdr_u_t;
-
-#else
-
-typedef union ii_icdr_u {
-	bdrkreg_t	ii_icdr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	59;
-		bdrkreg_t	i_pnd			  :	 1;
-		bdrkreg_t	i_crb_num		  :	 4;
-	} ii_icdr_fld_s;
-} ii_icdr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register provides debug access to two FIFOs inside of II.      *
- * Both IOQ_MAX* fields of this register contain the instantaneous      *
- * depth (in units of the number of available entries) of the           *
- * associated IOQ FIFO.  A read of this register will return the        *
- * number of free entries on each FIFO at the time of the read.  So     *
- * when a FIFO is idle, the associated field contains the maximum       *
- * depth of the FIFO.  This register is writable for debug reasons      *
- * and is intended to be written with the maximum desired FIFO depth    *
- * while the FIFO is idle. Software must assure that II is idle when    *
- * this register is written. If there are any active entries in any     *
- * of these FIFOs when this register is written, the results are        *
- * undefined.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ifdr_u {
-	bdrkreg_t	ii_ifdr_regval;
-	struct  {
-		bdrkreg_t	i_ioq_max_rq              :	 7;
-		bdrkreg_t	i_set_ioq_rq		  :	 1;
-		bdrkreg_t	i_ioq_max_rp		  :	 7;
-		bdrkreg_t	i_set_ioq_rp		  :	 1;
-		bdrkreg_t	i_rsvd			  :	48;
-	} ii_ifdr_fld_s;
-} ii_ifdr_u_t;
-
-#else
-
-typedef union ii_ifdr_u {
-	bdrkreg_t	ii_ifdr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	48;
-		bdrkreg_t	i_set_ioq_rp		  :	 1;
-		bdrkreg_t	i_ioq_max_rp		  :	 7;
-		bdrkreg_t	i_set_ioq_rq		  :	 1;
-		bdrkreg_t	i_ioq_max_rq		  :	 7;
-	} ii_ifdr_fld_s;
-} ii_ifdr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows the II to become sluggish in removing          *
- * messages from its inbound queue (IIQ). This will cause messages to   *
- * back up in either virtual channel. Disabling the "molasses" mode     *
- * subsequently allows the II to be tested under stress. In the         *
- * sluggish ("Molasses") mode, the localized effects of congestion      *
- * can be observed.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iiap_u {
-        bdrkreg_t       ii_iiap_regval;
-        struct  {
-                bdrkreg_t       i_rq_mls                  :      6;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_rp_mls		  :	 6;
-		bdrkreg_t       i_rsvd                    :     50;
-        } ii_iiap_fld_s;
-} ii_iiap_u_t;
-
-#else
-
-typedef union ii_iiap_u {
-	bdrkreg_t	ii_iiap_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	50;
-		bdrkreg_t	i_rp_mls                  :	 6;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_rq_mls                  :	 6;
-	} ii_iiap_fld_s;
-} ii_iiap_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows several parameters of CRB operation to be      *
- * set. Note that writing to this register can have catastrophic side   *
- * effects, if the CRB is not quiescent, i.e. if the CRB is             *
- * processing protocol messages when the write occurs.                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icmr_u {
-	bdrkreg_t	ii_icmr_regval;
-	struct  {
-		bdrkreg_t	i_sp_msg                  :	 1;
-		bdrkreg_t	i_rd_hdr		  :	 1;
-		bdrkreg_t	i_rsvd_4		  :	 2;
-		bdrkreg_t	i_c_cnt			  :	 4;
-		bdrkreg_t	i_rsvd_3		  :	 4;
-		bdrkreg_t	i_clr_rqpd		  :	 1;
-		bdrkreg_t	i_clr_rppd		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_fc_cnt		  :	 4;
-		bdrkreg_t	i_crb_vld		  :	15;
-		bdrkreg_t	i_crb_mark		  :	15;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_precise		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-	} ii_icmr_fld_s;
-} ii_icmr_u_t;
-
-#else
-
-typedef union ii_icmr_u {
-	bdrkreg_t	ii_icmr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_precise		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_crb_mark		  :	15;
-		bdrkreg_t	i_crb_vld		  :	15;
-		bdrkreg_t	i_fc_cnt		  :	 4;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_clr_rppd		  :	 1;
-		bdrkreg_t	i_clr_rqpd		  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 4;
-		bdrkreg_t	i_c_cnt			  :	 4;
-		bdrkreg_t	i_rsvd_4		  :	 2;
-		bdrkreg_t	i_rd_hdr		  :	 1;
-		bdrkreg_t	i_sp_msg		  :	 1;
-	} ii_icmr_fld_s;
-} ii_icmr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows control of the table portion of the CRB        *
- * logic via software. Control operations from this register have       *
- * priority over all incoming Crosstalk or BTE requests.                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iccr_u {
-	bdrkreg_t	ii_iccr_regval;
-	struct  {
-		bdrkreg_t	i_crb_num                 :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_cmd			  :	 8;
-		bdrkreg_t	i_pending		  :	 1;
-		bdrkreg_t	i_rsvd			  :	47;
-	} ii_iccr_fld_s;
-} ii_iccr_u_t;
-
-#else
-
-typedef union ii_iccr_u {
-	bdrkreg_t	ii_iccr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	47;
-		bdrkreg_t	i_pending		  :	 1;
-		bdrkreg_t	i_cmd			  :	 8;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_crb_num		  :	 4;
-	} ii_iccr_fld_s;
-} ii_iccr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows the maximum timeout value to be programmed.    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icto_u {
-	bdrkreg_t	ii_icto_regval;
-	struct  {
-		bdrkreg_t	i_timeout                 :	 8;
-		bdrkreg_t	i_rsvd			  :	56;
-	} ii_icto_fld_s;
-} ii_icto_u_t;
-
-#else
-
-typedef union ii_icto_u {
-	bdrkreg_t	ii_icto_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	56;
-		bdrkreg_t	i_timeout		  :	 8;
-	} ii_icto_fld_s;
-} ii_icto_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows the timeout prescalar to be programmed. An     *
- * internal counter is associated with this register. When the          *
- * internal counter reaches the value of the PRESCALE field, the        *
- * timer registers in all valid CRBs are incremented (CRBx_D[TIMEOUT]   *
- * field). The internal counter resets to zero, and then continues      *
- * counting.                                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ictp_u {
-	bdrkreg_t	ii_ictp_regval;
-	struct  {
-		bdrkreg_t	i_prescale                :	24;
-		bdrkreg_t	i_rsvd			  :	40;
-	} ii_ictp_fld_s;
-} ii_ictp_u_t;
-
-#else
-
-typedef union ii_ictp_u {
-	bdrkreg_t	ii_ictp_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	40;
-		bdrkreg_t	i_prescale		  :	24;
-	} ii_ictp_fld_s;
-} ii_ictp_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, four   *
- * registers (_A to _D) are required to read and write each entry.      *
- * The CRB Entry registers can be conceptualized as rows and columns    *
- * (illustrated in the table above). Each row contains the 4            *
- * registers required for a single CRB Entry. The first doubleword      *
- * (column) for each entry is labeled A, and the second doubleword      *
- * (higher address) is labeled B, the third doubleword is labeled C,    *
- * and the fourth doubleword is labeled D. All CRB entries have their   *
- * addresses on a quarter cacheline aligned boundary.                   *
- * Upon reset, only the following fields are initialized: valid         *
- * (VLD), priority count, timeout, timeout valid, and context valid.    *
- * All other bits should be cleared by software before use (after       *
- * recovering any potential error state from before the reset).         *
- * The following four tables summarize the format for the four          *
- * registers that are used for each ICRB# Entry.                        *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icrb0_a_u {
-	bdrkreg_t	ii_icrb0_a_regval;
-	struct  {
-		bdrkreg_t	ia_iow                    :	 1;
-		bdrkreg_t	ia_vld			  :	 1;
-		bdrkreg_t	ia_addr			  :	38;
-		bdrkreg_t	ia_tnum			  :	 5;
-		bdrkreg_t	ia_sidn			  :	 4;
-		bdrkreg_t	ia_xt_err		  :	 1;
-		bdrkreg_t	ia_mark			  :	 1;
-		bdrkreg_t	ia_ln_uce		  :	 1;
-		bdrkreg_t	ia_errcode		  :	 3;
-		bdrkreg_t	ia_error		  :	 1;
-		bdrkreg_t	ia_stall__bte_1		  :	 1;
-		bdrkreg_t	ia_stall__bte_0		  :	 1;
-		bdrkreg_t       ia_rsvd                   :      6;
-	} ii_icrb0_a_fld_s;
-} ii_icrb0_a_u_t;
-
-#else
-
-typedef union ii_icrb0_a_u {
-	bdrkreg_t	ii_icrb0_a_regval;
-	struct	{
-		bdrkreg_t	ia_rsvd			  :	 6;
-		bdrkreg_t	ia_stall__bte_0		  :	 1;
-		bdrkreg_t	ia_stall__bte_1		  :	 1;
-		bdrkreg_t	ia_error		  :	 1;
-		bdrkreg_t	ia_errcode		  :	 3;
-		bdrkreg_t	ia_ln_uce		  :	 1;
-		bdrkreg_t	ia_mark			  :	 1;
-		bdrkreg_t	ia_xt_err		  :	 1;
-		bdrkreg_t	ia_sidn			  :	 4;
-		bdrkreg_t	ia_tnum			  :	 5;
-		bdrkreg_t	ia_addr			  :	38;
-		bdrkreg_t	ia_vld			  :	 1;
-		bdrkreg_t	ia_iow			  :	 1;
-	} ii_icrb0_a_fld_s;
-} ii_icrb0_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, four   *
- * registers (_A to _D) are required to read and write each entry.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icrb0_b_u {
-	bdrkreg_t	ii_icrb0_b_regval;
-	struct	{
-		bdrkreg_t	ib_stall__intr		  :	 1;
-		bdrkreg_t	ib_stall_ib		  :	 1;
-		bdrkreg_t	ib_intvn		  :	 1;
-		bdrkreg_t	ib_wb			  :	 1;
-		bdrkreg_t	ib_hold			  :	 1;
-		bdrkreg_t	ib_ack			  :	 1;
-		bdrkreg_t	ib_resp			  :	 1;
-		bdrkreg_t	ib_ack_cnt		  :	11;
-		bdrkreg_t	ib_rsvd_1		  :	 7;
-		bdrkreg_t	ib_exc			  :	 5;
-		bdrkreg_t	ib_init			  :	 3;
-		bdrkreg_t	ib_imsg			  :	 8;
-		bdrkreg_t	ib_imsgtype		  :	 2;
-		bdrkreg_t	ib_use_old		  :	 1;
-		bdrkreg_t	ib_source		  :	12;
-		bdrkreg_t	ib_size			  :	 2;
-		bdrkreg_t	ib_ct			  :	 1;
-		bdrkreg_t	ib_bte_num		  :	 1;
-		bdrkreg_t	ib_rsvd			  :	 4;
-	} ii_icrb0_b_fld_s;
-} ii_icrb0_b_u_t;
-
-#else
-
-typedef union ii_icrb0_b_u {
-	bdrkreg_t	ii_icrb0_b_regval;
-	struct  {
-		bdrkreg_t	ib_rsvd                   :	 4;
-		bdrkreg_t	ib_bte_num                :	 1;
-		bdrkreg_t	ib_ct                     :	 1;
-		bdrkreg_t	ib_size                   :	 2;
-		bdrkreg_t	ib_source                 :	12;
-		bdrkreg_t	ib_use_old                :	 1;
-		bdrkreg_t	ib_imsgtype               :	 2;
-		bdrkreg_t	ib_imsg                   :	 8;
-		bdrkreg_t	ib_init                   :	 3;
-		bdrkreg_t	ib_exc                    :	 5;
-		bdrkreg_t	ib_rsvd_1                 :	 7;
-		bdrkreg_t	ib_ack_cnt                :	11;
-		bdrkreg_t	ib_resp                   :	 1;
-		bdrkreg_t	ib_ack                    :	 1;
-		bdrkreg_t	ib_hold                   :	 1;
-		bdrkreg_t	ib_wb                     :	 1;
-		bdrkreg_t	ib_intvn                  :	 1;
-		bdrkreg_t	ib_stall_ib               :	 1;
-		bdrkreg_t	ib_stall__intr            :	 1;
-	} ii_icrb0_b_fld_s;
-} ii_icrb0_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, four   *
- * registers (_A to _D) are required to read and write each entry.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icrb0_c_u {
-	bdrkreg_t	ii_icrb0_c_regval;
-	struct	{
-		bdrkreg_t	ic_gbr			  :	 1;
-		bdrkreg_t	ic_resprqd		  :	 1;
-		bdrkreg_t	ic_bo			  :	 1;
-		bdrkreg_t	ic_suppl		  :	12;
-		bdrkreg_t	ic_pa_be		  :	34;
-		bdrkreg_t	ic_bte_op		  :	 1;
-		bdrkreg_t	ic_pr_psc		  :	 4;
-		bdrkreg_t	ic_pr_cnt		  :	 4;
-		bdrkreg_t	ic_sleep		  :	 1;
-		bdrkreg_t	ic_rsvd			  :	 5;
-	} ii_icrb0_c_fld_s;
-} ii_icrb0_c_u_t;
-
-#else
-
-typedef union ii_icrb0_c_u {
-	bdrkreg_t	ii_icrb0_c_regval;
-	struct  {
-		bdrkreg_t	ic_rsvd                   :	 5;
-		bdrkreg_t	ic_sleep                  :	 1;
-		bdrkreg_t	ic_pr_cnt                 :	 4;
-		bdrkreg_t	ic_pr_psc                 :	 4;
-		bdrkreg_t	ic_bte_op                 :	 1;
-		bdrkreg_t	ic_pa_be                  :	34;
-		bdrkreg_t	ic_suppl                  :	12;
-		bdrkreg_t	ic_bo                     :	 1;
-		bdrkreg_t	ic_resprqd                :	 1;
-		bdrkreg_t	ic_gbr                    :	 1;
-	} ii_icrb0_c_fld_s;
-} ii_icrb0_c_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, four   *
- * registers (_A to _D) are required to read and write each entry.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icrb0_d_u {
-	bdrkreg_t	ii_icrb0_d_regval;
-	struct  {
-		bdrkreg_t	id_timeout                :	 8;
-		bdrkreg_t	id_context		  :	15;
-		bdrkreg_t	id_rsvd_1		  :	 1;
-		bdrkreg_t	id_tvld			  :	 1;
-		bdrkreg_t	id_cvld			  :	 1;
-		bdrkreg_t	id_rsvd			  :	38;
-	} ii_icrb0_d_fld_s;
-} ii_icrb0_d_u_t;
-
-#else
-
-typedef union ii_icrb0_d_u {
-	bdrkreg_t	ii_icrb0_d_regval;
-	struct	{
-		bdrkreg_t	id_rsvd			  :	38;
-		bdrkreg_t	id_cvld			  :	 1;
-		bdrkreg_t	id_tvld			  :	 1;
-		bdrkreg_t	id_rsvd_1		  :	 1;
-		bdrkreg_t	id_context		  :	15;
-		bdrkreg_t	id_timeout		  :	 8;
-	} ii_icrb0_d_fld_s;
-} ii_icrb0_d_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the lower 64 bits of the header of the       *
- * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
- * register is set.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icsml_u {
-	bdrkreg_t	ii_icsml_regval;
-	struct  {
-		bdrkreg_t	i_tt_addr                 :	38;
-		bdrkreg_t	i_tt_ack_cnt		  :	11;
-		bdrkreg_t	i_newsuppl_ex		  :	11;
-		bdrkreg_t	i_reserved		  :	 3;
-		bdrkreg_t       i_overflow                :      1;
-	} ii_icsml_fld_s;
-} ii_icsml_u_t;
-
-#else
-
-typedef union ii_icsml_u {
-	bdrkreg_t	ii_icsml_regval;
-	struct	{
-		bdrkreg_t	i_overflow		  :	 1;
-		bdrkreg_t	i_reserved		  :	 3;
-		bdrkreg_t	i_newsuppl_ex		  :	11;
-		bdrkreg_t	i_tt_ack_cnt		  :	11;
-		bdrkreg_t	i_tt_addr		  :	38;
-	} ii_icsml_fld_s;
-} ii_icsml_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the microscopic state, all the inputs to     *
- * the protocol table, captured with the spurious message. Valid when   *
- * the SP_MSG bit in the ICMR register is set.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icsmh_u {
-	bdrkreg_t	ii_icsmh_regval;
-	struct  {
-		bdrkreg_t	i_tt_vld                  :	 1;
-		bdrkreg_t	i_xerr			  :	 1;
-		bdrkreg_t	i_ft_cwact_o		  :	 1;
-		bdrkreg_t	i_ft_wact_o		  :	 1;
-		bdrkreg_t       i_ft_active_o             :      1;
-		bdrkreg_t	i_sync			  :	 1;
-		bdrkreg_t	i_mnusg			  :	 1;
-		bdrkreg_t	i_mnusz			  :	 1;
-		bdrkreg_t	i_plusz			  :	 1;
-		bdrkreg_t	i_plusg			  :	 1;
-		bdrkreg_t	i_tt_exc		  :	 5;
-		bdrkreg_t	i_tt_wb			  :	 1;
-		bdrkreg_t	i_tt_hold		  :	 1;
-		bdrkreg_t	i_tt_ack		  :	 1;
-		bdrkreg_t	i_tt_resp		  :	 1;
-		bdrkreg_t	i_tt_intvn		  :	 1;
-		bdrkreg_t	i_g_stall_bte1		  :	 1;
-		bdrkreg_t	i_g_stall_bte0		  :	 1;
-		bdrkreg_t	i_g_stall_il		  :	 1;
-		bdrkreg_t	i_g_stall_ib		  :	 1;
-		bdrkreg_t	i_tt_imsg		  :	 8;
-		bdrkreg_t	i_tt_imsgtype		  :	 2;
-		bdrkreg_t	i_tt_use_old		  :	 1;
-		bdrkreg_t	i_tt_respreqd		  :	 1;
-		bdrkreg_t	i_tt_bte_num		  :	 1;
-		bdrkreg_t	i_cbn			  :	 1;
-		bdrkreg_t	i_match			  :	 1;
-		bdrkreg_t	i_rpcnt_lt_34		  :	 1;
-		bdrkreg_t	i_rpcnt_ge_34		  :	 1;
-		bdrkreg_t	i_rpcnt_lt_18		  :	 1;
-		bdrkreg_t	i_rpcnt_ge_18		  :	 1;
-		bdrkreg_t       i_rpcnt_lt_2              :      1;
-		bdrkreg_t	i_rpcnt_ge_2		  :	 1;
-		bdrkreg_t	i_rqcnt_lt_18		  :	 1;
-		bdrkreg_t	i_rqcnt_ge_18		  :	 1;
-		bdrkreg_t	i_rqcnt_lt_2		  :	 1;
-		bdrkreg_t	i_rqcnt_ge_2		  :	 1;
-		bdrkreg_t	i_tt_device		  :	 7;
-		bdrkreg_t	i_tt_init		  :	 3;
-		bdrkreg_t	i_reserved		  :	 5;
-	} ii_icsmh_fld_s;
-} ii_icsmh_u_t;
-
-#else
-
-typedef union ii_icsmh_u {
-	bdrkreg_t	ii_icsmh_regval;
-	struct	{
-		bdrkreg_t	i_reserved		  :	 5;
-		bdrkreg_t	i_tt_init		  :	 3;
-		bdrkreg_t	i_tt_device		  :	 7;
-		bdrkreg_t	i_rqcnt_ge_2		  :	 1;
-		bdrkreg_t	i_rqcnt_lt_2		  :	 1;
-		bdrkreg_t	i_rqcnt_ge_18		  :	 1;
-		bdrkreg_t	i_rqcnt_lt_18		  :	 1;
-		bdrkreg_t	i_rpcnt_ge_2		  :	 1;
-		bdrkreg_t	i_rpcnt_lt_2		  :	 1;
-		bdrkreg_t	i_rpcnt_ge_18		  :	 1;
-		bdrkreg_t	i_rpcnt_lt_18		  :	 1;
-		bdrkreg_t	i_rpcnt_ge_34		  :	 1;
-		bdrkreg_t	i_rpcnt_lt_34		  :	 1;
-		bdrkreg_t	i_match			  :	 1;
-		bdrkreg_t	i_cbn			  :	 1;
-		bdrkreg_t	i_tt_bte_num		  :	 1;
-		bdrkreg_t	i_tt_respreqd		  :	 1;
-		bdrkreg_t	i_tt_use_old		  :	 1;
-		bdrkreg_t	i_tt_imsgtype		  :	 2;
-		bdrkreg_t	i_tt_imsg		  :	 8;
-		bdrkreg_t	i_g_stall_ib		  :	 1;
-		bdrkreg_t	i_g_stall_il		  :	 1;
-		bdrkreg_t	i_g_stall_bte0		  :	 1;
-		bdrkreg_t	i_g_stall_bte1		  :	 1;
-		bdrkreg_t	i_tt_intvn		  :	 1;
-		bdrkreg_t	i_tt_resp		  :	 1;
-		bdrkreg_t	i_tt_ack		  :	 1;
-		bdrkreg_t	i_tt_hold		  :	 1;
-		bdrkreg_t	i_tt_wb			  :	 1;
-		bdrkreg_t	i_tt_exc		  :	 5;
-		bdrkreg_t	i_plusg			  :	 1;
-		bdrkreg_t	i_plusz			  :	 1;
-		bdrkreg_t	i_mnusz			  :	 1;
-		bdrkreg_t	i_mnusg			  :	 1;
-		bdrkreg_t	i_sync			  :	 1;
-		bdrkreg_t	i_ft_active_o		  :	 1;
-		bdrkreg_t	i_ft_wact_o		  :	 1;
-		bdrkreg_t	i_ft_cwact_o		  :	 1;
-		bdrkreg_t	i_xerr			  :	 1;
-		bdrkreg_t	i_tt_vld		  :	 1;
-	} ii_icsmh_fld_s;
-} ii_icsmh_u_t;
-
-#endif
-
-
-/************************************************************************
- *                                                                      *
- *  The Bedrock DEBUG unit provides a 3-bit selection signal to the     *
- * II unit, thus allowing a choice of one set of debug signal outputs   *
- * from a menu of 8 options. Each option is limited to 32 bits in       *
- * size. There are more signals of interest than can be accommodated    *
- * in this 8*32 framework, so the IDBSS register has been defined to    *
- * extend the range of choices available. For each menu option          *
- * available to the DEBUG unit, the II provides a "submenu" of          *
- * several options. The value of the SUBMENU field in the IDBSS         *
- * register selects the desired submenu. Hence, the particular debug    *
- * signals provided by the II are determined by the 3-bit selection     *
- * signal from the DEBUG unit and the value of the SUBMENU field        *
- * within the IDBSS register. For a detailed description of the         *
- * available menus and submenus for II debug signals, refer to the      *
- * documentation in ii_interface.doc..                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LIITLE_ENDIAN
-
-typedef union ii_idbss_u {
-	bdrkreg_t	ii_idbss_regval;
-	struct  {
-		bdrkreg_t	i_submenu                 :	 3;
-		bdrkreg_t	i_rsvd			  :	61;
-	} ii_idbss_fld_s;
-} ii_idbss_u_t;
-
-#else
-
-typedef union ii_idbss_u {
-	bdrkreg_t	ii_idbss_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	61;
-		bdrkreg_t	i_submenu		  :	 3;
-	} ii_idbss_fld_s;
-} ii_idbss_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register is used to set up the length for a       *
- * transfer and then to monitor the progress of that transfer. This     *
- * register needs to be initialized before a transfer is started. A     *
- * legitimate write to this register will set the Busy bit, clear the   *
- * Error bit, and initialize the length to the value desired.           *
- * While the transfer is in progress, hardware will decrement the       *
- * length field with each successful block that is copied. Once the     *
- * transfer completes, hardware will clear the Busy bit. The length     *
- * field will also contain the number of cache lines left to be         *
- * transferred.                                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LIITLE_ENDIAN
-
-typedef union ii_ibls0_u {
-	bdrkreg_t	ii_ibls0_regval;
-	struct	{
-		bdrkreg_t	i_length		  :	16;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_busy			  :	 1;
-		bdrkreg_t       i_rsvd                    :     43;
-	} ii_ibls0_fld_s;
-} ii_ibls0_u_t;
-
-#else
-
-typedef union ii_ibls0_u {
-	bdrkreg_t	ii_ibls0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	43;
-		bdrkreg_t	i_busy                    :	 1;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_length                  :	16;
-	} ii_ibls0_fld_s;
-} ii_ibls0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibsa0_u {
-	bdrkreg_t	ii_ibsa0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t       i_rsvd                    :     24;
-	} ii_ibsa0_fld_s;
-} ii_ibsa0_u_t;
-
-#else
-
-typedef union ii_ibsa0_u {
-	bdrkreg_t	ii_ibsa0_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibsa0_fld_s;
-} ii_ibsa0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibda0_u {
-	bdrkreg_t	ii_ibda0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd			  :	24;
-	} ii_ibda0_fld_s;
-} ii_ibda0_u_t;
-
-#else
-
-typedef union ii_ibda0_u {
-	bdrkreg_t	ii_ibda0_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibda0_fld_s;
-} ii_ibda0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Writing to this register sets up the attributes of the transfer     *
- * and initiates the transfer operation. Reading this register has      *
- * the side effect of terminating any transfer in progress. Note:       *
- * stopping a transfer midstream could have an adverse impact on the    *
- * other BTE. If a BTE stream has to be stopped (due to error           *
- * handling for example), both BTE streams should be stopped and        *
- * their transfers discarded.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibct0_u {
-	bdrkreg_t	ii_ibct0_regval;
-	struct  {
-		bdrkreg_t	i_zerofill                :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_notify		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t       i_poison                  :      1;
-		bdrkreg_t       i_rsvd                    :     55;
-	} ii_ibct0_fld_s;
-} ii_ibct0_u_t;
-
-#else
-
-typedef union ii_ibct0_u {
-	bdrkreg_t	ii_ibct0_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	55;
-		bdrkreg_t	i_poison		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_notify		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_zerofill		  :	 1;
-	} ii_ibct0_fld_s;
-} ii_ibct0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the address to which the WINV is sent.       *
- * This address has to be cache line aligned.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibna0_u {
-	bdrkreg_t	ii_ibna0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd			  :	24;
-	} ii_ibna0_fld_s;
-} ii_ibna0_u_t;
-
-#else
-
-typedef union ii_ibna0_u {
-	bdrkreg_t	ii_ibna0_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibna0_fld_s;
-} ii_ibna0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the programmable level as well as the node   *
- * ID and PI unit of the processor to which the interrupt will be       *
- * sent.                                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibia0_u {
-	bdrkreg_t	ii_ibia0_regval;
-	struct  {
-		bdrkreg_t	i_pi_id                   :	 1;
-		bdrkreg_t	i_node_id		  :	 8;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_level			  :	 7;
-		bdrkreg_t       i_rsvd                    :     41;
-	} ii_ibia0_fld_s;
-} ii_ibia0_u_t;
-
-#else
-
-typedef union ii_ibia0_u {
-	bdrkreg_t	ii_ibia0_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	41;
-		bdrkreg_t	i_level			  :	 7;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_node_id		  :	 8;
-		bdrkreg_t	i_pi_id			  :	 1;
-	} ii_ibia0_fld_s;
-} ii_ibia0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register is used to set up the length for a       *
- * transfer and then to monitor the progress of that transfer. This     *
- * register needs to be initialized before a transfer is started. A     *
- * legitimate write to this register will set the Busy bit, clear the   *
- * Error bit, and initialize the length to the value desired.           *
- * While the transfer is in progress, hardware will decrement the       *
- * length field with each successful block that is copied. Once the     *
- * transfer completes, hardware will clear the Busy bit. The length     *
- * field will also contain the number of cache lines left to be         *
- * transferred.                                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibls1_u {
-	bdrkreg_t	ii_ibls1_regval;
-	struct  {
-		bdrkreg_t	i_length                  :	16;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_busy			  :	 1;
-		bdrkreg_t       i_rsvd                    :     43;
-	} ii_ibls1_fld_s;
-} ii_ibls1_u_t;
-
-#else
-
-typedef union ii_ibls1_u {
-	bdrkreg_t	ii_ibls1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	43;
-		bdrkreg_t	i_busy			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_length		  :	16;
-	} ii_ibls1_fld_s;
-} ii_ibls1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibsa1_u {
-	bdrkreg_t	ii_ibsa1_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd			  :	24;
-	} ii_ibsa1_fld_s;
-} ii_ibsa1_u_t;
-
-#else
-
-typedef union ii_ibsa1_u {
-	bdrkreg_t	ii_ibsa1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibsa1_fld_s;
-} ii_ibsa1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibda1_u {
-	bdrkreg_t	ii_ibda1_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd			  :	24;
-	} ii_ibda1_fld_s;
-} ii_ibda1_u_t;
-
-#else
-
-typedef union ii_ibda1_u {
-	bdrkreg_t	ii_ibda1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibda1_fld_s;
-} ii_ibda1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Writing to this register sets up the attributes of the transfer     *
- * and initiates the transfer operation. Reading this register has      *
- * the side effect of terminating any transfer in progress. Note:       *
- * stopping a transfer midstream could have an adverse impact on the    *
- * other BTE. If a BTE stream has to be stopped (due to error           *
- * handling for example), both BTE streams should be stopped and        *
- * their transfers discarded.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibct1_u {
-	bdrkreg_t	ii_ibct1_regval;
-	struct  {
-		bdrkreg_t	i_zerofill                :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_notify		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_poison		  :	 1;
-		bdrkreg_t	i_rsvd			  :	55;
-	} ii_ibct1_fld_s;
-} ii_ibct1_u_t;
-
-#else
-
-typedef union ii_ibct1_u {
-	bdrkreg_t	ii_ibct1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	55;
-		bdrkreg_t	i_poison		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_notify		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_zerofill		  :	 1;
-	} ii_ibct1_fld_s;
-} ii_ibct1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the address to which the WINV is sent.       *
- * This address has to be cache line aligned.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibna1_u {
-	bdrkreg_t	ii_ibna1_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t       i_rsvd                    :     24;
-	} ii_ibna1_fld_s;
-} ii_ibna1_u_t;
-
-#else
-
-typedef union ii_ibna1_u {
-	bdrkreg_t	ii_ibna1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibna1_fld_s;
-} ii_ibna1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the programmable level as well as the node   *
- * ID and PI unit of the processor to which the interrupt will be       *
- * sent.                                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibia1_u {
-	bdrkreg_t	ii_ibia1_regval;
-	struct  {
-		bdrkreg_t	i_pi_id                   :	 1;
-		bdrkreg_t	i_node_id		  :	 8;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_level			  :	 7;
-		bdrkreg_t	i_rsvd			  :	41;
-	} ii_ibia1_fld_s;
-} ii_ibia1_u_t;
-
-#else
-
-typedef union ii_ibia1_u {
-	bdrkreg_t	ii_ibia1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	41;
-		bdrkreg_t	i_level			  :	 7;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_node_id		  :	 8;
-		bdrkreg_t	i_pi_id			  :	 1;
-	} ii_ibia1_fld_s;
-} ii_ibia1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register defines the resources that feed information into      *
- * the two performance counters located in the IO Performance           *
- * Profiling Register. There are 17 different quantities that can be    *
- * measured. Given these 17 different options, the two performance      *
- * counters have 15 of them in common; menu selections 0 through 0xE    *
- * are identical for each performance counter. As for the other two     *
- * options, one is available from one performance counter and the       *
- * other is available from the other performance counter. Hence, the    *
- * II supports all 17*16=272 possible combinations of quantities to     *
- * measure.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ipcr_u {
-	bdrkreg_t	ii_ipcr_regval;
-	struct  {
-		bdrkreg_t	i_ippr0_c                 :	 4;
-		bdrkreg_t	i_ippr1_c		  :	 4;
-		bdrkreg_t	i_icct			  :	 8;
-		bdrkreg_t       i_rsvd                    :     48;
-	} ii_ipcr_fld_s;
-} ii_ipcr_u_t;
-
-#else
-
-typedef union ii_ipcr_u {
-	bdrkreg_t	ii_ipcr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	48;
-		bdrkreg_t	i_icct			  :	 8;
-		bdrkreg_t	i_ippr1_c		  :	 4;
-		bdrkreg_t	i_ippr0_c		  :	 4;
-	} ii_ipcr_fld_s;
-} ii_ipcr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ippr_u {
-	bdrkreg_t	ii_ippr_regval;
-	struct  {
-		bdrkreg_t	i_ippr0                   :	32;
-		bdrkreg_t	i_ippr1			  :	32;
-	} ii_ippr_fld_s;
-} ii_ippr_u_t;
-
-#else
-
-typedef union ii_ippr_u {
-	bdrkreg_t	ii_ippr_regval;
-	struct	{
-		bdrkreg_t	i_ippr1			  :	32;
-		bdrkreg_t	i_ippr0			  :	32;
-	} ii_ippr_fld_s;
-} ii_ippr_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- * The following defines which were not formed into structures are      *
- * probably indentical to another register, and the name of the         *
- * register is provided against each of these registers. This           *
- * information needs to be checked carefully                            *
- *                                                                      *
- *           IIO_ICRB1_A                IIO_ICRB0_A                       *
- *           IIO_ICRB1_B                IIO_ICRB0_B                       *
- *           IIO_ICRB1_C                IIO_ICRB0_C                       *
- *           IIO_ICRB1_D                IIO_ICRB0_D                       *
- *           IIO_ICRB2_A                IIO_ICRB0_A                       *
- *           IIO_ICRB2_B                IIO_ICRB0_B                       *
- *           IIO_ICRB2_C                IIO_ICRB0_C                       *
- *           IIO_ICRB2_D                IIO_ICRB0_D                       *
- *           IIO_ICRB3_A                IIO_ICRB0_A                       *
- *           IIO_ICRB3_B                IIO_ICRB0_B                       *
- *           IIO_ICRB3_C                IIO_ICRB0_C                       *
- *           IIO_ICRB3_D                IIO_ICRB0_D                       *
- *           IIO_ICRB4_A                IIO_ICRB0_A                       *
- *           IIO_ICRB4_B                IIO_ICRB0_B                       *
- *           IIO_ICRB4_C                IIO_ICRB0_C                       *
- *           IIO_ICRB4_D                IIO_ICRB0_D                       *
- *           IIO_ICRB5_A                IIO_ICRB0_A                       *
- *           IIO_ICRB5_B                IIO_ICRB0_B                       *
- *           IIO_ICRB5_C                IIO_ICRB0_C                       *
- *           IIO_ICRB5_D                IIO_ICRB0_D                       *
- *           IIO_ICRB6_A                IIO_ICRB0_A                       *
- *           IIO_ICRB6_B                IIO_ICRB0_B                       *
- *           IIO_ICRB6_C                IIO_ICRB0_C                       *
- *           IIO_ICRB6_D                IIO_ICRB0_D                       *
- *           IIO_ICRB7_A                IIO_ICRB0_A                       *
- *           IIO_ICRB7_B                IIO_ICRB0_B                       *
- *           IIO_ICRB7_C                IIO_ICRB0_C                       *
- *           IIO_ICRB7_D                IIO_ICRB0_D                       *
- *           IIO_ICRB8_A                IIO_ICRB0_A                       *
- *           IIO_ICRB8_B                IIO_ICRB0_B                       *
- *           IIO_ICRB8_C                IIO_ICRB0_C                       *
- *           IIO_ICRB8_D                IIO_ICRB0_D                       *
- *           IIO_ICRB9_A                IIO_ICRB0_A                       *
- *           IIO_ICRB9_B                IIO_ICRB0_B                       *
- *           IIO_ICRB9_C                IIO_ICRB0_C                       *
- *           IIO_ICRB9_D                IIO_ICRB0_D                       *
- *           IIO_ICRBA_A                IIO_ICRB0_A                       *
- *           IIO_ICRBA_B                IIO_ICRB0_B                       *
- *           IIO_ICRBA_C                IIO_ICRB0_C                       *
- *           IIO_ICRBA_D                IIO_ICRB0_D                       *
- *           IIO_ICRBB_A                IIO_ICRB0_A                       *
- *           IIO_ICRBB_B                IIO_ICRB0_B                       *
- *           IIO_ICRBB_C                IIO_ICRB0_C                       *
- *           IIO_ICRBB_D                IIO_ICRB0_D                       *
- *           IIO_ICRBC_A                IIO_ICRB0_A                       *
- *           IIO_ICRBC_B                IIO_ICRB0_B                       *
- *           IIO_ICRBC_C                IIO_ICRB0_C                       *
- *           IIO_ICRBC_D                IIO_ICRB0_D                       *
- *           IIO_ICRBD_A                IIO_ICRB0_A                       *
- *           IIO_ICRBD_B                IIO_ICRB0_B                       *
- *           IIO_ICRBD_C                IIO_ICRB0_C                       *
- *           IIO_ICRBD_D                IIO_ICRB0_D                       *
- *           IIO_ICRBE_A                IIO_ICRB0_A                       *
- *           IIO_ICRBE_B                IIO_ICRB0_B                       *
- *           IIO_ICRBE_C                IIO_ICRB0_C                       *
- *           IIO_ICRBE_D                IIO_ICRB0_D                       *
- *                                                                      *
- ************************************************************************/
-
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBIO_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubio_next.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubio_next.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubio_next.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubio_next.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,762 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBIO_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBIO_NEXT_H
-
-/*
- * Slightly friendlier names for some common registers.
- */
-#define IIO_WIDGET              IIO_WID      /* Widget identification */
-#define IIO_WIDGET_STAT         IIO_WSTAT    /* Widget status register */
-#define IIO_WIDGET_CTRL         IIO_WCR      /* Widget control register */
-#define IIO_PROTECT             IIO_ILAPR    /* IO interface protection */
-#define IIO_PROTECT_OVRRD       IIO_ILAPO    /* IO protect override */
-#define IIO_OUTWIDGET_ACCESS    IIO_IOWA     /* Outbound widget access */
-#define IIO_INWIDGET_ACCESS     IIO_IIWA     /* Inbound widget access */
-#define IIO_INDEV_ERR_MASK      IIO_IIDEM    /* Inbound device error mask */
-#define IIO_LLP_CSR             IIO_ILCSR    /* LLP control and status */
-#define IIO_LLP_LOG             IIO_ILLR     /* LLP log */
-#define IIO_XTALKCC_TOUT        IIO_IXCC     /* Xtalk credit count timeout*/
-#define IIO_XTALKTT_TOUT        IIO_IXTT     /* Xtalk tail timeout */
-#define IIO_IO_ERR_CLR          IIO_IECLR    /* IO error clear */
-#define IIO_IGFX_0 		IIO_IGFX0
-#define IIO_IGFX_1 		IIO_IGFX1
-#define IIO_IBCT_0		IIO_IBCT0
-#define IIO_IBCT_1		IIO_IBCT1
-#define IIO_IBLS_0		IIO_IBLS0
-#define IIO_IBLS_1		IIO_IBLS1
-#define IIO_IBSA_0		IIO_IBSA0
-#define IIO_IBSA_1		IIO_IBSA1
-#define IIO_IBDA_0		IIO_IBDA0
-#define IIO_IBDA_1		IIO_IBDA1
-#define IIO_IBNA_0		IIO_IBNA0
-#define IIO_IBNA_1		IIO_IBNA1
-#define IIO_IBIA_0		IIO_IBIA0
-#define IIO_IBIA_1		IIO_IBIA1
-#define IIO_IOPRB_0		IIO_IPRB0
-#define IIO_PRTE_0      	IIO_IPRTE0        /* PIO Read address table entry 0 */
-#define IIO_PRTE(_x)    	(IIO_PRTE_0 + (8 * (_x)))
-#define IIO_NUM_IPRBS 		(9) 
-#define IIO_WIDPRTE(x)  IIO_PRTE(((x) - 8)) /* widget ID to its PRTE num */
-
-#define IIO_LLP_CSR_IS_UP               0x00002000
-#define IIO_LLP_CSR_LLP_STAT_MASK       0x00003000
-#define IIO_LLP_CSR_LLP_STAT_SHFT       12
-
-#define IIO_LLP_CB_MAX  0xffff	/* in ILLR CB_CNT, Max Check Bit errors */
-#define IIO_LLP_SN_MAX  0xffff	/* in ILLR SN_CNT, Max Sequence Number errors */
-
-/* key to IIO_PROTECT_OVRRD */
-#define IIO_PROTECT_OVRRD_KEY   0x53474972756c6573ull   /* "SGIrules" */
-
-/* BTE register names */
-#define IIO_BTE_STAT_0          IIO_IBLS_0   /* Also BTE length/status 0 */
-#define IIO_BTE_SRC_0           IIO_IBSA_0   /* Also BTE source address  0 */
-#define IIO_BTE_DEST_0          IIO_IBDA_0   /* Also BTE dest. address 0 */
-#define IIO_BTE_CTRL_0          IIO_IBCT_0   /* Also BTE control/terminate 0 */
-#define IIO_BTE_NOTIFY_0        IIO_IBNA_0   /* Also BTE notification 0 */
-#define IIO_BTE_INT_0           IIO_IBIA_0   /* Also BTE interrupt 0 */
-#define IIO_BTE_OFF_0           0            /* Base offset from BTE 0 regs. */
-#define IIO_BTE_OFF_1  (IIO_IBLS_1 - IIO_IBLS_0) /* Offset from base to BTE 1 */
-
-/* BTE register offsets from base */
-#define BTEOFF_STAT             0
-#define BTEOFF_SRC              (IIO_BTE_SRC_0 - IIO_BTE_STAT_0)
-#define BTEOFF_DEST             (IIO_BTE_DEST_0 - IIO_BTE_STAT_0)
-#define BTEOFF_CTRL             (IIO_BTE_CTRL_0 - IIO_BTE_STAT_0)
-#define BTEOFF_NOTIFY           (IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0)
-#define BTEOFF_INT              (IIO_BTE_INT_0 - IIO_BTE_STAT_0)
-
-
-/* names used in hub_diags.c; carried over from SN0 */
-#define IIO_BASE_BTE0   IIO_IBLS_0		
-#define IIO_BASE_BTE1   IIO_IBLS_1		
-
-/*
- * Macro which takes the widget number, and returns the 
- * IO PRB address of that widget.
- * value _x is expected to be a widget number in the range 
- * 0, 8 - 0xF
- */
-#define	IIO_IOPRB(_x)	(IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
-			(_x) : \
-			(_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
-
-
-/* GFX Flow Control Node/Widget Register */
-#define IIO_IGFX_W_NUM_BITS	4	/* size of widget num field */
-#define IIO_IGFX_W_NUM_MASK	((1<<IIO_IGFX_W_NUM_BITS)-1)
-#define IIO_IGFX_W_NUM_SHIFT	0
-#define IIO_IGFX_PI_NUM_BITS	1	/* size of PI num field */
-#define IIO_IGFX_PI_NUM_MASK	((1<<IIO_IGFX_PI_NUM_BITS)-1)
-#define IIO_IGFX_PI_NUM_SHIFT	4
-#define IIO_IGFX_N_NUM_BITS	8	/* size of node num field */
-#define IIO_IGFX_N_NUM_MASK	((1<<IIO_IGFX_N_NUM_BITS)-1)
-#define IIO_IGFX_N_NUM_SHIFT	5
-#define IIO_IGFX_P_NUM_BITS	1	/* size of processor num field */
-#define IIO_IGFX_P_NUM_MASK	((1<<IIO_IGFX_P_NUM_BITS)-1)
-#define IIO_IGFX_P_NUM_SHIFT	16
-#define IIO_IGFX_INIT(widget, pi, node, cpu)				(\
-	(((widget) & IIO_IGFX_W_NUM_MASK) << IIO_IGFX_W_NUM_SHIFT) |	 \
-	(((pi)     & IIO_IGFX_PI_NUM_MASK)<< IIO_IGFX_PI_NUM_SHIFT)|	 \
-	(((node)   & IIO_IGFX_N_NUM_MASK) << IIO_IGFX_N_NUM_SHIFT) |	 \
-	(((cpu)    & IIO_IGFX_P_NUM_MASK) << IIO_IGFX_P_NUM_SHIFT))
-
-
-/* Scratch registers (all bits available) */
-#define IIO_SCRATCH_REG0        IIO_ISCR0
-#define IIO_SCRATCH_REG1        IIO_ISCR1
-#define IIO_SCRATCH_MASK        0xffffffffffffffff
-
-#define IIO_SCRATCH_BIT0_0      0x0000000000000001
-#define IIO_SCRATCH_BIT0_1      0x0000000000000002
-#define IIO_SCRATCH_BIT0_2      0x0000000000000004
-#define IIO_SCRATCH_BIT0_3      0x0000000000000008
-#define IIO_SCRATCH_BIT0_4      0x0000000000000010
-#define IIO_SCRATCH_BIT0_5      0x0000000000000020
-#define IIO_SCRATCH_BIT0_6      0x0000000000000040
-#define IIO_SCRATCH_BIT0_7      0x0000000000000080
-#define IIO_SCRATCH_BIT0_8      0x0000000000000100
-#define IIO_SCRATCH_BIT0_9      0x0000000000000200
-#define IIO_SCRATCH_BIT0_A      0x0000000000000400
-
-#define IIO_SCRATCH_BIT1_0      0x0000000000000001
-#define IIO_SCRATCH_BIT1_1      0x0000000000000002
-/* IO Translation Table Entries */
-#define IIO_NUM_ITTES   7               /* ITTEs numbered 0..6 */
-                                        /* Hw manuals number them 1..7! */
-/*
- * IIO_IMEM Register fields.
- */
-#define IIO_IMEM_W0ESD  0x1             /* Widget 0 shut down due to error */
-#define IIO_IMEM_B0ESD  (1 << 4)        /* BTE 0 shut down due to error */
-#define IIO_IMEM_B1ESD  (1 << 8)        /* BTE 1 Shut down due to error */
-
-/*
- * As a permanent workaround for a bug in the PI side of the hub, we've
- * redefined big window 7 as small window 0.
- XXX does this still apply for SN1??
- */
-#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
-
-/*
- * Use the top big window as a surrogate for the first small window
- */
-#define SWIN0_BIGWIN            HUB_NUM_BIG_WINDOW
-
-#define IIO_NUM_PRTES   8               /* Total number of PRB table entries */
-
-#define ILCSR_WARM_RESET        0x100
-
-/*
- * CRB manipulation macros
- *      The CRB macros are slightly complicated, since there are up to
- *      four registers associated with each CRB entry.
- */
-#define IIO_NUM_CRBS            15      /* Number of CRBs */
-#define IIO_NUM_NORMAL_CRBS     12      /* Number of regular CRB entries */
-#define IIO_NUM_PC_CRBS         4       /* Number of partial cache CRBs */
-#define IIO_ICRB_OFFSET         8
-#define IIO_ICRB_0              IIO_ICRB0_A
-#define IIO_ICRB_ADDR_SHFT	2	/* Shift to get proper address */
-/* XXX - This is now tuneable:
-        #define IIO_FIRST_PC_ENTRY 12
- */
-
-#define IIO_ICRB_A(_x)  (IIO_ICRB_0 + (4 * IIO_ICRB_OFFSET * (_x)))
-#define IIO_ICRB_B(_x)  (IIO_ICRB_A(_x) + 1*IIO_ICRB_OFFSET)
-#define IIO_ICRB_C(_x)  (IIO_ICRB_A(_x) + 2*IIO_ICRB_OFFSET)
-#define IIO_ICRB_D(_x)  (IIO_ICRB_A(_x) + 3*IIO_ICRB_OFFSET)
-
-#define TNUM_TO_WIDGET_DEV(_tnum)	(_tnum & 0x7)
-
-/*
- * values for "ecode" field
- */
-#define IIO_ICRB_ECODE_DERR     0       /* Directory error due to IIO access */
-#define IIO_ICRB_ECODE_PERR     1       /* Poison error on IO access */
-#define IIO_ICRB_ECODE_WERR     2       /* Write error by IIO access
-                                         * e.g. WINV to a Read only line. */
-#define IIO_ICRB_ECODE_AERR     3       /* Access error caused by IIO access */
-#define IIO_ICRB_ECODE_PWERR    4       /* Error on partial write       */
-#define IIO_ICRB_ECODE_PRERR    5       /* Error on partial read        */
-#define IIO_ICRB_ECODE_TOUT     6       /* CRB timeout before deallocating */
-#define IIO_ICRB_ECODE_XTERR    7       /* Incoming xtalk pkt had error bit */
-
-/*
- * Number of credits Hub widget has while sending req/response to
- * xbow.
- * Value of 3 is required by Xbow 1.1
- * We may be able to increase this to 4 with Xbow 1.2.
- */
-#define       HUBII_XBOW_CREDIT       3
-#define       HUBII_XBOW_REV2_CREDIT  4
-
-/*
- * Number of credits that xtalk devices should use when communicating
- * with a Bedrock (depth of Bedrock's queue).
- */
-#define HUB_CREDIT 4
-
-/*
- * Some IIO_PRB fields
- */
-#define IIO_PRB_MULTI_ERR	(1LL << 63)
-#define IIO_PRB_SPUR_RD		(1LL << 51)
-#define IIO_PRB_SPUR_WR		(1LL << 50)
-#define IIO_PRB_RD_TO		(1LL << 49)
-#define IIO_PRB_ERROR		(1LL << 48)
-
-/*************************************************************************
-
- Some of the IIO field masks and shifts are defined here.
- This is in order to maintain compatibility in SN0 and SN1 code
- 
-**************************************************************************/
-
-/*
- * ICMR register fields
- * (Note: the IIO_ICMR_P_CNT and IIO_ICMR_PC_VLD from Hub are not
- * present in Bedrock)
- */
-
-#define IIO_ICMR_CRB_VLD_SHFT   20
-#define IIO_ICMR_CRB_VLD_MASK   (0x7fffUL << IIO_ICMR_CRB_VLD_SHFT)
-
-#define IIO_ICMR_FC_CNT_SHFT    16
-#define IIO_ICMR_FC_CNT_MASK    (0xf << IIO_ICMR_FC_CNT_SHFT)
-
-#define IIO_ICMR_C_CNT_SHFT     4
-#define IIO_ICMR_C_CNT_MASK     (0xf << IIO_ICMR_C_CNT_SHFT)
-
-#define IIO_ICMR_PRECISE        (1UL << 52)
-#define IIO_ICMR_CLR_RPPD       (1UL << 13)
-#define IIO_ICMR_CLR_RQPD       (1UL << 12)
-
-/*
- * IIO PIO Deallocation register field masks : (IIO_IPDR)
- XXX present but not needed in bedrock?  See the manual.
- */
-#define IIO_IPDR_PND    (1 << 4)
-
-/*
- * IIO CRB deallocation register field masks: (IIO_ICDR)
- */
-#define IIO_ICDR_PND    (1 << 4)
-
-/* 
- * IO BTE Length/Status (IIO_IBLS) register bit field definitions
- */
-#define IBLS_BUSY		(0x1 << 20)
-#define IBLS_ERROR_SHFT		16
-#define IBLS_ERROR		(0x1 << IBLS_ERROR_SHFT)
-#define IBLS_LENGTH_MASK	0xffff
-
-/*
- * IO BTE Control/Terminate register (IBCT) register bit field definitions
- */
-#define IBCT_POISON		(0x1 << 8)
-#define IBCT_NOTIFY		(0x1 << 4)
-#define IBCT_ZFIL_MODE		(0x1 << 0)
-
-/*
- * IIO Incoming Error Packet Header (IIO_IIEPH1/IIO_IIEPH2)
- */
-#define IIEPH1_VALID		(1 << 44)
-#define IIEPH1_OVERRUN		(1 << 40)
-#define IIEPH1_ERR_TYPE_SHFT	32
-#define IIEPH1_ERR_TYPE_MASK	0xf
-#define IIEPH1_SOURCE_SHFT	20
-#define IIEPH1_SOURCE_MASK	11
-#define IIEPH1_SUPPL_SHFT	8
-#define IIEPH1_SUPPL_MASK	11
-#define IIEPH1_CMD_SHFT		0
-#define IIEPH1_CMD_MASK		7
-
-#define IIEPH2_TAIL		(1 << 40)
-#define IIEPH2_ADDRESS_SHFT	0
-#define IIEPH2_ADDRESS_MASK	38
-
-#define IIEPH1_ERR_SHORT_REQ	2
-#define IIEPH1_ERR_SHORT_REPLY	3
-#define IIEPH1_ERR_LONG_REQ	4
-#define IIEPH1_ERR_LONG_REPLY	5
-
-/*
- * IO Error Clear register bit field definitions
- */
-#define IECLR_PI1_FWD_INT	(1 << 31)  /* clear PI1_FORWARD_INT in iidsr */
-#define IECLR_PI0_FWD_INT	(1 << 30)  /* clear PI0_FORWARD_INT in iidsr */
-#define IECLR_SPUR_RD_HDR	(1 << 29)  /* clear valid bit in ixss reg */
-#define IECLR_BTE1		(1 << 18)  /* clear bte error 1 */
-#define IECLR_BTE0		(1 << 17)  /* clear bte error 0 */
-#define IECLR_CRAZY		(1 << 16)  /* clear crazy bit in wstat reg */
-#define IECLR_PRB_F		(1 << 15)  /* clear err bit in PRB_F reg */
-#define IECLR_PRB_E		(1 << 14)  /* clear err bit in PRB_E reg */
-#define IECLR_PRB_D		(1 << 13)  /* clear err bit in PRB_D reg */
-#define IECLR_PRB_C		(1 << 12)  /* clear err bit in PRB_C reg */
-#define IECLR_PRB_B		(1 << 11)  /* clear err bit in PRB_B reg */
-#define IECLR_PRB_A		(1 << 10)  /* clear err bit in PRB_A reg */
-#define IECLR_PRB_9		(1 << 9)   /* clear err bit in PRB_9 reg */
-#define IECLR_PRB_8		(1 << 8)   /* clear err bit in PRB_8 reg */
-#define IECLR_PRB_0		(1 << 0)   /* clear err bit in PRB_0 reg */
-
-/*
- * IIO CRB control register Fields: IIO_ICCR 
- */
-#define	IIO_ICCR_PENDING	(0x10000)
-#define	IIO_ICCR_CMD_MASK	(0xFF)
-#define	IIO_ICCR_CMD_SHFT	(7)
-#define	IIO_ICCR_CMD_NOP	(0x0)	/* No Op */
-#define	IIO_ICCR_CMD_WAKE	(0x100) /* Reactivate CRB entry and process */
-#define	IIO_ICCR_CMD_TIMEOUT	(0x200)	/* Make CRB timeout & mark invalid */
-#define	IIO_ICCR_CMD_EJECT	(0x400)	/* Contents of entry written to memory 
-					 * via a WB
-					 */
-#define	IIO_ICCR_CMD_FLUSH	(0x800)
-
-/*
- *
- * CRB Register description.
- *
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- *
- * Many of the fields in CRB are status bits used by hardware
- * for implementation of the protocol. It's very dangerous to
- * mess around with the CRB registers.
- *
- * It's OK to read the CRB registers and try to make sense out of the
- * fields in CRB.
- *
- * Updating CRB requires all activities in Hub IIO to be quiesced.
- * otherwise, a write to CRB could corrupt other CRB entries.
- * CRBs are here only as a back door peek to hub IIO's status.
- * Quiescing implies  no dmas no PIOs
- * either directly from the cpu or from sn0net.
- * this is not something that can be done easily. So, AVOID updating
- * CRBs.
- */
-
-#ifndef __ASSEMBLY__
-
-/*
- * Easy access macros for CRBs, all 4 registers (A-D)
- */
-typedef ii_icrb0_a_u_t icrba_t;	/* what it was called on SN0/hub */
-#define a_error         ii_icrb0_a_fld_s.ia_error
-#define a_ecode         ii_icrb0_a_fld_s.ia_errcode
-#define a_lnetuce       ii_icrb0_a_fld_s.ia_ln_uce
-#define a_mark          ii_icrb0_a_fld_s.ia_mark
-#define a_xerr          ii_icrb0_a_fld_s.ia_xt_err
-#define a_sidn          ii_icrb0_a_fld_s.ia_sidn
-#define a_tnum          ii_icrb0_a_fld_s.ia_tnum
-#define a_addr          ii_icrb0_a_fld_s.ia_addr
-#define a_valid         ii_icrb0_a_fld_s.ia_vld
-#define a_iow           ii_icrb0_a_fld_s.ia_iow
-#define a_regvalue	ii_icrb0_a_regval
-
-typedef ii_icrb0_b_u_t icrbb_t;
-#define b_btenum        ii_icrb0_b_fld_s.ib_bte_num
-#define b_cohtrans      ii_icrb0_b_fld_s.ib_ct
-#define b_xtsize        ii_icrb0_b_fld_s.ib_size
-#define b_source        ii_icrb0_b_fld_s.ib_source
-#define b_imsgtype      ii_icrb0_b_fld_s.ib_imsgtype
-#define b_imsg          ii_icrb0_b_fld_s.ib_imsg
-#define b_initiator     ii_icrb0_b_fld_s.ib_init
-#define b_regvalue	ii_icrb0_b_regval
-
-typedef ii_icrb0_c_u_t icrbc_t;
-#define c_pricnt        ii_icrb0_c_fld_s.ic_pr_cnt
-#define c_pripsc        ii_icrb0_c_fld_s.ic_pr_psc
-#define c_bteop         ii_icrb0_c_fld_s.ic_bte_op
-#define c_bteaddr       ii_icrb0_c_fld_s.ic_pa_be /* ic_pa_be fld has 2 names*/
-#define c_benable       ii_icrb0_c_fld_s.ic_pa_be /* ic_pa_be fld has 2 names*/
-#define c_suppl         ii_icrb0_c_fld_s.ic_suppl
-#define c_barrop        ii_icrb0_c_fld_s.ic_bo
-#define c_doresp        ii_icrb0_c_fld_s.ic_resprqd
-#define c_gbr           ii_icrb0_c_fld_s.ic_gbr
-#define c_regvalue	ii_icrb0_c_regval
-
-typedef ii_icrb0_d_u_t icrbd_t;
-#define icrbd_ctxtvld   ii_icrb0_d_fld_s.id_cvld
-#define icrbd_toutvld   ii_icrb0_d_fld_s.id_tvld
-#define icrbd_context   ii_icrb0_d_fld_s.id_context
-#define d_regvalue	ii_icrb0_d_regval
-
-#endif /* __ASSEMBLY__ */
-
-/* Number of widgets supported by hub */
-#define HUB_NUM_WIDGET          9
-#define HUB_WIDGET_ID_MIN       0x8
-#define HUB_WIDGET_ID_MAX       0xf
-
-#define HUB_WIDGET_PART_NUM     0xc110
-#define MAX_HUBS_PER_XBOW       2
-
-#ifndef __ASSEMBLY__
-/* A few more #defines for backwards compatibility */
-#define iprb_t          ii_iprb0_u_t
-#define iprb_regval     ii_iprb0_regval
-#define iprb_mult_err	ii_iprb0_fld_s.i_mult_err
-#define iprb_spur_rd	ii_iprb0_fld_s.i_spur_rd
-#define iprb_spur_wr	ii_iprb0_fld_s.i_spur_wr
-#define iprb_rd_to	ii_iprb0_fld_s.i_rd_to
-#define iprb_ovflow     ii_iprb0_fld_s.i_of_cnt
-#define iprb_error      ii_iprb0_fld_s.i_error
-#define iprb_ff         ii_iprb0_fld_s.i_f
-#define iprb_mode       ii_iprb0_fld_s.i_m
-#define iprb_bnakctr    ii_iprb0_fld_s.i_nb
-#define iprb_anakctr    ii_iprb0_fld_s.i_na
-#define iprb_xtalkctr   ii_iprb0_fld_s.i_c
-#endif
-
-#define LNK_STAT_WORKING        0x2
-
-#define IIO_WSTAT_ECRAZY        (1ULL << 32)    /* Hub gone crazy */
-#define IIO_WSTAT_TXRETRY       (1ULL << 9)     /* Hub Tx Retry timeout */
-#define IIO_WSTAT_TXRETRY_MASK  (0x7F)   /* should be 0xFF?? */
-#define IIO_WSTAT_TXRETRY_SHFT  (16)
-#define IIO_WSTAT_TXRETRY_CNT(w)        (((w) >> IIO_WSTAT_TXRETRY_SHFT) & \
-                                          IIO_WSTAT_TXRETRY_MASK)
-
-/* Number of II perf. counters we can multiplex at once */
-
-#define IO_PERF_SETS	32
-
-#if __KERNEL__
-#ifndef __ASSEMBLY__
-/* XXX moved over from SN/SN0/hubio.h -- each should be checked for SN1 */
-#include <asm/sn/alenlist.h>
-#include <asm/sn/dmamap.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/xtalk/xtalk.h>
-
-/* Bit for the widget in inbound access register */
-#define IIO_IIWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
-/* Bit for the widget in outbound access register */
-#define IIO_IOWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
-
-/* NOTE: The following define assumes that we are going to get
- * widget numbers from 8 thru F and the device numbers within
- * widget from 0 thru 7.
- */
-#define IIO_IIDEM_WIDGETDEV_MASK(w, d)  ((uint64_t)(1ULL << (8 * ((w) - 8) + (d))))
-
-/* IO Interrupt Destination Register */
-#define IIO_IIDSR_SENT_SHIFT    28
-#define IIO_IIDSR_SENT_MASK     0x10000000
-#define IIO_IIDSR_ENB_SHIFT     24
-#define IIO_IIDSR_ENB_MASK      0x01000000
-#define IIO_IIDSR_NODE_SHIFT    8
-#define IIO_IIDSR_NODE_MASK     0x0000ff00
-#define IIO_IIDSR_PI_ID_SHIFT   8
-#define IIO_IIDSR_PI_ID_MASK    0x00000010
-#define IIO_IIDSR_LVL_SHIFT     0
-#define IIO_IIDSR_LVL_MASK      0x0000007f
-
-/* Xtalk timeout threshhold register (IIO_IXTT) */
-#define IXTT_RRSP_TO_SHFT	55	   /* read response timeout */
-#define IXTT_RRSP_TO_MASK	(0x1FULL << IXTT_RRSP_TO_SHFT)
-#define IXTT_RRSP_PS_SHFT	32	   /* read responsed TO prescalar */
-#define IXTT_RRSP_PS_MASK	(0x7FFFFFULL << IXTT_RRSP_PS_SHFT)
-#define IXTT_TAIL_TO_SHFT	0	   /* tail timeout counter threshold */
-#define IXTT_TAIL_TO_MASK	(0x3FFFFFFULL << IXTT_TAIL_TO_SHFT)
-
-/*
- * The IO LLP control status register and widget control register
- */
-
-#ifdef LITTLE_ENDIAN
-
-typedef union hubii_wcr_u {
-        uint64_t      wcr_reg_value;
-        struct {
-	  uint64_t	wcr_widget_id:   4,     /* LLP crossbar credit */
-			wcr_tag_mode:	 1,	/* Tag mode */
-			wcr_rsvd1:	 8,	/* Reserved */
-			wcr_xbar_crd:	 3,	/* LLP crossbar credit */
-			wcr_f_bad_pkt:	 1,	/* Force bad llp pkt enable */
-			wcr_dir_con:	 1,	/* widget direct connect */
-			wcr_e_thresh:	 5,	/* elasticity threshold */
-			wcr_rsvd:	41;	/* unused */
-        } wcr_fields_s;
-} hubii_wcr_t;
-
-#else
-
-typedef union hubii_wcr_u {
-	uint64_t	wcr_reg_value;
-	struct {
-	    uint64_t	wcr_rsvd:	41,	/* unused */
-			wcr_e_thresh:	 5,	/* elasticity threshold */
-			wcr_dir_con:	 1,	/* widget direct connect */
-			wcr_f_bad_pkt:	 1,	/* Force bad llp pkt enable */
-			wcr_xbar_crd:	 3,	/* LLP crossbar credit */
-			wcr_rsvd1:	 8,	/* Reserved */
-			wcr_tag_mode:	 1,	/* Tag mode */
-			wcr_widget_id:	 4;	/* LLP crossbar credit */
-	} wcr_fields_s;
-} hubii_wcr_t;
-
-#endif
-
-#define iwcr_dir_con    wcr_fields_s.wcr_dir_con
-
-/* The structures below are defined to extract and modify the ii
-performance registers */
-
-/* io_perf_sel allows the caller to specify what tests will be
-   performed */
-#ifdef LITTLE_ENDIAN
-
-typedef union io_perf_sel {
-        uint64_t perf_sel_reg;
-        struct {
-               uint64_t	perf_ippr0 :  4,
-				perf_ippr1 :  4,
-				perf_icct  :  8,
-				perf_rsvd  : 48;
-        } perf_sel_bits;
-} io_perf_sel_t;
-
-#else
-
-typedef union io_perf_sel {
-	uint64_t perf_sel_reg;
-	struct {
-		uint64_t	perf_rsvd  : 48,
-				perf_icct  :  8,
-				perf_ippr1 :  4,
-				perf_ippr0 :  4;
-	} perf_sel_bits;
-} io_perf_sel_t;
-
-#endif
-
-/* io_perf_cnt is to extract the count from the hub registers. Due to
-   hardware problems there is only one counter, not two. */
-
-#ifdef LITTLE_ENDIAN
-
-typedef union io_perf_cnt {
-        uint64_t      perf_cnt;
-        struct {
-               uint64_t	perf_cnt   : 20,
-				perf_rsvd2 : 12,
-				perf_rsvd1 : 32;
-        } perf_cnt_bits;
-
-} io_perf_cnt_t;
-
-#else
-
-typedef union io_perf_cnt {
-	uint64_t	perf_cnt;
-	struct {
-		uint64_t	perf_rsvd1 : 32,
-				perf_rsvd2 : 12,
-				perf_cnt   : 20;
-	} perf_cnt_bits;
-
-} io_perf_cnt_t;
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-typedef union iprte_a {
-	bdrkreg_t	entry;
-	struct {
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t       i_vld                     :      1;
-	} iprte_fields;
-} iprte_a_t;
-
-#else
-
-typedef union iprte_a {
-	bdrkreg_t	entry;
-	struct {
-		bdrkreg_t	i_vld			  :	 1;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-	} iprte_fields;
-} iprte_a_t;
-
-#endif
-
-/* PIO MANAGEMENT */
-typedef struct hub_piomap_s *hub_piomap_t;
-
-extern hub_piomap_t
-hub_piomap_alloc(devfs_handle_t dev,      /* set up mapping for this device */
-                device_desc_t dev_desc, /* device descriptor */
-                iopaddr_t xtalk_addr,   /* map for this xtalk_addr range */
-                size_t byte_count,
-                size_t byte_count_max,  /* maximum size of a mapping */
-                unsigned flags);                /* defined in sys/pio.h */
-
-extern void hub_piomap_free(hub_piomap_t hub_piomap);
-
-extern caddr_t
-hub_piomap_addr(hub_piomap_t hub_piomap,        /* mapping resources */
-                iopaddr_t xtalk_addr,           /* map for this xtalk addr */
-                size_t byte_count);             /* map this many bytes */
-
-extern void
-hub_piomap_done(hub_piomap_t hub_piomap);
-
-extern caddr_t
-hub_piotrans_addr(      devfs_handle_t dev,       /* translate to this device */
-                        device_desc_t dev_desc, /* device descriptor */
-                        iopaddr_t xtalk_addr,   /* Crosstalk address */
-                        size_t byte_count,      /* map this many bytes */
-                        unsigned flags);        /* (currently unused) */
-
-/* DMA MANAGEMENT */
-typedef struct hub_dmamap_s *hub_dmamap_t;
-
-extern hub_dmamap_t
-hub_dmamap_alloc(       devfs_handle_t dev,       /* set up mappings for dev */
-                        device_desc_t dev_desc, /* device descriptor */
-                        size_t byte_count_max,  /* max size of a mapping */
-                        unsigned flags);        /* defined in dma.h */
-
-extern void
-hub_dmamap_free(hub_dmamap_t dmamap);
-
-extern iopaddr_t
-hub_dmamap_addr(        hub_dmamap_t dmamap,    /* use mapping resources */
-                        paddr_t paddr,          /* map for this address */
-                        size_t byte_count);     /* map this many bytes */
-
-extern alenlist_t
-hub_dmamap_list(        hub_dmamap_t dmamap,    /* use mapping resources */
-                        alenlist_t alenlist,    /* map this Addr/Length List */
-                        unsigned flags);
-
-extern void
-hub_dmamap_done(        hub_dmamap_t dmamap);   /* done w/ mapping resources */
-
-extern iopaddr_t
-hub_dmatrans_addr(      devfs_handle_t dev,       /* translate for this device */
-                        device_desc_t dev_desc, /* device descriptor */
-                        paddr_t paddr,          /* system physical address */
-                        size_t byte_count,      /* length */
-                        unsigned flags);                /* defined in dma.h */
-
-extern alenlist_t
-hub_dmatrans_list(      devfs_handle_t dev,       /* translate for this device */
-                        device_desc_t dev_desc, /* device descriptor */
-                        alenlist_t palenlist,   /* system addr/length list */
-                        unsigned flags);                /* defined in dma.h */
-
-extern void
-hub_dmamap_drain(       hub_dmamap_t map);
-
-extern void
-hub_dmaaddr_drain(      devfs_handle_t vhdl,
-                        paddr_t addr,
-                        size_t bytes);
-
-extern void
-hub_dmalist_drain(      devfs_handle_t vhdl,
-                        alenlist_t list);
-
-
-/* INTERRUPT MANAGEMENT */
-typedef struct hub_intr_s *hub_intr_t;
-
-extern hub_intr_t
-hub_intr_alloc( devfs_handle_t dev,               /* which device */
-                device_desc_t dev_desc,         /* device descriptor */
-                devfs_handle_t owner_dev);        /* owner of this interrupt */
-
-extern hub_intr_t
-hub_intr_alloc_nothd(devfs_handle_t dev,          /* which device */
-                device_desc_t dev_desc,         /* device descriptor */
-                devfs_handle_t owner_dev);        /* owner of this interrupt */
-
-extern void
-hub_intr_free(hub_intr_t intr_hdl);
-
-extern int
-hub_intr_connect(       hub_intr_t intr_hdl,    /* xtalk intr resource hndl */
-                        xtalk_intr_setfunc_t setfunc,
-                                                /* func to set intr hw */
-                        void *setfunc_arg);     /* arg to setfunc */
-
-extern void
-hub_intr_disconnect(hub_intr_t intr_hdl);
-
-extern devfs_handle_t
-hub_intr_cpu_get(hub_intr_t intr_hdl);
-
-/* CONFIGURATION MANAGEMENT */
-
-extern void
-hub_provider_startup(devfs_handle_t hub);
-
-extern void
-hub_provider_shutdown(devfs_handle_t hub);
-
-#define HUB_PIO_CONVEYOR        0x1     /* PIO in conveyor belt mode */
-#define HUB_PIO_FIRE_N_FORGET   0x2     /* PIO in fire-and-forget mode */
-
-/* Flags that make sense to hub_widget_flags_set */
-#define HUB_WIDGET_FLAGS        (                               \
-				 HUB_PIO_CONVEYOR       |       \
-				 HUB_PIO_FIRE_N_FORGET          \
-				)
-
-
-typedef int     hub_widget_flags_t;
-
-/* Set the PIO mode for a widget.  These two functions perform the
- * same operation, but hub_device_flags_set() takes a hardware graph
- * vertex while hub_widget_flags_set() takes a nasid and widget
- * number.  In most cases, hub_device_flags_set() should be used.
- */
-extern int      hub_widget_flags_set(nasid_t            nasid,
-                                     xwidgetnum_t       widget_num,
-                                     hub_widget_flags_t flags);
-
-/* Depending on the flags set take the appropriate actions */
-extern int      hub_device_flags_set(devfs_handle_t       widget_dev,
-                                     hub_widget_flags_t flags);
-                                                    
-
-/* Error Handling. */
-extern int hub_ioerror_handler(devfs_handle_t, int, int, struct io_error_s *);
-extern int kl_ioerror_handler(cnodeid_t, cnodeid_t, cpuid_t,
-                              int, paddr_t, caddr_t, ioerror_mode_t);
-extern void hub_widget_reset(devfs_handle_t, xwidgetnum_t);
-extern int hub_error_devenable(devfs_handle_t, int, int);
-extern void hub_widgetdev_enable(devfs_handle_t, int);
-extern void hub_widgetdev_shutdown(devfs_handle_t, int);
-extern int  hub_dma_enabled(devfs_handle_t);
-
-#endif /* __ASSEMBLY__ */
-#endif /* _KERNEL */
-#endif  /* _ASM_IA64_SN_SN1_HUBIO_NEXT_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hublb.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hublb.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hublb.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hublb.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,1607 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-
-#ifndef _ASM_IA64_SN_SN1_HUBLB_H
-#define _ASM_IA64_SN_SN1_HUBLB_H
-
-
-#define    LB_REV_ID                 0x00600000    /*
-                                                    * Bedrock Revision
-                                                    * and ID
-                                                    */
-
-
-
-#define    LB_CPU_PERMISSION         0x00604000    /*
-                                                    * CPU PIO access
-                                                    * permission bits
-                                                    */
-
-
-
-#define    LB_CPU_PERM_OVRRD         0x00604008    /*
-                                                    * CPU PIO access
-                                                    * permission bit
-                                                    * override
-                                                    */
-
-
-
-#define    LB_IO_PERMISSION          0x00604010    /*
-                                                    * IO PIO access
-                                                    * permission bits
-                                                    */
-
-
-
-#define    LB_SOFT_RESET             0x00604018    /*
-                                                    * Soft reset the
-                                                    * Bedrock chip
-                                                    */
-
-
-
-#define    LB_REGION_PRESENT         0x00604020    /*
-                                                    * Regions Present for
-                                                    * Invalidates
-                                                    */
-
-
-
-#define    LB_NODES_ABSENT           0x00604028    /*
-                                                    * Nodes Absent for
-                                                    * Invalidates
-                                                    */
-
-
-
-#define    LB_MICROLAN_CTL           0x00604030    /*
-                                                    * Microlan Control
-                                                    * (NIC)
-                                                    */
-
-
-
-#define    LB_ERROR_BITS             0x00604040    /*
-                                                    * Local Block error
-                                                    * bits
-                                                    */
-
-
-
-#define    LB_ERROR_MASK_CLR         0x00604048    /*
-                                                    * Bit mask write to
-                                                    * clear error bits
-                                                    */
-
-
-
-#define    LB_ERROR_HDR1             0x00604050    /*
-                                                    * Source, Suppl and
-                                                    * Cmd fields
-                                                    */
-
-
-
-#define    LB_ERROR_HDR2             0x00604058    /*
-                                                    * Address field from
-                                                    * first error
-                                                    */
-
-
-
-#define    LB_ERROR_DATA             0x00604060    /*
-                                                    * Data flit (if any)
-                                                    * from first error
-                                                    */
-
-
-
-#define    LB_DEBUG_SELECT           0x00604100    /*
-                                                    * Choice of debug
-                                                    * signals from chip
-                                                    */
-
-
-
-#define    LB_DEBUG_PINS             0x00604108    /*
-                                                    * Value on the chip's
-                                                    * debug pins
-                                                    */
-
-
-
-#define    LB_RT_LOCAL_CTRL          0x00604200    /*
-                                                    * Local generation of
-                                                    * real-time clock
-                                                    */
-
-
-
-#define    LB_RT_FILTER_CTRL         0x00604208    /*
-                                                    * Control of
-                                                    * filtering of global
-                                                    * clock
-                                                    */
-
-
-
-#define    LB_SCRATCH_REG0           0x00608000    /* Scratch Register 0     */
-
-
-
-#define    LB_SCRATCH_REG1           0x00608008    /* Scratch Register 1     */
-
-
-
-#define    LB_SCRATCH_REG2           0x00608010    /* Scratch Register 2     */
-
-
-
-#define    LB_SCRATCH_REG3           0x00608018    /* Scratch Register 3     */
-
-
-
-#define    LB_SCRATCH_REG4           0x00608020    /* Scratch Register 4     */
-
-
-
-#define    LB_SCRATCH_REG0_WZ        0x00608040    /*
-                                                    * Scratch Register 0
-                                                    * (WZ alias)
-                                                    */
-
-
-
-#define    LB_SCRATCH_REG1_WZ        0x00608048    /*
-                                                    * Scratch Register 1
-                                                    * (WZ alias)
-                                                    */
-
-
-
-#define    LB_SCRATCH_REG2_WZ        0x00608050    /*
-                                                    * Scratch Register 2
-                                                    * (WZ alias)
-                                                    */
-
-
-
-#define    LB_SCRATCH_REG3_RZ        0x00608058    /*
-                                                    * Scratch Register 3
-                                                    * (RZ alias)
-                                                    */
-
-
-
-#define    LB_SCRATCH_REG4_RZ        0x00608060    /*
-                                                    * Scratch Register 4
-                                                    * (RZ alias)
-                                                    */
-
-
-
-#define    LB_VECTOR_PARMS           0x0060C000    /*
-                                                    * Vector PIO
-                                                    * parameters
-                                                    */
-
-
-
-#define    LB_VECTOR_ROUTE           0x0060C008    /*
-                                                    * Vector PIO Vector
-                                                    * Route
-                                                    */
-
-
-
-#define    LB_VECTOR_DATA            0x0060C010    /*
-                                                    * Vector PIO Write
-                                                    * Data
-                                                    */
-
-
-
-#define    LB_VECTOR_STATUS          0x0060C020    /*
-                                                    * Vector PIO Return
-                                                    * Status
-                                                    */
-
-
-
-#define    LB_VECTOR_RETURN          0x0060C028    /*
-                                                    * Vector PIO Return
-                                                    * Route
-                                                    */
-
-
-
-#define    LB_VECTOR_READ_DATA       0x0060C030    /*
-                                                    * Vector PIO Read
-                                                    * Data
-                                                    */
-
-
-
-#define    LB_VECTOR_STATUS_CLEAR    0x0060C038    /*
-                                                    * Clear Vector PIO
-                                                    * Return Status
-                                                    */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains information that allows         *
- * exploratory software to probe for chip type. This is also the        *
- * register that sets this node's ID and the size of each region        *
- * (which affects the maximum possible system size). IBM assigns the    *
- * values for the REVISION, PART_NUMBER and MANUFACTURER fields, in     *
- * accordance with the IEEE 1149.1 standard; SGI is not at liberty to   *
- * unilaterally change the values of these fields.                      *
- *  .                                                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_rev_id_u {
-	bdrkreg_t	lb_rev_id_regval;
-	struct  {
-		bdrkreg_t	ri_reserved_2             :	 1;
-		bdrkreg_t       ri_manufacturer           :     11;
-		bdrkreg_t       ri_part_number            :     16;
-		bdrkreg_t       ri_revision               :      4;
-		bdrkreg_t       ri_node_id                :      8;
-		bdrkreg_t       ri_reserved_1             :      6;
-		bdrkreg_t       ri_region_size            :      2;
-		bdrkreg_t       ri_reserved               :     16;
-	} lb_rev_id_fld_s;
-} lb_rev_id_u_t;
-
-#else
-
-typedef union lb_rev_id_u {
-        bdrkreg_t       lb_rev_id_regval;
-	struct	{
-		bdrkreg_t	ri_reserved		  :	16;
-		bdrkreg_t	ri_region_size		  :	 2;
-		bdrkreg_t	ri_reserved_1		  :	 6;
-		bdrkreg_t	ri_node_id		  :	 8;
-		bdrkreg_t	ri_revision		  :	 4;
-		bdrkreg_t	ri_part_number		  :	16;
-		bdrkreg_t	ri_manufacturer		  :	11;
-		bdrkreg_t	ri_reserved_2		  :	 1;
-	} lb_rev_id_fld_s;
-} lb_rev_id_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the PI-access-rights bit-vector for the      *
- * LB, NI, XB and MD portions of the Bedrock local register space. If   *
- * a bit in the bit-vector is set, the region corresponding to that     *
- * bit has read/write permission on the LB, NI, XB and MD local         *
- * registers. If the bit is clear, that region has no write access to   *
- * the local registers and no read access if the read will cause any    *
- * state change. If a write or a read with side effects is attempted    *
- * by a PI in a region for which access is restricted, the LB will      *
- * not perform the operation and will send back a reply which           *
- * indicates an error.                                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_cpu_permission_u {
-	bdrkreg_t	lb_cpu_permission_regval;
-	struct  {
-		bdrkreg_t	cp_cpu_access             :	64;
-	} lb_cpu_permission_fld_s;
-} lb_cpu_permission_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register of the 64-bit value "SGIrules" will        *
- * cause the bit in the LB_CPU_PROTECT register corresponding to the    *
- * region of the requester to be set.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_cpu_perm_ovrrd_u {
-	bdrkreg_t	lb_cpu_perm_ovrrd_regval;
-	struct  {
-		bdrkreg_t	cpo_cpu_perm_ovr          :	64;
-	} lb_cpu_perm_ovrrd_fld_s;
-} lb_cpu_perm_ovrrd_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the II-access-rights bit-vector for the      *
- * LB, NI, XB and MD portions of the Bedrock local register space. If   *
- * a bit in the bit-vector is set, the region corresponding to that     *
- * bit has read/write permission on the LB, NI, XB and MD local         *
- * registers. If the bit is clear, then that region has no write        *
- * access to the local registers and no read access if the read         *
- * results in any state change. If a write or a read with side          *
- * effects is attempted by an II in a region for which access is        *
- * restricted, the LB will not perform the operation and will send      *
- * back a reply which indicates an error.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_io_permission_u {
-	bdrkreg_t	lb_io_permission_regval;
-	struct  {
-		bdrkreg_t	ip_io_permission          :	64;
-	} lb_io_permission_fld_s;
-} lb_io_permission_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this bit resets the Bedrock chip with a soft reset.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_soft_reset_u {
-	bdrkreg_t	lb_soft_reset_regval;
-	struct  {
-		bdrkreg_t	sr_soft_reset             :	 1;
-		bdrkreg_t	sr_reserved		  :	63;
-	} lb_soft_reset_fld_s;
-} lb_soft_reset_u_t;
-
-#else
-
-typedef union lb_soft_reset_u {
-	bdrkreg_t	lb_soft_reset_regval;
-	struct	{
-		bdrkreg_t	sr_reserved		  :	63;
-		bdrkreg_t	sr_soft_reset		  :	 1;
-	} lb_soft_reset_fld_s;
-} lb_soft_reset_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register indicates which regions are present and capable of    *
- * receiving an invalidate (INVAL) request. The LB samples this         *
- * register at the start of processing each LINVAL. When an LINVAL      *
- * indicates that a particular PI unit might hold a shared copy of a    *
- * cache block but this PI is in a region which is not present (i.e.,   *
- * its bit in LB_REGION_PRESENT is clear), then the LB sends an IVACK   *
- * reply packet on behalf of this PI. The REGION_SIZE field in the      *
- * LB_REV_ID register determines the number of nodes per region (and    *
- * hence, the number of PI units which share a common bit in the        *
- * LB_REGION_PRESENT register).                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_region_present_u {
-	bdrkreg_t	lb_region_present_regval;
-	struct  {
-		bdrkreg_t	rp_present_bits           :	64;
-	} lb_region_present_fld_s;
-} lb_region_present_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register indicates which nodes are absent and     *
- * not capable of receiving an invalidate (INVAL) request. The LB       *
- * samples this register at the start of processing each LINVAL. When   *
- * an LINVAL indicates that a particular PI unit might hold a shared    *
- * copy of a cache block but this PI unit's node is not present         *
- * (i.e., its node ID is listed in the LB_NODES_ABSENT register),       *
- * then the LB sends an IVACK reply packet on behalf of this PI.        *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_nodes_absent_u {
-	bdrkreg_t	lb_nodes_absent_regval;
-	struct  {
-		bdrkreg_t	na_node_0                 :	 8;
-		bdrkreg_t       na_reserved_3             :      7;
-		bdrkreg_t       na_node_0_valid           :      1;
-		bdrkreg_t       na_node_1                 :      8;
-		bdrkreg_t       na_reserved_2             :      7;
-		bdrkreg_t       na_node_1_valid           :      1;
-		bdrkreg_t       na_node_2                 :      8;
-		bdrkreg_t       na_reserved_1             :      7;
-		bdrkreg_t       na_node_2_valid           :      1;
-		bdrkreg_t       na_node_3                 :      8;
-		bdrkreg_t       na_reserved               :      7;
-		bdrkreg_t       na_node_3_valid           :      1;
-	} lb_nodes_absent_fld_s;
-} lb_nodes_absent_u_t;
-
-#else
-
-typedef union lb_nodes_absent_u {
-	bdrkreg_t	lb_nodes_absent_regval;
-	struct	{
-		bdrkreg_t	na_node_3_valid		  :	 1;
-		bdrkreg_t	na_reserved		  :	 7;
-		bdrkreg_t	na_node_3		  :	 8;
-		bdrkreg_t	na_node_2_valid		  :	 1;
-		bdrkreg_t	na_reserved_1		  :	 7;
-		bdrkreg_t	na_node_2		  :	 8;
-		bdrkreg_t	na_node_1_valid		  :	 1;
-		bdrkreg_t	na_reserved_2		  :	 7;
-		bdrkreg_t	na_node_1		  :	 8;
-		bdrkreg_t	na_node_0_valid		  :	 1;
-		bdrkreg_t	na_reserved_3		  :	 7;
-		bdrkreg_t	na_node_0		  :	 8;
-	} lb_nodes_absent_fld_s;
-} lb_nodes_absent_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register provides access to the Number-In-a-Can add-only       *
- * serial PROM that is used to store node board serial number and       *
- * configuration information. (Refer to NIC datasheet Dallas 1990A      *
- * that is viewable at                                                  *
- * URL::http://www.dalsemi.com/DocControl/PDFs/pdfindex.html). Data     *
- * comes from this interface LSB first.                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_microlan_ctl_u {
-	bdrkreg_t	lb_microlan_ctl_regval;
-	struct  {
-		bdrkreg_t	mc_rd_data                :	 1;
-		bdrkreg_t       mc_done                   :      1;
-		bdrkreg_t       mc_sample                 :      8;
-		bdrkreg_t       mc_pulse                  :     10;
-		bdrkreg_t       mc_clkdiv_phi0            :      7;
-		bdrkreg_t       mc_clkdiv_phi1            :      7;
-		bdrkreg_t       mc_reserved               :     30;
-	} lb_microlan_ctl_fld_s;
-} lb_microlan_ctl_u_t;
-
-#else
-
-typedef union lb_microlan_ctl_u {
-        bdrkreg_t       lb_microlan_ctl_regval;
-        struct  {
-                bdrkreg_t       mc_reserved               :     30;
-                bdrkreg_t       mc_clkdiv_phi1            :      7;
-                bdrkreg_t       mc_clkdiv_phi0            :      7;
-                bdrkreg_t       mc_pulse                  :     10;
-                bdrkreg_t       mc_sample                 :      8;
-                bdrkreg_t       mc_done                   :      1;
-                bdrkreg_t       mc_rd_data                :      1;
-        } lb_microlan_ctl_fld_s;
-} lb_microlan_ctl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains the LB error status bits.       *
- * Whenever a particular type of error occurs, the LB sets its bit in   *
- * this register so that software will be aware that such an event      *
- * has happened. Reads from this register are non-destructive and the   *
- * contents of this register remain intact across reset operations.     *
- * Whenever any of these bits is set, the LB will assert its            *
- * interrupt request output signals that go to the PI units.            *
- *  Software can simulate the occurrence of an error by first writing   *
- * appropriate values into the LB_ERROR_HDR1, LB_ERROR_HDR2 and         *
- * LB_ERROR_DATA registers, and then writing to the LB_ERROR_BITS       *
- * register to set the error bits in a particular way. Setting one or   *
- * more error bits will cause the LB to interrupt a processor and       *
- * invoke error-handling software.                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_error_bits_u {
-	bdrkreg_t	lb_error_bits_regval;
-	struct  {
-		bdrkreg_t	eb_rq_bad_cmd             :	 1;
-		bdrkreg_t       eb_rp_bad_cmd             :      1;
-		bdrkreg_t       eb_rq_short               :      1;
-		bdrkreg_t       eb_rp_short               :      1;
-		bdrkreg_t       eb_rq_long                :      1;
-		bdrkreg_t       eb_rp_long                :      1;
-		bdrkreg_t       eb_rq_bad_data            :      1;
-		bdrkreg_t       eb_rp_bad_data            :      1;
-		bdrkreg_t       eb_rq_bad_addr            :      1;
-		bdrkreg_t       eb_rq_bad_linval          :      1;
-		bdrkreg_t       eb_gclk_drop              :      1;
-		bdrkreg_t       eb_reserved               :     53;
-	} lb_error_bits_fld_s;
-} lb_error_bits_u_t;
-
-#else
-
-typedef union lb_error_bits_u {
-	bdrkreg_t	lb_error_bits_regval;
-	struct	{
-		bdrkreg_t	eb_reserved		  :	53;
-		bdrkreg_t	eb_gclk_drop		  :	 1;
-		bdrkreg_t	eb_rq_bad_linval	  :	 1;
-		bdrkreg_t	eb_rq_bad_addr		  :	 1;
-		bdrkreg_t	eb_rp_bad_data		  :	 1;
-		bdrkreg_t	eb_rq_bad_data		  :	 1;
-		bdrkreg_t	eb_rp_long		  :	 1;
-		bdrkreg_t	eb_rq_long		  :	 1;
-		bdrkreg_t	eb_rp_short		  :	 1;
-		bdrkreg_t	eb_rq_short		  :	 1;
-		bdrkreg_t	eb_rp_bad_cmd		  :	 1;
-		bdrkreg_t	eb_rq_bad_cmd		  :	 1;
-	} lb_error_bits_fld_s;
-} lb_error_bits_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register lets software clear some of the bits in the           *
- * LB_ERROR_BITS register without affecting other bits.  Essentially,   *
- * it provides bit mask functionality. When software writes to the      *
- * LB_ERROR_MASK_CLR register, the bits which are set in the data       *
- * value indicate which bits are to be cleared in LB_ERROR_BITS. If a   *
- * bit is clear in the data value written to the LB_ERROR_MASK_CLR      *
- * register, then its corresponding bit in the LB_ERROR_BITS register   *
- * is not affected. Hence, software can atomically clear any subset     *
- * of the error bits in the LB_ERROR_BITS register.                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_error_mask_clr_u {
-	bdrkreg_t	lb_error_mask_clr_regval;
-	struct  {
-		bdrkreg_t	emc_clr_rq_bad_cmd        :	 1;
-		bdrkreg_t       emc_clr_rp_bad_cmd        :      1;
-		bdrkreg_t       emc_clr_rq_short          :      1;
-		bdrkreg_t       emc_clr_rp_short          :      1;
-		bdrkreg_t       emc_clr_rq_long           :      1;
-		bdrkreg_t       emc_clr_rp_long           :      1;
-		bdrkreg_t       emc_clr_rq_bad_data       :      1;
-		bdrkreg_t       emc_clr_rp_bad_data       :      1;
-		bdrkreg_t       emc_clr_rq_bad_addr       :      1;
-		bdrkreg_t       emc_clr_rq_bad_linval     :      1;
-		bdrkreg_t       emc_clr_gclk_drop         :      1;
-		bdrkreg_t       emc_reserved              :     53;
-	} lb_error_mask_clr_fld_s;
-} lb_error_mask_clr_u_t;
-
-#else
-
-typedef union lb_error_mask_clr_u {
-	bdrkreg_t	lb_error_mask_clr_regval;
-	struct	{
-		bdrkreg_t	emc_reserved		  :	53;
-		bdrkreg_t	emc_clr_gclk_drop	  :	 1;
-		bdrkreg_t	emc_clr_rq_bad_linval	  :	 1;
-		bdrkreg_t	emc_clr_rq_bad_addr	  :	 1;
-		bdrkreg_t	emc_clr_rp_bad_data	  :	 1;
-		bdrkreg_t	emc_clr_rq_bad_data	  :	 1;
-		bdrkreg_t	emc_clr_rp_long		  :	 1;
-		bdrkreg_t	emc_clr_rq_long		  :	 1;
-		bdrkreg_t	emc_clr_rp_short	  :	 1;
-		bdrkreg_t	emc_clr_rq_short	  :	 1;
-		bdrkreg_t	emc_clr_rp_bad_cmd	  :	 1;
-		bdrkreg_t	emc_clr_rq_bad_cmd	  :	 1;
-	} lb_error_mask_clr_fld_s;
-} lb_error_mask_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  If the LB detects an error when VALID==0 in the LB_ERROR_HDR1       *
- * register, then it saves the contents of the offending packet's       *
- * header flit in the LB_ERROR_HDR1 and LB_ERROR_HDR2 registers, sets   *
- * the VALID bit in LB_ERROR_HDR1 and clears the OVERRUN bit in         *
- * LB_ERROR_HDR1 (and it will also set the corresponding bit in the     *
- * LB_ERROR_BITS register). The ERR_TYPE field indicates specifically   *
- * what kind of error occurred.  Its encoding corresponds to the bit    *
- * positions in the LB_ERROR_BITS register (e.g., ERR_TYPE==5           *
- * indicates a RP_LONG error).  If an error (of any type except         *
- * GCLK_DROP) subsequently happens while VALID==1, then the LB sets     *
- * the OVERRUN bit in LB_ERROR_HDR1. This register is not relevant      *
- * when a GCLK_DROP error occurs; the LB does not even attempt to       *
- * change the ERR_TYPE, VALID or OVERRUN field when a GCLK_DROP error   *
- * happens.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_error_hdr1_u {
-	bdrkreg_t	lb_error_hdr1_regval;
-	struct  {
-		bdrkreg_t	eh_command                :	 7;
-		bdrkreg_t       eh_reserved_5             :      1;
-		bdrkreg_t       eh_suppl                  :     11;
-		bdrkreg_t       eh_reserved_4             :      1;
-		bdrkreg_t       eh_source                 :     11;
-		bdrkreg_t       eh_reserved_3             :      1;
-		bdrkreg_t       eh_err_type               :      4;
-		bdrkreg_t       eh_reserved_2             :      4;
-		bdrkreg_t       eh_overrun                :      1;
-		bdrkreg_t       eh_reserved_1             :      3;
-		bdrkreg_t       eh_valid                  :      1;
-		bdrkreg_t       eh_reserved               :     19;
-	} lb_error_hdr1_fld_s;
-} lb_error_hdr1_u_t;
-
-#else
-
-typedef union lb_error_hdr1_u {
-	bdrkreg_t	lb_error_hdr1_regval;
-	struct	{
-		bdrkreg_t	eh_reserved		  :	19;
-		bdrkreg_t	eh_valid		  :	 1;
-		bdrkreg_t	eh_reserved_1		  :	 3;
-		bdrkreg_t	eh_overrun		  :	 1;
-		bdrkreg_t	eh_reserved_2		  :	 4;
-		bdrkreg_t	eh_err_type		  :	 4;
-		bdrkreg_t	eh_reserved_3		  :	 1;
-		bdrkreg_t	eh_source		  :	11;
-		bdrkreg_t	eh_reserved_4		  :	 1;
-		bdrkreg_t	eh_suppl		  :	11;
-		bdrkreg_t	eh_reserved_5		  :	 1;
-		bdrkreg_t	eh_command		  :	 7;
-	} lb_error_hdr1_fld_s;
-} lb_error_hdr1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contents of the Address field from header flit of first packet      *
- * that causes an error. This register is not relevant when a           *
- * GCLK_DROP error occurs.                                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_error_hdr2_u {
-	bdrkreg_t	lb_error_hdr2_regval;
-	struct  {
-		bdrkreg_t	eh_address                :	38;
-		bdrkreg_t       eh_reserved               :     26;
-	} lb_error_hdr2_fld_s;
-} lb_error_hdr2_u_t;
-
-#else
-
-typedef union lb_error_hdr2_u {
-	bdrkreg_t	lb_error_hdr2_regval;
-	struct	{
-		bdrkreg_t	eh_reserved		  :	26;
-		bdrkreg_t	eh_address		  :	38;
-	} lb_error_hdr2_fld_s;
-} lb_error_hdr2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register accompanies the LB_ERROR_HDR1 and        *
- * LB_ERROR_HDR2 registers.  The LB updates the value in this           *
- * register when an incoming packet with a data flit causes an error    *
- * while VALID==0 in the LB_ERROR_HDR1 register.  This register         *
- * retains the contents of the data flit from the incoming packet       *
- * that caused the error. This register is relevant for the following   *
- * types of errors:                                                     *
- * <UL >                                                                *
- * <UL >                                                                *
- * <UL >                                                                *
- * <UL >                                                                *
- * <UL >                                                                *
- * <LI >RQ_BAD_LINVAL for a LINVAL request.                             *
- * <LI >RQ_BAD_ADDR for a normal or vector PIO request.                 *
- * <LI >RP_BAD_DATA for a vector PIO reply.                             *
- * <LI >RQ_BAD DATA for an incoming request with data.                  *
- * <LI >RP_LONG for a vector PIO reply.                                 *
- * <LI >RQ_LONG for an incoming request with expected data.             *
- * <BLOCKQUOTE >                                                        *
- * In the case of RQ_BAD_LINVAL, the register retains the 64-bit data   *
- * value that followed the header flit.  In the case of RQ_BAD_ADDR     *
- * or RQ_BAD_DATA, the register retains the incoming packet's 64-bit    *
- * data value (i.e., 2nd flit in the packet for a normal PIO write or   *
- * an LINVAL, 3rd flit for a vector PIO read or write). In the case     *
- * of RP_BAD_DATA, the register retains the 64-bit data value in the    *
- * 3rd flit of the packet. When a RP_LONG or RQ_LONG error occurs,      *
- * the LB loads the LB_ERROR_DATA register with the contents of the     *
- * expected data flit (i.e., the 3rd flit in the packet for a vector    *
- * PIO request or reply, the 2nd flit for other packets), if any. The   *
- * contents of the LB_ERROR_DATA register are undefined after a         *
- * RP_SHORT, RQ_SHORT, RP_BAD_CMD or RQ_BAD_CMD error. The contents     *
- * of the LB_ERROR_DATA register are also undefined after an incoming   *
- * normal PIO read request which encounters a RQ_LONG error.            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_error_data_u {
-	bdrkreg_t	lb_error_data_regval;
-	struct  {
-		bdrkreg_t	ed_data                   :	64;
-	} lb_error_data_fld_s;
-} lb_error_data_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register enables software to control what internal Bedrock     *
- * signals are visible on the chip's debug pins. The LB provides the    *
- * 6-bit value in this register to Bedrock's DEBUG unit. The JTAG       *
- * unit provides a similar 6-bit selection input to the DEBUG unit,     *
- * along with another signal that tells the DEBUG unit whether to use   *
- * the selection signal from the LB or the JTAG unit. For a             *
- * description of the menu of choices for debug signals, refer to the   *
- * documentation for the DEBUG unit.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_debug_select_u {
-	bdrkreg_t	lb_debug_select_regval;
-	struct  {
-		bdrkreg_t	ds_debug_sel              :	 6;
-		bdrkreg_t       ds_reserved               :     58;
-	} lb_debug_select_fld_s;
-} lb_debug_select_u_t;
-
-#else
-
-typedef union lb_debug_select_u {
-	bdrkreg_t	lb_debug_select_regval;
-	struct	{
-		bdrkreg_t	ds_reserved		  :	58;
-		bdrkreg_t	ds_debug_sel		  :	 6;
-	} lb_debug_select_fld_s;
-} lb_debug_select_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A PIO read from this register returns the 32-bit value that is      *
- * currently on the Bedrock chip's debug pins. This register allows     *
- * software to observe debug pin output values which do not change      *
- * frequently (i.e., they remain constant over a period of many         *
- * cycles).                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_debug_pins_u {
-	bdrkreg_t	lb_debug_pins_regval;
-	struct  {
-		bdrkreg_t	dp_debug_pins             :	32;
-		bdrkreg_t       dp_reserved               :     32;
-	} lb_debug_pins_fld_s;
-} lb_debug_pins_u_t;
-
-#else
-
-typedef union lb_debug_pins_u {
-	bdrkreg_t	lb_debug_pins_regval;
-	struct	{
-		bdrkreg_t	dp_reserved		  :	32;
-		bdrkreg_t	dp_debug_pins		  :	32;
-	} lb_debug_pins_fld_s;
-} lb_debug_pins_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  The LB unit provides the PI0 and PI1 units with a real-time clock   *
- * signal. The LB can generate this signal itself, based on the         *
- * Bedrock chip's system clock which the LB receives as an input.       *
- * Alternatively, the LB can filter a global clock signal which it      *
- * receives as an input and provide the filtered version to PI0 and     *
- * PI1. The user can program the LB_RT_LOCAL_CTRL register to choose    *
- * the source of the real-time clock. If the user chooses to generate   *
- * the real-time clock internally within the LB, then the user can      *
- * specify the period for the real-time clock signal.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_rt_local_ctrl_u {
-	bdrkreg_t	lb_rt_local_ctrl_regval;
-	struct  {
-		bdrkreg_t	rlc_gclk_enable           :	 1;
-		bdrkreg_t       rlc_reserved_4            :      3;
-		bdrkreg_t       rlc_max_count             :     10;
-		bdrkreg_t       rlc_reserved_3            :      2;
-		bdrkreg_t       rlc_gclk_counter          :     10;
-		bdrkreg_t       rlc_reserved_2            :      2;
-		bdrkreg_t       rlc_gclk                  :      1;
-		bdrkreg_t       rlc_reserved_1            :      3;
-		bdrkreg_t       rlc_use_internal          :      1;
-		bdrkreg_t       rlc_reserved              :     31;
-	} lb_rt_local_ctrl_fld_s;
-} lb_rt_local_ctrl_u_t;
-
-#else
-
-typedef union lb_rt_local_ctrl_u {
-        bdrkreg_t       lb_rt_local_ctrl_regval;
-        struct  {
-                bdrkreg_t       rlc_reserved              :     31;
-                bdrkreg_t       rlc_use_internal          :      1;
-                bdrkreg_t       rlc_reserved_1            :      3;
-                bdrkreg_t       rlc_gclk                  :      1;
-                bdrkreg_t       rlc_reserved_2            :      2;
-                bdrkreg_t       rlc_gclk_counter          :     10;
-                bdrkreg_t       rlc_reserved_3            :      2;
-                bdrkreg_t       rlc_max_count             :     10;
-                bdrkreg_t       rlc_reserved_4            :      3;
-                bdrkreg_t       rlc_gclk_enable           :      1;
-        } lb_rt_local_ctrl_fld_s;
-} lb_rt_local_ctrl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  When the value of the USE_INTERNAL field in the LB_RT_LOCAL_CTRL    *
- * register is 0, the LB filters an incoming global clock signal and    *
- * provides the result to PI0 and PI1 for their real-time clock         *
- * inputs. The LB can perform either simple filtering or complex        *
- * filtering, depending on the value of the MASK_ENABLE bit. For the    *
- * simple filtering option, the LB merely removes glitches from the     *
- * incoming global clock; if the global clock goes high (or low) for    *
- * only a single cycle, the LB considers it to be a glitch and does     *
- * not pass it through to PI0 and PI1. For the complex filtering        *
- * option, the LB expects positive edges on the incoming global clock   *
- * to be spaced at fairly regular intervals and it looks for them at    *
- * these times; the LB keeps track of unexpected or missing positive    *
- * edges, and it generates an edge itself whenever the incoming         *
- * global clock apparently misses an edge. For each filtering option,   *
- * the real-time clock which the LB provides to PI0 and PI1 is not      *
- * necessarily a square wave; when a positive edge happens, the         *
- * real-time clock stays high for (2*MAX_COUNT+1-OFFSET)/2 cycles of    *
- * the LB's system clock, and then is low until the next positive       *
- * edge.                                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_rt_filter_ctrl_u {
-	bdrkreg_t	lb_rt_filter_ctrl_regval;
-	struct  {
-		bdrkreg_t       rfc_offset                :      5;
-		bdrkreg_t       rfc_reserved_4            :      3;
-		bdrkreg_t       rfc_mask_counter          :     12;
-		bdrkreg_t       rfc_mask_enable           :      1;
-		bdrkreg_t       rfc_reserved_3            :      3;
-		bdrkreg_t       rfc_dropout_counter       :     10;
-		bdrkreg_t       rfc_reserved_2            :      2;
-		bdrkreg_t       rfc_dropout_thresh        :     10;
-		bdrkreg_t       rfc_reserved_1            :      2;
-		bdrkreg_t       rfc_error_counter         :     10;
-		bdrkreg_t       rfc_reserved              :      6;
-	} lb_rt_filter_ctrl_fld_s;
-} lb_rt_filter_ctrl_u_t;
-
-#else
-
-typedef union lb_rt_filter_ctrl_u {
-        bdrkreg_t       lb_rt_filter_ctrl_regval;
-        struct  {
-                bdrkreg_t       rfc_reserved              :      6;
-                bdrkreg_t       rfc_error_counter         :     10;
-                bdrkreg_t       rfc_reserved_1            :      2;
-                bdrkreg_t       rfc_dropout_thresh        :     10;
-                bdrkreg_t       rfc_reserved_2            :      2;
-                bdrkreg_t       rfc_dropout_counter       :     10;
-                bdrkreg_t       rfc_reserved_3            :      3;
-                bdrkreg_t       rfc_mask_enable           :      1;
-                bdrkreg_t       rfc_mask_counter          :     12;
-                bdrkreg_t       rfc_reserved_4            :      3;
-                bdrkreg_t       rfc_offset                :      5;
-        } lb_rt_filter_ctrl_fld_s;
-} lb_rt_filter_ctrl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is a scratch register that is reset to 0x0. At the    *
- * normal address, the register is a simple storage location. At the    *
- * Write-If-Zero address, the register accepts a new value from a       *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg0_u {
-	bdrkreg_t	lb_scratch_reg0_regval;
-	struct  {
-		bdrkreg_t	sr_scratch_bits           :	64;
-	} lb_scratch_reg0_fld_s;
-} lb_scratch_reg0_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These registers are scratch registers that are not reset. At a      *
- * register's normal address, it is a simple storage location. At a     *
- * register's Write-If-Zero address, it accepts a new value from a      *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg1_u {
-	bdrkreg_t	lb_scratch_reg1_regval;
-	struct  {
-		bdrkreg_t	sr_scratch_bits           :	64;
-	} lb_scratch_reg1_fld_s;
-} lb_scratch_reg1_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These registers are scratch registers that are not reset. At a      *
- * register's normal address, it is a simple storage location. At a     *
- * register's Write-If-Zero address, it accepts a new value from a      *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg2_u {
-	bdrkreg_t	lb_scratch_reg2_regval;
-	struct  {
-		bdrkreg_t	sr_scratch_bits           :	64;
-	} lb_scratch_reg2_fld_s;
-} lb_scratch_reg2_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These one-bit registers are scratch registers. At a register's      *
- * normal address, it is a simple storage location. At a register's     *
- * Read-Set-If-Zero address, it returns the original contents and       *
- * sets the bit if the original value is zero.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_scratch_reg3_u {
-	bdrkreg_t	lb_scratch_reg3_regval;
-	struct  {
-		bdrkreg_t	sr_scratch_bit            :	 1;
-		bdrkreg_t	sr_reserved		  :	63;
-	} lb_scratch_reg3_fld_s;
-} lb_scratch_reg3_u_t;
-
-#else
-
-typedef union lb_scratch_reg3_u {
-	bdrkreg_t	lb_scratch_reg3_regval;
-	struct	{
-		bdrkreg_t	sr_reserved		  :	63;
-		bdrkreg_t	sr_scratch_bit		  :	 1;
-	} lb_scratch_reg3_fld_s;
-} lb_scratch_reg3_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These one-bit registers are scratch registers. At a register's      *
- * normal address, it is a simple storage location. At a register's     *
- * Read-Set-If-Zero address, it returns the original contents and       *
- * sets the bit if the original value is zero.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_scratch_reg4_u {
-	bdrkreg_t	lb_scratch_reg4_regval;
-	struct  {
-		bdrkreg_t	sr_scratch_bit            :	 1;
-		bdrkreg_t       sr_reserved               :     63;
-	} lb_scratch_reg4_fld_s;
-} lb_scratch_reg4_u_t;
-
-#else
-
-typedef union lb_scratch_reg4_u {
-	bdrkreg_t	lb_scratch_reg4_regval;
-	struct	{
-		bdrkreg_t	sr_reserved		  :	63;
-		bdrkreg_t	sr_scratch_bit		  :	 1;
-	} lb_scratch_reg4_fld_s;
-} lb_scratch_reg4_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is a scratch register that is reset to 0x0. At the    *
- * normal address, the register is a simple storage location. At the    *
- * Write-If-Zero address, the register accepts a new value from a       *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg0_wz_u {
-	bdrkreg_t	lb_scratch_reg0_wz_regval;
-	struct  {
-		bdrkreg_t	srw_scratch_bits          :	64;
-	} lb_scratch_reg0_wz_fld_s;
-} lb_scratch_reg0_wz_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These registers are scratch registers that are not reset. At a      *
- * register's normal address, it is a simple storage location. At a     *
- * register's Write-If-Zero address, it accepts a new value from a      *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg1_wz_u {
-	bdrkreg_t	lb_scratch_reg1_wz_regval;
-	struct  {
-		bdrkreg_t	srw_scratch_bits          :	64;
-	} lb_scratch_reg1_wz_fld_s;
-} lb_scratch_reg1_wz_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These registers are scratch registers that are not reset. At a      *
- * register's normal address, it is a simple storage location. At a     *
- * register's Write-If-Zero address, it accepts a new value from a      *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg2_wz_u {
-	bdrkreg_t	lb_scratch_reg2_wz_regval;
-	struct  {
-		bdrkreg_t	srw_scratch_bits          :	64;
-	} lb_scratch_reg2_wz_fld_s;
-} lb_scratch_reg2_wz_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These one-bit registers are scratch registers. At a register's      *
- * normal address, it is a simple storage location. At a register's     *
- * Read-Set-If-Zero address, it returns the original contents and       *
- * sets the bit if the original value is zero.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_scratch_reg3_rz_u {
-	bdrkreg_t	lb_scratch_reg3_rz_regval;
-	struct  {
-		bdrkreg_t	srr_scratch_bit           :	 1;
-		bdrkreg_t       srr_reserved              :     63;
-	} lb_scratch_reg3_rz_fld_s;
-} lb_scratch_reg3_rz_u_t;
-
-#else
-
-typedef union lb_scratch_reg3_rz_u {
-	bdrkreg_t	lb_scratch_reg3_rz_regval;
-	struct	{
-		bdrkreg_t	srr_reserved		  :	63;
-		bdrkreg_t	srr_scratch_bit		  :	 1;
-	} lb_scratch_reg3_rz_fld_s;
-} lb_scratch_reg3_rz_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These one-bit registers are scratch registers. At a register's      *
- * normal address, it is a simple storage location. At a register's     *
- * Read-Set-If-Zero address, it returns the original contents and       *
- * sets the bit if the original value is zero.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_scratch_reg4_rz_u {
-	bdrkreg_t	lb_scratch_reg4_rz_regval;
-	struct  {
-		bdrkreg_t	srr_scratch_bit           :	 1;
-		bdrkreg_t       srr_reserved              :     63;
-	} lb_scratch_reg4_rz_fld_s;
-} lb_scratch_reg4_rz_u_t;
-
-#else
-
-typedef union lb_scratch_reg4_rz_u {
-	bdrkreg_t	lb_scratch_reg4_rz_regval;
-	struct	{
-		bdrkreg_t	srr_reserved		  :	63;
-		bdrkreg_t	srr_scratch_bit		  :	 1;
-	} lb_scratch_reg4_rz_fld_s;
-} lb_scratch_reg4_rz_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains vector PIO parameters. A        *
- * write to this register triggers the LB to send out a vector PIO      *
- * request packet. Immediately after servicing a write request to the   *
- * LB_VECTOR_PARMS register, the LB sends back a reply (i.e., the LB    *
- * doesn't wait for the vector PIO operation to finish first). Three    *
- * LB registers provide the contents for an outgoing vector PIO         *
- * request packet. Software should wait until the BUSY bit in           *
- * LB_VECTOR_PARMS is clear and then initialize all three of these      *
- * registers before initiating a vector PIO operation. The three        *
- * vector PIO registers are:                                            *
- * LB_VECTOR_ROUTE                                                      *
- * LB_VECTOR_DATA                                                       *
- * LB_VECTOR_PARMS (should be written last)                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_vector_parms_u {
-	bdrkreg_t	lb_vector_parms_regval;
-	struct  {
-		bdrkreg_t	vp_type                   :	 1;
-		bdrkreg_t       vp_reserved_2             :      2;
-		bdrkreg_t       vp_address                :     21;
-		bdrkreg_t       vp_reserved_1             :      8;
-		bdrkreg_t       vp_write_id               :      8;
-		bdrkreg_t       vp_pio_id                 :     11;
-		bdrkreg_t       vp_reserved               :     12;
-		bdrkreg_t       vp_busy                   :      1;
-	} lb_vector_parms_fld_s;
-} lb_vector_parms_u_t;
-
-#else
-
-typedef union lb_vector_parms_u {
-	bdrkreg_t	lb_vector_parms_regval;
-	struct	{
-		bdrkreg_t	vp_busy			  :	 1;
-		bdrkreg_t	vp_reserved		  :	12;
-		bdrkreg_t	vp_pio_id		  :	11;
-		bdrkreg_t	vp_write_id		  :	 8;
-		bdrkreg_t	vp_reserved_1		  :	 8;
-		bdrkreg_t	vp_address		  :	21;
-		bdrkreg_t	vp_reserved_2		  :	 2;
-		bdrkreg_t	vp_type			  :	 1;
-	} lb_vector_parms_fld_s;
-} lb_vector_parms_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the vector PIO route. This is one of the 3   *
- * vector PIO control registers.                                        *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_vector_route_u {
-	bdrkreg_t	lb_vector_route_regval;
-	struct  {
-		bdrkreg_t	vr_vector                 :	64;
-	} lb_vector_route_fld_s;
-} lb_vector_route_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the vector PIO write data. This is one of    *
- * the 3 vector PIO control registers. The contents of this register    *
- * also provide the data value to be sent in outgoing vector PIO read   *
- * requests and vector PIO write replies.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_vector_data_u {
-	bdrkreg_t	lb_vector_data_regval;
-	struct  {
-		bdrkreg_t	vd_write_data             :	64;
-	} lb_vector_data_fld_s;
-} lb_vector_data_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains the vector PIO return status.   *
- * Software should clear this register before launching a vector PIO    *
- * request from the LB. The LB will not modify this register's value    *
- * if an incoming reply packet encounters any kind of error. If an      *
- * incoming reply packet does not encounter an error but the            *
- * STATUS_VALID bit is already set, then the LB sets the OVERRUN bit    *
- * and leaves the other fields unchanged. The LB updates the values     *
- * of the SOURCE, PIO_ID, WRITE_ID, ADDRESS and TYPE fields only if     *
- * an incoming vector PIO reply packet does not encounter an error      *
- * and the STATUS_VALID bit is clear; at the same time, the LB sets     *
- * the STATUS_VALID bit and will also update the LB_VECTOR_RETURN and   *
- * LB_VECTOR_READ_DATA registers.                                       *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_vector_status_u {
-	bdrkreg_t	lb_vector_status_regval;
-	struct  {
-		bdrkreg_t	vs_type                   :	 3;
-		bdrkreg_t       vs_address                :     21;
-		bdrkreg_t       vs_reserved               :      8;
-		bdrkreg_t       vs_write_id               :      8;
-		bdrkreg_t       vs_pio_id                 :     11;
-		bdrkreg_t       vs_source                 :     11;
-		bdrkreg_t       vs_overrun                :      1;
-		bdrkreg_t       vs_status_valid           :      1;
-	} lb_vector_status_fld_s;
-} lb_vector_status_u_t;
-
-#else
-
-typedef union lb_vector_status_u {
-	bdrkreg_t	lb_vector_status_regval;
-	struct	{
-		bdrkreg_t	vs_status_valid		  :	 1;
-		bdrkreg_t	vs_overrun		  :	 1;
-		bdrkreg_t	vs_source		  :	11;
-		bdrkreg_t	vs_pio_id		  :	11;
-		bdrkreg_t	vs_write_id		  :	 8;
-		bdrkreg_t	vs_reserved		  :	 8;
-		bdrkreg_t	vs_address		  :	21;
-		bdrkreg_t	vs_type			  :	 3;
-	} lb_vector_status_fld_s;
-} lb_vector_status_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the return vector PIO route. The LB will     *
- * not modify this register's value if an incoming reply packet         *
- * encounters any kind of error. The LB also will not modify this       *
- * register's value if the STATUS_VALID bit in the LB_VECTOR_STATUS     *
- * register is set when it receives an incoming vector PIO reply. The   *
- * LB stores an incoming vector PIO reply packet's vector route flit    *
- * in this register only if the packet does not encounter an error      *
- * and the STATUS_VALID bit is clear.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_vector_return_u {
-	bdrkreg_t	lb_vector_return_regval;
-	struct  {
-		bdrkreg_t	vr_return_vector          :	64;
-	} lb_vector_return_fld_s;
-} lb_vector_return_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the vector PIO read data, if any. The LB     *
- * will not modify this register's value if an incoming reply packet    *
- * encounters any kind of error. The LB also will not modify this       *
- * register's value if the STATUS_VALID bit in the LB_VECTOR_STATUS     *
- * register is set when it receives an incoming vector PIO reply. The   *
- * LB stores an incoming vector PIO reply packet's data flit in this    *
- * register only if the packet does not encounter an error and the      *
- * STATUS_VALID bit is clear.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_vector_read_data_u {
-	bdrkreg_t	lb_vector_read_data_regval;
-	struct  {
-		bdrkreg_t	vrd_read_data             :	64;
-	} lb_vector_read_data_fld_s;
-} lb_vector_read_data_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains the vector PIO return status.   *
- * Software should clear this register before launching a vector PIO    *
- * request from the LB. The LB will not modify this register's value    *
- * if an incoming reply packet encounters any kind of error. If an      *
- * incoming reply packet does not encounter an error but the            *
- * STATUS_VALID bit is already set, then the LB sets the OVERRUN bit    *
- * and leaves the other fields unchanged. The LB updates the values     *
- * of the SOURCE, PIO_ID, WRITE_ID, ADDRESS and TYPE fields only if     *
- * an incoming vector PIO reply packet does not encounter an error      *
- * and the STATUS_VALID bit is clear; at the same time, the LB sets     *
- * the STATUS_VALID bit and will also update the LB_VECTOR_RETURN and   *
- * LB_VECTOR_READ_DATA registers.                                       *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_vector_status_clear_u {
-	bdrkreg_t	lb_vector_status_clear_regval;
-	struct  {
-		bdrkreg_t	vsc_type                  :	 3;
-		bdrkreg_t       vsc_address               :     21;
-		bdrkreg_t       vsc_reserved              :      8;
-		bdrkreg_t       vsc_write_id              :      8;
-		bdrkreg_t       vsc_pio_id                :     11;
-		bdrkreg_t       vsc_source                :     11;
-		bdrkreg_t       vsc_overrun               :      1;
-		bdrkreg_t       vsc_status_valid          :      1;
-	} lb_vector_status_clear_fld_s;
-} lb_vector_status_clear_u_t;
-
-#else
-
-typedef union lb_vector_status_clear_u {
-	bdrkreg_t	lb_vector_status_clear_regval;
-	struct	{
-		bdrkreg_t	vsc_status_valid	  :	 1;
-		bdrkreg_t	vsc_overrun		  :	 1;
-		bdrkreg_t	vsc_source		  :	11;
-		bdrkreg_t	vsc_pio_id		  :	11;
-		bdrkreg_t	vsc_write_id		  :	 8;
-		bdrkreg_t	vsc_reserved		  :	 8;
-		bdrkreg_t	vsc_address		  :	21;
-		bdrkreg_t	vsc_type		  :	 3;
-	} lb_vector_status_clear_fld_s;
-} lb_vector_status_clear_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBLB_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hublb_next.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hublb_next.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hublb_next.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hublb_next.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,109 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBLB_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBLB_NEXT_H
-
-/**********************************************************************
-
- This contains some mask and shift values for LB defined as required
- for compatibility.
-
- **********************************************************************/
-
-#define LRI_SYSTEM_SIZE_SHFT        46
-#define LRI_SYSTEM_SIZE_MASK        (UINT64_CAST 0x3 << LRI_SYSTEM_SIZE_SHFT)
-#define LRI_NODEID_SHFT        32
-#define LRI_NODEID_MASK        (UINT64_CAST 0xff << LRI_NODEID_SHFT)/* Node ID    */
-#define LRI_CHIPID_SHFT		12
-#define LRI_CHIPID_MASK		(UINT64_CAST 0xffff << LRI_CHIPID_SHFT) /* should be 0x3012 */
-#define LRI_REV_SHFT        28
-#define LRI_REV_MASK        (UINT64_CAST 0xf << LRI_REV_SHFT)/* Chip revision    */
-
-/* Values for LRI_SYSTEM_SIZE */
-#define SYSTEM_SIZE_INVALID	0x3
-#define SYSTEM_SIZE_NMODE	0x2
-#define SYSTEM_SIZE_COARSE 	0x1
-#define SYSTEM_SIZE_SMALL	0x0
-
-/* In fine mode, each node is a region.  In coarse mode, there are
- * 2 nodes per region.  In N-mode, there are 4 nodes per region. */
-#define NASID_TO_FINEREG_SHFT   0
-#define NASID_TO_COARSEREG_SHFT 1
-#define NASID_TO_NMODEREG_SHFT  2
-
-#define LR_LOCALRESET               (UINT64_CAST 1)
-/*
- * LB_VECTOR_PARMS mask and shift definitions.
- * TYPE may be any of the first four PIOTYPEs defined under NI_VECTOR_STATUS.
- */
-
-#define LVP_BUSY		(UINT64_CAST 1 << 63)
-#define LVP_PIOID_SHFT          40
-#define LVP_PIOID_MASK          (UINT64_CAST 0x7ff << 40)
-#define LVP_WRITEID_SHFT        32
-#define LVP_WRITEID_MASK        (UINT64_CAST 0xff << 32)
-#define LVP_ADDRESS_MASK        (UINT64_CAST 0xfffff8)   /* Bits 23:3        */
-#define LVP_TYPE_SHFT           0
-#define LVP_TYPE_MASK           (UINT64_CAST 0x3)
-
-/* LB_VECTOR_STATUS mask and shift definitions */
-
-#define LVS_VALID               (UINT64_CAST 1 << 63)
-#define LVS_OVERRUN             (UINT64_CAST 1 << 62)
-#define LVS_TARGET_SHFT         51
-#define LVS_TARGET_MASK         (UINT64_CAST 0x7ff << 51)
-#define LVS_PIOID_SHFT          40
-#define LVS_PIOID_MASK          (UINT64_CAST 0x7ff << 40)
-#define LVS_WRITEID_SHFT        32
-#define LVS_WRITEID_MASK        (UINT64_CAST 0xff << 32)
-#define LVS_ADDRESS_MASK        (UINT64_CAST 0xfffff8)   /* Bits 23:3     */
-#define LVS_TYPE_SHFT           0
-#define LVS_TYPE_MASK           (UINT64_CAST 0x7)
-#define LVS_ERROR_MASK          (UINT64_CAST 0x4)  /* bit set means error */
-
-/* LB_RT_LOCAL_CTRL mask and shift definitions */
-
-#define LRLC_USE_INT_SHFT       32
-#define LRLC_USE_INT_MASK       (UINT64_CAST 1 << 32)
-#define LRLC_USE_INT            (UINT64_CAST 1 << 32)
-#define LRLC_GCLK_SHFT          28
-#define LRLC_GCLK_MASK          (UINT64_CAST 1 << 28)
-#define LRLC_GCLK               (UINT64_CAST 1 << 28)
-#define LRLC_GCLK_COUNT_SHFT    16
-#define LRLC_GCLK_COUNT_MASK    (UINT64_CAST 0x3ff << 16)
-#define LRLC_MAX_COUNT_SHFT     4
-#define LRLC_MAX_COUNT_MASK     (UINT64_CAST 0x3ff << 4)
-#define LRLC_GCLK_EN_SHFT       0
-#define LRLC_GCLK_EN_MASK       (UINT64_CAST 1)
-#define LRLC_GCLK_EN            (UINT64_CAST 1)
-
-/* LB_NODES_ABSENT mask and shift definitions */
-#define LNA_VALID_SHFT		15
-#define LNA_VALID_MASK		(UINT64_CAST 1 << LNA_VALID_SHFT)
-#define LNA_VALID		(UINT64_CAST 1 << LNA_VALID_SHFT)
-#define LNA_NODE_SHFT		0
-#define LNA_NODE_MASK		(UINT64_CAST 0xff << LNA_NODE_SHFT)
-
-/* LB_NODES_ABSENT has 4 identical sub-registers, on 16-bit boundaries */
-#define LNA_ENTRY_SHFT		16
-#define LNA_MAX_ENTRIES		4
-#define LNA_ADD(_reg, _n)	((_reg) = (_reg) << LNA_ENTRY_SHFT | \
-				 	LNA_VALID | (_n) << LNA_NODE_SHFT)
-
-#define  PIOTYPE_READ           0       /* VECTOR_PARMS and VECTOR_STATUS   */
-#define  PIOTYPE_WRITE          1       /* VECTOR_PARMS and VECTOR_STATUS   */
-#define  PIOTYPE_UNDEFINED      2       /* VECTOR_PARMS and VECTOR_STATUS   */
-/* XXX IP35 doesn't support vector exchange:  scr. regs. do locks directly */
-#define  PIOTYPE_EXCHANGE       3       /* VECTOR_PARMS and VECTOR_STATUS   */
-#define  PIOTYPE_ADDR_ERR       4       /* VECTOR_STATUS only               */
-#define  PIOTYPE_CMD_ERR        5       /* VECTOR_STATUS only               */
-#define  PIOTYPE_PROT_ERR       6       /* VECTOR_STATUS only               */
-#define  PIOTYPE_UNKNOWN        7       /* VECTOR_STATUS only               */
-
-#endif /* _ASM_IA64_SN_SN1_HUBLB_NEXT_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubmd.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubmd.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubmd.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubmd.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,2476 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBMD_H
-#define _ASM_IA64_SN_SN1_HUBMD_H
-
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-
-#define    MD_CURRENT_CELL           0x00780000    /*
-                                                    * BDDIR, LREG, LBOOT,
-                                                    * RREG, RBOOT
-                                                    * protection and mask
-                                                    * for using Local
-                                                    * Access protection.
-                                                    */
-
-
-
-#define    MD_MEMORY_CONFIG          0x00780008    /*
-                                                    * Memory/Directory
-                                                    * DIMM control
-                                                    */
-
-
-
-#define    MD_ARBITRATION_CONTROL    0x00780010    /*
-                                                    * Arbitration
-                                                    * Parameters
-                                                    */
-
-
-
-#define    MD_MIG_CONFIG             0x00780018    /*
-                                                    * Page Migration
-                                                    * control
-                                                    */
-
-
-
-#define    MD_FANDOP_CAC_STAT0       0x00780020    /*
-                                                    * Fetch-and-op cache
-                                                    * 0 status
-                                                    */
-
-
-
-#define    MD_FANDOP_CAC_STAT1       0x00780028    /*
-                                                    * Fetch-and-op cache
-                                                    * 1 status
-                                                    */
-
-
-
-#define    MD_MISC0_ERROR            0x00780040    /*
-                                                    * Miscellaneous MD
-                                                    * error
-                                                    */
-
-
-
-#define    MD_MISC1_ERROR            0x00780048    /*
-                                                    * Miscellaneous MD
-                                                    * error
-                                                    */
-
-
-
-#define    MD_MISC1_ERROR_CLR        0x00780058    /*
-                                                    * Miscellaneous MD
-                                                    * error clear
-                                                    */
-
-
-
-#define    MD_OUTGOING_RP_QUEUE_SIZE 0x00780060    /*
-                                                    * MD outgoing reply
-                                                    * queues sizing
-                                                    */
-
-
-
-#define    MD_PERF_SEL0              0x00790000    /*
-                                                    * Selects events
-                                                    * monitored by
-                                                    * MD_PERF_CNT0
-                                                    */
-
-
-
-#define    MD_PERF_SEL1              0x00790008    /*
-                                                    * Selects events
-                                                    * monitored by
-                                                    * MD_PERF_CNT1
-                                                    */
-
-
-
-#define    MD_PERF_CNT0              0x00790010    /*
-                                                    * Performance counter
-                                                    * 0
-                                                    */
-
-
-
-#define    MD_PERF_CNT1              0x00790018    /*
-                                                    * Performance counter
-                                                    * 1
-                                                    */
-
-
-
-#define    MD_REFRESH_CONTROL        0x007A0000    /*
-                                                    * Memory/Directory
-                                                    * refresh control
-                                                    */
-
-
-
-#define    MD_JUNK_BUS_TIMING        0x007A0008    /* Junk Bus Timing        */
-
-
-
-#define    MD_LED0                   0x007A0010    /* Reads of 8-bit LED0    */
-
-
-
-#define    MD_LED1                   0x007A0018    /* Reads of 8-bit LED1    */
-
-
-
-#define    MD_LED2                   0x007A0020    /* Reads of 8-bit LED2    */
-
-
-
-#define    MD_LED3                   0x007A0028    /* Reads of 8-bit LED3    */
-
-
-
-#define    MD_BIST_CTL               0x007A0030    /*
-                                                    * BIST general
-                                                    * control
-                                                    */
-
-
-
-#define    MD_BIST_DATA              0x007A0038    /*
-                                                    * BIST initial data
-                                                    * pattern and
-                                                    * variation control
-                                                    */
-
-
-
-#define    MD_BIST_AB_ERR_ADDR       0x007A0040    /* BIST error address     */
-
-
-
-#define    MD_BIST_STATUS            0x007A0048    /* BIST status            */
-
-
-
-#define    MD_IB_DEBUG               0x007A0060    /* IB debug select        */
-
-
-
-#define    MD_DIR_CONFIG             0x007C0000    /*
-                                                    * Directory mode
-                                                    * control
-                                                    */
-
-
-
-#define    MD_DIR_ERROR              0x007C0010    /*
-                                                    * Directory DIMM
-                                                    * error
-                                                    */
-
-
-
-#define    MD_DIR_ERROR_CLR          0x007C0018    /*
-                                                    * Directory DIMM
-                                                    * error clear
-                                                    */
-
-
-
-#define    MD_PROTOCOL_ERROR         0x007C0020    /*
-                                                    * Directory protocol
-                                                    * error
-                                                    */
-
-
-
-#define    MD_PROTOCOL_ERR_CLR       0x007C0028    /*
-                                                    * Directory protocol
-                                                    * error clear
-                                                    */
-
-
-
-#define    MD_MIG_CANDIDATE          0x007C0030    /*
-                                                    * Page migration
-                                                    * candidate
-                                                    */
-
-
-
-#define    MD_MIG_CANDIDATE_CLR      0x007C0038    /*
-                                                    * Page migration
-                                                    * candidate clear
-                                                    */
-
-
-
-#define    MD_MIG_DIFF_THRESH        0x007C0040    /*
-                                                    * Page migration
-                                                    * count difference
-                                                    * threshold
-                                                    */
-
-
-
-#define    MD_MIG_VALUE_THRESH       0x007C0048    /*
-                                                    * Page migration
-                                                    * count absolute
-                                                    * threshold
-                                                    */
-
-
-
-#define    MD_OUTGOING_RQ_QUEUE_SIZE 0x007C0050    /*
-                                                    * MD outgoing request
-                                                    * queues sizing
-                                                    */
-
-
-
-#define    MD_BIST_DB_ERR_DATA       0x007C0058    /*
-                                                    * BIST directory
-                                                    * error data
-                                                    */
-
-
-
-#define    MD_DB_DEBUG               0x007C0060    /* DB debug select        */
-
-
-
-#define    MD_MB_ECC_CONFIG          0x007E0000    /*
-                                                    * Data ECC
-                                                    * Configuration
-                                                    */
-
-
-
-#define    MD_MEM_ERROR              0x007E0010    /* Memory DIMM error      */
-
-
-
-#define    MD_MEM_ERROR_CLR          0x007E0018    /*
-                                                    * Memory DIMM error
-                                                    * clear
-                                                    */
-
-
-
-#define    MD_BIST_MB_ERR_DATA_0     0x007E0020    /*
-                                                    * BIST memory error
-                                                    * data
-                                                    */
-
-
-
-#define    MD_BIST_MB_ERR_DATA_1     0x007E0028    /*
-                                                    * BIST memory error
-                                                    * data
-                                                    */
-
-
-
-#define    MD_BIST_MB_ERR_DATA_2     0x007E0030    /*
-                                                    * BIST memory error
-                                                    * data
-                                                    */
-
-
-
-#define    MD_BIST_MB_ERR_DATA_3     0x007E0038    /*
-                                                    * BIST memory error
-                                                    * data
-                                                    */
-
-
-
-#define    MD_MB_DEBUG               0x007E0040    /* MB debug select        */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- * Description:  This register shows which regions are in the current   *
- * cell. If a region has its bit set in this register, then it uses     *
- * the Local Access protection in the directory instead of the          *
- * separate per-region protection (which would cause a small            *
- * performance penalty). In addition, writeback and write reply         *
- * commands from outside the current cell will always check the         *
- * directory protection before writing data to memory. Writeback and    *
- * write reply commands from inside the current cell will write         *
- * memory regardless of the protection value.                           *
- * This register is also used as the access-rights bit-vector for       *
- * most of the ASIC-special (HSpec) portion of the address space. It    *
- * covers the BDDIR, LREG, LBOOT, RREG, and RBOOT spaces. It does not   *
- * cover the UALIAS and BDECC spaces, as they are covered by the        *
- * protection in the directory. If a bit in the bit-vector is set,      *
- * the region corresponding to that bit has read/write permission on    *
- * these spaces. If the bit is clear, then that region has read-only    *
- * access to these spaces (except for LREG/RREG which have no access    *
- * when the bit is clear).                                              *
- * The granularity of a region is set by the REGION_SIZE register in    *
- * the NI local register space.                                         *
- * NOTE: This means that no processor outside the current cell can      *
- * write into the BDDIR, LREG, LBOOT, RREG, or RBOOT spaces.            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union md_current_cell_u {
-	bdrkreg_t	md_current_cell_regval;
-	struct  {
-		bdrkreg_t	cc_hspec_prot             :	64;
-	} md_current_cell_fld_s;
-} md_current_cell_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains three sets of information.      *
- * The first set describes the size and configuration of DIMMs that     *
- * are plugged into a system, the second set controls which set of      *
- * protection checks are performed on each access and the third set     *
- * controls various DDR SDRAM timing parameters.                        *
- * In order to config a DIMM bank, three fields must be initialized:    *
- * BANK_SIZE, DRAM_WIDTH, and BANK_ENABLE. The BANK_SIZE field sets     *
- * the address range that the MD unit will accept for that DIMM bank.   *
- * All addresses larger than the specified size will return errors on   *
- * access. In order to read from a DIMM bank, Bedrock must know         *
- * whether or not the bank contains x4 or x8/x16 DRAM. The operating    *
- * system must query the System Controller for this information and     *
- * then set the DRAM_WIDTH field accordingly. The BANK_ENABLE field     *
- * can be used to individually enable the two physical banks located    *
- * on each DIMM bank.                                                   *
- * The contents of this register are preserved through soft-resets.     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_memory_config_u {
-	bdrkreg_t	md_memory_config_regval;
-	struct  {
-		bdrkreg_t	mc_dimm0_bank_enable      :	 2;
-		bdrkreg_t       mc_reserved_7             :      1;
-		bdrkreg_t       mc_dimm0_dram_width       :      1;
-		bdrkreg_t       mc_dimm0_bank_size        :      4;
-		bdrkreg_t       mc_dimm1_bank_enable      :      2;
-		bdrkreg_t       mc_reserved_6             :      1;
-		bdrkreg_t       mc_dimm1_dram_width       :      1;
-		bdrkreg_t       mc_dimm1_bank_size        :      4;
-                bdrkreg_t       mc_dimm2_bank_enable      :      2;
-                bdrkreg_t       mc_reserved_5             :      1;
-                bdrkreg_t       mc_dimm2_dram_width       :      1;
-                bdrkreg_t       mc_dimm2_bank_size        :      4;
-                bdrkreg_t       mc_dimm3_bank_enable      :      2;
-                bdrkreg_t       mc_reserved_4             :      1;
-                bdrkreg_t       mc_dimm3_dram_width       :      1;
-                bdrkreg_t       mc_dimm3_bank_size        :      4;
-                bdrkreg_t       mc_dimm0_sel              :      2;
-                bdrkreg_t       mc_reserved_3             :     10;
-                bdrkreg_t       mc_cc_enable              :      1;
-                bdrkreg_t       mc_io_prot_en             :      1;
-                bdrkreg_t       mc_io_prot_ignore         :      1;
-                bdrkreg_t       mc_cpu_prot_ignore        :      1;
-                bdrkreg_t       mc_db_neg_edge            :      1;
-                bdrkreg_t       mc_phase_delay            :      1;
-                bdrkreg_t       mc_delay_mux_sel          :      2;
-                bdrkreg_t       mc_sample_time            :      2;
-                bdrkreg_t       mc_reserved_2             :      2;
-                bdrkreg_t       mc_mb_neg_edge            :      3;
-                bdrkreg_t       mc_reserved_1             :      1;
-                bdrkreg_t       mc_rcd_config             :      1;
-                bdrkreg_t       mc_rp_config              :      1;
-                bdrkreg_t       mc_reserved               :      2;
-	} md_memory_config_fld_s;
-} md_memory_config_u_t;
-
-#else
-
-typedef union md_memory_config_u {
-	bdrkreg_t	md_memory_config_regval;
-	struct	{
-		bdrkreg_t	mc_reserved		  :	 2;
-		bdrkreg_t	mc_rp_config		  :	 1;
-		bdrkreg_t	mc_rcd_config		  :	 1;
-		bdrkreg_t	mc_reserved_1		  :	 1;
-		bdrkreg_t	mc_mb_neg_edge		  :	 3;
-		bdrkreg_t	mc_reserved_2		  :	 2;
-		bdrkreg_t	mc_sample_time		  :	 2;
-		bdrkreg_t	mc_delay_mux_sel	  :	 2;
-		bdrkreg_t	mc_phase_delay		  :	 1;
-		bdrkreg_t	mc_db_neg_edge		  :	 1;
-		bdrkreg_t	mc_cpu_prot_ignore	  :	 1;
-		bdrkreg_t	mc_io_prot_ignore	  :	 1;
-		bdrkreg_t	mc_io_prot_en		  :	 1;
-		bdrkreg_t	mc_cc_enable		  :	 1;
-		bdrkreg_t	mc_reserved_3		  :	10;
-		bdrkreg_t	mc_dimm0_sel		  :	 2;
-		bdrkreg_t	mc_dimm3_bank_size	  :	 4;
-		bdrkreg_t	mc_dimm3_dram_width	  :	 1;
-		bdrkreg_t	mc_reserved_4		  :	 1;
-		bdrkreg_t	mc_dimm3_bank_enable	  :	 2;
-		bdrkreg_t	mc_dimm2_bank_size	  :	 4;
-		bdrkreg_t	mc_dimm2_dram_width	  :	 1;
-		bdrkreg_t	mc_reserved_5		  :	 1;
-		bdrkreg_t	mc_dimm2_bank_enable	  :	 2;
-		bdrkreg_t	mc_dimm1_bank_size	  :	 4;
-		bdrkreg_t	mc_dimm1_dram_width	  :	 1;
-		bdrkreg_t	mc_reserved_6		  :	 1;
-		bdrkreg_t	mc_dimm1_bank_enable	  :	 2;
-		bdrkreg_t	mc_dimm0_bank_size	  :	 4;
-		bdrkreg_t	mc_dimm0_dram_width	  :	 1;
-		bdrkreg_t	mc_reserved_7		  :	 1;
-		bdrkreg_t	mc_dimm0_bank_enable	  :	 2;
-	} md_memory_config_fld_s;
-} md_memory_config_u_t;
-
-#endif
-
-
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_arbitration_control_u {
-	bdrkreg_t	md_arbitration_control_regval;
-	struct  {
-		bdrkreg_t	ac_reply_guar             :	 4;
-		bdrkreg_t       ac_write_guar             :      4;
-		bdrkreg_t       ac_reserved               :     56;
-	} md_arbitration_control_fld_s;
-} md_arbitration_control_u_t;
-
-#else
-
-typedef union md_arbitration_control_u {
-	bdrkreg_t	md_arbitration_control_regval;
-	struct	{
-		bdrkreg_t	ac_reserved		  :	56;
-		bdrkreg_t	ac_write_guar		  :	 4;
-		bdrkreg_t	ac_reply_guar		  :	 4;
-	} md_arbitration_control_fld_s;
-} md_arbitration_control_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains page migration control fields.                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mig_config_u {
-	bdrkreg_t	md_mig_config_regval;
-	struct  {
-		bdrkreg_t	mc_mig_interval           :	10;
-		bdrkreg_t       mc_reserved_2             :      6;
-		bdrkreg_t       mc_mig_node_mask          :      8;
-		bdrkreg_t       mc_reserved_1             :      8;
-		bdrkreg_t       mc_mig_enable             :      1;
-		bdrkreg_t       mc_reserved               :     31;
-	} md_mig_config_fld_s;
-} md_mig_config_u_t;
-
-#else
-
-typedef union md_mig_config_u {
-	bdrkreg_t	md_mig_config_regval;
-	struct	{
-		bdrkreg_t	mc_reserved		  :	31;
-		bdrkreg_t	mc_mig_enable		  :	 1;
-		bdrkreg_t	mc_reserved_1		  :	 8;
-		bdrkreg_t	mc_mig_node_mask	  :	 8;
-		bdrkreg_t	mc_reserved_2		  :	 6;
-		bdrkreg_t	mc_mig_interval		  :	10;
-	} md_mig_config_fld_s;
-} md_mig_config_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each register contains the valid bit and address of the entry in    *
- * the fetch-and-op for cache 0 (or 1).                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_fandop_cac_stat0_u {
-	bdrkreg_t	md_fandop_cac_stat0_regval;
-	struct  {
-		bdrkreg_t	fcs_reserved_1            :	 6;
-		bdrkreg_t       fcs_addr                  :     27;
-		bdrkreg_t       fcs_reserved              :     30;
-		bdrkreg_t       fcs_valid                 :      1;
-	} md_fandop_cac_stat0_fld_s;
-} md_fandop_cac_stat0_u_t;
-
-#else
-
-typedef union md_fandop_cac_stat0_u {
-	bdrkreg_t	md_fandop_cac_stat0_regval;
-	struct	{
-		bdrkreg_t	fcs_valid		  :	 1;
-		bdrkreg_t	fcs_reserved		  :	30;
-		bdrkreg_t	fcs_addr		  :	27;
-		bdrkreg_t	fcs_reserved_1		  :	 6;
-	} md_fandop_cac_stat0_fld_s;
-} md_fandop_cac_stat0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each register contains the valid bit and address of the entry in    *
- * the fetch-and-op for cache 0 (or 1).                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_fandop_cac_stat1_u {
-	bdrkreg_t	md_fandop_cac_stat1_regval;
-	struct  {
-		bdrkreg_t	fcs_reserved_1            :	 6;
-		bdrkreg_t       fcs_addr                  :     27;
-		bdrkreg_t       fcs_reserved              :     30;
-		bdrkreg_t       fcs_valid                 :      1;
-	} md_fandop_cac_stat1_fld_s;
-} md_fandop_cac_stat1_u_t;
-
-#else
-
-typedef union md_fandop_cac_stat1_u {
-	bdrkreg_t	md_fandop_cac_stat1_regval;
-	struct	{
-		bdrkreg_t	fcs_valid		  :	 1;
-		bdrkreg_t	fcs_reserved		  :	30;
-		bdrkreg_t	fcs_addr		  :	27;
-		bdrkreg_t	fcs_reserved_1		  :	 6;
-	} md_fandop_cac_stat1_fld_s;
-} md_fandop_cac_stat1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Contains a number of fields to capture various         *
- * random memory/directory errors. For each 2-bit field, the LSB        *
- * indicates that additional information has been captured for the      *
- * error and the MSB indicates overrun, thus:                           *
- *  x1: bits 51...0 of this register contain additional information     *
- * for the message that caused this error                               *
- *  1x: overrun occurred                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_misc0_error_u {
-	bdrkreg_t	md_misc0_error_regval;
-	struct	{
-		bdrkreg_t	me_command		  :	 7;
-                bdrkreg_t       me_reserved_4             :      1;
-                bdrkreg_t       me_source                 :     11;
-                bdrkreg_t       me_reserved_3             :      1;
-                bdrkreg_t       me_suppl                  :     11;
-                bdrkreg_t       me_reserved_2             :      1;
-                bdrkreg_t       me_virtual_channel        :      2;
-                bdrkreg_t       me_reserved_1             :      2;
-                bdrkreg_t       me_tail                   :      1;
-                bdrkreg_t       me_reserved               :     11;
-                bdrkreg_t       me_xb_error               :      4;
-                bdrkreg_t       me_bad_partial_data       :      2;
-                bdrkreg_t       me_missing_dv             :      2;
-                bdrkreg_t       me_short_pack             :      2;
-                bdrkreg_t       me_long_pack              :      2;
-                bdrkreg_t       me_ill_msg                :      2;
-                bdrkreg_t       me_ill_revision           :      2;
-	} md_misc0_error_fld_s;
-} md_misc0_error_u_t;
-
-#else
-
-typedef union md_misc0_error_u {
-	bdrkreg_t	md_misc0_error_regval;
-	struct  {
-		bdrkreg_t	me_ill_revision           :	 2;
-		bdrkreg_t	me_ill_msg                :	 2;
-		bdrkreg_t	me_long_pack              :	 2;
-		bdrkreg_t	me_short_pack             :	 2;
-		bdrkreg_t	me_missing_dv             :	 2;
-		bdrkreg_t	me_bad_partial_data       :	 2;
-		bdrkreg_t	me_xb_error               :	 4;
-		bdrkreg_t	me_reserved               :	11;
-		bdrkreg_t	me_tail                   :	 1;
-		bdrkreg_t	me_reserved_1             :	 2;
-		bdrkreg_t	me_virtual_channel        :	 2;
-		bdrkreg_t	me_reserved_2             :	 1;
-		bdrkreg_t	me_suppl                  :	11;
-		bdrkreg_t	me_reserved_3             :	 1;
-		bdrkreg_t	me_source                 :	11;
-		bdrkreg_t	me_reserved_4             :	 1;
-		bdrkreg_t	me_command                :	 7;
-	} md_misc0_error_fld_s;
-} md_misc0_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Address for error captured in MISC0_ERROR. Error valid bits are     *
- * repeated in both MISC0_ERROR and MISC1_ERROR (allowing them to be    *
- * read sequentially without missing any errors).                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_misc1_error_u {
-	bdrkreg_t	md_misc1_error_regval;
-	struct  {
-		bdrkreg_t	me_reserved_1             :	 3;
-		bdrkreg_t       me_address                :     38;
-		bdrkreg_t       me_reserved               :      7;
-		bdrkreg_t       me_xb_error               :      4;
-		bdrkreg_t       me_bad_partial_data       :      2;
-		bdrkreg_t       me_missing_dv             :      2;
-		bdrkreg_t       me_short_pack             :      2;
-		bdrkreg_t       me_long_pack              :      2;
-		bdrkreg_t       me_ill_msg                :      2;
-		bdrkreg_t       me_ill_revision           :      2;
-	} md_misc1_error_fld_s;
-} md_misc1_error_u_t;
-
-#else
-
-typedef union md_misc1_error_u {
-	bdrkreg_t	md_misc1_error_regval;
-	struct	{
-		bdrkreg_t	me_ill_revision		  :	 2;
-		bdrkreg_t	me_ill_msg		  :	 2;
-		bdrkreg_t	me_long_pack		  :	 2;
-		bdrkreg_t	me_short_pack		  :	 2;
-		bdrkreg_t	me_missing_dv		  :	 2;
-		bdrkreg_t	me_bad_partial_data	  :	 2;
-		bdrkreg_t	me_xb_error		  :	 4;
-		bdrkreg_t	me_reserved		  :	 7;
-		bdrkreg_t	me_address		  :	38;
-		bdrkreg_t	me_reserved_1		  :	 3;
-	} md_misc1_error_fld_s;
-} md_misc1_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Address for error captured in MISC0_ERROR. Error valid bits are     *
- * repeated in both MISC0_ERROR and MISC1_ERROR (allowing them to be    *
- * read sequentially without missing any errors).                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_misc1_error_clr_u {
-	bdrkreg_t	md_misc1_error_clr_regval;
-	struct  {
-		bdrkreg_t	mec_reserved_1            :	 3;
-		bdrkreg_t       mec_address               :     38;
-		bdrkreg_t       mec_reserved              :      7;
-		bdrkreg_t       mec_xb_error              :      4;
-		bdrkreg_t       mec_bad_partial_data      :      2;
-		bdrkreg_t       mec_missing_dv            :      2;
-		bdrkreg_t       mec_short_pack            :      2;
-		bdrkreg_t       mec_long_pack             :      2;
-		bdrkreg_t       mec_ill_msg               :      2;
-		bdrkreg_t       mec_ill_revision          :      2;
-	} md_misc1_error_clr_fld_s;
-} md_misc1_error_clr_u_t;
-
-#else
-
-typedef union md_misc1_error_clr_u {
-	bdrkreg_t	md_misc1_error_clr_regval;
-	struct	{
-		bdrkreg_t	mec_ill_revision	  :	 2;
-		bdrkreg_t	mec_ill_msg		  :	 2;
-		bdrkreg_t	mec_long_pack		  :	 2;
-		bdrkreg_t	mec_short_pack		  :	 2;
-		bdrkreg_t	mec_missing_dv		  :	 2;
-		bdrkreg_t	mec_bad_partial_data	  :	 2;
-		bdrkreg_t	mec_xb_error		  :	 4;
-		bdrkreg_t	mec_reserved		  :	 7;
-		bdrkreg_t	mec_address		  :	38;
-		bdrkreg_t	mec_reserved_1		  :	 3;
-	} md_misc1_error_clr_fld_s;
-} md_misc1_error_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  The MD no longer allows for arbitrarily sizing the     *
- * reply queues, so all of the fields in this register are read-only    *
- * and contain the reset default value of 12 for the MOQHs (for         *
- * headers) and 24 for the MOQDs (for data).                            *
- * Reading from this register returns the values currently held in      *
- * the MD's credit counters. Writing to the register resets the         *
- * counters to the default reset values specified in the table below.   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_outgoing_rp_queue_size_u {
-	bdrkreg_t	md_outgoing_rp_queue_size_regval;
-	struct  {
-		bdrkreg_t	orqs_reserved_6           :	 8;
-		bdrkreg_t       orqs_moqh_p0_rp_size      :      4;
-		bdrkreg_t       orqs_reserved_5           :      4;
-		bdrkreg_t       orqs_moqh_p1_rp_size      :      4;
-		bdrkreg_t       orqs_reserved_4           :      4;
-		bdrkreg_t       orqs_moqh_np_rp_size      :      4;
-		bdrkreg_t       orqs_reserved_3           :      4;
-		bdrkreg_t       orqs_moqd_pi0_rp_size     :      5;
-		bdrkreg_t       orqs_reserved_2           :      3;
-		bdrkreg_t       orqs_moqd_pi1_rp_size     :      5;
-		bdrkreg_t       orqs_reserved_1           :      3;
-		bdrkreg_t       orqs_moqd_np_rp_size      :      5;
-		bdrkreg_t       orqs_reserved             :     11;
-	} md_outgoing_rp_queue_size_fld_s;
-} md_outgoing_rp_queue_size_u_t;
-
-#else
-
-typedef union md_outgoing_rp_queue_size_u {
-	bdrkreg_t	md_outgoing_rp_queue_size_regval;
-	struct	{
-		bdrkreg_t	orqs_reserved		  :	11;
-		bdrkreg_t	orqs_moqd_np_rp_size	  :	 5;
-		bdrkreg_t	orqs_reserved_1		  :	 3;
-		bdrkreg_t	orqs_moqd_pi1_rp_size	  :	 5;
-		bdrkreg_t	orqs_reserved_2		  :	 3;
-		bdrkreg_t	orqs_moqd_pi0_rp_size	  :	 5;
-		bdrkreg_t	orqs_reserved_3		  :	 4;
-		bdrkreg_t	orqs_moqh_np_rp_size	  :	 4;
-		bdrkreg_t	orqs_reserved_4		  :	 4;
-		bdrkreg_t	orqs_moqh_p1_rp_size	  :	 4;
-		bdrkreg_t	orqs_reserved_5		  :	 4;
-		bdrkreg_t	orqs_moqh_p0_rp_size	  :	 4;
-		bdrkreg_t	orqs_reserved_6		  :	 8;
-	} md_outgoing_rp_queue_size_fld_s;
-} md_outgoing_rp_queue_size_u_t;
-
-#endif
-
-
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_perf_sel0_u {
-	bdrkreg_t	md_perf_sel0_regval;
-	struct  {
-		bdrkreg_t	ps_cnt_mode               :	 2;
-		bdrkreg_t       ps_reserved_2             :      2;
-		bdrkreg_t       ps_activity               :      4;
-		bdrkreg_t       ps_source                 :      7;
-		bdrkreg_t       ps_reserved_1             :      1;
-		bdrkreg_t       ps_channel                :      4;
-		bdrkreg_t       ps_command                :     40;
-		bdrkreg_t       ps_reserved               :      3;
-		bdrkreg_t       ps_interrupt              :      1;
-	} md_perf_sel0_fld_s;
-} md_perf_sel0_u_t;
-
-#else
-
-typedef union md_perf_sel0_u {
-	bdrkreg_t	md_perf_sel0_regval;
-	struct	{
-		bdrkreg_t	ps_interrupt		  :	 1;
-		bdrkreg_t	ps_reserved		  :	 3;
-		bdrkreg_t	ps_command		  :	40;
-		bdrkreg_t	ps_channel		  :	 4;
-		bdrkreg_t	ps_reserved_1		  :	 1;
-		bdrkreg_t	ps_source		  :	 7;
-		bdrkreg_t	ps_activity		  :	 4;
-		bdrkreg_t	ps_reserved_2		  :	 2;
-		bdrkreg_t	ps_cnt_mode		  :	 2;
-	} md_perf_sel0_fld_s;
-} md_perf_sel0_u_t;
-
-#endif
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_perf_sel1_u {
-	bdrkreg_t	md_perf_sel1_regval;
-	struct  {
-		bdrkreg_t	ps_cnt_mode               :	 2;
-		bdrkreg_t       ps_reserved_2             :      2;
-		bdrkreg_t       ps_activity               :      4;
-		bdrkreg_t       ps_source                 :      7;
-		bdrkreg_t       ps_reserved_1             :      1;
-		bdrkreg_t       ps_channel                :      4;
-		bdrkreg_t       ps_command                :     40;
-		bdrkreg_t       ps_reserved               :      3;
-		bdrkreg_t       ps_interrupt              :      1;
-	} md_perf_sel1_fld_s;
-} md_perf_sel1_u_t;
-
-#else
-
-typedef union md_perf_sel1_u {
-	bdrkreg_t	md_perf_sel1_regval;
-	struct	{
-		bdrkreg_t	ps_interrupt		  :	 1;
-		bdrkreg_t	ps_reserved		  :	 3;
-		bdrkreg_t	ps_command		  :	40;
-		bdrkreg_t	ps_channel		  :	 4;
-		bdrkreg_t	ps_reserved_1		  :	 1;
-		bdrkreg_t	ps_source		  :	 7;
-		bdrkreg_t	ps_activity		  :	 4;
-		bdrkreg_t	ps_reserved_2		  :	 2;
-		bdrkreg_t	ps_cnt_mode		  :	 2;
-	} md_perf_sel1_fld_s;
-} md_perf_sel1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Performance counter.                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_perf_cnt0_u {
-	bdrkreg_t	md_perf_cnt0_regval;
-	struct  {
-		bdrkreg_t	pc_perf_cnt               :	41;
-		bdrkreg_t	pc_reserved		  :	23;
-	} md_perf_cnt0_fld_s;
-} md_perf_cnt0_u_t;
-
-#else
-
-typedef union md_perf_cnt0_u {
-	bdrkreg_t	md_perf_cnt0_regval;
-	struct	{
-		bdrkreg_t	pc_reserved		  :	23;
-		bdrkreg_t	pc_perf_cnt		  :	41;
-	} md_perf_cnt0_fld_s;
-} md_perf_cnt0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Performance counter.                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_perf_cnt1_u {
-	bdrkreg_t	md_perf_cnt1_regval;
-	struct  {
-		bdrkreg_t	pc_perf_cnt               :	41;
-		bdrkreg_t	pc_reserved		  :	23;
-	} md_perf_cnt1_fld_s;
-} md_perf_cnt1_u_t;
-
-#else
-
-typedef union md_perf_cnt1_u {
-	bdrkreg_t	md_perf_cnt1_regval;
-	struct	{
-		bdrkreg_t	pc_reserved		  :	23;
-		bdrkreg_t	pc_perf_cnt		  :	41;
-	} md_perf_cnt1_fld_s;
-} md_perf_cnt1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains the control for                 *
- * memory/directory refresh. Once the MEMORY_CONFIG register contains   *
- * the correct DIMM information, the hardware takes care of             *
- * refreshing all the banks in the system. Therefore, the value in      *
- * the counter threshold is corresponds exactly to the refresh value    *
- * required by the SDRAM parts (expressed in Bedrock clock cycles).     *
- * The refresh will execute whenever there is a free cycle and there    *
- * are still banks that have not been refreshed in the current          *
- * window. If the window expires with banks still waiting to be         *
- * refreshed, all other transactions are halted until the banks are     *
- * refreshed.                                                           *
- * The upper order bit contains an enable, which may be needed for      *
- * correct initialization of the DIMMs (according to the specs, the     *
- * first operation to the DIMMs should be a mode register write, not    *
- * a refresh, so this bit is cleared on reset) and is also useful for   *
- * diagnostic purposes.                                                 *
- * For the SDRAM parts used by Bedrock, 4096 refreshes need to be       *
- * issued during every 64 ms window, resulting in a refresh threshold   *
- * of 3125 Bedrock cycles.                                              *
- * The ENABLE and CNT_THRESH fields of this register are preserved      *
- * through soft-resets.                                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_refresh_control_u {
-	bdrkreg_t	md_refresh_control_regval;
-	struct  {
-		bdrkreg_t	rc_cnt_thresh             :	12;
-		bdrkreg_t       rc_counter                :     12;
-		bdrkreg_t       rc_reserved               :     39;
-		bdrkreg_t       rc_enable                 :      1;
-	} md_refresh_control_fld_s;
-} md_refresh_control_u_t;
-
-#else
-
-typedef union md_refresh_control_u {
-	bdrkreg_t	md_refresh_control_regval;
-	struct	{
-		bdrkreg_t	rc_enable		  :	 1;
-		bdrkreg_t	rc_reserved		  :	39;
-		bdrkreg_t	rc_counter		  :	12;
-		bdrkreg_t	rc_cnt_thresh		  :	12;
-	} md_refresh_control_fld_s;
-} md_refresh_control_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls the read and write timing for Flash PROM,    *
- * UART and Synergy junk bus devices.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_junk_bus_timing_u {
-	bdrkreg_t	md_junk_bus_timing_regval;
-	struct  {
-		bdrkreg_t	jbt_fprom_setup_hold      :	 8;
-		bdrkreg_t       jbt_fprom_enable          :      8;
-		bdrkreg_t       jbt_uart_setup_hold       :      8;
-		bdrkreg_t       jbt_uart_enable           :      8;
-		bdrkreg_t       jbt_synergy_setup_hold    :      8;
-		bdrkreg_t       jbt_synergy_enable        :      8;
-		bdrkreg_t       jbt_reserved              :     16;
-	} md_junk_bus_timing_fld_s;
-} md_junk_bus_timing_u_t;
-
-#else
-
-typedef union md_junk_bus_timing_u {
-	bdrkreg_t	md_junk_bus_timing_regval;
-	struct	{
-		bdrkreg_t	jbt_reserved		  :	16;
-		bdrkreg_t	jbt_synergy_enable	  :	 8;
-		bdrkreg_t	jbt_synergy_setup_hold	  :	 8;
-		bdrkreg_t	jbt_uart_enable		  :	 8;
-		bdrkreg_t	jbt_uart_setup_hold	  :	 8;
-		bdrkreg_t	jbt_fprom_enable	  :	 8;
-		bdrkreg_t	jbt_fprom_setup_hold	  :	 8;
-	} md_junk_bus_timing_fld_s;
-} md_junk_bus_timing_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each of these addresses allows the value on one 8-bit bank of       *
- * LEDs to be read.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_led0_u {
-	bdrkreg_t	md_led0_regval;
-	struct  {
-		bdrkreg_t	l_data                    :	 8;
-		bdrkreg_t       l_reserved                :     56;
-	} md_led0_fld_s;
-} md_led0_u_t;
-
-#else
-
-typedef union md_led0_u {
-	bdrkreg_t	md_led0_regval;
-	struct	{
-		bdrkreg_t	l_reserved		  :	56;
-		bdrkreg_t	l_data			  :	 8;
-	} md_led0_fld_s;
-} md_led0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each of these addresses allows the value on one 8-bit bank of       *
- * LEDs to be read.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_led1_u {
-	bdrkreg_t	md_led1_regval;
-	struct  {
-		bdrkreg_t	l_data                    :	 8;
-		bdrkreg_t       l_reserved                :     56;
-	} md_led1_fld_s;
-} md_led1_u_t;
-
-#else
-
-typedef union md_led1_u {
-	bdrkreg_t	md_led1_regval;
-	struct	{
-		bdrkreg_t	l_reserved		  :	56;
-		bdrkreg_t	l_data			  :	 8;
-	} md_led1_fld_s;
-} md_led1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each of these addresses allows the value on one 8-bit bank of       *
- * LEDs to be read.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_led2_u {
-	bdrkreg_t	md_led2_regval;
-	struct  {
-		bdrkreg_t	l_data                    :	 8;
-		bdrkreg_t       l_reserved                :     56;
-	} md_led2_fld_s;
-} md_led2_u_t;
-
-#else
-
-typedef union md_led2_u {
-	bdrkreg_t	md_led2_regval;
-	struct	{
-		bdrkreg_t	l_reserved		  :	56;
-		bdrkreg_t	l_data			  :	 8;
-	} md_led2_fld_s;
-} md_led2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each of these addresses allows the value on one 8-bit bank of       *
- * LEDs to be read.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_led3_u {
-	bdrkreg_t	md_led3_regval;
-	struct  {
-		bdrkreg_t	l_data                    :	 8;
-		bdrkreg_t       l_reserved                :     56;
-	} md_led3_fld_s;
-} md_led3_u_t;
-
-#else
-
-typedef union md_led3_u {
-	bdrkreg_t	md_led3_regval;
-	struct	{
-		bdrkreg_t	l_reserved		  :	56;
-		bdrkreg_t	l_data			  :	 8;
-	} md_led3_fld_s;
-} md_led3_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Core control for the BIST function. Start and stop BIST at any      *
- * time.                                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_ctl_u {
-	bdrkreg_t	md_bist_ctl_regval;
-	struct  {
-		bdrkreg_t	bc_bist_start             :	 1;
-		bdrkreg_t       bc_bist_stop              :      1;
-		bdrkreg_t       bc_bist_reset             :      1;
-		bdrkreg_t       bc_reserved_1             :      1;
-		bdrkreg_t       bc_bank_num               :      1;
-		bdrkreg_t       bc_dimm_num               :      2;
-		bdrkreg_t       bc_reserved               :     57;
-	} md_bist_ctl_fld_s;
-} md_bist_ctl_u_t;
-
-#else
-
-typedef union md_bist_ctl_u {
-	bdrkreg_t	md_bist_ctl_regval;
-	struct	{
-		bdrkreg_t	bc_reserved		  :	57;
-		bdrkreg_t	bc_dimm_num		  :	 2;
-		bdrkreg_t	bc_bank_num		  :	 1;
-		bdrkreg_t	bc_reserved_1		  :	 1;
-		bdrkreg_t	bc_bist_reset		  :	 1;
-		bdrkreg_t	bc_bist_stop		  :	 1;
-		bdrkreg_t	bc_bist_start		  :	 1;
-	} md_bist_ctl_fld_s;
-} md_bist_ctl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contain the initial BIST data nibble and the 4-bit data control     *
- * field..                                                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_data_u {
-	bdrkreg_t	md_bist_data_regval;
-	struct  {
-		bdrkreg_t	bd_bist_data              :	 4;
-		bdrkreg_t	bd_bist_nibble		  :	 1;
-		bdrkreg_t       bd_bist_byte              :      1;
-		bdrkreg_t       bd_bist_cycle             :      1;
-		bdrkreg_t       bd_bist_write             :      1;
-		bdrkreg_t       bd_reserved               :     56;
-	} md_bist_data_fld_s;
-} md_bist_data_u_t;
-
-#else
-
-typedef union md_bist_data_u {
-	bdrkreg_t	md_bist_data_regval;
-	struct	{
-		bdrkreg_t	bd_reserved		  :	56;
-		bdrkreg_t	bd_bist_write		  :	 1;
-		bdrkreg_t	bd_bist_cycle		  :	 1;
-		bdrkreg_t	bd_bist_byte		  :	 1;
-		bdrkreg_t	bd_bist_nibble		  :	 1;
-		bdrkreg_t	bd_bist_data		  :	 4;
-	} md_bist_data_fld_s;
-} md_bist_data_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Captures the BIST error address and indicates whether it is an MB   *
- * error or DB error.                                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_ab_err_addr_u {
-	bdrkreg_t	md_bist_ab_err_addr_regval;
-	struct  {
-		bdrkreg_t	baea_be_db_cas_addr       :	15;
-		bdrkreg_t       baea_reserved_3           :      1;
-		bdrkreg_t       baea_be_mb_cas_addr       :     15;
-		bdrkreg_t       baea_reserved_2           :      1;
-		bdrkreg_t       baea_be_ras_addr          :     15;
-		bdrkreg_t       baea_reserved_1           :      1;
-		bdrkreg_t       baea_bist_mb_error        :      1;
-		bdrkreg_t       baea_bist_db_error        :      1;
-		bdrkreg_t       baea_reserved             :     14;
-	} md_bist_ab_err_addr_fld_s;
-} md_bist_ab_err_addr_u_t;
-
-#else
-
-typedef union md_bist_ab_err_addr_u {
-	bdrkreg_t	md_bist_ab_err_addr_regval;
-	struct	{
-		bdrkreg_t	baea_reserved		  :	14;
-		bdrkreg_t	baea_bist_db_error	  :	 1;
-		bdrkreg_t	baea_bist_mb_error	  :	 1;
-		bdrkreg_t	baea_reserved_1		  :	 1;
-		bdrkreg_t	baea_be_ras_addr	  :	15;
-		bdrkreg_t	baea_reserved_2		  :	 1;
-		bdrkreg_t	baea_be_mb_cas_addr	  :	15;
-		bdrkreg_t	baea_reserved_3		  :	 1;
-		bdrkreg_t	baea_be_db_cas_addr	  :	15;
-	} md_bist_ab_err_addr_fld_s;
-} md_bist_ab_err_addr_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains information on BIST progress and memory bank currently     *
- * under BIST.                                                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_status_u {
-	bdrkreg_t	md_bist_status_regval;
-	struct  {
-		bdrkreg_t	bs_bist_passed            :	 1;
-		bdrkreg_t       bs_bist_done              :      1;
-		bdrkreg_t       bs_reserved               :     62;
-	} md_bist_status_fld_s;
-} md_bist_status_u_t;
-
-#else
-
-typedef union md_bist_status_u {
-	bdrkreg_t	md_bist_status_regval;
-	struct	{
-		bdrkreg_t	bs_reserved		  :	62;
-		bdrkreg_t	bs_bist_done		  :	 1;
-		bdrkreg_t	bs_bist_passed		  :	 1;
-	} md_bist_status_fld_s;
-} md_bist_status_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains 3 bits that allow the selection of IB debug information    *
- * at the debug port (see design specification for available debug      *
- * information).                                                        *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_ib_debug_u {
-	bdrkreg_t	md_ib_debug_regval;
-	struct  {
-		bdrkreg_t	id_ib_debug_sel           :	 2;
-		bdrkreg_t       id_reserved               :     62;
-	} md_ib_debug_fld_s;
-} md_ib_debug_u_t;
-
-#else
-
-typedef union md_ib_debug_u {
-	bdrkreg_t	md_ib_debug_regval;
-	struct	{
-		bdrkreg_t	id_reserved		  :	62;
-		bdrkreg_t	id_ib_debug_sel		  :	 2;
-	} md_ib_debug_fld_s;
-} md_ib_debug_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the directory specific mode bits. The contents of this     *
- * register are preserved through soft-resets.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_dir_config_u {
-	bdrkreg_t	md_dir_config_regval;
-	struct  {
-		bdrkreg_t	dc_dir_flavor             :	 1;
-		bdrkreg_t       dc_ignore_dir_ecc         :      1;
-		bdrkreg_t       dc_reserved               :     62;
-	} md_dir_config_fld_s;
-} md_dir_config_u_t;
-
-#else
-
-typedef union md_dir_config_u {
-	bdrkreg_t	md_dir_config_regval;
-	struct	{
-		bdrkreg_t	dc_reserved		  :	62;
-		bdrkreg_t	dc_ignore_dir_ecc	  :	 1;
-		bdrkreg_t	dc_dir_flavor		  :	 1;
-	} md_dir_config_fld_s;
-} md_dir_config_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Contains information on uncorrectable and              *
- * correctable directory ECC errors, along with protection ECC          *
- * errors. The priority of ECC errors latched is: uncorrectable         *
- * directory, protection error, correctable directory. Thus the valid   *
- * bits signal:                                                         *
- * 1xxx: uncorrectable directory ECC error (UCE)                        *
- * 01xx: access protection double bit error (AE)                        *
- * 001x: correctable directory ECC error (CE)                           *
- * 0001: access protection correctable error (ACE)                      *
- * If the UCE valid bit is set, the address field contains a pointer    *
- * to the Hspec address of the offending directory entry, the           *
- * syndrome field contains the bad syndrome, and the UCE overrun bit    *
- * indicates whether multiple double-bit errors were received.          *
- * If the UCE valid bit is clear but the AE valid bit is set, the       *
- * address field contains a pointer to the Hspec address of the         *
- * offending protection entry, the Bad Protection field contains the    *
- * 4-bit bad protection value, the PROT_INDEX field shows which of      *
- * the 8 protection values in the word was bad and the AE overrun bit   *
- * indicates whether multiple AE errors were received.                  *
- * If the UCE and AE valid bits are clear, but the CE valid bit is      *
- * set, the address field contains a pointer to the Hspec address of    *
- * the offending directory entry, the syndrome field contains the bad   *
- * syndrome, and the CE overrun bit indicates whether multiple          *
- * single-bit errors were received.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_dir_error_u {
-	bdrkreg_t	md_dir_error_regval;
-	struct  {
-		bdrkreg_t	de_reserved_3             :	 3;
-		bdrkreg_t       de_hspec_addr             :     30;
-		bdrkreg_t       de_reserved_2             :      7;
-		bdrkreg_t       de_bad_syn                :      7;
-		bdrkreg_t       de_reserved_1             :      1;
-                bdrkreg_t       de_bad_protect            :      4;
-                bdrkreg_t       de_prot_index             :      3;
-                bdrkreg_t       de_reserved               :      1;
-                bdrkreg_t       de_ace_overrun            :      1;
-                bdrkreg_t       de_ce_overrun             :      1;
-                bdrkreg_t       de_ae_overrun             :      1;
-                bdrkreg_t       de_uce_overrun            :      1;
-                bdrkreg_t       de_ace_valid              :      1;
-                bdrkreg_t       de_ce_valid               :      1;
-                bdrkreg_t       de_ae_valid               :      1;
-                bdrkreg_t       de_uce_valid              :      1;
-	} md_dir_error_fld_s;
-} md_dir_error_u_t;
-
-#else
-
-typedef union md_dir_error_u {
-	bdrkreg_t	md_dir_error_regval;
-	struct	{
-		bdrkreg_t	de_uce_valid		  :	 1;
-		bdrkreg_t	de_ae_valid		  :	 1;
-		bdrkreg_t	de_ce_valid		  :	 1;
-		bdrkreg_t	de_ace_valid		  :	 1;
-		bdrkreg_t	de_uce_overrun		  :	 1;
-		bdrkreg_t	de_ae_overrun		  :	 1;
-		bdrkreg_t	de_ce_overrun		  :	 1;
-		bdrkreg_t	de_ace_overrun		  :	 1;
-		bdrkreg_t	de_reserved		  :	 1;
-		bdrkreg_t	de_prot_index		  :	 3;
-		bdrkreg_t	de_bad_protect		  :	 4;
-		bdrkreg_t	de_reserved_1		  :	 1;
-		bdrkreg_t	de_bad_syn		  :	 7;
-		bdrkreg_t	de_reserved_2		  :	 7;
-		bdrkreg_t	de_hspec_addr		  :	30;
-		bdrkreg_t	de_reserved_3		  :	 3;
-	} md_dir_error_fld_s;
-} md_dir_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Contains information on uncorrectable and              *
- * correctable directory ECC errors, along with protection ECC          *
- * errors. The priority of ECC errors latched is: uncorrectable         *
- * directory, protection error, correctable directory. Thus the valid   *
- * bits signal:                                                         *
- * 1xxx: uncorrectable directory ECC error (UCE)                        *
- * 01xx: access protection double bit error (AE)                        *
- * 001x: correctable directory ECC error (CE)                           *
- * 0001: access protection correctable error (ACE)                      *
- * If the UCE valid bit is set, the address field contains a pointer    *
- * to the Hspec address of the offending directory entry, the           *
- * syndrome field contains the bad syndrome, and the UCE overrun bit    *
- * indicates whether multiple double-bit errors were received.          *
- * If the UCE valid bit is clear but the AE valid bit is set, the       *
- * address field contains a pointer to the Hspec address of the         *
- * offending protection entry, the Bad Protection field contains the    *
- * 4-bit bad protection value, the PROT_INDEX field shows which of      *
- * the 8 protection values in the word was bad and the AE overrun bit   *
- * indicates whether multiple AE errors were received.                  *
- * If the UCE and AE valid bits are clear, but the CE valid bit is      *
- * set, the address field contains a pointer to the Hspec address of    *
- * the offending directory entry, the syndrome field contains the bad   *
- * syndrome, and the CE overrun bit indicates whether multiple          *
- * single-bit errors were received.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_dir_error_clr_u {
-	bdrkreg_t	md_dir_error_clr_regval;
-	struct  {
-		bdrkreg_t	dec_reserved_3            :	 3;
-                bdrkreg_t       dec_hspec_addr            :     30;
-                bdrkreg_t       dec_reserved_2            :      7;
-                bdrkreg_t       dec_bad_syn               :      7;
-                bdrkreg_t       dec_reserved_1            :      1;
-                bdrkreg_t       dec_bad_protect           :      4;
-                bdrkreg_t       dec_prot_index            :      3;
-                bdrkreg_t       dec_reserved              :      1;
-                bdrkreg_t       dec_ace_overrun           :      1;
-                bdrkreg_t       dec_ce_overrun            :      1;
-                bdrkreg_t       dec_ae_overrun            :      1;
-                bdrkreg_t       dec_uce_overrun           :      1;
-                bdrkreg_t       dec_ace_valid             :      1;
-                bdrkreg_t       dec_ce_valid              :      1;
-                bdrkreg_t       dec_ae_valid              :      1;
-                bdrkreg_t       dec_uce_valid             :      1;
-	} md_dir_error_clr_fld_s;
-} md_dir_error_clr_u_t;
-
-#else
-
-typedef union md_dir_error_clr_u {
-	bdrkreg_t	md_dir_error_clr_regval;
-	struct	{
-		bdrkreg_t	dec_uce_valid		  :	 1;
-		bdrkreg_t	dec_ae_valid		  :	 1;
-		bdrkreg_t	dec_ce_valid		  :	 1;
-		bdrkreg_t	dec_ace_valid		  :	 1;
-		bdrkreg_t	dec_uce_overrun		  :	 1;
-		bdrkreg_t	dec_ae_overrun		  :	 1;
-		bdrkreg_t	dec_ce_overrun		  :	 1;
-		bdrkreg_t	dec_ace_overrun		  :	 1;
-		bdrkreg_t	dec_reserved		  :	 1;
-		bdrkreg_t	dec_prot_index		  :	 3;
-		bdrkreg_t	dec_bad_protect		  :	 4;
-		bdrkreg_t	dec_reserved_1		  :	 1;
-		bdrkreg_t	dec_bad_syn		  :	 7;
-		bdrkreg_t	dec_reserved_2		  :	 7;
-		bdrkreg_t	dec_hspec_addr		  :	30;
-		bdrkreg_t	dec_reserved_3		  :	 3;
-	} md_dir_error_clr_fld_s;
-} md_dir_error_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains information on requests that encounter no valid protocol   *
- * table entry.                                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_protocol_error_u {
-	bdrkreg_t	md_protocol_error_regval;
-	struct  {
-		bdrkreg_t	pe_overrun                :	 1;
-                bdrkreg_t       pe_pointer_me             :      1;
-                bdrkreg_t       pe_reserved_1             :      1;
-                bdrkreg_t       pe_address                :     30;
-                bdrkreg_t       pe_reserved               :      1;
-                bdrkreg_t       pe_ptr1_btmbits           :      3;
-                bdrkreg_t       pe_dir_format             :      2;
-                bdrkreg_t       pe_dir_state              :      3;
-                bdrkreg_t       pe_priority               :      1;
-                bdrkreg_t       pe_access                 :      1;
-                bdrkreg_t       pe_msg_type               :      8;
-                bdrkreg_t       pe_initiator              :     11;
-                bdrkreg_t       pe_valid                  :      1;
-	} md_protocol_error_fld_s;
-} md_protocol_error_u_t;
-
-#else
-
-typedef union md_protocol_error_u {
-	bdrkreg_t	md_protocol_error_regval;
-	struct	{
-		bdrkreg_t	pe_valid		  :	 1;
-		bdrkreg_t	pe_initiator		  :	11;
-		bdrkreg_t	pe_msg_type		  :	 8;
-		bdrkreg_t	pe_access		  :	 1;
-		bdrkreg_t	pe_priority		  :	 1;
-		bdrkreg_t	pe_dir_state		  :	 3;
-		bdrkreg_t	pe_dir_format		  :	 2;
-		bdrkreg_t	pe_ptr1_btmbits		  :	 3;
-		bdrkreg_t	pe_reserved		  :	 1;
-		bdrkreg_t	pe_address		  :	30;
-		bdrkreg_t	pe_reserved_1		  :	 1;
-		bdrkreg_t	pe_pointer_me		  :	 1;
-		bdrkreg_t	pe_overrun		  :	 1;
-	} md_protocol_error_fld_s;
-} md_protocol_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains information on requests that encounter no valid protocol   *
- * table entry.                                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_protocol_err_clr_u {
-	bdrkreg_t	md_protocol_err_clr_regval;
-	struct  {
-		bdrkreg_t	pec_overrun               :	 1;
-                bdrkreg_t       pec_pointer_me            :      1;
-                bdrkreg_t       pec_reserved_1            :      1;
-                bdrkreg_t       pec_address               :     30;
-                bdrkreg_t       pec_reserved              :      1;
-                bdrkreg_t       pec_ptr1_btmbits          :      3;
-                bdrkreg_t       pec_dir_format            :      2;
-                bdrkreg_t       pec_dir_state             :      3;
-                bdrkreg_t       pec_priority              :      1;
-                bdrkreg_t       pec_access                :      1;
-                bdrkreg_t       pec_msg_type              :      8;
-                bdrkreg_t       pec_initiator             :     11;
-                bdrkreg_t       pec_valid                 :      1;
-	} md_protocol_err_clr_fld_s;
-} md_protocol_err_clr_u_t;
-
-#else
-
-typedef union md_protocol_err_clr_u {
-	bdrkreg_t	md_protocol_err_clr_regval;
-	struct	{
-		bdrkreg_t	pec_valid		  :	 1;
-		bdrkreg_t	pec_initiator		  :	11;
-		bdrkreg_t	pec_msg_type		  :	 8;
-		bdrkreg_t	pec_access		  :	 1;
-		bdrkreg_t	pec_priority		  :	 1;
-		bdrkreg_t	pec_dir_state		  :	 3;
-		bdrkreg_t	pec_dir_format		  :	 2;
-		bdrkreg_t	pec_ptr1_btmbits	  :	 3;
-		bdrkreg_t	pec_reserved		  :	 1;
-		bdrkreg_t	pec_address		  :	30;
-		bdrkreg_t	pec_reserved_1		  :	 1;
-		bdrkreg_t	pec_pointer_me		  :	 1;
-		bdrkreg_t	pec_overrun		  :	 1;
-	} md_protocol_err_clr_fld_s;
-} md_protocol_err_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the address of the page and the requestor which caused a   *
- * migration threshold to be exceeded. Also contains the type of        *
- * threshold exceeded and an overrun bit. For Value mode type           *
- * interrupts, it indicates whether the local or the remote counter     *
- * triggered the interrupt. Unlike most registers, when the overrun     *
- * bit is set the register contains information on the most recent      *
- * (the last) migration candidate.                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mig_candidate_u {
-	bdrkreg_t	md_mig_candidate_regval;
-	struct  {
-		bdrkreg_t	mc_address                :	21;
-                bdrkreg_t       mc_initiator              :     11;
-                bdrkreg_t       mc_overrun                :      1;
-                bdrkreg_t       mc_type                   :      1;
-                bdrkreg_t       mc_local                  :      1;
-                bdrkreg_t       mc_reserved               :     28;
-                bdrkreg_t       mc_valid                  :      1;
-	} md_mig_candidate_fld_s;
-} md_mig_candidate_u_t;
-
-#else
-
-typedef union md_mig_candidate_u {
-	bdrkreg_t	md_mig_candidate_regval;
-	struct	{
-		bdrkreg_t	mc_valid		  :	 1;
-		bdrkreg_t	mc_reserved		  :	28;
-		bdrkreg_t	mc_local		  :	 1;
-		bdrkreg_t	mc_type			  :	 1;
-		bdrkreg_t	mc_overrun		  :	 1;
-		bdrkreg_t	mc_initiator		  :	11;
-		bdrkreg_t	mc_address		  :	21;
-	} md_mig_candidate_fld_s;
-} md_mig_candidate_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the address of the page and the requestor which caused a   *
- * migration threshold to be exceeded. Also contains the type of        *
- * threshold exceeded and an overrun bit. For Value mode type           *
- * interrupts, it indicates whether the local or the remote counter     *
- * triggered the interrupt. Unlike most registers, when the overrun     *
- * bit is set the register contains information on the most recent      *
- * (the last) migration candidate.                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mig_candidate_clr_u {
-	bdrkreg_t	md_mig_candidate_clr_regval;
-	struct  {
-		bdrkreg_t	mcc_address               :	21;
-                bdrkreg_t       mcc_initiator             :     11;
-                bdrkreg_t       mcc_overrun               :      1;
-                bdrkreg_t       mcc_type                  :      1;
-                bdrkreg_t       mcc_local                 :      1;
-                bdrkreg_t       mcc_reserved              :     28;
-                bdrkreg_t       mcc_valid                 :      1;
-	} md_mig_candidate_clr_fld_s;
-} md_mig_candidate_clr_u_t;
-
-#else
-
-typedef union md_mig_candidate_clr_u {
-	bdrkreg_t	md_mig_candidate_clr_regval;
-	struct	{
-		bdrkreg_t	mcc_valid		  :	 1;
-		bdrkreg_t	mcc_reserved		  :	28;
-		bdrkreg_t	mcc_local		  :	 1;
-		bdrkreg_t	mcc_type		  :	 1;
-		bdrkreg_t	mcc_overrun		  :	 1;
-		bdrkreg_t	mcc_initiator		  :	11;
-		bdrkreg_t	mcc_address		  :	21;
-	} md_mig_candidate_clr_fld_s;
-} md_mig_candidate_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Controls the generation of page-migration interrupts and loading    *
- * of the MIGRATION_CANDIDATE register for pages which are using the    *
- * difference between the requestor and home counts. If the             *
- * difference is greater-than or equal to than the threshold            *
- * contained in the register, and the valid bit is set, the migration   *
- * candidate is loaded (and an interrupt generated if enabled by the    *
- * page migration mode).                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mig_diff_thresh_u {
-	bdrkreg_t	md_mig_diff_thresh_regval;
-	struct  {
-		bdrkreg_t	mdt_threshold             :	15;
-                bdrkreg_t       mdt_reserved_1            :     17;
-                bdrkreg_t       mdt_th_action             :      3;
-                bdrkreg_t       mdt_sat_action            :      3;
-                bdrkreg_t       mdt_reserved              :     25;
-                bdrkreg_t       mdt_valid                 :      1;
-	} md_mig_diff_thresh_fld_s;
-} md_mig_diff_thresh_u_t;
-
-#else
-
-typedef union md_mig_diff_thresh_u {
-	bdrkreg_t	md_mig_diff_thresh_regval;
-	struct	{
-		bdrkreg_t	mdt_valid		  :	 1;
-		bdrkreg_t	mdt_reserved		  :	25;
-		bdrkreg_t	mdt_sat_action		  :	 3;
-		bdrkreg_t	mdt_th_action		  :	 3;
-		bdrkreg_t	mdt_reserved_1		  :	17;
-		bdrkreg_t	mdt_threshold		  :	15;
-	} md_mig_diff_thresh_fld_s;
-} md_mig_diff_thresh_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Controls the generation of page-migration interrupts and loading    *
- * of the MIGRATION_CANDIDATE register for pages that are using the     *
- * absolute value of the requestor count. If the value is               *
- * greater-than or equal to the threshold contained in the register,    *
- * and the register valid bit is set, the migration candidate is        *
- * loaded and an interrupt generated. For the value mode of page        *
- * migration, there are two variations. In the first variation,         *
- * interrupts are only generated when the remote counter reaches the    *
- * threshold, not when the local counter reaches the threshold. In      *
- * the second mode, both the local counter and the remote counter       *
- * generate interrupts if they reach the threshold. This second mode    *
- * is useful for performance monitoring, to track the number of local   *
- * and remote references to a page. LOCAL_INT determines whether we     *
- * will generate interrupts when the local counter reaches the          *
- * threshold.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mig_value_thresh_u {
-	bdrkreg_t	md_mig_value_thresh_regval;
-	struct  {
-		bdrkreg_t	mvt_threshold             :	15;
-                bdrkreg_t       mvt_reserved_1            :     17;
-                bdrkreg_t       mvt_th_action             :      3;
-                bdrkreg_t       mvt_sat_action            :      3;
-                bdrkreg_t       mvt_reserved              :     24;
-                bdrkreg_t       mvt_local_int             :      1;
-                bdrkreg_t       mvt_valid                 :      1;
-	} md_mig_value_thresh_fld_s;
-} md_mig_value_thresh_u_t;
-
-#else
-
-typedef union md_mig_value_thresh_u {
-        bdrkreg_t       md_mig_value_thresh_regval;
-        struct  {
-                bdrkreg_t       mvt_valid                 :      1;
-                bdrkreg_t       mvt_local_int             :      1;
-                bdrkreg_t       mvt_reserved              :     24;
-                bdrkreg_t       mvt_sat_action            :      3;
-                bdrkreg_t       mvt_th_action             :      3;
-                bdrkreg_t       mvt_reserved_1            :     17;
-                bdrkreg_t       mvt_threshold             :     15;
-        } md_mig_value_thresh_fld_s;
-} md_mig_value_thresh_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the controls for the sizing of the three MOQH request      *
- * queues. The maximum (and default) value is 4. Queue sizes are in     *
- * flits. One header equals one flit.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_outgoing_rq_queue_size_u {
-	bdrkreg_t	md_outgoing_rq_queue_size_regval;
-	struct  {
-		bdrkreg_t	orqs_reserved_3           :	 8;
-                bdrkreg_t       orqs_moqh_p0_rq_size      :      3;
-                bdrkreg_t       orqs_reserved_2           :      5;
-                bdrkreg_t       orqs_moqh_p1_rq_size      :      3;
-                bdrkreg_t       orqs_reserved_1           :      5;
-                bdrkreg_t       orqs_moqh_np_rq_size      :      3;
-                bdrkreg_t       orqs_reserved             :     37;
-	} md_outgoing_rq_queue_size_fld_s;
-} md_outgoing_rq_queue_size_u_t;
-
-#else
-
-typedef union md_outgoing_rq_queue_size_u {
-	bdrkreg_t	md_outgoing_rq_queue_size_regval;
-	struct	{
-		bdrkreg_t	orqs_reserved		  :	37;
-		bdrkreg_t	orqs_moqh_np_rq_size	  :	 3;
-		bdrkreg_t	orqs_reserved_1		  :	 5;
-		bdrkreg_t	orqs_moqh_p1_rq_size	  :	 3;
-		bdrkreg_t	orqs_reserved_2		  :	 5;
-		bdrkreg_t	orqs_moqh_p0_rq_size	  :	 3;
-		bdrkreg_t	orqs_reserved_3		  :	 8;
-	} md_outgoing_rq_queue_size_fld_s;
-} md_outgoing_rq_queue_size_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the 32-bit directory word failing BIST.                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_db_err_data_u {
-	bdrkreg_t	md_bist_db_err_data_regval;
-	struct  {
-		bdrkreg_t	bded_db_er_d              :	32;
-		bdrkreg_t       bded_reserved             :     32;
-	} md_bist_db_err_data_fld_s;
-} md_bist_db_err_data_u_t;
-
-#else
-
-typedef union md_bist_db_err_data_u {
-	bdrkreg_t	md_bist_db_err_data_regval;
-	struct	{
-		bdrkreg_t	bded_reserved		  :	32;
-		bdrkreg_t	bded_db_er_d		  :	32;
-	} md_bist_db_err_data_fld_s;
-} md_bist_db_err_data_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains 2 bits that allow the selection of DB debug information    *
- * at the debug port (see the design specification for descrition of    *
- * the available debug information).                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_db_debug_u {
-	bdrkreg_t	md_db_debug_regval;
-	struct  {
-		bdrkreg_t	dd_db_debug_sel           :	 2;
-		bdrkreg_t       dd_reserved               :     62;
-	} md_db_debug_fld_s;
-} md_db_debug_u_t;
-
-#else
-
-typedef union md_db_debug_u {
-	bdrkreg_t	md_db_debug_regval;
-	struct	{
-		bdrkreg_t	dd_reserved		  :	62;
-		bdrkreg_t	dd_db_debug_sel		  :	 2;
-	} md_db_debug_fld_s;
-} md_db_debug_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the IgnoreECC bit. When this bit is set, all ECC errors    *
- * are ignored. ECC bits will still be generated on writebacks.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mb_ecc_config_u {
-	bdrkreg_t	md_mb_ecc_config_regval;
-	struct  {
-		bdrkreg_t	mec_ignore_dataecc        :	 1;
-		bdrkreg_t       mec_reserved              :     63;
-	} md_mb_ecc_config_fld_s;
-} md_mb_ecc_config_u_t;
-
-#else
-
-typedef union md_mb_ecc_config_u {
-	bdrkreg_t	md_mb_ecc_config_regval;
-	struct	{
-		bdrkreg_t	mec_reserved		  :	63;
-		bdrkreg_t	mec_ignore_dataecc	  :	 1;
-	} md_mb_ecc_config_fld_s;
-} md_mb_ecc_config_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Contains information on read memory errors (both       *
- * correctable and uncorrectable) and write memory errors (always       *
- * uncorrectable). The errors are prioritized as follows:               *
- *  highest: uncorrectable read error (READ_UCE)                        *
- *  middle: write error (WRITE_UCE)                                     *
- *  lowest: correctable read error (READ_CE)                            *
- * Each type of error maintains a two-bit valid/overrun field           *
- * (READ_UCE, WRITE_UCE, or READ_CE). Bit 0 of each two-bit field       *
- * corresponds to the valid bit, and bit 1 of each two-bit field        *
- * corresponds to the overrun bit.                                      *
- * The rule for the valid bit is that it gets set whenever that error   *
- * occurs, regardless of whether a higher priority error has occurred.  *
- * The rule for the overrun bit is that it gets set whenever we are     *
- * unable to record the address information for this particular         *
- * error, due to a previous error of the same or higher priority.       *
- * Note that the syndrome and address information always corresponds    *
- * to the earliest, highest priority error.                             *
- *  Finally, the UCE_DIFF_ADDR bit is set whenever there have been      *
- * several uncorrectable errors, to different cache line addresses.     *
- * If all the UCEs were to the same cache line address, then            *
- * UCE_DIFF_ADDR will be 0. This allows the operating system to         *
- * detect the case where a UCE error is read exclusively, and then      *
- * written back by the processor. If the bit is 0, it indicates that    *
- * no information has been lost about UCEs on other cache lines. In     *
- * particular, partial writes do a read modify write of the cache       *
- * line. A UCE read error will be set when the cache line is read,      *
- * and a UCE write error will occur when the cache line is written      *
- * back, but the UCE_DIFF_ADDR will not be set.                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mem_error_u {
-	bdrkreg_t	md_mem_error_regval;
-	struct  {
-		bdrkreg_t	me_reserved_5             :	 3;
-                bdrkreg_t       me_address                :     30;
-                bdrkreg_t       me_reserved_4             :      7;
-                bdrkreg_t       me_bad_syn                :      8;
-                bdrkreg_t       me_reserved_3             :      4;
-                bdrkreg_t       me_read_ce                :      2;
-                bdrkreg_t       me_reserved_2             :      2;
-                bdrkreg_t       me_write_uce              :      2;
-                bdrkreg_t       me_reserved_1             :      2;
-                bdrkreg_t       me_read_uce               :      2;
-                bdrkreg_t       me_reserved               :      1;
-                bdrkreg_t       me_uce_diff_addr          :      1;
-	} md_mem_error_fld_s;
-} md_mem_error_u_t;
-
-#else
-
-typedef union md_mem_error_u {
-	bdrkreg_t	md_mem_error_regval;
-	struct	{
-		bdrkreg_t	me_uce_diff_addr	  :	 1;
-		bdrkreg_t	me_reserved		  :	 1;
-		bdrkreg_t	me_read_uce		  :	 2;
-		bdrkreg_t	me_reserved_1		  :	 2;
-		bdrkreg_t	me_write_uce		  :	 2;
-		bdrkreg_t	me_reserved_2		  :	 2;
-		bdrkreg_t	me_read_ce		  :	 2;
-		bdrkreg_t	me_reserved_3		  :	 4;
-		bdrkreg_t	me_bad_syn		  :	 8;
-		bdrkreg_t	me_reserved_4		  :	 7;
-		bdrkreg_t	me_address		  :	30;
-		bdrkreg_t	me_reserved_5		  :	 3;
-	} md_mem_error_fld_s;
-} md_mem_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Contains information on read memory errors (both       *
- * correctable and uncorrectable) and write memory errors (always       *
- * uncorrectable). The errors are prioritized as follows:               *
- *  highest: uncorrectable read error (READ_UCE)                        *
- *  middle: write error (WRITE_UCE)                                     *
- *  lowest: correctable read error (READ_CE)                            *
- * Each type of error maintains a two-bit valid/overrun field           *
- * (READ_UCE, WRITE_UCE, or READ_CE). Bit 0 of each two-bit field       *
- * corresponds to the valid bit, and bit 1 of each two-bit field        *
- * corresponds to the overrun bit.                                      *
- * The rule for the valid bit is that it gets set whenever that error   *
- * occurs, regardless of whether a higher priority error has occurred.  *
- * The rule for the overrun bit is that it gets set whenever we are     *
- * unable to record the address information for this particular         *
- * error, due to a previous error of the same or higher priority.       *
- * Note that the syndrome and address information always corresponds    *
- * to the earliest, highest priority error.                             *
- *  Finally, the UCE_DIFF_ADDR bit is set whenever there have been      *
- * several uncorrectable errors, to different cache line addresses.     *
- * If all the UCEs were to the same cache line address, then            *
- * UCE_DIFF_ADDR will be 0. This allows the operating system to         *
- * detect the case where a UCE error is read exclusively, and then      *
- * written back by the processor. If the bit is 0, it indicates that    *
- * no information has been lost about UCEs on other cache lines. In     *
- * particular, partial writes do a read modify write of the cache       *
- * line. A UCE read error will be set when the cache line is read,      *
- * and a UCE write error will occur when the cache line is written      *
- * back, but the UCE_DIFF_ADDR will not be set.                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mem_error_clr_u {
-	bdrkreg_t	md_mem_error_clr_regval;
-	struct  {
-		bdrkreg_t	mec_reserved_5            :	 3;
-                bdrkreg_t       mec_address               :     30;
-                bdrkreg_t       mec_reserved_4            :      7;
-                bdrkreg_t       mec_bad_syn               :      8;
-                bdrkreg_t       mec_reserved_3            :      4;
-                bdrkreg_t       mec_read_ce               :      2;
-                bdrkreg_t       mec_reserved_2            :      2;
-                bdrkreg_t       mec_write_uce             :      2;
-                bdrkreg_t       mec_reserved_1            :      2;
-                bdrkreg_t       mec_read_uce              :      2;
-                bdrkreg_t       mec_reserved              :      1;
-                bdrkreg_t       mec_uce_diff_addr         :      1;
-	} md_mem_error_clr_fld_s;
-} md_mem_error_clr_u_t;
-
-#else
-
-typedef union md_mem_error_clr_u {
-	bdrkreg_t	md_mem_error_clr_regval;
-	struct	{
-		bdrkreg_t	mec_uce_diff_addr	  :	 1;
-		bdrkreg_t	mec_reserved		  :	 1;
-		bdrkreg_t	mec_read_uce		  :	 2;
-		bdrkreg_t	mec_reserved_1		  :	 2;
-		bdrkreg_t	mec_write_uce		  :	 2;
-		bdrkreg_t	mec_reserved_2		  :	 2;
-		bdrkreg_t	mec_read_ce		  :	 2;
-		bdrkreg_t	mec_reserved_3		  :	 4;
-		bdrkreg_t	mec_bad_syn		  :	 8;
-		bdrkreg_t	mec_reserved_4		  :	 7;
-		bdrkreg_t	mec_address		  :	30;
-		bdrkreg_t	mec_reserved_5		  :	 3;
-	} md_mem_error_clr_fld_s;
-} md_mem_error_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains one-quarter of the error memory line failing BIST.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_mb_err_data_0_u {
-	bdrkreg_t	md_bist_mb_err_data_0_regval;
-	struct  {
-		bdrkreg_t	bmed0_mb_er_d             :	36;
-		bdrkreg_t       bmed0_reserved            :     28;
-	} md_bist_mb_err_data_0_fld_s;
-} md_bist_mb_err_data_0_u_t;
-
-#else
-
-typedef union md_bist_mb_err_data_0_u {
-	bdrkreg_t	md_bist_mb_err_data_0_regval;
-	struct	{
-		bdrkreg_t	bmed0_reserved		  :	28;
-		bdrkreg_t	bmed0_mb_er_d		  :	36;
-	} md_bist_mb_err_data_0_fld_s;
-} md_bist_mb_err_data_0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains one-quarter of the error memory line failing BIST.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_mb_err_data_1_u {
-	bdrkreg_t	md_bist_mb_err_data_1_regval;
-	struct  {
-		bdrkreg_t	bmed1_mb_er_d             :	36;
-		bdrkreg_t       bmed1_reserved            :     28;
-	} md_bist_mb_err_data_1_fld_s;
-} md_bist_mb_err_data_1_u_t;
-
-#else
-
-typedef union md_bist_mb_err_data_1_u {
-	bdrkreg_t	md_bist_mb_err_data_1_regval;
-	struct	{
-		bdrkreg_t	bmed1_reserved		  :	28;
-		bdrkreg_t	bmed1_mb_er_d		  :	36;
-	} md_bist_mb_err_data_1_fld_s;
-} md_bist_mb_err_data_1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains one-quarter of the error memory line failing BIST.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_mb_err_data_2_u {
-	bdrkreg_t	md_bist_mb_err_data_2_regval;
-	struct  {
-		bdrkreg_t	bmed2_mb_er_d             :	36;
-		bdrkreg_t       bmed2_reserved            :     28;
-	} md_bist_mb_err_data_2_fld_s;
-} md_bist_mb_err_data_2_u_t;
-
-#else
-
-typedef union md_bist_mb_err_data_2_u {
-	bdrkreg_t	md_bist_mb_err_data_2_regval;
-	struct	{
-		bdrkreg_t	bmed2_reserved		  :	28;
-		bdrkreg_t	bmed2_mb_er_d		  :	36;
-	} md_bist_mb_err_data_2_fld_s;
-} md_bist_mb_err_data_2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains one-quarter of the error memory line failing BIST.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_mb_err_data_3_u {
-	bdrkreg_t	md_bist_mb_err_data_3_regval;
-	struct  {
-		bdrkreg_t	bmed3_mb_er_d             :	36;
-		bdrkreg_t       bmed3_reserved            :     28;
-	} md_bist_mb_err_data_3_fld_s;
-} md_bist_mb_err_data_3_u_t;
-
-#else
-
-typedef union md_bist_mb_err_data_3_u {
-	bdrkreg_t	md_bist_mb_err_data_3_regval;
-	struct	{
-		bdrkreg_t	bmed3_reserved		  :	28;
-		bdrkreg_t	bmed3_mb_er_d		  :	36;
-	} md_bist_mb_err_data_3_fld_s;
-} md_bist_mb_err_data_3_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains 1 bit that allow the selection of MB debug information     *
- * at the debug port (see the design specification for the available    *
- * debug information).                                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mb_debug_u {
-	bdrkreg_t	md_mb_debug_regval;
-	struct  {
-		bdrkreg_t	md_mb_debug_sel           :	 1;
-		bdrkreg_t       md_reserved               :     63;
-	} md_mb_debug_fld_s;
-} md_mb_debug_u_t;
-
-#else
-
-typedef union md_mb_debug_u {
-	bdrkreg_t	md_mb_debug_regval;
-	struct	{
-		bdrkreg_t	md_reserved		  :	63;
-		bdrkreg_t	md_mb_debug_sel		  :	 1;
-	} md_mb_debug_fld_s;
-} md_mb_debug_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBMD_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubmd_next.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubmd_next.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubmd_next.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubmd_next.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,812 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBMD_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBMD_NEXT_H
-
-/* XXX moved over from SN/SN0/hubmd.h -- each should be checked for SN1 */
-/* In fact, most of this stuff is wrong. Some is correct, such as
- * MD_PAGE_SIZE and MD_PAGE_NUM_SHFT.
- */
-
-#define MD_PERF_COUNTERS        6
-#define MD_PERF_SETS            6
-
-#define MD_SIZE_EMPTY           0       
-#define MD_SIZE_64MB            1       
-#define MD_SIZE_128MB           2       
-#define MD_SIZE_256MB           3
-#define MD_SIZE_512MB           4      
-#define MD_SIZE_1GB             5      
-
-#define MD_SIZE_BYTES(size)     ((size) == 0 ? 0 : 0x2000000L << (size))
-#define MD_SIZE_MBYTES(size)    ((size) == 0 ? 0 :   0x20       << (size))
-#define MD_NUM_ENABLED(_x)	((_x & 0x1) + ((_x >> 1) & 0x1) + \
-				((_x >> 2) & 0x1) + ((_x >> 3) & 0x1))
-
-
-/* Hardware page size and shift */
-
-#define MD_PAGE_SIZE            16384    /* Page size in bytes              */
-#define MD_PAGE_NUM_SHFT        14       /* Address to page number shift    */
-
-#define MMC_IO_PROT 		(UINT64_CAST 1 << 45)
-
-/* Register offsets from LOCAL_HUB or REMOTE_HUB */
-#define MD_PERF_SEL             0x210000 /* Select perf monitor events      */
-
-/* MD_MIG_VALUE_THRESH bit definitions */
-
-#define MD_MIG_VALUE_THRES_VALID_MASK (UINT64_CAST 0x1 << 63)
-#define MD_MIG_VALUE_THRES_VALUE_MASK (UINT64_CAST 0xfffff)
-
-/* MD_MIG_CANDIDATE bit definitions */
-
-#define MD_MIG_CANDIDATE_VALID_MASK (UINT64_CAST 0x1 << 63)
-#define MD_MIG_CANDIDATE_VALID_SHFT 63
-#define MD_MIG_CANDIDATE_TYPE_MASK (UINT64_CAST 0x1 << 30)
-#define MD_MIG_CANDIDATE_TYPE_SHFT 30
-#define MD_MIG_CANDIDATE_OVERRUN_MASK (UINT64_CAST 0x1 << 29)
-#define MD_MIG_CANDIDATE_OVERRUN_SHFT 29
-#define MD_MIG_CANDIDATE_NODEID_MASK (UINT64_CAST 0x1ff << 20)
-#define MD_MIG_CANDIDATE_NODEID_SHFT 20
-#define MD_MIG_CANDIDATE_ADDR_MASK (UINT64_CAST 0x3ffff)
-
-
-/* XXX protection and migration are completely revised on SN1.  On
-   SN0, the reference count and protection fields were accessed in the
-   same word, but on SN1 they reside at different addresses.  The
-   users of these macros will need to be rewritten.  Also, the MD page
-   size is 16K on SN1 but 4K on SN0.  */
-
-/* Premium SIMM protection entry shifts and masks. */
-
-#define MD_PPROT_SHFT           0                       /* Prot. field      */
-#define MD_PPROT_MASK           0xf
-#define MD_PPROT_REFCNT_SHFT    5                       /* Reference count  */
-#define MD_PPROT_REFCNT_WIDTH   0x7ffff
-#define MD_PPROT_REFCNT_MASK    (MD_PPROT_REFCNT_WIDTH << 5)
-
-#define MD_PPROT_IO_SHFT        8                       /* I/O Prot field   */
-
-/* Standard SIMM protection entry shifts and masks. */
-
-#define MD_SPROT_SHFT           0                       /* Prot. field      */
-#define MD_SPROT_MASK           0xf
-#define MD_SPROT_IO_SHFT	8
-#define MD_SPROT_REFCNT_SHFT    5                       /* Reference count  */
-#define MD_SPROT_REFCNT_WIDTH   0x7ff
-#define MD_SPROT_REFCNT_MASK    (MD_SPROT_REFCNT_WIDTH << 5)
-
-/* Migration modes used in protection entries */
-
-#define MD_PROT_MIGMD_IREL      (UINT64_CAST 0x3 << 3)
-#define MD_PROT_MIGMD_IABS      (UINT64_CAST 0x2 << 3)
-#define MD_PROT_MIGMD_PREL      (UINT64_CAST 0x1 << 3)
-#define MD_PROT_MIGMD_OFF       (UINT64_CAST 0x0 << 3)
-
-/*
- * Operations on Memory/Directory DIMM control register
- */
-
-#define DIRTYPE_PREMIUM 1
-#define DIRTYPE_STANDARD 0
-
-/*
- * Operations on page migration count difference and absolute threshold
- * registers
- */
-
-#define MD_MIG_VALUE_THRESH_GET(region) (                               \
-        REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH) &  \
-        MD_MIG_VALUE_THRES_VALUE_MASK)
-
-#define MD_MIG_VALUE_THRESH_SET(region, value) (                        \
-        REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH,                     \
-                MD_MIG_VALUE_THRES_VALID_MASK | (value)))
-
-#define MD_MIG_VALUE_THRESH_ENABLE(region) (                    \
-        REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH,                     \
-                REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH)             \
-                             | MD_MIG_VALUE_THRES_VALID_MASK))
-
-/*
- * Operations on page migration candidate register
- */
-
-#define MD_MIG_CANDIDATE_GET(my_region_id) ( \
-        REMOTE_HUB_L((my_region_id), MD_MIG_CANDIDATE_CLR))
-
-#define MD_MIG_CANDIDATE_HWPFN(value) ((value) & MD_MIG_CANDIDATE_ADDR_MASK)
-
-#define MD_MIG_CANDIDATE_NODEID(value) ( \
-        ((value) & MD_MIG_CANDIDATE_NODEID_MASK) >> MD_MIG_CANDIDATE_NODEID_SHFT)
-
-#define MD_MIG_CANDIDATE_TYPE(value) ( \
-        ((value) & MD_MIG_CANDIDATE_TYPE_MASK) >> MD_MIG_CANDIDATE_TYPE_SHFT)
-
-#define MD_MIG_CANDIDATE_VALID(value) ( \
-        ((value) & MD_MIG_CANDIDATE_VALID_MASK) >> MD_MIG_CANDIDATE_VALID_SHFT)
-
-/*
- * Macros to retrieve fields in the protection entry
- */
-
-/* for Premium SIMM */
-#define MD_PPROT_REFCNT_GET(value) ( \
-        ((value) & MD_PPROT_REFCNT_MASK) >> MD_PPROT_REFCNT_SHFT)
-
-/* for Standard SIMM */
-#define MD_SPROT_REFCNT_GET(value) ( \
-        ((value) & MD_SPROT_REFCNT_MASK) >> MD_SPROT_REFCNT_SHFT)
-
-#ifndef __ASSEMBLY__
-#ifdef LITTLE_ENDIAN
-
-typedef union md_perf_sel {
-        uint64_t      perf_sel_reg;
-        struct  {
-                uint64_t      perf_sel  :  3,
-				perf_en   :  1,
-				perf_rsvd : 60;
-        } perf_sel_bits;
-} md_perf_sel_t;
-
-#else
-
-typedef union md_perf_sel {
-	uint64_t	perf_sel_reg;
-	struct	{
-		uint64_t	perf_rsvd : 60,
-				perf_en	  :  1,
-				perf_sel  :  3;
-	} perf_sel_bits;
-} md_perf_sel_t;
-
-#endif
-#endif /* __ASSEMBLY__ */
-
-
-/* Like SN0, SN1 supports a mostly-flat address space with 8
-   CPU-visible, evenly spaced, contiguous regions, or "software
-   banks".  On SN1, software bank n begins at addresses n * 1GB, 
-   0 <= n < 8.
-
-   Physically (and very unlike SN0), each SN1 node board contains 8
-   dimm sockets, arranged as 4 "DIMM banks" of 2 dimms each.  DIMM
-   size and width (x4/x8) is assigned per dimm bank.  Each DIMM bank
-   consists of 2 "physical banks", one on the front sides of the 2
-   DIMMs and the other on the back sides.  Therefore a node has a
-   total of 8 ( = 4 * 2) physical banks.  They are collectively
-   referred to as "locational banks", since the locational bank number
-   depends on the physical location of the DIMMs on the board.
-
-	      Dimm bank 0, Phys bank 0a (locational bank 0a)
-     Slot D0  ----------------------------------------------
-	      Dimm bank 0, Phys bank 1a (locational bank 1a)
-
-	      Dimm bank 1, Phys bank 0a (locational bank 2a)
-     Slot D1  ----------------------------------------------
-	      Dimm bank 1, Phys bank 1a (locational bank 3a)
-
-	      Dimm bank 2, Phys bank 0a (locational bank 4a)
-     Slot D2  ----------------------------------------------
-	      Dimm bank 2, Phys bank 1a (locational bank 5a)
-
-	      Dimm bank 3, Phys bank 0a (locational bank 6a)
-     Slot D3  ----------------------------------------------
-	      Dimm bank 3, Phys bank 1a (locational bank 7a)
-
-	      Dimm bank 0, Phys bank 0b (locational bank 0b)
-     Slot D4  ----------------------------------------------
-	      Dimm bank 0, Phys bank 1b (locational bank 1b)
-
-	      Dimm bank 1, Phys bank 0b (locational bank 2b)
-     Slot D5  ----------------------------------------------
-	      Dimm bank 1, Phys bank 1b (locational bank 3b)
-
-	      Dimm bank 2, Phys bank 0b (locational bank 4b)
-     Slot D6  ----------------------------------------------
-	      Dimm bank 2, Phys bank 1b (locational bank 5b)
-
-	      Dimm bank 3, Phys bank 0b (locational bank 6b)
-     Slot D7  ----------------------------------------------
-	      Dimm bank 3, Phys bank 1b (locational bank 7b)
-
-   Since bank size is assigned per DIMM bank, each pair of locational
-   banks must have the same size.  However, they may be
-   enabled/disabled individually.
-
-   The locational banks map to the software banks via the dimm0_sel
-   field in MD_MEMORY_CONFIG.  When the field is 0 (the usual case),
-   the mapping is direct:  eg. locational bank 1 (dimm bank 0,
-   physical bank 1, which is the back side of the first DIMM pair)
-   corresponds to software bank 1, at node offset 1GB.  More
-   generally, locational bank = software bank XOR dimm0_sel.
-
-   All the PROM's data structures (promlog variables, klconfig, etc.)
-   track memory by the locational bank number.  The kernel usually
-   tracks memory by the software bank number.
-   memsupport.c:slot_psize_compute() performs the mapping.
-
-   (Note:  the terms "locational bank" and "software bank" are not
-   offical in any way, but I've tried to make the PROM use them
-   consistently -- bjj.)
- */
-
-#define MD_MEM_BANKS 		8
-#define MD_MEM_DIMM_BANKS 	4
-#define MD_BANK_SHFT            30                     /* log2(1 GB)     */
-#define MD_BANK_MASK            (UINT64_CAST 0x7 << 30)
-#define MD_BANK_SIZE            (UINT64_CAST 1 << MD_BANK_SHFT)   /*  1 GB */
-#define MD_BANK_OFFSET(_b)      (UINT64_CAST (_b) << MD_BANK_SHFT)
-#define MD_BANK_GET(addr)	(((addr) & MD_BANK_MASK) >> MD_BANK_SHFT)
-#define MD_BANK_TO_DIMM_BANK(_b) (( (_b) >> 1) & 0x3)
-#define MD_BANK_TO_PHYS_BANK(_b) (( (_b) >> 0) & 0x1)
-#define MD_DIMM_BANK_GET(addr)   MD_BANK_TO_DIMM_BANK(MD_BANK_GET(addr))
-#define MD_PHYS_BANK_GET(addr)   MD_BANK_TO_PHYS_BANK(MD_BANK_GET(addr))
-
-
-/* Split an MD pointer (or message source & suppl. fields) into node, device */
-
-#define MD_PTR_NODE_SHFT	3
-#define MD_PTR_DEVICE_MASK	0x7
-#define MD_PTR_SUBNODE0_MASK	0x1
-#define MD_PTR_SUBNODE1_MASK	0x4
-
-
-/**********************************************************************
-
- Backdoor protection and page counter structures
-
-**********************************************************************/
-
-/* Protection entries and page counters are interleaved at 4 separate
-   addresses, 0x10 apart.  Software must read/write all four. */
-
-#define BD_ITLV_COUNT		4
-#define BD_ITLV_STRIDE		0x10
-
-/* Protection entries */
-
-/* (these macros work for standard (_rgn < 32) or premium DIMMs) */
-#define MD_PROT_SHFT(_rgn, _io)	((((_rgn) & 0x20) >> 2 | \
-				  ((_rgn) & 0x01) << 2 | \
-				  ((_io)  &  0x1) << 1) * 8)
-#define MD_PROT_MASK(_rgn, _io)	(0xff << MD_PROT_SHFT(_rgn, _io))
-#define MD_PROT_GET(_val, _rgn, _io) \
-	(((_val) & MD_PROT_MASK(_rgn, _io)) >> MD_PROT_SHFT(_rgn, _io))
-
-/* Protection field values */
-
-#define MD_PROT_RW              (UINT64_CAST 0xff)
-#define MD_PROT_RO              (UINT64_CAST 0x0f)
-#define MD_PROT_NO              (UINT64_CAST 0x00)
-
-
-
-
-/**********************************************************************
-
- Directory format structures
-
-***********************************************************************/
-
-#ifndef __ASSEMBLY__
-
-/* Standard Directory Entries */
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_sdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */
-	bdrkreg_t	sdp_format                :	 2;
-        bdrkreg_t       sdp_state                 :      3;
-        bdrkreg_t       sdp_priority              :      3;
-        bdrkreg_t       sdp_pointer1              :      8;
-        bdrkreg_t       sdp_ecc                   :      6;
-        bdrkreg_t       sdp_locprot               :      1;
-        bdrkreg_t       sdp_reserved              :      1;
-        bdrkreg_t       sdp_crit_word_off         :      3;
-        bdrkreg_t       sdp_pointer2              :      5;
-        bdrkreg_t       sdp_fill                  :     32;
-};
-
-#else
-
-struct	md_sdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */
-	bdrkreg_t	sdp_fill		  :	32;
-	bdrkreg_t	sdp_pointer2		  :	 5;
-	bdrkreg_t	sdp_crit_word_off	  :	 3;
-	bdrkreg_t	sdp_reserved		  :	 1;
-	bdrkreg_t	sdp_locprot		  :	 1;
-	bdrkreg_t	sdp_ecc			  :	 6;
-	bdrkreg_t	sdp_pointer1		  :	 8;
-	bdrkreg_t	sdp_priority		  :	 3;
-	bdrkreg_t	sdp_state		  :	 3;
-	bdrkreg_t	sdp_format		  :	 2;
-};
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_sdir_fine_fmt { /* shared (fine) */
-	bdrkreg_t	sdf_format                :	 2;
-        bdrkreg_t       sdf_tag1                  :      3;
-        bdrkreg_t       sdf_tag2                  :      3;
-        bdrkreg_t       sdf_vector1               :      8;
-        bdrkreg_t       sdf_ecc                   :      6;
-        bdrkreg_t       sdf_locprot               :      1;
-        bdrkreg_t       sdf_tag2valid             :      1;
-        bdrkreg_t       sdf_vector2               :      8;
-        bdrkreg_t       sdf_fill                  :     32;
-};
-
-#else
-
-struct	md_sdir_fine_fmt { /* shared (fine) */
-	bdrkreg_t	sdf_fill		  :	32;
-	bdrkreg_t	sdf_vector2		  :	 8;
-	bdrkreg_t	sdf_tag2valid		  :	 1;
-	bdrkreg_t	sdf_locprot		  :	 1;
-	bdrkreg_t	sdf_ecc			  :	 6;
-	bdrkreg_t	sdf_vector1		  :	 8;
-	bdrkreg_t	sdf_tag2		  :	 3;
-	bdrkreg_t	sdf_tag1		  :	 3;
-	bdrkreg_t	sdf_format		  :	 2;
-};
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_sdir_coarse_fmt { /* shared (coarse) */
-	bdrkreg_t	sdc_format                :	 2;
-        bdrkreg_t       sdc_reserved_1            :      6;
-        bdrkreg_t       sdc_vector_a              :      8;
-        bdrkreg_t       sdc_ecc                   :      6;
-        bdrkreg_t       sdc_locprot               :      1;
-        bdrkreg_t       sdc_reserved              :      1;
-        bdrkreg_t       sdc_vector_b              :      8;
-        bdrkreg_t       sdc_fill                  :     32;
-};
-
-#else
-
-struct	md_sdir_coarse_fmt { /* shared (coarse) */
-	bdrkreg_t	sdc_fill		  :	32;
-	bdrkreg_t	sdc_vector_b		  :	 8;
-	bdrkreg_t	sdc_reserved		  :	 1;
-	bdrkreg_t	sdc_locprot		  :	 1;
-	bdrkreg_t	sdc_ecc			  :	 6;
-	bdrkreg_t	sdc_vector_a		  :	 8;
-	bdrkreg_t	sdc_reserved_1		  :	 6;
-	bdrkreg_t	sdc_format		  :	 2;
-};
-
-#endif
-
-typedef union md_sdir {
-	/* The 32 bits of standard directory, in bits 31:0 */
-	uint64_t	sd_val;
-	struct	md_sdir_pointer_fmt	sdp_fmt;
-	struct	md_sdir_fine_fmt	sdf_fmt;
-	struct	md_sdir_coarse_fmt	sdc_fmt;
-} md_sdir_t;
-
-
-/* Premium Directory Entries */
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_pdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */
-	bdrkreg_t	pdp_format                :	 2;
-        bdrkreg_t       pdp_state                 :      3;
-        bdrkreg_t       pdp_priority              :      3;
-        bdrkreg_t       pdp_pointer1_a            :      8;
-        bdrkreg_t       pdp_reserved_4            :      6;
-        bdrkreg_t       pdp_pointer1_b            :      3;
-        bdrkreg_t       pdp_reserved_3            :      7;
-        bdrkreg_t       pdp_ecc_a                 :      6;
-        bdrkreg_t       pdp_locprot               :      1;
-        bdrkreg_t       pdp_reserved_2            :      1;
-        bdrkreg_t       pdp_crit_word_off         :      3;
-        bdrkreg_t       pdp_pointer2_a            :      5;
-        bdrkreg_t       pdp_ecc_b                 :      1;
-        bdrkreg_t       pdp_reserved_1            :      5;
-        bdrkreg_t       pdp_pointer2_b            :      3;
-        bdrkreg_t       pdp_reserved              :      7;
-};
-
-#else
-
-struct	md_pdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */
-	bdrkreg_t	pdp_reserved		  :	 7;
-	bdrkreg_t	pdp_pointer2_b		  :	 3;
-	bdrkreg_t	pdp_reserved_1		  :	 5;
-	bdrkreg_t	pdp_ecc_b		  :	 1;
-	bdrkreg_t	pdp_pointer2_a		  :	 5;
-	bdrkreg_t	pdp_crit_word_off	  :	 3;
-	bdrkreg_t	pdp_reserved_2		  :	 1;
-	bdrkreg_t	pdp_locprot		  :	 1;
-	bdrkreg_t	pdp_ecc_a		  :	 6;
-	bdrkreg_t	pdp_reserved_3		  :	 7;
-	bdrkreg_t	pdp_pointer1_b		  :	 3;
-	bdrkreg_t	pdp_reserved_4		  :	 6;
-	bdrkreg_t	pdp_pointer1_a		  :	 8;
-	bdrkreg_t	pdp_priority		  :	 3;
-	bdrkreg_t	pdp_state		  :	 3;
-	bdrkreg_t	pdp_format		  :	 2;
-};
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_pdir_fine_fmt { /* shared (fine) */
-	bdrkreg_t	pdf_format                :	 2;
-        bdrkreg_t       pdf_tag1_a                :      3;
-        bdrkreg_t       pdf_tag2_a                :      3;
-        bdrkreg_t       pdf_vector1_a             :      8;
-        bdrkreg_t       pdf_reserved_1            :      6;
-        bdrkreg_t       pdf_tag1_b                :      2;
-        bdrkreg_t       pdf_vector1_b             :      8;
-        bdrkreg_t       pdf_ecc_a                 :      6;
-        bdrkreg_t       pdf_locprot               :      1;
-        bdrkreg_t       pdf_tag2valid             :      1;
-        bdrkreg_t       pdf_vector2_a             :      8;
-        bdrkreg_t       pdf_ecc_b                 :      1;
-        bdrkreg_t       pdf_reserved              :      5;
-        bdrkreg_t       pdf_tag2_b                :      2;
-        bdrkreg_t       pdf_vector2_b             :      8;
-};
-
-#else
-
-struct	md_pdir_fine_fmt { /* shared (fine) */
-	bdrkreg_t	pdf_vector2_b		  :	 8;
-	bdrkreg_t	pdf_tag2_b		  :	 2;
-	bdrkreg_t	pdf_reserved		  :	 5;
-	bdrkreg_t	pdf_ecc_b		  :	 1;
-	bdrkreg_t	pdf_vector2_a		  :	 8;
-	bdrkreg_t	pdf_tag2valid		  :	 1;
-	bdrkreg_t	pdf_locprot		  :	 1;
-	bdrkreg_t	pdf_ecc_a		  :	 6;
-	bdrkreg_t	pdf_vector1_b		  :	 8;
-	bdrkreg_t	pdf_tag1_b		  :	 2;
-	bdrkreg_t	pdf_reserved_1		  :	 6;
-	bdrkreg_t	pdf_vector1_a		  :	 8;
-	bdrkreg_t	pdf_tag2_a		  :	 3;
-	bdrkreg_t	pdf_tag1_a		  :	 3;
-	bdrkreg_t	pdf_format		  :	 2;
-};
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_pdir_sparse_fmt { /* shared (sparse) */
-	bdrkreg_t	pds_format                :	 2;
-        bdrkreg_t       pds_column_a              :      6;
-        bdrkreg_t       pds_row_a                 :      8;
-        bdrkreg_t       pds_column_b              :     16;
-        bdrkreg_t       pds_ecc_a                 :      6;
-        bdrkreg_t       pds_locprot               :      1;
-        bdrkreg_t       pds_reserved_1            :      1;
-        bdrkreg_t       pds_row_b                 :      8;
-        bdrkreg_t       pds_ecc_b                 :      1;
-        bdrkreg_t       pds_column_c              :     10;
-        bdrkreg_t       pds_reserved              :      5;
-};
-
-#else
-
-struct	md_pdir_sparse_fmt { /* shared (sparse) */
-	bdrkreg_t	pds_reserved		  :	 5;
-	bdrkreg_t	pds_column_c		  :	10;
-	bdrkreg_t	pds_ecc_b		  :	 1;
-	bdrkreg_t	pds_row_b		  :	 8;
-	bdrkreg_t	pds_reserved_1		  :	 1;
-	bdrkreg_t	pds_locprot		  :	 1;
-	bdrkreg_t	pds_ecc_a		  :	 6;
-	bdrkreg_t	pds_column_b		  :	16;
-	bdrkreg_t	pds_row_a		  :	 8;
-	bdrkreg_t	pds_column_a		  :	 6;
-	bdrkreg_t	pds_format		  :	 2;
-};
-
-#endif
-
-typedef union md_pdir {
-	/* The 64 bits of premium directory */
-	uint64_t	pd_val;
-	struct	md_pdir_pointer_fmt	pdp_fmt;
-	struct	md_pdir_fine_fmt	pdf_fmt;
-	struct	md_pdir_sparse_fmt	pds_fmt;
-} md_pdir_t;
-
-#endif /* __ASSEMBLY__ */
-
-
-/**********************************************************************
-
- The defines for backdoor directory and backdoor ECC.
-
-***********************************************************************/
-
-/* Directory formats, for each format's "format" field */
-
-#define MD_FORMAT_UNOWNED	(UINT64_CAST 0x0)	/* 00 */
-#define MD_FORMAT_POINTER	(UINT64_CAST 0x1)	/* 01 */
-#define MD_FORMAT_SHFINE	(UINT64_CAST 0x2)	/* 10 */
-#define MD_FORMAT_SHCOARSE	(UINT64_CAST 0x3)	/* 11 */
-  /* Shared coarse (standard) and shared sparse (premium) both use fmt 0x3 */
-
-
-/*
- * Cacheline state values.
- *
- * These are really *software* notions of the "state" of a cacheline; but the
- * actual values have been carefully chosen to align with some hardware values!
- * The MD_FMT_ST_TO_STATE macro is used to convert from hardware format/state
- * pairs in the directory entried into one of these cacheline state values.
- */
-
-#define MD_DIR_EXCLUSIVE	(UINT64_CAST 0x0)	/* ptr format, hw-defined */
-#define MD_DIR_UNOWNED		(UINT64_CAST 0x1)	/* format=0 */
-#define MD_DIR_SHARED		(UINT64_CAST 0x2)	/* format=2,3 */
-#define MD_DIR_BUSY_SHARED	(UINT64_CAST 0x4)	/* ptr format, hw-defined */
-#define MD_DIR_BUSY_EXCL	(UINT64_CAST 0x5)	/* ptr format, hw-defined */
-#define MD_DIR_WAIT		(UINT64_CAST 0x6)	/* ptr format, hw-defined */
-#define MD_DIR_POISONED		(UINT64_CAST 0x7)	/* ptr format, hw-defined */
-
-#ifndef __ASSEMBLY__
-
-/* Convert format and state fields into a single "cacheline state" value, defined above */
-
-#define MD_FMT_ST_TO_STATE(fmt, state) \
-  ((fmt) == MD_FORMAT_POINTER ? (state) : \
-   (fmt) == MD_FORMAT_UNOWNED ? MD_DIR_UNOWNED : \
-   MD_DIR_SHARED)
-#define MD_DIR_STATE(x) MD_FMT_ST_TO_STATE(MD_DIR_FORMAT(x), MD_DIR_STVAL(x))
-
-#endif /* __ASSEMBLY__ */
-
-
-
-/* Directory field shifts and masks */
-
-/* Standard */
-
-#define MD_SDIR_FORMAT_SHFT	0			/* All formats */
-#define MD_SDIR_FORMAT_MASK	(0x3 << 0)
-#define MD_SDIR_STATE_SHFT	2			/* Pointer fmt. only */
-#define MD_SDIR_STATE_MASK	(0x7 << 2)
-
-/* Premium */
-
-#define MD_PDIR_FORMAT_SHFT	0			/* All formats */
-#define MD_PDIR_FORMAT_MASK	(0x3 << 0)
-#define MD_PDIR_STATE_SHFT	2			/* Pointer fmt. only */
-#define MD_PDIR_STATE_MASK	(0x7 << 2)
-
-/* Generic */
-
-#define MD_FORMAT_SHFT	0				/* All formats */
-#define MD_FORMAT_MASK	(0x3 << 0)
-#define MD_STATE_SHFT	2				/* Pointer fmt. only */
-#define MD_STATE_MASK	(0x7 << 2)
-
-
-/* Special shifts to reconstruct fields from the _a and _b parts */
-
-/* Standard:  only shared coarse has split fields */
-
-#define MD_SDC_VECTORB_SHFT	8	/* eg: sdc_vector_a is 8 bits */
-
-/* Premium:  pointer, shared fine, shared sparse */
-
-#define MD_PDP_POINTER1A_MASK	0xFF
-#define MD_PDP_POINTER1B_SHFT	8
-#define MD_PDP_POINTER2B_SHFT	5
-#define MD_PDP_ECCB_SHFT	6
-
-#define MD_PDF_VECTOR1B_SHFT	8
-#define MD_PDF_VECTOR2B_SHFT	8
-#define MD_PDF_TAG1B_SHFT	3
-#define MD_PDF_TAG2B_SHFT	3
-#define MD_PDF_ECC_SHFT		6
-
-#define MD_PDS_ROWB_SHFT	8
-#define MD_PDS_COLUMNB_SHFT	6
-#define MD_PDS_COLUMNC_SHFT	(MD_PDS_COLUMNB_SHFT + 16)
-#define MD_PDS_ECC_SHFT		6
-
-
-
-/*
- * Directory/protection/counter initialization values, premium and standard
- */
-
-#define MD_PDIR_INIT		0
-#define MD_PDIR_INIT_CNT	0
-#define MD_PDIR_INIT_PROT	0
-
-#define MD_SDIR_INIT		0
-#define MD_SDIR_INIT_CNT	0
-#define MD_SDIR_INIT_PROT	0
-
-#define MD_PDIR_MASK            0xffffffffffffffff
-#define MD_SDIR_MASK            0xffffffff
-
-/* When premium mode is on for probing but standard directory memory
-   is installed, the valid directory bits depend on the phys. bank */
-#define MD_PDIR_PROBE_MASK(pb)  0xffffffffffffffff
-#define MD_SDIR_PROBE_MASK(pb)  (0xffff0000ffff << ((pb) ? 16 : 0))
-
-
-/*
- * Misc. field extractions and conversions
- */
-
-/* Convert an MD pointer (or message source, supplemental fields) */
-
-#define MD_PTR_NODE(x)		((x) >> MD_PTR_NODE_SHFT)
-#define MD_PTR_DEVICE(x)	((x) & MD_PTR_DEVICE_MASK)
-#define MD_PTR_SLICE(x)		(((x) & MD_PTR_SUBNODE0_MASK) | \
-				 ((x) & MD_PTR_SUBNODE1_MASK) >> 1)
-#define MD_PTR_OWNER_CPU(x)	(! ((x) & 2))
-#define MD_PTR_OWNER_IO(x)	((x) & 2)
-
-/* Extract format and raw state from a directory entry */
-
-#define MD_DIR_FORMAT(x)	((x) >> MD_SDIR_FORMAT_SHFT & \
-				 MD_SDIR_FORMAT_MASK >> MD_SDIR_FORMAT_SHFT)
-#define MD_DIR_STVAL(x)		((x) >> MD_SDIR_STATE_SHFT & \
-				 MD_SDIR_STATE_MASK >> MD_SDIR_STATE_SHFT)
-
-/* Mask & Shift to get HSPEC_ADDR from MD DIR_ERROR register */
-#define ERROR_ADDR_SHFT         3
-#define ERROR_HSPEC_SHFT        3
-#define DIR_ERR_HSPEC_MASK      0x1fffffff8
-
-/*
- *  DIR_ERR* and MEM_ERR* defines are used to avoid ugly
- *  #ifdefs for SN0 and SN1 in memerror.c code.  See SN0/hubmd.h
- *  for corresponding SN0 definitions.
- */
-#define md_dir_error_t  md_dir_error_u_t
-#define md_mem_error_t  md_mem_error_u_t
-#define derr_reg        md_dir_error_regval
-#define merr_reg        md_mem_error_regval
-
-#define DIR_ERR_UCE_VALID       dir_err.md_dir_error_fld_s.de_uce_valid
-#define DIR_ERR_AE_VALID        dir_err.md_dir_error_fld_s.de_ae_valid
-#define DIR_ERR_BAD_SYN         dir_err.md_dir_error_fld_s.de_bad_syn
-#define DIR_ERR_CE_OVERRUN      dir_err.md_dir_error_fld_s.de_ce_overrun
-#define MEM_ERR_ADDRESS         mem_err.md_mem_error_fld_s.me_address
-        /* BRINGUP Can the overrun bit be set without the valid bit? */
-#define MEM_ERR_CE_OVERRUN      (mem_err.md_mem_error_fld_s.me_read_ce >> 1)
-#define MEM_ERR_BAD_SYN         mem_err.md_mem_error_fld_s.me_bad_syn
-#define MEM_ERR_UCE_VALID       (mem_err.md_mem_error_fld_s.me_read_uce & 1)
-
-
-
-/*********************************************************************
-
- We have the shift and masks of various fields defined below.
-
- *********************************************************************/
-
-/* MD_REFRESH_CONTROL fields */
-
-#define MRC_ENABLE_SHFT         63
-#define MRC_ENABLE_MASK         (UINT64_CAST 1 << 63)
-#define MRC_ENABLE              (UINT64_CAST 1 << 63)
-#define MRC_COUNTER_SHFT        12
-#define MRC_COUNTER_MASK        (UINT64_CAST 0xfff << 12)
-#define MRC_CNT_THRESH_MASK     0xfff
-#define MRC_RESET_DEFAULTS      (UINT64_CAST 0x800)
-
-/* MD_DIR_CONFIG fields */
-
-#define MDC_DIR_PREMIUM		(UINT64_CAST 1 << 0)
-#define MDC_IGNORE_ECC_SHFT      1
-#define MDC_IGNORE_ECC_MASK     (UINT64_CAST 1 << 1)
-
-/* MD_MEMORY_CONFIG fields */
-
-#define MMC_RP_CONFIG_SHFT	61
-#define MMC_RP_CONFIG_MASK	(UINT64_CAST 1 << 61)
-#define MMC_RCD_CONFIG_SHFT	60
-#define MMC_RCD_CONFIG_MASK	(UINT64_CAST 1 << 60)
-#define MMC_MB_NEG_EDGE_SHFT	56
-#define MMC_MB_NEG_EDGE_MASK	(UINT64_CAST 0x7 << 56)
-#define MMC_SAMPLE_TIME_SHFT	52
-#define MMC_SAMPLE_TIME_MASK	(UINT64_CAST 0x3 << 52)
-#define MMC_DELAY_MUX_SEL_SHFT	50
-#define MMC_DELAY_MUX_SEL_MASK	(UINT64_CAST 0x3 << 50)
-#define MMC_PHASE_DELAY_SHFT	49
-#define MMC_PHASE_DELAY_MASK	(UINT64_CAST 1 << 49)
-#define MMC_DB_NEG_EDGE_SHFT	48
-#define MMC_DB_NEG_EDGE_MASK	(UINT64_CAST 1 << 48)
-#define MMC_CPU_PROT_IGNORE_SHFT	 47
-#define MMC_CPU_PROT_IGNORE_MASK	(UINT64_CAST 1 << 47)
-#define MMC_IO_PROT_IGNORE_SHFT 46
-#define MMC_IO_PROT_IGNORE_MASK	(UINT64_CAST 1 << 46)
-#define MMC_IO_PROT_EN_SHFT	45
-#define MMC_IO_PROT_EN_MASK	(UINT64_CAST 1 << 45)
-#define MMC_CC_ENABLE_SHFT	44
-#define MMC_CC_ENABLE_MASK	(UINT64_CAST 1 << 44)
-#define MMC_DIMM0_SEL_SHFT	32
-#define MMC_DIMM0_SEL_MASK     (UINT64_CAST 0x3 << 32)
-#define MMC_DIMM_SIZE_SHFT(_dimm)    ((_dimm << 3) + 4)
-#define MMC_DIMM_SIZE_MASK(_dimm)    (UINT64_CAST 0xf << MMC_DIMM_SIZE_SHFT(_dimm))
-#define MMC_DIMM_WIDTH_SHFT(_dimm)    ((_dimm << 3) + 3)
-#define MMC_DIMM_WIDTH_MASK(_dimm)    (UINT64_CAST 0x1 << MMC_DIMM_WIDTH_SHFT(_dimm))
-#define MMC_DIMM_BANKS_SHFT(_dimm)    (_dimm << 3)
-#define MMC_DIMM_BANKS_MASK(_dimm)    (UINT64_CAST 0x3 << MMC_DIMM_BANKS_SHFT(_dimm))
-#define MMC_BANK_ALL_MASK	0xffffffffLL
-/* Default values for write-only bits in MD_MEMORY_CONFIG */
-#define MMC_DEFAULT_BITS	(UINT64_CAST 0x7 << MMC_MB_NEG_EDGE_SHFT)
-
-/* MD_MB_ECC_CONFIG fields */
-
-#define MEC_IGNORE_ECC		(UINT64_CAST 0x1 << 0)
-
-/* MD_BIST_DATA fields */
-
-#define MBD_BIST_WRITE		(UINT64_CAST 1 << 7)
-#define MBD_BIST_CYCLE		(UINT64_CAST 1 << 6)
-#define MBD_BIST_BYTE		(UINT64_CAST 1 << 5)
-#define MBD_BIST_NIBBLE		(UINT64_CAST 1 << 4)
-#define MBD_BIST_DATA_MASK	0xf
-
-/* MD_BIST_CTL fields */
-
-#define MBC_DIMM_SHFT		5
-#define MBC_DIMM_MASK		(UINT64_CAST 0x3 << 5)
-#define MBC_BANK_SHFT		4
-#define MBC_BANK_MASK		(UINT64_CAST 0x1 << 4)
-#define MBC_BIST_RESET		(UINT64_CAST 0x1 << 2)
-#define MBC_BIST_STOP		(UINT64_CAST 0x1 << 1)
-#define MBC_BIST_START		(UINT64_CAST 0x1 << 0)
-
-#define MBC_GO(dimm, bank) \
-    (((dimm) << MBC_DIMM_SHFT) & MBC_DIMM_MASK | \
-     ((bank) << MBC_BANK_SHFT) & MBC_BANK_MASK | \
-     MBC_BIST_START)
-
-/* MD_BIST_STATUS fields */
-
-#define MBS_BIST_DONE		(UINT64_CAST 0X1 << 1)
-#define MBS_BIST_PASSED		(UINT64_CAST 0X1 << 0)
-
-/* MD_JUNK_BUS_TIMING fields */
-
-#define MJT_SYNERGY_ENABLE_SHFT	40
-#define MJT_SYNERGY_ENABLE_MASK	(UINT64_CAST 0Xff << MJT_SYNERGY_ENABLE_SHFT)
-#define MJT_SYNERGY_SETUP_SHFT	32
-#define MJT_SYNERGY_SETUP_MASK	(UINT64_CAST 0Xff << MJT_SYNERGY_SETUP_SHFT)
-#define MJT_UART_ENABLE_SHFT	24
-#define MJT_UART_ENABLE_MASK	(UINT64_CAST 0Xff << MJT_UART_ENABLE_SHFT)
-#define MJT_UART_SETUP_SHFT	16
-#define MJT_UART_SETUP_MASK	(UINT64_CAST 0Xff << MJT_UART_SETUP_SHFT)
-#define MJT_FPROM_ENABLE_SHFT	8
-#define MJT_FPROM_ENABLE_MASK	(UINT64_CAST 0Xff << MJT_FPROM_ENABLE_SHFT)
-#define MJT_FPROM_SETUP_SHFT	0
-#define MJT_FPROM_SETUP_MASK	(UINT64_CAST 0Xff << MJT_FPROM_SETUP_SHFT)
-
-#define MEM_ERROR_VALID_CE      1
-
-
-/* MD_FANDOP_CAC_STAT0, MD_FANDOP_CAC_STAT1 addr field shift */
-
-#define MFC_ADDR_SHFT		6
-
-#endif  /* _ASM_IA64_SN_SN1_HUBMD_NEXT_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubni.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubni.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubni.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubni.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,1781 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBNI_H
-#define _ASM_IA64_SN_SN1_HUBNI_H
-
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-#define    NI_PORT_STATUS            0x00680000    /* LLP Status             */
-
-
-
-#define    NI_PORT_RESET             0x00680008    /*
-                                                    * Reset the Network
-                                                    * Interface
-                                                    */
-
-
-
-#define    NI_RESET_ENABLE           0x00680010    /* Warm Reset Enable      */
-
-
-
-#define    NI_DIAG_PARMS             0x00680018    /*
-                                                    * Diagnostic
-                                                    * Parameters
-                                                    */
-
-
-
-#define    NI_CHANNEL_CONTROL        0x00680020    /*
-                                                    * Virtual channel
-                                                    * control
-                                                    */
-
-
-
-#define    NI_CHANNEL_TEST           0x00680028    /* LLP Test Control.      */
-
-
-
-#define    NI_PORT_PARMS             0x00680030    /* LLP Parameters         */
-
-
-
-#define    NI_CHANNEL_AGE            0x00680038    /*
-                                                    * Network age
-                                                    * injection control
-                                                    */
-
-
-
-#define    NI_PORT_ERRORS            0x00680100    /* Errors                 */
-
-
-
-#define    NI_PORT_HEADER_A          0x00680108    /*
-                                                    * Error Header first
-                                                    * half
-                                                    */
-
-
-
-#define    NI_PORT_HEADER_B          0x00680110    /*
-                                                    * Error Header second
-                                                    * half
-                                                    */
-
-
-
-#define    NI_PORT_SIDEBAND          0x00680118    /* Error Sideband         */
-
-
-
-#define    NI_PORT_ERROR_CLEAR       0x00680120    /*
-                                                    * Clear the Error
-                                                    * bits
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_0          0x00681000    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_1          0x00681008    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_2          0x00681010    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_3          0x00681018    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_4          0x00681020    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_5          0x00681028    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_6          0x00681030    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_7          0x00681038    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_8          0x00681040    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_9          0x00681048    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_10         0x00681050    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_11         0x00681058    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_12         0x00681060    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_13         0x00681068    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_14         0x00681070    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_15         0x00681078    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_16         0x00681080    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_17         0x00681088    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_18         0x00681090    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_19         0x00681098    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_20         0x006810A0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_21         0x006810A8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_22         0x006810B0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_23         0x006810B8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_24         0x006810C0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_25         0x006810C8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_26         0x006810D0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_27         0x006810D8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_28         0x006810E0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_29         0x006810E8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_30         0x006810F0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_31         0x006810F8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_32         0x00681100    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_33         0x00681108    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_34         0x00681110    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_35         0x00681118    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_36         0x00681120    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_37         0x00681128    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_38         0x00681130    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_39         0x00681138    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_40         0x00681140    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_41         0x00681148    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_42         0x00681150    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_43         0x00681158    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_44         0x00681160    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_45         0x00681168    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_46         0x00681170    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_47         0x00681178    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_48         0x00681180    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_49         0x00681188    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_50         0x00681190    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_51         0x00681198    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_52         0x006811A0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_53         0x006811A8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_54         0x006811B0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_55         0x006811B8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_56         0x006811C0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_57         0x006811C8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_58         0x006811D0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_59         0x006811D8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_60         0x006811E0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_61         0x006811E8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_62         0x006811F0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_63         0x006811F8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_64         0x00681200    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_65         0x00681208    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_66         0x00681210    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_67         0x00681218    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_68         0x00681220    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_69         0x00681228    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_70         0x00681230    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_71         0x00681238    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_72         0x00681240    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_73         0x00681248    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_74         0x00681250    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_75         0x00681258    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_76         0x00681260    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_77         0x00681268    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_78         0x00681270    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_79         0x00681278    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_80         0x00681280    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_81         0x00681288    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_82         0x00681290    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_83         0x00681298    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_84         0x006812A0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_85         0x006812A8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_86         0x006812B0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_87         0x006812B8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_88         0x006812C0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_89         0x006812C8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_90         0x006812D0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_91         0x006812D8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_92         0x006812E0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_93         0x006812E8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_94         0x006812F0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_95         0x006812F8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_96         0x00681300    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_97         0x00681308    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_98         0x00681310    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_99         0x00681318    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_100        0x00681320    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_101        0x00681328    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_102        0x00681330    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_103        0x00681338    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_104        0x00681340    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_105        0x00681348    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_106        0x00681350    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_107        0x00681358    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_108        0x00681360    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_109        0x00681368    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_110        0x00681370    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_111        0x00681378    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_112        0x00681380    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_113        0x00681388    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_114        0x00681390    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_115        0x00681398    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_116        0x006813A0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_117        0x006813A8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_118        0x006813B0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_119        0x006813B8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_120        0x006813C0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_121        0x006813C8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_122        0x006813D0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_123        0x006813D8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_124        0x006813E0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_125        0x006813E8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_126        0x006813F0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_127        0x006813F8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_GLOBAL_TABLE           0x00682000    /*
-                                                    * Base of Global
-                                                    * Mapping Table
-                                                    */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- *  This register describes the LLP status.                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_status_u {
-	bdrkreg_t	ni_port_status_regval;
-	struct  {
-		bdrkreg_t	ps_port_status            :	 2;
-                bdrkreg_t       ps_remote_power           :      1;
-                bdrkreg_t       ps_rsvd                   :     61;
-	} ni_port_status_fld_s;
-} ni_port_status_u_t;
-
-#else
-
-typedef union ni_port_status_u {
-	bdrkreg_t	ni_port_status_regval;
-	struct	{
-		bdrkreg_t	ps_rsvd			  :	61;
-		bdrkreg_t	ps_remote_power		  :	 1;
-		bdrkreg_t	ps_port_status		  :	 2;
-	} ni_port_status_fld_s;
-} ni_port_status_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Writing this register issues a reset to the network interface.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_reset_u {
-	bdrkreg_t	ni_port_reset_regval;
-	struct  {
-		bdrkreg_t	pr_link_reset_out         :	 1;
-                bdrkreg_t       pr_port_reset             :      1;
-                bdrkreg_t       pr_local_reset            :      1;
-                bdrkreg_t       pr_rsvd                   :     61;
-	} ni_port_reset_fld_s;
-} ni_port_reset_u_t;
-
-#else
-
-typedef union ni_port_reset_u {
-	bdrkreg_t	ni_port_reset_regval;
-	struct	{
-		bdrkreg_t	pr_rsvd			  :	61;
-		bdrkreg_t	pr_local_reset		  :	 1;
-		bdrkreg_t	pr_port_reset		  :	 1;
-		bdrkreg_t	pr_link_reset_out	  :	 1;
-	} ni_port_reset_fld_s;
-} ni_port_reset_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the warm reset enable bit.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_reset_enable_u {
-	bdrkreg_t	ni_reset_enable_regval;
-	struct  {
-		bdrkreg_t	re_reset_ok               :	 1;
-                bdrkreg_t       re_rsvd                   :     63;
-	} ni_reset_enable_fld_s;
-} ni_reset_enable_u_t;
-
-#else
-
-typedef union ni_reset_enable_u {
-	bdrkreg_t	ni_reset_enable_regval;
-	struct	{
-		bdrkreg_t	re_rsvd			  :	63;
-		bdrkreg_t	re_reset_ok		  :	 1;
-	} ni_reset_enable_fld_s;
-} ni_reset_enable_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains parameters for diagnostics.                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_diag_parms_u {
-	bdrkreg_t	ni_diag_parms_regval;
-	struct  {
-		bdrkreg_t	dp_send_data_error        :	 1;
-                bdrkreg_t       dp_port_disable           :      1;
-                bdrkreg_t       dp_send_err_off           :      1;
-                bdrkreg_t       dp_rsvd                   :     61;
-	} ni_diag_parms_fld_s;
-} ni_diag_parms_u_t;
-
-#else
-
-typedef union ni_diag_parms_u {
-	bdrkreg_t	ni_diag_parms_regval;
-	struct	{
-		bdrkreg_t	dp_rsvd			  :	61;
-		bdrkreg_t	dp_send_err_off		  :	 1;
-		bdrkreg_t	dp_port_disable		  :	 1;
-		bdrkreg_t	dp_send_data_error	  :	 1;
-	} ni_diag_parms_fld_s;
-} ni_diag_parms_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the virtual channel selection control for    *
- * outgoing messages from the Bedrock.                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_channel_control_u {
-	bdrkreg_t	ni_channel_control_regval;
-	struct  {
-		bdrkreg_t	cc_vch_one_request        :	 1;
-                bdrkreg_t       cc_vch_two_request        :      1;
-                bdrkreg_t       cc_vch_nine_request       :      1;
-                bdrkreg_t       cc_vch_vector_request     :      1;
-                bdrkreg_t       cc_vch_one_reply          :      1;
-                bdrkreg_t       cc_vch_two_reply          :      1;
-                bdrkreg_t       cc_vch_nine_reply         :      1;
-                bdrkreg_t       cc_vch_vector_reply       :      1;
-                bdrkreg_t       cc_send_vch_sel           :      1;
-                bdrkreg_t       cc_rsvd                   :     55;
-	} ni_channel_control_fld_s;
-} ni_channel_control_u_t;
-
-#else
-
-typedef union ni_channel_control_u {
-	bdrkreg_t	ni_channel_control_regval;
-	struct	{
-		bdrkreg_t	cc_rsvd			  :	55;
-		bdrkreg_t	cc_send_vch_sel		  :	 1;
-		bdrkreg_t	cc_vch_vector_reply	  :	 1;
-		bdrkreg_t	cc_vch_nine_reply	  :	 1;
-		bdrkreg_t	cc_vch_two_reply	  :	 1;
-		bdrkreg_t	cc_vch_one_reply	  :	 1;
-		bdrkreg_t	cc_vch_vector_request	  :	 1;
-		bdrkreg_t	cc_vch_nine_request	  :	 1;
-		bdrkreg_t	cc_vch_two_request	  :	 1;
-		bdrkreg_t	cc_vch_one_request	  :	 1;
-	} ni_channel_control_fld_s;
-} ni_channel_control_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows access to the LLP test logic.                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_channel_test_u {
-	bdrkreg_t	ni_channel_test_regval;
-	struct  {
-		bdrkreg_t	ct_testseed               :	20;
-                bdrkreg_t       ct_testmask               :      8;
-                bdrkreg_t       ct_testdata               :     20;
-                bdrkreg_t       ct_testvalid              :      1;
-                bdrkreg_t       ct_testcberr              :      1;
-                bdrkreg_t       ct_testflit               :      3;
-                bdrkreg_t       ct_testclear              :      1;
-                bdrkreg_t       ct_testerrcapture         :      1;
-                bdrkreg_t       ct_rsvd                   :      9;
-	} ni_channel_test_fld_s;
-} ni_channel_test_u_t;
-
-#else
-
-typedef union ni_channel_test_u {
-	bdrkreg_t	ni_channel_test_regval;
-	struct	{
-		bdrkreg_t	ct_rsvd			  :	 9;
-		bdrkreg_t	ct_testerrcapture	  :	 1;
-		bdrkreg_t	ct_testclear		  :	 1;
-		bdrkreg_t	ct_testflit		  :	 3;
-		bdrkreg_t	ct_testcberr		  :	 1;
-		bdrkreg_t	ct_testvalid		  :	 1;
-		bdrkreg_t	ct_testdata		  :	20;
-		bdrkreg_t	ct_testmask		  :	 8;
-		bdrkreg_t	ct_testseed		  :	20;
-	} ni_channel_test_fld_s;
-} ni_channel_test_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains LLP port parameters and enables for the      *
- * capture of header data.                                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_parms_u {
-	bdrkreg_t	ni_port_parms_regval;
-	struct  {
-		bdrkreg_t	pp_max_burst              :	10;
-                bdrkreg_t       pp_null_timeout           :      6;
-                bdrkreg_t       pp_max_retry              :     10;
-                bdrkreg_t       pp_d_avail_sel            :      2;
-                bdrkreg_t       pp_rsvd_1                 :      1;
-                bdrkreg_t       pp_first_err_enable       :      1;
-                bdrkreg_t       pp_squash_err_enable      :      1;
-                bdrkreg_t       pp_vch_err_enable         :      4;
-                bdrkreg_t       pp_rsvd                   :     29;
-	} ni_port_parms_fld_s;
-} ni_port_parms_u_t;
-
-#else
-
-typedef union ni_port_parms_u {
-	bdrkreg_t	ni_port_parms_regval;
-	struct	{
-		bdrkreg_t	pp_rsvd			  :	29;
-		bdrkreg_t	pp_vch_err_enable	  :	 4;
-		bdrkreg_t	pp_squash_err_enable	  :	 1;
-		bdrkreg_t	pp_first_err_enable	  :	 1;
-		bdrkreg_t	pp_rsvd_1		  :	 1;
-		bdrkreg_t	pp_d_avail_sel		  :	 2;
-		bdrkreg_t	pp_max_retry		  :	10;
-		bdrkreg_t	pp_null_timeout		  :	 6;
-		bdrkreg_t	pp_max_burst		  :	10;
-	} ni_port_parms_fld_s;
-} ni_port_parms_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the age at which request and reply packets   *
- * are injected into the network. This feature allows replies to be     *
- * given a higher fixed priority than requests, which can be            *
- * important in some network saturation situations.                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_channel_age_u {
-	bdrkreg_t	ni_channel_age_regval;
-	struct  {
-		bdrkreg_t	ca_request_inject_age     :	 8;
-                bdrkreg_t       ca_reply_inject_age       :      8;
-                bdrkreg_t       ca_rsvd                   :     48;
-	} ni_channel_age_fld_s;
-} ni_channel_age_u_t;
-
-#else
-
-typedef union ni_channel_age_u {
-	bdrkreg_t	ni_channel_age_regval;
-	struct	{
-		bdrkreg_t	ca_rsvd			  :	48;
-		bdrkreg_t	ca_reply_inject_age	  :	 8;
-		bdrkreg_t	ca_request_inject_age	  :	 8;
-	} ni_channel_age_fld_s;
-} ni_channel_age_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains latched LLP port and problematic message     *
- * errors. The contents are the same information as the                 *
- * NI_PORT_ERROR_CLEAR register, but, in this register read accesses    *
- * are non-destructive. Bits [52:24] assert the NI interrupt.           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_errors_u {
-	bdrkreg_t	ni_port_errors_regval;
-	struct  {
-		bdrkreg_t	pe_sn_error_count         :	 8;
-                bdrkreg_t       pe_cb_error_count         :      8;
-                bdrkreg_t       pe_retry_count            :      8;
-                bdrkreg_t       pe_tail_timeout           :      4;
-                bdrkreg_t       pe_fifo_overflow          :      4;
-                bdrkreg_t       pe_external_short         :      4;
-                bdrkreg_t       pe_external_long          :      4;
-                bdrkreg_t       pe_external_bad_header    :      4;
-                bdrkreg_t       pe_internal_short         :      4;
-                bdrkreg_t       pe_internal_long          :      4;
-                bdrkreg_t       pe_link_reset_in          :      1;
-                bdrkreg_t       pe_rsvd                   :     11;
-	} ni_port_errors_fld_s;
-} ni_port_errors_u_t;
-
-#else
-
-typedef union ni_port_errors_u {
-	bdrkreg_t	ni_port_errors_regval;
-	struct	{
-		bdrkreg_t	pe_rsvd			  :	11;
-		bdrkreg_t	pe_link_reset_in	  :	 1;
-		bdrkreg_t	pe_internal_long	  :	 4;
-		bdrkreg_t	pe_internal_short	  :	 4;
-		bdrkreg_t	pe_external_bad_header	  :	 4;
-		bdrkreg_t	pe_external_long	  :	 4;
-		bdrkreg_t	pe_external_short	  :	 4;
-		bdrkreg_t	pe_fifo_overflow	  :	 4;
-		bdrkreg_t	pe_tail_timeout		  :	 4;
-		bdrkreg_t	pe_retry_count		  :	 8;
-		bdrkreg_t	pe_cb_error_count	  :	 8;
-		bdrkreg_t	pe_sn_error_count	  :	 8;
-	} ni_port_errors_fld_s;
-} ni_port_errors_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register provides the sideband data associated with the        *
- * NI_PORT_HEADER registers and also additional data for error          *
- * processing. This register is not cleared on reset.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_sideband_u {
-	bdrkreg_t	ni_port_sideband_regval;
-	struct  {
-		bdrkreg_t	ps_sideband               :	 8;
-                bdrkreg_t       ps_bad_dest               :      1;
-                bdrkreg_t       ps_bad_prexsel            :      1;
-                bdrkreg_t       ps_rcv_error              :      1;
-                bdrkreg_t       ps_bad_message            :      1;
-                bdrkreg_t       ps_squash                 :      1;
-                bdrkreg_t       ps_sn_status              :      1;
-                bdrkreg_t       ps_cb_status              :      1;
-                bdrkreg_t       ps_send_error             :      1;
-                bdrkreg_t       ps_vch_active             :      4;
-                bdrkreg_t       ps_rsvd                   :     44;
-	} ni_port_sideband_fld_s;
-} ni_port_sideband_u_t;
-
-#else
-
-typedef union ni_port_sideband_u {
-	bdrkreg_t	ni_port_sideband_regval;
-	struct	{
-		bdrkreg_t	ps_rsvd			  :	44;
-		bdrkreg_t	ps_vch_active		  :	 4;
-		bdrkreg_t	ps_send_error		  :	 1;
-		bdrkreg_t	ps_cb_status		  :	 1;
-		bdrkreg_t	ps_sn_status		  :	 1;
-		bdrkreg_t	ps_squash		  :	 1;
-		bdrkreg_t	ps_bad_message		  :	 1;
-		bdrkreg_t	ps_rcv_error		  :	 1;
-		bdrkreg_t	ps_bad_prexsel		  :	 1;
-		bdrkreg_t	ps_bad_dest		  :	 1;
-		bdrkreg_t	ps_sideband		  :	 8;
-	} ni_port_sideband_fld_s;
-} ni_port_sideband_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains latched LLP port and problematic message     *
- * errors. The contents are the same information as the                 *
- * NI_PORT_ERROR_CLEAR register, but, in this register read accesses    *
- * are non-destructive. Bits [52:24] assert the NI interrupt.           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_error_clear_u {
-	bdrkreg_t	ni_port_error_clear_regval;
-	struct  {
-		bdrkreg_t	pec_sn_error_count        :	 8;
-                bdrkreg_t       pec_cb_error_count        :      8;
-                bdrkreg_t       pec_retry_count           :      8;
-                bdrkreg_t       pec_tail_timeout          :      4;
-                bdrkreg_t       pec_fifo_overflow         :      4;
-                bdrkreg_t       pec_external_short        :      4;
-                bdrkreg_t       pec_external_long         :      4;
-                bdrkreg_t       pec_external_bad_header   :      4;
-                bdrkreg_t       pec_internal_short        :      4;
-                bdrkreg_t       pec_internal_long         :      4;
-                bdrkreg_t       pec_link_reset_in         :      1;
-                bdrkreg_t       pec_rsvd                  :     11;
-	} ni_port_error_clear_fld_s;
-} ni_port_error_clear_u_t;
-
-#else
-
-typedef union ni_port_error_clear_u {
-	bdrkreg_t	ni_port_error_clear_regval;
-	struct	{
-		bdrkreg_t	pec_rsvd		  :	11;
-		bdrkreg_t	pec_link_reset_in	  :	 1;
-		bdrkreg_t	pec_internal_long	  :	 4;
-		bdrkreg_t	pec_internal_short	  :	 4;
-		bdrkreg_t	pec_external_bad_header	  :	 4;
-		bdrkreg_t	pec_external_long	  :	 4;
-		bdrkreg_t	pec_external_short	  :	 4;
-		bdrkreg_t	pec_fifo_overflow	  :	 4;
-		bdrkreg_t	pec_tail_timeout	  :	 4;
-		bdrkreg_t	pec_retry_count		  :	 8;
-		bdrkreg_t	pec_cb_error_count	  :	 8;
-		bdrkreg_t	pec_sn_error_count	  :	 8;
-	} ni_port_error_clear_fld_s;
-} ni_port_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Lookup table for the next hop's exit port. The table entry          *
- * selection is based on the 7-bit LocalCube routing destination.       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_local_table_0_u {
-	bdrkreg_t	ni_local_table_0_regval;
-	struct  {
-		bdrkreg_t	lt0_next_exit_port        :	 4;
-                bdrkreg_t       lt0_next_vch_lsb          :      1;
-                bdrkreg_t       lt0_rsvd                  :     59;
-	} ni_local_table_0_fld_s;
-} ni_local_table_0_u_t;
-
-#else
-
-typedef union ni_local_table_0_u {
-	bdrkreg_t	ni_local_table_0_regval;
-	struct	{
-		bdrkreg_t	lt0_rsvd		  :	59;
-		bdrkreg_t	lt0_next_vch_lsb	  :	 1;
-		bdrkreg_t	lt0_next_exit_port	  :	 4;
-	} ni_local_table_0_fld_s;
-} ni_local_table_0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Lookup table for the next hop's exit port. The table entry          *
- * selection is based on the 7-bit LocalCube routing destination.       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_local_table_127_u {
-	bdrkreg_t	ni_local_table_127_regval;
-	struct  {
-		bdrkreg_t	lt1_next_exit_port        :	 4;
-                bdrkreg_t       lt1_next_vch_lsb          :      1;
-                bdrkreg_t       lt1_rsvd                  :     59;
-	} ni_local_table_127_fld_s;
-} ni_local_table_127_u_t;
-
-#else
-
-typedef union ni_local_table_127_u {
-	bdrkreg_t	ni_local_table_127_regval;
-	struct	{
-		bdrkreg_t	lt1_rsvd		  :	59;
-		bdrkreg_t	lt1_next_vch_lsb	  :	 1;
-		bdrkreg_t	lt1_next_exit_port	  :	 4;
-	} ni_local_table_127_fld_s;
-} ni_local_table_127_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Lookup table for the next hop's exit port. The table entry          *
- * selection is based on the 1-bit MetaCube routing destination.        *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_global_table_u {
-	bdrkreg_t	ni_global_table_regval;
-	struct  {
-		bdrkreg_t	gt_next_exit_port         :	 4;
-                bdrkreg_t       gt_next_vch_lsb           :      1;
-                bdrkreg_t       gt_rsvd                   :     59;
-	} ni_global_table_fld_s;
-} ni_global_table_u_t;
-
-#else
-
-typedef union ni_global_table_u {
-	bdrkreg_t	ni_global_table_regval;
-	struct	{
-		bdrkreg_t	gt_rsvd			  :	59;
-		bdrkreg_t	gt_next_vch_lsb		  :	 1;
-		bdrkreg_t	gt_next_exit_port	  :	 4;
-	} ni_global_table_fld_s;
-} ni_global_table_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- * The following defines which were not formed into structures are      *
- * probably indentical to another register, and the name of the         *
- * register is provided against each of these registers. This           *
- * information needs to be checked carefully                            *
- *                                                                      *
- *           NI_LOCAL_TABLE_1          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_2          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_3          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_4          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_5          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_6          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_7          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_8          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_9          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_10         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_11         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_12         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_13         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_14         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_15         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_16         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_17         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_18         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_19         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_20         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_21         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_22         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_23         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_24         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_25         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_26         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_27         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_28         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_29         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_30         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_31         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_32         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_33         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_34         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_35         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_36         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_37         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_38         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_39         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_40         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_41         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_42         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_43         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_44         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_45         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_46         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_47         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_48         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_49         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_50         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_51         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_52         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_53         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_54         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_55         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_56         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_57         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_58         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_59         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_60         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_61         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_62         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_63         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_64         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_65         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_66         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_67         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_68         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_69         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_70         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_71         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_72         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_73         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_74         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_75         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_76         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_77         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_78         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_79         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_80         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_81         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_82         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_83         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_84         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_85         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_86         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_87         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_88         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_89         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_90         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_91         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_92         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_93         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_94         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_95         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_96         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_97         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_98         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_99         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_100        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_101        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_102        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_103        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_104        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_105        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_106        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_107        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_108        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_109        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_110        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_111        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_112        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_113        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_114        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_115        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_116        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_117        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_118        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_119        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_120        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_121        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_122        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_123        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_124        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_125        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_126        NI_LOCAL_TABLE_0                 *
- *                                                                      *
- ************************************************************************/
-
-
-/************************************************************************
- *                                                                      *
- * The following defines were not formed into structures                *
- *                                                                      *
- * This could be because the document did not contain details of the    *
- * register, or because the automated script did not recognize the      *
- * register details in the documentation. If these register need        *
- * structure definition, please create them manually                    *
- *                                                                      *
- *           NI_PORT_HEADER_A         0x680108                          *
- *           NI_PORT_HEADER_B         0x680110                          *
- *                                                                      *
- ************************************************************************/
-
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBNI_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubni_next.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubni_next.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubni_next.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubni_next.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,174 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBNI_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBNI_NEXT_H
-
-#define NI_LOCAL_ENTRIES        128
-#define NI_META_ENTRIES        1
-
-#define NI_LOCAL_TABLE(_x)      (NI_LOCAL_TABLE_0 + (8 * (_x)))
-#define NI_META_TABLE(_x)       (NI_GLOBAL_TABLE + (8 * (_x)))
-
-/**************************************************************
-
-  Masks and shifts for NI registers are defined below. 
-
-**************************************************************/
-
-#define NPS_LINKUP_SHFT        1
-#define NPS_LINKUP_MASK        (UINT64_CAST 0x1 << 1)
-
-
-#define NPR_LOCALRESET          (UINT64_CAST 1 << 2)    /* Reset loc. bdrck */
-#define NPR_PORTRESET           (UINT64_CAST 1 << 1)    /* Send warm reset  */
-#define NPR_LINKRESET           (UINT64_CAST 1 << 0)    /* Send link reset  */
-
-/* NI_DIAG_PARMS bit definitions */
-#define NDP_SENDERROR           (UINT64_CAST 1 <<  0)   /* Send data error  */
-#define NDP_PORTDISABLE         (UINT64_CAST 1 <<  1)   /* Port disable     */
-#define NDP_SENDERROFF          (UINT64_CAST 1 <<  2)   /* Disable send error recovery */
-
-
-/* NI_PORT_ERROR mask and shift definitions (some are not present in SN0) */
-
-#define NPE_LINKRESET		(UINT64_CAST 1 << 52)
-#define NPE_INTLONG_SHFT	48
-#define NPE_INTLONG_MASK	(UINT64_CAST 0xf << NPE_INTLONG_SHFT)
-#define NPE_INTSHORT_SHFT	44
-#define NPE_INTSHORT_MASK	(UINT64_CAST 0xf << NPE_INTSHORT_SHFT)
-#define NPE_EXTBADHEADER_SHFT	40
-#define NPE_EXTBADHEADER_MASK	(UINT64_CAST 0xf << NPE_EXTBADHEADER_SHFT)
-#define NPE_EXTLONG_SHFT	36
-#define NPE_EXTLONG_MASK	(UINT64_CAST 0xf << NPE_EXTLONG_SHFT)
-#define NPE_EXTSHORT_SHFT	32
-#define NPE_EXTSHORT_MASK	(UINT64_CAST 0xf << NPE_EXTSHORT_SHFT)
-#define NPE_FIFOOVFLOW_SHFT	28
-#define NPE_FIFOOVFLOW_MASK	(UINT64_CAST 0xf << NPE_FIFOOVFLOW_SHFT)
-#define NPE_TAILTO_SHFT		24
-#define NPE_TAILTO_MASK		(UINT64_CAST 0xf << NPE_TAILTO_SHFT)
-#define NPE_RETRYCOUNT_SHFT	16
-#define NPE_RETRYCOUNT_MASK	(UINT64_CAST 0xff << NPE_RETRYCOUNT_SHFT)
-#define NPE_CBERRCOUNT_SHFT	8
-#define NPE_CBERRCOUNT_MASK	(UINT64_CAST 0xff << NPE_CBERRCOUNT_SHFT)
-#define NPE_SNERRCOUNT_SHFT	0
-#define NPE_SNERRCOUNT_MASK	(UINT64_CAST 0xff << NPE_SNERRCOUNT_SHFT)
-
-#define NPE_COUNT_MAX		0xff
-
-#define NPE_FATAL_ERRORS	(NPE_LINKRESET | NPE_INTLONG_MASK |\
-				 NPE_INTSHORT_MASK | NPE_EXTBADHEADER_MASK |\
-				 NPE_EXTLONG_MASK | NPE_EXTSHORT_MASK |\
-				 NPE_FIFOOVFLOW_MASK | NPE_TAILTO_MASK)
-
-#ifndef __ASSEMBLY__
-/* NI_PORT_HEADER[AB] registers (not automatically generated) */
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_header_a_u {
-	bdrkreg_t	ni_port_header_a_regval;
-	struct  {
-		bdrkreg_t	pha_v                     :	 1;
-                bdrkreg_t       pha_age                   :      8;
-                bdrkreg_t       pha_direction             :      4;
-                bdrkreg_t       pha_destination           :      8;
-                bdrkreg_t       pha_reserved_1            :      3;
-                bdrkreg_t       pha_command               :      8;
-                bdrkreg_t       pha_prexsel               :      3;
-                bdrkreg_t       pha_address_b             :     27;
-                bdrkreg_t       pha_reserved              :      2;
-	} ni_port_header_a_fld_s;
-} ni_port_header_a_u_t;
-
-#else
-
-typedef union ni_port_header_a_u {
-	bdrkreg_t	ni_port_header_a_regval;
-	struct	{
-		bdrkreg_t	pha_reserved		  :	 2;
-		bdrkreg_t	pha_address_b		  :	27;
-		bdrkreg_t	pha_prexsel		  :	 3;
-		bdrkreg_t	pha_command		  :	 8;
-		bdrkreg_t	pha_reserved_1		  :	 3;
-		bdrkreg_t	pha_destination		  :	 8;
-		bdrkreg_t	pha_direction		  :	 4;
-		bdrkreg_t	pha_age			  :	 8;
-		bdrkreg_t	pha_v			  :	 1;
-	} ni_port_header_a_fld_s;
-} ni_port_header_a_u_t;
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_header_b_u {
-	bdrkreg_t	ni_port_header_b_regval;
-	struct  {
-		bdrkreg_t	phb_supplemental           :	11;
-                bdrkreg_t       phb_reserved_2            :      5;
-                bdrkreg_t       phb_source                :     11;
-                bdrkreg_t       phb_reserved_1            :      8;
-                bdrkreg_t       phb_address_a             :      3;
-                bdrkreg_t       phb_address_c             :      8;
-                bdrkreg_t       phb_reserved              :     18;
-	} ni_port_header_b_fld_s;
-} ni_port_header_b_u_t;
-
-#else
-
-typedef union ni_port_header_b_u {
-	bdrkreg_t	ni_port_header_b_regval;
-	struct	{
-		bdrkreg_t	phb_reserved		  :	18;
-		bdrkreg_t	phb_address_c		  :	 8;
-		bdrkreg_t	phb_address_a		  :	 3;
-		bdrkreg_t	phb_reserved_1		  :	 8;
-		bdrkreg_t	phb_source		  :	11;
-		bdrkreg_t	phb_reserved_2		  :	 5;
-		bdrkreg_t	phb_supplemental	   :	11;
-	} ni_port_header_b_fld_s;
-} ni_port_header_b_u_t;
-
-#endif
-#endif
-
-/* NI_RESET_ENABLE mask definitions */
-
-#define NRE_RESETOK		(UINT64_CAST 1)	/* Let LLP reset bedrock */
-
-/* NI PORT_ERRORS, Max number of RETRY_COUNT, Check Bit, and Sequence   */
-/* Number errors (8 bit counters that do not wrap).                     */
-#define NI_LLP_RETRY_MAX        0xff
-#define NI_LLP_CB_MAX           0xff
-#define NI_LLP_SN_MAX           0xff
-
-/* NI_PORT_PARMS shift and mask definitions */
-
-#define NPP_VCH_ERR_EN_SHFT	31
-#define NPP_VCH_ERR_EN_MASK	(0xf << NPP_VCH_ERR_EN_SHFT)
-#define NPP_SQUASH_ERR_EN_SHFT	30
-#define NPP_SQUASH_ERR_EN_MASK	(0x1 << NPP_SQUASH_ERR_EN_SHFT)
-#define NPP_FIRST_ERR_EN_SHFT	29
-#define NPP_FIRST_ERR_EN_MASK	(0x1 << NPP_FIRST_ERR_EN_SHFT)
-#define NPP_D_AVAIL_SEL_SHFT	26
-#define NPP_D_AVAIL_SEL_MASK	(0x3 << NPP_D_AVAIL_SEL_SHFT)
-#define NPP_MAX_RETRY_SHFT	16
-#define NPP_MAX_RETRY_MASK	(0x3ff << NPP_MAX_RETRY_SHFT)
-#define NPP_NULL_TIMEOUT_SHFT	10
-#define NPP_NULL_TIMEOUT_MASK	(0x3f << NPP_NULL_TIMEOUT_SHFT)
-#define NPP_MAX_BURST_SHFT	0
-#define NPP_MAX_BURST_MASK	(0x3ff << NPP_MAX_BURST_SHFT)
-
-#define NPP_RESET_DEFAULTS	(0xf << NPP_VCH_ERR_EN_SHFT |   \
-				 0x1 << NPP_FIRST_ERR_EN_SHFT | \
-				 0x3ff << NPP_MAX_RETRY_SHFT |  \
-				 0x6 << NPP_NULL_TIMEOUT_SHFT | \
-				 0x3f0 << NPP_MAX_BURST_SHFT)
-
-#endif /* _ASM_IA64_SN_SN1_HUBNI_NEXT_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubpi.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubpi.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubpi.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubpi.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,4263 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBPI_H
-#define _ASM_IA64_SN_SN1_HUBPI_H
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-
-#define    PI_CPU_PROTECT            0x00000000    /* CPU Protection         */
-
-
-
-#define    PI_PROT_OVRRD             0x00000008    /*
-                                                    * Clear CPU
-                                                    * Protection bit in 
-                                                    * CPU_PROTECT
-                                                    */
-
-
-
-#define    PI_IO_PROTECT             0x00000010    /*
-                                                    * Interrupt Pending
-                                                    * Protection for IO
-                                                    * access
-                                                    */
-
-
-
-#define    PI_REGION_PRESENT         0x00000018    /* Region present         */
-
-
-
-#define    PI_CPU_NUM                0x00000020    /* CPU Number ID          */
-
-
-
-#define    PI_CALIAS_SIZE            0x00000028    /* Cached Alias Size      */
-
-
-
-#define    PI_MAX_CRB_TIMEOUT        0x00000030    /*
-                                                    * Maximum Timeout for
-                                                    * CRB
-                                                    */
-
-
-
-#define    PI_CRB_SFACTOR            0x00000038    /*
-                                                    * Scale Factor for
-                                                    * CRB Timeout
-                                                    */
-
-
-
-#define    PI_CPU_PRESENT_A          0x00000040    /*
-                                                    * CPU Present for
-                                                    * CPU_A
-                                                    */
-
-
-
-#define    PI_CPU_PRESENT_B          0x00000048    /*
-                                                    * CPU Present for
-                                                    * CPU_B
-                                                    */
-
-
-
-#define    PI_CPU_ENABLE_A           0x00000050    /*
-                                                    * CPU Enable for
-                                                    * CPU_A
-                                                    */
-
-
-
-#define    PI_CPU_ENABLE_B           0x00000058    /*
-                                                    * CPU Enable for
-                                                    * CPU_B
-                                                    */
-
-
-
-#define    PI_REPLY_LEVEL            0x00010060    /*
-                                                    * Reply FIFO Priority
-                                                    * Control
-                                                    */
-
-
-
-#define    PI_GFX_CREDIT_MODE        0x00020068    /*
-                                                    * Graphics Credit
-                                                    * Mode
-                                                    */
-
-
-
-#define    PI_NMI_A                  0x00000070    /*
-                                                    * Non-maskable
-                                                    * Interrupt to CPU A
-                                                    */
-
-
-
-#define    PI_NMI_B                  0x00000078    /*
-                                                    * Non-maskable
-                                                    * Interrupt to CPU B
-                                                    */
-
-
-
-#define    PI_INT_PEND_MOD           0x00000090    /*
-                                                    * Interrupt Pending
-                                                    * Modify
-                                                    */
-
-
-
-#define    PI_INT_PEND0              0x00000098    /* Interrupt Pending 0    */
-
-
-
-#define    PI_INT_PEND1              0x000000A0    /* Interrupt Pending 1    */
-
-
-
-#define    PI_INT_MASK0_A            0x000000A8    /*
-                                                    * Interrupt Mask 0
-                                                    * for CPU A
-                                                    */
-
-
-
-#define    PI_INT_MASK1_A            0x000000B0    /*
-                                                    * Interrupt Mask 1
-                                                    * for CPU A
-                                                    */
-
-
-
-#define    PI_INT_MASK0_B            0x000000B8    /*
-                                                    * Interrupt Mask 0
-                                                    * for CPU B
-                                                    */
-
-
-
-#define    PI_INT_MASK1_B            0x000000C0    /*
-                                                    * Interrupt Mask 1
-                                                    * for CPU B
-                                                    */
-
-
-
-#define    PI_CC_PEND_SET_A          0x000000C8    /*
-                                                    * CC Interrupt
-                                                    * Pending for CPU A
-                                                    */
-
-
-
-#define    PI_CC_PEND_SET_B          0x000000D0    /*
-                                                    * CC Interrupt
-                                                    * Pending for CPU B
-                                                    */
-
-
-
-#define    PI_CC_PEND_CLR_A          0x000000D8    /*
-                                                    * CPU to CPU
-                                                    * Interrupt Pending
-                                                    * Clear for CPU A
-                                                    */
-
-
-
-#define    PI_CC_PEND_CLR_B          0x000000E0    /*
-                                                    * CPU to CPU
-                                                    * Interrupt Pending
-                                                    * Clear for CPU B
-                                                    */
-
-
-
-#define    PI_CC_MASK                0x000000E8    /*
-                                                    * Mask of both
-                                                    * CC_PENDs
-                                                    */
-
-
-
-#define    PI_INT_PEND1_REMAP        0x000000F0    /*
-                                                    * Remap Interrupt
-                                                    * Pending
-                                                    */
-
-
-
-#define    PI_RT_COUNTER             0x00030100    /* Real Time Counter      */
-
-
-
-#define    PI_RT_COMPARE_A           0x00000108    /* Real Time Compare A    */
-
-
-
-#define    PI_RT_COMPARE_B           0x00000110    /* Real Time Compare B    */
-
-
-
-#define    PI_PROFILE_COMPARE        0x00000118    /* Profiling Compare      */
-
-
-
-#define    PI_RT_INT_PEND_A          0x00000120    /*
-                                                    * RT interrupt
-                                                    * pending
-                                                    */
-
-
-
-#define    PI_RT_INT_PEND_B          0x00000128    /*
-                                                    * RT interrupt
-                                                    * pending
-                                                    */
-
-
-
-#define    PI_PROF_INT_PEND_A        0x00000130    /*
-                                                    * Profiling interrupt
-                                                    * pending
-                                                    */
-
-
-
-#define    PI_PROF_INT_PEND_B        0x00000138    /*
-                                                    * Profiling interrupt
-                                                    * pending
-                                                    */
-
-
-
-#define    PI_RT_INT_EN_A            0x00000140    /* RT Interrupt Enable    */
-
-
-
-#define    PI_RT_INT_EN_B            0x00000148    /* RT Interrupt Enable    */
-
-
-
-#define    PI_PROF_INT_EN_A          0x00000150    /*
-                                                    * Profiling Interrupt
-                                                    * Enable
-                                                    */
-
-
-
-#define    PI_PROF_INT_EN_B          0x00000158    /*
-                                                    * Profiling Interrupt
-                                                    * Enable
-                                                    */
-
-
-
-#define    PI_DEBUG_SEL              0x00000160    /* PI Debug Select        */
-
-
-
-#define    PI_INT_PEND_MOD_ALIAS     0x00000180    /*
-                                                    * Interrupt Pending
-                                                    * Modify
-                                                    */
-
-
-
-#define    PI_PERF_CNTL_A            0x00040200    /*
-                                                    * Performance Counter
-                                                    * Control A
-                                                    */
-
-
-
-#define    PI_PERF_CNTR0_A           0x00040208    /*
-                                                    * Performance Counter
-                                                    * 0 A
-                                                    */
-
-
-
-#define    PI_PERF_CNTR1_A           0x00040210    /*
-                                                    * Performance Counter
-                                                    * 1 A
-                                                    */
-
-
-
-#define    PI_PERF_CNTL_B            0x00050200    /*
-                                                    * Performance Counter
-                                                    * Control B
-                                                    */
-
-
-
-#define    PI_PERF_CNTR0_B           0x00050208    /*
-                                                    * Performance Counter
-                                                    * 0 B
-                                                    */
-
-
-
-#define    PI_PERF_CNTR1_B           0x00050210    /*
-                                                    * Performance Counter
-                                                    * 1 B
-                                                    */
-
-
-
-#define    PI_GFX_PAGE_A             0x00000300    /* Graphics Page          */
-
-
-
-#define    PI_GFX_CREDIT_CNTR_A      0x00000308    /*
-                                                    * Graphics Credit
-                                                    * Counter
-                                                    */
-
-
-
-#define    PI_GFX_BIAS_A             0x00000310    /* TRex+ BIAS             */
-
-
-
-#define    PI_GFX_INT_CNTR_A         0x00000318    /*
-                                                    * Graphics Interrupt
-                                                    * Counter
-                                                    */
-
-
-
-#define    PI_GFX_INT_CMP_A          0x00000320    /*
-                                                    * Graphics Interrupt
-                                                    * Compare
-                                                    */
-
-
-
-#define    PI_GFX_PAGE_B             0x00000328    /* Graphics Page          */
-
-
-
-#define    PI_GFX_CREDIT_CNTR_B      0x00000330    /*
-                                                    * Graphics Credit
-                                                    * Counter
-                                                    */
-
-
-
-#define    PI_GFX_BIAS_B             0x00000338    /* TRex+ BIAS             */
-
-
-
-#define    PI_GFX_INT_CNTR_B         0x00000340    /*
-                                                    * Graphics Interrupt
-                                                    * Counter
-                                                    */
-
-
-
-#define    PI_GFX_INT_CMP_B          0x00000348    /*
-                                                    * Graphics Interrupt
-                                                    * Compare
-                                                    */
-
-
-
-#define    PI_ERR_INT_PEND_WR        0x000003F8    /*
-                                                    * Error Interrupt
-                                                    * Pending (Writable)
-                                                    */
-
-
-
-#define    PI_ERR_INT_PEND           0x00000400    /*
-                                                    * Error Interrupt
-                                                    * Pending
-                                                    */
-
-
-
-#define    PI_ERR_INT_MASK_A         0x00000408    /*
-                                                    * Error Interrupt
-                                                    * Mask CPU_A
-                                                    */
-
-
-
-#define    PI_ERR_INT_MASK_B         0x00000410    /*
-                                                    * Error Interrupt
-                                                    * Mask CPU_B
-                                                    */
-
-
-
-#define    PI_ERR_STACK_ADDR_A       0x00000418    /*
-                                                    * Error Stack Address
-                                                    * Pointer
-                                                    */
-
-
-
-#define    PI_ERR_STACK_ADDR_B       0x00000420    /*
-                                                    * Error Stack Address
-                                                    * Pointer
-                                                    */
-
-
-
-#define    PI_ERR_STACK_SIZE         0x00000428    /* Error Stack Size       */
-
-
-
-#define    PI_ERR_STATUS0_A          0x00000430    /* Error Status 0         */
-
-
-
-#define    PI_ERR_STATUS0_A_CLR      0x00000438    /* Error Status 0         */
-
-
-
-#define    PI_ERR_STATUS1_A          0x00000440    /* Error Status 1         */
-
-
-
-#define    PI_ERR_STATUS1_A_CLR      0x00000448    /* Error Status 1         */
-
-
-
-#define    PI_ERR_STATUS0_B          0x00000450    /* Error Status 0         */
-
-
-
-#define    PI_ERR_STATUS0_B_CLR      0x00000458    /* Error Status 0         */
-
-
-
-#define    PI_ERR_STATUS1_B          0x00000460    /* Error Status 1         */
-
-
-
-#define    PI_ERR_STATUS1_B_CLR      0x00000468    /* Error Status 1         */
-
-
-
-#define    PI_SPOOL_CMP_A            0x00000470    /* Spool Compare          */
-
-
-
-#define    PI_SPOOL_CMP_B            0x00000478    /* Spool Compare          */
-
-
-
-#define    PI_CRB_TIMEOUT_A          0x00000480    /*
-                                                    * CRB entries which
-                                                    * have timed out but
-                                                    * are still valid
-                                                    */
-
-
-
-#define    PI_CRB_TIMEOUT_B          0x00000488    /*
-                                                    * CRB entries which
-                                                    * have timed out but
-                                                    * are still valid
-                                                    */
-
-
-
-#define    PI_SYSAD_ERRCHK_EN        0x00000490    /*
-                                                    * enables
-                                                    * sysad/cmd/state
-                                                    * error checking
-                                                    */
-
-
-
-#define    PI_FORCE_BAD_CHECK_BIT_A  0x00000498    /*
-                                                    * force SysAD Check
-                                                    * Bit error
-                                                    */
-
-
-
-#define    PI_FORCE_BAD_CHECK_BIT_B  0x000004A0    /*
-                                                    * force SysAD Check
-                                                    * Bit error
-                                                    */
-
-
-
-#define    PI_NACK_CNT_A             0x000004A8    /*
-                                                    * consecutive NACK
-                                                    * counter
-                                                    */
-
-
-
-#define    PI_NACK_CNT_B             0x000004B0    /*
-                                                    * consecutive NACK
-                                                    * counter
-                                                    */
-
-
-
-#define    PI_NACK_CMP               0x000004B8    /* NACK count compare     */
-
-
-
-#define    PI_SPOOL_MASK             0x000004C0    /* Spool error mask       */
-
-
-
-#define    PI_SPURIOUS_HDR_0         0x000004C8    /* Spurious Error 0       */
-
-
-
-#define    PI_SPURIOUS_HDR_1         0x000004D0    /* Spurious Error 1       */
-
-
-
-#define    PI_ERR_INJECT             0x000004D8    /*
-                                                    * SysAD bus error
-                                                    * injection
-                                                    */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- * Description:  This read/write register determines on a               *
- * bit-per-region basis whether incoming CPU-initiated PIO Read and     *
- * Write to local PI registers are allowed. If access is allowed, the   *
- * PI's response to a partial read is a PRPLY message, and the          *
- * response to a partial write is a PACK message. If access is not      *
- * allowed, the PI's response to a partial read is a PRERR message,     *
- * and the response to a partial write is a PWERR message.              *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cpu_protect_u {
-	bdrkreg_t	pi_cpu_protect_regval;
-	struct  {
-		bdrkreg_t	cp_cpu_protect            :	64;
-	} pi_cpu_protect_fld_s;
-} pi_cpu_protect_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write with a special data pattern allows any CPU to set its       *
- * region's bit in CPU_PROTECT. This register has data pattern          *
- * protection.                                                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_prot_ovrrd_u {
-	bdrkreg_t	pi_prot_ovrrd_regval;
-	struct  {
-		bdrkreg_t	po_prot_ovrrd             :	64;
-	} pi_prot_ovrrd_fld_s;
-} pi_prot_ovrrd_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This read/write register determines on a               *
- * bit-per-region basis whether incoming IO-initiated interrupts are    *
- * allowed to set bits in INT_PEND0 and INT_PEND1. If access is         *
- * allowed, the PI's response to a partial read is a PRPLY message,     *
- * and the response to a partial write is a PACK message. If access     *
- * is not allowed, the PI's response to a partial read is a PRERR       *
- * message, and the response to a partial write is a PWERR message.     *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_io_protect_u {
-	bdrkreg_t	pi_io_protect_regval;
-	struct  {
-		bdrkreg_t	ip_io_protect             :	64;
-	} pi_io_protect_fld_s;
-} pi_io_protect_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This read/write register determines on a               *
- * bit-per-region basis whether read access from a local processor to   *
- * the region is permissible. For example, setting a bit to 0           *
- * prevents speculative reads to that non-existent node. If a read      *
- * request to a non-present region occurs, an ERR response is issued    *
- * to the TRex+ (no PI error registers are modified). It is up to       *
- * software to load this register with the proper contents.             *
- * Region-present checking is only done for coherent read requests -    *
- * partial reads/writes will be issued to a non-present region. The     *
- * setting of these bits does not affect a node's access to its         *
- * CALIAS space.                                                        *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_region_present_u {
-	bdrkreg_t	pi_region_present_regval;
-	struct  {
-		bdrkreg_t	rp_region_present         :	64;
-	} pi_region_present_fld_s;
-} pi_region_present_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A read to the location will allow a CPU to identify itself as       *
- * either CPU_A or CPU_B, and will indicate whether the CPU is          *
- * connected to PI 0 or PI 1.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_cpu_num_u {
-	bdrkreg_t	pi_cpu_num_regval;
-	struct  {
-		bdrkreg_t	cn_cpu_num                :	 1;
-                bdrkreg_t       cn_pi_id                  :      1;
-                bdrkreg_t       cn_rsvd                   :     62;
-	} pi_cpu_num_fld_s;
-} pi_cpu_num_u_t;
-
-#else
-
-typedef union pi_cpu_num_u {
-	bdrkreg_t	pi_cpu_num_regval;
-	struct	{
-		bdrkreg_t	cn_rsvd			  :	62;
-		bdrkreg_t	cn_pi_id		  :	 1;
-		bdrkreg_t	cn_cpu_num		  :	 1;
-	} pi_cpu_num_fld_s;
-} pi_cpu_num_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This read/write location determines the size of the    *
- * Calias Space.                                                        *
- * This register is not reset by a soft reset.                          *
- * NOTE: For predictable behavior, all Calias spaces in a system must   *
- * be set to the same size.                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_calias_size_u {
-	bdrkreg_t	pi_calias_size_regval;
-	struct  {
-		bdrkreg_t	cs_calias_size            :	 4;
-		bdrkreg_t       cs_rsvd                   :     60;
-	} pi_calias_size_fld_s;
-} pi_calias_size_u_t;
-
-#else
-
-typedef union pi_calias_size_u {
-	bdrkreg_t	pi_calias_size_regval;
-	struct	{
-		bdrkreg_t	cs_rsvd			  :	60;
-		bdrkreg_t	cs_calias_size		  :	 4;
-	} pi_calias_size_fld_s;
-} pi_calias_size_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This Read/Write location determines at which value (increment)      *
- * the CRB Timeout Counters cause a timeout error to occur. See         *
- * Section 3.4.2.2, &quot;Time-outs in RRB and WRB&quot; in the         *
- * Processor Interface chapter, volume 1 of this document for more      *
- * details.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_max_crb_timeout_u {
-	bdrkreg_t	pi_max_crb_timeout_regval;
-	struct  {
-		bdrkreg_t	mct_max_timeout           :	 8;
-		bdrkreg_t       mct_rsvd                  :     56;
-	} pi_max_crb_timeout_fld_s;
-} pi_max_crb_timeout_u_t;
-
-#else
-
-typedef union pi_max_crb_timeout_u {
-	bdrkreg_t	pi_max_crb_timeout_regval;
-	struct	{
-		bdrkreg_t	mct_rsvd		  :	56;
-		bdrkreg_t	mct_max_timeout		  :	 8;
-	} pi_max_crb_timeout_fld_s;
-} pi_max_crb_timeout_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This Read/Write location determines how often a valid CRB's         *
- * Timeout Counter is incremented. See Section 3.4.2.2,                 *
- * &quot;Time-outs in RRB and WRB&quot; in the Processor Interface      *
- * chapter, volume 1 of this document for more details.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_crb_sfactor_u {
-	bdrkreg_t	pi_crb_sfactor_regval;
-	struct  {
-		bdrkreg_t	cs_sfactor                :	24;
-		bdrkreg_t       cs_rsvd                   :     40;
-	} pi_crb_sfactor_fld_s;
-} pi_crb_sfactor_u_t;
-
-#else
-
-typedef union pi_crb_sfactor_u {
-	bdrkreg_t	pi_crb_sfactor_regval;
-	struct	{
-		bdrkreg_t	cs_rsvd			  :	40;
-		bdrkreg_t	cs_sfactor		  :	24;
-	} pi_crb_sfactor_fld_s;
-} pi_crb_sfactor_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. The PI sets this      *
- * bit when it sees the first transaction initiated by the associated   *
- * CPU.                                                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_cpu_present_a_u {
-	bdrkreg_t	pi_cpu_present_a_regval;
-	struct  {
-		bdrkreg_t	cpa_cpu_present           :	 1;
-		bdrkreg_t       cpa_rsvd                  :     63;
-	} pi_cpu_present_a_fld_s;
-} pi_cpu_present_a_u_t;
-
-#else
-
-typedef union pi_cpu_present_a_u {
-	bdrkreg_t	pi_cpu_present_a_regval;
-	struct	{
-		bdrkreg_t	cpa_rsvd		  :	63;
-		bdrkreg_t	cpa_cpu_present		  :	 1;
-	} pi_cpu_present_a_fld_s;
-} pi_cpu_present_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. The PI sets this      *
- * bit when it sees the first transaction initiated by the associated   *
- * CPU.                                                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_cpu_present_b_u {
-	bdrkreg_t	pi_cpu_present_b_regval;
-	struct  {
-		bdrkreg_t	cpb_cpu_present           :	 1;
-		bdrkreg_t       cpb_rsvd                  :     63;
-	} pi_cpu_present_b_fld_s;
-} pi_cpu_present_b_u_t;
-
-#else
-
-typedef union pi_cpu_present_b_u {
-	bdrkreg_t	pi_cpu_present_b_regval;
-	struct	{
-		bdrkreg_t	cpb_rsvd		  :	63;
-		bdrkreg_t	cpb_cpu_present		  :	 1;
-	} pi_cpu_present_b_fld_s;
-} pi_cpu_present_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. This     *
- * Read/Write location determines whether the associated CPU is         *
- * enabled to issue external requests. When this bit is zero for a      *
- * processor, the PI ignores SysReq_L from that processor, and so       *
- * never grants it the bus.                                             *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_cpu_enable_a_u {
-	bdrkreg_t	pi_cpu_enable_a_regval;
-	struct  {
-		bdrkreg_t	cea_cpu_enable            :	 1;
-		bdrkreg_t       cea_rsvd                  :     63;
-	} pi_cpu_enable_a_fld_s;
-} pi_cpu_enable_a_u_t;
-
-#else
-
-typedef union pi_cpu_enable_a_u {
-	bdrkreg_t	pi_cpu_enable_a_regval;
-	struct	{
-		bdrkreg_t	cea_rsvd		  :	63;
-		bdrkreg_t	cea_cpu_enable		  :	 1;
-	} pi_cpu_enable_a_fld_s;
-} pi_cpu_enable_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. This     *
- * Read/Write location determines whether the associated CPU is         *
- * enabled to issue external requests. When this bit is zero for a      *
- * processor, the PI ignores SysReq_L from that processor, and so       *
- * never grants it the bus.                                             *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_cpu_enable_b_u {
-	bdrkreg_t	pi_cpu_enable_b_regval;
-	struct  {
-		bdrkreg_t	ceb_cpu_enable            :	 1;
-		bdrkreg_t       ceb_rsvd                  :     63;
-	} pi_cpu_enable_b_fld_s;
-} pi_cpu_enable_b_u_t;
-
-#else
-
-typedef union pi_cpu_enable_b_u {
-	bdrkreg_t	pi_cpu_enable_b_regval;
-	struct	{
-		bdrkreg_t	ceb_rsvd		  :	63;
-		bdrkreg_t	ceb_cpu_enable		  :	 1;
-	} pi_cpu_enable_b_fld_s;
-} pi_cpu_enable_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. A write to this       *
- * location will cause an NMI to be issued to the CPU.                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_nmi_a_u {
-	bdrkreg_t	pi_nmi_a_regval;
-	struct  {
-		bdrkreg_t	na_nmi_cpu                :	64;
-	} pi_nmi_a_fld_s;
-} pi_nmi_a_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. A write to this       *
- * location will cause an NMI to be issued to the CPU.                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_nmi_b_u {
-	bdrkreg_t	pi_nmi_b_regval;
-	struct  {
-		bdrkreg_t	nb_nmi_cpu                :	64;
-	} pi_nmi_b_fld_s;
-} pi_nmi_b_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register allows a single bit in the INT_PEND0 or    *
- * INT_PEND1 registers to be set or cleared. If 6 is clear, a bit is    *
- * modified in INT_PEND0, while if 6 is set, a bit is modified in       *
- * INT_PEND1. The value in 5:0 (ranging from 63 to 0) will determine    *
- * which bit in the register is effected. The value of 8 will           *
- * determine whether the desired bit is set (8=1) or cleared (8=0).     *
- * This is the only register which is accessible by IO issued PWRI      *
- * command and is protected through the IO_PROTECT register. If the     *
- * region bit in the IO_PROTECT is not set then a WERR reply is         *
- * issued. CPU access is controlled through CPU_PROTECT. The contents   *
- * of this register are masked with the contents of INT_MASK_A          *
- * (INT_MASK_B) to determine whether an L2 interrupt is issued to       *
- * CPU_A (CPU_B).                                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_pend_mod_u {
-	bdrkreg_t	pi_int_pend_mod_regval;
-	struct  {
-		bdrkreg_t	ipm_bit_select            :	 6;
-                bdrkreg_t       ipm_reg_select            :      1;
-                bdrkreg_t       ipm_rsvd_1                :      1;
-                bdrkreg_t       ipm_value                 :      1;
-                bdrkreg_t       ipm_rsvd                  :     55;
-	} pi_int_pend_mod_fld_s;
-} pi_int_pend_mod_u_t;
-
-#else
-
-typedef union pi_int_pend_mod_u {
-	bdrkreg_t	pi_int_pend_mod_regval;
-	struct	{
-		bdrkreg_t	ipm_rsvd		  :	55;
-		bdrkreg_t	ipm_value		  :	 1;
-		bdrkreg_t	ipm_rsvd_1		  :	 1;
-		bdrkreg_t	ipm_reg_select		  :	 1;
-		bdrkreg_t	ipm_bit_select		  :	 6;
-	} pi_int_pend_mod_fld_s;
-} pi_int_pend_mod_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read-only register provides information about interrupts       *
- * that are currently pending. The interrupts in this register map to   *
- * interrupt level 2 (L2). The GFX_INT_A/B bits are set by hardware     *
- * but must be cleared by software.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_pend0_u {
-	bdrkreg_t	pi_int_pend0_regval;
-	struct  {
-		bdrkreg_t	ip_int_pend0_lo           :	 1;
-                bdrkreg_t       ip_gfx_int_a              :      1;
-                bdrkreg_t       ip_gfx_int_b              :      1;
-                bdrkreg_t       ip_page_migration         :      1;
-                bdrkreg_t       ip_uart_ucntrl            :      1;
-                bdrkreg_t       ip_or_cc_pend_a           :      1;
-                bdrkreg_t       ip_or_cc_pend_b           :      1;
-                bdrkreg_t       ip_int_pend0_hi           :     57;
-	} pi_int_pend0_fld_s;
-} pi_int_pend0_u_t;
-
-#else
-
-typedef union pi_int_pend0_u {
-	bdrkreg_t	pi_int_pend0_regval;
-	struct	{
-		bdrkreg_t	ip_int_pend0_hi		  :	57;
-		bdrkreg_t	ip_or_cc_pend_b		  :	 1;
-		bdrkreg_t	ip_or_cc_pend_a		  :	 1;
-		bdrkreg_t	ip_uart_ucntrl		  :	 1;
-		bdrkreg_t	ip_page_migration	  :	 1;
-		bdrkreg_t	ip_gfx_int_b		  :	 1;
-		bdrkreg_t	ip_gfx_int_a		  :	 1;
-		bdrkreg_t	ip_int_pend0_lo		  :	 1;
-	} pi_int_pend0_fld_s;
-} pi_int_pend0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read-only register provides information about interrupts       *
- * that are currently pending. The interrupts in this register map to   *
- * interrupt level 3 (L3), unless remapped by the INT_PEND1_REMAP       *
- * register. The SYS_COR_ERR_A/B, RTC_DROP_OUT, and NACK_INT_A/B bits   *
- * are set by hardware but must be cleared by software. The             *
- * SYSTEM_SHUTDOWN, NI_ERROR, LB_ERROR and XB_ERROR bits just reflect   *
- * the value of other logic, and cannot be changed by PI register       *
- * writes.                                                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_pend1_u {
-	bdrkreg_t	pi_int_pend1_regval;
-	struct  {
-		bdrkreg_t	ip_int_pend1              :	54;
-                bdrkreg_t       ip_xb_error               :      1;
-                bdrkreg_t       ip_lb_error               :      1;
-                bdrkreg_t       ip_nack_int_a             :      1;
-                bdrkreg_t       ip_nack_int_b             :      1;
-                bdrkreg_t       ip_perf_cntr_oflow        :      1;
-                bdrkreg_t       ip_sys_cor_err_b          :      1;
-                bdrkreg_t       ip_sys_cor_err_a          :      1;
-                bdrkreg_t       ip_md_corr_error          :      1;
-                bdrkreg_t       ip_ni_error               :      1;
-                bdrkreg_t       ip_system_shutdown        :      1;
-	} pi_int_pend1_fld_s;
-} pi_int_pend1_u_t;
-
-#else
-
-typedef union pi_int_pend1_u {
-	bdrkreg_t	pi_int_pend1_regval;
-	struct	{
-		bdrkreg_t	ip_system_shutdown	  :	 1;
-		bdrkreg_t	ip_ni_error		  :	 1;
-		bdrkreg_t	ip_md_corr_error	  :	 1;
-		bdrkreg_t	ip_sys_cor_err_a	  :	 1;
-		bdrkreg_t	ip_sys_cor_err_b	  :	 1;
-		bdrkreg_t	ip_perf_cntr_oflow	  :	 1;
-		bdrkreg_t	ip_nack_int_b		  :	 1;
-		bdrkreg_t	ip_nack_int_a		  :	 1;
-		bdrkreg_t	ip_lb_error		  :	 1;
-		bdrkreg_t	ip_xb_error		  :	 1;
-		bdrkreg_t	ip_int_pend1		  :	54;
-	} pi_int_pend1_fld_s;
-} pi_int_pend1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register masks the contents of INT_PEND0 to         *
- * determine whether an L2 interrupt (bit 10 of the processor's Cause   *
- * register) is sent to CPU_A if the same bit in the INT_PEND0          *
- * register is also set. Only one processor in a Bedrock should         *
- * enable the PAGE_MIGRATION bit/interrupt.                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_mask0_a_u {
-	bdrkreg_t	pi_int_mask0_a_regval;
-	struct  {
-		bdrkreg_t	ima_int_mask0_lo          :	 1;
-                bdrkreg_t       ima_gfx_int_a             :      1;
-                bdrkreg_t       ima_gfx_int_b             :      1;
-                bdrkreg_t       ima_page_migration        :      1;
-                bdrkreg_t       ima_uart_ucntrl           :      1;
-                bdrkreg_t       ima_or_ccp_mask_a         :      1;
-                bdrkreg_t       ima_or_ccp_mask_b         :      1;
-                bdrkreg_t       ima_int_mask0_hi          :     57;
-	} pi_int_mask0_a_fld_s;
-} pi_int_mask0_a_u_t;
-
-#else
-
-typedef union pi_int_mask0_a_u {
-	bdrkreg_t	pi_int_mask0_a_regval;
-	struct	{
-		bdrkreg_t	ima_int_mask0_hi	  :	57;
-		bdrkreg_t	ima_or_ccp_mask_b	  :	 1;
-		bdrkreg_t	ima_or_ccp_mask_a	  :	 1;
-		bdrkreg_t	ima_uart_ucntrl		  :	 1;
-		bdrkreg_t	ima_page_migration	  :	 1;
-		bdrkreg_t	ima_gfx_int_b		  :	 1;
-		bdrkreg_t	ima_gfx_int_a		  :	 1;
-		bdrkreg_t	ima_int_mask0_lo	  :	 1;
-	} pi_int_mask0_a_fld_s;
-} pi_int_mask0_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register masks the contents of INT_PEND1 to         *
- * determine whether an interrupt should be sent. Bits 63:32 always     *
- * generate an L3 interrupt (bit 11 of the processor's Cause            *
- * register) is sent to CPU_A if the same bit in the INT_PEND1          *
- * register is set. Bits 31:0 can generate either an L3 or L2           *
- * interrupt, depending on the value of INT_PEND1_REMAP[3:0]. Only      *
- * one processor in a Bedrock should enable the NI_ERROR, LB_ERROR,     *
- * XB_ERROR and MD_CORR_ERROR bits.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_int_mask1_a_u {
-	bdrkreg_t	pi_int_mask1_a_regval;
-	struct  {
-		bdrkreg_t	ima_int_mask1             :	64;
-	} pi_int_mask1_a_fld_s;
-} pi_int_mask1_a_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register masks the contents of INT_PEND0 to         *
- * determine whether an L2 interrupt (bit 10 of the processor's Cause   *
- * register) is sent to CPU_B if the same bit in the INT_PEND0          *
- * register is also set. Only one processor in a Bedrock should         *
- * enable the PAGE_MIGRATION bit/interrupt.                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_mask0_b_u {
-	bdrkreg_t	pi_int_mask0_b_regval;
-	struct  {
-		bdrkreg_t	imb_int_mask0_lo          :	 1;
-                bdrkreg_t       imb_gfx_int_a             :      1;
-                bdrkreg_t       imb_gfx_int_b             :      1;
-                bdrkreg_t       imb_page_migration        :      1;
-                bdrkreg_t       imb_uart_ucntrl           :      1;
-                bdrkreg_t       imb_or_ccp_mask_a         :      1;
-                bdrkreg_t       imb_or_ccp_mask_b         :      1;
-                bdrkreg_t       imb_int_mask0_hi          :     57;
-	} pi_int_mask0_b_fld_s;
-} pi_int_mask0_b_u_t;
-
-#else
-
-typedef union pi_int_mask0_b_u {
-	bdrkreg_t	pi_int_mask0_b_regval;
-	struct	{
-		bdrkreg_t	imb_int_mask0_hi	  :	57;
-		bdrkreg_t	imb_or_ccp_mask_b	  :	 1;
-		bdrkreg_t	imb_or_ccp_mask_a	  :	 1;
-		bdrkreg_t	imb_uart_ucntrl		  :	 1;
-		bdrkreg_t	imb_page_migration	  :	 1;
-		bdrkreg_t	imb_gfx_int_b		  :	 1;
-		bdrkreg_t	imb_gfx_int_a		  :	 1;
-		bdrkreg_t	imb_int_mask0_lo	  :	 1;
-	} pi_int_mask0_b_fld_s;
-} pi_int_mask0_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register masks the contents of INT_PEND1 to         *
- * determine whether an interrupt should be sent. Bits 63:32 always     *
- * generate an L3 interrupt (bit 11 of the processor's Cause            *
- * register) is sent to CPU_B if the same bit in the INT_PEND1          *
- * register is set. Bits 31:0 can generate either an L3 or L2           *
- * interrupt, depending on the value of INT_PEND1_REMAP[3:0]. Only      *
- * one processor in a Bedrock should enable the NI_ERROR, LB_ERROR,     *
- * XB_ERROR and MD_CORR_ERROR bits.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_int_mask1_b_u {
-	bdrkreg_t	pi_int_mask1_b_regval;
-	struct  {
-		bdrkreg_t	imb_int_mask1             :	64;
-	} pi_int_mask1_b_fld_s;
-} pi_int_mask1_b_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. These registers do    *
- * not have access protection. A store to this location by a CPU will   *
- * cause the bit corresponding to the source's region to be set in      *
- * CC_PEND_A (or CC_PEND_B). The contents of CC_PEND_A (or CC_PEND_B)   *
- * determines on a bit-per-region basis whether a CPU-to-CPU            *
- * interrupt is pending CPU_A (or CPU_B).                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cc_pend_set_a_u {
-	bdrkreg_t	pi_cc_pend_set_a_regval;
-	struct  {
-		bdrkreg_t	cpsa_cc_pend              :	64;
-	} pi_cc_pend_set_a_fld_s;
-} pi_cc_pend_set_a_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. These registers do    *
- * not have access protection. A store to this location by a CPU will   *
- * cause the bit corresponding to the source's region to be set in      *
- * CC_PEND_A (or CC_PEND_B). The contents of CC_PEND_A (or CC_PEND_B)   *
- * determines on a bit-per-region basis whether a CPU-to-CPU            *
- * interrupt is pending CPU_A (or CPU_B).                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cc_pend_set_b_u {
-	bdrkreg_t	pi_cc_pend_set_b_regval;
-	struct  {
-		bdrkreg_t	cpsb_cc_pend              :	64;
-	} pi_cc_pend_set_b_fld_s;
-} pi_cc_pend_set_b_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Reading this          *
- * location will return the contents of CC_PEND_A (or CC_PEND_B).       *
- * Writing this location will clear the bits corresponding to which     *
- * data bits are driven high during the store; therefore, storing all   *
- * ones would clear all bits.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cc_pend_clr_a_u {
-	bdrkreg_t	pi_cc_pend_clr_a_regval;
-	struct  {
-		bdrkreg_t	cpca_cc_pend              :	64;
-	} pi_cc_pend_clr_a_fld_s;
-} pi_cc_pend_clr_a_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Reading this          *
- * location will return the contents of CC_PEND_A (or CC_PEND_B).       *
- * Writing this location will clear the bits corresponding to which     *
- * data bits are driven high during the store; therefore, storing all   *
- * ones would clear all bits.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cc_pend_clr_b_u {
-	bdrkreg_t	pi_cc_pend_clr_b_regval;
-	struct  {
-		bdrkreg_t	cpcb_cc_pend              :	64;
-	} pi_cc_pend_clr_b_fld_s;
-} pi_cc_pend_clr_b_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register masks the contents of both CC_PEND_A and   *
- * CC_PEND_B.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cc_mask_u {
-	bdrkreg_t	pi_cc_mask_regval;
-	struct  {
-		bdrkreg_t	cm_cc_mask                :	64;
-	} pi_cc_mask_fld_s;
-} pi_cc_mask_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register redirects INT_PEND1[31:0] from L3 to L2    *
- * interrupt level.Bit 4 in this register is used to enable error       *
- * interrupt forwarding to the II. When this bit is set, if any of      *
- * the three memory interrupts (correctable error, uncorrectable        *
- * error, or page migration), or the NI, LB or XB error interrupts      *
- * are set, the PI_II_ERROR_INT wire will be asserted. When this wire   *
- * is asserted, the II will send an interrupt to the node specified     *
- * in its IIDSR (Interrupt Destination Register). This allows these     *
- * interrupts to be forwarded to another node.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_pend1_remap_u {
-	bdrkreg_t	pi_int_pend1_remap_regval;
-	struct  {
-		bdrkreg_t	ipr_remap_0               :	 1;
-                bdrkreg_t       ipr_remap_1               :      1;
-                bdrkreg_t       ipr_remap_2               :      1;
-                bdrkreg_t       ipr_remap_3               :      1;
-                bdrkreg_t       ipr_error_forward         :      1;
-                bdrkreg_t       ipr_reserved              :     59;
-	} pi_int_pend1_remap_fld_s;
-} pi_int_pend1_remap_u_t;
-
-#else
-
-typedef union pi_int_pend1_remap_u {
-	bdrkreg_t	pi_int_pend1_remap_regval;
-	struct	{
-		bdrkreg_t	ipr_reserved		  :	59;
-		bdrkreg_t	ipr_error_forward	  :	 1;
-		bdrkreg_t	ipr_remap_3		  :	 1;
-		bdrkreg_t	ipr_remap_2		  :	 1;
-		bdrkreg_t	ipr_remap_1		  :	 1;
-		bdrkreg_t	ipr_remap_0		  :	 1;
-	} pi_int_pend1_remap_fld_s;
-} pi_int_pend1_remap_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When the real time    *
- * counter (RT_Counter) is equal to the value in this register, the     *
- * RT_INT_PEND register is set, which causes a Level-4 interrupt to     *
- * be sent to the processor.                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_compare_a_u {
-	bdrkreg_t	pi_rt_compare_a_regval;
-	struct  {
-		bdrkreg_t	rca_rt_compare            :	55;
-		bdrkreg_t       rca_rsvd                  :      9;
-	} pi_rt_compare_a_fld_s;
-} pi_rt_compare_a_u_t;
-
-#else
-
-typedef union pi_rt_compare_a_u {
-        bdrkreg_t       pi_rt_compare_a_regval;
-        struct  {
-                bdrkreg_t       rca_rsvd                  :      9;
-                bdrkreg_t       rca_rt_compare            :     55;
-        } pi_rt_compare_a_fld_s;
-} pi_rt_compare_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When the real time    *
- * counter (RT_Counter) is equal to the value in this register, the     *
- * RT_INT_PEND register is set, which causes a Level-4 interrupt to     *
- * be sent to the processor.                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_compare_b_u {
-	bdrkreg_t	pi_rt_compare_b_regval;
-	struct  {
-		bdrkreg_t	rcb_rt_compare            :	55;
-		bdrkreg_t       rcb_rsvd                  :      9;
-	} pi_rt_compare_b_fld_s;
-} pi_rt_compare_b_u_t;
-
-#else
-
-typedef union pi_rt_compare_b_u {
-	bdrkreg_t	pi_rt_compare_b_regval;
-	struct	{
-		bdrkreg_t	rcb_rsvd		  :	 9;
-		bdrkreg_t	rcb_rt_compare		  :	55;
-	} pi_rt_compare_b_fld_s;
-} pi_rt_compare_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  When the least significant 32 bits of the real time counter         *
- * (RT_Counter) are equal to the value in this register, the            *
- * PROF_INT_PEND_A and PROF_INT_PEND_B registers are set to 0x1.        *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_profile_compare_u {
-	bdrkreg_t	pi_profile_compare_regval;
-	struct  {
-		bdrkreg_t	pc_profile_compare        :	32;
-		bdrkreg_t       pc_rsvd                   :     32;
-	} pi_profile_compare_fld_s;
-} pi_profile_compare_u_t;
-
-#else
-
-typedef union pi_profile_compare_u {
-	bdrkreg_t	pi_profile_compare_regval;
-	struct	{
-		bdrkreg_t	pc_rsvd			  :	32;
-		bdrkreg_t	pc_profile_compare	  :	32;
-	} pi_profile_compare_fld_s;
-} pi_profile_compare_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. If the bit in the     *
- * corresponding RT_INT_EN_A/B register is set, the processor's level   *
- * 5 interrupt is set to the value of the RTC_INT_PEND bit in this      *
- * register. Storing any value to this location will clear the          *
- * RTC_INT_PEND bit in the register.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_int_pend_a_u {
-	bdrkreg_t	pi_rt_int_pend_a_regval;
-	struct  {
-		bdrkreg_t	ripa_rtc_int_pend         :	 1;
-		bdrkreg_t       ripa_rsvd                 :     63;
-	} pi_rt_int_pend_a_fld_s;
-} pi_rt_int_pend_a_u_t;
-
-#else
-
-typedef union pi_rt_int_pend_a_u {
-	bdrkreg_t	pi_rt_int_pend_a_regval;
-	struct	{
-		bdrkreg_t	ripa_rsvd		  :	63;
-		bdrkreg_t	ripa_rtc_int_pend	  :	 1;
-	} pi_rt_int_pend_a_fld_s;
-} pi_rt_int_pend_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. If the bit in the     *
- * corresponding RT_INT_EN_A/B register is set, the processor's level   *
- * 5 interrupt is set to the value of the RTC_INT_PEND bit in this      *
- * register. Storing any value to this location will clear the          *
- * RTC_INT_PEND bit in the register.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_int_pend_b_u {
-	bdrkreg_t	pi_rt_int_pend_b_regval;
-	struct  {
-		bdrkreg_t	ripb_rtc_int_pend         :	 1;
-		bdrkreg_t       ripb_rsvd                 :     63;
-	} pi_rt_int_pend_b_fld_s;
-} pi_rt_int_pend_b_u_t;
-
-#else
-
-typedef union pi_rt_int_pend_b_u {
-	bdrkreg_t	pi_rt_int_pend_b_regval;
-	struct	{
-		bdrkreg_t	ripb_rsvd		  :	63;
-		bdrkreg_t	ripb_rtc_int_pend	  :	 1;
-	} pi_rt_int_pend_b_fld_s;
-} pi_rt_int_pend_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Both registers are    *
- * set when the PROFILE_COMPARE register is equal to bits [31:0] of     *
- * the RT_Counter. If the bit in the corresponding PROF_INT_EN_A/B      *
- * register is set, the processor's level 5 interrupt is set to the     *
- * value of the PROF_INT_PEND bit in this register. Storing any value   *
- * to this location will clear the PROF_INT_PEND bit in the register.   *
- * The reason for having A and B versions of this register is that      *
- * they need to be cleared independently.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_prof_int_pend_a_u {
-	bdrkreg_t	pi_prof_int_pend_a_regval;
-	struct  {
-		bdrkreg_t	pipa_prof_int_pend        :	 1;
-		bdrkreg_t       pipa_rsvd                 :     63;
-	} pi_prof_int_pend_a_fld_s;
-} pi_prof_int_pend_a_u_t;
-
-#else
-
-typedef union pi_prof_int_pend_a_u {
-	bdrkreg_t	pi_prof_int_pend_a_regval;
-	struct	{
-		bdrkreg_t	pipa_rsvd		  :	63;
-		bdrkreg_t	pipa_prof_int_pend	  :	 1;
-	} pi_prof_int_pend_a_fld_s;
-} pi_prof_int_pend_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Both registers are    *
- * set when the PROFILE_COMPARE register is equal to bits [31:0] of     *
- * the RT_Counter. If the bit in the corresponding PROF_INT_EN_A/B      *
- * register is set, the processor's level 5 interrupt is set to the     *
- * value of the PROF_INT_PEND bit in this register. Storing any value   *
- * to this location will clear the PROF_INT_PEND bit in the register.   *
- * The reason for having A and B versions of this register is that      *
- * they need to be cleared independently.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_prof_int_pend_b_u {
-	bdrkreg_t	pi_prof_int_pend_b_regval;
-	struct  {
-		bdrkreg_t	pipb_prof_int_pend        :	 1;
-		bdrkreg_t       pipb_rsvd                 :     63;
-	} pi_prof_int_pend_b_fld_s;
-} pi_prof_int_pend_b_u_t;
-
-#else
-
-typedef union pi_prof_int_pend_b_u {
-	bdrkreg_t	pi_prof_int_pend_b_regval;
-	struct	{
-		bdrkreg_t	pipb_rsvd		  :	63;
-		bdrkreg_t	pipb_prof_int_pend	  :	 1;
-	} pi_prof_int_pend_b_fld_s;
-} pi_prof_int_pend_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Enables RTC           *
- * interrupt to the associated CPU.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_int_en_a_u {
-	bdrkreg_t	pi_rt_int_en_a_regval;
-	struct  {
-		bdrkreg_t	riea_rtc_int_en           :	 1;
-		bdrkreg_t       riea_rsvd                 :     63;
-	} pi_rt_int_en_a_fld_s;
-} pi_rt_int_en_a_u_t;
-
-#else
-
-typedef union pi_rt_int_en_a_u {
-        bdrkreg_t       pi_rt_int_en_a_regval;
-        struct  {
-                bdrkreg_t       riea_rsvd                 :     63;
-                bdrkreg_t       riea_rtc_int_en           :      1;
-        } pi_rt_int_en_a_fld_s;
-} pi_rt_int_en_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Enables RTC           *
- * interrupt to the associated CPU.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_int_en_b_u {
-	bdrkreg_t	pi_rt_int_en_b_regval;
-	struct  {
-		bdrkreg_t	rieb_rtc_int_en           :	 1;
-		bdrkreg_t       rieb_rsvd                 :     63;
-	} pi_rt_int_en_b_fld_s;
-} pi_rt_int_en_b_u_t;
-
-#else
-
-typedef union pi_rt_int_en_b_u {
-        bdrkreg_t       pi_rt_int_en_b_regval;
-        struct  {
-                bdrkreg_t       rieb_rsvd                 :     63;
-                bdrkreg_t       rieb_rtc_int_en           :      1;
-        } pi_rt_int_en_b_fld_s;
-} pi_rt_int_en_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Enables profiling     *
- * interrupt to the associated CPU.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_prof_int_en_a_u {
-	bdrkreg_t	pi_prof_int_en_a_regval;
-	struct  {
-		bdrkreg_t	piea_prof_int_en          :	 1;
-		bdrkreg_t       piea_rsvd                 :     63;
-	} pi_prof_int_en_a_fld_s;
-} pi_prof_int_en_a_u_t;
-
-#else
-
-typedef union pi_prof_int_en_a_u {
-	bdrkreg_t	pi_prof_int_en_a_regval;
-	struct	{
-		bdrkreg_t	piea_rsvd		  :	63;
-		bdrkreg_t	piea_prof_int_en	  :	 1;
-	} pi_prof_int_en_a_fld_s;
-} pi_prof_int_en_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Enables profiling     *
- * interrupt to the associated CPU.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_prof_int_en_b_u {
-	bdrkreg_t	pi_prof_int_en_b_regval;
-	struct  {
-		bdrkreg_t	pieb_prof_int_en          :	 1;
-		bdrkreg_t       pieb_rsvd                 :     63;
-	} pi_prof_int_en_b_fld_s;
-} pi_prof_int_en_b_u_t;
-
-#else
-
-typedef union pi_prof_int_en_b_u {
-	bdrkreg_t	pi_prof_int_en_b_regval;
-	struct	{
-		bdrkreg_t	pieb_rsvd		  :	63;
-		bdrkreg_t	pieb_prof_int_en	  :	 1;
-	} pi_prof_int_en_b_fld_s;
-} pi_prof_int_en_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls operation of the debug data from the PI,     *
- * along with Debug_Sel[2:0] from the Debug module. For some values     *
- * of Debug_Sel[2:0], the B_SEL bit selects whether the debug bits      *
- * are looking at the processor A or processor B logic. The remaining   *
- * bits select which signal(s) are ORed to create DebugData bits 31     *
- * and 30 for all of the PI debug selections.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_debug_sel_u {
-	bdrkreg_t	pi_debug_sel_regval;
-	struct  {
-		bdrkreg_t	ds_low_t5cc_a             :	 1;
-                bdrkreg_t       ds_low_t5cc_b             :      1;
-                bdrkreg_t       ds_low_totcc_a            :      1;
-                bdrkreg_t       ds_low_totcc_b            :      1;
-                bdrkreg_t       ds_low_reqcc_a            :      1;
-                bdrkreg_t       ds_low_reqcc_b            :      1;
-                bdrkreg_t       ds_low_rplcc_a            :      1;
-                bdrkreg_t       ds_low_rplcc_b            :      1;
-                bdrkreg_t       ds_low_intcc              :      1;
-                bdrkreg_t       ds_low_perf_inc_a_0       :      1;
-                bdrkreg_t       ds_low_perf_inc_a_1       :      1;
-                bdrkreg_t       ds_low_perf_inc_b_0       :      1;
-                bdrkreg_t       ds_low_perf_inc_b_1       :      1;
-                bdrkreg_t       ds_high_t5cc_a            :      1;
-                bdrkreg_t       ds_high_t5cc_b            :      1;
-                bdrkreg_t       ds_high_totcc_a           :      1;
-                bdrkreg_t       ds_high_totcc_b           :      1;
-                bdrkreg_t       ds_high_reqcc_a           :      1;
-                bdrkreg_t       ds_high_reqcc_b           :      1;
-                bdrkreg_t       ds_high_rplcc_a           :      1;
-                bdrkreg_t       ds_high_rplcc_b           :      1;
-                bdrkreg_t       ds_high_intcc             :      1;
-                bdrkreg_t       ds_high_perf_inc_a_0      :      1;
-                bdrkreg_t       ds_high_perf_inc_a_1      :      1;
-                bdrkreg_t       ds_high_perf_inc_b_0      :      1;
-                bdrkreg_t       ds_high_perf_inc_b_1      :      1;
-                bdrkreg_t       ds_b_sel                  :      1;
-                bdrkreg_t       ds_rsvd                   :     37;
-	} pi_debug_sel_fld_s;
-} pi_debug_sel_u_t;
-
-#else
-
-typedef union pi_debug_sel_u {
-	bdrkreg_t	pi_debug_sel_regval;
-	struct	{
-		bdrkreg_t	ds_rsvd			  :	37;
-		bdrkreg_t	ds_b_sel		  :	 1;
-		bdrkreg_t	ds_high_perf_inc_b_1	  :	 1;
-		bdrkreg_t	ds_high_perf_inc_b_0	  :	 1;
-		bdrkreg_t	ds_high_perf_inc_a_1	  :	 1;
-		bdrkreg_t	ds_high_perf_inc_a_0	  :	 1;
-		bdrkreg_t	ds_high_intcc		  :	 1;
-		bdrkreg_t	ds_high_rplcc_b		  :	 1;
-		bdrkreg_t	ds_high_rplcc_a		  :	 1;
-		bdrkreg_t	ds_high_reqcc_b		  :	 1;
-		bdrkreg_t	ds_high_reqcc_a		  :	 1;
-		bdrkreg_t	ds_high_totcc_b		  :	 1;
-		bdrkreg_t	ds_high_totcc_a		  :	 1;
-		bdrkreg_t	ds_high_t5cc_b		  :	 1;
-		bdrkreg_t	ds_high_t5cc_a		  :	 1;
-		bdrkreg_t	ds_low_perf_inc_b_1	  :	 1;
-		bdrkreg_t	ds_low_perf_inc_b_0	  :	 1;
-		bdrkreg_t	ds_low_perf_inc_a_1	  :	 1;
-		bdrkreg_t	ds_low_perf_inc_a_0	  :	 1;
-		bdrkreg_t	ds_low_intcc		  :	 1;
-		bdrkreg_t	ds_low_rplcc_b		  :	 1;
-		bdrkreg_t	ds_low_rplcc_a		  :	 1;
-		bdrkreg_t	ds_low_reqcc_b		  :	 1;
-		bdrkreg_t	ds_low_reqcc_a		  :	 1;
-		bdrkreg_t	ds_low_totcc_b		  :	 1;
-		bdrkreg_t	ds_low_totcc_a		  :	 1;
-		bdrkreg_t	ds_low_t5cc_b		  :	 1;
-		bdrkreg_t	ds_low_t5cc_a		  :	 1;
-	} pi_debug_sel_fld_s;
-} pi_debug_sel_u_t;
-
-#endif
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register allows a single bit in the INT_PEND0 or    *
- * INT_PEND1 registers to be set or cleared. If 6 is clear, a bit is    *
- * modified in INT_PEND0, while if 6 is set, a bit is modified in       *
- * INT_PEND1. The value in 5:0 (ranging from 63 to 0) will determine    *
- * which bit in the register is effected. The value of 8 will           *
- * determine whether the desired bit is set (8=1) or cleared (8=0).     *
- * This is the only register which is accessible by IO issued PWRI      *
- * command and is protected through the IO_PROTECT register. If the     *
- * region bit in the IO_PROTECT is not set then a WERR reply is         *
- * issued. CPU access is controlled through CPU_PROTECT. The contents   *
- * of this register are masked with the contents of INT_MASK_A          *
- * (INT_MASK_B) to determine whether an L2 interrupt is issued to       *
- * CPU_A (CPU_B).                                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_pend_mod_alias_u {
-	bdrkreg_t	pi_int_pend_mod_alias_regval;
-	struct  {
-		bdrkreg_t	ipma_bit_select           :	 6;
-                bdrkreg_t       ipma_reg_select           :      1;
-                bdrkreg_t       ipma_rsvd_1               :      1;
-                bdrkreg_t       ipma_value                :      1;
-                bdrkreg_t       ipma_rsvd                 :     55;
-	} pi_int_pend_mod_alias_fld_s;
-} pi_int_pend_mod_alias_u_t;
-
-#else
-
-typedef union pi_int_pend_mod_alias_u {
-	bdrkreg_t	pi_int_pend_mod_alias_regval;
-	struct	{
-		bdrkreg_t	ipma_rsvd		  :	55;
-		bdrkreg_t	ipma_value		  :	 1;
-		bdrkreg_t	ipma_rsvd_1		  :	 1;
-		bdrkreg_t	ipma_reg_select		  :	 1;
-		bdrkreg_t	ipma_bit_select		  :	 6;
-	} pi_int_pend_mod_alias_fld_s;
-} pi_int_pend_mod_alias_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This register         *
- * specifies the value of the Graphics Page. Uncached writes into the   *
- * Graphics Page (with uncached attribute of IO) are done with GFXWS    *
- * commands rather than the normal PWRI commands. GFXWS commands are    *
- * tracked with the graphics credit counters.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_page_a_u {
-	bdrkreg_t	pi_gfx_page_a_regval;
-	struct  {
-		bdrkreg_t	gpa_rsvd_1                :	17;
-                bdrkreg_t       gpa_gfx_page_addr         :     23;
-                bdrkreg_t       gpa_en_gfx_page           :      1;
-                bdrkreg_t       gpa_rsvd                  :     23;
-	} pi_gfx_page_a_fld_s;
-} pi_gfx_page_a_u_t;
-
-#else
-
-typedef union pi_gfx_page_a_u {
-	bdrkreg_t	pi_gfx_page_a_regval;
-	struct	{
-		bdrkreg_t	gpa_rsvd		  :	23;
-		bdrkreg_t	gpa_en_gfx_page		  :	 1;
-		bdrkreg_t	gpa_gfx_page_addr	  :	23;
-		bdrkreg_t	gpa_rsvd_1		  :	17;
-	} pi_gfx_page_a_fld_s;
-} pi_gfx_page_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This register         *
- * counts graphics credits. This counter is decremented for each        *
- * doubleword sent to graphics with GFXWS or GFXWL commands. It is      *
- * incremented for each doubleword acknowledge from graphics. When      *
- * this counter has a smaller value than the GFX_BIAS register,         *
- * SysWrRdy_L is deasserted, an interrupt is sent to the processor,     *
- * and SysWrRdy_L is allowed to be asserted again. This is the basic    *
- * mechanism for flow-controlling graphics writes.                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_credit_cntr_a_u {
-	bdrkreg_t	pi_gfx_credit_cntr_a_regval;
-	struct  {
-		bdrkreg_t	gcca_gfx_credit_cntr      :	12;
-		bdrkreg_t       gcca_rsvd                 :     52;
-	} pi_gfx_credit_cntr_a_fld_s;
-} pi_gfx_credit_cntr_a_u_t;
-
-#else
-
-typedef union pi_gfx_credit_cntr_a_u {
-	bdrkreg_t	pi_gfx_credit_cntr_a_regval;
-	struct	{
-		bdrkreg_t	gcca_rsvd		  :	52;
-		bdrkreg_t	gcca_gfx_credit_cntr	  :	12;
-	} pi_gfx_credit_cntr_a_fld_s;
-} pi_gfx_credit_cntr_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When the graphics     *
- * credit counter is less than or equal to this value, a flow control   *
- * interrupt is sent.                                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_bias_a_u {
-	bdrkreg_t	pi_gfx_bias_a_regval;
-	struct  {
-		bdrkreg_t	gba_gfx_bias              :	12;
-		bdrkreg_t       gba_rsvd                  :     52;
-	} pi_gfx_bias_a_fld_s;
-} pi_gfx_bias_a_u_t;
-
-#else
-
-typedef union pi_gfx_bias_a_u {
-	bdrkreg_t	pi_gfx_bias_a_regval;
-	struct	{
-		bdrkreg_t	gba_rsvd		  :	52;
-		bdrkreg_t	gba_gfx_bias		  :	12;
-	} pi_gfx_bias_a_fld_s;
-} pi_gfx_bias_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. When     *
- * this counter reaches the value of the GFX_INT_CMP register, an       *
- * interrupt is sent to the associated processor. At each clock         *
- * cycle, the value in this register can be changed by any one of the   *
- * following actions:                                                   *
- * - Written by software.                                               *
- * - Loaded with the value of GFX_INT_CMP, when an interrupt, NMI, or   *
- * soft reset occurs, thus preventing an additional interrupt.          *
- * - Zeroed, when the GFX_CREDIT_CNTR rises above the bias value.       *
- * - Incremented (by one at each clock) for each clock that the         *
- * GFX_CREDIT_CNTR is less than or equal to zero.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_int_cntr_a_u {
-	bdrkreg_t	pi_gfx_int_cntr_a_regval;
-	struct  {
-		bdrkreg_t	gica_gfx_int_cntr         :	26;
-		bdrkreg_t       gica_rsvd                 :     38;
-	} pi_gfx_int_cntr_a_fld_s;
-} pi_gfx_int_cntr_a_u_t;
-
-#else
-
-typedef union pi_gfx_int_cntr_a_u {
-	bdrkreg_t	pi_gfx_int_cntr_a_regval;
-	struct	{
-		bdrkreg_t	gica_rsvd		  :	38;
-		bdrkreg_t	gica_gfx_int_cntr	  :	26;
-	} pi_gfx_int_cntr_a_fld_s;
-} pi_gfx_int_cntr_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. The value in this     *
- * register is loaded into the GFX_INT_CNTR register when an            *
- * interrupt, NMI, or soft reset is sent to the processor. The value    *
- * in this register is compared to the value of GFX_INT_CNTR and an     *
- * interrupt is sent when they become equal.                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LINUX
-
-typedef union pi_gfx_int_cmp_a_u {
-	bdrkreg_t	pi_gfx_int_cmp_a_regval;
-	struct  {
-		bdrkreg_t	gica_gfx_int_cmp          :	26;
-		bdrkreg_t       gica_rsvd                 :     38;
-	} pi_gfx_int_cmp_a_fld_s;
-} pi_gfx_int_cmp_a_u_t;
-
-#else
-
-typedef union pi_gfx_int_cmp_a_u {
-	bdrkreg_t	pi_gfx_int_cmp_a_regval;
-	struct	{
-		bdrkreg_t	gica_rsvd		  :	38;
-		bdrkreg_t	gica_gfx_int_cmp	  :	26;
-	} pi_gfx_int_cmp_a_fld_s;
-} pi_gfx_int_cmp_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This register         *
- * specifies the value of the Graphics Page. Uncached writes into the   *
- * Graphics Page (with uncached attribute of IO) are done with GFXWS    *
- * commands rather than the normal PWRI commands. GFXWS commands are    *
- * tracked with the graphics credit counters.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_page_b_u {
-	bdrkreg_t	pi_gfx_page_b_regval;
-	struct  {
-		bdrkreg_t	gpb_rsvd_1                :	17;
-                bdrkreg_t       gpb_gfx_page_addr         :     23;
-                bdrkreg_t       gpb_en_gfx_page           :      1;
-                bdrkreg_t       gpb_rsvd                  :     23;
-	} pi_gfx_page_b_fld_s;
-} pi_gfx_page_b_u_t;
-
-#else
-
-typedef union pi_gfx_page_b_u {
-	bdrkreg_t	pi_gfx_page_b_regval;
-	struct	{
-		bdrkreg_t	gpb_rsvd		  :	23;
-		bdrkreg_t	gpb_en_gfx_page		  :	 1;
-		bdrkreg_t	gpb_gfx_page_addr	  :	23;
-		bdrkreg_t	gpb_rsvd_1		  :	17;
-	} pi_gfx_page_b_fld_s;
-} pi_gfx_page_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This register         *
- * counts graphics credits. This counter is decremented for each        *
- * doubleword sent to graphics with GFXWS or GFXWL commands. It is      *
- * incremented for each doubleword acknowledge from graphics. When      *
- * this counter has a smaller value than the GFX_BIAS register,         *
- * SysWrRdy_L is deasserted, an interrupt is sent to the processor,     *
- * and SysWrRdy_L is allowed to be asserted again. This is the basic    *
- * mechanism for flow-controlling graphics writes.                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_credit_cntr_b_u {
-	bdrkreg_t	pi_gfx_credit_cntr_b_regval;
-	struct  {
-		bdrkreg_t	gccb_gfx_credit_cntr      :	12;
-		bdrkreg_t       gccb_rsvd                 :     52;
-	} pi_gfx_credit_cntr_b_fld_s;
-} pi_gfx_credit_cntr_b_u_t;
-
-#else
-
-typedef union pi_gfx_credit_cntr_b_u {
-	bdrkreg_t	pi_gfx_credit_cntr_b_regval;
-	struct	{
-		bdrkreg_t	gccb_rsvd		  :	52;
-		bdrkreg_t	gccb_gfx_credit_cntr	  :	12;
-	} pi_gfx_credit_cntr_b_fld_s;
-} pi_gfx_credit_cntr_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When the graphics     *
- * credit counter is less than or equal to this value, a flow control   *
- * interrupt is sent.                                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_bias_b_u {
-	bdrkreg_t	pi_gfx_bias_b_regval;
-	struct  {
-		bdrkreg_t	gbb_gfx_bias              :	12;
-		bdrkreg_t       gbb_rsvd                  :     52;
-	} pi_gfx_bias_b_fld_s;
-} pi_gfx_bias_b_u_t;
-
-#else
-
-typedef union pi_gfx_bias_b_u {
-	bdrkreg_t	pi_gfx_bias_b_regval;
-	struct	{
-		bdrkreg_t	gbb_rsvd		  :	52;
-		bdrkreg_t	gbb_gfx_bias		  :	12;
-	} pi_gfx_bias_b_fld_s;
-} pi_gfx_bias_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. When     *
- * this counter reaches the value of the GFX_INT_CMP register, an       *
- * interrupt is sent to the associated processor. At each clock         *
- * cycle, the value in this register can be changed by any one of the   *
- * following actions:                                                   *
- * - Written by software.                                               *
- * - Loaded with the value of GFX_INT_CMP, when an interrupt, NMI, or   *
- * soft reset occurs, thus preventing an additional interrupt.          *
- * - Zeroed, when the GFX_CREDIT_CNTR rises above the bias value.       *
- * - Incremented (by one at each clock) for each clock that the         *
- * GFX_CREDIT_CNTR is less than or equal to zero.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_int_cntr_b_u {
-	bdrkreg_t	pi_gfx_int_cntr_b_regval;
-	struct  {
-		bdrkreg_t	gicb_gfx_int_cntr         :	26;
-		bdrkreg_t       gicb_rsvd                 :     38;
-	} pi_gfx_int_cntr_b_fld_s;
-} pi_gfx_int_cntr_b_u_t;
-
-#else
-
-typedef union pi_gfx_int_cntr_b_u {
-	bdrkreg_t	pi_gfx_int_cntr_b_regval;
-	struct	{
-		bdrkreg_t	gicb_rsvd		  :	38;
-		bdrkreg_t	gicb_gfx_int_cntr	  :	26;
-	} pi_gfx_int_cntr_b_fld_s;
-} pi_gfx_int_cntr_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. The value in this     *
- * register is loaded into the GFX_INT_CNTR register when an            *
- * interrupt, NMI, or soft reset is sent to the processor. The value    *
- * in this register is compared to the value of GFX_INT_CNTR and an     *
- * interrupt is sent when they become equal.                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_int_cmp_b_u {
-	bdrkreg_t	pi_gfx_int_cmp_b_regval;
-	struct  {
-		bdrkreg_t	gicb_gfx_int_cmp          :	26;
-		bdrkreg_t       gicb_rsvd                 :     38;
-	} pi_gfx_int_cmp_b_fld_s;
-} pi_gfx_int_cmp_b_u_t;
-
-#else
-
-typedef union pi_gfx_int_cmp_b_u {
-	bdrkreg_t	pi_gfx_int_cmp_b_regval;
-	struct	{
-		bdrkreg_t	gicb_rsvd		  :	38;
-		bdrkreg_t	gicb_gfx_int_cmp	  :	26;
-	} pi_gfx_int_cmp_b_fld_s;
-} pi_gfx_int_cmp_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  A read of this register returns all sources of         *
- * Bedrock Error Interrupts. Storing to the write-with-clear location   *
- * clears any bit for which a one appears on the data bus. Storing to   *
- * the writable location does a direct write to all unreserved bits     *
- * (except for MEM_UNC).                                                *
- * In Synergy mode, the processor that is the source of the command     *
- * that got an error is independent of the A or B SysAD bus. So in      *
- * Synergy mode, Synergy provides the source processor number in bit    *
- * 52 of the SysAD bus in all commands. The PI saves this in the RRB    *
- * or WRB entry, and uses that value to determine which error bit (A    *
- * or B) to set, as well as which ERR_STATUS and spool registers to     *
- * use, for all error types in this register that are specified as an   *
- * error to CPU_A or CPU_B.                                             *
- * This register is not cleared at reset.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_int_pend_wr_u {
-	bdrkreg_t	pi_err_int_pend_wr_regval;
-	struct  {
-		bdrkreg_t	eipw_spool_comp_b         :	 1;
-                bdrkreg_t       eipw_spool_comp_a         :      1;
-                bdrkreg_t       eipw_spurious_b           :      1;
-                bdrkreg_t       eipw_spurious_a           :      1;
-                bdrkreg_t       eipw_wrb_terr_b           :      1;
-                bdrkreg_t       eipw_wrb_terr_a           :      1;
-                bdrkreg_t       eipw_wrb_werr_b           :      1;
-                bdrkreg_t       eipw_wrb_werr_a           :      1;
-                bdrkreg_t       eipw_sysstate_par_b       :      1;
-                bdrkreg_t       eipw_sysstate_par_a       :      1;
-                bdrkreg_t       eipw_sysad_data_ecc_b     :      1;
-                bdrkreg_t       eipw_sysad_data_ecc_a     :      1;
-                bdrkreg_t       eipw_sysad_addr_ecc_b     :      1;
-                bdrkreg_t       eipw_sysad_addr_ecc_a     :      1;
-                bdrkreg_t       eipw_syscmd_data_par_b    :      1;
-                bdrkreg_t       eipw_syscmd_data_par_a    :      1;
-                bdrkreg_t       eipw_syscmd_addr_par_b    :      1;
-                bdrkreg_t       eipw_syscmd_addr_par_a    :      1;
-                bdrkreg_t       eipw_spool_err_b          :      1;
-                bdrkreg_t       eipw_spool_err_a          :      1;
-                bdrkreg_t       eipw_ue_uncached_b        :      1;
-                bdrkreg_t       eipw_ue_uncached_a        :      1;
-                bdrkreg_t       eipw_sysstate_tag_b       :      1;
-                bdrkreg_t       eipw_sysstate_tag_a       :      1;
-                bdrkreg_t       eipw_mem_unc              :      1;
-                bdrkreg_t       eipw_sysad_bad_data_b     :      1;
-                bdrkreg_t       eipw_sysad_bad_data_a     :      1;
-                bdrkreg_t       eipw_ue_cached_b          :      1;
-                bdrkreg_t       eipw_ue_cached_a          :      1;
-                bdrkreg_t       eipw_pkt_len_err_b        :      1;
-                bdrkreg_t       eipw_pkt_len_err_a        :      1;
-                bdrkreg_t       eipw_irb_err_b            :      1;
-                bdrkreg_t       eipw_irb_err_a            :      1;
-                bdrkreg_t       eipw_irb_timeout_b        :      1;
-                bdrkreg_t       eipw_irb_timeout_a        :      1;
-                bdrkreg_t       eipw_rsvd                 :     29;
-	} pi_err_int_pend_wr_fld_s;
-} pi_err_int_pend_wr_u_t;
-
-#else
-
-typedef union pi_err_int_pend_wr_u {
-	bdrkreg_t	pi_err_int_pend_wr_regval;
-	struct	{
-		bdrkreg_t	eipw_rsvd		  :	29;
-		bdrkreg_t	eipw_irb_timeout_a	  :	 1;
-		bdrkreg_t	eipw_irb_timeout_b	  :	 1;
-		bdrkreg_t	eipw_irb_err_a		  :	 1;
-		bdrkreg_t	eipw_irb_err_b		  :	 1;
-		bdrkreg_t	eipw_pkt_len_err_a	  :	 1;
-		bdrkreg_t	eipw_pkt_len_err_b	  :	 1;
-		bdrkreg_t	eipw_ue_cached_a	  :	 1;
-		bdrkreg_t	eipw_ue_cached_b	  :	 1;
-		bdrkreg_t	eipw_sysad_bad_data_a	  :	 1;
-		bdrkreg_t	eipw_sysad_bad_data_b	  :	 1;
-		bdrkreg_t	eipw_mem_unc		  :	 1;
-		bdrkreg_t	eipw_sysstate_tag_a	  :	 1;
-		bdrkreg_t	eipw_sysstate_tag_b	  :	 1;
-		bdrkreg_t	eipw_ue_uncached_a	  :	 1;
-		bdrkreg_t	eipw_ue_uncached_b	  :	 1;
-		bdrkreg_t	eipw_spool_err_a	  :	 1;
-		bdrkreg_t	eipw_spool_err_b	  :	 1;
-		bdrkreg_t	eipw_syscmd_addr_par_a	  :	 1;
-		bdrkreg_t	eipw_syscmd_addr_par_b	  :	 1;
-		bdrkreg_t	eipw_syscmd_data_par_a	  :	 1;
-		bdrkreg_t	eipw_syscmd_data_par_b	  :	 1;
-		bdrkreg_t	eipw_sysad_addr_ecc_a	  :	 1;
-		bdrkreg_t	eipw_sysad_addr_ecc_b	  :	 1;
-		bdrkreg_t	eipw_sysad_data_ecc_a	  :	 1;
-		bdrkreg_t	eipw_sysad_data_ecc_b	  :	 1;
-		bdrkreg_t	eipw_sysstate_par_a	  :	 1;
-		bdrkreg_t	eipw_sysstate_par_b	  :	 1;
-		bdrkreg_t	eipw_wrb_werr_a		  :	 1;
-		bdrkreg_t	eipw_wrb_werr_b		  :	 1;
-		bdrkreg_t	eipw_wrb_terr_a		  :	 1;
-		bdrkreg_t	eipw_wrb_terr_b		  :	 1;
-		bdrkreg_t	eipw_spurious_a		  :	 1;
-		bdrkreg_t	eipw_spurious_b		  :	 1;
-		bdrkreg_t	eipw_spool_comp_a	  :	 1;
-		bdrkreg_t	eipw_spool_comp_b	  :	 1;
-	} pi_err_int_pend_wr_fld_s;
-} pi_err_int_pend_wr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  A read of this register returns all sources of         *
- * Bedrock Error Interrupts. Storing to the write-with-clear location   *
- * clears any bit for which a one appears on the data bus. Storing to   *
- * the writable location does a direct write to all unreserved bits     *
- * (except for MEM_UNC).                                                *
- * In Synergy mode, the processor that is the source of the command     *
- * that got an error is independent of the A or B SysAD bus. So in      *
- * Synergy mode, Synergy provides the source processor number in bit    *
- * 52 of the SysAD bus in all commands. The PI saves this in the RRB    *
- * or WRB entry, and uses that value to determine which error bit (A    *
- * or B) to set, as well as which ERR_STATUS and spool registers to     *
- * use, for all error types in this register that are specified as an   *
- * error to CPU_A or CPU_B.                                             *
- * This register is not cleared at reset.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_int_pend_u {
-	bdrkreg_t	pi_err_int_pend_regval;
-	struct  {
-		bdrkreg_t	eip_spool_comp_b          :	 1;
-                bdrkreg_t       eip_spool_comp_a          :      1;
-                bdrkreg_t       eip_spurious_b            :      1;
-                bdrkreg_t       eip_spurious_a            :      1;
-                bdrkreg_t       eip_wrb_terr_b            :      1;
-                bdrkreg_t       eip_wrb_terr_a            :      1;
-                bdrkreg_t       eip_wrb_werr_b            :      1;
-                bdrkreg_t       eip_wrb_werr_a            :      1;
-                bdrkreg_t       eip_sysstate_par_b        :      1;
-                bdrkreg_t       eip_sysstate_par_a        :      1;
-                bdrkreg_t       eip_sysad_data_ecc_b      :      1;
-                bdrkreg_t       eip_sysad_data_ecc_a      :      1;
-                bdrkreg_t       eip_sysad_addr_ecc_b      :      1;
-                bdrkreg_t       eip_sysad_addr_ecc_a      :      1;
-                bdrkreg_t       eip_syscmd_data_par_b     :      1;
-                bdrkreg_t       eip_syscmd_data_par_a     :      1;
-                bdrkreg_t       eip_syscmd_addr_par_b     :      1;
-                bdrkreg_t       eip_syscmd_addr_par_a     :      1;
-                bdrkreg_t       eip_spool_err_b           :      1;
-                bdrkreg_t       eip_spool_err_a           :      1;
-                bdrkreg_t       eip_ue_uncached_b         :      1;
-                bdrkreg_t       eip_ue_uncached_a         :      1;
-                bdrkreg_t       eip_sysstate_tag_b        :      1;
-                bdrkreg_t       eip_sysstate_tag_a        :      1;
-                bdrkreg_t       eip_mem_unc               :      1;
-                bdrkreg_t       eip_sysad_bad_data_b      :      1;
-                bdrkreg_t       eip_sysad_bad_data_a      :      1;
-                bdrkreg_t       eip_ue_cached_b           :      1;
-                bdrkreg_t       eip_ue_cached_a           :      1;
-                bdrkreg_t       eip_pkt_len_err_b         :      1;
-                bdrkreg_t       eip_pkt_len_err_a         :      1;
-                bdrkreg_t       eip_irb_err_b             :      1;
-                bdrkreg_t       eip_irb_err_a             :      1;
-                bdrkreg_t       eip_irb_timeout_b         :      1;
-                bdrkreg_t       eip_irb_timeout_a         :      1;
-                bdrkreg_t       eip_rsvd                  :     29;
-	} pi_err_int_pend_fld_s;
-} pi_err_int_pend_u_t;
-
-#else
-
-typedef union pi_err_int_pend_u {
-	bdrkreg_t	pi_err_int_pend_regval;
-	struct	{
-		bdrkreg_t	eip_rsvd		  :	29;
-		bdrkreg_t	eip_irb_timeout_a	  :	 1;
-		bdrkreg_t	eip_irb_timeout_b	  :	 1;
-		bdrkreg_t	eip_irb_err_a		  :	 1;
-		bdrkreg_t	eip_irb_err_b		  :	 1;
-		bdrkreg_t	eip_pkt_len_err_a	  :	 1;
-		bdrkreg_t	eip_pkt_len_err_b	  :	 1;
-		bdrkreg_t	eip_ue_cached_a		  :	 1;
-		bdrkreg_t	eip_ue_cached_b		  :	 1;
-		bdrkreg_t	eip_sysad_bad_data_a	  :	 1;
-		bdrkreg_t	eip_sysad_bad_data_b	  :	 1;
-		bdrkreg_t	eip_mem_unc		  :	 1;
-		bdrkreg_t	eip_sysstate_tag_a	  :	 1;
-		bdrkreg_t	eip_sysstate_tag_b	  :	 1;
-		bdrkreg_t	eip_ue_uncached_a	  :	 1;
-		bdrkreg_t	eip_ue_uncached_b	  :	 1;
-		bdrkreg_t	eip_spool_err_a		  :	 1;
-		bdrkreg_t	eip_spool_err_b		  :	 1;
-		bdrkreg_t	eip_syscmd_addr_par_a	  :	 1;
-		bdrkreg_t	eip_syscmd_addr_par_b	  :	 1;
-		bdrkreg_t	eip_syscmd_data_par_a	  :	 1;
-		bdrkreg_t	eip_syscmd_data_par_b	  :	 1;
-		bdrkreg_t	eip_sysad_addr_ecc_a	  :	 1;
-		bdrkreg_t	eip_sysad_addr_ecc_b	  :	 1;
-		bdrkreg_t	eip_sysad_data_ecc_a	  :	 1;
-		bdrkreg_t	eip_sysad_data_ecc_b	  :	 1;
-		bdrkreg_t	eip_sysstate_par_a	  :	 1;
-		bdrkreg_t	eip_sysstate_par_b	  :	 1;
-		bdrkreg_t	eip_wrb_werr_a		  :	 1;
-		bdrkreg_t	eip_wrb_werr_b		  :	 1;
-		bdrkreg_t	eip_wrb_terr_a		  :	 1;
-		bdrkreg_t	eip_wrb_terr_b		  :	 1;
-		bdrkreg_t	eip_spurious_a		  :	 1;
-		bdrkreg_t	eip_spurious_b		  :	 1;
-		bdrkreg_t	eip_spool_comp_a	  :	 1;
-		bdrkreg_t	eip_spool_comp_b	  :	 1;
-	} pi_err_int_pend_fld_s;
-} pi_err_int_pend_u_t;
-
-#endif
-
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This read/write       *
- * register masks the contents of ERR_INT_PEND to determine which       *
- * conditions cause a Level-6 interrupt to CPU_A or CPU_B. A bit set    *
- * allows the interrupt. Only one processor in a Bedrock should         *
- * enable the Memory/Directory Uncorrectable Error bit.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_int_mask_a_u {
-	bdrkreg_t	pi_err_int_mask_a_regval;
-	struct  {
-		bdrkreg_t	eima_mask                 :	35;
-		bdrkreg_t       eima_rsvd                 :     29;
-	} pi_err_int_mask_a_fld_s;
-} pi_err_int_mask_a_u_t;
-
-#else
-
-typedef union pi_err_int_mask_a_u {
-	bdrkreg_t	pi_err_int_mask_a_regval;
-	struct	{
-		bdrkreg_t	eima_rsvd		  :	29;
-		bdrkreg_t	eima_mask		  :	35;
-	} pi_err_int_mask_a_fld_s;
-} pi_err_int_mask_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This read/write       *
- * register masks the contents of ERR_INT_PEND to determine which       *
- * conditions cause a Level-6 interrupt to CPU_A or CPU_B. A bit set    *
- * allows the interrupt. Only one processor in a Bedrock should         *
- * enable the Memory/Directory Uncorrectable Error bit.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_int_mask_b_u {
-	bdrkreg_t	pi_err_int_mask_b_regval;
-	struct  {
-		bdrkreg_t	eimb_mask                 :	35;
-		bdrkreg_t       eimb_rsvd                 :     29;
-	} pi_err_int_mask_b_fld_s;
-} pi_err_int_mask_b_u_t;
-
-#else
-
-typedef union pi_err_int_mask_b_u {
-	bdrkreg_t	pi_err_int_mask_b_regval;
-	struct	{
-		bdrkreg_t	eimb_rsvd		  :	29;
-		bdrkreg_t	eimb_mask		  :	35;
-	} pi_err_int_mask_b_fld_s;
-} pi_err_int_mask_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. This     *
- * register is the address of the next write to the error stack. This   *
- * register is incremented after each such write. Only the low N bits   *
- * are incremented, where N is defined by the size of the error stack   *
- * specified in the ERR_STACK_SIZE register.                            *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_stack_addr_a_u {
-	bdrkreg_t	pi_err_stack_addr_a_regval;
-	struct  {
-		bdrkreg_t	esaa_rsvd_1               :	 3;
-                bdrkreg_t       esaa_addr                 :     30;
-                bdrkreg_t       esaa_rsvd                 :     31;
-	} pi_err_stack_addr_a_fld_s;
-} pi_err_stack_addr_a_u_t;
-
-#else
-
-typedef union pi_err_stack_addr_a_u {
-	bdrkreg_t	pi_err_stack_addr_a_regval;
-	struct	{
-		bdrkreg_t	esaa_rsvd		  :	31;
-		bdrkreg_t	esaa_addr		  :	30;
-		bdrkreg_t	esaa_rsvd_1		  :	 3;
-	} pi_err_stack_addr_a_fld_s;
-} pi_err_stack_addr_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. This     *
- * register is the address of the next write to the error stack. This   *
- * register is incremented after each such write. Only the low N bits   *
- * are incremented, where N is defined by the size of the error stack   *
- * specified in the ERR_STACK_SIZE register.                            *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_stack_addr_b_u {
-	bdrkreg_t	pi_err_stack_addr_b_regval;
-	struct  {
-		bdrkreg_t	esab_rsvd_1               :	 3;
-                bdrkreg_t       esab_addr                 :     30;
-                bdrkreg_t       esab_rsvd                 :     31;
-	} pi_err_stack_addr_b_fld_s;
-} pi_err_stack_addr_b_u_t;
-
-#else
-
-typedef union pi_err_stack_addr_b_u {
-	bdrkreg_t	pi_err_stack_addr_b_regval;
-	struct	{
-		bdrkreg_t	esab_rsvd		  :	31;
-		bdrkreg_t	esab_addr		  :	30;
-		bdrkreg_t	esab_rsvd_1		  :	 3;
-	} pi_err_stack_addr_b_fld_s;
-} pi_err_stack_addr_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Sets the size (number of 64-bit entries) in the        *
- * error stack that is spooled to local memory when an error occurs.    *
- * Table16 defines the format of each entry in the spooled error        *
- * stack.                                                               *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_stack_size_u {
-	bdrkreg_t	pi_err_stack_size_regval;
-	struct  {
-		bdrkreg_t	ess_size                  :	 4;
-                bdrkreg_t       ess_rsvd                  :     60;
-	} pi_err_stack_size_fld_s;
-} pi_err_stack_size_u_t;
-
-#else
-
-typedef union pi_err_stack_size_u {
-	bdrkreg_t	pi_err_stack_size_regval;
-	struct	{
-		bdrkreg_t	ess_rsvd		  :	60;
-		bdrkreg_t	ess_size		  :	 4;
-	} pi_err_stack_size_fld_s;
-} pi_err_stack_size_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_A and ERR_STATUS1_A registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status0_a_u {
-	bdrkreg_t	pi_err_status0_a_regval;
-	struct  {
-		bdrkreg_t	esa_error_type            :	 3;
-                bdrkreg_t       esa_proc_req_num          :      3;
-                bdrkreg_t       esa_supplemental          :     11;
-                bdrkreg_t       esa_cmd                   :      8;
-                bdrkreg_t       esa_addr                  :     37;
-                bdrkreg_t       esa_over_run              :      1;
-                bdrkreg_t       esa_valid                 :      1;
-	} pi_err_status0_a_fld_s;
-} pi_err_status0_a_u_t;
-
-#else
-
-typedef union pi_err_status0_a_u {
-	bdrkreg_t	pi_err_status0_a_regval;
-	struct	{
-		bdrkreg_t	esa_valid		  :	 1;
-		bdrkreg_t	esa_over_run		  :	 1;
-		bdrkreg_t	esa_addr		  :	37;
-		bdrkreg_t	esa_cmd			  :	 8;
-		bdrkreg_t	esa_supplemental	  :	11;
-		bdrkreg_t	esa_proc_req_num	  :	 3;
-		bdrkreg_t	esa_error_type		  :	 3;
-	} pi_err_status0_a_fld_s;
-} pi_err_status0_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_A and ERR_STATUS1_A registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status0_a_clr_u {
-	bdrkreg_t	pi_err_status0_a_clr_regval;
-	struct  {
-		bdrkreg_t	esac_error_type           :	 3;
-                bdrkreg_t       esac_proc_req_num         :      3;
-                bdrkreg_t       esac_supplemental         :     11;
-                bdrkreg_t       esac_cmd                  :      8;
-                bdrkreg_t       esac_addr                 :     37;
-                bdrkreg_t       esac_over_run             :      1;
-                bdrkreg_t       esac_valid                :      1;
-	} pi_err_status0_a_clr_fld_s;
-} pi_err_status0_a_clr_u_t;
-
-#else
-
-typedef union pi_err_status0_a_clr_u {
-	bdrkreg_t	pi_err_status0_a_clr_regval;
-	struct	{
-		bdrkreg_t	esac_valid		  :	 1;
-		bdrkreg_t	esac_over_run		  :	 1;
-		bdrkreg_t	esac_addr		  :	37;
-		bdrkreg_t	esac_cmd		  :	 8;
-		bdrkreg_t	esac_supplemental	  :	11;
-		bdrkreg_t	esac_proc_req_num	  :	 3;
-		bdrkreg_t	esac_error_type		  :	 3;
-	} pi_err_status0_a_clr_fld_s;
-} pi_err_status0_a_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_A and ERR_STATUS1_A registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status1_a_u {
-	bdrkreg_t	pi_err_status1_a_regval;
-	struct  {
-		bdrkreg_t	esa_spool_count           :	21;
-                bdrkreg_t       esa_time_out_count        :      8;
-                bdrkreg_t       esa_inval_count           :     10;
-                bdrkreg_t       esa_crb_num               :      3;
-                bdrkreg_t       esa_wrb                   :      1;
-                bdrkreg_t       esa_e_bits                :      2;
-                bdrkreg_t       esa_t_bit                 :      1;
-                bdrkreg_t       esa_i_bit                 :      1;
-                bdrkreg_t       esa_h_bit                 :      1;
-                bdrkreg_t       esa_w_bit                 :      1;
-                bdrkreg_t       esa_a_bit                 :      1;
-                bdrkreg_t       esa_r_bit                 :      1;
-                bdrkreg_t       esa_v_bit                 :      1;
-                bdrkreg_t       esa_p_bit                 :      1;
-                bdrkreg_t       esa_source                :     11;
-	} pi_err_status1_a_fld_s;
-} pi_err_status1_a_u_t;
-
-#else
-
-typedef union pi_err_status1_a_u {
-	bdrkreg_t	pi_err_status1_a_regval;
-	struct	{
-		bdrkreg_t	esa_source		  :	11;
-		bdrkreg_t	esa_p_bit		  :	 1;
-		bdrkreg_t	esa_v_bit		  :	 1;
-		bdrkreg_t	esa_r_bit		  :	 1;
-		bdrkreg_t	esa_a_bit		  :	 1;
-		bdrkreg_t	esa_w_bit		  :	 1;
-		bdrkreg_t	esa_h_bit		  :	 1;
-		bdrkreg_t	esa_i_bit		  :	 1;
-		bdrkreg_t	esa_t_bit		  :	 1;
-		bdrkreg_t	esa_e_bits		  :	 2;
-		bdrkreg_t	esa_wrb			  :	 1;
-		bdrkreg_t	esa_crb_num		  :	 3;
-		bdrkreg_t	esa_inval_count		  :	10;
-		bdrkreg_t	esa_time_out_count	  :	 8;
-		bdrkreg_t	esa_spool_count		  :	21;
-	} pi_err_status1_a_fld_s;
-} pi_err_status1_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_A and ERR_STATUS1_A registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status1_a_clr_u {
-	bdrkreg_t	pi_err_status1_a_clr_regval;
-	struct  {
-		bdrkreg_t	esac_spool_count          :	21;
-                bdrkreg_t       esac_time_out_count       :      8;
-                bdrkreg_t       esac_inval_count          :     10;
-                bdrkreg_t       esac_crb_num              :      3;
-                bdrkreg_t       esac_wrb                  :      1;
-                bdrkreg_t       esac_e_bits               :      2;
-                bdrkreg_t       esac_t_bit                :      1;
-                bdrkreg_t       esac_i_bit                :      1;
-                bdrkreg_t       esac_h_bit                :      1;
-                bdrkreg_t       esac_w_bit                :      1;
-                bdrkreg_t       esac_a_bit                :      1;
-                bdrkreg_t       esac_r_bit                :      1;
-                bdrkreg_t       esac_v_bit                :      1;
-                bdrkreg_t       esac_p_bit                :      1;
-                bdrkreg_t       esac_source               :     11;
-	} pi_err_status1_a_clr_fld_s;
-} pi_err_status1_a_clr_u_t;
-
-#else
-
-typedef union pi_err_status1_a_clr_u {
-	bdrkreg_t	pi_err_status1_a_clr_regval;
-	struct	{
-		bdrkreg_t	esac_source		  :	11;
-		bdrkreg_t	esac_p_bit		  :	 1;
-		bdrkreg_t	esac_v_bit		  :	 1;
-		bdrkreg_t	esac_r_bit		  :	 1;
-		bdrkreg_t	esac_a_bit		  :	 1;
-		bdrkreg_t	esac_w_bit		  :	 1;
-		bdrkreg_t	esac_h_bit		  :	 1;
-		bdrkreg_t	esac_i_bit		  :	 1;
-		bdrkreg_t	esac_t_bit		  :	 1;
-		bdrkreg_t	esac_e_bits		  :	 2;
-		bdrkreg_t	esac_wrb		  :	 1;
-		bdrkreg_t	esac_crb_num		  :	 3;
-		bdrkreg_t	esac_inval_count	  :	10;
-		bdrkreg_t	esac_time_out_count	  :	 8;
-		bdrkreg_t	esac_spool_count	  :	21;
-	} pi_err_status1_a_clr_fld_s;
-} pi_err_status1_a_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_B and ERR_STATUS1_B registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status0_b_u {
-	bdrkreg_t	pi_err_status0_b_regval;
-	struct  {
-		bdrkreg_t	esb_error_type            :	 3;
-                bdrkreg_t       esb_proc_request_number   :      3;
-                bdrkreg_t       esb_supplemental          :     11;
-                bdrkreg_t       esb_cmd                   :      8;
-                bdrkreg_t       esb_addr                  :     37;
-                bdrkreg_t       esb_over_run              :      1;
-                bdrkreg_t       esb_valid                 :      1;
-	} pi_err_status0_b_fld_s;
-} pi_err_status0_b_u_t;
-
-#else
-
-typedef union pi_err_status0_b_u {
-	bdrkreg_t	pi_err_status0_b_regval;
-	struct	{
-		bdrkreg_t	esb_valid		  :	 1;
-		bdrkreg_t	esb_over_run		  :	 1;
-		bdrkreg_t	esb_addr		  :	37;
-		bdrkreg_t	esb_cmd			  :	 8;
-		bdrkreg_t	esb_supplemental	  :	11;
-		bdrkreg_t	esb_proc_request_number	  :	 3;
-		bdrkreg_t	esb_error_type		  :	 3;
-	} pi_err_status0_b_fld_s;
-} pi_err_status0_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_B and ERR_STATUS1_B registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status0_b_clr_u {
-	bdrkreg_t	pi_err_status0_b_clr_regval;
-	struct  {
-		bdrkreg_t	esbc_error_type           :	 3;
-                bdrkreg_t       esbc_proc_request_number  :      3;
-                bdrkreg_t       esbc_supplemental         :     11;
-                bdrkreg_t       esbc_cmd                  :      8;
-                bdrkreg_t       esbc_addr                 :     37;
-                bdrkreg_t       esbc_over_run             :      1;
-                bdrkreg_t       esbc_valid                :      1;
-	} pi_err_status0_b_clr_fld_s;
-} pi_err_status0_b_clr_u_t;
-
-#else
-
-typedef union pi_err_status0_b_clr_u {
-	bdrkreg_t	pi_err_status0_b_clr_regval;
-	struct	{
-		bdrkreg_t	esbc_valid		  :	 1;
-		bdrkreg_t	esbc_over_run		  :	 1;
-		bdrkreg_t	esbc_addr		  :	37;
-		bdrkreg_t	esbc_cmd		  :	 8;
-		bdrkreg_t	esbc_supplemental	  :	11;
-		bdrkreg_t	esbc_proc_request_number  :	 3;
-		bdrkreg_t	esbc_error_type		  :	 3;
-	} pi_err_status0_b_clr_fld_s;
-} pi_err_status0_b_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_B and ERR_STATUS1_B registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status1_b_u {
-	bdrkreg_t	pi_err_status1_b_regval;
-	struct  {
-		bdrkreg_t	esb_spool_count           :	21;
-                bdrkreg_t       esb_time_out_count        :      8;
-                bdrkreg_t       esb_inval_count           :     10;
-                bdrkreg_t       esb_crb_num               :      3;
-                bdrkreg_t       esb_wrb                   :      1;
-                bdrkreg_t       esb_e_bits                :      2;
-                bdrkreg_t       esb_t_bit                 :      1;
-                bdrkreg_t       esb_i_bit                 :      1;
-                bdrkreg_t       esb_h_bit                 :      1;
-                bdrkreg_t       esb_w_bit                 :      1;
-                bdrkreg_t       esb_a_bit                 :      1;
-                bdrkreg_t       esb_r_bit                 :      1;
-                bdrkreg_t       esb_v_bit                 :      1;
-                bdrkreg_t       esb_p_bit                 :      1;
-                bdrkreg_t       esb_source                :     11;
-	} pi_err_status1_b_fld_s;
-} pi_err_status1_b_u_t;
-
-#else
-
-typedef union pi_err_status1_b_u {
-	bdrkreg_t	pi_err_status1_b_regval;
-	struct	{
-		bdrkreg_t	esb_source		  :	11;
-		bdrkreg_t	esb_p_bit		  :	 1;
-		bdrkreg_t	esb_v_bit		  :	 1;
-		bdrkreg_t	esb_r_bit		  :	 1;
-		bdrkreg_t	esb_a_bit		  :	 1;
-		bdrkreg_t	esb_w_bit		  :	 1;
-		bdrkreg_t	esb_h_bit		  :	 1;
-		bdrkreg_t	esb_i_bit		  :	 1;
-		bdrkreg_t	esb_t_bit		  :	 1;
-		bdrkreg_t	esb_e_bits		  :	 2;
-		bdrkreg_t	esb_wrb			  :	 1;
-		bdrkreg_t	esb_crb_num		  :	 3;
-		bdrkreg_t	esb_inval_count		  :	10;
-		bdrkreg_t	esb_time_out_count	  :	 8;
-		bdrkreg_t	esb_spool_count		  :	21;
-	} pi_err_status1_b_fld_s;
-} pi_err_status1_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_B and ERR_STATUS1_B registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status1_b_clr_u {
-	bdrkreg_t	pi_err_status1_b_clr_regval;
-	struct  {
-		bdrkreg_t	esbc_spool_count          :	21;
-                bdrkreg_t       esbc_time_out_count       :      8;
-                bdrkreg_t       esbc_inval_count          :     10;
-                bdrkreg_t       esbc_crb_num              :      3;
-                bdrkreg_t       esbc_wrb                  :      1;
-                bdrkreg_t       esbc_e_bits               :      2;
-                bdrkreg_t       esbc_t_bit                :      1;
-                bdrkreg_t       esbc_i_bit                :      1;
-                bdrkreg_t       esbc_h_bit                :      1;
-                bdrkreg_t       esbc_w_bit                :      1;
-                bdrkreg_t       esbc_a_bit                :      1;
-                bdrkreg_t       esbc_r_bit                :      1;
-                bdrkreg_t       esbc_v_bit                :      1;
-                bdrkreg_t       esbc_p_bit                :      1;
-                bdrkreg_t       esbc_source               :     11;
-	} pi_err_status1_b_clr_fld_s;
-} pi_err_status1_b_clr_u_t;
-
-#else
-
-typedef union pi_err_status1_b_clr_u {
-	bdrkreg_t	pi_err_status1_b_clr_regval;
-	struct	{
-		bdrkreg_t	esbc_source		  :	11;
-		bdrkreg_t	esbc_p_bit		  :	 1;
-		bdrkreg_t	esbc_v_bit		  :	 1;
-		bdrkreg_t	esbc_r_bit		  :	 1;
-		bdrkreg_t	esbc_a_bit		  :	 1;
-		bdrkreg_t	esbc_w_bit		  :	 1;
-		bdrkreg_t	esbc_h_bit		  :	 1;
-		bdrkreg_t	esbc_i_bit		  :	 1;
-		bdrkreg_t	esbc_t_bit		  :	 1;
-		bdrkreg_t	esbc_e_bits		  :	 2;
-		bdrkreg_t	esbc_wrb		  :	 1;
-		bdrkreg_t	esbc_crb_num		  :	 3;
-		bdrkreg_t	esbc_inval_count	  :	10;
-		bdrkreg_t	esbc_time_out_count	  :	 8;
-		bdrkreg_t	esbc_spool_count	  :	21;
-	} pi_err_status1_b_clr_fld_s;
-} pi_err_status1_b_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_spool_cmp_a_u {
-	bdrkreg_t	pi_spool_cmp_a_regval;
-	struct  {
-		bdrkreg_t	sca_compare               :	20;
-		bdrkreg_t       sca_rsvd                  :     44;
-	} pi_spool_cmp_a_fld_s;
-} pi_spool_cmp_a_u_t;
-
-#else
-
-typedef union pi_spool_cmp_a_u {
-	bdrkreg_t	pi_spool_cmp_a_regval;
-	struct	{
-		bdrkreg_t	sca_rsvd		  :	44;
-		bdrkreg_t	sca_compare		  :	20;
-	} pi_spool_cmp_a_fld_s;
-} pi_spool_cmp_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_spool_cmp_b_u {
-	bdrkreg_t	pi_spool_cmp_b_regval;
-	struct  {
-		bdrkreg_t	scb_compare               :	20;
-		bdrkreg_t       scb_rsvd                  :     44;
-	} pi_spool_cmp_b_fld_s;
-} pi_spool_cmp_b_u_t;
-
-#else
-
-typedef union pi_spool_cmp_b_u {
-	bdrkreg_t	pi_spool_cmp_b_regval;
-	struct	{
-		bdrkreg_t	scb_rsvd		  :	44;
-		bdrkreg_t	scb_compare		  :	20;
-	} pi_spool_cmp_b_fld_s;
-} pi_spool_cmp_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. A timeout can be      *
- * forced by writing one(s).                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_crb_timeout_a_u {
-	bdrkreg_t	pi_crb_timeout_a_regval;
-	struct  {
-		bdrkreg_t	cta_rrb                   :	 4;
-                bdrkreg_t       cta_wrb                   :      8;
-                bdrkreg_t       cta_rsvd                  :     52;
-	} pi_crb_timeout_a_fld_s;
-} pi_crb_timeout_a_u_t;
-
-#else
-
-typedef union pi_crb_timeout_a_u {
-	bdrkreg_t	pi_crb_timeout_a_regval;
-	struct	{
-		bdrkreg_t	cta_rsvd		  :	52;
-		bdrkreg_t	cta_wrb			  :	 8;
-		bdrkreg_t	cta_rrb			  :	 4;
-	} pi_crb_timeout_a_fld_s;
-} pi_crb_timeout_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. A timeout can be      *
- * forced by writing one(s).                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_crb_timeout_b_u {
-	bdrkreg_t	pi_crb_timeout_b_regval;
-	struct  {
-		bdrkreg_t	ctb_rrb                   :	 4;
-                bdrkreg_t       ctb_wrb                   :      8;
-                bdrkreg_t       ctb_rsvd                  :     52;
-	} pi_crb_timeout_b_fld_s;
-} pi_crb_timeout_b_u_t;
-
-#else
-
-typedef union pi_crb_timeout_b_u {
-	bdrkreg_t	pi_crb_timeout_b_regval;
-	struct	{
-		bdrkreg_t	ctb_rsvd		  :	52;
-		bdrkreg_t	ctb_wrb			  :	 8;
-		bdrkreg_t	ctb_rrb			  :	 4;
-	} pi_crb_timeout_b_fld_s;
-} pi_crb_timeout_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls error checking and forwarding of SysAD       *
- * errors.                                                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_sysad_errchk_en_u {
-	bdrkreg_t	pi_sysad_errchk_en_regval;
-	struct  {
-		bdrkreg_t	see_ecc_gen_en            :	 1;
-                bdrkreg_t       see_qual_gen_en           :      1;
-                bdrkreg_t       see_sadp_chk_en           :      1;
-                bdrkreg_t       see_cmdp_chk_en           :      1;
-                bdrkreg_t       see_state_chk_en          :      1;
-                bdrkreg_t       see_qual_chk_en           :      1;
-                bdrkreg_t       see_rsvd                  :     58;
-	} pi_sysad_errchk_en_fld_s;
-} pi_sysad_errchk_en_u_t;
-
-#else
-
-typedef union pi_sysad_errchk_en_u {
-	bdrkreg_t	pi_sysad_errchk_en_regval;
-	struct	{
-		bdrkreg_t	see_rsvd		  :	58;
-		bdrkreg_t	see_qual_chk_en		  :	 1;
-		bdrkreg_t	see_state_chk_en	  :	 1;
-		bdrkreg_t	see_cmdp_chk_en		  :	 1;
-		bdrkreg_t	see_sadp_chk_en		  :	 1;
-		bdrkreg_t	see_qual_gen_en		  :	 1;
-		bdrkreg_t	see_ecc_gen_en		  :	 1;
-	} pi_sysad_errchk_en_fld_s;
-} pi_sysad_errchk_en_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. If any bit in this    *
- * register is set, then whenever reply data arrives with the UE        *
- * (uncorrectable error) indication set, the check-bits that are        *
- * generated and sent to the SysAD will be inverted corresponding to    *
- * the bits set in the register. This will also prevent the assertion   *
- * of the data quality indicator.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_force_bad_check_bit_a_u {
-	bdrkreg_t	pi_force_bad_check_bit_a_regval;
-	struct  {
-		bdrkreg_t	fbcba_bad_check_bit       :	 8;
-		bdrkreg_t       fbcba_rsvd                :     56;
-	} pi_force_bad_check_bit_a_fld_s;
-} pi_force_bad_check_bit_a_u_t;
-
-#else
-
-typedef union pi_force_bad_check_bit_a_u {
-	bdrkreg_t	pi_force_bad_check_bit_a_regval;
-	struct	{
-		bdrkreg_t	fbcba_rsvd		  :	56;
-		bdrkreg_t	fbcba_bad_check_bit	  :	 8;
-	} pi_force_bad_check_bit_a_fld_s;
-} pi_force_bad_check_bit_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. If any bit in this    *
- * register is set, then whenever reply data arrives with the UE        *
- * (uncorrectable error) indication set, the check-bits that are        *
- * generated and sent to the SysAD will be inverted corresponding to    *
- * the bits set in the register. This will also prevent the assertion   *
- * of the data quality indicator.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_force_bad_check_bit_b_u {
-	bdrkreg_t	pi_force_bad_check_bit_b_regval;
-	struct  {
-		bdrkreg_t	fbcbb_bad_check_bit       :	 8;
-		bdrkreg_t       fbcbb_rsvd                :     56;
-	} pi_force_bad_check_bit_b_fld_s;
-} pi_force_bad_check_bit_b_u_t;
-
-#else
-
-typedef union pi_force_bad_check_bit_b_u {
-	bdrkreg_t	pi_force_bad_check_bit_b_regval;
-	struct	{
-		bdrkreg_t	fbcbb_rsvd		  :	56;
-		bdrkreg_t	fbcbb_bad_check_bit	  :	 8;
-	} pi_force_bad_check_bit_b_fld_s;
-} pi_force_bad_check_bit_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When a counter is     *
- * enabled, it increments each time a DNACK reply is received. The      *
- * counter is cleared when any other reply is received. The register    *
- * is cleared when the CNT_EN bit is zero. If a DNACK reply is          *
- * received when the counter equals the value in the NACK_CMP           *
- * register, the counter is cleared, an error response is sent to the   *
- * CPU instead of a nack response, and the NACK_INT_A/B bit is set in   *
- * INT_PEND1.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_nack_cnt_a_u {
-	bdrkreg_t	pi_nack_cnt_a_regval;
-	struct  {
-		bdrkreg_t	nca_nack_cnt              :	20;
-                bdrkreg_t       nca_cnt_en                :      1;
-                bdrkreg_t       nca_rsvd                  :     43;
-	} pi_nack_cnt_a_fld_s;
-} pi_nack_cnt_a_u_t;
-
-#else
-
-typedef union pi_nack_cnt_a_u {
-	bdrkreg_t	pi_nack_cnt_a_regval;
-	struct	{
-		bdrkreg_t	nca_rsvd		  :	43;
-		bdrkreg_t	nca_cnt_en		  :	 1;
-		bdrkreg_t	nca_nack_cnt		  :	20;
-	} pi_nack_cnt_a_fld_s;
-} pi_nack_cnt_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When a counter is     *
- * enabled, it increments each time a DNACK reply is received. The      *
- * counter is cleared when any other reply is received. The register    *
- * is cleared when the CNT_EN bit is zero. If a DNACK reply is          *
- * received when the counter equals the value in the NACK_CMP           *
- * register, the counter is cleared, an error response is sent to the   *
- * CPU instead of a nack response, and the NACK_INT_A/B bit is set in   *
- * INT_PEND1.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_nack_cnt_b_u {
-	bdrkreg_t	pi_nack_cnt_b_regval;
-	struct  {
-		bdrkreg_t	ncb_nack_cnt              :	20;
-                bdrkreg_t       ncb_cnt_en                :      1;
-                bdrkreg_t       ncb_rsvd                  :     43;
-	} pi_nack_cnt_b_fld_s;
-} pi_nack_cnt_b_u_t;
-
-#else
-
-typedef union pi_nack_cnt_b_u {
-	bdrkreg_t	pi_nack_cnt_b_regval;
-	struct	{
-		bdrkreg_t	ncb_rsvd		  :	43;
-		bdrkreg_t	ncb_cnt_en		  :	 1;
-		bdrkreg_t	ncb_nack_cnt		  :	20;
-	} pi_nack_cnt_b_fld_s;
-} pi_nack_cnt_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  The setting of this register affects both CPUs on this PI.          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_nack_cmp_u {
-	bdrkreg_t	pi_nack_cmp_regval;
-	struct  {
-		bdrkreg_t	nc_nack_cmp               :	20;
-		bdrkreg_t       nc_rsvd                   :     44;
-	} pi_nack_cmp_fld_s;
-} pi_nack_cmp_u_t;
-
-#else
-
-typedef union pi_nack_cmp_u {
-	bdrkreg_t	pi_nack_cmp_regval;
-	struct	{
-		bdrkreg_t	nc_rsvd			  :	44;
-		bdrkreg_t	nc_nack_cmp		  :	20;
-	} pi_nack_cmp_fld_s;
-} pi_nack_cmp_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls which errors are spooled. When a bit in      *
- * this register is set, the corresponding error is spooled. The        *
- * setting of this register affects both CPUs on this PI.               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_spool_mask_u {
-	bdrkreg_t	pi_spool_mask_regval;
-	struct  {
-		bdrkreg_t	sm_access_err             :	 1;
-                bdrkreg_t       sm_uncached_err           :      1;
-                bdrkreg_t       sm_dir_err                :      1;
-                bdrkreg_t       sm_timeout_err            :      1;
-                bdrkreg_t       sm_poison_err             :      1;
-                bdrkreg_t       sm_nack_oflow_err         :      1;
-                bdrkreg_t       sm_rsvd                   :     58;
-	} pi_spool_mask_fld_s;
-} pi_spool_mask_u_t;
-
-#else
-
-typedef union pi_spool_mask_u {
-	bdrkreg_t	pi_spool_mask_regval;
-	struct	{
-		bdrkreg_t	sm_rsvd			  :	58;
-		bdrkreg_t	sm_nack_oflow_err	  :	 1;
-		bdrkreg_t	sm_poison_err		  :	 1;
-		bdrkreg_t	sm_timeout_err		  :	 1;
-		bdrkreg_t	sm_dir_err		  :	 1;
-		bdrkreg_t	sm_uncached_err		  :	 1;
-		bdrkreg_t	sm_access_err		  :	 1;
-	} pi_spool_mask_fld_s;
-} pi_spool_mask_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. When the VALID bit is        *
- * zero, this register (along with SPURIOUS_HDR_1) will capture the     *
- * header of an incoming spurious message received from the XBar. A     *
- * spurious message is a message that does not match up with any of     *
- * the CRB entries. This is a read/write register, so it is cleared     *
- * by writing of all zeros.                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_spurious_hdr_0_u {
-	bdrkreg_t	pi_spurious_hdr_0_regval;
-	struct  {
-		bdrkreg_t	sh0_prev_valid_b          :	 1;
-                bdrkreg_t       sh0_prev_valid_a          :      1;
-                bdrkreg_t       sh0_rsvd                  :      4;
-                bdrkreg_t       sh0_supplemental          :     11;
-                bdrkreg_t       sh0_cmd                   :      8;
-                bdrkreg_t       sh0_addr                  :     37;
-                bdrkreg_t       sh0_tail                  :      1;
-                bdrkreg_t       sh0_valid                 :      1;
-	} pi_spurious_hdr_0_fld_s;
-} pi_spurious_hdr_0_u_t;
-
-#else
-
-typedef union pi_spurious_hdr_0_u {
-	bdrkreg_t	pi_spurious_hdr_0_regval;
-	struct	{
-		bdrkreg_t	sh0_valid		  :	 1;
-		bdrkreg_t	sh0_tail		  :	 1;
-		bdrkreg_t	sh0_addr		  :	37;
-		bdrkreg_t	sh0_cmd			  :	 8;
-		bdrkreg_t	sh0_supplemental	  :	11;
-		bdrkreg_t	sh0_rsvd		  :	 4;
-		bdrkreg_t	sh0_prev_valid_a	  :	 1;
-		bdrkreg_t	sh0_prev_valid_b	  :	 1;
-	} pi_spurious_hdr_0_fld_s;
-} pi_spurious_hdr_0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. When the VALID bit in        *
- * SPURIOUS_HDR_0 is zero, this register (along with SPURIOUS_HDR_0)    *
- * will capture the header of an incoming spurious message received     *
- * from the XBar. A spurious message is a message that does not match   *
- * up with any of the CRB entries. This is a read/write register, so    *
- * it is cleared by writing of all zeros.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_spurious_hdr_1_u {
-	bdrkreg_t	pi_spurious_hdr_1_regval;
-	struct  {
-		bdrkreg_t	sh1_rsvd                  :	53;
-		bdrkreg_t       sh1_source                :     11;
-	} pi_spurious_hdr_1_fld_s;
-} pi_spurious_hdr_1_u_t;
-
-#else
-
-typedef union pi_spurious_hdr_1_u {
-	bdrkreg_t	pi_spurious_hdr_1_regval;
-	struct	{
-		bdrkreg_t	sh1_source		  :	11;
-		bdrkreg_t	sh1_rsvd		  :	53;
-	} pi_spurious_hdr_1_fld_s;
-} pi_spurious_hdr_1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register controls the injection of errors in      *
- * outbound SysAD transfers. When a write sets a bit in this            *
- * register, the PI logic is "armed" to inject that error. At the       *
- * first transfer of the specified type, the error is injected and      *
- * the bit in this register is cleared. Writing to this register does   *
- * not cause a transaction to occur. A bit in this register will        *
- * remain set until a transaction of the specified type occurs as a     *
- * result of normal system activity. This register can be polled to     *
- * determine if an error has been injected or is still "armed".         *
- * This register does not control injection of data quality bad         *
- * indicator on a data cycle. This type of error can be created by      *
- * reading from a memory location that has an uncorrectable ECC         *
- * error.                                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_inject_u {
-	bdrkreg_t	pi_err_inject_regval;
-	struct  {
-		bdrkreg_t	ei_cmd_syscmd_par_a       :	 1;
-                bdrkreg_t       ei_data_syscmd_par_a      :      1;
-                bdrkreg_t       ei_cmd_sysad_corecc_a     :      1;
-                bdrkreg_t       ei_data_sysad_corecc_a    :      1;
-                bdrkreg_t       ei_cmd_sysad_uncecc_a     :      1;
-                bdrkreg_t       ei_data_sysad_uncecc_a    :      1;
-                bdrkreg_t       ei_sysresp_par_a          :      1;
-                bdrkreg_t       ei_reserved_1             :     25;
-                bdrkreg_t       ei_cmd_syscmd_par_b       :      1;
-                bdrkreg_t       ei_data_syscmd_par_b      :      1;
-                bdrkreg_t       ei_cmd_sysad_corecc_b     :      1;
-                bdrkreg_t       ei_data_sysad_corecc_b    :      1;
-                bdrkreg_t       ei_cmd_sysad_uncecc_b     :      1;
-                bdrkreg_t       ei_data_sysad_uncecc_b    :      1;
-                bdrkreg_t       ei_sysresp_par_b          :      1;
-                bdrkreg_t       ei_reserved               :     25;
-	} pi_err_inject_fld_s;
-} pi_err_inject_u_t;
-
-#else
-
-typedef union pi_err_inject_u {
-	bdrkreg_t	pi_err_inject_regval;
-	struct	{
-		bdrkreg_t	ei_reserved		  :	25;
-		bdrkreg_t	ei_sysresp_par_b	  :	 1;
-		bdrkreg_t	ei_data_sysad_uncecc_b	  :	 1;
-		bdrkreg_t	ei_cmd_sysad_uncecc_b	  :	 1;
-		bdrkreg_t	ei_data_sysad_corecc_b	  :	 1;
-		bdrkreg_t	ei_cmd_sysad_corecc_b	  :	 1;
-		bdrkreg_t	ei_data_syscmd_par_b	  :	 1;
-		bdrkreg_t	ei_cmd_syscmd_par_b	  :	 1;
-		bdrkreg_t	ei_reserved_1		  :	25;
-		bdrkreg_t	ei_sysresp_par_a	  :	 1;
-		bdrkreg_t	ei_data_sysad_uncecc_a	  :	 1;
-		bdrkreg_t	ei_cmd_sysad_uncecc_a	  :	 1;
-		bdrkreg_t	ei_data_sysad_corecc_a	  :	 1;
-		bdrkreg_t	ei_cmd_sysad_corecc_a	  :	 1;
-		bdrkreg_t	ei_data_syscmd_par_a	  :	 1;
-		bdrkreg_t	ei_cmd_syscmd_par_a	  :	 1;
-	} pi_err_inject_fld_s;
-} pi_err_inject_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This Read/Write location determines at what point the TRex+ is      *
- * stopped from issuing requests, based on the number of entries in     *
- * the incoming reply FIFO. When the number of entries in the Reply     *
- * FIFO is greater than the value of this register, the PI will         *
- * deassert both SysWrRdy and SysRdRdy to both processors. The Reply    *
- * FIFO has a depth of 0x3F entries, so setting this register to 0x3F   *
- * effectively disables this feature, allowing requests to be issued    *
- * always. Setting this register to 0x00 effectively lowers the         *
- * TRex+'s priority below the reply FIFO, disabling TRex+ requests      *
- * any time there is an entry waiting in the incoming FIFO.This         *
- * register is in its own 64KB page so that it can be mapped to user    *
- * space.                                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_reply_level_u {
-	bdrkreg_t	pi_reply_level_regval;
-	struct  {
-		bdrkreg_t	rl_reply_level            :	 6;
-		bdrkreg_t	rl_rsvd			  :	58;
-	} pi_reply_level_fld_s;
-} pi_reply_level_u_t;
-
-#else
-
-typedef union pi_reply_level_u {
-	bdrkreg_t	pi_reply_level_regval;
-	struct	{
-		bdrkreg_t	rl_rsvd			  :	58;
-		bdrkreg_t	rl_reply_level		  :	 6;
-	} pi_reply_level_fld_s;
-} pi_reply_level_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is used to change the graphics credit counter         *
- * operation from "Doubleword" mode to "Transaction" mode. This         *
- * register is in its own 64KB page so that it can be mapped to user    *
- * space.                                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_credit_mode_u {
-	bdrkreg_t	pi_gfx_credit_mode_regval;
-	struct  {
-		bdrkreg_t	gcm_trans_mode            :	 1;
-		bdrkreg_t       gcm_rsvd                  :     63;
-	} pi_gfx_credit_mode_fld_s;
-} pi_gfx_credit_mode_u_t;
-
-#else
-
-typedef union pi_gfx_credit_mode_u {
-	bdrkreg_t	pi_gfx_credit_mode_regval;
-	struct	{
-		bdrkreg_t	gcm_rsvd		  :	63;
-		bdrkreg_t	gcm_trans_mode		  :	 1;
-	} pi_gfx_credit_mode_fld_s;
-} pi_gfx_credit_mode_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- *  This location contains a 55-bit read/write counter that wraps to    *
- * zero when the maximum value is reached. This counter is              *
- * incremented at each rising edge of the global clock (GCLK). This     *
- * register is in its own 64KB page so that it can be mapped to user    *
- * space.                                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_counter_u {
-	bdrkreg_t	pi_rt_counter_regval;
-	struct  {
-		bdrkreg_t	rc_count                  :	55;
-		bdrkreg_t       rc_rsvd                   :      9;
-	} pi_rt_counter_fld_s;
-} pi_rt_counter_u_t;
-
-#else
-
-typedef union pi_rt_counter_u {
-	bdrkreg_t	pi_rt_counter_regval;
-	struct	{
-		bdrkreg_t	rc_rsvd			  :	 9;
-		bdrkreg_t	rc_count		  :	55;
-	} pi_rt_counter_fld_s;
-} pi_rt_counter_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls the performance counters for one CPU.        *
- * There are two counters for each CPU. Each counter can be             *
- * configured to count a variety of events. The performance counter     *
- * registers for each processor are in their own 64KB page so that      *
- * they can be mapped to user space.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntl_a_u {
-	bdrkreg_t	pi_perf_cntl_a_regval;
-	struct  {
-		bdrkreg_t	pca_cntr_0_select         :	28;
-                bdrkreg_t       pca_cntr_0_mode           :      3;
-                bdrkreg_t       pca_cntr_0_enable         :      1;
-                bdrkreg_t       pca_cntr_1_select         :     28;
-                bdrkreg_t       pca_cntr_1_mode           :      3;
-                bdrkreg_t       pca_cntr_1_enable         :      1;
-	} pi_perf_cntl_a_fld_s;
-} pi_perf_cntl_a_u_t;
-
-#else
-
-typedef union pi_perf_cntl_a_u {
-	bdrkreg_t	pi_perf_cntl_a_regval;
-	struct	{
-		bdrkreg_t	pca_cntr_1_enable	  :	 1;
-		bdrkreg_t	pca_cntr_1_mode		  :	 3;
-		bdrkreg_t	pca_cntr_1_select	  :	28;
-		bdrkreg_t	pca_cntr_0_enable	  :	 1;
-		bdrkreg_t	pca_cntr_0_mode		  :	 3;
-		bdrkreg_t	pca_cntr_0_select	  :	28;
-	} pi_perf_cntl_a_fld_s;
-} pi_perf_cntl_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register accesses the performance counter 0 for each CPU.      *
- * Each performance counter is 40-bits wide. On overflow, It wraps to   *
- * zero, sets the overflow bit in this register, and sets the           *
- * PERF_CNTR_OFLOW bit in the INT_PEND1 register.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntr0_a_u {
-	bdrkreg_t	pi_perf_cntr0_a_regval;
-	struct  {
-		bdrkreg_t	pca_count_value           :	40;
-                bdrkreg_t       pca_overflow              :      1;
-                bdrkreg_t       pca_rsvd                  :     23;
-	} pi_perf_cntr0_a_fld_s;
-} pi_perf_cntr0_a_u_t;
-
-#else
-
-typedef union pi_perf_cntr0_a_u {
-	bdrkreg_t	pi_perf_cntr0_a_regval;
-	struct	{
-		bdrkreg_t	pca_rsvd		  :	23;
-		bdrkreg_t	pca_overflow		  :	 1;
-		bdrkreg_t	pca_count_value		  :	40;
-	} pi_perf_cntr0_a_fld_s;
-} pi_perf_cntr0_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register accesses the performance counter 1for each CPU.       *
- * Each performance counter is 40-bits wide. On overflow, It wraps to   *
- * zero, sets the overflow bit in this register, and sets the           *
- * PERF_CNTR_OFLOW bit in the INT_PEND1 register.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntr1_a_u {
-	bdrkreg_t	pi_perf_cntr1_a_regval;
-	struct  {
-		bdrkreg_t	pca_count_value           :	40;
-                bdrkreg_t       pca_overflow              :      1;
-                bdrkreg_t       pca_rsvd                  :     23;
-	} pi_perf_cntr1_a_fld_s;
-} pi_perf_cntr1_a_u_t;
-
-#else
-
-typedef union pi_perf_cntr1_a_u {
-	bdrkreg_t	pi_perf_cntr1_a_regval;
-	struct	{
-		bdrkreg_t	pca_rsvd		  :	23;
-		bdrkreg_t	pca_overflow		  :	 1;
-		bdrkreg_t	pca_count_value		  :	40;
-	} pi_perf_cntr1_a_fld_s;
-} pi_perf_cntr1_a_u_t;
-
-#endif
-
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls the performance counters for one CPU.        *
- * There are two counters for each CPU. Each counter can be             *
- * configured to count a variety of events. The performance counter     *
- * registers for each processor are in their own 64KB page so that      *
- * they can be mapped to user space.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntl_b_u {
-	bdrkreg_t	pi_perf_cntl_b_regval;
-	struct  {
-		bdrkreg_t	pcb_cntr_0_select         :	28;
-                bdrkreg_t       pcb_cntr_0_mode           :      3;
-                bdrkreg_t       pcb_cntr_0_enable         :      1;
-                bdrkreg_t       pcb_cntr_1_select         :     28;
-                bdrkreg_t       pcb_cntr_1_mode           :      3;
-                bdrkreg_t       pcb_cntr_1_enable         :      1;
-	} pi_perf_cntl_b_fld_s;
-} pi_perf_cntl_b_u_t;
-
-#else
-
-typedef union pi_perf_cntl_b_u {
-	bdrkreg_t	pi_perf_cntl_b_regval;
-	struct	{
-		bdrkreg_t	pcb_cntr_1_enable	  :	 1;
-		bdrkreg_t	pcb_cntr_1_mode		  :	 3;
-		bdrkreg_t	pcb_cntr_1_select	  :	28;
-		bdrkreg_t	pcb_cntr_0_enable	  :	 1;
-		bdrkreg_t	pcb_cntr_0_mode		  :	 3;
-		bdrkreg_t	pcb_cntr_0_select	  :	28;
-	} pi_perf_cntl_b_fld_s;
-} pi_perf_cntl_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register accesses the performance counter 0 for each CPU.      *
- * Each performance counter is 40-bits wide. On overflow, It wraps to   *
- * zero, sets the overflow bit in this register, and sets the           *
- * PERF_CNTR_OFLOW bit in the INT_PEND1 register.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntr0_b_u {
-	bdrkreg_t	pi_perf_cntr0_b_regval;
-	struct  {
-		bdrkreg_t	pcb_count_value           :	40;
-                bdrkreg_t       pcb_overflow              :      1;
-                bdrkreg_t       pcb_rsvd                  :     23;
-	} pi_perf_cntr0_b_fld_s;
-} pi_perf_cntr0_b_u_t;
-
-#else
-
-typedef union pi_perf_cntr0_b_u {
-	bdrkreg_t	pi_perf_cntr0_b_regval;
-	struct	{
-		bdrkreg_t	pcb_rsvd		  :	23;
-		bdrkreg_t	pcb_overflow		  :	 1;
-		bdrkreg_t	pcb_count_value		  :	40;
-	} pi_perf_cntr0_b_fld_s;
-} pi_perf_cntr0_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register accesses the performance counter 1for each CPU.       *
- * Each performance counter is 40-bits wide. On overflow, It wraps to   *
- * zero, sets the overflow bit in this register, and sets the           *
- * PERF_CNTR_OFLOW bit in the INT_PEND1 register.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntr1_b_u {
-	bdrkreg_t	pi_perf_cntr1_b_regval;
-	struct  {
-		bdrkreg_t	pcb_count_value           :	40;
-                bdrkreg_t       pcb_overflow              :      1;
-                bdrkreg_t       pcb_rsvd                  :     23;
-	} pi_perf_cntr1_b_fld_s;
-} pi_perf_cntr1_b_u_t;
-
-#else
-
-typedef union pi_perf_cntr1_b_u {
-	bdrkreg_t	pi_perf_cntr1_b_regval;
-	struct	{
-		bdrkreg_t	pcb_rsvd		  :	23;
-		bdrkreg_t	pcb_overflow		  :	 1;
-		bdrkreg_t	pcb_count_value		  :	40;
-	} pi_perf_cntr1_b_fld_s;
-} pi_perf_cntr1_b_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-#define PI_GFX_OFFSET		(PI_GFX_PAGE_B - PI_GFX_PAGE_A)
-#define PI_GFX_PAGE_ENABLE	0x0000010000000000LL
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBPI_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubpi_next.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubpi_next.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubpi_next.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubpi_next.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,331 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBPI_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBPI_NEXT_H
-
-
-/* define for remote PI_1 space. It is always half of a node_addressspace
- * from PI_0. The normal REMOTE_HUB space for PI registers access
- * the PI_0 space, unless they are qualified by PI_1.
- */
-#define PI_0(x)			(x)
-#define PI_1(x)			((x) + 0x200000)
-#define PIREG(x,sn)		((sn) ? PI_1(x) : PI_0(x))
-
-#define PI_MIN_STACK_SIZE 4096  /* For figuring out the size to set */
-#define PI_STACK_SIZE_SHFT      12      /* 4k */
-
-#define PI_STACKADDR_OFFSET     (PI_ERR_STACK_ADDR_B - PI_ERR_STACK_ADDR_A)
-#define PI_ERRSTAT_OFFSET       (PI_ERR_STATUS0_B - PI_ERR_STATUS0_A)
-#define PI_RDCLR_OFFSET         (PI_ERR_STATUS0_A_RCLR - PI_ERR_STATUS0_A)
-/* these macros are correct, but fix their users to understand two PIs
-   and 4 CPUs (slices) per bedrock */
-#define PI_INT_MASK_OFFSET      (PI_INT_MASK0_B - PI_INT_MASK0_A)
-#define PI_INT_SET_OFFSET       (PI_CC_PEND_CLR_B - PI_CC_PEND_CLR_A)
-#define PI_NMI_OFFSET		(PI_NMI_B - PI_NMI_A)
-
-#define ERR_STACK_SIZE_BYTES(_sz) \
-       ((_sz) ? (PI_MIN_STACK_SIZE << ((_sz) - 1)) : 0)
-
-#define PI_CRB_STS_P	(1 << 9) 	/* "P" (partial word read/write) bit */
-#define PI_CRB_STS_V	(1 << 8)	/* "V" (valid) bit */
-#define PI_CRB_STS_R	(1 << 7)	/* "R" (response data sent to CPU) */
-#define PI_CRB_STS_A	(1 << 6)	/* "A" (data ack. received) bit */
-#define PI_CRB_STS_W	(1 << 5)	/* "W" (waiting for write compl.) */
-#define PI_CRB_STS_H	(1 << 4)	/* "H" (gathering invalidates) bit */
-#define PI_CRB_STS_I	(1 << 3)	/* "I" (targ. inbound invalidate) */
-#define PI_CRB_STS_T	(1 << 2)	/* "T" (targ. inbound intervention) */
-#define PI_CRB_STS_E	(0x3)		/* "E" (coherent read type) */
-
-/* When the "P" bit is set in the sk_crb_sts field of an error stack
- * entry, the "R," "A," "H," and "I" bits are actually bits 6..3 of
- * the address.  This macro extracts those address bits and shifts
- * them to their proper positions, ready to be ORed in to the rest of
- * the address (which is calculated as sk_addr << 7).
- */
-#define PI_CRB_STS_ADDR_BITS(sts) \
-    ((sts) & (PI_CRB_STS_I | PI_CRB_STS_H) | \
-     ((sts) & (PI_CRB_STS_A | PI_CRB_STS_R)) >> 1)
-
-#ifndef __ASSEMBLY__
-/*
- * format of error stack and error status registers.
- */
-
-#ifdef LITTLE_ENDIAN
-
-struct err_stack_format {
-        uint64_t      sk_err_type:  3,   /* error type        */
-                        sk_suppl   :  3,   /* lowest 3 bit of supplemental */
-                        sk_t5_req  :  3,   /* RRB T5 request number */
-                        sk_crb_num :  3,   /* WRB (0 to 7) or RRB (0 to 4) */
-                        sk_rw_rb   :  1,   /* RRB == 0, WRB == 1 */
-                        sk_crb_sts : 10,   /* status from RRB or WRB */
-                        sk_cmd     :  8,   /* message command */
-			sk_addr    : 33;   /* address */
-};
-
-#else
-
-struct err_stack_format {
-	uint64_t	sk_addr	   : 33,   /* address */
-			sk_cmd	   :  8,   /* message command */
-			sk_crb_sts : 10,   /* status from RRB or WRB */
-			sk_rw_rb   :  1,   /* RRB == 0, WRB == 1 */
-			sk_crb_num :  3,   /* WRB (0 to 7) or RRB (0 to 4) */
-			sk_t5_req  :  3,   /* RRB T5 request number */
-			sk_suppl   :  3,   /* lowest 3 bit of supplemental */
-			sk_err_type:  3;   /* error type	*/
-};
-
-#endif
-
-typedef union pi_err_stack {
-        uint64_t      pi_stk_word;
-        struct  err_stack_format pi_stk_fmt;
-} pi_err_stack_t;
-
-/* Simplified version of pi_err_status0_a_u_t (PI_ERR_STATUS0_A) */
-#ifdef LITTLE_ENDIAN
-
-struct err_status0_format {
-	uint64_t	s0_err_type	:  3,	/* Encoded error cause */
-                        s0_proc_req_num :  3,   /* Request number for RRB only */
-                        s0_supplemental : 11,   /* ncoming message sup field */
-                        s0_cmd          :  8,   /* Incoming message command */
-                        s0_addr         : 37,   /* Address */
-                        s0_over_run     :  1,   /* Subsequent errors spooled */
-			s0_valid        :  1;   /* error is valid */
-};
-
-#else
-
-struct err_status0_format {
-	uint64_t	s0_valid	:  1,	/* error is valid */
-			s0_over_run	:  1,	/* Subsequent errors spooled */
-			s0_addr		: 37,	/* Address */
-			s0_cmd		:  8,	/* Incoming message command */
-			s0_supplemental : 11,	/* ncoming message sup field */
-			s0_proc_req_num :  3,	/* Request number for RRB only */
-			s0_err_type	:  3;	/* Encoded error cause */
-};
-
-#endif
-
-
-typedef union pi_err_stat0 {
-	uint64_t	pi_stat0_word;
-        struct err_status0_format pi_stat0_fmt;
-} pi_err_stat0_t;
-
-/* Simplified version of pi_err_status1_a_u_t (PI_ERR_STATUS1_A) */
-
-#ifdef LITTLE_ENDIAN
-
-struct err_status1_format {
-	 uint64_t	s1_spl_cnt : 21,   /* number spooled to memory */
-                        s1_to_cnt  :  8,   /* crb timeout counter */
-                        s1_inval_cnt:10,   /* signed invalidate counter RRB */
-                        s1_crb_num :  3,   /* WRB (0 to 7) or RRB (0 to 4) */
-                        s1_rw_rb   :  1,   /* RRB == 0, WRB == 1 */
-                        s1_crb_sts : 10,   /* status from RRB or WRB */
-			s1_src     : 11;   /* message source */
-};
-
-#else
-
-struct err_status1_format {
-	uint64_t	s1_src	   : 11,   /* message source */
-			s1_crb_sts : 10,   /* status from RRB or WRB */
-			s1_rw_rb   :  1,   /* RRB == 0, WRB == 1 */
-			s1_crb_num :  3,   /* WRB (0 to 7) or RRB (0 to 4) */
-			s1_inval_cnt:10,   /* signed invalidate counter RRB */
-			s1_to_cnt  :  8,   /* crb timeout counter */
-			s1_spl_cnt : 21;   /* number spooled to memory */
-};
-
-#endif
-
-typedef union pi_err_stat1 {
-	uint64_t	pi_stat1_word;
-	struct err_status1_format pi_stat1_fmt;
-} pi_err_stat1_t;
-#endif
-
-/* Error stack types (sk_err_type) for reads:	*/
-#define PI_ERR_RD_AERR		0	/* Read Access Error */
-#define PI_ERR_RD_PRERR         1	/* Uncached Partitial Read */
-#define PI_ERR_RD_DERR          2	/* Directory Error */
-#define PI_ERR_RD_TERR          3	/* read timeout */
-#define PI_ERR_RD_PERR		4	/* Poison Access Violation */
-#define PI_ERR_RD_NACK		5	/* Excessive NACKs	*/
-#define PI_ERR_RD_RDE		6	/* Response Data Error	*/
-#define PI_ERR_RD_PLERR		7	/* Packet Length Error */
-/* Error stack types (sk_err_type) for writes:	*/
-#define PI_ERR_WR_WERR          0	/* Write Access Error */
-#define PI_ERR_WR_PWERR         1	/* Uncached Write Error */
-#define PI_ERR_WR_TERR          3	/* write timeout */
-#define PI_ERR_WR_RDE		6	/* Response Data Error */
-#define PI_ERR_WR_PLERR		7	/* Packet Length Error */
-
-
-/* For backwards compatibility */
-#define PI_RT_COUNT	PI_RT_COUNTER    /* Real Time Counter 		    */
-#define PI_RT_EN_A	PI_RT_INT_EN_A   /* RT int for CPU A enable         */
-#define PI_RT_EN_B	PI_RT_INT_EN_B   /* RT int for CPU B enable         */
-#define PI_PROF_EN_A	PI_PROF_INT_EN_A /* PROF int for CPU A enable       */
-#define PI_PROF_EN_B	PI_PROF_INT_EN_B /* PROF int for CPU B enable       */
-#define PI_RT_PEND_A    PI_RT_INT_PEND_A /* RT interrupt pending 	    */
-#define PI_RT_PEND_B    PI_RT_INT_PEND_B /* RT interrupt pending 	    */
-#define PI_PROF_PEND_A  PI_PROF_INT_PEND_A /* Profiling interrupt pending   */
-#define PI_PROF_PEND_B  PI_PROF_INT_PEND_B /* Profiling interrupt pending   */
-
-
-/* Bits in PI_SYSAD_ERRCHK_EN */
-#define PI_SYSAD_ERRCHK_ECCGEN  0x01    /* Enable ECC generation            */
-#define PI_SYSAD_ERRCHK_QUALGEN 0x02    /* Enable data quality signal gen.  */
-#define PI_SYSAD_ERRCHK_SADP    0x04    /* Enable SysAD parity checking     */
-#define PI_SYSAD_ERRCHK_CMDP    0x08    /* Enable SysCmd parity checking    */
-#define PI_SYSAD_ERRCHK_STATE   0x10    /* Enable SysState parity checking  */
-#define PI_SYSAD_ERRCHK_QUAL    0x20    /* Enable data quality checking     */
-#define PI_SYSAD_CHECK_ALL      0x3f    /* Generate and check all signals.  */
-
-/* CALIAS values */
-#define PI_CALIAS_SIZE_0        0
-#define PI_CALIAS_SIZE_4K       1
-#define PI_CALIAS_SIZE_8K       2
-#define PI_CALIAS_SIZE_16K      3
-#define PI_CALIAS_SIZE_32K      4
-#define PI_CALIAS_SIZE_64K      5
-#define PI_CALIAS_SIZE_128K     6
-#define PI_CALIAS_SIZE_256K     7
-#define PI_CALIAS_SIZE_512K     8
-#define PI_CALIAS_SIZE_1M       9
-#define PI_CALIAS_SIZE_2M       10
-#define PI_CALIAS_SIZE_4M       11
-#define PI_CALIAS_SIZE_8M       12
-#define PI_CALIAS_SIZE_16M      13
-#define PI_CALIAS_SIZE_32M      14
-#define PI_CALIAS_SIZE_64M      15
-
-/* Fields in PI_ERR_STATUS0_[AB] */
-#define PI_ERR_ST0_VALID_MASK	0x8000000000000000
-#define PI_ERR_ST0_VALID_SHFT	63
-
-/* Fields in PI_SPURIOUS_HDR_0 */
-#define PI_SPURIOUS_HDR_VALID_MASK	0x8000000000000000
-#define PI_SPURIOUS_HDR_VALID_SHFT	63
-
-/* Fields in PI_NACK_CNT_A/B */
-#define PI_NACK_CNT_EN_SHFT	20
-#define PI_NACK_CNT_EN_MASK	0x100000
-#define PI_NACK_CNT_MASK	0x0fffff
-#define PI_NACK_CNT_MAX		0x0fffff
-
-/* Bits in PI_ERR_INT_PEND */
-#define PI_ERR_SPOOL_CMP_B	0x000000001	/* Spool end hit high water */
-#define PI_ERR_SPOOL_CMP_A	0x000000002
-#define PI_ERR_SPUR_MSG_B	0x000000004	/* Spurious message intr.   */
-#define PI_ERR_SPUR_MSG_A	0x000000008
-#define PI_ERR_WRB_TERR_B	0x000000010	/* WRB TERR		    */
-#define PI_ERR_WRB_TERR_A	0x000000020
-#define PI_ERR_WRB_WERR_B	0x000000040	/* WRB WERR 		    */
-#define PI_ERR_WRB_WERR_A	0x000000080
-#define PI_ERR_SYSSTATE_B	0x000000100	/* SysState parity error    */
-#define PI_ERR_SYSSTATE_A	0x000000200
-#define PI_ERR_SYSAD_DATA_B	0x000000400	/* SysAD data parity error  */
-#define PI_ERR_SYSAD_DATA_A	0x000000800
-#define PI_ERR_SYSAD_ADDR_B	0x000001000	/* SysAD addr parity error  */
-#define PI_ERR_SYSAD_ADDR_A	0x000002000
-#define PI_ERR_SYSCMD_DATA_B	0x000004000	/* SysCmd data parity error */
-#define PI_ERR_SYSCMD_DATA_A	0x000008000
-#define PI_ERR_SYSCMD_ADDR_B	0x000010000	/* SysCmd addr parity error */
-#define PI_ERR_SYSCMD_ADDR_A	0x000020000
-#define PI_ERR_BAD_SPOOL_B	0x000040000	/* Error spooling to memory */
-#define PI_ERR_BAD_SPOOL_A	0x000080000
-#define PI_ERR_UNCAC_UNCORR_B	0x000100000	/* Uncached uncorrectable   */
-#define PI_ERR_UNCAC_UNCORR_A	0x000200000
-#define PI_ERR_SYSSTATE_TAG_B	0x000400000	/* SysState tag parity error */
-#define PI_ERR_SYSSTATE_TAG_A	0x000800000
-#define PI_ERR_MD_UNCORR	0x001000000	/* Must be cleared in MD    */
-#define PI_ERR_SYSAD_BAD_DATA_B	0x002000000	/* SysAD Data quality bad   */
-#define PI_ERR_SYSAD_BAD_DATA_A	0x004000000
-#define PI_ERR_UE_CACHED_B	0x008000000	/* UE during cached load    */
-#define PI_ERR_UE_CACHED_A	0x010000000
-#define PI_ERR_PKT_LEN_ERR_B	0x020000000	/* Xbar data too long/short */
-#define PI_ERR_PKT_LEN_ERR_A	0x040000000
-#define PI_ERR_IRB_ERR_B	0x080000000	/* Protocol error           */
-#define PI_ERR_IRB_ERR_A	0x100000000
-#define PI_ERR_IRB_TIMEOUT_B	0x200000000	/* IRB_B got a timeout      */
-#define PI_ERR_IRB_TIMEOUT_A	0x400000000
-
-#define PI_ERR_CLEAR_ALL_A	0x554aaaaaa
-#define PI_ERR_CLEAR_ALL_B	0x2aa555555
-
-
-/*
- * The following three macros define all possible error int pends. 
- */
-
-#define PI_FATAL_ERR_CPU_A	(PI_ERR_IRB_TIMEOUT_A	| \
-				 PI_ERR_IRB_ERR_A	| \
-				 PI_ERR_PKT_LEN_ERR_A	| \
-				 PI_ERR_SYSSTATE_TAG_A 	| \
-				 PI_ERR_BAD_SPOOL_A 	| \
-				 PI_ERR_SYSCMD_ADDR_A 	| \
-				 PI_ERR_SYSCMD_DATA_A 	| \
-				 PI_ERR_SYSAD_ADDR_A 	| \
-				 PI_ERR_SYSAD_DATA_A	| \
-				 PI_ERR_SYSSTATE_A)
-
-#define PI_MISC_ERR_CPU_A	(PI_ERR_UE_CACHED_A	| \
-				 PI_ERR_SYSAD_BAD_DATA_A| \
-				 PI_ERR_UNCAC_UNCORR_A 	| \
-				 PI_ERR_WRB_WERR_A 	| \
-				 PI_ERR_WRB_TERR_A 	| \
-				 PI_ERR_SPUR_MSG_A 	| \
-				 PI_ERR_SPOOL_CMP_A)
-
-#define PI_FATAL_ERR_CPU_B	(PI_ERR_IRB_TIMEOUT_B	| \
-				 PI_ERR_IRB_ERR_B	| \
-				 PI_ERR_PKT_LEN_ERR_B	| \
-				 PI_ERR_SYSSTATE_TAG_B 	| \
-				 PI_ERR_BAD_SPOOL_B 	| \
-				 PI_ERR_SYSCMD_ADDR_B 	| \
-				 PI_ERR_SYSCMD_DATA_B 	| \
-				 PI_ERR_SYSAD_ADDR_B 	| \
-				 PI_ERR_SYSAD_DATA_B	| \
-				 PI_ERR_SYSSTATE_B)
-
-#define PI_MISC_ERR_CPU_B	(PI_ERR_UE_CACHED_B	| \
-				 PI_ERR_SYSAD_BAD_DATA_B| \
-				 PI_ERR_UNCAC_UNCORR_B 	| \
-				 PI_ERR_WRB_WERR_B 	| \
-				 PI_ERR_WRB_TERR_B 	| \
-				 PI_ERR_SPUR_MSG_B 	| \
-				 PI_ERR_SPOOL_CMP_B)
-
-#define PI_ERR_GENERIC	(PI_ERR_MD_UNCORR)
-
-/* Values for PI_MAX_CRB_TIMEOUT and PI_CRB_SFACTOR */
-#define PMCT_MAX	0xff
-#define PCS_MAX		0xffffff
-
-/* pi_err_status0_a_u_t address shift */
-#define ERR_STAT0_ADDR_SHFT     3
-
-/* PI error read/write bit (RRB == 0, WRB == 1)	*/
-/* pi_err_status1_a_u_t.pi_err_status1_a_fld_s.esa_wrb */
-#define PI_ERR_RRB	0
-#define PI_ERR_WRB	1
-
-/* Error stack address shift, for use with pi_stk_fmt.sk_addr */
-#define ERR_STK_ADDR_SHFT	3
-
-#endif /* _ASM_IA64_SN_SN1_HUBPI_NEXT_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubspc.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubspc.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubspc.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubspc.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,24 +0,0 @@
-/*
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBSPC_H
-#define _ASM_IA64_SN_SN1_HUBSPC_H
-
-typedef enum {
-        HUBSPC_REFCOUNTERS,
-	HUBSPC_PROM
-} hubspc_subdevice_t;
-
-
-/*
- * Reference Counters
- */
-
-extern int refcounters_attach(devfs_handle_t hub);
-
-#endif /* _ASM_IA64_SN_SN1_HUBSPC_H */        
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubstat.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubstat.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubstat.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubstat.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,56 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_HUBSTAT_H
-#define _ASM_IA64_SN_SN1_HUBSTAT_H
-
-typedef int64_t 	hub_count_t;
-
-#define HUBSTAT_VERSION	1
-
-typedef struct hubstat_s {
-        char            hs_version;		/* structure version    */
-        cnodeid_t       hs_cnode;       	/* cnode of this hub    */
-        nasid_t         hs_nasid;       	/* Nasid of same        */	
-	int64_t		hs_timebase;		/* Time of first sample */
-	int64_t		hs_timestamp;		/* Time of last sample	*/
-	int64_t		hs_per_minute;		/* Ticks per minute 	*/
-
-	union {
-		hubreg_t	hs_niu_stat_rev_id; /* SN0: Status rev ID */
-		hubreg_t	hs_niu_port_status; /* SN1: Port status */
-	} hs_niu;
-
-        hub_count_t	hs_ni_retry_errors;	/* Total retry errors   */
-        hub_count_t	hs_ni_sn_errors;	/* Total sn errors      */
-        hub_count_t	hs_ni_cb_errors;	/* Total cb errors      */
-        int		hs_ni_overflows;	/* NI count overflows   */
-        hub_count_t	hs_ii_sn_errors;	/* Total sn errors      */
-        hub_count_t	hs_ii_cb_errors;	/* Total cb errors      */
-        int		hs_ii_overflows;	/* II count overflows   */
-
-	/*
-	 * Anything below this comment is intended for kernel internal-use
-	 * only and may be changed at any time.
-	 *
-	 * Any members that contain pointers or are conditionally compiled
-	 * need to be below here also.
-	 */
-        int64_t		hs_last_print;		/* When we last printed */
-        char		hs_print;		/* Should we print      */
-
-	char	       *hs_name;		/* This hub's name */
-	unsigned char	hs_maint;		/* Should we print to availmon */
-} hubstat_t;
-
-#define       hs_ni_stat_rev_id       hs_niu.hs_niu_stat_rev_id
-#define       hs_ni_port_status       hs_niu.hs_niu_port_status
-
-extern struct file_operations hub_mon_fops;
-
-#endif /* _ASM_IA64_SN_SN1_HUBSTAT_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubxb.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubxb.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubxb.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubxb.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,1288 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBXB_H
-#define _ASM_IA64_SN_SN1_HUBXB_H
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-
-#define    XB_PARMS                  0x00700000    /*
-                                                    * Controls
-                                                    * crossbar-wide
-                                                    * parameters.
-                                                    */
-
-
-
-#define    XB_SLOW_GNT               0x00700008    /*
-                                                    * Controls wavefront
-                                                    * arbiter grant
-                                                    * frequency, used to
-                                                    * slow XB grants
-                                                    */
-
-
-
-#define    XB_SPEW_CONTROL           0x00700010    /*
-                                                    * Controls spew
-                                                    * settings (debug
-                                                    * only).
-                                                    */
-
-
-
-#define    XB_IOQ_ARB_TRIGGER        0x00700018    /*
-                                                    * Controls IOQ
-                                                    * trigger level
-                                                    */
-
-
-
-#define    XB_FIRST_ERROR            0x00700090    /*
-                                                    * Records the first
-                                                    * crossbar error
-                                                    * seen.
-                                                    */
-
-
-
-#define    XB_POQ0_ERROR             0x00700020    /*
-                                                    * POQ0 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_PIQ0_ERROR             0x00700028    /*
-                                                    * PIQ0 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_POQ1_ERROR             0x00700030    /*
-                                                    * POQ1 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_PIQ1_ERROR             0x00700038    /*
-                                                    * PIQ1 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MP0_ERROR              0x00700040    /*
-                                                    * MOQ for PI0 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MP1_ERROR              0x00700048    /*
-                                                    * MOQ for PI1 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MMQ_ERROR              0x00700050    /*
-                                                    * MOQ for misc. (LB,
-                                                    * NI, II) error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MIQ_ERROR              0x00700058    /*
-                                                    * MIQ error register,
-                                                    * addtional MIQ
-                                                    * errors are logged
-                                                    * in MD &quot;Input
-                                                    * Error
-                                                    * Registers&quot;.
-                                                    */
-
-
-
-#define    XB_NOQ_ERROR              0x00700060    /* NOQ error register.    */
-
-
-
-#define    XB_NIQ_ERROR              0x00700068    /* NIQ error register.    */
-
-
-
-#define    XB_IOQ_ERROR              0x00700070    /* IOQ error register.    */
-
-
-
-#define    XB_IIQ_ERROR              0x00700078    /* IIQ error register.    */
-
-
-
-#define    XB_LOQ_ERROR              0x00700080    /* LOQ error register.    */
-
-
-
-#define    XB_LIQ_ERROR              0x00700088    /* LIQ error register.    */
-
-
-
-#define    XB_DEBUG_DATA_CTL         0x00700098    /*
-                                                    * Debug Datapath
-                                                    * Select
-                                                    */
-
-
-
-#define    XB_DEBUG_ARB_CTL          0x007000A0    /*
-                                                    * XB master debug
-                                                    * control
-                                                    */
-
-
-
-#define    XB_POQ0_ERROR_CLEAR       0x00700120    /*
-                                                    * Clears
-                                                    * XB_POQ0_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_PIQ0_ERROR_CLEAR       0x00700128    /*
-                                                    * Clears
-                                                    * XB_PIQ0_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_POQ1_ERROR_CLEAR       0x00700130    /*
-                                                    * Clears
-                                                    * XB_POQ1_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_PIQ1_ERROR_CLEAR       0x00700138    /*
-                                                    * Clears
-                                                    * XB_PIQ1_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MP0_ERROR_CLEAR        0x00700140    /*
-                                                    * Clears XB_MP0_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MP1_ERROR_CLEAR        0x00700148    /*
-                                                    * Clears XB_MP1_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MMQ_ERROR_CLEAR        0x00700150    /*
-                                                    * Clears XB_MMQ_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_XM_MIQ_ERROR_CLEAR     0x00700158    /*
-                                                    * Clears XB_MIQ_ERROR
-                                                    * register
-                                                    */
-
-
-
-#define    XB_NOQ_ERROR_CLEAR        0x00700160    /*
-                                                    * Clears XB_NOQ_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_NIQ_ERROR_CLEAR        0x00700168    /*
-                                                    * Clears XB_NIQ_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_IOQ_ERROR_CLEAR        0x00700170    /*
-                                                    * Clears XB_IOQ
-                                                    * _ERROR register.
-                                                    */
-
-
-
-#define    XB_IIQ_ERROR_CLEAR        0x00700178    /*
-                                                    * Clears XB_IIQ
-                                                    * _ERROR register.
-                                                    */
-
-
-
-#define    XB_LOQ_ERROR_CLEAR        0x00700180    /*
-                                                    * Clears XB_LOQ_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_LIQ_ERROR_CLEAR        0x00700188    /*
-                                                    * Clears XB_LIQ_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_FIRST_ERROR_CLEAR      0x00700190    /*
-                                                    * Clears
-                                                    * XB_FIRST_ERROR
-                                                    * register
-                                                    */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- *  Access to parameters which control various aspects of the           *
- * crossbar's operation.                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_parms_u {
-	bdrkreg_t	xb_parms_regval;
-	struct  {
-		bdrkreg_t	p_byp_en                  :	 1;
-                bdrkreg_t       p_rsrvd_1                 :      3;
-                bdrkreg_t       p_age_wrap                :      8;
-                bdrkreg_t       p_deadlock_to_wrap        :     20;
-                bdrkreg_t       p_tail_to_wrap            :     20;
-                bdrkreg_t       p_rsrvd                   :     12;
-	} xb_parms_fld_s;
-} xb_parms_u_t;
-
-#else
-
-typedef union xb_parms_u {
-	bdrkreg_t	xb_parms_regval;
-	struct	{
-		bdrkreg_t	p_rsrvd			  :	12;
-		bdrkreg_t	p_tail_to_wrap		  :	20;
-		bdrkreg_t	p_deadlock_to_wrap	  :	20;
-		bdrkreg_t	p_age_wrap		  :	 8;
-		bdrkreg_t	p_rsrvd_1		  :	 3;
-		bdrkreg_t	p_byp_en		  :	 1;
-	} xb_parms_fld_s;
-} xb_parms_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Sets the period of wavefront grants given to each unit. The         *
- * register's value corresponds to the number of cycles between each    *
- * wavefront grant opportunity given to the requesting unit. If set     *
- * to 0xF, no grants are given to this unit. If set to 0xE, the unit    *
- * is granted at the slowest rate (sometimes called "molasses mode").   *
- * This feature can be used to apply backpressure to a unit's output    *
- * queue(s). The setting does not affect bypass grants.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_slow_gnt_u {
-	bdrkreg_t	xb_slow_gnt_regval;
-	struct  {
-		bdrkreg_t	sg_lb_slow_gnt            :	 4;
-                bdrkreg_t       sg_ii_slow_gnt            :      4;
-                bdrkreg_t       sg_ni_slow_gnt            :      4;
-                bdrkreg_t       sg_mmq_slow_gnt           :      4;
-                bdrkreg_t       sg_mp1_slow_gnt           :      4;
-                bdrkreg_t       sg_mp0_slow_gnt           :      4;
-                bdrkreg_t       sg_pi1_slow_gnt           :      4;
-                bdrkreg_t       sg_pi0_slow_gnt           :      4;
-                bdrkreg_t       sg_rsrvd                  :     32;
-	} xb_slow_gnt_fld_s;
-} xb_slow_gnt_u_t;
-
-#else
-
-typedef union xb_slow_gnt_u {
-	bdrkreg_t	xb_slow_gnt_regval;
-	struct	{
-		bdrkreg_t	sg_rsrvd		  :	32;
-		bdrkreg_t	sg_pi0_slow_gnt		  :	 4;
-		bdrkreg_t	sg_pi1_slow_gnt		  :	 4;
-		bdrkreg_t	sg_mp0_slow_gnt		  :	 4;
-		bdrkreg_t	sg_mp1_slow_gnt		  :	 4;
-		bdrkreg_t	sg_mmq_slow_gnt		  :	 4;
-		bdrkreg_t	sg_ni_slow_gnt		  :	 4;
-		bdrkreg_t	sg_ii_slow_gnt		  :	 4;
-		bdrkreg_t	sg_lb_slow_gnt		  :	 4;
-	} xb_slow_gnt_fld_s;
-} xb_slow_gnt_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Enables snooping of internal crossbar traffic by spewing all        *
- * traffic across a selected crossbar point to the PI1 port. Only one   *
- * bit should be set at any one time, and any bit set will preclude     *
- * using the P1 for anything but a debug connection.                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_spew_control_u {
-	bdrkreg_t	xb_spew_control_regval;
-	struct  {
-		bdrkreg_t	sc_snoop_liq              :	 1;
-                bdrkreg_t       sc_snoop_iiq              :      1;
-                bdrkreg_t       sc_snoop_niq              :      1;
-                bdrkreg_t       sc_snoop_miq              :      1;
-                bdrkreg_t       sc_snoop_piq0             :      1;
-                bdrkreg_t       sc_snoop_loq              :      1;
-                bdrkreg_t       sc_snoop_ioq              :      1;
-                bdrkreg_t       sc_snoop_noq              :      1;
-                bdrkreg_t       sc_snoop_mmq              :      1;
-                bdrkreg_t       sc_snoop_mp0              :      1;
-                bdrkreg_t       sc_snoop_poq0             :      1;
-                bdrkreg_t       sc_rsrvd                  :     53;
-	} xb_spew_control_fld_s;
-} xb_spew_control_u_t;
-
-#else
-
-typedef union xb_spew_control_u {
-	bdrkreg_t	xb_spew_control_regval;
-	struct	{
-		bdrkreg_t	sc_rsrvd		  :	53;
-		bdrkreg_t	sc_snoop_poq0		  :	 1;
-		bdrkreg_t	sc_snoop_mp0		  :	 1;
-		bdrkreg_t	sc_snoop_mmq		  :	 1;
-		bdrkreg_t	sc_snoop_noq		  :	 1;
-		bdrkreg_t	sc_snoop_ioq		  :	 1;
-		bdrkreg_t	sc_snoop_loq		  :	 1;
-		bdrkreg_t	sc_snoop_piq0		  :	 1;
-		bdrkreg_t	sc_snoop_miq		  :	 1;
-		bdrkreg_t	sc_snoop_niq		  :	 1;
-		bdrkreg_t	sc_snoop_iiq		  :	 1;
-		bdrkreg_t	sc_snoop_liq		  :	 1;
-	} xb_spew_control_fld_s;
-} xb_spew_control_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Number of clocks the IOQ will wait before beginning XB              *
- * arbitration. This is set so that the slower IOQ data rate can        *
- * catch up up with the XB data rate in the IOQ buffer.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_ioq_arb_trigger_u {
-	bdrkreg_t	xb_ioq_arb_trigger_regval;
-	struct  {
-		bdrkreg_t	iat_ioq_arb_trigger       :	 4;
-	        bdrkreg_t       iat_rsrvd                 :     60;
-	} xb_ioq_arb_trigger_fld_s;
-} xb_ioq_arb_trigger_u_t;
-
-#else
-
-typedef union xb_ioq_arb_trigger_u {
-	bdrkreg_t	xb_ioq_arb_trigger_regval;
-	struct	{
-		bdrkreg_t	iat_rsrvd		  :	60;
-		bdrkreg_t	iat_ioq_arb_trigger	  :	 4;
-	} xb_ioq_arb_trigger_fld_s;
-} xb_ioq_arb_trigger_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by POQ0.Can be written to test software, will   *
- * cause an interrupt.                                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_poq0_error_u {
-	bdrkreg_t	xb_poq0_error_regval;
-	struct  {
-		bdrkreg_t	pe_invalid_xsel           :	 2;
-                bdrkreg_t       pe_rsrvd_3                :      2;
-                bdrkreg_t       pe_overflow               :      2;
-                bdrkreg_t       pe_rsrvd_2                :      2;
-                bdrkreg_t       pe_underflow              :      2;
-                bdrkreg_t       pe_rsrvd_1                :      2;
-                bdrkreg_t       pe_tail_timeout           :      2;
-                bdrkreg_t       pe_unused                 :      6;
-                bdrkreg_t       pe_rsrvd                  :     44;
-	} xb_poq0_error_fld_s;
-} xb_poq0_error_u_t;
-
-#else
-
-typedef union xb_poq0_error_u {
-	bdrkreg_t	xb_poq0_error_regval;
-	struct	{
-		bdrkreg_t	pe_rsrvd		  :	44;
-		bdrkreg_t	pe_unused		  :	 6;
-		bdrkreg_t	pe_tail_timeout		  :	 2;
-		bdrkreg_t	pe_rsrvd_1		  :	 2;
-		bdrkreg_t	pe_underflow		  :	 2;
-		bdrkreg_t	pe_rsrvd_2		  :	 2;
-		bdrkreg_t	pe_overflow		  :	 2;
-		bdrkreg_t	pe_rsrvd_3		  :	 2;
-		bdrkreg_t	pe_invalid_xsel		  :	 2;
-	} xb_poq0_error_fld_s;
-} xb_poq0_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by PIQ0. Note that the PIQ/PI interface         *
- * precludes PIQ underflow.                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_piq0_error_u {
-	bdrkreg_t	xb_piq0_error_regval;
-	struct  {
-		bdrkreg_t	pe_overflow               :	 2;
-                bdrkreg_t       pe_rsrvd_1                :      2;
-                bdrkreg_t       pe_deadlock_timeout       :      2;
-                bdrkreg_t       pe_rsrvd                  :     58;
-	} xb_piq0_error_fld_s;
-} xb_piq0_error_u_t;
-
-#else
-
-typedef union xb_piq0_error_u {
-	bdrkreg_t	xb_piq0_error_regval;
-	struct	{
-		bdrkreg_t	pe_rsrvd		  :	58;
-		bdrkreg_t	pe_deadlock_timeout	  :	 2;
-		bdrkreg_t	pe_rsrvd_1		  :	 2;
-		bdrkreg_t	pe_overflow		  :	 2;
-	} xb_piq0_error_fld_s;
-} xb_piq0_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by MP0 queue (the MOQ for processor 0). Since   *
- * the xselect is decoded on the MD/MOQ interface, no invalid xselect   *
- * errors are possible.                                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_mp0_error_u {
-	bdrkreg_t	xb_mp0_error_regval;
-	struct  {
-		bdrkreg_t	me_rsrvd_3                :	 4;
-                bdrkreg_t       me_overflow               :      2;
-                bdrkreg_t       me_rsrvd_2                :      2;
-                bdrkreg_t       me_underflow              :      2;
-                bdrkreg_t       me_rsrvd_1                :      2;
-                bdrkreg_t       me_tail_timeout           :      2;
-                bdrkreg_t       me_rsrvd                  :     50;
-	} xb_mp0_error_fld_s;
-} xb_mp0_error_u_t;
-
-#else
-
-typedef union xb_mp0_error_u {
-	bdrkreg_t	xb_mp0_error_regval;
-	struct	{
-		bdrkreg_t	me_rsrvd		  :	50;
-		bdrkreg_t	me_tail_timeout		  :	 2;
-		bdrkreg_t	me_rsrvd_1		  :	 2;
-		bdrkreg_t	me_underflow		  :	 2;
-		bdrkreg_t	me_rsrvd_2		  :	 2;
-		bdrkreg_t	me_overflow		  :	 2;
-		bdrkreg_t	me_rsrvd_3		  :	 4;
-	} xb_mp0_error_fld_s;
-} xb_mp0_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by MIQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_miq_error_u {
-	bdrkreg_t	xb_miq_error_regval;
-	struct  {
-		bdrkreg_t	me_rsrvd_1                :	 4;
-                bdrkreg_t       me_deadlock_timeout       :      4;
-                bdrkreg_t       me_rsrvd                  :     56;
-	} xb_miq_error_fld_s;
-} xb_miq_error_u_t;
-
-#else
-
-typedef union xb_miq_error_u {
-	bdrkreg_t	xb_miq_error_regval;
-	struct	{
-		bdrkreg_t	me_rsrvd		  :	56;
-		bdrkreg_t	me_deadlock_timeout	  :	 4;
-		bdrkreg_t	me_rsrvd_1		  :	 4;
-	} xb_miq_error_fld_s;
-} xb_miq_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by NOQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_noq_error_u {
-	bdrkreg_t	xb_noq_error_regval;
-	struct  {
-		bdrkreg_t	ne_rsvd                   :	 4;
-                bdrkreg_t       ne_overflow               :      4;
-                bdrkreg_t       ne_underflow              :      4;
-                bdrkreg_t       ne_tail_timeout           :      4;
-                bdrkreg_t       ne_rsrvd                  :     48;
-	} xb_noq_error_fld_s;
-} xb_noq_error_u_t;
-
-#else
-
-typedef union xb_noq_error_u {
-	bdrkreg_t	xb_noq_error_regval;
-	struct	{
-		bdrkreg_t	ne_rsrvd		  :	48;
-		bdrkreg_t	ne_tail_timeout		  :	 4;
-		bdrkreg_t	ne_underflow		  :	 4;
-		bdrkreg_t	ne_overflow		  :	 4;
-		bdrkreg_t	ne_rsvd			  :	 4;
-	} xb_noq_error_fld_s;
-} xb_noq_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by LOQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_loq_error_u {
-	bdrkreg_t	xb_loq_error_regval;
-	struct  {
-		bdrkreg_t	le_invalid_xsel           :	 2;
-                bdrkreg_t       le_rsrvd_1                :      6;
-                bdrkreg_t       le_underflow              :      2;
-                bdrkreg_t       le_rsvd                   :      2;
-                bdrkreg_t       le_tail_timeout           :      2;
-                bdrkreg_t       le_rsrvd                  :     50;
-	} xb_loq_error_fld_s;
-} xb_loq_error_u_t;
-
-#else
-
-typedef union xb_loq_error_u {
-	bdrkreg_t	xb_loq_error_regval;
-	struct	{
-		bdrkreg_t	le_rsrvd		  :	50;
-		bdrkreg_t	le_tail_timeout		  :	 2;
-		bdrkreg_t	le_rsvd			  :	 2;
-		bdrkreg_t	le_underflow		  :	 2;
-		bdrkreg_t	le_rsrvd_1		  :	 6;
-		bdrkreg_t	le_invalid_xsel		  :	 2;
-	} xb_loq_error_fld_s;
-} xb_loq_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by LIQ. Note that the LIQ only records errors   *
- * for the request channel. The reply channel can never deadlock or     *
- * overflow because it does not have hardware flow control.             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_liq_error_u {
-	bdrkreg_t	xb_liq_error_regval;
-	struct  {
-		bdrkreg_t	le_overflow               :	 1;
-                bdrkreg_t       le_rsrvd_1                :      3;
-                bdrkreg_t       le_deadlock_timeout       :      1;
-                bdrkreg_t       le_rsrvd                  :     59;
-	} xb_liq_error_fld_s;
-} xb_liq_error_u_t;
-
-#else
-
-typedef union xb_liq_error_u {
-	bdrkreg_t	xb_liq_error_regval;
-	struct	{
-		bdrkreg_t	le_rsrvd		  :	59;
-		bdrkreg_t	le_deadlock_timeout	  :	 1;
-		bdrkreg_t	le_rsrvd_1		  :	 3;
-		bdrkreg_t	le_overflow		  :	 1;
-	} xb_liq_error_fld_s;
-} xb_liq_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  First error is latched whenever the Valid bit is clear and an       *
- * error occurs. Any valid bit on in this register causes an            *
- * interrupt to PI0 and PI1. This interrupt bit will persist until      *
- * the specific error register to capture the error is cleared, then    *
- * the FIRST_ERROR register is cleared (in that oder.) The              *
- * FIRST_ERROR register is not writable, but will be set when any of    *
- * the corresponding error registers are written by software.           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_first_error_u {
-	bdrkreg_t	xb_first_error_regval;
-	struct  {
-		bdrkreg_t	fe_type                   :	 4;
-                bdrkreg_t       fe_channel                :      4;
-                bdrkreg_t       fe_source                 :      4;
-                bdrkreg_t       fe_valid                  :      1;
-                bdrkreg_t       fe_rsrvd                  :     51;
-	} xb_first_error_fld_s;
-} xb_first_error_u_t;
-
-#else
-
-typedef union xb_first_error_u {
-	bdrkreg_t	xb_first_error_regval;
-	struct	{
-		bdrkreg_t	fe_rsrvd		  :	51;
-		bdrkreg_t	fe_valid		  :	 1;
-		bdrkreg_t	fe_source		  :	 4;
-		bdrkreg_t	fe_channel		  :	 4;
-		bdrkreg_t	fe_type			  :	 4;
-	} xb_first_error_fld_s;
-} xb_first_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Controls DEBUG_DATA mux setting. Allows user to watch the output    *
- * of any OQ or input of any IQ on the DEBUG port. Note that bits       *
- * 13:0 are one-hot. If more than one bit is set in [13:0], the debug   *
- * output is undefined. Details on the debug output lines can be        *
- * found in the XB chapter of the Bedrock Interface Specification.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_debug_data_ctl_u {
-	bdrkreg_t	xb_debug_data_ctl_regval;
-	struct  {
-		bdrkreg_t	ddc_observe_liq_traffic   :	 1;
-                bdrkreg_t       ddc_observe_iiq_traffic   :      1;
-                bdrkreg_t       ddc_observe_niq_traffic   :      1;
-                bdrkreg_t       ddc_observe_miq_traffic   :      1;
-                bdrkreg_t       ddc_observe_piq1_traffic  :      1;
-                bdrkreg_t       ddc_observe_piq0_traffic  :      1;
-                bdrkreg_t       ddc_observe_loq_traffic   :      1;
-                bdrkreg_t       ddc_observe_ioq_traffic   :      1;
-                bdrkreg_t       ddc_observe_noq_traffic   :      1;
-                bdrkreg_t       ddc_observe_mp1_traffic   :      1;
-                bdrkreg_t       ddc_observe_mp0_traffic   :      1;
-                bdrkreg_t       ddc_observe_mmq_traffic   :      1;
-                bdrkreg_t       ddc_observe_poq1_traffic  :      1;
-                bdrkreg_t       ddc_observe_poq0_traffic  :      1;
-                bdrkreg_t       ddc_observe_source_field  :      1;
-                bdrkreg_t       ddc_observe_lodata        :      1;
-                bdrkreg_t       ddc_rsrvd                 :     48;
-	} xb_debug_data_ctl_fld_s;
-} xb_debug_data_ctl_u_t;
-
-#else
-
-typedef union xb_debug_data_ctl_u {
-	bdrkreg_t	xb_debug_data_ctl_regval;
-	struct	{
-		bdrkreg_t	ddc_rsrvd		  :	48;
-		bdrkreg_t	ddc_observe_lodata	  :	 1;
-		bdrkreg_t	ddc_observe_source_field  :	 1;
-		bdrkreg_t	ddc_observe_poq0_traffic  :	 1;
-		bdrkreg_t	ddc_observe_poq1_traffic  :	 1;
-		bdrkreg_t	ddc_observe_mmq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_mp0_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_mp1_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_noq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_ioq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_loq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_piq0_traffic  :	 1;
-		bdrkreg_t	ddc_observe_piq1_traffic  :	 1;
-		bdrkreg_t	ddc_observe_miq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_niq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_iiq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_liq_traffic	  :	 1;
-	} xb_debug_data_ctl_fld_s;
-} xb_debug_data_ctl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Controls debug mux setting for XB Input/Output Queues and           *
- * Arbiter. Can select one of the following values. Details on the      *
- * debug output lines can be found in the XB chapter of the Bedrock     *
- * Interface Specification.                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_debug_arb_ctl_u {
-	bdrkreg_t	xb_debug_arb_ctl_regval;
-	struct  {
-		bdrkreg_t	dac_xb_debug_select       :	 3;
-		bdrkreg_t       dac_rsrvd                 :     61;
-	} xb_debug_arb_ctl_fld_s;
-} xb_debug_arb_ctl_u_t;
-
-#else
-
-typedef union xb_debug_arb_ctl_u {
-        bdrkreg_t       xb_debug_arb_ctl_regval;
-        struct  {
-                bdrkreg_t       dac_rsrvd                 :     61;
-                bdrkreg_t       dac_xb_debug_select       :      3;
-        } xb_debug_arb_ctl_fld_s;
-} xb_debug_arb_ctl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by POQ0.Can be written to test software, will   *
- * cause an interrupt.                                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_poq0_error_clear_u {
-	bdrkreg_t	xb_poq0_error_clear_regval;
-	struct  {
-		bdrkreg_t	pec_invalid_xsel          :	 2;
-                bdrkreg_t       pec_rsrvd_3               :      2;
-                bdrkreg_t       pec_overflow              :      2;
-                bdrkreg_t       pec_rsrvd_2               :      2;
-                bdrkreg_t       pec_underflow             :      2;
-                bdrkreg_t       pec_rsrvd_1               :      2;
-                bdrkreg_t       pec_tail_timeout          :      2;
-                bdrkreg_t       pec_unused                :      6;
-                bdrkreg_t       pec_rsrvd                 :     44;
-	} xb_poq0_error_clear_fld_s;
-} xb_poq0_error_clear_u_t;
-
-#else
-
-typedef union xb_poq0_error_clear_u {
-	bdrkreg_t	xb_poq0_error_clear_regval;
-	struct	{
-		bdrkreg_t	pec_rsrvd		  :	44;
-		bdrkreg_t	pec_unused		  :	 6;
-		bdrkreg_t	pec_tail_timeout	  :	 2;
-		bdrkreg_t	pec_rsrvd_1		  :	 2;
-		bdrkreg_t	pec_underflow		  :	 2;
-		bdrkreg_t	pec_rsrvd_2		  :	 2;
-		bdrkreg_t	pec_overflow		  :	 2;
-		bdrkreg_t	pec_rsrvd_3		  :	 2;
-		bdrkreg_t	pec_invalid_xsel	  :	 2;
-	} xb_poq0_error_clear_fld_s;
-} xb_poq0_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by PIQ0. Note that the PIQ/PI interface         *
- * precludes PIQ underflow.                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_piq0_error_clear_u {
-	bdrkreg_t	xb_piq0_error_clear_regval;
-	struct  {
-		bdrkreg_t	pec_overflow              :	 2;
-                bdrkreg_t       pec_rsrvd_1               :      2;
-                bdrkreg_t       pec_deadlock_timeout      :      2;
-                bdrkreg_t       pec_rsrvd                 :     58;
-	} xb_piq0_error_clear_fld_s;
-} xb_piq0_error_clear_u_t;
-
-#else
-
-typedef union xb_piq0_error_clear_u {
-	bdrkreg_t	xb_piq0_error_clear_regval;
-	struct	{
-		bdrkreg_t	pec_rsrvd		  :	58;
-		bdrkreg_t	pec_deadlock_timeout	  :	 2;
-		bdrkreg_t	pec_rsrvd_1		  :	 2;
-		bdrkreg_t	pec_overflow		  :	 2;
-	} xb_piq0_error_clear_fld_s;
-} xb_piq0_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by MP0 queue (the MOQ for processor 0). Since   *
- * the xselect is decoded on the MD/MOQ interface, no invalid xselect   *
- * errors are possible.                                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_mp0_error_clear_u {
-	bdrkreg_t	xb_mp0_error_clear_regval;
-	struct  {
-		bdrkreg_t	mec_rsrvd_3               :	 4;
-                bdrkreg_t       mec_overflow              :      2;
-                bdrkreg_t       mec_rsrvd_2               :      2;
-                bdrkreg_t       mec_underflow             :      2;
-                bdrkreg_t       mec_rsrvd_1               :      2;
-                bdrkreg_t       mec_tail_timeout          :      2;
-                bdrkreg_t       mec_rsrvd                 :     50;
-	} xb_mp0_error_clear_fld_s;
-} xb_mp0_error_clear_u_t;
-
-#else
-
-typedef union xb_mp0_error_clear_u {
-	bdrkreg_t	xb_mp0_error_clear_regval;
-	struct	{
-		bdrkreg_t	mec_rsrvd		  :	50;
-		bdrkreg_t	mec_tail_timeout	  :	 2;
-		bdrkreg_t	mec_rsrvd_1		  :	 2;
-		bdrkreg_t	mec_underflow		  :	 2;
-		bdrkreg_t	mec_rsrvd_2		  :	 2;
-		bdrkreg_t	mec_overflow		  :	 2;
-		bdrkreg_t	mec_rsrvd_3		  :	 4;
-	} xb_mp0_error_clear_fld_s;
-} xb_mp0_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by MIQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_xm_miq_error_clear_u {
-	bdrkreg_t	xb_xm_miq_error_clear_regval;
-	struct  {
-		bdrkreg_t	xmec_rsrvd_1              :	 4;
-                bdrkreg_t       xmec_deadlock_timeout     :      4;
-                bdrkreg_t       xmec_rsrvd                :     56;
-	} xb_xm_miq_error_clear_fld_s;
-} xb_xm_miq_error_clear_u_t;
-
-#else
-
-typedef union xb_xm_miq_error_clear_u {
-	bdrkreg_t	xb_xm_miq_error_clear_regval;
-	struct	{
-		bdrkreg_t	xmec_rsrvd		  :	56;
-		bdrkreg_t	xmec_deadlock_timeout	  :	 4;
-		bdrkreg_t	xmec_rsrvd_1		  :	 4;
-	} xb_xm_miq_error_clear_fld_s;
-} xb_xm_miq_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by NOQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_noq_error_clear_u {
-	bdrkreg_t	xb_noq_error_clear_regval;
-	struct  {
-		bdrkreg_t	nec_rsvd                  :	 4;
-                bdrkreg_t       nec_overflow              :      4;
-                bdrkreg_t       nec_underflow             :      4;
-                bdrkreg_t       nec_tail_timeout          :      4;
-                bdrkreg_t       nec_rsrvd                 :     48;
-	} xb_noq_error_clear_fld_s;
-} xb_noq_error_clear_u_t;
-
-#else
-
-typedef union xb_noq_error_clear_u {
-	bdrkreg_t	xb_noq_error_clear_regval;
-	struct	{
-		bdrkreg_t	nec_rsrvd		  :	48;
-		bdrkreg_t	nec_tail_timeout	  :	 4;
-		bdrkreg_t	nec_underflow		  :	 4;
-		bdrkreg_t	nec_overflow		  :	 4;
-		bdrkreg_t	nec_rsvd		  :	 4;
-	} xb_noq_error_clear_fld_s;
-} xb_noq_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by LOQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_loq_error_clear_u {
-	bdrkreg_t	xb_loq_error_clear_regval;
-	struct  {
-		bdrkreg_t	lec_invalid_xsel          :	 2;
-                bdrkreg_t       lec_rsrvd_1               :      6;
-                bdrkreg_t       lec_underflow             :      2;
-                bdrkreg_t       lec_rsvd                  :      2;
-                bdrkreg_t       lec_tail_timeout          :      2;
-                bdrkreg_t       lec_rsrvd                 :     50;
-	} xb_loq_error_clear_fld_s;
-} xb_loq_error_clear_u_t;
-
-#else
-
-typedef union xb_loq_error_clear_u {
-	bdrkreg_t	xb_loq_error_clear_regval;
-	struct	{
-		bdrkreg_t	lec_rsrvd		  :	50;
-		bdrkreg_t	lec_tail_timeout	  :	 2;
-		bdrkreg_t	lec_rsvd		  :	 2;
-		bdrkreg_t	lec_underflow		  :	 2;
-		bdrkreg_t	lec_rsrvd_1		  :	 6;
-		bdrkreg_t	lec_invalid_xsel	  :	 2;
-	} xb_loq_error_clear_fld_s;
-} xb_loq_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by LIQ. Note that the LIQ only records errors   *
- * for the request channel. The reply channel can never deadlock or     *
- * overflow because it does not have hardware flow control.             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_liq_error_clear_u {
-	bdrkreg_t	xb_liq_error_clear_regval;
-	struct  {
-		bdrkreg_t	lec_overflow              :	 1;
-                bdrkreg_t       lec_rsrvd_1               :      3;
-                bdrkreg_t       lec_deadlock_timeout      :      1;
-                bdrkreg_t       lec_rsrvd                 :     59;
-	} xb_liq_error_clear_fld_s;
-} xb_liq_error_clear_u_t;
-
-#else
-
-typedef union xb_liq_error_clear_u {
-        bdrkreg_t       xb_liq_error_clear_regval;
-        struct  {
-                bdrkreg_t       lec_rsrvd                 :     59;
-                bdrkreg_t       lec_deadlock_timeout      :      1;
-                bdrkreg_t       lec_rsrvd_1               :      3;
-                bdrkreg_t       lec_overflow              :      1;
-        } xb_liq_error_clear_fld_s;
-} xb_liq_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  First error is latched whenever the Valid bit is clear and an       *
- * error occurs. Any valid bit on in this register causes an            *
- * interrupt to PI0 and PI1. This interrupt bit will persist until      *
- * the specific error register to capture the error is cleared, then    *
- * the FIRST_ERROR register is cleared (in that oder.) The              *
- * FIRST_ERROR register is not writable, but will be set when any of    *
- * the corresponding error registers are written by software.           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_first_error_clear_u {
-	bdrkreg_t	xb_first_error_clear_regval;
-	struct  {
-		bdrkreg_t	fec_type                  :	 4;
-                bdrkreg_t       fec_channel               :      4;
-                bdrkreg_t       fec_source                :      4;
-                bdrkreg_t       fec_valid                 :      1;
-                bdrkreg_t       fec_rsrvd                 :     51;
-	} xb_first_error_clear_fld_s;
-} xb_first_error_clear_u_t;
-
-#else
-
-typedef union xb_first_error_clear_u {
-	bdrkreg_t	xb_first_error_clear_regval;
-	struct	{
-		bdrkreg_t	fec_rsrvd		  :	51;
-		bdrkreg_t	fec_valid		  :	 1;
-		bdrkreg_t	fec_source		  :	 4;
-		bdrkreg_t	fec_channel		  :	 4;
-		bdrkreg_t	fec_type		  :	 4;
-	} xb_first_error_clear_fld_s;
-} xb_first_error_clear_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- * The following defines were not formed into structures                *
- *                                                                      *
- * This could be because the document did not contain details of the    *
- * register, or because the automated script did not recognize the      *
- * register details in the documentation. If these register need        *
- * structure definition, please create them manually                    *
- *                                                                      *
- *           XB_POQ1_ERROR            0x700030                          *
- *           XB_PIQ1_ERROR            0x700038                          *
- *           XB_MP1_ERROR             0x700048                          *
- *           XB_MMQ_ERROR             0x700050                          *
- *           XB_NIQ_ERROR             0x700068                          *
- *           XB_IOQ_ERROR             0x700070                          *
- *           XB_IIQ_ERROR             0x700078                          *
- *           XB_POQ1_ERROR_CLEAR      0x700130                          *
- *           XB_PIQ1_ERROR_CLEAR      0x700138                          *
- *           XB_MP1_ERROR_CLEAR       0x700148                          *
- *           XB_MMQ_ERROR_CLEAR       0x700150                          *
- *           XB_NIQ_ERROR_CLEAR       0x700168                          *
- *           XB_IOQ_ERROR_CLEAR       0x700170                          *
- *           XB_IIQ_ERROR_CLEAR       0x700178                          *
- *                                                                      *
- ************************************************************************/
-
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBXB_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubxb_next.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubxb_next.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hubxb_next.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hubxb_next.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,32 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBXB_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBXB_NEXT_H
-
-/* XB_FIRST_ERROR fe_source field encoding */
-#define XVE_SOURCE_POQ0 0xf	/* 1111 */
-#define XVE_SOURCE_PIQ0 0xe	/* 1110 */
-#define XVE_SOURCE_POQ1 0xd	/* 1101 */
-#define XVE_SOURCE_PIQ1 0xc	/* 1100 */
-#define XVE_SOURCE_MP0  0xb	/* 1011 */
-#define XVE_SOURCE_MP1  0xa	/* 1010 */
-#define XVE_SOURCE_MMQ  0x9	/* 1001 */
-#define XVE_SOURCE_MIQ  0x8	/* 1000 */
-#define XVE_SOURCE_NOQ  0x7	/* 0111 */
-#define XVE_SOURCE_NIQ  0x6	/* 0110 */
-#define XVE_SOURCE_IOQ  0x5	/* 0101 */
-#define XVE_SOURCE_IIQ  0x4	/* 0100 */
-#define XVE_SOURCE_LOQ  0x3	/* 0011 */
-#define XVE_SOURCE_LIQ  0x2	/* 0010 */
-
-/* XB_PARMS fields */
-#define XBP_RESET_DEFAULTS	0x0008000080000021LL
-#define XBP_ACTIVE_DEFAULTS	0x00080000fffff021LL
-
-#endif /* _ASM_IA64_SN_SN1_HUBXB_NEXT_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hwcntrs.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hwcntrs.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/hwcntrs.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/hwcntrs.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,96 +0,0 @@
-/*
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HWCNTRS_H
-#define _ASM_IA64_SN_SN1_HWCNTRS_H
-
-
-typedef  uint64_t refcnt_t;
-
-#define SN0_REFCNT_MAX_COUNTERS 64
-
-typedef struct sn0_refcnt_set {
-	refcnt_t    refcnt[SN0_REFCNT_MAX_COUNTERS];
-        uint64_t  flags;
-        uint64_t  reserved[4];
-} sn0_refcnt_set_t;
-
-typedef struct sn0_refcnt_buf {
-	sn0_refcnt_set_t   refcnt_set;
-	uint64_t         paddr;
-        uint64_t         page_size;
-        cnodeid_t          cnodeid;         /* cnodeid + pad[3] use 64 bits */
-        uint16_t           pad[3];
-        uint64_t         reserved[4];
-} sn0_refcnt_buf_t;
-
-typedef struct sn0_refcnt_args {
-	uint64_t          vaddr;
-	uint64_t          len;
-	sn0_refcnt_buf_t*   buf;
-        uint64_t          reserved[4];
-} sn0_refcnt_args_t;
-
-/*
- * Info needed by the user level program
- * to mmap the refcnt buffer
- */
-
-#define RCB_INFO_GET  1
-#define RCB_SLOT_GET  2
-
-typedef struct rcb_info {
-        uint64_t  rcb_len;                  /* total refcnt buffer len in bytes */
-
-        int         rcb_sw_sets;              /* number of sw counter sets in buffer */
-        int         rcb_sw_counters_per_set;  /* sw counters per set -- num_compact_nodes */
-        int         rcb_sw_counter_size;      /* sizeof(refcnt_t) -- size of sw cntr */
-
-        int         rcb_base_pages;           /* number of base pages in node */
-        int         rcb_base_page_size;       /* sw base page size */        
-        uint64_t  rcb_base_paddr;           /* base physical address for this node */
-
-        int         rcb_cnodeid;              /* cnodeid for this node */
-        int         rcb_granularity;          /* hw page size used for counter sets */
-        uint        rcb_hw_counter_max;       /* max hwcounter count (width mask) */
-        int         rcb_diff_threshold;       /* current node differential threshold */
-        int         rcb_abs_threshold;        /* current node absolute threshold */
-        int         rcb_num_slots;            /* physmem slots */
-        
-        int         rcb_reserved[512];
-        
-} rcb_info_t;
-
-typedef struct rcb_slot {
-        uint64_t  base;
-        uint64_t  size;
-} rcb_slot_t;
-
-#if defined(__KERNEL__)
-typedef struct sn0_refcnt_args_32 {
-	uint64_t    vaddr;
-	uint64_t    len;
-	app32_ptr_t   buf;
-        uint64_t    reserved[4];
-} sn0_refcnt_args_32_t;
-
-/* Defines and Macros  */
-/* A set of reference counts are for 4k bytes of physical memory */
-#define	NBPREFCNTP	0x1000	
-#define	BPREFCNTPSHIFT	12
-#define bytes_to_refcntpages(x)	(((__psunsigned_t)(x)+(NBPREFCNTP-1))>>BPREFCNTPSHIFT)
-#define refcntpage_offset(x)	((__psunsigned_t)(x)&((NBPP-1)&~(NBPREFCNTP-1)))
-#define align_to_refcntpage(x)	((__psunsigned_t)(x)&(~(NBPREFCNTP-1)))
-
-extern void migr_refcnt_read(sn0_refcnt_buf_t*);
-extern void migr_refcnt_read_extended(sn0_refcnt_buf_t*);
-extern int migr_refcnt_enabled(void);
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_IA64_SN_SN1_HWCNTRS_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/intr.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/intr.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/intr.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/intr.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,237 +0,0 @@
-/* $Id: intr.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_INTR_H
-#define _ASM_IA64_SN_SN1_INTR_H
-
-/* Subnode wildcard */
-#define SUBNODE_ANY		(-1)
-
-/* Number of interrupt levels associated with each interrupt register. */
-#define N_INTPEND_BITS		64
-
-#define INT_PEND0_BASELVL	0
-#define INT_PEND1_BASELVL	64
-
-#define	N_INTPENDJUNK_BITS	8
-#define	INTPENDJUNK_CLRBIT	0x80
-
-#include <asm/sn/intr_public.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/hack.h>
-
-#ifndef __ASSEMBLY__
-#define II_NAMELEN	24
-
-/*
- * Dispatch table entry - contains information needed to call an interrupt
- * routine.
- */
-typedef struct intr_vector_s {
-	intr_func_t	iv_func;	/* Interrupt handler function */
-	intr_func_t	iv_prefunc;	/* Interrupt handler prologue func */
-	void		*iv_arg;	/* Argument to pass to handler */
-	cpuid_t			iv_mustruncpu;	/* Where we must run. */
-} intr_vector_t;
-
-/* Interrupt information table. */
-typedef struct intr_info_s {
-	xtalk_intr_setfunc_t	ii_setfunc;	/* Function to set the interrupt
-						 * destination and level register.
-						 * It returns 0 (success) or an
-						 * error code.
-						 */
-	void			*ii_cookie;	/* arg passed to setfunc */
-	devfs_handle_t		ii_owner_dev;	/* device that owns this intr */
-	char			ii_name[II_NAMELEN];	/* Name of this intr. */
-	int			ii_flags;	/* informational flags */
-} intr_info_t;
-
-
-#define THD_CREATED	0x00000001	/*
-					 * We've created a thread for this
-					 * interrupt.
-					 */
-
-/*
- * Bits for ii_flags:
- */
-#define II_UNRESERVE	0
-#define II_RESERVE	1		/* Interrupt reserved. 			*/
-#define II_INUSE	2		/* Interrupt connected 			*/
-#define II_ERRORINT	4		/* INterrupt is an error condition 	*/
-#define II_THREADED	8		/* Interrupt handler is threaded.	*/
-
-/*
- * Interrupt level wildcard
- */
-#define INTRCONNECT_ANYBIT	(-1)
-
-/*
- * This structure holds information needed both to call and to maintain
- * interrupts.  The two are in separate arrays for the locality benefits.
- * Since there's only one set of vectors per hub chip (but more than one
- * CPU, the lock to change the vector tables must be here rather than in
- * the PDA.
- */
-
-typedef struct intr_vecblk_s {
-	intr_vector_t	vectors[N_INTPEND_BITS];  /* information needed to
-						     call an intr routine. */
-	intr_info_t	info[N_INTPEND_BITS];	  /* information needed only
-						     to maintain interrupts. */
-	spinlock_t	vector_lock;		  /* Lock for this and the
-						     masks in the PDA. */
-	splfunc_t	vector_spl;		  /* vector_lock req'd spl */
-	int		vector_state;		  /* Initialized to zero.
-						     Set to INTR_INITED
-						     by hubintr_init.
-						   */
-	int		vector_count;		  /* Number of vectors
-						   * reserved.
-						   */
-	int		cpu_count[CPUS_PER_SUBNODE]; /* How many interrupts are
-						   * connected to each CPU
-						   */
-	int		ithreads_enabled;	  /* Are interrupt threads
-						   * initialized on this node.
-						   * and block?
-						   */
-} intr_vecblk_t;
-
-/* Possible values for vector_state: */
-#define VECTOR_UNINITED	0
-#define VECTOR_INITED	1
-#define VECTOR_SET	2
-
-#define hub_intrvect0	private.p_intmasks.dispatch0->vectors
-#define hub_intrvect1	private.p_intmasks.dispatch1->vectors
-#define hub_intrinfo0	private.p_intmasks.dispatch0->info
-#define hub_intrinfo1	private.p_intmasks.dispatch1->info
-
-/*
- * Macros to manipulate the interrupt register on the calling hub chip.
- */
-
-#define LOCAL_HUB_SEND_INTR(_level)	LOCAL_HUB_S(PI_INT_PEND_MOD, \
-						    (0x100|(_level)))
-#define REMOTE_HUB_PI_SEND_INTR(_hub, _sn, _level) \
-		REMOTE_HUB_PI_S((_hub), _sn, PI_INT_PEND_MOD, (0x100|(_level)))
-
-#define REMOTE_CPU_SEND_INTR(_cpuid, _level) 					\
-		REMOTE_HUB_PI_S(cpuid_to_nasid(_cpuid),				\
-			SUBNODE(cpuid_to_slice(_cpuid)),				\
-			PI_INT_PEND_MOD, (0x100|(_level)))
-
-/*
- * When clearing the interrupt, make sure this clear does make it 
- * to the hub. Otherwise we could end up losing interrupts.
- * We do an uncached load of the int_pend0 register to ensure this.
- */
-
-#define LOCAL_HUB_CLR_INTR(_level)	  \
-                LOCAL_HUB_S(PI_INT_PEND_MOD, (_level)),	\
-                LOCAL_HUB_L(PI_INT_PEND0)
-#define REMOTE_HUB_PI_CLR_INTR(_hub, _sn, _level) \
-		REMOTE_HUB_PI_S((_hub), (_sn), PI_INT_PEND_MOD, (_level)),	\
-                REMOTE_HUB_PI_L((_hub), (_sn), PI_INT_PEND0)
-
-/* Special support for use by gfx driver only.  Supports special gfx hub interrupt. */
-extern void install_gfxintr(cpuid_t cpu, ilvl_t swlevel, intr_func_t intr_func, void *intr_arg);
-
-void setrtvector(intr_func_t func);
-
-/*
- * Interrupt blocking
- */
-extern void intr_block_bit(cpuid_t cpu, int bit);
-extern void intr_unblock_bit(cpuid_t cpu, int bit);
-
-#endif /* __ASSEMBLY__ */
-
-/*
- * Hard-coded interrupt levels:
- */
-
-/*
- *	L0 = SW1
- *	L1 = SW2
- *	L2 = INT_PEND0
- *	L3 = INT_PEND1
- *	L4 = RTC
- *	L5 = Profiling Timer
- *	L6 = Hub Errors
- *	L7 = Count/Compare (T5 counters)
- */
-
-
-/* INT_PEND0 hard-coded bits. */
-#ifdef DEBUG_INTR_TSTAMP
-/* hard coded interrupt level for interrupt latency test interrupt */
-#define	CPU_INTRLAT_B	62
-#define	CPU_INTRLAT_A	61
-#endif
-
-/* Hardcoded bits required by software. */
-#define MSC_MESG_INTR	9
-#define CPU_ACTION_B	8
-#define CPU_ACTION_A	7
-
-/* These are determined by hardware: */
-#define CC_PEND_B	6
-#define CC_PEND_A	5
-#define UART_INTR	4
-#define PG_MIG_INTR	3
-#define GFX_INTR_B	2
-#define GFX_INTR_A	1
-#define RESERVED_INTR	0
-
-/* INT_PEND1 hard-coded bits: */
-#define MSC_PANIC_INTR	63
-#define NI_ERROR_INTR	62
-#define MD_COR_ERR_INTR	61
-#define COR_ERR_INTR_B	60
-#define COR_ERR_INTR_A	59
-#define CLK_ERR_INTR	58
-
-# define NACK_INT_B	57
-# define NACK_INT_A	56
-# define LB_ERROR	55
-# define XB_ERROR	54
-
-#define BRIDGE_ERROR_INTR 53	/* Setup by PROM to catch Bridge Errors */
-
-#define IP27_INTR_0	52	/* Reserved for PROM use */
-#define IP27_INTR_1	51	/*   (do not use in Kernel) */
-#define IP27_INTR_2	50
-#define IP27_INTR_3	49
-#define IP27_INTR_4	48
-#define IP27_INTR_5	47
-#define IP27_INTR_6	46
-#define IP27_INTR_7	45
-
-#define	TLB_INTR_B	44	/* used for tlb flush random */
-#define	TLB_INTR_A	43
-
-#define LLP_PFAIL_INTR_B 42	/* see ml/SN/SN0/sysctlr.c */
-#define LLP_PFAIL_INTR_A 41
-
-#define NI_BRDCAST_ERR_B 40
-#define NI_BRDCAST_ERR_A 39
-
-# define IO_ERROR_INTR	38	/* set up by prom */
-# define DEBUG_INTR_B	37	/* used by symmon to stop all cpus */
-# define DEBUG_INTR_A	36
-
-// These aren't strictly accurate or complete.  See the
-// Synergy Spec. for details.
-#define SGI_UART_IRQ	(65)
-#define SGI_HUB_ERROR_IRQ	(182)
-
-#endif /* _ASM_IA64_SN_SN1_INTR_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/intr_public.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/intr_public.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/intr_public.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/intr_public.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,53 +0,0 @@
-/* $Id: intr_public.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_INTR_PUBLIC_H
-#define _ASM_IA64_SN_SN1_INTR_PUBLIC_H
-
-/* REMEMBER: If you change these, the whole world needs to be recompiled.
- * It would also require changing the hubspl.s code and SN0/intr.c
- * Currently, the spl code has no support for multiple INTPEND1 masks.
- */
-
-#define	N_INTPEND0_MASKS	1
-#define	N_INTPEND1_MASKS	1
-
-#define INTPEND0_MAXMASK	(N_INTPEND0_MASKS - 1)
-#define INTPEND1_MAXMASK	(N_INTPEND1_MASKS - 1)
-
-#ifndef __ASSEMBLY__
-#include <asm/sn/arch.h>
-
-struct intr_vecblk_s;	/* defined in asm/sn/intr.h */
-
-/*
- * The following are necessary to create the illusion of a CEL
- * on the IP27 hub.  We'll add more priority levels soon, but for
- * now, any interrupt in a particular band effectively does an spl.
- * These must be in the PDA since they're different for each processor.
- * Users of this structure must hold the vector_lock in the appropriate vector
- * block before modifying the mask arrays.  There's only one vector block
- * for each Hub so a lock in the PDA wouldn't be adequate.
- */
-typedef struct hub_intmasks_s {
-	/*
-	 * The masks are stored with the lowest-priority (most inclusive)
-	 * in the lowest-numbered masks (i.e., 0, 1, 2...).
-	 */
-	/* INT_PEND0: */
-	hubreg_t		intpend0_masks[N_INTPEND0_MASKS]; 
-	/* INT_PEND1: */
-	hubreg_t		intpend1_masks[N_INTPEND1_MASKS];
-	/* INT_PEND0: */
-	struct intr_vecblk_s	*dispatch0;	
-	/* INT_PEND1: */
-	struct intr_vecblk_s	*dispatch1;
-} hub_intmasks_t;
-
-#endif /* __ASSEMBLY__ */
-#endif /* _ASM_IA64_SN_SN1_INTR_PUBLIC_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/ip27config.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/ip27config.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/ip27config.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/ip27config.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,657 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_IP27CONFIG_H
-#define _ASM_IA64_SN_SN1_IP27CONFIG_H
-
-
-/*
- * Structure: 	ip27config_s
- * Typedef:	ip27config_t
- * Purpose: 	Maps out the region of the boot prom used to define
- *		configuration information.
- * Notes:       Corresponds to ip27config structure found in start.s.
- *		Fields are ulong where possible to facilitate IP27 PROM fetches.
- */
-
-#define CONFIG_INFO_OFFSET		0x60
-
-#define IP27CONFIG_ADDR			(LBOOT_BASE	    + \
-					 CONFIG_INFO_OFFSET)
-#define IP27CONFIG_ADDR_NODE(n)		(NODE_RBOOT_BASE(n) + \
-					 CONFIG_INFO_OFFSET)
-
-/* Offset to the config_type field within local ip27config structure */
-#define CONFIG_FLAGS_ADDR			(IP27CONFIG_ADDR + 72)
-/* Offset to the config_type field in the ip27config structure on 
- * node with nasid n
- */
-#define CONFIG_FLAGS_ADDR_NODE(n)		(IP27CONFIG_ADDR_NODE(n) + 72)
-
-/* Meaning of each valid bit in the config flags 
- * None are currently defined
- */
-
-/* Meaning of each mach_type value
- */
-#define SN1_MACH_TYPE 0
-
-/*
- * Since 800 ns works well with various HUB frequencies, (such as 360,
- * 380, 390, and 400 MHZ), we now use 800ns rtc cycle time instead of
- * 1 microsec.
- */
-#define IP27_RTC_FREQ			1250	/* 800ns cycle time */
-
-#ifndef __ASSEMBLY__
-
-typedef	struct ip27config_s {		/* KEEP IN SYNC w/ start.s & below  */
-    uint		time_const;	/* Time constant 		    */
-    uint		r10k_mode;	/* R10k boot mode bits 		    */
-
-    uint64_t		magic;		/* CONFIG_MAGIC			    */
-
-    uint64_t		freq_cpu;	/* Hz 				    */
-    uint64_t		freq_hub;	/* Hz 				    */
-    uint64_t		freq_rtc;	/* Hz 				    */
-
-    uint		ecc_enable;	/* ECC enable flag		    */
-    uint		fprom_cyc;	/* FPROM_CYC speed control  	    */
-
-    uint		mach_type;	/* Inidicate IP27 (0) or Sn00 (1)    */
-
-    uint		check_sum_adj;	/* Used after config hdr overlay    */
-					/* to make the checksum 0 again     */
-    uint		flash_count;	/* Value incr'd on each PROM flash  */
-    uint		fprom_wr;	/* FPROM_WR speed control  	    */
-
-    uint		pvers_vers;	/* Prom version number		    */
-    uint		pvers_rev;	/* Prom revision number		    */
-    uint		config_type;	/* To support special configurations
-					 * (none currently defined)
-					 */
-} ip27config_t;
-
-typedef	struct {
-    uint		r10k_mode;	/* R10k boot mode bits 		    */
-    uint		freq_cpu;	/* Hz 				    */
-    uint		freq_hub;	/* Hz 				    */
-    char		fprom_cyc;	/* FPROM_CYC speed control  	    */
-    char		mach_type;	/* IP35(0) is only type defined      */
-    char		fprom_wr;	/* FPROM_WR speed control  	    */
-} config_modifiable_t;
-
-#define IP27CONFIG		(*(ip27config_t *) IP27CONFIG_ADDR)
-#define IP27CONFIG_NODE(n)	(*(ip27config_t *) IP27CONFIG_ADDR_NODE(n))
-#define SN00			0 /* IP35 has no Speedo equivalent */
-
-/* Get the config flags from local ip27config */
-#define CONFIG_FLAGS		(*(uint *) (CONFIG_FLAGS_ADDR))
-
-/* Get the config flags from ip27config on the node
- * with nasid n
- */
-#define CONFIG_FLAGS_NODE(n)	(*(uint *) (CONFIG_FLAGS_ADDR_NODE(n)))
-
-/* Macro to check if the local ip27config indicates a config
- * of 12 p 4io
- */
-#define CONFIG_12P4I		(0) /* IP35 has no 12p4i equivalent */
-
-/* Macro to check if the ip27config on node with nasid n
- * indicates a config of 12 p 4io
- */
-#define CONFIG_12P4I_NODE(n)	(0)
-
-#endif /* __ASSEMBLY__ */
-
-#if __ASSEMBLY__
-	.struct		0		/* KEEP IN SYNC WITH C structure */
-
-ip27c_time_const:	.word	0
-ip27c_r10k_mode:	.word	0
-
-ip27c_magic:		.dword	0
-
-ip27c_freq_cpu:		.dword	0
-ip27c_freq_hub:		.dword	0
-ip27c_freq_rtc:		.dword	0
-
-ip27c_ecc_enable:	.word	1
-ip27c_fprom_cyc:	.word	0
-
-ip27c_mach_type:	.word	0
-ip27c_check_sum_adj:	.word	0
-
-ip27c_flash_count:	.word	0
-ip27c_fprom_wr:		.word	0
-
-ip27c_pvers_vers:	.word	0
-ip27c_pvers_rev:	.word	0
-
-ip27c_config_type:	.word 	0	/* To recognize special configs */
-#endif /* __ASSEMBLY__ */
-
-/*
- * R10000 Configuration Cycle - These define the SYSAD values used
- * during the reset cycle.
- */
-
-#define	IP27C_R10000_KSEG0CA_SHFT	0
-#define	IP27C_R10000_KSEG0CA_MASK	(7 << IP27C_R10000_KSEG0CA_SHFT)
-#define	IP27C_R10000_KSEG0CA(_B)	 ((_B) << IP27C_R10000_KSEG0CA_SHFT)
-
-#define	IP27C_R10000_DEVNUM_SHFT	3
-#define	IP27C_R10000_DEVNUM_MASK	(3 << IP27C_R10000_DEVNUM_SHFT)
-#define	IP27C_R10000_DEVNUM(_B)		((_B) << IP27C_R10000_DEVNUM_SHFT)
-
-#define	IP27C_R10000_CRPT_SHFT		5
-#define	IP27C_R10000_CRPT_MASK		(1 << IP27C_R10000_CRPT_SHFT)
-#define	IP27C_R10000_CPRT(_B)		((_B)<<IP27C_R10000_CRPT_SHFT)
-
-#define	IP27C_R10000_PER_SHFT		6
-#define	IP27C_R10000_PER_MASK		(1 << IP27C_R10000_PER_SHFT)
-#define	IP27C_R10000_PER(_B)		((_B) << IP27C_R10000_PER_SHFT)
-
-#define	IP27C_R10000_PRM_SHFT		7
-#define	IP27C_R10000_PRM_MASK		(3 << IP27C_R10000_PRM_SHFT)
-#define	IP27C_R10000_PRM(_B)		((_B) << IP27C_R10000_PRM_SHFT)
-
-#define	IP27C_R10000_SCD_SHFT		9
-#define	IP27C_R10000_SCD_MASK		(0xf << IP27C_R10000_SCD_MASK)
-#define	IP27C_R10000_SCD(_B)		((_B) << IP27C_R10000_SCD_SHFT)
-
-#define	IP27C_R10000_SCBS_SHFT		13
-#define	IP27C_R10000_SCBS_MASK		(1 << IP27C_R10000_SCBS_SHFT)
-#define	IP27C_R10000_SCBS(_B)		(((_B)) << IP27C_R10000_SCBS_SHFT)
-
-#define	IP27C_R10000_SCCE_SHFT		14
-#define	IP27C_R10000_SCCE_MASK		(1 << IP27C_R10000_SCCE_SHFT)
-#define	IP27C_R10000_SCCE(_B)		((_B) << IP27C_R10000_SCCE_SHFT)
-
-#define	IP27C_R10000_ME_SHFT		15
-#define	IP27C_R10000_ME_MASK		(1 << IP27C_R10000_ME_SHFT)
-#define	IP27C_R10000_ME(_B)		((_B) << IP27C_R10000_ME_SHFT)
-
-#define	IP27C_R10000_SCS_SHFT		16
-#define	IP27C_R10000_SCS_MASK		(7 << IP27C_R10000_SCS_SHFT)
-#define	IP27C_R10000_SCS(_B)		((_B) << IP27C_R10000_SCS_SHFT)
-
-#define	IP27C_R10000_SCCD_SHFT		19
-#define	IP27C_R10000_SCCD_MASK		(7 << IP27C_R10000_SCCD_SHFT)
-#define	IP27C_R10000_SCCD(_B)		((_B) << IP27C_R10000_SCCD_SHFT)
-
-#define	IP27C_R10000_DDR_SHFT		23
-#define	IP27C_R10000_DDR_MASK		(1 << IP27C_R10000_DDR_SHFT)
-#define	IP27C_R10000_DDR(_B)		((_B) << IP27C_R10000_DDR_SHFT)
-
-#define	IP27C_R10000_SCCT_SHFT		25
-#define	IP27C_R10000_SCCT_MASK		(0xf << IP27C_R10000_SCCT_SHFT)
-#define	IP27C_R10000_SCCT(_B)		((_B) << IP27C_R10000_SCCT_SHFT)
-
-#define	IP27C_R10000_ODSC_SHFT		29
-#define IP27C_R10000_ODSC_MASK		(1 << IP27C_R10000_ODSC_SHFT)
-#define	IP27C_R10000_ODSC(_B)		((_B) << IP27C_R10000_ODSC_SHFT)
-
-#define	IP27C_R10000_ODSYS_SHFT		30
-#define	IP27C_R10000_ODSYS_MASK		(1 << IP27C_R10000_ODSYS_SHFT)
-#define	IP27C_R10000_ODSYS(_B)		((_B) << IP27C_R10000_ODSYS_SHFT)
-
-#define	IP27C_R10000_CTM_SHFT		31
-#define	IP27C_R10000_CTM_MASK		(1 << IP27C_R10000_CTM_SHFT)
-#define	IP27C_R10000_CTM(_B)		((_B) << IP27C_R10000_CTM_SHFT)
-
-#define IP27C_MHZ(x)			(1000000 * (x))
-#define IP27C_KHZ(x)			(1000 * (x))
-#define IP27C_MB(x)			((x) << 20)
-
-/*
- * PROM Configurations
- */
-
-#define CONFIG_MAGIC		0x69703237636f6e66
-
-/* The high 32 bits of the "mode bits".  Bits 7..0 contain one more
- * than the number of 5ms clocks in the 100ms "long delay" intervals
- * of the TRex reset sequence.  Bit 8 is the "synergy mode" bit.
- */
-#define CONFIG_TIME_CONST	0x15
-
-#define CONFIG_ECC_ENABLE	1
-#define CONFIG_CHECK_SUM_ADJ	0
-#define CONFIG_DEFAULT_FLASH_COUNT    0
-
-/*
- * Some promICEs have trouble if CONFIG_FPROM_SETUP is too low.
- * The nominal value for 100 MHz hub is 5, for 200MHz bedrock is 16.
- * any update to the below should also reflected in the logic in
- *   IO7prom/flashprom.c function _verify_config_info and _fill_in_config_info
- */
-
-/* default junk bus timing values to use */
-#define CONFIG_SYNERGY_ENABLE	0xff
-#define CONFIG_SYNERGY_SETUP	0xff
-#define CONFIG_UART_ENABLE	0x0c
-#define CONFIG_UART_SETUP	0x02
-#define CONFIG_FPROM_ENABLE	0x10
-#define CONFIG_FPROM_SETUP	0x10
-
-#define CONFIG_FREQ_RTC	IP27C_KHZ(IP27_RTC_FREQ)
-
-#ifndef __ASSEMBLY__
-
-/* we are going to define all the known configs is a table
- * for building hex images we will pull out the particular
- * slice we care about by using the IP27_CONFIG_XX_XX as
- * entries into the table
- * to keep the table of reasonable size we only include the
- * values that differ across configurations
- * please note then that this makes assumptions about what
- * will and will not change across configurations
- */
-
-/* these numbers are as the are ordered in the table below */
-#define	IP27_CONFIG_UNKNOWN (-1)
-#define IP27_CONFIG_SN1_1MB_200_400_200_TABLE 0
-#define IP27_CONFIG_SN00_4MB_100_200_133_TABLE 1
-#define IP27_CONFIG_SN1_4MB_200_400_267_TABLE 2
-#define IP27_CONFIG_SN1_8MB_200_500_250_TABLE 3
-#define IP27_CONFIG_SN1_8MB_200_400_267_TABLE 4
-#define IP27_CONFIG_SN1_4MB_180_360_240_TABLE 5
-#define NUMB_IP_CONFIGS 6
-
-#ifdef DEF_IP_CONFIG_TABLE
-/*
- * N.B.: A new entry needs to be added here everytime a new config is added
- * The table is indexed by the PIMM PSC value
- */
-
-static int psc_to_flash_config[] = {
-        IP27_CONFIG_SN1_4MB_200_400_267_TABLE,	/* 0x0 */
-        IP27_CONFIG_SN1_8MB_200_500_250_TABLE,	/* 0x1 */
-        IP27_CONFIG_SN1_8MB_200_400_267_TABLE,	/* 0x2 */
-        IP27_CONFIG_UNKNOWN,	/* 0x3 */
-        IP27_CONFIG_UNKNOWN,	/* 0x4 */
-        IP27_CONFIG_UNKNOWN,	/* 0x5 */
-        IP27_CONFIG_UNKNOWN,	/* 0x6 */
-        IP27_CONFIG_UNKNOWN,	/* 0x7 */
-        IP27_CONFIG_SN1_4MB_180_360_240_TABLE,	/* 0x8 */
-        IP27_CONFIG_UNKNOWN,	/* 0x9 */
-        IP27_CONFIG_UNKNOWN,	/* 0xa */
-        IP27_CONFIG_UNKNOWN,	/* 0xb */
-        IP27_CONFIG_UNKNOWN,	/* 0xc */
-        IP27_CONFIG_UNKNOWN,	/* 0xd */
-        IP27_CONFIG_SN00_4MB_100_200_133_TABLE, /* 0xe  O200 PIMM for bringup */
-        IP27_CONFIG_UNKNOWN	/* 0xf == PIMM not installed */
-};
-
-static config_modifiable_t ip_config_table[NUMB_IP_CONFIGS] = {
-/* the 1MB_200_400_200 values (Generic settings, will work for any config.) */
-{
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(1)	 + \
-	 IP27C_R10000_SCCD(3)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(400),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-/* the 4MB_100_200_133 values (O200 PIMM w/translation board, PSC 0xe)
- * (SysAD at 100MHz (SCD=3), and bedrock core at 200 MHz) */
-{
- /* ODSYS == 0 means HSTL1 on SysAD bus; other PIMMs use HSTL2 */
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(0)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(200),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-/* 4MB_200_400_267 values (R12KS, 3.7ns, LWR, 030-1602-001, PSC 0x0) */
-{
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(400),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-/* 8MB_200_500_250 values (R14K, 4.0ns, DDR1, 030-1520-001, PSC 0x1) */
-{
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(4)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(4)	 + \
-	 IP27C_R10000_DDR(1)     + \
-	 IP27C_R10000_SCCD(3)	 + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(500),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-/* 8MB_200_400_267 values (R12KS, 3.7ns, LWR, 030-1616-001, PSC 0x2) */
-{
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(4)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(400),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-/* 4MB_180_360_240 values (R12KS, 3.7ns, LWR, 030-1627-001, PSC 0x8)
- * (SysAD at 180 MHz (SCD=3, the fastest possible), bedrock core at 200MHz) */
-{
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(360),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-};
-#else
-extern	config_modifiable_t	ip_config_table[];
-#endif /* DEF_IP27_CONFIG_TABLE */
-
-#ifdef IP27_CONFIG_SN00_4MB_100_200_133
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN00_4MB_100_200_133 */
-
-#ifdef IP27_CONFIG_SN1_1MB_200_400_200
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN1_1MB_200_400_200 */
-
-#ifdef IP27_CONFIG_SN1_4MB_200_400_267
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN1_4MB_200_400_267 */
-
-#ifdef IP27_CONFIG_SN1_8MB_200_500_250
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN1_8MB_200_500_250 */
-
-#ifdef IP27_CONFIG_SN1_8MB_200_400_267
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN1_8MB_200_400_267 */
-
-#ifdef IP27_CONFIG_SN1_4MB_180_360_240
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN1_4MB_180_360_240 */
-
-#endif /* __ASSEMBLY__ */
-
-#if __ASSEMBLY__
-
-/* these need to be in here since we need assembly definitions
- * for building hex images (as required by start.s)
- */
-#ifdef IP27_CONFIG_SN00_4MB_100_200_133
-#define	BRINGUP_PRM_VAL	3
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(BRINGUP_PRM_VAL)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(0)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(200)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN00_4MB_100_200_133 */
-
-#ifdef IP27_CONFIG_SN1_1MB_200_400_200
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(1)	 + \
-	 IP27C_R10000_SCCD(3)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(400)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN1_1MB_200_400_200 */
-
-#ifdef IP27_CONFIG_SN1_4MB_200_400_267
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(400)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN1_4MB_200_400_267 */
-
-#ifdef IP27_CONFIG_SN1_8MB_200_500_250
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(4)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(4)	 + \
-	 IP27C_R10000_SCCD(3)	 + \
-         IP27C_R10000_DDR(1)     + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(500)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN1_8MB_200_500_250 */
-
-#ifdef IP27_CONFIG_SN1_8MB_200_400_267
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(4)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(400)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN1_8MB_200_400_267 */
-
-#ifdef IP27_CONFIG_SN1_4MB_180_360_240
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(360)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN1_4MB_180_360_240 */
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_IA64_SN_SN1_IP27CONFIG_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/mem_refcnt.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/mem_refcnt.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/mem_refcnt.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/mem_refcnt.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,25 +0,0 @@
-/*
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_MEM_REFCNT_H
-#define _ASM_IA64_SN_SN1_MEM_REFCNT_H
-
-extern int mem_refcnt_attach(devfs_handle_t hub);
-extern int mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp);
-extern int mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp);
-extern int mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot);
-extern int mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt);
-extern int mem_refcnt_ioctl(devfs_handle_t dev,
-                 int cmd,
-                 void *arg,
-                 int mode,
-                 cred_t *cred_p,
-                 int *rvalp);
-        
-
-#endif /* _ASM_IA64_SN_SN1_MEM_REFCNT_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/mmzone_sn1.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/mmzone_sn1.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/mmzone_sn1.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/mmzone_sn1.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,149 +0,0 @@
-#ifndef _ASM_IA64_SN_MMZONE_SN1_H
-#define _ASM_IA64_SN_MMZONE_SN1_H
-
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/config.h>
-
-
-/*
- * SGI SN1 Arch defined values
- *
- * 	An SN1 physical address is broken down as follows:
- *
- *             +-----------------------------------------+
- *             |         |    |      |   node offset     |
- *             | unused  | AS | node |-------------------|
- *             |         |    |      | cn | clump offset |
- *             +-----------------------------------------+
- *              6       4 4  4 3    3 3  3 2            0
- *              3       4 3  0 9    3 2  0 9            0
- *
- *		bits 63-44	Unused - must be zero
- *		bits 43-40	Address space ID. Cached memory has a value of 0.
- *				Chipset & IO addresses have non-zero values.
- *		bits 39-33	Node number. Note that some configurations do NOT
- *				have a node zero.
- *		bits 32-0	Node offset.
- *
- *	The node offset can be further broken down as:
- *		bits 32-30	Clump (bank) number.
- *		bits 29-0	Clump (bank) offset.
- *
- *	A node consists of up to 8 clumps (banks) of memory. A clump may be empty, or may be
- *	populated with a single contiguous block of memory starting at clump
- *	offset 0. The size of the block is (2**n) * 64MB, where 0<n<5.
- *
- *
- * NOTE: This file exports symbols prefixed with "PLAT_". Symbols prefixed with
- *	 "SN_" are intended for internal use only and should not be used in
- *	 any platform independent code. 
- *
- *	 This file is also responsible for exporting the following definitions:
- *		cnodeid_t	Define a compact node id. 
- */
-
-typedef signed short cnodeid_t;
-
-#define SN1_BANKS_PER_NODE		8
-#define SN1_NODE_SIZE			(8UL*1024*1024*1024)	/* 8 GB per node */
-#define SN1_BANK_SIZE			(SN1_NODE_SIZE/SN1_BANKS_PER_NODE)
-#define SN1_NODE_SHIFT			33
-#define SN1_NODE_MASK			0x7fUL
-#define SN1_NODE_OFFSET_MASK		(SN1_NODE_SIZE-1)
-#define SN1_NODE_NUMBER(addr)		(((unsigned long)(addr) >> SN1_NODE_SHIFT) & SN1_NODE_MASK)
-#define SN1_NODE_CLUMP_NUMBER(addr)	(((unsigned long)(addr) >>30) & 7)
-#define SN1_NODE_OFFSET(addr)		(((unsigned long)(addr)) & SN1_NODE_OFFSET_MASK)
-#define SN1_KADDR(nasid, offset)	(((unsigned long)(nasid)<<SN1_NODE_SHIFT) | (offset) | PAGE_OFFSET)
-
-
-#define PLAT_MAX_NODE_NUMBER		128			/* Maximum node number +1 */
-#define PLAT_MAX_COMPACT_NODES		128			/* Maximum number of nodes in SSI */
-
-#define PLAT_MAX_PHYS_MEMORY		(1UL << 40)
-
-
-
-/*
- * On the SN platforms, a clump is the same as a memory bank.
- */
-#define PLAT_CLUMPS_PER_NODE		SN1_BANKS_PER_NODE
-#define PLAT_CLUMP_OFFSET(addr)		((unsigned long)(addr) & 0x3fffffffUL)
-#define PLAT_CLUMPSIZE                  (SN1_NODE_SIZE/PLAT_CLUMPS_PER_NODE)
-#define PLAT_MAXCLUMPS			(PLAT_CLUMPS_PER_NODE*PLAT_MAX_COMPACT_NODES)
-
-
-
-
-/*
- * PLAT_VALID_MEM_KADDR returns a boolean to indicate if a kaddr is potentially a
- * valid cacheable identity mapped RAM memory address.
- * Note that the RAM may or may not actually be present!!
- */
-#define SN1_VALID_KERN_ADDR_MASK	0xffffff0000000000UL
-#define SN1_VALID_KERN_ADDR_VALUE	0xe000000000000000UL
-#define PLAT_VALID_MEM_KADDR(kaddr)	(((unsigned long)(kaddr) & SN1_VALID_KERN_ADDR_MASK) == SN1_VALID_KERN_ADDR_VALUE)
-
-
-
-/*
- * Memory is conceptually divided into chunks. A chunk is either
- * completely present, or else the kernel assumes it is completely
- * absent. Each node consists of a number of possibly discontiguous chunks.
- */
-#define SN1_CHUNKSHIFT			26			/* 64 MB */
-#define PLAT_CHUNKSIZE			(1UL << SN1_CHUNKSHIFT)
-#define PLAT_CHUNKNUM(addr)		(((addr) & (PLAT_MAX_PHYS_MEMORY-1)) >> SN1_CHUNKSHIFT)
-
-
-/*
- * Given a kaddr, find the nid (compact nodeid)
- */
-#ifdef CONFIG_IA64_SGI_SN_DEBUG
-#define DISCONBUG(kaddr)		panic("DISCONTIG BUG: line %d, %s. kaddr 0x%lx",	 	\
-						__LINE__, __FILE__, (long)(kaddr))
-
-#define KVADDR_TO_NID(kaddr)		({long _ktn=(long)(kaddr);					\
-						kern_addr_valid(_ktn) ? 				\
-						local_node_data->physical_node_map[SN1_NODE_NUMBER(_ktn)] :\
-						(DISCONBUG(_ktn), 0UL);})
-#else
-#define KVADDR_TO_NID(kaddr)		(local_node_data->physical_node_map[SN1_NODE_NUMBER(kaddr)])
-#endif
-
-
-
-/*
- * Given a kaddr, find the index into the clump_mem_map_base array of the page struct entry
- * for the first page of the clump.
- */
-#define PLAT_CLUMP_MEM_MAP_INDEX(kaddr)		({long _kmmi=(long)(kaddr);				\
-							KVADDR_TO_NID(_kmmi) * PLAT_CLUMPS_PER_NODE +	\
-							SN1_NODE_CLUMP_NUMBER(_kmmi);})
-
-
-/*
- * Calculate a "goal" value to be passed to __alloc_bootmem_node for allocating structures on
- * nodes so that they dont alias to the same line in the cache as the previous allocated structure.
- * This macro takes an address of the end of previous allocation, rounds it to a page boundary & 
- * changes the node number.
- */
-#define PLAT_BOOTMEM_ALLOC_GOAL(cnode,kaddr)	__pa(SN1_KADDR(PLAT_PXM_TO_PHYS_NODE_NUMBER(nid_to_pxm_map[cnode]),		\
-						  (SN1_NODE_OFFSET(kaddr) + PAGE_SIZE - 1) >> PAGE_SHIFT << PAGE_SHIFT))
-
-
-
-
-/*
- * Convert a proximity domain number (from the ACPI tables) into a physical node number.
- */
-
-#define PLAT_PXM_TO_PHYS_NODE_NUMBER(pxm)	(pxm)
-
-#endif /* _ASM_IA64_SN_MMZONE_SN1_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/slotnum.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/slotnum.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/slotnum.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/slotnum.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,87 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_SLOTNUM_H
-#define _ASM_IA64_SN_SN1_SLOTNUM_H
-
-#define SLOTNUM_MAXLENGTH	16
-
-/*
- * This file attempts to define a slot number space across all slots.
- *
- *	Node slots
- *	Router slots
- *	Crosstalk slots
- *
- *	Other slots are children of their parent crosstalk slot:
- *		PCI slots
- *		VME slots
- *
- *	The PCI class has been added since the XBridge ASIC on SN-MIPS
- *	has built-in PCI bridges (2). On IBricks, widget E & F serve
- *	PCI busses, and on PBricks all widgets serve as PCI busses
- *	with the use of the super-bridge mode of the XBridge ASIC.
- */
-
-#define SLOTNUM_NODE_CLASS	0x00	/* Node   */
-#define SLOTNUM_ROUTER_CLASS	0x10	/* Router */
-#define SLOTNUM_XTALK_CLASS	0x20	/* Xtalk  */
-#define SLOTNUM_MIDPLANE_CLASS	0x30	/* Midplane */
-#define SLOTNUM_XBOW_CLASS	0x40	/* Xbow  */
-#define SLOTNUM_KNODE_CLASS	0x50	/* Kego node */
-#define SLOTNUM_PCI_CLASS	0x60	/* PCI widgets on XBridge */
-#define SLOTNUM_INVALID_CLASS	0xf0	/* Invalid */
-
-#define SLOTNUM_CLASS_MASK	0xf0
-#define SLOTNUM_SLOT_MASK	0x0f
-
-#define SLOTNUM_GETCLASS(_sn)	((_sn) & SLOTNUM_CLASS_MASK)
-#define SLOTNUM_GETSLOT(_sn)	((_sn) & SLOTNUM_SLOT_MASK)
-
-/* This determines module to pnode mapping. */
-/* NODESLOTS_PER_MODULE has changed from 4 to 6
- * to support the 12P 4IO configuration. This change
- * helps in minimum  number of changes to code which
- * depend on the number of node boards within a module.
- */
-#define NODESLOTS_PER_MODULE		6
-#define NODESLOTS_PER_MODULE_SHFT	2
-
-#define HIGHEST_I2C_VISIBLE_NODESLOT	4
-#define	RTRSLOTS_PER_MODULE		2
-
-#if __KERNEL__
-#include <asm/sn/xtalk/xtalk.h>
-
-extern slotid_t xbwidget_to_xtslot(int crossbow, int widget);
-extern slotid_t hub_slotbits_to_slot(slotid_t slotbits);
-extern slotid_t hub_slot_to_crossbow(slotid_t hub_slot);
-extern slotid_t router_slotbits_to_slot(slotid_t slotbits);
-extern slotid_t get_node_slotid(nasid_t nasid);
-extern slotid_t get_my_slotid(void);
-extern slotid_t get_node_crossbow(nasid_t);
-extern xwidgetnum_t hub_slot_to_widget(slotid_t);
-extern void get_slotname(slotid_t, char *);
-extern void get_my_slotname(char *);
-extern slotid_t get_widget_slotnum(int xbow, int widget);
-extern void get_widget_slotname(int, int, char *);
-extern void router_slotbits_to_slotname(int, char *);
-extern slotid_t meta_router_slotbits_to_slot(slotid_t) ;
-extern slotid_t hub_slot_get(void);
-
-extern int node_can_talk_to_elsc(void);
-
-extern int  slot_to_widget(int) ;
-#define MAX_IO_SLOT_NUM		12
-#define MAX_NODE_SLOT_NUM	4
-#define MAX_ROUTER_SLOTNUM	2
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_IA64_SN_SN1_SLOTNUM_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/sn_private.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/sn_private.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/sn_private.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/sn_private.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,292 +0,0 @@
-/* $Id: sn_private.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_SN_PRIVATE_H
-#define _ASM_IA64_SN_SN1_SN_PRIVATE_H
-
-#include <asm/sn/nodepda.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-
-extern nasid_t master_nasid;
-
-/* promif.c */
-#ifdef	LATER
-extern cpuid_t cpu_node_probe(cpumask_t *cpumask, int *numnodes);
-#endif
-extern void he_arcs_set_vectors(void);
-extern void mem_init(void);
-#ifdef	LATER
-extern int cpu_enabled(cpuid_t);
-#endif
-extern void cpu_unenable(cpuid_t);
-extern nasid_t get_lowest_nasid(void);
-extern __psunsigned_t get_master_bridge_base(void);
-extern void set_master_bridge_base(void);
-extern int check_nasid_equiv(nasid_t, nasid_t);
-extern nasid_t get_console_nasid(void);
-extern char get_console_pcislot(void);
-#ifdef	LATER
-extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
-#endif
-
-extern int is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid);
-
-/* memsupport.c */
-extern void poison_state_alter_range(__psunsigned_t start, int len, int poison);
-extern int memory_present(paddr_t);
-extern int memory_read_accessible(paddr_t);
-extern int memory_write_accessible(paddr_t);
-extern void memory_set_access(paddr_t, int, int);
-extern void show_dir_state(paddr_t, void (*)(char *, ...));
-extern void check_dir_state(nasid_t, int, void (*)(char *, ...));
-extern void set_dir_owner(paddr_t, int);
-extern void set_dir_state(paddr_t, int);
-extern void set_dir_state_POISONED(paddr_t);
-extern void set_dir_state_UNOWNED(paddr_t);
-extern int is_POISONED_dir_state(paddr_t);
-extern int is_UNOWNED_dir_state(paddr_t);
-extern void get_dir_ent(paddr_t paddr, int *state,
-			uint64_t *vec_ptr, hubreg_t *elo);
-
-/* intr.c */
-extern int intr_reserve_level(cpuid_t cpu, int level, int err, devfs_handle_t owner_dev, char *name);
-extern void intr_unreserve_level(cpuid_t cpu, int level);
-extern int intr_connect_level(cpuid_t cpu, int bit, ilvl_t mask_no, 
-			intr_func_t intr_prefunc);
-extern int intr_disconnect_level(cpuid_t cpu, int bit);
-extern cpuid_t intr_heuristic(devfs_handle_t dev, device_desc_t dev_desc,
-			      int req_bit,int intr_resflags,devfs_handle_t owner_dev,
-			      char *intr_name,int *resp_bit);
-extern void intr_block_bit(cpuid_t cpu, int bit);
-extern void intr_unblock_bit(cpuid_t cpu, int bit);
-extern void setrtvector(intr_func_t);
-extern void install_cpuintr(cpuid_t cpu);
-extern void install_dbgintr(cpuid_t cpu);
-extern void install_tlbintr(cpuid_t cpu);
-extern void hub_migrintr_init(cnodeid_t /*cnode*/);
-extern int cause_intr_connect(int level, intr_func_t handler, uint intr_spl_mask);
-extern int cause_intr_disconnect(int level);
-extern void intr_reserve_hardwired(cnodeid_t);
-extern void intr_clear_all(nasid_t);
-extern void intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...));
-
-/* error_dump.c */
-extern char *hub_rrb_err_type[];
-extern char *hub_wrb_err_type[];
-
-void nmi_dump(void);
-void install_cpu_nmi_handler(int slice);
-
-/* klclock.c */
-extern void hub_rtc_init(cnodeid_t);
-
-/* bte.c */
-void bte_lateinit(void);
-void bte_wait_for_xfer_completion(void *);
-
-/* klgraph.c */
-void klhwg_add_all_nodes(devfs_handle_t);
-void klhwg_add_all_modules(devfs_handle_t);
-
-/* klidbg.c */
-void install_klidbg_functions(void);
-
-/* klnuma.c */
-extern void replicate_kernel_text(int numnodes);
-extern __psunsigned_t get_freemem_start(cnodeid_t cnode);
-extern void setup_replication_mask(int maxnodes);
-
-/* init.c */
-extern cnodeid_t get_compact_nodeid(void);	/* get compact node id */
-extern void init_platform_nodepda(nodepda_t *npda, cnodeid_t node);
-extern void init_platform_pda(cpuid_t cpu);
-extern void per_cpu_init(void);
-#ifdef	LATER
-extern cpumask_t boot_cpumask;
-#endif
-extern int is_fine_dirmode(void);
-extern void update_node_information(cnodeid_t);
- 
-#ifdef	LATER
-/* clksupport.c */
-extern void early_counter_intr(eframe_t *);
-#endif
-
-/* hubio.c */
-extern void hubio_init(void);
-extern void hub_merge_clean(nasid_t nasid);
-extern void hub_set_piomode(nasid_t nasid, int conveyor);
-
-/* huberror.c */
-extern void hub_error_init(cnodeid_t);
-extern void dump_error_spool(cpuid_t cpu, void (*pf)(char *, ...));
-extern void hubni_error_handler(char *, int);
-extern int check_ni_errors(void);
-
-/* Used for debugger to signal upper software a breakpoint has taken place */
-
-extern void		*debugger_update;
-extern __psunsigned_t	debugger_stopped;
-
-/* 
- * IP27 piomap, created by hub_pio_alloc.
- * xtalk_info MUST BE FIRST, since this structure is cast to a
- * xtalk_piomap_s by generic xtalk routines.
- */
-struct hub_piomap_s {
-	struct xtalk_piomap_s	hpio_xtalk_info;/* standard crosstalk pio info */
-	devfs_handle_t		hpio_hub;	/* which hub's mapping registers are set up */
-	short			hpio_holdcnt;	/* count of current users of bigwin mapping */
-	char			hpio_bigwin_num;/* if big window map, which one */
-	int 			hpio_flags;	/* defined below */
-};
-/* hub_piomap flags */
-#define HUB_PIOMAP_IS_VALID		0x1
-#define HUB_PIOMAP_IS_BIGWINDOW		0x2
-#define HUB_PIOMAP_IS_FIXED		0x4
-
-#define	hub_piomap_xt_piomap(hp)	(&hp->hpio_xtalk_info)
-#define	hub_piomap_hub_v(hp)	(hp->hpio_hub)
-#define	hub_piomap_winnum(hp)	(hp->hpio_bigwin_num)
-
-#if TBD
- /* Ensure that hpio_xtalk_info is first */
- #assert (&(((struct hub_piomap_s *)0)->hpio_xtalk_info) == 0)
-#endif
-
-
-/* 
- * IP27 dmamap, created by hub_pio_alloc.
- * xtalk_info MUST BE FIRST, since this structure is cast to a
- * xtalk_dmamap_s by generic xtalk routines.
- */
-struct hub_dmamap_s {
-	struct xtalk_dmamap_s	hdma_xtalk_info;/* standard crosstalk dma info */
-	devfs_handle_t		hdma_hub;	/* which hub we go through */
-	int			hdma_flags;	/* defined below */
-};
-/* hub_dmamap flags */
-#define HUB_DMAMAP_IS_VALID		0x1
-#define HUB_DMAMAP_USED			0x2
-#define	HUB_DMAMAP_IS_FIXED		0x4
-
-#if TBD
- /* Ensure that hdma_xtalk_info is first */
- #assert (&(((struct hub_dmamap_s *)0)->hdma_xtalk_info) == 0)
-#endif
-
-/* 
- * IP27 interrupt handle, created by hub_intr_alloc.
- * xtalk_info MUST BE FIRST, since this structure is cast to a
- * xtalk_intr_s by generic xtalk routines.
- */
-struct hub_intr_s {
-	struct xtalk_intr_s	i_xtalk_info;	/* standard crosstalk intr info */
-	ilvl_t			i_swlevel;	/* software level for blocking intr */
-	cpuid_t			i_cpuid;	/* which cpu */
-	int			i_bit;		/* which bit */
-	int			i_flags;
-};
-/* flag values */
-#define HUB_INTR_IS_ALLOCED	0x1	/* for debug: allocated */
-#define HUB_INTR_IS_CONNECTED	0x4	/* for debug: connected to a software driver */
-
-#if TBD
- /* Ensure that i_xtalk_info is first */
- #assert (&(((struct hub_intr_s *)0)->i_xtalk_info) == 0)
-#endif
-
-
-/* IP27 hub-specific information stored under INFO_LBL_HUB_INFO */
-/* TBD: IP27-dependent stuff currently in nodepda.h should be here */
-typedef struct hubinfo_s {
-	nodepda_t			*h_nodepda;	/* pointer to node's private data area */
-	cnodeid_t			h_cnodeid;	/* compact nodeid */
-	nasid_t				h_nasid;	/* nasid */
-
-	/* structures for PIO management */
-	xwidgetnum_t			h_widgetid;	/* my widget # (as viewed from xbow) */
-	struct hub_piomap_s		h_small_window_piomap[HUB_WIDGET_ID_MAX+1];
-	sv_t				h_bwwait;	/* wait for big window to free */
-	spinlock_t			h_bwlock;	/* guard big window piomap's */
-	spinlock_t			h_crblock;      /* gaurd CRB error handling */
-	int				h_num_big_window_fixed;	/* count number of FIXED maps */
-	struct hub_piomap_s		h_big_window_piomap[HUB_NUM_BIG_WINDOW];
-	hub_intr_t			hub_ii_errintr;
-} *hubinfo_t;
-
-#define hubinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \
-	(vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t *)infoptr))
-
-#define hubinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \
-	(vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t)infoptr)
-
-#define	hubinfo_to_hubv(hinfo, hub_v)	(hinfo->h_nodepda->node_vertex)
-
-/*
- * Hub info PIO map access functions.
- */
-#define	hubinfo_bwin_piomap_get(hinfo, win) 	\
-			(&hinfo->h_big_window_piomap[win])
-#define	hubinfo_swin_piomap_get(hinfo, win)	\
-			(&hinfo->h_small_window_piomap[win])
-	
-/* IP27 cpu-specific information stored under INFO_LBL_CPU_INFO */
-/* TBD: IP27-dependent stuff currently in pda.h should be here */
-typedef struct cpuinfo_s {
-#ifdef	LATER
-	pda_t		*ci_cpupda;	/* pointer to CPU's private data area */
-#endif
-	cpuid_t		ci_cpuid;	/* CPU ID */
-} *cpuinfo_t;
-
-#define cpuinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \
-	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t *)infoptr))
-
-#define cpuinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \
-	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t)infoptr)
-
-/* Special initialization function for xswitch vertices created during startup. */
-extern void xswitch_vertex_init(devfs_handle_t xswitch);
-
-extern xtalk_provider_t hub_provider;
-
-/* du.c */
-int ducons_write(char *buf, int len);
-
-/* memerror.c */
-
-extern void install_eccintr(cpuid_t cpu);
-extern void memerror_get_stats(cnodeid_t cnode,
-			       int *bank_stats, int *bank_stats_max);
-extern void probe_md_errors(nasid_t);
-/* sysctlr.c */
-extern void sysctlr_init(void);
-extern void sysctlr_power_off(int sdonly);
-extern void sysctlr_keepalive(void);
-
-#define valid_cpuid(_x)		(((_x) >= 0) && ((_x) < maxcpus))
-
-/* Useful definitions to get the memory dimm given a physical
- * address.
- */
-#define paddr_dimm(_pa)		((_pa & MD_BANK_MASK) >> MD_BANK_SHFT)
-#define paddr_cnode(_pa)	(NASID_TO_COMPACT_NODEID(NASID_GET(_pa)))
-extern void membank_pathname_get(paddr_t,char *);
-
-/* To redirect the output into the error buffer */
-#define errbuf_print(_s)	printf("#%s",_s)
-
-extern void crbx(nasid_t nasid, void (*pf)(char *, ...));
-void bootstrap(void);
-
-/* sndrv.c */
-extern int sndrv_attach(devfs_handle_t vertex);
-
-#endif /* _ASM_IA64_SN_SN1_SN_PRIVATE_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn1/synergy.h linux-2.4.22-pre3/include/asm-ia64/sn/sn1/synergy.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn1/synergy.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn1/synergy.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,184 +0,0 @@
-#ifndef _ASM_IA64_SN_SN1_SYNERGY_H
-#define _ASM_IA64_SN_SN1_SYNERGY_H
-
-#include <asm/io.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/intr_public.h>
-
-
-/*
- * Definitions for the synergy asic driver
- * 
- * These are for SGI platforms only.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-
-#define SYNERGY_L4_BYTES		(64UL*1024*1024)
-#define SYNERGY_L4_WAYS			8
-#define SYNERGY_L4_BYTES_PER_WAY	(SYNERGY_L4_BYTES/SYNERGY_L4_WAYS)
-#define SYNERGY_BLOCK_SIZE		512UL
-
-
-#define SSPEC_BASE	(0xe0000000000UL)
-#define LB_REG_BASE	(SSPEC_BASE + 0x0)
-
-#define VEC_MASK3A_ADDR	(0x2a0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK3B_ADDR	(0x2a8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK3A	(0x2a0)
-#define VEC_MASK3B	(0x2a8)
-
-#define VEC_MASK2A_ADDR	(0x2b0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK2B_ADDR	(0x2b8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK2A	(0x2b0)
-#define VEC_MASK2B	(0x2b8)
-
-#define VEC_MASK1A_ADDR	(0x2c0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK1B_ADDR	(0x2c8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK1A	(0x2c0)
-#define VEC_MASK1B	(0x2c8)
-
-#define VEC_MASK0A_ADDR	(0x2d0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK0B_ADDR	(0x2d8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK0A	(0x2d0)
-#define VEC_MASK0B	(0x2d8)
-
-#define GBL_PERF_A_ADDR (0x330 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define GBL_PERF_B_ADDR (0x338 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-
-#define WRITE_LOCAL_SYNERGY_REG(addr, value)	__synergy_out(addr, value)
-
-#define HSPEC_SYNERGY0_0        0x04000000    /* Synergy0 Registers     */
-#define HSPEC_SYNERGY1_0        0x05000000    /* Synergy1 Registers     */
-#define HS_SYNERGY_STRIDE       (HSPEC_SYNERGY1_0 - HSPEC_SYNERGY0_0)
-#define REMOTE_HSPEC(_n, _x)    (HUBREG_CAST (RREG_BASE(_n) + (_x)))
-
-#define RREG_BASE(_n)           (NODE_LREG_BASE(_n))
-#define NODE_LREG_BASE(_n)      (NODE_HSPEC_BASE(_n) + 0x30000000)
-#define NODE_HSPEC_BASE(_n)     (HSPEC_BASE + NODE_OFFSET(_n))
-#ifndef HSPEC_BASE
-#define HSPEC_BASE              (SYN_UNCACHED_SPACE | HSPEC_BASE_SYN)
-#endif
-#define SYN_UNCACHED_SPACE      0xc000000000000000
-#define HSPEC_BASE_SYN          0x00000b0000000000
-#define NODE_OFFSET(_n)         (UINT64_CAST (_n) << NODE_SIZE_BITS)
-#define NODE_SIZE_BITS		33
-
-#define SYN_TAG_DISABLE_WAY	(SSPEC_BASE+0xae0)
-
-
-#define RSYN_REG_OFFSET(fsb, reg) (((fsb) ? HSPEC_SYNERGY1_0 : HSPEC_SYNERGY0_0) | (reg))
-
-#define REMOTE_SYNERGY_LOAD(nasid, fsb, reg)  __remote_synergy_in(nasid, fsb, reg)
-#define REMOTE_SYNERGY_STORE(nasid, fsb, reg, val) __remote_synergy_out(nasid, fsb, reg, val)
-
-static inline uint64_t
-__remote_synergy_in(int nasid, int fsb, uint64_t reg) {
-	volatile uint64_t *addr;
-
-	addr = (uint64_t *)(RREG_BASE(nasid) + RSYN_REG_OFFSET(fsb, reg));
-	return (*addr);
-}
-
-static inline void
-__remote_synergy_out(int nasid, int fsb, uint64_t reg, uint64_t value) {
-	volatile uint64_t *addr;
-
-        addr = (uint64_t *)(RREG_BASE(nasid) + RSYN_REG_OFFSET(fsb, (reg<<2)));
-        *(addr+0) = value >> 48;
-        *(addr+1) = value >> 32;
-        *(addr+2) = value >> 16;
-        *(addr+3) = value;
-        __ia64_mf_a();
-}
-
-/* XX this doesn't make a lot of sense. Which fsb?  */
-static inline void
-__synergy_out(unsigned long addr, unsigned long value)
-{
-	volatile unsigned long *adr = (unsigned long *)
-			(addr | __IA64_UNCACHED_OFFSET);
-
-	*adr = value;
-	__ia64_mf_a();
-}
-
-#define READ_LOCAL_SYNERGY_REG(addr)	__synergy_in(addr)
-
-/* XX this doesn't make a lot of sense. Which fsb? */
-static inline unsigned long
-__synergy_in(unsigned long addr)
-{
-	unsigned long ret, *adr = (unsigned long *)
-			(addr | __IA64_UNCACHED_OFFSET);
-
-	ret = *adr;
-	__ia64_mf_a();
-	return ret;
-}
-
-struct sn1_intr_action {
-	void (*handler)(int, void *, struct pt_regs *);
-	void *intr_arg;
-	unsigned long flags;
-	struct sn1_intr_action * next;
-};
-
-typedef struct synergy_da_s {
-	hub_intmasks_t	s_intmasks;
-}synergy_da_t;
-
-struct sn1_cnode_action_list {
-	spinlock_t action_list_lock;
-	struct sn1_intr_action *action_list;
-};
-
-/*
- * ioctl cmds for node/hub/synergy/[01]/mon for synergy
- * perf monitoring are defined in sndrv.h
- */
-
-/* multiplex the counters every 10 timer interrupts */ 
-#define SYNERGY_PERF_FREQ_DEFAULT 10
-
-/* macros for synergy "mon" device ioctl handler */
-#define SYNERGY_PERF_INFO(_s, _f)	(arbitrary_info_t)(((_s) << 16)|(_f))
-#define SYNERGY_PERF_INFO_CNODE(_x)	(cnodeid_t)(((uint64_t)_x) >> 16)
-#define SYNERGY_PERF_INFO_FSB(_x)	(((uint64_t)_x) & 1)
-
-/* synergy perf control registers */
-#define PERF_CNTL0_A            0xab0UL /* control A on FSB0 */
-#define PERF_CNTL0_B            0xab8UL /* control B on FSB0 */
-#define PERF_CNTL1_A            0xac0UL /* control A on FSB1 */
-#define PERF_CNTL1_B            0xac8UL /* control B on FSB1 */
-
-/* synergy perf counters */
-#define PERF_CNTR0_A            0xad0UL /* counter A on FSB0 */
-#define PERF_CNTR0_B            0xad8UL /* counter B on FSB0 */
-#define PERF_CNTR1_A            0xaf0UL /* counter A on FSB1 */
-#define PERF_CNTR1_B            0xaf8UL /* counter B on FSB1 */
-
-/* Synergy perf data. Each nodepda keeps a list of these */
-struct synergy_perf_s {
-        uint64_t        intervals;      /* count of active intervals for this event */
-        uint64_t        total_intervals;/* snapshot of total intervals */
-        uint64_t        modesel;        /* mode and sel bits, both A and B registers */
-        struct synergy_perf_s *next;	/* next in circular linked list */
-        uint64_t        counts[2];      /* [0] is synergy-A counter, [1] synergy-B counter */
-};
-
-typedef struct synergy_perf_s synergy_perf_t;
-
-typedef struct synergy_info_s synergy_info_t;
-
-extern void synergy_perf_init(void);
-extern void synergy_perf_update(int);
-extern struct file_operations synergy_mon_fops;
-
-#endif /* _ASM_IA64_SN_SN1_SYNERGY_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/addrs.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/addrs.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/addrs.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/addrs.h	2003-07-05 18:11:26.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_SN2_ADDRS_H
@@ -57,7 +57,7 @@
 #define LOCAL_MEM_SPACE		0xc000010000000000	/* Local Memory space */
 #define GLOBAL_MMR_SPACE	0xc000000800000000	/* Global MMR space */
 #define GLOBAL_PHYS_MMR_SPACE	0x0000000800000000	/* Global Physical MMR space */
-#define GET_SPACE		0xc000001000000000	/* GET space */
+#define GET_SPACE		0xe000001000000000	/* GET space */
 #define AMO_SPACE		0xc000002000000000	/* AMO space */
 #define CACHEABLE_MEM_SPACE	0xe000003000000000	/* Cacheable memory space */
 #define UNCACHED                0xc000000000000000      /* UnCacheable memory space */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/arch.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/arch.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/arch.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/arch.h	2003-07-05 18:11:26.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SN2_ARCH_H
 #define _ASM_IA64_SN_SN2_ARCH_H
@@ -46,6 +46,7 @@
 
 
 #define NASID_MASK_BYTES	((MAX_NASIDS + 7) / 8)
+#define CNASID_MASK_BYTES	(NASID_MASK_BYTES / 2)
 
 
 /*
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/geo.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/geo.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/geo.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/geo.h	2003-07-05 18:11:26.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef __SYS_SN_SN2_GEO_H__
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/intr.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/intr.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/intr.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/intr.h	2003-07-05 18:11:26.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SN2_INTR_H
 #define _ASM_IA64_SN_SN2_INTR_H
@@ -14,13 +14,17 @@
 
 // These two IRQ's are used by partitioning.
 #define SGI_XPC_ACTIVATE		(0x30)
+#define SGI_II_ERROR			(0x31)
+#define SGI_XBOW_ERROR			(0x32)
+#define SGI_PCIBR_ERROR			(0x33)
 #define SGI_XPC_NOTIFY			(0xe7)
 
-#define IA64_SN2_FIRST_DEVICE_VECTOR	(0x31)
+#define IA64_SN2_FIRST_DEVICE_VECTOR	(0x34)
 #define IA64_SN2_LAST_DEVICE_VECTOR	(0xe6)
 
 #define SN2_IRQ_RESERVED        (0x1)
 #define SN2_IRQ_CONNECTED       (0x2)
+#define SN2_IRQ_SHARED		(0x4)
 
 #define SN2_IRQ_PER_HUB         (2048)
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/io.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/io.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/io.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/io.h	2003-07-05 18:11:26.000000000 -0700
@@ -0,0 +1,222 @@
+/* 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#ifndef _ASM_SN_SN2_IO_H
+#define _ASM_SN_SN2_IO_H
+
+extern void * sn_io_addr(unsigned long port); /* Forward definition */
+extern void sn_mmiob(void); /* Forward definition */
+
+#define __sn_mf_a()   __asm__ __volatile__ ("mf.a" ::: "memory")
+
+extern void sn_dma_flush(unsigned long);
+
+/*
+ * The following routines are SN Platform specific, called when
+ * a reference is made to inX/outX set macros.  SN Platform
+ * inX set of macros ensures that Posted DMA writes on the
+ * Bridge is flushed.
+ *
+ * The routines should be self explainatory.
+ */
+
+static inline unsigned int
+__sn_inb (unsigned long port)
+{
+	volatile unsigned char *addr;
+	unsigned char ret = -1;
+
+	if ((addr = sn_io_addr(port))) {
+		ret = *addr;
+		__sn_mf_a();
+		sn_dma_flush((unsigned long)addr);
+	}
+	return ret;
+}
+
+static inline unsigned int
+__sn_inw (unsigned long port)
+{
+	volatile unsigned short *addr;
+	unsigned short ret = -1;
+
+	if ((addr = sn_io_addr(port))) {
+		ret = *addr;
+		__sn_mf_a();
+		sn_dma_flush((unsigned long)addr);
+	}
+	return ret;
+}
+
+static inline unsigned int
+__sn_inl (unsigned long port)
+{
+	volatile unsigned int *addr;
+	unsigned int ret = -1;
+
+	if ((addr = sn_io_addr(port))) {
+		ret = *addr;
+		__sn_mf_a();
+		sn_dma_flush((unsigned long)addr);
+	}
+	return ret;
+}
+
+static inline void
+__sn_outb (unsigned char val, unsigned long port)
+{
+	volatile unsigned char *addr;
+
+	if ((addr = sn_io_addr(port))) {
+		*addr = val;
+		sn_mmiob();
+	}
+}
+
+static inline void
+__sn_outw (unsigned short val, unsigned long port)
+{
+	volatile unsigned short *addr;
+
+	if ((addr = sn_io_addr(port))) {
+		*addr = val;
+		sn_mmiob();
+	}
+}
+
+static inline void
+__sn_outl (unsigned int val, unsigned long port)
+{
+	volatile unsigned int *addr;
+
+	if ((addr = sn_io_addr(port))) {
+		*addr = val;
+		sn_mmiob();
+	}
+}
+
+/*
+ * The following routines are SN Platform specific, called when 
+ * a reference is made to readX/writeX set macros.  SN Platform 
+ * readX set of macros ensures that Posted DMA writes on the 
+ * Bridge is flushed.
+ * 
+ * The routines should be self explainatory.
+ */
+
+static inline unsigned char
+__sn_readb (void *addr)
+{
+	unsigned char val;
+
+	val = *(volatile unsigned char *)addr;
+	__sn_mf_a();
+	sn_dma_flush((unsigned long)addr);
+        return val;
+}
+
+static inline unsigned short
+__sn_readw (void *addr)
+{
+	unsigned short val;
+
+	val = *(volatile unsigned short *)addr;
+	__sn_mf_a();
+	sn_dma_flush((unsigned long)addr);
+        return val;
+}
+
+static inline unsigned int
+__sn_readl (void *addr)
+{
+	unsigned int val;
+
+	val = *(volatile unsigned int *) addr;
+	__sn_mf_a();
+	sn_dma_flush((unsigned long)addr);
+        return val;
+}
+
+static inline unsigned long
+__sn_readq (void *addr)
+{
+	unsigned long val;
+
+	val = *(volatile unsigned long *) addr;
+	__sn_mf_a();
+	sn_dma_flush((unsigned long)addr);
+        return val;
+}
+
+/*
+ * For generic and SN2 kernels, we have a set of fast access
+ * PIO macros.	These macros are provided on SN Platform
+ * because the normal inX and readX macros perform an
+ * additional task of flushing Post DMA request on the Bridge.
+ *
+ * These routines should be self explainatory.
+ */
+
+static inline unsigned int
+sn_inb_fast (unsigned long port)
+{
+	volatile unsigned char *addr = (unsigned char *)port;
+	unsigned char ret;
+
+	ret = *addr;
+	__sn_mf_a();
+	return ret;
+}
+
+static inline unsigned int
+sn_inw_fast (unsigned long port)
+{
+	volatile unsigned short *addr = (unsigned short *)port;
+	unsigned short ret;
+
+	ret = *addr;
+	__sn_mf_a();
+	return ret;
+}
+
+static inline unsigned int
+sn_inl_fast (unsigned long port)
+{
+	volatile unsigned int *addr = (unsigned int *)port;
+	unsigned int ret;
+
+	ret = *addr;
+	__sn_mf_a();
+	return ret;
+}
+
+static inline unsigned char
+sn_readb_fast (void *addr)
+{
+	return *(volatile unsigned char *)addr;
+}
+
+static inline unsigned short
+sn_readw_fast (void *addr)
+{
+	return *(volatile unsigned short *)addr;
+}
+
+static inline unsigned int
+sn_readl_fast (void *addr)
+{
+	return *(volatile unsigned int *) addr;
+}
+
+static inline unsigned long
+sn_readq_fast (void *addr)
+{
+	return *(volatile unsigned long *) addr;
+}
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/mmzone_sn2.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/mmzone_sn2.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/mmzone_sn2.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/mmzone_sn2.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,165 +0,0 @@
-#ifndef _ASM_IA64_SN_MMZONE_SN2_H
-#define _ASM_IA64_SN_MMZONE_SN2_H
-
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/config.h>
-
-
-/*
- * SGI SN2 Arch defined values
- *
- * 	An SN2 physical address is broken down as follows:
- *
- *             +-----------------------------------------+
- *             |         |      |    |   node offset     |
- *             | unused  | node | AS |-------------------|
- *             |         |      |    | cn | clump offset |
- *             +-----------------------------------------+
- *              6       4 4    3 3  3 3  3 3            0
- *              3       9 8    8 7  6 5  4 3            0
- *
- *		bits 63-49	Unused - must be zero
- *		bits 48-38	Node number. Note that some configurations do NOT
- *				have a node zero.
- *		bits 37-36	Address space ID. Cached memory has a value of 3 (!!!).
- *				Chipset & IO addresses have other values.
- *				  (Yikes!! The hardware folks hate us...)
- *		bits 35-0	Node offset.
- *
- *	The node offset can be further broken down as:
- *		bits 35-34	Clump (bank) number.
- *		bits 33-0	Clump (bank) offset.
- *
- *	A node consists of up to 4 clumps (banks) of memory. A clump may be empty, or may be
- *	populated with a single contiguous block of memory starting at clump
- *	offset 0. The size of the block is (2**n) * 64MB, where 0<n<9.
- *
- *	Important notes:
- *		- IO space addresses are embedded with the range of valid memory addresses.
- *		- All cached memory addresses have bits 36 & 37 set to 1's.
- *		- There is no physical address 0.
- *
- * NOTE: This file exports symbols prefixed with "PLAT_". Symbols prefixed with
- *	 "SN_" are intended for internal use only and should not be used in
- *	 any platform independent code. 
- *
- *	 This file is also responsible for exporting the following definitions:
- *		cnodeid_t	Define a compact node id. 
- */
-
-typedef signed short cnodeid_t;
-
-#define SN2_BANKS_PER_NODE		4
-#define SN2_NODE_SIZE			(64UL*1024*1024*1024)	/* 64GB per node */
-#define SN2_BANK_SIZE			(SN2_NODE_SIZE/SN2_BANKS_PER_NODE)
-#define SN2_NODE_SHIFT			38
-#define SN2_NODE_MASK			0x7ffUL
-#define SN2_NODE_OFFSET_MASK		(SN2_NODE_SIZE-1)
-#define SN2_NODE_NUMBER(addr)		(((unsigned long)(addr) >> SN2_NODE_SHIFT) & SN2_NODE_MASK)
-#define SN2_NODE_CLUMP_NUMBER(kaddr)	(((unsigned long)(kaddr) >>34) & 3)
-#define SN2_NODE_OFFSET(addr)		(((unsigned long)(addr)) & SN2_NODE_OFFSET_MASK)
-#define SN2_KADDR(nasid, offset)	(((unsigned long)(nasid)<<SN2_NODE_SHIFT) | (offset) | SN2_PAGE_OFFSET)
-#define SN2_PAGE_OFFSET			0xe000003000000000UL      /* Cacheable memory space */
-
-
-#define PLAT_MAX_NODE_NUMBER		2048			/* Maximum node number + 1 */
-#define PLAT_MAX_COMPACT_NODES		128			/* Maximum number of nodes in SSI system */
-
-#define PLAT_MAX_PHYS_MEMORY		(1UL << 49)
-
-
-
-/*
- * On the SN platforms, a clump is the same as a memory bank.
- */
-#define PLAT_CLUMPS_PER_NODE		SN2_BANKS_PER_NODE
-#define PLAT_CLUMP_OFFSET(addr)		((unsigned long)(addr) & 0x3ffffffffUL)
-#define PLAT_CLUMPSIZE			(SN2_NODE_SIZE/PLAT_CLUMPS_PER_NODE)
-#define PLAT_MAXCLUMPS			(PLAT_CLUMPS_PER_NODE * PLAT_MAX_COMPACT_NODES)
-
-
-
-/*
- * PLAT_VALID_MEM_KADDR returns a boolean to indicate if a kaddr is potentially a
- * valid cacheable identity mapped RAM memory address.
- * Note that the RAM may or may not actually be present!!
- */
-#define SN2_VALID_KERN_ADDR_MASK	0xffff003000000000UL
-#define SN2_VALID_KERN_ADDR_VALUE	0xe000003000000000UL
-#define PLAT_VALID_MEM_KADDR(kaddr)	(((unsigned long)(kaddr) & SN2_VALID_KERN_ADDR_MASK) == SN2_VALID_KERN_ADDR_VALUE)
-
-
-
-/*
- * Memory is conceptually divided into chunks. A chunk is either
- * completely present, or else the kernel assumes it is completely
- * absent. Each node consists of a number of possibly contiguous chunks.
- */
-#define SN2_CHUNKSHIFT			25			/* 32 MB */
-#define PLAT_CHUNKSIZE			(1UL << SN2_CHUNKSHIFT)
-#define PLAT_CHUNKNUM(addr)		({unsigned long _p=(unsigned long)(addr);		\
-						(((_p&SN2_NODE_MASK)>>2) | 			\
-						(_p&SN2_NODE_OFFSET_MASK)) >>SN2_CHUNKSHIFT;})
-
-/*
- * Given a kaddr, find the nid (compact nodeid)
- */
-#ifdef CONFIG_IA64_SGI_SN_DEBUG
-#define DISCONBUG(kaddr)		panic("DISCONTIG BUG: line %d, %s. kaddr 0x%lx",	 	\
-						__LINE__, __FILE__, (long)(kaddr))
-
-#define KVADDR_TO_NID(kaddr)		({long _ktn=(long)(kaddr);					\
-						kern_addr_valid(_ktn) ? 				\
-						local_node_data->physical_node_map[SN2_NODE_NUMBER(_ktn)] :	\
-						(DISCONBUG(_ktn), 0UL);})
-#else
-#define KVADDR_TO_NID(kaddr)		(local_node_data->physical_node_map[SN2_NODE_NUMBER(kaddr)])
-#endif
-
-
-
-/*
- * Given a kaddr, find the index into the clump_mem_map_base array of the page struct entry 
- * for the first page of the clump.
- */
-#define PLAT_CLUMP_MEM_MAP_INDEX(kaddr)		({long _kmmi=(long)(kaddr);				\
-							KVADDR_TO_NID(_kmmi) * PLAT_CLUMPS_PER_NODE +	\
-							SN2_NODE_CLUMP_NUMBER(_kmmi);})
-
-
-
-/*
- * Calculate a "goal" value to be passed to __alloc_bootmem_node for allocating structures on
- * nodes so that they dont alias to the same line in the cache as the previous allocated structure.
- * This macro takes an address of the end of previous allocation, rounds it to a page boundary & 
- * changes the node number.
- */
-#define PLAT_BOOTMEM_ALLOC_GOAL(cnode,kaddr)	__pa(SN2_KADDR(PLAT_PXM_TO_PHYS_NODE_NUMBER(nid_to_pxm_map[cnode]),	       \
-						 (SN2_NODE_OFFSET(kaddr) + PAGE_SIZE - 1) >> PAGE_SHIFT << PAGE_SHIFT))
-
-
-
-
-/*
- * Convert a proximity domain number (from the ACPI tables) into a physical node number.
- *	Note: on SN2, the promity domain number is the same as bits [8:1] of the NASID. The following
- *	algorithm relies on:
- *		- bit 0 of the NASID for cpu nodes is always 0
- *		- bits [10:9] of all NASIDs in a partition are always the same
- *		- hard_smp_processor_id return the SAPIC of the current cpu &
- *			bits 0..11 contain the NASID.
- *
- *	All of this complexity is because MS architectually limited proximity domain numbers to
- *	8 bits. 
- */
-
-#define PLAT_PXM_TO_PHYS_NODE_NUMBER(pxm)	(((pxm)<<1) | (hard_smp_processor_id() & 0x300))
-
-#endif /* _ASM_IA64_SN_MMZONE_SN2_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/shub.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/shub.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/shub.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/shub.h	2003-07-05 18:11:26.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/shub_md.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/shub_md.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/shub_md.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/shub_md.h	2003-07-05 18:11:26.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001, 2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001, 2002-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -133,7 +133,7 @@
 #define MD_DIMM_SIZE_MBYTES(_size, _2bk) (				 \
 	 	( (_size) == 7 ? 0 : ( 0x40L << (_size) ) << (_2bk)))  	 \
 
-/* The top 1/32 of each bank is directory memory, and not accessable
+/* The top 1/32 of each bank is directory memory, and not accessible
  * via normal reads and writes */
 #define MD_DIMM_USER_SIZE(_size)	((_size) * 31 / 32)
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/shub_mmr.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/shub_mmr.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/shub_mmr.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/shub_mmr.h	2003-07-05 18:11:32.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -2720,7 +2720,7 @@
 #define SH_NI0_LLP_ERR_RETRY_COUNT_MASK          0x0000000000ff0000
 
 /*   SH_NI0_LLP_ERR_RETRY_TIMEOUT                                       */
-/*   Description:  Indicates a retry timeout has occured                */
+/*   Description:  Indicates a retry timeout has occurred               */
 #define SH_NI0_LLP_ERR_RETRY_TIMEOUT_SHFT        24
 #define SH_NI0_LLP_ERR_RETRY_TIMEOUT_MASK        0x0000000001000000
 
@@ -3017,7 +3017,7 @@
 #define SH_NI1_LLP_ERR_RETRY_COUNT_MASK          0x0000000000ff0000
 
 /*   SH_NI1_LLP_ERR_RETRY_TIMEOUT                                       */
-/*   Description:  Indicates a retry timeout has occured                */
+/*   Description:  Indicates a retry timeout has occurred               */
 #define SH_NI1_LLP_ERR_RETRY_TIMEOUT_SHFT        24
 #define SH_NI1_LLP_ERR_RETRY_TIMEOUT_MASK        0x0000000001000000
 
@@ -25746,14 +25746,14 @@
 /*                           Real-time Clock                            */
 /* ==================================================================== */
 
-#define SH_RTC                                   0x00000001101c0000
-#define SH_RTC_MASK                              0x007fffffffffffff
+#define SH_RTC                                   0x00000001101c0000UL
+#define SH_RTC_MASK                              0x007fffffffffffffUL
 #define SH_RTC_INIT                              0x0000000000000000
 
 /*   SH_RTC_REAL_TIME_CLOCK                                             */
 /*   Description:  Real-time Clock                                      */
 #define SH_RTC_REAL_TIME_CLOCK_SHFT              0
-#define SH_RTC_REAL_TIME_CLOCK_MASK              0x007fffffffffffff
+#define SH_RTC_REAL_TIME_CLOCK_MASK              0x007fffffffffffffUL
 
 /* ==================================================================== */
 /*                        Register "SH_SCRATCH0"                        */
@@ -26034,7 +26034,7 @@
 #define SH_PIO_WRITE_STATUS_0_INIT               0x8000000000000000
 
 /*   SH_PIO_WRITE_STATUS_0_MULTI_WRITE_ERROR                            */
-/*   Description:  More than one PIO write error occured                */
+/*   Description:  More than one PIO write error occurred               */
 #define SH_PIO_WRITE_STATUS_0_MULTI_WRITE_ERROR_SHFT 0
 #define SH_PIO_WRITE_STATUS_0_MULTI_WRITE_ERROR_MASK 0x0000000000000001
 
@@ -26073,7 +26073,7 @@
 #define SH_PIO_WRITE_STATUS_1_INIT               0x8000000000000000
 
 /*   SH_PIO_WRITE_STATUS_1_MULTI_WRITE_ERROR                            */
-/*   Description:  More than one PIO write error occured                */
+/*   Description:  More than one PIO write error occurred               */
 #define SH_PIO_WRITE_STATUS_1_MULTI_WRITE_ERROR_SHFT 0
 #define SH_PIO_WRITE_STATUS_1_MULTI_WRITE_ERROR_MASK 0x0000000000000001
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/shub_mmr_t.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/shub_mmr_t.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/shub_mmr_t.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/shub_mmr_t.h	2003-07-05 18:11:32.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/shubio.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/shubio.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/shubio.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/shubio.h	2003-07-05 18:11:33.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_SN2_SHUBIO_H
@@ -3035,31 +3035,31 @@
 /* Scratch registers (all bits available) */
 #define IIO_SCRATCH_REG0        IIO_ISCR0
 #define IIO_SCRATCH_REG1        IIO_ISCR1
-#define IIO_SCRATCH_MASK        0xffffffffffffffff
+#define IIO_SCRATCH_MASK        0xffffffffffffffffUL
 
-#define IIO_SCRATCH_BIT0_0      0x0000000000000001
-#define IIO_SCRATCH_BIT0_1      0x0000000000000002
-#define IIO_SCRATCH_BIT0_2      0x0000000000000004
-#define IIO_SCRATCH_BIT0_3      0x0000000000000008
-#define IIO_SCRATCH_BIT0_4      0x0000000000000010
-#define IIO_SCRATCH_BIT0_5      0x0000000000000020
-#define IIO_SCRATCH_BIT0_6      0x0000000000000040
-#define IIO_SCRATCH_BIT0_7      0x0000000000000080
-#define IIO_SCRATCH_BIT0_8      0x0000000000000100
-#define IIO_SCRATCH_BIT0_9      0x0000000000000200
-#define IIO_SCRATCH_BIT0_A      0x0000000000000400
+#define IIO_SCRATCH_BIT0_0      0x0000000000000001UL
+#define IIO_SCRATCH_BIT0_1      0x0000000000000002UL
+#define IIO_SCRATCH_BIT0_2      0x0000000000000004UL
+#define IIO_SCRATCH_BIT0_3      0x0000000000000008UL
+#define IIO_SCRATCH_BIT0_4      0x0000000000000010UL
+#define IIO_SCRATCH_BIT0_5      0x0000000000000020UL
+#define IIO_SCRATCH_BIT0_6      0x0000000000000040UL
+#define IIO_SCRATCH_BIT0_7      0x0000000000000080UL
+#define IIO_SCRATCH_BIT0_8      0x0000000000000100UL
+#define IIO_SCRATCH_BIT0_9      0x0000000000000200UL
+#define IIO_SCRATCH_BIT0_A      0x0000000000000400UL
 
-#define IIO_SCRATCH_BIT1_0      0x0000000000000001
-#define IIO_SCRATCH_BIT1_1      0x0000000000000002
+#define IIO_SCRATCH_BIT1_0      0x0000000000000001UL
+#define IIO_SCRATCH_BIT1_1      0x0000000000000002UL
 /* IO Translation Table Entries */
 #define IIO_NUM_ITTES   7               /* ITTEs numbered 0..6 */
                                         /* Hw manuals number them 1..7! */
 /*
  * IIO_IMEM Register fields.
  */
-#define IIO_IMEM_W0ESD  0x1             /* Widget 0 shut down due to error */
-#define IIO_IMEM_B0ESD  (1 << 4)        /* BTE 0 shut down due to error */
-#define IIO_IMEM_B1ESD  (1 << 8)        /* BTE 1 Shut down due to error */
+#define IIO_IMEM_W0ESD  0x1UL             /* Widget 0 shut down due to error */
+#define IIO_IMEM_B0ESD  (1UL << 4)        /* BTE 0 shut down due to error */
+#define IIO_IMEM_B1ESD  (1UL << 8)        /* BTE 1 Shut down due to error */
 
 /*
  * As a permanent workaround for a bug in the PI side of the shub, we've
@@ -3191,23 +3191,23 @@
 /* 
  * IO BTE Length/Status (IIO_IBLS) register bit field definitions
  */
-#define IBLS_BUSY		(0x1 << 20)
+#define IBLS_BUSY		(0x1UL << 20)
 #define IBLS_ERROR_SHFT		16
-#define IBLS_ERROR		(0x1 << IBLS_ERROR_SHFT)
+#define IBLS_ERROR		(0x1UL << IBLS_ERROR_SHFT)
 #define IBLS_LENGTH_MASK	0xffff
 
 /*
  * IO BTE Control/Terminate register (IBCT) register bit field definitions
  */
-#define IBCT_POISON		(0x1 << 8)
-#define IBCT_NOTIFY		(0x1 << 4)
-#define IBCT_ZFIL_MODE		(0x1 << 0)
+#define IBCT_POISON		(0x1UL << 8)
+#define IBCT_NOTIFY		(0x1UL << 4)
+#define IBCT_ZFIL_MODE		(0x1UL << 0)
 
 /*
  * IIO Incoming Error Packet Header (IIO_IIEPH1/IIO_IIEPH2)
  */
-#define IIEPH1_VALID		(1 << 44)
-#define IIEPH1_OVERRUN		(1 << 40)
+#define IIEPH1_VALID		(1UL << 44)
+#define IIEPH1_OVERRUN		(1UL << 40)
 #define IIEPH1_ERR_TYPE_SHFT	32
 #define IIEPH1_ERR_TYPE_MASK	0xf
 #define IIEPH1_SOURCE_SHFT	20
@@ -3217,7 +3217,7 @@
 #define IIEPH1_CMD_SHFT		0
 #define IIEPH1_CMD_MASK		7
 
-#define IIEPH2_TAIL		(1 << 40)
+#define IIEPH2_TAIL		(1UL << 40)
 #define IIEPH2_ADDRESS_SHFT	0
 #define IIEPH2_ADDRESS_MASK	38
 
@@ -3229,21 +3229,21 @@
 /*
  * IO Error Clear register bit field definitions
  */
-#define IECLR_PI1_FWD_INT	(1 << 31)  /* clear PI1_FORWARD_INT in iidsr */
-#define IECLR_PI0_FWD_INT	(1 << 30)  /* clear PI0_FORWARD_INT in iidsr */
-#define IECLR_SPUR_RD_HDR	(1 << 29)  /* clear valid bit in ixss reg */
-#define IECLR_BTE1		(1 << 18)  /* clear bte error 1 */
-#define IECLR_BTE0		(1 << 17)  /* clear bte error 0 */
-#define IECLR_CRAZY		(1 << 16)  /* clear crazy bit in wstat reg */
-#define IECLR_PRB_F		(1 << 15)  /* clear err bit in PRB_F reg */
-#define IECLR_PRB_E		(1 << 14)  /* clear err bit in PRB_E reg */
-#define IECLR_PRB_D		(1 << 13)  /* clear err bit in PRB_D reg */
-#define IECLR_PRB_C		(1 << 12)  /* clear err bit in PRB_C reg */
-#define IECLR_PRB_B		(1 << 11)  /* clear err bit in PRB_B reg */
-#define IECLR_PRB_A		(1 << 10)  /* clear err bit in PRB_A reg */
-#define IECLR_PRB_9		(1 << 9)   /* clear err bit in PRB_9 reg */
-#define IECLR_PRB_8		(1 << 8)   /* clear err bit in PRB_8 reg */
-#define IECLR_PRB_0		(1 << 0)   /* clear err bit in PRB_0 reg */
+#define IECLR_PI1_FWD_INT	(1UL << 31)  /* clear PI1_FORWARD_INT in iidsr */
+#define IECLR_PI0_FWD_INT	(1UL << 30)  /* clear PI0_FORWARD_INT in iidsr */
+#define IECLR_SPUR_RD_HDR	(1UL << 29)  /* clear valid bit in ixss reg */
+#define IECLR_BTE1		(1UL << 18)  /* clear bte error 1 */
+#define IECLR_BTE0		(1UL << 17)  /* clear bte error 0 */
+#define IECLR_CRAZY		(1UL << 16)  /* clear crazy bit in wstat reg */
+#define IECLR_PRB_F		(1UL << 15)  /* clear err bit in PRB_F reg */
+#define IECLR_PRB_E		(1UL << 14)  /* clear err bit in PRB_E reg */
+#define IECLR_PRB_D		(1UL << 13)  /* clear err bit in PRB_D reg */
+#define IECLR_PRB_C		(1UL << 12)  /* clear err bit in PRB_C reg */
+#define IECLR_PRB_B		(1UL << 11)  /* clear err bit in PRB_B reg */
+#define IECLR_PRB_A		(1UL << 10)  /* clear err bit in PRB_A reg */
+#define IECLR_PRB_9		(1UL << 9)   /* clear err bit in PRB_9 reg */
+#define IECLR_PRB_8		(1UL << 8)   /* clear err bit in PRB_8 reg */
+#define IECLR_PRB_0		(1UL << 0)   /* clear err bit in PRB_0 reg */
 
 /*
  * IIO CRB control register Fields: IIO_ICCR 
@@ -3495,7 +3495,7 @@
 typedef struct hub_piomap_s *hub_piomap_t;
 
 extern hub_piomap_t
-hub_piomap_alloc(devfs_handle_t dev,      /* set up mapping for this device */
+hub_piomap_alloc(vertex_hdl_t dev,      /* set up mapping for this device */
                 device_desc_t dev_desc, /* device descriptor */
                 iopaddr_t xtalk_addr,   /* map for this xtalk_addr range */
                 size_t byte_count,
@@ -3513,7 +3513,7 @@
 hub_piomap_done(hub_piomap_t hub_piomap);
 
 extern caddr_t
-hub_piotrans_addr(      devfs_handle_t dev,       /* translate to this device */
+hub_piotrans_addr(      vertex_hdl_t dev,       /* translate to this device */
                         device_desc_t dev_desc, /* device descriptor */
                         iopaddr_t xtalk_addr,   /* Crosstalk address */
                         size_t byte_count,      /* map this many bytes */
@@ -3523,7 +3523,7 @@
 typedef struct hub_dmamap_s *hub_dmamap_t;
 
 extern hub_dmamap_t
-hub_dmamap_alloc(       devfs_handle_t dev,       /* set up mappings for dev */
+hub_dmamap_alloc(       vertex_hdl_t dev,       /* set up mappings for dev */
                         device_desc_t dev_desc, /* device descriptor */
                         size_t byte_count_max,  /* max size of a mapping */
                         unsigned flags);        /* defined in dma.h */
@@ -3545,14 +3545,14 @@
 hub_dmamap_done(        hub_dmamap_t dmamap);   /* done w/ mapping resources */
 
 extern iopaddr_t
-hub_dmatrans_addr(      devfs_handle_t dev,       /* translate for this device */
+hub_dmatrans_addr(      vertex_hdl_t dev,       /* translate for this device */
                         device_desc_t dev_desc, /* device descriptor */
                         paddr_t paddr,          /* system physical address */
                         size_t byte_count,      /* length */
                         unsigned flags);                /* defined in dma.h */
 
 extern alenlist_t
-hub_dmatrans_list(      devfs_handle_t dev,       /* translate for this device */
+hub_dmatrans_list(      vertex_hdl_t dev,       /* translate for this device */
                         device_desc_t dev_desc, /* device descriptor */
                         alenlist_t palenlist,   /* system addr/length list */
                         unsigned flags);                /* defined in dma.h */
@@ -3561,12 +3561,12 @@
 hub_dmamap_drain(       hub_dmamap_t map);
 
 extern void
-hub_dmaaddr_drain(      devfs_handle_t vhdl,
+hub_dmaaddr_drain(      vertex_hdl_t vhdl,
                         paddr_t addr,
                         size_t bytes);
 
 extern void
-hub_dmalist_drain(      devfs_handle_t vhdl,
+hub_dmalist_drain(      vertex_hdl_t vhdl,
                         alenlist_t list);
 
 
@@ -3574,14 +3574,14 @@
 typedef struct hub_intr_s *hub_intr_t;
 
 extern hub_intr_t
-hub_intr_alloc( devfs_handle_t dev,               /* which device */
+hub_intr_alloc( vertex_hdl_t dev,               /* which device */
                 device_desc_t dev_desc,         /* device descriptor */
-                devfs_handle_t owner_dev);        /* owner of this interrupt */
+                vertex_hdl_t owner_dev);        /* owner of this interrupt */
 
 extern hub_intr_t
-hub_intr_alloc_nothd(devfs_handle_t dev,          /* which device */
+hub_intr_alloc_nothd(vertex_hdl_t dev,          /* which device */
                 device_desc_t dev_desc,         /* device descriptor */
-                devfs_handle_t owner_dev);        /* owner of this interrupt */
+                vertex_hdl_t owner_dev);        /* owner of this interrupt */
 
 extern void
 hub_intr_free(hub_intr_t intr_hdl);
@@ -3596,16 +3596,14 @@
 extern void
 hub_intr_disconnect(hub_intr_t intr_hdl);
 
-extern devfs_handle_t
-hub_intr_cpu_get(hub_intr_t intr_hdl);
 
 /* CONFIGURATION MANAGEMENT */
 
 extern void
-hub_provider_startup(devfs_handle_t hub);
+hub_provider_startup(vertex_hdl_t hub);
 
 extern void
-hub_provider_shutdown(devfs_handle_t hub);
+hub_provider_shutdown(vertex_hdl_t hub);
 
 #define HUB_PIO_CONVEYOR        0x1     /* PIO in conveyor belt mode */
 #define HUB_PIO_FIRE_N_FORGET   0x2     /* PIO in fire-and-forget mode */
@@ -3619,38 +3617,26 @@
 
 typedef int     hub_widget_flags_t;
 
-/* Set the PIO mode for a widget.  These two functions perform the
- * same operation, but hub_device_flags_set() takes a hardware graph
- * vertex while hub_widget_flags_set() takes a nasid and widget
- * number.  In most cases, hub_device_flags_set() should be used.
- */
+/* Set the PIO mode for a widget. */
 extern int      hub_widget_flags_set(nasid_t            nasid,
                                      xwidgetnum_t       widget_num,
                                      hub_widget_flags_t flags);
 
-/* Depending on the flags set take the appropriate actions */
-extern int      hub_device_flags_set(devfs_handle_t       widget_dev,
-                                     hub_widget_flags_t flags);
-                                                    
-
 /* Error Handling. */
-extern int hub_ioerror_handler(devfs_handle_t, int, int, struct io_error_s *);
+extern int hub_ioerror_handler(vertex_hdl_t, int, int, struct io_error_s *);
 extern int kl_ioerror_handler(cnodeid_t, cnodeid_t, cpuid_t,
                               int, paddr_t, caddr_t, ioerror_mode_t);
-extern void hub_widget_reset(devfs_handle_t, xwidgetnum_t);
-extern int hub_error_devenable(devfs_handle_t, int, int);
-extern void hub_widgetdev_enable(devfs_handle_t, int);
-extern void hub_widgetdev_shutdown(devfs_handle_t, int);
-extern int  hub_dma_enabled(devfs_handle_t);
+extern int hub_error_devenable(vertex_hdl_t, int, int);
+extern int  hub_dma_enabled(vertex_hdl_t);
 
 /* hubdev */
 extern void hubdev_init(void);
-extern void hubdev_register(int (*attach_method)(devfs_handle_t));
-extern int hubdev_unregister(int (*attach_method)(devfs_handle_t));
-extern int hubdev_docallouts(devfs_handle_t hub);
+extern void hubdev_register(int (*attach_method)(vertex_hdl_t));
+extern int hubdev_unregister(int (*attach_method)(vertex_hdl_t));
+extern int hubdev_docallouts(vertex_hdl_t hub);
 
-extern caddr_t hubdev_prombase_get(devfs_handle_t hub);
-extern cnodeid_t hubdev_cnodeid_get(devfs_handle_t hub);
+extern caddr_t hubdev_prombase_get(vertex_hdl_t hub);
+extern cnodeid_t hubdev_cnodeid_get(vertex_hdl_t hub);
 
 #endif /* __ASSEMBLY__ */
 #endif /* _KERNEL */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/slotnum.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/slotnum.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/slotnum.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/slotnum.h	2003-07-05 18:11:33.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1997,2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_SN2_SLOTNUM_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn2/sn_private.h linux-2.4.22-pre3/include/asm-ia64/sn/sn2/sn_private.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn2/sn_private.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn2/sn_private.h	2003-07-05 18:11:33.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SN2_SN_PRIVATE_H
 #define _ASM_IA64_SN_SN2_SN_PRIVATE_H
@@ -49,13 +49,13 @@
 #endif
 
 /* intr.c */
-extern int intr_reserve_level(cpuid_t cpu, int level, int err, devfs_handle_t owner_dev, char *name);
+extern int intr_reserve_level(cpuid_t cpu, int level, int err, vertex_hdl_t owner_dev, char *name);
 extern void intr_unreserve_level(cpuid_t cpu, int level);
 extern int intr_connect_level(cpuid_t cpu, int bit, ilvl_t mask_no, 
 			intr_func_t intr_prefunc);
 extern int intr_disconnect_level(cpuid_t cpu, int bit);
-extern cpuid_t intr_heuristic(devfs_handle_t dev, device_desc_t dev_desc,
-			      int req_bit,int intr_resflags,devfs_handle_t owner_dev,
+extern cpuid_t intr_heuristic(vertex_hdl_t dev, device_desc_t dev_desc,
+			      int req_bit,int intr_resflags,vertex_hdl_t owner_dev,
 			      char *intr_name,int *resp_bit);
 extern void intr_block_bit(cpuid_t cpu, int bit);
 extern void intr_unblock_bit(cpuid_t cpu, int bit);
@@ -83,8 +83,8 @@
 void bte_wait_for_xfer_completion(void *);
 
 /* klgraph.c */
-void klhwg_add_all_nodes(devfs_handle_t);
-void klhwg_add_all_modules(devfs_handle_t);
+void klhwg_add_all_nodes(vertex_hdl_t);
+void klhwg_add_all_modules(vertex_hdl_t);
 
 /* klidbg.c */
 void install_klidbg_functions(void);
@@ -97,7 +97,6 @@
 /* init.c */
 extern cnodeid_t get_compact_nodeid(void);	/* get compact node id */
 extern void init_platform_nodepda(nodepda_t *npda, cnodeid_t node);
-extern void init_platform_pda(cpuid_t cpu);
 extern void per_cpu_init(void);
 extern int is_fine_dirmode(void);
 extern void update_node_information(cnodeid_t);
@@ -125,7 +124,7 @@
  */
 struct hub_piomap_s {
 	struct xtalk_piomap_s	hpio_xtalk_info;/* standard crosstalk pio info */
-	devfs_handle_t		hpio_hub;	/* which shub's mapping registers are set up */
+	vertex_hdl_t		hpio_hub;	/* which shub's mapping registers are set up */
 	short			hpio_holdcnt;	/* count of current users of bigwin mapping */
 	char			hpio_bigwin_num;/* if big window map, which one */
 	int 			hpio_flags;	/* defined below */
@@ -146,7 +145,7 @@
  */
 struct hub_dmamap_s {
 	struct xtalk_dmamap_s	hdma_xtalk_info;/* standard crosstalk dma info */
-	devfs_handle_t		hdma_hub;	/* which shub we go through */
+	vertex_hdl_t		hdma_hub;	/* which shub we go through */
 	int			hdma_flags;	/* defined below */
 };
 /* shub_dmamap flags */
@@ -214,7 +213,7 @@
 	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t)infoptr)
 
 /* Special initialization function for xswitch vertices created during startup. */
-extern void xswitch_vertex_init(devfs_handle_t xswitch);
+extern void xswitch_vertex_init(vertex_hdl_t xswitch);
 
 extern xtalk_provider_t hub_provider;
 
@@ -248,6 +247,6 @@
 void bootstrap(void);
 
 /* sndrv.c */
-extern int sndrv_attach(devfs_handle_t vertex);
+extern int sndrv_attach(vertex_hdl_t vertex);
 
 #endif /* _ASM_IA64_SN_SN2_SN_PRIVATE_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn_cpuid.h linux-2.4.22-pre3/include/asm-ia64/sn/sn_cpuid.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn_cpuid.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn_cpuid.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -18,6 +18,7 @@
 #include <asm/sn/types.h>
 #include <asm/current.h>
 #include <asm/nodedata.h>
+#include <asm/sn/pda.h>
 
 
 /*
@@ -47,15 +48,10 @@
  *			hard_smp_processor_id()- cpu_physical_id of current processor
  *			cpu_physical_id(cpuid) - convert a <cpuid> to a <physical_cpuid>
  *			cpu_logical_id(phy_id) - convert a <physical_cpuid> to a <cpuid> 
- *				* not real efficient - dont use in perf critical code
+ *				* not real efficient - don't use in perf critical code
  *
  *         LID - processor defined register (see PRM V2).
  *
- *           On SN1
- *		31:24 - id   Contains the NASID
- *		23:16 - eid  Contains 0-3 to identify the cpu on the node
- *				bit 17 - synergy number
- *				bit 16 - FSB slot number 
  *           On SN2
  *		31:28 - id   Contains 0-3 to identify the cpu on the node
  *		27:16 - eid  Contains the NASID
@@ -64,34 +60,30 @@
  *
  * The following assumes the following mappings for LID register values:
  *
- * The macros convert between cpu physical ids & slice/fsb/synergy/nasid/cnodeid.
+ * The macros convert between cpu physical ids & slice/nasid/cnodeid.
  * These terms are described below:
  *
  *
+ * Brick
  *          -----   -----           -----   -----       CPU
- *          | 0 |   | 1 |           | 2 |   | 3 |       SLICE
+ *          | 0 |   | 1 |           | 0 |   | 1 |       SLICE
  *          -----   -----           -----   -----
  *            |       |               |       |
  *            |       |               |       |
- *          0 |       | 1           0 |       | 1       FSB SLOT
+ *          0 |       | 2           0 |       | 2       FSB SLOT
  *             -------                 -------  
  *                |                       |
  *                |                       |
- *             -------                 -------
- *             |     |                 |     |
- *             |  0  |                 |  1  |         SYNERGY (SN1 only)
- *             |     |                 |     |
- *             -------                 -------
  *                |                       |
- *                |                       |
- *             -------------------------------
- *             |                             |
- *             |         BEDROCK / SHUB      |        NASID   (0..MAX_NASIDS)
- *             |                             |        CNODEID (0..num_compact_nodes-1)
- *             |                             |
- *             |                             |
- *             -------------------------------
- *                           |
+ *             ------------      -------------
+ *             |          |      |           |
+ *             |    SHUB  |      |   SHUB    |        NASID   (0..MAX_NASIDS)
+ *             |          |----- |           |        CNODEID (0..num_compact_nodes-1)
+ *             |          |      |           |
+ *             |          |      |           |
+ *             ------------      -------------
+ *                   |                 |
+ *                           
  *
  */
 
@@ -100,25 +92,15 @@
 #define cpu_physical_id(cpuid)			((ia64_get_lid() >> 16) & 0xffff)
 #endif
 
-#ifdef CONFIG_IA64_SGI_SN1
 /*
  * macros for some of these exist in sn/addrs.h & sn/arch.h, etc. However, 
  * trying #include these files here causes circular dependencies.
  */
-#define cpu_physical_id_to_nasid(cpi)		((cpi) >> 8)
-#define cpu_physical_id_to_synergy(cpi)		(((cpi) >> 1) & 1)
-#define cpu_physical_id_to_fsb_slot(cpi)	((cpi) & 1)
-#define cpu_physical_id_to_slice(cpi)		((cpi) & 3)
-#define get_nasid()				((ia64_get_lid() >> 24))
-#define get_slice()				((ia64_get_lid() >> 16) & 3)
-#define get_node_number(addr)			(((unsigned long)(addr)>>33) & 0x7f)
-#else
 #define cpu_physical_id_to_nasid(cpi)		((cpi) &0xfff)
 #define cpu_physical_id_to_slice(cpi)		((cpi>>12) & 3)
 #define get_nasid()				((ia64_get_lid() >> 16) & 0xfff)
 #define get_slice()				((ia64_get_lid() >> 28) & 0xf)
 #define get_node_number(addr)			(((unsigned long)(addr)>>38) & 0x7ff)
-#endif
 
 /*
  * NOTE: id & eid refer to Intel's definitions of the LID register
@@ -129,11 +111,7 @@
 
 #define nasid_slice_to_cpuid(nasid,slice)		(cpu_logical_id(nasid_slice_to_cpu_physical_id((nasid),(slice))))
 
-#ifdef CONFIG_IA64_SGI_SN1
-#define nasid_slice_to_cpu_physical_id(nasid, slice)	(((nasid)<<8) | (slice))
-#else
 #define nasid_slice_to_cpu_physical_id(nasid, slice)	(((slice)<<12) | (nasid))
-#endif
 
 /*
  * The following table/struct  is used for managing PTC coherency domains.
@@ -145,26 +123,9 @@
 } sn_sapicid_info_t;
 
 extern sn_sapicid_info_t	sn_sapicid_info[];	/* indexed by cpuid */
+extern short physical_node_map[];			/* indexed by nasid to get cnode */
 
 
-
-#ifdef CONFIG_IA64_SGI_SN1
-/*
- * cpuid_to_fsb_slot  - convert a cpuid to the fsb slot number that it is in.
- *   (there are 2 cpus per FSB. This function returns 0 or 1)
- */
-#define cpuid_to_fsb_slot(cpuid)	(cpu_physical_id_to_fsb_slot(cpu_physical_id(cpuid)))
-
-
-/*
- * cpuid_to_synergy  - convert a cpuid to the synergy that it resides on
- *   (there are 2 synergies per node. Function returns 0 or 1 to
- *    specify which synergy the cpu is on)
- */
-#define cpuid_to_synergy(cpuid)		(cpu_physical_id_to_synergy(cpu_physical_id(cpuid)))
-
-#endif
-
 /*
  * cpuid_to_slice  - convert a cpuid to the slice that it resides on
  *  There are 4 cpus per node. This function returns 0 .. 3)
@@ -181,7 +142,7 @@
 /*
  * cpuid_to_cnodeid  - convert a cpuid to the cnode that it resides on
  */
-#define cpuid_to_cnodeid(cpuid)		(local_node_data->physical_node_map[cpuid_to_nasid(cpuid)])
+#define cpuid_to_cnodeid(cpuid)		(physical_node_map[cpuid_to_nasid(cpuid)])
 
 
 /*
@@ -190,13 +151,13 @@
  *	Just extract the NASID from the pointer.
  *
  */
-#define cnodeid_to_nasid(cnodeid)	(get_node_number(local_node_data->pg_data_ptrs[cnodeid]))
+#define cnodeid_to_nasid(cnodeid)	pda.cnodeid_to_nasid_table[cnodeid]
  
 
 /*
  * nasid_to_cnodeid - convert a NASID to a cnodeid
  */
-#define nasid_to_cnodeid(nasid)		(local_node_data->physical_node_map[nasid])
+#define nasid_to_cnodeid(nasid)		(physical_node_map[nasid])
 
 
 /*
@@ -214,23 +175,8 @@
 #define cpuid_to_subnode(cpuid)		((cpuid_to_slice(cpuid)<2) ? 0 : 1)
  
 
-/*
- * cpuid_to_localslice - convert a cpuid to a local slice
- *    slice 0 & 2 are local slice 0
- *    slice 1 & 3 are local slice 1
- */
-#define cpuid_to_localslice(cpuid)	(cpuid_to_slice(cpuid) & 1)
- 
-
 #define smp_physical_node_id()			(cpuid_to_nasid(smp_processor_id()))
 
 
-/*
- * cnodeid_to_cpuid - convert a cnode  to a cpuid of a cpu on the node.
- *	returns -1 if no cpus exist on the node
- */
-extern int cnodeid_to_cpuid(int cnode);
-
-
 #endif /* _ASM_IA64_SN_SN_CPUID_H */
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn_fru.h linux-2.4.22-pre3/include/asm-ia64/sn/sn_fru.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn_fru.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn_fru.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,1999-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,1999-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SN_FRU_H
 #define _ASM_IA64_SN_SN_FRU_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn_pio_sync.h linux-2.4.22-pre3/include/asm-ia64/sn/sn_pio_sync.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn_pio_sync.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn_pio_sync.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,53 +0,0 @@
-/*
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#ifndef _ASM_IA64_SN_SN_PIO_WRITE_SYNC_H
-#define _ASM_IA64_SN_SN_PIO_WRITE_SYNC_H
-
-#include <linux/config.h>
-#ifdef CONFIG_IA64_SGI_SN2
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn2/addrs.h>
-#include <asm/sn/sn2/shub_mmr.h>
-#include <asm/sn/sn2/shub_mmr_t.h>
-
-/*
- * This macro flushes all outstanding PIOs performed by this cpu to the 
- * intended destination SHUB.  This in essence ensures that all PIO's
- * issues by this cpu has landed at it's destination.
- *
- * This macro expects the caller:
- *	1.  The thread is locked.
- *	2.  All prior PIO operations has been fenced with __ia64_mf_a().
- *
- * The expectation is that get_slice() will return either 0 or 2.
- * When we have multi-core cpu's, the expectation is get_slice() will 
- * return either 0,1 or 2,3.
- */
-
-#define SN_PIO_WRITE_SYNC \
-	{ \
-		volatile unsigned long sn_pio_writes_done; \
-	do { \
-		sn_pio_writes_done = (volatile unsigned long) (SH_PIO_WRITE_STATUS_0_WRITES_OK_MASK & HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(get_nasid(), (get_slice() < 2) ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1 ))); \
-	} while (!sn_pio_writes_done); \
-	__ia64_mf_a(); \
-	}
-#else
-
-/*
- * For all ARCHITECTURE type, this is a NOOP.
- */
-
-#define SN_PIO_WRITE_SYNC
-
-#endif
-
-#endif /* _ASM_IA64_SN_SN_PIO_WRITE_SYNC_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn_private.h linux-2.4.22-pre3/include/asm-ia64/sn/sn_private.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn_private.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn_private.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SN_PRIVATE_H
 #define _ASM_IA64_SN_SN_PRIVATE_H
@@ -14,10 +14,6 @@
 #include <asm/sn/xtalk/xwidget.h>
 #include <asm/sn/xtalk/xtalk_private.h>
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/sn_private.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/sn_private.h>
-#endif
 
 #endif /* _ASM_IA64_SN_SN_PRIVATE_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sn_sal.h linux-2.4.22-pre3/include/asm-ia64/sn/sn_sal.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sn_sal.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sn_sal.h	2003-07-05 18:11:34.000000000 -0700
@@ -8,7 +8,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -27,6 +27,9 @@
 #define  SN_SAL_LOG_CE				   0x02000006
 #define  SN_SAL_REGISTER_CE			   0x02000007
 #define  SN_SAL_GET_PARTITION_ADDR		   0x02000009
+#define  SN_SAL_XP_ADDR_REGION			   0x0200000f
+#define  SN_SAL_NO_FAULT_ZONE_VIRTUAL		   0x02000010
+#define  SN_SAL_NO_FAULT_ZONE_PHYSICAL		   0x02000011
 #define  SN_SAL_PRINT_ERROR			   0x02000012
 #define  SN_SAL_CONSOLE_PUTC                       0x02000021
 #define  SN_SAL_CONSOLE_GETC                       0x02000022
@@ -36,6 +39,8 @@
 #define  SN_SAL_CONSOLE_POLL                       0x02000026
 #define  SN_SAL_CONSOLE_INTR                       0x02000027
 #define  SN_SAL_CONSOLE_PUTB			   0x02000028
+#define  SN_SAL_CONSOLE_XMIT_CHARS		   0x0200002a
+#define  SN_SAL_CONSOLE_READC			   0x0200002b
 #define  SN_SAL_SYSCTL_MODID_GET	           0x02000031
 #define  SN_SAL_SYSCTL_GET                         0x02000032
 #define  SN_SAL_SYSCTL_IOBRICK_MODULE_GET          0x02000033
@@ -47,17 +52,23 @@
 #define  SN_SAL_SYSCTL_PARTITION_GET		   0x0200003a
 #define  SN_SAL_SYSTEM_POWER_DOWN		   0x0200003b
 #define  SN_SAL_GET_MASTER_BASEIO_NASID		   0x0200003c
+#define  SN_SAL_COHERENCE                          0x0200003d
+#define  SN_SAL_MEMPROTECT                         0x0200003e
+#define  SN_SAL_SYSCTL_FRU_CAPTURE		   0x0200003f
 
 
 /*
  * Service-specific constants
  */
-#define SAL_CONSOLE_INTR_IN     0       /* manipulate input interrupts */
-#define SAL_CONSOLE_INTR_OUT    1       /* manipulate output low-water
-                                         * interrupts
-                                         */
+
+/* Console interrupt manipulation */
+	/* action codes */
 #define SAL_CONSOLE_INTR_OFF    0       /* turn the interrupt off */
 #define SAL_CONSOLE_INTR_ON     1       /* turn the interrupt on */
+#define SAL_CONSOLE_INTR_STATUS 2	/* retrieve the interrupt status */
+	/* interrupt specification & status return codes */
+#define SAL_CONSOLE_INTR_XMIT	1	/* output interrupt */
+#define SAL_CONSOLE_INTR_RECV	2	/* input interrupt */
 
 
 /*
@@ -103,15 +114,8 @@
  * Specify the minimum PROM revsion required for this kernel.
  * Note that they're stored in hex format...
  */
-#ifdef CONFIG_IA64_SGI_SN1
-#define SN_SAL_MIN_MAJOR	0x0
-#define SN_SAL_MIN_MINOR	0x03 /* SN1 PROMs are stuck at rev 0.03 */
-#elif defined(CONFIG_IA64_SGI_SN2)
-#define SN_SAL_MIN_MAJOR	0x0
-#define SN_SAL_MIN_MINOR	0x11
-#else
-#error "must specify which PROM revisions this kernel needs"
-#endif /* CONFIG_IA64_SGI_SN1 */
+#define SN_SAL_MIN_MAJOR	0x1  /* SN2 kernels need at least PROM 1.0 */
+#define SN_SAL_MIN_MINOR	0x0
 
 u64 ia64_sn_probe_io_slot(long paddr, long size, void *data_ptr);
 
@@ -124,10 +128,10 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
 	SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_NASID, 0, 0, 0, 0, 0, 0, 0);
 
 	if (ret_stuff.status < 0)
@@ -146,10 +150,10 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
 	SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_BASEIO_NASID, 0, 0, 0, 0, 0, 0, 0);
 
 	if (ret_stuff.status < 0)
@@ -168,10 +172,10 @@
 
 	cnodeid = nasid_to_cnodeid(nasid);
 	if (klgraph_addr[cnodeid] == 0) {
-		ret_stuff.status = (uint64_t)0;
-		ret_stuff.v0 = (uint64_t)0;
-		ret_stuff.v1 = (uint64_t)0;
-		ret_stuff.v2 = (uint64_t)0;
+		ret_stuff.status = 0;
+		ret_stuff.v0 = 0;
+		ret_stuff.v1 = 0;
+		ret_stuff.v2 = 0;
 		SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0);
 
 		/*
@@ -195,10 +199,10 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
 	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_GETC, 0, 0, 0, 0, 0, 0, 0);
 
 	/* character is in 'v0' */
@@ -208,6 +212,26 @@
 }
 
 /*
+ * Read a character from the SAL console device, after a previous interrupt
+ * or poll operation has given us to know that a character is available
+ * to be read.
+ */
+static inline u64
+ia64_sn_console_readc(void)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_READC, 0, 0, 0, 0, 0, 0, 0);
+
+	/* character is in 'v0' */
+	return ret_stuff.v0;
+}
+
+/*
  * Sends the given character to the console.
  */
 static inline u64
@@ -215,10 +239,10 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
 	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTC, (uint64_t)ch, 0, 0, 0, 0, 0, 0);
 
 	return ret_stuff.status;
@@ -228,17 +252,20 @@
  * Sends the given buffer to the console.
  */
 static inline u64
-ia64_sn_console_putb(char *buf, int len)
+ia64_sn_console_putb(const char *buf, int len)
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0; 
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
 	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTB, (uint64_t)buf, (uint64_t)len, 0, 0, 0, 0, 0);
 
-	return ret_stuff.status;
+	if ( ret_stuff.status == 0 ) {
+		return ret_stuff.v0;
+	}
+	return (u64)0;
 }
 
 /*
@@ -249,10 +276,10 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
 	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_PRINT_ERROR, (uint64_t)hook, (uint64_t)rec, 0, 0, 0, 0, 0);
 
 	return ret_stuff.status;
@@ -266,10 +293,10 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
 	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_LOG_CE, 0, 0, 0, 0, 0, 0, 0);
 
 	return ret_stuff.status;
@@ -283,10 +310,10 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
 	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_POLL, 0, 0, 0, 0, 0, 0, 0);
 
 	/* result is in 'v0' */
@@ -296,6 +323,86 @@
 }
 
 /*
+ * Checks console interrupt status
+ */
+static inline u64
+ia64_sn_console_intr_status(void)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
+		 0, SAL_CONSOLE_INTR_STATUS,
+		 0, 0, 0, 0, 0);
+
+	if (ret_stuff.status == 0) {
+	    return ret_stuff.v0;
+	}
+	
+	return 0;
+}
+
+/*
+ * Enable an interrupt on the SAL console device.
+ */
+static inline void
+ia64_sn_console_intr_enable(uint64_t intr)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
+		 intr, SAL_CONSOLE_INTR_ON,
+		 0, 0, 0, 0, 0);
+}
+
+/*
+ * Disable an interrupt on the SAL console device.
+ */
+static inline void
+ia64_sn_console_intr_disable(uint64_t intr)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
+		 intr, SAL_CONSOLE_INTR_OFF,
+		 0, 0, 0, 0, 0);
+}
+
+/*
+ * Sends a character buffer to the console asynchronously.
+ */
+static inline u64
+ia64_sn_console_xmit_chars(char *buf, int len)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_XMIT_CHARS,
+		 (uint64_t)buf, (uint64_t)len,
+		 0, 0, 0, 0, 0);
+
+	if (ret_stuff.status == 0) {
+	    return ret_stuff.v0;
+	}
+
+	return 0;
+}
+
+/*
  * Returns the iobrick module Id
  */
 static inline u64
@@ -303,11 +410,11 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
-	SAL_CALL(ret_stuff, SN_SAL_SYSCTL_IOBRICK_MODULE_GET, nasid, 0, 0, 0, 0, 0, 0);
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYSCTL_IOBRICK_MODULE_GET, nasid, 0, 0, 0, 0, 0, 0);
 
 	/* result is in 'v0' */
 	*result = (int)ret_stuff.v0;
@@ -339,7 +446,7 @@
 ia64_sn_sys_serial_get(char *buf)
 {
 	struct ia64_sal_retval ret_stuff;
-	SAL_CALL(ret_stuff, SN_SAL_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
 	return ret_stuff.status;
 }
 
@@ -395,7 +502,6 @@
 	return ((partid_t)ret_stuff.v0);
 }
 
-#ifdef CONFIG_IA64_SGI_SN2
 /*
  * Returns the partition id of the current processor.
  */
@@ -411,7 +517,96 @@
 	}
 }
 
-#endif /* CONFIG_IA64_SGI_SN2 */
+/*
+ * Register or unregister a physical address range being referenced across
+ * a partition boundary for which certain SAL errors should be scanned for,
+ * cleaned up and ignored.  This is of value for kernel partitioning code only.
+ * Values for the operation argument:
+ *	1 = register this address range with SAL
+ *	0 = unregister this address range with SAL
+ * 
+ * SAL maintains a reference count on an address range in case it is registered
+ * multiple times.
+ * 
+ * On success, returns the reference count of the address range after the SAL
+ * call has performed the current registration/unregistration.  Returns a
+ * negative value if an error occurred.
+ */
+static inline int
+sn_register_xp_addr_region(u64 paddr, u64 len, int operation)
+{
+	struct ia64_sal_retval ret_stuff;
+	SAL_CALL(ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len, (u64)operation,
+		 0, 0, 0, 0);
+	return ret_stuff.status;
+}
+
+/*
+ * Register or unregister an instruction range for which SAL errors should
+ * be ignored.  If an error occurs while in the registered range, SAL jumps
+ * to return_addr after ignoring the error.  Values for the operation argument:
+ *	1 = register this instruction range with SAL
+ *	0 = unregister this instruction range with SAL
+ *
+ * Returns 0 on success, or a negative value if an error occurred.
+ */
+static inline int
+sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr,
+			 int virtual, int operation)
+{
+	struct ia64_sal_retval ret_stuff;
+	u64 call;
+	if (virtual) {
+		call = SN_SAL_NO_FAULT_ZONE_VIRTUAL;
+	} else {
+		call = SN_SAL_NO_FAULT_ZONE_PHYSICAL;
+	}
+	SAL_CALL(ret_stuff, call, start_addr, end_addr, return_addr, (u64)1,
+		 0, 0, 0);
+	return ret_stuff.status;
+}
+
+/*
+ * Change or query the coherence domain for this partition. Each cpu-based
+ * nasid is represented by a bit in an array of 64-bit words:
+ *      0 = not in this partition's coherency domain
+ *      1 = in this partition's coherency domain
+ *
+ * It is not possible for the local system's nasids to be removed from
+ * the coherency domain.  Purpose of the domain arguments:
+ *      new_domain = set the coherence domain to the given nasids
+ *      old_domain = return the current coherence domain
+ *
+ * Returns 0 on success, or a negative value if an error occurred.
+ */
+static inline int
+sn_change_coherence(u64 *new_domain, u64 *old_domain)
+{
+	struct ia64_sal_retval ret_stuff;
+	SAL_CALL(ret_stuff, SN_SAL_COHERENCE, new_domain, old_domain, 0, 0,
+		 0, 0, 0);
+	return ret_stuff.status;
+}
+
+/*
+ * Change memory access protections for a physical address range.
+ * nasid_array is not used on Altix, but may be in future architectures.
+ * Available memory protection access classes are defined after the function.
+ */
+static inline int
+sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array)
+{
+	struct ia64_sal_retval ret_stuff;
+	SAL_CALL(ret_stuff, SN_SAL_MEMPROTECT, paddr, len, nasid_array,
+		 perms, 0, 0, 0);
+	return ret_stuff.status;
+}
+#define SN_MEMPROT_ACCESS_CLASS_0		0x14a080
+#define SN_MEMPROT_ACCESS_CLASS_1		0x2520c2
+#define SN_MEMPROT_ACCESS_CLASS_2		0x14a1ca
+#define SN_MEMPROT_ACCESS_CLASS_3		0x14a290
+#define SN_MEMPROT_ACCESS_CLASS_6		0x084080
+#define SN_MEMPROT_ACCESS_CLASS_7		0x021080
 
 /*
  * Turns off system power.
@@ -425,5 +620,20 @@
 	/* never returns */
 }
 
+/**
+ * ia64_sn_fru_capture - tell the system controller to capture hw state
+ *
+ * This routine will call the SAL which will tell the system controller(s)
+ * to capture hw mmr information from each SHub in the system.
+ */
+static inline u64
+ia64_sn_fru_capture(void)
+{
+        struct ia64_sal_retval isrv;
+        SAL_CALL(isrv, SN_SAL_SYSCTL_FRU_CAPTURE, 0, 0, 0, 0, 0, 0, 0);
+        if (isrv.status)
+                return 0;
+        return isrv.v0;
+}
 
 #endif /* _ASM_IA64_SN_SN_SAL_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/snconfig.h linux-2.4.22-pre3/include/asm-ia64/sn/snconfig.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/snconfig.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/snconfig.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,18 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- */
-#ifndef _ASM_IA64_SN_SNCONFIG_H
-#define _ASM_IA64_SN_SNCONFIG_H
-
-#include <linux/config.h>
-
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/ip27config.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
-#endif
-
-#endif /* _ASM_IA64_SN_SNCONFIG_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sndrv.h linux-2.4.22-pre3/include/asm-ia64/sn/sndrv.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sndrv.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sndrv.h	2003-07-05 18:11:34.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/sv.h linux-2.4.22-pre3/include/asm-ia64/sn/sv.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/sv.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/sv.h	2003-07-05 18:11:34.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This implemenation of synchronization variables is heavily based on
  * one done by Steve Lord <lord@sgi.com>
@@ -99,7 +99,7 @@
  * Set SV_WAIT_SIG in sv_wait_flags to let the sv_wait be interrupted by signals.
  *
  * timeout is how long to wait before giving up, or 0 to wait
- * indefinately.  It is given in jiffies, and is relative.
+ * indefinitely.  It is given in jiffies, and is relative.
  *
  * The associated lock must be locked on entry.  It is unlocked on return.
  *
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/systeminfo.h linux-2.4.22-pre3/include/asm-ia64/sn/systeminfo.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/systeminfo.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/systeminfo.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,73 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SYSTEMINFO_H
-#define _ASM_IA64_SN_SYSTEMINFO_H
-
-#include <linux/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MAX_SERIAL_SIZE 16
-
-typedef struct module_info_s {
-	uint64_t serial_num;
-	int mod_num;
-	char serial_str[MAX_SERIAL_SIZE];
-} module_info_t;
-
-
-
-/*
- * Commands to sysinfo()
- */
-
-#define SI_SYSNAME		1	/* return name of operating system */
-#define SI_HOSTNAME		2	/* return name of node */
-#define SI_RELEASE 		3	/* return release of operating system */
-#define SI_VERSION		4	/* return version field of utsname */
-#define SI_MACHINE		5	/* return kind of machine */
-#define SI_ARCHITECTURE		6	/* return instruction set arch */
-#define SI_HW_SERIAL		7	/* return hardware serial number */
-#define SI_HW_PROVIDER		8	/* return hardware manufacturer */
-#define SI_SRPC_DOMAIN		9	/* return secure RPC domain */
-#define SI_INITTAB_NAME	       10	/* return name of inittab file used */
-
-#define _MIPS_SI_VENDOR		100	/* return system provider */
-#define _MIPS_SI_OS_PROVIDER	101	/* return OS manufacturer */
-#define _MIPS_SI_OS_NAME	102	/* return OS name */
-#define _MIPS_SI_HW_NAME	103	/* return system name */
-#define _MIPS_SI_NUM_PROCESSORS	104	/* return number of processors */
-#define _MIPS_SI_HOSTID		105	/* return hostid */
-#define _MIPS_SI_OSREL_MAJ	106	/* return OS major release number */
-#define _MIPS_SI_OSREL_MIN	107	/* return OS minor release number */
-#define _MIPS_SI_OSREL_PATCH	108	/* return OS release number */
-#define _MIPS_SI_PROCESSORS	109	/* return CPU revison id */
-#define _MIPS_SI_AVAIL_PROCESSORS 110	/* return number of available processors */
-#define	_MIPS_SI_SERIAL		111
-/*
- * These commands are unpublished interfaces to sysinfo().
- */
-#define SI_SET_HOSTNAME		258	/* set name of node */
-					/*  -unpublished option */
-#define SI_SET_SRPC_DOMAIN	265	/* set secure RPC domain */
-					/* -unpublished option */
-
-#if !defined(__KERNEL__)
-int sysinfo(int, char *, long);
-int get_num_modules(void);
-int get_module_info(int, module_info_t *, size_t);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ASM_IA64_SN_SYSTEMINFO_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/types.h linux-2.4.22-pre3/include/asm-ia64/sn/types.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/types.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/types.h	2003-07-05 18:11:34.000000000 -0700
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright (C) 1999 by Ralf Baechle
  */
 #ifndef _ASM_IA64_SN_TYPES_H
@@ -13,16 +13,10 @@
 #include <linux/types.h>
 
 typedef unsigned long 	cpuid_t;
-typedef unsigned long 	cpumask_t;
 typedef signed short	nasid_t;	/* node id in numa-as-id space */
 typedef signed char	partid_t;	/* partition ID type */
-#ifdef CONFIG_IA64_SGI_SN2
 typedef unsigned int    moduleid_t;     /* user-visible module number type */
 typedef unsigned int    cmoduleid_t;    /* kernel compact module id type */
-#else
-typedef signed short	moduleid_t;	/* user-visible module number type */
-typedef signed short	cmoduleid_t;	/* kernel compact module id type */
-#endif
 typedef signed char slabid_t;
 typedef unsigned char	clusterid_t;	/* Clusterid of the cell */
 
@@ -32,5 +26,6 @@
 typedef unsigned char uchar_t;
 typedef unsigned long paddr_t;
 typedef unsigned long pfn_t;
+typedef short cnodeid_t;
 
 #endif /* _ASM_IA64_SN_TYPES_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/uart16550.h linux-2.4.22-pre3/include/asm-ia64/sn/uart16550.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/uart16550.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/uart16550.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_UART16550_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/vector.h linux-2.4.22-pre3/include/asm-ia64/sn/vector.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/vector.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/vector.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_VECTOR_H
 #define _ASM_IA64_SN_VECTOR_H
@@ -14,18 +14,6 @@
 #define NET_VEC_NULL            ((net_vec_t)  0)
 #define NET_VEC_BAD             ((net_vec_t) -1)
 
-#ifdef RTL
-
-#define VEC_POLLS_W		16	/* Polls before write times out */
-#define VEC_POLLS_R		16	/* Polls before read times out */
-#define VEC_POLLS_X		16	/* Polls before exch times out */
-
-#define VEC_RETRIES_W		1	/* Retries before write fails */
-#define VEC_RETRIES_R		1	/* Retries before read fails */
-#define VEC_RETRIES_X		1	/* Retries before exch fails */
-
-#else /* RTL */
-
 #define VEC_POLLS_W		128	/* Polls before write times out */
 #define VEC_POLLS_R		128	/* Polls before read times out */
 #define VEC_POLLS_X		128	/* Polls before exch times out */
@@ -34,37 +22,6 @@
 #define VEC_RETRIES_R           8	/* Retries before read fails */
 #define VEC_RETRIES_X		4	/* Retries before exch fails */
 
-#endif /* RTL */
-
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#define VECTOR_PARMS		LB_VECTOR_PARMS
-#define VECTOR_ROUTE		LB_VECTOR_ROUTE
-#define VECTOR_DATA		LB_VECTOR_DATA
-#define VECTOR_STATUS		LB_VECTOR_STATUS
-#define VECTOR_RETURN		LB_VECTOR_RETURN
-#define VECTOR_READ_DATA	LB_VECTOR_READ_DATA
-#define VECTOR_STATUS_CLEAR	LB_VECTOR_STATUS_CLEAR
-#define VP_PIOID_SHFT		LVP_PIOID_SHFT
-#define VP_PIOID_MASK		LVP_PIOID_MASK
-#define VP_WRITEID_SHFT		LVP_WRITEID_SHFT
-#define VP_WRITEID_MASK		LVP_WRITEID_MASK
-#define VP_ADDRESS_MASK		LVP_ADDRESS_MASK
-#define VP_TYPE_SHFT		LVP_TYPE_SHFT
-#define VP_TYPE_MASK		LVP_TYPE_MASK
-#define VS_VALID		LVS_VALID
-#define VS_OVERRUN		LVS_OVERRUN
-#define VS_TARGET_SHFT		LVS_TARGET_SHFT
-#define VS_TARGET_MASK		LVS_TARGET_MASK
-#define VS_PIOID_SHFT		LVS_PIOID_SHFT
-#define VS_PIOID_MASK		LVS_PIOID_MASK
-#define VS_WRITEID_SHFT		LVS_WRITEID_SHFT
-#define VS_WRITEID_MASK		LVS_WRITEID_MASK
-#define VS_ADDRESS_MASK		LVS_ADDRESS_MASK
-#define VS_TYPE_SHFT		LVS_TYPE_SHFT
-#define VS_TYPE_MASK		LVS_TYPE_MASK
-#define VS_ERROR_MASK		LVS_ERROR_MASK
-#endif
-
 #define NET_ERROR_NONE		0	/* No error		*/
 #define NET_ERROR_HARDWARE	(-1)	/* Hardware error	*/
 #define NET_ERROR_OVERRUN	(-2)	/* Extra response(s)	*/
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xbow.h linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xbow.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xbow.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xbow.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All Rights Reserved.
  */
 #ifndef _ASM_SN_SN_XTALK_XBOW_H
 #define _ASM_SN_SN_XTALK_XBOW_H
@@ -405,12 +405,6 @@
 /* XBOW_WID_ARB_RELOAD */
 #define	XBOW_WID_ARB_RELOAD_INT	0x3f	/* GBR reload interval */
 
-
-#ifdef	CONFIG_IA64_SGI_SN1
-#define nasid_has_xbridge(nasid)        \
-        (XWIDGET_PART_NUM(XWIDGET_ID_READ(nasid, 0)) == XXBOW_WIDGET_PART_NUM)
-#endif
-
 #define IS_XBRIDGE_XBOW(wid) \
         (XWIDGET_PART_NUM(wid) == XXBOW_WIDGET_PART_NUM && \
                         XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM)
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xbow_info.h linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xbow_info.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xbow_info.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xbow_info.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XBOW_INFO_H
 #define _ASM_SN_XTALK_XBOW_INFO_H
@@ -48,9 +48,9 @@
     volatile uint32_t    *xp_perf_reg;
 } xbow_perf_t;
 
-extern void             xbow_update_perf_counters(devfs_handle_t);
-extern xbow_perf_link_t *xbow_get_perf_counters(devfs_handle_t);
-extern int              xbow_enable_perf_counter(devfs_handle_t, int, int, int);
+extern void             xbow_update_perf_counters(vertex_hdl_t);
+extern xbow_perf_link_t *xbow_get_perf_counters(vertex_hdl_t);
+extern int              xbow_enable_perf_counter(vertex_hdl_t, int, int, int);
 
 #define XBOWIOC_PERF_ENABLE	  	1
 #define XBOWIOC_PERF_DISABLE	 	2
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xswitch.h linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xswitch.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xswitch.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xswitch.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XSWITCH_H
 #define _ASM_SN_XTALK_XSWITCH_H
@@ -23,39 +23,36 @@
 typedef struct xswitch_info_s *xswitch_info_t;
 
 typedef int
-                        xswitch_reset_link_f(devfs_handle_t xconn);
+                        xswitch_reset_link_f(vertex_hdl_t xconn);
 
 typedef struct xswitch_provider_s {
     xswitch_reset_link_f   *reset_link;
 } xswitch_provider_t;
 
-extern void             xswitch_provider_register(devfs_handle_t sw_vhdl, xswitch_provider_t * xsw_fns);
+extern void             xswitch_provider_register(vertex_hdl_t sw_vhdl, xswitch_provider_t * xsw_fns);
 
 xswitch_reset_link_f    xswitch_reset_link;
 
-extern xswitch_info_t   xswitch_info_new(devfs_handle_t vhdl);
+extern xswitch_info_t   xswitch_info_new(vertex_hdl_t vhdl);
 
 extern void             xswitch_info_link_is_ok(xswitch_info_t xswitch_info,
 						xwidgetnum_t port);
 extern void             xswitch_info_vhdl_set(xswitch_info_t xswitch_info,
 					      xwidgetnum_t port,
-					      devfs_handle_t xwidget);
+					      vertex_hdl_t xwidget);
 extern void             xswitch_info_master_assignment_set(xswitch_info_t xswitch_info,
 						       xwidgetnum_t port,
-					       devfs_handle_t master_vhdl);
+					       vertex_hdl_t master_vhdl);
 
-extern xswitch_info_t   xswitch_info_get(devfs_handle_t vhdl);
+extern xswitch_info_t   xswitch_info_get(vertex_hdl_t vhdl);
 
 extern int              xswitch_info_link_ok(xswitch_info_t xswitch_info,
 					     xwidgetnum_t port);
-extern devfs_handle_t     xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
+extern vertex_hdl_t     xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
 					      xwidgetnum_t port);
-extern devfs_handle_t     xswitch_info_master_assignment_get(xswitch_info_t xswitch_info,
+extern vertex_hdl_t     xswitch_info_master_assignment_get(xswitch_info_t xswitch_info,
 						      xwidgetnum_t port);
 
-extern int		xswitch_id_get(devfs_handle_t vhdl);
-extern void		xswitch_id_set(devfs_handle_t vhdl,int xbow_num);
-
 #endif				/* __ASSEMBLY__ */
 
 #endif				/* _ASM_SN_XTALK_XSWITCH_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xtalk.h linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xtalk.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xtalk.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xtalk.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,12 +4,15 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XTALK_H
 #define _ASM_SN_XTALK_XTALK_H
 #include <linux/config.h>
 
+#include "asm/sn/sgi.h"
+
+
 /*
  * xtalk.h -- platform-independent crosstalk interface
  */
@@ -85,7 +88,7 @@
 
 /* PIO MANAGEMENT */
 typedef xtalk_piomap_t
-xtalk_piomap_alloc_f    (devfs_handle_t dev,	/* set up mapping for this device */
+xtalk_piomap_alloc_f    (vertex_hdl_t dev,	/* set up mapping for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
 			 size_t byte_count,
@@ -103,14 +106,14 @@
 xtalk_piomap_done_f     (xtalk_piomap_t xtalk_piomap);
 
 typedef caddr_t
-xtalk_piotrans_addr_f   (devfs_handle_t dev,	/* translate for this device */
+xtalk_piotrans_addr_f   (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 iopaddr_t xtalk_addr,	/* Crosstalk address */
 			 size_t byte_count,	/* map this many bytes */
 			 unsigned flags);	/* (currently unused) */
 
 extern caddr_t
-xtalk_pio_addr		(devfs_handle_t dev,	/* translate for this device */
+xtalk_pio_addr		(vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 iopaddr_t xtalk_addr,	/* Crosstalk address */
 			 size_t byte_count,	/* map this many bytes */
@@ -122,7 +125,7 @@
 typedef struct xtalk_dmamap_s *xtalk_dmamap_t;
 
 typedef xtalk_dmamap_t
-xtalk_dmamap_alloc_f    (devfs_handle_t dev,	/* set up mappings for this device */
+xtalk_dmamap_alloc_f    (vertex_hdl_t dev,	/* set up mappings for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 size_t byte_count_max,		/* max size of a mapping */
 			 unsigned flags);	/* defined in dma.h */
@@ -144,14 +147,14 @@
 xtalk_dmamap_done_f     (xtalk_dmamap_t dmamap);
 
 typedef iopaddr_t
-xtalk_dmatrans_addr_f   (devfs_handle_t dev,	/* translate for this device */
+xtalk_dmatrans_addr_f   (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 paddr_t paddr,		/* system physical address */
 			 size_t byte_count,	/* length */
 			 unsigned flags);
 
 typedef alenlist_t
-xtalk_dmatrans_list_f   (devfs_handle_t dev,	/* translate for this device */
+xtalk_dmatrans_list_f   (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 alenlist_t palenlist,	/* system address/length list */
 			 unsigned flags);
@@ -160,12 +163,12 @@
 xtalk_dmamap_drain_f	(xtalk_dmamap_t map);	/* drain this map's channel */
 
 typedef void
-xtalk_dmaaddr_drain_f	(devfs_handle_t vhdl,	/* drain channel from this device */
+xtalk_dmaaddr_drain_f	(vertex_hdl_t vhdl,	/* drain channel from this device */
 			 paddr_t addr,		/* to this physical address */
 			 size_t bytes);		/* for this many bytes */
 
 typedef void
-xtalk_dmalist_drain_f	(devfs_handle_t vhdl,	/* drain channel from this device */
+xtalk_dmalist_drain_f	(vertex_hdl_t vhdl,	/* drain channel from this device */
 			 alenlist_t list);	/* for this set of physical blocks */
 
 
@@ -196,54 +199,47 @@
 xtalk_intr_setfunc_f    (xtalk_intr_t intr_hdl);	/* interrupt handle */
 
 typedef xtalk_intr_t
-xtalk_intr_alloc_f      (devfs_handle_t dev,	/* which crosstalk device */
+xtalk_intr_alloc_f      (vertex_hdl_t dev,	/* which crosstalk device */
 			 device_desc_t dev_desc,	/* device descriptor */
-			 devfs_handle_t owner_dev);	/* owner of this intr */
+			 vertex_hdl_t owner_dev);	/* owner of this intr */
 
 typedef void
 xtalk_intr_free_f       (xtalk_intr_t intr_hdl);
 
-#ifdef CONFIG_IA64_SGI_SN1
-typedef int
-xtalk_intr_connect_f    (xtalk_intr_t intr_hdl,		/* xtalk intr resource handle */
-			 xtalk_intr_setfunc_f *setfunc,		/* func to set intr hw */
-			 void *setfunc_arg);	/* arg to setfunc */
-#else
 typedef int
 xtalk_intr_connect_f    (xtalk_intr_t intr_hdl,		/* xtalk intr resource handle */
 			intr_func_t intr_func,         /* xtalk intr handler */
 			void *intr_arg,	/* arg to intr handler */
 			xtalk_intr_setfunc_f *setfunc,		/* func to set intr hw */
 			void *setfunc_arg);	/* arg to setfunc */
-#endif
 
 typedef void
 xtalk_intr_disconnect_f (xtalk_intr_t intr_hdl);
 
-typedef devfs_handle_t
+typedef vertex_hdl_t
 xtalk_intr_cpu_get_f    (xtalk_intr_t intr_hdl);	/* xtalk intr resource handle */
 
 /* CONFIGURATION MANAGEMENT */
 
 typedef void
-xtalk_provider_startup_f (devfs_handle_t xtalk_provider);
+xtalk_provider_startup_f (vertex_hdl_t xtalk_provider);
 
 typedef void
-xtalk_provider_shutdown_f (devfs_handle_t xtalk_provider);
+xtalk_provider_shutdown_f (vertex_hdl_t xtalk_provider);
 
 typedef void
-xtalk_widgetdev_enable_f (devfs_handle_t, int);
+xtalk_widgetdev_enable_f (vertex_hdl_t, int);
 
 typedef void
-xtalk_widgetdev_shutdown_f (devfs_handle_t, int);
+xtalk_widgetdev_shutdown_f (vertex_hdl_t, int);
 
 typedef int
-xtalk_dma_enabled_f (devfs_handle_t);
+xtalk_dma_enabled_f (vertex_hdl_t);
 
 /* Error Management */
 
 typedef int
-xtalk_error_devenable_f (devfs_handle_t xconn_vhdl,
+xtalk_error_devenable_f (vertex_hdl_t xconn_vhdl,
 			 int devnum,
 			 int error_code);
 
@@ -285,7 +281,6 @@
     xtalk_intr_free_f      *intr_free;
     xtalk_intr_connect_f   *intr_connect;
     xtalk_intr_disconnect_f *intr_disconnect;
-    xtalk_intr_cpu_get_f   *intr_cpu_get;
 
     /* CONFIGURATION MANAGEMENT */
     xtalk_provider_startup_f *provider_startup;
@@ -327,7 +322,7 @@
 
 /* error management */
 
-extern int              xtalk_error_handler(devfs_handle_t,
+extern int              xtalk_error_handler(vertex_hdl_t,
 					    int,
 					    ioerror_mode_t,
 					    ioerror_t *);
@@ -341,33 +336,33 @@
 #define XTALK_INTR_VECTOR_NONE	(xtalk_intr_vector_t)0
 
 /* Generic crosstalk interrupt interfaces */
-extern devfs_handle_t     xtalk_intr_dev_get(xtalk_intr_t xtalk_intr);
+extern vertex_hdl_t     xtalk_intr_dev_get(xtalk_intr_t xtalk_intr);
 extern xwidgetnum_t     xtalk_intr_target_get(xtalk_intr_t xtalk_intr);
 extern xtalk_intr_vector_t xtalk_intr_vector_get(xtalk_intr_t xtalk_intr);
 extern iopaddr_t        xtalk_intr_addr_get(xtalk_intr_t xtalk_intr);
-extern devfs_handle_t     xtalk_intr_cpu_get(xtalk_intr_t xtalk_intr);
+extern vertex_hdl_t     xtalk_intr_cpu_get(xtalk_intr_t xtalk_intr);
 extern void            *xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr);
 
 /* Generic crosstalk pio interfaces */
-extern devfs_handle_t     xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap);
+extern vertex_hdl_t     xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap);
 extern xwidgetnum_t     xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap);
 extern iopaddr_t        xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap);
 extern size_t           xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap);
 extern caddr_t          xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap);
 
 /* Generic crosstalk dma interfaces */
-extern devfs_handle_t     xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap);
+extern vertex_hdl_t     xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap);
 extern xwidgetnum_t     xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap);
 
 /* Register/unregister Crosstalk providers and get implementation handle */
 extern void             xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
-extern void             xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns);
-extern void             xtalk_provider_unregister(devfs_handle_t provider);
-extern xtalk_provider_t *xtalk_provider_fns_get(devfs_handle_t provider);
+extern void             xtalk_provider_register(vertex_hdl_t provider, xtalk_provider_t *xtalk_fns);
+extern void             xtalk_provider_unregister(vertex_hdl_t provider);
+extern xtalk_provider_t *xtalk_provider_fns_get(vertex_hdl_t provider);
 
 /* Crosstalk Switch generic layer, for use by initialization code */
-extern void             xswitch_census(devfs_handle_t xswitchv);
-extern void             xswitch_init_widgets(devfs_handle_t xswitchv);
+extern void             xswitch_census(vertex_hdl_t xswitchv);
+extern void             xswitch_init_widgets(vertex_hdl_t xswitchv);
 
 /* early init interrupt management */
 
@@ -397,7 +392,7 @@
 
 typedef xtalk_intr_setfunc_f *xtalk_intr_setfunc_t;
 
-typedef void		xtalk_iter_f(devfs_handle_t vhdl);
+typedef void		xtalk_iter_f(vertex_hdl_t vhdl);
 
 extern void		xtalk_iterate(char *prefix, xtalk_iter_f *func);
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xtalk_private.h linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xtalk_private.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xtalk_private.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xtalk_private.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XTALK_PRIVATE_H
 #define _ASM_SN_XTALK_XTALK_PRIVATE_H
@@ -23,7 +23,7 @@
  * All Crosstalk providers set up PIO using this information.
  */
 struct xtalk_piomap_s {
-    devfs_handle_t            xp_dev;	/* a requestor of this mapping */
+    vertex_hdl_t            xp_dev;	/* a requestor of this mapping */
     xwidgetnum_t            xp_target;	/* target (node's widget number) */
     iopaddr_t               xp_xtalk_addr;	/* which crosstalk addr is mapped */
     size_t                  xp_mapsz;	/* size of this mapping */
@@ -34,7 +34,7 @@
  * All Crosstalk providers set up DMA using this information.
  */
 struct xtalk_dmamap_s {
-    devfs_handle_t            xd_dev;	/* a requestor of this mapping */
+    vertex_hdl_t            xd_dev;	/* a requestor of this mapping */
     xwidgetnum_t            xd_target;	/* target (node's widget number) */
 };
 
@@ -42,7 +42,7 @@
  * All Crosstalk providers set up interrupts using this information.
  */
 struct xtalk_intr_s {
-    devfs_handle_t            xi_dev;	/* requestor of this intr */
+    vertex_hdl_t            xi_dev;	/* requestor of this intr */
     xwidgetnum_t            xi_target;	/* master's widget number */
     xtalk_intr_vector_t     xi_vector;	/* 8-bit interrupt vector */
     iopaddr_t               xi_addr;	/* xtalk address to generate intr */
@@ -72,10 +72,10 @@
  */
 struct xwidget_info_s {
     char                   *w_fingerprint;
-    devfs_handle_t            w_vertex;	/* back pointer to vertex */
+    vertex_hdl_t            w_vertex;	/* back pointer to vertex */
     xwidgetnum_t            w_id;	/* widget id */
     struct xwidget_hwid_s   w_hwid;	/* hardware identification (part/rev/mfg) */
-    devfs_handle_t            w_master;	/* CACHED widget's master */
+    vertex_hdl_t            w_master;	/* CACHED widget's master */
     xwidgetnum_t            w_masterid;		/* CACHED widget's master's widgetnum */
     error_handler_f        *w_efunc;	/* error handling function */
     error_handler_arg_t     w_einfo;	/* first parameter for efunc */
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xtalkaddrs.h linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xtalkaddrs.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xtalkaddrs.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xtalkaddrs.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XTALKADDRS_H
 #define _ASM_SN_XTALK_XTALKADDRS_H
diff -urN linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xwidget.h linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xwidget.h
--- linux-2.4.22-pre2/include/asm-ia64/sn/xtalk/xwidget.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/sn/xtalk/xwidget.h	2003-07-05 18:11:34.000000000 -0700
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All Rights Reserved.
  */
 #ifndef __ASM_SN_XTALK_XWIDGET_H__
 #define __ASM_SN_XTALK_XWIDGET_H__
@@ -260,27 +260,26 @@
 extern void             xwidget_driver_unregister(char *driver_prefix);
 
 extern int              xwidget_register(struct xwidget_hwid_s *hwid,
-					 devfs_handle_t dev,
+					 vertex_hdl_t dev,
 					 xwidgetnum_t id,
-					 devfs_handle_t master,
-					 xwidgetnum_t targetid,
-					 async_attach_t aa);
-
-extern int		xwidget_unregister(devfs_handle_t);
-
-extern void             xwidget_reset(devfs_handle_t xwidget);
-extern void             xwidget_gfx_reset(devfs_handle_t xwidget);
-extern char		*xwidget_name_get(devfs_handle_t xwidget);	
+					 vertex_hdl_t master,
+					 xwidgetnum_t targetid);
+
+extern int		xwidget_unregister(vertex_hdl_t);
+
+extern void             xwidget_reset(vertex_hdl_t xwidget);
+extern void             xwidget_gfx_reset(vertex_hdl_t xwidget);
+extern char		*xwidget_name_get(vertex_hdl_t xwidget);	
 
 /* Generic crosstalk widget information access interface */
-extern xwidget_info_t   xwidget_info_chk(devfs_handle_t widget);
-extern xwidget_info_t   xwidget_info_get(devfs_handle_t widget);
-extern void             xwidget_info_set(devfs_handle_t widget, xwidget_info_t widget_info);
-extern devfs_handle_t     xwidget_info_dev_get(xwidget_info_t xwidget_info);
+extern xwidget_info_t   xwidget_info_chk(vertex_hdl_t widget);
+extern xwidget_info_t   xwidget_info_get(vertex_hdl_t widget);
+extern void             xwidget_info_set(vertex_hdl_t widget, xwidget_info_t widget_info);
+extern vertex_hdl_t     xwidget_info_dev_get(xwidget_info_t xwidget_info);
 extern xwidgetnum_t     xwidget_info_id_get(xwidget_info_t xwidget_info);
 extern int              xwidget_info_type_get(xwidget_info_t xwidget_info);
 extern int              xwidget_info_state_get(xwidget_info_t xwidget_info);
-extern devfs_handle_t     xwidget_info_master_get(xwidget_info_t xwidget_info);
+extern vertex_hdl_t     xwidget_info_master_get(xwidget_info_t xwidget_info);
 extern xwidgetnum_t     xwidget_info_masterid_get(xwidget_info_t xwidget_info);
 extern xwidget_part_num_t xwidget_info_part_num_get(xwidget_info_t xwidget_info);
 extern xwidget_rev_num_t xwidget_info_rev_num_get(xwidget_info_t xwidget_info);
diff -urN linux-2.4.22-pre2/include/asm-ia64/system.h linux-2.4.22-pre3/include/asm-ia64/system.h
--- linux-2.4.22-pre2/include/asm-ia64/system.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/system.h	2003-07-05 18:11:34.000000000 -0700
@@ -213,172 +213,9 @@
 # define restore_flags(flags)	__restore_flags(flags)
 #endif /* !CONFIG_SMP */
 
-/*
- * Force an unresolved reference if someone tries to use
- * ia64_fetch_and_add() with a bad value.
- */
-extern unsigned long __bad_size_for_ia64_fetch_and_add (void);
-extern unsigned long __bad_increment_for_ia64_fetch_and_add (void);
-
-#define IA64_FETCHADD(tmp,v,n,sz)						\
-({										\
-	switch (sz) {								\
-	      case 4:								\
-		__asm__ __volatile__ ("fetchadd4.rel %0=[%1],%2"		\
-				      : "=r"(tmp) : "r"(v), "i"(n) : "memory");	\
-		break;								\
-										\
-	      case 8:								\
-		__asm__ __volatile__ ("fetchadd8.rel %0=[%1],%2"		\
-				      : "=r"(tmp) : "r"(v), "i"(n) : "memory");	\
-		break;								\
-										\
-	      default:								\
-		__bad_size_for_ia64_fetch_and_add();				\
-	}									\
-})
-
-#define ia64_fetch_and_add(i,v)							\
-({										\
-	__u64 _tmp;								\
-	volatile __typeof__(*(v)) *_v = (v);					\
-	switch (i) {								\
-	      case -16:	IA64_FETCHADD(_tmp, _v, -16, sizeof(*(v))); break;	\
-	      case  -8:	IA64_FETCHADD(_tmp, _v,  -8, sizeof(*(v))); break;	\
-	      case  -4:	IA64_FETCHADD(_tmp, _v,  -4, sizeof(*(v))); break;	\
-	      case  -1:	IA64_FETCHADD(_tmp, _v,  -1, sizeof(*(v))); break;	\
-	      case   1:	IA64_FETCHADD(_tmp, _v,   1, sizeof(*(v))); break;	\
-	      case   4:	IA64_FETCHADD(_tmp, _v,   4, sizeof(*(v))); break;	\
-	      case   8:	IA64_FETCHADD(_tmp, _v,   8, sizeof(*(v))); break;	\
-	      case  16:	IA64_FETCHADD(_tmp, _v,  16, sizeof(*(v))); break;	\
-	      default:								\
-		_tmp = __bad_increment_for_ia64_fetch_and_add();		\
-		break;								\
-	}									\
-	(__typeof__(*(v))) (_tmp + (i));	/* return new value */		\
-})
-
-/*
- * This function doesn't exist, so you'll get a linker error if
- * something tries to do an invalid xchg().
- */
-extern void __xchg_called_with_bad_pointer (void);
-
-static __inline__ unsigned long
-__xchg (unsigned long x, volatile void *ptr, int size)
-{
-	unsigned long result;
-
-	switch (size) {
-	      case 1:
-		__asm__ __volatile ("xchg1 %0=[%1],%2" : "=r" (result)
-				    : "r" (ptr), "r" (x) : "memory");
-		return result;
-
-	      case 2:
-		__asm__ __volatile ("xchg2 %0=[%1],%2" : "=r" (result)
-				    : "r" (ptr), "r" (x) : "memory");
-		return result;
-
-	      case 4:
-		__asm__ __volatile ("xchg4 %0=[%1],%2" : "=r" (result)
-				    : "r" (ptr), "r" (x) : "memory");
-		return result;
-
-	      case 8:
-		__asm__ __volatile ("xchg8 %0=[%1],%2" : "=r" (result)
-				    : "r" (ptr), "r" (x) : "memory");
-		return result;
-	}
-	__xchg_called_with_bad_pointer();
-	return x;
-}
-
-#define xchg(ptr,x)							     \
-  ((__typeof__(*(ptr))) __xchg ((unsigned long) (x), (ptr), sizeof(*(ptr))))
-
-/*
- * Atomic compare and exchange.  Compare OLD with MEM, if identical,
- * store NEW in MEM.  Return the initial value in MEM.  Success is
- * indicated by comparing RETURN with OLD.
- */
-
-#define __HAVE_ARCH_CMPXCHG 1
-
-/*
- * This function doesn't exist, so you'll get a linker error
- * if something tries to do an invalid cmpxchg().
- */
-extern long __cmpxchg_called_with_bad_pointer(void);
-
-#define ia64_cmpxchg(sem,ptr,old,new,size)						\
-({											\
-	__typeof__(ptr) _p_ = (ptr);							\
-	__typeof__(new) _n_ = (new);							\
-	__u64 _o_, _r_;									\
-											\
-	switch (size) {									\
-	      case 1: _o_ = (__u8 ) (long) (old); break;				\
-	      case 2: _o_ = (__u16) (long) (old); break;				\
-	      case 4: _o_ = (__u32) (long) (old); break;				\
-	      case 8: _o_ = (__u64) (long) (old); break;				\
-	      default: break;								\
-	}										\
-	 __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(_o_));				\
-	switch (size) {									\
-	      case 1:									\
-		__asm__ __volatile__ ("cmpxchg1."sem" %0=[%1],%2,ar.ccv"		\
-				      : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");	\
-		break;									\
-											\
-	      case 2:									\
-		__asm__ __volatile__ ("cmpxchg2."sem" %0=[%1],%2,ar.ccv"		\
-				      : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");	\
-		break;									\
-											\
-	      case 4:									\
-		__asm__ __volatile__ ("cmpxchg4."sem" %0=[%1],%2,ar.ccv"		\
-				      : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");	\
-		break;									\
-											\
-	      case 8:									\
-		__asm__ __volatile__ ("cmpxchg8."sem" %0=[%1],%2,ar.ccv"		\
-				      : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");	\
-		break;									\
-											\
-	      default:									\
-		_r_ = __cmpxchg_called_with_bad_pointer();				\
-		break;									\
-	}										\
-	(__typeof__(old)) _r_;								\
-})
-
-#define cmpxchg_acq(ptr,o,n)	ia64_cmpxchg("acq", (ptr), (o), (n), sizeof(*(ptr)))
-#define cmpxchg_rel(ptr,o,n)	ia64_cmpxchg("rel", (ptr), (o), (n), sizeof(*(ptr)))
-
-/* for compatibility with other platforms: */
-#define cmpxchg(ptr,o,n)	cmpxchg_acq(ptr,o,n)
-
-#ifdef CONFIG_IA64_DEBUG_CMPXCHG
-# define CMPXCHG_BUGCHECK_DECL	int _cmpxchg_bugcheck_count = 128;
-# define CMPXCHG_BUGCHECK(v)							\
-  do {										\
-	if (_cmpxchg_bugcheck_count-- <= 0) {					\
-		void *ip;							\
-		extern int printk(const char *fmt, ...);			\
-		asm ("mov %0=ip" : "=r"(ip));					\
-		printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v));	\
-		break;								\
-	}									\
-  } while (0)
-#else /* !CONFIG_IA64_DEBUG_CMPXCHG */
-# define CMPXCHG_BUGCHECK_DECL
-# define CMPXCHG_BUGCHECK(v)
-#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
-
 #ifdef __KERNEL__
 
-#define prepare_to_switch()    do { } while(0)
+#define prepare_to_switch()    local_irq_disable()
 
 #ifdef CONFIG_IA32_SUPPORT
 # define IS_IA32_PROCESS(regs)	(ia64_psr(regs)->is != 0)
@@ -407,14 +244,17 @@
 # define PERFMON_IS_SYSWIDE() (0)
 #endif
 
-#define __switch_to(prev,next,last) do {						\
-	if (((prev)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID))	\
-	    || IS_IA32_PROCESS(ia64_task_regs(prev)) || PERFMON_IS_SYSWIDE())	\
-		ia64_save_extra(prev);							\
-	if (((next)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID))	\
-	    || IS_IA32_PROCESS(ia64_task_regs(next)) || PERFMON_IS_SYSWIDE())	\
-		ia64_load_extra(next);							\
-	(last) = ia64_switch_to((next));						\
+#define IA64_HAS_EXTRA_STATE(t)							\
+	((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID)	\
+	 || IS_IA32_PROCESS(ia64_task_regs(t)) || PERFMON_IS_SYSWIDE())
+
+#define __switch_to(prev,next,last) do {							 \
+	if (IA64_HAS_EXTRA_STATE(prev))								 \
+		ia64_save_extra(prev);								 \
+	if (IA64_HAS_EXTRA_STATE(next))								 \
+		ia64_load_extra(next);								 \
+	ia64_psr(ia64_task_regs(next))->dfh = !ia64_is_local_fpu_owner(next);			 \
+	(last) = ia64_switch_to((next));							 \
 } while (0)
 
 #ifdef CONFIG_SMP
@@ -423,37 +263,25 @@
 #define arch_consoles_callable() (cpu_online_map & (1UL << smp_processor_id()))
 
 /*
- * In the SMP case, we save the fph state when context-switching
- * away from a thread that modified fph.  This way, when the thread
- * gets scheduled on another CPU, the CPU can pick up the state from
- * task->thread.fph, avoiding the complication of having to fetch
- * the latest fph state from another CPU.
- */
-# define switch_to(prev,next,last) do {					\
-	if (ia64_psr(ia64_task_regs(prev))->mfh) {			\
-		ia64_psr(ia64_task_regs(prev))->mfh = 0;		\
-		(prev)->thread.flags |= IA64_THREAD_FPH_VALID;		\
-		__ia64_save_fpu((prev)->thread.fph);			\
-		(prev)->thread.last_fph_cpu = smp_processor_id();	\
-	}								\
-	if ((next)->thread.flags & IA64_THREAD_FPH_VALID) {		\
-		if (((next)->thread.last_fph_cpu == smp_processor_id()) \
-		    && (ia64_get_fpu_owner() == next)) {		\
-			ia64_psr(ia64_task_regs(next))->dfh = 0;	\
-			ia64_psr(ia64_task_regs(next))->mfh = 0;	\
-		} else {						\
-			ia64_psr(ia64_task_regs(next))->dfh = 1;	\
-		}							\
-	}								\
-	__switch_to(prev,next,last);					\
-  } while (0)
-#else
-# define switch_to(prev,next,last) do {					\
-	ia64_psr(ia64_task_regs(next))->dfh = (ia64_get_fpu_owner() != (next));	\
-	__switch_to(prev,next,last);					\
+ * In the SMP case, we save the fph state when context-switching away from a thread that
+ * modified fph.  This way, when the thread gets scheduled on another CPU, the CPU can
+ * pick up the state from task->thread.fph, avoiding the complication of having to fetch
+ * the latest fph state from another CPU.  In other words: eager save, lazy restore.
+ */
+# define switch_to(prev,next,last) do {						\
+	if (ia64_psr(ia64_task_regs(prev))->mfh) {				\
+		ia64_psr(ia64_task_regs(prev))->mfh = 0;			\
+		(prev)->thread.flags |= IA64_THREAD_FPH_VALID;			\
+		__ia64_save_fpu((prev)->thread.fph);				\
+	}									\
+	__switch_to(prev, next, last);						\
 } while (0)
+#else
+# define switch_to(prev,next,last)	__switch_to(prev, next, last)
 #endif
 
+#define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
diff -urN linux-2.4.22-pre2/include/asm-ia64/unaligned.h linux-2.4.22-pre3/include/asm-ia64/unaligned.h
--- linux-2.4.22-pre2/include/asm-ia64/unaligned.h	2001-07-31 10:30:09.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/unaligned.h	2003-07-05 18:11:34.000000000 -0700
@@ -7,8 +7,8 @@
  * The main single-value unaligned transfer routines.  Derived from
  * the Linux/Alpha version.
  *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998, 1999, 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #define get_unaligned(ptr) \
 	((__typeof__(*(ptr)))ia64_get_unaligned((ptr), sizeof(*(ptr))))
@@ -16,110 +16,105 @@
 #define put_unaligned(x,ptr) \
 	ia64_put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr)))
 
-/*
- * EGCS 1.1 knows about arbitrary unaligned loads.  Define some
- * packed structures to talk about such things with.
- */
 struct __una_u64 { __u64 x __attribute__((packed)); };
 struct __una_u32 { __u32 x __attribute__((packed)); };
 struct __una_u16 { __u16 x __attribute__((packed)); };
 
 static inline unsigned long
-__uldq (const unsigned long * r11)
+__uld8 (const unsigned long * addr)
 {
-	const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
+	const struct __una_u64 *ptr = (const struct __una_u64 *) addr;
 	return ptr->x;
 }
 
 static inline unsigned long
-__uldl (const unsigned int * r11)
+__uld4 (const unsigned int * addr)
 {
-	const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
+	const struct __una_u32 *ptr = (const struct __una_u32 *) addr;
 	return ptr->x;
 }
 
 static inline unsigned long
-__uldw (const unsigned short * r11)
+__uld2 (const unsigned short * addr)
 {
-	const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
+	const struct __una_u16 *ptr = (const struct __una_u16 *) addr;
 	return ptr->x;
 }
 
 static inline void
-__ustq (unsigned long r5, unsigned long * r11)
+__ust8 (unsigned long val, unsigned long * addr)
 {
-	struct __una_u64 *ptr = (struct __una_u64 *) r11;
-	ptr->x = r5;
+	struct __una_u64 *ptr = (struct __una_u64 *) addr;
+	ptr->x = val;
 }
 
 static inline void
-__ustl (unsigned long r5, unsigned int * r11)
+__ust4 (unsigned long val, unsigned int * addr)
 {
-	struct __una_u32 *ptr = (struct __una_u32 *) r11;
-	ptr->x = r5;
+	struct __una_u32 *ptr = (struct __una_u32 *) addr;
+	ptr->x = val;
 }
 
 static inline void
-__ustw (unsigned long r5, unsigned short * r11)
+__ust2 (unsigned long val, unsigned short * addr)
 {
-	struct __una_u16 *ptr = (struct __una_u16 *) r11;
-	ptr->x = r5;
+	struct __una_u16 *ptr = (struct __una_u16 *) addr;
+	ptr->x = val;
 }
 
 
 /*
- * This function doesn't actually exist.  The idea is that when
- * someone uses the macros below with an unsupported size (datatype),
- * the linker will alert us to the problem via an unresolved reference
- * error.
+ * This function doesn't actually exist.  The idea is that when someone uses the macros
+ * below with an unsupported size (datatype), the linker will alert us to the problem via
+ * an unresolved reference error.
  */
 extern unsigned long ia64_bad_unaligned_access_length (void);
 
-#define ia64_get_unaligned(_ptr,size)				\
-({								\
-	const void *ptr = (_ptr);				\
-	unsigned long val;					\
-								\
-	switch (size) {						\
-	      case 1:						\
-		val = *(const unsigned char *) ptr;		\
-		break;						\
-	      case 2:						\
-		val = __uldw((const unsigned short *)ptr);	\
-		break;						\
-	      case 4:						\
-		val = __uldl((const unsigned int *)ptr);	\
-		break;						\
-	      case 8:						\
-		val = __uldq((const unsigned long *)ptr);	\
-		break;						\
-	      default:						\
-		val = ia64_bad_unaligned_access_length();	\
-	}							\
-	val;							\
+#define ia64_get_unaligned(_ptr,size)						\
+({										\
+	const void *__ia64_ptr = (_ptr);					\
+	unsigned long __ia64_val;						\
+										\
+	switch (size) {								\
+	      case 1:								\
+		__ia64_val = *(const unsigned char *) __ia64_ptr;		\
+		break;								\
+	      case 2:								\
+		__ia64_val = __uld2((const unsigned short *)__ia64_ptr);	\
+		break;								\
+	      case 4:								\
+		__ia64_val = __uld4((const unsigned int *)__ia64_ptr);		\
+		break;								\
+	      case 8:								\
+		__ia64_val = __uld8((const unsigned long *)__ia64_ptr);		\
+		break;								\
+	      default:								\
+		__ia64_val = ia64_bad_unaligned_access_length();		\
+	}									\
+	__ia64_val;								\
 })
 
-#define ia64_put_unaligned(_val,_ptr,size)		\
-do {							\
-	const void *ptr = (_ptr);			\
-	unsigned long val = (_val);			\
-							\
-	switch (size) {					\
-	      case 1:					\
-		*(unsigned char *)ptr = (val);		\
-	        break;					\
-	      case 2:					\
-		__ustw(val, (unsigned short *)ptr);	\
-		break;					\
-	      case 4:					\
-		__ustl(val, (unsigned int *)ptr);	\
-		break;					\
-	      case 8:					\
-		__ustq(val, (unsigned long *)ptr);	\
-		break;					\
-	      default:					\
-	    	ia64_bad_unaligned_access_length();	\
-	}						\
+#define ia64_put_unaligned(_val,_ptr,size)				\
+do {									\
+	const void *__ia64_ptr = (_ptr);				\
+	unsigned long __ia64_val = (_val);				\
+									\
+	switch (size) {							\
+	      case 1:							\
+		*(unsigned char *)__ia64_ptr = (__ia64_val);		\
+	        break;							\
+	      case 2:							\
+		__ust2(__ia64_val, (unsigned short *)__ia64_ptr);	\
+		break;							\
+	      case 4:							\
+		__ust4(__ia64_val, (unsigned int *)__ia64_ptr);		\
+		break;							\
+	      case 8:							\
+		__ust8(__ia64_val, (unsigned long *)__ia64_ptr);	\
+		break;							\
+	      default:							\
+	    	ia64_bad_unaligned_access_length();			\
+	}								\
 } while (0)
 
 #endif /* _ASM_IA64_UNALIGNED_H */
diff -urN linux-2.4.22-pre2/include/asm-ia64/unistd.h linux-2.4.22-pre3/include/asm-ia64/unistd.h
--- linux-2.4.22-pre2/include/asm-ia64/unistd.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/unistd.h	2003-07-05 18:11:34.000000000 -0700
@@ -223,6 +223,7 @@
 #define __NR_security			1233
 /* 1234-1235: reserved for {alloc,free}_hugepages */
 /* 1238-1242: reserved for io_{setup,destroy,getevents,submit,cancel} */
+#define __NR_semtimedop			1247
 
 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
 
diff -urN linux-2.4.22-pre2/include/asm-ia64/unwind.h linux-2.4.22-pre3/include/asm-ia64/unwind.h
--- linux-2.4.22-pre2/include/asm-ia64/unwind.h	2001-07-31 10:30:09.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ia64/unwind.h	2003-07-05 18:11:35.000000000 -0700
@@ -2,8 +2,8 @@
 #define _ASM_IA64_UNWIND_H
 
 /*
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2000, 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * A simple API for unwinding kernel stacks.  This is used for
  * debugging and error reporting purposes.  The kernel doesn't need
@@ -60,6 +60,7 @@
 	unsigned long ip;		/* instruction pointer value */
 	unsigned long pr;		/* current predicate values */
 	unsigned long *cfm_loc;		/* cfm save location (or NULL) */
+	unsigned long pt;		/* struct pt_regs location */
 
 	struct task_struct *task;
 	struct switch_stack *sw;
@@ -106,6 +107,13 @@
  */
 extern void unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t);
 
+/*
+ * Prepare to unwind from interruption.  The pt-regs and switch-stack structures must have
+ * be "adjacent" (no state modifications between pt-regs and switch-stack).
+ */
+extern void unw_init_from_interruption (struct unw_frame_info *info, struct task_struct *t,
+					struct pt_regs *pt, struct switch_stack *sw);
+
 extern void unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t,
 				 struct switch_stack *sw);
 
diff -urN linux-2.4.22-pre2/include/asm-m68k/floppy.h linux-2.4.22-pre3/include/asm-m68k/floppy.h
--- linux-2.4.22-pre2/include/asm-m68k/floppy.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-m68k/floppy.h	2003-07-05 18:11:35.000000000 -0700
@@ -72,6 +72,7 @@
 		return inb_p(port);
 	else if(MACH_IS_SUN3X)
 		return sun3x_82072_fd_inb(port);
+	return 0;
 }
 
 static __inline__ void fd_outb(unsigned char value, int port)
@@ -88,9 +89,9 @@
 	if(MACH_IS_Q40)
 		return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
 						   "floppy", floppy_hardint);
-	else if(MACH_IS_SUN3X) 
+	else if(MACH_IS_SUN3X)
 		return sun3xflop_request_irq();
-	
+	return -ENXIO;
 }
 
 static void fd_free_irq(void)
diff -urN linux-2.4.22-pre2/include/asm-m68k/motorola_pgtable.h linux-2.4.22-pre3/include/asm-m68k/motorola_pgtable.h
--- linux-2.4.22-pre2/include/asm-m68k/motorola_pgtable.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-m68k/motorola_pgtable.h	2003-07-05 18:11:35.000000000 -0700
@@ -12,9 +12,7 @@
 #define _PAGE_ACCESSED	0x008
 #define _PAGE_DIRTY	0x010
 #define _PAGE_SUPER	0x080	/* 68040 supervisor only */
-#define _PAGE_FAKE_SUPER 0x200	/* fake supervisor only on 680[23]0 */
 #define _PAGE_GLOBAL040	0x400	/* 68040 global bit, used for kva descs */
-#define _PAGE_COW	0x800	/* implemented in software */
 #define _PAGE_NOCACHE030 0x040	/* 68030 no-cache mode */
 #define _PAGE_NOCACHE	0x060	/* 68040 cache mode, non-serialized */
 #define _PAGE_NOCACHE_S	0x040	/* 68040 no-cache mode, serialized */
@@ -29,6 +27,8 @@
 #define _PAGE_TABLE	(_PAGE_SHORT)
 #define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_NOCACHE)
 
+#define _PAGE_PROTNONE	0x004
+
 #ifndef __ASSEMBLY__
 
 /* This is the cache mode to be used for pages containing page descriptors for
@@ -54,7 +54,7 @@
 extern unsigned long mm_cachebits;
 #endif
 
-#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
+#define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED | mm_cachebits)
 #define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits)
 #define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
 #define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
@@ -62,7 +62,7 @@
 
 /* Alternate definitions that are compile time constants, for
    initializing protection_map.  The cachebits are fixed later.  */
-#define PAGE_NONE_C	__pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED)
+#define PAGE_NONE_C	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
 #define PAGE_SHARED_C	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
 #define PAGE_COPY_C	__pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED)
 #define PAGE_READONLY_C	__pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED)
@@ -132,7 +132,7 @@
 
 
 #define pte_none(pte)		(!pte_val(pte))
-#define pte_present(pte)	(pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER))
+#define pte_present(pte)	(pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROTNONE))
 #define pte_clear(ptep)		({ pte_val(*(ptep)) = 0; })
 #define pte_pagenr(pte)		((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
 
diff -urN linux-2.4.22-pre2/include/asm-m68k/pgtable.h linux-2.4.22-pre3/include/asm-m68k/pgtable.h
--- linux-2.4.22-pre2/include/asm-m68k/pgtable.h	2001-10-25 13:53:55.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-m68k/pgtable.h	2003-07-05 18:11:35.000000000 -0700
@@ -154,9 +154,9 @@
 #else
 
 /* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */
-#define SWP_TYPE(x)			(((x).val >> 1) & 0xff)
-#define SWP_OFFSET(x)			((x).val >> 10)
-#define SWP_ENTRY(type, offset)		((swp_entry_t) { ((type) << 1) | ((offset) << 10) })
+#define SWP_TYPE(x)			(((x).val >> 3) & 0x1ff)
+#define SWP_OFFSET(x)			((x).val >> 12)
+#define SWP_ENTRY(type, offset)		((swp_entry_t) { ((type) << 3) | ((offset) << 12) })
 #define pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
 #define swp_entry_to_pte(x)		((pte_t) { (x).val })
 
diff -urN linux-2.4.22-pre2/include/asm-m68k/virtconvert.h linux-2.4.22-pre3/include/asm-m68k/virtconvert.h
--- linux-2.4.22-pre2/include/asm-m68k/virtconvert.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-m68k/virtconvert.h	2003-07-05 18:11:35.000000000 -0700
@@ -20,7 +20,6 @@
  */
 #ifndef CONFIG_SUN3
 extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const));
-extern unsigned long mm_vtop_fallback (unsigned long) __attribute__ ((const));
 extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
 #else
 extern inline unsigned long mm_vtop(unsigned long vaddr)
@@ -35,39 +34,22 @@
 #endif 
 
 #ifdef CONFIG_SINGLE_MEMORY_CHUNK
-extern inline unsigned long virt_to_phys(volatile void *vaddr)
+static inline unsigned long virt_to_phys(void *vaddr)
 {
-	unsigned long voff = (unsigned long)vaddr - PAGE_OFFSET;
-
-	if (voff < m68k_memory[0].size)
-		return voff + m68k_memory[0].addr;
-	return mm_vtop_fallback((unsigned long)vaddr);
+	return (unsigned long)vaddr - PAGE_OFFSET + m68k_memory[0].addr;
 }
 
-extern inline void * phys_to_virt(unsigned long paddr)
+static inline void * phys_to_virt(unsigned long paddr)
 {
-	unsigned long poff = paddr - m68k_memory[0].addr;
-
-	if (poff < m68k_memory[0].size)
-		return (void *)(poff + PAGE_OFFSET);
-
-#ifdef CONFIG_AMIGA
-	/*
-	 * if on an amiga and address is in first 16M, move it 
-	 * to the ZTWO_VADDR range
-	 */
-	if (MACH_IS_AMIGA && paddr < 16*1024*1024)
-		return (void *)ZTWO_VADDR(paddr);
-#endif
-	return (void *)paddr;
+	return (void *)(paddr - m68k_memory[0].addr + PAGE_OFFSET);
 }
 #else
-extern inline unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(void *address)
 {
 	return mm_vtop((unsigned long)address);
 }
 
-extern inline void * phys_to_virt(unsigned long address)
+static inline void *phys_to_virt(unsigned long address)
 {
 	return (void *) mm_ptov(address);
 }
diff -urN linux-2.4.22-pre2/include/asm-ppc/kmap_types.h linux-2.4.22-pre3/include/asm-ppc/kmap_types.h
--- linux-2.4.22-pre2/include/asm-ppc/kmap_types.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-ppc/kmap_types.h	2003-07-05 18:11:36.000000000 -0700
@@ -9,6 +9,8 @@
 	KM_USER0,
 	KM_USER1,
 	KM_BH_IRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff -urN linux-2.4.22-pre2/include/asm-ppc64/kmap_types.h linux-2.4.22-pre3/include/asm-ppc64/kmap_types.h
--- linux-2.4.22-pre2/include/asm-ppc64/kmap_types.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-ppc64/kmap_types.h	2003-07-05 18:11:37.000000000 -0700
@@ -0,0 +1,23 @@
+#ifdef __KERNEL__
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BIO_SRC_IRQ,
+	KM_BIO_DST_IRQ,
+	KM_PTE0,
+	KM_PTE1,
+	KM_IRQ0,
+	KM_IRQ1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,	
+	KM_TYPE_NR
+};
+
+#endif
+#endif /* __KERNEL__ */
diff -urN linux-2.4.22-pre2/include/asm-s390/ccwcache.h linux-2.4.22-pre3/include/asm-s390/ccwcache.h
--- linux-2.4.22-pre2/include/asm-s390/ccwcache.h	2001-04-11 19:02:28.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390/ccwcache.h	2003-07-05 18:11:38.000000000 -0700
@@ -1,8 +1,11 @@
 /* 
-   * File...........: linux/include/asm-s390/ccwcache.h
-   * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
-   * Bugreports.to..: <Linux390@de.ibm.com>
-   * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ * File...........: linux/include/asm-s390/ccwcache.h
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ *
+ * $Revision: 1.8 $
+ *
  */
 #ifndef CCWCACHE_H
 #define CCWCACHE_H
@@ -38,7 +41,7 @@
 	struct ccw_req_t *refers;	/* Does this request refer to another one? */
 	void *function; /* refers to the originating ERP action */ ;
 
-	unsigned long long expires;	/* expiratioj period */
+	unsigned long long expires;	/* expiration period */
 	/* these are for profiling purposes */
 	unsigned long long buildclk;	/* TOD-clock of request generation */
 	unsigned long long startclk;	/* TOD-clock of request start */
@@ -48,6 +51,8 @@
 	/* these are for internal use */
 	int cplength;		/* length of the channel program in CCWs */
 	int datasize;		/* amount of additional data in bytes */
+	void *lowmem_idal;      /* lowmem page for idals (if in use) */
+	void *lowmem_idal_ptr;  /* ptr to the actual idal word in the idals page */
 	kmem_cache_t *cache;	/* the cache this data comes from */
 
 } __attribute__ ((aligned(4))) ccw_req_t;
@@ -55,16 +60,19 @@
 /* 
  * ccw_req_t -> status can be:
  */
-#define CQR_STATUS_EMPTY    0x00	/* request is empty */
-#define CQR_STATUS_FILLED   0x01	/* request is ready to be preocessed */
-#define CQR_STATUS_QUEUED   0x02	/* request is queued to be processed */
-#define CQR_STATUS_IN_IO    0x03	/* request is currently in IO */
-#define CQR_STATUS_DONE     0x04	/* request is completed successfully */
-#define CQR_STATUS_ERROR    0x05	/* request is completed with error */
-#define CQR_STATUS_FAILED   0x06	/* request is finally failed */
-#define CQR_STATUS_PENDING  0x07        /* request is waiting for interrupt - ERP only */ 
-
-#define CQR_FLAGS_CHAINED  0x01	/* request is chained by another (last CCW is TIC) */
+#define CQR_STATUS_EMPTY    0x00	/* cqr is empty */
+#define CQR_STATUS_FILLED   0x01	/* cqr is ready to be preocessed */
+#define CQR_STATUS_QUEUED   0x02	/* cqr is queued to be processed */
+#define CQR_STATUS_IN_IO    0x03	/* cqr is currently in IO */
+#define CQR_STATUS_DONE     0x04	/* cqr is completed successfully */
+#define CQR_STATUS_ERROR    0x05	/* cqr is completed with error */
+#define CQR_STATUS_FAILED   0x06	/* cqr is finally failed */
+#define CQR_STATUS_PENDING  0x07        /* cqr is waiting for interrupt - ERP only */ 
+
+#define CQR_FLAGS_CHAINED   0x01	/* cqr is chained by another (last CCW is TIC) */
+#define CQR_FLAGS_FINALIZED 0x02	
+#define CQR_FLAGS_LM_CQR    0x04	/* cqr uses page from lowmem_pool */
+#define CQR_FLAGS_LM_IDAL   0x08	/* IDALs uses page from lowmem_pool */
 
 #ifdef __KERNEL__
 #define SMALLEST_SLAB (sizeof(struct ccw_req_t) <= 128 ? 128 :\
diff -urN linux-2.4.22-pre2/include/asm-s390/dasd.h linux-2.4.22-pre3/include/asm-s390/dasd.h
--- linux-2.4.22-pre2/include/asm-s390/dasd.h	2001-10-11 09:43:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390/dasd.h	2003-07-05 18:11:38.000000000 -0700
@@ -8,8 +8,15 @@
  * any future changes wrt the API will result in a change of the APIVERSION reported
  * to userspace by the DASDAPIVER-ioctl
  *
+ * $Revision: 1.51 $
+ *
  * History of changes (starts July 2000)
  * 05/04/01 created by moving the kernel interface to drivers/s390/block/dasd_int.h
+ * 12/06/01 DASD_API_VERSION 2 - binary compatible to 0 (new BIODASDINFO2)
+ * 01/23/02 DASD_API_VERSION 3 - added BIODASDPSRD IOCTL
+ * 02/15/02 DASD_API_VERSION 4 - added BIODASDSATTR IOCTL
+ * 06/07/02 DASD_API_VERSION 5 - added 'boxed DASD' support
+ *         
  */
 
 #ifndef DASD_H
@@ -18,11 +25,126 @@
 
 #define DASD_IOCTL_LETTER 'D'
 
-#if (DASD_API_VERSION == 0)
+#define DASD_API_VERSION 5
+
+/* 
+ * struct dasd_information2_t
+ * represents any data about the device, which is visible to userspace.
+ *  including foramt and featueres.
+ */
+typedef struct dasd_information2_t {
+        unsigned int devno;         /* S/390 devno */
+        unsigned int real_devno;    /* for aliases */
+        unsigned int schid;         /* S/390 subchannel identifier */
+        unsigned int cu_type  : 16; /* from SenseID */
+        unsigned int cu_model :  8; /* from SenseID */
+        unsigned int dev_type : 16; /* from SenseID */
+        unsigned int dev_model : 8; /* from SenseID */
+        unsigned int open_count; 
+        unsigned int req_queue_len; 
+        unsigned int chanq_len;     /* length of chanq */
+        char type[4];               /* from discipline.name, 'none' for unknown */
+        unsigned int status;        /* current device level */
+        unsigned int label_block;   /* where to find the VOLSER */
+        unsigned int FBA_layout;    /* fixed block size (like AIXVOL) */
+        unsigned int characteristics_size;
+        unsigned int confdata_size;
+        char characteristics[64];   /* from read_device_characteristics */
+        char configuration_data[256]; /* from read_configuration_data */
+        unsigned int format;          /* format info like formatted/cdl/ldl/... */
+        unsigned int features;        /* dasd features like 'ro',...            */
+        unsigned int reserved0;       /* reserved for further use ,...          */
+        unsigned int reserved1;       /* reserved for further use ,...          */
+        unsigned int reserved2;       /* reserved for further use ,...          */
+        unsigned int reserved3;       /* reserved for further use ,...          */
+        unsigned int reserved4;       /* reserved for further use ,...          */
+        unsigned int reserved5;       /* reserved for further use ,...          */
+        unsigned int reserved6;       /* reserved for further use ,...          */
+        unsigned int reserved7;       /* reserved for further use ,...          */
+} dasd_information2_t;
+
+/*
+ * values to be used for dasd_information_t.format
+ * 0x00: NOT formatted
+ * 0x01: Linux disc layout
+ * 0x02: Common disc layout
+ */
+#define DASD_FORMAT_NONE 0
+#define DASD_FORMAT_LDL  1
+#define DASD_FORMAT_CDL  2
+/*
+ * values to be used for dasd_information_t.features
+ * 0x00: default features
+ * 0x01: readonly (ro)
+ */
+#define DASD_FEATURE_DEFAULT  0
+#define DASD_FEATURE_READONLY 1
 
 #define DASD_PARTN_BITS 2
 
 /* 
+ * struct dasd_information_t
+ * represents any data about the data, which is visible to userspace
+ */
+typedef struct dasd_information_t {
+        unsigned int devno;         /* S/390 devno */
+        unsigned int real_devno;    /* for aliases */
+        unsigned int schid;         /* S/390 subchannel identifier */
+        unsigned int cu_type  : 16; /* from SenseID */
+        unsigned int cu_model :  8; /* from SenseID */
+        unsigned int dev_type : 16; /* from SenseID */
+        unsigned int dev_model : 8; /* from SenseID */
+        unsigned int open_count; 
+        unsigned int req_queue_len; 
+        unsigned int chanq_len;     /* length of chanq */
+        char type[4];               /* from discipline.name, 'none' for unknown */
+        unsigned int status;        /* current device level */
+        unsigned int label_block;   /* where to find the VOLSER */
+        unsigned int FBA_layout;    /* fixed block size (like AIXVOL) */
+        unsigned int characteristics_size;
+        unsigned int confdata_size;
+        char characteristics[64];   /* from read_device_characteristics */
+        char configuration_data[256]; /* from read_configuration_data */
+} dasd_information_t;
+
+/*
+ * Read Subsystem Data - Perfomance Statistics
+ */ 
+typedef struct dasd_rssd_perf_stats_t {
+	unsigned char  invalid:1;
+	unsigned char  format:3;
+	unsigned char  data_format:4;
+	unsigned char  unit_address;
+	unsigned short device_status;
+	unsigned int   nr_read_normal;
+	unsigned int   nr_read_normal_hits;
+	unsigned int   nr_write_normal;
+	unsigned int   nr_write_fast_normal_hits;
+	unsigned int   nr_read_seq;
+	unsigned int   nr_read_seq_hits;
+	unsigned int   nr_write_seq;
+	unsigned int   nr_write_fast_seq_hits;
+	unsigned int   nr_read_cache;
+	unsigned int   nr_read_cache_hits;
+	unsigned int   nr_write_cache;
+	unsigned int   nr_write_fast_cache_hits;
+	unsigned int   nr_inhibit_cache;
+	unsigned int   nr_bybass_cache;
+	unsigned int   nr_seq_dasd_to_cache;
+	unsigned int   nr_dasd_to_cache;
+	unsigned int   nr_cache_to_dasd;
+	unsigned int   nr_delayed_fast_write;
+	unsigned int   nr_normal_fast_write;
+	unsigned int   nr_seq_fast_write;
+	unsigned int   nr_cache_miss;
+	unsigned char  status2;
+	unsigned int   nr_quick_write_promotes;
+	unsigned char  reserved;
+	unsigned short ssid;
+	unsigned char  reseved2[96];
+} __attribute__((packed)) dasd_rssd_perf_stats_t;
+
+/* 
  * struct profile_info_t
  * holds the profinling information 
  */
@@ -62,30 +184,36 @@
 #define DASD_FMT_INT_INVAL  4 /* invalidate tracks */
 #define DASD_FMT_INT_COMPAT 8 /* use OS/390 compatible disk layout */
 
+
 /* 
- * struct dasd_information_t
- * represents any data about the data, which is visible to userspace
+ * struct attrib_data_t
+ * represents the operation (cache) bits for the device.
+ * Used in DE to influence caching of the DASD.
  */
-typedef struct dasd_information_t {
-        unsigned int devno; /* S/390 devno */
-        unsigned int real_devno; /* for aliases */
-        unsigned int schid; /* S/390 subchannel identifier */
-        unsigned int cu_type  : 16; /* from SenseID */
-        unsigned int cu_model :  8; /* from SenseID */
-        unsigned int dev_type : 16; /* from SenseID */
-        unsigned int dev_model : 8; /* from SenseID */
-        unsigned int open_count; 
-        unsigned int req_queue_len; 
-        unsigned int chanq_len;
-        char type[4]; /* from discipline.name, 'none' for unknown */
-        unsigned int status; /* current device level */
-        unsigned int label_block; /* where to find the VOLSER */
-        unsigned int FBA_layout; /* fixed block size (like AIXVOL) */
-        unsigned int characteristics_size;
-        unsigned int confdata_size;
-        char characteristics[64]; /* from read_device_characteristics */
-        char configuration_data[256]; /* from read_configuration_data */
-} dasd_information_t;
+typedef struct attrib_data_t {
+	unsigned char   operation:3;     /* cache operation mode */
+	unsigned char   reserved:5;      /* cache operation mode */
+	unsigned short  nr_cyl;          /* no of cyliners for read ahaed */
+	unsigned char   reserved2[29];   /* for future use */
+} __attribute__ ((packed)) attrib_data_t;
+
+/* definition of operation (cache) bits within attributes of DE */
+#define DASD_NORMAL_CACHE  0x0
+#define DASD_BYPASS_CACHE  0x1
+#define DASD_INHIBIT_LOAD  0x2
+#define DASD_SEQ_ACCESS    0x3
+#define DASD_SEQ_PRESTAGE  0x4
+#define DASD_REC_ACCESS    0x5
+
+
+/********************************************************************************
+ * SECTION: Definition of IOCTLs
+ *
+ * Here ist how the ioctl-nr should be used:
+ *    0 -   31   DASD driver itself
+ *   32 -  239   still open
+ *  240 -  255   reserved for EMC 
+ *******************************************************************************/
 
 /* Disable the volume (for Linux) */
 #define BIODASDDISABLE _IO(DASD_IOCTL_LETTER,0) 
@@ -97,15 +225,26 @@
 #define BIODASDSLCK    _IO(DASD_IOCTL_LETTER,4) /* steal lock */
 /* reset profiling information of a device */
 #define BIODASDPRRST   _IO(DASD_IOCTL_LETTER,5)
+
+
 /* retrieve API version number */
 #define DASDAPIVER     _IOR(DASD_IOCTL_LETTER,0,int)
 /* Get information on a dasd device */
 #define BIODASDINFO    _IOR(DASD_IOCTL_LETTER,1,dasd_information_t)
 /* retrieve profiling information of a device */
 #define BIODASDPRRD    _IOR(DASD_IOCTL_LETTER,2,dasd_profile_info_t)
+/* Get information on a dasd device (enhanced) */
+#define BIODASDINFO2   _IOR(DASD_IOCTL_LETTER,3,dasd_information2_t)
+/* Performance Statistics Read */
+#define BIODASDPSRD    _IOR(DASD_IOCTL_LETTER,4,dasd_rssd_perf_stats_t)
+
+
 /* #define BIODASDFORMAT  _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */
 #define BIODASDFMT     _IOW(DASD_IOCTL_LETTER,1,format_data_t) 
-#endif /* DASD_API_VERSION */
+/* Set Attributes (cache operations) */
+#define BIODASDSATTR   _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) 
+
+
 #endif				/* DASD_H */
 
 /*
diff -urN linux-2.4.22-pre2/include/asm-s390/idals.h linux-2.4.22-pre3/include/asm-s390/idals.h
--- linux-2.4.22-pre2/include/asm-s390/idals.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390/idals.h	2003-07-05 18:11:38.000000000 -0700
@@ -217,7 +217,7 @@
  * Copy count bytes from an idal buffer to user memory
  */
 static inline size_t
-idal_buffer_to_user(struct idal_buffer *ib, void *to, size_t count)
+idal_buffer_to_user(const struct idal_buffer *ib, void *to, size_t count)
 {
 	size_t left;
 	int i;
@@ -238,7 +238,7 @@
  * Copy count bytes from user memory to an idal buffer
  */
 static inline size_t
-idal_buffer_from_user(struct idal_buffer *ib, void *from, size_t count)
+idal_buffer_from_user(struct idal_buffer *ib, const void *from, size_t count)
 {
 	size_t left;
 	int i;
diff -urN linux-2.4.22-pre2/include/asm-s390/irq.h linux-2.4.22-pre3/include/asm-s390/irq.h
--- linux-2.4.22-pre2/include/asm-s390/irq.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-s390/irq.h	2003-07-05 18:11:38.000000000 -0700
@@ -497,6 +497,8 @@
 #define DEVSTAT_SUSPENDED          0x00000400
 #define DEVSTAT_UNKNOWN_DEV        0x00000800
 #define DEVSTAT_UNFRIENDLY_DEV     0x00001000
+#define DEVSTAT_NOT_ACC            0x00002000
+#define DEVSTAT_NOT_ACC_ERR        0x00004000
 #define DEVSTAT_FINAL_STATUS       0x80000000
 
 #define DEVINFO_NOT_OPER           DEVSTAT_NOT_OPER
@@ -581,6 +583,7 @@
 #define DOIO_TIMEOUT             0x0080 /* 3 secs. timeout for sync. I/O */
 #define DOIO_DONT_CALL_INTHDLR   0x0100 /* don't call interrupt handler */
 #define DOIO_CANCEL_ON_TIMEOUT   0x0200 /* cancel I/O if it timed out */
+#define DOIO_USE_DIAG98          0x0400 /* use DIAG98 instead of SSCH */
 
 /*
  * do_IO()
@@ -785,6 +788,25 @@
         return ccode;
 }
 
+extern __inline__ int diag98(int irq, volatile orb_t *addr)
+{
+        int ccode;
+
+        __asm__ __volatile__(
+                "   lr    1,%1\n"
+                "   lr    0,%2\n"    /* orb in 0 */
+		"   lhi   2,12\n"    /* function code 0x0c */
+		"   diag  2,0,152\n" /* diag98 instead of ssch,
+					result in gpr 1 */
+                "   ipm   %0\n"      /* usual cc evaluation. cc=3 will be
+				        reported as not operational */
+                "   srl   %0,28"
+                : "=d" (ccode) 
+		: "d" (irq | 0x10000L), "a" (addr)
+                : "cc", "0", "1", "2");
+        return ccode;
+}
+
 extern __inline__ int rsch(int irq)
 {
         int ccode;
@@ -888,25 +910,8 @@
 void VM_virtual_device_info( __u16      devno,   /* device number */
                              senseid_t *ps );    /* ptr to senseID data */
 
-extern __inline__ int diag210( diag210_t * addr)
-{
-        int ccode;
+extern int diag210( diag210_t * addr);
 
-        __asm__ __volatile__(
-#ifdef CONFIG_ARCH_S390X
-                "   sam31\n"
-                "   diag  %1,0,0x210\n"
-                "   sam64\n"
-#else
-                "   diag  %1,0,0x210\n"
-#endif
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "a" (addr)
-                : "cc" );
-        return ccode;
-}
 extern __inline__ int chsc( chsc_area_t * chsc_area)
 {
 	int cc;
@@ -999,6 +1004,8 @@
 
 #include <asm/s390io.h>
 
+#define get_irq_lock(irq) &ioinfo[irq]->irq_lock
+
 #define s390irq_spin_lock(irq) \
         spin_lock(&(ioinfo[irq]->irq_lock))
 
diff -urN linux-2.4.22-pre2/include/asm-s390/page.h linux-2.4.22-pre3/include/asm-s390/page.h
--- linux-2.4.22-pre2/include/asm-s390/page.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390/page.h	2003-07-05 18:11:38.000000000 -0700
@@ -9,7 +9,6 @@
 #ifndef _S390_PAGE_H
 #define _S390_PAGE_H
 
-#include <asm/errno.h>
 #include <asm/setup.h>
 #include <asm/types.h>
 
@@ -18,9 +17,6 @@
 #define PAGE_SIZE       (1UL << PAGE_SHIFT)
 #define PAGE_MASK       (~(PAGE_SIZE-1))
 
-#define STORAGE_ACC_KEY		6
-#define STORAGE_ACC_KEY_MASK	(STORAGE_ACC_KEY<<4)
-
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
@@ -124,62 +120,13 @@
 #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 
-/* the pfix table of all mem addresses */
-extern void* *pfix_table;
-#define pfix_get_page_addr(ptr) (pfix_table[(unsigned long)ptr>>PAGE_SHIFT])
-#define pfix_get_addr(ptr) (pfix_get_page_addr(ptr)+ \
-			    ((unsigned long)ptr&PAGE_MASK))
-
-/*
- * These functions allow to lock and unlock pages in VM. They need
- * the absolute address of the page to be locked or unlocked. This will
- * only work if the diag98 option in the user directory is enabled for
- * the guest.
- */
-
-/* if result is 0, addr will become the host absolute address */
-extern __inline__ int pfix_lock_page(void *addr)
-{
-        int ret = -ENOMEM;
-
-        if (!MACHINE_HAS_PFIX)
-                return -ENOSYS;
-
-        __asm__ __volatile__(
-                "   l     0,%1\n"  /* parameter in gpr 0 */
-                "   lhi   2,0\n"   /* function code is 0 */
-                "   diag  2,0,0x98\n" /* result in gpr 1 */
-                "   jnz   0f\n"
-                "   lhi   %0,0\n"
-                "0: l     %1,1\n"  /* gpr1 contains host absol. addr */
-                : "+d" (ret), "+d" ((unsigned long)addr) : 
-                : "0", "1", "2", "cc" );
-        return ret;
-}
-
-extern __inline__ int pfix_unlock_page(unsigned long addr)
-{
-        int ret = -EINVAL;
-
-        if (!MACHINE_HAS_PFIX)
-                return -ENOSYS;
-
-        __asm__ __volatile__(
-                "   lr    0,%1\n"  /* parameter in gpr 0 */
-                "   lhi   2,4\n"   /* function code is 4 */
-                "   diag  2,0,0x98\n" /* result in gpr 1 */
-                "   jnz   0f\n"
-                "   lhi   %0,0\n"
-                "0:\n"
-                : "+d" (ret)
-                : "a" (addr)
-                : "0", "1", "2", "cc" );
-        return ret;
-}
-
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+unsigned int get_storage_key(void);
+unsigned long pfix_get_page_addr(void *);
+unsigned long pfix_get_addr(void *);
+
 #endif /* __KERNEL__ */
 
 #endif /* _S390_PAGE_H */
diff -urN linux-2.4.22-pre2/include/asm-s390/pgtable.h linux-2.4.22-pre3/include/asm-s390/pgtable.h
--- linux-2.4.22-pre2/include/asm-s390/pgtable.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390/pgtable.h	2003-07-05 18:11:38.000000000 -0700
@@ -156,7 +156,6 @@
 
 /* Bits in the page table entry */
 #define _PAGE_PRESENT   0x001          /* Software                         */
-#define _PAGE_MKCLEAN   0x002          /* Software                         */
 #define _PAGE_ISCLEAN   0x004	       /* Software			   */
 #define _PAGE_RO        0x200          /* HW read-only                     */
 #define _PAGE_INVALID   0x400          /* HW invalid                       */
@@ -230,28 +229,9 @@
  */
 extern inline void set_pte(pte_t *pteptr, pte_t pteval)
 {
-	if ((pte_val(pteval) & (_PAGE_MKCLEAN|_PAGE_INVALID))
-	    == _PAGE_MKCLEAN) 
-	{
-		pte_val(pteval) &= ~_PAGE_MKCLEAN;
-               
-		asm volatile ("sske %0,%1" 
-				: : "d" (STORAGE_ACC_KEY_MASK),
-				"a" (pte_val(pteval)));
-	}
-
 	*pteptr = pteval;
 }
 
-extern inline void set_access_key(pte_t pteval)
-{
-	asm volatile ("    iske 0,%1\n"
-		      "    or   0,%0\n"
-		      "    sske 0,%1\n"
-			: : "d" (STORAGE_ACC_KEY_MASK),
-			"a" (pte_val(pteval)) : "0", "cc");
-}
-
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
 /*
@@ -362,7 +342,7 @@
 	 * sske instruction is slow. It is faster to let the
 	 * next instruction set the dirty bit.
 	 */
-	pte_val(pte) &= ~(_PAGE_MKCLEAN | _PAGE_ISCLEAN);
+	pte_val(pte) &= ~_PAGE_ISCLEAN;
 	return pte;
 }
 
@@ -404,7 +384,7 @@
 	/* We can't clear the changed bit atomically. For now we
          * clear (!) the page referenced bit. */
 	asm volatile ("sske %0,%1" 
-	              : : "d" (STORAGE_ACC_KEY_MASK), "a" (*ptep));
+	              : : "d" (get_storage_key()), "a" (*ptep));
 	return 1;
 }
 
@@ -443,15 +423,15 @@
 	pgprot_t __pgprot = (pgprot);					  \
 	unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
 	pte_t __pte = mk_pte_phys(__physpage, __pgprot);                  \
-	                                                                  \
-	if (!(pgprot_val(__pgprot) & _PAGE_ISCLEAN)) {			  \
-		int __users = !!__page->buffers + !!__page->mapping;      \
-		if (__users + page_count(__page) == 1)                    \
-			pte_val(__pte) |= _PAGE_MKCLEAN;                  \
-	}								  \
 	__pte;                                                            \
 })
 
+#define arch_set_page_uptodate(__page)					  \
+	do {								  \
+		asm volatile ("sske %0,%1" : : "d" (get_storage_key()),	  \
+			      "a" (__pa((__page-mem_map) << PAGE_SHIFT)));\
+	} while (0)
+
 #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
 
 #define pmd_page(pmd) \
diff -urN linux-2.4.22-pre2/include/asm-s390/s390io.h linux-2.4.22-pre3/include/asm-s390/s390io.h
--- linux-2.4.22-pre2/include/asm-s390/s390io.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-s390/s390io.h	2003-07-05 18:11:39.000000000 -0700
@@ -8,6 +8,7 @@
 
 #ifndef __s390io_h
 #define __s390io_h
+#include <linux/tqueue.h>
 
 /*
  * IRQ data structure used by I/O subroutines
@@ -57,7 +58,9 @@
            unsigned int  dval      : 1;  /* device number valid */
            unsigned int  unknown   : 1;  /* unknown device - if SenseID failed */
 	   unsigned int  unfriendly: 1;  /* device is locked by someone else */
-           unsigned int  unused    : (sizeof(unsigned int)*8 - 25); /* unused */
+	   unsigned int  killio    : 1;  /* currently killing pending io */
+	   unsigned int  noio      : 1;  /* don't let drivers start io */
+           unsigned int  unused    : (sizeof(unsigned int)*8 - 27); /* unused */
               } __attribute__ ((packed)) flags;
         } ui;
 
@@ -80,8 +83,9 @@
      unsigned long qflag;         /* queued flags */
      __u8          qlpm;          /* queued logical path mask */
      ssd_info_t    ssd_info;      /* subchannel description */
-
-   } __attribute__ ((aligned(8))) ioinfo_t;
+     struct tq_struct pver_bh;    /* path verification bottom half task */
+     atomic_t	   pver_pending;  /* != 0 if path verification for sch is pending */
+} __attribute__ ((aligned(8))) ioinfo_t;
 
 #define IOINFO_FLAGS_BUSY    0x80000000
 #define IOINFO_FLAGS_OPER    0x40000000
@@ -101,5 +105,9 @@
 #define CHSC_SEI_ACC_LINKADDR     2
 #define CHSC_SEI_ACC_FULLLINKADDR 3
 
+#define CIO_PATHGONE_WAIT4INT     0x01
+#define CIO_PATHGONE_IOERR        0x02
+#define CIO_PATHGONE_DEVGONE      0x04
+
 #endif  /* __s390io_h */
 
diff -urN linux-2.4.22-pre2/include/asm-s390/setup.h linux-2.4.22-pre3/include/asm-s390/setup.h
--- linux-2.4.22-pre2/include/asm-s390/setup.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390/setup.h	2003-07-05 18:11:39.000000000 -0700
@@ -30,6 +30,7 @@
 #define MACHINE_IS_P390  (machine_flags & 4)
 #define MACHINE_HAS_CSP  (machine_flags & 8)
 #define MACHINE_HAS_MVPG (machine_flags & 16)
+#define MACHINE_NEW_STIDP	(machine_flags & 64)
 #define MACHINE_HAS_PFIX (machine_flags & 128)
 
 #define MACHINE_HAS_HWC  (!MACHINE_IS_P390)
diff -urN linux-2.4.22-pre2/include/asm-s390/vtoc.h linux-2.4.22-pre3/include/asm-s390/vtoc.h
--- linux-2.4.22-pre2/include/asm-s390/vtoc.h	2001-11-09 14:11:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-s390/vtoc.h	2003-07-05 18:11:39.000000000 -0700
@@ -18,7 +18,6 @@
 #include <asm/dasd.h>
 #endif
 
-#define DASD_API_VERSION 0
 
 #define LINE_LENGTH 80
 #define VTOC_START_CC 0x0
diff -urN linux-2.4.22-pre2/include/asm-s390x/ccwcache.h linux-2.4.22-pre3/include/asm-s390x/ccwcache.h
--- linux-2.4.22-pre2/include/asm-s390x/ccwcache.h	2001-04-11 19:02:29.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390x/ccwcache.h	2003-07-05 18:11:39.000000000 -0700
@@ -1,8 +1,11 @@
 /* 
-   * File...........: linux/include/asm-s390/ccwcache.h
-   * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
-   * Bugreports.to..: <Linux390@de.ibm.com>
-   * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ * File...........: linux/include/asm-s390/ccwcache.h
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ *
+ * $Revision: 1.10 $
+ *
  */
 #ifndef CCWCACHE_H
 #define CCWCACHE_H
@@ -38,7 +41,7 @@
 	struct ccw_req_t *refers;	/* Does this request refer to another one? */
 	void *function; /* refers to the originating ERP action */ ;
 
-	unsigned long long expires;	/* expiratioj period */
+	unsigned long long expires;	/* expiration period */
 	/* these are for profiling purposes */
 	unsigned long long buildclk;	/* TOD-clock of request generation */
 	unsigned long long startclk;	/* TOD-clock of request start */
@@ -48,6 +51,8 @@
 	/* these are for internal use */
 	int cplength;		/* length of the channel program in CCWs */
 	int datasize;		/* amount of additional data in bytes */
+	void *lowmem_idal;      /* lowmem page for idals (if in use) */
+	void *lowmem_idal_ptr;  /* ptr to the actual idal word in the idals page */
 	kmem_cache_t *cache;	/* the cache this data comes from */
 
 } __attribute__ ((aligned(4))) ccw_req_t;
@@ -55,16 +60,19 @@
 /* 
  * ccw_req_t -> status can be:
  */
-#define CQR_STATUS_EMPTY    0x00	/* request is empty */
-#define CQR_STATUS_FILLED   0x01	/* request is ready to be preocessed */
-#define CQR_STATUS_QUEUED   0x02	/* request is queued to be processed */
-#define CQR_STATUS_IN_IO    0x03	/* request is currently in IO */
-#define CQR_STATUS_DONE     0x04	/* request is completed successfully */
-#define CQR_STATUS_ERROR    0x05	/* request is completed with error */
-#define CQR_STATUS_FAILED   0x06	/* request is finally failed */
-#define CQR_STATUS_PENDING  0x07        /* request is waiting for interrupt - ERP only */ 
-
-#define CQR_FLAGS_CHAINED  0x01	/* request is chained by another (last CCW is TIC) */
+#define CQR_STATUS_EMPTY    0x00	/* cqr is empty */
+#define CQR_STATUS_FILLED   0x01	/* cqr is ready to be preocessed */
+#define CQR_STATUS_QUEUED   0x02	/* cqr is queued to be processed */
+#define CQR_STATUS_IN_IO    0x03	/* cqr is currently in IO */
+#define CQR_STATUS_DONE     0x04	/* cqr is completed successfully */
+#define CQR_STATUS_ERROR    0x05	/* cqr is completed with error */
+#define CQR_STATUS_FAILED   0x06	/* cqr is finally failed */
+#define CQR_STATUS_PENDING  0x07        /* cqr is waiting for interrupt - ERP only */ 
+
+#define CQR_FLAGS_CHAINED   0x01	/* cqr is chained by another (last CCW is TIC) */
+#define CQR_FLAGS_FINALIZED 0x02	
+#define CQR_FLAGS_LM_CQR    0x04	/* cqr uses page from lowmem_pool */
+#define CQR_FLAGS_LM_IDAL   0x08	/* IDALs uses page from lowmem_pool */
 
 #ifdef __KERNEL__
 #define SMALLEST_SLAB (sizeof(struct ccw_req_t) <= 128 ? 128 :\
diff -urN linux-2.4.22-pre2/include/asm-s390x/dasd.h linux-2.4.22-pre3/include/asm-s390x/dasd.h
--- linux-2.4.22-pre2/include/asm-s390x/dasd.h	2001-10-11 09:43:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390x/dasd.h	2003-07-05 18:11:39.000000000 -0700
@@ -8,8 +8,15 @@
  * any future changes wrt the API will result in a change of the APIVERSION reported
  * to userspace by the DASDAPIVER-ioctl
  *
+ * $Revision: 1.51 $
+ *
  * History of changes (starts July 2000)
  * 05/04/01 created by moving the kernel interface to drivers/s390/block/dasd_int.h
+ * 12/06/01 DASD_API_VERSION 2 - binary compatible to 0 (new BIODASDINFO2)
+ * 01/23/02 DASD_API_VERSION 3 - added BIODASDPSRD IOCTL
+ * 02/15/02 DASD_API_VERSION 4 - added BIODASDSATTR IOCTL
+ * 06/07/02 DASD_API_VERSION 5 - added 'boxed DASD' support
+ *         
  */
 
 #ifndef DASD_H
@@ -18,11 +25,126 @@
 
 #define DASD_IOCTL_LETTER 'D'
 
-#if (DASD_API_VERSION == 0)
+#define DASD_API_VERSION 5
+
+/* 
+ * struct dasd_information2_t
+ * represents any data about the device, which is visible to userspace.
+ *  including foramt and featueres.
+ */
+typedef struct dasd_information2_t {
+        unsigned int devno;         /* S/390 devno */
+        unsigned int real_devno;    /* for aliases */
+        unsigned int schid;         /* S/390 subchannel identifier */
+        unsigned int cu_type  : 16; /* from SenseID */
+        unsigned int cu_model :  8; /* from SenseID */
+        unsigned int dev_type : 16; /* from SenseID */
+        unsigned int dev_model : 8; /* from SenseID */
+        unsigned int open_count; 
+        unsigned int req_queue_len; 
+        unsigned int chanq_len;     /* length of chanq */
+        char type[4];               /* from discipline.name, 'none' for unknown */
+        unsigned int status;        /* current device level */
+        unsigned int label_block;   /* where to find the VOLSER */
+        unsigned int FBA_layout;    /* fixed block size (like AIXVOL) */
+        unsigned int characteristics_size;
+        unsigned int confdata_size;
+        char characteristics[64];   /* from read_device_characteristics */
+        char configuration_data[256]; /* from read_configuration_data */
+        unsigned int format;          /* format info like formatted/cdl/ldl/... */
+        unsigned int features;        /* dasd features like 'ro',...            */
+        unsigned int reserved0;       /* reserved for further use ,...          */
+        unsigned int reserved1;       /* reserved for further use ,...          */
+        unsigned int reserved2;       /* reserved for further use ,...          */
+        unsigned int reserved3;       /* reserved for further use ,...          */
+        unsigned int reserved4;       /* reserved for further use ,...          */
+        unsigned int reserved5;       /* reserved for further use ,...          */
+        unsigned int reserved6;       /* reserved for further use ,...          */
+        unsigned int reserved7;       /* reserved for further use ,...          */
+} dasd_information2_t;
+
+/*
+ * values to be used for dasd_information_t.format
+ * 0x00: NOT formatted
+ * 0x01: Linux disc layout
+ * 0x02: Common disc layout
+ */
+#define DASD_FORMAT_NONE 0
+#define DASD_FORMAT_LDL  1
+#define DASD_FORMAT_CDL  2
+/*
+ * values to be used for dasd_information_t.features
+ * 0x00: default features
+ * 0x01: readonly (ro)
+ */
+#define DASD_FEATURE_DEFAULT  0
+#define DASD_FEATURE_READONLY 1
 
 #define DASD_PARTN_BITS 2
 
 /* 
+ * struct dasd_information_t
+ * represents any data about the data, which is visible to userspace
+ */
+typedef struct dasd_information_t {
+        unsigned int devno;         /* S/390 devno */
+        unsigned int real_devno;    /* for aliases */
+        unsigned int schid;         /* S/390 subchannel identifier */
+        unsigned int cu_type  : 16; /* from SenseID */
+        unsigned int cu_model :  8; /* from SenseID */
+        unsigned int dev_type : 16; /* from SenseID */
+        unsigned int dev_model : 8; /* from SenseID */
+        unsigned int open_count; 
+        unsigned int req_queue_len; 
+        unsigned int chanq_len;     /* length of chanq */
+        char type[4];               /* from discipline.name, 'none' for unknown */
+        unsigned int status;        /* current device level */
+        unsigned int label_block;   /* where to find the VOLSER */
+        unsigned int FBA_layout;    /* fixed block size (like AIXVOL) */
+        unsigned int characteristics_size;
+        unsigned int confdata_size;
+        char characteristics[64];   /* from read_device_characteristics */
+        char configuration_data[256]; /* from read_configuration_data */
+} dasd_information_t;
+
+/*
+ * Read Subsystem Data - Perfomance Statistics
+ */ 
+typedef struct dasd_rssd_perf_stats_t {
+	unsigned char  invalid:1;
+	unsigned char  format:3;
+	unsigned char  data_format:4;
+	unsigned char  unit_address;
+	unsigned short device_status;
+	unsigned int   nr_read_normal;
+	unsigned int   nr_read_normal_hits;
+	unsigned int   nr_write_normal;
+	unsigned int   nr_write_fast_normal_hits;
+	unsigned int   nr_read_seq;
+	unsigned int   nr_read_seq_hits;
+	unsigned int   nr_write_seq;
+	unsigned int   nr_write_fast_seq_hits;
+	unsigned int   nr_read_cache;
+	unsigned int   nr_read_cache_hits;
+	unsigned int   nr_write_cache;
+	unsigned int   nr_write_fast_cache_hits;
+	unsigned int   nr_inhibit_cache;
+	unsigned int   nr_bybass_cache;
+	unsigned int   nr_seq_dasd_to_cache;
+	unsigned int   nr_dasd_to_cache;
+	unsigned int   nr_cache_to_dasd;
+	unsigned int   nr_delayed_fast_write;
+	unsigned int   nr_normal_fast_write;
+	unsigned int   nr_seq_fast_write;
+	unsigned int   nr_cache_miss;
+	unsigned char  status2;
+	unsigned int   nr_quick_write_promotes;
+	unsigned char  reserved;
+	unsigned short ssid;
+	unsigned char  reseved2[96];
+} __attribute__((packed)) dasd_rssd_perf_stats_t;
+
+/* 
  * struct profile_info_t
  * holds the profinling information 
  */
@@ -62,30 +184,36 @@
 #define DASD_FMT_INT_INVAL  4 /* invalidate tracks */
 #define DASD_FMT_INT_COMPAT 8 /* use OS/390 compatible disk layout */
 
+
 /* 
- * struct dasd_information_t
- * represents any data about the data, which is visible to userspace
+ * struct attrib_data_t
+ * represents the operation (cache) bits for the device.
+ * Used in DE to influence caching of the DASD.
  */
-typedef struct dasd_information_t {
-        unsigned int devno; /* S/390 devno */
-        unsigned int real_devno; /* for aliases */
-        unsigned int schid; /* S/390 subchannel identifier */
-        unsigned int cu_type  : 16; /* from SenseID */
-        unsigned int cu_model :  8; /* from SenseID */
-        unsigned int dev_type : 16; /* from SenseID */
-        unsigned int dev_model : 8; /* from SenseID */
-        unsigned int open_count; 
-        unsigned int req_queue_len; 
-        unsigned int chanq_len;
-        char type[4]; /* from discipline.name, 'none' for unknown */
-        unsigned int status; /* current device level */
-        unsigned int label_block; /* where to find the VOLSER */
-        unsigned int FBA_layout; /* fixed block size (like AIXVOL) */
-        unsigned int characteristics_size;
-        unsigned int confdata_size;
-        char characteristics[64]; /* from read_device_characteristics */
-        char configuration_data[256]; /* from read_configuration_data */
-} dasd_information_t;
+typedef struct attrib_data_t {
+	unsigned char   operation:3;     /* cache operation mode */
+	unsigned char   reserved:5;      /* cache operation mode */
+	unsigned short  nr_cyl;          /* no of cyliners for read ahaed */
+	unsigned char   reserved2[29];   /* for future use */
+} __attribute__ ((packed)) attrib_data_t;
+
+/* definition of operation (cache) bits within attributes of DE */
+#define DASD_NORMAL_CACHE  0x0
+#define DASD_BYPASS_CACHE  0x1
+#define DASD_INHIBIT_LOAD  0x2
+#define DASD_SEQ_ACCESS    0x3
+#define DASD_SEQ_PRESTAGE  0x4
+#define DASD_REC_ACCESS    0x5
+
+
+/********************************************************************************
+ * SECTION: Definition of IOCTLs
+ *
+ * Here ist how the ioctl-nr should be used:
+ *    0 -   31   DASD driver itself
+ *   32 -  239   still open
+ *  240 -  255   reserved for EMC 
+ *******************************************************************************/
 
 /* Disable the volume (for Linux) */
 #define BIODASDDISABLE _IO(DASD_IOCTL_LETTER,0) 
@@ -97,15 +225,26 @@
 #define BIODASDSLCK    _IO(DASD_IOCTL_LETTER,4) /* steal lock */
 /* reset profiling information of a device */
 #define BIODASDPRRST   _IO(DASD_IOCTL_LETTER,5)
+
+
 /* retrieve API version number */
 #define DASDAPIVER     _IOR(DASD_IOCTL_LETTER,0,int)
 /* Get information on a dasd device */
 #define BIODASDINFO    _IOR(DASD_IOCTL_LETTER,1,dasd_information_t)
 /* retrieve profiling information of a device */
 #define BIODASDPRRD    _IOR(DASD_IOCTL_LETTER,2,dasd_profile_info_t)
+/* Get information on a dasd device (enhanced) */
+#define BIODASDINFO2   _IOR(DASD_IOCTL_LETTER,3,dasd_information2_t)
+/* Performance Statistics Read */
+#define BIODASDPSRD    _IOR(DASD_IOCTL_LETTER,4,dasd_rssd_perf_stats_t)
+
+
 /* #define BIODASDFORMAT  _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */
 #define BIODASDFMT     _IOW(DASD_IOCTL_LETTER,1,format_data_t) 
-#endif /* DASD_API_VERSION */
+/* Set Attributes (cache operations) */
+#define BIODASDSATTR   _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) 
+
+
 #endif				/* DASD_H */
 
 /*
diff -urN linux-2.4.22-pre2/include/asm-s390x/idals.h linux-2.4.22-pre3/include/asm-s390x/idals.h
--- linux-2.4.22-pre2/include/asm-s390x/idals.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390x/idals.h	2003-07-05 18:11:39.000000000 -0700
@@ -217,7 +217,7 @@
  * Copy count bytes from an idal buffer to user memory
  */
 static inline size_t
-idal_buffer_to_user(struct idal_buffer *ib, void *to, size_t count)
+idal_buffer_to_user(const struct idal_buffer *ib, void *to, size_t count)
 {
 	size_t left;
 	int i;
@@ -238,7 +238,7 @@
  * Copy count bytes from user memory to an idal buffer
  */
 static inline size_t
-idal_buffer_from_user(struct idal_buffer *ib, void *from, size_t count)
+idal_buffer_from_user(struct idal_buffer *ib, const void *from, size_t count)
 {
 	size_t left;
 	int i;
diff -urN linux-2.4.22-pre2/include/asm-s390x/irq.h linux-2.4.22-pre3/include/asm-s390x/irq.h
--- linux-2.4.22-pre2/include/asm-s390x/irq.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-s390x/irq.h	2003-07-05 18:11:39.000000000 -0700
@@ -498,6 +498,8 @@
 #define DEVSTAT_SUSPENDED          0x00000400
 #define DEVSTAT_UNKNOWN_DEV        0x00000800
 #define DEVSTAT_UNFRIENDLY_DEV     0x00001000
+#define DEVSTAT_NOT_ACC            0x00002000
+#define DEVSTAT_NOT_ACC_ERR        0x00004000
 #define DEVSTAT_FINAL_STATUS       0x80000000
 
 #define DEVINFO_NOT_OPER           DEVSTAT_NOT_OPER
@@ -582,6 +584,7 @@
 #define DOIO_TIMEOUT             0x0080 /* 3 secs. timeout for sync. I/O */
 #define DOIO_DONT_CALL_INTHDLR   0x0100 /* don't call interrupt handler */
 #define DOIO_CANCEL_ON_TIMEOUT   0x0200 /* cancel I/O if it timed out */
+#define DOIO_USE_DIAG98          0x0400 /* use DIAG98 instead of SSCH */
 
 /*
  * do_IO()
@@ -786,6 +789,25 @@
         return ccode;
 }
 
+extern __inline__ int diag98(int irq, volatile orb_t *addr)
+{
+        int ccode;
+
+        __asm__ __volatile__(
+                "   lr    1,%1\n"
+                "   lgr   0,%2\n"    /* orb in 0 */
+		"   lghi  2,12\n"    /* function code 0x0c */
+		"   diag  2,0,152\n" /* diag98 instead of ssch,
+					result in gpr 1 */
+                "   ipm   %0\n"      /* usual cc evaluation. cc=3 will be
+				        reported as not operational */
+                "   srl   %0,28"
+                : "=d" (ccode) 
+		: "d" (irq | 0x10000L), "a" (addr)
+                : "cc", "0", "1", "2");
+        return ccode;
+}
+
 extern __inline__ int rsch(int irq)
 {
         int ccode;
@@ -889,25 +911,7 @@
 void VM_virtual_device_info( __u16      devno,   /* device number */
                              senseid_t *ps );    /* ptr to senseID data */
 
-extern __inline__ int diag210( diag210_t * addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-#ifdef CONFIG_ARCH_S390X
-                "   sam31\n"
-                "   diag  %1,0,0x210\n"
-                "   sam64\n"
-#else
-                "   diag  %1,0,0x210\n"
-#endif
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "a" (addr)
-                : "cc" );
-        return ccode;
-}
+extern int diag210( diag210_t * addr);
 
 extern __inline__ int chsc( chsc_area_t * chsc_area)
 {
@@ -1001,6 +1005,8 @@
 
 #include <asm/s390io.h>
 
+#define get_irq_lock(irq) &ioinfo[irq]->irq_lock
+
 #define s390irq_spin_lock(irq) \
         spin_lock(&(ioinfo[irq]->irq_lock))
 
diff -urN linux-2.4.22-pre2/include/asm-s390x/page.h linux-2.4.22-pre3/include/asm-s390x/page.h
--- linux-2.4.22-pre2/include/asm-s390x/page.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390x/page.h	2003-07-05 18:11:39.000000000 -0700
@@ -9,7 +9,6 @@
 #ifndef _S390_PAGE_H
 #define _S390_PAGE_H
 
-#include <asm/errno.h>
 #include <asm/setup.h>
 
 /* PAGE_SHIFT determines the page size */
@@ -17,9 +16,6 @@
 #define PAGE_SIZE       (1UL << PAGE_SHIFT)
 #define PAGE_MASK       (~(PAGE_SIZE-1))
 
-#define STORAGE_ACC_KEY		6
-#define STORAGE_ACC_KEY_MASK	(STORAGE_ACC_KEY<<4)
-
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
@@ -130,62 +126,13 @@
 #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 
-/* the pfix table of all mem addresses */
-extern void* *pfix_table;
-#define pfix_get_page_addr(ptr) (pfix_table[(unsigned long)ptr>>PAGE_SHIFT])
-#define pfix_get_addr(ptr) (pfix_get_page_addr(ptr)+ \
-			    ((unsigned long)ptr&PAGE_MASK))
-
-/*
- * These two functions allow to lock and unlock pages in VM. They need
- * the absolute address of the page to be locked or unlocked. This will
- * only work if the diag98 option in the user directory is enabled for
- * the guest.
- */
-
-/* if result is 0, addr will become the host absolute address */
-extern __inline__ int pfix_lock_page(void *addr)
-{
-        int ret = -ENOMEM;
-
-        if (!MACHINE_HAS_PFIX)
-                return -ENOSYS;
-
-        __asm__ __volatile__(
-                "   lg    0,%1\n"  /* parameter in gpr 0 */
-                "   lghi  2,0\n"   /* function code is 0 */
-                "   diag  2,0,0x98\n" /* result in gpr 1 */
-                "   jnz   0f\n"
-                "   lghi  %0,0\n"
-                "0: lg    %1,1\n"  /* gpr1 contains host absol. addr */
-                : "+d" (ret), "+d" ((unsigned long)addr) : 
-                : "0", "1", "2", "cc" );
-        return ret;
-}
-
-extern __inline__ int pfix_unlock_page(unsigned long addr)
-{
-        int ret = -EINVAL;
-
-        if (!MACHINE_HAS_PFIX)
-                return -ENOSYS;
-
-        __asm__ __volatile__(
-                "   lgr   0,%1\n"  /* parameter in gpr 0 */
-                "   lghi  2,4\n"   /* function code is 4 */
-                "   diag  2,0,0x98\n" /* result in gpr 1 */
-                "   jnz   0f\n"
-                "   lghi  %0,0\n"
-                "0:\n"
-                : "+d" (ret)
-                : "a" (addr)
-                : "0", "1", "2", "cc" );
-        return ret;
-}
-
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define get_storage_key() 0
+#define pfix_get_page_addr(addr) (unsigned long)addr
+#define pfix_get_addr(addr) (unsigned long)addr
+
 #endif                                 /* __KERNEL__                       */
 
 #endif                                 /* _S390_PAGE_H                     */
diff -urN linux-2.4.22-pre2/include/asm-s390x/pgtable.h linux-2.4.22-pre3/include/asm-s390x/pgtable.h
--- linux-2.4.22-pre2/include/asm-s390x/pgtable.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390x/pgtable.h	2003-07-05 18:11:39.000000000 -0700
@@ -158,7 +158,6 @@
 
 /* Bits in the page table entry */
 #define _PAGE_PRESENT   0x001          /* Software                         */
-#define _PAGE_MKCLEAN   0x002          /* Software                         */
 #define _PAGE_ISCLEAN   0x004          /* Software                         */
 #define _PAGE_RO        0x200          /* HW read-only                     */
 #define _PAGE_INVALID   0x400          /* HW invalid                       */
@@ -227,28 +226,9 @@
  */
 extern inline void set_pte(pte_t *pteptr, pte_t pteval)
 {
-	if ((pte_val(pteval) & (_PAGE_MKCLEAN|_PAGE_INVALID))
-	    == _PAGE_MKCLEAN) 
-	{
-		pte_val(pteval) &= ~_PAGE_MKCLEAN;
-               
-		asm volatile ("sske %0,%1" 
-				: : "d" (STORAGE_ACC_KEY_MASK),
-				"a" (pte_val(pteval)));
-	}
-
 	*pteptr = pteval;
 }
 
-extern inline void set_access_key(pte_t pteval)
-{
-	asm volatile ("    iske 0,%1\n"
-		      "    or   0,%0\n"
-		      "    sske 0,%1\n"
-			: : "d" (STORAGE_ACC_KEY_MASK),
-			"a" (pte_val(pteval)) : "0", "cc");
-}
-
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
 /*
@@ -420,7 +400,7 @@
 	 * sske instruction is slow. It is faster to let the
 	 * next instruction set the dirty bit.
 	 */
-	pte_val(pte) &= ~(_PAGE_MKCLEAN | _PAGE_ISCLEAN);
+	pte_val(pte) &= ~_PAGE_ISCLEAN;
 	return pte;
 }
 
@@ -462,7 +442,7 @@
 	/* We can't clear the changed bit atomically. For now we
          * clear (!) the page referenced bit. */
 	asm volatile ("sske %0,%1" 
-	              : : "d" (STORAGE_ACC_KEY_MASK), "a" (*ptep));
+	              : : "d" (0), "a" (*ptep));
 	return 1;
 }
 
@@ -501,15 +481,15 @@
 	pgprot_t __pgprot = (pgprot);					  \
 	unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
 	pte_t __pte = mk_pte_phys(__physpage, __pgprot);                  \
- 	                                                                  \
-	if (!(pgprot_val(__pgprot) & _PAGE_ISCLEAN)) {			  \
-		int __users = !!__page->buffers + !!__page->mapping;      \
-		if (__users + page_count(__page) == 1)                    \
-			pte_val(__pte) |= _PAGE_MKCLEAN;                  \
-	}								  \
 	__pte;                                                            \
 })
 
+#define arch_set_page_uptodate(__page)					  \
+	do {								  \
+		asm volatile ("sske %0,%1" : : "d" (0),			  \
+			      "a" (__pa((__page-mem_map) << PAGE_SHIFT)));\
+	} while (0)
+
 #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
 
 #define pmd_page(pmd) \
diff -urN linux-2.4.22-pre2/include/asm-s390x/s390io.h linux-2.4.22-pre3/include/asm-s390x/s390io.h
--- linux-2.4.22-pre2/include/asm-s390x/s390io.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-s390x/s390io.h	2003-07-05 18:11:40.000000000 -0700
@@ -8,6 +8,7 @@
 
 #ifndef __s390io_h
 #define __s390io_h
+#include <linux/tqueue.h>
 
 /*
  * IRQ data structure used by I/O subroutines
@@ -23,7 +24,7 @@
      struct _ioinfo *prev;
      struct _ioinfo *next;
 
-     __u8          st;            /* subchannel type */	
+     __u8          st;            /* subchannel type */
 
      union {
         unsigned int info;
@@ -57,7 +58,9 @@
            unsigned int  dval      : 1;  /* device number valid */
            unsigned int  unknown   : 1;  /* unknown device - if SenseID failed */
 	   unsigned int  unfriendly: 1;  /* device is locked by someone else */
-           unsigned int  unused    : (sizeof(unsigned int)*8 - 25); /* unused */
+	   unsigned int  killio    : 1;  /* currently killing pending io */
+	   unsigned int  noio      : 1;  /* don't let drivers start io */
+           unsigned int  unused    : (sizeof(unsigned int)*8 - 27); /* unused */
               } __attribute__ ((packed)) flags;
         } ui;
 
@@ -80,8 +83,9 @@
      unsigned long qflag;         /* queued flags */
      __u8          qlpm;          /* queued logical path mask */
      ssd_info_t    ssd_info;      /* subchannel description */
-
-   } __attribute__ ((aligned(8))) ioinfo_t;
+     struct tq_struct pver_bh;    /* path verification bottom half task */
+     atomic_t	   pver_pending;  /* != 0 if path verification for sch is pending */
+} __attribute__ ((aligned(8))) ioinfo_t;
 
 #define IOINFO_FLAGS_BUSY    0x80000000
 #define IOINFO_FLAGS_OPER    0x40000000
@@ -101,5 +105,9 @@
 #define CHSC_SEI_ACC_LINKADDR     2
 #define CHSC_SEI_ACC_FULLLINKADDR 3
 
+#define CIO_PATHGONE_WAIT4INT     0x01
+#define CIO_PATHGONE_IOERR        0x02
+#define CIO_PATHGONE_DEVGONE      0x04
+
 #endif  /* __s390io_h */
 
diff -urN linux-2.4.22-pre2/include/asm-s390x/setup.h linux-2.4.22-pre3/include/asm-s390x/setup.h
--- linux-2.4.22-pre2/include/asm-s390x/setup.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-s390x/setup.h	2003-07-05 18:11:40.000000000 -0700
@@ -29,7 +29,8 @@
 #define MACHINE_IS_P390		(machine_flags & 4)
 #define MACHINE_HAS_MVPG	(machine_flags & 16)
 #define MACHINE_HAS_DIAG44	(machine_flags & 32)
-#define MACHINE_HAS_PFIX  	(machine_flags & 128)
+#define MACHINE_NEW_STIDP	(machine_flags & 64)
+#define MACHINE_HAS_PFIX  	(0)
 
 #define MACHINE_HAS_HWC		(!MACHINE_IS_P390)
 
diff -urN linux-2.4.22-pre2/include/asm-s390x/vtoc.h linux-2.4.22-pre3/include/asm-s390x/vtoc.h
--- linux-2.4.22-pre2/include/asm-s390x/vtoc.h	2001-11-09 14:11:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-s390x/vtoc.h	2003-07-05 18:11:40.000000000 -0700
@@ -18,7 +18,6 @@
 #include <asm/dasd.h>
 #endif
 
-#define DASD_API_VERSION 0
 
 #define LINE_LENGTH 80
 #define VTOC_START_CC 0x0
diff -urN linux-2.4.22-pre2/include/asm-sh64/a.out.h linux-2.4.22-pre3/include/asm-sh64/a.out.h
--- linux-2.4.22-pre2/include/asm-sh64/a.out.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/a.out.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,37 @@
+#ifndef __ASM_SH64_A_OUT_H
+#define __ASM_SH64_A_OUT_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/a.out.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+struct exec
+{
+  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
+  unsigned a_text;		/* length of text, in bytes */
+  unsigned a_data;		/* length of data, in bytes */
+  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+  unsigned a_syms;		/* length of symbol table data in file, in bytes */
+  unsigned a_entry;		/* start address */
+  unsigned a_trsize;		/* length of relocation info for text, in bytes */
+  unsigned a_drsize;		/* length of relocation info for data, in bytes */
+};
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+#ifdef __KERNEL__
+
+#define STACK_TOP	TASK_SIZE
+
+#endif
+
+#endif /* __ASM_SH64_A_OUT_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/atomic.h linux-2.4.22-pre3/include/asm-sh64/atomic.h
--- linux-2.4.22-pre2/include/asm-sh64/atomic.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/atomic.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,102 @@
+#ifndef __ASM_SH_ATOMIC_H
+#define __ASM_SH_ATOMIC_H
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ *
+ */
+
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i)	( (atomic_t) { (i) } )
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v,i)		((v)->counter = (i))
+
+#include <asm/system.h>
+
+/*
+ * To get proper branch prediction for the main line, we must branch
+ * forward to code at the end of this object's .text section, then
+ * branch back to restart the operation.
+ */
+
+static __inline__ void atomic_add(int i, atomic_t * v)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	*(long *)v += i;
+	restore_flags(flags);
+}
+
+static __inline__ void atomic_sub(int i, atomic_t *v)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	*(long *)v -= i;
+	restore_flags(flags);
+}
+
+static __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+	unsigned long temp, flags;
+
+	save_and_cli(flags);
+	temp = *(long *)v;
+	temp += i;
+	*(long *)v = temp;
+	restore_flags(flags);
+
+	return temp;
+}
+
+static __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+	unsigned long temp, flags;
+
+	save_and_cli(flags);
+	temp = *(long *)v;
+	temp -= i;
+	*(long *)v = temp;
+	restore_flags(flags);
+
+	return temp;
+}
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+#define atomic_inc(v) atomic_add(1,(v))
+#define atomic_dec(v) atomic_sub(1,(v))
+
+static __inline__ void atomic_clear_mask(unsigned int mask, atomic_t *v)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	*(long *)v &= ~mask;
+	restore_flags(flags);
+}
+
+static __inline__ void atomic_set_mask(unsigned int mask, atomic_t *v)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	*(long *)v |= mask;
+	restore_flags(flags);
+}
+
+/* Atomic operations are already serializing on SH */
+#define smp_mb__before_atomic_dec()	barrier()
+#define smp_mb__after_atomic_dec()	barrier()
+#define smp_mb__before_atomic_inc()	barrier()
+#define smp_mb__after_atomic_inc()	barrier()
+
+#endif /* __ASM_SH_ATOMIC_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/bitops.h linux-2.4.22-pre3/include/asm-sh64/bitops.h
--- linux-2.4.22-pre2/include/asm-sh64/bitops.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/bitops.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,364 @@
+#ifndef __ASM_SH64_BITOPS_H
+#define __ASM_SH64_BITOPS_H
+
+#ifdef __KERNEL__
+#include <asm/system.h>
+/* For __swab32 */
+#include <asm/byteorder.h>
+
+static __inline__ void set_bit(int nr, volatile void * addr)
+{
+	int	mask;
+	volatile unsigned int *a = addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	*a |= mask;
+	restore_flags(flags);
+}
+
+static __inline__ void __set_bit(int nr, volatile void * addr)
+{
+	int	mask;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a |= mask;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+static __inline__ void clear_bit(int nr, volatile void * addr)
+{
+	int	mask;
+	volatile unsigned int *a = addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	*a &= ~mask;
+	restore_flags(flags);
+}
+
+static __inline__ void __clear_bit(int nr, volatile void * addr)
+{
+	int	mask;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a &= ~mask;
+}
+
+static __inline__ void change_bit(int nr, volatile void * addr)
+{
+	int	mask;
+	volatile unsigned int *a = addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	*a ^= mask;
+	restore_flags(flags);
+}
+
+static __inline__ void __change_bit(int nr, volatile void * addr)
+{
+	int	mask;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a ^= mask;
+}
+
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+
+	return retval;
+}
+
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+
+	return retval;
+}
+
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+
+	return retval;
+}
+
+static __inline__ int test_bit(int nr, const volatile void *addr)
+{
+	return 1UL & (((const volatile unsigned int *) addr)[nr >> 5] >> (nr & 31));
+}
+
+static __inline__ unsigned long ffz(unsigned long word)
+{
+	unsigned long result, __d2, __d3;
+
+        __asm__("gettr  " __t0 ", %2\n\t"
+                "_pta   32, " __t0 "\n\t"
+                "andi   %1, 1, %3\n\t"
+                "beq    %3, r63, " __t0 "\n\t"
+                "_pta   4, " __t0 "\n"
+                "0:\n\t"
+                "shlri.l        %1, 1, %1\n\t"
+                "addi   %0, 1, %0\n\t"
+                "andi   %1, 1, %3\n\t"
+                "beqi   %3, 1, " __t0 "\n"
+                "1:\n\t"
+                "ptabs  %2, " __t0 "\n\t"
+                : "=r" (result), "=r" (word), "=r" (__d2), "=r" (__d3)
+                : "0" (0L), "1" (word));
+
+	return result;
+}
+
+static __inline__ int find_next_zero_bit(void *addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL << size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+/*
+ * ffs: find first bit set. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+
+#define ffs(x) generic_ffs(x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+#ifdef __LITTLE_ENDIAN__
+#define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr))
+#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr))
+#define ext2_test_bit(nr, addr) test_bit((nr), (addr))
+#define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size))
+#define ext2_find_next_zero_bit(addr, size, offset) \
+                find_next_zero_bit((addr), (size), (offset))
+#else
+static __inline__ int ext2_set_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR |= mask;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int ext2_clear_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR &= ~mask;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int ext2_test_bit(int nr, const volatile void * addr)
+{
+	int			mask;
+	const volatile unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if(offset) {
+		/* We hold the little endian value in tmp, but then the
+		 * shift is illegal. So we could keep a big endian value
+		 * in tmp, like this:
+		 *
+		 * tmp = __swab32(*(p++));
+		 * tmp |= ~0UL >> (32-offset);
+		 *
+		 * but this would decrease preformance, so we change the
+		 * shift:
+		 */
+		tmp = *(p++);
+		tmp |= __swab32(~0UL >> (32-offset));
+		if(size < 32)
+			goto found_first;
+		if(~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while(size & ~31UL) {
+		if(~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if(!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	/* tmp is little endian, so we would have to swab the shift,
+	 * see above. But then we have to swab tmp below for ffz, so
+	 * we might as well do this here.
+	 */
+	return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+	return result + ffz(__swab32(tmp));
+}
+#endif
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH64_BITOPS_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/bugs.h linux-2.4.22-pre3/include/asm-sh64/bugs.h
--- linux-2.4.22-pre2/include/asm-sh64/bugs.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/bugs.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,38 @@
+#ifndef __ASM_SH64_BUGS_H
+#define __ASM_SH64_BUGS_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/bugs.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+/*
+ * I don't know of any Super-H bugs yet.
+ */
+
+#include <asm/processor.h>
+
+static void __init check_bugs(void)
+{
+	extern char *get_cpu_subtype(void);
+	extern unsigned long loops_per_jiffy;
+
+	cpu_data->loops_per_jiffy = loops_per_jiffy;
+	
+	printk("CPU: %s\n", get_cpu_subtype());
+}
+#endif /* __ASM_SH64_BUGS_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/byteorder.h linux-2.4.22-pre3/include/asm-sh64/byteorder.h
--- linux-2.4.22-pre2/include/asm-sh64/byteorder.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/byteorder.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,49 @@
+#ifndef __ASM_SH64_BYTEORDER_H
+#define __ASM_SH64_BYTEORDER_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/byteorder.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <asm/types.h>
+
+static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+{
+	__asm__("byterev	%0, %0\n\t"
+		"shari		%0, 32, %0"
+		: "=r" (x)
+		: "0" (x));
+	return x;
+}
+
+static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+{
+	__asm__("byterev	%0, %0\n\t"
+		"shari		%0, 48, %0"
+		: "=r" (x)
+		: "0" (x));
+	return x;
+}
+
+#define __arch__swab32(x) ___arch__swab32(x)
+#define __arch__swab16(x) ___arch__swab16(x)
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#include <linux/byteorder/little_endian.h>
+#else
+#include <linux/byteorder/big_endian.h>
+#endif
+
+#endif /* __ASM_SH64_BYTEORDER_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/cache.h linux-2.4.22-pre3/include/asm-sh64/cache.h
--- linux-2.4.22-pre2/include/asm-sh64/cache.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/cache.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,139 @@
+#ifndef __ASM_SH64_CACHE_H
+#define __ASM_SH64_CACHE_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/cache.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ */
+
+/* bytes per L1 cache line */
+#define L1_CACHE_BYTES		32
+#define L1_CACHE_ALIGN_MASK	(~(L1_CACHE_BYTES - 1))
+#define L1_CACHE_ALIGN(x)	(((x)+(L1_CACHE_BYTES - 1)) & L1_CACHE_ALIGN_MASK)
+#define L1_CACHE_SIZE_BYTES	(1024 * 32)
+/* Largest L1 which this arch supports */
+#define L1_CACHE_SHIFT_MAX	5
+
+#ifdef MODULE
+#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
+#else
+#define __cacheline_aligned					\
+  __attribute__((__aligned__(L1_CACHE_BYTES),			\
+		 __section__(".data.cacheline_aligned")))
+#endif
+
+/*
+ * Control Registers.
+ */
+#define ICCR_BASE	0x01600000	/* Instruction Cache Control Register */
+#define ICCR_REG0	0		/* Register 0 offset */
+#define ICCR_REG1	1		/* Register 1 offset */
+#define ICCR0		ICCR_BASE+ICCR_REG0
+#define ICCR1		ICCR_BASE+ICCR_REG1
+
+#define ICCR0_OFF	0x0		/* Set ICACHE off */
+#define ICCR0_ON	0x1		/* Set ICACHE on */
+#define ICCR0_ICI	0x2		/* Invalidate all in IC */
+
+#define ICCR1_NOLOCK	0x0		/* Set No Locking */
+
+#define OCCR_BASE	0x01E00000	/* Operand Cache Control Register */
+#define OCCR_REG0	0		/* Register 0 offset */
+#define OCCR_REG1	1		/* Register 1 offset */
+#define OCCR0		OCCR_BASE+OCCR_REG0
+#define OCCR1		OCCR_BASE+OCCR_REG1
+
+#define OCCR0_OFF	0x0		/* Set OCACHE off */
+#define OCCR0_ON	0x1		/* Set OCACHE on */
+#define OCCR0_OCI	0x2		/* Invalidate all in OC */
+#define OCCR0_WT	0x4		/* Set OCACHE in WT Mode */
+#define OCCR0_WB	0x0		/* Set OCACHE in WB Mode */
+
+#define OCCR1_NOLOCK	0x0		/* Set No Locking */
+
+
+/*
+ * SH-5
+ * A bit of description here, for neff=32.
+ *
+ *                               |<--- tag  (19 bits) --->|
+ * +-----------------------------+-----------------+------+----------+------+
+ * |                             |                 | ways |set index |offset|
+ * +-----------------------------+-----------------+------+----------+------+
+ *                                ^                 2 bits   8 bits   5 bits
+ *                                +- Bit 31
+ *
+ * Cacheline size is based on offset: 5 bits = 32 bytes per line
+ * A cache line is identified by a tag + set but OCACHETAG/ICACHETAG
+ * have a broader space for registers. These are outlined by
+ * CACHE_?C_*_STEP below.
+ *
+ */
+
+/* Valid and Dirty bits */
+#define SH_CACHE_VALID		(1LL<<0)
+#define SH_CACHE_UPDATED	(1LL<<57)
+
+/* Cache flags */
+#define SH_CACHE_MODE_WT	(1LL<<0)
+#define SH_CACHE_MODE_WB	(1LL<<1)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Cache information structure.
+ *
+ * Defined for both I and D cache, per-processor.
+ */
+struct cache_info {
+	unsigned int ways;
+	unsigned int sets;
+	unsigned int linesz;
+
+	unsigned int way_shift;
+	unsigned int entry_shift;
+	unsigned int set_shift;
+	unsigned int way_step_shift;
+	unsigned int asid_shift;
+
+	unsigned int way_ofs;
+
+	unsigned int asid_mask;
+	unsigned int idx_mask;
+	unsigned int epn_mask;
+
+	unsigned long flags;
+};
+
+#endif /* __ASSEMBLY__ */
+
+/* Instruction cache */
+#define CACHE_IC_ADDRESS_ARRAY 0x01000000
+
+/* Operand Cache */
+#define CACHE_OC_ADDRESS_ARRAY 0x01800000
+
+/* These declarations relate to cache 'synonyms' in the operand cache.  A
+   'synonym' occurs where effective address bits overlap between those used for
+   indexing the cache sets and those passed to the MMU for translation.  In the
+   case of SH5-101 & SH5-103, only bit 12 is affected for 4k pages. */
+
+#define CACHE_OC_N_SYNBITS  1               /* Number of synonym bits */
+#define CACHE_OC_SYN_SHIFT  12
+/* Mask to select synonym bit(s) */
+#define CACHE_OC_SYN_MASK   (((1UL<<CACHE_OC_N_SYNBITS)-1)<<CACHE_OC_SYN_SHIFT)
+
+
+/*
+ * Instruction cache can't be invalidated based on physical addresses.
+ * No Instruction Cache defines required, then.
+ */
+
+#endif /* __ASM_SH64_CACHE_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/cayman.h linux-2.4.22-pre3/include/asm-sh64/cayman.h
--- linux-2.4.22-pre2/include/asm-sh64/cayman.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/cayman.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,20 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/shmedia/kernel/cayman.h
+ *
+ * ST50 Cayman definitions
+ *
+ * Global defintions for the SH5 Cayman board
+ *
+ * Copyright (C) 2002 Stuart Menefy
+ */
+
+
+/* Setup for the SMSC FDC37C935 */
+#define SMSC_IRQ         IRQ_IRL1
+
+/* Setup for PCI Bus 2, which transmits interrupts via the EPLD */
+#define PCI2_IRQ         IRQ_IRL3
diff -urN linux-2.4.22-pre2/include/asm-sh64/checksum.h linux-2.4.22-pre3/include/asm-sh64/checksum.h
--- linux-2.4.22-pre2/include/asm-sh64/checksum.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/checksum.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,321 @@
+#ifndef __ASM_SH64_CHECKSUM_H
+#define __ASM_SH64_CHECKSUM_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/checksum.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <asm/registers.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+asmlinkage unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+//x
+
+/*
+ *	Note: when you get a NULL pointer exception here this means someone
+ *	passed in an incorrect kernel address to one of these functions. 
+ *	
+ *	If you use these functions directly please don't forget the 
+ *	verify_area().
+ */
+
+
+#ifdef DJM_USE_ASM_CHECKSUM
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums, and handles user-space pointer exceptions correctly, when needed.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
+						   int *src_err_ptr, int *dst_err_ptr);
+extern __inline__
+unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
+					int len, int sum)
+{
+	return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
+}
+#else
+// Pre SIM:
+//#define csum_partial_copy_nocheck csum_partial_copy
+// Post SIM:
+unsigned int
+csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum);
+#endif
+
+#ifdef DJM_USE_ASM_CHECKSUM
+
+extern __inline__
+unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
+						int len, unsigned int sum, int *err_ptr)
+{
+	return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL);
+}
+#else 
+unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
+					   int len, int sum, int *err_ptr);
+//x
+#endif
+
+
+/*
+ * These are the old (and unsafe) way of doing checksums, a warning message will be
+ * printed if they are used and an exeption occurs.
+ *
+ * these functions should go away after some time.
+ */
+
+#define csum_partial_copy_fromuser csum_partial_copy
+//x
+unsigned int csum_partial_copy( const char *src, char *dst, int len, unsigned int sum);
+//x
+
+/*
+ *	Fold a partial checksum
+ */
+
+#ifdef DJM_USE_ASM_CHECKSUM
+static __inline__ unsigned int csum_fold(unsigned int sum)
+{
+	unsigned long long __dummy;
+	__asm__("mshflo.w	r63, %0, %0\n\t"
+		"mshflo.w	%0, r63, %1\n\t"
+		"mshfhi.w	%0, r63, %0\n\t"
+		"add		%0, %1, %0\n\t"
+		"shlli		%0, 16, %1\n\t"
+		"add		%0, %1, %0\n\t"
+		"sub		r63, %0, %0\n\t"
+		"shlri		%0, 48, %0"
+		: "=r" (sum), "=&r" (__dummy)
+		: "0" (sum));
+	return sum;
+}
+#else
+
+static inline unsigned short csum_fold(unsigned int sum)
+//x
+{
+        sum = (sum & 0xffff) + (sum >> 16);
+        sum = (sum & 0xffff) + (sum >> 16);
+        return ~(sum);
+}
+#endif
+
+
+
+
+#ifdef DJM_USE_ASM_CHECKSUM
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ *
+ *      i386 version by Jorge Cwik <jorge@laser.satlink.net>, adapted
+ *      for linux by * Arnt Gulbrandsen.
+ */
+static __inline__ unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	unsigned long long sum, __dummy0, __dummy1;
+
+	__asm__ __volatile__(
+		"or	r63, r63, %0\n\t"	/* Clear upper part */
+		"or	r63, r63, %3\n\t"	/* Clear upper part */
+		"gettr	" __t0 ", %4\n\t"		/* t0 saving */
+
+		/* Less waste using .UW than removing sign extension */
+		"shlli	%2, 1, %2\n\t"		/* Longs -> Shorts */
+		"addi	%2, -2, %2\n\t"		/* Last Short to start from */
+		"ldx.uw	%1, %2, %0\n\t"		/* Get last */
+		"addi	%2, -2, %2\n\t"		/* Do it reverse */
+		"_pta	4, " __t0 "\n\t"
+
+		"ldx.uw	%1, %2, %3\n\t"
+		"add	%0, %3, %0\n\t"		/* Do the sum */
+		"shlri	%0, 16, %3\n\t"
+		"add	%0, %3, %0\n\t"		/* Fold it now */
+		"shlli	%3, 16, %3\n\t"
+		"sub	%0, %3, %0\n\t"		/* Remove carry, if any */
+		"addi	%2, -2, %2\n\t"		/* Do it reverse */
+		"bnei	%2, -2, " __t0 "\n\t"
+
+		"shlli	%0, 48, %0\n\t"		/* Not sure this is required */
+		"sub	r63, %0, %0\n\t"	/* Not */
+		"shlri	%0, 48, %0\n\t"		/* Not sure this is required */
+		"ptabs	%4, " __t0 "\n\t"
+	
+	: "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (__dummy0), "=r" (__dummy1)
+	: "1" (iph), "2" (ihl));
+
+	return (unsigned short) sum;
+}
+#else
+unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
+//x
+#endif
+
+
+#ifdef DJM_USE_ASM_CHECKSUM
+
+static __inline__ unsigned long csum_tcpudp_nofold(unsigned long saddr,
+						   unsigned long daddr,
+						   unsigned short len,
+						   unsigned short proto,
+						   unsigned int sum) 
+{
+#ifdef __LITTLE_ENDIAN__
+	unsigned long len_proto = (ntohs(len)<<16)+proto*256;
+#else
+	unsigned long len_proto = (proto<<16)+len;
+#endif
+	__asm__("add	%0, %1, %0\n\t"
+		"add	%0, %2, %0\n\t"
+		"add	%0, %3, %0\n\t"
+		"shlri	%0, 32, %1\n\t"
+		"add	%0, %1, %0\n\t"		/* Fold it to a long */
+		"shlli	%1, 32, %1\n\t"
+		"sub	%0, %1, %0\n\t"		/* Remove carry, if any */
+		: "=r" (sum), "=r" (len_proto)
+		: "r" (daddr), "r" (saddr), "1" (len_proto), "0" (sum));
+
+	return sum;
+}
+#else
+unsigned long csum_tcpudp_nofold(unsigned long saddr,
+						   unsigned long daddr,
+						   unsigned short len,
+						   unsigned short proto,
+				 unsigned int sum) ;
+//x
+#endif
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static __inline__ unsigned short int csum_tcpudp_magic(unsigned long saddr,
+						       unsigned long daddr,
+						       unsigned short len,
+						       unsigned short proto,
+						       unsigned int sum) 
+//x
+{
+  unsigned short int x;
+  //printk("csum_tcpudp_magic saddr %08x daddr %08x len %04x proto %04x sum %08x\n",
+  //	 saddr,daddr,len,proto,sum);
+  x = csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+  //printk("csum_tcpudp_magic returning %04x\n", x);
+  return x;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+static __inline__ unsigned short ip_compute_csum(unsigned char * buff, int len)
+//x
+{
+    return csum_fold (csum_partial(buff, len, 0));
+}
+
+
+#ifdef DJM_USE_ASM_CHECKSUM
+#define _HAVE_ARCH_IPV6_CSUM
+static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
+						     struct in6_addr *daddr,
+						     __u32 len,
+						     unsigned short proto,
+						     unsigned int sum) 
+{
+	unsigned int __dummy;
+
+	__asm__("ld.l	%2, 0, %1\n\t"
+		"add	%0, %1, %0\n\t"
+		"ld.l	%2, 4, %1\n\t"
+		"add	%0, %1, %0\n\t"
+		"ld.l	%2, 8, %1\n\t"
+		"add	%0, %1, %0\n\t"
+		"ld.l	%2, 12, %1\n\t"
+		"add	%0, %1, %0\n\t"
+		"ld.l	%3, 0, %1\n\t"
+		"add	%0, %1, %0\n\t"
+		"ld.l	%3, 4, %1\n\t"
+		"add	%0, %1, %0\n\t"
+		"ld.l	%3, 8, %1\n\t"
+		"add	%0, %1, %0\n\t"
+		"ld.l	%3, 12, %1\n\t"
+		"add	%0, %1, %0\n\t"
+		"add	%0, %4, %0\n\t"
+		"add	%0, %5, %0\n\t"
+		"shlri	%0, 32, %1\n\t"
+		"add	%0, %1, %0\n\t"		/* Fold it to a long */
+		"shlli	%1, 32, %1\n\t"
+		"sub	%0, %1, %0\n\t"		/* Remove carry, if any */
+		: "=r" (sum), "=&r" (__dummy)
+		: "r" (saddr), "r" (daddr), 
+		  "r" (htonl(len)), "r" (htonl(proto)), "0" (sum));
+
+	return csum_fold(sum);
+}
+#endif
+
+
+#ifdef DJM_USE_ASM_CHECKSUM
+/* 
+ *	Copy and checksum to user
+ */
+
+
+#define HAVE_CSUM_COPY_USER
+static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
+				    int len, int sum, int *err_ptr)
+{
+	if (access_ok(VERIFY_WRITE, dst, len))
+		return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
+
+	if (len)
+		*err_ptr = -EFAULT;
+
+	return -1; /* invalid checksum */
+}
+
+#endif
+
+
+#endif /* __ASM_SH64_CHECKSUM_H */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.22-pre2/include/asm-sh64/current.h linux-2.4.22-pre3/include/asm-sh64/current.h
--- linux-2.4.22-pre2/include/asm-sh64/current.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/current.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,31 @@
+#ifndef __ASM_SH64_CURRENT_H
+#define __ASM_SH64_CURRENT_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/current.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <asm/registers.h>
+
+struct task_struct;
+
+static __inline__ struct task_struct * get_current(void)
+{
+	struct task_struct *current;
+
+	/* KCR0 */
+	asm volatile ("getcon	" __c17 ", %0" : "=r" (current));
+
+	return current;
+}
+
+#define current get_current()
+
+#endif /* __ASM_SH64_CURRENT_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/delay.h linux-2.4.22-pre3/include/asm-sh64/delay.h
--- linux-2.4.22-pre2/include/asm-sh64/delay.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/delay.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,11 @@
+#ifndef __ASM_SH64_DELAY_H
+#define __ASM_SH64_DELAY_H
+
+extern void __delay(int loops);
+extern void __udelay(unsigned long long usecs, unsigned long lpj);
+extern void __ndelay(unsigned long long nsecs, unsigned long lpj);
+extern void udelay(unsigned long usecs);
+extern void ndelay(unsigned long nsecs);
+
+#endif /* __ASM_SH64_DELAY_H */
+
diff -urN linux-2.4.22-pre2/include/asm-sh64/div64.h linux-2.4.22-pre3/include/asm-sh64/div64.h
--- linux-2.4.22-pre2/include/asm-sh64/div64.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/div64.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,21 @@
+#ifndef __ASM_SH64_DIV64_H
+#define __ASM_SH64_DIV64_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/div64.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#define do_div(n,base) ({ \
+int __res; \
+__res = ((unsigned long) n) % (unsigned) base; \
+n = ((unsigned long) n) / (unsigned) base; \
+__res; })
+
+#endif /* __ASM_SH64_DIV64_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/dma.h linux-2.4.22-pre3/include/asm-sh64/dma.h
--- linux-2.4.22-pre2/include/asm-sh64/dma.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/dma.h	2003-07-05 18:11:40.000000000 -0700
@@ -0,0 +1,41 @@
+#ifndef __ASM_SH64_DMA_H
+#define __ASM_SH64_DMA_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/dma.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ */
+
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+
+#define MAX_DMA_CHANNELS	4
+
+/*
+ * SH5 can DMA in any memory area.
+ *
+ * The static definition is dodgy because it should limit
+ * the highest DMA-able address based on the actual
+ * Physical memory available. This is actually performed
+ * at run time in defining the memory allowed to DMA_ZONE.
+ */
+#define MAX_DMA_ADDRESS		~(NPHYS_MASK)
+
+#define DMA_MODE_READ		0
+#define DMA_MODE_WRITE		1
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy 	(0)
+#endif
+
+#endif /* __ASM_SH64_DMA_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/elf.h linux-2.4.22-pre3/include/asm-sh64/elf.h
--- linux-2.4.22-pre2/include/asm-sh64/elf.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/elf.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,101 @@
+#ifndef __ASM_SH64_ELF_H
+#define __ASM_SH64_ELF_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/elf.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+#include <asm/byteorder.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_fpu_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ( (x)->e_machine == EM_SH )
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#ifdef __LITTLE_ENDIAN__
+#define ELF_DATA	ELFDATA2LSB
+#else
+#define ELF_DATA	ELFDATA2MSB
+#endif
+#define ELF_ARCH	EM_SH
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
+
+
+#define ELF_CORE_COPY_REGS(_dest,_regs)				\
+	memcpy((char *) &_dest, (char *) _regs,			\
+	       sizeof(struct pt_regs));
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this CPU supports.  This could be done in user space,
+   but it's not easy, and we've already done it here.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.
+
+   For the moment, we have only optimizations for the Intel generations,
+   but that could change... */
+
+#define ELF_PLATFORM  (NULL)
+
+#define ELF_PLAT_INIT(_r) \
+  do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \
+       _r->regs[4]=0; _r->regs[5]=0; _r->regs[6]=0; _r->regs[7]=0; \
+       _r->regs[8]=0; _r->regs[9]=0; _r->regs[10]=0; _r->regs[11]=0; \
+       _r->regs[12]=0; _r->regs[13]=0; _r->regs[14]=0; _r->regs[15]=0; \
+       _r->regs[16]=0; _r->regs[17]=0; _r->regs[18]=0; _r->regs[19]=0; \
+       _r->regs[20]=0; _r->regs[21]=0; _r->regs[22]=0; _r->regs[23]=0; \
+       _r->regs[24]=0; _r->regs[25]=0; _r->regs[26]=0; _r->regs[27]=0; \
+       _r->regs[28]=0; _r->regs[29]=0; _r->regs[30]=0; _r->regs[31]=0; \
+       _r->regs[32]=0; _r->regs[33]=0; _r->regs[34]=0; _r->regs[35]=0; \
+       _r->regs[36]=0; _r->regs[37]=0; _r->regs[38]=0; _r->regs[39]=0; \
+       _r->regs[40]=0; _r->regs[41]=0; _r->regs[42]=0; _r->regs[43]=0; \
+       _r->regs[44]=0; _r->regs[45]=0; _r->regs[46]=0; _r->regs[47]=0; \
+       _r->regs[48]=0; _r->regs[49]=0; _r->regs[50]=0; _r->regs[51]=0; \
+       _r->regs[52]=0; _r->regs[53]=0; _r->regs[54]=0; _r->regs[55]=0; \
+       _r->regs[56]=0; _r->regs[57]=0; _r->regs[58]=0; _r->regs[59]=0; \
+       _r->regs[60]=0; _r->regs[61]=0; _r->regs[62]=0; \
+       _r->tregs[0]=0; _r->tregs[1]=0; _r->tregs[2]=0; _r->tregs[3]=0; \
+       _r->tregs[4]=0; _r->tregs[5]=0; _r->tregs[6]=0; _r->tregs[7]=0; \
+       _r->sr = SR_FD | SR_MMU; } while (0)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+#endif
+
+#endif /* __ASM_SH64_ELF_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/errno.h linux-2.4.22-pre3/include/asm-sh64/errno.h
--- linux-2.4.22-pre2/include/asm-sh64/errno.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/errno.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,143 @@
+#ifndef __ASM_SH64_ERRNO_H
+#define __ASM_SH64_ERRNO_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/errno.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+#endif /* __ASM_SH64_ERRNO_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/fcntl.h linux-2.4.22-pre3/include/asm-sh64/fcntl.h
--- linux-2.4.22-pre2/include/asm-sh64/fcntl.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/fcntl.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,87 @@
+#ifndef __ASM_SH_FCNTL_H
+#define __ASM_SH_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	   0003
+#define O_RDONLY	     00
+#define O_WRONLY	     01
+#define O_RDWR		     02
+#define O_CREAT		   0100	/* not fcntl */
+#define O_EXCL		   0200	/* not fcntl */
+#define O_NOCTTY	   0400	/* not fcntl */
+#define O_TRUNC		  01000	/* not fcntl */
+#define O_APPEND	  02000
+#define O_NONBLOCK	  04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		 010000
+#define FASYNC		 020000	/* fcntl, for BSD compatibility */
+#define O_DIRECT	 040000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0100000
+#define O_DIRECTORY	0200000	/* must be a directory */
+#define O_NOFOLLOW	0400000 /* don't follow links */
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock */
+#define LOCK_READ	64	/* ... Which allows concurrent read operations */
+#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
+#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif /* __ASM_SH_FCNTL_H */
+
diff -urN linux-2.4.22-pre2/include/asm-sh64/hardirq.h linux-2.4.22-pre3/include/asm-sh64/hardirq.h
--- linux-2.4.22-pre2/include/asm-sh64/hardirq.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/hardirq.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,42 @@
+#ifndef __ASM_SH_HARDIRQ_H
+#define __ASM_SH_HARDIRQ_H
+
+#include <linux/config.h>
+#include <linux/threads.h>
+
+/* entry.S is sensitive to the offsets of these fields */
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __local_irq_count;
+	unsigned int __local_bh_count;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() ({ int __cpu = smp_processor_id(); \
+	(local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
+
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
+
+#define synchronize_irq()	barrier()
+
+#else
+
+#error Super-H SMP is not available
+
+#endif /* CONFIG_SMP */
+#endif /* __ASM_SH_HARDIRQ_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/hardware.h linux-2.4.22-pre3/include/asm-sh64/hardware.h
--- linux-2.4.22-pre2/include/asm-sh64/hardware.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/hardware.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,45 @@
+#ifndef __ASM_SH64_HARDWARE_H
+#define __ASM_SH64_HARDWARE_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/hardware.h
+ *
+ * Copyright (C) 2002 Stuart Menefy
+ * Copyright (C) 2003 Paul Mundt
+ *
+ * Defitions of the locations of registers in the physical address space.
+ */
+
+#define	PHYS_PERIPHERAL_BLOCK	0x09000000
+#define PHYS_DMAC_BLOCK		0x0e000000
+#define PHYS_PCI_BLOCK		0x60000000
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#include <asm/io.h>
+
+struct vcr_info {
+	u8	perr_flags;	/* P-port Error flags */
+	u8	merr_flags;	/* Module Error flags */
+	u16	mod_vers;	/* Module Version */
+	u16	mod_id;		/* Module ID */
+	u8	bot_mb;		/* Bottom Memory block */
+	u8	top_mb;		/* Top Memory block */
+};
+
+static inline struct vcr_info sh64_get_vcr_info(unsigned long base)
+{
+	unsigned long long tmp;
+
+	tmp = sh64_in64(base);
+
+	return *((struct vcr_info *)&tmp);
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_SH64_HARDWARE_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/hw_irq.h linux-2.4.22-pre3/include/asm-sh64/hw_irq.h
--- linux-2.4.22-pre2/include/asm-sh64/hw_irq.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/hw_irq.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,16 @@
+#ifndef __ASM_SH64_HW_IRQ_H
+#define __ASM_SH64_HW_IRQ_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/hw_irq.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+static __inline__ void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { /* Nothing to do */ }
+
+#endif /* __ASM_SH64_HW_IRQ_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/init.h linux-2.4.22-pre3/include/asm-sh64/init.h
--- linux-2.4.22-pre2/include/asm-sh64/init.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/init.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,17 @@
+#ifndef __ASM_SH64_INIT_H
+#define __ASM_SH64_INIT_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/init.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#error "<asm/init.h> should never be used - use <linux/init.h> instead"
+
+#endif /* __ASM_SH64_INIT_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/io.h linux-2.4.22-pre3/include/asm-sh64/io.h
--- linux-2.4.22-pre2/include/asm-sh64/io.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/io.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,217 @@
+#ifndef __ASM_SH64_IO_H
+#define __ASM_SH64_IO_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/io.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ */
+
+/*
+ * Convention:
+ *    read{b,w,l}/write{b,w,l} are for PCI,
+ *    while in{b,w,l}/out{b,w,l} are for ISA
+ * These may (will) be platform specific function.
+ *
+ * In addition, we have 
+ *   ctrl_in{b,w,l}/ctrl_out{b,w,l} for SuperH specific I/O.
+ * which are processor specific. Address should be the result of
+ * onchip_remap();
+ */
+
+#include <asm/cache.h>
+#include <asm/system.h>
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+#define page_to_bus page_to_phys
+
+/*
+ * Nothing overly special here.. instead of doing the same thing
+ * over and over again, we just define a set of sh64_in/out functions
+ * with an implicit size. The traditional read{b,w,l}/write{b,w,l}
+ * mess is wrapped to this, as are the SH-specific ctrl_in/out routines.
+ */
+static inline unsigned char sh64_in8(unsigned long addr)
+{
+	return *(volatile unsigned char *)addr;
+}
+
+static inline unsigned short sh64_in16(unsigned long addr)
+{
+	return *(volatile unsigned short *)addr;
+}
+
+static inline unsigned long sh64_in32(unsigned long addr)
+{
+	return *(volatile unsigned long *)addr;
+}
+
+static inline unsigned long long sh64_in64(unsigned long addr)
+{
+	return *(volatile unsigned long long *)addr;
+}
+
+static inline void sh64_out8(unsigned char b, unsigned long addr)
+{
+	*(volatile unsigned char *)addr = b;
+	wmb();
+}
+
+static inline void sh64_out16(unsigned short b, unsigned long addr)
+{
+	*(volatile unsigned short *)addr = b;
+	wmb();
+}
+
+static inline void sh64_out32(unsigned long b, unsigned long addr)
+{
+	*(volatile unsigned long *)addr = b;
+	wmb();
+}
+
+static inline void sh64_out64(unsigned long long b, unsigned long addr)
+{
+	*(volatile unsigned long long *)addr = b;
+	wmb();
+}
+
+#define readb(addr)		sh64_in8(addr)
+#define readw(addr)		sh64_in16(addr)
+#define readl(addr)		sh64_in32(addr)
+
+#define writeb(b, addr)		sh64_out8(b, addr)
+#define writew(b, addr)		sh64_out16(b, addr)
+#define writel(b, addr)		sh64_out32(b, addr)
+
+#define ctrl_inb(addr)		sh64_in8(addr)
+#define ctrl_inw(addr)		sh64_in16(addr)
+#define ctrl_inl(addr)		sh64_in32(addr)
+
+#define ctrl_outb(b, addr)	sh64_out8(b, addr)
+#define ctrl_outw(b, addr)	sh64_out16(b, addr)
+#define ctrl_outl(b, addr)	sh64_out32(b, addr)
+
+unsigned long inb(unsigned long port);
+unsigned long inw(unsigned long port);
+unsigned long inl(unsigned long port);
+void outb(unsigned long value, unsigned long port);
+void outw(unsigned long value, unsigned long port);
+void outl(unsigned long value, unsigned long port);
+
+#ifdef __KERNEL__
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * Change virtual addresses to physical addresses and vv.
+ * These are trivial on the 1:1 Linux/SuperH mapping
+ */
+extern __inline__ unsigned long virt_to_phys(volatile void * address)
+{
+	return __pa(address);
+}
+
+extern __inline__ void * phys_to_virt(unsigned long address)
+{
+	return __va(address);
+}
+
+extern void * __ioremap(unsigned long phys_addr, unsigned long size,
+			unsigned long flags);
+
+extern __inline__ void * ioremap(unsigned long phys_addr, unsigned long size)
+{
+	return __ioremap(phys_addr, size, 1);
+}
+	
+extern __inline__ void * ioremap_nocache (unsigned long phys_addr, unsigned long size)
+{
+	return __ioremap(phys_addr, size, 0);
+}
+
+extern void iounmap(void *addr);
+
+unsigned long onchip_remap(unsigned long addr, unsigned long size, const char* name);
+extern void onchip_unmap(unsigned long vaddr);
+
+static __inline__ int check_signature(unsigned long io_addr,
+			const unsigned char *signature, int length)
+{
+	int retval = 0;
+	do {
+		if (readb(io_addr) != *signature)
+			goto out;
+		io_addr++;
+		signature++;
+		length--;
+	} while (length);
+	retval = 1;
+out:
+	return retval;
+}
+
+/*
+ * The caches on some architectures aren't dma-coherent and have need to
+ * handle this in software.  There are three types of operations that
+ * can be applied to dma buffers.
+ *
+ *  - dma_cache_wback_inv(start, size) makes caches and RAM coherent by
+ *    writing the content of the caches back to memory, if necessary.
+ *    The function also invalidates the affected part of the caches as
+ *    necessary before DMA transfers from outside to memory.
+ *  - dma_cache_inv(start, size) invalidates the affected parts of the
+ *    caches.  Dirty lines of the caches may be written back or simply
+ *    be discarded.  This operation is necessary before dma operations
+ *    to the memory.
+ *  - dma_cache_wback(start, size) writes back any dirty lines but does
+ *    not invalidate the cache.  This can be used before DMA reads from
+ *    memory,
+ */
+
+/*
+ * Implemented despite DMA is not yet supported on ST50.
+ *
+ * Also note that PCI DMA is supposed to be cache coherent,
+ * therefore these should not be used by PCI device drivers.
+ *
+ */
+
+static __inline__ void dma_cache_wback_inv (unsigned long start, unsigned long size)
+{
+	unsigned long s = start & L1_CACHE_ALIGN_MASK;
+	unsigned long e = (start + size) & L1_CACHE_ALIGN_MASK;
+
+	for (; s <= e; s += L1_CACHE_BYTES)
+		asm volatile ("ocbp	%0, 0" : : "r" (s));
+}
+
+static __inline__ void dma_cache_inv (unsigned long start, unsigned long size)
+{
+	// Note that caller has to be careful with overzealous
+	// invalidation should there be partial cache lines at the extremities 
+	// of the specified range 
+	unsigned long s = start & L1_CACHE_ALIGN_MASK;
+	unsigned long e = (start + size) & L1_CACHE_ALIGN_MASK;
+
+	for (; s <= e; s += L1_CACHE_BYTES)
+		asm volatile ("ocbi	%0, 0" : : "r" (s));
+}
+
+static __inline__ void dma_cache_wback (unsigned long start, unsigned long size)
+{
+	unsigned long s = start & L1_CACHE_ALIGN_MASK;
+	unsigned long e = (start + size) & L1_CACHE_ALIGN_MASK;
+
+	for (; s <= e; s += L1_CACHE_BYTES)
+		asm volatile ("ocbwb	%0, 0" : : "r" (s));
+}
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_SH64_IO_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/ioctl.h linux-2.4.22-pre3/include/asm-sh64/ioctl.h
--- linux-2.4.22-pre2/include/asm-sh64/ioctl.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/ioctl.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,83 @@
+#ifndef __ASM_SH64_IOCTL_H
+#define __ASM_SH64_IOCTL_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/ioctl.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ *
+ */
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* __ASM_SH64_IOCTL_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/ioctls.h linux-2.4.22-pre3/include/asm-sh64/ioctls.h
--- linux-2.4.22-pre2/include/asm-sh64/ioctls.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/ioctls.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,110 @@
+#ifndef __ASM_SH64_IOCTLS_H
+#define __ASM_SH64_IOCTLS_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/ioctls.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <asm/ioctl.h>
+
+#define FIOCLEX		_IO('f', 1)
+#define FIONCLEX	_IO('f', 2)
+#define FIOASYNC	_IOW('f', 125, int)
+#define FIONBIO		_IOW('f', 126, int)
+#define FIONREAD	_IOR('f', 127, int)
+#define TIOCINQ		FIONREAD
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+
+#define TCGETA		_IOR('t', 23, struct termio)
+#define TCSETA		_IOW('t', 24, struct termio)
+#define TCSETAW		_IOW('t', 25, struct termio)
+#define TCSETAF		_IOW('t', 28, struct termio)
+
+#define TCSBRK		_IO('t', 29)
+#define TCXONC		_IO('t', 30)
+#define TCFLSH		_IO('t', 31)
+
+#define TIOCSWINSZ	_IOW('t', 103, struct winsize)
+#define TIOCGWINSZ	_IOR('t', 104, struct winsize)
+#define	TIOCSTART	_IO('t', 110)		/* start output, like ^Q */
+#define	TIOCSTOP	_IO('t', 111)		/* stop output, like ^S */
+#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
+
+#define TIOCSPGRP	_IOW('t', 118, int)
+#define TIOCGPGRP	_IOR('t', 119, int)
+
+#define TIOCEXCL	_IO('T', 12) /* 0x540C */
+#define TIOCNXCL	_IO('T', 13) /* 0x540D */
+#define TIOCSCTTY	_IO('T', 14) /* 0x540E */
+
+#define TIOCSTI		_IOW('T', 18, char) /* 0x5412 */
+#define TIOCMGET	_IOR('T', 21, unsigned int) /* 0x5415 */
+#define TIOCMBIS	_IOW('T', 22, unsigned int) /* 0x5416 */
+#define TIOCMBIC	_IOW('T', 23, unsigned int) /* 0x5417 */
+#define TIOCMSET	_IOW('T', 24, unsigned int) /* 0x5418 */
+# define TIOCM_LE	0x001
+# define TIOCM_DTR	0x002
+# define TIOCM_RTS	0x004
+# define TIOCM_ST	0x008
+# define TIOCM_SR	0x010
+# define TIOCM_CTS	0x020
+# define TIOCM_CAR	0x040
+# define TIOCM_RNG	0x080
+# define TIOCM_DSR	0x100
+# define TIOCM_CD	TIOCM_CAR
+# define TIOCM_RI	TIOCM_RNG
+
+#define TIOCGSOFTCAR	_IOR('T', 25, unsigned int) /* 0x5419 */
+#define TIOCSSOFTCAR	_IOW('T', 26, unsigned int) /* 0x541A */
+#define TIOCLINUX	_IOW('T', 28, char) /* 0x541C */
+#define TIOCCONS	_IO('T', 29) /* 0x541D */
+#define TIOCGSERIAL	_IOR('T', 30, struct serial_struct) /* 0x541E */
+#define TIOCSSERIAL	_IOW('T', 31, struct serial_struct) /* 0x541F */
+#define TIOCPKT		_IOW('T', 32, int) /* 0x5420 */
+# define TIOCPKT_DATA		 0
+# define TIOCPKT_FLUSHREAD	 1
+# define TIOCPKT_FLUSHWRITE	 2
+# define TIOCPKT_STOP		 4
+# define TIOCPKT_START		 8
+# define TIOCPKT_NOSTOP		16
+# define TIOCPKT_DOSTOP		32
+
+
+#define TIOCNOTTY	_IO('T', 34) /* 0x5422 */
+#define TIOCSETD	_IOW('T', 35, int) /* 0x5423 */
+#define TIOCGETD	_IOR('T', 36, int) /* 0x5424 */
+#define TCSBRKP		_IOW('T', 37, int) /* 0x5425 */	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	_IOR('T', 38, struct tty_struct) /* 0x5426 */ /* For debugging only */
+#define TIOCSBRK	_IO('T', 39) /* 0x5427 */ /* BSD compatibility */
+#define TIOCCBRK	_IO('T', 40) /* 0x5428 */ /* BSD compatibility */
+#define TIOCGSID	_IOR('T', 41, pid_t) /* 0x5429 */ /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define TIOCSERCONFIG	_IO('T', 83) /* 0x5453 */
+#define TIOCSERGWILD	_IOR('T', 84,  int) /* 0x5454 */
+#define TIOCSERSWILD	_IOW('T', 85,  int) /* 0x5455 */
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	_IOR('T', 88, struct async_struct) /* 0x5458 */ /* For debugging only */
+#define TIOCSERGETLSR   _IOR('T', 89, unsigned int) /* 0x5459 */ /* Get line status register */
+  /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+# define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+#define TIOCSERGETMULTI _IOR('T', 90, struct serial_multiport_struct) /* 0x545A */ /* Get multiport config  */
+#define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* 0x545B */ /* Set multiport config */
+
+#define TIOCMIWAIT	_IO('T', 92) /* 0x545C */	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	_IOR('T', 93, struct async_icount) /* 0x545D */	/* read serial port inline interrupt counts */
+
+#endif /* __ASM_SH64_IOCTLS_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/ipc.h linux-2.4.22-pre3/include/asm-sh64/ipc.h
--- linux-2.4.22-pre2/include/asm-sh64/ipc.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/ipc.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,42 @@
+#ifndef __ASM_SH64_IPC_H
+#define __ASM_SH64_IPC_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/ipc.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/* 
+ * These are used to wrap system calls on x86.
+ *
+ * See arch/i386/kernel/sys_i386.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC            25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif /* __ASM_SH64_IPC_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/ipcbuf.h linux-2.4.22-pre3/include/asm-sh64/ipcbuf.h
--- linux-2.4.22-pre2/include/asm-sh64/ipcbuf.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/ipcbuf.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,40 @@
+#ifndef __ASM_SH64_IPCBUF_H__
+#define __ASM_SH64_IPCBUF_H__
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/ipcbuf.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/*
+ * The ipc64_perm structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __ASM_SH64_IPCBUF_H__ */
diff -urN linux-2.4.22-pre2/include/asm-sh64/irq.h linux-2.4.22-pre3/include/asm-sh64/irq.h
--- linux-2.4.22-pre2/include/asm-sh64/irq.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/irq.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,142 @@
+#ifndef __ASM_SH64_IRQ_H
+#define __ASM_SH64_IRQ_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/irq.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <linux/config.h>
+
+/*
+ * Encoded IRQs are not considered worth to be supported.
+ * Main reason is that there's no per-encoded-interrupt
+ * enable/disable mechanism (as there was in SH3/4).
+ * An all enabled/all disabled is worth only if there's
+ * a cascaded IC to disable/enable/ack on. Until such
+ * IC is available there's no such support.
+ *
+ * Presumably Encoded IRQs may use extra IRQs beyond 64,
+ * below. Some logic must be added to cope with IRQ_IRL?
+ * in an exclusive way.
+ *
+ * Priorities are set at Platform level, when IRQ_IRL0-3
+ * are set to 0 Encoding is allowed. Otherwise it's not
+ * allowed.
+ */
+
+/* Independent IRQs */
+#define IRQ_IRL0	0
+#define IRQ_IRL1	1
+#define IRQ_IRL2	2
+#define IRQ_IRL3	3
+
+#define IRQ_INTA	4
+#define IRQ_INTB	5
+#define IRQ_INTC	6
+#define IRQ_INTD	7
+
+#define IRQ_SERR	12
+#define IRQ_ERR		13
+#define IRQ_PWR3	14
+#define IRQ_PWR2	15
+#define IRQ_PWR1	16
+#define IRQ_PWR0	17
+
+#define IRQ_DMTE0	18
+#define IRQ_DMTE1	19
+#define IRQ_DMTE2	20
+#define IRQ_DMTE3	21
+#define IRQ_DAERR	22
+
+#define IRQ_TUNI0	32
+#define IRQ_TUNI1	33
+#define IRQ_TUNI2	34
+#define IRQ_TICPI2	35
+
+#define IRQ_ATI		36
+#define IRQ_PRI		37
+#define IRQ_CUI		38
+
+#define IRQ_ERI		39
+#define IRQ_RXI		40
+#define IRQ_BRI		41
+#define IRQ_TXI		42
+
+#define IRQ_ITI		63
+
+#define NR_INTC_IRQS	64
+
+#ifdef CONFIG_SH_CAYMAN
+#define NR_EXT_IRQS     32
+#define START_EXT_IRQS  64
+
+/* PCI bus 2 uses encoded external interrupts on the Cayman board */
+#define IRQ_P2INTA      (START_EXT_IRQS + (3*8) + 0)
+#define IRQ_P2INTB      (START_EXT_IRQS + (3*8) + 1)
+#define IRQ_P2INTC      (START_EXT_IRQS + (3*8) + 2)
+#define IRQ_P2INTD      (START_EXT_IRQS + (3*8) + 3)
+
+#define START_EXT_IRQS  64
+#else
+#define NR_EXT_IRQS	0
+#endif
+
+#define NR_IRQS		(NR_INTC_IRQS+NR_EXT_IRQS)
+
+
+/* Default IRQs, fixed */
+#define TIMER_IRQ	IRQ_TUNI0
+#define RTC_IRQ		IRQ_CUI
+
+/* Default Priorities, Platform may choose differently */
+#define	NO_PRIORITY	0	/* Disabled */
+#define TIMER_PRIORITY	2
+#define RTC_PRIORITY	TIMER_PRIORITY
+#define SCIF_PRIORITY	3
+#define INTD_PRIORITY	3
+#define	IRL3_PRIORITY	4
+#define INTC_PRIORITY	6
+#define	IRL2_PRIORITY	7
+#define INTB_PRIORITY	9
+#define	IRL1_PRIORITY	10
+#define INTA_PRIORITY	12
+#define	IRL0_PRIORITY	13
+#define TOP_PRIORITY	15
+
+extern void disable_irq(unsigned int);
+extern void disable_irq_nosync(unsigned int);
+extern void enable_irq(unsigned int);
+
+extern int intc_evt_to_irq[(0xE20/0x20)+1];
+int intc_irq_describe(char* p, int irq);
+
+#ifdef CONFIG_SH_CAYMAN
+int cayman_irq_demux(int evt);
+int cayman_irq_describe(char* p, int irq);
+#define irq_demux(x) cayman_irq_demux(x)
+#define irq_describe(p, x) cayman_irq_describe(p, x)
+#else
+#define irq_demux(x) (intc_evt_to_irq[x])
+#define irq_describe(p, x) intc_irq_describe(p, x)
+#endif
+
+/*
+ * Function for "on chip support modules".
+ */
+
+/*
+ * SH-5 supports Priority based interrupts only.
+ * Interrupt priorities are defined at platform level.
+ */
+#define set_ipr_data(a, b, c, d)
+#define make_ipr_irq(a)
+#define make_imask_irq(a)
+
+#endif /* __ASM_SH64_IRQ_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/keyboard.h linux-2.4.22-pre3/include/asm-sh64/keyboard.h
--- linux-2.4.22-pre2/include/asm-sh64/keyboard.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/keyboard.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,74 @@
+/*
+ *  linux/include/asm-shmedia/keyboard.h
+ *
+ * Copied from i386 version:
+ *    Created 3 Nov 1996 by Geert Uytterhoeven
+ */
+
+/*
+ *  This file contains the i386 architecture specific keyboard definitions
+ */
+
+#ifndef __ASM_SH64_KEYBOARD_H
+#define __ASM_SH64_KEYBOARD_H
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SH_CAYMAN
+#define KEYBOARD_IRQ			(START_EXT_IRQS + 2) /* SMSC IRQ 1 */
+#endif
+#define DISABLE_KBD_DURING_INTERRUPTS	0
+
+extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int pckbd_getkeycode(unsigned int scancode);
+extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+			   char raw_mode);
+extern char pckbd_unexpected_up(unsigned char keycode);
+extern void pckbd_leds(unsigned char leds);
+extern void pckbd_init_hw(void);
+extern unsigned char pckbd_sysrq_xlate[128];
+
+#define kbd_setkeycode		pckbd_setkeycode
+#define kbd_getkeycode		pckbd_getkeycode
+#define kbd_translate		pckbd_translate
+#define kbd_unexpected_up	pckbd_unexpected_up
+#define kbd_leds		pckbd_leds
+#define kbd_init_hw		pckbd_init_hw
+#define kbd_sysrq_xlate		pckbd_sysrq_xlate
+
+#define SYSRQ_KEY 0x54
+
+/* resource allocation */
+#define kbd_request_region()
+#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \
+                                             "keyboard", NULL)
+
+/* How to access the keyboard macros on this platform.  */
+#define kbd_read_input() inb(KBD_DATA_REG)
+#define kbd_read_status() inb(KBD_STATUS_REG)
+#define kbd_write_output(val) outb(val, KBD_DATA_REG)
+#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
+
+/* Some stoneage hardware needs delays after some operations.  */
+#define kbd_pause() do { } while(0)
+
+/*
+ * Machine specific bits for the PS/2 driver
+ */
+
+#ifdef CONFIG_SH_CAYMAN
+#define AUX_IRQ (START_EXT_IRQS + 6) /* SMSC IRQ12 */
+#endif
+
+#define aux_request_irq(hand, dev_id)					\
+	request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id)
+
+#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_SH64_KEYBOARD_H */
+
diff -urN linux-2.4.22-pre2/include/asm-sh64/linux_logo.h linux-2.4.22-pre3/include/asm-sh64/linux_logo.h
--- linux-2.4.22-pre2/include/asm-sh64/linux_logo.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/linux_logo.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,47 @@
+/*
+ * include/asm-shmedia/linux_logo.h
+ *
+ * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ *
+ * You can put anything here, but:
+ * LINUX_LOGO_COLORS has to be less than 224
+ * image size has to be 80x80
+ * values have to start from 0x20
+ * (i.e. RGB(linux_logo_red[0],
+ *	     linux_logo_green[0],
+ *	     linux_logo_blue[0]) is color 0x20)
+ * BW image has to be 80x80 as well, with MS bit
+ * on the left
+ * Serial_console ascii image can be any size,
+ * but should contain %s to display the version
+ */
+ 
+#include <linux/init.h>
+#include <linux/version.h>
+
+#define linux_logo_banner "Linux/SHmedia version " UTS_RELEASE
+
+#define LINUX_LOGO_COLORS 214
+
+#ifdef INCLUDE_LINUX_LOGO_DATA
+
+#define INCLUDE_LINUX_LOGOBW
+#define INCLUDE_LINUX_LOGO16
+
+#include <linux/linux_logo.h>
+
+#else
+
+/* prototypes only */
+extern unsigned char linux_logo_red[];
+extern unsigned char linux_logo_green[];
+extern unsigned char linux_logo_blue[];
+extern unsigned char linux_logo[];
+extern unsigned char linux_logo_bw[];
+extern unsigned char linux_logo16_red[];
+extern unsigned char linux_logo16_green[];
+extern unsigned char linux_logo16_blue[];
+extern unsigned char linux_logo16[];
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-sh64/mman.h linux-2.4.22-pre3/include/asm-sh64/mman.h
--- linux-2.4.22-pre2/include/asm-sh64/mman.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/mman.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,49 @@
+#ifndef __ASM_SH64_MMAN_H
+#define __ASM_SH64_MMAN_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/mman.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __ASM_SH64_MMAN_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/mmu.h linux-2.4.22-pre3/include/asm-sh64/mmu.h
--- linux-2.4.22-pre2/include/asm-sh64/mmu.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/mmu.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,7 @@
+#ifndef __MMU_H
+#define __MMU_H
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-sh64/mmu_context.h linux-2.4.22-pre3/include/asm-sh64/mmu_context.h
--- linux-2.4.22-pre2/include/asm-sh64/mmu_context.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/mmu_context.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,209 @@
+#ifndef __ASM_SH64_MMU_CONTEXT_H
+#define __ASM_SH64_MMU_CONTEXT_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/mmu_context.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Richard Curnow
+ *
+ * ASID handling idea taken from MIPS implementation.
+ *
+ */
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Cache of MMU context last used.
+ *
+ * The MMU "context" consists of two things:
+ *   (a) TLB cache version (or cycle, top 24 bits of mmu_context_cache)
+ *   (b) ASID (Address Space IDentifier, bottom 8 bits of mmu_context_cache)
+ */
+extern unsigned long mmu_context_cache;
+
+#include <linux/config.h>
+#include <asm/page.h>
+
+
+/* Current mm's pgd */
+extern pgd_t *mmu_pdtp_cache;
+
+#define SR_ASID_MASK		0xffffffffff00ffff
+#define SR_ASID_SHIFT		16
+
+#define MMU_CONTEXT_ASID_MASK		0x000000ff
+#define MMU_CONTEXT_VERSION_MASK	0xffffff00
+#define MMU_CONTEXT_FIRST_VERSION	0x00000100
+#define NO_CONTEXT			0
+
+/* ASID is 8-bit value, so it can't be 0x100 */
+#define MMU_NO_ASID			0x100
+
+
+/*
+ * Virtual Page Number mask
+ */
+#define MMU_VPN_MASK	0xfffff000
+
+extern __inline__ void
+get_new_mmu_context(struct mm_struct *mm)
+{
+	extern void flush_tlb_all(void);
+	extern void flush_cache_all(void);
+
+	unsigned long mc = ++mmu_context_cache;
+
+	if (!(mc & MMU_CONTEXT_ASID_MASK)) {
+		/* We exhaust ASID of this version.
+		   Flush all TLB and start new cycle. */
+		flush_tlb_all();
+		/* We have to flush all caches as ASIDs are
+                   used in cache */
+		flush_cache_all();
+		/* Fix version if needed.
+		   Note that we avoid version #0/asid #0 to distingush NO_CONTEXT. */
+		if (!mc)
+			mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION;
+	}
+	mm->context = mc;
+}
+
+/*
+ * Get MMU context if needed.
+ */
+static __inline__ void
+get_mmu_context(struct mm_struct *mm)
+{
+	if (mm) {
+		unsigned long mc = mmu_context_cache;
+		/* Check if we have old version of context.
+		   If it's old, we need to get new context with new version. */
+		if ((mm->context ^ mc) & MMU_CONTEXT_VERSION_MASK)
+			get_new_mmu_context(mm);
+	}
+}
+
+/*
+ * Initialize the context related info for a new mm_struct
+ * instance.
+ */
+static __inline__ int init_new_context(struct task_struct *tsk,
+					struct mm_struct *mm)
+{
+	mm->context = NO_CONTEXT;
+	return 0;
+}
+
+/*
+ * Destroy context related info for an mm_struct that is about
+ * to be put to rest.
+ */
+static __inline__ void destroy_context(struct mm_struct *mm)
+{
+	extern void flush_tlb_mm(struct mm_struct *mm);
+
+	/* Well, at least free TLB entries */
+	flush_tlb_mm(mm);
+}
+
+#endif	/* __ASSEMBLY__ */
+
+/* Common defines */
+#define TLB_STEP	0x00000010
+#define TLB_PTEH	0x00000000
+#define TLB_PTEL	0x00000008
+
+/* PTEH defines */
+#define PTEH_ASID_SHIFT	2
+#define PTEH_VALID	0x0000000000000001
+#define PTEH_SHARED	0x0000000000000002
+#define PTEH_MATCH_ASID	0x00000000000003ff
+
+#ifndef __ASSEMBLY__
+/* This has to be a common function because the next location to fill
+ * information is shared. */
+extern void __do_tlb_refill(unsigned long address, unsigned long long is_text_not_data, pte_t *pte);
+
+/* Profiling counter. */
+#if (CONFIG_SH64_PROC_TLB)
+extern unsigned long long calls_to_do_fast_page_fault;
+#endif
+
+static inline unsigned long get_asid(void)
+{
+	unsigned long long sr;
+
+	asm volatile ("getcon   " __c0 ", %0\n\t"
+		      : "=r" (sr));
+
+	sr = (sr >> SR_ASID_SHIFT) & MMU_CONTEXT_ASID_MASK;
+	return (unsigned long) sr;
+}
+
+/* Set ASID into SR */
+static inline void set_asid(unsigned long asid)
+{
+	unsigned long long sr, pc;
+
+	asm volatile ("getcon	" __c0 ", %0" : "=r" (sr));
+
+	sr = (sr & SR_ASID_MASK) | (asid << SR_ASID_SHIFT);
+
+	/*
+	 * It is possible that this function may be inlined and so to avoid
+	 * the assembler reporting duplicate symbols we make use of the gas trick
+	 * of generating symbols using numerics and forward reference.
+	 */
+	asm volatile ("movi	1, %1\n\t"
+		      "shlli	%1, 28, %1\n\t"
+		      "or	%0, %1, %1\n\t"
+		      "putcon	%1, " __c0 "\n\t"
+		      "putcon	%0, " __c1 "\n\t"
+		      "_loada	1f, %1\n\t"
+		      "ori	%1, 1 , %1\n\t"
+		      "putcon	%1, " __c8 "\n\t"
+		      "rte\n"
+		      "1:\n\t"
+		      : "=r" (sr), "=r" (pc) : "0" (sr));
+}
+
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+static __inline__ void activate_context(struct mm_struct *mm)
+{
+	get_mmu_context(mm);
+	set_asid(mm->context & MMU_CONTEXT_ASID_MASK);
+}
+
+
+static __inline__ void switch_mm(struct mm_struct *prev,
+				 struct mm_struct *next,
+				 struct task_struct *tsk, unsigned int cpu)
+{
+	set_bit(cpu, &next->cpu_vm_mask);
+
+	if (prev != next) {
+		mmu_pdtp_cache = next->pgd;
+		activate_context(next);
+		clear_bit(cpu, &prev->cpu_vm_mask);
+	}
+}
+
+#define activate_mm(prev, next) \
+	switch_mm((prev),(next),NULL,smp_processor_id())
+
+static __inline__ void
+enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+#endif	/* __ASSEMBLY__ */
+
+#endif /* __ASM_SH64_MMU_CONTEXT_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/module.h linux-2.4.22-pre3/include/asm-sh64/module.h
--- linux-2.4.22-pre2/include/asm-sh64/module.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/module.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,12 @@
+#ifndef _ASM_SH_MODULE_H
+#define _ASM_SH_MODULE_H
+/*
+ * This file contains the SH architecture specific module code.
+ */
+
+#define module_map(x)		vmalloc(x)
+#define module_unmap(x)		vfree(x)
+#define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
+
+#endif /* _ASM_SH_MODULE_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/msgbuf.h linux-2.4.22-pre3/include/asm-sh64/msgbuf.h
--- linux-2.4.22-pre2/include/asm-sh64/msgbuf.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/msgbuf.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,42 @@
+#ifndef __ASM_SH64_MSGBUF_H
+#define __ASM_SH64_MSGBUF_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/msgbuf.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/* 
+ * The msqid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* __ASM_SH64_MSGBUF_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/namei.h linux-2.4.22-pre3/include/asm-sh64/namei.h
--- linux-2.4.22-pre2/include/asm-sh64/namei.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/namei.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,24 @@
+#ifndef __ASM_SH64_NAMEI_H
+#define __ASM_SH64_NAMEI_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/namei.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * Included from linux/fs/namei.c
+ *
+ */
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif /* __ASM_SH64_NAMEI_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/page.h linux-2.4.22-pre3/include/asm-sh64/page.h
--- linux-2.4.22-pre2/include/asm-sh64/page.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/page.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,129 @@
+#ifndef __ASM_SH64_PAGE_H
+#define __ASM_SH64_PAGE_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/page.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ * benedict.gaster@superh.com 19th, 24th July 2002.
+ * 
+ * Modified to take account of enabling for D-CACHE support.
+ *
+ */
+
+#include <linux/config.h>
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	12
+#ifdef __ASSEMBLY__
+#define PAGE_SIZE	4096
+#else
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#endif
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+#define PTE_MASK	PAGE_MASK
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+extern void sh64_page_clear(void *page);
+extern void sh64_page_copy(void *from, void *to);
+
+#define clear_page(page)		sh64_page_clear(page)
+#define copy_page(to,from)		sh64_page_copy(from, to)
+
+#if defined(CONFIG_DCACHE_DISABLED)
+
+#define clear_user_page(page, vaddr)	clear_page(page)
+#define copy_user_page(to, from, vaddr)	copy_page(to, from)
+
+#else
+
+extern void clear_user_page(void *to, unsigned long address);
+extern void copy_user_page(void *to, void *from, unsigned long address);
+
+#endif /* defined(CONFIG_DCACHE_DISABLED) */
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long long pte; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((x).pmd)
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x) ((pte_t) { (x) } )
+#define __pmd(x) ((pmd_t) { (x) } )
+#define __pgd(x) ((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+#endif /* !__ASSEMBLY__ */
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+/*
+ * config.in defined.
+ */
+#define __MEMORY_START		(CONFIG_MEMORY_START)
+#define PAGE_OFFSET		(CONFIG_CACHED_MEMORY_OFFSET)
+
+#define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
+#define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
+#define MAP_NR(addr)		((__pa(addr)-__MEMORY_START) >> PAGE_SHIFT)
+
+#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+#define phys_to_page(phys)	(mem_map + (((phys)-__MEMORY_START) >> PAGE_SHIFT))
+#define virt_to_page(kaddr)  (mem_map + MAP_NR(kaddr))
+#define page_to_phys(page)	(((page - mem_map) << PAGE_SHIFT) + __MEMORY_START)
+
+
+#ifndef __ASSEMBLY__
+
+
+/*
+ * Tell the user there is some problem.
+ */
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	asm volatile("nop"); \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+
+#define VM_DATA_DEFAULT_FLAGS   (VM_READ | VM_WRITE | VM_EXEC | \
+                                 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH64_PAGE_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/param.h linux-2.4.22-pre3/include/asm-sh64/param.h
--- linux-2.4.22-pre2/include/asm-sh64/param.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/param.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,43 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/param.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ */
+#ifndef __ASM_SH_PARAM_H
+#define __ASM_SH_PARAM_H
+
+#include <linux/config.h>
+
+#ifdef __KERNEL__
+# ifdef CONFIG_SH_WDT
+#  define HZ		1000		/* Needed for high-res WOVF */
+# else
+#  define HZ		100
+# endif
+# define USER_HZ	100		/* User interfaces are in "ticks" */
+# define CLOCKS_PER_SEC	(USER_HZ)	/* frequency at which times() counts */
+#endif
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#endif /* __ASM_SH_PARAM_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/pci.h linux-2.4.22-pre3/include/asm-sh64/pci.h
--- linux-2.4.22-pre2/include/asm-sh64/pci.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/pci.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,274 @@
+
+/*
+**
+**                      P C I  -  C O M M O N  Internal Interface
+**
+** Module:    This module includes all functions that can be used for all included
+**            bridge.
+**
+** Copyright: This file is subject to the terms and conditions of the GNU General Public
+**            License.  See the file "COPYING" in the main directory of this archive
+**            for more details.
+**
+**            Copyright (C) 2001   Roberto Giai Meniet (giai@while1.com)  
+**                                 Franco  Ometti      (ometti@while1.com) 
+**
+** File:      include/asm-sh64/pci.h
+**
+** Note:      For a good view of this file use TABSTOP=8
+**
+*/
+
+
+/*
+** System includes
+*/
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <asm/io.h>
+
+struct pci_dev;
+
+#ifndef __ASM_SH64_PCI_H
+#define __ASM_SH64_PCI_H
+
+#ifdef __KERNEL__
+
+/* 
+** Can be used to override the logic in pci_scan_bus for skipping
+** already-configured bus numbers - to be used for buggy BIOSes
+** or architectures with incomplete PCI setup by the loader 
+*/
+#define pcibios_assign_all_busses()     1
+
+/* 
+** These are currently the correct values for the STM overdrive board.
+** We need some way of setting this on a board specific way, it will
+** not be the same on other boards I think
+*/
+#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
+#define PCIBIOS_MIN_IO          0x2000
+#define PCIBIOS_MIN_MEM         0x40000000
+#endif
+
+
+/*
+** Set penalize isa irq function
+*/
+static inline void pcibios_penalize_isa_irq(int irq)
+{
+	/* We don't do dynamic PCI IRQ allocation */
+}
+
+
+/* 
+** Dynamic DMA mapping stuff.
+** SuperH has everything mapped statically like x86.
+*/
+
+/* 
+** Allocate and map kernel buffer using consistent mode DMA for a device.
+** hwdev should be valid struct pci_dev pointer for PCI devices,
+** NULL for PCI-like buses (ISA, EISA).
+** Returns non-NULL cpu-view pointer to the buffer if successful and
+** sets *dma_addrp to the pci side dma address as well, else *dma_addrp
+** is undefined.
+*/
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+				  dma_addr_t *dma_handle);
+
+/* 
+** Free and unmap a consistent DMA buffer.
+** cpu_addr is what was returned from pci_alloc_consistent,
+** size must be the same as what as passed into pci_alloc_consistent,
+** and likewise dma_addr must be the same as what *dma_addrp was set to.
+**
+** References to the memory and mappings associated with cpu_addr/dma_addr
+** past this call are illegal.
+*/
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+				void *vaddr, dma_addr_t dma_handle);
+
+/* 
+** Map a single buffer of the indicated size for DMA in streaming mode.
+** The 32-bit bus address to use is returned.
+**
+** Once the device is given the dma address, the device owns this memory
+** until either pci_unmap_single or pci_dma_sync_single is performed.
+*/
+static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+					size_t size,int direction)
+{
+	dma_cache_wback_inv((unsigned long)ptr, size);
+	return virt_to_bus(ptr);
+}
+
+
+/*
+** Unmap a single streaming mode DMA translation.  The dma_addr and size
+** must match what was provided for in a previous pci_map_single call.  All
+** other usages are undefined.
+**
+** After this call, reads by the cpu to the buffer are guarenteed to see
+** whatever the device wrote there.
+*/
+static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+				    size_t size,int direction)
+{
+	/* Nothing to do */
+}
+
+/*
+ * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical
+ * to pci_map_single, but takes a struct page instead of a virtual address
+ */
+static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
+				      unsigned long offset, size_t size, int direction)
+{
+	return ((dma_addr_t)(page - mem_map) *
+		(dma_addr_t) PAGE_SIZE +
+		(dma_addr_t) offset);
+}
+
+static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
+				  size_t size, int direction)
+{
+	/* Nothing to do */
+}
+
+/* 
+** Map a set of buffers described by scatterlist in streaming
+** mode for DMA.  This is the scather-gather version of the
+** above pci_map_single interface.  Here the scatter gather list
+** elements are each tagged with the appropriate dma address
+** and length.  They are obtained via sg_dma_{address,length}(SG).
+**
+** NOTE: An implementation may be able to use a smaller number of
+**       DMA address/length pairs than there are SG table elements.
+**       (for example via virtual mapping capabilities)
+**       The routine returns the number of addr/length pairs actually
+**       used, at most nents.
+**
+** Device ownership issues as mentioned above for pci_map_single are
+** the same here.
+*/
+static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+			     int nents,int direction)
+{
+	int i;
+
+	for (i = 0; i < nents; i++) {
+		if (sg[i].address) {
+			dma_cache_wback_inv((unsigned long)sg[i].address,
+					    sg[i].length);
+			sg[i].dma_address = virt_to_bus(sg[i].address);
+		} else {
+			sg[i].dma_address = page_to_bus(sg[i].page) +
+					    sg[i].offset;
+			dma_cache_wback_inv((unsigned long) bus_to_virt(sg[i].dma_address), sg[i].length);
+		}
+	}
+
+	return nents;
+}
+
+
+/* 
+** Unmap a set of streaming mode DMA translations.
+** Again, cpu read rules concerning calls here are the same as for
+** pci_unmap_single() above.
+*/
+static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+				int nents,int direction)
+{
+	int i;
+
+	if (direction == PCI_DMA_TODEVICE)
+		return;
+	
+	for (i = 0; i < nents; i++) {
+		if (!sg[i].address)
+			continue;
+
+		dma_cache_wback_inv((unsigned long)sg[i].address, sg[i].length);
+	}
+}
+
+
+/* 
+** Make physical memory consistent for a single
+** streaming mode DMA translation after a transfer.
+**
+** If you perform a pci_map_single() but wish to interrogate the
+** buffer using the cpu, yet do not wish to teardown the PCI dma
+** mapping, you must call this function before doing so.  At the
+** next point you give the PCI dma address back to the card, the
+** device again owns the buffer.
+*/
+static inline void pci_dma_sync_single(struct pci_dev *hwdev,
+				       dma_addr_t dma_handle,
+				       size_t size,int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+	
+	dma_cache_wback_inv((unsigned long) bus_to_virt(dma_handle), size);
+}
+
+
+/* 
+** Make physical memory consistent for a set of streaming
+** mode DMA translations after a transfer.
+**
+** The same as pci_dma_sync_single but for a scatter-gather list,
+** same rules and usage.
+*/
+static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+				   struct scatterlist *sg,
+				   int nelems,int direction)
+{
+	int i;
+
+	for (i = 0; i < nelems; i++)
+		dma_cache_wback_inv((unsigned long)sg[i].address, sg[i].length);
+}
+
+
+/* 
+** Return whether the given PCI device DMA address mask can
+** be supported properly.  For example, if your device can
+** only drive the low 24-bits during PCI bus mastering, then
+** you would pass 0x00ffffff as the mask to this function.
+*/
+extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
+{
+	return 1;
+}
+
+
+/* Not supporting more than 32-bit PCI bus addresses now, but
+ * must satisfy references to this function.  Change if needed.
+ */
+#define pci_dac_dma_supported(pci_dev, mask) (0)
+ 
+/* Return the index of the PCI controller for device PDEV. */
+#define pci_controller_num(PDEV)        (0)
+
+/* 
+** These macros should be used after a pci_map_sg call has been done
+** to get bus addresses of each of the SG entries and their lengths.
+** You should only work with the number of sg entries pci_map_sg
+** returns, or alternatively stop on the first sg_dma_len(sg) which
+** is 0.
+*/
+#define sg_dma_address(sg)      ((sg)->dma_address)
+#define sg_dma_len(sg)          ((sg)->length)
+
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH64_PCI_H */
+
diff -urN linux-2.4.22-pre2/include/asm-sh64/pgalloc-3level.h linux-2.4.22-pre3/include/asm-sh64/pgalloc-3level.h
--- linux-2.4.22-pre2/include/asm-sh64/pgalloc-3level.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/pgalloc-3level.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,78 @@
+#ifndef __ASM_SH64_PGALLOC_3LEVEL_H
+#define __ASM_SH64_PGALLOC_3LEVEL_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/pgalloc-3level.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#if 0
+
+extern __inline__ pmd_t *get_pmd_slow(void)
+{
+	pmd_t *ret = (pmd_t *)__get_free_page(GFP_KERNEL);
+
+	if (ret)
+		memset(ret, 0, PAGE_SIZE);
+	return ret;
+}
+
+extern __inline__ pmd_t *get_pmd_fast(void)
+{
+	unsigned long *ret;
+
+	if ((ret = pmd_quicklist) != NULL) {
+		pmd_quicklist = (unsigned long *)(*ret);
+		ret[0] = 0;
+		pgtable_cache_size--;
+	} else
+		ret = (unsigned long *)get_pmd_slow();
+	return (pmd_t *)ret;
+}
+
+extern __inline__ void free_pmd_fast(pmd_t *pmd)
+{
+	*(unsigned long *)pmd = (unsigned long) pmd_quicklist;
+	pmd_quicklist = (unsigned long *) pmd;
+	pgtable_cache_size++;
+}
+
+extern __inline__ void free_pmd_slow(pmd_t *pmd)
+{
+	free_page((unsigned long)pmd);
+}
+
+extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address)
+{
+	if (!pgd)
+		BUG();
+	address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
+	if (pgd_none(*pgd)) {
+		pmd_t *page = get_pmd_fast();
+
+		if (!page)
+			page = get_pmd_slow();
+		if (page) {
+			if (pgd_none(*pgd)) {
+				set_pgd(pgd, __pgd((unsigned long) page | _KERNPG_TABLE));
+
+				/* Flush TLB not required, SW tree walk */
+				return page + address;
+			} else
+				free_pmd_fast(page);
+		} else
+			return NULL;
+	}
+	return (pmd_t *)pgd_page(*pgd) + address;
+}
+
+#endif
+
+
+#endif /* __ASM_SH64_PGALLOC_3LEVEL_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/pgalloc.h linux-2.4.22-pre3/include/asm-sh64/pgalloc.h
--- linux-2.4.22-pre2/include/asm-sh64/pgalloc.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/pgalloc.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,173 @@
+#ifndef __ASM_SH_PGALLOC_H
+#define __ASM_SH_PGALLOC_H
+
+#include <asm/processor.h>
+#include <linux/threads.h>
+#include <linux/slab.h>
+
+#define pgd_quicklist ((unsigned long *)0)
+#define pmd_quicklist ((unsigned long *)0)
+#define pte_quicklist ((unsigned long *)0)
+#define pgtable_cache_size 0L
+
+/*
+#define pmd_populate(mm, pmd, pte) \
+		set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
+
+*/
+
+/*
+ * Allocate and free page tables.
+ */
+
+/* NB this is a pretty crap implementation, should use the quick functions
+ * but speed is not a concern at the moment.
+ */
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+	unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t));
+	pgd_t *pgd = (pgd_t *)kmalloc(pgd_size, GFP_KERNEL);
+
+	if (pgd)
+		memset(pgd, 0, pgd_size);
+
+	return pgd;
+}
+
+static inline void pgd_free(pgd_t *pgd)
+{
+	kfree(pgd);
+}
+
+static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+	pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL);
+	if (pte)
+		clear_page(pte);
+	return pte;
+}
+
+static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
+{
+	return 0;
+}
+
+static inline void pte_free_slow(pte_t *pte)
+{
+	free_page((unsigned long)pte);
+}
+
+#define pte_free(pte)		pte_free_slow(pte)
+
+#define pgd_set(pgd,pmd) pgd_val(*pgd) = ( ((unsigned long)pmd) & PAGE_MASK)
+
+#define pgd_populate(mm, pgd, pmd)	pgd_set(pgd,pmd)
+
+
+static inline pmd_t*
+pmd_alloc_one_fast (struct mm_struct *mm, unsigned long addr)
+{
+	return 0;
+}
+ 
+static inline pmd_t*
+pmd_alloc_one (struct mm_struct *mm, unsigned long addr)
+{
+        pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL);
+ 
+        if (pmd != NULL )
+                clear_page(pmd);
+        return pmd;
+}
+ 
+static inline void
+pmd_free (pmd_t *pmd)
+{
+
+ free_page((unsigned long)pmd);      
+}
+
+ 
+static inline void
+pmd_populate (struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
+{
+
+  pmd_set(pmd,pte);
+
+
+    //     pmd_val(*pmd_entry) = __pa(pte);
+}
+ 
+
+/* Do nothing */
+#define do_check_pgt_cache(low, high)	(0)
+
+/*
+ * TLB flushing:
+ *
+ *  - flush_tlb() flushes the current mm struct TLBs
+ *  - flush_tlb_all() flushes all processes TLBs
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_range(mm, start, end) flushes a range of pages
+ *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
+ */
+
+extern void flush_tlb(void);
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_range(struct mm_struct *mm, unsigned long start,
+			    unsigned long end);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
+
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
+				      unsigned long start, unsigned long end)
+{ /* Nothing to do */
+}
+
+/* These are generic functions. These will need to change once D cache 
+ * aliasing support has been added. 
+ */
+
+static inline pte_t ptep_get_and_clear(pte_t *ptep)
+{
+	pte_t pte = *ptep;
+	pte_clear(ptep);
+	return pte;
+}
+
+/*
+ * Following functions are same as generic ones.
+ */
+static inline int ptep_test_and_clear_young(pte_t *ptep)
+{
+	pte_t pte = *ptep;
+	if (!pte_young(pte))
+		return 0;
+	set_pte(ptep, pte_mkold(pte));
+	return 1;
+}
+
+static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+{
+	pte_t pte = *ptep;
+	if (!pte_dirty(pte))
+		return 0;
+	set_pte(ptep, pte_mkclean(pte));
+	return 1;
+}
+
+static inline void ptep_set_wrprotect(pte_t *ptep)
+{
+	pte_t old_pte = *ptep;
+	set_pte(ptep, pte_wrprotect(old_pte));
+}
+
+static inline void ptep_mkdirty(pte_t *ptep)
+{
+	pte_t old_pte = *ptep;
+	set_pte(ptep, pte_mkdirty(old_pte));
+}
+#endif /* __ASM_SH_PGALLOC_H */
+
diff -urN linux-2.4.22-pre2/include/asm-sh64/pgtable-3level.h linux-2.4.22-pre3/include/asm-sh64/pgtable-3level.h
--- linux-2.4.22-pre2/include/asm-sh64/pgtable-3level.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/pgtable-3level.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,152 @@
+#ifndef __ASM_SH64_PGTABLE_3LEVEL_H
+#define __ASM_SH64_PGTABLE_3LEVEL_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/pgtable-3level.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * Supporting 32-bit addressing mode for now and, of course, 64-bit pointers.
+ * Supporting variable NEFF/NPHYS defintions.
+ *
+ */
+
+/*
+ * NEFF and NPHYS related defines.
+ */
+#define NEFF		32
+#define	NEFF_SIGN	(1LL << (NEFF - 1))
+#define	NEFF_MASK	(-1LL << NEFF)
+
+#define NPHYS		32
+#define	NPHYS_SIGN	(1LL << (NPHYS - 1))
+#define	NPHYS_MASK	(-1LL << NPHYS)
+
+/*
+ * three-level asymmetric paging structure: PGD is top level.
+ * The asymmetry comes from 32-bit pointers and 64-bit PTEs.
+ */
+/* bottom level: PTE. It's 9 bits = 512 pointers */
+#define PTRS_PER_PTE	((1<<PAGE_SHIFT)/sizeof(unsigned long long))
+#define PTE_MAGNITUDE	3	      /* sizeof(unsigned long long) magnit. */
+#define PTE_SHIFT	PAGE_SHIFT
+#define PTE_BITS	(PAGE_SHIFT - PTE_MAGNITUDE)
+
+/* middle level: PMD. It's 10 bits = 1024 pointers */
+#define PTRS_PER_PMD	((1<<PAGE_SHIFT)/sizeof(unsigned long long *))
+#define PMD_MAGNITUDE	2	      /* sizeof(unsigned long long *) magnit. */
+#define PMD_SHIFT	(PTE_SHIFT + PTE_BITS)
+#define PMD_BITS	(PAGE_SHIFT - PMD_MAGNITUDE)
+
+/* top level: PMD. It's 1 bit = 2 pointers */
+#define PGDIR_SHIFT	(PMD_SHIFT + PMD_BITS)
+#define PGD_BITS	(NEFF - PGDIR_SHIFT)
+#define PTRS_PER_PGD	(1<<PGD_BITS)
+
+/*
+ * Error outputs.
+ */
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+/*
+ * Table setting routines. Used within arch/mm only.
+ */
+#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
+
+static __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
+{
+	unsigned long long x = ((unsigned long long) pteval.pte);
+	unsigned long long *xp = (unsigned long long *) pteptr;
+	/*
+	 * Sign-extend based on NPHYS.
+	 */
+	*(xp) = (x & NPHYS_SIGN) ? (x | NPHYS_MASK) : x;
+}
+
+static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
+{
+	pmd_val(*pmdp) = (unsigned long) ptep; 
+}
+
+  
+
+
+/*
+ * PGD defines. Top level.
+ */
+
+/* To find an entry in a generic PGD. */
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define __pgd_offset(address) pgd_index(address)
+#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
+
+/* To find an entry in a kernel PGD. */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+
+/*
+ * PGD level access routines.
+ *
+ * Note1:
+ * There's no need to use physical addresses since the tree walk is all
+ * in performed in software, until the PTE translation.
+ *
+ * Note 2:
+ * A PGD entry can be uninitialized (_PGD_UNUSED), generically bad,
+ * clear (_PGD_EMPTY), present. When present, lower 3 nibbles contain
+ * _KERNPG_TABLE. Being a kernel virtual pointer also bit 31 must
+ * be 1. Assuming an arbitrary clear value of bit 31 set to 0 and
+ * lower 3 nibbles set to 0xFFF (_PGD_EMPTY) any other value is a
+ * bad pgd that must be notified via printk().
+ *
+ */
+#define _PGD_EMPTY		0x0
+#define pgd_present(pgd_entry)	(1)
+#define pgd_clear(pgd_entry_p)	(set_pgd((pgd_entry_p), __pgd(_PGD_EMPTY)))
+#define pgd_none(pgd_entry)	(pgd_val((pgd_entry)) == _PGD_EMPTY)
+/* TODO: Think later about what a useful definition of 'bad' would be now. */
+#define pgd_bad(pgd_entry)	(0)
+#define pgd_page(pgd_entry)	((unsigned long) (pgd_val(pgd_entry) & PAGE_MASK))
+
+
+/*
+ * PMD defines. Middle level.
+ */
+
+/* PGD to PMD dereferencing */
+#define __pmd_offset(address) \
+		(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+#define pmd_offset(dir, addr) \
+		((pmd_t *) ((pgd_val(*(dir))) & PAGE_MASK) + __pmd_offset((addr)))
+
+
+/*
+ * PMD level access routines. Same notes as above.
+ */
+#define _PMD_EMPTY		0x0
+/* Either the PMD is empty or present, it's not paged out */
+#define pmd_present(pmd_entry)	(1)
+#define pmd_clear(pmd_entry_p)	(set_pmd((pmd_entry_p), __pmd(_PMD_EMPTY)))
+#define pmd_none(pmd_entry)	(pmd_val((pmd_entry)) == _PMD_EMPTY)
+/* TODO: Think later about what a useful definition of 'bad' would be now. */
+#define pmd_bad(pmd_entry)	(0)
+#define pmd_page(pmd_entry)	((unsigned long) (pmd_val(pmd_entry) & PAGE_MASK))
+
+/* PMD to PTE dereferencing */
+#define __pte_offset(address) \
+		((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+
+#define pte_offset(dir, addr) \
+		((pte_t *) ((pmd_val(*(dir))) & PAGE_MASK) + __pte_offset((addr)))
+
+#endif /* __ASM_SH64_PGTABLE_3LEVEL_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/pgtable.h linux-2.4.22-pre3/include/asm-sh64/pgtable.h
--- linux-2.4.22-pre2/include/asm-sh64/pgtable.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/pgtable.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,340 @@
+#ifndef __ASM_SH64_PGTABLE_H
+#define __ASM_SH64_PGTABLE_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/pgtable.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ * This file contains the functions and defines necessary to modify and use
+ * the SuperH page table tree.
+ */
+
+#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/pgtable-3level.h>
+#include <linux/threads.h>
+#include <linux/config.h>
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+extern void paging_init(void);
+
+extern void flush_cache_all(void);
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_range(struct mm_struct *mm, unsigned long start,
+			      unsigned long end);
+extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr);
+
+extern void flush_page_to_ram(struct page *page);
+
+extern void flush_icache_range(unsigned long start, unsigned long end);
+extern void flush_icache_page(struct vm_area_struct *vma, struct page *pg);
+
+extern void flush_dcache_page(struct page *pg);
+
+extern void flush_cache_sigtramp(unsigned long start, unsigned long end);
+
+#ifdef CONFIG_DCACHE_DISABLED
+
+#define sh64_dcache_purge_sets(base,sets)		do { } while (0)
+#define sh64_dcache_purge_all()				do { } while (0)
+#define sh64_dcache_purge_kernel_range(start,end)	do { } while (0)
+#define sh64_dcache_purge_coloured_phy_page(addr,eaddr)	do { } while (0)
+#define sh64_dcache_purge_phy_page(pg)			do { } while (0)
+#define sh64_dcache_purge_virt_page(mm,eaddr)		do { } while (0)
+#define sh64_dcache_purge_user_page(mm,eaddr)		do { } while (0)
+#define sh64_dcache_purge_user_range(mm,start,end)	do { } while (0)
+#define sh64_dcache_wback_current_user_range(start,end) do { } while (0)
+
+#define copy_user_page(to, from, addr)	memcpy(to, from, PAGE_SIZE)
+#define clear_user_page(to, addr)	memset(to, 0, PAGE_SIZE)
+
+#endif /* CONFIG_DCACHE_DISABLED */
+
+#ifdef CONFIG_ICACHE_DISABLED
+
+#define sh64_icache_inv_all()				do { } while (0)
+#define sh64_icache_inv_kernel_range(start,end)		do { } while (0)
+#define sh64_icache_inv_user_page(vma,eaddr)		do { } while (0)
+#define sh64_icache_inv_user_page_range(mm,start,end)	do { } while (0)
+#define sh64_icache_inv_user_small_range(mm,start,len)	do { } while (0)
+#define sh64_icache_inv_current_user_range(start,end)	do { } while (0)
+
+#endif /* CONFIG_ICACHE_DISABLED */
+
+/* We provide our own get_unmapped_area to avoid cache synonym issue */
+#define HAVE_ARCH_UNMAPPED_AREA
+
+/*
+ * Basically we have the same two-level (which is the logical three level
+ * Linux page table layout folded) page tables as the i386.
+ */
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern unsigned char empty_zero_page[PAGE_SIZE];
+#define ZERO_PAGE(vaddr) (mem_map + MAP_NR(empty_zero_page))
+
+#endif /* !__ASSEMBLY__ */
+
+#include <asm/pgtable-3level.h>
+
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE-1))
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+/* Round it up ! */
+#define USER_PTRS_PER_PGD	((TASK_SIZE+PGDIR_SIZE-1)/PGDIR_SIZE)
+#define FIRST_USER_PGD_NR	0
+
+#ifndef __ASSEMBLY__
+#define VMALLOC_END	0xff000000
+#define VMALLOC_START	0xf0000000
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+
+#define IOBASE_VADDR	0xff000000
+#define IOBASE_END	0xffffffff
+
+/*
+ * PTEL coherent flags.
+ * See Chapter 17 ST50 CPU Core Volume 1, Architecture.
+ */
+/* The bits that are required in the SH-5 TLB are placed in the h/w-defined
+   positions, to avoid expensive bit shuffling on every refill.  The remaining
+   bits are used for s/w purposes and masked out on each refill.
+
+   Note, the PTE slots are used to hold data of type swp_entry_t when a page is
+   swapped out.  Only the _PAGE_PRESENT flag is significant when the page is
+   swapped out, and it must be placed so that it doesn't overlap either the
+   type or offset fields of swp_entry_t.  For x86, offset is at [31:8] and type
+   at [6:1], with _PAGE_PRESENT at bit 0 for both pte_t and swp_entry_t.  This
+   scheme doesn't map to SH-5 because bit [0] controls cacheability.  So bit
+   [2] is used for _PAGE_PRESENT and the type field of swp_entry_t is split
+   into 2 pieces.  That is handled by SWP_ENTRY and SWP_TYPE below. */
+#define _PAGE_WT	0x001  /* CB0: uncachable/device or write-back/write-thru */
+#define _PAGE_CACHABLE	0x002  /* CB1: uncachable/cachable */
+#define _PAGE_PRESENT	0x004  /* software: if allocated */
+#define _PAGE_SIZE0	0x008  /* SZ0-bit : size of page */
+#define _PAGE_SIZE1	0x010  /* SZ1-bit : size of page */
+#define _PAGE_SHARED	0x020  /* software: reflects PTEH's SH */
+#define _PAGE_READ	0x040  /* PR0-bit : read access allowed */
+#define _PAGE_EXECUTE	0x080  /* PR1-bit : execute access allowed */
+#define _PAGE_WRITE	0x100  /* PR2-bit : write access allowed */
+#define _PAGE_USER	0x200  /* PR3-bit : user space access allowed */
+#define _PAGE_DIRTY	0x400  /* software: page accessed in write */
+#define _PAGE_ACCESSED	0x800  /* software: page referenced */
+
+/* Mask which drops software flags */
+#define _PAGE_FLAGS_HARDWARE_MASK	0xfffffffffffff3dbLL
+/* Flags default: 4KB, Read, Not write, Not execute, Not user */
+#define _PAGE_FLAGS_HARDWARE_DEFAULT	0x0000000000000040LL
+
+/*
+ * Default flags for a Kernel page.
+ * This is fundametally also SHARED because the main use of this define
+ * (other than for PGD/PMD entries) is for the VMALLOC pool which is
+ * contextless.
+ *
+ * _PAGE_EXECUTE is required for modules
+ *
+ */
+#define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
+			 _PAGE_EXECUTE | \
+			 _PAGE_CACHABLE | _PAGE_ACCESSED | _PAGE_DIRTY | \
+			 _PAGE_SHARED)
+
+/* Default flags for a User page */
+#define _PAGE_TABLE	(_KERNPG_TABLE | _PAGE_USER)
+
+#define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+#define PAGE_NONE	__pgprot(_PAGE_CACHABLE | _PAGE_ACCESSED)
+#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
+				 _PAGE_CACHABLE | _PAGE_ACCESSED | _PAGE_USER | \
+				 _PAGE_SHARED)
+/* We need to include PAGE_EXECUTE in PAGE_COPY because it is the default
+ * protection mode for the stack. */
+#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_CACHABLE | \
+				 _PAGE_ACCESSED | _PAGE_USER | _PAGE_EXECUTE)
+#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_CACHABLE | \
+				 _PAGE_ACCESSED | _PAGE_USER)
+#define PAGE_KERNEL	__pgprot(_KERNPG_TABLE)
+
+
+/*
+ * In ST50 we have full permissions (Read/Write/Execute/Shared).
+ * Just match'em all. These are for mmap(), therefore all at least
+ * User/Cachable/Present/Accessed. No point in making Fault on Write.
+ */
+#define __MMAP_COMMON	(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | _PAGE_ACCESSED)
+       /* sxwr */
+#define __P000	__pgprot(__MMAP_COMMON)
+#define __P001	__pgprot(__MMAP_COMMON | _PAGE_READ)
+#define __P010	__pgprot(__MMAP_COMMON)
+#define __P011	__pgprot(__MMAP_COMMON | _PAGE_READ)
+#define __P100	__pgprot(__MMAP_COMMON | _PAGE_EXECUTE)
+#define __P101	__pgprot(__MMAP_COMMON | _PAGE_EXECUTE | _PAGE_READ)
+#define __P110	__pgprot(__MMAP_COMMON | _PAGE_EXECUTE)
+#define __P111	__pgprot(__MMAP_COMMON | _PAGE_EXECUTE | _PAGE_READ)
+
+#define __S000	__pgprot(__MMAP_COMMON | _PAGE_SHARED)
+#define __S001	__pgprot(__MMAP_COMMON | _PAGE_SHARED | _PAGE_READ)
+#define __S010	__pgprot(__MMAP_COMMON | _PAGE_SHARED | _PAGE_WRITE)
+#define __S011	__pgprot(__MMAP_COMMON | _PAGE_SHARED | _PAGE_READ | _PAGE_WRITE)
+#define __S100	__pgprot(__MMAP_COMMON | _PAGE_SHARED | _PAGE_EXECUTE)
+#define __S101	__pgprot(__MMAP_COMMON | _PAGE_SHARED | _PAGE_EXECUTE | _PAGE_READ)
+#define __S110	__pgprot(__MMAP_COMMON | _PAGE_SHARED | _PAGE_EXECUTE | _PAGE_WRITE)
+#define __S111	__pgprot(__MMAP_COMMON | _PAGE_SHARED | _PAGE_EXECUTE | _PAGE_READ | _PAGE_WRITE)
+
+/*
+ * Handling allocation failures during page table setup.
+ */
+extern void __handle_bad_pmd_kernel(pmd_t * pmd);
+#define __handle_bad_pmd(x)	__handle_bad_pmd_kernel(x)
+
+/*
+ * PTE level access routines.
+ *
+ * Note1:
+ * It's the tree walk leaf. This is physical address to be stored.
+ *
+ * Note 2:
+ * Regarding the choice of _PTE_EMPTY:
+
+   We must choose a bit pattern that cannot be valid, whether or not the page
+   is present.  bit[2]==1 => present, bit[2]==0 => swapped out.  If swapped
+   out, bits [31:8], [6:3], [1:0] are under swapper control, so only bit[7] is
+   left for us to select.  If we force bit[7]==0 when swapped out, we could use
+   the combination bit[7,2]=2'b10 to indicate an empty PTE.  Alternatively, if
+   we force bit[7]==1 when swapped out, we can use all zeroes to indicate
+   empty.  This is convenient, because the page tables get cleared to zero
+   when they are allocated.
+
+ */
+#define _PTE_EMPTY	0x0
+#define pte_present(x)	(pte_val(x) & _PAGE_PRESENT)
+#define pte_clear(xp)	(set_pte(xp, __pte(_PTE_EMPTY)))
+#define pte_none(x)	(pte_val(x) == _PTE_EMPTY)
+
+/*
+ * Some definitions to translate between mem_map, PTEs, and page
+ * addresses:
+ */
+
+/*
+ * Given a PTE, return the index of the mem_map[] entry corresponding
+ * to the page frame the PTE. Get the absolute physical address, make
+ * a relative physical address and translate it to an index.
+ */
+#define pte_pagenr(x)		(((unsigned long) (pte_val(x)) - \
+				 __MEMORY_START) >> PAGE_SHIFT)
+
+/*
+ * Given a PTE, return the "struct page *".
+ */
+#define pte_page(x)		(mem_map + pte_pagenr(x))
+
+/*
+ * Return number of (down rounded) MB corresponding to x pages.
+ */
+#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
+
+
+/*
+ * The following have defined behavior only work if pte_present() is true.
+ */
+extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; }
+extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXECUTE; }
+extern inline int pte_dirty(pte_t pte){ return pte_val(pte) & _PAGE_DIRTY; }
+extern inline int pte_young(pte_t pte){ return pte_val(pte) & _PAGE_ACCESSED; }
+extern inline int pte_write(pte_t pte){ return pte_val(pte) & _PAGE_WRITE; }
+
+extern inline pte_t pte_rdprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_READ)); return pte; }
+extern inline pte_t pte_wrprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_WRITE)); return pte; }
+extern inline pte_t pte_exprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_EXECUTE)); return pte; }
+extern inline pte_t pte_mkclean(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
+extern inline pte_t pte_mkold(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
+
+extern inline pte_t pte_mkread(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_READ)); return pte; }
+extern inline pte_t pte_mkwrite(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_WRITE)); return pte; }
+extern inline pte_t pte_mkexec(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_EXECUTE)); return pte; }
+extern inline pte_t pte_mkdirty(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
+extern inline pte_t pte_mkyoung(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
+
+/*
+ * Conversion functions: convert a page and protection to a page entry.
+ *
+ * extern pte_t mk_pte(struct page *page, pgprot_t pgprot)
+ */
+#define mk_pte(page,pgprot)							\
+({										\
+	pte_t __pte;								\
+										\
+	set_pte(&__pte, __pte((((page)-mem_map) << PAGE_SHIFT) | 		\
+		__MEMORY_START | pgprot_val((pgprot))));			\
+	__pte;									\
+})
+
+/*
+ * This takes a (absolute) physical page address that is used
+ * by the remapping functions
+ */
+#define mk_pte_phys(physpage, pgprot) \
+({ pte_t __pte; set_pte(&__pte, __pte(physpage | pgprot_val(pgprot))); __pte; })
+
+extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{ set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
+
+#define page_pte_prot(page, prot) mk_pte(page, prot)
+#define page_pte(page) page_pte_prot(page, __pgprot(0))
+
+#define pte_same(A,B)        (pte_val(A) == pte_val(B)) 
+
+
+extern void update_mmu_cache(struct vm_area_struct * vma,
+			     unsigned long address, pte_t pte);
+
+/* Encode and de-code a swap entry */
+#define SWP_TYPE(x)			(((x).val & 3) + (((x).val >> 1) & 0x3c))
+#define SWP_OFFSET(x)			((x).val >> 8)
+
+/* Avoid bit 2 for type */
+static inline swp_entry_t SWP_ENTRY(unsigned long type, unsigned long offset)
+{
+	unsigned long result;
+	/* Assert bit[7], to make swapped out page table entries distinct
+	   from unused/uninitialised ones */
+	result = (offset << 8) + 0x80 + ((type & 0x3c) << 1) + (type & 3);
+	return (swp_entry_t) {result};
+}
+#define pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
+#define swp_entry_to_pte(x)		((pte_t) { (x).val })
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define PageSkip(page)		(0)
+#define kern_addr_valid(addr)	(1)
+
+#define io_remap_page_range remap_page_range
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()    do { } while (0)
+
+/* This must be implemented for ptrace() */
+#if 0
+#define flush_icache_user_range(vma,pg,adr,len)      do { } while (0)  
+#endif
+
+
+#endif /* __ASM_SH64_PGTABLE_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/platform.h linux-2.4.22-pre3/include/asm-sh64/platform.h
--- linux-2.4.22-pre2/include/asm-sh64/platform.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/platform.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,69 @@
+#ifndef __ASM_SH64_PLATFORM_H
+#define __ASM_SH64_PLATFORM_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/platform.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * benedict.gaster@superh.com:	 3rd May 2002
+ *    Added support for ramdisk, removing statically linked romfs at the same time.
+ */
+
+#include <linux/ioport.h>
+#include <asm/irq.h>
+
+
+/*
+ * Platform definition structure.
+ */
+struct sh64_platform {
+	unsigned int readonly_rootfs;
+	unsigned int ramdisk_flags;
+	unsigned int initial_root_dev;
+	unsigned int loader_type;
+	unsigned int initrd_start;
+	unsigned int initrd_size;
+	unsigned int fpu_flags;
+	unsigned int io_res_count;
+	unsigned int kram_res_count;
+	unsigned int xram_res_count;
+	unsigned int rom_res_count;
+	struct resource *io_res_p;
+	struct resource *kram_res_p;
+	struct resource *xram_res_p;
+	struct resource *rom_res_p;
+};
+
+extern struct sh64_platform platform_parms;
+
+extern unsigned long long memory_start, memory_end;
+
+extern unsigned long long fpu_in_use;
+
+extern int platform_int_priority[NR_INTC_IRQS];
+
+#define FPU_FLAGS		(platform_parms.fpu_flags)
+#define STANDARD_IO_RESOURCES	(platform_parms.io_res_count)
+#define STANDARD_KRAM_RESOURCES	(platform_parms.kram_res_count)
+#define STANDARD_XRAM_RESOURCES	(platform_parms.xram_res_count)
+#define STANDARD_ROM_RESOURCES	(platform_parms.rom_res_count)
+
+/*
+ * Kernel Memory description, Respectively:
+ * code = last but one memory descriptor
+ * data = last memory descriptor
+ */
+#define code_resource (platform_parms.kram_res_p[STANDARD_KRAM_RESOURCES - 2])
+#define data_resource (platform_parms.kram_res_p[STANDARD_KRAM_RESOURCES - 1])
+
+/* Be prepared to 64-bit sign extensions */
+#define PFN_UP(x)       ((((x) + PAGE_SIZE-1) >> PAGE_SHIFT) & 0x000fffff)
+#define PFN_DOWN(x)     (((x) >> PAGE_SHIFT) & 0x000fffff)
+#define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
+
+#endif	/* __ASM_SH64_PLATFORM_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/poll.h linux-2.4.22-pre3/include/asm-sh64/poll.h
--- linux-2.4.22-pre2/include/asm-sh64/poll.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/poll.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,36 @@
+#ifndef __ASM_SH64_POLL_H
+#define __ASM_SH64_POLL_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/poll.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/* These are specified by iBCS2 */
+#define POLLIN		0x0001
+#define POLLPRI		0x0002
+#define POLLOUT		0x0004
+#define POLLERR		0x0008
+#define POLLHUP		0x0010
+#define POLLNVAL	0x0020
+
+/* The rest seem to be more-or-less nonstandard. Check them! */
+#define POLLRDNORM	0x0040
+#define POLLRDBAND	0x0080
+#define POLLWRNORM	0x0100
+#define POLLWRBAND	0x0200
+#define POLLMSG		0x0400
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif /* __ASM_SH64_POLL_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/posix_types.h linux-2.4.22-pre3/include/asm-sh64/posix_types.h
--- linux-2.4.22-pre2/include/asm-sh64/posix_types.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/posix_types.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,128 @@
+#ifndef __ASM_SH64_POSIX_TYPES_H
+#define __ASM_SH64_POSIX_TYPES_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/posix_types.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned short	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef long unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef	__FD_SET
+static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	__fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
+}
+
+#undef	__FD_CLR
+static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	__fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
+}
+
+
+#undef	__FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
+{ 
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef	__FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
+{
+	unsigned long *__tmp = __p->fds_bits;
+	int __i;
+
+	if (__builtin_constant_p(__FDSET_LONGS)) {
+		switch (__FDSET_LONGS) {
+		case 16:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			__tmp[ 4] = 0; __tmp[ 5] = 0;
+			__tmp[ 6] = 0; __tmp[ 7] = 0;
+			__tmp[ 8] = 0; __tmp[ 9] = 0;
+			__tmp[10] = 0; __tmp[11] = 0;
+			__tmp[12] = 0; __tmp[13] = 0;
+			__tmp[14] = 0; __tmp[15] = 0;
+			return;
+
+		case 8:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			__tmp[ 4] = 0; __tmp[ 5] = 0;
+			__tmp[ 6] = 0; __tmp[ 7] = 0;
+			return;
+
+		case 4:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			return;
+		}
+	}
+	__i = __FDSET_LONGS;
+	while (__i) {
+		__i--;
+		*__tmp = 0;
+		__tmp++;
+	}
+}
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif /* __ASM_SH64_POSIX_TYPES_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/processor.h linux-2.4.22-pre3/include/asm-sh64/processor.h
--- linux-2.4.22-pre2/include/asm-sh64/processor.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/processor.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,273 @@
+#ifndef __ASM_SH64_PROCESSOR_H
+#define __ASM_SH64_PROCESSOR_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/processor.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ */
+
+#include <asm/page.h>
+
+#ifndef __ASSEMBLY__
+
+#include <asm/types.h>
+#include <asm/cache.h>
+#include <asm/tlb.h>
+#include <asm/registers.h>
+#include <linux/threads.h>
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ \
+void *pc; \
+unsigned long long __dummy; \
+__asm__("gettr	" __t0 ", %1\n\t" \
+	"pta	4, " __t0 "\n\t" \
+	"gettr	" __t0 ", %0\n\t" \
+	"ptabs	%1, " __t0 "\n\t"	\
+	:"=r" (pc), "=r" (__dummy) \
+	: "1" (__dummy)); \
+pc; })
+
+/*
+ *  CPU type and hardware bug flags. Kept separately for each CPU.
+ */
+enum cpu_type {
+	CPU_SH5_101,
+	CPU_SH5_103,
+	CPU_SH_NONE
+};
+
+struct sh_cpuinfo {
+	enum cpu_type type;
+	unsigned long loops_per_jiffy;
+
+	char	hard_math;
+
+	unsigned long *pgd_quick;
+	unsigned long *pmd_quick;
+	unsigned long *pte_quick;
+	unsigned long pgtable_cache_sz;
+	unsigned int cpu_clock, master_clock, bus_clock, module_clock;
+
+	/* Cache info */
+	struct cache_info icache;
+	struct cache_info dcache;
+
+	/* TLB info */
+	struct tlb_info itlb;
+	struct tlb_info dtlb;
+};
+
+extern struct sh_cpuinfo boot_cpu_data;
+
+#define cpu_data (&boot_cpu_data)
+#define current_cpu_data boot_cpu_data
+
+#endif
+
+/*
+ * User space process size: 2GB - 64MB.
+ */
+#define TASK_SIZE	0x7c000000UL
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
+
+/*
+ * Bit of SR register
+ *
+ * FD-bit:
+ *     When it's set, it means the processor doesn't have right to use FPU,
+ *     and it results exception when the floating operation is executed.
+ *
+ * IMASK-bit:
+ *     Interrupt level mask
+ *
+ * STEP-bit:
+ *     Single step bit
+ *
+ */
+#define SR_FD    0x00008000
+
+#ifdef ST_DEBUG
+#define SR_MMU   0x84000000
+#else
+#define SR_MMU   0x80000000
+#endif
+
+#define SR_IMASK 0x000000f0
+#define SR_SSTEP 0x08000000
+
+#ifndef __ASSEMBLY__
+
+/*
+ * FPU structure and data
+ */
+
+struct sh_fpu_hard_struct {
+	unsigned long long fp_regs[32];
+	unsigned int fpscr;
+	/* long status; * software status information */
+};
+
+#if 0
+/* Dummy fpu emulator  */
+struct sh_fpu_soft_struct {
+	unsigned long long fp_regs[32];
+	unsigned int fpscr;
+	unsigned char lookahead;
+	unsigned long entry_pc;
+};
+#endif
+
+union sh_fpu_union {
+	struct sh_fpu_hard_struct hard;
+	// struct sh_fpu_soft_struct soft;
+};
+
+struct thread_struct {
+	unsigned long sp;
+	unsigned long pc;
+
+	unsigned long trap_no, error_code;
+	unsigned long address;
+	/* Hardware debugging registers may come here */
+
+        struct pt_regs *kregs;
+	/* floating point info */
+	union sh_fpu_union fpu;
+};
+
+#define INIT_MMAP \
+{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
+
+extern  struct pt_regs fake_swapper_regs;
+
+#define INIT_THREAD  {						\
+	sizeof(init_stack) + (long) &init_stack, /* sp */	\
+	0,					 /* pc */	\
+	0, 0, 							\
+	0, 							\
+        &fake_swapper_regs,                     /*kregs*/       \
+	{{{0,}},} 				/* fpu state */	\
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ */
+#define SR_USER (SR_MMU | SR_FD)
+
+#define start_thread(regs, new_pc, new_sp) 	 		\
+	set_fs(USER_DS);			 		\
+	regs->sr = SR_USER;	/* User mode. */ 		\
+	regs->pc = new_pc - 4;	/* Compensate syscall exit */	\
+	regs->pc |= 1;		/* Set SHmedia ! */		\
+	regs->regs[18] = 0;   		 	 		\
+	regs->regs[15] = new_sp
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+struct mm_struct;
+
+/* Free all resources held by a thread. */
+extern void release_thread(struct task_struct *);
+/*
+ * create a kernel thread without removing it from tasklists
+ */
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+
+/* Copy and release all segment info associated with a VM */
+#define copy_segments(p, mm)	do { } while(0)
+#define release_segments(mm)	do { } while(0)
+#define forget_segments()	do { } while (0)
+
+/*
+ * FPU lazy state save handling.
+ */
+
+extern __inline__ void release_fpu(void)
+{
+	unsigned long long __dummy;
+
+	/* Set FD flag in SR */
+	__asm__ __volatile__("getcon	" __c0 ", %0\n\t"
+			     "or	%0, %1, %0\n\t"
+			     "putcon	%0, " __c0 "\n\t"
+			     : "=&r" (__dummy)
+			     : "r" (SR_FD));
+}
+
+extern __inline__ void grab_fpu(void)
+{
+	unsigned long long __dummy;
+
+	/* Clear out FD flag in SR */
+	__asm__ __volatile__("getcon	" __c0 ", %0\n\t"
+			     "and	%0, %1, %0\n\t"
+			     "putcon	%0, " __c0 "\n\t"
+			     : "=&r" (__dummy)
+			     : "r" (~SR_FD));
+}
+
+/* Double presision, NANS as NANS, rounding to nearest, no exceptions */
+#define FPSCR_INIT  0x00000000
+
+/* Save the current FP regs */
+void fpsave(struct sh_fpu_hard_struct *fpregs);
+
+/* Initialise the FP state of a task */
+void fpinit(struct sh_fpu_hard_struct *fpregs);
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	return t->pc;
+}
+
+extern unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk)  ((tsk)->thread.pc)
+#define KSTK_ESP(tsk)  ((tsk)->thread.sp)
+
+#endif	/* __ASSEMBLY__ */
+
+#define TASK_STKPAGES	2		/* Must be power of 2. 2 minimum */
+#define THREAD_SIZE	(TASK_STKPAGES * PAGE_SIZE)
+#define INIT_TASK_SIZE	THREAD_SIZE
+
+
+#ifndef __ASSEMBLY__
+extern struct task_struct *last_task_used_math;
+
+extern struct task_struct * alloc_task_struct(void);
+extern void free_task_struct(struct task_struct *);
+#define get_task_struct(tsk)      atomic_inc(&mem_map[MAP_NR(tsk)].count)
+
+#define init_task	(init_task_union.task)
+#define init_stack	(init_task_union.stack)
+
+#endif	/* __ASSEMBLY__ */
+#endif /* __ASM_SH64_PROCESSOR_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/ptrace.h linux-2.4.22-pre3/include/asm-sh64/ptrace.h
--- linux-2.4.22-pre2/include/asm-sh64/ptrace.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/ptrace.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,38 @@
+#ifndef __ASM_SH64_PTRACE_H
+#define __ASM_SH64_PTRACE_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/ptrace.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/*
+ * This struct defines the way the registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ */
+struct pt_regs {
+	unsigned long long pc;
+	unsigned long long sr;
+	unsigned long long syscall_nr;
+	unsigned long long regs[63];
+	unsigned long long tregs[8];
+	unsigned long long pad[2];
+};
+
+#ifdef __KERNEL__
+#define user_mode(regs) (((regs)->sr & 0x40000000)==0)
+#define instruction_pointer(regs) ((regs)->pc)
+extern void show_regs(struct pt_regs *);
+#endif
+
+#define PTRACE_SETOPTIONS 21
+
+#define PTRACE_O_TRACESYSGOOD     0x00000001   
+
+#endif /* __ASM_SH64_PTRACE_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/registers.h linux-2.4.22-pre3/include/asm-sh64/registers.h
--- linux-2.4.22-pre2/include/asm-sh64/registers.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/registers.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,199 @@
+#ifndef __ASM_SH64_REGISTERS_H
+#define __ASM_SH64_REGISTERS_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/registers.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#ifdef __ASSEMBLY__
+/* =====================================================================
+** 
+** Section 1: acts on assembly sources pre-processed by GPP ( <source.S>).
+**	      Assigns symbolic names to control & target registers.
+*/
+
+/*
+ * Concerning registers name, the assembly sources follows the
+ * CDC naming convention.
+ * This section converts CDC registers names into RedHat style.
+ */
+
+/*
+ * Control Registers.
+ */
+#define SR	cr0
+#define SSR	cr1
+#define PSSR	cr2
+			/* cr3 UNDEFINED */
+#define INTEVT	cr4
+#define EXPEVT	cr5
+#define PEXPEVT	cr6
+#define TRA	cr7
+#define SPC	cr8
+#define PSPC	cr9
+#define RESVEC	cr10
+#define VBR	cr11
+			/* cr12 UNDEFINED */
+#define TEA	cr13
+			/* cr14-cr15 UNDEFINED */
+#define DCR	cr16
+#define KCR0	cr17
+#define KCR1	cr18
+			/* cr19-cr31 UNDEFINED */
+			/* cr32-cr61 RESERVED */
+#define CTC	cr62
+#define USR	cr63
+
+/*
+ * ABI dependent registers (general purpose set)
+ * Note: this set of registers name could be shared by the
+ *       CDC and RedHat toolchain
+ */
+#define RET	r2
+#define ARG1	r2
+#define ARG2	r3
+#define ARG3	r4
+#define ARG4	r5
+#define ARG5	r6
+#define ARG6	r7
+#define FBP	r14
+#define SP	r15
+#define GVDT	r26
+#define GCDT	r27
+#define LINK	r18
+#define OS	r40
+#define ZERO	r63
+
+/*
+ * Target registers need name convertion...
+ * (defines only those used by assembly code)
+ */
+#define t0	tr0
+#define t1	tr1
+#define t2	tr2
+#define t3	tr3
+#define t4	tr4
+#define t5	tr5
+#define t6	tr6
+#define t7	tr7
+
+/*
+** RedHat style compatibility macros:
+**
+**   _loada: loads the address the address  of the symbol (first
+**           argument) into the general purpose register (second
+**           argument)
+*/
+        .macro  _loada   symbol, gp_reg
+         movi   \symbol, \gp_reg
+        .endm
+
+        .macro  _ptar    symbol, tr_reg
+         pt     \symbol, \tr_reg
+        .endm
+
+        .macro  _ptaru   symbol, tr_reg
+         pt/u   \symbol, \tr_reg
+        .endm
+
+        .macro  _pta    disp_b,  tr_reg
+         pta    $+\disp_b, \tr_reg
+        .endm
+
+/*
+ * Status register defines: used only by assembly sources (and
+ * 			    syntax independednt)
+ */
+#define SR_RESET_VAL	0x0000000050008000
+#define SR_HARMLESS	0x00000000500080f0	/* Write ignores for most */
+#define SR_ENABLE_FPU	0xffffffffffff7fff	/* AND with this */
+
+#ifdef ST_DEBUG
+#define SR_ENABLE_MMU	0x0000000084000000	/* OR with this */
+#else
+#define SR_ENABLE_MMU	0x0000000080000000	/* OR with this */
+#endif
+
+#define SR_UNBLOCK_EXC	0xffffffffefffffff	/* AND with this */
+#define SR_BLOCK_EXC	0x0000000010000000	/* OR with this */
+
+#else	/* Not __ASSEMBLY__ syntax */
+
+/* =====================================================================
+** 
+** Section 2: this is required to manage __asm__ statement expanded
+**            by "C" compiler
+*/
+	/*
+	** RedHat style symbolic address resolution inside "asm" blocks
+	*/
+        asm ("\t.macro  _loada   symbol, gp_reg\n"
+             "\tmovi    \\symbol, \\gp_reg\n"
+             "\t.endm\n"
+             "\n"
+             "\t.macro  _ptar    symbol, tr_reg\n"
+             "\tpt      \\symbol, \\tr_reg\n"
+             "\t.endm\n"
+             "\n"
+             "\t.macro  _pta    disp_b, tr_reg\n"
+             "\tpta     $+\\disp_b, \\tr_reg\n"
+             "\t.endm\n"
+	     "\n"
+             "\t.macro  _fgetscr  f_reg63\n"
+	     "\tfgetscr \\f_reg63\n"
+             "\t.endm\n"
+	     "\n"
+             "\t.macro  _fputscr  f_reg63\n"
+	     "\tfputscr \\f_reg63\n"
+             "\t.endm\n"
+	     "\n"
+	    );
+
+	/*
+	** RedHat style target register name inside "asm" blocks
+	*/
+#	define __t0	__str(tr0)
+#	define __t1	__str(tr1)
+#	define __t2	__str(tr2)
+#	define __t3	__str(tr3)
+#	define __t4	__str(tr4)
+#	define __t5	__str(tr5)
+#	define __t6	__str(tr6)
+#	define __t7	__str(tr7)
+
+	/*
+	** RedHat style control register name inside "asm" blocks
+	*/
+#	define __c0	__str(cr0)		/* SR       */
+#	define __c1	__str(cr1)		/* SSR      */
+#	define __c2	__str(cr2)		/* PSSR     */
+#	define __c4	__str(cr4)		/* INTEVT   */
+#	define __c5	__str(cr5)		/* EXPEVT   */
+#	define __c6	__str(cr6)		/* PEXPEVT  */
+#	define __c8	__str(cr8)		/* SPC      */
+#	define __c9	__str(cr9)		/* PSPC     */
+#	define __c13	__str(cr13)		/* TEA      */
+#	define __c17	__str(cr17)		/* KCR0     */
+#	define __c18	__str(cr18)		/* KCR1     */
+
+	/*
+	** RedHat style float and double register name inside "asm" blocks
+	** defines below are used only in .../arch/sh5/kernel/fpu.c
+	*/
+#	define __f(x)	__str(fr##x)
+#	define __d(x)	__str(dr##x)
+
+	/*
+	** Stringify reg. name (common for CDC & RedHat)
+	*/
+#	define __str(x)  #x
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_SH64_REGISTERS_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/resource.h linux-2.4.22-pre3/include/asm-sh64/resource.h
--- linux-2.4.22-pre2/include/asm-sh64/resource.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/resource.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,47 @@
+#ifndef __ASM_SH_RESOURCE_H
+#define __ASM_SH_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
+#define RLIMIT_AS	9		/* address space limit */
+#define RLIMIT_LOCKS	10		/* maximum file locks held */
+
+#define RLIM_NLIMITS	11
+
+#ifdef __KERNEL__
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+#define INIT_RLIMITS					\
+{							\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{      _STK_LIM, RLIM_INFINITY },		\
+	{             0, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{             0,             0 },		\
+	{      INR_OPEN,     INR_OPEN  },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH_RESOURCE_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/scatterlist.h linux-2.4.22-pre3/include/asm-sh64/scatterlist.h
--- linux-2.4.22-pre2/include/asm-sh64/scatterlist.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/scatterlist.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,37 @@
+
+/*
+**
+**                      P C I  -  C O M M O N  Internal Interface
+**
+** Module:    This module includes all functions that can be used for all included
+**            bridge.
+**
+** Copyright: This file is subject to the terms and conditions of the GNU General Public
+**            License.  See the file "COPYING" in the main directory of this archive
+**            for more details.
+**
+**            Copyright (C) 2001   Roberto Giai Meniet (giai@while1.com)  
+**                                 Franco  Ometti      (ometti@while1.com) 
+**
+** File:      include/asm-sh64/scatterlist.h
+**
+** Note:      For a good view of this file use TABSTOP=8
+**
+*/
+
+#ifndef _ASM_SH64_SCATTERLIST_H
+#define _ASM_SH64_SCATTERLIST_H
+
+struct scatterlist {
+	char *address;		/* Location data is to be transferred to, NULL
+    				   for highmem page */
+	struct page *page;	/* Location for highmem page, if any */
+	unsigned int offset;	/* for highmem, page offset */
+
+	dma_addr_t dma_address;
+	unsigned int length;
+};
+
+#define ISA_DMA_THRESHOLD (0xffffffff)
+
+#endif /* _ASM_SH64_SCATTERLIST_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/segment.h linux-2.4.22-pre3/include/asm-sh64/segment.h
--- linux-2.4.22-pre2/include/asm-sh64/segment.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/segment.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,6 @@
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
+
+/* Only here because we have some old header files that expect it.. */
+
+#endif /* _ASM_SEGMENT_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/semaphore-helper.h linux-2.4.22-pre3/include/asm-sh64/semaphore-helper.h
--- linux-2.4.22-pre2/include/asm-sh64/semaphore-helper.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/semaphore-helper.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,100 @@
+#ifndef __ASM_SH64_SEMAPHORE_HELPER_H
+#define __ASM_SH64_SEMAPHORE_HELPER_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/semaphore-helper.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/*
+ * SMP- and interrupt-safe semaphores helper functions.
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ * (C) Copyright 1999 Andrea Arcangeli
+ */
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ *
+ * This is trivially done with load_locked/store_cond,
+ * which we have.  Let the rest of the losers suck eggs.
+ */
+static __inline__ void wake_one_more(struct semaphore * sem)
+{
+	atomic_inc((atomic_t *)&sem->sleepers);
+}
+
+static __inline__ int waking_non_zero(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->sleepers > 0) {
+		sem->sleepers--;
+		ret = 1;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_interruptible:
+ *	1	got the lock
+ *	0	go to sleep
+ *	-EINTR	interrupted
+ *
+ * We must undo the sem->count down_interruptible() increment while we are
+ * protected by the spinlock in order to make atomic this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+static __inline__ int waking_non_zero_interruptible(struct semaphore *sem,
+						struct task_struct *tsk)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->sleepers > 0) {
+		sem->sleepers--;
+		ret = 1;
+	} else if (signal_pending(tsk)) {
+		atomic_inc(&sem->count);
+		ret = -EINTR;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_trylock:
+ *	1	failed to lock
+ *	0	got the lock
+ *
+ * We must undo the sem->count down_trylock() increment while we are
+ * protected by the spinlock in order to make atomic this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+static __inline__ int waking_non_zero_trylock(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 1;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->sleepers <= 0)
+		atomic_inc(&sem->count);
+	else {
+		sem->sleepers--;
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+#endif /* __ASM_SH64_SEMAPHORE_HELPER_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/semaphore.h linux-2.4.22-pre3/include/asm-sh64/semaphore.h
--- linux-2.4.22-pre2/include/asm-sh64/semaphore.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/semaphore.h	2003-07-05 18:11:41.000000000 -0700
@@ -0,0 +1,139 @@
+#ifndef __ASM_SH_SEMAPHORE_H
+#define __ASM_SH_SEMAPHORE_H
+
+#include <linux/linkage.h>
+
+#ifdef __KERNEL__
+/*
+ * SMP- and interrupt-safe semaphores.
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ *
+ * SuperH verison by Niibe Yutaka
+ *  (Currently no asm implementation but generic C code...)
+ */
+
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+struct semaphore {
+	atomic_t count;
+	int sleepers;
+	wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+	long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+# define __SEM_DEBUG_INIT(name) \
+		, (int)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+	__SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INITIALIZER(name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+static inline void sema_init (struct semaphore *sem, int val)
+{
+/*
+ *	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
+ *
+ * i'd rather use the more flexible initialization above, but sadly
+ * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well.
+ */
+	atomic_set(&sem->count, val);
+	sem->sleepers = 0;
+	init_waitqueue_head(&sem->wait);
+#if WAITQUEUE_DEBUG
+	sem->__magic = (int)&sem->__magic;
+#endif
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+#if 0
+asmlinkage void __down_failed(void /* special register calling convention */);
+asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
+asmlinkage int  __down_failed_trylock(void  /* params in registers */);
+asmlinkage void __up_wakeup(void /* special register calling convention */);
+#endif
+
+asmlinkage void __down(struct semaphore * sem);
+asmlinkage int  __down_interruptible(struct semaphore * sem);
+asmlinkage int  __down_trylock(struct semaphore * sem);
+asmlinkage void __up(struct semaphore * sem);
+
+extern spinlock_t semaphore_wake_lock;
+
+static inline void down(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	if (atomic_dec_return(&sem->count) < 0)
+		__down(sem);
+}
+
+static inline int down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	if (atomic_dec_return(&sem->count) < 0)
+		ret = __down_interruptible(sem);
+	return ret;
+}
+
+static inline int down_trylock(struct semaphore * sem)
+{
+	int ret = 0;
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	if (atomic_dec_return(&sem->count) < 0)
+		ret = __down_trylock(sem);
+	return ret;
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ */
+static inline void up(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+	if (atomic_inc_return(&sem->count) <= 0)
+		__up(sem);
+}
+
+#endif
+#endif /* __ASM_SH_SEMAPHORE_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/sembuf.h linux-2.4.22-pre3/include/asm-sh64/sembuf.h
--- linux-2.4.22-pre2/include/asm-sh64/sembuf.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/sembuf.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,36 @@
+#ifndef __ASM_SH64_SEMBUF_H
+#define __ASM_SH64_SEMBUF_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/sembuf.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/* 
+ * The semid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* __ASM_SH64_SEMBUF_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/serial.h linux-2.4.22-pre3/include/asm-sh64/serial.h
--- linux-2.4.22-pre2/include/asm-sh64/serial.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/serial.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,33 @@
+/*
+ * include/asm-sh/serial.h
+ *
+ * Configuration details for 8250, 16450, 16550, etc. serial ports
+ */
+
+#ifndef _ASM_SERIAL_H
+#define _ASM_SERIAL_H
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD ( 1843200 / 16 )
+
+#define RS_TABLE_SIZE  2
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+#define STD_SERIAL_PORT_DEFNS			\
+	/* UART CLK   PORT IRQ     FLAGS        */			\
+	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
+	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }	/* ttyS1 */
+
+#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
+
+/* XXX: This should be moved ino irq.h */
+#define irq_cannonicalize(x) (x)
+
+#endif /* _ASM_SERIAL_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/shmbuf.h linux-2.4.22-pre3/include/asm-sh64/shmbuf.h
--- linux-2.4.22-pre2/include/asm-sh64/shmbuf.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/shmbuf.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,53 @@
+#ifndef __ASM_SH64_SHMBUF_H
+#define __ASM_SH64_SHMBUF_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/shmbuf.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/* 
+ * The shmid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* __ASM_SH64_SHMBUF_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/shmparam.h linux-2.4.22-pre3/include/asm-sh64/shmparam.h
--- linux-2.4.22-pre2/include/asm-sh64/shmparam.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/shmparam.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,20 @@
+#ifndef __ASM_SH64_SHMPARAM_H
+#define __ASM_SH64_SHMPARAM_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/shmparam.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <asm/cache.h>
+
+/* attach addr a multiple of this */
+#define	SHMLBA	(cpu_data->dcache.sets * L1_CACHE_BYTES)
+
+#endif /* __ASM_SH64_SHMPARAM_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/sigcontext.h linux-2.4.22-pre3/include/asm-sh64/sigcontext.h
--- linux-2.4.22-pre2/include/asm-sh64/sigcontext.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/sigcontext.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,30 @@
+#ifndef __ASM_SH64_SIGCONTEXT_H
+#define __ASM_SH64_SIGCONTEXT_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/sigcontext.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+struct sigcontext {
+	unsigned long	oldmask;
+
+	/* CPU registers */
+	unsigned long long sc_regs[63];
+	unsigned long long sc_tregs[8];
+	unsigned long long sc_pc;
+	unsigned long long sc_sr;
+
+	/* FPU registers */
+	unsigned long long sc_fpregs[32];
+	unsigned int sc_fpscr;
+	unsigned int sc_fpvalid;
+};
+
+#endif /* __ASM_SH64_SIGCONTEXT_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/siginfo.h linux-2.4.22-pre3/include/asm-sh64/siginfo.h
--- linux-2.4.22-pre2/include/asm-sh64/siginfo.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/siginfo.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,233 @@
+#ifndef __ASM_SH_SIGINFO_H
+#define __ASM_SH_SIGINFO_H
+
+#include <linux/types.h>
+
+/* XXX: This structure was copied from the Alpha; is there an iBCS version?  */
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+			sigval_t _sigval;
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			pid_t _pid;		/* which child */
+			uid_t _uid;		/* sender's uid */
+			int _status;		/* exit code */
+			clock_t _utime;
+			clock_t _stime;
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t;
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#define si_uid		_sifields._kill._uid
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+#ifdef __KERNEL__
+#define __SI_MASK	0xffff0000
+#define __SI_KILL	(0 << 16)
+#define __SI_TIMER	(1 << 16)
+#define __SI_POLL	(2 << 16)
+#define __SI_FAULT	(3 << 16)
+#define __SI_CHLD	(4 << 16)
+#define __SI_RT		(5 << 16)
+#define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
+#else
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ	-3		/* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
+#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+#define NSIGBUS		3
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
+#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
+#define NSIGTRAP	2
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+
+static inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(siginfo_t));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH_SIGINFO_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/signal.h linux-2.4.22-pre3/include/asm-sh64/signal.h
--- linux-2.4.22-pre2/include/asm-sh64/signal.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/signal.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,184 @@
+#ifndef __ASM_SH64_SIGNAL_H
+#define __ASM_SH64_SIGNAL_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/signal.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/processor.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	THREAD_SIZE
+
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+
+#define sigmask(sig)	(1UL << ((sig) - 1))
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH64_SIGNAL_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/smp.h linux-2.4.22-pre3/include/asm-sh64/smp.h
--- linux-2.4.22-pre2/include/asm-sh64/smp.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/smp.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,15 @@
+#ifndef __ASM_SH64_SMP_H
+#define __ASM_SH64_SMP_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/smp.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#endif /* __ASM_SH64_SMP_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/smplock.h linux-2.4.22-pre3/include/asm-sh64/smplock.h
--- linux-2.4.22-pre2/include/asm-sh64/smplock.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/smplock.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,77 @@
+#ifndef __ASM_SH64_SMPLOCK_H
+#define __ASM_SH64_SMPLOCK_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/smplock.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <linux/config.h>
+
+#ifndef CONFIG_SMP
+
+#define lock_kernel()				do { } while(0)
+#define unlock_kernel()				do { } while(0)
+#define release_kernel_lock(task, cpu, depth)	((depth) = 1)
+#define reacquire_kernel_lock(task, cpu, depth)	do { } while(0)
+
+#else
+
+#error "We do not support SMP on ST50 yet"
+/*
+ * Default SMP lock implementation
+ */
+
+#include <linux/interrupt.h>
+#include <asm/spinlock.h>
+
+extern spinlock_t kernel_flag;
+
+/*
+ * Getting the big kernel lock.
+ *
+ * This cannot happen asynchronously,
+ * so we only need to worry about other
+ * CPU's.
+ */
+extern __inline__ void lock_kernel(void)
+{
+	if (!++current->lock_depth)
+		spin_lock(&kernel_flag);
+}
+
+extern __inline__ void unlock_kernel(void)
+{
+	if (--current->lock_depth < 0)
+		spin_unlock(&kernel_flag);
+}
+
+/*
+ * Release global kernel lock and global interrupt lock
+ */
+#define release_kernel_lock(task, cpu) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_unlock(&kernel_flag); \
+	release_irqlock(cpu); \
+	__sti(); \
+} while (0)
+
+/*
+ * Re-acquire the kernel lock
+ */
+#define reacquire_kernel_lock(task) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_lock(&kernel_flag); \
+} while (0)
+
+#endif /* CONFIG_SMP */
+
+#endif /* __ASM_SH64_SMPLOCK_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/socket.h linux-2.4.22-pre3/include/asm-sh64/socket.h
--- linux-2.4.22-pre2/include/asm-sh64/socket.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/socket.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,64 @@
+#ifndef __ASM_SH_SOCKET_H
+#define __ASM_SH_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM	1		/* stream (connection) socket	*/
+#define SOCK_DGRAM	2		/* datagram (conn.less) socket	*/
+#define SOCK_RAW	3		/* raw socket			*/
+#define SOCK_RDM	4		/* reliably-delivered message	*/
+#define SOCK_SEQPACKET	5		/* sequential packet socket	*/
+#define SOCK_PACKET	10		/* linux specific way of	*/
+					/* getting packets at the dev	*/
+					/* level.  For writing rarp and	*/
+					/* other similar things on the	*/
+					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
+#endif
+
+#endif /* __ASM_SH_SOCKET_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/sockios.h linux-2.4.22-pre3/include/asm-sh64/sockios.h
--- linux-2.4.22-pre2/include/asm-sh64/sockios.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/sockios.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,24 @@
+#ifndef __ASM_SH64_SOCKIOS_H
+#define __ASM_SH64_SOCKIOS_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/sockios.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/* Socket-level I/O control calls. */
+#define FIOGETOWN	_IOR('f', 123, int)
+#define FIOSETOWN 	_IOW('f', 124, int)
+
+#define SIOCATMARK	_IOR('s', 7, int)
+#define SIOCSPGRP	_IOW('s', 8, pid_t)
+#define SIOCGPGRP	_IOR('s', 9, pid_t)
+
+#define SIOCGSTAMP	_IOR('s', 100, struct timeval) /* Get stamp - linux-specific */
+#endif /* __ASM_SH64_SOCKIOS_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/softirq.h linux-2.4.22-pre3/include/asm-sh64/softirq.h
--- linux-2.4.22-pre2/include/asm-sh64/softirq.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/softirq.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,30 @@
+#ifndef __ASM_SH_SOFTIRQ_H
+#define __ASM_SH_SOFTIRQ_H
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define local_bh_disable()			\
+do {						\
+	local_bh_count(smp_processor_id())++;	\
+	barrier();				\
+} while (0)
+
+#define __local_bh_enable()			\
+do {						\
+	barrier();				\
+	local_bh_count(smp_processor_id())--;	\
+} while (0)
+
+#define local_bh_enable()				\
+do {							\
+	barrier();					\
+	if (!--local_bh_count(smp_processor_id())	\
+	    && softirq_pending(smp_processor_id())) {	\
+		do_softirq();				\
+	}						\
+} while (0)
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#endif /* __ASM_SH_SOFTIRQ_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/spinlock.h linux-2.4.22-pre3/include/asm-sh64/spinlock.h
--- linux-2.4.22-pre2/include/asm-sh64/spinlock.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/spinlock.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,17 @@
+#ifndef __ASM_SH64_SPINLOCK_H
+#define __ASM_SH64_SPINLOCK_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/spinlock.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#error "No SMP on ST50"
+
+#endif /* __ASM_SH64_SPINLOCK_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/stat.h linux-2.4.22-pre3/include/asm-sh64/stat.h
--- linux-2.4.22-pre2/include/asm-sh64/stat.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/stat.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,88 @@
+#ifndef __ASM_SH64_STAT_H
+#define __ASM_SH64_STAT_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/stat.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+struct stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  __unused1;
+	unsigned long  st_mtime;
+	unsigned long  __unused2;
+	unsigned long  st_ctime;
+	unsigned long  __unused3;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned short	st_dev;
+	unsigned char	__pad0[10];
+
+	unsigned long	st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned short	st_rdev;
+	unsigned char	__pad3[10];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	__pad5;
+
+	unsigned long	st_mtime;
+	unsigned long	__pad6;
+
+	unsigned long	st_ctime;
+	unsigned long	__pad7;		/* will be high 32 bits of ctime someday */
+
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+};
+
+#endif /* __ASM_SH64_STAT_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/statfs.h linux-2.4.22-pre3/include/asm-sh64/statfs.h
--- linux-2.4.22-pre2/include/asm-sh64/statfs.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/statfs.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,36 @@
+#ifndef __ASM_SH64_STATFS_H
+#define __ASM_SH64_STATFS_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/statfs.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif /* __ASM_SH64_STATFS_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/string.h linux-2.4.22-pre3/include/asm-sh64/string.h
--- linux-2.4.22-pre2/include/asm-sh64/string.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/string.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,21 @@
+#ifndef __ASM_SH64_STRING_H
+#define __ASM_SH64_STRING_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/string.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * Empty on purpose. ARCH ST50 ASM libs are out of the current project scope.
+ *
+ */
+
+#define __HAVE_ARCH_MEMCPY
+
+extern void *memcpy(void *dest, const void *src, size_t count);
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-sh64/system.h linux-2.4.22-pre3/include/asm-sh64/system.h
--- linux-2.4.22-pre2/include/asm-sh64/system.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/system.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,405 @@
+#ifndef __ASM_SH64_SYSTEM_H
+#define __ASM_SH64_SYSTEM_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/system.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ */
+
+#include <linux/config.h>
+#include <asm/registers.h>
+
+/*
+ *	switch_to() should switch tasks to task nr n, first
+ */
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#ifdef CONFIG_SMP
+#error "no SMP SH64"
+#else
+#define prepare_to_switch()	do { } while(0)
+#ifndef CS_SAVE_ALL
+#define SAVE_CALLER_SAVED
+#define RESTORE_CALLER_SAVED
+#else
+#define SAVE_CALLER_SAVED \
+ __asm__ __volatile__("addi.l	r15, -256, r15\n\t"		\
+		      "st.q	r15, 0, r0\n\t"			\
+		      "st.q	r15, 8, r1\n\t"			\
+		      "st.q	r15, 16, r2\n\t"		\
+		      "st.q	r15, 24, r3\n\t"		\
+		      "st.q	r15, 32, r4\n\t"		\
+		      "st.q	r15, 40, r5\n\t"		\
+		      "st.q	r15, 48, r6\n\t"		\
+		      "st.q	r15, 56, r7\n\t"		\
+		      "st.q	r15, 64, r8\n\t"		\
+		      "st.q	r15, 72, r9\n\t"		\
+		      "st.q	r15, 80, r17\n\t"		\
+		      "st.q	r15, 88, r19\n\t"		\
+		      "st.q	r15, 96, r20\n\t"		\
+		      "st.q	r15, 104, r21\n\t"		\
+		      "st.q	r15, 112, r22\n\t"		\
+		      "st.q	r15, 120, r23\n\t"		\
+		      "st.q	r15, 128, r36\n\t"		\
+		      "st.q	r15, 136, r37\n\t"		\
+		      "st.q	r15, 144, r38\n\t"		\
+		      "st.q	r15, 152, r39\n\t"		\
+		      "st.q	r15, 160, r40\n\t"		\
+		      "st.q	r15, 168, r41\n\t"		\
+		      "st.q	r15, 176, r42\n\t"		\
+		      "st.q	r15, 184, r43\n\t"		\
+		      "st.q	r15, 192, r60\n\t"		\
+		      "st.q	r15, 200, r61\n\t"		\
+		      "st.q	r15, 208, r62\n\t"		\
+		      "gettr	" __t0 ", r0\n\t"			\
+		      "st.q	r15, 216, r0\n\t"		\
+		      "gettr	" __t1 ", r1\n\t"			\
+		      "st.q	r15, 224, r1\n\t"		\
+		      "gettr	" __t2 ", r2\n\t"			\
+		      "st.q	r15, 232, r2\n\t"		\
+		      "gettr	" __t3 ", r3\n\t"			\
+		      "st.q	r15, 240, r3\n\t"		\
+		      "gettr	" __t4 ", r4\n\t"			\
+		      "st.q	r15, 248, r4\n\t");
+
+/* Note. Do not restore r42 ! */
+#define RESTORE_CALLER_SAVED \
+ __asm__ __volatile__("ld.q	r15, 216, r0\n\t"		\
+		      "ptabs	r0, " __t0 "\n\t"		\
+		      "ld.q	r15, 224, r1\n\t"		\
+		      "ptabs	r1, " __t1 "\n\t"		\
+		      "ld.q	r15, 232, r2\n\t"		\
+		      "ptabs	r2, " __t2 "\n\t"		\
+		      "ld.q	r15, 240, r3\n\t"		\
+		      "ptabs	r3, " __t3 "\n\t"		\
+		      "ld.q	r15, 248, r4\n\t"		\
+		      "ptabs	r4, " __t4 "\n\t"		\
+		      "ld.q	r15, 0, r0\n\t"			\
+		      "ld.q	r15, 8, r1\n\t"			\
+		      "ld.q	r15, 16, r2\n\t"		\
+		      "ld.q	r15, 24, r3\n\t"		\
+		      "ld.q	r15, 32, r4\n\t"		\
+		      "ld.q	r15, 40, r5\n\t"		\
+		      "ld.q	r15, 48, r6\n\t"		\
+		      "ld.q	r15, 56, r7\n\t"		\
+		      "ld.q	r15, 64, r8\n\t"		\
+		      "ld.q	r15, 72, r9\n\t"		\
+		      "ld.q	r15, 80, r17\n\t"		\
+		      "ld.q	r15, 88, r19\n\t"		\
+		      "ld.q	r15, 96, r20\n\t"		\
+		      "ld.q	r15, 104, r21\n\t"		\
+		      "ld.q	r15, 112, r22\n\t"		\
+		      "ld.q	r15, 120, r23\n\t"		\
+		      "ld.q	r15, 128, r36\n\t"		\
+		      "ld.q	r15, 136, r37\n\t"		\
+		      "ld.q	r15, 144, r38\n\t"		\
+		      "ld.q	r15, 152, r39\n\t"		\
+		      "ld.q	r15, 160, r40\n\t"		\
+		      "ld.q	r15, 168, r41\n\t"		\
+		      "ld.q	r15, 184, r43\n\t"		\
+		      "ld.q	r15, 192, r60\n\t"		\
+		      "ld.q	r15, 200, r61\n\t"		\
+		      "ld.q	r15, 208, r62\n\t"		\
+		      "addi.l	r15, 256, r15\n\t");
+#endif
+
+#define switch_to(prev,next,last) do { \
+ register unsigned long *      r36 __asm__ ("r36");		\
+ register unsigned long *      r37 __asm__ ("r37");		\
+ register unsigned long long   r38 __asm__ ("r38");		\
+ register unsigned long long   r39 __asm__ ("r39");		\
+ register unsigned long *      r40 __asm__ ("r40");		\
+ register unsigned long *      r41 __asm__ ("r41");		\
+ register struct task_struct * r42 __asm__ ("r42");		\
+								\
+/* printk("switch_to prev %08x next %08x last %08x\n", prev, next,last);  */ \
+ if (last_task_used_math != next) {				\
+  struct pt_regs* regs;						\
+  regs = next->thread.kregs;                                    \
+  regs->sr |= SR_FD;						\
+ }								\
+								\
+ SAVE_CALLER_SAVED						\
+								\
+ r36 = &prev->thread.sp;					\
+ r37 = &prev->thread.pc;					\
+								\
+ /* Note that we always are in kernel space */			\
+ r38 = next->thread.sp | NEFF_MASK;				\
+ r39 = next->thread.pc | NEFF_MASK;				\
+								\
+ r40 = (unsigned long *) prev;					\
+ r41 = (unsigned long *) next;					\
+								\
+ __asm__ __volatile__("addi.l	r15, -304, r15\n\t"		\
+		      "st.q	r15, 0, r10\n\t"		\
+		      "st.q	r15, 8, r11\n\t"		\
+		      "st.q	r15, 16, r12\n\t"		\
+		      "st.q	r15, 24, r13\n\t"		\
+		      "st.q	r15, 32, r14\n\t"		\
+		      "st.q	r15, 40, r16\n\t"		\
+		      "st.q	r15, 48, r18\n\t"		\
+		      "st.q	r15, 56, r24\n\t"		\
+		      "st.q	r15, 64, r25\n\t"		\
+		      "st.q	r15, 72, r26\n\t"		\
+		      "st.q	r15, 80, r27\n\t"		\
+		      "st.q	r15, 88, r28\n\t"		\
+		      "st.q	r15, 96, r29\n\t"		\
+		      "st.q	r15, 104, r30\n\t"		\
+		      "st.q	r15, 112, r31\n\t"		\
+		      "st.q	r15, 120, r32\n\t"		\
+		      "st.q	r15, 128, r33\n\t"		\
+		      "st.q	r15, 136, r34\n\t"		\
+		      "st.q	r15, 144, r35\n\t"		\
+		      "st.q	r15, 152, r44\n\t"		\
+		      "st.q	r15, 160, r45\n\t"		\
+		      "st.q	r15, 168, r46\n\t"		\
+		      "st.q	r15, 176, r47\n\t"		\
+		      "st.q	r15, 184, r48\n\t"		\
+		      "st.q	r15, 192, r49\n\t"		\
+		      "st.q	r15, 200, r50\n\t"		\
+		      "st.q	r15, 208, r51\n\t"		\
+		      "st.q	r15, 216, r52\n\t"		\
+		      "st.q	r15, 224, r53\n\t"		\
+		      "st.q	r15, 232, r54\n\t"		\
+		      "st.q	r15, 240, r55\n\t"		\
+		      "st.q	r15, 248, r56\n\t"		\
+		      "st.q	r15, 256, r57\n\t"		\
+		      "st.q	r15, 264, r58\n\t"		\
+		      "st.q	r15, 272, r59\n\t"		\
+		      "gettr	" __t5 ", r55\n\t"		\
+		      "st.q	r15, 280, r55\n\t"		\
+		      "gettr	" __t6 ", r56\n\t"		\
+		      "st.q	r15, 288, r56\n\t"		\
+		      "gettr	" __t7 ", r57\n\t"		\
+		      "st.q	r15, 296, r57\n\t"		\
+		      "_loada	__switch_to, r18\n\t"  \
+		      "ptabs	r18, " __t5 "\n\t"		\
+		      "_pta	36, " __t6 "\n\t"		\
+		      "gettr	" __t6 ", r18\n\t"		\
+		      "st.l	%1, 0, r15\n\t"			\
+		      "st.l	%2, 0, r18\n\t"			\
+		      "or	%3, r63, r15\n\t"		\
+		      "or	%4, r63, r18\n\t"		\
+		      "or	%5, r63, r2\n\t"		\
+		      "or	%6, r63, r3\n\t"		\
+		      "blink	" __t5 ", r63\n\t"		\
+                      "or       r2, r63, %0\n\t"                \
+		      "ld.q	r15, 280, r55\n\t"		\
+		      "ptabs	r55, " __t5 "\n\t"		\
+		      "ld.q	r15, 288, r56\n\t"		\
+		      "ptabs	r56, " __t6 "\n\t"		\
+		      "ld.q	r15, 296, r57\n\t"		\
+		      "ptabs	r57, " __t7 "\n\t"		\
+		      "ld.q	r15, 0, r10\n\t"		\
+		      "ld.q	r15, 8, r11\n\t"		\
+		      "ld.q	r15, 16, r12\n\t"		\
+		      "ld.q	r15, 24, r13\n\t"		\
+		      "ld.q	r15, 32, r14\n\t"		\
+		      "ld.q	r15, 40, r16\n\t"		\
+		      "ld.q	r15, 48, r18\n\t"		\
+		      "ld.q	r15, 56, r24\n\t"		\
+		      "ld.q	r15, 64, r25\n\t"		\
+		      "ld.q	r15, 72, r26\n\t"		\
+		      "ld.q	r15, 80, r27\n\t"		\
+		      "ld.q	r15, 88, r28\n\t"		\
+		      "ld.q	r15, 96, r29\n\t"		\
+		      "ld.q	r15, 104, r30\n\t"		\
+		      "ld.q	r15, 112, r31\n\t"		\
+		      "ld.q	r15, 120, r32\n\t"		\
+		      "ld.q	r15, 128, r33\n\t"		\
+		      "ld.q	r15, 136, r34\n\t"		\
+		      "ld.q	r15, 144, r35\n\t"		\
+		      "ld.q	r15, 152, r44\n\t"		\
+		      "ld.q	r15, 160, r45\n\t"		\
+		      "ld.q	r15, 168, r46\n\t"		\
+		      "ld.q	r15, 176, r47\n\t"		\
+		      "ld.q	r15, 184, r48\n\t"		\
+		      "ld.q	r15, 192, r49\n\t"		\
+		      "ld.q	r15, 200, r50\n\t"		\
+		      "ld.q	r15, 208, r51\n\t"		\
+		      "ld.q	r15, 216, r52\n\t"		\
+		      "ld.q	r15, 224, r53\n\t"		\
+		      "ld.q	r15, 232, r54\n\t"		\
+		      "ld.q	r15, 240, r55\n\t"		\
+		      "ld.q	r15, 248, r56\n\t"		\
+		      "ld.q	r15, 256, r57\n\t"		\
+		      "ld.q	r15, 264, r58\n\t"		\
+		      "ld.q	r15, 272, r59\n\t"		\
+		      "addi.l	r15, 304, r15\n\t"		\
+		      : "=r" (r42)				\
+		      : "r" (r36), "r" (r37), "r" (r38),	\
+			"r" (r39), "r" (r40), "r" (r41));	\
+ RESTORE_CALLER_SAVED						\
+  last = r42;							\
+} while (0)
+#endif
+
+#define nop() __asm__ __volatile__ ("nop")
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+#define tas(ptr) (xchg((ptr), 1))
+
+extern void __xchg_called_with_bad_pointer(void);
+
+#define mb()	__asm__ __volatile__ ("synco": : :"memory")
+#define rmb()	mb()
+#define wmb()	__asm__ __volatile__ ("synco": : :"memory")
+#define set_rmb(var, value) do { xchg(&var, value); } while (0)
+#define set_mb(var, value) set_rmb(var, value)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
+/* Interrupt Control */
+#ifndef HARD_CLI
+#define SR_MASK_L 0x000000f0L
+#define SR_MASK_LL 0x00000000000000f0LL
+#else
+#define SR_MASK_L 0x10000000L
+#define SR_MASK_LL 0x0000000010000000LL
+#endif
+
+extern __inline__ void __sti(void)
+{
+	/* cli/sti based on SR.BL */
+	unsigned long long __dummy0, __dummy1=~SR_MASK_LL;
+
+	__asm__ __volatile__("getcon	" __c0 ", %0\n\t"
+			     "and	%0, %1, %0\n\t"
+			     "putcon	%0, " __c0 "\n\t"
+			     : "=&r" (__dummy0)
+			     : "r" (__dummy1));
+}
+
+extern __inline__ void __cli(void)
+{
+	/* cli/sti based on SR.BL */
+	unsigned long long __dummy0, __dummy1=SR_MASK_LL;
+	__asm__ __volatile__("getcon	" __c0 ", %0\n\t"
+			     "or	%0, %1, %0\n\t"
+			     "putcon	%0, " __c0 "\n\t"
+			     : "=&r" (__dummy0)
+			     : "r" (__dummy1));
+}
+
+#define __save_flags(x) 						\
+(__extension__ ({	unsigned long long __dummy=SR_MASK_LL;		\
+	__asm__ __volatile__(						\
+		"getcon	" __c0 ", %0\n\t"				\
+		"and	%0, %1, %0"					\
+		: "=&r" (x)						\
+		: "r" (__dummy));}))
+
+#define __save_and_cli(x)    							\
+(__extension__ ({	unsigned long long __d2=SR_MASK_LL, __d1;	\
+	__asm__ __volatile__(          	         			\
+		"getcon	" __c0 ", %1\n\t" 				\
+		"or	%1, r63, %0\n\t"				\
+		"or	%1, %2, %1\n\t"					\
+		"putcon	%1, " __c0 "\n\t"    				\
+		"and	%0, %2, %0"    					\
+		: "=&r" (x), "=&r" (__d1)				\
+		: "r" (__d2));}));
+
+#define __restore_flags(x) do { 					\
+	if ( ((x) & SR_MASK_L) == 0 )		/* dropping to 0 ? */	\
+		__sti();			/* yes...re-enable */	\
+} while (0)
+
+#define __save_and_sti(x)	do { __save_flags(x); __sti(); } while (0)
+
+/* For spinlocks etc */
+#define local_irq_save(x)	__save_and_cli(x)
+#define local_irq_set(x)	__save_and_sti(x)
+#define local_irq_restore(x)	__restore_flags(x)
+#define local_irq_disable()	__cli()
+#define local_irq_enable()	__sti()
+
+#ifdef CONFIG_SMP
+
+extern void __global_cli(void);
+extern void __global_sti(void);
+extern unsigned long __global_save_flags(void);
+extern void __global_restore_flags(unsigned long);
+#define cli() __global_cli()
+#define sti() __global_sti()
+#define save_flags(x) ((x)=__global_save_flags())
+#define restore_flags(x) __global_restore_flags(x)
+#define save_and_sti(x) do { save_flags(x); sti(x); } while (0)
+
+#else
+
+#define cli() __cli()
+#define sti() __sti()
+#define save_flags(x) __save_flags(x)
+#define save_and_cli(x) __save_and_cli(x)
+#define restore_flags(x) __restore_flags(x)
+#define save_and_sti(x) __save_and_sti(x)
+
+#endif
+
+extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
+{
+	unsigned long flags, retval;
+
+	save_and_cli(flags);
+	retval = *m;
+	*m = val;
+	restore_flags(flags);
+	return retval;
+}
+
+extern __inline__ unsigned long xchg_u8(volatile unsigned char * m, unsigned long val)
+{
+	unsigned long flags, retval;
+
+	save_and_cli(flags);
+	retval = *m;
+	*m = val & 0xff;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+	switch (size) {
+	case 4:
+		return xchg_u32(ptr, x);
+		break;
+	case 1:
+		return xchg_u8(ptr, x);
+		break;
+	}
+	__xchg_called_with_bad_pointer();
+	return x;
+}
+
+/* XXX
+ * disable hlt during certain critical i/o operations
+ */
+#define HAVE_DISABLE_HLT
+void disable_hlt(void);
+void enable_hlt(void);
+
+
+#define smp_mb()        barrier()
+#define smp_rmb()       barrier()
+#define smp_wmb()       barrier()
+
+extern void print_seg(char *file,int line);
+
+#define PLS() print_seg(__FILE__,__LINE__) 
+
+#define PL() printk("@ <%s,%s:%d>\n",__FILE__,__FUNCTION__,__LINE__)
+
+#endif /* __ASM_SH64_SYSTEM_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/termbits.h linux-2.4.22-pre3/include/asm-sh64/termbits.h
--- linux-2.4.22-pre2/include/asm-sh64/termbits.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/termbits.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,183 @@
+#ifndef __ASM_SH64_TERMBITS_H
+#define __ASM_SH64_TERMBITS_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/termbits.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR	  010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* __ASM_SH64_TERMBITS_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/termios.h linux-2.4.22-pre3/include/asm-sh64/termios.h
--- linux-2.4.22-pre2/include/asm-sh64/termios.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/termios.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,118 @@
+#ifndef __ASM_SH64_TERMIOS_H
+#define __ASM_SH64_TERMIOS_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/termios.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IR - http://www.cs.uit.no/~dagb/irda/irda.html */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14
+#define N_HCI		15	/* Last slot for HCI UART */
+#define N_HCI		15	/* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/*	intr=^C		quit=^\		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+	unsigned short __tmp; \
+	get_user(__tmp,&(termio)->x); \
+	*(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif	/* __ASM_SH64_TERMIOS_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/timex.h linux-2.4.22-pre3/include/asm-sh64/timex.h
--- linux-2.4.22-pre2/include/asm-sh64/timex.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/timex.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,36 @@
+#ifndef __ASM_SH64_TIMEX_H
+#define __ASM_SH64_TIMEX_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/timex.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ * sh-5 architecture timex specifications
+ *
+ */
+
+#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+typedef unsigned long cycles_t;
+
+extern cycles_t cacheflush_time;
+
+static __inline__ cycles_t get_cycles (void)
+{
+	return 0;
+}
+
+#define vxtime_lock()		do {} while (0)
+#define vxtime_unlock()		do {} while (0)
+
+#endif /* __ASM_SH64_TIMEX_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/tlb.h linux-2.4.22-pre3/include/asm-sh64/tlb.h
--- linux-2.4.22-pre2/include/asm-sh64/tlb.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/tlb.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,95 @@
+/*
+ * include/asm-sh64/tlb.h
+ *
+ * Copyright (C) 2003  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */ 
+#ifndef __ASM_SH64_TLB_H
+#define __ASM_SH64_TLB_H
+
+/*
+ * Note! These are mostly unused, we just need the xTLB_LAST_VAR_UNRESTRICTED
+ * for head.S! Once this limitation is gone, we can clean the rest of this up.
+ */
+
+/* ITLB defines */
+#define ITLB_FIXED	0x00000000	/* First fixed ITLB, see head.S */
+#define ITLB_LAST_VAR_UNRESTRICTED	0x000003F0	/* Last ITLB */
+
+/* DTLB defines */
+#define DTLB_FIXED	0x00800000	/* First fixed DTLB, see head.S */
+#define DTLB_LAST_VAR_UNRESTRICTED	0x008003F0	/* Last DTLB */
+
+#ifndef __ASSEMBLY__
+
+#include <asm-generic/tlb.h>
+
+/*
+ * TLB information structure
+ *
+ * Defined for both I and D tlb, per-processor.
+ */
+struct tlb_info {
+	unsigned long long next;
+	unsigned long long first;
+	unsigned long long last;
+
+	unsigned int entries;
+	unsigned int step;
+
+	unsigned long flags;
+};
+
+/**
+ * for_each_dtlb_entry
+ *
+ * @tlb:	TLB entry
+ *
+ * Iterate over free (non-wired) DTLB entries
+ */
+#define for_each_dtlb_entry(tlb)		\
+	for (tlb  = cpu_data->dtlb.first;	\
+	     tlb <= cpu_data->dtlb.last;	\
+	     tlb += cpu_data->dtlb.step)
+
+/**
+ * for_each_itlb_entry
+ *
+ * @tlb:	TLB entry
+ *
+ * Iterate over free (non-wired) ITLB entries
+ */
+#define for_each_itlb_entry(tlb)		\
+	for (tlb  = cpu_data->itlb.first;	\
+	     tlb <= cpu_data->itlb.last;	\
+	     tlb += cpu_data->itlb.step)
+
+/**
+ * __flush_tlb_slot
+ *
+ * @slot:	Address of TLB slot.
+ *
+ * Flushes TLB slot @slot.
+ */
+static inline void __flush_tlb_slot(unsigned long long slot)
+{
+	__asm__ __volatile__ ("putcfg %0, 0, r63\n" : : "r" (slot));
+}
+
+/* arch/sh64/mm/tlb.c */
+extern int sh64_tlb_init(void);
+extern unsigned long long sh64_next_free_dtlb_entry(void);
+extern unsigned long long sh64_get_wired_dtlb_entry(void);
+extern int sh64_put_wired_dtlb_entry(unsigned long long entry);
+
+extern void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr, unsigned long asid, unsigned long paddr);
+extern void sh64_teardown_tlb_slot(unsigned long long config_addr);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_SH64_TLB_H */
+
diff -urN linux-2.4.22-pre2/include/asm-sh64/types.h linux-2.4.22-pre3/include/asm-sh64/types.h
--- linux-2.4.22-pre2/include/asm-sh64/types.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/types.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,66 @@
+#ifndef __ASM_SH64_TYPES_H
+#define __ASM_SH64_TYPES_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/types.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef __signed__ char s8;
+typedef unsigned char u8;
+
+typedef __signed__ short s16;
+typedef unsigned short u16;
+
+typedef __signed__ int s32;
+typedef unsigned int u32;
+
+typedef __signed__ long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* DMA addresses come in generic and 64-bit flavours.  */
+
+#ifdef CONFIG_HIGHMEM64G
+typedef u64 dma_addr_t;
+#else
+typedef u32 dma_addr_t;
+#endif
+typedef u64 dma64_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH64_TYPES_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/uaccess.h linux-2.4.22-pre3/include/asm-sh64/uaccess.h
--- linux-2.4.22-pre2/include/asm-sh64/uaccess.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/uaccess.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,288 @@
+#ifndef __ASM_SH64_UACCESS_H
+#define __ASM_SH64_UACCESS_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/uaccess.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * User space memory access functions
+ *
+ * Copyright (C) 1999  Niibe Yutaka
+ *
+ *  Based on:
+ *     MIPS implementation version 1.15 by
+ *              Copyright (C) 1996, 1997, 1998 by Ralf Baechle
+ *     and i386 version.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not.  If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons (Data Segment Register?), these macros are misnamed.
+ */
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+
+#define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFF)
+#define USER_DS		MAKE_MM_SEG(0x80000000)
+
+#define get_ds()	(KERNEL_DS)
+#define get_fs()        (current->addr_limit)
+#define set_fs(x)       (current->addr_limit=(x))
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#define __addr_ok(addr) ((unsigned long)(addr) < (current->addr_limit.seg))
+
+/*
+ * Uhhuh, this needs 33-bit arithmetic. We have a carry..
+ *
+ * sum := addr + size;  carry? --> flag = true;
+ * if (sum >= addr_limit) flag = true;
+ */
+#define __range_ok(addr,size) (((unsigned long) (addr) + (size) < (current->addr_limit.seg)) ? 0 : 1)
+
+#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
+#define __access_ok(addr,size) (__range_ok(addr,size) == 0)
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size) ? 0 : -EFAULT;
+}
+
+/*
+ * Uh, these should become the main single-value transfer routines ...
+ * They automatically use the right size if we just have the right
+ * pointer type ...
+ *
+ * As MIPS uses the same address space for kernel and user data, we
+ * can just do these as direct assignments.
+ *
+ * Careful to not
+ * (a) re-use the arguments for side effects (sizeof is ok)
+ * (b) require any knowledge of processes at this stage
+ */
+#define put_user(x,ptr)	__put_user_check((x),(ptr),sizeof(*(ptr)))
+#define get_user(x,ptr) __get_user_check((x),(ptr),sizeof(*(ptr)))
+
+/*
+ * The "__xxx" versions do not do address space checking, useful when
+ * doing multiple accesses to the same area (the user has to do the
+ * checks by hand with "access_ok()")
+ */
+#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+
+/*
+ * The "xxx_ret" versions return constant specified in third argument, if
+ * something bad happens. These macros can be optimized for the
+ * case of just returning from the function xxx_ret is used.
+ */
+
+#define put_user_ret(x,ptr,ret) ({ \
+if (put_user(x,ptr)) return ret; })
+
+#define get_user_ret(x,ptr,ret) ({ \
+if (get_user(x,ptr)) return ret; })
+
+#define __put_user_ret(x,ptr,ret) ({ \
+if (__put_user(x,ptr)) return ret; })
+
+#define __get_user_ret(x,ptr,ret) ({ \
+if (__get_user(x,ptr)) return ret; })
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) (*(struct __large_struct *)(x))
+
+#define __get_user_nocheck(x,ptr,size) ({ \
+long __gu_err; \
+__typeof(*(ptr)) __gu_val; \
+long __gu_addr; \
+__asm__("":"=r" (__gu_val)); \
+__asm__("":"=r" (__gu_err)); \
+__gu_addr = (long) (ptr); \
+switch (size) { \
+case 1: __gu_err = __get_user_asm_b((void *) &__gu_val, __gu_addr); break; \
+case 2: __gu_err = __get_user_asm_w((void *) &__gu_val, __gu_addr); break; \
+case 4: __gu_err = __get_user_asm_l((void *) &__gu_val, __gu_addr); break; \
+case 8: __gu_err = __get_user_asm_q((void *) &__gu_val, __gu_addr); break; \
+default: __get_user_unknown(); break; \
+} x = (__typeof__(*(ptr))) __gu_val; __gu_err; })
+
+#define __get_user_check(x,ptr,size) ({ \
+long __gu_err; \
+__typeof(*(ptr)) __gu_val; \
+long __gu_addr; \
+__asm__("":"=r" (__gu_val)); \
+__asm__("":"=r" (__gu_err)); \
+__gu_addr = (long) (ptr); \
+if (__access_ok(__gu_addr,size)) { \
+switch (size) { \
+case 1: __gu_err = __get_user_asm_b((void *) &__gu_val, __gu_addr); break; \
+case 2: __gu_err = __get_user_asm_w((void *) &__gu_val, __gu_addr); break; \
+case 4: __gu_err = __get_user_asm_l((void *) &__gu_val, __gu_addr); break; \
+case 8: __gu_err = __get_user_asm_q((void *) &__gu_val, __gu_addr); break; \
+default: __get_user_unknown(); break; \
+} } x = (__typeof__(*(ptr))) __gu_val; __gu_err; })
+
+extern long __get_user_asm_b(void *, long);
+extern long __get_user_asm_w(void *, long);
+extern long __get_user_asm_l(void *, long);
+extern long __get_user_asm_q(void *, long);
+extern void __get_user_unknown(void);
+
+#define __put_user_nocheck(x,ptr,size) ({ \
+long __pu_err; \
+__typeof__(*(ptr)) __pu_val; \
+long __pu_addr; \
+__pu_val = (x); \
+__pu_addr = (long) (ptr); \
+__asm__("":"=r" (__pu_err)); \
+switch (size) { \
+case 1: __pu_err = __put_user_asm_b((void *) &__pu_val, __pu_addr); break; \
+case 2: __pu_err = __put_user_asm_w((void *) &__pu_val, __pu_addr); break; \
+case 4: __pu_err = __put_user_asm_l((void *) &__pu_val, __pu_addr); break; \
+case 8: __pu_err = __put_user_asm_q((void *) &__pu_val, __pu_addr); break; \
+default: __put_user_unknown(); break; \
+} __pu_err; })
+
+#define __put_user_check(x,ptr,size) ({ \
+long __pu_err; \
+__typeof__(*(ptr)) __pu_val; \
+long __pu_addr; \
+__pu_val = (x); \
+__pu_addr = (long) (ptr); \
+__asm__("":"=r" (__pu_err)); \
+if (__access_ok(__pu_addr,size)) { \
+switch (size) { \
+case 1: __pu_err = __put_user_asm_b((void *) &__pu_val, __pu_addr); break; \
+case 2: __pu_err = __put_user_asm_w((void *) &__pu_val, __pu_addr); break; \
+case 4: __pu_err = __put_user_asm_l((void *) &__pu_val, __pu_addr); break; \
+case 8: __pu_err = __put_user_asm_q((void *) &__pu_val, __pu_addr); break; \
+default: __put_user_unknown(); break; \
+} } __pu_err; })
+
+extern long __put_user_asm_b(void *, long);
+extern long __put_user_asm_w(void *, long);
+extern long __put_user_asm_l(void *, long);
+extern long __put_user_asm_q(void *, long);
+extern void __put_user_unknown(void);
+
+
+/* Generic arbitrary sized copy.  */
+/* Return the number of bytes NOT copied */
+/* XXX: should be such that: 4byte and the rest. */
+extern __kernel_size_t __copy_user(void *__to, const void *__from, __kernel_size_t __n);
+
+#define copy_to_user(to,from,n) ({ \
+void *__copy_to = (void *) (to); \
+__kernel_size_t __copy_size = (__kernel_size_t) (n); \
+__kernel_size_t __copy_res; \
+if(__copy_size && __access_ok((unsigned long)__copy_to, __copy_size)) { \
+__copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \
+} else __copy_res = __copy_size; \
+__copy_res; })
+
+#define copy_to_user_ret(to,from,n,retval) ({ \
+if (copy_to_user(to,from,n)) \
+	return retval; \
+})
+
+#define __copy_to_user(to,from,n)		\
+	__copy_user((void *)(to),		\
+		    (void *)(from), n)
+
+#define __copy_to_user_ret(to,from,n,retval) ({ \
+if (__copy_to_user(to,from,n)) \
+	return retval; \
+})
+
+#define copy_from_user(to,from,n) ({ \
+void *__copy_to = (void *) (to); \
+void *__copy_from = (void *) (from); \
+__kernel_size_t __copy_size = (__kernel_size_t) (n); \
+__kernel_size_t __copy_res; \
+if(__copy_size && __access_ok((unsigned long)__copy_from, __copy_size)) { \
+__copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \
+} else __copy_res = __copy_size; \
+__copy_res; })
+
+#define copy_from_user_ret(to,from,n,retval) ({ \
+if (copy_from_user(to,from,n)) \
+	return retval; \
+})
+
+#define __copy_from_user(to,from,n)		\
+	__copy_user((void *)(to),		\
+		    (void *)(from), n)
+
+#define __copy_from_user_ret(to,from,n,retval) ({ \
+if (__copy_from_user(to,from,n)) \
+	return retval; \
+})
+
+/* XXX: Not sure it works well..
+   should be such that: 4byte clear and the rest. */
+extern __kernel_size_t __clear_user(void *addr, __kernel_size_t size);
+
+#define clear_user(addr,n) ({ \
+void * __cl_addr = (addr); \
+unsigned long __cl_size = (n); \
+if (__cl_size && __access_ok(((unsigned long)(__cl_addr)), __cl_size)) \
+__cl_size = __clear_user(__cl_addr, __cl_size); \
+__cl_size; })
+
+extern int __strncpy_from_user(unsigned long __dest, unsigned long __src, int __count);
+
+#define strncpy_from_user(dest,src,count) ({ \
+unsigned long __sfu_src = (unsigned long) (src); \
+int __sfu_count = (int) (count); \
+long __sfu_res = -EFAULT; \
+if(__access_ok(__sfu_src, __sfu_count)) { \
+__sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count); \
+} __sfu_res; })
+
+#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+
+/*
+ * Return the size of a string (including the ending 0!)
+ */
+extern long __strnlen_user(const char *__s, long __n);
+
+extern __inline__ long strnlen_user(const char *s, long n)
+{
+	if (!__addr_ok(s))
+		return 0;
+	else
+		return __strnlen_user(s, n);
+}
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup.unit otherwise.  */
+extern unsigned long search_exception_table(unsigned long addr);
+
+/* Returns the new pc */
+#define fixup_exception(map_reg, fixup_unit, pc)                \
+({                                                              \
+	fixup_unit;                                             \
+})
+
+#endif /* __ASM_SH64_UACCESS_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/ucontext.h linux-2.4.22-pre3/include/asm-sh64/ucontext.h
--- linux-2.4.22-pre2/include/asm-sh64/ucontext.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/ucontext.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,23 @@
+#ifndef __ASM_SH64_UCONTEXT_H
+#define __ASM_SH64_UCONTEXT_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/ucontext.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* __ASM_SH64_UCONTEXT_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/unaligned.h linux-2.4.22-pre3/include/asm-sh64/unaligned.h
--- linux-2.4.22-pre2/include/asm-sh64/unaligned.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/unaligned.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,30 @@
+#ifndef __ASM_SH64_UNALIGNED_H
+#define __ASM_SH64_UNALIGNED_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/unaligned.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * SH can't handle unaligned accesses.
+ *
+ */
+
+#include <linux/string.h>
+
+
+/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
+
+#define get_unaligned(ptr) \
+  ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
+
+#define put_unaligned(val, ptr)				\
+  ({ __typeof__(*(ptr)) __tmp = (val);			\
+     memmove((ptr), &__tmp, sizeof(*(ptr)));		\
+     (void)0; })
+
+#endif /* __ASM_SH64_UNALIGNED_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/unistd.h linux-2.4.22-pre3/include/asm-sh64/unistd.h
--- linux-2.4.22-pre2/include/asm-sh64/unistd.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/unistd.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,416 @@
+#ifndef __ASM_SH64_UNISTD_H
+#define __ASM_SH64_UNISTD_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/unistd.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * This file contains the system call numbers.
+ *
+ */
+
+#define __NR_setup		  0	/* used only by init, to get system going */
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_lchown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit	 	 76	/* Back compatible 2Gig limited rlimit */
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102	/* old implementation of socket systemcall */
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		110
+#define __NR_vhangup		111
+#define __NR_idle		112
+#define __NR_vm86old		113
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_modify_ldt		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_vm86		166
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl              172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_chown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_streams1		188	/* some people actually want it */
+#define __NR_streams2		189	/* some people actually want it */
+#define __NR_vfork		190
+#define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_lchown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+#define __NR_mincore		218
+#define __NR_madvise		219
+#define __NR_socket		220	/* New socket system calls implementation */
+#define __NR_bind		221
+#define __NR_connect		222
+#define __NR_listen		223
+#define __NR_accept		224
+#define __NR_getsockname	225
+#define __NR_getpeername	226
+#define __NR_socketpair		227
+#define __NR_send		228
+#define __NR_sendto		229
+#define __NR_recv		230
+#define __NR_recvfrom		231
+#define __NR_shutdown		232
+#define __NR_setsockopt		233
+#define __NR_getsockopt		234
+#define __NR_sendmsg		235
+#define __NR_recvmsg		236
+#define __NR_semop		237	/* New ipc system calls implementation */
+#define __NR_semget		238
+#define __NR_semctl		239
+#define __NR_msgsnd		240
+#define __NR_msgrcv		241
+#define __NR_msgget		242
+#define __NR_msgctl		243
+#define __NR_shmatcall		244
+#define __NR_shmdt		245
+#define __NR_shmget		246
+#define __NR_shmctl		247
+
+
+/* user-visible error numbers are in the range -1 - -125: see <asm-sh64/errno.h> */
+
+#define __syscall_return(type, res) \
+do { \
+	/* Note: when returning from kernel the return value is in r9	    \
+	**       This prevents conflicts between return value and arg1      \
+	**       when dispatching signal handler, in other words makes	    \
+	**       life easier in the system call epilogue (see entry.S)      \
+	*/								    \
+        register unsigned long __sr2 __asm__ ("r2") = res;		    \
+	if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+		errno = -(res);						    \
+		__sr2 = -1; 						    \
+	} \
+	return (type) (__sr2); 						    \
+} while (0)
+
+/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+register unsigned long __sc0 __asm__ ("r9") = ((0x10 << 16) | __NR_##name); \
+__asm__ __volatile__ ("trapa	%1" \
+	: "=r" (__sc0) 							    \
+	: "r" (__sc0) ); 						    \
+__syscall_return(type,__sc0); 						    \
+}
+
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+register unsigned long __sc0 __asm__ ("r9") = ((0x11 << 16) | __NR_##name); \
+register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1;	    \
+__asm__ __volatile__ ("trapa	%1" \
+	: "=r" (__sc0) 							    \
+	: "r" (__sc0), "r" (__sc2));					    \
+__syscall_return(type,__sc0); 						    \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+register unsigned long __sc0 __asm__ ("r9") = ((0x12 << 16) | __NR_##name); \
+register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1;	    \
+register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2;	    \
+__asm__ __volatile__ ("trapa	%1" \
+	: "=r" (__sc0) 							    \
+	: "r" (__sc0), "r" (__sc2), "r" (__sc3) );			    \
+__syscall_return(type,__sc0); 						    \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_##name); \
+register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1;	    \
+register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2;	    \
+register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3;	    \
+__asm__ __volatile__ ("trapa	%1" \
+	: "=r" (__sc0) 							    \
+	: "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) );		    \
+__syscall_return(type,__sc0); 						    \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+register unsigned long __sc0 __asm__ ("r9") = ((0x14 << 16) | __NR_##name); \
+register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1;	    \
+register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2;	    \
+register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3;	    \
+register unsigned long __sc5 __asm__ ("r5") = (unsigned long) arg4;	    \
+__asm__ __volatile__ ("trapa	%1" \
+	: "=r" (__sc0) 							    \
+	: "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5) );\
+__syscall_return(type,__sc0); 						    \
+}
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
+{ \
+register unsigned long __sc0 __asm__ ("r9") = ((0x15 << 16) | __NR_##name); \
+register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1;	    \
+register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2;	    \
+register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3;	    \
+register unsigned long __sc5 __asm__ ("r5") = (unsigned long) arg4;	    \
+register unsigned long __sc6 __asm__ ("r6") = (unsigned long) arg5;	    \
+__asm__ __volatile__ ("trapa	%1" \
+	: "=r" (__sc0) 							    \
+	: "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5), \
+	  "r" (__sc6));							    \
+__syscall_return(type,__sc0); 						    \
+}
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5, type6, arg6) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
+{ \
+register unsigned long __sc0 __asm__ ("r9") = ((0x16 << 16) | __NR_##name); \
+register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1;	    \
+register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2;	    \
+register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3;	    \
+register unsigned long __sc5 __asm__ ("r5") = (unsigned long) arg4;	    \
+register unsigned long __sc6 __asm__ ("r6") = (unsigned long) arg5;	    \
+register unsigned long __sc7 __asm__ ("r7") = (unsigned long) arg6;	    \
+__asm__ __volatile__ ("trapa	%1" \
+	: "=r" (__sc0) 							    \
+	: "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5), \
+	  "r" (__sc6), "r" (__sc7));					    \
+__syscall_return(type,__sc0); 						    \
+}
+
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static __inline__ _syscall0(int,pause)
+static __inline__ _syscall1(int,setup,int,magic)
+static __inline__ _syscall0(int,sync)
+static __inline__ _syscall0(pid_t,setsid)
+static __inline__ _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static __inline__ _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static __inline__ _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static __inline__ _syscall1(int,dup,int,fd)
+static __inline__ _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static __inline__ _syscall3(int,open,const char *,file,int,flag,int,mode)
+static __inline__ _syscall1(int,close,int,fd)
+static __inline__ _syscall1(int,_exit,int,exitcode)
+static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static __inline__ _syscall1(int,delete_module,const char *,name)
+
+static __inline__ pid_t wait(int * wait_stat)
+{
+	return waitpid(-1,wait_stat,0);
+}
+#endif
+
+#endif /* __ASM_SH64_UNISTD_H */
diff -urN linux-2.4.22-pre2/include/asm-sh64/user.h linux-2.4.22-pre3/include/asm-sh64/user.h
--- linux-2.4.22-pre2/include/asm-sh64/user.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sh64/user.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,71 @@
+#ifndef __ASM_SH64_USER_H
+#define __ASM_SH64_USER_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * include/asm-sh64/user.h
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+
+/*
+ * Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the `trad-core' bfd).  The file contents are as follows:
+ *
+ *  upage: 1 page consisting of a user struct that tells gdb
+ *	what is present in the file.  Directly after this is a
+ *	copy of the task_struct, which is currently not used by gdb,
+ *	but it may come in handy at some point.  All of the registers
+ *	are stored as part of the upage.  The upage should always be
+ *	only one page long.
+ *  data: The data segment follows next.  We use current->end_text to
+ *	current->brk to pick up all of the user variables, plus any memory
+ *	that may have been sbrk'ed.  No attempt is made to determine if a
+ *	page is demand-zero or if a page is totally unused, we just cover
+ *	the entire range.  All of the addresses are rounded in such a way
+ *	that an integral number of pages is written.
+ *  stack: We need the stack information in order to get a meaningful
+ *	backtrace.  We need to write the data from usp to
+ *	current->start_stack, so we round each of these in order to be able
+ *	to write an integer number of pages.
+ */
+
+struct user_fpu_struct {
+        unsigned long long fp_regs[32];
+	unsigned int fpscr;
+};
+
+struct user {
+	struct pt_regs	regs;			/* entire machine state */
+	struct user_fpu_struct fpu;	/* Math Co-processor registers  */
+	int u_fpvalid;		/* True if math co-processor being used */
+	size_t		u_tsize;		/* text size (pages) */
+	size_t		u_dsize;		/* data size (pages) */
+	size_t		u_ssize;		/* stack size (pages) */
+	unsigned long	start_code;		/* text starting address */
+	unsigned long	start_data;		/* data starting address */
+	unsigned long	start_stack;		/* stack starting address */
+	long int	signal;			/* signal causing core dump */
+	struct regs *	u_ar0;			/* help gdb find registers */
+	struct user_fpu_struct* u_fpstate;	/* Math Co-processor pointer */
+	unsigned long	magic;			/* identifies a core file */
+	char		u_comm[32];		/* user command name */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_DATA_START_ADDR	(u.start_data)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif /* __ASM_SH64_USER_H */
diff -urN linux-2.4.22-pre2/include/asm-sparc/kmap_types.h linux-2.4.22-pre3/include/asm-sparc/kmap_types.h
--- linux-2.4.22-pre2/include/asm-sparc/kmap_types.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sparc/kmap_types.h	2003-07-05 18:11:42.000000000 -0700
@@ -8,6 +8,8 @@
 	KM_USER0,
 	KM_USER1,
 	KM_BH_IRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff -urN linux-2.4.22-pre2/include/asm-sparc64/kmap_types.h linux-2.4.22-pre3/include/asm-sparc64/kmap_types.h
--- linux-2.4.22-pre2/include/asm-sparc64/kmap_types.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-sparc64/kmap_types.h	2003-07-05 18:11:42.000000000 -0700
@@ -0,0 +1,20 @@
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+/* Dummy header just to define km_type.  None of this
+ * is actually used on sparc64.  -DaveM
+ */
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BH_IRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+	KM_TYPE_NR
+};
+
+#endif
diff -urN linux-2.4.22-pre2/include/asm-sparc64/page.h linux-2.4.22-pre3/include/asm-sparc64/page.h
--- linux-2.4.22-pre2/include/asm-sparc64/page.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-sparc64/page.h	2003-07-05 18:11:42.000000000 -0700
@@ -36,6 +36,7 @@
 extern void _clear_page(void *page);
 #define clear_page(X)	_clear_page((void *)(X))
 extern void clear_user_page(void *page, unsigned long vaddr);
+#define copy_page(X,Y)	__memcpy((void *)(X), (void *)(Y), PAGE_SIZE)
 extern void copy_user_page(void *to, void *from, unsigned long vaddr);
 
 /* GROSS, defining this makes gcc pass these types as aggregates,
diff -urN linux-2.4.22-pre2/include/asm-x86_64/acpi.h linux-2.4.22-pre3/include/asm-x86_64/acpi.h
--- linux-2.4.22-pre2/include/asm-x86_64/acpi.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-x86_64/acpi.h	2003-07-05 18:11:43.000000000 -0700
@@ -0,0 +1,147 @@
+/*
+ *  asm-x86_64/acpi.h
+ *
+ *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2001 Patrick Mochel <mochel@osdl.org>
+  *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#ifndef _ASM_ACPI_H
+#define _ASM_ACPI_H
+
+#ifdef __KERNEL__
+
+#define COMPILER_DEPENDENT_INT64   long long
+#define COMPILER_DEPENDENT_UINT64  unsigned long long
+
+/*
+ * Calling conventions:
+ *
+ * ACPI_SYSTEM_XFACE        - Interfaces to host OS (handlers, threads)
+ * ACPI_EXTERNAL_XFACE      - External ACPI interfaces 
+ * ACPI_INTERNAL_XFACE      - Internal ACPI interfaces
+ * ACPI_INTERNAL_VAR_XFACE  - Internal variable-parameter list interfaces
+ */
+#define ACPI_SYSTEM_XFACE
+#define ACPI_EXTERNAL_XFACE
+#define ACPI_INTERNAL_XFACE
+#define ACPI_INTERNAL_VAR_XFACE
+
+/* Asm macros */
+
+#define ACPI_ASM_MACROS
+#define BREAKPOINT3
+#define ACPI_DISABLE_IRQS() __cli()
+#define ACPI_ENABLE_IRQS()  __sti()
+#define ACPI_FLUSH_CPU_CACHE()	wbinvd()
+
+/*
+ * A brief explanation as GNU inline assembly is a bit hairy
+ *  %0 is the output parameter in RAX ("=a")
+ *  %1 and %2 are the input parameters in RCX ("c")
+ *  and an immediate value ("i") respectively
+ *  All actual register references are preceded with "%%" as in "%%edx"
+ *  Immediate values in the assembly are preceded by "$" as in "$0x1"
+ *  The final asm parameter are the operation altered non-output registers.
+ */
+#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
+	do { \
+		unsigned long dummy; \
+		asm("1:     movl (%2),%%eax;" \
+			"movl   %%eax,%%edx;" \
+			"andq   %2,%%rdx;" \
+			"btsl   $0x1,%%edx;" \
+			"adcl   $0x0,%%edx;" \
+			"lock;  cmpxchgl %%edx,(%1);" \
+			"jnz    1b;" \
+			"cmpb   $0x3,%%dl;" \
+			"sbbl   %%eax,%%eax" \
+			:"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \
+	} while(0)
+#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
+	do { \
+		unsigned long dummy; \
+		asm("1:     movl (%2),%%eax;" \
+			"movl   %%eax,%%edx;" \
+			"andq   %2,%%rdx;" \
+			"lock;  cmpxchgl %%edx,(%1);" \
+			"jnz    1b;" \
+			"andl   $0x1,%%eax" \
+			:"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \
+	} while(0)
+
+/*
+ * Math helper asm macros
+ */
+#define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \
+        asm("divl %2;"        \
+        :"=a"(q32), "=d"(r32) \
+        :"r"(d32),            \
+        "0"(n_lo), "1"(n_hi))
+
+
+#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \
+    asm("shrl   $1,%2;"             \
+        "rcrl   $1,%3;"             \
+        :"=r"(n_hi), "=r"(n_lo)     \
+        :"0"(n_hi), "1"(n_lo))
+
+
+#ifndef CONFIG_ACPI_BOOT
+#define acpi_lapic 0
+#define acpi_ioapic 0
+#else
+#ifdef CONFIG_X86_LOCAL_APIC
+extern int acpi_lapic;
+#else
+#define acpi_lapic 0
+#endif
+#ifdef CONFIG_X86_IO_APIC
+extern int acpi_ioapic;
+#else
+#define acpi_ioapic 0
+#endif
+
+/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
+#define FIX_ACPI_PAGES 4
+
+#endif /*CONFIG_ACPI_BOOT*/
+
+#ifdef CONFIG_ACPI_SLEEP
+
+/* routines for saving/restoring kernel state */
+extern int acpi_save_state_mem(void);
+extern int acpi_save_state_disk(void);
+extern void acpi_restore_state_mem(void);
+
+extern unsigned long acpi_wakeup_address;
+
+/* early initialization routine */
+extern void acpi_reserve_bootmem(void);
+
+#endif /*CONFIG_ACPI_SLEEP*/
+
+#define boot_cpu_physical_apicid boot_cpu_id
+
+extern void mp_config_ioapic_for_sci(int irq);
+
+#endif /*__KERNEL__*/
+
+#endif /*_ASM_ACPI_H*/
diff -urN linux-2.4.22-pre2/include/asm-x86_64/apicdef.h linux-2.4.22-pre3/include/asm-x86_64/apicdef.h
--- linux-2.4.22-pre2/include/asm-x86_64/apicdef.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-x86_64/apicdef.h	2003-07-05 18:11:43.000000000 -0700
@@ -107,7 +107,7 @@
 
 #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
 
-#define MAX_IO_APICS 8
+#define MAX_IO_APICS 16
 
 /*
  * the local APIC register structure, memory mapped. Not terribly well
diff -urN linux-2.4.22-pre2/include/asm-x86_64/i387.h linux-2.4.22-pre3/include/asm-x86_64/i387.h
--- linux-2.4.22-pre2/include/asm-x86_64/i387.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-x86_64/i387.h	2003-07-05 18:11:43.000000000 -0700
@@ -16,6 +16,7 @@
 #include <asm/processor.h>
 #include <asm/sigcontext.h>
 #include <asm/user.h>
+#include <asm/uaccess.h>
 
 extern void init_fpu(struct task_struct *child);
 extern int save_i387(struct _fpstate *buf);
@@ -85,6 +86,8 @@
 		     ".previous"
 		     : [err] "=r" (err)
 		     : [fx] "r" (fx), "0" (0)); 
+	if (unlikely(err))
+		init_fpu(current);
 	return err;
 } 
 
@@ -103,6 +106,8 @@
 		     ".previous"
 		     : [err] "=r" (err)
 		     : [fx] "r" (fx), "0" (0)); 
+	if (unlikely(err))
+		__clear_user(fx, sizeof(struct i387_fxsave_struct));
 	return err;
 } 
 
diff -urN linux-2.4.22-pre2/include/asm-x86_64/irq.h linux-2.4.22-pre3/include/asm-x86_64/irq.h
--- linux-2.4.22-pre2/include/asm-x86_64/irq.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-x86_64/irq.h	2003-07-05 18:11:43.000000000 -0700
@@ -36,4 +36,6 @@
 extern void disable_irq_nosync(unsigned int);
 extern void enable_irq(unsigned int);
 
+#define ARCH_HAS_NMI_WATCHDOG 1
+
 #endif /* _ASM_IRQ_H */
diff -urN linux-2.4.22-pre2/include/asm-x86_64/kmap_types.h linux-2.4.22-pre3/include/asm-x86_64/kmap_types.h
--- linux-2.4.22-pre2/include/asm-x86_64/kmap_types.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-x86_64/kmap_types.h	2003-07-05 18:11:43.000000000 -0700
@@ -7,6 +7,8 @@
 	KM_SKB_DATA_SOFTIRQ,
 	KM_USER0,
 	KM_USER1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff -urN linux-2.4.22-pre2/include/asm-x86_64/mpspec.h linux-2.4.22-pre3/include/asm-x86_64/mpspec.h
--- linux-2.4.22-pre2/include/asm-x86_64/mpspec.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-x86_64/mpspec.h	2003-07-05 18:11:43.000000000 -0700
@@ -187,5 +187,20 @@
 extern int pic_mode;
 extern int using_apic_timer;
 
+
+#ifdef CONFIG_ACPI_BOOT
+extern void mp_register_lapic (u8 id, u8 enabled);
+extern void mp_register_lapic_address (u64 address);
+
+#ifdef CONFIG_X86_IO_APIC
+extern void mp_register_ioapic (u8 id, u32 address, u32 irq_base);
+extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 global_irq);
+extern void mp_config_acpi_legacy_irqs (void);
+extern void mp_config_ioapic_for_sci(int irq);
+extern void mp_parse_prt (void);
+#endif /*CONFIG_X86_IO_APIC*/
+
+#endif /*CONFIG_ACPI_BOOT*/
+
 #endif
 
diff -urN linux-2.4.22-pre2/include/asm-x86_64/page.h linux-2.4.22-pre3/include/asm-x86_64/page.h
--- linux-2.4.22-pre2/include/asm-x86_64/page.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-x86_64/page.h	2003-07-05 18:11:43.000000000 -0700
@@ -62,9 +62,13 @@
 #define __pte(x) ((pte_t) { (x) } )
 #define __pmd(x) ((pmd_t) { (x) } )
 #define __pgd(x) ((pgd_t) { (x) } )
-#define __level4(x) ((level4_t) { (x) } )
+#define __pml4(x) ((pml4_t) { (x) } )
 #define __pgprot(x)	((pgprot_t) { (x) } )
  
+extern unsigned long vm_stack_flags, vm_stack_flags32;
+extern unsigned long vm_data_default_flags, vm_data_default_flags32;
+extern unsigned long vm_force_exec32;
+
 #endif /* !__ASSEMBLY__ */
 
 /* to align the pointer to the (next) page boundary */
@@ -87,9 +91,9 @@
        char *filename;    /* should use 32bit offset instead, but the assembler doesn't like it */ 
        unsigned short line; 
 } __attribute__((packed)); 
-#define BUG() asm volatile("ud2 ; .quad %c1 ; .short %c0" :: "i"(__LINE__), \
+#define BUG() asm volatile("ud2 ; .quad %P1 ; .short %P0" :: "i"(__LINE__), \
 		"i" (__stringify(KBUILD_BASENAME)))
-#define HEADER_BUG() asm volatile("ud2 ; .quad %c1 ; .short %c0" :: "i"(__LINE__), \
+#define HEADER_BUG() asm volatile("ud2 ; .quad %P1 ; .short %P0" :: "i"(__LINE__), \
 		"i" (__stringify(__FILE__)))
 #define PAGE_BUG(page) BUG()
 
@@ -136,9 +140,15 @@
 
 #define phys_to_pfn(phys)	((phys) >> PAGE_SHIFT)
 
-
-#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+#define __VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+#define __VM_STACK_FLAGS 	(VM_GROWSDOWN | VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#define VM_DATA_DEFAULT_FLAGS \
+	((current->thread.flags & THREAD_IA32) ? vm_data_default_flags32 : \
+	  vm_data_default_flags) 
+#define VM_STACK_FLAGS	vm_stack_flags
 
 #endif /* __KERNEL__ */
 
diff -urN linux-2.4.22-pre2/include/asm-x86_64/pci.h linux-2.4.22-pre3/include/asm-x86_64/pci.h
--- linux-2.4.22-pre2/include/asm-x86_64/pci.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-x86_64/pci.h	2003-07-05 18:11:43.000000000 -0700
@@ -22,6 +22,11 @@
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		(pci_mem_start)
 
+void pcibios_config_init(void);
+struct pci_bus * pcibios_scan_root(int bus);
+extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
+extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
+
 void pcibios_set_master(struct pci_dev *dev);
 void pcibios_penalize_isa_irq(int irq);
 struct irq_routing_table *pcibios_get_irq_routing_table(void);
@@ -66,8 +71,8 @@
  * Once the device is given the dma address, the device owns this memory
  * until either pci_unmap_single or pci_dma_sync_single is performed.
  */
-extern dma_addr_t __pci_map_single(struct pci_dev *hwdev, void *ptr,
-			  size_t size, int direction, int flush);
+extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+				 size_t size, int direction);
 
 
 void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t addr,
@@ -116,8 +121,8 @@
 
 
 #else
-static inline dma_addr_t __pci_map_single(struct pci_dev *hwdev, void *ptr,
-					size_t size, int direction, int flush)
+static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+					size_t size, int direction)
 {
 	dma_addr_t addr; 
 
@@ -204,12 +209,6 @@
 extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 			 int nents, int direction);
 
-static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
-			  size_t size, int direction)
-{
-	return __pci_map_single(hwdev,ptr,size,direction,1); 
-}
-
 #define pci_unmap_page pci_unmap_single
 
 /* Return whether the given PCI device DMA address mask can
diff -urN linux-2.4.22-pre2/include/asm-x86_64/pda.h linux-2.4.22-pre3/include/asm-x86_64/pda.h
--- linux-2.4.22-pre2/include/asm-x86_64/pda.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-x86_64/pda.h	2003-07-05 18:11:43.000000000 -0700
@@ -41,9 +41,9 @@
 
 #define pda_to_op(op,field,val) do { \
        switch (sizeof_field(struct x8664_pda, field)) { 		\
-       case 2: asm volatile(op "w %0,%%gs:%c1" :: "r" (val), "i"(pda_offset(field)):"memory"); break;	\
-       case 4: asm volatile(op "l %0,%%gs:%c1" :: "r" (val), "i"(pda_offset(field)):"memory"); break;	\
-       case 8: asm volatile(op "q %0,%%gs:%c1" :: "r" (val), "i"(pda_offset(field)):"memory"); break;	\
+       case 2: asm volatile(op "w %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break;	\
+       case 4: asm volatile(op "l %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break;	\
+       case 8: asm volatile(op "q %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break;	\
        default: __bad_pda_field(); 					\
        } \
        } while (0)
@@ -52,9 +52,9 @@
 #define pda_from_op(op,field) ({ \
        typedef typeof_field(struct x8664_pda, field) T__; T__ ret__; \
        switch (sizeof_field(struct x8664_pda, field)) { 		\
-       case 2: asm volatile(op "w %%gs:%c1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break;	\
-       case 4: asm volatile(op "l %%gs:%c1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break;	\
-       case 8: asm volatile(op "q %%gs:%c1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break;	\
+       case 2: asm volatile(op "w %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break;	\
+       case 4: asm volatile(op "l %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break;	\
+       case 8: asm volatile(op "q %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break;	\
        default: __bad_pda_field(); 					\
        } \
        ret__; })
diff -urN linux-2.4.22-pre2/include/asm-x86_64/pgtable.h linux-2.4.22-pre3/include/asm-x86_64/pgtable.h
--- linux-2.4.22-pre2/include/asm-x86_64/pgtable.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-x86_64/pgtable.h	2003-07-05 18:11:43.000000000 -0700
@@ -231,8 +231,8 @@
 #define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
 #define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
 #define PAGE_SHARED_NOEXEC	__pgprot(_PAGE_NX | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
-
+#define PAGE_COPY_NOEXEC	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
+#define PAGE_COPY PAGE_COPY_NOEXEC
 #define PAGE_COPY_EXEC  \
 	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
@@ -427,12 +427,7 @@
 struct page;
 extern int change_page_attr(struct page *page, int numpages, pgprot_t prot);
 
-/* 
- * Map or remap large pages in the kernel mapping.
- * Only valid during kernel initilization (__init) 
- */
-extern void __map_kernel_range(void *, int, pgprot_t);
-#define map_kernel_range(adr,size) __map_kernel_range(adr,size,PAGE_KERNEL_LARGE)
+extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
 
 #endif /* !__ASSEMBLY__ */
 
diff -urN linux-2.4.22-pre2/include/asm-x86_64/processor.h linux-2.4.22-pre3/include/asm-x86_64/processor.h
--- linux-2.4.22-pre2/include/asm-x86_64/processor.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-x86_64/processor.h	2003-07-05 18:11:44.000000000 -0700
@@ -85,7 +85,7 @@
 #define cpu_has_vme 1
 #define cpu_has_fxsr 1
 #define cpu_has_xmm 1
-#define cpu_has_apic 1
+#define cpu_has_apic (test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability))
 
 extern char ignore_irq13;
 
@@ -362,6 +362,7 @@
  * create a kernel thread without removing it from tasklists
  */
 extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 /* Copy and release all segment info associated with a VM */
 extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
@@ -411,8 +412,8 @@
 #define ARCH_HAS_PREFETCHW
 #define ARCH_HAS_SPINLOCK_PREFETCH
 
-#define prefetch(x) __builtin_prefetch((x),0,1)
-#define prefetchw(x) __builtin_prefetch((x),1,1)
+#define prefetch(x) __builtin_prefetch((x),0)
+#define prefetchw(x) __builtin_prefetch((x),1)
 #define spin_lock_prefetch(x)  prefetchw(x)
 #define cpu_relax()   rep_nop()
 
diff -urN linux-2.4.22-pre2/include/asm-x86_64/proto.h linux-2.4.22-pre3/include/asm-x86_64/proto.h
--- linux-2.4.22-pre2/include/asm-x86_64/proto.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-x86_64/proto.h	2003-07-05 18:11:44.000000000 -0700
@@ -4,6 +4,7 @@
 /* misc architecture specific prototypes */
 
 struct cpuinfo_x86; 
+struct pt_regs;
 
 extern void get_cpu_vendor(struct cpuinfo_x86*);
 extern void start_kernel(void);
@@ -20,6 +21,7 @@
 extern void config_acpi_tables(void);
 extern void ia32_syscall(void);
 extern void iommu_hole_init(void);
+extern void syscall_init(void);
 
 extern void do_softirq_thunk(void);
 
@@ -38,6 +40,9 @@
 
 extern void show_stack(unsigned long * rsp);
 extern void show_trace(unsigned long *stack);
+extern void __show_regs(struct pt_regs * regs);
+extern void show_regs(struct pt_regs * regs);
+
 
 #define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))
 #define round_down(x,y) ((x) & ~((y)-1))
diff -urN linux-2.4.22-pre2/include/asm-x86_64/segment.h linux-2.4.22-pre3/include/asm-x86_64/segment.h
--- linux-2.4.22-pre2/include/asm-x86_64/segment.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-x86_64/segment.h	2003-07-05 18:11:44.000000000 -0700
@@ -16,5 +16,6 @@
 #define __USER_DS     0x2b   /* 5*8+3 */ 
 #define __USER_CS     0x33   /* 6*8+3 */ 
 #define __USER32_DS	__USER_DS 
+#define __KERNEL_COMPAT32_CS 0x08
 
 #endif
diff -urN linux-2.4.22-pre2/include/asm-x86_64/siginfo.h linux-2.4.22-pre3/include/asm-x86_64/siginfo.h
--- linux-2.4.22-pre2/include/asm-x86_64/siginfo.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-x86_64/siginfo.h	2003-07-05 18:11:44.000000000 -0700
@@ -54,7 +54,7 @@
 
 		/* SIGPOLL */
 		struct {
-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			long _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
 	} _sifields;
@@ -194,7 +194,7 @@
 #define SIGEV_THREAD	2	/* deliver via thread creation */
 
 #define SIGEV_MAX_SIZE	64
-#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 4)
 
 typedef struct sigevent {
 	sigval_t sigev_value;
diff -urN linux-2.4.22-pre2/include/asm-x86_64/smp.h linux-2.4.22-pre3/include/asm-x86_64/smp.h
--- linux-2.4.22-pre2/include/asm-x86_64/smp.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-x86_64/smp.h	2003-07-05 18:11:44.000000000 -0700
@@ -42,6 +42,7 @@
 extern void smp_invalidate_rcv(void);		/* Process an NMI */
 extern void (*mtrr_hook) (void);
 extern void zap_low_mappings (void);
+extern void smp_stop_cpu(void);
 
 /*
  * On x86 all CPUs are mapped 1:1 to the APIC space.
diff -urN linux-2.4.22-pre2/include/asm-x86_64/user.h linux-2.4.22-pre3/include/asm-x86_64/user.h
--- linux-2.4.22-pre2/include/asm-x86_64/user.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/asm-x86_64/user.h	2003-07-05 18:11:44.000000000 -0700
@@ -53,13 +53,13 @@
 	unsigned short	swd;
 	unsigned short	twd; /* Note this is not the same as the 32bit/x87/FSAVE twd */
 	unsigned short	fop;
-	u64	rip;
-	u64	rdp;
-	u32	mxcsr;
-	u32	mxcsr_mask;
-	u32	st_space[32];	/* 8*16 bytes for each FP-reg = 128 bytes */
-	u32	xmm_space[64];	/* 16*16 bytes for each XMM-reg = 256 bytes */
-	u32	padding[24];
+	__u64	rip;
+	__u64	rdp;
+	__u32	mxcsr;
+	__u32	mxcsr_mask;
+	__u32	st_space[32];	/* 8*16 bytes for each FP-reg = 128 bytes */
+	__u32	xmm_space[64];	/* 16*16 bytes for each XMM-reg = 256 bytes */
+	__u32	padding[24];
 };
 
 /*
diff -urN linux-2.4.22-pre2/include/asm-x86_64/vsyscall.h linux-2.4.22-pre3/include/asm-x86_64/vsyscall.h
--- linux-2.4.22-pre2/include/asm-x86_64/vsyscall.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/asm-x86_64/vsyscall.h	2003-07-05 18:11:44.000000000 -0700
@@ -30,6 +30,7 @@
 	int mode;
 };
 
+#define VXTIME_STUPID	0
 #define VXTIME_TSC	1
 #define	VXTIME_HPET	2
 
diff -urN linux-2.4.22-pre2/include/linux/ac97_codec.h linux-2.4.22-pre3/include/linux/ac97_codec.h
--- linux-2.4.22-pre2/include/linux/ac97_codec.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/ac97_codec.h	2003-07-05 18:11:44.000000000 -0700
@@ -214,6 +214,9 @@
                                     (CODEC)->supported_mixers & (1<<FOO) )
 
 struct ac97_codec {
+	/* Linked list of codecs */
+	struct list_head list;
+
 	/* AC97 controller connected with */
 	void *private_data;
 
@@ -221,18 +224,28 @@
 	int id;
 	int dev_mixer; 
 	int type;
+	u32 model;
 
 	int modem:1;
 
 	struct ac97_ops *codec_ops;
 
-	/* controller specific lower leverl ac97 accessing routines */
+	/* controller specific lower leverl ac97 accessing routines.
+	   must be re-entrant safe */
 	u16  (*codec_read)  (struct ac97_codec *codec, u8 reg);
 	void (*codec_write) (struct ac97_codec *codec, u8 reg, u16 val);
 
 	/* Wait for codec-ready.  Ok to sleep here.  */
 	void  (*codec_wait)  (struct ac97_codec *codec);
 
+	/* callback used by helper drivers for interesting ac97 setups */
+	void  (*codec_unregister) (struct ac97_codec *codec);
+	
+	struct ac97_driver *driver;
+	void *driver_private;	/* Private data for the driver */
+	
+	spinlock_t lock;
+	
 	/* OSS mixer masks */
 	int modcnt;
 	int supported_mixers;
@@ -269,7 +282,12 @@
 	/* Amplifier control */
 	int (*amplifier)(struct ac97_codec *codec, int on);
 	/* Digital mode control */
-	int (*digital)(struct ac97_codec *codec, int format);
+	int (*digital)(struct ac97_codec *codec, int slots, int rate, int mode);
+#define AUDIO_DIGITAL		0x8000
+#define AUDIO_PRO		0x4000
+#define AUDIO_DRS		0x2000
+#define AUDIO_CCMASK		0x003F
+	
 #define AC97_DELUDED_MODEM	1	/* Audio codec reports its a modem */
 #define AC97_NO_PCM_VOLUME	2	/* Volume control is missing 	   */
 };
@@ -282,4 +300,19 @@
 extern int ac97_save_state(struct ac97_codec *codec);
 extern int ac97_restore_state(struct ac97_codec *codec);
 
+extern struct ac97_codec *ac97_alloc_codec(void);
+extern void ac97_release_codec(struct ac97_codec *codec);
+
+struct ac97_driver {
+	struct list_head list;
+	char *name;
+	u32 codec_id;
+	u32 codec_mask;
+	int (*probe) (struct ac97_codec *codec, struct ac97_driver *driver);
+	void (*remove) (struct ac97_codec *codec, struct ac97_driver *driver);
+};
+
+extern int ac97_register_driver(struct ac97_driver *driver);
+extern void ac97_unregister_driver(struct ac97_driver *driver);
+
 #endif /* _AC97_CODEC_H_ */
diff -urN linux-2.4.22-pre2/include/linux/adb.h linux-2.4.22-pre3/include/linux/adb.h
--- linux-2.4.22-pre2/include/linux/adb.h	2000-09-17 09:48:05.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/adb.h	2003-07-05 18:11:44.000000000 -0700
@@ -30,6 +30,15 @@
 #define POWER_PACKET	4
 #define MACIIC_PACKET	5
 #define PMU_PACKET	6
+#define ADB_QUERY	7
+
+/* ADB queries */
+
+/* ADB_QUERY_GETDEVINFO
+ * Query ADB slot for device presence
+ * data[2] = id, rep[0] = orig addr, rep[1] = handler_id
+ */
+#define ADB_QUERY_GETDEVINFO	1
 
 #ifdef __KERNEL__
 
diff -urN linux-2.4.22-pre2/include/linux/apm_bios.h linux-2.4.22-pre3/include/linux/apm_bios.h
--- linux-2.4.22-pre2/include/linux/apm_bios.h	2001-08-13 16:39:28.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/apm_bios.h	2003-07-05 18:11:44.000000000 -0700
@@ -54,6 +54,7 @@
 	int			get_power_status_broken;
 	int			get_power_status_swabinminutes;
 	int			allow_ints;
+	int			forbid_idle;
 	int			realmode_power_off;
 	int			disabled;
 };
diff -urN linux-2.4.22-pre2/include/linux/atmdev.h linux-2.4.22-pre3/include/linux/atmdev.h
--- linux-2.4.22-pre2/include/linux/atmdev.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/atmdev.h	2003-07-05 18:11:44.000000000 -0700
@@ -30,9 +30,6 @@
 #define ATM_DS3_PCR	(8000*12)
 			/* DS3: 12 cells in a 125 usec time slot */
 
-#define ATM_PDU_OVHD	0	/* number of bytes to charge against buffer
-				   quota per PDU */
-
 #define ATM_SD(s)	((s)->sk->protinfo.af_atm)
 
 
@@ -292,10 +289,6 @@
 	struct atm_sap	sap;		/* SAP */
 	void (*push)(struct atm_vcc *vcc,struct sk_buff *skb);
 	void (*pop)(struct atm_vcc *vcc,struct sk_buff *skb); /* optional */
-	struct sk_buff *(*alloc_tx)(struct atm_vcc *vcc,unsigned int size);
-					/* TX allocation routine - can be */
-					/* modified by protocol or by driver.*/
-					/* NOTE: this interface will change */
 	int (*push_oam)(struct atm_vcc *vcc,void *cell);
 	int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
 	void		*dev_data;	/* per-device data */
@@ -388,8 +381,6 @@
 	void (*feedback)(struct atm_vcc *vcc,struct sk_buff *skb,
 	    unsigned long start,unsigned long dest,int len);
 	int (*change_qos)(struct atm_vcc *vcc,struct atm_qos *qos,int flags);
-	void (*free_rx_skb)(struct atm_vcc *vcc, struct sk_buff *skb);
-		/* @@@ temporary hack */
 	int (*proc_read)(struct atm_dev *dev,loff_t *pos,char *page);
 	struct module *owner;
 };
@@ -404,7 +395,6 @@
 
 struct atm_skb_data {
 	struct atm_vcc	*vcc;		/* ATM VCC */
-	int		iovcnt;		/* 0 for "normal" operation */
 	unsigned long	atm_options;	/* ATM layer options */
 };
 
@@ -431,19 +421,19 @@
 
 static __inline__ void atm_force_charge(struct atm_vcc *vcc,int truesize)
 {
-	atomic_add(truesize+ATM_PDU_OVHD,&vcc->sk->rmem_alloc);
+	atomic_add(truesize, &vcc->sk->rmem_alloc);
 }
 
 
 static __inline__ void atm_return(struct atm_vcc *vcc,int truesize)
 {
-	atomic_sub(truesize+ATM_PDU_OVHD,&vcc->sk->rmem_alloc);
+	atomic_sub(truesize, &vcc->sk->rmem_alloc);
 }
 
 
 static __inline__ int atm_may_send(struct atm_vcc *vcc,unsigned int size)
 {
-	return size+atomic_read(&vcc->sk->wmem_alloc)+ATM_PDU_OVHD < vcc->sk->sndbuf;
+	return (size + atomic_read(&vcc->sk->wmem_alloc)) < vcc->sk->sndbuf;
 }
 
 
diff -urN linux-2.4.22-pre2/include/linux/blkdev.h linux-2.4.22-pre3/include/linux/blkdev.h
--- linux-2.4.22-pre2/include/linux/blkdev.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/blkdev.h	2003-07-05 18:11:44.000000000 -0700
@@ -64,12 +64,6 @@
 typedef void (plug_device_fn) (request_queue_t *q, kdev_t device);
 typedef void (unplug_device_fn) (void *q);
 
-/*
- * Default nr free requests per queue, ll_rw_blk will scale it down
- * according to available RAM at init time
- */
-#define QUEUE_NR_REQUESTS	8192
-
 struct request_list {
 	unsigned int count;
 	struct list_head free;
@@ -80,7 +74,7 @@
 	/*
 	 * the queue request freelist, one for reads and one for writes
 	 */
-	struct request_list	rq[2];
+	struct request_list	rq;
 
 	/*
 	 * The total number of requests on each queue
@@ -93,6 +87,21 @@
 	int batch_requests;
 
 	/*
+	 * The total number of 512byte blocks on each queue
+	 */
+	atomic_t nr_sectors;
+
+	/*
+	 * Batching threshold for sleep/wakeup decisions
+	 */
+	int batch_sectors;
+
+	/*
+	 * The max number of 512byte blocks on each queue
+	 */
+	int max_queue_sectors;
+
+	/*
 	 * Together with queue_head for cacheline sharing
 	 */
 	struct list_head	queue_head;
@@ -118,13 +127,21 @@
 	/*
 	 * Boolean that indicates whether this queue is plugged or not.
 	 */
-	char			plugged;
+	int			plugged:1;
 
 	/*
 	 * Boolean that indicates whether current_request is active or
 	 * not.
 	 */
-	char			head_active;
+	int			head_active:1;
+
+	/*
+	 * Boolean that indicates you will use blk_started_sectors
+	 * and blk_finished_sectors in addition to blk_started_io
+	 * and blk_finished_io.  It enables the throttling code to 
+	 * help keep the sectors in flight to a reasonable value
+	 */
+	int			can_throttle:1;
 
 	unsigned long		bounce_pfn;
 
@@ -137,7 +154,7 @@
 	/*
 	 * Tasks wait here for free read and write requests
 	 */
-	wait_queue_head_t	wait_for_requests[2];
+	wait_queue_head_t	wait_for_requests;
 };
 
 #define blk_queue_plugged(q)	(q)->plugged
@@ -221,10 +238,11 @@
 /*
  * Access functions for manipulating queue properties
  */
-extern int blk_grow_request_list(request_queue_t *q, int nr_requests);
+extern int blk_grow_request_list(request_queue_t *q, int nr_requests, int max_queue_sectors);
 extern void blk_init_queue(request_queue_t *, request_fn_proc *);
 extern void blk_cleanup_queue(request_queue_t *);
 extern void blk_queue_headactive(request_queue_t *, int);
+extern void blk_queue_throttle_sectors(request_queue_t *, int);
 extern void blk_queue_make_request(request_queue_t *, make_request_fn *);
 extern void generic_unplug_device(void *);
 extern inline int blk_seg_merge_ok(struct buffer_head *, struct buffer_head *);
@@ -243,6 +261,8 @@
 
 #define MAX_SEGMENTS 128
 #define MAX_SECTORS 255
+#define MAX_QUEUE_SECTORS (4 << (20 - 9)) /* 4 mbytes when full sized */
+#define MAX_NR_REQUESTS 1024 /* 1024k when in 512 units, normally min is 1M in 1k units */
 
 #define PageAlignSize(size) (((size) + PAGE_SIZE -1) & PAGE_MASK)
 
@@ -268,9 +288,51 @@
 	return retval;
 }
 
+static inline int blk_oversized_queue(request_queue_t * q)
+{
+	if (q->can_throttle)
+		return atomic_read(&q->nr_sectors) > q->max_queue_sectors;
+	return q->rq.count == 0;
+}
+
+static inline int blk_oversized_queue_batch(request_queue_t * q)
+{
+	return atomic_read(&q->nr_sectors) > q->max_queue_sectors - q->batch_sectors;
+}
+
 #define blk_finished_io(nsects)	do { } while (0)
 #define blk_started_io(nsects)	do { } while (0)
 
+static inline void blk_started_sectors(struct request *rq, int count)
+{
+	request_queue_t *q = rq->q;
+	if (q && q->can_throttle) {
+		atomic_add(count, &q->nr_sectors);
+		if (atomic_read(&q->nr_sectors) < 0) {
+			printk("nr_sectors is %d\n", atomic_read(&q->nr_sectors));
+			BUG();
+		}
+	}
+}
+
+static inline void blk_finished_sectors(struct request *rq, int count)
+{
+	request_queue_t *q = rq->q;
+	if (q && q->can_throttle) {
+		atomic_sub(count, &q->nr_sectors);
+		
+		smp_mb();
+		if (q->rq.count >= q->batch_requests && !blk_oversized_queue_batch(q)) {
+			if (waitqueue_active(&q->wait_for_requests))
+				wake_up(&q->wait_for_requests);
+		}
+		if (atomic_read(&q->nr_sectors) < 0) {
+			printk("nr_sectors is %d\n", atomic_read(&q->nr_sectors));
+			BUG();
+		}
+	}
+}
+
 static inline unsigned int blksize_bits(unsigned int size)
 {
 	unsigned int bits = 8;
diff -urN linux-2.4.22-pre2/include/linux/crypto.h linux-2.4.22-pre3/include/linux/crypto.h
--- linux-2.4.22-pre2/include/linux/crypto.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/linux/crypto.h	2003-07-05 18:11:44.000000000 -0700
@@ -0,0 +1,379 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ *
+ * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
+ * and Nettle, by Niels Möller.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#ifndef _LINUX_CRYPTO_H
+#define _LINUX_CRYPTO_H
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/string.h>
+#include <asm/page.h>
+
+/*
+ * Algorithm masks and types.
+ */
+#define CRYPTO_ALG_TYPE_MASK		0x000000ff
+#define CRYPTO_ALG_TYPE_CIPHER		0x00000001
+#define CRYPTO_ALG_TYPE_DIGEST		0x00000002
+#define CRYPTO_ALG_TYPE_COMPRESS	0x00000004
+
+/*
+ * Transform masks and values (for crt_flags).
+ */
+#define CRYPTO_TFM_MODE_MASK		0x000000ff
+#define CRYPTO_TFM_REQ_MASK		0x000fff00
+#define CRYPTO_TFM_RES_MASK		0xfff00000
+
+#define CRYPTO_TFM_MODE_ECB		0x00000001
+#define CRYPTO_TFM_MODE_CBC		0x00000002
+#define CRYPTO_TFM_MODE_CFB		0x00000004
+#define CRYPTO_TFM_MODE_CTR		0x00000008
+
+#define CRYPTO_TFM_REQ_WEAK_KEY		0x00000100
+#define CRYPTO_TFM_RES_WEAK_KEY		0x00100000
+#define CRYPTO_TFM_RES_BAD_KEY_LEN   	0x00200000
+#define CRYPTO_TFM_RES_BAD_KEY_SCHED 	0x00400000
+#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 	0x00800000
+#define CRYPTO_TFM_RES_BAD_FLAGS 	0x01000000
+
+/*
+ * Miscellaneous stuff.
+ */
+#define CRYPTO_UNSPEC			0
+#define CRYPTO_MAX_ALG_NAME		64
+
+struct scatterlist;
+
+/*
+ * Algorithms: modular crypto algorithm implementations, managed
+ * via crypto_register_alg() and crypto_unregister_alg().
+ */
+struct cipher_alg {
+	unsigned int cia_min_keysize;
+	unsigned int cia_max_keysize;
+	unsigned int cia_ivsize;
+	int (*cia_setkey)(void *ctx, const u8 *key,
+	                  unsigned int keylen, u32 *flags);
+	void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
+	void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
+};
+
+struct digest_alg {
+	unsigned int dia_digestsize;
+	void (*dia_init)(void *ctx);
+	void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
+	void (*dia_final)(void *ctx, u8 *out);
+};
+
+struct compress_alg {
+	int (*coa_init)(void *ctx);
+	void (*coa_exit)(void *ctx);
+	int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
+	                    u8 *dst, unsigned int *dlen);
+	int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
+	                      u8 *dst, unsigned int *dlen);
+};
+
+#define cra_cipher	cra_u.cipher
+#define cra_digest	cra_u.digest
+#define cra_compress	cra_u.compress
+
+struct crypto_alg {
+	struct list_head cra_list;
+	u32 cra_flags;
+	unsigned int cra_blocksize;
+	unsigned int cra_ctxsize;
+	const char cra_name[CRYPTO_MAX_ALG_NAME];
+
+	union {
+		struct cipher_alg cipher;
+		struct digest_alg digest;
+		struct compress_alg compress;
+	} cra_u;
+	
+	struct module *cra_module;
+};
+
+/*
+ * Algorithm registration interface.
+ */
+int crypto_register_alg(struct crypto_alg *alg);
+int crypto_unregister_alg(struct crypto_alg *alg);
+
+/*
+ * Algorithm query interface.
+ */
+int crypto_alg_available(const char *name, u32 flags);
+
+/*
+ * Transforms: user-instantiated objects which encapsulate algorithms
+ * and core processing logic.  Managed via crypto_alloc_tfm() and
+ * crypto_free_tfm(), as well as the various helpers below.
+ */
+struct crypto_tfm;
+
+struct cipher_tfm {
+	void *cit_iv;
+	u32 cit_mode;
+	int (*cit_setkey)(struct crypto_tfm *tfm,
+	                  const u8 *key, unsigned int keylen);
+	int (*cit_encrypt)(struct crypto_tfm *tfm,
+			   struct scatterlist *dst,
+			   struct scatterlist *src,
+			   unsigned int nbytes);
+	int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
+	                      struct scatterlist *dst,
+	                      struct scatterlist *src,
+	                      unsigned int nbytes, u8 *iv);
+	int (*cit_decrypt)(struct crypto_tfm *tfm,
+			   struct scatterlist *dst,
+			   struct scatterlist *src,
+			   unsigned int nbytes);
+	int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
+			   struct scatterlist *dst,
+			   struct scatterlist *src,
+			   unsigned int nbytes, u8 *iv);
+	void (*cit_xor_block)(u8 *dst, const u8 *src);
+};
+
+struct digest_tfm {
+	void (*dit_init)(struct crypto_tfm *tfm);
+	void (*dit_update)(struct crypto_tfm *tfm,
+	                   struct scatterlist *sg, unsigned int nsg);
+	void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
+	void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
+	                   unsigned int nsg, u8 *out);
+#ifdef CONFIG_CRYPTO_HMAC
+	void *dit_hmac_block;
+#endif
+};
+
+struct compress_tfm {
+	int (*cot_compress)(struct crypto_tfm *tfm,
+	                    const u8 *src, unsigned int slen,
+	                    u8 *dst, unsigned int *dlen);
+	int (*cot_decompress)(struct crypto_tfm *tfm,
+	                      const u8 *src, unsigned int slen,
+	                      u8 *dst, unsigned int *dlen);
+};
+
+#define crt_cipher	crt_u.cipher
+#define crt_digest	crt_u.digest
+#define crt_compress	crt_u.compress
+
+struct crypto_tfm {
+
+	u32 crt_flags;
+	
+	union {
+		struct cipher_tfm cipher;
+		struct digest_tfm digest;
+		struct compress_tfm compress;
+	} crt_u;
+	
+	struct crypto_alg *__crt_alg;
+};
+
+/* 
+ * Transform user interface.
+ */
+ 
+/*
+ * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
+ * If that fails and the kernel supports dynamically loadable modules, it
+ * will then attempt to load a module of the same name or alias.  A refcount
+ * is grabbed on the algorithm which is then associated with the new transform.
+ *
+ * crypto_free_tfm() frees up the transform and any associated resources,
+ * then drops the refcount on the associated algorithm.
+ */
+struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
+void crypto_free_tfm(struct crypto_tfm *tfm);
+
+/*
+ * Transform helpers which query the underlying algorithm.
+ */
+static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_name;
+}
+
+static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
+{
+	struct crypto_alg *alg = tfm->__crt_alg;
+	
+	if (alg->cra_module)
+		return alg->cra_module->name;
+	else
+		return NULL;
+}
+
+static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
+}
+
+static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->__crt_alg->cra_cipher.cia_min_keysize;
+}
+
+static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->__crt_alg->cra_cipher.cia_max_keysize;
+}
+
+static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->__crt_alg->cra_cipher.cia_ivsize;
+}
+
+static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_blocksize;
+}
+
+static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	return tfm->__crt_alg->cra_digest.dia_digestsize;
+}
+
+/*
+ * API wrappers.
+ */
+static inline void crypto_digest_init(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_init(tfm);
+}
+
+static inline void crypto_digest_update(struct crypto_tfm *tfm,
+                                        struct scatterlist *sg,
+                                        unsigned int nsg)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_update(tfm, sg, nsg);
+}
+
+static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_final(tfm, out);
+}
+
+static inline void crypto_digest_digest(struct crypto_tfm *tfm,
+                                        struct scatterlist *sg,
+                                        unsigned int nsg, u8 *out)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
+}
+
+static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
+                                       const u8 *key, unsigned int keylen)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
+}
+
+static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
+                                        struct scatterlist *dst,
+                                        struct scatterlist *src,
+                                        unsigned int nbytes)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
+}                                        
+
+static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
+                                           struct scatterlist *dst,
+                                           struct scatterlist *src,
+                                           unsigned int nbytes, u8 *iv)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
+	return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
+}                                        
+
+static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
+                                        struct scatterlist *dst,
+                                        struct scatterlist *src,
+                                        unsigned int nbytes)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
+}
+
+static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
+                                           struct scatterlist *dst,
+                                           struct scatterlist *src,
+                                           unsigned int nbytes, u8 *iv)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
+	return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
+}
+
+static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
+                                        const u8 *src, unsigned int len)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	memcpy(tfm->crt_cipher.cit_iv, src, len);
+}
+
+static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
+                                        u8 *dst, unsigned int len)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	memcpy(dst, tfm->crt_cipher.cit_iv, len);
+}
+
+static inline int crypto_comp_compress(struct crypto_tfm *tfm,
+                                       const u8 *src, unsigned int slen,
+                                       u8 *dst, unsigned int *dlen)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
+	return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
+}
+
+static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
+                                         const u8 *src, unsigned int slen,
+                                         u8 *dst, unsigned int *dlen)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
+	return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
+}
+
+/*
+ * HMAC support.
+ */
+#ifdef CONFIG_CRYPTO_HMAC
+void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
+void crypto_hmac_update(struct crypto_tfm *tfm,
+                        struct scatterlist *sg, unsigned int nsg);
+void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
+                       unsigned int *keylen, u8 *out);
+void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
+                 struct scatterlist *sg, unsigned int nsg, u8 *out);
+#endif	/* CONFIG_CRYPTO_HMAC */
+
+#endif	/* _LINUX_CRYPTO_H */
+
diff -urN linux-2.4.22-pre2/include/linux/elevator.h linux-2.4.22-pre3/include/linux/elevator.h
--- linux-2.4.22-pre2/include/linux/elevator.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/linux/elevator.h	2003-07-05 18:11:44.000000000 -0700
@@ -80,7 +80,7 @@
 	return latency;
 }
 
-#define ELV_LINUS_SEEK_COST	16
+#define ELV_LINUS_SEEK_COST	1
 
 #define ELEVATOR_NOOP							\
 ((elevator_t) {								\
@@ -93,8 +93,8 @@
 
 #define ELEVATOR_LINUS							\
 ((elevator_t) {								\
-	2048,				/* read passovers */		\
-	8192,				/* write passovers */		\
+	128,				/* read passovers */		\
+	512,				/* write passovers */		\
 									\
 	elevator_linus_merge,		/* elevator_merge_fn */		\
 	elevator_linus_merge_req,	/* elevator_merge_req_fn */	\
diff -urN linux-2.4.22-pre2/include/linux/fs.h linux-2.4.22-pre3/include/linux/fs.h
--- linux-2.4.22-pre2/include/linux/fs.h	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/fs.h	2003-07-05 18:11:44.000000000 -0700
@@ -1461,6 +1461,7 @@
 extern int generic_file_mmap(struct file *, struct vm_area_struct *);
 extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
 extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
+extern int precheck_file_write(struct file *, struct inode *, size_t *, loff_t *);
 extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *);
 extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t);
 extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
diff -urN linux-2.4.22-pre2/include/linux/highmem.h linux-2.4.22-pre3/include/linux/highmem.h
--- linux-2.4.22-pre2/include/linux/highmem.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/highmem.h	2003-07-05 18:11:45.000000000 -0700
@@ -121,4 +121,15 @@
 	kunmap_atomic(vto, KM_USER1);
 }
 
+static inline void copy_highpage(struct page *to, struct page *from)
+{
+	char *vfrom, *vto;
+
+	vfrom = kmap_atomic(from, KM_USER0);
+	vto = kmap_atomic(to, KM_USER1);
+	copy_page(vto, vfrom);
+	kunmap_atomic(vfrom, KM_USER0);
+	kunmap_atomic(vto, KM_USER1);
+}
+
 #endif /* _LINUX_HIGHMEM_H */
diff -urN linux-2.4.22-pre2/include/linux/ide.h linux-2.4.22-pre3/include/linux/ide.h
--- linux-2.4.22-pre2/include/linux/ide.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/ide.h	2003-07-05 18:11:45.000000000 -0700
@@ -1744,6 +1744,12 @@
 extern void ide_toggle_bounce(ide_drive_t *drive, int on);
 extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate);
 
+/* ide driver registration */
+typedef void (*ide_driver_call)(void);
+extern void __init ide_register_driver(ide_driver_call);
+
+/* ide locks for 2.4 */
+
 #define ide_lock		(io_request_lock)
 #define DRIVE_LOCK(drive)       ((drive)->queue.queue_lock)
 
diff -urN linux-2.4.22-pre2/include/linux/if_ether.h linux-2.4.22-pre3/include/linux/if_ether.h
--- linux-2.4.22-pre2/include/linux/if_ether.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/if_ether.h	2003-07-05 18:11:45.000000000 -0700
@@ -65,6 +65,7 @@
 #define ETH_P_ATMFATE	0x8884		/* Frame-based ATM Transport
 					 * over Ethernet
 					 */
+#define ETH_P_EDP2	0x88A2		/* Coraid EDP2			*/
 
 /*
  *	Non DIX types. Won't clash for 1500 types.
diff -urN linux-2.4.22-pre2/include/linux/lockd/lockd.h linux-2.4.22-pre3/include/linux/lockd/lockd.h
--- linux-2.4.22-pre2/include/linux/lockd/lockd.h	2001-11-22 11:47:20.000000000 -0800
+++ linux-2.4.22-pre3/include/linux/lockd/lockd.h	2003-07-05 18:11:45.000000000 -0700
@@ -164,6 +164,7 @@
 unsigned long	  nlmsvc_retry_blocked(void);
 int		  nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
 					int action);
+void	  nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status);
 
 /*
  * File handling for the server personality
diff -urN linux-2.4.22-pre2/include/linux/mm.h linux-2.4.22-pre3/include/linux/mm.h
--- linux-2.4.22-pre2/include/linux/mm.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/mm.h	2003-07-05 18:11:46.000000000 -0700
@@ -104,7 +104,9 @@
 #define VM_DONTEXPAND	0x00040000	/* Cannot expand with mremap() */
 #define VM_RESERVED	0x00080000	/* Don't unmap it from swap_out */
 
+#ifndef VM_STACK_FLAGS
 #define VM_STACK_FLAGS	0x00000177
+#endif
 
 #define VM_READHINTMASK			(VM_SEQ_READ | VM_RAND_READ)
 #define VM_ClearReadHint(v)		(v)->vm_flags &= ~VM_READHINTMASK
@@ -299,10 +301,18 @@
 #define PG_launder		15	/* written out by VM pressure.. */
 #define PG_fs_1			16	/* Filesystem specific */
 
+#ifndef arch_set_page_uptodate
+#define arch_set_page_uptodate(page)
+#endif
+
 /* Make it prettier to test the above... */
 #define UnlockPage(page)	unlock_page(page)
 #define Page_Uptodate(page)	test_bit(PG_uptodate, &(page)->flags)
-#define SetPageUptodate(page)	set_bit(PG_uptodate, &(page)->flags)
+#define SetPageUptodate(page) \
+	do {								\
+		arch_set_page_uptodate(page);				\
+		set_bit(PG_uptodate, &(page)->flags);			\
+	} while (0)
 #define ClearPageUptodate(page)	clear_bit(PG_uptodate, &(page)->flags)
 #define PageDirty(page)		test_bit(PG_dirty, &(page)->flags)
 #define SetPageDirty(page)	set_bit(PG_dirty, &(page)->flags)
diff -urN linux-2.4.22-pre2/include/linux/msdos_fs.h linux-2.4.22-pre3/include/linux/msdos_fs.h
--- linux-2.4.22-pre2/include/linux/msdos_fs.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/msdos_fs.h	2003-07-05 18:11:46.000000000 -0700
@@ -145,8 +145,7 @@
 	__u32   reserved1[120];	/* Nothing as far as I can tell */
 	__u32   signature2;	/* 0x61417272L */
 	__u32   free_clusters;	/* Free cluster count.  -1 if unknown */
-	__u32   next_cluster;	/* Most recently allocated cluster.
-				 * Unused under Linux. */
+	__u32   next_cluster;	/* Most recently allocated cluster */
 	__u32   reserved2[4];
 };
 
diff -urN linux-2.4.22-pre2/include/linux/netfilter_arp/arpt_mangle.h linux-2.4.22-pre3/include/linux/netfilter_arp/arpt_mangle.h
--- linux-2.4.22-pre2/include/linux/netfilter_arp/arpt_mangle.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/include/linux/netfilter_arp/arpt_mangle.h	2003-07-05 18:11:46.000000000 -0700
@@ -0,0 +1,26 @@
+#ifndef _ARPT_MANGLE_H
+#define _ARPT_MANGLE_H
+#include <linux/netfilter_arp/arp_tables.h>
+
+#define ARPT_MANGLE_ADDR_LEN_MAX sizeof(struct in_addr)
+struct arpt_mangle
+{
+	char src_devaddr[ARPT_DEV_ADDR_LEN_MAX];
+	char tgt_devaddr[ARPT_DEV_ADDR_LEN_MAX];
+	union {
+		struct in_addr src_ip;
+	} u_s;
+	union {
+		struct in_addr tgt_ip;
+	} u_t;
+	u_int8_t flags;
+	int target;
+};
+
+#define ARPT_MANGLE_SDEV 0x01
+#define ARPT_MANGLE_TDEV 0x02
+#define ARPT_MANGLE_SIP 0x04
+#define ARPT_MANGLE_TIP 0x08
+#define ARPT_MANGLE_MASK 0x0f
+
+#endif /* _ARPT_MANGLE_H */
diff -urN linux-2.4.22-pre2/include/linux/pagemap.h linux-2.4.22-pre3/include/linux/pagemap.h
--- linux-2.4.22-pre2/include/linux/pagemap.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/linux/pagemap.h	2003-07-05 18:11:46.000000000 -0700
@@ -97,6 +97,8 @@
 		___wait_on_page(page);
 }
 
+extern void FASTCALL(wakeup_page_waiters(struct page * page));
+
 /*
  * Returns locked page at given index in given cache, creating it if needed.
  */
diff -urN linux-2.4.22-pre2/include/linux/pci_ids.h linux-2.4.22-pre3/include/linux/pci_ids.h
--- linux-2.4.22-pre2/include/linux/pci_ids.h	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/pci_ids.h	2003-07-05 18:11:47.000000000 -0700
@@ -493,6 +493,7 @@
 #define PCI_DEVICE_ID_SI_601		0x0601
 #define PCI_DEVICE_ID_SI_620		0x0620
 #define PCI_DEVICE_ID_SI_630		0x0630
+#define PCI_DEVICE_ID_SI_633		0x0633
 #define PCI_DEVICE_ID_SI_635		0x0635
 #define PCI_DEVICE_ID_SI_640		0x0640
 #define PCI_DEVICE_ID_SI_645		0x0645
@@ -501,7 +502,9 @@
 #define PCI_DEVICE_ID_SI_650		0x0650
 #define PCI_DEVICE_ID_SI_651		0x0651
 #define PCI_DEVICE_ID_SI_652		0x0652
+#define PCI_DEVICE_ID_SI_655		0x0655
 #define PCI_DEVICE_ID_SI_730		0x0730
+#define PCI_DEVICE_ID_SI_733		0x0733
 #define PCI_DEVICE_ID_SI_630_VGA	0x6300
 #define PCI_DEVICE_ID_SI_730_VGA	0x7300
 #define PCI_DEVICE_ID_SI_735		0x0735
@@ -519,7 +522,10 @@
 #define PCI_DEVICE_ID_SI_5513		0x5513
 #define PCI_DEVICE_ID_SI_5518		0x5518
 #define PCI_DEVICE_ID_SI_5571		0x5571
+#define PCI_DEVICE_ID_SI_5581		0x5581
+#define PCI_DEVICE_ID_SI_5582		0x5582
 #define PCI_DEVICE_ID_SI_5591		0x5591
+#define PCI_DEVICE_ID_SI_5596		0x5596
 #define PCI_DEVICE_ID_SI_5597		0x5597
 #define PCI_DEVICE_ID_SI_5598		0x5598
 #define PCI_DEVICE_ID_SI_5600		0x5600
@@ -760,6 +766,8 @@
 #define PCI_DEVICE_ID_SUN_HUMMINGBIRD	0xa001
 
 #define PCI_VENDOR_ID_CMD		0x1095
+#define PCI_DEVICE_ID_SII_1210SA	0x0240
+
 #define PCI_DEVICE_ID_CMD_640		0x0640
 #define PCI_DEVICE_ID_CMD_643		0x0643
 #define PCI_DEVICE_ID_CMD_646		0x0646
@@ -923,7 +931,9 @@
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA	0x0152
 #define PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO	0x0153
 #define PCI_DEVICE_ID_NVIDIA_IGEFORCE2		0x01a0
+#define PCI_DEVICE_ID_NVIDIA_NFORCE		0x01a4
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE		0x01bc
+#define PCI_DEVICE_ID_NVIDIA_NFORCE2		0x01e0
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3		0x0200
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1		0x0201
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2		0x0202
@@ -1025,13 +1035,14 @@
 #define PCI_DEVICE_ID_VIA_8622		0x3102
 #define PCI_DEVICE_ID_VIA_8233C_0	0x3109
 #define PCI_DEVICE_ID_VIA_8361		0x3112
-#define PCI_DEVICE_ID_VIA_8375     0x3116
+#define PCI_DEVICE_ID_VIA_8375		0x3116
 #define PCI_DEVICE_ID_VIA_8233A		0x3147
-#define PCI_DEVICE_ID_VIA_P4X333   0x3168
-#define PCI_DEVICE_ID_VIA_8235        0x3177
-#define PCI_DEVICE_ID_VIA_8377_0  0x3189
+#define PCI_DEVICE_ID_VIA_P4M266	0x3148
+#define PCI_DEVICE_ID_VIA_8237_SATA	0x3149
+#define PCI_DEVICE_ID_VIA_P4X333	0x3168
+#define PCI_DEVICE_ID_VIA_8235		0x3177
 #define PCI_DEVICE_ID_VIA_8377_0	0x3189
-#define PCI_DEVICE_ID_VIA_8237     0x3227
+#define PCI_DEVICE_ID_VIA_8237		0x3227
 #define PCI_DEVICE_ID_VIA_86C100A	0x6100
 #define PCI_DEVICE_ID_VIA_8231		0x8231
 #define PCI_DEVICE_ID_VIA_8231_4	0x8235
@@ -1185,6 +1196,7 @@
 #define PCI_DEVICE_ID_SBE_WANXL400	0x0104
 
 #define PCI_VENDOR_ID_TOSHIBA		0x1179
+#define PCI_DEVICE_ID_TOSHIBA_PICCOLO	0x0102
 #define PCI_DEVICE_ID_TOSHIBA_601	0x0601
 #define PCI_DEVICE_ID_TOSHIBA_TOPIC95	0x060a
 #define PCI_DEVICE_ID_TOSHIBA_TOPIC97	0x060f
@@ -1768,6 +1780,7 @@
 #define PCI_DEVICE_ID_INTEL_82801DB_7	0x24c7
 #define PCI_DEVICE_ID_INTEL_82801DB_10	0x24ca
 #define PCI_DEVICE_ID_INTEL_82801DB_11	0x24cb
+#define PCI_DEVICE_ID_INTEL_82801DB_12  0x24cc
 #define PCI_DEVICE_ID_INTEL_82801DB_13	0x24cd
 #define PCI_DEVICE_ID_INTEL_82801EB_0	0x24d0
 #define PCI_DEVICE_ID_INTEL_82801EB_1	0x24d1
diff -urN linux-2.4.22-pre2/include/linux/personality.h linux-2.4.22-pre3/include/linux/personality.h
--- linux-2.4.22-pre2/include/linux/personality.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/personality.h	2003-07-05 18:11:47.000000000 -0700
@@ -34,6 +34,7 @@
 	SHORT_INODE =		0x1000000,
 	WHOLE_SECONDS =		0x2000000,
 	STICKY_TIMEOUTS	=	0x4000000,
+	ADDR_LIMIT_3GB =	0x8000000,
 };
 
 /*
diff -urN linux-2.4.22-pre2/include/linux/pmu.h linux-2.4.22-pre3/include/linux/pmu.h
--- linux-2.4.22-pre2/include/linux/pmu.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/pmu.h	2003-07-05 18:11:47.000000000 -0700
@@ -30,8 +30,10 @@
 #define PMU_SET_INTR_MASK	0x70	/* set PMU interrupt mask */
 #define PMU_INT_ACK		0x78	/* read interrupt bits */
 #define PMU_SHUTDOWN		0x7e	/* turn power off */
+#define PMU_CPU_SPEED		0x7d	/* control CPU speed on some models */
 #define PMU_SLEEP		0x7f	/* put CPU to sleep */
 #define PMU_POWER_EVENTS	0x8f	/* Send power-event commands to PMU */
+#define PMU_I2C_CMD		0x9a	/* I2C operations */
 #define PMU_RESET		0xd0	/* reset CPU */
 #define PMU_GET_BRIGHTBUTTON	0xd9	/* report brightness up/down pos */
 #define PMU_GET_COVER		0xdc	/* report cover open/closed */
@@ -68,6 +70,20 @@
  * or via PMU_INT_ENVIRONMENT on core99 */
 #define PMU_ENV_LID_CLOSED	0x01	/* The lid is closed */
 
+/* I2C related definitions */
+#define PMU_I2C_MODE_SIMPLE	0
+#define PMU_I2C_MODE_STDSUB	1
+#define PMU_I2C_MODE_COMBINED	2
+
+#define PMU_I2C_BUS_STATUS	0
+#define PMU_I2C_BUS_SYSCLK	1
+#define PMU_I2C_BUS_POWER	2
+
+#define PMU_I2C_STATUS_OK	0
+#define PMU_I2C_STATUS_DATAREAD	1
+#define PMU_I2C_STATUS_BUSY	0xfe
+
+
 /* Kind of PMU (model) */
 enum {
 	PMU_UNKNOWN,
@@ -142,6 +158,12 @@
 extern int pmu_present(void);
 extern int pmu_get_model(void);
 
+extern int pmu_i2c_combined_read(int bus, int addr, int subaddr,  u8* data, int len);
+extern int pmu_i2c_stdsub_write(int bus, int addr, int subaddr,  u8* data, int len);
+extern int pmu_i2c_simple_read(int bus, int addr,  u8* data, int len);
+extern int pmu_i2c_simple_write(int bus, int addr,  u8* data, int len);
+
+
 #ifdef CONFIG_PMAC_PBOOK
 /*
  * Stuff for putting the powerbook to sleep and waking it again.
@@ -192,6 +214,10 @@
 /* values for pmu_battery_info.flags */
 #define PMU_BATT_PRESENT	0x00000001
 #define PMU_BATT_CHARGING	0x00000002
+#define PMU_BATT_TYPE_MASK	0x000000f0
+#define PMU_BATT_TYPE_SMART	0x00000010 /* Smart battery */
+#define PMU_BATT_TYPE_HOOPER	0x00000020 /* 3400/3500 */
+#define PMU_BATT_TYPE_COMET	0x00000030 /* 2400 */
 
 struct pmu_battery_info
 {
diff -urN linux-2.4.22-pre2/include/linux/reiserfs_fs.h linux-2.4.22-pre3/include/linux/reiserfs_fs.h
--- linux-2.4.22-pre2/include/linux/reiserfs_fs.h	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/reiserfs_fs.h	2003-07-05 18:11:48.000000000 -0700
@@ -99,6 +99,135 @@
  * Structure of super block on disk, a version of which in RAM is often accessed as s->u.reiserfs_sb.s_rs
  * the version in RAM is part of a larger structure containing fields never written to disk.
  */
+#define UNSET_HASH 0 // read_super will guess about, what hash names
+                     // in directories were sorted with
+#define TEA_HASH  1
+#define YURA_HASH 2
+#define R5_HASH   3
+#define DEFAULT_HASH R5_HASH
+
+
+struct journal_params {
+    __u32 jp_journal_1st_block;	      /* where does journal start from on its
+				       * device */
+    __u32 jp_journal_dev;	      /* journal device st_rdev */
+    __u32 jp_journal_size;	      /* size of the journal */
+    __u32 jp_journal_trans_max;	      /* max number of blocks in a transaction. */
+    __u32 jp_journal_magic; 	      /* random value made on fs creation (this
+				       * was sb_journal_block_count) */
+    __u32 jp_journal_max_batch;	      /* max number of blocks to batch into a
+				       * trans */
+    __u32 jp_journal_max_commit_age;  /* in seconds, how old can an async
+				       * commit be */
+    __u32 jp_journal_max_trans_age;   /* in seconds, how old can a transaction
+				       * be */
+};
+
+/* this is the super from 3.5.X, where X >= 10 */
+struct reiserfs_super_block_v1
+{
+    __u32 s_block_count;	   /* blocks count         */
+    __u32 s_free_blocks;           /* free blocks count    */
+    __u32 s_root_block;            /* root block number    */
+    struct journal_params s_journal;
+    __u16 s_blocksize;             /* block size */
+    __u16 s_oid_maxsize;	   /* max size of object id array, see
+				    * get_objectid() commentary  */
+    __u16 s_oid_cursize;	   /* current size of object id array */
+    __u16 s_umount_state;          /* this is set to 1 when filesystem was
+				    * umounted, to 2 - when not */    
+    char s_magic[10];              /* reiserfs magic string indicates that
+				    * file system is reiserfs:
+				    * "ReIsErFs" or "ReIsEr2Fs" or "ReIsEr3Fs" */
+    __u16 s_fs_state;	           /* it is set to used by fsck to mark which
+				    * phase of rebuilding is done */
+    __u32 s_hash_function_code;    /* indicate, what hash function is being use
+				    * to sort names in a directory*/
+    __u16 s_tree_height;           /* height of disk tree */
+    __u16 s_bmap_nr;               /* amount of bitmap blocks needed to address
+				    * each block of file system */
+    __u16 s_version;               /* this field is only reliable on filesystem
+				    * with non-standard journal */
+    __u16 s_reserved_for_journal;  /* size in blocks of journal area on main
+				    * device, we need to keep after
+				    * making fs with non-standard journal */	
+} __attribute__ ((__packed__));
+
+#define SB_SIZE_V1 (sizeof(struct reiserfs_super_block_v1))
+
+/* this is the on disk super block */
+struct reiserfs_super_block
+{
+    struct reiserfs_super_block_v1 s_v1;
+    __u32 s_inode_generation;
+    __u32 s_flags;                  /* Right now used only by inode-attributes, if enabled */
+    unsigned char s_uuid[16];       /* filesystem unique identifier */
+    unsigned char s_label[16];      /* filesystem volume label */
+    char s_unused[88] ;             /* zero filled by mkreiserfs and
+				     * reiserfs_convert_objectid_map_v1()
+				     * so any additions must be updated
+				     * there as well. */
+}  __attribute__ ((__packed__));
+
+#define SB_SIZE (sizeof(struct reiserfs_super_block))
+
+#define REISERFS_VERSION_1 0
+#define REISERFS_VERSION_2 2
+
+
+// on-disk super block fields converted to cpu form
+#define SB_DISK_SUPER_BLOCK(s) ((s)->u.reiserfs_sb.s_rs)
+#define SB_V1_DISK_SUPER_BLOCK(s) (&(SB_DISK_SUPER_BLOCK(s)->s_v1))
+#define SB_BLOCKSIZE(s) \
+        le32_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_blocksize))
+#define SB_BLOCK_COUNT(s) \
+        le32_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_block_count))
+#define SB_FREE_BLOCKS(s) \
+        le32_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_free_blocks))
+#define SB_REISERFS_MAGIC(s) \
+        (SB_V1_DISK_SUPER_BLOCK(s)->s_magic)
+#define SB_ROOT_BLOCK(s) \
+        le32_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_root_block))
+#define SB_TREE_HEIGHT(s) \
+        le16_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_tree_height))
+#define SB_REISERFS_STATE(s) \
+        le16_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_umount_state))
+#define SB_VERSION(s) le16_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_version))
+#define SB_BMAP_NR(s) le16_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_bmap_nr))
+
+#define PUT_SB_BLOCK_COUNT(s, val) \
+   do { SB_V1_DISK_SUPER_BLOCK(s)->s_block_count = cpu_to_le32(val); } while (0)
+#define PUT_SB_FREE_BLOCKS(s, val) \
+   do { SB_V1_DISK_SUPER_BLOCK(s)->s_free_blocks = cpu_to_le32(val); } while (0)
+#define PUT_SB_ROOT_BLOCK(s, val) \
+   do { SB_V1_DISK_SUPER_BLOCK(s)->s_root_block = cpu_to_le32(val); } while (0)
+#define PUT_SB_TREE_HEIGHT(s, val) \
+   do { SB_V1_DISK_SUPER_BLOCK(s)->s_tree_height = cpu_to_le16(val); } while (0)
+#define PUT_SB_REISERFS_STATE(s, val) \
+   do { SB_V1_DISK_SUPER_BLOCK(s)->s_umount_state = cpu_to_le16(val); } while (0) 
+#define PUT_SB_VERSION(s, val) \
+   do { SB_V1_DISK_SUPER_BLOCK(s)->s_version = cpu_to_le16(val); } while (0)
+#define PUT_SB_BMAP_NR(s, val) \
+   do { SB_V1_DISK_SUPER_BLOCK(s)->s_bmap_nr = cpu_to_le16 (val); } while (0)
+
+
+#define SB_ONDISK_JP(s) (&SB_V1_DISK_SUPER_BLOCK(s)->s_journal)
+#define SB_ONDISK_JOURNAL_SIZE(s) \
+         le32_to_cpu ((SB_ONDISK_JP(s)->jp_journal_size))
+#define SB_ONDISK_JOURNAL_1st_BLOCK(s) \
+         le32_to_cpu ((SB_ONDISK_JP(s)->jp_journal_1st_block))
+#define SB_ONDISK_JOURNAL_DEVICE(s) \
+         le32_to_cpu ((SB_ONDISK_JP(s)->jp_journal_dev))
+#define SB_ONDISK_RESERVED_FOR_JOURNAL(s) \
+         le32_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_reserved_for_journal))
+
+#define is_block_in_log_or_reserved_area(s, block) \
+         block >= SB_JOURNAL_1st_RESERVED_BLOCK(s) \
+         && block < SB_JOURNAL_1st_RESERVED_BLOCK(s) +  \
+         ((!is_reiserfs_jr(SB_DISK_SUPER_BLOCK(s)) ? \
+         SB_ONDISK_JOURNAL_SIZE(s) + 1 : SB_ONDISK_RESERVED_FOR_JOURNAL(s))) 
+
+
 
 				/* used by gcc */
 #define REISERFS_SUPER_MAGIC 0x52654973
@@ -106,17 +235,17 @@
                                    look at the superblock, etc. */
 #define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
 #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
+#define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs"
+
+extern const char reiserfs_3_5_magic_string[];
+extern const char reiserfs_3_6_magic_string[];
+extern const char reiserfs_jr_magic_string[];
+
+int is_reiserfs_3_5 (struct reiserfs_super_block * rs);
+int is_reiserfs_3_6 (struct reiserfs_super_block * rs);
+int is_reiserfs_jr (struct reiserfs_super_block * rs);
 
-extern char reiserfs_super_magic_string[];
-extern char reiser2fs_super_magic_string[];
 
-static inline int is_reiserfs_magic_string (const struct reiserfs_super_block * rs)
-{
-    return (!strncmp (rs->s_magic, reiserfs_super_magic_string, 
-		      strlen ( reiserfs_super_magic_string)) ||
-	    !strncmp (rs->s_magic, reiser2fs_super_magic_string, 
-		      strlen ( reiser2fs_super_magic_string)));
-}
 
 /* ReiserFS leaves the first 64k unused, so that partition labels have
    enough space.  If someone wants to write a fancy bootloader that
@@ -125,6 +254,7 @@
    platform, or code will break.  -Hans */
 #define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024)
 #define REISERFS_FIRST_BLOCK unused_define
+#define REISERFS_JOURNAL_OFFSET_IN_BYTES REISERFS_DISK_OFFSET_IN_BYTES
 
 /* the spot for the super in versions 3.5 - 3.5.10 (inclusive) */
 #define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024)
@@ -212,7 +342,7 @@
 
 
 /*
- * values for s_state field
+ * values for s_umount_state field
  */
 #define REISERFS_VALID_FS    1
 #define REISERFS_ERROR_FS    2
@@ -419,7 +549,7 @@
 #define V1_DIRENTRY_UNIQUENESS 500
 #define V1_ANY_UNIQUENESS 555 // FIXME: comment is required
 
-extern void reiserfs_warning (const char * fmt, ...);
+extern void reiserfs_warning (struct super_block *, const char * fmt, ...);
 /* __attribute__( ( format ( printf, 1, 2 ) ) ); */
 
 //
@@ -434,7 +564,7 @@
     case V1_DIRECT_UNIQUENESS: return TYPE_DIRECT;
     case V1_DIRENTRY_UNIQUENESS: return TYPE_DIRENTRY;
     default:
-	    reiserfs_warning( "vs-500: unknown uniqueness %d\n", uniqueness);
+	    reiserfs_warning(NULL, "vs-500: unknown uniqueness %d\n", uniqueness);
 	case V1_ANY_UNIQUENESS:
 	    return TYPE_ANY;
     }
@@ -449,7 +579,7 @@
     case TYPE_DIRECT: return V1_DIRECT_UNIQUENESS;
     case TYPE_DIRENTRY: return V1_DIRENTRY_UNIQUENESS;
     default:
-	    reiserfs_warning( "vs-501: unknown type %d\n", type);
+	    reiserfs_warning(NULL, "vs-501: unknown type %d\n", type);
 	case TYPE_ANY:
 	    return V1_ANY_UNIQUENESS;
     }
@@ -1158,6 +1288,7 @@
 
 /* Size of pointer to the unformatted node. */
 #define UNFM_P_SIZE (sizeof(unp_t))
+#define UNFM_P_SHIFT 2
 
 // in in-core inode key is stored on le form
 #define INODE_PKEY(inode) ((struct key *)((inode)->u.reiserfs_i.i_key))
@@ -1518,6 +1649,7 @@
   __u32 j_last_flush_trans_id ;		/* id of last fully flushed transaction */
   __u32 j_first_unflushed_offset ;      /* offset in the log of where to start replay after a crash */
   __u32 j_mount_id ;
+  /* 12 */ struct journal_params jh_journal;
 } ;
 
 extern task_queue reiserfs_commit_thread_tq ;
@@ -1525,7 +1657,10 @@
 
 /* biggest tunable defines are right here */
 #define JOURNAL_BLOCK_COUNT 8192 /* number of blocks in the journal */
-#define JOURNAL_MAX_BATCH   900 /* max blocks to batch into one transaction, don't make this any bigger than 900 */
+#define JOURNAL_TRANS_MAX_DEFAULT 1024   /* biggest possible single transaction, don't change for now (8/3/99) */
+#define JOURNAL_TRANS_MIN_DEFAULT 256
+#define JOURNAL_MAX_BATCH_DEFAULT   900 /* max blocks to batch into one transaction, don't make this any bigger than 900 */
+#define JOURNAL_MIN_RATIO 2
 #define JOURNAL_MAX_COMMIT_AGE 30 
 #define JOURNAL_MAX_TRANS_AGE 30
 #define JOURNAL_PER_BALANCE_CNT (3 * (MAX_HEIGHT-2) + 9)
@@ -1567,7 +1702,10 @@
 void reiserfs_check_lock_depth(char *caller) ;
 void reiserfs_prepare_for_journal(struct super_block *, struct buffer_head *bh, int wait) ;
 void reiserfs_restore_prepared_buffer(struct super_block *, struct buffer_head *bh) ;
-int journal_init(struct super_block *) ;
+struct buffer_head  * journal_bread (struct super_block *s, int block);
+struct buffer_head  * journal_getblk (struct super_block *s, int block);
+struct buffer_head  * journal_get_hash_table (struct super_block *s, int block);
+int journal_init(struct super_block *, const char * j_dev_name, int old_format) ;
 int journal_release(struct reiserfs_transaction_handle*, struct super_block *) ;
 int journal_release_error(struct reiserfs_transaction_handle*, struct super_block *) ;
 int journal_end(struct reiserfs_transaction_handle *, struct super_block *, unsigned long) ;
@@ -2017,9 +2155,6 @@
 __u32 yura_hash (const signed char *msg, int len);
 __u32 r5_hash (const signed char *msg, int len);
 
-/* version.c */
-const char *reiserfs_get_version_string(void) CONSTF;
-
 /* the ext2 bit routines adjust for big or little endian as
 ** appropriate for the arch, so in our laziness we use them rather
 ** than using the bit routines they call more directly.  These
@@ -2038,12 +2173,6 @@
    absolutely safe */
 #define SPARE_SPACE 500
 
-static inline unsigned long reiserfs_get_journal_block(const struct super_block *s) {
-    return le32_to_cpu(SB_DISK_SUPER_BLOCK(s)->s_journal_block) ;
-}
-static inline unsigned long reiserfs_get_journal_orig_size(const struct super_block *s) {
-    return le32_to_cpu(SB_DISK_SUPER_BLOCK(s)->s_orig_journal_size) ;
-}
 
 /* prototypes from ioctl.c */
 int reiserfs_ioctl (struct inode * inode, struct file * filp, 
diff -urN linux-2.4.22-pre2/include/linux/reiserfs_fs_sb.h linux-2.4.22-pre3/include/linux/reiserfs_fs_sb.h
--- linux-2.4.22-pre2/include/linux/reiserfs_fs_sb.h	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/reiserfs_fs_sb.h	2003-07-05 18:11:49.000000000 -0700
@@ -10,7 +10,7 @@
 
 //
 // super block's field values
-//
+//s
 /*#define REISERFS_VERSION 0 undistributed bitmap */
 /*#define REISERFS_VERSION 1 distributed bitmap and resizer*/
 #define REISERFS_VERSION_2 2 /* distributed bitmap, resizer, 64-bit, etc*/
@@ -21,137 +21,75 @@
 #define R5_HASH   3
 #define DEFAULT_HASH R5_HASH
 
-/* this is the on disk super block */
-
-struct reiserfs_super_block
-{
-  __u32 s_block_count;
-  __u32 s_free_blocks;                  /* free blocks count    */
-  __u32 s_root_block;           	/* root block number    */
-  __u32 s_journal_block;           	/* journal block number    */
-  __u32 s_journal_dev;           	/* journal device number  */
-
-  /* Since journal size is currently a #define in a header file, if 
-  ** someone creates a disk with a 16MB journal and moves it to a 
-  ** system with 32MB journal default, they will overflow their journal 
-  ** when they mount the disk.  s_orig_journal_size, plus some checks
-  ** while mounting (inside journal_init) prevent that from happening
-  */
-
-				/* great comment Chris. Thanks.  -Hans */
-
-  __u32 s_orig_journal_size; 		
-  __u32 s_journal_trans_max ;           /* max number of blocks in a transaction.  */
-  __u32 s_journal_block_count ;         /* total size of the journal. can change over time  */
-  __u32 s_journal_max_batch ;           /* max number of blocks to batch into a trans */
-  __u32 s_journal_max_commit_age ;      /* in seconds, how old can an async commit be */
-  __u32 s_journal_max_trans_age ;       /* in seconds, how old can a transaction be */
-  __u16 s_blocksize;                   	/* block size           */
-  __u16 s_oid_maxsize;			/* max size of object id array, see get_objectid() commentary  */
-  __u16 s_oid_cursize;			/* current size of object id array */
-  __u16 s_state;                       	/* valid or error       */
-  char s_magic[12];                     /* reiserfs magic string indicates that file system is reiserfs */
-  __u32 s_hash_function_code;		/* indicate, what hash function is being use to sort names in a directory*/
-  __u16 s_tree_height;                  /* height of disk tree */
-  __u16 s_bmap_nr;                      /* amount of bitmap blocks needed to address each block of file system */
-  __u16 s_version;		/* I'd prefer it if this was a string,
-                                   something like "3.6.4", and maybe
-                                   16 bytes long mostly unused. We
-                                   don't need to save bytes in the
-                                   superblock. -Hans */
-  __u16 s_reserved;
-  __u32 s_inode_generation;
-  __u32 s_flags;		       /* Right now used only by inode-attributes, if enabled */
-  unsigned char s_uuid[16];            /* filesystem unique identifier */
-  unsigned char s_label[16];           /* filesystem volume label */
-  char s_unused[88] ;                  /* zero filled by mkreiserfs and
-                                        * reiserfs_convert_objectid_map_v1()
-                                        * so any additions must be updated
-                                        * there as well. */
-} __attribute__ ((__packed__));
+/* struct reiserfs_super_block accessors/mutators
+ * since this is a disk structure, it will always be in 
+ * little endian format. */
 
 typedef enum {
   reiserfs_attrs_cleared       = 0x00000001,
 } reiserfs_super_block_flags;
 
-#define SB_SIZE (sizeof(struct reiserfs_super_block))
-/* struct reiserfs_super_block accessors/mutators
- * since this is a disk structure, it will always be in 
- * little endian format. */
-#define sb_block_count(sbp)           (le32_to_cpu((sbp)->s_block_count))
-#define set_sb_block_count(sbp,v)     ((sbp)->s_block_count = cpu_to_le32(v))
-#define sb_free_blocks(sbp)           (le32_to_cpu((sbp)->s_free_blocks))
-#define set_sb_free_blocks(sbp,v)     ((sbp)->s_free_blocks = cpu_to_le32(v))
-#define sb_root_block(sbp)            (le32_to_cpu((sbp)->s_root_block))
-#define set_sb_root_block(sbp,v)      ((sbp)->s_root_block = cpu_to_le32(v))
-#define sb_journal_block(sbp)         (le32_to_cpu((sbp)->s_journal_block))
-#define set_sb_journal_block(sbp,v)   ((sbp)->s_journal_block = cpu_to_le32(v))
-#define sb_journal_dev(sbp)           (le32_to_cpu((sbp)->s_journal_dev))
-#define set_sb_journal_dev(sbp,v)     ((sbp)->s_journal_dev = cpu_to_le32(v))
-#define sb_orig_journal_size(sbp)   (le32_to_cpu((sbp)->s_orig_journal_size))
-#define set_sb_orig_journal_size(sbp,v) \
-                            ((sbp)->s_orig_journal_size = cpu_to_le32(v))
-#define sb_journal_trans_max(sbp)     (le32_to_cpu((sbp)->s_journal_trans_max))
-#define set_journal_trans_max(sbp,v) \
-                            ((sbp)->s_journal_trans_max = cpu_to_le32(v))
-#define sb_journal_block_count(sbp)  (le32_to_cpu((sbp)->journal_block_count))
-#define sb_set_journal_block_count(sbp,v) \
-                            ((sbp)->s_journal_block_count = cpu_to_le32(v))
-#define sb_journal_max_batch(sbp)     (le32_to_cpu((sbp)->s_journal_max_batch))
-#define set_sb_journal_max_batch(sbp,v) \
-                            ((sbp)->s_journal_max_batch = cpu_to_le32(v))
-#define sb_jourmal_max_commit_age(sbp) \
-                            (le32_to_cpu((sbp)->s_journal_max_commit_age))
-#define set_sb_journal_max_commit_age(sbp,v) \
-                            ((sbp)->s_journal_max_commit_age = cpu_to_le32(v))
-#define sb_jourmal_max_trans_age(sbp) \
-                            (le32_to_cpu((sbp)->s_journal_max_trans_age))
-#define set_sb_journal_max_trans_age(sbp,v) \
-                            ((sbp)->s_journal_max_trans_age = cpu_to_le32(v))
-#define sb_blocksize(sbp)             (le16_to_cpu((sbp)->s_blocksize))
-#define set_sb_blocksize(sbp,v)       ((sbp)->s_blocksize = cpu_to_le16(v))
-#define sb_oid_maxsize(sbp)           (le16_to_cpu((sbp)->s_oid_maxsize))
-#define set_sb_oid_maxsize(sbp,v)     ((sbp)->s_oid_maxsize = cpu_to_le16(v))
-#define sb_oid_cursize(sbp)           (le16_to_cpu((sbp)->s_oid_cursize))
-#define set_sb_oid_cursize(sbp,v)     ((sbp)->s_oid_cursize = cpu_to_le16(v))
-#define sb_state(sbp)                 (le16_to_cpu((sbp)->s_state))
-#define set_sb_state(sbp,v)           ((sbp)->s_state = cpu_to_le16(v))
+#define sb_block_count(sbp)         (le32_to_cpu((sbp)->s_v1.s_block_count))
+#define set_sb_block_count(sbp,v)   ((sbp)->s_v1.s_block_count = cpu_to_le32(v))
+#define sb_free_blocks(sbp)         (le32_to_cpu((sbp)->s_v1.s_free_blocks))
+#define set_sb_free_blocks(sbp,v)   ((sbp)->s_v1.s_free_blocks = cpu_to_le32(v))
+#define sb_root_block(sbp)          (le32_to_cpu((sbp)->s_v1.s_root_block))
+#define set_sb_root_block(sbp,v)    ((sbp)->s_v1.s_root_block = cpu_to_le32(v))
+
+#define sb_jp_journal_1st_block(sbp)  \
+              (le32_to_cpu((sbp)->s_v1.s_journal.jp_journal_1st_block))
+#define set_sb_jp_journal_1st_block(sbp,v) \
+              ((sbp)->s_v1.s_journal.jp_journal_1st_block = cpu_to_le32(v))
+#define sb_jp_journal_dev(sbp) \
+              (le32_to_cpu((sbp)->s_v1.s_journal.jp_journal_dev))
+#define set_sb_jp_journal_dev(sbp,v) \
+              ((sbp)->s_v1.s_journal.jp_journal_dev = cpu_to_le32(v))
+#define sb_jp_journal_size(sbp) \
+              (le32_to_cpu((sbp)->s_v1.s_journal.jp_journal_size))
+#define set_sb_jp_journal_size(sbp,v) \
+              ((sbp)->s_v1.s_journal.jp_journal_size = cpu_to_le32(v))
+#define sb_jp_journal_trans_max(sbp) \
+              (le32_to_cpu((sbp)->s_v1.s_journal.jp_journal_trans_max))
+#define set_sb_jp_journal_trans_max(sbp,v) \
+              ((sbp)->s_v1.s_journal.jp_journal_trans_max = cpu_to_le32(v))
+#define sb_jp_journal_magic(sbp) \
+              (le32_to_cpu((sbp)->s_v1.s_journal.jp_journal_magic))
+#define set_sb_jp_journal_magic(sbp,v) \
+              ((sbp)->s_v1.s_journal.jp_journal_magic = cpu_to_le32(v))
+#define sb_jp_journal_max_batch(sbp) \
+              (le32_to_cpu((sbp)->s_v1.s_journal.jp_journal_max_batch))
+#define set_sb_jp_journal_max_batch(sbp,v) \
+              ((sbp)->s_v1.s_journal.jp_journal_max_batch = cpu_to_le32(v))
+#define sb_jp_jourmal_max_commit_age(sbp) \
+              (le32_to_cpu((sbp)->s_v1.s_journal.jp_journal_max_commit_age))
+#define set_sb_jp_journal_max_commit_age(sbp,v) \
+              ((sbp)->s_v1.s_journal.jp_journal_max_commit_age = cpu_to_le32(v))
+
+#define sb_blocksize(sbp)          (le16_to_cpu((sbp)->s_v1.s_blocksize))
+#define set_sb_blocksize(sbp,v)    ((sbp)->s_v1.s_blocksize = cpu_to_le16(v))
+#define sb_oid_maxsize(sbp)        (le16_to_cpu((sbp)->s_v1.s_oid_maxsize))
+#define set_sb_oid_maxsize(sbp,v)  ((sbp)->s_v1.s_oid_maxsize = cpu_to_le16(v))
+#define sb_oid_cursize(sbp)        (le16_to_cpu((sbp)->s_v1.s_oid_cursize))
+#define set_sb_oid_cursize(sbp,v)  ((sbp)->s_v1.s_oid_cursize = cpu_to_le16(v))
+#define sb_umount_state(sbp)       (le16_to_cpu((sbp)->s_v1.s_umount_state))
+#define set_sb_umount_state(sbp,v) ((sbp)->s_v1.s_umount_state = cpu_to_le16(v))
+#define sb_fs_state(sbp)           (le16_to_cpu((sbp)->s_v1.s_fs_state))
+#define set_sb_fs_state(sbp,v)     ((sbp)->s_v1.s_fs_state = cpu_to_le16(v)) 
 #define sb_hash_function_code(sbp) \
-                            (le32_to_cpu((sbp)->s_hash_function_code))
+              (le32_to_cpu((sbp)->s_v1.s_hash_function_code))
 #define set_sb_hash_function_code(sbp,v) \
-                            ((sbp)->s_hash_function_code = cpu_to_le32(v))
-#define sb_tree_height(sbp)           (le16_to_cpu((sbp)->s_tree_height))
-#define set_sb_tree_height(sbp,v)     ((sbp)->s_tree_height = cpu_to_le16(v))
-#define sb_bmap_nr(sbp)               (le16_to_cpu((sbp)->s_bmap_nr))
-#define set_sb_bmap_nr(sbp,v)         ((sbp)->s_bmap_nr = cpu_to_le16(v))
-#define sb_version(sbp)               (le16_to_cpu((sbp)->s_version))
-#define set_sb_version(sbp,v)         ((sbp)->s_version = cpu_to_le16(v))
-
-/* this is the super from 3.5.X, where X >= 10 */
-struct reiserfs_super_block_v1
-{
-  __u32 s_block_count;			/* blocks count         */
-  __u32 s_free_blocks;                  /* free blocks count    */
-  __u32 s_root_block;           	/* root block number    */
-  __u32 s_journal_block;           	/* journal block number    */
-  __u32 s_journal_dev;           	/* journal device number  */
-  __u32 s_orig_journal_size; 		/* size of the journal on FS creation.  used to make sure they don't overflow it */
-  __u32 s_journal_trans_max ;           /* max number of blocks in a transaction.  */
-  __u32 s_journal_block_count ;         /* total size of the journal. can change over time  */
-  __u32 s_journal_max_batch ;           /* max number of blocks to batch into a trans */
-  __u32 s_journal_max_commit_age ;      /* in seconds, how old can an async commit be */
-  __u32 s_journal_max_trans_age ;       /* in seconds, how old can a transaction be */
-  __u16 s_blocksize;                   	/* block size           */
-  __u16 s_oid_maxsize;			/* max size of object id array, see get_objectid() commentary  */
-  __u16 s_oid_cursize;			/* current size of object id array */
-  __u16 s_state;                       	/* valid or error       */
-  char s_magic[16];                     /* reiserfs magic string indicates that file system is reiserfs */
-  __u16 s_tree_height;                  /* height of disk tree */
-  __u16 s_bmap_nr;                      /* amount of bitmap blocks needed to address each block of file system */
-  __u32 s_reserved;
-} __attribute__ ((__packed__));
-
-#define SB_SIZE_V1 (sizeof(struct reiserfs_super_block_v1))
+              ((sbp)->s_v1.s_hash_function_code = cpu_to_le32(v))
+#define sb_tree_height(sbp)        (le16_to_cpu((sbp)->s_v1.s_tree_height))
+#define set_sb_tree_height(sbp,v)  ((sbp)->s_v1.s_tree_height = cpu_to_le16(v))
+#define sb_bmap_nr(sbp)            (le16_to_cpu((sbp)->s_v1.s_bmap_nr))
+#define set_sb_bmap_nr(sbp,v)      ((sbp)->s_v1.s_bmap_nr = cpu_to_le16(v))
+#define sb_version(sbp)            (le16_to_cpu((sbp)->s_v1.s_version))
+#define set_sb_version(sbp,v)      ((sbp)->s_v1.s_version = cpu_to_le16(v))
+
+#define sb_reserved_for_journal(sbp) \
+              (le16_to_cpu((sbp)->s_v1.s_reserved_for_journal))
+#define set_sb_reserved_for_journal(sbp,v) \
+              ((sbp)->s_v1.s_reserved_for_journal = cpu_to_le16(v))
 
 /* LOGGING -- */
 
@@ -180,7 +118,6 @@
 				/* we have a node size define somewhere in reiserfs_fs.h. -Hans */
 #define JOURNAL_BLOCK_SIZE  4096 /* BUG gotta get rid of this */
 #define JOURNAL_MAX_CNODE   1500 /* max cnodes to allocate. */
-#define JOURNAL_TRANS_MAX 1024   /* biggest possible single transaction, don't change for now (8/3/99) */
 #define JOURNAL_HASH_SIZE 8192   
 #define JOURNAL_NUM_BITMAPS 5 /* number of copies of the bitmaps to have floating.  Must be >= 2 */
 #define JOURNAL_LIST_COUNT 64
@@ -275,7 +212,12 @@
   struct buffer_head ** j_ap_blocks ; /* journal blocks on disk */
   struct reiserfs_journal_cnode *j_last ; /* newest journal block */
   struct reiserfs_journal_cnode *j_first ; /*  oldest journal block.  start here for traverse */
-				
+
+  kdev_t               j_dev;
+  struct file         *j_dev_file;
+  struct block_device *j_dev_bd;  
+	int j_1st_reserved_block;     /* first block of journal or reserved area on */
+				      /* _MAIN_ device, it is calculated by macro during mount */        
   long j_state ;			
   unsigned long j_trans_id ;
   unsigned long j_mount_id ;
@@ -306,6 +248,11 @@
   int j_cnode_used ;	      /* number of cnodes on the used list */
   int j_cnode_free ;          /* number of cnodes on the free list */
 
+  unsigned int s_journal_trans_max ;           /* max number of blocks in a transaction.  */
+  unsigned int s_journal_max_batch ;           /* max number of blocks to batch into a trans */
+  unsigned int s_journal_max_commit_age ;      /* in seconds, how old can an async commit be */
+  unsigned int s_journal_max_trans_age ;       /* in seconds, how old can a transaction be */  
+
   struct reiserfs_journal_cnode *j_cnode_free_list ;
   struct reiserfs_journal_cnode *j_cnode_free_orig ; /* orig pointer returned from vmalloc */
 
@@ -544,29 +491,19 @@
 
 #define SB_BUFFER_WITH_SB(s) ((s)->u.reiserfs_sb.s_sbh)
 #define SB_JOURNAL(s) ((s)->u.reiserfs_sb.s_journal)
+#define SB_JOURNAL_1st_RESERVED_BLOCK(s) (SB_JOURNAL(s)->j_1st_reserved_block)
 #define SB_JOURNAL_LIST(s) (SB_JOURNAL(s)->j_journal_list)
 #define SB_JOURNAL_LIST_INDEX(s) (SB_JOURNAL(s)->j_journal_list_index) 
 #define SB_JOURNAL_LEN_FREE(s) (SB_JOURNAL(s)->j_journal_len_free) 
 #define SB_AP_BITMAP(s) ((s)->u.reiserfs_sb.s_ap_bitmap)
 
+#define SB_DISK_JOURNAL_HEAD(s) (SB_JOURNAL(s)->j_header_bh->)
 
-// on-disk super block fields converted to cpu form
-#define SB_DISK_SUPER_BLOCK(s)        ((s)->u.reiserfs_sb.s_rs)
-#define SB_BLOCK_COUNT(s)             sb_block_count (SB_DISK_SUPER_BLOCK(s))
-#define SB_FREE_BLOCKS(s)             sb_free_blocks (SB_DISK_SUPER_BLOCK(s))
-#define SB_REISERFS_MAGIC(s)          (SB_DISK_SUPER_BLOCK(s)->s_magic)
-#define SB_ROOT_BLOCK(s)              sb_root_block (SB_DISK_SUPER_BLOCK(s))
-#define SB_TREE_HEIGHT(s)             sb_tree_height (SB_DISK_SUPER_BLOCK(s))
-#define SB_REISERFS_STATE(s)          sb_state (SB_DISK_SUPER_BLOCK(s))
-#define SB_VERSION(s)                 sb_version (SB_DISK_SUPER_BLOCK(s))
-#define SB_BMAP_NR(s)                 sb_bmap_nr(SB_DISK_SUPER_BLOCK(s))
-
-#define PUT_SB_BLOCK_COUNT(s, val)    do { set_sb_block_count( SB_DISK_SUPER_BLOCK(s), val); } while (0)
-#define PUT_SB_FREE_BLOCKS(s, val)    do { set_sb_free_blocks( SB_DISK_SUPER_BLOCK(s), val); } while (0)
-#define PUT_SB_ROOT_BLOCK(s, val)     do { set_sb_root_block( SB_DISK_SUPER_BLOCK(s), val); } while (0)
-#define PUT_SB_TREE_HEIGHT(s, val)    do { set_sb_tree_height( SB_DISK_SUPER_BLOCK(s), val); } while (0)
-#define PUT_SB_REISERFS_STATE(s, val) do { set_sb_state( SB_DISK_SUPER_BLOCK(s), val); } while (0) 
-#define PUT_SB_VERSION(s, val)        do { set_sb_version( SB_DISK_SUPER_BLOCK(s), val); } while (0)
-#define PUT_SB_BMAP_NR(s, val)        do { set_sb_bmap_nr( SB_DISK_SUPER_BLOCK(s), val); } while (0)
+#define SB_JOURNAL_TRANS_MAX(s)      (SB_JOURNAL(s)->s_journal_trans_max)
+#define SB_JOURNAL_MAX_BATCH(s)      (SB_JOURNAL(s)->s_journal_max_batch)
+#define SB_JOURNAL_MAX_COMMIT_AGE(s) (SB_JOURNAL(s)->s_journal_max_commit_age)
+#define SB_JOURNAL_MAX_TRANS_AGE(s)  (SB_JOURNAL(s)->s_journal_max_trans_age)
+#define SB_JOURNAL_DEV(s)            (SB_JOURNAL(s)->j_dev)
+  
 
 #endif	/* _LINUX_REISER_FS_SB */
diff -urN linux-2.4.22-pre2/include/linux/sem.h linux-2.4.22-pre3/include/linux/sem.h
--- linux-2.4.22-pre2/include/linux/sem.h	2001-11-22 11:46:18.000000000 -0800
+++ linux-2.4.22-pre3/include/linux/sem.h	2003-07-05 18:11:49.000000000 -0700
@@ -124,6 +124,8 @@
 asmlinkage long sys_semget (key_t key, int nsems, int semflg);
 asmlinkage long sys_semop (int semid, struct sembuf *sops, unsigned nsops);
 asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg);
+asmlinkage long sys_semtimedop (int semid, struct sembuf *sops, 
+			unsigned nsops, const struct timespec *timeout);
 
 #endif /* __KERNEL__ */
 
diff -urN linux-2.4.22-pre2/include/linux/shmem_fs.h linux-2.4.22-pre3/include/linux/shmem_fs.h
--- linux-2.4.22-pre2/include/linux/shmem_fs.h	2001-12-21 09:42:03.000000000 -0800
+++ linux-2.4.22-pre3/include/linux/shmem_fs.h	2003-07-05 18:11:49.000000000 -0700
@@ -17,16 +17,13 @@
 	unsigned long val;
 } swp_entry_t;
 
-extern atomic_t shmem_nrpages;
-
 struct shmem_inode_info {
 	spinlock_t		lock;
-	struct semaphore 	sem;
 	unsigned long		next_index;
 	swp_entry_t		i_direct[SHMEM_NR_DIRECT]; /* for the first blocks */
 	void		      **i_indirect; /* indirect blocks */
-	unsigned long		swapped;
-	int			locked;     /* into memory */
+	unsigned long		swapped;    /* data pages assigned to swap */
+	unsigned long		flags;
 	struct list_head	list;
 	struct inode	       *inode;
 };
diff -urN linux-2.4.22-pre2/include/linux/sisfb.h linux-2.4.22-pre3/include/linux/sisfb.h
--- linux-2.4.22-pre2/include/linux/sisfb.h	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/sisfb.h	2003-07-05 18:11:50.000000000 -0700
@@ -87,6 +87,7 @@
 	SIS_650,
 	SIS_740,
 	SIS_330,
+	SIS_660,
 	MAX_SIS_CHIP
 } SIS_CHIP_TYPE;
 
diff -urN linux-2.4.22-pre2/include/linux/sunrpc/xprt.h linux-2.4.22-pre3/include/linux/sunrpc/xprt.h
--- linux-2.4.22-pre2/include/linux/sunrpc/xprt.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/include/linux/sunrpc/xprt.h	2003-07-05 18:11:50.000000000 -0700
@@ -44,6 +44,19 @@
 #define RPC_MAX_UDP_TIMEOUT	(60*HZ)
 #define RPC_MAX_TCP_TIMEOUT	(600*HZ)
 
+/*
+ *  * Wait duration for an RPC TCP connection to be established.  Solaris
+ *   * NFS over TCP uses 60 seconds, for example, which is in line with how
+ *    * long a server takes to reboot.
+ *     */
+#define RPC_CONNECT_TIMEOUT	(60*HZ)
+
+/*
+ *  * Delay an arbitrary number of seconds before attempting to reconnect
+ *   * after an error.
+ *    */
+#define RPC_REESTABLISH_TIMEOUT	(15*HZ)
+
 /* RPC call and reply header size as number of 32bit words (verifier
  * size computed separately)
  */
@@ -57,8 +70,7 @@
 	unsigned long		to_current,		/* current timeout */
 				to_initval,		/* initial timeout */
 				to_maxval,		/* max timeout */
-				to_increment,		/* if !exponential */
-				to_resrvval;		/* reserve timeout */
+				to_increment;		/* if !exponential */
 	short			to_retries;		/* max # of retries */
 	unsigned char		to_exponential;
 };
@@ -134,6 +146,7 @@
 	unsigned long		sockstate;	/* Socket state */
 	unsigned char		shutdown   : 1,	/* being shut down */
 				nocong	   : 1,	/* no congestion control */
+				resvport   : 1, /* use a reserved port */
 				stream     : 1;	/* TCP */
 
 	/*
@@ -173,18 +186,18 @@
 void			xprt_set_timeout(struct rpc_timeout *, unsigned int,
 					unsigned long);
 
-int			xprt_reserve(struct rpc_task *);
+void			xprt_reserve(struct rpc_task *);
 void			xprt_transmit(struct rpc_task *);
 void			xprt_receive(struct rpc_task *);
 int			xprt_adjust_timeout(struct rpc_timeout *);
 void			xprt_release(struct rpc_task *);
-void			xprt_reconnect(struct rpc_task *);
+void			xprt_connect(struct rpc_task *);
 int			xprt_clear_backlog(struct rpc_xprt *);
 void			xprt_sock_setbufsize(struct rpc_xprt *);
 
 #define XPRT_CONNECT	0
 
-#define xprt_connected(xp)		(!(xp)->stream || test_bit(XPRT_CONNECT, &(xp)->sockstate))
+#define xprt_connected(xp)		(test_bit(XPRT_CONNECT, &(xp)->sockstate))
 #define xprt_set_connected(xp)		(set_bit(XPRT_CONNECT, &(xp)->sockstate))
 #define xprt_test_and_set_connected(xp)	(test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate))
 #define xprt_clear_connected(xp)	(clear_bit(XPRT_CONNECT, &(xp)->sockstate))
diff -urN linux-2.4.22-pre2/include/linux/swap.h linux-2.4.22-pre3/include/linux/swap.h
--- linux-2.4.22-pre2/include/linux/swap.h	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/swap.h	2003-07-05 18:11:50.000000000 -0700
@@ -210,7 +210,7 @@
 #define swap_device_lock(p)	spin_lock(&p->sdev_lock)
 #define swap_device_unlock(p)	spin_unlock(&p->sdev_lock)
 
-extern void shmem_unuse(swp_entry_t entry, struct page *page);
+extern int shmem_unuse(swp_entry_t entry, struct page *page);
 
 #endif /* __KERNEL__*/
 
diff -urN linux-2.4.22-pre2/include/linux/sysctl.h linux-2.4.22-pre3/include/linux/sysctl.h
--- linux-2.4.22-pre2/include/linux/sysctl.h	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/include/linux/sysctl.h	2003-07-05 18:11:50.000000000 -0700
@@ -126,6 +126,7 @@
 	KERN_CADPID=54,		/* int: PID of the process to notify on CAD */
  	KERN_CORE_PATTERN=56,	/* string: pattern for core-files */
 	KERN_PPC_L3CR=57,       /* l3cr register on PPC */
+	KERN_EXCEPTION_TRACE=58, /* boolean: exception trace */
 };
 
 
diff -urN linux-2.4.22-pre2/include/net/atmclip.h linux-2.4.22-pre3/include/net/atmclip.h
--- linux-2.4.22-pre2/include/net/atmclip.h	2001-11-22 11:49:31.000000000 -0800
+++ linux-2.4.22-pre3/include/net/atmclip.h	2003-07-05 18:11:50.000000000 -0700
@@ -55,13 +55,22 @@
 };
 
 
-extern struct atm_vcc *atmarpd; /* ugly */
-extern struct neigh_table clip_tbl;
+#ifdef __KERNEL__
+struct atm_clip_ops {
+	int (*clip_create)(int number);
+	int (*clip_mkip)(struct atm_vcc *vcc,int timeout);
+	int (*clip_setentry)(struct atm_vcc *vcc,u32 ip);
+	int (*clip_encap)(struct atm_vcc *vcc,int mode);
+	void (*clip_push)(struct atm_vcc *vcc,struct sk_buff *skb);
+	int (*atm_init_atmarp)(struct atm_vcc *vcc);
+	struct module *owner;
+};
+
+void atm_clip_ops_set(struct atm_clip_ops *);
+int try_atm_clip_ops(void);
 
-int clip_create(int number);
-int clip_mkip(struct atm_vcc *vcc,int timeout);
-int clip_setentry(struct atm_vcc *vcc,u32 ip);
-int clip_encap(struct atm_vcc *vcc,int mode);
-void atm_clip_init(void);
+extern struct neigh_table *clip_tbl_hook;
+extern struct atm_clip_ops *atm_clip_ops;
+#endif
 
 #endif
diff -urN linux-2.4.22-pre2/include/net/dst.h linux-2.4.22-pre3/include/net/dst.h
--- linux-2.4.22-pre2/include/net/dst.h	2001-11-22 11:47:14.000000000 -0800
+++ linux-2.4.22-pre3/include/net/dst.h	2003-07-05 18:11:51.000000000 -0700
@@ -18,8 +18,8 @@
  */
 #define RT_CACHE_DEBUG		0
 
-#define DST_GC_MIN	(1*HZ)
-#define DST_GC_INC	(5*HZ)
+#define DST_GC_MIN	(HZ/10)
+#define DST_GC_INC	(HZ/2)
 #define DST_GC_MAX	(120*HZ)
 
 struct sk_buff;
diff -urN linux-2.4.22-pre2/init/do_mounts.c linux-2.4.22-pre3/init/do_mounts.c
--- linux-2.4.22-pre2/init/do_mounts.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/init/do_mounts.c	2003-07-05 18:11:51.000000000 -0700
@@ -15,6 +15,7 @@
 #include <linux/minix_fs.h>
 #include <linux/ext2_fs.h>
 #include <linux/romfs_fs.h>
+#include <linux/cramfs_fs.h>
 
 #define BUILD_CRAMDISK
 
@@ -474,6 +475,7 @@
  * 	minix
  * 	ext2
  *	romfs
+ *	cramfs
  * 	gzip
  */
 static int __init 
@@ -483,6 +485,7 @@
 	struct minix_super_block *minixsb;
 	struct ext2_super_block *ext2sb;
 	struct romfs_super_block *romfsb;
+	struct cramfs_super *cramfsb;
 	int nblocks = -1;
 	unsigned char *buf;
 
@@ -493,6 +496,7 @@
 	minixsb = (struct minix_super_block *) buf;
 	ext2sb = (struct ext2_super_block *) buf;
 	romfsb = (struct romfs_super_block *) buf;
+	cramfsb = (struct cramfs_super *) buf;
 	memset(buf, 0xe5, size);
 
 	/*
@@ -522,6 +526,14 @@
 		goto done;
 	}
 
+	if (cramfsb->magic == CRAMFS_MAGIC) {
+		printk(KERN_NOTICE
+		       "RAMDISK: cramfs filesystem found at block %d\n",
+		       start_block);
+		nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
+		goto done;
+	}
+
 	/*
 	 * Read block 1 to test for minix and ext2 superblock
 	 */
@@ -908,6 +920,8 @@
 	mount_devfs_fs ();
 }
 
+#ifdef CONFIG_BLK_DEV_RAM
+
 #if defined(BUILD_CRAMDISK) && defined(CONFIG_BLK_DEV_RAM)
 
 /*
@@ -1054,3 +1068,4 @@
 }
 
 #endif  /* BUILD_CRAMDISK && CONFIG_BLK_DEV_RAM */
+#endif  /* CONFIG_BLK_DEV_RAM */
diff -urN linux-2.4.22-pre2/ipc/sem.c linux-2.4.22-pre3/ipc/sem.c
--- linux-2.4.22-pre2/ipc/sem.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/ipc/sem.c	2003-07-05 18:11:52.000000000 -0700
@@ -62,6 +62,7 @@
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/time.h>
 #include <asm/uaccess.h>
 #include "util.h"
 
@@ -251,39 +252,38 @@
 	for (sop = sops; sop < sops + nsops; sop++) {
 		curr = sma->sem_base + sop->sem_num;
 		sem_op = sop->sem_op;
-
-		if (!sem_op && curr->semval)
+		result = curr->semval;
+  
+		if (!sem_op && result)
 			goto would_block;
 
-		curr->sempid = (curr->sempid << 16) | pid;
-		curr->semval += sem_op;
-		if (sop->sem_flg & SEM_UNDO)
-		{
+		result += sem_op;
+		if (result < 0)
+			goto would_block;
+		if (result > SEMVMX)
+			goto out_of_range;
+		if (sop->sem_flg & SEM_UNDO) {
 			int undo = un->semadj[sop->sem_num] - sem_op;
 			/*
 	 		 *	Exceeding the undo range is an error.
 			 */
 			if (undo < (-SEMAEM - 1) || undo > SEMAEM)
-			{
-				/* Don't undo the undo */
-				sop->sem_flg &= ~SEM_UNDO;
 				goto out_of_range;
-			}
-			un->semadj[sop->sem_num] = undo;
 		}
-		if (curr->semval < 0)
-			goto would_block;
-		if (curr->semval > SEMVMX)
-			goto out_of_range;
+		curr->semval = result;
 	}
 
-	if (do_undo)
-	{
-		sop--;
+	if (do_undo) {
 		result = 0;
 		goto undo;
 	}
-
+	sop--;
+	while (sop >= sops) {
+		sma->sem_base[sop->sem_num].sempid = pid;
+		if (sop->sem_flg & SEM_UNDO)
+			un->semadj[sop->sem_num] -= sop->sem_op;
+		sop--;
+	}
 	sma->sem_otime = CURRENT_TIME;
 	return 0;
 
@@ -298,13 +298,9 @@
 		result = 1;
 
 undo:
+	sop--;
 	while (sop >= sops) {
-		curr = sma->sem_base + sop->sem_num;
-		curr->semval -= sop->sem_op;
-		curr->sempid >>= 16;
-
-		if (sop->sem_flg & SEM_UNDO)
-			un->semadj[sop->sem_num] += sop->sem_op;
+		sma->sem_base[sop->sem_num].semval -= sop->sem_op;
 		sop--;
 	}
 
@@ -624,7 +620,7 @@
 		err = curr->semval;
 		goto out_unlock;
 	case GETPID:
-		err = curr->sempid & 0xffff;
+		err = curr->sempid;
 		goto out_unlock;
 	case GETNCNT:
 		err = count_semncnt(sma,semnum);
@@ -839,6 +835,12 @@
 
 asmlinkage long sys_semop (int semid, struct sembuf *tsops, unsigned nsops)
 {
+	return sys_semtimedop(semid, tsops, nsops, NULL);
+}
+
+asmlinkage long sys_semtimedop (int semid, struct sembuf *tsops,
+			unsigned nsops, const struct timespec *timeout)
+{
 	int error = -EINVAL;
 	struct sem_array *sma;
 	struct sembuf fast_sops[SEMOPM_FAST];
@@ -846,6 +848,7 @@
 	struct sem_undo *un;
 	int undos = 0, decrease = 0, alter = 0;
 	struct sem_queue queue;
+	unsigned long jiffies_left = 0;
 
 	if (nsops < 1 || semid < 0)
 		return -EINVAL;
@@ -860,6 +863,19 @@
 		error=-EFAULT;
 		goto out_free;
 	}
+	if (timeout) {
+		struct timespec _timeout;
+		if (copy_from_user(&_timeout, timeout, sizeof(*timeout))) {
+			error = -EFAULT;
+			goto out_free;
+		}
+		if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 ||
+		    _timeout.tv_nsec >= 1000000000L) {
+			error = -EINVAL;
+			goto out_free;
+		}
+		jiffies_left = timespec_to_jiffies(&_timeout);
+	}
 	sma = sem_lock(semid);
 	error=-EINVAL;
 	if(sma==NULL)
@@ -932,7 +948,10 @@
 		current->state = TASK_INTERRUPTIBLE;
 		sem_unlock(semid);
 
-		schedule();
+		if (timeout)
+			jiffies_left = schedule_timeout(jiffies_left);
+		else
+			schedule();
 
 		tmp = sem_lock(semid);
 		if(tmp==NULL) {
@@ -957,6 +976,8 @@
 				break;
 		} else {
 			error = queue.status;
+			if (error == -EINTR && timeout && jiffies_left == 0)
+				error = -EAGAIN;
 			if (queue.prev) /* got Interrupt */
 				break;
 			/* Everything done by update_queue */
diff -urN linux-2.4.22-pre2/ipc/util.c linux-2.4.22-pre3/ipc/util.c
--- linux-2.4.22-pre2/ipc/util.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/ipc/util.c	2003-07-05 18:11:52.000000000 -0700
@@ -359,6 +359,12 @@
 	return -ENOSYS;
 }
 
+asmlinkage long sys_semtimedop(int semid, struct sembuf *sops, unsigned nsops,
+			       const struct timespec *timeout)
+{
+	return -ENOSYS;
+}
+
 asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
 {
 	return -ENOSYS;
diff -urN linux-2.4.22-pre2/kernel/exec_domain.c linux-2.4.22-pre3/kernel/exec_domain.c
--- linux-2.4.22-pre2/kernel/exec_domain.c	2002-02-25 11:38:13.000000000 -0800
+++ linux-2.4.22-pre3/kernel/exec_domain.c	2003-07-05 18:11:53.000000000 -0700
@@ -196,8 +196,6 @@
 
 	put_exec_domain(oep);
 
-	printk(KERN_DEBUG "[%s:%d]: set personality to %lx\n",
-			current->comm, current->pid, personality);
 	return 0;
 }
 
diff -urN linux-2.4.22-pre2/kernel/ksyms.c linux-2.4.22-pre3/kernel/ksyms.c
--- linux-2.4.22-pre2/kernel/ksyms.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/kernel/ksyms.c	2003-07-05 18:11:53.000000000 -0700
@@ -296,6 +296,7 @@
 EXPORT_SYMBOL(filemap_fdatawait);
 EXPORT_SYMBOL(lock_page);
 EXPORT_SYMBOL(unlock_page);
+EXPORT_SYMBOL(wakeup_page_waiters);
 
 /* device registration */
 EXPORT_SYMBOL(register_chrdev);
@@ -592,3 +593,7 @@
 
 /* debug */
 EXPORT_SYMBOL(dump_stack);
+
+/* To match ksyms with System.map */
+extern const char _end[];
+EXPORT_SYMBOL(_end);
diff -urN linux-2.4.22-pre2/kernel/module.c linux-2.4.22-pre3/kernel/module.c
--- linux-2.4.22-pre2/kernel/module.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/kernel/module.c	2003-07-05 18:11:53.000000000 -0700
@@ -345,10 +345,10 @@
 asmlinkage long
 sys_init_module(const char *name_user, struct module *mod_user)
 {
-	struct module mod_tmp, *mod;
+	struct module mod_tmp, *mod, *mod2 = NULL;
 	char *name, *n_name, *name_tmp = NULL;
 	long namelen, n_namelen, i, error;
-	unsigned long mod_user_size;
+	unsigned long mod_user_size, flags;
 	struct module_ref *dep;
 
 	if (!capable(CAP_SYS_MODULE))
@@ -387,11 +387,23 @@
 	}
 	strcpy(name_tmp, mod->name);
 
-	error = copy_from_user(mod, mod_user, mod_user_size);
+	/* Copying mod_user directly over mod breaks the module_list chain and
+	 * races against search_exception_table.  copy_from_user may sleep so it
+	 * cannot be under modlist_lock, do the copy in two stages.
+	 */
+	if (!(mod2 = vmalloc(mod_user_size))) {
+		error = -ENOMEM;
+		goto err2;
+	}
+	error = copy_from_user(mod2, mod_user, mod_user_size);
 	if (error) {
 		error = -EFAULT;
 		goto err2;
 	}
+	spin_lock_irqsave(&modlist_lock, flags);
+	memcpy(mod, mod2, mod_user_size);
+	mod->next = mod_tmp.next;
+	spin_unlock_irqrestore(&modlist_lock, flags);
 
 	/* Sanity check the size of the module.  */
 	error = -EINVAL;
@@ -505,7 +517,6 @@
 	   to make the I and D caches consistent.  */
 	flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size);
 
-	mod->next = mod_tmp.next;
 	mod->refs = NULL;
 
 	/* Sanity check the module's dependents */
@@ -571,6 +582,8 @@
 err1:
 	put_mod_name(name);
 err0:
+	if (mod2)
+		vfree(mod2);
 	unlock_kernel();
 	kfree(name_tmp);
 	return error;
diff -urN linux-2.4.22-pre2/kernel/printk.c linux-2.4.22-pre3/kernel/printk.c
--- linux-2.4.22-pre2/kernel/printk.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/kernel/printk.c	2003-07-05 18:11:53.000000000 -0700
@@ -556,7 +556,14 @@
 {
 	struct console *c;
 
-	acquire_console_sem();
+	/*
+	 * Try to get the console semaphore. If someone else owns it
+	 * we have to return without unblanking because console_unblank
+	 * may be called in interrupt context.
+	 */
+	if (down_trylock(&console_sem) != 0)
+		return;
+	console_may_schedule = 0;
 	for (c = console_drivers; c != NULL; c = c->next)
 		if ((c->flags & CON_ENABLED) && c->unblank)
 			c->unblank();
diff -urN linux-2.4.22-pre2/kernel/sys.c linux-2.4.22-pre3/kernel/sys.c
--- linux-2.4.22-pre2/kernel/sys.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/kernel/sys.c	2003-07-05 18:11:54.000000000 -0700
@@ -1045,6 +1045,7 @@
 asmlinkage long sys_sethostname(char *name, int len)
 {
 	int errno;
+	char tmp[__NEW_UTS_LEN];
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -1052,7 +1053,8 @@
 		return -EINVAL;
 	down_write(&uts_sem);
 	errno = -EFAULT;
-	if (!copy_from_user(system_utsname.nodename, name, len)) {
+	if (!copy_from_user(tmp, name, len)) {
+		memcpy(system_utsname.nodename, tmp, len);
 		system_utsname.nodename[len] = 0;
 		errno = 0;
 	}
@@ -1084,6 +1086,7 @@
 asmlinkage long sys_setdomainname(char *name, int len)
 {
 	int errno;
+	char tmp[__NEW_UTS_LEN];
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -1092,9 +1095,10 @@
 
 	down_write(&uts_sem);
 	errno = -EFAULT;
-	if (!copy_from_user(system_utsname.domainname, name, len)) {
-		errno = 0;
+	if (!copy_from_user(tmp, name, len)) {
+		memcpy(system_utsname.domainname, tmp, len);
 		system_utsname.domainname[len] = 0;
+		errno = 0;
 	}
 	up_write(&uts_sem);
 	return errno;
diff -urN linux-2.4.22-pre2/kernel/sysctl.c linux-2.4.22-pre3/kernel/sysctl.c
--- linux-2.4.22-pre2/kernel/sysctl.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/kernel/sysctl.c	2003-07-05 18:11:54.000000000 -0700
@@ -75,6 +75,8 @@
 extern int sem_ctls[];
 #endif
 
+extern int exception_trace;
+
 #ifdef __sparc__
 extern char reboot_command [];
 extern int stop_a_enabled;
@@ -263,6 +265,10 @@
 	{KERN_S390_USER_DEBUG_LOGGING,"userprocess_debug",
 	 &sysctl_userprocess_debug,sizeof(int),0644,NULL,&proc_dointvec},
 #endif
+#ifdef __x86_64__
+	{KERN_EXCEPTION_TRACE,"exception-trace",
+	 &exception_trace,sizeof(int),0644,NULL,&proc_dointvec},
+#endif	
 	{0}
 };
 
diff -urN linux-2.4.22-pre2/lib/Config.in linux-2.4.22-pre3/lib/Config.in
--- linux-2.4.22-pre2/lib/Config.in	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/lib/Config.in	2003-07-05 18:11:54.000000000 -0700
@@ -11,12 +11,14 @@
 #
 if [ "$CONFIG_CRAMFS" = "y" -o \
      "$CONFIG_PPP_DEFLATE" = "y" -o \
+     "$CONFIG_CRYPTO_DEFLATE" = "y" -o \
      "$CONFIG_JFFS2_FS" = "y" -o \
      "$CONFIG_ZISOFS_FS" = "y" ]; then
    define_tristate CONFIG_ZLIB_INFLATE y
 else
   if [ "$CONFIG_CRAMFS" = "m" -o \
        "$CONFIG_PPP_DEFLATE" = "m" -o \
+       "$CONFIG_CRYPTO_DEFLATE" = "m" -o \
        "$CONFIG_JFFS2_FS" = "m" -o \
        "$CONFIG_ZISOFS_FS" = "m" ]; then
      define_tristate CONFIG_ZLIB_INFLATE m
@@ -26,10 +28,12 @@
 fi
 
 if [ "$CONFIG_PPP_DEFLATE" = "y" -o \
+     "$CONFIG_CRYPTO_DEFLATE" = "y" -o \
      "$CONFIG_JFFS2_FS" = "y" ]; then
    define_tristate CONFIG_ZLIB_DEFLATE y
 else
   if [ "$CONFIG_PPP_DEFLATE" = "m" -o \
+       "$CONFIG_CRYPTO_DEFLATE" = "m" -o \
        "$CONFIG_JFFS2_FS" = "m" ]; then
      define_tristate CONFIG_ZLIB_DEFLATE m
   else
diff -urN linux-2.4.22-pre2/mm/filemap.c linux-2.4.22-pre3/mm/filemap.c
--- linux-2.4.22-pre2/mm/filemap.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/mm/filemap.c	2003-07-05 18:11:54.000000000 -0700
@@ -810,6 +810,20 @@
 	return &wait[hash];
 }
 
+/*
+ * This must be called after every submit_bh with end_io
+ * callbacks that would result into the blkdev layer waking
+ * up the page after a queue unplug.
+ */
+void wakeup_page_waiters(struct page * page)
+{
+	wait_queue_head_t * head;
+
+	head = page_waitqueue(page);
+	if (waitqueue_active(head))
+		wake_up(head);
+}
+
 /* 
  * Wait for a page to get unlocked.
  *
@@ -2491,14 +2505,17 @@
 {
 	long error = -EBADF;
 	struct file * file;
+	struct inode * inode;
 	unsigned long size, rlim_rss;
 
 	/* Doesn't work if there's no mapped file. */
 	if (!vma->vm_file)
 		return error;
 	file = vma->vm_file;
-	size = (file->f_dentry->d_inode->i_size + PAGE_CACHE_SIZE - 1) >>
-							PAGE_CACHE_SHIFT;
+	inode = file->f_dentry->d_inode;
+	if (!inode->i_mapping->a_ops->readpage)
+		return error;
+	size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 
 	start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 	if (end > vma->vm_end)
@@ -2957,8 +2974,8 @@
  * on it.  Contains the common precheck code for both buffered and direct
  * IO.
  */
-static int precheck_file_write(struct file *file, struct inode *inode,
-			       size_t *count, loff_t *ppos)
+int precheck_file_write(struct file *file, struct inode *inode,
+			size_t *count, loff_t *ppos)
 {
 	ssize_t		err;
 	unsigned long	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
@@ -3048,13 +3065,6 @@
 	}
 
 	err = 0;
-	if (*count == 0)
-		goto out;
-
-	remove_suid(inode);
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-	mark_inode_dirty_sync(inode);
-	
 out:
 	return err;
 }
@@ -3089,11 +3099,15 @@
 	cached_page = NULL;
 	pos = *ppos;
 	written = 0;
-	
+
 	err = precheck_file_write(file, inode, &count, &pos);
 	if (err != 0 || count == 0)
 		goto out;
-	
+
+	remove_suid(inode);
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	mark_inode_dirty_sync(inode);
+
 	do {
 		unsigned long index, offset;
 		long page_fault;
@@ -3204,14 +3218,18 @@
 
 	pos = *ppos;
 	written = 0;
-	
+
 	err = precheck_file_write(file, inode, &count, &pos);
 	if (err != 0 || count == 0)
 		goto out;
-	
+
 	if (!file->f_flags & O_DIRECT)
 		BUG();
 
+	remove_suid(inode);
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	mark_inode_dirty_sync(inode);
+
 	written = generic_file_direct_IO(WRITE, file, (char *) buf, count, pos);
 	if (written > 0) {
 		loff_t end = pos + written;
diff -urN linux-2.4.22-pre2/mm/mremap.c linux-2.4.22-pre3/mm/mremap.c
--- linux-2.4.22-pre2/mm/mremap.c	2001-09-20 20:31:26.000000000 -0700
+++ linux-2.4.22-pre3/mm/mremap.c	2003-07-05 18:11:55.000000000 -0700
@@ -177,11 +177,13 @@
 	}
 
 	if (!move_page_tables(current->mm, new_addr, addr, old_len)) {
+		unsigned long vm_locked = vma->vm_flags & VM_LOCKED;
+
 		if (allocated_vma) {
 			*new_vma = *vma;
 			new_vma->vm_start = new_addr;
 			new_vma->vm_end = new_addr+new_len;
-			new_vma->vm_pgoff += (addr - vma->vm_start) >> PAGE_SHIFT;
+			new_vma->vm_pgoff += (addr-vma->vm_start) >> PAGE_SHIFT;
 			new_vma->vm_raend = 0;
 			if (new_vma->vm_file)
 				get_file(new_vma->vm_file);
@@ -189,12 +191,15 @@
 				new_vma->vm_ops->open(new_vma);
 			insert_vm_struct(current->mm, new_vma);
 		}
+
 		do_munmap(current->mm, addr, old_len);
+
 		current->mm->total_vm += new_len >> PAGE_SHIFT;
-		if (new_vma->vm_flags & VM_LOCKED) {
+		if (vm_locked) {
 			current->mm->locked_vm += new_len >> PAGE_SHIFT;
-			make_pages_present(new_vma->vm_start,
-					   new_vma->vm_end);
+			if (new_len > old_len)
+				make_pages_present(new_addr + old_len,
+						   new_addr + new_len);
 		}
 		return new_addr;
 	}
diff -urN linux-2.4.22-pre2/mm/shmem.c linux-2.4.22-pre3/mm/shmem.c
--- linux-2.4.22-pre2/mm/shmem.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/mm/shmem.c	2003-07-05 18:11:55.000000000 -0700
@@ -5,7 +5,10 @@
  *		 2000 Transmeta Corp.
  *		 2000-2001 Christoph Rohland
  *		 2000-2001 SAP AG
- * 
+ *		 2002 Red Hat Inc.
+ * Copyright (C) 2002-2003 Hugh Dickins.
+ * Copyright (C) 2002-2003 VERITAS Software Corporation.
+ *
  * This file is released under the GPL.
  */
 
@@ -29,22 +32,35 @@
 #include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
+#include <asm/div64.h>
 
 /* This magic number is used in glibc for posix shared memory */
 #define TMPFS_MAGIC	0x01021994
 
 #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
+#define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
 #define BLOCKS_PER_PAGE  (PAGE_CACHE_SIZE/512)
 
-#define SHMEM_MAX_INDEX  (SHMEM_NR_DIRECT + ENTRIES_PER_PAGE * (ENTRIES_PER_PAGE/2) * (ENTRIES_PER_PAGE+1))
+#define SHMEM_MAX_INDEX  (SHMEM_NR_DIRECT + (ENTRIES_PER_PAGEPAGE/2) * (ENTRIES_PER_PAGE+1))
 #define SHMEM_MAX_BYTES  ((unsigned long long)SHMEM_MAX_INDEX << PAGE_CACHE_SHIFT)
-#define VM_ACCT(size)    (((size) + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT)
+
+#define VM_ACCT(size)    (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT)
 
 /* Pretend that each entry is of this size in directory's i_size */
 #define BOGO_DIRENT_SIZE 20
 
 #define SHMEM_SB(sb) (&sb->u.shmem_sb)
 
+/* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */
+enum sgp_type {
+	SGP_READ,	/* don't exceed i_size, don't allocate page */
+	SGP_CACHE,	/* don't exceed i_size, may allocate page */
+	SGP_WRITE,	/* may exceed i_size, may allocate page */
+};
+
+static int shmem_getpage(struct inode *inode, unsigned long idx,
+			 struct page **pagep, enum sgp_type sgp);
+
 static struct super_operations shmem_ops;
 static struct address_space_operations shmem_aops;
 static struct file_operations shmem_file_operations;
@@ -52,45 +68,22 @@
 static struct inode_operations shmem_dir_inode_operations;
 static struct vm_operations_struct shmem_vm_ops;
 
-LIST_HEAD (shmem_inodes);
+LIST_HEAD(shmem_inodes);
 static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
-atomic_t shmem_nrpages = ATOMIC_INIT(0); /* Not used right now */
 
-static struct page *shmem_getpage_locked(struct shmem_inode_info *, struct inode *, unsigned long);
-
-/*
- * shmem_recalc_inode - recalculate the size of an inode
- *
- * @inode: inode to recalc
- * @swap:  additional swap pages freed externally
- *
- * We have to calculate the free blocks since the mm can drop pages
- * behind our back
- *
- * But we know that normally
- * inodes->i_blocks/BLOCKS_PER_PAGE == 
- * 			inode->i_mapping->nrpages + info->swapped
- *
- * So the mm freed 
- * inodes->i_blocks/BLOCKS_PER_PAGE - 
- * 			(inode->i_mapping->nrpages + info->swapped)
- *
- * It has to be called with the spinlock held.
- */
-
-static void shmem_recalc_inode(struct inode * inode)
+static void shmem_free_block(struct inode *inode)
 {
-	unsigned long freed;
+	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+	spin_lock(&sbinfo->stat_lock);
+	sbinfo->free_blocks++;
+	inode->i_blocks -= BLOCKS_PER_PAGE;
+	spin_unlock(&sbinfo->stat_lock);
+}
 
-	freed = (inode->i_blocks/BLOCKS_PER_PAGE) -
-		(inode->i_mapping->nrpages + SHMEM_I(inode)->swapped);
-	if (freed){
-		struct shmem_sb_info * sbinfo = SHMEM_SB(inode->i_sb);
-		inode->i_blocks -= freed*BLOCKS_PER_PAGE;
-		spin_lock (&sbinfo->stat_lock);
-		sbinfo->free_blocks += freed;
-		spin_unlock (&sbinfo->stat_lock);
-	}
+static void shmem_removepage(struct page *page)
+{
+	if (!PageLaunder(page))
+		shmem_free_block(page->mapping->host);
 }
 
 /*
@@ -101,11 +94,9 @@
  * @page:  optional page to add to the structure. Has to be preset to
  *         all zeros
  *
- * If there is no space allocated yet it will return -ENOMEM when
- * page == 0 else it will use the page for the needed block.
- *
- * returns -EFBIG if the index is too big.
- *
+ * If there is no space allocated yet it will return NULL when
+ * page is 0, else it will use the page for the needed block,
+ * setting it to 0 on return to indicate that it has been used.
  *
  * The swap vector is organized the following way:
  *
@@ -133,90 +124,130 @@
  * 	      	       +-> 48-51
  * 	      	       +-> 52-55
  */
-static swp_entry_t * shmem_swp_entry (struct shmem_inode_info *info, unsigned long index, unsigned long page) 
+static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page)
 {
 	unsigned long offset;
 	void **dir;
 
 	if (index < SHMEM_NR_DIRECT)
 		return info->i_direct+index;
+	if (!info->i_indirect) {
+		if (page) {
+			info->i_indirect = (void **) *page;
+			*page = 0;
+		}
+		return NULL;			/* need another page */
+	}
 
 	index -= SHMEM_NR_DIRECT;
 	offset = index % ENTRIES_PER_PAGE;
 	index /= ENTRIES_PER_PAGE;
+	dir = info->i_indirect;
 
-	if (!info->i_indirect) {
-		info->i_indirect = (void *) page;
-		return ERR_PTR(-ENOMEM);
-	}
-
-	dir = info->i_indirect + index;
 	if (index >= ENTRIES_PER_PAGE/2) {
 		index -= ENTRIES_PER_PAGE/2;
-		dir = info->i_indirect + ENTRIES_PER_PAGE/2 
-			+ index/ENTRIES_PER_PAGE;
+		dir += ENTRIES_PER_PAGE/2 + index/ENTRIES_PER_PAGE;
 		index %= ENTRIES_PER_PAGE;
-
-		if(!*dir) {
-			*dir = (void *) page;
-			/* We return since we will need another page
-                           in the next step */
-			return ERR_PTR(-ENOMEM);
+		if (!*dir) {
+			if (page) {
+				*dir = (void *) *page;
+				*page = 0;
+			}
+			return NULL;		/* need another page */
 		}
-		dir = ((void **)*dir) + index;
+		dir = (void **) *dir;
 	}
+
+	dir += index;
 	if (!*dir) {
-		if (!page)
-			return ERR_PTR(-ENOMEM);
-		*dir = (void *)page;
+		if (!page || !*page)
+			return NULL;		/* need a page */
+		*dir = (void *) *page;
+		*page = 0;
 	}
-	return ((swp_entry_t *)*dir) + offset;
+	return (swp_entry_t *) *dir + offset;
 }
 
 /*
- * shmem_alloc_entry - get the position of the swap entry for the
- *                     page. If it does not exist allocate the entry
+ * shmem_swp_alloc - get the position of the swap entry for the page.
+ *                   If it does not exist allocate the entry.
  *
  * @info:	info structure for the inode
  * @index:	index of the page to find
+ * @sgp:	check and recheck i_size? skip allocation?
  */
-static inline swp_entry_t * shmem_alloc_entry (struct shmem_inode_info *info, unsigned long index)
+static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long index, enum sgp_type sgp)
 {
+	struct inode *inode = info->inode;
+	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
 	unsigned long page = 0;
-	swp_entry_t * res;
+	swp_entry_t *entry;
+	static const swp_entry_t unswapped = {0};
 
-	if (index >= SHMEM_MAX_INDEX)
-		return ERR_PTR(-EFBIG);
+	if (sgp != SGP_WRITE &&
+	    ((loff_t) index << PAGE_CACHE_SHIFT) >= inode->i_size)
+		return ERR_PTR(-EINVAL);
 
-	if (info->next_index <= index)
-		info->next_index = index + 1;
+	while (!(entry = shmem_swp_entry(info, index, &page))) {
+		if (sgp == SGP_READ)
+			return (swp_entry_t *) &unswapped;
+		/*
+		 * Test free_blocks against 1 not 0, since we have 1 data
+		 * page (and perhaps indirect index pages) yet to allocate:
+		 * a waste to allocate index if we cannot allocate data.
+		 */
+		spin_lock(&sbinfo->stat_lock);
+		if (sbinfo->free_blocks <= 1) {
+			spin_unlock(&sbinfo->stat_lock);
+			return ERR_PTR(-ENOSPC);
+		}
+		sbinfo->free_blocks--;
+		inode->i_blocks += BLOCKS_PER_PAGE;
+		spin_unlock(&sbinfo->stat_lock);
 
-	while ((res = shmem_swp_entry(info,index,page)) == ERR_PTR(-ENOMEM)) {
+		spin_unlock(&info->lock);
 		page = get_zeroed_page(GFP_USER);
-		if (!page)
+		spin_lock(&info->lock);
+
+		if (!page) {
+			shmem_free_block(inode);
+			return ERR_PTR(-ENOMEM);
+		}
+		if (sgp != SGP_WRITE &&
+		    ((loff_t) index << PAGE_CACHE_SHIFT) >= inode->i_size) {
+			entry = ERR_PTR(-EINVAL);
 			break;
+		}
+		if (info->next_index <= index)
+			info->next_index = index + 1;
 	}
-	return res;
+	if (page) {
+		/* another task gave its page, or truncated the file */
+		shmem_free_block(inode);
+		free_page(page);
+	}
+	if (info->next_index <= index && !IS_ERR(entry))
+		info->next_index = index + 1;
+	return entry;
 }
 
 /*
  * shmem_free_swp - free some swap entries in a directory
  *
  * @dir:   pointer to the directory
- * @count: number of entries to scan
+ * @edir:  pointer after last entry of the directory
  */
-static int shmem_free_swp(swp_entry_t *dir, unsigned int count)
+static int shmem_free_swp(swp_entry_t *dir, swp_entry_t *edir)
 {
-	swp_entry_t *ptr, entry;
+	swp_entry_t *ptr;
 	int freed = 0;
 
-	for (ptr = dir; ptr < dir + count; ptr++) {
-		if (!ptr->val)
-			continue;
-		entry = *ptr;
-		*ptr = (swp_entry_t){0};
-		freed++;
-		free_swap_and_cache(entry);
+	for (ptr = dir; ptr < edir; ptr++) {
+		if (ptr->val) {
+			free_swap_and_cache(*ptr);
+			*ptr = (swp_entry_t){0};
+			freed++;
+		}
 	}
 	return freed;
 }
@@ -225,41 +256,40 @@
  * shmem_truncate_direct - free the swap entries of a whole doubly
  *                         indirect block
  *
+ * @info:	the info structure of the inode
  * @dir:	pointer to the pointer to the block
  * @start:	offset to start from (in pages)
  * @len:	how many pages are stored in this block
- *
- * Returns the number of freed swap entries.
  */
-
-static inline unsigned long 
-shmem_truncate_direct(swp_entry_t *** dir, unsigned long start, unsigned long len) {
+static inline unsigned long
+shmem_truncate_direct(struct shmem_inode_info *info, swp_entry_t ***dir, unsigned long start, unsigned long len)
+{
 	swp_entry_t **last, **ptr;
-	unsigned long off, freed = 0;
- 
-	if (!*dir)
-		return 0;
+	unsigned long off, freed_swp, freed = 0;
 
-	last = *dir + (len + ENTRIES_PER_PAGE-1) / ENTRIES_PER_PAGE;
+	last = *dir + (len + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
 	off = start % ENTRIES_PER_PAGE;
 
-	for (ptr = *dir + start/ENTRIES_PER_PAGE; ptr < last; ptr++) {
-		if (!*ptr) {
-			off = 0;
+	for (ptr = *dir + start/ENTRIES_PER_PAGE; ptr < last; ptr++, off = 0) {
+		if (!*ptr)
 			continue;
+
+		if (info->swapped) {
+			freed_swp = shmem_free_swp(*ptr + off,
+						*ptr + ENTRIES_PER_PAGE);
+			info->swapped -= freed_swp;
+			freed += freed_swp;
 		}
 
 		if (!off) {
-			freed += shmem_free_swp(*ptr, ENTRIES_PER_PAGE);
-			free_page ((unsigned long) *ptr);
+			freed++;
+			free_page((unsigned long) *ptr);
 			*ptr = 0;
-		} else {
-			freed += shmem_free_swp(*ptr+off,ENTRIES_PER_PAGE-off);
-			off = 0;
 		}
 	}
-	
+
 	if (!start) {
+		freed++;
 		free_page((unsigned long) *dir);
 		*dir = 0;
 	}
@@ -279,29 +309,33 @@
 shmem_truncate_indirect(struct shmem_inode_info *info, unsigned long index)
 {
 	swp_entry_t ***base;
-	unsigned long baseidx, len, start;
-	unsigned long max = info->next_index-1;
+	unsigned long baseidx, start;
+	unsigned long len = info->next_index;
+	unsigned long freed;
 
-	if (max < SHMEM_NR_DIRECT) {
+	if (len <= SHMEM_NR_DIRECT) {
 		info->next_index = index;
-		return shmem_free_swp(info->i_direct + index,
-				      SHMEM_NR_DIRECT - index);
+		if (!info->swapped)
+			return 0;
+		freed = shmem_free_swp(info->i_direct + index,
+					info->i_direct + len);
+		info->swapped -= freed;
+		return freed;
 	}
 
-	if (max < ENTRIES_PER_PAGE * ENTRIES_PER_PAGE/2 + SHMEM_NR_DIRECT) {
-		max -= SHMEM_NR_DIRECT;
+	if (len <= ENTRIES_PER_PAGEPAGE/2 + SHMEM_NR_DIRECT) {
+		len -= SHMEM_NR_DIRECT;
 		base = (swp_entry_t ***) &info->i_indirect;
 		baseidx = SHMEM_NR_DIRECT;
-		len = max+1;
 	} else {
-		max -= ENTRIES_PER_PAGE*ENTRIES_PER_PAGE/2+SHMEM_NR_DIRECT;
-		if (max >= ENTRIES_PER_PAGE*ENTRIES_PER_PAGE*ENTRIES_PER_PAGE/2)
-			BUG();
-
-		baseidx = max & ~(ENTRIES_PER_PAGE*ENTRIES_PER_PAGE-1);
-		base = (swp_entry_t ***) info->i_indirect + ENTRIES_PER_PAGE/2 + baseidx/ENTRIES_PER_PAGE/ENTRIES_PER_PAGE ;
-		len = max - baseidx + 1;
-		baseidx += ENTRIES_PER_PAGE*ENTRIES_PER_PAGE/2+SHMEM_NR_DIRECT;
+		len -= ENTRIES_PER_PAGEPAGE/2 + SHMEM_NR_DIRECT;
+		BUG_ON(len > ENTRIES_PER_PAGEPAGE*ENTRIES_PER_PAGE/2);
+		baseidx = len - 1;
+		baseidx -= baseidx % ENTRIES_PER_PAGEPAGE;
+		base = (swp_entry_t ***) info->i_indirect +
+			ENTRIES_PER_PAGE/2 + baseidx/ENTRIES_PER_PAGEPAGE;
+		len -= baseidx;
+		baseidx += ENTRIES_PER_PAGEPAGE/2 + SHMEM_NR_DIRECT;
 	}
 
 	if (index > baseidx) {
@@ -311,89 +345,106 @@
 		info->next_index = baseidx;
 		start = 0;
 	}
-	return shmem_truncate_direct(base, start, len);
+	return *base? shmem_truncate_direct(info, base, start, len): 0;
 }
 
-static void shmem_truncate (struct inode * inode)
+static void shmem_truncate(struct inode *inode)
 {
-	unsigned long index;
-	unsigned long partial;
+	struct shmem_inode_info *info = SHMEM_I(inode);
+	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
 	unsigned long freed = 0;
-	struct shmem_inode_info * info = SHMEM_I(inode);
+	unsigned long index;
 
-	down(&info->sem);
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-	spin_lock (&info->lock);
 	index = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-	partial = inode->i_size & ~PAGE_CACHE_MASK;
+	if (index >= info->next_index)
+		return;
 
-	if (partial) {
-		swp_entry_t *entry = shmem_swp_entry(info, index-1, 0);
-		struct page *page;
-		/*
-		 * This check is racy: it's faintly possible that page
-		 * was assigned to swap during truncate_inode_pages,
-		 * and now assigned to file; but better than nothing.
-		 */
-		if (!IS_ERR(entry) && entry->val) {
-			spin_unlock(&info->lock);
-			page = shmem_getpage_locked(info, inode, index-1);
-			if (!IS_ERR(page)) {
-				memclear_highpage_flush(page, partial,
-					PAGE_CACHE_SIZE - partial);
-				UnlockPage(page);
-				page_cache_release(page);
+	spin_lock(&info->lock);
+	while (index < info->next_index)
+		freed += shmem_truncate_indirect(info, index);
+	BUG_ON(info->swapped > info->next_index);
+	spin_unlock(&info->lock);
+
+	spin_lock(&sbinfo->stat_lock);
+	sbinfo->free_blocks += freed;
+	inode->i_blocks -= freed*BLOCKS_PER_PAGE;
+	spin_unlock(&sbinfo->stat_lock);
+}
+
+static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
+{
+	struct inode *inode = dentry->d_inode;
+	struct page *page = NULL;
+	int error;
+
+	if (attr->ia_valid & ATTR_SIZE) {
+		if (attr->ia_size < inode->i_size) {
+			/*
+			 * If truncating down to a partial page, then
+			 * if that page is already allocated, hold it
+			 * in memory until the truncation is over, so
+			 * truncate_partial_page cannnot miss it were
+			 * it assigned to swap.
+			 */
+			if (attr->ia_size & (PAGE_CACHE_SIZE-1)) {
+				(void) shmem_getpage(inode,
+					attr->ia_size>>PAGE_CACHE_SHIFT,
+						&page, SGP_READ);
 			}
-			spin_lock(&info->lock);
 		}
 	}
 
-	while (index < info->next_index) 
-		freed += shmem_truncate_indirect(info, index);
-
-	info->swapped -= freed;
-	shmem_recalc_inode(inode);
-	spin_unlock (&info->lock);
-	up(&info->sem);
+	error = inode_change_ok(inode, attr);
+	if (!error)
+		error = inode_setattr(inode, attr);
+	if (page)
+		page_cache_release(page);
+	return error;
 }
 
-static void shmem_delete_inode(struct inode * inode)
+static void shmem_delete_inode(struct inode *inode)
 {
 	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+	struct shmem_inode_info *info = SHMEM_I(inode);
 
 	if (inode->i_op->truncate == shmem_truncate) {
-		spin_lock (&shmem_ilock);
-		list_del (&SHMEM_I(inode)->list);
-		spin_unlock (&shmem_ilock);
+		spin_lock(&shmem_ilock);
+		list_del(&info->list);
+		spin_unlock(&shmem_ilock);
 		inode->i_size = 0;
-		shmem_truncate (inode);
+		shmem_truncate(inode);
 	}
-	spin_lock (&sbinfo->stat_lock);
+	BUG_ON(inode->i_blocks);
+	spin_lock(&sbinfo->stat_lock);
 	sbinfo->free_inodes++;
-	spin_unlock (&sbinfo->stat_lock);
+	spin_unlock(&sbinfo->stat_lock);
 	clear_inode(inode);
 }
 
-static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *ptr, swp_entry_t *eptr)
+static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *dir, swp_entry_t *edir)
 {
-	swp_entry_t *test;
+	swp_entry_t *ptr;
 
-	for (test = ptr; test < eptr; test++) {
-		if (test->val == entry.val)
-			return test - ptr;
+	for (ptr = dir; ptr < edir; ptr++) {
+		if (ptr->val == entry.val)
+			return ptr - dir;
 	}
 	return -1;
 }
 
 static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, struct page *page)
 {
+	struct inode *inode;
+	struct address_space *mapping;
 	swp_entry_t *ptr;
 	unsigned long idx;
+	unsigned long limit;
 	int offset;
 
 	idx = 0;
 	ptr = info->i_direct;
-	spin_lock (&info->lock);
+	spin_lock(&info->lock);
 	offset = info->next_index;
 	if (offset > SHMEM_NR_DIRECT)
 		offset = SHMEM_NR_DIRECT;
@@ -401,10 +452,10 @@
 	if (offset >= 0)
 		goto found;
 
-	for (idx = SHMEM_NR_DIRECT; idx < info->next_index; 
+	for (idx = SHMEM_NR_DIRECT; idx < info->next_index;
 	     idx += ENTRIES_PER_PAGE) {
-		ptr = shmem_swp_entry(info, idx, 0);
-		if (IS_ERR(ptr))
+		ptr = shmem_swp_entry(info, idx, NULL);
+		if (!ptr)
 			continue;
 		offset = info->next_index - idx;
 		if (offset > ENTRIES_PER_PAGE)
@@ -413,50 +464,62 @@
 		if (offset >= 0)
 			goto found;
 	}
-	spin_unlock (&info->lock);
+	spin_unlock(&info->lock);
 	return 0;
 found:
-	swap_free(entry);
-	ptr[offset] = (swp_entry_t) {0};
+	idx += offset;
+	inode = info->inode;
+	mapping = inode->i_mapping;
 	delete_from_swap_cache(page);
-	add_to_page_cache(page, info->inode->i_mapping, offset + idx);
-	SetPageDirty(page);
-	SetPageUptodate(page);
-	info->swapped--;
+
+	/* Racing against delete or truncate? Must leave out of page cache */
+	limit = (inode->i_state & I_FREEING)? 0:
+		(inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+
+	if (idx >= limit || add_to_page_cache_unique(page,
+			mapping, idx, page_hash(mapping, idx)) == 0) {
+		ptr[offset].val = 0;
+		info->swapped--;
+	} else if (add_to_swap_cache(page, entry) != 0)
+		BUG();
 	spin_unlock(&info->lock);
+	SetPageUptodate(page);
+	/*
+	 * Decrement swap count even when the entry is left behind:
+	 * try_to_unuse will skip over mms, then reincrement count.
+	 */
+	swap_free(entry);
 	return 1;
 }
 
 /*
  * shmem_unuse() search for an eventually swapped out shmem page.
  */
-void shmem_unuse(swp_entry_t entry, struct page *page)
+int shmem_unuse(swp_entry_t entry, struct page *page)
 {
 	struct list_head *p;
-	struct shmem_inode_info * info;
+	struct shmem_inode_info *info;
+	int found = 0;
 
-	spin_lock (&shmem_ilock);
+	spin_lock(&shmem_ilock);
 	list_for_each(p, &shmem_inodes) {
 		info = list_entry(p, struct shmem_inode_info, list);
 
 		if (info->swapped && shmem_unuse_inode(info, entry, page)) {
 			/* move head to start search for next from here */
-			list_del(&shmem_inodes);
-			list_add_tail(&shmem_inodes, p);
+			list_move_tail(&shmem_inodes, &info->list);
+			found = 1;
 			break;
 		}
 	}
-	spin_unlock (&shmem_ilock);
+	spin_unlock(&shmem_ilock);
+	return found;
 }
 
 /*
  * Move the page from the page cache to the swap cache.
- *
- * The page lock prevents multiple occurences of shmem_writepage at
- * once.  We still need to guard against racing with
- * shmem_getpage_locked().  
  */
-static int shmem_writepage(struct page * page)
+static int shmem_writepage(struct page *page)
 {
 	struct shmem_inode_info *info;
 	swp_entry_t *entry, swap;
@@ -464,8 +527,7 @@
 	unsigned long index;
 	struct inode *inode;
 
-	if (!PageLocked(page))
-		BUG();
+	BUG_ON(!PageLocked(page));
 	if (!PageLaunder(page))
 		return fail_writepage(page);
 
@@ -473,7 +535,7 @@
 	index = page->index;
 	inode = mapping->host;
 	info = SHMEM_I(inode);
-	if (info->locked)
+	if (info->flags & VM_LOCKED)
 		return fail_writepage(page);
 getswap:
 	swap = get_swap_page();
@@ -481,12 +543,10 @@
 		return fail_writepage(page);
 
 	spin_lock(&info->lock);
-	entry = shmem_swp_entry(info, index, 0);
-	if (IS_ERR(entry))	/* this had been allocated on page allocation */
-		BUG();
-	shmem_recalc_inode(inode);
-	if (entry->val)
-		BUG();
+	BUG_ON(index >= info->next_index);
+	entry = shmem_swp_entry(info, index, NULL);
+	BUG_ON(!entry);
+	BUG_ON(entry->val);
 
 	/* Remove it from the page cache */
 	remove_inode_page(page);
@@ -514,204 +574,251 @@
 }
 
 /*
- * shmem_getpage_locked - either get the page from swap or allocate a new one
+ * shmem_getpage - either get the page from swap or allocate a new one
  *
  * If we allocate a new one we do not mark it dirty. That's up to the
  * vm. If we swap it in we mark it dirty since we also free the swap
  * entry since a page cannot live in both the swap and page cache
- *
- * Called with the inode locked, so it cannot race with itself, but we
- * still need to guard against racing with shm_writepage(), which might
- * be trying to move the page to the swap cache as we run.
  */
-static struct page * shmem_getpage_locked(struct shmem_inode_info *info, struct inode * inode, unsigned long idx)
+static int shmem_getpage(struct inode *inode, unsigned long idx, struct page **pagep, enum sgp_type sgp)
 {
-	struct address_space * mapping = inode->i_mapping;
+	struct address_space *mapping = inode->i_mapping;
+	struct shmem_inode_info *info = SHMEM_I(inode);
 	struct shmem_sb_info *sbinfo;
-	struct page * page;
+	struct page *filepage = *pagep;
+	struct page *swappage;
 	swp_entry_t *entry;
+	swp_entry_t swap;
+	int error = 0;
 
+	if (idx >= SHMEM_MAX_INDEX)
+		return -EFBIG;
+	/*
+	 * Normally, filepage is NULL on entry, and either found
+	 * uptodate immediately, or allocated and zeroed, or read
+	 * in under swappage, which is then assigned to filepage.
+	 * But shmem_readpage and shmem_prepare_write pass in a locked
+	 * filepage, which may be found not uptodate by other callers
+	 * too, and may need to be copied from the swappage read in.
+	 */
 repeat:
-	page = find_lock_page(mapping, idx);
-	if (page)
-		return page;
+	if (!filepage)
+		filepage = find_lock_page(mapping, idx);
+	if (filepage && Page_Uptodate(filepage))
+		goto done;
 
-	entry = shmem_alloc_entry (info, idx);
-	if (IS_ERR(entry))
-		return (void *)entry;
-
-	spin_lock (&info->lock);
-	
-	/* The shmem_alloc_entry() call may have blocked, and
-	 * shmem_writepage may have been moving a page between the page
-	 * cache and swap cache.  We need to recheck the page cache
-	 * under the protection of the info->lock spinlock. */
-
-	page = find_get_page(mapping, idx);
-	if (page) {
-		if (TryLockPage(page))
-			goto wait_retry;
-		spin_unlock (&info->lock);
-		return page;
-	}
-	
-	shmem_recalc_inode(inode);
-	if (entry->val) {
-		unsigned long flags;
+	spin_lock(&info->lock);
+	entry = shmem_swp_alloc(info, idx, sgp);
+	if (IS_ERR(entry)) {
+		spin_unlock(&info->lock);
+		error = PTR_ERR(entry);
+		goto failed;
+	}
+	swap = *entry;
 
+	if (swap.val) {
 		/* Look it up and read it in.. */
-		page = lookup_swap_cache(*entry);
-		if (!page) {
-			swp_entry_t swap = *entry;
-			spin_unlock (&info->lock);
-			swapin_readahead(*entry);
-			page = read_swap_cache_async(*entry);
-			if (!page) {
-				if (entry->val != swap.val)
-					goto repeat;
-				return ERR_PTR(-ENOMEM);
-			}
-			wait_on_page(page);
-			if (!Page_Uptodate(page) && entry->val == swap.val) {
-				page_cache_release(page);
-				return ERR_PTR(-EIO);
+		swappage = lookup_swap_cache(swap);
+		if (!swappage) {
+			spin_unlock(&info->lock);
+			swapin_readahead(swap);
+			swappage = read_swap_cache_async(swap);
+			if (!swappage) {
+				spin_lock(&info->lock);
+				entry = shmem_swp_alloc(info, idx, sgp);
+				if (IS_ERR(entry))
+					error = PTR_ERR(entry);
+				else if (entry->val == swap.val)
+					error = -ENOMEM;
+				spin_unlock(&info->lock);
+				if (error)
+					goto failed;
+				goto repeat;
 			}
-			
-			/* Too bad we can't trust this page, because we
-			 * dropped the info->lock spinlock */
-			page_cache_release(page);
+			wait_on_page(swappage);
+			page_cache_release(swappage);
 			goto repeat;
 		}
 
-		/* We have to this with page locked to prevent races */
-		if (TryLockPage(page)) 
-			goto wait_retry;
-
-		swap_free(*entry);
-		*entry = (swp_entry_t) {0};
-		delete_from_swap_cache(page);
-		flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) | (1 << PG_referenced) | (1 << PG_arch_1));
-		page->flags = flags | (1 << PG_dirty);
-		add_to_page_cache_locked(page, mapping, idx);
-		info->swapped--;
-		spin_unlock (&info->lock);
+		/* We have to do this with page locked to prevent races */
+		if (TryLockPage(swappage)) {
+			spin_unlock(&info->lock);
+			wait_on_page(swappage);
+			page_cache_release(swappage);
+			goto repeat;
+		}
+		if (!Page_Uptodate(swappage)) {
+			spin_unlock(&info->lock);
+			UnlockPage(swappage);
+			page_cache_release(swappage);
+			error = -EIO;
+			goto failed;
+		}
+
+		delete_from_swap_cache(swappage);
+		if (filepage) {
+			entry->val = 0;
+			info->swapped--;
+			spin_unlock(&info->lock);
+			flush_page_to_ram(swappage);
+			copy_highpage(filepage, swappage);
+			UnlockPage(swappage);
+			page_cache_release(swappage);
+			flush_dcache_page(filepage);
+			SetPageUptodate(filepage);
+			SetPageDirty(filepage);
+			swap_free(swap);
+		} else if (add_to_page_cache_unique(swappage,
+			mapping, idx, page_hash(mapping, idx)) == 0) {
+			entry->val = 0;
+			info->swapped--;
+			spin_unlock(&info->lock);
+			filepage = swappage;
+			SetPageUptodate(filepage);
+			SetPageDirty(filepage);
+			swap_free(swap);
+		} else {
+			if (add_to_swap_cache(swappage, swap) != 0)
+				BUG();
+			spin_unlock(&info->lock);
+			SetPageUptodate(swappage);
+			SetPageDirty(swappage);
+			UnlockPage(swappage);
+			page_cache_release(swappage);
+			goto repeat;
+		}
+	} else if (sgp == SGP_READ && !filepage) {
+		filepage = find_get_page(mapping, idx);
+		if (filepage &&
+		    (!Page_Uptodate(filepage) || TryLockPage(filepage))) {
+			spin_unlock(&info->lock);
+			wait_on_page(filepage);
+			page_cache_release(filepage);
+			filepage = NULL;
+			goto repeat;
+		}
+		spin_unlock(&info->lock);
 	} else {
 		sbinfo = SHMEM_SB(inode->i_sb);
-		spin_unlock (&info->lock);
-		spin_lock (&sbinfo->stat_lock);
-		if (sbinfo->free_blocks == 0)
-			goto no_space;
+		spin_lock(&sbinfo->stat_lock);
+		if (sbinfo->free_blocks == 0) {
+			spin_unlock(&sbinfo->stat_lock);
+			spin_unlock(&info->lock);
+			error = -ENOSPC;
+			goto failed;
+		}
 		sbinfo->free_blocks--;
-		spin_unlock (&sbinfo->stat_lock);
-
-		/* Ok, get a new page.  We don't have to worry about the
-		 * info->lock spinlock here: we cannot race against
-		 * shm_writepage because we have already verified that
-		 * there is no page present either in memory or in the
-		 * swap cache, so we are guaranteed to be populating a
-		 * new shm entry.  The inode semaphore we already hold
-		 * is enough to make this atomic. */
-		page = page_cache_alloc(mapping);
-		if (!page)
-			return ERR_PTR(-ENOMEM);
-		clear_highpage(page);
-		flush_dcache_page(page);
 		inode->i_blocks += BLOCKS_PER_PAGE;
-		add_to_page_cache (page, mapping, idx);
-	}
-
-	/* We have the page */
-	SetPageUptodate(page);
-	return page;
-no_space:
-	spin_unlock (&sbinfo->stat_lock);
-	return ERR_PTR(-ENOSPC);
-
-wait_retry:
-	spin_unlock (&info->lock);
-	wait_on_page(page);
-	page_cache_release(page);
-	goto repeat;
-}
+		spin_unlock(&sbinfo->stat_lock);
 
-static int shmem_getpage(struct inode * inode, unsigned long idx, struct page **ptr)
-{
-	struct shmem_inode_info *info = SHMEM_I(inode);
-	int error;
-
-	down (&info->sem);
-	*ptr = ERR_PTR(-EFAULT);
-	if (inode->i_size <= (loff_t) idx * PAGE_CACHE_SIZE)
-		goto failed;
+		if (!filepage) {
+			spin_unlock(&info->lock);
+			filepage = page_cache_alloc(mapping);
+			if (!filepage) {
+				shmem_free_block(inode);
+				error = -ENOMEM;
+				goto failed;
+			}
 
-	*ptr = shmem_getpage_locked(info, inode, idx);
-	if (IS_ERR (*ptr))
-		goto failed;
+			spin_lock(&info->lock);
+			entry = shmem_swp_alloc(info, idx, sgp);
+			if (IS_ERR(entry))
+				error = PTR_ERR(entry);
+			if (error || entry->val ||
+			    add_to_page_cache_unique(filepage,
+			    mapping, idx, page_hash(mapping, idx)) != 0) {
+				spin_unlock(&info->lock);
+				page_cache_release(filepage);
+				shmem_free_block(inode);
+				filepage = NULL;
+				if (error)
+					goto failed;
+				goto repeat;
+			}
+		}
 
-	UnlockPage(*ptr);
-	up (&info->sem);
+		spin_unlock(&info->lock);
+		clear_highpage(filepage);
+		flush_dcache_page(filepage);
+		SetPageUptodate(filepage);
+	}
+done:
+	if (!*pagep) {
+		if (filepage) {
+			UnlockPage(filepage);
+			*pagep = filepage;
+		} else
+			*pagep = ZERO_PAGE(0);
+	}
 	return 0;
+
 failed:
-	up (&info->sem);
-	error = PTR_ERR(*ptr);
-	*ptr = NOPAGE_SIGBUS;
-	if (error == -ENOMEM)
-		*ptr = NOPAGE_OOM;
+	if (*pagep != filepage) {
+		UnlockPage(filepage);
+		page_cache_release(filepage);
+	}
 	return error;
 }
 
-struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, int unused)
+struct page *shmem_nopage(struct vm_area_struct *vma, unsigned long address, int unused)
 {
-	struct page * page;
-	unsigned int idx;
-	struct inode * inode = vma->vm_file->f_dentry->d_inode;
+	struct inode *inode = vma->vm_file->f_dentry->d_inode;
+	struct page *page = NULL;
+	unsigned long idx;
+	int error;
 
-	idx = (address - vma->vm_start) >> PAGE_CACHE_SHIFT;
+	idx = (address - vma->vm_start) >> PAGE_SHIFT;
 	idx += vma->vm_pgoff;
+	idx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT;
 
-	if (shmem_getpage(inode, idx, &page))
-		return page;
+	error = shmem_getpage(inode, idx, &page, SGP_CACHE);
+	if (error)
+		return (error == -ENOMEM)? NOPAGE_OOM: NOPAGE_SIGBUS;
 
+	mark_page_accessed(page);
 	flush_page_to_ram(page);
-	return(page);
+	return page;
 }
 
-void shmem_lock(struct file * file, int lock)
+void shmem_lock(struct file *file, int lock)
 {
-	struct inode * inode = file->f_dentry->d_inode;
-	struct shmem_inode_info * info = SHMEM_I(inode);
+	struct inode *inode = file->f_dentry->d_inode;
+	struct shmem_inode_info *info = SHMEM_I(inode);
 
 	spin_lock(&info->lock);
-	info->locked = lock;
+	if (lock)
+		info->flags |= VM_LOCKED;
+	else
+		info->flags &= ~VM_LOCKED;
 	spin_unlock(&info->lock);
 }
 
-static int shmem_mmap(struct file * file, struct vm_area_struct * vma)
+static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	struct vm_operations_struct * ops;
+	struct vm_operations_struct *ops;
 	struct inode *inode = file->f_dentry->d_inode;
 
 	ops = &shmem_vm_ops;
-	if (!inode->i_sb || !S_ISREG(inode->i_mode))
+	if (!S_ISREG(inode->i_mode))
 		return -EACCES;
 	UPDATE_ATIME(inode);
 	vma->vm_ops = ops;
 	return 0;
 }
 
-struct inode *shmem_get_inode(struct super_block *sb, int mode, int dev)
+static struct inode *shmem_get_inode(struct super_block *sb, int mode, int dev)
 {
-	struct inode * inode;
+	struct inode *inode;
 	struct shmem_inode_info *info;
 	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
 
-	spin_lock (&sbinfo->stat_lock);
+	spin_lock(&sbinfo->stat_lock);
 	if (!sbinfo->free_inodes) {
-		spin_unlock (&sbinfo->stat_lock);
+		spin_unlock(&sbinfo->stat_lock);
 		return NULL;
 	}
 	sbinfo->free_inodes--;
-	spin_unlock (&sbinfo->stat_lock);
+	spin_unlock(&sbinfo->stat_lock);
 
 	inode = new_inode(sb);
 	if (inode) {
@@ -725,8 +832,7 @@
 		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 		info = SHMEM_I(inode);
 		info->inode = inode;
-		spin_lock_init (&info->lock);
-		sema_init (&info->sem, 1);
+		spin_lock_init(&info->lock);
 		switch (mode & S_IFMT) {
 		default:
 			init_special_inode(inode, mode, dev);
@@ -734,9 +840,9 @@
 		case S_IFREG:
 			inode->i_op = &shmem_inode_operations;
 			inode->i_fop = &shmem_file_operations;
-			spin_lock (&shmem_ilock);
+			spin_lock(&shmem_ilock);
 			list_add_tail(&info->list, &shmem_inodes);
-			spin_unlock (&shmem_ilock);
+			spin_unlock(&shmem_ilock);
 			break;
 		case S_IFDIR:
 			inode->i_nlink++;
@@ -781,16 +887,46 @@
 static struct inode_operations shmem_symlink_inode_operations;
 static struct inode_operations shmem_symlink_inline_operations;
 
+/*
+ * tmpfs itself makes no use of generic_file_read, generic_file_mmap
+ * or generic_file_write; but shmem_readpage, shmem_prepare_write and
+ * shmem_commit_write let a tmpfs file be used below the loop driver,
+ * and shmem_readpage lets a tmpfs file be used by sendfile.
+ */
+static int
+shmem_readpage(struct file *file, struct page *page)
+{
+	struct inode *inode = page->mapping->host;
+	int error = shmem_getpage(inode, page->index, &page, SGP_CACHE);
+	UnlockPage(page);
+	return error;
+}
+
+static int
+shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+{
+	struct inode *inode = page->mapping->host;
+	return shmem_getpage(inode, page->index, &page, SGP_WRITE);
+}
+
+static int
+shmem_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+{
+	struct inode *inode = page->mapping->host;
+	loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+
+	if (pos > inode->i_size)
+		inode->i_size = pos;
+	SetPageDirty(page);
+	return 0;
+}
+
 static ssize_t
-shmem_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
+shmem_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
-	struct inode	*inode = file->f_dentry->d_inode; 
-	struct shmem_inode_info *info;
-	unsigned long	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+	struct inode	*inode = file->f_dentry->d_inode;
 	loff_t		pos;
-	struct page	*page;
 	unsigned long	written;
-	long		status;
 	int		err;
 
 	if ((ssize_t) count < 0)
@@ -802,119 +938,69 @@
 	down(&inode->i_sem);
 
 	pos = *ppos;
-	err = -EINVAL;
-	if (pos < 0)
-		goto out;
-
-	err = file->f_error;
-	if (err) {
-		file->f_error = 0;
-		goto out;
-	}
-
 	written = 0;
 
-	if (file->f_flags & O_APPEND)
-		pos = inode->i_size;
-
-	/*
-	 * Check whether we've reached the file size limit.
-	 */
-	err = -EFBIG;
-	if (limit != RLIM_INFINITY) {
-		if (pos >= limit) {
-			send_sig(SIGXFSZ, current, 0);
-			goto out;
-		}
-		if (count > limit - pos) {
-			send_sig(SIGXFSZ, current, 0);
-			count = limit - pos;
-		}
-	}
+	err = precheck_file_write(file, inode, &count, &pos);
+	if (err || !count)
+		goto out;
 
-	status	= 0;
-	if (count) {
-		remove_suid(inode);
-		inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-	}
+	remove_suid(inode);
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 
-	while (count) {
+	do {
+		struct page *page = NULL;
 		unsigned long bytes, index, offset;
 		char *kaddr;
+		int left;
 
-		/*
-		 * Try to find the page in the cache. If it isn't there,
-		 * allocate a free page.
-		 */
 		offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
 		index = pos >> PAGE_CACHE_SHIFT;
 		bytes = PAGE_CACHE_SIZE - offset;
-		if (bytes > count) {
+		if (bytes > count)
 			bytes = count;
-		}
 
 		/*
-		 * Bring in the user page that we will copy from _first_.
-		 * Otherwise there's a nasty deadlock on copying from the
-		 * same page as we're writing to, without it being marked
-		 * up-to-date.
+		 * We don't hold page lock across copy from user -
+		 * what would it guard against? - so no deadlock here.
 		 */
-		{ volatile unsigned char dummy;
-			__get_user(dummy, buf);
-			__get_user(dummy, buf+bytes-1);
-		}
 
-		info = SHMEM_I(inode);
-		down (&info->sem);
-		page = shmem_getpage_locked(info, inode, index);
-		up (&info->sem);
-
-		status = PTR_ERR(page);
-		if (IS_ERR(page))
+		err = shmem_getpage(inode, index, &page, SGP_WRITE);
+		if (err)
 			break;
 
-		/* We have exclusive IO access to the page.. */
-		if (!PageLocked(page)) {
-			PAGE_BUG(page);
-		}
-
 		kaddr = kmap(page);
-		status = copy_from_user(kaddr+offset, buf, bytes);
+		left = __copy_from_user(kaddr + offset, buf, bytes);
 		kunmap(page);
-		if (status)
-			goto fail_write;
+
+		written += bytes;
+		count -= bytes;
+		pos += bytes;
+		buf += bytes;
+		if (pos > inode->i_size)
+			inode->i_size = pos;
 
 		flush_dcache_page(page);
-		if (bytes > 0) {
-			SetPageDirty(page);
-			written += bytes;
-			count -= bytes;
-			pos += bytes;
-			buf += bytes;
-			if (pos > inode->i_size) 
-				inode->i_size = pos;
-		}
-unlock:
-		/* Mark it unlocked again and drop the page.. */
-		UnlockPage(page);
+		SetPageDirty(page);
+		SetPageReferenced(page);
 		page_cache_release(page);
 
-		if (status < 0)
+		if (left) {
+			pos -= left;
+			written -= left;
+			err = -EFAULT;
 			break;
-	}
-	*ppos = pos;
+		}
+	} while (count);
 
-	err = written ? written : status;
+	*ppos = pos;
+	if (written)
+		err = written;
 out:
 	up(&inode->i_sem);
 	return err;
-fail_write:
-	status = -EFAULT;
-	ClearPageUptodate(page);
-	goto unlock;
 }
 
-static void do_shmem_file_read(struct file * filp, loff_t *ppos, read_descriptor_t * desc)
+static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_t *desc)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
 	struct address_space *mapping = inode->i_mapping;
@@ -924,26 +1010,55 @@
 	offset = *ppos & ~PAGE_CACHE_MASK;
 
 	for (;;) {
-		struct page *page;
+		struct page *page = NULL;
 		unsigned long end_index, nr, ret;
 
 		end_index = inode->i_size >> PAGE_CACHE_SHIFT;
 		if (index > end_index)
 			break;
-		nr = PAGE_CACHE_SIZE;
 		if (index == end_index) {
 			nr = inode->i_size & ~PAGE_CACHE_MASK;
 			if (nr <= offset)
 				break;
 		}
 
-		nr = nr - offset;
-
-		if ((desc->error = shmem_getpage(inode, index, &page)))
+		desc->error = shmem_getpage(inode, index, &page, SGP_READ);
+		if (desc->error) {
+			if (desc->error == -EINVAL)
+				desc->error = 0;
 			break;
+		}
 
-		if (mapping->i_mmap_shared != NULL)
-			flush_dcache_page(page);
+		/*
+		 * We must evaluate after, since reads (unlike writes)
+		 * are called without i_sem protection against truncate
+		 */
+		nr = PAGE_CACHE_SIZE;
+		end_index = inode->i_size >> PAGE_CACHE_SHIFT;
+		if (index == end_index) {
+			nr = inode->i_size & ~PAGE_CACHE_MASK;
+			if (nr <= offset) {
+				page_cache_release(page);
+				break;
+			}
+		}
+		nr -= offset;
+
+		if (page != ZERO_PAGE(0)) {
+			/*
+			 * If users can be writing to this page using arbitrary
+			 * virtual addresses, take care about potential aliasing
+			 * before reading the page on the kernel side.
+			 */
+			if (mapping->i_mmap_shared != NULL)
+				flush_dcache_page(page);
+			/*
+			 * Mark the page accessed if we read the
+			 * beginning or we just did an lseek.
+			 */
+			if (!offset || !filp->f_reada)
+				mark_page_accessed(page);
+		}
 
 		/*
 		 * Ok, we have the page, and it's up-to-date, so
@@ -959,39 +1074,37 @@
 		offset += ret;
 		index += offset >> PAGE_CACHE_SHIFT;
 		offset &= ~PAGE_CACHE_MASK;
-	
+
 		page_cache_release(page);
 		if (ret != nr || !desc->count)
 			break;
 	}
 
 	*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
+	filp->f_reada = 1;
 	UPDATE_ATIME(inode);
 }
 
-static ssize_t shmem_file_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
+static ssize_t shmem_file_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
 {
-	ssize_t retval;
-
-	retval = -EFAULT;
-	if (access_ok(VERIFY_WRITE, buf, count)) {
-		retval = 0;
-
-		if (count) {
-			read_descriptor_t desc;
+	read_descriptor_t desc;
 
-			desc.written = 0;
-			desc.count = count;
-			desc.buf = buf;
-			desc.error = 0;
-			do_shmem_file_read(filp, ppos, &desc);
+	if ((ssize_t) count < 0)
+		return -EINVAL;
+	if (!access_ok(VERIFY_WRITE, buf, count))
+		return -EFAULT;
+	if (!count)
+		return 0;
 
-			retval = desc.written;
-			if (!retval)
-				retval = desc.error;
-		}
-	}
-	return retval;
+	desc.written = 0;
+	desc.count = count;
+	desc.buf = buf;
+	desc.error = 0;
+
+	do_shmem_file_read(filp, ppos, &desc);
+	if (desc.written)
+		return desc.written;
+	return desc.error;
 }
 
 static int shmem_statfs(struct super_block *sb, struct statfs *buf)
@@ -1000,12 +1113,12 @@
 
 	buf->f_type = TMPFS_MAGIC;
 	buf->f_bsize = PAGE_CACHE_SIZE;
-	spin_lock (&sbinfo->stat_lock);
+	spin_lock(&sbinfo->stat_lock);
 	buf->f_blocks = sbinfo->max_blocks;
 	buf->f_bavail = buf->f_bfree = sbinfo->free_blocks;
 	buf->f_files = sbinfo->max_inodes;
 	buf->f_ffree = sbinfo->free_inodes;
-	spin_unlock (&sbinfo->stat_lock);
+	spin_unlock(&sbinfo->stat_lock);
 	buf->f_namelen = NAME_MAX;
 	return 0;
 }
@@ -1014,7 +1127,7 @@
  * Lookup the data. This is trivial - if the dentry didn't already
  * exist, we know it is negative.
  */
-static struct dentry * shmem_lookup(struct inode *dir, struct dentry *dentry)
+static struct dentry *shmem_lookup(struct inode *dir, struct dentry *dentry)
 {
 	d_add(dentry, NULL);
 	return NULL;
@@ -1025,7 +1138,7 @@
  */
 static int shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
 {
-	struct inode * inode = shmem_get_inode(dir->i_sb, mode, dev);
+	struct inode *inode = shmem_get_inode(dir->i_sb, mode, dev);
 	int error = -ENOSPC;
 
 	if (inode) {
@@ -1038,7 +1151,7 @@
 	return error;
 }
 
-static int shmem_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+static int shmem_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 {
 	int error;
 
@@ -1056,7 +1169,7 @@
 /*
  * Link a file..
  */
-static int shmem_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
+static int shmem_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = old_dentry->d_inode;
 
@@ -1105,7 +1218,7 @@
 	return 1;
 }
 
-static int shmem_unlink(struct inode * dir, struct dentry *dentry)
+static int shmem_unlink(struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = dentry->d_inode;
 
@@ -1116,7 +1229,7 @@
 	return 0;
 }
 
-static int shmem_rmdir(struct inode * dir, struct dentry *dentry)
+static int shmem_rmdir(struct inode *dir, struct dentry *dentry)
 {
 	if (!shmem_empty(dentry))
 		return -ENOTEMPTY;
@@ -1131,12 +1244,12 @@
  * it exists so that the VFS layer correctly free's it when it
  * gets overwritten.
  */
-static int shmem_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
+static int shmem_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
 {
 	struct inode *inode = old_dentry->d_inode;
 	int they_are_dirs = S_ISDIR(inode->i_mode);
 
-	if (!shmem_empty(new_dentry)) 
+	if (!shmem_empty(new_dentry))
 		return -ENOTEMPTY;
 
 	if (new_dentry->d_inode) {
@@ -1156,13 +1269,14 @@
 	return 0;
 }
 
-static int shmem_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
+static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
 {
+	int error;
 	int len;
 	struct inode *inode;
-	struct page *page;
+	struct page *page = NULL;
 	char *kaddr;
-	struct shmem_inode_info * info;
+	struct shmem_inode_info *info;
 
 	len = strlen(symname) + 1;
 	if (len > PAGE_CACHE_SIZE)
@@ -1179,24 +1293,20 @@
 		memcpy(info, symname, len);
 		inode->i_op = &shmem_symlink_inline_operations;
 	} else {
-		down(&info->sem);
-		page = shmem_getpage_locked(info, inode, 0);
-		if (IS_ERR(page)) {
-			up(&info->sem);
+		error = shmem_getpage(inode, 0, &page, SGP_WRITE);
+		if (error) {
 			iput(inode);
-			return PTR_ERR(page);
+			return error;
 		}
 		inode->i_op = &shmem_symlink_inode_operations;
-		spin_lock (&shmem_ilock);
+		spin_lock(&shmem_ilock);
 		list_add_tail(&info->list, &shmem_inodes);
-		spin_unlock (&shmem_ilock);
+		spin_unlock(&shmem_ilock);
 		kaddr = kmap(page);
 		memcpy(kaddr, symname, len);
 		kunmap(page);
 		SetPageDirty(page);
-		UnlockPage(page);
 		page_cache_release(page);
-		up(&info->sem);
 	}
 	dir->i_size += BOGO_DIRENT_SIZE;
 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
@@ -1207,7 +1317,7 @@
 
 static int shmem_readlink_inline(struct dentry *dentry, char *buffer, int buflen)
 {
-	return vfs_readlink(dentry,buffer,buflen, (const char *)SHMEM_I(dentry->d_inode));
+	return vfs_readlink(dentry, buffer, buflen, (const char *)SHMEM_I(dentry->d_inode));
 }
 
 static int shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
@@ -1217,27 +1327,26 @@
 
 static int shmem_readlink(struct dentry *dentry, char *buffer, int buflen)
 {
-	struct page * page;
-	int res = shmem_getpage(dentry->d_inode, 0, &page);
-
+	struct page *page = NULL;
+	int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ);
 	if (res)
 		return res;
-
-	res = vfs_readlink(dentry,buffer,buflen, kmap(page));
+	res = vfs_readlink(dentry, buffer, buflen, kmap(page));
 	kunmap(page);
+	mark_page_accessed(page);
 	page_cache_release(page);
 	return res;
 }
 
 static int shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
-	struct page * page;
-	int res = shmem_getpage(dentry->d_inode, 0, &page);
+	struct page *page = NULL;
+	int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ);
 	if (res)
 		return res;
-
 	res = vfs_follow_link(nd, kmap(page));
 	kunmap(page);
+	mark_page_accessed(page);
 	page_cache_release(page);
 	return res;
 }
@@ -1253,19 +1362,18 @@
 	follow_link:	shmem_follow_link,
 };
 
-static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long * blocks, unsigned long *inodes)
+static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long *blocks, unsigned long *inodes)
 {
 	char *this_char, *value, *rest;
 
-	this_char = NULL;
-	if ( options )
-		this_char = strtok(options,",");
-	for ( ; this_char; this_char = strtok(NULL,",")) {
+	while ((this_char = strsep(&options, ",")) != NULL) {
+		if (!*this_char)
+			continue;
 		if ((value = strchr(this_char,'=')) != NULL) {
 			*value++ = 0;
 		} else {
-			printk(KERN_ERR 
-			    "tmpfs: No value for mount option '%s'\n", 
+			printk(KERN_ERR
+			    "tmpfs: No value for mount option '%s'\n",
 			    this_char);
 			return 1;
 		}
@@ -1273,6 +1381,14 @@
 		if (!strcmp(this_char,"size")) {
 			unsigned long long size;
 			size = memparse(value,&rest);
+			if (*rest == '%') {
+				struct sysinfo si;
+				si_meminfo(&si);
+				size <<= PAGE_SHIFT;
+				size *= si.totalram;
+				do_div(size, 100);
+				rest++;
+			}
 			if (*rest)
 				goto bad_val;
 			*blocks = size >> PAGE_CACHE_SHIFT;
@@ -1311,33 +1427,32 @@
 	return 0;
 
 bad_val:
-	printk(KERN_ERR "tmpfs: Bad value '%s' for mount option '%s'\n", 
+	printk(KERN_ERR "tmpfs: Bad value '%s' for mount option '%s'\n",
 	       value, this_char);
 	return 1;
-
 }
 
-static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
+static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
 {
-	struct shmem_sb_info *sbinfo = &sb->u.shmem_sb;
+	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
 	unsigned long max_blocks = sbinfo->max_blocks;
 	unsigned long max_inodes = sbinfo->max_inodes;
 
-	if (shmem_parse_options (data, NULL, NULL, NULL, &max_blocks, &max_inodes))
+	if (shmem_parse_options(data, NULL, NULL, NULL, &max_blocks, &max_inodes))
 		return -EINVAL;
 	return shmem_set_size(sbinfo, max_blocks, max_inodes);
 }
 
-int shmem_sync_file(struct file * file, struct dentry *dentry, int datasync)
+static int shmem_sync_file(struct file *file, struct dentry *dentry, int datasync)
 {
 	return 0;
 }
 #endif
 
-static struct super_block *shmem_read_super(struct super_block * sb, void * data, int silent)
+static struct super_block *shmem_read_super(struct super_block *sb, void *data, int silent)
 {
-	struct inode * inode;
-	struct dentry * root;
+	struct inode *inode;
+	struct dentry *root;
 	unsigned long blocks, inodes;
 	int mode   = S_IRWXUGO | S_ISVTX;
 	uid_t uid = current->fsuid;
@@ -1353,11 +1468,11 @@
 	blocks = inodes = si.totalram / 2;
 
 #ifdef CONFIG_TMPFS
-	if (shmem_parse_options (data, &mode, &uid, &gid, &blocks, &inodes))
+	if (shmem_parse_options(data, &mode, &uid, &gid, &blocks, &inodes))
 		return NULL;
 #endif
 
-	spin_lock_init (&sbinfo->stat_lock);
+	spin_lock_init(&sbinfo->stat_lock);
 	sbinfo->max_blocks = blocks;
 	sbinfo->free_blocks = blocks;
 	sbinfo->max_inodes = inodes;
@@ -1382,23 +1497,28 @@
 	return sb;
 }
 
-
-
 static struct address_space_operations shmem_aops = {
+	removepage:	shmem_removepage,
 	writepage:	shmem_writepage,
+#ifdef CONFIG_TMPFS
+	readpage:	shmem_readpage,
+	prepare_write:	shmem_prepare_write,
+	commit_write:	shmem_commit_write,
+#endif
 };
 
 static struct file_operations shmem_file_operations = {
-	mmap:	shmem_mmap,
+	mmap:		shmem_mmap,
 #ifdef CONFIG_TMPFS
-	read:	shmem_file_read,
-	write:	shmem_file_write,
-	fsync:	shmem_sync_file,
+	read:		shmem_file_read,
+	write:		shmem_file_write,
+	fsync:		shmem_sync_file,
 #endif
 };
 
 static struct inode_operations shmem_inode_operations = {
 	truncate:	shmem_truncate,
+	setattr:	shmem_notify_change,
 };
 
 static struct inode_operations shmem_dir_inode_operations = {
@@ -1421,11 +1541,11 @@
 	remount_fs:	shmem_remount_fs,
 #endif
 	delete_inode:	shmem_delete_inode,
-	put_inode:	force_delete,	
+	put_inode:	force_delete,
 };
 
 static struct vm_operations_struct shmem_vm_ops = {
-	nopage:	shmem_nopage,
+	nopage:		shmem_nopage,
 };
 
 #ifdef CONFIG_TMPFS
@@ -1437,65 +1557,65 @@
 #endif
 static struct vfsmount *shm_mnt;
 
-static int __init init_shmem_fs(void)
+static int __init init_tmpfs(void)
 {
 	int error;
-	struct vfsmount * res;
 
-	if ((error = register_filesystem(&tmpfs_fs_type))) {
-		printk (KERN_ERR "Could not register tmpfs\n");
-		return error;
+	error = register_filesystem(&tmpfs_fs_type);
+	if (error) {
+		printk(KERN_ERR "Could not register tmpfs\n");
+		goto out3;
 	}
 #ifdef CONFIG_TMPFS
-	if ((error = register_filesystem(&shmem_fs_type))) {
-		printk (KERN_ERR "Could not register shm fs\n");
-		return error;
+	error = register_filesystem(&shmem_fs_type);
+	if (error) {
+		printk(KERN_ERR "Could not register shm fs\n");
+		goto out2;
 	}
-	devfs_mk_dir (NULL, "shm", NULL);
+	devfs_mk_dir(NULL, "shm", NULL);
 #endif
-	res = kern_mount(&tmpfs_fs_type);
-	if (IS_ERR (res)) {
-		printk (KERN_ERR "could not kern_mount tmpfs\n");
-		unregister_filesystem(&tmpfs_fs_type);
-		return PTR_ERR(res);
+	shm_mnt = kern_mount(&tmpfs_fs_type);
+	if (IS_ERR(shm_mnt)) {
+		error = PTR_ERR(shm_mnt);
+		printk(KERN_ERR "Could not kern_mount tmpfs\n");
+		goto out1;
 	}
-	shm_mnt = res;
 
 	/* The internal instance should not do size checking */
-	if ((error = shmem_set_size(SHMEM_SB(res->mnt_sb), ULONG_MAX, ULONG_MAX)))
-		printk (KERN_ERR "could not set limits on internal tmpfs\n");
-
+	shmem_set_size(SHMEM_SB(shm_mnt->mnt_sb), ULONG_MAX, ULONG_MAX);
 	return 0;
-}
 
-static void __exit exit_shmem_fs(void)
-{
+out1:
 #ifdef CONFIG_TMPFS
 	unregister_filesystem(&shmem_fs_type);
+out2:
 #endif
 	unregister_filesystem(&tmpfs_fs_type);
-	mntput(shm_mnt);
+out3:
+	shm_mnt = ERR_PTR(error);
+	return error;
 }
-
-module_init(init_shmem_fs)
-module_exit(exit_shmem_fs)
+module_init(init_tmpfs)
 
 /*
- * shmem_file_setup - get an unlinked file living in shmem fs
+ * shmem_file_setup - get an unlinked file living in tmpfs
  *
  * @name: name for dentry (to be seen in /proc/<pid>/maps
  * @size: size to be set for the file
  *
  */
-struct file *shmem_file_setup(char * name, loff_t size)
+struct file *shmem_file_setup(char *name, loff_t size)
 {
 	int error;
 	struct file *file;
-	struct inode * inode;
+	struct inode *inode;
 	struct dentry *dentry, *root;
 	struct qstr this;
 	int vm_enough_memory(long pages);
 
+	if (IS_ERR(shm_mnt))
+		return (void *)shm_mnt;
+
 	if (size > SHMEM_MAX_BYTES)
 		return ERR_PTR(-EINVAL);
 
@@ -1517,7 +1637,7 @@
 
 	error = -ENOSPC;
 	inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
-	if (!inode) 
+	if (!inode)
 		goto close_file;
 
 	d_instantiate(dentry, inode);
@@ -1527,13 +1647,13 @@
 	file->f_dentry = dentry;
 	file->f_op = &shmem_file_operations;
 	file->f_mode = FMODE_WRITE | FMODE_READ;
-	return(file);
+	return file;
 
 close_file:
 	put_filp(file);
 put_dentry:
-	dput (dentry);
-	return ERR_PTR(error);	
+	dput(dentry);
+	return ERR_PTR(error);
 }
 
 /*
@@ -1545,13 +1665,13 @@
 {
 	struct file *file;
 	loff_t size = vma->vm_end - vma->vm_start;
-	
+
 	file = shmem_file_setup("dev/zero", size);
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
 	if (vma->vm_file)
-		fput (vma->vm_file);
+		fput(vma->vm_file);
 	vma->vm_file = file;
 	vma->vm_ops = &shmem_vm_ops;
 	return 0;
diff -urN linux-2.4.22-pre2/mm/swapfile.c linux-2.4.22-pre3/mm/swapfile.c
--- linux-2.4.22-pre2/mm/swapfile.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/mm/swapfile.c	2003-07-05 18:11:55.000000000 -0700
@@ -521,6 +521,7 @@
 	int i = 0;
 	int retval = 0;
 	int reset_overflow = 0;
+	int shmem;
 
 	/*
 	 * When searching mms for an entry, a good strategy is to
@@ -599,11 +600,12 @@
 		 * Whenever we reach init_mm, there's no address space
 		 * to search, but use it as a reminder to search shmem.
 		 */
+		shmem = 0;
 		swcount = *swap_map;
 		if (swcount > 1) {
 			flush_page_to_ram(page);
 			if (start_mm == &init_mm)
-				shmem_unuse(entry, page);
+				shmem = shmem_unuse(entry, page);
 			else
 				unuse_process(start_mm, entry, page);
 		}
@@ -620,7 +622,9 @@
 				swcount = *swap_map;
 				if (mm == &init_mm) {
 					set_start_mm = 1;
-					shmem_unuse(entry, page);
+					spin_unlock(&mmlist_lock);
+					shmem = shmem_unuse(entry, page);
+					spin_lock(&mmlist_lock);
 				} else
 					unuse_process(mm, entry, page);
 				if (set_start_mm && *swap_map < swcount) {
@@ -669,14 +673,23 @@
 		 * read from disk into another page.  Splitting into two
 		 * pages would be incorrect if swap supported "shared
 		 * private" pages, but they are handled by tmpfs files.
-		 * Note shmem_unuse already deleted its from swap cache.
+		 *
+		 * Note shmem_unuse already deleted swappage from cache,
+		 * unless corresponding filepage found already in cache:
+		 * in which case it left swappage in cache, lowered its
+		 * swap count to pass quickly through the loops above,
+		 * and now we must reincrement count to try again later.
 		 */
 		if ((*swap_map > 1) && PageDirty(page) && PageSwapCache(page)) {
 			rw_swap_page(WRITE, page);
 			lock_page(page);
 		}
-		if (PageSwapCache(page))
-			delete_from_swap_cache(page);
+		if (PageSwapCache(page)) {
+			if (shmem)
+				swap_duplicate(entry);
+			else
+				delete_from_swap_cache(page);
+		}
 
 		/*
 		 * So we could skip searching mms once swap count went
diff -urN linux-2.4.22-pre2/net/802/llc_sendpdu.c linux-2.4.22-pre3/net/802/llc_sendpdu.c
--- linux-2.4.22-pre2/net/802/llc_sendpdu.c	2001-04-06 10:51:19.000000000 -0700
+++ linux-2.4.22-pre3/net/802/llc_sendpdu.c	2003-07-05 18:11:56.000000000 -0700
@@ -283,7 +283,7 @@
 		if(tmp!=NULL)
 		{
 			tmp->dev = lp->dev;
-			dev_queue_xmit(skb);
+			dev_queue_xmit(tmp);
 		}
 		resend_count++;
 		skb = skb->next;
diff -urN linux-2.4.22-pre2/net/Config.in linux-2.4.22-pre3/net/Config.in
--- linux-2.4.22-pre2/net/Config.in	2002-08-02 17:39:46.000000000 -0700
+++ linux-2.4.22-pre3/net/Config.in	2003-07-05 18:11:56.000000000 -0700
@@ -34,8 +34,8 @@
    bool 'Asynchronous Transfer Mode (ATM) (EXPERIMENTAL)' CONFIG_ATM
    if [ "$CONFIG_ATM" = "y" ]; then
       if [ "$CONFIG_INET" = "y" ]; then
-	 bool '  Classical IP over ATM' CONFIG_ATM_CLIP
-	 if [ "$CONFIG_ATM_CLIP" = "y" ]; then
+	 tristate '  Classical IP over ATM' CONFIG_ATM_CLIP
+	 if [ "$CONFIG_ATM_CLIP" != "n" ]; then
 	    bool '    Do NOT send ICMP if no neighbour' CONFIG_ATM_CLIP_NO_ICMP
 	 fi
       fi
diff -urN linux-2.4.22-pre2/net/atm/Makefile linux-2.4.22-pre3/net/atm/Makefile
--- linux-2.4.22-pre2/net/atm/Makefile	2002-08-02 17:39:46.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/Makefile	2003-07-05 18:11:56.000000000 -0700
@@ -16,10 +16,10 @@
 
 obj-$(CONFIG_ATM) := addr.o pvc.o signaling.o svc.o common.o atm_misc.o raw.o resources.o
 
-ifeq ($(CONFIG_ATM_CLIP),y)
-obj-y += clip.o
-NEED_IPCOM = ipcommon.o
+ifneq ($(CONFIG_ATM_CLIP),n)
+  NEED_IPCOM = ipcommon.o
 endif
+obj-$(CONFIG_ATM_CLIP) += clip.o
 
 ifeq ($(CONFIG_ATM_BR2684),y)
   NEED_IPCOM = ipcommon.o
diff -urN linux-2.4.22-pre2/net/atm/br2684.c linux-2.4.22-pre3/net/atm/br2684.c
--- linux-2.4.22-pre2/net/atm/br2684.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/br2684.c	2003-07-05 18:11:56.000000000 -0700
@@ -189,7 +189,6 @@
 		return 0;
 		}
 	atomic_add(skb->truesize, &atmvcc->sk->wmem_alloc);
-	ATM_SKB(skb)->iovcnt = 0;
 	ATM_SKB(skb)->atm_options = atmvcc->atm_options;
 	brdev->stats.tx_packets++;
 	brdev->stats.tx_bytes += skb->len;
@@ -482,6 +481,7 @@
 	}
 	brdev->stats.rx_packets++;
 	brdev->stats.rx_bytes += skb->len;
+	memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
 	netif_rx(skb);
 }
 
diff -urN linux-2.4.22-pre2/net/atm/clip.c linux-2.4.22-pre3/net/atm/clip.c
--- linux-2.4.22-pre2/net/atm/clip.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/clip.c	2003-07-05 18:11:56.000000000 -0700
@@ -7,6 +7,8 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/kernel.h> /* for UINT_MAX */
+#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/wait.h>
@@ -45,6 +47,7 @@
 
 struct net_device *clip_devs = NULL;
 struct atm_vcc *atmarpd = NULL;
+static struct neigh_table clip_tbl;
 static struct timer_list idle_timer;
 static int start_timer = 1;
 
@@ -127,6 +130,8 @@
 			struct atmarp_entry *entry = NEIGH2ENTRY(n);
 			struct clip_vcc *clip_vcc;
 
+			write_lock(&n->lock);
+
 			for (clip_vcc = entry->vccs; clip_vcc;
 			    clip_vcc = clip_vcc->next)
 				if (clip_vcc->idle_timeout &&
@@ -141,6 +146,7 @@
 			if (entry->vccs ||
 			    time_before(jiffies, entry->expires)) {
 				np = &n->next;
+				write_unlock(&n->lock);
 				continue;
 			}
 			if (atomic_read(&n->refcnt) > 1) {
@@ -152,11 +158,13 @@
 				     NULL) 
 					dev_kfree_skb(skb);
 				np = &n->next;
+				write_unlock(&n->lock);
 				continue;
 			}
 			*np = n->next;
 			DPRINTK("expired neigh %p\n",n);
 			n->dead = 1;
+			write_unlock(&n->lock);
 			neigh_release(n);
 		}
 	}
@@ -182,7 +190,7 @@
 }
 
 
-void clip_push(struct atm_vcc *vcc,struct sk_buff *skb)
+static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb)
 {
 	struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
 
@@ -218,6 +226,7 @@
 	clip_vcc->last_use = jiffies;
 	PRIV(skb->dev)->stats.rx_packets++;
 	PRIV(skb->dev)->stats.rx_bytes += skb->len;
+	memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
 	netif_rx(skb);
 }
 
@@ -319,7 +328,7 @@
 }
 
 
-struct neigh_table clip_tbl = {
+static struct neigh_table clip_tbl = {
 	NULL,			/* next */
 	AF_INET,		/* family */
 	sizeof(struct neighbour)+sizeof(struct atmarp_entry), /* entry_size */
@@ -365,7 +374,7 @@
  */
 
 
-int clip_encap(struct atm_vcc *vcc,int mode)
+static int clip_encap(struct atm_vcc *vcc,int mode)
 {
 	CLIP_VCC(vcc)->encap = mode;
 	return 0;
@@ -427,7 +436,6 @@
 		((u16 *) here)[3] = skb->protocol;
 	}
 	atomic_add(skb->truesize,&vcc->sk->wmem_alloc);
-	ATM_SKB(skb)->iovcnt = 0;
 	ATM_SKB(skb)->atm_options = vcc->atm_options;
 	entry->vccs->last_use = jiffies;
 	DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n",skb,vcc,vcc->dev);
@@ -463,7 +471,7 @@
 }
 
 
-int clip_mkip(struct atm_vcc *vcc,int timeout)
+static int clip_mkip(struct atm_vcc *vcc,int timeout)
 {
 	struct clip_vcc *clip_vcc;
 	struct sk_buff_head copy;
@@ -503,7 +511,7 @@
 }
 
 
-int clip_setentry(struct atm_vcc *vcc,u32 ip)
+static int clip_setentry(struct atm_vcc *vcc,u32 ip)
 {
 	struct neighbour *neigh;
 	struct atmarp_entry *entry;
@@ -575,7 +583,7 @@
 }
 
 
-int clip_create(int number)
+static int clip_create(int number)
 {
 	struct net_device *dev;
 	struct clip_priv *clip_priv;
@@ -695,28 +703,23 @@
 		    "pending\n");
 	skb_queue_purge(&vcc->sk->receive_queue);
 	DPRINTK("(done)\n");
+	MOD_DEC_USE_COUNT;
 }
 
 
 static struct atmdev_ops atmarpd_dev_ops = {
-	close:	atmarpd_close,
+	.close = atmarpd_close,
 };
 
 
 static struct atm_dev atmarpd_dev = {
-	&atmarpd_dev_ops,
-	NULL,		/* no PHY */
-	"arpd",		/* type */
-	999,		/* dummy device number */
-	NULL,NULL,	/* pretend not to have any VCCs */
-	NULL,NULL,	/* no data */
-	{ 0 },		/* no flags */
-	NULL,		/* no local address */
-	{ 0 }		/* no ESI, no statistics */
+	.ops =			&atmarpd_dev_ops,
+	.type =			"arpd",
+	.number =		999,
 };
 
 
-int atm_init_atmarp(struct atm_vcc *vcc)
+static int atm_init_atmarp(struct atm_vcc *vcc)
 {
 	struct net_device *dev;
 
@@ -743,13 +746,61 @@
 	for (dev = clip_devs; dev; dev = PRIV(dev)->next)
 		if (dev->flags & IFF_UP)
 			(void) to_atmarpd(act_up,PRIV(dev)->number,0);
+	MOD_INC_USE_COUNT;
 	return 0;
 }
 
+static struct atm_clip_ops __atm_clip_ops = {
+	.clip_create =		clip_create,
+	.clip_mkip =		clip_mkip,
+	.clip_setentry =	clip_setentry,
+	.clip_encap =		clip_encap,
+	.clip_push =		clip_push,
+	.atm_init_atmarp =	atm_init_atmarp,
+	.owner =		THIS_MODULE
+};
 
-void atm_clip_init(void)
+static int __init atm_clip_init(void)
 {
+	/* we should use neigh_table_init() */
 	clip_tbl.lock = RW_LOCK_UNLOCKED;
 	clip_tbl.kmem_cachep = kmem_cache_create(clip_tbl.id,
 	    clip_tbl.entry_size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+
+	/* so neigh_ifdown() doesn't complain */
+	clip_tbl.proxy_timer.data = 0;
+	clip_tbl.proxy_timer.function = 0;
+	init_timer(&clip_tbl.proxy_timer);
+	skb_queue_head_init(&clip_tbl.proxy_queue);
+
+	clip_tbl_hook = &clip_tbl;
+	atm_clip_ops_set(&__atm_clip_ops);
+
+	return 0;
 }
+
+static void __exit atm_clip_exit(void)
+{
+	struct net_device *dev, *next;
+
+	atm_clip_ops_set(NULL);
+
+	neigh_ifdown(&clip_tbl, NULL);
+	dev = clip_devs;
+	while (dev) {
+		next = PRIV(dev)->next;
+		unregister_netdev(dev);
+		kfree(dev);
+		dev = next;
+	}
+	if (start_timer == 0) del_timer(&idle_timer);
+
+	kmem_cache_destroy(clip_tbl.kmem_cachep);
+
+	clip_tbl_hook = NULL;
+}
+
+module_init(atm_clip_init);
+module_exit(atm_clip_exit);
+
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.22-pre2/net/atm/common.c linux-2.4.22-pre3/net/atm/common.c
--- linux-2.4.22-pre2/net/atm/common.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/common.c	2003-07-05 18:11:56.000000000 -0700
@@ -58,6 +58,36 @@
 #endif
 #endif
 
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+#include <net/atmclip.h>
+struct atm_clip_ops *atm_clip_ops;
+static DECLARE_MUTEX(atm_clip_ops_mutex);
+
+void atm_clip_ops_set(struct atm_clip_ops *hook)
+{
+	down(&atm_clip_ops_mutex);
+	atm_clip_ops = hook;
+	up(&atm_clip_ops_mutex);
+}
+
+int try_atm_clip_ops(void)
+{
+	down(&atm_clip_ops_mutex);
+	if (atm_clip_ops && try_inc_mod_count(atm_clip_ops->owner)) {
+		up(&atm_clip_ops_mutex);
+		return 1;
+	}
+	up(&atm_clip_ops_mutex);
+	return 0;
+}
+
+#ifdef CONFIG_ATM_CLIP_MODULE
+EXPORT_SYMBOL(atm_clip_ops);
+EXPORT_SYMBOL(atm_clip_ops_mutex);
+EXPORT_SYMBOL(atm_clip_ops_set);
+#endif
+#endif
+
 #if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
 int (*pppoatm_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
 EXPORT_SYMBOL(pppoatm_ioctl_hook);
@@ -99,7 +129,7 @@
 	}
 	while (!(skb = alloc_skb(size,GFP_KERNEL))) schedule();
 	DPRINTK("AlTx %d += %d\n",atomic_read(&vcc->sk->wmem_alloc),skb->truesize);
-	atomic_add(skb->truesize+ATM_PDU_OVHD,&vcc->sk->wmem_alloc);
+	atomic_add(skb->truesize, &vcc->sk->wmem_alloc);
 	return skb;
 }
 
@@ -115,7 +145,6 @@
 	vcc = sk->protinfo.af_atm;
 	memset(&vcc->flags,0,sizeof(vcc->flags));
 	vcc->dev = NULL;
-	vcc->alloc_tx = alloc_tx;
 	vcc->callback = NULL;
 	memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc));
 	memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc));
@@ -147,9 +176,7 @@
 		if (vcc->push) vcc->push(vcc,NULL); /* atmarpd has no push */
 		while ((skb = skb_dequeue(&vcc->sk->receive_queue))) {
 			atm_return(vcc,skb->truesize);
-			if (vcc->dev->ops->free_rx_skb)
-				vcc->dev->ops->free_rx_skb(vcc,skb);
-			else kfree_skb(skb);
+			kfree_skb(skb);
 		}
 		spin_lock (&atm_dev_lock);	
 		fops_put (vcc->dev->ops);
@@ -397,31 +424,8 @@
 		    (unsigned long) buff,eff_len);
 	DPRINTK("RcvM %d -= %d\n",atomic_read(&vcc->sk->rmem_alloc),skb->truesize);
 	atm_return(vcc,skb->truesize);
-	if (ATM_SKB(skb)->iovcnt) { /* @@@ hack */
-		/* iovcnt set, use scatter-gather for receive */
-		int el, cnt;
-		struct iovec *iov = (struct iovec *)skb->data;
-		unsigned char *p = (unsigned char *)buff;
-
-		el = eff_len;
-		error = 0;
-		for (cnt = 0; (cnt < ATM_SKB(skb)->iovcnt) && el; cnt++) {
-/*printk("s-g???: %p -> %p (%d)\n",iov->iov_base,p,iov->iov_len);*/
-			error = copy_to_user(p,iov->iov_base,
-			    (iov->iov_len > el) ? el : iov->iov_len) ?
-			    -EFAULT : 0;
-			if (error) break;
-			p += iov->iov_len;
-			el -= (iov->iov_len > el)?el:iov->iov_len;
-			iov++;
-		}
-		if (!vcc->dev->ops->free_rx_skb) kfree_skb(skb);
-		else vcc->dev->ops->free_rx_skb(vcc, skb);
-		return error ? error : eff_len;
-	}
 	error = copy_to_user(buff,skb->data,eff_len) ? -EFAULT : 0;
-	if (!vcc->dev->ops->free_rx_skb) kfree_skb(skb);
-	else vcc->dev->ops->free_rx_skb(vcc, skb);
+	kfree_skb(skb);
 	return error ? error : eff_len;
 }
 
@@ -453,7 +457,7 @@
 	add_wait_queue(&vcc->sleep,&wait);
 	set_current_state(TASK_INTERRUPTIBLE);
 	error = 0;
-	while (!(skb = vcc->alloc_tx(vcc,eff))) {
+	while (!(skb = alloc_tx(vcc,eff))) {
 		if (m->msg_flags & MSG_DONTWAIT) {
 			error = -EAGAIN;
 			break;
@@ -478,7 +482,6 @@
 	remove_wait_queue(&vcc->sleep,&wait);
 	if (error) return error;
 	skb->dev = NULL; /* for paths shared with net_device interfaces */
-	ATM_SKB(skb)->iovcnt = 0;
 	ATM_SKB(skb)->atm_options = vcc->atm_options;
 	if (copy_from_user(skb_put(skb,size),buff,size)) {
 		kfree_skb(skb);
@@ -505,8 +508,7 @@
 		mask |= POLLHUP;
 	if (sock->state != SS_CONNECTING) {
 		if (vcc->qos.txtp.traffic_class != ATM_NONE &&
-		    vcc->qos.txtp.max_sdu+atomic_read(&vcc->sk->wmem_alloc)+
-		    ATM_PDU_OVHD <= vcc->sk->sndbuf)
+		    vcc->qos.txtp.max_sdu+atomic_read(&vcc->sk->wmem_alloc) <= vcc->sk->sndbuf)
 			mask |= POLLOUT | POLLWRNORM;
 	}
 	else if (vcc->reply != WAITING) {
@@ -573,7 +575,7 @@
 				goto done;
 			}
 			ret_val =  put_user(vcc->sk->sndbuf-
-			    atomic_read(&vcc->sk->wmem_alloc)-ATM_PDU_OVHD,
+			    atomic_read(&vcc->sk->wmem_alloc),
 			    (int *) arg) ? -EFAULT : 0;
 			goto done;
 		case SIOCINQ:
@@ -654,39 +656,68 @@
 			if (!error) sock->state = SS_CONNECTED;
 			ret_val = error;
 			goto done;
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 		case SIOCMKCLIP:
-			if (!capable(CAP_NET_ADMIN))
+			if (!capable(CAP_NET_ADMIN)) {
 				ret_val = -EPERM;
-			else 
-				ret_val = clip_create(arg);
+				goto done;
+			}
+			if (try_atm_clip_ops()) {
+				ret_val = atm_clip_ops->clip_create(arg);
+				__MOD_DEC_USE_COUNT(atm_clip_ops->owner);
+			} else
+				ret_val = -ENOSYS;
 			goto done;
 		case ATMARPD_CTRL:
 			if (!capable(CAP_NET_ADMIN)) {
 				ret_val = -EPERM;
 				goto done;
 			}
-			error = atm_init_atmarp(vcc);
-			if (!error) sock->state = SS_CONNECTED;
-			ret_val = error;
+#if defined(CONFIG_ATM_CLIP_MODULE)
+			if (!atm_clip_ops)
+				request_module("clip");
+#endif
+			if (try_atm_clip_ops()) {
+				error = atm_clip_ops->atm_init_atmarp(vcc);
+				__MOD_DEC_USE_COUNT(atm_clip_ops->owner);
+				if (!error)
+					sock->state = SS_CONNECTED;
+				ret_val = error;
+			} else
+				ret_val = -ENOSYS;
 			goto done;
 		case ATMARP_MKIP:
-			if (!capable(CAP_NET_ADMIN)) 
+			if (!capable(CAP_NET_ADMIN)) {
 				ret_val = -EPERM;
-			else 
-				ret_val = clip_mkip(vcc,arg);
+				goto done;
+			}
+			if (try_atm_clip_ops()) {
+				ret_val = atm_clip_ops->clip_mkip(vcc, arg);
+				__MOD_DEC_USE_COUNT(atm_clip_ops->owner);
+			} else
+				ret_val = -ENOSYS;
 			goto done;
 		case ATMARP_SETENTRY:
-			if (!capable(CAP_NET_ADMIN)) 
+			if (!capable(CAP_NET_ADMIN)) {
 				ret_val = -EPERM;
-			else
-				ret_val = clip_setentry(vcc,arg);
+				goto done;
+			}
+			if (try_atm_clip_ops()) {
+				ret_val = atm_clip_ops->clip_setentry(vcc, arg);
+				__MOD_DEC_USE_COUNT(atm_clip_ops->owner);
+			} else
+				ret_val = -ENOSYS;
 			goto done;
 		case ATMARP_ENCAP:
-			if (!capable(CAP_NET_ADMIN)) 
+			if (!capable(CAP_NET_ADMIN)) {
 				ret_val = -EPERM;
-			else
-				ret_val = clip_encap(vcc,arg);
+				goto done;
+			}
+			if (try_atm_clip_ops()) {
+				ret_val = atm_clip_ops->clip_encap(vcc, arg);
+				__MOD_DEC_USE_COUNT(atm_clip_ops->owner);
+			} else
+				ret_val = -ENOSYS;
 			goto done;
 #endif
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
diff -urN linux-2.4.22-pre2/net/atm/ipcommon.c linux-2.4.22-pre3/net/atm/ipcommon.c
--- linux-2.4.22-pre2/net/atm/ipcommon.c	2000-07-06 21:37:24.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/ipcommon.c	2003-07-05 18:11:56.000000000 -0700
@@ -67,4 +67,5 @@
 }
 
 
+EXPORT_SYMBOL(llc_oui);
 EXPORT_SYMBOL(skb_migrate);
diff -urN linux-2.4.22-pre2/net/atm/lec.c linux-2.4.22-pre3/net/atm/lec.c
--- linux-2.4.22-pre2/net/atm/lec.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/lec.c	2003-07-05 18:11:56.000000000 -0700
@@ -341,7 +341,6 @@
                         lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
                         lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
                 ATM_SKB(skb2)->vcc = send_vcc;
-                ATM_SKB(skb2)->iovcnt = 0;
                 ATM_SKB(skb2)->atm_options = send_vcc->atm_options;
                 DPRINTK("%s:sending to vpi:%d vci:%d\n", dev->name,
                         send_vcc->vpi, send_vcc->vci);       
@@ -357,7 +356,6 @@
         }
 
         ATM_SKB(skb)->vcc = send_vcc;
-        ATM_SKB(skb)->iovcnt = 0;
         ATM_SKB(skb)->atm_options = send_vcc->atm_options;
         if (atm_may_send(send_vcc, skb->len)) {
                 atomic_add(skb->truesize, &send_vcc->sk->wmem_alloc);
@@ -404,7 +402,7 @@
         int i;
         char *tmp; /* FIXME */
 
-	atomic_sub(skb->truesize+ATM_PDU_OVHD, &vcc->sk->wmem_alloc);
+	atomic_sub(skb->truesize, &vcc->sk->wmem_alloc);
         mesg = (struct atmlec_msg *)skb->data;
         tmp = skb->data;
         tmp += sizeof(struct atmlec_msg);
@@ -726,6 +724,7 @@
                 skb->protocol = eth_type_trans(skb, dev);
                 priv->stats.rx_packets++;
                 priv->stats.rx_bytes += skb->len;
+                memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
                 netif_rx(skb);
         }
 }
diff -urN linux-2.4.22-pre2/net/atm/mpc.c linux-2.4.22-pre3/net/atm/mpc.c
--- linux-2.4.22-pre2/net/atm/mpc.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/mpc.c	2003-07-05 18:11:56.000000000 -0700
@@ -521,7 +521,6 @@
 	}
 
 	atomic_add(skb->truesize, &entry->shortcut->sk->wmem_alloc);
-	ATM_SKB(skb)->iovcnt = 0; /* just to be safe ... */
 	ATM_SKB(skb)->atm_options = entry->shortcut->atm_options;
 	entry->shortcut->send(entry->shortcut, skb);
 	entry->packets_fwded++;
@@ -730,6 +729,7 @@
 	eg->packets_rcvd++;
 	mpc->eg_ops->put(eg);
 
+	memset(ATM_SKB(new_skb), 0, sizeof(struct atm_skb_data));
 	netif_rx(new_skb);
 
 	return;
@@ -869,7 +869,7 @@
 	
 	struct mpoa_client *mpc = find_mpc_by_vcc(vcc);
 	struct k_message *mesg = (struct k_message*)skb->data;
-	atomic_sub(skb->truesize+ATM_PDU_OVHD, &vcc->sk->wmem_alloc);
+	atomic_sub(skb->truesize, &vcc->sk->wmem_alloc);
 	
 	if (mpc == NULL) {
 		printk("mpoa: msg_from_mpoad: no mpc found\n");
diff -urN linux-2.4.22-pre2/net/atm/pppoatm.c linux-2.4.22-pre3/net/atm/pppoatm.c
--- linux-2.4.22-pre2/net/atm/pppoatm.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/pppoatm.c	2003-07-05 18:11:57.000000000 -0700
@@ -232,7 +232,6 @@
 		return 1;
 	}
 	atomic_add(skb->truesize, &ATM_SKB(skb)->vcc->sk->wmem_alloc);
-	ATM_SKB(skb)->iovcnt = 0;
 	ATM_SKB(skb)->atm_options = ATM_SKB(skb)->vcc->atm_options;
 	DPRINTK("(unit %d): atm_skb(%p)->vcc(%p)->dev(%p)\n",
 	    pvcc->chan.unit, skb, ATM_SKB(skb)->vcc,
diff -urN linux-2.4.22-pre2/net/atm/proc.c linux-2.4.22-pre3/net/atm/proc.c
--- linux-2.4.22-pre2/net/atm/proc.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/proc.c	2003-07-05 18:11:57.000000000 -0700
@@ -39,10 +39,9 @@
 #include "common.h" /* atm_proc_init prototype */
 #include "signaling.h" /* to get sigd - ugly too */
 
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 #include <net/atmclip.h>
 #include "ipcommon.h"
-extern void clip_push(struct atm_vcc *vcc,struct sk_buff *skb);
 #endif
 
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
@@ -89,7 +88,7 @@
 }
 
 
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 
 
 static int svc_addr(char *buf,struct sockaddr_atmsvc *addr)
@@ -178,16 +177,21 @@
 	    aal_name[vcc->qos.aal],vcc->qos.rxtp.min_pcr,
 	    class_name[vcc->qos.rxtp.traffic_class],vcc->qos.txtp.min_pcr,
 	    class_name[vcc->qos.txtp.traffic_class]);
-#ifdef CONFIG_ATM_CLIP
-	if (vcc->push == clip_push) {
-		struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
-		struct net_device *dev;
-
-		dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL;
-		off += sprintf(buf+off,"CLIP, Itf:%s, Encap:",
-		    dev ? dev->name : "none?");
-		if (clip_vcc->encap) off += sprintf(buf+off,"LLC/SNAP");
-		else off += sprintf(buf+off,"None");
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+	if (try_atm_clip_ops()) {
+		if (vcc->push == atm_clip_ops->clip_push) {
+			struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
+			struct net_device *dev;
+
+			dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL;
+			off += sprintf(buf+off,"CLIP, Itf:%s, Encap:",
+			    dev ? dev->name : "none?");
+			if (clip_vcc->encap)
+				off += sprintf(buf+off,"LLC/SNAP");
+			else
+				off += sprintf(buf+off,"None");
+		}
+		__MOD_DEC_USE_COUNT(atm_clip_ops->owner);
 	}
 #endif
 	strcpy(buf+off,"\n");
@@ -407,7 +411,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 static int atm_arp_info(loff_t pos,char *buf)
 {
 	struct neighbour *n;
@@ -417,28 +421,33 @@
 		return sprintf(buf,"IPitf TypeEncp Idle IP address      "
 		    "ATM address\n");
 	}
+	if (!try_atm_clip_ops())
+		return 0;
 	count = pos;
-	read_lock_bh(&clip_tbl.lock);
+	read_lock_bh(&clip_tbl_hook->lock);
 	for (i = 0; i <= NEIGH_HASHMASK; i++)
-		for (n = clip_tbl.hash_buckets[i]; n; n = n->next) {
+		for (n = clip_tbl_hook->hash_buckets[i]; n; n = n->next) {
 			struct atmarp_entry *entry = NEIGH2ENTRY(n);
 			struct clip_vcc *vcc;
 
 			if (!entry->vccs) {
 				if (--count) continue;
 				atmarp_info(n->dev,entry,NULL,buf);
-				read_unlock_bh(&clip_tbl.lock);
+				read_unlock_bh(&clip_tbl_hook->lock);
+				__MOD_DEC_USE_COUNT(atm_clip_ops->owner);
 				return strlen(buf);
 			}
 			for (vcc = entry->vccs; vcc;
 			    vcc = vcc->next) {
 				if (--count) continue;
 				atmarp_info(n->dev,entry,vcc,buf);
-				read_unlock_bh(&clip_tbl.lock);
+				read_unlock_bh(&clip_tbl_hook->lock);
+				__MOD_DEC_USE_COUNT(atm_clip_ops->owner);
 				return strlen(buf);
 			}
 		}
-	read_unlock_bh(&clip_tbl.lock);
+	read_unlock_bh(&clip_tbl_hook->lock);
+	__MOD_DEC_USE_COUNT(atm_clip_ops->owner);
 	return 0;
 }
 #endif
@@ -612,7 +621,7 @@
 	CREATE_ENTRY(pvc);
 	CREATE_ENTRY(svc);
 	CREATE_ENTRY(vc);
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 	CREATE_ENTRY(arp);
 #endif
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
diff -urN linux-2.4.22-pre2/net/atm/pvc.c linux-2.4.22-pre3/net/atm/pvc.c
--- linux-2.4.22-pre2/net/atm/pvc.c	2001-04-12 12:11:39.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/pvc.c	2003-07-05 18:11:57.000000000 -0700
@@ -8,16 +8,12 @@
 				   struct proto_ops */
 #include <linux/atm.h>		/* ATM stuff */
 #include <linux/atmdev.h>	/* ATM devices */
-#include <linux/atmclip.h>	/* Classical IP over ATM */
 #include <linux/errno.h>	/* error codes */
 #include <linux/kernel.h>	/* printk */
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
 #include <net/sock.h>		/* for sock_no_* */
-#ifdef CONFIG_ATM_CLIP
-#include <net/atmclip.h>
-#endif
 
 #include "resources.h"		/* devs and vccs */
 #include "common.h"		/* common for PVCs and SVCs */
@@ -133,9 +129,6 @@
 		printk(KERN_ERR "ATMPVC: can't register (%d)",error);
 		return error;
 	}
-#ifdef CONFIG_ATM_CLIP
-	atm_clip_init();
-#endif
 #ifdef CONFIG_PROC_FS
 	error = atm_proc_init();
 	if (error) printk("atm_proc_init fails with %d\n",error);
diff -urN linux-2.4.22-pre2/net/atm/raw.c linux-2.4.22-pre3/net/atm/raw.c
--- linux-2.4.22-pre2/net/atm/raw.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/raw.c	2003-07-05 18:11:57.000000000 -0700
@@ -37,7 +37,7 @@
 static void atm_pop_raw(struct atm_vcc *vcc,struct sk_buff *skb)
 {
 	DPRINTK("APopR (%d) %d -= %d\n",vcc->vci,vcc->sk->wmem_alloc,skb->truesize);
-	atomic_sub(skb->truesize+ATM_PDU_OVHD,&vcc->sk->wmem_alloc);
+	atomic_sub(skb->truesize, &vcc->sk->wmem_alloc);
 	dev_kfree_skb_any(skb);
 	wake_up(&vcc->sleep);
 }
diff -urN linux-2.4.22-pre2/net/atm/signaling.c linux-2.4.22-pre3/net/atm/signaling.c
--- linux-2.4.22-pre2/net/atm/signaling.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/atm/signaling.c	2003-07-05 18:11:57.000000000 -0700
@@ -98,7 +98,7 @@
 	struct atm_vcc *session_vcc;
 
 	msg = (struct atmsvc_msg *) skb->data;
-	atomic_sub(skb->truesize+ATM_PDU_OVHD,&vcc->sk->wmem_alloc);
+	atomic_sub(skb->truesize, &vcc->sk->wmem_alloc);
 	DPRINTK("sigd_send %d (0x%lx)\n",(int) msg->type,
 	  (unsigned long) msg->vcc);
 	vcc = *(struct atm_vcc **) &msg->vcc;
diff -urN linux-2.4.22-pre2/net/bluetooth/cmtp/core.c linux-2.4.22-pre3/net/bluetooth/cmtp/core.c
--- linux-2.4.22-pre2/net/bluetooth/cmtp/core.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/net/bluetooth/cmtp/core.c	2003-07-05 18:11:58.000000000 -0700
@@ -35,6 +35,7 @@
 #include <linux/socket.h>
 #include <linux/ioctl.h>
 #include <linux/file.h>
+#include <linux/init.h>
 #include <net/sock.h>
 
 #include <net/bluetooth/bluetooth.h>
diff -urN linux-2.4.22-pre2/net/bridge/br_fdb.c linux-2.4.22-pre3/net/bridge/br_fdb.c
--- linux-2.4.22-pre2/net/bridge/br_fdb.c	2002-02-25 11:38:14.000000000 -0800
+++ linux-2.4.22-pre3/net/bridge/br_fdb.c	2003-07-05 18:12:00.000000000 -0700
@@ -292,21 +292,30 @@
 	write_lock_bh(&br->hash_lock);
 	fdb = br->hash[hash];
 	while (fdb != NULL) {
-		if (!fdb->is_local &&
-		    !memcmp(fdb->addr.addr, addr, ETH_ALEN)) {
+		if (!memcmp(fdb->addr.addr, addr, ETH_ALEN)) {
+			/* attempt to update an entry for a local interface */
+			if (fdb->is_local) {
+				if (is_local) 
+					printk(KERN_INFO "%s: attempt to add"
+					       " interface with same source address.\n",
+					       source->dev->name);
+				else if (net_ratelimit()) 
+					printk(KERN_WARNING "%s: received packet with "
+					       " own address as source address\n",
+					       source->dev->name);
+				goto out;
+			}
+
 			__fdb_possibly_replace(fdb, source, is_local);
-			write_unlock_bh(&br->hash_lock);
-			return;
+			goto out;
 		}
 
 		fdb = fdb->next_hash;
 	}
 
 	fdb = kmalloc(sizeof(*fdb), GFP_ATOMIC);
-	if (fdb == NULL) {
-		write_unlock_bh(&br->hash_lock);
-		return;
-	}
+	if (fdb == NULL) 
+		goto out;
 
 	memcpy(fdb->addr.addr, addr, ETH_ALEN);
 	atomic_set(&fdb->use_count, 1);
@@ -317,5 +326,6 @@
 
 	__hash_link(br, fdb, hash);
 
+ out:
 	write_unlock_bh(&br->hash_lock);
 }
diff -urN linux-2.4.22-pre2/net/bridge/br_if.c linux-2.4.22-pre3/net/bridge/br_if.c
--- linux-2.4.22-pre2/net/bridge/br_if.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/bridge/br_if.c	2003-07-05 18:12:00.000000000 -0700
@@ -118,7 +118,7 @@
 	br->bridge_id.prio[1] = 0x00;
 	memset(br->bridge_id.addr, 0, ETH_ALEN);
 
-	br->stp_enabled = 1;
+	br->stp_enabled = 0;
 	br->designated_root = br->bridge_id;
 	br->root_path_cost = 0;
 	br->root_port = 0;
diff -urN linux-2.4.22-pre2/net/bridge/br_input.c linux-2.4.22-pre3/net/bridge/br_input.c
--- linux-2.4.22-pre2/net/bridge/br_input.c	2002-08-02 17:39:46.000000000 -0700
+++ linux-2.4.22-pre3/net/bridge/br_input.c	2003-07-05 18:12:00.000000000 -0700
@@ -160,7 +160,8 @@
 
 handle_special_frame:
 	if (!dest[5]) {
-		br_stp_handle_bpdu(skb);
+		NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,NULL,
+			br_stp_handle_bpdu);
 		read_unlock(&br->lock);
 		return;
 	}
diff -urN linux-2.4.22-pre2/net/bridge/br_private.h linux-2.4.22-pre3/net/bridge/br_private.h
--- linux-2.4.22-pre2/net/bridge/br_private.h	2002-02-25 11:38:14.000000000 -0800
+++ linux-2.4.22-pre3/net/bridge/br_private.h	2003-07-05 18:12:00.000000000 -0700
@@ -199,6 +199,6 @@
 			  int path_cost);
 
 /* br_stp_bpdu.c */
-extern void br_stp_handle_bpdu(struct sk_buff *skb);
+extern int br_stp_handle_bpdu(struct sk_buff *skb);
 
 #endif
diff -urN linux-2.4.22-pre2/net/bridge/br_stp_bpdu.c linux-2.4.22-pre3/net/bridge/br_stp_bpdu.c
--- linux-2.4.22-pre2/net/bridge/br_stp_bpdu.c	2001-11-13 09:16:05.000000000 -0800
+++ linux-2.4.22-pre3/net/bridge/br_stp_bpdu.c	2003-07-05 18:12:00.000000000 -0700
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/if_ether.h>
 #include <linux/if_bridge.h>
+#include <linux/netfilter_bridge.h>
 #include "br_private.h"
 #include "br_private_stp.h"
 
@@ -53,7 +54,8 @@
 	memcpy(skb->nh.raw, data, length);
 	memset(skb->nh.raw + length, 0xa5, size - length - 2*ETH_ALEN - 2);
 
-	dev_queue_xmit(skb);
+	NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
+		dev_queue_xmit);
 }
 
 static __inline__ void br_set_ticks(unsigned char *dest, int jiff)
@@ -133,61 +135,65 @@
 static unsigned char header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
 
 /* called under bridge lock */
-void br_stp_handle_bpdu(struct sk_buff *skb)
+int br_stp_handle_bpdu(struct sk_buff *skb)
 {
 	unsigned char *buf;
 	struct net_bridge_port *p;
 
-	buf = skb->mac.raw + 14;
 	p = skb->dev->br_port;
-	if (!p->br->stp_enabled || memcmp(buf, header, 6)) {
-		kfree_skb(skb);
-		return;
-	}
 
-	if (buf[6] == BPDU_TYPE_CONFIG) {
+	if (!p->br->stp_enabled ||
+	    !pskb_may_pull(skb, sizeof(header)+1) ||
+	    memcmp(skb->data, header, sizeof(header)))
+		goto err;
+
+	buf = skb_pull(skb, sizeof(header));
+	if (buf[0] == BPDU_TYPE_CONFIG) {
 		struct br_config_bpdu bpdu;
 
-		bpdu.topology_change = (buf[7] & 0x01) ? 1 : 0;
-		bpdu.topology_change_ack = (buf[7] & 0x80) ? 1 : 0;
-		bpdu.root.prio[0] = buf[8];
-		bpdu.root.prio[1] = buf[9];
-		bpdu.root.addr[0] = buf[10];
-		bpdu.root.addr[1] = buf[11];
-		bpdu.root.addr[2] = buf[12];
-		bpdu.root.addr[3] = buf[13];
-		bpdu.root.addr[4] = buf[14];
-		bpdu.root.addr[5] = buf[15];
+		if (!pskb_may_pull(skb, 32))
+			goto err;
+
+		buf = skb->data;
+		bpdu.topology_change = (buf[1] & 0x01) ? 1 : 0;
+		bpdu.topology_change_ack = (buf[1] & 0x80) ? 1 : 0;
+
+		bpdu.root.prio[0] = buf[2];
+		bpdu.root.prio[1] = buf[3];
+		bpdu.root.addr[0] = buf[4];
+		bpdu.root.addr[1] = buf[5];
+		bpdu.root.addr[2] = buf[6];
+		bpdu.root.addr[3] = buf[7];
+		bpdu.root.addr[4] = buf[8];
+		bpdu.root.addr[5] = buf[9];
 		bpdu.root_path_cost =
-			(buf[16] << 24) |
-			(buf[17] << 16) |
-			(buf[18] << 8) |
-			buf[19];
-		bpdu.bridge_id.prio[0] = buf[20];
-		bpdu.bridge_id.prio[1] = buf[21];
-		bpdu.bridge_id.addr[0] = buf[22];
-		bpdu.bridge_id.addr[1] = buf[23];
-		bpdu.bridge_id.addr[2] = buf[24];
-		bpdu.bridge_id.addr[3] = buf[25];
-		bpdu.bridge_id.addr[4] = buf[26];
-		bpdu.bridge_id.addr[5] = buf[27];
-		bpdu.port_id = (buf[28] << 8) | buf[29];
-
-		bpdu.message_age = br_get_ticks(buf+30);
-		bpdu.max_age = br_get_ticks(buf+32);
-		bpdu.hello_time = br_get_ticks(buf+34);
-		bpdu.forward_delay = br_get_ticks(buf+36);
+			(buf[10] << 24) |
+			(buf[11] << 16) |
+			(buf[12] << 8) |
+			buf[13];
+		bpdu.bridge_id.prio[0] = buf[14];
+		bpdu.bridge_id.prio[1] = buf[15];
+		bpdu.bridge_id.addr[0] = buf[16];
+		bpdu.bridge_id.addr[1] = buf[17];
+		bpdu.bridge_id.addr[2] = buf[18];
+		bpdu.bridge_id.addr[3] = buf[19];
+		bpdu.bridge_id.addr[4] = buf[20];
+		bpdu.bridge_id.addr[5] = buf[21];
+		bpdu.port_id = (buf[22] << 8) | buf[23];
+
+		bpdu.message_age = br_get_ticks(buf+24);
+		bpdu.max_age = br_get_ticks(buf+26);
+		bpdu.hello_time = br_get_ticks(buf+28);
+		bpdu.forward_delay = br_get_ticks(buf+30);
 
-		kfree_skb(skb);
 		br_received_config_bpdu(p, &bpdu);
-		return;
 	}
 
-	if (buf[6] == BPDU_TYPE_TCN) {
+	else if (buf[0] == BPDU_TYPE_TCN) {
 		br_received_tcn_bpdu(p);
-		kfree_skb(skb);
-		return;
 	}
 
-	kfree_skb(skb);
+ err:
+	kfree(skb);
+	return 0;
 }
diff -urN linux-2.4.22-pre2/net/decnet/dn_table.c linux-2.4.22-pre3/net/decnet/dn_table.c
--- linux-2.4.22-pre2/net/decnet/dn_table.c	2001-12-21 09:42:05.000000000 -0800
+++ linux-2.4.22-pre3/net/decnet/dn_table.c	2003-07-05 18:12:01.000000000 -0700
@@ -836,8 +836,7 @@
                 return NULL;
 
         if (in_interrupt() && net_ratelimit()) {
-                printk(KERN_DEBUG "DECnet: BUG! Attempt to create routing table 
-from interrupt\n"); 
+                printk(KERN_DEBUG "DECnet: BUG! Attempt to create routing table from interrupt\n"); 
                 return NULL;
         }
         if ((t = kmalloc(sizeof(struct dn_fib_table), GFP_KERNEL)) == NULL)
diff -urN linux-2.4.22-pre2/net/ipv4/arp.c linux-2.4.22-pre3/net/ipv4/arp.c
--- linux-2.4.22-pre2/net/ipv4/arp.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-pre3/net/ipv4/arp.c	2003-07-05 18:12:02.000000000 -0700
@@ -105,8 +105,9 @@
 #include <net/netrom.h>
 #endif
 #endif
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 #include <net/atmclip.h>
+struct neigh_table *clip_tbl_hook;
 #endif
 
 #include <asm/system.h>
@@ -438,8 +439,8 @@
 		if (dev->flags&(IFF_LOOPBACK|IFF_POINTOPOINT))
 			nexthop = 0;
 		n = __neigh_lookup_errno(
-#ifdef CONFIG_ATM_CLIP
-		    dev->type == ARPHRD_ATM ? &clip_tbl :
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+		    dev->type == ARPHRD_ATM ? clip_tbl_hook :
 #endif
 		    &arp_tbl, &nexthop, dev);
 		if (IS_ERR(n))
diff -urN linux-2.4.22-pre2/net/ipv4/netfilter/Config.in linux-2.4.22-pre3/net/ipv4/netfilter/Config.in
--- linux-2.4.22-pre2/net/ipv4/netfilter/Config.in	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/net/ipv4/netfilter/Config.in	2003-07-05 18:12:06.000000000 -0700
@@ -114,6 +114,9 @@
 if [ "$CONFIG_IP_NF_ARPTABLES" != "n" ]; then
   dep_tristate '  ARP packet filtering' CONFIG_IP_NF_ARPFILTER $CONFIG_IP_NF_ARPTABLES 
 fi
+if [ "$CONFIG_IP_NF_ARPTABLES" != "n" ]; then
+  dep_tristate '  ARP payload mangling' CONFIG_IP_NF_ARP_MANGLE $CONFIG_IP_NF_ARPTABLES
+fi
 
 # Backwards compatibility modules: only if you don't build in the others.
 if [ "$CONFIG_IP_NF_CONNTRACK" != "y" ]; then
diff -urN linux-2.4.22-pre2/net/ipv4/netfilter/Makefile linux-2.4.22-pre3/net/ipv4/netfilter/Makefile
--- linux-2.4.22-pre2/net/ipv4/netfilter/Makefile	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/net/ipv4/netfilter/Makefile	2003-07-05 18:12:06.000000000 -0700
@@ -103,6 +103,7 @@
 
 # generic ARP tables
 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
+obj-$(CONFIG_IP_NF_ARP_MANGLE) += arpt_mangle.o
 
 # just filtering instance of ARP tables for now
 obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o
diff -urN linux-2.4.22-pre2/net/ipv4/netfilter/arp_tables.c linux-2.4.22-pre3/net/ipv4/netfilter/arp_tables.c
--- linux-2.4.22-pre2/net/ipv4/netfilter/arp_tables.c	2002-08-02 17:39:46.000000000 -0700
+++ linux-2.4.22-pre3/net/ipv4/netfilter/arp_tables.c	2003-07-05 18:12:06.000000000 -0700
@@ -136,6 +136,7 @@
 		dprintf("ARP hardware address length mismatch.\n");
 		dprintf("ar_hln: %02x info->arhln: %02x info->arhln_mask: %02x\n",
 			arphdr->ar_hln, arpinfo->arhln, arpinfo->arhln_mask);
+		return 0;
 	}
 
 	src_devaddr = arpptr;
diff -urN linux-2.4.22-pre2/net/ipv4/netfilter/arpt_mangle.c linux-2.4.22-pre3/net/ipv4/netfilter/arpt_mangle.c
--- linux-2.4.22-pre2/net/ipv4/netfilter/arpt_mangle.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/net/ipv4/netfilter/arpt_mangle.c	2003-07-05 18:12:06.000000000 -0700
@@ -0,0 +1,101 @@
+/* module that allows mangling of the arp payload */
+#include <linux/module.h>
+#include <linux/netfilter_arp/arpt_mangle.h>
+#include <net/sock.h>
+
+static unsigned int
+target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in,
+   const struct net_device *out, const void *targinfo, void *userinfo)
+{
+	const struct arpt_mangle *mangle = targinfo;
+	struct arphdr *arp;
+	unsigned char *arpptr;
+	int pln, hln;
+
+	if (skb_shared(*pskb) || skb_cloned(*pskb)) {
+		struct sk_buff *nskb;
+
+		nskb = skb_copy(*pskb, GFP_ATOMIC);
+		if (!nskb)
+			return NF_DROP;
+		if ((*pskb)->sk)
+			skb_set_owner_w(nskb, (*pskb)->sk);
+		kfree_skb(*pskb);
+		*pskb = nskb;
+	}
+
+	arp = (*pskb)->nh.arph;
+	arpptr = (*pskb)->nh.raw + sizeof(*arp);
+	pln = arp->ar_pln;
+	hln = arp->ar_hln;
+	/* We assume that hln was checked in the match */
+	if (mangle->flags & ARPT_MANGLE_SDEV) {
+		if (ARPT_DEV_ADDR_LEN_MAX < hln ||
+		   (arpptr + hln > (**pskb).tail))
+			return NF_DROP;
+		memcpy(arpptr, mangle->src_devaddr, hln);
+	}
+	arpptr += hln;
+	if (mangle->flags & ARPT_MANGLE_SIP) {
+		if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
+		   (arpptr + pln > (**pskb).tail))
+			return NF_DROP;
+		memcpy(arpptr, &mangle->u_s.src_ip, pln);
+	}
+	arpptr += pln;
+	if (mangle->flags & ARPT_MANGLE_TDEV) {
+		if (ARPT_DEV_ADDR_LEN_MAX < hln ||
+		   (arpptr + hln > (**pskb).tail))
+			return NF_DROP;
+		memcpy(arpptr, mangle->tgt_devaddr, hln);
+	}
+	arpptr += hln;
+	if (mangle->flags & ARPT_MANGLE_TIP) {
+		if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
+		   (arpptr + pln > (**pskb).tail))
+			return NF_DROP;
+		memcpy(arpptr, &mangle->u_t.tgt_ip, pln);
+	}
+	return mangle->target;
+}
+
+static int
+checkentry(const char *tablename, const struct arpt_entry *e, void *targinfo,
+   unsigned int targinfosize, unsigned int hook_mask)
+{
+	const struct arpt_mangle *mangle = targinfo;
+
+	if (mangle->flags & ~ARPT_MANGLE_MASK ||
+	    !(mangle->flags & ARPT_MANGLE_MASK))
+		return 0;
+
+	if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT &&
+	   mangle->target != ARPT_CONTINUE)
+		return 0;
+	return 1;
+}
+
+static struct arpt_target arpt_mangle_reg
+= {
+        .name		= "mangle",
+        .target		= target,
+        .checkentry	= checkentry,
+        .me		= THIS_MODULE,
+};
+
+static int __init init(void)
+{
+	if (arpt_register_target(&arpt_mangle_reg))
+		return -EINVAL;
+
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	arpt_unregister_target(&arpt_mangle_reg);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.22-pre2/net/ipv4/netfilter/ip_nat_helper.c linux-2.4.22-pre3/net/ipv4/netfilter/ip_nat_helper.c
--- linux-2.4.22-pre2/net/ipv4/netfilter/ip_nat_helper.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/net/ipv4/netfilter/ip_nat_helper.c	2003-07-05 18:12:07.000000000 -0700
@@ -487,9 +487,9 @@
 			const char *tmp = me->me->name;
 			
 			if (strlen(tmp) + 6 > MODULE_MAX_NAMELEN) {
-				printk(__FUNCTION__ ": unable to "
+				printk("%s: unable to "
 				       "compute conntrack helper name "
-				       "from %s\n", tmp);
+				       "from %s\n", __FUNCTION__, tmp);
 				return -EBUSY;
 			}
 			tmp += 6;
@@ -572,7 +572,8 @@
 		    && ct_helper->me) {
 			__MOD_DEC_USE_COUNT(ct_helper->me);
 		} else 
-			printk(__FUNCTION__ ": unable to decrement usage count"
-			       " of conntrack helper %s\n", me->me->name);
+			printk("%s: unable to decrement usage count"
+			       " of conntrack helper %s\n",
+			       __FUNCTION__, me->me->name);
 	}
 }
diff -urN linux-2.4.22-pre2/net/ipv4/netfilter/ipt_recent.c linux-2.4.22-pre3/net/ipv4/netfilter/ipt_recent.c
--- linux-2.4.22-pre2/net/ipv4/netfilter/ipt_recent.c	2003-07-05 18:09:20.000000000 -0700
+++ linux-2.4.22-pre3/net/ipv4/netfilter/ipt_recent.c	2003-07-05 18:12:09.000000000 -0700
@@ -302,9 +302,15 @@
 	info->name[IPT_RECENT_NAME_LEN-1] = '\0';
 
 	skb = kmalloc(sizeof(struct sk_buff),GFP_KERNEL);
-	if(!skb) { return -ENOMEM; }
+	if (!skb) {
+		used = -ENOMEM;
+		goto out_free_info;
+	}
 	skb->nh.iph = kmalloc(sizeof(struct iphdr),GFP_KERNEL);
-	if(!skb->nh.iph) { return -ENOMEM; }
+	if (!skb->nh.iph) {
+		used = -ENOMEM;
+		goto out_free_skb;
+	}
 
 	skb->nh.iph->saddr = addr;
 	skb->nh.iph->daddr = 0;
@@ -313,7 +319,9 @@
 	match(skb,NULL,NULL,info,0,NULL,sizeof(struct ipt_recent_info),NULL);
 
 	kfree(skb->nh.iph);
+out_free_skb:
 	kfree(skb);
+out_free_info:
 	kfree(info);
 
 #ifdef DEBUG
diff -urN linux-2.4.22-pre2/net/ipv6/route.c linux-2.4.22-pre3/net/ipv6/route.c
--- linux-2.4.22-pre2/net/ipv6/route.c	2003-07-05 18:09:21.000000000 -0700
+++ linux-2.4.22-pre3/net/ipv6/route.c	2003-07-05 18:12:13.000000000 -0700
@@ -71,7 +71,7 @@
 
 
 int ip6_rt_max_size = 4096;
-int ip6_rt_gc_min_interval = 5*HZ;
+int ip6_rt_gc_min_interval = HZ / 2;
 int ip6_rt_gc_timeout = 60*HZ;
 int ip6_rt_gc_interval = 30*HZ;
 int ip6_rt_gc_elasticity = 9;
diff -urN linux-2.4.22-pre2/net/netsyms.c linux-2.4.22-pre3/net/netsyms.c
--- linux-2.4.22-pre2/net/netsyms.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/netsyms.c	2003-07-05 18:12:34.000000000 -0700
@@ -45,6 +45,9 @@
 #include <linux/ip.h>
 #include <net/protocol.h>
 #include <net/arp.h>
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+#include <net/atmclip.h>
+#endif
 #include <net/ip.h>
 #include <net/udp.h>
 #include <net/tcp.h>
@@ -461,6 +464,9 @@
 EXPORT_SYMBOL(ip_rcv);
 EXPORT_SYMBOL(arp_rcv);
 EXPORT_SYMBOL(arp_tbl);
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+EXPORT_SYMBOL(clip_tbl_hook);
+#endif
 EXPORT_SYMBOL(arp_find);
 
 #endif  /* CONFIG_INET */
diff -urN linux-2.4.22-pre2/net/sched/sch_atm.c linux-2.4.22-pre3/net/sched/sch_atm.c
--- linux-2.4.22-pre2/net/sched/sch_atm.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/sched/sch_atm.c	2003-07-05 18:12:35.000000000 -0700
@@ -512,7 +512,6 @@
 			memcpy(skb_push(skb,flow->hdr_len),flow->hdr,
 			    flow->hdr_len);
 			atomic_add(skb->truesize,&flow->vcc->sk->wmem_alloc);
-			ATM_SKB(skb)->iovcnt = 0;
 			/* atm.atm_options are already set by atm_tc_enqueue */
 			(void) flow->vcc->send(flow->vcc,skb);
 		}
diff -urN linux-2.4.22-pre2/net/sunrpc/clnt.c linux-2.4.22-pre3/net/sunrpc/clnt.c
--- linux-2.4.22-pre2/net/sunrpc/clnt.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/sunrpc/clnt.c	2003-07-05 18:12:36.000000000 -0700
@@ -55,9 +55,8 @@
 static void	call_refresh(struct rpc_task *task);
 static void	call_refreshresult(struct rpc_task *task);
 static void	call_timeout(struct rpc_task *task);
-static void	call_reconnect(struct rpc_task *task);
-static void	child_reconnect(struct rpc_task *);
-static void	child_reconnect_status(struct rpc_task *);
+static void	call_connect(struct rpc_task *task);
+static void	call_connect_status(struct rpc_task *);
 static u32 *	call_header(struct rpc_task *task);
 static u32 *	call_verify(struct rpc_task *task);
 
@@ -394,8 +393,6 @@
 static void
 call_reserve(struct rpc_task *task)
 {
-	struct rpc_clnt	*clnt = task->tk_client;
-
 	dprintk("RPC: %4d call_reserve\n", task->tk_pid);
 
 	if (!rpcauth_uptodatecred(task)) {
@@ -405,7 +402,6 @@
 
 	task->tk_status  = 0;
 	task->tk_action  = call_reserveresult;
-	task->tk_timeout = clnt->cl_timeout.to_resrvval;
 	xprt_reserve(task);
 }
 
@@ -419,38 +415,46 @@
 
 	dprintk("RPC: %4d call_reserveresult (status %d)\n",
 				task->tk_pid, task->tk_status);
+
 	/*
 	 * After a call to xprt_reserve(), we must have either
 	 * a request slot or else an error status.
 	 */
-	if ((task->tk_status >= 0 && !task->tk_rqstp) ||
-	    (task->tk_status < 0 && task->tk_rqstp))
-		printk(KERN_ERR "call_reserveresult: status=%d, request=%p??\n",
-		 task->tk_status, task->tk_rqstp);
+	task->tk_status = 0;
+	if (status >= 0) {
+		if (task->tk_rqstp) {
+			task->tk_action = call_allocate;
+			return;
+		}
 
-	if (task->tk_status >= 0) {
-		task->tk_action = call_allocate;
+		printk(KERN_ERR "%s: status=%d, but no request slot, exiting\n",
+				__FUNCTION__, status);
+		rpc_exit(task, -EIO);
 		return;
 	}
 
-	task->tk_status = 0;
+	/*
+	 * Even though there was an error, we may have acquired
+	 * a request slot somehow.  Make sure not to leak it.
+	 */
+	if (task->tk_rqstp) {
+		printk(KERN_ERR "%s: status=%d, request allocated anyway\n",
+				__FUNCTION__, status);
+		xprt_release(task);
+	}
+
 	switch (status) {
-	case -EAGAIN:
-	case -ENOBUFS:
-		task->tk_timeout = task->tk_client->cl_timeout.to_resrvval;
+	case -EAGAIN:	/* woken up; retry */
 		task->tk_action = call_reserve;
-		break;
-	case -ETIMEDOUT:
-		dprintk("RPC: task timed out\n");
-		task->tk_action = call_timeout;
+		return;
+	case -EIO:	/* probably a shutdown */
 		break;
 	default:
-		if (!task->tk_rqstp) {
-			printk(KERN_INFO "RPC: task has no request, exit EIO\n");
-			rpc_exit(task, -EIO);
-		} else
-			rpc_exit(task, status);
+		printk(KERN_ERR "%s: unrecognized error %d, exiting\n",
+				__FUNCTION__, status);
+		break;
 	}
+	rpc_exit(task, status);
 }
 
 /*
@@ -545,53 +549,69 @@
 	struct rpc_clnt	*clnt = task->tk_client;
 	struct rpc_xprt *xprt = clnt->cl_xprt;
 
-	task->tk_action = (xprt_connected(xprt)) ? call_transmit : call_reconnect;
+	dprintk("RPC: %4d call_bind xprt %p %s connected\n", task->tk_pid,
+			xprt, (xprt_connected(xprt) ? "is" : "is not"));
+
+	task->tk_action = (xprt_connected(xprt)) ? call_transmit : call_connect;
 
 	if (!clnt->cl_port) {
-		task->tk_action = call_reconnect;
+		task->tk_action = call_connect;
 		task->tk_timeout = clnt->cl_timeout.to_maxval;
 		rpc_getport(task, clnt);
 	}
 }
 
 /*
- * 4a.	Reconnect to the RPC server (TCP case)
+ * 4a.	Establish socket
+ *	Connect to the RPC server (TCP case)
  */
 static void
-call_reconnect(struct rpc_task *task)
+call_connect(struct rpc_task *task)
 {
 	struct rpc_clnt *clnt = task->tk_client;
-	struct rpc_task *child;
 
-	dprintk("RPC: %4d call_reconnect status %d\n",
+	dprintk("RPC: %4d call_connect status %d\n",
 				task->tk_pid, task->tk_status);
 
-	task->tk_action = call_transmit;
-	if (task->tk_status < 0 || !clnt->cl_xprt->stream)
+	if (xprt_connected(clnt->cl_xprt)) {
+		task->tk_action = call_transmit;
 		return;
-
-	/* Run as a child to ensure it runs as an rpciod task */
-	child = rpc_new_child(clnt, task);
-	if (child) {
-		child->tk_action = child_reconnect;
-		rpc_run_child(task, child, NULL);
 	}
+	task->tk_action = call_connect_status;
+	if (task->tk_status < 0)
+		return;
+	xprt_connect(task);
 }
 
-static void child_reconnect(struct rpc_task *task)
+/*
+ * 4b.	Sort out reconnection result
+ */
+static void call_connect_status(struct rpc_task *task)
 {
-	task->tk_client->cl_stats->netreconn++;
+	struct rpc_clnt *clnt = task->tk_client;
+	int status = task->tk_status;
+
 	task->tk_status = 0;
-	task->tk_action = child_reconnect_status;
-	xprt_reconnect(task);
-}
+	if (status >= 0) {
+		clnt->cl_stats->netreconn++;
+		task->tk_action = call_transmit;
+		return;
+	}
 
-static void child_reconnect_status(struct rpc_task *task)
-{
-	if (task->tk_status == -EAGAIN)
-		task->tk_action = child_reconnect;
-	else
-		task->tk_action = NULL;
+	/* Something failed: we may have to rebind */
+	if (clnt->cl_autobind)
+		clnt->cl_port = 0;
+	switch (status) {
+	case -ECONNREFUSED:
+	case -ECONNRESET:
+	case -ENOTCONN:
+	case -ETIMEDOUT:
+	case -EAGAIN:
+		task->tk_action = (clnt->cl_port == 0) ? call_bind : call_connect;
+		break;
+	default:
+		rpc_exit(task, status);
+	}
 }
 
 /*
@@ -651,10 +671,8 @@
 			task->tk_action = call_bind;
 			break;
 		}
-		if (xprt->stream) {
-			task->tk_action = call_reconnect;
-			break;
-		}
+		task->tk_action = call_connect;
+		break;
 		/*
 		 * Sleep and dream of an open connection
 		 */
@@ -681,20 +699,15 @@
 call_timeout(struct rpc_task *task)
 {
 	struct rpc_clnt	*clnt = task->tk_client;
-	struct rpc_rqst	*req = task->tk_rqstp;
-
-	if (req) {
-		struct rpc_timeout *to = &req->rq_timeout;
+	struct rpc_timeout *to = &task->tk_rqstp->rq_timeout;
 
-		if (xprt_adjust_timeout(to)) {
-			dprintk("RPC: %4d call_timeout (minor timeo)\n",
-				task->tk_pid);
-			goto minor_timeout;
-		}
-		to->to_retries = clnt->cl_timeout.to_retries;
+	if (xprt_adjust_timeout(to)) {
+		dprintk("RPC: %4d call_timeout (minor)\n", task->tk_pid);
+		goto retry;
 	}
+	to->to_retries = clnt->cl_timeout.to_retries;
 
-	dprintk("RPC: %4d call_timeout (major timeo)\n", task->tk_pid);
+	dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid);
 	if (clnt->cl_softrtry) {
 		if (clnt->cl_chatty && !task->tk_exit)
 			printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
@@ -702,33 +715,18 @@
 		rpc_exit(task, -EIO);
 		return;
 	}
+
 	if (clnt->cl_chatty && !(task->tk_flags & RPC_CALL_MAJORSEEN) && rpc_ntimeo(&clnt->cl_rtt) > 7) {
 		task->tk_flags |= RPC_CALL_MAJORSEEN;
-		if (req)
-			printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
-				clnt->cl_protname, clnt->cl_server);
-#ifdef RPC_DEBUG				
-		else
-			printk(KERN_NOTICE "%s: task %d can't get a request slot\n",
-				clnt->cl_protname, task->tk_pid);
-#endif				
+		printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
+			clnt->cl_protname, clnt->cl_server);
 	}
 	if (clnt->cl_autobind)
 		clnt->cl_port = 0;
 
-minor_timeout:
-	if (!req)
-		task->tk_action = call_reserve;
-	else if (!clnt->cl_port) {
-		task->tk_action = call_bind;
-		clnt->cl_stats->rpcretrans++;
-	} else if (!xprt_connected(clnt->cl_xprt)) {
-		task->tk_action = call_reconnect;
-		clnt->cl_stats->rpcretrans++;
-	} else {
-		task->tk_action = call_transmit;
-		clnt->cl_stats->rpcretrans++;
-	}
+retry:
+	clnt->cl_stats->rpcretrans++;
+	task->tk_action = call_bind;
 	task->tk_status = 0;
 }
 
diff -urN linux-2.4.22-pre2/net/sunrpc/xdr.c linux-2.4.22-pre3/net/sunrpc/xdr.c
--- linux-2.4.22-pre2/net/sunrpc/xdr.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/sunrpc/xdr.c	2003-07-05 18:12:37.000000000 -0700
@@ -333,26 +333,219 @@
 		copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len);
 }
 
-void
-xdr_shift_buf(struct xdr_buf *xdr, size_t len)
+/*
+ * Helper routines for doing 'memmove' like operations on a struct xdr_buf
+ *
+ * _shift_data_right_pages
+ * @pages: vector of pages containing both the source and dest memory area.
+ * @pgto_base: page vector address of destination
+ * @pgfrom_base: page vector address of source
+ * @len: number of bytes to copy
+ *
+ * Note: the addresses pgto_base and pgfrom_base are both calculated in
+ *       the same way:
+ *            if a memory area starts at byte 'base' in page 'pages[i]',
+ *            then its address is given as (i << PAGE_CACHE_SHIFT) + base
+ * Also note: pgfrom_base must be < pgto_base, but the memory areas
+ * 	they point to may overlap.
+ */
+static void
+_shift_data_right_pages(struct page **pages, size_t pgto_base,
+		size_t pgfrom_base, size_t len)
 {
-	struct iovec iov[MAX_IOVEC];
-	unsigned int nr, len_part, n, skip;
+	struct page **pgfrom, **pgto;
+	char *vfrom, *vto;
+	size_t copy;
+
+	BUG_ON(pgto_base <= pgfrom_base);
+
+	pgto_base += len;
+	pgfrom_base += len;
+
+	pgto = pages + (pgto_base >> PAGE_CACHE_SHIFT);
+	pgfrom = pages + (pgfrom_base >> PAGE_CACHE_SHIFT);
+
+	pgto_base &= ~PAGE_CACHE_MASK;
+	pgfrom_base &= ~PAGE_CACHE_MASK;
 
-	skip = 0;
 	do {
+		/* Are any pointers crossing a page boundary? */
+		if (pgto_base == 0) {
+			pgto_base = PAGE_CACHE_SIZE;
+			pgto--;
+		}
+		if (pgfrom_base == 0) {
+			pgfrom_base = PAGE_CACHE_SIZE;
+			pgfrom--;
+		}
+
+		copy = len;
+		if (copy > pgto_base)
+			copy = pgto_base;
+		if (copy > pgfrom_base)
+			copy = pgfrom_base;
+		pgto_base -= copy;
+		pgfrom_base -= copy;
+
+		vto = kmap_atomic(*pgto, KM_USER0);
+		vfrom = kmap_atomic(*pgfrom, KM_USER1);
+		memmove(vto + pgto_base, vfrom + pgfrom_base, copy);
+		kunmap_atomic(vfrom, KM_USER1);
+		kunmap_atomic(vto, KM_USER0);
+
+	} while ((len -= copy) != 0);
+}
+
+/*
+ * _copy_to_pages
+ * @pages: array of pages
+ * @pgbase: page vector address of destination
+ * @p: pointer to source data
+ * @len: length
+ *
+ * Copies data from an arbitrary memory location into an array of pages
+ * The copy is assumed to be non-overlapping.
+ */
+static void
+_copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len)
+{
+	struct page **pgto;
+	char *vto;
+	size_t copy;
 
-		nr = xdr_kmap(iov, xdr, skip);
+	pgto = pages + (pgbase >> PAGE_CACHE_SHIFT);
+	pgbase &= ~PAGE_CACHE_MASK;
 
-		len_part = 0;
-		for (n = 0; n < nr; n++)
-			len_part += iov[n].iov_len;
+	do {
+		copy = PAGE_CACHE_SIZE - pgbase;
+		if (copy > len)
+			copy = len;
+
+		vto = kmap_atomic(*pgto, KM_USER0);
+		memcpy(vto + pgbase, p, copy);
+		kunmap_atomic(vto, KM_USER0);
+
+		pgbase += copy;
+		if (pgbase == PAGE_CACHE_SIZE) {
+			pgbase = 0;
+			pgto++;
+		}
+		p += copy;
 
-		xdr_shift_iovec(iov, nr, len_part);
+	} while ((len -= copy) != 0);
+}
 
-		xdr_kunmap(xdr, skip, nr);
+/*
+ * _copy_from_pages
+ * @p: pointer to destination
+ * @pages: array of pages
+ * @pgbase: offset of source data
+ * @len: length
+ *
+ * Copies data into an arbitrary memory location from an array of pages
+ * The copy is assumed to be non-overlapping.
+ */
+static void
+_copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
+{
+	struct page **pgfrom;
+	char *vfrom;
+	size_t copy;
 
-		skip += len_part;
-		len -= len_part;
-	} while (len);
+	pgfrom = pages + (pgbase >> PAGE_CACHE_SHIFT);
+	pgbase &= ~PAGE_CACHE_MASK;
+
+	do {
+		copy = PAGE_CACHE_SIZE - pgbase;
+		if (copy > len)
+			copy = len;
+
+		vfrom = kmap_atomic(*pgfrom, KM_USER0);
+		memcpy(p, vfrom + pgbase, copy);
+		kunmap_atomic(vfrom, KM_USER0);
+
+		pgbase += copy;
+		if (pgbase == PAGE_CACHE_SIZE) {
+			pgbase = 0;
+			pgfrom++;
+		}
+		p += copy;
+
+	} while ((len -= copy) != 0);
+}
+
+/*
+ * xdr_shrink_bufhead
+ * @buf: xdr_buf
+ * @len: bytes to remove from buf->head[0]
+ *
+ * Shrinks XDR buffer's header iovec buf->head[0] by 
+ * 'len' bytes. The extra data is not lost, but is instead
+ * moved into the inlined pages and/or the tail.
+ */
+void
+xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
+{
+	struct iovec *head, *tail;
+	size_t copy, offs;
+	unsigned int pglen = buf->page_len;
+
+	tail = buf->tail;
+	head = buf->head;
+	BUG_ON (len > head->iov_len);
+
+	/* Shift the tail first */
+	if (tail->iov_len != 0) {
+		if (tail->iov_len > len) {
+			copy = tail->iov_len - len;
+			memmove((char *)tail->iov_base + len,
+					tail->iov_base, copy);
+		}
+		/* Copy from the inlined pages into the tail */
+		copy = len;
+		if (copy > pglen)
+			copy = pglen;
+		offs = len - copy;
+		if (offs >= tail->iov_len)
+			copy = 0;
+		else if (copy > tail->iov_len - offs)
+			copy = tail->iov_len - offs;
+		if (copy != 0)
+			_copy_from_pages((char *)tail->iov_base + offs,
+					buf->pages,
+					buf->page_base + pglen + offs - len,
+					copy);
+		/* Do we also need to copy data from the head into the tail ? */
+		if (len > pglen) {
+			offs = copy = len - pglen;
+			if (copy > tail->iov_len)
+				copy = tail->iov_len;
+			memcpy(tail->iov_base,
+					(char *)head->iov_base +
+					head->iov_len - offs,
+					copy);
+		}
+	}
+	/* Now handle pages */
+	if (pglen != 0) {
+		if (pglen > len)
+			_shift_data_right_pages(buf->pages,
+					buf->page_base + len,
+					buf->page_base,
+					pglen - len);
+		copy = len;
+		if (len > pglen)
+			copy = pglen;
+		_copy_to_pages(buf->pages, buf->page_base,
+				(char *)head->iov_base + head->iov_len - len,
+				copy);
+	}
+	head->iov_len -= len;
+	buf->len -= len;
+}
+
+void
+xdr_shift_buf(struct xdr_buf *buf, size_t len)
+{
+	xdr_shrink_bufhead(buf, len);
 }
diff -urN linux-2.4.22-pre2/net/sunrpc/xprt.c linux-2.4.22-pre3/net/sunrpc/xprt.c
--- linux-2.4.22-pre2/net/sunrpc/xprt.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.22-pre3/net/sunrpc/xprt.c	2003-07-05 18:12:37.000000000 -0700
@@ -83,10 +83,10 @@
  */
 static void	xprt_request_init(struct rpc_task *, struct rpc_xprt *);
 static void	do_xprt_transmit(struct rpc_task *);
-static void	xprt_reserve_status(struct rpc_task *task);
+static inline void	do_xprt_reserve(struct rpc_task *);
 static void	xprt_disconnect(struct rpc_xprt *);
-static void	xprt_reconn_status(struct rpc_task *task);
-static struct socket *xprt_create_socket(int, struct rpc_timeout *);
+static void	xprt_connect_status(struct rpc_task *task);
+static struct socket *xprt_create_socket(int, struct rpc_timeout *, int);
 static int	xprt_bind_socket(struct rpc_xprt *, struct socket *);
 static int      __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
 
@@ -133,14 +133,17 @@
 /*
  * Serialize write access to sockets, in order to prevent different
  * requests from interfering with each other.
- * Also prevents TCP socket reconnections from colliding with writes.
+ * Also prevents TCP socket connections from colliding with writes.
  */
 static int
 __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
 {
 	if (!xprt->snd_task) {
-		if (xprt->nocong || __xprt_get_cong(xprt, task))
+		if (xprt->nocong || __xprt_get_cong(xprt, task)) {
 			xprt->snd_task = task;
+			if (task->tk_rqstp)
+				task->tk_rqstp->rq_bytes_sent = 0;
+		}
 	}
 	if (xprt->snd_task != task) {
 		dprintk("RPC: %4d TCP write queue full\n", task->tk_pid);
@@ -179,8 +182,11 @@
 		if (!task)
 			return;
 	}
-	if (xprt->nocong || __xprt_get_cong(xprt, task))
+	if (xprt->nocong || __xprt_get_cong(xprt, task)) {
 		xprt->snd_task = task;
+		if (task->tk_rqstp)
+			task->tk_rqstp->rq_bytes_sent = 0;
+	}
 }
 
 /*
@@ -266,6 +272,7 @@
 		 */
 	case -EAGAIN:
 		break;
+	case -ECONNRESET:
 	case -ENOTCONN:
 	case -EPIPE:
 		/* connection broken */
@@ -383,6 +390,7 @@
 	if (!sk)
 		return;
 
+	write_lock_bh(&sk->callback_lock);
 	xprt->inet = NULL;
 	xprt->sock = NULL;
 
@@ -390,17 +398,12 @@
 	sk->data_ready   = xprt->old_data_ready;
 	sk->state_change = xprt->old_state_change;
 	sk->write_space  = xprt->old_write_space;
+	write_unlock_bh(&sk->callback_lock);
 
 	xprt_disconnect(xprt);
 	sk->no_check	 = 0;
 
 	sock_release(sock);
-	/*
-	 *	TCP doesn't require the rpciod now - other things may
-	 *	but rpciod handles that not us.
-	 */
-	if(xprt->stream)
-		rpciod_down();
 }
 
 /*
@@ -410,31 +413,29 @@
 xprt_disconnect(struct rpc_xprt *xprt)
 {
 	dprintk("RPC:      disconnected transport %p\n", xprt);
+	spin_lock_bh(&xprt->sock_lock);
 	xprt_clear_connected(xprt);
 	rpc_wake_up_status(&xprt->pending, -ENOTCONN);
+	spin_unlock_bh(&xprt->sock_lock);
 }
 
 /*
  * Reconnect a broken TCP connection.
  *
- * Note: This cannot collide with the TCP reads, as both run from rpciod
  */
 void
-xprt_reconnect(struct rpc_task *task)
+xprt_connect(struct rpc_task *task)
 {
 	struct rpc_xprt	*xprt = task->tk_xprt;
 	struct socket	*sock = xprt->sock;
 	struct sock	*inet;
 	int		status;
 
-	dprintk("RPC: %4d xprt_reconnect %p connected %d\n",
+	dprintk("RPC: %4d xprt_connect %p connected %d\n",
 				task->tk_pid, xprt, xprt_connected(xprt));
 	if (xprt->shutdown)
 		return;
 
-	if (!xprt->stream)
-		return;
-
 	if (!xprt->addr.sin_port) {
 		task->tk_status = -EIO;
 		return;
@@ -445,76 +446,112 @@
 	if (xprt_connected(xprt))
 		goto out_write;
 
-	if (sock && sock->state != SS_UNCONNECTED)
-		xprt_close(xprt);
-	status = -ENOTCONN;
-	if (!(inet = xprt->inet)) {
-		/* Create an unconnected socket */
-		if (!(sock = xprt_create_socket(xprt->prot, &xprt->timeout)))
-			goto defer;
-		xprt_bind_socket(xprt, sock);
-		inet = sock->sk;
+	if (task->tk_rqstp)
+		task->tk_rqstp->rq_bytes_sent = 0;
+
+	xprt_close(xprt);
+	/* Create an unconnected socket */
+	sock = xprt_create_socket(xprt->prot, &xprt->timeout, xprt->resvport);
+	if (!sock) {
+		/* couldn't create socket or bind to reserved port;
+		 * this is likely a permanent error, so cause an abort */
+		task->tk_status = -EIO;
+		goto out_write;
 	}
+	xprt_bind_socket(xprt, sock);
+
+	if (!xprt->stream)
+		goto out_write;
+
+	inet = sock->sk;
 
 	/* Now connect it asynchronously. */
 	dprintk("RPC: %4d connecting new socket\n", task->tk_pid);
 	status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
 				sizeof(xprt->addr), O_NONBLOCK);
+	dprintk("RPC: %4d connect status %d connected %d\n",
+		task->tk_pid, status, xprt_connected(xprt));
 
-	if (status < 0) {
-		switch (status) {
-		case -EALREADY:
-		case -EINPROGRESS:
-			status = 0;
-			break;
-		case -EISCONN:
-		case -EPIPE:
-			status = 0;
-			xprt_close(xprt);
-			goto defer;
-		default:
-			printk("RPC: TCP connect error %d!\n", -status);
-			xprt_close(xprt);
-			goto defer;
-		}
+	if (status >= 0)
+		return;
 
+	switch (status) {
+	case -EALREADY:
+	case -EINPROGRESS:
 		/* Protect against TCP socket state changes */
 		lock_sock(inet);
-		dprintk("RPC: %4d connect status %d connected %d\n",
-				task->tk_pid, status, xprt_connected(xprt));
-
 		if (inet->state != TCP_ESTABLISHED) {
-			task->tk_timeout = xprt->timeout.to_maxval;
-			/* if the socket is already closing, delay 5 secs */
+			dprintk("RPC: %4d  waiting for connection\n",
+					task->tk_pid);
+			task->tk_timeout = RPC_CONNECT_TIMEOUT;
+			/* if the socket is already closing, delay briefly */
 			if ((1<<inet->state) & ~(TCPF_SYN_SENT|TCPF_SYN_RECV))
-				task->tk_timeout = 5*HZ;
-			rpc_sleep_on(&xprt->pending, task, xprt_reconn_status, NULL);
-			release_sock(inet);
-			return;
+				task->tk_timeout = RPC_REESTABLISH_TIMEOUT;
+			rpc_sleep_on(&xprt->pending, task, xprt_connect_status,
+					NULL);
 		}
 		release_sock(inet);
+		break;
+	case -ECONNREFUSED:
+	case -ECONNRESET:
+	case -ENOTCONN:
+		if (!task->tk_client->cl_softrtry) {
+			rpc_delay(task, RPC_REESTABLISH_TIMEOUT);
+			task->tk_status = -ENOTCONN;
+			break;
+		}
+	default:
+		/* Report myriad other possible returns.  If this file
+		 * system is soft mounted, just error out, like Solaris.  */
+		if (task->tk_client->cl_softrtry) {
+			printk(KERN_WARNING
+					"RPC: error %d connecting to server %s, exiting\n",
+					-status, task->tk_client->cl_server);
+			task->tk_status = -EIO;
+			goto out_write;
+		}
+		printk(KERN_WARNING "RPC: error %d connecting to server %s\n",
+				-status, task->tk_client->cl_server);
+		/* This will prevent anybody else from connecting */
+		rpc_delay(task, RPC_REESTABLISH_TIMEOUT);
+		task->tk_status = status;
+		break;
 	}
-defer:
-	if (status < 0) {
-		rpc_delay(task, 5*HZ);
-		task->tk_status = -ENOTCONN;
-	}
+	return;
  out_write:
 	xprt_release_write(xprt, task);
 }
 
 /*
- * Reconnect timeout. We just mark the transport as not being in the
- * process of reconnecting, and leave the rest to the upper layers.
+ * We arrive here when awoken from waiting on connection establishment.
  */
 static void
-xprt_reconn_status(struct rpc_task *task)
+xprt_connect_status(struct rpc_task *task)
 {
 	struct rpc_xprt	*xprt = task->tk_xprt;
 
-	dprintk("RPC: %4d xprt_reconn_timeout %d\n",
-				task->tk_pid, task->tk_status);
+	if (task->tk_status >= 0) {
+		dprintk("RPC: %4d xprt_connect_status: connection established\n",
+				task->tk_pid);
+		return;
+	}
+
+	/* if soft mounted, cause this RPC to fail */
+	if (task->tk_client->cl_softrtry)
+		task->tk_status = -EIO;
 
+	switch (task->tk_status) {
+	case -ENOTCONN:
+		rpc_delay(task, RPC_REESTABLISH_TIMEOUT);
+		return;
+	case -ETIMEDOUT:
+		dprintk("RPC: %4d xprt_connect_status: timed out\n",
+				task->tk_pid);
+		break;
+	default:
+		printk(KERN_ERR "RPC: error %d connecting to server %s\n",
+				-task->tk_status, task->tk_client->cl_server);
+	}
 	xprt_release_write(xprt, task);
 }
 
@@ -657,8 +694,9 @@
 	struct sk_buff	*skb;
 	int		err, repsize, copied;
 
+	read_lock(&sk->callback_lock);
 	dprintk("RPC:      udp_data_ready...\n");
-	if (!(xprt = xprt_from_sock(sk))) {
+	if (sk->dead || !(xprt = xprt_from_sock(sk))) {
 		printk("RPC:      udp_data_ready request not found!\n");
 		goto out;
 	}
@@ -707,6 +745,7 @@
  out:
 	if (sk->sleep && waitqueue_active(sk->sleep))
 		wake_up_interruptible(sk->sleep);
+	read_unlock(&sk->callback_lock);
 }
 
 /*
@@ -895,7 +934,7 @@
 		}
 		/* Skip over any trailing bytes on short reads */
 		tcp_read_discard(xprt, &desc);
-	} while (desc.count && xprt_connected(xprt));
+	} while (desc.count);
 	dprintk("RPC:      tcp_data_recv done\n");
 	return len - desc.count;
 }
@@ -905,18 +944,21 @@
 	struct rpc_xprt *xprt;
 	read_descriptor_t rd_desc;
 
+	read_lock(&sk->callback_lock);
 	dprintk("RPC:      tcp_data_ready...\n");
 	if (!(xprt = xprt_from_sock(sk))) {
 		printk("RPC:      tcp_data_ready socket info not found!\n");
-		return;
+		goto out;
 	}
 	if (xprt->shutdown)
-		return;
+		goto out;
 
 	/* We use rd_desc to pass struct xprt to tcp_data_recv */
 	rd_desc.buf = (char *)xprt;
 	rd_desc.count = 65536;
 	tcp_read_sock(sk, &rd_desc, tcp_data_recv);
+out:
+	read_unlock(&sk->callback_lock);
 }
 
 static void
@@ -924,6 +966,7 @@
 {
 	struct rpc_xprt	*xprt;
 
+	read_lock(&sk->callback_lock);
 	if (!(xprt = xprt_from_sock(sk)))
 		goto out;
 	dprintk("RPC:      tcp_state_change client %p...\n", xprt);
@@ -942,10 +985,10 @@
 		xprt->tcp_copied = 0;
 		xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
 
-		spin_lock(&xprt->sock_lock);
+		spin_lock_bh(&xprt->sock_lock);
 		if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->pending)
 			rpc_wake_up_task(xprt->snd_task);
-		spin_unlock(&xprt->sock_lock);
+		spin_unlock_bh(&xprt->sock_lock);
 		break;
 	case TCP_SYN_SENT:
 	case TCP_SYN_RECV:
@@ -957,6 +1000,7 @@
  out:
 	if (sk->sleep && waitqueue_active(sk->sleep))
 		wake_up_interruptible_all(sk->sleep);
+	read_unlock(&sk->callback_lock);
 }
 
 /*
@@ -971,24 +1015,25 @@
 	struct rpc_xprt	*xprt;
 	struct socket	*sock;
 
+	read_lock(&sk->callback_lock);
 	if (!(xprt = xprt_from_sock(sk)) || !(sock = sk->socket))
-		return;
+		goto out;
 	if (xprt->shutdown)
-		return;
+		goto out;
 
 	/* Wait until we have enough socket memory */
 	if (xprt->stream) {
 		/* from net/ipv4/tcp.c:tcp_write_space */
 		if (tcp_wspace(sk) < tcp_min_write_space(sk))
-			return;
+			goto out;
 	} else {
 		/* from net/core/sock.c:sock_def_write_space */
 		if (!sock_writeable(sk))
-			return;
+			goto out;
 	}
 
 	if (!test_and_clear_bit(SOCK_NOSPACE, &sock->flags))
-		return;
+		goto out;
 
 	spin_lock_bh(&xprt->sock_lock);
 	if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->pending)
@@ -996,6 +1041,8 @@
 	spin_unlock_bh(&xprt->sock_lock);
 	if (sk->sleep && waitqueue_active(sk->sleep))
 		wake_up_interruptible(sk->sleep);
+out:
+	read_unlock(&sk->callback_lock);
 }
 
 /*
@@ -1063,9 +1110,6 @@
 	if (xprt->shutdown)
 		task->tk_status = -EIO;
 
-	if (!xprt_connected(xprt))
-		task->tk_status = -ENOTCONN;
-
 	if (task->tk_status < 0)
 		return;
 
@@ -1081,10 +1125,14 @@
 	}
 
 	spin_lock_bh(&xprt->sock_lock);
-	if (!__xprt_lock_write(xprt, task)) {
-		spin_unlock_bh(&xprt->sock_lock);
-		return;
+	if (!__xprt_lock_write(xprt, task))
+		goto out_notrans;
+
+	if (!xprt_connected(xprt)) {
+		task->tk_status = -ENOTCONN;
+		goto out_notrans;
 	}
+
 	if (list_empty(&req->rq_list)) {
 		list_add_tail(&req->rq_list, &xprt->recv);
 		req->rq_received = 0;
@@ -1092,6 +1140,9 @@
 	spin_unlock_bh(&xprt->sock_lock);
 
 	do_xprt_transmit(task);
+	return;
+out_notrans:
+	spin_unlock_bh(&xprt->sock_lock);
 }
 
 static void
@@ -1135,11 +1186,12 @@
 			break;
 	}
 
-	/* Note: at this point, task->tk_sleeping has not yet been set,
-	 *	 hence there is no danger of the waking up task being put on
-	 *	 schedq, and being picked up by a parallel run of rpciod().
+	/* If we're doing a resend and have received a reply already,
+	 * then exit early.
+	 * Note, though, that we can't do this if we've already started
+	 * resending down a TCP stream.
 	 */
-	if (req->rq_received)
+	if (req->rq_received && !req->rq_bytes_sent)
 		goto out_release;
 
 	task->tk_status = status;
@@ -1149,7 +1201,10 @@
 		if (test_bit(SOCK_ASYNC_NOSPACE, &xprt->sock->flags)) {
 			/* Protect against races with xprt_write_space */
 			spin_lock_bh(&xprt->sock_lock);
-			if (test_bit(SOCK_NOSPACE, &xprt->sock->flags)) {
+			/* Don't race with disconnect */
+			if (!xprt_connected(xprt))
+				task->tk_status = -ENOTCONN;
+			else if (test_bit(SOCK_NOSPACE, &xprt->sock->flags)) {
 				task->tk_timeout = req->rq_timeout.to_current;
 				rpc_sleep_on(&xprt->pending, task, NULL, NULL);
 			}
@@ -1160,13 +1215,13 @@
 		rpc_delay(task, HZ>>4);
 		return;
 	case -ECONNREFUSED:
+		task->tk_timeout = RPC_REESTABLISH_TIMEOUT;
+		rpc_sleep_on(&xprt->sending, task, NULL, NULL);
 	case -ENOTCONN:
-		if (!xprt->stream)
-			return;
+		return;
 	default:
 		if (xprt->stream)
 			xprt_disconnect(xprt);
-		req->rq_bytes_sent = 0;
 	}
  out_release:
 	xprt_release_write(xprt, task);
@@ -1183,7 +1238,10 @@
 	} else
 		task->tk_timeout = req->rq_timeout.to_current;
 	spin_lock_bh(&xprt->sock_lock);
-	if (!req->rq_received)
+	/* Don't race with disconnect */
+	if (!xprt_connected(xprt))
+		task->tk_status = -ENOTCONN;
+	else if (!req->rq_received)
 		rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer);
 	__xprt_release_write(xprt, task);
 	spin_unlock_bh(&xprt->sock_lock);
@@ -1192,61 +1250,39 @@
 /*
  * Reserve an RPC call slot.
  */
-int
+void
 xprt_reserve(struct rpc_task *task)
 {
 	struct rpc_xprt	*xprt = task->tk_xprt;
 
-	/* We already have an initialized request. */
-	if (task->tk_rqstp)
-		return 0;
-
-	spin_lock(&xprt->xprt_lock);
-	xprt_reserve_status(task);
-	if (task->tk_rqstp) {
-		task->tk_timeout = 0;
-	} else if (!task->tk_timeout) {
-		task->tk_status = -ENOBUFS;
-	} else {
-		dprintk("RPC:      xprt_reserve waiting on backlog\n");
-		task->tk_status = -EAGAIN;
-		rpc_sleep_on(&xprt->backlog, task, NULL, NULL);
+	task->tk_status = -EIO;
+	if (!xprt->shutdown) {
+		spin_lock(&xprt->xprt_lock);
+		do_xprt_reserve(task);
+		spin_unlock(&xprt->xprt_lock);
 	}
-	spin_unlock(&xprt->xprt_lock);
-	dprintk("RPC: %4d xprt_reserve returns %d\n",
-				task->tk_pid, task->tk_status);
-	return task->tk_status;
 }
 
-/*
- * Reservation callback
- */
-static void
-xprt_reserve_status(struct rpc_task *task)
+static inline void
+do_xprt_reserve(struct rpc_task *task)
 {
 	struct rpc_xprt	*xprt = task->tk_xprt;
-	struct rpc_rqst	*req;
 
-	if (xprt->shutdown) {
-		task->tk_status = -EIO;
-	} else if (task->tk_status < 0) {
-		/* NOP */
-	} else if (task->tk_rqstp) {
-		/* We've already been given a request slot: NOP */
-	} else {
-		if (!(req = xprt->free))
-			goto out_nofree;
-		/* OK: There's room for us. Grab a free slot */
-		xprt->free     = req->rq_next;
-		req->rq_next   = NULL;
+	task->tk_status = 0;
+	if (task->tk_rqstp)
+		return;
+	if (xprt->free) {
+		struct rpc_rqst	*req = xprt->free;
+		xprt->free = req->rq_next;
+		req->rq_next = NULL;
 		task->tk_rqstp = req;
 		xprt_request_init(task, xprt);
+		return;
 	}
-
-	return;
-
-out_nofree:
+	dprintk("RPC:      waiting for request slot\n");
 	task->tk_status = -EAGAIN;
+	task->tk_timeout = 0;
+	rpc_sleep_on(&xprt->backlog, task, NULL, NULL);
 }
 
 /*
@@ -1339,7 +1375,6 @@
 	to->to_initval   = 
 	to->to_increment = incr;
 	to->to_maxval    = incr * retr;
-	to->to_resrvval  = incr * retr;
 	to->to_retries   = retr;
 	to->to_exponential = 0;
 }
@@ -1348,8 +1383,7 @@
  * Initialize an RPC client
  */
 static struct rpc_xprt *
-xprt_setup(struct socket *sock, int proto,
-			struct sockaddr_in *ap, struct rpc_timeout *to)
+xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
 {
 	struct rpc_xprt	*xprt;
 	struct rpc_rqst	*req;
@@ -1380,7 +1414,6 @@
 	if (to) {
 		xprt->timeout = *to;
 		xprt->timeout.to_current = to->to_initval;
-		xprt->timeout.to_resrvval = to->to_maxval << 1;
 	} else
 		xprt_default_timeout(&xprt->timeout, xprt->prot);
 
@@ -1395,9 +1428,11 @@
 	req->rq_next = NULL;
 	xprt->free = xprt->slot;
 
+	/* Check whether we want to use a reserved port */
+	xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
+
 	dprintk("RPC:      created transport %p\n", xprt);
 	
-	xprt_bind_socket(xprt, sock);
 	return xprt;
 }
 
@@ -1409,6 +1444,12 @@
 {
 	struct sockaddr_in myaddr;
 	int		err, port;
+	kernel_cap_t saved_cap = current->cap_effective;
+
+	/* Override capabilities.
+	 * They were checked in xprt_create_proto i.e. at mount time
+	 */
+	cap_raise (current->cap_effective, CAP_NET_BIND_SERVICE);
 
 	memset(&myaddr, 0, sizeof(myaddr));
 	myaddr.sin_family = AF_INET;
@@ -1418,6 +1459,7 @@
 		err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,
 						sizeof(myaddr));
 	} while (err == -EADDRINUSE && --port > 0);
+	current->cap_effective = saved_cap;
 
 	if (err < 0)
 		printk("RPC: Can't bind to reserved port (%d).\n", -err);
@@ -1433,6 +1475,7 @@
 	if (xprt->inet)
 		return -EBUSY;
 
+	write_lock_bh(&sk->callback_lock);
 	sk->user_data = xprt;
 	xprt->old_data_ready = sk->data_ready;
 	xprt->old_state_change = sk->state_change;
@@ -1453,11 +1496,7 @@
 	/* Reset to new socket */
 	xprt->sock = sock;
 	xprt->inet = sk;
-	/*
-	 *	TCP requires the rpc I/O daemon is present
-	 */
-	if(xprt->stream)
-		rpciod_up();
+	write_unlock_bh(&sk->callback_lock);
 
 	return 0;
 }
@@ -1487,7 +1526,7 @@
  * Create a client socket given the protocol and peer address.
  */
 static struct socket *
-xprt_create_socket(int proto, struct rpc_timeout *to)
+xprt_create_socket(int proto, struct rpc_timeout *to, int resvport)
 {
 	struct socket	*sock;
 	int		type, err;
@@ -1502,8 +1541,8 @@
 		goto failed;
 	}
 
-	/* If the caller has the capability, bind to a reserved port */
-	if (capable(CAP_NET_BIND_SERVICE) && xprt_bindresvport(sock) < 0)
+	/* bind to a reserved port */
+	if (resvport && xprt_bindresvport(sock) < 0)
 		goto failed;
 
 	return sock;
@@ -1519,18 +1558,19 @@
 struct rpc_xprt *
 xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
 {
-	struct socket	*sock;
 	struct rpc_xprt	*xprt;
 
-	dprintk("RPC:      xprt_create_proto called\n");
-
-	if (!(sock = xprt_create_socket(proto, to)))
-		return NULL;
-
-	if (!(xprt = xprt_setup(sock, proto, sap, to)))
-		sock_release(sock);
+	xprt = xprt_setup(proto, sap, to);
+	if (!xprt)
+		goto out_bad;
 
+	dprintk("RPC:      xprt_create_proto created xprt %p\n", xprt);
 	return xprt;
+out_bad:
+	dprintk("RPC:      xprt_create_proto failed\n");
+	if (xprt)
+		kfree(xprt);
+	return NULL;
 }
 
 /*
diff -urN linux-2.4.22-pre2/scripts/extract-ikconfig linux-2.4.22-pre3/scripts/extract-ikconfig
--- linux-2.4.22-pre2/scripts/extract-ikconfig	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/scripts/extract-ikconfig	2003-07-05 18:12:37.000000000 -0700
@@ -0,0 +1,17 @@
+#! /bin/bash -x
+# extracts .config info from a [b]zImage file
+# uses: binoffset (new), dd, zcat, strings, grep
+# $arg1 is [b]zImage filename
+
+HDR=`binoffset $1 0x1f 0x8b 0x08 0x0`
+PID=$$
+TMPFILE="$1.vmlin.$PID"
+
+# dd if=$1 bs=1 skip=$HDR | zcat - | strings /dev/stdin \
+# | grep "[A-Za-z_0-9]=[ynm]$" | sed "s/^/CONFIG_/" > $1.oldconfig.$PID
+# exit
+
+dd if=$1 bs=1 skip=$HDR | zcat - > $TMPFILE
+strings $TMPFILE | grep "^[\#[:blank:]]*CONFIG_[A-Za-z_0-9]*" > $1.oldconfig.$PID
+wc $1.oldconfig.$PID
+rm $TMPFILE
diff -urN linux-2.4.22-pre2/scripts/mkconfigs.c linux-2.4.22-pre3/scripts/mkconfigs.c
--- linux-2.4.22-pre2/scripts/mkconfigs.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-pre3/scripts/mkconfigs.c	2003-07-05 18:12:37.000000000 -0700
@@ -0,0 +1,181 @@
+/***************************************************************************
+ * mkconfigs.c
+ * (C) 2002 Randy Dunlap <rddunlap@osdl.org>
+
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Rules for scripts/mkconfigs.c input.config output.c
+# to generate configs.c from linux/.config:
+# - drop lines that begin with '#'
+# - drop blank lines
+# - lines that use double-quotes must \\-escape-quote them
+
+################## skeleton configs.c file: ####################
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+static char *configs[] __initdata =
+
+  <insert lines selected lines of .config, quoted, with added '\n'>,
+
+;
+
+################### end configs.c file ######################
+
+ * Changelog for ver. 0.2, 2002-02-15, rddunlap@osdl.org:
+ - strip leading "CONFIG_" from config option strings;
+ - use "static" and "__attribute__((unused))";
+ - don't use EXPORT_SYMBOL();
+ - separate each config line with \newline instead of space;
+
+ * Changelog for ver. 0.3, 2002-02-18, rddunlap@osdl.org:
+ - keep all "not set" comment lines from .config so that 'make *config'
+   will be happy, but don't keep other comments;
+ - keep leading "CONFIG_" on each line;
+
+****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define VERSION		"0.2"
+#define LINE_SIZE	1000
+
+int include_all_lines = 1;	// whether to include "=n" lines in the output
+
+void usage (const char *progname)
+{
+	fprintf (stderr, "%s ver. %s\n", progname, VERSION);
+	fprintf (stderr, "usage:  %s input.config.name path/configs.c\n",
+			progname);
+	exit (1);
+}
+
+void make_intro (FILE *sourcefile)
+{
+	fprintf (sourcefile, "#include <linux/init.h>\n");
+/////	fprintf (sourcefile, "#include <linux/module.h>\n");
+	fprintf (sourcefile, "\n");
+/////	fprintf (sourcefile, "char *configs[] __initdata = {\n");
+	fprintf (sourcefile, "static char __attribute__ ((unused)) *configs[] __initdata = {\n");
+	fprintf (sourcefile, "  \"CONFIG_BEGIN=n\\n\" ,\n");
+}
+
+void make_ending (FILE *sourcefile)
+{
+	fprintf (sourcefile, "  \"CONFIG_END=n\\n\"\n");
+	fprintf (sourcefile, "};\n");
+/////	fprintf (sourcefile, "EXPORT_SYMBOL (configs);\n");
+}
+
+void make_lines (FILE *configfile, FILE *sourcefile)
+{
+	char cfgline[LINE_SIZE];
+	char *ch;
+
+	while (fgets (cfgline, LINE_SIZE, configfile)) {
+		/* kill the trailing newline in cfgline */
+		cfgline[strlen (cfgline) - 1] = '\0';
+
+		/* don't keep #-only line or an empty/blank line */
+		if ((cfgline[0] == '#' && cfgline[1] == '\0') ||
+		    cfgline[0] == '\0')
+			continue;
+
+		if (!include_all_lines &&
+		    cfgline[0] == '#') // strip out all comment lines
+			continue;
+
+		/* really only want to keep lines that begin with
+		 * "CONFIG_" or "# CONFIG_" */
+		if (strncmp (cfgline, "CONFIG_", 7) &&
+		    strncmp (cfgline, "# CONFIG_", 9))
+		    	continue;
+
+		/*
+		 * use strchr() to check for "-quote in cfgline;
+		 * if not found, output the line, quoted;
+		 * if found, output a char at a time, with \\-quote
+		 * preceding double-quote chars
+		 */
+		if (!strchr (cfgline, '"')) {
+			fprintf (sourcefile, "  \"%s\\n\" ,\n", cfgline);
+			continue;
+		}
+
+		/* go to char-at-a-time mode for this config and
+		 * precede any double-quote with a backslash */
+		fprintf (sourcefile, "  \"");	/* lead-in */
+		for (ch = cfgline; *ch; ch++) {
+			if (*ch == '"')
+				fputc ('\\', sourcefile);
+			fputc (*ch, sourcefile);
+		}
+		fprintf (sourcefile, "\\n\" ,\n");
+	}
+}
+
+void make_configs (FILE *configfile, FILE *sourcefile)
+{
+	make_intro (sourcefile);
+	make_lines (configfile, sourcefile);
+	make_ending (sourcefile);
+}
+
+int main (int argc, char *argv[])
+{
+	char *progname = argv[0];
+	char *configname, *sourcename;
+	FILE *configfile, *sourcefile;
+
+	if (argc != 3)
+		usage (progname);
+
+	configname = argv[1];
+	sourcename = argv[2];
+
+	configfile = fopen (configname, "r");
+	if (!configfile) {
+		fprintf (stderr, "%s: cannot open '%s'\n",
+				progname, configname);
+		exit (2);
+	}
+	sourcefile = fopen (sourcename, "w");
+	if (!sourcefile) {
+		fprintf (stderr, "%s: cannot open '%s'\n",
+				progname, sourcename);
+		exit (2);
+	}
+
+	make_configs (configfile, sourcefile);
+
+	if (fclose (sourcefile)) {
+		fprintf (stderr, "%s: error %d closing '%s'\n",
+				progname, errno, sourcename);
+		exit (3);
+	}
+	if (fclose (configfile)) {
+		fprintf (stderr, "%s: error %d closing '%s'\n",
+				progname, errno, configname);
+		exit (3);
+	}
+
+	exit (0);
+}
+
+/* end mkconfigs.c */
